-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkromeobj.py
More file actions
9475 lines (8491 loc) · 377 KB
/
Copy pathkromeobj.py
File metadata and controls
9475 lines (8491 loc) · 377 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# KROME is a nice and friendly chemistry package for a wide range of
# astrophysical simulations. Given a chemical network (in CSV format)
# it automatically generates all the routines needed to solve the kinetic
# of the system, modelled as system of coupled Ordinary Differential
# Equations.
# It provides different options which make it unique and very flexible.
# Any suggestions and comments are welcomed. KROME is an open-source
# package, GNU-licensed, and any improvements provided by
# the users is well accepted. See disclaimer below and GNU License
# in gpl-3.0.txt.
#
# more details in http://kromepackage.org/
# also see https://bitbucket.org/krome/krome_stable
#
# Written and developed by Tommaso Grassi
# tgrassi@nbi.dk,
# Starplan Center, Copenhagen.
# Niels Bohr Institute, Copenhagen.
#
# and Stefano Bovino
# stefano.bovino@uni-hamburg.de
# Hamburger Sternwarte, Hamburg.
#
# Contributors: J.Boulangier, T.Frostholm, D.Galli, F.A.Gianturco, T.Haugboelle,
# A.Lupi, J.Prieto, J.Ramsey, D.R.G.Schleicher, D.Seifried, E.Simoncini,
# E.Tognelli
#
# KROME is provided "as it is", without any warranty.
# The Authors assume no liability for any damages of any kind
# (direct or indirect damages, contractual or non-contractual
# damages, pecuniary or non-pecuniary damages), directly or
# indirectly derived or arising from the correct or incorrect
# usage of KROME, in any possible environment, or arising from
# the impossibility to use, fully or partially, the software,
# or any bug or malefunction.
# Such exclusion of liability expressly includes any damages
# including the loss of data of any kind (including personal data)
# THIS FILE CONTAINS THE KROME CLASS
import os
import glob
import shutil
import argparse
import re
import copy
from kromelib import *
from os import listdir
from os.path import isfile, join
class krome:
#set defaults
solver_MF = 222
force_rwork = useHeating = doReport = checkConserv = useFileIdx = buildCompact = useEquilibrium = False
use_implicit_RHS = use_photons = useTabs = useDvodeF90 = useTopology = useFlux = skipDup = False
useCoolingAtomic = useCoolingH2 = useCoolingH2GP98 = useCoolingHD = useCoolingZ = useCoolingNebular = useCoolingDustGRREC = False
useCoolingCompton = useCoolingExpansion = useShieldingDB96 = useShieldingWG11 = useShieldingR14 = useShieldingC = useShieldingCO = useShieldingWG11_withH = False
useCoolingCIE = useCoolingDISS = useCoolingFF = use_cooling = useCoolingDust = useCoolingCont = useCoolingDustSemenov = useCoolingDustSemenov_fixedTdust = False
useCoolingZCIE = useCoolingZCIENOUV = useCoolingZExtended = useCoolingZCIEGF = useCoolingGH = False
useCoolingCO = useCustom = useDustTabs = dustTabsCool = dustTabsH2 = dustTabsAvVariable = False
useCoolingHCN = useCoolingOH = useCoolingH2O = useGOW = False
useReverse = useCustomCoe = useODEConstant = cleanBuild = usePlainIsotopes = useDust = usePhotoDust_3D = False
use_thermo = useStars = useNuclearMult = useCoolingdH = useHeatingdH = useCoolingChem = False
usePhIoniz = useHeatingCompress = useHeatingPhoto = useHeatingChem = useDecoupled = useHeatingAccretion = useHeatingTurbulence = False
useHeatingCR = useHeatingPhotoAv = useHeatingPhotoDust = useHeatingXRay = useThermoToggle = useHeatingPhotoDustNet = useHeatingPhotoDustWD = useHeatingPhotoDustNetWD = False
useX = pedanticMakefile = useFakeOpacity = useConserve = useConserveE = useConserveLin = noExample = useNLEQ = False
usePhotoOpacity = useXRay = hasSurfaceReactions = shieldHabingDust = False
has_plot = doIndent = useTlimits = useODEthermo = safe = doJacobian = sinkCheck = recCheck = shortHead = True
useDustGrowth = useDustSputter = useDustH2 = useDustT = useDustEvap = useDustH2const = False
doRamses = doRamsesTH = doFlash = doEnzo = doGizmo = interfaceC = interfacePy = mergeTlimits = False
isdry = useIERR = checkReverse = usePhotoInduced = checkThermochem = needLAPACK = useCoolFloor = False
useComputeElectrons = useChemisorption = useSemenov = usedTdust = useSurface = useHeatingVisc = False
useHeatingPumpH2 = reducer = useFexCustom = hasStoreOnceRates = useBroadening = False
applyElementConservation_popsicle_semenov = applyElementConservation_popsicle_semenov_photo_full = applyElementConservation_popsicle_semenov_photo_gow = popsicle_ice = popsicle_ice_gow = False
tigressNCR = False
verbatimFilename = "reactions_verbatim.dat"
useVerbatimFile = True
xsecKernelFunction = "" #kernel function for interpolating xsecs
humanFlux = True
dustTableMode = "" #type of dust tables required
dustTableDimension = "2D"
typeGamma = "DEFAULT"
test_name = "default"
test_status = "OK"
is_test = False
TlimitOpLow = "GE"
TlimitOpHigh = "LT"
customCoeFunction = "[CUSTOM COE FUNCTION NOT SET!]"
buildFolder = "build/"
srcFolder = "src/"
TminAuto = 1e99
TmaxAuto = 0e0
H2opacity = "" #H2 opacity model
checkMode = "ALL" #conservation check mode (ALL | [CHARGE],[MASS]| NONE)
RTOL = 1e-4 #default relative tolerance
ATOL = 1e-20 #default absolute tolerance
coolingQuench = -1e0 #if coolingQuench is negative cooling quench is not enabled, otherwise this is Tcrit
dustArraySize = dustTypesSize = photoBins = 0
maxord = 0 #default solver maximum order (0=automatic)
dustTypes = []
specs = []
reacts = []
constantList = []
dummy = molec()
coevars = dict() #variables in function coe() (krome_subs.f90)
coolVars = dict() #variables for custom cooling (krome_cooling.f90)
heatVars = dict() #variables for custom heating (krome_heating.f90)
coevarsODE = dict() #variables in function fex() (krome_ode.f90)
commonvars = [] #list of common variables
implicit_arrays = totMetals = ""
thermodata = dict() #thermochemistry data (nasa polynomials)
parser = filename = ""
deltajacMode = "RELATIVE" #increment mode: RELATIVE or ABSOLUTE
deltajac = "1d-3" #increment (relative or absolute, see deltajacMode)
atols = [] #custom ATOLs
rtols = [] #custom RTOLs
jaca = [] #unrolled sparse jacobian
customODEs = [] #custom ODEs
nrea = 0 #number of reactions
nPhotoRea = 0 #number of photoreactions (for photobin array)
dustSeed = "0d0" #default for dust seed in cm-3
full_cool = vars_cool = ""
coolZ_functions = []
coolZ_rates = []
coolZ_vars_cool = []
coolZ_poplevelvars = [] #population levels variables
fcn_levs = [] #list of number of cooling levels found
coolZ_nkrates = 0
zcoolants = [] #list of cooling read from file (flag name, e.g CII)
Zcools = [] #list of cooling read from file (species name, e.g. C+)
allCoolings = [] #list all coolings names from option
allHeatings = [] #list all heatings names from option
anytabvars = [] #variable names for the tables
anytabfiles = [] #file name for the tables
anytabpaths = [] #paths for the tables
anytabsizes = [] #sizes of the tables
coolLevels = [] #levels employed for cooling, if empty uses all
physVariables = [] #list of the phys variables (list of [variable_name, default_value_string])
kModifier = [] #modifier lines that will be appended after the rate calculation
odeModifier = [] #modifier lines that will be appended after the ODE calculation
photoPartners = dict() #dictionary of the reactants of photoreactions (key is reaction index)
reducerVars = ["ntot", "Tgas","Zmetals"] #variables for the reducer tool interface
columnDensityMethod = "DEFAULT"
compiler = "ifort" #default compiler
ramses_offset = 2 #offset in the array for ramses
photoDustVarAv = "" #variable for visual extinction in the photoelectric heating
photoDustVarG0 = "" #variable for normalization in the photoelectric heating
coolFile = ["data/coolZ.dat"]
customCoolList = [] #list of the custom cooling functions
customHeatList = [] #list of the custom heating functions
individualCoolingFloors = [] #list of individual floors
iceSpeciesList = dict() #list of species on ice
fdbase = "data/database/" #database of reaction folder for auto reactions
thermochemistryFolder = "data/thermochemistry/"
indexSolomon = -1 #default solomon index, -1 to trigger error
indexH2photodissociation = -1 #default H2pd index, -1 to trigger error
KindSingle = "real*4"
KindDouble = "real*8"
KindDoubleValue = "real*8"
KindDoubleValueOptional = "real*8,optional"
KindInteger = "integer"
KindIntegerValue = "integer"
KindBoolValueOptional = "logical,optional"
KindCharacter = "character"
BindC = ""
version = "14.08.dev"
codename = "Beastie Boyle"
#########################################
def checkPrereq(self):
#check for argparse module
try:
import argparse
except:
print("ERROR: you need installed argparse!")
print("You can obtain it by typing (ubuntu users):")
print(" apt-get install python-setuptools")
print(" easy_install argparse")
print("")
print("more details here:")
print(" https://pypi.python.org/pypi/argparse")
sys.exit()
#check python version
ver = sys.version_info
aver = list(ver)
#sver = (".".join([str(x) for x in aver[:3]]))
hver = aver[0] * 1e4 + aver[1] * 1e2 + aver[2]
if hver < 2e4 + 7e2:
print("ERROR: your version of Python ("+ver+") is not supported by KROME!")
print(" KROME needs at least Python 2.7.x!")
sys.exit()
#check necessary files
fles = get_file_list() #get the list of necessary files
for fle in fles:
if os.path.isdir(fle):
continue #do not check folders
if not os.path.isfile(fle):
print("************************************************")
print("WARNING: the file "+fle+" is missing!")
print("Do you want to proceed anyway?")
print("************************************************")
a = keyb_input("Any key to ignore q to quit... ")
if a == "q":
sys.exit()
#########################################
def init_argparser(self):
tests = ", ".join(next(os.walk('tests'))[1])
self.parser = argparse.ArgumentParser(description="KROME a package for astrochemistry and microphysics")
self.parser.add_argument("-ATOL", help="set solver absolute tolerance to the float or double value ATOL, e.g. -atol 1d-40\
Default is ATOL=1d-20, see also -RTOL and -customATOL")
self.parser.add_argument("-compact", action="store_true", help="creates a single fortran file with all the modules instead of\
various file with the different modules. Solver files remain stand-alone (see example make in test/MakefileCompact)")
self.parser.add_argument("-checkConserv", action="store_true", help="check mass conservation during integration (slower)")
self.parser.add_argument("-checkReverse", action="store_true", help="check network for reverse reactions including thermochemistry.\
Output written in build/krome_reverse.log file.")
self.parser.add_argument("-checkThermochem", action="store_true", help="print a warning when thermochemistry data are not found\
for a given species.")
self.parser.add_argument("-clean", action="store_true", help="clean all in /build (including krome_user_commons.f90 that\
is normally kept by default) before creating new f90 files.")
self.parser.add_argument("-columnDensityMethod", metavar="method", help="use an alternative method to \
N=1.8e21*(n*1e-3)**(2./3.) for column density calculation (N) from number density (n). Option available JEANS,\
which employs Jeans length (l) as N=n*l, or JEANS40, which employs the Jeans length capped at 40K (Safranek-Shrader \
et al. 2017).")
#self.parser.add_argument("-compressFluxes", action="store_true", help="in the ODE fluxes are stored in a single variable")
self.parser.add_argument("-computeElectrons", action="store_true", help="computes electrons by balancing charges instead of\
using the differential de/dt.")
self.parser.add_argument("-conserve", action="store_true", help="conserves the species total number and charge global\
neutrality. Works with some limitations, please read the manual.")
self.parser.add_argument("-conserveE", action="store_true", help="conserves the charge global neutrality only.")
self.parser.add_argument("-conserveLin", action="store_true", help="enable hydro-code oriented function to conserve mass using\
a mass-weighted method.")
self.parser.add_argument("-coolFile", metavar='FILENAME', help="select the filename to be used to load external cooling. See\
also tools/lamda2.py script for a LAMDA<->KROME converter. Default FILENAME is data/coolZ.dat, which contains\
fine-strucutre atomic metal cooling for C,O,Si,Fe, and their first ions. It can also be a list of files comma-separated.")
self.parser.add_argument("-cooling", metavar='TERMS', help="cooling options, TERMS can be ATOMIC, H2, HD, Z, DH, DUST, H2GP98,\
COMPTON, EXPANSION, CIE, DISS, NEBULAR, CI, CII, SiI, SiII, OI, OII, FeI, FeII, CHEM, CO (e.g. -\
cooling=ATOMIC,CII,OI,FeI),Z_CIE,Z_CIENOUV,Z_CIEGF,Z_EXTENDED,DUSTGRREC,DUSTSEMENOV.\
Note that further cooling options can be added when reading cooling function from file. If you want a complete list of\
the available cooling options type -cooling=?")
self.parser.add_argument("-coolLevels", metavar='MAXLEV', help="use only the levels up to MAXLEV (included), e.g. -coolLevels=3\
Note that levels are zero-based (i.e. ground state is zero).")
self.parser.add_argument("-coolingQuench", metavar='TCRIT', help="quenches the cooling when T<TCRIT with a tanh \
function.")
self.parser.add_argument("-compiler", metavar='COMPILER', help="changes the Makefile according to the selected COMPILER.")
self.parser.add_argument("-customATOL", help="file with the list of the individual ATOLs in the form SPECIES ATOL in each line,\
e.g. H2 1d-20, see also -ATOL", metavar="filename")
self.parser.add_argument("-customODE", help="file with the list of custom ODEs", metavar="FILENAME")
self.parser.add_argument("-customRTOL", help="file with the list of the individual RTOLs in the form SPECIES RTOL in each line,\
e.g. H3+ 1d-4, see also -RTOL", metavar="filename")
self.parser.add_argument("-gow", action="store_true", help="Whether the GOW (Gong, Ostriker, Wolfire 2017) ISM chemical network is being used")
self.parser.add_argument("-dry", action="store_true", help="dry pre-compilation: does not write anything in the build direactory")
self.parser.add_argument("-dust", help="include dust ODE using N bins for each TYPE, e.g. -dust 10,C,Si set 10 dust carbon\
bins and 10 dust silicon dust bins. Note: requires a call to the krome_init_dust subroutine.\
See -test=dust for an example.")
self.parser.add_argument("-dustOptions", help="activate dust options: (GROWTH) dust growth, (SPUTTER) sputtering, (H2) molecular\
hydrogen formation on dust, (EVAP) thermal evaporation, (T) dust temperature including CMB/radiation coupling,\
and (dT) to use dTdust/dt differential.",\
metavar="OPTIONS")
self.parser.add_argument("-dustTabs", help="activate dust dust tables for: (H2) molecular\
hydrogen formation on dust, and/or (COOL) cooling. Note that this tables depends on the environment (radiation, metallicity,\
dust type, dust power law characteristics, ...). To change enviroment you have to indicate a mode. Details are in the folder\
data/dust_tabs/ in the headers of the files. e.g. -dustTabs=H2,HM2012",
metavar="OPTIONS")
self.parser.add_argument("-dustSeed", help="set the dust seed in 1/cm3 for dust growth. Default is zero. Any F90 expression \
is allowed for SEED.", metavar="SEED")
self.parser.add_argument("-enzo", action="store_true", help="create patches for ENZO")
self.parser.add_argument("-fexArgument", action="store_true", help="add ODE function (fex) as additional argument to \
the main call to KROME")
self.parser.add_argument("-flash", action="store_true", help="create patches for FLASH")
self.parser.add_argument("-forceMF21", action="store_true", help="force explicit sparsity and Jacobian")
self.parser.add_argument("-forceMF222", action="store_true", help="force internal-generated sparsity and Jacobian")
self.parser.add_argument("-forceRWORK", help="force the size of RWORK to N", metavar="N")
self.parser.add_argument("-gamma",help="define the adiabatic index according to OPTION that can be FULL for employing Grassi et al.\
2011, i.e. a density dependent but temperature independent adiabatic index, VIB to keep into account the vibrational\
paritition function, ROT to keep into account the rotational partition function, EXACT to evaluate the\
adiabatic index accurately taking into account both contributions, or REDUCED to use only H2 and CO as diatomic\
molecules (faster). Finally a custom F90 expression e.g. -gamma=\"1d0\"\
can also be used. Default value is 5/3.",metavar="OPTION")
self.parser.add_argument("-gizmo", action="store_true", help="create patches for Gizmo")
self.parser.add_argument("-H2opacity", metavar="TYPE",help="use H2 opacity for H2 cooling, TYPE can be RIPAMONTI or OMUKAI")
self.parser.add_argument("-heating", metavar='TERMS', help="heating options, TERMS can be COMPRESS, PHOTO, CHEM\
, DH, CR, PHOTOAV,VISCOUS,PHOTODUSTNET,PHOTODUSTNETWD,PHOTODUSTWD,ACCRETION,TURBULENCE. If you want a complete list of the available heating options type -heating=?")
self.parser.add_argument("-ierr", action="store_true", help="same as -useIERR")
self.parser.add_argument("-interfaceC", action="store_true", help="create a C wrapper")
self.parser.add_argument("-interfacePy", action="store_true", help="create a Python wrapper (and a C wrapper \
since its a pre-requisite)")
self.parser.add_argument("-iRHS", action="store_true", help="implicit loop-based RHS (suggested for large systems).")
self.parser.add_argument("-lh", action="store_true", help="use long header in f90 files.")
self.parser.add_argument("-listAutomatics", action="store_true", help="list all the automatic reactions available.")
self.parser.add_argument("-listSWRI", action="store_true", help="list all the photo reactions available in the SWRI database.")
self.parser.add_argument("-maxord", help="max order of the BDF solver. Default (and maximum values) is 5.")
self.parser.add_argument("-mergeTlimits", action="store_true", help="use the same reaction index for equivalent\
reactions (same reactants and products) that have different temperature limits")
self.parser.add_argument("-n", help="reaction network file", metavar='FILENAME')
self.parser.add_argument("-network", help="same as -n", metavar='FILENAME')
self.parser.add_argument("-nochargeCheck", action="store_true", help="skip reaction charge check")
self.parser.add_argument("-noCheck", action="store_true", help="skip reaction charge and mass check. Equivalent to\
-nomassCheck -nochargeCheck options.")
self.parser.add_argument("-noExample", action="store_true", help="do not write test.f90 and Makefile in the build directory")
self.parser.add_argument("-nomassCheck", action="store_true", help="skip reaction mass check")
self.parser.add_argument("-noRecCheck", action="store_true", help="skip recombination check (species that do not\
recombine with electrons).")
self.parser.add_argument("-noSinkCheck", action="store_true", help="skip sink check (species that are only formed)")
self.parser.add_argument("-noTlimits", action="store_true", help="ignore rate coefficient temperature limits.")
self.parser.add_argument("-verbatimFilename", metavar='FILENAME', help="path to file with reaction names\
(ignored if -noVerbatimFile is set). Default is `reactions_verbatim.dat`")
self.parser.add_argument("-noVerbatimFile", action="store_true", help="do not read the file with reaction names")
self.parser.add_argument("-nuclearMult", action="store_true", help="keep into account reactants multeplicity, and modify\
fluxes according to this. Intended for nuclear networks.")
self.parser.add_argument("-options", metavar="filename", help="read the options from a file instead of command line\
(in principle you can use both). See options_example file.")
self.parser.add_argument("-pedantic", action="store_true", help="uses a pedantic Makefile (debug purposes)")
self.parser.add_argument("-photoDustVarAv", metavar="common_variable", help="set the name of the common variable that\
is employed for the visual extinction Av to attenuate the photoelectric effect on the dust. It follows\
G0*exp(-2.5*Av) where Av is the variable. The variable should be set in the network file using the token\
@common: user_Av, or any other custom name. This option must be used togheter with -heating=PHOTODUST")
self.parser.add_argument("-photoDustVarG0", metavar="common_variable", help="set the name of the common variable that\
is employed for the normalization G0 to attenuate the photoelectric effect on the dust. It follows\
G0*exp(-2.5*Av) where G0 is the variable. The variable should be set in the network file using the token\
@common: user_G0, or any other custom name. This option must be used togheter with -heating=PHOTODUST")
self.parser.add_argument("-project", help="build everything in a folder called build_NAME instead of building all in the\
default build folder. It also creates a NAME.kpj file with the krome input used.",metavar="NAME")
self.parser.add_argument("-quote", action="store_true", help="print a citation and exit")
self.parser.add_argument("-quotelist", action="store_true", help="print all the citations and exit")
self.parser.add_argument("-ramses", action="store_true", help="create patches for RAMSES, see also -enzo and -flash")
self.parser.add_argument("-ramsesOffset", metavar="offset", help="add an offset to the array of the passive scalar. The\
default is 3.")
self.parser.add_argument("-reducer", action="store_true", help="Create the interface to the reaction reducer (experimental).\
Variables are ntot, Tgas, and all the custom variable set with @common in the network file (i.e. user_*)")
self.parser.add_argument("-ramsesTH", action="store_true", help="create patches for RAMSES_TH. This is a private version\
and probably does not fix your needs.")
self.parser.add_argument("-report", action="store_true", help="generate report file in the main call to krome as\
KROME_ERROR_REPORT and when calling the fex as KROME_ODE_REPORT. It also stores abundances evolution in fex as \
fort.98, and prepares a report.gps gnuplot script file to plot evolutions callable in gnuplot with load \
'report.gps'. Warning: it slows the whole system!")
self.parser.add_argument("-reverse", action="store_true", help="create reverse reaction from the current network\
using NASA polynomials.")
self.parser.add_argument("-fixTdust", action="store_true", help="fix the dust temperature (used in the PDR tests for POPSICLE simulations)")
self.parser.add_argument("-RTOL", help="set solver relative tolerance to the float double value RTOL, e.g.\
-RTOL 1e-5 Default is RTOL=1d-4, see also -ATOL and -customRTOL")
self.parser.add_argument("-photoBins", metavar="NBINS", help="define the number of frequency bins for the impinging radiation.")
self.parser.add_argument("-sh", action="store_true", help="write a shorter header in the f90 files. Now this is the default, \
here for retrocompatibility, see option -lh.")
self.parser.add_argument("-shielding", metavar="TYPE", help="use H2 self-shielding, TYPE can be DB96 for Draine+Bertoldi 1996,\
WG11 for the more accurate Wolcott+Greene 2011, WG11_withH to include cross shielding by H, R14 for the Tgas-dependent by Richings+2014")
self.parser.add_argument("-shielding_CO", action="store_true", help="use CO self-shielding from Visser, van Dishoeck and Black 2009")
self.parser.add_argument("-shielding_C", action="store_true", help="use C cross-shielding by H2 from Tielens and Hollenbach 1985")
self.parser.add_argument("-shieldHabingDust", action="store_true", help="dust shielding for Habing flux \
(when calculated from photobins).")
self.parser.add_argument("-popsicle_ice", action="store_true", help="if the network is using evaporation rate coefficients in cm^-3 s^-1 (used for the popsicle simulations); see evaporation in krome_grfuncs.f90")
self.parser.add_argument("-popsicle_ice_gow", action="store_true", help="if the GOW network is using evaporation rate coefficients in cm^-3 s^-1 (used for the popsicle simulations); see evaporation in krome_grfuncs.f90")
self.parser.add_argument("-tigressNCR", action="store_true", help="flag to use the TIGRESS-NCR hybrid approach for chemistry with non-eq H chemistry and eq C chemistry")
self.parser.add_argument("-applyElementConservation_popsicle_semenov", action="store_true", help="apply element conservation for the popsicle semenov network by replacing ODEs of neutral species")
self.parser.add_argument("-applyElementConservation_popsicle_semenov_photo_full", action="store_true", help="apply element conservation for the popsicle semenov photo+cr network by replacing ODEs of neutral species")
self.parser.add_argument("-applyElementConservation_popsicle_semenov_photo_gow", action="store_true", help="apply element conservation for the popsicle semenov photo+cr GOW network by replacing ODEs of neutral species and electrons")
self.parser.add_argument("-skipDevTest", action="store_true", help="exit if test under development found.")
self.parser.add_argument("-skipDup", action="store_true", help="skip duplicate reactions")
self.parser.add_argument("-skipJacobian", action="store_true", help="do not write Jacobian in krome_ode.f90 file. Useful\
to reduce compilation time when Jacobian is not needed (MF=222).")
self.parser.add_argument("-skipODEthermo", action="store_true", help="do not compute dT/dt in the ODE RHS function (fex)")
self.parser.add_argument("-source", metavar="folder", help="use FOLDER as source directory")
self.parser.add_argument("-stars", action="store_true", help="use star module for nuclear reactions. NOTE: krome_stars\
module required in the Makefile")
self.parser.add_argument("-test",help=("Create a test model in /build. TEST can be: "+tests+"."))
self.parser.add_argument("-Tlimit", metavar="opLow,opHigh", help="set the operators for all the reaction temperature limits\
where opLow is the operator for the first temperature value in the reaction file, and opHigh is for the second one. e.g.\
if the T limits for a given reaction are 10. and 1d4 the option -Tlmit GE,LE will provide (Tgas>=10. AND Tgas<=1d4) as\
the reaction range of validity. Operators opLow and opHigh must be one of the following: LE, GE, LT, GT.")
self.parser.add_argument("-unsafe", action="store_true", help="skip to check if the build folder is empty or not")
self.parser.add_argument("-useBroadening", action="store_true", help="use broadening (note: be careful!).")
self.parser.add_argument("-useCoolFloor", action="store_true", help="include a cooling floor given by the Tfloor temperature.\
note that you must define Tfloor by using the subroutine krome_set_Tfloor(your_Tfloor) before calling krome.")
#self.parser.add_argument("-useCoolCMBFloorZ", action="store_true", help="as -useCoolCMBFloor, but for metals only.")
self.parser.add_argument("-useCustomCoe", help="use a user-defined custom function that returns a real*8 array of size\
NREA = number of reactions, that replaces the standard rate coefficient calculation function. Note that FUNCTION\
must be explicitly included in krome_user_commons module.", metavar="FUNCTION")
self.parser.add_argument("-useAutoNetwork", action="store_true", help="Use a set of instruction to build an automatic network\
instead of a pre-made one. This option changes the behaviour of -n FILENAME into -n INSTRUCTIONS. See\
custom.dat for an example. In this case you should use -n custom.dat -useAutoNetwork")
self.parser.add_argument("-useDustH2const", action="store_true", help="use Jura + Gnedin\
H2 formation on dust, needs user_clump defined. Cannot be used if you enable the dust Options.")
self.parser.add_argument("-useDvodeF90", action="store_true", help="use Dvode implementation in F90 (slower)")
self.parser.add_argument("-useEquilibrium", action="store_true", help="check if the solver has reached the equilbirum.\
If so break the solver's loop and return the values found. It is useful when the system oscillates around\
a solution (as in some photoheating cases). To be used with caution!")
self.parser.add_argument("-useFileIdx", action="store_true", help="use the reaction index in the reaction file instead of\
using the automatic progressive index starting from 1. Useful with rate coefficients that depends on other\
coefficients, e.g. k(10) = 1d-2*k(3)")
self.parser.add_argument("-useIERR", action="store_true",help="use ierr in the interface with KROME to return errors instead\
of stopping the exectution")
self.parser.add_argument("-useIndividualFloor", metavar="TERMS", help="applies a floor definded by Tfloor\
at the single cooling which are specified")
self.parser.add_argument("-useN", action="store_true",help="use number densities as input/ouput instead of\
mass fractions. This is the default.")
self.parser.add_argument("-useX", action="store_true",help="use mass fractions as input/ouput instead of number densities\
(1/cm3)")
self.parser.add_argument("-useODEConstant", help="postpone an expression to each ODE. EXPRESSION must be a valid f90\
expression (e.g. *3.d0 or +1.d-10)", metavar="EXPRESSION")
self.parser.add_argument("-usePhIoniz", action="store_true", help="includes photochemistry (obsolete)")
self.parser.add_argument("-usePhotoInduced", action="store_true", help="includes the photo-induced transitions in the calculation\
of the cooling according to the choosen photon flux.")
self.parser.add_argument("-usePhotoOpacity", action="store_true", help="computes photorates using opacity as a function of \
the species densities and the photo cross sections, i.e. exp(-sum_i N_i*sigma_i). Column densities are computed\
from density by using the local approximation N = 1.8e21*(n/1000)**(2/3) 1/cm2.")
self.parser.add_argument("-usePlainIsotopes", action="store_true", help="use kA format for isotopes instead of [k]A format,\
where k is the isotopic number and A is the atom name, e.g. krome looks for 14C instead of [14]C in the reactions file.")
self.parser.add_argument("-useSemenov", action="store_true", help="use semenov framework for surface chemistry")
self.parser.add_argument("-useThermoToggle", action="store_true", help="include thermal calculation control. Use\
krome_thermo_on and krome_thermo_off to switch on/off the thermal processes (i.e. cooling and heating). Default is on.")
self.parser.add_argument("-useTabs", action="store_true", help="use tabulated rate coefficients (free parameter: temperature)")
self.parser.add_argument("-v", action="store_true", help="print the current version of KROME")
self.parser.add_argument("-ver", action="store_true", help="same as -v")
self.parser.add_argument("-version", action="store_true", help="same as -v")
self.parser.add_argument("-xsecKernelFunction", help="use a function to scale photo cross-sections when interpolated. \
Function has to be a function of energy, i.e. f(energy). Store it in krome_user_commons.f90 module.", \
metavar="FUNCTION")
######################################
#select test name
def select_test(self,argv):
parser = self.parser
args = parser.parse_args()
all_status = ["OK","dev"]
test_status = "OK"
if args.test:
self.is_test = True
else:
return
#read options from file
optionFileName = "tests/" + args.test + "/options.opt"
#check if test folder and option file exist
if not file_exists(optionFileName):
print("ERROR: problem loading test "+args.test+"!")
print(" Missing option.opt file in tests/"+args.test+"/ folder or folder not present.")
#list available tests
tests = (", ".join(sorted(next(os.walk('tests'))[1])))
print(" Available tests are: " + tests)
sys.exit()
#read option file
fh = open(optionFileName)
for row in fh:
srow = row.strip()
#skip comments and blank lines
if srow == "":
continue
if srow.startswith("#"):
continue
#store file name
if srow.startswith("-n "):
(opt, filename) = [x.strip() for x in srow.split(" ") if x!=""]
continue
#store test status if DEV
if srow == "DEV":
test_status = "dev"
continue
#append options to argv
argv.append(srow)
fh.close()
#append extra arguments if listed
# e.g. -dustOptions=H2 -dustOptions=GROWTH is merged in one
argall = dict() #new argv
#loop on arguments
for arg in argv[1:]:
#if arguments have values split and merge
if "=" in arg:
(option, value) = arg.split("=")
#merge or create new
if option in argall:
argall[option] += ","+value
else:
argall[option] = "="+value
else:
#no options just add argument as key
argall[arg] = ""
#prepare the new argv from the dictionary
sys.argv = [argv[0]] + [k+v for (k,v) in argall.items()]
#check if the status of the test is valid
if test_status not in all_status:
sys.exit("ERROR: status "+test_status+" not recognized!")
self.filename = filename #add the network filename
self.test_name = args.test #copy the name of the test
self.test_status = test_status #development status of the test
##########################################
def argparsing(self,argv):
args = self.parser.parse_args() #return namespace from argv
#use short header for f90 files
if args.v or args.ver or args.version:
masterfile = ".git/refs/heads/master" #name of the git master file
print("You are using KROME "+self.version+" \""+self.codename+"\"")
#if git master file existst grep the changeset
if file_exists(masterfile):
changeset = open(masterfile).read()
print("[changeset: "+changeset[:7]+"]\n")
print(" Bye!")
sys.exit()
#use custom option file (load options from a file and append to argv)
if args.options:
fopt = args.options.strip() #get filename
print("Reading option -options=" + fopt)
#check if option file exists
if not file_exists(fopt):
print("ERROR: custom option file \""+fopt+"\" does not exist!")
sys.exit()
trues = ["T","TRUE","1","Y","YES","OK","YEP","SURE"]
falses = ["F","FALSE","0","N","NO","KO","NOPE"]
#read from file
fho = open(fopt,"r")
for row in fho:
srow = row.strip()
if srow == "":
continue #skip blank lines
if srow[0] == "#":
continue #skip comments
if srow[:2] == "//":
continue #skip comments
srow = srow.split("#")[0]
srow = srow.split("//")[0]
srow = srow.strip()
#replace tabs
srow = srow.replace("\t", " ")
#replace double spaces
while " " in srow:
srow = srow.replace(" ", " ")
if srow[0] != "-":
srow = "-"+srow
arow = srow.split()
if len(arow) == 1:
sys.argv.append(arow[0].strip())
continue
elif len(arow) == 2:
if arow[1].strip().upper() in trues:
sys.argv.append(arow[0].strip())
elif arow[1].strip().upper() in falses:
continue
else:
sys.argv.append("=".join([x.strip() for x in arow]))
else:
print("ERROR: problems with option line in option file "+fopt)
print(srow)
sys.exit()
args = self.parser.parse_args() #return updated namespace
#project name folder (required for dev.skip file)
if args.project:
self.projectName = projectName = args.project
print("Reading option -project (name="+str(projectName)+")")
self.buildFolder = "build_"+projectName+"/"
fout = open(projectName+".kpj","w")
fout.write((" ".join(argv)))
fout.close()
#EXIT if development test found and skipDevTest enabled
if args.skipDevTest and self.test_status == "dev":
fh = open(self.buildFolder+"dev.skip","w")
fh.close()
sys.exit("THIS IS A DEV TEST (and -skipDevTest enabled): KROME ENDS!")
#print a warning if the test is under development
if args.test and self.test_status == "dev":
print("************************************************")
print("WARNING: the test \""+self.test_name+"\" is currently")
print(" UNDER DEVELOPMENT and its results could be")
print(" horribly wrong. ")
print(" Some details about the test can be found in the")
print(" test_list file in the main KROME directory.")
print(" Do you want to proceed?")
print("************************************************")
a = keyb_input("Any key to ignore q to quit... ")
if a == "q":
sys.exit()
print("")
#list arguments if test
if args.test:
print("This TEST is running with the following arguments:")
for k in args.__dict__:
arg = args.__dict__[k]
if arg: print(" -"+k+" = "+str(arg))
print(" -n = "+self.filename)
print("")
#list all the automatic reactions available from the files in the fdbase folder and exit
if args.listAutomatics :
os.path.isdir(self.fdbase)
if not file_exists(self.fdbase):
print("ERROR: database directory "+self.fdbase+" not found!")
sys.exit()
file_list = [f for f in listdir(self.fdbase) if isfile(join(self.fdbase,f))]
for fname in file_list:
fname = self.fdbase+fname
print("retriving reactions in "+fname)
fhauto = open(fname,"r")
icounta = 0
reasa = prodsa = typea = ""
for row in fhauto:
srow = row.strip()
if "@type:" in srow:
reasa = prodsa = typea = ""
if reasa != "" and prodsa != "" and typea != "":
icounta += 1
print(str(icounta)+". ("+typea+") "+reasa+" -> "+prodsa)
if "@reacts:" in srow:
reasa = " + ".join([x.strip() for x in srow.replace("@reacts:","").split(",")])
if"@prods:" in srow:
prodsa = " + ".join([x.strip() for x in srow.replace("@prods:","").split(",")])
if "@type:" in srow:
typea = srow.replace("@type:", "").strip()
print("")
sys.exit()
#list all the reactions availbale from the SWRI database files
if args.listSWRI:
swriPath = "data/database/swri_xsecs/"
if not file_exists(swriPath):
print("ERROR: database directory "+swriPath+" not found!")
sys.exit()
print("List of the reactions present in the SWRI datafiles (-listSWRI option):")
file_list = [f for f in listdir(swriPath) if isfile(join(swriPath,f))]
for fname in file_list:
if "~" in fname: continue
swriR = fname.replace(".dat","")
fswri = open(swriPath+fname,"r")
for row in fswri:
srow = row.strip()
if srow == "": continue
arow = [x for x in srow.split(" ") if x!=""]
if arow[0] == "Lambda": storeLambda = arow
print("in "+fname)
for branch in storeLambda[2:]:
print(" "+swriR+" -> "
+ " + ".join([x for x in branch.replace("+","+/E/").split("/") if x!=""]))
sys.exit()
#get a citation and exit
if args.quote:
print("KROME is a quote random generator with some utility for astrochemistry.")
print("As requested a random citation:")
get_quote()
sys.exit()
#get the list of the quotes and exit
if args.quotelist:
print("KROME is a quote random generator with some utility for astrochemistry.")
print("As requested the complete list of the available citations:")
get_quote(True)
sys.exit()
#save options into a file
fopt = open("options.log","w")
for k, v in vars(args).items():
#if option is set add to the namespace
if v:
if v is True: v="" #if is exactly True write key only
fopt.write("-"+k+" "+v+"\n") #write to file
#you can select only one -forceMF
if args.forceMF222 and args.forceMF21:
die("ERROR: options -forceMF222 and -forceMF21 are mutually exclusive: choose one.")
#get filename
if not self.is_test and args.n: self.filename = args.n
if not self.is_test and args.network: self.filename = args.network
#chech if reactions file exists
if args.n or self.is_test:
if not os.path.isfile(self.filename):
die("ERROR: Reaction file \""+self.filename+"\" doesn't exist!")
else:
die("ERROR: you must define -n FILENAME or -network FILENAME, "
"where FILENAME is the reaction file!")
#read the coolFile
if args.coolFile:
self.coolFile = args.coolFile.split(",")
print("Reading option -coolFile (filename="+str(",".join(self.coolFile))+")")
#read compiler name
if args.compiler:
self.compiler = args.compiler.strip()
print("Reading option -compiler (COMPILER="+self.compiler+")")
sys.exit("ERROR: option -compiler is deprecated; see wiki. "
"Remove this from your command line.")
#use f90 solver
if args.useDvodeF90:
self.useDvodeF90 = True
self.solver_MF = 227
print("Reading option -useDvodeF90")
#set implicit RHS
if args.iRHS:
self.use_implicit_RHS = True
self.solver_MF = 222
if self.useDvodeF90:
self.solver_MF = 227
print("Reading option -iRHS")
#force MF=21
if args.forceMF21:
self.solver_MF = 21
if self.useDvodeF90:
self.solver_MF = 27
print("Reading option -forceMF21")
#force MF=222
if args.forceMF222:
self.solver_MF = 222
if self.useDvodeF90:
self.solver_MF = 227
print("Reading option -forceMF222")
#method for column density calculation
if args.columnDensityMethod:
allMethods = ["JEANS","JEANS40"]
if args.columnDensityMethod not in allMethods:
sys.exit("ERROR: method for -columnDensityMethod must be one of "
+(",".join(allMethods)))
self.columnDensityMethod = args.columnDensityMethod
#use Semenov framework
if args.useSemenov:
self.useSemenov = True
print("Reading option -useSemenov")
#use rate tables
if args.useTabs:
self.useTabs = True
print("Reading option -useTabs")
#do report
if args.report:
self.doReport = True
print("Reading option -report")
#check mass conservation
if args.checkConserv:
self.checkConserv = True
print("Reading option -checkConserv")
#use reaction indexes in reaction file
if args.useFileIdx:
self.useFileIdx = True
print("Reading option -useFileIdx")
#write a single compact file krome_all.f90
if args.compact:
self.buildCompact = True
print("Reading option -compact")
#perform a clean build
if args.clean:
self.cleanBuild = True
print("Reading option -clean")
#perform a clean build
if args.useAutoNetwork:
self.useCustom = True
print("Reading option -useAutoNetwork")
#build isotopes automatically
if args.usePlainIsotopes:
self.usePlainIsotopes = True
print("Reading option -usePlainIsotopes")
#replace square brackets
copydic = dict()
for k, v in self.mass_dic.items():
copydic[k.replace("[","").replace("]","")] = v
self.mass_dic = copydic
self.atoms = [x.replace("[","").replace("]","") for x in self.atoms]
#compute electrons by balancing the charge
if args.computeElectrons:
self.useComputeElectrons = True
print("Reading option -computeElectrons")
#use photoionization from Verner et al. 1996 (no longer working)
if args.usePhIoniz:
self.usePhIoniz = True
print("Reading option -usePhIoniz (now obsolete, you can remove it)")
#use photoionization
if args.usePhotoOpacity:
self.usePhotoOpacity = True
print("Reading option -usePhotoOpacity (now obsolete, you can remove it)")
#use a global cooling floor
if args.useCoolFloor:
self.useCoolFloor = True
if not args.cooling:
print("ERROR: option -useCoolFloor needs at least one active cooling option. "
"See -cooling=")
sys.exit()
print("Reading option -useCoolFloor")
#use broadening
if args.useBroadening:
self.useBroadening = True
print("Reading option -useBroadening")
#apply an individual cooling floor (SB, mod TG)
if args.useIndividualFloor:
myFloor = [x.strip() for x in args.useIndividualFloor.split(",")]
allFloor = ["H2","Z_CIE","Z","ATOMIC","HD","CHEM","CO","Z_CIENOUV","Z_EXTENDED","GH","NEBULAR","Z_CIEGF","DUSTGRREC","DUSTSEMENOV"]
for floor in myFloor:
if floor not in allFloor:
die("ERROR: Floor \""+floor+"\" is unknown!\nAvailable floor are: "
+(", ".join(allFloor)))
if self.useCoolFloor:
die("ERROR: useCoolFloor and useIndividualFloor are mutually exclusive!")
self.individualCoolingFloors = myFloor
print("Reading option -useIndividualFloor ("+(",".join(myFloor))+")")
#use photo-induced cooling transitions
if args.usePhotoInduced:
self.usePhotoInduced = True
if not args.photoBins:
print("ERROR: -usePhotoInduced requires the option -photoBins=N enabled")
print(" where N is the number of photon bins employed.")
sys.exit()
print("Reading option -usePhotoInduced")
#use equilibrium check to break loops earlier
if args.useEquilibrium:
self.useEquilibrium = True
print("Reading option -useEquilibrium")
#do not use temperature limits
if args.noTlimits:
self.useTlimits = False
print("Reading option -noTlimits")
#set the filename of the file with reaction names
if args.verbatimFilename:
self.verbatimFilename = args.verbatimFilename.strip()
if len(self.verbatimFilename) > 255:
print("ERROR: the path specified in -verbatimFilename must not exceed 255 characters.")
sys.exit()
print("Name of the file with reaction names: "+self.verbatimFilename)
#do not read the file with reaction names
if args.noVerbatimFile:
self.useVerbatimFile = False
print("Reading option -noVerbatimFile")
#skip duplicated reactions
if args.skipDup:
self.skipDup = True
print("Reading option -skipDup")
#skip duplicated reactions
if args.pedantic:
self.pedanticMakefile = True
print("Reading option -pedantic")
sys.exit("ERROR: option -pedantic is deprecated; see wiki. Remove this from your command line.")
#use reverse kinetics
if args.reverse:
self.useReverse = True
print("Reading option -reverse")
#use H2 on dust, constant rate by Jura
if args.useDustH2const:
self.useDustH2const = True
print("Reading option -useDustH2const")
#use H2opacity following
if args.H2opacity:
opacities = ["RIPAMONTI", "OMUKAI"]
if args.H2opacity not in opacities:
print("ERROR: H2opacity must be one of the following "+(", ".join(opacities))+".")
sys.exit()
self.H2opacity = args.H2opacity.strip()
print("Reading option -H2opacity="+self.H2opacity)
#determine H2shielding types
if args.shielding:
myShielding = [x.strip() for x in args.shielding.split(",")]
#list of the shielding approximations
allShielding = ["DB96","WG11","WG11_withH","R14"]
for shi in myShielding:
if shi not in allShielding:
die("ERROR: Shielding \""+shi+"\" is unknown!\nAvailable shielding are: "
+(", ".join(allShielding)))
if len(myShielding) > 1:
die("ERROR: "+(", ".join(allShielding))+" are mutually exclusive!")
self.useShieldingDB96 = ("DB96" in myShielding)
self.useShieldingWG11 = ("WG11" in myShielding)
self.useShieldingWG11_withH = ("WG11_withH" in myShielding)
self.useShieldingR14 = ("R14" in myShielding)
self.useShielding = True
print("Reading option -shielding (TYPE="+(",".join(myShielding))+")")
#determine if we use CO shielding for CO dissociation
if args.shielding_CO:
self.useShieldingCO = True
print("Reading option -shielding_CO (activating CO shielding from Visser, van Dishoeck and Black 2009)")
#determine if we use C cross shielding by H2 for C dissociation
if args.shielding_C:
self.useShieldingC = True
print("Reading option -shielding_C (activating C cross-shielding from Tielens and Hollenbach 1985)")
#use dust shielding for Habing flux
if args.shieldHabingDust:
self.shieldHabingDust = True
print("Reading option -shieldHabingDust")
#use cooling dT/dt in the ODE fex
if args.skipODEthermo:
self.useODEthermo = False
print("Reading option -skipODEthermo")
#use species mass conservation (and charge)
if args.conserve:
self.useConserve = True
self.useConserveE = True
print("Reading option -conserve")
#use species mass conservation (and charge)
if args.conserveLin:
self.useConserveLin = True
self.useConserveE = True
self.needLAPACK = True
print("Reading option -conserveLin")
#use species charge conservation only
if args.conserveE:
self.useConserveE = True
print("Reading option -conserveE")
#same index for equivalent reactions with different Tlimits
if args.mergeTlimits:
self.mergeTlimits = True
print("Reading option -mergeTlimits")
#use short header for f90 files
if args.sh:
self.shortHead = True
print("Reading option -sh")
#use short header for f90 files
if args.lh:
self.shortHead = False
print("Reading option -lh")
#enable thermochemistry checking
if args.checkThermochem:
self.checkThermochem = True
print("Reading option -checkThermochem")
#use IERR interface for krome
if args.useIERR or args.ierr:
self.useIERR = True
print("Reading option -useIERR")
#check if reverse reactions are present in the network
if args.checkReverse:
self.checkReverse = True
print("Reading option -checkReverse")
#do not write anything to the build directory
if args.dry:
self.isdry = True
print("Reading option -dry")
#skip reaction mass / charge check
if (args.nomassCheck and args.nochargeCheck) or args.noCheck:
print("Reading option -nochargeCheck")
print("Reading option -nomassCheck")
self.checkMode = "NONE"
elif args.nomassCheck and not args.nochargeCheck:
print("Reading option -nomassCheck")
self.checkMode = "CHARGE"
elif not args.nomassCheck and args.nochargeCheck:
print("Reading option -nochargeCheck")
self.checkMode = "MASS"
elif not args.nomassCheck and not args.nochargeCheck:
self.checkMode = "ALL"
else:
print("ERROR: problem with -nomassCheck and/or -nochargeCheck and/or -noCheck")
sys.exit()
#skip recombination check
if args.noRecCheck: