https://mooseframework.inl.gov
AbaqusUserElement.C
Go to the documentation of this file.
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 
20 {
21  auto params = GeneralUserObject::validParams();
24  params.addClassDescription("Coupling UserObject to use Abaqus UEL plugins in MOOSE");
25 
26  // execute during residual and Jacobian evaluation
27  ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
29  exec_enum = {EXEC_PRE_KERNELS};
30  params.suppressParameter<ExecFlagEnum>("execute_on");
31 
32  // Avoid uninitialized residual objects
33  params.suppressParameter<bool>("force_preic");
34 
35  // coupled variables
36  params.addParam<std::vector<NonlinearVariableName>>("variables", "Nonlinear coupled variables");
37  // auxiliary variables (including temperature)
38  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  params.addRequiredParam<FileName>("plugin", "UEL plugin file");
47 
48  params.addRequiredParam<std::vector<Real>>(
49  "constant_properties", "Constant mechanical and thermal material properties (PROPS)");
50  params.addRequiredParam<unsigned int>("num_state_vars",
51  "The number of state variables this UMAT is going to use");
52 
53  params.addParam<int>("jtype", 0, "Abaqus element type integer");
54 
55  return params;
56 }
57 
59  : GeneralUserObject(params),
60  BlockRestrictable(this),
61  TaggingInterface(this),
62  _plugin(getParam<FileName>("plugin")),
63  _library(_plugin + std::string("-") + QUOTE(METHOD) + ".plugin"),
64  _uel(_library.getFunction<uel_t>("uel_")),
65  _moose_mesh(UserObject::_subproblem.mesh()),
66  _mesh(_moose_mesh.getMesh()),
67  _dim(_moose_mesh.dimension()),
68  _variable_names(getParam<std::vector<NonlinearVariableName>>("variables")),
69  _aux_variable_names(getParam<std::vector<AuxVariableName>>("external_fields")),
70  _sub_ids(blockRestricted() ? blockIDs() : _moose_mesh.meshSubdomains()),
71  _props(getParam<std::vector<Real>>("constant_properties")),
72  _nprops(_props.size()),
73  _nstatev(getParam<unsigned int>("num_state_vars")),
74  _statev_index_current(0),
75  _statev_index_old(1),
76  _t_step_old(declareRestartableData<int>("uel_tstep_old", -1)),
77  _jtype(getParam<int>("jtype"))
78 {
79  // coupled variables must be nonlinear scalar fields
80  for (const auto & variable_name : _variable_names)
81  {
82  const auto * var = &UserObject::_subproblem.getVariable(
83  0, variable_name, Moose::VarKindType::VAR_SOLVER, Moose::VarFieldType::VAR_FIELD_STANDARD);
84  _variables.push_back(var);
85 
86  // check block restriction
87  if (!var->hasBlocks(blockIDs()))
88  paramError("variables", "must be defined on all blocks the UEL is operating on.");
89  }
90 
91  for (const auto & aux_variable_name : _aux_variable_names)
92  {
93  MooseVariableFEBase * aux_var =
95  aux_variable_name,
96  Moose::VarKindType::VAR_AUXILIARY,
97  Moose::VarFieldType::VAR_FIELD_STANDARD);
98  _aux_variables.push_back(aux_var);
99  aux_var->sys().addVariableToZeroOnResidual(aux_variable_name);
100 
101  // check block restriction
102  if (!aux_var->hasBlocks(blockIDs()))
103  paramError("aux_variables", "must be defined on all blocks the UEL is operating on.");
104  }
105 }
106 
107 void
109 {
110  setupElemRange();
111 }
112 
113 void
115 {
116  setupElemRange();
117 }
118 
119 void
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  if (_t_step == _t_step_old)
125  return;
126 
129 }
130 
131 void
133 {
134 }
135 
136 void
138 {
139  PARALLEL_TRY
140  {
141  UELThread ut(_fe_problem, *this);
142  Threads::parallel_reduce(*_elem_range, ut);
143  }
144  PARALLEL_CATCH;
145 }
146 
147 void
149 {
150  _elem_range =
151  std::make_unique<ConstElemRange>(_mesh.active_local_subdomain_set_elements_begin(_sub_ids),
152  _mesh.active_local_subdomain_set_elements_end(_sub_ids));
153 
154  // prepopulate the statev map outside of a threaded region
155  if (_nstatev > 0)
156  for (const auto & elem : *_elem_range)
157  {
158  _statev[0][elem->id()].resize(_nstatev);
159  _statev[1][elem->id()].resize(_nstatev);
160  }
161 }
std::array< std::map< dof_id_type, std::vector< Real > >, 2 > _statev
void paramError(const std::string &param, Args... args) const
T & getMesh(MooseMesh &mesh)
function to cast mesh
Definition: SCM.h:35
static InputParameters validParams()
std::vector< NonlinearVariableName > _variable_names
coupled variables to provide the DOF values
virtual void initialSetup() override
int _nstatev
stateful data
virtual void execute() override
const libMesh::MeshBase & _mesh
The libMesh mesh that this object acts on.
MeshBase & mesh
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
virtual const std::set< SubdomainID > & blockIDs() const
virtual void initialize() override final
virtual void timestepSetup() override
static InputParameters validParams()
SubProblem & _subproblem
virtual void meshChanged() override
std::size_t _statev_index_current
std::unique_ptr< ConstElemRange > _elem_range
All the active and elements local to this process that exist on this object&#39;s subdomains.
std::vector< AuxVariableName > _aux_variable_names
Auxiliary variable names.
const std::set< SubdomainID > _sub_ids
The subdomain ids this object operates on.
AbaqusUserElement(const InputParameters &params)
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const=0
This user-object is a testbed for implementing a custom element.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
registerMooseObject("SolidMechanicsApp", AbaqusUserElement)
virtual void addVariableToZeroOnResidual(std::string var_name)
FEProblemBase & _fe_problem
void setupElemRange()
setup the range of elements this object operates on
static InputParameters validParams()
const ExecFlagType EXEC_PRE_KERNELS
std::size_t _statev_index_old
bool hasBlocks(const SubdomainName &name) const
static InputParameters validParams()
SystemBase & sys()
void ErrorVector unsigned int
std::vector< const MooseVariableFieldBase * > _variables
pointers to the variable objects
std::vector< const MooseVariableFieldBase * > _aux_variables
pointers to the auxiliary variable objects