Line data Source code
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 "PorousFlowAddMaterialJoiner.h"
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 :
20 : InputParameters
21 9647 : PorousFlowAddMaterialJoiner::validParams()
22 : {
23 9647 : InputParameters params = Action::validParams();
24 9647 : params.addClassDescription(
25 : "Adds PorousFlowJoiner materials as required for each phase-dependent property");
26 9647 : return params;
27 0 : }
28 :
29 9647 : PorousFlowAddMaterialJoiner::PorousFlowAddMaterialJoiner(const InputParameters & params)
30 9647 : : Action(params), _already_joined()
31 : {
32 9647 : }
33 :
34 : void
35 9561 : PorousFlowAddMaterialJoiner::act()
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 9561 : 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 9561 : _problem->theWarehouse()
45 9561 : .query()
46 9561 : .condition<AttribSystem>("UserObject")
47 19122 : .condition<AttribThread>(0)
48 : .queryInto(userobjects);
49 39102 : for (auto & userobject : userobjects)
50 29541 : if (dynamic_cast<PorousFlowDictator *>(userobject))
51 9561 : _dictator_name = userobject->name();
52 :
53 : // Get the list of materials that have been added
54 9561 : auto materials = _problem->getMaterialWarehouse().getObjects();
55 95927 : for (auto & mat : materials)
56 : {
57 : const InputParameters & params = mat->parameters();
58 :
59 : // Only check PorousFlowMaterials
60 172732 : if (params.isParamValid("pf_material_type"))
61 : {
62 82469 : const std::string pf_material_type = params.get<std::string>("pf_material_type");
63 :
64 82469 : _block_restricted = params.isParamValid("block");
65 82469 : if (_block_restricted &&
66 13487 : (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 63050 : for (auto & mat2 : _problem->getMaterialWarehouse().getObjects())
72 : {
73 : const InputParameters & params2 = mat2->parameters();
74 120206 : if (params2.isParamValid("pf_material_type") &&
75 103440 : params2.get<std::string>("pf_material_type") == pf_material_type)
76 : {
77 23830 : 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 114 : _block_restricted = false;
82 114 : break;
83 : }
84 : const std::vector<SubdomainName> & bl =
85 11801 : params2.get<std::vector<SubdomainName>>("block");
86 11801 : std::copy(bl.begin(), bl.end(), std::inserter(unique_blocks, unique_blocks.end()));
87 : }
88 : }
89 3061 : _blocks.assign(unique_blocks.begin(), unique_blocks.end());
90 : }
91 :
92 : // Check if the material is evaluated at the nodes or qps
93 82469 : const bool at_nodes = params.get<bool>("at_nodes");
94 :
95 : // Add joiner material for fluid properties materials
96 82469 : if (pf_material_type == "fluid_properties")
97 : {
98 : // Check if the material defines AD material properties
99 11759 : 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 11759 : if (params.get<unsigned int>("phase") == 0)
103 : {
104 : // Join density and viscosity if they are calculated
105 9829 : if (params.get<bool>("compute_density_and_viscosity"))
106 : {
107 9772 : if (at_nodes)
108 : {
109 9760 : addJoiner(at_nodes,
110 : is_ad,
111 : "PorousFlow_fluid_phase_density_nodal",
112 : "PorousFlow_density_nodal_all");
113 9760 : addJoiner(at_nodes,
114 : is_ad,
115 : "PorousFlow_viscosity_nodal",
116 : "PorousFlow_viscosity_nodal_all");
117 : }
118 : else
119 : {
120 9784 : addJoiner(at_nodes,
121 : is_ad,
122 : "PorousFlow_fluid_phase_density_qp",
123 : "PorousFlow_density_qp_all");
124 9784 : addJoiner(
125 : at_nodes, is_ad, "PorousFlow_viscosity_qp", "PorousFlow_viscosity_qp_all");
126 : }
127 : }
128 :
129 : // Join enthalpy if it is calculated
130 9829 : if (params.get<bool>("compute_enthalpy"))
131 : {
132 7922 : if (at_nodes)
133 8562 : addJoiner(at_nodes,
134 : is_ad,
135 : "PorousFlow_fluid_phase_enthalpy_nodal",
136 : "PorousFlow_enthalpy_nodal_all");
137 : else
138 7282 : 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 9829 : if (params.get<bool>("compute_internal_energy"))
146 : {
147 7704 : if (at_nodes)
148 8486 : addJoiner(at_nodes,
149 : is_ad,
150 : "PorousFlow_fluid_phase_internal_energy_nodal",
151 : "PorousFlow_internal_energy_nodal_all");
152 : else
153 6922 : 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 82469 : if (pf_material_type == "relative_permeability")
163 : {
164 : // Check if the material defines AD material properties
165 9264 : 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 9264 : if (params.get<unsigned int>("phase") == 0)
169 : {
170 6853 : if (at_nodes)
171 6754 : addJoiner(at_nodes,
172 : is_ad,
173 : "PorousFlow_relative_permeability_nodal",
174 : "PorousFlow_relative_permeability_nodal_all");
175 : else
176 6952 : addJoiner(at_nodes,
177 : is_ad,
178 : "PorousFlow_relative_permeability_qp",
179 : "PorousFlow_relative_permeability_qp_all");
180 : }
181 : }
182 : }
183 : }
184 9561 : }
185 9561 : }
186 :
187 : void
188 42023 : PorousFlowAddMaterialJoiner::addJoiner(bool at_nodes,
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 42023 : if (std::find(_already_joined.begin(), _already_joined.end(), material_property) !=
197 : _already_joined.end())
198 : is_joined = true;
199 :
200 84046 : if (hasJoiner(material_property))
201 : is_joined = true;
202 :
203 41852 : if (!is_joined)
204 : {
205 : std::string material_type;
206 41434 : is_ad ? material_type = "ADPorousFlowJoiner" : material_type = "PorousFlowJoiner";
207 41434 : InputParameters params = _factory.getValidParams(material_type);
208 82868 : params.set<UserObjectName>("PorousFlowDictator") = _dictator_name;
209 41434 : params.set<bool>("at_nodes") = at_nodes;
210 41434 : params.set<std::string>("material_property") = material_property;
211 41434 : if (_block_restricted)
212 12024 : params.set<std::vector<SubdomainName>>("block") = _blocks;
213 41434 : _problem->addMaterial(material_type, output_name, params);
214 :
215 : // Add material to the already joined list
216 41434 : _already_joined.push_back(material_property);
217 41434 : }
218 42023 : }
219 :
220 : bool
221 42023 : PorousFlowAddMaterialJoiner::hasJoiner(std::string property)
222 : {
223 : // Get the list of materials in the input file
224 42023 : auto actions = _awh.getActions<AddMaterialAction>();
225 :
226 490775 : for (auto & action : actions)
227 : {
228 448923 : AddMaterialAction * material = const_cast<AddMaterialAction *>(action);
229 :
230 448923 : 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 855 : 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 855 : material->getObjectParams().get<std::string>("material_property");
240 :
241 : // Check if the given material property is joined by this material
242 855 : if (joiner_property == property)
243 : return true;
244 : }
245 : }
246 :
247 : // If no PorousFlowJoiner materials matched property, return false
248 : return false;
249 42023 : }
|