-
Notifications
You must be signed in to change notification settings - Fork 0
/
run_parallel.py
executable file
·154 lines (144 loc) · 8.86 KB
/
run_parallel.py
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
import os
import subprocess # to run bash commands like in a terminal
import sys
import numpy as np
import parallel_functions as pf
from mpi4py.MPI import COMM_WORLD as CW # for paralellisation
run_type = sys.argv[1] # 'meteor' or 'CtoO' or 'star' according to which experiment we run, used to make loop at end more readable
rank = CW.Get_rank()
size = CW.Get_size()
nsim = 15
sim_per_rank = int(nsim / size) # this is needed to distribure the tasks between tha CPUs
main_folder = '/scratch/s2555875/' # place to store outputs
output_folder = main_folder + 'output/'
conv_file = os.path.join(main_folder, 'converged.txt')
check_conv = True
# ------setting up parameterspace for all runs------
# meteoritic bombardment
bomb_rate = np.linspace(3e23, 1e25, nsim) # values from Pearce et al. (2022) Fig A4 min and max
# for extra sims: np.linspace(3.5e23, 9e23, nsim)
vdep = '1.'#,1.e-4,0.,1.' # deposition velocity for H2, CO2, CH4, NH3 (CO from lighning too so have to adjust later...)
prod_sp = {'H2':0.65}#, 'CO2':1.32, 'CH4':1e-6, 'NH3':7e-5} # produced amount per impactor os m_mass from Zahnle et al (2020)
m_mass = 1e22 # stick to this for now by Zahnle et al. (2020)
# C/O ratio
co2_for_CtoO_range = np.linspace(0.001,0.1,nsim, endpoint = True)
# star type
star_df = pf.read_stellar_data(main_folder + 'stellar_flux/stellar_params.csv') # NOT necessarily nsim long...
a_star_list = [0.0296, 0.0770, 0.0780, 0.1550, 0.1780, 0.3840, 0.4945, 0.6295, 0.6976, 1., 1.1623, 1.9047, 2.3155]
# distance case
a_list = np.linspace(0.85, 1.35, nsim, endpoint = True) # tested endpoints before running this cell to make sure durface temperature is habitable
# in case new sims with HELIOS TP
helios_tp = ''
#helios_tp = 'helios_tp_'
# local meteorite case
h2_bar_list = np.linspace(0, 2, 15, endpoint = True)
check_conv = True
# ------end of parameter set up-----
for i in range(rank*sim_per_rank, (rank+1)*sim_per_rank): # paralellisation itself, it spreads the task between the CPUs
# this is the magic, after this just think of it as a normal, sequential loop
if run_type == 'star' and i >= len(star_df.Name): # fewer stars than 15...
continue
sim = ''
if i < 10:
sim = helios_tp + 'sim_0' + str(i) + '_' + run_type
sim_folder = main_folder + sim
#new_folder = os.path.join(main_folder, sim) # my folder naming conventions
else:
sim = helios_tp + 'sim_' + str(i) + '_' + run_type
sim_folder = main_folder + sim
#new_folder = os.path.join(main_folder, sim)
# build files for simulation
out_file = sim + '.vul'
out_change = 'out_name,' + out_file + ',str'
new_cfg = sim_folder + '/vulcan_cfg.py'
# first create simulation folder
subprocess.check_call(['mkdir', sim_folder])
if run_type == 'meteor':
# then BC because of meteorite and outgassing and lightning
sp_names, sp_fluxes = pf.dict_to_input(pf.bombardment(bomb_rate[i], m_mass, prod_sp))
# need: species, flux, vdep and name of txt file
BC_bot_file = main_folder + 'BC_files/' + 'BC_bot_' + sim + '.txt'
subprocess.check_call(['python', 'gen_BC.py', sp_names, sp_fluxes, vdep, BC_bot_file])
# then use the new BC file in cfg file with output name
BC_bot_change = ','.join(['bot_BC_flux_file', BC_bot_file, 'str'])
# then change vulcan_cfg.py file
subprocess.check_call(['python', 'gen_cfg.py', new_cfg, BC_bot_change, out_change])
elif run_type == 'CtoO':
# generate new mixing file
new_mixing_file = main_folder + 'mixing_files/' + sim + 'mixing.txt'
mixing_change = ','.join(['vul_ini', new_mixing_file, 'str'])
pf.gen_mixing(co2_for_CtoO_range[i], new_mixing_file)
# then change vulcan_cfg.py file
subprocess.check_call(['python', 'gen_cfg.py', new_cfg, mixing_change, out_change])
elif run_type == 'star':
# new stellar radiation files already created, need to update vulcan_cfg with filename and r_star and orbit_radius
star_name = star_df.Name.iloc[i]
new_rad_file = pf.get_rad_prof(star_name)
rad_file_change = ','.join(['sflux_file', new_rad_file, 'str'])
new_r_star = str(star_df.loc[star_df.Name == star_name].R.iloc[0])
r_star_change = ','.join(['r_star', new_r_star, 'val'])
#new_orbit_radius = str(pf.semi_major_from_S_eff(star_df, star_name))
new_orbit_radius = str(a_star_list[i])
orbit_radius_change = ','.join(['orbit_radius', new_orbit_radius, 'val'])
# new TP files are already created with HELIOS, need to update vulcan_cfg with filename and orbit_radius
# surf temps are similar, but better to use corresponding ones
tp_file = main_folder + 'TP_files/' + sim + '.txt'
tp_change = ','.join(['atm_file', tp_file, 'str'])
subprocess.check_call(['python', 'gen_cfg.py', new_cfg, rad_file_change, r_star_change, orbit_radius_change, tp_change, out_change])
elif run_type == 'dist':
# new TP files are already created with HELIOS, need to update vulcan_cfg with filename and orbit_radius
tp_file = main_folder + 'TP_files/' + sim + '.txt'
tp_change = ','.join(['atm_file', tp_file, 'str'])
new_orbit_radius = str(a_list[i])
orbit_radius_change = ','.join(['orbit_radius', new_orbit_radius, 'val'])
subprocess.check_call(['python', 'gen_cfg.py', new_cfg, tp_change, orbit_radius_change, out_change])
elif run_type == 'local':
# generate new mixing ratios
new_mixing_file = main_folder + 'mixing_files/' + sim + 'mixing.txt'
mixing_change = ','.join(['vul_ini', new_mixing_file, 'str'])
pf.gen_mixing_local(h2_bar_list[i], new_mixing_file)
# H2 fiddles with cinvergence so reducing error tolerances
atol_change = ','.join(['atol', str(1.E-7), 'val'])
rtol_change = ','.join(['post_conden_rtol', str(0.5), 'val'])
# assumed to keep P-T profile and surface pressure the same
# then change vulcan_cfg.py file
subprocess.check_call(['python', 'gen_cfg.py', new_cfg, mixing_change, atol_change, rtol_change, out_change])
# then change to simulation folder and put symlinks in there to avoid copyying and make importing possible
#subprocess.check_call(['cp', '-p', 'build_atm.py', 'chem_funs.py', 'op.py', 'phy_const.py', 'store.py', 'vulcan.py', sim_folder])
wd = os.getcwd()
os.chdir(sim_folder)
subprocess.check_call(['ln', '-s', '/home/s2555875/VULCAN-2/build_atm.py', 'build_atm.py'])
subprocess.check_call(['ln', '-s', '/home/s2555875/VULCAN-2/chem_funs.py', 'chem_funs.py'])
subprocess.check_call(['ln', '-s', '/home/s2555875/VULCAN-2/op.py', 'op.py'])
subprocess.check_call(['ln', '-s', '/home/s2555875/VULCAN-2/phy_const.py', 'phy_const.py'])
subprocess.check_call(['ln', '-s', '/home/s2555875/VULCAN-2/store.py', 'store.py'])
subprocess.check_call(['cp', '-p', '/home/s2555875/VULCAN-2/vulcan.py', 'vulcan.py'])
subprocess.check_call(['ln', '-s', '/home/s2555875/VULCAN-2/thermo', 'thermo'])
subprocess.check_call(['ln', '-s', '/home/s2555875/VULCAN-2/atm', 'atm'])
# then run vulcan.py
subprocess.check_call(['python', 'vulcan.py', '-n'])
# check convergence and rerun once if needed:
os.chdir(wd)
if check_conv:# == True and n_round == 1:
with open(conv_file, 'r') as f:
conv_text = f.read()
if out_file not in conv_text:
vul_ini_change = ','.join(['vul_ini', os.path.join(output_folder,out_file), 'str'])
ini_mix_change = ','.join(['ini_mix', 'vulcan_ini', 'str'])
out_file = sim + '_rerun.vul' # change this last so the initial composition will use the previous run
out_change = ','.join(['out_name', out_file, 'str'])
subprocess.check_call(['python', 'gen_cfg.py', new_cfg, out_change, vul_ini_change, ini_mix_change, 'rerun', sim])
os.chdir(sim_folder)
subprocess.check_call(['python', 'vulcan.py', '-n'])
# then exit simulation folder and delete it
os.chdir(wd)
subprocess.check_call(['rm', '-rf', sim_folder])
# TO DO:
# DONE need something to prepare atmosphere and find a good place to store that, chemistry will be the same
# DONE similar for boundary conditions
# DONE make a generalised, probably with inputs, script for initial mixing ratios
# DONE write general vulcan_cfg generator -> NEED generic file to start from that has save structure
# DONE do I need to copy vulcan.py for each function or can I call the same file? -> can call the same as they run as different processes with their own memory, variables, etc.
# DONE after all these can the parallelisation run
# IMPROVE? plus figure out the output structure: how to name and what groupings should I save them in
# DONE so far every bit is in a different script, maybe can be as functions here, THINK about this -> less command line python stuff if they're here as functions...