source: src/comm/domain_decomposition_mpi.cpp@ dfed1c

Last change on this file since dfed1c was dfed1c, checked in by Julian Iseringhausen <isering@…>, 14 years ago

Major vmg update.

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@1136 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/**
2 * @file domain_decomposition_mpi.cpp
3 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
4 * @date Mon Jun 27 12:53:50 2011
5 *
6 * @brief Computes a domain decomposition which separates
7 * the finest grid equally for all processes.
8 *
9 */
10
11#ifdef HAVE_CONFIG_H
12#include <config.h>
13#endif
14
15#include "comm/comm.hpp"
16#include "comm/domain_decomposition_mpi.hpp"
17#include "grid/grid.hpp"
18#include "grid/multigrid.hpp"
19#include "interface/interface.hpp"
20
21using namespace VMG;
22
23void DomainDecompositionMPI::Compute(Comm* comm, const Interface* interface, std::vector<GlobalIndices>& global)
24{
25 GlobalIndices global_l;
26 Index remainder, procs;
27 Index begin_finest, end_finest;
28 Index last_procs = comm->GlobalProcs();
29
30 global.clear();
31
32 for (unsigned int i=0; i<interface->Global().size(); ++i) {
33
34 global_l.BeginFinest() = interface->Global()[i].BeginFinest();
35 global_l.EndFinest() = interface->Global()[i].EndFinest();
36 global_l.SizeFinest() = interface->Global()[i].SizeFinest();
37 global_l.SizeGlobal() = interface->Global()[i].SizeGlobal();
38
39 global_l.BoundaryType() = interface->Global()[i].BoundaryType();
40
41 if (IsActive(comm, global_l.SizeGlobal(), procs)) {
42
43 if (i == 0) {
44
45 global_l.SizeLocal() = global_l.SizeGlobal() / procs;
46 remainder = global_l.SizeGlobal() % procs;
47
48 for (int j=0; j<3; ++j)
49 if (comm->GlobalPos()[j] < remainder[j])
50 ++(global_l.SizeLocal()[j]);
51
52 global_l.BeginLocal() = comm->GlobalPos() * global_l.SizeLocal();
53
54 for (int j=0; j<3; ++j)
55 if (comm->GlobalPos()[j] >= remainder[j])
56 global_l.BeginLocal()[j] += remainder[j];
57
58 global_l.EndLocal() = global_l.BeginLocal() + global_l.SizeLocal();
59
60 }else {
61
62 for (int j=0; j<3; ++j) {
63
64 if (procs[j] == last_procs[j]) {
65
66 begin_finest[j] = (global.back().BeginFinest() +
67 GridIndexTranslations::GlobalToFiner(global.back().BeginLocal(), i-1))[j];
68 end_finest[j] = (global.back().BeginFinest() +
69 GridIndexTranslations::GlobalToFiner(global.back().EndLocal(), i-1))[j];
70
71 if (global.back().BeginLocal()[j] == 0)
72 begin_finest[j] = global_l.BeginFinest()[j];
73
74 if (global.back().EndLocal()[j] == global.back().SizeGlobal()[j])
75 end_finest[j] = global_l.EndFinest()[j];
76
77 begin_finest[j] -= global_l.BeginFinest()[j];
78 end_finest[j] -= global_l.BeginFinest()[j];
79
80 FineToCoarse(comm, begin_finest[j], end_finest[j], i);
81
82 global_l.BeginLocal()[j] = begin_finest[j];
83 global_l.EndLocal()[j] = end_finest[j];
84 global_l.SizeLocal()[j] = end_finest[j] - begin_finest[j];
85
86 }else {
87
88 global_l.SizeLocal()[j] = global_l.SizeGlobal()[j] / procs[j];
89 remainder[j] = global_l.SizeGlobal()[j] % procs[j];
90
91
92 if (comm->GlobalPos()[j] < remainder[j])
93 ++(global_l.SizeLocal()[j]);
94
95 global_l.BeginLocal()[j] = comm->GlobalPos()[j] * global_l.SizeLocal()[j];
96
97
98 if (comm->GlobalPos()[j] >= remainder[j])
99 global_l.BeginLocal()[j] += remainder[j];
100
101 global_l.EndLocal()[j] = global_l.BeginLocal()[j] + global_l.SizeLocal()[j];
102
103 }
104 }
105 }
106 }else {
107
108 global_l.BeginLocal() = 0;
109 global_l.EndLocal() = 0;
110 global_l.SizeLocal() = 0;
111
112 }
113
114 last_procs = procs;
115
116 global.push_back(global_l);
117
118 }
119}
120
121bool DomainDecompositionMPI::IsActive(Comm* comm, const Index& size_global, Index& procs)
122{
123 bool is_active = true;
124 const int points_min = 5;
125
126 procs = size_global / points_min + 1;
127
128 for (int i=0; i<3; ++i) {
129 procs[i] = std::min(procs[i], comm->GlobalProcs()[i]);
130 is_active &= comm->GlobalPos()[i] < procs[i];
131 }
132
133 return is_active;
134}
135
136void DomainDecompositionMPI::FineToCoarse(Comm* comm, int& begin, int& end, int levels)
137{
138 int last_point = end - 1;
139
140 for (int i=0; i<levels; ++i) {
141
142 if (begin % 2 == 0)
143 begin /= 2;
144 else
145 begin = (begin+1) / 2;
146
147 if (last_point % 2 == 0)
148 last_point /= 2;
149 else
150 last_point = (last_point-1) / 2;
151
152 }
153
154end = last_point + 1;
155}
Note: See TracBrowser for help on using the repository browser.