Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9fcead0
initial work on adaptive per-cell substepping: vector to store number…
pdziekan Oct 3, 2025
e0a5dc0
Merge branch 'phys_tests' into sstp_cond_adaptive
pdziekan Oct 3, 2025
4ffd30f
WIP on adaptive cond timestepping
pdziekan Oct 6, 2025
41929fa
Merge branch 'tmp_pool' into sstp_cond_adaptive
pdziekan Oct 15, 2025
0d2438d
more danity checks for mixing substepping options
pdziekan Oct 16, 2025
250b8c6
rw_mom3_ante/post_change to unify rv calculation
pdziekan Oct 16, 2025
3061da3
python binding for opts_init.sstp_cond_mix
pdziekan Oct 16, 2025
cf0cd35
cond sstp mixing: lgrngn_cond_s test
pdziekan Oct 16, 2025
7794e72
lgrngn_cond_substepping test: plot results
pdziekan Oct 21, 2025
a0b5e32
chemistry: one more tmp vector
pdziekan Oct 21, 2025
bb3ac53
Merge branch 'tmp_pool' into sstp_cond_adaptive
pdziekan Oct 21, 2025
4b9e7fd
refactor perparticle cond substepping code to simplify adaptive subst…
pdziekan Oct 22, 2025
605eb33
refactor code: put implementation files in directories depending on c…
pdziekan Oct 22, 2025
8c09fda
add tmp vector guard for perparticle number of substeps
pdziekan Oct 22, 2025
77b442a
further refactor condensation code unto smaller files
pdziekan Oct 22, 2025
1f3edfb
perparticle condensation: add an option to use an unconverged mask
pdziekan Oct 23, 2025
00bccef
constexp if and noexcept where applicable
pdziekan Oct 23, 2025
e783925
perparticle cond: get drw2 but dont advance rw2 immediately (cleaner …
pdziekan Oct 24, 2025
fd72bec
adaptive sstp_cond logic that compiles
pdziekan Oct 28, 2025
5c3ff90
sstp cond cleanup
pdziekan Oct 28, 2025
f7ed015
comments + more realistci RH limiters in lgrngn_cond_substepping test
pdziekan Oct 28, 2025
99e5ad1
adaptive wip
pdziekan Nov 3, 2025
4db416a
adaptive wip
pdziekan Nov 5, 2025
7937387
adaptive wip
pdziekan Nov 5, 2025
f2a1da1
adaptive wip - working, but can be optimized?
pdziekan Nov 5, 2025
4ed2537
adaptive substeps - loop over substeps, not over SDs
pdziekan Nov 6, 2025
2a3cf56
adaptive substeps - loop over SDs, adapt in this loop, sstp_cond does…
pdziekan Nov 7, 2025
baa2259
track additional perparticle substepping functions
pdziekan Nov 7, 2025
a26d9c3
cache rc2 and add drw<max*rw2 convergence condition
pdziekan Nov 12, 2025
e22b807
hskpng_rc2
pdziekan Nov 13, 2025
14dca57
substepping_plot.py
pdziekan Nov 13, 2025
92d12e1
remove logic for adaptive perparticle substepping done in a loop over…
pdziekan Nov 13, 2025
52f17f7
simplify condensation substepping functions after dropping adaptive p…
pdziekan Nov 13, 2025
bdf70be
adaptive sstp_cond epsilon moved from config to opts_init
pdziekan Nov 13, 2025
51ba5d6
lgrngn_cond_substepping: add a test that compares with refdata
pdziekan Nov 13, 2025
90d0f38
lgrngn_cond_substepping test: fix refdata path for running from other…
pdziekan Nov 13, 2025
318c2b4
add user_options and api markdown documentation; generated by Claude …
pdziekan Nov 13, 2025
f01c23d
perparticle with mixing (nonadaptive): calc drw3 from rw2+1 - rw2, no…
pdziekan Nov 19, 2025
92c8eb4
perparticle with mixing (nonadaptive): calc drw3 from rw2+1 - rw2, no…
pdziekan Nov 19, 2025
0d10e5b
nomix adapt cond: remove advance_rw2 lambdas; calc drw3 directly
pdziekan Nov 20, 2025
498e9f6
cond exact ppaticle nomix: Tp, rwx and drwx as local variables, not t…
pdziekan Nov 20, 2025
c0a3a49
nomixing cond adaptive: copy into local vars, do work, copy back
pdziekan Nov 20, 2025
3af1cf3
Merge branch 'sstp_cond_adaptive' of github.com:pdziekan/libcloudphxx…
pdziekan Nov 20, 2025
ea52d56
track perparticl_advance_rw2 files (renamed)
pdziekan Nov 21, 2025
5993b69
remove files that had new versions added in the previous commit
pdziekan Nov 21, 2025
4d0f7c2
add information that .md files are LLM-generated
pdziekan Nov 21, 2025
a6dc90a
lgrngn cond substepping new refdata; add refplots
pdziekan Nov 21, 2025
44d15b9
lgrngn cond substepping: record drw2_eps and _max
pdziekan Dec 3, 2025
54a68ad
adjust_timesteps: revert to using opts_init values
pdziekan Dec 9, 2025
6af2cf2
Merge branch 'master' of github.com:igfuw/libcloudphxx into sstp_cond…
pdziekan Jan 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,177 changes: 1,177 additions & 0 deletions API.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ if (CMAKE_CUDA_COMPILER)
target_compile_options(cloudphxx_lgrngn PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: -Xcompiler -DUSE_MPI>)
endif()

# target_compile_options(cloudphxx_lgrngn PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: --extended-lambda>)

target_compile_definitions(cloudphxx_lgrngn PRIVATE CUDA_FOUND)

# why was this added in the MPI PR? commented-out for now
Expand Down
417 changes: 417 additions & 0 deletions USER_OPTIONS.md

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions bindings/python/lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,10 @@ BOOST_PYTHON_MODULE(libcloudphxx)
.def_readwrite("turb_cond_switch", &lgr::opts_init_t<real_t>::turb_cond_switch)
.def_readwrite("turb_coal_switch", &lgr::opts_init_t<real_t>::turb_coal_switch)
.def_readwrite("exact_sstp_cond", &lgr::opts_init_t<real_t>::exact_sstp_cond)
.def_readwrite("sstp_cond_mix", &lgr::opts_init_t<real_t>::sstp_cond_mix)
.def_readwrite("sstp_cond", &lgr::opts_init_t<real_t>::sstp_cond)
.def_readwrite("sstp_cond_act", &lgr::opts_init_t<real_t>::sstp_cond_act)
.def_readwrite("rc2_T", &lgr::opts_init_t<real_t>::rc2_T)
.def_readwrite("sstp_coal", &lgr::opts_init_t<real_t>::sstp_coal)
.def_readwrite("sstp_chem", &lgr::opts_init_t<real_t>::sstp_chem)
.def_readwrite("supstp_rlx", &lgr::opts_init_t<real_t>::supstp_rlx)
Expand Down Expand Up @@ -352,6 +355,11 @@ BOOST_PYTHON_MODULE(libcloudphxx)
.def_readwrite("time_dep_ice_nucl", &lgr::opts_init_t<real_t>::time_dep_ice_nucl)
.def_readwrite("const_p", &lgr::opts_init_t<real_t>::const_p)
.def_readwrite("th_dry", &lgr::opts_init_t<real_t>::th_dry)
.def_readwrite("sstp_cond_mix", &lgr::opts_init_t<real_t>::sstp_cond_mix)
.def_readwrite("adaptive_sstp_cond", &lgr::opts_init_t<real_t>::adaptive_sstp_cond)
.def_readwrite("sstp_cond_adapt_drw2_eps", &lgr::opts_init_t<real_t>::sstp_cond_adapt_drw2_eps)
.def_readwrite("sstp_cond_adapt_drw2_max", &lgr::opts_init_t<real_t>::sstp_cond_adapt_drw2_max)

;
bp::class_<lgr::particles_proto_t<real_t>/*, boost::noncopyable*/>("particles_proto_t")
.add_property("opts_init", &lgrngn::get_oi<real_t>)
Expand Down
21 changes: 18 additions & 3 deletions include/libcloudph++/lgrngn/opts_init.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,16 @@ namespace libcloudphxx
int nx, ny, nz;
real_t dx, dy, dz, dt;

// no. of substeps
// no. of substeps for condensation/coalescence. If adaptive_sstp_cond=true, sstp_cond is the maximum no. of substeps.
int sstp_cond, sstp_coal;
// no. of condensation substeps for SDs that activate/deactivate in this timestep
// only work in adaptive_sstp_cond mode.
int sstp_cond_act;
// no. of substeps for chemistry
int sstp_chem;
// Note: If dt changes during simulation (by supplying opts.dt),
// no. of substeps is adjusted accordingly to keep process timestep close to dt / sstp_cond,
// but only if initially sstp_cond/coal/chem/cond_act > 1

// Lagrangian domain extents
real_t x0, y0, z0, x1, y1, z1;
Expand Down Expand Up @@ -90,12 +98,16 @@ namespace libcloudphxx
turb_coal_switch, // if true, turbulent coalescence kernels can be used
ice_switch, // if true, ice is allowed
exact_sstp_cond, // if true, use per-particle sstp_cond logic, if false, use per-cell
sstp_cond_mix, // if true, th and rv of all SDs in a cell after each timestep (instant mixing at substep timescale), else update it only after all substeps
adaptive_sstp_cond, // if true, use adaptive number of substeps for condensation
time_dep_ice_nucl; // it true, time-dependent freezing, if false, singular freezing

real_t sstp_cond_adapt_drw2_eps = 1e-4; // tolerance for adaptive substepping in condensation (drw2_err <= sstp_cond_adapt_eps * rw2)
real_t sstp_cond_adapt_drw2_max = 4; // tolerance for adaptive substepping in condensation (drw2 < sstp_cond_adapt_drw2_max * rw2)

// ice nucleating particles type
INP_t inp_type;

int sstp_chem;
real_t chem_rho;

// do we want to track the time SDs spend inside clouds
Expand Down Expand Up @@ -134,6 +146,7 @@ namespace libcloudphxx
bool open_side_walls, // if true, side walls are "open", i.e. SD are removed at contact. Periodic otherwise.
periodic_topbot_walls; // if true, top and bot walls are periodic. Open otherwise

real_t rc2_T = 10; // temperature [C] at which rc2 is calculated

// --- aerosol source stuff ---

Expand Down Expand Up @@ -188,7 +201,7 @@ namespace libcloudphxx
aerosol_independent_of_rhod(false),
sd_const_multi(0),
dt(0),
sstp_cond(1), sstp_coal(1), sstp_chem(1),
sstp_cond(1), sstp_coal(1), sstp_chem(1), sstp_cond_act(1),
chem_switch(false), // chemical reactions turned off by default
sedi_switch(true), // sedimentation turned on by default
subs_switch(false), // subsidence turned off by default
Expand All @@ -199,6 +212,8 @@ namespace libcloudphxx
time_dep_ice_nucl(false),
inp_type(INP_t::mineral),
exact_sstp_cond(false),
sstp_cond_mix(true),
adaptive_sstp_cond(false),
turb_cond_switch(false),
turb_adve_switch(false),
turb_coal_switch(false),
Expand Down
19 changes: 10 additions & 9 deletions src/detail/tmp_vector_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ namespace libcloudphxx
entry(size_t n) : vec(n) {}
};
std::vector<entry> pool;
const std::string name;

