LCOV - code coverage report
Current view: top level - src/postprocessors - DiscreteVariableResidualNorm.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 60 62 96.8 %
Date: 2025-08-08 20:01:16 Functions: 8 8 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 "DiscreteVariableResidualNorm.h"
      11             : #include "MooseVariableFieldBase.h"
      12             : #include "NonlinearSystemBase.h"
      13             : 
      14             : #include "libmesh/dof_map.h"
      15             : 
      16             : registerMooseObject("MooseApp", DiscreteVariableResidualNorm);
      17             : 
      18             : InputParameters
      19       14562 : DiscreteVariableResidualNorm::validParams()
      20             : {
      21       14562 :   InputParameters params = ElementPostprocessor::validParams();
      22             : 
      23       14562 :   params.addRequiredParam<VariableName>("variable",
      24             :                                         "The name of the variable to compute the residual for");
      25       14562 :   MooseEnum norm_type("l_1=0 l_2=1 l_inf=2");
      26       14562 :   norm_type.addDocumentation("l_1", "l-1 norm");
      27       14562 :   norm_type.addDocumentation("l_2", "l-2 norm");
      28       14562 :   norm_type.addDocumentation("l_inf", "l-infinity norm");
      29       14562 :   params.addRequiredParam<MooseEnum>("norm_type", norm_type, "Type of discrete norm to compute");
      30       43686 :   params.addParam<bool>(
      31             :       "correct_mesh_bias",
      32       29124 :       false,
      33             :       "If set to true, correct the mesh size bias associated with the selected norm. For l-1, "
      34             :       "divide by N, the number of block-restricted DoFs for the variable. For l-2, divide by "
      35             :       "sqrt(N). For l-infinity, no correction needs to be made.");
      36             : 
      37       14562 :   params.addClassDescription("Computes a discrete norm for a block-restricted variable residual.");
      38             : 
      39       29124 :   return params;
      40       14562 : }
      41             : 
      42         154 : DiscreteVariableResidualNorm::DiscreteVariableResidualNorm(const InputParameters & parameters)
      43             :   : ElementPostprocessor(parameters),
      44         462 :     _var(_fe_problem.getVariable(_tid,
      45         154 :                                  getParam<VariableName>("variable"),
      46             :                                  Moose::VarKindType::VAR_SOLVER,
      47             :                                  Moose::VarFieldType::VAR_FIELD_STANDARD)),
      48         154 :     _norm_type(getParam<MooseEnum>("norm_type").getEnum<NormType>()),
      49         154 :     _correct_mesh_bias(getParam<bool>("correct_mesh_bias")),
      50         308 :     _nl_residual_vector(_fe_problem.getNonlinearSystemBase(_sys.number()).RHS())
      51             : {
      52         154 : }
      53             : 
      54             : void
      55         143 : DiscreteVariableResidualNorm::initialize()
      56             : {
      57         143 :   _norm = 0;
      58         143 :   _local_dof_indices.clear();
      59         143 :   _nonlocal_dof_indices_map.clear();
      60         143 : }
      61             : 
      62             : void
      63        1170 : DiscreteVariableResidualNorm::execute()
      64             : {
      65        5175 :   for (const auto dof_index : _var.dofIndices())
      66             :   {
      67             :     // Dof indices may not be owned by the same processor as the current element
      68        4005 :     if (_var.dofMap().local_index(dof_index))
      69        3867 :       _local_dof_indices.insert(dof_index);
      70             :     else
      71             :     {
      72             :       // if a Dof is non-local add it to a map, to be communicated to the owner in finalize()
      73         138 :       const auto dof_owner = _var.dofMap().dof_owner(dof_index);
      74         138 :       _nonlocal_dof_indices_map[dof_owner].push_back(dof_index);
      75             :     }
      76             :   }
      77        1170 : }
      78             : 
      79             : void
      80          11 : DiscreteVariableResidualNorm::threadJoin(const UserObject & y)
      81             : {
      82          11 :   const auto & pps = static_cast<const DiscreteVariableResidualNorm &>(y);
      83          11 :   _local_dof_indices.insert(pps._local_dof_indices.begin(), pps._local_dof_indices.end());
      84          11 : }
      85             : 
      86             : void
      87         132 : DiscreteVariableResidualNorm::finalize()
      88             : {
      89             :   // communicate the non-local Dofs to their processors
      90          21 :   auto receive_functor = [&](processor_id_type /*pid*/, const std::vector<dof_id_type> & indices)
      91          21 :   { _local_dof_indices.insert(indices.begin(), indices.end()); };
      92         132 :   Parallel::push_parallel_vector_data(_communicator, _nonlocal_dof_indices_map, receive_functor);
      93             : 
      94             :   // compute the total number of Dofs for the variable on the subdomain
      95         132 :   auto n_dofs = _local_dof_indices.size();
      96         132 :   gatherSum(n_dofs);
      97             : 
      98         132 :   Real bias = 1.0;
      99         132 :   switch (_norm_type)
     100             :   {
     101          60 :     case NormType::l_1:
     102          60 :       _norm = _nl_residual_vector.subset_l1_norm(_local_dof_indices);
     103          60 :       bias = n_dofs;
     104          60 :       break;
     105          36 :     case NormType::l_2:
     106          36 :       _norm = _nl_residual_vector.subset_l2_norm(_local_dof_indices);
     107          36 :       bias = sqrt(n_dofs);
     108          36 :       break;
     109          36 :     case NormType::l_inf:
     110          36 :       _norm = _nl_residual_vector.subset_linfty_norm(_local_dof_indices);
     111          36 :       break;
     112           0 :     default:
     113           0 :       mooseError("Invalid norm type");
     114             :   }
     115             : 
     116         132 :   if (_correct_mesh_bias)
     117          36 :     _norm /= bias;
     118         132 : }
     119             : 
     120             : PostprocessorValue
     121         132 : DiscreteVariableResidualNorm::getValue() const
     122             : {
     123         132 :   return _norm;
     124             : }

Generated by: LCOV version 1.14