www.mooseframework.org
PorousFlowMassFraction.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 
10 #include "PorousFlowMassFraction.h"
11 
14 
15 template <bool is_ad>
18 {
20  params.addCoupledVar(
21  "mass_fraction_vars",
22  "List of variables that represent the mass fractions. Format is 'f_ph0^c0 "
23  "f_ph0^c1 f_ph0^c2 ... f_ph0^c(N-2) f_ph1^c0 f_ph1^c1 fph1^c2 ... "
24  "fph1^c(N-2) ... fphP^c0 f_phP^c1 fphP^c2 ... fphP^c(N-2)' where "
25  "N=num_components and P=num_phases, and it is assumed that "
26  "f_ph^c(N-1)=1-sum(f_ph^c,{c,0,N-2}) so that f_ph^c(N-1) need not be given. If no "
27  "variables are provided then num_phases=1=num_components.");
28  params.addPrivateParam<std::string>("pf_material_type", "mass_fraction");
29  params.addClassDescription("This Material forms a std::vector<std::vector ...> of mass-fractions "
30  "out of the individual mass fractions");
31  return params;
32 }
33 
34 template <bool is_ad>
36  : PorousFlowMaterialVectorBase(parameters),
37  _mass_frac(_nodal_material ? declareGenericProperty<std::vector<std::vector<Real>>, is_ad>(
38  "PorousFlow_mass_frac_nodal")
39  : declareGenericProperty<std::vector<std::vector<Real>>, is_ad>(
40  "PorousFlow_mass_frac_qp")),
41  _grad_mass_frac(_nodal_material
42  ? nullptr
43  : &declareGenericProperty<std::vector<std::vector<RealGradient>>, is_ad>(
44  "PorousFlow_grad_mass_frac_qp")),
45  _dmass_frac_dvar(is_ad ? nullptr
46  : _nodal_material
47  ? &declareProperty<std::vector<std::vector<std::vector<Real>>>>(
48  "dPorousFlow_mass_frac_nodal_dvar")
49  : &declareProperty<std::vector<std::vector<std::vector<Real>>>>(
50  "dPorousFlow_mass_frac_qp_dvar")),
51  _num_passed_mf_vars(isParamValid("mass_fraction_vars") ? coupledComponents("mass_fraction_vars")
52  : 0)
53 {
54  if (_num_phases < 1 || _num_components < 1)
55  mooseError("PorousFlowMassFraction: The Dictator proclaims that the number of phases is ",
57  " and the number of components is ",
59  ", and stipulates that you should not use PorousFlowMassFraction in this case");
60 
62  paramError("mass_fraction_vars",
63  "This value must be equal to the Dictator's num_phases (",
65  ") multiplied by num_components-1 (",
66  _num_components - 1,
67  ")");
68 
72  for (unsigned i = 0; i < _num_passed_mf_vars; ++i)
73  {
74  // If mass_fraction_vars are elemental AuxVariables (or constants), we want to use
75  // coupledGenericValue() rather than coupledGenericDofValue()
76  const bool is_nodal =
77  isCoupled("mass_fraction_vars") ? getFieldVar("mass_fraction_vars", i)->isNodal() : false;
78 
79  _mf_vars_num[i] = coupled("mass_fraction_vars", i);
80  _mf_vars[i] =
81  (_nodal_material && is_nodal ? &coupledGenericDofValue<is_ad>("mass_fraction_vars", i)
82  : &coupledGenericValue<is_ad>("mass_fraction_vars", i));
83  _grad_mf_vars[i] = &coupledGenericGradient<is_ad>("mass_fraction_vars", i);
84  }
85 }
86 
87 template <bool is_ad>
88 void
90 {
91  // all we need to do is compute _mass_frac for _nodal_materials
92  // but the following avoids code duplication
93  computeQpProperties();
94 }
95 
96 template <bool is_ad>
97 void
99 {
100  // size all properties correctly
101  _mass_frac[_qp].resize(_num_phases);
102 
103  if (!is_ad)
104  (*_dmass_frac_dvar)[_qp].resize(_num_phases);
105 
106  if (!_nodal_material)
107  (*_grad_mass_frac)[_qp].resize(_num_phases);
108 
109  for (unsigned int ph = 0; ph < _num_phases; ++ph)
110  {
111  _mass_frac[_qp][ph].resize(_num_components);
112 
113  if (!is_ad)
114  {
115  (*_dmass_frac_dvar)[_qp][ph].resize(_num_components);
116  for (unsigned int comp = 0; comp < _num_components; ++comp)
117  (*_dmass_frac_dvar)[_qp][ph][comp].assign(_num_var, 0.0);
118  }
119 
120  if (!_nodal_material)
121  (*_grad_mass_frac)[_qp][ph].resize(_num_components);
122  }
123 
124  // compute the values and derivatives
125  unsigned int i = 0;
126  for (unsigned int ph = 0; ph < _num_phases; ++ph)
127  {
128  GenericReal<is_ad> total_mass_frac = 0;
129 
130  if (!_nodal_material)
131  (*_grad_mass_frac)[_qp][ph][_num_components - 1] = 0.0;
132 
133  for (unsigned int comp = 0; comp < _num_components - 1; ++comp)
134  {
135  _mass_frac[_qp][ph][comp] = (*_mf_vars[i])[_qp];
136  total_mass_frac += _mass_frac[_qp][ph][comp];
137 
138  if (!_nodal_material)
139  {
140  (*_grad_mass_frac)[_qp][ph][comp] = (*_grad_mf_vars[i])[_qp];
141  (*_grad_mass_frac)[_qp][ph][_num_components - 1] -= (*_grad_mf_vars[i])[_qp];
142  }
143 
144  if (!is_ad && _dictator.isPorousFlowVariable(_mf_vars_num[i]))
145  {
146  // _mf_vars[i] is a PorousFlow variable
147  const unsigned int pf_var_num = _dictator.porousFlowVariableNum(_mf_vars_num[i]);
148  (*_dmass_frac_dvar)[_qp][ph][comp][pf_var_num] = 1.0;
149  (*_dmass_frac_dvar)[_qp][ph][_num_components - 1][pf_var_num] = -1.0;
150  }
151  i++;
152  }
153 
154  _mass_frac[_qp][ph][_num_components - 1] = 1.0 - total_mass_frac;
155  }
156 }
157 
159 template class PorousFlowMassFractionTempl<true>;
const unsigned int _num_phases
Number of phases.
Material designed to form a std::vector<std::vector> of mass fractions from the individual mass fract...
void addPrivateParam(const std::string &name, const T &value)
void mooseError(Args &&... args)
const unsigned int _num_passed_mf_vars
Number of mass-fraction variables provided by the user This needs to be num_phases*(_num_components -...
std::vector< unsigned int > _mf_vars_num
The variable number of the mass-fraction variables.
virtual void computeQpProperties() override
registerMooseObject("PorousFlowApp", PorousFlowMassFraction)
Base class for all PorousFlow vector materials.
const unsigned int _num_components
Number of fluid components.
std::vector< const GenericVariableGradient< is_ad > * > _grad_mf_vars
The gradient of the mass-fraction variables.
void addCoupledVar(const std::string &name, const std::string &doc_string)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addClassDescription(const std::string &doc_string)
virtual void initQpStatefulProperties() override
PorousFlowMassFractionTempl(const InputParameters &parameters)
std::vector< const GenericVariableValue< is_ad > * > _mf_vars
The mass-fraction variables.
typename Moose::GenericType< Real, is_ad > GenericReal
static InputParameters validParams()