LCOV - code coverage report
Current view: top level - src/mfem/equation_systems - TimeDependentEquationSystem.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32463 (9b8a52) with base a052fd Lines: 109 109 100.0 %
Date: 2026-05-26 14:49:46 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             :     auto test_mblfs =
      99        1066 :         std::make_shared<Moose::MFEM::NamedFieldsMap<Moose::MFEM::ParMixedBilinearForm>>();
     100        2168 :     for (const auto j : index_range(_coupled_var_names))
     101             :     {
     102        1102 :       const auto & coupled_var_name = _coupled_var_names.at(j);
     103        2204 :       auto mblf = std::make_shared<Moose::MFEM::ParMixedBilinearForm>(_coupled_pfespaces.at(j),
     104        1102 :                                                                       _test_pfespaces.at(i));
     105             :       // Register MixedBilinearForm if kernels exist for it, and assemble kernels
     106        1102 :       if (test_var_name != coupled_var_name)
     107             :       {
     108             :         // Apply all mixed kernels with this test/trial pair
     109          36 :         ApplyBoundaryBLFIntegrators<Moose::MFEM::ParMixedBilinearForm>(
     110          36 :             coupled_var_name, test_var_name, mblf, _integrated_bc_map, _dt);
     111          36 :         ApplyDomainBLFIntegrators<Moose::MFEM::ParMixedBilinearForm>(
     112          36 :             coupled_var_name, test_var_name, mblf, _kernels_map, _dt);
     113             :         // Apply dt*du/dt contributions from the operator on the trial variable
     114          72 :         ApplyDomainBLFIntegrators<Moose::MFEM::ParMixedBilinearForm>(
     115          36 :             coupled_var_name, test_var_name, mblf, _td_kernels_map);
     116          36 :         if (mblf->GetDBFI()->Size() || mblf->GetBBFI()->Size())
     117             :         {
     118             :           // Assemble mixed bilinear forms
     119          36 :           mblf->SetAssemblyLevel(_assembly_level);
     120          36 :           mblf->Assemble();
     121             :           // Register mixed bilinear forms associated with a single trial variable
     122             :           // for the current test variable
     123          36 :           test_mblfs->Register(coupled_var_name, mblf);
     124             :         }
     125             :       }
     126        1102 :     }
     127             :     // Register all mixed bilinear form sets associated with a single test variable
     128        1066 :     _mblfs.Register(test_var_name, test_mblfs);
     129        1066 :   }
     130             : 
     131             :   // Register mixed bilinear forms. Note that not all combinations may
     132             :   // have a kernel.
     133             : 
     134             :   // Create mblf for each test/trial variable pair with an added kernel
     135        2114 :   for (const auto i : index_range(_test_var_names))
     136             :   {
     137        1066 :     const auto & test_var_name = _test_var_names.at(i);
     138             :     auto test_td_mblfs =
     139        1066 :         std::make_shared<Moose::MFEM::NamedFieldsMap<Moose::MFEM::ParMixedBilinearForm>>();
     140        2168 :     for (const auto j : index_range(_trial_var_names))
     141             :     {
     142        1102 :       const auto & trial_var_name = _trial_var_names.at(j);
     143        2204 :       auto td_mblf = std::make_shared<Moose::MFEM::ParMixedBilinearForm>(_test_pfespaces.at(j),
     144        1102 :                                                                          _test_pfespaces.at(i));
     145             :       // Register MixedBilinearForm if kernels exist for it, and assemble kernels
     146        1102 :       if (test_var_name != trial_var_name)
     147             :       {
     148             :         // Apply all mixed kernels with this test/trial pair
     149          72 :         ApplyDomainBLFIntegrators<Moose::MFEM::ParMixedBilinearForm>(
     150          36 :             trial_var_name, test_var_name, td_mblf, _td_kernels_map);
     151             :         // Assemble mixed bilinear form
     152          36 :         if (td_mblf->GetDBFI()->Size() || td_mblf->GetBBFI()->Size())
     153             :         {
     154          18 :           td_mblf->SetAssemblyLevel(_assembly_level);
     155          18 :           td_mblf->Assemble();
     156             :           // Register mixed bilinear forms associated with a single trial variable
     157             :           // for the current test variable
     158          18 :           test_td_mblfs->Register(trial_var_name, td_mblf);
     159             :         }
     160             :       }
     161        1102 :     }
     162             :     // Register all mixed bilinear forms associated with a single test variable
     163        1066 :     _td_mblfs.Register(test_var_name, test_td_mblfs);
     164        1066 :   }
     165        1048 : }
     166             : 
     167             : void
     168        1048 : TimeDependentEquationSystem::BuildNonlinearForms()
     169             : {
     170             :   // Register non-linear Action forms
     171        2114 :   for (const auto i : index_range(_test_var_names))
     172             :   {
     173        1066 :     auto test_var_name = _test_var_names.at(i);
     174        1066 :     _nlfs.Register(test_var_name, std::make_shared<mfem::ParNonlinearForm>(_test_pfespaces.at(i)));
     175             :     // Apply kernels
     176        1066 :     auto nlf = _nlfs.GetShared(test_var_name);
     177        1066 :     nlf->SetEssentialTrueDofs(_ess_tdof_lists.at(i));
     178        1066 :     ApplyDomainNLFIntegrators(test_var_name, nlf, _kernels_map, _dt);
     179        1066 :     ApplyBoundaryNLFIntegrators(test_var_name, nlf, _integrated_bc_map, _dt);
     180        1066 :   }
     181        1048 : }
     182             : 
     183             : void
     184        1048 : TimeDependentEquationSystem::EliminateCoupledVariables()
     185             : {
     186        2114 :   for (const auto & test_var_name : _test_var_names)
     187             :   {
     188        1066 :     auto & lf = *_lfs.Get(test_var_name) *= _dt;
     189        2162 :     for (const auto & eliminated_var_name : _eliminated_var_names)
     190        1096 :       if (eliminated_var_name == test_var_name)
     191             :       {
     192             :         // if implicit, add contribution to linear form from terms involving state
     193             :         // The AddMult method in mfem::BilinearForm is not defined for non-legacy assembly
     194        1060 :         mfem::Vector lf_prev(lf.Size());
     195        1060 :         auto & td_blf = *_td_blfs.Get(test_var_name);
     196        1060 :         td_blf.Mult(*_eliminated_variables.Get(test_var_name), lf_prev);
     197        1060 :         lf += lf_prev;
     198        1060 :       }
     199          72 :       else if (_td_mblfs.Has(test_var_name) &&
     200          36 :                _td_mblfs.Get(test_var_name)->Has(eliminated_var_name))
     201             :       {
     202          18 :         auto & td_mblf = *_td_mblfs.Get(test_var_name)->Get(eliminated_var_name);
     203          18 :         td_mblf.AddMult(*_eliminated_variables.Get(eliminated_var_name), lf);
     204             :       }
     205             :   }
     206             :   // Eliminate contributions from other coupled variables.
     207        1048 :   EquationSystem::EliminateCoupledVariables();
     208        1048 : }
     209             : 
     210             : } // namespace Moose::MFEM
     211             : 
     212             : #endif

Generated by: LCOV version 1.14