diff --git a/README.md b/README.md index f8e5711..0eb9112 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Currently, the following functions are available in the `pyrte_rrtmgp` package: | **OPTICAL PROPS - INCREMENT BYBND** | | | `rte_inc_1scalar_by_1scalar_bybnd` | ✅ | | `rte_inc_1scalar_by_2stream_bybnd` | ✅ | -| `rte_inc_1scalar_by_nstream_bybnd` | 🔲 | +| `rte_inc_1scalar_by_nstream_bybnd` | ✅ | | `rte_inc_2stream_by_1scalar_bybnd` | ✅ | | `rte_inc_2stream_by_2stream_bybnd` | ✅ | | `rte_inc_2stream_by_nstream_bybnd` | ✅ | diff --git a/pybind_interface.cpp b/pybind_interface.cpp index fb663e0..5d07476 100644 --- a/pybind_interface.cpp +++ b/pybind_interface.cpp @@ -298,16 +298,16 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t tau_inout, py::array_t tau_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); + } + if (tau_inout.size() != ncol * nlay * ngpt || tau_in.size() != ncol * nlay * ngpt ) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); @@ -328,6 +328,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t tau_in, py::array_t ssa_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (tau_in.size() != ncol * nlay * ngpt) || @@ -336,10 +340,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); py::buffer_info buf_ssa_in = ssa_in.request(); @@ -362,6 +362,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t tau_in, py::array_t ssa_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (tau_in.size() != ncol * nlay * ngpt) || @@ -370,10 +374,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); py::buffer_info buf_ssa_in = ssa_in.request(); @@ -396,6 +396,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t ssa_inout, py::array_t tau_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -404,10 +408,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); @@ -433,6 +433,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t ssa_in, py::array_t g_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -444,10 +448,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_g_inout = g_inout.request(); @@ -480,6 +480,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t ssa_in, py::array_t p_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom <= 0) { + throw std::runtime_error("ncol, nlay, ngpt and nmom must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -491,10 +495,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom <= 0) { - throw std::runtime_error("ncol, nlay, ngpt and nmom must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_g_inout = g_inout.request(); @@ -524,6 +524,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t ssa_inout, py::array_t tau_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay and ngpt must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -532,10 +536,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay, and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); @@ -562,6 +562,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t ssa_in, py::array_t g_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0) { + throw std::runtime_error("ncol, nlay, ngpt and nmom1 must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -573,10 +577,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0) { - throw std::runtime_error("ncol, nlay, ngpt and nmom1 must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_p_inout = p_inout.request(); @@ -611,6 +611,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t ssa_in, py::array_t p_in ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0 || nmom2 <= 0) { + throw std::runtime_error("ncol, nlay, ngpt, nmom1 and nmom2 must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -622,10 +626,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0 || nmom2 <= 0) { - throw std::runtime_error("ncol, nlay, ngpt, nmom1 and nmom2 must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_p_inout = p_inout.request(); @@ -657,6 +657,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (tau_in.size() != ncol * nlay * nbnd) || @@ -665,10 +669,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); py::buffer_info buf_band_lims_gpoint = band_lims_gpoint.request(); @@ -694,6 +694,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (tau_in.size() != ncol * nlay * nbnd) || @@ -703,10 +707,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); py::buffer_info buf_ssa_in = ssa_in.request(); @@ -723,37 +723,45 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { reinterpret_cast(buf_band_lims_gpoint.ptr)); }); - // m.def("rte_inc_1scalar_by_nstream_bybnd", - // []( - // int ncol, - // int nlay, - // int ngpt, - // py::array_t tau_inout, - // int nbnd, - // py::array_t band_lims_gpoint - // ) { - // if ( - // (tau_inout.size() != ncol * nlay * ngpt) || - // (band_lims_gpoint.size() != 2 * nbnd) - // ) { - // throw std::runtime_error("Invalid size for input arrays"); - // } - - // if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { - // throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); - // } - - // py::buffer_info buf_tau_inout = tau_inout.request(); - // py::buffer_info buf_band_lims_gpoint = band_lims_gpoint.request(); - - // fortran::rte_inc_1scalar_by_nstream_bybnd( - // ncol, - // nlay, - // ngpt, - // reinterpret_cast(buf_tau_inout.ptr), - // nbnd, - // reinterpret_cast(buf_band_lims_gpoint.ptr)); - // }); + m.def("rte_inc_1scalar_by_nstream_bybnd", + []( + int ncol, + int nlay, + int ngpt, + py::array_t tau_inout, + py::array_t tau_in, + py::array_t ssa_in, + int nbnd, + py::array_t band_lims_gpoint + ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); + } + + if ( + (tau_inout.size() != ncol * nlay * ngpt) || + (tau_in.size() != ncol * nlay * ngpt) || + (ssa_in.size() != ncol * nlay * ngpt) || + (band_lims_gpoint.size() != 2 * nbnd) + ) { + throw std::runtime_error("Invalid size for input arrays"); + } + + py::buffer_info buf_tau_inout = tau_inout.request(); + py::buffer_info buf_tau_in = tau_in.request(); + py::buffer_info buf_ssa_in = ssa_in.request(); + py::buffer_info buf_band_lims_gpoint = band_lims_gpoint.request(); + + fortran::rte_inc_1scalar_by_nstream_bybnd( + ncol, + nlay, + ngpt, + reinterpret_cast(buf_tau_inout.ptr), + reinterpret_cast(buf_tau_in.ptr), + reinterpret_cast(buf_ssa_in.ptr), + nbnd, + reinterpret_cast(buf_band_lims_gpoint.ptr)); + }); m.def("rte_inc_2stream_by_1scalar_bybnd", []( @@ -766,6 +774,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -775,10 +787,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); @@ -809,6 +817,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -821,10 +833,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_g_inout = g_inout.request(); @@ -862,6 +870,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom < 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt, nmom and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -874,10 +886,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom < 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt, nmom and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_g_inout = g_inout.request(); @@ -912,6 +920,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -921,10 +933,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_tau_in = tau_in.request(); @@ -956,6 +964,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt, nmom1 and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -968,10 +980,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt, nmom1 and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_p_inout = p_inout.request(); @@ -1011,6 +1019,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int nbnd, py::array_t band_lims_gpoint ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0 || nmom2 < 0 || nbnd < 0) { + throw std::runtime_error("ncol, nlay, ngpt, nmom1, nmom2 and nbnd must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -1023,10 +1035,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom1 <= 0 || nmom2 < 0 || nbnd < 0) { - throw std::runtime_error("ncol, nlay, ngpt, nmom1, nmom2 and nbnd must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_p_inout = p_inout.request(); @@ -1060,6 +1068,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t ssa_inout, py::array_t g_inout ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay and ngpt must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -1068,10 +1080,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_g_inout = g_inout.request(); @@ -1095,6 +1103,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t g_inout, py::array_t f ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlay and ngpt must be positive integers"); + } + if ( (tau_inout.size() != ncol * nlay * ngpt) || (ssa_inout.size() != ncol * nlay * ngpt) || @@ -1104,10 +1116,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlay and ngpt must be positive integers"); - } - py::buffer_info buf_tau_inout = tau_inout.request(); py::buffer_info buf_ssa_inout = ssa_inout.request(); py::buffer_info buf_g_inout = g_inout.request(); @@ -1133,6 +1141,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int ncol_end, py::array_t array_out ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || ncol_start < 0 || ncol_end < 0) { + throw std::runtime_error("ncol, nlay, ngpt, ncol_start and ncol_end must be positive integers"); + } + if ( (array_in.size() != ncol * nlay * ngpt) || (array_out.size() != (ncol_end - ncol_start + 1) * nlay * ngpt) @@ -1140,10 +1152,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || ncol_start < 0 || ncol_end < 0) { - throw std::runtime_error("ncol, nlay, ngpt, ncol_start and ncol_end must be positive integers"); - } - py::buffer_info buf_array_in = array_in.request(); py::buffer_info buf_array_out = array_out.request(); @@ -1168,6 +1176,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int ncol_end, py::array_t array_out ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom <= 0 || ncol_start < 0 || ncol_end < 0) { + throw std::runtime_error("ncol, nlay, ngpt, nmom, ncol_start and ncol_end must be positive integers"); + } + if ( (array_in.size() != nmom * ncol * nlay * ngpt) || (array_out.size() != nmom * (ncol_end - ncol_start + 1) * nlay * ngpt) @@ -1175,10 +1187,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || nmom <= 0 || ncol_start < 0 || ncol_end < 0) { - throw std::runtime_error("ncol, nlay, ngpt, nmom, ncol_start and ncol_end must be positive integers"); - } - py::buffer_info buf_array_in = array_in.request(); py::buffer_info buf_array_out = array_out.request(); @@ -1204,6 +1212,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { int ncol_end, py::array_t tau_out ) { + if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || ncol_start < 0 || ncol_end < 0) { + throw std::runtime_error("ncol, nlay, ngpt, ncol_start and ncol_end must be positive integers"); + } + if ( (tau_in.size() != ncol * nlay * ngpt) || (ssa_in.size() != ncol * nlay * ngpt) || @@ -1212,10 +1224,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlay <= 0 || ngpt <= 0 || ncol_start < 0 || ncol_end < 0) { - throw std::runtime_error("ncol, nlay, ngpt, ncol_start and ncol_end must be positive integers"); - } - py::buffer_info buf_tau_in = tau_in.request(); py::buffer_info buf_ssa_in = ssa_in.request(); py::buffer_info buf_tau_out = tau_out.request(); @@ -1239,6 +1247,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t gpt_flux, py::array_t flux ) { + if (ncol <= 0 || nlev <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlev and ngpt must be positive integers"); + } + if ( (gpt_flux.size() != ncol * nlev * ngpt) || (flux.size() != ncol * nlev) @@ -1246,10 +1258,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlev <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlev and ngpt must be positive integers"); - } - py::buffer_info buf_gpt_flux = gpt_flux.request(); py::buffer_info buf_flux = flux.request(); @@ -1270,6 +1278,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t gpt_flux_up, py::array_t flux_net ) { + if (ncol <= 0 || nlev <= 0 || ngpt <= 0) { + throw std::runtime_error("ncol, nlev and ngpt must be positive integers"); + } + if ( (gpt_flux_dn.size() != ncol * nlev * ngpt) || (gpt_flux_up.size() != ncol * nlev * ngpt) || @@ -1278,10 +1290,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlev <= 0 || ngpt <= 0) { - throw std::runtime_error("ncol, nlev and ngpt must be positive integers"); - } - py::buffer_info buf_gpt_flux_dn = gpt_flux_dn.request(); py::buffer_info buf_gpt_flux_up = gpt_flux_up.request(); py::buffer_info buf_flux_net = flux_net.request(); @@ -1303,6 +1311,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t broadband_flux_up, py::array_t broadband_flux_net ) { + if (ncol <= 0 || nlev <= 0) { + throw std::runtime_error("ncol and nlev must be positive integers"); + } + if ( (broadband_flux_dn.size() != ncol * nlev) || (broadband_flux_up.size() != ncol * nlev) || @@ -1311,10 +1323,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlev <= 0) { - throw std::runtime_error("ncol and nlev must be positive integers"); - } - py::buffer_info buf_broadband_flux_dn = broadband_flux_dn.request(); py::buffer_info buf_broadband_flux_up = broadband_flux_up.request(); py::buffer_info buf_broadband_flux_net = broadband_flux_net.request(); @@ -1340,6 +1348,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t gpt_flux, py::array_t bnd_flux ) { + if (ncol <= 0 || nlev <= 0 || ngpt <= 0 || nbnd <= 0) { + throw std::runtime_error("ncol, nlev, ngpt and nbnd must be positive integers"); + } + if ( (band_lims.size() != 2 * nbnd) || (gpt_flux.size() != ncol * nlev * ngpt) @@ -1347,10 +1359,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlev <= 0 || ngpt <= 0 || nbnd <= 0) { - throw std::runtime_error("ncol, nlev, ngpt and nbnd must be positive integers"); - } - py::buffer_info buf_band_lims = band_lims.request(); py::buffer_info buf_gpt_flux = gpt_flux.request(); py::buffer_info buf_bnd_flux = bnd_flux.request(); @@ -1376,6 +1384,10 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { py::array_t bnd_flux_up, py::array_t bnd_flux_net ) { + if (ncol <= 0 || nlev <= 0 || ngpt <= 0 || nbnd <= 0) { + throw std::runtime_error("ncol, nlev, ngpt, nbnd and band_lims must be positive integers"); + } + if ( (band_lims.size() != 2 * nbnd) || (bnd_flux_dn.size() != ncol * nlev * nbnd) || @@ -1385,10 +1397,6 @@ PYBIND11_MODULE(pyrte_rrtmgp, m) { throw std::runtime_error("Invalid size for input arrays"); } - if (ncol <= 0 || nlev <= 0 || ngpt <= 0 || nbnd <= 0) { - throw std::runtime_error("ncol, nlev, ngpt, nbnd and band_lims must be positive integers"); - } - py::buffer_info buf_band_lims = band_lims.request(); py::buffer_info buf_bnd_flux_dn = bnd_flux_dn.request(); py::buffer_info buf_bnd_flux_up = bnd_flux_up.request(); diff --git a/rte-rrtmgp b/rte-rrtmgp index 5c0559a..8a955cb 160000 --- a/rte-rrtmgp +++ b/rte-rrtmgp @@ -1 +1 @@ -Subproject commit 5c0559a11497b7d5b8266a21711817454858875e +Subproject commit 8a955cbf8d8cd2d08d81019d6ccd7d55bc50f5ec diff --git a/tests/lw_solver_test/2stream_test/lw_2stream_test_data.zip b/tests/lw_solver_test/2stream_test/lw_2stream_test_data.zip new file mode 100644 index 0000000..21b5b74 Binary files /dev/null and b/tests/lw_solver_test/2stream_test/lw_2stream_test_data.zip differ diff --git a/tests/lw_solver_test/2stream_test/lw_solver_2stream_test.py b/tests/lw_solver_test/2stream_test/lw_solver_2stream_test.py new file mode 100644 index 0000000..03ecede --- /dev/null +++ b/tests/lw_solver_test/2stream_test/lw_solver_2stream_test.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +import json +import zipfile +import numpy as np +import pyrte_rrtmgp.pyrte_rrtmgp as py +import os + +def test_lw_solver(request): + path = os.path.dirname(request.path) + + # Unzip data + input_data = None + output_data = None + with zipfile.ZipFile(f'{path}/lw_2stream_test_data.zip') as myzip: + with myzip.open('lw_2stream_input.json') as input_data_file: + input_data = json.load(input_data_file) + with myzip.open('lw_2stream_output.json') as output_data_file: + output_data = json.load(output_data_file) + + assert input_data is not None and output_data is not None + + for key in input_data: + values = input_data[key] + if isinstance(values, list): + values = np.array(values) + input_data[key] = values + + args = list(input_data.values()) + + py.rte_lw_solver_2stream(*args) + + for key in output_data: + assert(np.allclose(output_data[key] - input_data[key], 0.)) \ No newline at end of file diff --git a/tests/lw_solver_test/lw_solver_noscat_parser.py b/tests/lw_solver_test/lw_solver_noscat_parser.py deleted file mode 100644 index f7beb2c..0000000 --- a/tests/lw_solver_test/lw_solver_noscat_parser.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -import json - -# This is the code that was used to save the output of the lw_solver_noscat function, you can use it as reference for other functions -# open(1, file = 'asd/asd/asd/fortran_data.txt', status = 'new') - -# ! Write data to the file -# write(1, *) 'ncol: ', ncol -# write(1, *) 'nlay: ', nlay -# write(1, *) 'ngpt: ', ngpt -# write(1, *) 'top_at_1: ', logical(top_at_1, wl) -# write(1, *) 'nmus: ', n_quad_angs -# write(1, *) 'Ds: ', secants -# write(1, *) 'weights: ', gauss_wts(1:n_quad_angs,n_quad_angs) -# write(1, *) 'tau: ', optical_props%tau -# write(1, *) 'lay_source: ', sources%lay_source -# write(1, *) 'lev_source: ', sources%lev_source -# write(1, *) 'sfc_emis: ', sfc_emis_gpt -# write(1, *) 'sfc_src: ', sources%sfc_source -# write(1, *) 'inc_flux: ', inc_flux_diffuse -# write(1, *) 'flux_up: ', gpt_flux_up -# write(1, *) 'flux_dn: ', gpt_flux_dn -# write(1, *) 'do_broadband: ', do_broadband -# write(1, *) 'broadband_up: ', flux_up_loc -# write(1, *) 'broadband_dn: ', flux_dn_loc -# write(1, *) 'do_Jacobians: ', logical(do_Jacobians, wl) -# write(1, *) 'sfc_srcJac: ', sources%sfc_source_Jac -# write(1, *) 'flux_upJac: ', jacobian -# write(1, *) 'do_rescaling: ', logical(.false., wl) -# write(1, *) 'ssa: ', optical_props%tau -# write(1, *) 'g: ', optical_props%tau - -# ! Close the file -# close(1) - -def parse_value(value): - # Handle NaN - if 'NaN' in value: - res = float('nan') - # Handle bool - elif value in ['T', 'F']: - res = True if value == 'T' else False - # Handle float - elif "." in value: - res = float(value) - else: - try: - # Handle int - res = int(value) - except ValueError: - # Keeping as string if not an int - res = value - return res - -def load_data_from_file(file_path): - data = {} - with open(file_path, 'r') as file: - for line in file: - parts = line.split(':') - assert(len(parts) == 2) - key = parts[0].strip() - values = parts[1].strip().split() - if len(values) == 1: - data[key] = parse_value(values[0]) - else: - data[key] = [float(val) for val in values] - return data - -file_path = 'fortran_data.txt' -data = load_data_from_file(file_path) - -with open('lw_solver_input.json', 'w') as f: - json.dump(data, f) \ No newline at end of file diff --git a/tests/lw_solver_test/lw_solver_input.json b/tests/lw_solver_test/noscat_test/lw_solver_input.json similarity index 100% rename from tests/lw_solver_test/lw_solver_input.json rename to tests/lw_solver_test/noscat_test/lw_solver_input.json diff --git a/tests/lw_solver_test/lw_solver_noscat_test.py b/tests/lw_solver_test/noscat_test/lw_solver_noscat_test.py similarity index 100% rename from tests/lw_solver_test/lw_solver_noscat_test.py rename to tests/lw_solver_test/noscat_test/lw_solver_noscat_test.py diff --git a/tests/lw_solver_test/lw_solver_output.npy b/tests/lw_solver_test/noscat_test/lw_solver_output.npy similarity index 100% rename from tests/lw_solver_test/lw_solver_output.npy rename to tests/lw_solver_test/noscat_test/lw_solver_output.npy diff --git a/tests/rrtmgp_compute_Planck_source_test/compute_Planck_source_test.py b/tests/rrtmgp_compute_Planck_source_test/compute_Planck_source_test.py new file mode 100644 index 0000000..bd36db1 --- /dev/null +++ b/tests/rrtmgp_compute_Planck_source_test/compute_Planck_source_test.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +import json +import numpy as np +import pyrte_rrtmgp.pyrte_rrtmgp as py +import os +import zipfile + +def test_rrtmgp_compute_Planck_source(request): + + path = os.path.dirname(request.path) + + input_data = None + output_data = None + with zipfile.ZipFile(f'{path}/compute_Planck_source_test_data.zip') as myzip: + with myzip.open('compute_Planck_source_input.json') as input_data_file: + input_data = json.load(input_data_file) + with myzip.open('compute_Planck_source_output.json') as output_data_file: + output_data = json.load(output_data_file) + + for key in input_data: + values = input_data[key] + if isinstance(values, list): + if isinstance(values[0], int): + values = np.array(values, dtype=np.int32) + else: + values = np.array(values, dtype=np.float64) + input_data[key] = values + + args = list(input_data.values()) + + py.rrtmgp_compute_Planck_source(*args) + + for key in output_data: + assert(np.allclose(output_data[key] - input_data[key], 0.)) \ No newline at end of file diff --git a/tests/rrtmgp_compute_Planck_source_test/compute_Planck_source_test_data.zip b/tests/rrtmgp_compute_Planck_source_test/compute_Planck_source_test_data.zip new file mode 100644 index 0000000..67a30db Binary files /dev/null and b/tests/rrtmgp_compute_Planck_source_test/compute_Planck_source_test_data.zip differ diff --git a/tests/rrtmgp_compute_tau_absorption_test/compute_tau_absorption_test.py b/tests/rrtmgp_compute_tau_absorption_test/compute_tau_absorption_test.py new file mode 100644 index 0000000..7b3e46e --- /dev/null +++ b/tests/rrtmgp_compute_tau_absorption_test/compute_tau_absorption_test.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +import json +import numpy as np +import pyrte_rrtmgp.pyrte_rrtmgp as py +import os +import zipfile + +def test_rrtmgp_compute_tau_absorption(request): + path = os.path.dirname(request.path) + + input_data = None + output_data = None + with zipfile.ZipFile(f'{path}/compute_tau_absorption_test_data.zip') as myzip: + with myzip.open('compute_tau_absorption_input.json') as input_data_file: + input_data = json.load(input_data_file) + with myzip.open('compute_tau_absorption_output.json') as output_data_file: + output_data = json.load(output_data_file) + + for key in input_data: + values = input_data[key] + if isinstance(values, list): + if isinstance(values[0], int): + values = np.array(values, dtype=np.int32) + else: + values = np.array(values, dtype=np.float64) + input_data[key] = values + + args = list(input_data.values()) + + py.rrtmgp_compute_tau_absorption(*args) + + for key in output_data: + assert(np.allclose(output_data[key] - input_data[key], 0.)) \ No newline at end of file diff --git a/tests/rrtmgp_compute_tau_absorption_test/compute_tau_absorption_test_data.zip b/tests/rrtmgp_compute_tau_absorption_test/compute_tau_absorption_test_data.zip new file mode 100644 index 0000000..031316d Binary files /dev/null and b/tests/rrtmgp_compute_tau_absorption_test/compute_tau_absorption_test_data.zip differ diff --git a/tests/rrtmgp_compute_tau_rayleigh_test/compute_tau_rayleigh_test_data.zip b/tests/rrtmgp_compute_tau_rayleigh_test/compute_tau_rayleigh_test_data.zip new file mode 100644 index 0000000..2ef4f16 Binary files /dev/null and b/tests/rrtmgp_compute_tau_rayleigh_test/compute_tau_rayleigh_test_data.zip differ diff --git a/tests/rrtmgp_compute_tau_rayleigh_test/rrtmgp_compute_tau_rayleigh_test.py b/tests/rrtmgp_compute_tau_rayleigh_test/rrtmgp_compute_tau_rayleigh_test.py new file mode 100644 index 0000000..69470bf --- /dev/null +++ b/tests/rrtmgp_compute_tau_rayleigh_test/rrtmgp_compute_tau_rayleigh_test.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +import json +import numpy as np +import pyrte_rrtmgp.pyrte_rrtmgp as py +import os +import zipfile + +def test_rrtmgp_compute_tau_rayleigh(request): + + path = os.path.dirname(request.path) + + input_data = None + output_data = None + with zipfile.ZipFile(f'{path}/compute_tau_rayleigh_test_data.zip') as myzip: + with myzip.open('compute_tau_rayleigh_input.json') as input_data_file: + input_data = json.load(input_data_file) + with myzip.open('compute_tau_rayleigh_output.json') as output_data_file: + output_data = json.load(output_data_file) + + for key in input_data: + values = input_data[key] + if isinstance(values, list): + if isinstance(values[0], int): + values = np.array(values, dtype=np.int32) + else: + values = np.array(values, dtype=np.float64) + input_data[key] = values + + args = list(input_data.values()) + + py.rrtmgp_compute_tau_rayleigh(*args) + + for key in output_data: + assert(np.allclose(output_data[key] - input_data[key], 0.)) \ No newline at end of file diff --git a/tests/rrtmgp_interpolation_test/interpolation_test.py b/tests/rrtmgp_interpolation_test/interpolation_test.py new file mode 100644 index 0000000..6934d23 --- /dev/null +++ b/tests/rrtmgp_interpolation_test/interpolation_test.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +import json +import numpy as np +import pyrte_rrtmgp.pyrte_rrtmgp as py +import os +import zipfile + +def load_json_file(file_path): + with open(file_path, 'r') as f: + return json.load(f) + +def test_rrtmgp_interpolation(request): + path = os.path.dirname(request.path) + + input_data = None + output_data = None + with zipfile.ZipFile(f'{path}/interpolation_test_data.zip') as myzip: + with myzip.open('input.json') as input_data_file: + input_data = json.load(input_data_file) + with myzip.open('output.json') as output_data_file: + output_data = json.load(output_data_file) + + assert input_data is not None and output_data is not None + + for key in input_data: + values = input_data[key] + if isinstance(values, list): + if isinstance(values[0], int): + values = np.array(values, dtype=np.int32) + else: + values = np.array(values, dtype=np.float64) + input_data[key] = values + + args = list(input_data.values()) + + py.rrtmgp_interpolation(*args) + + for key in output_data: + assert(np.allclose(output_data[key] - input_data[key], 0.)) \ No newline at end of file diff --git a/tests/rrtmgp_interpolation_test/interpolation_test_data.zip b/tests/rrtmgp_interpolation_test/interpolation_test_data.zip new file mode 100644 index 0000000..b044a49 Binary files /dev/null and b/tests/rrtmgp_interpolation_test/interpolation_test_data.zip differ diff --git a/tests/sw_solver_test/2stream_test/sw_2stream_input.json b/tests/sw_solver_test/2stream_test/sw_2stream_input.json new file mode 100644 index 0000000..224fe1e --- /dev/null +++ b/tests/sw_solver_test/2stream_test/sw_2stream_input.json @@ -0,0 +1 @@ +{"ncol": 8, "nlay": 16, "ngpt": 1, "top_at_1": true, "tau": [1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997, 1.7348265625000005e-06, 0.00017348265625000004, 1.7795312500000008e-06, 0.00017795312500000008, 3.6096390625000003e-06, 0.00036096390625, 3.63578125e-06, 0.00036357812499999997], "ssa": [0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227, 0.9996397334387714, 0.9996397334387714, 0.9648783914303275, 0.9648783914303275, 0.9998268524943413, 0.9998268524943413, 0.9828097468735227, 0.9828097468735227], "g": [0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.45945945945945954, 0.393939393939394, 0.393939393939394, 0.393939393939394, 0.393939393939394], "mu0": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], "sfc_alb_dir": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "sfc_alb_dif": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "inc_flux_dir": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], "flux_up": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "flux_dn": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "flux_dir": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "has_dif_bc": false, "inc_flux_dif": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "do_broadband": true, "broadband_up": [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN], "broadband_dn": [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN], "broadband_dir": [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]} \ No newline at end of file diff --git a/tests/sw_solver_test/2stream_test/sw_2stream_output.json b/tests/sw_solver_test/2stream_test/sw_2stream_output.json new file mode 100644 index 0000000..b1ea4ca --- /dev/null +++ b/tests/sw_solver_test/2stream_test/sw_2stream_output.json @@ -0,0 +1 @@ +{"flux_up": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "flux_dn": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "flux_dir": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "broadband_up": [4.312116421898994e-06, 0.00043168212837027336, 4.269415387324866e-06, 0.0004273398677522095, 1.1811425346403988e-05, 0.001182187146981845, 1.1694462130956495e-05, 0.0011702980227031314, 4.0426147857163466e-06, 0.0004047583423168658, 4.00258257850357e-06, 0.00040068759460034996, 1.1073235687056404e-05, 0.0011085442041985985, 1.0963582530491595e-05, 0.0010973967052258645, 3.773112397502808e-06, 0.000377827037253042, 3.735749015958049e-06, 0.0003740277862862827, 1.0335042771013622e-05, 0.00103486870614384, 1.0232699692277219e-05, 0.0010244630264866449, 3.5036092572596827e-06, 0.00035088821448263423, 3.4689146996895945e-06, 0.00034736044410036933, 9.596846598287394e-06, 0.0009611606645637205, 9.501813616324825e-06, 0.0009514969979433168, 3.2341053649882736e-06, 0.0003239418753092484, 3.2020796296994984e-06, 0.00032068556933271863, 8.85864716888947e-06, 0.000887420091200149, 8.770924302645877e-06, 0.0008784986310493107, 2.964600720689886e-06, 0.0002969880210362639, 2.93524380598905e-06, 0.0002940031632731866, 8.120444482831604e-06, 0.0008136469977907951, 8.04003175125184e-06, 0.0008054679372536456, 2.6950953243658227e-06, 0.00027002665296683396, 2.6684072285595403e-06, 0.0002673132272113763, 7.3822385401255445e-06, 0.0007398413960690898, 7.309135962154174e-06, 0.0007324049280009306, 2.4255891760173894e-06, 0.00024305777240388545, 2.4015698974122594e-06, 0.00024061576243663825, 6.644029340783049e-06, 0.000666003297764227, 6.578236935364348e-06, 0.0006593096147313661, 2.15608227564589e-06, 0.00021608138065011903, 2.134731812548498e-06, 0.00021391077023807004, 5.905816884815869e-06, 0.0005921327146011647, 5.84733467089382e-06, 0.0005861820088807456, 1.886574623252628e-06, 0.00018909747900800922, 1.867892973969547e-06, 0.00018719825190451653, 5.1676011722357546e-06, 0.0005182296583006278, 5.116429168754057e-06, 0.0005130221218804575, 1.6170662188389078e-06, 0.00016210606877980433, 1.6010533816766974e-06, 0.0001604782087245703, 4.429382203054459e-06, 0.0004442941405791079, 4.385520428956521e-06, 0.00043982996515748625, 1.3475570624060338e-06, 0.00013510715126752661, 1.3342130356712398e-06, 0.0001337506419865711, 3.6911599772837356e-06, 0.00037032617314886626, 3.6546084515126747e-06, 0.00036660555013441474, 1.0780471539553102e-06, 0.00010810072777297215, 1.0673719359544643e-06, 0.00010701555297860627, 2.9529344949353346e-06, 0.00029632576771793453, 2.9236932364339817e-06, 0.00029334888822942504, 8.085364934880409e-07, 8.108679959771114e-05, 8.005300825276621e-07, 8.027294298851057e-05, 2.2147057560210084e-06, 0.00022229293599011673, 2.1927747837319043e-06, 0.00022005999085630037, 5.390250810055299e-07, 5.406536804308765e-05, 5.336874753921235e-07, 5.352281330386636e-05, 1.476473760552509e-06, 0.00014822768966499036, 1.4618530934179065e-06, 0.00014673886942442676, 2.6951291650908165e-07, 2.7036434410219853e-05, 2.668441145491392e-07, 2.676516521200363e-05, 7.382385085415892e-07, 7.413004043790828e-05, 7.309281655034505e-07, 7.338553533879456e-05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "broadband_dn": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.9999997298733576, 0.9999730136579331, 0.9999996706666393, 0.9999670922012639, 0.9999992611853258, 0.9999262944073739, 0.9999992066189197, 0.9999208338681074, 0.9999994597459626, 0.9999460197927548, 0.9999993413324881, 0.9999341764999538, 0.9999985223673945, 0.9998525562553469, 0.999998413234565, 0.9998416350046654, 0.9999991896178153, 0.9999190184057726, 0.9999990119975467, 0.999901252897751, 0.999997783546206, 0.9997787855556812, 0.9999976198469358, 0.9997624034227713, 0.9999989194889156, 0.9998920094982937, 0.9999986826618148, 0.9998683213963362, 0.9999970447217604, 0.9997049823201352, 0.9999968264560322, 0.9996831391355171, 0.9999986493592634, 0.9998649930716256, 0.9999983533252924, 0.9998353819973901, 0.999996305894058, 0.9996311465604627, 0.9999960330618541, 0.9996038421559899, 0.9999983792288588, 0.9998379691270749, 0.9999980239879797, 0.9998024347025928, 0.9999955670630983, 0.9995572782884136, 0.9999952396644017, 0.9995245124972715, 0.9999981090977018, 0.9998109376659484, 0.9999976946498764, 0.9997694795136242, 0.9999948282288816, 0.9994833775157331, 0.999994446263675, 0.9994451501724391, 0.9999978389657923, 0.9997838986895526, 0.9999973653109827, 0.9997365164321639, 0.999994089391408, 0.9994094442541626, 0.9999936528596738, 0.9993657551945647, 0.9999975688331305, 0.9997568521991937, 0.9999970359712987, 0.999703545459891, 0.9999933505506773, 0.9993354785154389, 0.9999928594523982, 0.9992863275767153, 0.9999972986997161, 0.9997297981961777, 0.9999967066308243, 0.9996705665984846, 0.9999926117066895, 0.9992614803112948, 0.9999920660418483, 0.9992068673319527, 0.9999970285655493, 0.9997027366818103, 0.9999963772895594, 0.9996375798496232, 0.9999918728594447, 0.9991874496534587, 0.999991272628024, 0.9991273744733342, 0.9999967584306301, 0.9996756676573972, 0.9999960479475042, 0.9996045852149851, 0.999991134008943, 0.9991133865536551, 0.9999904792109255, 0.9990478490139115, 0.9999964882949585, 0.9996485911242435, 0.9999957186046585, 0.9995715826962481, 0.9999903951551843, 0.9990392910236039, 0.9999896857905527, 0.9989682909667316, 0.9999962181585343, 0.9996215070836546, 0.9999953892610225, 0.9995385722950899, 0.9999896562981687, 0.9989651630750208, 0.9999888923669056, 0.9988887003448365, 0.9999959480213578, 0.9995944155369353, 0.999995059916596, 0.9995055540131877, 0.9999889174378961, 0.9988910027196174, 0.9999880989399842, 0.9988090771612631, 0.9999956778834289, 0.99956731648539, 0.9999947305713792, 0.9994725278522186, 0.9999881785743665, 0.998816809969101, 0.9999873055097885, 0.9987294214290434], "broadband_dir": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.9999982651749423, 0.9998265323909958, 0.9999982204703334, 0.9998220627077182, 0.9999963903674522, 0.9996391012333828, 0.9999963642253594, 0.999636487961517, 0.9999965303528942, 0.999653094873003, 0.9999964409438334, 0.9996441570771164, 0.999992780747934, 0.9992783327146855, 0.9999927284639377, 0.9992731080640362, 0.9999947955338556, 0.9994796874408018, 0.9999946614205003, 0.9994662831025608, 0.999989171141445, 0.9989176943969015, 0.9999890927157348, 0.9989098602595227, 0.9999930607178268, 0.9993063100891733, 0.9999928819003339, 0.9992884407784186, 0.9999855615479855, 0.9985571862330416, 0.9999854569807506, 0.9985467444999591, 0.9999913259048075, 0.9991329628128993, 0.9999911023833341, 0.999110630099058, 0.9999819519675552, 0.9981968081761333, 0.9999818212589852, 0.9981837607373454, 0.9999895910947979, 0.9989596456067629, 0.999989322869501, 0.9989328510588482, 0.9999783424001543, 0.9978365601792214, 0.9999781855504384, 0.9978209089236991, 0.9999878562877978, 0.9987863584655479, 0.9999875433588347, 0.9987551036521595, 0.9999747328457825, 0.9974764421953672, 0.9999745498551103, 0.9974581890110553, 0.9999861214838074, 0.9986131013840389, 0.999985763851335, 0.998577387873363, 0.9999711233044399, 0.9971164541776493, 0.9999709141730007, 0.9970956009514664, 0.9999843866828265, 0.9984398743570216, 0.999983984347002, 0.9983997037168311, 0.9999675137761265, 0.9967565960791629, 0.9999672785041096, 0.9967331446970021, 0.9999826518848551, 0.9982666773792825, 0.9999822048458357, 0.9982220511769367, 0.999963904260842, 0.9963968678530204, 0.999963642848437, 0.9963708201997498, 0.9999809170898933, 0.998093510445609, 0.999980425347836, 0.9980444302480543, 0.9999602947585866, 0.996037269452351, 0.9999600072059828, 0.9960086274118141, 0.9999791822979411, 0.9979203735507894, 0.9999786458530031, 0.9978668409245591, 0.9999566852693602, 0.995677800830301, 0.999956371576747, 0.995646566285317, 0.9999774475089985, 0.997747266689613, 0.9999768663613369, 0.9976892832008273, 0.9999530757931627, 0.9953184619400333, 0.9999527359607295, 0.9952846367723981, 0.9999757127230654, 0.99757418985687, 0.9999750868728372, 0.997511757071236, 0.9999494663299942, 0.9949592527347279, 0.9999491003579304, 0.9949228388252142, 0.9999739779401419, 0.9974011430473513, 0.9999733073875042, 0.9973342625301634, 0.9999458568798544, 0.9946001731675815, 0.9999454647683494, 0.9945611723959396, 0.9999722431602278, 0.9972281262558489, 0.9999715279053379, 0.997156799571989, 0.9999422474427434, 0.9942412231918082, 0.9999418291919867, 0.9941996374367659]} \ No newline at end of file diff --git a/tests/sw_solver_test/2stream_test/sw_solver_2stream_test.py b/tests/sw_solver_test/2stream_test/sw_solver_2stream_test.py new file mode 100644 index 0000000..0be9e89 --- /dev/null +++ b/tests/sw_solver_test/2stream_test/sw_solver_2stream_test.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +import json +import numpy as np +import pyrte_rrtmgp.pyrte_rrtmgp as py +import os + +def load_json_file(file_path): + with open(file_path, 'r') as f: + return json.load(f) + +def test_lw_solver(request): + path = os.path.dirname(request.path) + input_data = load_json_file(f'{path}/sw_2stream_input.json') + + for key in input_data: + values = input_data[key] + if isinstance(values, list): + values = np.array(values) + input_data[key] = values + + args = list(input_data.values()) + + py.rte_sw_solver_2stream(*args) + + output_data = load_json_file(f'{path}/sw_2stream_output.json') + + for key in output_data: + assert(np.allclose(output_data[key] - input_data[key], 0.)) \ No newline at end of file diff --git a/tests/test_exported_functions.py b/tests/test_exported_functions.py index 431a471..fd929ea 100644 --- a/tests/test_exported_functions.py +++ b/tests/test_exported_functions.py @@ -1,4 +1,5 @@ import pytest +import copy import numpy as np import pyrte_rrtmgp.pyrte_rrtmgp as py @@ -37,4 +38,468 @@ def test_empty_array_exception(array, method): def test_zero_array(shape, fortran_zero_array): arr = np.random.rand(*shape) fortran_zero_array(arr) - assert np.all(arr == 0) \ No newline at end of file + assert np.all(arr == 0) + +########################################### +## test_rte_increment_1scalar_by_1scalar ## +########################################### + +def test_rte_increment_1scalar_by_1scalar_dimension_check(): + + ncol = 0 + nlay = 0 + ngpt = 0 + tau_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + + with pytest.raises(RuntimeError) as excinfo: + py.rte_increment_1scalar_by_1scalar(ncol, nlay, ngpt, tau_inout, tau_in) + assert str(excinfo.value) == "ncol, nlay, and ngpt must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_1scalar_by_1scalar) +]) +def test_rte_increment_1scalar_by_1scalar_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_1scalar_by_1scalar(): + ncol, nlay, ngpt = (3,4,5) + tau_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + + parameters = [ncol, nlay, ngpt, tau_inout, tau_in] + + res = np.array(tau_inout) + + for igpt in range(ngpt): + for ilay in range(nlay): + for icol in range(ncol): + res[icol][ilay][igpt] += tau_in[icol][ilay][igpt] + + py.rte_increment_1scalar_by_1scalar(*parameters) + assert np.array_equal(tau_inout, res) + +########################################### +## test_rte_increment_1scalar_by_2stream ## +########################################### + +def test_rte_increment_1scalar_by_2stream_dimension_check(): + ncol = 0 + nlay = 0 + ngpt = 0 + tau_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + ssa_in = np.random.rand(ncol, nlay, ngpt) + with pytest.raises(RuntimeError) as excinfo: + py.rte_increment_1scalar_by_2stream(ncol, nlay, ngpt, tau_inout, tau_in, ssa_in) + assert str(excinfo.value) == "ncol, nlay, and ngpt must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_1scalar_by_2stream) +]) +def test_rte_increment_1scalar_by_2stream_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +@pytest.mark.parametrize("parameters, method", [ + ((3, 4, 5, np.ones((3, 4, 5)), np.ones((3, 4, 5)), np.ones((3, 4, 5))), py.rte_increment_1scalar_by_2stream) +]) +def test_rte_increment_1scalar_by_2stream(parameters, method): + ncol, nlay, ngpt, tau_inout, tau_in, ssa_in = parameters + res = np.array(tau_inout) + + for igpt in range(ngpt): + for ilay in range(nlay): + for icol in range(ncol): + res[icol, ilay, igpt] += tau_in[icol, ilay, igpt] * (1.0 - ssa_in[icol, ilay, igpt]) + + method(*parameters) + assert np.array_equal(tau_inout, res) + +########################################### +## test_rte_increment_1scalar_by_nstream ## +########################################### + +def test_rte_increment_1scalar_by_nstream_dimension_check(): + ncol = 0 + nlay = 0 + ngpt = 0 + tau_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + ssa_in = np.random.rand(ncol, nlay, ngpt) + + parameters = [ncol, nlay, ngpt, tau_inout, tau_in, ssa_in] + + with pytest.raises(RuntimeError) as excinfo: + py.rte_increment_1scalar_by_nstream(ncol, nlay, ngpt, tau_inout, tau_in, ssa_in) + assert str(excinfo.value) == "ncol, nlay, and ngpt must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_1scalar_by_nstream) +]) +def test_rte_increment_1scalar_by_nstream_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_1scalar_by_nstream(): + ncol = 3 + nlay = 4 + ngpt = 5 + tau_inout = np.random.rand(ncol, nlay, ngpt) + ssa_in = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + + parameters = [ncol, nlay, ngpt, tau_inout, ssa_in, tau_in] + res = np.array(tau_inout) + + for igpt in range(ngpt): + for ilay in range(nlay): + for icol in range(ncol): + res[icol - 1, ilay - 1, igpt - 1] += ssa_in[icol - 1, ilay - 1, igpt - 1] * (1.0 - tau_in[icol - 1, ilay - 1, igpt - 1]) + + py.rte_increment_1scalar_by_nstream(*parameters) + assert np.array_equal(tau_inout, res) + +########################################### +## test_rte_increment_2stream_by_1scalar ## +########################################### + +@pytest.mark.parametrize("parameters,method", [ + ((0, 0, 0, np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3))), + py.rte_increment_2stream_by_1scalar) +]) +def test_rte_increment_2stream_by_1scalar_dimension_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "ncol, nlay, and ngpt must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_2stream_by_1scalar) +]) +def test_rte_increment_2stream_by_1scalar_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_2stream_by_1scalar(): + + eps = 3.0 * np.finfo(float).tiny + + ncol = 3 + nlay = 4 + ngpt = 5 + tau_inout = np.random.rand(ncol, nlay, ngpt) + ssa_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + + parameters = [ncol, nlay, ngpt, tau_inout, ssa_inout, tau_in] + + res_tau_inout = np.array(tau_inout) + res_ssa_inout = np.array(ssa_inout) + + eps = 3.0 * np.finfo(float).tiny + + for igpt in range(1, ngpt + 1): + for ilay in range(1, nlay + 1): + for icol in range(1, ncol + 1): + tau12 = tau_inout[icol - 1, ilay - 1, igpt - 1] + tau_in[icol - 1, ilay - 1, igpt - 1] + res_ssa_inout[icol - 1, ilay - 1, igpt - 1] = tau_inout[icol - 1, ilay - 1, igpt - 1] * ssa_inout[icol - 1, ilay - 1, igpt - 1] / max(eps, tau12) + res_tau_inout[icol - 1, ilay - 1, igpt - 1] = tau12 + + py.rte_increment_2stream_by_1scalar(*parameters) + assert np.array_equal(res_tau_inout, tau_inout) and np.array_equal(res_ssa_inout, ssa_inout) + +########################################### +## test_rte_increment_2stream_by_2stream ## +########################################### + +@pytest.mark.parametrize("parameters,method", [ + ((0, 0, 0, np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3))), + py.rte_increment_2stream_by_2stream) +]) +def test_rte_increment_2stream_by_2stream_dimension_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "ncol, nlay, and ngpt must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_2stream_by_2stream) +]) +def test_rte_increment_2stream_by_2stream_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_2stream_by_2stream(): + ncol = 3 + nlay = 4 + ngpt = 5 + tau_inout = np.random.rand(ncol, nlay, ngpt) + ssa_inout = np.random.rand(ncol, nlay, ngpt) + g_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + ssa_in = np.random.rand(ncol, nlay, ngpt) + g_in = np.random.rand(ncol, nlay, ngpt) + + parameters = [ncol, nlay, ngpt, tau_inout, ssa_inout, g_inout, tau_in, ssa_in, g_in] + + res_tau_inout = np.array(tau_inout) + res_ssa_inout = np.array(ssa_inout) + res_g_inout = np.array(g_inout) + + eps = 3.0 * np.finfo(float).tiny + + for igpt in range(1, ngpt + 1): + for ilay in range(1, nlay + 1): + for icol in range(1, ncol + 1): + tau12 = tau_inout[icol - 1, ilay - 1, igpt - 1] + tau_in[icol - 1, ilay - 1, igpt - 1] + tauscat12 = tau_inout[icol - 1, ilay - 1, igpt - 1] * ssa_inout[icol - 1, ilay - 1, igpt - 1] + tau_in[icol - 1, ilay - 1, igpt - 1] * ssa_in[icol - 1, ilay - 1, igpt - 1] + + res_g_inout[icol - 1, ilay - 1, igpt - 1] = (tau_inout[icol - 1, ilay - 1, igpt - 1] * ssa_inout[icol - 1, ilay - 1, igpt - 1] * g_inout[icol - 1, ilay - 1, igpt - 1] + tau_in[icol - 1, ilay - 1, igpt - 1] * ssa_in[icol - 1, ilay - 1, igpt - 1] * g_in[icol - 1, ilay - 1, igpt - 1]) / max(eps, tauscat12) + res_ssa_inout[icol - 1, ilay - 1, igpt - 1] = tauscat12 / max(eps, tau12) + res_tau_inout[icol - 1, ilay - 1, igpt - 1] = tau12 + + py.rte_increment_2stream_by_2stream(*parameters) + assert np.array_equal(res_tau_inout, tau_inout) and np.array_equal(res_ssa_inout, ssa_inout) and np.array_equal(res_g_inout, g_inout) + +########################################### +## test_rte_increment_2stream_by_nstream ## +########################################### + +@pytest.mark.parametrize("parameters,method", [ + ((0, 0, 0, 0, np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3, 3))), + py.rte_increment_2stream_by_nstream) +]) +def test_rte_increment_2stream_by_nstream_dimension_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "ncol, nlay, ngpt and nmom must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_2stream_by_nstream) +]) +def test_rte_increment_2stream_by_nstream_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_2stream_by_nstream(): + + ncol = 3 + nlay = 4 + ngpt = 5 + nmom = 6 + tau_inout = np.random.rand(ncol, nlay, ngpt) + ssa_inout = np.random.rand(ncol, nlay, ngpt) + g_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + ssa_in = np.random.rand(ncol, nlay, ngpt) + p_in = np.random.rand(ncol, nlay, ngpt, nmom) + + expected_tau_inout = np.empty_like(tau_inout) + expected_ssa_inout = np.empty_like(ssa_inout) + expected_g_inout = np.empty_like(g_inout) + + eps = 3.0 * np.finfo(float).tiny + + for igpt in range(ngpt): + for ilay in range(nlay): + for icol in range(ncol): + tau12 = tau_inout[icol, ilay, igpt] + tau_in[icol, ilay, igpt] + tauscat12 = (tau_inout[icol, ilay, igpt] * ssa_inout[icol, ilay, igpt] + + tau_in[icol, ilay, igpt] * ssa_in[icol, ilay, igpt]) + expected_g_inout[icol, ilay, igpt] = (tau_inout[icol, ilay, igpt] * ssa_inout[icol, ilay, igpt] * g_inout[icol, ilay, igpt] + + tau_in[icol, ilay, igpt] * ssa_in[icol, ilay, igpt] * p_in[icol, ilay, igpt, 0]) \ + / max(tauscat12, eps) + expected_ssa_inout[icol, ilay, igpt] = tauscat12 / max(eps, tau12) + expected_tau_inout[icol, ilay, igpt] = tau12 + + py.rte_increment_2stream_by_nstream(ncol, nlay, ngpt, nmom, tau_inout, ssa_inout, g_inout, tau_in, ssa_in, p_in) + + assert np.allclose(expected_tau_inout - tau_inout, 0.) + assert np.allclose(expected_ssa_inout - ssa_inout, 0.) + assert np.allclose(expected_g_inout - g_inout, 0.) + +########################################### +## test_rte_increment_nstream_by_1scalar ## +########################################### + +@pytest.mark.parametrize("parameters,method", [ + ((0, 0, 0, np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3))), + py.rte_increment_nstream_by_1scalar) +]) +def test_rte_increment_nstream_by_1scalar_dimension_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "ncol, nlay and ngpt must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_nstream_by_1scalar) +]) +def test_rte_increment_nstream_by_1scalar_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_nstream_by_1scalar(): + ncol, nlay, ngpt = 3, 3, 3 + tau_inout = np.random.rand(ncol, nlay, ngpt) + g_inout = np.random.rand(ncol, nlay, ngpt) + tau_in = np.random.rand(ncol, nlay, ngpt) + + res_tau_inout = np.array(tau_inout) + res_g_inout = np.array(g_inout) + + eps = 3.0 * np.finfo(float).eps + for icol in range(ncol): + for ilay in range(nlay): + for igpt in range(ngpt): + tau12 = tau_inout[icol, ilay, igpt] + tau_in[icol, ilay, igpt] + res_g_inout[icol, ilay, igpt] = tau_inout[icol, ilay, igpt] * g_inout[icol, ilay, igpt] / max(tau12, eps) + res_tau_inout[icol, ilay, igpt] = tau12 + + py.rte_increment_nstream_by_1scalar(ncol, nlay, ngpt, tau_inout, g_inout, tau_in) + assert np.allclose(res_tau_inout, tau_inout) and np.allclose(res_g_inout, g_inout) + +########################################### +## test_rte_increment_nstream_by_2stream ## +########################################### + +@pytest.mark.parametrize("parameters,method", [ + ((0, 0, 0, 0, np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3))), + py.rte_increment_nstream_by_2stream) +]) +def test_rte_increment_nstream_by_2stream_dimension_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "ncol, nlay, ngpt and nmom1 must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_nstream_by_2stream) +]) +def test_rte_increment_nstream_by_2stream_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_nstream_by_2stream(): + + ncol = 3 + nlay = 4 + ngpt = 5 + nmom1 = 6 + tau_inout = np.random.rand(ncol, nlay, ngpt) + ssa_inout = np.random.rand(ncol, nlay, ngpt) + p_inout = np.random.rand(ncol, nlay, ngpt, nmom1) + tau_in = np.random.rand(ncol, nlay, ngpt) + ssa_in = np.random.rand(ncol, nlay, ngpt) + g_in = np.random.rand(ncol, nlay, ngpt) + + expected_tau_inout = np.empty_like(tau_inout) + expected_ssa_inout = np.empty_like(ssa_inout) + expected_phase_inout = np.empty_like(p_inout) + + eps = 3.0 * np.finfo(float).tiny + + temp_moms = np.zeros(nmom1, dtype=float) + + for icol in range(ncol): + for ilay in range(nlay): + for igpt in range(ngpt): + tau12 = tau_inout[icol, ilay, igpt] + tau_in[icol, ilay, igpt] + tauscat12 = tau_inout[icol, ilay, igpt] * ssa_inout[icol, ilay, igpt] + tau_in[icol, ilay, igpt] * ssa_in[icol, ilay, igpt] + + temp_moms[0] = g_in[icol, ilay, igpt] + for imom in range(1, nmom1): + temp_moms[imom] = temp_moms[imom - 1] * g_in[icol, ilay, igpt] + + p_a = tau_inout[icol, ilay, igpt] * ssa_inout[icol, ilay, igpt] * p_inout[icol, ilay, igpt, 0:nmom1] + p_b = tau_in[icol, ilay, igpt] * ssa_in[icol, ilay, igpt] * temp_moms[0:nmom1] + p_c = (p_a + p_b) / max(tauscat12, eps) + + expected_phase_inout[icol, ilay, igpt, 0:nmom1] = p_c + expected_ssa_inout[icol, ilay, igpt] = tauscat12 / max(eps,tau12) + expected_tau_inout[icol, ilay, igpt] = tau12 + + py.rte_increment_nstream_by_2stream(ncol, nlay, ngpt, nmom1, tau_inout, ssa_inout, p_inout, tau_in, ssa_in, g_in) + + assert np.allclose(expected_tau_inout - tau_inout, 0.) + assert np.allclose(expected_ssa_inout - ssa_inout, 0.) + assert np.allclose(expected_phase_inout - p_inout, 0.) + +########################################### +## test_rte_increment_nstream_by_nstream ## +########################################### + +@pytest.mark.parametrize("parameters,method", [ + ((0, 0, 0, 0, 0, np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3)), np.ones((3, 3, 3, 3))), + py.rte_increment_nstream_by_nstream) +]) +def test_rte_increment_nstream_by_nstream_dimension_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "ncol, nlay, ngpt, nmom1 and nmom2 must be positive integers" + +@pytest.mark.parametrize("parameters,method", [ + ((3, 3, 3, 3, 3, np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3)), np.ones((3, 3))), + py.rte_increment_nstream_by_nstream) +]) +def test_rte_increment_nstream_by_nstream_array_size_check(parameters, method): + with pytest.raises(RuntimeError) as excinfo: + method(*parameters) + assert str(excinfo.value) == "Invalid size for input arrays" + +def test_rte_increment_nstream_by_nstream(): + ncol = 3 + nlay = 4 + ngpt = 5 + nmom1 = 6 + nmom2 = 7 + tau_inout = np.random.rand(ncol, nlay, ngpt) + ssa_inout = np.random.rand(ncol, nlay, ngpt) + p_inout = np.random.rand(ncol, nlay, ngpt, nmom1) + tau_in = np.random.rand(ncol, nlay, ngpt) + ssa_in = np.random.rand(ncol, nlay, ngpt) + p_in = np.random.rand(ncol, nlay, ngpt, nmom2) + + expected_tau_inout = np.empty_like(tau_inout) + expected_ssa_inout = np.empty_like(ssa_inout) + expected_phase_inout = np.empty_like(p_inout) + + mom_lim = min(nmom1, nmom2) + + eps = 3.0 * np.finfo(np.float64).tiny + + for icol in range(ncol): + for ilay in range(nlay): + for igpt in range(ngpt): + tau12 = tau_inout[icol, ilay, igpt] + tau_in[icol, ilay, igpt] + + tauscat12_a = tau_inout[icol, ilay, igpt] * ssa_inout[icol, ilay, igpt] + tauscat12_b = tau_in[icol, ilay, igpt] * ssa_in[icol, ilay, igpt] + tauscat12 = tauscat12_a + tauscat12_b + + p_a = tauscat12_a * p_inout[icol, ilay, igpt,0:mom_lim] + p_b = tauscat12_b * p_in[icol, ilay, igpt, 0:mom_lim] + p = (p_a + p_b) / max(tauscat12, eps) + + expected_ssa_inout[icol, ilay, igpt] = tauscat12 / max(eps,tau12) + expected_tau_inout[icol, ilay, igpt] = tau12 + expected_phase_inout[icol, ilay, igpt, 0:mom_lim] = p + + py.rte_increment_nstream_by_nstream(ncol, nlay, ngpt, nmom1, nmom2, tau_inout, ssa_inout, p_inout, tau_in, ssa_in, p_in) + assert np.allclose(expected_tau_inout - tau_inout, 0.) + assert np.allclose(expected_ssa_inout - ssa_inout, 0.) + assert np.allclose(expected_phase_inout - p_inout, 0.) \ No newline at end of file diff --git a/tests/utils/data_parser.py b/tests/utils/data_parser.py new file mode 100644 index 0000000..baf79e4 --- /dev/null +++ b/tests/utils/data_parser.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +import json + +def parse_value(value): + # Handle NaN + if 'NaN' in value: + res = float('nan') + # Handle bool + elif value in ['T', 'F']: + res = True if value == 'T' else False + # Handle float + elif "." in value: + res = float(value) + else: + try: + # Handle int + res = int(value) + except ValueError: + # Keeping as string if not an int + res = value + return res + +def load_data_from_file(file_path): + data = {} + with open(file_path, 'r') as file: + for line in file: + parts = line.split(':') + assert(len(parts) == 2) + key = parts[0].strip() + values = parts[1].strip().split() + if len(values) == 1: + data[key] = parse_value(values[0]) + else: + data[key] = [float(val) for val in values] + return data + +file_path = 'fortran_data_input.txt' +data = load_data_from_file(file_path) + +with open('input.json', 'w') as f: + json.dump(data, f) \ No newline at end of file diff --git a/tests/utils/zip.py b/tests/utils/zip.py new file mode 100644 index 0000000..3c19b34 --- /dev/null +++ b/tests/utils/zip.py @@ -0,0 +1,30 @@ +import zipfile +import json +import os + +ZIP = True + +p = os.getcwd() +base_name = p + "/tests/rrtmgp_interpolation_test/interpolation" + + +if ZIP: + with zipfile.ZipFile(base_name+"_test_data.zip", "w", zipfile.ZIP_DEFLATED) as zip_file: + zip_file.write("input.json") + zip_file.write("output.json") +else: + # Unzip data + input_data = None + output_data = None + with zipfile.ZipFile(base_name+'_test_data.zip') as myzip: + with myzip.open('input.json') as myfile: + input_data = json.load(myfile) + with myzip.open('output.json') as myfile: + output_data = json.load(myfile) + + # Store to Json for verification + with open(base_name+'_output.json', 'w') as f: + json.dump(output_data, f) + + with open(base_name+'_input.json', 'w') as f: + json.dump(input_data, f) \ No newline at end of file