https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SingularShapeTensorEliminatorUserObjectPD.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
11#include "AuxiliarySystem.h"
12
14
17{
19 params.addClassDescription("UserObject to eliminate the existance of singular shape tensor");
20
21 return params;
22}
23
29
30void
35
36void
38{
39 bool converged = false;
40
41 // Loop through the active local elements to check the shape tensor singularity
42 auto first_elem = _mesh.getMesh().active_local_elements_begin();
43 auto last_elem = _mesh.getMesh().active_local_elements_end();
44
45 unsigned int singularity_count, loop_count = 0;
46 bool should_print = true; // for printing purpose only
47
48 while (!converged)
49 {
50 singularity_count = 0;
51 for (auto elem = first_elem; elem != last_elem; ++elem)
52 {
53 // shape tensor singularity check only applies to intact Edge2 elems
54 if ((*elem)->type() == 0 && _bond_status_var->getElementalValue(*elem) > 0.5)
55 {
57 {
58 dof_id_type dof = (*elem)->dof_number(_aux.number(), _bond_status_var->number(), 0);
59 _aux.solution().set(dof, 0); // treat bonds with singular shape tensor as broken
60
61 singularity_count++;
62 }
63 }
64 }
65
66 gatherSum(singularity_count); // gather the value across processors
67
68 if (singularity_count == 0)
69 converged = true;
70 else // sync aux across processors
71 {
73 _aux.update();
74 }
75
76 if (singularity_count > 0 && should_print) // print once
77 {
78 _console << COLOR_MAGENTA << " Singular shape tensor detected! Elimination in process ... "
79 << COLOR_DEFAULT << std::endl;
80 should_print = false;
81 }
82
83 loop_count++;
84 if ((loop_count == 1 && singularity_count != 0) || loop_count > 1)
85 _console << COLOR_MAGENTA << " Loop: " << loop_count
86 << ", Singularities: " << singularity_count << COLOR_DEFAULT << std::endl;
87 }
88
89 if (loop_count > 1)
90 _console << COLOR_MAGENTA << " Elimination done!" << COLOR_DEFAULT << std::endl;
91}
92
93void
98
99bool
101{
102 bool singular = false;
103
104 RankTwoTensor shape_tensor;
105 Real vol_nb, weight_nb, horizon_nd;
106 RealGradient origin_vec_nb;
107 for (unsigned int nd = 0; nd < _nnodes; ++nd)
108 {
109 std::vector<dof_id_type> neighbors = _pdmesh.getNeighbors(elem->node_id(nd));
110 std::vector<dof_id_type> bonds =
111 _pdmesh.getBonds(elem->node_id(nd)); // potentially includes ghosted elems
112 horizon_nd = _pdmesh.getHorizon(elem->node_id(nd));
113
114 shape_tensor.zero();
115 if (_dim == 2)
116 shape_tensor(2, 2) = 1.0;
117
118 for (unsigned int nb = 0; nb < neighbors.size(); ++nb)
119 if (_bond_status_var->getElementalValue(_pdmesh.elemPtr(bonds[nb])) > 0.5)
120 {
121 vol_nb = _pdmesh.getNodeVolume(neighbors[nb]);
122 origin_vec_nb =
123 _pdmesh.getNodeCoord(neighbors[nb]) - _pdmesh.getNodeCoord(elem->node_id(nd));
124 weight_nb = horizon_nd / origin_vec_nb.norm();
125
126 for (unsigned int k = 0; k < _dim; ++k)
127 for (unsigned int l = 0; l < _dim; ++l)
128 shape_tensor(k, l) += weight_nb * origin_vec_nb(k) * origin_vec_nb(l) * vol_nb;
129 }
130
131 if (shape_tensor.det() == 0.)
132 singular = true;
133 }
134
135 return singular;
136}
registerMooseObject("PeridynamicsApp", SingularShapeTensorEliminatorUserObjectPD)
const ConsoleStream _console
PeridynamicsMesh & _pdmesh
Reference to peridynamics mesh.
const unsigned int _nnodes
number of nodes for a edge element
AuxiliarySystem & _aux
Reference to auxiliary system.
MooseVariable * _bond_status_var
Bond status aux variable.
const unsigned int _dim
Problem dimension.
static InputParameters validParams()
MooseMesh & _mesh
Reference to Moose mesh.
void addClassDescription(const std::string &doc_string)
virtual Elem * elemPtr(const dof_id_type i)
MeshBase & getMesh()
unsigned int number() const
DofValue getElementalValue(const Elem *elem, unsigned int idx=0) const
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.
UserObject class to eliminate the existance of singular shape tensor due to bond breakage determined ...
bool checkShapeTensorSingularity(const Elem *elem)
function to compute and check the singularity of shape tensor of a bond
SingularShapeTensorEliminatorUserObjectPD(const InputParameters &parameters)
unsigned int number() const
NumericVector< Number > & solution()
void gatherSum(T &value)
virtual void set(const numeric_index_type i, const T value)=0
virtual void close()=0