source: src/comm/domain_decomposition_mpi.cpp@ f003a9

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

Refactored vmg in order to separate the core library and the particle simulation part properly.

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

  • Property mode set to 100644
File size: 4.4 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 "base/interface.hpp"
16#include "comm/comm.hpp"
17#include "comm/domain_decomposition_mpi.hpp"
18#include "grid/grid.hpp"
19#include "grid/multigrid.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
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();
43 global_l.BoundaryType() = interface->Global()[i].BoundaryType();
44
45 if (IsActive(comm, global_l.GlobalSize(), procs)) {
46
47 if (i == 0) {
48
49 global_l.LocalSize() = global_l.GlobalSize() / procs;
50
51 remainder = global_l.GlobalSize() % procs;
52 for (int j=0; j<3; ++j)
53 if (comm->GlobalPos()[j] < remainder[j])
54 ++(global_l.LocalSize()[j]);
55
56 global_l.LocalBegin() = comm->GlobalPos() * global_l.LocalSize();
57
58 for (int j=0; j<3; ++j)
59 if (comm->GlobalPos()[j] >= remainder[j])
60 global_l.LocalBegin()[j] += remainder[j];
61
62 global_l.LocalEnd() = global_l.LocalBegin() + global_l.LocalSize();
63
64 global_l.LocalFinerBegin() = 0;
65 global_l.LocalFinerEnd() = 0;
66 global_l.LocalFinerSize() = 0;
67
68 }else {
69
70 for (int j=0; j<3; ++j) {
71
72 if (procs[j] == last_procs[j]) {
73
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];
78
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];
83
84 global_l.LocalSize()[j] = global_l.LocalEnd()[j] - global_l.LocalBegin()[j];
85
86 }else {
87
88 global_l.LocalSize()[j] = global_l.GlobalSize()[j] / procs[j];
89
90 remainder[j] = global_l.GlobalSize()[j] % procs[j];
91 if (comm->GlobalPos()[j] < remainder[j])
92 ++(global_l.LocalSize()[j]);
93
94 global_l.LocalBegin()[j] = comm->GlobalPos()[j] * global_l.LocalSize()[j];
95
96 if (comm->GlobalPos()[j] >= remainder[j])
97 global_l.LocalBegin()[j] += remainder[j];
98
99 global_l.LocalEnd()[j] = global_l.LocalBegin()[j] + global_l.LocalSize()[j];
100
101 }
102 }
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
108 }
109
110 }else {
111
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;
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.