LCOV - code coverage report
Current view: top level - src/userobjects - AbaqusUserElement.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 66 71 93.0 %
Date: 2024-02-27 11:53:14 Functions: 6 7 85.7 %
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 "AbaqusUserElement.h"
      11             : #include "SystemBase.h"
      12             : #include "UELThread.h"
      13             : 
      14             : #define QUOTE(macro) stringifyName(macro)
      15             : 
      16             : registerMooseObject("TensorMechanicsApp", AbaqusUserElement);
      17             : 
      18             : InputParameters
      19          34 : AbaqusUserElement::validParams()
      20             : {
      21          34 :   auto params = GeneralUserObject::validParams();
      22          34 :   params += BlockRestrictable::validParams();
      23          34 :   params += TaggingInterface::validParams();
      24          34 :   params.addClassDescription("Coupling UserObject to use Abaqus UEL plugins in MOOSE");
      25             : 
      26             :   // execute during residual and Jacobian evaluation
      27          34 :   ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
      28          34 :   exec_enum.addAvailableFlags(EXEC_PRE_KERNELS);
      29         136 :   exec_enum = {EXEC_PRE_KERNELS, EXEC_TIMESTEP_END};
      30          34 :   params.suppressParameter<ExecFlagEnum>("execute_on");
      31             : 
      32             :   // Avoid uninitialized residual objects
      33          34 :   params.suppressParameter<bool>("force_preic");
      34             : 
      35             :   // coupled variables
      36          68 :   params.addParam<std::vector<NonlinearVariableName>>("variables", "Nonlinear coupled variables");
      37             :   // auxiliary variables (including temperature)
      38          68 :   params.addParam<std::vector<AuxVariableName>>(
      39             :       "external_fields",
      40             :       {},
      41             :       "Auxiliary field variables (or 'predifined field variables') passed to the UEL plugin. Some "
      42             :       "plugins may assume that the first field is temperature when there are multiple external "
      43             :       "fields.");
      44             : 
      45             :   // UEL plugin file
      46          68 :   params.addRequiredParam<FileName>("plugin", "UEL plugin file");
      47             : 
      48          68 :   params.addRequiredParam<std::vector<Real>>(
      49             :       "constant_properties", "Constant mechanical and thermal material properties (PROPS)");
      50          68 :   params.addRequiredParam<unsigned int>("num_state_vars",
      51             :                                         "The number of state variables this UMAT is going to use");
      52             : 
      53          68 :   params.addParam<int>("jtype", 0, "Abaqus element type integer");
      54             : 
      55          34 :   return params;
      56          34 : }
      57             : 
      58          17 : AbaqusUserElement::AbaqusUserElement(const InputParameters & params)
      59             :   : GeneralUserObject(params),
      60             :     BlockRestrictable(this),
      61             :     TaggingInterface(this),
      62          34 :     _plugin(getParam<FileName>("plugin")),
      63          34 :     _library(_plugin + std::string("-") + QUOTE(METHOD) + ".plugin"),
      64          17 :     _uel(_library.getFunction<uel_t>("uel_")),
      65          17 :     _moose_mesh(UserObject::_subproblem.mesh()),
      66          17 :     _mesh(_moose_mesh.getMesh()),
      67          17 :     _dim(_moose_mesh.dimension()),
      68          34 :     _variable_names(getParam<std::vector<NonlinearVariableName>>("variables")),
      69          34 :     _aux_variable_names(getParam<std::vector<AuxVariableName>>("external_fields")),
      70          17 :     _sub_ids(blockRestricted() ? blockIDs() : _moose_mesh.meshSubdomains()),
      71          51 :     _props(getParam<std::vector<Real>>("constant_properties")),
      72          17 :     _nprops(_props.size()),
      73          34 :     _nstatev(getParam<unsigned int>("num_state_vars")),
      74          17 :     _statev_index_current(0),
      75          17 :     _statev_index_old(1),
      76          85 :     _jtype(getParam<int>("jtype"))
      77             : {
      78             :   // coupled variables must be nonlinear scalar fields
      79          53 :   for (const auto & variable_name : _variable_names)
      80             :   {
      81             :     const auto * var =
      82          36 :         &UserObject::_subproblem.getVariable(0,
      83             :                                              variable_name,
      84             :                                              Moose::VarKindType::VAR_NONLINEAR,
      85          36 :                                              Moose::VarFieldType::VAR_FIELD_STANDARD);
      86          36 :     _variables.push_back(var);
      87             : 
      88             :     // check block restriction
      89          36 :     if (!var->hasBlocks(blockIDs()))
      90           0 :       paramError("variables", "must be defined on all blocks the UEL is operating on.");
      91             :   }
      92             : 
      93          33 :   for (const auto & aux_variable_name : _aux_variable_names)
      94             :   {
      95             :     MooseVariableFEBase * aux_var =
      96          16 :         &UserObject::_subproblem.getVariable(0,
      97             :                                              aux_variable_name,
      98             :                                              Moose::VarKindType::VAR_AUXILIARY,
      99          16 :                                              Moose::VarFieldType::VAR_FIELD_STANDARD);
     100          16 :     _aux_variables.push_back(aux_var);
     101          16 :     aux_var->sys().addVariableToZeroOnResidual(aux_variable_name);
     102             : 
     103             :     // check block restriction
     104          16 :     if (!aux_var->hasBlocks(blockIDs()))
     105           0 :       paramError("aux_variables", "must be defined on all blocks the UEL is operating on.");
     106             :   }
     107          17 : }
     108             : 
     109             : void
     110          17 : AbaqusUserElement::initialSetup()
     111             : {
     112          17 :   setupElemRange();
     113          17 : }
     114             : 
     115             : void
     116           0 : AbaqusUserElement::meshChanged()
     117             : {
     118           0 :   setupElemRange();
     119           0 : }
     120             : 
     121             : void
     122        1133 : AbaqusUserElement::initialize()
     123             : {
     124        1133 : }
     125             : 
     126             : void
     127        1133 : AbaqusUserElement::execute()
     128             : {
     129             :   // swap the current and old state data at the end of a converged timestep
     130        1133 :   if (_fe_problem.getCurrentExecuteOnFlag() == EXEC_TIMESTEP_END)
     131             :   {
     132             :     std::swap(_statev_index_old, _statev_index_current);
     133         225 :     return;
     134             :   }
     135             : 
     136             :   PARALLEL_TRY
     137             :   {
     138         908 :     UELThread ut(_fe_problem, *this);
     139         908 :     Threads::parallel_reduce(*_elem_range, ut);
     140         908 :   }
     141         908 :   PARALLEL_CATCH;
     142             : }
     143             : 
     144             : void
     145          17 : AbaqusUserElement::setupElemRange()
     146             : {
     147             :   _elem_range =
     148          51 :       std::make_unique<ConstElemRange>(_mesh.active_local_subdomain_set_elements_begin(_sub_ids),
     149          17 :                                        _mesh.active_local_subdomain_set_elements_end(_sub_ids));
     150             : 
     151             :   // prepopulate the statev map outside of a threaded region
     152          17 :   if (_nstatev > 0)
     153        4071 :     for (const auto & elem : *_elem_range)
     154             :     {
     155        4054 :       _statev[0][elem->id()].resize(_nstatev);
     156        4054 :       _statev[1][elem->id()].resize(_nstatev);
     157             :     }
     158          17 : }

Generated by: LCOV version 1.14