13 #include "libmesh/quadrature.h" 20 "Base material strain class for the peridynamic correspondence models");
22 MooseEnum stabilization_option(
"FORCE BOND_HORIZON_I BOND_HORIZON_II");
26 "Stabilization techniques used for the peridynamic correspondence model");
27 params.
addParam<
bool>(
"plane_strain",
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");
39 _stabilization(getParam<
MooseEnum>(
"stabilization")),
40 _plane_strain(getParam<bool>(
"plane_strain")),
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"))
68 if (_qrule->n_points() < 2)
70 "NOSPD models require Gauss_Lobatto rule and a minimum of 2 quadrature points, i.e., " 88 if (_bond_status_var->getElementalValue(_current_elem) > 0.5)
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];
102 paramError(
"stabilization",
103 "Unknown stabilization scheme for peridynamic correspondence model!");
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));
119 Real vol_nb, weight_nb;
122 for (
unsigned int nb = 0; nb < neighbors.size(); ++nb)
123 if (_bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[nb])) > 0.5)
125 vol_nb = _pdmesh.getNodeVolume(neighbors[nb]);
127 _pdmesh.getNodeCoord(neighbors[nb]) - _pdmesh.getNodeCoord(_current_elem->node_id(_qp));
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));
134 weight_nb = _horizon_radius[_qp] / origin_vec_nb.
norm();
135 for (
unsigned int k = 0;
k < _dim; ++
k)
137 for (
unsigned int l = 0; l < _dim; ++l)
139 _shape2[_qp](
k, l) += weight_nb * origin_vec_nb(
k) * origin_vec_nb(l) * vol_nb;
141 weight_nb * current_vec_nb(
k) * origin_vec_nb(l) * vol_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;
147 _ddgraddw[_qp](2,
k) += -weight_nb * origin_vec_nb(
k) * vol_nb;
153 mooseError(
"Singular shape tensor is detected in ComputeStrainBaseNOSPD! Use " 154 "SingularShapeTensorEliminatorUserObjectPD to avoid singular shape tensor!");
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));
169 std::find(neighbors.begin(), neighbors.end(), _current_elem->node_id(1 - _qp)) -
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));
177 Real vol_nb, weight_nb;
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)
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));
187 for (
unsigned int k = 0;
k < _dim; ++
k)
190 _disp_var[
k]->getNodalValue(*_pdmesh.nodePtr(neighbors[dg_neighbors[nb]])) -
191 _disp_var[
k]->getNodalValue(*_current_elem->node_ptr(_qp));
193 weight_nb = _horizon_radius[_qp] / origin_vec_nb.
norm();
194 for (
unsigned int k = 0;
k < _dim; ++
k)
196 for (
unsigned int l = 0; l < _dim; ++l)
198 _shape2[_qp](
k, l) += weight_nb * origin_vec_nb(
k) * origin_vec_nb(l) * vol_nb;
200 weight_nb * current_vec_nb(
k) * origin_vec_nb(l) * vol_nb;
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;
206 _ddgraddw[_qp](2,
k) += -weight_nb * origin_vec_nb(
k) * vol_nb;
223 _multi[_qp] = _horizon_radius[_qp] / _origin_vec.norm() * _node_vol[0] * _node_vol[1] *
224 dg_sub_vol / _horizon_vol[_qp];
226 _multi[_qp] = _node_vol[_qp] * dg_sub_vol / dg_sub_vol_sum;
232 setupMeshRelatedData();
233 computeBondCurrentLength();
236 for (_qp = 0; _qp < _nnodes; ++_qp)
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];
252 _mechanical_stretch[0] -= 0.5 * factor * ((*es)[0](2, 2) + (*es)[1](2, 2));
254 _mechanical_stretch[1] = _mechanical_stretch[0];
virtual void computeBondStretch() override
virtual void computeQpDeformationGradient()
Function to compute deformation gradient for peridynamic correspondence model.
MaterialProperty< RankTwoTensor > & _shape2
Material properties to store.
auto norm() const -> decltype(std::norm(Real()))
MaterialProperty< RankTwoTensor > & _deformation_gradient
virtual void initQpStatefulProperties() override
const MooseEnum _stabilization
Option of stabilization scheme for correspondence material model: FORCE, BOND_HORIZON_I or BOND_HORIZ...
void mooseError(Args &&... args)
MaterialProperty< RankTwoTensor > & _ddgraddv
MaterialProperty< RankTwoTensor > & _ddgraddw
static InputParameters validParams()
const bool _plane_strain
Plane strain problem or not, this is only used for mechanical stretch calculation.
virtual void computeQpStrain()=0
Function to compute strain tensors.
ComputeStrainBaseNOSPD(const InputParameters ¶meters)
virtual void computeBondHorizonQpDeformationGradient()
Function to compute bond-associated horizon based deformation gradient.
std::vector< const MaterialProperty< RankTwoTensor > * > _eigenstrains
virtual void computeProperties() override
MaterialProperty< Real > & _sf_coeff
fictitious force coefficient for force stabilized model
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void computeConventionalQpDeformationGradient()
Function to compute conventional nonlocal deformation gradient.
std::vector< MaterialPropertyName > _eigenstrain_names
MaterialProperty< Real > & _multi
MaterialProperty< RankTwoTensor > & _total_strain
const MaterialProperty< RankFourTensor > & _Cijkl
Material properties to fetch.
static InputParameters validParams()
Base material class for peridynamic solid mechanics models.
static const std::string k
MaterialProperty< RankTwoTensor > & _ddgraddu
MaterialProperty< RankTwoTensor > & _mechanical_strain