4 import pluto_files_IO
as pfIO
7 def __init__(self, work_dir, pluto_dir, auto_update):
8 """Defines the problem for the PLUTO code.
10 This class essentially creates the definitions.h file
11 based on the inputs given by the user from the PlutoSetup menu.
12 In case the header file is already present, this class will
13 read those default values to re-create the file.
16 1. work_dir = Path to PLUTO code working directory
17 2. pluto_dir = Path to PLUTO source directory
18 3. auto-update = Boolean that indicates auto-update of definitions.h file.
21 It generates a definitions.h file.
38 self.
entries = [
'PHYSICS',
'DIMENSIONS',
'COMPONENTS',
'GEOMETRY',
39 'BODY_FORCE',
'COOLING',
'RECONSTRUCTION',
'TIME_STEPPING',
40 'DIMENSIONAL_SPLITTING',
'NTRACER',
'USER_DEF_PARAMETERS']
41 self.
default = [
'HD',
'1',
'1',
'CARTESIAN',
'NO',
46 flag_keys = [
'WITH-CHOMBO',
'FULL',
'WITH-FD',
'WITH-SB',
'WITH-FARGO']
48 self.flag_dict = {
'WITH-CHOMBO':
False,
'FULL':
False,
'WITH-FD':
False,
'WITH-SB':
False,
'WITH-FARGO':
False}
51 if arg[2:].upper()
in flag_keys:
52 self.flag_dict[arg[2:].upper()] =
True
53 elif arg[2:] ==
'with-chombo:':
54 self.flag_dict[
'WITH-CHOMBO'] =
True
62 if True in self.flag_dict.values():
70 if self.
default[self.entries.index(
'PHYSICS')] ==
'HD':
73 self.eos = self.
default_HD[self.entries_HD.index(
'EOS')]
75 if self.
default[self.entries.index(
'PHYSICS')] ==
'RHD':
78 self.eos = self.
default_RHD[self.entries_RHD.index(
'EOS')]
80 if self.
default[self.entries.index(
'PHYSICS')] ==
'MHD':
83 self.eos = self.
default_MHD[self.entries_MHD.index(
'EOS')]
85 if self.
default[self.entries.index(
'PHYSICS')] ==
'RMHD':
88 self.eos = self.
default_RMHD[self.entries_RMHD.index(
'EOS')]
93 self.udef_const_vals = []
94 self.nparam = int(self.
default[self.entries.index(
'USER_DEF_PARAMETERS')])
104 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
109 oldKeys_ = [
'INTERPOLATION',
'MHD_FORMULATION',
'RESISTIVE_MHD']
110 replaceKeys_ = [
'RECONSTRUCTION',
'DIVB_CONTROL',
'RESISTIVITY']
111 if (os.path.exists(self.
work_dir+
'/definitions.h')):
112 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
113 for i
in range(len(oldKeys_)):
114 pf.ReplaceWord(oldKeys_[i], replaceKeys_[i])
117 """Creates a default option list.
119 This method of class DefineProblem will create a
120 default valued options list for each entry in the
121 entries list. These are essentially the options
122 that will be browsed in the Pluto Setup Menu.
124 phylist = [
'ADVECTION',
'HD',
'RHD',
'MHD',
'RMHD']
125 dimlist = [
'1',
'2',
'3']
126 comlist = [
'1',
'2',
'3']
127 geolist = [
'CARTESIAN',
'CYLINDRICAL',
'POLAR',
'SPHERICAL']
128 bfolist = [
'NO',
'VECTOR',
'POTENTIAL',
'(VECTOR+POTENTIAL)']
129 coolist = [
'NO',
'POWER_LAW',
'TABULATED',
'SNEq',
'MINEq',
'H2_COOL']
131 intlist = [
'FLAT',
'LINEAR',
'LimO3',
'WENO3',
'PARABOLIC']
132 tmslist = [
'EULER',
'RK2',
'RK3',
'HANCOCK',
'CHARACTERISTIC_TRACING']
133 dislist = [
'YES',
'NO']
134 ntrlist = [
'%d'%n
for n
in range(9)]
135 udplist = [
'%d'%n
for n
in range(32)]
136 udclist = [
'%d'%n
for n
in range(32)]
138 self.
options = [phylist, dimlist, comlist, geolist, bfolist,
139 coolist, intlist, tmslist,
140 dislist, ntrlist, udplist,
144 """Modify options and default list based on command-line flags.
146 This method is called after generation of default option list.
147 It modifies the members of the options list and if required
148 also the default list based on the conditions required by
149 the flags set using system arguments.
151 if self.flag_dict[
'FULL']:
152 self.
options[self.entries.index(
'RECONSTRUCTION')] = [
'FLAT',
'LINEAR',
'LimO3',
'WENO3',
'PARABOLIC',
'MP5']
154 if self.flag_dict[
'WITH-CHOMBO']:
155 self.
options[self.entries.index(
'GEOMETRY')] = [
'CARTESIAN',
'CYLINDRICAL',
'POLAR',
'SPHERICAL']
156 self.
options[self.entries.index(
'RECONSTRUCTION')] = [
'FLAT',
'LINEAR',
'WENO3',
'PARABOLIC']
157 self.
options[self.entries.index(
'TIME_STEPPING')] = [
'EULER',
'HANCOCK',
'CHARACTERISTIC_TRACING',
'RK2']
158 self.
default[self.entries.index(
'TIME_STEPPING')] =
'HANCOCK'
159 self.
options[self.entries.index(
'DIMENSIONAL_SPLITTING')] = [
'NO']
160 self.
default[self.entries.index(
'DIMENSIONAL_SPLITTING')] =
'NO'
162 if self.flag_dict[
'WITH-FARGO']:
163 self.
options[self.entries.index(
'PHYSICS')] = [
'HD',
'MHD']
164 self.
options[self.entries.index(
'DIMENSIONS')] = [
'2',
'3']
165 self.
default[self.entries.index(
'DIMENSIONS')] =
'2'
166 self.
options[self.entries.index(
'DIMENSIONAL_SPLITTING')] = [
'NO']
167 self.
default[self.entries.index(
'DIMENSIONAL_SPLITTING')] =
'NO'
170 if self.flag_dict[
'WITH-FD']:
171 self.
options[self.entries.index(
'PHYSICS')] = [
'HD',
'MHD']
172 self.
options[self.entries.index(
'GEOMETRY')] = [
'CARTESIAN']
173 self.
options[self.entries.index(
'RECONSTRUCTION')] = [
'WENO3_FD',
'WENOZ_FD',
'MP5_FD',
'LIMO3_FD']
174 self.
default[self.entries.index(
'RECONSTRUCTION')] =
'WENOZ_FD'
175 self.
options[self.entries.index(
'TIME_STEPPING')] = [
'RK3',
'SSP_RK4']
176 self.
default[self.entries.index(
'TIME_STEPPING')] =
'RK3'
179 if self.flag_dict[
'WITH-SB']:
180 self.
options[self.entries.index(
'PHYSICS')] = [
'HD',
'MHD']
181 self.
default[self.entries.index(
'PHYSICS')] =
'MHD'
182 self.
options[self.entries.index(
'DIMENSIONS')] = [
'2',
'3']
183 self.
default[self.entries.index(
'DIMENSIONS')] =
'2'
184 self.
options[self.entries.index(
'COMPONENTS')] = [
'2',
'3']
185 self.
default[self.entries.index(
'COMPONENTS')] =
'2'
186 self.
options[self.entries.index(
'BODY_FORCE')] = [
'VECTOR',
'POTENTIAL',
'(VECTOR+POTENTIAL)']
187 self.
default[self.entries.index(
'BODY_FORCE')] =
'VECTOR'
190 def ReadOrBrowse(self, Ents=None, Opts=None, Defs=None, MenuTitle=None):
191 """Reads or Browses the entries, options and defaults to create header file.
193 This method either reads the already exsisting definitions.h file or browses
194 throught the three lists which are provided as inputs.
197 1. Ents = List of entries. [None]
198 2. Opts = List of options corresponding to each member in Ents [None]
199 3. Defs = List of default value from Opts corresponding to each member in Ents [None]
200 4. MenuTitle = Title for the Menu to be Browsed [None]
202 if (os.path.exists(self.
work_dir+
'/definitions.h')):
203 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
204 pf.UpdateListFromFile(Ents, Defs)
205 for i
in range(len(Ents)):
206 if Defs[i]
not in Opts[i]:
215 selection =
menu.Browse(Ents, default=Defs, options=Opts)
219 Provides entries, options and defaults specific to Hydro Module.
220 Also updates them accordingly if required by flags.
223 'THERMAL_CONDUCTION',
232 [
'NO',
'SELECTIVE',
'ALWAYS',
'CHOMBO_REGRID'],
233 [
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],
234 [
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],
237 if self.flag_dict[
'WITH-CHOMBO']:
239 i = self.entries_HD.index(
'THERMAL_CONDUCTION')
241 i = self.entries_HD.index(
'VISCOSITY')
246 Provides entries, options and defaults specific to Relativistic
247 Hydro Module. Also updates them accordingly if required by flags.
253 [
'NO',
'SELECTIVE',
'ALWAYS',
'CHOMBO_REGRID']]
257 Provides entries, options and defaults specific to Magneto-
258 Hydro Module.Also updates them accordingly if required by flags.
260 self.
entries_MHD = [
'EOS',
'ENTROPY_SWITCH',
'DIVB_CONTROL',
'BACKGROUND_FIELD',
261 'RESISTIVITY',
'THERMAL_CONDUCTION',
'VISCOSITY',
'ROTATING_FRAME']
262 self.
default_MHD = [
'IDEAL',
'NO',
'EIGHT_WAVES',
'NO',
'NO',
'NO',
'NO',
'NO']
265 [
'NO',
'SELECTIVE',
'ALWAYS',
'CHOMBO_REGRID'],
266 [
'NO',
'EIGHT_WAVES',
'DIV_CLEANING',
'CONSTRAINED_TRANSPORT'],
267 [
'NO',
'YES'],[
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],
268 [
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],[
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],[
'NO',
'YES']]
270 if self.flag_dict[
'WITH-CHOMBO']:
271 indx_ = self.entries_MHD.index(
'DIVB_CONTROL')
272 self.
options_MHD[indx_] = [
'NO',
'EIGHT_WAVES',
'DIV_CLEANING']
273 indx_ = self.entries_MHD.index(
'RESISTIVITY')
275 indx_ = self.entries_MHD.index(
'THERMAL_CONDUCTION')
277 indx_ = self.entries_MHD.index(
'VISCOSITY')
280 if self.flag_dict[
'WITH-FD']:
281 indx_ = self.entries_MHD.index(
'DIVB_CONTROL')
282 self.
options_MHD[indx_] = [
'NO',
'EIGHT_WAVES',
'DIV_CLEANING']
284 if self.flag_dict[
'WITH-SB']
or self.flag_dict[
'WITH-FARGO']:
285 indx_ = self.entries_MHD.index(
'DIVB_CONTROL')
286 self.
options_MHD[indx_] = [
'CONSTRAINED_TRANSPORT']
291 Provides entries, options and defaults specific to Relativisitc
292 Magneto-Hydro Module.Also updates them accordingly if required by flags.
298 [
'NO',
'SELECTIVE',
'ALWAYS',
'CHOMBO_REGRID'],
299 [
'NO',
'EIGHT_WAVES',
'DIV_CLEANING',
'CONSTRAINED_TRANSPORT']]
301 if self.flag_dict[
'WITH-CHOMBO']:
302 indx_ = self.entries_RMHD.index(
'DIVB_CONTROL')
303 self.
options_RMHD[indx_] = [
'NO',
'EIGHT_WAVES',
'DIV_CLEANING']
307 Sets the Userdefined parameters
309 self.
udef_params = [
'USER_PAR_%.2d'%i
for i
in range(self.nparam)]
310 if (os.path.exists(self.
work_dir+
'/definitions.h')):
311 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
312 scrh = pf.LocateString(
'parameters')
314 par_lines = pf.ReadLines(k0, k0 + self.nparam)
315 for n
in range(self.nparam):
317 x = par_lines[n].split()
322 if (x[0] ==
"#define"):
328 menu.SetTitle (
"User-defined Parameters")
329 par_entries = [
'%d'%i
for i
in range(self.nparam)]
338 Sets the Userdefined Constants.
340 if (os.path.exists(self.
work_dir+
'/definitions.h')):
341 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
342 old_beg_scrh = pf.LocateString(
'symbolic')
348 del_indx = pf.LocateString(
'USER_DEF_CONSTANTS')
349 pf.DeleteLines(del_indx[0][0], del_indx[0][0])
350 old_beg_scrh = pf.LocateString(
'symbolic')
351 pf.ReplaceLine(
'/* [Beg] user-defined constants (do not change this line) */', old_beg_scrh[0][0])
352 old_end_scrh = pf.LocateString(
'supplementary')
353 pf.InsertLine(
'/* [End] user-defined constants (do not change this line) */', old_end_scrh[0][0] - 1)
355 scrh_beg = pf.LocateString(
'[Beg]')
356 k_beg = scrh_beg[0][0]+1
357 scrh_end = pf.LocateString(
'[End]')
358 k_end = scrh_end[0][0]-1
359 const_lines = pf.ReadLines(k_beg, k_end)
361 for n
in range(len(const_lines)):
362 x = const_lines[n].split()
368 if (x[0] ==
'#define'):
369 self.udef_const.append(x[1])
370 self.udef_const_vals.append(x[2])
377 Sets the non-user friendly constants.
379 tmplist1 = [
'INITIAL_SMOOTHING',
'WARNING_MESSAGES',
'PRINT_TO_FILE',
380 'INTERNAL_BOUNDARY',
'SHOCK_FLATTENING']
381 tmplist2 = len(tmplist1)*[
'NO']
387 if not self.flag_dict[
'WITH-FD']:
388 tmplist1 = tmplist1 + [
'CHAR_LIMITING',
'LIMITER']
389 tmplist2 = tmplist2 + [
'NO',
'DEFAULT']
392 divb_mode = self.
mod_default[self.mod_entries.index(
'DIVB_CONTROL')]
393 if divb_mode ==
'CONSTRAINED_TRANSPORT':
394 tmplist1 = tmplist1 + [
'CT_EMF_AVERAGE',
'CT_EN_CORRECTION',
'ASSIGN_VECTOR_POTENTIAL']
395 tmplist2 = tmplist2 + [
'UCT_HLL',
'NO',
'NO']
397 tmplist1 = tmplist1 + [
'ASSIGN_VECTOR_POTENTIAL']
398 tmplist2 = tmplist2 + [
'NO']
400 if not self.flag_dict[
'WITH-CHOMBO']:
401 tmplist1 = tmplist1 + [
'UPDATE_VECTOR_POTENTIAL']
402 tmplist2 = tmplist2 + [
'NO']
406 tmplist1 = tmplist1 + [
'PRIMITIVE_HANCOCK']
407 tmplist2 = tmplist2 + [
'NO']
409 tmplist1 = tmplist1 + [
'PRIMITIVE_HANCOCK']
410 tmplist2 = tmplist2 + [
'YES']
412 longword =
max(len(w)
for w
in tmplist1)
414 if (os.path.exists(self.
work_dir+
'/definitions.h')):
415 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
416 pf.UpdateListFromFile(tmplist1, tmplist2)
418 self.
non_usfr = [
'#define '+tmplist1[i].ljust(longword+3)+tmplist2[i]+
'\n' for i
in range(len(tmplist1))]
422 Adds additional object files based on
423 modular defintions and requirements.
425 interp_mode = self.
default[self.entries.index(
'RECONSTRUCTION')]
427 if interp_mode ==
'LINEAR':
428 self.additional_files.append(
'plm_states.o')
429 elif interp_mode ==
'PARABOLIC':
430 self.additional_files.append(
'ppm_states.o')
431 self.additional_files.append(
'ppm_coeffs.o')
432 self.header_files.append(
'ppm_coeffs.h')
433 elif interp_mode
in [
'FLAT',
'LimO3',
'WENO3']:
434 self.additional_files.append(interp_mode.lower()+
'_states.o')
438 if self.flag_dict[
'WITH-FD']:
441 if self.
default[self.entries.index(
'COOLING')]
not in [
'NO',
'POWER_LAW']:
445 self.additional_files.append(
'vec_pot_diff.o')
446 if not self.flag_dict[
'WITH-CHOMBO']:
447 self.additional_files.append(
'vec_pot_update.o')
449 if self.flag_dict[
'WITH-CHOMBO']:
450 if self.
default[self.entries.index(
'TIME_STEPPING')]
in [
'EULER',
'RK2']:
451 self.additional_files.append(
'PatchEuler.o')
452 self.additional_files.append(
'update_stage.o')
454 self.additional_files.append(
'PatchCTU.o')
456 cmset = set([
'CHARACTERISTIC_TRACING',
'HANCOCK']) & set(self.
default)
457 if len(cmset) != 0
and self.
default[self.entries.index(
'DIMENSIONAL_SPLITTING')] ==
'NO':
458 self.additional_files.append(
'ctu_step.o')
459 elif self.
default[self.entries.index(
'TIME_STEPPING')] ==
'SSP_RK4':
460 self.additional_files.append(
'unsplit.ssprk.o')
462 self.additional_files.append(
'rk_step.o')
463 self.additional_files.append(
'update_stage.o')
466 self.additional_files.append(
'hancock.o')
468 if 'CHARACTERISTIC_TRACING' in self.
default:
469 self.additional_files.append(
'char_tracing.o')
475 self.additional_files.append(
'parabolic_flux.o')
480 Adds additional C flags and path to 'makefile' based on
481 modular defintions and requirements.
483 self.pluto_path.append(self.
phymodule+
'/')
485 dis_eff = [
'Dust',
'Thermal_Conduction',
'Viscosity']
488 self.pluto_path.append(de+
'/')
491 divb_mode = self.
mod_default[self.mod_entries.index(
'DIVB_CONTROL')]
492 if divb_mode ==
'CONSTRAINED_TRANSPORT':
493 self.pluto_path.append(
'MHD/CT/')
494 elif divb_mode ==
'DIV_CLEANING':
495 self.pluto_path.append(
'MHD/GLM/')
500 self.pluto_path.append(
'MHD/Resistivity/')
502 if self.flag_dict[
'WITH-SB']:
503 self.pluto_path.append(
'MHD/ShearingBox/')
504 self.additional_flags.append(
' -DSHEARINGBOX')
506 if self.flag_dict[
'WITH-FARGO']:
507 self.pluto_path.append(
'Fargo/')
508 self.additional_flags.append(
' -DFARGO')
510 if self.flag_dict[
'WITH-FD']:
511 self.additional_flags.append(
' -DFINITE_DIFFERENCE')
513 cool_mode = self.
default[self.entries.index(
'COOLING')]
514 if cool_mode !=
'NO':
515 if cool_mode ==
'TABULATED':
516 self.pluto_path.append(
'Cooling/TABULATED/')
517 elif cool_mode ==
'POWER_LAW':
518 self.pluto_path.append(
'Cooling/Power_Law/')
520 self.pluto_path.append(
'Cooling/'+ cool_mode +
'/')
526 tmp1 = self.eos[0]+self.eos[1:].lower()
527 self.pluto_path.append(
'EOS/'+tmp1+
'/')
531 Updates pluto.ini file with values of UserDefined Parameters
533 pf = pfIO.PlutoFiles(self.
work_dir+
'/pluto.ini')
534 scrh = pf.LocateString(
'[Parameters]')
538 print "Parameters keyword not found in pluto.ini"
543 ipos = scrh[0][0] + 2
544 tmplist1 = pf.ReadLines(ipos,100)
548 if (len(x.split()) == 0):
continue
549 paradict.update({x.split()[0]:x.split()[1]})
551 cmmval = x.split()[2]
556 if cmmval ==
'#' or cmmval.startswith(
'#'):
557 cmms.append(
' '.join(x.split()[2:]))
562 if x
in paradict.keys():
563 pf.InsertLine(x.ljust(21) + paradict[x] +
' '+cmms[self.udef_params.index(x)]+
'\n', ipos)
566 cmms[self.udef_params.index(x)]
568 pf.InsertLine(x.ljust(21) +
'0.0' +
'\n', ipos)
570 pf.InsertLine(x.ljust(21) +
'0.0'+
' '+cmms[self.udef_params.index(x)]+
'\n', ipos)
572 pf.DeleteLines(ipos,ipos+100)
576 Writes all modular entries, options, defaults into a list.
579 self.def_file_list.append(
'#define '+x.ljust(21)+
' '+self.
default[self.entries.index(x)]+
'\n')
581 self.def_file_list.append(
'\n/* -- physics dependent declarations -- */\n\n')
588 self.def_file_list.append(
'#define '+x.ljust(21)+
' '+ self.
mod_default[self.mod_entries.index(x)]+
'\n')
595 self.def_file_list.append(
'\n/* -- user-defined parameters (labels) -- */\n\n')
597 self.def_file_list.append(
'#define '+x.ljust(21)+
' '+
'%d'%self.udef_params.index(x)+
'\n')
602 self.def_file_list.append(
'\n/* [Beg] user-defined constants (do not change this line) */\n\n')
603 for i
in range(len(self.udef_const)):
604 self.def_file_list.append(
'#define '+self.udef_const[i].ljust(21)+
' '+self.udef_const_vals[i]+
'\n')
606 self.def_file_list.append(
'\n/* [End] user-defined constants (do not change this line) */\n')
608 self.def_file_list.append(
'\n/* -- supplementary constants (user editable) -- */ \n\n')
611 self.def_file_list.append(x)
def WriteDefFileList(self)
def __init__(self, work_dir, pluto_dir, auto_update)
def ProcessRHDModule(self)
def ChkCompatiblity(self)
def AppendPlutoPathAndFlags(self)
def ProcessHDModule(self)
def AppendAdditionalFiles(self)
def ProcessMHDModule(self)
def ProcessRMHDModule(self)
def NonUserFriendlyConst(self)
def ProcessUserDefPara(self)
def ProcessUserDefConst(self)
def GenerateOptionsList(self)