SpECTRE Documentation Coverage Report
Current view: top level - Elliptic/Systems/Xcts/Events - ObserveAdmIntegrals.hpp Hit Total Coverage
Commit: bcc6763cee2b3f1593fb35e61fb83412a3313e95 Lines: 3 20 15.0 %
Date: 2024-09-16 17:23:19
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <optional>
       7             : #include <pup.h>
       8             : #include <string>
       9             : #include <vector>
      10             : 
      11             : #include "DataStructures/DataVector.hpp"
      12             : #include "DataStructures/Tensor/Tensor.hpp"
      13             : #include "Domain/Structure/ElementId.hpp"
      14             : #include "Domain/Tags.hpp"
      15             : #include "Domain/Tags/FaceNormal.hpp"
      16             : #include "Domain/Tags/Faces.hpp"
      17             : #include "Elliptic/Systems/Xcts/Tags.hpp"
      18             : #include "IO/Observer/GetSectionObservationKey.hpp"
      19             : #include "IO/Observer/ObservationId.hpp"
      20             : #include "IO/Observer/ObserverComponent.hpp"
      21             : #include "IO/Observer/ReductionActions.hpp"
      22             : #include "IO/Observer/TypeOfObservation.hpp"
      23             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      24             : #include "Options/String.hpp"
      25             : #include "Parallel/ArrayIndex.hpp"
      26             : #include "Parallel/GlobalCache.hpp"
      27             : #include "Parallel/Reduction.hpp"
      28             : #include "Parallel/TypeTraits.hpp"
      29             : #include "ParallelAlgorithms/Events/Tags.hpp"
      30             : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      31             : #include "Utilities/Serialization/CharmPupable.hpp"
      32             : 
      33           0 : namespace Events {
      34             : 
      35             : /// @{
      36             : /*!
      37             :  * \brief Computes the ADM integrals locally (within one element).
      38             :  *
      39             :  * To get the total ADM integrals, the results need to be summed over in a
      40             :  * reduction.
      41             :  *
      42             :  * See `Xcts::adm_linear_momentum_surface_integrand` for details on the formula
      43             :  * for each integrand.
      44             :  */
      45           1 : void local_adm_integrals(
      46             :     gsl::not_null<Scalar<double>*> adm_mass,
      47             :     gsl::not_null<tnsr::I<double, 3>*> adm_linear_momentum,
      48             :     gsl::not_null<tnsr::I<double, 3>*> center_of_mass,
      49             :     const Scalar<DataVector>& conformal_factor,
      50             :     const tnsr::i<DataVector, 3>& deriv_conformal_factor,
      51             :     const tnsr::ii<DataVector, 3>& conformal_metric,
      52             :     const tnsr::II<DataVector, 3>& inv_conformal_metric,
      53             :     const tnsr::Ijj<DataVector, 3>& conformal_christoffel_second_kind,
      54             :     const tnsr::i<DataVector, 3>& conformal_christoffel_contracted,
      55             :     const tnsr::ii<DataVector, 3>& spatial_metric,
      56             :     const tnsr::II<DataVector, 3>& inv_spatial_metric,
      57             :     const tnsr::ii<DataVector, 3>& extrinsic_curvature,
      58             :     const Scalar<DataVector>& trace_extrinsic_curvature,
      59             :     const InverseJacobian<DataVector, 3, Frame::ElementLogical,
      60             :                           Frame::Inertial>& inv_jacobian,
      61             :     const Mesh<3>& mesh, const Element<3>& element,
      62             :     const DirectionMap<3, tnsr::i<DataVector, 3>>& conformal_face_normals,
      63             :     const DirectionMap<3, tnsr::I<DataVector, 3>>&
      64             :         conformal_face_normal_vectors);
      65             : /// @}
      66             : 
      67             : /// @{
      68             : /*!
      69             :  * \brief Observe ADM integrals after the XCTS solve.
      70             :  *
      71             :  * The surface integrals are taken over the outer boundary, which is defined as
      72             :  * the domain boundary in the upper logical zeta direction.
      73             :  *
      74             :  * Writes reduction quantities:
      75             :  * - ADM mass
      76             :  * - Linear momentum
      77             :  * - Center of mass
      78             :  */
      79             : template <typename ArraySectionIdTag = void>
      80           1 : class ObserveAdmIntegrals : public Event {
      81             :  private:
      82           0 :   using ReductionData = Parallel::ReductionData<
      83             :       // ADM Mass
      84             :       Parallel::ReductionDatum<double, funcl::Plus<>>,
      85             :       // ADM Linear Momentum (x-component)
      86             :       Parallel::ReductionDatum<double, funcl::Plus<>>,
      87             :       // ADM Linear Momentum (y-component)
      88             :       Parallel::ReductionDatum<double, funcl::Plus<>>,
      89             :       // ADM Linear Momentum (z-component)
      90             :       Parallel::ReductionDatum<double, funcl::Plus<>>,
      91             :       // Center of Mass (x-component)
      92             :       Parallel::ReductionDatum<double, funcl::Plus<>, funcl::Divides<>,
      93             :                                std::index_sequence<0>>,
      94             :       // Center of Mass (y-component)
      95             :       Parallel::ReductionDatum<double, funcl::Plus<>, funcl::Divides<>,
      96             :                                std::index_sequence<0>>,
      97             :       // Center of Mass (z-component)
      98             :       Parallel::ReductionDatum<double, funcl::Plus<>, funcl::Divides<>,
      99             :                                std::index_sequence<0>>>;
     100             : 
     101             :  public:
     102             :   /// \cond
     103             :   explicit ObserveAdmIntegrals(CkMigrateMessage* msg) : Event(msg) {}
     104             :   using PUP::able::register_constructor;
     105             :   WRAPPED_PUPable_decl_template(ObserveAdmIntegrals);  // NOLINT
     106             :   /// \endcond
     107             : 
     108           0 :   using options = tmpl::list<>;
     109           0 :   static constexpr Options::String help =
     110             :       "Observe ADM integrals after the XCTS solve.\n"
     111             :       "\n"
     112             :       "Writes reduction quantities:\n"
     113             :       "- Linear momentum";
     114             : 
     115           0 :   ObserveAdmIntegrals() = default;
     116             : 
     117           0 :   using observed_reduction_data_tags =
     118             :       observers::make_reduction_data_tags<tmpl::list<ReductionData>>;
     119             : 
     120           0 :   using compute_tags_for_observation_box = tmpl::list<>;
     121             : 
     122           0 :   using return_tags = tmpl::list<>;
     123             : 
     124           0 :   using argument_tags = tmpl::list<
     125             :       Xcts::Tags::ConformalFactor<DataVector>,
     126             :       ::Tags::deriv<Xcts::Tags::ConformalFactor<DataVector>, tmpl::size_t<3>,
     127             :                     Frame::Inertial>,
     128             :       Xcts::Tags::ConformalMetric<DataVector, 3, Frame::Inertial>,
     129             :       Xcts::Tags::InverseConformalMetric<DataVector, 3, Frame::Inertial>,
     130             :       Xcts::Tags::ConformalChristoffelSecondKind<DataVector, 3,
     131             :                                                  Frame::Inertial>,
     132             :       Xcts::Tags::ConformalChristoffelContracted<DataVector, 3,
     133             :                                                  Frame::Inertial>,
     134             :       gr::Tags::SpatialMetric<DataVector, 3, Frame::Inertial>,
     135             :       gr::Tags::InverseSpatialMetric<DataVector, 3, Frame::Inertial>,
     136             :       gr::Tags::ExtrinsicCurvature<DataVector, 3, Frame::Inertial>,
     137             :       gr::Tags::TraceExtrinsicCurvature<DataVector>,
     138             :       domain::Tags::InverseJacobian<3, Frame::ElementLogical, Frame::Inertial>,
     139             :       domain::Tags::Mesh<3>, domain::Tags::Element<3>,
     140             :       domain::Tags::Faces<3, domain::Tags::FaceNormal<3>>,
     141             :       domain::Tags::Faces<3, domain::Tags::FaceNormalVector<3>>,
     142             :       ::Tags::ObservationBox>;
     143             : 
     144             :   template <typename DataBoxType, typename ComputeTagsList,
     145             :             typename Metavariables, typename ArrayIndex,
     146             :             typename ParallelComponent>
     147           0 :   void operator()(
     148             :       const Scalar<DataVector>& conformal_factor,
     149             :       const tnsr::i<DataVector, 3>& deriv_conformal_factor,
     150             :       const tnsr::ii<DataVector, 3>& conformal_metric,
     151             :       const tnsr::II<DataVector, 3>& inv_conformal_metric,
     152             :       const tnsr::Ijj<DataVector, 3>& conformal_christoffel_second_kind,
     153             :       const tnsr::i<DataVector, 3>& conformal_christoffel_contracted,
     154             :       const tnsr::ii<DataVector, 3>& spatial_metric,
     155             :       const tnsr::II<DataVector, 3>& inv_spatial_metric,
     156             :       const tnsr::ii<DataVector, 3>& extrinsic_curvature,
     157             :       const Scalar<DataVector>& trace_extrinsic_curvature,
     158             :       const InverseJacobian<DataVector, 3, Frame::ElementLogical,
     159             :                             Frame::Inertial>& inv_jacobian,
     160             :       const Mesh<3>& mesh, const Element<3>& element,
     161             :       const DirectionMap<3, tnsr::i<DataVector, 3>>& conformal_face_normals,
     162             :       const DirectionMap<3, tnsr::I<DataVector, 3>>&
     163             :           conformal_face_normal_vectors,
     164             :       const ObservationBox<DataBoxType, ComputeTagsList>& box,
     165             :       Parallel::GlobalCache<Metavariables>& cache,
     166             :       const ArrayIndex& array_index, const ParallelComponent* const /*meta*/,
     167             :       const ObservationValue& observation_value) const {
     168             :     // Skip observation on elements that are not part of a section
     169             :     const std::optional<std::string> section_observation_key =
     170             :         observers::get_section_observation_key<ArraySectionIdTag>(box);
     171             :     if (not section_observation_key.has_value()) {
     172             :       return;
     173             :     }
     174             :     const std::string subfile_path = subfile_path_ + *section_observation_key;
     175             : 
     176             :     Scalar<double> adm_mass;
     177             :     tnsr::I<double, 3> adm_linear_momentum;
     178             :     tnsr::I<double, 3> center_of_mass;
     179             :     local_adm_integrals(
     180             :         make_not_null(&adm_mass), make_not_null(&adm_linear_momentum),
     181             :         make_not_null(&center_of_mass), conformal_factor,
     182             :         deriv_conformal_factor, conformal_metric, inv_conformal_metric,
     183             :         conformal_christoffel_second_kind, conformal_christoffel_contracted,
     184             :         spatial_metric, inv_spatial_metric, extrinsic_curvature,
     185             :         trace_extrinsic_curvature, inv_jacobian, mesh, element,
     186             :         conformal_face_normals, conformal_face_normal_vectors);
     187             : 
     188             :     // Save components of linear momentum as reduction data
     189             :     ReductionData reduction_data{get(adm_mass),
     190             :                                  get<0>(adm_linear_momentum),
     191             :                                  get<1>(adm_linear_momentum),
     192             :                                  get<2>(adm_linear_momentum),
     193             :                                  get<0>(center_of_mass),
     194             :                                  get<1>(center_of_mass),
     195             :                                  get<2>(center_of_mass)};
     196             :     std::vector<std::string> legend{"AdmMass",
     197             :                                     "AdmLinearMomentum_x",
     198             :                                     "AdmLinearMomentum_y",
     199             :                                     "AdmLinearMomentum_z",
     200             :                                     "CenterOfMass_x",
     201             :                                     "CenterOfMass_y",
     202             :                                     "CenterOfMass_z"};
     203             : 
     204             :     // Get information required for reduction
     205             :     auto& local_observer = *Parallel::local_branch(
     206             :         Parallel::get_parallel_component<
     207             :             tmpl::conditional_t<Parallel::is_nodegroup_v<ParallelComponent>,
     208             :                                 observers::ObserverWriter<Metavariables>,
     209             :                                 observers::Observer<Metavariables>>>(cache));
     210             :     observers::ObservationId observation_id{observation_value.value,
     211             :                                             subfile_path + ".dat"};
     212             :     Parallel::ArrayComponentId array_component_id{
     213             :         std::add_pointer_t<ParallelComponent>{nullptr},
     214             :         Parallel::ArrayIndex<ElementId<3>>(array_index)};
     215             : 
     216             :     // Send reduction action
     217             :     if constexpr (Parallel::is_nodegroup_v<ParallelComponent>) {
     218             :       Parallel::threaded_action<
     219             :           observers::ThreadedActions::CollectReductionDataOnNode>(
     220             :           local_observer, std::move(observation_id),
     221             :           std::move(array_component_id), subfile_path, std::move(legend),
     222             :           std::move(reduction_data));
     223             :     } else {
     224             :       Parallel::simple_action<observers::Actions::ContributeReductionData>(
     225             :           local_observer, std::move(observation_id),
     226             :           std::move(array_component_id), subfile_path, std::move(legend),
     227             :           std::move(reduction_data));
     228             :     }
     229             :   }
     230             : 
     231           0 :   using observation_registration_tags = tmpl::list<::Tags::DataBox>;
     232             : 
     233             :   template <typename DbTagsList>
     234             :   std::optional<
     235             :       std::pair<observers::TypeOfObservation, observers::ObservationKey>>
     236           0 :   get_observation_type_and_key_for_registration(
     237             :       const db::DataBox<DbTagsList>& box) const {
     238             :     const std::optional<std::string> section_observation_key =
     239             :         observers::get_section_observation_key<ArraySectionIdTag>(box);
     240             :     if (not section_observation_key.has_value()) {
     241             :       return std::nullopt;
     242             :     }
     243             :     return {{observers::TypeOfObservation::Reduction,
     244             :              observers::ObservationKey(
     245             :                  subfile_path_ + section_observation_key.value() + ".dat")}};
     246             :   }
     247             : 
     248           0 :   using is_ready_argument_tags = tmpl::list<>;
     249             : 
     250             :   template <typename Metavariables, typename ArrayIndex, typename Component>
     251           0 :   bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
     252             :                 const ArrayIndex& /*array_index*/,
     253             :                 const Component* const /*meta*/) const {
     254             :     return true;
     255             :   }
     256             : 
     257           1 :   bool needs_evolved_variables() const override { return false; }
     258             : 
     259             :   // NOLINTNEXTLINE(google-runtime-references)
     260           0 :   void pup(PUP::er& p) override {
     261             :     Event::pup(p);
     262             :     p | subfile_path_;
     263             :   }
     264             : 
     265             :  private:
     266           0 :   std::string subfile_path_ = "/AdmIntegrals";
     267             : };
     268             : /// @}
     269             : 
     270             : /// \cond
     271             : template <typename ArraySectionIdTag>
     272             : PUP::able::PUP_ID ObserveAdmIntegrals<ArraySectionIdTag>::my_PUP_ID =
     273             :     0;  // NOLINT
     274             : /// \endcond
     275             : 
     276             : }  // namespace Events

Generated by: LCOV version 1.14