LCOV - code coverage report
Current view: top level - src/actions - PorousFlowAddMaterialAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #31405 (292dce) with base fef103 Lines: 82 83 98.8 %
Date: 2025-09-04 07:55:56 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          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 "PorousFlowAddMaterialAction.h"
      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             : InputParameters
      27        9647 : PorousFlowAddMaterialAction::validParams()
      28             : {
      29        9647 :   InputParameters params = Action::validParams();
      30        9647 :   params.addClassDescription(
      31             :       "Makes sure that the correct nodal and/or qp materials are added for each property");
      32        9647 :   return params;
      33           0 : }
      34             : 
      35        9647 : PorousFlowAddMaterialAction::PorousFlowAddMaterialAction(const InputParameters & params)
      36        9647 :   : Action(params), PorousFlowDependencies()
      37             : {
      38        9647 : }
      39             : 
      40             : void
      41        9647 : PorousFlowAddMaterialAction::act()
      42             : {
      43             :   // Create the list of kernels, auxkernels, actions etc that each material may be
      44             :   // required by
      45        9647 :   createDependencyList();
      46             : 
      47             :   // Get the list of materials that have been added
      48        9647 :   auto actions = _awh.getActions<AddMaterialAction>();
      49             : 
      50       64509 :   for (auto & action : actions)
      51       54862 :     _ama_materials.push_back(const_cast<AddMaterialAction *>(action));
      52             : 
      53       64509 :   for (auto & material : _ama_materials)
      54             :   {
      55       54862 :     InputParameters & pars = material->getObjectParams();
      56             : 
      57             :     // Check if the material is a PorousFlow material
      58      109724 :     if (pars.isParamValid("pf_material_type"))
      59             :     {
      60       50965 :       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       50965 :       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      101588 :         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       84018 :           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       29173 :             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      112028 :           if (isPFMaterialRequired(pf_material_type, at_nodes) &&
      96       28010 :               !isPFMaterialPresent(material, at_nodes))
      97             :           {
      98       27858 :             if (!qp_material_required)
      99        8458 :               pars.set<bool>("at_nodes") = at_nodes;
     100             :             else
     101       19400 :               addPFMaterial(material, at_nodes);
     102             :           }
     103             :         }
     104             :       }
     105             :     }
     106             :   }
     107        9647 : }
     108             : 
     109             : void
     110        9647 : PorousFlowAddMaterialAction::createDependencyList()
     111             : {
     112             :   // Unique list of kernels added in input file
     113        9647 :   auto kernels = _awh.getActions<AddKernelAction>();
     114       47538 :   for (auto & kernel : kernels)
     115       37891 :     _dependency_list.insert(kernel->getMooseObjectType());
     116             : 
     117             :   // Unique list of PorousFlowActions added in input file
     118        9647 :   auto actions = _awh.getActions<PorousFlowActionBase>();
     119       10924 :   for (auto & action : actions)
     120        1277 :     _dependency_list.insert(action->name());
     121             : 
     122             :   // Unique list of auxkernels added in input file
     123        9647 :   auto auxkernels = _awh.getActions<AddKernelAction>();
     124       47538 :   for (auto & auxkernel : auxkernels)
     125       37891 :     _dependency_list.insert(auxkernel->getMooseObjectType());
     126             : 
     127             :   // Unique list of postprocessors added in input file
     128        9647 :   auto postprocessors = _awh.getActions<AddPostprocessorAction>();
     129       41303 :   for (auto & postprocessor : postprocessors)
     130       31656 :     _dependency_list.insert(postprocessor->getMooseObjectType());
     131             : 
     132             :   // Unique list of userojects added in input file
     133        9647 :   auto userobjects = _awh.getActions<AddUserObjectAction>();
     134       34182 :   for (auto & userobject : userobjects)
     135       24535 :     _dependency_list.insert(userobject->getMooseObjectType());
     136             : 
     137             :   // Unique list of BCs added in input file
     138        9647 :   auto bcs = _awh.getActions<AddBCAction>();
     139       22568 :   for (auto & bc : bcs)
     140       12921 :     _dependency_list.insert(bc->getMooseObjectType());
     141             : 
     142             :   // Unique list of Dirac kernels added in input file
     143        9647 :   auto diracs = _awh.getActions<AddDiracKernelAction>();
     144       11660 :   for (auto & dirac : diracs)
     145        2013 :     _dependency_list.insert(dirac->getMooseObjectType());
     146        9647 : }
     147             : 
     148             : bool
     149       84018 : PorousFlowAddMaterialAction::isPFMaterialRequired(std::string pf_material_type, bool at_nodes)
     150             : {
     151      126027 :   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      427220 :   for (auto item : _dependency_list)
     156             :   {
     157      400385 :     required = _deps.dependsOn(item, pf_material_type + nodal_ext);
     158      400385 :     if (required)
     159             :       break;
     160             :   }
     161             : 
     162       84018 :   return required;
     163             : }
     164             : 
     165             : bool
     166       28010 : PorousFlowAddMaterialAction::isPFMaterialPresent(AddMaterialAction * material, bool at_nodes)
     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      242110 :   for (auto & ama_material : _ama_materials)
     173             :   {
     174      214100 :     if (ama_material->name() != material->name() &&
     175      186090 :         ama_material->getMooseObjectType() == material->getMooseObjectType())
     176             :     {
     177             :       InputParameters & mat_params = ama_material->getObjectParams();
     178        4486 :       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        6198 :       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        8972 :       if (pars.isParamValid("phase"))
     191             :       {
     192        4220 :         const unsigned int phase = pars.get<unsigned int>("phase");
     193             : 
     194        8098 :         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        4486 :       if (mat_params.get<std::vector<SubdomainName>>("block") !=
     201             :           pars.get<std::vector<SubdomainName>>("block"))
     202             :         is_present = false;
     203             :     }
     204             :   }
     205             : 
     206       28010 :   return is_present;
     207             : }
     208             : 
     209             : void
     210       19400 : PorousFlowAddMaterialAction::addPFMaterial(AddMaterialAction * material, bool at_nodes)
     211             : {
     212       19400 :   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       19400 :   const std::string pf_material_type = pars.get<std::string>("pf_material_type");
     219       19400 :   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       38800 :   if (pars.isParamValid("phase"))
     224             :   {
     225        4814 :     unsigned int phase = pars.get<unsigned int>("phase");
     226        9628 :     phase_str = "_phase" + Moose::stringify(phase);
     227             :   }
     228             : 
     229             :   // Add material to the action warehouse
     230       19400 :   InputParameters action_params = _action_factory.getValidParams("AddMaterialAction");
     231       19400 :   action_params.set<ActionWarehouse *>("awh") = &_awh;
     232             : 
     233             :   // Setup action for passed in material type
     234       38800 :   action_params.set<std::string>("type") = moose_object_type;
     235             : 
     236       19400 :   const std::string material_name = material->name() + phase_str + nodal_ext;
     237             : 
     238             :   auto action = MooseSharedNamespace::dynamic_pointer_cast<MooseObjectAction>(
     239       38800 :       _action_factory.create("AddMaterialAction", material_name, action_params));
     240             : 
     241       19400 :   action->getObjectParams().applyParameters(pars);
     242       19400 :   action->getObjectParams().set<bool>("at_nodes") = at_nodes;
     243             : 
     244       58200 :   _awh.addActionBlock(action);
     245       38800 : }

Generated by: LCOV version 1.14