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