public:
tmp_vector_pool(size_t pool_size = 1): pool(pool_size, 0) {}
tmp_vector_pool(std::string name, size_t pool_size = 1): pool(pool_size, 0), name(name) {}

// Add a new vector to the pool
// void add_vector(size_t vec_size) {
// pool.emplace_back(vec_size);
// }
void add_vector() {
pool.emplace_back(0);
void add_vectors(size_t no_vectors = 1) {
for (size_t i = 0; i < no_vectors; ++i) {
pool.emplace_back(0);
}
}

void resize(size_t n) {
Expand All @@ -41,14 +41,15 @@ namespace libcloudphxx

// Acquire an available vector, returns its index
size_t acquire() {
// std::cerr << "tmp_vector_pool: acquiring vector from pool of size " << pool.size() << "\n";
for (size_t i = 0; i < pool.size(); ++i) {
if (!pool[i].in_use) {
pool[i].in_use = true;
return i;
}
}
assert(false && "No available temporary vectors in pool!");
std::cerr << "LIBCLOUDPH++: tmp_vector_pool: No available temporary vectors in pool! Pool size: " << pool.size() << ". Pool name: " << name << " \n";
// assert(false && "No available temporary vectors in pool!");
assert(false);
return size_t(-1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace libcloudphxx
}

template <typename real_t, backend_t device>
void particles_t<real_t, device>::impl::init_sstp_chem()
void particles_t<real_t, device>::impl::init_percell_sstp_chem()
{
if (!allow_sstp_chem) return;

Expand All @@ -50,7 +50,7 @@ namespace libcloudphxx
}

template <typename real_t, backend_t device>
void particles_t<real_t, device>::impl::sstp_step_chem(
void particles_t<real_t, device>::impl::sstp_percell_step_chem(
const int &step
)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ namespace libcloudphxx
}
};

struct invalidator // set value of some parameter to invalid in the SD that had its parameters changed (other than multiplicity)
{
template<class tpl_t>
BOOST_GPU_ENABLED
void operator()(tpl_t tpl)
{
if(thrust::get<2>(tpl) <= 0) return; // do nothing if no collisions or first one passed was a SD with an uneven number in the cell
thrust::get<3>(tpl) == na_ge_nb ? // does the first SD of the pair have greater multiplicity?
thrust::get<1>(tpl) = detail::invalid:
thrust::get<0>(tpl) = detail::invalid;
}
};

struct summator
{
template<class tpl_t>
Expand Down Expand Up @@ -510,6 +523,26 @@ namespace libcloudphxx
);
nancheck(incloud_time, "incloud_time - post coalescence");
}

// invalidate rc2 due to changed rd3 and kappa
if(opts_init.sstp_cond_act > 1 && allow_sstp_cond) // rc2 only used in adaptive activation substepping
{
thrust::for_each(
thrust::make_zip_iterator(thrust::make_tuple(
thrust::make_permutation_iterator(rc2.begin(), sorted_id.begin()),
thrust::make_permutation_iterator(rc2.begin(), sorted_id.begin())+1,
col.begin(),
col.begin()+1
)),
thrust::make_zip_iterator(thrust::make_tuple(
thrust::make_permutation_iterator(rc2.begin(), sorted_id.begin()),
thrust::make_permutation_iterator(rc2.begin(), sorted_id.begin())+1,
col.begin(),
col.begin()+1
)) + n_part -1,
detail::invalidator()
);
}
}
};
};
50 changes: 50 additions & 0 deletions src/impl/common/calc_liq_ice_content_change.ipp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// vim:filetype=cpp
/** @file
* @copyright University of Warsaw
* @section LICENSE
* GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/)
*/

