From a7561caf84169dc2982cddbe9b0c4c93fe9fe440 Mon Sep 17 00:00:00 2001 From: mac/cli Date: Mon, 2 Jun 2025 23:35:03 -0500 Subject: [PATCH 1/4] wip --- cmake/examples/exo3.cmake | 2 +- examples/2019-Li-snap/CMakeLists.txt | 2 +- examples/2023-Chen-exo3/CMakeLists.txt | 4 +- examples/2023-Chen-exo3/earth-dry.yaml | 14 + examples/2023-Chen-exo3/hot-jupiter.yaml | 14 + examples/2023-Chen-exo3/hot_jupiter.cpp | 22 +- examples/2023-Chen-exo3/hs94.cpp | 29 +- examples/2023-Chen-exo3/polar_dry.cpp | 17 +- examples/2023-Chen-exo3/test_adiabat.cpp | 23 +- patches/33.bvals_cc_cpp.patch | 2 +- src/CMakeLists.txt | 13 - src/checks.cpp | 9 - src/exo3/cs_velocity_rotation.cpp | 46 +- src/exo3/cs_velocity_rotation.hpp | 24 +- src/exo3/cubed_sphere.cpp | 26 +- src/exo3/cubed_sphere.hpp | 4 + src/exo3/cubed_sphere_transform.cpp | 4 +- src/exo3/cubed_sphere_utility.cpp | 15 +- src/exo3/cubed_sphere_utility.hpp | 4 +- src/impl.cpp | 18 - src/inversion/CMakeLists.txt | 40 - src/inversion/composition_inversion.cpp | 56 -- src/inversion/gaussian_process.cpp | 81 -- src/inversion/gaussian_process.hpp | 32 - src/inversion/inversion.hpp | 102 -- src/inversion/inversion_factory.cpp | 61 -- src/inversion/profile_inversion.cpp | 184 ---- src/inversion/todo/inversion_helper.cpp | 57 -- .../todo/juno_profile_inversion_target.cpp | 81 -- src/inversion/todo/mcmc.cpp | 898 ------------------ src/inversion/todo/mcmc.hpp | 118 --- src/inversion/todo/mcmc_init.cpp | 79 -- src/inversion/todo/mcmc_step.cpp | 104 -- .../todo/profile_inversion_posterior.cpp | 90 -- .../todo/profile_inversion_prior.cpp | 42 - .../todo/vla_profile_inversion_target.cpp | 61 -- src/modules/CMakeLists.txt | 24 - src/modules/chemistry.hpp | 0 src/modules/coordinates.cpp | 91 -- src/modules/coordinates.hpp | 55 -- src/modules/eos_equilibrate_sp.cpp_ | 37 - src/modules/eos_equilibrate_tp.cpp_ | 76 -- src/modules/eos_equilibrate_uv.cpp_ | 93 -- src/modules/eos_rk4_integrate_z.cpp_ | 110 --- src/modules/eos_saturation_adjustment.cpp_ | 27 - src/modules/eos_thermodynamics.cpp_ | 541 ----------- src/modules/eos_thermodynamics.hpp_ | 463 --------- src/modules/equation_of_state.cpp | 55 -- src/modules/equation_of_state.hpp | 51 - src/modules/hydrodynamics.cpp | 74 -- src/modules/hydrodynamics.hpp | 60 -- src/modules/opacity_manager.hpp | 0 src/modules/radiative_transfer.hpp | 0 src/modules/ssp_rk.hpp | 37 - src/modules/thermodynamics.cpp | 36 - src/modules/thermodynamics.hpp | 41 - src/modules/transport.hpp | 0 src/nbody/CMakeLists.txt | 19 - src/nbody/nbody_inbound.cpp | 56 -- src/nbody/nbody_interaction.hpp | 0 src/nbody/particle_data.cpp | 75 -- src/nbody/particle_data.hpp | 62 -- src/nbody/particle_exchanger.cpp | 234 ----- src/nbody/particle_integrator.cpp | 44 - src/nbody/particle_outputs.cpp | 30 - src/nbody/particle_restart.cpp | 60 -- src/nbody/particle_to_mesh.cpp | 66 -- src/nbody/particles.cpp | 67 -- src/nbody/particles.hpp | 117 --- src/nbody/z.to_do/particle_exchanger.cpp | 25 - src/nbody/z.to_do/particle_exchanger.hpp | 41 - src/nbody/z.to_do/particles.cpp | 19 - src/nbody/z.to_do/particulate.cpp | 174 ---- src/nbody/z.to_do/simple_cloud_particles.cpp | 129 --- .../z.to_do/two_phase_cloud_particles.cpp | 37 - src/outputs/fits.cpp | 63 -- src/single_column/CMakeLists.txt | 19 - src/single_column/convective_adjustment.cpp | 205 ---- src/single_column/single_column.cpp | 37 - src/single_column/single_column.hpp | 47 - src/snap/implicit/solve_implicit_3d.cpp | 8 +- src/surface/surface.cpp | 6 - src/surface/surface.hpp | 43 - src/tasklist/extra_tasks.hpp | 22 - src/tasklist/implicit_hydro_tasks.cpp | 3 - src/tasklist/inversion_tasks.cpp | 82 -- src/tasklist/task_list_factory.hpp | 2 - src/torch/CMakeLists.txt | 28 - src/torch/column/decom.cpp | 76 -- src/torch/column/decom.hpp | 19 - src/torch/eos/eos.cpp | 35 - src/torch/eos/eos.hpp | 38 - src/torch/eos/eos_hydro_ideal.cpp | 120 --- src/torch/exo3/exo3.cpp | 8 - src/torch/exo3/exo3.hpp | 18 - src/torch/hydro/flux_divergence.cpp | 47 - src/torch/hydro/hydro.hpp | 20 - src/torch/recon/interpolation.cpp | 91 -- src/torch/recon/interpolation.hpp | 47 - src/torch/recon/recon.hpp | 18 - src/torch/recon/weno5.cpp | 204 ---- src/torch/riemann/riemann.cpp | 17 - src/torch/riemann/riemann.hpp | 34 - src/torch/riemann/rs_hydro_lmars.cpp | 115 --- tests/test_cs_velocity_rotation.cpp | 202 ++-- 105 files changed, 241 insertions(+), 6937 deletions(-) create mode 100644 examples/2023-Chen-exo3/earth-dry.yaml create mode 100644 examples/2023-Chen-exo3/hot-jupiter.yaml delete mode 100644 src/inversion/CMakeLists.txt delete mode 100644 src/inversion/composition_inversion.cpp delete mode 100644 src/inversion/gaussian_process.cpp delete mode 100644 src/inversion/gaussian_process.hpp delete mode 100644 src/inversion/inversion.hpp delete mode 100644 src/inversion/inversion_factory.cpp delete mode 100644 src/inversion/profile_inversion.cpp delete mode 100644 src/inversion/todo/inversion_helper.cpp delete mode 100644 src/inversion/todo/juno_profile_inversion_target.cpp delete mode 100644 src/inversion/todo/mcmc.cpp delete mode 100644 src/inversion/todo/mcmc.hpp delete mode 100644 src/inversion/todo/mcmc_init.cpp delete mode 100644 src/inversion/todo/mcmc_step.cpp delete mode 100644 src/inversion/todo/profile_inversion_posterior.cpp delete mode 100644 src/inversion/todo/profile_inversion_prior.cpp delete mode 100644 src/inversion/todo/vla_profile_inversion_target.cpp delete mode 100644 src/modules/CMakeLists.txt delete mode 100644 src/modules/chemistry.hpp delete mode 100644 src/modules/coordinates.cpp delete mode 100644 src/modules/coordinates.hpp delete mode 100644 src/modules/eos_equilibrate_sp.cpp_ delete mode 100644 src/modules/eos_equilibrate_tp.cpp_ delete mode 100644 src/modules/eos_equilibrate_uv.cpp_ delete mode 100644 src/modules/eos_rk4_integrate_z.cpp_ delete mode 100644 src/modules/eos_saturation_adjustment.cpp_ delete mode 100644 src/modules/eos_thermodynamics.cpp_ delete mode 100644 src/modules/eos_thermodynamics.hpp_ delete mode 100644 src/modules/equation_of_state.cpp delete mode 100644 src/modules/equation_of_state.hpp delete mode 100644 src/modules/hydrodynamics.cpp delete mode 100644 src/modules/hydrodynamics.hpp delete mode 100644 src/modules/opacity_manager.hpp delete mode 100644 src/modules/radiative_transfer.hpp delete mode 100644 src/modules/ssp_rk.hpp delete mode 100644 src/modules/thermodynamics.cpp delete mode 100644 src/modules/thermodynamics.hpp delete mode 100644 src/modules/transport.hpp delete mode 100644 src/nbody/CMakeLists.txt delete mode 100644 src/nbody/nbody_inbound.cpp delete mode 100644 src/nbody/nbody_interaction.hpp delete mode 100644 src/nbody/particle_data.cpp delete mode 100644 src/nbody/particle_data.hpp delete mode 100644 src/nbody/particle_exchanger.cpp delete mode 100644 src/nbody/particle_integrator.cpp delete mode 100644 src/nbody/particle_outputs.cpp delete mode 100644 src/nbody/particle_restart.cpp delete mode 100644 src/nbody/particle_to_mesh.cpp delete mode 100644 src/nbody/particles.cpp delete mode 100644 src/nbody/particles.hpp delete mode 100644 src/nbody/z.to_do/particle_exchanger.cpp delete mode 100644 src/nbody/z.to_do/particle_exchanger.hpp delete mode 100644 src/nbody/z.to_do/particles.cpp delete mode 100644 src/nbody/z.to_do/particulate.cpp delete mode 100644 src/nbody/z.to_do/simple_cloud_particles.cpp delete mode 100644 src/nbody/z.to_do/two_phase_cloud_particles.cpp delete mode 100644 src/outputs/fits.cpp delete mode 100644 src/single_column/CMakeLists.txt delete mode 100644 src/single_column/convective_adjustment.cpp delete mode 100644 src/single_column/single_column.cpp delete mode 100644 src/single_column/single_column.hpp delete mode 100644 src/surface/surface.cpp delete mode 100644 src/surface/surface.hpp delete mode 100644 src/tasklist/inversion_tasks.cpp delete mode 100644 src/torch/CMakeLists.txt delete mode 100644 src/torch/column/decom.cpp delete mode 100644 src/torch/column/decom.hpp delete mode 100644 src/torch/eos/eos.cpp delete mode 100644 src/torch/eos/eos.hpp delete mode 100644 src/torch/eos/eos_hydro_ideal.cpp delete mode 100644 src/torch/exo3/exo3.cpp delete mode 100644 src/torch/exo3/exo3.hpp delete mode 100644 src/torch/hydro/flux_divergence.cpp delete mode 100644 src/torch/hydro/hydro.hpp delete mode 100644 src/torch/recon/interpolation.cpp delete mode 100644 src/torch/recon/interpolation.hpp delete mode 100644 src/torch/recon/recon.hpp delete mode 100644 src/torch/recon/weno5.cpp delete mode 100644 src/torch/riemann/riemann.cpp delete mode 100644 src/torch/riemann/riemann.hpp delete mode 100644 src/torch/riemann/rs_hydro_lmars.cpp diff --git a/cmake/examples/exo3.cmake b/cmake/examples/exo3.cmake index 2324f083..06f72950 100644 --- a/cmake/examples/exo3.cmake +++ b/cmake/examples/exo3.cmake @@ -16,4 +16,4 @@ set(MPI ON) set(PNETCDF ON) set(RSOLVER hllc_transform) -set (NTRACER 3) \ No newline at end of file +# set (NTRACER 3) diff --git a/examples/2019-Li-snap/CMakeLists.txt b/examples/2019-Li-snap/CMakeLists.txt index ca2ee294..086cd7cb 100644 --- a/examples/2019-Li-snap/CMakeLists.txt +++ b/examples/2019-Li-snap/CMakeLists.txt @@ -16,5 +16,5 @@ endif() # 4. Copy input files to run directory file(GLOB inputs *.inp *.yaml) foreach(input ${inputs}) - execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/${inp}) + execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/${input}) endforeach() diff --git a/examples/2023-Chen-exo3/CMakeLists.txt b/examples/2023-Chen-exo3/CMakeLists.txt index 6315d163..04047f58 100644 --- a/examples/2023-Chen-exo3/CMakeLists.txt +++ b/examples/2023-Chen-exo3/CMakeLists.txt @@ -19,7 +19,7 @@ else() endif() # 2. Copy input file to run directory -file(GLOB inputs *.inp *.dat) +file(GLOB inputs *.inp *.dat *.yaml) foreach(input ${inputs}) - file(COPY ${input} DESTINATION ${CMAKE_BINARY_DIR}/bin) + execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/${input}) endforeach() diff --git a/examples/2023-Chen-exo3/earth-dry.yaml b/examples/2023-Chen-exo3/earth-dry.yaml new file mode 100644 index 00000000..bf02baf6 --- /dev/null +++ b/examples/2023-Chen-exo3/earth-dry.yaml @@ -0,0 +1,14 @@ + +phases: + - name: atm + thermo: ideal-moist + species: [atm] + kinetics: condensation + reactions: none + +species: + - name: atm + composition: {O: 0.42, N: 1.56, Ar: 0.01} + thermo: + model: constant-cp + cp0: 29.1 J/mol/K diff --git a/examples/2023-Chen-exo3/hot-jupiter.yaml b/examples/2023-Chen-exo3/hot-jupiter.yaml new file mode 100644 index 00000000..2588bc14 --- /dev/null +++ b/examples/2023-Chen-exo3/hot-jupiter.yaml @@ -0,0 +1,14 @@ + +phases: + - name: atm + thermo: ideal-moist + species: [atm] + kinetics: condensation + reactions: none + +species: + - name: atm + composition: {H: 1.5, He: 0.15} + thermo: + model: constant-cp + cp0: 29.1 J/mol/K diff --git a/examples/2023-Chen-exo3/hot_jupiter.cpp b/examples/2023-Chen-exo3/hot_jupiter.cpp index a92cc1d5..fcb668b8 100644 --- a/examples/2023-Chen-exo3/hot_jupiter.cpp +++ b/examples/2023-Chen-exo3/hot_jupiter.cpp @@ -29,7 +29,6 @@ #include // canoe -#include #include #include @@ -234,20 +233,23 @@ void MeshBlock::ProblemGenerator(ParameterInput *pin) { // construct an isothermal atmosphere auto pthermo = Thermodynamics::GetInstance(); - AirParcel air(AirParcel::Type::MoleFrac); + auto &w = phydro->w; + std::vector yfrac(1, 1.); for (int k = ks; k <= ke; ++k) for (int j = js; j <= je; ++j) { - air.w[IPR] = p0; - air.w[IDN] = Ts; + pthermo->SetMassFractions(yfrac.data()); + pthermo->EquilibrateTP(Ts, p0); int i = is; for (; i <= ie; ++i) { - AirParcelHelper::distribute_to_conserved(this, k, j, i, air); - pthermo->Extrapolate(&air, pcoord->dx1f(i), "isothermal", grav, 0.001); + pthermo->GetPrimitive(w.at(k, j, i)); + pthermo->Extrapolate_inplace(pcoord->dx1f(i), "isothermal", grav, + 0.001); + // add noise - air.w[IVY] = 10. * distribution(generator); - air.w[IVZ] = 10. * distribution(generator); + w(IVY, k, j, i) = 10. * distribution(generator); + w(IVZ, k, j, i) = 10. * distribution(generator); } } @@ -277,8 +279,8 @@ void MeshBlock::ProblemGenerator(ParameterInput *pin) { // transfer to conservative variables // bcc is cell-centered magnetic fields, it is only a place holder here - // peos->PrimitiveToConserved(phydro->w, pfield->bcc, phydro->u, pcoord, is, - // ie, js, je, ks, ke); + peos->PrimitiveToConserved(phydro->w, pfield->bcc, phydro->u, pcoord, is, ie, + js, je, ks, ke); } void MeshBlock::InitUserMeshBlockData(ParameterInput *pin) { diff --git a/examples/2023-Chen-exo3/hs94.cpp b/examples/2023-Chen-exo3/hs94.cpp index 1ef88038..c204b8df 100644 --- a/examples/2023-Chen-exo3/hs94.cpp +++ b/examples/2023-Chen-exo3/hs94.cpp @@ -29,7 +29,6 @@ #include // canoe -#include #include #include @@ -53,8 +52,6 @@ Real piso = 1E4; std::default_random_engine generator; std::normal_distribution distribution(0.0, 1.0); -namespace cs = CubedSphereUtility; - // \brief Held-Suarez atmosphere benchmark test. Refernce: Held & Suarez, // (1994). Forcing parameters are given in the paper. @@ -265,30 +262,38 @@ void MeshBlock::ProblemGenerator(ParameterInput *pin) { // construct an adiabatic atmosphere auto pthermo = Thermodynamics::GetInstance(); - AirParcel air(AirParcel::Type::MoleFrac); + auto &w = phydro->w; + std::vector yfrac(1, 1.); for (int k = ks; k <= ke; ++k) for (int j = js; j <= je; ++j) { - air.w[IPR] = p0; - air.w[IDN] = Ts; + pthermo->SetMassFractions(yfrac.data()); + pthermo->EquilibrateTP(Ts, p0); + + // half a grid to cell center + pthermo->Extrapolate_inplace(pcoord->dx1f(is) / 2., "dry", grav); int i = is; for (; i <= ie; ++i) { if (pcoord->x1v(i) - Rp > z_iso) break; - AirParcelHelper::distribute_to_conserved(this, k, j, i, air); - pthermo->Extrapolate(&air, pcoord->dx1f(i), "dry", grav, 0.001); + pthermo->GetPrimitive(w.at(k, j, i)); + pthermo->Extrapolate_inplace(pcoord->dx1f(i), "dry", grav); + // add noise - air.w[IVY] = 10. * distribution(generator); - air.w[IVZ] = 10. * distribution(generator); + w(IVY, k, j, i) = 10. * distribution(generator); + w(IVZ, k, j, i) = 10. * distribution(generator); } // construct isothermal atmosphere for (; i <= ie; ++i) { - AirParcelHelper::distribute_to_conserved(this, k, j, i, air); - pthermo->Extrapolate(&air, pcoord->dx1f(i), "isothermal", grav); + pthermo->GetPrimitive(w.at(k, j, i)); + pthermo->Extrapolate_inplace(pcoord->dx1f(i), "isothermal", grav); } } + + peos->PrimitiveToConserved(w, pfield->bcc, phydro->u, pcoord, is, ie, js, je, + ks, ke); } void MeshBlock::InitUserMeshBlockData(ParameterInput *pin) { diff --git a/examples/2023-Chen-exo3/polar_dry.cpp b/examples/2023-Chen-exo3/polar_dry.cpp index 76592507..e40db37e 100644 --- a/examples/2023-Chen-exo3/polar_dry.cpp +++ b/examples/2023-Chen-exo3/polar_dry.cpp @@ -210,14 +210,16 @@ void MeshBlock::ProblemGenerator(ParameterInput *pin) { z_iso = pin->GetReal("problem", "z_iso"); sponge_lat = pin->GetReal("problem", "sponge_lat"); heat_flux = pin->GetReal("problem", "heat_flux"); + // construct an adiabatic atmosphere auto pthermo = Thermodynamics::GetInstance(); - AirParcel air(AirParcel::Type::MoleFrac); + auto &w = phydro->w; + std::vector yfrac(1, 1.); for (int k = ks; k <= ke; ++k) for (int j = js; j <= je; ++j) { - air.w[IPR] = p0; - air.w[IDN] = Ts; + pthermo->SetMassFractions(yfrac.data()); + pthermo->EquilibrateTP(Ts, p0); int i = is; // for (; i <= ie; ++i) { @@ -232,11 +234,12 @@ void MeshBlock::ProblemGenerator(ParameterInput *pin) { // construct isothermal atmosphere for (; i <= ie; ++i) { - AirParcelHelper::distribute_to_conserved(this, k, j, i, air); - pthermo->Extrapolate(&air, pcoord->dx1f(i), "isothermal", grav, 0.001); + pthermo->GetPrimitive(w.at(k, j, i)); + pthermo->Extrapolate_inplace(pcoord->dx1f(i), "isothermal", grav, + 0.001); // add noise - air.w[IVY] = 0.00001 * distribution(generator); - air.w[IVZ] = 0.00001 * distribution(generator); + w(IVY, k, j, i) = 0.00001 * distribution(generator); + w(IVZ, k, j, i) = 0.00001 * distribution(generator); } } } diff --git a/examples/2023-Chen-exo3/test_adiabat.cpp b/examples/2023-Chen-exo3/test_adiabat.cpp index c758d1ec..9e349f6b 100644 --- a/examples/2023-Chen-exo3/test_adiabat.cpp +++ b/examples/2023-Chen-exo3/test_adiabat.cpp @@ -13,7 +13,6 @@ #include // canoe -#include #include #include @@ -23,6 +22,7 @@ #include // snap +#include #include Real Ps, Ts, grav; @@ -36,15 +36,16 @@ void MeshBlock::InitUserMeshBlockData(ParameterInput *pin) { void MeshBlock::UserWorkBeforeOutput(ParameterInput *pin) { auto pthermo = Thermodynamics::GetInstance(); + auto &w = phydro->w; for (int k = ks; k <= ke; ++k) for (int j = js; j <= je; ++j) for (int i = is; i <= ie; ++i) { user_out_var(0, k, j, i) = pthermo->GetTemp(w.at(k, j, i)); - user_out_var(1, k, j, i) = pthermo->PotentialTemp(w.at(k, j, i), Ps); + user_out_var(1, k, j, i) = potential_temp(pthermo, w.at(k, j, i), Ps); // msv user_out_var(2, k, j, i) = - pthermo->MoistStaticEnergy(this, grav * pcoord->x1v(i), k, j, i); + moist_static_energy(pthermo, w.at(k, j, i), grav * pcoord->x1v(i)); } } @@ -56,17 +57,21 @@ void Mesh::InitUserMeshData(ParameterInput *pin) { void MeshBlock::ProblemGenerator(ParameterInput *pin) { auto pthermo = Thermodynamics::GetInstance(); - - AirParcel air(AirParcel::Type::MoleFrac); + auto &w = phydro->w; // construct a reversible adiabat + std::vector yfrac(IVX, 1.); for (int k = ks; k <= ke; ++k) for (int j = js; j <= je; ++j) { - air.w[IPR] = Ps; - air.w[IDN] = Ts; + pthermo->SetMassFractions(yfrac.data()); + pthermo->EquilibrateTP(Ts, Ps); + + // half a grid to cell center + pthermo->Extrapolate_inplace(pcoord->dx1f(is) / 2., "reversible", grav); + for (int i = is; i <= ie; ++i) { - AirParcelHelper::distribute_to_conserved(this, k, j, i, air); - pthermo->Extrapolate(&air, pcoord->dx1f(i), "dry", grav); + pthermo->GetPrimitive(w.at(k, j, i)); + pthermo->Extrapolate_inplace(pcoord->dx1f(i), "reversible", grav); } } } diff --git a/patches/33.bvals_cc_cpp.patch b/patches/33.bvals_cc_cpp.patch index 4c3a6e14..d625cb0a 100644 --- a/patches/33.bvals_cc_cpp.patch +++ b/patches/33.bvals_cc_cpp.patch @@ -18,7 +18,7 @@ index 223962de..74b3ab79 100644 AthenaArray &var = *var_cc; +#ifdef CUBED_SPHERE +// nl_, nu_, after buf var -+ CubedSphereUtility::PackData(var, buf, nl_, nu_, si, ei, sj, ej, sk, ek, p, nb.ni.ox1, nb.ni.ox2, nb.ni.ox3, pmb->loc, TypeFlag); ++ cs::PackData(var, buf, nl_, nu_, si, ei, sj, ej, sk, ek, p, nb.ni.ox1, nb.ni.ox2, nb.ni.ox3, pmb->loc, TypeFlag); +#else BufferUtility::PackData(var, buf, nl_, nu_, si, ei, sj, ej, sk, ek, p); +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7f8d716..6ae7830b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,6 @@ # astro: astronomy library in cpp # utils: utility library in c/cpp # harp: radiation library in c/cpp (backed by cdisort) -# inversion: spectral inversion library # outputs: write netcdf/pnetcdf outputs # opacity: opacity library @@ -48,7 +47,6 @@ add_subdirectory(astro) add_subdirectory(utils) add_subdirectory(snap) add_subdirectory(harp) -#add_subdirectory(inversion) add_subdirectory(outputs) add_subdirectory(opacity) add_subdirectory(microphysics) @@ -58,16 +56,9 @@ add_subdirectory(tasklist) add_subdirectory(exo3) add_subdirectory(exchanger) add_subdirectory(special) -#add_subdirectory(single_column) add_subdirectory(diagnostics) add_subdirectory(forcing) -#if (${Torch_FOUND}) -# add_subdirectory(torch) -# add_subdirectory(modules) -#endif() -#add_subdirectory(nbody) - if(UNIX AND NOT APPLE) set(EXTRA_LIBS dl stdc++fs) endif() @@ -81,7 +72,6 @@ set(CANOE_LIBRARY_${buildu} "utils_${buildl}" "snap_${buildl}" "harp_${buildl}" - #"inversion_${buildl}" "outputs_${buildl}" "opacity_${buildl}" "dusts_${buildl}" @@ -90,13 +80,10 @@ set(CANOE_LIBRARY_${buildu} "tasklist_${buildl}" "exo3_${buildl}" "exchanger_${buildl}" - #"nbody_${buildl}" - #"scm_${buildl}" "diagnostics_${buildl}" "forcing_${buildl}" $<$:minichem::minichem++> $<$:exofmsrt::exofmsrt++> - #"modules_${buildl}" ${YAML_CPP_LIBRARIES} ${CPPDISORT_LIBRARY_${buildu}} ${PYTHON_LIBRARY_RELEASE} diff --git a/src/checks.cpp b/src/checks.cpp index 47af3196..d701f80b 100644 --- a/src/checks.cpp +++ b/src/checks.cpp @@ -17,9 +17,6 @@ // snap #include -// single column -#include - #ifdef ENABLE_GLOG #include #endif @@ -160,7 +157,6 @@ void fix_eos_cons2prim(MeshBlock* pmb, AthenaArray& prim, #ifdef ENABLE_FIX auto pthermo = Thermodynamics::GetInstance(); auto pcoord = pmb->pcoord; - auto pscm = pmb->pimpl->pscm; Real Rd = pthermo->GetRd(); Real grav = pmb->phydro->hsrc.GetG1(); @@ -181,8 +177,6 @@ void fix_eos_cons2prim(MeshBlock* pmb, AthenaArray& prim, } } - // pscm->ConvectiveAdjustment(ac, k, j, ifix - 1, iu); - for (int i = ifix - 1; i <= iu; ++i) { ac[i].ToMassFraction(); for (int n = 0; n < NHYDRO; ++n) { @@ -245,7 +239,6 @@ void fix_implicit_cons(MeshBlock* pmb, AthenaArray& cons, int il, int iu, #ifdef ENABLE_FIX auto pthermo = Thermodynamics::GetInstance(); auto pcoord = pmb->pcoord; - auto pscm = pmb->pimpl->pscm; Real Rd = pthermo->GetRd(); Real grav = pmb->phydro->hsrc.GetG1(); @@ -269,8 +262,6 @@ void fix_implicit_cons(MeshBlock* pmb, AthenaArray& cons, int il, int iu, } } - // pscm->ConvectiveAdjustment(ac, k, j, ifix - 1, iu); - for (int i = ifix - 1; i <= iu; ++i) { for (int n = 0; n < NHYDRO; ++n) { cons(n, k, j, i) = ac[i].w[n]; diff --git a/src/exo3/cs_velocity_rotation.cpp b/src/exo3/cs_velocity_rotation.cpp index 5b82f230..840a11d5 100644 --- a/src/exo3/cs_velocity_rotation.cpp +++ b/src/exo3/cs_velocity_rotation.cpp @@ -1,6 +1,6 @@ #include "cs_velocity_rotation.hpp" -namespace CubedSphereUtility { +namespace cs { //! Transform cubed sphere velocity to local cartesian velocity void vel_zab_to_zxy(Real *v1, Real *v2, Real *v3, Real a, Real b) { @@ -11,15 +11,13 @@ void vel_zab_to_zxy(Real *v1, Real *v2, Real *v3, Real a, Real b) { Real vy = *v3; Real vz = *v1; - Real delta = sqrt(x*x + y*y + 1); - Real C = sqrt(1 + x*x); - Real D = sqrt(1 + y*y); + Real delta = sqrt(x * x + y * y + 1); + Real C = sqrt(1 + x * x); + Real D = sqrt(1 + y * y); *v1 = (vz - D * x * vx - C * y * vy) / delta; - *v2 = - (x * vz + D * vx) / delta; - *v3 = - (y * vz + C * vy) / delta; + *v2 = (x * vz + D * vx) / delta; + *v3 = (y * vz + C * vy) / delta; } //! Transform local cartesian velocity to cubed sphere velocity @@ -31,22 +29,19 @@ void vel_zxy_to_zab(Real *v1, Real *v2, Real *v3, Real a, Real b) { Real vy = *v3; Real vz = *v1; - Real delta = sqrt(x*x + y*y + 1); - Real C = sqrt(1 + x*x); - Real D = sqrt(1 + y*y); + Real delta = sqrt(x * x + y * y + 1); + Real C = sqrt(1 + x * x); + Real D = sqrt(1 + y * y); *v1 = (vz + x * vx + y * vy) / delta; - *v2 = - (-x * vz / D + vx * (1 + y*y) / D - vy * x * y / D) / delta; - *v3 = - (-y * vz / C - x * y * vx / C + (1 + x*x) * vy / C) / delta; + *v2 = (-x * vz / D + vx * (1 + y * y) / D - vy * x * y / D) / delta; + *v3 = (-y * vz / C - x * y * vx / C + (1 + x * x) * vy / C) / delta; } //! Transform cubed sphere velocity from panel 1 to panel 2 //! \param a $x = \tan(\xi)$ coordinates //! \param b $y = \tan(\eta)$ coordinat -void vel_zab_from_p1(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel) { +void vel_zab_from_p1(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel) { vel_zab_to_zxy(vz, vx, vy, a, b); Real v1 = *vz; Real v2 = *vx; @@ -84,8 +79,7 @@ void vel_zab_from_p1(Real *vz, Real *vx, Real *vy, Real a, Real b, } } -void vel_zab_from_p2(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel) { +void vel_zab_from_p2(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel) { vel_zab_to_zxy(vz, vx, vy, a, b); Real v1 = *vz; Real v2 = *vx; @@ -122,8 +116,7 @@ void vel_zab_from_p2(Real *vz, Real *vx, Real *vy, Real a, Real b, } } -void vel_zab_from_p3(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel) { +void vel_zab_from_p3(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel) { vel_zab_to_zxy(vz, vx, vy, a, b); Real v1 = *vz; Real v2 = *vx; @@ -160,8 +153,7 @@ void vel_zab_from_p3(Real *vz, Real *vx, Real *vy, Real a, Real b, } } -void vel_zab_from_p4(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel) { +void vel_zab_from_p4(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel) { vel_zab_to_zxy(vz, vx, vy, a, b); Real v1 = *vz; Real v2 = *vx; @@ -198,8 +190,7 @@ void vel_zab_from_p4(Real *vz, Real *vx, Real *vy, Real a, Real b, } } -void vel_zab_from_p5(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel) { +void vel_zab_from_p5(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel) { vel_zab_to_zxy(vz, vx, vy, a, b); Real v1 = *vz; Real v2 = *vx; @@ -236,8 +227,7 @@ void vel_zab_from_p5(Real *vz, Real *vx, Real *vy, Real a, Real b, } } -void vel_zab_from_p6(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel) { +void vel_zab_from_p6(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel) { vel_zab_to_zxy(vz, vx, vy, a, b); Real v1 = *vz; Real v2 = *vx; @@ -273,4 +263,4 @@ void vel_zab_from_p6(Real *vz, Real *vx, Real *vy, Real a, Real b, break; } } -} // namespace CubedSphereUtility \ No newline at end of file +} // namespace cs diff --git a/src/exo3/cs_velocity_rotation.hpp b/src/exo3/cs_velocity_rotation.hpp index 9df5b4b6..ebb91856 100644 --- a/src/exo3/cs_velocity_rotation.hpp +++ b/src/exo3/cs_velocity_rotation.hpp @@ -38,7 +38,7 @@ //! \|_______.| / | //! y z -namespace CubedSphereUtility { +namespace cs { //! Transform cubed sphere velocity to local cartesian velocity void vel_zab_to_zxy(Real *v1, Real *v2, Real *v3, Real a, Real b); @@ -48,18 +48,12 @@ void vel_zxy_to_zab(Real *v1, Real *v2, Real *v3, Real a, Real b); //! Transform cubed sphere velocity from panel 1 to panel 2 //! \param a $x = \tan(\xi)$ coordinates //! \param b $y = \tan(\eta)$ coordinat -void vel_zab_from_p1(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel); -void vel_zab_from_p2(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel); -void vel_zab_from_p3(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel); -void vel_zab_from_p4(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel); -void vel_zab_from_p5(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel); -void vel_zab_from_p6(Real *vz, Real *vx, Real *vy, Real a, Real b, - int panel); -} // namespace CubedSphereUtility +void vel_zab_from_p1(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel); +void vel_zab_from_p2(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel); +void vel_zab_from_p3(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel); +void vel_zab_from_p4(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel); +void vel_zab_from_p5(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel); +void vel_zab_from_p6(Real *vz, Real *vx, Real *vy, Real a, Real b, int panel); +} // namespace cs -#endif // SRC_EXO3_VELOCITY_ROTATION_HPP_ \ No newline at end of file +#endif // SRC_EXO3_VELOCITY_ROTATION_HPP_ diff --git a/src/exo3/cubed_sphere.cpp b/src/exo3/cubed_sphere.cpp index 90795f80..f4f35604 100644 --- a/src/exo3/cubed_sphere.cpp +++ b/src/exo3/cubed_sphere.cpp @@ -23,8 +23,6 @@ #include #endif -namespace cs = CubedSphereUtility; - CubedSphere::CubedSphere(MeshBlock *pmb) : pmy_block_(pmb) { int nc1 = pmb->ncells1, nc2 = pmb->ncells2, nc3 = pmb->ncells3; @@ -539,14 +537,10 @@ void CubedSphere::sendNeighborBlocks(int ox2, int ox3, int tg_rank, // Calculate the tag of destination #ifdef USE_NBLOCKS - if (tox2 == -1) - DirTag = 0 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; - if (tox2 == 1) - DirTag = 1 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; - if (tox3 == -1) - DirTag = 2 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; - if (tox3 == 1) - DirTag = 3 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; + if (tox2 == -1) DirTag = 0 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; + if (tox2 == 1) DirTag = 1 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; + if (tox3 == -1) DirTag = 2 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; + if (tox3 == 1) DirTag = 3 + 4 * pmb->gid + 24 * (bound_lim + 1) * tg_gid; #else if (tox2 == -1) DirTag = 0 + 4 * pmb->gid + 24 * (1 << (loc.level - 2)) * tg_gid; @@ -645,14 +639,10 @@ void CubedSphere::recvNeighborBlocks(int ox2, int ox3, int tg_rank, Real *data = new Real[dsize]; // Calculate the tag for receiving #ifdef USE_NBLOCKS - if (ox2 == -1) - DirTag = 0 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; - if (ox2 == 1) - DirTag = 1 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; - if (ox3 == -1) - DirTag = 2 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; - if (ox3 == 1) - DirTag = 3 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; + if (ox2 == -1) DirTag = 0 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; + if (ox2 == 1) DirTag = 1 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; + if (ox3 == -1) DirTag = 2 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; + if (ox3 == 1) DirTag = 3 + 4 * tg_gid + 24 * (bound_lim + 1) * pmb->gid; #else if (ox2 == -1) DirTag = 0 + 4 * tg_gid + 24 * (1 << (loc.level - 2)) * pmb->gid; diff --git a/src/exo3/cubed_sphere.hpp b/src/exo3/cubed_sphere.hpp index 9c8649d1..7cd05079 100644 --- a/src/exo3/cubed_sphere.hpp +++ b/src/exo3/cubed_sphere.hpp @@ -10,6 +10,10 @@ // canoe #include +#include + +#include "cubed_sphere_utility.hpp" +#include "gnomonic_equiangle.hpp" class CubedSphere { public: diff --git a/src/exo3/cubed_sphere_transform.cpp b/src/exo3/cubed_sphere_transform.cpp index 75f37ff6..f108993a 100644 --- a/src/exo3/cubed_sphere_transform.cpp +++ b/src/exo3/cubed_sphere_transform.cpp @@ -4,7 +4,7 @@ // athena #include -namespace CubedSphereUtility { +namespace cs { #define DBL_EPSILON 1.0e-10 @@ -197,4 +197,4 @@ void XYPFromRLL(Real lon, Real lat, Real &dX, Real &dY, int &nP) { dY = sy / sz; } -} // namespace CubedSphereUtility +} // namespace cs diff --git a/src/exo3/cubed_sphere_utility.cpp b/src/exo3/cubed_sphere_utility.cpp index 933f3231..ff9ee3c5 100644 --- a/src/exo3/cubed_sphere_utility.cpp +++ b/src/exo3/cubed_sphere_utility.cpp @@ -20,7 +20,7 @@ #include "cubed_sphere.hpp" #include "cubed_sphere_utility.hpp" -namespace CubedSphereUtility { +namespace cs { void PackDataR3(const AthenaArray &src, Real *buf, int sn, int en, int si, int ei, int sj, int ej, int sk, int ek, int &offset) { @@ -103,7 +103,8 @@ void InteprolateX2(const AthenaArray &src, AthenaArray &tgt, // Interpolation along X2 (j) axis, used before sending data to X3 (k) axis // Get the local indices int lv2_lx2, lv2_lx3, local_lx2, local_lx3, bound_lim; - CubedSphere::GetLocalIndex(&lv2_lx2, &lv2_lx3, &local_lx2, &local_lx3, &bound_lim, loc); + CubedSphere::GetLocalIndex(&lv2_lx2, &lv2_lx3, &local_lx2, &local_lx3, + &bound_lim, loc); int meshblock_size = ej - sj + 1; int N_blk = meshblock_size * @@ -233,7 +234,8 @@ void InteprolateX3(const AthenaArray &src, AthenaArray &tgt, // Interpolation along X3 (k) axis, used before sending data to ghost zone in // X2 (j) direction Get the local indices int lv2_lx2, lv2_lx3, local_lx2, local_lx3, bound_lim; - CubedSphere::GetLocalIndex(&lv2_lx2, &lv2_lx3, &local_lx2, &local_lx3, &bound_lim, loc); + CubedSphere::GetLocalIndex(&lv2_lx2, &lv2_lx3, &local_lx2, &local_lx3, + &bound_lim, loc); int meshblock_size = ek - sk + 1; int N_blk = meshblock_size * @@ -286,7 +288,7 @@ void InteprolateX3(const AthenaArray &src, AthenaArray &tgt, Real y1 = src_x3[src_pointer]; Real y2 = src_x3[src_pointer + 1]; Real yq = tgt_x3[k - sk]; - if ((n == IVY || n == IVZ) && (TypeFlag == 2)){ + if ((n == IVY || n == IVZ) && (TypeFlag == 2)) { // Projection needed, find the tgt locations first Real v1y = src(IVY, src_pointer - n_start - N_blk / 2 + sk, j, i); Real v1z = src(IVZ, src_pointer - n_start - N_blk / 2 + sk, j, i); @@ -402,7 +404,8 @@ void PackData(const AthenaArray &src, Real *buf, int sn, int en, int si, // Get the local indices int lv2_lx2, lv2_lx3, local_lx2, local_lx3, bound_lim; - CubedSphere::GetLocalIndex(&lv2_lx2, &lv2_lx3, &local_lx2, &local_lx3, &bound_lim, loc); + CubedSphere::GetLocalIndex(&lv2_lx2, &lv2_lx3, &local_lx2, &local_lx3, + &bound_lim, loc); // Work on interpolation AthenaArray interpolatedSrc; @@ -635,4 +638,4 @@ void get_latlon_on_sphere(Real *lat, Real *lon, MeshBlock const *pmb, int k, #endif // CUBED_SPHERE } -} // namespace CubedSphereUtility +} // namespace cs diff --git a/src/exo3/cubed_sphere_utility.hpp b/src/exo3/cubed_sphere_utility.hpp index 058f8c45..24600d81 100644 --- a/src/exo3/cubed_sphere_utility.hpp +++ b/src/exo3/cubed_sphere_utility.hpp @@ -5,7 +5,7 @@ #include #include -namespace CubedSphereUtility { +namespace cs { void PackData(const AthenaArray &src, Real *buf, int sn, int en, int si, int ei, int sj, int ej, int sk, int ek, int &offset, int ox1, @@ -40,6 +40,6 @@ void ContravariantToCovariant(A a, Real cth) { void get_latlon_on_sphere(Real *lat, Real *lon, MeshBlock const *pmb, int k, int j, int i); -} // namespace CubedSphereUtility +} // namespace cs #endif // SRC_EXO3_CUBED_SPHERE_UTILITY_HPP_ diff --git a/src/impl.cpp b/src/impl.cpp index c08d7298..05ed436f 100644 --- a/src/impl.cpp +++ b/src/impl.cpp @@ -25,27 +25,18 @@ // tracer #include "tracer/tracer.hpp" -// n-body -// #include "nbody/particles.hpp" - // astro #include "astro/celestrial_body.hpp" // exo3 #include "exo3/cubed_sphere.hpp" -// single column -#include "single_column/single_column.hpp" - // diagnostics #include "diagnostics/diagnostics.hpp" // forcing #include "forcing/forcing.hpp" -// surface -// #include "surface/surface.hpp" - // canoe #include "impl.hpp" #include "index_map.hpp" @@ -75,9 +66,6 @@ MeshBlock::Impl::Impl(MeshBlock *pmb, ParameterInput *pin) : pmy_block_(pmb) { // turbulence pturb = TurbulenceFactory::Create(pmb, pin); - // particle queue - // all_particles = ParticlesFactory::Create(pmb, pin); - // diagnostics all_diags = DiagnosticsFactory::CreateFrom(pmb, pin); @@ -87,12 +75,6 @@ MeshBlock::Impl::Impl(MeshBlock *pmb, ParameterInput *pin) : pmy_block_(pmb) { // cubed sphere pexo3 = std::make_shared(pmb); - // single column model - // pscm = std::make_shared(pmb, pin); - - // surface - // psurf = std::make_shared(pmb, pin); - // planet planet = PlanetFactory::CreateFrom(pmb, pin); } diff --git a/src/inversion/CMakeLists.txt b/src/inversion/CMakeLists.txt deleted file mode 100644 index eee43017..00000000 --- a/src/inversion/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -# Installs inversion library -# -# library: libinversion_debug.o -# library: libinversion_release.o -# -# Define the following variables -# -# INVERSION_INCLUDE_DIR -# INVERSION_LIBRARY_DEBUG -# INVERSION_LIBRARY_RELEASE -# -# Normal usage would be: -# -# include_directories( ${INVERSION_INCLUDE_DIR}) -# target_link_libraries( ${INVERSION_LIBRARY_DEBUG}) - -set(namel inversion) -string(TOUPPER ${namel} nameu) - -file(GLOB src_files - *.cpp - ) - -string(TOLOWER ${CMAKE_BUILD_TYPE} buildl) -string(TOUPPER ${CMAKE_BUILD_TYPE} buildu) - -add_library(${namel}_${buildl} - OBJECT - ${src_files} - ) - -target_include_directories(${namel}_${buildl} - PRIVATE - ${EIGEN3_INCLUDE_DIR} - ) - -set_target_properties(${namel}_${buildl} - PROPERTIES - COMPILE_FLAGS ${CMAKE_CXX_FLAGS_${buildu}} - ) diff --git a/src/inversion/composition_inversion.cpp b/src/inversion/composition_inversion.cpp deleted file mode 100644 index ce716214..00000000 --- a/src/inversion/composition_inversion.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// C/C++ -#include -#include - -// external -#include - -// athena -#include -#include -#include - -// application -#include - -// canoe -#include - -// snap -#include - -// inversion -#include "inversion.hpp" - -CompositionInversion::CompositionInversion(YAML::Node const &node) - : Inversion("composition") { - Application::Logger app("inversion"); - app->Log("Initializing CompositionInversion"); - char buf[80]; - - // species id - auto species = node["variables"].as>(); - SetSpeciesIndex(species); -} - -void CompositionInversion::UpdateModel(MeshBlock *pmb, - std::vector const &par, - int k) const { - Application::Logger app("inversion"); - app->Log("Update Model"); - auto pthermo = Thermodynamics::GetInstance(); - - auto air = AirParcelHelper::gather_from_primitive(pmb, k, ju_, pmb->is); - air.ToMoleFraction(); - - Real dlnp = 1.; - - // read in vapors - for (auto n : GetMySpeciesIndices()) { - air.w[n] = par[n]; - } - - for (int i = pmb->is; i <= pmb->ie; ++i) { - pthermo->Extrapolate(&air, -dlnp / 2., "dry"); - } -} diff --git a/src/inversion/gaussian_process.cpp b/src/inversion/gaussian_process.cpp deleted file mode 100644 index 1778317d..00000000 --- a/src/inversion/gaussian_process.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// C/C++ headers -#include "gaussian_process.hpp" - -#include - -#include -#include -#include -#include - -void gp_covariance(KernelFunction_t kernel, double **cov, double const *x, - double const *s, int n, double l) { - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) { - cov[i][j] = kernel(x[i], x[j], l, s[i] * s[j]); - } -} - -void gp_covariance2(KernelFunction_t kernel, double **cov, double const *x1, - double const *s1, int n1, double const *x2, - double const *s2, int n2, double l) { - for (int i = 0; i < n1; ++i) - for (int j = 0; j < n2; ++j) { - cov[i][j] = kernel(x1[i], x2[j], l, s1[i] * s2[j]); - } -} - -double gp_predict(KernelFunction_t kernel, double *arr2, double const *x2, - double const *s2, int n2, double const *arr1, - double const *x1, double const *s1, int n1, double len) { - double **cov1, **cov2; - NewCArray(cov1, n1, n1); - NewCArray(cov2, n2, n1); - - gp_covariance(kernel, cov1, x1, s1, n1, len); - gp_covariance2(kernel, cov2, x2, s2, n2, x1, s1, n1, len); - - // copy arr1 to b because the solution x=A^{-1}*b will be stored - // in b after calling lubksb - int *indx = new int[n1]; - double *b = new double[n1]; - memcpy(b, arr1, n1 * sizeof(double)); - - ludcmp(cov1, n1, indx); - lubksb(cov1, n1, indx, b); - mvdot(arr2, cov2, b, n2, n1); - - double d = -0.5 * vvdot(arr1, b, n1); - - delete[] b; - delete[] indx; - FreeCArray(cov1); - FreeCArray(cov2); - - // returns prior probability - return d; -} - -double gp_lnprior(KernelFunction_t kernel, double const *arr1, double const *x1, - double const *s1, int n1, double len) { - double **cov1; - NewCArray(cov1, n1, n1); - - gp_covariance(kernel, cov1, x1, s1, n1, len); - - int *indx = new int[n1]; - double d, *b = new double[n1]; - memcpy(b, arr1, n1 * sizeof(double)); - - ludcmp(cov1, n1, indx); - lubksb(cov1, n1, indx, b); - - d = -0.5 * vvdot(arr1, b, n1); - - delete[] b; - delete[] indx; - FreeCArray(cov1); - - // returns prior probability - return d; -} diff --git a/src/inversion/gaussian_process.hpp b/src/inversion/gaussian_process.hpp deleted file mode 100644 index 9a485b6f..00000000 --- a/src/inversion/gaussian_process.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef SRC_INVERSION_GAUSSIAN_PROCESS_HPP_ -#define SRC_INVERSION_GAUSSIAN_PROCESS_HPP_ - -#include - -typedef double (*KernelFunction_t)(double, double, double, double); - -inline double SquaredExponential(double x1, double x2, double l, - double s1s2 = 1.) { - return s1s2 * exp(-(x1 - x2) * (x1 - x2) / (2. * l * l)); -} - -inline double OrnsteinUhlenbeck(double x1, double x2, double l, - double s1s2 = 1.) { - return s1s2 * exp(-std::fabs(x1 - x2) / l); -} - -void gp_covariance(KernelFunction_t kernel, double **cov, double const *x, - double const *s, int n, double l); - -void gp_covariance2(KernelFunction_t kernel, double **cov, double const *x1, - double const *s1, int n1, double const *x2, - double const *s2, int n2, double l); - -double gp_predict(KernelFunction_t kernel, double *arr2, double const *x2, - double const *s2, int n2, double const *arr1, - double const *x1, double const *s1, int n1, double len); - -double gp_lnprior(KernelFunction_t kernel, double const *arr1, double const *x1, - double const *s1, int n1, double len); - -#endif // SRC_INVERSION_GAUSSIAN_PROCESS_HPP_ diff --git a/src/inversion/inversion.hpp b/src/inversion/inversion.hpp deleted file mode 100644 index 7b2d3945..00000000 --- a/src/inversion/inversion.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef SRC_INVERSION_INVERSION_HPP_ -#define SRC_INVERSION_INVERSION_HPP_ - -// C/C++ -#include -#include -#include - -// athena -#include - -// canoe -#include -#include -#include - -class MeshBlock; -namespace YAML { -class Node; -} - -//! \brief Base class for inversion -//! -//! This class is the base class for inversion. -//! It provides the interface for two functions, UpdateModel and GetSteps. -//! The UpdateModel function takes a vector of parameters and updates the model. -//! The parameters are to be adjusted for a better fit to the data. -//! The UpdateModel function may take several steps to update the model. -//! The results of each step are stored from index jl_ to ju_ (exclusive). -class Inversion : public NamedGroup, - public ParameterGroup, - public SpeciesIndexGroup { - public: - /// Constructor and destructor - Inversion(std::string name) : NamedGroup(name), jl_(0), ju_(0) {} - - virtual ~Inversion() {} - - virtual void UpdateModel(MeshBlock *pmb, std::vector const &par, - int k) const {} - - virtual int GetSteps() const { return 0; } - - void SetStepRange(int js, int je) { - jl_ = js; - ju_ = je; - } - - protected: - // step index range (j-direction) - int jl_, ju_; -}; - -class CompositionInversion : public Inversion { - public: - CompositionInversion(YAML::Node const &node); - ~CompositionInversion() {} - - int GetSteps() const override { return GetMySpeciesIndices().size(); } - - void UpdateModel(MeshBlock *pmb, std::vector const &par, - int k) const override; - - protected: - // prior standard deviation - Real Xstd_[1 + NVAPOR]; -}; - -class ProfileInversion : public Inversion { - public: - ProfileInversion(YAML::Node const &node); - ~ProfileInversion() {} - - void UpdateModel(MeshBlock *pmb, std::vector const &par, - int k) const override; - - void UpdateProfiles(Hydro *phydro, Real **XpSample, int k, int jl, - int ju) const; - - int GetSteps() const override { return GetMySpeciesIndices().size() + 1; } - - protected: - void enforceStability(AirColumn &ac) const; - - protected: - // pressure levels - std::vector plevel_; - - // hyper-parameters - Real chi_; - std::vector Xstd_; - std::vector Xlen_; -}; - -using InversionPtr = std::shared_ptr; - -class InversionFactory { - public: - static std::vector CreateFrom(YAML::Node const &node); -}; - -#endif // SRC_INVERSION_INVERSION_HPP_ diff --git a/src/inversion/inversion_factory.cpp b/src/inversion/inversion_factory.cpp deleted file mode 100644 index b90289b8..00000000 --- a/src/inversion/inversion_factory.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// C/C++ -#include - -// external -#include - -// application -#include -#include - -// athena -#include - -// utils -#include - -// inversion -#include "inversion.hpp" - -std::vector InversionFactory::CreateFrom(YAML::Node const& node) { - Application::Logger app("inversion"); - app->Log("Create inversion queue"); - - if (!node["tasks"]) { - throw NotFoundError("InversionFactory::CreateFrom", "tasks"); - } - - if (!node["tasks"].IsSequence()) { - throw RuntimeError("InversionFactory::CreateFrom", - "tasks must be a sequence"); - } - - std::vector task_names; - - for (auto const& item : node["tasks"]) { - task_names.push_back(item.as()); - } - - std::vector all_fits; - InversionPtr pfit; - - int jl = NGHOST, ju = NGHOST; - for (auto p : task_names) { - if (p == "profile") { - pfit = std::make_shared(node["profile"]); - } else if (p == "composition") { - pfit = std::make_shared(node["composition"]); - } else { - throw NotFoundError("CreateAllInversions", p); - } - - ju += pfit->GetSteps(); - pfit->SetStepRange(jl, ju); - jl = ju; - all_fits.push_back(std::move(pfit)); - } - - app->Log("Number of inversions = " + std::to_string(all_fits.size())); - - return all_fits; -} diff --git a/src/inversion/profile_inversion.cpp b/src/inversion/profile_inversion.cpp deleted file mode 100644 index b31ba46c..00000000 --- a/src/inversion/profile_inversion.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// C/C++ -#include -#include -#include -#include -#include - -// external -#include - -// canoe -#include -#include - -// climath -#include - -// athena -#include -#include -#include -#include -#include - -// application -#include -#include - -// snap -#include -#include - -// utils -#include -#include - -// inversion -#include "gaussian_process.hpp" -#include "inversion.hpp" - -ProfileInversion::ProfileInversion(YAML::Node const &node) - : Inversion("profile") { - Application::Logger app("inversion"); - app->Log("Initializing ProfileInversion"); - - // species id - auto species = node["variables"].as>(); - SetSpeciesIndex(species); - - // Pressure sample - plevel_ = node["sample-pressures"].as>(); - - // add boundaries - Real pmax = node["bottom-pressure"].as(); - Real pmin = node["top-pressure"].as(); - - if (pmax < (plevel_.front() + 1.E-6)) - throw RuntimeError("ProfileInversion", - "Pmax < " + std::to_string(plevel_.front())); - - if (pmin > (plevel_.back() - 1.E-6)) - throw RuntimeError("ProfileInversion", - "Pmin > " + std::to_string(plevel_.back())); - - plevel_.insert(plevel_.begin(), pmax); - plevel_.push_back(pmin); - - // bar -> pa - for (size_t n = 0; n < plevel_.size(); ++n) { - plevel_[n] *= 1.E5; - } -} - -void ProfileInversion::UpdateModel(MeshBlock *pmb, std::vector const &par, - int k) const { - Application::Logger app("inversion"); - app->Log("Update Model"); - - auto pthermo = Thermodynamics::GetInstance(); - - int nlayer = pmb->ie - pmb->is + 1; - int nvar = GetMySpeciesIndices().size(); - int nsample = plevel_.size(); - - std::vector zlev(nsample); - Real P0 = pmb->pcoord->GetReferencePressure(); - Real H0 = pmb->pcoord->GetPressureScaleHeight(); - - for (int i = 0; i < nsample; ++i) { - zlev[i] = -H0 * log(plevel_[i] / P0); - } - - // calculate the covariance matrix of T - std::vector stdAll(nlayer); - std::vector stdSample(nsample); - - Real const **XpSample; - Real **Xp; - - XpSample = new Real const *[nvar]; - for (size_t n = 0; n < GetMySpeciesIndices().size(); ++n) { - XpSample[n] = &par[nvar * nsample]; - } - - NewCArray(Xp, nvar, nlayer); - - Real Rd = pthermo->GetRd(); - Real chi = GetPar("chi"); - int is = pmb->is, ie = pmb->ie; - - // calculate perturbed profiles - auto pcoord = pmb->pcoord; - auto ac = AirParcelHelper::gather_from_primitive(pmb, k, jl_, is, ie); - - for (size_t n = 0; n < nvar; ++n) { - int m = mySpeciesId(n); - - for (int i = is; i <= ie; ++i) - stdAll[i - is] = Xstd_[n] * pow(exp(pcoord->x1v(i) / H0), chi); - - for (int i = 0; i < nsample; ++i) - stdSample[i] = Xstd_[n] * pow(exp(zlev[i] / H0), chi); - - gp_predict(SquaredExponential, Xp[n], &pcoord->x1v(is), stdAll.data(), - nlayer, XpSample[n], zlev.data(), stdSample.data(), nsample, - Xlen_[n]); - - for (int i = 0; i < nlayer; ++i) { - ac[i].ToMoleFraction(); - - // do not alter levels lower than zlev[0] or higher than zlev[nsample-1] - if (pcoord->x1v(is + i) < zlev[0] || - pcoord->x1v(is + i) > zlev[nsample - 1]) - continue; - - // save perturbed T profile - if (m == IDN) { - if (ac[i].w[IDN] + Xp[n][i] < 0.) { - ac[i].w[IDN] = 1.; // min 1K temperature - } else { - ac[i].w[IDN] += Xp[n][i]; - } - } else { // save perturbed compositional profiles - ac[i].w[m] += Xp[n][i - is]; - ac[i].w[m] = std::max(ac[i].w[m], 0.); - ac[i].w[m] = std::min(ac[i].w[m], 1.); - } - } - - AirParcelHelper::distribute_to_primitive(pmb, k, jl_ + n, ac); - } - - enforceStability(ac); - AirParcelHelper::distribute_to_primitive(pmb, k, ju_, ac); - - delete[] XpSample; - FreeCArray(Xp); -} - -void ProfileInversion::enforceStability(AirColumn &ac) const { - Application::Logger app("inversion"); - app->Log("Enforce stability"); - - auto pthermo = Thermodynamics::GetInstance(); - - for (int i = 1; i < ac.size(); ++i) { - auto air = ac[i - 1]; - air.ToMoleFraction(); - - Real dlnp = ac[i].w[IPR] / ac[i - 1].w[IPR]; - pthermo->Extrapolate(&air, dlnp, "neutral"); - - air.ToMassFraction(); - - // stability - ac[i].w[IDN] = std::min(air.w[IDN], ac[i].w[IDN]); - - // saturation - for (int n = 1; n <= NVAPOR; ++n) { - Real rh = get_relative_humidity(ac[i], n); - if (rh > 1.) ac[i].w[n] /= rh; - } - } -} diff --git a/src/inversion/todo/inversion_helper.cpp b/src/inversion/todo/inversion_helper.cpp deleted file mode 100644 index ed4b6814..00000000 --- a/src/inversion/todo/inversion_helper.cpp +++ /dev/null @@ -1,57 +0,0 @@ - -namespace InversionHelper { -#define MAX_LINE 512 -void read_observation_file(Eigen::VectorXd *target, Eigen::MatrixXd *icov, - std::string fname) { - std::stringstream msg; - FILE *fp = fopen(fname.c_str(), "r"); - if (fp == NULL) { - msg << "### FATAL ERROR in ProfileInversion::ReadObseravtionFile" - << std::endl - << fname << " cannot be opened."; - ATHENA_ERROR(msg); - } - char line[MAX_LINE], *pl; - - int rows; - // header - pl = NextLine(line, MAX_LINE, fp); - - // target values - sscanf(pl, "%d", &rows); - target->resize(rows); - icov->resize(rows, rows); - - for (int i = 0; i < rows; ++i) { - pl = NextLine(line, MAX_LINE, fp); - sscanf(pl, "%lf", &(*target)(i)); - } - - // inverse covariance matrix - char *saveptr; - for (int i = 0; i < rows; ++i) { - pl = NextLine(line, MAX_LINE, fp); - char *p = strtok_r(pl, " ", &saveptr); - for (int j = 0; j < rows; ++j) { - sscanf(p, "%lf", &(*icov)(i, j)); - p = strtok_r(NULL, " ", &saveptr); - } - } - - fclose(fp); -} -#undef MAX_LINE - -void gather_probability(std::vector const &fitq) { - auto qlast = fitq[fitq.size() - 1]; - - // replace the log probability by the last one - for (auto q : fitq) { - int nwalker = q->GetWalkers(); - - for (int k = 0; k < nwalker; ++k) { - q->SetLogProbability(k, qlast->GetLogProbability(k)); - } - } -} -} // namespace InversionHelper diff --git a/src/inversion/todo/juno_profile_inversion_target.cpp b/src/inversion/todo/juno_profile_inversion_target.cpp deleted file mode 100644 index 8440ed3f..00000000 --- a/src/inversion/todo/juno_profile_inversion_target.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** @file calculate_fit_target.cpp - * @brief - * - * @author Cheng Li (chengcli@umich.edu) - * @date Thursday Nov 18, 2021 21:07:59 EST - * @bug No known bugs. - */ - -// C/C++ headers -#include -#include - -// climath -#include -#include - -// athena -#include -#include - -// application -#include -#include - -// harp -#include -#include - -// inversion -#include "profile_inversion.hpp" - -void JunoProfileInversion::CalculateFitTarget(Radiation const *prad, Real *val, - int nvalue, int k, int j) const { - std::stringstream msg; - Application::Logger app("inversioon"); - - app->Log("JunoProfileInversion::CalculateFitTarget"); - app->Log("model = " + std::to_string(j)); - - if (nvalue != 2 * prad->GetNumBands()) { - throw ValueError("CalculateFitTarget", "nvalue", prad->GetNumBands(), - nvalue); - } - - // 11. log likelihood - std::vector mus, tbs; - - for (int b = 0; b < prad->GetNumBands(); ++b) { - auto pband = prad->GetBand(b); - - // emission angles; - int ndir = pband->GetNumOutgoingRays(); - mus.resize(ndir); - tbs.resize(ndir); - - for (int n = 0; n < ndir; ++n) mus[n] = pband->GetCosinePolarAngle(n); - - // brightness temperatures - val[b * 2] = pband->btoa(0, k, j); - - // limb darkening - for (int n = 0; n < ndir; ++n) tbs[n] = pband->btoa(n, k, j); - - Real tb45 = interp1(cos(45. / 180. * M_PI), tbs.data(), mus.data(), ndir); - val[b * 2 + 1] = (tbs[0] - tb45) / tbs[0] * 100.; - - if (fit_differential_) { - // brightness temperatures - val[b * 2] -= pband->btoa(0, k, pmy_block_->js - 1); - - // limb darkening - for (int n = 0; n < ndir; ++n) - tbs[n] = pband->btoa(n, k, pmy_block_->js - 1); - - tb45 = interp1(cos(45. / 180. * M_PI), tbs.data(), mus.data(), ndir); - val[b * 2 + 1] -= (tbs[0] - tb45) / tbs[0] * 100.; - } - } - - // app->Log("foward model results = ", val, nvalue); -} diff --git a/src/inversion/todo/mcmc.cpp b/src/inversion/todo/mcmc.cpp deleted file mode 100644 index 5aa38331..00000000 --- a/src/inversion/todo/mcmc.cpp +++ /dev/null @@ -1,898 +0,0 @@ -// C/C++ -#include -#include -#include -#include -#include -#include - -// canoe -#include - -#ifdef FITSOUTPUT -extern "C" { -#include -} -#endif - -// climath -#include - -// utils -#include - -// inversion -#include "mcmc.hpp" - -void _choldc(double **a, int n, double *p) { - int i, j, k; - double sum; - - for (i = 0; i < n; ++i) - for (j = i; j < n; ++j) { - for (sum = a[i][j], k = i - 1; k >= 0; --k) { - sum -= a[i][k] * a[j][k]; - } - if (i == j) { - assert(sum > 0.); - p[i] = sqrt(sum); - } else { - a[j][i] = sum / p[i]; - } - } -} - -// Compute tau directly only if tau < TAUMAX. -// Otherwise compute tau using the pairwise sum series -#define TAUMAX 2 - -// Compute autocovariances up to lag s = WINMULT*TAU -#define WINMULT 5 - -// The autocovariance array is double C[MAXLAG+1] -// so that C[s] makes sense for s = MAXLAG. -#define MAXLAG TAUMAX *WINMULT - -// Stop and print an error message if the array is shorter -// than MINFAC * MAXLAG. -#define MINFAC 5 - -int _acor(double *mean, double *sigma, double *tau, double *X, int L) { - *mean = 0.; // Compute the mean of X ... - for (int i = 0; i < L; i++) *mean += X[i]; - *mean = *mean / L; - for (int i = 0; i < L; i++) X[i] -= *mean; // ... and subtract it away. - - if (L < MINFAC * MAXLAG) { - // printf("Acor error 1: The autocorrelation time is too long relative to - // the variance.\n"); - return 1; - } - - double C[MAXLAG + 1]; - for (int s = 0; s <= MAXLAG; s++) - C[s] = - 0.; // Here, s=0 is the variance, s = MAXLAG is the last one computed. - - int iMax = L - MAXLAG; // Compute the autocovariance function . . . - for (int i = 0; i < iMax; i++) - for (int s = 0; s <= MAXLAG; s++) - C[s] += X[i] * X[i + s]; // ... first the inner products ... - for (int s = 0; s <= MAXLAG; s++) - C[s] = C[s] / iMax; // ... then the normalization. - - double D = - C[0]; // The "diffusion coefficient" is the sum of the autocovariances - for (int s = 1; s <= MAXLAG; s++) - D += 2 * - C[s]; // The rest of the C[s] are double counted since C[-s] = C[s]. - *sigma = sqrt( - D / L); // The standard error bar formula, if D were the complete sum. - *tau = D / C[0]; // A provisional estimate, since D is only part of the - // complete sum. - - if (*tau * WINMULT < MAXLAG) { - return 0; // Stop if the D sum includes the given multiple of tau. - // This is the self consistent window approach. - - } else { // If the provisional tau is so large that we don't think tau - // is accurate, apply the acor procedure to the pairwase sums - // of X. - int Lh = L / 2; // The pairwise sequence is half the length (if L is even) - double newMean; // The mean of the new sequence, to throw away. - int j1 = 0; - int j2 = 1; - for (int i = 0; i < Lh; i++) { - X[i] = X[j1] + X[j2]; - j1 += 2; - j2 += 2; - } - _acor(&newMean, sigma, tau, X, Lh); - D = .25 * (*sigma) * (*sigma) * - L; // Reconstruct the fine time series numbers from the coarse series - // numbers. - *tau = D / C[0]; // As before, but with a corrected D. - *sigma = sqrt(D / L); // As before, again. - } - - return 0; -} - -#undef TAUMAX -#undef WINMULT -#undef MAXLAG -#undef MINFAC - -void mcmc_alloc(mcmc_recs *recs, int nstep, int nwalker, int ndim, int nvalue) { - recs->nstep = nstep; - recs->nwalker = nwalker; - recs->ndim = ndim; - recs->nvalue = nvalue; - - NewCArray(recs->par, nstep, nwalker, ndim); - NewCArray(recs->val, nstep, nwalker, nvalue); - NewCArray(recs->lnp, nstep, nwalker); - NewCArray(recs->newstate, nstep, nwalker); - - memset(recs->par[0][0], 0, nstep * nwalker * ndim * sizeof(double)); - memset(recs->val[0][0], 0, nstep * nwalker * nvalue * sizeof(double)); - memset(recs->lnp[0], 0, nstep * nwalker * sizeof(double)); - memset(recs->newstate[0], 0, nstep * nwalker * sizeof(int)); - - recs->opt_par = new double[ndim]; - recs->opt_val = new double[nvalue]; - - recs->cur = 0; - recs->accept = 0; - recs->reset = 0; - recs->opt_lnp = -1.E10; -} - -void mcmc_free(mcmc_recs *recs) { - FreeCArray(recs->par); - FreeCArray(recs->val); - FreeCArray(recs->lnp); - FreeCArray(recs->newstate); - delete[] recs->opt_par; - delete[] recs->opt_val; -} - -void mcmc_statistics(double *mean, double *sigma, double *tau, - mcmc_recs *recs) { - double *x = new double[recs->cur]; - - for (size_t p = 0; p < recs->ndim; ++p) { - for (size_t t = 0; t < recs->cur; ++t) { - x[t] = 0.; - for (size_t k = 0; k < recs->nwalker; ++k) x[t] += recs->par[t][k][p]; - x[t] /= recs->nwalker; - } - - int err = _acor(mean + p, sigma + p, tau + p, x, recs->cur); - - if (err != 0) tau[p] = -1.; - } - - delete[] x; -} - -void mcmc_save_fits(char const *fname, mcmc_opts *opts, mcmc_recs *recs, - int include_last) { - double ***buf; - int ***ibuf; - - double ***par, ***val, **lnp; - int **newstate; - - // indices - int rank = 0, size = 1; - int nwalker = recs->nwalker; - int ndim = recs->ndim; - int nvalue = recs->nvalue; - int cur = include_last ? recs->cur : recs->cur - 1; - - int accept = recs->accept; - int reset = recs->reset; - double opt_lnp = recs->opt_lnp; - - // do not make outputs if cur <= 0 - if (cur <= 0) return; - -#ifdef MPI_PARALLEL - MPI_Comm_rank(opts->mpi_comm, &rank); - MPI_Comm_size(opts->mpi_comm, &size); - - NewCArray(par, cur, size * nwalker, ndim); - NewCArray(val, cur, size * nwalker, nvalue); - NewCArray(lnp, cur, size * nwalker); - NewCArray(newstate, cur, size * nwalker); - - // 1. gather walker positions - NewCArray(buf, size, cur * nwalker, ndim); - MPI_Gather(**recs->par, cur * nwalker * ndim, MPI_DOUBLE, **buf, - cur * nwalker * ndim, MPI_DOUBLE, 0, opts->mpi_comm); - if (rank == 0) { // reorder dimension - for (int t = 0; t < cur; ++t) - for (int r = 0; r < size; ++r) - for (int k = 0; k < nwalker; ++k) - for (int d = 0; d < ndim; ++d) - par[t][r * nwalker + k][d] = buf[r][t * nwalker + k][d]; - } - FreeCArray(buf); - - // 2. gather function values - NewCArray(buf, size, cur * nwalker, nvalue); - MPI_Gather(**recs->val, cur * nwalker * nvalue, MPI_DOUBLE, **buf, - cur * nwalker * nvalue, MPI_DOUBLE, 0, opts->mpi_comm); - if (rank == 0) { // reorder dimension - for (int t = 0; t < cur; ++t) - for (int r = 0; r < size; ++r) - for (int k = 0; k < nwalker; ++k) - for (int d = 0; d < nvalue; ++d) - val[t][r * nwalker + k][d] = buf[r][t * nwalker + k][d]; - } - FreeCArray(buf); - - // 3. gather log probability - NewCArray(buf, size, cur, nwalker); - MPI_Gather(*recs->lnp, cur * nwalker, MPI_DOUBLE, **buf, cur * nwalker, - MPI_DOUBLE, 0, opts->mpi_comm); - if (rank == 0) { // reorder dimension - for (int t = 0; t < cur; ++t) - for (int r = 0; r < size; ++r) - for (int k = 0; k < nwalker; ++k) - lnp[t][r * nwalker + k] = buf[r][t][k]; - } - FreeCArray(buf); - - // 4. reduce optimal log probability - MPI_Reduce(&recs->opt_lnp, &opt_lnp, 1, MPI_DOUBLE, MPI_MAX, 0, - opts->mpi_comm); - - // 5. reduce accepted states - MPI_Reduce(&recs->accept, &accept, 1, MPI_INT, MPI_SUM, 0, opts->mpi_comm); - - // 6. reduce resetted states - MPI_Reduce(&recs->reset, &reset, 1, MPI_INT, MPI_SUM, 0, opts->mpi_comm); - - // 7. gather new state indicator - NewCArray(ibuf, size, cur, nwalker); - MPI_Gather(*recs->newstate, cur * nwalker, MPI_INT, **ibuf, cur * nwalker, - MPI_INT, 0, opts->mpi_comm); - if (rank == 0) { // reorder dimension - for (int t = 0; t < cur; ++t) - for (int r = 0; r < size; ++r) - for (int k = 0; k < nwalker; ++k) - newstate[t][r * nwalker + k] = ibuf[r][t][k]; - } - FreeCArray(ibuf); -#endif - - // 6. write FITS file -#ifdef FITSOUTPUT - if (rank == 0) { - fitsfile *fp; - int status = 0; - long naxis = 3; - long naxes[3] = {ndim, size * nwalker, cur}; - long fpixel = 1; - long nelements = naxes[0] * naxes[1] * naxes[2]; - - fits_create_file(&fp, fname, &status); - if (status) fits_report_error(stderr, status); - - // 6.1 create parameter fields - fits_create_img(fp, DOUBLE_IMG, naxis, naxes, &status); - if (status) fits_report_error(stderr, status); - - // 6.2 write parameter fields -#ifdef MPI_PARALLEL - fits_write_img(fp, TDOUBLE, fpixel, nelements, **par, &status); -#else - fits_write_img(fp, TDOUBLE, fpixel, nelements, **recs->par, &status); -#endif - if (status) fits_report_error(stderr, status); - - // 6.3 write headers - char key[80] = "C.Li"; - fits_write_key(fp, TSTRING, "CREATOR", key, "file created by Cheng Li", - &status); - - snprintf(key, sizeof(key), "%s", "par"); - fits_write_key(fp, TSTRING, "VAR", key, "retrieved parameters", &status); - - snprintf(key, sizeof(key), "%s", "MCMC"); - fits_write_key(fp, TSTRING, "METHOD", key, "retrieval method", &status); - - fits_write_key(fp, TDOUBLE, "A", &opts->a, "stretch move parameter", - &status); - fits_write_key(fp, TINT, "P", &opts->p, "walk move parameter", &status); - - fits_write_key(fp, TDOUBLE, "LOGP", &opt_lnp, "optimal log probability", - &status); - fits_write_key(fp, TINT, "RESET", &reset, "number of resetted states", - &status); - fits_write_key(fp, TINT, "ACCEPT", &accept, "number of accepted states", - &status); - - // 6.4 create function value fields, 2nd HDU - naxes[0] = nvalue; - nelements = naxes[0] * naxes[1] * naxes[2]; - fits_create_img(fp, DOUBLE_IMG, naxis, naxes, &status); - if (status) fits_report_error(stderr, status); - - // write function values -#ifdef MPI_PARALLEL - fits_write_img(fp, TDOUBLE, fpixel, nelements, **val, &status); -#else - fits_write_img(fp, TDOUBLE, fpixel, nelements, **recs->val, &status); -#endif - if (status) fits_report_error(stderr, status); - - snprintf(key, sizeof(key), "%s", "val"); - fits_write_key(fp, TSTRING, "VAR", key, "values of forward model", &status); - - // 6.5 create log probability fields, 3rd HDU - naxis = 2; - nelements = naxes[1] * naxes[2]; - fits_create_img(fp, DOUBLE_IMG, naxis, naxes + 1, &status); - if (status) fits_report_error(stderr, status); - - snprintf(key, sizeof(key), "%s", "lnp"); - fits_write_key(fp, TSTRING, "VAR", key, "log probability", &status); - - // write log probability -#ifdef MPI_PARALLEL - fits_write_img(fp, TDOUBLE, fpixel, nelements, *lnp, &status); -#else - fits_write_img(fp, TDOUBLE, fpixel, nelements, *recs->lnp, &status); -#endif - if (status) fits_report_error(stderr, status); - - // 6.6 create newstate masks, 4th HDU - fits_create_img(fp, SHORT_IMG, naxis, naxes + 1, &status); - if (status) fits_report_error(stderr, status); - - snprintf(key, sizeof(key), "%s", "inew"); - fits_write_key(fp, TSTRING, "VAR", key, "new state indicator", &status); - - // write new state indicator -#ifdef MPI_PARALLEL - fits_write_img(fp, TINT, fpixel, nelements, *newstate, &status); -#else - fits_write_img(fp, TINT, fpixel, nelements, *recs->newstate, &status); -#endif - if (status) fits_report_error(stderr, status); - - fits_close_file(fp, &status); - } -#endif // FITSOUTPUT - -#ifdef MPI_PARALLEL - FreeCArray(par); - FreeCArray(val); - FreeCArray(lnp); - FreeCArray(newstate); -#endif -} - -void mcmc_load_fits(char const *fname, mcmc_opts *opts, mcmc_recs *recs, - int alloc) { - int status = 0, hdutype; - int nstep, nwalker, ndim, nvalue; - long dims[3] = {1, 1, 1}; - long fpixel[3] = {1, 1, 1}; - -#ifdef FITSOUTPUT - fitsfile *fp; - - // open FITS file - fits_open_file(&fp, fname, READONLY, &status); - if (status) { - fits_report_error(stderr, status); - exit(1); - } - - // move to the first hdu, containing the parameters - fits_movabs_hdu(fp, 1, &hdutype, &status); - - // read img dimensions - fits_get_img_size(fp, 3, dims, &status); - nstep = dims[2]; - nwalker = dims[1]; - ndim = dims[0]; - - // move to the second hdu, containing the values of the forward model - fits_movabs_hdu(fp, 2, &hdutype, &status); - fits_get_img_size(fp, 3, dims, &status); - nvalue = dims[0]; - - // allocate memory - if (alloc) { - mcmc_alloc(recs, nstep, nwalker, ndim, nvalue); - } else { - assert(recs->nstep >= nstep); - assert(recs->nwalker == nwalker); - assert(recs->ndim == ndim); - assert(recs->nvalue == nvalue); - } - - // move to first hdu, read positions - fits_movabs_hdu(fp, 1, &hdutype, &status); - fits_read_pix(fp, TDOUBLE, fpixel, nstep * nwalker * ndim, NULL, **recs->par, - NULL, &status); - - // read keywords - fits_read_key(fp, TDOUBLE, "LOGP", &recs->opt_lnp, NULL, &status); - fits_read_key(fp, TDOUBLE, "A", &opts->a, NULL, &status); - fits_read_key(fp, TINT, "P", &opts->p, NULL, &status); - fits_read_key(fp, TINT, "RESET", &recs->reset, NULL, &status); - fits_read_key(fp, TINT, "ACCEPT", &recs->accept, NULL, &status); - - // move to second hdu, read values - fits_movabs_hdu(fp, 2, &hdutype, &status); - fits_read_pix(fp, TDOUBLE, fpixel, nstep * nwalker * nvalue, NULL, - **recs->val, NULL, &status); - - // move to third hdu, read lnp - fits_movabs_hdu(fp, 3, &hdutype, &status); - fits_read_pix(fp, TDOUBLE, fpixel, nstep * nwalker, NULL, *recs->lnp, NULL, - &status); - - // move to forth hdu, read new state indicator - fits_movabs_hdu(fp, 4, &hdutype, &status); - // fits_read_pix(fp, TSHORT, fpixel, nstep*nwalker, NULL, - fits_read_pix(fp, TINT, fpixel, nstep * nwalker, NULL, *recs->newstate, NULL, - &status); - - if (status) { - fits_report_error(stderr, status); - exit(1); - } - - recs->cur = nstep; - - fits_close_file(fp, &status); -#endif -} - -void mcmc_append_recs(mcmc_recs *dst, mcmc_recs *src) { - assert(dst->ndim == src->ndim); - assert(dst->nvalue == src->nvalue); - assert(dst->nwalker == src->nwalker); - assert(dst->nstep >= dst->cur + src->cur); - - int size_par = src->cur * src->nwalker * src->ndim; - int size_val = src->cur * src->nwalker * src->nvalue; - int size_lnp = src->cur * src->nwalker; - int cur = dst->cur; - - memcpy(*dst->par[cur], **src->par, size_par * sizeof(double)); - memcpy(*dst->val[cur], **src->val, size_val * sizeof(double)); - memcpy(dst->lnp[cur], *src->lnp, size_lnp * sizeof(double)); - memcpy(dst->newstate[cur], *src->newstate, size_lnp * sizeof(int)); - - if (dst->opt_lnp < src->opt_lnp) { - memcpy(dst->opt_par, src->opt_par, src->ndim * sizeof(double)); - memcpy(dst->opt_val, src->opt_val, src->nvalue * sizeof(double)); - dst->opt_lnp = src->opt_lnp; - } - - dst->cur += src->cur; - dst->accept += src->accept; - dst->reset += src->reset; -} - -void mcmc_report(mcmc_opts *opts, mcmc_recs *recs, char const *mode) { - int rank = 0, size = 1; - double **par, *lnp, **opt_par, **opt_val; - int accept; - double *mean, *sigma, *tau, **cov; - - struct { - double value; - int rank; - } opt_lnp; - - // indices - int nwalker = recs->nwalker; - int ndim = recs->ndim; - int nvalue = recs->nvalue; - int cur = recs->cur; - - // local statistics - mean = new double[ndim]; - sigma = new double[ndim]; - tau = new double[ndim]; - NewCArray(cov, ndim, ndim); - mcmc_statistics(mean, sigma, tau, recs); - - // amend the calculation of standard deviation - for (int d = 0; d < ndim; ++d) { - sigma[d] = 0.; - for (int t = 0; t < cur; ++t) - for (int k = 0; k < nwalker; ++k) - sigma[d] += sqr(recs->par[t][k][d] - mean[d]); - } - - // calculate correlation coefficients - for (int i = 0; i < ndim; ++i) - for (int j = 0; j < ndim; ++j) { - cov[i][j] = 0; - for (int t = 0; t < cur; ++t) - for (int k = 0; k < nwalker; ++k) - cov[i][j] += - (recs->par[t][k][i] - mean[i]) * (recs->par[t][k][j] - mean[j]); - } - -#ifdef MPI_PARALLEL - MPI_Comm_rank(opts->mpi_comm, &rank); - MPI_Comm_size(opts->mpi_comm, &size); - - lnp = new double[nwalker * size]; - NewCArray(par, nwalker * size, ndim); - NewCArray(opt_par, size, ndim); - NewCArray(opt_val, size, nvalue); - - // 1. gather walker positions - MPI_Gather(*recs->par[cur - 1], nwalker * ndim, MPI_DOUBLE, *par, - nwalker * ndim, MPI_DOUBLE, 0, opts->mpi_comm); - - // 2. gather log probability - MPI_Gather(recs->lnp[cur - 1], nwalker, MPI_DOUBLE, lnp, nwalker, MPI_DOUBLE, - 0, opts->mpi_comm); - - // 3. gather optimal positions - MPI_Gather(recs->opt_par, ndim, MPI_DOUBLE, *opt_par, ndim, MPI_DOUBLE, 0, - opts->mpi_comm); - - // 4. gather optimal forward result - MPI_Gather(recs->opt_val, nvalue, MPI_DOUBLE, *opt_val, nvalue, MPI_DOUBLE, 0, - opts->mpi_comm); - - // 5. reduce optimal log probability with rank - opt_lnp.value = recs->opt_lnp; - opt_lnp.rank = rank; - if (rank == 0) - MPI_Reduce(MPI_IN_PLACE, &opt_lnp, 1, MPI_DOUBLE_INT, MPI_MAXLOC, 0, - opts->mpi_comm); - else - MPI_Reduce(&opt_lnp, &opt_lnp, 1, MPI_DOUBLE_INT, MPI_MAXLOC, 0, - opts->mpi_comm); - - // 6. reduce total number of accepted states - MPI_Reduce(&recs->accept, &accept, 1, MPI_INT, MPI_SUM, 0, opts->mpi_comm); - - // 7. reduce mean value - MPI_Allreduce(MPI_IN_PLACE, mean, ndim, MPI_DOUBLE, MPI_SUM, opts->mpi_comm); - for (int d = 0; d < ndim; ++d) mean[d] /= size; - - // 8. reduce standard deviation - if (rank == 0) - MPI_Reduce(MPI_IN_PLACE, sigma, ndim, MPI_DOUBLE, MPI_SUM, 0, - opts->mpi_comm); - else - MPI_Reduce(sigma, sigma, ndim, MPI_DOUBLE, MPI_SUM, 0, opts->mpi_comm); - - // 9. reduce correlation coefficients - if (rank == 0) - MPI_Reduce(MPI_IN_PLACE, *cov, ndim * ndim, MPI_DOUBLE, MPI_SUM, 0, - opts->mpi_comm); - else - MPI_Reduce(*cov, *cov, ndim * ndim, MPI_DOUBLE, MPI_SUM, 0, opts->mpi_comm); - - // 10. reduce autocorrelation time - if (rank == 0) - MPI_Reduce(MPI_IN_PLACE, tau, ndim, MPI_DOUBLE, MPI_SUM, 0, opts->mpi_comm); - else - MPI_Reduce(tau, tau, ndim, MPI_DOUBLE, MPI_SUM, 0, opts->mpi_comm); - for (int d = 0; d < ndim; ++d) tau[d] /= size; -#else - par = recs->par[cur - 1]; - lnp = recs->lnp[cur - 1]; - opt_par = new double *[1]; - opt_par[0] = recs->opt_par; - opt_val = new double *[1]; - opt_val[0] = recs->opt_val; - opt_lnp.value = recs->opt_lnp; - opt_lnp.rank = rank; - accept = recs->accept; -#endif - - // final step for standard deviation - for (int d = 0; d < ndim; ++d) - sigma[d] = sqrt(sigma[d] / (nwalker * size * cur)); - - // final step for correlation coefficients - for (int i = 0; i < ndim; ++i) - for (int j = 0; j < ndim; ++j) cov[i][j] /= size * nwalker * cur; - - // report - if (rank == 0) { - FILE *fout = fopen(opts->logfile, mode); - - fprintf(fout, "#### MCMC Iteration: No. %d ####\n", recs->reset + cur); - // 1. walkers positions - fprintf(fout, "1. Current positions:\n"); - fprintf(fout, "%3s", " "); - for (int d = 0; d < ndim; ++d) fprintf(fout, "%9s%-2d", "D", d + 1); - fprintf(fout, "\n"); - for (int k = 0; k < nwalker * size; k++) { - fprintf(fout, "%3d", static_cast(k) + 1); - for (int d = 0; d < ndim; ++d) fprintf(fout, "%11.4g", par[k][d]); - fprintf(fout, " |%9.4f\n", lnp[k]); - fflush(stdout); - } - - // 2. optimal position - fprintf(fout, "2. Optimal parameters:\n"); - fprintf(fout, "%3s", " "); - for (int d = 0; d < ndim; ++d) - fprintf(fout, "%11.4g", opt_par[opt_lnp.rank][d]); - fprintf(fout, "\n"); - - // 3. mean value - fprintf(fout, "4. Mean value:\n"); - fprintf(fout, "%3s", " "); - for (int d = 0; d < ndim; ++d) fprintf(fout, "%11.4g", mean[d]); - fprintf(fout, "\n"); - - // 4. standard deviation - fprintf(fout, "4. Standard deviation:\n"); - fprintf(fout, "%3s", " "); - for (int d = 0; d < ndim; ++d) fprintf(fout, "%11.4g", sigma[d]); - fprintf(fout, "\n"); - - // 5. correlation coefficient - fprintf(fout, "5. Correlation coefficient:\n"); - for (int i = 0; i < ndim; ++i) { - fprintf(fout, "%1s%-2d", "D", i + 1); - for (int j = 0; j < ndim; ++j) - fprintf(fout, "%11.4g", cov[i][j] / (sigma[i] * sigma[j])); - fprintf(fout, "\n"); - } - - // 6. autocorrelation time - fprintf(fout, "6. Autocorrelation time:\n"); - fprintf(fout, "%3s", " "); - for (int d = 0; d < ndim; ++d) fprintf(fout, "%11.4g", tau[d]); - fprintf(fout, "\n"); - - // 7. optimal model results - fprintf(fout, "7. Optimal model results:\n"); - for (int d = 0; d < nvalue; ++d) { - fprintf(fout, "%11.4f", opt_val[opt_lnp.rank][d]); - if ((d + 1) % 6 == 0) fprintf(fout, "\n"); - } - if (nvalue % 6 != 0) fprintf(fout, "\n"); - - // 8. optimal probability - fprintf(fout, "8. Optimal log probability:\n"); - fprintf(fout, "%11.4g\n", opt_lnp.value); - - // 9. acceptance fraction - fprintf(fout, "9. Acceptance fraction:\n"); - fprintf(fout, "%11.4g", - 1. * accept / ((recs->reset + cur) * nwalker * size)); - fprintf(fout, "\n##############################\n"); - - fclose(fout); - } - -#ifdef MPI_PARALLEL - delete[] lnp; - FreeCArray(par); - FreeCArray(opt_par); - FreeCArray(opt_val); -#else - delete[] opt_par; - delete[] opt_val; -#endif - - delete[] mean; - delete[] sigma; - delete[] tau; - FreeCArray(cov); -} - -void mcmc_init(ObjectiveFunction_t lnprob, double **par, mcmc_opts *opts, - mcmc_recs *recs, void *obj) { - int nwalker = recs->nwalker; - int ndim = recs->ndim; - int nval = recs->nvalue; - - // make sure that the start points are valid - for (int k = 0; k < nwalker; ++k) { - recs->lnp[0][k] = lnprob(par[k], recs->val[0][k], ndim, nval, obj); - - int niter = 0; - while (std::isnan(recs->lnp[0][k]) && - (niter++ < 10)) { // if point (k) is invalid - mcmc_stretch_move(par[k], par, k, nwalker, ndim, opts); - recs->lnp[0][k] = lnprob(par[k], recs->val[0][k], ndim, nval, obj); - } - - if (niter >= 10) { - std::cerr << "Starting point iteration > 10 times" << std::endl; - std::exit(1); - } - - // transfer input parameters to records - for (int d = 0; d < ndim; ++d) recs->par[0][k][d] = par[k][d]; - - if (recs->lnp[0][k] > recs->opt_lnp) { - recs->opt_lnp = recs->lnp[0][k]; - for (int d = 0; d < ndim; ++d) recs->opt_par[d] = recs->par[0][k][d]; - for (int d = 0; d < nval; ++d) recs->opt_val[d] = recs->val[0][k][d]; - } - recs->newstate[0][k] = 1; - } - - recs->cur++; - recs->accept += nwalker; - - // make initial output - mcmc_report(opts, recs, "w"); -} - -void mcmc_advance(ObjectiveFunction_t lnprob, mcmc_opts *opts, mcmc_recs *recs, - void *obj) { - int cur = recs->cur; - int ndim = recs->ndim; - int nwalker = recs->nwalker; - int nval = recs->nvalue; - - double *par = new double[ndim]; - - unsigned int seed = time(NULL); - for (int k = 0; k < nwalker; ++k) { - double zz = - mcmc_stretch_move(par, recs->par[cur - 1], k, nwalker, ndim, opts); - // mcmc_walk_move(par_all + k*np, par, np, k, nwalker, zz + k, opts); - - recs->lnp[cur][k] = lnprob(par, recs->val[cur][k], ndim, nval, obj); - - double lnp0 = recs->lnp[cur - 1][k], lnp1 = recs->lnp[cur][k], - pdiff = (ndim - 1.) * log(zz) + lnp1 - lnp0; - - if (pdiff > log(1. * rand_r(&seed) / RAND_MAX)) { // accept this position - for (int d = 0; d < ndim; ++d) recs->par[cur][k][d] = par[d]; - - if (lnp1 > recs->opt_lnp) { // new best position - recs->opt_lnp = lnp1; - for (int d = 0; d < ndim; ++d) recs->opt_par[d] = recs->par[cur][k][d]; - for (int d = 0; d < nval; ++d) recs->opt_val[d] = recs->val[cur][k][d]; - } - - recs->accept++; - recs->newstate[cur][k] = 1; - } else { // do not accept this position - for (int d = 0; d < ndim; ++d) - recs->par[cur][k][d] = recs->par[cur - 1][k][d]; - for (int d = 0; d < nval; ++d) - recs->val[cur][k][d] = recs->val[cur - 1][k][d]; - recs->lnp[cur][k] = recs->lnp[cur - 1][k]; - recs->newstate[cur][k] = 0; - } - } - - recs->cur++; - if (recs->cur % opts->print == 0) mcmc_report(opts, recs, "a"); - delete[] par; -} - -double mcmc_stretch_move(double *newp, double **oldp, int iwalker, int nwalker, - int ndim, mcmc_opts *opts) { - int irank = 0, size = 1; - double ***par; - -#ifdef MPI_PARALLEL - MPI_Comm_rank(opts->mpi_comm, &irank); - MPI_Comm_size(opts->mpi_comm, &size); -#endif - - NewCArray(par, size, nwalker, ndim); - -#ifdef MPI_PARALLEL - MPI_Allgather(*oldp, nwalker * ndim, MPI_DOUBLE, **par, nwalker * ndim, - MPI_DOUBLE, opts->mpi_comm); -#else - for (int k = 0; k < nwalker; ++k) - for (int d = 0; d < ndim; ++d) par[0][k][d] = oldp[k][d]; -#endif - - // strech step - unsigned int seed = time(NULL); - double r = 1. * rand_r(&seed) / RAND_MAX; - // *zz = sqr((opts->a - 1.) * r + 1.) / opts->a; - double zz = ((opts->a - 1.) * r + 1.) * ((opts->a - 1.) * r + 1) / opts->a; - - int jwalker; // pick a waker - int jrank = rand_r(&seed) % size; // pick a rank - if (jrank == irank) { // same rank - jwalker = rand_r(&seed) % (nwalker - 1); - if (jwalker >= iwalker) jwalker++; // avoid myself - } else { // another rank - jwalker = rand_r(&seed) % nwalker; - } - - for (int d = 0; d < ndim; ++d) - newp[d] = (1. - zz) * par[jrank][jwalker][d] + zz * par[irank][iwalker][d]; - - FreeCArray(par); - - return zz; -} - -void mcmc_walk_move(double *newp, double **oldp, int k, int nwalker, int np, - mcmc_opts *opts) { - int *sub = new int[opts->p]; - double **cov; - double *mean = new double[np], *diag = new double[np]; - - NewCArray(cov, np, np); - - // draw unique sub-sample of size opts->p - bool redraw; - assert(opts->p < static_cast(nwalker)); - assert(opts->p > static_cast(np)); - - unsigned int seed = time(NULL); - - for (int i = 0; i < opts->p; ++i) { - do { - int s = rand_r(&seed) % (nwalker - 1); - if (s >= static_cast(k)) s++; - redraw = false; - for (int j = 0; j < i; ++j) - if (sub[j] == s) redraw = true; - if (!redraw) sub[i] = s; - } while (redraw); - } - - // calculate mean - for (size_t p = 0; p < np; ++p) { - mean[p] = 0.; - for (int q = 0; q < opts->p; ++q) mean[p] += oldp[sub[q]][p]; - mean[p] /= opts->p; - } - - // calculate covariance matrix of this sample - for (size_t i = 0; i < np; ++i) { - for (size_t j = 0; j < np; ++j) { - cov[i][j] = 0.; - for (int q = 0; q < opts->p; ++q) - cov[i][j] += (oldp[sub[q]][i] - mean[i]) * (oldp[sub[q]][j] - mean[j]); - cov[i][j] /= opts->p; - } - } - - // Cholesky decomposition: cov = L * L' - // L is stored in the lower triangle of A, with diag being the diagonal - // elements - _choldc(cov, np, diag); - - // Box-Muller method to generate standard multi-variate normal - // https://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution - // mean is reused to store the standard normal variable - - for (size_t i = 0; i < np; ++i) { - double u = 1. * rand_r(&seed) / RAND_MAX; - double v = 1. * rand_r(&seed) / RAND_MAX; - - mean[i] = sqrt(-2. * log(u)) * cos(2. * M_PI * v); - } - - // multi-variate gaussian with cov: Y = P + L * X, x is a standard normal - for (size_t i = 0; i < np; ++i) { - newp[i] = oldp[k][i]; - for (size_t j = 0; j < i; ++j) newp[i] += cov[i][j] * mean[j]; - newp[i] += diag[i] * mean[i]; - } - - delete[] diag; - delete[] mean; - delete[] sub; - - FreeCArray(cov); -} diff --git a/src/inversion/todo/mcmc.hpp b/src/inversion/todo/mcmc.hpp deleted file mode 100644 index 702a44ad..00000000 --- a/src/inversion/todo/mcmc.hpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef SRC_INVERSION_MCMC_HPP_ -#define SRC_INVERSION_MCMC_HPP_ -#include - -#ifdef MPI_PARALLEL -#include -#endif - -/**@file - * @brief This file contains data structure and subroutines implementing Markov - * Chain Monte Carlo sampler - * - * **Author** : Cheng Li, California Institute of Technology
- * **Contact** : cli@gps.caltech.edu
- * **Revision history** :
- * - June 21 2015, initial document - * - July 18 2016, remove MathHelper dependence - */ - -/** Given a positive definite symmetric matrix a[0..n-1][0..n-1], this - * subroutine constructs its Cholesky decomposition: A = L*L'. On input, only - * the upper triangle of A need be given; it is not modified. The Cholesky - * factor L is returned in the lower triangle of A, except for its diagonal - * elements which are returned in p[0..n-1]. - * see Numerical Recipes in C, pg 97 - */ -void _choldc(double **a, int n, double *p); - -/** calculate auto-correlation time given a time series - * Written by Jonathan Goodman, March 2009, goodman@cims.nyu.edu - * Modified by Cheng Li, June 2016, cli@gps.caltech.edu - */ -int _acor(double *mean, double *sigma, double *tau, double *X, int L); - -/** mcmc options */ -struct mcmc_opts { - double a, b, c, d; - int p, q, r; - - int print; - char logfile[80]; - -#ifdef MPI_PARALLEL - MPI_Comm mpi_comm; -#endif -}; - -/** mcmc chains and records */ -struct mcmc_recs { - int ndim, /**< dimension of state vector */ - nvalue, /**< dimension of measurement */ - nwalker, /**< number of walkers */ - nstep; /**< number of steps */ - - double ***par, /**< state vector in each chain */ - ***val, /**< forward result in each chain */ - **lnp; /**< log probability of each state */ - - double *opt_par, /**< optimal parameter */ - *opt_val; /**< optimal forward result */ - - int **newstate; /**< 0/1 whether the current state is a new state */ - - int cur, /**< current chain length */ - accept, /**< number of accepted states */ - reset; /**< reset chain length */ - double opt_lnp; /**< optimal log probability */ -}; - -/** allocate memory for mcmc chains */ -void mcmc_alloc(mcmc_recs *recs, int nstep, int nwalker, int ndim, int nvalue); - -/** free memory */ -void mcmc_free(mcmc_recs *recs); - -/** calculate autocorrelation time */ -void mcmc_statistics(double *mean, double *sigma, double *tau, mcmc_recs *recs); - -/** save mcmc chains to a FITS file */ -void mcmc_save_fits(char const *fname, mcmc_opts *opts, mcmc_recs *recs, - int include_last = false); - -/** load mcmc chains from a FITS file */ -void mcmc_load_fits(char const *fname, mcmc_opts *opts, mcmc_recs *recs, - int alloc = true); - -/** copy mcmc chains */ -void mcmc_append_recs(mcmc_recs *dst, mcmc_recs *src); - -// report MCMC sampler result -void mcmc_report(mcmc_opts *opts, mcmc_recs *recs, char const *mode); - -typedef double (*ObjectiveFunction_t)(double *, double *, int, int, void *); - -void mcmc_init(ObjectiveFunction_t lnprob, double **par, mcmc_opts *opts, - mcmc_recs *recs, void *obj); - -/** implement Ensemble Samplers with Affine Invariance, Goodman and Weare (2010) - * @param lnprob I, function calculating log probabiligy - * @param par I/O, parameter vector - * @param val I, measurement vector - * @param np I, size of input parameter vector - * @param nv I, size of measurement vector - * @param nwalker I, number of walkers - * @param nstep I, number of steps - * @param opts I, mcmc options - * @param recs O, mcmc chains - */ -void mcmc_advance(ObjectiveFunction_t lnprob, mcmc_opts *opts, mcmc_recs *recs, - void *obj); - -double mcmc_stretch_move(double *newp, double **oldp, int iwalker, int nwalker, - int ndim, mcmc_opts *opts); - -void mcmc_walk_move(double *newp, double **oldp, int k, int nwalker, int np, - mcmc_opts *opts); - -#endif // SRC_INVERSION_MCMC_HPP_ diff --git a/src/inversion/todo/mcmc_init.cpp b/src/inversion/todo/mcmc_init.cpp deleted file mode 100644 index fe3cd303..00000000 --- a/src/inversion/todo/mcmc_init.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// C/C++ headers -#include -#include -#include -#include -#include - -// canoe -#include - -// climath -#include - -// athena -#include -#include - -// application -#include - -// inversion -#include "inversion.hpp" -#include "mcmc.hpp" - -void Inversion::MCMCInit(Radiation *prad, Hydro *phydro) { - int nwalker = recs_.nwalker; - int ndim = recs_.ndim; - int nval = recs_.nvalue; - - Application::Logger app("inversion"); - - Real **par = init_pos_; - - recs_.lnp[0][0] = 1.; - - int is = pmy_block_->is, ie = pmy_block_->ie; - int ks = pmy_block_->ks; - - // make sure that the start points are valid - for (int k = 0; k < nwalker; ++k) { - recs_.lnp[0][k] = - LogPosteriorProbability(prad, phydro, par[k], recs_.val[0][k], ks + k); - - int niter = 0; - while (std::isnan(recs_.lnp[0][k]) && - (niter++ < 10)) { // if point (k) is invalid - mcmc_stretch_move(par[k], par, k, nwalker, ndim, &opts_); - recs_.lnp[0][k] = LogPosteriorProbability(prad, phydro, par[k], - recs_.val[0][k], ks + k); - } - - if (niter >= 10) { - app->Error("Starting point iteration > 10 times"); - } - - // transfer input parameters to records - for (int d = 0; d < ndim; ++d) recs_.par[0][k][d] = par[k][d]; - - if (recs_.lnp[0][k] > recs_.opt_lnp) { - recs_.opt_lnp = recs_.lnp[0][k]; - for (int d = 0; d < ndim; ++d) recs_.opt_par[d] = recs_.par[0][k][d]; - for (int d = 0; d < nval; ++d) recs_.opt_val[d] = recs_.val[0][k][d]; - } - recs_.newstate[0][k] = 1; - - // save hydro to w1 - for (int n = 0; n < NHYDRO; ++n) - for (int j = jl_; j <= ju_; ++j) - for (int i = is; i <= ie; ++i) { - phydro->w1(n, ks + k, j, i) = phydro->w(n, ks + k, j, i); - } - } - - recs_.cur++; - recs_.accept += nwalker; - - // make initial output - mcmc_report(&opts_, &recs_, "w"); -} diff --git a/src/inversion/todo/mcmc_step.cpp b/src/inversion/todo/mcmc_step.cpp deleted file mode 100644 index eaacb2fd..00000000 --- a/src/inversion/todo/mcmc_step.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// C/C++ -#include -#include -#include -#include -#include - -// canoe -#include - -// climath -#include - -// athena -#include -#include - -// application -#include - -// inversion -#include "inversion.hpp" -#include "mcmc.hpp" - -void Inversion::MCMCMove(Radiation *prad, Hydro *phydro) { - Application::Logger app("inversion"); - app->Log("MCMC move"); - - // initialize model - if (recs_.cur == 0) { - MCMCInit(prad, phydro); - } - - std::stringstream msg; - if (!mcmc_initialized_) { - app->Error("mcmc chain uninitialized"); - } - - int cur = recs_.cur; - int ndim = recs_.ndim; - int nwalker = recs_.nwalker; - - for (int k = 0; k < nwalker; ++k) { - zz_[k] = - mcmc_stretch_move(par_, recs_.par[cur - 1], k, nwalker, ndim, &opts_); - // mcmc_walk_move(par_all + k*np, par, np, k, nwalker, zz + k, opts_); - - recs_.lnp[cur][k] = LogPosteriorProbability( - prad, phydro, par_, recs_.val[cur][k], pmy_block_->ks + k); - } -} - -void Inversion::MCMCSave(Hydro *phydro) { - int cur = recs_.cur; - int ndim = recs_.ndim; - int nwalker = recs_.nwalker; - int nval = recs_.nvalue; - - int is = pmy_block_->is, ie = pmy_block_->ie; - int ks = pmy_block_->ks; - - unsigned int seed = time(NULL); - for (int k = 0; k < nwalker; ++k) { - double lnp0 = recs_.lnp[cur - 1][k], lnp1 = recs_.lnp[cur][k], - pdiff = (ndim - 1.) * log(zz_[k]) + lnp1 - lnp0; - - if (pdiff > log(1. * rand_r(&seed) / RAND_MAX)) { // accept this position - for (int d = 0; d < ndim; ++d) recs_.par[cur][k][d] = par_[d]; - - if (lnp1 > recs_.opt_lnp) { // new best position - recs_.opt_lnp = lnp1; - for (int d = 0; d < ndim; ++d) recs_.opt_par[d] = recs_.par[cur][k][d]; - for (int d = 0; d < nval; ++d) recs_.opt_val[d] = recs_.val[cur][k][d]; - } - - recs_.accept++; - recs_.newstate[cur][k] = 1; - - // save hydro to w1 - for (int n = 0; n < NHYDRO; ++n) - for (int j = jl_; j <= ju_; ++j) - for (int i = is; i <= ie; ++i) { - phydro->w1(n, ks + k, j, i) = phydro->w(n, ks + k, j, i); - } - } else { // do not accept this position - for (int d = 0; d < ndim; ++d) - recs_.par[cur][k][d] = recs_.par[cur - 1][k][d]; - for (int d = 0; d < nval; ++d) - recs_.val[cur][k][d] = recs_.val[cur - 1][k][d]; - recs_.lnp[cur][k] = recs_.lnp[cur - 1][k]; - recs_.newstate[cur][k] = 0; - - // load hydro from w1 - for (int n = 0; n < NHYDRO; ++n) - for (int j = jl_; j <= ju_; ++j) - for (int i = is; i <= ie; ++i) { - phydro->w(n, ks + k, j, i) = phydro->w1(n, ks + k, j, i); - } - } - } - - recs_.cur++; - if (recs_.cur % opts_.print == 0) mcmc_report(&opts_, &recs_, "a"); -} diff --git a/src/inversion/todo/profile_inversion_posterior.cpp b/src/inversion/todo/profile_inversion_posterior.cpp deleted file mode 100644 index a6ac342a..00000000 --- a/src/inversion/todo/profile_inversion_posterior.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/** @file pi_log_posterior_probability.cpp - * @brief - * - * @author Cheng Li (chengcli@umich.edu) - * @date Saturday Nov 20, 2021 09:00:13 EST - * @bug No known bugs. - */ - -// C/C++ header -#include -#include -#include - -// athena -#include - -// harp -#include - -// application -#include - -// utils -#include - -// inversion -#include "profile_inversion.hpp" - -Real ProfileInversion::LogPosteriorProbability(Radiation *prad, Hydro *phydro, - Real const *par, Real *val, - int k) const { - Application::Logger app("inversion"); - int is = pmy_block_->is, ie = pmy_block_->ie; - int ks = pmy_block_->ks; - - int ndim = GetDims(); - int nvalue = GetValues(); - - // logging - app->Log("Calculate LogPosteriorProbability"); - app->Log("I am walker = " + std::to_string(k - ks)); - - Real **XpSample; - NewCArray(XpSample, 1 + NVAPOR, plevel_.size()); - std::fill(*XpSample, *XpSample + (1 + NVAPOR) * plevel_.size(), 0.); - - // sample temperature, sample composition #1, sample composition #2, ... - // app->Log("parameters = ", par, ndim); - - int ip = 0; - for (auto m : idx_) { - XpSample[m][0] = 0.; - for (int i = 1; i <= plevel_.size() - 2; ++i) - XpSample[m][i] = par[ip * (plevel_.size() - 2) + i - 1]; - XpSample[m][plevel_.size() - 1] = 0.; - ip++; - } - - // update atmosphere based on XpSample - UpdateProfiles(phydro, XpSample, k, jl_, ju_); - - // calculate radiation for updated profiles located at j = jl_ ... ju_ - for (int j = jl_; j <= ju_; ++j) { - app->Log("run RT for model = " + std::to_string(j)); - prad->CalRadiance(pmy_block_, k, j); - } - - // prior probability - Real lnprior = LogPriorProbability(XpSample); - - // posterior probability - Eigen::VectorXd misfit(nvalue); - - // calculate model result for profile at j = ju_ - CalculateFitTarget(prad, val, nvalue, k, ju_); - - Real lnpost = 0.; - if (target_.size() > 0) { - for (int m = 0; m < nvalue; ++m) misfit(m) = val[m] - target_(m); - lnpost = -0.5 * misfit.transpose() * icov_ * misfit; - } - - // posterior probability - // Real lnprior = 0., lnpost = 0.; - app->Log("log posterir probability = " + std::to_string(lnpost)); - - FreeCArray(XpSample); - - return lnprior + lnpost; -} diff --git a/src/inversion/todo/profile_inversion_prior.cpp b/src/inversion/todo/profile_inversion_prior.cpp deleted file mode 100644 index 2af8fb8c..00000000 --- a/src/inversion/todo/profile_inversion_prior.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// C/C++ -#include - -// canoe -#include - -// athena -#include -#include -#include - -// application -#include - -// inversion -#include "gaussian_process.hpp" -#include "profile_inversion.hpp" - -Real ProfileInversion::LogPriorProbability(Real **XpSample) const { - Application::Logger app("inversion"); - - int nsample = plevel_.size(); - std::vector zlev(nsample); - std::vector zstd(nsample); - - Real P0 = pmy_block_->pcoord->GetReferencePressure(); - Real H0 = pmy_block_->pcoord->GetPressureScaleHeight(); - - for (int i = 0; i < nsample; ++i) zlev[i] = -H0 * log(plevel_[i] / P0); - - Real lnprior = 0.; - for (auto m : idx_) { - for (int i = 0; i < nsample; ++i) - zstd[i] = Xstd_[m] * pow(exp(zlev[i] / H0), chi_); - lnprior += gp_lnprior(SquaredExponential, XpSample[m], zlev.data(), - zstd.data(), nsample, Xlen_[m]); - } - - app->Log("Log prior probability = " + std::to_string(lnprior)); - - return lnprior; -} diff --git a/src/inversion/todo/vla_profile_inversion_target.cpp b/src/inversion/todo/vla_profile_inversion_target.cpp deleted file mode 100644 index 4a69e5be..00000000 --- a/src/inversion/todo/vla_profile_inversion_target.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** @file calculate_fit_target.cpp - * @brief - * - * @author Cheng Li (chengcli@umich.edu) - * @date Thursday Nov 18, 2021 21:07:59 EST - * @bug No known bugs. - */ - -// C/C++ headers -#include -#include - -// climath -#include -#include - -// athena -#include -#include - -// harp -#include -#include - -// application -#include -#include - -// inversion -#include "profile_inversion.hpp" - -void VLAProfileInversion::CalculateFitTarget(Radiation const *prad, Real *val, - int nvalue, int k, int j) const { - std::stringstream msg; - Application::Logger app("inversion"); - - app->Log("VLAProfileInversion::CalculateFitTarget"); - app->Log("model = " + std::to_string(j)); - - if (nvalue != prad->GetNumBands()) { - throw ValueError("CalculateFitTarget", "nvalue", prad->GetNumBands(), - nvalue); - } - - // 11. log likelihood - std::vector mus, tbs; - - for (int b = 0; b < prad->GetNumBands(); ++b) { - auto pband = prad->GetBand(b); - - // emission angles; - int ndir = pband->GetNumOutgoingRays(); - mus.resize(ndir); - tbs.resize(ndir); - - for (int n = 0; n < ndir; ++n) mus[n] = pband->GetCosinePolarAngle(n); - - // brightness temperature - val[b] = prad->radiance(b, k, j); - } -} diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt deleted file mode 100644 index 9ca561e2..00000000 --- a/src/modules/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -set(namel modules) -string(TOUPPER ${namel} nameu) - -file(GLOB src_files - *.cpp - ) - -string(TOLOWER ${CMAKE_BUILD_TYPE} buildl) -string(TOUPPER ${CMAKE_BUILD_TYPE} buildu) - -add_library(${namel}_${buildl} - OBJECT - ${src_files} - ) - -set_target_properties(${namel}_${buildl} - PROPERTIES - COMPILE_FLAGS ${CMAKE_CXX_FLAGS_${buildu}} - ) - -target_include_directories(${namel}_${buildl} - PRIVATE - ${EIGEN3_INCLUDE_DIR} - ) diff --git a/src/modules/chemistry.hpp b/src/modules/chemistry.hpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/modules/coordinates.cpp b/src/modules/coordinates.cpp deleted file mode 100644 index bac14cd8..00000000 --- a/src/modules/coordinates.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "coordinates.hpp" - -#include - -namespace canoe { - -CoordinatesImpl::CoordinatesImpl(const CoordinatesOptions& options_) - : options(options_) { - reset(); -} - -void CoordinatesImpl::reset() { - auto nc1 = options.nx1() > 1 ? options.nx1() + 2 * options.nghost() : 1; - auto nc2 = options.nx2() > 1 ? options.nx2() + 2 * options.nghost() : 1; - auto nc3 = options.nx3() > 1 ? options.nx3() + 2 * options.nghost() : 1; - - // dimension 1 - auto x1f = register_buffer("x1f", torch::empty({nc1 + 1})); - x1f = torch::linspace(options.x1min(), options.x1max(), nc1); - - auto dx1f = register_buffer("dx1f", torch::empty({nc1 + 1})); - dx1f = x1f.slice(0, 1, nc1 + 1) - x1f.slice(0, 0, nc1); - - auto x1v = register_buffer("x1v", torch::empty({nc1})); - x1v = 0.5 * (x1f.slice(0, 0, nc1) + x1f.slice(0, 1, nc1 + 1)); - - // dimension 2 - auto x2f = register_buffer("x2f", torch::empty({nc2 + 1})); - x2f = torch::linspace(options.x2min(), options.x2max(), nc2); - - auto dx2f = register_buffer("dx2f", torch::empty({nc2 + 1})); - dx2f = x2f.slice(0, 1, nc2 + 1) - x2f.slice(0, 0, nc2); - - auto x2v = register_buffer("x2v", torch::empty({nc2})); - x2v = 0.5 * (x2f.slice(0, 0, nc2) + x2f.slice(0, 1, nc2 + 1)); - - // dimension 3 - auto x3f = register_buffer("x3f", torch::empty({nc3 + 1})); - x3f = torch::linspace(options.x3min(), options.x3max(), nc3); - - auto dx3f = register_buffer("dx3f", torch::empty({nc3 + 1})); - dx3f = x3f.slice(0, 1, nc3 + 1) - x3f.slice(0, 0, nc3); - - auto x3v = register_buffer("x3v", torch::empty({nc3})); - x3v = 0.5 * (x3f.slice(0, 0, nc3) + x3f.slice(0, 1, nc3 + 1)); - - auto area1 = register_buffer("area1", torch::empty({1, nc3, nc2, nc1 + 1})); - - register_buffer("area2", torch::empty({1, nc3, nc2 + 1, nc1})); - register_buffer("area3", torch::empty({1, nc3 + 1, nc2, nc1})); - - register_buffer("vol", torch::empty({1, nc3, nc2, nc1})); -} - -int64_t CoordinatesImpl::ncells3() const { return vol().size(1); } - -int64_t CoordinatesImpl::ncells2() const { return vol().size(2); } - -int64_t CoordinatesImpl::ncells1() const { return vol().size(3); } - -torch::TensorList CoordinatesImpl::areas() const { - auto buf = named_buffers(/*recurse=*/false); - return {buf["area1"], buf["area2"], buf["area3"]}; -} - -torch::Tensor CoordinatesImpl::areas(int64_t dim) const { - auto buf = named_buffers(/*recurse=*/false); - - switch (dim) { - case 3: - return buf["area1"]; - case 2: - return buf["area2"]; - case 1: - return buf["area3"]; - default: - throw std::invalid_argument("dim must be 1, 2, or 3"); - } -} - -torch::Tensor CoordinatesImpl::vol() const { - auto buf = named_buffers(/*recurse=*/false); - return buf["vol"]; -} - -torch::TensorList CoordinatesImpl::cos_theta() const { - auto buf = named_buffers(/*recurse=*/false); - return {buf["cos_theta1"], buf["cos_theta2"], buf["cos_theta3"]}; -} - -} // namespace canoe diff --git a/src/modules/coordinates.hpp b/src/modules/coordinates.hpp deleted file mode 100644 index 13676f6d..00000000 --- a/src/modules/coordinates.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include -#include - -namespace canoe { - -struct CoordinatesOptions { - CoordinatesOptions() {} - - TORCH_ARG(float, x1min) = 0; - TORCH_ARG(float, x1max) = 1; - TORCH_ARG(float, x2min) = 0; - TORCH_ARG(float, x2max) = 1; - TORCH_ARG(float, x3min) = 0; - TORCH_ARG(float, x3max) = 1; - - TORCH_ARG(int64_t, nx1) = 1; - TORCH_ARG(int64_t, nx2) = 1; - TORCH_ARG(int64_t, nx3) = 1; - - TORCH_ARG(int64_t, nghost) = 0; -}; - -class CoordinatesImpl : public torch::nn::Cloneable { - public: - //! options with which this `Coordinates` was constructed - CoordinatesOptions options; - - // Constructor to initialize the layers - explicit CoordinatesImpl(const CoordinatesOptions& options_); - - void reset() override; - - int64_t ncells3() const; - int64_t ncells2() const; - int64_t ncells1() const; - - torch::Tensor vol() const; - torch::TensorList areas() const; - torch::Tensor areas(int64_t dim) const; - - torch::TensorList cos_theta() const; - torch::Tensor cos_theta(int64_t dim) const; - - bool is_physical_boundary_low(int64_t dim) const; - bool is_physical_boundary_high(int64_t dim) const; - - protected: - bool is_physical_boundary_[6]; -}; - -TORCH_MODULE(Coordinates); - -} // namespace canoe diff --git a/src/modules/eos_equilibrate_sp.cpp_ b/src/modules/eos_equilibrate_sp.cpp_ deleted file mode 100644 index c0274e13..00000000 --- a/src/modules/eos_equilibrate_sp.cpp_ +++ /dev/null @@ -1,37 +0,0 @@ -// cantera -#include -#include -#include - -// application -#include - -// climath -#include - -// snap -#include - -void Thermodynamics::EquilibrateSP(double P) const { - std::static_pointer_cast(kinetics_) - ->setQuantityMoleFraction(); - - auto& thermo = kinetics_->thermo(); - - double entropy = thermo.entropy_mole(); - Real temp = thermo.temperature(); - - int err = root(temp / 2., temp * 2., 1.E-8, &temp, [&](Real T) { - thermo.setTemperature(T); - thermo.setPressure(P); - EquilibrateTP(); - return thermo.entropy_mole() - entropy; - }); - if (err) - throw RuntimeError("Thermodynamics::EquilibrateSP", - "EquilibrateSP doesn't converge"); - - thermo.setTemperature(temp); - thermo.setPressure(P); - EquilibrateTP(); -} diff --git a/src/modules/eos_equilibrate_tp.cpp_ b/src/modules/eos_equilibrate_tp.cpp_ deleted file mode 100644 index b4f508b9..00000000 --- a/src/modules/eos_equilibrate_tp.cpp_ +++ /dev/null @@ -1,76 +0,0 @@ -// cantera -#include -#include -#include - -// canoe -#include - -// snap -#include "atm_thermodynamics.hpp" - -void Thermodynamics::EquilibrateTP(AirParcel* air) const { - air->ToMassFraction(); - Real pres = air->w[IPR]; - for (int n = IVX; n < IVX + NCLOUD; ++n) air->w[n] = air->c[n - IVX]; - auto& thermo = kinetics_->thermo(); - thermo.setMassFractionsPartial(&air->w[1]); - thermo.setDensity(air->w[IDN]); - thermo.setPressure(air->w[IPR]); - - EquilibrateTP(); - - for (int n = 0; n < NCLOUD; ++n) air->c[n] = air->w[IVX + n]; - air->w[IPR] = pres; - air->ToMoleFraction(); -} - -void Thermodynamics::EquilibrateTP() const { - std::static_pointer_cast(kinetics_) - ->setQuantityMoleFraction(); - - std::vector rates(kinetics_->nTotalSpecies()); - std::vector mfrac(kinetics_->nTotalSpecies()); - - auto& thermo = kinetics_->thermo(); - Real temp = thermo.temperature(); - Real pres = thermo.pressure(); - - int iter = 0, max_iter = 3; - - while (iter++ < max_iter) { - // std::cout << "Iteration " << iter << std::endl; - - // get mole fraction - kinetics_->getActivityConcentrations(mfrac.data()); - - /* print initial conditions - std::cout << "Mole fractions" << std::endl; - for (size_t i = 0; i < mfrac.size(); ++i) { - std::cout << "Mole fraction " << i << ": " << mfrac[i] << std::endl; - }*/ - - kinetics_->getNetProductionRates(rates.data()); - /*for (size_t i = 0; i < rates.size(); ++i) { - std::cout << "NET Production " << i << ": " << rates[i] << std::endl; - }*/ - - // update mole fraction - for (size_t i = 1; i < rates.size(); ++i) { - mfrac[i] += rates[i]; - } - - thermo.setMoleFractions(mfrac.data()); - thermo.setTemperature(temp); - thermo.setPressure(pres); - - /* print again - std::cout << "After Mole fractions" << std::endl; - for (size_t i = 0; i < mfrac.size(); ++i) { - std::cout << "Mole fraction " << i << ": " << mfrac[i] << std::endl; - } - std::cout << "T = " << thermo.temperature() << std::endl; - std::cout << "P = " << thermo.pressure() << std::endl; - std::cout << "D = " << thermo.density() << std::endl;*/ - } -} diff --git a/src/modules/eos_equilibrate_uv.cpp_ b/src/modules/eos_equilibrate_uv.cpp_ deleted file mode 100644 index 4933f32d..00000000 --- a/src/modules/eos_equilibrate_uv.cpp_ +++ /dev/null @@ -1,93 +0,0 @@ -// cantera -#include -#include -#include - -// canoe -#include - -// snap -#include "atm_thermodynamics.hpp" - -void Thermodynamics::EquilibrateUV(AirParcel* air) const { - air->ToMassFraction(); - Real pres = air->w[IPR]; - for (int n = IVX; n < IVX + NCLOUD; ++n) air->w[n] = air->c[n - IVX]; - auto& thermo = kinetics_->thermo(); - thermo.setMassFractionsPartial(&air->w[1]); - thermo.setDensity(air->w[IDN]); - thermo.setPressure(air->w[IPR]); - - EquilibrateUV(); - - for (int n = 0; n < NCLOUD; ++n) air->c[n] = air->w[IVX + n]; - air->w[IPR] = pres; - air->ToMoleFraction(); -} - -void Thermodynamics::EquilibrateUV() const { - auto kin = std::static_pointer_cast(kinetics_); - kin->setQuantityConcentration(); - - Eigen::VectorXd rates(kin->nTotalSpecies()); - Eigen::VectorXd conc(kin->nTotalSpecies()); - Eigen::VectorXd intEng(kin->nTotalSpecies()); - Eigen::VectorXd cv(kin->nTotalSpecies()); - - auto& thermo = kin->thermo(); - - int iter = 0, max_iter = 3; - while (iter++ < max_iter) { - /*std::cout << "#############" << std::endl; - std::cout << "Iteration " << iter << std::endl;*/ - - Real temp = thermo.temperature(); - // Real pres = thermo.pressure(); - - // get concentration - kin->getActivityConcentrations(conc.data()); - thermo.getIntEnergy_RT(intEng.data()); - thermo.getCv_R(cv.data()); - - Real cc = conc.dot(cv); - Real uc = conc.dot(intEng); - - /*std::cout << "internal energy 1 = " << uc * temp << std::endl; - - // print initial conditions - std::cout << "Concentration" << std::endl; - for (size_t i = 0; i < conc.size(); ++i) { - std::cout << "Concentration" << i << ": " << conc[i] << std::endl; - }*/ - - kin->getNetProductionRates(rates.data()); - // std::cout << "rates = " << rates << std::endl; - - // update concentrations - for (size_t i = 1; i < rates.size(); ++i) { - conc(i) += rates(i); - } - - // update temperature - auto dT = -temp * rates.dot(intEng) / conc.dot(cv); - // std::cout << "dT = " << dT << std::endl; - - /* print initial conditions - std::cout << "Concentration" << std::endl; - for (size_t i = 0; i < conc.size(); ++i) { - std::cout << "Concentration" << i << ": " << conc[i] << std::endl; - }*/ - - thermo.setConcentrationsNoNorm(conc.data()); - thermo.setTemperature(temp + dT); - - /*thermo.getIntEnergy_RT(intEng.data()); - thermo.getCv_R(cv.data()); - std::cout << "internal energy 2 = " - << conc.dot(intEng) * thermo.temperature() << std::endl; - - std::cout << "T = " << thermo.temperature() << std::endl; - std::cout << "P = " << thermo.pressure() << std::endl; - std::cout << "D = " << thermo.density() << std::endl;*/ - } -} diff --git a/src/modules/eos_rk4_integrate_z.cpp_ b/src/modules/eos_rk4_integrate_z.cpp_ deleted file mode 100644 index 4b398718..00000000 --- a/src/modules/eos_rk4_integrate_z.cpp_ +++ /dev/null @@ -1,110 +0,0 @@ -// C/C++ -#include -#include -#include - -// cantera -#include -#include - -// thermodynamics -#include "atm_thermodynamics.hpp" - -void rk4_integrate_z(AirParcel* air, Real dz, std::string method, Real grav, - Real adTdz) { - auto pthermo = Thermodynamics::GetInstance(); - auto& thermo = pthermo->Kinetics()->thermo(); - - auto const& mu_ratio = pthermo->GetMuRatio(); - auto const& cp_ratio_mole = pthermo->GetCpRatioMole(); - - Real step[] = {0.5, 0.5, 1.}; - Real dTdz[4], chi[4]; - Real latent[1 + NVAPOR]; - Real temp = air->w[IDN]; - - std::vector rates(pthermo->Kinetics()->nTotalSpecies()); - std::vector enthalpy(pthermo->Kinetics()->nTotalSpecies()); - - air->ToMassFraction(); - Real pres = air->w[IPR]; - for (int n = IVX; n < IVX + NCLOUD; ++n) air->w[n] = air->c[n - IVX]; - thermo.setMassFractionsPartial(&air->w[1]); - thermo.setDensity(air->w[IDN]); - thermo.setPressure(air->w[IPR]); - - thermo.getEnthalpy_RT(enthalpy.data()); - pthermo->Kinetics()->getNetProductionRates(rates.data()); - - for (int n = 0; n < NCLOUD; ++n) air->c[n] = air->w[IVX + n]; - air->w[IPR] = pres; - air->ToMoleFraction(); - - for (int i = 1; i <= NVAPOR; ++i) { - if (rates[i] > 0.) { - latent[i] = enthalpy[i] - enthalpy[i + NVAPOR]; - } else { - latent[i] = 0.; - } - } - - for (int rk = 0; rk < 4; ++rk) { - pthermo->EquilibrateTP(air); - - if (method != "reversible") { - for (int j = 0; j < NCLOUD; ++j) air->c[j] = 0; - } - - Real q_gas = 1., q_eps = 1.; - for (int i = 1; i <= NVAPOR; ++i) { - q_eps += air->w[i] * (mu_ratio[i] - 1.); - } - - for (int j = 0; j < NCLOUD; ++j) { - q_eps += air->c[j] * (mu_ratio[1 + NVAPOR + j] - 1.); - q_gas += -air->c[j]; - } - - Real g_ov_Rd = grav / pthermo->GetRd(); - Real R_ov_Rd = q_gas / q_eps; - - if (method == "reversible" || method == "pseudo") { - chi[rk] = cal_dlnT_dlnP(*air, cp_ratio_mole, latent); - } else if (method == "dry") { - for (int i = 1; i <= NVAPOR; ++i) latent[i] = 0; - chi[rk] = cal_dlnT_dlnP(*air, cp_ratio_mole, latent); - } else { // isothermal - chi[rk] = 0.; - } - - dTdz[rk] = -chi[rk] * g_ov_Rd / R_ov_Rd + adTdz; - chi[rk] = -R_ov_Rd / g_ov_Rd * dTdz[rk]; - - // integrate over dz - Real chi_avg; - if (rk < 3) { - air->w[IDN] = temp + dTdz[rk] * dz * step[rk]; - chi_avg = chi[rk]; - } else { - air->w[IDN] = - temp + - 1. / 6. * (dTdz[0] + 2. * dTdz[1] + 2. * dTdz[2] + dTdz[3]) * dz; - chi_avg = 1. / 6. * (chi[0] + 2. * chi[1] + 2. * chi[2] + chi[3]); - } - - if (!(air->w[IDN] > 0.)) air->w[IDN] = temp; - - if (fabs(air->w[IDN] - temp) > 0.01) { - air->w[IPR] = pres * pow(air->w[IDN] / temp, 1. / chi_avg); - } else { // isothermal limit - air->w[IPR] = - pres * exp(-2. * g_ov_Rd * dz / (R_ov_Rd * (air->w[IDN] + temp))); - } - } - - // recondensation - pthermo->EquilibrateTP(air); - if (method != "reversible") { - for (int j = 0; j < NCLOUD; ++j) air->c[j] = 0; - } -} diff --git a/src/modules/eos_saturation_adjustment.cpp_ b/src/modules/eos_saturation_adjustment.cpp_ deleted file mode 100644 index 8bca5780..00000000 --- a/src/modules/eos_saturation_adjustment.cpp_ +++ /dev/null @@ -1,27 +0,0 @@ -// C/C++ -#include -#include -#include - -// athena -#include -#include - -// application -#include - -// canoe -#include -#include - -// snap -#include "atm_thermodynamics.hpp" - -void Thermodynamics::SaturationAdjustment(AirColumn& air_column) const { - // return if there's no vapor - if (NVAPOR == 0) return; - - for (auto& air : air_column) { - EquilibrateUV(&air); - } -} diff --git a/src/modules/eos_thermodynamics.cpp_ b/src/modules/eos_thermodynamics.cpp_ deleted file mode 100644 index a1416e3f..00000000 --- a/src/modules/eos_thermodynamics.cpp_ +++ /dev/null @@ -1,541 +0,0 @@ -// C/C++ header -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // fill - -// cantera -#include -#include - -// athena -#include -#include -#include -#include -#include - -// application -#include -#include - -// canoe -#include -#include -#include -#include -#include - -// climath -#include - -// snap -#include "atm_thermodynamics.hpp" -#include "molecules.hpp" - -static std::mutex thermo_mutex; - -const std::string Thermodynamics::input_key = "thermodynamics_config"; - -Thermodynamics::~Thermodynamics() { - Application::Logger app("snap"); - app->Log("Destroy Thermodynamics"); -} - -Thermodynamics* Thermodynamics::fromYAMLInput(std::string const& fname) { - mythermo_ = new Thermodynamics(); - - auto thermo = Cantera::newThermo(fname, "gas"); - - if (thermo->nSpecies() != 1 + NVAPOR + NCLOUD) { - throw RuntimeError("Thermodynamics", - "Number of species does not match the input file"); - } - - auto& kinetics = mythermo_->kinetics_; - kinetics = Cantera::newKinetics({thermo}, fname); - - // --------- vapor + cloud thermo --------- - std::vector mu(thermo->nSpecies()); - std::vector cp_mole(thermo->nSpecies()); - - // g/mol - thermo->getMolecularWeights(mu.data()); - - // J/kmol/K - thermo->getPartialMolarCp(cp_mole.data()); - - mythermo_->Rd_ = Cantera::GasConstant / mu[0]; - mythermo_->gammad_ref_ = cp_mole[0] / (cp_mole[0] - Cantera::GasConstant); - - // ---------- dimensionless properties ---------- - - // cp ratios - for (size_t i = 0; i < cp_mole.size(); ++i) { - mythermo_->cp_ratio_mole_[i] = cp_mole[i] / cp_mole[0]; - } - - // molecular weight ratios - for (size_t i = 0; i < mu.size(); ++i) { - mythermo_->mu_ratio_[i] = mu[i] / mu[0]; - } - - // beta parameter (dimensionless internal energy) - for (size_t i = 0; i < thermo->nSpecies(); ++i) { - auto& tp = thermo->species(i)->thermo; - size_t n; - int type; - Real tlow, thigh, pref; - std::vector coeffs(tp->nCoeffs()); - tp->reportParameters(n, type, tlow, thigh, pref, coeffs.data()); - - Real t0 = coeffs[0]; - Real h0 = coeffs[1]; - Real s0 = coeffs[2]; - Real cp0 = coeffs[3]; - mythermo_->beta_[i] = h0 / (Cantera::GasConstant * t0); - } - - return mythermo_; -} - -Thermodynamics* Thermodynamics::fromLegacyInput(ParameterInput* pin) { - if (NCLOUD < (NPHASE - 1) * NVAPOR) { - throw RuntimeError( - "Thermodynamics", - "NCLOUD < (NPHASE-1)*NVAPOR is not supported for legacy input"); - } - - mythermo_ = new Thermodynamics(); - - // Read molecular weight ratios - read_thermo_property(mythermo_->mu_ratio_.data(), "eps", NPHASE, 1., pin); - - // Read cp ratios - read_thermo_property(mythermo_->cp_ratio_mass_.data(), "rcp", NPHASE, 1., - pin); - - // Read beta parameter - read_thermo_property(mythermo_->beta_.data(), "beta", NPHASE, 0., pin); - - // Read triple point temperature - read_thermo_property(mythermo_->t3_.data(), "Ttriple", 1, 0., pin); - - // Read triple point pressure - read_thermo_property(mythermo_->p3_.data(), "Ptriple", 1, 0., pin); - - mythermo_->svp_func1_.resize(1 + NVAPOR); - mythermo_->cloud_index_set_.resize(1 + NVAPOR); - - for (int i = 0; i <= NVAPOR; ++i) { - mythermo_->cloud_index_set_[i].resize(NPHASE - 1); - mythermo_->svp_func1_[i].resize(NPHASE - 1); - for (int j = 1; j < NPHASE; ++j) { - mythermo_->cloud_index_set_[i][j - 1] = (j - 1) * NVAPOR + (i - 1); - } - } - - mythermo_->Rd_ = pin->GetOrAddReal("thermodynamics", "Rd", 1.); - mythermo_->gammad_ref_ = pin->GetReal("hydro", "gamma"); - - return mythermo_; -} - -Thermodynamics const* Thermodynamics::GetInstance() { - // RAII - std::unique_lock lock(thermo_mutex); - - if (mythermo_ == nullptr) { - mythermo_ = new Thermodynamics(); - } - - return mythermo_; -} - -Thermodynamics const* Thermodynamics::InitFromYAMLInput( - std::string const& fname) { - if (mythermo_ != nullptr) { - throw RuntimeError("Thermodynamics", "Thermodynamics has been initialized"); - } - - Application::Logger app("snap"); - app->Log("Initialize Thermodynamics"); - - return fromYAMLInput(fname); -} - -Thermodynamics const* Thermodynamics::InitFromAthenaInput(ParameterInput* pin) { - if (mythermo_ != nullptr) { - throw RuntimeError("Thermodynamics", "Thermodynamics has been initialized"); - } - - Application::Logger app("snap"); - app->Log("Initialize Thermodynamics"); - - if (pin->DoesParameterExist("thermodynamics", input_key)) { - std::string filename = pin->GetString("thermodynamics", input_key); - mythermo_ = fromYAMLInput(filename); - } else { // legacy input - mythermo_ = fromLegacyInput(pin); - } - - // alias - auto& Rd = mythermo_->Rd_; - auto& gammad = mythermo_->gammad_ref_; - auto& mu_ratio = mythermo_->mu_ratio_; - auto& inv_mu_ratio = mythermo_->inv_mu_ratio_; - auto& mu = mythermo_->mu_; - auto& inv_mu = mythermo_->inv_mu_; - - auto& cp_ratio_mole = mythermo_->cp_ratio_mole_; - auto& cp_ratio_mass = mythermo_->cp_ratio_mass_; - auto& cv_ratio_mole = mythermo_->cv_ratio_mole_; - auto& cv_ratio_mass = mythermo_->cv_ratio_mass_; - - auto& latent_energy_mass = mythermo_->latent_energy_mass_; - auto& latent_energy_mole = mythermo_->latent_energy_mole_; - - auto& beta = mythermo_->beta_; - auto& delta = mythermo_->delta_; - auto& t3 = mythermo_->t3_; - auto& p3 = mythermo_->p3_; - auto& cloud_index_set = mythermo_->cloud_index_set_; - - // molecular weight - mu[0] = Constants::Rgas / Rd; - - // inverse mu ratio - for (int n = 0; n < mu_ratio.size(); ++n) { - inv_mu_ratio[n] = 1. / mu_ratio[n]; - mu[n] = mu[0] * mu_ratio[n]; - inv_mu[n] = 1. / mu[n]; - cp_ratio_mass[n] = cp_ratio_mole[n] * inv_mu_ratio[n]; - } - - /* calculate latent energy = $\beta\frac{R_d}{\epsilon}T^r$ - for (int n = 0; n <= NVAPOR; ++n) { - latent_energy_mass[n] = 0.; - latent_energy_mole[n] = 0.; - } - - for (int i = 1; i <= NVAPOR; ++i) { - for (int j = 0; j < NPHASE - 1; ++j) { - int n = cloud_index_set[i][j] + 1 + NVAPOR; - latent_energy_mass[n] = beta[n] * Rd / mu_ratio[n] * t3[i]; - latent_energy_mole[n] = latent_energy_mass[n] * mu[n]; - } - } - - // calculate delta = $(\sigma_j - \sigma_i)*\epsilon_i*\gamma/(\gamma - 1)$ - for (int n = 0; n <= NVAPOR; ++n) delta[n] = 0.; - for (int i = 1; i <= NVAPOR; ++i) { - for (int j = 0; j < cloud_index_set[i].size(); ++j) { - int n = cloud_index_set[i][j] + 1 + NVAPOR; - delta[n] = (cp_ratio_mass[n] - cp_ratio_mass[i]) * mu_ratio[i] / - (1. - 1. / gammad); - } - }*/ - - // finally, set up cv ratio - // calculate cv_ratio = $\sigma_i + (1. - \gamma)/\epsilon_i$ - for (int n = 0; n <= NVAPOR; ++n) { - cv_ratio_mass[n] = - gammad * cp_ratio_mass[n] + (1. - gammad) * inv_mu_ratio[n]; - cv_ratio_mole[n] = cv_ratio_mass[n] * mu_ratio[n]; - } - - for (int n = 1 + NVAPOR; n < Size; ++n) { - cv_ratio_mass[n] = gammad * cp_ratio_mass[n]; - cv_ratio_mole[n] = cv_ratio_mass[n] * mu_ratio[n]; - } - - // saturation adjustment parmaeters - mythermo_->sa_max_iter_ = - pin->GetOrAddReal("thermodynamics", "sa.max_iter", 10); - mythermo_->sa_relax_ = pin->GetOrAddReal("thermodynamics", "sa.relax", 0.8); - mythermo_->sa_ftol_ = pin->GetOrAddReal("thermodynamics", "sa.ftol", 1.e-4); - - return mythermo_; -} - -void Thermodynamics::Destroy() { - std::unique_lock lock(thermo_mutex); - - if (Thermodynamics::mythermo_ != nullptr) { - delete Thermodynamics::mythermo_; - Thermodynamics::mythermo_ = nullptr; - } -} - -Real Thermodynamics::GetPres(MeshBlock const* pmb, int k, int j, int i) const { - Real gm1 = pmb->peos->GetGamma() - 1; - auto& u = pmb->phydro->u; - - Real rho = 0., fsig = 0., feps = 0.; -#pragma omp simd reduction(+ : rho, fsig, feps) - for (int n = 0; n <= NVAPOR; ++n) { - rho += u(n, k, j, i); - fsig += u(n, k, j, i) * cv_ratio_mass_[n]; - feps += u(n, k, j, i) * inv_mu_ratio_[n]; - } - - // TODO(cli): not correct for Cubed sphere - Real KE = - 0.5 * - (sqr(u(IM1, k, j, i)) + sqr(u(IM2, k, j, i)) + sqr(u(IM3, k, j, i))) / - rho; - return gm1 * (u(IEN, k, j, i) - KE) * feps / fsig; -} - -// Eq.71 in Li2019 -Real Thermodynamics::GetChi(MeshBlock const* pmb, int k, int j, int i) const { - Real gammad = pmb->peos->GetGamma(); - auto& w = pmb->phydro->w; - - Real qsig = 1., feps = 1.; -#pragma omp simd reduction(+ : qsig, feps) - for (int n = 1; n <= NVAPOR; ++n) { - feps += w(n, k, j, i) * (inv_mu_ratio_[n] - 1.); - qsig += w(n, k, j, i) * (cp_ratio_mass_[n] - 1.); - } - - return (gammad - 1.) / gammad * feps / qsig; -} - -// Eq.63 in Li2019 -Real Thermodynamics::GetGamma(MeshBlock const* pmb, int k, int j, int i) const { - Real gammad = pmb->peos->GetGamma(); - - auto&& air = AirParcelHelper::gather_from_primitive(pmb, k, j, i); - - Real fsig = 1., feps = 1.; -#pragma omp simd reduction(+ : fsig, feps) - for (int n = 1; n <= NVAPOR; ++n) { - fsig += air.w[n] * (cv_ratio_mass_[n] - 1.); - feps += air.w[n] * (inv_mu_ratio_[n] - 1.); - } - - for (int n = 0; n < NCLOUD; ++n) { - fsig += air.c[n] * (cv_ratio_mass_[n + 1 + NVAPOR] - 1.); - feps += -air.c[n]; - } - - return 1. + (gammad - 1.) * feps / fsig; -} - -Real Thermodynamics::MoistStaticEnergy(MeshBlock const* pmb, Real gz, int k, - int j, int i) const { - auto&& air = AirParcelHelper::gather_from_primitive(pmb, k, j, i); - air.ToMassConcentration(); - - Real temp = GetTemp(pmb, k, j, i); - Real rho = 0., LE = 0., IE = 0.; - -#pragma omp simd reduction(+ : IE, rho) - for (int n = 0; n <= NVAPOR; ++n) { - IE += air.w[n] * GetCpMassRef(n) * temp; - rho += air.w[n]; - } - -#pragma omp simd reduction(+ : IE, LE, rho) - for (int n = 0; n < NCLOUD; ++n) { - IE += air.c[n] * GetCpMassRef(1 + NVAPOR + n) * temp; - LE += -latent_energy_mass_[1 + NVAPOR + n] * air.c[n]; - rho += air.c[n]; - } - - return (IE + LE) / rho + gz; -} - -// TODO(cli): check -Real Thermodynamics::GetCpMass(MeshBlock const* pmb, int k, int j, - int i) const { - Real gammad = pmb->peos->GetGamma(); - auto& w = pmb->phydro->w; - - Real qsig = 1.; -#pragma omp simd reduction(+ : qsig) - for (int n = 1; n <= NVAPOR; ++n) - qsig += w(n, k, j, i) * (cp_ratio_mass_[n] - 1.); - return gammad / (gammad - 1.) * Rd_ * qsig; -} - -// TODO(cli): check -Real Thermodynamics::GetCvMass(MeshBlock const* pmb, int k, int j, - int i) const { - Real gammad = pmb->peos->GetGamma(); - auto& w = pmb->phydro->w; - - Real qsig = 1.; -#pragma omp simd reduction(+ : qsig) - for (int n = 1; n <= NVAPOR; ++n) - qsig += w(n, k, j, i) * (cv_ratio_mass_[n] - 1.); - return 1. / (gammad - 1.) * Rd_ * qsig; -} - -Real Thermodynamics::GetEnthalpyMass(MeshBlock const* pmb, int k, int j, - int i) const { - Real gammad = pmb->peos->GetGamma(); - auto& w = pmb->phydro->w; - - Real qsig = 1.; -#pragma omp simd reduction(+ : qsig) - for (int n = 1; n <= NVAPOR; ++n) - qsig += w(n, k, j, i) * (cp_ratio_mass_[n] - 1.); - return gammad / (gammad - 1.) * Rd_ * qsig * w(IDN, k, j, i); -} - -Real Thermodynamics::GetMu(MeshBlock const* pmb, int k, int j, int i) const { - auto& w = pmb->phydro->w; - - Real feps = 1.; -#pragma omp simd reduction(+ : feps) - for (int n = 1; n <= NVAPOR; ++n) feps += w(n, k, j, i) * (mu_ratio_[n] - 1.); - return mu_[0] * feps; -} - -Real Thermodynamics::RelativeHumidity(MeshBlock const* pmb, int n, int k, int j, - int i) const { - auto&& air = AirParcelHelper::gather_from_primitive(pmb, k, j, i); - air.ToMoleFraction(); - return get_relative_humidity(air, n); -} - -void Thermodynamics::Extrapolate(AirParcel* qfrac, Real dzORdlnp, - std::string method, Real grav, - Real userp) const { - qfrac->ToMassFraction(); - - auto& thermo = kinetics_->thermo(); - - double pres = qfrac->w[IPR]; - for (int n = IVX; n < IVX + NCLOUD; ++n) qfrac->w[n] = qfrac->c[n - IVX]; - thermo.setMassFractionsPartial(&qfrac->w[1]); - thermo.setDensity(qfrac->w[IDN]); - thermo.setPressure(qfrac->w[IPR]); - - EquilibrateTP(); - - thermo.getMassFractions(&qfrac->w[0]); - - for (int n = 0; n < NCLOUD; ++n) { - qfrac->c[n] = qfrac->w[IVX + n]; - } - - qfrac->w[IPR] = pres; - qfrac->w[IDN] = thermo.density(); - qfrac->w[IVX] = 0.; - qfrac->w[IVX] = 0.; - qfrac->w[IVX] = 0.; - - qfrac->ToMoleFraction(); - - // std::cout << *qfrac << std::endl; - - // RK4 integration -#ifdef HYDROSTATIC - rk4_integrate_lnp(qfrac, dzORdlnp, method, userp); -#else - rk4_integrate_z(qfrac, dzORdlnp, method, grav, userp); -#endif -} - -Real Thermodynamics::GetLatentHeatMole(int i, std::vector const& rates, - Real temp) const { - if (std::abs(rates[0]) < 1.E-8) return 0.; - - Real heat = 0.; - for (int j = 1; j < rates.size(); ++j) { - int n = cloud_index_set_[i][j - 1] + 1 + NVAPOR; - heat += rates[j] * GetLatentEnergyMole(n, temp); - } - - return heat / std::abs(rates[0]); -} - -void Thermodynamics::SetStateFromPrimitive(MeshBlock* pmb, int k, int j, - int i) const { - Hydro* phydro = pmb->phydro; - - auto& thermo = kinetics_->thermo(); - size_t total_cells = pmb->ncells1 * pmb->ncells2 * pmb->ncells3; - - thermo.setMassFractionsPartial(&phydro->w(1, k, j, i), total_cells); - thermo.setDensity(phydro->w(IDN, k, j, i)); - thermo.setPressure(phydro->w(IPR, k, j, i)); -} - -void Thermodynamics::SetStateFromConserved(MeshBlock* pmb, int k, int j, - int i) const { - Hydro* phydro = pmb->phydro; - - auto& thermo = kinetics_->thermo(); - size_t total_cells = pmb->ncells1 * pmb->ncells2 * pmb->ncells3; - - thermo.setMassFractions(&phydro->u(0, k, j, i), total_cells); - Real rho = 0.; - for (int n = 0; n < Size; ++n) { - rho += phydro->u(n, k, j, i); - } - thermo.setDensity(rho); - thermo.setPressure(GetPres(pmb, k, j, i)); -} - -// Eq.4.5.11 in Emanuel (1994) -Real Thermodynamics::EquivalentPotentialTemp(MeshBlock* pmb, Real p0, int v, - int k, int j, int i) const { -#if (NVAPOR > 0) - AirParcel&& air_mass = AirParcelHelper::gather_from_primitive(pmb, k, j, i); - - AirParcel air_mole = air_mass; - air_mole.ToMoleFraction(); - - // get dry air mixing ratio - Real xg = 1., qd = 1.; -#pragma omp simd reduction(+ : xg, qd) - for (int n = 0; n < NCLOUD; ++n) { - xg += -air_mole.c[n]; - qd += -air_mass.c[n]; - } - - Real xd = xg; -#pragma omp simd reduction(+ : xd, qd) - for (int n = 1; n <= NVAPOR; ++n) { - xd += -air_mole.w[n]; - qd += -air_mass.w[n]; - } - - Real temp = air_mole.w[IDN]; - Real pres = air_mole.w[IPR]; - - Real qv = air_mass.w[v]; - Real qc = air_mass.c[cloud_index_set_[v][0]]; - Real qt = qv + qc; - - Real Rd = Rd_; - Real Rv = Rd_ / mu_ratio_[v]; - - Real cpd = GetCpMassRef(0); - Real cl = GetCpMassRef(cloud_index_set_[v][0] + 1 + NVAPOR); - - std::vector rates{-0.01, 0.01}; - Real lv = GetLatentHeatMass(v, rates, temp); - - Real rh = RelativeHumidity(pmb, v, k, j, i); - Real pd = xd / xg * pres; - Real cpt = cpd * qd + cl * qt; - - return temp * pow(p0 / pd, Rd * qd / cpt) * pow(rh, -Rv * qv / cpt) * - exp(lv * qv / (cpt * temp)); -#else - return PotentialTemp(pmb, p0, k, j, i); -#endif -} - -Thermodynamics* Thermodynamics::mythermo_ = nullptr; diff --git a/src/modules/eos_thermodynamics.hpp_ b/src/modules/eos_thermodynamics.hpp_ deleted file mode 100644 index 33109270..00000000 --- a/src/modules/eos_thermodynamics.hpp_ +++ /dev/null @@ -1,463 +0,0 @@ -#ifndef SRC_SNAP_THERMODYNAMICS_THERMODYNAMICS_HPP_ -#define SRC_SNAP_THERMODYNAMICS_THERMODYNAMICS_HPP_ - -// C/C++ -#include -#include -#include -#include -#include -#include -#include -#include - -// athena -#include -#include -#include - -// canoe -#include -#include -#include - -class MeshBlock; -class ParameterInput; - -namespace Cantera { -class ThermoPhase; -class Kinetics; -} // namespace Cantera - -using IndexPair = std::pair; -using IndexSet = std::vector; - -using RealArray3 = std::array; -using RealArrayX = std::vector; - -using SatVaporPresFunc1 = Real (*)(AirParcel const &, int i, int j); -using SatVaporPresFunc2 = Real (*)(AirParcel const &, int i, int j, int k); - -enum { MAX_REACTANT = 3 }; - -using ReactionIndx = std::array; -using ReactionStoi = std::array; -using ReactionInfo = std::pair; - -Real NullSatVaporPres1(AirParcel const &, int, int); -Real NullSatVaporPres2(AirParcel const &, int, int, int); - -void read_thermo_property(Real var[], char const name[], int len, Real v0, - ParameterInput *pin); -Real saha_ionization_electron_density(Real T, Real num, Real ion_ev); - -//! Ideal saturation vapor pressure -//! $p^* = p^r\exp[\beta(1-1/t)-\delta\lnt]$ -//! $p^r$ is the reference pressure, usually choosen to be the triple point -//! pressure \n $t=T/T^r$ is the dimensionless temperature. $T^r$ is the -//! reference temperature. \n Similar to $p^r$, $T^r$ is usually choosen to be -//! the triple point temperature -//! \return $p^*$ [pa] -inline Real SatVaporPresIdeal(Real t, Real p3, Real beta, Real delta) { - return p3 * exp((1. - 1. / t) * beta - delta * log(t)); -} - -// Thermodynamic variables are ordered in the array as the following -// 0: dry air (non-condensible gas) -// 1..NVAPOR: moist air (condensible gas) -// NVAPOR+1..NVAPOR+NCLOUD: clouds - -// 0 is a special buffer place for cloud in equilibrium with vapor at the same -// temperature - -class Thermodynamics { - protected: - enum { NPHASE = NPHASE_LEGACY }; - - //! Constructor for class sets up the initial conditions - //! Protected ctor access thru static member function Instance - Thermodynamics() {} - static Thermodynamics *fromLegacyInput(ParameterInput *pin); - static Thermodynamics *fromYAMLInput(std::string const &fname); - - public: - using SVPFunc1Container = std::vector>; - using SVPFunc2Container = std::map; - - enum { Size = 1 + NVAPOR + NCLOUD }; - - //! thermodynamics input key in the input file [thermodynamics_config] - static const std::string input_key; - - // member functions - ~Thermodynamics(); - - //! Return a pointer to the one and only instance of Thermodynamics - static Thermodynamics const *GetInstance(); - - static Thermodynamics const *InitFromYAMLInput(std::string const &fname); - - static Thermodynamics const *InitFromAthenaInput(ParameterInput *pin); - - //! Destroy the one and only instance of Thermodynamics - static void Destroy(); - - //! Ideal gas constant of dry air in [J/(kg K)] - //! \return $R_d=\hat{R}/\mu_d$ - Real GetRd() const { return Rd_; } - - //! reference adiabatic index of dry air [1] - Real GetGammadRef() const { return gammad_ref_; } - - //! Molecular weight [kg/mol] - //! \param[in] n the index of the thermodynamic species - //! \return $\mu$ - Real GetMu(int n) const { return mu_[n]; } - - //! Inverse molecular weight [mol/kg] - //! \param[in] n the index of the thermodynamic species - //! \return $\mu$ - Real GetInvMu(int n) const { return inv_mu_[n]; } - - //! Ratio of molecular weights [1] - //! \param[in] n the index of the thermodynamic species - //! \return $\epsilon_i=\mu_i/\mu_d$ - Real GetMuRatio(int n) const { return mu_ratio_[n]; } - - //! const pointer to mu_ratio_ - Real const *GetMuRatio() const { return &mu_ratio_[0]; } - - //! Ratio of molecular weights [1] - //! \param[in] n the index of the thermodynamic species - //! \return $\epsilon_i^{-1} =\mu_d/\mu_i$ - Real GetInvMuRatio(int n) const { return inv_mu_ratio_[n]; } - - //! Ratio of specific heat capacity [J/(kg K)] at constant volume [1] - //! \param[in] n the index of the thermodynamic species - //! \return $c_{v,i}/c_{v,d}$ - Real GetCvRatioMass(int n) const { return cv_ratio_mass_[n]; } - - //! const pointer to cv_ratio_mass_ - Real const *GetCvRatioMass() const { return cv_ratio_mass_.data(); } - - //! Ratio of specific heat capacity [J/(mol K)] at constant volume [1] - //! \param[in] n the index of the thermodynamic species - //! \return $\hat{c}_{v,i}/\hat{c}_{v,d}$ - Real GetCvRatioMole(int n) const { return cv_ratio_mole_[n]; } - - //! const pointer to cv_ratio_mole_ - Real const *GetCvRatioMole() const { return cv_ratio_mole_.data(); } - - std::shared_ptr Kinetics() const { return kinetics_; } - - //! \return the index of the cloud - //! \param[in] i the index of the vapor - //! \param[in] j the sequential index of the cloud - int GetCloudIndex(int i, int j) const { return cloud_index_set_[i][j]; } - - //! \return the index set of the cloud - //! \param[in] i the index of the vapor - std::vector GetCloudIndexSet(int i) const { return cloud_index_set_[i]; } - - //! const pointer to cloud_index_set_ - IndexSet const *GetCloudIndexSet() const { return cloud_index_set_.data(); } - - //! Reference specific heat capacity [J/(kg K)] at constant volume - Real GetCvMassRef(int n) const { - Real cvd = Rd_ / (gammad_ref_ - 1.); - return cv_ratio_mass_[n] * cvd; - } - - //! Ratio of specific heat capacity [J/(kg K)] at constant pressure - //! \return $c_{p,i}/c_{p,d}$ - Real GetCpRatioMass(int n) const { return cp_ratio_mass_[n]; } - - //! const pointer to cp_ratio_mass_ - Real const *GetCpRatioMass() const { return cp_ratio_mass_.data(); } - - //! Ratio of specific heat capacity [J/(mol K)] at constant pressure - //! \return $\hat{c}_{p,i}/\hat{c}_{p,d}$ - Real GetCpRatioMole(int n) const { return cp_ratio_mole_[n]; } - - //! const pointer to cp_ratio_mole_ - Real const *GetCpRatioMole() const { return cp_ratio_mole_.data(); } - - Real GetCpMassRef(int n) const { - Real cpd = Rd_ * gammad_ref_ / (gammad_ref_ - 1.); - return cp_ratio_mass_[n] * cpd; - } - - //! \brief Temperature dependent specific latent energy [J/kg] of condensates - //! at constant volume $L_{ij}(T) = L_{ij}^r - (c_{ij} - c_{p,i})\times(T - - //! T^r)$ - //! - //! $= L_{ij}^r - \delta_{ij}R_i(T - T^r)$ - //! \return $L_{ij}(T)$ - Real GetLatentEnergyMass(int n, Real temp = 0.) const { - return latent_energy_mass_[n] - delta_[n] * Rd_ * inv_mu_ratio_[n] * temp; - } - - //! \brief Temperature dependent specific latent energy [J/mol] of condensates - //! at constant volume - //! - //! \return $L_{ij}(T)$ - Real GetLatentEnergyMole(int n, Real temp = 0.) const { - return GetLatentEnergyMass(n, temp) * mu_[n]; - } - - //! const pointer to latent_energy_mole_ - Real const *GetLatentEnergyMole() const { return &latent_energy_mole_[0]; } - - Real GetLatentHeatMole(int i, std::vector const &rates, - Real temp) const; - - Real GetLatentHeatMass(int i, std::vector const &rates, - Real temp) const { - return GetLatentHeatMole(i, rates, temp) * inv_mu_[i]; - } - - //! \brief Calculate the equilibrium mole transfer by cloud reaction - //! vapor -> cloud - //! - //! \param[in] qfrac mole fraction representation of air parcel - //! \param[in] ivapor the index of the vapor - //! \param[in] cv_hat $cv_hat$ molar heat capacity - //! \param[in] misty if true, there is an infinite supple of cloud - //! \return molar fraction change of vapor to cloud - RealArrayX TryEquilibriumTP_VaporCloud(AirParcel const &qfrac, int ivapor, - Real cv_hat = 0., - bool misty = false) const; - - //! \brief Calculate the equilibrium mole transfer by cloud reaction - //! vapor1 + vapor2 -> cloud - //! - //! \param[in] air mole fraction representation of air parcel - //! \param[in] ij the index pair of the vapor1 and vapor2 - //! \param[in] cv_hat $\har{cv}$ molar heat capacity - //! \param[in] misty if true, there is an infinite supple of cloud - //! \return molar fraction change of vapor1, vapor2 and cloud - RealArray3 TryEquilibriumTP_VaporVaporCloud(AirParcel const &air, - IndexPair ij, Real cv_hat = 0., - bool misty = false) const; - - //! Construct an 1d atmosphere - //! \param[in,out] qfrac mole fraction representation of air parcel - //! \param[in] dzORdlnp vertical grid spacing - //! \param[in] method choose from [reversible, pseudo, dry, isothermal] - //! \param[in] grav gravitational acceleration - //! \param[in] userp user parameter to adjust the temperature gradient - void Extrapolate(AirParcel *qfrac, Real dzORdlnp, std::string method, - Real grav = 0., Real userp = 0.) const; - - //! Thermodnamic equilibrium at current TP - //! \param[in,out] qfrac mole fraction representation of air parcel - void EquilibrateTP() const; - - void EquilibrateTP(AirParcel *qfrac) const; - - //! Thermodnamic equilibrium at current UV - void EquilibrateUV() const; - - void EquilibrateUV(AirParcel *qfrac) const; - - void EquilibrateSP(double P) const; - - //! Adjust to the maximum saturation state conserving internal energy - //! \param[in,out] ac mole fraction representation of a collection of air - //! parcels - void SaturationAdjustment(AirColumn &ac) const; - - void SetStateFromPrimitive(MeshBlock *pmb, int k, int j, int i) const; - void SetStateFromConserved(MeshBlock *pmb, int k, int j, int i) const; - - //! \brief Calculate potential temperature from primitive variable - //! - //! $\theta = T(\frac{p_0}{p})^{\chi}$ - //! \return $\theta$ - Real PotentialTemp(MeshBlock *pmb, Real p0, int k, int j, int i) const { - auto &w = pmb->phydro->w; - return GetTemp(pmb, k, j, i) * - pow(p0 / w(IPR, k, j, i), GetChi(pmb, k, j, i)); - } - - //! \brief Calculate equivalent potential temperature from primitive variable - //! - //! $\theta_e = T(\frac{p}{p_d})^{Rd/(cpd + cl r_t} \exp(\frac{L_v q_v}{c_p - //! T})$ - Real EquivalentPotentialTemp(MeshBlock *pmb, Real p0, int v, int k, int j, - int i) const; - - //! \brief Calculate temperature from primitive variable - //! - //! $T = p/(\rho R) = p/(\rho \frac{R}{R_d} Rd)$ - //! \return $T$ - Real GetTemp(MeshBlock const *pmb, int k, int j, int i) const { - auto &w = pmb->phydro->w; - return w(IPR, k, j, i) / (w(IDN, k, j, i) * Rd_ * RovRd(pmb, k, j, i)); - } - - //! \brief Mean molecular weight - //! - //! $mu = \mu_d (1 + \sum_i q_i (\epsilon_i - 1))$ - //! \return $mu$ - Real GetMu(MeshBlock const *pmb, int k, int j, int i) const; - - //! \brief Inverse of the mean molecular weight (no cloud) - //! - //! $ \frac{R}{R_d} = \frac{\mu_d}{\mu}$ - //! \return $1/\mu$ - //! Eq.16 in Li2019 - Real RovRd(MeshBlock const *pmb, int k, int j, int i) const { - Real feps = 1.; - auto &w = pmb->phydro->w; -#pragma omp simd reduction(+ : feps) - for (int n = 1; n <= NVAPOR; ++n) - feps += w(n, k, j, i) * (inv_mu_ratio_[n] - 1.); - return feps; - } - - //! \brief Specific heat capacity [J/(kg K)] of the air parcel at constant - //! volume - //! - //! $c_v = c_{v,d}*(1 + \sum_i (q_i*(\hat{c}_{v,i} - 1.))) - //! = \gamma_d/(\gamma_d - 1.)*R_d*T*(1 + \sum_i (q_i*(\hat{c}_{v,i} - //! - 1.)))$ - //! \return $c_v$ - Real GetCvMass(MeshBlock const *pmb, int k, int j, int i) const; - - //! \brief Specific heat capacity [J/(kg K)] of the air parcel at constant - //! pressure - //! - //! $c_p = c_{p,d}*(1 + \sum_i (q_i*(\hat{c}_{p,i} - 1.))) - //! = \gamma_d/(\gamma_d - 1.)*R_d*T*(1 + \sum_i (q_i*(\hat{c}_{p,i} - //! - 1.)))$ - //! \return $c_p$ - Real GetCpMass(MeshBlock const *pmb, int k, int j, int i) const; - - //! \brief Adiabatic index - //! - //! $\chi = \frac{R}{c_p}$ - //! \return $\chi$ - Real GetChi(MeshBlock const *pmb, int k, int j, int i) const; - - //! \brief Polytropic index - //! - //! $\gamma = \frac{c_p}{c_v}$ - //! \return $\gamma$ - Real GetGamma(MeshBlock const *pmb, int k, int j, int i) const; - - //! Pressure from conserved variables - //! \return $p$ - Real GetPres(MeshBlock const *pmb, int k, int j, int i) const; - - //! \brief specific enthalpy [J/kg] of the air parcel - //! - //! $h = c_{p,d}*T*(1 + \sum_i (q_i*(\hat{c}_{p,i} - 1.)))$ - //! $ = \gamma_d/(\gamma_d - 1.)*R_d*T*(1 + \sum_i (q_i*(\hat{c}_{pi} - //! - 1.)))$ - Real GetEnthalpyMass(MeshBlock const *pmb, int k, int j, int i) const; - - //! \brief Moist static energy - //! - //! $h_s = c_{pd}T + gz + L_vq_v + L_s\sum_i q_i$ - //! \return $h_s$ - Real MoistStaticEnergy(MeshBlock const *pmb, Real gz, int k, int j, - int i) const; - - //! \brief Relative humidity - Real RelativeHumidity(MeshBlock const *pmb, int n, int k, int j, int i) const; - - protected: - //! custom functions for vapor (to be overridden by user mods) - void enrollVaporFunctions(); - - protected: - std::shared_ptr kinetics_; - - //! ideal gas constant of dry air in J/kg - Real Rd_; - - //! reference polytropic index of dry air - Real gammad_ref_; - - //! ratio of mean molecular weights - std::array mu_ratio_; - - //! inverse ratio of mean molecular weights - std::array inv_mu_ratio_; - - //! molecular weight [kg/mol] - std::array mu_; - - //! inverse molecular weight [mol/kg] - std::array inv_mu_; - - //! ratio of specific heat capacities [J/mol] at constant pressure - std::array cp_ratio_mole_; - - //! ratio of specific heat capacities [J/mol] at constant pressure - std::array cp_ratio_mass_; - - //! ratio of specific heat capacities [J/mol] at constant volume - std::array cv_ratio_mole_; - - //! ratio of specific heat capacities [J/mol] at constant volume - std::array cv_ratio_mass_; - - //! latent energy at constant volume [J/mol] - std::array latent_energy_mole_; - - //! \brief latent energy at constant volume [J/kg] - //! - //! $L_i^r+\Delta c_{ij}T^r == \beta_{ij}\frac{R_d}{\epsilon_i}T^r$ - std::array latent_energy_mass_; - - //! \brief Dimensionless latent heat - //! - //! $\beta_{ij} = \frac{\Delta U_{ij}}{R_i T^r}$ - //! $\Delta U_{ij}$ is the difference in internal energy between the vapor $i$ - //! and the condensate $j$ $R_i=\hat{R}/m_i=R_d/\epsilon_i$ $T^r$ is the - //! triple point temperature - //! $\beta_{ij} == \frac{L_{ij}^r + \Delta c_{ij}T^r}{R_i T^r}$ - std::array beta_; - - //! \brief Dimensionless differences in specific heat capacity - //! - //! $\delta_{ij} = \frac{c_{ij} - c_{p,i}}{R_i}$ - //! $c_{ij} - c_{p,j}$ is the difference in specific heat - //! capacity at constant pressure. $c_{ij}$ is the heat capacity of - //! condensate $j$ of vapor $i$ - std::array delta_; - - //! triple point temperature [K] - std::array t3_; - - //! triple point pressure [pa] - std::array p3_; - - //! saturation vapor pressure function: Vapor -> Cloud - SVPFunc1Container svp_func1_; - - //! cloud index set - std::vector cloud_index_set_; - - //! reaction information map - std::map cloud_reaction_map_; - - //! saturation vapor pressure function: Vapor + Vapor -> Cloud - SVPFunc2Container svp_func2_; - - //! pointer to the single Thermodynamics instance - static Thermodynamics *mythermo_; - - //! maximum saturation adjustment iterations - int sa_max_iter_ = 5; - - //! saturation adjustment relaxation parameter - Real sa_relax_ = 0.8; - - //! saturation adjustment temperature tolerance - Real sa_ftol_ = 0.01; -}; - -#endif // SRC_SNAP_THERMODYNAMICS_THERMODYNAMICS_HPP_ diff --git a/src/modules/equation_of_state.cpp b/src/modules/equation_of_state.cpp deleted file mode 100644 index e6c9e319..00000000 --- a/src/modules/equation_of_state.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "equation_of_state.hpp" - -#include - -namespace canoe { - -EquationOfStateImpl::EquationOfStateImpl(const EquationOfStateOptions& options_, - std::optional thermo) - : options(options_) { - if (thermo.has_value()) { - thermo_ = register_module("thermo", thermo.value()); - } else { - thermo_ = - register_module("thermo", Thermodynamics(ThermodynamicsOptions())); - } - - reset(); -} - -void EquationOfStateImpl::reset() { - IVX = 1 + thermo_->nvapor() + thermo_->ncloud(); - IPR = 3 + IVX; - NHYDRO = 1 + IPR; - - register_buffer("rmu", torch::zeros({IVX - 1})); - register_buffer("rcv", torch::zeros({IVX - 1})); - register_buffer("gammad", torch::zeros({IVX - 1})); -} - -void EquationOfStateImpl::update_thermo(torch::Tensor const& hydro_u) const { - auto buf = named_buffers(/*recurse=*/false); - - buf["rcv"] = (thermo_->cv_ratio() - 1.).slice(0, 1, IVX); - buf["rmu"] = (1. / thermo_->mu_ratio()).slice(0, 1, IVX); - buf["gammad"] = thermo_->gammad(hydro_u); -} - -torch::Tensor EquationOfStateImpl::gammad(torch::Tensor const& hydro_u) const { - auto buf = named_buffers(/*recurse=*/false); - return buf["gammad"]; -} - -torch::Tensor EquationOfStateImpl::rmu() const { - auto buf = named_buffers(/*recurse=*/false); - return buf["rmu"]; -} - -torch::Tensor EquationOfStateImpl::rcv() const { - auto buf = named_buffers(/*recurse=*/false); - return buf["rcv"]; -} - -int64_t EquationOfStateImpl::ncloud() const { return thermo_->ncloud(); } - -} // namespace canoe diff --git a/src/modules/equation_of_state.hpp b/src/modules/equation_of_state.hpp deleted file mode 100644 index 58b6fc76..00000000 --- a/src/modules/equation_of_state.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include - -#include "thermodynamics.hpp" - -namespace Cantera { -class Kinetics; -} // namespace Cantera - -namespace canoe { - -class Thermodynamics; - -struct EquationOfStateOptions { - EquationOfStateOptions() {} -}; - -class EquationOfStateImpl : public torch::nn::Cloneable { - public: - //! options with which this `EquationOfState` was constructed - EquationOfStateOptions options; - - int64_t IDN = 0; - int64_t IVX = 1; - int64_t IPR = 4; - int64_t NHYDRO = 5; - - // Constructor to initialize the layers - explicit EquationOfStateImpl( - const EquationOfStateOptions& options_, - std::optional thermo = std::nullopt); - - void reset() override; - - void update_thermo(torch::Tensor const& hydro_u) const; - - torch::Tensor gammad(torch::Tensor const& hydro_u) const; - torch::Tensor rmu() const; - torch::Tensor rcv() const; - int64_t ncloud() const; - - protected: - Thermodynamics thermo_ = nullptr; - std::shared_ptr kinetics_; -}; - -TORCH_MODULE(EquationOfState); - -} // namespace canoe diff --git a/src/modules/hydrodynamics.cpp b/src/modules/hydrodynamics.cpp deleted file mode 100644 index b4086a36..00000000 --- a/src/modules/hydrodynamics.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// torch -#include "hydrodynamics.hpp" - -#include - -#include -#include -#include -#include - -enum { DIM1 = 3, DIM2 = 2, DIM3 = 1 }; - -namespace canoe { - -HydrodynamicsImpl::HydrodynamicsImpl(const HydrodynamicsOptions& options_, - Coordinates coord, - std::optional eos) { - coord_ = register_module("coord", coord); - - if (eos.has_value()) { - eos_ = register_module("eos", eos.value()); - } else { - eos_ = register_module("eos", EquationOfState(EquationOfStateOptions())); - } - - reset(); -} - -void HydrodynamicsImpl::reset() { - register_buffer( - "flux1", torch::zeros({eos_->NHYDRO, coord_->ncells3(), coord_->ncells2(), - coord_->ncells1() + 1})); - register_buffer("flux2", - torch::zeros({eos_->NHYDRO, coord_->ncells3(), - coord_->ncells2() + 1, coord_->ncells1()})); - register_buffer("flux3", - torch::zeros({eos_->NHYDRO, coord_->ncells3() + 1, - coord_->ncells2(), coord_->ncells1()})); - register_buffer("w", torch::zeros({eos_->NHYDRO, coord_->ncells3(), - coord_->ncells2(), coord_->ncells1()})); -} - -float HydrodynamicsImpl::cfl() const { return options.cfl(); } - -torch::Tensor HydrodynamicsImpl::forward(torch::Tensor u, double dt) { - auto buf = named_buffers(); - auto gammad = eos_->gammad(u); - - buf["w"] = eos_cons2prim_hydro_ideal(u, gammad, eos_->rmu(), eos_->rcv(), - eos_->ncloud(), coord_->cos_theta()); - - // bc_apply_boundary_conditions_inplace(buf["w"], coord_.options()); - - if (u.size(DIM1) > 0.) { - auto result = recon_weno5_hydro(buf["w"], eos_->IVX, 1); - buf["flux1"] = - rs_hydro_lmars(DIM1, result.first, result.first, gammad, eos_->rmu(), - eos_->rcv(), eos_->ncloud(), coord_->cos_theta()); - } - - // auto dt = max_timestep(w); - - return u - cfl() * dt * - flux_divergence({buf["flux1"], buf["flux2"], buf["flux3"]}, - coord_->areas(), coord_->vol()); - - // Use one of many tensor manipulation functions - // auto prim = torch::relu(fc1->forward(x)); - // x = torch::dropout(x, /*p=*/0.5, /*train=*/is_training()); - // x = fc2->forward(x); - // return torch::log_softmax(x, /*dim=*/1); -} - -} // namespace canoe diff --git a/src/modules/hydrodynamics.hpp b/src/modules/hydrodynamics.hpp deleted file mode 100644 index 2ef359f6..00000000 --- a/src/modules/hydrodynamics.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include -#include - -#include "coordinates.hpp" -#include "equation_of_state.hpp" - -// torch module macro is defined in -// torch/csrc/api/include/torch/nn/pimpl.h - -namespace canoe { - -class EquationOfState; -class Coordinates; - -struct HydrodynamicsOptions { - HydrodynamicsOptions() {} - - TORCH_ARG(float, cfl) = 0.9; - TORCH_ARG(float, grav1) = 0.; -}; - -class HydrodynamicsImpl : public torch::nn::Cloneable { - public: - //! options with which this `Hydrodynamics` was constructed - HydrodynamicsOptions options; - - // Constructor to initialize the layers - explicit HydrodynamicsImpl(const HydrodynamicsOptions& options_, - Coordinates coord, - std::optional eos = std::nullopt); - - void reset() override; - - torch::Tensor initialize() const; - - float cfl() const; - - float max_timestep(torch::Tensor w) const; - - // Implement the one stage forward computation - torch::Tensor forward(torch::Tensor u, double dt); - - protected: - EquationOfState eos_ = nullptr; - Coordinates coord_ = nullptr; - - // Use one of many "standard library" modules - // torch::nn::Linear fc1{nullptr}, fc2{nullptr}; -}; - -/// A `ModuleHolder` subclass for `HydrodynamicsImpl`. -/// See the documentation for `HydrodynamicsImpl` class to learn what methods it -/// provides, and examples of how to use `Hydrodynamics` with -/// `torch::nn::HydrodynamicsOptions`. See the documentation for `ModuleHolder` -/// to learn about PyTorch's module storage semantics. -TORCH_MODULE(Hydrodynamics); - -} // namespace canoe diff --git a/src/modules/opacity_manager.hpp b/src/modules/opacity_manager.hpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/modules/radiative_transfer.hpp b/src/modules/radiative_transfer.hpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/modules/ssp_rk.hpp b/src/modules/ssp_rk.hpp deleted file mode 100644 index 067cf179..00000000 --- a/src/modules/ssp_rk.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - -namespace canoe { - -class Hydrodynamics; -class Transport; - -class SSPRKOptions { - public: - SSPRKOptions(); - - TORCH_ARG(int64_t, nstage) = 1; -}; - -class SSPRKImpl : public torch::nn::Cloneable { - public: - //! options with which this `SSPRK` was constructed - SSPRKOptions options; - - // Constructor to initialize the layers - explicit SSPRKImpl(const SSPRKOptions& options_); - - void reset() override; - - // Implement the one stage forward computation - std::pair forward(torch::Tensor hydro_u, - torch::Tensor scalar_u); - - protected: - Hydrodynamics hydro_; - Transport transport_; -}; - -} // namespace canoe diff --git a/src/modules/thermodynamics.cpp b/src/modules/thermodynamics.cpp deleted file mode 100644 index b8b79063..00000000 --- a/src/modules/thermodynamics.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "thermodynamics.hpp" - -#include - -namespace canoe { - -ThermodynamicsImpl::ThermodynamicsImpl(const ThermodynamicsOptions& options_) - : options(options_) { - reset(); -} - -void ThermodynamicsImpl::reset() { - // Do nothing - register_buffer("cv_ratio", torch::empty({1 + nvapor() + ncloud()})); - register_buffer("mu_ratio", torch::empty({1 + nvapor() + ncloud()})); -} - -int64_t ThermodynamicsImpl::nvapor() const { return options.nvapor(); } - -int64_t ThermodynamicsImpl::ncloud() const { return options.ncloud(); } - -torch::Tensor ThermodynamicsImpl::mu_ratio() const { - auto buf = named_buffers(/*recurse=*/false); - return buf["mu_ratio"]; -} - -torch::Tensor ThermodynamicsImpl::cv_ratio() const { - auto buf = named_buffers(/*recurse=*/false); - return buf["cv_ratio"]; -} - -torch::Tensor ThermodynamicsImpl::gammad(torch::Tensor const& hydro_u) const { - return torch::ones_like(hydro_u) * options.gammad_ref(); -} - -} // namespace canoe diff --git a/src/modules/thermodynamics.hpp b/src/modules/thermodynamics.hpp deleted file mode 100644 index 89688a0c..00000000 --- a/src/modules/thermodynamics.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include -#include - -namespace canoe { - -class ThermodynamicsOptions { - public: - ThermodynamicsOptions() {} - - TORCH_ARG(double, gammad_ref) = 1.4; - TORCH_ARG(int64_t, nvapor) = 0; - TORCH_ARG(int64_t, ncloud) = 0; -}; - -class ThermodynamicsImpl : public torch::nn::Cloneable { - public: - //! options with which this `Thermodynamics` was constructed - ThermodynamicsOptions options; - - // Constructor to initialize the layers - explicit ThermodynamicsImpl(const ThermodynamicsOptions& options_); - - void reset() override; - - int64_t nvapor() const; - int64_t ncloud() const; - - torch::Tensor mu_ratio() const; - torch::Tensor cv_ratio() const; - torch::Tensor gammad(torch::Tensor const& hydro_u) const; - - // Implement the one stage forward computation - std::pair forward(torch::Tensor hydro_u, - torch::Tensor scalar_u); -}; - -TORCH_MODULE(Thermodynamics); - -} // namespace canoe diff --git a/src/modules/transport.hpp b/src/modules/transport.hpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/nbody/CMakeLists.txt b/src/nbody/CMakeLists.txt deleted file mode 100644 index e08d34ce..00000000 --- a/src/nbody/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -set(namel nbody) -string(TOUPPER ${namel} nameu) - -file(GLOB src_files - *.cpp - ) - -string(TOLOWER ${CMAKE_BUILD_TYPE} buildl) -string(TOUPPER ${CMAKE_BUILD_TYPE} buildu) - -add_library(${namel}_${buildl} - OBJECT - ${src_files} - ) - -set_target_properties(${namel}_${buildl} - PROPERTIES - COMPILE_FLAGS ${CMAKE_CXX_FLAGS_${buildu}} - ) diff --git a/src/nbody/nbody_inbound.cpp b/src/nbody/nbody_inbound.cpp deleted file mode 100644 index cf4e7438..00000000 --- a/src/nbody/nbody_inbound.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//! \file nbody_inbound.cpp -//! \brief Implementations of inbound functions to particle - -// Athena++ headers -#include -#include -#include -#include - -// climath -#include // interpn - -// particle -#include "particle_data.hpp" -#include "particles.hpp" - -void ParticleBase::SetVelocitiesFromHydro(Hydro const *phydro, - Coordinates const *pcoord) { - AthenaArray v1, v2, v3; - Real loc[3]; - - v1.InitWithShallowSlice(const_cast &>(phydro->w), 4, IM1, - 1); - v2.InitWithShallowSlice(const_cast &>(phydro->w), 4, IM2, - 1); - v3.InitWithShallowSlice(const_cast &>(phydro->w), 4, IM3, - 1); - - auto pm = pmy_block_->pmy_mesh; - - // loop over particles - for (auto &q : pc) { - loc[0] = q.x3; - loc[1] = q.x2; - loc[2] = q.x1; - - int f = pm->f2 + pm->f3; - // interpolate Eulerian velocity to particle velocity - interpn(&q.v1, loc + 2 - f, v1.data(), pcoord->GetCellCoords() + 2 - f, - pcoord->GetDimensions() + 2 - f, 1 + f, 1); - - if (pm->f2) { - interpn(&q.v2, loc + 2 - f, v2.data(), pcoord->GetCellCoords() + 2 - f, - pcoord->GetDimensions() + 2 - f, 1 + f, 1); - } else { - q.v2 = 0.; - } - - if (pm->f3) { - interpn(&q.v3, loc + 2 - f, v3.data(), pcoord->GetCellCoords() + 2 - f, - pcoord->GetDimensions() + 2 - f, 1 + f, 1); - } else { - q.v3 = 0.; - } - } -} diff --git a/src/nbody/nbody_interaction.hpp b/src/nbody/nbody_interaction.hpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/nbody/particle_data.cpp b/src/nbody/particle_data.cpp deleted file mode 100644 index 7bf99706..00000000 --- a/src/nbody/particle_data.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//! \file particle_data.cpp -//! \brief Implementation of functions in class ParticleData - -// C/C++ headers -#include - -// Athena++ -#include - -// canoe -#include - -// nbody -#include "particle_data.hpp" -#include "particles.hpp" - -std::ostream& operator<<(std::ostream& os, ParticleData const& pt) { - os << "pid: " << pt.pid << ", tid: " << pt.tid << std::endl - << "time: " << pt.time << ", weight: " << pt.weight - << ", charge: " << pt.charge << std::endl - << "x1: " << pt.x1 << ", v1: " << pt.v1 << ", a1: " << pt.a1 << std::endl - << "x2: " << pt.x2 << ", v2: " << pt.v2 << ", a2: " << pt.a2 << std::endl - << "x3: " << pt.x3 << ", v3: " << pt.v3 << ", a3: " << pt.a3 << std::endl; - os << "extra real data: "; - for (int i = 0; i < NREAL_PARTICLE_DATA; ++i) os << pt.rr[i] << ", "; - os << std::endl; - - os << "extra integer data: "; - for (int i = 0; i < NREAL_PARTICLE_DATA; ++i) os << pt.ii[i] << ", "; - os << std::endl; - - return os; -} - -namespace ParticleHelper { - -bool check_in_meshblock(ParticleData const& pd, MeshBlock const* pmb) { - auto pm = pmb->pmy_mesh; - - bool inblock_x1 = - (pd.x1 > pmb->block_size.x1min) && (pd.x1 < pmb->block_size.x1max); - bool inblock_x2 = - (pd.x2 > pmb->block_size.x2min) && (pd.x2 < pmb->block_size.x2max); - bool inblock_x3 = - (pd.x3 > pmb->block_size.x3min) && (pd.x3 < pmb->block_size.x3max); - - return inblock_x1 && (!pm->f2 || inblock_x2) && (!pm->f3 || inblock_x3); -} - -#ifdef MPI_PARALLEL -#include - -MPI_Datatype MPI_PARTICLE_DATA; - -void commit_mpi_particle_data() { - int counts[3] = {1, 2 + NINT_PARTICLE_DATA, 8 + NREAL_PARTICLE_DATA}; - MPI_Datatype types[3] = {MPI_AINT, MPI_INT, MPI_ATHENA_REAL}; - MPI_Aint disps[3] = {offsetof(ParticleData, next), - offsetof(ParticleData, pid), - offsetof(ParticleData, time)}; - - MPI_Type_create_struct(3, counts, disps, types, &MPI_PARTICLE_DATA); - MPI_Type_commit(&MPI_PARTICLE_DATA); -} - -void free_mpi_particle_data() { MPI_Type_free(&MPI_PARTICLE_DATA); } - -#else // NOT_MPI_PARALLEL - -void commit_mpi_particle_data() {} -void free_mpi_particle_data() {} - -#endif // MPI_PARALLEL - -} // namespace ParticleHelper diff --git a/src/nbody/particle_data.hpp b/src/nbody/particle_data.hpp deleted file mode 100644 index 1bf0e059..00000000 --- a/src/nbody/particle_data.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef SRC_NBODY_PARTICLE_DATA_HPP_ -#define SRC_NBODY_PARTICLE_DATA_HPP_ - -// C/C++ headers -#include -#include -#include - -// Athena++ headers -#include - -// canoe -#include - -#ifdef MPI_PARALLEL -#include -#endif // MPI_PARALLEL - -class MeshBlock; - -struct ParticleData { - //! particle can form a linked list - ParticleData* next; - - //! particle id, type id - int pid, tid; - - //! extra integer data - std::array ii; - - //! time instantiated, weight and charge - Real time, weight, charge; - - //! positions - Real x1, x2, x3; - - //! velocities - Real v1, v2, v3; - - //! accelerations - Real a1, a2, a3; - - //! extra real data - std::array rr; -}; - -std::ostream& operator<<(std::ostream& os, ParticleData const& mp); - -// helper functions -namespace ParticleHelper { - -bool check_in_meshblock(ParticleData const& pd, MeshBlock const* pmb); -void commit_mpi_particle_data(); -void free_mpi_particle_data(); - -#ifdef MPI_PARALLEL -extern MPI_Datatype MPI_PARTICLE_DATA; -#endif - -} // namespace ParticleHelper - -#endif // SRC_NBODY_PARTICLE_DATA_HPP_ diff --git a/src/nbody/particle_exchanger.cpp b/src/nbody/particle_exchanger.cpp deleted file mode 100644 index b21e37cc..00000000 --- a/src/nbody/particle_exchanger.cpp +++ /dev/null @@ -1,234 +0,0 @@ -//! \file particle_exchanger.cpp -//! \brief Implements functions derived from class NeighborExchanger - -// C/C++ header -#include -#include -#include - -// application -#include - -// Athena++ headers -#include -#include - -// canoe -#include - -// n-body -#include "particle_data.hpp" -#include "particles.hpp" - -#ifdef MPI_PARALLEL -#include -#endif - -bool ParticleBase::UnpackData(MeshBlock const *pmb) { - bool success = true; - int test; - - auto pm = pmb->pmy_mesh; - - for (auto &nb : pmb->pbval->neighbor) { - if (status_flag_[nb.bufid] == BoundaryStatus::completed) continue; - -#ifdef MPI_PARALLEL - if (status_flag_[nb.bufid] == BoundaryStatus::waiting) { - MPI_Test(&req_mpi_recv_[nb.bufid], &test, MPI_STATUS_IGNORE); - if (test) - status_flag_[nb.bufid] = BoundaryStatus::arrived; - else { - success = false; - continue; - } - } -#endif - - if (status_flag_[nb.bufid] == BoundaryStatus::arrived) { - auto it = recv_buffer_[nb.bufid].begin(); - - for (; it != recv_buffer_[nb.bufid].end(); ++it) { - // 0:INNER_X1, 1:OUTER_X1 - if (pm->mesh_bcs[(nb.ni.ox1 + 1) >> 1] == BoundaryFlag::periodic) { - if (it->x1 >= pm->mesh_size.x1max) - it->x1 -= pm->mesh_size.x1max - pm->mesh_size.x1min; - if (it->x1 <= pm->mesh_size.x1min) - it->x1 += pm->mesh_size.x1max - pm->mesh_size.x1min; - } - - // 2:INNER_X2, 3:OUTER_X2 - if (pm->mesh_bcs[2 + ((nb.ni.ox2 + 1) >> 1)] == - BoundaryFlag::periodic) { - if (it->x2 >= pm->mesh_size.x2max) - it->x2 -= pm->mesh_size.x2max - pm->mesh_size.x2min; - if (it->x2 <= pm->mesh_size.x2min) - it->x2 += pm->mesh_size.x2max - pm->mesh_size.x2min; - } - - // 4:INNER_X3, 5:OUTER_X3 - if (pm->mesh_bcs[4 + ((nb.ni.ox3 + 1) >> 1)] == - BoundaryFlag::periodic) { - if (it->x3 >= pm->mesh_size.x3max) - it->x3 -= pm->mesh_size.x3max - pm->mesh_size.x3min; - if (it->x3 <= pm->mesh_size.x3min) - it->x3 += pm->mesh_size.x3max - pm->mesh_size.x3min; - } - - bool in_meshblock = ParticleHelper::check_in_meshblock(*it, pmb); - if (!in_meshblock) { - throw RuntimeError("ParticleBase::AttachParticles", - "Particle moved out of MeshBlock limits"); - } else { - pc.push_back(*it); - } - } - - SetBoundaryStatus(nb.bufid, BoundaryStatus::completed); // completed - } - } - - return success; -} - -// This subroutine will remove inactive particles (id < 0) and move particles to -// appropriate buffers if they moved out of the current domain -void ParticleBase::PackData(MeshBlock const *pmb) { - auto pm = pmb->pmy_mesh; - - Real x1min = pmb->block_size.x1min; - Real x1max = pmb->block_size.x1max; - Real x2min = pmb->block_size.x2min; - Real x2max = pmb->block_size.x2max; - Real x3min = pmb->block_size.x3min; - Real x3max = pmb->block_size.x3max; - - int ox1 = 0, ox2 = 0, ox3 = 0, fi1 = 0, fi2 = 0; - auto qi = pc.begin(); - auto qj = pc.end(); - - while (qi < qj) { - // if particle is inactive, swap the current one with the last one - if (qi->pid < 0) { - *qi = *(qj - 1); - qj--; - continue; - } // proceed to living particle - // take care of reflective boundary condition - if (pmb->pbval->block_bcs[inner_x1] == BoundaryFlag::reflect && - qi->x1 < x1min) { - qi->x1 = 2 * x1min - qi->x1; - qi->v1 = -qi->v1; - } - if (pmb->pbval->block_bcs[outer_x1] == BoundaryFlag::reflect && - qi->x1 > x1max) { - qi->x1 = 2 * x1max - qi->x1; - qi->v1 = -qi->v1; - } - ox1 = qi->x1 < x1min ? -1 : (qi->x1 > x1max ? 1 : 0); - - if (pm->f2) { - if (pmb->pbval->block_bcs[inner_x2] == BoundaryFlag::reflect && - qi->x2 < x2min) { - qi->x2 = 2 * x2min - qi->x2; - qi->v2 = -qi->v2; - } else if (pmb->pbval->block_bcs[inner_x2] == BoundaryFlag::polar && - qi->x2 < 0.) { - // \todo TODO: fix pole problem - } - if (pmb->pbval->block_bcs[outer_x2] == BoundaryFlag::reflect && - qi->x2 > x2max) { - qi->x2 = 2 * x2max - qi->x2; - qi->v2 = -qi->v2; - } else if (pmb->pbval->block_bcs[outer_x2] == BoundaryFlag::polar && - qi->x2 > 2. * M_PI) { - // \todo TODO: fix pole problem - } - ox2 = qi->x2 < x2min ? -1 : (qi->x2 > x2max ? 1 : 0); - } - - if (pm->f3) { - if (pmb->pbval->block_bcs[inner_x3] == BoundaryFlag::reflect && - qi->x3 < x3min) { - qi->x3 = 2 * x3min - qi->x3; - qi->v3 = -qi->v3; - } - if (pmb->pbval->block_bcs[outer_x3] == BoundaryFlag::reflect && - qi->x3 > x3max) { - qi->x3 = 2 * x3max - qi->x3; - qi->v3 = -qi->v3; - } - ox3 = qi->x3 < x3min ? -1 : (qi->x3 > x3max ? 1 : 0); - } - - if (pm->multilevel) { - // reserved implementation for multilevel, fi1, fi2 - } - - int bid = BoundaryBase::FindBufferID(ox1, ox2, ox3, fi1, fi2); - if (bid == -1) { // particle inside domain - qi++; - } else { // particle moved out of the domain - // std::cout << "particle (" << qi->id << "," << qi->x2 << ") move to " << - // bid << std::endl;; std::cout << "block range = (" << x1min << "," << - // x1max << ")" << std::endl; - send_buffer_[bid].push_back(*qi); - // pmb->pdebug->msg << *qi; - *qi = *(qj - 1); - qj--; - } - } - - // particles beyond qi are inactive particles. Remove them from the list - pc.resize(qi - pc.begin()); -} - -void ParticleBase::Transfer(MeshBlock const *pmb, int n) { - for (auto &nb : pmb->pbval->neighbor) { - if (nb.snb.rank == Globals::my_rank) { // on the same process - MeshBlock *neighbor = pmb->pmy_mesh->FindMeshBlock(nb.snb.gid); - auto exchanger = static_cast( - neighbor->pimpl->GetExchanger("Particle")); - exchanger->recv_buffer_[nb.targetid].swap(send_buffer_[nb.bufid]); - exchanger->SetBoundaryStatus(nb.targetid, BoundaryStatus::arrived); - } -#ifdef MPI_PARALLEL - else { // MPI - int tag = - ExchangerHelper::create_mpi_tag(nb.snb.lid, nb.targetid, "Particle"); - int ssize = send_buffer_[nb.bufid].size(); - MPI_Isend(send_buffer_[nb.bufid].data(), ssize, - ParticleHelper::MPI_PARTICLE_DATA, nb.snb.rank, tag, mpi_comm_, - &req_mpi_send_[nb.bufid]); - } -#endif - } - - int rsize, tag; - -#ifdef MPI_PARALLEL - MPI_Status status; - for (auto &nb : pmb->pbval->neighbor) { - if (nb.snb.rank == Globals::my_rank) continue; // local boundary received - - int tag = ExchangerHelper::create_mpi_tag(pmb->lid, nb.bufid, "Particle"); - - MPI_Probe(nb.snb.rank, tag, MPI_COMM_WORLD, &status); - MPI_Get_count(&status, ParticleHelper::MPI_PARTICLE_DATA, &rsize); - - recv_buffer_[nb.bufid].resize(rsize); - MPI_Irecv(recv_buffer_[nb.bufid].data(), rsize, - ParticleHelper::MPI_PARTICLE_DATA, nb.snb.rank, tag, mpi_comm_, - &req_mpi_recv_[nb.bufid]); - } -#endif -} - -void ParticleBase::ClearBuffer(MeshBlock const *pmb) { - for (auto &nb : pmb->pbval->neighbor) { -#ifdef MPI_PARALLEL - if (nb.snb.rank != Globals::my_rank) - MPI_Wait(&req_mpi_send_[nb.bufid], MPI_STATUS_IGNORE); -#endif - } -} diff --git a/src/nbody/particle_integrator.cpp b/src/nbody/particle_integrator.cpp deleted file mode 100644 index 1c1a4248..00000000 --- a/src/nbody/particle_integrator.cpp +++ /dev/null @@ -1,44 +0,0 @@ -//! \file particle_integrator.cpp -//! \brief Implements functions derived from clas MultistageTimeIntegrator - -// C/C++ -#include - -// athena -#include - -// n-body -#include "particle_data.hpp" -#include "particles.hpp" - -void ParticleBase::TimeIntegrate(Real time, Real dt) { - if (std::strcmp(COORDINATE_SYSTEM, "cartesian") == 0) { - for (auto& it : pc) { - it.x1 += it.v1 * dt; - it.x2 += it.v2 * dt; - it.x3 += it.v3 * dt; - } - } else if (std::strcmp(COORDINATE_SYSTEM, "spherical_polar") == 0) { - for (auto& it : pc) { - it.x1 += it.v1 * dt; - it.x2 += it.v2 * dt / it.x1; - it.x3 += it.v3 * dt / (it.x1 * sin(it.x2)); - } - } - - linked_flag_ = false; -} - -void ParticleBase::WeightedAverage(Real ave_wghts[]) { - size_t psize = pc.size(); - - for (size_t i = 0; i < psize; ++i) { - pc[i].x1 = ave_wghts[0] * pc[i].x1 + ave_wghts[1] * pc1[i].x1; - pc[i].x2 = ave_wghts[0] * pc[i].x2 + ave_wghts[1] * pc1[i].x2; - pc[i].x3 = ave_wghts[0] * pc[i].x3 + ave_wghts[1] * pc1[i].x3; - - pc[i].v1 = ave_wghts[0] * pc[i].v1 + ave_wghts[1] * pc1[i].v1; - pc[i].v2 = ave_wghts[0] * pc[i].v2 + ave_wghts[1] * pc1[i].v2; - pc[i].v3 = ave_wghts[0] * pc[i].v3 + ave_wghts[1] * pc1[i].v3; - } -} diff --git a/src/nbody/particle_outputs.cpp b/src/nbody/particle_outputs.cpp deleted file mode 100644 index d5249311..00000000 --- a/src/nbody/particle_outputs.cpp +++ /dev/null @@ -1,30 +0,0 @@ -//! \file particle_outputs.cpp -//! \brief Output functions for particles - -// athena -#include - -// n-body -#include "particles.hpp" - -bool ParticleBase::ShouldMeshOutput(std::string variable_name) const { - return variable_name.compare("particle") == 0; -} - -void ParticleBase::LoadMeshOutputData(OutputType *out, int *num_vars) const { - OutputData *pod = new OutputData; - pod->type = "SCALARS"; - pod->name = "p-weight"; - pod->data.InitWithShallowSlice(const_cast &>(weight), 4, 0, - 1); - out->AppendOutputDataNode(pod); - *num_vars += 1; - - pod = new OutputData; - pod->type = "SCALARS"; - pod->name = "p-charge"; - pod->data.InitWithShallowSlice(const_cast &>(charge), 4, 0, - 1); - out->AppendOutputDataNode(pod); - *num_vars += 1; -} diff --git a/src/nbody/particle_restart.cpp b/src/nbody/particle_restart.cpp deleted file mode 100644 index 0253f732..00000000 --- a/src/nbody/particle_restart.cpp +++ /dev/null @@ -1,60 +0,0 @@ -//! \file particle_restart.cpp -//! \brief Implements functions derived from clas RestartGroup - -// Athena++ -#include - -// canoe -#include - -// n-body -#include "particle_data.hpp" -#include "particles.hpp" - -// mpi -#ifdef MPI_PARALLEL -#include -#endif - -size_t ParticleBase::RestartDataSizeInBytes(Mesh const *pm) const { - size_t size = sizeof(int); - size += pc.size() * sizeof(ParticleData); - - // gather maximum size across all local blocks - for (int b = 0; b < pm->nbtotal; b++) { - auto pmb = pm->my_blocks(b); - for (auto &pt : pmb->pimpl->all_particles) { - size_t tmp = sizeof(int) + pt->pc.size() * sizeof(ParticleData); - if (tmp > size) size = tmp; - } - } - - // gather maximum size across all MPI ranks -#ifdef MPI_PARALLEL - MPI_Allreduce(MPI_IN_PLACE, &size, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); -#endif - - return size; -} - -//! \todo mark out invalid particles -void ParticleBase::DumpRestartData(char *pdst) const { - int size = pc.size(); - - std::memcpy(pdst, &size, sizeof(int)); - pdst += sizeof(int); - std::memcpy(pdst, pc.data(), size * sizeof(ParticleData)); - pdst += size * sizeof(ParticleData); -} - -size_t ParticleBase::LoadRestartData(char *psrc) { - int size; - - std::memcpy(&size, psrc, sizeof(int)); - psrc += sizeof(int); - pc.resize(size); - std::memcpy(pc.data(), psrc, size * sizeof(ParticleData)); - psrc += size * sizeof(ParticleData); - - return size; -} diff --git a/src/nbody/particle_to_mesh.cpp b/src/nbody/particle_to_mesh.cpp deleted file mode 100644 index 23490e9b..00000000 --- a/src/nbody/particle_to_mesh.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//! \file particle_mesh.cpp -//! \brief Implements the functions to transfer particle data to mesh - -// C/C++ headers -#include - -// Athena++ headers -#include -#include -#include - -// climath -#include // locate - -// n-body -#include "particle_data.hpp" -#include "particles.hpp" - -void ParticleBase::LinkMesh() { - auto pmb = pmy_block_; - auto pcoord = pmb->pcoord; - - // initialize cell aggregated particle weight u and linked list - weight.ZeroClear(); - charge.ZeroClear(); - - std::fill(pd_in_cell_.data(), pd_in_cell_.data() + pd_in_cell_.GetSize(), - nullptr); - int i, j, k; - - auto dims = pcoord->GetDimensions(); - auto x321f = pcoord->GetFaceCoords(); - - // loop over particles - for (auto& qi : pc) { - k = locate(x321f, qi.x3, dims[0] + 1); - j = locate(x321f + dims[0] + 1, qi.x2, dims[1] + 1); - i = locate(x321f + dims[0] + dims[1] + 2, qi.x1, dims[2] + 1); - - auto tid = qi.tid; - - weight(tid, k, j, i) += qi.weight; - charge(tid, k, j, i) += qi.charge; - - if (pd_in_cell_(tid, k, j, i) == nullptr) { - pd_in_cell_(tid, k, j, i) = &qi; - pd_in_cell_(tid, k, j, i)->next = nullptr; - } else { // insert sort from low to high weight - ParticleData* tmp; - if (pd_in_cell_(tid, k, j, i)->weight < qi.weight) { - auto qj = pd_in_cell_(tid, k, j, i); - while (qj->next != nullptr && qj->next->weight < qi.weight) - qj = qj->next; - tmp = qj->next; - qj->next = &qi; - qj->next->next = tmp; - } else { - tmp = pd_in_cell_(tid, k, j, i); - pd_in_cell_(tid, k, j, i) = &qi; - pd_in_cell_(tid, k, j, i)->next = tmp; - } - } - } - - linked_flag_ = true; -} diff --git a/src/nbody/particles.cpp b/src/nbody/particles.cpp deleted file mode 100644 index 57e1fdd6..00000000 --- a/src/nbody/particles.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//! \file particles.cpp -//! \brief Implements class ParticleBase and helper functions - -// C++ headers -#include - -// application -#include -#include - -// Athena++ -#include - -// utils -#include - -// n-body -#include "particle_data.hpp" -#include "particles.hpp" - -// constructor, initializes data structure and parameters -ParticleBase::ParticleBase(MeshBlock *pmb, std::string name) - : NamedGroup(name), linked_flag_(false), pmy_block_(pmb) { - Application::Logger app("n-body"); - app->Log("Initialize ParticleBase"); - - int nc1 = pmb->ncells1, nc2 = pmb->ncells2, nc3 = pmb->ncells3; - - weight.NewAthenaArray(nc3, nc2, nc1); - charge.NewAthenaArray(nc3, nc2, nc1); - pd_in_cell_.NewAthenaArray(nc3, nc2, nc1); -} - -ParticleBase::~ParticleBase() { - Application::Logger app("n-body"); - app->Log("Destroy ParticleBase"); -} - -AllParticles ParticlesFactory::Create(MeshBlock *pmb, ParameterInput *pin) { - AllParticles all_particles; - - std::string str = pin->GetOrAddString("particles", "particles", ""); - auto particle_names = Vectorize(str.c_str()); - - for (auto const &name : particle_names) { - if (name == "2pcp") { - all_particles.push_back(std::make_shared(pmb, name)); - } else if (name == "scp") { - all_particles.push_back(std::make_shared(pmb, name)); - } else { - throw NotImplementedError("Particle '" + name + "' unrecognized."); - } - } - - return all_particles; -} - -namespace ParticlesHelper { - -ParticlePtr find_particle(AllParticles const &pts, std::string name) { - for (auto &pt : pts) { - if (pt->GetName() == name) return pt; - } - return nullptr; -} - -} // namespace ParticlesHelper diff --git a/src/nbody/particles.hpp b/src/nbody/particles.hpp deleted file mode 100644 index 9203083c..00000000 --- a/src/nbody/particles.hpp +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef SRC_NBODY_PARTICLES_HPP_ -#define SRC_NBODY_PARTICLES_HPP_ - -// C++ headers -#include -#include -#include - -// Athena++ -#include - -// canoe -#include - -// exchanger -#include - -// integrator -#include - -class MeshBlock; -class ParameterInput; -class Coordinates; -class ParticleData; -class Hydro; - -using ParticleContainer = std::vector; - -class ParticleBase : public NamedGroup, - public RestartGroup, - // ASCIIOutputGroup, - // BinaryOutputGroup, - public MeshOutputGroup { - public: - /// public data - //! particle data container. pc1 is reserved for multi-stage integration - ParticleContainer pc, pc1; - - //! exchanger - std::shared_ptr> pexb; - - //! integrator - std::shared_ptr pint; - - //! mesh data container - AthenaArray weight, charge; - - public: // constructor and destructor - ParticleBase(MeshBlock *pmb, std::string name); - virtual ~ParticleBase(); - - public: // member functions - /// particle-mesh - void LinkMesh(); - - public: // inbound functions - void SetVelocitiesFromHydro(Hydro const *phydro, Coordinates const *pcoord); - - public: // RestartGroup functions - size_t RestartDataSizeInBytes(Mesh const *pm) const override; - void DumpRestartData(char *pdst) const override; - size_t LoadRestartData(char *psrt) override; - - public: // MeshOutputGroup functions - bool ShouldMeshOutput(std::string variable_name) const override; - void LoadMeshOutputData(OutputType *pod, int *num_vars) const override; - - public: // MultiStageIntegrator functions - void TimeIntegrate(Real time, Real dt) override; - void WeightedAverage(Real ave_wghts[]) override; - - public: // Exchanger functions - void PackData(MeshBlock const *pmb); - bool UnpackData(MeshBlock const *pmb); - void Transfer(MeshBlock const *pmb, int n = -1); - void ClearBuffer(MeshBlock const *pmb); - - protected: - /// protected data - //! linked list of particles in cell - AthenaArray pd_in_cell_; - - //! linked flag - bool linked_flag_; - - private: - //! pointer to parent MeshBlock - MeshBlock const *pmy_block_; -}; - -using ParticlePtr = std::shared_ptr; -using AllParticles = std::vector; - -// factory methods -class ParticlesFactory { - public: - static AllParticles Create(MeshBlock *pmb, ParameterInput *pin); -}; - -// helper functions -namespace ParticlesHelper { -ParticlePtr find_particle(AllParticles const &pts, std::string name); -} // namespace ParticlesHelper - -namespace AllTasks { - -bool launch_particles(MeshBlock *pmb, int stage); -bool integrate_particles(MeshBlock *pmb, int stage); -bool mesh_to_particles(MeshBlock *pmb, int stage); -bool send_particles(MeshBlock *pmb, int stage); -bool recv_particles(MeshBlock *pmb, int stage); -bool particles_to_mesh(MeshBlock *pmb, int stage); -bool attach_particles(MeshBlock *pmb, int stage); - -} // namespace AllTasks - -#endif // SRC_NBODY_PARTICLE_BASE_HPP_ diff --git a/src/nbody/z.to_do/particle_exchanger.cpp b/src/nbody/z.to_do/particle_exchanger.cpp deleted file mode 100644 index 682d02fc..00000000 --- a/src/nbody/z.to_do/particle_exchanger.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// C/C++ headers -#include -// #include -#include // hash -#include - -// n-body -#include "particle_data.hpp" -#include "particle_exchanger.hpp" -#include "particle_group.hpp" - -#ifdef MPI_PARALLEL -// defined in main.cpp -extern MPI_Datatype MPI_PARTICLE; -#endif - -ParticleExchanger::ParticleExchanger(ParticleGroup *pg) : pmy_particle(pg) {} - -ParticleExchanger::~ParticleExchanger() {} - -void ParticleExchanger::SendParticle() {} - -void ParticleExchanger::RecvParticle() {} - -void ParticleExchanger::ClearBoundary() {} diff --git a/src/nbody/z.to_do/particle_exchanger.hpp b/src/nbody/z.to_do/particle_exchanger.hpp deleted file mode 100644 index 6ed34728..00000000 --- a/src/nbody/z.to_do/particle_exchanger.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef NBODY_PARTICLE_EXCHANGER_HPP_ -#define NBODY_PARTICLE_EXCHANGER_HPP_ - -// MPI header -#ifdef MPI_PARALLEL -#include -#endif - -// C/C++ header -#include - -// communication -#include - -// n-body -#include "particle_data.hpp" -#include "particle_group.hpp" - -//! Defines the class for managing buffers for transporting particles. -class ParticleExchanger : public Exchanger { - protected: - Particle const *pmy_particle; - - public: - // functions - ParticleExchanger(Particle *pg) : pmy_particle(pg) {} - - ~ParticleExchanger() {} - - void DetachTo(std::vector &buffer) override; - bool AttachTo(std::vector &container) const override; - - protected: - bool checkOutOfDomain(ParticleData &p) const; - - MeshBlock const *getMeshBlock() const override { - return pmy_particle->pmy_block; - } -}; - -#endif // NBODY_PARTICLE_EXCHANGER_HPP_ diff --git a/src/nbody/z.to_do/particles.cpp b/src/nbody/z.to_do/particles.cpp deleted file mode 100644 index 6f8b47a9..00000000 --- a/src/nbody/z.to_do/particles.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//! \file particle_factory.cpp -//! \brief Implements Particle factory methods - -// C/C++ -#include - -// application -#include - -// Athena++ -#include -#include - -// utils -#include - -// nbody -#include "particles.hpp" -#include "particles_factory.hpp" diff --git a/src/nbody/z.to_do/particulate.cpp b/src/nbody/z.to_do/particulate.cpp deleted file mode 100644 index cdfc73c6..00000000 --- a/src/nbody/z.to_do/particulate.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/** @file particulate.cpp - * @brief - * - * @author Cheng Li (chengcli@umich.edu) - * @date Sunday Jun 13, 2021 12:16:32 PDT - * @bug No known bugs. - */ - -// C++ headers -#include -#include // hash -#include -#include - -// Athena++ headers -#include "../coordinates/coordinates.hpp" -#include "../debugger/debugger.hpp" -#include "../globals.hpp" -#include "particles.hpp" - -// Particulate executes after chemistry, which is applied to aggreated -// quantities u It synchronized the particles in mp and the aggreated quantities -// after chemistry -void Particles::Particulate(std::vector &mp, - AthenaArray const &u) { - MeshBlock *pmb = pmy_block; - pmb->pdebug->Call("Particles::Particulate-" + myname); - - Coordinates *pco = pmb->pcoord; - // particle buffer - std::vector mpb; - - for (int t = 0; t < u.GetDim4(); ++t) - for (int k = pmb->ks; k <= pmb->ke; ++k) - for (int j = pmb->js; j <= pmb->je; ++j) - for (int i = pmb->is; i <= pmb->ie; ++i) { - // u1_ stores the total particle density before chemistry - // u stores the total particle density after chemistry - // if delta_u is positive, new particles are added. Otherwise, - // particle densities are adjusted to reflect the change of density - Real delta_u = u(t, k, j, i) - u1_(t, k, j, i); - // 1. count current number of particles in the cell - int nparts = 0; - MaterialPoint *pc = pcell_(t, k, j, i); - while (pc != nullptr) { - pc = pc->next; - nparts++; - } - - // 2. if the number of particles (n0) is greater than the maximum - // allowed particles per cell (nmax_per_cell_), mark particles for - // merging (destroy). Particle densities have been sorted from low to - // high. particles to be removed (merged) are marked as inactive (id = - // -1) and zero density (rho = 0). nparts reflects the number of - // active particles in cell - int n0 = nparts; - Real drho = 0., sum = 0.; - pc = pcell_(t, k, j, i); - /* method 1 - if (pc != nullptr) { - while (nparts > nmax_per_cell_ || pc->rho+drho < density_floor_) { - if (nparts == 1) break; - drho += (pc->rho+drho)/(nparts-1); - pc->id = -1; - pc->rho = 0; - pc = pc->next; - nparts--; - } - }*/ - - // method 2 - for (int n = 0; n < n0 - nmax_per_cell_; ++n) { - sum += pc->rho; - pc->id = -1; - pc->rho = 0; - pc = pc->next; - nparts--; - } - drho = sum / nparts; - - // Distribute the total density of inactive particles to active - // particles. - pcell_(t, k, j, i) = pc; - while (pc != nullptr) { - pc->rho += drho; - pc = pc->next; - } - - // 3. add new particles to the empty particle buffer mpb or increase - // the density of existing particles - if (delta_u > 0.) { - // avg stores the mean density to be allocated to particles - Real avg = delta_u / seeds_per_cell_; - // num sotres the available number of particles to be added to cell - int num = std::min(nmax_per_cell_ - nparts, seeds_per_cell_); - // add new particles with density avg - std::string str = myname + std::to_string(t) + - std::to_string(pmb->gid) + std::to_string(i) + - std::to_string(j) + std::to_string(k) + 't' + - std::to_string(pmb->pmy_mesh->time) + 'n'; - for (int n = 0; n < num; ++n) { - MaterialPoint p; - p.id = std::abs((int)std::hash{}( - str + std::to_string(n))) % - (1 << 20); - p.type = t; - p.time = pmb->pmy_mesh->time; - p.x1 = pco->x1f(i) + (1. * rand() / RAND_MAX) * pco->dx1f(i); - p.x2 = pco->x2f(j) + (1. * rand() / RAND_MAX) * pco->dx2f(j); - p.x3 = pco->x3f(k) + (1. * rand() / RAND_MAX) * pco->dx3f(k); - p.v1 = 0.; - p.v2 = 0.; - p.v3 = 0.; - p.rho = avg; - mpb.push_back(p); - } - - // add the remaining mass to existing particles - pc = pcell_(t, k, j, i); - for (int n = 0; n < seeds_per_cell_ - num; ++n) { - pc->rho += avg; - pc = pc->next; - } - // 4. removes existing particles - } else if (delta_u < 0.) { - Real avg = std::abs(delta_u) / nparts; - pc = pcell_(t, k, j, i); - // std::cout << "c = " << u(t,k,j,i) << " c1 = " << u1_(t,k,j,i) << - // std::endl; std::cout << "[" << pco->x1f(i) << "," << - // pco->x1f(i+1) << "]" << std::endl; std::cout << "delta_u = " << - // delta_u << " nparts = " << nparts << std::endl; - for (int n = 0; n < nparts; ++n) { - // std::cout << pc->x1 << " " << pc->rho << " "; - if (pc->rho > avg) { - delta_u += avg; - pc->rho -= avg; - } else { - delta_u += pc->rho; - avg = std::abs(delta_u) / (nparts - n - 1); - // available_ids_.push_back(pc->id); - pc->id = -1; - pc->rho = 0; - } - // std::cout << pc->rho << std::endl; - // std::cout << delta_u << " " << avg << std::endl; - pc = pc->next; - } - std::stringstream msg; - /*if (std::abs(delta_u) > density_floor_) { - msg << "### FATAL ERROR in Particles::Particulate:" << std::endl - << "(" << k << "," << j << "," << i << ") = " << nparts << - std::endl - << "u = " << u(t,k,j,i) << " u1 = " << u1_(t,k,j,i) << - std::endl - << "delta_u = " << delta_u << std::endl - << "density_floor_ = " << density_floor_ << std::endl; - ATHENA_ERROR(msg); - }*/ - } - } - - // transfer from particle buffer (mpb) to storage (mp); - // mp.reserve(mp.size() + mpb.size()); - // mp.insert(mp.end(), mpb.begin(), mpb.end()); - for (std::vector::iterator it = mpb.begin(); it != mpb.end(); - ++it) - mp.push_back(*it); - -#if DEBUG_LEVEL > 2 - pmb->pdebug->CheckParticleConservation(cnames_, mp); -#endif - - pmb->pdebug->Leave(); -} diff --git a/src/nbody/z.to_do/simple_cloud_particles.cpp b/src/nbody/z.to_do/simple_cloud_particles.cpp deleted file mode 100644 index 17d367c9..00000000 --- a/src/nbody/z.to_do/simple_cloud_particles.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** @file simple_cloud_particles.cpp - * @brief - * - * @author Cheng Li (chengcli@umich.edu) - * @date Wednesday Jun 09, 2021 18:33:03 PDT - * @bug No known bugs. - */ - -// C/C++ header -#include -#include -#include - -// Athena++ header -#include "../coordinates/coordinates.hpp" -#include "../debugger/debugger.hpp" -#include "../hydro/hydro.hpp" -#include "../hydro/srcterms/hydro_srcterms.hpp" -#include "../math/interpolation.h" // locate -#include "../mesh/mesh.hpp" -#include "particles.hpp" - -SimpleCloudParticles::SimpleCloudParticles(MeshBlock *pmb, ParameterInput *pin, - std::string name) - : Particles(pmb, pin, name, 2) { - // ATHENA_LOG("SimpleCloudParticles"); - pmb->pdebug->Enter("SimpleCloudParticles"); - std::stringstream &msg = pmb->pdebug->msg; - msg << "- first category is " << name + " cloud" << std::endl - << "- second category is " << name + " precipitation" << std::endl; - cnames_.resize(2); - cnames_[0] = "cloud"; - cnames_[1] = "rain"; - - Real mu = pin->GetReal("particles", name + ".mu"); - Real cc = pin->GetReal("particles", name + ".cc"); - - mu_.push_back(mu); - mu_.push_back(mu); - - cc_.push_back(cc); - cc_.push_back(cc); - pmb->pdebug->Leave(); -} - -void SimpleCloudParticles::ExchangeHydro(std::vector &mp, - AthenaArray &du, - AthenaArray const &w, Real dt) { - MeshBlock *pmb = pmy_block; - pmb->pdebug->Call("SimpleCloudParticles::ExchangeHydro-" + myname); - std::stringstream &msg = pmb->pdebug->msg; - - Mesh *pm = pmb->pmy_mesh; - Coordinates *pcoord = pmb->pcoord; - AthenaArray v1, v2, v3; - Real loc[3]; - - v1.InitWithShallowSlice(const_cast &>(w), 4, IM1, 1); - v2.InitWithShallowSlice(const_cast &>(w), 4, IM2, 1); - v3.InitWithShallowSlice(const_cast &>(w), 4, IM3, 1); - - Real g1 = pmb->phydro->hsrc.GetG1(); - Real g2 = pmb->phydro->hsrc.GetG2(); - Real g3 = pmb->phydro->hsrc.GetG3(); - - int f = pm->f2 + pm->f3; - for (std::vector::iterator q = mp.begin(); q != mp.end(); - ++q) { - loc[0] = q->x3; - loc[1] = q->x2; - loc[2] = q->x1; - - interpnf(&q->v1, loc + 2 - f, v1.data(), xcenter_.data() + 2 - f, - dims_.data() + 2 - f, 1 + f); - if (pm->f2) - interpnf(&q->v2, loc + 2 - f, v2.data(), xcenter_.data() + 2 - f, - dims_.data() + 2 - f, 1 + f); - else - q->v2 = 0.; - if (pm->f3) - interpnf(&q->v3, loc + 2 - f, v3.data(), xcenter_.data() + 2 - f, - dims_.data() + 2 - f, 1 + f); - else - q->v3 = 0.; - - if (std::isnan(q->v1) || std::isnan(q->v2) || std::isnan(q->v3)) { - msg << "### FATAL ERROR in SimpleCloudParticle::ExchangeHydro. Particles " - << myname << " velocity is nan" << std::endl; - msg << "id = " << q->id << std::endl - << "type = " << q->type << std::endl - << "x1 = " << q->x1 << std::endl - << "x2 = " << q->x2 << std::endl - << "x3 = " << q->x3 << std::endl - << "v1 = " << q->v1 << std::endl - << "v2 = " << q->v2 << std::endl - << "v3 = " << q->v3 << std::endl; - Real k = locate(xcenter_.data(), q->x3, dims_[0]); - Real j = locate(xcenter_.data() + dims_[0], q->x2, dims_[1]); - Real i = locate(xcenter_.data() + dims_[0] + dims_[1], q->x1, dims_[2]); - std::cout << i << " " << pcoord->x1v(i) << " " << pcoord->x1v(i + 1) - << std::endl; - std::cout << j << " " << pcoord->x2v(j) << " " << pcoord->x2v(j + 1) - << std::endl; - std::cout << k << " " << pcoord->x3v(k) << " " << pcoord->x3v(k + 1); - ATHENA_ERROR(msg); - } - - // \todo TODO: hard coded sedimentation - if (q->type == 1) q->v1 += -10.; - - // add gravititional acceleration - int k, j, i; - k = locate(xface_.data(), q->x3, dims_[0] + 1); - j = locate(xface_.data() + dims_[0] + 1, q->x2, dims_[1] + 1); - i = locate(xface_.data() + dims_[0] + dims_[1] + 2, q->x1, dims_[2] + 1); - - Real src = dt * q->rho; - du(IM1, k, j, i) += src * g1; - du(IM2, k, j, i) += src * g2; - du(IM3, k, j, i) += src * g3; - du(IEN, k, j, i) += src * (g1 * q->v1 + g2 * q->v2 + g3 * q->v3); - } - -#if DEBUG_LEVEL > 2 - pmb->pdebug->CheckConservation("du", du, pmb->is, pmb->ie, pmb->js, pmb->je, - pmb->ks, pmb->ke); -#endif - pmb->pdebug->Leave(); -} diff --git a/src/nbody/z.to_do/two_phase_cloud_particles.cpp b/src/nbody/z.to_do/two_phase_cloud_particles.cpp deleted file mode 100644 index e3c35ced..00000000 --- a/src/nbody/z.to_do/two_phase_cloud_particles.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/** @file two_phase_cloud_particles.cpp - * @brief - * - * @author Cheng Li (chengcli@umich.edu) - * @date Monday May 31, 2021 13:38:00 PDT - * @bug No known bugs. - */ - -// C/C++ headers -#include - -// Athena++ headers -#include "../mesh/mesh.hpp" -#include "particles.hpp" - -TwoPhaseCloudParticles::TwoPhaseCloudParticles(MeshBlock *pmb, - ParameterInput *pin, - std::string name) - : Particles(pmb, pin, name, 2) { - ATHENA_LOG("TwoPhaseCloudParticles") - cnames_.resize(2); - cnames_[0] = "liquid"; - cnames_[1] = "solid"; - std::cout << "- First category is " << name + " liquid" << std::endl; - std::cout << "- Second category is " << name + " solid" << std::endl; -} - -void TwoPhaseCloudParticles::ExchangeHydro(std::vector &mp, - AthenaArray &du, - AthenaArray const &w, - Real dt) { - Particles::ExchangeHydro(mp, du, w, dt); - // for (std::vector::iterator it = mp.begin(); it != mp.end(); - // ++it) { - // it->v1 += -10.; - // } -} diff --git a/src/outputs/fits.cpp b/src/outputs/fits.cpp deleted file mode 100644 index 3fc0b990..00000000 --- a/src/outputs/fits.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*! \file fits.cpp - * \brief writes output data in FITS format (for inversion tasks) - */ - -// C/C++ -#include -#include -#include -#include -#include - -// athena -#include -#include -#include - -// canoe -#include - -// inversion -#include - -#ifdef FITSOUTPUT -extern "C" { -#include -} - -FITSOutput::FITSOutput(OutputParameters oparams) : OutputType(oparams) {} - -void FITSOutput::WriteOutputFile(Mesh *pm, ParameterInput *pin, bool flag) { - // TODO : saftgard for pfit == null - // create filename: "file_basename"+"."+"file_id"+"."+XXXXX+".fits", - // where XXXXX = 5-digit file_number - if (output_params.file_number > 0) { - std::string fname = "!"; // clobber - char number[6]; - int err; - snprintf(number, sizeof(number), "%05d", output_params.file_number); - - fname.append(output_params.file_basename); - fname.append("."); - fname.append(output_params.file_id); - fname.append("."); - fname.append(number); - fname.append(".fits"); - - for (int i = 0; i < pm->nblocal; ++i) { - MeshBlock *pmb = pm->my_blocks(i); - auto &pfit = pmb->pimpl->all_fits.back(); - pfit->MakeMCMCOutputs(fname); - pfit->ResetChain(); - } - } - - // increment counters - output_params.file_number++; - output_params.next_time += output_params.dt; - pin->SetInteger(output_params.block_name, "file_number", - output_params.file_number); - pin->SetReal(output_params.block_name, "next_time", output_params.next_time); -} - -#endif // FITSOUTPUT diff --git a/src/single_column/CMakeLists.txt b/src/single_column/CMakeLists.txt deleted file mode 100644 index 9f9b1dce..00000000 --- a/src/single_column/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -set(namel scm) -string(TOUPPER ${namel} nameu) - -file(GLOB src_files - *.cpp - ) - -string(TOLOWER ${CMAKE_BUILD_TYPE} buildl) -string(TOUPPER ${CMAKE_BUILD_TYPE} buildu) - -add_library(${namel}_${buildl} - OBJECT - ${src_files} - ) - -set_target_properties(${namel}_${buildl} - PROPERTIES - COMPILE_FLAGS ${CMAKE_CXX_FLAGS_${buildu}} - ) diff --git a/src/single_column/convective_adjustment.cpp b/src/single_column/convective_adjustment.cpp deleted file mode 100644 index 1ceb1faa..00000000 --- a/src/single_column/convective_adjustment.cpp +++ /dev/null @@ -1,205 +0,0 @@ -// C/C++ -#include -#include -#include - -// external -#include - -// athena -#include -#include -#include - -// canoe -#include - -// climath -#include - -// snap -#include -#include - -// scm -#include "single_column.hpp" - -struct TPBottomSolver { - SingleColumn *pscm; - int il, iu; - Real mass0, enthalpy0; - AirParcel air0; -}; - -//! wrapper function passing to broyden_root -//! over SingleColumn::findTPBottom -void find_tp_bottom(int n, double *x, double *f, void *arg) { - TPBottomSolver *psolver = static_cast(arg); - - AirParcel air = psolver->air0; - - air.w[IDN] *= x[0]; - air.w[IPR] *= x[1]; - - auto result = - psolver->pscm->findAdiabaticMassEnthalpy(air, psolver->il, psolver->iu); - - f[0] = result[0] / psolver->mass0 - 1.; - f[1] = result[1] / psolver->enthalpy0 - 1.; -} - -std::array SingleColumn::findAdiabaticMassEnthalpy(AirParcel air, - int il, int iu) { - auto pthermo = Thermodynamics::GetInstance(); - auto pcoord = pmy_block_->pcoord; - Real grav = -pmy_block_->phydro->hsrc.GetG1(); - - // adjust pressure and density, and examine mass and energy conservation - Real mass1 = 0., enthalpy1 = 0.; - - for (int i = il; i <= iu; ++i) { - air.ToMassConcentration(); - - Real density = air.w[IDN]; - for (int n = 1; n <= NVAPOR; ++n) { - density += air.w[n]; - } - - mass1 += density * vol_(i); - enthalpy1 += (air.w[IEN] + density * grav * pcoord->x1v(i)) * vol_(i); - pthermo->Extrapolate(&air, pcoord->dx1f(i), "reversible", grav); - } - - return std::array({mass1, enthalpy1}); -} - -std::array SingleColumn::FindMassEnthalpy(AirColumn const &ac, int k, - int j, int il, int iu) { - auto pcoord = pmy_block_->pcoord; - Real grav = -pmy_block_->phydro->hsrc.GetG1(); - - pcoord->CellVolume(k, j, il, iu, vol_); - - Real mass = 0.; - Real enthalpy = 0.; - - for (int i = il; i <= iu; ++i) { - auto air = ac[i]; - air.ToMassConcentration(); - - Real density = air.w[IDN]; - for (int n = 1; n <= NVAPOR; ++n) { - density += air.w[n]; - } - mass += density * vol_(i); - enthalpy += (air.w[IEN] + density * grav * pcoord->x1v(i)) * vol_(i); - } - - return std::array({mass, enthalpy}); -} - -// type of the function -void SingleColumn::FindUnstableRange(AirColumn const &ac, int il, int iu, - std::vector> &ranges) { - if (il >= iu) return; - - auto pthermo = Thermodynamics::GetInstance(); - auto pcoord = pmy_block_->pcoord; - auto phydro = pmy_block_->phydro; - - Real den_tol = GetPar("den_tol"); - Real grav = -pmy_block_->phydro->hsrc.GetG1(); - - // determine il where convective adjustment starts - for (; il <= iu; ++il) { - auto air0 = ac[il]; - auto air1 = ac[il + 1]; - if (air0.w[IDN] < 0. || air0.w[IPR] < 0.) break; - pthermo->Extrapolate(&air0, pcoord->dx1f(il), "reversible", grav); - air0.ToMassFraction(); - air1.ToMassFraction(); - - if (air0.w[IDN] - air1.w[IDN] < -den_tol) break; - } - - // determine iu where convective adjustment stops - auto air0 = ac[il]; - - int i = il; - for (; i < iu; ++i) { - auto air1 = ac[i + 1]; - pthermo->Extrapolate(&air0, pcoord->dx1f(i), "reversible", grav); - air0.ToMassFraction(); - air1.ToMassFraction(); - - if (air1.w[IDN] < 0. || air1.w[IPR] < 0.) continue; - if (air0.w[IDN] - air1.w[IDN] > den_tol) break; - } - - ranges.push_back(std::array({il, i})); - - FindUnstableRange(ac, i + 1, iu, ranges); -} - -void SingleColumn::ConvectiveAdjustment(AirColumn &ac, int k, int j, int il, - int iu) { - if (il >= iu) return; - - auto pthermo = Thermodynamics::GetInstance(); - auto pcoord = pmy_block_->pcoord; - Real grav = -pmy_block_->phydro->hsrc.GetG1(); - - Real tp_tol = GetPar("rel_tol"); - int max_iter = GetPar("max_iter"); - - TPBottomSolver solver; - solver.pscm = this; - solver.il = il; - solver.iu = iu; - solver.air0 = ac[il]; - solver.air0.ToMassFraction(); - - // sum the energy and mass of all air parcels that to be adjusted - // (conservation of energy and mass) - auto result = FindMassEnthalpy(ac, k, j, il, iu); - solver.mass0 = result[0]; - solver.enthalpy0 = result[1]; - - if (solver.mass0 < 0. || solver.enthalpy0 < 0.) { - throw std::runtime_error("ConvectiveAdjustment: negative mass or enthalpy"); - } - - Real tp_bot[2] = {1., 1.}; - int status = - broyden_root(2, tp_bot, find_tp_bottom, tp_tol, max_iter, &solver); - /*if (status != 0) { - if (status == 4) { - std::cout << "status = " << status << std::endl; - throw std::runtime_error( - "ConvectiveAdjustment: " - "Broyden's method failed to converge"); - } else { - std::cout << "maximum iteration exceeded" << std::endl; - } - }*/ - - solver.air0.w[IDN] *= tp_bot[0]; - solver.air0.w[IPR] *= tp_bot[1]; - - auto app = Application::Logger("single_column"); - - for (int i = il; i <= iu; ++i) { - solver.air0.ConvertTo(ac[i].GetType()); - ac[i].w[IDN] = solver.air0.w[IDN]; - ac[i].w[IPR] = solver.air0.w[IPR]; - ac[i].w[IVX] /= 2.; - ac[i].w[IVY] /= 2.; - ac[i].w[IVZ] /= 2.; - - std::stringstream msg; - msg << "ac[" << k << "," << j << "," << i << "] = " << ac[i]; - app->Log(msg.str()); - - pthermo->Extrapolate(&solver.air0, pcoord->dx1f(i), "reversible", grav); - } -} diff --git a/src/single_column/single_column.cpp b/src/single_column/single_column.cpp deleted file mode 100644 index 2ac58cb4..00000000 --- a/src/single_column/single_column.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// external -#include - -// athena -#include -#include - -// canoe -#include - -// scm -#include "single_column.hpp" - -SingleColumn::SingleColumn(MeshBlock *pmb, ParameterInput *pin) - : pmy_block_(pmb) { - // auto app = Application::GetInstance(); - // app->InstallMonitor("single_column", "single_column.out", - // "single_column.out"); auto log = app->GetMonitor("single_column"); - - Application::Logger app("single_column"); - app->Log("Initialize SingleColumn"); - - SetPar("den_tol", - pin->GetOrAddReal("convective_adjustment", "den_tol", 0.001)); - SetPar("rel_tol", - pin->GetOrAddReal("convective_adjustment", "rel_tol", 1.0e-4)); - SetPar("max_iter", - pin->GetOrAddInteger("convective_adjustment", "max_iter", 10)); - - // allocate scratch arrays - vol_.NewAthenaArray(pmb->ncells1); -} - -SingleColumn::~SingleColumn() { - Application::Logger app("single_column"); - app->Log("Destroy SingleColumn"); -} diff --git a/src/single_column/single_column.hpp b/src/single_column/single_column.hpp deleted file mode 100644 index d554616e..00000000 --- a/src/single_column/single_column.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// C/C++ -#include -#include - -// athena -#include - -// canoe -#include -#include - -class MeshBlock; - -class SingleColumn : public ParameterGroup { - public: - friend void find_tp_bottom(int n, double *x, double *f, void *arg); - - SingleColumn(MeshBlock *pmb, ParameterInput *pin); - virtual ~SingleColumn(); - - //! \param ac vector of air parcels [Mass Fraction] - //! \param il lower index of the range - //! \param iu upper index of the range - void FindUnstableRange(AirColumn const &ac, int il, int iu, - std::vector> &ranges); - - std::array FindMassEnthalpy(AirColumn const &ac, int k, int j, - int il, int iu); - - //! \brief perform convective adjustment over a column range - //! \param ac vector of air parcels [Mass Fraction] - //! \param il lower index of the range - //! \param iu upper index of the range - void ConvectiveAdjustment(AirColumn &ac, int k, int j, int il, int iu); - - protected: // convective adjustment functions - //! Find the mass and enthalpy of an adiabatic air column - //! The air parcel at the starting level is given by ac - std::array findAdiabaticMassEnthalpy(AirParcel air, int il, int iu); - - protected: - //! ptr to meshblock - MeshBlock *pmy_block_; - - //! scrach arrays for volumn - AthenaArray vol_; -}; diff --git a/src/snap/implicit/solve_implicit_3d.cpp b/src/snap/implicit/solve_implicit_3d.cpp index d517c282..5833b302 100644 --- a/src/snap/implicit/solve_implicit_3d.cpp +++ b/src/snap/implicit/solve_implicit_3d.cpp @@ -17,10 +17,6 @@ #include "implicit_solver.hpp" -#ifdef CUBED_SPHERE -namespace cs = CubedSphereUtility; -#endif - void ImplicitSolver::SolveImplicit3D(AthenaArray &du, AthenaArray &w, Real dt) { auto pmb = pmy_block_; @@ -106,7 +102,7 @@ void ImplicitSolver::SolveImplicit3D(AthenaArray &du, for (int k = ks; k <= ke; ++k) for (int j = js; j <= je; ++j) { - // project velocity + // project velocity #ifdef CUBED_SPHERE auto pco = static_cast(pmb->pcoord); Real cos_theta = pco->GetCosineCell(k, j); @@ -129,7 +125,7 @@ void ImplicitSolver::SolveImplicit3D(AthenaArray &du, PartialCorrection(du_, w, dt, k, j, is, ie); } - // de-project velocity + // de-project velocity #ifdef CUBED_SPHERE for (int i = 0; i < w.GetDim1(); ++i) { w(IVZ, k, j, i) /= sin_theta; diff --git a/src/surface/surface.cpp b/src/surface/surface.cpp deleted file mode 100644 index 05658280..00000000 --- a/src/surface/surface.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// athena -#include -#include - -// surface -#include "surface.hpp" diff --git a/src/surface/surface.hpp b/src/surface/surface.hpp deleted file mode 100644 index 16c57338..00000000 --- a/src/surface/surface.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef SRC_SURFACE_SURFACE_HPP_ -#define SRC_SURFACE_SURFACE_HPP_ - -// C/C++ headers -#include -#include - -// Athena++ headers -#include - -// canoe -#include - -// Forward declarations -class MeshBlock; -class ParameterInput; - -//! \brief manages all physics package data and functions -class Surface : public ParameterGroup { - public: - // functions - Surface() {} - virtual ~Surface() {} - - virtual void Initialize(MeshBlock *pmb) {} - - virtual size_t RestartDataSizeInBytes() const { return 0; } - virtual size_t DumpRestartData(char *pdst) const { return 0; } - virtual size_t LoadRestartData(char *psrc) { return 0; } - - virtual void Apply(AthenaArray &du, MeshBlock *pmb, Real time, - Real dt) = 0; -}; - -using SurfacePtr = std::shared_ptr; -using SurfaceContainer = std::vector; - -class SurfaceFactory { - public: - static SurfaceContainer CreateFrom(MeshBlock *pmb, ParameterInput *pin); -}; - -#endif // SRC_SURFACE_SURFACE_HPP_ diff --git a/src/tasklist/extra_tasks.hpp b/src/tasklist/extra_tasks.hpp index ecfc69a8..a402a8be 100644 --- a/src/tasklist/extra_tasks.hpp +++ b/src/tasklist/extra_tasks.hpp @@ -12,28 +12,6 @@ class TaskID; class TaskList; class ParameterInput; -class InversionTasks : public TaskList { - public: - InversionTasks(ParameterInput *pin, Mesh *pm); - ~InversionTasks() {} - // void AddInversionTask(uint64_t id, uint64_t dep); - - TaskStatus CalculateGradient(MeshBlock *pmb, int step); - TaskStatus Sample(MeshBlock *pmb, int step); - TaskStatus Optimize(MeshBlock *pmb, int step); - - private: - void AddTask(const TaskID &id, const TaskID &dep) override; - void StartupTaskList(MeshBlock *pmb, int stage) override; -}; - -namespace InversionTaskNames { -const TaskID NONE(0); -const TaskID CALC_GRAD(1); -const TaskID OPTIMIZE(2); -const TaskID SAMPLE(3); -} // namespace InversionTaskNames - class ImplicitHydroTasks : public TimeIntegratorTaskList { public: ImplicitHydroTasks(ParameterInput *pin, Mesh *pm); diff --git a/src/tasklist/implicit_hydro_tasks.cpp b/src/tasklist/implicit_hydro_tasks.cpp index ee643084..2a555193 100644 --- a/src/tasklist/implicit_hydro_tasks.cpp +++ b/src/tasklist/implicit_hydro_tasks.cpp @@ -28,9 +28,6 @@ // forcing #include -// scm -#include - // checks #include diff --git a/src/tasklist/inversion_tasks.cpp b/src/tasklist/inversion_tasks.cpp deleted file mode 100644 index afdc607c..00000000 --- a/src/tasklist/inversion_tasks.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// C/C++ -#include -#include -#include - -// athena -#include -#include -#include - -// canoe -#include - -// inversion -#include - -// tasklist -#include "extra_tasks.hpp" - -using namespace InversionTaskNames; - -InversionTasks::InversionTasks(ParameterInput *pin, Mesh *pm) { - nstages = 1; - std::string task = pin->GetString("inversion", "task"); - - // Now assemble list of tasks for each step of inversion task - - if (task == "atm_profile") { - AddTask(SAMPLE, NONE); - } else { - std::stringstream msg; - msg << "### FATAL ERROR in InversionTasks::InversionTasks" << std::endl - << "Unrecognized inversion task"; - ATHENA_ERROR(msg); - // AddTask(CALC_GRAD,NONE); - // AddTask(OPTIMIZE,CALC_GRAD); - } -} - -void InversionTasks::AddTask(const TaskID &id, const TaskID &dep) { - task_list_[ntasks].task_id = id; - task_list_[ntasks].dependency = dep; - - if (id == CALC_GRAD) { - task_list_[ntasks].TaskFunc = - static_cast( - &InversionTasks::CalculateGradient); - } else if (id == OPTIMIZE) { - task_list_[ntasks].TaskFunc = - static_cast( - &InversionTasks::Optimize); - } else if (id == SAMPLE) { - task_list_[ntasks].TaskFunc = - static_cast( - &InversionTasks::Sample); - } else { - std::stringstream msg; - msg << "### FATAL ERROR in InversionTasks::AddTask" << std::endl - << "Invalid Task is specified" << std::endl; - ATHENA_ERROR(msg); - } - ntasks++; - return; -} - -void InversionTasks::StartupTaskList(MeshBlock *pmb, int stage) {} - -TaskStatus InversionTasks::CalculateGradient(MeshBlock *pmb, int step) { - // std::cout << "Calculate gradient" << std::endl; - return TaskStatus::success; -} - -TaskStatus InversionTasks::Optimize(MeshBlock *pmb, int step) { - // std::cout << "Optimize" << std::endl; - return TaskStatus::success; -} - -TaskStatus InversionTasks::Sample(MeshBlock *pmb, int step) { - // pmb->pimpl->fitq.front()->MCMCMove(pmb->pimpl->prad.get(), pmb->phydro); - // std::cout << "Sample" << std::endl; - return TaskStatus::success; -} diff --git a/src/tasklist/task_list_factory.hpp b/src/tasklist/task_list_factory.hpp index e2743d53..4769a753 100644 --- a/src/tasklist/task_list_factory.hpp +++ b/src/tasklist/task_list_factory.hpp @@ -28,8 +28,6 @@ class TaskListFactory { ptlist = std::make_unique(pin, mesh); } else if (tasklist_name == "ImplicitHydroTasks") { ptlist = std::make_unique(pin, mesh); - } else if (tasklist_name == "InversionTasks") { - ptlist = std::make_unique(pin, mesh); } else { throw RuntimeError("main", "Unknown tasklist name: " + tasklist_name); } diff --git a/src/torch/CMakeLists.txt b/src/torch/CMakeLists.txt deleted file mode 100644 index 3d425eaf..00000000 --- a/src/torch/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -set(namel torch) -string(TOUPPER ${namel} nameu) - -file(GLOB src_files - eos/*.cpp - hydro/*.cpp - riemann/*.cpp - recon/*.cpp - column/*.cpp - ) - -string(TOLOWER ${CMAKE_BUILD_TYPE} buildl) -string(TOUPPER ${CMAKE_BUILD_TYPE} buildu) - -add_library(${namel}_${buildl} - OBJECT - ${src_files} - ) - -set_target_properties(${namel}_${buildl} - PROPERTIES - COMPILE_FLAGS ${CMAKE_CXX_FLAGS_${buildu}} - ) - -target_include_directories(${namel}_${buildl} - PRIVATE - ${EIGEN3_INCLUDE_DIR} - ) diff --git a/src/torch/column/decom.cpp b/src/torch/column/decom.cpp deleted file mode 100644 index cf1cf970..00000000 --- a/src/torch/column/decom.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// torch -#include - -enum { - DIM1 = 2, - IDN = 0, -}; - -namespace canoe { - -std::tuple decom_obtain_anomaly( - int64_t is, int64_t ie, torch::Tensor const& w, torch::Tensor const& dx1f, - torch::Tensor const& grav) { - auto sizes = w.sizes(); - auto nx1 = w.size(DIM1 + 1); - auto wa = torch::zeros_like(w); - - auto IPR = w.size(0) - 1; - - auto psf = - torch::zeros({w.size(0), w.size(1), w.size(2), nx1 + 1}, w.options()); - auto tsf = torch::zeros(psf.sizes(), w.options()); - - // pressure anomaly - auto RdTv = w[IPR].select(DIM1, ie) / w[IDN].select(DIM1, ie); - auto rhogz = - -grav * w[IDN].slice(DIM1, is, ie + 1) * dx1f.slice(DIM1, is, ie + 1); - - psf.select(DIM1, ie + 1) = - w[IPR].select(DIM1, ie) * exp(-grav * dx1f[ie] / (2. * RdTv)); - psf.slice(DIM1, is + 1, ie + 1) = rhogz.slice(DIM1, is, ie); - psf.select(DIM1, is) = psf.select(DIM1, ie + 1) + rhogz.sum(DIM1); - psf.slice(DIM1, is, ie + 1) = psf.slice(DIM1, is, ie + 1).cumsum(DIM1); - - auto dpsf = psf.slice(DIM1, 0, nx1 - 1) - psf.slice(DIM1, 1, nx1); - auto mask = dpsf.abs() < 1.e-5; - - auto psv = torch::where( - mask, 0.5 * (psf.slice(DIM1, 0, nx1 - 1) + psf.slice(DIM1, 1, nx1)), - dpsf / (psf.slice(DIM1, 0, nx1 - 1) / psf.slice(DIM1, 1, nx1)).log()); - - //! virtual temperature anomaly - auto tsv = psv / w[IDN]; - tsf.slice(DIM1, is + 1, ie) = - 0.5 * (tsv.slice(DIM1, is, ie - 1) + tsv.slice(DIM1, is + 1, ie)); - tsf.select(DIM1, ie + 1) = tsv.select(DIM1, ie); - tsf.select(DIM1, is) = 2 * tsv.select(DIM1, is) - tsf.select(DIM1, is + 1); - - wa[IDN] = w[IPR] / w[IDN] - tsv; - wa[IPR] -= psv; - return {wa, psf, tsf}; -} - -void decom_apply_anomaly_inplace(torch::Tensor const& psf, - torch::Tensor const& tsf, torch::Tensor& wl, - torch::Tensor& wr) { - auto IPR = wl.size(0) - 1; - - wl[IPR] += psf; - torch::Tensor mask = wl[IPR] < 0; - wl[IPR] = torch::where(mask, psf, wl[IPR]); - - wr[IPR] += psf; - mask = wr[IPR] < 0; - wr[IPR] = torch::where(mask, psf, wr[IPR]); - - wl[IDN] += tsf; - mask = wl[IDN] < 0; - wl[IDN] = wl[IPR] / torch::where(mask, tsf, wl[IDN]); - - wr[IDN] += tsf; - mask = wr[IDN] < 0; - wr[IDN] = wr[IPR] / torch::where(mask, tsf, wr[IDN]); -} - -} // namespace canoe diff --git a/src/torch/column/decom.hpp b/src/torch/column/decom.hpp deleted file mode 100644 index 9f38f556..00000000 --- a/src/torch/column/decom.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -namespace at { -class Tensor; -} // namespace at - -namespace torch { -using Tensor = at::Tensor; -} // namespace torch - -namespace canoe { -std::pair decom_obtain_anomaly( - int64_t is, int64_t ie, torch::Tensor const& w, torch::Tensor const& dx1f, - torch::Tensor const& grav); - -void decom_apply_anomaly_inplace(torch::Tensor const& psf, - torch::Tensor const& tsf, torch::Tensor& wl, - torch::Tensor& wr) -} // namespace canoe diff --git a/src/torch/eos/eos.cpp b/src/torch/eos/eos.cpp deleted file mode 100644 index ae2eea1f..00000000 --- a/src/torch/eos/eos.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// torch -#include - -namespace canoe::eos { -void _check_dim1(int64_t IVX, int64_t ncloud, const torch::Tensor &var, - const torch::Tensor &gammad) { - if (IVX < 1) { - AT_ERROR("IVX must be at least 1"); - } - - if (var.dim() != 4) { - AT_ERROR("variable must have 4 dimensions"); - } - - if (gammad.dim() != 3) { - AT_ERROR("gammad must have 3 dimensions"); - } - - if (ncloud >= IVX) { - AT_ERROR("ncloud must be less than IVX"); - } -} - -void _check_dim2(int64_t IVX, std::optional var) { - if (var.value().dim() != 1 || var.value().size(0) != IVX - 1) { - AT_ERROR("array must have size", IVX - 1, ", and dimension 1"); - } -} - -//! \todo Implement this function. -void _apply_conserved_limiter_inplace(torch::Tensor &cons) {} - -//! \todo Implement this function. -void _apply_primitive_limiter_inplace(torch::Tensor &prim) {} -} // namespace canoe::eos diff --git a/src/torch/eos/eos.hpp b/src/torch/eos/eos.hpp deleted file mode 100644 index c3db71ad..00000000 --- a/src/torch/eos/eos.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -namespace c10 { -template -class ArrayRef; -} - -namespace at { -class Tensor; -} - -namespace torch { -using Tensor = at::Tensor; -using TensorList = c10::ArrayRef; -} // namespace torch - -namespace canoe { -namespace eos { -void _check_dim1(int64_t IVX, int64_t ncloud, const torch::Tensor &var, - const torch::Tensor &gammad); -void _check_dim2(int64_t IVX, std::optional var); - -void _apply_conserved_limiter_inplace(torch::Tensor &cons); -void _apply_primitive_limiter_inplace(torch::Tensor &prim); -} // namespace eos - -torch::Tensor eos_cons2prim_hydro_ideal( - torch::Tensor &cons, const torch::Tensor &gammad, - std::optional rmu = std::nullopt, - std::optional rcv = std::nullopt, int64_t ncloud = 0, - std::optional cos_theta = std::nullopt); - -torch::Tensor eos_prim2cons_hydro_ideal( - torch::Tensor &prim, const torch::Tensor &gammad, - std::optional rmu = std::nullopt, - std::optional rcv = std::nullopt, int64_t ncloud = 0, - std::optional cos_theta = std::nullopt); -} // namespace canoe diff --git a/src/torch/eos/eos_hydro_ideal.cpp b/src/torch/eos/eos_hydro_ideal.cpp deleted file mode 100644 index 65a86049..00000000 --- a/src/torch/eos/eos_hydro_ideal.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// torch -#include - -// exo3 -#include // vec_raise_inplace - -// snap -#include "eos.hpp" - -enum { - DIMC = 0, - IDN = 0, -}; - -namespace canoe { -using namespace eos; - -torch::Tensor eos_cons2prim_hydro_ideal( - torch::Tensor &cons, const torch::Tensor &gammad, - std::optional rmu, std::optional rcv, - int64_t ncloud, std::optional cos_theta) { - auto IVX = cons.size(DIMC) - 4; - auto IVY = IVX + 1; - auto IVZ = IVX + 2; - auto IPR = IVX + 3; - - _check_dim1(IVX, ncloud, cons, gammad); - - _apply_conserved_limiter_inplace(cons); - - auto prim = torch::zeros_like(cons); - - prim[IDN] = cons.slice(DIMC, 0, IVX).sum(DIMC); - prim.slice(DIMC, 1, IPR) = cons.slice(DIMC, 1, IPR) / prim[IDN]; - - if (cos_theta.has_value()) { // velocities are at an angle - vec_raise_inplace(prim, cos_theta.value()); - } - - auto feps = torch::ones_like(cons[0]); - - if (rmu.has_value() && IVX > 1) { - _check_dim2(IVX, rmu); - auto primu = - prim.slice(DIMC, 1, IVX - ncloud).unfold(DIMC, IVX - ncloud - 1, 1); - feps += torch::matmul(primu, rmu.value().slice(DIMC, 0, IVX - ncloud - 1)) - .squeeze(DIMC) - - prim.slice(DIMC, IVX - ncloud, IVX).sum(DIMC); - } - - auto fsig = torch::ones_like(cons[0]); - - if (rcv.has_value() && IVX > 1) { - _check_dim2(IVX, rcv); - auto primu = prim.slice(DIMC, 1, IVX).unfold(DIMC, IVX - 1, 1); - fsig += torch::matmul(primu, rcv.value()).squeeze(DIMC); - } - - auto ke = 0.5 * (prim[IVX] * cons[IVX] + prim[IVY] * cons[IVY] + - prim[IVZ] * cons[IVZ]); - - prim[IPR] = (gammad - 1) * (cons[IPR] - ke) * feps / fsig; - - _apply_primitive_limiter_inplace(prim); - - return prim; -} - -torch::Tensor eos_prim2cons_hydro_ideal( - torch::Tensor &prim, const torch::Tensor &gammad, - std::optional rmu, std::optional rcv, - int64_t ncloud, std::optional cos_theta) { - auto IVX = prim.size(DIMC) - 4; - auto IVY = IVX + 1; - auto IVZ = IVX + 2; - auto IPR = IVX + 3; - - _check_dim1(IVX, ncloud, prim, gammad); - - _apply_primitive_limiter_inplace(prim); - - auto cons = torch::zeros_like(prim); - - cons[IDN] = (1. - prim.slice(DIMC, 1, IVX).sum(DIMC)) * prim[IDN]; - cons.slice(DIMC, 1, IPR) = prim.slice(DIMC, 1, IPR) * prim[IDN]; - - if (cos_theta.has_value()) { // velocities are at an angle - vec_lower_inplace(cons, cos_theta.value()); - } - - auto feps = torch::ones_like(cons[0]); - - if (rmu.has_value()) { - _check_dim2(IVX, rmu); - auto primu = - prim.slice(DIMC, 1, IVX - ncloud).unfold(DIMC, IVX - ncloud - 1, 1); - - feps += torch::matmul(primu, rmu.value().slice(DIMC, 0, IVX - ncloud - 1)) - .squeeze(DIMC) - - prim.slice(DIMC, IVX - ncloud, IVX).sum(DIMC); - } - - auto fsig = torch::ones_like(cons[0]); - - if (rcv.has_value()) { - _check_dim2(IVX, rcv); - auto primu = prim.slice(DIMC, 1, IVX).unfold(DIMC, IVX - 1, 1); - fsig += torch::matmul(primu, rcv.value()).squeeze(DIMC); - } - - auto ke = 0.5 * (prim[IVX] * cons[IVX] + prim[IVY] * cons[IVY] + - prim[IVZ] * cons[IVZ]); - - cons[IPR] = prim[IPR] * fsig / feps / (gammad - 1) + ke; - - _apply_conserved_limiter_inplace(cons); - - return cons; -} -} // namespace canoe diff --git a/src/torch/exo3/exo3.cpp b/src/torch/exo3/exo3.cpp deleted file mode 100644 index 4925bc13..00000000 --- a/src/torch/exo3/exo3.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// torch -#include - -//! \todo Implement this function. -void vec_lower_inplace(torch::Tensor &prim, torch::TensorList cos_theta) {} - -//! \todo Implement this function. -void vec_raise_inplace(torch::Tensor &prim, torch::TensorList cos_theta) {} diff --git a/src/torch/exo3/exo3.hpp b/src/torch/exo3/exo3.hpp deleted file mode 100644 index 7223b083..00000000 --- a/src/torch/exo3/exo3.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -namespace c10 { -template -class ArrayRef; -} - -namespace at { -class Tensor; -} - -namespace torch { -using Tensor = at::Tensor; -using TensorList = c10::ArrayRef; -} // namespace torch - -void vec_lower_inplace(torch::Tensor &prim, torch::TensorList cos_theta); -void vec_raise_inplace(torch::Tensor &prim, torch::TensorList cos_theta); diff --git a/src/torch/hydro/flux_divergence.cpp b/src/torch/hydro/flux_divergence.cpp deleted file mode 100644 index cabedb5f..00000000 --- a/src/torch/hydro/flux_divergence.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// torch -#include - -// snap -#include "hydro.hpp" - -namespace canoe { - -enum { - DIM1 = 3, - DIM2 = 2, - DIM3 = 1, - DIMC = 0, -}; - -torch::Tensor flux_divergence(torch::TensorList flux, torch::TensorList area, - torch::Tensor const& vol) { - // vol and area are 3D - auto nvar = flux[0].size(DIMC); - auto nx1 = vol.size(DIM1); - auto nx2 = vol.size(DIM2); - auto nx3 = vol.size(DIM3); - - torch::Tensor dflx = torch::zeros({nvar, nx3, nx2, nx1}, vol.options()); - - if (nx1 > 1) { - dflx.slice(DIM1, 0, nx1 - 1) += - area[0].slice(DIM1, 1, nx1) * flux[0].slice(DIM1, 1, nx1) - - area[0].slice(DIM1, 0, nx1 - 1) * flux[0].slice(DIM1, 0, nx1 - 1); - } - - if (nx2 > 1) { - dflx.slice(DIM2, 0, nx2 - 1) += - area[1].slice(DIM2, 1, nx2) * flux[1].slice(DIM2, 1, nx2) - - area[1].slice(DIM2, 0, nx2 - 1) * flux[1].slice(DIM2, 0, nx2 - 1); - } - - if (nx3 > 1) { - dflx.slice(DIM3, 0, nx3 - 1) += - area[2].slice(DIM3, 1, nx3) * flux[2].slice(DIM3, 1, nx3) - - area[2].slice(DIM3, 0, nx3 - 1) * flux[2].slice(DIM3, 0, nx3 - 1); - } - - return dflx / vol; -} - -} // namespace canoe diff --git a/src/torch/hydro/hydro.hpp b/src/torch/hydro/hydro.hpp deleted file mode 100644 index e7fea2de..00000000 --- a/src/torch/hydro/hydro.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -namespace c10 { -template -class ArrayRef; -} // namespace c10 - -namespace at { -class Tensor; -} // namespace at - -namespace torch { -using Tensor = at::Tensor; -using TensorList = c10::ArrayRef; -} // namespace torch - -namespace canoe { -torch::Tensor flux_divergence(torch::TensorList flux, torch::TensorList area, - torch::Tensor const& vol); -} // namespace canoe diff --git a/src/torch/recon/interpolation.cpp b/src/torch/recon/interpolation.cpp deleted file mode 100644 index 3d3c654b..00000000 --- a/src/torch/recon/interpolation.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// torch -#include - -// snap -#include "interpolation.hpp" - -#define sqr(x) ((x) * (x)) - -using namespace torch; - -namespace canoe { -namespace cp5coeff { -Tensor c1m = tensor({-1. / 20., 9. / 20., 47. / 60., -13. / 60., 1. / 30.}, - dtype(kFloat32)); -} // namespace cp5coeff - -namespace weno5coeff { -Tensor c1m = tensor({-1. / 6., 5. / 6., 1. / 3., 0., 0.}, dtype(kFloat32)); -Tensor c2m = tensor({0., 1. / 3., 5. / 6., -1. / 6., 0.}, dtype(kFloat32)); -Tensor c3m = tensor({0., 0., 11. / 6., -7. / 6., 1. / 3.}, dtype(kFloat32)); -Tensor c4m = tensor({1, -2, 1, 0, 0}, dtype(kFloat32)); -Tensor c5m = tensor({1, -4, 3, 0, 0}, dtype(kFloat32)); -Tensor c6m = tensor({0, 1, -2, 1, 0}, dtype(kFloat32)); -Tensor c7m = tensor({0, -1, 0, 1, 0}, dtype(kFloat32)); -Tensor c8m = tensor({0, 0, 1, -2, 1}, dtype(kFloat32)); -Tensor c9m = tensor({0, 0, 3, -4, 1}, dtype(kFloat32)); -} // namespace weno5coeff - -void Interpolation::ToDevice(c10::DeviceType dtype) { - for (auto& c : cm_) c = c.to(dtype); - for (auto& c : cp_) c = c.to(dtype); -} - -Center5Interp::Center5Interp(c10::DeviceType dtype) { - cm_ = {cp5coeff::c1m}; - cp_ = cm_; - for (auto& c : cp_) c = flip(c, {0}); - - ToDevice(dtype); -} - -Tensor Center5Interp::left(Tensor const& phi) const { - return matmul(phi, cm_[0]); -} - -Tensor Center5Interp::right(Tensor const& phi) const { - return matmul(phi, cp_[0]); -} - -Weno5Interp::Weno5Interp(c10::DeviceType dtype) { - cm_ = {weno5coeff::c1m, weno5coeff::c2m, weno5coeff::c3m, - weno5coeff::c4m, weno5coeff::c5m, weno5coeff::c6m, - weno5coeff::c7m, weno5coeff::c8m, weno5coeff::c9m}; - cp_ = cm_; - for (auto& c : cp_) c = flip(c, {0}); - - ToDevice(dtype); -} - -Tensor Weno5Interp::left(Tensor const& phi) const { - Tensor beta1 = - 13. / 12. * sqr(matmul(phi, cm_[3])) + 1. / 4. * sqr(matmul(phi, cm_[4])); - Tensor beta2 = - 13. / 12. * sqr(matmul(phi, cm_[5])) + 1. / 4. * sqr(matmul(phi, cm_[6])); - Tensor beta3 = - 13. / 12. * sqr(matmul(phi, cm_[7])) + 1. / 4. * sqr(matmul(phi, cm_[8])); - - Tensor alpha1 = 0.3 / sqr(beta1 + 1e-6); - Tensor alpha2 = 0.6 / sqr(beta2 + 1e-6); - Tensor alpha3 = 0.1 / sqr(beta3 + 1e-6); - return (alpha1 * matmul(phi, cm_[0]) + alpha2 * matmul(phi, cm_[1]) + - alpha3 * matmul(phi, cm_[2])) / - (alpha1 + alpha2 + alpha3); -} - -Tensor Weno5Interp::right(Tensor const& phi) const { - Tensor beta1 = - 13. / 12. * sqr(matmul(phi, cp_[3])) + 1. / 4. * sqr(matmul(phi, cp_[4])); - Tensor beta2 = - 13. / 12. * sqr(matmul(phi, cp_[5])) + 1. / 4. * sqr(matmul(phi, cp_[6])); - Tensor beta3 = - 13. / 12. * sqr(matmul(phi, cp_[7])) + 1. / 4. * sqr(matmul(phi, cp_[8])); - - Tensor alpha1 = 0.3 / sqr(beta1 + 1e-6); - Tensor alpha2 = 0.6 / sqr(beta2 + 1e-6); - Tensor alpha3 = 0.1 / sqr(beta3 + 1e-6); - return (alpha1 * matmul(phi, cp_[0]) + alpha2 * matmul(phi, cp_[1]) + - alpha3 * matmul(phi, cp_[2])) / - (alpha1 + alpha2 + alpha3); -} -} // namespace canoe diff --git a/src/torch/recon/interpolation.hpp b/src/torch/recon/interpolation.hpp deleted file mode 100644 index f58561ae..00000000 --- a/src/torch/recon/interpolation.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -// C/C++ -#include - -// torch -#include - -namespace at { -class Tensor; -} - -namespace torch { -using Tensor = at::Tensor; -} - -namespace canoe { -class Interpolation { - public: - Interpolation() {} - virtual ~Interpolation() {} - - void ToDevice(c10::DeviceType dtype); - virtual torch::Tensor left(torch::Tensor const& phi) const = 0; - virtual torch::Tensor right(torch::Tensor const& phi) const = 0; - - protected: - std::vector cm_; - std::vector cp_; -}; - -class Center5Interp : public Interpolation { - public: - explicit Center5Interp(c10::DeviceType dtype = c10::kCPU); - - torch::Tensor left(torch::Tensor const& phi) const override; - torch::Tensor right(torch::Tensor const& phi) const override; -}; - -class Weno5Interp : public Interpolation { - public: - explicit Weno5Interp(c10::DeviceType dtype = c10::kCPU); - - torch::Tensor left(torch::Tensor const& phi) const override; - torch::Tensor right(torch::Tensor const& phi) const override; -}; -} // namespace canoe diff --git a/src/torch/recon/recon.hpp b/src/torch/recon/recon.hpp deleted file mode 100644 index 794d89cb..00000000 --- a/src/torch/recon/recon.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -namespace at { -class Tensor; -} // namespace at - -namespace torch { -using Tensor = at::Tensor; -} // namespace torch - -namespace canoe { -std::pair recon_weno5_hydro( - const torch::Tensor &w, int64_t IVX, int64_t dim, bool mixed = true, - bool is_boundary_lower = false, bool is_boundary_upper = false); - -std::pair recon_weno5_scalar( - const torch::Tensor &w, int64_t dim); -} // namespace canoe diff --git a/src/torch/recon/weno5.cpp b/src/torch/recon/weno5.cpp deleted file mode 100644 index 769c3b20..00000000 --- a/src/torch/recon/weno5.cpp +++ /dev/null @@ -1,204 +0,0 @@ -// C/C++ header -#include - -// torch -#include - -// snap -#include "interpolation.hpp" - -// C,D,H,W -enum { - DIMC = 0, - DIM3 = 1, - DIM2 = 2, - DIM1 = 3, - DIMX = 4, - NGHOST = 3, -}; - -namespace canoe { -inline void _weno5_hydro_range(int64_t dim, int64_t il, int64_t iu, - const torch::Tensor &w, const torch::Tensor &wl, - const torch::Tensor &wr, - const Interpolation &interp) { - if (il > iu) return; - - auto wu = w.slice(dim, il - NGHOST, iu + NGHOST - 1).unfold(dim, 5, 1); - auto scale = wu.abs().mean(DIMX) + std::numeric_limits::min(); - wu /= scale.unsqueeze(DIMX); - - wl.slice(dim, il, iu + 1) = interp.right(wu) * scale; - wr.slice(dim, il - 1, iu) = interp.left(wu) * scale; -} - -std::pair recon_weno5_hydro( - const torch::Tensor &w, int64_t IVX, int64_t dim, bool mixed, - bool is_boundary_lower, bool is_boundary_upper) { - int64_t nhydro = w.size(DIMC); - int64_t nweno = mixed ? IVX : nhydro; - Weno5Interp interp1(w.device().type()); - Center5Interp interp2(w.device().type()); - - auto wl = torch::zeros_like(w); - auto wr = torch::zeros_like(w); - - auto w_ = w.slice(DIMC, 0, nweno); - auto wl_ = wl.slice(DIMC, 0, nweno); - auto wr_ = wr.slice(DIMC, 0, nweno); - - auto dim_size = w.size(dim); - int64_t il = NGHOST; - int64_t iu = dim_size - NGHOST + 1; - - if (il > iu) { - AT_ERROR("recon_weno5_hydro: il > iu"); - } - - _weno5_hydro_range(dim, il, iu, w_, wl_, wr_, interp1); - - if (nweno == nhydro) return {wl, wr}; - - // rest of the hydro variables - w_ = w.slice(DIMC, nweno, nhydro); - wl_ = wl.slice(DIMC, nweno, nhydro); - wr_ = wr.slice(DIMC, nweno, nhydro); - - // boundaries - if (dim_size > 2 * NGHOST) { - if (is_boundary_lower) { - _weno5_hydro_range(dim, il, il + NGHOST - 1, w_, wl_, wr_, interp1); - il += NGHOST; - } else if (is_boundary_upper) { - _weno5_hydro_range(dim, iu - NGHOST + 1, iu, w_, wl_, wr_, interp1); - iu -= NGHOST; - } - } else { - if (is_boundary_lower && !is_boundary_upper) { - _weno5_hydro_range(dim, il, il + NGHOST - 1, w_, wl_, wr_, interp1); - il += NGHOST; - } else if (!is_boundary_lower && is_boundary_upper) { - _weno5_hydro_range(dim, iu - NGHOST + 1, iu, w_, wl_, wr_, interp1); - iu -= NGHOST; - } else if (is_boundary_lower && is_boundary_upper) { - int64_t len1 = dim_size / 2; - int64_t len2 = dim_size - len1; - _weno5_hydro_range(dim, il, il + len1 - 1, w_, wl_, wr_, interp1); - _weno5_hydro_range(dim, iu - len2 + 1, iu, w_, wl_, wr_, interp1); - il += len1; - iu -= len2; - } - } - - // interior - _weno5_hydro_range(dim, il, iu, w_, wl_, wr_, interp2); - - return {wl, wr}; -} - -std::pair recon_weno5_scalar( - const torch::Tensor &w, int64_t dim) { - auto wl = torch::zeros_like(w); - auto wr = torch::zeros_like(w); - - int64_t il = NGHOST; - int64_t iu = w.size(dim) - NGHOST + 1; - - if (il > iu) { - AT_ERROR("recon_weno5_scalar: il > iu"); - } - - _weno5_hydro_range(dim, il, iu, w, wl, wr, Weno5Interp(w.device().type())); - return {wl, wr}; -} -} // namespace canoe - -//---------------------------------------------------------------------------------------- -//! \fn Reconstruction::Weno5X2() -/* \brief - -void Reconstruction::Weno5X2(int jl, int ju, const Tensor &w, Tensor &wl, - Tensor &wr) { - int64_t nweno = shock_capture_flag_ ? NHYDRO : IVX; - Weno5Interp interp1(w.device().type()); - Center5Interp interp2(w.device().type()); - - auto w_ = w.slice(DIMC, 0, nweno); - auto wl_ = wl.slice(DIMC, 0, nweno); - auto wr_ = wr.slice(DIMC, 0, nweno); - - for (int j = jl; j <= ju; ++j) { - auto wj = w_.slice(DIM2, j - 2, j + 3); - auto scale = wj.abs().mean(DIM2) + std::numeric_limits::min(); - scale = scale.unsqueeze(DIM2); - wj /= scale; - - wl_.narrow(DIM2, j + 1, 1) = - interp1.right(wj, "nkji,j->nki").unsqueeze(DIM2); - wl_.narrow(DIM2, j + 1, 1) *= scale; - - wr_.narrow(DIM2, j, 1) = interp1.left(wj, "nkji,j->nki").unsqueeze(DIM2); - wr_.narrow(DIM2, j, 1) *= scale; - - wj *= scale; - } - - if (nweno == NHYDRO) return; - - // rest of the hydro variables - w_ = w.slice(DIMC, nweno, NHYDRO); - wl_ = wl.slice(DIMC, nweno, NHYDRO); - wr_ = wr.slice(DIMC, nweno, NHYDRO); - - for (int j = jl; j <= ju; ++j) { - auto wj = w_.slice(DIM2, j - 2, j + 3); - wl_.narrow(DIM2, j + 1, 1) = - interp2.right(wj, "nkji,j->nki").unsqueeze(DIM2); - wr_.narrow(DIM2, j, 1) = interp2.left(wj, "nkji,j->nki").unsqueeze(DIM2); - } -} - -//---------------------------------------------------------------------------------------- -//! \fn Reconstruction::Weno5X3() -// \brief - -void Reconstruction::Weno5X3(int kl, int ku, const Tensor &w, Tensor &wl, - Tensor &wr) { - int64_t nweno = shock_capture_flag_ ? NHYDRO : IVX; - Weno5Interp interp1(w.device().type()); - Center5Interp interp2(w.device().type()); - - auto w_ = w.slice(DIMC, 0, nweno); - auto wl_ = wl.slice(DIMC, 0, nweno); - auto wr_ = wr.slice(DIMC, 0, nweno); - - for (int k = kl; k <= ku; ++k) { - auto wk = w_.slice(DIM3, k - 2, k + 3); - auto scale = wk.abs().mean(DIM3) + std::numeric_limits::min(); - scale = scale.unsqueeze(DIM3); - wk /= scale; - - wl_.narrow(DIM3, k + 1, 1) = - interp1.right(wk, "nkji,k->nji").unsqueeze(DIM3); - wr_.narrow(DIM3, k + 1, 1) *= scale; - - wr_.narrow(DIM3, k, 1) = interp1.left(wk, "nkji,k->nji").unsqueeze(DIM3); - wr_.narrow(DIM3, k, 1) *= scale; - - wk *= scale; - } - - if (nweno == NHYDRO) return; - - // rest of the hydro variables - w_ = w.slice(DIMC, nweno, NHYDRO); - wl_ = wl.slice(DIMC, nweno, NHYDRO); - wr_ = wr.slice(DIMC, nweno, NHYDRO); - - for (int k = kl; k <= ku; ++k) { - auto wk = w_.slice(DIM3, k - 2, k + 3); - wl_.narrow(DIM3, k + 1, 1) = - interp2.right(wk, "nkji,k->nji").unsqueeze(DIM3); - wr_.narrow(DIM3, k, 1) = interp2.left(wk, "nkji,k->nji").unsqueeze(DIM3); - } -}*/ diff --git a/src/torch/riemann/riemann.cpp b/src/torch/riemann/riemann.cpp deleted file mode 100644 index f0a9ab30..00000000 --- a/src/torch/riemann/riemann.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// torch -#include - -// snap -#include "riemann.hpp" - -namespace canoe::riemann { - -//! \todo Implement this function. -void _prim2local_inplace(int64_t ivx, torch::Tensor const& w, - torch::TensorList cos_theta) {} - -//! \todo Implement this function. -void _flux2global_inplace(int64_t ivx, torch::Tensor const& w, - torch::TensorList cos_theta) {} - -} // namespace canoe::riemann diff --git a/src/torch/riemann/riemann.hpp b/src/torch/riemann/riemann.hpp deleted file mode 100644 index 6d5a6400..00000000 --- a/src/torch/riemann/riemann.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -// C/C++ -#include - -namespace c10 { -template -class ArrayRef; -} // namespace c10 - -namespace at { -class Tensor; -} // namespace at - -namespace torch { -using Tensor = at::Tensor; -using TensorList = c10::ArrayRef; -} // namespace torch - -namespace canoe { -namespace riemann { -void _prim2local_inplace(int64_t ivx, torch::Tensor const &w, - torch::TensorList cos_theta); -void _flux2global_inplace(int64_t ivx, torch::Tensor const &w, - torch::TensorList cos_theta); -} // namespace riemann - -torch::Tensor rs_hydro_lmars( - int64_t dim, const torch::Tensor &wl, const torch::Tensor &wr, - const torch::Tensor &gammad, - std::optional rmu = std::nullopt, - std::optional rcv = std::nullopt, int64_t ncloud = 0, - std::optional cos_theta = std::nullopt); -} // namespace canoe diff --git a/src/torch/riemann/rs_hydro_lmars.cpp b/src/torch/riemann/rs_hydro_lmars.cpp deleted file mode 100644 index ff2a5ee0..00000000 --- a/src/torch/riemann/rs_hydro_lmars.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// torch -#include - -// snap -#include "riemann.hpp" - -#define sqr(x) ((x) * (x)) - -enum { - DIMC = 0, - IDN = 0, -}; - -namespace canoe { -using namespace riemann; - -torch::Tensor rs_hydro_lmars(int64_t dim, const torch::Tensor &wl, - const torch::Tensor &wr, - const torch::Tensor &gammad, - std::optional rmu, - std::optional rcv, int64_t ncloud, - std::optional cos_theta) { - auto IVX = wl.size(DIMC) - 4; - auto IPR = IVX + 3; // pressure index - - // dim, ivx - // 3, IVX - // 2, IVX + 1 - // 1, IVX + 2 - auto ivx = IPR - dim; - auto ivy = IVX + ((ivx - IVX) + 1) % 3; - auto ivz = IVX + ((ivx - IVX) + 2) % 3; - - auto fepsl = torch::ones_like(wl[0]); - auto fepsr = torch::ones_like(wr[0]); - - if (rmu.has_value()) { - auto wlu = - wl.slice(DIMC, 1, IVX - ncloud).unfold(DIMC, IVX - ncloud - 1, 1); - fepsl += torch::matmul(wlu, rmu.value().slice(DIMC, 0, IVX - ncloud - 1)) - .squeeze(DIMC) - - wl.slice(DIMC, IVX - ncloud, IVX).sum(DIMC); - - auto wru = - wr.slice(DIMC, 1, IVX - ncloud).unfold(DIMC, IVX - ncloud - 1, 1); - fepsr += torch::matmul(wru, rmu.value().slice(DIMC, 0, IVX - ncloud - 1)) - .squeeze(DIMC) - - wr.slice(DIMC, IVX - ncloud, IVX).sum(DIMC); - } - - auto fsigl = torch::ones_like(wl[0]); - auto fsigr = torch::ones_like(wr[0]); - - if (rcv.has_value()) { - auto wlu = wl.slice(DIMC, 1, IVX).unfold(DIMC, IVX - 1, 1); - fsigl += torch::matmul(wlu, rcv.value()).squeeze(DIMC); - - auto wru = wr.slice(DIMC, 1, IVX).unfold(DIMC, IVX - 1, 1); - fsigr += torch::matmul(wru, rcv.value()).squeeze(DIMC); - } - - auto kappal = 1.f / (gammad - 1.f) * fsigl / fepsl; - auto kappar = 1.f / (gammad - 1.f) * fsigr / fepsr; - - if (cos_theta.has_value()) { // velocities are at an angle - _prim2local_inplace(ivx, wl, cos_theta.value()); - } - - auto kel = 0.5 * (sqr(wl[ivx]) + sqr(wl[ivy]) + sqr(wl[ivz])); - auto ker = 0.5 * (sqr(wr[ivx]) + sqr(wr[ivy]) + sqr(wr[ivz])); - - // enthalpy - auto hl = wl[IPR] / wl[IDN] * (kappal + 1.) + kel; - auto hr = wr[IPR] / wr[IDN] * (kappar + 1.) + ker; - - auto rhobar = 0.5 * (wl[IDN] + wr[IDN]); - auto cbar = sqrt(0.5 * (1. + (1. / kappar + 1. / kappal) / 2.) * - (wl[IPR] + wr[IPR]) / rhobar); - auto pbar = - 0.5 * (wl[IPR] + wr[IPR]) + 0.5 * (rhobar * cbar) * (wl[ivx] - wr[ivx]); - auto ubar = - 0.5 * (wl[ivx] + wr[ivx]) + 0.5 / (rhobar * cbar) * (wl[IPR] - wr[IPR]); - - // left/right flux - auto fluxl = torch::zeros_like(wl); - auto fluxr = torch::zeros_like(wr); - - fluxl[IDN] = ubar * wl[IDN] * - (torch::ones_like(wl[IDN]) - wl.slice(DIMC, 1, IVX).sum(DIMC)); - fluxl.slice(DIMC, 1, IVX) = ubar * wl[IDN] * wl.slice(DIMC, 1, IVX); - - fluxl[ivx] = ubar * wl[IDN] * wl[ivx] + pbar; - fluxl[ivy] = ubar * wl[IDN] * wl[ivy]; - fluxl[ivz] = ubar * wl[IDN] * wl[ivz]; - fluxl[IPR] = ubar * wl[IDN] * hl; - - fluxr[IDN] = ubar * wr[IDN] * - (torch::ones_like(wr[IDN]) - wr.slice(DIMC, 1, IVX).sum(DIMC)); - fluxr.slice(DIMC, 1, IVX) = ubar * wr[IDN] * wr.slice(DIMC, 1, IVX); - - fluxr[ivx] = ubar * wr[IDN] * wr[ivx] + pbar; - fluxr[ivy] = ubar * wr[IDN] * wr[ivy]; - fluxr[ivz] = ubar * wr[IDN] * wr[ivz]; - fluxr[IPR] = ubar * wr[IDN] * hr; - - auto ui = (ubar > 0).to(torch::kInt); - auto flx = ui * fluxl + (1 - ui) * fluxr; - - if (cos_theta.has_value()) { // velocities are at an angle - _flux2global_inplace(ivx, flx, cos_theta.value()); - } - - return flx; -} -} // namespace canoe diff --git a/tests/test_cs_velocity_rotation.cpp b/tests/test_cs_velocity_rotation.cpp index e0536841..7b57bf71 100644 --- a/tests/test_cs_velocity_rotation.cpp +++ b/tests/test_cs_velocity_rotation.cpp @@ -15,326 +15,326 @@ #include TEST(vel_zab_to_zxy, test_ab_to_xy_to_ab) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zxy_to_zab(vz, vx, vy, PI/3, PI/4); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zxy_to_zab(vz, vx, vy, PI / 3, PI / 4); std::cout << *vz << " " << *vx << " " << *vy; - CubedSphereUtility::vel_zab_to_zxy(vz, vx, vy, PI/3, PI/4); + cs::vel_zab_to_zxy(vz, vx, vy, PI / 3, PI / 4); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_1_to_2_to_1) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 2); - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 1); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_1_to_3_to_1) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 3); - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 1); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_1_to_4_to_1) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 4); - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 1); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_1_to_6_to_1) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 6); - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 1); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_2_to_1_to_2) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 1); - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 2); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_2_to_3_to_2) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 3); - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 2); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_2_to_4_to_2) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 4); - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 2); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_2_to_5_to_2) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 5); - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 2); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_3_to_1_to_3) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 1); - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 3); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_3_to_2_to_3) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 2); - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 3); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_3_to_5_to_3) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 5); - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 3); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_3_to_6_to_3) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 6); - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 3); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_4_to_2_to_4) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 2); - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 4); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_4_to_1_to_4) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 1); - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 4); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_4_to_5_to_4) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 5); - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 4); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_4_to_6_to_4) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 6); - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 4); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_5_to_2_to_5) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 2); - CubedSphereUtility::vel_zab_from_p2(vz, vx, vy, PI/5*2, PI/8*3, 5); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 2); + cs::vel_zab_from_p2(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_5_to_3_to_5) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 3); - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 5); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_5_to_4_to_5) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 4); - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 5); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_5_to_6_to_5) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 6); - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 5); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_6_to_1_to_6) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 1); - CubedSphereUtility::vel_zab_from_p1(vz, vx, vy, PI/5*2, PI/8*3, 6); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 1); + cs::vel_zab_from_p1(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_6_to_3_to_6) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 3); - CubedSphereUtility::vel_zab_from_p3(vz, vx, vy, PI/5*2, PI/8*3, 6); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 3); + cs::vel_zab_from_p3(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_6_to_4_to_6) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 4); - CubedSphereUtility::vel_zab_from_p4(vz, vx, vy, PI/5*2, PI/8*3, 6); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 4); + cs::vel_zab_from_p4(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } } TEST(vel_zab_from_test, test_case_6_to_5_to_6) { - Real result[3] = {1,2,3}; + Real result[3] = {1, 2, 3}; Real *vz = result; Real *vx = result + 1; Real *vy = result + 2; - Real expected_result[3] = {1,2,3}; - CubedSphereUtility::vel_zab_from_p6(vz, vx, vy, PI/5*2, PI/8*3, 5); - CubedSphereUtility::vel_zab_from_p5(vz, vx, vy, PI/5*2, PI/8*3, 6); + Real expected_result[3] = {1, 2, 3}; + cs::vel_zab_from_p6(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 5); + cs::vel_zab_from_p5(vz, vx, vy, PI / 5 * 2, PI / 8 * 3, 6); for (int i = 0; i < 3; i++) { EXPECT_NEAR(result[i], expected_result[i], 1e-5); } @@ -343,4 +343,4 @@ TEST(vel_zab_from_test, test_case_6_to_5_to_6) { int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} \ No newline at end of file +} From 7c6dd91936b725729e540f6cbd8761f40b162e3b Mon Sep 17 00:00:00 2001 From: mac/cli Date: Mon, 2 Jun 2025 23:56:25 -0500 Subject: [PATCH 2/4] wip --- CMakeLists.txt | 19 +++++++++++++++++++ cmake/compilers.cmake | 7 ------- examples/2019-Li-snap/CMakeLists.txt | 2 +- examples/2023-Chen-exo3/CMakeLists.txt | 2 +- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb7b0a76..f18f3918 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,25 @@ project(canoe # search for _ROOT cmake_policy(SET CMP0074 NEW) +find_program(Python3_EXECUTABLE NAMES python) +find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module) +execute_process( + COMMAND ${Python3_EXECUTABLE} -c "import torch; print(int(torch._C._GLIBCXX_USE_CXX11_ABI))" + RESULT_VARIABLE _ABI_RESULT + OUTPUT_VARIABLE _ABI_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(NOT _ABI_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to detect Torch GLIBCXX ABI") +endif() + +# Set the _GLIBCXX_USE_CXX11_ABI flag +add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=${_ABI_OUTPUT}) + +# Set MacOS deployment target +set(CMAKE_OSX_DEPLOYMENT_TARGET "15.0") + string(ASCII 27 Esc) set(ColorReset "${Esc}[m") set(Green "${Esc}[32m") diff --git a/cmake/compilers.cmake b/cmake/compilers.cmake index ed34255f..0f1a0988 100644 --- a/cmake/compilers.cmake +++ b/cmake/compilers.cmake @@ -16,12 +16,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(CMAKE_CXX_FLAGS_DEBUG "-g3") set(CMAKE_C_FLAGS_DEBUG "-g3") - set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} -D_GLIBCXX_USE_CXX11_ABI=0") - set(CMAKE_CXX_FLAGS_DEBUG - "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_USE_CXX11_ABI=0") - - # set(CMAKE_Fortran_FLAGS_RELEASE "-O3" ) set(KNOWN_COMPILER TRUE) endif() @@ -32,7 +26,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS_DEBUG "-g3") set(CMAKE_C_FLAGS_DEBUG "-g3") - # set(CMAKE_Fortran_FLAGS_RELEASE "-O3" ) set(KNOWN_COMPILER TRUE) endif() diff --git a/examples/2019-Li-snap/CMakeLists.txt b/examples/2019-Li-snap/CMakeLists.txt index 086cd7cb..ab0458b4 100644 --- a/examples/2019-Li-snap/CMakeLists.txt +++ b/examples/2019-Li-snap/CMakeLists.txt @@ -16,5 +16,5 @@ endif() # 4. Copy input files to run directory file(GLOB inputs *.inp *.yaml) foreach(input ${inputs}) - execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/${input}) + execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/) endforeach() diff --git a/examples/2023-Chen-exo3/CMakeLists.txt b/examples/2023-Chen-exo3/CMakeLists.txt index 04047f58..ff3202ca 100644 --- a/examples/2023-Chen-exo3/CMakeLists.txt +++ b/examples/2023-Chen-exo3/CMakeLists.txt @@ -21,5 +21,5 @@ endif() # 2. Copy input file to run directory file(GLOB inputs *.inp *.dat *.yaml) foreach(input ${inputs}) - execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/${input}) + execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/) endforeach() From d07c2cb01cd1aa7e89fcb2603710977042ab1283 Mon Sep 17 00:00:00 2001 From: mac/cli Date: Tue, 3 Jun 2025 00:21:44 -0500 Subject: [PATCH 3/4] wip --- examples/2023-Chen-exo3/hot_jupiter.inp | 2 ++ examples/2023-Chen-exo3/hs94.inp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/2023-Chen-exo3/hot_jupiter.inp b/examples/2023-Chen-exo3/hot_jupiter.inp index d22220aa..b5de0da3 100644 --- a/examples/2023-Chen-exo3/hot_jupiter.inp +++ b/examples/2023-Chen-exo3/hot_jupiter.inp @@ -64,6 +64,8 @@ gamma = 1.4 # gamma = C_p/C_v implicit_flag = 1 +thermodynamics_config = hot-jupiter.yaml + Rd = 3779. # Gas constant dT_e2p = 300. # Temperature contrast from equator to pole, K dT_stra = 10. # Temperature contrast, K diff --git a/examples/2023-Chen-exo3/hs94.inp b/examples/2023-Chen-exo3/hs94.inp index a72e985a..54f49035 100644 --- a/examples/2023-Chen-exo3/hs94.inp +++ b/examples/2023-Chen-exo3/hs94.inp @@ -66,6 +66,8 @@ implicit_flag = 1 +thermodynamics_config = earth-dry.yaml + dT = 60. # horizontal temperature difference dtheta = 10. # vertical potential temperature difference Rd = 287. From 86901ac8336534e5b53f679a0c632aa92c8839a7 Mon Sep 17 00:00:00 2001 From: mac/cli Date: Tue, 3 Jun 2025 00:23:43 -0500 Subject: [PATCH 4/4] wip --- examples/2023-Chen-exo3/hot_jupiter.inp | 4 ++-- examples/2023-Chen-exo3/hs94.inp | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/2023-Chen-exo3/hot_jupiter.inp b/examples/2023-Chen-exo3/hot_jupiter.inp index b5de0da3..2bcac0d3 100644 --- a/examples/2023-Chen-exo3/hot_jupiter.inp +++ b/examples/2023-Chen-exo3/hot_jupiter.inp @@ -64,8 +64,6 @@ gamma = 1.4 # gamma = C_p/C_v implicit_flag = 1 -thermodynamics_config = hot-jupiter.yaml - Rd = 3779. # Gas constant dT_e2p = 300. # Temperature contrast from equator to pole, K dT_stra = 10. # Temperature contrast, K @@ -73,6 +71,8 @@ z_stra = 2.E6 # Stratosphere height, m Gamma_trop = 2.E-4 # Lapse rate, K/m +thermodynamics_config = hot-jupiter.yaml + Kt = 1.5E5 # Damping timescale, s Ts = 1600. # Surface temperature, K p0 = 1.E5 # Surface pressure, Pa diff --git a/examples/2023-Chen-exo3/hs94.inp b/examples/2023-Chen-exo3/hs94.inp index 54f49035..46094760 100644 --- a/examples/2023-Chen-exo3/hs94.inp +++ b/examples/2023-Chen-exo3/hs94.inp @@ -64,16 +64,15 @@ gamma = 1.4 # gamma = C_p/C_v grav_acc1 = -9.81 # gravity accelaration implicit_flag = 1 - -thermodynamics_config = earth-dry.yaml - dT = 60. # horizontal temperature difference dtheta = 10. # vertical potential temperature difference Rd = 287. cp = 1004. +thermodynamics_config = earth-dry.yaml + Omega = 7.292E-5 Rp = 6.371E6 p0 = 1.E5 # surface pressure