Skip to content

Commit 565e3b2

Browse files
authored
Merge pull request #129 from pdziekan/gccn_max_height_and_accr_acnv
Gccn max height and accr acnv
2 parents 0fc77ec + 5a83db7 commit 565e3b2

17 files changed

+393
-123
lines changed

src/cases/CasesCommon.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ namespace setup
116116

117117
real_t div_LS = 0.; // large-scale wind divergence (same as ForceParameters::D), 0. to turn off large-scale subsidence of SDs, TODO: add a process switch in libcloudph++ like for coal/cond/etc
118118

119+
quantity<si::length, real_t> gccn_max_height; // GCCN added (at init and via relaxation) only up to this level
119120

120121
template<bool enable_sgs = case_ct_params_t::enable_sgs>
121122
void setopts_sgs(rt_params_t &params,
@@ -218,6 +219,7 @@ namespace setup
218219
X = 0 * si::metres;
219220
Y = 0 * si::metres;
220221
Z = 0 * si::metres;
222+
gccn_max_height = 0 * si::metres;
221223
}
222224

223225
virtual ~CasesCommon() = default;

src/cases/DYCOMS.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace setup
2020
const real_t z_abs = 1250;
2121
const real_t z_i[] = {/*RF1*/840, /*RF2*/795}; //initial inversion height
2222
const quantity<si::length, real_t> z_rlx = 25 * si::metres;
23+
const quantity<si::length, real_t> gccn_max_height = 460 * si::metres; // below inversion
2324
const real_t D = 3.75e-6; // large-scale wind horizontal divergence [1/s], needed only in radiation procedure of DYCOMS
2425

2526
// liquid water potential temperature at height z
@@ -285,6 +286,7 @@ namespace setup
285286
this->ForceParameters.D = D; // large-scale wind horizontal divergence [1/s], needed in the radiation procedure of DYCOMS
286287
this->Z = Z;
287288
this->z_rlx = z_rlx;
289+
this->gccn_max_height = gccn_max_height;
288290
}
289291
};
290292

src/cases/RICO11.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace setup
3030
const real_t z_abs = 3000;
3131
// const real_t z_i = 795; //initial inversion height
3232
const quantity<si::length, real_t> z_rlx = 100 * si::metres;
33+
const quantity<si::length, real_t> gccn_max_height = 460 * si::metres; // below cloud base
3334

3435
inline quantity<si::temperature, real_t> th_l_rico(const real_t &z)
3536
{
@@ -321,6 +322,7 @@ namespace setup
321322
this->X = X;
322323
this->Z = Z;
323324
this->z_rlx = z_rlx;
325+
this->gccn_max_height = gccn_max_height;
324326
}
325327
};
326328

src/detail/exec_timer.hpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ class exec_timer : public solver_t
5454
parent_t::hook_ante_loop(nt);
5555
this->mem->barrier();
5656
if (this->rank == 0)
57+
{
5758
tbeg_loop = parent_t::clock::now();
59+
trecord_all = parent_t::timer::zero(); // reset to 0, because we only want record all done in loop, not the one in ante_loop
60+
}
5861
this->mem->barrier();
5962
}
6063

@@ -86,11 +89,17 @@ class exec_timer : public solver_t
8689
tend_loop = parent_t::clock::now();
8790
tloop = std::chrono::duration_cast<std::chrono::milliseconds>( tend_loop - tbeg_loop );
8891

