https://mooseframework.inl.gov
ProblemOperatorBase.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 
12 #include "ProblemOperatorBase.h"
13 #include "EquationSystem.h"
14 
15 class MFEMProblem;
16 
17 namespace Moose::MFEM
18 {
19 
21  : _problem(problem), _problem_data(problem.getProblemData())
22 {
23 }
24 
25 void
27 {
30 
31  // Set operator size and block structure for trial spaces
32  _block_true_offsets_trial.SetSize(_trial_variables.size() + 1);
34  for (const auto ind : index_range(_trial_variables))
35  _block_true_offsets_trial[ind + 1] = _trial_variables.at(ind)->ParFESpace()->TrueVSize();
36  _block_true_offsets_trial.PartialSum();
37 
38  // Set operator size and block structure for test spaces
39  _block_true_offsets_test.SetSize(_test_variables.size() + 1);
41  for (const auto ind : index_range(_test_variables))
42  _block_true_offsets_test[ind + 1] = _test_variables.at(ind)->ParFESpace()->TrueVSize();
43  _block_true_offsets_test.PartialSum();
44 
47 }
48 
49 void
50 ProblemOperatorBase::Init(mfem::BlockVector & X)
51 {
52  X.Update(_block_true_offsets_trial);
53  for (const auto i : index_range(_trial_variables))
54  X.GetBlock(i) = _trial_variables[i]->GetTrueVector();
55  // Sync the flags from the global vector with the sub-vectors (copies to global vector location)
56  X.SyncFromBlocks();
57 
58  // After initial assignment of X from the grid function, which may contain initial conditions,
59  // we alias the grid function to X
60  for (const auto i : index_range(_trial_variables))
61  _trial_variables[i]->MakeTRef(
62  _trial_variables[i]->ParFESpace(), X, _block_true_offsets_trial[i]);
63  _trial_true_vector = &X;
64 }
65 
66 void
68 {
69  mooseAssert(_trial_true_vector, "The true vector should already have been set");
70  for (const auto trial_var : _trial_variables)
71  {
72  // Sync the memory flags from the global true vector to the gridfunction aliases
73  trial_var->GetTrueVector().SyncMemory(*_trial_true_vector);
74  trial_var->SetFromTrueVector();
75  }
76 }
77 
78 void
80  const mfem::Vector & rhs,
81  mfem::Vector & x)
82 {
83  const bool nonlinear = equation_system.Nonlinear();
84 
85  // `nonlinear` describes the assembled MFEM operator, not whether the user configured a
86  // nonlinear solver object. A linear problem may still intentionally be solved through the
87  // nonlinear solver machinery when one is provided.
88  if (nonlinear || _problem_data.nonlinear_solver)
89  {
90  if (nonlinear && !_problem_data.nonlinear_solver)
91  mooseError("A nonlinear MFEM solve requires a nonlinear solver, but none was provided.");
92 
93  auto & nonlinear_solver = *_problem_data.nonlinear_solver;
94  if (nonlinear_solver.RequiresExternalLinearSolver())
95  {
97  mooseError("The configured MFEM nonlinear solver requires an external linear solver, but "
98  "none was provided.");
99  auto & linear_solver = *_problem_data.jacobian_solver;
100  equation_system.PrepareLinearSolver(linear_solver);
101  nonlinear_solver.SetLinearSolver(linear_solver.GetSolver());
102  }
103 
104  nonlinear_solver.SetOperator(equation_system);
105  nonlinear_solver.Mult(rhs, x);
106  return;
107  }
108  else
109  {
110  //
111  // pure linear path
112  //
113 
115  mooseError("A linear MFEM solve requires a linear solver, but none was provided.");
116 
117  auto & linear_solver = *_problem_data.jacobian_solver;
118  equation_system.PrepareLinearSolver(linear_solver);
119  linear_solver.GetSolver().Mult(rhs, x);
120  }
121 }
122 
123 } // namespace Moose::MFEM
124 
125 #endif
std::vector< std::string > _test_var_names
void PrepareLinearSolver(LinearSolverBase &solver)
Prepare the provided linear solver.
std::vector< std::string > _trial_var_names
Vector of names of state gridfunctions used in formulation, ordered by appearance in block vector dur...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
ProblemOperatorBase(MFEMProblem &problem)
mfem::Array< int > _block_true_offsets_test
std::shared_ptr< Moose::MFEM::LinearSolverBase > jacobian_solver
Class to store weak form components (bilinear and linear forms, and optionally mixed and nonlinear fo...
std::vector< mfem::ParGridFunction * > _test_variables
mfem::Array< int > _block_true_offsets_trial
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::vector< mfem::ParGridFunction * > _trial_variables
std::shared_ptr< Moose::MFEM::NonlinearSolverBase > nonlinear_solver
virtual void Init(mfem::BlockVector &X)
void SolveWithOperator(EquationSystem &equation_system, const mfem::Vector &rhs, mfem::Vector &x)
Solve the current equation system/operator using the configured nonlinear solver or linear solver for...
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
Moose::MFEM::GridFunctions gridfunctions
auto index_range(const T &sizable)