https://mooseframework.inl.gov
Loading...
Searching...
No Matches
FVPorousFlowFluidMass.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
13
16{
18 params.addParam<unsigned int>(
19 "fluid_component",
20 0,
21 "The index corresponding to the fluid component that this Postprocessor acts on");
22 params.addRequiredParam<UserObjectName>(
23 "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
24 params.addParam<std::vector<unsigned int>>("phase",
25 {},
26 "The index of the fluid phase that this "
27 "Postprocessor is restricted to. Multiple "
28 "indices can be entered");
29 params.addRangeCheckedParam<Real>("saturation_threshold",
30 1.0,
31 "saturation_threshold >= 0 & saturation_threshold <= 1",
32 "The saturation threshold below which the mass is calculated "
33 "for a specific phase. Default is 1.0. Note: only one "
34 "phase_index can be entered");
35 params.addParam<std::string>(
36 "base_name",
37 "For non-mechanically-coupled systems with no TensorMechanics strain calculators, base_name "
38 "need not be set. For mechanically-coupled systems, base_name should be the same base_name "
39 "as given to the TensorMechanics object that computes strain, so that this Postprocessor can "
40 "correctly account for changes in mesh volume. For non-mechanically-coupled systems, "
41 "base_name should not be the base_name of any TensorMechanics strain calculators.");
42 params.set<bool>("use_displaced_mesh") = false;
43 params.suppressParameter<bool>("use_displaced_mesh");
44 params.addClassDescription("Calculates the mass of a fluid component in a region");
45 return params;
46}
47
49 : ElementIntegralPostprocessor(parameters),
50 _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
51 _fluid_component(getParam<unsigned int>("fluid_component")),
52 _phase_index(getParam<std::vector<unsigned int>>("phase")),
53 _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
54 _has_total_strain(hasMaterialProperty<RankTwoTensor>(_base_name + "total_strain")),
55 _total_strain(_has_total_strain
56 ? &getMaterialProperty<RankTwoTensor>(_base_name + "total_strain")
57 : nullptr),
58 _porosity(getADMaterialProperty<Real>("PorousFlow_porosity_qp")),
59 _fluid_density(getADMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_density_qp")),
60 _fluid_saturation(getADMaterialProperty<std::vector<Real>>("PorousFlow_saturation_qp")),
61 _mass_fraction(
62 getADMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_qp")),
63 _saturation_threshold(getParam<Real>("saturation_threshold"))
64{
65 const unsigned int num_phases = _dictator.numPhases();
66 const unsigned int num_components = _dictator.numComponents();
67
68 // Check that the number of components entered is not greater than the total number of components
69 if (_fluid_component >= num_components)
71 "fluid_component",
72 "The Dictator proclaims that the number of components in this simulation is ",
73 num_components,
74 " whereas you have used a component index of ",
76 ". Remember that indexing starts at 0. The Dictator does not take such mistakes lightly.");
77
78 // Check that the number of phases entered is not more than the total possible phases
79 if (_phase_index.size() > num_phases)
80 paramError("phase",
81 "The Dictator decrees that the number of phases in this simulation is ",
82 num_phases,
83 " but you have entered ",
84 _phase_index.size(),
85 " phases.");
86
87 // Also check that the phase indices entered are not greater than the number of phases
88 // to avoid a segfault. Note that the input parser takes care of negative inputs so we
89 // don't need to guard against them
90 if (!_phase_index.empty())
91 {
92 unsigned int max_phase_num = *std::max_element(_phase_index.begin(), _phase_index.end());
93 if (max_phase_num > num_phases - 1)
94 paramError("phase",
95 "The Dictator proclaims that the phase index ",
96 max_phase_num,
97 " is greater than the largest phase index possible, which is ",
98 num_phases - 1);
99 }
100
101 // Using saturation_threshold only makes sense for a specific phase_index
102 if (_saturation_threshold < 1.0 && _phase_index.size() != 1)
103 paramError("saturation_threshold",
104 "A single phase_index must be entered when prescribing a saturation_threshold");
105
106 // If _phase_index is empty, create vector of all phase numbers to calculate mass over all phases
107 if (_phase_index.empty())
108 for (unsigned int i = 0; i < num_phases; ++i)
109 _phase_index.push_back(i);
110
111 // Error if a strain base_name is provided but doesn't exist
112 if (parameters.isParamSetByUser("base_name") && !_has_total_strain)
113 paramError("base_name", "A strain base_name ", _base_name, " does not exist");
114}
115
116Real
118{
119 // The fluid mass for the finite volume case is much simpler
120 Real mass = 0.0;
121 const Real strain = (_has_total_strain ? (*_total_strain)[_qp].trace() : 0.0);
122
123 for (auto ph : _phase_index)
124 {
128 }
129
130 return MetaPhysicL::raw_value(_porosity[_qp]) * (1.0 + strain) * mass;
131}
registerMooseObject("PorousFlowApp", FVPorousFlowFluidMass)
void ErrorVector unsigned int
static InputParameters validParams()
Postprocessor that calculates the mass of a given fluid component in the given phase(s) in a given bl...
const bool _has_total_strain
Whether there is a Material called _base_name_total_strain.
const Real _saturation_threshold
Saturation threshold - only fluid mass at saturations below this are calculated.
static InputParameters validParams()
const ADMaterialProperty< std::vector< Real > > & _fluid_density
Phase density (kg/m^3)
FVPorousFlowFluidMass(const InputParameters &parameters)
const unsigned int _fluid_component
The fluid component index that this Postprocessor applies to.
std::vector< unsigned int > _phase_index
The phase indices that this Postprocessor is restricted to.
const ADMaterialProperty< std::vector< Real > > & _fluid_saturation
Phase saturation (-)
virtual Real computeQpIntegral() override
const ADMaterialProperty< Real > & _porosity
Porosity.
const ADMaterialProperty< std::vector< std::vector< Real > > > & _mass_fraction
Mass fraction of each fluid component in each phase.
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
const std::string _base_name
base name used in the Tensor Mechanics strain calculator
void suppressParameter(const std::string &name)
bool isParamSetByUser(const std::string &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const InputParameters & parameters() const
void paramError(const std::string &param, Args... args) const
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
unsigned int numPhases() const
The number of fluid phases.
unsigned int numComponents() const
The number of fluid components.
auto raw_value(const Eigen::Map< T > &in)