9tarch::logging::Log applications::exahype2::swe::FVSolver::_log(
"applications::exahype2::swe::FVSolver");
12void applications::exahype2::swe::FVSolver::initialCondition(
13 [[maybe_unused]]
double*
const NOALIAS Q,
14 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& x,
15 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& h,
16 [[maybe_unused]]
const bool gridIsConstructed
18 Q[Shortcuts::h] = 100;
21 Q[Shortcuts::b] = -100;
25void applications::exahype2::swe::FVSolver::boundaryConditions(
26 [[maybe_unused]]
const double*
const NOALIAS Qinside,
27 [[maybe_unused]]
double*
const NOALIAS Qoutside,
28 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& x,
29 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& h,
30 [[maybe_unused]]
const double t,
31 [[maybe_unused]]
const int normal
33 Qoutside[Shortcuts::h] = Qinside[Shortcuts::h];
34 Qoutside[Shortcuts::hu] = -Qinside[Shortcuts::hu];
35 Qoutside[Shortcuts::hv] = -Qinside[Shortcuts::hv];
36 Qoutside[Shortcuts::b] = Qinside[Shortcuts::b];
40::exahype2::RefinementCommand applications::exahype2::swe::FVSolver::refinementCriterion(
41 [[maybe_unused]]
const double*
const NOALIAS Q,
42 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& x,
43 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& h,
44 [[maybe_unused]]
const double t
46 auto result = ::exahype2::RefinementCommand::Keep;
52double applications::exahype2::swe::FVSolver::maxEigenvalue(
53 [[maybe_unused]]
const double*
const NOALIAS Q,
54 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& x,
55 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& h,
56 [[maybe_unused]]
const double t,
57 [[maybe_unused]]
const double dt,
58 [[maybe_unused]]
const int normal
61 L[Shortcuts::h] = 0.0;
62 L[Shortcuts::hu] = 0.0;
63 L[Shortcuts::hv] = 0.0;
65 constexpr double DRY_TOL = std::numeric_limits<double>::epsilon();
66 if (Q[Shortcuts::h] <= DRY_TOL) {
70 const double u = Q[Shortcuts::hu + normal] / Q[Shortcuts::h];
71 const double c = std::sqrt(GRAV * Q[Shortcuts::h]);
73 L[Shortcuts::hu] =
u +
c;
74 L[Shortcuts::hv] =
u -
c;
76 return std::fmax(std::fabs(L[0]), std::fmax(std::fabs(L[1]), std::fabs(L[2])));
80void applications::exahype2::swe::FVSolver::flux(
81 [[maybe_unused]]
const double*
const NOALIAS Q,
82 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& x,
83 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& h,
84 [[maybe_unused]]
const double t,
85 [[maybe_unused]]
const double dt,
86 [[maybe_unused]]
const int normal,
87 [[maybe_unused]]
double*
const NOALIAS F
89 F[Shortcuts::h] = 0.0;
90 F[Shortcuts::hu] = 0.0;
91 F[Shortcuts::hv] = 0.0;
92 F[Shortcuts::b] = 0.0;
94 constexpr double DRY_TOL = std::numeric_limits<double>::epsilon();
95 if (Q[Shortcuts::h] <= DRY_TOL) {
99 const double ih = 1.0 / Q[Shortcuts::h];
101 F[Shortcuts::h] = Q[Shortcuts::hu + normal];
102 F[Shortcuts::hu] = Q[Shortcuts::hu + normal] * Q[Shortcuts::hu] * ih;
103 F[Shortcuts::hv] = Q[Shortcuts::hu + normal] * Q[Shortcuts::hv] * ih;
104 F[Shortcuts::hu + normal] += 0.5 * GRAV * Q[Shortcuts::h] * Q[Shortcuts::h];
108void applications::exahype2::swe::FVSolver::nonconservativeProduct(
109 [[maybe_unused]]
const double*
const NOALIAS Q,
110 [[maybe_unused]]
const double*
const NOALIAS deltaQ,
111 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& x,
112 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& h,
113 [[maybe_unused]]
const double t,
114 [[maybe_unused]]
const double dt,
115 [[maybe_unused]]
const int normal,
116 [[maybe_unused]]
double*
const NOALIAS BTimesDeltaQ
118 BTimesDeltaQ[Shortcuts::h] = 0.0;
119 BTimesDeltaQ[Shortcuts::hu] = 0.0;
120 BTimesDeltaQ[Shortcuts::hv] = 0.0;
121 BTimesDeltaQ[Shortcuts::b] = 0.0;
123 constexpr double DRY_TOL = std::numeric_limits<double>::epsilon();
124 if (Q[Shortcuts::h] <= DRY_TOL) {
128 BTimesDeltaQ[Shortcuts::hu + normal] = GRAV * Q[Shortcuts::h] * (deltaQ[Shortcuts::h] + deltaQ[Shortcuts::b]);
145 auto constant([[maybe_unused]]
const auto x, [[maybe_unused]]
const auto y) {
168 auto betaPlane([[maybe_unused]]
const auto x, [[maybe_unused]]
const auto y) {
176 constexpr double f0 = 1.0e-4;
177 constexpr double beta = 2.0e-11;
179 return f0 + (beta * y);
194 auto sphere([[maybe_unused]]
const auto x, [[maybe_unused]]
const auto y) {
203 constexpr double omega = 7.2921150e-5;
204 constexpr double toRad = M_PI / 180.0;
207 const auto latRad = lat * toRad;
208 return 2.0 * omega * std::sin(latRad);
229 auto manningFriction(
const auto h,
const auto hu,
const auto hv) {
230 namespace constants = ::applications::exahype2::swe;
231 constexpr auto manningFriction = 0.025;
232 constexpr auto hMin = 0.2;
234 const auto hSafe = (h > hMin ? h : hMin);
236 const auto h43 = (hSafe * std::cbrt(hSafe));
239 return -constants::GRAV * manningFriction * manningFriction * std::sqrt((hu * hu) + (hv * hv)) / h43;
242 auto atmosphericPressure(
const auto x,
const auto y,
const auto t) {
243 namespace constants = ::applications::exahype2::swe;
244 constexpr auto aLon = constants::pointLonA;
245 constexpr auto aLat = constants::pointLatA;
247 constexpr auto bLon = constants::pointLonB;
248 constexpr auto bLat = constants::pointLatB;
251 auto pressureGaus = [](
const auto x,
const auto y) {
252 constexpr auto C = 0.5;
253 constexpr auto AL = 37.61;
254 constexpr auto AR = 4.665;
255 constexpr auto BL = 0.31;
256 constexpr auto BR = 0.5;
257 const auto y2 = ((
y / C) * (
y / C));
259 return -AL *
x * std::exp(-y2 - ((x / BL) * (x / BL)));
262 return -AR *
x * std::exp(-y2 - ((x / BR) * (x / BR)));
267 auto distanceOverTime = [](
const auto t) {
268 constexpr auto speed = 20.0;
274 auto pointOnVector = [](
const auto l) {
277 static const auto distance = std::sqrt(((bX - aX) * (bX - aX)) + ((bY - aY) * (bY - aY)));
278 return std::pair{aLon + (l * (bLon - aLon) / distance), aLat + (l * (bLat - aLat) / distance)};
283 auto rotLonLat = [](
const auto lon,
const auto lat) {
284 constexpr auto dLon = bLon - aLon;
285 constexpr auto dLat = bLat - aLat;
287 static const auto rad = std::atan2(dLat, dLon);
289 static const auto sin = std::sin(rad);
290 static const auto cos = std::cos(rad);
292 const auto lonNew = (lon * cos) + (lat * sin);
293 const auto latNew = (-lon * sin) + (lat * cos);
294 return std::pair{lonNew, latNew};
297 const auto distance = distanceOverTime(t);
299 const auto [lonCenter, latCenter] = pointOnVector(distance);
300 const auto [lonRot, latRot] = rotLonLat(lon - lonCenter, lat - latCenter);
301 return pressureGaus(lonRot, latRot);
305void applications::exahype2::swe::FVSolver::sourceTerm(
306 [[maybe_unused]]
const double*
const NOALIAS Q,
307 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& x,
308 [[maybe_unused]]
const tarch::la::Vector<DIMENSIONS, double>& h,
309 [[maybe_unused]]
const double t,
310 [[maybe_unused]]
const double dt,
311 [[maybe_unused]]
double*
const NOALIAS S
313 namespace constants = ::applications::exahype2::swe;
323 S[Shortcuts::hu] = 0;
324 S[Shortcuts::hv] = 0;
327 constexpr double DRY_TOL = std::numeric_limits<double>::epsilon();
328 if (Q[Shortcuts::h] <= DRY_TOL) {
339 constexpr auto waterDensity = constants::waterDensity;
341 const auto xCoord =
x(0);
342 const auto yCoord =
x(1);
344 const auto uVel = Q[Shortcuts::hu] / Q[Shortcuts::h];
345 const auto vVel = Q[Shortcuts::hv] / Q[Shortcuts::h];
348 S[Shortcuts::hu] = corriolis_force::sphere(xCoord, yCoord) * uVel;
349 S[Shortcuts::hv] = -corriolis_force::sphere(xCoord, yCoord) * vVel;
351 S[Shortcuts::hu] += manningFriction(Q[Shortcuts::h], Q[Shortcuts::hu], Q[Shortcuts::hv]) * Q[Shortcuts::hu];
352 S[Shortcuts::hv] += manningFriction(Q[Shortcuts::h], Q[Shortcuts::hu], Q[Shortcuts::hv]) * Q[Shortcuts::hv];
354 auto wrapperAtmosphericPressure = [](
const auto x,
const auto y,
const auto t) {
355 return atmosphericPressure(x, y, t);
359 partialX(wrapperAtmosphericPressure, xCoord, yCoord, t)
362 partialY(wrapperAtmosphericPressure, xCoord, yCoord, t)
auto partialY(auto f, const auto x, const auto y, const auto t)
Approximates the partial derivative ∂f/∂y of a function f(x, y, t) using central differences.
auto partialX(auto f, const auto x, const auto y, const auto t)
Approximates the partial derivative ∂f/∂x of a function f(x, y, t) using central differences.
auto inverse(const auto x, const auto y)
Inverts the Albers Equal-Area Conic projection for WGS_1984 and returns the geographic coordinates (l...
auto forward(const auto lon, const auto lat)