LCOV - code coverage report
Current view: top level - include/mfem/equation_systems - ComplexEquationSystem.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: fa5e60 Lines: 48 56 85.7 %
Date: 2026-06-24 08:03:36 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             : 
      22             : public:
      23          63 :   ComplexEquationSystem() = default;
      24          63 :   ~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           0 :   virtual bool Complex() const override { return true; }
     108             : 
     109             : protected:
     110             :   // Complex Linear and Bilinear Forms
     111             :   NamedFieldsMap<mfem::ParSesquilinearForm> _slfs;
     112             :   NamedFieldsMap<mfem::ParComplexLinearForm> _clfs;
     113             : 
     114             :   // Complex kernels and integrated BCs
     115             :   NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>>
     116             :       _cmplx_kernels_map;
     117             :   NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>>
     118             :       _cmplx_integrated_bc_map;
     119             : 
     120             :   // Complex essential BCs
     121             :   NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexEssentialBC>>> _cmplx_essential_bc_map;
     122             : 
     123             :   /// Pointers to coupled variables not part of the reduced EquationSystem.
     124             :   ComplexGridFunctions _cmplx_eliminated_variables;
     125             : 
     126             :   /// Complex Gridfunctions holding essential constraints from Dirichlet BCs
     127             :   std::vector<std::unique_ptr<mfem::ParComplexGridFunction>> _cmplx_var_ess_constraints;
     128             : 
     129             :   // Pointer to complex GridFunctions to enable updates during nonlinear iterations
     130             :   Moose::MFEM::ComplexGridFunctions * _complex_gfuncs;
     131             : };
     132             : 
     133             : template <class FormType>
     134             : void
     135          42 : ComplexEquationSystem::ApplyDomainBLFIntegrators(
     136             :     const std::string & trial_var_name,
     137             :     const std::string & test_var_name,
     138             :     std::shared_ptr<FormType> form,
     139             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
     140             : {
     141          42 :   if (kernels_map.Has(test_var_name) && kernels_map.Get(test_var_name)->Has(trial_var_name))
     142             :   {
     143          42 :     auto kernels = kernels_map.GetRef(test_var_name).GetRef(trial_var_name);
     144         105 :     for (auto & kernel : kernels)
     145             :     {
     146          63 :       mfem::BilinearFormIntegrator * integ_real = kernel->getRealBFIntegrator();
     147          63 :       mfem::BilinearFormIntegrator * integ_imag = kernel->getImagBFIntegrator();
     148             : 
     149          63 :       if (integ_real || integ_imag)
     150             :       {
     151          63 :         kernel->isSubdomainRestricted()
     152          63 :             ? form->AddDomainIntegrator(
     153           0 :                   std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
     154          63 :             : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
     155             :       }
     156             :     }
     157          42 :   }
     158          42 : }
     159             : 
     160             : inline void
     161          42 : ComplexEquationSystem::ApplyDomainLFIntegrators(
     162             :     const std::string & test_var_name,
     163             :     std::shared_ptr<mfem::ParComplexLinearForm> form,
     164             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
     165             : {
     166          42 :   if (kernels_map.Has(test_var_name))
     167             :   {
     168          42 :     auto kernels = kernels_map.GetRef(test_var_name).GetRef(test_var_name);
     169         105 :     for (auto & kernel : kernels)
     170             :     {
     171          63 :       mfem::LinearFormIntegrator * integ_real = kernel->getRealLFIntegrator();
     172          63 :       mfem::LinearFormIntegrator * integ_imag = kernel->getImagLFIntegrator();
     173             : 
     174          63 :       if (integ_real || integ_imag)
     175             :       {
     176           0 :         kernel->isSubdomainRestricted()
     177           0 :             ? form->AddDomainIntegrator(
     178           0 :                   std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
     179           0 :             : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
     180             :       }
     181             :     }
     182          42 :   }
     183          42 : }
     184             : 
     185             : template <class FormType>
     186             : void
     187          42 : ComplexEquationSystem::ApplyBoundaryBLFIntegrators(
     188             :     const std::string & trial_var_name,
     189             :     const std::string & test_var_name,
     190             :     std::shared_ptr<FormType> form,
     191             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
     192             :         integrated_bc_map)
     193             : {
     194          49 :   if (integrated_bc_map.Has(test_var_name) &&
     195           7 :       integrated_bc_map.Get(test_var_name)->Has(trial_var_name))
     196             :   {
     197           7 :     auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(trial_var_name);
     198          21 :     for (auto & bc : bcs)
     199             :     {
     200          14 :       mfem::BilinearFormIntegrator * integ_real = bc->getRealBFIntegrator();
     201          14 :       mfem::BilinearFormIntegrator * integ_imag = bc->getImagBFIntegrator();
     202             : 
     203          14 :       if (integ_real || integ_imag)
     204             :       {
     205          14 :         bc->isBoundaryRestricted()
     206          42 :             ? form->AddBoundaryIntegrator(
     207          28 :                   std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
     208           0 :             : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
     209             :       }
     210             :     }
     211           7 :   }
     212          42 : }
     213             : 
     214             : inline void
     215          42 : ComplexEquationSystem::ApplyBoundaryLFIntegrators(
     216             :     const std::string & test_var_name,
     217             :     std::shared_ptr<mfem::ParComplexLinearForm> form,
     218             :     NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
     219             :         integrated_bc_map)
     220             : {
     221          42 :   if (integrated_bc_map.Has(test_var_name))
     222             :   {
     223           7 :     auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(test_var_name);
     224          21 :     for (auto & bc : bcs)
     225             :     {
     226          14 :       mfem::LinearFormIntegrator * integ_real = bc->getRealLFIntegrator();
     227          14 :       mfem::LinearFormIntegrator * integ_imag = bc->getImagLFIntegrator();
     228             : 
     229          14 :       if (integ_real || integ_imag)
     230             :       {
     231           7 :         bc->isBoundaryRestricted()
     232          21 :             ? form->AddBoundaryIntegrator(
     233          14 :                   std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
     234           0 :             : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
     235             :       }
     236             :     }
     237           7 :   }
     238          42 : }
     239             : 
     240             : }
     241             : 
     242             : #endif

Generated by: LCOV version 1.14