www.mooseframework.org
PorousFlowAddMaterialAction.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 
11 #include "AddBCAction.h"
12 #include "AddDiracKernelAction.h"
13 #include "AddKernelAction.h"
14 #include "AddMaterialAction.h"
15 #include "AddPostprocessorAction.h"
16 #include "AddUserObjectAction.h"
17 #include "PorousFlowActionBase.h"
18 #include "ActionWarehouse.h"
19 #include "ActionFactory.h"
20 #include "FEProblem.h"
21 #include "MooseObjectAction.h"
22 #include "Conversion.h"
23 
24 registerMooseAction("PorousFlowApp", PorousFlowAddMaterialAction, "meta_action");
25 
28 {
30  params.addClassDescription(
31  "Makes sure that the correct nodal and/or qp materials are added for each property");
32  return params;
33 }
34 
36  : Action(params), PorousFlowDependencies()
37 {
38 }
39 
40 void
42 {
43  // Create the list of kernels, auxkernels, actions etc that each material may be
44  // required by
46 
47  // Get the list of materials that have been added
48  auto actions = _awh.getActions<AddMaterialAction>();
49 
50  for (auto & action : actions)
51  _ama_materials.push_back(const_cast<AddMaterialAction *>(action));
52 
53  for (auto & material : _ama_materials)
54  {
55  InputParameters & pars = material->getObjectParams();
56 
57  // Check if the material is a PorousFlow material
58  if (pars.isParamValid("pf_material_type"))
59  {
60  const std::string pf_material_type = pars.get<std::string>("pf_material_type");
61 
62  // PorousFlowJoiner materials are added automatically by the PorousFlowAddMaterialJoiner
63  // action, so no need to check these here
64  if (pf_material_type != "joiner")
65  {
66  // There are two possibilities that must be considered:
67  // 1) The parameter at_nodes has been set by the user. In this case, the material will
68  // be added as normal by AddMaterialAction
69  // 2) The parameter at_nodes has not been set by the user. In this case, this action
70  // will check to see if the material is required at the qps, at the nodes, or possibly both
71 
72  // Only check the second possibility
73  if (!pars.isParamSetByUser("at_nodes"))
74  {
75  bool qp_material_required = false;
76 
77  // First, check the case at_nodes = false, as this is the default behaviour for the
78  // at_nodes parameter. Note: the local variable at_nodes is set to true, so the material
79  // is at the qps when !at_nodes
80  const bool at_nodes = true;
81 
82  if (isPFMaterialRequired(pf_material_type, !at_nodes))
83  {
84  // This material is required at the qps, so add it as normal (setting the paramter
85  // at_nodes = false for clarity)
86  pars.set<bool>("at_nodes") = !at_nodes;
87  qp_material_required = true;
88  }
89 
90  // Check if the material is required at the nodes as well and that it isn't already
91  // added in the input file. If it is needed and not already supplied, then it is added
92  // in one of two ways: 1) If the material wasn't also required at the qps (checked above),
93  // then we can simply set the at_nodes parameter to true. 2) If it was also required at
94  // the qps, then a new material action is required to be added to the action warehouse
95  if (isPFMaterialRequired(pf_material_type, at_nodes) &&
96  !isPFMaterialPresent(material, at_nodes))
97  {
98  if (!qp_material_required)
99  pars.set<bool>("at_nodes") = at_nodes;
100  else
101  addPFMaterial(material, at_nodes);
102  }
103  }
104  }
105  }
106  }
107 }
108 
109 void
111 {
112  // Unique list of kernels added in input file
113  auto kernels = _awh.getActions<AddKernelAction>();
114  for (auto & kernel : kernels)
115  _dependency_list.insert(kernel->getMooseObjectType());
116 
117  // Unique list of PorousFlowActions added in input file
118  auto actions = _awh.getActions<PorousFlowActionBase>();
119  for (auto & action : actions)
120  _dependency_list.insert(action->name());
121 
122  // Unique list of auxkernels added in input file
123  auto auxkernels = _awh.getActions<AddKernelAction>();
124  for (auto & auxkernel : auxkernels)
125  _dependency_list.insert(auxkernel->getMooseObjectType());
126 
127  // Unique list of postprocessors added in input file
128  auto postprocessors = _awh.getActions<AddPostprocessorAction>();
129  for (auto & postprocessor : postprocessors)
130  _dependency_list.insert(postprocessor->getMooseObjectType());
131 
132  // Unique list of userojects added in input file
133  auto userobjects = _awh.getActions<AddUserObjectAction>();
134  for (auto & userobject : userobjects)
135  _dependency_list.insert(userobject->getMooseObjectType());
136 
137  // Unique list of BCs added in input file
138  auto bcs = _awh.getActions<AddBCAction>();
139  for (auto & bc : bcs)
140  _dependency_list.insert(bc->getMooseObjectType());
141 
142  // Unique list of Dirac kernels added in input file
143  auto diracs = _awh.getActions<AddDiracKernelAction>();
144  for (auto & dirac : diracs)
145  _dependency_list.insert(dirac->getMooseObjectType());
146 }
147 
148 bool
149 PorousFlowAddMaterialAction::isPFMaterialRequired(std::string pf_material_type, bool at_nodes)
150 {
151  const std::string nodal_ext = at_nodes ? "_nodal" : "_qp";
152 
153  // Check if this material is required by looping through the list of dependencies
154  bool required = false;
155  for (auto item : _dependency_list)
156  {
157  required = _deps.dependsOn(item, pf_material_type + nodal_ext);
158  if (required)
159  break;
160  }
161 
162  return required;
163 }
164 
165 bool
167 {
168  bool is_present = false;
169 
170  // Need to check that it hasn't been added in the input file also to
171  // avoid a duplicate material property error
172  for (auto & ama_material : _ama_materials)
173  {
174  if (ama_material->name() != material->name() &&
175  ama_material->getMooseObjectType() == material->getMooseObjectType())
176  {
177  InputParameters & mat_params = ama_material->getObjectParams();
178  const bool mat_at_nodes = mat_params.get<bool>("at_nodes");
179 
180  InputParameters & pars = material->getObjectParams();
181 
182  // If the material isn't related to a fluid phase, it is present if
183  // its at_nodes parameter is equal to the given at_nodes
184  if (mat_at_nodes == at_nodes && !pars.isParamValid("phase"))
185  is_present = true;
186 
187  // If the material is related to a fluid phase, it is present if
188  // its at_nodes parameter is equal to the given at_nodes, and its
189  // phase is equal to phase
190  if (pars.isParamValid("phase"))
191  {
192  const unsigned int phase = pars.get<unsigned int>("phase");
193 
194  if (mat_params.isParamValid("phase") && mat_params.get<unsigned int>("phase") == phase)
195  is_present = true;
196  }
197 
198  // Finally, if the material is block restricted then it is not already
199  // present if the block parameter is not identical
200  if (mat_params.get<std::vector<SubdomainName>>("block") !=
201  pars.get<std::vector<SubdomainName>>("block"))
202  is_present = false;
203  }
204  }
205 
206  return is_present;
207 }
208 
209 void
211 {
212  const std::string nodal_ext = at_nodes ? "_nodal" : "_qp";
213 
214  // Input parameters for the material that is being added
215  InputParameters & pars = material->getObjectParams();
216 
217  // PorousFlowMaterial type
218  const std::string pf_material_type = pars.get<std::string>("pf_material_type");
219  const std::string moose_object_type = material->getMooseObjectType();
220 
221  // If it is a material that also has a fluid phase, then extract that to add to name
222  std::string phase_str;
223  if (pars.isParamValid("phase"))
224  {
225  unsigned int phase = pars.get<unsigned int>("phase");
226  phase_str = "_phase" + Moose::stringify(phase);
227  }
228 
229  // Add material to the action warehouse
230  InputParameters action_params = _action_factory.getValidParams("AddMaterialAction");
231  action_params.set<ActionWarehouse *>("awh") = &_awh;
232 
233  // Setup action for passed in material type
234  action_params.set<std::string>("type") = moose_object_type;
235 
236  const std::string material_name = material->name() + phase_str + nodal_ext;
237 
238  auto action = MooseSharedNamespace::dynamic_pointer_cast<MooseObjectAction>(
239  _action_factory.create("AddMaterialAction", material_name, action_params));
240 
241  action->getObjectParams().applyParameters(pars);
242  action->getObjectParams().set<bool>("at_nodes") = at_nodes;
243 
244  _awh.addActionBlock(action);
245 }
bool isPFMaterialPresent(AddMaterialAction *material, bool at_nodes)
Check to see if the material with a given at_nodes parameter has already been included in the input f...
void addPFMaterial(AddMaterialAction *material, bool at_nodes)
Adds the material for the given at_nodes parameter.
PorousFlowAddMaterialAction(const InputParameters &params)
ActionWarehouse & _awh
InputParameters getValidParams(const std::string &name)
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)
bool dependsOn(const std::string &key, const std::string &value)
void applyParameters(const InputParameters &common, const std::vector< std::string > &exclude={}, const bool allow_private=false)
void addActionBlock(std::shared_ptr< Action > blk)
bool isPFMaterialRequired(std::string pf_material_type, bool at_nodes)
Check to see if the material with a given at_nodes parameter is required.
virtual const std::string & name() const
static InputParameters validParams()
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
std::set< std::string > _dependency_list
List of kernels, actions etc that may depend on PorousFlow materials.
static InputParameters validParams()
InputParameters & getObjectParams()
Base class for PorousFlow actions.
ActionFactory & _action_factory
std::string stringify(const T &t)
const std::string & getMooseObjectType() const
bool isParamSetByUser(const std::string &name) const
Holds the PorousFlow dependencies of kernels, auxkernels, materials, etc.
Action to automatically ensure that PorousFlowMaterials are correctly evaluated at either the qps...
void addClassDescription(const std::string &doc_string)
std::vector< AddMaterialAction * > _ama_materials
List of all materials added in the input file by AddMaterialAction.
std::vector< const T *> getActions()
registerMooseAction("PorousFlowApp", PorousFlowAddMaterialAction, "meta_action")
void createDependencyList()
Creates a set of all actions, kernels, etc to check material dependency against in order to determine...
DependencyResolver< std::string > _deps
All dependencies of kernels, auxkernels, materials, etc, are stored in _dependencies.
bool isParamValid(const std::string &name) const