source: src/comm/domain_decomposition_mpi.cpp@ ac6d04

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

Merge recent changes of the vmg library into ScaFaCos.

Includes a fix for the communication problems on Jugene.

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

  • Property mode set to 100644
File size: 4.4 KB
RevLine 
[dfed1c]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 last_procs = comm->GlobalProcs();
28
29 global.clear();
30
31 for (unsigned int i=0; i<interface->Global().size(); ++i) {
32
[ac6d04]33 /*
34 * Inherit global properties from interface
35 */
36 global_l.GlobalFinerBegin() = interface->Global()[i].GlobalFinerBegin();
37 global_l.GlobalFinerEnd() = interface->Global()[i].GlobalFinerEnd();
38 global_l.GlobalFinerSize() = interface->Global()[i].GlobalFinerSize();
39 global_l.FinestAbsBegin() = interface->Global()[i].FinestAbsBegin();
40 global_l.FinestAbsEnd() = interface->Global()[i].FinestAbsEnd();
41 global_l.FinestAbsSize() = interface->Global()[i].FinestAbsSize();
42 global_l.GlobalSize() = interface->Global()[i].GlobalSize();
[dfed1c]43 global_l.BoundaryType() = interface->Global()[i].BoundaryType();
44
[ac6d04]45 if (IsActive(comm, global_l.GlobalSize(), procs)) {
[dfed1c]46
47 if (i == 0) {
48
[ac6d04]49 global_l.LocalSize() = global_l.GlobalSize() / procs;
[dfed1c]50
[ac6d04]51 remainder = global_l.GlobalSize() % procs;
[dfed1c]52 for (int j=0; j<3; ++j)
53 if (comm->GlobalPos()[j] < remainder[j])
[ac6d04]54 ++(global_l.LocalSize()[j]);
[dfed1c]55
[ac6d04]56 global_l.LocalBegin() = comm->GlobalPos() * global_l.LocalSize();
[dfed1c]57
58 for (int j=0; j<3; ++j)
59 if (comm->GlobalPos()[j] >= remainder[j])
[ac6d04]60 global_l.LocalBegin()[j] += remainder[j];
61
62 global_l.LocalEnd() = global_l.LocalBegin() + global_l.LocalSize();
[dfed1c]63
[ac6d04]64 global_l.LocalFinerBegin() = 0;
65 global_l.LocalFinerEnd() = 0;
66 global_l.LocalFinerSize() = 0;
[dfed1c]67
68 }else {
69
70 for (int j=0; j<3; ++j) {
71
72 if (procs[j] == last_procs[j]) {
73
[ac6d04]74 if (global.back().LocalBegin()[j] == 0)
75 global_l.LocalBegin()[j] = 0;
76 else
77 global_l.LocalBegin()[j] = global.back().LocalBegin()[j] / 2 + global_l.GlobalFinerBegin()[j];
[dfed1c]78
[ac6d04]79 if (global.back().LocalEnd()[j] == global.back().GlobalSize()[j])
80 global_l.LocalEnd()[j] = global_l.GlobalSize()[j];
81 else
82 global_l.LocalEnd()[j] = global.back().LocalEnd()[j] / 2 + global_l.GlobalFinerBegin()[j];
[dfed1c]83
[ac6d04]84 global_l.LocalSize()[j] = global_l.LocalEnd()[j] - global_l.LocalBegin()[j];
[dfed1c]85
86 }else {
87
[ac6d04]88 global_l.LocalSize()[j] = global_l.GlobalSize()[j] / procs[j];
[dfed1c]89
[ac6d04]90 remainder[j] = global_l.GlobalSize()[j] % procs[j];
[dfed1c]91 if (comm->GlobalPos()[j] < remainder[j])
[ac6d04]92 ++(global_l.LocalSize()[j]);
[dfed1c]93
[ac6d04]94 global_l.LocalBegin()[j] = comm->GlobalPos()[j] * global_l.LocalSize()[j];
[dfed1c]95
96 if (comm->GlobalPos()[j] >= remainder[j])
[ac6d04]97 global_l.LocalBegin()[j] += remainder[j];
[dfed1c]98
[ac6d04]99 global_l.LocalEnd()[j] = global_l.LocalBegin()[j] + global_l.LocalSize()[j];
[dfed1c]100
101 }
102 }
[ac6d04]103
104 global_l.LocalFinerBegin() = global_l.LocalBegin().Clamp(global_l.GlobalFinerBegin(), global_l.GlobalFinerEnd());
105 global_l.LocalFinerEnd() = global_l.LocalEnd().Clamp(global_l.GlobalFinerBegin(), global_l.GlobalFinerEnd());
106 global_l.LocalFinerSize() = global_l.LocalFinerEnd() - global_l.LocalFinerBegin();
107
[dfed1c]108 }
[ac6d04]109
[dfed1c]110 }else {
111
[ac6d04]112 global_l.LocalBegin() = 0;
113 global_l.LocalEnd() = 0;
114 global_l.LocalSize() = 0;
115 global_l.LocalFinerBegin() = 0;
116 global_l.LocalFinerEnd() = 0;
117 global_l.LocalFinerSize() = 0;
[dfed1c]118
119 }
120
121 last_procs = procs;
122
123 global.push_back(global_l);
124
125 }
126}
127
128bool DomainDecompositionMPI::IsActive(Comm* comm, const Index& size_global, Index& procs)
129{
130 bool is_active = true;
131 const int points_min = 5;
132
133 procs = size_global / points_min + 1;
134
135 for (int i=0; i<3; ++i) {
136 procs[i] = std::min(procs[i], comm->GlobalProcs()[i]);
137 is_active &= comm->GlobalPos()[i] < procs[i];
138 }
139
140 return is_active;
141}
142
143void DomainDecompositionMPI::FineToCoarse(Comm* comm, int& begin, int& end, int levels)
144{
145 int last_point = end - 1;
146
147 for (int i=0; i<levels; ++i) {
148
149 if (begin % 2 == 0)
150 begin /= 2;
151 else
152 begin = (begin+1) / 2;
153
154 if (last_point % 2 == 0)
155 last_point /= 2;
156 else
157 last_point = (last_point-1) / 2;
158
159 }
160
161end = last_point + 1;
162}
Note: See TracBrowser for help on using the repository browser.