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 : #pragma once 13 : 14 : #include "MFEMProblem.h" 15 : #include <functional> 16 : 17 : namespace Moose::MFEM 18 : { 19 : 20 : /** 21 : * Connects MFEMProblem's MOOSE solver objects to EquationSystem's mathematics. 22 : * 23 : * Three distinct layers collaborate to run an MFEM solve inside MOOSE: 24 : * 25 : * - **MFEMProblem** owns MOOSE infrastructure: the object factory, the action system, 26 : * ProblemData, and the configured solver objects. Embedding the mfem::Operator 27 : * solve-dispatch logic here would couple MOOSE's object-management layer directly 28 : * to specific MFEM operator patterns, so it delegates to ProblemOperator instead. 29 : * 30 : * - **EquationSystem** owns the mathematics: it builds weak-form components 31 : * (bilinear/linear/nonlinear forms contributed by kernels and BCs), forms the constrained 32 : * linear part, retains nonlinear action forms for residual/Jacobian evaluation, and exposes 33 : * the resulting mfem::Operator interface consumed by both linear solvers (CG, GMRES, direct) 34 : * and nonlinear solvers (Newton). Solver selection is a user-configuration concern owned by 35 : * MFEMProblem; coupling it into EquationSystem would conflate the mathematical description of 36 : * a PDE with how MOOSE happens to solve it. 37 : * 38 : * - **ProblemOperator** (this class) connects the two. It provides: 39 : * 1. The steady vs. time-dependent dispatch boundary: all subclasses implement 40 : * Solve() as the MOOSE-level entry point ("do whatever this step requires"). 41 : * Transient subclasses additionally inherit from mfem::TimeDependentOperator 42 : * and implement ImplicitSolve(dt, t, x) - a different, MFEM-level contract 43 : * that MFEM's ODE solvers (BackwardEuler, SDIRK, etc.) call internally. 44 : * Solve() and ImplicitSolve() live at different abstraction layers and are 45 : * not interchangeable; ImplicitSolve() carries dt and t precisely because 46 : * it is the per-step callback in an ODE integration loop. 47 : * 2. SolveWithOperator() - the linear/nonlinear dispatch that requires knowing 48 : * which MOOSE solver objects are configured (jacobian_solver, nonlinear_solver). 49 : * 3. Block-vector bookkeeping (trial/test true-DoF offsets and vectors) that 50 : * bridges between the true-DoF algebraic world with the FE gridfunction world. 51 : */ 52 : class ProblemOperatorBase 53 : { 54 : public: 55 : ProblemOperatorBase(MFEMProblem & problem); 56 1631 : virtual ~ProblemOperatorBase() = default; 57 : 58 : virtual void SetGridFunctions(); 59 : virtual void SetTrialVariablesFromTrueVectors(); 60 : virtual void Init(mfem::BlockVector & X); 61 : virtual void Solve() = 0; 62 : 63 : mfem::Array<int> _block_true_offsets_test; 64 : mfem::Array<int> _block_true_offsets_trial; 65 : 66 : mfem::BlockVector _true_x, _true_rhs; 67 : 68 : protected: 69 : /// Solve the current system operator using the configured nonlinear and linear solvers 70 : void SolveWithOperator(mfem::Operator & system_operator, 71 : mfem::Operator & linear_operator, 72 : const mfem::Vector & rhs, 73 : mfem::Vector & x); 74 : 75 : /// Solve the current system operator using system_operator.GetGradient(x) as the linear operator 76 : void 77 2624 : SolveWithOperator(mfem::Operator & system_operator, const mfem::Vector & rhs, mfem::Vector & x) 78 : { 79 2624 : return SolveWithOperator(system_operator, system_operator.GetGradient(x), rhs, x); 80 : } 81 : 82 : /// Reference to the current problem. 83 : MFEMProblem & _problem; 84 : MFEMProblemData & _problem_data; 85 : 86 : /// Vector of names of state gridfunctions used in formulation, ordered by appearance in block 87 : /// vector during solve. 88 : std::vector<std::string> _trial_var_names; 89 : std::vector<std::string> _test_var_names; 90 : std::vector<mfem::ParGridFunction *> _trial_variables; 91 : std::vector<mfem::ParGridFunction *> _test_variables; 92 : mfem::Vector * _trial_true_vector = nullptr; 93 : }; 94 : } 95 : 96 : #endif