LCOV - code coverage report
Current view: top level - include/mfem/equation_systems - ComplexEquationSystem.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 48 55 87.3 %
Date: 2026-05-29 20:35:17 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #ifdef MOOSE_MFEM_ENABLED
       2             : 
       3             : #pragma once
       4             : 
       5             : #include "libmesh/ignore_warnings.h"
       6             : #include "mfem/miniapps/common/pfem_extras.hpp"
       7             : #include "libmesh/restore_warnings.h"
       8             : #include "EquationSystem.h"
       9             : #include "MFEMComplexKernel.h"
      10             : #include "MFEMComplexIntegratedBC.h"
      11             : #include "MFEMComplexEssentialBC.h"
      12             : 
      13             : namespace Moose::MFEM
      14             : {
      15             : /*
      16             : Class to store weak form components (bilinear and linear forms, and optionally
      17             : mixed and nonlinear forms) and build methods
      18             : */
      19             : class ComplexEquationSystem : public EquationSystem
      20             : {
      21             : 
      22             : public:
      23          62 :   ComplexEquationSystem() = default;
      24          62 :   ~ComplexEquationSystem() = default;
      25             : 
      26             :   // Build forms
      27             :   virtual void Init(GridFunctions & gridfunctions,
      28             :                     ComplexGridFunctions & cmplx_gridfunctions,
      29             :                     mfem::AssemblyLevel assembly_level) override;
      30             : 
      31             :   ///Nonlinear Mult (Used by Newton-solver not necessarily nonlinear)
      32             :   virtual void Mult(const mfem::Vector & x, mfem::Vector & y) const override;
      33             : 
      34             :   /// Build all forms comprising this EquationSystem
      35             :   virtual void BuildEquationSystem() override;
      36             : 
      37             :   /// Build linear forms and eliminate constrained DoFs
      38             :   virtual void BuildLinearForms() override;
      39             : 
      40             :   /// Build bilinear forms (diagonal Jacobian contributions)
      41             :   virtual void BuildBilinearForms() override;
      42             : 
      43             :   /// Apply essential BC(s) associated with var_name to set true DoFs of trial_gf and update
      44             :   /// markers of all essential boundaries
      45             :   virtual void ApplyComplexEssentialBC(const std::string & var_name,
      46             :                                        mfem::ParComplexGridFunction & trial_gf,
      47             :                                        mfem::Array<int> & global_ess_markers);
      48             :   /// Update all essentially constrained true DoF markers and values on boundaries
      49             :   virtual void ApplyEssentialBCs() override;
      50             : 
      51             :   /// Add complex kernels
      52             :   void AddComplexKernel(std::shared_ptr<MFEMComplexKernel> kernel);
      53             : 
      54             :   /// Add complex integrated BCs
      55             :   void AddComplexIntegratedBC(std::shared_ptr<MFEMComplexIntegratedBC> bc);
      56             : 
      57             :   /// Add complex essential BCs
      58             :   void AddComplexEssentialBCs(std::shared_ptr<MFEMComplexEssentialBC> bc);
      59             : 
      60             :   /// Form matrix-free representation of system operator.
      61             :   /// Used when EquationSystem assembly level is set to 'FULL', 'ELEMENT', 'PARTIAL', or 'NONE'.
      62             :   virtual void FormSystemOperator(mfem::OperatorHandle & op,
      63             :                                   mfem::BlockVector & trueX,
      64             :                                   mfem::BlockVector & trueRHS) override;
      65             : 
      66             :   /// Form matrix representation of system operator as a HypreParMatrix.
      67             :   /// Used when EquationSystem assembly level is set to 'LEGACY'.
      68             :   virtual void FormSystemMatrix(mfem::OperatorHandle & op,
      69             :                                 mfem::BlockVector & trueX,
      70             :                                 mfem::BlockVector & trueRHS) override;
      71             : 
      72             :   /// Update variable from solution vector after solve
      73             :   virtual void SetTrialVariablesFromTrueVectors(const mfem::BlockVector & trueX) const override;
      74             : 
      75             :   /// Template method for applying BilinearFormIntegrators on domains from kernels to a SesquilinearForm
      76             :   template <class FormType>
      77             :   void ApplyDomainBLFIntegrators(
      78             :       const std::string & trial_var_name,
      79             :       const std::string & test_var_name,
      80             :       std::shared_ptr<FormType> form,
      81             :       NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> &
      82             :           kernels_map);
      83             : 
      84             :   /// Method for applying LinearFormIntegrators on domains from kernels to a ParComplexLinearForm
      85             :   inline void ApplyDomainLFIntegrators(
      86             :       const std::string & test_var_name,
      87             :       std::shared_ptr<mfem::ParComplexLinearForm> form,
      88             :       NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> &
      89             :           kernels_map);
      90             : 
      91             :   /// Template method for applying BilinearFormIntegrators on boudaries from kernels to a SesquilinearForm
      92             :   template <class FormType>
      93             :   void ApplyBoundaryBLFIntegrators(
      94             :       const std::string & trial_var_name,
      95             :       const std::string & test_var_name,
      96             :       std::shared_ptr<FormType> form,
      97             :       NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
      98             :           integrated_bc_map);
      99             : 
     100             :   /// Method for applying LinearFormIntegrators on boundaries from kernels to a ParComplexLinearForm
     101             :   inline void ApplyBoundaryLFIntegrators(
     102             :       const std::string & test_var_name,
     103             :       std::shared_ptr<mfem::ParComplexLinearForm> form,
     104             :       NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
     105             :           integrated_bc_map);
     106             : 
     107             :   // Complex Linear and Bilinear Forms
     108             :   NamedFieldsMap<mfem::ParSesquilinearForm> _slfs;
     109             :   NamedFieldsMap<mfem::ParComplexLinearForm> _clfs;
     110             : 
     111             :   // Complex kernels and integrated BCs
     112             :   NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>>
     113             :       _cmplx_kernels_map;
     114             :   NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>>
     115             :       _cmplx_integrated_bc_map;
     116             : 
     117             :   // Complex essential BCs
     118             :   NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexEssentialBC>>> _cmplx_essential_bc_map;
     119             : 
     120             :   /// Pointers to coupled variables not part of the reduced EquationSystem.
     121             :   ComplexGridFunctions _cmplx_eliminated_variables;
     122             : 
     123             :   /// Complex Gridfunctions holding essential constraints from Dirichlet BCs
     124             :   std::vector<std::unique_ptr<mfem::ParComplexGridFunction>> _cmplx_var_ess_constraints;
     125             : 
     126             :   // Pointer to complex GridFunctions to enable updates during nonlinear iterations
     127             :   Moose::MFEM::ComplexGridFunctions * _complex_gfuncs;
     128             : };
     129             : 
     130             : template <class FormType>
     131             : void
     132          41 : ComplexEquationSystem::ApplyDomainBLFIntegrators(
     133             :     const std::string & trial_var_name,
     134             :     const std::string & test_var_name,
     135             :     std::shared_ptr<FormType> form,
     136             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
     137             : {
     138          41 :   if (kernels_map.Has(test_var_name) && kernels_map.Get(test_var_name)->Has(trial_var_name))
     139             :   {
     140          41 :     auto kernels = kernels_map.GetRef(test_var_name).GetRef(trial_var_name);
     141         102 :     for (auto & kernel : kernels)
     142             :     {
     143          61 :       mfem::BilinearFormIntegrator * integ_real = kernel->getRealBFIntegrator();
     144          61 :       mfem::BilinearFormIntegrator * integ_imag = kernel->getImagBFIntegrator();
     145             : 
     146          61 :       if (integ_real || integ_imag)
     147             :       {
     148          61 :         kernel->isSubdomainRestricted()
     149          61 :             ? form->AddDomainIntegrator(
     150           0 :                   std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
     151          61 :             : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
     152             :       }
     153             :     }
     154          41 :   }
     155          41 : }
     156             : 
     157             : inline void
     158          41 : ComplexEquationSystem::ApplyDomainLFIntegrators(
     159             :     const std::string & test_var_name,
     160             :     std::shared_ptr<mfem::ParComplexLinearForm> form,
     161             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
     162             : {
     163          41 :   if (kernels_map.Has(test_var_name))
     164             :   {
     165          41 :     auto kernels = kernels_map.GetRef(test_var_name).GetRef(test_var_name);
     166         102 :     for (auto & kernel : kernels)
     167             :     {
     168          61 :       mfem::LinearFormIntegrator * integ_real = kernel->getRealLFIntegrator();
     169          61 :       mfem::LinearFormIntegrator * integ_imag = kernel->getImagLFIntegrator();
     170             : 
     171          61 :       if (integ_real || integ_imag)
     172             :       {
     173           0 :         kernel->isSubdomainRestricted()
     174           0 :             ? form->AddDomainIntegrator(
     175           0 :                   std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
     176           0 :             : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
     177             :       }
     178             :     }
     179          41 :   }
     180          41 : }
     181             : 
     182             : template <class FormType>
     183             : void
     184          41 : ComplexEquationSystem::ApplyBoundaryBLFIntegrators(
     185             :     const std::string & trial_var_name,
     186             :     const std::string & test_var_name,
     187             :     std::shared_ptr<FormType> form,
     188             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
     189             :         integrated_bc_map)
     190             : {
     191          47 :   if (integrated_bc_map.Has(test_var_name) &&
     192           6 :       integrated_bc_map.Get(test_var_name)->Has(trial_var_name))
     193             :   {
     194           6 :     auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(trial_var_name);
     195          18 :     for (auto & bc : bcs)
     196             :     {
     197          12 :       mfem::BilinearFormIntegrator * integ_real = bc->getRealBFIntegrator();
     198          12 :       mfem::BilinearFormIntegrator * integ_imag = bc->getImagBFIntegrator();
     199             : 
     200          12 :       if (integ_real || integ_imag)
     201             :       {
     202          12 :         bc->isBoundaryRestricted()
     203          36 :             ? form->AddBoundaryIntegrator(
     204          24 :                   std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
     205           0 :             : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
     206             :       }
     207             :     }
     208           6 :   }
     209          41 : }
     210             : 
     211             : inline void
     212          41 : ComplexEquationSystem::ApplyBoundaryLFIntegrators(
     213             :     const std::string & test_var_name,
     214             :     std::shared_ptr<mfem::ParComplexLinearForm> form,
     215             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
     216             :         integrated_bc_map)
     217             : {
     218          41 :   if (integrated_bc_map.Has(test_var_name))
     219             :   {
     220           6 :     auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(test_var_name);
     221          18 :     for (auto & bc : bcs)
     222             :     {
     223          12 :       mfem::LinearFormIntegrator * integ_real = bc->getRealLFIntegrator();
     224          12 :       mfem::LinearFormIntegrator * integ_imag = bc->getImagLFIntegrator();
     225             : 
     226          12 :       if (integ_real || integ_imag)
     227             :       {
     228           6 :         bc->isBoundaryRestricted()
     229          18 :             ? form->AddBoundaryIntegrator(
     230          12 :                   std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
     231           0 :             : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
     232             :       }
     233             :     }
     234           6 :   }
     235          41 : }
     236             : 
     237             : }
     238             : 
     239             : #endif

Generated by: LCOV version 1.14