SpECTRE Documentation Coverage Report
Current view: top level - ControlSystem/Measurements - BNSCenterOfMass.hpp Hit Total Coverage
Commit: 5db9f551b6705558889446086cdf9fac3b14a186 Lines: 8 18 44.4 %
Date: 2023-12-05 01:47:12
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/DataBox/Tag.hpp"
      16             : #include "DataStructures/LinkedMessageId.hpp"
      17             : #include "DataStructures/Tensor/TypeAliases.hpp"
      18             : #include "Domain/Structure/ObjectLabel.hpp"
      19             : #include "IO/Observer/ObserverComponent.hpp"
      20             : #include "IO/Observer/ReductionActions.hpp"
      21             : #include "NumericalAlgorithms/LinearOperators/DefiniteIntegral.hpp"
      22             : #include "Parallel/Invoke.hpp"
      23             : #include "Parallel/Reduction.hpp"
      24             : #include "ParallelAlgorithms/Events/Tags.hpp"
      25             : #include "Utilities/ProtocolHelpers.hpp"
      26             : #include "Utilities/StdArrayHelpers.hpp"
      27             : #include "Utilities/TMPL.hpp"
      28             : 
      29             : /// \cond
      30             : class DataVector;
      31             : template <size_t VolumeDim>
      32             : class ElementId;
      33             : template <size_t Dim>
      34             : class Mesh;
      35             : namespace control_system::Tags {
      36             : struct WriteDataToDisk;
      37             : }  // namespace control_system::Tags
      38             : namespace Parallel {
      39             : template <typename Metavariables>
      40             : class GlobalCache;
      41             : }  // namespace Parallel
      42             : namespace domain::Tags {
      43             : template <size_t Dim>
      44             : struct Mesh;
      45             : template <size_t Dim, typename Frame>
      46             : struct Coordinates;
      47             : }  // namespace domain::Tags
      48             : namespace grmhd::ValenciaDivClean::Tags {
      49             : struct TildeD;
      50             : }
      51             : /// \endcond
      52             : 
      53           0 : namespace control_system::measurements {
      54             : 
      55             : template <typename ControlSystems>
      56             : struct PostReductionSendBNSStarCentersToControlSystem;
      57             : 
      58           0 : namespace Tags {
      59             : /// \ingroup DataBoxTagsGroup
      60             : /// \ingroup ControlSystemGroup
      61             : /// DataBox tag for location of neutron star center (or more accurately, center
      62             : /// of mass of the matter in the x>0 (label A) or x<0 (label B) region, in grid
      63             : /// coordinates).
      64             : template <::domain::ObjectLabel Center>
      65           1 : struct NeutronStarCenter : db::SimpleTag {
      66           0 :   using type = std::array<double, 3>;
      67             : };
      68             : }  // namespace Tags
      69             : 
      70             : /*!
      71             :  * \brief  Factored Center of Mass calculation (for easier testing)
      72             :  *
      73             :  * \details This function computes the integral of tildeD (assumed to be the
      74             :  * conservative baryon density in the inertial frame), as well as its first
      75             :  * moment in the grid frame. The integrals are limited to \f$x>0\f$ (label A) or
      76             :  * \f$x<0\f$ (label B).
      77             :  *
      78             :  * \param mass_a Integral of tildeD (x > 0)
      79             :  * \param mass_b Integral of tildeD (x < 0)
      80             :  * \param first_moment_A First moment of integral of tildeD (x > 0)
      81             :  * \param first_moment_B First moment of integral of tildeD (x < 0)
      82             :  * \param mesh The mesh
      83             :  * \param inv_det_jacobian The inverse determinant of the jacobian of the map
      84             :  * between logical and inertial coordinates \param tilde_d TildeD on the mesh
      85             :  * \param x_grid The coordinates in the grid frame
      86             :  */
      87           1 : void center_of_mass_integral_on_element(
      88             :     const gsl::not_null<double*> mass_a, const gsl::not_null<double*> mass_b,
      89             :     const gsl::not_null<std::array<double, 3>*> first_moment_A,
      90             :     const gsl::not_null<std::array<double, 3>*> first_moment_B,
      91             :     const Mesh<3>& mesh, const Scalar<DataVector>& inv_det_jacobian,
      92             :     const Scalar<DataVector>& tilde_d,
      93             :     const tnsr::I<DataVector, 3, Frame::Grid>& x_grid);
      94             : 
      95             : /*!
      96             :  * \brief Measurement providing the location of the center of mass of the matter
      97             :  * in the \f$x>0\f$ and \f$x<0\f$ regions (assumed to correspond to the center
      98             :  * of mass of the two neutron stars in a BNS merger).
      99             :  *
     100             :  * \details We use Events::Tags::ObserverXXX for tags that might need to be
     101             :  * retrieved from either the Subcell or DG grid.
     102             :  */
     103           1 : struct BothNSCenters : tt::ConformsTo<protocols::Measurement> {
     104           0 :   struct FindTwoCenters : tt::ConformsTo<protocols::Submeasurement> {
     105           0 :     static std::string name() { return "BothNSCenters::FindTwoCenters"; }
     106             :     /// Unused tag needed to conform to the submeasurement protocol.
     107             :     template <typename ControlSystems>
     108           1 :     using interpolation_target_tag = void;
     109             : 
     110           0 :     using compute_tags_for_observation_box = tmpl::list<>;
     111             : 
     112             :     /// Tags for the arguments to the apply function.
     113           1 :     using argument_tags =
     114             :         tmpl::list<Events::Tags::ObserverMesh<3>,
     115             :                    Events::Tags::ObserverDetInvJacobian<Frame::ElementLogical,
     116             :                                                         Frame::Inertial>,
     117             :                    grmhd::ValenciaDivClean::Tags::TildeD,
     118             :                    Events::Tags::ObserverCoordinates<3, Frame::Grid>>;
     119             : 
     120             :     /// Calculate integrals needed for CoM computation on each element,
     121             :     /// then reduce the data.
     122             :     template <typename Metavariables, typename ParallelComponent,
     123             :               typename ControlSystems>
     124           1 :     static void apply(const Mesh<3>& mesh,
     125             :                       const Scalar<DataVector>& inv_det_jacobian,
     126             :                       const Scalar<DataVector>& tilde_d,
     127             :                       const tnsr::I<DataVector, 3, Frame::Grid> x_grid,
     128             :                       const LinkedMessageId<double>& measurement_id,
     129             :                       Parallel::GlobalCache<Metavariables>& cache,
     130             :                       const ElementId<3>& array_index,
     131             :                       const ParallelComponent* const /*meta*/,
     132             :                       ControlSystems /*meta*/) {
     133             :       // Initialize integrals and perform local calculations
     134             :       double mass_a = 0.;
     135             :       double mass_b = 0.;
     136             :       std::array<double, 3> first_moment_a = {0., 0., 0.};
     137             :       std::array<double, 3> first_moment_b = {0., 0., 0.};
     138             :       center_of_mass_integral_on_element(&mass_a, &mass_b, &first_moment_a,
     139             :                                          &first_moment_b, mesh,
     140             :                                          inv_det_jacobian, tilde_d, x_grid);
     141             : 
     142             :       // Reduction
     143             :       auto my_proxy = Parallel::get_parallel_component<ParallelComponent>(
     144             :           cache)[array_index];
     145             :       // We need a place to run RunCallback on... this does not need to be
     146             :       // the control system using the CoM data.
     147             :       auto& reduction_target_proxy = Parallel::get_parallel_component<
     148             :           ControlComponent<Metavariables, tmpl::front<ControlSystems>>>(cache);
     149             :       Parallel::ReductionData<
     150             :           Parallel::ReductionDatum<LinkedMessageId<double>,
     151             :                                    funcl::AssertEqual<>>,
     152             :           Parallel::ReductionDatum<double, funcl::Plus<>>,
     153             :           Parallel::ReductionDatum<double, funcl::Plus<>>,
     154             :           Parallel::ReductionDatum<std::array<double, 3>, funcl::Plus<>>,
     155             :           Parallel::ReductionDatum<std::array<double, 3>, funcl::Plus<>>>
     156             :           reduction_data{measurement_id, mass_a, mass_b, first_moment_a,
     157             :                          first_moment_b};
     158             :       Parallel::contribute_to_reduction<
     159             :           PostReductionSendBNSStarCentersToControlSystem<ControlSystems>>(
     160             :           std::move(reduction_data), my_proxy, reduction_target_proxy);
     161             :     }
     162             :   };
     163             :   /// List of submeasurements used by this measurement -- only FindTwoCenters
     164             :   /// here.
     165           1 :   using submeasurements = tmpl::list<FindTwoCenters>;
     166             : };
     167             : 
     168             : /*!
     169             :  * \brief Simple action called after reduction of the center of mass data.
     170             :  *
     171             :  * \details `mass_a`, `mass_b`, `first_moment_a`, and `first_moment_b` will
     172             :  * contain the reduced data for the integral of the density (and its first
     173             :  * moment) in the x>=0 (A label) and x<0 (B label) regions. This action
     174             :  * calculates the center of mass in each region, and sends the result to the
     175             :  * control system.
     176             :  *
     177             :  * If the `control_system::Tags::WriteDataToDisk` tag is true, then this will
     178             :  * also write the centers of mass to the `/ControlSystems/BnsCenters` subfile of
     179             :  * the reductions h5 file. The columns of the file are
     180             :  *
     181             :  * - %Time
     182             :  * - Center_A_x
     183             :  * - Center_A_y
     184             :  * - Center_A_z
     185             :  * - Center_B_x
     186             :  * - Center_B_y
     187             :  * - Center_B_z
     188             :  */
     189             : template <typename ControlSystems>
     190           1 : struct PostReductionSendBNSStarCentersToControlSystem {
     191             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
     192             :             typename ArrayIndex>
     193           0 :   static void apply(db::DataBox<DbTags>& /*box*/,
     194             :                     Parallel::GlobalCache<Metavariables>& cache,
     195             :                     const ArrayIndex& /*array_index*/,
     196             :                     const LinkedMessageId<double>& measurement_id,
     197             :                     const double& mass_a, const double& mass_b,
     198             :                     const std::array<double, 3>& first_moment_a,
     199             :                     const std::array<double, 3>& first_moment_b) {
     200             :     // Function called after reduction of the CoM data.
     201             :     // Calculate CoM from integrals
     202             :     std::array<double, 3> center_a = first_moment_a / mass_a;
     203             :     std::array<double, 3> center_b = first_moment_b / mass_b;
     204             :     const auto center_databox = db::create<
     205             :         db::AddSimpleTags<Tags::NeutronStarCenter<::domain::ObjectLabel::A>,
     206             :                           Tags::NeutronStarCenter<::domain::ObjectLabel::B>>>(
     207             :         center_a, center_b);
     208             :     // Send results to the control system(s)
     209             :     RunCallbacks<BothNSCenters::FindTwoCenters, ControlSystems>::apply(
     210             :         center_databox, cache, measurement_id);
     211             : 
     212             :     if (Parallel::get<control_system::Tags::WriteDataToDisk>(cache)) {
     213             :       std::vector<double> data_to_write{
     214             :           measurement_id.id, center_a[0], center_a[1], center_a[2],
     215             :           center_b[0],       center_b[1], center_b[2]};
     216             : 
     217             :       auto& writer_proxy = Parallel::get_parallel_component<
     218             :           observers::ObserverWriter<Metavariables>>(cache);
     219             : 
     220             :       Parallel::threaded_action<
     221             :           observers::ThreadedActions::WriteReductionDataRow>(
     222             :           // Node 0 is always the writer
     223             :           writer_proxy[0], subfile_path_, legend_,
     224             :           std::make_tuple(std::move(data_to_write)));
     225             :     }
     226             :   }
     227             : 
     228             :  private:
     229           0 :   const static inline std::vector<std::string> legend_{
     230             :       "Time",       "Center_A_x", "Center_A_y", "Center_A_z",
     231             :       "Center_B_x", "Center_B_y", "Center_B_z"};
     232           0 :   const static inline std::string subfile_path_{"/ControlSystems/BnsCenters"};
     233             : };
     234             : 
     235             : }  // namespace control_system::measurements

Generated by: LCOV version 1.14