www.mooseframework.org
RichardsMultiphaseProblem.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
12 // MOOSE includes
13 #include "MooseMesh.h"
14 #include "MooseVariable.h"
15 #include "NonlinearSystem.h"
16 
18 
21 {
23  params.addRequiredParam<NonlinearVariableName>(
24  "bounded_var", "Variable whose value will be constrained to be greater than lower_var");
25  params.addRequiredParam<NonlinearVariableName>(
26  "lower_var",
27  "Variable that acts as a lower bound to bounded_var. It will not be "
28  "constrained during the solution procedure");
29  return params;
30 }
31 
33  : FEProblem(params),
34  // in the following have to get the names of the variables, and then find their numbers in
35  // initialSetup,
36  // as their numbers won't be defined at the moment of instantiation of this class
37  _bounded_var_name(params.get<NonlinearVariableName>("bounded_var")),
38  _lower_var_name(params.get<NonlinearVariableName>("lower_var")),
39  _bounded_var_num(0),
40  _lower_var_num(0)
41 {
42 }
43 
45 
46 void
48 {
49  // the first argument to getVariable is threadID - i hope the following always works
50  unsigned int tid = 0;
51 
52  // We are going to do more specific checks below, hence allowing
53  // more specific error messages to be printed in case something goes
54  // wrong. Therefore we just pass VAR_ANY here.
55  MooseVariableFEBase & bounded = getVariable(
56  tid, _bounded_var_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_STANDARD);
58  tid, _lower_var_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_STANDARD);
59 
60  // some checks
61  if (!bounded.isNodal() || !lower.isNodal())
62  mooseError("Both the bounded and lower variables must be nodal variables in "
63  "RichardsMultiphaseProblem");
64  if (bounded.feType().family != lower.feType().family)
65  mooseError("Both the bounded and lower variables must belong to the same element family, eg "
66  "LAGRANGE, in RichardsMultiphaseProblem");
67  if (bounded.feType().order != lower.feType().order)
68  mooseError("Both the bounded and lower variables must have the same order, eg FIRST, in "
69  "RichardsMultiphaseProblem");
70 
71  // extract the required info
72  _bounded_var_num = bounded.number();
73  _lower_var_num = lower.number();
74 
76 }
77 
78 bool
80 {
81  return true;
82 }
83 
84 bool
86  NumericVector<Number> & ghosted_solution)
87 {
88  bool updatedSolution =
89  false; // this gets set to true if we needed to enforce the bound at any node
90 
91  unsigned int sys_num = getNonlinearSystemBase(/*nl_sys_num=*/0).number();
92 
93  // For parallel procs i believe that i have to use local_nodes_begin, rather than just nodes_begin
94  // _mesh comes from SystemBase (_mesh = getNonlinearSystemBase().subproblem().mesh(), and
95  // subproblem is this object)
96  for (const auto & node : _mesh.getMesh().local_node_ptr_range())
97  {
98  // dofs[0] is the dof number of the bounded variable at this node
99  // dofs[1] is the dof number of the lower variable at this node
100  std::vector<dof_id_type> dofs(2);
101  dofs[0] = node->dof_number(sys_num, _bounded_var_num, 0);
102  dofs[1] = node->dof_number(sys_num, _lower_var_num, 0);
103 
104  // soln[0] is the value of the bounded variable at this node
105  // soln[1] is the value of the lower variable at this node
106  std::vector<Number> soln(2);
107  vec_solution.get(dofs, soln);
108 
109  // do the bounding
110  if (soln[0] < soln[1])
111  {
112  vec_solution.set(dofs[0], soln[1]); // set the bounded variable equal to the lower value
113  updatedSolution = true;
114  }
115  }
116 
117  // The above vec_solution.set calls potentially added "set" commands to a queue
118  // The following actions the queue (doing MPI commands if necessary), so
119  // vec_solution will actually be modified by this following command
120  vec_solution.close();
121 
122  // if any proc updated the solution, all procs will know about it
123  _communicator.max(updatedSolution);
124 
125  if (updatedSolution)
126  {
127  ghosted_solution = vec_solution;
128  ghosted_solution.close();
129  }
130 
131  return updatedSolution;
132 }
NonlinearVariableName _bounded_var_name
name of the bounded variable (this is the variable that gets altered to respect bounded_var > lower_v...
virtual bool isNodal() const
NonlinearVariableName _lower_var_name
name of the variable that acts as the lower bound to bounded_var
virtual void get(const std::vector< numeric_index_type > &index, Number *values) const
virtual bool shouldUpdateSolution()
returns true, indicating that updateSolution should be run
unsigned int number() const
RichardsMultiphaseProblem(const InputParameters &params)
const Parallel::Communicator & _communicator
unsigned int _bounded_var_num
internal moose variable number associated with _bounded_var
static InputParameters validParams()
const FEType & feType() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
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
unsigned int _lower_var_num
internal moose variable number associated with _lower_var
virtual void initialSetup()
extracts the moose variable numbers associated with bounded_var and lower_var
MeshBase & getMesh()
Allows a constraint u>=v to be enforced during the nonlinear iteration process.
virtual bool updateSolution(NumericVector< Number > &vec_solution, NumericVector< Number > &ghosted_solution)
Does the bounding by modifying vec_solution, and then ghosted_solution.
MooseMesh & _mesh
void initialSetup() override
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
unsigned int number() const
virtual void close()=0
void max(const T &r, T &o, Request &req) const
registerMooseObject("RichardsApp", RichardsMultiphaseProblem)
void mooseError(Args &&... args) const
static InputParameters validParams()
virtual void set(const numeric_index_type i, const Number value)=0
const Elem & get(const ElemType type_in)