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 "ProblemOperatorBase.h" 13 : 14 : class MFEMProblem; 15 : 16 : namespace Moose::MFEM 17 : { 18 : 19 1663 : ProblemOperatorBase::ProblemOperatorBase(MFEMProblem & problem) 20 1663 : : _problem(problem), _problem_data(problem.getProblemData()) 21 : { 22 1663 : } 23 : 24 : void 25 1598 : ProblemOperatorBase::SetGridFunctions() 26 : { 27 1598 : _trial_variables = _problem_data.gridfunctions.Get(_trial_var_names); 28 1598 : _test_variables = _problem_data.gridfunctions.Get(_test_var_names); 29 : 30 : // Set operator size and block structure for trial spaces 31 1598 : _block_true_offsets_trial.SetSize(_trial_variables.size() + 1); 32 1598 : _block_true_offsets_trial[0] = 0; 33 2700 : for (const auto ind : index_range(_trial_variables)) 34 1102 : _block_true_offsets_trial[ind + 1] = _trial_variables.at(ind)->ParFESpace()->TrueVSize(); 35 1598 : _block_true_offsets_trial.PartialSum(); 36 : 37 : // Set operator size and block structure for test spaces 38 1598 : _block_true_offsets_test.SetSize(_test_variables.size() + 1); 39 1598 : _block_true_offsets_test[0] = 0; 40 2700 : for (const auto ind : index_range(_test_variables)) 41 1102 : _block_true_offsets_test[ind + 1] = _test_variables.at(ind)->ParFESpace()->TrueVSize(); 42 1598 : _block_true_offsets_test.PartialSum(); 43 : 44 1598 : _true_x.Update(_block_true_offsets_trial); 45 1598 : _true_rhs.Update(_block_true_offsets_test); 46 1598 : } 47 : 48 : void 49 1635 : ProblemOperatorBase::Init(mfem::BlockVector & X) 50 : { 51 1635 : X.Update(_block_true_offsets_trial); 52 2711 : for (const auto i : index_range(_trial_variables)) 53 1076 : X.GetBlock(i) = _trial_variables[i]->GetTrueVector(); 54 : // Sync the flags from the global vector with the sub-vectors (copies to global vector location) 55 1635 : X.SyncFromBlocks(); 56 : 57 : // After initial assignment of X from the grid function, which may contain initial conditions, 58 : // we alias the grid function to X 59 2711 : for (const auto i : index_range(_trial_variables)) 60 2152 : _trial_variables[i]->MakeTRef( 61 1076 : _trial_variables[i]->ParFESpace(), X, _block_true_offsets_trial[i]); 62 1635 : _trial_true_vector = &X; 63 1635 : } 64 : 65 : void 66 1728 : ProblemOperatorBase::SetTrialVariablesFromTrueVectors() 67 : { 68 : mooseAssert(_trial_true_vector, "The true vector should already have been set"); 69 3474 : for (const auto trial_var : _trial_variables) 70 : { 71 : // Sync the memory flags from the global true vector to the gridfunction aliases 72 1746 : trial_var->GetTrueVector().SyncMemory(*_trial_true_vector); 73 1746 : trial_var->SetFromTrueVector(); 74 : } 75 1728 : } 76 : 77 : void 78 2624 : ProblemOperatorBase::SolveWithOperator(mfem::Operator & system_operator, 79 : mfem::Operator & linear_operator, 80 : const mfem::Vector & rhs, 81 : mfem::Vector & x) 82 : { 83 : // Nonlinear solver path for both linear and nonlinear problems. (as a linear problem may still 84 : // intentionally be solved through the nonlinear solver machinery when one is provided) 85 2624 : if (_problem_data.nonlinear_solver) 86 : { 87 736 : auto & nonlinear_solver = *_problem_data.nonlinear_solver; 88 736 : if (nonlinear_solver.RequiresExternalLinearSolver()) 89 : { 90 729 : if (!_problem_data.jacobian_solver) 91 0 : mooseError("The configured MFEM nonlinear solver requires an external linear solver, but " 92 : "none was provided."); 93 729 : auto & linear_solver = *_problem_data.jacobian_solver; 94 729 : linear_solver.SetOperator(linear_operator); 95 727 : nonlinear_solver.SetLinearSolver(linear_solver.GetSolver()); 96 : } 97 : 98 734 : nonlinear_solver.SetOperator(system_operator); 99 734 : nonlinear_solver.Mult(rhs, x); 100 : } 101 : // Linear solver path for linear problems. 102 : else 103 : { 104 1888 : if (!_problem_data.jacobian_solver) 105 0 : mooseError("A linear MFEM solve requires a linear solver, but none was provided."); 106 : 107 1888 : auto & linear_solver = *_problem_data.jacobian_solver; 108 1888 : linear_solver.SetOperator(linear_operator); 109 1888 : linear_solver.Mult(rhs, x); 110 : } 111 2622 : } 112 : 113 : } // namespace Moose::MFEM 114 : 115 : #endif