https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
18registerMooseAction("PorousFlowApp", PorousFlowAddMaterialJoiner, "add_joiners");
19
22{
25 "Adds PorousFlowJoiner materials as required for each phase-dependent property");
26 return params;
27}
28
30 : Action(params), _already_joined()
31{
32}
33
34void
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");
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
187void
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;
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
220bool
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}
registerMooseAction("PorousFlowApp", PorousFlowAddMaterialJoiner, "add_joiners")
std::vector< const T * > getActions()
static InputParameters validParams()
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
ActionWarehouse & _awh
InputParameters getValidParams(const std::string &name) const
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
bool isParamValid(const std::string &name) const
void mooseDeprecated(Args &&... args) const
const std::string & getMooseObjectType() const
InputParameters & getObjectParams()
Factory & _factory
Action to programatically add PorousFlowJoiner materials without having to manually enter them in the...
std::string _dictator_name
Name of the PorousFlowDictator.
PorousFlowAddMaterialJoiner(const InputParameters &params)
bool _block_restricted
whether the Material that is currently being Joined is block-restricted
std::vector< std::string > _already_joined
Vector of already joined materials (to avoid joining them again)
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.
bool hasJoiner(std::string property)
Helper method to determine if a PorousFLowJoiner material is already present in the input file for th...
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...