.. _program_listing_file_src_pcms_transfer_interpolator.h: Program Listing for File interpolator.h ======================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/pcms/transfer/interpolator.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef PCMS_FIELD_INTERPOLATOR_H #define PCMS_FIELD_INTERPOLATOR_H #include "pcms/field/field.h" #include "pcms/field/field_data.h" #include "pcms/field/function_space.h" #include "pcms/field/point_evaluator_factory.hpp" #include "pcms/field/out_of_bounds_policy.h" #include "pcms/field/point_evaluator.h" #include "pcms/utility/arrays.h" #include "pcms/utility/memory_spaces.h" #include "pcms/utility/profile.h" #include "pcms/utility/types.h" #include #include #include "pcms/transfer/transfer_operator.hpp" namespace pcms { // Interpolator separates the expensive localization step from the cheap // repeated evaluation step, making it efficient to use in a coupling loop. // // Construct once per sourceƗtarget function-space pair (localizes target DOF // coordinates into the source mesh), then call Apply repeatedly for different // field states at zero additional localization cost. Any Field sharing the // same target FunctionSpace can be passed to Apply. // // Usage: // Interpolator interp(src_space, tgt_space); // interp.Apply(src_field, tgt_field); // cheap; called in coupling loop // interp.Apply(src_field_next, tgt_field_next); // reuses cached localization template class Interpolator : public TransferOperator { public: // Expensive: localizes target DOF coords into source mesh. Called once. Interpolator(const PointEvaluatorFactory& source, const FunctionSpace& target_space, OutOfBoundsPolicy policy = {}) : num_points_(static_cast( target_space.GetLayout()->GetDOFHolderCoordinates().GetValues().extent( 0))), n_comp_(target_space.GetLayout()->GetNumComponents()), evaluator_(source.CreatePointEvaluator( EvaluationRequest::FromFunctionSpace(target_space, policy))), target_values_("interp_output", num_points_, n_comp_) { } void Apply(const Field& source, Field& target) const override { PCMS_FUNCTION_TIMER; const auto& sd = source.GetData(); const auto& td = target.GetData(); if (sd.GetValueType() != td.GetValueType()) { throw pcms_error("Interpolator: source and target value types differ"); } const ValueBasis written = evaluator_->OutputBasis(sd.GetValueBasis()); if (!SameValueBasis(written, td.GetValueBasis())) { throw pcms_error( "Interpolator: the basis written for the source's stored basis " "differs from the target's declared basis"); } evaluator_->Evaluate(source, ValueView( written, MakeRank2View(target_values_))); target.SetDOFHolderDataUnchecked(MakeConstRank2View(target_values_)); } private: LO num_points_; int n_comp_; std::unique_ptr> evaluator_; mutable Kokkos::View target_values_; }; } // namespace pcms #endif // PCMS_FIELD_INTERPOLATOR_H