12 #include "RankTwoTensor.h"
13 #include "RankFourTensor.h"
22 params.addClassDescription(
"Class for calculating residual and Jacobian for Non-Ordinary "
23 "State-based PeriDynamic solid mechanics formulation using a "
24 "fictitious force method for stabilization.");
26 params.addRequiredParam<
unsigned int>(
28 "An integer corresponding to the variable this kernel acts on (0 for x, 1 for y, 2 for z)");
34 const InputParameters & parameters)
36 _sf_coeff(getMaterialProperty<Real>(
"stabilization_force_coeff")),
37 _component(getParam<unsigned int>(
"component"))
54 std::vector<Real> nodal_force_comp(_nnodes);
55 for (
unsigned int nd = 0; nd < _nnodes; ++nd)
57 (nd == 0 ? 1 : -1) * _origin_vec_ij;
59 _local_re(0) = -(nodal_force_comp[0] - nodal_force_comp[1] + sforce) * _bond_status_ij;
60 _local_re(1) = -_local_re(0);
67 for (_i = 0; _i < _test.size(); ++_i)
68 for (_j = 0; _j < _phi.size(); ++_j)
69 _local_ke(_i, _j) += (_i == 0 ? -1 : 1) *
_multi[_j] *
71 _origin_vec_ij * _bond_status_ij;
75 for (_i = 0; _i < _test.size(); ++_i)
76 for (_j = 0; _j < _phi.size(); ++_j)
77 _local_ke(_i, _j) += (_i == _j ? 1 : -1) * diag * _bond_status_ij;
84 for (
unsigned int cur_nd = 0; cur_nd < _nnodes; ++cur_nd)
87 std::vector<dof_id_type> dof(_nnodes);
88 dof[0] = _current_elem->node_ptr(cur_nd)->dof_number(_sys.number(), _var.number(), 0);
89 std::vector<dof_id_type> neighbors = _pdmesh.getNeighbors(_current_elem->node_id(cur_nd));
90 std::vector<dof_id_type> bonds = _pdmesh.getBonds(_current_elem->node_id(cur_nd));
91 for (
unsigned int k = 0; k < neighbors.size(); ++k)
93 Node * node_k = _pdmesh.nodePtr(neighbors[k]);
94 dof[1] = node_k->dof_number(_sys.number(), _var.number(), 0);
95 Real vol_k = _pdmesh.getPDNodeVolume(neighbors[k]);
98 RealGradient origin_vec_ijk = *node_k - *_pdmesh.nodePtr(_current_elem->node_id(cur_nd));
102 for (
unsigned int j = 0; j < _dim; ++j)
104 vol_k * _horiz_rad[cur_nd] / origin_vec_ijk.norm() * origin_vec_ijk(j);
106 dFdUk *=
_shape2[cur_nd].inverse();
110 Real bond_status_ijk = _bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[k]));
112 _local_ke.resize(_test.size(), _phi.size());
114 for (_i = 0; _i < _test.size(); ++_i)
115 for (_j = 0; _j < _phi.size(); ++_j)
116 _local_ke(_i, _j) = (_i == 0 ? -1 : 1) * (_j == 0 ? 0 : 1) *
_multi[cur_nd] *
118 _origin_vec_ij * _bond_status_ij * bond_status_ijk;
120 _assembly.cacheJacobianBlock(_local_ke,
_ivardofs_ij, dof, _var.scalingFactor());
122 if (_has_diag_save_in)
124 unsigned int rows = _test.size();
125 DenseVector<Real> diag(rows);
126 for (
unsigned int i = 0; i < rows; ++i)
127 diag(i) = _local_ke(i, i);
129 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
130 for (
unsigned int i = 0; i < _diag_save_in.size(); ++i)
131 _diag_save_in[i]->sys().solution().add_vector(diag, _diag_save_in[i]->dofIndices());
139 unsigned int coupled_component)
142 if (coupled_component == 3)
144 std::vector<RankTwoTensor> dSdT(_nnodes);
145 for (
unsigned int nd = 0; nd < _nnodes; ++nd)
149 for (_i = 0; _i < _test.size(); ++_i)
150 for (_j = 0; _j < _phi.size(); ++_j)
151 _local_ke(_i, _j) += (_i == 0 ? -1 : 1) *
_multi[_j] *
157 for (_i = 0; _i < _test.size(); ++_i)
158 for (_j = 0; _j < _phi.size(); ++_j)
160 (_i == 0 ? -1 : 1) *
_multi[_j] *
162 _origin_vec_ij * _bond_status_ij;
168 unsigned int jvar_num,
unsigned int coupled_component)
170 if (coupled_component != 3)
172 for (
unsigned int cur_nd = 0; cur_nd < _nnodes; ++cur_nd)
175 std::vector<dof_id_type> jvardofs_ijk(_nnodes);
176 jvardofs_ijk[0] = _current_elem->node_ptr(cur_nd)->dof_number(_sys.number(), jvar_num, 0);
177 std::vector<dof_id_type> neighbors = _pdmesh.getNeighbors(_current_elem->node_id(cur_nd));
178 std::vector<dof_id_type> bonds = _pdmesh.getBonds(_current_elem->node_id(cur_nd));
179 for (
unsigned int k = 0; k < neighbors.size(); ++k)
181 Node * node_k = _pdmesh.nodePtr(neighbors[k]);
182 jvardofs_ijk[1] = node_k->dof_number(_sys.number(), jvar_num, 0);
183 Real vol_k = _pdmesh.getPDNodeVolume(neighbors[k]);
186 RealGradient origin_vec_ijk = *node_k - *_pdmesh.nodePtr(_current_elem->node_id(cur_nd));
190 for (
unsigned int j = 0; j < _dim; ++j)
191 dFdUk(coupled_component, j) =
192 _horiz_rad[cur_nd] / origin_vec_ijk.norm() * origin_vec_ijk(j) * vol_k;
194 dFdUk *=
_shape2[cur_nd].inverse();
198 Real bond_status_ijk = _bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[k]));
201 for (_i = 0; _i < _test.size(); ++_i)
202 for (_j = 0; _j < _phi.size(); ++_j)
203 _local_ke(_i, _j) = (_i == 0 ? -1 : 1) * (_j == 0 ? 0 : 1) *
_multi[cur_nd] *
205 _origin_vec_ij * _bond_status_ij * bond_status_ijk;
207 _assembly.cacheJacobianBlock(_local_ke,
_ivardofs_ij, jvardofs_ijk, _var.scalingFactor());