https://mooseframework.inl.gov
RichardsPolyLineSink.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 
10 #include "RichardsPolyLineSink.h"
11 
12 #include <fstream>
13 
15 
18 {
20  params.addRequiredParam<std::vector<Real>>(
21  "pressures", "Tuple of pressure values. Must be monotonically increasing.");
22  params.addRequiredParam<std::vector<Real>>(
23  "fluxes",
24  "Tuple of flux values (measured in kg.m^-3.s^-1). A piecewise-linear fit is "
25  "performed to the (pressure,flux) pairs to obtain the flux at any arbitrary "
26  "pressure. If a quad-point pressure is less than the first pressure value, the "
27  "first flux value is used. If quad-point pressure exceeds the final pressure "
28  "value, the final flux value is used. This flux is OUT of the medium: hence "
29  "positive values of flux means this will be a SINK, while negative values indicate "
30  "this flux will be a SOURCE.");
31  params.addRequiredParam<FileName>(
32  "point_file",
33  "The file containing the coordinates of the point sinks that will approximate "
34  "the polyline. Each line in the file must contain a space-separated "
35  "coordinate. Note that you will get segementation faults if your points do "
36  "not lie within your mesh!");
37  params.addRequiredParam<UserObjectName>(
38  "SumQuantityUO",
39  "User Object of type=RichardsSumQuantity in which to place the total "
40  "outflow from the polylinesink for each time step.");
41  params.addRequiredParam<UserObjectName>(
42  "richardsVarNames_UO", "The UserObject that holds the list of Richards variable names.");
43  params.addClassDescription("Approximates a polyline sink in the mesh by using a number of point "
44  "sinks whose positions are read from a file");
45  return params;
46 }
47 
49  : DiracKernel(parameters),
50  _total_outflow_mass(
51  const_cast<RichardsSumQuantity &>(getUserObject<RichardsSumQuantity>("SumQuantityUO"))),
52  _sink_func(getParam<std::vector<Real>>("pressures"), getParam<std::vector<Real>>("fluxes")),
53  _point_file(getParam<FileName>("point_file")),
54  _richards_name_UO(getUserObject<RichardsVarNames>("richardsVarNames_UO")),
55  _pvar(_richards_name_UO.richards_var_num(_var.number())),
56  _pp(getMaterialProperty<std::vector<Real>>("porepressure")),
57  _dpp_dv(getMaterialProperty<std::vector<std::vector<Real>>>("dporepressure_dv"))
58 {
59  // open file
60  std::ifstream file(_point_file.c_str());
61  if (!file.good())
62  mooseError("Error opening file '" + _point_file + "' from RichardsPolyLineSink.");
63 
64  std::vector<Real> scratch;
65  while (parseNextLineReals(file, scratch))
66  {
67  if (scratch.size() >= 1)
68  {
69  _xs.push_back(scratch[0]);
70  if (scratch.size() >= 2)
71  _ys.push_back(scratch[1]);
72  else
73  _ys.push_back(0.0);
74 
75  if (scratch.size() >= 3)
76  _zs.push_back(scratch[2]);
77  else
78  _zs.push_back(0.0);
79  }
80  }
81 
82  file.close();
83 
84  // To correctly compute the Jacobian terms,
85  // tell MOOSE that this DiracKernel depends on all the Richards Vars
86  const std::vector<MooseVariableFEBase *> & coupled_vars = _richards_name_UO.getCoupledMooseVars();
87  for (unsigned int i = 0; i < coupled_vars.size(); i++)
88  addMooseVariableDependency(coupled_vars[i]);
89 }
90 
91 bool
92 RichardsPolyLineSink::parseNextLineReals(std::ifstream & ifs, std::vector<Real> & myvec)
93 // reads a space-separated line of floats from ifs and puts in myvec
94 {
95  std::string line;
96  myvec.clear();
97  bool gotline(false);
98  if (getline(ifs, line))
99  {
100  gotline = true;
101 
102  // Harvest floats separated by whitespace
103  std::istringstream iss(line);
104  Real f;
105  while (iss >> f)
106  {
107  myvec.push_back(f);
108  }
109  }
110  return gotline;
111 }
112 
113 void
115 {
117 
118  // Add point using the unique ID "i", let the DiracKernel take
119  // care of the caching. This should be fast after the first call,
120  // as long as the points don't move around.
121  for (unsigned int i = 0; i < _zs.size(); i++)
122  addPoint(Point(_xs[i], _ys[i], _zs[i]), i);
123 }
124 
125 Real
127 {
128  Real test_fcn = _test[_i][_qp];
129  Real flow = test_fcn * _sink_func.sample(_pp[_qp][_pvar]);
130  _total_outflow_mass.add(flow * _dt);
131  return flow;
132 }
133 
134 Real
136 {
137  Real test_fcn = _test[_i][_qp];
138  return test_fcn * _sink_func.sampleDerivative(_pp[_qp][_pvar]) * _dpp_dv[_qp][_pvar][_pvar] *
139  _phi[_j][_qp];
140 }
141 
142 Real
144 {
146  return 0.0;
147  unsigned int dvar = _richards_name_UO.richards_var_num(jvar);
148  Real test_fcn = _test[_i][_qp];
149  return test_fcn * _sink_func.sampleDerivative(_pp[_qp][_pvar]) * _dpp_dv[_qp][_pvar][dvar] *
150  _phi[_j][_qp];
151 }
Sums into _total This is used, for instance, to record the total mass flowing into a borehole...
Approximates a polyline by a sequence of Dirac Points the mass flux from each Dirac Point is _sink_fu...
virtual Real computeQpResidual()
std::string _point_file
contains rows of the form x y z (space separated)
static InputParameters validParams()
void addPoint(const Elem *elem, Point p, unsigned id=libMesh::invalid_uint)
const OutputTools< T >::VariableTestValue & _test
const OutputTools< T >::VariablePhiValue & _phi
registerMooseObject("RichardsApp", RichardsPolyLineSink)
std::vector< Real > _ys
vector of Dirac Points&#39; y positions
bool not_richards_var(unsigned int moose_var_num) const
returns true if moose_var_num is not a richards var
T sample(const T &x) const
This holds maps between pressure_var or pressure_var, sat_var used in RichardsMaterial and kernels...
void addRequiredParam(const std::string &name, const std::string &doc_string)
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
Computes the off-diagonal part of the jacobian Note: at March2014 this is never called since moose do...
RichardsPolyLineSink(const InputParameters &parameters)
LinearInterpolation _sink_func
mass flux = _sink_func as a function of porepressure
T sampleDerivative(const T &x) const
virtual Real computeQpJacobian()
Real f(Real x)
Test function for Brents method.
void zero()
sets _total = 0
unsigned int _pvar
The moose internal variable number of the richards variable of this Dirac Kernel. ...
bool parseNextLineReals(std::ifstream &ifs, std::vector< Real > &myvec)
reads a space-separated line of floats from ifs and puts in myvec
RichardsSumQuantity & _total_outflow_mass
This is used to hold the total fluid flowing into the sink Hence, it is positive for sinks where flui...
void add(Real contrib)
adds contrib to _total
const std::vector< MooseVariableFieldBase *> & getCoupledMooseVars() const
const MaterialProperty< std::vector< Real > > & _pp
fluid porepressure (or porepressures in case of multiphase)
void addMooseVariableDependency(MooseVariableFieldBase *var)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int _j
unsigned int richards_var_num(unsigned int moose_var_num) const
the richards variable number
const MaterialProperty< std::vector< std::vector< Real > > > & _dpp_dv
d(porepressure_i)/d(variable_j)
unsigned int _qp
std::vector< Real > _xs
vector of Dirac Points&#39; x positions
std::vector< Real > _zs
vector of Dirac Points&#39; z positions
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
const RichardsVarNames & _richards_name_UO
Defines the richards variables in the simulation.
unsigned int _i
static InputParameters validParams()