www.mooseframework.org
PeridynamicsMesh.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "PeridynamicsMesh.h"
11 
12 #include "libmesh/elem.h"
13 
14 registerMooseObject("PeridynamicsApp", PeridynamicsMesh);
15 
16 template <>
17 InputParameters
19 {
20  InputParameters params = validParams<MooseMesh>();
21  params.addClassDescription("Mesh class to store and return peridynamics specific mesh data");
22 
23  params.addParam<Real>("horizon_radius", "Value of horizon size in terms of radius");
24  params.addParam<Real>("horizon_number",
25  "The material points spacing number, i.e. ratio of horizon radius to the "
26  "effective average spacing");
27  params.addParam<Real>("bond_associated_horizon_ratio",
28  1.5,
29  "Ratio of bond-associated horizon to nodal horizon. This is the only "
30  "parameters to control the size of bond-associated horizon");
31  params.addParam<std::vector<Point>>("cracks_start",
32  "Cartesian coordinates where predefined line cracks start");
33  params.addParam<std::vector<Point>>("cracks_end",
34  "Cartesian coordinates where predefined line cracks end");
35  params.addParam<std::vector<Real>>("cracks_width", "Widths of predefined line cracks");
36 
37  params.set<bool>("_mesh_generator_mesh") = true;
38 
39  return params;
40 }
41 
42 PeridynamicsMesh::PeridynamicsMesh(const InputParameters & parameters)
43  : MooseMesh(parameters),
44  _horiz_rad(isParamValid("horizon_radius") ? getParam<Real>("horizon_radius") : 0),
45  _has_horiz_num(isParamValid("horizon_number")),
46  _horiz_num(_has_horiz_num ? getParam<Real>("horizon_number") : 0),
47  _bah_ratio(getParam<Real>("bond_associated_horizon_ratio")),
48  _has_cracks(isParamValid("cracks_start") || isParamValid("cracks_end")),
49  _dim(declareRestartableData<unsigned int>("dim")),
50  _n_pdnodes(declareRestartableData<unsigned int>("n_pdnodes")),
51  _n_pdbonds(declareRestartableData<unsigned int>("n_pdbonds")),
52  _pdnode_avg_spacing(declareRestartableData<std::vector<Real>>("pdnode_avg_spacing")),
53  _pdnode_horiz_rad(declareRestartableData<std::vector<Real>>("pdnode_horiz_radius")),
54  _pdnode_vol(declareRestartableData<std::vector<Real>>("pdnode_vol")),
55  _pdnode_horiz_vol(declareRestartableData<std::vector<Real>>("pdnode_horiz_vol")),
56  _pdnode_blockID(declareRestartableData<std::vector<SubdomainID>>("pdnode_blockID")),
57  _pdnode_elemID(declareRestartableData<std::vector<dof_id_type>>("pdnode_elemID")),
58  _pdnode_neighbors(
59  declareRestartableData<std::vector<std::vector<dof_id_type>>>("pdnode_neighbors")),
60  _pdnode_bonds(declareRestartableData<std::vector<std::vector<dof_id_type>>>("pdnode_bonds")),
61  _dg_neighbors(
62  declareRestartableData<std::vector<std::vector<std::vector<dof_id_type>>>>("dg_neighbors")),
63  _dg_vol_frac(declareRestartableData<std::vector<std::vector<Real>>>("dg_vol_fraction")),
64  _boundary_node_offset(
65  declareRestartableData<std::map<dof_id_type, Real>>("boundary_node_offset"))
66 {
67  if (!(isParamValid("horizon_radius") || _has_horiz_num))
68  mooseError("Must specify either horizon_radius or horizon_number to determine horizon size in "
69  "the mesh block!");
70 
71  if (_has_cracks)
72  {
73  _cracks_start = getParam<std::vector<Point>>("cracks_start");
74  _cracks_end = getParam<std::vector<Point>>("cracks_end");
75  }
76  else
77  {
78  _cracks_start.push_back(Point(0., 0., 0.));
79  _cracks_end.push_back(Point(0., 0., 0.));
80  }
81 
82  if (_cracks_start.size() != _cracks_end.size())
83  mooseError(
84  "Number of cracks starting points is NOT the same as number of cracks ending points!");
85 
86  if (_has_cracks)
87  {
88  if (isParamValid("cracks_width"))
89  {
90  _cracks_width = getParam<std::vector<Real>>("cracks_width");
91  if (_cracks_width.size() != _cracks_start.size())
92  mooseError("Number of cracks width is NOT the same as number of cracks!");
93  }
94  else
95  {
96  for (unsigned int i = 0; i < _cracks_start.size(); ++i)
97  _cracks_width.push_back(0);
98  }
99  }
100  else
101  _cracks_width.push_back(0);
102 }
103 
104 std::unique_ptr<MooseMesh>
106 {
107  return libmesh_make_unique<PeridynamicsMesh>(*this);
108 }
109 
110 void
112 {
113  if (!hasMeshBase())
114  _mesh = _app.getMeshGeneratorMesh();
115 
116  _mesh->prepare_for_use(/*skip_renumber =*/true);
117 }
118 
119 unsigned int
121 {
122  return _dim;
123 }
124 
125 dof_id_type
127 {
128  return _n_pdnodes;
129 }
130 
131 dof_id_type
133 {
134  return _n_pdbonds;
135 }
136 
137 void
139  MeshBase & fe_mesh,
140  std::set<dof_id_type> converted_elem_id,
141  std::multimap<SubdomainID, SubdomainID> connect_block_id_pairs,
142  std::multimap<SubdomainID, SubdomainID> non_connect_block_id_pairs)
143 {
144  _dim = fe_mesh.mesh_dimension();
145  _n_pdnodes = converted_elem_id.size();
146 
147  // initialize data size
148  _pdnode_coord.resize(_n_pdnodes);
151  _pdnode_vol.resize(_n_pdnodes);
153  _pdnode_blockID.resize(_n_pdnodes);
154  _pdnode_elemID.resize(_n_pdnodes);
156  _pdnode_bonds.resize(_n_pdnodes);
157  _dg_neighbors.resize(_n_pdnodes);
158  _dg_vol_frac.resize(_n_pdnodes);
159 
160  // loop through converted fe elements to generate PD nodes structure
161  unsigned int id = 0; // make pd nodes start at 0 in the new mesh
162  for (const auto & eid : converted_elem_id)
163  {
164  Elem * fe_elem = fe_mesh.elem_ptr(eid);
165  // calculate the nodes spacing as average distance between fe element with its neighbors
166  unsigned int n_fe_neighbors = 0;
167  Real dist_sum = 0.0;
168  for (unsigned int j = 0; j < fe_elem->n_neighbors(); ++j)
169  if (fe_elem->neighbor_ptr(j) != nullptr)
170  {
171  dist_sum += (fe_elem->centroid() - fe_elem->neighbor_ptr(j)->centroid()).norm();
172  n_fe_neighbors++;
173  }
174  else // this side is on boundary and calculate the distance to the centroid
175  {
176  Real dist = 0.0;
177  std::vector<unsigned int> nid = fe_elem->nodes_on_side(j);
178  Point p0 = fe_elem->centroid();
179  Point p1 = fe_elem->point(nid[0]);
180  if (fe_elem->dim() == 2) // 2D elems
181  {
182  Point p2 = fe_elem->point(nid.back());
183  Real area = 0.5 * std::abs(p0(0) * (p1(1) - p2(1)) + p1(0) * (p2(1) - p0(1)) +
184  p2(0) * (p0(1) - p1(1)));
185  dist = 2.0 * area / fe_elem->length(nid[0], nid[1]);
186  }
187  else // 3D elems
188  {
189  Point p2 = fe_elem->point(nid[1]);
190  Point p3 = fe_elem->point(nid.back());
191  Point vec0 = p1 - p2;
192  Point vec1 = p1 - p3;
193  Point normal = vec0.cross(vec1);
194  normal /= normal.norm();
195  dist = std::abs(normal(0) * (p0(0) - p1(0)) + normal(1) * (p0(1) - p1(1)) +
196  normal(2) * (p0(2) - p1(2)));
197  }
198  _boundary_node_offset.insert(std::make_pair(id, -dist));
199  }
200 
201  _pdnode_coord[id] = fe_elem->centroid();
202  _pdnode_avg_spacing[id] = dist_sum / n_fe_neighbors;
203  _pdnode_horiz_rad[id] = (_has_horiz_num ? _horiz_num * dist_sum / n_fe_neighbors : _horiz_rad);
204  _pdnode_vol[id] = fe_elem->volume();
205  _pdnode_horiz_vol[id] = 0.0;
206  _pdnode_blockID[id] = fe_elem->subdomain_id() + 1000; // set new subdomain id for PD mesh in
207  // case FE mesh is retained
208  _pdnode_elemID[id] = fe_elem->id();
209 
210  ++id;
211  }
212 
213  // search node neighbors and create other nodal data
214  createNodeHorizBasedData(connect_block_id_pairs, non_connect_block_id_pairs);
215 
216  createNeighborHorizonBasedData(); // applies to non-ordinary state-based model only.
217 
218  // total number of peridynamic bonds
219  _n_pdbonds = 0;
220  for (unsigned int i = 0; i < _n_pdnodes; ++i)
221  _n_pdbonds += _pdnode_neighbors[i].size();
222  _n_pdbonds /= 2;
223 
224  unsigned int k = 0;
225  for (unsigned int i = 0; i < _n_pdnodes; ++i)
226  for (unsigned int j = 0; j < _pdnode_neighbors[i].size(); ++j)
227  if (_pdnode_neighbors[i][j] > i)
228  {
229  // build the bond list for each node
230  _pdnode_bonds[i].push_back(k);
231  _pdnode_bonds[_pdnode_neighbors[i][j]].push_back(k);
232  ++k;
233  }
234 }
235 
236 void
238  std::multimap<SubdomainID, SubdomainID> connect_block_id_pairs,
239  std::multimap<SubdomainID, SubdomainID> non_connect_block_id_pairs)
240 {
241  // search neighbors
242  for (unsigned int i = 0; i < _n_pdnodes; ++i)
243  {
244  Real dis = 0.0;
245  for (unsigned int j = 0; j < _n_pdnodes; ++j)
246  {
247  dis = (_pdnode_coord[i] - _pdnode_coord[j]).norm();
248  if (dis <= 1.0001 * _pdnode_horiz_rad[i] && j != i)
249  {
250  bool is_interface = false;
251  if (!connect_block_id_pairs.empty())
252  is_interface =
253  checkInterface(_pdnode_blockID[i], _pdnode_blockID[j], connect_block_id_pairs);
254 
255  if (!non_connect_block_id_pairs.empty())
256  is_interface =
257  !checkInterface(_pdnode_blockID[i], _pdnode_blockID[j], non_connect_block_id_pairs);
258 
259  if (_pdnode_blockID[i] == _pdnode_blockID[j] || is_interface)
260  {
261  // check whether pdnode i falls in the region whose bonds may need to be removed due to
262  // the pre-existing cracks
263  bool intersect = false;
264  for (unsigned int k = 0; k < _cracks_start.size(); ++k)
265  {
267  _cracks_start[k],
268  _cracks_end[k],
269  _cracks_width[k] + 4.0 * _pdnode_horiz_rad[i],
270  4.0 * _pdnode_horiz_rad[i]))
271  intersect = intersect || checkCrackIntersectBond(_cracks_start[k],
272  _cracks_end[k],
273  _cracks_width[k],
274  _pdnode_coord[i],
275  _pdnode_coord[j]);
276  }
277  // remove bonds cross the crack to form crack surface
278  if (!intersect)
279  {
280  // Use the addition balance scheme to remove unbalanced interactions
281  // check whether j was already considered as a neighbor of i, if not, add j to i's
282  // neighborlist
283  if (std::find(_pdnode_neighbors[i].begin(), _pdnode_neighbors[i].end(), j) ==
284  _pdnode_neighbors[i].end())
285  {
286  _pdnode_neighbors[i].push_back(j);
288  }
289  // check whether i was also considered as a neighbor of j, if not, add i to j's
290  // neighborlist
291  if (std::find(_pdnode_neighbors[j].begin(), _pdnode_neighbors[j].end(), i) ==
292  _pdnode_neighbors[j].end())
293  {
294  _pdnode_neighbors[j].push_back(i);
296  }
297  }
298  }
299  }
300  }
301  }
302 }
303 
304 bool
305 PeridynamicsMesh::checkInterface(SubdomainID pdnode_blockID_i,
306  SubdomainID pdnode_blockID_j,
307  std::multimap<SubdomainID, SubdomainID> blockID_pairs)
308 {
309  bool is_interface = false;
310  std::pair<std::multimap<SubdomainID, SubdomainID>::iterator,
311  std::multimap<SubdomainID, SubdomainID>::iterator>
312  ret;
313  // check existence of the case when i is the key and j is the value
314  ret = blockID_pairs.equal_range(pdnode_blockID_i);
315  for (std::multimap<SubdomainID, SubdomainID>::iterator it = ret.first; it != ret.second; ++it)
316  if (pdnode_blockID_j == it->second)
317  is_interface = true;
318 
319  // check existence of the case when j is the key and i is the value
320  ret = blockID_pairs.equal_range(pdnode_blockID_j);
321  for (std::multimap<SubdomainID, SubdomainID>::iterator it = ret.first; it != ret.second; ++it)
322  if (pdnode_blockID_i == it->second)
323  is_interface = true;
324 
325  return is_interface;
326 }
327 
328 void
330 {
331  for (unsigned int i = 0; i < _n_pdnodes; ++i)
332  {
333  std::vector<dof_id_type> n_pd_neighbors = _pdnode_neighbors[i];
334  _dg_neighbors[i].resize(n_pd_neighbors.size());
335  _dg_vol_frac[i].resize(n_pd_neighbors.size());
336  Real dg_vol_sum = 0.0;
337  std::vector<Real> dg_vol(n_pd_neighbors.size(), 0.0);
338  for (unsigned int j = 0; j < n_pd_neighbors.size(); ++j)
339  for (unsigned int k = j; k < n_pd_neighbors.size(); ++k) // only search greater number index
340  if ((_pdnode_coord[n_pd_neighbors[j]] - _pdnode_coord[n_pd_neighbors[k]]).norm() <=
342  {
343  // only save the corresponding index in neighbor list, rather than the actual node id
344  // for neighbor j
345  _dg_neighbors[i][j].push_back(k);
346  dg_vol[j] += _pdnode_vol[n_pd_neighbors[k]];
347  dg_vol_sum += _pdnode_vol[n_pd_neighbors[k]];
348  // for neighbor k
349  if (k > j)
350  {
351  _dg_neighbors[i][k].push_back(j);
352  dg_vol[k] += _pdnode_vol[n_pd_neighbors[j]];
353  dg_vol_sum += _pdnode_vol[n_pd_neighbors[j]];
354  }
355  }
356  for (unsigned int j = 0; j < n_pd_neighbors.size(); ++j)
357  _dg_vol_frac[i][j] = dg_vol[j] / dg_vol_sum;
358  }
359 }
360 
361 std::vector<dof_id_type>
362 PeridynamicsMesh::getNeighbors(dof_id_type node_id)
363 {
364  return _pdnode_neighbors[node_id];
365 }
366 
367 dof_id_type
368 PeridynamicsMesh::getNeighborIndex(dof_id_type node_i, dof_id_type node_j)
369 {
370  std::vector<dof_id_type> n_pd_neighbors = _pdnode_neighbors[node_i];
371  auto it = std::find(n_pd_neighbors.begin(), n_pd_neighbors.end(), node_j);
372  if (it != n_pd_neighbors.end())
373  return it - n_pd_neighbors.begin();
374  else
375  mooseError(
376  "Material point ", node_j, " is not in the neighbor list of material point ", node_i);
377 
378  return -1;
379 }
380 
381 std::vector<dof_id_type>
382 PeridynamicsMesh::getBonds(dof_id_type node_id)
383 {
384  if (node_id > _n_pdnodes)
385  mooseError("Querying node ID exceeds the available PD node IDs!");
386 
387  return _pdnode_bonds[node_id];
388 }
389 
390 std::vector<dof_id_type>
391 PeridynamicsMesh::getDefGradNeighbors(dof_id_type node_id, unsigned int neighbor_id)
392 {
393  if (node_id > _n_pdnodes)
394  mooseError("Querying node ID exceeds the available PD node IDs!");
395 
396  std::vector<dof_id_type> dg_neighbors = _dg_neighbors[node_id][neighbor_id];
397  if (dg_neighbors.size() < _dim)
398  mooseError("Not enough number of neighbors to calculate deformation gradient at PD node: ",
399  node_id);
400 
401  return dg_neighbors;
402 }
403 
404 SubdomainID
406 {
407  if (node_id > _n_pdnodes)
408  mooseError("Querying node ID exceeds the available PD node IDs!");
409 
410  return _pdnode_blockID[node_id];
411 }
412 
413 void
415 {
416  _pdnode_blockID.assign(_n_pdnodes, id);
417 }
418 
419 Point
421 {
422  if (node_id > _n_pdnodes)
423  mooseError("Querying node ID exceeds the available PD node IDs!");
424 
425  return _pdnode_coord[node_id];
426 }
427 
428 std::vector<dof_id_type>
430 {
431  return _pdnode_elemID;
432 }
433 
434 Real
436 {
437  if (node_id > _n_pdnodes)
438  mooseError("Querying node ID exceeds the available PD node IDs!");
439 
440  return _pdnode_vol[node_id];
441 }
442 
443 Real
445 {
446  if (node_id > _n_pdnodes)
447  mooseError("Querying node ID exceeds the available PD node IDs!");
448 
449  return _pdnode_horiz_vol[node_id];
450 }
451 
452 Real
453 PeridynamicsMesh::getDefGradVolFraction(dof_id_type node_id, dof_id_type neighbor_id)
454 {
455  if (node_id > _n_pdnodes)
456  mooseError("Querying node ID exceeds the available PD node IDs!");
457 
458  return _dg_vol_frac[node_id][neighbor_id];
459 }
460 
461 Real
463 {
464  if (node_id > _n_pdnodes)
465  mooseError("Querying node ID exceeds the available PD node IDs!");
466 
467  return _pdnode_avg_spacing[node_id];
468 }
469 
470 Real
471 PeridynamicsMesh::getHorizon(dof_id_type node_id)
472 {
473  if (node_id > _n_pdnodes)
474  mooseError("Querying node ID exceeds the available PD node IDs!");
475 
476  return _pdnode_horiz_rad[node_id];
477 }
478 
479 Real
481 {
482  if (_boundary_node_offset.count(node_id))
483  return _boundary_node_offset[node_id];
484  else
485  return 0.0;
486 }
487 
488 bool
490  Point point, Point rec_p1, Point rec_p2, Real rec_height, Real tol)
491 {
492  Real crack_length = (rec_p2 - rec_p1).norm();
493  bool inside = crack_length;
494 
495  if (inside)
496  {
497  Real a = rec_p2(1) - rec_p1(1);
498  Real b = rec_p1(0) - rec_p2(0);
499  Real c = rec_p2(0) * rec_p1(1) - rec_p2(1) * rec_p1(0);
500  inside *= std::abs(a * point(0) + b * point(1) + c) / crack_length < rec_height / 2.0;
501 
502  a = rec_p2(0) - rec_p1(0);
503  b = rec_p2(1) - rec_p1(1);
504  c = 0.5 * (rec_p1(1) * rec_p1(1) - rec_p2(1) * rec_p2(1) - rec_p2(0) * rec_p2(0) +
505  rec_p1(0) * rec_p1(0));
506  inside *= std::abs(a * point(0) + b * point(1) + c) / crack_length < (tol + crack_length) / 2.0;
507  }
508 
509  return inside;
510 }
511 
512 bool
514  Point crack_p1, Point crack_p2, Real crack_width, Point bond_p1, Point bond_p2)
515 {
516  bool intersect0 = false;
517  bool intersect1 = false;
518  bool intersect2 = false;
519  if ((crack_p2 - crack_p1).norm())
520  {
521  intersect0 = checkSegmentIntersectSegment(crack_p1, crack_p2, bond_p1, bond_p2);
522  if (crack_width != 0.)
523  {
524  Real crack_len = (crack_p1 - crack_p2).norm();
525  Real cos_crack = (crack_p2(0) - crack_p1(0)) / crack_len;
526  Real sin_crack = (crack_p2(1) - crack_p1(1)) / crack_len;
527  Real new_crack_p1x = crack_p1(0) - crack_width / 2.0 * sin_crack;
528  Real new_crack_p1y = crack_p1(1) + crack_width / 2.0 * cos_crack;
529  Real new_crack_p2x = crack_p2(0) - crack_width / 2.0 * sin_crack;
530  Real new_crack_p2y = crack_p2(1) + crack_width / 2.0 * cos_crack;
531  Point new_crack_p1 = Point(new_crack_p1x, new_crack_p1y, 0.);
532  Point new_crack_p2 = Point(new_crack_p2x, new_crack_p2y, 0.);
533  intersect1 = checkSegmentIntersectSegment(new_crack_p1, new_crack_p2, bond_p1, bond_p2);
534  new_crack_p1x = crack_p1(0) + crack_width / 2.0 * sin_crack;
535  new_crack_p1y = crack_p1(1) - crack_width / 2.0 * cos_crack;
536  new_crack_p2x = crack_p2(0) + crack_width / 2.0 * sin_crack;
537  new_crack_p2y = crack_p2(1) - crack_width / 2.0 * cos_crack;
538  new_crack_p1 = Point(new_crack_p1x, new_crack_p1y, 0.);
539  new_crack_p2 = Point(new_crack_p2x, new_crack_p2y, 0.);
540  intersect2 = checkSegmentIntersectSegment(new_crack_p1, new_crack_p2, bond_p1, bond_p2);
541  }
542  }
543 
544  return intersect0 || intersect1 || intersect2;
545 }
546 
547 bool
549  Point seg1_p2,
550  Point seg2_p1,
551  Point seg2_p2)
552 {
553  // Fail if the segments share an end-point
554  if ((seg1_p1(0) == seg2_p1(0) && seg1_p1(1) == seg2_p1(1)) ||
555  (seg1_p2(0) == seg2_p1(0) && seg1_p2(1) == seg2_p1(1)) ||
556  (seg1_p1(0) == seg2_p2(0) && seg1_p1(1) == seg2_p2(1)) ||
557  (seg1_p2(0) == seg2_p2(0) && seg1_p2(1) == seg2_p2(1)))
558  {
559  return false;
560  }
561 
562  // Fail if the segments intersect at a given end-point but not normal to the crack
563  if ((seg1_p1(1) - seg1_p2(1)) / (seg1_p1(0) - seg1_p2(0)) ==
564  (seg1_p1(1) - seg2_p1(1)) / (seg1_p1(0) - seg2_p1(0)) ||
565  (seg1_p1(1) - seg1_p2(1)) / (seg1_p1(0) - seg1_p2(0)) ==
566  (seg1_p1(1) - seg2_p2(1)) / (seg1_p1(0) - seg2_p2(0)) ||
567  (seg2_p1(1) - seg2_p2(1)) / (seg2_p1(0) - seg2_p2(0)) ==
568  (seg2_p1(1) - seg1_p1(1)) / (seg2_p1(0) - seg1_p1(0)) ||
569  (seg2_p1(1) - seg2_p2(1)) / (seg2_p1(0) - seg2_p2(0)) ==
570  (seg2_p1(1) - seg1_p2(1)) / (seg2_p1(0) - seg1_p2(0)))
571  {
572  Real COSseg1_seg2 = (seg1_p2 - seg1_p1) * (seg2_p2 - seg2_p1) /
573  ((seg1_p2 - seg1_p1).norm() * (seg2_p2 - seg2_p1).norm());
574  if (COSseg1_seg2 > -0.08715574 && COSseg1_seg2 < 0.08715574)
575  return false;
576  }
577 
578  // Translate the system so that point seg1_p1 is on the origin
579  seg1_p2(0) -= seg1_p1(0);
580  seg1_p2(1) -= seg1_p1(1);
581  seg2_p1(0) -= seg1_p1(0);
582  seg2_p1(1) -= seg1_p1(1);
583  seg2_p2(0) -= seg1_p1(0);
584  seg2_p2(1) -= seg1_p1(1);
585 
586  // Length of segment seg1_p1-seg1_p2
587  Real seg1_len = seg1_p2.norm();
588 
589  // Rotate the system so that point seg1_p2 is on the positive X axis
590  Real cos_seg1 = seg1_p2(0) / seg1_len;
591  Real sin_seg1 = seg1_p2(1) / seg1_len;
592  Real newX = seg2_p1(0) * cos_seg1 + seg2_p1(1) * sin_seg1;
593  seg2_p1(1) = seg2_p1(1) * cos_seg1 - seg2_p1(0) * sin_seg1;
594  seg2_p1(0) = newX;
595  newX = seg2_p2(0) * cos_seg1 + seg2_p2(1) * sin_seg1;
596  seg2_p2(1) = seg2_p2(1) * cos_seg1 - seg2_p2(0) * sin_seg1;
597  seg2_p2(0) = newX;
598 
599  // Fail if segment seg2_p1-seg2_p2 doesn't cross segment seg1_p1-seg1_p2
600  if ((seg2_p1(1) < 0. && seg2_p2(1) < 0.) || (seg2_p1(1) >= 0. && seg2_p2(1) >= 0.))
601  return false;
602 
603  // Fail if segment seg2_p1-seg2_p2 crosses segment seg1_p1-seg1_p2 outside of segment
604  // seg1_p1-seg1_p2
605  Real seg1_pos = seg2_p2(0) + (seg2_p1(0) - seg2_p2(0)) * seg2_p2(1) / (seg2_p2(1) - seg2_p1(1));
606  if (seg1_pos < 0. || seg1_pos > seg1_len)
607  return false;
608 
609  return true;
610 }
PeridynamicsMesh::_dim
unsigned int & _dim
Mesh dimension.
Definition: PeridynamicsMesh.h:180
PeridynamicsMesh::getPDNodeIDToFiniteElemIDMap
std::vector< dof_id_type > getPDNodeIDToFiniteElemIDMap()
Function to return the correspondence between PD node IDs and FE element IDs.
Definition: PeridynamicsMesh.C:429
PeridynamicsMesh::getNodeBlockID
SubdomainID getNodeBlockID(dof_id_type node_id)
Function to return block ID for node node_id.
Definition: PeridynamicsMesh.C:405
PeridynamicsMesh::getPDNodeVolume
Real getPDNodeVolume(dof_id_type node_id)
Function to return nodal volume for node node_id.
Definition: PeridynamicsMesh.C:435
PeridynamicsMesh::checkPointInsideRectangle
bool checkPointInsideRectangle(Point point, Point rec_p1, Point rec_p2, Real rec_height, Real tol=0)
Function to check whether a material point falls within a given rectangular crack geometry.
Definition: PeridynamicsMesh.C:489
PeridynamicsMesh::PeridynamicsMesh
PeridynamicsMesh(const InputParameters &parameters)
Definition: PeridynamicsMesh.C:42
PeridynamicsMesh::_pdnode_horiz_rad
std::vector< Real > & _pdnode_horiz_rad
Definition: PeridynamicsMesh.h:191
PeridynamicsMesh::checkCrackIntersectBond
bool checkCrackIntersectBond(Point crack_p1, Point crack_p2, Real crack_width, Point bond_p1, Point bond_p2)
Function to check whether a bond crosses crack surface.
Definition: PeridynamicsMesh.C:513
PeridynamicsMesh::safeClone
virtual std::unique_ptr< MooseMesh > safeClone() const override
Definition: PeridynamicsMesh.C:105
PeridynamicsMesh::_cracks_width
std::vector< Real > _cracks_width
Definition: PeridynamicsMesh.h:176
PeridynamicsMesh::_dg_vol_frac
std::vector< std::vector< Real > > & _dg_vol_frac
Volume fraction of deformation gradient region to its sum at a node.
Definition: PeridynamicsMesh.h:208
PeridynamicsMesh::dimension
virtual unsigned int dimension() const override
Definition: PeridynamicsMesh.C:120
PeridynamicsMesh::_pdnode_avg_spacing
std::vector< Real > & _pdnode_avg_spacing
Definition: PeridynamicsMesh.h:190
PeridynamicsMesh::_pdnode_bonds
std::vector< std::vector< dof_id_type > > & _pdnode_bonds
Bond lists associated with material points.
Definition: PeridynamicsMesh.h:202
PeridynamicsMesh::checkInterface
bool checkInterface(SubdomainID pdnode_blockID_i, SubdomainID pdnode_blockID_j, std::multimap< SubdomainID, SubdomainID > blockID_pairs)
Function to check existence of interface between two blocks.
Definition: PeridynamicsMesh.C:305
PeridynamicsMesh::_dg_neighbors
std::vector< std::vector< std::vector< dof_id_type > > > & _dg_neighbors
Neighbor lists for deformation gradient calculation using bond-associated horizon.
Definition: PeridynamicsMesh.h:205
PeridynamicsMesh::_pdnode_horiz_vol
std::vector< Real > & _pdnode_horiz_vol
Definition: PeridynamicsMesh.h:193
PeridynamicsMesh::createPeridynamicsMeshData
void createPeridynamicsMeshData(MeshBase &fe_mesh, std::set< dof_id_type > converted_elem_id, std::multimap< SubdomainID, SubdomainID > connect_block_id_pairs, std::multimap< SubdomainID, SubdomainID > non_connect_block_id_pairs)
Function to assign values to member variables (PD mesh data) of this class this function will be call...
Definition: PeridynamicsMesh.C:138
PeridynamicsMesh::getBoundaryOffset
Real getBoundaryOffset(dof_id_type node_id)
Function to return offset for boundary nodes.
Definition: PeridynamicsMesh.C:480
PeridynamicsMesh.h
PeridynamicsMesh
Peridynamics mesh class.
Definition: PeridynamicsMesh.h:25
PeridynamicsMesh::_pdnode_neighbors
std::vector< std::vector< dof_id_type > > & _pdnode_neighbors
Neighbor lists for each material point determined using the horizon.
Definition: PeridynamicsMesh.h:199
PeridynamicsMesh::setNodeBlockID
void setNodeBlockID(SubdomainID id)
Function to set block ID for all PD nodes.
Definition: PeridynamicsMesh.C:414
PeridynamicsMesh::createNodeHorizBasedData
void createNodeHorizBasedData(std::multimap< SubdomainID, SubdomainID > connect_block_id_pairs, std::multimap< SubdomainID, SubdomainID > non_connect_block_id_pairs)
Function to create neighbors and other data for each material point with given horizon.
Definition: PeridynamicsMesh.C:237
PeridynamicsMesh::nPDBonds
dof_id_type nPDBonds() const
Function to return number of PD Edge elements.
Definition: PeridynamicsMesh.C:132
tol
const double tol
Definition: Setup.h:18
registerMooseObject
registerMooseObject("PeridynamicsApp", PeridynamicsMesh)
PeridynamicsMesh::_horiz_num
const Real _horiz_num
Definition: PeridynamicsMesh.h:168
PeridynamicsMesh::getPDNodeCoord
Point getPDNodeCoord(dof_id_type node_id)
Function to return coordinates for node node_id.
Definition: PeridynamicsMesh.C:420
PeridynamicsMesh::_pdnode_vol
std::vector< Real > & _pdnode_vol
Definition: PeridynamicsMesh.h:192
PeridynamicsMesh::_boundary_node_offset
std::map< dof_id_type, Real > & _boundary_node_offset
Offset of each boundary node to its original FE element boundary edge or face.
Definition: PeridynamicsMesh.h:211
PeridynamicsMesh::_cracks_start
std::vector< Point > _cracks_start
Definition: PeridynamicsMesh.h:174
PeridynamicsMesh::getNeighbors
std::vector< dof_id_type > getNeighbors(dof_id_type node_id)
Function to return neighbor nodes indices for node node_id.
Definition: PeridynamicsMesh.C:362
PeridynamicsMesh::getHorizon
Real getHorizon(dof_id_type node_id)
Function to return horizon size.
Definition: PeridynamicsMesh.C:471
PeridynamicsMesh::_has_cracks
const bool _has_cracks
Information for crack generation.
Definition: PeridynamicsMesh.h:173
PeridynamicsMesh::_cracks_end
std::vector< Point > _cracks_end
Definition: PeridynamicsMesh.h:175
PeridynamicsMesh::checkSegmentIntersectSegment
bool checkSegmentIntersectSegment(Point seg1_p1, Point seg1_p2, Point seg2_p1, Point seg2_p2)
Function to check whether a segment crosses another segment.
Definition: PeridynamicsMesh.C:548
PeridynamicsMesh::getHorizVolume
Real getHorizVolume(dof_id_type node_id)
Function to return summation of neighbor nodal volumes for node node_id.
Definition: PeridynamicsMesh.C:444
PeridynamicsMesh::_pdnode_elemID
std::vector< dof_id_type > & _pdnode_elemID
Definition: PeridynamicsMesh.h:195
PeridynamicsMesh::getBonds
std::vector< dof_id_type > getBonds(dof_id_type node_id)
Function to return the bond number connected with node node_id.
Definition: PeridynamicsMesh.C:382
PeridynamicsMesh::getNeighborIndex
dof_id_type getNeighborIndex(dof_id_type node_i, dof_id_type node_j)
Function to return the local neighbor index of node_j from node_i's neighbor list.
Definition: PeridynamicsMesh.C:368
validParams< PeridynamicsMesh >
InputParameters validParams< PeridynamicsMesh >()
Definition: PeridynamicsMesh.C:18
PeridynamicsMesh::_pdnode_blockID
std::vector< SubdomainID > & _pdnode_blockID
Definition: PeridynamicsMesh.h:194
PeridynamicsMesh::_n_pdbonds
unsigned int & _n_pdbonds
Number of total bonds.
Definition: PeridynamicsMesh.h:186
PeridynamicsMesh::createNeighborHorizonBasedData
void createNeighborHorizonBasedData()
Function to create node neighbors and other data for each material point based on NEIGHBOR_HORIZON ba...
Definition: PeridynamicsMesh.C:329
PeridynamicsMesh::getNodeAvgSpacing
Real getNodeAvgSpacing(dof_id_type node_id)
Function to return the average spacing between node node_id with its most adjacent neighbors.
Definition: PeridynamicsMesh.C:462
PeridynamicsMesh::buildMesh
virtual void buildMesh() override
Definition: PeridynamicsMesh.C:111
PeridynamicsMesh::getDefGradNeighbors
std::vector< dof_id_type > getDefGradNeighbors(dof_id_type node_id, unsigned int neighbor_id)
Function to return indices of neighbors used in formulation of bond-associated deformation gradient f...
Definition: PeridynamicsMesh.C:391
PeridynamicsMesh::_bah_ratio
const Real _bah_ratio
Definition: PeridynamicsMesh.h:169
PeridynamicsMesh::getDefGradVolFraction
Real getDefGradVolFraction(dof_id_type node_id, dof_id_type neighbor_id)
Function to return summation of volumes of bond-associated neighbors used in the deformation gradient...
Definition: PeridynamicsMesh.C:453
PeridynamicsMesh::_n_pdnodes
unsigned int & _n_pdnodes
Number of total material points.
Definition: PeridynamicsMesh.h:183
PeridynamicsMesh::nPDNodes
dof_id_type nPDNodes() const
Function to return number of PD nodes.
Definition: PeridynamicsMesh.C:126
PeridynamicsMesh::_horiz_rad
const Real _horiz_rad
Horizon size control parameters.
Definition: PeridynamicsMesh.h:166
PeridynamicsMesh::_pdnode_coord
std::vector< Point > _pdnode_coord
Data associated with each peridynamics node.
Definition: PeridynamicsMesh.h:189
PeridynamicsMesh::_has_horiz_num
const bool _has_horiz_num
Definition: PeridynamicsMesh.h:167