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

Generated by: LCOV version 1.14