namespace libcloudphxx
{
namespace lgrngn
{
template <typename real_t, backend_t device>
void particles_t<real_t, device>::impl::calc_liq_ice_content_change()
{
// TODO: assert that save_liq_ice_content_before_change was called beforehand?
thrust_device::vector<real_t> &drw_mom3 = drw_mom3_gp->get();

moms_all();
moms_calc(rw2.begin(), real_t(3./2.));

// drw_mom3 = -rw_mom3_ante + rw_mom3_post
thrust::transform(
count_mom.begin(), count_mom.begin() + count_n, // input - 1st arg
thrust::make_permutation_iterator(drw_mom3.begin(), count_ijk.begin()), // 2nd arg
thrust::make_permutation_iterator(drw_mom3.begin(), count_ijk.begin()), // output
thrust::plus<real_t>()
);

if(opts_init.ice_switch)
{
thrust_device::vector<real_t> &d_ice_mass = d_ice_mass_gp->get();

moms_gt0(ice_a.begin()); // choose ice particles (ice_a>0)
moms_calc(thrust::make_transform_iterator(
thrust::make_zip_iterator(thrust::make_tuple(ice_a.begin(), ice_c.begin(), ice_rho.begin())),
detail::ice_mass<real_t>()
),
real_t(1)
);

thrust::transform(
count_mom.begin(), count_mom.begin() + count_n, // input - 1st arg
thrust::make_permutation_iterator(d_ice_mass.begin(), count_ijk.begin()), // 2nd arg
thrust::make_permutation_iterator(d_ice_mass.begin(), count_ijk.begin()), // output
thrust::plus<real_t>()
);
}
}
};
};
Loading
Loading