LCOV - code coverage report
Current view: top level - src/FieldLayout - SubFieldLayout.h (source / functions) Coverage Total Hit
Test: final_report.info Lines: 100.0 % 1 1
Test Date: 2025-09-02 12:20:15 Functions: 50.0 % 12 6

            Line data    Source code
       1              : //
       2              : // Class SubFieldLayout
       3              : // SubFieldLayout provides a layout for a sub-region of a larger field.
       4              : // It ensures that the sub-region is partitioned in the same way as the original FieldLayout,
       5              : // maintaining consistent parallel decomposition and neighbor relationships within the sub-region.
       6              : //
       7              : #ifndef IPPL_SUB_FIELD_LAYOUT_H
       8              : #define IPPL_SUB_FIELD_LAYOUT_H
       9              : 
      10              : #include <array>
      11              : #include <iostream>
      12              : #include <map>
      13              : #include <vector>
      14              : 
      15              : #include "Types/ViewTypes.h"
      16              : 
      17              : #include "Communicate/Communicator.h"
      18              : #include "FieldLayout/FieldLayout.h"
      19              : 
      20              : namespace ippl {
      21              : 
      22              :     /**
      23              :      * @class SubFieldLayout
      24              :      * @brief SubFieldLayout provides a layout for a sub-region of a larger field
      25              :      * 
      26              :      * SubFieldLayout extends FieldLayout to handle sub-regions of a larger computational domain.
      27              :      * It ensures that the sub-region is partitioned in the same way as the original FieldLayout,
      28              :      * maintaining consistent parallel decomposition and neighbor relationships within the sub-region.
      29              :      * 
      30              :      * @par Important Constraint:
      31              :      * SubFieldLayout only allows for sub-layouts that do NOT leave local domains empty.
      32              :      * All MPI ranks must have at least some portion of the sub-domain assigned to them.
      33              :      * If a sub-domain would result in empty local domains for some ranks, an exception
      34              :      * will be thrown during initialization.
      35              :      * 
      36              :      * @tparam Dim Number of spatial dimensions
      37              :      */
      38              :     template <unsigned Dim>
      39              :     class SubFieldLayout : public FieldLayout<Dim> {
      40              :     public:
      41              :         using NDIndex_t        = NDIndex<Dim>;
      42              :         using view_type        = typename detail::ViewType<NDIndex_t, 1>::view_type;
      43              :         using host_mirror_type = typename view_type::host_mirror_type;
      44              : 
      45              :         /**
      46              :          * @brief Default constructor, which should only be used if you are going to
      47              :          * call 'initialize' soon after (before using in any context)
      48              :          * 
      49              :          * @param communicator MPI communicator to use (defaults to MPI_COMM_WORLD)
      50              :          */
      51              :         SubFieldLayout(const mpi::Communicator& = MPI_COMM_WORLD);
      52              : 
      53              :         /**
      54              :          * @brief Constructor that creates a SubFieldLayout for a sub-region of a larger domain
      55              :          * 
      56              :          * @param communicator MPI communicator to use
      57              :          * @param domain The full domain that defines the partitioning
      58              :          * @param subDomain The sub-region within the full domain, which is partitioned in the same way as the fullomain
      59              :          * @param decomp Array specifying which dimensions should be parallel
      60              :          * @param isAllPeriodic Whether all dimensions have periodic boundary conditions
      61              :          */
      62              :         SubFieldLayout(mpi::Communicator, const NDIndex<Dim>& domain, const NDIndex<Dim>& subDomain, std::array<bool, Dim> decomp,
      63              :                     bool isAllPeriodic = false);
      64              : 
      65              :         /**
      66              :          * @brief Constructor for full-domain layout.
      67              :          * 
      68              :          * @param communicator MPI communicator to use
      69              :          * @param domain The full domain that defines the partitioning and is used as the sub-domain simultaneously
      70              :          * @param decomp Array specifying which dimensions should be parallel
      71              :          * @param isAllPeriodic Whether all dimensions have periodic boundary conditions
      72              :          */
      73              :         SubFieldLayout(mpi::Communicator, const NDIndex<Dim>& domain, std::array<bool, Dim> decomp,
      74              :                     bool isAllPeriodic = false);
      75              : 
      76              :         /**
      77              :          * @brief Destructor: Everything deletes itself automatically
      78              :          */
      79          768 :         virtual ~SubFieldLayout() = default;
      80              :         
      81              :         /**
      82              :          * @brief Initializes a SubFieldLayout with the sub-domain partitioned in the same way
      83              :          * as the original FieldLayout partitiones the full domain
      84              :          * 
      85              :          * @param domain The full domain to be partitioned
      86              :          * @param subDomain The sub-region within the full domain
      87              :          * @param decomp Array specifying which dimensions should be parallel
      88              :          * @param isAllPeriodic Whether all dimensions have periodic boundary conditions
      89              :          */
      90              :         void initialize(const NDIndex<Dim>& domain, const NDIndex<Dim>& subDomain, std::array<bool, Dim> decomp,
      91              :             bool isAllPeriodic = false);
      92              :             
      93              :         /**
      94              :          * @brief Initializes a SubFieldLayout using the domain as both the full domain and sub-domain
      95              :          * 
      96              :          * @param domain The domain to be partitioned
      97              :          * @param decomp Array specifying which dimensions should be parallel
      98              :          * @param isAllPeriodic Whether all dimensions have periodic boundary conditions
      99              :          */
     100              :         void initialize(const NDIndex<Dim>& domain, std::array<bool, Dim> decomp,
     101              :             bool isAllPeriodic = false);
     102              : 
     103              :         /**
     104              :          * @brief Return the original domain before sub-region extraction
     105              :          * 
     106              :          * @return Reference to the original full domain
     107              :          */
     108              :         const NDIndex<Dim>& getOriginDomain() const { return originDomain_m; }
     109              :                 
     110              :         /**
     111              :          * @brief Compare SubFieldLayouts to see if they represent the same domain
     112              :          * 
     113              :          * @tparam Dim2 Dimension of the other SubFieldLayout
     114              :          * @param x The other SubFieldLayout to compare with
     115              :          * @return true if both the current domain, origin domain and local domains match
     116              :          */
     117              :         template <unsigned Dim2>
     118              :         bool operator==(const SubFieldLayout<Dim2>& x) const {
     119              :             // Ensure the dimensions match
     120              :             if (Dim2 != Dim) {
     121              :                 return false;
     122              :             }
     123              : 
     124              :             // Check if the original and global domains match
     125              :             if (originDomain_m != x.getOriginDomain() || this->gDomain_m != x.getDomain()) {
     126              :                 return false;
     127              :             }
     128              : 
     129              :             // Ensure the local domains match
     130              :             for (unsigned int rank = 0; rank < this->comm.size(); ++rank) {
     131              :                 if (this->hLocalDomains_m(rank) != x.getLocalNDIndex(rank)) {
     132              :                     return false;
     133              :                 }
     134              :             }
     135              : 
     136              :             // If all checks passed, the SubFieldLayouts matche
     137              :             return true;
     138              :         }
     139              : 
     140              :         /**
     141              :          * @brief Compare SubFieldLayout to a FieldLayout to see if they represent the same domain
     142              :          * 
     143              :          * @tparam Dim2 Dimension of the FieldLayout
     144              :          * @param x The FieldLayout to compare with
     145              :          * @return true if the SubFieldLayout's domain equals its original domain and matches the FieldLayout's domain and local domains
     146              :          */
     147              :         template <unsigned Dim2>
     148              :         bool operator==(const FieldLayout<Dim2>& x) const {
     149              :             // Ensure the dimensions match
     150              :             if (Dim2 != Dim) {
     151              :                 return false;
     152              :             }
     153              : 
     154              :             // Check if the global domain matches the original domain and the FieldLayout's domain
     155              :             if (this->gDomain_m != originDomain_m || this->gDomain_m != x.getDomain()) {
     156              :                 return false;
     157              :             }
     158              : 
     159              :             // Ensure the local domains match
     160              :             for (unsigned int rank = 0; rank < this->comm.size(); ++rank) {
     161              :                 if (this->hLocalDomains_m(rank) != x.getLocalNDIndex(rank)) {
     162              :                     return false;
     163              :                 }
     164              :             }
     165              : 
     166              :             // If all checks passed, the SubFieldLayout matches the FieldLayout
     167              :             return true;
     168              :         }
     169              : 
     170              :     private:
     171              :         /**
     172              :          * @brief Original global domain in which the sub-field is defined
     173              :          * 
     174              :          * This stores the full domain before any sub-region extraction,
     175              :          * allowing comparison with regular FieldLayouts.
     176              :          */
     177              :         NDIndex_t originDomain_m;
     178              :     };
     179              : }  // namespace ippl
     180              : 
     181              : #include "FieldLayout/SubFieldLayout.hpp"
     182              : 
     183              : #endif
        

Generated by: LCOV version 2.0-1