00001
00002
00003
00004
00005
00006 #include <boost/foreach.hpp>
00007
00008 #include "Subgraph.h"
00009 #include "Topology.h"
00010 #include "Topology_Utils.h"
00011
00012 namespace LCM {
00013
00014
00015
00016
00017 Topology::Topology() :
00018 discretization_(Teuchos::null),
00019 stk_mesh_struct_(Teuchos::null),
00020 fracture_criterion_(Teuchos::null)
00021 {
00022 return;
00023 }
00024
00025
00026
00027
00028 Topology::Topology(
00029 std::string const & input_file,
00030 std::string const & output_file) :
00031 discretization_(Teuchos::null),
00032 stk_mesh_struct_(Teuchos::null),
00033 fracture_criterion_(Teuchos::null)
00034 {
00035 RCP<Teuchos::ParameterList>
00036 params = Teuchos::rcp(new Teuchos::ParameterList("params"));
00037
00038
00039 RCP<Teuchos::ParameterList>
00040 disc_params = Teuchos::sublist(params, "Discretization");
00041
00042
00043 disc_params->set<std::string>("Method", "Exodus");
00044 disc_params->set<std::string>("Exodus Input File Name", input_file);
00045 disc_params->set<std::string>("Exodus Output File Name", output_file);
00046
00047 RCP<Teuchos::ParameterList>
00048 problem_params = Teuchos::sublist(params, "Problem");
00049
00050 RCP<Teuchos::ParameterList>
00051 adapt_params = Teuchos::sublist(problem_params, "Adaptation");
00052
00053 RCP<Epetra_Comm>
00054 communicator = Albany::createEpetraCommFromMpiComm(Albany_MPI_COMM_WORLD);
00055
00056 Albany::DiscretizationFactory
00057 disc_factory(params, communicator);
00058
00059
00060 Teuchos::ArrayRCP<RCP<Albany::MeshSpecsStruct> >
00061 mesh_specs = disc_factory.createMeshSpecs();
00062
00063 RCP<Albany::StateInfoStruct>
00064 state_info = Teuchos::rcp(new Albany::StateInfoStruct());
00065
00066
00067 Albany::AbstractFieldContainer::FieldContainerRequirements
00068 req;
00069
00070 setDiscretization(disc_factory.createDiscretization(3, state_info, req));
00071
00072 Topology::createDiscretization();
00073
00074
00075
00076 double const
00077 probability = 0.1;
00078
00079 setFractureCriterion(
00080 Teuchos::rcp(new FractureCriterionRandom(
00081 getSpaceDimension(), probability))
00082 );
00083
00084
00085
00086
00087 Topology::graphInitialization();
00088
00089 return;
00090 }
00091
00092
00093
00094
00095
00096 Topology::
00097 Topology(RCP<Albany::AbstractDiscretization> & discretization) :
00098 discretization_(Teuchos::null),
00099 stk_mesh_struct_(Teuchos::null),
00100 fracture_criterion_(Teuchos::null)
00101 {
00102 setDiscretization(discretization);
00103
00104 Topology::createDiscretization();
00105
00106
00107
00108 double const
00109 probability = 0.1;
00110
00111 setFractureCriterion(
00112 Teuchos::rcp(new FractureCriterionRandom(
00113 getSpaceDimension(), probability))
00114 );
00115
00116 return;
00117 }
00118
00119
00120
00121
00122 Topology::
00123 Topology(RCP<Albany::AbstractDiscretization>& discretization,
00124 RCP<AbstractFractureCriterion>& fracture_criterion) :
00125 discretization_(Teuchos::null),
00126 stk_mesh_struct_(Teuchos::null),
00127 fracture_criterion_(Teuchos::null)
00128 {
00129 setDiscretization(discretization);
00130 setFractureCriterion(fracture_criterion);
00131 Topology::createDiscretization();
00132
00133 return;
00134 }
00135
00136
00137
00138
00139
00140 void
00141 Topology::initializeFractureState()
00142 {
00143 stk::mesh::Selector
00144 local_selector = getMetaData()->locally_owned_part();
00145
00146 for (EntityRank rank = NODE_RANK; rank < getCellRank(); ++rank) {
00147
00148 std::vector<Bucket*> const &
00149 buckets = getBulkData()->buckets(rank);
00150
00151 EntityVector
00152 entities;
00153
00154 stk::mesh::get_selected_entities(local_selector, buckets, entities);
00155
00156 for (EntityVector::size_type i = 0; i < entities.size(); ++i) {
00157
00158 Entity const &
00159 entity = *(entities[i]);
00160
00161 setFractureState(entity, CLOSED);
00162
00163 }
00164 }
00165
00166 return;
00167 }
00168
00169
00170
00171
00172 void
00173 Topology::createDiscretization()
00174 {
00175
00176
00177 STKDiscretization &
00178 stk_discretization = static_cast<STKDiscretization &>(*getDiscretization());
00179
00180 setSTKMeshStruct(stk_discretization.getSTKMeshStruct());
00181
00182
00183
00184 stk::mesh::Selector
00185 local_selector = getMetaData()->locally_owned_part();
00186
00187 std::vector<Bucket*> const &
00188 buckets = getBulkData()->buckets(getCellRank());
00189
00190 EntityVector
00191 cells;
00192
00193 stk::mesh::get_selected_entities(local_selector, buckets, cells);
00194
00195 Entity const &
00196 first_cell = *(cells[0]);
00197
00198 setCellTopology(stk::mesh::fem::get_cell_topology(first_cell));
00199
00200 return;
00201 }
00202
00203
00204
00205
00206 void Topology::graphInitialization()
00207 {
00208 stk::mesh::PartVector add_parts;
00209 stk::mesh::create_adjacent_entities(*(getBulkData()), add_parts);
00210
00211 getBulkData()->modification_begin();
00212
00213 removeMultiLevelRelations();
00214 initializeFractureState();
00215
00216 getBulkData()->modification_end();
00217
00218 return;
00219 }
00220
00221
00222
00223
00224 void Topology::removeMultiLevelRelations()
00225 {
00226 typedef std::vector<EdgeId> EdgeIdList;
00227
00228 size_t const
00229 cell_node_rank_distance = getCellRank() - NODE_RANK;
00230
00231
00232 for (EntityRank rank = NODE_RANK; rank <= getCellRank(); ++rank) {
00233
00234 EntityVector
00235 entities;
00236
00237 stk::mesh::get_entities(*(getBulkData()), rank, entities);
00238
00239 for (size_t i = 0; i < entities.size(); ++i) {
00240
00241 Entity &
00242 entity = *(entities[i]);
00243
00244 PairIterRelation
00245 relations = entity.relations();
00246
00247 EntityVector
00248 far_entities;
00249
00250 EdgeIdList
00251 multilevel_relation_ids;
00252
00253
00254 for (PairIterRelation::iterator relation_iter = relations.begin();
00255 relation_iter != relations.end(); ++relation_iter) {
00256
00257 Relation const &
00258 relation = *relation_iter;
00259
00260 EntityRank
00261 target_rank = relation.entity_rank();
00262
00263 size_t const
00264 rank_distance =
00265 rank > target_rank ? rank - target_rank : target_rank - rank;
00266
00267 bool const
00268 is_valid_relation =
00269 rank < target_rank ||
00270 rank_distance == 1 ||
00271 rank_distance == cell_node_rank_distance;
00272
00273 if (is_valid_relation == false) {
00274 far_entities.push_back(relation_iter->entity());
00275 multilevel_relation_ids.push_back(relation_iter->identifier());
00276 }
00277
00278 }
00279
00280
00281 for (size_t i = 0; i < multilevel_relation_ids.size(); ++i) {
00282
00283 Entity &
00284 far_entity = *(far_entities[i]);
00285
00286 EdgeId const
00287 multilevel_relation_id = multilevel_relation_ids[i];
00288
00289 getBulkData()->destroy_relation(
00290 entity,
00291 far_entity,
00292 multilevel_relation_id);
00293 }
00294
00295 }
00296
00297 }
00298
00299 return;
00300 }
00301
00302
00303
00304
00305
00306 void Topology::removeExtraRelations()
00307 {
00308 EntityVector element_list;
00309 stk::mesh::get_entities(*(getBulkData()), getCellRank(), element_list);
00310
00311
00312 for (int i = 0; i < element_list.size(); ++i) {
00313 Entity & element = *(element_list[i]);
00314 PairIterRelation relations = element.relations();
00315 EntityVector del_relations;
00316 std::vector<int> del_ids;
00317 for (PairIterRelation::iterator j = relations.begin();
00318 j != relations.end(); ++j) {
00319
00320
00321 if (j->entity_rank() != getCellRank() - 1
00322 && j->entity_rank() != NODE_RANK) {
00323 del_relations.push_back(j->entity());
00324 del_ids.push_back(j->identifier());
00325 }
00326 }
00327 for (int j = 0; j < del_relations.size(); ++j) {
00328 Entity & entity = *(del_relations[j]);
00329 getBulkData()->destroy_relation(element, entity, del_ids[j]);
00330 }
00331 };
00332
00333 if (getCellRank() == VOLUME_RANK) {
00334
00335 EntityVector face_list;
00336 stk::mesh::get_entities(*(getBulkData()), getCellRank() - 1, face_list);
00337 EntityRank entityRank = face_list[0]->entity_rank();
00338 for (int i = 0; i < face_list.size(); ++i) {
00339 Entity & face = *(face_list[i]);
00340 PairIterRelation relations = face_list[i]->relations();
00341 EntityVector del_relations;
00342 std::vector<int> del_ids;
00343 for (PairIterRelation::iterator j = relations.begin();
00344 j != relations.end(); ++j) {
00345 if (j->entity_rank() != entityRank + 1
00346 && j->entity_rank() != entityRank - 1) {
00347 del_relations.push_back(j->entity());
00348 del_ids.push_back(j->identifier());
00349 }
00350 }
00351 for (int j = 0; j < del_relations.size(); ++j) {
00352 Entity & entity = *(del_relations[j]);
00353 getBulkData()->destroy_relation(face, entity, del_ids[j]);
00354 }
00355 }
00356 }
00357
00358 return;
00359 }
00360
00361
00362
00363
00364
00365
00366 void Topology::removeNodeRelations()
00367 {
00368
00369 EntityVector element_list;
00370 stk::mesh::get_entities(*(getBulkData()), getCellRank(), element_list);
00371
00372 getBulkData()->modification_begin();
00373 for (int i = 0; i < element_list.size(); ++i) {
00374 PairIterRelation nodes = element_list[i]->relations(NODE_RANK);
00375 EntityVector temp;
00376 for (int j = 0; j < nodes.size(); ++j) {
00377 Entity* node = nodes[j].entity();
00378 temp.push_back(node);
00379 }
00380 connectivity_temp_.push_back(temp);
00381
00382 for (int j = 0; j < temp.size(); ++j) {
00383 getBulkData()->destroy_relation(*(element_list[i]), *(temp[j]), j);
00384 }
00385 }
00386
00387 getBulkData()->modification_end();
00388
00389 return;
00390 }
00391
00392
00393
00394
00395 std::vector<EntityVector>
00396 Topology::getElementToNodeConnectivity()
00397 {
00398
00399 EntityVector
00400 element_list;
00401
00402 EntityVector
00403 node_list;
00404
00405 stk::mesh::get_entities(*(getBulkData()), getCellRank(), element_list);
00406
00407
00408 std::vector<EntityVector>
00409 element_to_node_connectivity;
00410
00411
00412 EntityVector::size_type const
00413 number_of_elements = element_list.size();
00414
00415 for (EntityVector::size_type i(0); i < number_of_elements; ++i) {
00416
00417 PairIterRelation
00418 relations = element_list[i]->relations(NODE_RANK);
00419
00420 size_t const
00421 nodes_per_element = relations.size();
00422
00423 for (size_t j(0); j < nodes_per_element; ++j) {
00424
00425 Entity*
00426 node = relations[j].entity();
00427
00428 node_list.push_back(node);
00429 }
00430
00431 element_to_node_connectivity.push_back(node_list);
00432 }
00433
00434 return element_to_node_connectivity;
00435 }
00436
00437
00438 void
00439 Topology::
00440 removeElementToNodeConnectivity(std::vector<EntityVector>& oldElemToNode)
00441 {
00442
00443 EntityVector element_list;
00444 stk::mesh::get_entities(*(getBulkData()), getCellRank(), element_list);
00445
00446 getBulkData()->modification_begin();
00447 for (int i = 0; i < element_list.size(); ++i) {
00448 PairIterRelation nodes = element_list[i]->relations(NODE_RANK);
00449 EntityVector temp;
00450 for (int j = 0; j < nodes.size(); ++j) {
00451 Entity* node = nodes[j].entity();
00452 temp.push_back(node);
00453 }
00454
00455
00456
00457 connectivity_temp_.push_back(temp);
00458 element_global_to_local_ids_[element_list[i]->identifier()] = i;
00459
00460 for (int j = 0; j < temp.size(); ++j) {
00461 getBulkData()->destroy_relation(*(element_list[i]), *(temp[j]), j);
00462 }
00463 }
00464
00465 getBulkData()->modification_end();
00466
00467 return;
00468 }
00469
00470
00471
00472
00473
00474 void Topology::restoreElementToNodeConnectivity()
00475 {
00476 EntityVector element_list;
00477 stk::mesh::get_entities(*(getBulkData()), getCellRank(), element_list);
00478
00479 getBulkData()->modification_begin();
00480
00481
00482 for (int i = 0; i < element_list.size(); ++i) {
00483 Entity & element = *(element_list[i]);
00484 EntityVector element_connectivity = connectivity_temp_[i];
00485 for (int j = 0; j < element_connectivity.size(); ++j) {
00486 Entity & node = *(element_connectivity[j]);
00487 getBulkData()->declare_relation(element, node, j);
00488 }
00489 }
00490
00491
00492 STKDiscretization & stk_discretization =
00493 static_cast<STKDiscretization &>(*discretization_);
00494
00495 RCP<Epetra_Comm> communicator =
00496 Albany::createEpetraCommFromMpiComm(Albany_MPI_COMM_WORLD);
00497
00498
00499 stk_discretization.updateMesh();
00500
00501 getBulkData()->modification_end();
00502
00503 return;
00504 }
00505
00506
00507 void
00508 Topology::
00509 restoreElementToNodeConnectivity(std::vector<EntityVector>& oldElemToNode)
00510 {
00511 EntityVector element_list;
00512 stk::mesh::get_entities(*(getBulkData()), getCellRank(), element_list);
00513
00514
00515
00516
00517 for (int i = 0; i < element_list.size(); ++i) {
00518 Entity & element = *(element_list[i]);
00519 EntityVector element_connectivity = oldElemToNode[i];
00520 for (int j = 0; j < element_connectivity.size(); ++j) {
00521 Entity & node = *(element_connectivity[j]);
00522 getBulkData()->declare_relation(element, node, j);
00523 }
00524 }
00525
00526 getBulkData()->modification_end();
00527
00528 return;
00529 }
00530
00531
00532
00533
00534
00535 EntityVector Topology::getFaceNodes(Entity * entity)
00536 {
00537 EntityVector face_nodes;
00538
00539 PairIterRelation elements = entity->relations(getCellRank());
00540
00541 unsigned faceId = elements[0].identifier();
00542 Entity * element = elements[0].entity();
00543
00544 unsigned numFaceNodes = getCellTopology().getNodeCount(entity->entity_rank(),
00545 faceId);
00546
00547
00548 for (int i = 0; i < numFaceNodes; ++i) {
00549
00550 unsigned elem_node = getCellTopology().getNodeMap(entity->entity_rank(),
00551 faceId, i);
00552
00553 int element_local_id = element_global_to_local_ids_[element->identifier()];
00554 Entity* node = connectivity_temp_[element_local_id][elem_node];
00555 face_nodes.push_back(node);
00556 }
00557
00558 return face_nodes;
00559 }
00560
00561
00562
00563
00564 EntityVector
00565 Topology::getBoundaryEntityNodes(Entity const & boundary_entity)
00566 {
00567 EntityRank const
00568 boundary_rank = boundary_entity.entity_rank();
00569
00570 assert(boundary_rank == getCellRank() - 1);
00571
00572 EntityVector
00573 nodes;
00574
00575 PairIterRelation
00576 relations = relations_one_up(boundary_entity);
00577
00578 Entity const &
00579 first_cell = *(relations[0].entity());
00580
00581 EdgeId const
00582 face_order = relations[0].identifier();
00583
00584 size_t const
00585 number_face_nodes =
00586 getCellTopology().getNodeCount(boundary_rank, face_order);
00587
00588 for (size_t i = 0; i < number_face_nodes; ++i) {
00589 EdgeId const
00590 cell_order = getCellTopology().getNodeMap(boundary_rank, face_order, i);
00591
00592
00593 PairIterRelation
00594 node_relations = first_cell.relations(NODE_RANK);
00595
00596 for (size_t i = 0; i < node_relations.size(); ++i) {
00597 if (node_relations[i].identifier() == cell_order) {
00598 nodes.push_back(node_relations[i].entity());
00599 }
00600 }
00601 }
00602
00603 return nodes;
00604 }
00605
00606
00607
00608
00609 void
00610 Topology::createBoundary()
00611 {
00612 stk::mesh::Part &
00613 boundary_part = *(getMetaData()->get_part("boundary"));
00614
00615 stk::mesh::PartVector
00616 add_parts;
00617
00618 add_parts.push_back(&boundary_part);
00619
00620 stk::mesh::PartVector const
00621 part_vector = getMetaData()->get_parts();
00622
00623 for (size_t i = 0; i < part_vector.size(); ++i) {
00624 std::cout << part_vector[i]->name() << '\n';
00625 }
00626
00627 EntityRank const
00628 boundary_entity_rank = getCellRank() - 1;
00629
00630 stk::mesh::Selector
00631 local_selector = getMetaData()->locally_owned_part();
00632
00633 std::vector<Bucket*> const &
00634 buckets = getBulkData()->buckets(boundary_entity_rank);
00635
00636 EntityVector
00637 entities;
00638
00639 stk::mesh::get_selected_entities(local_selector, buckets, entities);
00640
00641 getBulkData()->modification_begin();
00642 for (EntityVector::size_type i = 0; i < entities.size(); ++i) {
00643
00644 Entity &
00645 entity = *(entities[i]);
00646
00647 PairIterRelation
00648 relations = relations_one_up(entity);
00649
00650 size_t const
00651 number_connected_cells = std::distance(relations.begin(), relations.end());
00652
00653 switch (number_connected_cells) {
00654
00655 default:
00656 std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
00657 std::cerr << '\n';
00658 std::cerr << "Invalid number of connected cells: ";
00659 std::cerr << number_connected_cells;
00660 std::cerr << '\n';
00661 exit(1);
00662 break;
00663
00664 case 1:
00665 getBulkData()->change_entity_parts(entity, add_parts);
00666 break;
00667
00668 case 2:
00669
00670 break;
00671
00672 }
00673
00674 }
00675 getBulkData()->modification_end();
00676
00677 return;
00678 }
00679
00680
00681
00682
00683 void
00684 Topology::outputBoundary()
00685 {
00686 EntityRank const
00687 boundary_entity_rank = getCellRank() - 1;
00688
00689 stk::mesh::Selector
00690 local_selector = getMetaData()->locally_owned_part();
00691
00692 std::vector<Bucket*> const &
00693 buckets = getBulkData()->buckets(boundary_entity_rank);
00694
00695 EntityVector
00696 entities;
00697
00698 stk::mesh::get_selected_entities(local_selector, buckets, entities);
00699
00700 for (EntityVector::size_type i = 0; i < entities.size(); ++i) {
00701
00702 Entity const &
00703 entity = *(entities[i]);
00704
00705 PairIterRelation
00706 relations = relations_one_up(entity);
00707
00708 size_t const
00709 number_connected_cells = std::distance(relations.begin(), relations.end());
00710
00711 switch (number_connected_cells) {
00712
00713 default:
00714 std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
00715 std::cerr << '\n';
00716 std::cerr << "Invalid number of connected cells: ";
00717 std::cerr << number_connected_cells;
00718 std::cerr << '\n';
00719 exit(1);
00720 break;
00721
00722 case 1:
00723 {
00724 EntityVector const
00725 face_nodes = getBoundaryEntityNodes(entity);
00726 std::cout << entity.identifier() << " ";
00727 for (EntityVector::size_type i = 0; i < face_nodes.size(); ++i) {
00728 std::cout << face_nodes[i]->identifier() << " ";
00729 }
00730 std::cout << '\n';
00731 }
00732 break;
00733
00734 case 2:
00735
00736 break;
00737
00738 }
00739
00740 }
00741
00742 return;
00743 }
00744
00745
00746
00747
00748
00749 EntityVector
00750 Topology::createSurfaceElementConnectivity(Entity const & bcell1,
00751 Entity const & bcell2)
00752 {
00753
00754 size_t
00755 number_face_nodes = getCellTopology().getNodeCount(bcell1.entity_rank(), 0);
00756
00757
00758
00759 PairIterRelation
00760 bcell1_relations = relations_one_down(bcell1);
00761
00762 PairIterRelation
00763 bcell2_relations = relations_one_down(bcell2);
00764
00765 EntityVector
00766 connectivity(2 * number_face_nodes);
00767
00768 for (size_t i = 0; i < bcell1_relations.size(); ++i) {
00769
00770 Entity &
00771 entity1 = *(bcell1_relations[i].entity());
00772
00773 Entity &
00774 entity2 = *(bcell2_relations[i].entity());
00775
00776 EntityRank const
00777 cell_rank = getCellRank();
00778
00779 switch (getCellRank()) {
00780 default:
00781 std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
00782 std::cerr << '\n';
00783 std::cerr << "Surface element not implemented for dimension: ";
00784 std::cerr << cell_rank;
00785 std::cerr << '\n';
00786 exit(1);
00787 break;
00788
00789 case FACE_RANK:
00790 connectivity[i] = &entity1;
00791 connectivity[i + number_face_nodes] = &entity2;
00792 break;
00793
00794 case VOLUME_RANK:
00795 {
00796 PairIterRelation
00797 segment1_relations = entity1.relations(entity1.entity_rank() - 1);
00798 PairIterRelation
00799 segment2_relations = entity2.relations(entity2.entity_rank() - 1);
00800
00801
00802
00803 bool const
00804 unique_node =
00805 (i == 0) ||
00806 (i > 0 && connectivity[i - 1] != segment1_relations[0].entity()) ||
00807 (i == number_face_nodes - 1
00808 && connectivity[0] != segment1_relations[0].entity());
00809
00810 if (unique_node == true) {
00811 connectivity[i] = segment1_relations[0].entity();
00812 connectivity[i + number_face_nodes] = segment2_relations[0].entity();
00813 } else {
00814 connectivity[i] = segment1_relations[1].entity();
00815 connectivity[i + number_face_nodes] = segment2_relations[1].entity();
00816 }
00817 }
00818 break;
00819
00820 }
00821
00822 }
00823
00824 return connectivity;
00825 }
00826
00827
00828
00829
00830
00831 void
00832 Topology::createStar(
00833 Entity & entity,
00834 std::set<EntityKey> & subgraph_entities,
00835 std::set<stkEdge, EdgeLessThan> & subgraph_edges)
00836 {
00837 subgraph_entities.insert(entity.key());
00838
00839 PairIterRelation
00840 relations = relations_one_up(entity);
00841
00842 for (PairIterRelation::iterator i = relations.begin();
00843 i != relations.end(); ++i) {
00844
00845 Relation
00846 relation = *i;
00847
00848 Entity &
00849 source = *(relation.entity());
00850
00851 stkEdge
00852 edge;
00853
00854 edge.source = source.key();
00855 edge.target = entity.key();
00856 edge.local_id = relation.identifier();
00857
00858 subgraph_edges.insert(edge);
00859 createStar(source, subgraph_entities, subgraph_edges);
00860 }
00861
00862 return;
00863 }
00864
00865
00866
00867
00868 void
00869 Topology::splitOpenFaces()
00870 {
00871
00872 assert(getSpaceDimension() == VOLUME_RANK);
00873
00874 EntityVector
00875 points;
00876
00877 EntityVector
00878 open_points;
00879
00880 stk::mesh::Selector
00881 selector_owned = getMetaData()->locally_owned_part();
00882
00883 std::set<EntityPair>
00884 fractured_faces;
00885
00886 stk::mesh::get_selected_entities(
00887 selector_owned,
00888 getBulkData()->buckets(NODE_RANK),
00889 points);
00890
00891
00892 for (EntityVector::iterator i = points.begin();i != points.end(); ++i) {
00893
00894 Entity &
00895 point = *(*i);
00896
00897 if (getFractureState(point) == OPEN) {
00898 open_points.push_back(&point);
00899 }
00900 }
00901
00902 getBulkData()->modification_begin();
00903
00904
00905 for (EntityVector::iterator i = open_points.begin();
00906 i != open_points.end(); ++i) {
00907
00908 Entity &
00909 point = *(*i);
00910
00911 PairIterRelation
00912 relations = relations_one_up(point);
00913
00914 EntityVector
00915 open_segments;
00916
00917
00918 for (PairIterRelation::iterator j = relations.begin();
00919 j != relations.end(); ++j) {
00920
00921 Entity &
00922 segment = *j->entity();
00923
00924 bool const
00925 is_local_and_open =
00926 isLocalEntity(segment) == true && getFractureState(segment) == OPEN;
00927
00928 if (is_local_and_open == true) {
00929 open_segments.push_back(&segment);
00930 }
00931
00932 }
00933
00934
00935 for (EntityVector::iterator j = open_segments.begin();
00936 j != open_segments.end(); ++j) {
00937
00938 Entity &
00939 segment = *(*j);
00940
00941
00942 std::set<EntityKey>
00943 subgraph_entities;
00944
00945 std::set<stkEdge, EdgeLessThan>
00946 subgraph_edges;
00947
00948 createStar(segment, subgraph_entities, subgraph_edges);
00949
00950
00951 std::set<EntityKey>::iterator
00952 first_entity = subgraph_entities.begin();
00953
00954 std::set<EntityKey>::iterator
00955 last_entity = subgraph_entities.end();
00956
00957 std::set<stkEdge>::iterator
00958 first_edge = subgraph_edges.begin();
00959
00960 std::set<stkEdge>::iterator
00961 last_edge = subgraph_edges.end();
00962
00963 Subgraph
00964 subgraph(getSTKMeshStruct(),
00965 first_entity, last_entity, first_edge, last_edge);
00966
00967
00968 PairIterRelation
00969 face_relations = relations_one_up(segment);
00970
00971 EntityVector
00972 open_faces;
00973
00974 for (PairIterRelation::iterator k = face_relations.begin();
00975 k != face_relations.end(); ++k) {
00976
00977 Entity *
00978 face = k->entity();
00979
00980 if (isInternalAndOpen(*face) == true) {
00981 open_faces.push_back(face);
00982 }
00983 }
00984
00985
00986 for (EntityVector::iterator k = open_faces.begin();
00987 k != open_faces.end(); ++k) {
00988
00989 Entity *
00990 face = *k;
00991
00992 Vertex
00993 face_vertex = subgraph.globalToLocal(face->key());
00994
00995 Vertex
00996 new_face_vertex;
00997 subgraph.cloneBoundaryEntity(face_vertex);
00998
00999 EntityKey
01000 new_face_key = subgraph.localToGlobal(new_face_vertex);
01001
01002 Entity *
01003 new_face = getBulkData()->get_entity(new_face_key);
01004
01005
01006 setFractureState(*face, CLOSED);
01007 setFractureState(*new_face, CLOSED);
01008
01009 EntityPair
01010 ff = std::make_pair(face, new_face);
01011
01012 fractured_faces.insert(ff);
01013 }
01014
01015
01016 Vertex
01017 segment_vertex = subgraph.globalToLocal(segment.key());
01018
01019 subgraph.splitArticulationPoint(segment_vertex);
01020
01021
01022 setFractureState(segment, CLOSED);
01023
01024 }
01025
01026
01027
01028
01029 std::set<EntityKey>
01030 subgraph_entities;
01031
01032 std::set<stkEdge, EdgeLessThan>
01033 subgraph_edges;
01034
01035 createStar(point, subgraph_entities, subgraph_edges);
01036
01037
01038 std::set<EntityKey>::iterator
01039 first_entity = subgraph_entities.begin();
01040
01041 std::set<EntityKey>::iterator
01042 last_entity = subgraph_entities.end();
01043
01044 std::set<stkEdge>::iterator
01045 first_edge = subgraph_edges.begin();
01046
01047 std::set<stkEdge>::iterator
01048 last_edge = subgraph_edges.end();
01049
01050 Subgraph
01051 subgraph(
01052 getSTKMeshStruct(),
01053 first_entity,
01054 last_entity,
01055 first_edge,
01056 last_edge);
01057
01058 Vertex
01059 node = subgraph.globalToLocal(point.key());
01060
01061 std::map<Entity*, Entity*>
01062 new_connectivity = subgraph.splitArticulationPoint(node);
01063
01064
01065 setFractureState(point, CLOSED);
01066
01067
01068 for (std::map<Entity*, Entity*>::iterator j = new_connectivity.begin();
01069 j != new_connectivity.end(); ++j) {
01070
01071 Entity *
01072 element = (*j).first;
01073
01074 Entity *
01075 new_node = (*j).second;
01076
01077 getBulkData()->copy_entity_fields(point, *new_node);
01078 }
01079
01080 }
01081
01082 getBulkData()->modification_end();
01083
01084 getBulkData()->modification_begin();
01085
01086
01087 for (std::set<EntityPair>::iterator i =
01088 fractured_faces.begin(); i != fractured_faces.end(); ++i) {
01089
01090 Entity & face1 = *((*i).first);
01091 Entity & face2 = *((*i).second);
01092
01093 EntityVector
01094 cohesive_connectivity = createSurfaceElementConnectivity(face1, face2);
01095
01096 }
01097
01098 getBulkData()->modification_end();
01099 return;
01100 }
01101
01102
01103
01104
01105
01106 #if 0 // original
01107 void
01108 Topology::splitOpenFaces(std::map<EntityKey, bool> & entity_open)
01109 {
01110 int numfractured = 0;
01111
01112
01113 EntityVector node_list;
01114 EntityVector open_node_list;
01115 stk::mesh::Selector select_owned_or_shared = getMetaData()->locally_owned_part() |
01116 getMetaData()->globally_shared_part();
01117
01118 stk::mesh::get_selected_entities( select_owned_or_shared,
01119 getBulkData()->buckets( NODE_RANK ),
01120 node_list );
01121 for (EntityVector::iterator i = node_list.begin();
01122 i != node_list.end(); ++i) {
01123 Entity* entity = *i;
01124 if (entity_open[entity->key()] == true) {
01125 open_node_list.push_back(entity);
01126 }
01127 }
01128
01129 getBulkData()->modification_begin();
01130
01131
01132 for (EntityVector::iterator i = open_node_list.begin();
01133 i != open_node_list.end(); ++i) {
01134
01135 Entity * entity = *i;
01136 PairIterRelation relations = entity->relations(EDGE_RANK);
01137 EntityVector open_segment_list;
01138
01139 for (PairIterRelation::iterator j = relations.begin();
01140 j != relations.end(); ++j) {
01141 Entity & source = *j->entity();
01142 if (entity_open[source.key()] == true) {
01143 open_segment_list.push_back(&source);
01144 }
01145 }
01146
01147
01148 for (EntityVector::iterator j = open_segment_list.begin();
01149 j != open_segment_list.end(); ++j) {
01150 Entity * segment = *j;
01151
01152 std::set<EntityKey> subgraph_entity_list;
01153 std::set<stkEdge, EdgeLessThan> subgraph_edge_list;
01154 Topology::createStar(*segment, subgraph_entity_list, subgraph_edge_list);
01155
01156 std::set<EntityKey>::iterator firstEntity = subgraph_entity_list.begin();
01157 std::set<EntityKey>::iterator lastEntity = subgraph_entity_list.end();
01158 std::set<stkEdge>::iterator firstEdge = subgraph_edge_list.begin();
01159 std::set<stkEdge>::iterator lastEdge = subgraph_edge_list.end();
01160
01161 Subgraph subgraph(getSTKMeshStruct(), firstEntity, lastEntity, firstEdge,
01162 lastEdge);
01163
01164
01165 PairIterRelation faces = segment->relations(FACE_RANK);
01166 EntityVector open_face_list;
01167
01168 for (PairIterRelation::iterator k = faces.begin();
01169 k != faces.end(); ++k) {
01170 Entity & source = *k->entity();
01171 if (entity_open[source.key()] == true) {
01172 open_face_list.push_back(&source);
01173 }
01174 }
01175
01176
01177 for (EntityVector::iterator k = open_face_list.begin();
01178 k != open_face_list.end(); ++k) {
01179 Entity * face = *k;
01180 Vertex faceVertex = subgraph.globalToLocal(face->key());
01181 Vertex newFaceVertex;
01182 subgraph.cloneBoundaryEntity(faceVertex, newFaceVertex,
01183 entity_open);
01184
01185 EntityKey newFaceKey = subgraph.localToGlobal(newFaceVertex);
01186 Entity * newFace = getBulkData()->get_entity(newFaceKey);
01187
01188
01189 fractured_faces_.insert(std::make_pair(face, newFace));
01190
01191 ++numfractured;
01192 }
01193
01194
01195 Vertex segmentVertex = subgraph.globalToLocal(segment->key());
01196 subgraph.splitArticulationPoint(segmentVertex, entity_open);
01197 }
01198
01199
01200 std::set<EntityKey> subgraph_entity_list;
01201 std::set<stkEdge, EdgeLessThan> subgraph_edge_list;
01202 Topology::createStar(*entity, subgraph_entity_list, subgraph_edge_list);
01203
01204 std::set<EntityKey>::iterator firstEntity = subgraph_entity_list.begin();
01205 std::set<EntityKey>::iterator lastEntity = subgraph_entity_list.end();
01206 std::set<stkEdge>::iterator firstEdge = subgraph_edge_list.begin();
01207 std::set<stkEdge>::iterator lastEdge = subgraph_edge_list.end();
01208 Subgraph subgraph(getSTKMeshStruct(),
01209 firstEntity, lastEntity, firstEdge, lastEdge);
01210
01211 Vertex node = subgraph.globalToLocal(entity->key());
01212 std::map<Entity*, Entity*> new_connectivity =
01213 subgraph.splitArticulationPoint(node, entity_open);
01214
01215
01216 for (std::map<Entity*, Entity*>::iterator j = new_connectivity.begin();
01217 j != new_connectivity.end(); ++j) {
01218 Entity* element = (*j).first;
01219 Entity* newNode = (*j).second;
01220
01221 int element_id = element_global_to_local_ids_[element->identifier()];
01222 EntityVector & element_connectivity = connectivity_temp_[element_id];
01223 for (int k = 0; k < element_connectivity.size(); ++k) {
01224
01225
01226 if (element_connectivity[k] == entity) {
01227 element_connectivity[k] = newNode;
01228
01229 getBulkData()->copy_entity_fields(*entity, *newNode);
01230 }
01231 }
01232 }
01233 }
01234
01235 getBulkData()->modification_end();
01236 getBulkData()->modification_begin();
01237
01238
01239 int j = 1;
01240 for (std::set<EntityPair>::iterator i =
01241 fractured_faces_.begin(); i != fractured_faces_.end(); ++i, ++j) {
01242 Entity * face1 = (*i).first;
01243 Entity * face2 = (*i).second;
01244 EntityVector cohesive_connectivity;
01245 cohesive_connectivity =
01246 Topology::createSurfaceElementConnectivity(*face1, *face2);
01247
01248
01249 std::cout << "Cohesive Element " << j << ": ";
01250 for (int j = 0; j < cohesive_connectivity.size(); ++j) {
01251 std::cout << cohesive_connectivity[j]->identifier() << ":";
01252 }
01253 std::cout << "\n";
01254 }
01255
01256 getBulkData()->modification_end();
01257 return;
01258 }
01259 #endif
01260
01261 void Topology::splitOpenFaces(std::map<EntityKey, bool> & global_entity_open)
01262 {
01263 EntityVector open_node_list;
01264
01265 std::cout << " \n\nGlobal stuff in fracture_boundary\n\n" << '\n';
01266
01267
01268
01269 std::pair<EntityKey,bool> me;
01270
01271 BOOST_FOREACH(me, global_entity_open) {
01272
01273 if(stk::mesh::entity_rank( me.first) == NODE_RANK){
01274
01275 Entity *entity = getBulkData()->get_entity(me.first);
01276 std::cout << "Found open node: " << entity->identifier() << " belonging to pe: " << entity->owner_rank() << '\n';
01277 open_node_list.push_back(entity);
01278 }
01279 }
01280
01281 getBulkData()->modification_begin();
01282
01283
01284 for (EntityVector::iterator i = open_node_list.begin();
01285 i != open_node_list.end(); ++i) {
01286
01287 Entity * entity = *i;
01288 PairIterRelation relations = entity->relations(EDGE_RANK);
01289 EntityVector open_segment_list;
01290
01291 for (PairIterRelation::iterator j = relations.begin();
01292 j != relations.end(); ++j) {
01293 Entity & source = *j->entity();
01294 if (global_entity_open[source.key()] == true) {
01295 std::cout << "Found open segment: " << source.identifier() << " belonging to pe: " << source.owner_rank() << '\n';
01296 open_segment_list.push_back(&source);
01297 }
01298 }
01299
01300
01301 for (EntityVector::iterator j = open_segment_list.begin();
01302 j != open_segment_list.end(); ++j) {
01303 Entity * segment = *j;
01304
01305
01306 std::set<EntityKey> subgraph_entity_list;
01307 std::set<stkEdge, EdgeLessThan> subgraph_edge_list;
01308 Topology::createStar(*segment, subgraph_entity_list, subgraph_edge_list);
01309
01310
01311 std::set<EntityKey>::iterator first_entity = subgraph_entity_list.begin();
01312 std::set<EntityKey>::iterator last_entity = subgraph_entity_list.end();
01313 std::set<stkEdge>::iterator first_edge = subgraph_edge_list.begin();
01314 std::set<stkEdge>::iterator last_edge = subgraph_edge_list.end();
01315
01316 Subgraph subgraph(getSTKMeshStruct(),
01317 first_entity, last_entity, first_edge, last_edge);
01318
01319
01320 PairIterRelation faces = segment->relations(FACE_RANK);
01321 EntityVector open_face_list;
01322
01323
01324 for (PairIterRelation::iterator k = faces.begin();
01325 k != faces.end(); ++k) {
01326 Entity & source = *k->entity();
01327 if (global_entity_open[source.key()] == true) {
01328 std::cout << "Found open face: " << source.identifier() << " belonging to pe: " << source.owner_rank() << '\n';
01329 open_face_list.push_back(&source);
01330 }
01331 }
01332 std::cout << "\n\n\n\n\n" << '\n';
01333
01334
01335 for (EntityVector::iterator k = open_face_list.begin();
01336 k != open_face_list.end(); ++k) {
01337 Entity * face = *k;
01338 Vertex face_vertex = subgraph.globalToLocal(face->key());
01339 Vertex new_face_vertex;
01340 subgraph.cloneBoundaryEntity(face_vertex, new_face_vertex,
01341 global_entity_open);
01342 EntityKey new_face_key = subgraph.localToGlobal(new_face_vertex);
01343 Entity * new_face = getBulkData()->get_entity(new_face_key);
01344
01345
01346 fractured_faces_.insert(std::make_pair(face, new_face));
01347
01348 }
01349
01350
01351 Vertex segment_vertex = subgraph.globalToLocal(segment->key());
01352 std::cout << "Calling split_articulation_point with segmentVertex: " << '\n';
01353 subgraph.splitArticulationPoint(segment_vertex, global_entity_open);
01354 std::cout << "done Calling split_articulation_point with segmentVertex: " << '\n';
01355 }
01356
01357
01358 std::set<EntityKey> subgraph_entity_list;
01359 std::set<stkEdge, EdgeLessThan> subgraph_edge_list;
01360 Topology::createStar(*entity, subgraph_entity_list, subgraph_edge_list);
01361
01362 std::set<EntityKey>::iterator firstEntity = subgraph_entity_list.begin();
01363 std::set<EntityKey>::iterator lastEntity = subgraph_entity_list.end();
01364 std::set<stkEdge>::iterator firstEdge = subgraph_edge_list.begin();
01365 std::set<stkEdge>::iterator lastEdge = subgraph_edge_list.end();
01366 Subgraph subgraph(
01367 getSTKMeshStruct(),
01368 firstEntity, lastEntity, firstEdge, lastEdge);
01369
01370 Vertex node = subgraph.globalToLocal(entity->key());
01371 std::cout << "Calling split_articulation_point with node: " << '\n';
01372 std::map<Entity*, Entity*> new_connectivity =
01373 subgraph.splitArticulationPoint(node, global_entity_open);
01374 std::cout << "done Calling split_articulation_point with node: " << '\n';
01375
01376
01377 for (std::map<Entity*, Entity*>::iterator j = new_connectivity.begin();
01378 j != new_connectivity.end(); ++j) {
01379 Entity* element = (*j).first;
01380 Entity* newNode = (*j).second;
01381
01382
01383
01384
01385 int element_local_id = element_global_to_local_ids_[element->identifier()];
01386
01387 EntityVector & element_connectivity = connectivity_temp_[element_local_id];
01388 for (int k = 0; k < element_connectivity.size(); ++k) {
01389 if (element_connectivity[k] == entity) {
01390 element_connectivity[k] = newNode;
01391
01392 getBulkData()->copy_entity_fields(*entity, *newNode);
01393 }
01394 }
01395 }
01396 }
01397
01398 getBulkData()->modification_end();
01399
01400
01401
01402
01403 getBulkData()->modification_begin();
01404
01405
01406 int j = 1;
01407 for (std::set<EntityPair>::iterator i =
01408 fractured_faces_.begin(); i != fractured_faces_.end(); ++i, ++j) {
01409 Entity & face1 = *((*i).first);
01410 Entity & face2 = *((*i).second);
01411 EntityVector cohesive_connectivity;
01412 cohesive_connectivity =
01413 Topology::createSurfaceElementConnectivity(face1, face2);
01414
01415
01416 std::cout << "Cohesive Element " << j << ": ";
01417 for (int j = 0; j < cohesive_connectivity.size(); ++j) {
01418 std::cout << cohesive_connectivity[j]->identifier() << ":";
01419 }
01420 std::cout << "\n";
01421 }
01422
01423 getBulkData()->modification_end();
01424
01425 return;
01426 }
01427
01428
01429
01430
01431 void Topology::setEntitiesOpen()
01432 {
01433 EntityVector
01434 boundary_entities;
01435
01436 stk::mesh::Selector
01437 select_owned = getMetaData()->locally_owned_part();
01438
01439 stk::mesh::get_selected_entities(
01440 select_owned,
01441 getBulkData()->buckets(getBoundaryRank()) ,
01442 boundary_entities);
01443
01444
01445 for (size_t i = 0; i < boundary_entities.size(); ++i) {
01446
01447 Entity &
01448 entity = *(boundary_entities[i]);
01449
01450 if (checkOpen(entity) == false) continue;
01451
01452 setFractureState(entity, OPEN);
01453
01454 switch(getCellRank()) {
01455
01456 default:
01457 std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
01458 std::cerr << '\n';
01459 std::cerr << "Invalid cells rank in fracture: ";
01460 std::cerr << getCellRank();
01461 std::cerr << '\n';
01462 exit(1);
01463 break;
01464
01465 case VOLUME_RANK:
01466 {
01467 PairIterRelation segments = entity.relations(EDGE_RANK);
01468 for (size_t j = 0; j < segments.size(); ++j) {
01469 Entity & segment = *(segments[j].entity());
01470 setFractureState(segment, OPEN);
01471 PairIterRelation points = segment.relations(NODE_RANK);
01472 for (size_t k = 0; k < points.size(); ++k) {
01473 Entity & point = *(points[k].entity());
01474 setFractureState(point, OPEN);
01475 }
01476 }
01477 }
01478 break;
01479
01480 case EDGE_RANK:
01481 {
01482 PairIterRelation points = entity.relations(NODE_RANK);
01483 for (size_t j = 0; j < points.size(); ++j) {
01484 Entity & point = *(points[j].entity());
01485 setFractureState(point, OPEN);
01486 }
01487 }
01488 break;
01489 }
01490
01491 }
01492
01493 return;
01494 }
01495
01505 void Topology::setEntitiesOpen(std::map<EntityKey, bool>& entity_open)
01506 {
01507
01508
01509
01510 EntityVector boundary_list;
01511
01512 stk::mesh::Selector select_owned = getMetaData()->locally_owned_part();
01513
01514
01515 stk::mesh::get_selected_entities( select_owned,
01516 getBulkData()->buckets(getSpaceDimension() - 1 ) ,
01517 boundary_list );
01518
01519
01520 for (int i = 0; i < boundary_list.size(); ++i) {
01521 Entity& entity = *(boundary_list[i]);
01522 bool is_open = fracture_criterion_->check(entity);
01523
01524
01525 if (is_open == true && getSpaceDimension() == 3) {
01526 entity_open[entity.key()] = true;
01527 PairIterRelation segments = entity.relations(
01528 entity.entity_rank() - 1);
01529
01530 for (int j = 0; j < segments.size(); ++j) {
01531 Entity & segment = *(segments[j].entity());
01532 entity_open[segment.key()] = true;
01533 PairIterRelation nodes = segment.relations(
01534 segment.entity_rank() - 1);
01535
01536 for (int k = 0; k < nodes.size(); ++k) {
01537 Entity& node = *(nodes[k].entity());
01538 entity_open[node.key()] = true;
01539 }
01540 }
01541 }
01542
01543 else if (is_open == true && getSpaceDimension() == 2) {
01544 entity_open[entity.key()] = true;
01545 PairIterRelation nodes = entity.relations(
01546 entity.entity_rank() - 1);
01547
01548 for (int j = 0; j < nodes.size(); ++j) {
01549 Entity & node = *(nodes[j].entity());
01550 entity_open[node.key()] = true;
01551 }
01552 }
01553 }
01554
01555 return;
01556
01557 }
01558
01569 void Topology::setEntitiesOpen(const EntityVector& fractured_edges,
01570 std::map<EntityKey, bool>& entity_open)
01571 {
01572
01573 entity_open.clear();
01574
01575
01576 for (int i = 0; i < fractured_edges.size(); ++i) {
01577 Entity& entity = *(fractured_edges[i]);
01578
01579
01580 if (getSpaceDimension() == 3) {
01581 entity_open[entity.key()] = true;
01582 PairIterRelation segments = entity.relations(
01583 entity.entity_rank() - 1);
01584
01585 for (int j = 0; j < segments.size(); ++j) {
01586 Entity & segment = *(segments[j].entity());
01587 entity_open[segment.key()] = true;
01588 PairIterRelation nodes = segment.relations(
01589 segment.entity_rank() - 1);
01590
01591 for (int k = 0; k < nodes.size(); ++k) {
01592 Entity& node = *(nodes[k].entity());
01593 entity_open[node.key()] = true;
01594 }
01595 }
01596 }
01597
01598 else if (getSpaceDimension() == 2) {
01599 entity_open[entity.key()] = true;
01600 PairIterRelation nodes = entity.relations(
01601 entity.entity_rank() - 1);
01602
01603 for (int j = 0; j < nodes.size(); ++j) {
01604 Entity & node = *(nodes[j].entity());
01605 entity_open[node.key()] = true;
01606 }
01607 }
01608 }
01609
01610 return;
01611
01612 }
01613
01614 namespace {
01615
01616
01617
01618
01619 std::string
01620 entity_label(EntityRank const rank)
01621 {
01622 std::ostringstream
01623 oss;
01624
01625 switch (rank) {
01626 default:
01627 oss << rank << "-Polytope";
01628 break;
01629 case NODE_RANK:
01630 oss << "Point";
01631 break;
01632 case EDGE_RANK:
01633 oss << "Segment";
01634 break;
01635 case FACE_RANK:
01636 oss << "Polygon";
01637 break;
01638 case VOLUME_RANK:
01639 oss << "Polyhedron";
01640 break;
01641 case 4:
01642 oss << "Polychoron";
01643 break;
01644 case 5:
01645 oss << "Polyteron";
01646 break;
01647 case 6:
01648 oss << "Polypeton";
01649 break;
01650 }
01651
01652 return oss.str();
01653 }
01654
01655
01656
01657
01658 std::string
01659 entity_color(EntityRank const rank, FractureState const fracture_state)
01660 {
01661 std::ostringstream
01662 oss;
01663
01664 switch (fracture_state) {
01665
01666 default:
01667 std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
01668 std::cerr << '\n';
01669 std::cerr << "Fracture state is invalid: " << fracture_state;
01670 std::cerr << '\n';
01671 exit(1);
01672 break;
01673
01674 case CLOSED:
01675 switch (rank) {
01676 default:
01677 oss << 2 * (rank + 1);
01678 break;
01679 case NODE_RANK:
01680 oss << "6";
01681 break;
01682 case EDGE_RANK:
01683 oss << "4";
01684 break;
01685 case FACE_RANK:
01686 oss << "2";
01687 break;
01688 case VOLUME_RANK:
01689 oss << "8";
01690 break;
01691 case 4:
01692 oss << "10";
01693 break;
01694 case 5:
01695 oss << "12";
01696 break;
01697 case 6:
01698 oss << "14";
01699 break;
01700 }
01701 break;
01702
01703 case OPEN:
01704 switch (rank) {
01705 default:
01706 oss << 2 * rank + 1;
01707 break;
01708 case NODE_RANK:
01709 oss << "5";
01710 break;
01711 case EDGE_RANK:
01712 oss << "3";
01713 break;
01714 case FACE_RANK:
01715 oss << "1";
01716 break;
01717 case VOLUME_RANK:
01718 oss << "7";
01719 break;
01720 case 4:
01721 oss << "9";
01722 break;
01723 case 5:
01724 oss << "11";
01725 break;
01726 case 6:
01727 oss << "13";
01728 break;
01729 }
01730 break;
01731 }
01732
01733 return oss.str();
01734 }
01735
01736
01737
01738
01739 std::string
01740 dot_header()
01741 {
01742 std::string
01743 header = "digraph mesh {\n";
01744
01745 header += " node [colorscheme=paired12]\n";
01746 header += " edge [colorscheme=paired12]\n";
01747
01748 return header;
01749 }
01750
01751
01752
01753
01754 std::string
01755 dot_footer()
01756 {
01757 return "}";
01758 }
01759
01760
01761
01762
01763 std::string
01764 dot_entity(
01765 EntityId const id,
01766 EntityRank const rank,
01767 FractureState const fracture_state)
01768 {
01769 std::ostringstream
01770 oss;
01771
01772 oss << " \"";
01773 oss << id;
01774 oss << "_";
01775 oss << rank;
01776 oss << "\"";
01777 oss << " [label=\"";
01778
01779
01780 oss << id;
01781 oss << "\",style=filled,fillcolor=\"";
01782 oss << entity_color(rank, fracture_state);
01783 oss << "\"]\n";
01784
01785 return oss.str();
01786 }
01787
01788
01789
01790
01791 std::string
01792 relation_color(unsigned int const relation_id)
01793 {
01794 std::ostringstream
01795 oss;
01796
01797 switch (relation_id) {
01798 default:
01799 oss << 2 * (relation_id + 1);
01800 break;
01801 case 0:
01802 oss << "6";
01803 break;
01804 case 1:
01805 oss << "4";
01806 break;
01807 case 2:
01808 oss << "2";
01809 break;
01810 case 3:
01811 oss << "8";
01812 break;
01813 case 4:
01814 oss << "10";
01815 break;
01816 case 5:
01817 oss << "12";
01818 break;
01819 }
01820
01821 return oss.str();
01822 }
01823
01824
01825
01826
01827 std::string
01828 dot_relation(
01829 EntityId const source_id,
01830 EntityRank const source_rank,
01831 EntityId const target_id,
01832 EntityRank const target_rank,
01833 unsigned int const relation_local_id)
01834 {
01835 std::ostringstream
01836 oss;
01837
01838 oss << " \"";
01839 oss << source_id;
01840 oss << "_";
01841 oss << source_rank;
01842 oss << "\" -> \"";
01843 oss << target_id;
01844 oss << "_";
01845 oss << target_rank;
01846 oss << "\" [color=\"";
01847 oss << relation_color(relation_local_id);
01848 oss << "\"]\n";
01849
01850 return oss.str();
01851 }
01852
01853 }
01854
01855
01856
01857
01858
01859
01860 void
01861 Topology::outputToGraphviz(
01862 std::string const & output_filename,
01863 OutputType const output_type)
01864 {
01865
01866 std::ofstream gviz_out;
01867 gviz_out.open(output_filename.c_str(), std::ios::out);
01868
01869 if (gviz_out.is_open() == false) {
01870 std::cout << "Unable to open graphviz output file :";
01871 std::cout << output_filename << '\n';
01872 return;
01873 }
01874
01875 std::cout << "Write graph to graphviz dot file" << '\n';
01876
01877
01878 gviz_out << dot_header();
01879
01880 typedef std::vector<EntityPair> RelationList;
01881
01882 RelationList
01883 relation_list;
01884
01885 std::vector<EdgeId>
01886 relation_local_id;
01887
01888
01889 for (EntityRank rank = NODE_RANK; rank <= getCellRank(); ++rank) {
01890
01891 EntityVector
01892 entities;
01893
01894 stk::mesh::get_entities(*(getBulkData()), rank, entities);
01895
01896 for (EntityVector::size_type i = 0; i < entities.size(); ++i) {
01897
01898 Entity &
01899 source_entity = *(entities[i]);
01900
01901 FractureState const
01902 fracture_state = getFractureState(source_entity);
01903
01904 PairIterRelation
01905 relations = relations_all(source_entity);
01906
01907 gviz_out << dot_entity(source_entity.identifier(), rank, fracture_state);
01908
01909 for (size_t j = 0; j < relations.size(); ++j) {
01910
01911 Relation const &
01912 relation = relations[j];
01913
01914 Entity &
01915 target_entity = *(relation.entity());
01916
01917 EntityRank const
01918 target_rank = target_entity.entity_rank();
01919
01920 bool
01921 is_valid_target_rank = false;
01922
01923 switch (output_type) {
01924
01925 default:
01926 std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
01927 std::cerr << '\n';
01928 std::cerr << "Invalid output type: ";
01929 std::cerr << output_type;
01930 std::cerr << '\n';
01931 exit(1);
01932 break;
01933
01934 case UNIDIRECTIONAL_UNILEVEL:
01935 is_valid_target_rank = target_rank + 1 == rank;
01936 break;
01937
01938 case UNDIRECTIONAL_MULTILEVEL:
01939 is_valid_target_rank = target_rank < rank;
01940 break;
01941
01942 case BIDIRECTIONAL_UNILEVEL:
01943 is_valid_target_rank =
01944 (target_rank == rank + 1) || (target_rank + 1 == rank);
01945 break;
01946
01947 case BIDIRECTIONAL_MULTILEVEL:
01948 is_valid_target_rank = target_rank != rank;
01949 break;
01950
01951 }
01952
01953 if (is_valid_target_rank == false) continue;
01954
01955 EntityPair
01956 entity_pair = std::make_pair(&source_entity, &target_entity);
01957
01958 EdgeId const
01959 edge_id = relation.identifier();
01960
01961 relation_list.push_back(entity_pair);
01962 relation_local_id.push_back(edge_id);
01963 }
01964
01965 }
01966
01967 }
01968
01969
01970 for (RelationList::size_type i = 0; i < relation_list.size(); ++i) {
01971
01972 EntityPair
01973 entity_pair = relation_list[i];
01974
01975 Entity &
01976 source = *(entity_pair.first);
01977
01978 Entity &
01979 target = *(entity_pair.second);
01980
01981 gviz_out << dot_relation(
01982 source.identifier(), source.entity_rank(),
01983 target.identifier(), target.entity_rank(),
01984 relation_local_id[i]);
01985
01986 }
01987
01988
01989 gviz_out << dot_footer();
01990
01991 gviz_out.close();
01992
01993 return;
01994 }
01995
01996 }
01997