https://mooseframework.inl.gov
Loading...
Searching...
No Matches
NodalRankTwoPD.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 "NodalRankTwoPD.h"
11#include "PeridynamicsMesh.h"
12#include "RankTwoScalarTools.h"
13
15
18{
21 "Class for computing and outputing components and scalar quantities "
22 "of nodal rank two strain and stress tensors for bond-based and ordinary "
23 "state-based peridynamic models");
24
25 params.addRequiredCoupledVar("displacements", "Nonlinear variable names for the displacements");
26 params.addCoupledVar("temperature", "Nonlinear variable name for the temperature");
27 params.addCoupledVar("scalar_out_of_plane_strain",
28 "Scalar variable for strain in the out-of-plane direction");
29 params.addParam<bool>(
30 "plane_stress",
31 false,
32 "Plane stress problem or not. This option applies to BPD and OSPD models only");
33 params.addParam<Real>("youngs_modulus", "Material constant: Young's modulus");
34 params.addParam<Real>("poissons_ratio", "Material constant: Poisson's ratio");
35 params.addParam<Real>("thermal_expansion_coeff",
36 "Value of material thermal expansion coefficient");
37 params.addParam<Real>("stress_free_temperature", 0.0, "Stress free temperature");
38 params.addRequiredParam<std::string>(
39 "rank_two_tensor",
40 "Parameter to set which rank two tensor: total_strain, mechanical_strain or stress");
41 params.addRequiredParam<std::string>("output_type", "Type of output: component or scalar");
42 params.addParam<MooseEnum>(
43 "scalar_type", RankTwoScalarTools::scalarOptions(), "Type of scalar output");
44 params.addParam<unsigned int>("index_i", "The index i of ij for the tensor to output (0, 1, 2)");
45 params.addParam<unsigned int>("index_j", "The index j of ij for the tensor to output (0, 1, 2)");
46 params.addParam<Point>("point1",
47 Point(0, 0, 0),
48 "Start point for axis used to calculate some direction dependent material "
49 "tensor scalar quantities");
50 params.addParam<Point>("point2",
51 Point(1, 0, 0),
52 "End point for axis used to calculate some direction dependent material "
53 "tensor scalar quantities");
54
55 return params;
56}
57
59 : AuxKernelBasePD(parameters),
60 _has_temp(isCoupled("temperature")),
61 _temp_var(_has_temp ? getVar("temperature", 0) : nullptr),
62 _bond_status_var(&_subproblem.getStandardVariable(_tid, "bond_status")),
63 _scalar_out_of_plane_strain_coupled(isCoupledScalar("scalar_out_of_plane_strain")),
64 _scalar_out_of_plane_strain(_scalar_out_of_plane_strain_coupled
65 ? coupledScalarValue("scalar_out_of_plane_strain")
66 : _zero),
67 _plane_stress(getParam<bool>("plane_stress")),
68 _temp_ref(getParam<Real>("stress_free_temperature")),
69 _rank_two_tensor(getParam<std::string>("rank_two_tensor")),
70 _output_type(getParam<std::string>("output_type")),
71 _scalar_type(getParam<MooseEnum>("scalar_type")),
72 _point1(parameters.get<Point>("point1")),
73 _point2(parameters.get<Point>("point2"))
74{
75 if (!_var.isNodal())
76 mooseError("NodalRankTwoPD operates on nodal variable!");
77
78 if (coupledComponents("displacements") != _dim)
79 mooseError("Number of displacements should be the same as problem dimension!");
80 for (unsigned int i = 0; i < coupledComponents("displacements"); ++i)
81 _disp_var.push_back(getVar("displacements", i));
82
83 _Cijkl.zero();
84 if (_rank_two_tensor == "stress")
85 {
86 if (!isParamValid("youngs_modulus") || !isParamValid("poissons_ratio"))
88 "Both Young's modulus and Poisson's ratio must be provided for stress calculation");
89 else
90 {
91 _youngs_modulus = getParam<Real>("youngs_modulus");
92 _poissons_ratio = getParam<Real>("poissons_ratio");
93 }
94
95 std::vector<Real> iso_const(2);
96 iso_const[0] = _youngs_modulus * _poissons_ratio /
97 ((1.0 + _poissons_ratio) * (1.0 - 2.0 * _poissons_ratio));
98 iso_const[1] = _youngs_modulus / (2.0 * (1.0 + _poissons_ratio));
99
100 // fill elasticity tensor
102 }
103
104 if (_has_temp && !isParamValid("thermal_expansion_coeff"))
105 mooseError("thermal_expansion_coeff is required when temperature is coupled");
106 else if (_has_temp)
107 _alpha = getParam<Real>("thermal_expansion_coeff");
108
109 if (_output_type == "component")
110 {
111 if (!isParamValid("index_i") || !isParamValid("index_j"))
112 mooseError("The output_type is 'component', both 'index_i' and 'index_j' must be provided!");
113 else
114 {
115 _i = getParam<unsigned int>("index_i");
116 _j = getParam<unsigned int>("index_j");
117 }
118 }
119
120 if (_output_type == "scalar" && !isParamValid("scalar_type"))
121 mooseError("The output_type is 'scalar', but no 'scalar_type' is provided!");
122}
123
124Real
126{
127
128 Real val = 0.0;
129 RankTwoTensor tensor;
130 Point p = Point(0, 0, 0);
131
133
134 if (_rank_two_tensor == "total_strain")
135 tensor = _total_strain;
136 else if (_rank_two_tensor == "mechanical_strain")
137 tensor = _mechanical_strain;
138 else if (_rank_two_tensor == "stress")
139 tensor = _stress;
140 else
141 mooseError("NodalRankTwoPD Error: Pass valid rank two tensor: total_strain, "
142 "mechanical_strain or stress");
143
144 if (_output_type == "component")
145 val = RankTwoScalarTools::component(tensor, _i, _j);
146 else if (_output_type == "scalar")
148 else
149 mooseError("NodalRankTwoPD Error: Pass valid output type - component or scalar");
150
151 return val;
152}
153
154void
156{
157 _total_strain.zero();
158 _mechanical_strain.zero();
159 _stress.zero();
160
161 std::vector<dof_id_type> neighbors = _pdmesh.getNeighbors(_current_node->id());
162 std::vector<dof_id_type> bonds = _pdmesh.getBonds(_current_node->id());
163 Real horizon = _pdmesh.getHorizon(_current_node->id());
164
165 // calculate the shape tensor and prepare the deformation gradient tensor
166 RankTwoTensor shape, dgrad, delta(RankTwoTensor::initIdentity), thermal_strain;
167 shape.zero();
168 dgrad.zero();
169 if (_dim == 2)
170 shape(2, 2) = dgrad(2, 2) = 1.0;
171
172 thermal_strain.zero();
173
174 Real vol_nb, weight;
175 RealGradient origin_vec, current_vec;
176
177 for (unsigned int nb = 0; nb < neighbors.size(); ++nb)
178 if (_bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[nb])) > 0.5)
179 {
180 Node * neighbor_nb = _pdmesh.nodePtr(neighbors[nb]);
181 vol_nb = _pdmesh.getNodeVolume(neighbors[nb]);
182 origin_vec =
183 _pdmesh.getNodeCoord(neighbor_nb->id()) - _pdmesh.getNodeCoord(_current_node->id());
184
185 for (unsigned int k = 0; k < _dim; ++k)
186 current_vec(k) = origin_vec(k) + _disp_var[k]->getNodalValue(*neighbor_nb) -
187 _disp_var[k]->getNodalValue(*_current_node);
188
189 weight = horizon / origin_vec.norm();
190
191 for (unsigned int k = 0; k < _dim; ++k)
192 for (unsigned int l = 0; l < _dim; ++l)
193 {
194 shape(k, l) += weight * origin_vec(k) * origin_vec(l) * vol_nb;
195 dgrad(k, l) += weight * current_vec(k) * origin_vec(l) * vol_nb;
196 }
197 }
198
199 // finalize the deformation gradient tensor
200 if (shape.det() != 0.)
201 {
202 dgrad *= shape.inverse();
203
204 // the green-lagrange strain tensor
205 _total_strain = 0.5 * (dgrad.transpose() * dgrad - delta);
206
209 else if (_plane_stress)
210 {
211 if (_has_temp)
212 {
213 Real mstrain00 =
215 Real mstrain11 =
217 Real mstrain22 =
218 -(_Cijkl(2, 2, 0, 0) * mstrain00 + _Cijkl(2, 2, 1, 1) * mstrain11) / _Cijkl(2, 2, 2, 2);
219
220 _total_strain(2, 2) =
222 }
223 else
224 _total_strain(2, 2) =
225 -(_Cijkl(2, 2, 0, 0) * _total_strain(0, 0) + _Cijkl(2, 2, 1, 1) * _total_strain(1, 1)) /
226 _Cijkl(2, 2, 2, 2);
227 }
228
229 if (_has_temp)
230 thermal_strain = _alpha * (_temp_var->getNodalValue(*_current_node) - _temp_ref) * delta;
231
232 _mechanical_strain = _total_strain - thermal_strain;
233
235 }
236}
const Real p
registerMooseObject("PeridynamicsApp", NodalRankTwoPD)
Peridynamic Aux Kernel base class.
PeridynamicsMesh & _pdmesh
Reference to peridynamic mesh object.
const unsigned int _dim
Problem dimension.
static InputParameters validParams()
const MooseArray< Point > & _q_point
const Node *const & _current_node
MooseVariableField< ComputeValueType > & _var
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
unsigned int coupledComponents(const std::string &var_name) const
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
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)
void addCoupledVar(const std::string &name, const std::string &doc_string)
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
virtual Elem * elemPtr(const dof_id_type i)
virtual const Node * nodePtr(const dof_id_type i) const
virtual bool isNodal() const
DofValue getElementalValue(const Elem *elem, unsigned int idx=0) const
DofValue getNodalValue(const Node &node) const
Aux Kernel class to postprocess and output the strain and stress components and equivalents for perid...
const bool _plane_stress
plane stress problem or not
bool _scalar_out_of_plane_strain_coupled
variable for generalized plane strain cases
const Point _point2
const Point _point1
Points for direction dependent scalar output.
virtual void computeRankTwoTensors()
Function to compute the total strain, mechanical strain, and stress tensors at each discrete material...
static InputParameters validParams()
Real computeValue() override
MooseVariable * _temp_var
coupled temperature variable
std::vector< MooseVariable * > _disp_var
@
RankFourTensor _Cijkl
elasticity tensor
NodalRankTwoPD(const InputParameters &parameters)
const Real _temp_ref
reference temperature
MooseVariable * _bond_status_var
bond_status variable
std::string _output_type
output type: component or scalar
RankTwoTensor _mechanical_strain
Real _youngs_modulus
material constants
const VariableValue & _scalar_out_of_plane_strain
unsigned int _i
component index
unsigned int _j
std::string _rank_two_tensor
name of rank two tensor to be processed: total_strain, mechanical_strain or stress
MooseEnum _scalar_type
specific scalar type to be output
RankTwoTensor _stress
RankTwoTensor _total_strain
rank two tensors
Real getNodeVolume(dof_id_type node_id)
Function to return nodal volume for node node_id.
Real getHorizon(dof_id_type node_id)
Function to return horizon size.
Point getNodeCoord(dof_id_type node_id)
Function to return coordinates for node node_id.
std::vector< dof_id_type > getBonds(dof_id_type node_id)
Function to return the bond number connected with node node_id.
std::vector< dof_id_type > getNeighbors(dof_id_type node_id)
Function to return neighbor nodes indices for node node_id.
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method)
RankTwoTensorTempl< T > inverse() const
RankTwoTensorTempl< T > transpose() const
MooseEnum scalarOptions()
This enum is left for legacy calls.
T component(const RankTwoTensorTempl< T > &r2tensor, unsigned int i, unsigned int j)
T getQuantity(const RankTwoTensorTempl< T > &tensor, const MooseEnum &scalar_type, const Point &point1, const Point &point2, const Point &curr_point, Point &direction)