LCOV - code coverage report
Current view: top level - src/mfem/problem_operators - ProblemOperatorBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33390 (250e9c) with base 846a5c Lines: 50 53 94.3 %
Date: 2026-07-31 18:15:22 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          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             : #include "EquationSystem.h"
      14             : 
      15             : class MFEMProblem;
      16             : 
      17             : namespace Moose::MFEM
      18             : {
      19             : 
      20        1590 : ProblemOperatorBase::ProblemOperatorBase(MFEMProblem & problem)
      21        1590 :   : _problem(problem), _problem_data(problem.getProblemData())
      22             : {
      23        1590 : }
      24             : 
      25             : void
      26        1539 : ProblemOperatorBase::SetGridFunctions()
      27             : {
      28        1539 :   _trial_variables = _problem_data.gridfunctions.Get(_trial_var_names);
      29        1539 :   _test_variables = _problem_data.gridfunctions.Get(_test_var_names);
      30             : 
      31             :   // Set operator size and block structure for trial spaces
      32        1539 :   _block_true_offsets_trial.SetSize(_trial_variables.size() + 1);
      33        1539 :   _block_true_offsets_trial[0] = 0;
      34        2612 :   for (const auto ind : index_range(_trial_variables))
      35        1073 :     _block_true_offsets_trial[ind + 1] = _trial_variables.at(ind)->ParFESpace()->TrueVSize();
      36        1539 :   _block_true_offsets_trial.PartialSum();
      37             : 
      38             :   // Set operator size and block structure for test spaces
      39        1539 :   _block_true_offsets_test.SetSize(_test_variables.size() + 1);
      40        1539 :   _block_true_offsets_test[0] = 0;
      41        2612 :   for (const auto ind : index_range(_test_variables))
      42        1073 :     _block_true_offsets_test[ind + 1] = _test_variables.at(ind)->ParFESpace()->TrueVSize();
      43        1539 :   _block_true_offsets_test.PartialSum();
      44             : 
      45        1539 :   _true_x.Update(_block_true_offsets_trial);
      46        1539 :   _true_rhs.Update(_block_true_offsets_test);
      47        1539 : }
      48             : 
      49             : void
      50        1576 : ProblemOperatorBase::Init(mfem::BlockVector & X)
      51             : {
      52        1576 :   X.Update(_block_true_offsets_trial);
      53        2623 :   for (const auto i : index_range(_trial_variables))
      54        1047 :     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        1576 :   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        2623 :   for (const auto i : index_range(_trial_variables))
      61        2094 :     _trial_variables[i]->MakeTRef(
      62        1047 :         _trial_variables[i]->ParFESpace(), X, _block_true_offsets_trial[i]);
      63        1576 :   _trial_true_vector = &X;
      64        1576 : }
      65             : 
      66             : void
      67        1624 : ProblemOperatorBase::SetTrialVariablesFromTrueVectors()
      68             : {
      69             :   mooseAssert(_trial_true_vector, "The true vector should already have been set");
      70        3266 :   for (const auto trial_var : _trial_variables)
      71             :   {
      72             :     // Sync the memory flags from the global true vector to the gridfunction aliases
      73        1642 :     trial_var->GetTrueVector().SyncMemory(*_trial_true_vector);
      74        1642 :     trial_var->SetFromTrueVector();
      75             :   }
      76        1624 : }
      77             : 
      78             : void
      79        2511 : ProblemOperatorBase::SolveWithOperator(EquationSystem & equation_system,
      80             :                                        const mfem::Vector & rhs,
      81             :                                        mfem::Vector & x)
      82             : {
      83             :   // `IsNonlinear()` describes the assembled operator, not whether a nonlinear solver is available.
      84        2511 :   if (equation_system.IsNonlinear() && !_problem_data.nonlinear_solver)
      85           0 :     mooseError("A nonlinear MFEM solve requires a nonlinear solver, but none was provided.");
      86             : 
      87             :   // Nonlinear solver path for both linear and nonlinear problems. (as a linear problem may still
      88             :   // intentionally be solved through the nonlinear solver machinery when one is provided)
      89        2511 :   if (_problem_data.nonlinear_solver)
      90             :   {
      91         680 :     auto & nonlinear_solver = *_problem_data.nonlinear_solver;
      92         680 :     if (nonlinear_solver.RequiresExternalLinearSolver())
      93             :     {
      94         673 :       if (!_problem_data.jacobian_solver)
      95           0 :         mooseError("The configured MFEM nonlinear solver requires an external linear solver, but "
      96             :                    "none was provided.");
      97         673 :       auto & linear_solver = *_problem_data.jacobian_solver;
      98         673 :       equation_system.PrepareLinearSolver(linear_solver);
      99         671 :       nonlinear_solver.SetLinearSolver(linear_solver.GetSolver());
     100             :     }
     101             : 
     102         678 :     nonlinear_solver.SetOperator(equation_system);
     103         678 :     nonlinear_solver.Mult(rhs, x);
     104             :   }
     105             :   // Linear solver path for linear problems.
     106             :   else
     107             :   {
     108        1831 :     if (!_problem_data.jacobian_solver)
     109           0 :       mooseError("A linear MFEM solve requires a linear solver, but none was provided.");
     110             : 
     111        1831 :     auto & linear_solver = *_problem_data.jacobian_solver;
     112        1831 :     equation_system.PrepareLinearSolver(linear_solver);
     113        1831 :     linear_solver.Mult(rhs, x);
     114             :   }
     115        2509 : }
     116             : 
     117             : } // namespace Moose::MFEM
     118             : 
     119             : #endif

Generated by: LCOV version 1.14