LCOV - code coverage report
Current view: top level - src/actions - MaterialDerivativeTestAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 11 152 7.2 %
Date: 2025-07-17 01:28:37 Functions: 1 3 33.3 %
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 "MaterialDerivativeTestAction.h"
      11             : 
      12             : #include "Conversion.h"
      13             : #include "MooseEnum.h"
      14             : #include "FEProblemBase.h"
      15             : #include "MoosePreconditioner.h"
      16             : #include "NonlinearSystemBase.h"
      17             : #include "MooseVariableBase.h"
      18             : 
      19             : #include "libmesh/fe.h"
      20             : #include "libmesh/string_to_enum.h"
      21             : 
      22             : registerMooseAction("MooseApp", MaterialDerivativeTestAction, "add_variable");
      23             : 
      24             : registerMooseAction("MooseApp", MaterialDerivativeTestAction, "add_kernel");
      25             : 
      26             : registerMooseAction("MooseApp", MaterialDerivativeTestAction, "add_preconditioning");
      27             : 
      28             : InputParameters
      29         203 : MaterialDerivativeTestAction::validParams()
      30             : {
      31         203 :   InputParameters params = Action::validParams();
      32         203 :   params.addClassDescription(
      33             :       "Action for setting up the necessary objects for debugging material property derivatives.");
      34         203 :   params.addParam<std::vector<VariableName>>("args",
      35             :                                              "Variables the tested material property depends on.");
      36         203 :   params.addRequiredParam<MaterialPropertyName>(
      37             :       "prop_name", "Name of the material property to test the derivatives of.");
      38         203 :   MooseEnum prop_type_enum("Real RankTwoTensor RankFourTensor");
      39         203 :   params.addParam<MooseEnum>(
      40             :       "prop_type", prop_type_enum, "Type of the material property to test the derivatives of.");
      41         609 :   params.addParam<unsigned int>(
      42         406 :       "derivative_order", 0, "Highest order derivative to test derivatives of.");
      43         406 :   return params;
      44         203 : }
      45             : 
      46           0 : MaterialDerivativeTestAction::MaterialDerivativeTestAction(const InputParameters & parameters)
      47             :   : Action(parameters),
      48           0 :     _args(getParam<std::vector<VariableName>>("args")),
      49           0 :     _prop_name(getParam<MaterialPropertyName>("prop_name")),
      50           0 :     _prop_type(getParam<MooseEnum>("prop_type").getEnum<PropTypeEnum>()),
      51           0 :     _derivative_order(getParam<unsigned int>("derivative_order")),
      52           0 :     _second(false),
      53           0 :     _derivatives({{_prop_name, {}}})
      54             : {
      55           0 :   std::vector<std::vector<std::vector<SymbolName>>> derivative_table(_derivative_order + 1);
      56             : 
      57             :   // 0th derivative is a (single) derivative w.r.t. to _no_ variables
      58           0 :   derivative_table[0] = {{}};
      59             : 
      60             :   // build higher order derivatives
      61           0 :   for (unsigned int n = 1; n <= _derivative_order; ++n)
      62           0 :     for (const auto & function : derivative_table[n - 1])
      63           0 :       for (const auto & var : _args)
      64             :       {
      65             :         // take previous order derivative and derive w.r.t. one of the args
      66           0 :         auto derivative = std::vector<SymbolName>(function);
      67           0 :         derivative.push_back(var);
      68             : 
      69             :         // add derivative to list
      70           0 :         derivative_table[n].push_back(derivative);
      71           0 :         _derivatives.insert(
      72           0 :             std::make_pair(derivativePropertyName(_prop_name, derivative), derivative));
      73           0 :       }
      74           0 : }
      75             : 
      76             : void
      77           0 : MaterialDerivativeTestAction::act()
      78             : {
      79             :   // finite element type
      80           0 :   const std::string order = _second ? "SECOND" : "FIRST";
      81           0 :   const std::string family("LAGRANGE");
      82           0 :   const auto type = "MooseVariable";
      83           0 :   auto params = _factory.getValidParams(type);
      84           0 :   params.set<MooseEnum>("order") = order;
      85           0 :   params.set<MooseEnum>("family") = family;
      86             : 
      87             :   // build higher order derivatives
      88           0 :   for (const auto & derivative : _derivatives)
      89             :   {
      90             :     // Create variables
      91           0 :     if (_current_task == "add_variable")
      92             :     {
      93           0 :       switch (_prop_type)
      94             :       {
      95           0 :         case PropTypeEnum::REAL:
      96           0 :           _problem->addVariable(type, "var_" + derivative.first, params);
      97           0 :           break;
      98             : 
      99           0 :         case PropTypeEnum::RANKTWOTENSOR:
     100           0 :           for (unsigned int i = 0; i < 3; ++i)
     101           0 :             for (unsigned int j = 0; j < 3; ++j)
     102           0 :               _problem->addVariable(type,
     103           0 :                                     "var_" + derivative.first + '_' + Moose::stringify(i) + '_' +
     104           0 :                                         Moose::stringify(j),
     105             :                                     params);
     106           0 :           break;
     107             : 
     108           0 :         case PropTypeEnum::RANKFOURTENSOR:
     109           0 :           for (unsigned int i = 0; i < 3; ++i)
     110           0 :             for (unsigned int j = 0; j < 3; ++j)
     111           0 :               for (unsigned int k = 0; k < 3; ++k)
     112           0 :                 for (unsigned int l = 0; l < 3; ++l)
     113           0 :                   _problem->addVariable(type,
     114           0 :                                         "var_" + derivative.first + '_' + Moose::stringify(i) +
     115           0 :                                             '_' + Moose::stringify(j) + '_' + Moose::stringify(k) +
     116           0 :                                             '_' + Moose::stringify(l),
     117             :                                         params);
     118           0 :           break;
     119             : 
     120           0 :         default:
     121           0 :           mooseError("Unknown property type.");
     122             :       }
     123             :     }
     124             : 
     125           0 :     if (_current_task == "add_kernel")
     126             :     {
     127           0 :       switch (_prop_type)
     128             :       {
     129           0 :         case PropTypeEnum::REAL:
     130             :         {
     131           0 :           auto params = _factory.getValidParams("MaterialDerivativeTestKernel");
     132           0 :           params.set<std::vector<VariableName>>("args") = _args;
     133           0 :           params.set<std::vector<SymbolName>>("derivative") = derivative.second;
     134           0 :           params.set<MaterialPropertyName>("material_property") = _prop_name;
     135           0 :           params.set<NonlinearVariableName>("variable") = "var_" + derivative.first;
     136           0 :           _problem->addKernel("MaterialDerivativeTestKernel", "kernel_" + derivative.first, params);
     137           0 :           break;
     138           0 :         }
     139             : 
     140           0 :         case PropTypeEnum::RANKTWOTENSOR:
     141             :         {
     142           0 :           auto params = _factory.getValidParams("MaterialDerivativeRankTwoTestKernel");
     143           0 :           params.set<std::vector<VariableName>>("args") = _args;
     144           0 :           params.set<std::vector<SymbolName>>("derivative") = derivative.second;
     145           0 :           params.set<MaterialPropertyName>("material_property") = _prop_name;
     146           0 :           for (unsigned int i = 0; i < 3; ++i)
     147           0 :             for (unsigned int j = 0; j < 3; ++j)
     148             :             {
     149             :               auto suffix =
     150           0 :                   derivative.first + '_' + Moose::stringify(i) + '_' + Moose::stringify(j);
     151           0 :               params.set<NonlinearVariableName>("variable") = "var_" + suffix;
     152           0 :               params.set<unsigned int>("i") = i;
     153           0 :               params.set<unsigned int>("j") = j;
     154           0 :               _problem->addKernel(
     155           0 :                   "MaterialDerivativeRankTwoTestKernel", "kernel_" + suffix, params);
     156           0 :             }
     157           0 :           break;
     158           0 :         }
     159             : 
     160           0 :         case PropTypeEnum::RANKFOURTENSOR:
     161             :         {
     162           0 :           auto params = _factory.getValidParams("MaterialDerivativeRankFourTestKernel");
     163           0 :           params.set<std::vector<VariableName>>("args") = _args;
     164           0 :           params.set<std::vector<SymbolName>>("derivative") = derivative.second;
     165           0 :           params.set<MaterialPropertyName>("material_property") = _prop_name;
     166           0 :           for (unsigned int i = 0; i < 3; ++i)
     167           0 :             for (unsigned int j = 0; j < 3; ++j)
     168           0 :               for (unsigned int k = 0; k < 3; ++k)
     169           0 :                 for (unsigned int l = 0; l < 3; ++l)
     170             :                 {
     171           0 :                   auto suffix = derivative.first + '_' + Moose::stringify(i) + '_' +
     172           0 :                                 Moose::stringify(j) + '_' + Moose::stringify(k) + '_' +
     173           0 :                                 Moose::stringify(l);
     174           0 :                   params.set<NonlinearVariableName>("variable") = "var_" + suffix;
     175           0 :                   params.set<unsigned int>("i") = i;
     176           0 :                   params.set<unsigned int>("j") = j;
     177           0 :                   params.set<unsigned int>("k") = k;
     178           0 :                   params.set<unsigned int>("l") = l;
     179           0 :                   _problem->addKernel(
     180           0 :                       "MaterialDerivativeRankFourTestKernel", "kernel_" + suffix, params);
     181           0 :                 }
     182           0 :           break;
     183           0 :         }
     184             : 
     185           0 :         default:
     186           0 :           mooseError("Unknown property type.");
     187             :       }
     188             :     }
     189             :   }
     190             : 
     191           0 :   if (_current_task == "add_preconditioning")
     192             :   {
     193           0 :     auto params = _factory.getValidParams("SMP");
     194           0 :     auto & row = params.set<std::vector<NonlinearVariableName>>("off_diag_row");
     195           0 :     auto & col = params.set<std::vector<NonlinearVariableName>>("off_diag_column");
     196             : 
     197           0 :     for (const auto & derivative : _derivatives)
     198             :     {
     199           0 :       switch (_prop_type)
     200             :       {
     201           0 :         case PropTypeEnum::REAL:
     202           0 :           for (auto & arg : _args)
     203             :           {
     204           0 :             row.push_back("var_" + derivative.first);
     205           0 :             col.push_back(arg);
     206             :           }
     207           0 :           break;
     208             : 
     209           0 :         case PropTypeEnum::RANKTWOTENSOR:
     210           0 :           for (unsigned int i = 0; i < 3; ++i)
     211           0 :             for (unsigned int j = 0; j < 3; ++j)
     212           0 :               for (auto & arg : _args)
     213             :               {
     214           0 :                 row.push_back("var_" + derivative.first + '_' + Moose::stringify(i) + '_' +
     215           0 :                               Moose::stringify(j));
     216           0 :                 col.push_back(arg);
     217             :               }
     218           0 :           break;
     219             : 
     220           0 :         case PropTypeEnum::RANKFOURTENSOR:
     221           0 :           for (unsigned int i = 0; i < 3; ++i)
     222           0 :             for (unsigned int j = 0; j < 3; ++j)
     223           0 :               for (unsigned int k = 0; k < 3; ++k)
     224           0 :                 for (unsigned int l = 0; l < 3; ++l)
     225           0 :                   for (auto & arg : _args)
     226             :                   {
     227           0 :                     row.push_back("var_" + derivative.first + '_' + Moose::stringify(i) + '_' +
     228           0 :                                   Moose::stringify(j) + '_' + Moose::stringify(k) + '_' +
     229           0 :                                   Moose::stringify(l));
     230           0 :                     col.push_back(arg);
     231             :                   }
     232           0 :           break;
     233             : 
     234           0 :         default:
     235           0 :           mooseError("Unknown property type.");
     236             :       }
     237             :     }
     238             : 
     239           0 :     if (_problem.get() != nullptr)
     240             :     {
     241             :       std::shared_ptr<MoosePreconditioner> pc =
     242           0 :           _factory.create<MoosePreconditioner>("SMP", "material_derivative_SMP", params);
     243             : 
     244           0 :       _problem->getNonlinearSystemBase(/*nl_sys=*/0).setPreconditioner(pc);
     245           0 :     }
     246             :     else
     247           0 :       mooseError("_problem.get() returned nullptr");
     248           0 :   }
     249           0 : }

Generated by: LCOV version 1.14