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