LCOV - code coverage report
Current view: top level - src/actions - CohesiveZoneAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 174 212 82.1 %
Date: 2025-07-25 05:00:39 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         206 : CohesiveZoneAction::validParams()
      26             : {
      27         206 :   InputParameters params = CohesiveZoneActionBase::validParams();
      28         206 :   params.addClassDescription("Action to create an instance of the cohesive zone model kernel for "
      29             :                              "each displacement component");
      30         412 :   params.addRequiredParam<std::vector<BoundaryName>>(
      31             :       "boundary", "The list of boundary IDs from the mesh where the cohesive zone will be applied");
      32         206 :   return params;
      33           0 : }
      34             : 
      35         206 : CohesiveZoneAction::CohesiveZoneAction(const InputParameters & params)
      36             :   : CohesiveZoneActionBase(params),
      37         412 :     _displacements(getParam<std::vector<VariableName>>("displacements")),
      38         206 :     _ndisp(_displacements.size()),
      39         412 :     _use_AD(getParam<bool>("use_automatic_differentiation")),
      40         636 :     _base_name(isParamValid("base_name") && !getParam<std::string>("base_name").empty()
      41         206 :                    ? getParam<std::string>("base_name")
      42             :                    : ""),
      43         412 :     _boundary(getParam<std::vector<BoundaryName>>("boundary")),
      44         412 :     _strain(getParam<MooseEnum>("strain").getEnum<Strain>()),
      45         412 :     _save_in_master(getParam<std::vector<AuxVariableName>>("save_in_master")),
      46         412 :     _diag_save_in_master(getParam<std::vector<AuxVariableName>>("diag_save_in_master")),
      47         412 :     _save_in_slave(getParam<std::vector<AuxVariableName>>("save_in_slave")),
      48         412 :     _diag_save_in_slave(getParam<std::vector<AuxVariableName>>("diag_save_in_slave")),
      49         412 :     _material_output_order(getParam<MultiMooseEnum>("material_output_order")),
      50         618 :     _material_output_family(getParam<MultiMooseEnum>("material_output_family")),
      51         824 :     _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         206 :   if (_ndisp > 3 || _ndisp < 1)
      56           0 :     mooseError("the CZM Action requires 1, 2 or 3 displacement variables.");
      57             : 
      58         206 :   switch (_strain)
      59             :   {
      60         138 :     case Strain::Small:
      61             :     {
      62             :       _czm_kernel_name =
      63         138 :           _use_AD ? "ADCZMInterfaceKernelSmallStrain" : "CZMInterfaceKernelSmallStrain";
      64         138 :       _disp_jump_provider_name = _use_AD ? "ADCZMComputeDisplacementJumpSmallStrain"
      65         138 :                                          : "CZMComputeDisplacementJumpSmallStrain";
      66             :       _equilibrium_traction_calculator_name =
      67         138 :           _use_AD ? "ADCZMComputeGlobalTractionSmallStrain" : "CZMComputeGlobalTractionSmallStrain";
      68             :       break;
      69             :     }
      70          68 :     case Strain::Finite:
      71             :     {
      72             :       _czm_kernel_name =
      73          68 :           _use_AD ? "ADCZMInterfaceKernelTotalLagrangian" : "CZMInterfaceKernelTotalLagrangian";
      74          68 :       _disp_jump_provider_name = _use_AD ? "ADCZMComputeDisplacementJumpTotalLagrangian"
      75          68 :                                          : "CZMComputeDisplacementJumpTotalLagrangian";
      76          68 :       _equilibrium_traction_calculator_name = _use_AD ? "ADCZMComputeGlobalTractionTotalLagrangian"
      77          68 :                                                       : "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         206 :   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         206 :   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         206 :   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         206 :   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        1576 :   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        1164 :     _generate_output.push_back(lower);
     109             :   }
     110             : 
     111         206 :   if (!_generate_output.empty())
     112         120 :     verifyOrderAndFamilyOutputs();
     113         206 : }
     114             : 
     115             : void
     116         198 : CohesiveZoneAction::addRequiredCZMInterfaceKernels()
     117             : {
     118         726 :   for (unsigned int i = 0; i < _ndisp; ++i)
     119             :   {
     120             :     // Create unique kernel name for each displacement component
     121        1584 :     std::string unique_kernel_name = _czm_kernel_name + "_" + _name + "_" + Moose::stringify(i);
     122             : 
     123         528 :     InputParameters paramsk = _factory.getValidParams(_czm_kernel_name);
     124             : 
     125         528 :     paramsk.set<unsigned int>("component") = i;
     126        1056 :     paramsk.set<NonlinearVariableName>("variable") = _displacements[i];
     127        1584 :     paramsk.set<std::vector<VariableName>>("neighbor_var") = {_displacements[i]};
     128         528 :     paramsk.set<std::vector<VariableName>>("displacements") = _displacements;
     129         528 :     paramsk.set<std::vector<BoundaryName>>("boundary") = _boundary;
     130        1056 :     paramsk.set<std::string>("base_name") = _base_name;
     131             : 
     132             :     std::string save_in_side;
     133             :     std::vector<AuxVariableName> save_in_var_names;
     134         528 :     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         528 :     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         528 :     _problem->addInterfaceKernel(_czm_kernel_name, unique_kernel_name, paramsk);
     148        1056 :   }
     149         198 : }
     150             : 
     151             : void
     152         198 : CohesiveZoneAction::addRequiredCZMInterfaceMaterials()
     153             : {
     154             :   // Create unique material name for the "CZMComputeDisplacementJump" object
     155         198 :   std::string unique_material_name = _disp_jump_provider_name + "_" + _name;
     156         198 :   InputParameters paramsm = _factory.getValidParams(_disp_jump_provider_name);
     157         198 :   paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
     158             :   ;
     159         198 :   paramsm.set<std::vector<VariableName>>("displacements") = _displacements;
     160         198 :   paramsm.set<std::string>("base_name") = _base_name;
     161         198 :   _problem->addInterfaceMaterial(_disp_jump_provider_name, unique_material_name, paramsm);
     162             : 
     163             :   // Create unique material name for the "CZMComputeGlobalTraction" object
     164         198 :   unique_material_name = _equilibrium_traction_calculator_name + "_" + _name;
     165         198 :   paramsm = _factory.getValidParams(_equilibrium_traction_calculator_name);
     166         198 :   paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
     167             :   ;
     168         198 :   paramsm.set<std::string>("base_name") = _base_name;
     169         198 :   _problem->addInterfaceMaterial(
     170             :       _equilibrium_traction_calculator_name, unique_material_name, paramsm);
     171         396 : }
     172             : 
     173             : void
     174        1390 : CohesiveZoneAction::act()
     175             : {
     176             :   // Enforce consistency
     177        1390 :   if (_ndisp != _mesh->dimension())
     178           0 :     paramError("displacements", "Number of displacements must match problem dimension.");
     179             : 
     180        1390 :   chekMultipleActionParameters();
     181             : 
     182        1386 :   if (_current_task == "add_interface_kernel")
     183         198 :     addRequiredCZMInterfaceKernels();
     184        1188 :   else if (_current_task == "add_master_action_material")
     185         198 :     addRequiredCZMInterfaceMaterials();
     186             : 
     187             :   // optional, add required outputs
     188        1386 :   actOutputGeneration();
     189        1386 : }
     190             : 
     191             : void
     192         602 : CohesiveZoneAction::addRelationshipManagers(Moose::RelationshipManagerType input_rm_type)
     193             : {
     194         602 :   InputParameters ips = _factory.getValidParams(_czm_kernel_name);
     195         602 :   addRelationshipManagers(input_rm_type, ips);
     196         602 : }
     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             :   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         120 : 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         120 :   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         120 :   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         120 :   if (_material_output_order.size() == 0)
     242         216 :     _material_output_order.setAdditionalValue("CONSTANT");
     243             : 
     244             :   // For only one order, make all orders the same magnitude
     245         120 :   if (_material_output_order.size() == 1)
     246             :     _material_output_order =
     247         120 :         std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
     248             : 
     249         120 :   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         120 :   if (_material_output_family.size() == 0)
     257         240 :     _material_output_family.setAdditionalValue("MONOMIAL");
     258             : 
     259             :   // For only one family, make all families that value
     260         120 :   if (_material_output_family.size() == 1)
     261             :     _material_output_family =
     262         120 :         std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
     263             : 
     264         120 :   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         120 : }
     270             : 
     271             : void
     272        1386 : CohesiveZoneAction::actOutputGeneration()
     273             : {
     274        1386 :   if (_current_task == "add_material")
     275         198 :     actOutputMatProp();
     276             : 
     277             :   // Add variables (optional)
     278        1386 :   if (_current_task == "add_aux_variable")
     279             :   {
     280             :     unsigned int index = 0;
     281        1362 :     for (auto out : _generate_output)
     282             :     {
     283        1164 :       const auto & order = _material_output_order[index];
     284        1164 :       const auto & family = _material_output_family[index];
     285             : 
     286        1044 :       std::string type = (order == "CONSTANT" && family == "MONOMIAL")
     287             :                              ? "MooseVariableConstMonomial"
     288        2328 :                              : "MooseVariable";
     289             : 
     290             :       // Create output helper aux variables
     291        1164 :       auto params = _factory.getValidParams(type);
     292        1164 :       params.set<MooseEnum>("order") = order;
     293        2328 :       params.set<MooseEnum>("family") = family;
     294        1164 :       if (family == "MONOMIAL")
     295        2328 :         _problem->addAuxVariable(type, addBaseName(out), params);
     296             :       else
     297           0 :         _problem->addVariable(type, addBaseName(out), params);
     298             : 
     299        1164 :       index++;
     300        1164 :     }
     301             :   }
     302             : 
     303             :   // Add output AuxKernels
     304        1188 :   else if (_current_task == "add_aux_kernel")
     305             :   {
     306         384 :     const std::string material_output_aux_name = _use_AD ? "ADMaterialRealAux" : "MaterialRealAux";
     307             :     // Loop through output aux variables
     308             :     unsigned int index = 0;
     309        1362 :     for (auto out : _generate_output)
     310             :     {
     311        2328 :       if (_material_output_family[index] == "MONOMIAL")
     312             :       {
     313        1164 :         InputParameters params = _factory.getValidParams(material_output_aux_name);
     314        3492 :         params.set<MaterialPropertyName>("property") = addBaseName(out);
     315        3492 :         params.set<AuxVariableName>("variable") = addBaseName(out);
     316        1164 :         params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
     317        1164 :         params.set<std::vector<BoundaryName>>("boundary") = _boundary;
     318        1164 :         params.set<bool>("check_boundary_restricted") = false;
     319        1164 :         _problem->addAuxKernel(material_output_aux_name, addBaseName(out) + '_' + name(), params);
     320        1164 :       }
     321        1164 :       index++;
     322             :     }
     323             :   }
     324        1386 : }
     325             : 
     326             : void
     327         198 : CohesiveZoneAction::actOutputMatProp()
     328             : {
     329         198 :   if (_current_task == "add_material")
     330             :   {
     331             :     // Add output Materials
     332        1362 :     for (auto out : _generate_output)
     333             :     {
     334        1164 :       InputParameters params = emptyInputParameters();
     335             : 
     336             :       // RealVectorCartesianComponent
     337        1872 :       if (
     338        2328 :           [&]()
     339             :           {
     340        3240 :             for (const auto & vq : _real_vector_cartesian_component_table)
     341        9696 :               for (unsigned int a = 0; a < 3; ++a)
     342       15240 :                 if (vq.first + '_' + _component_table[a] == out)
     343             :                 {
     344         708 :                   auto type = _use_AD ? "ADCZMRealVectorCartesianComponent"
     345             :                                       : "CZMRealVectorCartesianComponent";
     346        1416 :                   params = _factory.getValidParams(type);
     347         708 :                   params.set<std::string>("real_vector_value") = vq.second;
     348         708 :                   params.set<unsigned int>("index") = a;
     349         708 :                   params.set<std::vector<BoundaryName>>("boundary") = _boundary;
     350        2124 :                   params.set<MaterialPropertyName>("property_name") = addBaseName(out);
     351         708 :                   params.set<std::string>("base_name") = _base_name;
     352        2124 :                   _problem->addInterfaceMaterial(type, addBaseName(out) + '_' + name(), params);
     353             :                   return true;
     354             :                 }
     355             :             return false;
     356        1164 :           }())
     357         708 :         continue;
     358             : 
     359             :       // CZMRealVectorScalar
     360         912 :       if (setupOutput(out,
     361             :                       _vector_direction_table,
     362         456 :                       [&](std::string prop_name, std::string direction)
     363             :                       {
     364         456 :                         auto type = _use_AD ? "ADCZMRealVectorScalar" : "CZMRealVectorScalar";
     365         456 :                         params = _factory.getValidParams(type);
     366         456 :                         params.set<std::string>("real_vector_value") = prop_name;
     367         456 :                         params.set<MooseEnum>("direction") = direction;
     368        1368 :                         params.set<MaterialPropertyName>("property_name") = addBaseName(out);
     369         456 :                         params.set<std::vector<BoundaryName>>("boundary") = _boundary;
     370         456 :                         params.set<std::string>("base_name") = _base_name;
     371        1368 :                         _problem->addInterfaceMaterial(
     372         456 :                             type, addBaseName(out) + '_' + name(), params);
     373         456 :                       }))
     374         456 :         continue;
     375             : 
     376           0 :       mooseError("CZM Master: unable to add output Material");
     377        1164 :     }
     378             :   }
     379         198 : }
     380             : 
     381             : void
     382        1390 : CohesiveZoneAction::chekMultipleActionParameters()
     383             : {
     384             : 
     385             :   // Gather info about all other master actions when we add variables
     386        1390 :   if (_current_task == "validate_coordinate_systems")
     387             :   {
     388         202 :     auto actions = _awh.getActions<CohesiveZoneAction>();
     389         454 :     for (const auto & action : actions)
     390             :     {
     391             :       const auto size_before = _boundary_name_union.size();
     392         254 :       const auto added_size = action->_boundary.size();
     393         254 :       _boundary_name_union.insert(action->_boundary.begin(), action->_boundary.end());
     394             :       const auto size_after = _boundary_name_union.size();
     395         254 :       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         448 :     for (const auto & action : actions)
     401             :     {
     402             :       // check for different strain definitions
     403         250 :       _strain_formulation_union.insert(action->_strain);
     404             :       const auto size_after = _strain_formulation_union.size();
     405             : 
     406         250 :       if (size_after != 1)
     407           2 :         mooseError("All blocks of the CohesiveZoneAction should have the same strain formulation");
     408             :     }
     409             :   }
     410        1386 : }

Generated by: LCOV version 1.14