diff --git a/ci_tools/reusable_ci_jobs.yml b/ci_tools/reusable_ci_jobs.yml index 314fb18ec..5a1808104 100644 --- a/ci_tools/reusable_ci_jobs.yml +++ b/ci_tools/reusable_ci_jobs.yml @@ -44,4 +44,4 @@ setup_env_mr: timeout: 2 hours variables: GIT_SUBMODULE_STRATEGY: recursive - GENERAL_CMAKE_OPTIONS: "-DKokkos_ENABLE_DEPRECATED_CODE_3=OFF -DKokkos_ENABLE_DEPRECATION_WARNINGS=OFF -DSLL_SPLINES_TEST_DEGREE_MIN=1 -DSLL_SPLINES_TEST_DEGREE_MAX=7 -DSLL_BUILD_TESTING=$SLL_BUILD_TESTING -DPOISSON_2D_BUILD_TESTING=$POISSON_2D_BUILD_TESTING" + GENERAL_CMAKE_OPTIONS: "-DKokkos_ENABLE_DEPRECATED_CODE_3=OFF -DKokkos_ENABLE_DEPRECATION_WARNINGS=OFF -DSLL_SPLINES_TEST_DEGREE_MIN=1 -DSLL_SPLINES_TEST_DEGREE_MAX=6 -DSLL_BUILD_TESTING=$SLL_BUILD_TESTING -DPOISSON_2D_BUILD_TESTING=$POISSON_2D_BUILD_TESTING" diff --git a/simulations/geometryRTheta/diocotron/CMakeLists.txt b/simulations/geometryRTheta/diocotron/CMakeLists.txt index 9aa87d041..61b6bd762 100644 --- a/simulations/geometryRTheta/diocotron/CMakeLists.txt +++ b/simulations/geometryRTheta/diocotron/CMakeLists.txt @@ -26,7 +26,7 @@ function (diocotron_executable PREDCORR_METHOD TIME_METHOD ) Eigen3::Eigen - sll::splines + sll::SLL gslx::paraconfpp gslx::poisson_RTheta diff --git a/simulations/geometryRTheta/diocotron/diocotron.cpp b/simulations/geometryRTheta/diocotron/diocotron.cpp index d32fe5c90..8b78d7615 100644 --- a/simulations/geometryRTheta/diocotron/diocotron.cpp +++ b/simulations/geometryRTheta/diocotron/diocotron.cpp @@ -7,13 +7,9 @@ #include -#include #include #include #include -#include -#include -#include #include #include @@ -47,7 +43,8 @@ namespace { using PoissonSolver = PolarSplineFEMPoissonSolver; -using DiscreteMapping = DiscreteToCartesian; +using DiscreteMapping + = DiscreteToCartesian; using Mapping = CircularToCartesian; namespace fs = std::filesystem; @@ -146,16 +143,14 @@ int main(int argc, char** argv) SplineRPBuilder const builder(grid); // --- Define the mapping. ------------------------------------------------------------------------ - ConstantExtrapolationBoundaryValue2D boundary_condition_r_left( - r_min); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_right( - r_max); + ddc::ConstantExtrapolationRule boundary_condition_r_left(r_min); + ddc::ConstantExtrapolationRule boundary_condition_r_right(r_max); - SplineRPEvaluator spline_evaluator_extrapol( + SplineRPEvaluatorConstBound spline_evaluator_extrapol( boundary_condition_r_left, boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::PeriodicExtrapolationRule(), + ddc::PeriodicExtrapolationRule()); const Mapping mapping; DiscreteMapping const discrete_mapping @@ -185,11 +180,13 @@ int main(int argc, char** argv) // --- Advection operator ------------------------------------------------------------------------- - SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound spline_evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); PreallocatableSplineInterpolatorRP interpolator(builder, spline_evaluator); @@ -214,8 +211,8 @@ int main(int argc, char** argv) Spline2D coeff_alpha_spline(dom_bsplinesRP); Spline2D coeff_beta_spline(dom_bsplinesRP); - builder(coeff_alpha_spline, coeff_alpha); - builder(coeff_beta_spline, coeff_beta); + builder(coeff_alpha_spline.span_view(), coeff_alpha.span_cview()); + builder(coeff_beta_spline.span_view(), coeff_beta.span_cview()); PoissonSolver poisson_solver(coeff_alpha_spline, coeff_beta_spline, discrete_mapping); @@ -314,7 +311,7 @@ int main(int argc, char** argv) // Compute phi equilibrium phi_eq from Poisson solver. *********** DFieldRP phi_eq(grid); Spline2D rho_coef_eq(dom_bsplinesRP); - builder(rho_coef_eq, rho_eq); + builder(rho_coef_eq.span_view(), rho_eq.span_cview()); PoissonRHSFunction poisson_rhs_eq(rho_coef_eq, spline_evaluator); poisson_solver(poisson_rhs_eq, coords.span_cview(), phi_eq.span_view()); diff --git a/simulations/geometryRTheta/vortex_merger/CMakeLists.txt b/simulations/geometryRTheta/vortex_merger/CMakeLists.txt index 8b0157087..b0d76842e 100644 --- a/simulations/geometryRTheta/vortex_merger/CMakeLists.txt +++ b/simulations/geometryRTheta/vortex_merger/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(vortex_merger Eigen3::Eigen - sll::splines + sll::SLL gslx::paraconfpp gslx::poisson_RTheta diff --git a/simulations/geometryRTheta/vortex_merger/vortex_merger.cpp b/simulations/geometryRTheta/vortex_merger/vortex_merger.cpp index a36289f4f..8355f86d2 100644 --- a/simulations/geometryRTheta/vortex_merger/vortex_merger.cpp +++ b/simulations/geometryRTheta/vortex_merger/vortex_merger.cpp @@ -8,13 +8,9 @@ #include -#include #include #include #include -#include -#include -#include #include #include @@ -48,7 +44,8 @@ namespace { using PoissonSolver = PolarSplineFEMPoissonSolver; -using DiscreteMapping = DiscreteToCartesian; +using DiscreteMapping + = DiscreteToCartesian; using CircularMapping = CircularToCartesian; } // end namespace @@ -141,16 +138,14 @@ int main(int argc, char** argv) SplineRPBuilder const builder(grid); // --- Define the mapping. ------------------------------------------------------------------------ - ConstantExtrapolationBoundaryValue2D boundary_condition_r_left( - r_min); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_right( - r_max); + ddc::ConstantExtrapolationRule boundary_condition_r_left(r_min); + ddc::ConstantExtrapolationRule boundary_condition_r_right(r_max); - SplineRPEvaluator spline_evaluator_extrapol( + SplineRPEvaluatorConstBound spline_evaluator_extrapol( boundary_condition_r_left, boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::PeriodicExtrapolationRule(), + ddc::PeriodicExtrapolationRule()); const CircularMapping mapping; DiscreteMapping const discrete_mapping @@ -166,11 +161,13 @@ int main(int argc, char** argv) // --- Advection operator ------------------------------------------------------------------------- - SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound spline_evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); PreallocatableSplineInterpolatorRP interpolator(builder, spline_evaluator); @@ -195,8 +192,8 @@ int main(int argc, char** argv) Spline2D coeff_alpha_spline(dom_bsplinesRP); Spline2D coeff_beta_spline(dom_bsplinesRP); - builder(coeff_alpha_spline, coeff_alpha); - builder(coeff_beta_spline, coeff_beta); + builder(coeff_alpha_spline.span_view(), coeff_alpha.span_cview()); + builder(coeff_beta_spline.span_view(), coeff_beta.span_cview()); PoissonSolver poisson_solver(coeff_alpha_spline, coeff_beta_spline, discrete_mapping); @@ -279,8 +276,8 @@ int main(int argc, char** argv) // Compute phi equilibrium phi_eq from Poisson solver. *********** DFieldRP phi_eq(grid); Spline2D rho_coef_eq(dom_bsplinesRP); - builder(rho_coef_eq, rho_eq); - PoissonRHSFunction poisson_rhs_eq(rho_coef_eq, spline_evaluator); + builder(rho_coef_eq.span_view(), rho_eq.span_cview()); + PoissonRHSFunction poisson_rhs_eq(rho_coef_eq.span_view(), spline_evaluator); poisson_solver(poisson_rhs_eq, coords.span_cview(), phi_eq.span_view()); diff --git a/src/advection/CMakeLists.txt b/src/advection/CMakeLists.txt index 239cb6fa3..e5b4e45a4 100644 --- a/src/advection/CMakeLists.txt +++ b/src/advection/CMakeLists.txt @@ -14,7 +14,7 @@ target_include_directories("advection" target_link_libraries("advection" INTERFACE DDC::DDC - sll::splines + sll::SLL gslx::interpolation gslx::speciesinfo gslx::utils diff --git a/src/geometry5D/geometry/CMakeLists.txt b/src/geometry5D/geometry/CMakeLists.txt index 87032f47c..4d24a422f 100644 --- a/src/geometry5D/geometry/CMakeLists.txt +++ b/src/geometry5D/geometry/CMakeLists.txt @@ -7,7 +7,7 @@ target_include_directories("geometry5D" ) target_link_libraries("geometry5D" INTERFACE DDC::DDC - sll::splines + sll::SLL gslx::speciesinfo gslx::utils ) diff --git a/src/geometryRTheta/advection/CMakeLists.txt b/src/geometryRTheta/advection/CMakeLists.txt index e466da8fb..0d58566b8 100644 --- a/src/geometryRTheta/advection/CMakeLists.txt +++ b/src/geometryRTheta/advection/CMakeLists.txt @@ -8,7 +8,7 @@ target_include_directories(advection_rp target_link_libraries(advection_rp INTERFACE DDC::DDC - sll::splines + sll::SLL Eigen3::Eigen gslx::interpolation_2D_rp gslx::geometry_RTheta diff --git a/src/geometryRTheta/advection/advection_domain.hpp b/src/geometryRTheta/advection/advection_domain.hpp index 0107359bc..ddcea90c8 100644 --- a/src/geometryRTheta/advection/advection_domain.hpp +++ b/src/geometryRTheta/advection/advection_domain.hpp @@ -315,7 +315,7 @@ class AdvectionPseudoCartesianDomain : public AdvectionDomain VectorDViewRP const& advection_field, double const dt) const { - assert(typeid(m_mapping) != typeid(CircularToCartesian)); + static_assert(!std::is_same_v>); auto const rp_dom = advection_field.domain(); CircularToCartesian const pseudo_Cartesian_mapping; @@ -357,7 +357,7 @@ class AdvectionPseudoCartesianDomain : public AdvectionDomain VectorDViewRP advection_field, VectorDSpanRP advection_field_pseudo_Cart) const { - assert(typeid(m_mapping) != typeid(CircularToCartesian)); + static_assert(!std::is_same_v>); IDomainRP const rp_dom = advection_field.domain(); CircularToCartesian const pseudo_Cartesian_mapping; diff --git a/src/geometryRTheta/advection/bsl_advection_rp.hpp b/src/geometryRTheta/advection/bsl_advection_rp.hpp index 49ddbea9e..18a980587 100644 --- a/src/geometryRTheta/advection/bsl_advection_rp.hpp +++ b/src/geometryRTheta/advection/bsl_advection_rp.hpp @@ -60,7 +60,7 @@ template class BslAdvectionRP : public IAdvectionRP { private: - PreallocatableSplineInterpolatorRP const& m_interpolator; + PreallocatableSplineInterpolatorRP const& m_interpolator; FootFinder const& m_find_feet; @@ -84,7 +84,8 @@ class BslAdvectionRP : public IAdvectionRP * A child class of IFootFinder. */ BslAdvectionRP( - PreallocatableSplineInterpolatorRP const& function_interpolator, + PreallocatableSplineInterpolatorRP const& + function_interpolator, FootFinder const& foot_finder, Mapping const& mapping) : m_interpolator(function_interpolator) diff --git a/src/geometryRTheta/advection/spline_foot_finder.hpp b/src/geometryRTheta/advection/spline_foot_finder.hpp index 79fd7d525..62c5327a9 100644 --- a/src/geometryRTheta/advection/spline_foot_finder.hpp +++ b/src/geometryRTheta/advection/spline_foot_finder.hpp @@ -33,7 +33,7 @@ class SplineFootFinder : public IFootFinder AdvectionDomain const& m_advection_domain; SplineRPBuilder const& m_builder_advection_field; - SplineRPEvaluator const& m_evaluator_advection_field; + SplineRPEvaluatorConstBound const& m_evaluator_advection_field; public: @@ -64,7 +64,7 @@ class SplineFootFinder : public IFootFinder TimeStepper const& time_stepper, AdvectionDomain const& advection_domain, SplineRPBuilder const& builder_advection_field, - SplineRPEvaluator const& evaluator_advection_field) + SplineRPEvaluatorConstBound const& evaluator_advection_field) : m_time_stepper(time_stepper) , m_advection_domain(advection_domain) , m_builder_advection_field(builder_advection_field) @@ -105,10 +105,10 @@ class SplineFootFinder : public IFootFinder // Get the coefficients of the advection field in the advection domain. m_builder_advection_field( ddcHelper::get(advection_field_in_adv_dom_coefs), - ddcHelper::get(advection_field_in_adv_dom)); + ddcHelper::get(advection_field_in_adv_dom.span_cview())); m_builder_advection_field( ddcHelper::get(advection_field_in_adv_dom_coefs), - ddcHelper::get(advection_field_in_adv_dom)); + ddcHelper::get(advection_field_in_adv_dom.span_cview())); // The function describing how the derivative of the evolve function is calculated. diff --git a/src/geometryRTheta/advection_field/CMakeLists.txt b/src/geometryRTheta/advection_field/CMakeLists.txt index c08621390..00a5b7965 100644 --- a/src/geometryRTheta/advection_field/CMakeLists.txt +++ b/src/geometryRTheta/advection_field/CMakeLists.txt @@ -8,9 +8,9 @@ target_include_directories("advection_field_RTheta" ) target_link_libraries("advection_field_RTheta" INTERFACE DDC::DDC - sll::splines + sll::SLL gslx::speciesinfo gslx::utils gslx::poisson_RTheta ) -add_library("gslx::advection_field_RTheta" ALIAS "advection_field_RTheta") \ No newline at end of file +add_library("gslx::advection_field_RTheta" ALIAS "advection_field_RTheta") diff --git a/src/geometryRTheta/advection_field/advection_field_rp.hpp b/src/geometryRTheta/advection_field/advection_field_rp.hpp index 7132e75da..d0201f806 100644 --- a/src/geometryRTheta/advection_field/advection_field_rp.hpp +++ b/src/geometryRTheta/advection_field/advection_field_rp.hpp @@ -97,9 +97,10 @@ class AdvectionFieldFinder private: Mapping const& m_mapping; - PolarSplineEvaluator const m_polar_spline_evaluator; + PolarSplineEvaluator const + m_polar_spline_evaluator; - SplineRPEvaluator const m_spline_evaluator; + SplineRPEvaluatorNullBound const m_spline_evaluator; double const m_epsilon; @@ -117,12 +118,8 @@ class AdvectionFieldFinder */ AdvectionFieldFinder(Mapping const& mapping, double const epsilon = 1e-12) : m_mapping(mapping) - , m_polar_spline_evaluator(g_polar_null_boundary_2d) - , m_spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d) + , m_polar_spline_evaluator(ddc::NullExtrapolationRule()) + , m_spline_evaluator {ddc::NullExtrapolationRule(), ddc::NullExtrapolationRule(), ddc::PeriodicExtrapolationRule(), ddc::PeriodicExtrapolationRule()} , m_epsilon(epsilon) {}; ~AdvectionFieldFinder() {}; @@ -153,7 +150,7 @@ class AdvectionFieldFinder SplineRPBuilder const builder(grid); BSDomainRP const dom_bsplinesRP = builder.spline_domain(); Spline2D electrostatic_potential_coef(dom_bsplinesRP); - builder(electrostatic_potential_coef, electrostatic_potential); + builder(electrostatic_potential_coef.span_view(), electrostatic_potential.span_cview()); (*this)(electrostatic_potential_coef.span_view(), advection_field_xy); } @@ -217,13 +214,15 @@ class AdvectionFieldFinder SplineType& electrostatic_potential_coef, VectorFieldSpan> advection_field_xy) const { - assert((std::is_same_v< - Evaluator, - SplineRPEvaluator> && std::is_same_v) - || (std::is_same_v< - Evaluator, - PolarSplineEvaluator< - PolarBSplinesRP>> && std::is_same_v)); + static_assert( + (std::is_same_v< + Evaluator, + SplineRPEvaluatorNullBound> && std::is_same_v) + || (std::is_same_v< + Evaluator, + PolarSplineEvaluator< + PolarBSplinesRP, + ddc::NullExtrapolationRule>> && std::is_same_v)); IDomainRP const grid = advection_field_xy.domain(); VectorDFieldRP electric_field(grid); @@ -238,11 +237,11 @@ class AdvectionFieldFinder evaluator.deriv_dim_1( deriv_r_phi.span_view(), coords.span_cview(), - electrostatic_potential_coef); + electrostatic_potential_coef.span_cview()); evaluator.deriv_dim_2( deriv_p_phi.span_view(), coords.span_cview(), - electrostatic_potential_coef); + electrostatic_potential_coef.span_cview()); // > computation of the electric field ddc::for_each(grid, [&](IndexRP const irp) { @@ -280,10 +279,12 @@ class AdvectionFieldFinder double const dr_x_2 = m_mapping.jacobian_11(coord_2_0); // dr_x (0, th2) double const dr_y_2 = m_mapping.jacobian_21(coord_2_0); // dr_y (0, th2) - double deriv_r_phi_1 - = evaluator.deriv_dim_1(coord_1_0, electrostatic_potential_coef); - double deriv_r_phi_2 - = evaluator.deriv_dim_1(coord_2_0, electrostatic_potential_coef); + double deriv_r_phi_1 = evaluator.deriv_dim_1( + coord_1_0, + electrostatic_potential_coef.span_cview()); + double deriv_r_phi_2 = evaluator.deriv_dim_1( + coord_2_0, + electrostatic_potential_coef.span_cview()); double const determinant = dr_x_1 * dr_y_2 - dr_x_2 * dr_y_1; @@ -304,10 +305,12 @@ class AdvectionFieldFinder Matrix_2x2 inv_J_eps; // Jacobian matrix m_mapping.inv_jacobian_matrix(coord_rp_epsilon, inv_J_eps); - double const deriv_r_phi_epsilon - = evaluator.deriv_dim_1(coord_rp_epsilon, electrostatic_potential_coef); - double const deriv_p_phi_epsilon - = evaluator.deriv_dim_2(coord_rp_epsilon, electrostatic_potential_coef); + double const deriv_r_phi_epsilon = evaluator.deriv_dim_1( + coord_rp_epsilon, + electrostatic_potential_coef.span_cview()); + double const deriv_p_phi_epsilon = evaluator.deriv_dim_2( + coord_rp_epsilon, + electrostatic_potential_coef.span_cview()); // Gradiant of phi in the physical domain (Cartesian domain) double const deriv_x_phi_epsilon = deriv_r_phi_epsilon * inv_J_eps[0][0] @@ -367,7 +370,7 @@ class AdvectionFieldFinder SplineRPBuilder const builder(grid); BSDomainRP const dom_bsplinesRP = builder.spline_domain(); Spline2D electrostatic_potential_coef(dom_bsplinesRP); - builder(electrostatic_potential_coef, electrostatic_potential); + builder(electrostatic_potential_coef.span_view(), electrostatic_potential.span_cview()); (*this)(electrostatic_potential_coef.span_view(), advection_field_rp, @@ -445,13 +448,15 @@ class AdvectionFieldFinder VectorFieldSpan> advection_field_rp, CoordXY& advection_field_xy_center) const { - assert((std::is_same_v< - Evaluator, - SplineRPEvaluator> && std::is_same_v) - || (std::is_same_v< - Evaluator, - PolarSplineEvaluator< - PolarBSplinesRP>> && std::is_same_v)); + static_assert( + (std::is_same_v< + Evaluator, + SplineRPEvaluatorNullBound> && std::is_same_v) + || (std::is_same_v< + Evaluator, + PolarSplineEvaluator< + PolarBSplinesRP, + ddc::NullExtrapolationRule>> && std::is_same_v)); IDomainRP const grid_without_Opoint = advection_field_rp.domain(); @@ -467,11 +472,11 @@ class AdvectionFieldFinder evaluator.deriv_dim_1( deriv_r_phi.span_view(), coords.span_cview(), - electrostatic_potential_coef); + electrostatic_potential_coef.span_cview()); evaluator.deriv_dim_2( deriv_p_phi.span_view(), coords.span_cview(), - electrostatic_potential_coef); + electrostatic_potential_coef.span_cview()); // > computation of the advection field ddc::for_each(grid_without_Opoint, [&](IndexRP const irp) { @@ -512,8 +517,10 @@ class AdvectionFieldFinder double const dr_x_2 = m_mapping.jacobian_11(coord_2_0); // dr_x (0, th2) double const dr_y_2 = m_mapping.jacobian_21(coord_2_0); // dr_y (0, th2) - double const deriv_r_phi_1 = evaluator.deriv_dim_1(coord_1_0, electrostatic_potential_coef); - double const deriv_r_phi_2 = evaluator.deriv_dim_1(coord_2_0, electrostatic_potential_coef); + double const deriv_r_phi_1 + = evaluator.deriv_dim_1(coord_1_0, electrostatic_potential_coef.span_cview()); + double const deriv_r_phi_2 + = evaluator.deriv_dim_1(coord_2_0, electrostatic_potential_coef.span_cview()); double const determinant = dr_x_1 * dr_y_2 - dr_x_2 * dr_y_1; diff --git a/src/geometryRTheta/geometry/CMakeLists.txt b/src/geometryRTheta/geometry/CMakeLists.txt index 117c589aa..a6e192de3 100644 --- a/src/geometryRTheta/geometry/CMakeLists.txt +++ b/src/geometryRTheta/geometry/CMakeLists.txt @@ -10,7 +10,7 @@ target_include_directories("geometry_RTheta" ) target_link_libraries("geometry_RTheta" INTERFACE DDC::DDC - sll::splines + sll::SLL gslx::speciesinfo gslx::utils ) diff --git a/src/geometryRTheta/geometry/geometry.hpp b/src/geometryRTheta/geometry/geometry.hpp index ac013e3d3..eb72c8c48 100644 --- a/src/geometryRTheta/geometry/geometry.hpp +++ b/src/geometryRTheta/geometry/geometry.hpp @@ -1,16 +1,9 @@ #pragma once #include +#include -#include -#include -#include -#include #include -#include -#include -#include -#include #include #include @@ -63,23 +56,23 @@ bool constexpr BsplineOnUniformCellsP = false; using BSplinesR = std::conditional_t< BsplineOnUniformCellsR, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; using BSplinesP = std::conditional_t< BsplineOnUniformCellsP, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; using PolarBSplinesRP = PolarBSplines; -auto constexpr SplineRBoundary = RDimR::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; -auto constexpr SplinePBoundary = RDimP::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; +auto constexpr SplineRBoundary = ddc::BoundCond::GREVILLE; +auto constexpr SplinePBoundary = ddc::BoundCond::PERIODIC; -bool constexpr UniformMeshR = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshR = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsR, SplineRBoundary, SplineRBoundary, BSDegreeR); -bool constexpr UniformMeshP = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshP = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsP, SplinePBoundary, SplinePBoundary, @@ -95,15 +88,70 @@ using IDimP = std::conditional_t< ddc::NonUniformPointSampling>; using SplineInterpPointsR - = GrevilleInterpolationPoints; + = ddc::GrevilleInterpolationPoints; using SplineInterpPointsP - = GrevilleInterpolationPoints; - -using SplineRBuilder = SplineBuilder; -using SplinePBuilder = SplineBuilder; -using SplineRPBuilder = SplineBuilder2D; - -using SplineRPEvaluator = SplineEvaluator2D; + = ddc::GrevilleInterpolationPoints; + +using SplineRBuilder = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + IDimR, + SplineRBoundary, // boundary at r=0 + SplineRBoundary, // boundary at rmax + ddc::SplineSolver::GINKGO, + IDimR>; +using SplinePBuilder = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesP, + IDimP, + SplinePBoundary, + SplinePBoundary, + ddc::SplineSolver::GINKGO, + IDimP>; +using SplineRPBuilder = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + SplineRBoundary, // boundary at r=0 + SplineRBoundary, // boundary at rmax + SplinePBoundary, + SplinePBoundary, + ddc::SplineSolver::GINKGO, + IDimR, + IDimP>; + +using SplineRPEvaluatorConstBound = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::ConstantExtrapolationRule, // boundary at r=0 + ddc::ConstantExtrapolationRule, // boundary at rmax + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; + +using SplineRPEvaluatorNullBound = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::NullExtrapolationRule, // boundary at r=0 + ddc::NullExtrapolationRule, // boundary at rmax + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; using BSDomainR = ddc::DiscreteDomain; using BSDomainP = ddc::DiscreteDomain; @@ -248,25 +296,27 @@ bool constexpr BsplineOnUniformCellsVp = false; using BSplinesVr = std::conditional_t< BsplineOnUniformCellsVr, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; using BSplinesVp = std::conditional_t< BsplineOnUniformCellsVp, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; using PolarBSplinesVrVp = PolarBSplines; -auto constexpr SplineVrBoundary = RDimVr::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; -auto constexpr SplineVpBoundary = RDimVp::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; +auto constexpr SplineVrBoundary + = RDimVr::PERIODIC ? ddc::BoundCond::PERIODIC : ddc::BoundCond::GREVILLE; +auto constexpr SplineVpBoundary + = RDimVp::PERIODIC ? ddc::BoundCond::PERIODIC : ddc::BoundCond::GREVILLE; -bool constexpr UniformMeshVr = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshVr = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsVr, SplineVrBoundary, SplineVrBoundary, BSDegreeVr); -bool constexpr UniformMeshVp = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshVp = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsVp, SplineVpBoundary, SplineVpBoundary, @@ -283,13 +333,42 @@ using IDimVp = std::conditional_t< using SplineInterpPointsVr - = GrevilleInterpolationPoints; + = ddc::GrevilleInterpolationPoints; using SplineInterpPointsVp - = GrevilleInterpolationPoints; + = ddc::GrevilleInterpolationPoints; -using SplineVrBuilder = SplineBuilder; -using SplineVpBuilder = SplineBuilder; -using SplineVrVpBuilder = SplineBuilder2D; +using SplineVrBuilder = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesVr, + IDimVr, + SplineVrBoundary, + SplineVrBoundary, + ddc::SplineSolver::GINKGO, + IDimVr>; +using SplineVpBuilder = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesVp, + IDimVp, + SplineVpBoundary, + SplineVpBoundary, + ddc::SplineSolver::GINKGO, + IDimVp>; +using SplineVrVpBuilder = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesVr, + BSplinesVp, + IDimVr, + IDimVp, + SplineVrBoundary, + SplineVrBoundary, + SplineVpBoundary, + SplineVpBoundary, + ddc::SplineSolver::GINKGO, + IDimVr, + IDimVp>; using BSDomainVr = ddc::DiscreteDomain; @@ -465,23 +544,24 @@ bool constexpr BsplineOnUniformCellsVx = false; using BSplinesX = std::conditional_t< BsplineOnUniformCellsX, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; using BSplinesVx = std::conditional_t< BsplineOnUniformCellsVx, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; -auto constexpr SplineXBoundary = RDimX::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; -auto constexpr SplineVxBoundary = BoundCond::HERMITE; +auto constexpr SplineXBoundary + = RDimX::PERIODIC ? ddc::BoundCond::PERIODIC : ddc::BoundCond::GREVILLE; +auto constexpr SplineVxBoundary = ddc::BoundCond::HERMITE; -bool constexpr UniformMeshX = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshX = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsX, SplineXBoundary, SplineXBoundary, BSDegreeX); -bool constexpr UniformMeshVx = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshVx = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsVx, SplineVxBoundary, SplineVxBoundary, @@ -497,12 +577,9 @@ using IDimVx = std::conditional_t< ddc::NonUniformPointSampling>; using SplineInterpPointsX - = GrevilleInterpolationPoints; + = ddc::GrevilleInterpolationPoints; using SplineInterpPointsVx - = GrevilleInterpolationPoints; - -using SplineXBuilder = SplineBuilder; -using SplineVxBuilder = SplineBuilder; + = ddc::GrevilleInterpolationPoints; @@ -678,25 +755,26 @@ bool constexpr BsplineOnUniformCellsVy = false; using BSplinesY = std::conditional_t< BsplineOnUniformCellsY, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; using BSplinesVy = std::conditional_t< BsplineOnUniformCellsVy, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; -auto constexpr SplineYBoundary = RDimY::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; -auto constexpr SplineVyBoundary = BoundCond::HERMITE; +auto constexpr SplineYBoundary + = RDimY::PERIODIC ? ddc::BoundCond::PERIODIC : ddc::BoundCond::GREVILLE; +auto constexpr SplineVyBoundary = ddc::BoundCond::HERMITE; -bool constexpr UniformMeshY = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshY = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsY, SplineYBoundary, SplineYBoundary, BSDegreeY); -bool constexpr UniformMeshVy = is_spline_interpolation_mesh_uniform( +bool constexpr UniformMeshVy = ddc::is_spline_interpolation_mesh_uniform( BsplineOnUniformCellsVy, SplineVyBoundary, SplineVyBoundary, @@ -712,12 +790,9 @@ using IDimVy = std::conditional_t< ddc::NonUniformPointSampling>; using SplineInterpPointsY - = GrevilleInterpolationPoints; + = ddc::GrevilleInterpolationPoints; using SplineInterpPointsVy - = GrevilleInterpolationPoints; - -using SplineYBuilder = SplineBuilder; -using SplineVyBuilder = SplineBuilder; + = ddc::GrevilleInterpolationPoints; // Species dimension @@ -843,10 +918,6 @@ using CoordVxVy = ddc::Coordinate; using CoordXYVxVy = ddc::Coordinate; -using SplineXYBuilder = SplineBuilder2D; -using SplineVxVyBuilder = SplineBuilder2D; - - // Species dimension using IndexXY = ddc::DiscreteElement; using IndexVxVy = ddc::DiscreteElement; diff --git a/src/geometryRTheta/initialization/CMakeLists.txt b/src/geometryRTheta/initialization/CMakeLists.txt index 516fd54ef..493060968 100644 --- a/src/geometryRTheta/initialization/CMakeLists.txt +++ b/src/geometryRTheta/initialization/CMakeLists.txt @@ -19,7 +19,7 @@ target_link_libraries(diocotron_init_eq DDC::PDI_Wrapper Eigen3::Eigen - sll::splines + sll::SLL gslx::geometry_RTheta ) @@ -39,10 +39,10 @@ target_link_libraries(vortex_merger_init_eq #DDC::PDI_Wrapper #Eigen3::Eigen - sll::splines + sll::SLL gslx::geometry_RTheta gslx::utils gslx::poisson_RTheta ) -add_library("gslx::vortex_merger_init_eq" ALIAS "vortex_merger_init_eq") \ No newline at end of file +add_library("gslx::vortex_merger_init_eq" ALIAS "vortex_merger_init_eq") diff --git a/src/geometryRTheta/initialization/vortex_merger_equilibrium.hpp b/src/geometryRTheta/initialization/vortex_merger_equilibrium.hpp index 86376bc18..88baa7728 100644 --- a/src/geometryRTheta/initialization/vortex_merger_equilibrium.hpp +++ b/src/geometryRTheta/initialization/vortex_merger_equilibrium.hpp @@ -6,9 +6,6 @@ #include -#include "sll/spline_builder_2d.hpp" -#include "sll/spline_evaluator_2d.hpp" - #include "poisson_rhs_function.hpp" #include "polarpoissonsolver.hpp" #include "utils_tools.hpp" @@ -28,7 +25,7 @@ class VortexMergerEquilibria Mapping const& m_mapping; IDomainRP const& m_grid; SplineRPBuilder const& m_builder; - SplineRPEvaluator const& m_evaluator; + SplineRPEvaluatorNullBound const& m_evaluator; PolarSplineFEMPoissonSolver const& m_poisson_solver; public: @@ -53,7 +50,7 @@ class VortexMergerEquilibria Mapping const& mapping, IDomainRP const& grid, SplineRPBuilder const& builder, - SplineRPEvaluator const& evaluator, + SplineRPEvaluatorNullBound const& evaluator, PolarSplineFEMPoissonSolver const& poisson_solver) : m_mapping(mapping) , m_grid(grid) @@ -128,7 +125,7 @@ class VortexMergerEquilibria // STEP 2: compute phi_star^i with Poisson solver - m_builder(rho_coef, rho_eq); + m_builder(rho_coef.span_view(), rho_eq.span_cview()); PoissonRHSFunction poisson_rhs(rho_coef, m_evaluator); m_poisson_solver(poisson_rhs, coords.span_cview(), phi_star.span_view()); diff --git a/src/geometryRTheta/interpolation/CMakeLists.txt b/src/geometryRTheta/interpolation/CMakeLists.txt index 03b914365..34c624e61 100644 --- a/src/geometryRTheta/interpolation/CMakeLists.txt +++ b/src/geometryRTheta/interpolation/CMakeLists.txt @@ -1,23 +1,22 @@ # SPDX-License-Identifier: MIT -add_library("interpolation_2D_rp" STATIC - spline_interpolator_2d_rp.cpp +add_library("interpolation_2D_rp" INTERFACE ) target_compile_features("interpolation_2D_rp" - PUBLIC + INTERFACE cxx_std_17 ) target_include_directories("interpolation_2D_rp" - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" + INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" ) target_link_libraries("interpolation_2D_rp" - PUBLIC + INTERFACE DDC::DDC - sll::splines + sll::SLL gslx::geometry_RTheta ) diff --git a/src/geometryRTheta/interpolation/spline_interpolator_2d_rp.cpp b/src/geometryRTheta/interpolation/spline_interpolator_2d_rp.cpp deleted file mode 100644 index ba2d95f07..000000000 --- a/src/geometryRTheta/interpolation/spline_interpolator_2d_rp.cpp +++ /dev/null @@ -1,30 +0,0 @@ - -#include -#include - -#include "i_interpolator_2d_rp.hpp" -#include "spline_interpolator_2d_rp.hpp" - - -DSpanRP SplineInterpolatorRP::operator()( - DSpanRP const inout_data, - ddc::ChunkSpan const coordinates) const -{ -#ifndef NDEBUG - // To ensure that the interpolator is C0, we ensure that - // the value at (r=0,theta) is the same for all theta. - auto r_domain = ddc::get_domain(inout_data); - auto theta_domain = ddc::get_domain(inout_data); - if (ddc::coordinate(r_domain.front()) == 0) { - ddc::for_each(theta_domain, [&](IndexP const ip) { - assert(("Unicity of the value at the center point:", - inout_data(r_domain.front(), ip) - == inout_data(r_domain.front(), theta_domain.front()))); - }); - } -#endif - - m_builder(m_coefs, inout_data); - m_evaluator(inout_data, coordinates, m_coefs); - return inout_data; -} diff --git a/src/geometryRTheta/interpolation/spline_interpolator_2d_rp.hpp b/src/geometryRTheta/interpolation/spline_interpolator_2d_rp.hpp index fc6eecedb..d8d4ae737 100644 --- a/src/geometryRTheta/interpolation/spline_interpolator_2d_rp.hpp +++ b/src/geometryRTheta/interpolation/spline_interpolator_2d_rp.hpp @@ -1,8 +1,4 @@ #pragma once - -#include -#include - #include "geometry.hpp" #include "i_interpolator_2d_rp.hpp" @@ -10,24 +6,45 @@ /** * @brief A class for interpolating a function using splines in polar coordinates. * - * @tag Spline_interpolator_polar + * @tparam RadialExtrapolationRule The extrapolation rule applied at the outer radial bound. */ +template class SplineInterpolatorRP : public IInterpolatorRP { +public: + /// The type of the 2D Spline Evaluator used by this class + using evaluator_type = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + RadialExtrapolationRule, + RadialExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; + private: SplineRPBuilder const& m_builder; - SplineRPEvaluator const& m_evaluator; + evaluator_type const& m_evaluator; mutable ddc::Chunk m_coefs; + using r_deriv_type = ddc::ChunkSpan; + using p_deriv_type = ddc::ChunkSpan; + using mixed_deriv_type = ddc::ChunkSpan; + public: /** * @brief Create a spline interpolator object. * @param[in] builder An operator which builds spline coefficients from the values of a function at known interpolation points. * @param[in] evaluator An operator which evaluates the value of a spline at requested coordinates. */ - SplineInterpolatorRP(SplineRPBuilder const& builder, SplineRPEvaluator const& evaluator) + SplineInterpolatorRP(SplineRPBuilder const& builder, evaluator_type const& evaluator) : m_builder(builder) , m_evaluator(evaluator) , m_coefs(builder.spline_domain()) @@ -48,8 +65,28 @@ class SplineInterpolatorRP : public IInterpolatorRP * * @return A reference to the inout_data array containing the value of the function at the coordinates. */ - DSpanRP operator()(DSpanRP inout_data, ddc::ChunkSpan coordinates) - const override; + DSpanRP operator()( + DSpanRP const inout_data, + ddc::ChunkSpan const coordinates) const override + { +#ifndef NDEBUG + // To ensure that the interpolator is C0, we ensure that + // the value at (r=0,theta) is the same for all theta. + auto r_domain = ddc::get_domain(inout_data); + auto theta_domain = ddc::get_domain(inout_data); + if (ddc::coordinate(r_domain.front()) == 0) { + ddc::for_each(theta_domain, [&](IndexP const ip) { + assert(("Unicity of the value at the center point:", + inout_data(r_domain.front(), ip) + == inout_data(r_domain.front(), theta_domain.front()))); + }); + } +#endif + + m_builder(m_coefs.span_view(), inout_data.span_cview()); + m_evaluator(inout_data.span_view(), coordinates, m_coefs.span_cview()); + return inout_data; + } }; @@ -61,11 +98,29 @@ class SplineInterpolatorRP : public IInterpolatorRP * memory allocated in the private members of the SplineInterpolatorRP to be freed when the object is not in use. * These objects are: m_coefs. */ +template class PreallocatableSplineInterpolatorRP : public IPreallocatableInterpolatorRP { +public: + /// The type of the 2D Spline Evaluator used by this class + using evaluator_type = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + RadialExtrapolationRule, + RadialExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; + +private: SplineRPBuilder const& m_builder; - SplineRPEvaluator const& m_evaluator; + evaluator_type const& m_evaluator; public: /** @@ -75,7 +130,7 @@ class PreallocatableSplineInterpolatorRP : public IPreallocatableInterpolatorRP */ PreallocatableSplineInterpolatorRP( SplineRPBuilder const& builder, - SplineRPEvaluator const& evaluator) + evaluator_type const& evaluator) : m_builder(builder) , m_evaluator(evaluator) { @@ -90,6 +145,7 @@ class PreallocatableSplineInterpolatorRP : public IPreallocatableInterpolatorRP */ std::unique_ptr preallocate() const override { - return std::make_unique(m_builder, m_evaluator); + return std::make_unique< + SplineInterpolatorRP>(m_builder, m_evaluator); } }; diff --git a/src/geometryRTheta/poisson/CMakeLists.txt b/src/geometryRTheta/poisson/CMakeLists.txt index 540e174bd..5a465284b 100644 --- a/src/geometryRTheta/poisson/CMakeLists.txt +++ b/src/geometryRTheta/poisson/CMakeLists.txt @@ -8,7 +8,7 @@ target_include_directories(poisson_RTheta ) target_link_libraries(poisson_RTheta INTERFACE DDC::DDC - sll::splines + sll::SLL gslx::geometry_RTheta gslx::speciesinfo gslx::utils diff --git a/src/geometryRTheta/poisson/poisson_rhs_function.hpp b/src/geometryRTheta/poisson/poisson_rhs_function.hpp index 53a94fafe..eedc6a7c3 100644 --- a/src/geometryRTheta/poisson/poisson_rhs_function.hpp +++ b/src/geometryRTheta/poisson/poisson_rhs_function.hpp @@ -2,8 +2,6 @@ #include -#include - #include "geometry.hpp" #include "spline_interpolator_2d_rp.hpp" @@ -11,12 +9,30 @@ /** * @brief Type of right-hand side (rhs) function of the Poisson equation. + * @tparam RadialExtrapolationRule The extrapolation rule applied at the outer radial bound. */ +template class PoissonRHSFunction { +public: + /// The type of the 2D Spline Evaluator used by this class + using evaluator_type = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + RadialExtrapolationRule, + RadialExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; + private: Spline2DView const m_coefs; - SplineRPEvaluator const& m_evaluator; + evaluator_type const& m_evaluator; public: /** @@ -27,7 +43,7 @@ class PoissonRHSFunction * @param[in] evaluator * Evaluator on bsplines. */ - PoissonRHSFunction(Spline2DView coefs, SplineRPEvaluator const& evaluator) + PoissonRHSFunction(Spline2DView coefs, evaluator_type const& evaluator) : m_coefs(coefs) , m_evaluator(evaluator) { diff --git a/src/geometryRTheta/poisson/polarpoissonsolver.hpp b/src/geometryRTheta/poisson/polarpoissonsolver.hpp index c735c2a7b..94e7737c2 100644 --- a/src/geometryRTheta/poisson/polarpoissonsolver.hpp +++ b/src/geometryRTheta/poisson/polarpoissonsolver.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -111,6 +110,14 @@ class PolarSplineFEMPoissonSolver */ using QuadratureLengthP = ddc::DiscreteVector; + using BSplinesR_Polar = PolarBSplinesRP::BSplinesR_tag; + using BSplinesP_Polar = PolarBSplinesRP::BSplinesP_tag; + + using IDimBSpline2D_Polar = ddc::DiscreteElement; + + using BSDomainR_Polar = ddc::DiscreteDomain; + using BSDomainP_Polar = ddc::DiscreteDomain; + /** * @brief Object storing a value and a value of the derivative * of a 1D function. @@ -142,19 +149,19 @@ class PolarSplineFEMPoissonSolver using MatrixElement = Eigen::Triplet; private: - static constexpr int n_gauss_legendre_r = BSplinesR::degree() + 1; - static constexpr int n_gauss_legendre_p = BSplinesP::degree() + 1; + static constexpr int n_gauss_legendre_r = BSplinesR_Polar::degree() + 1; + static constexpr int n_gauss_legendre_p = BSplinesP_Polar::degree() + 1; // The number of cells (in the radial direction) in which both types of basis splines can be found static constexpr int n_overlap_cells = PolarBSplinesRP::continuity + 1; // Number of cells over which a radial B-splines has its support // This is the case for b-splines which are not affected by the higher knot multiplicity at the boundary. static constexpr ddc::DiscreteVector n_non_zero_bases_r - = ddc::DiscreteVector(BSplinesR::degree() + 1); + = ddc::DiscreteVector(BSplinesR_Polar::degree() + 1); // Number of cells over which a poloidal B-splines has its support static constexpr ddc::DiscreteVector n_non_zero_bases_p - = ddc::DiscreteVector(BSplinesP::degree() + 1); + = ddc::DiscreteVector(BSplinesP_Polar::degree() + 1); static constexpr ddc::DiscreteDomain non_zero_bases_r = ddc::DiscreteDomain< RBasisSubset>(ddc::DiscreteElement {0}, n_non_zero_bases_r); @@ -166,8 +173,8 @@ class PolarSplineFEMPoissonSolver // Domains BSDomainPolar fem_non_singular_domain; - BSDomainR radial_bsplines; - BSDomainP polar_bsplines; + BSDomainR_Polar radial_bsplines; + BSDomainP_Polar polar_bsplines; QuadratureDomainR quadrature_domain_r; QuadratureDomainP quadrature_domain_p; @@ -189,7 +196,7 @@ class PolarSplineFEMPoissonSolver ddc::Chunk int_volume; - PolarSplineEvaluator m_polar_spline_evaluator; + PolarSplineEvaluator m_polar_spline_evaluator; Eigen::SimplicialLDLT> m_matrix; @@ -220,23 +227,23 @@ class PolarSplineFEMPoissonSolver Spline2DView coeff_alpha, Spline2DView coeff_beta, Mapping const& mapping) - : nbasis_r(ddc::discrete_space().nbasis() - n_overlap_cells - 1) - , nbasis_p(ddc::discrete_space().nbasis()) + : nbasis_r(ddc::discrete_space().nbasis() - n_overlap_cells - 1) + , nbasis_p(ddc::discrete_space().nbasis()) , fem_non_singular_domain( ddc::discrete_space().tensor_bspline_domain().remove_last( ddc::DiscreteVector {nbasis_p})) - , radial_bsplines(ddc::discrete_space().full_domain().remove_first( - ddc::DiscreteVector {n_overlap_cells})) - , polar_bsplines(ddc::discrete_space().full_domain().take_first( - ddc::DiscreteVector {nbasis_p})) + , radial_bsplines(ddc::discrete_space().full_domain().remove_first( + ddc::DiscreteVector {n_overlap_cells})) + , polar_bsplines(ddc::discrete_space().full_domain().take_first( + ddc::DiscreteVector {nbasis_p})) , quadrature_domain_r( ddc::DiscreteElement(0), ddc::DiscreteVector( - n_gauss_legendre_r * ddc::discrete_space().ncells())) + n_gauss_legendre_r * ddc::discrete_space().ncells())) , quadrature_domain_p( ddc::DiscreteElement(0), ddc::DiscreteVector( - n_gauss_legendre_p * ddc::discrete_space().ncells())) + n_gauss_legendre_p * ddc::discrete_space().ncells())) , quadrature_domain_singular( quadrature_domain_r.take_first( ddc::DiscreteVector {n_overlap_cells * n_gauss_legendre_r}), @@ -256,10 +263,10 @@ class PolarSplineFEMPoissonSolver PBasisSubset, QDimPMesh>(non_zero_bases_p, quadrature_domain_p)) , int_volume(QuadratureDomainRP(quadrature_domain_r, quadrature_domain_p)) - , m_polar_spline_evaluator(g_polar_null_boundary_2d) + , m_polar_spline_evaluator(ddc::NullExtrapolationRule()) { - const std::size_t ncells_r = ddc::discrete_space().ncells(); - const std::size_t ncells_p = ddc::discrete_space().ncells(); + const std::size_t ncells_r = ddc::discrete_space().ncells(); + const std::size_t ncells_p = ddc::discrete_space().ncells(); // Get break points ddc::DiscreteDomain r_edges_dom( @@ -273,11 +280,11 @@ class PolarSplineFEMPoissonSolver ddc::for_each(r_edges_dom, [&](ddc::DiscreteElement i) { breaks_r(i) = ddc::Coordinate( - ddc::get(ddc::discrete_space().get_knot(i.uid()))); + ddc::get(ddc::discrete_space().get_knot(i.uid()))); }); ddc::for_each(p_edges_dom, [&](ddc::DiscreteElement i) { breaks_p(i) = ddc::Coordinate( - ddc::get(ddc::discrete_space().get_knot(i.uid()))); + ddc::get(ddc::discrete_space().get_knot(i.uid()))); }); // Define quadrature points and weights @@ -309,7 +316,8 @@ class PolarSplineFEMPoissonSolver ddc::for_each(quadrature_domain_r, [&](QuadratureIndexR const ir) { std::array data; DSpan2D vals(data.data(), n_non_zero_bases_r, 2); - ddc::discrete_space().eval_basis_and_n_derivs(vals, get_coordinate(ir), 1); + ddc::discrete_space() + .eval_basis_and_n_derivs(vals, get_coordinate(ir), 1); for (auto ib : non_zero_bases_r) { r_basis_vals_and_derivs(ib, ir).value = vals(ib.uid(), 0); r_basis_vals_and_derivs(ib, ir).derivative = vals(ib.uid(), 1); @@ -320,7 +328,8 @@ class PolarSplineFEMPoissonSolver ddc::for_each(quadrature_domain_p, [&](QuadratureIndexP const ip) { std::array data; DSpan2D vals(data.data(), n_non_zero_bases_p, 2); - ddc::discrete_space().eval_basis_and_n_derivs(vals, get_coordinate(ip), 1); + ddc::discrete_space() + .eval_basis_and_n_derivs(vals, get_coordinate(ip), 1); for (auto ib : non_zero_bases_p) { p_basis_vals_and_derivs(ib, ip).value = vals(ib.uid(), 0); p_basis_vals_and_derivs(ib, ip).derivative = vals(ib.uid(), 1); @@ -374,11 +383,13 @@ class PolarSplineFEMPoissonSolver int_volume(ir, ip) = abs(mapping.jacobian(coord)) * weights_r(ir) * weights_p(ip); }); - SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound spline_evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); // Number of elements in the matrix that correspond to the splines // that cover the singular point @@ -387,10 +398,10 @@ class PolarSplineFEMPoissonSolver // Number of non-zero elements in the matrix corresponding to the inner product of // polar splines at the singular point and the other splines const int n_elements_overlap - = 2 * (PolarBSplinesRP::n_singular_basis() * BSplinesR::degree() * nbasis_p); - const int n_stencil_p = nbasis_p * min(int(1 + 2 * BSplinesP::degree()), nbasis_p); - const int n_stencil_r = nbasis_r * (1 + 2 * BSplinesR::degree()) - - (1 + BSplinesR::degree()) * BSplinesR::degree(); + = 2 * (PolarBSplinesRP::n_singular_basis() * BSplinesR_Polar::degree() * nbasis_p); + const int n_stencil_p = nbasis_p * min(int(1 + 2 * BSplinesP_Polar::degree()), nbasis_p); + const int n_stencil_r = nbasis_r * (1 + 2 * BSplinesR_Polar::degree()) + - (1 + BSplinesR_Polar::degree()) * BSplinesR_Polar::degree(); // Number of non-zero elements in the matrix corresponding to the inner product of // non-central splines. These have a tensor product structure const int n_elements_stencil = n_stencil_r * n_stencil_p; @@ -430,93 +441,108 @@ class PolarSplineFEMPoissonSolver assert(matrix_idx == n_elements_singular); // Create domains associated with the 2D splines - BSDomainR central_radial_bspline_domain( - radial_bsplines.take_first(ddc::DiscreteVector {BSplinesR::degree()})); + BSDomainR central_radial_bspline_domain(radial_bsplines.take_first( + ddc::DiscreteVector {BSplinesR_Polar::degree()})); BSDomainRP non_singular_domain_near_centre(central_radial_bspline_domain, polar_bsplines); // Calculate the matrix elements where bspline products overlap the bsplines which cover the singular point ddc::for_each(singular_domain, [&](IDimPolarBspl const idx_test) { - ddc::for_each(non_singular_domain_near_centre, [&](IDimBSpline2D const idx_trial) { - const IDimPolarBspl polar_idx_trial(PolarBSplinesRP::get_polar_index(idx_trial)); - const ddc::DiscreteElement r_idx_trial( - ddc::select(idx_trial)); - const ddc::DiscreteElement p_idx_trial( - ddc::select(idx_trial)); - - // Find the domain covering the cells where both the test and trial functions are non-zero - const ddc::DiscreteElement first_overlap_element_r( - r_idx_trial.uid() < BSplinesR::degree() - ? 0 - : r_idx_trial.uid() - BSplinesR::degree()); - const ddc::DiscreteElement first_overlap_element_p( - pmod(p_idx_trial.uid() - BSplinesP::degree())); - - const ddc::DiscreteVector n_overlap_r( - n_overlap_cells - first_overlap_element_r.uid()); - const ddc::DiscreteVector n_overlap_p(BSplinesP::degree() + 1); - - const ddc::DiscreteDomain r_cells(first_overlap_element_r, n_overlap_r); - const ddc::DiscreteDomain p_cells(first_overlap_element_p, n_overlap_p); - const ddc::DiscreteDomain non_zero_cells(r_cells, p_cells); - - if (n_overlap_r > 0) { - double element = 0.0; - - ddc::for_each(non_zero_cells, [&](CellIndex const cell_idx) { - const int cell_idx_r(ddc::select(cell_idx).uid()); - const int cell_idx_p(pmod(ddc::select(cell_idx).uid())); - - const QuadratureDomainRP cell_quad_points( - get_quadrature_points_in_cell(cell_idx_r, cell_idx_p)); - // Find the column where the non-zero data is stored - ddc::DiscreteElement ib_trial_r( - r_idx_trial.uid() - cell_idx_r); - ddc::DiscreteElement ib_trial_p( - pmod(p_idx_trial.uid() - cell_idx_p)); - // Calculate the weak integral - element += ddc::transform_reduce( - cell_quad_points, - 0.0, - ddc::reducer::sum(), - [&](QuadratureIndexRP const quad_idx) { - QuadratureIndexR const ir = ddc::select(quad_idx); - QuadratureIndexP const ip = ddc::select(quad_idx); - return weak_integral_element( - ir, - ip, - singular_basis_vals_and_derivs(idx_test, ir, ip), - r_basis_vals_and_derivs(ib_trial_r, ir), - p_basis_vals_and_derivs(ib_trial_p, ip), - coeff_alpha, - coeff_beta, - spline_evaluator, - mapping); - }); + ddc::for_each( + non_singular_domain_near_centre, + [&](IDimBSpline2D_Polar const idx_trial) { + const IDimPolarBspl polar_idx_trial( + PolarBSplinesRP::get_polar_index(idx_trial)); + const ddc::DiscreteElement r_idx_trial( + ddc::select(idx_trial)); + const ddc::DiscreteElement p_idx_trial( + ddc::select(idx_trial)); + + // Find the domain covering the cells where both the test and trial functions are non-zero + const ddc::DiscreteElement first_overlap_element_r( + r_idx_trial.uid() < BSplinesR_Polar::degree() + ? 0 + : r_idx_trial.uid() - BSplinesR_Polar::degree()); + const ddc::DiscreteElement first_overlap_element_p( + pmod(p_idx_trial.uid() - BSplinesP_Polar::degree())); + + const ddc::DiscreteVector n_overlap_r( + n_overlap_cells - first_overlap_element_r.uid()); + const ddc::DiscreteVector n_overlap_p( + BSplinesP_Polar::degree() + 1); + + const ddc::DiscreteDomain + r_cells(first_overlap_element_r, n_overlap_r); + const ddc::DiscreteDomain + p_cells(first_overlap_element_p, n_overlap_p); + const ddc::DiscreteDomain + non_zero_cells(r_cells, p_cells); + + if (n_overlap_r > 0) { + double element = 0.0; + + ddc::for_each(non_zero_cells, [&](CellIndex const cell_idx) { + const int cell_idx_r(ddc::select(cell_idx).uid()); + const int cell_idx_p(pmod(ddc::select(cell_idx).uid())); + + const QuadratureDomainRP cell_quad_points( + get_quadrature_points_in_cell(cell_idx_r, cell_idx_p)); + // Find the column where the non-zero data is stored + ddc::DiscreteElement ib_trial_r( + r_idx_trial.uid() - cell_idx_r); + ddc::DiscreteElement ib_trial_p( + pmod(p_idx_trial.uid() - cell_idx_p)); + // Calculate the weak integral + element += ddc::transform_reduce( + cell_quad_points, + 0.0, + ddc::reducer::sum(), + [&](QuadratureIndexRP const quad_idx) { + QuadratureIndexR const ir + = ddc::select(quad_idx); + QuadratureIndexP const ip + = ddc::select(quad_idx); + return weak_integral_element( + ir, + ip, + singular_basis_vals_and_derivs( + idx_test, + ir, + ip), + r_basis_vals_and_derivs(ib_trial_r, ir), + p_basis_vals_and_derivs(ib_trial_p, ip), + coeff_alpha, + coeff_beta, + spline_evaluator, + mapping); + }); + }); + matrix_elements[matrix_idx++] + = MatrixElement(idx_test.uid(), polar_idx_trial.uid(), element); + matrix_elements[matrix_idx++] + = MatrixElement(polar_idx_trial.uid(), idx_test.uid(), element); + } }); - matrix_elements[matrix_idx++] - = MatrixElement(idx_test.uid(), polar_idx_trial.uid(), element); - matrix_elements[matrix_idx++] - = MatrixElement(polar_idx_trial.uid(), idx_test.uid(), element); - } - }); }); assert(matrix_idx == n_elements_singular + n_elements_overlap); // Calculate the matrix elements following a stencil ddc::for_each(fem_non_singular_domain, [&](IDimPolarBspl const polar_idx_test) { - const IDimBSpline2D idx_test(PolarBSplinesRP::get_2d_index(polar_idx_test)); - const std::size_t r_idx_test(ddc::select(idx_test).uid()); - const std::size_t p_idx_test(ddc::select(idx_test).uid()); + const IDimBSpline2D_Polar idx_test(PolarBSplinesRP::get_2d_index(polar_idx_test)); + const std::size_t r_idx_test( + ddc::select(idx_test).uid()); + const std::size_t p_idx_test( + ddc::select(idx_test).uid()); // Calculate the index of the elements that are already filled - BSDomainP remaining_p( - ddc::DiscreteElement {p_idx_test}, - ddc::DiscreteVector {BSplinesP::degree() + 1}); + BSDomainP_Polar remaining_p( + ddc::DiscreteElement {p_idx_test}, + ddc::DiscreteVector {BSplinesP_Polar::degree() + 1}); ddc::for_each(remaining_p, [&](auto const p_idx_trial) { - IDimBSpline2D idx_trial(ddc::DiscreteElement(r_idx_test), p_idx_trial); + IDimBSpline2D_Polar + idx_trial(ddc::DiscreteElement(r_idx_test), p_idx_trial); IDimPolarBspl polar_idx_trial(PolarBSplinesRP::get_polar_index( - IDimBSpline2D(r_idx_test, pmod(p_idx_trial.uid())))); + IDimBSpline2D_Polar(r_idx_test, pmod(p_idx_trial.uid())))); double element = get_matrix_stencil_element( idx_test, idx_trial, @@ -536,23 +562,23 @@ class PolarSplineFEMPoissonSolver } }); BSDomainR remaining_r( - ddc::select(idx_test) + 1, - ddc::DiscreteVector { - min(BSplinesR::degree(), - ddc::discrete_space().nbasis() - 2 - r_idx_test)}); - BSDomainP relevant_p( - ddc::DiscreteElement { - p_idx_test + ddc::discrete_space().nbasis() - - BSplinesP::degree()}, - ddc::DiscreteVector {2 * BSplinesP::degree() + 1}); + ddc::select(idx_test) + 1, + ddc::DiscreteVector { + min(BSplinesR_Polar::degree(), + ddc::discrete_space().nbasis() - 2 - r_idx_test)}); + BSDomainP_Polar relevant_p( + ddc::DiscreteElement { + p_idx_test + ddc::discrete_space().nbasis() + - BSplinesP_Polar::degree()}, + ddc::DiscreteVector {2 * BSplinesP_Polar::degree() + 1}); BSDomainRP trial_domain(remaining_r, relevant_p); - ddc::for_each(trial_domain, [&](IDimBSpline2D const idx_trial) { - const int r_idx_trial(ddc::select(idx_trial).uid()); - const int p_idx_trial(ddc::select(idx_trial).uid()); + ddc::for_each(trial_domain, [&](IDimBSpline2D_Polar const idx_trial) { + const int r_idx_trial(ddc::select(idx_trial).uid()); + const int p_idx_trial(ddc::select(idx_trial).uid()); IDimPolarBspl polar_idx_trial(PolarBSplinesRP::get_polar_index( - IDimBSpline2D(r_idx_trial, pmod(p_idx_trial)))); + IDimBSpline2D_Polar(r_idx_trial, pmod(p_idx_trial)))); double element = get_matrix_stencil_element( idx_test, idx_trial, @@ -595,7 +621,7 @@ class PolarSplineFEMPoissonSolver { Eigen::VectorXd b( ddc::discrete_space().nbasis() - - ddc::discrete_space().nbasis()); + - ddc::discrete_space().nbasis()); // Fill b ddc::for_each(PolarBSplinesRP::singular_domain(), [&](IDimPolarBspl const idx) { @@ -611,22 +637,22 @@ class PolarSplineFEMPoissonSolver * int_volume(ir, ip); }); }); - const std::size_t ncells_r = ddc::discrete_space().ncells(); + const std::size_t ncells_r = ddc::discrete_space().ncells(); ddc::for_each(fem_non_singular_domain, [&](IDimPolarBspl const idx) { - const IDimBSpline2D idx_2d(PolarBSplinesRP::get_2d_index(idx)); - const std::size_t r_idx(ddc::select(idx_2d).uid()); - const std::size_t p_idx(ddc::select(idx_2d).uid()); + const IDimBSpline2D_Polar idx_2d(PolarBSplinesRP::get_2d_index(idx)); + const std::size_t r_idx(ddc::select(idx_2d).uid()); + const std::size_t p_idx(ddc::select(idx_2d).uid()); // Find the cells on which the bspline is non-zero - int first_cell_r(r_idx - BSplinesR::degree()); - int first_cell_p(p_idx - BSplinesP::degree()); + int first_cell_r(r_idx - BSplinesR_Polar::degree()); + int first_cell_p(p_idx - BSplinesP_Polar::degree()); std::size_t last_cell_r(r_idx + 1); if (first_cell_r < 0) first_cell_r = 0; if (last_cell_r > ncells_r) last_cell_r = ncells_r; ddc::DiscreteVector const r_length(last_cell_r - first_cell_r); - ddc::DiscreteVector const p_length(BSplinesP::degree() + 1); + ddc::DiscreteVector const p_length(BSplinesP_Polar::degree() + 1); ddc::DiscreteElement const start_r(first_cell_r); @@ -667,13 +693,10 @@ class PolarSplineFEMPoissonSolver // Solve the matrix equation Eigen::VectorXd x = m_matrix.solve(b); - BSDomainRP non_singular_2d_domain( - radial_bsplines.remove_last(ddc::DiscreteVector {1}), - polar_bsplines); BSDomainRP dirichlet_boundary_domain( - radial_bsplines.take_last(ddc::DiscreteVector {1}), + radial_bsplines.take_last(ddc::DiscreteVector {1}), polar_bsplines); - BSDomainP polar_domain(ddc::discrete_space().full_domain()); + BSDomainP_Polar polar_domain(ddc::discrete_space().full_domain()); // Fill the spline @@ -681,24 +704,26 @@ class PolarSplineFEMPoissonSolver spline.singular_spline_coef(idx) = x(idx.uid()); }); ddc::for_each(fem_non_singular_domain, [&](IDimPolarBspl const idx) { - const IDimBSpline2D idx_2d(PolarBSplinesRP::get_2d_index(idx)); + const IDimBSpline2D_Polar idx_2d(PolarBSplinesRP::get_2d_index(idx)); spline.spline_coef(idx_2d) = x(idx.uid()); }); - ddc::for_each(dirichlet_boundary_domain, [&](IDimBSpline2D const idx) { + ddc::for_each(dirichlet_boundary_domain, [&](IDimBSpline2D_Polar const idx) { spline.spline_coef(idx) = 0.0; }); // Copy the periodic elements BSDomainRP copy_domain( radial_bsplines, - polar_domain.remove_first( - ddc::DiscreteVector(ddc::discrete_space().nbasis()))); - ddc::for_each(copy_domain, [&](IDimBSpline2D const idx_2d) { - spline.spline_coef(ddc::select(idx_2d), ddc::select(idx_2d)) + polar_domain.remove_first(ddc::DiscreteVector( + ddc::discrete_space().nbasis()))); + ddc::for_each(copy_domain, [&](IDimBSpline2D_Polar const idx_2d) { + spline.spline_coef( + ddc::select(idx_2d), + ddc::select(idx_2d)) = spline.spline_coef( - ddc::select(idx_2d), - ddc::select(idx_2d) - - ddc::discrete_space().nbasis()); + ddc::select(idx_2d), + ddc::select(idx_2d) + - ddc::discrete_space().nbasis()); }); } @@ -721,7 +746,7 @@ class PolarSplineFEMPoissonSolver template void operator()(RHSFunction const& rhs, ViewRP const coords_eval, DSpanRP result) const { - BSDomainP polar_domain(ddc::discrete_space().full_domain()); + BSDomainP_Polar polar_domain(ddc::discrete_space().full_domain()); SplinePolar spline(PolarBSplinesRP::singular_domain(), BSDomainRP(radial_bsplines, polar_domain)); @@ -751,7 +776,7 @@ class PolarSplineFEMPoissonSolver EvalDeriv2DType const& trial_bspline_val_and_deriv, Spline2DView coeff_alpha, Spline2DView coeff_beta, - SplineRPEvaluator const& evaluator, + SplineRPEvaluatorNullBound const& evaluator, Mapping const& mapping) { return templated_weak_integral_element( @@ -776,7 +801,7 @@ class PolarSplineFEMPoissonSolver EvalDeriv1DType const& trial_bspline_val_and_deriv_p, Spline2DView coeff_alpha, Spline2DView coeff_beta, - SplineRPEvaluator const& evaluator, + SplineRPEvaluatorNullBound const& evaluator, Mapping const& mapping) { return templated_weak_integral_element( @@ -801,7 +826,7 @@ class PolarSplineFEMPoissonSolver EvalDeriv1DType const& test_bspline_val_and_deriv_p, Spline2DView coeff_alpha, Spline2DView coeff_beta, - SplineRPEvaluator const& evaluator, + SplineRPEvaluatorNullBound const& evaluator, Mapping const& mapping) { return templated_weak_integral_element( @@ -827,7 +852,7 @@ class PolarSplineFEMPoissonSolver EvalDeriv1DType const& trial_bspline_val_and_deriv_p, Spline2DView coeff_alpha, Spline2DView coeff_beta, - SplineRPEvaluator const& evaluator, + SplineRPEvaluatorNullBound const& evaluator, Mapping const& mapping) { return templated_weak_integral_element( @@ -882,7 +907,7 @@ class PolarSplineFEMPoissonSolver TrialValDerivType const& trial_bspline_val_and_deriv_p, Spline2DView coeff_alpha, Spline2DView coeff_beta, - SplineRPEvaluator const& spline_evaluator, + SplineRPEvaluatorNullBound const& spline_evaluator, Mapping const& mapping) { static_assert( @@ -930,50 +955,50 @@ class PolarSplineFEMPoissonSolver */ template double get_matrix_stencil_element( - IDimBSpline2D idx_test, - IDimBSpline2D idx_trial, + IDimBSpline2D_Polar idx_test, + IDimBSpline2D_Polar idx_trial, Spline2DView coeff_alpha, Spline2DView coeff_beta, - SplineRPEvaluator const& evaluator, + SplineRPEvaluatorNullBound const& evaluator, Mapping const& mapping) { // 0 <= r_idx_test < 8 // 0 <= r_idx_trial < 8 // r_idx_test < r_idx_trial - const int r_idx_test(ddc::select(idx_test).uid()); - const int r_idx_trial(ddc::select(idx_trial).uid()); + const int r_idx_test(ddc::select(idx_test).uid()); + const int r_idx_trial(ddc::select(idx_trial).uid()); // 0 <= p_idx_test < 8 // 0 <= p_idx_trial < 8 - int p_idx_test(pmod(ddc::select(idx_test).uid())); - int p_idx_trial(pmod(ddc::select(idx_trial).uid())); + int p_idx_test(pmod(ddc::select(idx_test).uid())); + int p_idx_trial(pmod(ddc::select(idx_trial).uid())); - const std::size_t ncells_r = ddc::discrete_space().ncells(); - const std::size_t nbasis_p = ddc::discrete_space().nbasis(); + const std::size_t ncells_r = ddc::discrete_space().ncells(); + const std::size_t nbasis_p = ddc::discrete_space().nbasis(); // 0<= r_offset <= degree_r // -degree_p <= p_offset <= degree_p const int r_offset = r_idx_trial - r_idx_test; int p_offset = pmod(p_idx_trial - p_idx_test); - if (p_offset >= int(nbasis_p - BSplinesP::degree())) { + if (p_offset >= int(nbasis_p - BSplinesP_Polar::degree())) { p_offset -= nbasis_p; } assert(r_offset >= 0); - assert(r_offset <= int(BSplinesR::degree())); - assert(p_offset >= -int(BSplinesP::degree())); - assert(p_offset <= int(BSplinesP::degree())); + assert(r_offset <= int(BSplinesR_Polar::degree())); + assert(p_offset >= -int(BSplinesP_Polar::degree())); + assert(p_offset <= int(BSplinesP_Polar::degree())); // Find the domain covering the cells where both the test and trial functions are non-zero - int n_overlap_stencil_r(BSplinesR::degree() + 1 - r_offset); - int first_overlap_r(r_idx_trial - BSplinesR::degree()); + int n_overlap_stencil_r(BSplinesR_Polar::degree() + 1 - r_offset); + int first_overlap_r(r_idx_trial - BSplinesR_Polar::degree()); int first_overlap_p; int n_overlap_stencil_p; if (p_offset > 0) { - n_overlap_stencil_p = BSplinesP::degree() + 1 - p_offset; - first_overlap_p = pmod(p_idx_trial - BSplinesP::degree()); + n_overlap_stencil_p = BSplinesP_Polar::degree() + 1 - p_offset; + first_overlap_p = pmod(p_idx_trial - BSplinesP_Polar::degree()); } else { - n_overlap_stencil_p = BSplinesP::degree() + 1 + p_offset; - first_overlap_p = pmod(p_idx_test - BSplinesP::degree()); + n_overlap_stencil_p = BSplinesP_Polar::degree() + 1 + p_offset; + first_overlap_p = pmod(p_idx_test - BSplinesP_Polar::degree()); } if (first_overlap_r < 0) { @@ -1015,10 +1040,10 @@ class PolarSplineFEMPoissonSolver ddc::DiscreteElement ib_trial_r(r_idx_trial - cell_idx_r); ddc::DiscreteElement ib_trial_p(pmod(ib_trial_p_idx)); - assert(ib_test_r.uid() < BSplinesR::degree() + 1); - assert(ib_test_p.uid() < BSplinesP::degree() + 1); - assert(ib_trial_r.uid() < BSplinesR::degree() + 1); - assert(ib_trial_p.uid() < BSplinesP::degree() + 1); + assert(ib_test_r.uid() < BSplinesR_Polar::degree() + 1); + assert(ib_test_p.uid() < BSplinesP_Polar::degree() + 1); + assert(ib_trial_r.uid() < BSplinesR_Polar::degree() + 1); + assert(ib_trial_p.uid() < BSplinesP_Polar::degree() + 1); // Calculate the weak integral return ddc::transform_reduce( @@ -1055,7 +1080,7 @@ class PolarSplineFEMPoissonSolver static int pmod(int idx_p) { - int ncells_p = ddc::discrete_space().ncells(); + int ncells_p = ddc::discrete_space().ncells(); while (idx_p < 0) idx_p += ncells_p; while (idx_p >= ncells_p) diff --git a/src/geometryRTheta/time_solver/CMakeLists.txt b/src/geometryRTheta/time_solver/CMakeLists.txt index 9c4f3f54e..67974f58e 100644 --- a/src/geometryRTheta/time_solver/CMakeLists.txt +++ b/src/geometryRTheta/time_solver/CMakeLists.txt @@ -9,7 +9,7 @@ target_include_directories(time_integration_rp target_link_libraries(time_integration_rp INTERFACE DDC::DDC - sll::splines + sll::SLL Eigen3::Eigen gslx::interpolation_2D_rp gslx::geometry_RTheta diff --git a/src/geometryRTheta/time_solver/bsl_predcorr.hpp b/src/geometryRTheta/time_solver/bsl_predcorr.hpp index 021b8990d..cbd509fa7 100644 --- a/src/geometryRTheta/time_solver/bsl_predcorr.hpp +++ b/src/geometryRTheta/time_solver/bsl_predcorr.hpp @@ -12,8 +12,6 @@ #include #include -#include "sll/spline_evaluator_2d.hpp" - #include "advection_domain.hpp" #include "advection_field_rp.hpp" #include "bsl_advection_rp.hpp" @@ -67,7 +65,7 @@ class BslPredCorrRP : public ITimeSolverRP PolarSplineFEMPoissonSolver const& m_poisson_solver; SplineRPBuilder const& m_builder; - SplineRPEvaluator const& m_spline_evaluator; + SplineRPEvaluatorNullBound const& m_spline_evaluator; public: @@ -92,7 +90,7 @@ class BslPredCorrRP : public ITimeSolverRP Mapping const& mapping, BslAdvectionRP const& advection_solver, SplineRPBuilder const& builder, - SplineRPEvaluator const& rhs_evaluator, + SplineRPEvaluatorNullBound const& rhs_evaluator, PolarSplineFEMPoissonSolver const& poisson_solver) : m_mapping(mapping) , m_advection_solver(advection_solver) @@ -126,15 +124,17 @@ class BslPredCorrRP : public ITimeSolverRP SplinePolar electrostatic_potential_coef( PolarBSplinesRP::singular_domain(), BSDomainRP(radial_bsplines, polar_domain)); - PolarSplineEvaluator polar_spline_evaluator( - g_polar_null_boundary_2d); + ddc::NullExtrapolationRule extrapolation_rule; + PolarSplineEvaluator polar_spline_evaluator( + extrapolation_rule); DFieldRP electrical_potential0(grid); Spline2D allfdistribu_coef(m_builder.spline_domain()); - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord(allfdistribu_coef, m_spline_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const + charge_density_coord(allfdistribu_coef.span_cview(), m_spline_evaluator); m_poisson_solver(charge_density_coord, coords, electrical_potential0); ddc::PdiEvent("iteration") @@ -148,9 +148,10 @@ class BslPredCorrRP : public ITimeSolverRP = [&](VectorDSpanRP advection_field, DViewRP allfdistribu) { // --- compute electrostatic potential: Spline2D allfdistribu_coef(m_builder.spline_domain()); - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const - charge_density_coord(allfdistribu_coef, m_spline_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const charge_density_coord( + allfdistribu_coef.span_cview(), + m_spline_evaluator); m_poisson_solver(charge_density_coord, electrostatic_potential_coef); // --- compute advection field: @@ -175,8 +176,9 @@ class BslPredCorrRP : public ITimeSolverRP DFieldRP electrical_potential(grid); Spline2D allfdistribu_coef(m_builder.spline_domain()); - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord(allfdistribu_coef, m_spline_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const + charge_density_coord(allfdistribu_coef.span_cview(), m_spline_evaluator); m_poisson_solver(charge_density_coord, coords, electrical_potential); ddc::PdiEvent("iteration") diff --git a/src/geometryRTheta/time_solver/bsl_predcorr_second_order_explicit.hpp b/src/geometryRTheta/time_solver/bsl_predcorr_second_order_explicit.hpp index 61f2ab73f..c68496764 100644 --- a/src/geometryRTheta/time_solver/bsl_predcorr_second_order_explicit.hpp +++ b/src/geometryRTheta/time_solver/bsl_predcorr_second_order_explicit.hpp @@ -11,8 +11,6 @@ #include -#include "sll/spline_evaluator_2d.hpp" - #include "advection_domain.hpp" #include "advection_field_rp.hpp" #include "bsl_advection_rp.hpp" @@ -82,7 +80,7 @@ class BslExplicitPredCorrRP : public ITimeSolverRP PolarSplineFEMPoissonSolver const& m_poisson_solver; SplineRPBuilder const& m_builder; - SplineRPEvaluator const& m_evaluator; + SplineRPEvaluatorConstBound const& m_evaluator; @@ -118,9 +116,9 @@ class BslExplicitPredCorrRP : public ITimeSolverRP advection_solver, IDomainRP const& grid, SplineRPBuilder const& builder, - SplineRPEvaluator const& rhs_evaluator, + SplineRPEvaluatorNullBound const& rhs_evaluator, PolarSplineFEMPoissonSolver const& poisson_solver, - SplineRPEvaluator const& advection_evaluator) + SplineRPEvaluatorConstBound const& advection_evaluator) : m_mapping(mapping) , m_advection_solver(advection_solver) , m_euler(grid) @@ -160,8 +158,9 @@ class BslExplicitPredCorrRP : public ITimeSolverRP PolarBSplinesRP::singular_domain(), BSDomainRP(radial_bsplines, polar_domain)); - PolarSplineEvaluator polar_spline_evaluator( - g_polar_null_boundary_2d); + ddc::NullExtrapolationRule extrapolation_rule; + PolarSplineEvaluator polar_spline_evaluator( + extrapolation_rule); // --- For the computation of advection field from the electrostatic potential (phi): ------------- VectorDFieldRP electric_field(grid); @@ -179,8 +178,9 @@ class BslExplicitPredCorrRP : public ITimeSolverRP double const time = iter * dt; // STEP 1: From rho^n, we compute phi^n: Poisson equation Spline2D allfdistribu_coef(m_builder.spline_domain()); - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord_1(allfdistribu_coef, m_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const + charge_density_coord_1(allfdistribu_coef.span_cview(), m_evaluator); m_poisson_solver(charge_density_coord_1, electrostatic_potential_coef); polar_spline_evaluator( @@ -213,8 +213,9 @@ class BslExplicitPredCorrRP : public ITimeSolverRP // STEP 4: From rho^P, we compute phi^P: Poisson equation - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord_4(allfdistribu_coef, m_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const + charge_density_coord_4(allfdistribu_coef.span_cview(), m_evaluator); m_poisson_solver(charge_density_coord_4, electrostatic_potential_coef); // STEP 5: From phi^P, we compute A^P: @@ -227,19 +228,19 @@ class BslExplicitPredCorrRP : public ITimeSolverRP m_builder( ddcHelper::get(advection_field_coefs), - ddcHelper::get(advection_field)); + ddcHelper::get(advection_field.span_cview())); m_builder( ddcHelper::get(advection_field_coefs), - ddcHelper::get(advection_field)); + ddcHelper::get(advection_field.span_cview())); m_evaluator( ddcHelper::get(advection_field_evaluated).span_view(), feet_coords.span_cview(), - ddcHelper::get(advection_field_coefs)); + ddcHelper::get(advection_field_coefs.span_cview())); m_evaluator( ddcHelper::get(advection_field_evaluated).span_view(), feet_coords.span_cview(), - ddcHelper::get(advection_field_coefs)); + ddcHelper::get(advection_field_coefs.span_cview())); // STEP 6: From rho^n and (A^n(X^P) + A^P(X^n))/2, we compute rho^{n+1}: Vlasov equation @@ -260,8 +261,8 @@ class BslExplicitPredCorrRP : public ITimeSolverRP // STEP 1: From rho^n, we compute phi^n: Poisson equation Spline2D allfdistribu_coef(m_builder.spline_domain()); - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord(allfdistribu_coef, m_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const charge_density_coord(allfdistribu_coef.span_cview(), m_evaluator); m_poisson_solver(charge_density_coord, coords, electrical_potential); ddc::PdiEvent("last_iteration") diff --git a/src/geometryRTheta/time_solver/bsl_predcorr_second_order_implicit.hpp b/src/geometryRTheta/time_solver/bsl_predcorr_second_order_implicit.hpp index 168eb399e..6392c6bc0 100644 --- a/src/geometryRTheta/time_solver/bsl_predcorr_second_order_implicit.hpp +++ b/src/geometryRTheta/time_solver/bsl_predcorr_second_order_implicit.hpp @@ -11,8 +11,6 @@ #include -#include "sll/spline_evaluator_2d.hpp" - #include "advection_domain.hpp" #include "advection_field_rp.hpp" #include "bsl_advection_rp.hpp" @@ -82,7 +80,7 @@ class BslImplicitPredCorrRP : public ITimeSolverRP PolarSplineFEMPoissonSolver const& m_poisson_solver; SplineRPBuilder const& m_builder; - SplineRPEvaluator const& m_evaluator; + SplineRPEvaluatorConstBound const& m_evaluator; @@ -118,9 +116,9 @@ class BslImplicitPredCorrRP : public ITimeSolverRP advection_solver, IDomainRP const& grid, SplineRPBuilder const& builder, - SplineRPEvaluator const& rhs_evaluator, + SplineRPEvaluatorNullBound const& rhs_evaluator, PolarSplineFEMPoissonSolver const& poisson_solver, - SplineRPEvaluator const& advection_evaluator) + SplineRPEvaluatorConstBound const& advection_evaluator) : m_mapping(mapping) , m_advection_solver(advection_solver) , m_euler(grid) @@ -160,8 +158,9 @@ class BslImplicitPredCorrRP : public ITimeSolverRP PolarBSplinesRP::singular_domain(), BSDomainRP(radial_bsplines, polar_domain)); - PolarSplineEvaluator polar_spline_evaluator( - g_polar_null_boundary_2d); + ddc::NullExtrapolationRule extrapolation_rule; + PolarSplineEvaluator polar_spline_evaluator( + extrapolation_rule); // --- For the computation of advection field from the electrostatic potential (phi): ------------- VectorDFieldRP electric_field(grid); @@ -175,8 +174,9 @@ class BslImplicitPredCorrRP : public ITimeSolverRP for (int iter(0); iter < steps; ++iter) { // STEP 1: From rho^n, we compute phi^n: Poisson equation Spline2D allfdistribu_coef(m_builder.spline_domain()); - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord_1(allfdistribu_coef, m_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const + charge_density_coord_1(allfdistribu_coef.span_cview(), m_evaluator); m_poisson_solver(charge_density_coord_1, electrostatic_potential_coef); polar_spline_evaluator( @@ -202,10 +202,10 @@ class BslImplicitPredCorrRP : public ITimeSolverRP VectorSpline2D advection_field_coefs_k(m_builder.spline_domain()); m_builder( ddcHelper::get(advection_field_coefs_k), - ddcHelper::get(advection_field)); + ddcHelper::get(advection_field.span_cview())); m_builder( ddcHelper::get(advection_field_coefs_k), - ddcHelper::get(advection_field)); + ddcHelper::get(advection_field.span_cview())); FieldRP feet_coords(grid); FieldRP feet_coords_tmp(grid); @@ -223,11 +223,11 @@ class BslImplicitPredCorrRP : public ITimeSolverRP m_evaluator( ddcHelper::get(advection_field_k).span_view(), feet_coords.span_cview(), - ddcHelper::get(advection_field_coefs_k)); + ddcHelper::get(advection_field_coefs_k.span_cview())); m_evaluator( ddcHelper::get(advection_field_k).span_view(), feet_coords.span_cview(), - ddcHelper::get(advection_field_coefs_k)); + ddcHelper::get(advection_field_coefs_k.span_cview())); // Compute the new advection field (E^n(X^n) + E^n(X^P)) /2: ddc::for_each(grid, [&](IndexRP const irp) { @@ -259,8 +259,9 @@ class BslImplicitPredCorrRP : public ITimeSolverRP // STEP 4: From rho^P, we compute phi^P: Poisson equation - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord_4(allfdistribu_coef, m_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const + charge_density_coord_4(allfdistribu_coef.span_cview(), m_evaluator); m_poisson_solver(charge_density_coord_4, electrostatic_potential_coef); // STEP 5: From phi^P, we compute A^P: @@ -270,10 +271,10 @@ class BslImplicitPredCorrRP : public ITimeSolverRP // STEP 6: From rho^n and A^P, we compute rho^{n+1}: Vlasov equation m_builder( ddcHelper::get(advection_field_coefs_k), - ddcHelper::get(advection_field)); + ddcHelper::get(advection_field.span_cview())); m_builder( ddcHelper::get(advection_field_coefs_k), - ddcHelper::get(advection_field)); + ddcHelper::get(advection_field.span_cview())); // initialisation: @@ -287,11 +288,11 @@ class BslImplicitPredCorrRP : public ITimeSolverRP m_evaluator( ddcHelper::get(advection_field_k).span_view(), feet_coords.span_cview(), - ddcHelper::get(advection_field_coefs_k)); + ddcHelper::get(advection_field_coefs_k.span_cview())); m_evaluator( ddcHelper::get(advection_field_k).span_view(), feet_coords.span_cview(), - ddcHelper::get(advection_field_coefs_k)); + ddcHelper::get(advection_field_coefs_k.span_cview())); // Computed advection field (A^P(X^n) + A^P(X^P)) /2: ddc::for_each(grid, [&](IndexRP const irp) { @@ -310,8 +311,8 @@ class BslImplicitPredCorrRP : public ITimeSolverRP // STEP 1: From rho^n, we compute phi^n: Poisson equation Spline2D allfdistribu_coef(m_builder.spline_domain()); - m_builder(allfdistribu_coef, allfdistribu); - PoissonRHSFunction const charge_density_coord(allfdistribu_coef, m_evaluator); + m_builder(allfdistribu_coef.span_view(), allfdistribu.span_cview()); + PoissonRHSFunction const charge_density_coord(allfdistribu_coef.span_cview(), m_evaluator); m_poisson_solver(charge_density_coord, coords, electrical_potential); ddc::PdiEvent("last_iteration") diff --git a/src/geometryXVx/rhs/CMakeLists.txt b/src/geometryXVx/rhs/CMakeLists.txt index 82ba2846d..8553aff7c 100644 --- a/src/geometryXVx/rhs/CMakeLists.txt +++ b/src/geometryXVx/rhs/CMakeLists.txt @@ -24,7 +24,7 @@ target_link_libraries("rhs_${GEOMETRY_VARIANT}" PUBLIC DDC::DDC DDC::PDI_Wrapper - sll::splines + sll::SLL gslx::geometry_${GEOMETRY_VARIANT} gslx::quadrature gslx::speciesinfo diff --git a/src/geometryXYVxVy/poisson/CMakeLists.txt b/src/geometryXYVxVy/poisson/CMakeLists.txt index d4b25c852..e0f46a0f6 100644 --- a/src/geometryXYVxVy/poisson/CMakeLists.txt +++ b/src/geometryXYVxVy/poisson/CMakeLists.txt @@ -18,7 +18,7 @@ target_include_directories("poisson_xy" target_link_libraries("poisson_xy" PUBLIC DDC::DDC - sll::splines + sll::SLL gslx::geometry_xyvxvy gslx::speciesinfo gslx::utils diff --git a/src/geometryXYVxVy/poisson/fftpoissonsolver.cpp b/src/geometryXYVxVy/poisson/fftpoissonsolver.cpp index 89517f698..2fe450f22 100644 --- a/src/geometryXYVxVy/poisson/fftpoissonsolver.cpp +++ b/src/geometryXYVxVy/poisson/fftpoissonsolver.cpp @@ -7,11 +7,6 @@ #include -#include -#include -#include -#include - #include #include "fftpoissonsolver.hpp" diff --git a/src/geometryXYVxVy/vlasov/CMakeLists.txt b/src/geometryXYVxVy/vlasov/CMakeLists.txt index 1a4d68dd8..aba781dbf 100644 --- a/src/geometryXYVxVy/vlasov/CMakeLists.txt +++ b/src/geometryXYVxVy/vlasov/CMakeLists.txt @@ -16,7 +16,7 @@ target_include_directories("vlasov_xyvxvy" target_link_libraries("vlasov_xyvxvy" PUBLIC DDC::DDC - sll::splines + sll::SLL gslx::speciesinfo gslx::geometry_xyvxvy gslx::advection diff --git a/src/interpolation/CMakeLists.txt b/src/interpolation/CMakeLists.txt index d60c2ecc5..01c4a2010 100644 --- a/src/interpolation/CMakeLists.txt +++ b/src/interpolation/CMakeLists.txt @@ -14,7 +14,7 @@ target_include_directories("interpolation" target_link_libraries("interpolation" INTERFACE DDC::DDC - sll::splines + sll::SLL gslx::utils ) diff --git a/src/interpolation/README.md b/src/interpolation/README.md index 55b46fd2e..929ce64af 100644 --- a/src/interpolation/README.md +++ b/src/interpolation/README.md @@ -17,7 +17,7 @@ Interpolation by a spline interpolating function is implemented in the class Spl In order for the interpolation to function correctly the values $`f_j=f(x_j)`$ provided must be located at the points $`x_j`$ identified as the spline interpolation points. -The spline interpolation method is based entirely on the SplineBuilder and SplineEvaluator classes which are found in [sll](../../vendor/sll). +The spline interpolation method is based entirely on the SplineBuilder and SplineEvaluator classes which are found in DDC. ## Memory concerns diff --git a/src/quadrature/CMakeLists.txt b/src/quadrature/CMakeLists.txt index 62cf2ddf8..3a6148c8b 100644 --- a/src/quadrature/CMakeLists.txt +++ b/src/quadrature/CMakeLists.txt @@ -7,7 +7,7 @@ target_include_directories(quadrature ) target_link_libraries(quadrature INTERFACE DDC::DDC - sll::splines + sll::SLL ) add_library(gslx::quadrature ALIAS quadrature) diff --git a/src/quadrature/spline_quadrature.hpp b/src/quadrature/spline_quadrature.hpp index 3c5da62ba..662a242a0 100644 --- a/src/quadrature/spline_quadrature.hpp +++ b/src/quadrature/spline_quadrature.hpp @@ -11,11 +11,7 @@ #include -#include #include -#include -#include -#include @@ -79,7 +75,7 @@ ddc::Chunk> spline_quadrature_coefficients_1d( // Vector of integrals of B-splines ddc::Chunk> integral_bsplines( builder.spline_domain()); - ddc::discrete_space().integrals(integral_bsplines); + ddc::discrete_space().integrals(integral_bsplines.span_view()); // Coefficients of quadrature in integral_bsplines ddc::DiscreteDomain slice = builder.spline_domain().take_first( diff --git a/src/speciesinfo/CMakeLists.txt b/src/speciesinfo/CMakeLists.txt index b1117a9f5..4f09ab8c0 100644 --- a/src/speciesinfo/CMakeLists.txt +++ b/src/speciesinfo/CMakeLists.txt @@ -9,6 +9,6 @@ target_include_directories(speciesinfo ) target_link_libraries(speciesinfo INTERFACE DDC::DDC - sll::splines + sll::SLL ) add_library(gslx::speciesinfo ALIAS speciesinfo) diff --git a/tests/geometryRTheta/2d_spline_interpolator/2d_spline_interpolator.cpp b/tests/geometryRTheta/2d_spline_interpolator/2d_spline_interpolator.cpp index 5421bfd4d..8502684af 100644 --- a/tests/geometryRTheta/2d_spline_interpolator/2d_spline_interpolator.cpp +++ b/tests/geometryRTheta/2d_spline_interpolator/2d_spline_interpolator.cpp @@ -9,10 +9,6 @@ #include -#include -#include -#include - #include "geometry.hpp" #include "paraconfpp.hpp" #include "params.yaml.hpp" @@ -120,11 +116,13 @@ void Interpolation_on_random_coord( // Interpolate the function on Bsplines on the "random" grid. ---------------------------- - SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound spline_evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); DSpanRP function_interpolated; SplineInterpolatorRP interpolator(builder, spline_evaluator); diff --git a/tests/geometryRTheta/2d_spline_interpolator/CMakeLists.txt b/tests/geometryRTheta/2d_spline_interpolator/CMakeLists.txt index 687ec123f..bc422bb8c 100644 --- a/tests/geometryRTheta/2d_spline_interpolator/CMakeLists.txt +++ b/tests/geometryRTheta/2d_spline_interpolator/CMakeLists.txt @@ -12,7 +12,7 @@ target_compile_features(2d_spline_interpolator_tests PUBLIC cxx_std_17) target_link_libraries(2d_spline_interpolator_tests PUBLIC DDC::DDC - sll::splines + sll::SLL gslx::geometry_RTheta gslx::interpolation_2D_rp gslx::paraconfpp diff --git a/tests/geometryRTheta/advection_2d_rp/CMakeLists.txt b/tests/geometryRTheta/advection_2d_rp/CMakeLists.txt index 1ae59f68d..7c6f374bc 100644 --- a/tests/geometryRTheta/advection_2d_rp/CMakeLists.txt +++ b/tests/geometryRTheta/advection_2d_rp/CMakeLists.txt @@ -35,7 +35,7 @@ foreach(MAPPING_TYPE "CIRCULAR_MAPPING_PHYSICAL" "CZARNY_MAPPING_PHYSICAL" "CZAR PDI::pdi Eigen3::Eigen - sll::splines + sll::SLL gslx::paraconfpp gslx::interpolation_2D_rp @@ -75,7 +75,7 @@ target_link_libraries(advection_ALL PDI::pdi Eigen3::Eigen - sll::splines + sll::SLL gslx::paraconfpp gslx::interpolation_2D_rp diff --git a/tests/geometryRTheta/advection_2d_rp/advection_all_tests.cpp b/tests/geometryRTheta/advection_2d_rp/advection_all_tests.cpp index cc6d94f2c..3faa9a147 100644 --- a/tests/geometryRTheta/advection_2d_rp/advection_all_tests.cpp +++ b/tests/geometryRTheta/advection_2d_rp/advection_all_tests.cpp @@ -12,23 +12,14 @@ #include -#include -#include -#include -#include #include #include #include #include #include #include -#include #include #include -#include -#include -#include -#include #include #include @@ -61,7 +52,8 @@ using AnalyticalInvertibleMapping = AnalyticalInvertibleCurvilinear2DToCartesian; using CircularMapping = CircularToCartesian; using CzarnyMapping = CzarnyToCartesian; -using DiscreteMapping = DiscreteToCartesian; +using DiscreteMapping + = DiscreteToCartesian; } // end namespace @@ -169,9 +161,9 @@ struct Numerics struct GeneralParameters { IDomainRP grid; - PreallocatableSplineInterpolatorRP const& interpolator; + PreallocatableSplineInterpolatorRP const& interpolator; SplineRPBuilder const& advection_builder; - SplineRPEvaluator& advection_evaluator; + SplineRPEvaluatorConstBound& advection_evaluator; double final_time; bool if_save_curves; bool if_save_feet; @@ -302,27 +294,27 @@ int main(int argc, char** argv) SplineRPBuilder const builder(grid); // --- Evaluator for the test function: - SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound spline_evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); PreallocatableSplineInterpolatorRP interpolator(builder, spline_evaluator); // --- Evaluator for the test advection field: - ConstantExtrapolationBoundaryValue2D boundary_condition_r_left( - r_min); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_right( - r_max); + ddc::ConstantExtrapolationRule boundary_condition_r_left(r_min); + ddc::ConstantExtrapolationRule boundary_condition_r_right(r_max); - SplineRPEvaluator spline_evaluator_extrapol( + SplineRPEvaluatorConstBound spline_evaluator_extrapol( boundary_condition_r_left, boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::PeriodicExtrapolationRule(), + ddc::PeriodicExtrapolationRule()); diff --git a/tests/geometryRTheta/advection_2d_rp/advection_selected_test.cpp b/tests/geometryRTheta/advection_2d_rp/advection_selected_test.cpp index 4b363d993..b7a6c0c59 100644 --- a/tests/geometryRTheta/advection_2d_rp/advection_selected_test.cpp +++ b/tests/geometryRTheta/advection_2d_rp/advection_selected_test.cpp @@ -4,13 +4,9 @@ #include -#include #include -#include #include #include -#include -#include #include "advection_domain.hpp" #include "bsl_advection_rp.hpp" @@ -28,15 +24,10 @@ #include // ... -#include -#include -#include #include #include #include #include -#include -#include #include #include @@ -73,9 +64,9 @@ using RDimY_adv = typename AdvectionPseudoCartesianDomain< #elif defined(DISCRETE_MAPPING_PSEUDO_CARTESIAN) using RDimX_adv = typename AdvectionPseudoCartesianDomain< - DiscreteToCartesian>::RDimX_adv; + DiscreteToCartesian>::RDimX_adv; using RDimY_adv = typename AdvectionPseudoCartesianDomain< - DiscreteToCartesian>::RDimY_adv; + DiscreteToCartesian>::RDimY_adv; #endif } //end namespace @@ -174,26 +165,26 @@ int main(int argc, char** argv) SplineRPBuilder const builder(grid); // --- Evaluator for the test function: - SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound spline_evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); PreallocatableSplineInterpolatorRP interpolator(builder, spline_evaluator); // --- Evaluator for the test advection field: - ConstantExtrapolationBoundaryValue2D boundary_condition_r_left( - r_min); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_right( - r_max); + ddc::ConstantExtrapolationRule boundary_condition_r_left(r_min); + ddc::ConstantExtrapolationRule boundary_condition_r_right(r_max); - SplineRPEvaluator spline_evaluator_extrapol( + SplineRPEvaluatorConstBound spline_evaluator_extrapol( boundary_condition_r_left, boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::PeriodicExtrapolationRule(), + ddc::PeriodicExtrapolationRule()); std::string key; @@ -229,8 +220,8 @@ int main(int argc, char** argv) #elif defined(DISCRETE_MAPPING_PSEUDO_CARTESIAN) CzarnyToCartesian analytical_mapping(czarny_e, czarny_epsilon); - DiscreteToCartesian mapping - = DiscreteToCartesian:: + DiscreteToCartesian mapping + = DiscreteToCartesian:: analytical_to_discrete(analytical_mapping, builder, spline_evaluator_extrapol); AdvectionPseudoCartesianDomain advection_domain(mapping); std::string const mapping_name = "DISCRETE"; diff --git a/tests/geometryRTheta/advection_2d_rp/advection_simulation_utils.hpp b/tests/geometryRTheta/advection_2d_rp/advection_simulation_utils.hpp index 7b4ceba2d..7067b9043 100644 --- a/tests/geometryRTheta/advection_2d_rp/advection_simulation_utils.hpp +++ b/tests/geometryRTheta/advection_2d_rp/advection_simulation_utils.hpp @@ -3,13 +3,9 @@ #include -#include #include -#include #include #include -#include -#include #include "geometry.hpp" #include "paraconfpp.hpp" @@ -28,12 +24,6 @@ // ... -#include -#include -#include -#include -#include - #include #include #include @@ -182,7 +172,9 @@ FieldRP compute_exact_feet_rp( AdvectionField const& advection_field, double const time) { - static_assert(!std::is_same_v>); + static_assert(!std::is_same_v< + Mapping, + DiscreteToCartesian>); FieldRP feet_coords_rp(rp_dom); CoordXY const coord_xy_center = CoordXY(mapping(CoordRP(0, 0))); @@ -341,9 +333,9 @@ void simulate( TimeStepper const& time_stepper, AdvectionDomain& advection_domain, Simulation& simulation, - PreallocatableSplineInterpolatorRP const& function_interpolator, + PreallocatableSplineInterpolatorRP const& function_interpolator, SplineRPBuilder const& advection_builder, - SplineRPEvaluator& advection_evaluator, + SplineRPEvaluatorConstBound& advection_evaluator, double const final_time, double const dt, bool if_save_curves, @@ -553,9 +545,9 @@ void simulate_the_3_simulations( IDomainRP const& grid, TimeStepper& time_stepper, AdvectionDomain& advection_domain, - PreallocatableSplineInterpolatorRP const& function_interpolator, + PreallocatableSplineInterpolatorRP const& function_interpolator, SplineRPBuilder const& advection_builder, - SplineRPEvaluator& advection_evaluator, + SplineRPEvaluatorConstBound& advection_evaluator, double const final_time, double const dt, bool const& save_curves, diff --git a/tests/geometryRTheta/advection_2d_rp/test_cases.hpp b/tests/geometryRTheta/advection_2d_rp/test_cases.hpp index ea8a96538..a17567f0a 100644 --- a/tests/geometryRTheta/advection_2d_rp/test_cases.hpp +++ b/tests/geometryRTheta/advection_2d_rp/test_cases.hpp @@ -5,11 +5,8 @@ #include #include #include -#include #include #include -#include -#include #include "geometry.hpp" #include "paraconfpp.hpp" diff --git a/tests/geometryRTheta/advection_field_rp/CMakeLists.txt b/tests/geometryRTheta/advection_field_rp/CMakeLists.txt index d8bdf339b..9f8c4cebe 100644 --- a/tests/geometryRTheta/advection_field_rp/CMakeLists.txt +++ b/tests/geometryRTheta/advection_field_rp/CMakeLists.txt @@ -25,7 +25,7 @@ function (advection_field_test_executable SIMULATION) Eigen3::Eigen - sll::splines + sll::SLL gslx::paraconfpp GTest::gtest diff --git a/tests/geometryRTheta/advection_field_rp/advection_field_gtest.cpp b/tests/geometryRTheta/advection_field_rp/advection_field_gtest.cpp index 2df1a4b89..8e01f9a24 100644 --- a/tests/geometryRTheta/advection_field_rp/advection_field_gtest.cpp +++ b/tests/geometryRTheta/advection_field_rp/advection_field_gtest.cpp @@ -10,13 +10,9 @@ #include -#include #include #include #include -#include -#include -#include #include @@ -46,7 +42,8 @@ namespace { using PoissonSolver = PolarSplineFEMPoissonSolver; -using DiscreteMapping = DiscreteToCartesian; +using DiscreteMapping + = DiscreteToCartesian; using Mapping = CircularToCartesian; namespace fs = std::filesystem; @@ -120,20 +117,19 @@ TEST(AdvectionFieldRPComputation, TestAdvectionFieldFinder) SplinePBuilder const p_builder(interpolation_domain_P); SplineRPBuilder const builder(grid); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_left( - r_min); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_right( - r_max); + ddc::ConstantExtrapolationRule boundary_condition_r_left(r_min); + ddc::ConstantExtrapolationRule boundary_condition_r_right(r_max); - SplineRPEvaluator spline_evaluator_extrapol( + SplineRPEvaluatorConstBound spline_evaluator_extrapol( boundary_condition_r_left, boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::PeriodicExtrapolationRule(), + ddc::PeriodicExtrapolationRule()); - PolarSplineEvaluator polar_spline_evaluator( - g_polar_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + PolarSplineEvaluator polar_spline_evaluator( + r_extrapolation_rule); // --- Define the mapping. ------------------------------------------------------------------------ const Mapping mapping; @@ -144,11 +140,12 @@ TEST(AdvectionFieldRPComputation, TestAdvectionFieldFinder) // --- Advection operator ------------------------------------------------------------------------- - SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound spline_evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); PreallocatableSplineInterpolatorRP interpolator(builder, spline_evaluator); @@ -280,8 +277,8 @@ TEST(AdvectionFieldRPComputation, TestAdvectionFieldFinder) EXPECT_LE(abs(ddcHelper::get(difference_between_fields_exact_and_xy)(irp)), 1e-5); EXPECT_LE(abs(ddcHelper::get(difference_between_fields_exact_and_xy)(irp)), 1e-5); - EXPECT_LE(abs(ddcHelper::get(difference_between_fields_xy_and_rp)(irp)), 1e-14); - EXPECT_LE(abs(ddcHelper::get(difference_between_fields_xy_and_rp)(irp)), 1e-14); + EXPECT_LE(abs(ddcHelper::get(difference_between_fields_xy_and_rp)(irp)), 1e-13); + EXPECT_LE(abs(ddcHelper::get(difference_between_fields_xy_and_rp)(irp)), 1e-13); }); diff --git a/tests/geometryRTheta/advection_field_rp/test_cases_adv_field.hpp b/tests/geometryRTheta/advection_field_rp/test_cases_adv_field.hpp index f977bedc3..17f1ba78e 100644 --- a/tests/geometryRTheta/advection_field_rp/test_cases_adv_field.hpp +++ b/tests/geometryRTheta/advection_field_rp/test_cases_adv_field.hpp @@ -5,11 +5,8 @@ #include #include #include -#include #include #include -#include -#include #include "../advection_2d_rp/test_cases.hpp" diff --git a/tests/geometryRTheta/polar_poisson/CMakeLists.txt b/tests/geometryRTheta/polar_poisson/CMakeLists.txt index aaf17fce9..e1b634128 100644 --- a/tests/geometryRTheta/polar_poisson/CMakeLists.txt +++ b/tests/geometryRTheta/polar_poisson/CMakeLists.txt @@ -13,7 +13,7 @@ foreach(MAPPING_TYPE "CIRCULAR_MAPPING" "CZARNY_MAPPING") DDC::PDI_Wrapper paraconf::paraconf PDI::pdi - sll::splines + sll::SLL gslx::poisson_RTheta gslx::paraconfpp Eigen3::Eigen @@ -29,4 +29,4 @@ foreach(MAPPING_TYPE "CIRCULAR_MAPPING" "CZARNY_MAPPING") set_property(TEST TestPoissonConvergence_${MAPPING_TYPE}_${SOLUTION} PROPERTY TIMEOUT 200) set_property(TEST TestPoissonConvergence_${MAPPING_TYPE}_${SOLUTION} PROPERTY COST 100) endforeach() -endforeach() \ No newline at end of file +endforeach() diff --git a/tests/geometryRTheta/polar_poisson/polarpoissonfemsolver.cpp b/tests/geometryRTheta/polar_poisson/polarpoissonfemsolver.cpp index 376cfffb1..77d66c601 100644 --- a/tests/geometryRTheta/polar_poisson/polarpoissonfemsolver.cpp +++ b/tests/geometryRTheta/polar_poisson/polarpoissonfemsolver.cpp @@ -27,7 +27,8 @@ using Mapping = CircularToCartesian; #elif defined(CZARNY_MAPPING) using Mapping = CzarnyToCartesian; #endif -using DiscreteMapping = DiscreteToCartesian; +using DiscreteMapping + = DiscreteToCartesian; #if defined(CURVILINEAR_SOLUTION) using LHSFunction = CurvilinearSolution; @@ -105,11 +106,11 @@ int main(int argc, char** argv) #elif defined(CZARNY_MAPPING) const Mapping mapping(0.3, 1.4); #endif - SplineRPEvaluator evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule bv_r_min; + ddc::NullExtrapolationRule bv_r_max; + ddc::PeriodicExtrapolationRule bv_p_min; + ddc::PeriodicExtrapolationRule bv_p_max; + SplineRPEvaluatorNullBound evaluator(bv_r_min, bv_r_max, bv_p_min, bv_p_max); DiscreteMapping const discrete_mapping = DiscreteMapping::analytical_to_discrete(mapping, builder, evaluator); @@ -137,15 +138,16 @@ int main(int argc, char** argv) Spline2D coeff_alpha_spline(dom_bsplinesRP); Spline2D coeff_beta_spline(dom_bsplinesRP); - builder(coeff_alpha_spline, coeff_alpha); // coeff_alpha_spline are the coefficients - // of the spline representation of the values given by coeff_alpha. - builder(coeff_beta_spline, coeff_beta); + builder(coeff_alpha_spline.span_view(), + coeff_alpha.span_cview()); // coeff_alpha_spline are the coefficients + // of the spline representation of the values given by coeff_alpha. + builder(coeff_beta_spline.span_view(), coeff_beta.span_cview()); Spline2D x_spline_representation(dom_bsplinesRP); Spline2D y_spline_representation(dom_bsplinesRP); - builder(x_spline_representation, x); - builder(y_spline_representation, y); + builder(x_spline_representation.span_view(), x.span_cview()); + builder(y_spline_representation.span_view(), y.span_cview()); end_time = std::chrono::system_clock::now(); std::cout << "Setup time : " @@ -177,17 +179,19 @@ int main(int argc, char** argv) Spline2D rhs_spline(dom_bsplinesRP); DFieldRP rhs_vals(grid); ddc::for_each(grid, [&](IndexRP const irp) { rhs_vals(irp) = rhs(coords(irp)); }); - builder(rhs_spline, rhs_vals); + builder(rhs_spline.span_view(), rhs_vals.span_cview()); start_time = std::chrono::system_clock::now(); - SplineRPEvaluator - eval(g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); - solver([&](CoordRP const& coord) { return eval(coord, rhs_spline); }, + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluatorNullBound + eval(r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); + solver([&](CoordRP const& coord) { return eval(coord, rhs_spline.span_cview()); }, coords.span_cview(), result.span_view()); end_time = std::chrono::system_clock::now(); diff --git a/tests/geometryRTheta/quadrature/CMakeLists.txt b/tests/geometryRTheta/quadrature/CMakeLists.txt index 18df44567..99f1e514f 100644 --- a/tests/geometryRTheta/quadrature/CMakeLists.txt +++ b/tests/geometryRTheta/quadrature/CMakeLists.txt @@ -11,8 +11,8 @@ target_link_libraries(Li_norms_spline_quadrature_tests GTest::gtest GTest::gmock DDC::DDC - sll::splines + sll::SLL gslx::geometry_RTheta gslx::quadrature ) -gtest_discover_tests(Li_norms_spline_quadrature_tests) \ No newline at end of file +gtest_discover_tests(Li_norms_spline_quadrature_tests) diff --git a/tests/geometryRTheta/quadrature/tests_L1_and_L2_norms.cpp b/tests/geometryRTheta/quadrature/tests_L1_and_L2_norms.cpp index 3ef3cc169..f0f998403 100644 --- a/tests/geometryRTheta/quadrature/tests_L1_and_L2_norms.cpp +++ b/tests/geometryRTheta/quadrature/tests_L1_and_L2_norms.cpp @@ -1,14 +1,9 @@ #include -#include #include -#include #include #include #include -#include -#include -#include #include @@ -110,11 +105,13 @@ void launch_tests( std::array, 5> const& expected_norms, std::array, 5> const& TOLs) { + SplineRBuilder r_builder(ddc::select(builder.interpolation_domain())); + SplinePBuilder p_builder(ddc::select(builder.interpolation_domain())); // Test spline quadrature: ------------------------------------------------------------------------ // Instantiate a quadrature with coefficients where we added the Jacobian determinant. DFieldRP const quadrature_coeffs = compute_coeffs_on_mapping( mapping, - spline_quadrature_coefficients(grid, builder.get_builder_1(), builder.get_builder_2())); + spline_quadrature_coefficients(grid, r_builder, p_builder)); Quadrature quadrature(quadrature_coeffs); @@ -234,14 +231,14 @@ TEST_P(SplineQuadrature, TestFunctions) expected_norms[4][1] = std::sqrt(M_PI / 12.); std::array, 5> TOLs; - TOLs[0][0] = 1e-15; - TOLs[0][1] = 1e-15; + TOLs[0][0] = 1e-14; + TOLs[0][1] = 1e-14; TOLs[1][0] = 5e-3; - TOLs[1][1] = 1e-15; - TOLs[2][0] = 1e-15; - TOLs[2][1] = 1e-15; + TOLs[1][1] = 1e-14; + TOLs[2][0] = 1e-14; + TOLs[2][1] = 1e-14; TOLs[3][0] = 5e-3; - TOLs[3][1] = 1e-15; + TOLs[3][1] = 1e-14; TOLs[4][0] = 5e-2; TOLs[4][1] = 5e-6; @@ -251,14 +248,14 @@ TEST_P(SplineQuadrature, TestFunctions) std::cout << std::endl << "DISCRETE MAPPING ---------------------------------------------------" << std::endl; - SplineRPEvaluator spline_evaluator_extrapol( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); - - DiscreteToCartesian const discrete_mapping - = DiscreteToCartesian:: + ddc::ConstantExtrapolationRule bv_r_min(r_min); + ddc::ConstantExtrapolationRule bv_r_max(r_max); + ddc::PeriodicExtrapolationRule bv_p_min; + ddc::PeriodicExtrapolationRule bv_p_max; + SplineRPEvaluatorConstBound spline_evaluator_extrapol(bv_r_min, bv_r_max, bv_p_min, bv_p_max); + + DiscreteToCartesian const discrete_mapping + = DiscreteToCartesian:: analytical_to_discrete(mapping_1, builder, spline_evaluator_extrapol); TOLs[0][0] = 5e-6; TOLs[0][1] = 5e-7; diff --git a/tests/geometryXVx/CMakeLists.txt b/tests/geometryXVx/CMakeLists.txt index d45b2ae72..b348b05d1 100644 --- a/tests/geometryXVx/CMakeLists.txt +++ b/tests/geometryXVx/CMakeLists.txt @@ -85,7 +85,7 @@ foreach(GEOMETRY_VARIANT IN LISTS GEOMETRY_XVx_VARIANTS_LIST) GTest::gtest GTest::gmock paraconf::paraconf - sll::splines + sll::SLL gslx::quadrature gslx::geometry_${GEOMETRY_VARIANT} ) diff --git a/tests/geometryXVx/quadrature_spline.cpp b/tests/geometryXVx/quadrature_spline.cpp index a7e2f75f1..b6c5a26b4 100644 --- a/tests/geometryXVx/quadrature_spline.cpp +++ b/tests/geometryXVx/quadrature_spline.cpp @@ -1,11 +1,5 @@ // SPDX-License-Identifier: MIT -#include -#include -#include -#include -#include - #include #include @@ -22,29 +16,37 @@ TEST(SplineQuadratureTest, ExactForConstantFunc) IVectX const x_size(10); // Creating mesh & supports - using sllBSplinesX = UniformBSplines; - auto constexpr sllSplineXBoundary = RDimX::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; - using sllGrevillePointsX - = GrevilleInterpolationPoints; - using sllIDimX = typename sllGrevillePointsX::interpolation_mesh_type; - using sllSplineXBuilder - = SplineBuilder; - using sllIDomainX = ddc::DiscreteDomain; - using sllDFieldX = device_t>; - - ddc::init_discrete_space(x_min, x_max, x_size); - - ddc::init_discrete_space(sllGrevillePointsX::get_sampling()); - sllIDomainX interpolation_domain_x(sllGrevillePointsX::get_domain()); - - sllSplineXBuilder const builder_x(interpolation_domain_x); - - sllIDomainX const gridx = builder_x.interpolation_domain(); - - host_t const quadrature_coeffs = spline_quadrature_coefficients(gridx, builder_x); + using BSplinesX = ddc::UniformBSplines; + auto constexpr SplineXBoundary + = RDimX::PERIODIC ? ddc::BoundCond::PERIODIC : ddc::BoundCond::GREVILLE; + using GrevillePointsX + = ddc::GrevilleInterpolationPoints; + using IDimX = typename GrevillePointsX::interpolation_mesh_type; + using SplineXBuilder = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesX, + IDimX, + SplineXBoundary, + SplineXBoundary, + ddc::SplineSolver::GINKGO, + IDimX>; + using IDomainX = ddc::DiscreteDomain; + using DFieldX = device_t>; + + ddc::init_discrete_space(x_min, x_max, x_size); + + ddc::init_discrete_space(GrevillePointsX::get_sampling()); + IDomainX interpolation_domain_x(GrevillePointsX::get_domain()); + + SplineXBuilder const builder_x(interpolation_domain_x); + + IDomainX const gridx = builder_x.interpolation_domain(); + + host_t const quadrature_coeffs = spline_quadrature_coefficients(gridx, builder_x); Quadrature const integrate(quadrature_coeffs.span_cview()); - host_t values(gridx); + host_t values(gridx); ddc::for_each(gridx, [&](ddc::DiscreteElement const idx) { values(idx) = 1.0; }); double integral = integrate(values); @@ -63,12 +65,20 @@ template double compute_error(int n_elems) { using DimY = Y; - using BSplinesY = UniformBSplines; + using BSplinesY = ddc::UniformBSplines; + auto constexpr SplineYBoundary = ddc::BoundCond::GREVILLE; using GrevillePointsY - = GrevilleInterpolationPoints; + = ddc::GrevilleInterpolationPoints; using IDimY = typename GrevillePointsY::interpolation_mesh_type; - using SplineYBuilder - = SplineBuilder; + using SplineYBuilder = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesY, + IDimY, + SplineYBoundary, + SplineYBoundary, + ddc::SplineSolver::GINKGO, + IDimY>; using IDomainY = ddc::DiscreteDomain; using DFieldY = device_t>; diff --git a/tests/geometryXYVxVy/CMakeLists.txt b/tests/geometryXYVxVy/CMakeLists.txt index 9bf635c49..3061a33ce 100644 --- a/tests/geometryXYVxVy/CMakeLists.txt +++ b/tests/geometryXYVxVy/CMakeLists.txt @@ -15,7 +15,7 @@ target_link_libraries(unit_tests_xy_vxvy GTest::gmock paraconf::paraconf gslx::geometry_xyvxvy - sll::splines + sll::SLL gslx::advection gslx::poisson_xy gslx::quadrature diff --git a/tests/geometryXYVxVy/fft_poisson.cpp b/tests/geometryXYVxVy/fft_poisson.cpp index 9013fcef3..668a0654a 100644 --- a/tests/geometryXYVxVy/fft_poisson.cpp +++ b/tests/geometryXYVxVy/fft_poisson.cpp @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MIT -#include - #include #include diff --git a/vendor/sll/CMakeLists.txt b/vendor/sll/CMakeLists.txt index d9c49553b..015523771 100644 --- a/vendor/sll/CMakeLists.txt +++ b/vendor/sll/CMakeLists.txt @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.15) -project(splines CXX) +project(SLL CXX) # Our project option(SLL_BUILD_TESTING "Build sll tests" ON) ## The library itself -add_library(splines STATIC +add_library(SLL STATIC src/matrix.cpp src/matrix_dense.cpp src/matrix_banded.cpp @@ -15,34 +15,22 @@ add_library(splines STATIC src/matrix_pds_tridiag.cpp src/gauss_legendre_integration.cpp ) -if(GYSELALIBXX_ENABLE_DEPRECATED) - target_sources(splines - PRIVATE - src/deprecated/bsplines.cpp - src/deprecated/bsplines_uniform.cpp - src/deprecated/bsplines_non_uniform.cpp - src/deprecated/spline_1d.cpp - src/deprecated/spline_2d.cpp - src/deprecated/spline_builder_1d.cpp - src/deprecated/spline_builder_2d.cpp - ) -endif() -target_compile_features(splines PUBLIC cxx_std_17) -target_include_directories(splines +target_compile_features(SLL PUBLIC cxx_std_17) +target_include_directories(SLL PUBLIC "$" ) -target_link_libraries(splines +target_link_libraries(SLL PUBLIC DDC::DDC std::mdspan ) if(CMAKE_VERSION GREATER_EQUAL 3.18) - target_link_libraries(splines PRIVATE LAPACK::LAPACK) + target_link_libraries(SLL PRIVATE LAPACK::LAPACK) else() - target_link_libraries(splines PRIVATE ${LAPACK_LIBRARIES}) + target_link_libraries(SLL PRIVATE ${LAPACK_LIBRARIES}) endif() -add_library(sll::splines ALIAS splines) +add_library(sll::SLL ALIAS SLL) ## if tests are enabled, build the tests in `tests/` if("${BUILD_TESTING}" AND "${SLL_BUILD_TESTING}") diff --git a/vendor/sll/include/sll/bspline.hpp b/vendor/sll/include/sll/bspline.hpp deleted file mode 100644 index acab42c8e..000000000 --- a/vendor/sll/include/sll/bspline.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -template -struct BSpline -{ -}; diff --git a/vendor/sll/include/sll/bsplines_non_uniform.hpp b/vendor/sll/include/sll/bsplines_non_uniform.hpp deleted file mode 100644 index 6f51f6a07..000000000 --- a/vendor/sll/include/sll/bsplines_non_uniform.hpp +++ /dev/null @@ -1,511 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -#include "sll/bspline.hpp" -#include "sll/view.hpp" - -/// NonUniformPointSampling specialization of BSplines -template -class NonUniformBSplines -{ - static_assert(D > 0, "Parameter `D` must be positive"); - -public: - // From nvcc: 'A type that is defined inside a class and has private or protected access cannot be used - // in the template argument type of a variable template instantiation' - template - struct InternalTagGenerator; - - /// An internal tag necessary to allocate an internal ddc::discrete_space function. - /// It must remain internal, for example it shall not be exposed when returning ddc::coordinates. Instead use `Tag` - using KnotDim = InternalTagGenerator; - - using mesh_type = ddc::NonUniformPointSampling; - - static inline ddc::Coordinate knot_from_coord(ddc::Coordinate const& coord) - { - return ddc::Coordinate(ddc::get(coord)); - } - static inline ddc::Coordinate coord_from_knot(ddc::Coordinate const& coord) - { - return ddc::Coordinate(ddc::get(coord)); - } - -public: - using tag_type = Tag; - - using continuous_dimension_type = BSpline; - - - using discrete_dimension_type = NonUniformBSplines; - - using discrete_element_type = ddc::DiscreteElement; - - using discrete_domain_type = ddc::DiscreteDomain; - - using discrete_vector_type = ddc::DiscreteVector; - -public: - static constexpr std::size_t rank() - { - return 1; - } - - static constexpr std::size_t degree() noexcept - { - return D; - } - - static constexpr bool is_periodic() noexcept - { - return Tag::PERIODIC; - } - - static constexpr bool is_radial() noexcept - { - return false; - } - - static constexpr bool is_uniform() noexcept - { - return false; - } - - template - class Impl - { - template - friend class Impl; - - private: - ddc::DiscreteDomain m_domain; - const int m_nknots; - - public: - using discrete_dimension_type = NonUniformBSplines; - - Impl() = default; - - template - explicit Impl(Impl const& impl) - : m_domain(impl.m_domain) - , m_nknots(impl.m_nknots) - { - } - - /// @brief Construct a `Impl` using a brace-list, i.e. `Impl bsplines({0., 1.})` - explicit Impl(std::initializer_list> breaks) - : Impl(breaks.begin(), breaks.end()) - { - } - - /// @brief Construct a `Impl` using a C++20 "common range". - explicit Impl(std::vector> const& breaks) - : Impl(breaks.begin(), breaks.end()) - { - } - - /// @brief Construct a `Impl` using a pair of iterators. - template - Impl(RandomIt breaks_begin, RandomIt breaks_end); - - Impl(Impl const& x) = default; - - Impl(Impl&& x) = default; - - ~Impl() = default; - - Impl& operator=(Impl const& x) = default; - - Impl& operator=(Impl&& x) = default; - - discrete_element_type eval_basis(DSpan1D values, ddc::Coordinate const& x) const; - - discrete_element_type eval_deriv(DSpan1D derivs, ddc::Coordinate const& x) const; - - discrete_element_type eval_basis_and_n_derivs( - DSpan2D derivs, - ddc::Coordinate const& x, - std::size_t n) const; - - ddc::ChunkSpan integrals( - ddc::ChunkSpan int_vals) const; - - ddc::Coordinate get_knot(int knot_idx) const noexcept - { - return coord_from_knot( - ddc::coordinate(ddc::DiscreteElement(knot_idx + degree()))); - } - - ddc::Coordinate get_first_support_knot(discrete_element_type const& ix) const - { - return coord_from_knot(ddc::coordinate(ddc::DiscreteElement(ix.uid()))); - } - - ddc::Coordinate get_last_support_knot(discrete_element_type const& ix) const - { - return coord_from_knot( - ddc::coordinate(ddc::DiscreteElement(ix.uid() + degree() + 1))); - } - - ddc::Coordinate get_support_knot_n(discrete_element_type const& ix, int n) const - { - return coord_from_knot(ddc::coordinate(ddc::DiscreteElement(ix.uid() + n))); - } - - ddc::Coordinate rmin() const noexcept - { - return get_knot(0); - } - - ddc::Coordinate rmax() const noexcept - { - return get_knot(ncells()); - } - - double length() const noexcept - { - return rmax() - rmin(); - } - - std::size_t size() const noexcept - { - return degree() + ncells(); - } - - /// Returns the discrete domain including ghost bsplines - discrete_domain_type full_domain() const - { - return discrete_domain_type(discrete_element_type(0), discrete_vector_type(size())); - } - - std::size_t npoints() const noexcept - { - return m_nknots - 2 * degree(); - } - - std::size_t nbasis() const noexcept - { - return ncells() + !is_periodic() * degree(); - } - - std::size_t ncells() const noexcept - { - return npoints() - 1; - } - - private: - int find_cell(ddc::Coordinate const& x) const; - }; -}; - -template -template -template -NonUniformBSplines::Impl::Impl( - RandomIt const break_begin, - RandomIt const break_end) - : m_domain( - ddc::DiscreteElement(0), - ddc::DiscreteVector( - (break_end - break_begin) - + 2 * degree())) // Create a mesh including the eventual periodic point - , m_nknots((break_end - break_begin) + 2 * degree()) -{ - std::vector> knots((break_end - break_begin) + 2 * degree()); - // Fill the provided knots - int ii = 0; - for (RandomIt it = break_begin; it < break_end; ++it) { - knots[degree() + ii] = knot_from_coord(*it); - ++ii; - } - ddc::Coordinate const rmin = knots[degree()]; - ddc::Coordinate const rmax = knots[(break_end - break_begin) + degree() - 1]; - assert(rmin < rmax); - - // Fill out the extra knots - if constexpr (is_periodic()) { - double const period = rmax - rmin; - for (std::size_t i = 1; i < degree() + 1; ++i) { - knots[degree() + -i] - = ddc::Coordinate(knots[degree() + ncells() - i] - period); - knots[degree() + ncells() + i] = ddc::Coordinate(knots[degree() + i] + period); - } - } else // open - { - for (std::size_t i = 1; i < degree() + 1; ++i) { - knots[degree() + -i] = rmin; - knots[degree() + npoints() - 1 + i] = rmax; - } - } - ddc::init_discrete_space(knots); -} - -template -template -ddc::DiscreteElement> NonUniformBSplines::Impl< - MemorySpace>::eval_basis(DSpan1D const values, ddc::Coordinate const& x) const -{ - std::array left; - std::array right; - - assert(x >= rmin()); - assert(x <= rmax()); - assert(values.extent(0) == degree() + 1); - - // 1. Compute cell index 'icell' - int const icell = find_cell(x); - - assert(icell >= 0); - assert(icell <= int(ncells() - 1)); - assert(get_knot(icell) <= x); - assert(get_knot(icell + 1) >= x); - - // 2. Compute values of B-splines with support over cell 'icell' - double temp; - values(0) = 1.0; - for (std::size_t j = 0; j < degree(); ++j) { - left[j] = x - get_knot(icell - j); - right[j] = get_knot(icell + j + 1) - x; - double saved = 0.0; - for (std::size_t r = 0; r < j + 1; ++r) { - temp = values(r) / (right[r] + left[j - r]); - values(r) = saved + right[r] * temp; - saved = left[j - r] * temp; - } - values(j + 1) = saved; - } - - return discrete_element_type(icell); -} - -template -template -ddc::DiscreteElement> NonUniformBSplines::Impl< - MemorySpace>::eval_deriv(DSpan1D const derivs, ddc::Coordinate const& x) const -{ - std::array left; - std::array right; - - assert(x >= rmin()); - assert(x <= rmax()); - assert(derivs.extent(0) == degree() + 1); - - // 1. Compute cell index 'icell' - int const icell = find_cell(x); - - assert(icell >= 0); - assert(icell <= int(ncells() - 1)); - assert(get_knot(icell) <= x); - assert(get_knot(icell + 1) >= x); - - // 2. Compute values of derivatives of B-splines with support over cell 'icell' - - /* - * Compute nonzero basis functions and knot differences - * for splines up to degree degree-1 which are needed to compute derivative - * First part of Algorithm A3.2 of NURBS book - */ - double saved, temp; - derivs(0) = 1.0; - for (std::size_t j = 0; j < degree() - 1; ++j) { - left[j] = x - get_knot(icell - j); - right[j] = get_knot(icell + j + 1) - x; - saved = 0.0; - for (std::size_t r = 0; r < j + 1; ++r) { - temp = derivs(r) / (right[r] + left[j - r]); - derivs(r) = saved + right[r] * temp; - saved = left[j - r] * temp; - } - derivs(j + 1) = saved; - } - - /* - * Compute derivatives at x using values stored in bsdx and formula - * for spline derivative based on difference of splines of degree degree-1 - */ - saved = degree() * derivs(0) / (get_knot(icell + 1) - get_knot(icell + 1 - degree())); - derivs(0) = -saved; - for (std::size_t j = 1; j < degree(); ++j) { - temp = saved; - saved = degree() * derivs(j) - / (get_knot(icell + j + 1) - get_knot(icell + j + 1 - degree())); - derivs(j) = temp - saved; - } - derivs(degree()) = saved; - - return discrete_element_type(icell); -} - -template -template -ddc::DiscreteElement> NonUniformBSplines::Impl:: - eval_basis_and_n_derivs( - DSpan2D const derivs, - ddc::Coordinate const& x, - std::size_t const n) const -{ - std::array left; - std::array right; - - std::array a_ptr; - std::experimental:: - mdspan> const a( - a_ptr.data()); - - std::array ndu_ptr; - std::experimental::mdspan< - double, - std::experimental::extents> const - ndu(ndu_ptr.data()); - - assert(x >= rmin()); - assert(x <= rmax()); - // assert(n >= 0); as long as n is unsigned - assert(n <= degree()); - assert(derivs.extent(0) == 1 + degree()); - assert(derivs.extent(1) == 1 + n); - - // 1. Compute cell index 'icell' and x_offset - int const icell = find_cell(x); - - assert(icell >= 0); - assert(icell <= int(ncells() - 1)); - assert(get_knot(icell) <= x); - assert(get_knot(icell + 1) >= x); - - // 2. Compute nonzero basis functions and knot differences for splines - // up to degree (degree-1) which are needed to compute derivative - // Algorithm A2.3 of NURBS book - // - // 21.08.2017: save inverse of knot differences to avoid unnecessary - // divisions - // [Yaman Güçlü, Edoardo Zoni] - - double saved, temp; - ndu(0, 0) = 1.0; - for (std::size_t j = 0; j < degree(); ++j) { - left[j] = x - get_knot(icell - j); - right[j] = get_knot(icell + j + 1) - x; - saved = 0.0; - for (std::size_t r = 0; r < j + 1; ++r) { - // compute inverse of knot differences and save them into lower - // triangular part of ndu - ndu(r, j + 1) = 1.0 / (right[r] + left[j - r]); - // compute basis functions and save them into upper triangular part - // of ndu - temp = ndu(j, r) * ndu(r, j + 1); - ndu(j + 1, r) = saved + right[r] * temp; - saved = left[j - r] * temp; - } - ndu(j + 1, j + 1) = saved; - } - // Save 0-th derivative - for (std::size_t j = 0; j < degree() + 1; ++j) { - derivs(j, 0) = ndu(degree(), j); - } - - for (int r = 0; r < int(degree() + 1); ++r) { - int s1 = 0; - int s2 = 1; - a(0, 0) = 1.0; - for (int k = 1; k < int(n + 1); ++k) { - double d = 0.0; - int const rk = r - k; - int const pk = degree() - k; - if (r >= k) { - a(0, s2) = a(0, s1) * ndu(rk, pk + 1); - d = a(0, s2) * ndu(pk, rk); - } - int const j1 = rk > -1 ? 1 : (-rk); - int const j2 = (r - 1) <= pk ? k : (degree() - r + 1); - for (int j = j1; j < j2; ++j) { - a(j, s2) = (a(j, s1) - a(j - 1, s1)) * ndu(rk + j, pk + 1); - d += a(j, s2) * ndu(pk, rk + j); - } - if (r <= pk) { - a(k, s2) = -a(k - 1, s1) * ndu(r, pk + 1); - d += a(k, s2) * ndu(pk, r); - } - derivs(r, k) = d; - std::swap(s1, s2); - } - } - - int r = degree(); - for (int k = 1; k < int(n + 1); ++k) { - for (std::size_t i = 0; i < derivs.extent(0); i++) { - derivs(i, k) *= r; - } - r *= degree() - k; - } - - return discrete_element_type(icell); -} - -template -template -int NonUniformBSplines::Impl::find_cell(ddc::Coordinate const& x) const -{ - if (x > rmax()) - return -1; - if (x < rmin()) - return -1; - - if (x == rmin()) - return 0; - if (x == rmax()) - return ncells() - 1; - - // Binary search - int low = 0, high = ncells(); - int icell = (low + high) / 2; - while (x < get_knot(icell) || x >= get_knot(icell + 1)) { - if (x < get_knot(icell)) { - high = icell; - } else { - low = icell; - } - icell = (low + high) / 2; - } - return icell; -} - -template -template -ddc::ChunkSpan>> NonUniformBSplines:: - Impl::integrals( - ddc::ChunkSpan>> int_vals) - const -{ - if constexpr (is_periodic()) { - assert(int_vals.size() == nbasis() || int_vals.size() == size()); - } else { - assert(int_vals.size() == nbasis()); - } - - double const inv_deg = 1.0 / (degree() + 1); - - discrete_domain_type const dom_bsplines( - full_domain().take_first(discrete_vector_type {nbasis()})); - for (auto ix : dom_bsplines) { - int_vals(ix) = (get_last_support_knot(ix) - get_first_support_knot(ix)) * inv_deg; - } - - if constexpr (is_periodic()) { - if (int_vals.size() == size()) { - discrete_domain_type const dom_bsplines_wrap( - full_domain().take_last(discrete_vector_type {degree()})); - for (auto ix : dom_bsplines_wrap) { - int_vals(ix) = 0; - } - } - } - return int_vals; -} diff --git a/vendor/sll/include/sll/bsplines_uniform.hpp b/vendor/sll/include/sll/bsplines_uniform.hpp deleted file mode 100644 index 7ad05b40a..000000000 --- a/vendor/sll/include/sll/bsplines_uniform.hpp +++ /dev/null @@ -1,465 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#include "sll/bspline.hpp" -#include "sll/math_tools.hpp" -#include "sll/view.hpp" - -template -class UniformBSplines -{ - static_assert(D > 0, "Parameter `D` must be positive"); - -public: - // From nvcc: 'A type that is defined inside a class and has private or protected access cannot be used - // in the template argument type of a variable template instantiation' - template - struct InternalTagGenerator; - - /// An internal tag necessary to allocate an internal ddc::discrete_space function. - /// It must remain internal, for example it shall not be exposed when returning ddc::coordinates. Instead use `Tag` - using KnotDim = InternalTagGenerator; - - using mesh_type = ddc::UniformPointSampling; - - static inline ddc::Coordinate knot_from_coord(ddc::Coordinate const& coord) - { - return ddc::Coordinate(ddc::get(coord)); - } - static inline ddc::Coordinate coord_from_knot(ddc::Coordinate const& coord) - { - return ddc::Coordinate(ddc::get(coord)); - } - -public: - using tag_type = Tag; - - using continuous_dimension_type = BSpline; - - - using discrete_dimension_type = UniformBSplines; - - using discrete_element_type = ddc::DiscreteElement; - - using discrete_domain_type = ddc::DiscreteDomain; - - using discrete_vector_type = ddc::DiscreteVector; - -public: - static constexpr std::size_t rank() - { - return 1; - } - - static constexpr std::size_t degree() noexcept - { - return D; - } - - static constexpr bool is_periodic() noexcept - { - return Tag::PERIODIC; - } - - static constexpr bool is_radial() noexcept - { - return false; - } - - static constexpr bool is_uniform() noexcept - { - return true; - } - - template - class Impl - { - template - friend class Impl; - - private: - // In the periodic case, it contains twice the periodic point!!! - ddc::DiscreteDomain m_domain; - - public: - using discrete_dimension_type = UniformBSplines; - - Impl() = default; - - template - explicit Impl(Impl const& impl) : m_domain(impl.m_domain) - { - } - - /** Constructs a BSpline basis with n equidistant knots over \f$[a, b]\f$ - * - * @param rmin the real ddc::coordinate of the first knot - * @param rmax the real ddc::coordinate of the last knot - * @param n_knots the number of knots - */ - explicit Impl(ddc::Coordinate rmin, ddc::Coordinate rmax, std::size_t ncells) - : m_domain( - ddc::DiscreteElement(0), - ddc::DiscreteVector( - ncells + 1)) // Create a mesh including the eventual periodic point - { - assert(ncells > 0); - ddc::init_discrete_space(mesh_type:: - init(knot_from_coord(rmin), - knot_from_coord(rmax), - ddc::DiscreteVector(ncells + 1))); - } - - Impl(Impl const& x) = default; - - Impl(Impl&& x) = default; - - ~Impl() = default; - - Impl& operator=(Impl const& x) = default; - - Impl& operator=(Impl&& x) = default; - - discrete_element_type eval_basis(DSpan1D values, ddc::Coordinate const& x) const - { - return eval_basis(values, x, degree()); - } - - discrete_element_type eval_deriv(DSpan1D derivs, ddc::Coordinate const& x) const; - - discrete_element_type eval_basis_and_n_derivs( - DSpan2D derivs, - ddc::Coordinate const& x, - std::size_t n) const; - - ddc::ChunkSpan integrals( - ddc::ChunkSpan int_vals) const; - - ddc::Coordinate get_knot(int idx) const noexcept - { - return ddc::Coordinate(rmin() + idx * ddc::step()); - } - - double get_first_support_knot(discrete_element_type const& ix) const - { - return get_knot(ix.uid() - degree()); - } - - double get_last_support_knot(discrete_element_type const& ix) const - { - return get_knot(ix.uid() + 1); - } - - double get_support_knot_n(discrete_element_type const& ix, int n) const - { - return get_knot(ix.uid() + n - degree()); - } - - ddc::Coordinate rmin() const noexcept - { - return coord_from_knot(ddc::coordinate(m_domain.front())); - } - - ddc::Coordinate rmax() const noexcept - { - return coord_from_knot(ddc::coordinate(m_domain.back())); - } - - double length() const noexcept - { - return rmax() - rmin(); - } - - std::size_t size() const noexcept - { - return degree() + ncells(); - } - - /// Returns the discrete domain including ghost bsplines - discrete_domain_type full_domain() const - { - return discrete_domain_type(discrete_element_type(0), discrete_vector_type(size())); - } - - std::size_t nbasis() const noexcept - { - return ncells() + !is_periodic() * degree(); - } - - std::size_t ncells() const noexcept - { - return m_domain.size() - 1; - } - - private: - double inv_step() const noexcept - { - return 1.0 / ddc::step(); - } - - discrete_element_type eval_basis( - DSpan1D values, - ddc::Coordinate const& x, - std::size_t degree) const; - void get_icell_and_offset(int& icell, double& offset, ddc::Coordinate const& x) const; - }; -}; - -template -template -ddc::DiscreteElement> UniformBSplines::Impl:: - eval_basis(DSpan1D const values, ddc::Coordinate const& x, std::size_t const deg) const -{ - assert(values.extent(0) == deg + 1); - - double offset; - int jmin; - // 1. Compute cell index 'icell' and x_offset - // 2. Compute index range of B-splines with support over cell 'icell' - get_icell_and_offset(jmin, offset, x); - - // 3. Compute values of aforementioned B-splines - double xx, temp, saved; - values(0) = 1.0; - for (std::size_t j = 1; j < deg + 1; ++j) { - xx = -offset; - saved = 0.0; - for (std::size_t r = 0; r < j; ++r) { - xx += 1; - temp = values(r) / j; - values(r) = saved + xx * temp; - saved = (j - xx) * temp; - } - values(j) = saved; - } - - return discrete_element_type(jmin); -} - -template -template -ddc::DiscreteElement> UniformBSplines::Impl< - MemorySpace>::eval_deriv(DSpan1D const derivs, ddc::Coordinate const& x) const -{ - assert(derivs.extent(0) == degree() + 1); - - double offset; - int jmin; - // 1. Compute cell index 'icell' and x_offset - // 2. Compute index range of B-splines with support over cell 'icell' - get_icell_and_offset(jmin, offset, x); - - // 3. Compute derivatives of aforementioned B-splines - // Derivatives are normalized, hence they should be divided by dx - double xx, temp, saved; - derivs(0) = 1.0 / ddc::step(); - for (std::size_t j = 1; j < degree(); ++j) { - xx = -offset; - saved = 0.0; - for (std::size_t r = 0; r < j; ++r) { - xx += 1.0; - temp = derivs(r) / j; - derivs(r) = saved + xx * temp; - saved = (j - xx) * temp; - } - derivs(j) = saved; - } - - // Compute derivatives - double bjm1 = derivs(0); - double bj = bjm1; - derivs(0) = -bjm1; - for (std::size_t j = 1; j < degree(); ++j) { - bj = derivs(j); - derivs(j) = bjm1 - bj; - bjm1 = bj; - } - derivs(degree()) = bj; - - return discrete_element_type(jmin); -} - -template -template -ddc::DiscreteElement> UniformBSplines::Impl:: - eval_basis_and_n_derivs( - DSpan2D const derivs, - ddc::Coordinate const& x, - std::size_t const n) const -{ - std::array ndu_ptr; - std::experimental::mdspan< - double, - std::experimental::extents> const - ndu(ndu_ptr.data()); - std::array a_ptr; - std::experimental:: - mdspan> const a( - a_ptr.data()); - double offset; - int jmin; - - assert(x >= rmin()); - assert(x <= rmax()); - // assert(n >= 0); as long as n is unsigned - assert(n <= degree()); - assert(derivs.extent(0) == 1 + degree()); - assert(derivs.extent(1) == 1 + n); - - // 1. Compute cell index 'icell' and x_offset - // 2. Compute index range of B-splines with support over cell 'icell' - get_icell_and_offset(jmin, offset, x); - - // 3. Recursively evaluate B-splines (see - // "sll_s_uniform_BSplines_eval_basis") - // up to self%degree, and store them all in the upper-right triangle of - // ndu - double xx, temp, saved; - ndu(0, 0) = 1.0; - for (std::size_t j = 1; j < degree() + 1; ++j) { - xx = -offset; - saved = 0.0; - for (std::size_t r = 0; r < j; ++r) { - xx += 1.0; - temp = ndu(j - 1, r) / j; - ndu(j, r) = saved + xx * temp; - saved = (j - xx) * temp; - } - ndu(j, j) = saved; - } - for (std::size_t i = 0; i < ndu.extent(1); ++i) { - derivs(i, 0) = ndu(degree(), i); - } - - for (int r = 0; r < int(degree() + 1); ++r) { - int s1 = 0; - int s2 = 1; - a(0, 0) = 1.0; - for (int k = 1; k < int(n + 1); ++k) { - double d = 0.0; - int const rk = r - k; - int const pk = degree() - k; - if (r >= k) { - a(0, s2) = a(0, s1) / (pk + 1); - d = a(0, s2) * ndu(pk, rk); - } - int const j1 = rk > -1 ? 1 : (-rk); - int const j2 = (r - 1) <= pk ? k : (degree() - r + 1); - for (int j = j1; j < j2; ++j) { - a(j, s2) = (a(j, s1) - a(j - 1, s1)) / (pk + 1); - d += a(j, s2) * ndu(pk, rk + j); - } - if (r <= pk) { - a(k, s2) = -a(k - 1, s1) / (pk + 1); - d += a(k, s2) * ndu(pk, r); - } - derivs(r, k) = d; - std::swap(s1, s2); - } - } - - // Multiply result by correct factors: - // degree!/(degree-n)! = degree*(degree-1)*...*(degree-n+1) - // k-th derivatives are normalized, hence they should be divided by dx^k - double const inv_dx = inv_step(); - double d = degree() * inv_dx; - for (int k = 1; k < int(n + 1); ++k) { - for (std::size_t i = 0; i < derivs.extent(0); ++i) { - derivs(i, k) *= d; - } - d *= (degree() - k) * inv_dx; - } - - return discrete_element_type(jmin); -} - -template -template -void UniformBSplines::Impl::get_icell_and_offset( - int& icell, - double& offset, - ddc::Coordinate const& x) const -{ - assert(x >= rmin()); - assert(x <= rmax()); - - double const inv_dx = inv_step(); - if (x == rmin()) { - icell = 0; - offset = 0.0; - } else if (x == rmax()) { - icell = ncells() - 1; - offset = 1.0; - } else { - offset = (x - rmin()) * inv_dx; - icell = static_cast(offset); - offset = offset - icell; - - // When x is very close to xmax, round-off may cause the wrong answer - // icell=ncells and x_offset=0, which we convert to the case x=xmax: - if (icell == int(ncells()) && offset == 0.0) { - icell = ncells() - 1; - offset = 1.0; - } - } -} - -template -template -ddc::ChunkSpan>> UniformBSplines::Impl< - MemorySpace>::integrals(ddc::ChunkSpan>> - int_vals) const -{ - if constexpr (is_periodic()) { - assert(int_vals.size() == nbasis() || int_vals.size() == size()); - } else { - assert(int_vals.size() == nbasis()); - } - discrete_domain_type const full_dom_splines(full_domain()); - - if constexpr (is_periodic()) { - discrete_domain_type const dom_bsplines( - full_dom_splines.take_first(discrete_vector_type {nbasis()})); - for (auto ix : dom_bsplines) { - int_vals(ix) = ddc::step(); - } - if (int_vals.size() == size()) { - discrete_domain_type const dom_bsplines_repeated( - full_dom_splines.take_last(discrete_vector_type {degree()})); - for (auto ix : dom_bsplines_repeated) { - int_vals(ix) = 0; - } - } - } else { - discrete_domain_type const dom_bspline_entirely_in_domain - = full_dom_splines - .remove(discrete_vector_type(degree()), discrete_vector_type(degree())); - for (auto ix : dom_bspline_entirely_in_domain) { - int_vals(ix) = ddc::step(); - } - - std::array edge_vals_ptr; - std::experimental:: - mdspan> const - edge_vals(edge_vals_ptr.data()); - - eval_basis(edge_vals, rmin(), degree() + 1); - - double const d_eval = sum(edge_vals); - - for (std::size_t i = 0; i < degree(); ++i) { - double const c_eval = sum(edge_vals, 0, degree() - i); - - double const edge_value = ddc::step() * (d_eval - c_eval); - - int_vals(discrete_element_type(i)) = edge_value; - int_vals(discrete_element_type(nbasis() - 1 - i)) = edge_value; - } - } - return int_vals; -} diff --git a/vendor/sll/include/sll/constant_extrapolation_boundary_value.hpp b/vendor/sll/include/sll/constant_extrapolation_boundary_value.hpp deleted file mode 100644 index 2b8753e32..000000000 --- a/vendor/sll/include/sll/constant_extrapolation_boundary_value.hpp +++ /dev/null @@ -1,267 +0,0 @@ -#pragma once - -#include - -#include "sll/view.hpp" - -/** - * @brief A class for describing a spline boundary value by a constant extrapolation for 1D evaluator. - * - * To define the value of a function on B-splines out of the domain, we here use a constant - * extrapolation on the edge. - * - * @see SplineBoundaryValue - */ -template -class ConstantExtrapolationBoundaryValue : public SplineBoundaryValue -{ -public: - /** - * @brief Indicate the dimension we are working on. - */ - using tag_type = typename BSplines::tag_type; - /** - * @brief Indicate the coordinate type in the dimension of the boundary condition. - */ - using coord_type = ddc::Coordinate; - -private: - coord_type m_eval_pos; - -public: - /** - * @brief Instantiate a ConstantExtrapolationBoundaryValue. - * - * The boundary value will be the same as at the coordinate eval_pos given. - * - * @param[in] eval_pos - * Coordinate inside the domain where we will evaluate each points outside the domain. - */ - explicit ConstantExtrapolationBoundaryValue(coord_type eval_pos) : m_eval_pos(eval_pos) {} - - ~ConstantExtrapolationBoundaryValue() override = default; - - /** - * @brief Get the value of the function on B-splines at a coordinate outside the domain. - * - * @param[in] pos - * The coordinate where we want to evaluate the function on B-splines. - * @param[in] spline_coef - * The coefficients of the function on B-splines. - * - *@return A double with the value of the function on B-splines evaluated at the coordinate. - */ - double operator()( - coord_type const pos, - ddc::ChunkSpan> const spline_coef) - const final - { - std::array values; - DSpan1D const vals = as_span(values); - - ddc::DiscreteElement idx - = ddc::discrete_space().eval_basis(vals, m_eval_pos); - - double y = 0.0; - for (std::size_t i = 0; i < BSplines::degree() + 1; ++i) { - y += spline_coef(idx + i) * vals(i); - } - return y; - } -}; - - - -/** - * @brief A class for describing a spline boundary value by a constant extrapolation for 2D evaluator. - * - * To define the value of a function on B-splines out of the domain, we here use a constant - * extrapolation on the edge. - * - * @see SplineBoundaryValue - */ -template -class ConstantExtrapolationBoundaryValue2D : public SplineBoundaryValue2D -{ -public: - /** - * @brief Indicate the first dimension we are working on. - */ - using Dim1 = typename BSplines1::tag_type; - /** - * @brief Indicate the second dimension we are working on. - */ - using Dim2 = typename BSplines2::tag_type; - /** - * @brief Indicate coordinate type in the first dimension we are working on. - */ - using coord_type1 = ddc::Coordinate; - /** - * @brief Indicate coordinate type in the second dimension we are working on. - */ - using coord_type2 = ddc::Coordinate; - /** - * @brief Indicate coordinate type in the dimension of the boundary condition. - */ - using coord_type_bc = ddc::Coordinate; - /** - * @brief Indicate the complementary dimension of the boundary condition dimension. - */ - using NoBCDim = typename std::conditional_t, Dim2, Dim1>; - /** - * @brief Indicate the coordinate type of the complementary dimension of the boundary condition dimension. - */ - using coord_type_no_bc = ddc::Coordinate; - /** - * @brief Boolean set at True if the Bsplines on the first dimension is periodic. - */ - static constexpr bool BSplines1_is_periodic = BSplines1::is_periodic(); - /** - * @brief Boolean set at True if the Bsplines on the second dimension is periodic. - */ - static constexpr bool BSplines2_is_periodic = BSplines2::is_periodic(); - /** - * @brief Boolean set at True if the Bsplines on the complementary dimension of the boundary - * condition dimension is periodic. - */ - static constexpr bool BSplinesNoBC_is_periodic - = std::is_same_v ? BSplines2_is_periodic : BSplines1_is_periodic; - - - - static_assert(std::is_same_v || std::is_same_v); - static_assert(std::is_same_v || std::is_same_v); - -private: - coord_type_bc const m_eval_pos_bc; - coord_type_no_bc const m_eval_pos_no_bc_min; - coord_type_no_bc const m_eval_pos_no_bc_max; - -public: - /** - * @brief Instantiate a ConstantExtrapolationBoundaryValue2D. - * - * The boundary value will be the same as at the coordinate given in a dimension given. - * The dimension of the input defines the dimension of the boundary condition. - * The second and the third parameters are needed in case of non-periodic splines on the - * no-boundary condition dimension (the complementary dimension of the boundary condition), - * because the evaluator can receive coordinates outside the domain in both dimension. - * - * @param[in] eval_pos_bc - * Coordinate in the dimension given inside the domain where we will evaluate - * each points outside the domain. - * @param[in] eval_pos_no_bc_min - * The minimum coordinate inside the domain on the complementary dimension of the boundary condition. - * @param[in] eval_pos_no_bc_max - * The maximum coordinate inside the domain on the complementary dimension of the boundary condition. - */ - template > - explicit ConstantExtrapolationBoundaryValue2D( - coord_type_bc const eval_pos_bc, - coord_type_no_bc const eval_pos_no_bc_min, - coord_type_no_bc const eval_pos_no_bc_max) - : m_eval_pos_bc(eval_pos_bc) - , m_eval_pos_no_bc_min(eval_pos_no_bc_min) - , m_eval_pos_no_bc_max(eval_pos_no_bc_max) - { - } - - /** - * @brief Instantiate a ConstantExtrapolationBoundaryValue2D with periodic splines - * on the no-boundary condition dimension. - * - * The boundary value will be the same as at the coordinate given in a dimension given. - * The dimension of the input defines the dimension of the boundary condition. - * This constructor can only be used with periodic splines on the no-boundary condition - * dimension. Otherwise, we have to use the previous constructor. - * - * @param[in] eval_pos_bc - * Coordinate in the dimension given inside the domain where we will evaluate - * each point outside the domain. - */ - template > - explicit ConstantExtrapolationBoundaryValue2D(coord_type_bc const eval_pos_bc) - : m_eval_pos_bc(eval_pos_bc) - , m_eval_pos_no_bc_min(coord_type_no_bc(0.)) - , m_eval_pos_no_bc_max(coord_type_no_bc(0.)) - { - } - - - ~ConstantExtrapolationBoundaryValue2D() override = default; - - /** - * @brief Get the value of the function on B-splines at a coordinate outside the domain. - * - * In the dimension defined in the constructor Dim1 (or Dim2), it sets the coordinate pos_1 (or pos_2) - * given at the m_eval_pos_bc coordinate if it is outside the domain. - * If the coordinate on the complementary dimension of the boundary condition dimension pos_2 (or pos_1) is - * outside the domain, then it also sets the coordinate at eval_pos_no_bc_min - * (if pos_2 (or pos_1) @f$ < @f$ eval_pos_no_bc_min) or - * at eval_pos_no_bc_max (if pos_2 (or pos_1) @f$ > @f$ eval_pos_no_bc_max). - * - * @param[in] pos_1 - * The coordinate in the first dimension where we want to evaluate the function on B-splines - * @param[in] pos_2 - * The coordinate in the second dimension where we want to evaluate the function on B-splines. - * @param[in] spline_coef - * The coefficients of the function on B-splines. - * - *@return A double with the value of the function on B-splines evaluated at the coordinate. - */ - double operator()( - coord_type1 const pos_1, - coord_type2 const pos_2, - ddc::ChunkSpan> const - spline_coef) const final - { - coord_type1 eval_pos_1; - coord_type2 eval_pos_2; - - if constexpr (BSplinesNoBC_is_periodic) { - if constexpr (std::is_same_v) { - eval_pos_1 = m_eval_pos_bc; - eval_pos_2 = pos_2; - } else { - eval_pos_1 = pos_1; - eval_pos_2 = m_eval_pos_bc; - } - - } else { - double bc_min = m_eval_pos_no_bc_min; - double bc_max = m_eval_pos_no_bc_max; - - if constexpr (std::is_same_v) { - eval_pos_1 = m_eval_pos_bc; - // Take the maximum between m_eval_pos_no_bc_min and pos_2 - // and the minimum between m_eval_pos_no_bc_max and pos_2 - // to be inside the domain. - eval_pos_2 = coord_type2(std::max(bc_min, std::min(bc_max, double(pos_2)))); - } else { - // Take the maximum between m_eval_pos_no_bc_min and pos_1 - // and the minimum between m_eval_pos_no_bc_max and pos_1 - // to be inside the domain. - eval_pos_1 = coord_type1(std::max(bc_min, std::min(bc_max, double(pos_1)))); - eval_pos_2 = m_eval_pos_bc; - } - } - - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - ddc::DiscreteElement idx1 - = ddc::discrete_space().eval_basis(vals1, eval_pos_1); - ddc::DiscreteElement idx2 - = ddc::discrete_space().eval_basis(vals2, eval_pos_2); - - double y = 0.0; - for (std::size_t i = 0; i < BSplines1::degree() + 1; ++i) { - for (std::size_t j = 0; j < BSplines2::degree() + 1; ++j) { - y += spline_coef(idx1 + i, idx2 + j) * vals1(i) * vals2(j); - } - } - return y; - } -}; diff --git a/vendor/sll/include/sll/deprecated/boundary_conditions.hpp b/vendor/sll/include/sll/deprecated/boundary_conditions.hpp deleted file mode 100644 index 1a183f166..000000000 --- a/vendor/sll/include/sll/deprecated/boundary_conditions.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -enum class BoundCond { - // Periodic boundary condition u(1)=u(n) - PERIODIC, - // Hermite boundary condition - HERMITE, - // Use Greville points instead of conditions on derivative for B-Spline - // interpolation - GREVILLE, -}; - -static inline std::ostream& operator<<(std::ostream& out, BoundCond bc) -{ - switch (bc) { - case BoundCond::PERIODIC: - return out << "PERIODIC"; - case BoundCond::HERMITE: - return out << "HERMITE"; - case BoundCond::GREVILLE: - return out << "GREVILLE"; - default: - std::exit(1); - } -} diff --git a/vendor/sll/include/sll/deprecated/bsplines.hpp b/vendor/sll/include/sll/deprecated/bsplines.hpp deleted file mode 100644 index 115e0fb5d..000000000 --- a/vendor/sll/include/sll/deprecated/bsplines.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include "sll/view.hpp" - -namespace deprecated { - -class BSplines -{ -protected: - int m_degree; - bool m_radial; - int m_nbasis; - - /// TODO: take all that from a Mesh object - int m_ncells; - bool m_periodic; - double m_xmin; - double m_xmax; - double m_length; - -public: - virtual ~BSplines() = default; - - constexpr inline int degree() const - { - return m_degree; - } - - constexpr inline bool radial() const - { - return m_radial; - } - - constexpr inline int nbasis() const - { - return m_nbasis; - } - - constexpr inline int ncells() const - { - return m_ncells; - } - - constexpr inline bool is_periodic() const - { - return m_periodic; - } - - constexpr inline double xmin() const - { - return m_xmin; - } - - constexpr inline double xmax() const - { - return m_xmax; - } - - constexpr inline double length() const - { - return m_length; - } - - virtual void eval_basis(double x, DSpan1D& values, int& jmin) const = 0; - - virtual void eval_deriv(double x, DSpan1D& derivs, int& jmin) const = 0; - - virtual void eval_basis_and_n_derivs(double x, int n, DSpan2D& derivs, int& jmin) const = 0; - - virtual void integrals(DSpan1D& int_vals) const = 0; - - virtual double get_knot(int idx) const = 0; - - virtual bool is_uniform() const = 0; - -protected: - BSplines( - int degree, - bool periodic, - int ncells, - int nbasis, - double xmin, - double xmax, - bool radial); -}; - -} // namespace deprecated diff --git a/vendor/sll/include/sll/deprecated/bsplines_non_uniform.hpp b/vendor/sll/include/sll/deprecated/bsplines_non_uniform.hpp deleted file mode 100644 index 3bac444ab..000000000 --- a/vendor/sll/include/sll/deprecated/bsplines_non_uniform.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include -#include - -#include "sll/deprecated/bsplines.hpp" -#include "sll/view.hpp" - -namespace deprecated { - -class NonUniformBSplines : public BSplines -{ -private: - std::unique_ptr m_knots; - - int m_npoints; - -public: - NonUniformBSplines() = delete; - NonUniformBSplines(int degree, bool periodic, const std::vector& breaks); - NonUniformBSplines(const NonUniformBSplines& x) = delete; - NonUniformBSplines(NonUniformBSplines&& x) = delete; - virtual ~NonUniformBSplines() = default; - NonUniformBSplines& operator=(const NonUniformBSplines& x) = delete; - NonUniformBSplines& operator=(NonUniformBSplines&& x) = delete; - - int npoints() const noexcept - { - return m_npoints; - } - - virtual void eval_basis(double x, DSpan1D& values, int& jmin) const override; - virtual void eval_deriv(double x, DSpan1D& derivs, int& jmin) const override; - virtual void eval_basis_and_n_derivs(double x, int n, DSpan2D& derivs, int& jmin) - const override; - virtual void integrals(DSpan1D& int_vals) const override; - - virtual double get_knot(int break_idx) const override - { - // TODO: assert break_idx >= 1 - degree - // TODO: assert break_idx <= npoints + degree - return m_knots[break_idx + m_degree]; - } - - bool is_uniform() const override; - -private: - int find_cell(double x) const; - - inline double& get_knot(int break_idx) - { - // TODO: assert break_idx >= 1 - degree - // TODO: assert break_idx <= npoints + degree - return m_knots[break_idx + m_degree]; - } -}; - -} // namespace deprecated diff --git a/vendor/sll/include/sll/deprecated/bsplines_uniform.hpp b/vendor/sll/include/sll/deprecated/bsplines_uniform.hpp deleted file mode 100644 index f36da088a..000000000 --- a/vendor/sll/include/sll/deprecated/bsplines_uniform.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "sll/deprecated/bsplines.hpp" -#include "sll/view.hpp" - -namespace deprecated { - -class UniformBSplines : public BSplines -{ -private: - double m_inv_dx; - - double m_dx; - -public: - UniformBSplines() = delete; - UniformBSplines(int degree, bool periodic, double xmin, double xmax, int ncells); - UniformBSplines(const UniformBSplines& x) = delete; - UniformBSplines(UniformBSplines&& x) = delete; - virtual ~UniformBSplines() = default; - UniformBSplines& operator=(const UniformBSplines& x) = delete; - UniformBSplines& operator=(UniformBSplines&& x) = delete; - virtual inline void eval_basis(double x, DSpan1D& values, int& jmin) const override - { - return eval_basis(x, values, jmin, m_degree); - } - virtual void eval_deriv(double x, DSpan1D& derivs, int& jmin) const override; - virtual void eval_basis_and_n_derivs(double x, int n, DSpan2D& derivs, int& jmin) - const override; - virtual void integrals(DSpan1D& int_vals) const override; - - virtual double get_knot(int idx) const override - { - return m_xmin + idx * m_dx; - } - - bool is_uniform() const override; - -private: - void eval_basis(double x, DSpan1D& values, int& jmin, int degree) const; - void get_icell_and_offset(double x, int& icell, double& offset) const; -}; - -} // namespace deprecated diff --git a/vendor/sll/include/sll/deprecated/spline_1d.hpp b/vendor/sll/include/sll/deprecated/spline_1d.hpp deleted file mode 100644 index f7e7ee1d0..000000000 --- a/vendor/sll/include/sll/deprecated/spline_1d.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#include "sll/null_boundary_value.hpp" -#include "sll/view.hpp" - -class BoundaryValue; - -namespace deprecated { -class BSplines; - -class Spline1D -{ -private: - // Friends - friend class SplineBuilder1D; - friend class SplineBuilder2D; - -private: - std::unique_ptr m_bcoef_ptr; - DSpan1D m_bcoef; - const BSplines& m_bspl; - const BoundaryValue& m_left_bc; - const BoundaryValue& m_right_bc; - -public: - Spline1D() = delete; - Spline1D( - const BSplines& bspl, - const BoundaryValue& left_bc = NullBoundaryValue::value, - const BoundaryValue& right_bc = NullBoundaryValue::value); - Spline1D(const Spline1D& x) = delete; - Spline1D(Spline1D&& x) = delete; - ~Spline1D() = default; - Spline1D& operator=(const Spline1D& x) = delete; - Spline1D& operator=(Spline1D&& x) = delete; - - DSpan1D const& bcoef() const noexcept - { - return m_bcoef; - } - - double const& bcoef(std::size_t i) const noexcept - { - return m_bcoef(i); - } - - double& bcoef(std::size_t i) noexcept - { - return m_bcoef(i); - } - - bool belongs_to_space(const BSplines& bspline) const; - double eval(double x) const; - double eval_deriv(double x) const; - void eval_array(DSpan1D const x, DSpan1D y) const; - void eval_array_deriv(DSpan1D const x, DSpan1D y) const; - double integrate() const; - -private: - // Internal templated functions - template >* = nullptr> - double eval_intern_no_bcs(double x, const T& bspl, DSpan1D& vals) const; - template >* = nullptr> - double eval_intern(double x, const T& bspl, DSpan1D& vals) const; - template >* = nullptr> - double eval_deriv_intern(double x, const T& bspl, DSpan1D& vals) const; - template >* = nullptr> - void eval_array_loop(DSpan1D const& x, DSpan1D& y) const; - template >* = nullptr> - void eval_array_deriv_loop(DSpan1D const& x, DSpan1D& y) const; -}; - -} // namespace deprecated diff --git a/vendor/sll/include/sll/deprecated/spline_2d.hpp b/vendor/sll/include/sll/deprecated/spline_2d.hpp deleted file mode 100644 index 75e9680de..000000000 --- a/vendor/sll/include/sll/deprecated/spline_2d.hpp +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "sll/view.hpp" - -namespace deprecated { -class BSplines; - -class Spline2D -{ -private: - friend class SplineBuilder2D; - -private: - std::unique_ptr m_bcoef_ptr; - DSpan2D m_bcoef; - const BSplines& m_bspl1; - const BSplines& m_bspl2; - -public: - Spline2D() = delete; - Spline2D(const BSplines& bspl1, const BSplines& bspl2); - Spline2D(const Spline2D& x) = delete; - Spline2D(Spline2D&& x) = delete; - ~Spline2D() = default; - Spline2D& operator=(const Spline2D& x) = delete; - Spline2D& operator=(Spline2D&& x) = delete; - - DSpan2D const& bcoef() const noexcept - { - return m_bcoef; - } - - double& bcoef(std::size_t i, std::size_t j) const noexcept - { - return m_bcoef(i, j); - } - - bool belongs_to_space(const BSplines& bspline1, const BSplines& bspline2) const; - double eval(const double x1, const double x2) const; - template - double eval_deriv(const double x1, const double x2) const; - void eval_array(DSpan2D const& x1, DSpan2D const& x2, DSpan2D& y) const; - template - void eval_array_deriv(DSpan2D const& x1, DSpan2D const& x2, DSpan2D& y) const; - void integrate_dim(DSpan1D& y, const int dim) const; - double integrate() const; - -private: - template < - class T1, - class T2, - bool deriv1, - bool deriv2, - std::enable_if_t>* = nullptr, - std::enable_if_t>* = nullptr> - double eval_intern( - double x1, - double x2, - const T1& bspl1, - const T2& bspl2, - DSpan1D& vals1, - DSpan1D& vals2) const; - template < - class T1, - std::enable_if_t>* = nullptr, - class T2, - std::enable_if_t>* = nullptr> - void eval_array_loop(DSpan2D const& x1, DSpan2D const& x2, DSpan2D& y) const; -}; - -} // namespace deprecated diff --git a/vendor/sll/include/sll/deprecated/spline_builder_1d.hpp b/vendor/sll/include/sll/deprecated/spline_builder_1d.hpp deleted file mode 100644 index 8cdf8ed84..000000000 --- a/vendor/sll/include/sll/deprecated/spline_builder_1d.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -#include -#include - -#include "sll/deprecated/boundary_conditions.hpp" -#include "sll/matrix.hpp" -#include "sll/view.hpp" - -namespace deprecated { -class BSplines; -class Spline1D; - -class SplineBuilder1D -{ -private: - // hand-made inheritance - static std::array allowed_bcs; - -private: - const BSplines& bspl; - - // bspline stuff: TODO move - const bool odd; // bspl.degree % 2 == 1 - const int offset; // bspl.periodic ? bspl.degree / 2 : 0 - const double dx; // average cell size for normalization of derivatives - - // mesh info: TODO use Mesh - std::unique_ptr interp_pts_ptr; - DSpan1D interp_pts; - - // interpolator specific - std::unique_ptr matrix; - - const BoundCond m_xmin_bc; - - const BoundCond m_xmax_bc; - - const int m_nbc_xmin; - - const int m_nbc_xmax; - -public: - SplineBuilder1D() = delete; - SplineBuilder1D(const BSplines& bspl, BoundCond xmin_bc, BoundCond xmax_bc); - SplineBuilder1D(const SplineBuilder1D& x) = delete; - SplineBuilder1D(SplineBuilder1D&& x) = delete; - ~SplineBuilder1D() = default; - SplineBuilder1D& operator=(const SplineBuilder1D& x) = delete; - SplineBuilder1D& operator=(SplineBuilder1D&& x) = delete; - - const DSpan1D& get_interp_points() const; - - void compute_interpolant( - Spline1D& spline, - const DSpan1D& vals, - const DSpan1D* derivs_xmin = nullptr, - const DSpan1D* derivs_xmax = nullptr) const; - - static int compute_num_cells(int degree, BoundCond xmin, BoundCond xmax, int nipts); - - BoundCond xmin_bc() const noexcept - { - return m_xmin_bc; - } - - BoundCond xmax_bc() const noexcept - { - return m_xmax_bc; - } - - int nbc_xmin() const noexcept - { - return m_nbc_xmin; - } - - int nbc_xmax() const noexcept - { - return m_nbc_xmax; - } - -private: - void compute_interpolation_points_uniform(); - void compute_interpolation_points_non_uniform(); - void compute_block_sizes_uniform(int& kl, int& ku) const; - void compute_block_sizes_non_uniform(int& kl, int& ku) const; - - void constructor_sanity_checks() const; - void allocate_matrix(int kl, int ku); - void compute_interpolant_degree1(Spline1D& spline, const DSpan1D& vals) const; - void build_matrix_system(); -}; - -} // namespace deprecated diff --git a/vendor/sll/include/sll/deprecated/spline_builder_2d.hpp b/vendor/sll/include/sll/deprecated/spline_builder_2d.hpp deleted file mode 100644 index 33fe329a6..000000000 --- a/vendor/sll/include/sll/deprecated/spline_builder_2d.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include -#include - -#include "sll/view.hpp" - -#include "boundary_conditions.hpp" - -namespace deprecated { -class BSplines; -class Spline1D; -class Spline2D; -class SplineBuilder1D; - -struct Boundary_data_2d -{ - DSpan2D* derivs_x1_min = nullptr; - DSpan2D* derivs_x1_max = nullptr; - DSpan2D* derivs_x2_min = nullptr; - DSpan2D* derivs_x2_max = nullptr; - DSpan2D* mixed_derivs_a = nullptr; - DSpan2D* mixed_derivs_b = nullptr; - DSpan2D* mixed_derivs_c = nullptr; - DSpan2D* mixed_derivs_d = nullptr; -}; - -class SplineBuilder2D -{ -private: - const std::array, 2> bspl; - std::array interp_1d; - // TODO: Improve - std::array spline_1d; - -public: - const std::array m_xmin_bc; - const std::array m_xmax_bc; - const std::array m_nbc_xmin; - const std::array m_nbc_xmax; - -public: - SplineBuilder2D() = delete; - SplineBuilder2D( - std::array, 2> bspl, - std::array xmin_bc, - std::array xmax_bc); - SplineBuilder2D(const SplineBuilder2D& x) = delete; - SplineBuilder2D(SplineBuilder2D&& x) = delete; - ~SplineBuilder2D() = default; - SplineBuilder2D& operator=(const SplineBuilder2D& x) = delete; - SplineBuilder2D& operator=(SplineBuilder2D&& x) = delete; - - std::array get_interp_points() const; - - void compute_interpolant( - Spline2D const& spline, - DSpan2D const& vals, - Boundary_data_2d boundary_data) const; - - void compute_interpolant(Spline2D const& spline, DSpan2D const& vals) const; - - static std::array compute_num_cells( - std::array degree, - std::array xmin, - std::array xmax, - std::array nipts); - - std::array const& xmin_bc() const noexcept - { - return m_xmin_bc; - } - - std::array const& xmax_bc() const noexcept - { - return m_xmax_bc; - } - - std::array const& nbc_xmin() const noexcept - { - return m_nbc_xmin; - } - - std::array const& nbc_xmax() const noexcept - { - return m_nbc_xmax; - } - -private: - void compute_interpolant_boundary_done(Spline2D const& spline, DSpan2D const& vals) const; -}; - -} // namespace deprecated diff --git a/vendor/sll/include/sll/greville_interpolation_points.hpp b/vendor/sll/include/sll/greville_interpolation_points.hpp deleted file mode 100644 index 3f623ff02..000000000 --- a/vendor/sll/include/sll/greville_interpolation_points.hpp +++ /dev/null @@ -1,233 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#include - -/** - * A class which provides helper functions to initialise the Greville points from a B-Spline definition. - * - * @tparam BSplines The bspline class relative to which the Greville points will be calculated. - * @tparam BcXmin The (left) boundary condition that will be used to build the splines. - * @tparam BcXmax The (right) boundary condition that will be used to build the splines. - */ -template -class GrevilleInterpolationPoints -{ - using tag_type = typename BSplines::tag_type; - - template > - static auto uniform_greville_points() - { - using Sampling = ddc::UniformPointSampling; - using SamplingImpl = typename Sampling::template Impl; - - double constexpr shift = (BSplines::degree() % 2 == 0) ? 0.5 : 0.0; - double dx - = (ddc::discrete_space().rmax() - ddc::discrete_space().rmin()) - / ddc::discrete_space().ncells(); - return SamplingImpl( - ddc::Coordinate(ddc::discrete_space().rmin() + shift * dx), - ddc::Coordinate(dx)); - } - - template > - static auto non_uniform_greville_points() - { - using Sampling = ddc::NonUniformPointSampling; - using SamplingImpl = typename Sampling::template Impl; - - int n_greville_points = ddc::discrete_space().nbasis(); - if constexpr (U::is_periodic()) { - n_greville_points += 1; - } - - std::vector greville_points(n_greville_points); - ddc::DiscreteDomain bspline_domain - = ddc::discrete_space().full_domain().take_first( - ddc::DiscreteVector(ddc::discrete_space().nbasis())); - - ddc::for_each(bspline_domain, [&](ddc::DiscreteElement ib) { - // Define the Greville points from the bspline knots - greville_points[ib.uid()] = 0.0; - for (std::size_t i(0); i < BSplines::degree(); ++i) { - greville_points[ib.uid()] - += ddc::discrete_space().get_support_knot_n(ib, i + 1); - } - greville_points[ib.uid()] /= BSplines::degree(); - }); - - std::vector temp_knots(BSplines::degree()); - // Use periodicity to ensure all points are in the domain - if constexpr (U::is_periodic()) { - int npoints(0); - // Count the number of interpolation points that need shifting to preserve the ordering - while (greville_points[npoints] < ddc::discrete_space().rmin()) { - temp_knots[npoints] - = greville_points[npoints] + ddc::discrete_space().length(); - npoints++; - } - // Shift the points - for (std::size_t i = 0; i < ddc::discrete_space().nbasis() - npoints; ++i) { - greville_points[i] = greville_points[i + npoints]; - } - for (int i = 0; i < npoints; ++i) { - greville_points[ddc::discrete_space().nbasis() - npoints + i] - = temp_knots[i]; - } - - // Save a periodic point to initialise the domain size - greville_points[n_greville_points - 1] - = greville_points[0] + ddc::discrete_space().length(); - } - - return SamplingImpl(greville_points); - } - - static constexpr int N_BE_MIN = n_boundary_equations(BcXmin, BSplines::degree()); - static constexpr int N_BE_MAX = n_boundary_equations(BcXmax, BSplines::degree()); - template - static constexpr bool is_uniform_mesh_v - = U::is_uniform() && ((N_BE_MIN != 0 && N_BE_MAX != 0) || U::is_periodic()); - -public: - /** - * Get the UniformPointSampling defining the Greville points. - * - * This function is called when the result is a UniformPointSampling. This is the case - * when uniform splines are used with an odd degree and with boundary conditions which - * do not introduce additional interpolation points. - * - * @returns The mesh of uniform Greville points. - */ - template < - typename U = BSplines, - std::enable_if_t< - is_uniform_mesh_v, - bool> = true> // U must be in condition for SFINAE - static auto get_sampling() - { - return uniform_greville_points(); - } - - /** - * Get the NonUniformPointSampling defining the Greville points. - * - * @returns The mesh of non-uniform Greville points. - */ - template < - typename U = BSplines, - std::enable_if_t< - !is_uniform_mesh_v, - bool> = true> // U must be in condition for SFINAE - static auto get_sampling() - { - using Sampling = ddc::NonUniformPointSampling; - using SamplingImpl = typename Sampling::template Impl; - if constexpr (U::is_uniform()) { - auto points_wo_bcs = uniform_greville_points(); - int const n_break_points = ddc::discrete_space().ncells() + 1; - int const npoints = ddc::discrete_space().nbasis() - N_BE_MIN - N_BE_MAX; - std::vector points_with_bcs(npoints); - - // Construct Greville-like points at the edge - if constexpr (BcXmin == BoundCond::GREVILLE) { - for (std::size_t i(0); i < BSplines::degree() / 2 + 1; ++i) { - points_with_bcs[i] - = (BSplines::degree() - i) * ddc::discrete_space().rmin(); - for (std::size_t j(0); j < i; ++j) { - points_with_bcs[i] += ddc::discrete_space().get_support_knot_n( - ddc::DiscreteElement(i), - BSplines::degree() - j); - } - points_with_bcs[i] /= BSplines::degree(); - } - } else { - points_with_bcs[0] = points_wo_bcs.coordinate( - ddc::DiscreteElement>(0)); - } - - int const n_start = (BcXmin == BoundCond::GREVILLE) ? BSplines::degree() / 2 + 1 : 1; - int const domain_size = n_break_points - 2; - ddc::DiscreteDomain> const - domain(ddc::DiscreteElement>(1), - ddc::DiscreteVector>(domain_size)); - - // Copy central points - ddc::for_each(domain, [&](auto ip) { - points_with_bcs[ip.uid() + n_start - 1] = points_wo_bcs.coordinate(ip); - }); - - // Construct Greville-like points at the edge - if constexpr (BcXmax == BoundCond::GREVILLE) { - for (std::size_t i(0); i < BSplines::degree() / 2 + 1; ++i) { - points_with_bcs[npoints - 1 - i] - = (BSplines::degree() - i) * ddc::discrete_space().rmax(); - for (std::size_t j(0); j < i; ++j) { - points_with_bcs[npoints - 1 - i] - += ddc::discrete_space().get_support_knot_n( - ddc::DiscreteElement( - ddc::discrete_space().nbasis() - 1 - i), - j + 1); - } - points_with_bcs[npoints - 1 - i] /= BSplines::degree(); - } - } else { - points_with_bcs[npoints - 1] = points_wo_bcs.coordinate( - ddc::DiscreteElement>( - ddc::discrete_space().ncells() - 1 - + BSplines::degree() % 2)); - } - return SamplingImpl(points_with_bcs); - } else { - auto points_wo_bcs = non_uniform_greville_points(); - if constexpr (N_BE_MIN == 0 && N_BE_MAX == 0) { - return points_wo_bcs; - } else { - // All points are Greville points. Extract unnecessary points near the boundary - std::vector points_with_bcs(points_wo_bcs.size() - N_BE_MIN - N_BE_MAX); - int constexpr n_start = N_BE_MIN; - - using length = ddc::DiscreteVector>; - - ddc::DiscreteDomain> const - domain(ddc::DiscreteElement>( - n_start), - length(points_with_bcs.size())); - - points_with_bcs[0] = points_wo_bcs.coordinate(domain.front()); - ddc::for_each(domain.remove(length(1), length(1)), [&](auto ip) { - points_with_bcs[ip.uid() - n_start] = points_wo_bcs.coordinate(ip); - }); - points_with_bcs[points_with_bcs.size() - 1] - = points_wo_bcs.coordinate(domain.back()); - - return SamplingImpl(points_with_bcs); - } - } - } - - /** - * The type of the mesh. - * - * This is either NonUniformPointSampling or UniformPointSampling. - */ - using interpolation_mesh_type = typename decltype(get_sampling())::discrete_dimension_type; - - /** - * Get the domain which gives us access to all of the Greville points. - * - * @returns The domain of the Greville points. - */ - static ddc::DiscreteDomain get_domain() - { - int const npoints = ddc::discrete_space().nbasis() - N_BE_MIN - N_BE_MAX; - return ddc::DiscreteDomain( - ddc::DiscreteElement(0), - ddc::DiscreteVector(npoints)); - } -}; diff --git a/vendor/sll/include/sll/knots_as_interpolation_points.hpp b/vendor/sll/include/sll/knots_as_interpolation_points.hpp deleted file mode 100644 index 65fad3d12..000000000 --- a/vendor/sll/include/sll/knots_as_interpolation_points.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include - -#include - -#include - -/** - * @brief Helper class for the initialisation of the mesh of interpolation points. - * - * A helper class for the initialisation of the mesh of interpolation points. This - * class should be used when the interpolation points should be located at the - * knots of the spline. This is possible with any kind of boundary condition except - * Greville boundary conditions (as there will not be enough interpolation points). - * In the case of strongly non-uniform splines this choice may result in a less - * well conditioned problem, however most mathematical stability results are proven - * with this choice of interpolation points. - */ -template -class KnotsAsInterpolationPoints -{ - static_assert(BcXmin != BoundCond::GREVILLE); - static_assert(BcXmax != BoundCond::GREVILLE); - - using tag_type = typename BSplines::tag_type; - -public: - /** - * Get the sampling of interpolation points. - * - * @return sampling The DDC point sampling of the interpolation points. - */ - template - static auto get_sampling() - { - if constexpr (U::is_uniform()) { - using Sampling = ddc::UniformPointSampling; - return std::get<0>( - Sampling:: - init(ddc::discrete_space().rmin(), - ddc::discrete_space().rmax(), - ddc::DiscreteVector>( - ddc::discrete_space().ncells() + 1))); - } else { - using Sampling = ddc::NonUniformPointSampling; - using SamplingImpl = typename Sampling::template Impl; - std::vector knots(ddc::discrete_space().npoints()); - for (int i(0); i < ddc::discrete_space().npoints(); ++i) { - knots[i] = ddc::discrete_space().get_knot(i); - } - return SamplingImpl(knots); - } - } - - /// The DDC type of the sampling for the interpolation points. - using interpolation_mesh_type = typename decltype(get_sampling())::discrete_dimension_type; - - /** - * Get the domain which can be used to access the interpolation points in the sampling. - * - * @return domain The DDC discrete domain which maps to the sampling of interpolation points. - */ - static ddc::DiscreteDomain get_domain() - { - int const npoints = ddc::discrete_space().ncells() + !BSplines::is_periodic(); - return ddc::DiscreteDomain( - ddc::DiscreteElement(0), - ddc::DiscreteVector(npoints)); - } -}; diff --git a/vendor/sll/include/sll/mapping/discrete_mapping_to_cartesian.hpp b/vendor/sll/include/sll/mapping/discrete_mapping_to_cartesian.hpp index 167b2f2d9..80f3a3ee7 100644 --- a/vendor/sll/include/sll/mapping/discrete_mapping_to_cartesian.hpp +++ b/vendor/sll/include/sll/mapping/discrete_mapping_to_cartesian.hpp @@ -1,11 +1,9 @@ #pragma once #include +#include #include -#include -#include -#include /** @@ -22,7 +20,7 @@ * * @see Curvilinear2DToCartesian */ -template +template class DiscreteToCartesian : public Curvilinear2DToCartesian< DimX, @@ -76,10 +74,15 @@ class DiscreteToCartesian using interpolation_domain = typename SplineBuilder::interpolation_domain_type; using spline_domain = ddc::DiscreteDomain; + using SplineType = ddc::Chunk< + double, + spline_domain, + ddc::KokkosAllocator>; + private: - ddc::Chunk x_spline_representation; - ddc::Chunk y_spline_representation; - SplineEvaluator2D const& spline_evaluator; + SplineType x_spline_representation; + SplineType y_spline_representation; + SplineEvaluator const& spline_evaluator; public: /** @@ -110,9 +113,9 @@ class DiscreteToCartesian * @see SplineBoundaryValue */ DiscreteToCartesian( - ddc::Chunk&& curvilinear_to_x, - ddc::Chunk&& curvilinear_to_y, - SplineEvaluator2D const& evaluator) + SplineType&& curvilinear_to_x, + SplineType&& curvilinear_to_y, + SplineEvaluator const& evaluator) : x_spline_representation(std::move(curvilinear_to_x)) , y_spline_representation(std::move(curvilinear_to_y)) , spline_evaluator(evaluator) @@ -135,8 +138,8 @@ class DiscreteToCartesian ddc::Coordinate operator()( ddc::Coordinate const& coord) const final { - const double x = spline_evaluator(coord, x_spline_representation); - const double y = spline_evaluator(coord, y_spline_representation); + const double x = spline_evaluator(coord, x_spline_representation.span_cview()); + const double y = spline_evaluator(coord, y_spline_representation.span_cview()); return ddc::Coordinate(x, y); } @@ -162,10 +165,10 @@ class DiscreteToCartesian ddc::Coordinate const& coord, Matrix_2x2& matrix) const final { - matrix[0][0] = spline_evaluator.deriv_dim_1(coord, x_spline_representation); - matrix[0][1] = spline_evaluator.deriv_dim_2(coord, x_spline_representation); - matrix[1][0] = spline_evaluator.deriv_dim_1(coord, y_spline_representation); - matrix[1][1] = spline_evaluator.deriv_dim_2(coord, y_spline_representation); + matrix[0][0] = spline_evaluator.deriv_dim_1(coord, x_spline_representation.span_cview()); + matrix[0][1] = spline_evaluator.deriv_dim_2(coord, x_spline_representation.span_cview()); + matrix[1][0] = spline_evaluator.deriv_dim_1(coord, y_spline_representation.span_cview()); + matrix[1][1] = spline_evaluator.deriv_dim_2(coord, y_spline_representation.span_cview()); } /** @@ -186,7 +189,7 @@ class DiscreteToCartesian */ double jacobian_11(ddc::Coordinate const& coord) const final { - return spline_evaluator.deriv_dim_1(coord, x_spline_representation); + return spline_evaluator.deriv_dim_1(coord, x_spline_representation.span_cview()); } /** @@ -207,7 +210,7 @@ class DiscreteToCartesian */ double jacobian_12(ddc::Coordinate const& coord) const final { - return spline_evaluator.deriv_dim_2(coord, x_spline_representation); + return spline_evaluator.deriv_dim_2(coord, x_spline_representation.span_cview()); } /** @@ -228,7 +231,7 @@ class DiscreteToCartesian */ double jacobian_21(ddc::Coordinate const& coord) const final { - return spline_evaluator.deriv_dim_1(coord, y_spline_representation); + return spline_evaluator.deriv_dim_1(coord, y_spline_representation.span_cview()); } /** @@ -249,7 +252,7 @@ class DiscreteToCartesian */ double jacobian_22(ddc::Coordinate const& coord) const final { - return spline_evaluator.deriv_dim_2(coord, y_spline_representation); + return spline_evaluator.deriv_dim_2(coord, y_spline_representation.span_cview()); } @@ -314,12 +317,14 @@ class DiscreteToCartesian ddc::for_each(theta_domain, [&](auto const ip) { const double th = ddc::coordinate(ip); ddc::Coordinate const coord(0, th); - double const deriv_1_x = spline_evaluator.deriv_dim_1(coord, x_spline_representation); + double const deriv_1_x + = spline_evaluator.deriv_dim_1(coord, x_spline_representation.span_cview()); double const deriv_1_2_x - = spline_evaluator.deriv_1_and_2(coord, x_spline_representation); - double const deriv_1_y = spline_evaluator.deriv_dim_1(coord, y_spline_representation); + = spline_evaluator.deriv_1_and_2(coord, x_spline_representation.span_cview()); + double const deriv_1_y + = spline_evaluator.deriv_dim_1(coord, y_spline_representation.span_cview()); double const deriv_1_2_y - = spline_evaluator.deriv_1_and_2(coord, y_spline_representation); + = spline_evaluator.deriv_1_and_2(coord, y_spline_representation.span_cview()); // Matrix from pseudo-Cart domain to physical domain by logical domain double const j11 = deriv_1_x * std::cos(th) - deriv_1_2_x * std::sin(th); @@ -473,21 +478,23 @@ class DiscreteToCartesian * The spline builder on the B-splines on which we want to decompose the mapping. * @param[in] evaluator * The spline evaluator with which we want to evaluate the mapping. + * @tparam Mapping + * The analytical mapping described by this discrete mapping. * * @return A DiscreteToCartesian version of the analytical mapping. * - * @see SplineBuilder2D - * @see SplineEvaluator2D + * @see ddc::SplineBuilder2D + * @see ddc::SplineEvaluator2D */ - template + template static DiscreteToCartesian analytical_to_discrete( Mapping const& analytical_mapping, - Builder2D const& builder, - Evaluator2D const& evaluator) + SplineBuilder const& builder, + SplineEvaluator const& evaluator) { - using Domain = typename Builder2D::interpolation_domain_type; - ddc::Chunk curvilinear_to_x_spline(builder.spline_domain()); - ddc::Chunk curvilinear_to_y_spline(builder.spline_domain()); + using Domain = typename SplineBuilder::interpolation_domain_type; + SplineType curvilinear_to_x_spline(builder.spline_domain()); + SplineType curvilinear_to_y_spline(builder.spline_domain()); ddc::Chunk curvilinear_to_x_vals(builder.interpolation_domain()); ddc::Chunk curvilinear_to_y_vals(builder.interpolation_domain()); ddc::for_each( @@ -499,8 +506,8 @@ class DiscreteToCartesian curvilinear_to_x_vals(el) = ddc::select(cart_coord); curvilinear_to_y_vals(el) = ddc::select(cart_coord); }); - builder(curvilinear_to_x_spline, curvilinear_to_x_vals); - builder(curvilinear_to_y_spline, curvilinear_to_y_vals); + builder(curvilinear_to_x_spline.span_view(), curvilinear_to_x_vals.span_cview()); + builder(curvilinear_to_y_spline.span_view(), curvilinear_to_y_vals.span_cview()); return DiscreteToCartesian( std::move(curvilinear_to_x_spline), std::move(curvilinear_to_y_spline), diff --git a/vendor/sll/include/sll/mapping/refined_discrete_mapping_to_cartesian.hpp b/vendor/sll/include/sll/mapping/refined_discrete_mapping_to_cartesian.hpp index bf55dafbf..f994dc43c 100644 --- a/vendor/sll/include/sll/mapping/refined_discrete_mapping_to_cartesian.hpp +++ b/vendor/sll/include/sll/mapping/refined_discrete_mapping_to_cartesian.hpp @@ -1,15 +1,10 @@ #pragma once #include +#include -#include -#include -#include #include #include -#include -#include -#include /** @@ -27,7 +22,7 @@ * @see DiscreteToCartesian * @see Curvilinear2DToCartesian */ -template +template class RefinedDiscreteToCartesian : public Curvilinear2DToCartesian< RDimX, @@ -129,17 +124,17 @@ class RefinedDiscreteToCartesian private: using BSplineRRefined = std::conditional_t< BSplineR_uniform, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; using BSplinePRefined = std::conditional_t< BSplineP_uniform, - UniformBSplines, - NonUniformBSplines>; + ddc::UniformBSplines, + ddc::NonUniformBSplines>; - static auto constexpr SplineRBoundaryRefined_min = SplineRPBuilder::BcXmin1; - static auto constexpr SplineRBoundaryRefined_max = SplineRPBuilder::BcXmax1; - static auto constexpr SplinePBoundaryRefined_min = SplineRPBuilder::BcXmin2; - static auto constexpr SplinePBoundaryRefined_max = SplineRPBuilder::BcXmax2; + static auto constexpr SplineRBoundaryRefined_min = SplineRPBuilder::builder_type1::s_bc_xmin; + static auto constexpr SplineRBoundaryRefined_max = SplineRPBuilder::builder_type1::s_bc_xmax; + static auto constexpr SplinePBoundaryRefined_min = SplineRPBuilder::builder_type2::s_bc_xmin; + static auto constexpr SplinePBoundaryRefined_max = SplineRPBuilder::builder_type2::s_bc_xmax; static bool constexpr UniformMeshR @@ -158,34 +153,51 @@ class RefinedDiscreteToCartesian ddc::NonUniformPointSampling>; - using SplineRBuilderRefined = SplineBuilder< + using REvalBoundary = ddc::ConstantExtrapolationRule; + + using SplineRPBuilderRefined = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, BSplineRRefined, + BSplinePRefined, IDimRRefined, + IDimPRefined, SplineRBoundaryRefined_min, - SplineRBoundaryRefined_max>; - using SplinePBuilderRefined = SplineBuilder< + SplineRBoundaryRefined_max, + SplinePBoundaryRefined_min, + SplinePBoundaryRefined_max, + ddc::SplineSolver::GINKGO, + IDimRRefined, + IDimPRefined>; + + using SplineRPEvaluatorRefined = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplineRRefined, BSplinePRefined, + IDimRRefined, IDimPRefined, - SplinePBoundaryRefined_min, - SplinePBoundaryRefined_max>; - using SplineRPBuilderRefined = SplineBuilder2D; + REvalBoundary, + REvalBoundary, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimRRefined, + IDimPRefined>; using CoordRRefined = ddc::Coordinate; using CoordPRefined = ddc::Coordinate; using CoordRPRefined = ddc::Coordinate; - using SplineInterpPointsRRefined = GrevilleInterpolationPoints< + using SplineInterpPointsRRefined = ddc::GrevilleInterpolationPoints< BSplineRRefined, SplineRBoundaryRefined_min, SplineRBoundaryRefined_max>; - using SplineInterpPointsPRefined = GrevilleInterpolationPoints< + using SplineInterpPointsPRefined = ddc::GrevilleInterpolationPoints< BSplinePRefined, SplinePBoundaryRefined_min, SplinePBoundaryRefined_max>; - using SplineRPEvaluatorRefined = SplineEvaluator2D; - using BSDomainRRefined = ddc::DiscreteDomain; using BSDomainPRefined = ddc::DiscreteDomain; using BSDomainRPRefined = ddc::DiscreteDomain; @@ -205,9 +217,6 @@ class RefinedDiscreteToCartesian using spline_domain = ddc::DiscreteDomain; - using REvalBoundary - = ConstantExtrapolationBoundaryValue2D; - /** * @brief Define a 2x2 matrix with an 2D array of an 2D array. */ @@ -217,7 +226,11 @@ class RefinedDiscreteToCartesian REvalBoundary const boundary_condition_r_left; REvalBoundary const boundary_condition_r_right; SplineRPEvaluatorRefined const refined_evaluator; - DiscreteToCartesian const m_mapping; + DiscreteToCartesian< + RDimXRefined, + RDimYRefined, + SplineRPBuilderRefined, + SplineRPEvaluatorRefined> const m_mapping; static inline ddc::Coordinate to_refined(ddc::Coordinate const& coord) @@ -319,8 +332,8 @@ class RefinedDiscreteToCartesian , refined_evaluator( boundary_condition_r_left, boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d) + ddc::PeriodicExtrapolationRule(), + ddc::PeriodicExtrapolationRule()) , m_mapping(std::move(curvilinear_to_x), std::move(curvilinear_to_y), refined_evaluator) { } @@ -642,8 +655,8 @@ class RefinedDiscreteToCartesian curvilinear_to_x_vals(el) = ddc::select(cart_coord); curvilinear_to_y_vals(el) = ddc::select(cart_coord); }); - refined_builder(curvilinear_to_x_spline, curvilinear_to_x_vals); - refined_builder(curvilinear_to_y_spline, curvilinear_to_y_vals); + refined_builder(curvilinear_to_x_spline.span_view(), curvilinear_to_x_vals.span_cview()); + refined_builder(curvilinear_to_y_spline.span_view(), curvilinear_to_y_vals.span_cview()); return RefinedDiscreteToCartesian( refined_domain, diff --git a/vendor/sll/include/sll/null_boundary_value.hpp b/vendor/sll/include/sll/null_boundary_value.hpp deleted file mode 100644 index 721c6f124..000000000 --- a/vendor/sll/include/sll/null_boundary_value.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "sll/spline_boundary_value.hpp" - -template -class NullBoundaryValue : public SplineBoundaryValue -{ -public: - NullBoundaryValue() = default; - - ~NullBoundaryValue() override = default; - - double operator()( - ddc::Coordinate, - ddc::ChunkSpan>) const final - { - return 0.0; - } -}; - -template -inline NullBoundaryValue const g_null_boundary; - -template -class NullBoundaryValue2D : public SplineBoundaryValue2D -{ -public: - NullBoundaryValue2D() = default; - - ~NullBoundaryValue2D() override = default; - - double operator()( - ddc::Coordinate x, - ddc::Coordinate y, - ddc::ChunkSpan>) const final - { - return 0.0; - } -}; - -template -inline NullBoundaryValue2D const g_null_boundary_2d; - -template -class PolarNullBoundaryValue2D : public PolarSplineBoundaryValue2D -{ -public: - PolarNullBoundaryValue2D() = default; - - ~PolarNullBoundaryValue2D() override = default; - - double operator()(double x, double y, PolarSplineView) const final - { - return 0.0; - } -}; - -template -inline PolarNullBoundaryValue2D const g_polar_null_boundary_2d; diff --git a/vendor/sll/include/sll/polar_bsplines.hpp b/vendor/sll/include/sll/polar_bsplines.hpp index d543f53c7..fb63c0941 100644 --- a/vendor/sll/include/sll/polar_bsplines.hpp +++ b/vendor/sll/include/sll/polar_bsplines.hpp @@ -5,14 +5,9 @@ #include #include -#include #include #include -#include #include -#include -#include -#include #include /** @@ -230,12 +225,16 @@ class PolarBSplines * @param spline_builder_r A class which can be used to construct the coefficients of a radial bspline. * @param spline_builder_p A class which can be used to construct the coefficients of a poloidal bspline. */ - template - Impl(const DiscreteToCartesian>& - curvilinear_to_cartesian, + template + Impl(const DiscreteMapping& curvilinear_to_cartesian, SplineBuilderR const& spline_builder_r, SplineBuilderP const& spline_builder_p) { + using DimX = typename DiscreteMapping::cartesian_tag_x; + using DimY = typename DiscreteMapping::cartesian_tag_y; + using mapping_tensor_product_discrete_element_type = ddc::DiscreteElement< + typename DiscreteMapping::BSplineR, + typename DiscreteMapping::BSplineP>; if constexpr (C > -1) { const ddc::Coordinate pole = curvilinear_to_cartesian(ddc::Coordinate(0.0, 0.0)); @@ -245,7 +244,7 @@ class PolarBSplines for (std::size_t i(0); i < ddc::discrete_space().size(); ++i) { const ddc::Coordinate point = curvilinear_to_cartesian.control_point( - tensor_product_discrete_element_type(1, i)); + mapping_tensor_product_discrete_element_type(1, i)); const double c_x = ddc::get(point); const double c_y = ddc::get(point); @@ -313,7 +312,7 @@ class PolarBSplines spline_builder_p.spline_domain().take_first(np_in_singular)) { const ddc::Coordinate point = curvilinear_to_cartesian.control_point( - tensor_product_discrete_element_type(ir, ip)); + mapping_tensor_product_discrete_element_type(ir, ip)); ddc::Chunk> bernstein_vals( bernstein_domain); ddc::discrete_space().eval_basis(bernstein_vals, point); @@ -601,10 +600,8 @@ ddc::DiscreteElement PolarBSplines vals_r_data; - std::array vals_p_data; - DSpan1D vals_r(vals_r_data.data(), nr); - DSpan1D vals_p(vals_p_data.data(), np); + std::array vals_r; + std::array vals_p; if constexpr (std::is_same_v) { jmin_r = ddc::discrete_space().eval_basis(vals_r, ddc::select(coord_eval)); @@ -626,7 +623,7 @@ ddc::DiscreteElement PolarBSplines PolarBSplines::Impl::integrals( assert(int_vals.spline_coef.domain().template extent() == p_bspl_space.nbasis() || int_vals.spline_coef.domain().template extent() == p_bspl_space.size()); - ddc::Chunk r_integrals( + ddc::Chunk r_integrals_alloc( r_bspl_space.full_domain().take_first( typename BSplinesR::discrete_vector_type {r_bspl_space.nbasis()})); - ddc::Chunk p_integrals( + ddc::Chunk p_integrals_alloc( p_bspl_space.full_domain().take_first( typename BSplinesP::discrete_vector_type {p_bspl_space.size()})); + ddc::ChunkSpan r_integrals = r_integrals_alloc.span_view(); + ddc::ChunkSpan p_integrals = p_integrals_alloc.span_view(); r_bspl_space.integrals(r_integrals); p_bspl_space.integrals(p_integrals); diff --git a/vendor/sll/include/sll/polar_spline.hpp b/vendor/sll/include/sll/polar_spline.hpp index 8303e7736..87055d314 100644 --- a/vendor/sll/include/sll/polar_spline.hpp +++ b/vendor/sll/include/sll/polar_spline.hpp @@ -2,6 +2,12 @@ #include +template +struct PolarSplineSpan; + +template +struct PolarSplineView; + /** * @brief A structure containing the two Chunks necessary to define a spline on a set of * polar basis splines. @@ -68,6 +74,26 @@ struct PolarSpline ddc::DiscreteVector(PolarBSplinesType::n_singular_basis()))) { } + + /** + * Get a modifiable reference to this polar spline. + * + * @return A modifiable reference to this polar spline. + */ + PolarSplineSpan span_view() + { + return PolarSplineSpan(*this); + } + + /** + * Get a constant reference to this polar spline view. + * + * @return A constant reference to this polar spline. + */ + PolarSplineView span_cview() + { + return PolarSplineView(*this); + } }; /** @@ -109,6 +135,26 @@ struct PolarSplineSpan , singular_spline_coef(spl.singular_spline_coef.span_view()) { } + + /** + * Get a modifiable reference to the polar spline referenced by this polar spline view. + * + * @return A modifiable reference to a polar spline. + */ + PolarSplineSpan span_view() + { + return *this; + } + + /** + * Get a constant reference to the polar spline referenced by this polar spline view. + * + * @return A constant reference to a polar spline. + */ + PolarSplineView span_cview() + { + return PolarSplineView(*this); + } }; /** @@ -150,4 +196,35 @@ struct PolarSplineView , singular_spline_coef(spl.singular_spline_coef.span_cview()) { } + + /** + * Construct a constant reference to a PolarSpline from a PolarSplineSpan + * + * @param spl The PolarSpline being referenced. + */ + PolarSplineView(PolarSplineSpan const& spl) + : spline_coef(spl.spline_coef.span_cview()) + , singular_spline_coef(spl.singular_spline_coef.span_cview()) + { + } + + /** + * Get a reference to the polar spline referenced by this polar spline view. + * + * @return A reference to a polar spline. + */ + PolarSplineSpan span_view() + { + return *this; + } + + /** + * Get a constant reference to the polar spline referenced by this polar spline view. + * + * @return A constant reference to a polar spline. + */ + PolarSplineView span_cview() + { + return *this; + } }; diff --git a/vendor/sll/include/sll/polar_spline_evaluator.hpp b/vendor/sll/include/sll/polar_spline_evaluator.hpp index 2d9bd925f..9dbfba389 100644 --- a/vendor/sll/include/sll/polar_spline_evaluator.hpp +++ b/vendor/sll/include/sll/polar_spline_evaluator.hpp @@ -1,13 +1,14 @@ #pragma once #include +#include /** * @brief Define an evaluator on polar B-splines. * * @see PolarBSplines */ -template +template class PolarSplineEvaluator { private: @@ -72,7 +73,7 @@ class PolarSplineEvaluator static int constexpr continuity = PolarBSplinesType::continuity; private: - PolarSplineBoundaryValue2D const& m_outer_bc; + OuterExtrapolationRule m_outer_bc; public: PolarSplineEvaluator() = delete; @@ -88,10 +89,7 @@ class PolarSplineEvaluator * A class containing an operator which can be called to provide a boundary value to * evaluate a point lying outside the domain. */ - explicit PolarSplineEvaluator(PolarSplineBoundaryValue2D const& outer_bc) - : m_outer_bc(outer_bc) - { - } + explicit PolarSplineEvaluator(OuterExtrapolationRule const& outer_bc) : m_outer_bc(outer_bc) {} /** * @brief Instantiate a PolarSplineEvaluator from another. @@ -339,7 +337,7 @@ class PolarSplineEvaluator const double coord_eval1 = ddc::get(coord_eval); double coord_eval2 = ddc::get(coord_eval); if (coord_eval1 > ddc::discrete_space().rmax()) { - return m_outer_bc(coord_eval1, coord_eval2, spline_coef); + return m_outer_bc(coord_eval, spline_coef); } if (coord_eval2 < ddc::discrete_space().rmin() || coord_eval2 > ddc::discrete_space().rmax()) { @@ -348,10 +346,7 @@ class PolarSplineEvaluator / ddc::discrete_space().length()) * ddc::discrete_space().length(); } - return eval_no_bc( - ddc::Coordinate(coord_eval1, coord_eval2), - spline_coef, - eval_type()); + return eval_no_bc(coord_eval, spline_coef, eval_type()); } template diff --git a/vendor/sll/include/sll/spline_boundary_conditions.hpp b/vendor/sll/include/sll/spline_boundary_conditions.hpp deleted file mode 100644 index 50a0c2861..000000000 --- a/vendor/sll/include/sll/spline_boundary_conditions.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include -#include - -enum class BoundCond { - // Periodic boundary condition u(1)=u(n) - PERIODIC, - // Hermite boundary condition - HERMITE, - // Use Greville points instead of conditions on derivative for B-Spline - // interpolation - GREVILLE, - // Natural boundary condition - NATURAL -}; - -static inline std::ostream& operator<<(std::ostream& out, BoundCond const bc) -{ - switch (bc) { - case BoundCond::PERIODIC: - return out << "PERIODIC"; - case BoundCond::HERMITE: - return out << "HERMITE"; - case BoundCond::GREVILLE: - return out << "GREVILLE"; - case BoundCond::NATURAL: - return out << "NATURAL"; - default: - throw std::runtime_error("BoundCond not handled"); - } -} - -constexpr int n_boundary_equations(BoundCond const bc, std::size_t const degree) -{ - if (bc == BoundCond::PERIODIC) { - return 0; - } else if (bc == BoundCond::HERMITE) { - return degree / 2; - } else if (bc == BoundCond::GREVILLE) { - return 0; - } else if (bc == BoundCond::NATURAL) { - return degree / 2; - } else { - throw std::runtime_error("BoundCond not handled"); - } -} - -constexpr int n_user_input(BoundCond const bc, std::size_t const degree) -{ - if (bc == BoundCond::PERIODIC) { - return 0; - } else if (bc == BoundCond::HERMITE) { - return degree / 2; - } else if (bc == BoundCond::GREVILLE) { - return 0; - } else if (bc == BoundCond::NATURAL) { - return 0; - } else { - throw std::runtime_error("BoundCond not handled"); - } -} diff --git a/vendor/sll/include/sll/spline_boundary_value.hpp b/vendor/sll/include/sll/spline_boundary_value.hpp deleted file mode 100644 index 562e8dbaa..000000000 --- a/vendor/sll/include/sll/spline_boundary_value.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include - -#include - -#include - -template -class SplineBoundaryValue -{ -public: - virtual ~SplineBoundaryValue() = default; - - virtual double operator()( - ddc::Coordinate x, - ddc::ChunkSpan>) const = 0; -}; - -template -class SplineBoundaryValue2D -{ -public: - virtual ~SplineBoundaryValue2D() = default; - - virtual double operator()( - ddc::Coordinate x, - ddc::Coordinate y, - ddc::ChunkSpan>) const = 0; -}; - -template -class PolarSplineBoundaryValue2D -{ -public: - virtual ~PolarSplineBoundaryValue2D() = default; - - virtual double operator()(double x, double y, PolarSplineView) const = 0; -}; diff --git a/vendor/sll/include/sll/spline_builder.hpp b/vendor/sll/include/sll/spline_builder.hpp deleted file mode 100644 index d55ba3b86..000000000 --- a/vendor/sll/include/sll/spline_builder.hpp +++ /dev/null @@ -1,558 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "sll/math_tools.hpp" -#include "sll/matrix.hpp" -#include "sll/spline_boundary_conditions.hpp" -#include "sll/view.hpp" - -constexpr bool is_spline_interpolation_mesh_uniform( - bool const is_uniform, - BoundCond const BcXmin, - BoundCond const BcXmax, - int degree) -{ - int N_BE_MIN = n_boundary_equations(BcXmin, degree); - int N_BE_MAX = n_boundary_equations(BcXmax, degree); - bool is_periodic = (BcXmin == BoundCond::PERIODIC) && (BcXmax == BoundCond::PERIODIC); - return is_uniform && ((N_BE_MIN != 0 && N_BE_MAX != 0) || is_periodic); -} - -/** - * @brief A class for creating a spline approximation of a function. - * - * A class which contains an operator () which can be used to build a spline approximation - * of a function. A spline approximation is represented by coefficients stored in a Chunk - * of BSplines. The spline is constructed such that it respects the boundary conditions - * BcXmin and BcXmax, and it interpolates the function at the points on the interpolation_mesh - * associated with interpolation_mesh_type. - */ -template -class SplineBuilder -{ - static_assert( - (BSplines::is_periodic() && (BcXmin == BoundCond::PERIODIC) - && (BcXmax == BoundCond::PERIODIC)) - || (!BSplines::is_periodic() && (BcXmin != BoundCond::PERIODIC) - && (BcXmax != BoundCond::PERIODIC))); - static_assert(!BSplines::is_radial()); - -private: - using tag_type = typename interpolation_mesh_type::continuous_dimension_type; - -public: - /** - * @brief The type of the BSplines which are compatible with this class. - */ - using bsplines_type = BSplines; - - /** - * @brief The type of the interpolation mesh used by this class. - */ - using mesh_type = interpolation_mesh_type; - - /** - * @brief The type of the domain for the interpolation mesh used by this class. - */ - using interpolation_domain_type = ddc::DiscreteDomain; - -public: - /** - * @brief Indicates if the degree of the splines is odd or even. - */ - static constexpr bool s_odd = BSplines::degree() % 2; - - /** - * @brief The number of equations which define the boundary conditions at the lower bound. - */ - static constexpr int s_nbe_xmin = n_boundary_equations(BcXmin, BSplines::degree()); - - /** - * @brief The number of equations which define the boundary conditions at the upper bound. - */ - static constexpr int s_nbe_xmax = n_boundary_equations(BcXmax, BSplines::degree()); - - /** - * @brief The number of boundary conditions which must be provided by the user at the lower bound. - * - * This value is usually equal to s_nbe_xmin, but it may be difference if the chosen boundary - * conditions impose a specific value (e.g. no values need to be provided for Dirichlet boundary - * conditions). - */ - static constexpr int s_nbc_xmin = n_user_input(BcXmin, BSplines::degree()); - - /** - * @brief The number of boundary conditions which must be provided by the user at the upper bound. - * - * This value is usually equal to s_nbe_xmin, but it may be difference if the chosen boundary - * conditions impose a specific value (e.g. no values need to be provided for Dirichlet boundary - * conditions). - */ - static constexpr int s_nbc_xmax = n_user_input(BcXmax, BSplines::degree()); - - /** - * @brief The boundary condition implemented at the lower bound. - */ - static constexpr BoundCond s_bc_xmin = BcXmin; - /** - * @brief The boundary condition implemented at the upper bound. - */ - static constexpr BoundCond s_bc_xmax = BcXmax; - -private: - interpolation_domain_type m_interpolation_domain; - - double m_dx; // average cell size for normalization of derivatives - - // interpolator specific - std::unique_ptr matrix; - - int m_offset; - -public: - /** - * @brief Create a new SplineBuilder. - * - * @param interpolation_domain The domain on which points will be provided in order to - * create the spline approximation. - */ - SplineBuilder(interpolation_domain_type const& interpolation_domain); - - /** - * @brief Create a new SplineBuilder by copy - * - * @param x The SplineBuilder being copied. - */ - SplineBuilder(SplineBuilder const& x) = delete; - - /** - * @brief Create a new SplineBuilder by copy - * - * @param x The SplineBuilder being copied. - */ - SplineBuilder(SplineBuilder&& x) = default; - - ~SplineBuilder() = default; - - SplineBuilder& operator=(SplineBuilder const& x) = delete; - - /** - * @brief Copy a SplineBuilder. - * - * @param x The SplineBuilder being copied. - * @returns A reference to this object. - */ - SplineBuilder& operator=(SplineBuilder&& x) = default; - - /** - * @brief Build a spline approximation of a function. - * - * Use the values of a function at known grid points (as specified by - * SplineBuilder::interpolation_domain) and the derivatives of the - * function at the boundaries (if necessary for the chosen boundary - * conditions) to calculate a spline approximation of a function. - * - * The spline approximation is stored as a ChunkSpan of coefficients - * associated with basis-splines. - * - * @param[out] spline The coefficients of the spline calculated by the function. - * @param[in] vals The values of the function at the grid points. - * @param[in] derivs_xmin The values of the derivatives at the lower boundary. - * @param[in] derivs_xmax The values of the derivatives at the upper boundary. - */ - void operator()( - ddc::ChunkSpan> spline, - ddc::ChunkSpan vals, - std::optional const derivs_xmin = std::nullopt, - std::optional const derivs_xmax = std::nullopt) const; - - /** - * @brief Get the domain from which the approximation is defined. - * - * Get the domain on which values of the function must be provided in order - * to build a spline approximation of the function. - * - * @return The domain for the grid points. - */ - interpolation_domain_type const& interpolation_domain() const noexcept - { - return m_interpolation_domain; - } - - /** - * @brief Get the domain on which the approximation is defined. - * - * Get the domain of the basis-splines for which the coefficients of the spline - * approximation must be calculated. - * - * @return The domain for the splines. - */ - ddc::DiscreteDomain spline_domain() const noexcept - { - return ddc::discrete_space().full_domain(); - } - - /** - * @brief Get the interpolation matrix. - * - * Get the interpolation matrix. This can be useful for debugging (as it allows - * one to print the matrix) or for more complex quadrature schemes. - * - * @return A reference to the interpolation matrix. - */ - const Matrix& get_interpolation_matrix() const noexcept - { - return *matrix; - } - -private: - void compute_block_sizes_uniform(int& lower_block_size, int& upper_block_size) const; - - void compute_block_sizes_non_uniform(int& lower_block_size, int& upper_block_size) const; - - void allocate_matrix(int lower_block_size, int upper_block_size); - - void compute_interpolant_degree1( - ddc::ChunkSpan> spline, - ddc::ChunkSpan vals) const; - - void build_matrix_system(); -}; - -template -SplineBuilder::SplineBuilder( - interpolation_domain_type const& interpolation_domain) - : m_interpolation_domain(interpolation_domain) - , m_dx((ddc::discrete_space().rmax() - ddc::discrete_space().rmin()) - / ddc::discrete_space().ncells()) - , matrix(nullptr) - , m_offset(0) -{ - if constexpr (bsplines_type::is_periodic()) { - // Calculate offset so that the matrix is diagonally dominant - std::array values_ptr; - DSpan1D values(values_ptr.data(), bsplines_type::degree() + 1); - ddc::DiscreteElement start(interpolation_domain.front()); - auto jmin = ddc::discrete_space() - .eval_basis(values, ddc::coordinate(start + BSplines::degree())); - if constexpr (bsplines_type::degree() % 2 == 0) { - m_offset = jmin.uid() - start.uid() + bsplines_type::degree() / 2 - BSplines::degree(); - } else { - int const mid = bsplines_type::degree() / 2; - m_offset = jmin.uid() - start.uid() + (values(mid) > values(mid + 1) ? mid : mid + 1) - - BSplines::degree(); - } - } - - // Calculate block sizes - int lower_block_size, upper_block_size; - if constexpr (bsplines_type::is_uniform()) { - compute_block_sizes_uniform(lower_block_size, upper_block_size); - } else { - compute_block_sizes_non_uniform(lower_block_size, upper_block_size); - } - allocate_matrix(lower_block_size, upper_block_size); -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Compute interpolant functions * - ************************************************************************************/ - -template -void SplineBuilder::compute_interpolant_degree1( - ddc::ChunkSpan> const spline, - ddc::ChunkSpan const vals) const -{ - for (std::size_t i = 0; i < ddc::discrete_space().nbasis(); ++i) { - spline(ddc::DiscreteElement(i)) - = vals(ddc::DiscreteElement(i)); - } - if constexpr (bsplines_type::is_periodic()) { - spline(ddc::DiscreteElement(ddc::discrete_space().nbasis())) - = spline(ddc::DiscreteElement(0)); - } -} - -//------------------------------------------------------------------------------------------------- - -template -void SplineBuilder::operator()( - ddc::ChunkSpan> const spline, - ddc::ChunkSpan const vals, - std::optional const derivs_xmin, - std::optional const derivs_xmax) const -{ - assert(vals.template extent() - == ddc::discrete_space().nbasis() - s_nbe_xmin - s_nbe_xmax); - // assert(spline.belongs_to_space(ddc::discrete_space())); - // TODO: LOG Errors - if constexpr (bsplines_type::degree() == 1) - return compute_interpolant_degree1(spline, vals); - - assert((BcXmin == BoundCond::HERMITE) - != (!derivs_xmin.has_value() || derivs_xmin->extent(0) == 0)); - assert((BcXmax == BoundCond::HERMITE) - != (!derivs_xmax.has_value() || derivs_xmax->extent(0) == 0)); - - // Hermite boundary conditions at xmin, if any - // NOTE: For consistency with the linear system, the i-th derivative - // provided by the user must be multiplied by dx^i - if constexpr (BcXmin == BoundCond::HERMITE) { - assert(derivs_xmin->extent(0) == s_nbc_xmin); - for (int i = s_nbc_xmin; i > 0; --i) { - spline(ddc::DiscreteElement(s_nbc_xmin - i)) - = (*derivs_xmin)(i - 1) * ipow(m_dx, i + s_odd - 1); - } - } - for (int i = s_nbc_xmin; i < s_nbc_xmin + m_offset; ++i) { - spline(ddc::DiscreteElement(i)) = 0.0; - } - - for (int i = 0; i < m_interpolation_domain.extents(); ++i) { - spline(ddc::DiscreteElement(s_nbc_xmin + i + m_offset)) - = vals(ddc::DiscreteElement(i)); - } - - // Hermite boundary conditions at xmax, if any - // NOTE: For consistency with the linear system, the i-th derivative - // provided by the user must be multiplied by dx^i - if constexpr (BcXmax == BoundCond::HERMITE) { - assert(derivs_xmax->extent(0) == s_nbc_xmax); - for (int i = 0; i < s_nbc_xmax; ++i) { - spline(ddc::DiscreteElement( - ddc::discrete_space().nbasis() - s_nbc_xmax + i)) - = (*derivs_xmax)(i)*ipow(m_dx, i + s_odd); - } - } - - DSpan1D const bcoef_section( - spline.data_handle() + m_offset, - ddc::discrete_space().nbasis()); - matrix->solve_inplace(bcoef_section); - - if constexpr (bsplines_type::is_periodic()) { - if (m_offset != 0) { - for (int i = 0; i < m_offset; ++i) { - spline(ddc::DiscreteElement(i)) - = spline(ddc::DiscreteElement( - ddc::discrete_space().nbasis() + i)); - } - for (std::size_t i = m_offset; i < bsplines_type::degree(); ++i) { - spline(ddc::DiscreteElement( - ddc::discrete_space().nbasis() + i)) - = spline(ddc::DiscreteElement(i)); - } - } - } -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Compute num diags functions * - ************************************************************************************/ - -template -void SplineBuilder::compute_block_sizes_uniform( - int& lower_block_size, - int& upper_block_size) const -{ - switch (BcXmin) { - case BoundCond::PERIODIC: - upper_block_size = (bsplines_type::degree()) / 2; - break; - case BoundCond::NATURAL: - case BoundCond::HERMITE: - upper_block_size = s_nbc_xmin; - break; - case BoundCond::GREVILLE: - upper_block_size = bsplines_type::degree() - 1; - break; - default: - throw std::runtime_error("BoundCond not handled"); - } - switch (BcXmax) { - case BoundCond::PERIODIC: - lower_block_size = (bsplines_type::degree()) / 2; - break; - case BoundCond::NATURAL: - case BoundCond::HERMITE: - lower_block_size = s_nbc_xmax; - break; - case BoundCond::GREVILLE: - lower_block_size = bsplines_type::degree() - 1; - break; - default: - throw std::runtime_error("BoundCond not handled"); - } -} - -//------------------------------------------------------------------------------------------------- - -template -void SplineBuilder:: - compute_block_sizes_non_uniform(int& lower_block_size, int& upper_block_size) const -{ - switch (BcXmin) { - case BoundCond::PERIODIC: - upper_block_size = bsplines_type::degree() - 1; - break; - case BoundCond::HERMITE: - upper_block_size = s_nbc_xmin + 1; - break; - case BoundCond::GREVILLE: - upper_block_size = bsplines_type::degree() - 1; - break; - default: - throw std::runtime_error("BoundCond not handled"); - } - switch (BcXmax) { - case BoundCond::PERIODIC: - lower_block_size = bsplines_type::degree() - 1; - break; - case BoundCond::HERMITE: - lower_block_size = s_nbc_xmax + 1; - break; - case BoundCond::GREVILLE: - lower_block_size = bsplines_type::degree() - 1; - break; - default: - throw std::runtime_error("BoundCond not handled"); - } -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Initialize matrix functions * - ************************************************************************************/ - -template -void SplineBuilder::allocate_matrix( - int lower_block_size, - int upper_block_size) -{ - // Special case: linear spline - // No need for matrix assembly - if constexpr (bsplines_type::degree() == 1) - return; - - int upper_band_width; - if (bsplines_type::is_uniform()) { - upper_band_width = bsplines_type::degree() / 2; - } else { - upper_band_width = bsplines_type::degree() - 1; - } - - if constexpr (bsplines_type::is_periodic()) { - matrix = Matrix::make_new_periodic_banded( - ddc::discrete_space().nbasis(), - upper_band_width, - upper_band_width, - bsplines_type::is_uniform()); - } else { - matrix = Matrix::make_new_block_with_banded_region( - ddc::discrete_space().nbasis(), - upper_band_width, - upper_band_width, - bsplines_type::is_uniform(), - upper_block_size, - lower_block_size); - } - - build_matrix_system(); - - matrix->factorize(); -} - -//------------------------------------------------------------------------------------------------- - -template -void SplineBuilder::build_matrix_system() -{ - // Hermite boundary conditions at xmin, if any - if constexpr (BcXmin == BoundCond::HERMITE) { - double derivs_ptr[(bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)]; - DSpan2D derivs(derivs_ptr, bsplines_type::degree() + 1, bsplines_type::degree() / 2 + 1); - ddc::discrete_space().eval_basis_and_n_derivs( - derivs, - ddc::discrete_space().rmin(), - s_nbc_xmin); - - // In order to improve the condition number of the matrix, we normalize - // all derivatives by multiplying the i-th derivative by dx^i - for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) { - for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) { - derivs(i, j) *= ipow(m_dx, j); - } - } - - // iterate only to deg as last bspline is 0 - for (std::size_t i = 0; i < s_nbc_xmin; ++i) { - for (std::size_t j = 0; j < bsplines_type::degree(); ++j) { - matrix->set_element(i, j, derivs(j, s_nbc_xmin - i - 1 + s_odd)); - } - } - } - - // Interpolation points - std::array values_ptr; - std::experimental::mdspan< - double, - std::experimental::extents> const - values(values_ptr.data()); - int start = m_interpolation_domain.front().uid(); - ddc::for_each(m_interpolation_domain, [&](auto ix) { - auto jmin = ddc::discrete_space().eval_basis( - values, - ddc::coordinate(ddc::DiscreteElement(ix))); - for (std::size_t s = 0; s < bsplines_type::degree() + 1; ++s) { - int const j = modulo( - int(jmin.uid() - m_offset + s), - (int)ddc::discrete_space().nbasis()); - matrix->set_element(ix.uid() - start + s_nbc_xmin, j, values(s)); - } - }); - - // Hermite boundary conditions at xmax, if any - if constexpr (BcXmax == BoundCond::HERMITE) { - std::array - derivs_ptr; - std::experimental::mdspan< - double, - std::experimental::extents< - std::size_t, - bsplines_type::degree() + 1, - bsplines_type::degree() / 2 + 1>> const derivs(derivs_ptr.data()); - - ddc::discrete_space().eval_basis_and_n_derivs( - derivs, - ddc::discrete_space().rmax(), - s_nbc_xmax); - - // In order to improve the condition number of the matrix, we normalize - // all derivatives by multiplying the i-th derivative by dx^i - for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) { - for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) { - derivs(i, j) *= ipow(m_dx, j); - } - } - - int const i0 = ddc::discrete_space().nbasis() - s_nbc_xmax; - int const j0 = ddc::discrete_space().nbasis() - bsplines_type::degree(); - for (std::size_t j = 0; j < bsplines_type::degree(); ++j) { - for (std::size_t i = 0; i < s_nbc_xmax; ++i) { - matrix->set_element(i0 + i, j0 + j, derivs(j + 1, i + s_odd)); - } - } - } -} diff --git a/vendor/sll/include/sll/spline_builder_2d.hpp b/vendor/sll/include/sll/spline_builder_2d.hpp deleted file mode 100644 index 6b410229e..000000000 --- a/vendor/sll/include/sll/spline_builder_2d.hpp +++ /dev/null @@ -1,520 +0,0 @@ -#pragma once -#include - - -/** - * @brief A class for creating a 2D spline approximation of a function. - * - * A class which contains an operator () which can be used to build a 2D spline approximation - * of a function. A 2D spline approximation uses a cross-product between two 1D spline builder. - * - * @see SplineBuilder - */ -template -class SplineBuilder2D -{ -private: - /** - * @brief Tag the dimension of the first 1D SplineBuilder. - */ - using tag_type1 = typename SplineBuilder1::bsplines_type::tag_type; - /** - * @brief Tag the dimension of the second 1D SplineBuilder. - */ - using tag_type2 = typename SplineBuilder2::bsplines_type::tag_type; - -public: - /** - * @brief The type of the BSplines in the first dimension which are compatible with this class. - */ - using bsplines_type1 = typename SplineBuilder1::bsplines_type; - /** - * @brief The type of the BSplines in the second dimension which are compatible with this class. - */ - using bsplines_type2 = typename SplineBuilder2::bsplines_type; - - /** - * @brief Tag the type of the Bsplines in the first dimension. - */ - using builder_type1 = SplineBuilder1; - /** - * @brief Tag the type of the Bsplines in the second dimension. - */ - using builder_type2 = SplineBuilder2; - - /** - * @brief The type of the interpolation mesh in the first dimension used by this class. - */ - using interpolation_mesh_type1 = typename SplineBuilder1::mesh_type; - /** - * @brief The type of the interpolation mesh in the second dimension used by this class. - */ - using interpolation_mesh_type2 = typename SplineBuilder2::mesh_type; - - /** - * @brief The type of the domain for the interpolation mesh is the first dimension used by this class. - */ - using interpolation_domain_type1 = ddc::DiscreteDomain; - /** - * @brief The type of the domain for the interpolation mesh is the second dimension used by this class. - */ - using interpolation_domain_type2 = ddc::DiscreteDomain; - /** - * @brief The type of the domain for the interpolation mesh is the 2D dimension used by this class. - */ - using interpolation_domain_type - = ddc::DiscreteDomain; - - /** - * @brief The boundary condition implemented at the lower bound in the first dimension. - */ - static constexpr BoundCond BcXmin1 = SplineBuilder1::s_bc_xmin; - /** - * @brief The boundary condition implemented at the upper bound in the first dimension. - */ - static constexpr BoundCond BcXmax1 = SplineBuilder1::s_bc_xmax; - /** - * @brief The boundary condition implemented at the lower bound in the second dimension. - */ - static constexpr BoundCond BcXmin2 = SplineBuilder2::s_bc_xmin; - /** - * @brief The boundary condition implemented at the upper bound in the second dimension. - */ - static constexpr BoundCond BcXmax2 = SplineBuilder2::s_bc_xmax; - -private: - builder_type1 spline_builder1; - builder_type2 spline_builder2; - interpolation_domain_type m_interpolation_domain; - -public: - /** - * @brief Create a new SplineBuilder2D. - * - * @param interpolation_domain - * The 2D domain on which points will be provided in order to - * create the 2D spline approximation. - */ - SplineBuilder2D(interpolation_domain_type const& interpolation_domain) - : spline_builder1(ddc::select(interpolation_domain)) - , spline_builder2(ddc::select(interpolation_domain)) - , m_interpolation_domain(interpolation_domain) - { - } - - /** - * @brief Create a new SplineBuilder2D by copy - * - * @param x - * The SplineBuilder2D being copied. - */ - SplineBuilder2D(SplineBuilder2D const& x) = delete; - - /** - * @brief Create a new SplineBuilder2D by copy - * - * @param x - * The temporary SplineBuilder2D being copied. - */ - SplineBuilder2D(SplineBuilder2D&& x) = default; - - ~SplineBuilder2D() = default; - - SplineBuilder2D& operator=(SplineBuilder2D const& x) = delete; - - - /** - * @brief Copy a SplineBuilder2D. - * - * @param x - * The temporary SplineBuilder2D being copied. - * @returns A reference to this object. - */ - SplineBuilder2D& operator=(SplineBuilder2D&& x) = default; - - /** - * @brief Build a 2D spline approximation of a function. - * - * Use the values of a function at known grid points (as specified by - * SplineBuilder2D::interpolation_domain_type) and the derivatives of the - * function at the boundaries (if necessary for the chosen boundary - * conditions) to calculate a 2D spline approximation of a function. - * - * The spline approximation is stored as a ChunkSpan of coefficients - * associated with basis-splines. - * - * @param[out] spline - * The coefficients of the spline calculated by the function. - * @param[in] vals - * The values of the function at the grid points. - * @param[in] derivs_xmin - * The values of the derivatives at the lower boundary in the first dimension. - * @param[in] derivs_xmax - * The values of the derivatives at the upper boundary in the first dimension. - * @param[in] derivs_ymin - * The values of the derivatives at the lower boundary in the second dimension. - * @param[in] derivs_ymax - * The values of the derivatives at the upper boundary in the second dimension. - * @param[in] mixed_derivs_xmin_ymin - * The values of the the cross-derivatives at the lower boundary in the first dimension - * and the lower boundary in the second dimension. - * @param[in] mixed_derivs_xmax_ymin - * The values of the the cross-derivatives at the upper boundary in the first dimension - * and the lower boundary in the second dimension. - * @param[in] mixed_derivs_xmin_ymax - * The values of the the cross-derivatives at the lower boundary in the first dimension - * and the upper boundary in the second dimension. - * @param[in] mixed_derivs_xmax_ymax - * The values of the the cross-derivatives at the upper boundary in the first dimension - * and the upper boundary in the second dimension. - */ - void operator()( - ddc::ChunkSpan> spline, - ddc::ChunkSpan vals, - std::optional const derivs_xmin = std::nullopt, - std::optional const derivs_xmax = std::nullopt, - std::optional const derivs_ymin = std::nullopt, - std::optional const derivs_ymax = std::nullopt, - std::optional const mixed_derivs_xmin_ymin = std::nullopt, - std::optional const mixed_derivs_xmax_ymin = std::nullopt, - std::optional const mixed_derivs_xmin_ymax = std::nullopt, - std::optional const mixed_derivs_xmax_ymax = std::nullopt) const; - - /** - * @brief Get the first dimension domain from which the approximation is defined. - * - * Get the first dimension domain on which values of the function must be provided in order - * to build a spline approximation of the function. - * - * @return The first dimension domain for the grid points. - */ - interpolation_domain_type1 const& interpolation_domain1() const noexcept - { - return spline_builder1.interpolation_domain(); - } - - /** - * @brief Get the second dimension domain from which the approximation is defined. - * - * Get the second dimension domain on which values of the function must be provided in order - * to build a spline approximation of the function. - * - * @return The second dimension domain for the grid points. - */ - interpolation_domain_type2 const& interpolation_domain2() const noexcept - { - return spline_builder2.interpolation_domain(); - } - - /** - * @brief Get the 2D dimension domain from which the approximation is defined. - * - * Get the 2D dimension domain on which values of the function must be provided in order - * to build a spline approximation of the function. - * - * @return The 2D dimension domain for the grid points. - */ - interpolation_domain_type const& interpolation_domain() const noexcept - { - return m_interpolation_domain; - } - - /** - * @brief Get the 2D domain on which the approximation is defined. - * - * Get the 2D domain of the basis-splines for which the coefficients of the spline - * approximation must be calculated. - * - * @return The 2D domain for the splines. - */ - ddc::DiscreteDomain spline_domain() const noexcept - { - return ddc::DiscreteDomain( - ddc::DiscreteElement(0, 0), - ddc::DiscreteVector( - ddc::discrete_space().size(), - ddc::discrete_space().size())); - } - - /** - * @brief Get the 1D spline builder in the first dimension. - * - * @return the 1D spline builder in the first dimension. - */ - builder_type1 const& get_builder_1() const noexcept - { - return spline_builder1; - } - - /** - * @brief Get the 1D spline builder in the second dimension. - * - * @return the 1D spline builder in the second dimension. - */ - builder_type2 const& get_builder_2() const noexcept - { - return spline_builder2; - } -}; - - -template -void SplineBuilder2D::operator()( - ddc::ChunkSpan> spline, - ddc::ChunkSpan vals, - std::optional const derivs_xmin, - std::optional const derivs_xmax, - std::optional const derivs_ymin, - std::optional const derivs_ymax, - std::optional const mixed_derivs_xmin_ymin, - std::optional const mixed_derivs_xmax_ymin, - std::optional const mixed_derivs_xmin_ymax, - std::optional const mixed_derivs_xmax_ymax) const -{ - const std::size_t nbc_xmin = spline_builder1.s_nbc_xmin; - const std::size_t nbc_xmax = spline_builder1.s_nbc_xmax; - const std::size_t nbc_ymin = spline_builder2.s_nbc_xmin; - const std::size_t nbc_ymax = spline_builder2.s_nbc_xmax; - - assert((BcXmin1 == BoundCond::HERMITE) - != (!derivs_xmin.has_value() || derivs_xmin->extent(0) == 0)); - assert((BcXmax1 == BoundCond::HERMITE) - != (!derivs_xmax.has_value() || derivs_xmax->extent(0) == 0)); - assert((BcXmin2 == BoundCond::HERMITE) - != (!derivs_ymin.has_value() || derivs_ymin->extent(0) == 0)); - assert((BcXmax2 == BoundCond::HERMITE) - != (!derivs_ymax.has_value() || derivs_ymax->extent(0) == 0)); - assert((BcXmin1 == BoundCond::HERMITE && BcXmin2 == BoundCond::HERMITE) - != (!mixed_derivs_xmin_ymin.has_value() - || mixed_derivs_xmin_ymin->extent(0) != nbc_xmin)); - assert((BcXmax1 == BoundCond::HERMITE && BcXmin2 == BoundCond::HERMITE) - != (!mixed_derivs_xmax_ymin.has_value() - || mixed_derivs_xmax_ymin->extent(0) != nbc_xmax)); - assert((BcXmin2 == BoundCond::HERMITE && BcXmax2 == BoundCond::HERMITE) - != (!mixed_derivs_xmin_ymax.has_value() - || mixed_derivs_xmin_ymax->extent(0) != nbc_xmin)); - assert((BcXmax2 == BoundCond::HERMITE && BcXmax2 == BoundCond::HERMITE) - != (!mixed_derivs_xmax_ymax.has_value() - || mixed_derivs_xmax_ymax->extent(0) != nbc_xmax)); - - ddc::Chunk> spline1( - spline_builder1.spline_domain()); - ddc::Chunk> spline2( - spline_builder2.spline_domain()); - - using IMesh1 = ddc::DiscreteElement; - using IMesh2 = ddc::DiscreteElement; - - /****************************************************************** - * Cycle over x1 position (or order of x1-derivative at boundary) - * and interpolate f along x2 direction. - *******************************************************************/ - if constexpr (BcXmin2 == BoundCond::HERMITE) { - assert((long int)(derivs_ymin->extent(0)) - == spline_builder1.interpolation_domain().extents() - && derivs_ymin->extent(1) == nbc_ymin); - if constexpr (BcXmin1 == BoundCond::HERMITE) { - assert(mixed_derivs_xmin_ymin->extent(0) == nbc_xmin - && mixed_derivs_xmin_ymin->extent(1) == nbc_ymin); - } - if constexpr (BcXmax1 == BoundCond::HERMITE) { - assert(mixed_derivs_xmax_ymin->extent(0) == nbc_xmax - && mixed_derivs_xmax_ymin->extent(1) == nbc_ymin); - } - // In the boundary region we interpolate the derivatives - for (int i = nbc_ymin; i > 0; --i) { - const ddc::DiscreteElement spl_idx(i - 1); - - // Get interpolated values - ddc::Chunk vals1( - spline_builder1.interpolation_domain()); - ddc::for_each(spline_builder1.interpolation_domain(), [&](IMesh1 const j) { - vals1(j) = (*derivs_ymin)(j.uid(), i - 1); - }); - - // Get interpolated derivatives - std::vector l_derivs(nbc_xmin); - if constexpr (BcXmin1 == BoundCond::HERMITE) { - for (std::size_t j(0); j < nbc_xmin; ++j) - l_derivs[j] = (*mixed_derivs_xmin_ymin)(j, i - 1); - } - const std::optional deriv_l( - BcXmin1 == BoundCond::HERMITE - ? std::optional(CDSpan1D(l_derivs.data(), nbc_xmin)) - : std::nullopt); - - std::vector r_derivs(nbc_xmax); - if constexpr (BcXmax1 == BoundCond::HERMITE) { - for (std::size_t j(0); j < nbc_xmax; ++j) - r_derivs[j] = (*mixed_derivs_xmax_ymin)(j, i - 1); - } - const std::optional deriv_r( - BcXmax1 == BoundCond::HERMITE - ? std::optional(CDSpan1D(r_derivs.data(), nbc_xmax)) - : std::nullopt); - - // Interpolate derivatives - spline_builder1(spline1, vals1, deriv_l, deriv_r); - - // Save result into 2d spline structure - ddc::for_each( - ddc::get_domain(spline), - [&](ddc::DiscreteElement const j) { - spline(spl_idx, j) = spline1(j); - }); - } - } - - if (BcXmin1 == BoundCond::HERMITE) { - assert((long int)(derivs_xmin->extent(0)) - == spline_builder2.interpolation_domain().extents() - && derivs_xmin->extent(1) == nbc_xmin); - } - if (BcXmax1 == BoundCond::HERMITE) { - assert((long int)(derivs_xmax->extent(0)) - == spline_builder2.interpolation_domain().extents() - && derivs_xmax->extent(1) == nbc_xmax); - } - ddc::for_each(spline_builder2.interpolation_domain(), [&](IMesh2 const i) { - const std::size_t ii = i.uid(); - const ddc::DiscreteElement spl_idx(nbc_ymin + ii); - - // Get interpolated values - ddc::Chunk vals1( - spline_builder1.interpolation_domain()); - ddc::parallel_deepcopy(vals1, vals[i]); - - // Get interpolated derivatives - const std::optional deriv_l( - BcXmin1 == BoundCond::HERMITE ? std::optional( - CDSpan1D(derivs_xmin->data_handle() + ii * nbc_xmin, nbc_xmin)) - : std::nullopt); - const std::optional deriv_r( - BcXmax1 == BoundCond::HERMITE ? std::optional( - CDSpan1D(derivs_xmax->data_handle() + ii * nbc_xmax, nbc_xmax)) - : std::nullopt); - - // Interpolate values - spline_builder1(spline1, vals1, deriv_l, deriv_r); - - // Save result into 2d spline structure - ddc::for_each( - ddc::get_domain(spline), - [&](ddc::DiscreteElement const j) { - spline(spl_idx, j) = spline1(j); - }); - }); - - if constexpr (BcXmax2 == BoundCond::HERMITE) { - assert((long int)(derivs_ymax->extent(0)) - == spline_builder1.interpolation_domain().extents() - && derivs_ymax->extent(1) == nbc_ymax); - if constexpr (BcXmin2 == BoundCond::HERMITE) { - assert(mixed_derivs_xmin_ymax->extent(0) == nbc_xmin - && mixed_derivs_xmin_ymax->extent(1) == nbc_ymax); - } - if constexpr (BcXmax2 == BoundCond::HERMITE) { - assert(mixed_derivs_xmax_ymax->extent(0) == nbc_xmax - && mixed_derivs_xmax_ymax->extent(1) == nbc_ymax); - } - for (int i = nbc_ymax; i > 0; --i) { - // In the boundary region we interpolate the derivatives - const ddc::DiscreteElement spl_idx( - i + ddc::discrete_space().nbasis() - nbc_ymax - 1); - - // Get interpolated values - ddc::Chunk vals1( - spline_builder1.interpolation_domain()); - ddc::for_each(spline_builder1.interpolation_domain(), [&](IMesh1 const j) { - vals1(j) = (*derivs_ymax)(j.uid(), i - 1); - }); - - // Get interpolated derivatives - std::vector l_derivs(nbc_xmin); - if constexpr (BcXmin1 == BoundCond::HERMITE) { - for (std::size_t j(0); j < nbc_xmin; ++j) - l_derivs[j] = (*mixed_derivs_xmin_ymax)(j, i - 1); - } - const std::optional deriv_l( - BcXmin1 == BoundCond::HERMITE - ? std::optional(CDSpan1D(l_derivs.data(), nbc_xmin)) - : std::nullopt); - - std::vector r_derivs(nbc_xmax); - if constexpr (BcXmax1 == BoundCond::HERMITE) { - for (std::size_t j(0); j < nbc_xmax; ++j) - r_derivs[j] = (*mixed_derivs_xmax_ymax)(j, i - 1); - } - const std::optional deriv_r( - BcXmax1 == BoundCond::HERMITE - ? std::optional(CDSpan1D(r_derivs.data(), nbc_xmax)) - : std::nullopt); - - // Interpolate derivatives - spline_builder1(spline1, vals1, deriv_l, deriv_r); - - // Save result into 2d spline structure - ddc::for_each( - ddc::get_domain(spline), - [&](ddc::DiscreteElement const j) { - spline(spl_idx, j) = spline1(j); - }); - } - } - - using IMeshV2 = ddc::DiscreteVector; - - /****************************************************************** - * Cycle over x1 position (or order of x1-derivative at boundary) - * and interpolate x2 cofficients along x2 direction. - *******************************************************************/ - const ddc::DiscreteDomain spline_basis_domain - = ddc::DiscreteDomain( - ddc::DiscreteElement(0), - ddc::DiscreteVector( - ddc::discrete_space().nbasis())); - - ddc::for_each(spline_basis_domain, [&](ddc::DiscreteElement const i) { - const ddc::ChunkSpan> line_2 = spline[i]; - const ddc::DiscreteDomain whole_line_dom - = ddc::get_domain(spline); - // Get interpolated values - ddc::ChunkSpan> const vals2( - line_2[whole_line_dom.remove(IMeshV2(nbc_ymin), IMeshV2(nbc_ymax))]); - // Get interpolated values acting as derivatives - ddc::ChunkSpan> const l_derivs( - line_2[whole_line_dom.take_first(IMeshV2(nbc_ymin))]); - ddc::ChunkSpan> const r_derivs( - line_2[whole_line_dom.take_last(IMeshV2(nbc_ymax))]); - const std::optional deriv_l( - BcXmin2 == BoundCond::HERMITE ? std::optional(l_derivs.allocation_mdspan()) - : std::nullopt); - const std::optional deriv_r( - BcXmax2 == BoundCond::HERMITE ? std::optional(r_derivs.allocation_mdspan()) - : std::nullopt); - - ddc::ChunkSpan - vals2_i(vals2.data_handle(), spline_builder2.interpolation_domain()); - - // Interpolate coefficients - spline_builder2(spline2, vals2_i, deriv_l, deriv_r); - - // Re-write result into 2d spline structure - ddc::for_each( - ddc::get_domain(spline), - [&](ddc::DiscreteElement const j) { spline(i, j) = spline2(j); }); - }); - - if (bsplines_type1::is_periodic()) { - for (std::size_t i(0); i < bsplines_type1::degree(); ++i) { - const ddc::DiscreteElement i_start(i); - const ddc::DiscreteElement i_end( - ddc::discrete_space().nbasis() + i); - ddc::for_each( - ddc::get_domain(spline), - [&](ddc::DiscreteElement const j) { - spline(i_end, j) = spline(i_start, j); - }); - } - } -} diff --git a/vendor/sll/include/sll/spline_evaluator.hpp b/vendor/sll/include/sll/spline_evaluator.hpp deleted file mode 100644 index a24afe860..000000000 --- a/vendor/sll/include/sll/spline_evaluator.hpp +++ /dev/null @@ -1,167 +0,0 @@ -#pragma once - -#include -#include - -#include - -#include "sll/spline_boundary_value.hpp" -#include "sll/view.hpp" - -template -class SplineEvaluator -{ -private: - // Tags to determine what to evaluate - struct eval_type - { - }; - - struct eval_deriv_type - { - }; - -public: - using bsplines_type = BSplinesType; - - using tag_type = typename BSplinesType::tag_type; - -private: - SplineBoundaryValue const& m_left_bc; - - SplineBoundaryValue const& m_right_bc; - -public: - SplineEvaluator() = delete; - - explicit SplineEvaluator( - SplineBoundaryValue const& left_bc, - SplineBoundaryValue const& right_bc) - : m_left_bc(left_bc) - , m_right_bc(right_bc) - { - } - - SplineEvaluator(SplineEvaluator const& x) = default; - - SplineEvaluator(SplineEvaluator&& x) = default; - - ~SplineEvaluator() = default; - - SplineEvaluator& operator=(SplineEvaluator const& x) = default; - - SplineEvaluator& operator=(SplineEvaluator&& x) = default; - - double operator()( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const spline_coef) const - { - std::array values; - DSpan1D const vals = as_span(values); - - return eval(coord_eval, spline_coef, vals); - } - - template - void operator()( - ddc::ChunkSpan const spline_eval, - ddc::ChunkSpan, Domain> const coords_eval, - ddc::ChunkSpan> const spline_coef) const - { - std::array values; - DSpan1D const vals = as_span(values); - - for (auto i : coords_eval.domain()) { - spline_eval(i) = eval(coords_eval(i), spline_coef, vals); - } - } - - double deriv( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const spline_coef) const - { - std::array values; - DSpan1D const vals = as_span(values); - - return eval_no_bc(coord_eval, spline_coef, vals, eval_deriv_type()); - } - - template - void deriv( - ddc::ChunkSpan const spline_eval, - ddc::ChunkSpan, Domain> const coords_eval, - ddc::ChunkSpan> const spline_coef) const - { - std::array values; - DSpan1D const vals = as_span(values); - - for (auto i : coords_eval.domain()) { - spline_eval(i) = eval_no_bc(coords_eval(i), spline_coef, vals, eval_deriv_type()); - } - } - - double integrate( - ddc::ChunkSpan> const spline_coef) const - { - ddc::Chunk> values(spline_coef.domain()); - - ddc::discrete_space().integrals(values); - - return ddc::transform_reduce( - spline_coef.domain(), - 0.0, - ddc::reducer::sum(), - [&](ddc::DiscreteElement const ibspl) { - return spline_coef(ibspl) * values(ibspl); - }); - } - -private: - double eval( - ddc::Coordinate coord_eval, - ddc::ChunkSpan> const spline_coef, - DSpan1D const vals) const - { - if constexpr (bsplines_type::is_periodic()) { - if (coord_eval < ddc::discrete_space().rmin() - || coord_eval > ddc::discrete_space().rmax()) { - coord_eval -= std::floor( - (coord_eval - ddc::discrete_space().rmin()) - / ddc::discrete_space().length()) - * ddc::discrete_space().length(); - } - } else { - if (coord_eval < ddc::discrete_space().rmin()) { - return m_left_bc(coord_eval, spline_coef); - } - if (coord_eval > ddc::discrete_space().rmax()) { - return m_right_bc(coord_eval, spline_coef); - } - } - return eval_no_bc(coord_eval, spline_coef, vals, eval_type()); - } - - template - double eval_no_bc( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const spline_coef, - DSpan1D const vals, - EvalType const) const - { - static_assert( - std::is_same_v || std::is_same_v); - ddc::DiscreteElement jmin; - - if constexpr (std::is_same_v) { - jmin = ddc::discrete_space().eval_basis(vals, coord_eval); - } else if constexpr (std::is_same_v) { - jmin = ddc::discrete_space().eval_deriv(vals, coord_eval); - } - - double y = 0.0; - for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) { - y += spline_coef(jmin + i) * vals(i); - } - return y; - } -}; diff --git a/vendor/sll/include/sll/spline_evaluator_2d.hpp b/vendor/sll/include/sll/spline_evaluator_2d.hpp deleted file mode 100644 index 4ce5e5f89..000000000 --- a/vendor/sll/include/sll/spline_evaluator_2d.hpp +++ /dev/null @@ -1,537 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include - -/** - * @brief Define an evaluator 2D on B-splines. - */ -template -class SplineEvaluator2D -{ -private: - /** - * @brief Tag to indicate that the value of the spline should be evaluated. - */ - struct eval_type - { - }; - - /** - * @brief Tag to indicate that derivative of the spline should be evaluated. - */ - struct eval_deriv_type - { - }; - -public: - /** - * @brief Tag the B-spline type of the first dimension. - */ - using bsplines_type1 = BSplinesType1; - /** - * @brief Tag the B-spline type of the second dimension. - */ - using bsplines_type2 = BSplinesType2; - /** - * @brief Tag the first dimension. - */ - using Dim1 = typename BSplinesType1::tag_type; - /** - * @brief Tag the second dimension. - */ - using Dim2 = typename BSplinesType2::tag_type; - -private: - SplineBoundaryValue2D const& m_left_bc_1; - - SplineBoundaryValue2D const& m_right_bc_1; - - SplineBoundaryValue2D const& m_left_bc_2; - - SplineBoundaryValue2D const& m_right_bc_2; - -public: - SplineEvaluator2D() = delete; - - /** - * @brief Instantiate an evaluator operator. - * - * @param[in] left_bc_1 - * A SplineBoundaryValue2D object giving the value on the "left side" of the domain - * in the first dimension. - * @param[in] right_bc_1 - * A SplineBoundaryValue2D object giving the value on the "right side" of the domain - * in the first dimension. - * @param[in] left_bc_2 - * A SplineBoundaryValue2D object giving the value on the "left side" of the domain - * in the second dimension. - * @param[in] right_bc_2 - * A SplineBoundaryValue2D object giving the value on the "right side" of the domain - * in the second dimension. - * - * @see SplineBoundaryValue2D - */ - explicit SplineEvaluator2D( - SplineBoundaryValue2D const& left_bc_1, - SplineBoundaryValue2D const& right_bc_1, - SplineBoundaryValue2D const& left_bc_2, - SplineBoundaryValue2D const& right_bc_2) - : m_left_bc_1(left_bc_1) - , m_right_bc_1(right_bc_1) - , m_left_bc_2(left_bc_2) - , m_right_bc_2(right_bc_2) - { - } - - /** - * @brief Instantiate a SplineEvaluator2D from another - * SplineEvaluator2D (lvalue). - * - * @param[in] x - * SplineEvaluator2D evaluator used to instantiate the new one. - */ - SplineEvaluator2D(SplineEvaluator2D const& x) = default; - - /** - * @brief Instantiate a SplineEvaluator2D from another temporary - * SplineEvaluator2D (rvalue). - * - * @param[in] x - * SplineEvaluator2D evaluator used to instantiate the new one. - */ - SplineEvaluator2D(SplineEvaluator2D&& x) = default; - - ~SplineEvaluator2D() = default; - - /** - * @brief Assign a SplineEvaluator2D from another SplineEvaluator2D (lvalue). - * - * @param[in] x - * SplineEvaluator2D mapping used to assign. - * - * @return The SplineEvaluator2D assigned. - */ - SplineEvaluator2D& operator=(SplineEvaluator2D const& x) = default; - - /** - * @brief Assign a SplineEvaluator2D from another temporary SplineEvaluator2D (rvalue). - * - * @param[in] x - * SplineEvaluator2D mapping used to assign. - * - * @return The SplineEvaluator2D assigned. - */ - SplineEvaluator2D& operator=(SplineEvaluator2D&& x) = default; - - /** - * @brief Get the value of the function on B-splines at the coordinate given. - * - * @param[in] coord_eval - * The 2D coordinate where we want to evaluate the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - * - * @return A double containing the value of the function at the coordinate given. - */ - double operator()( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - return eval(coord_eval, spline_coef, vals1, vals2); - } - - /** - * @brief Get the values of the function on B-splines at the coordinates given. - * - * @param[out] spline_eval - * A ChunkSpan containing the values of the function evaluated at the coordinates given. - * @param[in] coords_eval - * A ChunkSpan with the 2D coordinates where we want to evaluate the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - */ - template - void operator()( - ddc::ChunkSpan const spline_eval, - ddc::ChunkSpan const, Domain> const coords_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - ddc::for_each(coords_eval.domain(), [=](auto i) { - spline_eval(i) = eval(coords_eval(i), spline_coef, vals1, vals2); - }); - } - - /** - * @brief Get the value of the derivative of the first dimension of the function on B-splines at the coordinate given. - * - * @param[in] coord_eval - * The 2D coordinate where we want to evaluate the derivative of the first dimension of the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - * - * @return A double containing the value of the derivative of the first dimension of the function at the coordinate given. - */ - double deriv_dim_1( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - return eval_no_bc( - ddc::select(coord_eval), - ddc::select(coord_eval), - spline_coef, - vals1, - vals2, - eval_deriv_type(), - eval_type()); - } - - /** - * @brief Get the value of the derivative of the second dimension of the function on B-splines at the coordinate given. - * - * @param[in] coord_eval - * The 2D coordinate where we want to evaluate the derivative of the second dimension of the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - * - * @return A double containing the value of the derivative of the second dimension of the function at the coordinate given. - */ - double deriv_dim_2( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - return eval_no_bc( - ddc::select(coord_eval), - ddc::select(coord_eval), - spline_coef, - vals1, - vals2, - eval_type(), - eval_deriv_type()); - } - - /** - * @brief Get the value of the cross derivative of the function on B-splines at the coordinate given. - * - * @param[in] coord_eval - * The 2D coordinate where we want to evaluate the cross derivative of the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - * - * @return A double containing the value of the cross derivative of the function at the coordinate given. - */ - double deriv_1_and_2( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - return eval_no_bc( - ddc::select(coord_eval), - ddc::select(coord_eval), - spline_coef, - vals1, - vals2, - eval_deriv_type(), - eval_deriv_type()); - } - - /** - * @brief Get the values of the derivative of the first dimension of the function on B-splines at the coordinates given. - * - * @param[out] spline_eval - * A ChunkSpan with the values of the derivative of the first dimension of the function at the coordinates given. - * @param[in] coords_eval - * A ChunkSpan with the 2D coordinates where we want to evaluate the derivative of the first dimension of the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - */ - template - void deriv_dim_1( - ddc::ChunkSpan const spline_eval, - ddc::ChunkSpan const, Domain> const coords_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - ddc::for_each(coords_eval.domain(), [=](auto i) { - spline_eval(i) = eval_no_bc( - ddc::select(coords_eval(i)), - ddc::select(coords_eval(i)), - spline_coef, - vals1, - vals2, - eval_deriv_type(), - eval_type()); - }); - } - - /** - * @brief Get the values of the derivative of the second dimension of the function on B-splines at the coordinates given. - * - * @param[out] spline_eval - * A ChunkSpan with the values of the derivative of the second dimension of the function at the coordinates given. - * @param[in] coords_eval - * A ChunkSpan with the 2D coordinates where we want to evaluate the derivative of the second dimension of the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - */ - template - void deriv_dim_2( - ddc::ChunkSpan const spline_eval, - ddc::ChunkSpan const, Domain> const coords_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - ddc::for_each(coords_eval.domain(), [=](auto i) { - spline_eval(i) = eval_no_bc( - ddc::select(coords_eval(i)), - ddc::select(coords_eval(i)), - spline_coef, - vals1, - vals2, - eval_type(), - eval_deriv_type()); - }); - } - - /** - * @brief Get the values of the cross derivative of the function on B-splines at the coordinates given. - * - * @param[out] spline_eval - * A ChunkSpan with the values of the cross derivative of the function at the coordinates given. - * @param[in] coords_eval - * A ChunkSpan with the 2D coordinates where we want to evaluate the cross derivative of the function. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - */ - template - void deriv_dim_1_and_2( - ddc::ChunkSpan const spline_eval, - ddc::ChunkSpan const, Domain> const coords_eval, - ddc::ChunkSpan> const - spline_coef) const - { - std::array values1; - DSpan1D const vals1 = as_span(values1); - std::array values2; - DSpan1D const vals2 = as_span(values2); - - ddc::for_each(coords_eval.domain(), [=](auto i) { - spline_eval(i) = eval_no_bc( - ddc::select(coords_eval(i)), - ddc::select(coords_eval(i)), - spline_coef, - vals1, - vals2, - eval_deriv_type(), - eval_deriv_type()); - }); - } - - /** - * @brief Get the the integral of the function on B-splines on the domain. - * - * @param[in] spline_coef - * The B-splines coefficients of the function we want to integrate. - * - * @return A double with the value of the integral of the function. - */ - double integrate( - ddc::ChunkSpan> const - spline_coef) const - { - ddc::Chunk> values1( - ddc::DiscreteDomain(spline_coef.domain())); - ddc::Chunk> values2( - ddc::DiscreteDomain(spline_coef.domain())); - - ddc::discrete_space().integrals(values1.span_view()); - ddc::discrete_space().integrals(values2.span_view()); - - return ddc::transform_reduce( - spline_coef.domain(), - 0.0, - ddc::reducer::sum(), - [&](ddc::DiscreteElement const i) { - return spline_coef(i) * values1(ddc::select(i)) - * values2(ddc::select(i)); - }); - } - -private: - /** - * @brief Evaluate the function on B-splines at the coordinate given. - * - * This function firstly deals with the boundary conditions and calls the SplineEvaluator2D::eval_no_bc function - * to evaluate. - * - * @param[in] coord_eval - * The 2D coordinate where we want to evaluate. - * @param[in] spline_coef - * The B-splines coefficients of the function we want to evaluate. - * @param[out] vals1 - * A ChunkSpan with the not-null values of each function of the spline in the first dimension. - * @param[out] vals2 - * A ChunkSpan with the not-null values of each function of the spline in the second dimension. - * - * @return A double with the value of the function at the coordinate given. - * - * @see SplineBoundaryValue - */ - double eval( - ddc::Coordinate const& coord_eval, - ddc::ChunkSpan> const - spline_coef, - DSpan1D const vals1, - DSpan1D const vals2) const - { - ddc::Coordinate coord_eval1 = ddc::select(coord_eval); - ddc::Coordinate coord_eval2 = ddc::select(coord_eval); - if constexpr (bsplines_type1::is_periodic()) { - if (coord_eval1 < ddc::discrete_space().rmin() - || coord_eval1 > ddc::discrete_space().rmax()) { - coord_eval1 -= std::floor( - (coord_eval1 - ddc::discrete_space().rmin()) - / ddc::discrete_space().length()) - * ddc::discrete_space().length(); - } - } - - if constexpr (bsplines_type2::is_periodic()) { - if (coord_eval2 < ddc::discrete_space().rmin() - || coord_eval2 > ddc::discrete_space().rmax()) { - coord_eval2 -= std::floor( - (coord_eval2 - ddc::discrete_space().rmin()) - / ddc::discrete_space().length()) - * ddc::discrete_space().length(); - } - } - - if constexpr (!bsplines_type1::is_periodic()) { - if (coord_eval1 < ddc::discrete_space().rmin()) { - return m_left_bc_1(coord_eval1, coord_eval2, spline_coef); - } - if (coord_eval1 > ddc::discrete_space().rmax()) { - return m_right_bc_1(coord_eval1, coord_eval2, spline_coef); - } - } - - if constexpr (!bsplines_type2::is_periodic()) { - if (coord_eval2 < ddc::discrete_space().rmin()) { - return m_left_bc_2(coord_eval1, coord_eval2, spline_coef); - } - if (coord_eval2 > ddc::discrete_space().rmax()) { - return m_right_bc_2(coord_eval1, coord_eval2, spline_coef); - } - } - - return eval_no_bc( - coord_eval1, - coord_eval2, - spline_coef, - vals1, - vals2, - eval_type(), - eval_type()); - } - - /** - * @brief Evaluate the function or its derivative at the coordinate given. - * - * @param[in] coord_eval1 - * The coordinate on the first dimension where we want to evaluate. - * @param[in] coord_eval2 - * The coordinate on the second dimension where we want to evaluate. - * @param[in] splne_coef - * The B-splines coefficients of the function we want to evaluate. - * @param[out] vals1 - * A ChunkSpan with the not-null values of each function of the spline in the first dimension. - * @param[out] vals2 - * A ChunkSpan with the not-null values of each function of the spline in the second dimension. - * @param[in] eval_type_1 - * A flag indicating if we evaluate the function or its derivative in the first dimension. - * The type of this object is either `eval_type` or `eval_deriv_type`. - * @param[in] eval_type_2 - * A flag indicating if we evaluate the function or its derivative in the second dimension. - * The type of this object is either `eval_type` or `eval_deriv_type`. - */ - template - double eval_no_bc( - ddc::Coordinate const& coord_eval1, - ddc::Coordinate const& coord_eval2, - ddc::ChunkSpan> const - spline_coef, - DSpan1D const vals1, - DSpan1D const vals2, - EvalType1 const eval_type_1, - EvalType2 const eval_type_2) const - { - static_assert( - std::is_same_v || std::is_same_v); - static_assert( - std::is_same_v || std::is_same_v); - ddc::DiscreteElement jmin1; - ddc::DiscreteElement jmin2; - - if constexpr (std::is_same_v) { - jmin1 = ddc::discrete_space().eval_basis(vals1, coord_eval1); - } else if constexpr (std::is_same_v) { - jmin1 = ddc::discrete_space().eval_deriv(vals1, coord_eval1); - } - if constexpr (std::is_same_v) { - jmin2 = ddc::discrete_space().eval_basis(vals2, coord_eval2); - } else if constexpr (std::is_same_v) { - jmin2 = ddc::discrete_space().eval_deriv(vals2, coord_eval2); - } - - double y = 0.0; - for (std::size_t i = 0; i < bsplines_type1::degree() + 1; ++i) { - for (std::size_t j = 0; j < bsplines_type2::degree() + 1; ++j) { - y += spline_coef(jmin1 + i, jmin2 + j) * vals1(i) * vals2(j); - } - } - return y; - } -}; diff --git a/vendor/sll/src/deprecated/bsplines.cpp b/vendor/sll/src/deprecated/bsplines.cpp deleted file mode 100644 index d2d40dcd8..000000000 --- a/vendor/sll/src/deprecated/bsplines.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "sll/deprecated/bsplines.hpp" - -namespace deprecated { - -BSplines::BSplines( - int degree, - bool periodic, - int ncells, - int nbasis, - double xmin, - double xmax, - bool radial) - : m_degree(degree) - , m_radial(radial) - , m_nbasis(nbasis) - , m_ncells(ncells) - , m_periodic(periodic) - , m_xmin(xmin) - , m_xmax(xmax) - , m_length(xmax - xmin) -{ -} - -} // namespace deprecated diff --git a/vendor/sll/src/deprecated/bsplines_non_uniform.cpp b/vendor/sll/src/deprecated/bsplines_non_uniform.cpp deleted file mode 100644 index 49469e210..000000000 --- a/vendor/sll/src/deprecated/bsplines_non_uniform.cpp +++ /dev/null @@ -1,290 +0,0 @@ -#include -#include -#include - -#include - -#include "sll/deprecated/bsplines.hpp" -#include "sll/deprecated/bsplines_non_uniform.hpp" - -namespace stdex = std::experimental; - -namespace deprecated { - -NonUniformBSplines::NonUniformBSplines(int degree, bool periodic, const std::vector& breaks) - : BSplines( - degree, - periodic, - breaks.size() - 1, // ncells - periodic ? (breaks.size() - 1) : (breaks.size() - 1 + degree), // nbasis - breaks.front(), // xmin - breaks.back(), // xmax - false) // radial -{ - assert(degree > 0); - assert(m_ncells > 0); - assert(m_xmin < m_xmax); - assert(breaks.size() == m_ncells + 1); - - m_npoints = breaks.size(); - m_knots = std::make_unique(m_npoints + 2 * degree); - - for (int i(0); i < m_npoints; ++i) { - get_knot(i) = breaks[i]; - } - - // Fill out the extra nodes - if (periodic) { - double period = breaks[m_npoints - 1] - breaks[0]; - for (int i(1); i < degree + 1; ++i) { - get_knot(-i) = breaks[m_npoints - 1 - i] - period; - get_knot(m_npoints - 1 + i) = breaks[i] + period; - } - } else // open - { - for (int i(1); i < degree + 1; ++i) { - get_knot(-i) = breaks[0]; - get_knot(m_npoints - 1 + i) = breaks[m_npoints - 1]; - } - } -} - -void NonUniformBSplines::eval_basis(double x, DSpan1D& values, int& jmin) const -{ - std::vector left(m_degree); - std::vector right(m_degree); - - assert(x >= m_xmin); - assert(x <= m_xmax); - assert(values.extent(0) == m_degree + 1); - - // 1. Compute cell index 'icell' - int icell = find_cell(x); - - assert(icell >= 0); - assert(icell <= m_ncells - 1); - assert(get_knot(icell) <= x); - assert(get_knot(icell + 1) >= x); - - // 2. Compute index range of B-splines with support over cell 'icell' - jmin = icell; - - // 3. Compute values of aforementioned B-splines - double temp; - values(0) = 1.0; - for (int j(0); j < m_degree; ++j) { - left[j] = x - get_knot(icell - j); - right[j] = get_knot(icell + j + 1) - x; - double saved(0.0); - for (int r(0); r < j + 1; ++r) { - temp = values(r) / (right[r] + left[j - r]); - values(r) = saved + right[r] * temp; - saved = left[j - r] * temp; - } - values(j + 1) = saved; - } -} - -void NonUniformBSplines::eval_deriv(double x, DSpan1D& derivs, int& jmin) const -{ - std::vector left(m_degree); - std::vector right(m_degree); - - assert(x >= m_xmin); - assert(x <= m_xmax); - assert(derivs.extent(0) == m_degree + 1); - - // 1. Compute cell index 'icell' - int icell = find_cell(x); - - assert(icell >= 0); - assert(icell <= m_ncells - 1); - assert(get_knot(icell) <= x); - assert(get_knot(icell + 1) >= x); - - // 2. Compute index range of B-splines with support over cell 'icell' - jmin = icell; - - // 3. Compute values of aforementioned B-splines - - /* - * Compute nonzero basis functions and knot differences - * for splines up to degree degree-1 which are needed to compute derivative - * First part of Algorithm A3.2 of NURBS book - */ - double saved, temp; - derivs(0) = 1.0; - for (int j(0); j < m_degree - 1; ++j) { - left[j] = x - get_knot(icell - j); - right[j] = get_knot(icell + j + 1) - x; - saved = 0.0; - for (int r(0); r < j + 1; ++r) { - temp = derivs(r) / (right[r] + left[j - r]); - derivs(r) = saved + right[r] * temp; - saved = left[j - r] * temp; - } - derivs(j + 1) = saved; - } - - /* - * Compute derivatives at x using values stored in bsdx and formula - * for spline derivative based on difference of splines of degree degree-1 - */ - saved = m_degree * derivs(0) / (get_knot(icell + 1) - get_knot(icell + 1 - m_degree)); - derivs(0) = -saved; - for (int j(1); j < m_degree; ++j) { - temp = saved; - saved = m_degree * derivs(j) - / (get_knot(icell + j + 1) - get_knot(icell + j + 1 - m_degree)); - derivs(j) = temp - saved; - } - derivs(m_degree) = saved; -} -void NonUniformBSplines::eval_basis_and_n_derivs(double x, int n, DSpan2D& derivs, int& jmin) const -{ - std::vector left(m_degree); - std::vector right(m_degree); - - std::vector a_ptr(2 * (m_degree + 1)); - stdex::mdspan> a(a_ptr.data(), m_degree + 1); - - std::vector ndu_ptr((m_degree + 1) * (m_degree + 1)); - DSpan2D ndu(ndu_ptr.data(), m_degree + 1, m_degree + 1); - - assert(x >= m_xmin); - assert(x <= m_xmax); - assert(n >= 0); - assert(n <= m_degree); - assert(derivs.extent(0) == 1 + m_degree); - assert(derivs.extent(1) == 1 + n); - - // 1. Compute cell index 'icell' and x_offset - int icell(find_cell(x)); - - assert(icell >= 0); - assert(icell <= m_ncells - 1); - assert(get_knot(icell) <= x); - assert(get_knot(icell + 1) >= x); - - // 2. Compute index range of B-splines with support over cell 'icell' - jmin = icell; - - // 3. Compute nonzero basis functions and knot differences for splines - // up to degree (degree-1) which are needed to compute derivative - // Algorithm A2.3 of NURBS book - // - // 21.08.2017: save inverse of knot differences to avoid unnecessary - // divisions - // [Yaman Güçlü, Edoardo Zoni] - - double saved, temp; - ndu(0, 0) = 1.0; - for (int j(0); j < m_degree; ++j) { - left[j] = x - get_knot(icell - j); - right[j] = get_knot(icell + j + 1) - x; - saved = 0.0; - for (int r(0); r < j + 1; ++r) { - // compute inverse of knot differences and save them into lower - // triangular part of ndu - ndu(r, j + 1) = 1.0 / (right[r] + left[j - r]); - // compute basis functions and save them into upper triangular part - // of ndu - temp = ndu(j, r) * ndu(r, j + 1); - ndu(j + 1, r) = saved + right[r] * temp; - saved = left[j - r] * temp; - } - ndu(j + 1, j + 1) = saved; - } - // Save 0-th derivative - for (int j(0); j < m_degree + 1; ++j) { - derivs(j, 0) = ndu(m_degree, j); - } - - for (int r(0); r < m_degree + 1; ++r) { - int s1 = 0; - int s2 = 1; - a(0, 0) = 1.0; - for (int k(1); k < n + 1; ++k) { - double d(0.0); - int rk = r - k; - int pk = m_degree - k; - if (r >= k) { - a(0, s2) = a(0, s1) * ndu(rk, pk + 1); - d = a(0, s2) * ndu(pk, rk); - } - int j1 = rk > -1 ? 1 : (-rk); - int j2 = (r - 1) <= pk ? k : (m_degree - r + 1); - for (int j(j1); j < j2; ++j) { - a(j, s2) = (a(j, s1) - a(j - 1, s1)) * ndu(rk + j, pk + 1); - d += a(j, s2) * ndu(pk, rk + j); - } - if (r <= pk) { - a(k, s2) = -a(k - 1, s1) * ndu(r, pk + 1); - d += a(k, s2) * ndu(pk, r); - } - derivs(r, k) = d; - int tmp(s1); - s1 = s2; - s2 = tmp; - } - } - - int r(m_degree); - for (int k(1); k < n + 1; ++k) { - for (int i(0); i < derivs.extent(0); i++) { - derivs(i, k) *= r; - } - r *= (m_degree - k); - } -} - -int NonUniformBSplines::find_cell(double x) const -{ - if (x > m_xmax) - return -1; - if (x < m_xmin) - return -1; - - if (x == m_xmin) - return 0; - if (x == m_xmax) - return m_ncells - 1; - - // Binary search - int low(0), high(m_ncells); - int icell((low + high) / 2); - while (x < get_knot(icell) or x >= get_knot(icell + 1)) { - if (x < get_knot(icell)) { - high = icell; - } else { - low = icell; - } - icell = (low + high) / 2; - } - return icell; -} - -void NonUniformBSplines::integrals(DSpan1D& int_vals) const -{ - assert(int_vals.extent(0) == m_nbasis + m_degree * m_periodic); - - double inv_deg(1.0 / (m_degree + 1)); - - for (int i(0); i < m_nbasis; ++i) { - int_vals(i) = (get_knot(i + 1) - get_knot(i - m_degree)) * inv_deg; - } - - if (m_periodic) { - for (int i(0); i < m_degree; ++i) { - int_vals(m_nbasis + i) = 0; - } - } -} - -bool NonUniformBSplines::is_uniform() const -{ - return false; -} - - -} // namespace deprecated diff --git a/vendor/sll/src/deprecated/bsplines_uniform.cpp b/vendor/sll/src/deprecated/bsplines_uniform.cpp deleted file mode 100644 index a30c3c0e4..000000000 --- a/vendor/sll/src/deprecated/bsplines_uniform.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include -#include - -#include - -#include "sll/deprecated/bsplines.hpp" -#include "sll/deprecated/bsplines_uniform.hpp" -#include "sll/math_tools.hpp" - -namespace stdex = std::experimental; - -namespace deprecated { - -UniformBSplines::UniformBSplines(int degree, bool periodic, double xmin, double xmax, int ncells) - : BSplines(degree, periodic, ncells, periodic ? ncells : ncells + degree, xmin, xmax, false) -{ - assert(degree > 0); - assert(ncells > 0); - assert(xmin < xmax); - m_inv_dx = ncells / (xmax - xmin); - m_dx = (xmax - xmin) / ncells; -} - -void UniformBSplines::eval_basis(double x, DSpan1D& values, int& jmin, int deg) const -{ - assert(values.extent(0) == deg + 1); - - double offset; - // 1. Compute cell index 'icell' and x_offset - // 2. Compute index range of B-splines with support over cell 'icell' - get_icell_and_offset(x, jmin, offset); - - // 3. Compute values of aforementioned B-splines - double xx, temp, saved; - values(0) = 1.0; - for (int j(1); j < deg + 1; ++j) { - xx = -offset; - saved = 0.0; - for (int r(0); r < j; ++r) { - xx += 1; - temp = values(r) / j; - values(r) = saved + xx * temp; - saved = (j - xx) * temp; - } - values(j) = saved; - } -} - -void UniformBSplines::eval_deriv(double x, DSpan1D& derivs, int& jmin) const -{ - assert(derivs.extent(0) == m_degree + 1); - - double offset; - // 1. Compute cell index 'icell' and x_offset - // 2. Compute index range of B-splines with support over cell 'icell' - get_icell_and_offset(x, jmin, offset); - - // 3. Compute derivatives of aforementioned B-splines - // Derivatives are normalized, hence they should be divided by dx - double xx, temp, saved; - derivs(0) = m_inv_dx; - for (int j(1); j < m_degree; ++j) { - xx = -offset; - saved = 0.0; - for (int r(0); r < j; ++r) { - xx += 1.0; - temp = derivs(r) / j; - derivs(r) = saved + xx * temp; - saved = (j - xx) * temp; - } - derivs(j) = saved; - } - - // Compute derivatives - double bjm1 = derivs(0); - double bj = bjm1; - derivs(0) = -bjm1; - for (int j(1); j < m_degree; ++j) { - bj = derivs(j); - derivs(j) = bjm1 - bj; - bjm1 = bj; - } - derivs(m_degree) = bj; -} - -void UniformBSplines::eval_basis_and_n_derivs(double x, int n, DSpan2D& derivs, int& jmin) const -{ - std::vector ndu_ptr((m_degree + 1) * (m_degree + 1)); - DSpan2D ndu(ndu_ptr.data(), m_degree + 1, m_degree + 1); - std::vector a_ptr(2 * (m_degree + 1)); - stdex::mdspan> a(a_ptr.data(), m_degree + 1); - double offset; - - // 1. Compute cell index 'icell' and x_offset - // 2. Compute index range of B-splines with support over cell 'icell' - get_icell_and_offset(x, jmin, offset); - - // 3. Recursively evaluate B-splines (see - // "sll_s_uniform_BSplines_eval_basis") - // up to self%degree, and store them all in the upper-right triangle of - // ndu - double xx, temp, saved; - ndu(0, 0) = 1.0; - for (int j(1); j < m_degree + 1; ++j) { - xx = -offset; - saved = 0.0; - for (int r(0); r < j; ++r) { - xx += 1.0; - temp = ndu(j - 1, r) / j; - ndu(j, r) = saved + xx * temp; - saved = (j - xx) * temp; - } - ndu(j, j) = saved; - } - for (int i(0); i < ndu.extent(1); ++i) { - derivs(i, 0) = ndu(m_degree, i); - } - - for (int r(0); r < m_degree + 1; ++r) { - int s1 = 0; - int s2 = 1; - a(0, 0) = 1.0; - for (int k(1); k < n + 1; ++k) { - double d(0.0); - int rk = r - k; - int pk = m_degree - k; - if (r >= k) { - a(0, s2) = a(0, s1) / (pk + 1); - d = a(0, s2) * ndu(pk, rk); - } - int j1 = rk > -1 ? 1 : (-rk); - int j2 = (r - 1) <= pk ? k : (m_degree - r + 1); - for (int j(j1); j < j2; ++j) { - a(j, s2) = (a(j, s1) - a(j - 1, s1)) / (pk + 1); - d += a(j, s2) * ndu(pk, rk + j); - } - if (r <= pk) { - a(k, s2) = -a(k - 1, s1) / (pk + 1); - d += a(k, s2) * ndu(pk, r); - } - derivs(r, k) = d; - int tmp(s1); - s1 = s2; - s2 = tmp; - } - } - - // Multiply result by correct factors: - // degree!/(degree-n)! = degree*(degree-1)*...*(degree-n+1) - // k-th derivatives are normalized, hence they should be divided by dx^k - double d = m_degree * m_inv_dx; - for (int k(1); k < n + 1; ++k) { - for (int i(0); i < derivs.extent(0); ++i) { - derivs(i, k) *= d; - } - d *= (m_degree - k) * m_inv_dx; - } -} - -void UniformBSplines::get_icell_and_offset(double x, int& icell, double& offset) const -{ - assert(x >= m_xmin); - assert(x <= m_xmax); - - if (x == m_xmin) { - icell = 0; - offset = 0.0; - } else if (x == m_xmax) { - icell = m_ncells - 1; - offset = 1.0; - } else { - offset = (x - m_xmin) * m_inv_dx; - icell = int(offset); - offset = offset - icell; - - // When x is very close to xmax, round-off may cause the wrong answer - // icell=ncells and x_offset=0, which we convert to the case x=xmax: - if (icell == m_ncells and offset == 0.0) { - icell = m_ncells - 1; - offset = 1.0; - } - } -} - -void UniformBSplines::integrals(DSpan1D& int_vals) const -{ - assert(int_vals.extent(0) == m_nbasis + m_degree * m_periodic); - for (int i(m_degree); i < m_nbasis - m_degree; ++i) { - int_vals(i) = m_dx; - } - - if (m_periodic) { - // Periodic conditions lead to repeat spline coefficients - for (int i(0); i < m_degree; ++i) { - int_vals(i) = m_dx; - int_vals(m_nbasis - i - 1) = m_dx; - int_vals(m_nbasis + i) = 0; - } - } else { - int jmin(0); - std::vector edge_vals_ptr(m_degree + 2); - DSpan1D edge_vals(edge_vals_ptr.data(), m_degree + 2); - - eval_basis(m_xmin, edge_vals, jmin, m_degree + 1); - - double d_eval = sum(edge_vals); - - for (int i(0); i < m_degree; ++i) { - double c_eval = sum(edge_vals, 0, m_degree - i); - - int_vals(i) = m_dx * (d_eval - c_eval); - int_vals(m_nbasis - 1 - i) = int_vals(i); - } - } -} - -bool UniformBSplines::is_uniform() const -{ - return true; -} - -} // namespace deprecated diff --git a/vendor/sll/src/deprecated/spline_1d.cpp b/vendor/sll/src/deprecated/spline_1d.cpp deleted file mode 100644 index 27c61280d..000000000 --- a/vendor/sll/src/deprecated/spline_1d.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include -#include -#include -#include -#include - -#include "sll/boundary_value.hpp" -#include "sll/deprecated/bsplines.hpp" -#include "sll/deprecated/bsplines_non_uniform.hpp" -#include "sll/deprecated/bsplines_uniform.hpp" -#include "sll/deprecated/spline_1d.hpp" - -namespace deprecated { - -Spline1D::Spline1D( - const BSplines& bspl, - const BoundaryValue& left_bc, - const BoundaryValue& right_bc) - : m_bcoef_ptr(std::make_unique(bspl.degree() + bspl.ncells())) - , m_bcoef(m_bcoef_ptr.get(), bspl.degree() + bspl.ncells()) - , m_bspl(bspl) - , m_left_bc(left_bc) - , m_right_bc(right_bc) -{ -} - -bool Spline1D::belongs_to_space(const BSplines& bspline) const -{ - return &m_bspl == &bspline; -} - -template >*> -double Spline1D::eval_intern_no_bcs(double x, const T& bspl, DSpan1D& vals) const -{ - int jmin; - - bspl.eval_basis(x, vals, jmin); - - double y = 0.0; - for (int i(0); i < bspl.degree() + 1; ++i) { - y += m_bcoef(jmin + i) * vals(i); - } - return y; -} - -template >*> -double Spline1D::eval_intern(double x, const T& bspl, DSpan1D& vals) const -{ - if constexpr (periodic) { - if (x < bspl.xmin() || x > bspl.xmax()) [[unlikely]] { - x -= std::floor((x - bspl.xmin()) / bspl.length()) * bspl.length(); - } - } else { - if (x < bspl.xmin()) [[unlikely]] { - return m_left_bc(x); - } - if (x > bspl.xmax()) [[unlikely]] { - return m_right_bc(x); - } - } - return eval_intern_no_bcs(x, bspl, vals); -} - -template >*> -double Spline1D::eval_deriv_intern(double x, const T& bspl, DSpan1D& vals) const -{ - int jmin; - - bspl.eval_deriv(x, vals, jmin); - - double y = 0.0; - for (int i(0); i < bspl.degree() + 1; ++i) { - y += m_bcoef(jmin + i) * vals(i); - } - return y; -} - -double Spline1D::eval(double x) const -{ - std::vector values(m_bspl.degree() + 1); - DSpan1D vals(values.data(), values.size()); - - if (m_bspl.is_uniform()) { - if (m_bspl.is_periodic()) { - return eval_intern< - UniformBSplines, - true>(x, static_cast(m_bspl), vals); - } else { - return eval_intern< - UniformBSplines, - false>(x, static_cast(m_bspl), vals); - } - } else { - if (m_bspl.is_periodic()) { - return eval_intern< - NonUniformBSplines, - true>(x, static_cast(m_bspl), vals); - } else { - return eval_intern< - NonUniformBSplines, - false>(x, static_cast(m_bspl), vals); - } - } -} - -double Spline1D::eval_deriv(double x) const -{ - std::vector values(m_bspl.degree() + 1); - DSpan1D vals(values.data(), values.size()); - - if (m_bspl.is_uniform()) - return eval_deriv_intern< - UniformBSplines>(x, static_cast(m_bspl), vals); - else - return eval_deriv_intern< - NonUniformBSplines>(x, static_cast(m_bspl), vals); -} - -template >*> -void Spline1D::eval_array_loop(DSpan1D const& x, DSpan1D& y) const -{ - const T& l_bspl = static_cast(m_bspl); - - assert(x.extent(0) == y.extent(0)); - std::vector values(l_bspl.degree() + 1); - DSpan1D vals(values.data(), values.size()); - - for (int i(0); i < x.extent(0); ++i) { - y(i) = eval_intern(x(i), l_bspl, vals); - } -} - -template >*> -void Spline1D::eval_array_deriv_loop(DSpan1D const& x, DSpan1D& y) const -{ - const T& l_bspl = static_cast(m_bspl); - - assert(x.extent(0) == y.extent(0)); - std::vector values(l_bspl.degree() + 1); - DSpan1D vals(values.data(), values.size()); - - for (int i(0); i < x.extent(0); ++i) { - y(i) = eval_deriv_intern(x(i), l_bspl, vals); - } -} - -void Spline1D::eval_array(DSpan1D const x, DSpan1D y) const -{ - if (m_bspl.is_uniform()) { - if (m_bspl.is_periodic()) { - return eval_array_loop(x, y); - } else { - return eval_array_loop(x, y); - } - } else { - if (m_bspl.is_periodic()) { - return eval_array_loop(x, y); - } else { - return eval_array_loop(x, y); - } - } -} - -void Spline1D::eval_array_deriv(DSpan1D const x, DSpan1D y) const -{ - if (m_bspl.is_uniform()) - eval_array_deriv_loop(x, y); - else - eval_array_deriv_loop(x, y); -} - -double Spline1D::integrate() const -{ - std::vector values(m_bcoef.extent(0)); - DSpan1D vals(values.data(), values.size()); - - m_bspl.integrals(vals); - - double y = 0.0; - for (int i(0); i < m_bcoef.extent(0); ++i) { - y += m_bcoef(i) * vals(i); - } - return y; -} - -} // namespace deprecated diff --git a/vendor/sll/src/deprecated/spline_2d.cpp b/vendor/sll/src/deprecated/spline_2d.cpp deleted file mode 100644 index ad8a82a2d..000000000 --- a/vendor/sll/src/deprecated/spline_2d.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include - -#include - -#include "sll/deprecated/bsplines.hpp" -#include "sll/deprecated/bsplines_non_uniform.hpp" -#include "sll/deprecated/bsplines_uniform.hpp" -#include "sll/deprecated/spline_2d.hpp" - -namespace deprecated { - -Spline2D::Spline2D(const BSplines& bspl1, const BSplines& bspl2) - : m_bcoef_ptr(std::make_unique( - (bspl1.degree() + bspl1.ncells()) * (bspl2.degree() + bspl2.ncells()))) - , m_bcoef(m_bcoef_ptr.get(), bspl1.degree() + bspl1.ncells(), bspl2.degree() + bspl2.ncells()) - , m_bspl1(bspl1) - , m_bspl2(bspl2) -{ -} - -bool Spline2D::belongs_to_space(const BSplines& bspline1, const BSplines& bspline2) const -{ - return (&m_bspl1 == &bspline1 && &m_bspl2 == &bspline2); -} - -template < - class T1, - class T2, - bool deriv1, - bool deriv2, - std::enable_if_t>*, - std::enable_if_t>*> -double Spline2D::eval_intern( - double x1, - double x2, - const T1& bspl1, - const T2& bspl2, - DSpan1D& vals1, - DSpan1D& vals2) const -{ - int jmin1, jmin2; - - if constexpr (deriv1) { - bspl1.eval_deriv(x1, vals1, jmin1); - } else { - bspl1.eval_basis(x1, vals1, jmin1); - } - if constexpr (deriv2) { - bspl2.eval_deriv(x2, vals2, jmin2); - } else { - bspl2.eval_basis(x2, vals2, jmin2); - } - - double y = 0.0; - for (int i(0); i < bspl1.degree() + 1; ++i) { - for (int j(0); j < bspl2.degree() + 1; ++j) { - y += m_bcoef(jmin1 + i, jmin2 + j) * vals1(i) * vals2(j); - } - } - return y; -} - -double Spline2D::eval(const double x1, const double x2) const -{ - return eval_deriv(x1, x2); -} - -template -double Spline2D::eval_deriv(const double x1, const double x2) const -{ - std::vector values1(m_bspl1.degree() + 1); - std::vector values2(m_bspl2.degree() + 1); - DSpan1D vals1(values1.data(), values1.size()); - DSpan1D vals2(values2.data(), values2.size()); - - if (m_bspl1.is_uniform()) { - if (m_bspl2.is_uniform()) { - return eval_intern( - x1, - x2, - static_cast(m_bspl1), - static_cast(m_bspl2), - vals1, - vals2); - } else { - return eval_intern( - x1, - x2, - static_cast(m_bspl1), - static_cast(m_bspl2), - vals1, - vals2); - } - } else { - if (m_bspl2.is_uniform()) { - return eval_intern( - x1, - x2, - static_cast(m_bspl1), - static_cast(m_bspl2), - vals1, - vals2); - } else { - return eval_intern( - x1, - x2, - static_cast(m_bspl1), - static_cast(m_bspl2), - vals1, - vals2); - } - } -} - -void Spline2D::eval_array(DSpan2D const& x1, DSpan2D const& x2, DSpan2D& y) const -{ - assert(x1.extent(0) == y.extent(0)); - assert(x1.extent(1) == y.extent(1)); - assert(x2.extent(0) == y.extent(0)); - assert(x2.extent(1) == y.extent(1)); - - for (int i(0); i < x1.extent(0); ++i) { - for (int j(0); j < x1.extent(1); ++j) { - y(i, j) = eval(x1(i, j), x2(i, j)); - } - } -} - -template < - class T1, - std::enable_if_t>*, - class T2, - std::enable_if_t>*> -void Spline2D::eval_array_loop(DSpan2D const& x1, DSpan2D const& x2, DSpan2D& y) const -{ - std::vector values1(m_bspl1.degree() + 1); - std::vector values2(m_bspl2.degree() + 1); - DSpan1D vals1(values1.data(), values1.size()); - DSpan1D vals2(values2.data(), values2.size()); - - const T1& l_bspl1 = static_cast(m_bspl1); - const T2& l_bspl2 = static_cast(m_bspl2); - - for (int i(0); i < x1.extent(0); ++i) { - for (int j(0); j < x1.extent(1); ++j) { - y(i, j) = eval_intern< - T1, - T2, - false, - false>(x1(i, j), x2(i, j), l_bspl1, l_bspl2, vals1, vals2); - } - } -} - -template -void Spline2D::eval_array_deriv(DSpan2D const& x1, DSpan2D const& x2, DSpan2D& y) const -{ - assert(x1.extent(0) == y.extent(0)); - assert(x1.extent(1) == y.extent(1)); - assert(x2.extent(0) == y.extent(0)); - assert(x2.extent(1) == y.extent(1)); - - for (int i(0); i < x1.extent(0); ++i) { - for (int j(0); j < x1.extent(1); ++j) { - y(i, j) = eval_deriv(x1(i, j), x2(i, j)); - } - } -} - -void Spline2D::integrate_dim(DSpan1D& y, const int dim) const -{ - assert(dim >= 0 and dim < 2); - assert(y.extent(0) == m_bcoef.extent(1 - dim)); - - const BSplines& bspline((dim == 0) ? m_bspl1 : m_bspl2); - - std::vector values(m_bcoef.extent(dim)); - DSpan1D vals(values.data(), values.size()); - - bspline.integrals(vals); - - if (dim == 0) { - for (int i(0); i < y.extent(0); ++i) { - y(i) = 0; - for (int j(0); j < m_bcoef.extent(0); ++j) { - y(i) += m_bcoef(j, i) * vals(j); - } - } - } else { - for (int i(0); i < y.extent(0); ++i) { - y(i) = 0; - for (int j(0); j < m_bcoef.extent(1); ++j) { - y(i) += m_bcoef(i, j) * vals(j); - } - } - } -} - -double Spline2D::integrate() const -{ - std::vector int_values(m_bcoef.extent(0)); - DSpan1D int_vals(int_values.data(), int_values.size()); - - integrate_dim(int_vals, 1); - - std::vector values(m_bcoef.extent(0)); - DSpan1D vals(values.data(), values.size()); - - m_bspl1.integrals(vals); - - double y = 0.0; - for (int i(0); i < m_bcoef.extent(0); ++i) { - y += int_vals(i) * vals(i); - } - return y; -} - -} // namespace deprecated diff --git a/vendor/sll/src/deprecated/spline_builder_1d.cpp b/vendor/sll/src/deprecated/spline_builder_1d.cpp deleted file mode 100644 index 5f5e8aa01..000000000 --- a/vendor/sll/src/deprecated/spline_builder_1d.cpp +++ /dev/null @@ -1,472 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "sll/deprecated/boundary_conditions.hpp" -#include "sll/deprecated/bsplines.hpp" -#include "sll/deprecated/bsplines_non_uniform.hpp" -#include "sll/deprecated/spline_1d.hpp" -#include "sll/deprecated/spline_builder_1d.hpp" -#include "sll/math_tools.hpp" -#include "sll/matrix.hpp" - -namespace deprecated { - -std::array SplineBuilder1D::allowed_bcs - = {BoundCond::PERIODIC, BoundCond::HERMITE, BoundCond::GREVILLE}; - -SplineBuilder1D::SplineBuilder1D(const BSplines& bspl, BoundCond xmin_bc, BoundCond xmax_bc) - : bspl(bspl) - , odd(bspl.degree() % 2) - , offset(bspl.is_periodic() ? bspl.degree() / 2 : 0) - , dx((bspl.xmax() - bspl.xmin()) / bspl.ncells()) - , matrix(nullptr) - , m_xmin_bc(xmin_bc) - , m_xmax_bc(xmax_bc) - , m_nbc_xmin(xmin_bc == BoundCond::HERMITE ? bspl.degree() / 2 : 0) - , m_nbc_xmax(xmax_bc == BoundCond::HERMITE ? bspl.degree() / 2 : 0) -{ - int lower_block_size, upper_block_size; - constructor_sanity_checks(); - if (bspl.is_uniform()) { - compute_interpolation_points_uniform(); - compute_block_sizes_uniform(lower_block_size, upper_block_size); - } else { - compute_interpolation_points_non_uniform(); - compute_block_sizes_non_uniform(lower_block_size, upper_block_size); - } - allocate_matrix(lower_block_size, upper_block_size); -} - -//------------------------------------------------------------------------------------------------- - -inline void SplineBuilder1D::constructor_sanity_checks() const -{ - assert(m_xmin_bc == allowed_bcs[0] || m_xmin_bc == allowed_bcs[1] - || m_xmin_bc == allowed_bcs[2]); - assert(m_xmax_bc == allowed_bcs[0] || m_xmax_bc == allowed_bcs[1] - || m_xmax_bc == allowed_bcs[2]); - if (bspl.is_periodic()) { - assert(m_xmin_bc == BoundCond::PERIODIC); - assert(m_xmax_bc == BoundCond::PERIODIC); - } - - assert(not bspl.radial()); -} - -//------------------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------- - -const DSpan1D& SplineBuilder1D::get_interp_points() const -{ - return interp_pts; -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Compute interpolant functions * - ************************************************************************************/ - -void SplineBuilder1D::compute_interpolant_degree1(Spline1D& spline, const DSpan1D& vals) const -{ - for (int i(0); i < bspl.nbasis(); ++i) { - spline.bcoef(i) = vals(i); - } - if (bspl.is_periodic()) { - spline.bcoef(bspl.nbasis()) = spline.bcoef(0); - } - return; -} - -//------------------------------------------------------------------------------------------------- - -void SplineBuilder1D::compute_interpolant( - Spline1D& spline, - const DSpan1D& vals, - const DSpan1D* derivs_xmin, - const DSpan1D* derivs_xmax) const -{ - assert(vals.extent(0) == bspl.nbasis() - m_nbc_xmin - m_nbc_xmax); - assert(spline.belongs_to_space(bspl)); - // TODO: LOG Errors - if (bspl.degree() == 1) - return compute_interpolant_degree1(spline, vals); - - assert((m_xmin_bc == BoundCond::HERMITE) - != (derivs_xmin == nullptr || derivs_xmin->extent(0) == 0)); - assert((m_xmax_bc == BoundCond::HERMITE) - != (derivs_xmax == nullptr || derivs_xmax->extent(0) == 0)); - - // Hermite boundary conditions at xmin, if any - // NOTE: For consistency with the linear system, the i-th derivative - // provided by the user must be multiplied by dx^i - if (m_xmin_bc == BoundCond::HERMITE) { - for (int i(m_nbc_xmin); i > 0; --i) { - spline.bcoef(m_nbc_xmin - i) = (*derivs_xmin)(i - 1) * ipow(dx, i + odd - 1); - } - } - for (int i(m_nbc_xmin); i < m_nbc_xmin + offset; ++i) { - spline.bcoef(i) = 0.0; - } - - for (int i(0); i < interp_pts.extent(0); ++i) { - spline.bcoef(m_nbc_xmin + i + offset) = vals(i); - } - - // Hermite boundary conditions at xmax, if any - // NOTE: For consistency with the linear system, the i-th derivative - // provided by the user must be multiplied by dx^i - if (m_xmax_bc == BoundCond::HERMITE) { - for (int i(0); i < m_nbc_xmax; ++i) { - spline.bcoef(bspl.nbasis() - m_nbc_xmax + i) = (*derivs_xmax)(i)*ipow(dx, i + odd); - } - } - - DSpan1D bcoef_section(spline.bcoef().data() + offset, bspl.nbasis()); - matrix->solve_inplace(bcoef_section); - - if (m_xmin_bc == BoundCond::PERIODIC and offset != 0) { - for (int i(0); i < offset; ++i) { - spline.bcoef(i) = spline.bcoef(bspl.nbasis() + i); - } - for (int i(offset); i < bspl.degree(); ++i) { - spline.bcoef(bspl.nbasis() + i) = spline.bcoef(i); - } - } -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Compute interpolation points functions * - ************************************************************************************/ - -void SplineBuilder1D::compute_interpolation_points_uniform() -{ - int n_interp_pts = bspl.nbasis() - m_nbc_xmin - m_nbc_xmax; - interp_pts_ptr = std::make_unique(n_interp_pts); - interp_pts = DSpan1D(interp_pts_ptr.get(), n_interp_pts); - - if (m_xmin_bc == BoundCond::PERIODIC) { - double shift(odd == 0 ? 0.5 : 0.0); - for (int i(0); i < n_interp_pts; ++i) { - interp_pts(i) = bspl.xmin() + (i + shift) * dx; - } - } else { - int n_iknots = n_interp_pts + bspl.degree() - 1; - int iknots[n_iknots]; - int i(0); - - // Additional knots near x=xmin - int n_to_fill_min(bspl.degree() - m_nbc_xmin - 1); - for (; i < n_to_fill_min; ++i) { - if (m_xmin_bc == BoundCond::GREVILLE) - iknots[i] = 0; - if (m_xmin_bc == BoundCond::HERMITE) - iknots[i] = -n_to_fill_min + i; - } - - // Knots inside the domain - for (int j(0); j < bspl.ncells() + 1; ++i, ++j) { - iknots[i] = j; - } - - // Additional knots near x=xmax - for (int j(1); i < n_iknots; ++i, ++j) { - if (m_xmax_bc == BoundCond::GREVILLE) - iknots[i] = bspl.ncells(); - if (m_xmax_bc == BoundCond::HERMITE) - iknots[i] = bspl.ncells() + j; - } - - for (int j(0); j < n_interp_pts; ++j) { - int isum(sum(iknots + j, bspl.degree())); - interp_pts(j) = bspl.xmin() + dx * isum / bspl.degree(); - } - - // Non-periodic case, odd degree: fix round-off issues - if (odd == 1) { - interp_pts(0) = bspl.xmin(); - interp_pts(n_interp_pts - 1) = bspl.xmax(); - } - } -} - -//------------------------------------------------------------------------------------------------- - -void SplineBuilder1D::compute_interpolation_points_non_uniform() -{ - const NonUniformBSplines& bspl_nu = static_cast(bspl); - int n_interp_pts = bspl_nu.nbasis() - m_nbc_xmin - m_nbc_xmax; - interp_pts_ptr = std::make_unique(n_interp_pts); - interp_pts = DSpan1D(interp_pts_ptr.get(), n_interp_pts); - - int n_temp_knots(n_interp_pts - 1 + bspl_nu.degree()); - double temp_knots[n_temp_knots]; - - if (m_xmin_bc == BoundCond::PERIODIC) { - for (int i(0); i < n_interp_pts - 1 + bspl_nu.degree(); ++i) { - temp_knots[i] = bspl_nu.get_knot(1 - bspl_nu.degree() + offset + i); - } - } else { - int i(0); - int n_start_pts(bspl_nu.degree() - m_nbc_xmin - 1); - - // Initialise knots relevant to the xmin boundary condition - for (; i < n_start_pts; ++i) { - // As xmin_bc is a const variable the compiler should optimize - // for(if..else..) to if(for..)else(for...) - if (m_xmin_bc == BoundCond::GREVILLE) - temp_knots[i] = bspl_nu.get_knot(0); - if (m_xmin_bc == BoundCond::HERMITE) - temp_knots[i] = 2.0 * bspl_nu.get_knot(0) - bspl_nu.get_knot(n_start_pts - i); - } - - // Initialise central knots - for (int j(0); j < bspl_nu.npoints(); ++i, ++j) { - temp_knots[i] = bspl_nu.get_knot(j); - } - - // Initialise knots relevant to the xmax boundary condition - for (int j(0); i < n_temp_knots; ++i, ++j) { - if (m_xmax_bc == BoundCond::GREVILLE) - temp_knots[i] = bspl_nu.get_knot(bspl_nu.ncells()); - if (m_xmax_bc == BoundCond::HERMITE) - temp_knots[i] = 2.0 * bspl_nu.get_knot(bspl_nu.ncells()) - - bspl_nu.get_knot(bspl_nu.ncells() - 1 - j); - } - } - - // Compute interpolation points using Greville-style averaging - double inv_deg = 1.0 / bspl.degree(); - for (int i(0); i < n_interp_pts; ++i) { - interp_pts(i) = sum(temp_knots + i, bspl.degree()) * inv_deg; - } - - // Periodic case: apply periodic BCs to interpolation points - if (m_xmin_bc == BoundCond::PERIODIC) { - double zone_width(bspl.xmax() - bspl.xmin()); - for (int i(0); i < n_interp_pts; ++i) { - interp_pts(i) = modulo(interp_pts(i) - m_nbc_xmin, zone_width) + bspl.xmin(); - } - } - // Non-periodic case, odd degree: fix round-off issues - else if (odd == 1) { - interp_pts(0) = bspl.xmin(); - interp_pts(n_interp_pts - 1) = bspl.xmax(); - } -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Compute num diags functions * - ************************************************************************************/ - -void SplineBuilder1D::compute_block_sizes_uniform(int& lower_block_size, int& upper_block_size) - const -{ - switch (m_xmin_bc) { - case BoundCond::PERIODIC: - upper_block_size = (bspl.degree()) / 2; - break; - case BoundCond::HERMITE: - upper_block_size = m_nbc_xmin; - break; - case BoundCond::GREVILLE: - upper_block_size = bspl.degree() - 1; - break; - default: - break; // TODO: throw error - } - switch (m_xmax_bc) { - case BoundCond::PERIODIC: - lower_block_size = (bspl.degree()) / 2; - break; - case BoundCond::HERMITE: - lower_block_size = m_nbc_xmax; - break; - case BoundCond::GREVILLE: - lower_block_size = bspl.degree() - 1; - break; - default: - break; // TODO: throw error - } -} - -//------------------------------------------------------------------------------------------------- - -void SplineBuilder1D::compute_block_sizes_non_uniform(int& lower_block_size, int& upper_block_size) - const -{ - switch (m_xmin_bc) { - case BoundCond::PERIODIC: - upper_block_size = (bspl.degree() + 1) / 2; - break; - case BoundCond::HERMITE: - upper_block_size = m_nbc_xmin + 1; - break; - case BoundCond::GREVILLE: - upper_block_size = bspl.degree() - 1; - break; - default: - break; // TODO: throw error - } - switch (m_xmax_bc) { - case BoundCond::PERIODIC: - lower_block_size = (bspl.degree() + 1) / 2; - break; - case BoundCond::HERMITE: - lower_block_size = m_nbc_xmax + 1; - break; - case BoundCond::GREVILLE: - lower_block_size = bspl.degree() - 1; - break; - default: - break; // TODO: throw error - } -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Initailise matrix functions * - ************************************************************************************/ - -void SplineBuilder1D::allocate_matrix(int lower_block_size, int upper_block_size) -{ - // Special case: linear spline - // No need for matrix assembly - if (bspl.degree() == 1) - return; - - int upper_band_width; - if (bspl.is_uniform()) { - upper_band_width = bspl.degree() / 2; - } else { - upper_band_width = (bspl.degree() + 1) / 2; - } - - if (m_xmin_bc == BoundCond::PERIODIC) { - matrix = Matrix::make_new_periodic_banded( - bspl.nbasis(), - upper_band_width, - upper_band_width, - bspl.is_uniform()); - } else { - matrix = Matrix::make_new_block_with_banded_region( - bspl.nbasis(), - upper_band_width, - upper_band_width, - bspl.is_uniform(), - upper_block_size, - lower_block_size); - } - - build_matrix_system(); - - matrix->factorize(); -} - -//------------------------------------------------------------------------------------------------- - -void SplineBuilder1D::build_matrix_system() -{ - int jmin; - - // Hermite boundary conditions at xmin, if any - if (m_xmin_bc == BoundCond::HERMITE) { - double derivs_ptr[(bspl.degree() / 2 + 1) * (bspl.degree() + 1)]; - DSpan2D derivs(derivs_ptr, bspl.degree() + 1, bspl.degree() / 2 + 1); - bspl.eval_basis_and_n_derivs(bspl.xmin(), m_nbc_xmin, derivs, jmin); - - // In order to improve the condition number of the matrix, we normalize - // all derivatives by multiplying the i-th derivative by dx^i - for (int i(0); i < bspl.degree() + 1; ++i) { - for (int j(1); j < bspl.degree() / 2 + 1; ++j) { - derivs(i, j) *= ipow(dx, j); - } - } - - // iterate only to deg as last bspline is 0 - for (int j(0); j < m_nbc_xmin; ++j) { - for (int i(0); i < bspl.degree(); ++i) { - // Elements are set in Fortran order as they are LAPACK input - matrix->set_element(j, i, derivs(i, m_nbc_xmin - j - 1 + odd)); - } - } - } - - // Interpolation points - double values_ptr[bspl.degree() + 1]; - DSpan1D values(values_ptr, bspl.degree() + 1); - for (int i(0); i < bspl.nbasis() - m_nbc_xmin - m_nbc_xmax; ++i) { - bspl.eval_basis(interp_pts(i), values, jmin); - for (int s(0); s < bspl.degree() + 1; ++s) { - int j = modulo(jmin - offset + s, bspl.nbasis()); - matrix->set_element(i + m_nbc_xmin, j, values(s)); - } - } - - // Hermite boundary conditions at xmax, if any - if (m_xmax_bc == BoundCond::HERMITE) { - double derivs_ptr[(bspl.degree() / 2 + 1) * (bspl.degree() + 1)]; - DSpan2D derivs(derivs_ptr, bspl.degree() + 1, bspl.degree() / 2 + 1); - - bspl.eval_basis_and_n_derivs(bspl.xmax(), m_nbc_xmax, derivs, jmin); - - // In order to improve the condition number of the matrix, we normalize - // all derivatives by multiplying the i-th derivative by dx^i - for (int i(0); i < bspl.degree() + 1; ++i) { - for (int j(1); j < bspl.degree() / 2 + 1; ++j) { - derivs(i, j) *= ipow(dx, j); - } - } - - int i0(bspl.nbasis() - bspl.degree()); - int j0(bspl.nbasis() - m_nbc_xmax); - for (int i(0); i < bspl.degree(); ++i) { - for (int j(0); j < m_nbc_xmax; ++j) { - matrix->set_element(j0 + j, i0 + i, derivs(i + 1, j + odd)); - } - } - } -} - -//------------------------------------------------------------------------------------------------- -/************************************************************************************ - * Static functions * - ************************************************************************************/ - -int SplineBuilder1D::compute_num_cells(int degree, BoundCond xmin_bc, BoundCond xmax_bc, int nipts) -{ - assert(degree > 0); - // TODO: xmin in allowed_bcs - // TODO: xmax in allowed_bcs - - if ((xmin_bc == BoundCond::PERIODIC) != (xmax_bc == BoundCond::PERIODIC)) { - std::cerr << "Incompatible BCs" << std::endl; - // TODO: raise error - return -1; - } - - if (xmin_bc == BoundCond::PERIODIC) { - return nipts; - } else { - int nbc_xmin, nbc_xmax; - if (xmin_bc == BoundCond::HERMITE) - nbc_xmin = degree / 2; - else - nbc_xmin = 0; - - if (xmax_bc == BoundCond::HERMITE) - nbc_xmax = degree / 2; - else - nbc_xmax = 0; - - return nipts + nbc_xmin + nbc_xmax - degree; - } -} - -} // namespace deprecated diff --git a/vendor/sll/src/deprecated/spline_builder_2d.cpp b/vendor/sll/src/deprecated/spline_builder_2d.cpp deleted file mode 100644 index 691550979..000000000 --- a/vendor/sll/src/deprecated/spline_builder_2d.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "sll/deprecated/bsplines.hpp" -#include "sll/deprecated/spline_1d.hpp" -#include "sll/deprecated/spline_2d.hpp" -#include "sll/deprecated/spline_builder_1d.hpp" -#include "sll/deprecated/spline_builder_2d.hpp" - -namespace deprecated { - -/****************************************************************************** - * @brief Initialize a 2D tensor product spline interpolator object - * @param[out] self 2D tensor product spline interpolator - * @param[in] bspl1 B-splines (basis) along x1 direction - * @param[in] bspl2 B-splines (basis) along x2 direction - * @param[in] bc_xmin boundary conditions at x1_min and x2_min - * @param[in] bc_xmax boundary conditions at x1_max and x2_max - ******************************************************************************/ -SplineBuilder2D::SplineBuilder2D( - std::array, 2> bspl, - std::array xmin_bc, - std::array xmax_bc) - : bspl(std::move(bspl)) - , interp_1d {SplineBuilder1D(*bspl[0], xmin_bc[0], xmax_bc[0]), SplineBuilder1D(*bspl[1], xmin_bc[1], xmax_bc[1])} - , spline_1d {Spline1D(*bspl[0]), Spline1D(*bspl[1])} - , m_xmin_bc(xmin_bc) - , m_xmax_bc(xmax_bc) - , m_nbc_xmin({interp_1d[0].nbc_xmin(), interp_1d[1].nbc_xmin()}) - , m_nbc_xmax({interp_1d[0].nbc_xmax(), interp_1d[1].nbc_xmax()}) -{ -} - -/****************************************************************************** - * @brief Get coordinates of interpolation points (2D tensor grid) - * @param[in] self 2D tensor product spline interpolator - * @param[out] tau1 x1 coordinates of interpolation points - * @param[out] tau2 x2 coordinates of interpolation points - ******************************************************************************/ -std::array SplineBuilder2D::get_interp_points() const -{ - return {interp_1d[0].get_interp_points(), interp_1d[1].get_interp_points()}; -} - -/****************************************************************************** - * @brief Calculate number of cells from number of interpolation points - * @details Important for parallelization: for given spline degree and BCs, - * calculate the numbers of grid cells along x1 and x2 that yield - * the desired number of interpolation points along x1 and x2 - * - * @param[in] degree spline degrees along x1 and x2 - * @param[in] bc_xmin boundary conditions at x1_min and x2_min - * @param[in] bc_xmax boundary conditions at x1_max and x2_max - * @param[in] nipts desired number of interpolation points along x1 and x2 - * @param[out] ncells calculated number of grid cells along x1 and x2 - ******************************************************************************/ -std::array SplineBuilder2D::compute_num_cells( - std::array degree, - std::array xmin, - std::array xmax, - std::array nipts) -{ - int n0(SplineBuilder1D::compute_num_cells(degree[0], xmin[0], xmax[0], nipts[0])); - int n1(SplineBuilder1D::compute_num_cells(degree[1], xmin[1], xmax[1], nipts[1])); - return {n0, n1}; -} - -/****************************************************************************** - * @brief Compute interpolating 2D spline - * @details Compute coefficients of 2D tensor product spline that - * interpolates function values on grid. If Hermite BCs are used, - * function derivatives at appropriate boundaries are also - *needed. - * - * @param[inout] self 2D tensor product spline interpolator - * @param[inout] spline 2D tensor product spline - * @param[in] gtau function values of interpolation points - * @param[in] boundary_data (optional) structure with boundary conditions - ******************************************************************************/ -void SplineBuilder2D::compute_interpolant( - Spline2D const& spline, - DSpan2D const& vals, - Boundary_data_2d boundary_data) const -{ - int dim_0_size = (bspl[0]->nbasis() - m_nbc_xmin[0] - m_nbc_xmax[0]); - int dim_1_size = (bspl[1]->nbasis() - m_nbc_xmin[1] - m_nbc_xmax[1]); - // TODO fix assert - if (m_nbc_xmin[0] > 0) { - assert(boundary_data.derivs_x1_min != nullptr); - assert(boundary_data.derivs_x1_min->extent(0) == dim_1_size); - assert(boundary_data.derivs_x1_min->extent(1) == m_nbc_xmin[0]); - for (int i(0); i < m_nbc_xmin[0]; ++i) { - for (int j(0); j < dim_1_size; ++j) { - spline.bcoef(i, j + m_nbc_xmin[1]) = (*boundary_data.derivs_x1_min)(j, i); - } - } - } - if (m_nbc_xmax[0] > 0) { - assert(boundary_data.derivs_x1_max != nullptr); - assert(boundary_data.derivs_x1_max->extent(0) == dim_1_size); - assert(boundary_data.derivs_x1_max->extent(1) == m_nbc_xmax[0]); - for (int i(0); i < m_nbc_xmax[0]; ++i) { - for (int j(0); j < dim_1_size; ++j) { - spline.bcoef(i + bspl[0]->nbasis() - m_nbc_xmax[0], j + m_nbc_xmin[1]) - = (*boundary_data.derivs_x1_max)(j, i); - } - } - } - if (m_nbc_xmin[1] > 0) { - assert(boundary_data.derivs_x2_min != nullptr); - assert(boundary_data.derivs_x2_min->extent(0) == dim_0_size); - assert(boundary_data.derivs_x2_min->extent(1) == m_nbc_xmin[1]); - for (int i(0); i < dim_0_size; ++i) { - for (int j(0); j < m_nbc_xmin[1]; ++j) { - spline.bcoef(i + m_nbc_xmin[0], j) = (*boundary_data.derivs_x2_min)(i, j); - } - } - } - if (m_nbc_xmax[1] > 0) { - assert(boundary_data.derivs_x2_max != nullptr); - assert(boundary_data.derivs_x2_max->extent(0) == dim_0_size); - assert(boundary_data.derivs_x2_max->extent(1) == m_nbc_xmax[1]); - for (int i(0); i < dim_0_size; ++i) { - for (int j(0); j < m_nbc_xmax[1]; ++j) { - spline.bcoef(i + m_nbc_xmin[0], j + bspl[1]->nbasis() - m_nbc_xmax[1]) - = (*boundary_data.derivs_x2_max)(i, j); - } - } - } - if (m_nbc_xmin[0] > 0 and m_nbc_xmin[1] > 0) { - assert(boundary_data.mixed_derivs_a != nullptr); - assert(boundary_data.mixed_derivs_a->extent(0) == m_nbc_xmin[0]); - assert(boundary_data.mixed_derivs_a->extent(1) == m_nbc_xmin[1]); - for (int i(0); i < m_nbc_xmin[0]; ++i) { - for (int j(0); j < m_nbc_xmin[1]; ++j) { - spline.bcoef(i, j) = (*boundary_data.mixed_derivs_a)(i, j); - } - } - } - if (m_nbc_xmax[0] > 0 and m_nbc_xmin[1] > 0) { - assert(boundary_data.mixed_derivs_b != nullptr); - assert(boundary_data.mixed_derivs_b->extent(0) == m_nbc_xmax[0]); - assert(boundary_data.mixed_derivs_b->extent(1) == m_nbc_xmin[1]); - for (int i(0); i < m_nbc_xmax[0]; ++i) { - for (int j(0); j < m_nbc_xmin[1]; ++j) { - spline.bcoef(i + bspl[0]->nbasis() - m_nbc_xmax[0], j) - = (*boundary_data.mixed_derivs_b)(i, j); - } - } - } - if (m_nbc_xmin[0] > 0 and m_nbc_xmax[1] > 0) { - assert(boundary_data.mixed_derivs_c != nullptr); - assert(boundary_data.mixed_derivs_c->extent(0) == m_nbc_xmin[0]); - assert(boundary_data.mixed_derivs_c->extent(1) == m_nbc_xmax[1]); - for (int i(0); i < m_nbc_xmin[0]; ++i) { - for (int j(0); j < m_nbc_xmax[1]; ++j) { - spline.bcoef(i, j + bspl[1]->nbasis() - m_nbc_xmax[1]) - = (*boundary_data.mixed_derivs_c)(i, j); - } - } - } - if (m_nbc_xmax[0] > 0 and m_nbc_xmax[1] > 0) { - assert(boundary_data.mixed_derivs_d != nullptr); - assert(boundary_data.mixed_derivs_d->extent(0) == m_nbc_xmax[0]); - assert(boundary_data.mixed_derivs_d->extent(1) == m_nbc_xmax[1]); - for (int i(0); i < m_nbc_xmax[0]; ++i) { - for (int j(0); j < m_nbc_xmax[1]; ++j) { - spline - .bcoef(i + bspl[0]->nbasis() - m_nbc_xmax[0], - j + bspl[1]->nbasis() - m_nbc_xmax[1]) - = (*boundary_data.mixed_derivs_d)(i, j); - } - } - } - - compute_interpolant_boundary_done(spline, vals); -} - -/****************************************************************************** - * @brief Compute interpolating 2D spline - * @details Compute coefficients of 2D tensor product spline that - * interpolates function values on grid. If Hermite BCs are used, - * function derivatives at appropriate boundaries are also - *needed. - * - * @param[inout] self 2D tensor product spline interpolator - * @param[inout] spline 2D tensor product spline - * @param[in] gtau function values of interpolation points - * @param[in] boundary_data (optional) structure with boundary conditions - ******************************************************************************/ -void SplineBuilder2D::compute_interpolant(Spline2D const& spline, DSpan2D const& vals) const -{ - assert(m_xmin_bc[0] != BoundCond::HERMITE); - assert(m_xmax_bc[0] != BoundCond::HERMITE); - assert(m_xmin_bc[1] != BoundCond::HERMITE); - assert(m_xmax_bc[1] != BoundCond::HERMITE); - compute_interpolant_boundary_done(spline, vals); -} - -/****************************************************************************** - * @brief Compute interpolating 2D spline - * @details Compute coefficients of 2D tensor product spline that - * interpolates function values on grid. If Hermite BCs are used, - * function derivatives at appropriate boundaries are also - *needed. - * - * @param[inout] self 2D tensor product spline interpolator - * @param[inout] spline 2D tensor product spline - * @param[in] gtau function values of interpolation points - * @param[in] boundary_data (optional) structure with boundary conditions - ******************************************************************************/ -void SplineBuilder2D::compute_interpolant_boundary_done(Spline2D const& spline, DSpan2D const& vals) - const -{ - assert(vals.extent(0) == (bspl[0]->nbasis() - m_nbc_xmin[0] - m_nbc_xmax[0])); - assert(vals.extent(1) == (bspl[1]->nbasis() - m_nbc_xmin[1] - m_nbc_xmax[1])); - assert(spline.belongs_to_space(*bspl[0], *bspl[1])); - - int dim_0_size = (bspl[0]->nbasis() - m_nbc_xmin[0] - m_nbc_xmax[0]); - int dim_1_size = (bspl[1]->nbasis() - m_nbc_xmin[1] - m_nbc_xmax[1]); - - // Copy interpolation data onto w array - for (int i(0); i < vals.extent(0); ++i) { - for (int j(0); j < vals.extent(1); ++j) { - spline.bcoef(m_nbc_xmin[0] + i, m_nbc_xmin[1] + j) = vals(i, j); - } - } - - std::array spline_1d {Spline1D(*bspl[0]), Spline1D(*bspl[1])}; - double t_storage_ptr[spline.bcoef().extent(0) * spline.bcoef().extent(1)]; - DSpan2D t_storage(t_storage_ptr, spline.bcoef().extent(1), spline.bcoef().extent(0)); - // Cycle over x1 position (or order of x1-derivative at boundary) - // and interpolate f along x2 direction. Store coefficients in bcoef - { - int i(0); - for (; i < bspl[0]->nbasis(); ++i) { - DSpan1D values(&spline.bcoef(i, m_nbc_xmin[1]), dim_1_size); - DSpan1D derivs_xmin(&spline.bcoef(i, 0), m_nbc_xmin[1]); - DSpan1D derivs_xmax(&spline.bcoef(i, bspl[1]->nbasis() - m_nbc_xmax[1]), m_nbc_xmax[1]); - interp_1d[1].compute_interpolant(spline_1d[1], values, &derivs_xmin, &derivs_xmax); - - int j(0); - for (; j < bspl[1]->nbasis(); ++j) { - t_storage(j, i) = spline_1d[1].bcoef(j); - } - for (; j < spline.bcoef().extent(1); ++j) { - t_storage(j, i) = spline.bcoef(i, j); - } - } - for (; i < spline.bcoef().extent(0); ++i) { - for (int j(0); j < spline.bcoef().extent(1); ++j) { - t_storage(j, i) = spline.bcoef(i, j); - } - } - } - - // Cycle over x2 position (or order of x2-derivative at boundary) - // and interpolate f along x1 direction. Store coefficients in bwork - { - int j(0); - for (; j < bspl[1]->nbasis(); ++j) { - DSpan1D values(&t_storage(j, m_nbc_xmin[0]), dim_0_size); - DSpan1D derivs_xmin(&t_storage(j, 0), m_nbc_xmin[0]); - DSpan1D derivs_xmax(&t_storage(j, bspl[0]->nbasis() - m_nbc_xmax[0]), m_nbc_xmax[0]); - interp_1d[0].compute_interpolant(spline_1d[0], values, &derivs_xmin, &derivs_xmax); - - int i(0); - for (; i < bspl[0]->nbasis(); ++i) { - spline.bcoef(i, j) = spline_1d[0].bcoef(i); - } - for (; i < spline.bcoef().extent(0); ++i) { - spline.bcoef(i, j) = t_storage(j, i); - } - } - for (; j < spline.bcoef().extent(1); ++j) { - for (int i(0); i < spline.bcoef().extent(0); ++i) { - spline.bcoef(i, j) = t_storage(j, i); - } - } - } - if (m_xmin_bc[1] == BoundCond::PERIODIC) { - for (int i(0); i < spline.bcoef().extent(0); ++i) { - for (int j(0); j < bspl[1]->degree(); ++j) { - spline.bcoef(i, j + bspl[1]->nbasis()) = spline.bcoef(i, j); - } - } - } - if (m_xmin_bc[0] == BoundCond::PERIODIC) { - for (int i(0); i < bspl[0]->degree(); ++i) { - for (int j(0); j < spline.bcoef().extent(1); ++j) { - spline.bcoef(i + bspl[0]->nbasis(), j) = spline.bcoef(i, j); - } - } - } -} - -} // namespace deprecated diff --git a/vendor/sll/tests/2d_spline_builder.cpp b/vendor/sll/tests/2d_spline_builder.cpp deleted file mode 100644 index 2b5a45fd2..000000000 --- a/vendor/sll/tests/2d_spline_builder.cpp +++ /dev/null @@ -1,349 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "cosine_evaluator.hpp" -#include "evaluator_2d.hpp" -#include "polynomial_evaluator.hpp" -#include "spline_error_bounds.hpp" - - -#if defined(BCL_GREVILLE) -static constexpr BoundCond s_bcl = BoundCond::GREVILLE; -#elif defined(BCL_HERMITE) -static constexpr BoundCond s_bcl = BoundCond::HERMITE; -#endif - -#if defined(BCR_GREVILLE) -static constexpr BoundCond s_bcr = BoundCond::GREVILLE; -#elif defined(BCR_HERMITE) -static constexpr BoundCond s_bcr = BoundCond::HERMITE; -#endif - -struct DimX -{ - static constexpr bool PERIODIC = false; -}; - -struct DimY -{ - static constexpr bool PERIODIC = false; -}; - -static constexpr std::size_t s_degree_x = DEGREE_X; -static constexpr std::size_t s_degree_y = DEGREE_Y; - -#if defined(BSPLINES_TYPE_UNIFORM) -using BSplinesX = UniformBSplines; -using BSplinesY = UniformBSplines; -#elif defined(BSPLINES_TYPE_NON_UNIFORM) -using BSplinesX = NonUniformBSplines; -using BSplinesY = NonUniformBSplines; -#endif - -using GrevillePointsX = GrevilleInterpolationPoints; - -using IDimX = GrevillePointsX::interpolation_mesh_type; -using IndexX = ddc::DiscreteElement; -using DVectX = ddc::DiscreteVector; -using CoordX = ddc::Coordinate; - -using GrevillePointsY = GrevilleInterpolationPoints; - -using IDimY = GrevillePointsY::interpolation_mesh_type; -using IndexY = ddc::DiscreteElement; -using DVectY = ddc::DiscreteVector; -using CoordY = ddc::Coordinate; - -using IndexXY = ddc::DiscreteElement; -using BsplIndexXY = ddc::DiscreteElement; -using SplineXY = ddc::Chunk>; -using FieldXY = ddc::Chunk>; -using CoordXY = ddc::Coordinate; - -using BuilderX = SplineBuilder; -using BuilderY = SplineBuilder; -using BuilderXY = SplineBuilder2D; - -using EvaluatorType = Evaluator2D::Evaluator< - PolynomialEvaluator::Evaluator, - PolynomialEvaluator::Evaluator>; - -// Checks that when evaluating the spline at interpolation points one -// recovers values that were used to build the spline -TEST(NonPeriodic2DSplineBuilderTest, Identity) -{ - CoordXY constexpr x0(0., 0.); - CoordXY constexpr xN(1., 1.); - std::size_t constexpr ncells1 = 100; - std::size_t constexpr ncells2 = 50; - - // 1. Create BSplines - { -#if defined(BSPLINES_TYPE_UNIFORM) - ddc::init_discrete_space(ddc::select(x0), ddc::select(xN), ncells1); -#elif defined(BSPLINES_TYPE_NON_UNIFORM) - DVectX constexpr npoints(ncells1 + 1); - std::vector breaks(npoints); - double constexpr dx = (ddc::get(xN) - ddc::get(x0)) / ncells1; - for (int i(0); i < npoints; ++i) { - breaks[i] = CoordX(ddc::get(x0) + i * dx); - } - ddc::init_discrete_space(breaks); -#endif - } - { -#if defined(BSPLINES_TYPE_UNIFORM) - ddc::init_discrete_space(ddc::select(x0), ddc::select(xN), ncells2); -#elif defined(BSPLINES_TYPE_NON_UNIFORM) - DVectY constexpr npoints(ncells2 + 1); - std::vector breaks(npoints); - double constexpr dx = (ddc::get(xN) - ddc::get(x0)) / ncells2; - for (int i(0); i < npoints; ++i) { - breaks[i] = CoordY(ddc::get(x0) + i * dx); - } - ddc::init_discrete_space(breaks); -#endif - } - - ddc::DiscreteDomain const dom_bsplines_xy( - BsplIndexXY(0, 0), - ddc::DiscreteVector( - ddc::discrete_space().size(), - ddc::discrete_space().size())); - - // 2. Create a Spline represented by a chunk over BSplines - // The chunk is filled with garbage data, we need to initialize it - SplineXY coef(dom_bsplines_xy); - - // 3. Create the interpolation domain - ddc::init_discrete_space(GrevillePointsX::get_sampling()); - ddc::init_discrete_space(GrevillePointsY::get_sampling()); - ddc::DiscreteDomain interpolation_domain_X(GrevillePointsX::get_domain()); - ddc::DiscreteDomain interpolation_domain_Y(GrevillePointsY::get_domain()); - ddc::DiscreteDomain - interpolation_domain(interpolation_domain_X, interpolation_domain_Y); - - // 4. Create a SplineBuilder over BSplines using some boundary conditions - const BuilderXY spline_builder(interpolation_domain); - - // 5. Allocate and fill a chunk over the interpolation domain - FieldXY yvals(interpolation_domain); - EvaluatorType evaluator(interpolation_domain); - evaluator(yvals.span_view()); - - int constexpr shift_X = s_degree_x % 2; // shift = 0 for even order, 1 for odd order - int constexpr shift_Y = s_degree_y % 2; // shift = 0 for even order, 1 for odd order - - int constexpr n_bc_X = s_degree_x / 2; - int constexpr n_bc_Y = s_degree_y / 2; - - std::vector deriv_xmin_data_X(n_bc_X * interpolation_domain_Y.size()); - std::vector deriv_xmax_data_X(n_bc_X * interpolation_domain_Y.size()); - DSpan2D deriv_xmin(deriv_xmin_data_X.data(), interpolation_domain_Y.size(), n_bc_X); - DSpan2D deriv_xmax(deriv_xmax_data_X.data(), interpolation_domain_Y.size(), n_bc_X); - CDSpan2D c_deriv_xmin(deriv_xmin_data_X.data(), interpolation_domain_Y.size(), n_bc_X); - CDSpan2D c_deriv_xmax(deriv_xmax_data_X.data(), interpolation_domain_Y.size(), n_bc_X); - auto yiter = interpolation_domain_Y.begin(); - for (std::size_t ii = 0; ii < interpolation_domain_Y.size(); ++ii) { - for (std::size_t jj = 0; jj < n_bc_X; ++jj) { - deriv_xmin(ii, jj) = evaluator - .deriv(ddc::get(x0), - double(ddc::coordinate(*yiter)), - jj + shift_X, - 0); - deriv_xmax(ii, jj) = evaluator - .deriv(ddc::get(xN), - double(ddc::coordinate(*yiter)), - jj + shift_X, - 0); - } - yiter++; - } - - std::vector deriv_xmin_data_Y(n_bc_Y * interpolation_domain_X.size()); - std::vector deriv_xmax_data_Y(n_bc_Y * interpolation_domain_X.size()); - DSpan2D deriv_ymin(deriv_xmin_data_Y.data(), interpolation_domain_X.size(), n_bc_Y); - DSpan2D deriv_ymax(deriv_xmax_data_Y.data(), interpolation_domain_X.size(), n_bc_Y); - CDSpan2D c_deriv_ymin(deriv_xmin_data_Y.data(), interpolation_domain_X.size(), n_bc_Y); - CDSpan2D c_deriv_ymax(deriv_xmax_data_Y.data(), interpolation_domain_X.size(), n_bc_Y); - auto xiter = interpolation_domain_X.begin(); - for (std::size_t ii = 0; ii < interpolation_domain_X.size(); ++ii) { - for (std::size_t jj = 0; jj < n_bc_Y; ++jj) { - deriv_ymin(ii, jj) = evaluator - .deriv(double(ddc::coordinate(*xiter)), - ddc::get(x0), - 0, - jj + shift_Y); - deriv_ymax(ii, jj) = evaluator - .deriv(double(ddc::coordinate(*xiter)), - ddc::get(xN), - 0, - jj + shift_Y); - } - xiter++; - } - - std::vector mixed_derivs_xmin_ymin_data(n_bc_X * n_bc_Y); - std::vector mixed_derivs_xmin_ymax_data(n_bc_X * n_bc_Y); - std::vector mixed_derivs_xmax_ymin_data(n_bc_X * n_bc_Y); - std::vector mixed_derivs_xmax_ymax_data(n_bc_X * n_bc_Y); - DSpan2D mixed_derivs_xmin_ymin(mixed_derivs_xmin_ymin_data.data(), n_bc_X, n_bc_Y); - DSpan2D mixed_derivs_xmin_ymax(mixed_derivs_xmin_ymax_data.data(), n_bc_X, n_bc_Y); - DSpan2D mixed_derivs_xmax_ymin(mixed_derivs_xmax_ymin_data.data(), n_bc_X, n_bc_Y); - DSpan2D mixed_derivs_xmax_ymax(mixed_derivs_xmax_ymax_data.data(), n_bc_X, n_bc_Y); - CDSpan2D c_mixed_derivs_xmin_ymin(mixed_derivs_xmin_ymin_data.data(), n_bc_X, n_bc_Y); - CDSpan2D c_mixed_derivs_xmin_ymax(mixed_derivs_xmin_ymax_data.data(), n_bc_X, n_bc_Y); - CDSpan2D c_mixed_derivs_xmax_ymin(mixed_derivs_xmax_ymin_data.data(), n_bc_X, n_bc_Y); - CDSpan2D c_mixed_derivs_xmax_ymax(mixed_derivs_xmax_ymax_data.data(), n_bc_X, n_bc_Y); - for (std::size_t ii = 0; ii < n_bc_X; ++ii) { - for (std::size_t jj = 0; jj < n_bc_Y; ++jj) { - mixed_derivs_xmin_ymin(ii, jj) = evaluator - .deriv(ddc::get(x0), - ddc::get(x0), - ii + shift_X, - jj + shift_Y); - mixed_derivs_xmin_ymax(ii, jj) = evaluator - .deriv(ddc::get(x0), - ddc::get(xN), - ii + shift_X, - jj + shift_Y); - mixed_derivs_xmax_ymin(ii, jj) = evaluator - .deriv(ddc::get(xN), - ddc::get(x0), - ii + shift_X, - jj + shift_Y); - mixed_derivs_xmax_ymax(ii, jj) = evaluator - .deriv(ddc::get(xN), - ddc::get(xN), - ii + shift_X, - jj + shift_Y); - } - } - - const std::optional deriv_l_X( - s_bcl == BoundCond::HERMITE ? std::optional(c_deriv_xmin) : std::nullopt); - const std::optional deriv_r_X( - s_bcr == BoundCond::HERMITE ? std::optional(c_deriv_xmax) : std::nullopt); - const std::optional deriv_l_Y( - s_bcl == BoundCond::HERMITE ? std::optional(c_deriv_ymin) : std::nullopt); - const std::optional deriv_r_Y( - s_bcr == BoundCond::HERMITE ? std::optional(c_deriv_ymax) : std::nullopt); - const std::optional md_xmin_ymin( - s_bcl == BoundCond::HERMITE ? std::optional(c_mixed_derivs_xmin_ymin) : std::nullopt); - const std::optional md_xmin_ymax( - s_bcl == BoundCond::HERMITE && s_bcr == BoundCond::HERMITE - ? std::optional(c_mixed_derivs_xmin_ymax) - : std::nullopt); - const std::optional md_xmax_ymin( - s_bcl == BoundCond::HERMITE && s_bcr == BoundCond::HERMITE - ? std::optional(c_mixed_derivs_xmax_ymin) - : std::nullopt); - const std::optional md_xmax_ymax( - s_bcr == BoundCond::HERMITE ? std::optional(c_mixed_derivs_xmax_ymax) : std::nullopt); - - // 5. Finally build the spline by filling `coef` - spline_builder( - coef, - yvals, - deriv_l_X, - deriv_r_X, - deriv_l_Y, - deriv_r_Y, - md_xmin_ymin, - md_xmax_ymin, - md_xmin_ymax, - md_xmax_ymax); - - // 6. Create a SplineEvaluator to evaluate the spline at any point in the domain of the BSplines - const SplineEvaluator2D spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); - - ddc::Chunk> coords_eval(interpolation_domain); - ddc::for_each(interpolation_domain, [&](IndexXY const ixy) { - coords_eval(ixy) = CoordXY( - ddc::coordinate(ddc::select(ixy)), - ddc::coordinate(ddc::select(ixy))); - }); - - FieldXY spline_eval(interpolation_domain); - spline_evaluator(spline_eval.span_view(), coords_eval.span_cview(), coef.span_cview()); - - FieldXY spline_eval_deriv1(interpolation_domain); - spline_evaluator.deriv_dim_1( - spline_eval_deriv1.span_view(), - coords_eval.span_cview(), - coef.span_cview()); - - FieldXY spline_eval_deriv2(interpolation_domain); - spline_evaluator.deriv_dim_2( - spline_eval_deriv2.span_view(), - coords_eval.span_cview(), - coef.span_cview()); - - FieldXY spline_eval_deriv12(interpolation_domain); - spline_evaluator.deriv_dim_1_and_2( - spline_eval_deriv12.span_view(), - coords_eval.span_cview(), - coef.span_cview()); - - // 7. Checking errors - double max_norm_error = 0.; - double max_norm_error_diff1 = 0.; - double max_norm_error_diff2 = 0.; - double max_norm_error_diff12 = 0.; - ddc::for_each(interpolation_domain, [&](IndexXY const ixy) { - IndexX const ix = ddc::select(ixy); - IndexY const iy = ddc::select(ixy); - CoordX const x = ddc::coordinate(ix); - CoordY const y = ddc::coordinate(iy); - - // Compute error - double const error = spline_eval(ix, iy) - yvals(ix, iy); - max_norm_error = std::fmax(max_norm_error, std::fabs(error)); - - // Compute error - double const error_deriv1 = spline_eval_deriv1(ix, iy) - evaluator.deriv(x, y, 1, 0); - max_norm_error_diff1 = std::fmax(max_norm_error_diff1, std::fabs(error_deriv1)); - - // Compute error - double const error_deriv2 = spline_eval_deriv2(ix, iy) - evaluator.deriv(x, y, 0, 1); - max_norm_error_diff2 = std::fmax(max_norm_error_diff2, std::fabs(error_deriv2)); - - // Compute error - double const error_deriv12 = spline_eval_deriv12(ix, iy) - evaluator.deriv(x, y, 1, 1); - max_norm_error_diff12 = std::fmax(max_norm_error_diff12, std::fabs(error_deriv12)); - }); - EXPECT_LE(max_norm_error / evaluator.max_norm(), 1.0e-14); - EXPECT_LE(max_norm_error_diff1 / evaluator.max_norm(1, 0), 1.0e-12); - EXPECT_LE(max_norm_error_diff2 / evaluator.max_norm(0, 1), 1.0e-12); - EXPECT_LE(max_norm_error_diff12 / evaluator.max_norm(1, 1), 1.0e-10); -} - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - ::Kokkos::ScopeGuard kokkos_scope(argc, argv); - ::ddc::ScopeGuard ddc_scope(argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/vendor/sll/tests/2d_spline_builder_periodic.cpp b/vendor/sll/tests/2d_spline_builder_periodic.cpp deleted file mode 100644 index 8b29f9801..000000000 --- a/vendor/sll/tests/2d_spline_builder_periodic.cpp +++ /dev/null @@ -1,239 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "cosine_evaluator.hpp" -#include "evaluator_2d.hpp" -#include "polynomial_evaluator.hpp" -#include "spline_error_bounds.hpp" - -struct DimX -{ - static constexpr bool PERIODIC = true; -}; - -struct DimY -{ - static constexpr bool PERIODIC = true; -}; - -static constexpr std::size_t s_degree_x = DEGREE_X; -static constexpr std::size_t s_degree_y = DEGREE_Y; - -#if defined(BSPLINES_TYPE_UNIFORM) -using BSplinesX = UniformBSplines; -using BSplinesY = UniformBSplines; -#elif defined(BSPLINES_TYPE_NON_UNIFORM) -using BSplinesX = NonUniformBSplines; -using BSplinesY = NonUniformBSplines; -#endif - -using GrevillePointsX - = GrevilleInterpolationPoints; -using GrevillePointsY - = GrevilleInterpolationPoints; - -using IDimX = GrevillePointsX::interpolation_mesh_type; -using IndexX = ddc::DiscreteElement; -using DVectX = ddc::DiscreteVector; -using CoordX = ddc::Coordinate; - -using IDimY = GrevillePointsY::interpolation_mesh_type; -using IndexY = ddc::DiscreteElement; -using DVectY = ddc::DiscreteVector; -using CoordY = ddc::Coordinate; - -using IndexXY = ddc::DiscreteElement; -using BsplIndexXY = ddc::DiscreteElement; -using SplineXY = ddc::Chunk>; -using FieldXY = ddc::Chunk>; -using CoordXY = ddc::Coordinate; - -using BuilderX = SplineBuilder; -using BuilderY = SplineBuilder; -using BuilderXY = SplineBuilder2D; - -using EvaluatorType = Evaluator2D:: - Evaluator, CosineEvaluator::Evaluator>; - -// Checks that when evaluating the spline at interpolation points one -// recovers values that were used to build the spline -TEST(Periodic2DSplineBuilderTest, Identity) -{ - CoordXY constexpr x0(0., 0.); - CoordXY constexpr xN(1., 1.); - std::size_t constexpr ncells1 = 100; - std::size_t constexpr ncells2 = 50; - - // 1. Create BSplines - { -#if defined(BSPLINES_TYPE_UNIFORM) - ddc::init_discrete_space(ddc::select(x0), ddc::select(xN), ncells1); -#elif defined(BSPLINES_TYPE_NON_UNIFORM) - DVectX constexpr npoints(ncells1 + 1); - std::vector breaks(npoints); - double constexpr dx = (ddc::get(xN) - ddc::get(x0)) / ncells1; - for (int i(0); i < npoints; ++i) { - breaks[i] = CoordX(ddc::get(x0) + i * dx); - } - ddc::init_discrete_space(breaks); -#endif - } - { -#if defined(BSPLINES_TYPE_UNIFORM) - ddc::init_discrete_space(ddc::select(x0), ddc::select(xN), ncells2); -#elif defined(BSPLINES_TYPE_NON_UNIFORM) - DVectY constexpr npoints(ncells2 + 1); - std::vector breaks(npoints); - double constexpr dx = (ddc::get(xN) - ddc::get(x0)) / ncells2; - for (int i(0); i < npoints; ++i) { - breaks[i] = CoordY(ddc::get(x0) + i * dx); - } - ddc::init_discrete_space(breaks); -#endif - } - - ddc::DiscreteDomain const dom_bsplines_xy( - BsplIndexXY(0, 0), - ddc::DiscreteVector( - ddc::discrete_space().size(), - ddc::discrete_space().size())); - - // 2. Create a Spline represented by a chunk over BSplines - // The chunk is filled with garbage data, we need to initialize it - SplineXY coef(dom_bsplines_xy); - - // 3. Create the interpolation domain - ddc::init_discrete_space(GrevillePointsX::get_sampling()); - ddc::init_discrete_space(GrevillePointsY::get_sampling()); - ddc::DiscreteDomain interpolation_domain_X(GrevillePointsX::get_domain()); - ddc::DiscreteDomain interpolation_domain_Y(GrevillePointsY::get_domain()); - ddc::DiscreteDomain - interpolation_domain(interpolation_domain_X, interpolation_domain_Y); - - // 4. Create a SplineBuilder over BSplines using some boundary conditions - const BuilderXY spline_builder(interpolation_domain); - - // 5. Allocate and fill a chunk over the interpolation domain - FieldXY yvals(interpolation_domain); - EvaluatorType evaluator(interpolation_domain); - evaluator(yvals.span_view()); - - // 6. Finally build the spline by filling `coef` - spline_builder(coef, yvals); - - // 7. Create a SplineEvaluator to evaluate the spline at any point in the domain of the BSplines - const SplineEvaluator2D spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); - - ddc::Chunk> coords_eval(interpolation_domain); - ddc::for_each(interpolation_domain, [&](IndexXY const ixy) { - coords_eval(ixy) = CoordXY( - ddc::coordinate(ddc::select(ixy)), - ddc::coordinate(ddc::select(ixy))); - }); - - FieldXY spline_eval(interpolation_domain); - spline_evaluator(spline_eval.span_view(), coords_eval.span_cview(), coef.span_cview()); - - FieldXY spline_eval_deriv1(interpolation_domain); - spline_evaluator.deriv_dim_1( - spline_eval_deriv1.span_view(), - coords_eval.span_cview(), - coef.span_cview()); - - FieldXY spline_eval_deriv2(interpolation_domain); - spline_evaluator.deriv_dim_2( - spline_eval_deriv2.span_view(), - coords_eval.span_cview(), - coef.span_cview()); - - FieldXY spline_eval_deriv12(interpolation_domain); - spline_evaluator.deriv_dim_1_and_2( - spline_eval_deriv12.span_view(), - coords_eval.span_cview(), - coef.span_cview()); - - // 8. Checking errors - double max_norm_error = 0.; - double max_norm_error_diff1 = 0.; - double max_norm_error_diff2 = 0.; - double max_norm_error_diff12 = 0.; - ddc::for_each(interpolation_domain, [&](IndexXY const ixy) { - IndexX const ix = ddc::select(ixy); - IndexY const iy = ddc::select(ixy); - CoordX const x = ddc::coordinate(ix); - CoordY const y = ddc::coordinate(iy); - - // Compute error - double const error = spline_eval(ix, iy) - yvals(ix, iy); - max_norm_error = std::fmax(max_norm_error, std::fabs(error)); - - // Compute error - double const error_deriv1 = spline_eval_deriv1(ix, iy) - evaluator.deriv(x, y, 1, 0); - max_norm_error_diff1 = std::fmax(max_norm_error_diff1, std::fabs(error_deriv1)); - - // Compute error - double const error_deriv2 = spline_eval_deriv2(ix, iy) - evaluator.deriv(x, y, 0, 1); - max_norm_error_diff2 = std::fmax(max_norm_error_diff2, std::fabs(error_deriv2)); - - // Compute error - double const error_deriv12 = spline_eval_deriv12(ix, iy) - evaluator.deriv(x, y, 1, 1); - max_norm_error_diff12 = std::fmax(max_norm_error_diff12, std::fabs(error_deriv12)); - }); - - double const max_norm = evaluator.max_norm(); - double const max_norm_diff1 = evaluator.max_norm(1, 0); - double const max_norm_diff2 = evaluator.max_norm(0, 1); - double const max_norm_diff12 = evaluator.max_norm(1, 1); - - SplineErrorBounds error_bounds(evaluator); - const double h1 = (ddc::get(xN) - ddc::get(x0)) / ncells1; - const double h2 = (ddc::get(xN) - ddc::get(x0)) / ncells2; - EXPECT_LE( - max_norm_error, - std::max(error_bounds.error_bound(h1, h2, s_degree_x, s_degree_y), 1.0e-14 * max_norm)); - EXPECT_LE( - max_norm_error_diff1, - std:: - max(error_bounds.error_bound_on_deriv_1(h1, h2, s_degree_x, s_degree_y), - 1e-12 * max_norm_diff1)); - EXPECT_LE( - max_norm_error_diff2, - std:: - max(error_bounds.error_bound_on_deriv_2(h1, h2, s_degree_x, s_degree_y), - 1e-12 * max_norm_diff2)); - EXPECT_LE( - max_norm_error_diff12, - std:: - max(error_bounds.error_bound_on_deriv_12(h1, h2, s_degree_x, s_degree_y), - 1e-10 * max_norm_diff12)); -} - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - ::Kokkos::ScopeGuard kokkos_scope(argc, argv); - ::ddc::ScopeGuard ddc_scope(argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/vendor/sll/tests/CMakeLists.txt b/vendor/sll/tests/CMakeLists.txt index 774d3a653..ed891c0ad 100644 --- a/vendor/sll/tests/CMakeLists.txt +++ b/vendor/sll/tests/CMakeLists.txt @@ -5,54 +5,20 @@ include(GoogleTest) set(SLL_SPLINES_TEST_DEGREE_MIN 3 CACHE STRING "Minimum degree to test splines.") set(SLL_SPLINES_TEST_DEGREE_MAX 3 CACHE STRING "Maximum degree to test splines.") -add_executable(splines_tests_sll - main.cpp - chunk.cpp - view.cpp - gauss_legendre_integration.cpp -) -if(GYSELALIBXX_ENABLE_DEPRECATED) - target_sources(splines_tests_sll - PRIVATE - bsplines_non_uniform.cpp - bsplines_uniform.cpp - splines.cpp - ) -endif() -target_compile_features(splines_tests_sll PUBLIC cxx_std_17) -target_link_libraries(splines_tests_sll - PUBLIC - GTest::gtest - sll::splines -) -gtest_discover_tests(splines_tests_sll) add_executable(bsplines_tests_sll main.cpp - bsplines.cpp polar_bsplines.cpp ) target_compile_features(bsplines_tests_sll PUBLIC cxx_std_17) target_link_libraries(bsplines_tests_sll PUBLIC GTest::gtest - sll::splines + sll::SLL ) gtest_discover_tests(bsplines_tests_sll) -add_executable(matrix_tests_sll - main.cpp - matrix.cpp -) -target_compile_features(matrix_tests_sll PUBLIC cxx_std_17) -target_link_libraries(matrix_tests_sll - PUBLIC - GTest::gtest - sll::splines -) -gtest_discover_tests(matrix_tests_sll) - add_executable(bernstein_tests_sll main.cpp bernstein.cpp @@ -61,7 +27,7 @@ target_compile_features(bernstein_tests_sll PUBLIC cxx_std_17) target_link_libraries(bernstein_tests_sll PUBLIC GTest::gtest - sll::splines + sll::SLL ) gtest_discover_tests(bernstein_tests_sll) @@ -73,7 +39,7 @@ target_compile_features(metric_tensor_tests_sll PUBLIC cxx_std_17) target_link_libraries(metric_tensor_tests_sll PUBLIC GTest::gtest - sll::splines + sll::SLL ) gtest_discover_tests(metric_tensor_tests_sll) @@ -86,7 +52,7 @@ target_compile_features(jacobian_mapping_tests_sll PUBLIC cxx_std_17) target_link_libraries(jacobian_mapping_tests_sll PUBLIC GTest::gtest - sll::splines + sll::SLL ) gtest_discover_tests(jacobian_mapping_tests_sll) @@ -99,23 +65,11 @@ target_compile_features(jacobian_mapping_matrix_coef_tests_sll PUBLIC cxx_std_17 target_link_libraries(jacobian_mapping_matrix_coef_tests_sll PUBLIC GTest::gtest - sll::splines + sll::SLL ) gtest_discover_tests(jacobian_mapping_matrix_coef_tests_sll) -add_executable(const_extrapol_tests_sll - main.cpp - constant_extrapolation_bc.cpp -) -target_compile_features(const_extrapol_tests_sll PUBLIC cxx_std_17) -target_link_libraries(const_extrapol_tests_sll - PUBLIC - GTest::gtest - sll::splines -) -gtest_discover_tests(const_extrapol_tests_sll) - add_executable(pseudo_cartesian_tests_sll @@ -126,7 +80,7 @@ target_compile_features(pseudo_cartesian_tests_sll PUBLIC cxx_std_17) target_link_libraries(pseudo_cartesian_tests_sll PUBLIC GTest::gtest - sll::splines + sll::SLL ) gtest_discover_tests(pseudo_cartesian_tests_sll) @@ -140,109 +94,22 @@ target_compile_features(refined_discrete_mapping_test PUBLIC cxx_std_17) target_link_libraries(refined_discrete_mapping_test PUBLIC GTest::gtest - sll::splines + sll::SLL ) gtest_discover_tests(refined_discrete_mapping_test) - -foreach(DEGREE_X RANGE "${SLL_SPLINES_TEST_DEGREE_MIN}" "${SLL_SPLINES_TEST_DEGREE_MAX}") - foreach(BSPLINES_TYPE "BSPLINES_TYPE_UNIFORM" "BSPLINES_TYPE_NON_UNIFORM") - set(test_name "splines_tests_sll_DEGREE_X_${DEGREE_X}_${BSPLINES_TYPE}") - add_executable("${test_name}" periodic_spline_builder.cpp) - target_compile_features("${test_name}" PUBLIC cxx_std_17) - target_link_libraries("${test_name}" - PUBLIC - GTest::gtest - sll::splines - ) - target_compile_definitions("${test_name}" PUBLIC -DDEGREE_X=${DEGREE_X} -D${BSPLINES_TYPE}) - add_test("${test_name}" "${test_name}") - endforeach() -endforeach() - -foreach(DEGREE_X RANGE "${SLL_SPLINES_TEST_DEGREE_MIN}" "${SLL_SPLINES_TEST_DEGREE_MAX}") - set(test_name "splines_ordered_points_tests_sll_DEGREE_X_${DEGREE_X}") - add_executable("${test_name}" periodic_spline_builder_ordered_points.cpp) - target_compile_features("${test_name}" PUBLIC cxx_std_17) - target_link_libraries("${test_name}" - PUBLIC - GTest::gtest - sll::splines - ) - target_compile_definitions("${test_name}" PUBLIC -DDEGREE_X=${DEGREE_X}) - add_test("${test_name}" "${test_name}") -endforeach() - -foreach(BCL "BCL_GREVILLE" "BCL_HERMITE") - foreach(BCR "BCR_GREVILLE" "BCR_HERMITE") - foreach(EVALUATOR "EVALUATOR_COSINE" "EVALUATOR_POLYNOMIAL") - foreach(DEGREE_X RANGE "${SLL_SPLINES_TEST_DEGREE_MIN}" "${SLL_SPLINES_TEST_DEGREE_MAX}") - foreach(BSPLINES_TYPE "BSPLINES_TYPE_UNIFORM" "BSPLINES_TYPE_NON_UNIFORM") - set(test_name "splines_tests_sll_DEGREE_X_${DEGREE_X}_${BSPLINES_TYPE}_${EVALUATOR}_bcl_${BCL}_bcr_${BCR}") - add_executable("${test_name}" non_periodic_spline_builder.cpp) - target_compile_features("${test_name}" PUBLIC cxx_std_17) - target_link_libraries("${test_name}" - PUBLIC - GTest::gtest - sll::splines - ) - target_compile_definitions("${test_name}" PUBLIC -DDEGREE_X=${DEGREE_X} -D${BSPLINES_TYPE} -D${EVALUATOR} -D${BCL} -D${BCR}) - add_test("${test_name}" "${test_name}") - endforeach() - endforeach() - endforeach() - endforeach() -endforeach() - -foreach(DEGREE_X RANGE "${SLL_SPLINES_TEST_DEGREE_MIN}" "${SLL_SPLINES_TEST_DEGREE_MAX}") - foreach(DEGREE_Y RANGE "${SLL_SPLINES_TEST_DEGREE_MIN}" "${SLL_SPLINES_TEST_DEGREE_MAX}") - foreach(BSPLINES_TYPE "BSPLINES_TYPE_UNIFORM" "BSPLINES_TYPE_NON_UNIFORM") - set(test_name "2d_splines_tests_sll_DEGREE_X_${DEGREE_X}_DEGREE_Y_${DEGREE_Y}_${BSPLINES_TYPE}") - add_executable("${test_name}" 2d_spline_builder_periodic.cpp) - target_compile_features("${test_name}" PUBLIC cxx_std_17) - target_link_libraries("${test_name}" - PUBLIC - GTest::gtest - sll::splines - ) - target_compile_definitions("${test_name}" PUBLIC -DDEGREE_X=${DEGREE_X} -DDEGREE_Y=${DEGREE_Y} -D${BSPLINES_TYPE}) - add_test("${test_name}" "${test_name}") - endforeach() - endforeach() -endforeach() - -foreach(BCL "BCL_GREVILLE" "BCL_HERMITE") - foreach(BCR "BCR_GREVILLE" "BCR_HERMITE") - foreach(EVALUATOR "EVALUATOR_POLYNOMIAL") - foreach(DEGREE_X RANGE "${SLL_SPLINES_TEST_DEGREE_MIN}" "${SLL_SPLINES_TEST_DEGREE_MAX}") - foreach(DEGREE_Y RANGE "${SLL_SPLINES_TEST_DEGREE_MIN}" "${SLL_SPLINES_TEST_DEGREE_MAX}") - foreach(BSPLINES_TYPE "BSPLINES_TYPE_UNIFORM" "BSPLINES_TYPE_NON_UNIFORM") - set(test_name "2d_splines_tests_sll_DEGREE_X_${DEGREE_X}_DEGREE_Y_${DEGREE_Y}_${BSPLINES_TYPE}_${EVALUATOR}_${BCL}_${BCR}") - add_executable("${test_name}" 2d_spline_builder.cpp) - target_compile_features("${test_name}" PUBLIC cxx_std_17) - target_link_libraries("${test_name}" - PUBLIC - GTest::gtest - sll::splines - ) - target_compile_definitions("${test_name}" PUBLIC -DDEGREE_X=${DEGREE_X} -DDEGREE_Y=${DEGREE_Y} -D${BSPLINES_TYPE} -D${EVALUATOR} -D${BCL} -D${BCR}) - add_test("${test_name}" "${test_name}") - endforeach() - endforeach() - endforeach() - endforeach() - endforeach() -endforeach() - foreach(CONTINUITY RANGE -1 1) math(EXPR MIN_DEGREE "${CONTINUITY}+1") if (${MIN_DEGREE} LESS 1) set(MIN_DEGREE 1) endif() - foreach(DEGREE_R RANGE ${MIN_DEGREE} 6) - foreach(DEGREE_P RANGE ${MIN_DEGREE} 6) + if (${MIN_DEGREE} LESS ${SLL_SPLINES_TEST_DEGREE_MIN}) + set(MIN_DEGREE ${SLL_SPLINES_TEST_DEGREE_MIN}) + endif() + foreach(DEGREE_R RANGE ${MIN_DEGREE} ${SLL_SPLINES_TEST_DEGREE_MAX}) + foreach(DEGREE_P RANGE ${MIN_DEGREE} ${SLL_SPLINES_TEST_DEGREE_MAX}) foreach(BSPLINES_TYPE "BSPLINES_TYPE_UNIFORM" "BSPLINES_TYPE_NON_UNIFORM") foreach(MAPPING_TYPE "CIRCULAR_MAPPING" "CZARNY_MAPPING") set(test_name "polar_splines_tests_sll_DEGREE_R_${DEGREE_R}_DEGREE_P_${DEGREE_P}_CONTINUITY_${CONTINUITY}_${BSPLINES_TYPE}_${MAPPING_TYPE}") @@ -251,7 +118,7 @@ foreach(CONTINUITY RANGE -1 1) target_link_libraries("${test_name}" PUBLIC GTest::gtest - sll::splines + sll::SLL ) target_compile_definitions("${test_name}" PUBLIC -DDEGREE_R=${DEGREE_R} -DDEGREE_P=${DEGREE_P} -D${BSPLINES_TYPE} -DCONTINUITY=${CONTINUITY} -D${MAPPING_TYPE}) add_test("${test_name}" "${test_name}") diff --git a/vendor/sll/tests/bsplines.cpp b/vendor/sll/tests/bsplines.cpp deleted file mode 100644 index 07553945c..000000000 --- a/vendor/sll/tests/bsplines.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include - -#include - -#include -#include -#include - -#include - -#include "test_utils.hpp" - -template -struct BSplinesFixture; - -template -struct BSplinesFixture, - std::integral_constant, - std::integral_constant>> : public testing::Test -{ - struct DimX - { - static constexpr bool PERIODIC = periodic; - }; - static constexpr std::size_t spline_degree = D; - static constexpr std::size_t ncells = Nc; -}; - -using degrees = std::integer_sequence; -using ncells = std::integer_sequence; -using periodicity = std::integer_sequence; - -using Cases = tuple_to_types_t>; - -TYPED_TEST_SUITE(BSplinesFixture, Cases); - -TYPED_TEST(BSplinesFixture, PartitionOfUnity_Uniform) -{ - std::size_t constexpr degree = TestFixture::spline_degree; - using DimX = typename TestFixture::DimX; - using CoordX = ddc::Coordinate; - static constexpr CoordX xmin = CoordX(0.0); - static constexpr CoordX xmax = CoordX(0.2); - static constexpr std::size_t ncells = TestFixture::ncells; - ddc::init_discrete_space>(xmin, xmax, ncells); - - std::array vals_data; - DSpan1D values = as_span(vals_data); - - std::size_t const n_test_points = ncells * 30; - double const dx = (xmax - xmin) / (n_test_points - 1); - - for (std::size_t i(0); i < n_test_points; ++i) { - CoordX test_point(xmin + dx * i); - ddc::discrete_space>().eval_basis(values, test_point); - double sum = 0.0; - for (std::size_t j(0); j < degree + 1; ++j) { - sum += values(j); - } - EXPECT_LE(fabs(sum - 1.0), 1.0e-15); - } -} - -TYPED_TEST(BSplinesFixture, PartitionOfUnity_NonUniform) -{ - std::size_t constexpr degree = TestFixture::spline_degree; - using DimX = typename TestFixture::DimX; - using CoordX = ddc::Coordinate; - static constexpr CoordX xmin = CoordX(0.0); - static constexpr CoordX xmax = CoordX(0.2); - static constexpr std::size_t ncells = TestFixture::ncells; - std::vector breaks(ncells + 1); - double dx = (xmax - xmin) / ncells; - for (std::size_t i(0); i < ncells + 1; ++i) { - breaks[i] = CoordX(xmin + i * dx); - } - ddc::init_discrete_space>(breaks); - - std::array vals_data; - DSpan1D values = as_span(vals_data); - - std::size_t n_test_points = ncells * 30; - dx = (xmax - xmin) / (n_test_points - 1); - - for (std::size_t i(0); i < n_test_points; ++i) { - CoordX test_point(xmin + dx * i); - ddc::discrete_space>().eval_basis(values, test_point); - double sum = 0.0; - for (std::size_t j(0); j < degree + 1; ++j) { - sum += values(j); - } - EXPECT_LE(fabs(sum - 1.0), 1.0e-15); - } -} diff --git a/vendor/sll/tests/bsplines_non_uniform.cpp b/vendor/sll/tests/bsplines_non_uniform.cpp deleted file mode 100644 index f10a59bbd..000000000 --- a/vendor/sll/tests/bsplines_non_uniform.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include - -#include - -#include - -#include -#include -#include - -#include - -struct DimX -{ - static constexpr bool PERIODIC = true; -}; -using IDimX = ddc::NonUniformPointSampling; -using CoordX = ddc::Coordinate; -using IndexX = ddc::DiscreteElement; - -class BSplinesNonUniformTest : public ::testing::Test -{ -protected: - static constexpr std::size_t spline_degree = 2; - std::vector const breaks {0.0, 0.5, 1.0, 1.5, 2.0}; - NonUniformBSplines const bsplines {breaks}; - deprecated::NonUniformBSplines old_bsplines {spline_degree, DimX::PERIODIC, breaks}; -}; - -TEST_F(BSplinesNonUniformTest, Constructor) -{ - EXPECT_EQ(bsplines.degree(), spline_degree); - EXPECT_EQ(bsplines.is_periodic(), DimX::PERIODIC); - EXPECT_EQ(bsplines.rmin(), 0.); - EXPECT_EQ(bsplines.rmax(), 2.); - EXPECT_EQ(bsplines.npoints(), 5); - EXPECT_EQ(bsplines.ncells(), 4); -} - -TEST_F(BSplinesNonUniformTest, Comparison) -{ - EXPECT_EQ(bsplines.degree(), old_bsplines.degree()); - EXPECT_EQ(bsplines.is_radial(), old_bsplines.radial()); - EXPECT_EQ(bsplines.is_periodic(), old_bsplines.is_periodic()); - EXPECT_EQ(bsplines.is_uniform(), old_bsplines.is_uniform()); - EXPECT_EQ(bsplines.nbasis(), old_bsplines.nbasis()); - EXPECT_EQ(bsplines.ncells(), old_bsplines.ncells()); - EXPECT_EQ(bsplines.rmin(), old_bsplines.xmin()); - EXPECT_EQ(bsplines.rmax(), old_bsplines.xmax()); - EXPECT_EQ(bsplines.length(), old_bsplines.length()); - - std::vector values_data(bsplines.degree() + 1); - DSpan1D values(values_data.data(), values_data.size()); - int jmin; - std::vector old_values_data(old_bsplines.degree() + 1); - DSpan1D old_values(old_values_data.data(), old_values_data.size()); - int old_jmin; - - double const x = 1.07; - - bsplines.eval_basis(values, jmin, x); - old_bsplines.eval_basis(x, old_values, old_jmin); - EXPECT_EQ(jmin, old_jmin); - for (std::size_t i = 0; i < values.extent(0); ++i) { - EXPECT_EQ(values(i), old_values(i)); - } - - bsplines.eval_deriv(values, jmin, x); - old_bsplines.eval_deriv(x, old_values, old_jmin); - EXPECT_EQ(jmin, old_jmin); - for (std::size_t i = 0; i < values.extent(0); ++i) { - EXPECT_EQ(values(i), old_values(i)); - } -} diff --git a/vendor/sll/tests/bsplines_uniform.cpp b/vendor/sll/tests/bsplines_uniform.cpp deleted file mode 100644 index 30aa9ae38..000000000 --- a/vendor/sll/tests/bsplines_uniform.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include - -#include - -#include - -#include -#include -#include - -#include - -struct DimX -{ - static constexpr bool PERIODIC = true; -}; -using IDimX = ddc::UniformPointSampling; -using CoordX = ddc::Coordinate; -using IndexX = ddc::DiscreteElement; - -class BSplinesUniformTest : public ::testing::Test -{ -protected: - static constexpr std::size_t spline_degree = 2; - static constexpr std::size_t ncells = 100; - static constexpr CoordX xmin = CoordX(0.); - static constexpr CoordX xmax = CoordX(2.); - UniformBSplines const bsplines {xmin, xmax, ncells}; - deprecated::UniformBSplines const - old_bsplines {spline_degree, DimX::PERIODIC, xmin, xmax, ncells}; -}; - -TEST_F(BSplinesUniformTest, Constructor) -{ - EXPECT_EQ(bsplines.degree(), spline_degree); - EXPECT_EQ(bsplines.is_periodic(), DimX::PERIODIC); - EXPECT_EQ(bsplines.rmin(), xmin); - EXPECT_EQ(bsplines.rmax(), xmax); - EXPECT_EQ(bsplines.ncells(), ncells); -} - -TEST_F(BSplinesUniformTest, Comparison) -{ - EXPECT_EQ(bsplines.degree(), old_bsplines.degree()); - EXPECT_EQ(bsplines.is_radial(), old_bsplines.radial()); - EXPECT_EQ(bsplines.is_periodic(), old_bsplines.is_periodic()); - EXPECT_EQ(bsplines.is_uniform(), old_bsplines.is_uniform()); - EXPECT_EQ(bsplines.nbasis(), old_bsplines.nbasis()); - EXPECT_EQ(bsplines.ncells(), old_bsplines.ncells()); - EXPECT_EQ(bsplines.rmin(), old_bsplines.xmin()); - EXPECT_EQ(bsplines.rmax(), old_bsplines.xmax()); - EXPECT_EQ(bsplines.length(), old_bsplines.length()); - - std::vector values_data(bsplines.degree() + 1); - DSpan1D values(values_data.data(), values_data.size()); - int jmin; - std::vector old_values_data(old_bsplines.degree() + 1); - DSpan1D old_values(old_values_data.data(), old_values_data.size()); - int old_jmin; - - double const x = 1.07; - - bsplines.eval_basis(values, jmin, x); - old_bsplines.eval_basis(x, old_values, old_jmin); - EXPECT_EQ(jmin, old_jmin); - for (std::size_t i = 0; i < values.extent(0); ++i) { - EXPECT_EQ(values(i), old_values(i)); - } - - bsplines.eval_deriv(values, jmin, x); - old_bsplines.eval_deriv(x, old_values, old_jmin); - EXPECT_EQ(jmin, old_jmin); - for (std::size_t i = 0; i < values.extent(0); ++i) { - EXPECT_EQ(values(i), old_values(i)); - } -} diff --git a/vendor/sll/tests/chunk.cpp b/vendor/sll/tests/chunk.cpp deleted file mode 100644 index 310915103..000000000 --- a/vendor/sll/tests/chunk.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include - -#include - -#include - -#include -#include - -#include - -namespace { - -struct DimX -{ - [[maybe_unused]] static constexpr bool PERIODIC = true; -}; -struct DimY -{ - [[maybe_unused]] static constexpr bool PERIODIC = false; -}; - -using CoordX = ddc::Coordinate; -using IDimX = ddc::UniformPointSampling; -using IndexX = ddc::DiscreteElement; -using BSplinesX = UniformBSplines; - -using RCoordY = ddc::Coordinate; -using MeshY = ddc::NonUniformPointSampling; -using MCoordY = ddc::DiscreteElement; -using BSplinesY = NonUniformBSplines; - -constexpr std::size_t ncells = 100; -constexpr CoordX xmin(0.); -constexpr CoordX xmax(2.); - -} // namespace - -TEST(ChunkBSplinesTest, Constructor) -{ - ddc::init_discrete_space(xmin, xmax, ncells); - - ddc::init_discrete_space( - std::initializer_list {RCoordY(0.1), RCoordY(0.4), RCoordY(1.0)}); - - ddc::DiscreteElement start(0, 0); - ddc::DiscreteVector size(ncells, ncells); - ddc::DiscreteDomain dom(start, size); - - ddc::Chunk> chunk(dom); - auto view = chunk.span_view(); - - for (ddc::DiscreteElement ibsx : ddc::get_domain(chunk)) { - for (ddc::DiscreteElement ibsy : ddc::get_domain(chunk)) { - view(ibsx, ibsy) = 1.0; - } - } -} diff --git a/vendor/sll/tests/constant_extrapolation_bc.cpp b/vendor/sll/tests/constant_extrapolation_bc.cpp deleted file mode 100644 index 0b5420b87..000000000 --- a/vendor/sll/tests/constant_extrapolation_bc.cpp +++ /dev/null @@ -1,887 +0,0 @@ -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "test_utils.hpp" - - - -namespace { -struct DimX -{ - static bool constexpr PERIODIC = false; -}; -struct DimY -{ - static bool constexpr PERIODIC = false; -}; -struct DimR -{ - static bool constexpr PERIODIC = false; -}; - -struct DimP -{ - static bool constexpr PERIODIC = true; -}; - -int constexpr BSDegree = 3; - -// Polar dimensions -using CoordR = ddc::Coordinate; -using CoordP = ddc::Coordinate; -using CoordRP = ddc::Coordinate; - -using BSplinesR = NonUniformBSplines; -using BSplinesP = NonUniformBSplines; - -using InterpPointsR - = GrevilleInterpolationPoints; -using InterpPointsP - = GrevilleInterpolationPoints; - -using IDimR = typename InterpPointsR::interpolation_mesh_type; -using IDimP = typename InterpPointsP::interpolation_mesh_type; - -using SplineRBuilder = SplineBuilder; -using SplinePBuilder = SplineBuilder; -using SplineRPBuilder = SplineBuilder2D; - -using SplineRPEvaluator = SplineEvaluator2D; - -using BSDomainR = ddc::DiscreteDomain; -using BSDomainP = ddc::DiscreteDomain; -using BSDomainRP = ddc::DiscreteDomain; - -using IDomainR = ddc::DiscreteDomain; -using IDomainP = ddc::DiscreteDomain; -using IDomainRP = ddc::DiscreteDomain; - -using IndexR = ddc::DiscreteElement; -using IndexP = ddc::DiscreteElement; -using IndexRP = ddc::DiscreteElement; - -using IVectR = ddc::DiscreteVector; -using IVectP = ddc::DiscreteVector; -using IVectRP = ddc::DiscreteVector; - -template -using SpanR = ddc::ChunkSpan; - -template -using SpanP = ddc::ChunkSpan; - -template -using SpanRP = ddc::ChunkSpan; - -using DSpanR = SpanR; -using DSpanP = SpanP; -using DSpanRP = SpanRP; - -using IDomainRP = ddc::DiscreteDomain; - - -template -using FieldRP = ddc::Chunk; -using DFieldRP = FieldRP; - - - -// Cartesian dimensions -using CoordX = ddc::Coordinate; -using CoordY = ddc::Coordinate; -using CoordXY = ddc::Coordinate; - -using BSplinesX = NonUniformBSplines; -using BSplinesY = NonUniformBSplines; - - -auto constexpr SplineXBoundary = DimX::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; -using InterpPointsX = GrevilleInterpolationPoints; -using IDimX = typename InterpPointsX::interpolation_mesh_type; -using SplineXBuilder = SplineBuilder; - -auto constexpr SplineYBoundary = DimY::PERIODIC ? BoundCond::PERIODIC : BoundCond::GREVILLE; -using InterpPointsY = GrevilleInterpolationPoints; -using IDimY = typename InterpPointsY::interpolation_mesh_type; -using SplineYBuilder = SplineBuilder; - - -using SplineXYBuilder = SplineBuilder2D; -using SplineXYEvaluator = SplineEvaluator2D; - -using BSDomainX = ddc::DiscreteDomain; -using BSDomainY = ddc::DiscreteDomain; -using BSDomainXY = ddc::DiscreteDomain; - -using IDomainX = ddc::DiscreteDomain; -using IDomainY = ddc::DiscreteDomain; -using IDomainXY = ddc::DiscreteDomain; - -using IndexX = ddc::DiscreteElement; -using IndexY = ddc::DiscreteElement; -using IndexXY = ddc::DiscreteElement; - -using IVectX = ddc::DiscreteVector; -using IVectY = ddc::DiscreteVector; -using IVectXY = ddc::DiscreteVector; - -template -using SpanX = ddc::ChunkSpan; - -template -using SpanY = ddc::ChunkSpan; - -template -using SpanXY = ddc::ChunkSpan; - -using DSpanX = SpanX; -using DSpanY = SpanY; -using DSpanXY = SpanXY; - -using IDomainXY = ddc::DiscreteDomain; - - -template -using FieldXY = ddc::Chunk; -using DFieldXY = FieldXY; - - - -/** - * @brief Check in the polar domain if the maximum absolute value of the difference between - * the exact value and the computed value is below the tolerance error given. - * - * @param[in] function_evaluated - * The evaluated function on B-splines on a polar grid. . - * @param[in] exact_function - * The exact function PolarExactFunction type. - * @param[in] coords - * The polar coordinates of the grid used to define the discrete space. - * @param[in] outside_coords - * The polar coordinates where we evaluate the function. All points are supposed to be outside the domain. - * @param[in] TOL - * The tolerance error on the maximum absolute value of the difference between the exact value - * and the computed value. - */ -template -void check_constant_outside_domain( - DSpanRP function_evaluated, - Function& exact_function, - SpanRP coords, - SpanRP outside_coords, - double const TOL) -{ - auto r_domain = ddc::get_domain(coords); - double r_max = ddc::coordinate(r_domain.back()); - double max_err(0.0); - ddc::for_each(outside_coords.domain(), [&](IndexRP const irp) { - CoordRP coords_edge(r_max, ddc::get(outside_coords(irp))); - const double err = fabs(function_evaluated(irp) - exact_function(coords_edge)); - max_err = max_err > err ? max_err : err; - }); - EXPECT_NEAR(max_err, 0., TOL); -} - - -/** - * @brief Check in the Cartesian domain if the maximum absolute value of the difference between - * the exact value and the computed value is below the tolerance error given. - * - * @param[in] function_evaluated - * The evaluated function on B-splines on a Cartesian grid. - * @param[in] exact_function - * The exact function CartesianExactFunction type. - * @param[in] coords - * The Cartesian coordinates of the grid used to define the discrete space. - * @param[in] outside_coords - * The Cartesian coordinates where we evaluate the function. All points are supposed to be outside the domain. - * @param[in] TOL - * The tolerance error on the maximum absolute value of the difference between the exact value - * and the computed value. - */ -template -void check_constant_outside_domain( - DSpanXY function_evaluated, - Function& exact_function, - SpanXY coords, - SpanXY outside_coords, - double const TOL) -{ - auto x_domain = ddc::get_domain(coords); - auto y_domain = ddc::get_domain(coords); - const double x_max = ddc::coordinate(x_domain.back()); - const double x_min = ddc::coordinate(x_domain.front()); - const double y_max = ddc::coordinate(y_domain.back()); - const double y_min = ddc::coordinate(y_domain.front()); - double max_err(0.0); - ddc::for_each(outside_coords.domain(), [&](IndexXY const ixy) { - const double x = ddc::get(outside_coords(ixy)); - const double y = ddc::get(outside_coords(ixy)); - const double coord_x = std::max(x_min, std::min(x_max, x)); - const double coord_y = std::max(y_min, std::min(y_max, y)); - CoordXY coords_edge(coord_x, coord_y); - const double err = fabs(function_evaluated(ixy) - exact_function(coords_edge)); - max_err = max_err > err ? max_err : err; - }); - EXPECT_NEAR(max_err, 0., TOL); -} - -/** - * @brief Build a polar grid with points outside the domain. - * - * On the @f& \theta @f$ dimension, the points are not on the mesh points. - * On the @f$ r @f$ dimension, all of the points are outside the domain. - * - * @param[in] grid - * A polar grid used to define the discrete space. - * @param[out] outside_coords - * The built polar grid with points outside the domain. - */ -void build_outside_grid(IDomainRP const& grid, FieldRP& outside_coords) -{ - auto r_domain = ddc::get_domain(outside_coords); - IndexR const ir_max(r_domain.back()); - IndexR const ir_min(r_domain.front()); - - auto theta_domain = ddc::get_domain(outside_coords); - IndexP const ip_min(theta_domain.front()); - IndexP const ip_max(theta_domain.back()); - - CoordR const r_min(ddc::coordinate(ir_min)); - CoordR const r_max(ddc::coordinate(ir_max)); - - ddc::for_each(outside_coords.domain(), [&](IndexRP const irp) { - CoordR const coord_r(coordinate(ddc::select(irp))); - CoordP const coord_p(coordinate(ddc::select(irp))); - - IndexR const ir(ddc::select(irp)); - IndexP const ip(ddc::select(irp)); - - - CoordR delta_coord_r; - if (ir + 1 <= ir_max) { - delta_coord_r = ddc::coordinate(ir + 1) - ddc::coordinate(ir); - } else { - delta_coord_r = CoordR(0.); - } - - CoordP delta_coord_p; - if (ip + 1 <= ip_max) { - delta_coord_p = ddc::coordinate(ip + 1) - ddc::coordinate(ip); - } else { - delta_coord_p = ddc::coordinate(ip_min + 1) - ddc::coordinate(ip_min); - } - - outside_coords(irp) = CoordRP( - double(coord_r + delta_coord_r + (r_max - r_min)), - fmod(double(coord_p + delta_coord_p * 1.3), 2 * M_PI)); - }); -} - - -/** - * @brief Build a Cartesian grid with points outside the domain. - * - * On the @f& x @f$ and the @f$ y @f$ dimensions, all of the points are outside the domain. - * - * @param[in] grid - * A Cartesian grid used to define the discrete space. - * @param[out] outside_coords - * The built Cartesian grid with points outside the domain. - */ -void build_outside_grid(IDomainXY const& grid, FieldXY& outside_coords) -{ - auto x_domain = ddc::get_domain(outside_coords); - IndexX const ix_max(x_domain.back()); - IndexX const ix_min(x_domain.front()); - - auto theta_domain = ddc::get_domain(outside_coords); - IndexY const iy_min(theta_domain.front()); - IndexY const iy_max(theta_domain.back()); - - CoordX const x_min(ddc::coordinate(ix_min)); - CoordX const x_max(ddc::coordinate(ix_max)); - - CoordY const y_min(ddc::coordinate(iy_min)); - CoordY const y_max(ddc::coordinate(iy_max)); - - ddc::for_each(outside_coords.domain(), [&](IndexXY const ixy) { - CoordX const coord_x(coordinate(ddc::select(ixy))); - CoordY const coord_y(coordinate(ddc::select(ixy))); - - IndexX const ix(ddc::select(ixy)); - IndexY const iy(ddc::select(ixy)); - - - CoordX delta_coord_x; - if (ix + 1 <= ix_max) { - delta_coord_x = ddc::coordinate(ix + 1) - ddc::coordinate(ix); - } else { - delta_coord_x = CoordX(0.); - } - - CoordY delta_coord_y; - if (iy + 1 <= iy_max) { - delta_coord_y = ddc::coordinate(iy + 1) - ddc::coordinate(iy); - } else { - delta_coord_y = CoordY(0.); - } - - int sign_x = (coord_x >= 0) - (coord_x < 0); - int sign_y = (coord_y >= 0) - (coord_y < 0); - - outside_coords(ixy) = CoordXY( - coord_x + delta_coord_x + sign_x * (x_max - x_min) / 6., - coord_y + delta_coord_y + sign_y * (y_max - y_min) / 6.); - - double const outside_x = ddc::get(outside_coords(ixy)); - double const outside_y = ddc::get(outside_coords(ixy)); - - // If the outside_coord is inside the domain, it is put outside the domain: - if ((outside_x <= x_max) and (outside_x >= x_min) and (outside_y <= y_max) - and (outside_y >= y_min)) { - sign_x = (outside_x >= 0) - (outside_x < 0); - sign_y = (outside_y >= 0) - (outside_y < 0); - int const sign_xy = (sign_x * sign_y >= 0) - (sign_x * sign_y < 0); - outside_coords(ixy) = outside_coords(ixy) - + CoordXY( - -sign_xy * sign_x * (x_max - x_min) * 1 / 3., - +sign_xy * sign_y * (y_max - y_min) * 1 / 3.); - } - }); -} - -/** - * @brief Evaluate a function on B-splines and compare the obtained values with the exact values. - * - * We build another grid with points outside the domain and evaluate the function on B-splines on the grid. - * If the point is outside the domain, we expect that the value of the function will be the same - * than the value of the exact function at the edge of the domain. - * - * @param[in] grid - * The polar grid used to define the discrete domain. - * @param[in] exact_function - * A function PolarExactFunction type. - * @param[in] TOL - * The tolerance error on the maximum absolute value of the difference between the exact value - * and the computed value. - */ -template -void Evaluate_on_outside_coord(IDomainRP const& grid, Function& exact_function, double const TOL) -{ - // Coordinates on the grid. -------------------------------------------------------------- - FieldRP coords(grid); - ddc::for_each(grid, [&](IndexRP const irp) { coords(irp) = ddc::coordinate(irp); }); - - - // Build the decomposition of the function on B-splines. --------------------------------- - SplineRPBuilder const builder(grid); - ddc::Chunk function_coefs(builder.spline_domain()); - DFieldRP function_evaluated(grid); - ddc::for_each(grid, [&](IndexRP const irp) { - function_evaluated(irp) = exact_function(coords(irp)); - }); - builder(function_coefs, function_evaluated); - - - // Build a "outside" grid to test the evaluator. ------------------------------------------ - IDomainRP outside_grid(grid); - FieldRP outside_coords(outside_grid); - build_outside_grid(grid, outside_coords); - - - // Evaluate the function on B-splines on the "outside" grid. ------------------------------ - auto r_domain = ddc::get_domain(outside_coords); - CoordR const r_min(ddc::coordinate(r_domain.front())); - CoordR const r_max(ddc::coordinate(r_domain.back())); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_left( - r_min); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_right( - r_max); - - SplineRPEvaluator spline_evaluator( - boundary_condition_r_left, - boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d); - - spline_evaluator(function_evaluated.span_view(), outside_coords.span_cview(), function_coefs); - - - // Compare the obtained values with the exact function. ---------------------------------- - check_constant_outside_domain(function_evaluated, exact_function, coords, outside_coords, TOL); -} - - - -/** @brief Evaluate a function on B-splines and compare the obtained values with the exact values. -* -* We build another grid with points outside the domain and evaluate the function on B-splines on the grid. -* If the point is outside the domain, we expect that the value of the function will be the same -* than the value of the exact function at the edge of the domain. -* -* @param[in] grid -* The Cartesian grid used to define the discrete domain. -* @param[in] exact_function -* A function CartesianExactFunction type. -* @param[in] TOL -* The tolerance error on the maximum absolute value of the difference between the exact value -* and the computed value. -*/ -template -void Evaluate_on_outside_coord(IDomainXY const& grid, Function& exact_function, double const TOL) -{ - // Coordinates on the grid. -------------------------------------------------------------- - FieldXY coords(grid); - ddc::for_each(grid, [&](IndexXY const ixy) { - CoordXY coord(ddc::coordinate(ixy)); - coords(ixy) = coord; - }); - - - // Build the decomposition of the function on B-splines. --------------------------------- - SplineXYBuilder const builder(grid); - ddc::Chunk function_coefs(builder.spline_domain()); - DFieldXY function_evaluated(grid); - ddc::for_each(grid, [&](IndexXY const ixy) { - CoordXY coord = coords(ixy); - function_evaluated(ixy) = exact_function(coord); - }); - builder(function_coefs, function_evaluated); - - - // Build a "outside" grid to test the evaluator. ------------------------------------------ - IDomainXY outside_grid(grid); - FieldXY outside_coords(outside_grid); - build_outside_grid(grid, outside_coords); - - - // Evaluate the function on B-splines on the "outside" grid. ------------------------------ - auto x_domain = ddc::get_domain(outside_coords); - CoordX const x_min(ddc::coordinate(x_domain.front())); - CoordX const x_max(ddc::coordinate(x_domain.back())); - auto y_domain = ddc::get_domain(outside_coords); - CoordY const y_min(ddc::coordinate(y_domain.front())); - CoordY const y_max(ddc::coordinate(y_domain.back())); - ConstantExtrapolationBoundaryValue2D - boundary_condition_x_left(x_min, y_min, y_max); - ConstantExtrapolationBoundaryValue2D - boundary_condition_x_right(x_max, y_min, y_max); - ConstantExtrapolationBoundaryValue2D - boundary_condition_y_left(y_min, x_min, x_max); - ConstantExtrapolationBoundaryValue2D - boundary_condition_y_right(y_max, x_min, x_max); - - SplineXYEvaluator spline_evaluator( - boundary_condition_x_left, - boundary_condition_x_right, - boundary_condition_y_left, - boundary_condition_y_right); - - spline_evaluator(function_evaluated.span_view(), outside_coords.span_cview(), function_coefs); - - - // Compare the obtained values with the exact function. ---------------------------------- - check_constant_outside_domain(function_evaluated, exact_function, coords, outside_coords, TOL); -} - - - -/** - * @brief A class to define exact function in the polar domain. - */ -class PolarExactFunction -{ -public: - /** - * @brief Instantiate a exact function in the polar domain. - */ - virtual ~PolarExactFunction() = default; - - /** - * @brief Get the value of the function at the coordinate point. - * - * @param[in] coord - * The coordinate point in the polar domain. - * - * @return The value of the function at the coordinate point which is by default 0. - */ - virtual double operator()(CoordRP const& coord) - { - return 0.0; - }; -}; - -/** - * @brief A class for functions of type @f$ (r, theta) \mapsto r^{d_r}\cos^{d_c}(\theta) \sin^{d_s}(\theta)@f$. - */ -class PolarExactFunction_r_theta_cos_sin : public PolarExactFunction -{ -private: - int const m_d_r; - int const m_d_cos; - int const m_d_sin; - -public: - /** - * @brief Instantiate a type @f$ (r, theta) \mapsto r^{d_r}\cos^{d_c}(\theta) \sin^{d_s}(\theta)@f$. - * - * @param[in] d_r - * The degree of the r. - * @param[in] d_cos - * The degree of the cosine. - * @param[in] d_sin - * The degree of the sine. - */ - PolarExactFunction_r_theta_cos_sin(int const d_r, int const d_cos, int const d_sin) - : m_d_r(d_r) - , m_d_cos(d_cos) - , m_d_sin(d_sin) {}; - ~PolarExactFunction_r_theta_cos_sin() {}; - - /** - * @brief Get the value of the function at the coordinate point. - * - * @param[in] coord - * The coordinate point in the polar domain. - * - * @return The value of the function at the coordinate point. - */ - double operator()(CoordRP const& coord) override - { - const double r = ddc::get(coord); - const double t = ddc::get(coord); - double val_r = 1.0; - double val_cos = 1.0; - double val_sin = 1.0; - for (int i(0); i < m_d_r; i++) - val_r *= r; - for (int i(0); i < m_d_cos; i++) - val_cos *= std::cos(t); - for (int i(0); i < m_d_sin; i++) - val_sin *= std::sin(t); - return val_r * val_cos * val_sin; - } -}; - - -/** - * @brief A class for functions of type @f$ (r, theta) \mapsto r*\cos^{d_c}(n\theta)@f$. - */ -class PolarExactFunction_r_cos_theta_pulsation : public PolarExactFunction -{ -private: - int const m_d_cos; - int const m_n; - -public: - /** - * @brief Instantiate a type @f$ (r, theta) \mapsto r*\cos^{d_c}(n\theta)@f$. - * - * @param[in] d_cos - * The degree of the cosine. - * @param[in] n - * The number of oscillations. - */ - PolarExactFunction_r_cos_theta_pulsation(int const d_cos, double const n) - : m_d_cos(d_cos) - , m_n(n) {}; - ~PolarExactFunction_r_cos_theta_pulsation() {}; - - /** - * @brief Get the value of the function at the coordinate point. - * - * @param[in] coord - * The coordinate point in the polar domain. - * - * @return The value of the function at the coordinate point. - */ - double operator()(CoordRP const& coord) override - { - const double r = ddc::get(coord); - const double t = ddc::get(coord); - double val_cos = 1.0; - for (int i(0); i < m_d_cos; i++) - val_cos *= std::cos(t * m_n); - return r * val_cos; - } -}; - - - -/** - * @brief A class to define exact function in the Cartesian domain. - */ -class CartesianExactFunction -{ -public: - /** - * @brief Instantiate a exact function in the Cartesian domain. - */ - virtual ~CartesianExactFunction() = default; - - /** - * @brief Get the value of the function at the coordinate point. - * - * @param[in] coord - * The coordinate point in the Cartesian domain. - * - * @return The value of the function at the coordinate point which is by default 0. - */ - virtual double operator()(CoordXY const& coord) - { - return 0.0; - }; -}; - - -/** - * @brief A class to define exact function in the cartesian domain of type - * @f$ (x,y) \mapsto \cos^{d_x}(n_x x)\sin^{d_y}(n_y y)@f$. - */ -class CartesianExactFunction_cos_x_sin_y : public CartesianExactFunction -{ -private: - int const m_d_x; - double const m_n_x; - int const m_d_y; - double const m_n_y; - -public: - /** - * @brief Instantiate a exact function in the cartesian domain of type - * @f$ (x,y) \mapsto \cos^{d_x}(n_x x)\sin^{d_y}(n_y y)@f$. - * - * @param[in] d_x - * The degree of the x-cosine. - * @param[in] n_x - * The number of oscillantion in the x direction. - * @param[in] d_y - * The degree of the y-sine. - * @param[in] n_y - * The number of oscillantion in the y direction. - */ - CartesianExactFunction_cos_x_sin_y( - int const d_x, - double const n_x, - int const d_y, - double const n_y) - : m_d_x(d_x) - , m_n_x(n_x) - , m_d_y(d_y) - , m_n_y(n_y) {}; - ~CartesianExactFunction_cos_x_sin_y() {}; - - /** - * @brief Get the value of the function at the coordinate point. - * - * @param[in] coord - * The coordinate point in the cartesian domain. - * - * @return The value of the function at the coordinate point. - */ - double operator()(CoordXY const& coord) - { - const double x = ddc::get(coord); - const double y = ddc::get(coord); - double val_cos = 1.0; - double val_sin = 1.0; - for (int i(0); i < m_d_x; i++) - val_cos *= std::cos(x * m_n_x); - for (int i(0); i < m_d_y; i++) - val_sin *= std::sin(y * m_n_y); - return val_cos * val_sin; - }; -}; - - - -} // end namespace - - - -/** - * @brief A class for the Google tests. - */ -class ConstantExtrapolationBCEvaluator2D - : public testing::TestWithParam> -{ -}; - - -namespace fs = std::filesystem; - -TEST_P(ConstantExtrapolationBCEvaluator2D, PolarDomain) -{ - // INITIALISATION OF THE DISCRETE SPACE ================================================== - // Parameters of the grid. --------------------------------------------------------------- - auto const [Nr, Nt] = GetParam(); - - // Grid creation (uniform grid). ---------------------------------------------------------- - CoordR const r_min(0.0); - CoordR const r_max(1.0); - IVectR const r_size(Nr); - - CoordP const p_min(0.0); - CoordP const p_max(2.0 * M_PI); - IVectP const p_size(Nt); - - double const dr((r_max - r_min) / r_size); - double const dp((p_max - p_min) / p_size); - - std::vector r_knots(r_size + 1); - std::vector p_knots(p_size + 1); - - for (int i(0); i < r_size; ++i) { - r_knots[i] = CoordR(r_min + i * dr); - } - r_knots[r_size] = CoordR(r_max); - for (int i(0); i < p_size + 1; ++i) { - p_knots[i] = CoordP(p_min + i * dp); - } - - - // Creating mesh & supports - ddc::init_discrete_space(r_knots); - ddc::init_discrete_space(p_knots); - - ddc::init_discrete_space(InterpPointsR::get_sampling()); - ddc::init_discrete_space(InterpPointsP::get_sampling()); - - IDomainR interpolation_domain_R(InterpPointsR::get_domain()); - IDomainP interpolation_domain_P(InterpPointsP::get_domain()); - IDomainRP grid(interpolation_domain_R, interpolation_domain_P); - - - - // TESTS ON THE DISCRETE SPACE =========================================================== - const int spline_degree = BSplinesR::degree(); - std::cout << "Test constant extrapolation as boundary conditions for evaluator 2D with " - "Bsplines " - << "of degree " << spline_degree << " on r " - << "and degree " << BSplinesP::degree() << " on theta" - << " on a grid of " << Nr << " x " << Nt << "." << std::endl; - - // r-polynomials functions: - for (int degree(std::max(spline_degree - 3, 0)); degree <= spline_degree + 3; degree++) { - PolarExactFunction_r_theta_cos_sin exact_function_Rd(degree, 0, 0); - Evaluate_on_outside_coord(grid, exact_function_Rd, 1e-15); - } - - // r*cosine function: - PolarExactFunction_r_theta_cos_sin exact_function_r_theta_cos(1, 1, 0); - Evaluate_on_outside_coord(grid, exact_function_r_theta_cos, 1e-7); - - // r*sine function: - PolarExactFunction_r_theta_cos_sin exact_function_r_theta_sin(1, 0, 1); - Evaluate_on_outside_coord(grid, exact_function_r_theta_sin, 1e-7); - - // r *squared cosine function: - PolarExactFunction_r_theta_cos_sin exact_function_r_theta_cos2(1, 2, 0); - Evaluate_on_outside_coord(grid, exact_function_r_theta_cos2, 1e-6); - - // r *squared cosine function: - PolarExactFunction_r_theta_cos_sin exact_function_r_theta_sin2(1, 0, 2); - Evaluate_on_outside_coord(grid, exact_function_r_theta_sin2, 1e-6); - - // very oscillating r *squared cosine function: - PolarExactFunction_r_cos_theta_pulsation exact_function_r_cos_pul(1, 10); - Evaluate_on_outside_coord(grid, exact_function_r_cos_pul, 1e-3); -} - - - -TEST_P(ConstantExtrapolationBCEvaluator2D, CartesianDomain) -{ - // INITIALISATION OF THE DISCRETE SPACE ================================================== - // Parameters of the grid. --------------------------------------------------------------- - auto const [Nx, Ny] = GetParam(); - - // Grid creation (uniform grid). ---------------------------------------------------------- - CoordX const x_min(-1.0); - CoordX const x_max(1.0); - IVectX const x_size(Nx); - - CoordY const y_min(-1.0); - CoordY const y_max(1.0); - IVectY const y_size(Ny); - - double const dx((x_max - x_min) / x_size); - double const dy((y_max - y_min) / y_size); - - std::vector x_knots(x_size + 1); - std::vector y_knots(y_size + 1); - - for (int i(0); i < x_size; ++i) { - x_knots[i] = CoordX(x_min + i * dx); - } - x_knots[x_size] = CoordX(x_max); - - for (int i(0); i < y_size; ++i) { - y_knots[i] = CoordY(y_min + i * dy); - } - y_knots[y_size] = CoordY(y_max); - - - // Creating mesh & supports - ddc::init_discrete_space(x_knots); - ddc::init_discrete_space(y_knots); - - ddc::init_discrete_space(InterpPointsX::get_sampling()); - ddc::init_discrete_space(InterpPointsY::get_sampling()); - - IDomainX interpolation_domain_X(InterpPointsX::get_domain()); - IDomainY interpolation_domain_Y(InterpPointsY::get_domain()); - IDomainXY grid(interpolation_domain_X, interpolation_domain_Y); - - - - // TESTS ON THE DISCRETE SPACE =========================================================== - const int spline_degree_x = BSplinesX::degree(); - const int spline_degree_y = BSplinesY::degree(); - std::cout << "Test constant extrapolation as boundary conditions for evaluator 2D with " - "Bsplines " - << "of degree " << spline_degree_x << " on x " - << "and degree " << spline_degree_y << " on y" - << " on a grid of " << Nx << " x " << Ny << "." << std::endl; - - // Cosine x function: - CartesianExactFunction_cos_x_sin_y exact_function_cos_x(1, 1, 0, 0); - Evaluate_on_outside_coord(grid, exact_function_cos_x, 1e-7); - - // Sine y function: - CartesianExactFunction_cos_x_sin_y exact_function_sin_y(0, 0, 1, 1); - Evaluate_on_outside_coord(grid, exact_function_sin_y, 1e-7); - - - // Cosine x sine y function: - CartesianExactFunction_cos_x_sin_y exact_function_cos_x_sin_y(1, 1, 1, 1); - Evaluate_on_outside_coord(grid, exact_function_cos_x_sin_y, 1e-7); - - // Very oscillating cosine x sine y function: - CartesianExactFunction_cos_x_sin_y exact_function_cos_x_sin_y_osc(1, 10, 1, 10); - Evaluate_on_outside_coord(grid, exact_function_cos_x_sin_y_osc, 1e-4); -} - - - -INSTANTIATE_TEST_SUITE_P( - MyGroup, - ConstantExtrapolationBCEvaluator2D, - testing::Combine(testing::Values(40), testing::Values(80))); diff --git a/vendor/sll/tests/mapping_jacobian.cpp b/vendor/sll/tests/mapping_jacobian.cpp index eb93466ca..9fede5a6f 100644 --- a/vendor/sll/tests/mapping_jacobian.cpp +++ b/vendor/sll/tests/mapping_jacobian.cpp @@ -3,10 +3,6 @@ #include -#include -#include -#include - #include "sll/mapping/analytical_invertible_curvilinear2d_to_cartesian.hpp" #include "sll/mapping/circular_to_cartesian.hpp" #include "sll/mapping/curvilinear2d_to_cartesian.hpp" @@ -40,20 +36,45 @@ using CoordRP = ddc::Coordinate; int constexpr BSDegree = 3; -using BSplinesR = NonUniformBSplines; -using BSplinesP = NonUniformBSplines; +using BSplinesR = ddc::NonUniformBSplines; +using BSplinesP = ddc::NonUniformBSplines; -using InterpPointsR - = GrevilleInterpolationPoints; -using InterpPointsP - = GrevilleInterpolationPoints; +using InterpPointsR = ddc:: + GrevilleInterpolationPoints; +using InterpPointsP = ddc:: + GrevilleInterpolationPoints; using IDimR = typename InterpPointsR::interpolation_mesh_type; using IDimP = typename InterpPointsP::interpolation_mesh_type; -using SplineRBuilder = SplineBuilder; -using SplinePBuilder = SplineBuilder; -using SplineRPBuilder = SplineBuilder2D; +using SplineRPBuilder = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimR, + IDimP>; + +using SplineRPEvaluator = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::NullExtrapolationRule, + ddc::NullExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; using BSDomainR = ddc::DiscreteDomain; using BSDomainP = ddc::DiscreteDomain; @@ -241,13 +262,15 @@ TEST_P(InverseJacobianMatrix, InverseMatrixDiscCzarMap) IDomainRP grid(interpolation_domain_R, interpolation_domain_P); SplineRPBuilder builder(grid); - SplineEvaluator2D evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); - DiscreteToCartesian mapping - = DiscreteToCartesian:: + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluator evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); + DiscreteToCartesian mapping + = DiscreteToCartesian:: analytical_to_discrete(analytical_mapping, builder, evaluator); // Test for each coordinates if the inv_Jacobian_matrix is the inverse of the Jacobian_matrix diff --git a/vendor/sll/tests/mapping_jacobian_matrix_coef.cpp b/vendor/sll/tests/mapping_jacobian_matrix_coef.cpp index 55dcbb70b..ea735b953 100644 --- a/vendor/sll/tests/mapping_jacobian_matrix_coef.cpp +++ b/vendor/sll/tests/mapping_jacobian_matrix_coef.cpp @@ -3,12 +3,6 @@ #include -#include -#include -#include -#include -#include - #include "sll/mapping/analytical_invertible_curvilinear2d_to_cartesian.hpp" #include "sll/mapping/circular_to_cartesian.hpp" #include "sll/mapping/curvilinear2d_to_cartesian.hpp" @@ -42,20 +36,45 @@ using CoordRP = ddc::Coordinate; int constexpr BSDegree = 3; -using BSplinesR = NonUniformBSplines; -using BSplinesP = NonUniformBSplines; +using BSplinesR = ddc::NonUniformBSplines; +using BSplinesP = ddc::NonUniformBSplines; -using InterpPointsR - = GrevilleInterpolationPoints; -using InterpPointsP - = GrevilleInterpolationPoints; +using InterpPointsR = ddc:: + GrevilleInterpolationPoints; +using InterpPointsP = ddc:: + GrevilleInterpolationPoints; using IDimR = typename InterpPointsR::interpolation_mesh_type; using IDimP = typename InterpPointsP::interpolation_mesh_type; -using SplineRBuilder = SplineBuilder; -using SplinePBuilder = SplineBuilder; -using SplineRPBuilder = SplineBuilder2D; +using SplineRPBuilder = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimR, + IDimP>; + +using SplineRPEvaluator = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::NullExtrapolationRule, + ddc::NullExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; using BSDomainR = ddc::DiscreteDomain; using BSDomainP = ddc::DiscreteDomain; @@ -283,13 +302,15 @@ TEST_P(JacobianMatrixAndJacobianCoefficients, MatrixDiscCzarMap) IDomainRP grid(interpolation_domain_R, interpolation_domain_P); SplineRPBuilder builder(grid); - SplineEvaluator2D evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); - DiscreteToCartesian mapping - = DiscreteToCartesian:: + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluator evaluator( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); + DiscreteToCartesian mapping + = DiscreteToCartesian:: analytical_to_discrete(analytical_mapping, builder, evaluator); // Test for each coordinates if the coefficients defined by the coefficients functions diff --git a/vendor/sll/tests/metric_tensor.cpp b/vendor/sll/tests/metric_tensor.cpp index 3ff235433..1990ecc19 100644 --- a/vendor/sll/tests/metric_tensor.cpp +++ b/vendor/sll/tests/metric_tensor.cpp @@ -1,6 +1,4 @@ /// Test of the metric tensor and its inverse: (singular point avoided) -#include -#include #include #include "sll/mapping/circular_to_cartesian.hpp" @@ -32,14 +30,14 @@ using CoordRP = ddc::Coordinate; int constexpr BSDegree = 3; -using BSplinesR = NonUniformBSplines; -using BSplinesP = NonUniformBSplines; +using BSplinesR = ddc::NonUniformBSplines; +using BSplinesP = ddc::NonUniformBSplines; using PolarBSplinesRP = PolarBSplines; -using InterpPointsR - = GrevilleInterpolationPoints; -using InterpPointsP - = GrevilleInterpolationPoints; +using InterpPointsR = ddc:: + GrevilleInterpolationPoints; +using InterpPointsP = ddc:: + GrevilleInterpolationPoints; using IDimR = typename InterpPointsR::interpolation_mesh_type; using IDimP = typename InterpPointsP::interpolation_mesh_type; diff --git a/vendor/sll/tests/non_periodic_spline_builder.cpp b/vendor/sll/tests/non_periodic_spline_builder.cpp deleted file mode 100644 index 560a940b8..000000000 --- a/vendor/sll/tests/non_periodic_spline_builder.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "cosine_evaluator.hpp" -#include "polynomial_evaluator.hpp" -#include "spline_error_bounds.hpp" - -struct DimX -{ - static constexpr bool PERIODIC = false; -}; - -static constexpr std::size_t s_degree_x = DEGREE_X; - -#if defined(BCL_GREVILLE) -static constexpr BoundCond s_bcl = BoundCond::GREVILLE; -#elif defined(BCL_HERMITE) -static constexpr BoundCond s_bcl = BoundCond::HERMITE; -#endif - -#if defined(BCR_GREVILLE) -static constexpr BoundCond s_bcr = BoundCond::GREVILLE; -#elif defined(BCR_HERMITE) -static constexpr BoundCond s_bcr = BoundCond::HERMITE; -#endif - -#if defined(BSPLINES_TYPE_UNIFORM) -using BSplinesX = UniformBSplines; -#elif defined(BSPLINES_TYPE_NON_UNIFORM) -using BSplinesX = NonUniformBSplines; -#endif - -using GrevillePoints = GrevilleInterpolationPoints; - -using IDimX = GrevillePoints::interpolation_mesh_type; - -#if defined(EVALUATOR_COSINE) -using evaluator_type = CosineEvaluator::Evaluator; -#elif defined(EVALUATOR_POLYNOMIAL) -using evaluator_type = PolynomialEvaluator::Evaluator; -#endif - -using IndexX = ddc::DiscreteElement; -using DVectX = ddc::DiscreteVector; -using BsplIndexX = ddc::DiscreteElement; -using SplineX = ddc::Chunk>; -using FieldX = ddc::Chunk>; -using CoordX = ddc::Coordinate; - -// Checks that when evaluating the spline at interpolation points one -// recovers values that were used to build the spline -TEST(NonPeriodicSplineBuilderTest, Identity) -{ - CoordX constexpr x0(0.); - CoordX constexpr xN(1.); - std::size_t constexpr ncells = 100; - - // 1. Create BSplines - { -#if defined(BSPLINES_TYPE_UNIFORM) - ddc::init_discrete_space(x0, xN, ncells); -#elif defined(BSPLINES_TYPE_NON_UNIFORM) - DVectX constexpr npoints(ncells + 1); - std::vector breaks(npoints); - double dx = (xN - x0) / ncells; - for (int i(0); i < npoints; ++i) { - breaks[i] = CoordX(x0 + i * dx); - } - ddc::init_discrete_space(breaks); -#endif - } - ddc::DiscreteDomain const dom_bsplines_x( - ddc::discrete_space().full_domain()); - - // 2. Create a Spline represented by a chunk over BSplines - // The chunk is filled with garbage data, we need to initialize it - SplineX coef(dom_bsplines_x); - - // 3. Create the interpolation domain - ddc::init_discrete_space(GrevillePoints::get_sampling()); - ddc::DiscreteDomain interpolation_domain(GrevillePoints::get_domain()); - - // 4. Create a SplineBuilder over BSplines using some boundary conditions - SplineBuilder spline_builder(interpolation_domain); - - // 5. Allocate and fill a chunk over the interpolation domain - FieldX yvals(interpolation_domain); - evaluator_type evaluator(interpolation_domain); - evaluator(yvals.span_view()); - - int constexpr shift = s_degree_x % 2; // shift = 0 for even order, 1 for odd order - std::array Sderiv_lhs_data; - DSpan1D Sderiv_lhs(Sderiv_lhs_data.data(), Sderiv_lhs_data.size()); - std::optional deriv_l; - if (s_bcl == BoundCond::HERMITE) { - for (std::size_t ii = 0; ii < Sderiv_lhs.extent(0); ++ii) { - Sderiv_lhs(ii) = evaluator.deriv(x0, ii + shift); - } - deriv_l = Sderiv_lhs; - } - - std::array Sderiv_rhs_data; - DSpan1D Sderiv_rhs(Sderiv_rhs_data.data(), Sderiv_rhs_data.size()); - std::optional deriv_r; - if (s_bcr == BoundCond::HERMITE) { - for (std::size_t ii = 0; ii < Sderiv_rhs.extent(0); ++ii) { - Sderiv_rhs(ii) = evaluator.deriv(xN, ii + shift); - } - deriv_r = Sderiv_rhs; - } - - // 6. Finally build the spline by filling `coef` - spline_builder(coef, yvals, deriv_l, deriv_r); - - // 7. Create a SplineEvaluator to evaluate the spline at any point in the domain of the BSplines - SplineEvaluator - spline_evaluator(g_null_boundary, g_null_boundary); - - ddc::Chunk, ddc::DiscreteDomain> coords_eval(interpolation_domain); - for (IndexX const ix : interpolation_domain) { - coords_eval(ix) = ddc::coordinate(ix); - } - - FieldX spline_eval(interpolation_domain); - spline_evaluator(spline_eval.span_view(), coords_eval.span_cview(), coef.span_cview()); - - FieldX spline_eval_deriv(interpolation_domain); - spline_evaluator - .deriv(spline_eval_deriv.span_view(), coords_eval.span_cview(), coef.span_cview()); - - // 8. Checking errors - double max_norm_error = 0.; - double max_norm_error_diff = 0.; - for (IndexX const ix : interpolation_domain) { - CoordX const x = ddc::coordinate(ix); - - // Compute error - double const error = spline_eval(ix) - yvals(ix); - max_norm_error = std::fmax(max_norm_error, std::fabs(error)); - - // Compute error - double const error_deriv = spline_eval_deriv(ix) - evaluator.deriv(x, 1); - max_norm_error_diff = std::fmax(max_norm_error_diff, std::fabs(error_deriv)); - } - double const max_norm_error_integ = std::fabs( - spline_evaluator.integrate(coef.span_cview()) - evaluator.deriv(xN, -1) - + evaluator.deriv(x0, -1)); - double const max_norm = evaluator.max_norm(); - double const max_norm_diff = evaluator.max_norm(1); - double const max_norm_int = evaluator.max_norm(-1); - if constexpr (std::is_same_v< - evaluator_type, - PolynomialEvaluator::Evaluator>) { - EXPECT_LE(max_norm_error / max_norm, 1.0e-14); - EXPECT_LE(max_norm_error_diff / max_norm_diff, 1.0e-12); - EXPECT_LE(max_norm_error_integ / max_norm_int, 1.0e-14); - } else { - SplineErrorBounds error_bounds(evaluator); - const double h = (xN - x0) / ncells; - EXPECT_LE( - max_norm_error, - std::max(error_bounds.error_bound(h, s_degree_x), 1.0e-14 * max_norm)); - EXPECT_LE( - max_norm_error_diff, - std::max(error_bounds.error_bound_on_deriv(h, s_degree_x), 1e-12 * max_norm_diff)); - EXPECT_LE( - max_norm_error_integ, - std::max(error_bounds.error_bound_on_int(h, s_degree_x), 1.0e-14 * max_norm_int)); - } -} - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - ::Kokkos::ScopeGuard kokkos_scope(argc, argv); - ::ddc::ScopeGuard ddc_scope(argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/vendor/sll/tests/periodic_spline_builder.cpp b/vendor/sll/tests/periodic_spline_builder.cpp deleted file mode 100644 index c27d30f2b..000000000 --- a/vendor/sll/tests/periodic_spline_builder.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "cosine_evaluator.hpp" -#include "polynomial_evaluator.hpp" -#include "spline_error_bounds.hpp" - -struct DimX -{ - static constexpr bool PERIODIC = true; -}; - -static constexpr std::size_t s_degree_x = DEGREE_X; - -#if defined(BSPLINES_TYPE_UNIFORM) -using BSplinesX = UniformBSplines; -#elif defined(BSPLINES_TYPE_NON_UNIFORM) -using BSplinesX = NonUniformBSplines; -#endif - -using GrevillePoints - = GrevilleInterpolationPoints; - -using IDimX = GrevillePoints::interpolation_mesh_type; - -using evaluator_type = CosineEvaluator::Evaluator; - -using IndexX = ddc::DiscreteElement; -using DVectX = ddc::DiscreteVector; -using BsplIndexX = ddc::DiscreteElement; -using SplineX = ddc::Chunk>; -using FieldX = ddc::Chunk>; -using CoordX = ddc::Coordinate; - -// Checks that when evaluating the spline at interpolation points one -// recovers values that were used to build the spline -TEST(PeriodicSplineBuilderTest, Identity) -{ - CoordX constexpr x0(0.); - CoordX constexpr xN(1.); - std::size_t constexpr ncells = 10; - - // 1. Create BSplines - { -#if defined(BSPLINES_TYPE_UNIFORM) - ddc::init_discrete_space(x0, xN, ncells); -#elif defined(BSPLINES_TYPE_NON_UNIFORM) - DVectX constexpr npoints(ncells + 1); - std::vector breaks(npoints); - double dx = (xN - x0) / ncells; - for (int i(0); i < npoints; ++i) { - breaks[i] = CoordX(x0 + i * dx); - } - ddc::init_discrete_space(breaks); -#endif - } - ddc::DiscreteDomain const dom_bsplines_x( - ddc::discrete_space().full_domain()); - - // 2. Create a Spline represented by a chunk over BSplines - // The chunk is filled with garbage data, we need to initialize it - SplineX coef(dom_bsplines_x); - - // 3. Create the interpolation domain - ddc::init_discrete_space(GrevillePoints::get_sampling()); - ddc::DiscreteDomain interpolation_domain(GrevillePoints::get_domain()); - - // 4. Create a SplineBuilder over BSplines using some boundary conditions - SplineBuilder spline_builder( - interpolation_domain); - - // 5. Allocate and fill a chunk over the interpolation domain - FieldX yvals(interpolation_domain); - evaluator_type evaluator(interpolation_domain); - evaluator(yvals); - - // 6. Finally build the spline by filling `coef` - spline_builder(coef, yvals); - - // 7. Create a SplineEvaluator to evaluate the spline at any point in the domain of the BSplines - SplineEvaluator - spline_evaluator(g_null_boundary, g_null_boundary); - - ddc::Chunk> coords_eval(interpolation_domain); - for (IndexX const ix : interpolation_domain) { - coords_eval(ix) = ddc::coordinate(ix); - } - - FieldX spline_eval(interpolation_domain); - spline_evaluator(spline_eval.span_view(), coords_eval.span_cview(), coef.span_cview()); - - FieldX spline_eval_deriv(interpolation_domain); - spline_evaluator - .deriv(spline_eval_deriv.span_view(), coords_eval.span_cview(), coef.span_cview()); - - // 8. Checking errors - double max_norm_error = 0.; - double max_norm_error_diff = 0.; - for (IndexX const ix : interpolation_domain) { - CoordX const x = ddc::coordinate(ix); - - // Compute error - double const error = spline_eval(ix) - yvals(ix); - max_norm_error = std::fmax(max_norm_error, std::fabs(error)); - - // Compute error - double const error_deriv = spline_eval_deriv(ix) - evaluator.deriv(x, 1); - max_norm_error_diff = std::fmax(max_norm_error_diff, std::fabs(error_deriv)); - } - double const max_norm_error_integ = std::fabs( - spline_evaluator.integrate(coef.span_cview()) - evaluator.deriv(xN, -1) - + evaluator.deriv(x0, -1)); - - double const max_norm = evaluator.max_norm(); - double const max_norm_diff = evaluator.max_norm(1); - double const max_norm_int = evaluator.max_norm(-1); - - SplineErrorBounds error_bounds(evaluator); - const double h = (xN - x0) / ncells; - EXPECT_LE( - max_norm_error, - std::max(error_bounds.error_bound(h, s_degree_x), 1.0e-14 * max_norm)); - EXPECT_LE( - max_norm_error_diff, - std::max(error_bounds.error_bound_on_deriv(h, s_degree_x), 1e-12 * max_norm_diff)); - EXPECT_LE( - max_norm_error_integ, - std::max(error_bounds.error_bound_on_int(h, s_degree_x), 1.0e-14 * max_norm_int)); -} - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - ::Kokkos::ScopeGuard kokkos_scope(argc, argv); - ::ddc::ScopeGuard ddc_scope(argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/vendor/sll/tests/periodic_spline_builder_ordered_points.cpp b/vendor/sll/tests/periodic_spline_builder_ordered_points.cpp deleted file mode 100644 index 526815a37..000000000 --- a/vendor/sll/tests/periodic_spline_builder_ordered_points.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -struct DimX -{ - static constexpr bool PERIODIC = true; -}; - -static constexpr std::size_t s_degree_x = DEGREE_X; - -using BSplinesX = NonUniformBSplines; - -using GrevillePoints - = GrevilleInterpolationPoints; - -using IDimX = GrevillePoints::interpolation_mesh_type; - -using IndexX = ddc::DiscreteElement; -using DVectX = ddc::DiscreteVector; -using BsplIndexX = ddc::DiscreteElement; -using SplineX = ddc::Chunk>; -using FieldX = ddc::Chunk>; -using CoordX = ddc::Coordinate; - -TEST(PeriodicSplineBuilderOrderTest, OrderedPoints) -{ - std::size_t constexpr ncells = 10; - - // 1. Create BSplines - int constexpr npoints(ncells + 1); - std::vector d_breaks({0, 0.01, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}); - std::vector breaks(npoints); - for (std::size_t i(0); i < npoints; ++i) { - breaks[i] = CoordX(d_breaks[i]); - } - ddc::init_discrete_space(breaks); - - // 2. Create the interpolation domain - ddc::init_discrete_space(GrevillePoints::get_sampling()); - ddc::DiscreteDomain interpolation_domain(GrevillePoints::get_domain()); - - double last(ddc::coordinate(interpolation_domain.front())); - double current; - for (IndexX const ix : interpolation_domain) { - current = ddc::coordinate(ix); - ASSERT_LE(current, ddc::discrete_space().rmax()); - ASSERT_GE(current, ddc::discrete_space().rmin()); - ASSERT_LE(last, current); - last = current; - } -} - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - ::Kokkos::ScopeGuard kokkos_scope(argc, argv); - ::ddc::ScopeGuard ddc_scope(argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/vendor/sll/tests/polar_bsplines.cpp b/vendor/sll/tests/polar_bsplines.cpp index e4283c396..6d6d095f6 100644 --- a/vendor/sll/tests/polar_bsplines.cpp +++ b/vendor/sll/tests/polar_bsplines.cpp @@ -3,9 +3,6 @@ #include -#include -#include -#include #include #include #include @@ -41,14 +38,18 @@ struct PolarBsplineFixture; - using BSplineP - = std::conditional_t, NonUniformBSplines>; - - using GrevillePointsR - = GrevilleInterpolationPoints; - using GrevillePointsP - = GrevilleInterpolationPoints; + using BSplineR = ddc::NonUniformBSplines; + using BSplineP = std:: + conditional_t, ddc::NonUniformBSplines>; + + using GrevillePointsR = ddc::GrevilleInterpolationPoints< + BSplineR, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE>; + using GrevillePointsP = ddc::GrevilleInterpolationPoints< + BSplineP, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC>; using IDimR = typename GrevillePointsR::interpolation_mesh_type; using IDimP = typename GrevillePointsP::interpolation_mesh_type; @@ -77,10 +78,52 @@ TYPED_TEST(PolarBsplineFixture, PartitionOfUnity) using BSplinesR = typename TestFixture::BSplineR; using BSplinesP = typename TestFixture::BSplineP; using CircToCart = CircularToCartesian; - using BuilderR = SplineBuilder; - using BuilderP = SplineBuilder; - using BuilderRP = SplineBuilder2D; - using DiscreteMapping = DiscreteToCartesian; + using BuilderR = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + IDimR, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::SplineSolver::GINKGO, + IDimR>; + using BuilderP = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesP, + IDimP, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimP>; + using SplineRPBuilder = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimR, + IDimP>; + using SplineRPEvaluator = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::NullExtrapolationRule, + ddc::NullExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; + using DiscreteMapping = DiscreteToCartesian; using BSplines = PolarBSplines; using CoordR = ddc::Coordinate; using CoordP = ddc::Coordinate; @@ -124,13 +167,15 @@ TYPED_TEST(PolarBsplineFixture, PartitionOfUnity) BuilderR builder_r(interpolation_domain_R); BuilderP builder_p(interpolation_domain_P); - BuilderRP builder_rp(interpolation_domain); - - SplineEvaluator2D evaluator_rp( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + SplineRPBuilder builder_rp(interpolation_domain); + + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + SplineRPEvaluator evaluator_rp( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); const CircToCart coord_changer; DiscreteMapping const mapping diff --git a/vendor/sll/tests/polar_splines.cpp b/vendor/sll/tests/polar_splines.cpp index e144e4091..c4a98043e 100644 --- a/vendor/sll/tests/polar_splines.cpp +++ b/vendor/sll/tests/polar_splines.cpp @@ -3,9 +3,6 @@ #include -#include -#include -#include #include #include #include @@ -36,17 +33,17 @@ static constexpr std::size_t spline_r_degree = DEGREE_R; static constexpr std::size_t spline_p_degree = DEGREE_P; static constexpr int continuity = CONTINUITY; -using BSplinesR = NonUniformBSplines; +using BSplinesR = ddc::NonUniformBSplines; #if defined(BSPLINES_TYPE_UNIFORM) -using BSplinesP = UniformBSplines; +using BSplinesP = ddc::UniformBSplines; #elif defined(BSPLINES_TYPE_NON_UNIFORM) -using BSplinesP = NonUniformBSplines; +using BSplinesP = ddc::NonUniformBSplines; #endif -using GrevillePointsR - = GrevilleInterpolationPoints; -using GrevillePointsP - = GrevilleInterpolationPoints; +using GrevillePointsR = ddc:: + GrevilleInterpolationPoints; +using GrevillePointsP = ddc:: + GrevilleInterpolationPoints; using IDimR = GrevillePointsR::interpolation_mesh_type; using IDimP = GrevillePointsP::interpolation_mesh_type; @@ -64,11 +61,54 @@ TEST(PolarSplineTest, ConstantEval) using CoordR = ddc::Coordinate; using CoordP = ddc::Coordinate; using Spline = PolarSpline; - using Evaluator = PolarSplineEvaluator; - using BuilderR = SplineBuilder; - using BuilderP = SplineBuilder; - using BuilderRP = SplineBuilder2D; - using DiscreteMapping = DiscreteToCartesian; + using Evaluator = PolarSplineEvaluator; + using BuilderR = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + IDimR, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::SplineSolver::GINKGO, + IDimR>; + using BuilderP = ddc::SplineBuilder< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesP, + IDimP, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimP>; + using BuilderRP = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimR, + IDimP>; + + using EvaluatorRP = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::NullExtrapolationRule, + ddc::NullExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; + using DiscreteMapping = DiscreteToCartesian; CoordR constexpr r0(0.); CoordR constexpr rN(1.); @@ -109,11 +149,13 @@ TEST(PolarSplineTest, ConstantEval) BuilderP builder_p(interpolation_domain_P); BuilderRP builder_rp(interpolation_domain); - SplineEvaluator2D evaluator_rp( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; + EvaluatorRP evaluator_rp( + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); #if defined(CIRCULAR_MAPPING) CircToCart const coord_changer; @@ -133,7 +175,8 @@ TEST(PolarSplineTest, ConstantEval) coef.spline_coef.domain(), [&](ddc::DiscreteElement const i) { coef.spline_coef(i) = 1.0; }); - const Evaluator spline_evaluator(g_polar_null_boundary_2d); + ddc::NullExtrapolationRule extrapolation_rule; + const Evaluator spline_evaluator(extrapolation_rule); std::size_t const n_test_points = 100; double const dr = (rN - r0) / n_test_points; diff --git a/vendor/sll/tests/pseudo_cartesian_matrix.cpp b/vendor/sll/tests/pseudo_cartesian_matrix.cpp index 769f3c111..0025c02c3 100644 --- a/vendor/sll/tests/pseudo_cartesian_matrix.cpp +++ b/vendor/sll/tests/pseudo_cartesian_matrix.cpp @@ -1,14 +1,10 @@ -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "sll/mapping/circular_to_cartesian.hpp" #include "sll/mapping/czarny_to_cartesian.hpp" #include "sll/mapping/discrete_mapping_to_cartesian.hpp" +#include "sll/math_tools.hpp" #include "test_utils.hpp" @@ -23,11 +19,9 @@ class PseudoCartesianJacobianMatrixTest public: struct DimX { - static bool constexpr PERIODIC = false; }; struct DimY { - static bool constexpr PERIODIC = false; }; struct DimR { @@ -45,14 +39,18 @@ class PseudoCartesianJacobianMatrixTest static int constexpr BSDegree = 3; - using BSplinesR = NonUniformBSplines; - using BSplinesP = NonUniformBSplines; + using BSplinesR = ddc::NonUniformBSplines; + using BSplinesP = ddc::NonUniformBSplines; - using InterpPointsR - = GrevilleInterpolationPoints; - using InterpPointsP - = GrevilleInterpolationPoints; + using InterpPointsR = ddc::GrevilleInterpolationPoints< + BSplinesR, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE>; + using InterpPointsP = ddc::GrevilleInterpolationPoints< + BSplinesP, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC>; using IDimR = typename InterpPointsR::interpolation_mesh_type; @@ -79,16 +77,37 @@ class PseudoCartesianJacobianMatrixTest using IDomainRP = ddc::DiscreteDomain; - using SplineRBuilder - = SplineBuilder; - using SplinePBuilder - = SplineBuilder; - - using SplineRPBuilder = SplineBuilder2D; - using SplineRPEvaluator = SplineEvaluator2D; - - - using DiscreteMapping = DiscreteToCartesian; + using SplineRPBuilder = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimR, + IDimP>; + + using SplineRPEvaluator = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::NullExtrapolationRule, + ddc::NullExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; + + + using DiscreteMapping = DiscreteToCartesian; using spline_domain = ddc::DiscreteDomain; @@ -160,11 +179,13 @@ class PseudoCartesianJacobianMatrixTest // --- Define the operators. ---------------------------------------------------------------------- SplineRPBuilder const builder(grid); + ddc::NullExtrapolationRule r_extrapolation_rule; + ddc::PeriodicExtrapolationRule p_extrapolation_rule; SplineRPEvaluator spline_evaluator( - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d, - g_null_boundary_2d); + r_extrapolation_rule, + r_extrapolation_rule, + p_extrapolation_rule, + p_extrapolation_rule); Matrix_2x2 analytical_matrix; Matrix_2x2 discrete_matrix; @@ -247,12 +268,11 @@ TEST(PseudoCartesianJacobianMatrix, TestDiscreteMapping) << std::endl << ">>> L_inf norm of | M_map - M_dis_map |" << std::endl; - std::array, 5> results; + std::array, 4> results; results[0] = (PseudoCartesianJacobianMatrixTest<16>()).test_circ_and_czar(); results[1] = (PseudoCartesianJacobianMatrixTest<32>()).test_circ_and_czar(); results[2] = (PseudoCartesianJacobianMatrixTest<64>()).test_circ_and_czar(); results[3] = (PseudoCartesianJacobianMatrixTest<128>()).test_circ_and_czar(); - results[4] = (PseudoCartesianJacobianMatrixTest<256>()).test_circ_and_czar(); diff --git a/vendor/sll/tests/refined_discrete_mapping.cpp b/vendor/sll/tests/refined_discrete_mapping.cpp index fbe924554..e0dbe1021 100644 --- a/vendor/sll/tests/refined_discrete_mapping.cpp +++ b/vendor/sll/tests/refined_discrete_mapping.cpp @@ -3,10 +3,7 @@ #include #include - -#include -#include -#include +#include #include "sll/mapping/analytical_invertible_curvilinear2d_to_cartesian.hpp" #include "sll/mapping/circular_to_cartesian.hpp" @@ -43,22 +40,46 @@ using CoordXY = ddc::Coordinate; int constexpr BSDegree = 3; -using BSplinesR = NonUniformBSplines; -using BSplinesP = NonUniformBSplines; +using BSplinesR = ddc::NonUniformBSplines; +using BSplinesP = ddc::NonUniformBSplines; + -using SplineInterpPointsR - = GrevilleInterpolationPoints; -using SplineInterpPointsP - = GrevilleInterpolationPoints; +using SplineInterpPointsR = ddc:: + GrevilleInterpolationPoints; +using SplineInterpPointsP = ddc:: + GrevilleInterpolationPoints; using IDimR = typename SplineInterpPointsR::interpolation_mesh_type; using IDimP = typename SplineInterpPointsP::interpolation_mesh_type; -using SplineRBuilder = SplineBuilder; -using SplinePBuilder = SplineBuilder; -using SplineRPBuilder = SplineBuilder2D; - -using SplineRPEvaluator = SplineEvaluator2D; +using SplineRPBuilder = ddc::SplineBuilder2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::GREVILLE, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::GINKGO, + IDimR, + IDimP>; + +using SplineRPEvaluator = ddc::SplineEvaluator2D< + Kokkos::DefaultHostExecutionSpace, + Kokkos::DefaultHostExecutionSpace::memory_space, + BSplinesR, + BSplinesP, + IDimR, + IDimP, + ddc::ConstantExtrapolationRule, + ddc::ConstantExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + IDimR, + IDimP>; using BSDomainR = ddc::DiscreteDomain; using BSDomainP = ddc::DiscreteDomain; @@ -219,9 +240,15 @@ double test_on_grid_and_not_on_grid( int const Nr, int const Nt, Mapping const& analytical_mapping, - RefinedDiscreteToCartesian const& - refined_mapping, - DiscreteToCartesian const& discrete_mapping, + RefinedDiscreteToCartesian< + RDimX, + RDimY, + SplineRPBuilder, + SplineRPEvaluator, + refined_Nr, + refined_Nt> const& refined_mapping, + DiscreteToCartesian const& + discrete_mapping, IDomainRP const& grid) { std::cout << std::endl @@ -371,9 +398,15 @@ double test_Jacobian( int const Nr, int const Nt, Mapping const& analytical_mapping, - RefinedDiscreteToCartesian const& - refined_mapping, - DiscreteToCartesian const& discrete_mapping, + RefinedDiscreteToCartesian< + RDimX, + RDimY, + SplineRPBuilder, + SplineRPEvaluator, + refined_Nr, + refined_Nt> const& refined_mapping, + DiscreteToCartesian const& + discrete_mapping, IDomainRP const& grid) { std::cout << std::endl @@ -443,9 +476,15 @@ double test_pseudo_Cart( int const Nr, int const Nt, Mapping const& analytical_mapping, - RefinedDiscreteToCartesian const& - refined_mapping, - DiscreteToCartesian const& discrete_mapping, + RefinedDiscreteToCartesian< + RDimX, + RDimY, + SplineRPBuilder, + SplineRPEvaluator, + refined_Nr, + refined_Nt> const& refined_mapping, + DiscreteToCartesian const& + discrete_mapping, IDomainRP const& grid) { std::cout << std::endl @@ -515,36 +554,38 @@ TEST(RefinedDiscreteMapping, TestRefinedDiscreteMapping) // Operators --- SplineRPBuilder builder(grid); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_left( - r_min); - ConstantExtrapolationBoundaryValue2D boundary_condition_r_right( - r_max); - SplineRPEvaluator evaluator( + ddc::ConstantExtrapolationRule boundary_condition_r_left(r_min); + ddc::ConstantExtrapolationRule boundary_condition_r_right(r_max); + SplineRPEvaluator spline_evaluator( boundary_condition_r_left, boundary_condition_r_right, - g_null_boundary_2d, - g_null_boundary_2d); + ddc::PeriodicExtrapolationRule(), + ddc::PeriodicExtrapolationRule()); // Tests --- std::array results; - DiscreteToCartesian discrete_mapping - = DiscreteToCartesian:: - analytical_to_discrete(analytical_mapping, builder, evaluator); + DiscreteToCartesian discrete_mapping + = DiscreteToCartesian:: + analytical_to_discrete(analytical_mapping, builder, spline_evaluator); - RefinedDiscreteToCartesian refined_mapping_16x32 - = RefinedDiscreteToCartesian:: + RefinedDiscreteToCartesian refined_mapping_16x32 + = RefinedDiscreteToCartesian:: analytical_to_refined(analytical_mapping, grid); - RefinedDiscreteToCartesian refined_mapping_32x64 - = RefinedDiscreteToCartesian:: + RefinedDiscreteToCartesian refined_mapping_32x64 + = RefinedDiscreteToCartesian:: analytical_to_refined(analytical_mapping, grid); - RefinedDiscreteToCartesian refined_mapping_64x128 - = RefinedDiscreteToCartesian:: - analytical_to_refined(analytical_mapping, grid); + RefinedDiscreteToCartesian refined_mapping_64x128 = RefinedDiscreteToCartesian< + RDimX, + RDimY, + SplineRPBuilder, + SplineRPEvaluator, + 64, + 128>::analytical_to_refined(analytical_mapping, grid); std::cout << std::endl diff --git a/vendor/sll/tests/spline_error_bounds.hpp b/vendor/sll/tests/spline_error_bounds.hpp deleted file mode 100644 index 55dc843c2..000000000 --- a/vendor/sll/tests/spline_error_bounds.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include -#include - -#include - -template -class SplineErrorBounds -{ -private: - static constexpr std::array tihomirov_error_bound_array = std::array( - {1.0 / 2.0, - 1.0 / 8.0, - 1.0 / 24.0, - 5.0 / 384.0, - 1.0 / 240.0, - 61.0 / 46080.0, - 17.0 / 40320.0, - 277.0 / 2064384.0, - 31.0 / 725760.0, - 50521.0 / 3715891200.0}); - -private: - Evaluator const& m_evaluator; - -private: - /******************************************************************************* - * Error bound in max norm for spline interpolation of periodic functions from: - * - * V M Tihomirov 1969 Math. USSR Sb. 9 275 - * https://doi.org/10.1070/SM1969v009n02ABEH002052 (page 286, bottom) - * - * Yu. S. Volkov and Yu. N. Subbotin - * https://doi.org/10.1134/S0081543815020236 (equation 14) - * - * Also applicable to first derivative by passing deg-1 instead of deg - * Volkov & Subbotin 2015, eq. 15 - *******************************************************************************/ - static double tihomirov_error_bound(double cell_width, int degree, double max_norm) - { - degree = std::min(degree, 9); - return tihomirov_error_bound_array[degree] * ipow(cell_width, degree + 1) * max_norm; - } - -public: - SplineErrorBounds(Evaluator const& evaluator) : m_evaluator(evaluator) {} - - double error_bound(double cell_width, int degree) - { - return tihomirov_error_bound(cell_width, degree, m_evaluator.max_norm(degree + 1)); - } - double error_bound(double cell_width1, double cell_width2, int degree1, int degree2) - { - double norm1 = m_evaluator.max_norm(degree1 + 1, 0); - double norm2 = m_evaluator.max_norm(0, degree2 + 1); - return tihomirov_error_bound(cell_width1, degree1, norm1) - + tihomirov_error_bound(cell_width2, degree2, norm2); - } - double error_bound_on_deriv(double cell_width, int degree) - { - return tihomirov_error_bound(cell_width, degree - 1, m_evaluator.max_norm(degree + 1)); - } - double error_bound_on_deriv_1(double cell_width1, double cell_width2, int degree1, int degree2) - { - double norm1 = m_evaluator.max_norm(degree1 + 1, 0); - double norm2 = m_evaluator.max_norm(0, degree2 + 1); - return tihomirov_error_bound(cell_width1, degree1 - 1, norm1) - + tihomirov_error_bound(cell_width2, degree2, norm2); - } - double error_bound_on_deriv_2(double cell_width1, double cell_width2, int degree1, int degree2) - { - double norm1 = m_evaluator.max_norm(degree1 + 1, 0); - double norm2 = m_evaluator.max_norm(0, degree2 + 1); - return tihomirov_error_bound(cell_width1, degree1, norm1) - + tihomirov_error_bound(cell_width2, degree2 - 1, norm2); - } - - /******************************************************************************* - * NOTE: The following estimates have no theoretical justification but capture - * the correct asympthotic rate of convergence. - * The error constant may be overestimated. - *******************************************************************************/ - double error_bound_on_deriv_12(double cell_width1, double cell_width2, int degree1, int degree2) - { - double norm1 = m_evaluator.max_norm(degree1 + 1, 1); - double norm2 = m_evaluator.max_norm(1, degree2 + 1); - return tihomirov_error_bound(cell_width1, degree1 - 1, norm1) - + tihomirov_error_bound(cell_width2, degree2 - 1, norm2); - } - - double error_bound_on_int(double cell_width, int degree) - { - return tihomirov_error_bound(cell_width, degree + 1, m_evaluator.max_norm(degree + 1)); - } -}; diff --git a/vendor/sll/tests/splines.cpp b/vendor/sll/tests/splines.cpp deleted file mode 100644 index cd63173d9..000000000 --- a/vendor/sll/tests/splines.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include - -using namespace std; -using namespace std::experimental; -using namespace deprecated; - -constexpr double TWO_PI = 2. * M_PI; - -static inline double eval_cos( - double const x, - Span1D const& coeffs, - int const derivative = 0); - -Span1D& eval_cos( - Span1D& y, - Span1D const& x, - Span1D const& coeffs, - int const derivative = 0); - -void cos_splines_test( - double& max_norm_error, - double& max_norm_error_diff, - double& max_norm_error_int, - int const degree, - int const N, - double const x0, - double const xN, - BoundCond const bc_xmin, - BoundCond const bc_xmax, - Span1D const& coeffs, - DSpan1D const& eval_pts_input = {}); - -static inline double eval_cos(double const x, Span1D const& coeffs, int const derivative) -{ - return pow(TWO_PI * coeffs[0], derivative) - * cos(M_PI_2 * derivative + TWO_PI * (coeffs[0] * x + coeffs[1])); -} - -Span1D& eval_cos( - Span1D& y, - Span1D const& x, - Span1D const& coeffs, - int const derivative) -{ - assert(y.extent(0) == x.extent(0)); - for (int ii = 0; ii < y.extent(0); ++ii) { - y[ii] = eval_cos(x[ii], coeffs, derivative); - } - return y; -} - - -void cos_splines_test( - double& max_norm_error, - double& max_norm_error_diff, - double& max_norm_error_int, - int const degree, - int const N, - double const x0, - double const xN, - BoundCond const bc_xmin, - BoundCond const bc_xmax, - Span1D const& coeffs, - DSpan1D const& eval_pts_input) -{ - // Create B-splines (uniform or non-uniform depending on input) - std::shared_ptr bspline = std::make_shared( - degree, - (bc_xmin == BoundCond::PERIODIC), - x0, - xN, - SplineBuilder1D::compute_num_cells(degree, bc_xmin, bc_xmax, N)); - - // Initialize 1D spline - Spline1D spline(*bspline); - - // Initialize 1D spline interpolator - SplineBuilder1D spline_interpolator(*bspline, bc_xmin, bc_xmax); - - DSpan1D const xgrid = spline_interpolator.get_interp_points(); - DSpan1D eval_pts; - if (0 != eval_pts_input.extent(0)) { - eval_pts = eval_pts_input; - } else { - eval_pts = xgrid; - } - - vector yvals_data(N); - Span1D yvals(yvals_data.data(), yvals_data.size()); - eval_cos(yvals, xgrid, coeffs); - - // computation of rhs'(0) and rhs'(n) - // -> deriv_rhs(0) = rhs'(n) and deriv_rhs(1) = rhs'(0) - int const shift = (degree % 2); // shift = 0 for even order, -1 for odd order - vector Sderiv_lhs_data(degree / 2); - Span1D Sderiv_lhs(Sderiv_lhs_data.data(), Sderiv_lhs_data.size()); - vector Sderiv_rhs_data(degree / 2); - Span1D Sderiv_rhs(Sderiv_rhs_data.data(), Sderiv_rhs_data.size()); - Span1D* deriv_l(nullptr); - Span1D* deriv_r(nullptr); - if (bc_xmin == BoundCond::HERMITE) { - for (int ii = 0; ii < degree / 2; ++ii) { - Sderiv_lhs(ii) = eval_cos(x0, coeffs, ii - shift); - } - deriv_l = &Sderiv_lhs; - } - if (bc_xmax == BoundCond::HERMITE) { - for (int ii = 0; ii < degree / 2; ++ii) { - Sderiv_rhs(ii) = eval_cos(xN, coeffs, ii - shift); - } - deriv_r = &Sderiv_rhs; - } - spline_interpolator.compute_interpolant(spline, yvals, deriv_l, deriv_r); - - max_norm_error = 0.; - max_norm_error_diff = 0.; - - for (int ii = 0; ii < eval_pts.extent(0); ++ii) { - // Check eval function - double const spline_value = spline.eval(eval_pts[ii]); - - // Compute error - double const error = spline_value - eval_cos(eval_pts[ii], coeffs); - max_norm_error = std::max(max_norm_error, abs(error)); - - // Check eval_deriv function - double const spline_deriv_value = spline.eval_deriv(eval_pts[ii]); - - // Compute error - double const error_deriv = spline_deriv_value - eval_cos(eval_pts[ii], coeffs, 1); - max_norm_error_diff = std::max(max_norm_error_diff, abs(error_deriv)); - } - - max_norm_error_int = spline.integrate(); -} - - - -constexpr array available_bc - = {BoundCond::PERIODIC, BoundCond::HERMITE, BoundCond::GREVILLE}; -//TODO : Add missing test conditions NEUMANN and HERMITE_LAGRANGE - -class SplinesTest : public testing::TestWithParam> -{ - // You can implement all the usual fixture class members here. - // To access the test parameter, call GetParam() from class - // TestWithParam. -}; - -INSTANTIATE_TEST_SUITE_P( - SplinesAtPoints, - SplinesTest, - testing::Combine( - testing::Range(4, 7), - testing::ValuesIn(available_bc), - testing::ValuesIn(available_bc))); - -//-------------------------------------- -// TESTS -//-------------------------------------- -TEST_P(SplinesTest, Test) -{ - //int const ncells; - //int const bc_xmin, bc_xmax; - - - constexpr double x0 = 0.0; - constexpr double xN = 1.0; - constexpr int N = 22; - constexpr double tol = 1e-12; - constexpr double max_norm_profile = 1.0; - - - array coeffs_data = {1., 0.}; - Span1D coeffs(coeffs_data.data(), coeffs_data.size()); - - auto const [degree, bc_xmin, bc_xmax] = GetParam(); - - if (bc_xmin != bc_xmax and (bc_xmin == BoundCond::PERIODIC or bc_xmax == BoundCond::PERIODIC)) { - return; - } - - //if (degree != 3 - // and (bc_xmin == BoundCond::HERMITE_LAGRANGE - // or bc_xmax == BoundCond::HERMITE_LAGRANGE)) { - // continue; - //} - - //if ((degree > 3 or degree == 2) - // and (bc_xmin == BoundCond::NEUMANN or bc_xmax == BoundCond::NEUMANN)) { - // continue; - //} - - double max_norm_error; - double max_norm_error_diff; - double max_norm_error_int; - cos_splines_test( - max_norm_error, - max_norm_error_diff, - max_norm_error_int, - degree, - N, - x0, - xN, - bc_xmin, - bc_xmax, - coeffs); - - // Calculate relative error norms from absolute ones - max_norm_error = max_norm_error / max_norm_profile; - EXPECT_LE(max_norm_error, tol) - << "While evaluating spline at interpolation points (error should be zero) \n" - << "With \n" - << " * Number of points in grid: N = " << N << "\n" - << " * Number of evaluation points : " << N << "\n"; -}