00001
00002
00003
00004
00005
00006 #include "Subgraph.h"
00007 #include "Topology_Utils.h"
00008
00009 namespace LCM {
00010
00011
00012
00013
00014 Subgraph::Subgraph(RCP<Albany::AbstractSTKMeshStruct> stk_mesh_struct,
00015 std::set<EntityKey>::iterator first_vertex,
00016 std::set<EntityKey>::iterator last_vertex,
00017 std::set<stkEdge>::iterator first_edge,
00018 std::set<stkEdge>::iterator last_edge) :
00019 stk_mesh_struct_(stk_mesh_struct)
00020 {
00021
00022 for (std::set<EntityKey>::iterator vertex_iterator = first_vertex;
00023 vertex_iterator != last_vertex;
00024 ++vertex_iterator) {
00025
00026
00027 EntityKey
00028 global_vertex = *vertex_iterator;
00029
00030
00031 EntityRank
00032 vertex_rank = getBulkData()->get_entity(global_vertex)->entity_rank();
00033
00034
00035 Vertex
00036 local_vertex = boost::add_vertex(*this);
00037
00038 std::pair<Vertex, EntityKey>
00039 local_to_global = std::make_pair(local_vertex, global_vertex);
00040
00041 std::pair<EntityKey, Vertex>
00042 global_to_local = std::make_pair(global_vertex, local_vertex);
00043
00044 local_global_vertex_map_.insert(local_to_global);
00045
00046 global_local_vertex_map_.insert(global_to_local);
00047
00048
00049 VertexNamePropertyMap
00050 vertex_property_map = boost::get(VertexName(), *this);
00051
00052 boost::put(vertex_property_map, local_vertex, vertex_rank);
00053 }
00054
00055
00056 for (std::set<stkEdge>::iterator edge_iterator = first_edge;
00057 edge_iterator != last_edge;
00058 ++edge_iterator) {
00059
00060
00061 stkEdge
00062 global_edge = *edge_iterator;
00063
00064
00065 EntityKey
00066 global_source_vertex = global_edge.source;
00067
00068 EntityKey
00069 global_target_vertex = global_edge.target;
00070
00071
00072 Vertex
00073 local_source_vertex =
00074 global_local_vertex_map_.find(global_source_vertex)->second;
00075
00076 Vertex
00077 local_target_vertex =
00078 global_local_vertex_map_.find(global_target_vertex)->second;
00079
00080 EdgeId
00081 edge_id = global_edge.local_id;
00082
00083 Edge
00084 local_edge;
00085
00086 bool
00087 is_inserted;
00088
00089 boost::tie(local_edge, is_inserted) =
00090 boost::add_edge(local_source_vertex, local_target_vertex, *this);
00091
00092 assert(is_inserted == true);
00093
00094
00095 EdgeNamePropertyMap
00096 edge_property_map = boost::get(EdgeName(), *this);
00097
00098 boost::put(edge_property_map, local_edge, edge_id);
00099 }
00100
00101 return;
00102 }
00103
00104
00105
00106
00107 EntityKey
00108 Subgraph::localToGlobal(Vertex local_vertex)
00109 {
00110 std::map<Vertex, EntityKey>::const_iterator
00111 vertex_map_iterator = local_global_vertex_map_.find(local_vertex);
00112
00113 assert(vertex_map_iterator != local_global_vertex_map_.end());
00114
00115 return (*vertex_map_iterator).second;
00116 }
00117
00118
00119
00120
00121 Vertex
00122 Subgraph::globalToLocal(EntityKey global_vertex_key)
00123 {
00124 std::map<EntityKey, Vertex>::const_iterator
00125 vertex_map_iterator = global_local_vertex_map_.find(global_vertex_key);
00126
00127 assert(vertex_map_iterator != global_local_vertex_map_.end());
00128
00129 return (*vertex_map_iterator).second;
00130 }
00131
00132
00133
00134
00135 Vertex
00136 Subgraph::addVertex(EntityRank vertex_rank)
00137 {
00138
00139
00140
00141 std::vector<size_t>
00142 requests(getSpaceDimension() + 1, 0);
00143
00144 requests[vertex_rank] = 1;
00145
00146 EntityVector
00147 new_entities;
00148
00149 getBulkData()->generate_new_entities(requests, new_entities);
00150
00151 EntityKey
00152 global_vertex = new_entities[0]->key();
00153
00154
00155 Vertex
00156 local_vertex = boost::add_vertex(*this);
00157
00158
00159 std::pair<Vertex, EntityKey>
00160 local_to_global = std::make_pair(local_vertex, global_vertex);
00161
00162 std::pair<EntityKey, Vertex>
00163 global_to_local = std::make_pair(global_vertex, local_vertex);
00164
00165 local_global_vertex_map_.insert(local_to_global);
00166
00167 global_local_vertex_map_.insert(global_to_local);
00168
00169
00170 VertexNamePropertyMap
00171 vertex_property_map = boost::get(VertexName(), *this);
00172
00173 boost::put(vertex_property_map, local_vertex, vertex_rank);
00174
00175 return local_vertex;
00176 }
00177
00178
00179 void
00180 Subgraph::communicate_and_create_shared_entities(Entity & node,
00181 EntityKey new_node_key){
00182
00183 stk::CommAll comm(getBulkData()->parallel());
00184
00185 {
00186 stk::mesh::PairIterEntityComm entity_comm = node.sharing();
00187
00188 for (; entity_comm.first != entity_comm.second; ++entity_comm.first) {
00189
00190 unsigned proc = entity_comm.first->proc;
00191 comm.send_buffer(proc).pack<EntityKey>(node.key())
00192 .pack<EntityKey>(new_node_key);
00193
00194 }
00195 }
00196
00197 comm.allocate_buffers(getBulkData()->parallel_size()/4 );
00198
00199 {
00200 stk::mesh::PairIterEntityComm entity_comm = node.sharing();
00201
00202 for (; entity_comm.first != entity_comm.second; ++entity_comm.first) {
00203
00204 unsigned proc = entity_comm.first->proc;
00205 comm.send_buffer(proc).pack<EntityKey>(node.key())
00206 .pack<EntityKey>(new_node_key);
00207
00208 }
00209 }
00210
00211 comm.communicate();
00212
00213 const stk::mesh::PartVector no_parts;
00214
00215 for (size_t process = 0; process < getBulkData()->parallel_size(); ++process) {
00216 EntityKey old_key;
00217 EntityKey new_key;
00218
00219 while ( comm.recv_buffer(process).remaining()) {
00220
00221 comm.recv_buffer(process).unpack<EntityKey>(old_key)
00222 .unpack<EntityKey>(new_key);
00223
00224 Entity * new_entity = & getBulkData()->declare_entity(new_key.rank(), new_key.id(), no_parts);
00225
00226
00227
00228 }
00229 }
00230
00231 }
00232
00233
00234 void
00235 Subgraph::bcast_key(unsigned root, EntityKey& node_key){
00236
00237 stk::CommBroadcast comm(getBulkData()->parallel(), root);
00238
00239 unsigned rank = getBulkData()->parallel_rank();
00240
00241 if(rank == root)
00242
00243 comm.send_buffer().pack<EntityKey>(node_key);
00244
00245 comm.allocate_buffer();
00246
00247 if(rank == root)
00248
00249 comm.send_buffer().pack<EntityKey>(node_key);
00250
00251 comm.communicate();
00252
00253 comm.recv_buffer().unpack<EntityKey>(node_key);
00254
00255 }
00256
00257
00258 Vertex
00259 Subgraph::cloneVertex(Vertex & vertex)
00260 {
00261
00262
00263 EntityRank
00264 vertex_rank = Subgraph::getVertexRank(vertex);
00265
00266 EntityKey
00267 vertex_key = Subgraph::localToGlobal(vertex);
00268
00269
00270 Entity *
00271 old_vertex = getBulkData()->get_entity(vertex_key);
00272
00273
00274 int owner_proc = old_vertex->owner_rank();
00275
00276
00277
00278 std::vector<size_t> requests(getSpaceDimension() + 1, 0);
00279 EntityVector new_entity;
00280 const stk::mesh::PartVector no_parts;
00281
00282 int my_proc = getBulkData()->parallel_rank();
00283 int source;
00284 Entity *global_vertex;
00285 EntityKey global_vertex_key;
00286 EntityKey::raw_key_type gvertkey;
00287
00288 if(my_proc == owner_proc){
00289
00290
00291
00292 requests[vertex_rank] = 1;
00293
00294
00295
00296 getBulkData()->generate_new_entities(requests, new_entity);
00297 global_vertex = new_entity[0];
00298
00299
00300 global_vertex_key = global_vertex->key();
00301 gvertkey = global_vertex_key.raw_key();
00302
00303 }
00304 else {
00305
00306
00307
00308 getBulkData()->generate_new_entities(requests, new_entity);
00309
00310 }
00311
00312 Subgraph::bcast_key(owner_proc, global_vertex_key);
00313
00314 if(my_proc != owner_proc){
00315
00316
00317
00318 const stk::mesh::PartVector no_parts;
00319 Entity * new_entity = & getBulkData()->declare_entity(global_vertex_key.rank(), global_vertex_key.id(), no_parts);
00320
00321 }
00322
00323
00324 Vertex local_vertex = boost::add_vertex(*this);
00325
00326
00327 local_global_vertex_map_.insert(
00328 std::map<Vertex, EntityKey>::value_type(local_vertex,
00329 global_vertex_key));
00330 global_local_vertex_map_.insert(
00331 std::map<EntityKey, Vertex>::value_type(global_vertex_key,
00332 local_vertex));
00333
00334
00335 VertexNamePropertyMap vertex_property_map = boost::get(VertexName(), *this);
00336 boost::put(vertex_property_map, local_vertex, vertex_rank);
00337
00338 return local_vertex;
00339 }
00340
00341
00342
00343
00344 void
00345 Subgraph::removeVertex(Vertex const vertex)
00346 {
00347
00348 EntityKey
00349 key = localToGlobal(vertex);
00350
00351
00352 Entity *
00353 entity = getBulkData()->get_entity(key);
00354
00355
00356
00357 global_local_vertex_map_.erase(key);
00358 local_global_vertex_map_.erase(vertex);
00359
00360
00361
00362 boost::clear_vertex(vertex, *this);
00363
00364 boost::remove_vertex(vertex, *this);
00365
00366
00367 PairIterRelation
00368 relations = entity->relations();
00369
00370 for (size_t i = 0; i < relations.size(); ++i) {
00371
00372 EdgeId
00373 edge_id = relations[i].identifier();
00374
00375 Entity &
00376 target = *(relations[i].entity());
00377
00378 getBulkData()->destroy_relation(*entity, target, edge_id);
00379 }
00380
00381
00382 bool const
00383 deleted = getBulkData()->destroy_entity(entity);
00384 assert(deleted);
00385
00386 return;
00387 }
00388
00389
00390
00391
00392 std::pair<Edge, bool>
00393 Subgraph::addEdge(
00394 EdgeId const edge_id,
00395 Vertex const local_source_vertex,
00396 Vertex const local_target_vertex)
00397 {
00398
00399 EntityKey
00400 global_source_key = localToGlobal(local_source_vertex);
00401
00402 EntityKey
00403 global_target_key = localToGlobal(local_target_vertex);
00404
00405 Entity *
00406 global_source_vertex = getBulkData()->get_entity(global_source_key);
00407
00408 Entity *
00409 global_target_vertex = getBulkData()->get_entity(global_target_key);
00410
00411 assert(global_source_vertex->entity_rank() -
00412 global_target_vertex->entity_rank() == 1);
00413
00414
00415 std::pair<Edge, bool>
00416 local_edge = boost::add_edge(local_source_vertex, local_target_vertex, *this);
00417
00418 if (local_edge.second == false) return local_edge;
00419
00420
00421 getBulkData()->declare_relation(
00422 *(global_source_vertex),
00423 *(global_target_vertex),
00424 edge_id);
00425
00426
00427 EdgeNamePropertyMap
00428 edge_property_map = boost::get(EdgeName(), *this);
00429
00430 boost::put(edge_property_map, local_edge.first, edge_id);
00431
00432 return local_edge;
00433 }
00434
00435
00436
00437
00438 void
00439 Subgraph::removeEdge(
00440 Vertex const & local_source_vertex,
00441 Vertex const & local_target_vertex)
00442 {
00443
00444 Edge
00445 edge;
00446
00447 bool
00448 inserted;
00449
00450 boost::tie(edge, inserted) =
00451 boost::edge(local_source_vertex, local_target_vertex, *this);
00452
00453 assert(inserted);
00454
00455 EdgeId
00456 edge_id = getEdgeId(edge);
00457
00458
00459 boost::remove_edge(local_source_vertex, local_target_vertex, *this);
00460
00461
00462 EntityKey
00463 global_source_id = localToGlobal(local_source_vertex);
00464
00465 EntityKey
00466 global_target_id = localToGlobal(local_target_vertex);
00467
00468 Entity *
00469 global_source_vertex = getBulkData()->get_entity(global_source_id);
00470
00471 Entity *
00472 global_target_vertex = getBulkData()->get_entity(global_target_id);
00473
00474 getBulkData()->destroy_relation(
00475 *(global_source_vertex),
00476 *(global_target_vertex),
00477 edge_id);
00478
00479 return;
00480 }
00481
00482
00483
00484
00485 EntityRank
00486 Subgraph::getVertexRank(Vertex const vertex)
00487 {
00488 VertexNamePropertyMap
00489 vertex_property_map = boost::get(VertexName(), *this);
00490 return boost::get(vertex_property_map, vertex);
00491 }
00492
00493
00494
00495
00496 EdgeId
00497 Subgraph::getEdgeId(Edge const edge)
00498 {
00499 EdgeNamePropertyMap
00500 edge_property_map = boost::get(EdgeName(), *this);
00501 return boost::get(edge_property_map, edge);
00502 }
00503
00504
00505
00506
00507
00508 void
00509 Subgraph::testArticulationPoint(
00510 Vertex const input_vertex,
00511 size_t & number_components,
00512 ComponentMap & component_map)
00513 {
00514
00515
00516
00517
00518
00519 typedef boost::adjacency_list<Vector, Vector, Undirected> UGraph;
00520 typedef boost::graph_traits<UGraph>::vertex_descriptor UVertex;
00521 typedef boost::graph_traits<UGraph>::edge_descriptor UEdge;
00522
00523
00524 std::map<UVertex, Vertex>
00525 u_sub_vertex_map;
00526
00527 std::map<Vertex, UVertex>
00528 sub_u_vertex_map;
00529
00530 UGraph
00531 graph;
00532
00533 VertexIterator
00534 vertex_begin;
00535
00536 VertexIterator
00537 vertex_end;
00538
00539 boost::tie(vertex_begin, vertex_end) = vertices(*this);
00540
00541
00542 for (VertexIterator i = vertex_begin; i != vertex_end; ++i) {
00543
00544 Vertex
00545 vertex = *i;
00546
00547 if (vertex == input_vertex) continue;
00548
00549 UVertex
00550 uvertex = boost::add_vertex(graph);
00551
00552
00553 std::pair<UVertex, Vertex>
00554 u_sub = std::make_pair(uvertex, vertex);
00555
00556 std::pair<Vertex, UVertex>
00557 sub_u = std::make_pair(vertex, uvertex);
00558
00559 u_sub_vertex_map.insert(u_sub);
00560 sub_u_vertex_map.insert(sub_u);
00561 }
00562
00563
00564 for (VertexIterator i = vertex_begin; i != vertex_end; ++i) {
00565
00566 Vertex
00567 source = *i;
00568
00569 if (source == input_vertex) continue;
00570
00571 std::map<Vertex, UVertex>::const_iterator
00572 source_map_iterator = sub_u_vertex_map.find(source);
00573
00574 UVertex
00575 usource = (*source_map_iterator).second;
00576
00577
00578 OutEdgeIterator
00579 out_edge_begin;
00580
00581 OutEdgeIterator
00582 out_edge_end;
00583
00584 boost::tie(out_edge_begin, out_edge_end) = out_edges(source, *this);
00585
00586 for (OutEdgeIterator j = out_edge_begin; j != out_edge_end; ++j) {
00587
00588 Edge
00589 edge = *j;
00590
00591 Vertex
00592 target = boost::target(edge, *this);
00593
00594 if (target == input_vertex) continue;
00595
00596 std::map<Vertex, UVertex>::const_iterator
00597 target_map_iterator = sub_u_vertex_map.find(target);
00598
00599 UVertex
00600 utarget = (*target_map_iterator).second;
00601
00602 boost::add_edge(usource, utarget, graph);
00603
00604 }
00605 }
00606
00607 std::vector<size_t>
00608 components(boost::num_vertices(graph));
00609
00610 number_components = boost::connected_components(graph, &components[0]);
00611
00612 for (std::map<UVertex, Vertex>::iterator i = u_sub_vertex_map.begin();
00613 i != u_sub_vertex_map.end(); ++i) {
00614
00615 Vertex
00616 vertex = (*i).second;
00617
00618 size_t
00619 component_number = static_cast<size_t>((*i).first);
00620
00621 std::pair<Vertex, size_t>
00622 component = std::make_pair(vertex, components[component_number]);
00623
00624 component_map.insert(component);
00625 }
00626
00627 return;
00628 }
00629
00630
00631
00632
00633
00634 Vertex
00635 Subgraph::cloneBoundaryEntity(Vertex vertex)
00636 {
00637 EntityRank
00638 vertex_rank = getVertexRank(vertex);
00639
00640 assert(vertex_rank == getBoundaryRank());
00641
00642 Vertex
00643 new_vertex = addVertex(vertex_rank);
00644
00645
00646 OutEdgeIterator
00647 out_edge_begin;
00648
00649 OutEdgeIterator
00650 out_edge_end;
00651
00652 boost::tie(out_edge_begin, out_edge_end) = boost::out_edges(vertex, *this);
00653
00654 for (OutEdgeIterator i = out_edge_begin; i != out_edge_end; ++i) {
00655 Edge
00656 edge = *i;
00657
00658 EdgeId
00659 edge_id = getEdgeId(edge);
00660
00661 Vertex
00662 target = boost::target(edge, *this);
00663
00664 addEdge(edge_id, new_vertex, target);
00665 }
00666
00667
00668 cloneOutEdges(vertex, new_vertex);
00669
00670
00671
00672 InEdgeIterator
00673 in_edge_begin;
00674
00675 InEdgeIterator
00676 in_edge_end;
00677
00678 boost::tie(in_edge_begin, in_edge_end) = boost::in_edges(vertex, *this);
00679
00680 Edge
00681 edge = *(in_edge_begin);
00682
00683 EdgeId
00684 edge_id = getEdgeId(edge);
00685
00686 Vertex
00687 source = boost::source(edge, *this);
00688
00689 removeEdge(source, vertex);
00690
00691
00692 addEdge(edge_id, source, new_vertex);
00693
00694 return new_vertex;
00695 }
00696
00697
00698 void
00699 Subgraph::cloneBoundaryEntity(Vertex & vertex, Vertex & new_vertex,
00700 std::map<EntityKey, bool> & entity_open)
00701 {
00702
00703 boost::graph_traits<Graph>::degree_size_type num_in_edges =
00704 boost::in_degree(vertex, *this);
00705 if (num_in_edges != 2) return;
00706
00707
00708 EntityKey vertex_key = Subgraph::localToGlobal(vertex);
00709 assert(entity_open[vertex_key]==true);
00710
00711
00712
00713
00714
00715
00716 new_vertex = Subgraph::cloneVertex(vertex);
00717
00718
00719 OutEdgeIterator out_edge_begin;
00720 OutEdgeIterator out_edge_end;
00721 boost::tie(out_edge_begin, out_edge_end) = boost::out_edges(vertex, *this);
00722 for (OutEdgeIterator i = out_edge_begin; i != out_edge_end; ++i) {
00723 Edge edge = *i;
00724 EdgeId edgeId = Subgraph::getEdgeId(edge);
00725 Vertex target = boost::target(edge, *this);
00726 Subgraph::addEdge(edgeId, new_vertex, target);
00727 }
00728
00729
00730 Subgraph::cloneOutEdges(vertex, new_vertex);
00731
00732
00733
00734 InEdgeIterator in_edge_begin;
00735 InEdgeIterator in_edge_end;
00736 boost::tie(in_edge_begin, in_edge_end) = boost::in_edges(vertex, *this);
00737 Edge edge = *(in_edge_begin);
00738 EdgeId edgeId = Subgraph::getEdgeId(edge);
00739 Vertex source = boost::source(edge, *this);
00740 Subgraph::removeEdge(source, vertex);
00741
00742
00743 Subgraph::addEdge(edgeId, source, new_vertex);
00744
00745
00746
00747
00748
00749 entity_open[vertex_key] = false;
00750
00751 return;
00752 }
00753
00754
00755
00756
00757 std::map<Entity*, Entity*>
00758 Subgraph::splitArticulationPoint(Vertex vertex)
00759 {
00760 EntityRank
00761 vertex_rank = Subgraph::getVertexRank(vertex);
00762
00763
00764 size_t
00765 number_components;
00766
00767 ComponentMap
00768 components;
00769
00770 testArticulationPoint(vertex, number_components, components);
00771
00772
00773
00774 std::map<Entity*, Entity*>
00775 new_connectivity;
00776
00777 if (number_components == 1) return new_connectivity;
00778
00779
00780 std::vector<Vertex>
00781 new_vertices;
00782
00783 for (size_t i = 0; i < number_components - 1; ++i) {
00784 Vertex
00785 new_vertex = addVertex(vertex_rank);
00786
00787 new_vertices.push_back(new_vertex);
00788 }
00789
00790
00791
00792 if (vertex_rank == NODE_RANK) {
00793 for (ComponentMap::iterator i = components.begin();
00794 i != components.end(); ++i) {
00795
00796 size_t
00797 component_number = (*i).second;
00798
00799 Vertex
00800 current_vertex = (*i).first;
00801
00802 EntityRank
00803 current_rank = getVertexRank(current_vertex);
00804
00805
00806 if (current_rank == getCellRank() && component_number != 0) {
00807
00808 Entity *
00809 element = getBulkData()->get_entity(localToGlobal(current_vertex));
00810
00811 Vertex
00812 new_vertex = new_vertices[component_number - 1];
00813
00814 Entity *
00815 new_node = getBulkData()->get_entity(localToGlobal(new_vertex));
00816
00817 std::pair<Entity*, Entity*>
00818 nc = std::make_pair(element, new_node);
00819
00820 new_connectivity.insert(nc);
00821 }
00822 }
00823 }
00824
00825
00826 for (size_t i = 0; i < new_vertices.size(); ++i) {
00827 cloneOutEdges(vertex, new_vertices[i]);
00828 }
00829
00830
00831
00832 std::vector<std::pair<Vertex, EdgeId> >
00833 removed;
00834
00835
00836
00837 InEdgeIterator
00838 in_edge_begin;
00839
00840 InEdgeIterator
00841 in_edge_end;
00842
00843 boost::tie(in_edge_begin, in_edge_end) = boost::in_edges(vertex, *this);
00844
00845 for (InEdgeIterator i = in_edge_begin; i != in_edge_end; ++i) {
00846 Edge
00847 edge = *i;
00848
00849 Vertex
00850 source = boost::source(edge, *this);
00851
00852 ComponentMap::const_iterator
00853 component_iterator = components.find(source);
00854
00855 size_t
00856 vertex_component = (*component_iterator).second;
00857
00858 Entity &
00859 entity = *(getBulkData()->get_entity(localToGlobal(source)));
00860
00861
00862 if (vertex_component != 0) {
00863 EdgeId
00864 edge_id = getEdgeId(edge);
00865
00866 removed.push_back(std::make_pair(source, edge_id));
00867 }
00868 }
00869
00870
00871 for (std::vector<std::pair<Vertex, EdgeId> >::iterator i = removed.begin();
00872 i != removed.end(); ++i) {
00873
00874 std::pair<Vertex, EdgeId>
00875 edge = *i;
00876
00877 Vertex
00878 source = edge.first;
00879
00880 EdgeId
00881 edge_id = edge.second;
00882
00883 ComponentMap::const_iterator
00884 component_iterator = components.find(source);
00885
00886 size_t vertex_component = (*component_iterator).second;
00887
00888 removeEdge(source, vertex);
00889
00890 Vertex
00891 new_vertex = new_vertices[vertex_component - 1];
00892
00893 std::pair<Edge, bool>
00894 inserted = addEdge(edge_id, source, new_vertex);
00895
00896 assert(inserted.second==true);
00897 }
00898
00899 return new_connectivity;
00900 }
00901
00902
00903
00904
00905
00906 std::map<Entity*, Entity*>
00907 Subgraph::splitArticulationPoint(Vertex vertex,
00908 std::map<EntityKey, bool> & entity_open)
00909 {
00910
00911 EntityKey vertex_key = Subgraph::localToGlobal(vertex);
00912 assert(entity_open[vertex_key]==true);
00913
00914
00915 EntityRank vertex_rank = Subgraph::getVertexRank(vertex);
00916
00917
00918 size_t num_components;
00919 ComponentMap components;
00920 Subgraph::testArticulationPoint(vertex, num_components, components);
00921
00922
00923
00924 std::map<Entity*, Entity*> new_connectivity;
00925
00926
00927
00928 if (num_components == 1) return new_connectivity;
00929
00930
00931
00932 std::vector<Vertex> new_vertex;
00933 for (int i = 0; i < num_components - 1; ++i) {
00934
00935 Vertex new_vert = Subgraph::cloneVertex(vertex);
00936 new_vertex.push_back(new_vert);
00937 }
00938
00939
00940
00941 if (vertex_rank == 0) {
00942 for (ComponentMap::iterator i = components.begin();
00943 i != components.end(); ++i) {
00944 int component_num = (*i).second;
00945 Vertex current_vertex = (*i).first;
00946 EntityRank current_rank = Subgraph::getVertexRank(current_vertex);
00947
00948 if (current_rank == getSpaceDimension() && component_num != 0) {
00949 Entity* element =
00950 getBulkData()->get_entity(Subgraph::localToGlobal(current_vertex));
00951 Entity* new_node =
00952 getBulkData()->
00953 get_entity(Subgraph::localToGlobal(new_vertex[component_num - 1]));
00954 new_connectivity.
00955 insert(std::map<Entity*, Entity*>::value_type(element, new_node));
00956 }
00957 }
00958 }
00959
00960
00961 for (int i = 0; i < new_vertex.size(); ++i) {
00962 Subgraph::cloneOutEdges(vertex, new_vertex[i]);
00963 }
00964
00965
00966
00967 std::vector<std::pair<Vertex, EdgeId> > removed;
00968
00969
00970
00971 InEdgeIterator in_edge_begin;
00972 InEdgeIterator in_edge_end;
00973 boost::tie(in_edge_begin, in_edge_end) = boost::in_edges(vertex, *this);
00974 for (InEdgeIterator i = in_edge_begin; i != in_edge_end; ++i) {
00975 Edge edge = *i;
00976 Vertex source = boost::source(edge, *this);
00977
00978 ComponentMap::const_iterator componentIterator =
00979 components.find(source);
00980 int vertComponent = (*componentIterator).second;
00981 Entity& entity =
00982 *(getBulkData()->get_entity(Subgraph::localToGlobal(source)));
00983
00984 if (vertComponent != 0) {
00985 EdgeId edgeId = Subgraph::getEdgeId(edge);
00986 removed.push_back(std::make_pair(source, edgeId));
00987 }
00988 }
00989
00990
00991 for (std::vector<std::pair<Vertex, EdgeId> >::iterator i = removed.begin();
00992 i != removed.end(); ++i) {
00993 std::pair<Vertex, EdgeId> edge = *i;
00994 Vertex source = edge.first;
00995 EdgeId edgeId = edge.second;
00996 ComponentMap::const_iterator componentIterator =
00997 components.find(source);
00998 int vertComponent = (*componentIterator).second;
00999
01000 Subgraph::removeEdge(source, vertex);
01001 std::pair<Edge, bool> inserted =
01002 Subgraph::addEdge(edgeId, source,new_vertex[vertComponent - 1]);
01003 assert(inserted.second==true);
01004 }
01005
01006
01007 entity_open[vertex_key] = false;
01008
01009 return new_connectivity;
01010 }
01011
01012
01013
01014
01015 void
01016 Subgraph::cloneOutEdges(Vertex old_vertex, Vertex new_vertex)
01017 {
01018
01019 EntityKey
01020 old_key = localToGlobal(old_vertex);
01021
01022 EntityKey
01023 new_key = localToGlobal(new_vertex);
01024
01025 Entity &
01026 old_entity = *(getBulkData()->get_entity(old_key));
01027
01028 Entity &
01029 new_entity = *(getBulkData()->get_entity(new_key));
01030
01031
01032
01033 PairIterRelation
01034 old_relations = old_entity.relations(old_entity.entity_rank() - 1);
01035
01036 for (size_t i = 0; i < old_relations.size(); ++i) {
01037 PairIterRelation
01038 new_relations = new_entity.relations(new_entity.entity_rank() - 1);
01039
01040
01041 bool
01042 exists = false;
01043
01044 for (size_t j = 0; j < new_relations.size(); ++j) {
01045 if (old_relations[i].entity() == new_relations[j].entity()) {
01046 exists = true;
01047 }
01048 }
01049
01050 if (exists == false) {
01051 EdgeId
01052 edge_id = old_relations[i].identifier();
01053
01054 Entity &
01055 target = *(old_relations[i].entity());
01056
01057 getBulkData()->declare_relation(new_entity, target, edge_id);
01058 }
01059 }
01060
01061 return;
01062 }
01063
01079 void Subgraph::outputToGraphviz(std::string & gviz_output,
01080 std::map<EntityKey, bool> entity_open)
01081 {
01082
01083 std::ofstream gviz_out;
01084 gviz_out.open(gviz_output.c_str(), std::ios::out);
01085
01086 std::cout << "Write graph to graphviz dot file\n";
01087
01088 if (gviz_out.is_open()) {
01089
01090 gviz_out << "digraph mesh {\n" << " node [colorscheme=paired12]\n"
01091 << " edge [colorscheme=paired12]\n";
01092
01093 VertexIterator vertex_begin;
01094 VertexIterator vertex_end;
01095 boost::tie(vertex_begin, vertex_end) = vertices(*this);
01096
01097 for (VertexIterator i = vertex_begin; i != vertex_end; ++i) {
01098 EntityKey key = localToGlobal(*i);
01099 Entity & entity = *(getBulkData()->get_entity(key));
01100 std::string label;
01101 std::string color;
01102
01103
01104 switch (entity.entity_rank()) {
01105
01106 case 0:
01107 label = "Node";
01108 if (entity_open[entity.key()] == false)
01109 color = "6";
01110 else
01111 color = "5";
01112 break;
01113
01114 case 1:
01115 label = "Segment";
01116 if (entity_open[entity.key()] == false)
01117 color = "4";
01118 else
01119 color = "3";
01120 break;
01121
01122 case 2:
01123 label = "Face";
01124 if (entity_open[entity.key()] == false)
01125 color = "2";
01126 else
01127 color = "1";
01128 break;
01129
01130 case 3:
01131 label = "Element";
01132 if (entity_open[entity.key()] == false)
01133 color = "8";
01134 else
01135 color = "7";
01136 break;
01137 }
01138 gviz_out << " \"" << entity.identifier() << "_" << entity.entity_rank()
01139 << "\" [label=\" " << label << " " << entity.identifier()
01140 << "\",style=filled,fillcolor=\"" << color << "\"]\n";
01141
01142
01143 OutEdgeIterator out_edge_begin;
01144 OutEdgeIterator out_edge_end;
01145 boost::tie(out_edge_begin, out_edge_end) = out_edges(*i, *this);
01146
01147 for (OutEdgeIterator j = out_edge_begin; j != out_edge_end; ++j) {
01148 Edge out_edge = *j;
01149 Vertex source = boost::source(out_edge, *this);
01150 Vertex target = boost::target(out_edge, *this);
01151
01152 EntityKey sourceKey = localToGlobal(source);
01153 Entity & global_source = *(getBulkData()->get_entity(sourceKey));
01154
01155 EntityKey targetKey = localToGlobal(target);
01156 Entity & global_target = *(getBulkData()->get_entity(targetKey));
01157
01158 EdgeId edgeId = getEdgeId(out_edge);
01159
01160 switch (edgeId) {
01161 case 0:
01162 color = "6";
01163 break;
01164 case 1:
01165 color = "4";
01166 break;
01167 case 2:
01168 color = "2";
01169 break;
01170 case 3:
01171 color = "8";
01172 break;
01173 case 4:
01174 color = "10";
01175 break;
01176 case 5:
01177 color = "12";
01178 break;
01179 default:
01180 color = "9";
01181 }
01182 gviz_out << " \"" << global_source.identifier() << "_"
01183 << global_source.entity_rank() << "\" -> \""
01184 << global_target.identifier() << "_"
01185 << global_target.entity_rank() << "\" [color=\"" << color << "\"]"
01186 << "\n";
01187 }
01188
01189 }
01190
01191
01192 gviz_out << "}";
01193 gviz_out.close();
01194 } else
01195 std::cout << "Unable to open graphviz output file 'output.dot'\n";
01196
01197 return;
01198 }
01199
01200 }