Gyselalib++
 
Loading...
Searching...
No Matches
spline_foot_finder.hpp
1// SPDX-License-Identifier: MIT
2#pragma once
3#include <functional>
4
5#include <sll/mapping/circular_to_cartesian.hpp>
6#include <sll/mapping/combined_mapping.hpp>
7
8#include "ddc_alias_inline_functions.hpp"
9#include "ddc_aliases.hpp"
10#include "geometry_pseudo_cartesian.hpp"
11#include "ifoot_finder.hpp"
12#include "vector_mapper.hpp"
13
24template <class TimeStepper, class AdvectionDomain, class Mapping>
26{
27private:
31 using X_adv = typename AdvectionDomain::X_adv;
35 using Y_adv = typename AdvectionDomain::Y_adv;
36
39
40 TimeStepper const& m_time_stepper;
41
42 AdvectionDomain const& m_advection_domain;
43 InvAdvectionMapping m_mapping;
44
45 SplineRThetaBuilder_host const& m_builder_advection_field;
46 SplineRThetaEvaluatorConstBound_host const& m_evaluator_advection_field;
47
48
49public:
79 TimeStepper const& time_stepper,
80 AdvectionDomain const& advection_domain,
81 Mapping const& mapping,
82 SplineRThetaBuilder_host const& builder_advection_field,
83 SplineRThetaEvaluatorConstBound_host const& evaluator_advection_field,
84 double epsilon = 1e-12)
85 : m_time_stepper(time_stepper)
86 , m_advection_domain(advection_domain)
87 , m_mapping(mapping, PseudoCartesianToCircular(), epsilon)
88 , m_builder_advection_field(builder_advection_field)
89 , m_evaluator_advection_field(evaluator_advection_field)
90 {
91 }
92
110 host_t<FieldRTheta<CoordRTheta>> feet,
111 host_t<DConstVectorFieldRTheta<X, Y>> advection_field,
112 double dt) const final
113 {
114 host_t<VectorSplineCoeffsMem2D<X_adv, Y_adv>> advection_field_in_adv_domain_coefs(
115 get_spline_idx_range(m_builder_advection_field));
116
117 // Compute the advection field in the advection domain.
118 auto advection_field_in_adv_domain = create_geometry_mirror_view(
119 Kokkos::DefaultHostExecutionSpace(),
120 advection_field,
121 m_mapping);
122
123 // Get the coefficients of the advection field in the advection domain.
124 m_builder_advection_field(
125 ddcHelper::get<X_adv>(advection_field_in_adv_domain_coefs),
126 ddcHelper::get<X_adv>(get_const_field(advection_field_in_adv_domain)));
127 m_builder_advection_field(
128 ddcHelper::get<Y_adv>(advection_field_in_adv_domain_coefs),
129 ddcHelper::get<Y_adv>(get_const_field(advection_field_in_adv_domain)));
130
131
132 // The function describing how the derivative of the evolve function is calculated.
133 std::function<
135 host_t<ConstFieldRTheta<CoordRTheta>>)>
136 dy = [&](host_t<DVectorFieldRTheta<X_adv, Y_adv>> updated_advection_field,
137 host_t<ConstFieldRTheta<CoordRTheta>> feet) {
138 m_evaluator_advection_field(
139 get_field(ddcHelper::get<X_adv>(updated_advection_field)),
140 get_const_field(feet),
141 get_const_field(
142 ddcHelper::get<X_adv>(advection_field_in_adv_domain_coefs)));
143 m_evaluator_advection_field(
144 get_field(ddcHelper::get<Y_adv>(updated_advection_field)),
145 get_const_field(feet),
146 get_const_field(
147 ddcHelper::get<Y_adv>(advection_field_in_adv_domain_coefs)));
148 };
149
150 // The function describing how the value(s) are updated using the derivative.
151 std::function<
152 void(host_t<FieldRTheta<CoordRTheta>>,
154 double)>
155 update_function = [&](host_t<FieldRTheta<CoordRTheta>> feet,
156 host_t<DConstVectorFieldRTheta<X_adv, Y_adv>> advection_field,
157 double dt) {
158 // Compute the characteristic feet at t^n:
159 m_advection_domain.advect_feet(feet, advection_field, dt);
160
161 // Treatment to conserve the C0 property of the advected function:
162 unify_value_at_center_pt(feet);
163 // Test if the values are the same at the center point
164 is_unified(feet);
165 };
166
167
168 // Solve the characteristic equation
169 m_time_stepper.update(Kokkos::DefaultHostExecutionSpace(), feet, dt, dy, update_function);
170
171 is_unified(feet);
172 }
173
174
175
176private:
189 template <class T>
190 void is_unified(Field<T, IdxRangeRTheta, Kokkos::HostSpace> const& values) const
191 {
192 IdxRangeR const r_idx_range = get_idx_range<GridR>(values);
193 IdxRangeTheta const theta_idx_range = get_idx_range<GridTheta>(values);
194 if (std::fabs(ddc::coordinate(r_idx_range.front())) < 1e-15) {
195 ddc::for_each(theta_idx_range, [&](const IdxTheta ip) {
196 if (norm_inf(
197 values(r_idx_range.front(), ip)
198 - values(r_idx_range.front(), theta_idx_range.front()))
199 > 1e-15) {
200 std::cout << "WARNING ! -> Discontinous at the center point." << std::endl;
201 }
202 assert(values(r_idx_range.front(), ip)
203 == values(r_idx_range.front(), theta_idx_range.front()));
204 });
205 }
206 }
207
208
222 template <class T>
223 void unify_value_at_center_pt(Field<T, IdxRangeRTheta, Kokkos::HostSpace> values) const
224 {
225 IdxRangeR const r_idx_range = get_idx_range<GridR>(values);
226 IdxRangeTheta const theta_idx_range = get_idx_range<GridTheta>(values);
227 if (std::fabs(ddc::coordinate(r_idx_range.front())) < 1e-15) {
228 ddc::for_each(theta_idx_range, [&](const IdxTheta ip) {
229 values(r_idx_range.front(), ip)
230 = values(r_idx_range.front(), theta_idx_range.front());
231 });
232 }
233 }
234};
Define a domain for the advection.
Definition advection_domain.hpp:40
typename PhysicalToLogicalMapping::cartesian_tag_y Y_adv
The second dimension in the advection domain.
Definition advection_domain.hpp:54
void advect_feet(host_t< FieldRTheta< CoordRTheta > > feet_coords_rp, host_t< DConstVectorFieldRTheta< X_adv, Y_adv > > advection_field, double dt) const
Advect the characteristic feet.
Definition advection_domain.hpp:113
typename PhysicalToLogicalMapping::cartesian_tag_x X_adv
The first dimension in the advection domain.
Definition advection_domain.hpp:50
A class for describing the circular 2D mapping.
Definition cartesian_to_circular.hpp:40
Define a base class for all the time integration methods used for the advection.
Definition ifoot_finder.hpp:14
Define a base class for all the time integration methods used for the advection.
Definition spline_foot_finder.hpp:26
void operator()(host_t< FieldRTheta< CoordRTheta > > feet, host_t< DConstVectorFieldRTheta< X, Y > > advection_field, double dt) const final
Advect the feet over .
Definition spline_foot_finder.hpp:109
SplineFootFinder(TimeStepper const &time_stepper, AdvectionDomain const &advection_domain, Mapping const &mapping, SplineRThetaBuilder_host const &builder_advection_field, SplineRThetaEvaluatorConstBound_host const &evaluator_advection_field, double epsilon=1e-12)
Instantiate a time integration method for the advection operator.
Definition spline_foot_finder.hpp:78
A class which holds multiple (scalar) fields in order to represent a vector field.
Definition vector_field.hpp:64
KOKKOS_FUNCTION double norm_inf(ddc::Coordinate< Tags... > coord)
Compute the infinity norm.
Definition l_norm_tools.hpp:25