92+
// calculate CPU/GPU times and concurrency, valid only for async runs and not taking into account diagnostics in record_all
93+
typename parent_t::timer tsync_in = parent_t::tsync,
94+
tgpu = parent_t::tasync_wait_in_record_all + parent_t::tsync_wait + parent_t::tasync_wait + tsync_in, // time of pure GPU calculations (= wait time of CPU)
95+
tcpugpu = tsync_in + parent_t::tasync_gpu + parent_t::tsync_gpu - tgpu, // time of concurrent CPU and GPU calculations (= total time of GPU calculations - tgpu)
96+
tcpu = tloop - tgpu - tcpugpu;
97+
8998
std::cout << "wall time in milliseconds: " << std::endl
9099
<< "loop: " << tloop.count() << std::endl
91100
<< " hook_ante_step: " << thas.count() << " ("<< setup::real_t(thas.count())/tloop.count()*100 <<"%)" << std::endl
92-
<< " async_wait: " << parent_t::tasync_wait.count() << " ("<< setup::real_t(parent_t::tasync_wait.count())/tloop.count()*100 <<"%)" << std::endl
93101
<< " hook_mixed_rhs_ante_step: " << thmas.count() << " ("<< setup::real_t(thmas.count())/tloop.count()*100 <<"%)" << std::endl
102+
<< " async_wait: " << parent_t::tasync_wait.count() << " ("<< setup::real_t(parent_t::tasync_wait.count())/tloop.count()*100 <<"%)" << std::endl
94103
<< " sync: " << parent_t::tsync.count() << " ("<< setup::real_t(parent_t::tsync.count())/tloop.count()*100 <<"%)" << std::endl
95104
<< " step: " << thas_hads.count() << " ("<< setup::real_t(thas_hads.count())/tloop.count()*100 <<"%)" << std::endl
96105
<< " hook_ante_delayed_step: " << thads.count() << " ("<< setup::real_t(thads.count())/tloop.count()*100 <<"%)" << std::endl
@@ -99,9 +108,18 @@ class exec_timer : public solver_t
99108
<< " delayed step: " << thads_hps.count() << " ("<< setup::real_t(thads_hps.count())/tloop.count()*100 <<"%)" << std::endl
100109
<< " hook_post_step: " << thps.count() << " ("<< setup::real_t(thps.count())/tloop.count()*100 <<"%)" << std::endl
101110
<< " hook_mixed_rhs_post_step: " << thmps.count() << " ("<< setup::real_t(thmps.count())/tloop.count()*100 <<"%)" << std::endl
102-
<< " record_all: " << trecord_all.count() << " ("<< setup::real_t(trecord_all.count())/tloop.count()*100 <<"%)" << std::endl
111+
<< " record_all (in loop): " << trecord_all.count() << " ("<< setup::real_t(trecord_all.count())/tloop.count()*100 <<"%)" << std::endl
103112
<< " async_wait in record_all: " << parent_t::tasync_wait_in_record_all.count() << " ("<< setup::real_t(parent_t::tasync_wait_in_record_all.count())/tloop.count()*100 <<"%)" << std::endl
104113
<< " hook_post_step->hook_ante_step: " << thps_has.count() << " ("<< setup::real_t(thps_has.count())/tloop.count()*100 <<"%)" << std::endl;
114+
115+
std::cout << std::endl
116+
<< "CPU/GPU concurrency stats, only make sense for async lgrngn runs" << std::endl
117+
<< "and does not take into account GPU time in record_all, so most accurate without diag:" << std::endl
118+
<< " pure CPU calculations: " << tcpu.count() << " ("<< setup::real_t(tcpu.count())/tloop.count()*100 <<"%)" << std::endl
119+
<< " pure GPU calculations: " << tgpu.count() << " ("<< setup::real_t(tgpu.count())/tloop.count()*100 <<"%)" << std::endl
120+
<< " concurrent CPU&GPU: " << tcpugpu.count() << " ("<< setup::real_t(tcpugpu.count())/tloop.count()*100 <<"%)" << std::endl
121+
<< " tsync_gpu: " << parent_t::tsync_gpu.count() << " ("<< setup::real_t(parent_t::tsync_gpu.count())/tloop.count()*100 <<"%)" << std::endl
122+
<< " tasync_gpu: " << parent_t::tasync_gpu.count() << " ("<< setup::real_t(parent_t::tasync_gpu.count())/tloop.count()*100 <<"%)" << std::endl;
105123
}
106124
}
107125
}

src/detail/func_time.hpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// function that calculates execution time of any other member function called via ptr
2+
#pragma once
3+
4+
// async_forwarder code taken from https://kholdstare.github.io/technical/2012/12/18/perfect-forwarding-to-async-2.html (C) Alexander Kondratskiy
5+
// it is used to pass any type of reference (lvalue or rvalue) to std::async
6+
template <typename T>
7+
class async_forwarder
8+
{
9+
// Store value directly
10+
T val_;
11+
12+
public:
13+
/**
14+
* Move an rvalue of T into the wrapper,
15+
* incurring no copies.
16+
*/
17+
async_forwarder(T&& t)
18+
: val_(std::move(t)) { }
19+
20+
// ensure no copies are made
21+
async_forwarder(async_forwarder const& other) = delete;
22+
23+
// move constructor
24+
async_forwarder(async_forwarder&& other)
25+
: val_(std::move(other.val_)) { }
26+
27+
// Move the value out.
28+
// Note: can only occur once!
29+
operator T&& () { return std::move(val_); }
30+
operator T&& () const { return std::move(val_); }
31+
};
32+
33+
// This particular specialization
34+
// is essentially std::ref
35+
template <typename T>
36+
class async_forwarder<T&>
37+
{
38+
T& val_;
39+
40+
public:
41+
/**
42+
* Wrap the reference when passed an lvalue reference,
43+
* to fool std::async
44+
*/
45+
async_forwarder(T& t) : val_(t) { }
46+
47+
// ensure no copies are made
48+
async_forwarder(async_forwarder const& other) = delete;
49+
50+
// move constructor
51+
async_forwarder(async_forwarder&& other)
52+
: val_(other.val_) { }
53+
54+
// User-defined conversion that automatically
55+
// converts to the appropriate type
56+
operator T& () { return val_; }
57+
operator T const& () const { return val_; }
58+
};
59+
60+
61+
#if defined(UWLCM_TIMING)
62+
template<class clock, class timer, class F, class ptr, typename... Args>
63+
timer func_time(F func, ptr p, Args&&... args){
64+
auto t1=clock::now();
65+
(p->*func)(std::forward<Args>(args)...);
66+
return std::chrono::duration_cast<timer>(clock::now()-t1);
67+
}
68+
#else
69+
template<class clock, class timer, class F, class ptr, typename... Args>
70+
timer func_time(F func, ptr p, Args&&... args){
71+
(p->*func)(std::forward<Args>(args)...);
72+
return timer();
73+
}
74+
#endif
75+
76+
template<class clock, class timer, class F, class ptr, typename... Args>
77+
std::future<timer> async_timing_launcher(F func, ptr p, Args&&... args) // func and p are pointers, so their copies are lightweight
78+
{
79+
return std::async(
80+
std::launch::async,
81+
func_time<clock, timer, F, ptr, Args...>,
82+
func,
83+
p,
84+
async_forwarder<Args>(std::forward<Args>(args))... // ATTENTION! args are passed by reference to async
85+
);
86+
}

