Skip to content

Commit 659d000

Browse files
authored
Merge pull request #274 from trontrytel/thesis_automate
Thesis automate
2 parents 0e3d01f + bf19613 commit 659d000

File tree

11 files changed

+626
-622
lines changed

11 files changed

+626
-622
lines changed

.travis_scripts/icicle.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ cd ../../..
3535
## icicle
3636
if [[ $TRAVIS_OS_NAME == 'linux' ]]; then sudo $apt_get_install libboost-program-options-dev; fi
3737
cd libcloudphxx/tests/paper_GMD_2015
38-
mkdir build
38+
mkdir -p build
3939
cd build
4040
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then cmake .. -DBOOST_ROOT=/usr/local; fi
4141
if [[ $TRAVIS_OS_NAME == 'linux' && $CXX == 'clang++' ]]; then cmake -DCMAKE_CXX_COMPILER=/usr/bin/clang++ ../; fi # Travis default is not the packaged one

.travis_scripts/parcel.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ git clone --depth=1 git://github.com/igfuw/parcel.git
2424
cd parcel
2525
mkdir plots/outputs
2626
py.test -v long_test
27+
py.test -v unit_test
2728
cd ..
2829

2930
# make libcloudph++ in Debug mode
@@ -35,7 +36,6 @@ cd ../../
3536

3637
# parcel tests for Debug mode of libcloudph++
3738
cd parcel
38-
py.test -v unit_test
3939
py.test -v unit_test_debug
4040

4141
set +e # see https://github.com/travis-ci/travis-ci/issues/6522

