LCOV - code coverage report
Current view: top level - src/mfem/problem_operators - ProblemOperatorBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: fa5e60 Lines: 51 54 94.4 %
Date: 2026-06-24 08:03:36 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        1440 : ProblemOperatorBase::ProblemOperatorBase(MFEMProblem & problem)
      21        1440 :   : _problem(problem), _problem_data(problem.getProblemData())
      22             : {
      23        1440 : }
      24             : 
      25             : void
      26        1403 : ProblemOperatorBase::SetGridFunctions()
      27             : {
      28        1403 :   _trial_variables = _problem_data.gridfunctions.Get(_trial_var_names);
      29        1403 :   _test_variables = _problem_data.gridfunctions.Get(_test_var_names);
      30             : 
      31             :   // Set operator size and block structure for trial spaces
      32        1403 :   _block_true_offsets_trial.SetSize(_trial_variables.size() + 1);
      33        1403 :   _block_true_offsets_trial[0] = 0;
      34        2392 :   for (const auto ind : index_range(_trial_variables))
      35         989 :     _block_true_offsets_trial[ind + 1] = _trial_variables.at(ind)->ParFESpace()->TrueVSize();
      36        1403 :   _block_true_offsets_trial.PartialSum();
      37             : 
      38             :   // Set operator size and block structure for test spaces
      39        1403 :   _block_true_offsets_test.SetSize(_test_variables.size() + 1);
      40        1403 :   _block_true_offsets_test[0] = 0;
      41        2392 :   for (const auto ind : index_range(_test_variables))
      42         989 :     _block_true_offsets_test[ind + 1] = _test_variables.at(ind)->ParFESpace()->TrueVSize();
      43        1403 :   _block_true_offsets_test.PartialSum();
      44             : 
      45        1403 :   _true_x.Update(_block_true_offsets_trial);
      46        1403 :   _true_rhs.Update(_block_true_offsets_test);
      47        1403 : }
      48             : 
      49             : void
      50        1440 : ProblemOperatorBase::Init(mfem::BlockVector & X)
      51             : {
      52        1440 :   X.Update(_block_true_offsets_trial);
      53        2403 :   for (const auto i : index_range(_trial_variables))
      54         963 :     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        1440 :   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        2403 :   for (const auto i : index_range(_trial_variables))
      61        1926 :     _trial_variables[i]->MakeTRef(
      62         963 :         _trial_variables[i]->ParFESpace(), X, _block_true_offsets_trial[i]);
      63        1440 :   _trial_true_vector = &X;
      64        1440 : }
      65             : 
      66             : void
      67        1324 : ProblemOperatorBase::SetTrialVariablesFromTrueVectors()
      68             : {
      69             :   mooseAssert(_trial_true_vector, "The true vector should already have been set");
      70        2666 :   for (const auto trial_var : _trial_variables)
      71             :   {
      72             :     // Sync the memory flags from the global true vector to the gridfunction aliases
      73        1342 :     trial_var->GetTrueVector().SyncMemory(*_trial_true_vector);
      74        1342 :     trial_var->SetFromTrueVector();
      75             :   }
      76        1324 : }
      77             : 
      78             : void
      79        2135 : ProblemOperatorBase::SolveWithOperator(EquationSystem & equation_system,
      80             :                                        const mfem::Vector & rhs,
      81             :                                        mfem::Vector & x)
      82             : {
      83        2135 :   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        2135 :   if (nonlinear || _problem_data.nonlinear_solver)
      89             :   {
      90         378 :     if (nonlinear && !_problem_data.nonlinear_solver)
      91           0 :       mooseError("A nonlinear MFEM solve requires a nonlinear solver, but none was provided.");
      92             : 
      93         378 :     auto & nonlinear_solver = *_problem_data.nonlinear_solver;
      94         378 :     if (nonlinear_solver.RequiresExternalLinearSolver())
      95             :     {
      96         371 :       if (!_problem_data.jacobian_solver)
      97           0 :         mooseError("The configured MFEM nonlinear solver requires an external linear solver, but "
      98             :                    "none was provided.");
      99         371 :       auto & linear_solver = *_problem_data.jacobian_solver;
     100         371 :       equation_system.PrepareLinearSolver(linear_solver);
     101         371 :       nonlinear_solver.SetLinearSolver(linear_solver.GetSolver());
     102             :     }
     103             : 
     104         378 :     nonlinear_solver.SetOperator(equation_system);
     105         378 :     nonlinear_solver.Mult(rhs, x);
     106         378 :     return;
     107             :   }
     108             :   else
     109             :   {
     110             :     //
     111             :     // pure linear path
     112             :     //
     113             : 
     114        1757 :     if (!_problem_data.jacobian_solver)
     115           0 :       mooseError("A linear MFEM solve requires a linear solver, but none was provided.");
     116             : 
     117        1757 :     auto & linear_solver = *_problem_data.jacobian_solver;
     118        1757 :     equation_system.PrepareLinearSolver(linear_solver);
     119        1757 :     linear_solver.GetSolver().Mult(rhs, x);
     120             :   }
     121             : }
     122             : 
     123             : } // namespace Moose::MFEM
     124             : 
     125             : #endif

Generated by: LCOV version 1.14