SpECTRE Documentation Coverage Report
Current view: top level - ControlSystem/Measurements - BNSCenterOfMass.hpp Hit Total Coverage
Commit: f23e75c235cae5144b8ac7ce01280be5b8cd2c8a Lines: 8 26 30.8 %
Date: 2024-09-07 06:21:00
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 <cstddef>
       7             : #include <string>
       8             : #include <tuple>
       9             : #include <vector>
      10             : 
      11             : #include "ControlSystem/Component.hpp"
      12             : #include "ControlSystem/Protocols/Measurement.hpp"
      13             : #include "ControlSystem/Protocols/Submeasurement.hpp"
      14             : #include "ControlSystem/RunCallbacks.hpp"
      15             : #include "DataStructures/LinkedMessageId.hpp"
      16             : #include "DataStructures/Tensor/TypeAliases.hpp"
      17             : #include "Domain/FunctionsOfTime/Tags.hpp"
      18             : #include "Domain/Structure/ObjectLabel.hpp"
      19             : #include "IO/Logging/Verbosity.hpp"
      20             : #include "IO/Observer/ObserverComponent.hpp"
      21             : #include "IO/Observer/ReductionActions.hpp"
      22             : #include "NumericalAlgorithms/LinearOperators/DefiniteIntegral.hpp"
      23             : #include "Parallel/GlobalCache.hpp"
      24             : #include "Parallel/Invoke.hpp"
      25             : #include "Parallel/Reduction.hpp"
      26             : #include "ParallelAlgorithms/Actions/FunctionsOfTimeAreReady.hpp"
      27             : #include "ParallelAlgorithms/Events/Tags.hpp"
      28             : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      29             : #include "Utilities/GetOutput.hpp"
      30             : #include "Utilities/ProtocolHelpers.hpp"
      31             : #include "Utilities/Serialization/CharmPupable.hpp"
      32             : #include "Utilities/StdArrayHelpers.hpp"
      33             : #include "Utilities/TMPL.hpp"
      34             : 
      35             : /// \cond
      36             : class DataVector;
      37             : template <size_t VolumeDim>
      38             : class ElementId;
      39             : template <size_t Dim>
      40             : class Mesh;
      41             : namespace control_system::Tags {
      42             : struct WriteDataToDisk;
      43             : }  // namespace control_system::Tags
      44             : namespace Parallel {
      45             : template <typename Metavariables>
      46             : class GlobalCache;
      47             : }  // namespace Parallel
      48             : namespace domain::Tags {
      49             : template <size_t Dim>
      50             : struct Mesh;
      51             : template <size_t Dim, typename Frame>
      52             : struct Coordinates;
      53             : }  // namespace domain::Tags
      54             : namespace grmhd::ValenciaDivClean::Tags {
      55             : struct TildeD;
      56             : }  // namespace grmhd::ValenciaDivClean::Tags
      57             : namespace Tags {
      58             : struct PreviousTriggerTime;
      59             : }  // namespace Tags
      60             : /// \endcond
      61             : 
      62             : namespace control_system {
      63           0 : namespace measurements {
      64             : /// \cond
      65             : template <typename ControlSystems>
      66             : struct PostReductionSendBNSStarCentersToControlSystem;
      67             : /// \endcond
      68             : 
      69             : /*!
      70             :  * \brief  Factored Center of Mass calculation (for easier testing)
      71             :  *
      72             :  * \details This function computes the integral of tildeD (assumed to be the
      73             :  * conservative baryon density in the inertial frame), as well as its first
      74             :  * moment in the grid frame. The integrals are limited to \f$x>0\f$ (label A) or
      75             :  * \f$x<0\f$ (label B).
      76             :  *
      77             :  * \param mass_a Integral of tildeD (x > 0)
      78             :  * \param mass_b Integral of tildeD (x < 0)
      79             :  * \param first_moment_A First moment of integral of tildeD (x > 0)
      80             :  * \param first_moment_B First moment of integral of tildeD (x < 0)
      81             :  * \param mesh The mesh
      82             :  * \param inv_det_jacobian The inverse determinant of the jacobian of the map
      83             :  * between logical and inertial coordinates \param tilde_d TildeD on the mesh
      84             :  * \param x_grid The coordinates in the grid frame
      85             :  */
      86           1 : void center_of_mass_integral_on_element(
      87             :     const gsl::not_null<double*> mass_a, const gsl::not_null<double*> mass_b,
      88             :     const gsl::not_null<std::array<double, 3>*> first_moment_A,
      89             :     const gsl::not_null<std::array<double, 3>*> first_moment_B,
      90             :     const Mesh<3>& mesh, const Scalar<DataVector>& inv_det_jacobian,
      91             :     const Scalar<DataVector>& tilde_d,
      92             :     const tnsr::I<DataVector, 3, Frame::Grid>& x_grid);
      93             : }  // namespace measurements
      94             : 
      95             : /*!
      96             :  * \brief An `::Event` that computes the center of mass for $x > 0$ and $x < 0$
      97             :  * where $x$ is the in the `Frame::Grid`.
      98             :  *
      99             :  * \details See
     100             :  * `control_system::measurements::center_of_mass_integral_on_element` for the
     101             :  * calculation of the CoM. This event then does a reduction and calls
     102             :  * `control_system::PostReductionSendBNSStarCentersToControlSystem` as a post
     103             :  * reduction callback.
     104             :  *
     105             :  * \tparam ControlSystems `tmpl::list` of all control systems that use this
     106             :  * event.
     107             :  */
     108             : template <typename ControlSystems>
     109           1 : class BNSEvent : public ::Event {
     110             :  public:
     111             :   /// \cond
     112             :   // LCOV_EXCL_START
     113             :   explicit BNSEvent(CkMigrateMessage* /*unused*/) {}
     114             :   using PUP::able::register_constructor;
     115             :   WRAPPED_PUPable_decl_template(BNSEvent);  // NOLINT
     116             :   // LCOV_EXCL_STOP
     117             :   /// \endcond
     118             : 
     119             :   // This event is created during control system initialization, not
     120             :   // from the input file.
     121           0 :   static constexpr bool factory_creatable = false;
     122           0 :   BNSEvent() = default;
     123             : 
     124           0 :   using compute_tags_for_observation_box = tmpl::list<>;
     125             : 
     126           0 :   using return_tags = tmpl::list<>;
     127           0 :   using argument_tags =
     128             :       tmpl::list<::Tags::Time, ::Tags::PreviousTriggerTime,
     129             :                  ::Events::Tags::ObserverMesh<3>,
     130             :                  ::Events::Tags::ObserverDetInvJacobian<Frame::ElementLogical,
     131             :                                                         Frame::Inertial>,
     132             :                  grmhd::ValenciaDivClean::Tags::TildeD,
     133             :                  ::Events::Tags::ObserverCoordinates<3, Frame::Grid>>;
     134             : 
     135             :   template <typename Metavariables, typename ArrayIndex,
     136             :             typename ParallelComponent>
     137           0 :   void operator()(const double time, const std::optional<double>& previous_time,
     138             :                   const Mesh<3>& mesh,
     139             :                   const Scalar<DataVector>& inv_det_jacobian,
     140             :                   const Scalar<DataVector>& tilde_d,
     141             :                   const tnsr::I<DataVector, 3, Frame::Grid>& x_grid,
     142             :                   Parallel::GlobalCache<Metavariables>& cache,
     143             :                   const ArrayIndex& array_index,
     144             :                   const ParallelComponent* const /*meta*/,
     145             :                   const ObservationValue& /*observation_value*/) const {
     146             :     const LinkedMessageId<double> measurement_id{time, previous_time};
     147             : 
     148             :     // Initialize integrals and perform local calculations
     149             :     double mass_a = 0.;
     150             :     double mass_b = 0.;
     151             :     std::array<double, 3> first_moment_a = {0., 0., 0.};
     152             :     std::array<double, 3> first_moment_b = {0., 0., 0.};
     153             :     measurements::center_of_mass_integral_on_element(
     154             :         &mass_a, &mass_b, &first_moment_a, &first_moment_b, mesh,
     155             :         inv_det_jacobian, tilde_d, x_grid);
     156             : 
     157             :     // Reduction
     158             :     auto my_proxy =
     159             :         Parallel::get_parallel_component<ParallelComponent>(cache)[array_index];
     160             :     // We need a place to run RunCallback on... this does not need to be
     161             :     // the control system using the CoM data.
     162             :     auto& reduction_target_proxy = Parallel::get_parallel_component<
     163             :         ControlComponent<Metavariables, tmpl::front<ControlSystems>>>(cache);
     164             :     Parallel::ReductionData<
     165             :         Parallel::ReductionDatum<LinkedMessageId<double>, funcl::AssertEqual<>>,
     166             :         Parallel::ReductionDatum<double, funcl::Plus<>>,
     167             :         Parallel::ReductionDatum<double, funcl::Plus<>>,
     168             :         Parallel::ReductionDatum<std::array<double, 3>, funcl::Plus<>>,
     169             :         Parallel::ReductionDatum<std::array<double, 3>, funcl::Plus<>>>
     170             :         reduction_data{measurement_id, mass_a, mass_b, first_moment_a,
     171             :                        first_moment_b};
     172             :     Parallel::contribute_to_reduction<
     173             :         measurements::PostReductionSendBNSStarCentersToControlSystem<
     174             :             ControlSystems>>(std::move(reduction_data), my_proxy,
     175             :                              reduction_target_proxy);
     176             :   }
     177             : 
     178           0 :   using is_ready_argument_tags = tmpl::list<>;
     179             : 
     180             :   template <typename Metavariables, typename ArrayIndex, typename Component>
     181           0 :   bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
     182             :                 const ArrayIndex& /*array_index*/,
     183             :                 const Component* const /*component*/) const {
     184             :     return true;
     185             :   }
     186             : 
     187           1 :   bool needs_evolved_variables() const override { return true; }
     188             : };
     189             : 
     190             : /// \cond
     191             : template <typename ControlSystems>
     192             : PUP::able::PUP_ID BNSEvent<ControlSystems>::my_PUP_ID = 0;  // NOLINT
     193             : /// \endcond
     194             : 
     195             : namespace measurements {
     196           0 : namespace Tags {
     197             : /// \ingroup DataBoxTagsGroup
     198             : /// \ingroup ControlSystemGroup
     199             : /// DataBox tag for location of neutron star center (or more accurately, center
     200             : /// of mass of the matter in the x>0 (label A) or x<0 (label B) region, in grid
     201             : /// coordinates).
     202             : template <::domain::ObjectLabel Center>
     203           1 : struct NeutronStarCenter : db::SimpleTag {
     204           0 :   using type = std::array<double, 3>;
     205             : };
     206             : }  // namespace Tags
     207             : 
     208             : /*!
     209             :  * \brief Measurement providing the location of the center of mass of the matter
     210             :  * in the \f$x>0\f$ and \f$x<0\f$ regions (assumed to correspond to the center
     211             :  * of mass of the two neutron stars in a BNS merger).
     212             :  *
     213             :  * \details We use Events::Tags::ObserverXXX for tags that might need to be
     214             :  * retrieved from either the Subcell or DG grid.
     215             :  */
     216           1 : struct BothNSCenters : tt::ConformsTo<protocols::Measurement> {
     217           0 :   struct FindTwoCenters : tt::ConformsTo<protocols::Submeasurement> {
     218           0 :     static std::string name() { return "BothNSCenters::FindTwoCenters"; }
     219             :     /// Unused tag needed to conform to the submeasurement protocol.
     220             :     template <typename ControlSystems>
     221           1 :     using interpolation_target_tag = void;
     222             : 
     223             :     template <typename ControlSystems>
     224           0 :     using event = BNSEvent<ControlSystems>;
     225             :   };
     226             :   /// List of submeasurements used by this measurement -- only FindTwoCenters
     227             :   /// here.
     228           1 :   using submeasurements = tmpl::list<FindTwoCenters>;
     229             : };
     230             : 
     231             : /*!
     232             :  * \brief Simple action called after reduction of the center of mass data.
     233             :  *
     234             :  * \details `mass_a`, `mass_b`, `first_moment_a`, and `first_moment_b` will
     235             :  * contain the reduced data for the integral of the density (and its first
     236             :  * moment) in the x>=0 (A label) and x<0 (B label) regions. This action
     237             :  * calculates the center of mass in each region, and sends the result to the
     238             :  * control system.
     239             :  *
     240             :  * If the `control_system::Tags::WriteDataToDisk` tag is true, then this will
     241             :  * also write the centers of mass to the `/ControlSystems/BnsCenters` subfile of
     242             :  * the reductions h5 file. The columns of the file are
     243             :  *
     244             :  * - %Time
     245             :  * - Center_A_x
     246             :  * - Center_A_y
     247             :  * - Center_A_z
     248             :  * - Center_B_x
     249             :  * - Center_B_y
     250             :  * - Center_B_z
     251             :  */
     252             : template <typename ControlSystems>
     253           1 : struct PostReductionSendBNSStarCentersToControlSystem {
     254             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
     255             :             typename ArrayIndex>
     256           0 :   static void apply(db::DataBox<DbTags>& /*box*/,
     257             :                     Parallel::GlobalCache<Metavariables>& cache,
     258             :                     const ArrayIndex& /*array_index*/,
     259             :                     const LinkedMessageId<double>& measurement_id,
     260             :                     const double& mass_a, const double& mass_b,
     261             :                     const std::array<double, 3>& first_moment_a,
     262             :                     const std::array<double, 3>& first_moment_b) {
     263             :     // Function called after reduction of the CoM data.
     264             :     // Calculate CoM from integrals
     265             :     std::array<double, 3> center_a = first_moment_a / mass_a;
     266             :     std::array<double, 3> center_b = first_moment_b / mass_b;
     267             :     const auto center_databox = db::create<
     268             :         db::AddSimpleTags<Tags::NeutronStarCenter<::domain::ObjectLabel::A>,
     269             :                           Tags::NeutronStarCenter<::domain::ObjectLabel::B>>>(
     270             :         center_a, center_b);
     271             :     // Send results to the control system(s)
     272             :     RunCallbacks<BothNSCenters::FindTwoCenters, ControlSystems>::apply(
     273             :         center_databox, cache, measurement_id);
     274             : 
     275             :     if (Parallel::get<control_system::Tags::WriteDataToDisk>(cache)) {
     276             :       std::vector<double> data_to_write{
     277             :           measurement_id.id, center_a[0], center_a[1], center_a[2],
     278             :           center_b[0],       center_b[1], center_b[2]};
     279             : 
     280             :       auto& writer_proxy = Parallel::get_parallel_component<
     281             :           observers::ObserverWriter<Metavariables>>(cache);
     282             : 
     283             :       Parallel::threaded_action<
     284             :           observers::ThreadedActions::WriteReductionDataRow>(
     285             :           // Node 0 is always the writer
     286             :           writer_proxy[0], subfile_path_, legend_,
     287             :           std::make_tuple(std::move(data_to_write)));
     288             :     }
     289             :   }
     290             : 
     291             :  private:
     292           0 :   const static inline std::vector<std::string> legend_{
     293             :       "Time",       "Center_A_x", "Center_A_y", "Center_A_z",
     294             :       "Center_B_x", "Center_B_y", "Center_B_z"};
     295           0 :   const static inline std::string subfile_path_{"/ControlSystems/BnsCenters"};
     296             : };
     297             : }  // namespace measurements
     298             : }  // namespace control_system

Generated by: LCOV version 1.14