14 #include "libmesh/edge_edge2.h" 15 #include "libmesh/face_tri3.h" 16 #include "libmesh/cell_tet4.h" 27 "The mesh based on which PD mesh will be created");
28 params.
addParam<std::vector<SubdomainID>>(
"blocks_to_pd",
29 "IDs of the FE mesh blocks to be converted to PD mesh");
30 params.
addParam<std::vector<SubdomainID>>(
32 "IDs of the FE mesh blocks to not be converted to PD mesh. This should only be used when the " 33 "number of to-be-converted FE blocks is considerably large.");
35 "retain_fe_mesh",
"Whether to retain the FE mesh or not after conversion into PD mesh");
37 "construct_pd_sidesets",
39 "Whether to construct PD sidesets based on the sidesets in original FE mesh");
40 params.
addParam<std::vector<boundary_id_type>>(
41 "sidesets_to_pd",
"IDs of the FE sidesets to be reconstructed based on converted PD mesh");
42 params.
addParam<std::vector<std::vector<SubdomainID>>>(
43 "bonding_block_pairs",
44 "List of FE block pairs between which inter-block bonds will be created after being " 45 "converted into PD mesh");
46 params.
addParam<std::vector<std::vector<SubdomainID>>>(
47 "non_bonding_block_pairs",
48 "List of FE block pairs between which inter-block bonds will NOT be created after being " 49 "converted into PD mesh");
53 "Whether to merge all converted PD mesh blocks into a single block. This is " 54 "used when all PD blocks have the same properties");
56 "merge_pd_interfacial_blocks",
58 "Whether to merge all PD interfacial mesh blocks into a single block. This is used " 59 "when all PD interfacial blocks have the same properties");
67 _has_blks_to_pd(isParamValid(
"blocks_to_pd")),
68 _has_blks_as_fe(isParamValid(
"blocks_as_fe")),
69 _retain_fe_mesh(getParam<bool>(
"retain_fe_mesh")),
70 _merge_pd_blks(getParam<bool>(
"merge_pd_blocks")),
71 _construct_pd_sideset(getParam<bool>(
"construct_pd_sidesets")),
72 _has_sidesets_to_pd(isParamValid(
"sidesets_to_pd")),
73 _has_bonding_blk_pairs(isParamValid(
"bonding_block_pairs")),
74 _has_non_bonding_blk_pairs(isParamValid(
"non_bonding_block_pairs")),
75 _merge_pd_interfacial_blks(getParam<bool>(
"merge_pd_interfacial_blocks"))
78 mooseError(
"Please specifiy either 'blocks_to_pd' or 'blocks_as_fe'!");
82 std::vector<SubdomainID> ids = getParam<std::vector<SubdomainID>>(
"blocks_as_fe");
83 for (
unsigned int i = 0; i < ids.size(); ++i)
89 std::vector<SubdomainID> ids = getParam<std::vector<SubdomainID>>(
"blocks_to_pd");
90 for (
unsigned int i = 0; i < ids.size(); ++i)
95 mooseError(
"'sidesets_to_pd' is provided without setting " 96 "'construct_pd_sidesets' to 'true'!");
100 std::vector<boundary_id_type> ids = getParam<std::vector<boundary_id_type>>(
"sidesets_to_pd");
101 for (
unsigned int i = 0; i < ids.size(); ++i)
106 mooseError(
"Please specifiy either 'bonding_block_pairs' or " 107 "'non_bonding_block_pairs'!");
112 std::vector<std::vector<SubdomainID>> id_pairs =
113 getParam<std::vector<std::vector<SubdomainID>>>(
"bonding_block_pairs");
115 for (
unsigned int i = 0; i < id_pairs.size(); ++i)
123 std::vector<std::vector<SubdomainID>> id_pairs =
124 getParam<std::vector<std::vector<SubdomainID>>>(
"non_bonding_block_pairs");
126 for (
unsigned int i = 0; i < id_pairs.size(); ++i)
132 std::unique_ptr<MeshBase>
136 std::unique_ptr<MeshBase> old_mesh = std::move(
_input);
140 if (!old_mesh->is_prepared())
141 old_mesh->prepare_for_use();
146 std::set<SubdomainID> all_fe_blks;
147 for (
const auto & old_elem : old_mesh->element_ptr_range())
148 all_fe_blks.insert(old_elem->subdomain_id());
153 if (!all_fe_blks.count(blkit))
154 mooseError(
"Block ID ", blkit,
" in the 'blocks_to_pd' does not exist in the FE mesh!");
158 if (!all_fe_blks.count(blkit))
159 mooseError(
"Block ID ", blkit,
" in the 'blocks_as_fe' does not exist in the FE mesh!");
163 const unsigned int max_fe_blk_id = *all_fe_blks.rbegin();
167 std::set_difference(all_fe_blks.begin(),
173 std::set_difference(all_fe_blks.begin(),
188 " in the 'bonding_block_pairs' does not exist in the FE mesh!");
192 " in the 'bonding_block_pairs' does not exist in the FE mesh!");
196 " in the 'bonding_block_pairs' is a FE mesh block!");
200 " in the 'bonding_block_pairs' is a FE mesh block!");
210 " in the 'non_bonding_block_pairs' does not exist in the FE mesh!");
214 " in the 'non_bonding_block_pairs' does not exist in the FE mesh!");
218 " in the 'non_bonding_block_pairs' is a FE mesh block!");
222 " in the 'non_bonding_block_pairs' is a FE mesh block!");
227 const unsigned int min_converted_fe_blk_id = *
_blks_to_pd.begin();
230 std::set<dof_id_type> elems_to_pd;
232 std::set<dof_id_type> fe_nodes;
233 std::set<dof_id_type> fe_elems;
234 for (
const auto & old_elem : old_mesh->element_ptr_range())
237 elems_to_pd.insert(old_elem->id());
240 fe_elems.insert(old_elem->id());
241 for (
unsigned int i = 0; i < old_elem->n_nodes(); ++i)
242 fe_nodes.insert(old_elem->node_id(i));
247 fe_elems.insert(old_elem->id());
248 for (
unsigned int i = 0; i < old_elem->n_nodes(); ++i)
249 fe_nodes.insert(old_elem->node_id(i));
259 BoundaryInfo & old_boundary_info = old_mesh->get_boundary_info();
260 const std::set<boundary_id_type> & all_fe_sidesets = old_boundary_info.get_side_boundary_ids();
266 if (!all_fe_sidesets.count(
sideset))
269 " in the 'sidesets_to_pd' does not exist in the finite " 278 std::map<boundary_id_type, std::set<dof_id_type>> fe_bid_eid;
279 auto fe_sbc_tuples = old_boundary_info.build_side_list();
281 for (
const auto & sbct : fe_sbc_tuples)
285 fe_bid_eid[std::get<2>(sbct)].insert(std::get<0>(sbct));
304 new_mesh->set_mesh_dimension(old_mesh->mesh_dimension());
305 new_mesh->set_spatial_dimension(old_mesh->spatial_dimension());
307 new_mesh->reserve_nodes(n_pd_nodes + n_fe_nodes);
308 new_mesh->reserve_elem(n_pd_bonds + n_fe_elems + n_phantom_elems);
310 BoundaryInfo & new_boundary_info = new_mesh->get_boundary_info();
315 unsigned int new_node_id = 0;
317 std::map<dof_id_type, dof_id_type> fe_elem_pd_node_map;
318 for (
const auto & eid : elems_to_pd)
320 new_mesh->add_point(old_mesh->elem_ptr(eid)->vertex_average(), new_node_id);
321 fe_elem_pd_node_map.insert(std::make_pair(eid, new_node_id));
327 std::map<dof_id_type, dof_id_type> fe_nodes_map;
328 for (
const auto & nid : fe_nodes)
330 new_mesh->add_point(*old_mesh->node_ptr(nid), new_node_id);
331 fe_nodes_map.insert(std::make_pair(old_mesh->node_ptr(nid)->id(), new_node_id));
339 unsigned int new_elem_id = 0;
340 for (
unsigned int i = 0; i < n_pd_nodes; ++i)
342 std::vector<dof_id_type> pd_node_neighbors = pd_mesh.
getNeighbors(i);
343 for (
unsigned int j = 0;
j < pd_node_neighbors.size(); ++
j)
344 if (pd_node_neighbors[
j] > i)
348 Elem * new_elem =
new Edge2;
349 new_elem->set_id(new_elem_id);
354 new_elem->subdomain_id() = bid_i;
359 new_elem->subdomain_id() = bid_i + bid_j;
361 new_elem = new_mesh->add_elem(new_elem);
362 new_elem->set_node(0, new_mesh->node_ptr(i));
363 new_elem->set_node(1, new_mesh->node_ptr(pd_node_neighbors[
j]));
373 std::map<std::pair<dof_id_type, dof_id_type>, std::set<dof_id_type>> elem_edge_nodes;
378 for (
const auto & eidit : fe_bid_eid[bidit])
380 bool should_add =
false;
381 Elem * old_elem = old_mesh->elem_ptr(eidit);
383 old_elem->subdomain_id()))
385 std::vector<dof_id_type> pd_nodes;
386 Point p0, p1, p2, p3;
388 if (old_elem->dim() == 2)
392 pd_nodes[0] = fe_elem_pd_node_map.at(eidit);
393 p0 = *new_mesh->node_ptr(pd_nodes[0]);
396 if (old_elem->n_nodes() == 3 ||
397 old_elem->n_nodes() == 6)
400 bool has_neighbor_on_boundary =
false;
401 for (
unsigned int i = 0; i < old_elem->n_neighbors(); ++i)
403 Elem * nb = old_elem->neighbor_ptr(i);
406 if (fe_bid_eid[bidit].count(nb->id()))
408 has_neighbor_on_boundary =
true;
409 pd_nodes[1] = fe_elem_pd_node_map.at(nb->id());
410 p1 = *new_mesh->node_ptr(pd_nodes[1]);
414 pd_nodes[2] = fe_elem_pd_node_map.at(nb->id());
415 p2 = *new_mesh->node_ptr(pd_nodes[2]);
420 if (has_neighbor_on_boundary &&
421 (p1(1) - p0(1)) * (p2(0) - p1(0)) - (p1(0) - p0(0)) * (p2(1) - p1(1)) < 0)
427 for (
unsigned int i = 0; i < old_elem->n_neighbors(); ++i)
429 Elem * nb = old_elem->neighbor_ptr(i);
433 p2 = *new_mesh->node_ptr(fe_elem_pd_node_map.at(nb->id()));
435 for (
unsigned int j = 0;
j < nb->n_neighbors(); ++
j)
437 Elem * nb_nb = nb->neighbor_ptr(
j);
439 if (nb_nb !=
nullptr && fe_bid_eid[bidit].count(nb_nb->id()) &&
440 nb_nb->id() != eidit)
442 p1 = *new_mesh->node_ptr(fe_elem_pd_node_map.at(nb_nb->id()));
445 if ((p1(1) - p0(1)) * (p2(0) - p1(0)) - (p1(0) - p0(0)) * (p2(1) - p1(1)) <
449 pd_nodes[1] = fe_elem_pd_node_map.at(nb_nb->id());
450 pd_nodes[2] = fe_elem_pd_node_map.at(nb->id());
459 for (
unsigned int i = 0; i < old_elem->n_neighbors(); ++i)
461 Elem * nb = old_elem->neighbor_ptr(i);
465 p2 = *new_mesh->node_ptr(fe_elem_pd_node_map.at(nb->id()));
467 for (
unsigned int j = 0;
j < nb->n_neighbors(); ++
j)
469 Elem * nb_nb = nb->neighbor_ptr(
j);
470 if (nb_nb !=
nullptr && nb_nb->id() != eidit)
472 for (
unsigned int k = 0;
k < nb_nb->n_neighbors(); ++
k)
474 Elem * nb_nb_nb = nb_nb->neighbor_ptr(
k);
476 if (nb_nb_nb !=
nullptr &&
477 fe_bid_eid[bidit].count(nb_nb_nb->id()) &&
478 nb_nb_nb->id() != eidit)
480 p1 = *new_mesh->node_ptr(fe_elem_pd_node_map.at(nb_nb_nb->id()));
484 if ((p1(1) - p0(1)) * (p2(0) - p1(0)) -
485 (p1(0) - p0(0)) * (p2(1) - p1(1)) <
489 pd_nodes[1] = fe_elem_pd_node_map.at(nb_nb_nb->id());
490 pd_nodes[2] = fe_elem_pd_node_map.at(nb->id());
503 else if (old_elem->n_nodes() == 4 || old_elem->n_nodes() == 8 ||
504 old_elem->n_nodes() ==
507 std::vector<dof_id_type> pd_boundary_node_ids;
508 for (
unsigned int i = 0; i < old_elem->n_neighbors(); ++i)
510 Elem * nb = old_elem->neighbor_ptr(i);
511 if (nb !=
nullptr && fe_bid_eid[bidit].count(nb->id()))
512 pd_boundary_node_ids.push_back(fe_elem_pd_node_map.at(nb->id()));
515 pd_nodes[2] = fe_elem_pd_node_map.at(
517 ->neighbor_ptr(old_elem->opposite_side(
518 old_boundary_info.side_with_boundary_id(old_elem, bidit)))
520 p2 = *new_mesh->node_ptr(pd_nodes[2]);
524 for (
unsigned int i = 0; i < pd_boundary_node_ids.size(); ++i)
526 p1 = *new_mesh->node_ptr(pd_boundary_node_ids[i]);
529 if ((p1(1) - p0(1)) * (p2(0) - p1(0)) - (p1(0) - p0(0)) * (p2(1) - p1(1)) < 0)
532 pd_nodes[1] = pd_boundary_node_ids[i];
539 " is not supported for PD sideset construction!");
543 Elem * new_elem =
new Tri3;
544 new_elem->set_id(new_elem_id);
549 new_elem = new_mesh->add_elem(new_elem);
550 new_elem->set_node(0, new_mesh->node_ptr(pd_nodes[0]));
551 new_elem->set_node(1, new_mesh->node_ptr(pd_nodes[1]));
552 new_elem->set_node(2, new_mesh->node_ptr(pd_nodes[2]));
557 if (old_boundary_info.get_sideset_name(bidit) !=
"")
559 "pd_side_" + old_boundary_info.get_sideset_name(bidit);
562 else if (old_elem->dim() == 3)
565 pd_nodes[0] = fe_elem_pd_node_map.at(eidit);
566 p0 = *new_mesh->node_ptr(pd_nodes[0]);
568 if (old_elem->n_nodes() == 4 ||
569 old_elem->n_nodes() == 10)
572 mooseError(
"Peridynamics sideset generation does not accept tetrahedral elements!");
574 else if (old_elem->n_nodes() == 8 || old_elem->n_nodes() == 20 ||
575 old_elem->n_nodes() ==
578 std::vector<dof_id_type> boundary_elem_ids;
579 for (
unsigned int i = 0; i < old_elem->n_neighbors(); ++i)
581 Elem * nb = old_elem->neighbor_ptr(i);
582 if (nb !=
nullptr && fe_bid_eid[bidit].count(nb->id()))
583 boundary_elem_ids.push_back(nb->id());
587 pd_nodes[3] = fe_elem_pd_node_map.at(
589 ->neighbor_ptr(old_elem->opposite_side(
590 old_boundary_info.side_with_boundary_id(old_elem, bidit)))
592 p3 = *new_mesh->node_ptr(pd_nodes[3]);
596 for (
unsigned int i = 0; i < boundary_elem_ids.size(); ++i)
598 Elem * nb_i = old_mesh->elem_ptr(boundary_elem_ids[i]);
599 p1 = *new_mesh->node_ptr(fe_elem_pd_node_map.at(boundary_elem_ids[i]));
601 for (
unsigned int j = i + 1;
j < boundary_elem_ids.size(); ++
j)
603 Elem * nb_j = old_mesh->elem_ptr(boundary_elem_ids[
j]);
604 p2 = *new_mesh->node_ptr(fe_elem_pd_node_map.at(boundary_elem_ids[
j]));
606 if (old_elem->which_neighbor_am_i(nb_i) !=
607 old_elem->opposite_side(old_elem->which_neighbor_am_i(nb_j)))
612 std::pair<dof_id_type, dof_id_type> nodes_pair_i;
613 nodes_pair_i.first = std::min(eidit, boundary_elem_ids[i]);
614 nodes_pair_i.second = std::max(eidit, boundary_elem_ids[i]);
615 if (elem_edge_nodes.count(nodes_pair_i))
617 for (
const auto & nbid : elem_edge_nodes[nodes_pair_i])
618 if (nbid != old_elem->id() && old_mesh->elem_ptr(nbid)->has_neighbor(nb_j))
622 std::pair<dof_id_type, dof_id_type> nodes_pair_j;
623 nodes_pair_j.first = std::min(eidit, boundary_elem_ids[
j]);
624 nodes_pair_j.second = std::max(eidit, boundary_elem_ids[
j]);
625 if (elem_edge_nodes.count(nodes_pair_j))
627 for (
const auto & nbid : elem_edge_nodes[nodes_pair_j])
628 if (nbid != old_elem->id() && old_mesh->elem_ptr(nbid)->has_neighbor(nb_i))
636 ((p1(1) - p0(1)) * (p2(2) - p0(2)) - (p1(2) - p0(2)) * (p2(1) - p0(1))) *
638 ((p1(2) - p0(2)) * (p2(0) - p0(0)) - (p1(0) - p0(0)) * (p2(2) - p0(2))) *
640 ((p1(0) - p0(0)) * (p2(1) - p0(1)) - (p1(1) - p0(1)) * (p2(0) - p0(0))) *
644 pd_nodes[1] = fe_elem_pd_node_map.at(boundary_elem_ids[i]);
645 pd_nodes[2] = fe_elem_pd_node_map.at(boundary_elem_ids[
j]);
649 pd_nodes[1] = fe_elem_pd_node_map.at(boundary_elem_ids[
j]);
650 pd_nodes[2] = fe_elem_pd_node_map.at(boundary_elem_ids[i]);
654 Elem * new_elem =
new Tet4;
655 new_elem->set_id(new_elem_id);
658 new_elem->subdomain_id() =
661 new_elem->subdomain_id() =
664 new_elem = new_mesh->add_elem(new_elem);
665 new_elem->set_node(0, new_mesh->node_ptr(pd_nodes[0]));
666 new_elem->set_node(1, new_mesh->node_ptr(pd_nodes[1]));
667 new_elem->set_node(2, new_mesh->node_ptr(pd_nodes[2]));
668 new_elem->set_node(3, new_mesh->node_ptr(pd_nodes[3]));
672 elem_edge_nodes[nodes_pair_i].insert(boundary_elem_ids[
j]);
673 elem_edge_nodes[nodes_pair_j].insert(boundary_elem_ids[i]);
678 if (old_boundary_info.get_sideset_name(bidit) !=
"")
681 "pd_side_" + old_boundary_info.get_sideset_name(bidit);
691 " is not supported for PD sidesets construction!");
699 std::map<dof_id_type, dof_id_type> fe_elems_map;
700 for (
const auto & eid : fe_elems)
702 Elem * old_elem = old_mesh->elem_ptr(eid);
703 Elem * new_elem = Elem::build(old_elem->type()).release();
704 new_elem->set_id(new_elem_id);
705 new_elem->subdomain_id() = old_elem->subdomain_id();
706 new_elem = new_mesh->add_elem(new_elem);
707 for (
unsigned int j = 0;
j < old_elem->n_nodes(); ++
j)
708 new_elem->set_node(
j, new_mesh->node_ptr(fe_nodes_map.at(old_elem->node_ptr(
j)->id())));
710 fe_elems_map.insert(std::make_pair(old_elem->id(), new_elem_id));
719 if (old_boundary_info.n_edge_conds())
720 mooseError(
"PeridynamicsMesh does not support edgesets!");
723 if (old_boundary_info.n_nodeset_conds())
724 old_boundary_info.build_side_list_from_node_list();
728 auto old_fe_sbc_tuples = old_boundary_info.build_side_list();
731 std::map<boundary_id_type, std::set<dof_id_type>> old_fe_bnd_elem_ids;
733 std::map<dof_id_type, std::map<boundary_id_type, dof_id_type>> old_fe_elem_bnd_side_ids;
734 for (
const auto & sbct : old_fe_sbc_tuples)
736 old_fe_bnd_elem_ids[std::get<2>(sbct)].insert(std::get<0>(sbct));
737 old_fe_elem_bnd_side_ids[std::get<0>(sbct)].insert(
738 std::make_pair(std::get<2>(sbct), std::get<1>(sbct)));
742 std::set<boundary_id_type> old_side_bid(old_boundary_info.get_side_boundary_ids());
745 for (
const auto & sbid : old_side_bid)
746 for (
const auto & beid : old_fe_bnd_elem_ids[sbid])
747 if (elems_to_pd.count(beid))
750 new_boundary_info.add_node(new_mesh->node_ptr(fe_elem_pd_node_map.at(beid)),
752 if (old_boundary_info.get_sideset_name(sbid) !=
"")
754 "pd_nodes_" + old_boundary_info.get_sideset_name(sbid);
759 new_boundary_info.add_side(
760 new_mesh->elem_ptr(fe_elems_map[beid]), old_fe_elem_bnd_side_ids[beid][sbid], sbid);
761 new_boundary_info.sideset_name(sbid) = old_boundary_info.get_sideset_name(sbid);
767 new_boundary_info.add_side(
768 new_mesh->elem_ptr(fe_elems_map[beid]), old_fe_elem_bnd_side_ids[beid][sbid], sbid);
769 new_boundary_info.sideset_name(sbid) = old_boundary_info.get_sideset_name(sbid);
774 auto old_node_bc_tuples = old_boundary_info.build_node_list();
776 std::map<boundary_id_type, std::set<dof_id_type>> old_bnd_node_ids;
777 for (
const auto & nbct : old_node_bc_tuples)
778 old_bnd_node_ids[std::get<1>(nbct)].insert(std::get<0>(nbct));
780 std::set<boundary_id_type> old_node_bid(old_boundary_info.get_node_boundary_ids());
782 for (
const auto & nbid : old_node_bid)
783 for (
const auto & bnid : old_bnd_node_ids[nbid])
784 if (fe_nodes.count(bnid))
786 new_boundary_info.add_node(new_mesh->node_ptr(fe_nodes_map.at(bnid)), nbid);
787 new_boundary_info.nodeset_name(nbid) = old_boundary_info.get_sideset_name(nbid);
791 for (
unsigned int i = 0; i < n_pd_nodes; ++i)
unsigned int _pd_nodeset_offset_number
a number used to offset the boundary nodeset ID after being converted into PD nodeset ...
std::set< boundary_id_type > _fe_sidesets_for_pd_construction
std::multimap< SubdomainID, SubdomainID > _pd_non_bonding_blk_pairs
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...
T & getMesh(MooseMesh &mesh)
function to cast mesh
std::set< SubdomainID > _blks_to_pd
MeshGeneratorPD(const InputParameters ¶meters)
std::set< std::string > sideset
std::multimap< SubdomainID, SubdomainID > _pd_bonding_blk_pairs
std::vector< dof_id_type > getNeighbors(dof_id_type node_id)
Function to return neighbor nodes indices for node node_id.
bool _merge_pd_interfacial_blks
flag to specify whether a single block should be used for all PD interfacial blocks this is used when...
bool _merge_pd_blks
flag to specify whether to combine converted PD mesh blocks into a single mesh block or not this is u...
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
bool _retain_fe_mesh
flag to specify whether the FE mesh should be retained or not in addition to newly created PD mesh ...
bool _has_non_bonding_blk_pairs
pairs of converted FE block IDs when only certain blocks need NOT to be connected this is usually use...
bool _has_blks_to_pd
block ID(s) of input FE mesh when only certain block(s) needs to be converted to PD mesh this is used...
bool _has_sidesets_to_pd
list of sideset ID(s) to be constructed based on converted PD mesh if the _construct_pd_sideset is tr...
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.
std::unique_ptr< MeshBase > & _input
Reference to the input finite element mesh.
bool _has_blks_as_fe
block ID(s) of input FE mesh when only certain block(s) needs NOT to be converted to PD mesh this is ...
static InputParameters validParams()
static InputParameters validParams()
std::string stringify(const T &t)
unsigned int _phantom_blk_offset_number
a number used to offset the block ID for phantom elements
std::set< SubdomainID > _blks_as_fe
bool _has_bonding_blk_pairs
pairs of converted FE block IDs when only certain blocks need to be connected using interfacial bonds...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int _pd_blk_offset_number
a number used to offset the block ID after being converted into PD mesh
void mooseError(Args &&... args) const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Generate peridynamics mesh based on finite element mesh.
static const std::string k
bool _construct_pd_sideset
flag to specify whether PD sideset should be constructed or not
std::unique_ptr< MeshBase > generate()
Function to convert the finite element mesh to peridynamics mesh.
void setNodeBlockID(SubdomainID id)
Function to set block ID for all PD nodes.
registerMooseObject("PeridynamicsApp", MeshGeneratorPD)