Skip to content

Add enabling of CAMP for chemistry #368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
777c8bd
first pass at linking camp
jcurtis2 Jun 6, 2024
8507274
update to pass file path
jcurtis2 Jul 3, 2024
d4f6094
add example
jcurtis2 Jul 3, 2024
a582055
add missing camp_core
jcurtis2 Aug 26, 2024
36eccb3
update camp notebook. remove a few json files
jcurtis2 Sep 10, 2024
203a468
remove more json files
jcurtis2 Sep 11, 2024
250a167
remove more currently unused json files
jcurtis2 Sep 11, 2024
a1e7d7d
update notebook
jcurtis2 Sep 11, 2024
25e92c9
embedding cloud_and_rain_partitioning.json in the notebook
slayoo Sep 24, 2024
a9d8cb4
shorter lines for pylint
slayoo Sep 25, 2024
e5140ac
yaml fix
slayoo Sep 25, 2024
e341821
refactors in initialisation, timestepping and plotting code
slayoo Oct 19, 2024
1c81b3b
moving monarch_mod37/cb05_abs_tol.json into the notebook
slayoo Oct 19, 2024
15b0a97
moving monarch_mod37/cb05_mechanism_without_R142_R143.json into the n…
slayoo Oct 19, 2024
d73e26e
fetching json files from CAMP repo
slayoo Oct 20, 2024
3d950d7
addressing pylint hints
slayoo Oct 20, 2024
d388c53
fix var name
slayoo Oct 20, 2024
78167ae
replace TODOs with TO-DOs in CAMP json files to trick our devops tests
slayoo Oct 20, 2024
16629d0
remove leftover files; workaround TODO label warning from TODO-label …
slayoo Oct 20, 2024
686a4a2
trick pylint...
slayoo Oct 20, 2024
fe3536d
enable debug ssh access
slayoo Oct 25, 2024
bdfef62
Merge remote-tracking branch 'upstream/main' into HEAD
slayoo Oct 25, 2024
70de37c
disable tmate
slayoo Nov 5, 2024
e8083de
try putting CampCore ctors first?
slayoo Nov 5, 2024
3092156
check if differentiating by number of args would help?
slayoo Nov 8, 2024
3fa5ed8
add basic test for Photolysis ctor
slayoo Nov 8, 2024
921cb22
address pylint comment
slayoo Nov 8, 2024
cc4aa22
Merge branch 'main' into camp
slayoo Apr 22, 2025
a557a9e
Merge branch 'main' into camp
slayoo Apr 23, 2025
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
5,718 changes: 5,718 additions & 0 deletions examples/particle_simulation_with_camp.ipynb

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions src/aero_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ subroutine f_aero_data_from_json(ptr_c) bind(C)
call spec_file_read_aero_data(file, ptr_f)
end subroutine

subroutine f_aero_data_from_camp(ptr_c, camp_core_ptr_c) bind(C)
type(aero_data_t), pointer :: ptr_f => null()
type(c_ptr), intent(in) :: ptr_c
type(c_ptr), intent(in) :: camp_core_ptr_c
type(camp_core_t), pointer :: camp_core_ptr_f => null()

call c_f_pointer(ptr_c, ptr_f)
call c_f_pointer(camp_core_ptr_c, camp_core_ptr_f)

call aero_data_initialize(ptr_f, camp_core_ptr_f)

end subroutine

subroutine f_aero_data_spec_by_name(ptr_c, value, name_data, name_size) bind(C)
type(aero_data_t), pointer :: ptr_f => null()
type(c_ptr), intent(in) :: ptr_c
Expand Down
8 changes: 8 additions & 0 deletions src/aero_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@

#include "pmc_resource.hpp"
#include "json_resource.hpp"
#include "camp_core.hpp"
#include "pybind11/stl.h"
#include "aero_data_parameters.hpp"

