LCOV - code coverage report
Current view: top level - src/systems - LinearFVGradientInterface.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 80 93 86.0 %
Date: 2026-05-29 20:35:17 Functions: 6 6 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             : #include "LinearFVGradientInterface.h"
      11             : 
      12             : #include "ComputeLinearFVGreenGaussGradientFaceThread.h"
      13             : #include "ComputeLinearFVGreenGaussGradientVolumeThread.h"
      14             : #include "ComputeLinearFVLimitedGradientThread.h"
      15             : #include "FEProblemBase.h"
      16             : #include "PerfGraphInterface.h"
      17             : #include "PerfGuard.h"
      18             : #include "SystemBase.h"
      19             : #include "MooseVariableFieldBase.h"
      20             : #include "MooseError.h"
      21             : 
      22             : #include "libmesh/numeric_vector.h"
      23             : 
      24             : using namespace libMesh;
      25             : 
      26             : void
      27       52237 : LinearFVGradientInterface::computeGradients()
      28             : {
      29             :   // No gradients have been requested, by now we should have set up the
      30             :   // containers to receive the gradients. Time to early return.
      31       52237 :   if (_raw_grad_container.empty())
      32        8660 :     return;
      33             : 
      34       43577 :   auto & temporary_gradient = temporaryLinearFVGradientContainer();
      35             :   mooseAssert(temporary_gradient.size() == _raw_grad_container.size(),
      36             :               "Temporary and raw gradient containers must have the same size.");
      37      121291 :   for (auto & vec : temporary_gradient)
      38       77714 :     vec->zero();
      39             : 
      40       43577 :   auto & fe_problem = _sys.feProblem();
      41       43577 :   auto * const perf_graph_interface = dynamic_cast<PerfGraphInterface *>(&_sys);
      42             :   mooseAssert(perf_graph_interface,
      43             :               "LinearFVGradientInterface requires its owning system to implement "
      44             :               "PerfGraphInterface.");
      45       87154 :   const auto perf_id = perf_graph_interface->registerTimedSection("LinearVariableFV_Gradients", 3);
      46             :   mooseAssert(!Threads::in_threads, "PerfGraph timing cannot be used within threaded sections");
      47       43577 :   PerfGuard time_guard(perf_graph_interface->perfGraph(), perf_id);
      48             : 
      49             :   PARALLEL_TRY
      50             :   {
      51             :     using FaceInfoRange = StoredRange<MooseMesh::const_face_info_iterator, const FaceInfo *>;
      52       87154 :     FaceInfoRange face_info_range(fe_problem.mesh().ownedFaceInfoBegin(),
      53      130731 :                                   fe_problem.mesh().ownedFaceInfoEnd());
      54             : 
      55             :     ComputeLinearFVGreenGaussGradientFaceThread gradient_face_thread(
      56       43577 :         fe_problem, _sys, temporary_gradient);
      57       43577 :     Threads::parallel_reduce(face_info_range, gradient_face_thread);
      58       43577 :   }
      59       43577 :   fe_problem.checkExceptionAndStopSolve();
      60             : 
      61      121291 :   for (auto & vec : temporary_gradient)
      62       77714 :     vec->close();
      63             : 
      64             :   PARALLEL_TRY
      65             :   {
      66             :     using ElemInfoRange = StoredRange<MooseMesh::const_elem_info_iterator, const ElemInfo *>;
      67       87154 :     ElemInfoRange elem_info_range(fe_problem.mesh().ownedElemInfoBegin(),
      68      130731 :                                   fe_problem.mesh().ownedElemInfoEnd());
      69             : 
      70             :     ComputeLinearFVGreenGaussGradientVolumeThread gradient_volume_thread(
      71       43577 :         fe_problem, _sys, temporary_gradient);
      72       43577 :     Threads::parallel_reduce(elem_info_range, gradient_volume_thread);
      73       43577 :   }
      74       43577 :   fe_problem.checkExceptionAndStopSolve();
      75             : 
      76      121291 :   for (const auto i : index_range(_raw_grad_container))
      77       77714 :     temporary_gradient[i]->close();
      78             : 
      79       43577 :   _raw_grad_container.swap(temporary_gradient);
      80             : 
      81       43577 :   if (!requestedLinearFVLimitedGradientTypes().empty())
      82             :   {
      83             :     using ElemInfoRange = StoredRange<MooseMesh::const_elem_info_iterator, const ElemInfo *>;
      84       23740 :     ElemInfoRange elem_info_range(fe_problem.mesh().ownedElemInfoBegin(),
      85       35610 :                                   fe_problem.mesh().ownedElemInfoEnd());
      86             : 
      87       23740 :     for (const auto limiter_type : requestedLinearFVLimitedGradientTypes())
      88             :     {
      89       11870 :       if (limiter_type == Moose::FV::GradientLimiterType::None)
      90           0 :         continue;
      91             : 
      92       11870 :       auto & raw_container = rawLinearFVLimitedGradientContainer(limiter_type);
      93       11870 :       auto & temporary_container = temporaryLinearFVLimitedGradientContainer(limiter_type);
      94             :       mooseAssert(temporary_container.size() == raw_container.size(),
      95             :                   "Temporary and raw limited gradient containers must have the same size.");
      96       32580 :       for (auto & vec : temporary_container)
      97       20710 :         vec->zero();
      98             : 
      99             :       PARALLEL_TRY
     100             :       {
     101             :         ComputeLinearFVLimitedGradientThread limited_gradient_thread(
     102             :             fe_problem,
     103             :             _sys,
     104       11870 :             _raw_grad_container,
     105             :             temporary_container,
     106             :             limiter_type,
     107       11870 :             requestedLinearFVLimitedGradientVariables(limiter_type));
     108       11870 :         Threads::parallel_reduce(elem_info_range, limited_gradient_thread);
     109             :       }
     110       11870 :       fe_problem.checkExceptionAndStopSolve();
     111             : 
     112       32580 :       for (auto & vec : temporary_container)
     113       20710 :         vec->close();
     114             : 
     115       11870 :       raw_container.swap(temporary_container);
     116             :     }
     117       11870 :   }
     118       43577 : }
     119             : 
     120             : bool
     121       63722 : LinearFVGradientInterface::needsLinearFVGradientStorage() const
     122             : {
     123      159472 :   for (const auto * const field_var : _sys.variableWarehouse().fieldVariables())
     124       96574 :     if (field_var->needsGradientVectorStorage())
     125         824 :       return true;
     126             : 
     127       62898 :   return false;
     128             : }
     129             : 
     130             : void
     131        1774 : LinearFVGradientInterface::initializeContainer(
     132             :     std::vector<std::unique_ptr<NumericVector<Number>>> & container) const
     133             : {
     134        1774 :   container.clear();
     135             :   mooseAssert(_sys.currentSolution(),
     136             :               "Current solution must exist before building FV gradient storage.");
     137        4702 :   for (unsigned int i = 0; i < _sys.mesh().dimension(); ++i)
     138        2928 :     container.push_back(_sys.currentSolution()->zero_clone());
     139        1774 : }
     140             : 
     141             : void
     142       63722 : LinearFVGradientInterface::rebuildLinearFVGradientStorage()
     143             : {
     144       63722 :   _raw_grad_container.clear();
     145       63722 :   _temporary_gradient.clear();
     146       63722 :   _raw_limited_grad_containers.clear();
     147       63722 :   _temporary_limited_gradient.clear();
     148             : 
     149       63722 :   if (!needsLinearFVGradientStorage())
     150       62898 :     return;
     151             : 
     152         824 :   initializeContainer(_raw_grad_container);
     153         824 :   initializeContainer(_temporary_gradient);
     154             : 
     155         887 :   for (const auto limiter_type : _requested_limited_gradient_types)
     156             :   {
     157          63 :     if (limiter_type == Moose::FV::GradientLimiterType::None)
     158           0 :       continue;
     159             : 
     160          63 :     initializeContainer(_raw_limited_grad_containers[limiter_type]);
     161          63 :     initializeContainer(_temporary_limited_gradient[limiter_type]);
     162             :   }
     163             : }
     164             : 
     165             : void
     166          63 : LinearFVGradientInterface::requestLinearFVLimitedGradients(
     167             :     const Moose::FV::GradientLimiterType limiter_type, const unsigned int variable_number)
     168             : {
     169          63 :   if (limiter_type == Moose::FV::GradientLimiterType::None)
     170           0 :     return;
     171             : 
     172             :   auto * const variable =
     173          63 :       dynamic_cast<MooseVariableFieldBase *>(_sys.variableWarehouse().getVariable(variable_number));
     174          63 :   if (!variable)
     175           0 :     mooseError("Limited gradients were requested for variable number ",
     176             :                variable_number,
     177             :                " on system '",
     178           0 :                _sys.name(),
     179             :                "', but no field variable with that number exists on the system.");
     180             : 
     181          63 :   if (!variable->needsGradientVectorStorage())
     182           0 :     mooseError("Limited gradients were requested for variable '",
     183           0 :                variable->name(),
     184             :                "' on system '",
     185           0 :                _sys.name(),
     186             :                "', but regular gradients were not requested for that variable.");
     187             : 
     188          63 :   _requested_limited_gradient_variables[limiter_type].insert(variable_number);
     189             : 
     190          63 :   if (_requested_limited_gradient_types.insert(limiter_type).second && !_raw_grad_container.empty())
     191             :   {
     192           0 :     initializeContainer(_raw_limited_grad_containers[limiter_type]);
     193           0 :     initializeContainer(_temporary_limited_gradient[limiter_type]);
     194             :   }
     195             : }
     196             : 
     197             : const std::vector<std::unique_ptr<NumericVector<Number>>> &
     198    28016490 : LinearFVGradientInterface::linearFVLimitedGradientContainer(
     199             :     const Moose::FV::GradientLimiterType limiter_type) const
     200             : {
     201    28016490 :   if (limiter_type == Moose::FV::GradientLimiterType::None)
     202           0 :     return _raw_grad_container;
     203             : 
     204    28016490 :   const auto it = _raw_limited_grad_containers.find(limiter_type);
     205    28016490 :   if (it == _raw_limited_grad_containers.end())
     206           0 :     mooseError("Limited gradient container was requested but not initialized on system '",
     207           0 :                _sys.name(),
     208             :                "'.");
     209             : 
     210    28016490 :   return it->second;
     211             : }

Generated by: LCOV version 1.14