tests/paper_GMD_2015/src/opts_lgrngn.hpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ void setopts_micro(
241241
("sedi", po::value<bool>()->default_value(rt_params.cloudph_opts.sedi) , "particle sedimentation (1=on, 0=off)")
242242
("cond", po::value<bool>()->default_value(rt_params.cloudph_opts.cond) , "condensational growth (1=on, 0=off)")
243243
("coal", po::value<bool>()->default_value(rt_params.cloudph_opts.coal) , "collisional growth (1=on, 0=off)")
244+
("rcyc", po::value<bool>()->default_value(rt_params.cloudph_opts.rcyc) , "recycling of droplets (1=on, 0=off)")
244245
("chem_dsl", po::value<bool>()->default_value(rt_params.cloudph_opts.chem_dsl) , "dissolving trace gases (1=on, 0=off)")
245246
("chem_dsc", po::value<bool>()->default_value(rt_params.cloudph_opts.chem_dsc) , "dissociation (1=on, 0=off)")
246247
("chem_rct", po::value<bool>()->default_value(rt_params.cloudph_opts.chem_rct) , "aqueous chemistry (1=on, 0=off)")
@@ -259,6 +260,7 @@ void setopts_micro(
259260
// collision and sedimentation
260261
("kernel", po::value<std::string>()->default_value("geometric"), "collision kernel (geometric, long, hall, hall_davis_no_waals, golovin, onishi_hall, onishi_hall_davis_no_waals, vohl_davis_no_waals, hall_pinsky_cumulonimbus, hall_pinsky_stratocumulus)")
261262
("terminal_velocity", po::value<std::string>()->default_value("khvorostyanov_spherical"), "sedimentation velocity (khvorostyanov_spherical, khvorostyanov_nonspherical, beard76, beard77, beard77fast)")
263+
("adve_scheme", po::value<std::string>()->default_value("implicit"), "advection for super-droplets (implicit, euler, pred_corr)")
262264
// TODO: MAC, HAC, vent_coef
263265
;
264266
po::variables_map vm;
@@ -295,7 +297,7 @@ void setopts_micro(
295297
rt_params.cloudph_opts.cond = vm["cond"].as<bool>();
296298
rt_params.cloudph_opts.coal = vm["coal"].as<bool>();
297299

298-
//rt_params.cloudph_opts.rcyc = vm["rcyc"].as<bool>();
300+
rt_params.cloudph_opts.rcyc = vm["rcyc"].as<bool>();
299301
rt_params.cloudph_opts.chem_dsl = vm["chem_dsl"].as<bool>();
300302
rt_params.cloudph_opts.chem_dsc = vm["chem_dsc"].as<bool>();
301303
rt_params.cloudph_opts.chem_rct = vm["chem_rct"].as<bool>();
@@ -309,6 +311,21 @@ void setopts_micro(
309311
rt_params.cloudph_opts_init.dev_count = vm["dev_count"].as<int>();
310312
rt_params.cloudph_opts_init.rng_seed = vm["rng_seed"].as<int>();
311313

314+
// advection of super droplets choice
315+
if (vm["adve_scheme"].as<std::string>() == "implicit") {
316+
rt_params.cloudph_opts_init.adve_scheme = libcloudphxx::lgrngn::as_t::implicit;
317+
}
318+
if (vm["adve_scheme"].as<std::string>() == "euler") {
319+
rt_params.cloudph_opts_init.adve_scheme = libcloudphxx::lgrngn::as_t::euler;
320+
}
321+
if (vm["adve_scheme"].as<std::string>() == "pred_corr") {
322+
rt_params.cloudph_opts_init.adve_scheme = libcloudphxx::lgrngn::as_t::pred_corr;
323+
}
324+
else {
325+
std::cerr<<"Invalid advection choice"<<std::endl;
326+
assert(false);
327+
}
328+
312329
// coalescence kernel choice
313330
if (vm["kernel"].as<std::string>() == "geometric") {
314331
rt_params.cloudph_opts_init.kernel = libcloudphxx::lgrngn::kernel_t::geometric;

tests/paper_GMD_2015/tests/chem_sandbox/calc_chem.cpp

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#include <string>
44
#include <sstream> // std::ostringstream
55

6+
#include <fstream>
7+
#include <iostream>
8+
69
#include "../common.hpp"
710
#include "bins.hpp"
811

@@ -40,54 +43,99 @@ int main(int ac, char** av)
4043
bins_wet_str_2 = tmp.str();
4144
}
4245

43-
44-
for (const string &kernel : {"hall_pinsky_stratocumulus"})
45-
/* {"hall", "hall_davis_no_waals",
46-
"onishi_hall", "onishi_hall_davis_no_waals",
47-
"vohl_davis_no_waals",
48-
"hall_pinsky_stratocumulus"
49-
}) */
5046
{
47+
string cmn =
48+
"--outfreq=200 --dt=1 --nt=11800 --spinup=10000 --nx=76 --nz=76 --relax_th_rv=false "
49+
"--backend=CUDA --adv_serial=false --sd_conc=256 --sstp_cond=10 --coal=true --sedi=true "
50+
"--adve=true --adve_scheme=pred_corr --async=true --rcyc=true "
51+
"--w_max=.6 --terminal_velocity=beard77fast ";
5152

52-
string opts_common =
53-
//"--outfreq=11800 --dt=1 --nt=11800 --spinup=10000 --nx=76 --nz=76 --relax_th_rv=false --rng_seed=44 ";
54-
"--outfreq=200 --dt=1 --nt=11800 --spinup=10000 --nx=76 --nz=76 --relax_th_rv=false --rng_seed=44 ";
55-
set<string> opts_micro({
56-
"--micro=lgrngn_chem --outdir=out_"+kernel+" --backend=CUDA --adv_serial=False --sd_conc=256 "
57-
"--sstp_cond=10 --coal=True --sedi=True "
58-
"--w_max=.6 "
59-
"--chem_switch=True --chem_dsl=True --chem_dsc=True --chem_rho=1.8e3 --sstp_chem=10 "
60-
//chem_rct switched on afetr spinup in set_chem
61-
"--mean_rd1=0.05e-6 --sdev_rd1=1.8 --n1_stp=50e6 "
62-
"--mean_rd2=0.1e-6 --sdev_rd2=1.5 --n2_stp=0 "
63-
"--kernel="+kernel+" --terminal_velocity=beard77fast "
64-
//"--SO2_g_0=.2e-9 --O3_g_0=25e-9 --H2O2_g_0=.4e-9 --CO2_g_0=360e-6 --NH3_g_0=.4e-9 --HNO3_g_0=.1e-9 "
65-
"--SO2_g_0=.2e-9 --O3_g_0=25e-9 --H2O2_g_0=.4e-9 --CO2_g_0=360e-6 --NH3_g_0=.1e-9 --HNO3_g_0=.1e-9 "
53+
string stats =
6654
" --out_wet=\""
67-
".5e-6:25e-6|0,1,2,3;" // FSSP
68-
"25e-6:1|0,3;" // "rain"
55+
"1.e-6:25e-6|0,1,2,3;" // "cloud"
56+
"25e-6:1|0,3;" // "rain"
6957
+ bins_wet_str_2 + // aerosol spectrum (wet)
7058
"\""
7159
" --out_dry=\""
72-
"0.:1.|0,1;"
73-
+ bins_dry_str + // aerosol spectrum (dry)
74-
"\""
60+
"0.:1.|0,1,3;"
61+
+ bins_dry_str + // aerosol spectrum (dry)
62+
"\"";
63+
64+
string chem_stats =
7565
" --out_chem=\""
76-
"0:1|0;" // chem spectrum (dry)
66+
"0.:1.|0;" // chem spectrum (dry)
7767
"\""
7868
" --out_wet_pH=\""
79-
+ bins_wet_str + // spectrum for S_VI and H+ (wet)
80-
"\""
69+
+ bins_wet_str + // spectrum for S_VI and H+ (wet)
70+
"\"";
71+
72+
string size1 = "--mean_rd1=0.05e-6 --sdev_rd1=1.8 --n1_stp=50e6 --mean_rd2=0.1e-6 --sdev_rd2=1.5 --n2_stp=0 ";
73+
string size2 = "--mean_rd1=0.05e-6 --sdev_rd1=1.8 --n1_stp=150e6 --mean_rd2=0.1e-6 --sdev_rd2=1.5 --n2_stp=0 ";
74+
string size3 = "--mean_rd1=0.05e-6 --sdev_rd1=1.8 --n1_stp=0 --mean_rd2=0.1e-6 --sdev_rd2=1.5 --n2_stp=50e6 ";
75+
string size4 = "--mean_rd1=0.05e-6 --sdev_rd1=1.8 --n1_stp=0 --mean_rd2=0.1e-6 --sdev_rd2=1.5 --n2_stp=150e6 ";
76+
77+
//chem_rct switched on afetr spinup in set_chem
78+
string chem_cmn = "--micro=lgrngn_chem --kernel=hall_pinsky_stratocumulus --rng_seed=42 "
79+
"--chem_switch=true --chem_dsl=true --chem_dsc=true --chem_rho=1.8e3 --sstp_chem=10 ";
80+
81+
string ch_ini_base = "--SO2_g_0=.2e-9 --O3_g_0=25e-9 --H2O2_g_0=.4e-9 --CO2_g_0=360e-6 --NH3_g_0=.1e-9 --HNO3_g_0=.1e-9 ";
82+
string ch_ini_case3 = "--SO2_g_0=.2e-9 --O3_g_0=25e-9 --H2O2_g_0=.4e-9 --CO2_g_0=360e-6 --NH3_g_0=.4e-9 --HNO3_g_0=.1e-9 ";
83+
string ch_ini_case1a = "--SO2_g_0=.2e-9 --O3_g_0=0 --H2O2_g_0=0 --CO2_g_0=360e-6 --NH3_g_0=.1e-9 --HNO3_g_0=.1e-9 ";
84+
85+
string case1 = "--micro=lgrngn --outdir=out_case1 --kernel=hall_pinsky_stratocumulus --rng_seed=42 ";
86+
string case1a = "--outdir=out_case1a ";
87+
string caseb = "--outdir=out_case_base ";
88+
string case3 = "--outdir=out_case3 ";
89+
string case4 = "--outdir=out_case4 ";
90+
string case5 = "--outdir=out_case5 ";
91+
string case6 = "--outdir=out_case6 ";
92+
93+
set<string> opts_micro({
94+
cmn + " " + case1 + " " + stats + " " + size1, // case1
95+
cmn + " " + chem_cmn + " " + stats + " " + chem_stats + " " + size1 + " " + ch_ini_base + " " + caseb, // case base
96+
cmn + " " + chem_cmn + " " + stats + " " + chem_stats + " " + size1 + " " + ch_ini_case1a + " " + case1a, // case1a
97+
cmn + " " + chem_cmn + " " + stats + " " + chem_stats + " " + size1 + " " + ch_ini_case3 + " " + case3, // case3
98+
cmn + " " + chem_cmn + " " + stats + " " + chem_stats + " " + size2 + " " + ch_ini_base + " " + case4, // case4
99+
cmn + " " + chem_cmn + " " + stats + " " + chem_stats + " " + size3 + " " + ch_ini_base + " " + case5, // case5
100+
cmn + " " + chem_cmn + " " + stats + " " + chem_stats + " " + size4 + " " + ch_ini_base + " " + case6 // case6
81101
});
82-
102+
103+
// run the above simulation cases
83104
for (auto &opts_m : opts_micro)
84105
{
85106
ostringstream cmd;
86-
cmd << av[1] << "/src/icicle " << opts_common << " " << opts_m;
107+
cmd << av[1] << "/src/icicle " << opts_m;
87108
notice_macro("about to call: " << cmd.str())
88-
109+
110+
std::ofstream log;
111+
log.open("command_log", std::ios::app);
112+
log << cmd.str() << "\n";
113+
log.close();
114+
89115
if (EXIT_SUCCESS != system(cmd.str().c_str()))
90116
error_macro("model run failed: " << cmd.str())
91117
}
118+
119+
// run case2 sumulations (all collision kernels and 5 different random seeds)
120+
for (const std::string kernel : {"hall", "hall_davis_no_waals", "hall_pinsky_stratocumulus",
121+
"onishi_hall", "onishi_hall_davis_no_waals", "vohl_davis_no_waals"})
122+
{
123+
for (const std::string seed : {"13", "42", "44", "9", "6"})
124+
{
125+
string case2 = cmn+ " " + "--micro=lgrngn --rng_seed="+seed+ " --outdir=out_case2_"+kernel+"_"+seed+ " --kernel="+kernel + " " +stats+ " " +size1;
126+
127+
ostringstream cmd;
128+
cmd << av[1] << "/src/icicle " << case2;
129+
notice_macro("about to call: " << cmd.str())
130+
131+
std::ofstream log;
132+
log.open("command_log", std::ios::app);
133+
log << cmd.str() << "\n";
134+
log.close();
135+
136+
if (EXIT_SUCCESS != system(cmd.str().c_str()))
137+
error_macro("model run failed: " << cmd.str())
138+
}
139+
}
92140
}
93141
}
Lines changed: 64 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,98 @@
11
"""
2-
Prints how effective (in terms of the depleted moles / ug of dry air) was:
3-
oxidation in total (looking at the depletes S_IV)
2+
Prints how effective (in terms of the total depleted moles in the domain) was:
3+
oxidation in total (looking at the depleted S_IV and gained S_VI)
44
oxidation by H2O2 (looking at the depleted H2O2)
55
oxidation by O3 (looking at the depleted O3)
6+
Prints the initial and final dry particulate mass (total value and in % of the final mass)
67
"""
78
import numpy as np
89
import h5py as h5
910
import sys
11+
import math
1012

1113
# libcloudph++ bindings to python (to have access to library constants)
1214
sys.path.insert(0, "../../../../../build/bindings/python/")
1315
from libcloudphxx import common as cm
1416

15-
#for case in ('case_base', 'case_base_rk', 'case3', 'case4', 'case4_no_O3', 'case5'):
16-
for case in ('case4', 'case5', 'case6'):
17-
print " "
18-
print case
19-
17+
# path to build directory with data
18+
dir_path = '../../../build/tests/chem_sandbox/'
19+
20+
for case in ['case_base', 'case3', 'case4', 'case5', 'case6']:
2021

2122
# open hdf5 files with data
22-
h5f_ini = h5.File('data/' + case + '/out_hall_pinsky_stratocumulus/timestep0000000000.h5', 'r')
23-
h5f_end = h5.File('data/' + case + '/out_hall_pinsky_stratocumulus/timestep0000011800.h5', 'r')
23+
h5f_ini = h5.File(dir_path + 'out_' + case + '/timestep0000010000.h5', 'r') # model state afer spinup
24+
h5f_end = h5.File(dir_path + 'out_' + case + '/timestep0000011800.h5', 'r') # model state at the end of simulation
25+
h5f_cst = h5.File(dir_path + 'out_' + case + '/const.h5', 'r') # constant dry air density profile
2426

27+
# dry air density
28+
rho_d = h5f_cst["G"][:] # Apparently it's important to multiply
29+
# volume of grid cells # by both in order to properly compare the initial
30+
dv = np.ones(shape=(76,76)) # and final mass in the domain.
31+
dv[0,:] = 0.5 # (The sedimentation process displaces super droplets.
32+
dv[-1,:] = 0.5 # The size distribution moments reported from the libcloud
33+
dv[:,0] = 0.5 # are divided by grid-cell volume and density.
34+
dv[:,-1] = 0.5 # Without taking into account dv and rhod one gets errors ~ 1-10% of the
35+
dv[0,0] = 0.25 # total created S_VI)
36+
dv[-1,-1] = 0.25
37+
dv[0,-1] = 0.25
38+
dv[-1,0] = 0.25
39+
dv *= 20.
40+
# total domain volume
41+
total_vol = dv.sum()
42+
2543
# helper dict for chem names and molar mass
26-
#name gas molar mass aqueous molar mass label in hdf5 ini spn end
44+
#name gas molar mass aqueous molar mass label in hdf5 spn end
2745
help_dict = {
28-
'H2O2' : [cm.M_H2O2, cm.M_H2O2, 'H2O2', 0, 0, 0],
29-
'O3' : [cm.M_O3, cm.M_O3, 'O3', 0, 0, 0],
30-
'SO2' : [cm.M_SO2, cm.M_SO2_H2O, 'S_IV', 0, 0, 0],
31-
'H2SO4': [0, cm.M_H2SO4, 'S_VI', 0, 0, 0]
46+
'H2O2' : [cm.M_H2O2, cm.M_H2O2, 'H2O2', 0, 0],
47+
'O3' : [cm.M_O3, cm.M_O3, 'O3', 0, 0],
48+
'SO2' : [cm.M_SO2, cm.M_SO2_H2O, 'S_IV', 0, 0],
49+
'H2SO4': [0, cm.M_H2SO4, 'S_VI', 0, 0]
3250
}
3351

34-
# calulate the initial and final number of moles per micro gram of dry air
35-
# and store them in dict
52+
# calulate the initial and final number of moles and store them in dict
3653
# (additionally one could also check state after spinup)
3754
for key, val in help_dict.iteritems():
3855

39-
name1 = key + "g" # gas phase chem species
40-
size_all = 76. * 76
56+
name1 = key + "g" # gas phase chem species
4157

4258
if key == 'H2SO4':
4359
name2 = 'chem_S_VI_aq'
4460

45-
# total concentration [moles/ug of dry air]
46-
ini = (h5f_ini[name2][:] / val[1]).sum() / size_all * 1e9
47-
end = (h5f_end[name2][:] / val[1]).sum() / size_all * 1e9
61+
# total moles
62+
ini = (h5f_ini[name2][:] * rho_d * dv).sum() / val[1]
63+
end = (h5f_end[name2][:] * rho_d * dv).sum() / val[1]
4864

4965
else:
50-
name2 = "chem_" + val[2] + "_aq" # aq phase chem species
66+
name2 = "chem_" + val[2] + "_aq" # aq phase chem species
5167

52-
# total concentration [moles/ug of dry air]
53-
ini = (h5f_ini[name1][:].sum() / val[0] + h5f_ini[name2][:].sum() / val[1]) / size_all * 1e9
54-
print " "
55-
print "ini ", val[2], ini
56-
end = (h5f_end[name1][:].sum() / val[0] + h5f_end[name2][:].sum() / val[1]) / size_all * 1e9
57-
print "end", val[2], end
58-
print " "
59-
60-
# calculate average over all
61-
#ini = (total_ini_conc[:]).sum() / size_all * 1e9
62-
#end = (total_end_conc[:]).sum() / size_all * 1e9
68+
# total moles
69+
ini = (h5f_ini[name1][:] * dv * rho_d).sum() / val[0] + (h5f_ini[name2][:] * dv * rho_d).sum() / val[1]
70+
end = (h5f_end[name1][:] * dv * rho_d).sum() / val[0] + (h5f_end[name2][:] * dv * rho_d).sum() / val[1]
6371

6472
val[3] = ini
65-
val[5] = end
66-
67-
print "-------------- % difference % --------------------------------"
68-
69-
print "iniO3 - endO3 / init O3 ", (help_dict['O3'][3] - help_dict['O3'][5]) / help_dict['O3'][3] * 100
70-
print "iniH2O2 - endH2O2 / init H2O2 ", (help_dict['H2O2'][3] - help_dict['H2O2'][5]) / help_dict['H2O2'][3] * 100
71-
print "iniS4 - endS4 / init S4 ", (help_dict['SO2'][3] - help_dict['SO2'][5]) / help_dict['SO2'][3] * 100
73+
val[4] = end
7274

73-
#print "dO3 / dSO2 ", (help_dict['O3'][3] - help_dict['O3'][5]) / (help_dict['SO2'][3] - help_dict['SO2'][5])
74-
#print "dH2O2 / dSO2 ", (help_dict['H2O2'][3] - help_dict['H2O2'][5]) / (help_dict['SO2'][3] - help_dict['SO2'][5])
75+
# changes in moles due to oxidation
76+
dn_S6 = (help_dict['H2SO4'][4] - help_dict['H2SO4'][3])
77+
dn_S4 = (help_dict['SO2'][3] - help_dict['SO2'][4])
78+
dn_O3 = (help_dict['O3'][3] - help_dict['O3'][4])
79+
dn_H2O2 = (help_dict['H2O2'][3] - help_dict['H2O2'][4])
80+
81+
# change in dry particulate matter
82+
ini_dry_mass = 4./3 * math.pi * (h5f_ini["rd_rng000_mom3"][:] * dv * rho_d).sum() * 1800 / total_vol * 1e9 # ug/m3 dry air
83+
fin_dry_mass = 4./3 * math.pi * (h5f_end["rd_rng000_mom3"][:] * dv * rho_d).sum() * 1800 / total_vol * 1e9 # ug/m3 dry air
84+
ini_dry_mass_chem = help_dict['H2SO4'][3] * (cm.M_NH3 + cm.M_H2SO4) / total_vol * 1e9 # ug/m3 dry air
7585

7686
print " "
77-
print "ini S6", help_dict['H2SO4'][3] * val[1] , "ug/kg of dry air"
78-
print "fin S6", help_dict['H2SO4'][5] * val[1] , "ug/kg of dry air"
79-
print "delta S6", help_dict['H2SO4'][5] * val[1] - help_dict['H2SO4'][3] * val[1], "ug/kg of dry air"
80-
print "finS6 - iniS6 / final S6 ", (help_dict['H2SO4'][5] - help_dict['H2SO4'][3]) / help_dict['H2SO4'][5] * 100
81-
82-
87+
print "---------------------- " + case + " ------------------------------"
88+
print "init. SO2 is depleted by ", (help_dict['SO2'][3] - help_dict['SO2'][4]) / help_dict['SO2'][3] * 100, "%"
89+
print "oxidation by O3 ", dn_O3 / dn_S6 * 100, "%"
90+
print "oxidation by H2O2 ", dn_H2O2 / dn_S6 * 100, "%"
91+
print " "
92+
print "ini particulate mass (r dry) ", ini_dry_mass, "ug/m3 dry air"
93+
print "ini particulate mass (chem) ", ini_dry_mass_chem, "ug/m3 dry air"
94+
print "fin particulate mass (r_dry) ", fin_dry_mass, "ug/m3 dry air"
95+
print "delta particulate mass ", fin_dry_mass - ini_dry_mass, "ug/m3 dry air"
96+
print " "
97+
print "init mass [% final mass] ", ini_dry_mass / fin_dry_mass * 100, "%"
98+
print "created mass [% final mass] ", (fin_dry_mass - ini_dry_mass) / fin_dry_mass * 100, "%"

0 commit comments

Comments
 (0)