LCOV - code coverage report
Current view: top level - src/correctors - PointwiseRenormalizeVector.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 54 62 87.1 %
Date: 2025-07-17 01:28:37 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             : #include "PointwiseRenormalizeVector.h"
      11             : #include "MooseError.h"
      12             : #include "NonlinearSystemBase.h"
      13             : 
      14             : #include "libmesh/numeric_vector.h"
      15             : #include "libmesh/int_range.h"
      16             : 
      17             : registerMooseObject("MooseApp", PointwiseRenormalizeVector);
      18             : 
      19             : InputParameters
      20       14289 : PointwiseRenormalizeVector::validParams()
      21             : {
      22       14289 :   InputParameters params = GeneralUserObject::validParams();
      23       14289 :   params.addClassDescription(
      24             :       "Pointwise renormalize the solution of a set of variables comprising a vector");
      25       14289 :   params.addCoupledVar("v", "Variables comprising the vector");
      26       14289 :   params.addParam<Real>("norm", 1.0, "Desired norm for the coupled variable vector");
      27       14289 :   params.registerBase("Corrector");
      28             : 
      29       14289 :   return params;
      30           0 : }
      31             : 
      32          12 : PointwiseRenormalizeVector::PointwiseRenormalizeVector(const InputParameters & parameters)
      33             :   : GeneralUserObject(parameters),
      34          24 :     _mesh(_fe_problem.mesh()),
      35          12 :     _var_names(getParam<std::vector<VariableName>>("v")),
      36          24 :     _target_norm(getParam<Real>("norm"))
      37             : {
      38          12 :   const MooseVariableFieldBase * first_var = nullptr;
      39          36 :   for (const auto & var_name : _var_names)
      40             :   {
      41          24 :     auto & var = _fe_problem.getVariable(0, var_name);
      42          24 :     if (!first_var)
      43          12 :       first_var = &var;
      44             :     else
      45             :     {
      46             :       // check order and family for consistency
      47          12 :       if (first_var->feType() != var.feType())
      48           0 :         paramError("v", "All supplied variables must be of the same order and family.");
      49             :       // check block restriction for consistency
      50          12 :       if (!first_var->hasBlocks(var.blockIDs()) || !var.hasBlocks(first_var->blockIDs()))
      51           0 :         paramError("v", "All supplied variables must have the same block restriction.");
      52             :     }
      53             : 
      54          24 :     if (_sys.number() != var.sys().system().number())
      55           0 :       paramError("v", "Variables must be all in the non-linear system.");
      56             : 
      57          24 :     if (var.isArray())
      58             :     {
      59           0 :       const auto & array_var = _fe_problem.getArrayVariable(0, var_name);
      60           0 :       for (unsigned int p = 0; p < var.count(); ++p)
      61           0 :         _var_numbers.push_back(_sys.system().variable_number(array_var.componentName(p)));
      62             :     }
      63             :     else
      64          24 :       _var_numbers.push_back(_sys.system().variable_number(var_name));
      65             :   }
      66          12 : }
      67             : 
      68             : void
      69         110 : PointwiseRenormalizeVector::initialize()
      70             : {
      71             :   // do one solution.close to get updated
      72         110 :   _sys.system().solution->close();
      73         110 : }
      74             : 
      75             : void
      76         110 : PointwiseRenormalizeVector::execute()
      77             : {
      78         110 :   auto & dof_map = _sys.system().get_dof_map();
      79         110 :   const auto local_dof_begin = dof_map.first_dof();
      80         110 :   const auto local_dof_end = dof_map.end_dof();
      81             : 
      82         110 :   std::vector<std::vector<dof_id_type>> dof_indices(_var_numbers.size());
      83         110 :   std::vector<Real> cache(_var_numbers.size());
      84             : 
      85        8110 :   for (const auto & elem : *_mesh.getActiveLocalElementRange())
      86             :   {
      87             :     // prepare variable dofs
      88       24000 :     for (const auto i : index_range(_var_numbers))
      89             :     {
      90       16000 :       dof_map.dof_indices(elem, dof_indices[i], _var_numbers[i]);
      91             : 
      92             :       // check that all vars have the same number of dofs
      93             :       mooseAssert(dof_indices[i].size() == dof_indices[0].size(),
      94             :                   "All specified variables should have the same number of DOFs");
      95             :     }
      96             : 
      97             :     // iterate over current, old, and older solutions
      98       32000 :     for (const auto s : make_range(3))
      99       24000 :       if (_sys.hasSolutionState(s))
     100             :       {
     101       16000 :         auto & solution = _sys.solutionState(s);
     102             : 
     103             :         // loop over all DOFs
     104       80000 :         for (const auto j : index_range(dof_indices[0]))
     105             :         {
     106             :           // check if the first variable's DOFs are local (if they are all other variables should
     107             :           // have local DOFS as well)
     108       64000 :           if (dof_indices[0][j] > local_dof_end || dof_indices[0][j] < local_dof_begin)
     109        1360 :             continue;
     110             : 
     111             :           // compute current norm
     112       62640 :           Real norm = 0.0;
     113      187920 :           for (const auto i : index_range(_var_numbers))
     114      125280 :             norm += Utility::pow<2>(solution(dof_indices[i][j]));
     115             : 
     116       62640 :           if (norm == 0.0)
     117           0 :             continue;
     118       62640 :           norm = std::sqrt(norm);
     119             : 
     120             :           // renormalize
     121      187920 :           for (const auto i : index_range(_var_numbers))
     122      125280 :             solution.set(dof_indices[i][j], solution(dof_indices[i][j]) / norm * _target_norm);
     123             :         }
     124             :       }
     125             :   }
     126         110 : }
     127             : 
     128             : void
     129         110 : PointwiseRenormalizeVector::finalize()
     130             : {
     131         440 :   for (const auto s : make_range(3))
     132         330 :     if (_sys.hasSolutionState(s))
     133         220 :       _sys.solutionState(s).close();
     134             : 
     135         110 :   _sys.update();
     136         110 : }

Generated by: LCOV version 1.14