11"""
2- example code for bridging a gravity solver with a hydrodynamics solver
2+ example code for bridging a gravity solver with a hydrodynamics solver
33"""
4- import numpy
5- from amuse .lab import *
4+
5+ import argparse
6+ import numpy as np
7+ from amuse .units import nbody_system , units , constants
8+ from amuse .io import write_set_to_file
9+ from amuse .ic .gasplummer import new_plummer_gas_model
10+ from amuse .community .fi import Fi
11+ from amuse .community .ph4 import Ph4
612from amuse .couple import bridge
713from amuse .ext .orbital_elements import new_binary_from_orbital_elements
814from amuse .ext .orbital_elements import orbital_elements_from_binary
915
16+
1017# #BOOKLISTSTART1# #
1118class BaseCode :
12- def __init__ (self , code , particles , eps = 0 | units .RSun ):
19+ def __init__ (self , code , particles , eps = 0 | units .RSun ):
1320
1421 self .local_particles = particles
1522 m = self .local_particles .mass .sum ()
@@ -20,144 +27,218 @@ def __init__(self, code, particles, eps=0|units.RSun):
2027
2128 def evolve_model (self , time ):
2229 self .code .evolve_model (time )
30+
2331 def copy_to_framework (self ):
2432 self .channel_to_framework .copy ()
33+
2534 def get_gravity_at_point (self , r , x , y , z ):
2635 return self .code .get_gravity_at_point (r , x , y , z )
36+
2737 def get_potential_at_point (self , r , x , y , z ):
2838 return self .code .get_potential_at_point (r , x , y , z )
39+
2940 def get_timestep (self ):
3041 return self .code .parameters .timestep
42+
3143 @property
32- def model_time (self ):
44+ def model_time (self ):
3345 return self .code .model_time
46+
3447 @property
3548 def particles (self ):
3649 return self .code .particles
50+
3751 @property
3852 def total_energy (self ):
3953 return self .code .kinetic_energy + self .code .potential_energy
54+
4055 @property
4156 def stop (self ):
4257 return self .code .stop
58+
59+
4360# #BOOKLISTSTOP1# #
4461
62+
4563# #BOOKLISTSTART2# #
4664class Gravity (BaseCode ):
47- def __init__ (self , code , particles , eps = 0 | units .RSun ):
65+ def __init__ (self , code , particles , eps = 0 | units .RSun ):
4866 BaseCode .__init__ (self , code , particles , eps )
4967 self .code .particles .add_particles (self .local_particles )
50- self .channel_to_framework \
51- = self .code .particles .new_channel_to (self .local_particles )
52- self .channel_from_framework \
53- = self .local_particles .new_channel_to (self .code .particles )
68+ self .channel_to_framework = self .code .particles .new_channel_to (
69+ self .local_particles
70+ )
71+ self .channel_from_framework = self .local_particles .new_channel_to (
72+ self .code .particles
73+ )
5474 self .initial_total_energy = self .total_energy
75+
76+
5577# #BOOKLISTSTOP2# #
5678
79+
5780# #BOOKLISTSTART3# #
5881class Hydro (BaseCode ):
59- def __init__ (self , code , particles , eps = 0 | units .RSun ,
60- dt = None , Rbound = None ):
82+ def __init__ (self , code , particles , eps = 0 | units .RSun , dt = None , Rbound = None ):
6183 BaseCode .__init__ (self , code , particles , eps )
62- self .channel_to_framework \
63- = self .code .gas_particles .new_channel_to (self .local_particles )
64- self .channel_from_framework \
65- = self .local_particles .new_channel_to (self .code .gas_particles )
84+ self .channel_to_framework = self .code .gas_particles .new_channel_to (
85+ self .local_particles
86+ )
87+ self .channel_from_framework = self .local_particles .new_channel_to (
88+ self .code .gas_particles
89+ )
6690 self .code .gas_particles .add_particles (particles )
6791 m = self .local_particles .mass .sum ()
6892 l = self .code .gas_particles .position .length ()
6993 if Rbound is None :
70- Rbound = 10 * l
94+ Rbound = 10 * l
7195 self .code .parameters .periodic_box_size = Rbound
7296 if dt is None :
73- dt = 0.01 * numpy .sqrt (l ** 3 / (constants .G * m ))
74- self .code .parameters .timestep = dt / 8.
97+ dt = 0.01 * np .sqrt (l ** 3 / (constants .G * m ))
98+ self .code .parameters .timestep = dt / 8.0
7599 self .initial_total_energy = self .total_energy
100+
76101 @property
77102 def total_energy (self ):
78- return self .code .kinetic_energy \
79- + self .code .potential_energy \
103+ return (
104+ self .code .kinetic_energy
105+ + self .code .potential_energy
80106 + self .code .thermal_energy
107+ )
108+
109+
81110# #BOOKLISTSTOP3# #
82-
83- # #BOOKLISTSTART4# #
84- def gravity_hydro_bridge (Mprim , Msec , a , ecc , t_end , n_steps ,
85- Rgas , Mgas , Ngas ):
86111
87- stars = new_binary_from_orbital_elements (Mprim , Msec , a , ecc ,
88- G = constants .G )
112+
113+ # #BOOKLISTSTART4# #
114+ def gravity_hydro_bridge (Mprim , Msec , a , ecc , time_end , n_steps , Rgas , Mgas , Ngas ):
115+ stars = new_binary_from_orbital_elements (Mprim , Msec , a , ecc , G = constants .G )
89116 eps = 1 | units .RSun
90- gravity = Gravity (ph4 , stars , eps )
117+ gravity = Gravity (Ph4 , stars , eps )
91118
92- converter = nbody_system .nbody_to_si (1.0 | units .MSun , Rgas )
119+ converter = nbody_system .nbody_to_si (1.0 | units .MSun , Rgas )
93120 ism = new_plummer_gas_model (Ngas , convert_nbody = converter )
94121 ism .move_to_center ()
95- ism = ism .select (lambda r : r .length ()< 2 * a , ["position" ])
122+ ism = ism .select (lambda r : r .length () < 2 * a , ["position" ])
96123 hydro = Hydro (Fi , ism , eps )
97124 model_time = 0 | units .Myr
98125 filename = "gravhydro.hdf5"
99- write_set_to_file (stars .savepoint (model_time ), filename , ' amuse' )
100- write_set_to_file (ism , filename , ' amuse' , append_to_file = True )
126+ write_set_to_file (stars .savepoint (model_time ), filename , " amuse" )
127+ write_set_to_file (ism , filename , " amuse" , append_to_file = True )
101128
102129 gravhydro = bridge .Bridge (use_threading = False )
103130 gravhydro .add_system (gravity , (hydro ,))
104131 gravhydro .add_system (hydro , (gravity ,))
105- gravhydro .timestep = 2 * hydro .get_timestep ()
132+ gravhydro .timestep = 2 * hydro .get_timestep ()
106133
107- while model_time < t_end :
134+ while model_time < time_end :
108135 orbit = orbital_elements_from_binary (stars , G = constants .G )
109- dE_gravity = gravity .initial_total_energy / gravity .total_energy
110- dE_hydro = hydro .initial_total_energy / hydro .total_energy
111- print (("Time:" , model_time .in_ (units .yr ), \
112- "ae=" , orbit [2 ].in_ (units .AU ), orbit [3 ], \
113- "dE=" , dE_gravity , dE_hydro ))
114-
115- model_time += 10 * gravhydro .timestep
136+ dE_gravity = gravity .initial_total_energy / gravity .total_energy
137+ dE_hydro = hydro .initial_total_energy / hydro .total_energy
138+ print (
139+ (
140+ "Time:" ,
141+ model_time .in_ (units .yr ),
142+ "ae=" ,
143+ orbit [2 ].in_ (units .au ),
144+ orbit [3 ],
145+ "dE=" ,
146+ dE_gravity ,
147+ dE_hydro ,
148+ )
149+ )
150+
151+ model_time += 10 * gravhydro .timestep
116152 gravhydro .evolve_model (model_time )
117153 gravity .copy_to_framework ()
118154 hydro .copy_to_framework ()
119- write_set_to_file (stars .savepoint (model_time ), filename , 'amuse' , append_to_file = True )
120- write_set_to_file (ism , filename , 'amuse' , append_to_file = True )
155+ write_set_to_file (
156+ stars .savepoint (model_time ), filename , "amuse" , append_to_file = True
157+ )
158+ write_set_to_file (ism , filename , "amuse" , append_to_file = True )
121159 print ("P=" , model_time .in_ (units .yr ), gravity .particles .x .in_ (units .au ))
122160 gravity .stop ()
123161 hydro .stop ()
162+
163+
124164# #BOOKLISTSTOP4# #
125165
126- def new_option_parser ():
127- from amuse .units .optparse import OptionParser
128- result = OptionParser ()
129- result .add_option ("-n" , dest = "n_steps" , type = "int" , default = 1000 ,
130- help = "number of diagnostics time steps [%default]" )
131- result .add_option ("-N" , dest = "Ngas" , type = "int" , default = 1024 ,
132- help = "number of gas particles [%default]" )
133- result .add_option ("--Mprim" , unit = units .MSun ,
134- dest = "Mprim" , type = "float" , default = 3.2 | units .MSun ,
135- help = "Mass of the primary star [%default]" )
136- result .add_option ("--Msec" , unit = units .MSun ,
137- dest = "Msec" , type = "float" , default = 3.1 | units .MSun ,
138- help = "Mass of the secondary star [%default]" )
139- result .add_option ("-M" , unit = units .MSun ,
140- dest = "Mgas" , type = "float" , default = 1 | units .MSun ,
141- help = "Mass of the gas [%default]" )
142- result .add_option ("-R" , unit = units .AU ,
143- dest = "Rgas" , type = "float" , default = 10 | units .AU ,
144- help = "Size of the gas distribution [%default]" )
145- result .add_option ("-a" , unit = units .AU ,
146- dest = "a" , type = "float" , default = 1 | units .AU ,
147- help = "initial orbital separation [%default]" )
148- result .add_option ("-e" , dest = "ecc" , type = "float" , default = 0.6 ,
149- help = "initial orbital eccentricity [%default]" )
150- result .add_option ("-t" , unit = units .yr ,
151- dest = "t_end" , type = "float" , default = 10000 | units .yr ,
152- help = "end time of the simulation [%default]" )
153- return result
154-
155-
156- def main ():
157- o , arguments = new_option_parser ().parse_args ()
158- numpy .random .seed (123 )
159- gravity_hydro_bridge (** o .__dict__ )
160-
161-
162- if __name__ in ('__main__' , '__plot__' ):
166+
167+ def new_argument_parser ():
168+ parser = argparse .ArgumentParser (
169+ formatter_class = argparse .ArgumentDefaultsHelpFormatter
170+ )
171+ parser .add_argument (
172+ "-n" ,
173+ "--n_steps" ,
174+ type = int ,
175+ default = 1000 ,
176+ help = "number of diagnostics time steps" ,
177+ )
178+ parser .add_argument (
179+ "-N" ,
180+ "--Ngas" ,
181+ type = int ,
182+ default = 1024 ,
183+ help = "number of gas particles" ,
184+ )
185+ parser .add_argument (
186+ "--Mprim" ,
187+ type = units .MSun ,
188+ dest = "Mprim" ,
189+ default = 3.2 | units .MSun ,
190+ help = "Mass of the primary star" ,
191+ )
192+ parser .add_argument (
193+ "--Msec" ,
194+ type = units .MSun ,
195+ dest = "Msec" ,
196+ default = 3.1 | units .MSun ,
197+ help = "Mass of the secondary star" ,
198+ )
199+ parser .add_argument (
200+ "-M" ,
201+ type = units .MSun ,
202+ dest = "Mgas" ,
203+ default = 1 | units .MSun ,
204+ help = "Mass of the gas" ,
205+ )
206+ parser .add_argument (
207+ "-R" ,
208+ type = units .au ,
209+ dest = "Rgas" ,
210+ default = 10 | units .au ,
211+ help = "Size of the gas distribution" ,
212+ )
213+ parser .add_argument (
214+ "-a" ,
215+ type = units .au ,
216+ dest = "a" ,
217+ default = 1 | units .au ,
218+ help = "initial orbital separation" ,
219+ )
220+ parser .add_argument (
221+ "-e" ,
222+ dest = "ecc" ,
223+ type = float ,
224+ default = 0.6 ,
225+ help = "initial orbital eccentricity" ,
226+ )
227+ parser .add_argument (
228+ "-t" ,
229+ type = units .yr ,
230+ dest = "time_end" ,
231+ default = 10000 | units .yr ,
232+ help = "end time of the simulation" ,
233+ )
234+ return parser
235+
236+
237+ def main ():
238+ args = new_argument_parser ().parse_args ()
239+ np .random .seed (123 )
240+ gravity_hydro_bridge (** args .__dict__ )
241+
242+
243+ if __name__ == "__main__" :
163244 main ()
0 commit comments