diff --git a/libmpdata++/CMakeLists.txt b/libmpdata++/CMakeLists.txt index 264ae3a5..6bf368a9 100644 --- a/libmpdata++/CMakeLists.txt +++ b/libmpdata++/CMakeLists.txt @@ -5,7 +5,7 @@ project(libmpdata++ CXX) # using include() istead of find_package(libmpdata++) to use local CMake code # and not the system-installed one include(${CMAKE_SOURCE_DIR}/../libmpdata++-config.cmake) -if (NOT libmpdataxx_FOUND) +if (NOT libmpdataxx_FOUND) message(FATAL_ERROR "local libmpdata++-config.cmake not found!") endif() @@ -13,20 +13,20 @@ endif() if (EXISTS "${CMAKE_SOURCE_DIR}/../.git") execute_process(COMMAND bash -c "git log -1 --format=\"format:#define LIBMPDATAXX_GIT_REVISION \\\"%H\\\"%n\" HEAD > git_revision.hpp" - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) endif() install( DIRECTORY bcond concurr formulae output solvers - DESTINATION + DESTINATION include/libmpdata++ ) install( FILES blitz.hpp git_revision.hpp kahan_reduction.hpp opts.hpp - DESTINATION + DESTINATION include/libmpdata++ ) install( diff --git a/libmpdata++/bcond/cyclic_1d.hpp b/libmpdata++/bcond/cyclic_1d.hpp index 830aedbe..8671a961 100644 --- a/libmpdata++/bcond/cyclic_1d.hpp +++ b/libmpdata++/bcond/cyclic_1d.hpp @@ -11,11 +11,11 @@ namespace libmpdataxx { namespace bcond { - template + template class bcond< real_t, halo, knd, dir, n_dims, dim, typename std::enable_if< - knd == cyclic && - dir == left && + knd == cyclic && + dir == left && n_dims == 1 >::type > : public detail::bcond_common @@ -28,14 +28,14 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const bool deriv = false) { - a(this->left_halo_sclr) = a(this->rght_intr_sclr); + a(this->left_halo_sclr) = a(this->rght_intr_sclr); } void fill_halos_vctr_alng(arrvec_t &av, const bool ad = false) { - av[0](this->left_halo_vctr) = av[0](this->rght_intr_vctr); + av[0](this->left_halo_vctr) = av[0](this->rght_intr_vctr); } - + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const bool ad = false) { fill_halos_vctr_alng(av, ad); @@ -59,14 +59,14 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const bool deriv = false) { - a(this->rght_halo_sclr) = a(this->left_intr_sclr); + a(this->rght_halo_sclr) = a(this->left_intr_sclr); } void fill_halos_vctr_alng(arrvec_t &av, const bool ad = false) { - av[0](this->rght_halo_vctr) = av[0](this->left_intr_vctr); + av[0](this->rght_halo_vctr) = av[0](this->left_intr_vctr); } - + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const bool ad = false) { fill_halos_vctr_alng(av, ad); diff --git a/libmpdata++/bcond/cyclic_2d.hpp b/libmpdata++/bcond/cyclic_2d.hpp index fe31b853..19111088 100644 --- a/libmpdata++/bcond/cyclic_2d.hpp +++ b/libmpdata++/bcond/cyclic_2d.hpp @@ -12,14 +12,14 @@ namespace libmpdataxx namespace bcond { template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == cyclic && dir == left && n_dims == 2 >::type > : public detail::bcond_common - { + { using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -28,25 +28,25 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { - using namespace idxperm; - a(pi(this->left_halo_sclr, j)) = a(pi(this->rght_intr_sclr, j)); + using namespace idxperm; + a(pi(this->left_halo_sclr, j)) = a(pi(this->rght_intr_sclr, j)); } void fill_halos_pres(arr_t &a, const rng_t &j) { fill_halos_sclr(a, j); } - + void save_edge_vel(const arr_t &, const rng_t &) {} void set_edge_pres(arr_t &, const rng_t &, int) {} void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const bool ad = false) { - using namespace idxperm; + using namespace idxperm; av[d](pi(this->left_halo_vctr, j)) = av[d](pi(this->rght_intr_vctr, j)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j) { fill_halos_sclr(a, j); @@ -54,11 +54,11 @@ namespace libmpdataxx void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! av[d + offset](pi(this->left_halo_vctr, j)) = av[d + offset](pi(this->rght_intr_vctr, j)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const real_t) { fill_halos_vctr_alng(av, j); @@ -68,7 +68,7 @@ namespace libmpdataxx { fill_halos_sclr(a, j); } - + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const bool ad = false) { fill_halos_vctr_alng(av, j, ad); @@ -81,14 +81,14 @@ namespace libmpdataxx }; template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == cyclic && dir == rght && n_dims == 2 >::type > : public detail::bcond_common - { + { using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -97,25 +97,25 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { - using namespace idxperm; - a(pi(this->rght_halo_sclr, j)) = a(pi(this->left_intr_sclr, j)); + using namespace idxperm; + a(pi(this->rght_halo_sclr, j)) = a(pi(this->left_intr_sclr, j)); } - + void fill_halos_pres(arr_t &a, const rng_t &j) { fill_halos_sclr(a, j); } - + void save_edge_vel(const arr_t &, const rng_t &) {} void set_edge_pres(arr_t &, const rng_t &, int) {} void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const bool ad = false) { - using namespace idxperm; + using namespace idxperm; av[d](pi(this->rght_halo_vctr, j)) = av[d](pi(this->left_intr_vctr, j)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j) { fill_halos_sclr(a, j); @@ -123,21 +123,21 @@ namespace libmpdataxx void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! av[d + offset](pi(this->rght_halo_vctr, j)) = av[d + offset](pi(this->left_intr_vctr, j)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const real_t) { fill_halos_vctr_alng(av, j); } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) { fill_halos_sclr(a, j); } - + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const bool ad = false) { fill_halos_vctr_alng(av, j, ad); diff --git a/libmpdata++/bcond/cyclic_3d.hpp b/libmpdata++/bcond/cyclic_3d.hpp index 677fc025..18d4b039 100644 --- a/libmpdata++/bcond/cyclic_3d.hpp +++ b/libmpdata++/bcond/cyclic_3d.hpp @@ -12,14 +12,14 @@ namespace libmpdataxx namespace bcond { template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == cyclic && dir == left && n_dims == 3 >::type > : public detail::bcond_common - { + { using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -28,37 +28,37 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { - using namespace idxperm; - a(pi(this->left_halo_sclr, j, k)) = a(pi(this->rght_intr_sclr, j, k)); + using namespace idxperm; + a(pi(this->left_halo_sclr, j, k)) = a(pi(this->rght_intr_sclr, j, k)); } void fill_halos_pres(arr_t &a, const rng_t &j, const rng_t &k) { fill_halos_sclr(a, j, k); } - + void save_edge_vel(const arr_t &, const rng_t &, const rng_t &) {} - + void set_edge_pres(arr_t &, const rng_t &, const rng_t &, int) {} void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; + using namespace idxperm; av[d](pi(this->left_halo_vctr, j, k)) = av[d](pi(this->rght_intr_vctr, j, k)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j, const rng_t &k) { fill_halos_sclr(a, j, k); } - + void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const rng_t &k, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! av[d + offset](pi(this->left_halo_vctr, j, k)) = av[d + offset](pi(this->rght_intr_vctr, j, k)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const rng_t &k, const real_t) { fill_halos_vctr_alng(av, j, k); @@ -68,7 +68,7 @@ namespace libmpdataxx { fill_halos_sclr(a, j, k); } - + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { fill_halos_vctr_alng(av, j, k, ad); @@ -81,7 +81,7 @@ namespace libmpdataxx }; template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == cyclic && dir == rght && @@ -97,37 +97,37 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { - using namespace idxperm; - a(pi(this->rght_halo_sclr, j, k)) = a(pi(this->left_intr_sclr, j, k)); + using namespace idxperm; + a(pi(this->rght_halo_sclr, j, k)) = a(pi(this->left_intr_sclr, j, k)); } void fill_halos_pres(arr_t &a, const rng_t &j, const rng_t &k) { fill_halos_sclr(a, j, k); } - + void save_edge_vel(const arr_t &, const rng_t &, const rng_t &) {} - + void set_edge_pres(arr_t &, const rng_t &, const rng_t &, int) {} - + void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; + using namespace idxperm; av[d](pi(this->rght_halo_vctr, j, k)) = av[d](pi(this->left_intr_vctr, j, k)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j, const rng_t &k) { fill_halos_sclr(a, j, k); } - + void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const rng_t &k, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! av[d + offset](pi(this->rght_halo_vctr, j, k)) = av[d + offset](pi(this->left_intr_vctr, j, k)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const rng_t &k, const real_t) { fill_halos_vctr_alng(av, j, k); @@ -137,7 +137,7 @@ namespace libmpdataxx { fill_halos_sclr(a, j, k); } - + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { fill_halos_vctr_alng(av, j, k, ad); diff --git a/libmpdata++/bcond/detail/bcond_common.hpp b/libmpdata++/bcond/detail/bcond_common.hpp index a1890beb..45ce263f 100644 --- a/libmpdata++/bcond/detail/bcond_common.hpp +++ b/libmpdata++/bcond/detail/bcond_common.hpp @@ -14,18 +14,18 @@ namespace libmpdataxx { using namespace arakawa_c; - enum bcond_e { null, cyclic, polar, open, rigid, remote, gndsky, custom }; + enum bcond_e { null, cyclic, polar, open, rigid, remote, gndsky, custom }; enum drctn_e { left, rght }; template< - typename real_t, + typename real_t, int halo, bcond_e knd, - drctn_e dir, + drctn_e dir, int n_dims, int dim, class enableif = void - > + > class bcond {}; @@ -40,200 +40,200 @@ namespace libmpdataxx using arr_2d_t = blitz::Array; using arr_3d_t = blitz::Array; - public: + public: - // 1D - virtual void fill_halos_sclr(arr_1d_t &, const bool deriv = false) - { - assert(false && "bcond::fill_halos_sclr() called!"); - }; + // 1D + virtual void fill_halos_sclr(arr_1d_t &, const bool deriv = false) + { + assert(false && "bcond::fill_halos_sclr() called!"); + }; + + virtual void fill_halos_vctr_alng(arrvec_t &, const bool ad = false) + { + assert(false && "bcond::fill_halos_vctr() called!"); + }; - virtual void fill_halos_vctr_alng(arrvec_t &, const bool ad = false) - { - assert(false && "bcond::fill_halos_vctr() called!"); - }; - virtual void fill_halos_vctr_alng_cyclic(arrvec_t> &, const bool ad = false) - {}; - - // 2D - virtual void fill_halos_sclr(arr_2d_t &, const rng_t &, const bool deriv = false) - { - assert(false && "bcond::fill_halos_sclr() called!"); - }; - - virtual void fill_halos_pres(arr_2d_t &, const rng_t &) - { - assert(false && "bcond::fill_halos_pres() called!"); - }; - - virtual void save_edge_vel(const arr_2d_t &, const rng_t &) - { - assert(false && "bcond::save_edge_vel() called!"); - }; - - virtual void set_edge_pres(arr_2d_t &, const rng_t &, int) - { - assert(false && "bcond::set_edge() called!"); - }; - - virtual void fill_halos_vctr_alng(arrvec_t &, const rng_t &, const bool ad = false) - { - assert(false && "bcond::fill_halos_vctr_alng() called!"); - }; - + {}; + + // 2D + virtual void fill_halos_sclr(arr_2d_t &, const rng_t &, const bool deriv = false) + { + assert(false && "bcond::fill_halos_sclr() called!"); + }; + + virtual void fill_halos_pres(arr_2d_t &, const rng_t &) + { + assert(false && "bcond::fill_halos_pres() called!"); + }; + + virtual void save_edge_vel(const arr_2d_t &, const rng_t &) + { + assert(false && "bcond::save_edge_vel() called!"); + }; + + virtual void set_edge_pres(arr_2d_t &, const rng_t &, int) + { + assert(false && "bcond::set_edge() called!"); + }; + + virtual void fill_halos_vctr_alng(arrvec_t &, const rng_t &, const bool ad = false) + { + assert(false && "bcond::fill_halos_vctr_alng() called!"); + }; + virtual void fill_halos_sgs_div(arr_2d_t &, const rng_t &) - { - assert(false && "bcond::fill_halos_sgs_div() called!"); - }; + { + assert(false && "bcond::fill_halos_sgs_div() called!"); + }; virtual void fill_halos_sgs_vctr(arrvec_t &, const arr_2d_t &, const rng_t &, const int offset = 0) - { - assert(false && "bcond::fill_halos_sgs_vctr() called!"); - }; - + { + assert(false && "bcond::fill_halos_sgs_vctr() called!"); + }; + virtual void fill_halos_sgs_tnsr(arrvec_t &, const arr_2d_t &, const arr_2d_t &, const rng_t &, const real_t) - { - assert(false && "bcond::fill_halos_sgs_tnsr called!"); - }; - - virtual void fill_halos_vctr_nrml(arr_2d_t &, const rng_t &) - { - assert(false && "bcond::fill_halos_vctr_nrml() called!"); - }; - - virtual void fill_halos_vctr_alng_cyclic(arrvec_t> &, const rng_t &, const bool ad = false) - {}; - - virtual void fill_halos_vctr_nrml_cyclic(blitz::Array &, const rng_t &) - {}; - - virtual void fill_halos_flux(arrvec_t> &, const rng_t &) - {}; - - // 3D - virtual void fill_halos_sclr(arr_3d_t &, const rng_t &, const rng_t &, const bool deriv = false) - { - assert(false && "bcond::fill_halos_sclr() called!"); - }; - + { + assert(false && "bcond::fill_halos_sgs_tnsr called!"); + }; + + virtual void fill_halos_vctr_nrml(arr_2d_t &, const rng_t &) + { + assert(false && "bcond::fill_halos_vctr_nrml() called!"); + }; + + virtual void fill_halos_vctr_alng_cyclic(arrvec_t> &, const rng_t &, const bool ad = false) + {}; + + virtual void fill_halos_vctr_nrml_cyclic(blitz::Array &, const rng_t &) + {}; + + virtual void fill_halos_flux(arrvec_t> &, const rng_t &) + {}; + + // 3D + virtual void fill_halos_sclr(arr_3d_t &, const rng_t &, const rng_t &, const bool deriv = false) + { + assert(false && "bcond::fill_halos_sclr() called!"); + }; + virtual void fill_halos_pres(arr_3d_t &, const rng_t &, const rng_t &) - { - assert(false && "bcond::fill_halos_pres() called!"); - }; - - virtual void save_edge_vel(const arr_3d_t &, const rng_t &, const rng_t &) - { - assert(false && "bcond::save_edge_vel() called!"); - }; - - virtual void set_edge_pres(arr_3d_t &, const rng_t &, const rng_t &, int) - { - assert(false && "bcond::set_edge() called!"); - }; - - virtual void fill_halos_vctr_alng(arrvec_t &, const rng_t &, const rng_t &, const bool ad = false) - { - assert(false && "bcond::fill_halos_vctr() called!"); - }; - - virtual void fill_halos_sgs_div(arr_3d_t &, const rng_t &, const rng_t &) - { - assert(false && "bcond::fill_halos_sgs_div() called!"); - }; - + { + assert(false && "bcond::fill_halos_pres() called!"); + }; + + virtual void save_edge_vel(const arr_3d_t &, const rng_t &, const rng_t &) + { + assert(false && "bcond::save_edge_vel() called!"); + }; + + virtual void set_edge_pres(arr_3d_t &, const rng_t &, const rng_t &, int) + { + assert(false && "bcond::set_edge() called!"); + }; + + virtual void fill_halos_vctr_alng(arrvec_t &, const rng_t &, const rng_t &, const bool ad = false) + { + assert(false && "bcond::fill_halos_vctr() called!"); + }; + + virtual void fill_halos_sgs_div(arr_3d_t &, const rng_t &, const rng_t &) + { + assert(false && "bcond::fill_halos_sgs_div() called!"); + }; + virtual void fill_halos_sgs_vctr(arrvec_t &, const arr_3d_t &, const rng_t &, const rng_t &, const int offset = 0) - { - assert(false && "bcond::fill_halos_sgs_vctr() called!"); - }; - + { + assert(false && "bcond::fill_halos_sgs_vctr() called!"); + }; + virtual void fill_halos_sgs_tnsr(arrvec_t &, const arr_3d_t &, const arr_3d_t &, const rng_t &, const rng_t &, const real_t) - { - assert(false && "bcond::fill_halos_sgs_tnsr called!"); - }; - - virtual void fill_halos_vctr_nrml(arr_3d_t &, const rng_t &, const rng_t &) - { - assert(false && "bcond::fill_halos_vctr_nrml() called!"); - }; - - virtual void fill_halos_vctr_alng_cyclic(arrvec_t> &, const rng_t &, const rng_t &, const bool ad = false) - {}; - - virtual void fill_halos_vctr_nrml_cyclic(blitz::Array &, const rng_t &, const rng_t &) - {}; - - virtual void fill_halos_flux(arrvec_t> &, const rng_t &, const rng_t &) - {}; - - protected: - // sclr - int - left_edge_sclr, rght_edge_sclr; - rng_t - left_halo_sclr, rght_halo_sclr, - left_intr_sclr, rght_intr_sclr, - // vctr - left_halo_vctr, rght_halo_vctr, - left_intr_vctr, rght_intr_vctr; - - public: - - // ctor - bcond_common(const rng_t &i, const std::array &) : - // sclr - left_edge_sclr( - i.first() - ), - rght_edge_sclr( - i.last() - ), - left_halo_sclr( - (i^halo).first(), - (i^halo).first() + halo - 1 - ), - rght_halo_sclr( - (i^halo).last() - (halo - 1), - (i^halo).last() - ), - left_intr_sclr( - (i^(-1)).first(), - (i^(-1)).first() + halo - 1 - ), - rght_intr_sclr( - (i^(-1)).last() - (halo - 1), - (i^(-1)).last() - ), - // vctr - left_halo_vctr( - (i^h^(halo-1)).first(), - (i^h^(halo-1)).first() + halo - 1 - ), - rght_halo_vctr( - (i^h^(halo-1)).last() - (halo - 1), - (i^h^(halo-1)).last() - ), - left_intr_vctr( - (i^h^(-1)).first(), - (i^h^(-1)).first() + halo - 1 - ), - rght_intr_vctr( - (i^h^(-1)).last() - (halo - 1), - (i^h^(-1)).last() - ) - {} + { + assert(false && "bcond::fill_halos_sgs_tnsr called!"); + }; + + virtual void fill_halos_vctr_nrml(arr_3d_t &, const rng_t &, const rng_t &) + { + assert(false && "bcond::fill_halos_vctr_nrml() called!"); + }; + + virtual void fill_halos_vctr_alng_cyclic(arrvec_t> &, const rng_t &, const rng_t &, const bool ad = false) + {}; + + virtual void fill_halos_vctr_nrml_cyclic(blitz::Array &, const rng_t &, const rng_t &) + {}; + + virtual void fill_halos_flux(arrvec_t> &, const rng_t &, const rng_t &) + {}; + + protected: + // sclr + int + left_edge_sclr, rght_edge_sclr; + rng_t + left_halo_sclr, rght_halo_sclr, + left_intr_sclr, rght_intr_sclr, + // vctr + left_halo_vctr, rght_halo_vctr, + left_intr_vctr, rght_intr_vctr; + + public: + + // ctor + bcond_common(const rng_t &i, const std::array &) : + // sclr + left_edge_sclr( + i.first() + ), + rght_edge_sclr( + i.last() + ), + left_halo_sclr( + (i^halo).first(), + (i^halo).first() + halo - 1 + ), + rght_halo_sclr( + (i^halo).last() - (halo - 1), + (i^halo).last() + ), + left_intr_sclr( + (i^(-1)).first(), + (i^(-1)).first() + halo - 1 + ), + rght_intr_sclr( + (i^(-1)).last() - (halo - 1), + (i^(-1)).last() + ), + // vctr + left_halo_vctr( + (i^h^(halo-1)).first(), + (i^h^(halo-1)).first() + halo - 1 + ), + rght_halo_vctr( + (i^h^(halo-1)).last() - (halo - 1), + (i^h^(halo-1)).last() + ), + left_intr_vctr( + (i^h^(-1)).first(), + (i^h^(-1)).first() + halo - 1 + ), + rght_intr_vctr( + (i^h^(-1)).last() - (halo - 1), + (i^h^(-1)).last() + ) + {} // the one for use in shared - bcond_common() + bcond_common() {} }; } // namespace detail diff --git a/libmpdata++/bcond/detail/polar_common.hpp b/libmpdata++/bcond/detail/polar_common.hpp index ccea1cb6..ebdb8326 100644 --- a/libmpdata++/bcond/detail/polar_common.hpp +++ b/libmpdata++/bcond/detail/polar_common.hpp @@ -13,35 +13,35 @@ namespace libmpdataxx { namespace bcond { - namespace detail + namespace detail { using namespace arakawa_c; template class polar_common : public bcond_common { - using parent_t = bcond_common; + using parent_t = bcond_common; - protected: + protected: - // member fields - const int pole; + // member fields + const int pole; - int polar_neighbours(const int j) - { - return (j + pole) % (2 * pole); - } + int polar_neighbours(const int j) + { + return (j + pole) % (2 * pole); + } - public: + public: - // ctor - polar_common( - const rng_t &i, + // ctor + polar_common( + const rng_t &i, const std::array &grid_size ) : - parent_t(i, grid_size), - pole((grid_size[0] - 1) / 2) - {} + parent_t(i, grid_size), + pole((grid_size[0] - 1) / 2) + {} }; } // namespace detail } // namespace bcond diff --git a/libmpdata++/bcond/detail/remote_common.hpp b/libmpdata++/bcond/detail/remote_common.hpp index 3bd64fac..2d2cfba7 100644 --- a/libmpdata++/bcond/detail/remote_common.hpp +++ b/libmpdata++/bcond/detail/remote_common.hpp @@ -22,11 +22,11 @@ namespace libmpdataxx template class remote_common : public detail::bcond_common { - using parent_t = detail::bcond_common; + using parent_t = detail::bcond_common; protected: - using arr_t = blitz::Array; + using arr_t = blitz::Array; using idx_t = blitz::RectDomain; private: @@ -54,46 +54,46 @@ namespace libmpdataxx # if !defined(NDEBUG) const int debug = 2; - std::pair buf_rng; + std::pair buf_rng; # endif #endif protected: - const bool is_cyclic = + const bool is_cyclic = #if defined(USE_MPI) - (dir == left && mpicom.rank() == 0) || - (dir == rght && mpicom.rank() == mpicom.size()-1); + (dir == left && mpicom.rank() == 0) || + (dir == rght && mpicom.rank() == mpicom.size()-1); #else false; #endif void send_hlpr( - const arr_t &a, - const idx_t &idx_send + const arr_t &a, + const idx_t &idx_send ) { #if defined(USE_MPI) - // distinguishing between left and right messages + // distinguishing between left and right messages // (important e.g. with 2 procs and cyclic bc) - const int + const int msg_send = dir == left ? left : rght; // arr_send references part of the send buffer that will be used arr_t arr_send(buf_send, a(idx_send).shape(), blitz::neverDeleteData); // copying data to be sent - arr_send = a(idx_send); + arr_send = a(idx_send); // launching async data transfer if(arr_send.size()!=0) { // use the pointer+size kind of send instead of serialization of blitz arrays, because // serialization caused memory leaks, probably because it breaks blitz reference counting - reqs[0] = mpicom.isend(peer, msg_send, buf_send, arr_send.size()); + reqs[0] = mpicom.isend(peer, msg_send, buf_send, arr_send.size()); // sending debug information # if !defined(NDEBUG) - reqs[1] = mpicom.isend(peer, msg_send ^ debug, std::pair( - idx_send[0].first(), + reqs[1] = mpicom.isend(peer, msg_send ^ debug, std::pair( + idx_send[0].first(), idx_send[0].last() )); # endif @@ -104,23 +104,23 @@ namespace libmpdataxx }; void recv_hlpr( - const arr_t &a, + const arr_t &a, const idx_t &idx_recv ) { #if defined(USE_MPI) - const int + const int msg_recv = dir == left ? rght : left; // launching async data transfer if(a(idx_recv).size()!=0) // TODO: test directly size of idx_recv { - reqs[1+n_dbg_reqs] = mpicom.irecv(peer, msg_recv, buf_recv, a(idx_recv).size()); + reqs[1+n_dbg_reqs] = mpicom.irecv(peer, msg_recv, buf_recv, a(idx_recv).size()); // sending debug information # if !defined(NDEBUG) - reqs[3] = mpicom.irecv(peer, msg_recv ^ debug, buf_rng); + reqs[3] = mpicom.irecv(peer, msg_recv ^ debug, buf_rng); # endif } #else @@ -129,22 +129,22 @@ namespace libmpdataxx } void send( - const arr_t &a, - const idx_t &idx_send + const arr_t &a, + const idx_t &idx_send ) { #if defined(USE_MPI) send_hlpr(a, idx_send); // waiting for the transfers to finish - boost::mpi::wait_all(reqs.begin(), reqs.begin() + 1 + n_dbg_reqs); // MPI_Waitall is thread-safe? + boost::mpi::wait_all(reqs.begin(), reqs.begin() + 1 + n_dbg_reqs); // MPI_Waitall is thread-safe? #else assert(false); #endif } void recv( - const arr_t &a, + const arr_t &a, const idx_t &idx_recv ) { @@ -153,28 +153,28 @@ namespace libmpdataxx recv_hlpr(a, idx_recv); // waiting for the transfers to finish - boost::mpi::wait_all(reqs.begin() + 1 + n_dbg_reqs, reqs.end()); // MPI_Waitall is thread-safe? + boost::mpi::wait_all(reqs.begin() + 1 + n_dbg_reqs, reqs.end()); // MPI_Waitall is thread-safe? // a blitz handler for the used part of the receive buffer arr_t arr_recv(buf_recv, a(idx_recv).shape(), blitz::neverDeleteData); // TODO: shape directly from idx_recv // checking debug information - + // positive modulo (grid_size_0 - 1) // auto wrap = [this](int n) {return (n % (grid_size_0 - 1) + grid_size_0 - 1) % (grid_size_0 - 1);}; // assert(wrap(buf_rng.first) == wrap(idx_recv[0].first())); // assert(wrap(buf_rng.second) == wrap(idx_recv[0].last())); // writing received data to the array - a(idx_recv) = arr_recv; + a(idx_recv) = arr_recv; #else assert(false); #endif } void xchng( - const arr_t &a, - const idx_t &idx_send, + const arr_t &a, + const idx_t &idx_send, const idx_t &idx_recv ) { @@ -183,20 +183,20 @@ namespace libmpdataxx recv_hlpr(a, idx_recv); // waiting for the transfers to finish - boost::mpi::wait_all(reqs.begin(), reqs.end()); + boost::mpi::wait_all(reqs.begin(), reqs.end()); // a blitz handler for the used part of the receive buffer arr_t arr_recv(buf_recv, a(idx_recv).shape(), blitz::neverDeleteData); // checking debug information - + // positive modulo (grid_size_0 - 1) // auto wrap = [this](int n) {return (n % (grid_size_0 - 1) + grid_size_0 - 1) % (grid_size_0 - 1);}; - // assert(wrap(buf_rng.first) == wrap(idx_recv[0].first())); + // assert(wrap(buf_rng.first) == wrap(idx_recv[0].first())); // assert(wrap(buf_rng.second) == wrap(idx_recv[0].last())); // writing received data to the array - a(idx_recv) = arr_recv; + a(idx_recv) = arr_recv; #else assert(false); #endif @@ -204,8 +204,8 @@ namespace libmpdataxx public: - // ctor - remote_common( + // ctor + remote_common( const rng_t &i, const std::array &grid_size ) : @@ -218,9 +218,9 @@ namespace libmpdataxx buf_send = (real_t *) malloc(halo * slice_size * sizeof(real_t)); buf_recv = (real_t *) malloc(halo * slice_size * sizeof(real_t)); #endif - } + } - // dtor + // dtor ~remote_common() { #if defined(USE_MPI) diff --git a/libmpdata++/bcond/gndsky_2d.hpp b/libmpdata++/bcond/gndsky_2d.hpp index 9a451e9f..4a032b78 100644 --- a/libmpdata++/bcond/gndsky_2d.hpp +++ b/libmpdata++/bcond/gndsky_2d.hpp @@ -13,14 +13,14 @@ namespace libmpdataxx { // ground template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == gndsky && dir == left && n_dims == 2 >::type > : public bcond - { + { using parent_t = bcond; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -32,7 +32,7 @@ namespace libmpdataxx using namespace idxperm; a(pi(this->left_edge_sclr - h, j)) = 2 * a(pi(this->left_edge_sclr + h, j)) - a(pi(this->left_edge_sclr + 1 + h, j)); } - + void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &b, const rng_t &j, const int offset = 0) { using namespace idxperm; @@ -41,16 +41,16 @@ namespace libmpdataxx const auto &a = av[offset + d]; a(pi(this->left_edge_sclr - h, j)) = 2 * b(pi(this->left_edge_sclr, j)) - a(pi(this->left_edge_sclr + h, j)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &u, const arr_t &div, const rng_t &j, const real_t di) { using namespace idxperm; const auto &a = av[d]; a(pi(this->left_edge_sclr - h, j)) = 2 * ( ( 3 * u(pi(this->left_edge_sclr + 1, j)) - - 2 * u(pi(this->left_edge_sclr, j)) - - u(pi(this->left_edge_sclr + 2, j)) + - 2 * u(pi(this->left_edge_sclr, j)) + - u(pi(this->left_edge_sclr + 2, j)) ) / di - - div(pi(this->left_edge_sclr - h, j)) + - div(pi(this->left_edge_sclr - h, j)) ); } }; diff --git a/libmpdata++/bcond/gndsky_3d.hpp b/libmpdata++/bcond/gndsky_3d.hpp index e6d5cc96..65499210 100644 --- a/libmpdata++/bcond/gndsky_3d.hpp +++ b/libmpdata++/bcond/gndsky_3d.hpp @@ -13,14 +13,14 @@ namespace libmpdataxx { // ground template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == gndsky && dir == left && n_dims == 3 >::type > : public bcond - { + { using parent_t = bcond; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -42,14 +42,14 @@ namespace libmpdataxx const auto &a = av[offset + d]; a(pi(this->left_edge_sclr - h, j, k)) = 2 * b(pi(this->left_edge_sclr, j, k)) - a(pi(this->left_edge_sclr + h, j, k)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &u, const arr_t &div, const rng_t &j, const rng_t &k, const real_t di) { using namespace idxperm; const auto &a = av[d]; a(pi(this->left_edge_sclr - h, j, k)) = 2 * ( ( 3 * u(pi(this->left_edge_sclr + 1, j, k)) - - 2 * u(pi(this->left_edge_sclr, j, k)) - - u(pi(this->left_edge_sclr + 2, j, k)) + - 2 * u(pi(this->left_edge_sclr, j, k)) + - u(pi(this->left_edge_sclr + 2, j, k)) ) / di - div(pi(this->left_edge_sclr - h, j, k)) ); diff --git a/libmpdata++/bcond/open_1d.hpp b/libmpdata++/bcond/open_1d.hpp index bcdbacc1..ceea4770 100644 --- a/libmpdata++/bcond/open_1d.hpp +++ b/libmpdata++/bcond/open_1d.hpp @@ -23,14 +23,14 @@ namespace libmpdataxx using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor - + public: void fill_halos_sclr(arr_t &a, const bool deriv = false) { for (int i = this->left_halo_sclr.first(); i <= this->left_halo_sclr.last(); ++i) { - if (deriv) + if (deriv) a(rng_t(i, i)) = 0; else a(rng_t(i, i)) = a(this->left_edge_sclr); @@ -40,7 +40,7 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const bool ad = false) { for (int i = this->left_halo_vctr.first(); i <= this->left_halo_vctr.last() - (ad ? 1 : 0); ++i) - av[0](rng_t(i, i)) = av[0](this->left_intr_vctr.first()); + av[0](rng_t(i, i)) = av[0](this->left_intr_vctr.first()); } }; @@ -56,14 +56,14 @@ namespace libmpdataxx using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor - + public: void fill_halos_sclr(arr_t &a, const bool deriv = false) { for (int i = this->rght_halo_sclr.first(); i <= this->rght_halo_sclr.last(); ++i) { - if (deriv) + if (deriv) a(rng_t(i, i)) = 0; else a(rng_t(i, i)) = a(this->rght_edge_sclr); @@ -73,7 +73,7 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const bool ad = false) { for (int i = this->rght_halo_vctr.first() + (ad ? 1 : 0); i <= this->rght_halo_vctr.last(); ++i) - av[0](rng_t(i, i)) = av[0](this->rght_intr_vctr.first()); + av[0](rng_t(i, i)) = av[0](this->rght_intr_vctr.first()); } }; } // namespace bcond diff --git a/libmpdata++/bcond/open_2d.hpp b/libmpdata++/bcond/open_2d.hpp index 055af9a7..8b165446 100644 --- a/libmpdata++/bcond/open_2d.hpp +++ b/libmpdata++/bcond/open_2d.hpp @@ -31,16 +31,16 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = this->left_halo_sclr.first(); i <= this->left_halo_sclr.last(); ++i) { if (deriv) - a(pi(i, j)) = 0; - else - a(pi(i, j)) = a(pi(this->left_edge_sclr, j)); // zero-gradient condition for scalar + a(pi(i, j)) = 0; + else + a(pi(i, j)) = a(pi(this->left_edge_sclr, j)); // zero-gradient condition for scalar } } - + void fill_halos_pres(arr_t &a, const rng_t &j) { using namespace idxperm; @@ -48,7 +48,7 @@ namespace libmpdataxx a(pi(this->left_halo_sclr.last(), j)) = 2 * a(pi(this->left_edge_sclr, j)) - a(pi(this->left_edge_sclr + 1, j)); } - + void save_edge_vel(const arr_t &a, const rng_t &j) { using namespace idxperm; @@ -58,12 +58,12 @@ namespace libmpdataxx if(d != 0) edge_velocity.reindexSelf({a.lbound(0), 0}); edge_velocity(pi(0, j)) = a(pi(this->left_edge_sclr, j)); } - + void set_edge_pres(arr_t &a, const rng_t &j, int sign) { using namespace idxperm; a(pi(this->left_edge_sclr, j)) = sign * edge_velocity(pi(0, j)); - + if (halo > 1) { a(pi(this->left_halo_sclr.last() - 1, j)) = 3 * a(pi(this->left_edge_sclr, j)) @@ -73,34 +73,34 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const bool ad = false) { - using namespace idxperm; - const int i = this->left_edge_sclr; - + using namespace idxperm; + const int i = this->left_edge_sclr; + // if executed first (d=0) this could contain NaNs - if (d == 0) + if (d == 0) { av[d+1](pi(i, (j-h).first())) = 0; av[d+1](pi(i, (j+h).last())) = 0; } - - // zero-divergence condition + + // zero-divergence condition for (int ii = this->left_halo_vctr.first(); ii <= this->left_halo_vctr.last() - (ad ? 1 : 0); ++ii) { - av[d](pi(ii, j)) = - av[d](pi(i+h, j)) + av[d](pi(ii, j)) = + av[d](pi(i+h, j)) -( - av[d+1](pi(i, j-h)) - - av[d+1](pi(i, j+h)) - ); + av[d+1](pi(i, j-h)) - + av[d+1](pi(i, j+h)) + ); } } void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) { - using namespace idxperm; + using namespace idxperm; // note intentional sclr for (int i = this->left_halo_sclr.first(); i <= this->left_halo_sclr.last(); ++i) - a(pi(i, j)) = 0; + a(pi(i, j)) = 0; } }; @@ -116,24 +116,24 @@ namespace libmpdataxx using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor - + // holds saved initial value of edge velocity arr_t edge_velocity; - + public: void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = this->rght_halo_sclr.first(); i <= this->rght_halo_sclr.last(); ++i) { - if (deriv) + if (deriv) a(pi(i, j)) = 0; // zero gradient for scalar gradient else a(pi(i, j)) = a(pi(this->rght_edge_sclr, j)); // zero gradient for scalar } } - + void fill_halos_pres(arr_t &a, const rng_t &j) { using namespace idxperm; @@ -147,7 +147,7 @@ namespace libmpdataxx } } - + void save_edge_vel(const arr_t &a, const rng_t &j) { using namespace idxperm; @@ -157,7 +157,7 @@ namespace libmpdataxx if(d != 0) edge_velocity.reindexSelf({a.lbound(0), 0}); edge_velocity(pi(0, j)) = a(pi(this->rght_edge_sclr, j)); } - + void set_edge_pres(arr_t &a, const rng_t &j, int sign) { using namespace idxperm; @@ -166,33 +166,33 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const bool ad = false) { - using namespace idxperm; - const int i = this->rght_edge_sclr; + using namespace idxperm; + const int i = this->rght_edge_sclr; // if executed first (d=0) this could contain NaNs - if (d == 0) + if (d == 0) { av[d+1](pi(i, (j-h).first())) = 0; av[d+1](pi(i, (j+h).last())) = 0; } - - // zero-divergence condition + + // zero-divergence condition for (int ii = this->rght_halo_vctr.first() + (ad ? 1 : 0); ii <= this->rght_halo_vctr.last(); ++ii) { - av[d](pi(ii, j)) = - av[d](pi(i-h, j)) + ( - av[d+1](pi(i, j-h)) - - av[d+1](pi(i, j+h)) - ); + av[d](pi(ii, j)) = + av[d](pi(i-h, j)) + ( + av[d+1](pi(i, j-h)) - + av[d+1](pi(i, j+h)) + ); } } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) { - using namespace idxperm; + using namespace idxperm; // note intentional sclr for (int i = this->rght_halo_sclr.first(); i <= this->rght_halo_sclr.last(); ++i) - a(pi(i, j)) = 0; + a(pi(i, j)) = 0; } }; } // namespace bcond diff --git a/libmpdata++/bcond/open_3d.hpp b/libmpdata++/bcond/open_3d.hpp index 064cfeb4..b621748a 100644 --- a/libmpdata++/bcond/open_3d.hpp +++ b/libmpdata++/bcond/open_3d.hpp @@ -12,18 +12,18 @@ namespace libmpdataxx namespace bcond { template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == open && dir == left && n_dims == 3 - >::type + >::type > : public detail::bcond_common - { + { using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor - + // holds saved initial value of edge velocity arr_t edge_velocity; @@ -31,16 +31,16 @@ namespace libmpdataxx void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = this->left_halo_sclr.first(); i <= this->left_halo_sclr.last(); ++i) { if (deriv) - a(pi(i, j, k)) = 0; + a(pi(i, j, k)) = 0; else - a(pi(i, j, k)) = a(pi(this->left_edge_sclr, j, k)); + a(pi(i, j, k)) = a(pi(this->left_edge_sclr, j, k)); } } - + void fill_halos_pres(arr_t &a, const rng_t &j, const rng_t &k) { using namespace idxperm; @@ -53,7 +53,7 @@ namespace libmpdataxx - 2 * a(pi(this->left_edge_sclr + 1, j, k)); } } - + void save_edge_vel(const arr_t &a, const rng_t &j, const rng_t &k) { using namespace idxperm; @@ -63,7 +63,7 @@ namespace libmpdataxx if(d != 0) edge_velocity.reindexSelf({a.lbound(0), 0, 0}); edge_velocity(pi(0, j, k)) = a(pi(this->left_edge_sclr, j, k)); } - + void set_edge_pres(arr_t &a, const rng_t &j, const rng_t &k, int sign) { using namespace idxperm; @@ -72,8 +72,8 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; - const int i = this->left_edge_sclr; + using namespace idxperm; + const int i = this->left_edge_sclr; // TODO: exactly the same code below! switch (d) // note: order and lack of breaks intentional! @@ -86,73 +86,73 @@ namespace libmpdataxx av[d+1](pi(i, (j-h).first(), k)) = 0; av[d+1](pi(i, (j+h).last(), k)) = 0; - case 2: + case 2: break; default: assert(false); } - assert(std::isfinite(sum(av[d ](pi(i+h, j, k))))); - assert(std::isfinite(sum(av[d+1](pi(i, j-h, k))))); - assert(std::isfinite(sum(av[d+1](pi(i, j+h, k))))); - assert(std::isfinite(sum(av[d+2](pi(i, j, k-h))))); - assert(std::isfinite(sum(av[d+2](pi(i, j, k+h))))); + assert(std::isfinite(sum(av[d ](pi(i+h, j, k))))); + assert(std::isfinite(sum(av[d+1](pi(i, j-h, k))))); + assert(std::isfinite(sum(av[d+1](pi(i, j+h, k))))); + assert(std::isfinite(sum(av[d+2](pi(i, j, k-h))))); + assert(std::isfinite(sum(av[d+2](pi(i, j, k+h))))); // zero-divergence condition for (int ii = this->left_halo_vctr.first(); ii <= this->left_halo_vctr.last() - (ad ? 1 : 0); ++ii) { - av[d](pi(ii, j, k)) = - av[d](pi(i+h, j, k)) + av[d](pi(ii, j, k)) = + av[d](pi(i+h, j, k)) -( - av[d+1](pi(i, j-h, k)) - - av[d+1](pi(i, j+h, k)) - ) + av[d+1](pi(i, j-h, k)) - + av[d+1](pi(i, j+h, k)) + ) -( av[d+2](pi(i, j, k-h)) - - av[d+2](pi(i, j, k+h)) + av[d+2](pi(i, j, k+h)) ); } } void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) { - using namespace idxperm; + using namespace idxperm; // note intentional sclr for (int i = this->left_halo_sclr.first(); i <= this->left_halo_sclr.last(); ++i) - a(pi(i, j, k)) = 0; + a(pi(i, j, k)) = 0; } }; template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == open && dir == rght && n_dims == 3 - >::type + >::type > : public detail::bcond_common - { + { using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor - + // holds saved initial value of edge velocity arr_t edge_velocity; - + public: void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = this->rght_halo_sclr.first(); i <= this->rght_halo_sclr.last(); ++i) { if (deriv) - a(pi(i, j, k)) = 0; + a(pi(i, j, k)) = 0; else - a(pi(i, j, k)) = a(pi(this->rght_edge_sclr, j, k)); + a(pi(i, j, k)) = a(pi(this->rght_edge_sclr, j, k)); } } - + void fill_halos_pres(arr_t &a, const rng_t &j, const rng_t &k) { using namespace idxperm; @@ -166,7 +166,7 @@ namespace libmpdataxx - 2 * a(pi(this->rght_edge_sclr - 1, j, k)); } } - + void save_edge_vel(const arr_t &a, const rng_t &j, const rng_t &k) { using namespace idxperm; @@ -176,7 +176,7 @@ namespace libmpdataxx if(d != 0) edge_velocity.reindexSelf({a.lbound(0), 0, 0}); edge_velocity(pi(0, j, k)) = a(pi(this->rght_edge_sclr, j, k)); } - + void set_edge_pres(arr_t &a, const rng_t &j, const rng_t &k, int sign) { using namespace idxperm; @@ -185,52 +185,52 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; + using namespace idxperm; const int i = this->rght_edge_sclr; switch (d) // note: order and lack of breaks intentional! { case 0: - av[d+2](pi(i, j, (k-h).first())) = 0; - av[d+2](pi(i, j, (k+h).last() )) = 0; + av[d+2](pi(i, j, (k-h).first())) = 0; + av[d+2](pi(i, j, (k+h).last() )) = 0; case 1: - av[d+1](pi(i, (j-h).first(), k)) = 0; - av[d+1](pi(i, (j+h).last(), k)) = 0; + av[d+1](pi(i, (j-h).first(), k)) = 0; + av[d+1](pi(i, (j+h).last(), k)) = 0; - case 2: + case 2: break; default: assert(false); } - assert(std::isfinite(sum(av[d ](pi(i-h, j, k))))); - assert(std::isfinite(sum(av[d+1](pi(i, j-h, k))))); - assert(std::isfinite(sum(av[d+1](pi(i, j+h, k))))); - assert(std::isfinite(sum(av[d+2](pi(i, j, k-h))))); - assert(std::isfinite(sum(av[d+2](pi(i, j, k+h))))); + assert(std::isfinite(sum(av[d ](pi(i-h, j, k))))); + assert(std::isfinite(sum(av[d+1](pi(i, j-h, k))))); + assert(std::isfinite(sum(av[d+1](pi(i, j+h, k))))); + assert(std::isfinite(sum(av[d+2](pi(i, j, k-h))))); + assert(std::isfinite(sum(av[d+2](pi(i, j, k+h))))); for (int ii = this->rght_halo_vctr.first() + (ad ? 1 : 0); ii <= this->rght_halo_vctr.last(); ++ii) { - av[d](pi(ii, j, k)) = - av[d](pi(i-h, j, k)) + av[d](pi(ii, j, k)) = + av[d](pi(i-h, j, k)) +( - av[d+1](pi(i, j-h, k)) - - av[d+1](pi(i, j+h, k)) + av[d+1](pi(i, j-h, k)) - + av[d+1](pi(i, j+h, k)) ) +( - av[d+2](pi(i, j, k-h)) - - av[d+2](pi(i, j, k+h)) + av[d+2](pi(i, j, k-h)) - + av[d+2](pi(i, j, k+h)) ); } } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) { - using namespace idxperm; + using namespace idxperm; // note intentional sclr for (int i = this->rght_halo_sclr.first(); i <= this->rght_halo_sclr.last(); ++i) - a(pi(i, j, k)) = 0; + a(pi(i, j, k)) = 0; } }; } // namespace bcond diff --git a/libmpdata++/bcond/polar_2d.hpp b/libmpdata++/bcond/polar_2d.hpp index ba41f577..0d87112f 100644 --- a/libmpdata++/bcond/polar_2d.hpp +++ b/libmpdata++/bcond/polar_2d.hpp @@ -12,14 +12,14 @@ namespace libmpdataxx namespace bcond { template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == polar && dir == left && n_dims == 2 - >::type + >::type > : public detail::polar_common - { + { using parent_t = detail::polar_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -29,31 +29,31 @@ namespace libmpdataxx // method invoked by the solver void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { a(pi(this->left_halo_sclr.last() - i, - jj)) + jj)) = a(pi(this->left_edge_sclr + i, this->polar_neighbours(jj))); - + } } } void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const bool ad = false) { - using namespace idxperm; - if (!ad) av[d](pi(this->left_halo_vctr.last(), j)) = 0; + using namespace idxperm; + if (!ad) av[d](pi(this->left_halo_vctr.last(), j)) = 0; if (halo > 1) { for (int jj = j.first(); jj <= j.last(); jj++) { - av[d](pi(this->left_halo_vctr.first(), jj)) - = + av[d](pi(this->left_halo_vctr.first(), jj)) + = av[d](pi(this->left_edge_sclr + h, this->polar_neighbours(jj))); } } @@ -61,31 +61,31 @@ namespace libmpdataxx void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { a(pi(this->left_halo_sclr.first() + i, - jj + h)) + jj + h)) = a(pi(this->left_intr_vctr.last() - i, this->polar_neighbours(jj) + h)); - + } } } }; template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == polar && dir == rght && n_dims == 2 >::type > : public detail::polar_common - { + { using parent_t = detail::polar_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -95,50 +95,50 @@ namespace libmpdataxx // method invoked by the solver void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { a(pi(this->rght_halo_sclr.first() + i, - jj)) + jj)) = a(pi(this->rght_edge_sclr - i, this->polar_neighbours(jj))); - + } } } void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const bool ad = false) { - using namespace idxperm; - if (!ad) av[d](pi(this->rght_halo_vctr.first(), j)) = 0; + using namespace idxperm; + if (!ad) av[d](pi(this->rght_halo_vctr.first(), j)) = 0; if (halo > 1) { for (int jj = j.first(); jj <= j.last(); jj++) { - av[d](pi(this->rght_halo_vctr.last(), jj)) + av[d](pi(this->rght_halo_vctr.last(), jj)) = - av[d](pi(this->rght_edge_sclr - h, this->polar_neighbours(jj))); + av[d](pi(this->rght_edge_sclr - h, this->polar_neighbours(jj))); } } } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { a(pi(this->rght_halo_sclr.first() + i, - jj + h)) + jj + h)) = a(pi(this->rght_intr_vctr.last() - i, this->polar_neighbours(jj) + h)); - + } } } diff --git a/libmpdata++/bcond/polar_3d.hpp b/libmpdata++/bcond/polar_3d.hpp index e67ebdbb..96b1ae4c 100644 --- a/libmpdata++/bcond/polar_3d.hpp +++ b/libmpdata++/bcond/polar_3d.hpp @@ -12,14 +12,14 @@ namespace libmpdataxx namespace bcond { template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == polar && dir == left && n_dims == 3 - >::type + >::type > : public detail::polar_common - { + { using parent_t = detail::polar_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -29,29 +29,29 @@ namespace libmpdataxx // method invoked by the solver void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { - a(pi(this->left_halo_sclr.last() - i, jj, k)) + a(pi(this->left_halo_sclr.last() - i, jj, k)) = a(pi(this->left_edge_sclr + i, this->polar_neighbours(jj), k)); - + } } } void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; - if (!ad) av[d](pi(this->left_halo_vctr.last(), j, k)) = 0; + using namespace idxperm; + if (!ad) av[d](pi(this->left_halo_vctr.last(), j, k)) = 0; if (halo > 1) { for (int jj = j.first(); jj <= j.last(); jj++) { - av[d](pi(this->left_halo_vctr.first(), jj, k)) - = + av[d](pi(this->left_halo_vctr.first(), jj, k)) + = av[d](pi(this->left_edge_sclr + h, this->polar_neighbours(jj), k)); } } @@ -59,12 +59,12 @@ namespace libmpdataxx void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { - a(pi(this->left_halo_sclr.first() + i, jj + h, k)) + a(pi(this->left_halo_sclr.first() + i, jj + h, k)) = a(pi(this->left_intr_vctr.last() - i, this->polar_neighbours(jj) + h, k)); } @@ -73,14 +73,14 @@ namespace libmpdataxx }; template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == polar && dir == rght && n_dims == 3 >::type > : public detail::polar_common - { + { using parent_t = detail::polar_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor @@ -90,13 +90,13 @@ namespace libmpdataxx // method invoked by the solver void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { - a(pi(this->rght_halo_sclr.first() + i, jj, k)) + a(pi(this->rght_halo_sclr.first() + i, jj, k)) = a(pi(this->rght_edge_sclr - i, this->polar_neighbours(jj), k)); } @@ -105,27 +105,27 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; - if (!ad) av[d](pi(this->rght_halo_vctr.first(), j, k)) = 0; + using namespace idxperm; + if (!ad) av[d](pi(this->rght_halo_vctr.first(), j, k)) = 0; if (halo > 1) { for (int jj = j.first(); jj <= j.last(); jj++) { - av[d](pi(this->rght_halo_vctr.last(), jj, k)) + av[d](pi(this->rght_halo_vctr.last(), jj, k)) = - av[d](pi(this->rght_edge_sclr - h, this->polar_neighbours(jj), k)); + av[d](pi(this->rght_edge_sclr - h, this->polar_neighbours(jj), k)); } } } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) { - using namespace idxperm; + using namespace idxperm; for (int i = 0; i < halo; ++i) - { + { for (int jj = j.first(); jj <= j.last(); jj++) { - a(pi(this->rght_halo_sclr.first() + i, jj + h, k)) + a(pi(this->rght_halo_sclr.first() + i, jj + h, k)) = a(pi(this->rght_intr_vctr.last() - i, this->polar_neighbours(jj) + h, k)); } diff --git a/libmpdata++/bcond/remote_1d.hpp b/libmpdata++/bcond/remote_1d.hpp index 4c250888..616faa78 100644 --- a/libmpdata++/bcond/remote_1d.hpp +++ b/libmpdata++/bcond/remote_1d.hpp @@ -11,11 +11,11 @@ namespace libmpdataxx { namespace bcond { - template + template class bcond< real_t, halo, knd, dir, n_dims, dim, typename std::enable_if< - knd == remote && - dir == left && + knd == remote && + dir == left && n_dims == 1 >::type > : public detail::remote_common @@ -39,26 +39,26 @@ namespace libmpdataxx { fill_halos_sclr(a); } - + void save_edge_vel(const arr_t &) {} void set_edge_pres(arr_t &, int) {} void fill_halos_vctr_alng(arrvec_t &av, const bool ad = false) { - if(!this->is_cyclic) + if(!this->is_cyclic) { if(halo == 1) - this->send(av[0], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off))); + this->send(av[0], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off))); else // processes fill vectors to the left of their domain - this->xchng(av[0], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t((this->left_halo_vctr^h)^(-1)))); + this->xchng(av[0], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t((this->left_halo_vctr^h)^(-1)))); } - else - // cyclic should communicate both ways - this->xchng(av[0], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->left_halo_vctr))); + else + // cyclic should communicate both ways + this->xchng(av[0], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->left_halo_vctr))); } - + void fill_halos_sgs_div(arr_t &a) { fill_halos_sclr(a); @@ -66,31 +66,31 @@ namespace libmpdataxx void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! - if(!this->is_cyclic) + if(!this->is_cyclic) { if(halo == 1) - this->send(av[0 + offset], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off))); + this->send(av[0 + offset], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off))); else // processes fill vectors to the left of their domain - this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t((this->left_halo_vctr^h)^(-1)))); + this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t((this->left_halo_vctr^h)^(-1)))); } - else - // cyclic should communicate both ways - this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->left_halo_vctr))); + else + // cyclic should communicate both ways + this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(this->left_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->left_halo_vctr))); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const real_t) { fill_halos_vctr_alng(av); } - void fill_halos_vctr_nrml(arr_t &a) - { - fill_halos_sclr(a); - } - + void fill_halos_vctr_nrml(arr_t &a) + { + fill_halos_sclr(a); + } + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const bool ad = false) { fill_halos_vctr_alng(av, ad); @@ -132,7 +132,7 @@ namespace libmpdataxx { fill_halos_sclr(a); } - + void save_edge_vel(const arr_t &) {} void set_edge_pres(arr_t &, int) {} @@ -140,17 +140,17 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const bool ad = false) { - if(!this->is_cyclic) + if(!this->is_cyclic) { if(halo == 1) - this->recv(av[0], idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); + this->recv(av[0], idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); else - this->xchng(av[0], idx_t(idx_ctor_arg_t(((this->rght_intr_vctr + off)^h)^(-1))), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); + this->xchng(av[0], idx_t(idx_ctor_arg_t(((this->rght_intr_vctr + off)^h)^(-1))), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); } else - this->xchng(av[0], idx_t(idx_ctor_arg_t(this->rght_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); + this->xchng(av[0], idx_t(idx_ctor_arg_t(this->rght_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); } - + void fill_halos_sgs_div(arr_t &a) { fill_halos_sclr(a); @@ -158,29 +158,29 @@ namespace libmpdataxx void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! - if(!this->is_cyclic) + if(!this->is_cyclic) { if(halo == 1) - this->recv(av[0 + offset], idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); + this->recv(av[0 + offset], idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); else - this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(((this->rght_intr_vctr + off)^h)^(-1))), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); + this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(((this->rght_intr_vctr + off)^h)^(-1))), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); } else - this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(this->rght_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); + this->xchng(av[0 + offset], idx_t(idx_ctor_arg_t(this->rght_intr_vctr + off)), idx_t(idx_ctor_arg_t(this->rght_halo_vctr))); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const real_t) { fill_halos_vctr_alng(av); } - void fill_halos_vctr_nrml(arr_t &a) - { - fill_halos_sclr(a); - } - + void fill_halos_vctr_nrml(arr_t &a) + { + fill_halos_sclr(a); + } + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const bool ad = false) { fill_halos_vctr_alng(av, ad); diff --git a/libmpdata++/bcond/remote_2d.hpp b/libmpdata++/bcond/remote_2d.hpp index 483f6de6..6c9f3460 100644 --- a/libmpdata++/bcond/remote_2d.hpp +++ b/libmpdata++/bcond/remote_2d.hpp @@ -11,11 +11,11 @@ namespace libmpdataxx { namespace bcond { - template + template class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< - knd == remote && - dir == left && + knd == remote && + dir == left && n_dims == 2 >::type > : public detail::remote_common @@ -38,7 +38,7 @@ namespace libmpdataxx { fill_halos_sclr(a, j); } - + void save_edge_vel(const arr_t &, const rng_t &) {} void set_edge_pres(arr_t &, const rng_t &, int) {} @@ -47,7 +47,7 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const bool ad = false) { using namespace idxperm; - if(!this->is_cyclic) + if(!this->is_cyclic) { if(halo == 1) // send vectors to the left of the domain @@ -59,7 +59,7 @@ namespace libmpdataxx else this->xchng(av[0], pi(this->left_intr_vctr + off, j), pi(this->left_halo_vctr, j)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j) { fill_halos_sclr(a, j); @@ -67,9 +67,9 @@ namespace libmpdataxx void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! - if(!this->is_cyclic) + if(!this->is_cyclic) { if(halo == 1) // send vectors to the left of the domain @@ -81,7 +81,7 @@ namespace libmpdataxx else this->xchng(av[0 + offset], pi(this->left_intr_vctr + off, j), pi(this->left_halo_vctr, j)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const real_t) { fill_halos_vctr_alng(av, j); @@ -90,11 +90,11 @@ namespace libmpdataxx // TODO: sgs fill_halos // TODO: move to common? (same in cyclic!) - void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) - { - fill_halos_sclr(a, j); - } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) + { + fill_halos_sclr(a, j); + } + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const bool ad = false) { fill_halos_vctr_alng(av, j, ad); @@ -134,7 +134,7 @@ namespace libmpdataxx { fill_halos_sclr(a, j); } - + void save_edge_vel(const arr_t &, const rng_t &) {} void set_edge_pres(arr_t &, const rng_t &, int) {} @@ -154,7 +154,7 @@ namespace libmpdataxx else this->xchng(av[0], pi(this->rght_intr_vctr + off, j), pi(this->rght_halo_vctr, j)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j) { fill_halos_sclr(a, j); @@ -162,7 +162,7 @@ namespace libmpdataxx void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! if(!this->is_cyclic) { @@ -176,18 +176,18 @@ namespace libmpdataxx else this->xchng(av[0 + offset], pi(this->rght_intr_vctr + off, j), pi(this->rght_halo_vctr, j)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const real_t) { fill_halos_vctr_alng(av, j); } // TODO: move to common? (same in cyclic!) - void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) - { - fill_halos_sclr(a, j); - } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) + { + fill_halos_sclr(a, j); + } + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const bool ad = false) { fill_halos_vctr_alng(av, j, ad); diff --git a/libmpdata++/bcond/remote_3d.hpp b/libmpdata++/bcond/remote_3d.hpp index 89564ff5..cbac8bb5 100644 --- a/libmpdata++/bcond/remote_3d.hpp +++ b/libmpdata++/bcond/remote_3d.hpp @@ -11,11 +11,11 @@ namespace libmpdataxx { namespace bcond { - template + template class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< - knd == remote && - dir == left && + knd == remote && + dir == left && n_dims == 3 >::type > : public detail::remote_common @@ -39,9 +39,9 @@ namespace libmpdataxx { fill_halos_sclr(a, j, k); } - + void save_edge_vel(const arr_t &, const rng_t &, const rng_t &) {} - + void set_edge_pres(arr_t &, const rng_t &, const rng_t &, int) {} @@ -59,15 +59,15 @@ namespace libmpdataxx else this->xchng(av[0], pi(this->left_intr_vctr + off, j, k), pi(this->left_halo_vctr, j, k)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j, const rng_t &k) { fill_halos_sclr(a, j, k); } - + void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const rng_t &k, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! if(!this->is_cyclic) { @@ -80,18 +80,18 @@ namespace libmpdataxx else this->xchng(av[0 + offset], pi(this->left_intr_vctr + off, j, k), pi(this->left_halo_vctr, j, k)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const rng_t &k, const real_t) { fill_halos_vctr_alng(av, j, k); } // TODO: move to common? (same in cyclic!) - void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) - { - fill_halos_sclr(a, j, k); - } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) + { + fill_halos_sclr(a, j, k); + } + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { fill_halos_vctr_alng(av, j, k, ad); @@ -131,9 +131,9 @@ namespace libmpdataxx { fill_halos_sclr(a, j, k); } - + void save_edge_vel(const arr_t &, const rng_t &, const rng_t &) {} - + void set_edge_pres(arr_t &, const rng_t &, const rng_t &, int) {} @@ -143,22 +143,22 @@ namespace libmpdataxx if(!this->is_cyclic) { if(halo == 1) - this->recv(av[0], pi(this->rght_halo_vctr, j, k)); + this->recv(av[0], pi(this->rght_halo_vctr, j, k)); else this->xchng(av[0], pi(((this->rght_intr_vctr + off)^h)^(-1), j, k), pi(this->rght_halo_vctr, j, k)); } else this->xchng(av[0], pi(this->rght_intr_vctr + off, j, k), pi(this->rght_halo_vctr, j, k)); } - + void fill_halos_sgs_div(arr_t &a, const rng_t &j, const rng_t &k) { fill_halos_sclr(a, j, k); } - + void fill_halos_sgs_vctr(arrvec_t &av, const arr_t &, const rng_t &j, const rng_t &k, const int offset = 0) { - using namespace idxperm; + using namespace idxperm; // the same logic as fill_halos_vctr_alng but have to consider offset ... TODO: find a way to reuse ! if(!this->is_cyclic) { @@ -170,18 +170,18 @@ namespace libmpdataxx else this->xchng(av[0 + offset], pi(this->rght_intr_vctr + off, j, k), pi(this->rght_halo_vctr, j, k)); } - + void fill_halos_sgs_tnsr(arrvec_t &av, const arr_t &, const arr_t &, const rng_t &j, const rng_t &k, const real_t) { fill_halos_vctr_alng(av, j, k); } // TODO: move to common? (same in cyclic!) - void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) - { - fill_halos_sclr(a, j, k); + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) + { + fill_halos_sclr(a, j, k); } - + void fill_halos_vctr_alng_cyclic(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { fill_halos_vctr_alng(av, j, k, ad); diff --git a/libmpdata++/bcond/rigid_2d.hpp b/libmpdata++/bcond/rigid_2d.hpp index 998eb6c1..c1867a7b 100644 --- a/libmpdata++/bcond/rigid_2d.hpp +++ b/libmpdata++/bcond/rigid_2d.hpp @@ -12,20 +12,20 @@ namespace libmpdataxx namespace bcond { template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == rigid && dir == left && n_dims == 2 >::type > : public detail::bcond_common - { + { using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor public: - + void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { using namespace idxperm; @@ -35,7 +35,7 @@ namespace libmpdataxx a(pi(i, j)) = a(pi(this->left_edge_sclr + n, j)); } } - + void fill_halos_pres(arr_t &a, const rng_t &j) { using namespace idxperm; @@ -45,10 +45,10 @@ namespace libmpdataxx a(pi(i, j)) = 2 * a(pi(this->left_edge_sclr, j)) - a(pi(this->left_edge_sclr + n, j)); } - } + } void save_edge_vel(const arr_t &, const rng_t &) {} - + void set_edge_pres(arr_t &a, const rng_t &j, int) { using namespace idxperm; @@ -70,7 +70,7 @@ namespace libmpdataxx // note intentional sclr fill_halos_sclr(a, j); } - + void fill_halos_flux(arrvec_t &av, const rng_t &j) { using namespace idxperm; @@ -103,7 +103,7 @@ namespace libmpdataxx }; template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == rigid && dir == rght && @@ -114,9 +114,9 @@ namespace libmpdataxx using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor - + public: - + void fill_halos_sclr(arr_t &a, const rng_t &j, const bool deriv = false) { // zero flux condition @@ -126,7 +126,7 @@ namespace libmpdataxx a(pi(i, j)) = a(pi(this->rght_edge_sclr - n, j)); // zero gradient for scalar gradient } } - + void fill_halos_pres(arr_t &a, const rng_t &j) { using namespace idxperm; @@ -137,9 +137,9 @@ namespace libmpdataxx - a(pi(this->rght_edge_sclr - n, j)); } } - + void save_edge_vel(const arr_t &, const rng_t &) {} - + void set_edge_pres(arr_t &a, const rng_t &j, int) { using namespace idxperm; @@ -155,13 +155,13 @@ namespace libmpdataxx av[d](pi(i, j)) = -av[d](pi(this->rght_edge_sclr - n + h, j)); } } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j) { // note intentional sclr fill_halos_sclr(a, j); } - + void fill_halos_flux(arrvec_t &av, const rng_t &j) { using namespace idxperm; diff --git a/libmpdata++/bcond/rigid_3d.hpp b/libmpdata++/bcond/rigid_3d.hpp index 413d5706..2c683a68 100644 --- a/libmpdata++/bcond/rigid_3d.hpp +++ b/libmpdata++/bcond/rigid_3d.hpp @@ -12,20 +12,20 @@ namespace libmpdataxx namespace bcond { template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == rigid && dir == left && n_dims == 3 >::type > : public detail::bcond_common - { + { using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor public: - + void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { using namespace idxperm; @@ -35,7 +35,7 @@ namespace libmpdataxx a(pi(i, j, k)) = a(pi(this->left_edge_sclr + n, j, k)); } } - + void fill_halos_pres(arr_t &a, const rng_t &j, const rng_t &k) { using namespace idxperm; @@ -46,9 +46,9 @@ namespace libmpdataxx - a(pi(this->left_edge_sclr + n, j, k)); } } - + void save_edge_vel(const arr_t &, const rng_t &, const rng_t &) {} - + void set_edge_pres(arr_t &a, const rng_t &j, const rng_t &k, int) { using namespace idxperm; @@ -57,11 +57,11 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; + using namespace idxperm; // zero velocity condition for (int i = this->left_halo_vctr.first(), n = halo; i <= this->left_halo_vctr.last() - (ad ? 1 : 0); ++i, --n) { - av[d](pi(i, j, k)) = -av[d](pi(this->left_edge_sclr + n - h, j, k)); + av[d](pi(i, j, k)) = -av[d](pi(this->left_edge_sclr + n - h, j, k)); } } @@ -70,12 +70,12 @@ namespace libmpdataxx // note intentional sclr fill_halos_sclr(a, j, k); } - + void fill_halos_flux(arrvec_t &av, const rng_t &j, const rng_t &k) { - using namespace idxperm; + using namespace idxperm; // zero flux condition - av[d](pi(this->left_halo_vctr.last(), j, k)) = -av[d](pi(this->left_edge_sclr + h, j, k)); + av[d](pi(this->left_halo_vctr.last(), j, k)) = -av[d](pi(this->left_edge_sclr + h, j, k)); } void fill_halos_sgs_div(arr_t &a, const rng_t &j, const rng_t &k) @@ -104,7 +104,7 @@ namespace libmpdataxx }; template - class bcond< real_t, halo, knd, dir, n_dims, d, + class bcond< real_t, halo, knd, dir, n_dims, d, typename std::enable_if< knd == rigid && dir == rght && @@ -115,9 +115,9 @@ namespace libmpdataxx using parent_t = detail::bcond_common; using arr_t = blitz::Array; using parent_t::parent_t; // inheriting ctor - + public: - + void fill_halos_sclr(arr_t &a, const rng_t &j, const rng_t &k, const bool deriv = false) { // zero flux condition @@ -127,10 +127,10 @@ namespace libmpdataxx a(pi(i, j, k)) = a(pi(this->rght_edge_sclr - n, j, k)); // zero gradient for scalar gradient } } - - + + void save_edge_vel(const arr_t &, const rng_t &, const rng_t &) {} - + void fill_halos_pres(arr_t &a, const rng_t &j, const rng_t &k) { using namespace idxperm; @@ -141,7 +141,7 @@ namespace libmpdataxx - a(pi(this->rght_edge_sclr - n, j, k)); } } - + void set_edge_pres(arr_t &a, const rng_t &j, const rng_t &k, int) { using namespace idxperm; @@ -150,25 +150,25 @@ namespace libmpdataxx void fill_halos_vctr_alng(arrvec_t &av, const rng_t &j, const rng_t &k, const bool ad = false) { - using namespace idxperm; + using namespace idxperm; // zero velocity condition for (int i = this->rght_halo_vctr.first() + (ad ? 1 : 0), n = 1; i <= this->rght_halo_vctr.last(); ++i, ++n) { - av[d](pi(i, j, k)) = -av[d](pi(this->rght_edge_sclr - n + h, j, k)); + av[d](pi(i, j, k)) = -av[d](pi(this->rght_edge_sclr - n + h, j, k)); } } - + void fill_halos_vctr_nrml(arr_t &a, const rng_t &j, const rng_t &k) { // note intentional sclr fill_halos_sclr(a, j, k); } - + void fill_halos_flux(arrvec_t &av, const rng_t &j, const rng_t &k) { - using namespace idxperm; + using namespace idxperm; // zero flux condition - av[d](pi(this->rght_halo_vctr.first(), j, k)) = -av[d](pi(this->rght_edge_sclr - h, j, k)); + av[d](pi(this->rght_halo_vctr.first(), j, k)) = -av[d](pi(this->rght_edge_sclr - h, j, k)); } void fill_halos_sgs_div(arr_t &a, const rng_t &j, const rng_t &k) diff --git a/libmpdata++/bcond/shared.hpp b/libmpdata++/bcond/shared.hpp index f41f2bc2..c677d077 100644 --- a/libmpdata++/bcond/shared.hpp +++ b/libmpdata++/bcond/shared.hpp @@ -15,9 +15,9 @@ namespace libmpdataxx class shared : public detail::bcond_common { public: - + using parent_t = detail::bcond_common; - + using arr_1d_t = typename parent_t::arr_1d_t; using arr_2d_t = typename parent_t::arr_2d_t; using arr_3d_t = typename parent_t::arr_3d_t; @@ -28,7 +28,7 @@ namespace libmpdataxx virtual void fill_halos_pres(arr_2d_t &, const rng_t &) { }; virtual void fill_halos_pres(arr_3d_t &, const rng_t &, const rng_t &) { }; - + virtual void save_edge_vel(const arr_2d_t &, const rng_t &) { }; virtual void save_edge_vel(const arr_3d_t &, const rng_t &, const rng_t &) { }; @@ -37,17 +37,17 @@ namespace libmpdataxx virtual void fill_halos_vctr_alng(arrvec_t &, const bool) { }; virtual void fill_halos_vctr_alng(arrvec_t &, const rng_t &, const bool) { }; - virtual void fill_halos_vctr_alng(arrvec_t &, const rng_t &, const rng_t &, const bool) { }; - + virtual void fill_halos_vctr_alng(arrvec_t &, const rng_t &, const rng_t &, const bool) { }; + virtual void fill_halos_vctr_nrml(arr_2d_t &, const rng_t &) { }; virtual void fill_halos_vctr_nrml(arr_3d_t &, const rng_t &, const rng_t &) { }; - + virtual void fill_halos_sgs_div(arr_2d_t &, const rng_t &) { }; virtual void fill_halos_sgs_div(arr_3d_t &, const rng_t &, const rng_t &) { }; - + virtual void fill_halos_sgs_vctr(arrvec_t &, const arr_2d_t &, const rng_t &, const int offset = 0) { }; virtual void fill_halos_sgs_vctr(arrvec_t &, const arr_3d_t &, const rng_t &, const rng_t &, const int offset = 0) { }; - + virtual void fill_halos_sgs_tnsr(arrvec_t &, const arr_2d_t &, const arr_2d_t &, const rng_t &, const real_t) { }; virtual void fill_halos_sgs_tnsr(arrvec_t &, const arr_3d_t &, const arr_3d_t &, const rng_t &, const rng_t &, const real_t) { }; diff --git a/libmpdata++/blitz.hpp b/libmpdata++/blitz.hpp index b23bb5a3..606b0996 100644 --- a/libmpdata++/blitz.hpp +++ b/libmpdata++/blitz.hpp @@ -18,7 +18,7 @@ // force use of #pragma ivdep even if Blitz thinks the compiler does not support it // (as of gcc 20140212, it gives an ICE: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60198) - TODO: check in CMake -//#define BZ_USE_ALIGNMENT_PRAGMAS +//#define BZ_USE_ALIGNMENT_PRAGMAS //#if defined(USE_MPI) //# define BZ_HAVE_BOOST_SERIALIZATION @@ -27,7 +27,7 @@ #include // otherwise Clang fails in debug mode #include - + #include ////////////////////////////////////////////////////////// @@ -46,7 +46,7 @@ { \ init \ return safeToReturn(expr); \ -} +} namespace libmpdataxx { @@ -73,31 +73,31 @@ namespace libmpdataxx { using type = typename expr_t::T_numtype; }; - + template struct real_t_helper { using type = expr_t; }; - // Boost ptr_vector + // Boost ptr_vector template - struct arrvec_t : boost::ptr_vector + struct arrvec_t : boost::ptr_vector { using parent_t = boost::ptr_vector; - const arr_t &operator[](const int i) const - { + const arr_t &operator[](const int i) const + { return this->at( - (i + this->size()) % this->size() - ); + (i + this->size()) % this->size() + ); } - + arr_t &operator[](const int i) - { + { return this->at( (i + this->size()) % this->size() - ); + ); } void push_back(arr_t *arr) @@ -107,8 +107,8 @@ namespace libmpdataxx #if !defined(NDEBUG) // filling the array with NaNs to ease debugging *arr = blitz::has_signalling_NaN(*arr->dataFirst()) - ? blitz::signalling_NaN(*arr->dataFirst()) - : blitz::quiet_NaN(*arr->dataFirst()); + ? blitz::signalling_NaN(*arr->dataFirst()) + : blitz::quiet_NaN(*arr->dataFirst()); #endif } }; diff --git a/libmpdata++/concurr/any.hpp b/libmpdata++/concurr/any.hpp index 8d8e9d9d..3285ff4f 100644 --- a/libmpdata++/concurr/any.hpp +++ b/libmpdata++/concurr/any.hpp @@ -15,57 +15,57 @@ namespace libmpdataxx template struct any { - virtual - void advance(advance_arg_t) - { assert(false); throw; } + virtual + void advance(advance_arg_t) + { assert(false); throw; } - virtual + virtual blitz::Array advectee(int eqn = 0) { assert(false); throw; } - virtual + virtual const blitz::Array advectee_global(int eqn = 0) { assert(false); throw; } - virtual + virtual void advectee_global_set(const blitz::Array, int eqn = 0) { assert(false); throw; } - virtual - blitz::Array advector(int dim = 0) + virtual + blitz::Array advector(int dim = 0) { assert(false); throw; } - virtual - blitz::Array g_factor() + virtual + blitz::Array g_factor() { assert(false); throw; } - - virtual - blitz::Array vab_coefficient() + + virtual + blitz::Array vab_coefficient() { assert(false); throw; } - - virtual - blitz::Array vab_relaxed_state(int d = 0) + + virtual + blitz::Array vab_relaxed_state(int d = 0) { assert(false); throw; } - - virtual + + virtual blitz::Array sclr_array(const std::string &name, int n = 0) { assert(false); throw; } - virtual - bool *panic_ptr() + virtual + bool *panic_ptr() { assert(false && "unimplemented!"); throw; } - - virtual + + virtual const real_t time() const { assert(false); throw; } - + // minimum of an advectee, mpi-aware - virtual + virtual const real_t min(int eqn = 0) const { assert(false); throw; } - + // maximum of an advectee, mpi-aware - virtual + virtual const real_t max(int eqn = 0) const { assert(false); throw; } diff --git a/libmpdata++/concurr/boost_thread.hpp b/libmpdata++/concurr/boost_thread.hpp index f4e55685..83675a7c 100644 --- a/libmpdata++/concurr/boost_thread.hpp +++ b/libmpdata++/concurr/boost_thread.hpp @@ -29,38 +29,38 @@ namespace libmpdataxx class boost_thread : public detail::concurr_common { using parent_t = detail::concurr_common; - - class mem_t : public parent_t::mem_t + + class mem_t : public parent_t::mem_t { boost::barrier b; public: - static int size(const unsigned max_threads = std::numeric_limits::max()) - { - const char *env_var("OMP_NUM_THREADS"); + static int size(const unsigned max_threads = std::numeric_limits::max()) + { + const char *env_var("OMP_NUM_THREADS"); int nthreads = std::min((std::getenv(env_var) != NULL) ? std::atoi(std::getenv(env_var)) // TODO: check if conversion OK? - : boost::thread::hardware_concurrency() + : boost::thread::hardware_concurrency() , max_threads); - return nthreads; - } + return nthreads; + } // ctor mem_t(const std::array &grid_size) : b(size(grid_size[0])), - parent_t::mem_t(grid_size, size(grid_size[0])) - {}; + parent_t::mem_t(grid_size, size(grid_size[0])) + {}; - void barrier() - { + void barrier() + { // TODO: if (size() != 1) ??? - b.wait(); - } + b.wait(); + } }; public: @@ -68,8 +68,8 @@ namespace libmpdataxx void solve(typename parent_t::advance_arg_t nt) { boost::thread_group threads; - for (int i = 0; i < this->algos.size(); ++i) - { + for (int i = 0; i < this->algos.size(); ++i) + { std::unique_ptr thp; thp.reset(new boost::thread( &solver_t::solve, boost::ref(this->algos[i]), nt @@ -80,7 +80,7 @@ namespace libmpdataxx } // ctor - boost_thread(const typename solver_t::rt_params_t &p) : + boost_thread(const typename solver_t::rt_params_t &p) : parent_t(p, new mem_t(p.grid_size), mem_t::size(p.grid_size[0])) {} diff --git a/libmpdata++/concurr/cxx11_thread.hpp b/libmpdata++/concurr/cxx11_thread.hpp index 78418fe4..b89a556e 100644 --- a/libmpdata++/concurr/cxx11_thread.hpp +++ b/libmpdata++/concurr/cxx11_thread.hpp @@ -26,21 +26,21 @@ namespace libmpdataxx // based on boost barrier's code class barrier { - std::mutex m_mutex; - std::condition_variable m_cond; - std::size_t m_generation, m_count; + std::mutex m_mutex; + std::condition_variable m_cond; + std::size_t m_generation, m_count; const std::size_t m_threshold; - public: + public: - explicit barrier(const std::size_t count) : - m_count(count), + explicit barrier(const std::size_t count) : + m_count(count), m_threshold(count), - m_generation(0) + m_generation(0) { } - bool wait() - { + bool wait() + { std::unique_lock lock(m_mutex); unsigned int gen = m_generation; @@ -55,7 +55,7 @@ namespace libmpdataxx while (gen == m_generation) m_cond.wait(lock); return false; - } + } }; }; @@ -71,36 +71,36 @@ namespace libmpdataxx class cxx11_thread : public detail::concurr_common { using parent_t = detail::concurr_common; - - class mem_t : public parent_t::mem_t + + class mem_t : public parent_t::mem_t { detail::barrier b; public: - static int size(const unsigned max_threads = std::numeric_limits::max()) - { - const char *env_var("OMP_NUM_THREADS"); + static int size(const unsigned max_threads = std::numeric_limits::max()) + { + const char *env_var("OMP_NUM_THREADS"); int nthreads = std::min((std::getenv(env_var) != NULL) ? std::atoi(std::getenv(env_var)) // TODO: check if conversion OK? - : std::thread::hardware_concurrency() + : std::thread::hardware_concurrency() , max_threads); - return nthreads; - } + return nthreads; + } // ctor mem_t(const std::array &grid_size) : b(size(grid_size[0])), - parent_t::mem_t(grid_size, size(grid_size[0])) - {}; + parent_t::mem_t(grid_size, size(grid_size[0])) + {}; - void barrier() - { - b.wait(); - } + void barrier() + { + b.wait(); + } }; public: @@ -108,8 +108,8 @@ namespace libmpdataxx void solve(typename parent_t::advance_arg_t nt) { boost::ptr_vector threads(mem_t::size()); - for (int i = 0; i < this->algos.size(); ++i) - { + for (int i = 0; i < this->algos.size(); ++i) + { threads.push_back(new std::thread( &solver_t::solve, &(this->algos[i]), nt )); @@ -118,7 +118,7 @@ namespace libmpdataxx } // ctor - cxx11_thread(const typename solver_t::rt_params_t &p) : + cxx11_thread(const typename solver_t::rt_params_t &p) : parent_t(p, new mem_t(p.grid_size), mem_t::size(p.grid_size[0])) {} diff --git a/libmpdata++/concurr/detail/concurr_common.hpp b/libmpdata++/concurr/detail/concurr_common.hpp index 4c24dde3..691e4ff0 100644 --- a/libmpdata++/concurr/detail/concurr_common.hpp +++ b/libmpdata++/concurr/detail/concurr_common.hpp @@ -41,7 +41,7 @@ namespace libmpdataxx namespace detail { template< - class solver_t_, + class solver_t_, bcond::bcond_e bcxl, bcond::bcond_e bcxr, bcond::bcond_e bcyl, bcond::bcond_e bcyr, bcond::bcond_e bczl, bcond::bcond_e bczr @@ -51,24 +51,24 @@ namespace libmpdataxx public: typedef solver_t_ solver_t; - + static_assert( (solver_t::n_dims == 3) || - (solver_t::n_dims == 2 - && bczl == bcond::null + (solver_t::n_dims == 2 + && bczl == bcond::null && bczr == bcond::null ) || - (solver_t::n_dims == 1 - && bczl == bcond::null + (solver_t::n_dims == 1 + && bczl == bcond::null && bczr == bcond::null - && bcyl == bcond::null + && bcyl == bcond::null && bcyr == bcond::null ) , "more boundary conditions than dimensions" ); - protected: + protected: // (cannot be nested due to templates) typedef sharedmem< @@ -77,38 +77,38 @@ namespace libmpdataxx solver_t::n_tlev > mem_t; - // member fields - boost::ptr_vector algos; + // member fields + boost::ptr_vector algos; std::unique_ptr mem; timer tmr; - public: + public: typedef typename solver_t::real_t real_t; using advance_arg_t = typename solver_t::advance_arg_t; // dtor - virtual ~concurr_common() + virtual ~concurr_common() { tmr.print(); } - // ctor - concurr_common( - const typename solver_t::rt_params_t &p, + // ctor + concurr_common( + const typename solver_t::rt_params_t &p, mem_t *mem_p, - const int &size - ) { + const int &size + ) { // allocate the memory to be shared by multiple threads mem.reset(mem_p); - solver_t::alloc(mem.get(), p.n_iters); + solver_t::alloc(mem.get(), p.n_iters); // allocate per-thread structures - init(p, mem->grid_size, size); + init(p, mem->grid_size, size); } private: - + template < bcond::bcond_e type, bcond::drctn_e dir, @@ -116,31 +116,31 @@ namespace libmpdataxx > void bc_set( typename solver_t::bcp_t &bcp - ) + ) { // sanity check - polar coords do not work with MPI yet - if (type == bcond::polar && mem->distmem.size() > 1) + if (type == bcond::polar && mem->distmem.size() > 1) throw std::runtime_error("Polar boundary conditions do not work with MPI."); // distmem overrides - if (type != bcond::remote && mem->distmem.size() > 1 && dim == 0) - { - if ( - // distmem domain interior - (dir == bcond::left && mem->distmem.rank() > 0) - || - (dir == bcond::rght && mem->distmem.rank() != mem->distmem.size() - 1) - // cyclic condition for distmem domain (note: will not work if a non-cyclic condition is on the other end) - || - (type == bcond::cyclic) - ) return bc_set(bcp); - } + if (type != bcond::remote && mem->distmem.size() > 1 && dim == 0) + { + if ( + // distmem domain interior + (dir == bcond::left && mem->distmem.rank() > 0) + || + (dir == bcond::rght && mem->distmem.rank() != mem->distmem.size() - 1) + // cyclic condition for distmem domain (note: will not work if a non-cyclic condition is on the other end) + || + (type == bcond::cyclic) + ) return bc_set(bcp); + } // bc allocation, all mpi routines called by the remote bcnd ctor are thread-safe (?) - bcp.reset( + bcp.reset( new bcond::bcond( - mem->slab(mem->grid_size[dim]), - mem->distmem.grid_size + mem->slab(mem->grid_size[dim]), + mem->distmem.grid_size ) ); } @@ -154,46 +154,46 @@ namespace libmpdataxx typename solver_t::bcp_t bxl, bxr, shrdl, shrdr; bc_set(bxl); - bc_set(bxr); + bc_set(bxr); - for (int i0 = 0; i0 < n0; ++i0) + for (int i0 = 0; i0 < n0; ++i0) { shrdl.reset(new bcond::shared()); shrdr.reset(new bcond::shared()); - algos.push_back( + algos.push_back( new solver_t( typename solver_t::ctor_args_t({ i0, - mem.get(), - i0 == 0 ? bxl : shrdl, - i0 == n0 - 1 ? bxr : shrdr, - mem->slab(grid_size[0], i0, n0) - }), + mem.get(), + i0 == 0 ? bxl : shrdl, + i0 == n0 - 1 ? bxr : shrdr, + mem->slab(grid_size[0], i0, n0) + }), p ) ); } - } + } // 2D version // TODO: assert parallelisation in the right dimensions! (blitz::assertContiguous) void init( const typename solver_t::rt_params_t &p, - const std::array &grid_size, + const std::array &grid_size, const int &n0, const int &n1 = 1 ) { - for (int i0 = 0; i0 < n0; ++i0) + for (int i0 = 0; i0 < n0; ++i0) { - for (int i1 = 0; i1 < n1; ++i1) + for (int i1 = 0; i1 < n1; ++i1) { - typename solver_t::bcp_t bxl, bxr, byl, byr, shrdl, shrdr; + typename solver_t::bcp_t bxl, bxr, byl, byr, shrdl, shrdr; bc_set(bxl); - bc_set(bxr); + bc_set(bxr); bc_set(byl); - bc_set(byr); + bc_set(byr); shrdl.reset(new bcond::shared()); // TODO: shrdy if n1 != 1 shrdr.reset(new bcond::shared()); // TODO: shrdy if n1 != 1 @@ -202,34 +202,34 @@ namespace libmpdataxx new solver_t( typename solver_t::ctor_args_t({ i0, - mem.get(), - i0 == 0 ? bxl : shrdl, - i0 == n0 - 1 ? bxr : shrdr, - byl, byr, - mem->slab(grid_size[0], i0, n0), + mem.get(), + i0 == 0 ? bxl : shrdl, + i0 == n0 - 1 ? bxr : shrdr, + byl, byr, + mem->slab(grid_size[0], i0, n0), mem->slab(grid_size[1], i1, n1) - }), + }), p ) ); } } - } + } // 3D version void init( const typename solver_t::rt_params_t &p, - const std::array &grid_size, + const std::array &grid_size, const int &n0, const int &n1 = 1, const int &n2 = 1 ) { typename solver_t::bcp_t bxl, bxr, byl, byr, bzl, bzr, shrdl, shrdr; - // TODO: renew pointers only if invalid ? - for (int i0 = 0; i0 < n0; ++i0) + // TODO: renew pointers only if invalid ? + for (int i0 = 0; i0 < n0; ++i0) { - for (int i1 = 0; i1 < n1; ++i1) + for (int i1 = 0; i1 < n1; ++i1) { - for (int i2 = 0; i2 < n2; ++i2) + for (int i2 = 0; i2 < n2; ++i2) { bc_set(bxl); bc_set(bxr); @@ -243,19 +243,19 @@ namespace libmpdataxx shrdl.reset(new bcond::shared()); // TODO: shrdy if n1 != 1 shrdr.reset(new bcond::shared()); // TODO: shrdy if n1 != 1 - algos.push_back( + algos.push_back( new solver_t( typename solver_t::ctor_args_t({ i0, - mem.get(), - i0 == 0 ? bxl : shrdl, - i0 == n0 - 1 ? bxr : shrdr, - byl, byr, - bzl, bzr, - mem->slab(grid_size[0], i0, n0), - mem->slab(grid_size[1], i1, n1), + mem.get(), + i0 == 0 ? bxl : shrdl, + i0 == n0 - 1 ? bxr : shrdr, + byl, byr, + bzl, bzr, + mem->slab(grid_size[0], i0, n0), + mem->slab(grid_size[1], i1, n1), mem->slab(grid_size[2], i2, n2) - }), + }), p ) ); @@ -267,61 +267,61 @@ namespace libmpdataxx virtual void solve(advance_arg_t nt) = 0; public: - + void advance(advance_arg_t nt) final - { + { tmr.resume(); solve(nt); tmr.stop(); - } + } - typename solver_t::arr_t advectee(int e = 0) final - { - return mem->advectee(e); - } + typename solver_t::arr_t advectee(int e = 0) final + { + return mem->advectee(e); + } - const typename solver_t::arr_t advectee_global(int e = 0) final - { + const typename solver_t::arr_t advectee_global(int e = 0) final + { #if defined(USE_MPI) return mem->advectee_global(e); #else - return advectee(e); + return advectee(e); #endif - } + } - void advectee_global_set(const typename solver_t::arr_t arr, int e = 0) final - { + void advectee_global_set(const typename solver_t::arr_t arr, int e = 0) final + { #if defined(USE_MPI) mem->advectee_global_set(arr, e); #else - advectee(e) = arr; + advectee(e) = arr; #endif - } + } - typename solver_t::arr_t advector(int d = 0) final - { - return mem->advector(d); - } + typename solver_t::arr_t advector(int d = 0) final + { + return mem->advector(d); + } - typename solver_t::arr_t g_factor() final - { - return mem->g_factor(); - } + typename solver_t::arr_t g_factor() final + { + return mem->g_factor(); + } typename solver_t::arr_t vab_coefficient() final - { - return mem->vab_coefficient(); - } - + { + return mem->vab_coefficient(); + } + typename solver_t::arr_t vab_relaxed_state(int d = 0) final - { - return mem->vab_relaxed_state(d); - } - + { + return mem->vab_relaxed_state(d); + } + typename solver_t::arr_t sclr_array(const std::string &name, int n = 0) final - { - return mem->sclr_array(name, n); - } + { + return mem->sclr_array(name, n); + } bool *panic_ptr() final { @@ -333,15 +333,15 @@ namespace libmpdataxx return algos[0].time_(); } - const real_t min(int e = 0) const final - { - return mem->min(mem->advectee(e)); - } + const real_t min(int e = 0) const final + { + return mem->min(mem->advectee(e)); + } - const real_t max(int e = 0) const final - { - return mem->max(mem->advectee(e)); - } + const real_t max(int e = 0) const final + { + return mem->max(mem->advectee(e)); + } }; } // namespace detail } // namespace concurr diff --git a/libmpdata++/concurr/detail/distmem.hpp b/libmpdata++/concurr/detail/distmem.hpp index ace2aa87..a73b8f5c 100644 --- a/libmpdata++/concurr/detail/distmem.hpp +++ b/libmpdata++/concurr/detail/distmem.hpp @@ -49,8 +49,8 @@ namespace libmpdataxx std::array grid_size; - int rank() - { + int rank() + { #if defined(USE_MPI) return mpicom.rank(); // is it thread-safe? TODO: init once in ctor? #else @@ -58,7 +58,7 @@ namespace libmpdataxx #endif } - int size() + int size() { #if defined(USE_MPI) return mpicom.size(); // is it thread-safe? TODO: init once in ctor? @@ -102,8 +102,8 @@ namespace libmpdataxx } // ctor - distmem(const std::array &grid_size) - : grid_size(grid_size) + distmem(const std::array &grid_size) + : grid_size(grid_size) { #if !defined(USE_MPI) if ( diff --git a/libmpdata++/concurr/detail/sharedmem.hpp b/libmpdata++/concurr/detail/sharedmem.hpp index 926881f0..cf927d6a 100644 --- a/libmpdata++/concurr/detail/sharedmem.hpp +++ b/libmpdata++/concurr/detail/sharedmem.hpp @@ -26,15 +26,15 @@ namespace libmpdataxx typename real_t, int n_dims, int n_tlev - > + > class sharedmem_common { - using arr_t = blitz::Array; + using arr_t = blitz::Array; static_assert(n_dims > 0, "n_dims <= 0"); static_assert(n_tlev > 0, "n_tlev <= 0"); - std::unique_ptr> xtmtmp; + std::unique_ptr> xtmtmp; std::unique_ptr> sumtmp; protected: @@ -45,7 +45,7 @@ namespace libmpdataxx int n = 0; const int size; - std::array grid_size; + std::array grid_size; bool panic = false; // for multi-threaded SIGTERM handling detail::distmem distmem; @@ -58,13 +58,13 @@ namespace libmpdataxx arrvec_t vab_relax; // velocity absorber relaxed state arrvec_t khn_tmp; // Kahan sum for donor-cell - std::unordered_map< + std::unordered_map< const char*, // intended for addressing with __FILE__ boost::ptr_vector> > tmp; - + // list of temporary fields that can be accessed from outside of concurr - std::unordered_map< + std::unordered_map< std::string, std::pair > avail_tmp; @@ -73,7 +73,7 @@ namespace libmpdataxx { assert(false && "sharedmem_common::barrier() called!"); } - + void cycle(const int &rank) { barrier(); @@ -86,7 +86,7 @@ namespace libmpdataxx sharedmem_common(const std::array &grid_size, const int &size) : n(0), distmem(grid_size), size(size) // TODO: is n(0) needed? { - for (int d = 0; d < n_dims; ++d) + for (int d = 0; d < n_dims; ++d) { this->grid_size[d] = slab( rng_t(0, grid_size[d]-1), @@ -100,10 +100,10 @@ namespace libmpdataxx oss << "grid_size[0]: " << this->grid_size[0] << " origin[0]: " << origin[0] << std::endl; std::cerr << oss.str() << std::endl; - if (size > grid_size[0]) + if (size > grid_size[0]) throw std::runtime_error("number of subdomains greater than number of gridpoints"); - if (n_dims != 1) + if (n_dims != 1) sumtmp.reset(new blitz::Array(this->grid_size[0])); xtmtmp.reset(new blitz::Array(size)); } @@ -111,7 +111,7 @@ namespace libmpdataxx /// @brief concurrency-aware summation of array elements double sum(const int &rank, const arr_t &arr, const idx_t &ijk, const bool sum_khn) { - // doing a two-step sum to reduce numerical error + // doing a two-step sum to reduce numerical error // and make parallel results reproducible for (int c = ijk[0].first(); c <= ijk[0].last(); ++c) // TODO: optimise for i.count() == 1 { @@ -134,7 +134,7 @@ namespace libmpdataxx barrier(); return result; #else - if(rank == 0) + if(rank == 0) { // master thread calculates the sum from this process, stores in shared array if (sum_khn) @@ -154,7 +154,7 @@ namespace libmpdataxx /// @brief concurrency-aware summation of a (element-wise) product of two arrays double sum(const int &rank, const arr_t &arr1, const arr_t &arr2, const idx_t &ijk, const bool sum_khn) { - // doing a two-step sum to reduce numerical error + // doing a two-step sum to reduce numerical error // and make parallel results reproducible for (int c = ijk[0].first(); c <= ijk[0].last(); ++c) { @@ -165,7 +165,7 @@ namespace libmpdataxx if (sum_khn) (*sumtmp)(c) = blitz::kahan_sum(arr1(slice_idx) * arr2(slice_idx)); else - (*sumtmp)(c) = blitz::sum(arr1(slice_idx) * arr2(slice_idx)); + (*sumtmp)(c) = blitz::sum(arr1(slice_idx) * arr2(slice_idx)); } // TODO: code below same as in the function above barrier(); // wait for all threads to calc their part @@ -178,7 +178,7 @@ namespace libmpdataxx barrier(); return result; #else - if(rank == 0) + if(rank == 0) { // master thread calculates the sum from this process, stores in shared array if (sum_khn) @@ -198,7 +198,7 @@ namespace libmpdataxx real_t min(const int &rank, const arr_t &arr) { // min across local threads - (*xtmtmp)(rank) = blitz::min(arr); + (*xtmtmp)(rank) = blitz::min(arr); barrier(); #if !defined(USE_MPI) real_t result = blitz::min(*xtmtmp); @@ -222,7 +222,7 @@ namespace libmpdataxx real_t max(const int &rank, const arr_t &arr) { // max across local threads - (*xtmtmp)(rank) = blitz::max(arr); + (*xtmtmp)(rank) = blitz::max(arr); barrier(); #if !defined(USE_MPI) real_t result = blitz::max(*xtmtmp); @@ -265,7 +265,7 @@ namespace libmpdataxx // and hence to not use BZ_THREADSAFE private: boost::ptr_vector tobefreed; - + public: arr_t *never_delete(arr_t *arg) { @@ -283,21 +283,21 @@ namespace libmpdataxx private: // helper methods to define subdomain ranges - static int min(const int &span, const int &rank, const int &size) + static int min(const int &span, const int &rank, const int &size) { - return rank * span / size; + return rank * span / size; } - static int max(const int &span, const int &rank, const int &size) + static int max(const int &span, const int &rank, const int &size) { - return min(span, rank + 1, size) - 1; + return min(span, rank + 1, size) - 1; } public: static rng_t slab( const rng_t &span, - const int &rank = 0, - const int &size = 1 + const int &rank = 0, + const int &size = 1 ) { return rng_t( span.first() + min(span.length(), rank, size), @@ -308,7 +308,7 @@ namespace libmpdataxx virtual arr_t advectee(int e = 0) = 0; void advectee_global_set(const arr_t arr, int e = 0) - { + { #if defined(USE_MPI) if(this->distmem.size() > 1) { @@ -317,7 +317,7 @@ namespace libmpdataxx else #endif advectee(e) = arr; - } + } protected: @@ -353,7 +353,7 @@ namespace libmpdataxx } const blitz::Array advectee_global(int e = 0) - { + { #if defined(USE_MPI) if(this->distmem.size() > 1) { @@ -366,7 +366,7 @@ namespace libmpdataxx for(auto &size : sizes) { size = this->slab(rng_t(0, this->distmem.grid_size[0]-1), size, this->distmem.size()).length();} // calc displacement std::vector displ(sizes.size()); - std::partial_sum(sizes.begin(), sizes.end(), displ.begin()); + std::partial_sum(sizes.begin(), sizes.end(), displ.begin()); std::transform(displ.begin(), displ.end(), sizes.begin(), displ.begin(), std::minus()); // exclusive_scan is c++17 // a vector that will store the received data, relevant only on process rank=0 std::vector out_values(this->distmem.grid_size[0]); @@ -385,18 +385,18 @@ namespace libmpdataxx else #endif return advectee(e); - } + } - blitz::Array advector(int d = 0) - { + blitz::Array advector(int d = 0) + { using namespace arakawa_c; assert(d == 0); // returning just the domain interior, i.e. without halos // reindexed to make it more intuitive when working with index placeholders // (i.e. border between cell 0 and cell 1 is indexed with 0) auto orgn = decltype(this->origin)({ - this->origin[0] - 1 - }); + this->origin[0] - 1 + }); return this->GC[d]( this->distmem_ext(this->grid_size[0]^(-1)^h) @@ -405,12 +405,12 @@ namespace libmpdataxx ? decltype(this->origin)({this->origin[0] - 1}) : orgn ); - } + } blitz::Array g_factor() { // a sanity check - if (this->G.get() == nullptr) + if (this->G.get() == nullptr) throw std::runtime_error("g_factor() called with nug option unset?"); // the same logic as in advectee() - see above @@ -418,17 +418,17 @@ namespace libmpdataxx this->grid_size[0] ).reindex(this->origin); } - + blitz::Array vab_coefficient() { throw std::logic_error("absorber not yet implemented in 1d"); } - - blitz::Array vab_relaxed_state(int d = 0) - { + + blitz::Array vab_relaxed_state(int d = 0) + { throw std::logic_error("absorber not yet implemented in 1d"); - } - + } + blitz::Array sclr_array(const std::string& name, int n = 0) { return this->tmp.at(this->avail_tmp[name].first)[this->avail_tmp[name].second][n]( @@ -456,7 +456,7 @@ namespace libmpdataxx } const blitz::Array advectee_global(int e = 0) - { + { #if defined(USE_MPI) if(this->distmem.size() > 1) { @@ -466,14 +466,14 @@ namespace libmpdataxx // a vector of number of elements to be sent by each non-root process std::vector sizes(this->distmem.size()); std::iota(sizes.begin(), sizes.end(), 0); // fill with 1,2,3,... - for(auto &size : sizes) - { + for(auto &size : sizes) + { size = this->slab(rng_t(0, this->distmem.grid_size[0]-1), size, this->distmem.size()).length() * this->grid_size[1].length(); } // calc displacement std::vector displ(sizes.size()); - std::partial_sum(sizes.begin(), sizes.end(), displ.begin()); + std::partial_sum(sizes.begin(), sizes.end(), displ.begin()); std::transform(displ.begin(), displ.end(), sizes.begin(), displ.begin(), std::minus()); // exclusive_scan is c++17 // a vector that will store the received data, relevant only on process rank=0 std::vector out_values(this->distmem.grid_size[0] * this->grid_size[1].length()); @@ -485,7 +485,7 @@ namespace libmpdataxx boost::mpi::gatherv(this->distmem.mpicom, in_values_vec, out_values.data(), sizes, displ, 0); // send the result to other processes boost::mpi::broadcast(this->distmem.mpicom, out_values, 0); - + blitz::Array res(out_values.data(), blitz::shape( this->distmem.grid_size[0], this->grid_size[1].length()), blitz::duplicateData); @@ -494,39 +494,39 @@ namespace libmpdataxx else #endif return advectee(e); - } + } - blitz::Array advector(int d = 0) - { + blitz::Array advector(int d = 0) + { using namespace arakawa_c; assert(d == 0 || d== 1); // returning just the domain interior, i.e. without halos // reindexed to make it more intuitive when working with index placeholders auto orgn = decltype(this->origin)({ - this->origin[0] - 1, + this->origin[0] - 1, this->origin[1] - }); + }); switch (d) - { - case 0: + { + case 0: return this->GC[d]( - this->distmem_ext(this->grid_size[0]^(-1)^h), + this->distmem_ext(this->grid_size[0]^(-1)^h), this->grid_size[1] - ).reindex(orgn); - case 1: + ).reindex(orgn); + case 1: return this->GC[d]( - this->distmem_ext(this->grid_size[0]), + this->distmem_ext(this->grid_size[0]), this->grid_size[1]^(-1)^h ).reindex(orgn); default: assert(false); throw; } - } + } blitz::Array g_factor() { // a sanity check - if (this->G.get() == nullptr) + if (this->G.get() == nullptr) throw std::runtime_error("g_factor() called with nug option unset?"); // the same logic as in advectee() - see above @@ -535,11 +535,11 @@ namespace libmpdataxx this->grid_size[1] ).reindex(this->origin); } - + blitz::Array vab_coefficient() { // a sanity check - if (this->vab_coeff.get() == nullptr) + if (this->vab_coeff.get() == nullptr) throw std::runtime_error("vab_coeff() called with option vip_vab unset?"); // the same logic as in advectee() - see above @@ -548,20 +548,20 @@ namespace libmpdataxx this->grid_size[1] ).reindex(this->origin); } - - blitz::Array vab_relaxed_state(int d = 0) - { + + blitz::Array vab_relaxed_state(int d = 0) + { assert(d == 0 || d== 1); // a sanity check - if (this->vab_coeff.get() == nullptr) + if (this->vab_coeff.get() == nullptr) throw std::runtime_error("vab_relaxed_state() called with option vip_vab unset?"); // the same logic as in advectee() - see above return this->vab_relax[d]( this->grid_size[0], this->grid_size[1] ).reindex(this->origin); - } - + } + blitz::Array sclr_array(const std::string& name, int n = 0) { return this->tmp.at(this->avail_tmp[name].first)[this->avail_tmp[name].second][n]( @@ -591,7 +591,7 @@ namespace libmpdataxx } const blitz::Array advectee_global(int e = 0) - { + { #if defined(USE_MPI) if(this->distmem.size() > 1) { @@ -601,14 +601,14 @@ namespace libmpdataxx // a vector of number of elements to be sent by each non-root process std::vector sizes(this->distmem.size()); std::iota(sizes.begin(), sizes.end(), 0); // fill with 1,2,3,... - for(auto &size : sizes) - { + for(auto &size : sizes) + { size = this->slab(rng_t(0, this->distmem.grid_size[0]-1), size, this->distmem.size()).length() * this->grid_size[1].length() * this->grid_size[2].length(); } // calc displacement std::vector displ(sizes.size()); - std::partial_sum(sizes.begin(), sizes.end(), displ.begin()); + std::partial_sum(sizes.begin(), sizes.end(), displ.begin()); std::transform(displ.begin(), displ.end(), sizes.begin(), displ.begin(), std::minus()); // exclusive_scan is c++17 // a vector that will store the received data, relevant only on process rank=0 std::vector out_values(this->distmem.grid_size[0] * this->grid_size[1].length() * this->grid_size[2].length()); @@ -620,7 +620,7 @@ namespace libmpdataxx boost::mpi::gatherv(this->distmem.mpicom, in_values_vec, out_values.data(), sizes, displ, 0); // send the result to other processes boost::mpi::broadcast(this->distmem.mpicom, out_values, 0); - + blitz::Array res(out_values.data(), blitz::shape( this->distmem.grid_size[0], this->grid_size[1].length(), this->grid_size[2].length()), blitz::duplicateData); @@ -629,48 +629,48 @@ namespace libmpdataxx else #endif return advectee(e); - } + } - blitz::Array advector(int d = 0) - { + blitz::Array advector(int d = 0) + { using namespace arakawa_c; assert(d == 0 || d == 1 || d == 2); // returning just the domain interior, i.e. without halos // reindexed to make it more intuitive when working with index placeholders auto orgn = decltype(this->origin)({ - this->origin[0] - 1, + this->origin[0] - 1, this->origin[1], this->origin[2] - }); + }); switch (d) - { - case 0: + { + case 0: return this->GC[d]( this->distmem_ext(this->grid_size[0]^(-1)^h), this->grid_size[1], this->grid_size[2] - ).reindex(orgn); - case 1: + ).reindex(orgn); + case 1: return this->GC[d]( this->distmem_ext(this->grid_size[0]), this->grid_size[1]^(-1)^h, this->grid_size[2] - ).reindex(orgn); - case 2: + ).reindex(orgn); + case 2: return this->GC[d]( this->distmem_ext(this->grid_size[0]), this->grid_size[1], this->grid_size[2]^(-1)^h - ).reindex(orgn); + ).reindex(orgn); default: assert(false); throw; } - } + } blitz::Array g_factor() { // a sanity check - if (this->G.get() == nullptr) + if (this->G.get() == nullptr) throw std::runtime_error("g_factor() called with nug option unset?"); // the same logic as in advectee() - see above @@ -684,7 +684,7 @@ namespace libmpdataxx blitz::Array vab_coefficient() { // a sanity check - if (this->vab_coeff.get() == nullptr) + if (this->vab_coeff.get() == nullptr) throw std::runtime_error("vab_coeff() called with option vip_vab unset?"); // the same logic as in advectee() - see above @@ -694,12 +694,12 @@ namespace libmpdataxx this->grid_size[2] ).reindex(this->origin); } - - blitz::Array vab_relaxed_state(int d = 0) - { + + blitz::Array vab_relaxed_state(int d = 0) + { assert(d == 0 || d == 1 || d == 2); // a sanity check - if (this->vab_coeff.get() == nullptr) + if (this->vab_coeff.get() == nullptr) throw std::runtime_error("vab_relaxed_state() called with option vip_vab unset?"); // the same logic as in advectee() - see above return this->vab_relax[d]( @@ -707,7 +707,7 @@ namespace libmpdataxx this->grid_size[1], this->grid_size[2] ).reindex(this->origin); - } + } blitz::Array sclr_array(const std::string& name, int n = 0) { diff --git a/libmpdata++/concurr/detail/timer.hpp b/libmpdata++/concurr/detail/timer.hpp index 5e4af1e5..10d8d190 100644 --- a/libmpdata++/concurr/detail/timer.hpp +++ b/libmpdata++/concurr/detail/timer.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -14,15 +14,15 @@ namespace libmpdataxx { namespace concurr { - namespace detail + namespace detail { - class timer + class timer { - std::unique_ptr tmr; + std::unique_ptr tmr; bool started = false; public: - + // ctor timer() { @@ -30,9 +30,9 @@ namespace libmpdataxx } void resume() - { + { if (started) tmr->resume(); - else + else { started = true; tmr->start(); @@ -41,18 +41,18 @@ namespace libmpdataxx void stop() { - tmr->stop(); + tmr->stop(); } void print() { - boost::timer::cpu_times t = tmr->elapsed(); - std::ostringstream tmp; - tmp << " wall time: " << double(t.wall) * 1e-9 << "s"; - tmp << " user time: " << double(t.user) * 1e-9 << "s"; - tmp << " system time: " << double(t.system) * 1e-9 << "s"; - std::cerr << tmp.str() << std::endl; - } + boost::timer::cpu_times t = tmr->elapsed(); + std::ostringstream tmp; + tmp << " wall time: " << double(t.wall) * 1e-9 << "s"; + tmp << " user time: " << double(t.user) * 1e-9 << "s"; + tmp << " system time: " << double(t.system) * 1e-9 << "s"; + std::cerr << tmp.str() << std::endl; + } }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/concurr/openmp.hpp b/libmpdata++/concurr/openmp.hpp index b86c9af3..24f7c78b 100644 --- a/libmpdata++/concurr/openmp.hpp +++ b/libmpdata++/concurr/openmp.hpp @@ -30,26 +30,26 @@ namespace libmpdataxx class openmp : public detail::concurr_common { using parent_t = detail::concurr_common; - + struct mem_t : parent_t::mem_t { - static int size(const unsigned max_threads = std::numeric_limits::max()) - { + static int size(const unsigned max_threads = std::numeric_limits::max()) + { #if defined(_OPENMP) - const char *env_var("OMP_NUM_THREADS"); + const char *env_var("OMP_NUM_THREADS"); - int nthreads = std::min(max_threads, static_cast( + int nthreads = std::min(max_threads, static_cast( (std::getenv(env_var) != NULL) ? std::atoi(std::getenv(env_var)) : omp_get_max_threads() )); omp_set_num_threads(nthreads); - return omp_get_max_threads(); + return omp_get_max_threads(); #else - return 1; + return 1; #endif - } + } void barrier() { @@ -70,13 +70,13 @@ namespace libmpdataxx i = omp_get_thread_num(); #endif this->algos[i].solve(nt); - } + } } public: // ctor - openmp(const typename solver_t::rt_params_t &p) : + openmp(const typename solver_t::rt_params_t &p) : parent_t(p, new mem_t(p.grid_size), mem_t::size(p.grid_size[0])) {} diff --git a/libmpdata++/concurr/serial.hpp b/libmpdata++/concurr/serial.hpp index 887d4f9c..f6abc1ea 100644 --- a/libmpdata++/concurr/serial.hpp +++ b/libmpdata++/concurr/serial.hpp @@ -24,17 +24,17 @@ namespace libmpdataxx class serial : public detail::concurr_common { using parent_t = detail::concurr_common; - + struct mem_t : parent_t::mem_t { - static int size() { return 1; } + static int size() { return 1; } void barrier() { } // ctors - mem_t(const std::array &grid_size) - : parent_t::mem_t(grid_size, size()) + mem_t(const std::array &grid_size) + : parent_t::mem_t(grid_size, size()) {}; }; @@ -46,7 +46,7 @@ namespace libmpdataxx public: // ctor - serial(const typename solver_t::rt_params_t &p) : + serial(const typename solver_t::rt_params_t &p) : parent_t(p, new mem_t(p.grid_size), mem_t::size()) {} diff --git a/libmpdata++/concurr/threads.hpp b/libmpdata++/concurr/threads.hpp index 164b8219..2da9488e 100644 --- a/libmpdata++/concurr/threads.hpp +++ b/libmpdata++/concurr/threads.hpp @@ -18,8 +18,8 @@ namespace libmpdataxx { namespace concurr { - /// @brief shared-memory concurency logic using threads - /// (\ref libmpdataxx::concurr::openmp if supported, + /// @brief shared-memory concurency logic using threads + /// (\ref libmpdataxx::concurr::openmp if supported, /// \ref libmpdataxx::concurr::boost_thread otherwise) template < class solver_t, @@ -29,7 +29,7 @@ namespace libmpdataxx bcond::bcond_e bcyr = bcond::null, bcond::bcond_e bczl = bcond::null, bcond::bcond_e bczr = bcond::null - > using threads = + > using threads = #if defined(_OPENMP) openmp; #else diff --git a/libmpdata++/formulae/arakawa_c.hpp b/libmpdata++/formulae/arakawa_c.hpp index 6c3e3b43..631f0d63 100644 --- a/libmpdata++/formulae/arakawa_c.hpp +++ b/libmpdata++/formulae/arakawa_c.hpp @@ -14,41 +14,41 @@ namespace libmpdataxx { namespace { - struct hlf_t {} h; + struct hlf_t {} h; inline rng_t operator+( const rng_t &i, const hlf_t & - ) { - return i; - } + ) { + return i; + } inline rng_t operator-( const rng_t &i, const hlf_t & - ) { - return i-1; + ) { + return i-1; } - + inline int operator+( const int i, const hlf_t & - ) { - return i; - } + ) { + return i; + } inline int operator-( const int i, const hlf_t & - ) { - return i-1; + ) { + return i-1; } template inline rng_t operator^( const rng_t &r, const n_t &n - ) { + ) { return rng_t( - (r - n).first(), + (r - n).first(), (r + n).last() - ); - } + ); + } }; } // namespace arakawa_c } // namespace libmpdataxx diff --git a/libmpdata++/formulae/common.hpp b/libmpdata++/formulae/common.hpp index 3b9846b6..800839c2 100644 --- a/libmpdata++/formulae/common.hpp +++ b/libmpdata++/formulae/common.hpp @@ -25,7 +25,7 @@ namespace libmpdataxx { return std::abs(a); } - + template forceinline_macro auto abs(const arg_t &a, typename std::enable_if::value>::type* = 0) { @@ -38,7 +38,7 @@ namespace libmpdataxx using cm_t = typename std::common_type::type; return std::min(static_cast(a), static_cast(b)); } - + template forceinline_macro auto min(const a_t &a, const b_t &b, typename std::enable_if::value>::type* = 0) { @@ -51,34 +51,34 @@ namespace libmpdataxx using cm_t = typename std::common_type::type; return std::max(static_cast(a), static_cast(b)); } - + template forceinline_macro auto max(const a_t &a, const b_t &b, typename std::enable_if::value>::type* = 0) { return blitz::max(a, b); } - + // variadic max & min template forceinline_macro auto max(const a_t &a, const b_ts & ... bs) { return max(a, max(bs...)); } - + template forceinline_macro auto min(const a_t &a, const b_ts & ... bs) { return min(a, min(bs...)); } - + template - forceinline_macro auto where(bool c, const arg_t &a, const arg_t &b, typename std::enable_if::value>::type* = 0) + forceinline_macro auto where(bool c, const arg_t &a, const arg_t &b, typename std::enable_if::value>::type* = 0) { return c ? a : b; } - + template - forceinline_macro auto where(c_t c, const a_t &a, const b_t &b, typename std::enable_if::value>::type* = 0) + forceinline_macro auto where(c_t c, const a_t &a, const b_t &b, typename std::enable_if::value>::type* = 0) { return blitz::where(c, a, b); } @@ -130,7 +130,7 @@ namespace libmpdataxx const ix_t &, typename std::enable_if::type* = 0 // enabled if nug == false ) { - return 1; + return 1; } // 2D: G = const = 1 @@ -140,7 +140,7 @@ namespace libmpdataxx const ix_t &, const ix_t &, typename std::enable_if::type* = 0 // enabled if nug == false ) { - return 1; + return 1; } // 3D: G = const = 1 @@ -150,7 +150,7 @@ namespace libmpdataxx const ix_t &, const ix_t &, const ix_t &, typename std::enable_if::type* = 0 // enabled if nug == false ) { - return 1; + return 1; } // 1D on ND: G != const @@ -159,15 +159,15 @@ namespace libmpdataxx const arr_t &G, const ix_t &i, typename std::enable_if::type* = 0 // enabled if nug == true - ) + ) { return return_helper( G(i) + 0 // return_macro includes a call to blitz::safeToReturn() which expects an expression as an arg ); } - + // 2D: G != const - template + template inline auto G( const arr_t &G, const ix_t &i, @@ -179,9 +179,9 @@ namespace libmpdataxx G(idxperm::pi(i, j)) + 0 ); } - + // 3D: G != const - template + template inline auto G( const arr_t &G, const ix_t &i, diff --git a/libmpdata++/formulae/donorcell_formulae.hpp b/libmpdata++/formulae/donorcell_formulae.hpp index 40d3ca4b..eda4cf9c 100644 --- a/libmpdata++/formulae/donorcell_formulae.hpp +++ b/libmpdata++/formulae/donorcell_formulae.hpp @@ -22,67 +22,67 @@ namespace libmpdataxx const int n_tlev = 2, halo = 1; - template + template inline auto F( - const T1 &psi_l, const T2 &psi_r, const T3 &GC + const T1 &psi_l, const T2 &psi_r, const T3 &GC ) { - return return_helper( + return return_helper( pospart(GC) * psi_l + negpart(GC) * psi_r ); } template - inline auto make_flux( - const arr_1d_t &psi, - const arr_1d_t &GC, - const rng_t &i + inline auto make_flux( + const arr_1d_t &psi, + const arr_1d_t &GC, + const rng_t &i ) { - return return_helper(F( - psi(i ), - psi(i+1), - GC(i+h) + return return_helper(F( + psi(i ), + psi(i+1), + GC(i+h) )); } - template - inline auto make_flux( - const arr_2d_t &psi, - const arr_2d_t &GC, - const rng_t &i, - const rng_t &j - ) + template + inline auto make_flux( + const arr_2d_t &psi, + const arr_2d_t &GC, + const rng_t &i, + const rng_t &j + ) { - return return_helper(F( - psi(pi(i, j)), - psi(pi(i+1, j)), - GC(pi(i+h, j)) - )); + return return_helper(F( + psi(pi(i, j)), + psi(pi(i+1, j)), + GC(pi(i+h, j)) + )); } - template - inline auto make_flux( - const arr_3d_t &psi, - const arr_3d_t &GC, - const rng_t &i, - const rng_t &j, - const rng_t &k + template + inline auto make_flux( + const arr_3d_t &psi, + const arr_3d_t &GC, + const rng_t &i, + const rng_t &j, + const rng_t &k ) { - return return_helper(F( - psi(pi(i, j, k)), - psi(pi(i+1, j, k)), - GC(pi(i+h, j, k)) - )); + return return_helper(F( + psi(pi(i, j, k)), + psi(pi(i+1, j, k)), + GC(pi(i+h, j, k)) + )); } template inline void donorcell_sum( const arrvec_t &khn_tmp, const idx_t<1> i, - a_t psi_new, + a_t psi_new, const a_t &psi_old, const f1_t &flx_1, const f2_t &flx_2, @@ -91,7 +91,7 @@ namespace libmpdataxx { if (!opts::isset(opts, opts::khn)) { - psi_new = psi_old + (-flx_1 + flx_2) / g; + psi_new = psi_old + (-flx_1 + flx_2) / g; } else { @@ -117,11 +117,11 @@ namespace libmpdataxx { if (!opts::isset(opts, opts::khn)) { - // note: the parentheses are intended to minimise chances of numerical errors - psi_new = psi_old + ((-flx_1 + flx_2) + (-flx_3 + flx_4)) / g; + // note: the parentheses are intended to minimise chances of numerical errors + psi_new = psi_old + ((-flx_1 + flx_2) + (-flx_3 + flx_4)) / g; } else - { + { kahan_zro(khn_tmp[0](ij), khn_tmp[1](ij), khn_tmp[2](ij), psi_new); kahan_add(khn_tmp[0](ij), khn_tmp[1](ij), khn_tmp[2](ij), psi_new, psi_old); kahan_add(khn_tmp[0](ij), khn_tmp[1](ij), khn_tmp[2](ij), psi_new, -flx_1 / g); @@ -148,9 +148,9 @@ namespace libmpdataxx { if (!opts::isset(opts, opts::khn)) { - // note: the parentheses are intended to minimise chances of numerical errors - psi_new = psi_old + ((-flx_1 + flx_2) + (-flx_3 + flx_4) + (-flx_5 + flx_6)) / g; - } + // note: the parentheses are intended to minimise chances of numerical errors + psi_new = psi_old + ((-flx_1 + flx_2) + (-flx_3 + flx_4) + (-flx_5 + flx_6)) / g; + } else { kahan_zro(khn_tmp[0](ijk), khn_tmp[1](ijk), khn_tmp[2](ijk), psi_new); @@ -164,6 +164,6 @@ namespace libmpdataxx } } - } // namespace donorcell + } // namespace donorcell } // namespace formulae } // namespace libmpdataxx diff --git a/libmpdata++/formulae/idxperm.hpp b/libmpdata++/formulae/idxperm.hpp index 7b77aaf4..5c5c1c74 100644 --- a/libmpdata++/formulae/idxperm.hpp +++ b/libmpdata++/formulae/idxperm.hpp @@ -13,14 +13,14 @@ namespace libmpdataxx template using int_idx_t = blitz::TinyVector; // 2D - ranges or mix of ranges with ints - template + template inline idx_t<2> pi(const rng_t &i, const rng_t &j); template<> inline idx_t<2> pi<0>(const rng_t &i, const rng_t &j) { return idx_t<2>({i,j}); } template<> - inline idx_t<2> pi<1>(const rng_t &j, const rng_t &i) { return idx_t<2>({i,j}); } + inline idx_t<2> pi<1>(const rng_t &j, const rng_t &i) { return idx_t<2>({i,j}); } template inline idx_t<2> pi(const int &i, const rng_t &j) { return pi(rng_t(i,i), j); } @@ -28,15 +28,15 @@ namespace libmpdataxx // 2D - ints template inline int_idx_t<2> pi(const int i, const int j); - + template<> inline int_idx_t<2> pi<0>(const int i, const int j) { return int_idx_t<2>({i,j}); } - + template<> inline int_idx_t<2> pi<1>(const int j, const int i) { return int_idx_t<2>({i,j}); } // 3D - ranges or mix of ranges with ints - template + template inline idx_t<3> pi(const rng_t &i, const rng_t &j, const rng_t &k); template<> @@ -47,7 +47,7 @@ namespace libmpdataxx template<> inline idx_t<3> pi<2>(const rng_t &k, const rng_t &i, const rng_t &j) { return idx_t<3>({i,j,k}); } - + template inline idx_t<3> pi(const int &i, const rng_t &j, const rng_t &k) { return pi(rng_t(i,i), j, k); } @@ -56,17 +56,17 @@ namespace libmpdataxx template inline idx_t<3> pi(const int &i, const int &j, const rng_t &k) { return pi(rng_t(i,i), rng_t(j,j), k); } - + // 3D - ints - template + template inline int_idx_t<3> pi(const int i, const int j, const int k); - + template<> inline int_idx_t<3> pi<0>(const int i, const int j, const int k) { return int_idx_t<3>({i,j,k}); } - + template<> inline int_idx_t<3> pi<1>(const int j, const int k, const int i) { return int_idx_t<3>({i,j,k}); } - + template<> inline int_idx_t<3> pi<2>(const int k, const int i, const int j) { return int_idx_t<3>({i,j,k}); } } // namespace idxperm diff --git a/libmpdata++/formulae/kahan_sum.hpp b/libmpdata++/formulae/kahan_sum.hpp index ade01a01..929820f4 100644 --- a/libmpdata++/formulae/kahan_sum.hpp +++ b/libmpdata++/formulae/kahan_sum.hpp @@ -11,14 +11,14 @@ namespace libmpdataxx namespace formulae { template - inline void kahan_zro(a_t c, const a_t&, const a_t&, a_t sum) + inline void kahan_zro(a_t c, const a_t&, const a_t&, a_t sum) { sum = 0; c = 0; } template - inline void kahan_add(a_t c, a_t y, a_t t, a_t sum, f_t input) + inline void kahan_add(a_t c, a_t y, a_t t, a_t sum, f_t input) { y = input - c; t = sum + y; diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_1d.hpp index c7ef5073..1ea33166 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_1d.hpp @@ -12,59 +12,59 @@ #include namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +{ + namespace formulae + { + namespace mpdata { // first come helpers for divergence form of antidiffusive velocity template forceinline_macro auto div_2nd( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, - const arr_1d_t &G, + const arr_1d_t &G, const ix_t &i ) { return return_helper( abs(GC[0](i+h)) / 2 - * ndx_psi(psi, i) - - + * ndx_psi(psi, i) + - GC[0](i+h) / 2 * nfdiv(psi, GC, G, i) ); } - + template forceinline_macro auto div_3rd_upwind( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, - const arr_1d_t &G, - const ix_t &i, + const arr_1d_t &G, + const ix_t &i, typename std::enable_if::type* = 0 ) { return return_helper( abs(div_2nd(psi, GC, G, i)) / 2 - * ndx_psi(psi, i) + * ndx_psi(psi, i) ); } template forceinline_macro auto div_3rd_upwind( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, - const arr_1d_t &G, - const ix_t &i, + const arr_1d_t &G, + const ix_t &i, typename std::enable_if::type* = 0 ) { return 0; } - + template forceinline_macro auto div_3rd_temporal( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &ndtt_GC, const ix_t &i, typename std::enable_if::type* = 0 @@ -72,10 +72,10 @@ namespace libmpdataxx { return ndtt_GC0(psi, ndtt_GC[0], i); } - + template forceinline_macro auto div_3rd_temporal( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &ndtt_GC, const ix_t &i, typename std::enable_if::type* = 0 @@ -83,10 +83,10 @@ namespace libmpdataxx { return 10 * ndtt_GC0(psi, ndtt_GC[0], i); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, const ix_t &i, typename std::enable_if::type* = 0 @@ -96,10 +96,10 @@ namespace libmpdataxx ndxx_GC0(psi, GC[0], i) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, const ix_t &i, typename std::enable_if::type* = 0 @@ -109,10 +109,10 @@ namespace libmpdataxx 4 * ndxx_GC0(psi, GC[0], i) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, const ix_t &i, typename std::enable_if::type* = 0 @@ -120,12 +120,12 @@ namespace libmpdataxx { return 0; } - + template forceinline_macro auto div_3rd_spatial( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, - const arr_1d_t &G, + const arr_1d_t &G, const ix_t &i ) { @@ -138,31 +138,31 @@ namespace libmpdataxx ) ); } - + template forceinline_macro auto div_3rd( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_1d_t &G, - const ix_t &i, + const arr_1d_t &G, + const ix_t &i, typename std::enable_if::type* = 0 ) { return 0; } - + template forceinline_macro auto div_3rd( - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_1d_t &G, + const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 - ) + ) { return return_helper( // upwind differencing correction @@ -181,12 +181,12 @@ namespace libmpdataxx ) ); } - + // antidiffusive velocity - standard version template inline void antidiff( // antidiffusive velocity - arr_1d_t &res, - const arr_1d_t &psi, + arr_1d_t &res, + const arr_1d_t &psi, const arrvec_t &GC, const arrvec_t &ndt_GC, // to have consistent interface with the div_3rd version const arrvec_t &ndtt_GC, // ditto @@ -197,11 +197,11 @@ namespace libmpdataxx { for (int i = ir.first(); i <= ir.last(); ++i) { - res(i) = + res(i) = // second-order terms abs(GC[0](i+h)) / 2 * (1 - abs(GC[0](i+h)) / G_bar_x(G, i)) - * ndx_psi(psi, i) + * ndx_psi(psi, i) // third-order terms + TOT(psi, GC[0], G, i) //higher order term // divergent flow terms @@ -213,12 +213,12 @@ namespace libmpdataxx template inline void antidiff( arr_1d_t &res, - const arr_1d_t &psi, + const arr_1d_t &psi, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_1d_t &G, - const rng_t &ir, + const arr_1d_t &G, + const rng_t &ir, typename std::enable_if::type* = 0 ) { @@ -227,11 +227,11 @@ namespace libmpdataxx for (int i = ir.first(); i <= ir.last(); ++i) { - res(i + h) = + res(i + h) = div_2nd(psi, GC, G, i) + div_3rd(psi, GC, ndt_GC, ndtt_GC, G, i); } - } + } } // namespace mpdata } // namespace formulae diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_2d.hpp index 1b7ce8b0..3c24215d 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_2d.hpp @@ -12,66 +12,66 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // first come helpers for divergence form of antidiffusive velocity template forceinline_macro auto div_2nd( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &GC, - const arr_2d_t &G, - const ix_t &i, + const arr_2d_t &G, + const ix_t &i, const ix_t &j ) { return return_helper( // second order terms abs(GC[dim](pi(i+h, j))) / 2 - * ndx_psi(psi, i, j) - - + * ndx_psi(psi, i, j) + - GC[dim](pi(i+h, j)) / 2 * nfdiv(psi, GC, G, i, j) ); } - + template forceinline_macro auto div_3rd_upwind( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &GC, - const arr_2d_t &G, - const ix_t &i, + const arr_2d_t &G, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) { return return_helper( abs(div_2nd(psi, GC, G, i, j)) / 2 - * ndx_psi(psi, i, j) + * ndx_psi(psi, i, j) ); } template forceinline_macro auto div_3rd_upwind( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &GC, - const arr_2d_t &G, - const ix_t &i, + const arr_2d_t &G, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) { return 0; } - + template forceinline_macro auto div_3rd_temporal( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &ndtt_GC, - const ix_t &i, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -80,12 +80,12 @@ namespace libmpdataxx ndtt_GC0(psi, ndtt_GC[dim], i, j) ); } - + template forceinline_macro auto div_3rd_temporal( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &ndtt_GC, - const ix_t &i, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -94,12 +94,12 @@ namespace libmpdataxx 10 * ndtt_GC0(psi, ndtt_GC[dim], i, j) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &GC, - const ix_t &i, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -108,12 +108,12 @@ namespace libmpdataxx ndxx_GC0(psi, GC[dim], i, j) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &GC, - const ix_t &i, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -122,25 +122,25 @@ namespace libmpdataxx 4 * ndxx_GC0(psi, GC[dim], i, j) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &GC, - const ix_t &i, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) { return 0; } - + template forceinline_macro auto div_3rd_spatial( - const arr_2d_t &psi, + const arr_2d_t &psi, const arrvec_t &GC, - const arr_2d_t &G, - const ix_t &i, + const arr_2d_t &G, + const ix_t &i, const ix_t &j ) { @@ -153,36 +153,36 @@ namespace libmpdataxx ) ); } - + template forceinline_macro auto div_3rd( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_2d_t &G, - const ix_t &i, + const arr_2d_t &G, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) { return 0; } - + template forceinline_macro auto div_3rd( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_2d_t &G, - const ix_t &i, + const arr_2d_t &G, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -204,18 +204,18 @@ namespace libmpdataxx ) ); } - + template forceinline_macro auto div_3rd( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_2d_t &G, - const ix_t &i, + const arr_2d_t &G, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -237,33 +237,33 @@ namespace libmpdataxx ) ); } - + // antidiffusive velocity - standard version template inline void antidiff( - arr_2d_t &res, - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, + arr_2d_t &res, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, // to have consistent interface with the div_3rd version const arrvec_t &ndtt_GC, // ditto - const arr_2d_t &G, - const rng_t &ir, + const arr_2d_t &G, + const rng_t &ir, const rng_t &jr, typename std::enable_if::type* = 0 - ) + ) { for (int i = ir.first(); i <= ir.last(); ++i) { for (int j = jr.first(); j <= jr.last(); ++j) { - res(pi(i, j)) = + res(pi(i, j)) = // second order terms abs(GC[dim](pi(i+h, j))) / 2 * (1 - abs(GC[dim](pi(i+h, j))) / G_bar_x(G, i, j)) - * ndx_psi(psi_np1, i, j) - - - GC[dim](pi(i+h, j)) + * ndx_psi(psi_np1, i, j) + - + GC[dim](pi(i+h, j)) * GC1_bar_xy(GC[dim+1], i, j) / (2 * G_bar_x(G, i, j)) * ndy_psi(psi_np1, i, j) @@ -280,14 +280,14 @@ namespace libmpdataxx // antidiffusive velocity - divergence form template inline void antidiff( - arr_2d_t &res, - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, + arr_2d_t &res, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_2d_t &G, - const rng_t &ir, + const arr_2d_t &G, + const rng_t &ir, const rng_t &jr, typename std::enable_if::type* = 0 ) @@ -298,14 +298,14 @@ namespace libmpdataxx { for (int j = jr.first(); j <= jr.last(); ++j) { - res(pi(i + h, j)) = + res(pi(i + h, j)) = div_2nd(psi_np1, GC, G, i, j) + div_3rd(psi_np1, psi_n, GC, ndt_GC, ndtt_GC, G, i, j) // fourth order terms + FOT(psi_np1, GC, G, i, j); } } - } + } } // namespace mpdata } // namespace formulae -} // namespcae libmpdataxx +} // namespcae libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_3d.hpp index 2581b85b..36be071c 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_3d.hpp @@ -21,10 +21,10 @@ namespace libmpdataxx // first come helpers for divergence form of antidiffusive velocity template forceinline_macro auto div_2nd( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &GC, - const arr_3d_t &G, - const ix_t &i, + const arr_3d_t &G, + const ix_t &i, const ix_t &j, const ix_t &k ) @@ -32,19 +32,19 @@ namespace libmpdataxx return return_helper( // second order terms abs(GC[dim](pi(i+h, j, k))) / 2 - * ndx_psi(psi, i, j, k) - - + * ndx_psi(psi, i, j, k) + - GC[dim](pi(i+h, j, k)) / 2 * nfdiv(psi, GC, G, i, j, k) ); } - + template forceinline_macro auto div_3rd_upwind( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &GC, - const arr_3d_t &G, - const ix_t &i, + const arr_3d_t &G, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -52,16 +52,16 @@ namespace libmpdataxx { return return_helper( abs(div_2nd(psi, GC, G, i, j, k)) / 2 - * ndx_psi(psi, i, j, k) + * ndx_psi(psi, i, j, k) ); } template forceinline_macro auto div_3rd_upwind( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &GC, - const arr_3d_t &G, - const ix_t &i, + const arr_3d_t &G, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -69,12 +69,12 @@ namespace libmpdataxx { return 0; } - + template forceinline_macro auto div_3rd_temporal( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &ndtt_GC, - const ix_t &i, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -84,12 +84,12 @@ namespace libmpdataxx ndtt_GC0(psi, ndtt_GC[dim], i, j, k) ); } - + template forceinline_macro auto div_3rd_temporal( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &ndtt_GC, - const ix_t &i, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -99,12 +99,12 @@ namespace libmpdataxx 10 * ndtt_GC0(psi, ndtt_GC[dim], i, j, k) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &GC, - const ix_t &i, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -114,12 +114,12 @@ namespace libmpdataxx ndxx_GC0(psi, GC[dim], i, j, k) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &GC, - const ix_t &i, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -129,12 +129,12 @@ namespace libmpdataxx 4 * ndxx_GC0(psi, GC[dim], i, j, k) ); } - + template forceinline_macro auto div_3rd_spatial_helper( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &GC, - const ix_t &i, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -145,10 +145,10 @@ namespace libmpdataxx template forceinline_macro auto div_3rd_spatial( - const arr_3d_t &psi, + const arr_3d_t &psi, const arrvec_t &GC, - const arr_3d_t &G, - const ix_t &i, + const arr_3d_t &G, + const ix_t &i, const ix_t &j, const ix_t &k ) @@ -162,18 +162,18 @@ namespace libmpdataxx ) ); } - + template forceinline_macro auto div_3rd( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_3d_t &G, - const ix_t &i, + const arr_3d_t &G, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -181,18 +181,18 @@ namespace libmpdataxx { return 0; } - + template forceinline_macro auto div_3rd( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_3d_t &G, - const ix_t &i, + const arr_3d_t &G, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -215,18 +215,18 @@ namespace libmpdataxx ) ); } - + template forceinline_macro auto div_3rd( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_3d_t &G, - const ix_t &i, + const arr_3d_t &G, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -272,7 +272,7 @@ namespace libmpdataxx { for (int k = kr.first(); k <= kr.last(); ++k) { - res(pi(i, j, k)) = + res(pi(i, j, k)) = // second order terms abs(GC[dim](pi(i+h, j, k))) / 2 * (1 - abs(GC[dim](pi(i+h, j, k))) / G_bar_x(G, i, j, k)) @@ -297,14 +297,14 @@ namespace libmpdataxx // antidiffusive velocity - divergence form template inline void antidiff( - arr_3d_t &res, - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, + arr_3d_t &res, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, const arrvec_t &GC, const arrvec_t &ndt_GC, const arrvec_t &ndtt_GC, - const arr_3d_t &G, - const rng_t &ir, + const arr_3d_t &G, + const rng_t &ir, const rng_t &jr, const rng_t &kr, typename std::enable_if::type* = 0 @@ -319,13 +319,13 @@ namespace libmpdataxx { for (int k = kr.first(); k <= kr.last(); ++k) { - res(pi(i + h, j, k)) = + res(pi(i + h, j, k)) = div_2nd(psi_np1, GC, G, i, j, k) + div_3rd(psi_np1, psi_n, GC, ndt_GC, ndtt_GC, G, i, j, k); } } } - } + } } // namespace mpdata } // namespace formulae } // namespcae libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_common.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_common.hpp index 09d14544..b5f15ed1 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_common.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_common.hpp @@ -14,54 +14,54 @@ //#include namespace libmpdataxx -{ +{ // in namespace solvers to be consistent with other options namespace solvers { enum sptl_intrp_t - { + { exact, aver2, aver4, }; - + enum tmprl_extrp_t - { + { noextrp, linear2, }; } - namespace formulae - { - namespace mpdata + namespace formulae + { + namespace mpdata { using namespace arakawa_c; using idxperm::pi; using opts::opts_t; using std::abs; - + using blitz::pow2; using blitz::pow3; using blitz::pow4; const int n_tlev = 2; - constexpr const int halo(const opts_t &opts) + constexpr const int halo(const opts_t &opts) { return ( opts::isset(opts, opts::tot) || // see psi 2-nd derivatives in eq. (36) in PKS & LGM 1998 opts::isset(opts, opts::dfl) || // see +3/2 in eq. (30) in PKS & LGM 1998 - opts::isset(opts, opts::div_2nd) || + opts::isset(opts, opts::div_2nd) || opts::isset(opts, opts::div_3rd) || opts::isset(opts, opts::div_3rd_dt) - ) ? 2 : 1; + ) ? 2 : 1; } // frac: implemented using blitz::where() template forceinline_macro auto frac( - const nom_t &nom, + const nom_t &nom, const den_t &den, typename std::enable_if::type* = 0 // enabled if pfc == true ) @@ -75,7 +75,7 @@ namespace libmpdataxx // if den == 0, then adding a smallest representable positive number template forceinline_macro auto frac( - const nom_t &nom, + const nom_t &nom, const den_t &den, typename std::enable_if::type* = 0 // enabled if pfc == false ) @@ -88,7 +88,7 @@ namespace libmpdataxx // a bigger-epsilon version for FCT (used regardless of opts::eps setting) template forceinline_macro auto fct_frac( - const nom_t &nom, + const nom_t &nom, const den_t &den ) { diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_1d.hpp index e262ac98..b7747b01 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_1d.hpp @@ -9,10 +9,10 @@ #include namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +{ + namespace formulae + { + namespace mpdata { //divergent flow correction see eq. (30) from @copybrief Smolarkiewicz_and_Margolin_1998) @@ -22,10 +22,10 @@ namespace libmpdataxx const arr_1d_t &GC, const arr_1d_t &G, const ix_t &i, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) - { - return 0; + { + return 0; } template @@ -34,14 +34,14 @@ namespace libmpdataxx const arr_1d_t &GC, const arr_1d_t &G, const ix_t &i, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) { return return_helper( - - fconst(0.5) * GC(i+h) - / - (formulae::G(G, i+1) + formulae::G(G, i)) - * + - fconst(0.5) * GC(i+h) + / + (formulae::G(G, i+1) + formulae::G(G, i)) + * (GC((i+1)+h) - GC(i-h)) ); } @@ -52,14 +52,14 @@ namespace libmpdataxx const arr_1d_t &GC, const arr_1d_t &G, const ix_t &i, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) { return return_helper( - - fconst(0.5) * GC(i+h) - / - (formulae::G(G, i+1) + formulae::G(G, i)) - * + - fconst(0.5) * GC(i+h) + / + (formulae::G(G, i+1) + formulae::G(G, i)) + * (GC((i+1)+h) - GC(i-h)) * fconst(0.5) * (psi(i+1) + psi(i)) //to be compatible with iga formulation diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_2d.hpp index 68a3347c..10ec4188 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_2d.hpp @@ -10,11 +10,11 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // divergent flow correction - no correction template @@ -24,38 +24,38 @@ namespace libmpdataxx const arr_2d_t &G, const ix_t &i, const ix_t &j, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) - { - return 0; + { + return 0; } // divergent flow correction - general case template inline auto DFL( const arr_2d_t &psi, //to have the same arguments as in iga option - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) { return return_helper( - - fconst(0.25) * GC[dim](pi(i+h, j)) + - fconst(0.25) * GC[dim](pi(i+h, j)) / - G_bar_x(G, i, j) - * + G_bar_x(G, i, j) + * ( ( - GC[dim](pi((i+1)+h, j)) - + GC[dim](pi((i+1)+h, j)) - GC[dim](pi(i-h , j)) ) + ( - GC[dim-1](pi(i+1, j+h)) + + GC[dim-1](pi(i+1, j+h)) + GC[dim-1](pi(i, j+h)) - - GC[dim-1](pi(i+1, j-h)) - + GC[dim-1](pi(i+1, j-h)) - GC[dim-1](pi(i, j-h)) ) ) @@ -70,30 +70,30 @@ namespace libmpdataxx const arr_2d_t &G, const ix_t &i, const ix_t &j, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) { return return_helper( - - fconst(0.25) * GC[dim](pi(i+h, j)) + - fconst(0.25) * GC[dim](pi(i+h, j)) / - G_bar_x(G, i, j) - * + G_bar_x(G, i, j) + * ( ( - GC[dim](pi((i+1)+h, j)) - + GC[dim](pi((i+1)+h, j)) - GC[dim](pi(i-h , j)) ) + ( - GC[dim-1](pi(i+1, j+h)) + + GC[dim-1](pi(i+1, j+h)) + GC[dim-1](pi(i, j+h)) - - GC[dim-1](pi(i+1, j-h)) - + GC[dim-1](pi(i+1, j-h)) - GC[dim-1](pi(i, j-h)) ) ) - * psi_bar_x(psi, i, j) + * psi_bar_x(psi, i, j) ); } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_3d.hpp index cba75024..b10bcacd 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_dfl_3d.hpp @@ -10,11 +10,11 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // divergent flow correction - no correction template @@ -25,46 +25,46 @@ namespace libmpdataxx const ix_t &i, const ix_t &j, const ix_t &k, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) - { - return 0; + { + return 0; } // divergent flow correction - general case template inline auto DFL( const arr_3d_t &psi, //to have the same arguments as in iga option - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, const ix_t &k, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) { return return_helper( - - fconst(0.25) * GC[dim](pi(i+h, j, k)) + - fconst(0.25) * GC[dim](pi(i+h, j, k)) / G_bar_x(G, i, j, k) - * + * ( ( - GC[dim](pi((i+1)+h, j, k)) - + GC[dim](pi((i+1)+h, j, k)) - GC[dim](pi(i-h , j, k)) ) + ( - GC[dim+1](pi(i+1, j+h, k)) + + GC[dim+1](pi(i+1, j+h, k)) + GC[dim+1](pi(i, j+h, k)) - - GC[dim+1](pi(i+1, j-h, k)) - + GC[dim+1](pi(i+1, j-h, k)) - GC[dim+1](pi(i, j-h, k)) ) + ( - GC[dim-1](pi(i+1, j, k+h)) + + GC[dim-1](pi(i+1, j, k+h)) + GC[dim-1](pi(i, j, k+h)) - - GC[dim-1](pi(i+1, j, k-h)) - + GC[dim-1](pi(i+1, j, k-h)) - GC[dim-1](pi(i, j, k-h)) ) ) @@ -80,31 +80,31 @@ namespace libmpdataxx const ix_t &i, const ix_t &j, const ix_t &k, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) { return return_helper( - - fconst(0.25) * GC[dim](pi(i+h, j, k)) + - fconst(0.25) * GC[dim](pi(i+h, j, k)) / G_bar_x(G, i, j, k) - * + * ( ( - GC[dim](pi((i+1)+h, j, k)) - + GC[dim](pi((i+1)+h, j, k)) - GC[dim](pi(i-h , j, k)) ) + ( - GC[dim+1](pi(i+1, j+h, k)) + + GC[dim+1](pi(i+1, j+h, k)) + GC[dim+1](pi(i, j+h, k)) - - GC[dim+1](pi(i+1, j-h, k)) - + GC[dim+1](pi(i+1, j-h, k)) - GC[dim+1](pi(i, j-h, k)) ) + ( - GC[dim-1](pi(i+1, j, k+h)) + + GC[dim-1](pi(i+1, j, k+h)) + GC[dim-1](pi(i, j, k+h)) - - GC[dim-1](pi(i+1, j, k-h)) - + GC[dim-1](pi(i+1, j, k-h)) - GC[dim-1](pi(i, j, k-h)) ) ) @@ -113,4 +113,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_fct_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_fct_1d.hpp index 544b8ac7..eaa8e2d3 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_fct_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_fct_1d.hpp @@ -2,7 +2,7 @@ * @copyright University of Warsaw * @author Anna Jaruga * @author Sylwester Arabas - * @brief Flux Corrected Transport formulae for MPDATA + * @brief Flux Corrected Transport formulae for MPDATA * (aka non-oscillatory, monotonic, sign-preserving option) * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) @@ -13,22 +13,22 @@ #include namespace libmpdataxx -{ - namespace formulae - { +{ + namespace formulae + { namespace mpdata { using namespace arakawa_c; /// \f$ \beta^{\uparrow}_{i} = \frac { \psi^{max}_{i}- \psi^{*}_{i} } - /// { \sum\limits_{I} \frac{\Delta t}{\Delta x^{I}} \left( [u^{I}_{i-1/2}]^{+} \psi^{*}_{i-1} - + /// { \sum\limits_{I} \frac{\Delta t}{\Delta x^{I}} \left( [u^{I}_{i-1/2}]^{+} \psi^{*}_{i-1} - /// [u^{I}_{i+1/2}]^{-} \psi^{*}_{i+1} \right) } \f$ \n /// eq.(19a) in Smolarkiewicz & Grabowski 1990 (J.Comp.Phys.,86,355-375) template forceinline_macro auto beta_up_nominator( const arr_1d_t &psi, - const arr_1d_t &psi_max, + const arr_1d_t &psi_max, const arr_1d_t &G, const ix_t &i ) @@ -36,7 +36,7 @@ namespace libmpdataxx return return_helper( (max(psi_max(i), psi(i-1), psi(i), psi(i+1)) - psi(i)) * formulae::G(G, i) ); - } //to make beta dimensionless + } //to make beta dimensionless //when transporting mixing ratios with momentum template forceinline_macro void beta_up( // for positive sign signal @@ -51,7 +51,7 @@ namespace libmpdataxx using ix_t = int; for (int i = ir.first(); i <= ir.last(); ++i) { - b(i) = + b(i) = fct_frac( beta_up_nominator(psi, psi_max, G, i) , // ---------------------------- @@ -59,40 +59,40 @@ namespace libmpdataxx - negpart(flx[0](i+h)) ); } - } + } /// \f$ \beta^{\downarrow}_{i} = \frac { \psi^{*}_{i}- \psi^{min}_{i} } - /// { \sum\limits_{I} \frac{\Delta t}{\Delta x^{I}} \left( [u^{I}_{i+1/2}]^{+} \psi^{*}_{i} - + /// { \sum\limits_{I} \frac{\Delta t}{\Delta x^{I}} \left( [u^{I}_{i+1/2}]^{+} \psi^{*}_{i} - /// [u^{I}_{i-1/2}]^{-} \psi^{*}_{i} \right) } \f$ \n /// eq.(19b) in Smolarkiewicz & Grabowski 1990 (J.Comp.Phys.,86,355-375) template forceinline_macro auto beta_dn_nominator( const arr_1d_t &psi, - const arr_1d_t &psi_min, - const arr_1d_t &G, + const arr_1d_t &psi_min, + const arr_1d_t &G, const ix_t &i ) { return return_helper( (psi(i) - min(psi_min(i), psi(i-1), psi(i), psi(i+1))) * formulae::G(G, i) ); - } //to make beta dimensionless + } //to make beta dimensionless //when transporting mixing ratios with momentum template forceinline_macro void beta_dn( //positive sign signal - arr_1d_t &b, - const arr_1d_t &psi, + arr_1d_t &b, + const arr_1d_t &psi, const arr_1d_t &psi_min, // from before the first iteration - const flx_t &flx, - const arr_1d_t &G, + const flx_t &flx, + const arr_1d_t &G, const rng_t &ir ) { using ix_t = int; for (int i = ir.first(); i <= ir.last(); ++i) { - b(i) = + b(i) = fct_frac( beta_dn_nominator(psi, psi_min, G, i) , // -------------------------- @@ -100,10 +100,10 @@ namespace libmpdataxx - negpart(flx[0](i-h)) ); } - } + } /// nonoscillatory antidiffusive velocity: \n - /// \f$ U^{MON}_{i+1/2}=min(1,\beta ^{\downarrow}_i,\beta ^{\uparrow} _{i+1})[U_{i+1/2}]^{+} + /// \f$ U^{MON}_{i+1/2}=min(1,\beta ^{\downarrow}_i,\beta ^{\uparrow} _{i+1})[U_{i+1/2}]^{+} /// + min(1,\beta^{\uparrow}_{i},\beta^{\downarrow}_{i+1/2})[u_{i+1/2}]^{-} \f$ \n /// where \f$ [\cdot]^{+}=max(\cdot,0) \f$ and \f$ [\cdot]^{-}=min(\cdot,0) \f$ \n /// eq.(18) in Smolarkiewicz & Grabowski 1990 (J.Comp.Phys.,86,355-375) @@ -132,32 +132,32 @@ namespace libmpdataxx psi(i) > 0, // then min(1, - beta_dn(i ), + beta_dn(i ), beta_up(i + 1) - ), + ), // else min(1, - beta_up(i ), + beta_up(i ), beta_dn(i + 1) - ) - ), + ) + ), // else where( // if psi(i+1) > 0, // then min(1, - beta_up(i ), + beta_up(i ), beta_dn(i + 1) - ), + ), // else min(1, - beta_dn(i ), + beta_dn(i ), beta_up(i + 1) - ) - ) + ) + ) ); - } + } } template @@ -175,7 +175,7 @@ namespace libmpdataxx using ix_t = int; for (int i = ir.first(); i <= ir.last(); ++i) { - GC_m(i+h) = + GC_m(i+h) = GC_corr(i+h) * where( // if GC_corr(i+h) > 0, @@ -183,15 +183,15 @@ namespace libmpdataxx min(1, beta_dn(i), beta_up(i + 1) - ), + ), // else min(1, beta_up(i), beta_dn(i + 1) - ) + ) ); } - } + } } // namespace mpdata_fct } // namespace formulae } // namespcae libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_fct_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_fct_2d.hpp index 40b1239d..dd905a21 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_fct_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_fct_2d.hpp @@ -10,25 +10,25 @@ #include namespace libmpdataxx -{ - namespace formulae - { +{ + namespace formulae + { namespace mpdata { using namespace arakawa_c; - + //see Smolarkiewicz & Grabowski 1990 (J.Comp.Phys.,86,355-375) template forceinline_macro auto beta_up_nominator( const arr_2d_t &psi, const arr_2d_t &psi_max, const arr_2d_t &G, - const ix_t &i, + const ix_t &i, const ix_t &j ) { return return_helper( - ( + ( max( psi_max(i, j), psi(i, j+1), psi(i-1, j), psi(i, j ), psi(i+1, j), @@ -45,7 +45,7 @@ namespace libmpdataxx const arr_2d_t &psi_max, // from before the first iteration const flx_t &flx, const arr_2d_t &G, - const rng_t &ir, + const rng_t &ir, const rng_t &jr ) { @@ -54,48 +54,48 @@ namespace libmpdataxx { for (int j = jr.first(); j <= jr.last(); ++j) { - b(i, j) = + b(i, j) = fct_frac( beta_up_nominator(psi, psi_max, G, i, j) , // ----------------------------------------------------------- ( pospart(flx[0](i-h, j)) - negpart(flx[0](i+h, j)) ) // additional parenthesis so that we first sum - + // fluxes in separate dimensions + + // fluxes in separate dimensions ( pospart(flx[1](i, j-h)) // could be important for accuracy if one of them - negpart(flx[1](i, j+h)) ) // is of different magnitude than the other ); } } - } + } template forceinline_macro auto beta_dn_nominator( - const arr_2d_t &psi, + const arr_2d_t &psi, const arr_2d_t &psi_min, - const arr_2d_t &G, + const arr_2d_t &G, const ix_t &i, - const ix_t &j + const ix_t &j ) { return return_helper( ( psi(i, j) - - min( psi_min(i,j), + - min( psi_min(i,j), psi(i, j+1), psi(i-1, j), psi(i, j ), psi(i+1, j), psi(i, j-1) ) ) * formulae::G(G, i, j) //see beta_up_nominator ); - } + } template forceinline_macro auto beta_dn( - arr_2d_t &b, - const arr_2d_t &psi, + arr_2d_t &b, + const arr_2d_t &psi, const arr_2d_t &psi_min, // from before the first iteration const flx_t &flx, - const arr_2d_t &G, + const arr_2d_t &G, const rng_t &ir, const rng_t &jr ) @@ -105,7 +105,7 @@ namespace libmpdataxx { for (int j = jr.first(); j <= jr.last(); ++j) { - b(i, j) = + b(i, j) = fct_frac( beta_dn_nominator(psi, psi_min, G, i, j) , // --------------------------------------------------------- @@ -117,7 +117,7 @@ namespace libmpdataxx ); } } - } + } template forceinline_macro auto GC_mono( //for variable-sign signal and no infinite gauge option @@ -148,7 +148,7 @@ namespace libmpdataxx // then min(1, beta_dn(pi(i, j)), - beta_up(pi(i + 1, j)) + beta_up(pi(i + 1, j)) ), // else min(1, @@ -174,7 +174,7 @@ namespace libmpdataxx ); } } - } + } template forceinline_macro auto GC_mono( //for infinite gauge option or positive-sign signal @@ -197,7 +197,7 @@ namespace libmpdataxx GC_m[d]( pi(i+h, j) ) = GC_corr[d]( pi(i+h, j) ) * where( // if - GC_corr[d]( pi(i+h, j) ) > 0, + GC_corr[d]( pi(i+h, j) ) > 0, // then min(1, beta_dn(pi(i, j)), diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_fct_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_fct_3d.hpp index def743fe..44e97c25 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_fct_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_fct_3d.hpp @@ -23,7 +23,7 @@ namespace libmpdataxx const arr_3d_t &psi, const arr_3d_t &psi_max, const arr_3d_t &G, - const ix_t &i, + const ix_t &i, const ix_t &j, const ix_t &k ) @@ -42,7 +42,7 @@ namespace libmpdataxx - psi(i, j, k) ) * formulae::G(G, i, j, k) //to make beta up dimensionless when transporting mixing ratios with momentum ); - } + } template forceinline_macro void beta_up( @@ -51,7 +51,7 @@ namespace libmpdataxx const arr_3d_t &psi_max, // from before the first iteration const flx_t &flx, const arr_3d_t &G, - const rng_t &ir, + const rng_t &ir, const rng_t &jr, const rng_t &kr ) @@ -63,7 +63,7 @@ namespace libmpdataxx { for (int k = kr.first(); k <= kr.last(); ++k) { - b(i, j, k) = + b(i, j, k) = fct_frac( beta_up_nominator(psi, psi_max, G, i, j, k) , //------------------------------------------------------------------------------------- @@ -106,7 +106,7 @@ namespace libmpdataxx ) * formulae::G(G, i, j, k) //to make beta up dimensionless when transporting mixing ratios with momentum ); } - + template forceinline_macro void beta_dn( arr_3d_t &b, @@ -126,7 +126,7 @@ namespace libmpdataxx { for (int k = kr.first(); k <= kr.last(); ++k) { - b(i, j, k) = + b(i, j, k) = fct_frac( beta_dn_nominator(psi, psi_min, G, i, j, k) , //----------------------------------------------------------------------------------- diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_1d.hpp index 67341b41..4e15475d 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_1d.hpp @@ -13,18 +13,18 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { - // flux divergence i.e. + // flux divergence i.e. // 1 / G * dx * d(GC * psi)/dx at (i) template forceinline_macro auto fdiv_centre( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i ) @@ -36,13 +36,13 @@ namespace libmpdataxx ) / formulae::G(G, i) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * dx * d(GC * psi)/dx at (i+1/2) - positive sign scalar version template forceinline_macro auto nfdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -61,13 +61,13 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * dx * d(GC * psi)/dx at (i+1/2) - variable sign scalar version template forceinline_macro auto nfdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -86,13 +86,13 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * dx * d(GC * psi)/dx at (i+1/2) - infinite gauge version template forceinline_macro auto nfdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -105,13 +105,13 @@ namespace libmpdataxx ) / G_bar_x(G, i) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * dx * d(GC * fdiv)/dx at (i+1/2) - positive sign scalar version template forceinline_macro auto nfdiv_fdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -132,13 +132,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * dx * d(GC * fdiv)/dx at (i+1/2) - variable sign scalar version template forceinline_macro auto nfdiv_fdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -159,13 +159,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * dx * d(GC * fdiv)/dx at (i+1/2) - infinite gauge version template forceinline_macro auto nfdiv_fdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -178,20 +178,20 @@ namespace libmpdataxx ) / G_bar_x(G, i) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2) - positive sign scalar version template forceinline_macro auto ndx_fdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 ) { return return_helper( - 4 * + 4 * frac( fdiv_centre(psi, GC, G, i+1) - fdiv_centre(psi, GC, G, i ) @@ -203,20 +203,20 @@ namespace libmpdataxx ) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2) - variable sign scalar version template forceinline_macro auto ndx_fdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 ) { return return_helper( - 4 * + 4 * frac( fdiv_centre(psi, GC, G, i+1) - fdiv_centre(psi, GC, G, i ) @@ -228,13 +228,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2) - infinite gauge version template forceinline_macro auto ndx_fdiv( const arr_1d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -247,4 +247,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_2d.hpp index 4755f640..9283a0b1 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_2d.hpp @@ -16,18 +16,18 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { - // flux divergence i.e. + // flux divergence i.e. // 1 / G * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy) at (i, j) template forceinline_macro auto fdiv_centre( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j @@ -42,13 +42,13 @@ namespace libmpdataxx ) / formulae::G(G, i, j) ); } - - // flux divergence i.e. + + // flux divergence i.e. // 1 / G * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy) at (i+1/2, j+1/2) template forceinline_macro auto fdiv_corner_xy( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j @@ -58,19 +58,19 @@ namespace libmpdataxx ( GC0_bar_xy(GC[dim], i+1, j ) * psi_bar_y(psi, i+1, j) - GC0_bar_xy(GC[dim], i , j ) * psi_bar_y(psi, i , j) - + + GC1_bar_xy(GC[dim+1], i, j+1) * psi_bar_x(psi, i, j+1) - GC1_bar_xy(GC[dim+1], i, j ) * psi_bar_x(psi, i, j ) ) / G_bar_xy(G, i, j) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy) at (i+1/2, j) - positive sign scalar version template forceinline_macro auto nfdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -96,13 +96,13 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy) at (i+1/2, j) - variable sign scalar version template forceinline_macro auto nfdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -128,18 +128,18 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy) at (i+1/2, j) - infinite gauge version template forceinline_macro auto nfdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) + ) { return return_helper( ( @@ -150,13 +150,13 @@ namespace libmpdataxx ) / G_bar_x(G, i, j) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * (dx * d(GC * fdiv)/dx + dy * d(GC * fdiv)/dy) at (i+1/2, j) - positive sign scalar version template forceinline_macro auto nfdiv_fdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -184,18 +184,18 @@ namespace libmpdataxx ) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * (dx * d(GC * fdiv)/dx + dy * d(GC * fdiv)/dy) at (i+1/2, j) - variable sign scalar version template forceinline_macro auto nfdiv_fdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) + ) { return return_helper( 8 * @@ -218,13 +218,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * (dx * d(GC * fdiv)/dx + dy * d(GC * fdiv)/dy) at (i+1/2, j) - infinite gauge version template forceinline_macro auto nfdiv_fdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -240,13 +240,13 @@ namespace libmpdataxx ) / G_bar_x(G, i, j) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2, j) - positive sign scalar version template forceinline_macro auto ndx_fdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -254,7 +254,7 @@ namespace libmpdataxx ) { return return_helper( - 8 * + 8 * frac( fdiv_centre(psi, GC, G, i+1, j) - fdiv_centre(psi, GC, G, i , j) @@ -270,13 +270,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2, j) - variable sign scalar version template forceinline_macro auto ndx_fdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -284,7 +284,7 @@ namespace libmpdataxx ) { return return_helper( - 8 * + 8 * frac( fdiv_centre(psi, GC, G, i+1, j) - fdiv_centre(psi, GC, G, i , j) @@ -300,13 +300,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2, j) - infinite gauge version template forceinline_macro auto ndx_fdiv( const arr_2d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -319,13 +319,13 @@ namespace libmpdataxx ); } - // nondimensionalised flux divergence of time derivative of psi i.e. + // nondimensionalised flux divergence of time derivative of psi i.e. // 1 / (G * psi) * (dx * d(GC * dpsi/dt)/dx + dy * d(GC * dpsi/dt)/dy) at (i+1/2, j) - positive sign scalar version template forceinline_macro auto nfdiv_dt( const arr_2d_t &psi_np1, const arr_2d_t &psi_n, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -359,14 +359,14 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence of time derivative of psi i.e. + + // nondimensionalised flux divergence of time derivative of psi i.e. // 1 / (G * psi) * (dx * d(GC * dpsi/dt)/dx + dy * d(GC * dpsi/dt)/dy) at (i+1/2, j) - variable sign scalar version template forceinline_macro auto nfdiv_dt( const arr_2d_t &psi_np1, const arr_2d_t &psi_n, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -400,14 +400,14 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence of time derivative of psi i.e. + + // nondimensionalised flux divergence of time derivative of psi i.e. // 1 / (G * psi) * (dx * d(GC * dpsi/dt)/dx + dy * d(GC * dpsi/dt)/dy) at (i+1/2, j) - infinite gauge version template forceinline_macro auto nfdiv_dt( const arr_2d_t &psi_np1, const arr_2d_t &psi_n, - const arrvec_t &GC, + const arrvec_t &GC, const arr_2d_t &G, const ix_t &i, const ix_t &j, @@ -428,4 +428,4 @@ namespace libmpdataxx } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_3d.hpp index df8f3637..26d013b0 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_fdiv_3d.hpp @@ -17,18 +17,18 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { - // flux divergence i.e. + // flux divergence i.e. // 1 / G * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy + dz * d(GC * psi)/dz) at (i, j, k) template forceinline_macro auto fdiv_centre( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -48,13 +48,13 @@ namespace libmpdataxx ) / formulae::G(G, i, j, k) ); } - - // flux divergence i.e. + + // flux divergence i.e. // 1 / G * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy + dz * d(GC * psi)/dz) at (i+1/2, j+1/2, k) template forceinline_macro auto fdiv_corner_xy( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -65,22 +65,22 @@ namespace libmpdataxx ( GC0_bar_xy(GC[dim ], i+1, j, k) * psi_bar_y(psi, i+1, j, k) - GC0_bar_xy(GC[dim ], i , j, k) * psi_bar_y(psi, i , j, k) - + + GC1_bar_xy(GC[dim+1], i, j+1, k) * psi_bar_x(psi, i, j+1, k) - GC1_bar_xy(GC[dim+1], i, j , k) * psi_bar_x(psi, i, j , k) - + + GC2_bar_xy(GC[dim-1], i, j, k ) * psi_bar_xyz(psi, i, j , k ) - GC2_bar_xy(GC[dim-1], i, j, k-1) * psi_bar_xyz(psi, i, j , k-1) ) / G_bar_xy(G, i, j, k) ); } - - // flux divergence i.e. + + // flux divergence i.e. // 1 / G * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy + dz * d(GC * psi)/dz) at (i+1/2, j, k+1/2) template forceinline_macro auto fdiv_corner_xz( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -91,23 +91,23 @@ namespace libmpdataxx ( GC0_bar_xz(GC[dim ], i+1, j, k) * psi_bar_z(psi, i+1, j, k) - GC0_bar_xz(GC[dim ], i , j, k) * psi_bar_z(psi, i , j, k) - + + GC1_bar_xz(GC[dim+1], i, j , k) * psi_bar_xyz(psi, i, j , k) - GC1_bar_xz(GC[dim+1], i, j-1, k) * psi_bar_xyz(psi, i, j-1, k) - + + GC2_bar_xz(GC[dim-1], i, j, k+1) * psi_bar_x(psi, i, j , k+1) - GC2_bar_xz(GC[dim-1], i, j, k ) * psi_bar_x(psi, i, j , k ) ) / G_bar_xz(G, i, j, k) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy + dz * d(GC * psi)/dz) at (i+1/2, j, k) // positive sign scalar version template forceinline_macro auto nfdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -123,7 +123,7 @@ namespace libmpdataxx + GC1_bar_x(GC[dim+1], i, j , k) * psi_bar_xy(psi, i, j , k) - GC1_bar_x(GC[dim+1], i, j-1, k) * psi_bar_xy(psi, i, j-1, k) - + + GC2_bar_x(GC[dim-1], i, j, k ) * psi_bar_xz(psi, i, j, k ) - GC2_bar_x(GC[dim-1], i, j, k-1) * psi_bar_xz(psi, i, j, k-1) , @@ -142,14 +142,14 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy + dz * d(GC * psi)/dz) at (i+1/2, j, k) // variable sign scalar version template forceinline_macro auto nfdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -165,7 +165,7 @@ namespace libmpdataxx + GC1_bar_x(GC[dim+1], i, j , k) * psi_bar_xy(psi, i, j , k) - GC1_bar_x(GC[dim+1], i, j-1, k) * psi_bar_xy(psi, i, j-1, k) - + + GC2_bar_x(GC[dim-1], i, j, k ) * psi_bar_xz(psi, i, j, k ) - GC2_bar_x(GC[dim-1], i, j, k-1) * psi_bar_xz(psi, i, j, k-1) , @@ -184,14 +184,14 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence i.e. + + // nondimensionalised flux divergence i.e. // 1 / (G * psi) * (dx * d(GC * psi)/dx + dy * d(GC * psi)/dy + dz * d(GC * psi)/dz) at (i+1/2, j, k) // infinite gauge version template forceinline_macro auto nfdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -206,20 +206,20 @@ namespace libmpdataxx + GC1_bar_x(GC[dim+1], i, j , k) * psi_bar_xy(psi, i, j , k) - GC1_bar_x(GC[dim+1], i, j-1, k) * psi_bar_xy(psi, i, j-1, k) - + + GC2_bar_x(GC[dim-1], i, j, k ) * psi_bar_xz(psi, i, j, k ) - GC2_bar_x(GC[dim-1], i, j, k-1) * psi_bar_xz(psi, i, j, k-1) ) / G_bar_x(G, i, j, k) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * (dx * d(GC * fdiv)/dx + dy * d(GC * fdiv)/dy + dz * d(GC * fdiv)/dz) at (i+1/2, j, k) // positive sign scalar version template forceinline_macro auto nfdiv_fdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -235,7 +235,7 @@ namespace libmpdataxx + GC1_bar_x(GC[dim+1], i, j , k) * fdiv_corner_xy(psi, GC, G, i, j , k) - GC1_bar_x(GC[dim+1], i, j-1, k) * fdiv_corner_xy(psi, GC, G, i, j-1, k) - + + GC2_bar_x(GC[dim-1], i, j, k ) * fdiv_corner_xz(psi, GC, G, i, j, k ) - GC2_bar_x(GC[dim-1], i, j, k-1) * fdiv_corner_xz(psi, GC, G, i, j, k-1) , @@ -256,14 +256,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * (dx * d(GC * fdiv)/dx + dy * d(GC * fdiv)/dy + dz * d(GC * fdiv)/dz) at (i+1/2, j, k) // variable sign scalar version template forceinline_macro auto nfdiv_fdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -279,7 +279,7 @@ namespace libmpdataxx + GC1_bar_x(GC[dim+1], i, j , k) * fdiv_corner_xy(psi, GC, G, i, j , k) - GC1_bar_x(GC[dim+1], i, j-1, k) * fdiv_corner_xy(psi, GC, G, i, j-1, k) - + + GC2_bar_x(GC[dim-1], i, j, k ) * fdiv_corner_xz(psi, GC, G, i, j, k ) - GC2_bar_x(GC[dim-1], i, j, k-1) * fdiv_corner_xz(psi, GC, G, i, j, k-1) , @@ -300,14 +300,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised divergence of flux divergence flux i.e. // 1 / (G * psi) * (dx * d(GC * fdiv)/dx + dy * d(GC * fdiv)/dy + dz * d(GC * fdiv)/dz) at (i+1/2, j, k) // infinite gauge version template forceinline_macro auto nfdiv_fdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -322,19 +322,19 @@ namespace libmpdataxx + GC1_bar_x(GC[dim+1], i, j , k) * fdiv_corner_xy(psi, GC, G, i, j , k) - GC1_bar_x(GC[dim+1], i, j-1, k) * fdiv_corner_xy(psi, GC, G, i, j-1, k) - + + GC2_bar_x(GC[dim-1], i, j, k ) * fdiv_corner_xz(psi, GC, G, i, j, k ) - GC2_bar_x(GC[dim-1], i, j, k-1) * fdiv_corner_xz(psi, GC, G, i, j, k-1) ) / G_bar_x(G, i, j, k) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2, j, k) - positive sign scalar version template forceinline_macro auto ndx_fdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -343,7 +343,7 @@ namespace libmpdataxx ) { return return_helper( - 12 * + 12 * frac( fdiv_centre(psi, GC, G, i+1, j, k) - fdiv_centre(psi, GC, G, i , j, k) @@ -363,13 +363,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2, j, k) - variable sign scalar version template forceinline_macro auto ndx_fdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -378,7 +378,7 @@ namespace libmpdataxx ) { return return_helper( - 12 * + 12 * frac( fdiv_centre(psi, GC, G, i+1, j, k) - fdiv_centre(psi, GC, G, i , j, k) @@ -398,13 +398,13 @@ namespace libmpdataxx ) ); } - + // nondimensionalised x derivative of flux divergence i.e. // 1 / (G * psi) * dx * d(fdiv)/dx at (i+1/2, j, k) - infinite gauge version template forceinline_macro auto ndx_fdiv( const arr_3d_t &psi, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -417,15 +417,15 @@ namespace libmpdataxx - fdiv_centre(psi, GC, G, i , j, k) ); } - - // nondimensionalised flux divergence of time derivative of psi i.e. + + // nondimensionalised flux divergence of time derivative of psi i.e. // 1 / (G * psi) * (dx * d(GC * dpsi/dt)/dx + dy * d(GC * dpsi/dt)/dy + dz * d(GC * dpsi/dt)/dz) at (i+1/2, j, k) // positive sign scalar version template forceinline_macro auto nfdiv_dt( const arr_3d_t &psi_np1, const arr_3d_t &psi_n, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -442,11 +442,11 @@ namespace libmpdataxx (psi_np1(pi(i , j, k)) - psi_n(pi(i , j, k))) + GC1_bar_x(GC[dim+1], i, j , k) * - (psi_bar_xy(psi_np1, i, j, k) - psi_bar_xy(psi_n, i, j, k)) + (psi_bar_xy(psi_np1, i, j, k) - psi_bar_xy(psi_n, i, j, k)) - GC1_bar_x(GC[dim+1], i, j-1, k) * - (psi_bar_xy(psi_np1, i, j-1, k) - psi_bar_xy(psi_n, i, j-1, k)) - - + GC2_bar_x(GC[dim-1], i, j, k ) * + (psi_bar_xy(psi_np1, i, j-1, k) - psi_bar_xy(psi_n, i, j-1, k)) + + + GC2_bar_x(GC[dim-1], i, j, k ) * (psi_bar_xz(psi_np1, i, j, k)- psi_bar_xz(psi_n, i, j, k)) - GC2_bar_x(GC[dim-1], i, j, k-1) * (psi_bar_xz(psi_np1, i, j, k-1) - psi_bar_xz(psi_n, i, j, k-1)) @@ -477,14 +477,14 @@ namespace libmpdataxx ); } - // nondimensionalised flux divergence of time derivative of psi i.e. + // nondimensionalised flux divergence of time derivative of psi i.e. // 1 / (G * psi) * (dx * d(GC * dpsi/dt)/dx + dy * d(GC * dpsi/dt)/dy + dz * d(GC * dpsi/dt)/dz) at (i+1/2, j, k) // variable sign scalar version template forceinline_macro auto nfdiv_dt( const arr_3d_t &psi_np1, const arr_3d_t &psi_n, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -501,11 +501,11 @@ namespace libmpdataxx (abs(psi_np1(pi(i , j, k))) - abs(psi_n(pi(i , j, k)))) + GC1_bar_x(GC[dim+1], i, j , k) * - (psi_bar_xy(psi_np1, i, j, k) - psi_bar_xy(psi_n, i, j, k)) + (psi_bar_xy(psi_np1, i, j, k) - psi_bar_xy(psi_n, i, j, k)) - GC1_bar_x(GC[dim+1], i, j-1, k) * - (psi_bar_xy(psi_np1, i, j-1, k) - psi_bar_xy(psi_n, i, j-1, k)) - - + GC2_bar_x(GC[dim-1], i, j, k ) * + (psi_bar_xy(psi_np1, i, j-1, k) - psi_bar_xy(psi_n, i, j-1, k)) + + + GC2_bar_x(GC[dim-1], i, j, k ) * (psi_bar_xz(psi_np1, i, j, k)- psi_bar_xz(psi_n, i, j, k)) - GC2_bar_x(GC[dim-1], i, j, k-1) * (psi_bar_xz(psi_np1, i, j, k-1) - psi_bar_xz(psi_n, i, j, k-1)) @@ -535,15 +535,15 @@ namespace libmpdataxx ) ); } - - // nondimensionalised flux divergence of time derivative of psi i.e. + + // nondimensionalised flux divergence of time derivative of psi i.e. // 1 / (G * psi) * (dx * d(GC * dpsi/dt)/dx + dy * d(GC * dpsi/dt)/dy + dz * d(GC * dpsi/dt)/dz) at (i+1/2, j, k) // infinite gauge version template forceinline_macro auto nfdiv_dt( const arr_3d_t &psi_np1, const arr_3d_t &psi_n, - const arrvec_t &GC, + const arrvec_t &GC, const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -559,11 +559,11 @@ namespace libmpdataxx (psi_np1(pi(i , j, k)) - psi_n(pi(i , j, k))) + GC1_bar_x(GC[dim+1], i, j , k) * - (psi_bar_xy(psi_np1, i, j, k) - psi_bar_xy(psi_n, i, j, k)) + (psi_bar_xy(psi_np1, i, j, k) - psi_bar_xy(psi_n, i, j, k)) - GC1_bar_x(GC[dim+1], i, j-1, k) * - (psi_bar_xy(psi_np1, i, j-1, k) - psi_bar_xy(psi_n, i, j-1, k)) - - + GC2_bar_x(GC[dim-1], i, j, k ) * + (psi_bar_xy(psi_np1, i, j-1, k) - psi_bar_xy(psi_n, i, j-1, k)) + + + GC2_bar_x(GC[dim-1], i, j, k ) * (psi_bar_xz(psi_np1, i, j, k)- psi_bar_xz(psi_n, i, j, k)) - GC2_bar_x(GC[dim-1], i, j, k-1) * (psi_bar_xz(psi_np1, i, j, k-1) - psi_bar_xz(psi_n, i, j, k-1)) @@ -572,4 +572,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_g_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_g_1d.hpp index 58761eed..aaa30e91 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_g_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_g_1d.hpp @@ -10,15 +10,15 @@ #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of G to (i+1/2) - general case template - inline auto G_bar_x( + inline auto G_bar_x( const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 @@ -37,10 +37,10 @@ namespace libmpdataxx const arr_1d_t &G, const ix_t &i, typename std::enable_if::type* = 0 - ) + ) { return 1; } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_g_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_g_2d.hpp index 4ebefaf8..44932ea6 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_g_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_g_2d.hpp @@ -13,21 +13,21 @@ #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of G to (i+1/2, j) - general case template - inline auto G_bar_x( + inline auto G_bar_x( const arr_2d_t &G, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) - { + ) + { return return_helper( ( formulae::G(G, i+1, j) + formulae::G(G, i, j) @@ -45,7 +45,7 @@ namespace libmpdataxx ) { return 1; } - + // interpolation of G to (i+1/2, j+1/2) - general case template inline auto G_bar_xy( @@ -54,7 +54,7 @@ namespace libmpdataxx const ix_t &j, typename std::enable_if::type* = 0 ) - { + { return return_helper( ( formulae::G(G, i , j ) + @@ -64,7 +64,7 @@ namespace libmpdataxx ) / 4 ); } - + // interpolation of G to (i+1/2, j+1/2) - constant G version template inline auto G_bar_xy( @@ -77,4 +77,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_g_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_g_3d.hpp index 213b5b77..916e8112 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_g_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_g_3d.hpp @@ -14,11 +14,11 @@ #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of G to (i+1/2, j, k) - general case template @@ -40,7 +40,7 @@ namespace libmpdataxx // interpolation of G to (i+1/2, j, k) - constant G version template - inline auto G_bar_x( + inline auto G_bar_x( const arr_3d_t &G, const ix_t &i, const ix_t &j, @@ -50,7 +50,7 @@ namespace libmpdataxx { return 1; } - + // interpolation of G to (i+1/2, j+1/2, k) - general case template inline auto G_bar_xy( @@ -70,7 +70,7 @@ namespace libmpdataxx ) / 4 ); } - + // interpolation of G to (i+1/2, j+1/2, k) - constant G version template inline auto G_bar_xy( @@ -83,7 +83,7 @@ namespace libmpdataxx { return 1; } - + // interpolation of G to (i+1/2, j, k+1/2) - general case template inline auto G_bar_xz( @@ -103,7 +103,7 @@ namespace libmpdataxx ) / 4 ); } - + // interpolation of G to (i+1/2, j, k+1/2) - constant G version template inline auto G_bar_xz( @@ -117,4 +117,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_gc_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_gc_1d.hpp index 5d66690d..7dd5694b 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_gc_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_gc_1d.hpp @@ -11,15 +11,15 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of GC[0] to (i) template - inline auto GC0_bar_x( + inline auto GC0_bar_x( const arr_1d_t &GC, const ix_t &i ) @@ -35,7 +35,7 @@ namespace libmpdataxx // dx * dGC[0]/dx at (i+1/2) template inline auto ndx_GC0( - const arr_1d_t &GC, + const arr_1d_t &GC, const ix_t &i ) { @@ -43,13 +43,13 @@ namespace libmpdataxx (GC(i+h+1) - GC(i+h-1)) / 2 ); } - + // nondimensionalised xx derivative of GC[0] i.e. // dx^2 * dGC[0]/dxx at (i+1/2) - general case template inline auto ndxx_GC0( - const arr_1d_t &psi, - const arr_1d_t &GC, + const arr_1d_t &psi, + const arr_1d_t &GC, const ix_t &i, typename std::enable_if::type* = 0 ) @@ -58,29 +58,29 @@ namespace libmpdataxx GC(i+h+1) + GC(i+h-1) - 2 * GC(i+h) ); } - + // nondimensionalised xx derivative of GC[0] i.e. // dx^2 * dGC[0]/dxx at (i+1/2) - infinite gauge version template inline auto ndxx_GC0( - const arr_1d_t &psi, - const arr_1d_t &GC, + const arr_1d_t &psi, + const arr_1d_t &GC, const ix_t &i, typename std::enable_if::type* = 0 ) { return return_helper( - (GC(i+h+1) + GC(i+h-1) - 2 * GC(i+h)) * + (GC(i+h+1) + GC(i+h-1) - 2 * GC(i+h)) * psi_bar_x(psi, i) ); } - + // nondimensionalised tt derivative of GC[0] i.e. // dt^2 * dGC[0]/dtt at (i+1/2) - general case template inline auto ndtt_GC0( - const arr_1d_t &psi, - const arr_1d_t &ndtt_GC, + const arr_1d_t &psi, + const arr_1d_t &ndtt_GC, const ix_t &i, typename std::enable_if::type* = 0 ) @@ -89,13 +89,13 @@ namespace libmpdataxx ndtt_GC(i+h) + 0 ); } - + // nondimensionalised tt derivative of GC[0] i.e. // dGC[0]/dtt at (i+1/2) - infinite-gauge version template inline auto ndtt_GC0( - const arr_1d_t &psi, - const arr_1d_t &ndtt_GC, + const arr_1d_t &psi, + const arr_1d_t &ndtt_GC, const ix_t &i, typename std::enable_if::type* = 0 ) @@ -106,4 +106,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_gc_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_gc_2d.hpp index 3671b3e4..3b58c9b2 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_gc_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_gc_2d.hpp @@ -14,15 +14,15 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of GC[0] to (i, j) template - inline auto GC0_bar_x( + inline auto GC0_bar_x( const arr_2d_t &GC, const ix_t &i, const ix_t &j @@ -38,26 +38,26 @@ namespace libmpdataxx // interpolation of GC[0] to (i, j+1/2) template inline auto GC0_bar_xy( - const arr_2d_t &GC, - const ix_t &i, + const arr_2d_t &GC, + const ix_t &i, const ix_t &j ) { return return_helper( ( - GC(pi(i+h, j )) + + GC(pi(i+h, j )) + GC(pi(i-h, j )) + - GC(pi(i+h, j+1)) + - GC(pi(i-h, j+1)) + GC(pi(i+h, j+1)) + + GC(pi(i-h, j+1)) ) / 4 ); } - - + + // interpolation of GC[1] to (i+1/2, j+1/2) - // caution proper call looks like GC1_bar_x(GC[dim+1], i, j) - note dim vs dim+1 + // caution proper call looks like GC1_bar_x(GC[dim+1], i, j) - note dim vs dim+1 template - inline auto GC1_bar_x( + inline auto GC1_bar_x( const arr_2d_t &GC, const ix_t &i, const ix_t &j @@ -69,22 +69,22 @@ namespace libmpdataxx ) / 2 ); } - + // interpolation of GC[1] to (i+1/2, j) - // caution proper call looks like GC1_bar_xy(GC[dim+1], i, j) - note dim vs dim+1 + // caution proper call looks like GC1_bar_xy(GC[dim+1], i, j) - note dim vs dim+1 template inline auto GC1_bar_xy( - const arr_2d_t &GC, - const ix_t &i, + const arr_2d_t &GC, + const ix_t &i, const ix_t &j ) - { + { return return_helper( ( - GC(pi(i+1, j+h)) + + GC(pi(i+1, j+h)) + GC(pi(i, j+h)) + - GC(pi(i+1, j-h)) + - GC(pi(i, j-h)) + GC(pi(i+1, j-h)) + + GC(pi(i, j-h)) ) / 4 ); } @@ -93,22 +93,22 @@ namespace libmpdataxx // dx * dGC[0]/dx at (i+1/2, j) template inline auto ndx_GC0( - const arr_2d_t &GC, + const arr_2d_t &GC, const ix_t &i, const ix_t &j ) - { + { return return_helper( (GC(pi(i+h+1, j)) - GC(pi(i+h-1, j))) / 2 ); } - + // nondimensionalised xx derivative of GC[0] i.e. // dx^2 * dGC[0]/dxx at (i+1/2, j) - general case template inline auto ndxx_GC0( - const arr_2d_t &psi, - const arr_2d_t &GC, + const arr_2d_t &psi, + const arr_2d_t &GC, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 @@ -118,30 +118,30 @@ namespace libmpdataxx GC(pi(i+h+1, j)) + GC(pi(i+h-1, j)) - 2 * GC(pi(i+h, j)) ); } - + // nondimensionalised xx derivative of GC[0] i.e. // dx^2 * dGC[0]/dxx at (i+1/2, j) - infinite gauge version template inline auto ndxx_GC0( - const arr_2d_t &psi, - const arr_2d_t &GC, + const arr_2d_t &psi, + const arr_2d_t &GC, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) { return return_helper( - (GC(pi(i+h+1, j)) + GC(pi(i+h-1, j)) - 2 * GC(pi(i+h, j))) * + (GC(pi(i+h+1, j)) + GC(pi(i+h-1, j)) - 2 * GC(pi(i+h, j))) * psi_bar_x(psi, i, j) ); } - + // nondimensionalised tt derivative of GC[0] i.e. // dt^2 * dGC[0]/dtt at (i+1/2, j) - general case template inline auto ndtt_GC0( - const arr_2d_t &psi, - const arr_2d_t &ndtt_GC, + const arr_2d_t &psi, + const arr_2d_t &ndtt_GC, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 @@ -151,13 +151,13 @@ namespace libmpdataxx ndtt_GC(pi(i+h, j)) + 0 ); } - + // nondimensionalised tt derivative of GC[0] i.e. // dt^2 * dGC[0]/dtt at (i+1/2, j) - infinite gauge version template inline auto ndtt_GC0( - const arr_2d_t &psi, - const arr_2d_t &ndtt_GC, + const arr_2d_t &psi, + const arr_2d_t &ndtt_GC, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 @@ -169,4 +169,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_gc_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_gc_3d.hpp index f2c3b0fc..1b74d4c6 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_gc_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_gc_3d.hpp @@ -7,9 +7,9 @@ // various numerical expressions relating to the advector field GC // note that the function naming convention and the comments in this file correspond to dim = 0, // if dim = 1 or 2 then you have to mentally perform appropiate substitutions -// for example for dim = 1 (GC[0], GC[1], GC[2]) -> (GC[1], GC[2], GC[0]), +// for example for dim = 1 (GC[0], GC[1], GC[2]) -> (GC[1], GC[2], GC[0]), // (x, y, z) -> (y, z, x) and (i+1/2, j, k) -> (i, j+1/2, k), -// for dim = 2 (GC[0], GC[1], GC[2]) -> (GC[2], GC[0], GC[1]), +// for dim = 2 (GC[0], GC[1], GC[2]) -> (GC[2], GC[0], GC[1]), // (x, y, z) -> (z, x, y) and (i+1/2, j, k) -> (i, j, k+1/2) #pragma once @@ -17,15 +17,15 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of GC[0] to (i, j, k) template - inline auto GC0_bar_x( + inline auto GC0_bar_x( const arr_3d_t &GC, const ix_t &i, const ix_t &j, @@ -34,27 +34,27 @@ namespace libmpdataxx { return return_helper( ( - GC(pi(i+h, j, k)) + + GC(pi(i+h, j, k)) + GC(pi(i-h, j, k)) ) / 2 ); } - + // interpolation of GC[0] to (i, j+1/2, k) template inline auto GC0_bar_xy( - const arr_3d_t &GC, - const ix_t &i, + const arr_3d_t &GC, + const ix_t &i, const ix_t &j, const ix_t &k ) { return return_helper( ( - GC(pi(i+h, j , k)) + + GC(pi(i+h, j , k)) + GC(pi(i-h, j , k)) + - GC(pi(i+h, j+1, k)) + - GC(pi(i-h, j+1, k)) + GC(pi(i+h, j+1, k)) + + GC(pi(i-h, j+1, k)) ) / 4 ); } @@ -62,25 +62,25 @@ namespace libmpdataxx // interpolation of GC[0] to (i, j, k+1/2) template inline auto GC0_bar_xz( - const arr_3d_t &GC, - const ix_t &i, + const arr_3d_t &GC, + const ix_t &i, const ix_t &j, const ix_t &k ) { return return_helper( ( - GC(pi(i+h, j, k )) + + GC(pi(i+h, j, k )) + GC(pi(i-h, j, k )) + - GC(pi(i+h, j, k+1)) + - GC(pi(i-h, j, k+1)) + GC(pi(i+h, j, k+1)) + + GC(pi(i-h, j, k+1)) ) / 4 ); } // interpolation of GC[1] to (i+1/2, j+1/2, k) template - inline auto GC1_bar_x( + inline auto GC1_bar_x( const arr_3d_t &GC, const ix_t &i, const ix_t &j, @@ -89,7 +89,7 @@ namespace libmpdataxx { return return_helper( ( - GC(pi(i+1, j+h, k)) + + GC(pi(i+1, j+h, k)) + GC(pi(i , j+h, k)) ) / 2 ); @@ -98,53 +98,53 @@ namespace libmpdataxx // interpolation of GC[1] to (i+1/2, j, k) template inline auto GC1_bar_xy( - const arr_3d_t &GC, - const ix_t &i, + const arr_3d_t &GC, + const ix_t &i, const ix_t &j, const ix_t &k ) { return return_helper( ( - GC(pi(i+1, j+h, k)) + + GC(pi(i+1, j+h, k)) + GC(pi(i , j+h, k)) + - GC(pi(i+1, j-h, k)) + - GC(pi(i , j-h, k)) + GC(pi(i+1, j-h, k)) + + GC(pi(i , j-h, k)) ) / 4 ); } - + // interpolation of GC[1] to (i+1/2, j+1/2, k+1/2) template inline auto GC1_bar_xz( - const arr_3d_t &GC, - const ix_t &i, + const arr_3d_t &GC, + const ix_t &i, const ix_t &j, const ix_t &k ) { return return_helper( ( - GC(pi(i+1, j+h, k )) + + GC(pi(i+1, j+h, k )) + GC(pi(i+1, j+h, k+1)) + - GC(pi(i , j+h, k )) + - GC(pi(i , j+h, k+1)) + GC(pi(i , j+h, k )) + + GC(pi(i , j+h, k+1)) ) / 4 ); } - + // interpolation of GC[2] to (i+1/2, j, k) template inline auto GC2_bar_x( - const arr_3d_t &GC, - const ix_t &i, + const arr_3d_t &GC, + const ix_t &i, const ix_t &j, const ix_t &k ) { return return_helper( ( - GC(pi(i+1, j, k+h)) + + GC(pi(i+1, j, k+h)) + GC(pi(i , j, k+h)) ) / 2 ); @@ -153,36 +153,36 @@ namespace libmpdataxx // interpolation of GC[2] to (i+1/2, j, k) template inline auto GC2_bar_xz( - const arr_3d_t &GC, - const ix_t &i, + const arr_3d_t &GC, + const ix_t &i, const ix_t &j, const ix_t &k ) { return return_helper( ( - GC(pi(i+1, j, k+h)) + + GC(pi(i+1, j, k+h)) + GC(pi(i , j, k+h)) + - GC(pi(i+1, j, k-h)) + - GC(pi(i , j, k-h)) + GC(pi(i+1, j, k-h)) + + GC(pi(i , j, k-h)) ) / 4 ); } - + // interpolation of GC[2] to (i+1/2, j+1/2, k+1/2) template inline auto GC2_bar_xy( - const arr_3d_t &GC, - const ix_t &i, + const arr_3d_t &GC, + const ix_t &i, const ix_t &j, const ix_t &k ) { return return_helper( ( - GC(pi(i+1, j+1, k+h)) + + GC(pi(i+1, j+1, k+h)) + GC(pi(i , j+1, k+h)) + - GC(pi(i+1, j , k+h)) + + GC(pi(i+1, j , k+h)) + GC(pi(i , j , k+h)) ) / 4 ); @@ -192,7 +192,7 @@ namespace libmpdataxx // dx * dGC[0]/dx at (i+1/2, j, k) template inline auto ndx_GC0( - const arr_3d_t &GC, + const arr_3d_t &GC, const ix_t &i, const ix_t &j, const ix_t &k @@ -202,13 +202,13 @@ namespace libmpdataxx (GC(pi(i+h+1, j, k)) - GC(pi(i+h-1, j, k))) / 2 ); } - + // nondimensionalised xx derivative of GC[0] i.e. // dx^2 * dGC[0]/dxx at (i+1/2, j, k) - general case template inline auto ndxx_GC0( - const arr_3d_t &psi, - const arr_3d_t &GC, + const arr_3d_t &psi, + const arr_3d_t &GC, const ix_t &i, const ix_t &j, const ix_t &k, @@ -219,13 +219,13 @@ namespace libmpdataxx GC(pi(i+h+1, j, k)) + GC(pi(i+h-1, j, k)) - 2 * GC(pi(i+h, j, k)) ); } - + // nondimensionalised xx derivative of GC[0] i.e. // dx^2 * dGC[0]/dxx at (i+1/2, j, k) - infinite gauge version template inline auto ndxx_GC0( - const arr_3d_t &psi, - const arr_3d_t &GC, + const arr_3d_t &psi, + const arr_3d_t &GC, const ix_t &i, const ix_t &j, const ix_t &k, @@ -233,16 +233,16 @@ namespace libmpdataxx ) { return return_helper( - (GC(pi(i+h+1, j, k)) + GC(pi(i+h-1, j, k)) - 2 * GC(pi(i+h, j, k))) * + (GC(pi(i+h+1, j, k)) + GC(pi(i+h-1, j, k)) - 2 * GC(pi(i+h, j, k))) * psi_bar_x(psi, i, j, k) ); } - + // nondimensionalised tt derivative of GC[0] i.e. // dt^2 * dGC[0]/dtt at (i+1/2, j, k) - general case template inline auto ndtt_GC0( - const arr_3d_t &psi, + const arr_3d_t &psi, const arr_3d_t &ndtt_GC, const ix_t &i, const ix_t &j, @@ -254,12 +254,12 @@ namespace libmpdataxx ndtt_GC(pi(i+h, j, k)) + 0 ); } - + // nondimensionalised tt derivative of GC[0] i.e. // dt^2 * dGC[0]/dtt at (i+1/2, j, k) - infinite gauge version template inline auto ndtt_GC0( - const arr_3d_t &psi, + const arr_3d_t &psi, const arr_3d_t &ndtt_GC, const ix_t &i, const ix_t &j, @@ -273,4 +273,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespace libmpdataxx +} // namespace libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_hot_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_hot_1d.hpp index 94b70891..7538896a 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_hot_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_hot_1d.hpp @@ -11,10 +11,10 @@ #include namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +{ + namespace formulae + { + namespace mpdata { template forceinline_macro auto ndxx_psi_coeff( @@ -39,23 +39,23 @@ namespace libmpdataxx const arr_1d_t &GC, const arr_1d_t &G, const ix_t &i, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) { return return_helper( ndxx_psi(psi, i) * ndxx_psi_coeff(GC, G, i) ); } - + template forceinline_macro auto TOT( const arr_1d_t &psi, const arr_1d_t &GC, const arr_1d_t &G, const ix_t &i, - typename std::enable_if::type* = 0 + typename std::enable_if::type* = 0 ) - { + { return 0; } } // namespace mpdata diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_hot_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_hot_2d.hpp index 16d40160..4266ac9a 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_hot_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_hot_2d.hpp @@ -12,11 +12,11 @@ #include #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { template forceinline_macro auto ndxx_psi_coeff( @@ -44,11 +44,11 @@ namespace libmpdataxx ) { return return_helper( - (abs(GC[dim](pi(i+h, j))) - 2 * pow2(GC[dim](pi(i+h, j))) / G_bar_x(G, i, j)) + (abs(GC[dim](pi(i+h, j))) - 2 * pow2(GC[dim](pi(i+h, j))) / G_bar_x(G, i, j)) * GC1_bar_xy(GC[dim+1], i, j) / (2 * G_bar_x(G, i, j)) ); } - + // third order terms template forceinline_macro auto TOT( @@ -58,11 +58,11 @@ namespace libmpdataxx const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) + ) { return return_helper( - ndxx_psi(psi, i, j) * ndxx_psi_coeff(GC[dim], G, i, j) - + + ndxx_psi(psi, i, j) * ndxx_psi_coeff(GC[dim], G, i, j) + + ndxy_psi(psi, i, j) * ndxy_psi_coeff(GC, G, i, j) ); } @@ -96,7 +96,7 @@ namespace libmpdataxx ) / 2 ); } - + template forceinline_macro auto ndxxy_psi_coeff( const arrvec_t &GC, @@ -106,13 +106,13 @@ namespace libmpdataxx ) { return return_helper( - 3 * - (abs(GC[dim](pi(i+h, j))) - pow2(GC[dim](pi(i+h, j))) / G_bar_x(G, i, j)) + 3 * + (abs(GC[dim](pi(i+h, j))) - pow2(GC[dim](pi(i+h, j))) / G_bar_x(G, i, j)) * GC[dim](pi(i+h, j)) * GC1_bar_xy(GC[dim-1], i, j) / pow2(G_bar_x(G, i, j)) ); } - + template forceinline_macro auto ndxyy_psi_coeff( const arrvec_t &GC, @@ -132,7 +132,7 @@ namespace libmpdataxx ) / G_bar_x(G, i, j) / 4 ); } - + // fourth order terms template forceinline_macro auto FOT( @@ -148,10 +148,10 @@ namespace libmpdataxx "adding fourth-order terms makes sense only when third-order terms are present (tot or div_3rd option)"); static_assert(opts::isset(opts, opts::iga), "fot option only available with iga"); return return_helper( - ndxxx_psi(psi, i, j) * ndxxx_psi_coeff(GC[dim], G, i, j) - + + ndxxx_psi(psi, i, j) * ndxxx_psi_coeff(GC[dim], G, i, j) + + ndxxy_psi(psi, i, j) * ndxxy_psi_coeff(GC, G, i, j) - + + + ndxyy_psi(psi, i, j) * ndxyy_psi_coeff(GC, G, i, j) ); } @@ -170,4 +170,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespcae libmpdataxx +} // namespcae libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_hot_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_hot_3d.hpp index fc2afd3f..79ad44ed 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_hot_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_hot_3d.hpp @@ -99,11 +99,11 @@ namespace libmpdataxx { return return_helper( ndxx_psi(psi, i, j, k) * ndxx_psi_coeff(GC[dim], G, i, j, k) - + + + ndxy_psi(psi, i, j, k) * ndxy_psi_coeff(GC, G, i, j, k) - + + + ndxz_psi(psi, i, j, k) * ndxz_psi_coeff(GC, G, i, j, k) - + + + ndyz_psi(psi, i, j, k) * ndyz_psi_coeff(GC, G, i, j, k) ); } diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_psi_1d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_psi_1d.hpp index 9b7c24ec..98f1eb01 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_psi_1d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_psi_1d.hpp @@ -10,15 +10,15 @@ #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of psi to (i+1/2) - positive sign scalar / infinite gauge version template - inline auto psi_bar_x( + inline auto psi_bar_x( const arr_1d_t &psi, const ix_t &i, typename std::enable_if::type* = 0 @@ -30,10 +30,10 @@ namespace libmpdataxx ) / 2 ); } - + // interpolation of psi to (i+1/2) - variable sign scalar version template - inline auto psi_bar_x( + inline auto psi_bar_x( const arr_1d_t &psi, const ix_t &i, typename std::enable_if::type* = 0 @@ -47,11 +47,11 @@ namespace libmpdataxx } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2) - positive sign scalar version + // dx/psi * dpsi/dx at (i+1/2) - positive sign scalar version template inline auto ndx_psi( - const arr_1d_t &psi, - const ix_t &i, + const arr_1d_t &psi, + const ix_t &i, typename std::enable_if::type* = 0 ) { @@ -66,11 +66,11 @@ namespace libmpdataxx } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2) - variable-sign scalar version + // dx/psi * dpsi/dx at (i+1/2) - variable-sign scalar version template inline auto ndx_psi( - const arr_1d_t &psi, - const ix_t &i, + const arr_1d_t &psi, + const ix_t &i, typename std::enable_if::type* = 0 ) { @@ -80,16 +80,16 @@ namespace libmpdataxx abs(psi(i+1)) - abs(psi(i)) ,// ----------------------- abs(psi(i+1)) + abs(psi(i)) - ) + ) ); } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2) - infinite gauge version + // dx/psi * dpsi/dx at (i+1/2) - infinite gauge version template inline auto ndx_psi( - const arr_1d_t &psi, - const ix_t &i, + const arr_1d_t &psi, + const ix_t &i, typename std::enable_if::type* = 0 ) { @@ -103,7 +103,7 @@ namespace libmpdataxx ) ); } - + // nondimensionalised xx derivative of psi i.e. // dx^2/psi * dpsi/dxx at (i+1/2) - positive sign scalar version template @@ -130,7 +130,7 @@ namespace libmpdataxx const arr_1d_t &psi, const ix_t &i, typename std::enable_if::type* = 0 - ) + ) { return return_helper( 2 * @@ -149,7 +149,7 @@ namespace libmpdataxx const arr_1d_t &psi, const ix_t &i, typename std::enable_if::type* = 0 - ) + ) { static_assert(!opts::isset(opts, opts::abs), "iga & abs are mutually exclusive"); return return_helper( @@ -161,4 +161,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespcae libmpdataxx +} // namespcae libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_psi_2d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_psi_2d.hpp index cab81531..d8a5255d 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_psi_2d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_psi_2d.hpp @@ -13,20 +13,20 @@ #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of psi to (i+1/2, j) - positive sign scalar / infinite gauge version template - inline auto psi_bar_x( + inline auto psi_bar_x( const arr_2d_t &psi, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) + ) { return return_helper( ( @@ -34,15 +34,15 @@ namespace libmpdataxx ) / 2 ); } - + // interpolation of psi to (i+1/2, j) - variable sign scalar version template - inline auto psi_bar_x( + inline auto psi_bar_x( const arr_2d_t &psi, const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) + ) { return return_helper( ( @@ -50,10 +50,10 @@ namespace libmpdataxx ) / 2 ); } - + // interpolation of psi to (i, j+1/2) - positive sign scalar / infinite gauge version template - inline auto psi_bar_y( + inline auto psi_bar_y( const arr_2d_t &psi, const ix_t &i, const ix_t &j, @@ -69,7 +69,7 @@ namespace libmpdataxx // interpolation of psi to (i, j+1/2) - variable sign scalar version template - inline auto psi_bar_y( + inline auto psi_bar_y( const arr_2d_t &psi, const ix_t &i, const ix_t &j, @@ -82,10 +82,10 @@ namespace libmpdataxx ) / 2 ); } - + // interpolation of psi to (i+1/2, j+1/2) - positive sign scalar / infinite gauge version template - inline auto psi_bar_xy( + inline auto psi_bar_xy( const arr_2d_t &psi, const ix_t &i, const ix_t &j, @@ -94,7 +94,7 @@ namespace libmpdataxx { return return_helper( ( - psi(pi(i+1, j )) + + psi(pi(i+1, j )) + psi(pi(i , j )) + psi(pi(i , j+1)) + psi(pi(i+1, j+1)) @@ -104,7 +104,7 @@ namespace libmpdataxx // interpolation of psi to (i+1/2, j+1/2) - variable sign scalar version template - inline auto psi_bar_xy( + inline auto psi_bar_xy( const arr_2d_t &psi, const ix_t &i, const ix_t &j, @@ -113,7 +113,7 @@ namespace libmpdataxx { return return_helper( ( - abs(psi(pi(i+1, j ))) + + abs(psi(pi(i+1, j ))) + abs(psi(pi(i , j ))) + abs(psi(pi(i , j+1))) + abs(psi(pi(i+1, j+1))) @@ -122,14 +122,14 @@ namespace libmpdataxx } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2, j) - positive sign scalar version + // dx/psi * dpsi/dx at (i+1/2, j) - positive sign scalar version template inline auto ndx_psi( - const arr_2d_t &psi, - const ix_t &i, + const arr_2d_t &psi, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) + ) { return return_helper( 2 * @@ -142,11 +142,11 @@ namespace libmpdataxx } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2, j) - variable-sign scalar version + // dx/psi * dpsi/dx at (i+1/2, j) - variable-sign scalar version template inline auto ndx_psi( - const arr_2d_t &psi, - const ix_t &i, + const arr_2d_t &psi, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -157,16 +157,16 @@ namespace libmpdataxx abs(psi(pi(i+1, j))) - abs(psi(pi(i, j))) ,// ------------------------------------------- abs(psi(pi(i+1, j))) + abs(psi(pi(i, j))) - ) + ) ); } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2, j) - infinite gauge version + // dx/psi * dpsi/dx at (i+1/2, j) - infinite gauge version template inline auto ndx_psi( - const arr_2d_t &psi, - const ix_t &i, + const arr_2d_t &psi, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -181,19 +181,19 @@ namespace libmpdataxx ) ); } - + // nondimensionalised y derivative of psi i.e. // dy/psi * dpsi/dy at (i+1/2, j) - positive sign scalar version template inline auto ndy_psi( - const arr_2d_t &psi, - const ix_t &i, + const arr_2d_t &psi, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) { return return_helper( - frac( + frac( psi(pi(i+1, j+1)) + psi(pi(i, j+1)) - psi(pi(i+1, j-1)) - psi(pi(i, j-1)) ,// --------------------------------------------------------------------------------- psi(pi(i+1, j+1)) + psi(pi(i, j+1)) + psi(pi(i+1, j-1)) + psi(pi(i, j-1)) @@ -205,14 +205,14 @@ namespace libmpdataxx // dy/psi * dpsi/dy at (i+1/2, j) - variable sign scalar version template inline auto ndy_psi( - const arr_2d_t &psi, - const ix_t &i, + const arr_2d_t &psi, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) { return return_helper( - frac( + frac( abs(psi(pi(i+1, j+1))) + abs(psi(pi(i, j+1))) - abs(psi(pi(i+1, j-1))) - abs(psi(pi(i, j-1))) ,// ----------------------------------------------------------------------------------------------------- abs(psi(pi(i+1, j+1))) + abs(psi(pi(i, j+1))) + abs(psi(pi(i+1, j-1))) + abs(psi(pi(i, j-1))) @@ -224,8 +224,8 @@ namespace libmpdataxx // dy/psi * dpsi/dy at (i+1/2, j) - infinite gauge version template inline auto ndy_psi( - const arr_2d_t &psi, - const ix_t &i, + const arr_2d_t &psi, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -239,7 +239,7 @@ namespace libmpdataxx ) ); } - + // nondimensionalised xx derivative of psi i.e. // dx^2/psi * dpsi/dxx at (i+1/2, j) - positive sign scalar version template @@ -312,7 +312,7 @@ namespace libmpdataxx return return_helper( 2 * frac( - psi(pi(i+1, j+1)) - psi(pi(i, j+1)) - psi(pi(i+1, j-1)) + psi(pi(i, j-1)) + psi(pi(i+1, j+1)) - psi(pi(i, j+1)) - psi(pi(i+1, j-1)) + psi(pi(i, j-1)) ,//----------------------------------------------------------------------------------------- psi(pi(i+1, j+1)) + psi(pi(i, j+1)) + psi(pi(i+1, j-1)) + psi(pi(i, j-1)) ) @@ -332,7 +332,7 @@ namespace libmpdataxx return return_helper( 2 * frac( - abs(psi(pi(i+1, j+1))) - abs(psi(pi(i, j+1))) - abs(psi(pi(i+1, j-1))) + abs(psi(pi(i, j-1))) + abs(psi(pi(i+1, j+1))) - abs(psi(pi(i, j+1))) - abs(psi(pi(i+1, j-1))) + abs(psi(pi(i, j-1))) ,//------------------------------------------------------------------------------------------------------------- abs(psi(pi(i+1, j+1))) + abs(psi(pi(i, j+1))) + abs(psi(pi(i+1, j-1))) + abs(psi(pi(i, j-1))) ) @@ -352,7 +352,7 @@ namespace libmpdataxx static_assert(!opts::isset(opts, opts::abs), "iga & abs options are mutually exclusive"); return return_helper( 2 * - (psi(pi(i+1, j+1)) - psi(pi(i, j+1)) - psi(pi(i+1, j-1)) + psi(pi(i, j-1))) + (psi(pi(i+1, j+1)) - psi(pi(i, j+1)) - psi(pi(i+1, j-1)) + psi(pi(i, j-1))) / //------------------------------------------------------------------------------------------- (1 + 1 + 1 + 1) ); @@ -374,7 +374,7 @@ namespace libmpdataxx (1 + 1 + 1 + 1) ); } - + // nondimensionalised xxy derivative of psi i.e. // dx^2*dy/psi * dpsi/dxxy at (i+1/2, j) - infinite gauge version template @@ -383,16 +383,16 @@ namespace libmpdataxx const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 - ) + ) { return return_helper( - ( psi(pi(i+2, j+1)) - psi(pi(i+1, j+1)) - psi(pi(i, j+1)) + psi(pi(i-1, j+1)) + ( psi(pi(i+2, j+1)) - psi(pi(i+1, j+1)) - psi(pi(i, j+1)) + psi(pi(i-1, j+1)) -psi(pi(i+2, j-1)) + psi(pi(i+1, j-1)) + psi(pi(i, j-1)) - psi(pi(i-1, j-1)) ) / //------------------------------------------------------------------------------------------------ (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1) ); } - + // nondimensionalised xyy derivative of psi i.e. // dx*dy^2/psi * dpsi/dxyy at (i+1/2, j) - infinite gauge version template @@ -412,12 +412,12 @@ namespace libmpdataxx } // nondimensionalised tx derivative of psi i.e. - // dx*dt/psi * dpsi/dtx at (i+1/2, j) - positive sign scalar version + // dx*dt/psi * dpsi/dtx at (i+1/2, j) - positive sign scalar version template inline auto ndtx_psi( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, - const ix_t &i, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -437,14 +437,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised tx derivative of psi i.e. - // dx*dt/psi * dpsi/dtx at (i+1/2, j) - variable sign scalar version + // dx*dt/psi * dpsi/dtx at (i+1/2, j) - variable sign scalar version template inline auto ndtx_psi( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, - const ix_t &i, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -464,14 +464,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised tx derivative of psi i.e. - // dx*dt/psi * dpsi/dtx at (i+1/2, j) - infinite gauge version + // dx*dt/psi * dpsi/dtx at (i+1/2, j) - infinite gauge version template inline auto ndtx_psi( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, - const ix_t &i, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -485,12 +485,12 @@ namespace libmpdataxx } // nondimensionalised t derivative of psi i.e. - // dt/psi * dpsi/dt at (i+1/2, j) - positive sign scalar version + // dt/psi * dpsi/dt at (i+1/2, j) - positive sign scalar version template inline auto ndt_psi( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, - const ix_t &i, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -510,14 +510,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised t derivative of psi i.e. - // dt/psi * dpsi/dt at (i+1/2, j) - variable sign scalar version + // dt/psi * dpsi/dt at (i+1/2, j) - variable sign scalar version template inline auto ndt_psi( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, - const ix_t &i, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -537,14 +537,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised t derivative of psi i.e. - // dt/psi * dpsi/dt at (i+1/2, j) - infinite gauge version + // dt/psi * dpsi/dt at (i+1/2, j) - infinite gauge version template inline auto ndt_psi( - const arr_2d_t &psi_np1, - const arr_2d_t &psi_n, - const ix_t &i, + const arr_2d_t &psi_np1, + const arr_2d_t &psi_n, + const ix_t &i, const ix_t &j, typename std::enable_if::type* = 0 ) @@ -560,4 +560,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespcae libmpdataxx +} // namespcae libmpdataxx diff --git a/libmpdata++/formulae/mpdata/formulae_mpdata_psi_3d.hpp b/libmpdata++/formulae/mpdata/formulae_mpdata_psi_3d.hpp index 2f0c30c6..329c7210 100644 --- a/libmpdata++/formulae/mpdata/formulae_mpdata_psi_3d.hpp +++ b/libmpdata++/formulae/mpdata/formulae_mpdata_psi_3d.hpp @@ -14,15 +14,15 @@ #include -namespace libmpdataxx -{ - namespace formulae - { - namespace mpdata +namespace libmpdataxx +{ + namespace formulae + { + namespace mpdata { // interpolation of psi to (i+1/2, j, k) - positive sign scalar / infinite gauge version template - inline auto psi_bar_x( + inline auto psi_bar_x( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -32,15 +32,15 @@ namespace libmpdataxx { return return_helper( ( - psi(pi(i+1, j, k)) + + psi(pi(i+1, j, k)) + psi(pi(i , j, k)) ) / 2 ); } - + // interpolation of psi to (i+1/2, j, k) - variable sign scalar version template - inline auto psi_bar_x( + inline auto psi_bar_x( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -50,15 +50,15 @@ namespace libmpdataxx { return return_helper( ( - abs(psi(pi(i+1, j, k))) + + abs(psi(pi(i+1, j, k))) + abs(psi(pi(i , j, k))) ) / 2 ); } - + // interpolation of psi to (i, j+1/2, k) - positive sign scalar / infinite gauge version template - inline auto psi_bar_y( + inline auto psi_bar_y( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -68,7 +68,7 @@ namespace libmpdataxx { return return_helper( ( - psi(pi(i, j , k)) + + psi(pi(i, j , k)) + psi(pi(i, j+1, k)) ) / 2 ); @@ -76,7 +76,7 @@ namespace libmpdataxx // interpolation of psi to (i, j+1/2, k) - variable sign scalar version template - inline auto psi_bar_y( + inline auto psi_bar_y( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -86,15 +86,15 @@ namespace libmpdataxx { return return_helper( ( - abs(psi(pi(i, j , k))) + + abs(psi(pi(i, j , k))) + abs(psi(pi(i, j+1, k))) ) / 2 ); } - + // interpolation of psi to (i, j, k+1/2) - positive sign scalar / infinite gauge version template - inline auto psi_bar_z( + inline auto psi_bar_z( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -104,7 +104,7 @@ namespace libmpdataxx { return return_helper( ( - psi(pi(i, j, k )) + + psi(pi(i, j, k )) + psi(pi(i, j, k+1)) ) / 2 ); @@ -112,7 +112,7 @@ namespace libmpdataxx // interpolation of psi to (i, j, k+1/2) - variable sign scalar version template - inline auto psi_bar_z( + inline auto psi_bar_z( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -122,15 +122,15 @@ namespace libmpdataxx { return return_helper( ( - abs(psi(pi(i, j, k ))) + + abs(psi(pi(i, j, k ))) + abs(psi(pi(i, j, k+1))) ) / 2 ); } - + // interpolation of psi to (i+1/2, j+1/2, k) - positive sign scalar / infinite gauge version template - inline auto psi_bar_xy( + inline auto psi_bar_xy( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -140,7 +140,7 @@ namespace libmpdataxx { return return_helper( ( - psi(pi(i+1, j , k)) + + psi(pi(i+1, j , k)) + psi(pi(i , j , k)) + psi(pi(i , j+1, k)) + psi(pi(i+1, j+1, k)) @@ -150,7 +150,7 @@ namespace libmpdataxx // interpolation of psi to (i+1/2, j+1/2, k) - variable sign scalar version template - inline auto psi_bar_xy( + inline auto psi_bar_xy( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -160,17 +160,17 @@ namespace libmpdataxx { return return_helper( ( - abs(psi(pi(i+1, j , k))) + + abs(psi(pi(i+1, j , k))) + abs(psi(pi(i , j , k))) + abs(psi(pi(i , j+1, k))) + abs(psi(pi(i+1, j+1, k))) ) / 4 ); } - + // interpolation of psi to (i+1/2, j, k+1/2) - positive sign scalar / infinite gauge version template - inline auto psi_bar_xz( + inline auto psi_bar_xz( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -180,7 +180,7 @@ namespace libmpdataxx { return return_helper( ( - psi(pi(i+1, j , k)) + + psi(pi(i+1, j , k)) + psi(pi(i , j , k)) + psi(pi(i , j, k+1)) + psi(pi(i+1, j, k+1)) @@ -190,7 +190,7 @@ namespace libmpdataxx // interpolation of psi to (i+1/2, j, k+1/2) - variable sign scalar version template - inline auto psi_bar_xz( + inline auto psi_bar_xz( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -200,17 +200,17 @@ namespace libmpdataxx { return return_helper( ( - abs(psi(pi(i+1, j , k))) + + abs(psi(pi(i+1, j , k))) + abs(psi(pi(i , j , k))) + abs(psi(pi(i , j, k+1))) + abs(psi(pi(i+1, j, k+1))) ) / 4 ); } - + // interpolation of psi to (i+1/2, j+1/2, k+1/2) - positive sign scalar / infinite gauge version template - inline auto psi_bar_xyz( + inline auto psi_bar_xyz( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -221,20 +221,20 @@ namespace libmpdataxx return return_helper( ( psi(pi(i , j , k )) + - psi(pi(i+1, j , k )) + + psi(pi(i+1, j , k )) + psi(pi(i , j+1, k )) + psi(pi(i , j , k+1)) + - psi(pi(i+1, j+1, k )) + - psi(pi(i+1, j , k+1)) + - psi(pi(i , j+1, k+1)) + + psi(pi(i+1, j+1, k )) + + psi(pi(i+1, j , k+1)) + + psi(pi(i , j+1, k+1)) + psi(pi(i+1, j+1, k+1)) ) / 8 ); } - + // interpolation of psi to (i+1/2, j+1/2, k+1/2) - variable sign scalar version template - inline auto psi_bar_xyz( + inline auto psi_bar_xyz( const arr_3d_t &psi, const ix_t &i, const ix_t &j, @@ -245,23 +245,23 @@ namespace libmpdataxx return return_helper( ( abs(psi(pi(i , j , k ))) + - abs(psi(pi(i+1, j , k ))) + + abs(psi(pi(i+1, j , k ))) + abs(psi(pi(i , j+1, k ))) + abs(psi(pi(i , j , k+1))) + - abs(psi(pi(i+1, j+1, k ))) + - abs(psi(pi(i+1, j , k+1))) + - abs(psi(pi(i , j+1, k+1))) + + abs(psi(pi(i+1, j+1, k ))) + + abs(psi(pi(i+1, j , k+1))) + + abs(psi(pi(i , j+1, k+1))) + abs(psi(pi(i+1, j+1, k+1))) ) / 8 ); } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2, j, k) - positive sign scalar version + // dx/psi * dpsi/dx at (i+1/2, j, k) - positive sign scalar version template inline auto ndx_psi( - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -278,11 +278,11 @@ namespace libmpdataxx } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2, j, k) - variable-sign scalar version + // dx/psi * dpsi/dx at (i+1/2, j, k) - variable-sign scalar version template inline auto ndx_psi( - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -294,16 +294,16 @@ namespace libmpdataxx abs(psi(pi(i+1, j, k))) - abs(psi(pi(i, j, k))) , abs(psi(pi(i+1, j, k))) + abs(psi(pi(i, j, k))) - ) + ) ); } // nondimensionalised x derivative of psi i.e. - // dx/psi * dpsi/dx at (i+1/2, j, k) - infinite gauge version + // dx/psi * dpsi/dx at (i+1/2, j, k) - infinite gauge version template inline auto ndx_psi( // inf. gauge option - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -319,15 +319,15 @@ namespace libmpdataxx // dy/psi * dpsi/dy at (i+1/2, j, k) - positive sign scalar version template inline auto ndy_psi( - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 ) { return return_helper( - frac( + frac( psi(pi(i+1, j+1, k)) + psi(pi(i , j+1, k)) - psi(pi(i+1, j-1, k)) @@ -345,15 +345,15 @@ namespace libmpdataxx // dy/psi * dpsi/dy at (i+1/2, j, k) - variable sign scalar version template inline auto ndy_psi( - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 ) { return return_helper( - frac( + frac( abs(psi(pi(i+1, j+1, k))) + abs(psi(pi(i , j+1, k))) - abs(psi(pi(i+1, j-1, k))) @@ -371,8 +371,8 @@ namespace libmpdataxx // dy/psi * dpsi/dy at (i+1/2, j, k) - infinite gauge version template inline auto ndy_psi( - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -388,20 +388,20 @@ namespace libmpdataxx ) / 4 ); } - + // nondimensionalised z derivative of psi i.e. // dz/psi * dpsi/dz at (i+1/2, j, k) - positive sign scalar version template inline auto ndz_psi( // positive sign signal - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 ) { return return_helper( - frac( + frac( psi(pi(i+1, j, k+1)) + psi(pi(i , j, k+1)) - psi(pi(i+1, j, k-1)) @@ -419,15 +419,15 @@ namespace libmpdataxx // dz/psi * dpsi/dz at (i+1/2, j, k) - variable sign scalar version template inline auto ndz_psi( - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 ) { return return_helper( - frac( + frac( abs(psi(pi(i+1, j, k+1))) + abs(psi(pi(i , j, k+1))) - abs(psi(pi(i+1, j, k-1))) @@ -445,8 +445,8 @@ namespace libmpdataxx // dz/psi * dpsi/dz at (i+1/2, j, k) - infinite gauge version template inline auto ndz_psi( - const arr_3d_t &psi, - const ix_t &i, + const arr_3d_t &psi, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -556,7 +556,7 @@ namespace libmpdataxx psi(pi(i+1, j+1, k)) - psi(pi(i , j+1, k)) - psi(pi(i+1, j-1, k)) - + psi(pi(i , j-1, k)) + + psi(pi(i , j-1, k)) , psi(pi(i+1, j+1, k)) + psi(pi(i , j+1, k)) @@ -583,7 +583,7 @@ namespace libmpdataxx abs(psi(pi(i+1, j+1, k))) - abs(psi(pi(i , j+1, k))) - abs(psi(pi(i+1, j-1, k))) - + abs(psi(pi(i , j-1, k))) + + abs(psi(pi(i , j-1, k))) , abs(psi(pi(i+1, j+1, k))) + abs(psi(pi(i , j+1, k))) @@ -610,11 +610,11 @@ namespace libmpdataxx psi(pi(i+1, j+1, k)) - psi(pi(i , j+1, k)) - psi(pi(i+1, j-1, k)) - + psi(pi(i , j-1, k)) + + psi(pi(i , j-1, k)) ) / 4 ); } - + // nondimensionalised xz derivative of psi i.e. // dx*dz/psi * dpsi/dxdz at (i+1/2, j, k) - positive sign scalar version template @@ -632,7 +632,7 @@ namespace libmpdataxx psi(pi(i+1, j, k+1)) - psi(pi(i , j, k+1)) - psi(pi(i+1, j, k-1)) - + psi(pi(i , j, k-1)) + + psi(pi(i , j, k-1)) , psi(pi(i+1, j, k+1)) + psi(pi(i , j, k+1)) @@ -641,7 +641,7 @@ namespace libmpdataxx ) ); } - + // nondimensionalised xz derivative of psi i.e. // dx*dz/psi * dpsi/dxdz at (i+1/2, j, k) - variable sign scalar version template @@ -659,7 +659,7 @@ namespace libmpdataxx abs(psi(pi(i+1, j, k+1))) - abs(psi(pi(i , j, k+1))) - abs(psi(pi(i+1, j, k-1))) - + abs(psi(pi(i , j, k-1))) + + abs(psi(pi(i , j, k-1))) , abs(psi(pi(i+1, j, k+1))) + abs(psi(pi(i , j, k+1))) @@ -668,7 +668,7 @@ namespace libmpdataxx ) ); } - + // nondimensionalised xz derivative of psi i.e. // dx*dz/psi * dpsi/dxdz at (i+1/2, j, k) - infinite gauge version template @@ -686,7 +686,7 @@ namespace libmpdataxx psi(pi(i+1, j, k+1)) - psi(pi(i , j, k+1)) - psi(pi(i+1, j, k-1)) - + psi(pi(i , j, k-1)) + + psi(pi(i , j, k-1)) ) / 4 ); } @@ -707,19 +707,19 @@ namespace libmpdataxx psi(pi(i+1, j+1, k+1)) + psi(pi(i+1, j-1, k-1)) - psi(pi(i+1, j+1, k-1)) - - psi(pi(i+1, j-1, k+1)) + - psi(pi(i+1, j-1, k+1)) + psi(pi(i , j+1, k+1)) + psi(pi(i , j-1, k-1)) - - psi(pi(i , j+1, k-1)) + - psi(pi(i , j+1, k-1)) - psi(pi(i , j-1, k+1)) , //------------------------- psi(pi(i+1, j+1, k+1)) + psi(pi(i+1, j-1, k-1)) + psi(pi(i+1, j+1, k-1)) - + psi(pi(i+1, j-1, k+1)) + + psi(pi(i+1, j-1, k+1)) + psi(pi(i , j+1, k+1)) + psi(pi(i , j-1, k-1)) - + psi(pi(i , j+1, k-1)) + + psi(pi(i , j+1, k-1)) + psi(pi(i , j-1, k+1)) ) ); @@ -741,19 +741,19 @@ namespace libmpdataxx abs(psi(pi(i+1, j+1, k+1))) + abs(psi(pi(i+1, j-1, k-1))) - abs(psi(pi(i+1, j+1, k-1))) - - abs(psi(pi(i+1, j-1, k+1))) + - abs(psi(pi(i+1, j-1, k+1))) + abs(psi(pi(i , j+1, k+1))) + abs(psi(pi(i , j-1, k-1))) - - abs(psi(pi(i , j+1, k-1))) + - abs(psi(pi(i , j+1, k-1))) - abs(psi(pi(i , j-1, k+1))) , //------------------------------ abs(psi(pi(i+1, j+1, k+1))) + abs(psi(pi(i+1, j-1, k-1))) + abs(psi(pi(i+1, j+1, k-1))) - + abs(psi(pi(i+1, j-1, k+1))) + + abs(psi(pi(i+1, j-1, k+1))) + abs(psi(pi(i , j+1, k+1))) + abs(psi(pi(i , j-1, k-1))) - + abs(psi(pi(i , j+1, k-1))) + + abs(psi(pi(i , j+1, k-1))) + abs(psi(pi(i , j-1, k+1))) ) ); @@ -768,7 +768,7 @@ namespace libmpdataxx const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 - ) + ) { static_assert(!opts::isset(opts, opts::abs), "iga & abs options are mutually exclusive"); return return_helper( @@ -778,7 +778,7 @@ namespace libmpdataxx - psi(pi(i+1, j+1, k-1)) - psi(pi(i+1, j-1, k+1)) + psi(pi(i , j+1, k+1)) - + psi(pi(i , j-1, k-1)) + + psi(pi(i , j-1, k-1)) - psi(pi(i , j+1, k-1)) - psi(pi(i , j-1, k+1)) ) @@ -788,14 +788,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised tx derivative of psi i.e. - // dx*dt/psi * dpsi/dtx at (i+1/2, j, k) - positive sign scalar version + // dx*dt/psi * dpsi/dtx at (i+1/2, j, k) - positive sign scalar version template inline auto ndtx_psi( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, - const ix_t &i, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -816,14 +816,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised tx derivative of psi i.e. - // dx*dt/psi * dpsi/dtx at (i+1/2, j, k) - variable sign scalar version + // dx*dt/psi * dpsi/dtx at (i+1/2, j, k) - variable sign scalar version template inline auto ndtx_psi( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, - const ix_t &i, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -844,14 +844,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised tx derivative of psi i.e. // dx*dt/psi * dpsi/dtx at (i+1/2, j, k) - infinite gauge version template inline auto ndtx_psi( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, - const ix_t &i, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -862,14 +862,14 @@ namespace libmpdataxx psi_np1(pi(i+1, j, k)) - psi_n(pi(i+1, j, k)) - psi_np1(pi(i, j, k)) + psi_n(pi(i, j, k)) ); } - + // nondimensionalised t derivative of psi i.e. - // dt/psi * dpsi/dt at (i+1/2, j, k) - positive sign scalar version + // dt/psi * dpsi/dt at (i+1/2, j, k) - positive sign scalar version template inline auto ndt_psi( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, - const ix_t &i, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -890,14 +890,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised t derivative of psi i.e. - // dt/psi * dpsi/dt at (i+1/2, j, k) - variable sign scalar version + // dt/psi * dpsi/dt at (i+1/2, j, k) - variable sign scalar version template inline auto ndt_psi( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, - const ix_t &i, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -918,14 +918,14 @@ namespace libmpdataxx ) ); } - + // nondimensionalised tx derivative of psi i.e. // dt/psi * dpsi/dt at (i+1/2, j, k) - infinite gauge version template inline auto ndt_psi( - const arr_3d_t &psi_np1, - const arr_3d_t &psi_n, - const ix_t &i, + const arr_3d_t &psi_np1, + const arr_3d_t &psi_n, + const ix_t &i, const ix_t &j, const ix_t &k, typename std::enable_if::type* = 0 @@ -938,4 +938,4 @@ namespace libmpdataxx } } // namespace mpdata } // namespace formulae -} // namespcae libmpdataxx +} // namespcae libmpdataxx diff --git a/libmpdata++/formulae/nabla_formulae.hpp b/libmpdata++/formulae/nabla_formulae.hpp index 6ff594b1..c5523e5f 100644 --- a/libmpdata++/formulae/nabla_formulae.hpp +++ b/libmpdata++/formulae/nabla_formulae.hpp @@ -21,106 +21,106 @@ namespace libmpdataxx template inline auto grad( - const arg_t &x, - const rng_t &i, - const real_t dx + const arg_t &x, + const rng_t &i, + const real_t dx ) { return blitz::safeToReturn( - ( - x(i+1) - - x(i-1) - ) / dx / 2 + ( + x(i+1) - + x(i-1) + ) / dx / 2 ); } // 2D version template inline auto grad( - const arg_t &x, - const rng_t &i, - const rng_t &j, - const real_t dx + const arg_t &x, + const rng_t &i, + const rng_t &j, + const real_t dx ) { return blitz::safeToReturn( - ( - x(pi(i+1, j)) - - x(pi(i-1, j)) - ) / dx / 2 + ( + x(pi(i+1, j)) - + x(pi(i-1, j)) + ) / dx / 2 ); } - + // 3D version template inline auto grad( - const arg_t &x, - const rng_t &i, - const rng_t &j, - const rng_t &k, - const real_t dx - ) + const arg_t &x, + const rng_t &i, + const rng_t &j, + const rng_t &k, + const real_t dx + ) { return blitz::safeToReturn( - ( - x(pi(i+1, j, k)) - - x(pi(i-1, j, k)) - ) / dx / 2 + ( + x(pi(i+1, j, k)) - + x(pi(i-1, j, k)) + ) / dx / 2 ); } - + template inline auto grad_cmpct( - const arg_t &x, - const rng_t &i, - const real_t dx + const arg_t &x, + const rng_t &i, + const real_t dx ) { return blitz::safeToReturn( - ( - x(i+1) - - x(i) - ) / dx + ( + x(i+1) - + x(i) + ) / dx ); } // 2D version template inline auto grad_cmpct( - const arg_t &x, - const rng_t &i, - const rng_t &j, - const real_t dx - ) + const arg_t &x, + const rng_t &i, + const rng_t &j, + const real_t dx + ) { return blitz::safeToReturn( - ( - x(pi(i+1, j)) - - x(pi(i , j)) - ) / dx + ( + x(pi(i+1, j)) - + x(pi(i , j)) + ) / dx ); } - + // 3D version template inline auto grad_cmpct( - const arg_t &x, - const rng_t &i, - const rng_t &j, - const rng_t &k, - const real_t dx + const arg_t &x, + const rng_t &i, + const rng_t &j, + const rng_t &k, + const real_t dx ) { return blitz::safeToReturn( - ( - x(pi(i+1, j, k)) - - x(pi(i, j, k)) - ) / dx + ( + x(pi(i+1, j, k)) - + x(pi(i, j, k)) + ) / dx ); } - + // helper function to calculate gradient components of a scalar field - + // 1D version template inline void calc_grad(arrvec_t v, arr_t a, ijk_t ijk, dijk_t dijk, typename std::enable_if::type* = 0) @@ -144,7 +144,7 @@ namespace libmpdataxx v[1](ijk) = formulae::nabla::grad<1>(a, ijk[1], ijk[2], ijk[0], dijk[1]); v[2](ijk) = formulae::nabla::grad<2>(a, ijk[2], ijk[0], ijk[1], dijk[2]); } - + // 2D version template inline void calc_grad_cmpct(arrvec_t v, arr_t a, ijk_t ijk, ijkm_t ijkm, dijk_t dijk, typename std::enable_if::type* = 0) @@ -161,40 +161,40 @@ namespace libmpdataxx v[1](ijk[0], ijkm[1] + h, ijk[2]) = formulae::nabla::grad_cmpct<1>(a, ijkm[1], ijk[2], ijk[0], dijk[1]); v[2](ijk[0], ijk[1], ijkm[2] + h) = formulae::nabla::grad_cmpct<2>(a, ijkm[2], ijk[0], ijk[1], dijk[2]); } - + // divergence - + // 2D version template inline auto div( - const arrvec_t &v, // vector field - const ijk_t &ijk, - const dijk_t dijk, + const arrvec_t &v, // vector field + const ijk_t &ijk, + const dijk_t dijk, typename std::enable_if::type* = 0 - ) + ) { return blitz::safeToReturn( - (v[0](ijk[0]+1, ijk[1]) - v[0](ijk[0]-1, ijk[1])) / dijk[0] / 2 - + - (v[1](ijk[0], ijk[1]+1) - v[1](ijk[0], ijk[1]-1)) / dijk[1] / 2 + (v[0](ijk[0]+1, ijk[1]) - v[0](ijk[0]-1, ijk[1])) / dijk[0] / 2 + + + (v[1](ijk[0], ijk[1]+1) - v[1](ijk[0], ijk[1]-1)) / dijk[1] / 2 ); } - + // 3D version template inline auto div( - const arrvec_t &v, // vector field - const ijk_t &ijk, - const dijk_t dijk, + const arrvec_t &v, // vector field + const ijk_t &ijk, + const dijk_t dijk, typename std::enable_if::type* = 0 - ) + ) { return blitz::safeToReturn( - (v[0](ijk[0]+1, ijk[1], ijk[2]) - v[0](ijk[0]-1, ijk[1], ijk[2])) / dijk[0] / 2 - + - (v[1](ijk[0], ijk[1]+1, ijk[2]) - v[1](ijk[0], ijk[1]-1, ijk[2])) / dijk[1] / 2 - + - (v[2](ijk[0], ijk[1], ijk[2]+1) - v[2](ijk[0], ijk[1], ijk[2]-1)) / dijk[2] / 2 + (v[0](ijk[0]+1, ijk[1], ijk[2]) - v[0](ijk[0]-1, ijk[1], ijk[2])) / dijk[0] / 2 + + + (v[1](ijk[0], ijk[1]+1, ijk[2]) - v[1](ijk[0], ijk[1]-1, ijk[2])) / dijk[1] / 2 + + + (v[2](ijk[0], ijk[1], ijk[2]+1) - v[2](ijk[0], ijk[1], ijk[2]-1)) / dijk[2] / 2 ); } } // namespace nabla_op diff --git a/libmpdata++/formulae/stress_formulae.hpp b/libmpdata++/formulae/stress_formulae.hpp index df3e117c..710853e6 100644 --- a/libmpdata++/formulae/stress_formulae.hpp +++ b/libmpdata++/formulae/stress_formulae.hpp @@ -53,12 +53,12 @@ namespace libmpdataxx vg[7](ijk) = formulae::nabla::grad<2>(v[1], ijk[2], ijk[0], ijk[1], dijk[2]); vg[8](ijk) = formulae::nabla::grad<2>(v[2], ijk[2], ijk[0], ijk[1], dijk[2]); } - + // calculates unique deformation tensor components // 2D version template inline void calc_deform(arrvec_t &tau, - const arrvec_t &vg, + const arrvec_t &vg, const ijk_t &ijk, typename std::enable_if::type* = 0) { @@ -66,7 +66,7 @@ namespace libmpdataxx tau[1](ijk) = vg[1](ijk) + vg[2](ijk); tau[2](ijk) = 2 * vg[3](ijk); } - + // 3D version template inline void calc_deform(arrvec_t &tau, @@ -81,7 +81,7 @@ namespace libmpdataxx tau[4](ijk) = vg[5](ijk) + vg[7](ijk); tau[5](ijk) = 2 * vg[8](ijk); } - + // calculate elements of stress tensor divergence // 2D version template @@ -97,7 +97,7 @@ namespace libmpdataxx sdiv[2](ijk) = formulae::nabla::grad<1>(tau[1], ijk[1], ijk[0], dijk[1]); sdiv[3](ijk) = formulae::nabla::grad<1>(tau[2], ijk[1], ijk[0], dijk[1]); } - + // 3D version template inline void calc_stress_div(arrvec_t &sdiv, @@ -118,7 +118,7 @@ namespace libmpdataxx sdiv[7](ijk) = formulae::nabla::grad<2>(tau[4], ijk[2], ijk[0], ijk[1], dijk[2]); sdiv[8](ijk) = formulae::nabla::grad<2>(tau[5], ijk[2], ijk[0], ijk[1], dijk[2]); } - + // add stress forces // 2D version @@ -128,7 +128,7 @@ namespace libmpdataxx rhs[0](ijk) += coeff * (drv[0](ijk) + drv[2](ijk)); rhs[1](ijk) += coeff * (drv[1](ijk) + drv[3](ijk)); } - + // 3D version template inline void calc_stress_rhs(arrvec_t &rhs, const arrvec_t &drv, ijk_t &ijk, real_t coeff, typename std::enable_if::type* = 0) @@ -137,31 +137,31 @@ namespace libmpdataxx rhs[1](ijk) += coeff * (drv[1](ijk) + drv[4](ijk) + drv[7](ijk)); rhs[2](ijk) += coeff * (drv[2](ijk) + drv[5](ijk) + drv[8](ijk)); } - + // Total deformation // 2D version template inline auto calc_tdef_sq( - const arrvec_t &tau, + const arrvec_t &tau, const ijk_t &ijk, typename std::enable_if::type* = 0 - ) - { + ) + { return blitz::safeToReturn( - pow2(tau[0](ijk)) / 2 + pow2(tau[1](ijk)) + pow2(tau[2](ijk)) / 2 + pow2(tau[0](ijk)) / 2 + pow2(tau[1](ijk)) + pow2(tau[2](ijk)) / 2 ); } - + // 3D version template inline auto calc_tdef_sq( - const arrvec_t &tau, + const arrvec_t &tau, const ijk_t &ijk, typename std::enable_if::type* = 0 - ) + ) { return blitz::safeToReturn( - pow2(tau[0](ijk)) / 2 + + pow2(tau[0](ijk)) / 2 + pow2(tau[1](ijk)) + pow2(tau[2](ijk)) + pow2(tau[3](ijk)) / 2 + @@ -169,9 +169,9 @@ namespace libmpdataxx pow2(tau[5](ijk)) / 2 ); } - + // Compact formulation - + // surface stress // 2D version template @@ -184,7 +184,7 @@ namespace libmpdataxx typename std::enable_if::type* = 0) { auto zro = rng_t(0, 0); - tau[0](ijkm[0] + h, zro) = cdrag / 8 * + tau[0](ijkm[0] + h, zro) = cdrag / 8 * abs((v[0](ijkm[0] + 1, zro) + v[0](ijkm[0], zro))) * (v[0](ijkm[0] + 1, zro) + v[0](ijkm[0], zro)) * ( G(rho, ijkm[0] + 1, zro) @@ -219,7 +219,7 @@ namespace libmpdataxx ( G(rho, ijk[0], ijkm[1] + 1, zro) + G(rho, ijk[0], ijkm[1] , zro) ); } - + // velocity divergence // 2D version template @@ -234,7 +234,7 @@ namespace libmpdataxx (rho(ijk[0], ijk[1] + 1) - rho(ijk[0], ijk[1])) / (dijk[1] * (rho(ijk[0], ijk[1] + 1) + rho(ijk[0], ijk[1]))); } - + // 3D version template inline void calc_vip_div_cmpct(arr_t &div, @@ -264,10 +264,10 @@ namespace libmpdataxx = 2 * ( (v[0](ijkm[0] + 1, ijk[1]) - v[0](ijkm[0], ijk[1])) / dijk[0] - - fconst(0.25 / 2) * ( div_v(ijkm[0], ijk[1] + h) + div_v(ijkm[0], ijk[1] - h) + - fconst(0.25 / 2) * ( div_v(ijkm[0], ijk[1] + h) + div_v(ijkm[0], ijk[1] - h) + div_v(ijkm[0] + 1, ijk[1] + h) + div_v(ijkm[0] + 1, ijk[1] - h)) ); - + tau[1](ijk[0], ijkm[1] + h) = 2 * ( @@ -279,11 +279,11 @@ namespace libmpdataxx = fconst(0.5) * ( - ( v[0](ijkm[0], ijkm[1] + 1) - v[0](ijkm[0], ijkm[1]) + ( v[0](ijkm[0], ijkm[1] + 1) - v[0](ijkm[0], ijkm[1]) + v[0](ijkm[0] + 1, ijkm[1] + 1) - v[0](ijkm[0] + 1, ijkm[1]) ) / dijk[1] + - ( v[1](ijkm[0] + 1, ijkm[1]) - v[1](ijkm[0], ijkm[1]) + ( v[1](ijkm[0] + 1, ijkm[1]) - v[1](ijkm[0], ijkm[1]) + v[1](ijkm[0] + 1, ijkm[1] + 1) - v[1](ijkm[0], ijkm[1] + 1) ) / dijk[0] ); @@ -306,7 +306,7 @@ namespace libmpdataxx - fconst(0.25 / 3) * ( div_v(ijkm[0], ijk[1], ijk[2] + h) + div_v(ijkm[0], ijk[1], ijk[2] - h) + div_v(ijkm[0] + 1, ijk[1], ijk[2] + h) + div_v(ijkm[0] + 1, ijk[1], ijk[2] - h)) ); - + tau[1](ijk[0], ijkm[1] + h, ijk[2]) = 2 * ( @@ -314,27 +314,27 @@ namespace libmpdataxx - fconst(0.25 / 3) * ( div_v(ijk[0], ijkm[1], ijk[2] + h) + div_v(ijk[0], ijkm[1], ijk[2] - h) + div_v(ijk[0], ijkm[1] + 1, ijk[2] + h) + div_v(ijk[0], ijkm[1] + 1, ijk[2] - h)) ); - + tau[2](ijk[0], ijk[1], ijkm[2] + h) = 2 * ( (v[2](ijk[0], ijk[1], ijkm[2] + 1) - v[2](ijk[0], ijk[1], ijkm[2])) / dijk[2] - - fconst(1.0 / 3) * div_v(ijk[0], ijk[1], ijkm[2] + h) + - fconst(1.0 / 3) * div_v(ijk[0], ijk[1], ijkm[2] + h) ); tau[3](ijkm[0] + h, ijkm[1] + h, ijk[2]) = fconst(0.5) * ( - ( v[0](ijkm[0], ijkm[1] + 1, ijk[2]) - v[0](ijkm[0], ijkm[1], ijk[2]) + ( v[0](ijkm[0], ijkm[1] + 1, ijk[2]) - v[0](ijkm[0], ijkm[1], ijk[2]) + v[0](ijkm[0] + 1, ijkm[1] + 1, ijk[2]) - v[0](ijkm[0] + 1, ijkm[1], ijk[2]) ) / dijk[1] + - ( v[1](ijkm[0] + 1, ijkm[1], ijk[2]) - v[1](ijkm[0], ijkm[1], ijk[2]) + ( v[1](ijkm[0] + 1, ijkm[1], ijk[2]) - v[1](ijkm[0], ijkm[1], ijk[2]) + v[1](ijkm[0] + 1, ijkm[1] + 1, ijk[2]) - v[1](ijkm[0], ijkm[1] + 1, ijk[2]) ) / dijk[0] ); - + tau[4](ijkm[0] + h, ijk[1], ijkm[2] + h) = fconst(0.5) * @@ -343,11 +343,11 @@ namespace libmpdataxx + v[0](ijkm[0] + 1, ijk[1], ijkm[2] + 1) - v[0](ijkm[0] + 1, ijk[1], ijkm[2]) ) / dijk[2] + - ( v[2](ijkm[0] + 1, ijk[1], ijkm[2]) - v[2](ijkm[0], ijk[1], ijkm[2]) + ( v[2](ijkm[0] + 1, ijk[1], ijkm[2]) - v[2](ijkm[0], ijk[1], ijkm[2]) + v[2](ijkm[0] + 1, ijk[1], ijkm[2] + 1) - v[2](ijkm[0], ijk[1], ijkm[2] + 1) ) / dijk[0] ); - + tau[5](ijk[0], ijkm[1] + h, ijkm[2] + h) = fconst(0.5) * @@ -356,23 +356,23 @@ namespace libmpdataxx + v[1](ijk[0], ijkm[1] + 1, ijkm[2] + 1) - v[1](ijk[0], ijkm[1] + 1, ijkm[2]) ) / dijk[2] + - ( v[2](ijk[0], ijkm[1] + 1, ijkm[2]) - v[2](ijk[0], ijkm[1], ijkm[2]) + ( v[2](ijk[0], ijkm[1] + 1, ijkm[2]) - v[2](ijk[0], ijkm[1], ijkm[2]) + v[2](ijk[0], ijkm[1] + 1, ijkm[2] + 1) - v[2](ijk[0], ijkm[1], ijkm[2] + 1) ) / dijk[1] ); } - + // Total deformation // 2D version template inline auto calc_tdef_sq_cmpct( - const arrvec_t &tau, + const arrvec_t &tau, const ijk_t &ijk, typename std::enable_if::type* = 0 - ) + ) { return blitz::safeToReturn( - // one half taken as an average + // one half taken as an average ( pow2(tau[0](ijk[0] + h, ijk[1])) + pow2(tau[0](ijk[0] - h, ijk[1])) + pow2(tau[1](ijk[0], ijk[1] + h)) + pow2(tau[1](ijk[0], ijk[1] - h)) @@ -393,13 +393,13 @@ namespace libmpdataxx // 3D version template inline auto calc_tdef_sq_cmpct( - const arrvec_t &tau, + const arrvec_t &tau, const ijk_t &ijk, typename std::enable_if::type* = 0 ) { return blitz::safeToReturn( - // one half taken as an average + // one half taken as an average ( pow2(tau[0](ijk[0] + h, ijk[1], ijk[2])) + pow2(tau[0](ijk[0] - h, ijk[1], ijk[2])) + pow2(tau[1](ijk[0], ijk[1] + h, ijk[2])) + pow2(tau[1](ijk[0], ijk[1] - h, ijk[2])) @@ -426,7 +426,7 @@ namespace libmpdataxx ) / 4 ); } - + // multiplication of compact vector components by constant molecular viscosity // 2D version template @@ -461,12 +461,12 @@ namespace libmpdataxx const ijk_t &ijk, typename std::enable_if::type* = 0) { - av[0](ijk[0] + h, ijk[1]) *= coeff * + av[0](ijk[0] + h, ijk[1]) *= coeff * real_t(0.5) * (k_m(ijk[0] + 1, ijk[1]) + k_m(ijk[0], ijk[1])) * real_t(0.5) * (G(rho, ijk[0] + 1, ijk[1]) + G(rho, ijk[0], ijk[1])); - + av[1](ijk[0], ijk[1] + h) *= coeff * - real_t(0.5) * (k_m(ijk[0], ijk[1] + 1) + k_m(ijk[0], ijk[1])) * + real_t(0.5) * (k_m(ijk[0], ijk[1] + 1) + k_m(ijk[0], ijk[1])) * real_t(0.5) * (G(rho, ijk[0], ijk[1] + 1) + G(rho, ijk[0], ijk[1])); } @@ -482,16 +482,16 @@ namespace libmpdataxx av[0](ijk[0] + h, ijk[1], ijk[2]) *= coeff * real_t(0.5) * (k_m(ijk[0] + 1, ijk[1], ijk[2]) + k_m(ijk[0], ijk[1], ijk[2])) * real_t(0.5) * (G(rho, ijk[0] + 1, ijk[1], ijk[2]) + G(rho,ijk[0], ijk[1], ijk[2])); - + av[1](ijk[0], ijk[1] + h, ijk[2]) *= coeff * real_t(0.5) * (k_m(ijk[0], ijk[1] + 1, ijk[2]) + k_m(ijk[0], ijk[1], ijk[2])) * real_t(0.5) * (G(rho, ijk[0], ijk[1] + 1, ijk[2]) + G(rho, ijk[0], ijk[1], ijk[2])); - + av[2](ijk[0], ijk[1], ijk[2] + h) *= coeff * real_t(0.5) * (k_m(ijk[0], ijk[1], ijk[2] + 1) + k_m(ijk[0], ijk[1], ijk[2])) * real_t(0.5) * (G(rho, ijk[0], ijk[1], ijk[2] + 1) + G(rho, ijk[0], ijk[1], ijk[2])); } - + // multiplication of compact tensor components by constant molecular viscosity // 2D version template @@ -527,7 +527,7 @@ namespace libmpdataxx typename std::enable_if::type* = 0) { multiply_vctr_cmpct(av, coeff, k_m, rho, ijk); - av[2](ijk[0] + h, ijk[1] + h) *= coeff * + av[2](ijk[0] + h, ijk[1] + h) *= coeff * real_t(0.25) * ( k_m(ijk[0] + 1, ijk[1] ) + k_m(ijk[0] , ijk[1] ) + k_m(ijk[0] + 1, ijk[1] + 1) @@ -561,7 +561,7 @@ namespace libmpdataxx + G(rho, ijk[0] + 1, ijk[1] + 1, ijk[2]) + G(rho, ijk[0] , ijk[1] + 1, ijk[2]) ); - + av[4](ijk[0] + h, ijk[1], ijk[2] + h) *= coeff * real_t(0.25) * ( k_m(ijk[0] + 1, ijk[1], ijk[2] ) + k_m(ijk[0] , ijk[1], ijk[2] ) @@ -591,41 +591,41 @@ namespace libmpdataxx // 2D version template inline auto flux_div_cmpct( - const arrvec_t &f, - const arr_t &rho, - const ijk_t &ijk, - const dijk_t dijk, + const arrvec_t &f, + const arr_t &rho, + const ijk_t &ijk, + const dijk_t dijk, typename std::enable_if::type* = 0 - ) + ) { return blitz::safeToReturn( - ( (f[0](ijk[0]+h, ijk[1]) - f[0](ijk[0]-h, ijk[1])) / dijk[0] - + - (f[1](ijk[0], ijk[1]+h) - f[1](ijk[0], ijk[1]-h)) / dijk[1] + ( (f[0](ijk[0]+h, ijk[1]) - f[0](ijk[0]-h, ijk[1])) / dijk[0] + + + (f[1](ijk[0], ijk[1]+h) - f[1](ijk[0], ijk[1]-h)) / dijk[1] ) / G(rho, ijk) ); } - + // 3D version template inline auto flux_div_cmpct( - const arrvec_t &f, - const arr_t &rho, - const ijk_t &ijk, - const dijk_t dijk, + const arrvec_t &f, + const arr_t &rho, + const ijk_t &ijk, + const dijk_t dijk, typename std::enable_if::type* = 0 - ) + ) { return blitz::safeToReturn( - ( (f[0](ijk[0]+h, ijk[1], ijk[2]) - f[0](ijk[0]-h, ijk[1], ijk[2])) / dijk[0] - + - (f[1](ijk[0], ijk[1]+h, ijk[2]) - f[1](ijk[0], ijk[1]-h, ijk[2])) / dijk[1] - + - (f[2](ijk[0], ijk[1], ijk[2]+h) - f[2](ijk[0], ijk[1], ijk[2]-h)) / dijk[2] + ( (f[0](ijk[0]+h, ijk[1], ijk[2]) - f[0](ijk[0]-h, ijk[1], ijk[2])) / dijk[0] + + + (f[1](ijk[0], ijk[1]+h, ijk[2]) - f[1](ijk[0], ijk[1]-h, ijk[2])) / dijk[1] + + + (f[2](ijk[0], ijk[1], ijk[2]+h) - f[2](ijk[0], ijk[1], ijk[2]-h)) / dijk[2] ) / G(rho, ijk) ); } - + // add stress forces // 2D version template @@ -642,17 +642,17 @@ namespace libmpdataxx coeff * ( (tau[0](ijk[0] + h, ijk[1]) - tau[0](ijk[0] - h, ijk[1])) / dijk[0] - + real_t(0.5) * + + real_t(0.5) * ( tau[2](ijk[0] + h, ijk[1] + h) - tau[2](ijk[0] + h, ijk[1] - h) + tau[2](ijk[0] - h, ijk[1] + h) - tau[2](ijk[0] - h, ijk[1] - h) ) / dijk[1] ) / G(rho, ijk); - + rhs[1](ijk) += coeff * ( - real_t(0.5) * + real_t(0.5) * ( tau[2](ijk[0] + h, ijk[1] + h) - tau[2](ijk[0] - h, ijk[1] + h) + tau[2](ijk[0] + h, ijk[1] - h) - tau[2](ijk[0] - h, ijk[1] - h) ) / dijk[0] @@ -676,41 +676,41 @@ namespace libmpdataxx coeff * ( (tau[0](ijk[0] + h, ijk[1], ijk[2]) - tau[0](ijk[0] - h, ijk[1], ijk[2])) / dijk[0] - + real_t(0.5) * + + real_t(0.5) * ( tau[3](ijk[0] + h, ijk[1] + h, ijk[2]) - tau[3](ijk[0] + h, ijk[1] - h, ijk[2]) + tau[3](ijk[0] - h, ijk[1] + h, ijk[2]) - tau[3](ijk[0] - h, ijk[1] - h, ijk[2]) ) / dijk[1] - + real_t(0.5) * + + real_t(0.5) * ( tau[4](ijk[0] + h, ijk[1], ijk[2] + h) - tau[4](ijk[0] + h, ijk[1], ijk[2] - h) + tau[4](ijk[0] - h, ijk[1], ijk[2] + h) - tau[4](ijk[0] - h, ijk[1], ijk[2] - h) ) / dijk[2] ) / G(rho, ijk); - + rhs[1](ijk) += coeff * ( - real_t(0.5) * + real_t(0.5) * ( tau[3](ijk[0] + h, ijk[1] + h, ijk[2]) - tau[3](ijk[0] - h, ijk[1] + h, ijk[2]) + tau[3](ijk[0] + h, ijk[1] - h, ijk[2]) - tau[3](ijk[0] - h, ijk[1] - h, ijk[2]) ) / dijk[0] + (tau[1](ijk[0], ijk[1] + h, ijk[2]) - tau[1](ijk[0], ijk[1] - h, ijk[2])) / dijk[1] - + real_t(0.5) * + + real_t(0.5) * ( tau[5](ijk[0], ijk[1] + h, ijk[2] + h) - tau[5](ijk[0], ijk[1] + h, ijk[2] - h) + tau[5](ijk[0], ijk[1] - h, ijk[2] + h) - tau[5](ijk[0], ijk[1] - h, ijk[2] - h) ) / dijk[2] ) / G(rho, ijk); - + rhs[2](ijk) += coeff * ( - real_t(0.5) * + real_t(0.5) * ( tau[4](ijk[0] + h, ijk[1], ijk[2] + h) - tau[4](ijk[0] - h, ijk[1], ijk[2] + h) + tau[4](ijk[0] + h, ijk[1], ijk[2] - h) - tau[4](ijk[0] - h, ijk[1], ijk[2] - h) ) / dijk[0] - + real_t(0.5) * + + real_t(0.5) * ( tau[5](ijk[0], ijk[1] + h, ijk[2] + h) - tau[5](ijk[0], ijk[1] - h, ijk[2] + h) + tau[5](ijk[0], ijk[1] + h, ijk[2] - h) - tau[5](ijk[0], ijk[1] - h, ijk[2] - h) ) / dijk[1] @@ -724,13 +724,13 @@ namespace libmpdataxx // 2D version template inline auto pade_helper( - const arg_t &x, - const rng_t &i, - const rng_t &j - ) + const arg_t &x, + const rng_t &i, + const rng_t &j + ) { return blitz::safeToReturn( - x(idxperm::pi(i + 1, j)) + 2 * x(idxperm::pi(i, j)) + x(idxperm::pi(i - 1, j)) + x(idxperm::pi(i + 1, j)) + 2 * x(idxperm::pi(i, j)) + x(idxperm::pi(i - 1, j)) ); } @@ -756,14 +756,14 @@ namespace libmpdataxx // 3D version template inline auto pade_helper( - const arg_t &x, - const rng_t &i, - const rng_t &j, - const rng_t &k - ) + const arg_t &x, + const rng_t &i, + const rng_t &j, + const rng_t &k + ) { return blitz::safeToReturn( - x(idxperm::pi(i+1, j, k)) + 2 * x(idxperm::pi(i, j, k)) + x(idxperm::pi(i - 1, j, k)) + x(idxperm::pi(i+1, j, k)) + 2 * x(idxperm::pi(i, j, k)) + x(idxperm::pi(i - 1, j, k)) ); } diff --git a/libmpdata++/kahan_reduction.hpp b/libmpdata++/kahan_reduction.hpp index 551cb191..2e89c708 100644 --- a/libmpdata++/kahan_reduction.hpp +++ b/libmpdata++/kahan_reduction.hpp @@ -13,7 +13,7 @@ namespace blitz { template - class ReduceKahanSum + class ReduceKahanSum { public: @@ -23,33 +23,33 @@ namespace blitz static const bool needIndex = false, needInit = false; - ReduceKahanSum() { } + ReduceKahanSum() { } #pragma GCC push_options #pragma GCC optimize ("O3") // assuming -Ofast could optimise out the algorithm - bool operator()(const T_sourcetype& x, const int=0) const - { + bool operator()(const T_sourcetype& x, const int=0) const + { #if defined(__FAST_MATH__) && defined(__llvm__) volatile // without volatile clang optimises the algorithm out with -Ofast #endif - T_resulttype t, y; + T_resulttype t, y; y = x - c_; t = sum_ + y; c_ = (t - sum_) - y; sum_ = t; return true; - } + } #pragma GCC pop_options T_resulttype result(const int) const { return sum_; } - void reset() const - { - sum_ = c_ = zero(T_resulttype()); + void reset() const + { + sum_ = c_ = zero(T_resulttype()); } - + static const char* name() { return "sum"; } - + protected: mutable T_resulttype sum_, c_; diff --git a/libmpdata++/opts.hpp b/libmpdata++/opts.hpp index bd93ea67..35a89ea2 100644 --- a/libmpdata++/opts.hpp +++ b/libmpdata++/opts.hpp @@ -36,7 +36,7 @@ namespace libmpdataxx fct = opts::bit(0), // flux-corrected transport abs = opts::bit(1), // use the abs() trick to handle variable-sign signal tot = opts::bit(2), // third-order accuracy terms - pfc = opts::bit(3), // use conditional statements like frac=where(den!=0,nom/den,0) instead of frac=nom/(den+eps) in psi-fraction factors + pfc = opts::bit(3), // use conditional statements like frac=where(den!=0,nom/den,0) instead of frac=nom/(den+eps) in psi-fraction factors npa = opts::bit(4), // use nprt=(x-abs(x))/2 instead of nprt=min(0,x), and analogous formulae for pprt iga = opts::bit(5), // infinite-gauge option nug = opts::bit(6), // non-unit G (default G = 1) - see Smolarkiewicz 2006 eq (25) and discussion below for info on G diff --git a/libmpdata++/output/detail/output_common.hpp b/libmpdata++/output/detail/output_common.hpp index a100b350..47920259 100644 --- a/libmpdata++/output/detail/output_common.hpp +++ b/libmpdata++/output/detail/output_common.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -15,38 +15,38 @@ namespace libmpdataxx { namespace output { - namespace detail + namespace detail { template class output_common : public solver_t { - using parent_t = solver_t; + using parent_t = solver_t; - protected: + protected: - struct info_t { std::string name, unit; }; - std::map outvars; + struct info_t { std::string name, unit; }; + std::map outvars; int do_record_cnt = 0; - typename parent_t::real_t record_time; - const typename parent_t::advance_arg_t outfreq; - const int outwindow; + typename parent_t::real_t record_time; + const typename parent_t::advance_arg_t outfreq; + const int outwindow; const std::string outdir; arrvec_t &intrp_vars; std::array intrp_times; - virtual void record(const int var) {} - virtual void start(const typename parent_t::advance_arg_t nt) {} - + virtual void record(const int var) {} + virtual void start(const typename parent_t::advance_arg_t nt) {} + typename parent_t::arr_t out_data(const int var) { return this->var_dt ? intrp_vars[var] : this->mem->advectee(var); } - void hook_ante_loop(const typename parent_t::advance_arg_t nt) - { - parent_t::hook_ante_loop(nt); + void hook_ante_loop(const typename parent_t::advance_arg_t nt) + { + parent_t::hook_ante_loop(nt); if (this->var_dt) { @@ -55,24 +55,24 @@ namespace libmpdataxx this->mem->barrier(); } - if (this->rank == 0) + if (this->rank == 0) { record_time = this->time; start(nt); record_all(); } - this->mem->barrier(); - } + this->mem->barrier(); + } - virtual void record_all() - { - for (const auto &v : outvars) record(v.first); - } + virtual void record_all() + { + for (const auto &v : outvars) record(v.first); + } - void hook_ante_step() + void hook_ante_step() { parent_t::hook_ante_step(); - + if (this->var_dt) { static_assert(parent_t::ct_params_t_::out_intrp_ord == 1 || @@ -85,7 +85,7 @@ namespace libmpdataxx int curr_idx = std::floor(this->time / outfreq); do_record_cnt = (do_record_cnt > 0 ? do_record_cnt - 1 : 0); - if (next_idx > curr_idx || do_record_cnt > 0) + if (next_idx > curr_idx || do_record_cnt > 0) { if (do_record_cnt == 0) { @@ -101,11 +101,11 @@ namespace libmpdataxx } } - void hook_post_step() - { - parent_t::hook_post_step(); + void hook_post_step() + { + parent_t::hook_post_step(); - this->mem->barrier(); // waiting for all threads befor doing global output + this->mem->barrier(); // waiting for all threads befor doing global output if (this->var_dt && do_record_cnt == 1) { @@ -133,10 +133,10 @@ namespace libmpdataxx const auto & y0 = intrp_vars[v.first](this->ijk); const auto & y1 = intrp_vars[v.first + parent_t::n_eqns](this->ijk); const auto & y2 = this->mem->advectee(v.first)(this->ijk); - + intrp_vars[v.first](this->ijk) = y0 + (y1 - y0) / (t1 - t0) * (t - t0) + - ( (y2 - y1) / ((t2 - t1) * (t2 - t0)) + ( (y2 - y1) / ((t2 - t1) * (t2 - t0)) - (y1 - y0) / ((t1 - t0) * (t2 - t0)) ) * (t - t0) * (t - t1); break; } @@ -145,8 +145,8 @@ namespace libmpdataxx this->mem->barrier(); } - if (this->rank == 0) - { + if (this->rank == 0) + { //TODO: output of solver statistics every timesteps could probably go here if (this->var_dt && do_record_cnt == 1) @@ -162,40 +162,40 @@ namespace libmpdataxx } } } - - this->mem->barrier(); // waiting for the output to be finished - } - public: + this->mem->barrier(); // waiting for the output to be finished + } + + public: - struct rt_params_t : parent_t::rt_params_t - { - typename parent_t::advance_arg_t outfreq = 1; - int outwindow = 1; - std::map outvars; + struct rt_params_t : parent_t::rt_params_t + { + typename parent_t::advance_arg_t outfreq = 1; + int outwindow = 1; + std::map outvars; std::string outdir; // TODO: pass adiitional info? (command_line, library versions, ...) - }; + }; - // ctor - output_common( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : + // ctor + output_common( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : parent_t(args, p), - outfreq(p.outfreq), - outwindow(p.outwindow), + outfreq(p.outfreq), + outwindow(p.outwindow), outvars(p.outvars), outdir(p.outdir), intrp_vars(args.mem->tmp[__FILE__][0]) - { + { // default value for outvars if (this->outvars.size() == 0 && parent_t::n_eqns == 1) outvars = {{0, {"", ""}}}; - + // assign 1 to dt, di, dj, dk for output purposes if they are not defined by the user - for (auto ref : + for (auto ref : std::vector>{this->dt, this->di, this->dj, this->dk}) { if (ref.get() == 0) diff --git a/libmpdata++/output/detail/xdmf_writer.hpp b/libmpdata++/output/detail/xdmf_writer.hpp index a3a6db29..173ebd4a 100644 --- a/libmpdata++/output/detail/xdmf_writer.hpp +++ b/libmpdata++/output/detail/xdmf_writer.hpp @@ -130,7 +130,7 @@ namespace libmpdataxx attrs.insert(make_attribute(n, dimensions + 1)); } } - + void add_attribute(const std::string& name, const std::string& hdf_name, @@ -171,7 +171,7 @@ namespace libmpdataxx for (auto a : attrs) a.add(grid_node); - + for (auto ca : c_attrs) ca.add(grid_node); diff --git a/libmpdata++/output/gnuplot.hpp b/libmpdata++/output/gnuplot.hpp index 7509bc05..2b02d2ed 100644 --- a/libmpdata++/output/gnuplot.hpp +++ b/libmpdata++/output/gnuplot.hpp @@ -1,9 +1,9 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) - * @brief a thin wrapper around the gnuplot-iostream library intended + * @brief a thin wrapper around the gnuplot-iostream library intended * for debugging/demonstration purposes only (used in many tests) */ @@ -25,7 +25,7 @@ namespace libmpdataxx protected: using output_t = gnuplot; - + private: using parent_t = detail::output_common; @@ -42,68 +42,68 @@ namespace libmpdataxx // fixed instead of scientific to allow automatic comparison of test results for values near zero // some common 1D/2D settings - *gp - << (p.gnuplot_grid ? "" : "un") << "set grid\n" - << "set border " << p.gnuplot_border << "\n" - << "set palette " << p.gnuplot_palette << "\n" - << "set view " << p.gnuplot_view << "\n" - << "set zrange " << p.gnuplot_zrange << "\n" - << "set xlabel '" << p.gnuplot_xlabel << "'\n" - << "set ylabel '" << p.gnuplot_ylabel << "'\n" - << "set term " << p.gnuplot_term << "\n" - << "set size " << p.gnuplot_size << "\n" + *gp + << (p.gnuplot_grid ? "" : "un") << "set grid\n" + << "set border " << p.gnuplot_border << "\n" + << "set palette " << p.gnuplot_palette << "\n" + << "set view " << p.gnuplot_view << "\n" + << "set zrange " << p.gnuplot_zrange << "\n" + << "set xlabel '" << p.gnuplot_xlabel << "'\n" + << "set ylabel '" << p.gnuplot_ylabel << "'\n" + << "set term " << p.gnuplot_term << "\n" + << "set size " << p.gnuplot_size << "\n" << "set cbtics " << p.gnuplot_cbtics << "\n" - << "set termoption font \"," << p.gnuplot_fontsize << "\"\n" + << "set termoption font \"," << p.gnuplot_fontsize << "\"\n" << "set termoption solid\n" ; - if (p.gnuplot_xrange == "[*:*]") - *gp << "set xrange [" - << this->mem->grid_size[0].first() - << ":" + if (p.gnuplot_xrange == "[*:*]") + *gp << "set xrange [" + << this->mem->grid_size[0].first() + << ":" << this->mem->grid_size[0].last() << "]\n"; - else - *gp << "set xrange " << p.gnuplot_xrange << "\n"; + else + *gp << "set xrange " << p.gnuplot_xrange << "\n"; // 1D settings if (parent_t::n_dims == 1) // known at compile time { - if (p.gnuplot_command == "splot") + if (p.gnuplot_command == "splot") { *gp << "set yrange [0:" << nt << "]\n" - << "set xtics out\n" - << "set ytics out\n" - << "set ztics out\n" - << "set ticslevel " << p.gnuplot_ticslevel << "\n"; + << "set xtics out\n" + << "set ytics out\n" + << "set ztics out\n" + << "set ticslevel " << p.gnuplot_ticslevel << "\n"; if (p.gnuplot_xyplane_at != "") *gp << "set xyplane at " << p.gnuplot_xyplane_at << "\n"; if (p.gnuplot_yrange != "[*:*]") throw std::runtime_error("gnupot_yrange was specified for a 1D splot where Y axis represents time"); if (p.gnuplot_ylabel == "") *gp << "set ylabel 't/dt'\n"; } - else if (p.gnuplot_command == "plot") + else if (p.gnuplot_command == "plot") { if (p.gnuplot_with != "histeps") throw std::runtime_error("histeps is the only meaningfull style for 1D plots"); *gp << "set yrange " << p.gnuplot_yrange << "\n"; - } + } else throw std::runtime_error("gnuplot_command must equal plot or splot"); - - *gp - << "set output '" << p.gnuplot_output; - if (this->mem->distmem.size() > 1) + + *gp + << "set output '" << p.gnuplot_output; + if (this->mem->distmem.size() > 1) *gp << "." << this->mem->distmem.rank(); *gp <<"'\n"; - *gp - << "set title '" << p.gnuplot_title << "'\n" + *gp + << "set title '" << p.gnuplot_title << "'\n" << p.gnuplot_command << " 1/0 notitle" // for the comma below :) ; for (int t = 0; t <= nt; t+=p.outfreq) { - for (const auto &v : this->outvars) + for (const auto &v : this->outvars) { - *gp << ", '-'"; - if (p.gnuplot_command == "splot") + *gp << ", '-'"; + if (p.gnuplot_command == "splot") { *gp << " using (((int($0)+1)/2+(int($0)-1)/2)*.5"; if (this->mem->distmem.size() > 1) @@ -111,13 +111,13 @@ namespace libmpdataxx *gp << "):(" << t << "):1"; } *gp << " with " << p.gnuplot_with; // TODO: assert histeps -> emulation - + *gp << " lt "; if (this->outvars.size() == 1) *gp << p.gnuplot_lt; else *gp << v.first + 1; // +1 so that the "0" lt is not used (gives dashed lines) *gp << ( - t == 0 + t == 0 ? std::string(" title '") + v.second.name + "'" : std::string(" notitle") ); @@ -129,22 +129,22 @@ namespace libmpdataxx // 2D settings if (parent_t::n_dims == 2) // known at compile time { - if (p.gnuplot_yrange == "[*:*]") + if (p.gnuplot_yrange == "[*:*]") *gp << "set yrange [0:" << this->mem->advectee(0).extent(1)-1 << "]\n"; - else + else *gp << "set yrange " << p.gnuplot_yrange << "\n"; - *gp - << "set cbrange " << p.gnuplot_cbrange << "\n" - << "set xtics out\n" - << "set ytics out\n" - << (p.gnuplot_surface ? "set" : "unset") << " surface\n" - << (p.gnuplot_contour ? "set" : "unset") << " contour\n" - ; + *gp + << "set cbrange " << p.gnuplot_cbrange << "\n" + << "set xtics out\n" + << "set ytics out\n" + << (p.gnuplot_surface ? "set" : "unset") << " surface\n" + << (p.gnuplot_contour ? "set" : "unset") << " contour\n" + ; if (p.gnuplot_contour) { - *gp + *gp << "unset clabel\n" << "set cntrparam " << p.gnuplot_cntrparam << "\n"; } @@ -155,7 +155,7 @@ namespace libmpdataxx { gp.reset(); } - + // helper constructs to make it compilable for both 1D and 2D versions std::string binfmt(blitz::Array) { throw std::logic_error("binfmt() only for 2D!"); } std::string binfmt(blitz::Array a) { return gp->binfmt(a.transpose(blitz::secondDim, blitz::firstDim)) + " scan=yx "; } @@ -163,15 +163,15 @@ namespace libmpdataxx void record(const int var) { if (parent_t::n_dims == 1) // known at compile time - { - if (p.gnuplot_command == "splot") + { + if (p.gnuplot_command == "splot") { // emulating histeps - decltype(this->mem->advectee(var)) + decltype(this->mem->advectee(var)) tmp(2 * this->mem->grid_size[0].length()); - for (int i = 0; i < tmp.extent(0); ++i) + for (int i = 0; i < tmp.extent(0); ++i) tmp(i) = this->mem->advectee(var)(this->mem->grid_size[0].first() + i/2); - gp->send(tmp); + gp->send(tmp); } else gp->send(this->mem->advectee(var).reindex({0})); } @@ -180,74 +180,74 @@ namespace libmpdataxx { { std::ostringstream tmp; - tmp << "set output '" << boost::format(p.gnuplot_output) % this->outvars[var].name % this->timestep; - if (this->mem->distmem.size() > 1) + tmp << "set output '" << boost::format(p.gnuplot_output) % this->outvars[var].name % this->timestep; + if (this->mem->distmem.size() > 1) tmp << "." << this->mem->distmem.rank(); tmp << "'\n"; - if (p.gnuplot_title == "notitle") + if (p.gnuplot_title == "notitle") tmp << "set title ''\n"; else - tmp << "set title '"<< this->outvars[var].name << " (" // TODO: handle the option + tmp << "set title '"<< this->outvars[var].name << " (" // TODO: handle the option << "t/dt=" << std::setprecision(3) << this->timestep << ")'\n"; *gp << tmp.str(); } - *gp << p.gnuplot_command; + *gp << p.gnuplot_command; { - bool imagebg = (p.gnuplot_with == "lines"); + bool imagebg = (p.gnuplot_with == "lines"); typename parent_t::real_t ox, oy; // ox = oy = .5; // old: x = (i+.5) * dx // ox = oy = 0; // new: x = i * dx ox = this->mem->grid_size[0].first(); - oy = 0; + oy = 0; auto data = this->mem->advectee(var).copy(); data.reindexSelf({0,0}); - if (imagebg) - { - float zmin, zmax; - int count = sscanf(p.gnuplot_zrange.c_str(), "[%g:%g]", &zmin, &zmax); - if (count != 2) zmin = 0; - *gp << " '-' binary " << binfmt(data) - << " origin=(" << ox << "," << oy << "," << zmin << ")" - << " with image failsafe notitle,"; - } - *gp << " '-'" - << " binary" << binfmt(data) - << " origin=(" << ox << "," << oy << ",0)" - << " with " << p.gnuplot_with << " lt " << p.gnuplot_lt << " notitle\n"; + if (imagebg) + { + float zmin, zmax; + int count = sscanf(p.gnuplot_zrange.c_str(), "[%g:%g]", &zmin, &zmax); + if (count != 2) zmin = 0; + *gp << " '-' binary " << binfmt(data) + << " origin=(" << ox << "," << oy << "," << zmin << ")" + << " with image failsafe notitle,"; + } + *gp << " '-'" + << " binary" << binfmt(data) + << " origin=(" << ox << "," << oy << ",0)" + << " with " << p.gnuplot_with << " lt " << p.gnuplot_lt << " notitle\n"; data = blitz::rint(data * pow(10, precision)) * pow(10, -precision); - gp->sendBinary(data); - if (imagebg) gp->sendBinary(data); + gp->sendBinary(data); + if (imagebg) gp->sendBinary(data); } } } public: - struct rt_params_t : parent_t::rt_params_t - { - std::string + struct rt_params_t : parent_t::rt_params_t + { + std::string gnuplot_output = std::string("out.svg"), - gnuplot_with = ( - parent_t::n_dims == 2 - ? std::string("image failsafe") // 2D - : std::string("histeps") + gnuplot_with = ( + parent_t::n_dims == 2 + ? std::string("image failsafe") // 2D + : std::string("histeps") ), gnuplot_command = std::string("splot"), gnuplot_xlabel = std::string("x/dx"), gnuplot_ylabel = ( - parent_t::n_dims == 2 + parent_t::n_dims == 2 ? std::string("y/dy") // 2D : std::string("") // 1D ), gnuplot_size = ( - parent_t::n_dims == 2 + parent_t::n_dims == 2 ? std::string("square") // 2D : std::string("noratio") // 1D ), - gnuplot_fontsize = std::string("15"), - gnuplot_ticslevel = std::string("0"), - gnuplot_view = std::string(""), - gnuplot_title = std::string(""), + gnuplot_fontsize = std::string("15"), + gnuplot_ticslevel = std::string("0"), + gnuplot_view = std::string(""), + gnuplot_title = std::string(""), gnuplot_zrange = std::string("[*:*]"), gnuplot_yrange = std::string("[*:*]"), gnuplot_xrange = std::string("[*:*]"), @@ -259,7 +259,7 @@ namespace libmpdataxx gnuplot_term = std::string("svg dynamic"), gnuplot_palette = std::string(""), gnuplot_cbtics = std::string(""); - bool + bool gnuplot_contour = false, gnuplot_grid = true, gnuplot_surface = true; @@ -270,13 +270,13 @@ namespace libmpdataxx // ctor gnuplot( - typename parent_t::ctor_args_t args, - const rt_params_t &p + typename parent_t::ctor_args_t args, + const rt_params_t &p ) : parent_t(args, p), p(p) { - if (!this->outdir.empty()) + if (!this->outdir.empty()) this->p.gnuplot_output = this->outdir + "/" + p.gnuplot_output; // TODO: get rid of gnuplot_output } - }; + }; } // namespace output } // namespace libmpdataxx diff --git a/libmpdata++/output/hdf5.hpp b/libmpdata++/output/hdf5.hpp index 3018d589..553cedef 100644 --- a/libmpdata++/output/hdf5.hpp +++ b/libmpdata++/output/hdf5.hpp @@ -74,20 +74,20 @@ namespace libmpdataxx boost::filesystem::create_directory(this->outdir); } - + { // creating the const file #if defined(USE_MPI) this->mem->distmem.barrier(); - H5Pset_fapl_mpio(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL); - H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE); + H5Pset_fapl_mpio(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL); + H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE); #endif hdfp.reset(new H5::H5File(const_file, H5F_ACC_TRUNC #if defined(USE_MPI) , H5P_DEFAULT, fapl_id #endif )); - + // save selected compile and runtime parameters, the choice depends on the solver family // record_params(*hdfp, typename parent_t::solver_family{}); } @@ -117,7 +117,7 @@ namespace libmpdataxx shape[0] = this->mem->grid_size[0].length(); cshape[0] = this->mem->grid_size[0].length(); - if (this->mem->distmem.rank() == this->mem->distmem.size() - 1) + if (this->mem->distmem.rank() == this->mem->distmem.size() - 1) cshape[0] += 1; offst[0] = this->mem->grid_size[0].first(); @@ -173,10 +173,10 @@ namespace libmpdataxx dim_space.selectHyperslab(H5S_SELECT_SET, cshape.data(), offst.data()); curr_dim.write(coord.data(), flttype_solver, H5::DataSpace(parent_t::n_dims, cshape.data()), dim_space, dxpl_id); } - + // T { - const hsize_t + const hsize_t nt_out = nt / this->outfreq + 1; // incl. t=0 float dt = this->dt; @@ -189,14 +189,14 @@ namespace libmpdataxx dim_space.selectHyperslab(H5S_SELECT_SET, &nt_out, &zero); curr_dim.write(coord.data(), flttype_solver, H5::DataSpace(1, &nt_out), dim_space, dxpl_id); } - + // G factor if (this->mem->G.get() != nullptr) { auto g_set = (*hdfp).createDataSet("G", flttype_output, sspace); record_dsc_helper(g_set, *this->mem->G); } - + // save selected compile and runtime parameters, the choice depends on the solver family record_params(*hdfp, typename parent_t::solver_family{}); } @@ -209,7 +209,7 @@ namespace libmpdataxx ss << "timestep" << std::setw(10) << std::setfill('0') << this->timestep; return ss.str(); } - + std::string hdf_name() { // TODO: add option of .nc extension for Paraview sake ? @@ -266,7 +266,7 @@ namespace libmpdataxx } case 2: { - typename solver_t::arr_t contiguous_arr(this->mem->grid_size[0], zro); + typename solver_t::arr_t contiguous_arr(this->mem->grid_size[0], zro); contiguous_arr = arr(this->mem->grid_size[0], zro); // create a copy that is contiguous dset.write(contiguous_arr.data(), flttype_solver, H5::DataSpace(parent_t::n_dims, srfcshape.data()), space, dxpl_id); break; @@ -281,7 +281,7 @@ namespace libmpdataxx default: assert(false); }; } - + void record_dsc_helper(const H5::DataSet &dset, const typename solver_t::arr_t &arr) { H5::DataSpace space = dset.getSpace(); @@ -333,7 +333,7 @@ namespace libmpdataxx { record_aux_hlpr(name, data, *hdfp); } - + // for discontiguous array with halos void record_aux_dsc_hlpr(const std::string &name, const typename solver_t::arr_t &arr, H5::H5File hdf, bool srfc = false) { @@ -341,14 +341,14 @@ namespace libmpdataxx if(srfc) params.setChunk(parent_t::n_dims, srfcchunk.data()); - + auto aux = hdf.createDataSet( name, flttype_output, srfc ? srfcspace : sspace, params ); - + if(srfc) { // revert to default chunk @@ -421,12 +421,12 @@ namespace libmpdataxx { record_aux_scalar(name, "/", data); } - + // see above, also assumes that z is the last dimension void record_prof_const(const std::string &name, typename solver_t::real_t *data) { assert(this->rank == 0); - + H5::H5File hdfcp(const_file, H5F_ACC_RDWR #if defined(USE_MPI) , H5P_DEFAULT, fapl_id @@ -485,7 +485,7 @@ namespace libmpdataxx group.createAttribute("n_iters", type, H5::DataSpace(1, &one)).write(type, &data); } } - + // as above but for solvers with rhs void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_rhs_family_tag) { @@ -497,24 +497,24 @@ namespace libmpdataxx const auto type = H5::StrType(H5::PredType::C_S1, scheme_str.size()); group.createAttribute("rhs_scheme", type, H5::DataSpace(1, &one)).write(type, scheme_str.data()); } - + // as above but for solvers with velocities void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_rhs_vip_family_tag) { record_params(hdfcp, typename solvers::mpdata_rhs_family_tag{}); - + hdfcp.createGroup("vip"); const auto &group = hdfcp.openGroup("vip"); const auto vab_str = solvers::vab2string.at(static_cast(parent_t::ct_params_t_::vip_vab)); const auto type = H5::StrType(H5::PredType::C_S1, vab_str.size()); group.createAttribute("vip_abs", type, H5::DataSpace(1, &one)).write(type, vab_str.data()); } - + // as above but for solvers with pressure equation void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_rhs_vip_prs_family_tag) { record_params(hdfcp, typename solvers::mpdata_rhs_vip_family_tag{}); - + hdfcp.createGroup("prs"); const auto &group = hdfcp.openGroup("prs"); { @@ -527,12 +527,12 @@ namespace libmpdataxx group.createAttribute("prs_tol", type, H5::DataSpace(1, &one)).write(type, &this->prs_tol); } } - + // as above but for solvers with subgrid model (parameters common to all subgrid models) void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_rhs_vip_prs_sgs_family_tag) { record_params(hdfcp, typename solvers::mpdata_rhs_vip_prs_family_tag{}); - + hdfcp.createGroup("sgs"); const auto &group = hdfcp.openGroup("sgs"); { @@ -550,24 +550,24 @@ namespace libmpdataxx group.createAttribute("cdrag", type, H5::DataSpace(1, &one)).write(type, &this->cdrag); } } - + // as above but for solvers with the dns subgrid model void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_rhs_vip_prs_sgs_dns_family_tag) { record_params(hdfcp, typename solvers::mpdata_rhs_vip_prs_sgs_family_tag{}); - + const auto &group = hdfcp.openGroup("sgs"); { const auto type = flttype_solver; group.createAttribute("eta", type, H5::DataSpace(1, &one)).write(type, &this->eta); } } - + // as above but for solvers with the smg subgrid model void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_rhs_vip_prs_sgs_smg_family_tag) { record_params(hdfcp, typename solvers::mpdata_rhs_vip_prs_sgs_family_tag{}); - + const auto &group = hdfcp.openGroup("sgs"); { const auto type = flttype_solver; @@ -575,7 +575,7 @@ namespace libmpdataxx group.createAttribute("c_m", type, H5::DataSpace(1, &one)).write(type, &this->c_m); } } - + // as above but for the boussinesq solver void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_boussinesq_family_tag) { @@ -601,7 +601,7 @@ namespace libmpdataxx void record_params(const H5::H5File &hdfcp, typename solvers::mpdata_boussinesq_sgs_family_tag) { record_params(hdfcp, typename solvers::mpdata_boussinesq_family_tag{}); - + const auto &group = hdfcp.openGroup("boussinesq"); { const auto type = flttype_solver; diff --git a/libmpdata++/output/hdf5_xdmf.hpp b/libmpdata++/output/hdf5_xdmf.hpp index 791d646b..91425fce 100644 --- a/libmpdata++/output/hdf5_xdmf.hpp +++ b/libmpdata++/output/hdf5_xdmf.hpp @@ -29,12 +29,12 @@ namespace libmpdataxx class hdf5_xdmf : public hdf5 { protected: - + using output_t = hdf5_xdmf; using parent_t = hdf5; - + static_assert(parent_t::n_dims > 1, "only 2D and 3D output supported"); - + std::vector timesteps; //xdmf writer detail::xdmf_writer xdmfw; @@ -53,7 +53,7 @@ namespace libmpdataxx { attr_names.push_back(v.second.name); } - + if (this->mem->G.get() != nullptr) xdmfw.add_const_attribute("G", this->const_name, this->mem->distmem.grid_size.data()); xdmfw.setup(this->const_name, this->dim_names, attr_names, this->mem->distmem.grid_size.data()); @@ -88,10 +88,10 @@ namespace libmpdataxx #if defined(USE_MPI) if (this->mem->distmem.rank() == 0) #endif - xdmfw.add_attribute(name, this->hdf_name(), this->mem->distmem.grid_size.data()); + xdmfw.add_attribute(name, this->hdf_name(), this->mem->distmem.grid_size.data()); parent_t::record_aux(name, data); } - + void record_aux_dsc(const std::string &name, const typename solver_t::arr_t &arr, bool srfc = false) { auto shape = this->mem->distmem.grid_size; @@ -99,7 +99,7 @@ namespace libmpdataxx #if defined(USE_MPI) if (this->mem->distmem.rank() == 0) #endif - xdmfw.add_attribute(name, this->hdf_name(), shape.data()); + xdmfw.add_attribute(name, this->hdf_name(), shape.data()); parent_t::record_aux_dsc(name, arr, srfc); } @@ -107,8 +107,8 @@ namespace libmpdataxx // ctor hdf5_xdmf( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p ) : parent_t(args, p) {} }; diff --git a/libmpdata++/solvers/boussinesq.hpp b/libmpdata++/solvers/boussinesq.hpp index 01fc3da8..ee7919c9 100644 --- a/libmpdata++/solvers/boussinesq.hpp +++ b/libmpdata++/solvers/boussinesq.hpp @@ -35,7 +35,7 @@ namespace libmpdataxx mpdata_boussinesq_family_tag, mpdata_boussinesq_sgs_family_tag>::type; }; - + template class boussinesq< ct_params_t, @@ -44,7 +44,7 @@ namespace libmpdataxx { using parent_t = detail::boussinesq_impl; using parent_t::parent_t; // inheriting constructors - + protected: using solver_family = typename std::conditional(ct_params_t::sgs_scheme) == iles, mpdata_boussinesq_family_tag, diff --git a/libmpdata++/solvers/detail/boussinesq_common.hpp b/libmpdata++/solvers/detail/boussinesq_common.hpp index 6424e222..c7c1a6c0 100644 --- a/libmpdata++/solvers/detail/boussinesq_common.hpp +++ b/libmpdata++/solvers/detail/boussinesq_common.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -29,14 +29,14 @@ namespace libmpdataxx virtual void calc_full_tht(typename parent_t::arr_t&) = 0; public: - struct rt_params_t : parent_t::rt_params_t - { + struct rt_params_t : parent_t::rt_params_t + { real_t g = 9.81, Tht_ref = 0, hflux_const = 0; }; // ctor - boussinesq_common( - typename parent_t::ctor_args_t args, + boussinesq_common( + typename parent_t::ctor_args_t args, const rt_params_t &p ) : parent_t(args, p), diff --git a/libmpdata++/solvers/detail/boussinesq_expl.hpp b/libmpdata++/solvers/detail/boussinesq_expl.hpp index 48b68966..ab7caede 100644 --- a/libmpdata++/solvers/detail/boussinesq_expl.hpp +++ b/libmpdata++/solvers/detail/boussinesq_expl.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -30,8 +30,8 @@ namespace libmpdataxx using ix = typename ct_params_t::ix; bool buoy_filter; typename parent_t::arr_t &tmp1, &tmp2; - - template + + template void filter(typename std::enable_if::type* = 0) { const auto &i(this->i), &j(this->j); @@ -39,14 +39,14 @@ namespace libmpdataxx tmp2(i, j) = real_t(0.25) * (tmp1(i, j + 1) + 2 * tmp1(i, j) + tmp1(i, j - 1)); } - template + template void filter(typename std::enable_if::type* = 0) { const auto &i(this->i), &j(this->j), &k(this->k); this->xchng_sclr(tmp1, this->ijk); tmp2(i, j, k) = real_t(0.25) * (tmp1(i, j, k + 1) + 2 * tmp1(i, j, k) + tmp1(i, j, k - 1)); } - + // helpers for buoyancy forces template inline auto buoy_at_0(const ijk_t &ijk) @@ -55,7 +55,7 @@ namespace libmpdataxx this->g * (this->state(ix::tht)(ijk) - this->tht_e(ijk)) / this->Tht_ref ); } - + template inline auto buoy_at_1(const ijk_t &ijk) { @@ -74,17 +74,17 @@ namespace libmpdataxx full_tht(this->ijk) = this->state(ix::tht)(this->ijk); } - // explicit forcings + // explicit forcings void update_rhs( libmpdataxx::arrvec_t< typename parent_t::arr_t - > &rhs, - const real_t &dt, - const int &at + > &rhs, + const real_t &dt, + const int &at ) { - parent_t::update_rhs(rhs, dt, at); + parent_t::update_rhs(rhs, dt, at); - const auto &tht = this->state(ix::tht); + const auto &tht = this->state(ix::tht); const auto &ijk = this->ijk; auto ix_w = this->vip_ixs[ct_params_t::n_dims - 1]; @@ -94,7 +94,7 @@ namespace libmpdataxx case (0): { rhs.at(ix::tht)(ijk) += this->hflux_frc(ijk) - this->tht_abs(ijk) * (tht(ijk) - this->tht_e(ijk)); - + if (!buoy_filter) { rhs.at(ix_w)(ijk) += buoy_at_0(ijk); @@ -128,16 +128,16 @@ namespace libmpdataxx } } } - + public: - struct rt_params_t : parent_t::rt_params_t - { - bool buoy_filter = false; + struct rt_params_t : parent_t::rt_params_t + { + bool buoy_filter = false; }; // ctor - boussinesq_expl( - typename parent_t::ctor_args_t args, + boussinesq_expl( + typename parent_t::ctor_args_t args, const rt_params_t &p ) : parent_t(args, p), diff --git a/libmpdata++/solvers/detail/boussinesq_impl.hpp b/libmpdata++/solvers/detail/boussinesq_impl.hpp index be1ccb5b..e2617be8 100644 --- a/libmpdata++/solvers/detail/boussinesq_impl.hpp +++ b/libmpdata++/solvers/detail/boussinesq_impl.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -29,14 +29,14 @@ namespace libmpdataxx // member fields using ix = typename ct_params_t::ix; typename parent_t::arr_t &dtht_e; - + template void calc_dtht_e(typename std::enable_if::type* = 0) { this->xchng_sclr(this->tht_e, this->ijk); this->dtht_e(this->ijk) = formulae::nabla::grad<1>(this->tht_e, this->j, this->i, this->dj); } - + template void calc_dtht_e(typename std::enable_if::type* = 0) { @@ -49,11 +49,11 @@ namespace libmpdataxx full_tht(this->ijk) = this->state(ix::tht)(this->ijk) + this->tht_e(this->ijk); } - void hook_ante_loop(const typename parent_t::advance_arg_t nt) - { + void hook_ante_loop(const typename parent_t::advance_arg_t nt) + { calc_dtht_e(); - parent_t::hook_ante_loop(nt); - } + parent_t::hook_ante_loop(nt); + } virtual void normalize_vip(const arrvec_t &v) { @@ -75,19 +75,19 @@ namespace libmpdataxx / (1 + real_t(0.5) * this->dt * this->tht_abs(this->ijk))); } } - + void update_rhs( libmpdataxx::arrvec_t< typename parent_t::arr_t - > &rhs, - const real_t &dt, - const int &at + > &rhs, + const real_t &dt, + const int &at ) { parent_t::update_rhs(rhs, dt, at); auto ix_w = this->vip_ixs[ct_params_t::n_dims - 1]; - const auto &tht = this->state(ix::tht); + const auto &tht = this->state(ix::tht); const auto &w = this->state(ix_w); const auto &ijk = this->ijk; @@ -110,23 +110,23 @@ namespace libmpdataxx } } } - + void vip_rhs_impl_fnlz() { parent_t::vip_rhs_impl_fnlz(); - + const auto &w = this->vips()[ct_params_t::n_dims - 1]; - this->state(ix::tht)(this->ijk) = ( this->state(ix::tht)(this->ijk) + this->state(ix::tht)(this->ijk) = ( this->state(ix::tht)(this->ijk) - real_t(0.5) * this->dt * w(this->ijk) * this->dtht_e(this->ijk)) / (1 + real_t(0.5) * this->dt * this->tht_abs(this->ijk)); this->rhs.at(ix::tht)(this->ijk) += -w(this->ijk) * this->dtht_e(this->ijk) -this->tht_abs(this->ijk) * this->state(ix::tht)(this->ijk); } - + public: // ctor - boussinesq_impl( - typename parent_t::ctor_args_t args, + boussinesq_impl( + typename parent_t::ctor_args_t args, const typename parent_t::rt_params_t &p ) : parent_t(args, p), diff --git a/libmpdata++/solvers/detail/boussinesq_sgs_common.hpp b/libmpdata++/solvers/detail/boussinesq_sgs_common.hpp index 74a40b6d..51c7317b 100644 --- a/libmpdata++/solvers/detail/boussinesq_sgs_common.hpp +++ b/libmpdata++/solvers/detail/boussinesq_sgs_common.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -27,7 +27,7 @@ namespace libmpdataxx typename parent_t::arr_t &rcdsn_num, &full_tht, &tdef_sq, &mix_len, &hflux_srfc; arrvec_t &grad_tht; - template + template void calc_rcdsn_num(typename std::enable_if::type* = 0) { rcdsn_num(this->ijk) = this->g * real_t(0.5) * ( @@ -36,7 +36,7 @@ namespace libmpdataxx ) / (this->Tht_ref * tdef_sq(this->ijk)); } - template + template void calc_rcdsn_num(typename std::enable_if::type* = 0) { rcdsn_num(this->ijk) = this->g * real_t(0.5) * ( @@ -69,7 +69,7 @@ namespace libmpdataxx this->xchng_pres(full_tht, this->ijk); formulae::nabla::calc_grad_cmpct(grad_tht, this->full_tht, this->ijk, this->ijkm, this->dijk); - + tdef_sq(this->ijk) = formulae::stress::calc_tdef_sq_cmpct(this->tau, this->ijk); calc_rcdsn_num(); @@ -86,7 +86,7 @@ namespace libmpdataxx ijp1.ubound(ct_params_t::n_dims - 1) = 1; this->k_m(ij) = this->k_m(ijp1); - + this->xchng_sclr(this->k_m, this->ijk, 1); // havo to use modified ijkm due to shared-memory parallelisation, otherwise overlapping ranges @@ -120,14 +120,14 @@ namespace libmpdataxx } public: - struct rt_params_t : parent_t::rt_params_t - { + struct rt_params_t : parent_t::rt_params_t + { real_t prandtl_num = 0; }; // ctor - boussinesq_sgs_common( - typename parent_t::ctor_args_t args, + boussinesq_sgs_common( + typename parent_t::ctor_args_t args, const rt_params_t &p ) : parent_t(args, p), diff --git a/libmpdata++/solvers/detail/monitor.hpp b/libmpdata++/solvers/detail/monitor.hpp index c14e08b7..0f33a705 100644 --- a/libmpdata++/solvers/detail/monitor.hpp +++ b/libmpdata++/solvers/detail/monitor.hpp @@ -18,23 +18,23 @@ namespace libmpdataxx { inline void monitor(float frac) { - char name[17]; + char name[17]; #if defined(__linux__) name[16] = '\0'; - prctl(PR_GET_NAME, name, 0, 0, 0); + prctl(PR_GET_NAME, name, 0, 0, 0); #elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(HAVE_PTHREAD_GETNAME_NP) pthread_getname_np(pthread_self(), name, 16); #endif - static int len = strlen(name); - // ... 1 0 0 % \0 - // ... 10 11 12 13 14 15 - sprintf( - &name[std::min(len, 10)], // taking care of short thread-names - " %3d%%", - int(frac * 100) - ); + static int len = strlen(name); + // ... 1 0 0 % \0 + // ... 10 11 12 13 14 15 + sprintf( + &name[std::min(len, 10)], // taking care of short thread-names + " %3d%%", + int(frac * 100) + ); #if defined(__linux__) - prctl(PR_SET_NAME, name, 0, 0, 0); + prctl(PR_SET_NAME, name, 0, 0, 0); #elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(HAVE_PTHREAD_GETNAME_NP) pthread_setname_np(name); #endif diff --git a/libmpdata++/solvers/detail/mpdata_common.hpp b/libmpdata++/solvers/detail/mpdata_common.hpp index e7706fc5..e744fb41 100644 --- a/libmpdata++/solvers/detail/mpdata_common.hpp +++ b/libmpdata++/solvers/detail/mpdata_common.hpp @@ -14,77 +14,77 @@ namespace libmpdataxx { template class mpdata_common : public detail::solver< - ct_params_t, - formulae::mpdata::n_tlev, + ct_params_t, + formulae::mpdata::n_tlev, detail::max(minhalo, formulae::mpdata::halo(ct_params_t::opts)) > { using parent_t = detail::solver< - ct_params_t, - formulae::mpdata::n_tlev, + ct_params_t, + formulae::mpdata::n_tlev, detail::max(minhalo, formulae::mpdata::halo(ct_params_t::opts)) >; - using GC_t = arrvec_t; - - protected: + using GC_t = arrvec_t; + + protected: // static constants - const int n_iters, upwind_filter_freq; + const int n_iters, upwind_filter_freq; - // member fields - std::vector tmp; + // member fields + std::vector tmp; GC_t &flux, *flux_ptr; // methods - GC_t &GC_unco(int iter) - { - return (iter == 1) - ? this->mem->GC - : (iter % 2) - ? *tmp[1] // odd iters - : *tmp[0]; // even iters - } + GC_t &GC_unco(int iter) + { + return (iter == 1) + ? this->mem->GC + : (iter % 2) + ? *tmp[1] // odd iters + : *tmp[0]; // even iters + } GC_t &GC_corr(int iter) - { - return (iter % 2) - ? *tmp[0] // odd iters - : *tmp[1]; // even iters - } + { + return (iter % 2) + ? *tmp[0] // odd iters + : *tmp[1]; // even iters + } virtual GC_t &GC(int iter) - { - if (iter == 0) return this->mem->GC; - return GC_corr(iter); - } + { + if (iter == 0) return this->mem->GC; + return GC_corr(iter); + } - // for Flux-Corrected Transport - virtual void fct_init(int e) { } - virtual void fct_adjust_antidiff(int e, int iter) { } + // for Flux-Corrected Transport + virtual void fct_init(int e) { } + virtual void fct_adjust_antidiff(int e, int iter) { } - // + // static int n_tmp(const int &n_iters) { - return n_iters > 2 ? 2 : 1; + return n_iters > 2 ? 2 : 1; } public: - struct rt_params_t : parent_t::rt_params_t + struct rt_params_t : parent_t::rt_params_t { - int n_iters = 2; - int upwind_filter_freq = 0; + int n_iters = 2; + int upwind_filter_freq = 0; }; protected: - // ctor - mpdata_common( - typename parent_t::ctor_args_t args, + // ctor + mpdata_common( + typename parent_t::ctor_args_t args, const rt_params_t &p - ) : - parent_t(args, p), + ) : + parent_t(args, p), n_iters(p.n_iters), upwind_filter_freq(p.upwind_filter_freq), tmp(n_tmp(n_iters)), @@ -92,26 +92,26 @@ namespace libmpdataxx { assert(n_iters > 0); // TODO: throw! - for (int n = 0; n < n_tmp(n_iters); ++n) - tmp[n] = &args.mem->tmp[__FILE__][n]; + for (int n = 0; n < n_tmp(n_iters); ++n) + tmp[n] = &args.mem->tmp[__FILE__][n]; } public: // memory allocation - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters - ) { - parent_t::alloc(mem, n_iters); - for (int n = 0; n < n_tmp(n_iters); ++n) - parent_t::alloc_tmp_vctr(mem, __FILE__); + ) { + parent_t::alloc(mem, n_iters); + for (int n = 0; n < n_tmp(n_iters); ++n) + parent_t::alloc_tmp_vctr(mem, __FILE__); parent_t::alloc_tmp_vctr(mem, __FILE__); // fluxes - } + } }; // partial specialisations - template + template class mpdata_osc {}; } // namespace detail diff --git a/libmpdata++/solvers/detail/mpdata_fct_1d.hpp b/libmpdata++/solvers/detail/mpdata_fct_1d.hpp index 8a1ae938..38714bb7 100644 --- a/libmpdata++/solvers/detail/mpdata_fct_1d.hpp +++ b/libmpdata++/solvers/detail/mpdata_fct_1d.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -18,39 +18,39 @@ namespace libmpdataxx { namespace detail { - template + template class mpdata_fct< - ct_params_t, - minhalo, - typename std::enable_if::type - > : public detail::mpdata_fct_common + ct_params_t, + minhalo, + typename std::enable_if::type + > : public detail::mpdata_fct_common { - using parent_t = detail::mpdata_fct_common; - using parent_t::parent_t; // inheriting constructors + using parent_t = detail::mpdata_fct_common; + using parent_t::parent_t; // inheriting constructors - void fct_init(int e) - { - const auto i1 = this->i^1; // TODO: isn't it a race condition with more than one thread? - const auto psi = this->mem->psi[e][this->n[e]]; + void fct_init(int e) + { + const auto i1 = this->i^1; // TODO: isn't it a race condition with more than one thread? + const auto psi = this->mem->psi[e][this->n[e]]; - /// \f$ \psi^{max}_{i}=max_{I}(\psi^{n}_{i-1},\psi^{n}_{i},\psi^{n}_{i+1},\psi^{*}_{i-1},\psi^{*}_{i},\psi^{*}_{i+1}) \f$ \n - /// \f$ \psi^{min}_{i}=min_{I}(\psi^{n}_{i-1},\psi^{n}_{i},\psi^{n}_{i+1},\psi^{*}_{i-1},\psi^{*}_{i},\psi^{*}_{i+1}) \f$ \n - /// eq.(20a, 20b) in Smolarkiewicz & Grabowski 1990 (J.Comp.Phys.,86,355-375) - this->psi_min(i1) = min(min(psi(i1-1), psi(i1)), psi(i1+1)); - this->psi_max(i1) = max(max(psi(i1-1), psi(i1)), psi(i1+1)); - } + /// \f$ \psi^{max}_{i}=max_{I}(\psi^{n}_{i-1},\psi^{n}_{i},\psi^{n}_{i+1},\psi^{*}_{i-1},\psi^{*}_{i},\psi^{*}_{i+1}) \f$ \n + /// \f$ \psi^{min}_{i}=min_{I}(\psi^{n}_{i-1},\psi^{n}_{i},\psi^{n}_{i+1},\psi^{*}_{i-1},\psi^{*}_{i},\psi^{*}_{i+1}) \f$ \n + /// eq.(20a, 20b) in Smolarkiewicz & Grabowski 1990 (J.Comp.Phys.,86,355-375) + this->psi_min(i1) = min(min(psi(i1-1), psi(i1)), psi(i1+1)); + this->psi_max(i1) = max(max(psi(i1-1), psi(i1)), psi(i1+1)); + } - void fct_adjust_antidiff(int e, int iter) - { - const int d = 0; // 1D version -> working in x dimension only - const auto psi = this->mem->psi[e][this->n[e]]; - auto &GC_corr = parent_t::GC_corr(iter); - const auto &G = *this->mem->G; - const auto &im = this->im; // calculating once for i-1/2 and i+1/2 - const auto i1 = this->i^1; - const auto im1 = this->im^1; + void fct_adjust_antidiff(int e, int iter) + { + const int d = 0; // 1D version -> working in x dimension only + const auto psi = this->mem->psi[e][this->n[e]]; + auto &GC_corr = parent_t::GC_corr(iter); + const auto &G = *this->mem->G; + const auto &im = this->im; // calculating once for i-1/2 and i+1/2 + const auto i1 = this->i^1; + const auto im1 = this->im^1; - // fill halos in GC_corr + // fill halos in GC_corr this->xchng_vctr_alng(GC_corr, true); // calculation of fluxes for betas denominators @@ -72,13 +72,13 @@ namespace libmpdataxx // calculating betas formulae::mpdata::beta_up(this->beta_up, psi, this->psi_max, flx, G, i1); formulae::mpdata::beta_dn(this->beta_dn, psi, this->psi_min, flx, G, i1); - + // assuring flx, psi_min and psi_max are not overwritten this->beta_barrier(iter); - // calculating the monotonic corrective velocity - formulae::mpdata::GC_mono(this->GC_mono[d], psi, this->beta_up, this->beta_dn, GC_corr[d], G, im); - } + // calculating the monotonic corrective velocity + formulae::mpdata::GC_mono(this->GC_mono[d], psi, this->beta_up, this->beta_dn, GC_corr[d], G, im); + } }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/mpdata_fct_2d.hpp b/libmpdata++/solvers/detail/mpdata_fct_2d.hpp index 9b255191..fb4b61ac 100644 --- a/libmpdata++/solvers/detail/mpdata_fct_2d.hpp +++ b/libmpdata++/solvers/detail/mpdata_fct_2d.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -18,43 +18,43 @@ namespace libmpdataxx { namespace detail { - template + template class mpdata_fct< - ct_params_t, - minhalo, - typename std::enable_if::type - > : public detail::mpdata_fct_common + ct_params_t, + minhalo, + typename std::enable_if::type + > : public detail::mpdata_fct_common { - using parent_t = detail::mpdata_fct_common; - using parent_t::parent_t; // inheriting ctors + using parent_t = detail::mpdata_fct_common; + using parent_t::parent_t; // inheriting ctors - void fct_init(int e) - { - const auto i1 = this->i^1, j1 = this->j^1; // not optimal - with multiple threads some indices are repeated among threads - const auto psi = this->mem->psi[e][this->n[e]]; + void fct_init(int e) + { + const auto i1 = this->i^1, j1 = this->j^1; // not optimal - with multiple threads some indices are repeated among threads + const auto psi = this->mem->psi[e][this->n[e]]; - this->psi_min(i1,j1) = min(min(min(min( - psi(i1,j1+1), - psi(i1-1,j1)), psi(i1,j1 )), psi(i1+1,j1)), - psi(i1,j1-1) - ); - this->psi_max(i1,j1) = max(max(max(max( - psi(i1,j1+1), - psi(i1-1,j1)), psi(i1,j1 )), psi(i1+1,j1)), - psi(i1,j1-1) - ); - } + this->psi_min(i1,j1) = min(min(min(min( + psi(i1,j1+1), + psi(i1-1,j1)), psi(i1,j1 )), psi(i1+1,j1)), + psi(i1,j1-1) + ); + this->psi_max(i1,j1) = max(max(max(max( + psi(i1,j1+1), + psi(i1-1,j1)), psi(i1,j1 )), psi(i1+1,j1)), + psi(i1,j1-1) + ); + } - void fct_adjust_antidiff(int e, int iter) - { - const auto psi = this->mem->psi[e][this->n[e]]; - auto &GC_corr = parent_t::GC_corr(iter); + void fct_adjust_antidiff(int e, int iter) + { + const auto psi = this->mem->psi[e][this->n[e]]; + auto &GC_corr = parent_t::GC_corr(iter); const auto &G = *this->mem->G; - const auto i1 = this->i^1, j1 = this->j^1; - const auto im1 = this->im^1, jm1 = this->jm^1; - const auto &im(this->im), &jm(this->jm); // calculating once for (i/j)-1/2 and (i/j)+1/2 + const auto i1 = this->i^1, j1 = this->j^1; + const auto im1 = this->im^1, jm1 = this->jm^1; + const auto &im(this->im), &jm(this->jm); // calculating once for (i/j)-1/2 and (i/j)+1/2 - // fill halos of GC_corr -> mpdata works with halo=1, we need halo=2 + // fill halos of GC_corr -> mpdata works with halo=1, we need halo=2 this->xchng_vctr_alng(GC_corr, true); this->xchng_vctr_nrml(this->GC_corr(iter), this->ijk); @@ -77,18 +77,18 @@ namespace libmpdataxx formulae::mpdata::beta_dn(this->beta_dn, psi, this->psi_min, flx, G, i1, j1); // should detect the need for ext=1 halo-filling above (TODO: double check) - assert(std::isfinite(sum(this->beta_up(i1, this->j)))); - assert(std::isfinite(sum(this->beta_up(this->i, j1)))); - assert(std::isfinite(sum(this->beta_dn(i1, this->j)))); - assert(std::isfinite(sum(this->beta_dn(this->i, j1)))); + assert(std::isfinite(sum(this->beta_up(i1, this->j)))); + assert(std::isfinite(sum(this->beta_up(this->i, j1)))); + assert(std::isfinite(sum(this->beta_dn(i1, this->j)))); + assert(std::isfinite(sum(this->beta_dn(this->i, j1)))); // assuring flx, psi_min and psi_max are not overwritten this->beta_barrier(iter); - // calculating the monotonic corrective velocity - formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, im, this->j); - formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, jm, this->i); - } + // calculating the monotonic corrective velocity + formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, im, this->j); + formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, jm, this->i); + } }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/mpdata_fct_3d.hpp b/libmpdata++/solvers/detail/mpdata_fct_3d.hpp index 3f67d80f..180e9270 100644 --- a/libmpdata++/solvers/detail/mpdata_fct_3d.hpp +++ b/libmpdata++/solvers/detail/mpdata_fct_3d.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -18,59 +18,59 @@ namespace libmpdataxx { namespace detail { - template + template class mpdata_fct< - ct_params_t, - minhalo, - typename std::enable_if::type - > : public detail::mpdata_fct_common + ct_params_t, + minhalo, + typename std::enable_if::type + > : public detail::mpdata_fct_common { - using parent_t = detail::mpdata_fct_common; - using parent_t::parent_t; // inheriting ctors - - void fct_init(int e) - { - const auto i1 = this->i^1, j1 = this->j^1, k1 = this->k^1; // not optimal - with multiple threads some indices are repeated among threads - const auto psi = this->mem->psi[e][this->n[e]]; - - this->psi_min(i1,j1,k1) = min(min(min(min(min(min( - psi(i1, j1, k1), - psi(i1+1,j1, k1)), - psi(i1-1,j1, k1)), - psi(i1, j1+1,k1)), - psi(i1, j1-1,k1)), - psi(i1, j1, k1+1)), - psi(i1, j1, k1-1) - ); - - this->psi_max(i1,j1,k1) = max(max(max(max(max(max( - psi(i1, j1, k1), - psi(i1+1,j1, k1)), - psi(i1-1,j1, k1)), - psi(i1, j1+1,k1)), - psi(i1, j1-1,k1)), - psi(i1, j1, k1+1)), - psi(i1, j1, k1-1) - ); - } - - void fct_adjust_antidiff(int e, int iter) - { - const auto psi = this->mem->psi[e][this->n[e]]; - auto &GC_corr = parent_t::GC_corr(iter); + using parent_t = detail::mpdata_fct_common; + using parent_t::parent_t; // inheriting ctors + + void fct_init(int e) + { + const auto i1 = this->i^1, j1 = this->j^1, k1 = this->k^1; // not optimal - with multiple threads some indices are repeated among threads + const auto psi = this->mem->psi[e][this->n[e]]; + + this->psi_min(i1,j1,k1) = min(min(min(min(min(min( + psi(i1, j1, k1), + psi(i1+1,j1, k1)), + psi(i1-1,j1, k1)), + psi(i1, j1+1,k1)), + psi(i1, j1-1,k1)), + psi(i1, j1, k1+1)), + psi(i1, j1, k1-1) + ); + + this->psi_max(i1,j1,k1) = max(max(max(max(max(max( + psi(i1, j1, k1), + psi(i1+1,j1, k1)), + psi(i1-1,j1, k1)), + psi(i1, j1+1,k1)), + psi(i1, j1-1,k1)), + psi(i1, j1, k1+1)), + psi(i1, j1, k1-1) + ); + } + + void fct_adjust_antidiff(int e, int iter) + { + const auto psi = this->mem->psi[e][this->n[e]]; + auto &GC_corr = parent_t::GC_corr(iter); const auto &G = *this->mem->G; - const auto &im(this->im), &jm(this->jm), &km(this->km); // calculating once for (i/j/k)-1/2 and (i/j/k)+1/2 + const auto &im(this->im), &jm(this->jm), &km(this->km); // calculating once for (i/j/k)-1/2 and (i/j/k)+1/2 // not optimal - with multiple threads some indices are repeated among threads - const auto + const auto i = this->i, j = this->j, k = this->k, i1 = i^1, j1 = j^1, k1 = k^1, - im1 = this->im^1, jm1 = this->jm^1, km1 = this->km^1; + im1 = this->im^1, jm1 = this->jm^1, km1 = this->km^1; - // fill halos -> mpdata works with halo=1, we need halo=2 + // fill halos -> mpdata works with halo=1, we need halo=2 this->xchng_vctr_alng(GC_corr, true); this->xchng_vctr_nrml(this->GC_corr(iter), this->ijk); - + // calculation of fluxes for betas denominators if (opts::isset(ct_params_t::opts, opts::iga)) { @@ -90,23 +90,23 @@ namespace libmpdataxx // calculating betas formulae::mpdata::beta_up(this->beta_up, psi, this->psi_max, flx, G, i1, j1, k1); formulae::mpdata::beta_dn(this->beta_dn, psi, this->psi_min, flx, G, i1, j1, k1); - + // should detect the need for ext=1 in hallo-filling above - assert(std::isfinite(sum(this->beta_up(i1, j, k)))); - assert(std::isfinite(sum(this->beta_up(i, j1, k)))); - assert(std::isfinite(sum(this->beta_up(i, j, k1)))); - assert(std::isfinite(sum(this->beta_dn(i1, j, k)))); - assert(std::isfinite(sum(this->beta_dn(i, j1, k)))); - assert(std::isfinite(sum(this->beta_dn(i, j, k1)))); + assert(std::isfinite(sum(this->beta_up(i1, j, k)))); + assert(std::isfinite(sum(this->beta_up(i, j1, k)))); + assert(std::isfinite(sum(this->beta_up(i, j, k1)))); + assert(std::isfinite(sum(this->beta_dn(i1, j, k)))); + assert(std::isfinite(sum(this->beta_dn(i, j1, k)))); + assert(std::isfinite(sum(this->beta_dn(i, j, k1)))); // assuring flx, psi_min and psi_max are not overwritten this->beta_barrier(iter); - // calculating the monotonic corrective velocity - formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, im, this->j, this->k); - formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, jm, this->k, this->i); - formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, km, this->i, this->j); + // calculating the monotonic corrective velocity + formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, im, this->j, this->k); + formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, jm, this->k, this->i); + formulae::mpdata::GC_mono(this->GC_mono, psi, this->beta_up, this->beta_dn, GC_corr, G, km, this->i, this->j); } }; diff --git a/libmpdata++/solvers/detail/mpdata_fct_common.hpp b/libmpdata++/solvers/detail/mpdata_fct_common.hpp index 880aa4c8..6622e205 100644 --- a/libmpdata++/solvers/detail/mpdata_fct_common.hpp +++ b/libmpdata++/solvers/detail/mpdata_fct_common.hpp @@ -26,51 +26,51 @@ namespace libmpdataxx protected: // member fields - typename parent_t::arr_t psi_min, psi_max, beta_up, beta_dn; - arrvec_t GC_mono; + typename parent_t::arr_t psi_min, psi_max, beta_up, beta_dn; + arrvec_t GC_mono; - arrvec_t &GC(int iter) - { - if (iter > 0) return GC_mono; - return parent_t::GC(iter); - } + arrvec_t &GC(int iter) + { + if (iter > 0) return GC_mono; + return parent_t::GC(iter); + } void beta_barrier(const int &iter) { - if (!opts::isset(ct_params_t::opts, opts::iga)) // this->flux would be overwritten by donor-cell - this->mem->barrier(); + if (!opts::isset(ct_params_t::opts, opts::iga)) // this->flux would be overwritten by donor-cell + this->mem->barrier(); } public: // ctor - mpdata_fct_common( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p - ) : + mpdata_fct_common( + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p + ) : parent_t(args, p), - psi_min(args.mem->tmp[__FILE__][0][0]), - psi_max(args.mem->tmp[__FILE__][0][1]), - GC_mono(args.mem->tmp[__FILE__][1]), - beta_up(args.mem->tmp[__FILE__][2][0]), - beta_dn(args.mem->tmp[__FILE__][2][1]) + psi_min(args.mem->tmp[__FILE__][0][0]), + psi_max(args.mem->tmp[__FILE__][0][1]), + GC_mono(args.mem->tmp[__FILE__][1]), + beta_up(args.mem->tmp[__FILE__][2][0]), + beta_dn(args.mem->tmp[__FILE__][2][1]) {} - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters ) { - parent_t::alloc(mem, n_iters); - parent_t::alloc_tmp_sclr(mem, __FILE__, 2); // psi_min and psi_max - parent_t::alloc_tmp_vctr(mem, __FILE__); // GC_mono - parent_t::alloc_tmp_sclr(mem, __FILE__, 2); // beta_up, beta_dn - } + parent_t::alloc(mem, n_iters); + parent_t::alloc_tmp_sclr(mem, __FILE__, 2); // psi_min and psi_max + parent_t::alloc_tmp_vctr(mem, __FILE__); // GC_mono + parent_t::alloc_tmp_sclr(mem, __FILE__, 2); // beta_up, beta_dn + } }; // partial specialisations - template + template class mpdata_fct - {}; + {}; } // namespace detail } // namespace solvers } // namescpae libmpdataxx diff --git a/libmpdata++/solvers/detail/mpdata_osc_1d.hpp b/libmpdata++/solvers/detail/mpdata_osc_1d.hpp index 11c458e9..ff74c3e4 100644 --- a/libmpdata++/solvers/detail/mpdata_osc_1d.hpp +++ b/libmpdata++/solvers/detail/mpdata_osc_1d.hpp @@ -23,55 +23,55 @@ namespace libmpdataxx template class mpdata_osc< - ct_params_t, - minhalo, - typename std::enable_if::type + ct_params_t, + minhalo, + typename std::enable_if::type > : public detail::mpdata_common { - using parent_t = detail::mpdata_common; + using parent_t = detail::mpdata_common; - protected: + protected: - const rng_t im; + const rng_t im; - void hook_ante_loop(const typename parent_t::advance_arg_t nt) - { + void hook_ante_loop(const typename parent_t::advance_arg_t nt) + { // note that it's not needed for upstream - parent_t::hook_ante_loop(nt); - if (opts::isset(ct_params_t::opts, opts::nug)) - this->xchng_sclr(*this->mem->G); + parent_t::hook_ante_loop(nt); + if (opts::isset(ct_params_t::opts, opts::nug)) + this->xchng_sclr(*this->mem->G); // set time derivatives of GC to zero // needed for stationary flows prescribed using the advector method if (opts::isset(ct_params_t::opts, opts::div_3rd_dt) || opts::isset(ct_params_t::opts, opts::div_3rd)) { this->mem->ndt_GC[0](this->im + h) = 0; - + this->mem->ndtt_GC[0](this->im + h) = 0; this->xchng_vctr_alng(this->mem->ndt_GC); this->xchng_vctr_alng(this->mem->ndtt_GC); } - } - - // method invoked by the solver - void advop(int e) - { - this->fct_init(e); // e.g. store psi_min, psi_max in FCT - - for (int iter = 0; iter < this->n_iters; ++iter) - { - if (iter != 0) - { - this->cycle(e); // cycles subdomain's "n", and global "n" if it's the last equation + } + + // method invoked by the solver + void advop(int e) + { + this->fct_init(e); // e.g. store psi_min, psi_max in FCT + + for (int iter = 0; iter < this->n_iters; ++iter) + { + if (iter != 0) + { + this->cycle(e); // cycles subdomain's "n", and global "n" if it's the last equation this->xchng(e); - // calculating the antidiffusive C + // calculating the antidiffusive C formulae::mpdata::antidiff(ct_params_t::sptl_intrp), static_cast(ct_params_t::tmprl_extrp)>( this->GC_corr(iter)[0], - this->mem->psi[e][this->n[e]], + this->mem->psi[e][this->n[e]], this->GC_unco(iter), this->mem->ndt_GC, this->mem->ndtt_GC, @@ -88,30 +88,30 @@ namespace libmpdataxx this->xchng_vctr_alng(this->GC_corr(iter)); } - this->fct_adjust_antidiff(e, iter); // i.e. calculate GC_mono=GC_mono(GC_corr) in FCT - } + this->fct_adjust_antidiff(e, iter); // i.e. calculate GC_mono=GC_mono(GC_corr) in FCT + } - // calculation of fluxes - if (!opts::isset(ct_params_t::opts, opts::iga) || iter == 0) - { + // calculation of fluxes + if (!opts::isset(ct_params_t::opts, opts::iga) || iter == 0) + { this->flux[0](im+h) = formulae::donorcell::make_flux( this->mem->psi[e][this->n[e]], - this->GC(iter)[0], + this->GC(iter)[0], im ); this->flux_ptr = &this->flux; // TODO: if !iga this is needed only once per simulation, TODO: move to common - } - else - { - assert(iter == 1); // infinite gauge option uses just one corrective step // TODO: not true? + } + else + { + assert(iter == 1); // infinite gauge option uses just one corrective step // TODO: not true? this->flux_ptr = &this->GC(iter); // TODO: move to common - } + } // sanity checks for input // TODO: move to common - //assert(std::isfinite(sum(psi[this->n[e]](this->ijk)))); + //assert(std::isfinite(sum(psi[this->n[e]](this->ijk)))); //assert(std::isfinite(sum(flux_ref[0](i^h)))); - // donor-cell call // TODO: could be made common for 1D/2D/3D + // donor-cell call // TODO: could be made common for 1D/2D/3D formulae::donorcell::donorcell_sum( this->mem->khn_tmp, this->ijk, @@ -127,9 +127,9 @@ namespace libmpdataxx break; } // sanity checks for output // TODO: move to common - //assert(std::isfinite(sum(psi[this->n[e]+1](this->ijk)))); - } - } + //assert(std::isfinite(sum(psi[this->n[e]+1](this->ijk)))); + } + } // performs advection of a given field using the donorcell scheme // and stores the result in the same field @@ -139,17 +139,17 @@ namespace libmpdataxx const auto &i(this->i); auto &GC(this->mem->GC); using namespace formulae::donorcell; - + this->xchng_sclr(field, this->ijk); - + // calculation of fluxes this->flux[0](im+h) = make_flux(field, GC[0], im); - + // sanity check for input assert(std::isfinite(sum(field(i)))); assert(std::isfinite(sum(this->flux[0](i^h)))); - - // donor-cell call + + // donor-cell call donorcell_sum( this->mem->khn_tmp, i, @@ -165,16 +165,16 @@ namespace libmpdataxx } - public: + public: - // ctor - mpdata_osc( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p - ) : - parent_t(args, p), - im(args.i.first() - 1, args.i.last()) - {} + // ctor + mpdata_osc( + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p + ) : + parent_t(args, p), + im(args.i.first() - 1, args.i.last()) + {} }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/mpdata_osc_2d.hpp b/libmpdata++/solvers/detail/mpdata_osc_2d.hpp index b98763a0..f86e9927 100644 --- a/libmpdata++/solvers/detail/mpdata_osc_2d.hpp +++ b/libmpdata++/solvers/detail/mpdata_osc_2d.hpp @@ -25,25 +25,25 @@ namespace libmpdataxx template class mpdata_osc< - ct_params_t, - minhalo, - typename std::enable_if::type + ct_params_t, + minhalo, + typename std::enable_if::type > : public detail::mpdata_common { - using parent_t = detail::mpdata_common; + using parent_t = detail::mpdata_common; - protected: + protected: - // member fields - const rng_t im, jm; + // member fields + const rng_t im, jm; - void hook_ante_loop(const typename parent_t::advance_arg_t nt) - { + void hook_ante_loop(const typename parent_t::advance_arg_t nt) + { // note that it's not needed for upstream - parent_t::hook_ante_loop(nt); - if (opts::isset(ct_params_t::opts, opts::nug)) + parent_t::hook_ante_loop(nt); + if (opts::isset(ct_params_t::opts, opts::nug)) this->xchng_sclr(*this->mem->G, this->ijk, this->halo); - + // filling Y halos for GC_x, and X halos for GC_y auto ex = this->halo - 1; this->xchng_vctr_nrml(this->mem->GC, this->ijk, ex); @@ -54,7 +54,7 @@ namespace libmpdataxx { this->mem->ndt_GC[0](this->im + h, this->j) = 0; this->mem->ndt_GC[1](this->i, this->jm + h) = 0; - + this->mem->ndtt_GC[0](this->im + h, this->j) = 0; this->mem->ndtt_GC[1](this->i, this->jm + h) = 0; @@ -64,32 +64,32 @@ namespace libmpdataxx this->xchng_vctr_nrml(this->mem->ndt_GC, this->ijk, ex); this->xchng_vctr_nrml(this->mem->ndtt_GC, this->ijk, ex); } - } - - // method invoked by the solver - void advop(int e) - { - this->fct_init(e); - - for (int iter = 0; iter < this->n_iters; ++iter) - { - if (iter != 0) - { - this->cycle(e); + } + + // method invoked by the solver + void advop(int e) + { + this->fct_init(e); + + for (int iter = 0; iter < this->n_iters; ++iter) + { + if (iter != 0) + { + this->cycle(e); this->xchng(e); - // calculating the antidiffusive C + // calculating the antidiffusive C formulae::mpdata::antidiff(ct_params_t::sptl_intrp), static_cast(ct_params_t::tmprl_extrp)>( this->GC_corr(iter)[0], - this->mem->psi[e][this->n[e]], + this->mem->psi[e][this->n[e]], this->mem->psi[e][this->n[e]-1], this->GC_unco(iter), this->mem->ndt_GC, this->mem->ndtt_GC, *this->mem->G, - this->im, + this->im, this->j ); assert(std::isfinite(sum(this->GC_corr(iter)[0](this->im+h, this->j)))); @@ -98,13 +98,13 @@ namespace libmpdataxx static_cast(ct_params_t::sptl_intrp), static_cast(ct_params_t::tmprl_extrp)>( this->GC_corr(iter)[1], - this->mem->psi[e][this->n[e]], + this->mem->psi[e][this->n[e]], this->mem->psi[e][this->n[e]-1], this->GC_unco(iter), this->mem->ndt_GC, this->mem->ndtt_GC, *this->mem->G, - this->jm, + this->jm, this->i ); assert(std::isfinite(sum(this->GC_corr(iter)[1](this->i, this->jm+h)))); @@ -112,8 +112,8 @@ namespace libmpdataxx if (opts::isset(ct_params_t::opts, opts::div_3rd_dt)) this->mem->barrier(); - // filling Y halos for GC_x, and X halos for GC_y - // needed for calculation of antidiffusive velocities in the third and subsequent + // filling Y halos for GC_x, and X halos for GC_y + // needed for calculation of antidiffusive velocities in the third and subsequent // iterations, also needed for fct but it is done there independently hence // the following check if (!opts::isset(ct_params_t::opts, opts::fct) && iter != (this->n_iters - 1)) @@ -123,33 +123,33 @@ namespace libmpdataxx if (opts::isset(ct_params_t::opts, opts::dfl)) this->xchng_vctr_alng(this->GC_corr(iter)); } - this->fct_adjust_antidiff(e, iter); + this->fct_adjust_antidiff(e, iter); assert(std::isfinite(sum(this->GC_corr(iter)[0](this->im+h, this->j)))); assert(std::isfinite(sum(this->GC_corr(iter)[1](this->i, this->jm+h)))); - // TODO: shouldn't the above halo-filling be repeated here? - } + // TODO: shouldn't the above halo-filling be repeated here? + } // calculation of fluxes if (!opts::isset(ct_params_t::opts, opts::iga) || iter == 0) { this->flux[0](im+h, this->j) = formulae::donorcell::make_flux( - this->mem->psi[e][this->n[e]], - this->GC(iter)[0], + this->mem->psi[e][this->n[e]], + this->GC(iter)[0], im, this->j ); this->flux[1](this->i, jm+h) = formulae::donorcell::make_flux( - this->mem->psi[e][this->n[e]], - this->GC(iter)[1], + this->mem->psi[e][this->n[e]], + this->GC(iter)[1], jm, this->i ); this->flux_ptr = &this->flux; // TODO: if !iga this is needed only once per simulation, TODO: move to common } else - { + { assert(iter == 1); // infinite gauge option uses just one corrective step // TODO: not true? this->flux_ptr = &this->GC(iter); - } + } auto &flx = (*(this->flux_ptr)); this->xchng_flux(flx); @@ -159,19 +159,19 @@ namespace libmpdataxx //assert(std::isfinite(sum(flx[0](i^h, j )))); //assert(std::isfinite(sum(flx[1](i, j^h)))); - // donor-cell call - // TODO: doing antidiff,upstream,antidiff,upstream (for each dimension separately) could help optimise memory consumption! - formulae::donorcell::donorcell_sum( - this->mem->khn_tmp, + // donor-cell call + // TODO: doing antidiff,upstream,antidiff,upstream (for each dimension separately) could help optimise memory consumption! + formulae::donorcell::donorcell_sum( + this->mem->khn_tmp, this->ijk, - this->mem->psi[e][this->n[e]+1](this->ijk), - this->mem->psi[e][this->n[e] ](this->ijk), + this->mem->psi[e][this->n[e]+1](this->ijk), + this->mem->psi[e][this->n[e] ](this->ijk), flx[0](this->i+h, this->j ), flx[0](this->i-h, this->j ), flx[1](this->i, this->j+h), flx[1](this->i, this->j-h), formulae::G(*this->mem->G, this->i, this->j) - ); + ); if (this->upwind_filter_freq > 0 && this->timestep % this->upwind_filter_freq == 0) { @@ -179,8 +179,8 @@ namespace libmpdataxx } // sanity check for output // TODO: move to common //assert(std::isfinite(sum(this->mem->psi[e][this->n[e]+1](this->ijk)))); - } - } + } + } // performs advection of a given field using the donorcell scheme // and stores the result in the same field @@ -191,21 +191,21 @@ namespace libmpdataxx const auto &ijk(this->ijk); auto &GC(this->mem->GC); using namespace formulae::donorcell; - + this->xchng_sclr(field, this->ijk); - + // calculation of fluxes this->flux[0](im+h, j) = make_flux(field, GC[0], im, j); this->flux[1](i, jm+h) = make_flux(field, GC[1], jm, i); - + this->xchng_flux(this->flux); - + // sanity check for input assert(std::isfinite(sum(field(ijk)))); assert(std::isfinite(sum(this->flux[0](i^h, j )))); assert(std::isfinite(sum(this->flux[1](i, j^h)))); - - // donor-cell call + + // donor-cell call donorcell_sum( this->mem->khn_tmp, ijk, @@ -222,17 +222,17 @@ namespace libmpdataxx assert(std::isfinite(sum(field(ijk)))); } - public: - - // ctor - mpdata_osc( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p - ) : - parent_t(args, p), - im(args.i.first() - 1, args.i.last()), - jm(args.j.first() - 1, args.j.last()) - { } + public: + + // ctor + mpdata_osc( + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p + ) : + parent_t(args, p), + im(args.i.first() - 1, args.i.last()), + jm(args.j.first() - 1, args.j.last()) + { } }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/mpdata_osc_3d.hpp b/libmpdata++/solvers/detail/mpdata_osc_3d.hpp index 9be0fdaa..8c7901e8 100644 --- a/libmpdata++/solvers/detail/mpdata_osc_3d.hpp +++ b/libmpdata++/solvers/detail/mpdata_osc_3d.hpp @@ -25,30 +25,30 @@ namespace libmpdataxx template class mpdata_osc< - ct_params_t, - minhalo, - typename std::enable_if::type + ct_params_t, + minhalo, + typename std::enable_if::type > : public detail::mpdata_common { - using parent_t = detail::mpdata_common; + using parent_t = detail::mpdata_common; - protected: + protected: - // member fields - const rng_t im, jm, km; - - void hook_ante_loop(const typename parent_t::advance_arg_t nt) - { + // member fields + const rng_t im, jm, km; + + void hook_ante_loop(const typename parent_t::advance_arg_t nt) + { // note that it's not needed for upstream - parent_t::hook_ante_loop(nt); - if (opts::isset(ct_params_t::opts, opts::nug)) + parent_t::hook_ante_loop(nt); + if (opts::isset(ct_params_t::opts, opts::nug)) this->xchng_sclr(*this->mem->G, this->ijk, this->halo); - + // filling Y and Z halos for GC_x, X and Z halos for GC_y, X and Y // halos for GC_z auto ex = this->halo - 1; this->xchng_vctr_nrml(this->mem->GC, this->ijk, ex); - + // set time derivatives of GC to zero // needed for stationary flows prescribed using the advector method if (opts::isset(ct_params_t::opts, opts::div_3rd_dt) || opts::isset(ct_params_t::opts, opts::div_3rd)) @@ -56,7 +56,7 @@ namespace libmpdataxx this->mem->ndt_GC[0](this->im + h, this->j, this->k) = 0; this->mem->ndt_GC[1](this->i, this->jm + h, this->k) = 0; this->mem->ndt_GC[2](this->i, this->j, this->km + h) = 0; - + this->mem->ndtt_GC[0](this->im + h, this->j, this->k) = 0; this->mem->ndtt_GC[1](this->i, this->jm + h, this->k) = 0; this->mem->ndtt_GC[2](this->i, this->j, this->km + h) = 0; @@ -67,26 +67,26 @@ namespace libmpdataxx this->xchng_vctr_nrml(this->mem->ndt_GC, this->ijk, ex); this->xchng_vctr_nrml(this->mem->ndtt_GC, this->ijk, ex); } - } - - // method invoked by the solver - void advop(int e) - { - this->fct_init(e); - - for (int iter = 0; iter < this->n_iters; ++iter) - { - if (iter != 0) - { - this->cycle(e); + } + + // method invoked by the solver + void advop(int e) + { + this->fct_init(e); + + for (int iter = 0; iter < this->n_iters; ++iter) + { + if (iter != 0) + { + this->cycle(e); this->xchng(e); - // calculating the antidiffusive C + // calculating the antidiffusive C formulae::mpdata::antidiff(ct_params_t::sptl_intrp), static_cast(ct_params_t::tmprl_extrp)>( this->GC_corr(iter)[0], - this->mem->psi[e][this->n[e]], + this->mem->psi[e][this->n[e]], this->mem->psi[e][this->n[e]-1], this->GC_unco(iter), this->mem->ndt_GC, @@ -101,8 +101,8 @@ namespace libmpdataxx static_cast(ct_params_t::sptl_intrp), static_cast(ct_params_t::tmprl_extrp)>( this->GC_corr(iter)[1], - this->mem->psi[e][this->n[e]], - this->mem->psi[e][this->n[e]-1], + this->mem->psi[e][this->n[e]], + this->mem->psi[e][this->n[e]-1], this->GC_unco(iter), this->mem->ndt_GC, this->mem->ndtt_GC, @@ -111,13 +111,13 @@ namespace libmpdataxx this->k, this->i ); - + formulae::mpdata::antidiff(ct_params_t::sptl_intrp), static_cast(ct_params_t::tmprl_extrp)>( this->GC_corr(iter)[2], - this->mem->psi[e][this->n[e]], - this->mem->psi[e][this->n[e]-1], + this->mem->psi[e][this->n[e]], + this->mem->psi[e][this->n[e]-1], this->GC_unco(iter), this->mem->ndt_GC, this->mem->ndtt_GC, @@ -126,12 +126,12 @@ namespace libmpdataxx this->i, this->j ); - + if (opts::isset(ct_params_t::opts, opts::div_3rd_dt)) this->mem->barrier(); - - // filling Y and Z halos for GC_x, X and Z halos for GC_y, X and Y halos for GC_z - // needed for calculation of antidiffusive velocities in the third and subsequent + + // filling Y and Z halos for GC_x, X and Z halos for GC_y, X and Y halos for GC_z + // needed for calculation of antidiffusive velocities in the third and subsequent // iterations, also needed for fct but it is done there independently hence // the following check if (!opts::isset(ct_params_t::opts, opts::fct) && iter != (this->n_iters - 1)) @@ -141,10 +141,10 @@ namespace libmpdataxx if (opts::isset(ct_params_t::opts, opts::dfl)) this->xchng_vctr_alng(this->GC_corr(iter)); } - this->fct_adjust_antidiff(e, iter); + this->fct_adjust_antidiff(e, iter); - // TODO: shouldn't the above halo-filling be repeated here? - } + // TODO: shouldn't the above halo-filling be repeated here? + } const auto &i(this->i), &j(this->j), &k(this->k); const auto &ijk(this->ijk); @@ -166,7 +166,7 @@ namespace libmpdataxx assert(iter == 1); // infinite gauge option uses just one corrective step // TODO: not true? this->flux_ptr = &GC; } - + auto &flx = (*(this->flux_ptr)); this->xchng_flux(flx); @@ -176,13 +176,13 @@ namespace libmpdataxx assert(std::isfinite(sum(flx[1](i, j^h, k )))); assert(std::isfinite(sum(flx[2](i, j, k^h)))); - // donor-cell call - // TODO: doing antidiff,upstream,antidiff,upstream (for each dimension separately) could help optimise memory consumption! - donorcell_sum( - this->mem->khn_tmp, + // donor-cell call + // TODO: doing antidiff,upstream,antidiff,upstream (for each dimension separately) could help optimise memory consumption! + donorcell_sum( + this->mem->khn_tmp, ijk, - psi[n+1](ijk), - psi[n ](ijk), + psi[n+1](ijk), + psi[n ](ijk), flx[0](i+h, j, k ), flx[0](i-h, j, k ), flx[1](i, j+h, k ), @@ -190,16 +190,16 @@ namespace libmpdataxx flx[2](i, j, k+h), flx[2](i, j, k-h), formulae::G(*this->mem->G, i, j, k) - ); - + ); + if (this->upwind_filter_freq > 0 && this->timestep % this->upwind_filter_freq == 0) { break; } // sanity check for output assert(std::isfinite(sum(psi[n+1](ijk)))); - } - } + } + } // performs advection of a given field using the donorcell scheme // and stores the result in the same field @@ -210,23 +210,23 @@ namespace libmpdataxx const auto &ijk(this->ijk); auto &GC(this->mem->GC); using namespace formulae::donorcell; - + this->xchng_sclr(field, this->ijk); - + // calculation of fluxes this->flux[0](im+h, j, k) = make_flux(field, GC[0], im, j, k); this->flux[1](i, jm+h, k) = make_flux(field, GC[1], jm, k, i); this->flux[2](i, j, km+h) = make_flux(field, GC[2], km, i, j); - + this->xchng_flux(this->flux); - + // sanity check for input assert(std::isfinite(sum(field(ijk)))); assert(std::isfinite(sum(this->flux[0](i^h, j, k )))); assert(std::isfinite(sum(this->flux[1](i, j^h, k )))); assert(std::isfinite(sum(this->flux[2](i, j, k^h)))); - - // donor-cell call + + // donor-cell call donorcell_sum( this->mem->khn_tmp, ijk, @@ -245,18 +245,18 @@ namespace libmpdataxx assert(std::isfinite(sum(field(ijk)))); } - public: - - // ctor - mpdata_osc( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p - ) : - parent_t(args, p), - im(args.i.first() - 1, args.i.last()), - jm(args.j.first() - 1, args.j.last()), - km(args.k.first() - 1, args.k.last()) - { } + public: + + // ctor + mpdata_osc( + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p + ) : + parent_t(args, p), + im(args.i.first() - 1, args.i.last()), + jm(args.j.first() - 1, args.j.last()), + km(args.k.first() - 1, args.k.last()) + { } }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_common.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_common.hpp index b0898474..5f382f33 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_common.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_common.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -31,7 +31,7 @@ namespace libmpdataxx namespace detail { // override default extrapolation/interpolation in ct_params - template + template struct ct_params_vip_default_t : ct_params_t { // only override if it has the default value, preserve any special options @@ -40,7 +40,7 @@ namespace libmpdataxx enum {tmprl_extrp = linear2}; }; - template + template class mpdata_rhs_vip_common : public mpdata_rhs, minhalo> { using parent_t = mpdata_rhs, minhalo>; @@ -49,10 +49,10 @@ namespace libmpdataxx using ix = typename ct_params_t::ix; using real_t = typename ct_params_t::real_t; - protected: - // member fields + protected: + // member fields std::array vip_ixs; - arrvec_t &stash, &vip_rhs; + arrvec_t &stash, &vip_rhs; real_t eps; arrvec_t& vip_stash(const int t_lev) @@ -60,7 +60,7 @@ namespace libmpdataxx // t_lev == 0 -> output for extrapolation/derivatives // t_lev == -1 -> (n-1) state // t_lev == -2 -> (n-2) state, only available with div3_mpdata - + static thread_local arrvec_t ret; ret.resize(parent_t::n_dims); for (int d = 0; d < parent_t::n_dims; ++d) @@ -87,7 +87,7 @@ namespace libmpdataxx // and the (n-2) state and juggle them around to avoid array copying assert(t_lev == 0 || t_lev == -1 || t_lev == -2); auto& comp = (t_lev == 0 ? stash[d] : - this->timestep % 2 == 0 ? stash[d - t_lev * ct_params_t::n_dims] : + this->timestep % 2 == 0 ? stash[d - t_lev * ct_params_t::n_dims] : stash[d + (3 + t_lev) * ct_params_t::n_dims] ); ret.replace(ret.begin() + d, this->mem->never_delete(&(comp))); @@ -97,76 +97,76 @@ namespace libmpdataxx } virtual void fill_stash_helper(const int d) final - { + { // for third-order mpdata saving to t_lev == -2 so that it becomes -1 at the next time step int save_t_lev = parent_t::div3_mpdata ? -2 : -1; - if (ix::vip_den == -1) - vip_stash(save_t_lev)[d](this->ijk) = vips()[d](this->ijk); - else if (eps == 0) // this is the default + if (ix::vip_den == -1) + vip_stash(save_t_lev)[d](this->ijk) = vips()[d](this->ijk); + else if (eps == 0) // this is the default { // for those simulations advecting momentum where the division by mass will not cause division by zero // (for shallow water simulations it means simulations with no collapsing/inflating shallow water layers) vip_stash(save_t_lev)[d](this->ijk) = vips()[d](this->ijk) / this->state(ix::vip_den)(this->ijk); } - else - { - vip_stash(save_t_lev)[d](this->ijk) = where( - // if - this->state(ix::vip_den)(this->ijk) > eps, - // then - vips()[d](this->ijk) / this->state(ix::vip_den)(this->ijk), - // else - 0 - ); - } + else + { + vip_stash(save_t_lev)[d](this->ijk) = where( + // if + this->state(ix::vip_den)(this->ijk) > eps, + // then + vips()[d](this->ijk) / this->state(ix::vip_den)(this->ijk), + // else + 0 + ); + } assert(std::isfinite(sum(vip_stash(save_t_lev)[d](this->ijk)))); - } + } - void fill_stash() + void fill_stash() { for (int d = 0; d < ct_params_t::n_dims; ++d) fill_stash_helper(d); } - void extrp(const int d, const int e) // extrapolate velocity field in time to t+1/2 - { - using namespace arakawa_c; + void extrp(const int d, const int e) // extrapolate velocity field in time to t+1/2 + { + using namespace arakawa_c; const auto beta = this->dt_stash[0] > 0 ? this->dt / (2 * this->dt_stash[0]) : 0; if (!ct_params_t::var_dt && !parent_t::div3_mpdata) { - this->vip_stash(0)[d](this->ijk) *= -beta; + this->vip_stash(0)[d](this->ijk) *= -beta; } else { - this->vip_stash(0)[d](this->ijk) = -beta * this->vip_stash(-1)[d](this->ijk); + this->vip_stash(0)[d](this->ijk) = -beta * this->vip_stash(-1)[d](this->ijk); } - if (ix::vip_den == -1) - this->vip_stash(0)[d](this->ijk) += (1 + beta) * this->state(e)(this->ijk); - else if (eps == 0) //this is the default - { + if (ix::vip_den == -1) + this->vip_stash(0)[d](this->ijk) += (1 + beta) * this->state(e)(this->ijk); + else if (eps == 0) //this is the default + { // for those simulations advecting momentum where the division by mass will not cause division by zero // (for shallow water simulations it means simulations with no collapsing/inflating shallow water layers) - this->vip_stash(0)[d](this->ijk) += (1 + beta) * (this->state(e)(this->ijk) / this->state(ix::vip_den)(this->ijk)); + this->vip_stash(0)[d](this->ijk) += (1 + beta) * (this->state(e)(this->ijk) / this->state(ix::vip_den)(this->ijk)); + } + else + { + this->vip_stash(0)[d](this->ijk) += where( + // if + this->state(ix::vip_den)(this->ijk) > eps, + // then + (1 + beta) * this->state(e)(this->ijk) / this->state(ix::vip_den)(this->ijk), + // else + 0 + ); } - else - { - this->vip_stash(0)[d](this->ijk) += where( - // if - this->state(ix::vip_den)(this->ijk) > eps, - // then - (1 + beta) * this->state(e)(this->ijk) / this->state(ix::vip_den)(this->ijk), - // else - 0 - ); - } assert(std::isfinite(sum(this->vip_stash(0)[d](this->ijk)))); - } + } - arrvec_t& vips() + arrvec_t& vips() { static thread_local arrvec_t ret; ret.resize(parent_t::n_dims); @@ -175,8 +175,8 @@ namespace libmpdataxx return ret; } - virtual void extrapolate_in_time() = 0; - virtual void interpolate_in_space(arrvec_t &dst, + virtual void extrapolate_in_time() = 0; + virtual void interpolate_in_space(arrvec_t &dst, const arrvec_t &src) = 0; virtual void vip_rhs_impl_init() @@ -185,7 +185,7 @@ namespace libmpdataxx { if (static_cast(ct_params_t::vip_vab) == impl) { - vip_rhs[d](this->ijk) = - + vip_rhs[d](this->ijk) = - (*this->mem->vab_coeff)(this->ijk) * (vips()[d](this->ijk) - this->mem->vab_relax[d](this->ijk)); } else @@ -194,7 +194,7 @@ namespace libmpdataxx } } } - + virtual void vip_rhs_expl_calc() { if (static_cast(ct_params_t::vip_vab) == expl) @@ -202,12 +202,12 @@ namespace libmpdataxx for (int d = 0; d < parent_t::n_dims; ++d) { // factor of 2 because it is multiplied by 0.5 * dt in vip_rhs_apply - vip_rhs[d](this->ijk) += -2 * + vip_rhs[d](this->ijk) += -2 * (*this->mem->vab_coeff)(this->ijk) * (vips()[d](this->ijk) - this->mem->vab_relax[d](this->ijk)); } } } - + virtual void vip_rhs_impl_fnlz() { if (static_cast(ct_params_t::vip_vab) == impl) @@ -225,9 +225,9 @@ namespace libmpdataxx } } } - + void vip_rhs_apply() - { + { for (int d = 0; d < parent_t::n_dims; ++d) { vips()[d](this->ijk) += real_t(0.5) * this->dt * vip_rhs[d](this->ijk); @@ -245,7 +245,7 @@ namespace libmpdataxx } } } - + void add_relax() { for (int d = 0; d < parent_t::n_dims; ++d) @@ -255,11 +255,11 @@ namespace libmpdataxx } } - void hook_ante_loop(const typename parent_t::advance_arg_t nt) - { + void hook_ante_loop(const typename parent_t::advance_arg_t nt) + { // fill Courant numbers with zeros so that the divergence test does no harm if (this->rank == 0) - for (int d=0; d < parent_t::n_dims; ++d) this->mem->GC.at(d) = 0; + for (int d=0; d < parent_t::n_dims; ++d) this->mem->GC.at(d) = 0; this->mem->barrier(); for (int d = 0; d < parent_t::n_dims; ++d) @@ -270,25 +270,25 @@ namespace libmpdataxx if (parent_t::div3_mpdata) vip_stash(-2)[d](this->ijk) = 0; } - parent_t::hook_ante_loop(nt); - + parent_t::hook_ante_loop(nt); + vip_rhs_impl_init(); - } + } bool calc_gc() { - //extrapolate velocity field in time (t+1/2) - extrapolate_in_time(); + //extrapolate velocity field in time (t+1/2) + extrapolate_in_time(); - //interpolate from velocity field to courant field (mpdata needs courant numbers from t+1/2) - interpolate_in_space(this->mem->GC, vip_stash(0)); + //interpolate from velocity field to courant field (mpdata needs courant numbers from t+1/2) + interpolate_in_space(this->mem->GC, vip_stash(0)); // TODO: why??? - this->mem->barrier(); + this->mem->barrier(); return true; } - + void calc_ndt_gc() final { if (parent_t::div3_mpdata) @@ -304,7 +304,7 @@ namespace libmpdataxx interpolate_in_space(this->mem->ndt_GC, vip_stash(0)); this->mem->barrier(); } - + if (this->dt_stash[0] > 0 && this->dt_stash[1] > 0) { for (int d = 0; d < parent_t::n_dims; ++d) @@ -324,57 +324,57 @@ namespace libmpdataxx } } - void hook_ante_step() - { - // filling the stash with data from current velocity field - // (so that in the next time step they can be used for extrapolation in time) - fill_stash(); + void hook_ante_step() + { + // filling the stash with data from current velocity field + // (so that in the next time step they can be used for extrapolation in time) + fill_stash(); - // intentionally after stash !!! - // (we have to stash data from the current time step before applying any forcings to it) + // intentionally after stash !!! + // (we have to stash data from the current time step before applying any forcings to it) vip_rhs_expl_calc(); // finish calculating velocity forces before moving on this->mem->barrier(); - parent_t::hook_ante_step(); + parent_t::hook_ante_step(); vip_rhs_apply(); - } - + } + void hook_post_step() - { - parent_t::hook_post_step(); + { + parent_t::hook_post_step(); vip_rhs_impl_fnlz(); } - public: - + public: + struct rt_params_t : parent_t::rt_params_t { real_t vip_eps = 0; }; - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters - ) { - parent_t::alloc(mem, n_iters); - parent_t::alloc_tmp_sclr(mem, __FILE__, + ) { + parent_t::alloc(mem, n_iters); + parent_t::alloc_tmp_sclr(mem, __FILE__, (parent_t::div3_mpdata ? 3 : ct_params_t::var_dt ? 2 : 1) * parent_t::n_dims); // stash - parent_t::alloc_tmp_sclr(mem, __FILE__, parent_t::n_dims); // vip_rhs - } - + parent_t::alloc_tmp_sclr(mem, __FILE__, parent_t::n_dims); // vip_rhs + } + protected: - // ctor - mpdata_rhs_vip_common( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : - parent_t(args, p), - stash(args.mem->tmp[__FILE__][0]), - vip_rhs(args.mem->tmp[__FILE__][1]), + // ctor + mpdata_rhs_vip_common( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : + parent_t(args, p), + stash(args.mem->tmp[__FILE__][0]), + vip_rhs(args.mem->tmp[__FILE__][1]), eps(p.vip_eps) - {} + {} }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_common.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_common.hpp index 2477dd5f..d014a882 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_common.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_common.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -8,7 +8,7 @@ #pragma once #include -#include +#include namespace libmpdataxx { @@ -19,18 +19,18 @@ namespace libmpdataxx template class mpdata_rhs_vip_prs_common : public mpdata_rhs_vip { - using parent_t = mpdata_rhs_vip; + using parent_t = mpdata_rhs_vip; using ix = typename ct_params_t::ix; - using ijk_t = decltype(mpdata_rhs_vip_prs_common::ijk); + using ijk_t = decltype(mpdata_rhs_vip_prs_common::ijk); public: using real_t = typename ct_params_t::real_t; using arr_t = typename parent_t::arr_t; - protected: + protected: - // member fields - const real_t prs_tol, err_tol; + // member fields + const real_t prs_tol, err_tol; int iters = 0; bool converged = false; @@ -48,9 +48,9 @@ namespace libmpdataxx } auto lap( - arr_t &arr, - const ijk_t &ijk, - const std::array& dijk, + arr_t &arr, + const ijk_t &ijk, + const std::array& dijk, bool err_init, // if true then subtract initial state for error calculation bool simple // if true do not normalize gradients (simple laplacian) ) return_macro( @@ -81,42 +81,42 @@ namespace libmpdataxx / formulae::G(*this->mem->G, this->ijk) ) - void ini_pressure() - { - Phi(this->ijk) = 0; + void ini_pressure() + { + Phi(this->ijk) = 0; int npoints = 1; for (int d = 0; d < parent_t::n_dims; ++d) { - Phi(this->ijk) -= real_t(0.5) * pow2(this->vips()[d](this->ijk)); + Phi(this->ijk) -= real_t(0.5) * pow2(this->vips()[d](this->ijk)); npoints *= (this->mem->distmem.grid_size[d]); } - + auto Phi_mean = prs_sum(Phi, this->ijk) / npoints; - Phi(this->ijk) -= Phi_mean; - } + Phi(this->ijk) -= Phi_mean; + } - virtual void pressure_solver_loop_init(bool) = 0; - virtual void pressure_solver_loop_body(bool) = 0; + virtual void pressure_solver_loop_init(bool) = 0; + virtual void pressure_solver_loop_body(bool) = 0; - void pressure_solver_update(bool simple = false) + void pressure_solver_update(bool simple = false) { for (int d = 0; d < parent_t::n_dims; ++d) { tmp_uvw[d](this->ijk) = this->vips()[d](this->ijk); } - //initial error + //initial error err(this->ijk) = lap(Phi, this->ijk, this->dijk, true, simple); - iters = 0; + iters = 0; converged = false; pressure_solver_loop_init(simple); - //pseudo-time loop - while (!converged) - { + //pseudo-time loop + while (!converged) + { pressure_solver_loop_body(simple); - iters++; + iters++; if (iters > 10000) // going beyond 10000 iters means something is really wrong, // usually boundary conditions but not always ! @@ -125,42 +125,42 @@ namespace libmpdataxx } } - this->xchng_pres(this->Phi, this->ijk); + this->xchng_pres(this->Phi, this->ijk); formulae::nabla::calc_grad(tmp_uvw, Phi, this->ijk, this->dijk); } - void pressure_solver_apply() - { + void pressure_solver_apply() + { for (int d = 0; d < parent_t::n_dims; ++d) { - this->vips()[d](this->ijk) -= tmp_uvw[d](this->ijk); + this->vips()[d](this->ijk) -= tmp_uvw[d](this->ijk); } - } + } void hook_ante_loop(const typename parent_t::advance_arg_t nt) { // save initial edge velocities this->save_edges(this->vips(), this->ijk); - + // correct initial velocity - Phi(this->ijk) = real_t(0); - this->xchng_pres(Phi, this->ijk); + Phi(this->ijk) = real_t(0); + this->xchng_pres(Phi, this->ijk); - pressure_solver_update(true); + pressure_solver_update(true); this->xchng_pres(this->Phi, this->ijk); formulae::nabla::calc_grad(tmp_uvw, Phi, this->ijk, this->dijk); - pressure_solver_apply(); + pressure_solver_apply(); this->set_edges(this->vips(), this->ijk, 1); - + parent_t::hook_ante_loop(nt); // potential pressure ini_pressure(); - + // allow pressure_solver_apply at the first time step - this->xchng_pres(this->Phi, this->ijk); + this->xchng_pres(this->Phi, this->ijk); formulae::nabla::calc_grad(tmp_uvw, Phi, this->ijk, this->dijk); for (int d = 0; d < parent_t::n_dims; ++d) { @@ -188,37 +188,37 @@ namespace libmpdataxx } } - public: + public: - struct rt_params_t : parent_t::rt_params_t - { + struct rt_params_t : parent_t::rt_params_t + { real_t prs_tol; }; - // ctor - mpdata_rhs_vip_prs_common( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : - parent_t(args, p), + // ctor + mpdata_rhs_vip_prs_common( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : + parent_t(args, p), prs_tol(p.prs_tol), err_tol(p.prs_tol / this->dt), // make stopping criterion correspond to dimensionless divergence Phi(args.mem->tmp[__FILE__][0][0]), err(args.mem->tmp[__FILE__][0][1]), tmp_uvw(args.mem->tmp[__FILE__][1]), - lap_tmp(args.mem->tmp[__FILE__][2]) - {} + lap_tmp(args.mem->tmp[__FILE__][2]) + {} - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters ) { - parent_t::alloc(mem, n_iters); + parent_t::alloc(mem, n_iters); parent_t::alloc_tmp_sclr(mem, __FILE__, 2); // Phi, err parent_t::alloc_tmp_sclr(mem, __FILE__, parent_t::n_dims); // tmp_uvw parent_t::alloc_tmp_sclr(mem, __FILE__, parent_t::n_dims); // lap_tmp } - }; + }; } // namespace detail } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_gcrk.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_gcrk.hpp index d1145b1d..141fcc46 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_gcrk.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_gcrk.hpp @@ -1,12 +1,12 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) * - * @brief generalized conjugate residual pressure solver - * (for more detailed discussion consult Smolarkiewicz & Margolin 1994 - * Appl. Math and Comp. Sci. + * @brief generalized conjugate residual pressure solver + * (for more detailed discussion consult Smolarkiewicz & Margolin 1994 + * Appl. Math and Comp. Sci. * Variational solver for elliptic problems in atmospheric flows) */ @@ -24,22 +24,22 @@ namespace libmpdataxx { public: - using real_t = typename ct_params_t::real_t; + using real_t = typename ct_params_t::real_t; private: - using parent_t = detail::mpdata_rhs_vip_prs_common; + using parent_t = detail::mpdata_rhs_vip_prs_common; using ix = typename ct_params_t::ix; - real_t beta; + real_t beta; std::vector alpha, tmp_den; - typename parent_t::arr_t lap_err; - arrvec_t p_err, lap_p_err; - + typename parent_t::arr_t lap_err; + arrvec_t p_err, lap_p_err; + void pressure_solver_loop_init(bool simple) final { - p_err[0](this->ijk) = this->err(this->ijk); - lap_p_err[0](this->ijk) = this->lap(p_err[0], this->ijk, this->dijk, false, simple); + p_err[0](this->ijk) = this->err(this->ijk); + lap_p_err[0](this->ijk) = this->lap(p_err[0], this->ijk, this->dijk, false, simple); } void pressure_solver_loop_body(bool simple) final @@ -52,7 +52,7 @@ namespace libmpdataxx this->err(this->ijk) += beta * lap_p_err[v](this->ijk); real_t error = std::max( - std::abs(this->mem->max(this->rank, this->err(this->ijk))), + std::abs(this->mem->max(this->rank, this->err(this->ijk))), std::abs(this->mem->min(this->rank, this->err(this->ijk))) ); @@ -62,15 +62,15 @@ namespace libmpdataxx for (int l = 0; l <= v; ++l) { - if (tmp_den[l] != 0) + if (tmp_den[l] != 0) alpha[l] = - this->prs_sum(lap_err, lap_p_err[l], this->ijk) / tmp_den[l]; } - + if (v < (k_iters - 1)) { - p_err[v + 1](this->ijk) = this->err(this->ijk); + p_err[v + 1](this->ijk) = this->err(this->ijk); lap_p_err[v + 1](this->ijk) = lap_err(this->ijk); - + for (int l = 0; l <= v; ++l) { p_err[v + 1](this->ijk) += alpha[l] * p_err[l](this->ijk); @@ -80,7 +80,7 @@ namespace libmpdataxx } else { - p_err[0](this->ijk) = this->err(this->ijk) + alpha[0] * p_err[0](this->ijk); + p_err[0](this->ijk) = this->err(this->ijk) + alpha[0] * p_err[0](this->ijk); lap_p_err[0](this->ijk) = lap_err(this->ijk) + alpha[0] * lap_p_err[0](this->ijk); for (int l = 1; l <= v; ++l) { @@ -91,34 +91,34 @@ namespace libmpdataxx } } - public: + public: - struct rt_params_t : parent_t::rt_params_t { }; + struct rt_params_t : parent_t::rt_params_t { }; - // ctor - mpdata_rhs_vip_prs_gcrk( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : - parent_t(args, p), + // ctor + mpdata_rhs_vip_prs_gcrk( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : + parent_t(args, p), beta(.25), alpha(k_iters, 1.), tmp_den(k_iters, 1.), - lap_err(args.mem->tmp[__FILE__][0][0]), - lap_p_err(args.mem->tmp[__FILE__][1]), - p_err(args.mem->tmp[__FILE__][2]) - {} + lap_err(args.mem->tmp[__FILE__][0][0]), + lap_p_err(args.mem->tmp[__FILE__][1]), + p_err(args.mem->tmp[__FILE__][2]) + {} - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters ) { - parent_t::alloc(mem, n_iters); - parent_t::alloc_tmp_sclr(mem, __FILE__, 1); - parent_t::alloc_tmp_sclr(mem, __FILE__, k_iters); - parent_t::alloc_tmp_sclr(mem, __FILE__, k_iters); - } - }; + parent_t::alloc(mem, n_iters); + parent_t::alloc_tmp_sclr(mem, __FILE__, 1); + parent_t::alloc_tmp_sclr(mem, __FILE__, k_iters); + parent_t::alloc_tmp_sclr(mem, __FILE__, k_iters); + } + }; } // namespace detail } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_mr.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_mr.hpp index c29e4f4c..fbf0db22 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_mr.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_mr.hpp @@ -1,12 +1,12 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) * - * @brief minimum residual pressure solver - * (for more detailed discussion consult Smolarkiewicz & Margolin 1994 - * Appl. Math and Comp. Sci. + * @brief minimum residual pressure solver + * (for more detailed discussion consult Smolarkiewicz & Margolin 1994 + * Appl. Math and Comp. Sci. * Variational solver for elliptic problems in atmospheric flows) */ @@ -29,11 +29,11 @@ namespace libmpdataxx private: - using parent_t = mpdata_rhs_vip_prs_common; + using parent_t = mpdata_rhs_vip_prs_common; using ix = typename ct_params_t::ix; - real_t beta, tmp_den; - typename parent_t::arr_t lap_err; + real_t beta, tmp_den; + typename parent_t::arr_t lap_err; void pressure_solver_loop_init(bool simple) final {} @@ -48,7 +48,7 @@ namespace libmpdataxx this->err(this->ijk) += beta * this->lap_err(this->ijk); real_t error = std::max( - std::abs(this->mem->max(this->rank, this->err(this->ijk))), + std::abs(this->mem->max(this->rank, this->err(this->ijk))), std::abs(this->mem->min(this->rank, this->err(this->ijk))) ); @@ -57,27 +57,27 @@ namespace libmpdataxx public: - struct rt_params_t : parent_t::rt_params_t { }; + struct rt_params_t : parent_t::rt_params_t { }; - // ctor - mpdata_rhs_vip_prs_mr( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : - parent_t(args, p), + // ctor + mpdata_rhs_vip_prs_mr( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : + parent_t(args, p), beta(.25), tmp_den(1.), - lap_err(args.mem->tmp[__FILE__][0][0]) - {} + lap_err(args.mem->tmp[__FILE__][0][0]) + {} - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters ) { - parent_t::alloc(mem, n_iters); - parent_t::alloc_tmp_sclr(mem, __FILE__, 1); - } - }; + parent_t::alloc(mem, n_iters); + parent_t::alloc_tmp_sclr(mem, __FILE__, 1); + } + }; } // namespace detail } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_pc.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_pc.hpp index f1706533..3c24e1c6 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_pc.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_pc.hpp @@ -1,10 +1,10 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) * - * @brief preconditioned conjugate residual pressure solver + * @brief preconditioned conjugate residual pressure solver * (for more detailed discussion consult Smolarkiewicz & Szmelter 2011 * A Nonhydrostatic Unstructured-Mesh Soundproof Model for Simulation of Internal Gravity Waves * Acta Geophysica) @@ -24,53 +24,53 @@ namespace libmpdataxx class mpdata_rhs_vip_prs_pc : public detail::mpdata_rhs_vip_prs_common { public: - + using real_t = typename ct_params_t::real_t; private: - using parent_t = detail::mpdata_rhs_vip_prs_common; + using parent_t = detail::mpdata_rhs_vip_prs_common; using ix = typename ct_params_t::ix; - const int pc_iters; - real_t beta, alpha, tmp_den; - - typename parent_t::arr_t p_err, q_err, lap_p_err, lap_q_err, pcnd_err; + const int pc_iters; + real_t beta, alpha, tmp_den; - void precond(bool simple) //Richardson scheme - { - //initail q_err for preconditioner - q_err(this->ijk) = real_t(0); + typename parent_t::arr_t p_err, q_err, lap_p_err, lap_q_err, pcnd_err; - //initail preconditioner error - this->pcnd_err(this->ijk) = this->lap(this->q_err, this->ijk, this->dijk, false, simple) - this->err(this->ijk); - //TODO does it change with non_const density? - - assert(pc_iters >= 0 && pc_iters < 10 && "params.pc_iters not specified?"); - for (int it=0; it<=pc_iters; it++) - { - q_err(this->ijk) += real_t(.25) * pcnd_err(this->ijk); - pcnd_err(this->ijk) += real_t(.25) * this->lap(this->pcnd_err, this->ijk, this->dijk); - } - } + void precond(bool simple) //Richardson scheme + { + //initail q_err for preconditioner + q_err(this->ijk) = real_t(0); + + //initail preconditioner error + this->pcnd_err(this->ijk) = this->lap(this->q_err, this->ijk, this->dijk, false, simple) - this->err(this->ijk); + //TODO does it change with non_const density? + + assert(pc_iters >= 0 && pc_iters < 10 && "params.pc_iters not specified?"); + for (int it=0; it<=pc_iters; it++) + { + q_err(this->ijk) += real_t(.25) * pcnd_err(this->ijk); + pcnd_err(this->ijk) += real_t(.25) * this->lap(this->pcnd_err, this->ijk, this->dijk); + } + } void pressure_solver_loop_init(bool simple) final { - precond(simple); - p_err(this->ijk) = q_err(this->ijk); - this->lap_p_err(this->ijk) = this->lap(this->p_err, this->ijk, this->dijk, false, simple); + precond(simple); + p_err(this->ijk) = q_err(this->ijk); + this->lap_p_err(this->ijk) = this->lap(this->p_err, this->ijk, this->dijk, false, simple); } void pressure_solver_loop_body(bool simple) final { tmp_den = this->prs_sum(lap_p_err, lap_p_err, this->ijk); if (tmp_den != 0) beta = -this->prs_sum(this->err, lap_p_err, this->ijk) / tmp_den; - + this->Phi(this->ijk) += beta * p_err(this->ijk); this->err(this->ijk) += beta * lap_p_err(this->ijk); real_t error = std::max( - std::abs(this->mem->max(this->rank, this->err(this->ijk))), + std::abs(this->mem->max(this->rank, this->err(this->ijk))), std::abs(this->mem->min(this->rank, this->err(this->ijk))) ); @@ -83,41 +83,41 @@ namespace libmpdataxx if (tmp_den != 0) alpha = -this->prs_sum(lap_q_err, lap_p_err, this->ijk) / tmp_den; p_err(this->ijk) *= alpha; - p_err(this->ijk) += q_err(this->ijk); - + p_err(this->ijk) += q_err(this->ijk); + lap_p_err(this->ijk) *= alpha; lap_p_err(this->ijk) += lap_q_err(this->ijk); } - public: + public: - struct rt_params_t : parent_t::rt_params_t { int pc_iters; }; + struct rt_params_t : parent_t::rt_params_t { int pc_iters; }; - // ctor - mpdata_rhs_vip_prs_pc( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : - parent_t(args, p), - pc_iters(p.pc_iters), + // ctor + mpdata_rhs_vip_prs_pc( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : + parent_t(args, p), + pc_iters(p.pc_iters), beta(.25), alpha(1.), tmp_den(1.), - lap_p_err(args.mem->tmp[__FILE__][0][0]), - lap_q_err(args.mem->tmp[__FILE__][0][1]), - p_err(args.mem->tmp[__FILE__][0][2]), - q_err(args.mem->tmp[__FILE__][0][3]), - pcnd_err(args.mem->tmp[__FILE__][0][4]) - {} - - static void alloc( - typename parent_t::mem_t *mem, + lap_p_err(args.mem->tmp[__FILE__][0][0]), + lap_q_err(args.mem->tmp[__FILE__][0][1]), + p_err(args.mem->tmp[__FILE__][0][2]), + q_err(args.mem->tmp[__FILE__][0][3]), + pcnd_err(args.mem->tmp[__FILE__][0][4]) + {} + + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters ) { - parent_t::alloc(mem, n_iters); - parent_t::alloc_tmp_sclr(mem, __FILE__, 5); - } - }; + parent_t::alloc(mem, n_iters); + parent_t::alloc_tmp_sclr(mem, __FILE__, 5); + } + }; } // namespcae detail } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_common.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_common.hpp index d3e318ff..4292e670 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_common.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_common.hpp @@ -94,7 +94,7 @@ namespace libmpdataxx // TODO: get rid of superfluous barriers for (auto& vip : this->vips()) this->xchng_sclr(vip, this->ijk, 1); - + if (static_cast(ct_params_t::stress_diff) == compact) { calc_drag_cmpct(); @@ -115,10 +115,10 @@ namespace libmpdataxx this->xchng_sgs_tnsr_diag(tau, this->vips()[ct_params_t::n_dims - 1], vip_div, this->ijk); this->xchng_sgs_tnsr_offdiag(tau, tau_srfc, this->ijk, this->ijkm); - + // multiply deformation tensor by sgs viscosity to obtain stress tensor multiply_sgs_visc(); - + // update forces formulae::stress::calc_stress_rhs_cmpct(this->vip_rhs, tau, @@ -138,13 +138,13 @@ namespace libmpdataxx for (int d = 0; d < std::pow(static_cast(ct_params_t::n_dims), 2); ++d) pade_deriv(d); } - + // calculate independent components of deformation tensor formulae::stress::calc_deform(tau, drv, this->ijk); - + // multiply deformation tensor by sgs viscosity to obtain stress tensor multiply_sgs_visc(); - + // TODO: get rid of superfluous barriers for (auto& t : tau) { @@ -167,9 +167,9 @@ namespace libmpdataxx public: - struct rt_params_t : parent_t::rt_params_t - { - real_t cdrag = 0; + struct rt_params_t : parent_t::rt_params_t + { + real_t cdrag = 0; }; // ctor @@ -195,11 +195,11 @@ namespace libmpdataxx } static void alloc( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const int &n_iters ) { parent_t::alloc(mem, n_iters); - // no staggering for non-compact differencing + // no staggering for non-compact differencing if (static_cast(ct_params_t::stress_diff) != compact) { parent_t::alloc_tmp_sclr(mem, __FILE__, 3 * (ct_params_t::n_dims - 1)); // unique strain rate tensor elements diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_dns.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_dns.hpp index 6f3c1ed0..23f4ce4f 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_dns.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_dns.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -17,11 +17,11 @@ namespace libmpdataxx template class mpdata_rhs_vip_prs_sgs_dns : public detail::mpdata_rhs_vip_prs_sgs_common { - using parent_t = detail::mpdata_rhs_vip_prs_sgs_common; + using parent_t = detail::mpdata_rhs_vip_prs_sgs_common; protected: - - typename ct_params_t::real_t eta; + + typename ct_params_t::real_t eta; void multiply_sgs_visc() final { @@ -41,24 +41,24 @@ namespace libmpdataxx } } - public: + public: struct rt_params_t : parent_t::rt_params_t { typename ct_params_t::real_t eta = 0; }; - // ctor - mpdata_rhs_vip_prs_sgs_dns( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : - parent_t(args, p), + // ctor + mpdata_rhs_vip_prs_sgs_dns( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : + parent_t(args, p), eta(p.eta) - { + { if (eta == 0) throw std::runtime_error("eta == 0"); } - }; + }; } // namespace detail } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_smg.hpp b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_smg.hpp index c3254b03..d8c57950 100644 --- a/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_smg.hpp +++ b/libmpdata++/solvers/detail/mpdata_rhs_vip_prs_sgs_smg.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -17,15 +17,15 @@ namespace libmpdataxx template class mpdata_rhs_vip_prs_sgs_smg : public detail::mpdata_rhs_vip_prs_sgs_common { - using parent_t = detail::mpdata_rhs_vip_prs_sgs_common; + using parent_t = detail::mpdata_rhs_vip_prs_sgs_common; public: using real_t = typename ct_params_t::real_t; protected: - - real_t smg_c, c_m; + + real_t smg_c, c_m; typename parent_t::arr_t &k_m; void multiply_sgs_visc() @@ -56,34 +56,34 @@ namespace libmpdataxx } } - public: + public: struct rt_params_t : parent_t::rt_params_t { real_t smg_c, c_m; }; - // ctor - mpdata_rhs_vip_prs_sgs_smg( - typename parent_t::ctor_args_t args, - const rt_params_t &p - ) : - parent_t(args, p), + // ctor + mpdata_rhs_vip_prs_sgs_smg( + typename parent_t::ctor_args_t args, + const rt_params_t &p + ) : + parent_t(args, p), smg_c(p.smg_c), c_m(p.c_m), k_m(args.mem->tmp[__FILE__][0][0]) - { + { if (smg_c == 0) throw std::runtime_error("smg_c == 0"); } static void alloc( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const int &n_iters ) { parent_t::alloc(mem, n_iters); parent_t::alloc_tmp_sclr(mem, __FILE__, 1); // k_m } - }; + }; } // namespace detail } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/detail/solver_1d.hpp b/libmpdata++/solvers/detail/solver_1d.hpp index f579a6bf..ff8c0890 100644 --- a/libmpdata++/solvers/detail/solver_1d.hpp +++ b/libmpdata++/solvers/detail/solver_1d.hpp @@ -17,21 +17,21 @@ namespace libmpdataxx { template class solver< - ct_params_t, - n_tlev, + ct_params_t, + n_tlev, minhalo, typename std::enable_if::type > : public solver_common { - using parent_t = solver_common; + using parent_t = solver_common; public: - using real_t = typename ct_params_t::real_t; + using real_t = typename ct_params_t::real_t; - protected: + protected: - const rng_t i; //TODO: to be removed + const rng_t i; //TODO: to be removed // generic field used for various statistics (currently Courant number and divergence) typename parent_t::arr_t &stat_field; // TODO: should be in solver common but cannot be allocated there ? @@ -50,17 +50,17 @@ namespace libmpdataxx xchng_sclr(arr); } - void xchng(int e) final - { + void xchng(int e) final + { xchng_sclr(this->mem->psi[e][ this->n[e]]); - } + } void xchng_vctr_alng(arrvec_t &arrvec, const bool ad = false, const bool cyclic = false) final { this->mem->barrier(); if (!cyclic) { - for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_alng(arrvec, ad); + for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_alng(arrvec, ad); } else { @@ -74,7 +74,7 @@ namespace libmpdataxx stat_field(this->ijk) = real_t(0.5) * (abs(arrvec[0](i+h) + arrvec[0](i-h))); return this->mem->max(this->rank, stat_field(this->ijk)); } - + real_t max_abs_vctr_div(const arrvec_t &arrvec) final { stat_field(this->ijk) = abs((arrvec[0](i+h) - arrvec[0](i-h))); @@ -90,14 +90,14 @@ namespace libmpdataxx } public: - + struct ctor_args_t { // these should be common for 1D,2D,3D int rank; typename parent_t::mem_t *mem; // - typename parent_t::bcp_t &bcxl, &bcxr; + typename parent_t::bcp_t &bcxl, &bcxr; const rng_t &i; }; @@ -108,20 +108,20 @@ namespace libmpdataxx protected: - // ctor - solver( + // ctor + solver( ctor_args_t args, const rt_params_t &p ) : - parent_t( + parent_t( args.rank, - args.mem, - p, + args.mem, + p, idx_t(args.i) - ), + ), i(args.i), stat_field(args.mem->tmp[__FILE__][0][0]) - { + { this->di = p.di; this->dijk = {p.di}; this->set_bcs(0, args.bcxl, args.bcxr); @@ -131,38 +131,38 @@ namespace libmpdataxx private: - static void alloc_tmp( - typename parent_t::mem_t *mem, - const char * __file__, - const int n_arr, - const rng_t rng, + static void alloc_tmp( + typename parent_t::mem_t *mem, + const char * __file__, + const int n_arr, + const rng_t rng, std::string name = "" - ) - { - mem->tmp[__file__].push_back(new arrvec_t()); + ) + { + mem->tmp[__file__].push_back(new arrvec_t()); if (!name.empty()) mem->avail_tmp[name] = std::make_pair(__file__, mem->tmp[__file__].size() - 1); for (int n = 0; n < n_arr; ++n) { - mem->tmp[__file__].back().push_back( + mem->tmp[__file__].back().push_back( mem->old(new typename parent_t::arr_t( rng )) - ); + ); } - } + } public: - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters ) { mem->psi.resize(parent_t::n_eqns); - for (int e = 0; e < parent_t::n_eqns; ++e) // equations - for (int n = 0; n < n_tlev; ++n) // time levels - mem->psi[e].push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_sclr(mem->grid_size[0])))); - - mem->GC.push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_vctr(mem->grid_size[0])))); + for (int e = 0; e < parent_t::n_eqns; ++e) // equations + for (int n = 0; n < n_tlev; ++n) // time levels + mem->psi[e].push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_sclr(mem->grid_size[0])))); + + mem->GC.push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_vctr(mem->grid_size[0])))); // fully third-order accurate mpdata needs also time derivatives of // the Courant field @@ -170,42 +170,42 @@ namespace libmpdataxx opts::isset(ct_params_t::opts, opts::div_3rd_dt)) { // TODO: why for (auto f : {mem->ndt_GC, mem->ndtt_GC}) doesn't work ? - mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_vctr(mem->grid_size[0])))); - mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_vctr(mem->grid_size[0])))); + mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_vctr(mem->grid_size[0])))); + mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t(parent_t::rng_vctr(mem->grid_size[0])))); } if (opts::isset(ct_params_t::opts, opts::nug)) - mem->G.reset(mem->old(new typename parent_t::arr_t(parent_t::rng_sclr(mem->grid_size[0])))); + mem->G.reset(mem->old(new typename parent_t::arr_t(parent_t::rng_sclr(mem->grid_size[0])))); // allocate Kahan summation temporary vars if (opts::isset(ct_params_t::opts, opts::khn)) - for (int n = 0; n < 3; ++n) - mem->khn_tmp.push_back(mem->old(new typename parent_t::arr_t( + for (int n = 0; n < 3; ++n) + mem->khn_tmp.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]) ))); // courant field alloc_tmp_sclr(mem, __FILE__, 1); - } + } protected: // helper method to allocate a vector-component temporary array static void alloc_tmp_vctr( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const char * __file__ ) { alloc_tmp(mem, __file__, 1, parent_t::rng_vctr(mem->grid_size[0])); // always one-component vectors } - // helper method to allocate n_arr scalar temporary arrays + // helper method to allocate n_arr scalar temporary arrays static void alloc_tmp_sclr( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const char * __file__, const int n_arr ) { - alloc_tmp(mem, __file__, n_arr, parent_t::rng_sclr(mem->grid_size[0])); + alloc_tmp(mem, __file__, n_arr, parent_t::rng_sclr(mem->grid_size[0])); } }; } // namespace detail diff --git a/libmpdata++/solvers/detail/solver_2d.hpp b/libmpdata++/solvers/detail/solver_2d.hpp index 82c216a3..59ad0107 100644 --- a/libmpdata++/solvers/detail/solver_2d.hpp +++ b/libmpdata++/solvers/detail/solver_2d.hpp @@ -1,4 +1,4 @@ -/** @file +/** @file * @copyright University of Warsaw * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) @@ -18,42 +18,42 @@ namespace libmpdataxx template class solver< - ct_params_t, - n_tlev, + ct_params_t, + n_tlev, minhalo, typename std::enable_if::type > : public solver_common { - using parent_t = solver_common; + using parent_t = solver_common; public: - using real_t = typename ct_params_t::real_t; + using real_t = typename ct_params_t::real_t; - protected: - - const rng_t i, j; // TODO: to be removed + protected: + + const rng_t i, j; // TODO: to be removed // generic field used for various statistics (currently Courant number and divergence) typename parent_t::arr_t &stat_field; // TODO: should be in solver common but cannot be allocated there ? - virtual void xchng_sclr(typename parent_t::arr_t &arr, + virtual void xchng_sclr(typename parent_t::arr_t &arr, const idx_t<2> &range_ijk, const int ext = 0, const bool deriv = false ) final // for a given array - { + { const auto range_ijk_0__ext = this->extend_range(range_ijk[0], ext); this->mem->barrier(); for (auto &bc : this->bcs[0]) bc->fill_halos_sclr(arr, range_ijk[1]^ext, deriv); - for (auto &bc : this->bcs[1]) bc->fill_halos_sclr(arr, range_ijk_0__ext, deriv); + for (auto &bc : this->bcs[1]) bc->fill_halos_sclr(arr, range_ijk_0__ext, deriv); this->mem->barrier(); - } + } - void xchng(int e) final - { + void xchng(int e) final + { this->xchng_sclr(this->mem->psi[e][ this->n[e]], this->ijk, this->halo); - } + } void xchng_vctr_alng(arrvec_t &arrvec, const bool ad = false, const bool cyclic = false) final { @@ -71,7 +71,7 @@ namespace libmpdataxx // TODO: open bc nust be last!!! this->mem->barrier(); } - + virtual void xchng_flux(arrvec_t &arrvec) final { this->mem->barrier(); @@ -79,7 +79,7 @@ namespace libmpdataxx for (auto &bc : this->bcs[1]) bc->fill_halos_flux(arrvec, i); this->mem->barrier(); } - + virtual void xchng_sgs_div( typename parent_t::arr_t &arr, const idx_t<2> &range_ijk @@ -90,7 +90,7 @@ namespace libmpdataxx for (auto &bc : this->bcs[1]) bc->fill_halos_sgs_div(arr, range_ijk[0]); this->mem->barrier(); } - + virtual void xchng_sgs_vctr(arrvec_t &av, const typename parent_t::arr_t &b, const idx_t<2> &range_ijk @@ -105,7 +105,7 @@ namespace libmpdataxx virtual void xchng_sgs_tnsr_diag(arrvec_t &av, const typename parent_t::arr_t &w, const typename parent_t::arr_t &vip_div, - const idx_t<2> &range_ijk + const idx_t<2> &range_ijk ) final { this->mem->barrier(); @@ -115,21 +115,21 @@ namespace libmpdataxx } virtual void xchng_sgs_tnsr_offdiag(arrvec_t &av, - const arrvec_t &bv, - const idx_t<2> &range_ijk, - const std::array &range_ijkm + const arrvec_t &bv, + const idx_t<2> &range_ijk, + const std::array &range_ijkm ) final { // off-diagonal components of stress tensor are treated the same as a vector this->mem->barrier(); for (auto &bc : this->bcs[0]) bc->fill_halos_sgs_vctr(av, bv[0], range_ijkm[1], 2); - for (auto &bc : this->bcs[1]) bc->fill_halos_sgs_vctr(av, bv[0], range_ijkm[0], 1); + for (auto &bc : this->bcs[1]) bc->fill_halos_sgs_vctr(av, bv[0], range_ijkm[0], 1); this->mem->barrier(); } virtual void xchng_vctr_nrml( - arrvec_t &arrvec, + arrvec_t &arrvec, const idx_t<2> &range_ijk, const int ext = 0, const bool cyclic = false @@ -197,8 +197,8 @@ namespace libmpdataxx { real_t max_abs_div = max_abs_vctr_div(this->mem->GC); - if (max_abs_div > this->max_abs_div_eps) - throw std::runtime_error("initial advector field is divergent"); + if (max_abs_div > this->max_abs_div_eps) + throw std::runtime_error("initial advector field is divergent"); } } @@ -210,7 +210,7 @@ namespace libmpdataxx ) / formulae::G(*this->mem->G, i, j); return this->mem->max(this->rank, stat_field(this->ijk)); } - + real_t max_abs_vctr_div(const arrvec_t &arrvec) final { stat_field(this->ijk) = abs( @@ -219,7 +219,7 @@ namespace libmpdataxx ) / formulae::G(*this->mem->G, i, j); return this->mem->max(this->rank, stat_field(this->ijk)); } - + void scale_gc(const real_t time, const real_t cur_dt, const real_t old_dt) final @@ -232,17 +232,17 @@ namespace libmpdataxx } public: - + struct ctor_args_t - { + { // these should be common for 1D,2D,3D int rank; typename parent_t::mem_t *mem; // - typename parent_t::bcp_t &bcxl, &bcxr, &bcyl, &bcyr; - const rng_t &i, &j; - }; - + typename parent_t::bcp_t &bcxl, &bcxr, &bcyl, &bcyr; + const rng_t &i, &j; + }; + struct rt_params_t : parent_t::rt_params_t { real_t di = 0, dj = 0; @@ -250,53 +250,53 @@ namespace libmpdataxx protected: - // ctor - solver( + // ctor + solver( ctor_args_t args, const rt_params_t &p ) : - parent_t( + parent_t( args.rank, - args.mem, - p, + args.mem, + p, idx_t({args.i, args.j}) ), - i(args.i), - j(args.j), + i(args.i), + j(args.j), stat_field(args.mem->tmp[__FILE__][0][0]) - { + { this->di = p.di; this->dj = p.dj; this->dijk = {p.di, p.dj}; - this->set_bcs(0, args.bcxl, args.bcxr); - this->set_bcs(1, args.bcyl, args.bcyr); + this->set_bcs(0, args.bcxl, args.bcxr); + this->set_bcs(1, args.bcyl, args.bcyr); } // memory allocation logic using static methods - public: + public: - static void alloc( - typename parent_t::mem_t *mem, + static void alloc( + typename parent_t::mem_t *mem, const int &n_iters ) { - // psi + // psi mem->psi.resize(parent_t::n_eqns); - for (int e = 0; e < parent_t::n_eqns; ++e) // equations - for (int n = 0; n < n_tlev; ++n) // time levels - mem->psi[e].push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_sclr(mem->grid_size[0]), + for (int e = 0; e < parent_t::n_eqns; ++e) // equations + for (int n = 0; n < n_tlev; ++n) // time levels + mem->psi[e].push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]) ))); // Courant field components (Arakawa-C grid) - mem->GC.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_vctr(mem->grid_size[0]), - parent_t::rng_sclr(mem->grid_size[1]) + mem->GC.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_vctr(mem->grid_size[0]), + parent_t::rng_sclr(mem->grid_size[1]) ))); - mem->GC.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_sclr(mem->grid_size[0]), - parent_t::rng_vctr(mem->grid_size[1]) + mem->GC.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_sclr(mem->grid_size[0]), + parent_t::rng_vctr(mem->grid_size[1]) ))); // fully third-order accurate mpdata needs also time derivatives of @@ -305,36 +305,36 @@ namespace libmpdataxx opts::isset(ct_params_t::opts, opts::div_3rd_dt)) { // TODO: why for (auto f : {mem->ndt_GC, mem->ndtt_GC}) doesn't work ? - mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_vctr(mem->grid_size[0]), - parent_t::rng_sclr(mem->grid_size[1]) + mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_vctr(mem->grid_size[0]), + parent_t::rng_sclr(mem->grid_size[1]) ))); - mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_sclr(mem->grid_size[0]), - parent_t::rng_vctr(mem->grid_size[1]) + mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_sclr(mem->grid_size[0]), + parent_t::rng_vctr(mem->grid_size[1]) ))); - mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_vctr(mem->grid_size[0]), - parent_t::rng_sclr(mem->grid_size[1]) + mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_vctr(mem->grid_size[0]), + parent_t::rng_sclr(mem->grid_size[1]) ))); - mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_sclr(mem->grid_size[0]), - parent_t::rng_vctr(mem->grid_size[1]) + mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_sclr(mem->grid_size[0]), + parent_t::rng_vctr(mem->grid_size[1]) ))); } - + // allocate G if (opts::isset(ct_params_t::opts, opts::nug)) - mem->G.reset(mem->old(new typename parent_t::arr_t( + mem->G.reset(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]) ))); // allocate Kahan summation temporary vars if (opts::isset(ct_params_t::opts, opts::khn)) - for (int n = 0; n < 3; ++n) - mem->khn_tmp.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_sclr(mem->grid_size[0]), + for (int n = 0; n < 3; ++n) + mem->khn_tmp.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]) ))); // courant field @@ -360,10 +360,10 @@ namespace libmpdataxx srfc ? rng_t(0, 0) : stgr[n][1] ? parent_t::rng_vctr(mem->grid_size[1]) : parent_t::rng_sclr(mem->grid_size[1]) - ))); + ))); } } - + // helper method to allocate a temporary space composed of vector-component arrays static void alloc_tmp_vctr( typename parent_t::mem_t *mem, @@ -373,24 +373,24 @@ namespace libmpdataxx alloc_tmp_stgr(mem, __file__, 2, {{true, false}, {false, true}}); } - // helper method to allocate n_arr scalar temporary arrays + // helper method to allocate n_arr scalar temporary arrays static void alloc_tmp_sclr( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const char * __file__, const int n_arr, std::string name = "", bool srfc = false - ) - { + ) + { mem->tmp[__file__].push_back(new arrvec_t()); if (!name.empty()) mem->avail_tmp[name] = std::make_pair(__file__, mem->tmp[__file__].size() - 1); for (int n = 0; n < n_arr; ++n) - mem->tmp[__file__].back().push_back(mem->old(new typename parent_t::arr_t( + mem->tmp[__file__].back().push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), srfc ? rng_t(0, 0) : parent_t::rng_sclr(mem->grid_size[1]) ))); - } + } }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/solver_3d.hpp b/libmpdata++/solvers/detail/solver_3d.hpp index 595bf8e8..bbf041d7 100644 --- a/libmpdata++/solvers/detail/solver_3d.hpp +++ b/libmpdata++/solvers/detail/solver_3d.hpp @@ -15,64 +15,64 @@ namespace libmpdataxx namespace detail { using namespace arakawa_c; - + template class solver< - ct_params_t, - n_tlev, + ct_params_t, + n_tlev, minhalo, typename std::enable_if::type > : public solver_common { - using parent_t = solver_common; + using parent_t = solver_common; public: - using real_t = typename ct_params_t::real_t; + using real_t = typename ct_params_t::real_t; - protected: + protected: - const rng_t i, j, k; // TODO: we have ijk in solver_common - could it be removed? + const rng_t i, j, k; // TODO: we have ijk in solver_common - could it be removed? // generic field used for various statistics (currently Courant number and divergence) typename parent_t::arr_t &stat_field; // TODO:/: should be in solver common but cannot be allocated there ? - virtual void xchng_sclr(typename parent_t::arr_t &arr, - const idx_t<3> &range_ijk, + virtual void xchng_sclr(typename parent_t::arr_t &arr, + const idx_t<3> &range_ijk, const int ext = 0, const bool deriv = false ) final // for a given array - { + { const auto range_ijk_0__ext = this->extend_range(range_ijk[0], ext); this->mem->barrier(); for (auto &bc : this->bcs[0]) bc->fill_halos_sclr(arr, range_ijk[1]^ext, range_ijk[2]^ext, deriv); - for (auto &bc : this->bcs[1]) bc->fill_halos_sclr(arr, range_ijk[2]^ext, range_ijk_0__ext, deriv); - for (auto &bc : this->bcs[2]) bc->fill_halos_sclr(arr, range_ijk_0__ext, range_ijk[1]^ext, deriv); + for (auto &bc : this->bcs[1]) bc->fill_halos_sclr(arr, range_ijk[2]^ext, range_ijk_0__ext, deriv); + for (auto &bc : this->bcs[2]) bc->fill_halos_sclr(arr, range_ijk_0__ext, range_ijk[1]^ext, deriv); this->mem->barrier(); - } - void xchng(int e) final - { - this->xchng_sclr(this->mem->psi[e][ this->n[e]], this->ijk, this->halo); - } + } + void xchng(int e) final + { + this->xchng_sclr(this->mem->psi[e][ this->n[e]], this->ijk, this->halo); + } void xchng_vctr_alng(arrvec_t &arrvec, const bool ad = false, const bool cyclic = false) final { this->mem->barrier(); if (!cyclic) { - for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_alng(arrvec, j, k, ad); - for (auto &bc : this->bcs[1]) bc->fill_halos_vctr_alng(arrvec, k, i, ad); + for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_alng(arrvec, j, k, ad); + for (auto &bc : this->bcs[1]) bc->fill_halos_vctr_alng(arrvec, k, i, ad); for (auto &bc : this->bcs[2]) bc->fill_halos_vctr_alng(arrvec, i, j, ad); } else { - for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_alng_cyclic(arrvec, j, k, ad); - for (auto &bc : this->bcs[1]) bc->fill_halos_vctr_alng_cyclic(arrvec, k, i, ad); + for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_alng_cyclic(arrvec, j, k, ad); + for (auto &bc : this->bcs[1]) bc->fill_halos_vctr_alng_cyclic(arrvec, k, i, ad); for (auto &bc : this->bcs[2]) bc->fill_halos_vctr_alng_cyclic(arrvec, i, j, ad); } this->mem->barrier(); } - + virtual void xchng_flux(arrvec_t &arrvec) final { this->mem->barrier(); @@ -80,10 +80,10 @@ namespace libmpdataxx for (auto &bc : this->bcs[1]) bc->fill_halos_flux(arrvec, k, i); for (auto &bc : this->bcs[2]) bc->fill_halos_flux(arrvec, i, j); } - + virtual void xchng_sgs_div( - typename parent_t::arr_t &arr, - const idx_t<3> &range_ijk + typename parent_t::arr_t &arr, + const idx_t<3> &range_ijk ) final { this->mem->barrier(); @@ -92,38 +92,38 @@ namespace libmpdataxx for (auto &bc : this->bcs[2]) bc->fill_halos_sgs_div(arr, range_ijk[0], range_ijk[1]); this->mem->barrier(); } - + virtual void xchng_sgs_vctr(arrvec_t &av, - const typename parent_t::arr_t &b, - const idx_t<3> &range_ijk + const typename parent_t::arr_t &b, + const idx_t<3> &range_ijk ) final - { + { this->mem->barrier(); for (auto &bc : this->bcs[0]) bc->fill_halos_sgs_vctr(av, b, range_ijk[1], range_ijk[2]); - for (auto &bc : this->bcs[1]) bc->fill_halos_sgs_vctr(av, b, range_ijk[2], range_ijk[0]); - for (auto &bc : this->bcs[2]) bc->fill_halos_sgs_vctr(av, b, range_ijk[0], range_ijk[1]); + for (auto &bc : this->bcs[1]) bc->fill_halos_sgs_vctr(av, b, range_ijk[2], range_ijk[0]); + for (auto &bc : this->bcs[2]) bc->fill_halos_sgs_vctr(av, b, range_ijk[0], range_ijk[1]); this->mem->barrier(); - } - + } + virtual void xchng_sgs_tnsr_diag(arrvec_t &av, const typename parent_t::arr_t &w, const typename parent_t::arr_t &vip_div, - const idx_t<3> &range_ijk + const idx_t<3> &range_ijk ) final - { + { this->mem->barrier(); for (auto &bc : this->bcs[0]) bc->fill_halos_sgs_tnsr(av, w, vip_div, range_ijk[1], range_ijk[2], this->dijk[0]); - for (auto &bc : this->bcs[1]) bc->fill_halos_sgs_tnsr(av, w, vip_div, range_ijk[2], range_ijk[0], this->dijk[1]); - for (auto &bc : this->bcs[2]) bc->fill_halos_sgs_tnsr(av, w, vip_div, range_ijk[0], range_ijk[1], this->dijk[2]); + for (auto &bc : this->bcs[1]) bc->fill_halos_sgs_tnsr(av, w, vip_div, range_ijk[2], range_ijk[0], this->dijk[1]); + for (auto &bc : this->bcs[2]) bc->fill_halos_sgs_tnsr(av, w, vip_div, range_ijk[0], range_ijk[1], this->dijk[2]); this->mem->barrier(); - } - + } + virtual void xchng_sgs_tnsr_offdiag(arrvec_t &av, - const arrvec_t &bv, - const idx_t<3> &range_ijk, - const std::array &range_ijkm + const arrvec_t &bv, + const idx_t<3> &range_ijk, + const std::array &range_ijkm ) final - { + { // off-diagonal components of stress tensor are treated the same as a vector this->mem->barrier(); for (auto &bc : this->bcs[0]) @@ -132,19 +132,19 @@ namespace libmpdataxx bc->fill_halos_sgs_vctr(av, bv[1], range_ijk[1]^1, range_ijkm[2], 4); } - for (auto &bc : this->bcs[1]) + for (auto &bc : this->bcs[1]) { bc->fill_halos_sgs_vctr(av, bv[0], range_ijk[2]^1, range_ijkm[0], 2); bc->fill_halos_sgs_vctr(av, bv[1], range_ijkm[2], range_ijk[0]^1, 4); } - for (auto &bc : this->bcs[2]) + for (auto &bc : this->bcs[2]) { bc->fill_halos_sgs_vctr(av, bv[0], range_ijkm[0], range_ijk[1]^1, 2); bc->fill_halos_sgs_vctr(av, bv[1], range_ijk[0]^1, range_ijkm[1], 3); } this->mem->barrier(); - } + } virtual void xchng_vctr_nrml( arrvec_t &arrvec, @@ -159,7 +159,7 @@ namespace libmpdataxx if (!cyclic) { for (auto &bc : this->bcs[1]) bc->fill_halos_vctr_nrml(arrvec[0], range_ijk[2]^ext^1, range_ijk[0]^ext^h); - + // without this barrier, there is a race condition when some threads handle subdomains // with one gridpoint width, the problem manifests itself, for example, in pbl test // TODO: figure out the exact cause and try to avoid this barrier, what about 2D, @@ -173,7 +173,7 @@ namespace libmpdataxx for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_nrml(arrvec[1], range_ijk[1]^ext^h, range_ijk[2]^ext^1); for (auto &bc : this->bcs[2]) bc->fill_halos_vctr_nrml(arrvec[1], range_ijk_0__ext_1, range_ijk[1]^ext^h); - + for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_nrml(arrvec[2], range_ijk[1]^ext^1, range_ijk[2]^ext^h); for (auto &bc : this->bcs[1]) bc->fill_halos_vctr_nrml(arrvec[2], range_ijk[2]^ext^h, range_ijk_0__ext_1); } @@ -184,7 +184,7 @@ namespace libmpdataxx for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_nrml_cyclic(arrvec[1], range_ijk[1]^ext^h, range_ijk[2]^ext^1); for (auto &bc : this->bcs[2]) bc->fill_halos_vctr_nrml_cyclic(arrvec[1], range_ijk_0__ext_1, range_ijk[1]^ext^h); - + for (auto &bc : this->bcs[0]) bc->fill_halos_vctr_nrml_cyclic(arrvec[2], range_ijk[1]^ext^1, range_ijk[2]^ext^h); for (auto &bc : this->bcs[1]) bc->fill_halos_vctr_nrml_cyclic(arrvec[2], range_ijk[2]^ext^h, range_ijk_0__ext_1); } @@ -192,8 +192,8 @@ namespace libmpdataxx } virtual void xchng_pres( - typename parent_t::arr_t &arr, - const idx_t<3> &range_ijk, + typename parent_t::arr_t &arr, + const idx_t<3> &range_ijk, const int ext = 0 ) final { @@ -207,7 +207,7 @@ namespace libmpdataxx virtual void set_edges( arrvec_t &av, - const idx_t<3> &range_ijk, + const idx_t<3> &range_ijk, const int &sign ) final { @@ -216,10 +216,10 @@ namespace libmpdataxx for (auto &bc : this->bcs[2]) bc->set_edge_pres(av[2], range_ijk[0], range_ijk[1], sign); this->mem->barrier(); } - + virtual void save_edges( const arrvec_t &av, - const idx_t<3> &range_ijk + const idx_t<3> &range_ijk ) final { for (auto &bc : this->bcs[0]) bc->save_edge_vel(av[0], range_ijk[1], range_ijk[2]); @@ -227,19 +227,19 @@ namespace libmpdataxx for (auto &bc : this->bcs[2]) bc->save_edge_vel(av[2], range_ijk[0], range_ijk[1]); this->mem->barrier(); } - + void hook_ante_loop(const typename parent_t::advance_arg_t nt) // TODO: this nt conflicts in fact with multiple-advance()-call logic! { parent_t::hook_ante_loop(nt); - + // sanity check for non-divergence of the initial Courant number field // TODO: same in 1D if (!opts::isset(ct_params_t::opts, opts::dfl)) { real_t max_abs_div = max_abs_vctr_div(this->mem->GC); - if (max_abs_div > this->max_abs_div_eps) - throw std::runtime_error("initial advector field is divergent"); + if (max_abs_div > this->max_abs_div_eps) + throw std::runtime_error("initial advector field is divergent"); } } @@ -252,7 +252,7 @@ namespace libmpdataxx ) / formulae::G(*this->mem->G, i, j, k); return this->mem->max(this->rank, stat_field(this->ijk)); } - + real_t max_abs_vctr_div(const arrvec_t &arrvec) final { stat_field(this->ijk) = abs( @@ -279,17 +279,17 @@ namespace libmpdataxx public: struct ctor_args_t - { + { // these should be common for 1D,2D,3D int rank; typename parent_t::mem_t *mem; // - typename parent_t::bcp_t - &bcxl, &bcxr, + typename parent_t::bcp_t + &bcxl, &bcxr, &bcyl, &bcyr, - &bczl, &bczr; - const rng_t &i, &j, &k; - }; + &bczl, &bczr; + const rng_t &i, &j, &k; + }; struct rt_params_t : parent_t::rt_params_t { @@ -298,60 +298,60 @@ namespace libmpdataxx protected: - // ctor - solver( + // ctor + solver( ctor_args_t args, const rt_params_t &p ) : - parent_t( + parent_t( args.rank, - args.mem, + args.mem, p, - idx_t({args.i, args.j, args.k}) + idx_t({args.i, args.j, args.k}) ), - i(args.i), - j(args.j), + i(args.i), + j(args.j), k(args.k), stat_field(args.mem->tmp[__FILE__][0][0]) - { + { this->di = p.di; this->dj = p.dj; this->dk = p.dk; this->dijk = {p.di, p.dj, p.dk}; this->set_bcs(0, args.bcxl, args.bcxr); - this->set_bcs(1, args.bcyl, args.bcyr); - this->set_bcs(2, args.bczl, args.bczr); - } + this->set_bcs(1, args.bcyl, args.bcyr); + this->set_bcs(2, args.bczl, args.bczr); + } - public: + public: - static void alloc( + static void alloc( typename parent_t::mem_t *mem, const int &n_iters - ) + ) { // psi mem->psi.resize(parent_t::n_eqns); - for (int e = 0; e < parent_t::n_eqns; ++e) // equations - for (int n = 0; n < n_tlev; ++n) // time levels - mem->psi[e].push_back(mem->old(new typename parent_t::arr_t( + for (int e = 0; e < parent_t::n_eqns; ++e) // equations + for (int n = 0; n < n_tlev; ++n) // time levels + mem->psi[e].push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_sclr(mem->grid_size[2]) - ))); + ))); // Courant field components (Arakawa-C grid) - mem->GC.push_back(mem->old(new typename parent_t::arr_t( + mem->GC.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_vctr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_sclr(mem->grid_size[2]) ))); - mem->GC.push_back(mem->old(new typename parent_t::arr_t( + mem->GC.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_vctr(mem->grid_size[1]), parent_t::rng_sclr(mem->grid_size[2]) ))); - mem->GC.push_back(mem->old(new typename parent_t::arr_t( + mem->GC.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_vctr(mem->grid_size[2]) @@ -363,7 +363,7 @@ namespace libmpdataxx opts::isset(ct_params_t::opts, opts::div_3rd_dt)) { // TODO: why for (auto f : {mem->ndt_GC, mem->ndtt_GC}) doesn't work ? - mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t( + mem->ndt_GC.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_vctr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_sclr(mem->grid_size[2]) @@ -378,8 +378,8 @@ namespace libmpdataxx parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_vctr(mem->grid_size[2]) ))); - - mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t( + + mem->ndtt_GC.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_vctr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_sclr(mem->grid_size[2]) @@ -398,24 +398,24 @@ namespace libmpdataxx // allocate G if (opts::isset(ct_params_t::opts, opts::nug)) - mem->G.reset(mem->old(new typename parent_t::arr_t( + mem->G.reset(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_sclr(mem->grid_size[2]) ))); - // allocate Kahan summation temporary vars - if (opts::isset(ct_params_t::opts, opts::khn)) - for (int n = 0; n < 3; ++n) - mem->khn_tmp.push_back(mem->old(new typename parent_t::arr_t( - parent_t::rng_sclr(mem->grid_size[0]), - parent_t::rng_sclr(mem->grid_size[1]), - parent_t::rng_sclr(mem->grid_size[2]) - ))); + // allocate Kahan summation temporary vars + if (opts::isset(ct_params_t::opts, opts::khn)) + for (int n = 0; n < 3; ++n) + mem->khn_tmp.push_back(mem->old(new typename parent_t::arr_t( + parent_t::rng_sclr(mem->grid_size[0]), + parent_t::rng_sclr(mem->grid_size[1]), + parent_t::rng_sclr(mem->grid_size[2]) + ))); // courant field alloc_tmp_sclr(mem, __FILE__, 1); - } - + } + // helper method to allocate a temporary space composed of arbitrarily staggered arrays static void alloc_tmp_stgr( typename parent_t::mem_t *mem, @@ -434,10 +434,10 @@ namespace libmpdataxx srfc ? rng_t(0, 0) : stgr[n][2] ? parent_t::rng_vctr(mem->grid_size[2]) : parent_t::rng_sclr(mem->grid_size[2]) - ))); + ))); } } - + // helper method to allocate a temporary space composed of vector-component arrays static void alloc_tmp_vctr( typename parent_t::mem_t *mem, @@ -447,25 +447,25 @@ namespace libmpdataxx alloc_tmp_stgr(mem, __file__, 3, {{true, false, false}, {false, true, false}, {false, false, true}}); } - // helper method to allocate n_arr scalar temporary arrays + // helper method to allocate n_arr scalar temporary arrays static void alloc_tmp_sclr( typename parent_t::mem_t *mem, const char * __file__, const int n_arr, std::string name = "", bool srfc = false // allocate only surface data - ) - { + ) + { mem->tmp[__file__].push_back(new arrvec_t()); if (!name.empty()) mem->avail_tmp[name] = std::make_pair(__file__, mem->tmp[__file__].size() - 1); for (int n = 0; n < n_arr; ++n) - mem->tmp[__file__].back().push_back(mem->old(new typename parent_t::arr_t( + mem->tmp[__file__].back().push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]), srfc ? rng_t(0, 0) : parent_t::rng_sclr(mem->grid_size[2]) ))); - } + } }; } // namespace detail } // namespace solvers diff --git a/libmpdata++/solvers/detail/solver_common.hpp b/libmpdata++/solvers/detail/solver_common.hpp index b75dc174..c70cb54e 100644 --- a/libmpdata++/solvers/detail/solver_common.hpp +++ b/libmpdata++/solvers/detail/solver_common.hpp @@ -32,13 +32,13 @@ namespace libmpdataxx template class solver_common { - public: + public: enum { n_eqns = ct_params_t::n_eqns }; - enum { halo = minhalo }; + enum { halo = minhalo }; enum { n_dims = ct_params_t::n_dims }; enum { n_tlev = n_tlev_ }; - + using ct_params_t_ = ct_params_t; // propagate ct_params_t mainly for output purposes using real_t = typename ct_params_t::real_t; typedef blitz::Array arr_t; @@ -49,7 +49,7 @@ namespace libmpdataxx using advance_arg_t = typename std::conditional::type; - protected: + protected: // TODO: output common doesnt know about ct_params_t static constexpr bool var_dt = ct_params_t::var_dt; @@ -66,19 +66,19 @@ namespace libmpdataxx std::array dt_stash; std::array dijk; - const idx_t ijk; + const idx_t ijk; long long int timestep = 0; real_t time = 0; - std::vector n; + std::vector n; - typedef concurr::detail::sharedmem mem_t; - mem_t *mem; + typedef concurr::detail::sharedmem mem_t; + mem_t *mem; - // helper methods invoked by solve() - virtual void advop(int e) = 0; + // helper methods invoked by solve() + virtual void advop(int e) = 0; - // helper method telling us if equation e is the last one advected assuming increasing order, + // helper method telling us if equation e is the last one advected assuming increasing order, // but taking into account possible delay of advection of some equations // and assuming that is_last_eqn is not called for delayed equations before it's called for non-delayed equations constexpr bool is_last_eqn(int e) @@ -88,13 +88,13 @@ namespace libmpdataxx (e == opts::most_significant(ct_params_t::delayed_step)-1); // last of the delayed equations } - virtual void cycle(int e) final - { - n[e] = (n[e] + 1) % n_tlev - n_tlev; // -n_tlev so that n+1 does not give out of bounds - if(is_last_eqn(e)) mem->cycle(rank); - } + virtual void cycle(int e) final + { + n[e] = (n[e] + 1) % n_tlev - n_tlev; // -n_tlev so that n+1 does not give out of bounds + if(is_last_eqn(e)) mem->cycle(rank); + } - virtual void xchng(int e) = 0; + virtual void xchng(int e) = 0; // TODO: implement flagging of valid/invalid halo for optimisations virtual void xchng_vctr_alng(arrvec_t&, const bool ad = false, const bool cyclic = false) = 0; @@ -103,20 +103,20 @@ namespace libmpdataxx { // with distributed memory and cyclic boundary conditions, // leftmost node must send left first, as - // rightmost node is waiting - if (d == 0 && this->mem->distmem.size() > 0 && this->mem->distmem.rank() == 0) - std::swap(bcl, bcr); + // rightmost node is waiting + if (d == 0 && this->mem->distmem.size() > 0 && this->mem->distmem.rank() == 0) + std::swap(bcl, bcr); bcs[d][0] = std::move(bcl); bcs[d][1] = std::move(bcr); } - virtual real_t courant_number(const arrvec_t&) = 0; - virtual real_t max_abs_vctr_div(const arrvec_t&) = 0; - + virtual real_t courant_number(const arrvec_t&) = 0; + virtual real_t max_abs_vctr_div(const arrvec_t&) = 0; + // return false if advector does not change in time virtual bool calc_gc() {return false;} - + // used to calculate nondimensionalised first and second time derivatives of advector virtual void calc_ndt_gc() {} @@ -125,11 +125,11 @@ namespace libmpdataxx void solve_loop_body(const int e) { scale(e, ct_params_t::hint_scale(e)); - xchng(e); + xchng(e); advop(e); if(!is_last_eqn(e)) mem->barrier(); - cycle(e); // note: assuming ascending order, mem->cycle is done after the lest eqn + cycle(e); // note: assuming ascending order, mem->cycle is done after the lest eqn scale(e, -ct_params_t::hint_scale(e)); } @@ -142,7 +142,7 @@ namespace libmpdataxx rank == mem->size - 1 ? rng_t(r.first(), (r + n).last()) : r; } - + // thread-aware range extension, variadic version template rng_t extend_range(const rng_t &r, const n_t n, const ns_t... ns) const @@ -151,49 +151,49 @@ namespace libmpdataxx } private: - + #if !defined(NDEBUG) - bool - hook_ante_step_called = true, // initially true to handle nt=0 - hook_ante_delayed_step_called = true, - hook_post_step_called = true, + bool + hook_ante_step_called = true, // initially true to handle nt=0 + hook_ante_delayed_step_called = true, + hook_post_step_called = true, hook_ante_loop_called = true; #endif protected: - virtual void hook_ante_step() - { + virtual void hook_ante_step() + { // sanity check if all subclasses call their parents' hooks #if !defined(NDEBUG) hook_ante_step_called = true; #endif } - virtual void hook_ante_delayed_step() - { + virtual void hook_ante_delayed_step() + { // sanity check if all subclasses call their parents' hooks #if !defined(NDEBUG) hook_ante_delayed_step_called = true; #endif } - virtual void hook_post_step() + virtual void hook_post_step() { #if !defined(NDEBUG) hook_post_step_called = true; #endif } - virtual void hook_ante_loop(const advance_arg_t nt) + virtual void hook_ante_loop(const advance_arg_t nt) { #if !defined(NDEBUG) hook_ante_loop_called = true; #endif // fill halos in velocity field this->xchng_vctr_alng(mem->GC); - + // adaptive timestepping - for constant in time velocity it suffices // to change the timestep once and do a simple scaling of advector if (ct_params_t::var_dt) @@ -208,24 +208,24 @@ namespace libmpdataxx } } - public: + public: const real_t time_() const { return time;} - struct rt_params_t + struct rt_params_t { std::array grid_size; real_t dt=0, max_abs_div_eps = blitz::epsilon(real_t(44)), max_courant = real_t(0.5); }; - // ctor - solver_common( - const int &rank, - mem_t *mem, - const rt_params_t &p, + // ctor + solver_common( + const int &rank, + mem_t *mem, + const rt_params_t &p, const decltype(ijk) &ijk ) : - rank(rank), + rank(rank), dt_stash{}, dt(p.dt), di(0), @@ -233,16 +233,16 @@ namespace libmpdataxx dk(0), max_abs_div_eps(p.max_abs_div_eps), max_courant(p.max_courant), - n(n_eqns, 0), + n(n_eqns, 0), mem(mem), ijk(ijk) - { + { // compile-time sanity checks - static_assert(n_eqns > 0, "!"); + static_assert(n_eqns > 0, "!"); // run-time sanity checks for (int d = 0; d < n_dims; ++d) - if (p.grid_size[d] < 1) + if (p.grid_size[d] < 1) throw std::runtime_error("bogus grid size"); } @@ -252,55 +252,55 @@ namespace libmpdataxx #if defined(USE_MPI) // finalize mpi if it was initialized by distmem, // otherwise it would break programs that instantiate many solvers; - // TODO: MPI standard requires that the same thread that called mpi_init + // TODO: MPI standard requires that the same thread that called mpi_init // calls mpi_finalize, we don't ensure it - if(!libmpdataxx::concurr::detail::mpi_initialized_before && rank==0) + if(!libmpdataxx::concurr::detail::mpi_initialized_before && rank==0) MPI::Finalize(); #endif #if !defined(NDEBUG) - assert(hook_ante_step_called && "any overriding hook_ante_step() must call parent_t::hook_ante_step()"); - assert(hook_post_step_called && "any overriding hook_post_step() must call parent_t::hook_post_step()"); - assert(hook_ante_loop_called && "any overriding hook_ante_loop() must call parent_t::hook_ante_loop()"); - assert(hook_ante_delayed_step_called && "any overriding hook_ante_delayed_step() must call parent_t::hook_ante_delayed_step()"); + assert(hook_ante_step_called && "any overriding hook_ante_step() must call parent_t::hook_ante_step()"); + assert(hook_post_step_called && "any overriding hook_post_step() must call parent_t::hook_post_step()"); + assert(hook_ante_loop_called && "any overriding hook_ante_loop() must call parent_t::hook_ante_loop()"); + assert(hook_ante_delayed_step_called && "any overriding hook_ante_delayed_step() must call parent_t::hook_ante_delayed_step()"); #endif } - virtual void solve(advance_arg_t nt) final - { + virtual void solve(advance_arg_t nt) final + { // multiple calls to sovlve() are meant to advance the solution by nt // TODO: does it really work with var_dt ? we do not advance by time exactly ... nt += ct_params_t::var_dt ? time : timestep; - // being generous about out-of-loop barriers + // being generous about out-of-loop barriers if (timestep == 0) { - mem->barrier(); + mem->barrier(); #if !defined(NDEBUG) - hook_ante_loop_called = false; + hook_ante_loop_called = false; #endif - hook_ante_loop(nt); - mem->barrier(); + hook_ante_loop(nt); + mem->barrier(); } // moved here so that if an exception is thrown from hook_ante_loop these do not cause complaints #if !defined(NDEBUG) - hook_ante_step_called = false; - hook_post_step_called = false; - hook_ante_delayed_step_called = false; + hook_ante_step_called = false; + hook_post_step_called = false; + hook_ante_delayed_step_called = false; #endif // higher-order temporal interpolation for output requires doing a few additional steps int additional_steps = ct_params_t::out_intrp_ord; - while (ct_params_t::var_dt ? (time < nt || additional_steps > 0) : timestep < nt) - { - // progress-bar info through thread name (check top -H) - monitor(float(ct_params_t::var_dt ? time : timestep) / nt); // TODO: does this value make sanse with repeated advence() calls? + while (ct_params_t::var_dt ? (time < nt || additional_steps > 0) : timestep < nt) + { + // progress-bar info through thread name (check top -H) + monitor(float(ct_params_t::var_dt ? time : timestep) / nt); // TODO: does this value make sanse with repeated advence() calls? // might be used to implement multi-threaded signal handling mem->barrier(); if (mem->panic) break; // proper solver stuff - + // for variable in time velocity calculate advector at n+1/2, returns false if // velocity does not change in time bool var_gc = calc_gc(); @@ -312,7 +312,7 @@ namespace libmpdataxx real_t cfl = courant_number(mem->GC); if (cfl > 0) { - do + do { dt *= max_courant / cfl; calc_gc(); @@ -321,14 +321,14 @@ namespace libmpdataxx while (cfl > max_courant); } } - + // once we set the time step // for third-order MPDATA we need to calculate time derivatives of the advector field if (var_gc && div3_mpdata) calc_ndt_gc(); - + hook_ante_step(); - for (int e = 0; e < n_eqns; ++e) + for (int e = 0; e < n_eqns; ++e) { if (opts::isset(ct_params_t::delayed_step, opts::bit(e))) continue; solve_loop_body(e); @@ -336,7 +336,7 @@ namespace libmpdataxx hook_ante_delayed_step(); - for (int e = 0; e < n_eqns; ++e) + for (int e = 0; e < n_eqns; ++e) { if (!opts::isset(ct_params_t::delayed_step, opts::bit(e))) continue; solve_loop_body(e); @@ -349,7 +349,7 @@ namespace libmpdataxx hook_post_step(); if (time >= nt) additional_steps--; - } + } mem->barrier(); // note: hook_post_loop was removed as conficling with multiple-advance()-call logic @@ -357,13 +357,13 @@ namespace libmpdataxx protected: - // psi[n] getter - just to shorten the code - // note that e.g. in hook_post_loop it points rather to + // psi[n] getter - just to shorten the code + // note that e.g. in hook_post_loop it points rather to // psi^{n+1} than psi^{n} (hence not using the name psi_n) - virtual arr_t &state(const int &e) final - { - return mem->psi[e][n[e]]; - } + virtual arr_t &state(const int &e) final + { + return mem->psi[e][n[e]]; + } static rng_t rng_vctr(const rng_t &rng) { return rng^h^(halo-1); } static rng_t rng_sclr(const rng_t &rng) { return rng^halo; } @@ -379,7 +379,7 @@ namespace libmpdataxx template class solver - {}; + {}; } // namespace detail } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/mpdata.hpp b/libmpdata++/solvers/mpdata.hpp index aec7b161..1e19bde3 100644 --- a/libmpdata++/solvers/mpdata.hpp +++ b/libmpdata++/solvers/mpdata.hpp @@ -6,13 +6,13 @@ #pragma once -#include -#include -#include +#include +#include +#include -#include -#include -#include +#include +#include +#include namespace libmpdataxx { @@ -21,18 +21,18 @@ namespace libmpdataxx struct mpdata_family_tag {}; // the mpdata class - template + template class mpdata {}; // oscillatory version template class mpdata< - ct_params_t, minhalo, + ct_params_t, minhalo, typename std::enable_if::type > : public detail::mpdata_osc { - using parent_t = detail::mpdata_osc; + using parent_t = detail::mpdata_osc; using parent_t::parent_t; // inheriting constructors protected: @@ -46,9 +46,9 @@ namespace libmpdataxx typename std::enable_if::type > : public detail::mpdata_fct { - using parent_t = detail::mpdata_fct; + using parent_t = detail::mpdata_fct; using parent_t::parent_t; // inheriting constructors - + protected: using solver_family = mpdata_family_tag; }; diff --git a/libmpdata++/solvers/mpdata_rhs.hpp b/libmpdata++/solvers/mpdata_rhs.hpp index 4af3f67d..351d7c43 100644 --- a/libmpdata++/solvers/mpdata_rhs.hpp +++ b/libmpdata++/solvers/mpdata_rhs.hpp @@ -1,10 +1,10 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) * - * @brief improved Euler inhomogeneous solver + * @brief improved Euler inhomogeneous solver * (cf. eq. 32 in Smolarkiewicz 1998) // TODO cite */ @@ -16,11 +16,11 @@ namespace libmpdataxx { namespace solvers { - enum rhs_scheme_t - { + enum rhs_scheme_t + { euler_a, // Euler's method, Eulerian spirit: psi^n+1 = ADV(psi^n) + R^n euler_b, // Euler's method, semi-Lagrangian spirit: psi^n+1 = ADV(psi^n + R^n) - trapez, // paraphrase of trapezoidal rule: psi^n+1 = ADV(psi^n + 1/2 * R^n) + 1/2 * R^n+1 + trapez, // paraphrase of trapezoidal rule: psi^n+1 = ADV(psi^n + 1/2 * R^n) + 1/2 * R^n+1 mixed // allows implementation of arbitrary mixed explicit/implicit schemes }; @@ -30,7 +30,7 @@ namespace libmpdataxx {trapez , "trapez" }, {mixed , "mixed" } }; - + struct mpdata_rhs_family_tag {}; template @@ -51,17 +51,17 @@ namespace libmpdataxx arrvec_t &rhs; virtual void update_rhs( - arrvec_t &rhs, + arrvec_t &rhs, const typename parent_t::real_t &dt, const int &at - ) + ) { assert(at == n || at == n+1); #if !defined(NDEBUG) update_rhs_called = true; #endif // zero-out all rhs arrays - for (int e = 0; e < parent_t::n_eqns; ++e) + for (int e = 0; e < parent_t::n_eqns; ++e) { // do nothing for equations with no rhs if (opts::isset(ct_params_t::hint_norhs, opts::bit(e))) continue; @@ -78,7 +78,7 @@ namespace libmpdataxx const typename parent_t::real_t &dt_arg ) final { - for (int e = 0; e < parent_t::n_eqns; ++e) + for (int e = 0; e < parent_t::n_eqns; ++e) { // do nothing for equations with no rhs if (opts::isset(ct_params_t::hint_norhs, opts::bit(e))) continue; @@ -89,13 +89,13 @@ namespace libmpdataxx } public: - + // ctor mpdata_rhs( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p ) : - parent_t(args, p), + parent_t(args, p), rhs(args.mem->tmp[__FILE__][0]) { assert(this->dt != 0); @@ -130,8 +130,8 @@ namespace libmpdataxx switch ((rhs_scheme_t)ct_params_t::rhs_scheme) { - case rhs_scheme_t::euler_a: - case rhs_scheme_t::euler_b: + case rhs_scheme_t::euler_a: + case rhs_scheme_t::euler_b: break; case rhs_scheme_t::trapez: update_rhs(rhs, this->dt / 2, n); @@ -139,7 +139,7 @@ namespace libmpdataxx case rhs_scheme_t::mixed: hook_mixed_rhs_ante_loop(); break; - default: + default: assert(false); } } @@ -154,20 +154,20 @@ namespace libmpdataxx switch ((rhs_scheme_t)ct_params_t::rhs_scheme) { - case rhs_scheme_t::euler_a: + case rhs_scheme_t::euler_a: update_rhs(rhs, this->dt, n); break; - case rhs_scheme_t::euler_b: + case rhs_scheme_t::euler_b: update_rhs(rhs, this->dt, n); - apply_rhs(this->dt); + apply_rhs(this->dt); break; - case rhs_scheme_t::trapez: - apply_rhs(this->dt / 2); + case rhs_scheme_t::trapez: + apply_rhs(this->dt / 2); break; - case rhs_scheme_t::mixed: + case rhs_scheme_t::mixed: hook_mixed_rhs_ante_step(); break; - default: + default: assert(false); } } @@ -177,29 +177,29 @@ namespace libmpdataxx parent_t::hook_post_step(); switch ((rhs_scheme_t)ct_params_t::rhs_scheme) { - case rhs_scheme_t::euler_a: + case rhs_scheme_t::euler_a: apply_rhs(this->dt); break; - case rhs_scheme_t::euler_b: + case rhs_scheme_t::euler_b: break; - case rhs_scheme_t::trapez: + case rhs_scheme_t::trapez: update_rhs(rhs, this->dt / 2, n+1); apply_rhs(this->dt / 2); break; - case rhs_scheme_t::mixed: + case rhs_scheme_t::mixed: hook_mixed_rhs_post_step(); break; default: assert(false); } - } + } static void alloc( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const int &n_iters ) { // TODO: optimise to skip allocs for equations with no rhs - parent_t::alloc(mem, n_iters); + parent_t::alloc(mem, n_iters); parent_t::alloc_tmp_sclr(mem, __FILE__, parent_t::n_eqns); // rhs array for each equation } }; diff --git a/libmpdata++/solvers/mpdata_rhs_vip.hpp b/libmpdata++/solvers/mpdata_rhs_vip.hpp index e363a775..a037049e 100644 --- a/libmpdata++/solvers/mpdata_rhs_vip.hpp +++ b/libmpdata++/solvers/mpdata_rhs_vip.hpp @@ -1,4 +1,4 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE @@ -16,11 +16,11 @@ namespace libmpdataxx // to be specialised template - class mpdata_rhs_vip + class mpdata_rhs_vip {}; // 1D version - template + template class mpdata_rhs_vip< ct_params_t, minhalo, typename std::enable_if::type @@ -42,44 +42,44 @@ namespace libmpdataxx using namespace libmpdataxx::arakawa_c; using real_t = typename ct_params_t::real_t; - if (!this->mem->G) - { - dst[0](im + h) = this->dt / this->di * real_t(.5) * ( - src[0](im ) + - src[0](im + 1) - ); - } - else - { - assert(false); // TODO: and if G is not const... - } + if (!this->mem->G) + { + dst[0](im + h) = this->dt / this->di * real_t(.5) * ( + src[0](im ) + + src[0](im + 1) + ); + } + else + { + assert(false); // TODO: and if G is not const... + } this->xchng_vctr_alng(dst, /*ad*/ false, /*cyclic*/ true); } void extrapolate_in_time() final { - this->extrp(0, ix::vip_i); - this->xchng_sclr(this->vip_stash(0)[0]); // filling halos + this->extrp(0, ix::vip_i); + this->xchng_sclr(this->vip_stash(0)[0]); // filling halos } public: // ctor mpdata_rhs_vip( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p - ) : - parent_t(args, p), - im(args.i.first() - 1, args.i.last()) + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p + ) : + parent_t(args, p), + im(args.i.first() - 1, args.i.last()) { assert(this->di != 0); this->vip_ixs = {ix::vip_i}; - } + } }; // 2D version - template + template class mpdata_rhs_vip< ct_params_t, minhalo, typename std::enable_if::type @@ -95,81 +95,81 @@ namespace libmpdataxx // member fields const rng_t im, jm; - template + template void intrp( - arr_t &dst, - const arr_t &src, - const rng_t &i, - const rng_t &j, - const typename ct_params_t::real_t &di + arr_t &dst, + const arr_t &src, + const rng_t &i, + const rng_t &j, + const typename ct_params_t::real_t &di ) - { - using idxperm::pi; - using namespace arakawa_c; + { + using idxperm::pi; + using namespace arakawa_c; using real_t = typename ct_params_t::real_t; - - if (!this->mem->G) - { - dst(pi(i+h,j)) = this->dt / di * real_t(.5) * ( - src(pi(i, j)) + - src(pi(i + 1,j)) - ); - } - else - { - dst(pi(i+h,j)) = this->dt / di * real_t(.5) * ( - (*this->mem->G)(pi(i, j)) * src(pi(i, j)) + - (*this->mem->G)(pi(i + 1,j)) * src(pi(i + 1,j)) - ); - } - } + + if (!this->mem->G) + { + dst(pi(i+h,j)) = this->dt / di * real_t(.5) * ( + src(pi(i, j)) + + src(pi(i + 1,j)) + ); + } + else + { + dst(pi(i+h,j)) = this->dt / di * real_t(.5) * ( + (*this->mem->G)(pi(i, j)) * src(pi(i, j)) + + (*this->mem->G)(pi(i + 1,j)) * src(pi(i + 1,j)) + ); + } + } void interpolate_in_space(arrvec_t &dst, const arrvec_t &src) final { using namespace arakawa_c; // for rng_t operator^ auto ex = this->halo - 1; - intrp<0>(dst[0], src[0], im^ex, this->j^ex, this->di); - intrp<1>(dst[1], src[1], jm^ex, this->i^ex, this->dj); + intrp<0>(dst[0], src[0], im^ex, this->j^ex, this->di); + intrp<1>(dst[1], src[1], jm^ex, this->i^ex, this->dj); this->xchng_vctr_alng(dst, /*ad*/ false, /*cyclic*/ true); this->xchng_vctr_nrml(dst, this->ijk, ex, /*cyclic*/ false); } void extrapolate_in_time() final { - using namespace libmpdataxx::arakawa_c; + using namespace libmpdataxx::arakawa_c; - this->extrp(0, ix::vip_i); + this->extrp(0, ix::vip_i); // using xchng_pres because bcs have to be consistent with those used in // pressure solver to obtain non-divergent advector field auto ex = this->halo - 1; - this->extrp(1, ix::vip_j); - this->xchng_pres(this->vip_stash(0)[0], this->ijk, ex); - this->xchng_pres(this->vip_stash(0)[1], this->ijk, ex); + this->extrp(1, ix::vip_j); + this->xchng_pres(this->vip_stash(0)[0], this->ijk, ex); + this->xchng_pres(this->vip_stash(0)[1], this->ijk, ex); } public: - + // ctor mpdata_rhs_vip( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p - ) : - parent_t(args, p), - im(args.i.first() - 1, args.i.last()), - jm(args.j.first() - 1, args.j.last()) + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p + ) : + parent_t(args, p), + im(args.i.first() - 1, args.i.last()), + jm(args.j.first() - 1, args.j.last()) { assert(this->di != 0); assert(this->dj != 0); - + this->vip_ixs = {ix::vip_i, ix::vip_j}; } - + static void alloc( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const int &n_iters ) { - parent_t::alloc(mem, n_iters); + parent_t::alloc(mem, n_iters); // allocate velocity absorber if (static_cast(ct_params_t::vip_vab) != 0) @@ -178,7 +178,7 @@ namespace libmpdataxx parent_t::rng_sclr(mem->grid_size[0]), parent_t::rng_sclr(mem->grid_size[1]) ))); - + for (int n = 0; n < ct_params_t::n_dims; ++n) mem->vab_relax.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), @@ -187,9 +187,9 @@ namespace libmpdataxx } } }; - + // 3D version - template + template class mpdata_rhs_vip< ct_params_t, minhalo, typename std::enable_if::type @@ -198,78 +198,78 @@ namespace libmpdataxx using ix = typename ct_params_t::ix; protected: - + using solver_family = mpdata_rhs_vip_family_tag; using parent_t = detail::mpdata_rhs_vip_common; // member fields const rng_t im, jm, km; - template + template void intrp( - arr_t &dst, - const arr_t &src, - const rng_t &i, - const rng_t &j, - const rng_t &k, - const typename ct_params_t::real_t &di + arr_t &dst, + const arr_t &src, + const rng_t &i, + const rng_t &j, + const rng_t &k, + const typename ct_params_t::real_t &di ) - { - using idxperm::pi; - using namespace arakawa_c; + { + using idxperm::pi; + using namespace arakawa_c; using real_t = typename ct_params_t::real_t; - - if (!this->mem->G) - { - dst(pi(i+h, j, k)) = this->dt / di * real_t(.5) * ( - src(pi(i, j, k)) + - src(pi(i + 1, j, k)) - ); - } - else - { - dst(pi(i+h, j, k)) = this->dt / di * real_t(.5) * ( - (*this->mem->G)(pi(i , j, k)) * src(pi(i, j, k)) + - (*this->mem->G)(pi(i+1, j, k)) * src(pi(i+1, j, k)) - ); - } - } + + if (!this->mem->G) + { + dst(pi(i+h, j, k)) = this->dt / di * real_t(.5) * ( + src(pi(i, j, k)) + + src(pi(i + 1, j, k)) + ); + } + else + { + dst(pi(i+h, j, k)) = this->dt / di * real_t(.5) * ( + (*this->mem->G)(pi(i , j, k)) * src(pi(i, j, k)) + + (*this->mem->G)(pi(i+1, j, k)) * src(pi(i+1, j, k)) + ); + } + } void interpolate_in_space(arrvec_t &dst, const arrvec_t &src) final { using namespace arakawa_c; // for rng_t operator^ auto ex = this->halo - 1; - intrp<0>(dst[0], src[0], im^ex, this->j^ex, this->k^ex, this->di); - intrp<1>(dst[1], src[1], jm^ex, this->k^ex, this->i^ex, this->dj); - intrp<2>(dst[2], src[2], km^ex, this->i^ex, this->j^ex, this->dk); + intrp<0>(dst[0], src[0], im^ex, this->j^ex, this->k^ex, this->di); + intrp<1>(dst[1], src[1], jm^ex, this->k^ex, this->i^ex, this->dj); + intrp<2>(dst[2], src[2], km^ex, this->i^ex, this->j^ex, this->dk); this->xchng_vctr_alng(dst, /*ad*/ false, /*cyclic*/ true); this->xchng_vctr_nrml(dst, this->ijk, ex, /*cyclic*/ false); } void extrapolate_in_time() final { - using namespace libmpdataxx::arakawa_c; + using namespace libmpdataxx::arakawa_c; // using xchng_pres because bcs have to be consistent with those used in // pressure solver to obtain non-divergent advector field auto ex = this->halo - 1; - this->extrp(0, ix::vip_i); - this->extrp(1, ix::vip_j); - this->extrp(2, ix::vip_k); - this->xchng_pres(this->vip_stash(0)[0], this->ijk, ex); - this->xchng_pres(this->vip_stash(0)[1], this->ijk, ex); - this->xchng_pres(this->vip_stash(0)[2], this->ijk, ex); + this->extrp(0, ix::vip_i); + this->extrp(1, ix::vip_j); + this->extrp(2, ix::vip_k); + this->xchng_pres(this->vip_stash(0)[0], this->ijk, ex); + this->xchng_pres(this->vip_stash(0)[1], this->ijk, ex); + this->xchng_pres(this->vip_stash(0)[2], this->ijk, ex); } public: - + static void alloc( - typename parent_t::mem_t *mem, + typename parent_t::mem_t *mem, const int &n_iters - ) + ) { - parent_t::alloc(mem, n_iters); + parent_t::alloc(mem, n_iters); // allocate velocity absorber if (static_cast(ct_params_t::vip_vab) != 0) @@ -279,7 +279,7 @@ namespace libmpdataxx parent_t::rng_sclr(mem->grid_size[1]), parent_t::rng_sclr(mem->grid_size[2]) ))); - + for (int n = 0; n < ct_params_t::n_dims; ++n) mem->vab_relax.push_back(mem->old(new typename parent_t::arr_t( parent_t::rng_sclr(mem->grid_size[0]), @@ -291,20 +291,20 @@ namespace libmpdataxx // ctor mpdata_rhs_vip( - typename parent_t::ctor_args_t args, - const typename parent_t::rt_params_t &p - ) : - parent_t(args, p), - im(args.i.first() - 1, args.i.last()), - jm(args.j.first() - 1, args.j.last()), - km(args.k.first() - 1, args.k.last()) + typename parent_t::ctor_args_t args, + const typename parent_t::rt_params_t &p + ) : + parent_t(args, p), + im(args.i.first() - 1, args.i.last()), + jm(args.j.first() - 1, args.j.last()), + km(args.k.first() - 1, args.k.last()) { assert(this->di != 0); assert(this->dj != 0); assert(this->dk != 0); - + this->vip_ixs = {ix::vip_i, ix::vip_j, ix::vip_k}; - } - }; + } + }; } // namespace solvers } // namespace libmpdataxx diff --git a/libmpdata++/solvers/mpdata_rhs_vip_prs.hpp b/libmpdata++/solvers/mpdata_rhs_vip_prs.hpp index a08b6ced..52e1f9d1 100644 --- a/libmpdata++/solvers/mpdata_rhs_vip_prs.hpp +++ b/libmpdata++/solvers/mpdata_rhs_vip_prs.hpp @@ -6,16 +6,16 @@ #pragma once -#include -#include -#include +#include +#include +#include namespace libmpdataxx { namespace solvers { - enum prs_scheme_t - { + enum prs_scheme_t + { mr, // minimal residual cr, // conjugate residual gcrk, // generalized conjugate residual (restarted after k steps) @@ -32,7 +32,7 @@ namespace libmpdataxx struct mpdata_rhs_vip_prs_family_tag {}; // the mpdata class - template + template class mpdata_rhs_vip_prs { static_assert(!std::is_void::value, "please specify pressure scheme type !"); @@ -45,7 +45,7 @@ namespace libmpdataxx typename std::enable_if<(int)ct_params_t::prs_scheme == (int)mr>::type > : public detail::mpdata_rhs_vip_prs_mr { - using parent_t = detail::mpdata_rhs_vip_prs_mr; + using parent_t = detail::mpdata_rhs_vip_prs_mr; using parent_t::parent_t; // inheriting constructors protected: @@ -59,13 +59,13 @@ namespace libmpdataxx typename std::enable_if<(int)ct_params_t::prs_scheme == (int)cr>::type > : public detail::mpdata_rhs_vip_prs_gcrk { - using parent_t = detail::mpdata_rhs_vip_prs_gcrk; + using parent_t = detail::mpdata_rhs_vip_prs_gcrk; using parent_t::parent_t; // inheriting constructors - + protected: using solver_family = mpdata_rhs_vip_prs_family_tag; }; - + // generalized conjugate residual template class mpdata_rhs_vip_prs< @@ -73,9 +73,9 @@ namespace libmpdataxx typename std::enable_if<(int)ct_params_t::prs_scheme == (int)gcrk>::type > : public detail::mpdata_rhs_vip_prs_gcrk { - using parent_t = detail::mpdata_rhs_vip_prs_gcrk; + using parent_t = detail::mpdata_rhs_vip_prs_gcrk; using parent_t::parent_t; // inheriting constructors - + protected: using solver_family = mpdata_rhs_vip_prs_family_tag; }; @@ -87,9 +87,9 @@ namespace libmpdataxx typename std::enable_if<(int)ct_params_t::prs_scheme == (int)pc>::type > : public detail::mpdata_rhs_vip_prs_pc { - using parent_t = detail::mpdata_rhs_vip_prs_pc; + using parent_t = detail::mpdata_rhs_vip_prs_pc; using parent_t::parent_t; // inheriting constructors - + protected: using solver_family = mpdata_rhs_vip_prs_family_tag; }; diff --git a/libmpdata++/solvers/mpdata_rhs_vip_prs_sgs.hpp b/libmpdata++/solvers/mpdata_rhs_vip_prs_sgs.hpp index 93459cb4..fba000d7 100644 --- a/libmpdata++/solvers/mpdata_rhs_vip_prs_sgs.hpp +++ b/libmpdata++/solvers/mpdata_rhs_vip_prs_sgs.hpp @@ -33,7 +33,7 @@ namespace libmpdataxx struct mpdata_rhs_vip_prs_sgs_dns_family_tag {}; struct mpdata_rhs_vip_prs_sgs_smg_family_tag {}; - template + template class mpdata_rhs_vip_prs_sgs; template @@ -42,32 +42,32 @@ namespace libmpdataxx typename std::enable_if<(int)ct_params_t::sgs_scheme == (int)iles>::type > : public mpdata_rhs_vip_prs { - using parent_t = mpdata_rhs_vip_prs; + using parent_t = mpdata_rhs_vip_prs; using parent_t::parent_t; // inheriting constructors }; - + template class mpdata_rhs_vip_prs_sgs< ct_params_t, minhalo, typename std::enable_if<(int)ct_params_t::sgs_scheme == (int)dns>::type > : public detail::mpdata_rhs_vip_prs_sgs_dns { - using parent_t = detail::mpdata_rhs_vip_prs_sgs_dns; + using parent_t = detail::mpdata_rhs_vip_prs_sgs_dns; using parent_t::parent_t; // inheriting constructors protected: using solver_family = mpdata_rhs_vip_prs_sgs_dns_family_tag; }; - + template class mpdata_rhs_vip_prs_sgs< ct_params_t, minhalo, typename std::enable_if<(int)ct_params_t::sgs_scheme == (int)smg>::type > : public detail::mpdata_rhs_vip_prs_sgs_smg { - using parent_t = detail::mpdata_rhs_vip_prs_sgs_smg; + using parent_t = detail::mpdata_rhs_vip_prs_sgs_smg; using parent_t::parent_t; // inheriting constructors - + protected: using solver_family = mpdata_rhs_vip_prs_sgs_smg_family_tag; }; diff --git a/libmpdata++/solvers/shallow_water.hpp b/libmpdata++/solvers/shallow_water.hpp index 464f635e..84a0173b 100644 --- a/libmpdata++/solvers/shallow_water.hpp +++ b/libmpdata++/solvers/shallow_water.hpp @@ -1,11 +1,11 @@ -/** +/** * @file * @copyright University of Warsaw * @section LICENSE * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) */ -#include +#include #include /** @brief the 2D shallow-water equations system @@ -22,7 +22,7 @@ * - \f$ \eta_0(x,y) \f$ - bathymetry * - \f$ h = \eta - \eta_0 \f$ - thickness of the fluid layer * - \f$ \vec{u} = (u,v) \f$ - * - \f$ \nabla_z = (\partial_x, \partial_y) \f$ + * - \f$ \nabla_z = (\partial_x, \partial_y) \f$ * * momentum equation: * \f$ \partial_t u + u \cdot \nabla_z u = - \frac{1}{\rho} \nabla_z p \f$ @@ -36,12 +36,12 @@ * h times momentum eq. plus u times mass continuity equation: * \f$ \partial_t (uh) + \nabla_z (u \cdot uh) = -g h \nabla_z \eta \f$ */ -namespace libmpdataxx +namespace libmpdataxx { namespace solvers { template - class shallow_water + class shallow_water {}; namespace detail @@ -56,7 +56,7 @@ namespace libmpdataxx // member fields const typename ct_params_t::real_t g; - // + // void update_rhs( libmpdataxx::arrvec_t &rhs, const typename parent_t::real_t &dt, @@ -65,7 +65,7 @@ namespace libmpdataxx parent_t::update_rhs(rhs, dt, at); enum { n = 0 }; // just to make n, n+1 look nice :) assert( - this->timestep == 0 && at == n + this->timestep == 0 && at == n || this->timestep > 0 && at == n+1 ); // note: we know only how to calculate R^{n+1} @@ -76,29 +76,29 @@ namespace libmpdataxx void hook_post_step() { parent_t::hook_post_step(); - assert(min(this->state(ct_params_t::ix::h)(this->ijk)) >= 0); + assert(min(this->state(ct_params_t::ix::h)(this->ijk)) >= 0); } void hook_ante_step() { parent_t::hook_ante_step(); - assert(min(this->state(ct_params_t::ix::h)(this->ijk)) >= 0); + assert(min(this->state(ct_params_t::ix::h)(this->ijk)) >= 0); } public: // run-time parameters - struct rt_params_t : parent_t::rt_params_t - { - typename parent_t::real_t g = 9.81; // default value + struct rt_params_t : parent_t::rt_params_t + { + typename parent_t::real_t g = 9.81; // default value }; // ctor - shallow_water_common( - typename parent_t::ctor_args_t args, + shallow_water_common( + typename parent_t::ctor_args_t args, const rt_params_t &p ) : - parent_t(args, p), + parent_t(args, p), g(p.g) {} }; @@ -107,7 +107,7 @@ namespace libmpdataxx // 1D version template class shallow_water< - ct_params_t, + ct_params_t, typename std::enable_if::type > : public detail::shallow_water_common { @@ -127,17 +127,17 @@ namespace libmpdataxx parent_t::update_rhs(rhs, dt, at); - rhs.at(ix::qx)(this->i) -= - this->g - * this->state(ix::h)(this->i) - * grad(this->state(ix::h), this->i, this->di); + rhs.at(ix::qx)(this->i) -= + this->g + * this->state(ix::h)(this->i) + * grad(this->state(ix::h), this->i, this->di); } }; // 2D version template class shallow_water< - ct_params_t, + ct_params_t, typename std::enable_if::type > : public detail::shallow_water_common { @@ -155,9 +155,9 @@ namespace libmpdataxx ) { using namespace libmpdataxx::formulae::nabla; - rhs(pi(i,j)) -= this->g * this->state(ix::h)(pi(i,j)) * grad(this->state(ix::h), i, j, di); + rhs(pi(i,j)) -= this->g * this->state(ix::h)(pi(i,j)) * grad(this->state(ix::h), i, j, di); } - + /// @brief Shallow Water Equations: Momentum forcings for the X and Y coordinates void update_rhs( libmpdataxx::arrvec_t &rhs, @@ -169,7 +169,7 @@ namespace libmpdataxx // forcings_helper<0>(rhs.at(ix::qx), this->i, this->j, this->di); - forcings_helper<1>(rhs.at(ix::qy), this->j, this->i, this->dj); + forcings_helper<1>(rhs.at(ix::qy), this->j, this->i, this->dj); } }; } // namespace solvers