https://mooseframework.inl.gov
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 
25  const InputParameters & parameters)
26  : GeneralUserObjectBasePD(parameters)
27 {
28 }
29 
30 void
32 {
33  _aux.solution().close();
34 }
35 
36 void
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  {
56  if (checkShapeTensorSingularity(*elem))
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  {
72  _aux.solution().close();
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 
93 void
95 {
96  _aux.solution().close();
97 }
98 
99 bool
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)
AuxiliarySystem & _aux
Reference to auxiliary system.
auto norm() const -> decltype(std::norm(Real()))
virtual Elem * elemPtr(const dof_id_type i)
MooseMesh & _mesh
Reference to Moose mesh.
NumericVector< Number > & solution()
unsigned int number() const
std::vector< dof_id_type > getNeighbors(dof_id_type node_id)
Function to return neighbor nodes indices for node node_id.
SingularShapeTensorEliminatorUserObjectPD(const InputParameters &parameters)
UserObject class to eliminate the existance of singular shape tensor due to bond breakage determined ...
const unsigned int _dim
Problem dimension.
static InputParameters validParams()
OutputData getElementalValue(const Elem *elem, unsigned int idx=0) const
bool converged(const std::vector< std::pair< unsigned int, Real >> &residuals, const std::vector< Real > &abs_tolerances)
Based on the residuals, determine if the iterative process converged or not.
const unsigned int _nnodes
number of nodes for a edge element
PeridynamicsMesh & _pdmesh
Reference to peridynamics mesh.
void gatherSum(T &value)
MeshBase & getMesh()
bool first_elem
unsigned int number() const
virtual void close()=0
Real getNodeVolume(dof_id_type node_id)
Function to return nodal volume for node node_id.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Point getNodeCoord(dof_id_type node_id)
Function to return coordinates for node node_id.
bool checkShapeTensorSingularity(const Elem *elem)
function to compute and check the singularity of shape tensor of a bond
void addClassDescription(const std::string &doc_string)
virtual void set(const numeric_index_type i, const Number value)=0
const ConsoleStream _console
std::vector< dof_id_type > getBonds(dof_id_type node_id)
Function to return the bond number connected with node node_id.
static const std::string k
Definition: NS.h:130
MooseVariable * _bond_status_var
Bond status aux variable.
uint8_t dof_id_type
Real getHorizon(dof_id_type node_id)
Function to return horizon size.