Repaso de programación cientÃfica en Python¶
Variables¶
Tipos fundamentales
i = 4 # integer
x = -0.4 # float
z = 3 + 4j # complex
t = "text" # string
b = True # boolean
Operaciones fundamentales con los tipos fundamentales
x = -0.5
y = 2
print(f"x+y = {x+y}, x-y={x-y}, x*y = {x*y}, x/y = {x/y}, x//y = {x//y}, y**x = {y**x}")
x+y = 1.5, x-y=-2.5, x*y = -1.0, x/y = -0.25, x//y = -1.0, y**x = 0.7071067811865476
Organización de la información¶
Listas
l = [1,2,'a',-1.5] # list
# access an element of the list
l[2]
'a'
# access the last element of the list
l[-1]
-1.5
# access some elements of the list
l[0:2]
[1, 2]
# add an element to a list
l.append('new')
l
[1, 2, 'a', -1.5, 'new']
# check whether an element is in a list or not
print(3 in l)
print(2 in l)
False True
Diccionarios
d = {'physics': 'science that studies the principles of the universe',
'astronomy': 'science that studies the '}
# access an element
d['physics']
'science that studies the principles of the universe'
# define a new element
d[130] = 4
d
{'physics': 'science that studies the principles of the universe',
'astronomy': 'science that studies the ',
130: 4}
# get only the keys
d.keys()
dict_keys(['physics', 'astronomy', 130])
Clases y objetos¶
class Particle:
mass = 0
position = 0
ball = Particle()
ball.mass = 4
ball.position = -0.4
Condiciones¶
energy = -4.0
if energy < 0:
print("energy is leaving the system")
elif energy == 0:
print("energy is conserved")
else:
print("energy is entering the system")
energy is leaving the system
Bucles¶
l
[1, 2, 'a', -1.5, 'new']
for element in l:
print("the element",element,"is a",type(element))
the element 1 is a <class 'int'> the element 2 is a <class 'int'> the element a is a <class 'str'> the element -1.5 is a <class 'float'> the element new is a <class 'str'>
for i,element in enumerate(l):
print(i,element)
0 1 1 2 2 a 3 -1.5 4 new
# Imagine you want to plot several lines, each one has different colors, and different start and end points
line_colors = ['blue','red','orange','black']
intervals = [[1,2],[-3,4.4],[-1.2,0.4],[5,6]]
for line_color, interval in zip(line_colors,intervals):
print(f"this line extends from {interval[0]} to {interval[1]} and has color {line_color}")
this line extends from 1 to 2 and has color blue this line extends from -3 to 4.4 and has color red this line extends from -1.2 to 0.4 and has color orange this line extends from 5 to 6 and has color black
One-liners¶
# List comprehensions
new_list = [i for i in range(45,50)]
new_list
[45, 46, 47, 48, 49]
positions = [3,-4,-1,2]
# get only the positive positions (filter a list)
positions = [pos for pos in positions if pos > 0]
positions
[3, 2]
frequency = 50e5 # Hz
is_a_radio_wave = True if frequency > 1e4 or frequency < 1e7 else False
print(is_a_radio_wave)
True
Numpy¶
import numpy as np
import matplotlib.pyplot as plt
# array of integers
a = np.array([1,2,3,4,6],dtype=int)
a
array([1, 2, 3, 4, 6])
# array of floats
a = np.array([3,4,3,5],dtype=float)
a
array([3., 4., 3., 5.])
# bidimensional array
x_points = np.linspace(-10,10,1000)
y_points = np.linspace(-10,10,1000)
x, y = np.meshgrid(x_points, y_points, indexing='ij')
x_points.shape, y_points.shape, x.shape, y.shape
((1000,), (1000,), (1000, 1000), (1000, 1000))
# calculation of the distance to the origin
r = np.sqrt(x**2 + y**2)
# plot of the distance as a pcolormesh
plt.pcolormesh(x, y, r, cmap='gray_r')
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x111002510>
# delete all distances larger than a threshold
threshold = 8
# first we make a copy of the original array
modif_r = np.array(r)
modif_r[ r > 8] = 0.
# plot of the distance as a pcolormesh
plt.pcolormesh(x, y, modif_r, cmap='gray_r')
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x111188550>
# calculation of a force
force = 0.1/r**2
# plot of the distance as a pcolormesh
plt.pcolormesh(x, y, force, vmin=0,vmax=10,cmap='gray_r')
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x11126cb90>
Example with simulation data¶
This simulation data has been produced by PLUTO and then interpolated into a Cartesian grid. All quantities are expressed in Gaussian-CGS units. The Cartesian grid extends from x = 0 to x = 200 au, and from z = 0 to z = 200 au and has 1000 cells in each direction.
At the instant of this simulation data, the star has a mass of 2.90 solar masses.
x_points = np.linspace(0,200,1000)
z_points = np.linspace(0,200,1000)
x, z = np.meshgrid(x_points, z_points, indexing='ij')
rho = np.load('sim1data/rho.npy')
v_r = np.load('sim1data/vx1.npy')
v_th = np.load('sim1data/vx2.npy')
v_ph = np.load('sim1data/vx3.npy')
# density
plt.pcolormesh(x,z, np.log10(rho))
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x111327750>
# radial velocity in km/s
plt.pcolormesh(x,z, v_r/1e5, vmin=-10,vmax=10, cmap='seismic_r')
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x11140fc50>
# Separating the outflow from the inflow
outflow = np.array(v_r)/1e5 # km/s
outflow[outflow < 0] = 0
plt.pcolormesh(x,z, outflow, cmap='plasma')
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x1114ffb10>
Let's compute the magnitude of the gravitational force that the star exerts on the circumstellar material.
au_in_cm = 14950000000000.0
r = np.sqrt(x**2 + z**2)*au_in_cm
G = 6.67e-08 # gravitational constant G in cgs units
Msun = 2e33 # solar mass in g
Mstar = 2.9*Msun # (given from the simulation)
F_grav = rho*G*Mstar/r**2 # in dynes/cm^3
plt.pcolormesh(x,z,F_grav, cmap='plasma')
plt.colorbar()
/var/folders/1r/kzh10jnx48jcn2l34mt99ctw0000gn/T/ipykernel_2776/1293598483.py:8: RuntimeWarning: divide by zero encountered in divide F_grav = rho*G*Mstar/r**2 # in dynes/cm^3
<matplotlib.colorbar.Colorbar at 0x1115ea0d0>
The result is somewhat meaningless because we don't have anyting to compare it against. Let's compute the centrifugal force per volume (in the co-rotating frame), that is, $\rho v_\phi^2/r \, \mathbf e_x$, and then let's compare it against the horizontal component of gravity, that is, $\rho GM/r^2 \sin\theta \, \mathbf e_x$.
th = np.atan2(x,z)
F_centrif_x = rho*v_ph**2/r
F_grav_x = F_grav*np.sin(th)
/var/folders/1r/kzh10jnx48jcn2l34mt99ctw0000gn/T/ipykernel_2776/3700062375.py:3: RuntimeWarning: divide by zero encountered in divide F_centrif_x = rho*v_ph**2/r /var/folders/1r/kzh10jnx48jcn2l34mt99ctw0000gn/T/ipykernel_2776/3700062375.py:4: RuntimeWarning: invalid value encountered in multiply F_grav_x = F_grav*np.sin(th)
Now, let's divide the magnitude of both components and plot the result
plt.pcolormesh(x,z, np.abs(F_centrif_x)/np.abs(F_grav_x), vmin=0, vmax=2, cmap='seismic_r')
plt.colorbar()
/var/folders/1r/kzh10jnx48jcn2l34mt99ctw0000gn/T/ipykernel_2776/46531648.py:1: RuntimeWarning: divide by zero encountered in divide plt.pcolormesh(x,z, np.abs(F_centrif_x)/np.abs(F_grav_x), vmin=0, vmax=2, cmap='seismic_r')
<matplotlib.colorbar.Colorbar at 0x1116ccf50>
The red regions (the ratio < 1) mean that the gravity wins. The blue regions (ratio > 1) mean that the centrifugal force wins. The centrifugal force, together with the magnetic field, is the cause the jet is being launched. We'll see this later in the course.