source: src/grid/grid_index_translations.cpp@ 8bec32

Last change on this file since 8bec32 was 6e10f33, checked in by Julian Iseringhausen <isering@…>, 13 years ago

Some work...

  • Property mode set to 100644
File size: 6.9 KB
RevLine 
[fcf7f6]1/*
2 * vmg - a versatile multigrid solver
3 * Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
4 *
5 * vmg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * vmg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
[dfed1c]19/**
20 * @file grid_index_translations.cpp
21 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
22 * @date Tue May 17 11:46:37 2011
23 *
24 * @brief Class to convert different representations of grid
25 * indices.
26 *
27 */
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33#include "base/helper.hpp"
[6e10f33]34#include "comm/comm.hpp"
[8180d8]35#include "grid/grid_double_iterator.hpp"
[dfed1c]36#include "grid/grid_index_translations.hpp"
37#include "grid/grid.hpp"
38#include "grid/multigrid.hpp"
[e85cfd]39#include "mg.hpp"
[dfed1c]40
41using namespace VMG;
42
[8180d8]43bool GridIndexTranslations::IsGridPointOf(const Grid& grid, const Index& index_finest)
[dfed1c]44{
[e85cfd]45 const int max_level = MG::GetSol()->MaxLevel();
46 return index_finest[0] % Helper::intpow(2, max_level - grid.Level()) == 0 &&
47 index_finest[1] % Helper::intpow(2, max_level - grid.Level()) == 0 &&
48 index_finest[2] % Helper::intpow(2, max_level - grid.Level()) == 0;
[dfed1c]49}
50
[8180d8]51Index GridIndexTranslations::LocalToGlobal(const Grid& grid, const Index& index_local)
[dfed1c]52{
[6e10f33]53 return index_local - grid.Local().HaloSize1() + grid.Global().LocalBegin();
[dfed1c]54}
55
[8180d8]56Index GridIndexTranslations::LocalToGlobalFinest(const Grid& grid, const Index& index_local)
[dfed1c]57{
[8180d8]58 return GlobalToGlobalFinest(grid, LocalToGlobal(grid, index_local));
[dfed1c]59}
60
[8180d8]61Index GridIndexTranslations::GlobalToLocal(const Grid& grid, const Index& index_global)
[dfed1c]62{
[6e10f33]63 return index_global - grid.Global().LocalBegin() + grid.Local().HaloSize1();
[dfed1c]64}
65
[8180d8]66Index GridIndexTranslations::GlobalToGlobalFinest(const Grid& grid, const Index& index_global)
[dfed1c]67{
[e85cfd]68 return Helper::intpow(2, MG::GetSol()->MaxLevel() - grid.Level()) * index_global;
[dfed1c]69}
70
[8180d8]71Index GridIndexTranslations::GlobalFinestToLocal(const Grid& grid, const Index& index_finest)
[dfed1c]72{
[8180d8]73 return GlobalToLocal(grid, GlobalFinestToGlobal(grid, index_finest));
[dfed1c]74}
75
[8180d8]76Index GridIndexTranslations::GlobalFinestToGlobal(const Grid& grid, const Index& index_finest)
[dfed1c]77{
[8180d8]78 assert(IsGridPointOf(grid, index_finest));
[e85cfd]79 return index_finest / Helper::intpow(2, MG::GetSol()->MaxLevel() - grid.Level());
[dfed1c]80}
81
[8180d8]82void GridIndexTranslations::GlobalCoarseToFine(Index& begin, Index& end)
[dfed1c]83{
[8180d8]84 for (int j=0; j<3; ++j) {
85 begin[j] = 2 * begin[j];
86 end[j] = 2 * (end[j]-1) + 1;
87 }
[dfed1c]88}
89
[8180d8]90void GridIndexTranslations::GlobalFineToCoarse(Index& begin, Index& end)
[dfed1c]91{
[8180d8]92 for (int j=0; j<3; ++j) {
93 begin[j] = Helper::RoundUpToNextMultiple(begin[j], 2) / 2;
94 end[j] = Helper::RoundDownToNextMultiple(end[j]-1, 2) / 2 + 1;
95 }
[dfed1c]96}
97
[8180d8]98void GridIndexTranslations::GetGridAlignment(const Grid& grid_1, GridIteratorSet& bounds_1,
[e85cfd]99 const Grid& grid_2, GridIteratorSet& bounds_2)
[dfed1c]100{
[6e10f33]101 const Boundary& boundary = MG::GetComm()->BoundaryConditions();
102
[8180d8]103 if (grid_1.Level() == grid_2.Level()) {
[6e10f33]104 Index begin_global = grid_1.Global()
105 .LocalBegin()
106 .Clamp(grid_2.Global().LocalBegin(), grid_2.Global().LocalEnd());
[dfed1c]107
[6e10f33]108 Index end_global = grid_1.Global()
109 .LocalEnd()
110 .Clamp(grid_2.Global().LocalBegin(), grid_2.Global().LocalEnd());
111
112 for (int j=0; j<3; ++j) {
113 if (boundary[j] == Dirichlet || boundary[j] == Open) {
114 if (begin_global[j] == grid_1.Global().GlobalBegin()[j] || begin_global[j] == grid_2.Global().GlobalBegin()[j])
115 begin_global[j] += 1;
116 if (end_global[j] == grid_1.Global().GlobalEnd()[j] || end_global[j] == grid_2.Global().GlobalEnd()[j])
117 end_global[j] -= 1;
118 }
119 }
[dfed1c]120
[8180d8]121 bounds_1 = GridIteratorSet(GlobalToLocal(grid_1, begin_global), GlobalToLocal(grid_2, end_global));
122 bounds_2 = GridIteratorSet(GlobalToLocal(grid_2, begin_global), GlobalToLocal(grid_2, end_global));
[dfed1c]123
[8180d8]124 } else {
[dfed1c]125
[8180d8]126 const Grid& grid_c = (grid_1.Level() < grid_2.Level() ? grid_1 : grid_2);
[e85cfd]127 const int global_mult = Helper::intpow(2, MG::GetSol()->MaxLevel() - grid_c.Level());
[dfed1c]128
[8180d8]129 Index begin_finest = GlobalToGlobalFinest(grid_1, grid_1.Global().LocalBegin())
130 .Clamp(GlobalToGlobalFinest(grid_2, grid_2.Global().LocalBegin()),
131 GlobalToGlobalFinest(grid_2, grid_2.Global().LocalEnd()-1));
[dfed1c]132
[8180d8]133 Index end_finest = GlobalToGlobalFinest(grid_1, grid_1.Global().LocalEnd()-1)
134 .Clamp(GlobalToGlobalFinest(grid_2, grid_2.Global().LocalBegin()),
135 GlobalToGlobalFinest(grid_2, grid_2.Global().LocalEnd()-1));
[dfed1c]136
[8180d8]137 for (int j=0; j<3; ++j) {
138 begin_finest[j] = Helper::RoundUpToNextMultiple(begin_finest[j], global_mult);
139 end_finest[j] = Helper::RoundDownToNextMultiple(end_finest[j], global_mult);
140 }
[dfed1c]141
[6e10f33]142 for (int j=0; j<3; ++j) {
143 if (boundary[j] == Dirichlet || boundary[j] == Open) {
144 if (grid_1.Global().LocalBegin()[j] == grid_1.Global().GlobalBegin()[j] || grid_2.Global().LocalBegin()[j] == grid_2.Global().GlobalBegin()[j])
145 begin_finest[j] += global_mult;
146 if (grid_1.Global().LocalEnd()[j] == grid_1.Global().GlobalEnd()[j] || grid_2.Global().LocalEnd()[j] == grid_2.Global().GlobalEnd()[j])
147 end_finest[j] -= global_mult;
148 }
149 }
150
[8180d8]151 bounds_1 = GridIteratorSet(GlobalFinestToLocal(grid_1, begin_finest), GlobalFinestToLocal(grid_1, end_finest)+1);
152 bounds_2 = GridIteratorSet(GlobalFinestToLocal(grid_2, begin_finest), GlobalFinestToLocal(grid_2, end_finest)+1);
[dfed1c]153
154 }
155}
[6e10f33]156
157void GridIndexTranslations::GetInnerBoundary(const Grid& grid_c, Index& b1_c, Index& b2_c,
158 const Grid& grid_f, Index& b1_f, Index& b2_f)
159{
160 if (grid_f.Global().BoundaryType() == LocallyRefined) {
161
162 const int global_mult = Helper::intpow(2, MG::GetSol()->MaxLevel() - grid_c.Level());
163
164 Index begin_finest = GlobalToGlobalFinest(grid_c, grid_c.Global().LocalBegin())
165 .Clamp(GlobalToGlobalFinest(grid_f, grid_f.Global().LocalBegin()),
166 GlobalToGlobalFinest(grid_f, grid_f.Global().LocalEnd()-1));
167
168 Index end_finest = GlobalToGlobalFinest(grid_c, grid_c.Global().LocalEnd()-1)
169 .Clamp(GlobalToGlobalFinest(grid_f, grid_f.Global().LocalBegin()),
170 GlobalToGlobalFinest(grid_f, grid_f.Global().LocalEnd()-1));
171
172 } else {
173 b1_c = -1;
174 b2_c = -1;
175 b1_f = -1;
176 b2_f = -1;
177 }
178}
Note: See TracBrowser for help on using the repository browser.