https://mooseframework.inl.gov
PointwiseRenormalizeVector.C
Go to the documentation of this file.
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 
11 #include "MooseError.h"
12 #include "NonlinearSystemBase.h"
13 
14 #include "libmesh/numeric_vector.h"
15 #include "libmesh/int_range.h"
16 
18 
21 {
23  params.addClassDescription(
24  "Pointwise renormalize the solution of a set of variables comprising a vector");
25  params.addCoupledVar("v", "Variables comprising the vector");
26  params.addParam<Real>("norm", 1.0, "Desired norm for the coupled variable vector");
27  params.registerBase("Corrector");
28 
29  return params;
30 }
31 
33  : GeneralUserObject(parameters),
34  _mesh(_fe_problem.mesh()),
35  _var_names(getParam<std::vector<VariableName>>("v")),
36  _target_norm(getParam<Real>("norm"))
37 {
38  const MooseVariableFieldBase * first_var = nullptr;
39  for (const auto & var_name : _var_names)
40  {
41  auto & var = _fe_problem.getVariable(0, var_name);
42  if (!first_var)
43  first_var = &var;
44  else
45  {
46  // check order and family for consistency
47  if (first_var->feType() != var.feType())
48  paramError("v", "All supplied variables must be of the same order and family.");
49  // check block restriction for consistency
50  if (!first_var->hasBlocks(var.blockIDs()) || !var.hasBlocks(first_var->blockIDs()))
51  paramError("v", "All supplied variables must have the same block restriction.");
52  }
53 
54  if (_sys.number() != var.sys().system().number())
55  paramError("v", "Variables must be all in the non-linear system.");
56 
57  if (var.isArray())
58  {
59  const auto & array_var = _fe_problem.getArrayVariable(0, var_name);
60  for (unsigned int p = 0; p < var.count(); ++p)
61  _var_numbers.push_back(_sys.system().variable_number(array_var.componentName(p)));
62  }
63  else
64  _var_numbers.push_back(_sys.system().variable_number(var_name));
65  }
66 }
67 
68 void
70 {
71  // do one solution.close to get updated
72  _sys.system().solution->close();
73 }
74 
75 void
77 {
78  auto & dof_map = _sys.system().get_dof_map();
79  const auto local_dof_begin = dof_map.first_dof();
80  const auto local_dof_end = dof_map.end_dof();
81 
82  std::vector<std::vector<dof_id_type>> dof_indices(_var_numbers.size());
83  std::vector<Real> cache(_var_numbers.size());
84 
85  for (const auto & elem : *_mesh.getActiveLocalElementRange())
86  {
87  // prepare variable dofs
88  for (const auto i : index_range(_var_numbers))
89  {
90  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  for (const auto s : make_range(3))
99  if (_sys.hasSolutionState(s))
100  {
101  auto & solution = _sys.solutionState(s);
102 
103  // loop over all DOFs
104  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  if (dof_indices[0][j] > local_dof_end || dof_indices[0][j] < local_dof_begin)
109  continue;
110 
111  // compute current norm
112  Real norm = 0.0;
113  for (const auto i : index_range(_var_numbers))
114  norm += Utility::pow<2>(solution(dof_indices[i][j]));
115 
116  if (norm == 0.0)
117  continue;
118  norm = std::sqrt(norm);
119 
120  // renormalize
121  for (const auto i : index_range(_var_numbers))
122  solution.set(dof_indices[i][j], solution(dof_indices[i][j]) / norm * _target_norm);
123  }
124  }
125  }
126 }
127 
128 void
130 {
131  for (const auto s : make_range(3))
132  if (_sys.hasSolutionState(s))
133  _sys.solutionState(s).close();
134 
135  _sys.update();
136 }
libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems...
Definition: MooseMesh.C:1238
const libMesh::FEType & feType() const
Get the type of finite element object.
void execute() override
Execute method.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition: MooseBase.h:435
static InputParameters validParams()
static InputParameters validParams()
const std::vector< VariableName > & _var_names
names of the variables to renormalize
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
virtual NumericVector< Number > & solutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time)
Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
Definition: SystemBase.C:1423
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted, this function returns all mesh subdomain ids.
void initialize() override
Called before execute() is ever called so that data can be cleared.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
unsigned int variable_number(std::string_view var) const
void update()
Update the system (doing libMesh magic)
Definition: SystemBase.C:1235
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
std::unique_ptr< NumericVector< Number > > solution
std::vector< unsigned int > _var_numbers
MooseMesh & _mesh
reference to the mesh
registerMooseObject("MooseApp", PointwiseRenormalizeVector)
SystemBase & _sys
Reference to the system object for this user object.
Definition: UserObject.h:215
virtual bool hasSolutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time) const
Whether or not the system has the solution state (0 = current, 1 = old, 2 = older, etc).
Definition: SystemBase.h:1090
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1149
auto norm(const T &a) -> decltype(std::abs(a))
virtual void close()=0
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
Definition: UserObject.h:211
Renormalization of a vector variable (i.e.
IntRange< T > make_range(T beg, T end)
const Real _target_norm
desired norm
PointwiseRenormalizeVector(const InputParameters &parameters)
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
void finalize() override
Finalize.
virtual ArrayMooseVariable & getArrayVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested ArrayMooseVariable which may be in any system...
dof_id_type first_dof(const processor_id_type proc) const
bool hasBlocks(const SubdomainName &name) const
Test if the supplied block name is valid for this object.
const DofMap & get_dof_map() const
auto index_range(const T &sizable)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template pow< 2 >(tan(_arg))+1.0) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(sqrt