LCOV - code coverage report
Current view: top level - src/mfem/equation_systems - TimeDependentEquationSystem.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 109 109 100.0 %
Date: 2026-05-29 20:35:17 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #ifdef MOOSE_MFEM_ENABLED
      11             : 
      12             : #include "TimeDependentEquationSystem.h"
      13             : 
      14             : namespace Moose::MFEM
      15             : {
      16         274 : TimeDependentEquationSystem::TimeDependentEquationSystem(
      17         274 :     const Moose::MFEM::TimeDerivativeMap & time_derivative_map)
      18         274 :   : _dt(1.0), _time_derivative_map(time_derivative_map)
      19             : {
      20         274 : }
      21             : 
      22             : void
      23         290 : TimeDependentEquationSystem::AddKernel(std::shared_ptr<MFEMKernel> kernel)
      24             : {
      25         290 :   if (!_time_derivative_map.isTimeDerivative(kernel->getTrialVariableName()))
      26             :   {
      27         145 :     EquationSystem::AddKernel(kernel);
      28         145 :     return;
      29             :   }
      30             : 
      31             :   const auto & trial_var_name =
      32         145 :       _time_derivative_map.getTimeIntegralName(kernel->getTrialVariableName());
      33         145 :   const auto & test_var_name = kernel->getTestVariableName();
      34         145 :   AddEliminatedVariableNameIfMissing(trial_var_name);
      35         145 :   AddTestVariableNameIfMissing(test_var_name);
      36             :   // Register new td kernels map if not present for the test variable
      37         145 :   if (!_td_kernels_map.Has(test_var_name))
      38             :   {
      39             :     auto kernel_field_map =
      40         139 :         std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
      41         139 :     _td_kernels_map.Register(test_var_name, std::move(kernel_field_map));
      42         139 :   }
      43             :   // Register new td kernels map if not present for the test/trial variable pair
      44         145 :   if (!_td_kernels_map.Get(test_var_name)->Has(trial_var_name))
      45             :   {
      46         145 :     auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
      47         145 :     _td_kernels_map.Get(test_var_name)->Register(trial_var_name, std::move(kernels));
      48         145 :   }
      49         145 :   _td_kernels_map.GetRef(test_var_name).Get(trial_var_name)->push_back(std::move(kernel));
      50             : }
      51             : 
      52             : void
      53        1048 : TimeDependentEquationSystem::BuildBilinearForms()
      54             : {
      55             :   // Register bilinear forms
      56        2114 :   for (const auto i : index_range(_test_var_names))
      57             :   {
      58        1066 :     const auto & test_var_name = _test_var_names.at(i);
      59             : 
      60             :     // Apply kernels to blf
      61        1066 :     _blfs.Register(test_var_name, std::make_shared<mfem::ParBilinearForm>(_test_pfespaces.at(i)));
      62        1066 :     auto blf = _blfs.GetShared(test_var_name);
      63        1066 :     blf->SetAssemblyLevel(_assembly_level);
      64        1066 :     ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
      65        1066 :         test_var_name, test_var_name, blf, _integrated_bc_map, _dt);
      66        1066 :     ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
      67        1066 :         test_var_name, test_var_name, blf, _kernels_map, _dt);
      68             :     // Apply dt*du/dt contributions from the operator on the trial variable
      69        2132 :     ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
      70        1066 :         test_var_name, test_var_name, blf, _td_kernels_map);
      71             :     // Assemble
      72        1066 :     blf->Assemble();
      73             : 
      74             :     // Apply kernels to td_blf
      75        1066 :     _td_blfs.Register(test_var_name,
      76        2132 :                       std::make_shared<mfem::ParBilinearForm>(_test_pfespaces.at(i)));
      77        1066 :     auto td_blf = _td_blfs.GetShared(test_var_name);
      78        1066 :     td_blf->SetAssemblyLevel(_assembly_level);
      79        2132 :     ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
      80        1066 :         test_var_name, test_var_name, td_blf, _td_kernels_map);
      81             :     // Assemble
      82        1066 :     td_blf->Assemble();
      83        1066 :   }
      84        1048 : }
      85             : 
      86             : void
      87        1048 : TimeDependentEquationSystem::BuildMixedBilinearForms()
      88             : {
      89             :   // Register mixed bilinear forms. Note that not all combinations may
      90             :   // have a kernel.
      91             : 
      92             :   // Create mblf for each test/coupled variable pair with an added kernel.
      93             :   // Mixed bilinear forms with coupled variables that are not trial variables are
      94             :   // associated with contributions from eliminated variables.
      95        2114 :   for (const auto i : index_range(_test_var_names))
      96             :   {
      97        1066 :     const auto & test_var_name = _test_var_names.at(i);
      98        1066 :     auto test_mblfs = std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
      99        2168 :     for (const auto j : index_range(_coupled_var_names))
     100             :     {
     101        1102 :       const auto & coupled_var_name = _coupled_var_names.at(j);
     102        2204 :       auto mblf = std::make_shared<mfem::ParMixedBilinearForm>(_coupled_pfespaces.at(j),
     103        1102 :                                                                _test_pfespaces.at(i));
     104             :       // Register MixedBilinearForm if kernels exist for it, and assemble kernels
     105        1102 :       if (test_var_name != coupled_var_name)
     106             :       {
     107             :         // Apply all mixed kernels with this test/trial pair
     108          36 :         ApplyBoundaryBLFIntegrators<mfem::ParMixedBilinearForm>(
     109          36 :             coupled_var_name, test_var_name, mblf, _integrated_bc_map, _dt);
     110          36 :         ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
     111          36 :             coupled_var_name, test_var_name, mblf, _kernels_map, _dt);
     112             :         // Apply dt*du/dt contributions from the operator on the trial variable
     113          72 :         ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
     114          36 :             coupled_var_name, test_var_name, mblf, _td_kernels_map);
     115          36 :         if (mblf->GetDBFI()->Size() || mblf->GetBBFI()->Size())
     116             :         {
     117             :           // Assemble mixed bilinear forms
     118          36 :           mblf->SetAssemblyLevel(_assembly_level);
     119          36 :           mblf->Assemble();
     120             :           // Register mixed bilinear forms associated with a single trial variable
     121             :           // for the current test variable
     122          36 :           test_mblfs->Register(coupled_var_name, mblf);
     123             :         }
     124             :       }
     125        1102 :     }
     126             :     // Register all mixed bilinear form sets associated with a single test variable
     127        1066 :     _mblfs.Register(test_var_name, test_mblfs);
     128        1066 :   }
     129             : 
     130             :   // Register mixed bilinear forms. Note that not all combinations may
     131             :   // have a kernel.
     132             : 
     133             :   // Create mblf for each test/trial variable pair with an added kernel
     134        2114 :   for (const auto i : index_range(_test_var_names))
     135             :   {
     136        1066 :     const auto & test_var_name = _test_var_names.at(i);
     137             :     auto test_td_mblfs =
     138        1066 :         std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
     139        2168 :     for (const auto j : index_range(_trial_var_names))
     140             :     {
     141        1102 :       const auto & trial_var_name = _trial_var_names.at(j);
     142        2204 :       auto td_mblf = std::make_shared<mfem::ParMixedBilinearForm>(_test_pfespaces.at(j),
     143        1102 :                                                                   _test_pfespaces.at(i));
     144             :       // Register MixedBilinearForm if kernels exist for it, and assemble kernels
     145        1102 :       if (test_var_name != trial_var_name)
     146             :       {
     147             :         // Apply all mixed kernels with this test/trial pair
     148          72 :         ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
     149          36 :             trial_var_name, test_var_name, td_mblf, _td_kernels_map);
     150             :         // Assemble mixed bilinear form
     151          36 :         if (td_mblf->GetDBFI()->Size() || td_mblf->GetBBFI()->Size())
     152             :         {
     153          18 :           td_mblf->SetAssemblyLevel(_assembly_level);
     154          18 :           td_mblf->Assemble();
     155             :           // Register mixed bilinear forms associated with a single trial variable
     156             :           // for the current test variable
     157          18 :           test_td_mblfs->Register(trial_var_name, td_mblf);
     158             :         }
     159             :       }
     160        1102 :     }
     161             :     // Register all mixed bilinear forms associated with a single test variable
     162        1066 :     _td_mblfs.Register(test_var_name, test_td_mblfs);
     163        1066 :   }
     164        1048 : }
     165             : 
     166             : void
     167        1048 : TimeDependentEquationSystem::BuildNonlinearForms()
     168             : {
     169             :   // Register non-linear Action forms
     170        2114 :   for (const auto i : index_range(_test_var_names))
     171             :   {
     172        1066 :     auto test_var_name = _test_var_names.at(i);
     173        1066 :     _nlfs.Register(test_var_name, std::make_shared<mfem::ParNonlinearForm>(_test_pfespaces.at(i)));
     174             :     // Apply kernels
     175        1066 :     auto nlf = _nlfs.GetShared(test_var_name);
     176        1066 :     nlf->SetEssentialTrueDofs(_ess_tdof_lists.at(i));
     177        1066 :     ApplyDomainNLFIntegrators(test_var_name, nlf, _kernels_map, _dt);
     178        1066 :     ApplyBoundaryNLFIntegrators(test_var_name, nlf, _integrated_bc_map, _dt);
     179        1066 :   }
     180        1048 : }
     181             : 
     182             : void
     183        1048 : TimeDependentEquationSystem::EliminateCoupledVariables()
     184             : {
     185        2114 :   for (const auto & test_var_name : _test_var_names)
     186             :   {
     187        1066 :     auto & lf = *_lfs.Get(test_var_name) *= _dt;
     188        2162 :     for (const auto & eliminated_var_name : _eliminated_var_names)
     189        1096 :       if (eliminated_var_name == test_var_name)
     190             :       {
     191             :         // if implicit, add contribution to linear form from terms involving state
     192             :         // The AddMult method in mfem::BilinearForm is not defined for non-legacy assembly
     193        1060 :         mfem::Vector lf_prev(lf.Size());
     194        1060 :         auto & td_blf = *_td_blfs.Get(test_var_name);
     195        1060 :         td_blf.Mult(*_eliminated_variables.Get(test_var_name), lf_prev);
     196        1060 :         lf += lf_prev;
     197        1060 :       }
     198          72 :       else if (_td_mblfs.Has(test_var_name) &&
     199          36 :                _td_mblfs.Get(test_var_name)->Has(eliminated_var_name))
     200             :       {
     201          18 :         auto & td_mblf = *_td_mblfs.Get(test_var_name)->Get(eliminated_var_name);
     202          18 :         td_mblf.AddMult(*_eliminated_variables.Get(eliminated_var_name), lf);
     203             :       }
     204             :   }
     205             :   // Eliminate contributions from other coupled variables.
     206        1048 :   EquationSystem::EliminateCoupledVariables();
     207        1048 : }
     208             : 
     209             : } // namespace Moose::MFEM
     210             : 
     211             : #endif

Generated by: LCOV version 1.14