https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeStrainBaseNOSPD.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
12
13#include "libmesh/quadrature.h"
14
17{
20 "Base material strain class for the peridynamic correspondence models");
21
22 MooseEnum stabilization_option("FORCE BOND_HORIZON_I BOND_HORIZON_II");
24 "stabilization",
25 stabilization_option,
26 "Stabilization techniques used for the peridynamic correspondence model");
27 params.addParam<bool>("plane_strain",
28 false,
29 "Plane strain problem or not, this will affect the mechanical stretch "
30 "calculation for problem with eigenstrains");
31 params.addParam<std::vector<MaterialPropertyName>>(
32 "eigenstrain_names", {}, "List of eigenstrains to be applied in this strain calculation");
33
34 return params;
35}
36
39 _stabilization(getParam<MooseEnum>("stabilization")),
40 _plane_strain(getParam<bool>("plane_strain")),
41 _Cijkl(getMaterialProperty<RankFourTensor>("elasticity_tensor")),
42 _eigenstrain_names(getParam<std::vector<MaterialPropertyName>>("eigenstrain_names")),
43 _eigenstrains(_eigenstrain_names.size()),
44 _shape2(declareProperty<RankTwoTensor>("rank_two_shape_tensor")),
45 _deformation_gradient(declareProperty<RankTwoTensor>("deformation_gradient")),
46 _ddgraddu(declareProperty<RankTwoTensor>("ddeformation_gradient_du")),
47 _ddgraddv(declareProperty<RankTwoTensor>("ddeformation_gradient_dv")),
48 _ddgraddw(declareProperty<RankTwoTensor>("ddeformation_gradient_dw")),
49 _total_strain(declareProperty<RankTwoTensor>("total_strain")),
50 _mechanical_strain(declareProperty<RankTwoTensor>("mechanical_strain")),
51 _multi(declareProperty<Real>("multi")),
52 _sf_coeff(declareProperty<Real>("stabilization_force_coeff"))
53{
54 for (unsigned int i = 0; i < _eigenstrains.size(); ++i)
55 {
57 _eigenstrains[i] = &getMaterialProperty<RankTwoTensor>(_eigenstrain_names[i]);
58 }
59}
60
61void
63{
64 _mechanical_strain[_qp].zero();
65 _total_strain[_qp].zero();
66 _deformation_gradient[_qp].setToIdentity();
67
68 if (_qrule->n_points() < 2) // Gauss_Lobatto: order = 2n-3 (n is number of qp)
70 "NOSPD models require Gauss_Lobatto rule and a minimum of 2 quadrature points, i.e., "
71 "order of FIRST");
72}
73
74void
76{
77 _shape2[_qp].zero();
78 _deformation_gradient[_qp].zero();
79 _ddgraddu[_qp].zero();
80 _ddgraddv[_qp].zero();
81 _ddgraddw[_qp].zero();
82 _multi[_qp] = 0.0;
83 _sf_coeff[_qp] = 0.0;
84
85 if (_dim == 2)
86 _shape2[_qp](2, 2) = _deformation_gradient[_qp](2, 2) = 1.0;
87
88 if (_bond_status_var->getElementalValue(_current_elem) > 0.5)
89 {
90 if (_stabilization == "FORCE")
91 {
93
95 _pdmesh.getNodeAverageSpacing(_current_elem->node_id(_qp)) *
96 _horizon_radius[_qp] / _origin_vec.norm();
97 _multi[_qp] = _horizon_radius[_qp] / _origin_vec.norm() * _node_vol[0] * _node_vol[1];
98 }
99 else if (_stabilization == "BOND_HORIZON_I" || _stabilization == "BOND_HORIZON_II")
101 else
102 paramError("stabilization",
103 "Unknown stabilization scheme for peridynamic correspondence model!");
104 }
105 else
106 {
107 _shape2[_qp].setToIdentity();
108 _deformation_gradient[_qp].setToIdentity();
109 }
110}
111
112void
114{
115 std::vector<dof_id_type> neighbors = _pdmesh.getNeighbors(_current_elem->node_id(_qp));
116 std::vector<dof_id_type> bonds = _pdmesh.getBonds(_current_elem->node_id(_qp));
117
118 // calculate the shape tensor and prepare the deformation gradient tensor
119 Real vol_nb, weight_nb;
120 RealGradient origin_vec_nb, current_vec_nb;
121
122 for (unsigned int nb = 0; nb < neighbors.size(); ++nb)
123 if (_bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[nb])) > 0.5)
124 {
125 vol_nb = _pdmesh.getNodeVolume(neighbors[nb]);
126 origin_vec_nb =
127 _pdmesh.getNodeCoord(neighbors[nb]) - _pdmesh.getNodeCoord(_current_elem->node_id(_qp));
128
129 for (unsigned int k = 0; k < _dim; ++k)
130 current_vec_nb(k) = origin_vec_nb(k) +
131 _disp_var[k]->getNodalValue(*_pdmesh.nodePtr(neighbors[nb])) -
132 _disp_var[k]->getNodalValue(*_current_elem->node_ptr(_qp));
133
134 weight_nb = _horizon_radius[_qp] / origin_vec_nb.norm();
135 for (unsigned int k = 0; k < _dim; ++k)
136 {
137 for (unsigned int l = 0; l < _dim; ++l)
138 {
139 _shape2[_qp](k, l) += weight_nb * origin_vec_nb(k) * origin_vec_nb(l) * vol_nb;
140 _deformation_gradient[_qp](k, l) +=
141 weight_nb * current_vec_nb(k) * origin_vec_nb(l) * vol_nb;
142 }
143 // calculate derivatives of deformation_gradient w.r.t displacements of node nb
144 _ddgraddu[_qp](0, k) += -weight_nb * origin_vec_nb(k) * vol_nb;
145 _ddgraddv[_qp](1, k) += -weight_nb * origin_vec_nb(k) * vol_nb;
146 if (_dim == 3)
147 _ddgraddw[_qp](2, k) += -weight_nb * origin_vec_nb(k) * vol_nb;
148 }
149 }
150
151 // finalize the deformation gradient tensor
152 if (_shape2[_qp].det() == 0.)
153 mooseError("Singular shape tensor is detected in ComputeStrainBaseNOSPD! Use "
154 "SingularShapeTensorEliminatorUserObjectPD to avoid singular shape tensor!");
155
156 _deformation_gradient[_qp] *= _shape2[_qp].inverse();
157 _ddgraddu[_qp] *= _shape2[_qp].inverse();
158 _ddgraddv[_qp] *= _shape2[_qp].inverse();
159 _ddgraddw[_qp] *= _shape2[_qp].inverse();
160}
161
162void
164{
165 std::vector<dof_id_type> neighbors = _pdmesh.getNeighbors(_current_elem->node_id(_qp));
166 std::vector<dof_id_type> bonds = _pdmesh.getBonds(_current_elem->node_id(_qp));
167
168 dof_id_type nb_index =
169 std::find(neighbors.begin(), neighbors.end(), _current_elem->node_id(1 - _qp)) -
170 neighbors.begin();
171 std::vector<dof_id_type> dg_neighbors =
172 _pdmesh.getBondDeformationGradientNeighbors(_current_elem->node_id(_qp), nb_index);
173 Real dg_sub_vol = _pdmesh.getHorizonSubsetVolume(_current_elem->node_id(_qp), nb_index);
174 Real dg_sub_vol_sum = _pdmesh.getHorizonSubsetVolumeSum(_current_elem->node_id(_qp));
175
176 // calculate the shape tensor and prepare the deformation gradient tensor
177 Real vol_nb, weight_nb;
178 RealGradient origin_vec_nb, current_vec_nb;
179
180 for (unsigned int nb = 0; nb < dg_neighbors.size(); ++nb)
181 if (_bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[dg_neighbors[nb]])) > 0.5)
182 {
183 vol_nb = _pdmesh.getNodeVolume(neighbors[dg_neighbors[nb]]);
184 origin_vec_nb = _pdmesh.getNodeCoord(neighbors[dg_neighbors[nb]]) -
185 _pdmesh.getNodeCoord(_current_elem->node_id(_qp));
186
187 for (unsigned int k = 0; k < _dim; ++k)
188 current_vec_nb(k) =
189 origin_vec_nb(k) +
190 _disp_var[k]->getNodalValue(*_pdmesh.nodePtr(neighbors[dg_neighbors[nb]])) -
191 _disp_var[k]->getNodalValue(*_current_elem->node_ptr(_qp));
192
193 weight_nb = _horizon_radius[_qp] / origin_vec_nb.norm();
194 for (unsigned int k = 0; k < _dim; ++k)
195 {
196 for (unsigned int l = 0; l < _dim; ++l)
197 {
198 _shape2[_qp](k, l) += weight_nb * origin_vec_nb(k) * origin_vec_nb(l) * vol_nb;
199 _deformation_gradient[_qp](k, l) +=
200 weight_nb * current_vec_nb(k) * origin_vec_nb(l) * vol_nb;
201 }
202 // calculate derivatives of deformation_gradient w.r.t displacements of node i
203 _ddgraddu[_qp](0, k) += -weight_nb * origin_vec_nb(k) * vol_nb;
204 _ddgraddv[_qp](1, k) += -weight_nb * origin_vec_nb(k) * vol_nb;
205 if (_dim == 3)
206 _ddgraddw[_qp](2, k) += -weight_nb * origin_vec_nb(k) * vol_nb;
207 }
208 }
209 // finalize the deformation gradient and its derivatives
210 if (_shape2[_qp].det() == 0.)
211 computeConventionalQpDeformationGradient(); // this will affect the corresponding jacobian
212 // calculation
213 else
214 {
215 _deformation_gradient[_qp] *= _shape2[_qp].inverse();
216 _ddgraddu[_qp] *= _shape2[_qp].inverse();
217 _ddgraddv[_qp] *= _shape2[_qp].inverse();
218 _ddgraddw[_qp] *= _shape2[_qp].inverse();
219 }
220
221 // force state multiplier
222 if (_stabilization == "BOND_HORIZON_I")
223 _multi[_qp] = _horizon_radius[_qp] / _origin_vec.norm() * _node_vol[0] * _node_vol[1] *
224 dg_sub_vol / _horizon_vol[_qp];
225 else if (_stabilization == "BOND_HORIZON_II")
226 _multi[_qp] = _node_vol[_qp] * dg_sub_vol / dg_sub_vol_sum;
227}
228
229void
231{
232 setupMeshRelatedData(); // function from base class
233 computeBondCurrentLength(); // current length of a bond from base class
234 computeBondStretch(); // stretch of a bond
235
236 for (_qp = 0; _qp < _nnodes; ++_qp)
238}
239
240void
242{
243 _total_stretch[0] = _current_len / _origin_vec.norm() - 1.0;
244 _total_stretch[1] = _total_stretch[0];
245 _mechanical_stretch[0] = _total_stretch[0];
246
247 Real factor = 1.0;
248 if (_plane_strain)
250
251 for (auto es : _eigenstrains)
252 _mechanical_stretch[0] -= 0.5 * factor * ((*es)[0](2, 2) + (*es)[1](2, 2));
253
254 _mechanical_stretch[1] = _mechanical_stretch[0];
255}
void mooseError(Args &&... args)
std::vector< const MaterialProperty< RankTwoTensor > * > _eigenstrains
virtual void computeBondHorizonQpDeformationGradient()
Function to compute bond-associated horizon based deformation gradient.
const MaterialProperty< RankFourTensor > & _Cijkl
Material properties to fetch.
const bool _plane_strain
Plane strain problem or not, this is only used for mechanical stretch calculation.
ComputeStrainBaseNOSPD(const InputParameters &parameters)
MaterialProperty< RankTwoTensor > & _total_strain
MaterialProperty< RankTwoTensor > & _ddgraddu
virtual void computeConventionalQpDeformationGradient()
Function to compute conventional nonlocal deformation gradient.
MaterialProperty< RankTwoTensor > & _ddgraddw
static InputParameters validParams()
MaterialProperty< RankTwoTensor > & _shape2
Material properties to store.
const MooseEnum _stabilization
Option of stabilization scheme for correspondence material model: FORCE, BOND_HORIZON_I or BOND_HORIZ...
virtual void computeProperties() override
std::vector< MaterialPropertyName > _eigenstrain_names
virtual void computeQpDeformationGradient()
Function to compute deformation gradient for peridynamic correspondence model.
MaterialProperty< RankTwoTensor > & _ddgraddv
MaterialProperty< RankTwoTensor > & _mechanical_strain
virtual void initQpStatefulProperties() override
virtual void computeBondStretch() override
MaterialProperty< RankTwoTensor > & _deformation_gradient
virtual void computeQpStrain()=0
Function to compute strain tensors.
MaterialProperty< Real > & _sf_coeff
fictitious force coefficient for force stabilized model
MaterialProperty< Real > & _multi
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
Base material class for peridynamic solid mechanics models.
static InputParameters validParams()
T getIsotropicYoungsModulus(const RankFourTensorTempl< T > &elasticity_tensor)
Get the Young's modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must b...
T getIsotropicPoissonsRatio(const RankFourTensorTempl< T > &elasticity_tensor)
Get the Poisson's modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must...