LCOV - code coverage report
Current view: top level - src/actions - CohesiveZoneAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: #31405 (292dce) with base fef103 Lines: 175 214 81.8 %
Date: 2025-09-04 07:57:23 Functions: 12 13 92.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 "CohesiveZoneAction.h"
      11             : #include "AddAuxVariableAction.h"
      12             : #include "Factory.h"
      13             : #include "FEProblem.h"
      14             : #include "Conversion.h"
      15             : 
      16             : registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_interface_kernel");
      17             : registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_material");
      18             : registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_master_action_material");
      19             : registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_aux_variable");
      20             : registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_aux_kernel");
      21             : registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_kernel");
      22             : registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "validate_coordinate_systems");
      23             : 
      24             : InputParameters
      25         239 : CohesiveZoneAction::validParams()
      26             : {
      27         239 :   InputParameters params = CohesiveZoneActionBase::validParams();
      28         239 :   params.addClassDescription("Action to create an instance of the cohesive zone model kernel for "
      29             :                              "each displacement component");
      30         478 :   params.addRequiredParam<std::vector<BoundaryName>>(
      31             :       "boundary", "The list of boundary IDs from the mesh where the cohesive zone will be applied");
      32         239 :   return params;
      33           0 : }
      34             : 
      35         239 : CohesiveZoneAction::CohesiveZoneAction(const InputParameters & params)
      36             :   : CohesiveZoneActionBase(params),
      37         478 :     _displacements(getParam<std::vector<VariableName>>("displacements")),
      38         239 :     _ndisp(_displacements.size()),
      39         478 :     _use_AD(getParam<bool>("use_automatic_differentiation")),
      40         734 :     _base_name(isParamValid("base_name") && !getParam<std::string>("base_name").empty()
      41         239 :                    ? getParam<std::string>("base_name")
      42             :                    : ""),
      43         478 :     _boundary(getParam<std::vector<BoundaryName>>("boundary")),
      44         478 :     _strain(getParam<MooseEnum>("strain").getEnum<Strain>()),
      45         478 :     _save_in_master(getParam<std::vector<AuxVariableName>>("save_in_master")),
      46         478 :     _diag_save_in_master(getParam<std::vector<AuxVariableName>>("diag_save_in_master")),
      47         478 :     _save_in_slave(getParam<std::vector<AuxVariableName>>("save_in_slave")),
      48         717 :     _diag_save_in_slave(getParam<std::vector<AuxVariableName>>("diag_save_in_slave")),
      49         478 :     _material_output_order(getParam<MultiMooseEnum>("material_output_order")),
      50         717 :     _material_output_family(getParam<MultiMooseEnum>("material_output_family")),
      51         717 :     _verbose(getParam<bool>("verbose"))
      52             : {
      53             :   // We can't enforce consistency between the number of displacement variables and the mesh
      54             :   // dimension. Hence we only check we have a reasonable number of displacement variables
      55         239 :   if (_ndisp > 3 || _ndisp < 1)
      56           0 :     mooseError("the CZM Action requires 1, 2 or 3 displacement variables.");
      57             : 
      58         239 :   switch (_strain)
      59             :   {
      60         160 :     case Strain::Small:
      61             :     {
      62             :       _czm_kernel_name =
      63         313 :           _use_AD ? "ADCZMInterfaceKernelSmallStrain" : "CZMInterfaceKernelSmallStrain";
      64         160 :       _disp_jump_provider_name = _use_AD ? "ADCZMComputeDisplacementJumpSmallStrain"
      65         313 :                                          : "CZMComputeDisplacementJumpSmallStrain";
      66             :       _equilibrium_traction_calculator_name =
      67         313 :           _use_AD ? "ADCZMComputeGlobalTractionSmallStrain" : "CZMComputeGlobalTractionSmallStrain";
      68             :       break;
      69             :     }
      70          79 :     case Strain::Finite:
      71             :     {
      72             :       _czm_kernel_name =
      73         151 :           _use_AD ? "ADCZMInterfaceKernelTotalLagrangian" : "CZMInterfaceKernelTotalLagrangian";
      74          79 :       _disp_jump_provider_name = _use_AD ? "ADCZMComputeDisplacementJumpTotalLagrangian"
      75         151 :                                          : "CZMComputeDisplacementJumpTotalLagrangian";
      76          79 :       _equilibrium_traction_calculator_name = _use_AD ? "ADCZMComputeGlobalTractionTotalLagrangian"
      77         151 :                                                       : "CZMComputeGlobalTractionTotalLagrangian";
      78             :       break;
      79             :     }
      80           0 :     default:
      81           0 :       mooseError("CohesiveZoneAction Error: Invalid kinematic parameter. Allowed values are: "
      82             :                  "SmallStrain or TotalLagrangian");
      83             :   }
      84             : 
      85         239 :   if (_save_in_master.size() != 0 && _save_in_master.size() != _ndisp)
      86           0 :     mooseError(
      87             :         "Number of save_in_master variables should equal to the number of displacement variables ",
      88           0 :         _ndisp);
      89         239 :   if (_diag_save_in_master.size() != 0 && _diag_save_in_master.size() != _ndisp)
      90           0 :     mooseError("Number of diag_save_in_master variables should equal to the number of displacement "
      91             :                "variables ",
      92           0 :                _ndisp);
      93         239 :   if (_save_in_slave.size() != 0 && _save_in_slave.size() != _ndisp)
      94           0 :     mooseError(
      95             :         "Number of save_in_slave variables should equal to the number of displacement variables ",
      96           0 :         _ndisp);
      97             : 
      98         239 :   if (_diag_save_in_slave.size() != 0 && _diag_save_in_slave.size() != _ndisp)
      99           0 :     mooseError("Number of diag_save_in_slave variables should equal to the number of displacement "
     100             :                "variables ",
     101           0 :                _ndisp);
     102             : 
     103             :   // convert output variable names to lower case
     104        1836 :   for (const auto & out : getParam<MultiMooseEnum>("generate_output"))
     105             :   {
     106             :     std::string lower(out);
     107             :     std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
     108        1358 :     _generate_output.push_back(lower);
     109             :   }
     110             : 
     111         239 :   if (!_generate_output.empty())
     112         140 :     verifyOrderAndFamilyOutputs();
     113         239 : }
     114             : 
     115             : void
     116         231 : CohesiveZoneAction::addRequiredCZMInterfaceKernels()
     117             : {
     118         847 :   for (unsigned int i = 0; i < _ndisp; ++i)
     119             :   {
     120             :     // Create unique kernel name for each displacement component
     121        1848 :     std::string unique_kernel_name = _czm_kernel_name + "_" + _name + "_" + Moose::stringify(i);
     122             : 
     123         616 :     InputParameters paramsk = _factory.getValidParams(_czm_kernel_name);
     124             : 
     125         616 :     paramsk.set<unsigned int>("component") = i;
     126        1232 :     paramsk.set<NonlinearVariableName>("variable") = _displacements[i];
     127        1848 :     paramsk.set<std::vector<VariableName>>("neighbor_var") = {_displacements[i]};
     128         616 :     paramsk.set<std::vector<VariableName>>("displacements") = _displacements;
     129         616 :     paramsk.set<std::vector<BoundaryName>>("boundary") = _boundary;
     130        1232 :     paramsk.set<std::string>("base_name") = _base_name;
     131             : 
     132             :     std::string save_in_side;
     133             :     std::vector<AuxVariableName> save_in_var_names;
     134         616 :     if (_save_in_master.size() == _ndisp || _save_in_slave.size() == _ndisp)
     135             :     {
     136           0 :       prepareSaveInInputs(save_in_var_names, save_in_side, _save_in_master, _save_in_slave, i);
     137           0 :       paramsk.set<std::vector<AuxVariableName>>("save_in") = save_in_var_names;
     138           0 :       paramsk.set<MultiMooseEnum>("save_in_var_side") = save_in_side;
     139             :     }
     140         616 :     if (_diag_save_in_master.size() == _ndisp || _diag_save_in_slave.size() == _ndisp)
     141             :     {
     142           0 :       prepareSaveInInputs(
     143           0 :           save_in_var_names, save_in_side, _diag_save_in_master, _diag_save_in_slave, i);
     144           0 :       paramsk.set<std::vector<AuxVariableName>>("diag_save_in") = save_in_var_names;
     145           0 :       paramsk.set<MultiMooseEnum>("diag_save_in_var_side") = save_in_side;
     146             :     }
     147         616 :     _problem->addInterfaceKernel(_czm_kernel_name, unique_kernel_name, paramsk);
     148        1232 :   }
     149         231 : }
     150             : 
     151             : void
     152         231 : CohesiveZoneAction::addRequiredCZMInterfaceMaterials()
     153             : {
     154             :   // Create unique material name for the "CZMComputeDisplacementJump" object
     155         231 :   std::string unique_material_name = _disp_jump_provider_name + "_" + _name;
     156         231 :   InputParameters paramsm = _factory.getValidParams(_disp_jump_provider_name);
     157         231 :   paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
     158             :   ;
     159         231 :   paramsm.set<std::vector<VariableName>>("displacements") = _displacements;
     160         231 :   paramsm.set<std::string>("base_name") = _base_name;
     161         231 :   _problem->addInterfaceMaterial(_disp_jump_provider_name, unique_material_name, paramsm);
     162             : 
     163             :   // Create unique material name for the "CZMComputeGlobalTraction" object
     164         231 :   unique_material_name = _equilibrium_traction_calculator_name + "_" + _name;
     165         231 :   paramsm = _factory.getValidParams(_equilibrium_traction_calculator_name);
     166         231 :   paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
     167             :   ;
     168         231 :   paramsm.set<std::string>("base_name") = _base_name;
     169         231 :   _problem->addInterfaceMaterial(
     170             :       _equilibrium_traction_calculator_name, unique_material_name, paramsm);
     171         462 : }
     172             : 
     173             : void
     174        1621 : CohesiveZoneAction::act()
     175             : {
     176             :   // Enforce consistency
     177        1621 :   if (_ndisp != _mesh->dimension())
     178           0 :     paramError("displacements", "Number of displacements must match problem dimension.");
     179             : 
     180        1621 :   chekMultipleActionParameters();
     181             : 
     182        1617 :   if (_current_task == "add_interface_kernel")
     183         231 :     addRequiredCZMInterfaceKernels();
     184        1386 :   else if (_current_task == "add_master_action_material")
     185         231 :     addRequiredCZMInterfaceMaterials();
     186             : 
     187             :   // optional, add required outputs
     188        1617 :   actOutputGeneration();
     189        1617 : }
     190             : 
     191             : void
     192         701 : CohesiveZoneAction::addRelationshipManagers(Moose::RelationshipManagerType input_rm_type)
     193             : {
     194         701 :   InputParameters ips = _factory.getValidParams(_czm_kernel_name);
     195         701 :   addRelationshipManagers(input_rm_type, ips);
     196         701 : }
     197             : 
     198             : void
     199           0 : CohesiveZoneAction::prepareSaveInInputs(std::vector<AuxVariableName> & save_in_names,
     200             :                                         std::string & save_in_side,
     201             :                                         const std::vector<AuxVariableName> & var_name_master,
     202             :                                         const std::vector<AuxVariableName> & var_name_slave,
     203             :                                         const int & i) const
     204             : {
     205           0 :   save_in_names.clear();
     206             :   save_in_side.clear();
     207           0 :   if (var_name_master.size() == _ndisp)
     208             :   {
     209           0 :     save_in_names.push_back(var_name_master[i]);
     210             :     save_in_side += "m";
     211           0 :     if (var_name_slave.size() == _ndisp)
     212             :       save_in_side += " ";
     213             :   }
     214           0 :   if (var_name_slave.size() == _ndisp)
     215             :   {
     216           0 :     save_in_names.push_back(var_name_slave[i]);
     217             :     save_in_side += "s";
     218             :   }
     219           0 : }
     220             : 
     221             : void
     222         140 : CohesiveZoneAction::verifyOrderAndFamilyOutputs()
     223             : {
     224             :   // Ensure material output order and family vectors are same size as generate output
     225             : 
     226             :   // check number of supplied orders and families
     227         140 :   if (_material_output_order.size() > 1 && _material_output_order.size() < _generate_output.size())
     228           0 :     paramError("material_output_order",
     229             :                "The number of orders assigned to material outputs must be: 0 to be assigned "
     230             :                "CONSTANT; 1 to assign all outputs the same value, or the same size as the number "
     231             :                "of generate outputs listed.");
     232             : 
     233         140 :   if (_material_output_family.size() > 1 &&
     234           0 :       _material_output_family.size() < _generate_output.size())
     235           0 :     paramError("material_output_family",
     236             :                "The number of families assigned to material outputs must be: 0 to be assigned "
     237             :                "MONOMIAL; 1 to assign all outputs the same value, or the same size as the number "
     238             :                "of generate outputs listed.");
     239             : 
     240             :   // if no value was provided, chose the default CONSTANT
     241         140 :   if (_material_output_order.size() == 0)
     242         252 :     _material_output_order.setAdditionalValue("CONSTANT");
     243             : 
     244             :   // For only one order, make all orders the same magnitude
     245         140 :   if (_material_output_order.size() == 1)
     246             :     _material_output_order =
     247         140 :         std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
     248             : 
     249         140 :   if (_verbose)
     250           0 :     Moose::out << COLOR_CYAN << "*** Automatic applied material output orders ***"
     251             :                << "\n"
     252           0 :                << _name << ": " << Moose::stringify(_material_output_order) << "\n"
     253           0 :                << COLOR_DEFAULT;
     254             : 
     255             :   // if no value was provided, chose the default MONOMIAL
     256         140 :   if (_material_output_family.size() == 0)
     257         280 :     _material_output_family.setAdditionalValue("MONOMIAL");
     258             : 
     259             :   // For only one family, make all families that value
     260         140 :   if (_material_output_family.size() == 1)
     261             :     _material_output_family =
     262         140 :         std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
     263             : 
     264         140 :   if (_verbose)
     265           0 :     Moose::out << COLOR_CYAN << "*** Automatic applied material output families ***"
     266             :                << "\n"
     267           0 :                << _name << ": " << Moose::stringify(_material_output_family) << "\n"
     268           0 :                << COLOR_DEFAULT;
     269         140 : }
     270             : 
     271             : void
     272        1617 : CohesiveZoneAction::actOutputGeneration()
     273             : {
     274        1617 :   if (_current_task == "add_material")
     275         231 :     actOutputMatProp();
     276             : 
     277             :   // Add variables (optional)
     278        1617 :   if (_current_task == "add_aux_variable")
     279             :   {
     280             :     unsigned int index = 0;
     281        1589 :     for (auto out : _generate_output)
     282             :     {
     283        1358 :       const auto & order = _material_output_order[index];
     284        1358 :       const auto & family = _material_output_family[index];
     285             : 
     286        1218 :       std::string type = (order == "CONSTANT" && family == "MONOMIAL")
     287             :                              ? "MooseVariableConstMonomial"
     288        2716 :                              : "MooseVariable";
     289             : 
     290             :       // Create output helper aux variables
     291        1358 :       auto params = _factory.getValidParams(type);
     292        1358 :       params.set<MooseEnum>("order") = order;
     293        1358 :       params.set<MooseEnum>("family") = family;
     294        1358 :       if (family == "MONOMIAL")
     295        2716 :         _problem->addAuxVariable(type, addBaseName(out), params);
     296             :       else
     297           0 :         _problem->addVariable(type, addBaseName(out), params);
     298             : 
     299        1358 :       index++;
     300        1358 :     }
     301             :   }
     302             : 
     303             :   // Add output AuxKernels
     304        1386 :   else if (_current_task == "add_aux_kernel")
     305             :   {
     306         448 :     const std::string material_output_aux_name = _use_AD ? "ADMaterialRealAux" : "MaterialRealAux";
     307             :     // Loop through output aux variables
     308             :     unsigned int index = 0;
     309        1589 :     for (auto out : _generate_output)
     310             :     {
     311        1358 :       if (_material_output_family[index] == "MONOMIAL")
     312             :       {
     313        1358 :         InputParameters params = _factory.getValidParams(material_output_aux_name);
     314        4074 :         params.set<MaterialPropertyName>("property") = addBaseName(out);
     315        4074 :         params.set<AuxVariableName>("variable") = addBaseName(out);
     316        1358 :         params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
     317        1358 :         params.set<std::vector<BoundaryName>>("boundary") = _boundary;
     318        1358 :         params.set<bool>("check_boundary_restricted") = false;
     319        1358 :         _problem->addAuxKernel(material_output_aux_name, addBaseName(out) + '_' + name(), params);
     320        1358 :       }
     321        1358 :       index++;
     322             :     }
     323             :   }
     324        1617 : }
     325             : 
     326             : void
     327         231 : CohesiveZoneAction::actOutputMatProp()
     328             : {
     329         231 :   if (_current_task == "add_material")
     330             :   {
     331             :     // Add output Materials
     332        1589 :     for (auto out : _generate_output)
     333             :     {
     334        1358 :       InputParameters params = emptyInputParameters();
     335             : 
     336             :       // RealVectorCartesianComponent
     337        2184 :       if (
     338        2716 :           [&]()
     339             :           {
     340        3780 :             for (const auto & vq : _real_vector_cartesian_component_table)
     341       11312 :               for (unsigned int a = 0; a < 3; ++a)
     342       17780 :                 if (vq.first + '_' + _component_table[a] == out)
     343             :                 {
     344         826 :                   auto type = _use_AD ? "ADCZMRealVectorCartesianComponent"
     345             :                                       : "CZMRealVectorCartesianComponent";
     346         826 :                   params = _factory.getValidParams(type);
     347         826 :                   params.set<std::string>("real_vector_value") = vq.second;
     348         826 :                   params.set<unsigned int>("index") = a;
     349         826 :                   params.set<std::vector<BoundaryName>>("boundary") = _boundary;
     350        2478 :                   params.set<MaterialPropertyName>("property_name") = addBaseName(out);
     351         826 :                   params.set<std::string>("base_name") = _base_name;
     352        2478 :                   _problem->addInterfaceMaterial(type, addBaseName(out) + '_' + name(), params);
     353             :                   return true;
     354             :                 }
     355             :             return false;
     356        1358 :           }())
     357         826 :         continue;
     358             : 
     359             :       // CZMRealVectorScalar
     360        1064 :       if (setupOutput(out,
     361             :                       _vector_direction_table,
     362         532 :                       [&](std::string prop_name, std::string direction)
     363             :                       {
     364         532 :                         auto type = _use_AD ? "ADCZMRealVectorScalar" : "CZMRealVectorScalar";
     365         532 :                         params = _factory.getValidParams(type);
     366         532 :                         params.set<std::string>("real_vector_value") = prop_name;
     367         532 :                         params.set<MooseEnum>("direction") = direction;
     368        1596 :                         params.set<MaterialPropertyName>("property_name") = addBaseName(out);
     369         532 :                         params.set<std::vector<BoundaryName>>("boundary") = _boundary;
     370         532 :                         params.set<std::string>("base_name") = _base_name;
     371        1596 :                         _problem->addInterfaceMaterial(
     372         532 :                             type, addBaseName(out) + '_' + name(), params);
     373         532 :                       }))
     374         532 :         continue;
     375             : 
     376           0 :       mooseError("CZM Master: unable to add output Material");
     377        1358 :     }
     378             :   }
     379         231 : }
     380             : 
     381             : void
     382        1621 : CohesiveZoneAction::chekMultipleActionParameters()
     383             : {
     384             : 
     385             :   // Gather info about all other master actions when we add variables
     386        1621 :   if (_current_task == "validate_coordinate_systems")
     387             :   {
     388         235 :     auto actions = _awh.getActions<CohesiveZoneAction>();
     389         528 :     for (const auto & action : actions)
     390             :     {
     391             :       const auto size_before = _boundary_name_union.size();
     392         295 :       const auto added_size = action->_boundary.size();
     393         295 :       _boundary_name_union.insert(action->_boundary.begin(), action->_boundary.end());
     394             :       const auto size_after = _boundary_name_union.size();
     395         295 :       if (size_after != size_before + added_size)
     396           2 :         mooseError("The boundary restrictions in the CohesiveZoneAction actions must be "
     397             :                    "non-overlapping.");
     398             :     }
     399             : 
     400         522 :     for (const auto & action : actions)
     401             :     {
     402             :       // check for different strain definitions
     403         291 :       _strain_formulation_union.insert(action->_strain);
     404             :       const auto size_after = _strain_formulation_union.size();
     405             : 
     406         291 :       if (size_after != 1)
     407           2 :         mooseError("All blocks of the CohesiveZoneAction should have the same strain formulation");
     408             :     }
     409         231 :   }
     410        1617 : }

Generated by: LCOV version 1.14