12 #include "libmesh/elem.h" 20 params.
addClassDescription(
"Mesh class to store and return peridynamics specific mesh data");
22 params.
addParam<
Real>(
"horizon_radius",
"Value of horizon size in terms of radius");
24 "The material points spacing number, i.e. ratio of horizon radius to the " 25 "effective average spacing");
28 "Ratio of bond-associated horizon to nodal horizon. This is the only " 29 "parameters to control the size of bond-associated horizon");
30 params.
addParam<std::vector<Point>>(
"cracks_start",
31 "Cartesian coordinates where predefined line cracks start");
32 params.
addParam<std::vector<Point>>(
"cracks_end",
33 "Cartesian coordinates where predefined line cracks end");
34 params.
addParam<std::vector<Real>>(
"cracks_width",
"Widths of predefined line cracks");
36 params.
set<
bool>(
"_mesh_generator_mesh") =
true;
43 _horizon_radius(isParamValid(
"horizon_radius") ? getParam<
Real>(
"horizon_radius") : 0),
44 _has_horizon_number(isParamValid(
"horizon_number")),
45 _horizon_number(_has_horizon_number ? getParam<
Real>(
"horizon_number") : 0),
46 _bah_ratio(getParam<
Real>(
"bond_associated_horizon_ratio")),
47 _has_cracks(isParamValid(
"cracks_start") || isParamValid(
"cracks_end")),
48 _dim(declareRestartableData<unsigned
int>(
"dim")),
49 _n_pdnodes(declareRestartableData<unsigned
int>(
"n_pdnodes")),
50 _n_pdbonds(declareRestartableData<unsigned
int>(
"n_pdbonds")),
51 _pdnode_average_spacing(declareRestartableData<
std::vector<
Real>>(
"pdnode_average_spacing")),
52 _pdnode_horizon_radius(declareRestartableData<
std::vector<
Real>>(
"pdnode_horizon_radius")),
53 _pdnode_vol(declareRestartableData<
std::vector<
Real>>(
"pdnode_vol")),
54 _pdnode_horizon_vol(declareRestartableData<
std::vector<
Real>>(
"pdnode_horizon_vol")),
55 _pdnode_blockID(declareRestartableData<
std::vector<
SubdomainID>>(
"pdnode_blockID")),
56 _pdnode_elemID(declareRestartableData<
std::vector<
dof_id_type>>(
"pdnode_elemID")),
58 declareRestartableData<
std::vector<
std::vector<
dof_id_type>>>(
"pdnode_neighbors")),
59 _pdnode_bonds(declareRestartableData<
std::vector<
std::vector<
dof_id_type>>>(
"pdnode_bonds")),
62 _pdnode_sub_vol(declareRestartableData<
std::vector<
std::vector<
Real>>>(
"pdnode_sub_vol")),
63 _pdnode_sub_vol_sum(declareRestartableData<
std::vector<
Real>>(
"pdnode_sub_vol_sum")),
64 _boundary_node_offset(
66 _pdnode_weight_normalizer(declareRestartableData<
std::vector<
Real>>(
"pdnode_weight_normalizer"))
69 mooseError(
"Must specify either horizon_radius or horizon_number to determine horizon size in " 75 _cracks_end = getParam<std::vector<Point>>(
"cracks_end");
85 "Number of cracks starting points is NOT the same as number of cracks ending points!");
93 mooseError(
"Number of cracks width is NOT the same as number of cracks!");
105 std::unique_ptr<MooseMesh>
117 _mesh = entry.getSavedMesh(entry.mainMeshGeneratorName());
119 _mesh->allow_renumbering(
false);
120 _mesh->prepare_for_use();
121 _mesh->allow_renumbering(
true);
145 std::set<dof_id_type> converted_elem_id,
146 std::multimap<SubdomainID, SubdomainID> bonding_block_pairs,
147 std::multimap<SubdomainID, SubdomainID> non_bonding_block_pairs)
149 _dim = fe_mesh.mesh_dimension();
169 for (
const auto & eid : converted_elem_id)
171 Elem * fe_elem = fe_mesh.elem_ptr(eid);
173 unsigned int n_fe_neighbors = 0;
175 for (
unsigned int j = 0;
j < fe_elem->n_neighbors(); ++
j)
176 if (fe_elem->neighbor_ptr(
j) !=
nullptr)
178 dist_sum += (fe_elem->vertex_average() - fe_elem->neighbor_ptr(
j)->vertex_average()).
norm();
184 std::vector<unsigned int> nid = fe_elem->nodes_on_side(
j);
185 Point p0 = fe_elem->vertex_average();
186 Point p1 = fe_elem->point(nid[0]);
187 if (fe_elem->dim() == 2)
189 Point p2 = fe_elem->point(nid.back());
190 Real area = 0.5 * std::abs(p0(0) * (p1(1) - p2(1)) + p1(0) * (p2(1) - p0(1)) +
191 p2(0) * (p0(1) - p1(1)));
192 dist = 2.0 * area / fe_elem->length(nid[0], nid[1]);
196 Point p2 = fe_elem->point(nid[1]);
197 Point p3 = fe_elem->point(nid.back());
198 Point vec0 = p1 - p2;
199 Point vec1 = p1 - p3;
200 Point normal = vec0.cross(vec1);
201 normal /= normal.norm();
202 dist = std::abs(normal(0) * (p0(0) - p1(0)) + normal(1) * (p0(1) - p1(1)) +
203 normal(2) * (p0(2) - p1(2)));
247 std::multimap<SubdomainID, SubdomainID> bonding_block_pairs,
248 std::multimap<SubdomainID, SubdomainID> non_bonding_block_pairs)
259 bool is_interface =
false;
260 if (!bonding_block_pairs.empty())
264 if (!non_bonding_block_pairs.empty())
272 bool intersect =
false;
318 std::multimap<SubdomainID, SubdomainID> blockID_pairs)
320 bool is_interface =
false;
321 std::pair<std::multimap<SubdomainID, SubdomainID>::iterator,
322 std::multimap<SubdomainID, SubdomainID>::iterator>
325 ret = blockID_pairs.equal_range(pdnode_blockID_i);
326 for (std::multimap<SubdomainID, SubdomainID>::iterator it = ret.first; it != ret.second; ++it)
327 if (pdnode_blockID_j == it->second)
331 ret = blockID_pairs.equal_range(pdnode_blockID_j);
332 for (std::multimap<SubdomainID, SubdomainID>::iterator it = ret.first; it != ret.second; ++it)
333 if (pdnode_blockID_i == it->second)
348 for (
unsigned int j = 0;
j < n_pd_neighbors.size(); ++
j)
349 for (
unsigned int k =
j;
k < n_pd_neighbors.size(); ++
k)
369 std::vector<dof_id_type>
379 auto it = std::find(n_pd_neighbors.begin(), n_pd_neighbors.end(), node_j);
380 if (it != n_pd_neighbors.end())
381 return it - n_pd_neighbors.begin();
384 "Material point ", node_j,
" is not in the neighbor list of material point ", node_i);
389 std::vector<dof_id_type>
393 mooseError(
"Querying node ID exceeds the available PD node IDs!");
398 std::vector<dof_id_type>
402 mooseError(
"Querying node ID exceeds the available PD node IDs!");
405 mooseError(
"Querying neighbor index exceeds the available neighbors!");
407 std::vector<dof_id_type> dg_neighbors =
_dg_neighbors[node_id][neighbor_id];
408 if (dg_neighbors.size() <
_dim)
409 mooseError(
"Not enough number of neighbors to calculate deformation gradient at PD node: ",
419 mooseError(
"Querying node ID exceeds the available PD node IDs!");
434 mooseError(
"Querying node ID exceeds the available PD node IDs!");
439 std::vector<dof_id_type>
449 mooseError(
"Querying node ID exceeds the available PD node IDs!");
458 mooseError(
"Querying node ID exceeds the available PD node IDs!");
467 mooseError(
"Querying node ID exceeds the available PD node IDs!");
470 mooseError(
"Querying neighbor index exceeds the available neighbors!");
479 mooseError(
"Querying node ID exceeds the available PD node IDs!");
488 mooseError(
"Querying node ID exceeds the available PD node IDs!");
491 mooseError(
"Querying neighbor index exceeds the available neighbors!");
500 mooseError(
"Querying node ID exceeds the available PD node IDs!");
509 mooseError(
"Querying node ID exceeds the available PD node IDs!");
527 mooseError(
"Querying node ID exceeds the available PD node IDs!");
530 mooseError(
"Querying neighbor index exceeds the available neighbors!");
541 Point point, Point rec_p1, Point rec_p2, Real rec_height, Real
tol)
543 Real crack_length = (rec_p2 - rec_p1).
norm();
544 bool inside = crack_length;
548 Real a = rec_p2(1) - rec_p1(1);
549 Real b = rec_p1(0) - rec_p2(0);
550 Real c = rec_p2(0) * rec_p1(1) - rec_p2(1) * rec_p1(0);
552 inside && (std::abs(
a * point(0) +
b * point(1) +
c) / crack_length < rec_height / 2.0);
554 a = rec_p2(0) - rec_p1(0);
555 b = rec_p2(1) - rec_p1(1);
556 c = 0.5 * (rec_p1(1) * rec_p1(1) - rec_p2(1) * rec_p2(1) - rec_p2(0) * rec_p2(0) +
557 rec_p1(0) * rec_p1(0));
558 inside = inside && (std::abs(
a * point(0) +
b * point(1) +
c) / crack_length <
559 (
tol + crack_length) / 2.0);
567 Point crack_p1, Point crack_p2, Real crack_width, Point bond_p1, Point bond_p2)
569 bool intersect0 =
false;
570 bool intersect1 =
false;
571 bool intersect2 =
false;
572 if ((crack_p2 - crack_p1).
norm())
575 if (crack_width != 0.)
577 Real crack_len = (crack_p1 - crack_p2).
norm();
578 Real cos_crack = (crack_p2(0) - crack_p1(0)) / crack_len;
579 Real sin_crack = (crack_p2(1) - crack_p1(1)) / crack_len;
580 Real new_crack_p1x = crack_p1(0) - crack_width / 2.0 * sin_crack;
581 Real new_crack_p1y = crack_p1(1) + crack_width / 2.0 * cos_crack;
582 Real new_crack_p2x = crack_p2(0) - crack_width / 2.0 * sin_crack;
583 Real new_crack_p2y = crack_p2(1) + crack_width / 2.0 * cos_crack;
584 Point new_crack_p1 = Point(new_crack_p1x, new_crack_p1y, 0.);
585 Point new_crack_p2 = Point(new_crack_p2x, new_crack_p2y, 0.);
587 new_crack_p1x = crack_p1(0) + crack_width / 2.0 * sin_crack;
588 new_crack_p1y = crack_p1(1) - crack_width / 2.0 * cos_crack;
589 new_crack_p2x = crack_p2(0) + crack_width / 2.0 * sin_crack;
590 new_crack_p2y = crack_p2(1) - crack_width / 2.0 * cos_crack;
591 new_crack_p1 = Point(new_crack_p1x, new_crack_p1y, 0.);
592 new_crack_p2 = Point(new_crack_p2x, new_crack_p2y, 0.);
597 return intersect0 || intersect1 || intersect2;
607 if ((seg1_p1(0) == seg2_p1(0) && seg1_p1(1) == seg2_p1(1)) ||
608 (seg1_p2(0) == seg2_p1(0) && seg1_p2(1) == seg2_p1(1)) ||
609 (seg1_p1(0) == seg2_p2(0) && seg1_p1(1) == seg2_p2(1)) ||
610 (seg1_p2(0) == seg2_p2(0) && seg1_p2(1) == seg2_p2(1)))
616 if ((seg1_p1(1) - seg1_p2(1)) / (seg1_p1(0) - seg1_p2(0)) ==
617 (seg1_p1(1) - seg2_p1(1)) / (seg1_p1(0) - seg2_p1(0)) ||
618 (seg1_p1(1) - seg1_p2(1)) / (seg1_p1(0) - seg1_p2(0)) ==
619 (seg1_p1(1) - seg2_p2(1)) / (seg1_p1(0) - seg2_p2(0)) ||
620 (seg2_p1(1) - seg2_p2(1)) / (seg2_p1(0) - seg2_p2(0)) ==
621 (seg2_p1(1) - seg1_p1(1)) / (seg2_p1(0) - seg1_p1(0)) ||
622 (seg2_p1(1) - seg2_p2(1)) / (seg2_p1(0) - seg2_p2(0)) ==
623 (seg2_p1(1) - seg1_p2(1)) / (seg2_p1(0) - seg1_p2(0)))
625 Real COSseg1_seg2 = (seg1_p2 - seg1_p1) * (seg2_p2 - seg2_p1) /
626 ((seg1_p2 - seg1_p1).
norm() * (seg2_p2 - seg2_p1).
norm());
627 if (COSseg1_seg2 > -0.08715574 && COSseg1_seg2 < 0.08715574)
632 seg1_p2(0) -= seg1_p1(0);
633 seg1_p2(1) -= seg1_p1(1);
634 seg2_p1(0) -= seg1_p1(0);
635 seg2_p1(1) -= seg1_p1(1);
636 seg2_p2(0) -= seg1_p1(0);
637 seg2_p2(1) -= seg1_p1(1);
640 Real seg1_len = seg1_p2.norm();
643 Real cos_seg1 = seg1_p2(0) / seg1_len;
644 Real sin_seg1 = seg1_p2(1) / seg1_len;
645 Real newX = seg2_p1(0) * cos_seg1 + seg2_p1(1) * sin_seg1;
646 seg2_p1(1) = seg2_p1(1) * cos_seg1 - seg2_p1(0) * sin_seg1;
648 newX = seg2_p2(0) * cos_seg1 + seg2_p2(1) * sin_seg1;
649 seg2_p2(1) = seg2_p2(1) * cos_seg1 - seg2_p2(0) * sin_seg1;
653 if ((seg2_p1(1) < 0. && seg2_p2(1) < 0.) || (seg2_p1(1) >= 0. && seg2_p2(1) >= 0.))
658 Real seg1_pos = seg2_p2(0) + (seg2_p1(0) - seg2_p2(0)) * seg2_p2(1) / (seg2_p2(1) - seg2_p1(1));
659 if (seg1_pos < 0. || seg1_pos > seg1_len)
std::vector< std::vector< dof_id_type > > & _pdnode_neighbors
Neighbor lists for each material point determined using the horizon.
static InputParameters validParams()
std::vector< SubdomainID > & _pdnode_blockID
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.
static InputParameters validParams()
Real getNeighborWeight(dof_id_type node_id, dof_id_type neighbor_id)
Function to return normalized weight for neighbor neighbor_id of node node_id based on predefined wei...
std::vector< dof_id_type > getBondDeformationGradientNeighbors(dof_id_type node_id, dof_id_type neighbor_id)
Function to return indices of neighbors used in formulation of bond-associated deformation gradient f...
dof_id_type nPDBonds() const
Function to return number of PD Edge elements.
void createPeridynamicsMeshData(MeshBase &fe_mesh, std::set< dof_id_type > converted_elem_id, std::multimap< SubdomainID, SubdomainID > bonding_block_pairs, std::multimap< SubdomainID, SubdomainID > non_bonding_block_pairs)
Function to assign values to member variables (PD mesh data) of this class this function will be call...
bool checkSegmentIntersectSegment(Point seg1_p1, Point seg1_p2, Point seg2_p1, Point seg2_p2)
Function to check whether a segment crosses another segment.
Real getBoundaryOffset(dof_id_type node_id)
Function to return offset for boundary nodes.
void createNodeHorizBasedData(std::multimap< SubdomainID, SubdomainID > bonding_block_pairs, std::multimap< SubdomainID, SubdomainID > non_bonding_block_pairs)
Function to create neighbors and other data for each material point with given horizon.
std::vector< Point > _cracks_end
std::vector< dof_id_type > getNeighbors(dof_id_type node_id)
Function to return neighbor nodes indices for node node_id.
std::vector< std::vector< Real > > & _pdnode_sub_vol
Volume of horizon subsets for bond-associated deformation gradients at a node.
unsigned int & _n_pdnodes
Number of total material points.
Real getHorizonSubsetVolumeSum(dof_id_type node_id)
Function to return the summation of all horizon subset volumes for node node_id.
std::vector< Real > & _pdnode_vol
std::vector< Real > & _pdnode_sub_vol_sum
Summation of volumes of all horizon subsets at a node.
std::vector< Real > & _pdnode_average_spacing
std::map< dof_id_type, Real > & _boundary_node_offset
Offset of each boundary node to its original FE element boundary edge or face.
Real getNodeAverageSpacing(dof_id_type node_id)
Function to return the average spacing between node node_id with its most adjacent neighbors...
std::vector< dof_id_type > getPDNodeIDToFEElemIDMap()
Function to return the correspondence between PD node IDs and FE element IDs.
std::vector< dof_id_type > & _pdnode_elemID
std::vector< Point > _pdnode_coord
Data associated with each peridynamics node.
PeridynamicsMesh(const InputParameters ¶meters)
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.
std::unique_ptr< T > copyConstruct(const T &object)
virtual void buildMesh() override
bool isParamValid(const std::string &name) const
void createNeighborHorizonBasedData()
Function to create node neighbors and other data for each material point based on NEIGHBOR_HORIZON ba...
const Real _horizon_number
const Real _horizon_radius
Horizon size control parameters.
const bool _has_cracks
Information for crack generation.
Real getHorizonVolume(dof_id_type node_id)
Function to return summation of neighbor nodal volumes for node node_id.
virtual std::unique_ptr< MooseMesh > safeClone() const override
unsigned int & _dim
Mesh dimension.
std::vector< Real > & _pdnode_horizon_vol
SubdomainID getNodeBlockID(dof_id_type node_id)
Function to return block ID for node node_id.
dof_id_type nPDNodes() const
Function to return number of PD nodes.
Real getHorizonSubsetVolumeFraction(dof_id_type node_id, dof_id_type neighbor_id)
Function to return the volume fraction of a horizon subset used for bond-associated deformation gradi...
std::vector< Real > & _pdnode_horizon_radius
std::vector< Real > & _pdnode_weight_normalizer
normalizer for calculating weighted values at a node from elemental values within its horizon ...
Real getNodeVolume(dof_id_type node_id)
Function to return nodal volume for node node_id.
std::vector< Real > _cracks_width
std::vector< std::vector< dof_id_type > > & _pdnode_bonds
Bond lists associated with material points.
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.
Real getHorizonSubsetVolume(dof_id_type node_id, dof_id_type neighbor_id)
Function to return the volume of a horizon subset for bond-associated deformation gradient calculatio...
std::unique_ptr< libMesh::MeshBase > _mesh
const bool _has_horizon_number
std::vector< std::vector< std::vector< dof_id_type > > > & _dg_neighbors
Neighbor lists for deformation gradient calculation using bond-associated horizon.
void mooseError(Args &&... args) const
virtual unsigned int dimension() const override
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
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.
MeshGeneratorSystem & getMeshGeneratorSystem()
std::vector< dof_id_type > getBonds(dof_id_type node_id)
Function to return the bond number connected with node node_id.
registerMooseObject("PeridynamicsApp", PeridynamicsMesh)
std::vector< Point > _cracks_start
static const std::string k
void ErrorVector unsigned int
unsigned int & _n_pdbonds
Number of total bonds.
void setNodeBlockID(SubdomainID id)
Function to set block ID for all PD nodes.
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...
Real getHorizon(dof_id_type node_id)
Function to return horizon size.