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

Generated by: LCOV version 1.14