extern "C" void f_aero_data_ctor(void *ptr) noexcept;
extern "C" void f_aero_data_dtor(void *ptr) noexcept;
extern "C" void f_aero_data_from_json(const void *ptr) noexcept;
extern "C" void f_aero_data_from_camp(const void *ptr, const void *camp_core_ptr) noexcept;
extern "C" void f_aero_data_spec_by_name(const void *ptr, int *value, const char *name_data, const int *name_size) noexcept;
extern "C" void f_aero_data_len(const void *ptr, int *len) noexcept;
extern "C" void f_aero_data_n_source(const void *ptr, int *len) noexcept;
Expand All @@ -38,6 +40,12 @@ extern "C" void f_aero_data_spec_name_by_index(const void *ptr, const int *i_spe
struct AeroData {
PMCResource ptr;

AeroData(const nlohmann::json &json, const CampCore &camp_core) :
ptr(f_aero_data_ctor, f_aero_data_dtor)
{
f_aero_data_from_camp(this->ptr.f_arg(), camp_core.ptr.f_arg());
}

AeroData(const nlohmann::json &json) :
ptr(f_aero_data_ctor, f_aero_data_dtor)
{
Expand Down
14 changes: 14 additions & 0 deletions src/aero_state.F90
Original file line number Diff line number Diff line change
Expand Up @@ -638,4 +638,18 @@ subroutine f_aero_state_sample_particles(ptr_c, aero_state_to_ptr_c, &

end subroutine

subroutine f_aero_state_initialize(ptr_c, aero_data_ptr_c, camp_core_ptr_c) bind(C)
type(c_ptr) :: ptr_c, aero_data_ptr_c, camp_core_ptr_c
type(aero_state_t), pointer :: ptr_f => null()
type(aero_data_t), pointer :: aero_data_ptr_f => null()
type(camp_core_t), pointer :: camp_core_ptr_f => null()

call c_f_pointer(ptr_c, ptr_f)
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
call c_f_pointer(camp_core_ptr_c, camp_core_ptr_f)

call aero_state_initialize(ptr_f, aero_data_ptr_f, camp_core_ptr_f)

end subroutine

end module
45 changes: 45 additions & 0 deletions src/aero_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "pmc_resource.hpp"
#include "aero_data.hpp"
#include "aero_dist.hpp"
#include "camp_core.hpp"
#include "aero_particle.hpp"
#include "env_state.hpp"
#include "bin_grid.hpp"
Expand Down Expand Up @@ -208,6 +209,12 @@ extern "C" void f_aero_state_sample_particles(
const double *sample_prob
) noexcept;

extern "C" void f_aero_state_initialize(
void *ptr_c,
const void *aero_data_ptr_c,
const void *camp_core_ptr_c
) noexcept;

template <typename arr_t, typename arg_t>
auto pointer_vec_magic(arr_t &data_vec, const arg_t &arg) {
std::vector<char*> pointer_vec(data_vec.size());
Expand Down Expand Up @@ -269,6 +276,44 @@ struct AeroState {
{
}

AeroState(
std::shared_ptr<AeroData> aero_data,
const double &n_part,
const bpstd::string_view &weight,
const CampCore &camp_core
):
ptr(f_aero_state_ctor, f_aero_state_dtor),
aero_data(aero_data)
{
static const std::map<bpstd::string_view, char> weight_c{
//{"none", '-'},
{"flat", 'f'},
{"flat_source", 'F'},
//{"power", 'p'},
//{"power_source", 'P'},
{"nummass", 'n'},
{"nummass_source", 'N'},
};

if (weight_c.find(weight) == weight_c.end()) {
std::ostringstream msg;
msg << "unknown weighting scheme '" << weight << "', valid options are: ";
auto index = 0;
for (auto const& pair: weight_c)
msg << (!index++ ? "" : ", ") << pair.first;
throw std::runtime_error(msg.str());
}

f_aero_state_init(
ptr.f_arg(),
aero_data->ptr.f_arg(),
&n_part,
&weight_c.at(weight)
);
f_aero_state_initialize(ptr.f_arg_non_const(), aero_data->ptr.f_arg(),
camp_core.ptr.f_arg());
}

static std::size_t __len__(const AeroState &self) {
int len;
f_aero_state_len(
Expand Down
18 changes: 18 additions & 0 deletions src/camp_core.F90
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@ subroutine f_camp_core_ctor(ptr_c) bind(C)
ptr_c = c_loc(ptr_f)
end subroutine

subroutine f_camp_core_initialize(ptr_c, prefix_data, prefix_size) bind(C)
type(camp_core_t), pointer :: ptr_f => null()
type(c_ptr), intent(out) :: ptr_c

character(kind=c_char), dimension(*), intent(in) :: prefix_data
integer(c_int), intent(in) :: prefix_size
character(len=prefix_size) :: prefix
integer :: i

do i=1, prefix_size
prefix(i:i) = prefix_data(i)
end do

ptr_f => camp_core_t(prefix)
call ptr_f%initialize()
ptr_c = c_loc(ptr_f)
end subroutine

subroutine f_camp_core_dtor(ptr_c) bind(C)
type(camp_core_t), pointer :: ptr_f => null()
type(c_ptr), intent(in) :: ptr_c
Expand Down
9 changes: 9 additions & 0 deletions src/camp_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

extern "C" void f_camp_core_ctor(void *ptr) noexcept;
extern "C" void f_camp_core_dtor(void *ptr) noexcept;
extern "C" void f_camp_core_initialize(void *ptr, const char *prefix,
const int *prefix_size) noexcept;

struct CampCore {
PMCResource ptr;
Expand All @@ -19,4 +21,11 @@ struct CampCore {
ptr(f_camp_core_ctor, f_camp_core_dtor)
{
}

CampCore(const std::string &config_name) :
ptr(f_camp_core_ctor, f_camp_core_dtor)
{
const int config_name_size = config_name.size();
f_camp_core_initialize(ptr.f_arg_non_const(), config_name.c_str(), &config_name_size);
}
};
10 changes: 10 additions & 0 deletions src/gas_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ subroutine f_gas_data_from_json(ptr_c) bind(C)
call spec_file_read_gas_data(nofile, ptr_f)
end subroutine

subroutine f_gas_data_from_camp(ptr_c, camp_core_ptr_c) bind(C)
type(gas_data_t), pointer :: ptr_f => null()
type(c_ptr), intent(in) :: ptr_c, camp_core_ptr_c
type(camp_core_t), pointer :: camp_core_ptr_f => null()

call c_f_pointer(ptr_c, ptr_f)
call c_f_pointer(camp_core_ptr_c, camp_core_ptr_f)
call gas_data_initialize(ptr_f, camp_core_ptr_f)
end subroutine

subroutine f_gas_data_spec_by_name(ptr_c, value, name_data, name_size) &
bind(C)
type(gas_data_t), pointer :: ptr_f => null()
Expand Down
8 changes: 8 additions & 0 deletions src/gas_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
#include "json_resource.hpp"
#include "pmc_resource.hpp"
#include "gas_data_parameters.hpp"
#include "camp_core.hpp"
#include "pybind11/stl.h"
#include "pybind11_json/pybind11_json.hpp"

extern "C" void f_gas_data_ctor(void *ptr) noexcept;
extern "C" void f_gas_data_dtor(void *ptr) noexcept;
extern "C" void f_gas_data_len(const void *ptr, int *len) noexcept;
extern "C" void f_gas_data_from_json(const void *ptr) noexcept;
extern "C" void f_gas_data_from_camp(const void *ptr, const void *camp_core_ptr) noexcept;
extern "C" void f_gas_data_to_json(const void *ptr) noexcept;
extern "C" void f_gas_data_spec_by_name(const void *ptr, int *value, const char *name_data,
const int *name_size) noexcept;
Expand All @@ -26,6 +28,12 @@ struct GasData {
PMCResource ptr;
const nlohmann::json json;

GasData(const CampCore &CampCore) :
ptr(f_gas_data_ctor, f_gas_data_dtor)
{
f_gas_data_from_camp(this->ptr.f_arg(), CampCore.ptr.f_arg());
}

GasData(const pybind11::tuple &tpl) :
ptr(f_gas_data_ctor, f_gas_data_dtor),
json(tpl)
Expand Down
15 changes: 15 additions & 0 deletions src/photolysis.F90
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

module PyPartMC_photolysis
use iso_c_binding
use camp_camp_core
use pmc_photolysis
implicit none

Expand All @@ -19,6 +20,20 @@ subroutine f_photolysis_ctor(ptr_c) bind(C)
ptr_c = c_loc(ptr_f)
end subroutine

subroutine f_photolysis_create(ptr_c, camp_core_ptr_c) bind(C)
type(photolysis_t), pointer :: ptr_f => null()
type(camp_core_t), pointer :: camp_core_ptr_f => null()
type(c_ptr), intent(inout) :: ptr_c
type(c_ptr), intent(in) :: camp_core_ptr_c

call c_f_pointer(ptr_c, ptr_f)
call c_f_pointer(camp_core_ptr_c, camp_core_ptr_f)

ptr_f => photolysis_t(camp_core_ptr_f)

ptr_c = c_loc(ptr_f)
end subroutine

subroutine f_photolysis_dtor(ptr_c) bind(C)
type(photolysis_t), pointer :: ptr_f => null()
type(c_ptr), intent(in) :: ptr_c
Expand Down
9 changes: 8 additions & 1 deletion src/photolysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@

#include "json_resource.hpp"
#include "pmc_resource.hpp"
#include "camp_core.hpp"

extern "C" void f_photolysis_ctor(void *ptr) noexcept;
extern "C" void f_photolysis_dtor(void *ptr) noexcept;

extern "C" void f_photolysis_create(const void *ptr, const void *camp_core) noexcept;
struct Photolysis {
PMCResource ptr;

Photolysis() :
ptr(f_photolysis_ctor, f_photolysis_dtor)
{
}

Photolysis(const CampCore &camp_core) :
ptr(f_photolysis_ctor, f_photolysis_dtor)
{
f_photolysis_create(this->ptr.f_arg(), camp_core.ptr.f_arg());
}
};
6 changes: 6 additions & 0 deletions src/pypartmc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ PYBIND11_MODULE(_PyPartMC, m) {
same, but without the \c _a suffix.
)pbdoc"
)
.def(py::init<const nlohmann::json&, const CampCore&>())
.def(py::init<const nlohmann::json&>())
.def("spec_by_name", AeroData::spec_by_name,
"Returns the number of the species in AeroData with the given name")
Expand Down Expand Up @@ -229,6 +230,8 @@ PYBIND11_MODULE(_PyPartMC, m) {
)pbdoc"
)
.def(py::init<std::shared_ptr<AeroData>, const double, const std::string>())
.def(py::init<std::shared_ptr<AeroData>, const double, const std::string,
const CampCore&>())
.def("__len__", AeroState::__len__,
"returns current number of particles")
.def_property_readonly("total_num_conc", AeroState::total_num_conc,
Expand Down Expand Up @@ -307,6 +310,7 @@ PYBIND11_MODULE(_PyPartMC, m) {
is gas_state%%mix_rat(i).
)pbdoc"
)
.def(py::init<const CampCore&>())
.def(py::init<const py::tuple&>())
.def("__len__", GasData::__len__,
"returns number of gas species")
Expand Down Expand Up @@ -357,6 +361,7 @@ PYBIND11_MODULE(_PyPartMC, m) {
)pbdoc"
)
.def(py::init<>())
.def(py::init<const CampCore&>())
;

py::class_<CampCore>(m,
Expand All @@ -366,6 +371,7 @@ PYBIND11_MODULE(_PyPartMC, m) {
)pbdoc"
)
.def(py::init<>())
.def(py::init<const std::string &>())
;

py::class_<Scenario>(m,
Expand Down
13 changes: 13 additions & 0 deletions src/run_part.F90
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module PyPartMC_run_part

use iso_c_binding
use pmc_run_part
use camp_camp_core
use pmc_photolysis

implicit none

Expand Down Expand Up @@ -61,6 +63,10 @@ subroutine f_run_part( &
call c_f_pointer(camp_core_ptr_c, camp_core_ptr_f)
call c_f_pointer(photolysis_ptr_c, photolysis_ptr_f)

if (run_part_opt_ptr_f%do_camp_chem) then
call camp_core_ptr_f%solver_initialize()
end if

call run_part( &
scenario_ptr_f, &
env_state_ptr_f, &
Expand Down Expand Up @@ -148,6 +154,9 @@ subroutine f_run_part_timestep( &
if (env_state_ptr_f%elapsed_time < run_part_opt_ptr_f%del_t) then
call mosaic_init(env_state_ptr_f, aero_data_ptr_f, run_part_opt_ptr_f%del_t, &
run_part_opt_ptr_f%do_optical)
if (run_part_opt_ptr_f%do_camp_chem) then
call camp_core_ptr_f%solver_initialize()
end if
if (run_part_opt_ptr_f%t_output > 0) then
call output_state(run_part_opt_ptr_f%output_prefix, &
run_part_opt_ptr_f%output_type, aero_data_ptr_f, aero_state_ptr_f, gas_data_ptr_f, &
Expand All @@ -156,6 +165,7 @@ subroutine f_run_part_timestep( &
run_part_opt_ptr_f%do_optical, run_part_opt_ptr_f%uuid)
end if
end if

call run_part_timestep(scenario_ptr_f, env_state_ptr_f, aero_data_ptr_f, aero_state_ptr_f, &
gas_data_ptr_f, gas_state_ptr_f, run_part_opt_ptr_f, camp_core_ptr_f, photolysis_ptr_f, &
i_time, t_start, last_output_time, &
Expand Down Expand Up @@ -241,6 +251,9 @@ subroutine f_run_part_timeblock( &
if (env_state_ptr_f%elapsed_time < run_part_opt_ptr_f%del_t) then
call mosaic_init(env_state_ptr_f, aero_data_ptr_f, run_part_opt_ptr_f%del_t, &
run_part_opt_ptr_f%do_optical)
if (run_part_opt_ptr_f%do_camp_chem) then
call camp_core_ptr_f%solver_initialize()
end if
if (run_part_opt_ptr_f%t_output > 0) then
call output_state(run_part_opt_ptr_f%output_prefix, &
run_part_opt_ptr_f%output_type, aero_data_ptr_f, aero_state_ptr_f, gas_data_ptr_f, &
Expand Down
11 changes: 11 additions & 0 deletions tests/test_photolysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import PyPartMC as ppmc


class TestPhotolysis:
@staticmethod
def test_ctor_without_camp():
_ = ppmc.Photolysis()

@staticmethod
def test_ctor_with_camp():
_ = ppmc.Photolysis(ppmc.CampCore())
Loading