src/detail/setup.hpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,23 @@ namespace setup
8484
template <typename T>
8585
struct log_dry_radii_gccn : public libcloudphxx::common::unary_function<T>
8686
{
87+
real_t lnrd_min, lnrd_max, conc_multiplier;
88+
8789
T funval(const T lnrd) const
8890
{
89-
return T((
90-
lognormal::n_e(mean_rd3, sdev_rd3, n3_stp, quantity<si::dimensionless, real_t>(lnrd))
91-
) * si::cubic_metres
92-
);
91+
return
92+
lnrd < lnrd_min ? 0 :
93+
lnrd > lnrd_max ? 0 :
94+
T((
95+
lognormal::n_e(mean_rd3, sdev_rd3, conc_multiplier * n3_stp, quantity<si::dimensionless, real_t>(lnrd))
96+
) * si::cubic_metres
97+
);
9398
}
99+
100+
log_dry_radii_gccn(const real_t lnrd_min = 0, const real_t lnrd_max = 1000000, const real_t conc_multiplier = 1):
101+
lnrd_min(lnrd_min),
102+
lnrd_max(lnrd_max),
103+
conc_multiplier(conc_multiplier)
104+
{}
94105
};
95106
};

src/detail/user_params.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ struct user_params_t
1010
int nt, outfreq, spinup, rng_seed, rng_seed_init;
1111
setup::real_t dt;
1212
std::string outdir, model_case;
13-
bool th_src, rv_src, rc_src, rr_src, nc_src, nr_src, uv_src, w_src;
13+
bool th_src, rv_src, rc_src, rr_src, nc_src, nr_src, uv_src, w_src, ccn_relax;
1414
setup::real_t sgs_delta;
1515
quantity<si::length, setup::real_t> mean_rd1, mean_rd2;
1616
quantity<si::dimensionless, setup::real_t> sdev_rd1, sdev_rd2;
1717
quantity<power_typeof_helper<si::length, static_rational<-3>>::type, setup::real_t> n1_stp, n2_stp;
1818
quantity<si::dimensionless, setup::real_t> kappa1, kappa2;
19+
quantity<si::dimensionless, setup::real_t> case_n_stp_multiplier;
1920
};

src/opts/opts_blk_2m.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ void setopts_micro(
6868
rt_params.cloudph_opts.dry_distros.push_back({
6969
.mean_rd = case_ptr->mean_rd1 / si::metres,
7070
.sdev_rd = case_ptr->sdev_rd1,
71-
.N_stp = case_ptr->n1_stp * si::cubic_metres,
71+
.N_stp = user_params.case_n_stp_multiplier * case_ptr->n1_stp * si::cubic_metres,
7272
.chem_b = case_ptr->kappa
7373
});
7474
rt_params.cloudph_opts.dry_distros.push_back({
7575
.mean_rd = case_ptr->mean_rd2 / si::metres,
7676
.sdev_rd = case_ptr->sdev_rd2,
77-
.N_stp = case_ptr->n2_stp * si::cubic_metres,
77+
.N_stp = user_params.case_n_stp_multiplier * case_ptr->n2_stp * si::cubic_metres,
7878
.chem_b = case_ptr->kappa
7979
});
8080
}

0 commit comments

Comments
 (0)