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

Generated by: LCOV version 1.14