https://mooseframework.inl.gov
PorousFlowAddMaterialJoiner.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 "AddMaterialAction.h"
12 #include "ActionWarehouse.h"
13 #include "FEProblem.h"
14 #include "Material.h"
15 #include "UserObject.h"
16 #include "PorousFlowDictator.h"
17 
18 registerMooseAction("PorousFlowApp", PorousFlowAddMaterialJoiner, "add_joiners");
19 
22 {
24  params.addClassDescription(
25  "Adds PorousFlowJoiner materials as required for each phase-dependent property");
26  return params;
27 }
28 
30  : Action(params), _already_joined()
31 {
32 }
33 
34 void
36 {
37  // This task only runs after the UserObject and material actions have run,
38  // so we can get the name of the PorousFlowDictator UserObject and all material
39  // types
40  if (_current_task == "add_joiners")
41  {
42  // Get the user objects that have been added to get the name of the PorousFlowDictator
43  std::vector<UserObject *> userobjects;
44  _problem->theWarehouse()
45  .query()
46  .condition<AttribSystem>("UserObject")
47  .condition<AttribThread>(0)
48  .queryInto(userobjects);
49  for (auto & userobject : userobjects)
50  if (dynamic_cast<PorousFlowDictator *>(userobject))
51  _dictator_name = userobject->name();
52 
53  // Get the list of materials that have been added
54  auto materials = _problem->getMaterialWarehouse().getObjects();
55  for (auto & mat : materials)
56  {
57  const InputParameters & params = mat->parameters();
58 
59  // Only check PorousFlowMaterials
60  if (params.isParamValid("pf_material_type"))
61  {
62  const std::string pf_material_type = params.get<std::string>("pf_material_type");
63 
64  _block_restricted = params.isParamValid("block");
65  if (_block_restricted &&
66  (pf_material_type == "fluid_properties" || pf_material_type == "relative_permeability"))
67  {
68  // this Material is block-restricted, and we're about to add Joiners for it, so must get
69  // a union of all the blocks for this material type in order to block-restrict the Joiner
70  std::set<SubdomainName> unique_blocks;
71  for (auto & mat2 : _problem->getMaterialWarehouse().getObjects())
72  {
73  const InputParameters & params2 = mat2->parameters();
74  if (params2.isParamValid("pf_material_type") &&
75  params2.get<std::string>("pf_material_type") == pf_material_type)
76  {
77  if (!params2.isParamValid("block"))
78  {
79  // a Material of this type is not block-restricted, so the non-block-restricted
80  // Joiner can be added
81  _block_restricted = false;
82  break;
83  }
84  const std::vector<SubdomainName> & bl =
85  params2.get<std::vector<SubdomainName>>("block");
86  std::copy(bl.begin(), bl.end(), std::inserter(unique_blocks, unique_blocks.end()));
87  }
88  }
89  _blocks.assign(unique_blocks.begin(), unique_blocks.end());
90  }
91 
92  // Check if the material is evaluated at the nodes or qps
93  const bool at_nodes = params.get<bool>("at_nodes");
94 
95  // Add joiner material for fluid properties materials
96  if (pf_material_type == "fluid_properties")
97  {
98  // Check if the material defines AD material properties
99  const bool is_ad = params.get<bool>("is_ad");
100 
101  // Key the addition of the joiner off the phase 0 fluid so it is only added once
102  if (params.get<unsigned int>("phase") == 0)
103  {
104  // Join density and viscosity if they are calculated
105  if (params.get<bool>("compute_density_and_viscosity"))
106  {
107  if (at_nodes)
108  {
109  addJoiner(at_nodes,
110  is_ad,
111  "PorousFlow_fluid_phase_density_nodal",
112  "PorousFlow_density_nodal_all");
113  addJoiner(at_nodes,
114  is_ad,
115  "PorousFlow_viscosity_nodal",
116  "PorousFlow_viscosity_nodal_all");
117  }
118  else
119  {
120  addJoiner(at_nodes,
121  is_ad,
122  "PorousFlow_fluid_phase_density_qp",
123  "PorousFlow_density_qp_all");
124  addJoiner(
125  at_nodes, is_ad, "PorousFlow_viscosity_qp", "PorousFlow_viscosity_qp_all");
126  }
127  }
128 
129  // Join enthalpy if it is calculated
130  if (params.get<bool>("compute_enthalpy"))
131  {
132  if (at_nodes)
133  addJoiner(at_nodes,
134  is_ad,
135  "PorousFlow_fluid_phase_enthalpy_nodal",
136  "PorousFlow_enthalpy_nodal_all");
137  else
138  addJoiner(at_nodes,
139  is_ad,
140  "PorousFlow_fluid_phase_enthalpy_qp",
141  "PorousFlow_enthalpy_qp_all");
142  }
143 
144  // Join internal energy if it is calculated
145  if (params.get<bool>("compute_internal_energy"))
146  {
147  if (at_nodes)
148  addJoiner(at_nodes,
149  is_ad,
150  "PorousFlow_fluid_phase_internal_energy_nodal",
151  "PorousFlow_internal_energy_nodal_all");
152  else
153  addJoiner(at_nodes,
154  is_ad,
155  "PorousFlow_fluid_phase_internal_energy_qp",
156  "PorousFlow_internal_energy_qp_all");
157  }
158  }
159  }
160 
161  // Add joiner materials for relative permeability materials
162  if (pf_material_type == "relative_permeability")
163  {
164  // Check if the material defines AD material properties
165  const bool is_ad = params.get<bool>("is_ad");
166 
167  // Key the addition of the joiner off the phase 0 fluid so it is only added once
168  if (params.get<unsigned int>("phase") == 0)
169  {
170  if (at_nodes)
171  addJoiner(at_nodes,
172  is_ad,
173  "PorousFlow_relative_permeability_nodal",
174  "PorousFlow_relative_permeability_nodal_all");
175  else
176  addJoiner(at_nodes,
177  is_ad,
178  "PorousFlow_relative_permeability_qp",
179  "PorousFlow_relative_permeability_qp_all");
180  }
181  }
182  }
183  }
184  }
185 }
186 
187 void
189  bool is_ad,
190  const std::string & material_property,
191  const std::string & output_name)
192 {
193  bool is_joined = false;
194 
195  // Check if this material is already joined
196  if (std::find(_already_joined.begin(), _already_joined.end(), material_property) !=
197  _already_joined.end())
198  is_joined = true;
199 
200  if (hasJoiner(material_property))
201  is_joined = true;
202 
203  if (!is_joined)
204  {
205  std::string material_type;
206  is_ad ? material_type = "ADPorousFlowJoiner" : material_type = "PorousFlowJoiner";
207  InputParameters params = _factory.getValidParams(material_type);
208  params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
209  params.set<bool>("at_nodes") = at_nodes;
210  params.set<std::string>("material_property") = material_property;
211  if (_block_restricted)
212  params.set<std::vector<SubdomainName>>("block") = _blocks;
213  _problem->addMaterial(material_type, output_name, params);
214 
215  // Add material to the already joined list
216  _already_joined.push_back(material_property);
217  }
218 }
219 
220 bool
222 {
223  // Get the list of materials in the input file
224  auto actions = _awh.getActions<AddMaterialAction>();
225 
226  for (auto & action : actions)
227  {
228  AddMaterialAction * material = const_cast<AddMaterialAction *>(action);
229 
230  if (material->getMooseObjectType() == "PorousFlowJoiner")
231  {
232  // If a PorousFlowJoiner material has been included in the input file,
233  // let the user know that it should be removed
234  mooseDeprecated("PorousFlowJoiner materials are no longer required in the input "
235  "file.\nPlease remove all PorousFlowJoiner materials from this input file to "
236  "get rid of this warning");
237 
238  const std::string joiner_property =
239  material->getObjectParams().get<std::string>("material_property");
240 
241  // Check if the given material property is joined by this material
242  if (joiner_property == property)
243  return true;
244  }
245  }
246 
247  // If no PorousFlowJoiner materials matched property, return false
248  return false;
249 }
void mooseDeprecated(Args &&... args) const
ActionWarehouse & _awh
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
Factory & _factory
std::string _dictator_name
Name of the PorousFlowDictator.
registerMooseAction("PorousFlowApp", PorousFlowAddMaterialJoiner, "add_joiners")
static InputParameters validParams()
InputParameters & getObjectParams()
PorousFlowAddMaterialJoiner(const InputParameters &params)
const std::string & _current_task
std::vector< SubdomainName > _blocks
if _block_restricted == true, then these are the blocks that the Joiner will be restricted to ...
void addJoiner(bool at_nodes, bool is_ad, const std::string &material_property, const std::string &output_name)
Adds a PorousFlowJoiner for the given material property.
static InputParameters validParams()
const std::string & getMooseObjectType() const
Action to programatically add PorousFlowJoiner materials without having to manually enter them in the...
bool hasJoiner(std::string property)
Helper method to determine if a PorousFLowJoiner material is already present in the input file for th...
void addClassDescription(const std::string &doc_string)
std::shared_ptr< FEProblemBase > & _problem
bool _block_restricted
whether the Material that is currently being Joined is block-restricted
std::vector< const T *> getActions()
std::vector< std::string > _already_joined
Vector of already joined materials (to avoid joining them again)
bool isParamValid(const std::string &name) const