https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TimeDependentEquationSystem.C
Go to the documentation of this file.
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
13
14namespace Moose::MFEM
15{
17 const Moose::MFEM::TimeDerivativeMap & time_derivative_map)
18 : _dt(1.0), _time_derivative_map(time_derivative_map)
19{
20}
21
22void
23TimeDependentEquationSystem::AddKernel(std::shared_ptr<MFEMKernel> kernel)
24{
25 if (!_time_derivative_map.isTimeDerivative(kernel->getTrialVariableName()))
26 {
28 return;
29 }
30
31 const auto & trial_var_name =
32 _time_derivative_map.getTimeIntegralName(kernel->getTrialVariableName());
33 const auto & test_var_name = kernel->getTestVariableName();
35 AddTestVariableNameIfMissing(test_var_name);
36 // Register new td kernels map if not present for the test variable
37 if (!_td_kernels_map.Has(test_var_name))
38 {
39 auto kernel_field_map =
40 std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
41 _td_kernels_map.Register(test_var_name, std::move(kernel_field_map));
42 }
43 // Register new td kernels map if not present for the test/trial variable pair
44 if (!_td_kernels_map.Get(test_var_name)->Has(trial_var_name))
45 {
46 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
47 _td_kernels_map.Get(test_var_name)->Register(trial_var_name, std::move(kernels));
48 }
49 _td_kernels_map.GetRef(test_var_name).Get(trial_var_name)->push_back(std::move(kernel));
50}
51
52void
54{
55 // Register bilinear forms
56 for (const auto i : index_range(_test_var_names))
57 {
58 const auto & test_var_name = _test_var_names.at(i);
59
60 // Apply kernels to blf
61 _blfs.Register(test_var_name, std::make_shared<mfem::ParBilinearForm>(_test_pfespaces.at(i)));
62 auto blf = _blfs.GetShared(test_var_name);
63 blf->SetAssemblyLevel(_assembly_level);
64 ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
65 test_var_name, test_var_name, blf, _integrated_bc_map, _dt);
66 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
67 test_var_name, test_var_name, blf, _kernels_map, _dt);
68 // Apply dt*du/dt contributions from the operator on the trial variable
69 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
70 test_var_name, test_var_name, blf, _td_kernels_map);
71 // Assemble
72 blf->Assemble();
73
74 // Apply kernels to td_blf
75 _td_blfs.Register(test_var_name,
76 std::make_shared<mfem::ParBilinearForm>(_test_pfespaces.at(i)));
77 auto td_blf = _td_blfs.GetShared(test_var_name);
78 td_blf->SetAssemblyLevel(_assembly_level);
79 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
80 test_var_name, test_var_name, td_blf, _td_kernels_map);
81 // Assemble
82 td_blf->Assemble();
83 }
84}
85
86void
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 for (const auto i : index_range(_test_var_names))
96 {
97 const auto & test_var_name = _test_var_names.at(i);
98 auto test_mblfs = std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
99 for (const auto j : index_range(_coupled_var_names))
100 {
101 const auto & coupled_var_name = _coupled_var_names.at(j);
102 auto mblf = std::make_shared<mfem::ParMixedBilinearForm>(_coupled_pfespaces.at(j),
103 _test_pfespaces.at(i));
104 // Register MixedBilinearForm if kernels exist for it, and assemble kernels
105 if (test_var_name != coupled_var_name)
106 {
107 // Apply all mixed kernels with this test/trial pair
108 ApplyBoundaryBLFIntegrators<mfem::ParMixedBilinearForm>(
109 coupled_var_name, test_var_name, mblf, _integrated_bc_map, _dt);
110 ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
111 coupled_var_name, test_var_name, mblf, _kernels_map, _dt);
112 // Apply dt*du/dt contributions from the operator on the trial variable
113 ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
114 coupled_var_name, test_var_name, mblf, _td_kernels_map);
115 if (mblf->GetDBFI()->Size() || mblf->GetBBFI()->Size())
116 {
117 // Assemble mixed bilinear forms
118 mblf->SetAssemblyLevel(_assembly_level);
119 mblf->Assemble();
120 // Register mixed bilinear forms associated with a single trial variable
121 // for the current test variable
122 test_mblfs->Register(coupled_var_name, mblf);
123 }
124 }
125 }
126 // Register all mixed bilinear form sets associated with a single test variable
127 _mblfs.Register(test_var_name, test_mblfs);
128 }
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 for (const auto i : index_range(_test_var_names))
135 {
136 const auto & test_var_name = _test_var_names.at(i);
137 auto test_td_mblfs =
138 std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
139 for (const auto j : index_range(_trial_var_names))
140 {
141 const auto & trial_var_name = _trial_var_names.at(j);
142 auto td_mblf = std::make_shared<mfem::ParMixedBilinearForm>(_test_pfespaces.at(j),
143 _test_pfespaces.at(i));
144 // Register MixedBilinearForm if kernels exist for it, and assemble kernels
145 if (test_var_name != trial_var_name)
146 {
147 // Apply all mixed kernels with this test/trial pair
148 ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
149 trial_var_name, test_var_name, td_mblf, _td_kernels_map);
150 // Assemble mixed bilinear form
151 if (td_mblf->GetDBFI()->Size() || td_mblf->GetBBFI()->Size())
152 {
153 td_mblf->SetAssemblyLevel(_assembly_level);
154 td_mblf->Assemble();
155 // Register mixed bilinear forms associated with a single trial variable
156 // for the current test variable
157 test_td_mblfs->Register(trial_var_name, td_mblf);
158 }
159 }
160 }
161 // Register all mixed bilinear forms associated with a single test variable
162 _td_mblfs.Register(test_var_name, test_td_mblfs);
163 }
164}
165
166void
168{
169 // Register non-linear Action forms
170 for (const auto i : index_range(_test_var_names))
171 {
172 auto test_var_name = _test_var_names.at(i);
173 _nlfs.Register(test_var_name, std::make_shared<mfem::ParNonlinearForm>(_test_pfespaces.at(i)));
174 // Apply kernels
175 auto nlf = _nlfs.GetShared(test_var_name);
176 nlf->SetEssentialTrueDofs(_ess_tdof_lists.at(i));
177 ApplyDomainNLFIntegrators(test_var_name, nlf, _kernels_map, _dt);
179 }
180}
181
182void
184{
185 for (const auto & test_var_name : _test_var_names)
186 {
187 auto & lf = *_lfs.Get(test_var_name) *= _dt;
188 for (const auto & eliminated_var_name : _eliminated_var_names)
189 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 mfem::Vector lf_prev(lf.Size());
194 auto & td_blf = *_td_blfs.Get(test_var_name);
195 td_blf.Mult(*_eliminated_variables.Get(test_var_name), lf_prev);
196 lf += lf_prev;
197 }
198 else if (_td_mblfs.Has(test_var_name) &&
199 _td_mblfs.Get(test_var_name)->Has(eliminated_var_name))
200 {
201 auto & td_mblf = *_td_mblfs.Get(test_var_name)->Get(eliminated_var_name);
202 td_mblf.AddMult(*_eliminated_variables.Get(eliminated_var_name), lf);
203 }
204 }
205 // Eliminate contributions from other coupled variables.
207}
208
209} // namespace Moose::MFEM
210
211#endif
virtual void AddTestVariableNameIfMissing(const std::string &test_var_name)
Add test variable to EquationSystem.
std::vector< std::string > _coupled_var_names
Names of all trial variables of kernels and boundary conditions added to this EquationSystem.
std::vector< mfem::ParFiniteElementSpace * > _test_pfespaces
Pointers to finite element spaces associated with test variables.
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > _kernels_map
Arrays to store kernels to act on each component of weak form.
std::vector< mfem::ParFiniteElementSpace * > _coupled_pfespaces
Pointers to finite element spaces associated with coupled variables.
void ApplyDomainNLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParNonlinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > &kernels_map, std::optional< mfem::real_t > scale_factor=std::nullopt)
Apply domain NonlinearFormIntegrators from kernels to the nonlinear form associated with the supplied...
virtual void EliminateCoupledVariables()
Perform trivial eliminations of coupled variables lacking corresponding test variables.
std::vector< std::string > _test_var_names
Names of all test variables corresponding to linear forms in this equation system.
void ApplyBoundaryNLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParNonlinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > &integrated_bc_map, std::optional< mfem::real_t > scale_factor=std::nullopt)
Apply boundary NonlinearFormIntegrators from integrated boundary conditions to the nonlinear form ass...
NamedFieldsMap< mfem::ParLinearForm > _lfs
mfem::AssemblyLevel _assembly_level
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel)
Add kernels.
std::vector< mfem::Array< int > > _ess_tdof_lists
NamedFieldsMap< mfem::ParBilinearForm > _blfs
std::vector< std::string > _trial_var_names
Subset of _coupled_var_names of all variables corresponding to gridfunctions with degrees of freedom ...
NamedFieldsMap< NamedFieldsMap< mfem::ParMixedBilinearForm > > _mblfs
virtual void AddEliminatedVariableNameIfMissing(const std::string &eliminated_var_name)
Add eliminated variable to EquationSystem.
NamedFieldsMap< mfem::ParNonlinearForm > _nlfs
Moose::MFEM::GridFunctions _eliminated_variables
Pointers to coupled variables not part of the reduced EquationSystem.
std::vector< std::string > _eliminated_var_names
Names of all coupled variables without a corresponding test variable.
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > _integrated_bc_map
Arrays to store integrated BCs to act on each component of weak form.
void Register(const std::string &field_name, FieldArgs &&... args)
Construct new field with name field_name and register.
bool Has(const std::string &field_name) const
Predicate to check if a field is registered with name field_name.
T * Get(const std::string &field_name) const
Returns a non-owning pointer to the field. This is guaranteed to return a non-null pointer.
std::shared_ptr< T > GetShared(const std::string &field_name) const
Returns a shared pointer to the field. This is guaranteed to return a non-null shared pointer.
T & GetRef(const std::string &field_name) const
Returns a reference to a field.
const Moose::MFEM::TimeDerivativeMap & _time_derivative_map
Map between variable names and their time derivatives.
virtual void BuildBilinearForms() override
Build bilinear forms (diagonal Jacobian contributions)
Moose::MFEM::NamedFieldsMap< mfem::ParBilinearForm > _td_blfs
Containers to store contributions to weak form of the form (F du/dt, v)
virtual void BuildMixedBilinearForms() override
Build mixed bilinear forms (off-diagonal Jacobian contributions)
virtual void EliminateCoupledVariables() override
Perform trivial eliminations of coupled variables lacking corresponding test variables.
virtual void BuildNonlinearForms() override
Build non-linear action forms.
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel) override
Add kernels.
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< mfem::ParMixedBilinearForm > > _td_mblfs
TimeDependentEquationSystem(const Moose::MFEM::TimeDerivativeMap &time_derivative_map)
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > _td_kernels_map
Lightweight adaptor over a std::map relating names of GridFunctions with the name of their time deriv...
const std::string & getTimeIntegralName(const std::string &time_derivative_var_name) const
bool isTimeDerivative(const std::string &time_derivative_var_name) const
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).