https://mooseframework.inl.gov
Loading...
Searching...
No Matches
UELThread.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 "UELThread.h"
11#include "NonlinearSystemBase.h"
12
14 : ThreadedElementLoop<ConstElemRange>(fe_problem),
15 _sys(fe_problem.currentNonlinearSystem()),
16 _aux_sys(&_fe_problem.getAuxiliarySystem()),
17 _variables(uel_uo.getVariables()),
18 _aux_variables(uel_uo.getAuxVariables()),
19 _uel_uo(uel_uo),
20 _uel(uel_uo.getPlugin()),
21 _statev_copy(uel_uo._nstatev)
22{
23 // general solve step
24 _lflags[3] = 0;
25
26 // newton based solution (should be 1 when using a predictor or maybe at the start of the
27 // iteration)
28 _lflags[4] = 0;
29}
30
31// Splitting Constructor
32UELThread::UELThread(UELThread & x, Threads::split split)
33 : ThreadedElementLoop<ConstElemRange>(x, split),
34 _sys(x._sys),
35 _aux_sys(x._aux_sys),
36 _variables(x._variables),
37 _aux_variables(x._aux_variables),
38 _uel_uo(x._uel_uo),
39 _uel(x._uel),
40 _lflags(x._lflags),
41 _statev_copy(_uel_uo._nstatev)
42{
43}
44
45void
49
55void
56UELThread::onElement(const Elem * elem)
57{
58 // get all dof indices for the coupled variables on this element
59 int nnode = elem->n_nodes();
60 const auto nvar = _variables.size();
61 _all_dof_indices.resize(nnode * nvar);
62
63 // ** System variables **
64 // prepare DOF indices in the correct order
65 for (const auto i : index_range(_variables))
66 {
67 _variables[i]->getDofIndices(elem, _var_dof_indices);
68
69 // sanity checks
70 if (_variables[i]->scalingFactor() != 1)
71 mooseError("Scaling factors other than unity are not yet supported");
72 if (static_cast<int>(_var_dof_indices.size()) != nnode)
73 mooseError("All coupled variables must be full order lagrangian");
74
75 for (const auto j : make_range(nnode))
76 _all_dof_indices[j * nvar + i] = _var_dof_indices[j];
77 }
78
79 int ndofel = _all_dof_indices.size();
80
81 // Get solution values
82 _all_dof_values.resize(ndofel);
83
85 _all_dof_increments.resize(ndofel);
87
88 mooseAssert(_all_dof_values.size() == _all_dof_increments.size(), "Inconsistent solution size.");
89 for (const auto i : index_range(_all_dof_values))
91
92 _all_udot_dof_values.resize(ndofel);
93 _all_udotdot_dof_values.resize(ndofel);
94
95 // Get u_dot and u_dotdot solution values (required for future expansion of the interface)
96 if (false)
97 {
98 _all_udot_dof_values.resize(ndofel);
100 _all_udotdot_dof_values.resize(ndofel);
102 }
103
104 // Prepare external fields
105 const auto nvar_aux = _aux_variables.size();
106 _all_aux_var_dof_indices.resize(nnode * nvar_aux);
107 _all_aux_var_dof_increments.resize(nnode * nvar_aux);
108
109 for (const auto i : index_range(_aux_variables))
110 {
111 _aux_variables[i]->getDofIndices(elem, _aux_var_dof_indices);
112
113 if (static_cast<int>(_aux_var_dof_indices.size()) != nnode)
114 mooseError("All auxiliary variables must be full order Lagrangian");
115
116 for (const auto j : make_range(nnode))
117 _all_aux_var_dof_indices[j * nvar_aux + i] = _aux_var_dof_indices[j];
118 }
119
120 _all_aux_var_dof_values.resize(nnode * nvar_aux);
121 _aux_var_values_to_uel.resize(nnode * nvar_aux * 2); // Value _and_ increment
122
124 _all_aux_var_dof_increments.resize(nnode * nvar_aux);
126
127 // First, one external field and increment; then, second external field and increment, etc.
128 for (const auto i : index_range(_all_aux_var_dof_values))
130
131 for (const auto i : index_range(_all_aux_var_dof_values))
132 {
135 }
136 // End of prepare external fields.
137
138 const bool do_residual = _sys.hasVector(_sys.residualVectorTag());
139 const bool do_jacobian = _sys.hasMatrix(_sys.systemMatrixTag());
140
141 // set flags
142 if (do_residual && do_jacobian)
143 _lflags[2] = 0;
144 else if (!do_residual && do_jacobian)
145 _lflags[2] = 4;
146 else if (do_residual && !do_jacobian)
147 _lflags[2] = 5;
148 else
149 _lflags[2] = 0;
150
151 // copy coords
152 int dim = _uel_uo._dim;
153 _coords.resize(nnode * dim);
154 for (const auto i : make_range(nnode))
155 for (const auto j : make_range(dim))
156 _coords[j + dim * i] = elem->node_ref(i)(j);
157
158 // prepare residual and jacobian storage
159 _local_re.resize(ndofel);
160 _local_ke.resize(ndofel, ndofel);
161
162 int nrhs = 1; // : RHS should contain the residual vector
163 int jtype = _uel_uo._jtype; // type of user element
164
165 Real dt = _fe_problem.dt();
166 Real time = _fe_problem.time();
167 std::vector<Real> times{time - dt, time - dt}; // first entry should be the step time (TODO)
168
169 std::array<Real, 8> energy;
170 int jelem = elem->id() + 1; // User-assigned element number
171 Real pnewdt;
172
173 int npredf = nvar_aux; // Number of external fields.
174
175 // dummy vars
176 Real rdummy = 0;
177 int idummy = 0;
178
179 // stateful data
180 if (_uel_uo._nstatev)
181 {
182 const auto & statev_old = _uel_uo._statev[_uel_uo._statev_index_old][elem->id()];
183 std::copy(statev_old.begin(), statev_old.end(), _statev_copy.begin());
184 }
185
186 // call the plugin
187 _uel(_local_re.get_values().data(),
188 _local_ke.get_values().data(),
189 _statev_copy.data(),
190 energy.data(),
191 &ndofel,
192 &nrhs,
194 _uel_uo._props.data(),
196 _coords.data(),
197 &dim,
198 &nnode,
199 _all_dof_values.data() /* U[] */,
200 _all_dof_increments.data() /* DU[] */,
201 _all_udot_dof_values.data() /* V[] */,
202 _all_udotdot_dof_values.data() /* A[] */,
203 &jtype,
204 times.data(),
205 &dt,
206 &idummy /* KSTEP */,
207 &idummy /* KINC */,
208 &jelem,
209 nullptr /* PARAMS[] */,
210 &idummy /* NDLOAD */,
211 nullptr /* JDLTYP[] */,
212 nullptr /* ADLMAG[] */,
213 _aux_var_values_to_uel.data() /* PREDEF[] */,
214 &npredf /* NPREDF */,
215 nullptr /* LFLAGS[] */,
216 &ndofel /* MLVARX */,
217 nullptr /* DDLMAG[] */,
218 &idummy /* MDLOAD */,
219 &pnewdt,
220 nullptr /* JPROPS[] */,
221 &idummy /* NJPROP */,
222 &rdummy /* PERIOD */
223 );
224
225 if (_uel_uo._nstatev)
226 {
227 auto & statev_current = _uel_uo._statev[_uel_uo._statev_index_current][elem->id()];
228 std::copy(_statev_copy.begin(), _statev_copy.end(), statev_current.begin());
229 }
230
231 // write to the residual vector
232 // sign of 'residuals' has been tested with external loading and matches that of moose-umat
233 // setups.
234 if (do_residual)
237
238 // write to the Jacobian (hope we don't have to transpose...)
239 if (do_jacobian)
241 _local_ke,
244 -1.0);
245}
const std::vector< double > x
void mooseError(Args &&... args)
unsigned int dim
This user-object is a testbed for implementing a custom element.
std::size_t _statev_index_old
std::vector< Real > _props
props
const int _jtype
Abaqus element type.
std::size_t _statev_index_current
std::array< std::map< dof_id_type, std::vector< Real > >, 2 > _statev
int _nstatev
stateful data
const unsigned int _dim
The dimension of the mesh, e.g. 3 for hexes and tets, 2 for quads and tris.
const NumericVector< Number > *const & currentSolution() const override
virtual Real & dt() const
virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num) override
virtual Real & time() const
TagID systemMatrixTag() const override
TagID residualVectorTag() const override
virtual const NumericVector< Number > *const & currentSolution() const override final
bool hasVector(const std::string &tag_name) const
virtual NumericVector< Number > * solutionUDot()
unsigned int number() const
NumericVector< Number > & solutionOld()
virtual bool hasMatrix(TagID tag) const
void addJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
void addResiduals(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
UELThread(FEProblemBase &fe_problem, AbaqusUserElement &uel_uo)
Definition UELThread.C:13
std::vector< Real > _coords
Definition UELThread.h:68
const std::vector< const MooseVariableFieldBase * > & _variables
Definition UELThread.h:56
std::vector< Real > _statev_copy
state variable copy
Definition UELThread.h:71
NonlinearSystemBase & _sys
Current nonlinear system.
Definition UELThread.h:33
AuxiliarySystem * _aux_sys
Auxiliary system object.
Definition UELThread.h:36
std::vector< Real > _all_udotdot_dof_values
Definition UELThread.h:44
std::vector< Real > _all_aux_var_dof_increments
Definition UELThread.h:49
AbaqusUserElement & _uel_uo
reference to the userobject (to access parameters)
Definition UELThread.h:61
std::vector< dof_id_type > _var_dof_indices
dof indices of all coupled variables
Definition UELThread.h:39
std::vector< dof_id_type > _all_dof_indices
Definition UELThread.h:40
std::vector< Real > _aux_var_values_to_uel
Definition UELThread.h:51
std::vector< Real > _all_udot_dof_values
Definition UELThread.h:43
std::vector< dof_id_type > _all_aux_var_dof_indices
Definition UELThread.h:48
DenseVector< Real > _local_re
Definition UELThread.h:53
DenseMatrix< Real > _local_ke
Definition UELThread.h:54
const std::vector< const MooseVariableFieldBase * > & _aux_variables
Definition UELThread.h:58
const AbaqusUserElement::uel_t & _uel
have a reference to the UEL plugin here
Definition UELThread.h:64
virtual void subdomainChanged() override final
Definition UELThread.C:46
std::array< int, 5 > _lflags
parameters for the UEL plugin
Definition UELThread.h:67
std::vector< Real > _all_dof_increments
Definition UELThread.h:42
std::vector< dof_id_type > _aux_var_dof_indices
Definition UELThread.h:47
virtual void onElement(const Elem *elem) override final
Fortran array memory layout: (1,1), (2,1) (3,1) (1,2) (2,2) (3,2) (1,3) (2,3) (3,3) C++ array memory ...
Definition UELThread.C:56
std::vector< Real > _all_aux_var_dof_values
Definition UELThread.h:50
std::vector< Real > _all_dof_values
Definition UELThread.h:41
std::vector< T > & get_values()
void resize(const unsigned int new_m, const unsigned int new_n)
virtual void get(const std::vector< numeric_index_type > &index, T *values) const