Gyselalib++
 
Loading...
Searching...
No Matches
bsl_advection_rp.hpp
1// SPDX-License-Identifier: MIT
2
3#pragma once
4#include <sll/mapping/metric_tensor.hpp>
5
6#include "advection_domain.hpp"
7#include "ddc_alias_inline_functions.hpp"
8#include "ddc_aliases.hpp"
9#include "directional_tag.hpp"
10#include "geometry.hpp"
11#include "i_interpolator_2d_rp.hpp"
12#include "iadvectionrp.hpp"
13#include "spline_foot_finder.hpp"
14#include "spline_interpolator_2d_rp.hpp"
15#include "vector_field.hpp"
16#include "vector_field_mem.hpp"
17
18
19
57template <class FootFinder, class Mapping>
59{
60private:
62
63 FootFinder const& m_find_feet;
64
65 Mapping const& m_mapping;
66
67
68public:
86 function_interpolator,
87 FootFinder const& foot_finder,
88 Mapping const& mapping)
89 : m_interpolator(function_interpolator)
90 , m_find_feet(foot_finder)
91 , m_mapping(mapping)
92 {
93 }
94
95 ~BslAdvectionRTheta() override = default;
96
97
111 host_t<DFieldRTheta> operator()(
112 host_t<DFieldRTheta> allfdistribu,
113 host_t<DConstVectorFieldRTheta<X, Y>> advection_field_xy,
114 double dt) const override
115 {
116 // Pre-allocate some memory to prevent allocation later in loop
117 std::unique_ptr<IInterpolatorRTheta> const interpolator_ptr = m_interpolator.preallocate();
118
119 // Initialise the feet
120 host_t<FieldMemRTheta<CoordRTheta>> feet_rp(get_idx_range(advection_field_xy));
121 ddc::for_each(get_idx_range(advection_field_xy), [&](IdxRTheta const irp) {
122 feet_rp(irp) = ddc::coordinate(irp);
123 });
124
125 // Compute the characteristic feet at tn ----------------------------------------------------
126 m_find_feet(get_field(feet_rp), advection_field_xy, dt);
127
128 // Interpolate the function on the characteristic feet. -------------------------------------
129 (*interpolator_ptr)(allfdistribu, get_const_field(feet_rp));
130
131 return allfdistribu;
132 }
133
134
151 host_t<DFieldRTheta> operator()(
152 host_t<DFieldRTheta> allfdistribu,
153 host_t<DConstVectorFieldRTheta<R, Theta>> advection_field_rp,
154 CoordXY const& advection_field_xy_center,
155 double dt) const override
156 {
157 Kokkos::Profiling::pushRegion("PolarAdvection");
158 IdxRangeRTheta grid(get_idx_range<GridR, GridTheta>(allfdistribu));
159
160 const int npoints_p = IdxRangeTheta(grid).size();
161 IdxRangeRTheta const grid_without_Opoint(grid.remove_first(IdxStepRTheta(1, 0)));
162 IdxRangeRTheta const Opoint_grid(grid.take_first(IdxStepRTheta(1, npoints_p)));
163
164
165 // Convert advection field on RTheta to advection field on XY
166 host_t<DVectorFieldMemRTheta<X, Y>> advection_field_xy(grid);
167
168 MetricTensor<Mapping, CoordRTheta> metric_tensor(m_mapping);
169
170 ddc::for_each(grid_without_Opoint, [&](IdxRTheta const irp) {
171 CoordRTheta const coord_rp(ddc::coordinate(irp));
172
173 std::array<std::array<double, 2>, 2> J; // Jacobian matrix
174 m_mapping.jacobian_matrix(coord_rp, J);
175 std::array<std::array<double, 2>, 2> G; // Metric tensor
176 metric_tensor(G, coord_rp);
177
178 ddcHelper::get<X>(advection_field_xy)(irp)
179 = ddcHelper::get<R>(advection_field_rp)(irp) * J[1][1] / std::sqrt(G[1][1])
180 + ddcHelper::get<Theta>(advection_field_rp)(irp) * -J[1][0]
181 / std::sqrt(G[0][0]);
182 ddcHelper::get<Y>(advection_field_xy)(irp)
183 = ddcHelper::get<R>(advection_field_rp)(irp) * -J[0][1] / std::sqrt(G[1][1])
184 + ddcHelper::get<Theta>(advection_field_rp)(irp) * J[0][0]
185 / std::sqrt(G[0][0]);
186 });
187
188 ddc::for_each(Opoint_grid, [&](IdxRTheta const irp) {
189 ddcHelper::get<X>(advection_field_xy)(irp) = CoordX(advection_field_xy_center);
190 ddcHelper::get<Y>(advection_field_xy)(irp) = CoordY(advection_field_xy_center);
191 });
192
193 // Pre-allocate some memory to prevent allocation later in loop
194 std::unique_ptr<IInterpolatorRTheta> const interpolator_ptr = m_interpolator.preallocate();
195
196 // Initialise the feet
197 host_t<FieldMemRTheta<CoordRTheta>> feet_rp(grid);
198 ddc::for_each(grid, [&](IdxRTheta const irp) { feet_rp(irp) = ddc::coordinate(irp); });
199
200 // Compute the characteristic feet at tn ----------------------------------------------------
201 m_find_feet(get_field(feet_rp), get_const_field(advection_field_xy), dt);
202
203 // Interpolate the function on the characteristic feet. -------------------------------------
204 (*interpolator_ptr)(allfdistribu, get_const_field(feet_rp));
205 Kokkos::Profiling::popRegion();
206
207 return allfdistribu;
208 }
209};
Define an advection operator on 2D index range.
Definition bsl_advection_rp.hpp:59
host_t< DFieldRTheta > operator()(host_t< DFieldRTheta > allfdistribu, host_t< DConstVectorFieldRTheta< X, Y > > advection_field_xy, double dt) const override
Allocate a Field of the advected function.
Definition bsl_advection_rp.hpp:111
BslAdvectionRTheta(PreallocatableSplineInterpolatorRTheta< ddc::NullExtrapolationRule > const &function_interpolator, FootFinder const &foot_finder, Mapping const &mapping)
Instantiate an advection operator.
Definition bsl_advection_rp.hpp:84
host_t< DFieldRTheta > operator()(host_t< DFieldRTheta > allfdistribu, host_t< DConstVectorFieldRTheta< R, Theta > > advection_field_rp, CoordXY const &advection_field_xy_center, double dt) const override
Allocate a Field to the advected function.
Definition bsl_advection_rp.hpp:151
Define the base class of 2D advection operators in polar index range.
Definition iadvectionrp.hpp:13
An operator for calculating the metric tensor.
Definition metric_tensor.hpp:15
A class which stores information necessary to create a pointer to an instance of the SplineInterpolat...
Definition spline_interpolator_2d_rp.hpp:113
std::unique_ptr< IInterpolatorRTheta > preallocate() const override
Create a pointer to an instance of the SplineInterpolatorRTheta class.
Definition spline_interpolator_2d_rp.hpp:156
A class which holds multiple (scalar) fields in order to represent a vector field.
Definition vector_field.hpp:64