13 #include "libmesh/quadrature.h"
20 params.addClassDescription(
21 "Base class for Self-stabilized Non-Ordinary State-based PeriDynamic (SNOSPD) "
22 "correspondence material model");
24 params.addParam<
bool>(
"plane_strain",
26 "Plane strain problem or not, this will affect the mechanical stretch "
27 "calculation for problem with eigenstrains");
28 params.addParam<std::vector<MaterialPropertyName>>(
29 "eigenstrain_names",
"List of eigenstrains to be applied in this strain calculation");
36 _plane_strain(getParam<bool>(
"plane_strain")),
38 _eigenstrain_names(getParam<std::vector<MaterialPropertyName>>(
"eigenstrain_names")),
39 _eigenstrains(_eigenstrain_names.size()),
40 _shape2(declareProperty<
RankTwoTensor>(
"rank_two_shape_tensor")),
41 _deformation_gradient(declareProperty<
RankTwoTensor>(
"deformation_gradient")),
42 _ddgraddu(declareProperty<
RankTwoTensor>(
"ddeformation_gradient_du")),
43 _ddgraddv(declareProperty<
RankTwoTensor>(
"ddeformation_gradient_dv")),
44 _ddgraddw(declareProperty<
RankTwoTensor>(
"ddeformation_gradient_dw")),
45 _total_strain(declareProperty<
RankTwoTensor>(
"total_strain")),
46 _mechanical_strain(declareProperty<
RankTwoTensor>(
"mechanical_strain")),
47 _multi(declareProperty<Real>(
"multi"))
64 if (_qrule->n_points() < 2)
66 "NOSPD models require Gauss_Lobatto rule and a minimum of 2 quadrature points, i.e., "
81 if (_bond_status_var->getElementalValue(_current_elem) < 0.5)
83 _shape2[_qp] = RankTwoTensor::initIdentity;
91 const Node * cur_nd = _current_elem->node_ptr(_qp);
92 const Node * end_nd = _current_elem->node_ptr(1 - _qp);
93 std::vector<dof_id_type> neighbors = _pdmesh.getNeighbors(cur_nd->id());
94 std::vector<dof_id_type> bonds = _pdmesh.getBonds(cur_nd->id());
97 std::find(neighbors.begin(), neighbors.end(), end_nd->id()) - neighbors.begin();
98 std::vector<dof_id_type> dg_neighbors = _pdmesh.getDefGradNeighbors(cur_nd->id(), nb);
101 Real dgnodes_vsum = 0.0;
104 for (
unsigned int j = 0; j < dg_neighbors.size(); ++j)
105 if (_bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[dg_neighbors[j]])) > 0.5)
107 Node * node_j = _pdmesh.nodePtr(neighbors[dg_neighbors[j]]);
108 Real vol_j = _pdmesh.getPDNodeVolume(neighbors[dg_neighbors[j]]);
109 dgnodes_vsum += vol_j;
110 ori_vec = *node_j - *_pdmesh.nodePtr(cur_nd->id());
112 for (
unsigned int k = 0; k < _dim; ++k)
113 cur_vec(k) = ori_vec(k) + _disp_var[k]->getNodalValue(*node_j) -
114 _disp_var[k]->getNodalValue(*cur_nd);
116 Real ori_len = ori_vec.norm();
117 for (
unsigned int k = 0; k < _dim; ++k)
119 for (
unsigned int l = 0; l < _dim; ++l)
121 _shape2[_qp](k, l) += _horiz_rad[_qp] / ori_len * ori_vec(k) * ori_vec(l) * vol_j;
123 _horiz_rad[_qp] / ori_len * cur_vec(k) * ori_vec(l) * vol_j;
126 _ddgraddu[_qp](0, k) += -_horiz_rad[_qp] / ori_len * ori_vec(k) * vol_j;
127 _ddgraddv[_qp](1, k) += -_horiz_rad[_qp] / ori_len * ori_vec(k) * vol_j;
129 _ddgraddw[_qp](2, k) += -_horiz_rad[_qp] / ori_len * ori_vec(k) * vol_j;
139 _multi[_qp] = _horiz_rad[_qp] / _origin_length * _node_vol[0] * _node_vol[1] * dgnodes_vsum /
147 setupMeshRelatedData();
148 computeBondCurrentLength();
151 for (_qp = 0; _qp < _nnodes; ++_qp)
158 _total_stretch[0] = _current_length / _origin_length - 1.0;
159 _total_stretch[1] = _total_stretch[0];
160 _mechanical_stretch[0] = _total_stretch[0];
167 _mechanical_stretch[0] -= 0.5 * factor * ((*es)[0](2, 2) + (*es)[1](2, 2));
169 _mechanical_stretch[1] = _mechanical_stretch[0];