4 import pluto_files_IO
as pfIO
6 class DefineProblem(object):
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.
37 self.
entries = [
'PHYSICS',
'DIMENSIONS',
'COMPONENTS',
'GEOMETRY',
38 'BODY_FORCE',
'COOLING',
'INTERPOLATION',
'TIME_STEPPING',
39 'DIMENSIONAL_SPLITTING',
'NTRACER',
'USER_DEF_PARAMETERS'
41 self.
default = [
'HD',
'1',
'1',
'CARTESIAN',
'NO',
47 flag_keys = [
'WITH-CHOMBO',
'FULL',
'WITH-FD',
'WITH-SB',
'WITH-FARGO']
49 self.flag_dict = {
'WITH-CHOMBO':
False,
'FULL':
False,
'WITH-FD':
False,
'WITH-SB':
False,
'WITH-FARGO':
False}
52 if arg[2:].upper()
in flag_keys:
53 self.flag_dict[arg[2:].upper()] =
True
54 elif arg[2:] ==
'with-chombo:':
55 self.flag_dict[
'WITH-CHOMBO'] =
True
63 if True in self.flag_dict.values():
71 if self.
default[self.entries.index(
'PHYSICS')] ==
'HD':
74 self.eos = self.
default_HD[self.entries_HD.index(
'EOS')]
76 if self.
default[self.entries.index(
'PHYSICS')] ==
'RHD':
79 self.eos = self.
default_RHD[self.entries_RHD.index(
'EOS')]
81 if self.
default[self.entries.index(
'PHYSICS')] ==
'MHD':
84 self.eos = self.
default_MHD[self.entries_MHD.index(
'EOS')]
86 if self.
default[self.entries.index(
'PHYSICS')] ==
'RMHD':
89 self.eos = self.
default_RMHD[self.entries_RMHD.index(
'EOS')]
91 if self.
default[self.entries.index(
'COOLING')] ==
'KROME':
101 self.udef_const_vals = []
102 self.nparam = int(self.
default[self.entries.index(
'USER_DEF_PARAMETERS')])
112 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
116 """Creates a default option list.
118 This method of class DefineProblem will create a
119 default valued options list for each entry in the
120 entries list. These are essentially the options
121 that will be browsed in the Pluto Setup Menu.
123 phylist = [
'ADVECTION',
'HD',
'RHD',
'MHD',
'RMHD']
124 dimlist = [
'1',
'2',
'3']
125 comlist = [
'1',
'2',
'3']
126 geolist = [
'CARTESIAN',
'CYLINDRICAL',
'POLAR',
'SPHERICAL']
127 bfolist = [
'NO',
'VECTOR',
'POTENTIAL',
'(VECTOR+POTENTIAL)']
128 coolist = [
'NO',
'POWER_LAW',
'TABULATED',
'SNEq',
'MINEq',
'H2_COOL',
'KROME']
130 intlist = [
'FLAT',
'LINEAR',
'LimO3',
'WENO3',
'PARABOLIC']
131 tmslist = [
'EULER',
'RK2',
'RK3',
'HANCOCK',
'CHARACTERISTIC_TRACING']
132 dislist = [
'YES',
'NO']
133 ntrlist = [
'%d'%n
for n
in range(5)]
134 udplist = [
'%d'%n
for n
in range(32)]
135 udclist = [
'%d'%n
for n
in range(32)]
137 self.
options = [phylist, dimlist, comlist, geolist, bfolist,
138 coolist, intlist, tmslist,
139 dislist, ntrlist, udplist,
143 """Modify options and default list based on command-line flags.
145 This method is called after generation of default option list.
146 It modifies the members of the options list and if required
147 also the default list based on the conditions required by
148 the flags set using system arguments.
150 if self.flag_dict[
'FULL']:
151 self.
options[self.entries.index(
'INTERPOLATION')] = [
'FLAT',
'LINEAR',
'LimO3',
'WENO3',
'PARABOLIC',
'MP5']
153 if self.flag_dict[
'WITH-CHOMBO']:
154 self.
options[self.entries.index(
'GEOMETRY')] = [
'CARTESIAN',
'CYLINDRICAL',
'POLAR',
'SPHERICAL']
155 self.
options[self.entries.index(
'INTERPOLATION')] = [
'FLAT',
'LINEAR',
'WENO3',
'PARABOLIC']
156 self.
options[self.entries.index(
'TIME_STEPPING')] = [
'EULER',
'HANCOCK',
'CHARACTERISTIC_TRACING',
'RK2']
157 self.
default[self.entries.index(
'TIME_STEPPING')] =
'HANCOCK'
158 self.
options[self.entries.index(
'DIMENSIONAL_SPLITTING')] = [
'NO']
159 self.
default[self.entries.index(
'DIMENSIONAL_SPLITTING')] =
'NO'
161 if self.flag_dict[
'WITH-FARGO']:
162 self.
options[self.entries.index(
'PHYSICS')] = [
'HD',
'MHD']
163 self.
options[self.entries.index(
'DIMENSIONS')] = [
'2',
'3']
164 self.
default[self.entries.index(
'DIMENSIONS')] =
'2'
165 self.
options[self.entries.index(
'DIMENSIONAL_SPLITTING')] = [
'NO']
166 self.
default[self.entries.index(
'DIMENSIONAL_SPLITTING')] =
'NO'
169 if self.flag_dict[
'WITH-FD']:
170 self.
options[self.entries.index(
'PHYSICS')] = [
'HD',
'MHD']
171 self.
options[self.entries.index(
'GEOMETRY')] = [
'CARTESIAN']
172 self.
options[self.entries.index(
'INTERPOLATION')] = [
'WENO3_FD',
'WENOZ_FD',
'MP5_FD',
'LIMO3_FD']
173 self.
default[self.entries.index(
'INTERPOLATION')] =
'WENOZ_FD'
174 self.
options[self.entries.index(
'TIME_STEPPING')] = [
'RK3']
175 self.
default[self.entries.index(
'TIME_STEPPING')] =
'RK3'
178 if self.flag_dict[
'WITH-SB']:
179 self.
options[self.entries.index(
'PHYSICS')] = [
'HD',
'MHD']
180 self.
default[self.entries.index(
'PHYSICS')] =
'MHD'
181 self.
options[self.entries.index(
'DIMENSIONS')] = [
'2',
'3']
182 self.
default[self.entries.index(
'DIMENSIONS')] =
'2'
183 self.
options[self.entries.index(
'COMPONENTS')] = [
'2',
'3']
184 self.
default[self.entries.index(
'COMPONENTS')] =
'2'
185 self.
options[self.entries.index(
'BODY_FORCE')] = [
'VECTOR',
'POTENTIAL',
'(VECTOR+POTENTIAL)']
186 self.
default[self.entries.index(
'BODY_FORCE')] =
'VECTOR'
189 def ReadOrBrowse(self, Ents=None, Opts=None, Defs=None, MenuTitle=None):
190 """Reads or Browses the entries, options and defaults to create header file.
192 This method either reads the already exsisting definitions.h file or browses
193 throught the three lists which are provided as inputs.
196 1. Ents = List of entries. [None]
197 2. Opts = List of options corresponding to each member in Ents [None]
198 3. Defs = List of default value from Opts corresponding to each member in Ents [None]
199 4. MenuTitle = Title for the Menu to be Browsed [None]
201 if (os.path.exists(self.
work_dir+
'/definitions.h')):
202 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
203 pf.UpdateListFromFile(Ents, Defs)
204 for i
in range(len(Ents)):
205 if Defs[i]
not in Opts[i]:
214 selection =
menu.Browse(Ents, default=Defs, options=Opts)
218 Provides entries, options and defaults specific to Hydro Module.
219 Also updates them accordingly if required by flags.
221 self.
entries_HD = [
'EOS',
'ENTROPY_SWITCH',
'THERMAL_CONDUCTION',
'VISCOSITY',
'ROTATING_FRAME']
222 self.
default_HD = [
'IDEAL',
'NO',
'NO',
'NO',
'NO']
223 self.
options_HD = [[
'IDEAL',
'PVTE_LAW',
'ISOTHERMAL'], [
'NO',
'YES'], [
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],
224 [
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'], [
'NO',
'YES']]
226 if self.flag_dict[
'WITH-CHOMBO']:
232 Provides entries, options and defaults specific to Relativistic
233 Hydro Module. Also updates them accordingly if required by flags.
235 self.
entries_RHD = [
'EOS',
'ENTROPY_SWITCH',
'USE_FOUR_VELOCITY']
237 self.
options_RHD = [[
'IDEAL',
'TAUB'], [
'NO',
'YES'], [
'NO',
'YES']]
241 Provides entries, options and defaults specific to Magneto-
242 Hydro Module.Also updates them accordingly if required by flags.
244 self.
entries_MHD = [
'EOS',
'ENTROPY_SWITCH',
'MHD_FORMULATION',
'BACKGROUND_FIELD',
245 'RESISTIVE_MHD',
'THERMAL_CONDUCTION',
'VISCOSITY',
'ROTATING_FRAME']
246 self.
default_MHD = [
'IDEAL',
'NO',
'EIGHT_WAVES',
'NO',
'NO',
'NO',
'NO',
'NO']
247 self.
options_MHD = [[
'IDEAL',
'PVTE_LAW',
'ISOTHERMAL'], [
'NO',
'YES'],
248 [
'NONE',
'EIGHT_WAVES',
'DIV_CLEANING',
'CONSTRAINED_TRANSPORT'],
249 [
'NO',
'YES'],[
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],
250 [
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],[
'NO',
'EXPLICIT',
'SUPER_TIME_STEPPING'],[
'NO',
'YES']]
252 if self.flag_dict[
'WITH-CHOMBO']:
253 self.
options_MHD[2] = [
'NONE',
'EIGHT_WAVES',
'DIV_CLEANING']
258 if self.flag_dict[
'WITH-FD']:
259 self.
options_MHD[2] = [
'NONE',
'EIGHT_WAVES',
'DIV_CLEANING']
261 if self.flag_dict[
'WITH-SB']
or self.flag_dict[
'WITH-FARGO']:
267 Provides entries, options and defaults specific to Relativisitc
268 Magneto-Hydro Module.Also updates them accordingly if required by flags.
270 self.
entries_RMHD = [
'EOS',
'ENTROPY_SWITCH',
'MHD_FORMULATION' ]
273 [
'NONE',
'EIGHT_WAVES',
'DIV_CLEANING',
'CONSTRAINED_TRANSPORT']]
275 if self.flag_dict[
'WITH-CHOMBO']:
276 self.
options_RMHD[2] = [
'NONE',
'EIGHT_WAVES',
'DIV_CLEANING']
280 Provides entries, options, and defaults for the KROME cooling module.
282 netwrkfiles = os.listdir(self.
krome_dir+
'/networks/')
283 self.
entries_KROME = [
'NETWORK_FILE',
'USE_N',
'COOLING_TYPE',
'HEATING_TYPE',
'GAMMA_TYPE']
285 self.
options_KROME = [netwrkfiles, [
'NO',
'YES'], [
'NONE',
'H2',
'ATOMIC',
'Z'], [
'NONE',
'COMPRESS',
'PHOTO',
'XRAY'], [
'DEFAULT',
'FULL',
'ROT',
'VIB',
'EXACT',
'REDUCED']]
290 Sets the Userdefined parameters
292 self.
udef_params = [
'USER_PAR_%.2d'%i
for i
in range(self.nparam)]
293 if (os.path.exists(self.
work_dir+
'/definitions.h')):
294 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
295 scrh = pf.LocateString(
'parameters')
297 par_lines = pf.ReadLines(k0, k0 + self.nparam)
298 for n
in range(self.nparam):
300 x = par_lines[n].split()
305 if (x[0] ==
"#define"):
311 menu.SetTitle (
"User-defined Parameters")
312 par_entries = [
'%d'%i
for i
in range(self.nparam)]
317 Sets the Userdefined Constants.
319 if (os.path.exists(self.
work_dir+
'/definitions.h')):
320 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
321 scrh_beg = pf.LocateString(
'User_Constants_Beg')
322 k_beg = scrh_beg[0][0]+1
323 scrh_end = pf.LocateString(
'User_Constants_End')
324 k_end = scrh_end[0][0]-1
325 const_lines = pf.ReadLines(k_beg, k_end)
327 for n
in range(len(const_lines)):
328 x = const_lines[n].split()
334 if (x[0] ==
'#define'):
335 self.udef_const.append(x[1])
336 self.udef_const_vals.append(x[2])
345 Sets the non-user friendly constants.
347 tmplist1 = [
'INITIAL_SMOOTHING',
'WARNING_MESSAGES',
'PRINT_TO_FILE',
'INTERNAL_BOUNDARY',
'SHOCK_FLATTENING']
348 tmplist2 = len(tmplist1)*[
'NO']
350 if self.flag_dict[
'WITH-CHOMBO']:
351 tmplist1 += [
'CHOMBO_EN_SWITCH',
'CHOMBO_REF_VAR',
'CHOMBO_LOGR']
352 tmplist2 += [
'NO',
'ENG',
'NO']
354 if not self.flag_dict[
'WITH-FD']:
355 tmplist1 = tmplist1 + [
'ARTIFICIAL_VISCOSITY',
'CHAR_LIMITING',
'LIMITER']
356 tmplist2 = tmplist2 + [
'NO',
'NO',
'DEFAULT']
359 divb_mode = self.
mod_default[self.mod_entries.index(
'MHD_FORMULATION')]
360 if divb_mode ==
'CONSTRAINED_TRANSPORT':
361 tmplist1 = tmplist1 + [
'CT_EMF_AVERAGE',
'CT_EN_CORRECTION',
'ASSIGN_VECTOR_POTENTIAL']
362 tmplist2 = tmplist2 + [
'UCT_HLL',
'NO',
'YES']
364 tmplist1 = tmplist1 + [
'ASSIGN_VECTOR_POTENTIAL']
365 tmplist2 = tmplist2 + [
'NO']
367 if not self.flag_dict[
'WITH-CHOMBO']:
368 tmplist1 = tmplist1 + [
'UPDATE_VECTOR_POTENTIAL']
369 tmplist2 = tmplist2 + [
'NO']
373 tmplist1 = tmplist1 + [
'PRIMITIVE_HANCOCK']
374 tmplist2 = tmplist2 + [
'NO']
376 tmplist1 = tmplist1 + [
'PRIMITIVE_HANCOCK']
377 tmplist2 = tmplist2 + [
'YES']
380 tmplist1 = tmplist1 + [
'STS_nu']
381 tmplist2 = tmplist2 + [
'0.01']
383 longword =
max(len(w)
for w
in tmplist1)
385 if (os.path.exists(self.
work_dir+
'/definitions.h')):
386 pf = pfIO.PlutoFiles(self.
work_dir+
'/definitions.h')
387 pf.UpdateListFromFile(tmplist1, tmplist2)
389 self.
non_usfr = [
'#define '+tmplist1[i].ljust(longword+3)+tmplist2[i]+
'\n' for i
in range(len(tmplist1))]
393 Adds additional object files based on
394 modular defintions and requirements.
396 interp_mode = self.
default[self.entries.index(
'INTERPOLATION')]
398 if interp_mode ==
'LINEAR':
399 self.additional_files.append(
'plm_states.o')
400 elif interp_mode ==
'PARABOLIC':
401 self.additional_files.append(
'ppm_states.o')
402 self.additional_files.append(
'ppm_coeffs.o')
403 self.header_files.append(
'ppm_coeffs.h')
404 elif interp_mode
in [
'FLAT',
'LimO3',
'WENO3']:
405 self.additional_files.append(
'states_'+interp_mode.lower()+
'.o')
409 if self.flag_dict[
'WITH-FD']:
412 if self.
default[self.entries.index(
'COOLING')]
not in [
'NO',
'POWER_LAW',
'KROME']:
416 self.additional_files.append(
'vec_pot_diff.o')
417 if not self.flag_dict[
'WITH-CHOMBO']:
418 self.additional_files.append(
'vec_pot_update.o')
420 if self.flag_dict[
'WITH-CHOMBO']:
421 if self.
default[self.entries.index(
'DIMENSIONS')] ==
'1':
422 self.additional_files.append(
'PatchCTU.1D.o')
423 elif self.
default[self.entries.index(
'TIME_STEPPING')]
in [
'EULER',
'RK2']:
424 self.additional_files.append(
'PatchEuler.3D.o')
426 self.additional_files.append(
'PatchCTU.3D.o')
428 cmset = set([
'CHARACTERISTIC_TRACING',
'HANCOCK']) & set(self.
default)
429 if len(cmset) != 0
and self.
default[self.entries.index(
'DIMENSIONAL_SPLITTING')] ==
'NO':
430 self.additional_files.append(
'ctu_update.o')
432 self.additional_files.append(
'rk_update.o')
435 self.additional_files.append(
'hancock.o')
437 if 'CHARACTERISTIC_TRACING' in self.
default:
438 self.additional_files.append(
'char_tracing.o')
444 self.additional_files.append(
'parabolic_flux.o')
449 Adds additional C flags and path to 'makefile' based on
450 modular defintions and requirements.
452 self.pluto_path.append(self.
phymodule+
'/')
454 dis_eff = [
'Thermal_Conduction',
'Viscosity']
457 self.pluto_path.append(de+
'/')
460 divb_mode = self.
mod_default[self.mod_entries.index(
'MHD_FORMULATION')]
461 if divb_mode ==
'CONSTRAINED_TRANSPORT':
462 self.pluto_path.append(
'MHD/CT/')
463 elif divb_mode ==
'DIV_CLEANING':
464 self.pluto_path.append(
'MHD/GLM/')
468 if self.
phymodule ==
'MHD' and self.
mod_default[self.mod_entries.index(
'RESISTIVE_MHD')] !=
'NO':
469 self.pluto_path.append(
'MHD/Resistive/')
471 if self.flag_dict[
'WITH-SB']:
472 self.pluto_path.append(
'MHD/ShearingBox/')
473 self.additional_flags.append(
' -DSHEARINGBOX')
475 if self.flag_dict[
'WITH-FARGO']:
476 self.pluto_path.append(
'Fargo/')
477 self.additional_flags.append(
' -DFARGO')
479 if self.flag_dict[
'WITH-FD']:
480 self.additional_flags.append(
' -DFINITE_DIFFERENCE')
482 cool_mode = self.
default[self.entries.index(
'COOLING')]
483 if cool_mode !=
'NO':
484 if cool_mode ==
'TABULATED':
485 self.pluto_path.append(
'Cooling/Tab/')
486 elif cool_mode ==
'POWER_LAW':
487 self.pluto_path.append(
'Cooling/Power_Law/')
489 self.pluto_path.append(
'Cooling/'+ cool_mode +
'/')
495 tmp1 = self.eos[0]+self.eos[1:].lower()
496 self.pluto_path.append(
'EOS/'+tmp1+
'/')
500 Updates pluto.ini file with values of UserDefined Parameters
502 pf = pfIO.PlutoFiles(self.
work_dir+
'/pluto.ini')
503 scrh = pf.LocateString(
'[Parameters]')
507 print "Parameters keyword not found in pluto.ini"
512 ipos = scrh[0][0] + 2
513 tmplist1 = pf.ReadLines(ipos,100)
517 if (len(x.split()) == 0):
continue
518 paradict.update({x.split()[0]:x.split()[1]})
520 cmmval = x.split()[2]
525 if cmmval ==
'#' or cmmval.startswith(
'#'):
526 cmms.append(
' '.join(x.split()[2:]))
531 if x
in paradict.keys():
532 pf.InsertLine(x.ljust(21) + paradict[x] +
' '+cmms[self.udef_params.index(x)]+
'\n', ipos)
535 cmms[self.udef_params.index(x)]
537 pf.InsertLine(x.ljust(21) +
'0.0' +
'\n', ipos)
539 pf.InsertLine(x.ljust(21) +
'0.0'+
' '+cmms[self.udef_params.index(x)]+
'\n', ipos)
541 pf.DeleteLines(ipos,ipos+100)
548 if self.
default_KROME[self.entries_KROME.index(
'COOLING_TYPE')] !=
'NONE':
551 if self.
default_KROME[self.entries_KROME.index(
'HEATING_TYPE')] !=
'NONE':
554 if self.
default_KROME[self.entries_KROME.index(
'GAMMA_TYPE')] !=
'DEFAULT':
559 Writes all modular entries, options, defaults into a list.
562 self.def_file_list.append(
'#define '+x.ljust(21)+
' '+self.
default[self.entries.index(x)]+
'\n')
564 self.def_file_list.append(
'\n/* -- physics dependent declarations -- */\n\n')
571 self.def_file_list.append(
'#define '+x.ljust(21)+
' '+ self.
mod_default[self.mod_entries.index(x)]+
'\n')
578 self.def_file_list.append(
'\n/* -- user-defined parameters (labels) -- */\n\n')
580 self.def_file_list.append(
'#define '+x.ljust(21)+
' '+
'%d'%self.udef_params.index(x)+
'\n')
585 self.def_file_list.append(
'\n/* -- User_Constants_Beg -- DO NOT REMOVE THIS LINE*/\n\n')
586 for i
in range(len(self.udef_const)):
587 self.def_file_list.append(
'#define '+self.udef_const[i].ljust(21)+
' '+self.udef_const_vals[i]+
'\n')
588 self.def_file_list.append(
'\n/* -- User_Constants_End -- DO NOT REMOVE THIS LINE*/\n\n')
591 self.def_file_list.append(
'\n/* -- supplementary constants (user editable) -- */ \n\n')
594 self.def_file_list.append(x)
def WriteDefFileList(self)
def __init__(self, work_dir, pluto_dir, auto_update)
def ProcessRHDModule(self)
def AppendPlutoPathAndFlags(self)
def ProcessHDModule(self)
def AppendAdditionalFiles(self)
def ProcessMHDModule(self)
def ProcessRMHDModule(self)
def NonUserFriendlyConst(self)
def ProcessKROMEModule(self)
def ProcessUserDefPara(self)
def ProcessUserDefConst(self)
def GenerateOptionsList(self)