|
| 1 | +/* |
| 2 | + * @file |
| 3 | + * @copyright University of Warsaw |
| 4 | + * @section LICENSE |
| 5 | + * GPLv3+ (see the COPYING file or http://www.gnu.org/licenses/) |
| 6 | + */ |
| 7 | + |
| 8 | +#include <cmath> |
| 9 | +#include <boost/math/constants/constants.hpp> |
| 10 | + |
| 11 | +#include <libmpdata++/solvers/mpdata.hpp> |
| 12 | +#include <libmpdata++/concurr/threads.hpp> |
| 13 | +#include <libmpdata++/output/hdf5_xdmf.hpp> |
| 14 | + |
| 15 | +#include "gmd_2012.hpp" |
| 16 | + |
| 17 | +using namespace libmpdataxx; |
| 18 | + |
| 19 | +struct ct_test_params_t |
| 20 | +{ |
| 21 | + // choosing non-dimensional sphere radius and evolution period |
| 22 | + static constexpr ::T |
| 23 | + R = 1, |
| 24 | + T = 5; |
| 25 | +}; |
| 26 | +// to make refering to compile time test params easier |
| 27 | +using tp = ct_test_params_t; |
| 28 | + |
| 29 | +// gaussian hills initial condition |
| 30 | +struct gauss_t |
| 31 | +{ |
| 32 | + T x0, y0; |
| 33 | + static constexpr T b = 5, hmax = 0.95; |
| 34 | + T xc(const T x, const T y) const { return tp::R * std::cos(y) * std::cos(x); } |
| 35 | + T yc(const T x, const T y) const { return tp::R * std::cos(y) * std::sin(x); } |
| 36 | + T zc(const T x, const T y) const { return tp::R * std::sin(y); } |
| 37 | + |
| 38 | + T operator()(const T x, const T y) const |
| 39 | + { |
| 40 | + return hmax * std::exp(-b * ( std::pow(xc(x, y) - xc(x0, y0), 2) |
| 41 | + + std::pow(yc(x, y) - yc(x0, y0), 2) |
| 42 | + + std::pow(zc(x, y) - zc(x0, y0), 2))); |
| 43 | + } |
| 44 | + BZ_DECLARE_FUNCTOR2(gauss_t); |
| 45 | +}; |
| 46 | + |
| 47 | +// cosine bells initial condition |
| 48 | +struct bells_t |
| 49 | +{ |
| 50 | + T x0, y0; |
| 51 | + static constexpr T r = tp::R / 2, hmax = 1.0, c = 0.9; |
| 52 | + T operator()(const T x, const T y) const |
| 53 | + { |
| 54 | + T ri = tp::R * std::acos(std::sin(y0) * std::sin(y) + std::cos(y0) * std::cos(y) * std::cos(x - x0)); |
| 55 | + return ri < r ? c * hmax / 2 * (1 + std::cos(pi * ri / r)) : 0; |
| 56 | + } |
| 57 | + BZ_DECLARE_FUNCTOR2(bells_t); |
| 58 | +}; |
| 59 | + |
| 60 | +// slotted cylinders initial condition |
| 61 | +struct scyls_t |
| 62 | +{ |
| 63 | + T x0, y0; |
| 64 | + bool flip; |
| 65 | + static constexpr T r = tp::R / 2, c = 1.0; |
| 66 | + T operator()(const T x, const T y) const |
| 67 | + { |
| 68 | + T ri = tp::R * std::acos(std::sin(y0) * std::sin(y) + std::cos(y0) * std::cos(y) * std::cos(x - x0)); |
| 69 | + bool cond1 = ri < r && std::abs(x - x0) >= r / (6 * tp::R); |
| 70 | + bool cond2 = flip ? (y - y0) < -5. / 12 * r / tp::R : (y - y0) > 5. / 12 * r / tp::R; |
| 71 | + bool cond3 = ri < r && (std::abs(x - x0) < r / (6 * tp::R) && cond2); |
| 72 | + |
| 73 | + return cond1 || cond3 ? c : 0; |
| 74 | + } |
| 75 | + BZ_DECLARE_FUNCTOR2(scyls_t); |
| 76 | +}; |
| 77 | + |
| 78 | +template <bool var_dt_arg, int opts_arg, int opts_iters> |
| 79 | +void test(const std::string &base_name, const int ny, const T max_cfl) |
| 80 | +{ |
| 81 | + auto dir_name = base_name + "_" + std::to_string(ny); |
| 82 | + std::cout << "Calculating: " << dir_name << std::endl; |
| 83 | + |
| 84 | + struct ct_params_t : ct_params_default_t |
| 85 | + { |
| 86 | + using real_t = double; |
| 87 | + enum { var_dt = var_dt_arg }; |
| 88 | + enum { n_dims = 2 }; |
| 89 | + enum { n_eqns = 4 }; |
| 90 | + enum { opts = opts_arg }; |
| 91 | + }; |
| 92 | + |
| 93 | + |
| 94 | + const int nx = 2 * ny + 1; |
| 95 | + const T dx = 2 * pi / (nx - 1), dy = pi / ny; |
| 96 | + const T time = tp::T; |
| 97 | + const T dt = dx / (48 * 2 * pi); |
| 98 | + const int nt = time / dt; |
| 99 | + |
| 100 | + using slv_out_t = |
| 101 | + output::hdf5_xdmf< |
| 102 | + gmd_2012<ct_params_t, ct_test_params_t> |
| 103 | + >; |
| 104 | + typename slv_out_t::rt_params_t p; |
| 105 | + |
| 106 | + p.n_iters = opts_iters; |
| 107 | + p.grid_size = {nx, ny}; |
| 108 | + p.dt = dt; |
| 109 | + p.di = dx; |
| 110 | + p.dj = dy; |
| 111 | + p.max_courant = max_cfl; |
| 112 | + |
| 113 | + p.outfreq = var_dt_arg ? tp::T / 2 : nt / 2; |
| 114 | + p.outvars[0].name = "gh"; |
| 115 | + p.outvars[1].name = "cb"; |
| 116 | + p.outvars[2].name = "sc"; |
| 117 | + p.outvars[3].name = "ccb"; |
| 118 | + p.outdir = dir_name; |
| 119 | + |
| 120 | + concurr::threads< |
| 121 | + slv_out_t, |
| 122 | + bcond::cyclic, bcond::cyclic, |
| 123 | + bcond::polar, bcond::polar |
| 124 | + > run(p); |
| 125 | + |
| 126 | + blitz::firstIndex i; |
| 127 | + blitz::secondIndex j; |
| 128 | + |
| 129 | + // coordinates |
| 130 | + decltype(run.advectee()) X(run.advectee().extent()), Y(run.advectee().extent()); |
| 131 | + X = i * dx; |
| 132 | + Y = (j + 0.5) * dy - pi / 2; |
| 133 | + |
| 134 | + std::array<T, 2> x0s = {5 * pi / 6, 7 * pi / 6}; |
| 135 | + std::array<T, 2> y0s = {0, 0}; |
| 136 | + |
| 137 | + // initial conditions |
| 138 | + const T b = 0.1; |
| 139 | + run.advectee(0) = 0; |
| 140 | + run.advectee(1) = b; |
| 141 | + run.advectee(2) = b; |
| 142 | + |
| 143 | + for (int m = 0; m < 2; ++m) |
| 144 | + { |
| 145 | + run.advectee(0) += gauss_t{x0s[m], y0s[m]}(X, Y); |
| 146 | + run.advectee(1) += bells_t{x0s[m], y0s[m]}(X, Y); |
| 147 | + run.advectee(2) += scyls_t{x0s[m], y0s[m], m > 0}(X, Y); |
| 148 | + } |
| 149 | + run.advectee(3) = -0.8 * blitz::pow(run.advectee(1), 2) + 0.9; |
| 150 | + run.g_factor() = tp::R * blitz::cos(Y) * dx * dy; |
| 151 | + |
| 152 | + // to avoid divergence check |
| 153 | + run.advector(0) = 0; |
| 154 | + run.advector(1) = 0; |
| 155 | + |
| 156 | + // integration |
| 157 | + run.advance(var_dt_arg ? time : nt); |
| 158 | +} |
| 159 | + |
| 160 | +int main() |
| 161 | +{ |
| 162 | + const bool var_dt = true; |
| 163 | + const T max_cfl = 0.90; |
| 164 | + |
| 165 | + std::vector<int> nys = {120, 240}; |
| 166 | + { |
| 167 | + enum { opts = opts::nug}; |
| 168 | + const int opts_iters = 2; |
| 169 | + for (const auto ny : nys) test<var_dt, opts, opts_iters>("nug_i2", ny, max_cfl); |
| 170 | + } |
| 171 | + |
| 172 | + { |
| 173 | + enum { opts = opts::nug | opts::iga | opts::fct}; |
| 174 | + const int opts_iters = 2; |
| 175 | + for (const auto ny : nys) test<var_dt, opts, opts_iters>("nug_iga_fct_i2", ny, max_cfl); |
| 176 | + } |
| 177 | +} |
0 commit comments