Merge lp:~morandini/dolfin/facet-connections into lp:~fenics-core/dolfin/trunk

Proposed by Marco Morandini
Status: Merged
Merge reported by: Garth Wells
Merged at revision: not available
Proposed branch: lp:~morandini/dolfin/facet-connections
Merge into: lp:~fenics-core/dolfin/trunk
Diff against target: 183 lines (+89/-48)
2 files modified
dolfin/mesh/MeshDistributed.cpp (+48/-19)
dolfin/mesh/MeshPartitioning.h (+41/-29)
To merge this branch: bzr merge lp:~morandini/dolfin/facet-connections
Reviewer Review Type Date Requested Status
Garth Wells Approve
Review via email: mp+106203@code.launchpad.net

Description of the change

proposed fix for Bug 928342

To post a comment you must log in.
Revision history for this message
Garth Wells (garth-wells) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dolfin/mesh/MeshDistributed.cpp'
2--- dolfin/mesh/MeshDistributed.cpp 2012-03-01 12:01:06 +0000
3+++ dolfin/mesh/MeshDistributed.cpp 2012-05-17 14:50:21 +0000
4@@ -77,19 +77,40 @@
5 // FIXME: work on optimising below code
6
7 // List of indices to send
8- std::vector<uint> my_entities = entity_indices;
9+ std::vector<uint> my_entities;
10
11 // Remove local cells from my_entities to reduce communication
12 if (dim == D)
13 {
14- std::vector<uint>::iterator it;
15- for (uint i = 0; i < global_entity_indices.size(); ++i)
16- {
17- const uint global_index = global_entity_indices[i];
18- it = std::find(my_entities.begin(), my_entities.end(), global_index);
19- if (it != my_entities.end())
20- my_entities.erase(it);
21- }
22+ // In order to fill vector my_entities...
23+ // build and populate a local set for non-local cells
24+ std::set<uint> set_of_my_entities;
25+ for (uint j = 0; j < entity_indices.size(); j++) {
26+ set_of_my_entities.insert(entity_indices[j]);
27+ }
28+
29+ // Remove local cells from set_of_my_entities to reduce communication
30+ std::set<uint>::iterator it;
31+ for (uint j = 0; j < global_entity_indices.size(); ++j)
32+ {
33+ const uint global_index = global_entity_indices[j];
34+ it = set_of_my_entities.find(global_index);
35+ if (it != set_of_my_entities.end()) {
36+ set_of_my_entities.erase(it);
37+ }
38+ }
39+
40+ //copy entries from set_of_my_entities to my_entities
41+ my_entities.resize(set_of_my_entities.size());
42+ {
43+ uint j = 0;
44+ for (std::set<uint>::iterator it = set_of_my_entities.begin(); it != set_of_my_entities.end(); it++) {
45+ my_entities[j] = *it;
46+ j++;
47+ }
48+ }
49+ } else {
50+ my_entities = entity_indices;
51 }
52
53 // FIXME: handle case when my_entities.empty()
54@@ -114,17 +135,25 @@
55 // Check if this process owns received entities, and if so
56 // store local index
57 std::vector<uint> my_hosted_entities;
58- for (uint j = 0; j < recv_entity_count; ++j)
59 {
60- // Check if this process hosts 'received_entity'
61- const uint received_entity = off_process_entities[j];
62- std::vector<uint>::const_iterator it;
63- it = std::find(global_entity_indices.begin(), global_entity_indices.end(), received_entity);
64- if (it != global_entity_indices.end())
65- {
66- const uint local_index = std::distance(global_entity_indices.begin(), it);
67- my_hosted_entities.push_back(received_entity);
68- my_hosted_entities.push_back(local_index);
69+ // Build a temporary map hosting global_entity_indices
70+ std::map<uint, uint> map_of_global_entity_indices;
71+ for (uint j = 0; j < global_entity_indices.size(); j++)
72+ {
73+ map_of_global_entity_indices[global_entity_indices[j]] = j;
74+ }
75+ for (uint j = 0; j < recv_entity_count; j++)
76+ {
77+ // Check if this process hosts 'received_entity'
78+ const uint received_entity = off_process_entities[j];
79+ std::map<uint, uint>::const_iterator it;
80+ it = map_of_global_entity_indices.find(received_entity);
81+ if (it != map_of_global_entity_indices.end())
82+ {
83+ const uint local_index = it->second;
84+ my_hosted_entities.push_back(received_entity);
85+ my_hosted_entities.push_back(local_index);
86+ }
87 }
88 }
89
90
91=== modified file 'dolfin/mesh/MeshPartitioning.h'
92--- dolfin/mesh/MeshPartitioning.h 2011-11-18 12:14:50 +0000
93+++ dolfin/mesh/MeshPartitioning.h 2012-05-17 14:50:21 +0000
94@@ -216,14 +216,20 @@
95 // Add local (to this process) data to domain marker
96 std::vector<uint>::iterator it;
97 std::vector<uint> off_process_global_cell_entities;
98+ // Build and populate a local map for global_entity_indices
99+ std::map<uint, uint> map_of_global_entity_indices;
100+ for (uint i = 0; i < global_entity_indices.size(); i++) {
101+ map_of_global_entity_indices[global_entity_indices[i]] = i;
102+ }
103+
104 for (uint i = 0; i < ldata.size(); ++i)
105 {
106 const uint global_cell_index = ldata[i].first.first;
107- std::vector<uint>::const_iterator it;
108- it = std::find(global_entity_indices.begin(), global_entity_indices.end(), global_cell_index);
109- if (it != global_entity_indices.end())
110+ std::map<uint, uint>::const_iterator it;
111+ it = map_of_global_entity_indices.find(global_cell_index);
112+ if (it != map_of_global_entity_indices.end())
113 {
114- const uint local_cell_index = std::distance(global_entity_indices.begin(), it);
115+ const uint local_cell_index = it->second;
116 const uint entity_local_index = ldata[i].first.second;
117 const T value = ldata[i].second;
118 markers.set_value(local_cell_index, entity_local_index, value);
119@@ -242,34 +248,40 @@
120 std::vector<uint> destinations0;
121 std::vector<uint> destinations1;
122 std::map<uint, std::set<std::pair<uint, uint> > >::const_iterator entity_host;
123- for (entity_host = entity_hosts.begin(); entity_host != entity_hosts.end(); ++entity_host)
124+
125 {
126- const uint host_global_cell_index = entity_host->first;
127- const std::set<std::pair<uint, uint> >& processes_data = entity_host->second;
128-
129- // Loop over local data
130- for (uint i = 0; i < ldata.size(); ++i)
131+ // Build a convenience map in order to speedup the loop over local data
132+ std::map<uint, std::set<uint> > map_of_ldata;
133+ for (uint i = 0; i < ldata.size(); ++i) {
134+ map_of_ldata[ldata[i].first.first].insert(i);
135+ }
136+ for (entity_host = entity_hosts.begin(); entity_host != entity_hosts.end(); ++entity_host)
137 {
138- const uint local_global_cell_index = ldata[i].first.first;
139- if (local_global_cell_index == host_global_cell_index)
140- {
141- const uint local_entity_index = ldata[i].first.second;
142- const T domain_value = ldata[i].second;
143-
144- std::set<std::pair<uint, uint> >::const_iterator process_data;
145- for (process_data = processes_data.begin(); process_data != processes_data.end(); ++process_data)
146- {
147- const uint proc = process_data->first;
148- const uint local_cell_entity = process_data->second;
149-
150- send_data0.push_back(local_cell_entity);
151- send_data0.push_back(local_entity_index);
152- destinations0.insert(destinations0.end(), 2, proc);
153-
154- send_data1.push_back(domain_value);
155- destinations1.push_back(proc);
156+ const uint host_global_cell_index = entity_host->first;
157+ const std::set<std::pair<uint, uint> >& processes_data = entity_host->second;
158+
159+ // Loop over local data
160+ std::map<uint, std::set<uint> >::const_iterator ldata_it = map_of_ldata.find(host_global_cell_index);
161+ if (ldata_it != map_of_ldata.end()) {
162+ for (std::set<uint>::const_iterator it = ldata_it->second.begin(); it != ldata_it->second.end(); it++) {
163+ const uint local_entity_index = ldata[*it].first.second;
164+ const T domain_value = ldata[*it].second;
165+
166+ std::set<std::pair<uint, uint> >::const_iterator process_data;
167+ for (process_data = processes_data.begin(); process_data != processes_data.end(); ++process_data)
168+ {
169+ const uint proc = process_data->first;
170+ const uint local_cell_entity = process_data->second;
171+
172+ send_data0.push_back(local_cell_entity);
173+ send_data0.push_back(local_entity_index);
174+ destinations0.insert(destinations0.end(), 2, proc);
175+
176+ send_data1.push_back(domain_value);
177+ destinations1.push_back(proc);
178+ }
179 }
180- }
181+ }
182 }
183 }
184

Subscribers

People subscribed via source and target branches