LCOV - code coverage report
Current view: top level - models - spaceoperator.hpp (source / functions) Coverage Total Hit
Test: Palace Coverage Report Lines: 44.4 % 9 4
Test Date: 2025-10-23 22:45:05 Functions: - 0 0
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : 
       4              : #ifndef PALACE_MODELS_SPACE_OPERATOR_HPP
       5              : #define PALACE_MODELS_SPACE_OPERATOR_HPP
       6              : 
       7              : #include <complex>
       8              : #include <memory>
       9              : #include <vector>
      10              : #include <mfem.hpp>
      11              : #include "fem/fespace.hpp"
      12              : #include "linalg/operator.hpp"
      13              : #include "linalg/vector.hpp"
      14              : #include "models/farfieldboundaryoperator.hpp"
      15              : #include "models/lumpedportoperator.hpp"
      16              : #include "models/materialoperator.hpp"
      17              : #include "models/portexcitations.hpp"
      18              : #include "models/surfaceconductivityoperator.hpp"
      19              : #include "models/surfacecurrentoperator.hpp"
      20              : #include "models/surfaceimpedanceoperator.hpp"
      21              : #include "models/waveportoperator.hpp"
      22              : 
      23              : namespace palace
      24              : {
      25              : 
      26              : class IoData;
      27              : class Mesh;
      28              : 
      29              : //
      30              : // A class handling spatial discretization of the governing equations.
      31              : //
      32              : class SpaceOperator
      33              : {
      34              : private:
      35              :   const bool pc_mat_real;     // Use real-valued matrix for preconditioner
      36              :   const bool pc_mat_shifted;  // Use shifted mass matrix for preconditioner
      37              : 
      38              :   // Helper variables for log file printing.
      39              :   bool print_hdr, print_prec_hdr;
      40              : 
      41              :   // Perfect electrical conductor essential boundary condition attributes.
      42              :   mfem::Array<int> dbc_attr, aux_bdr_attr;
      43              :   std::vector<mfem::Array<int>> nd_dbc_tdof_lists, h1_dbc_tdof_lists, aux_bdr_tdof_lists;
      44              : 
      45              :   // Objects defining the finite element spaces for the electric field (Nedelec) and
      46              :   // magnetic flux density (Raviart-Thomas) on the given mesh. The H1 spaces are used for
      47              :   // various purposes throughout the code including postprocessing.
      48              :   std::vector<std::unique_ptr<mfem::ND_FECollection>> nd_fecs;
      49              :   std::vector<std::unique_ptr<mfem::H1_FECollection>> h1_fecs;
      50              :   std::vector<std::unique_ptr<mfem::RT_FECollection>> rt_fecs;
      51              :   FiniteElementSpaceHierarchy nd_fespaces, h1_fespaces, rt_fespaces;
      52              : 
      53              :   // Operator for domain material properties.
      54              :   MaterialOperator mat_op;
      55              : 
      56              :   // Operators for boundary conditions and source excitations.
      57              :   FarfieldBoundaryOperator farfield_op;
      58              :   SurfaceConductivityOperator surf_sigma_op;
      59              :   SurfaceImpedanceOperator surf_z_op;
      60              :   LumpedPortOperator lumped_port_op;
      61              :   WavePortOperator wave_port_op;
      62              :   SurfaceCurrentOperator surf_j_op;
      63              : 
      64              :   PortExcitations port_excitation_helper;
      65              : 
      66              :   mfem::Array<int> SetUpBoundaryProperties(const IoData &iodata, const mfem::ParMesh &mesh);
      67              :   void CheckBoundaryProperties();
      68              : 
      69              :   // Helper functions for building the bilinear forms corresponding to the discretized
      70              :   // operators in Maxwell's equations.
      71              :   void AddStiffnessCoefficients(double coeff, MaterialPropertyCoefficient &df,
      72              :                                 MaterialPropertyCoefficient &f);
      73              :   void AddStiffnessBdrCoefficients(double coeff, MaterialPropertyCoefficient &fb);
      74              :   void AddDampingCoefficients(double coeff, MaterialPropertyCoefficient &f);
      75              :   void AddDampingBdrCoefficients(double coeff, MaterialPropertyCoefficient &fb);
      76              :   void AddRealMassCoefficients(double coeff, MaterialPropertyCoefficient &f);
      77              :   void AddRealMassBdrCoefficients(double coeff, MaterialPropertyCoefficient &fb);
      78              :   void AddImagMassCoefficients(double coeff, MaterialPropertyCoefficient &f);
      79              :   void AddAbsMassCoefficients(double coeff, MaterialPropertyCoefficient &f);
      80              :   void AddExtraSystemBdrCoefficients(double omega, MaterialPropertyCoefficient &dfbr,
      81              :                                      MaterialPropertyCoefficient &dfbi,
      82              :                                      MaterialPropertyCoefficient &fbr,
      83              :                                      MaterialPropertyCoefficient &fbi);
      84              :   void AddRealPeriodicCoefficients(double coeff, MaterialPropertyCoefficient &f);
      85              :   void AddImagPeriodicCoefficients(double coeff, MaterialPropertyCoefficient &f);
      86              : 
      87              :   // Helper functions for excitation vector assembly.
      88              :   bool AddExcitationVector1Internal(int excitation_idx, Vector &RHS);
      89              :   bool AddExcitationVector2Internal(int excitation_idx, double omega, ComplexVector &RHS);
      90              : 
      91              :   // Helper functions to build the preconditioner matrix.
      92              :   void AssemblePreconditioner(std::complex<double> a0, std::complex<double> a1,
      93              :                               std::complex<double> a2, double a3,
      94              :                               std::vector<std::unique_ptr<Operator>> &br_vec,
      95              :                               std::vector<std::unique_ptr<Operator>> &br_aux_vec,
      96              :                               std::vector<std::unique_ptr<Operator>> &bi_vec,
      97              :                               std::vector<std::unique_ptr<Operator>> &bi_aux_vec);
      98              :   void AssemblePreconditioner(std::complex<double> a0, std::complex<double> a1,
      99              :                               std::complex<double> a2, double a3,
     100              :                               std::vector<std::unique_ptr<Operator>> &br_vec,
     101              :                               std::vector<std::unique_ptr<Operator>> &br_aux_vec);
     102              :   void AssemblePreconditioner(double a0, double a1, double a2, double a3,
     103              :                               std::vector<std::unique_ptr<Operator>> &br_vec,
     104              :                               std::vector<std::unique_ptr<Operator>> &br_aux_vec);
     105              : 
     106              : public:
     107              :   SpaceOperator(const IoData &iodata, const std::vector<std::unique_ptr<Mesh>> &mesh);
     108              : 
     109              :   // Return list of all PEC boundary true dofs for all finite element space levels.
     110              :   const std::vector<mfem::Array<int>> &GetNDDbcTDofLists() const
     111              :   {
     112              :     return nd_dbc_tdof_lists;
     113              :   }
     114              :   const std::vector<mfem::Array<int>> &GetH1DbcTDofLists() const
     115              :   {
     116              :     return h1_dbc_tdof_lists;
     117              :   }
     118              : 
     119              :   // Returns lists of all boundary condition true dofs, PEC included, for the auxiliary
     120              :   // H1 space hierarchy. These are all boundaries which affect the stiffness and damping
     121              :   // (K and C) matrices, used for nullspace corrections.
     122              :   const std::vector<mfem::Array<int>> &GetAuxBdrTDofLists() const
     123              :   {
     124              :     return aux_bdr_tdof_lists;
     125              :   }
     126              : 
     127              :   // Return material operator for postprocessing.
     128           75 :   const MaterialOperator &GetMaterialOp() const { return mat_op; }
     129              : 
     130              :   // Access to underlying BC operator objects for postprocessing.
     131           11 :   auto &GetLumpedPortOp() { return lumped_port_op; }
     132            0 :   auto &GetWavePortOp() { return wave_port_op; }
     133            8 :   auto &GetSurfaceCurrentOp() { return surf_j_op; }
     134              :   const auto &GetLumpedPortOp() const { return lumped_port_op; }
     135              :   const auto &GetWavePortOp() const { return wave_port_op; }
     136              :   const auto &GetSurfaceCurrentOp() const { return surf_j_op; }
     137              : 
     138            5 :   const auto &GetPortExcitations() const { return port_excitation_helper; }
     139              : 
     140              :   // Return the parallel finite element space objects.
     141            0 :   auto &GetNDSpaces() { return nd_fespaces; }
     142              :   const auto &GetNDSpaces() const { return nd_fespaces; }
     143              :   auto &GetNDSpace() { return nd_fespaces.GetFinestFESpace(); }
     144              :   const auto &GetNDSpace() const { return nd_fespaces.GetFinestFESpace(); }
     145            0 :   auto &GetH1Spaces() { return h1_fespaces; }
     146              :   const auto &GetH1Spaces() const { return h1_fespaces; }
     147              :   auto &GetH1Space() { return h1_fespaces.GetFinestFESpace(); }
     148              :   const auto &GetH1Space() const { return h1_fespaces.GetFinestFESpace(); }
     149            0 :   auto &GetRTSpaces() { return rt_fespaces; }
     150              :   const auto &GetRTSpaces() const { return rt_fespaces; }
     151              :   auto &GetRTSpace() { return rt_fespaces.GetFinestFESpace(); }
     152              :   const auto &GetRTSpace() const { return rt_fespaces.GetFinestFESpace(); }
     153              : 
     154              :   // Access the underlying mesh object.
     155              :   const auto &GetMesh() const { return GetNDSpace().GetMesh(); }
     156              : 
     157              :   // Return the number of true (conforming) dofs on the finest ND space.
     158              :   auto GlobalTrueVSize() const { return GetNDSpace().GlobalTrueVSize(); }
     159              : 
     160              :   // Construct any part of the frequency-dependent complex linear system matrix:
     161              :   //                     A = K + iω C - ω² (Mr + i Mi) + A2(ω).
     162              :   // For time domain problems, any one of K, C, or M = Mr can be constructed. The argument
     163              :   // ω is required only for the constructing the "extra" matrix A2(ω).
     164              :   template <typename OperType>
     165              :   std::unique_ptr<OperType> GetStiffnessMatrix(Operator::DiagonalPolicy diag_policy);
     166              :   template <typename OperType>
     167              :   std::unique_ptr<OperType> GetDampingMatrix(Operator::DiagonalPolicy diag_policy);
     168              :   template <typename OperType>
     169              :   std::unique_ptr<OperType> GetMassMatrix(Operator::DiagonalPolicy diag_policy);
     170              :   template <typename OperType>
     171              :   std::unique_ptr<OperType> GetExtraSystemMatrix(double omega,
     172              :                                                  Operator::DiagonalPolicy diag_policy);
     173              : 
     174              :   // Construct the complete frequency or time domain system matrix using the provided
     175              :   // stiffness, damping, mass, and extra matrices:
     176              :   //                     A = a0 K + a1 C + a2 (Mr + i Mi) + A2.
     177              :   // It is assumed that the inputs have been constructed using previous calls to
     178              :   // GetSystemMatrix() and the returned operator does not inherit ownership of any of them.
     179              :   template <typename OperType, typename ScalarType>
     180              :   std::unique_ptr<OperType>
     181              :   GetSystemMatrix(ScalarType a0, ScalarType a1, ScalarType a2, const OperType *K,
     182              :                   const OperType *C, const OperType *M, const OperType *A2 = nullptr);
     183              : 
     184              :   // Construct the real, SPD matrix for weighted L2 or H(curl) inner products:
     185              :   //                           B = a0 Kr + a2 Mr .
     186              :   // It is assumed that the inputs have been constructed using previous calls to
     187              :   // GetSystemMatrix() and the returned operator does not inherit ownership of any of them.
     188              :   // If K or M have eliminated boundary conditions, they are not eliminated from the
     189              :   // returned operator.
     190              :   std::unique_ptr<Operator> GetInnerProductMatrix(double a0, double a2,
     191              :                                                   const ComplexOperator *K,
     192              :                                                   const ComplexOperator *M);
     193              : 
     194              :   // Construct the matrix for frequency or time domain linear system preconditioning. If it
     195              :   // is real-valued (Mr > 0, Mi < 0, |Mr + Mi| is done on the material property coefficient,
     196              :   // not the matrix entries themselves):
     197              :   //             B = a0 K + a1 C -/+ a2 |Mr + Mi| + A2r(a3) + A2i(a3).
     198              :   template <typename OperType, typename ScalarType>
     199              :   std::unique_ptr<OperType> GetPreconditionerMatrix(ScalarType a0, ScalarType a1,
     200              :                                                     ScalarType a2, double a3);
     201              : 
     202              :   // Construct and return the discrete curl or gradient matrices.
     203              :   const Operator &GetGradMatrix() const
     204              :   {
     205              :     return GetNDSpace().GetDiscreteInterpolator(GetH1Space());
     206              :   }
     207              :   const Operator &GetCurlMatrix() const
     208              :   {
     209            0 :     return GetRTSpace().GetDiscreteInterpolator(GetNDSpace());
     210              :   }
     211              : 
     212              :   // Assemble the right-hand side source term vector for an incident field or current source
     213              :   // applied on specified excited boundaries. The return value indicates whether or not the
     214              :   // excitation is nonzero (and thus is true most of the time).
     215              :   bool GetExcitationVector(int excitation_idx, Vector &RHS);
     216              :   bool GetExcitationVector(int excitation_idx, double omega, ComplexVector &RHS);
     217              : 
     218              :   // Separate out RHS vector as RHS = iω RHS1 + RHS2(ω). The return value indicates whether
     219              :   // or not the excitation is nonzero (and thus is true most of the time).
     220              :   bool GetExcitationVector1(int excitation_idx, ComplexVector &RHS1);
     221              :   bool GetExcitationVector2(int excitation_idx, double omega, ComplexVector &RHS2);
     222              : 
     223              :   // Construct a constant or randomly initialized vector which satisfies the PEC essential
     224              :   // boundary conditions.
     225              :   void GetRandomInitialVector(ComplexVector &v);
     226              :   void GetConstantInitialVector(ComplexVector &v);
     227              : 
     228              :   // Get the associated MPI communicator.
     229              :   MPI_Comm GetComm() const { return GetNDSpace().GetComm(); }
     230              : };
     231              : 
     232              : }  // namespace palace
     233              : 
     234              : #endif  // PALACE_MODELS_SPACE_OPERATOR_HPP
        

Generated by: LCOV version 2.0-1