Loading...
Searching...
No Matches
voloctree_mapper_example_00001.cpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
32#include <array>
33#if BITPIT_ENABLE_MPI==1
34#include <mpi.h>
35#endif
36
37#include "bitpit_POD.hpp"
38#include "bitpit_patchkernel.hpp"
39#include "bitpit_voloctree.hpp"
40
41using namespace bitpit;
42using namespace pod;
43
47void run()
48{
49
50 log::cout() << " >> 2D octree patch" << "\n";
51
55 double x_0 = 10.;
56 double y_0 = 20.;
57 double z_0 = 30.;
58 double l = 1.5;
59
60 std::unique_ptr<PabloUniform> treePointer = std::unique_ptr<PabloUniform>(new PabloUniform(x_0, y_0, z_0, l, 2));
61 PabloUniform &octree = *treePointer;
62
63 std::cout << " Origin : ( " << octree.getX0() << ", " << octree.getY0() << ", " << octree.getZ0() << " )" << std::endl;
64 std::cout << " Length : " << octree.getL() << std::endl;
65
67 octree.adaptGlobalRefine();
68 octree.adaptGlobalRefine();
69 octree.adaptGlobalRefine();
70 octree.adaptGlobalRefine();
71
76 VolOctree *patch_2D_original = new VolOctree(std::move(treePointer), &treePointer);
77
78 patch_2D_original->initializeAdjacencies();
79 patch_2D_original->initializeInterfaces();
80
81 patch_2D_original->update();
82
83#if BITPIT_ENABLE_MPI==1
85 patch_2D_original->partition(true);
86#endif
87
88 std::vector<uint64_t> refineList;
89 refineList.push_back( 7);
90 refineList.push_back( 13);
91 refineList.push_back( 15);
92 refineList.push_back( 26);
93 refineList.push_back( 27);
94 refineList.push_back( 31);
95 refineList.push_back( 37);
96 refineList.push_back( 39);
97 refineList.push_back( 49);
98 refineList.push_back( 50);
99 refineList.push_back( 51);
100 refineList.push_back( 53);
101 refineList.push_back( 55);
102 refineList.push_back( 63);
103 refineList.push_back( 78);
104 refineList.push_back(100);
105 refineList.push_back(102);
106 refineList.push_back(105);
107 refineList.push_back(108);
108 refineList.push_back(109);
109 refineList.push_back(110);
110 refineList.push_back(135);
111 refineList.push_back(141);
112 refineList.push_back(143);
113 refineList.push_back(146);
114 refineList.push_back(147);
115 refineList.push_back(151);
116 refineList.push_back(153);
117 refineList.push_back(154);
118 refineList.push_back(155);
119 refineList.push_back(157);
120 refineList.push_back(159);
121 refineList.push_back(165);
122 refineList.push_back(167);
123 refineList.push_back(183);
124 refineList.push_back(198);
125 refineList.push_back(204);
126 refineList.push_back(206);
127 refineList.push_back(225);
128 refineList.push_back(228);
129 refineList.push_back(229);
130 refineList.push_back(230);
131
132 for (uint64_t ind : refineList) {
133#if BITPIT_ENABLE_MPI==1
134 int owner = patch_2D_original->getTree().getOwnerRank(ind);
135 if (patch_2D_original->getRank() == owner){
136 uint32_t lind = patch_2D_original->getTree().getLocalIdx(ind, owner);
137#else
138 uint32_t lind = patch_2D_original->getTree().getLocalIdx(ind);
139#endif
140 VolOctree::OctantInfo octinfo(lind, true);
141 long id = patch_2D_original->getOctantId(octinfo);
142 patch_2D_original->markCellForRefinement(id);
143#if BITPIT_ENABLE_MPI==1
144 }
145#endif
146 }
147
148 patch_2D_original->update();
149
151 log::cout() << "Cell count: " << patch_2D_original->getCellCount() << std::endl;
152 log::cout() << "Vertex count: " << patch_2D_original->getVertexCount() << std::endl;
153
155 PiercedStorage<double> data(1, &patch_2D_original->getCells());
156 std::vector<double> vdata(patch_2D_original->getInternalCellCount());
157 int count = 0;
158 for (Cell & cell : patch_2D_original->getCells()){
159 if (cell.isInterior()){
160 long id = cell.getId();
161 data[id] = double(patch_2D_original->getCellLevel(id));
162 vdata[count] = data[id];
163 count++;
164 }
165 }
166
167 patch_2D_original->getVTK().setName("mesh_original.0");
168 patch_2D_original->getVTK().addData("data", VTKFieldType::SCALAR, VTKLocation::CELL, vdata);
169#if BITPIT_ENABLE_MPI==1
170 patch_2D_original->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
171#endif
172 patch_2D_original->write();
173
177 std::unique_ptr<PabloUniform> treePointer2 = std::unique_ptr<PabloUniform>(new PabloUniform(x_0, y_0, z_0, l, 2));
178 PabloUniform &octree2 = *treePointer2;
179
181 octree2.adaptGlobalRefine();
182 octree2.adaptGlobalRefine();
183 octree2.adaptGlobalRefine();
184 octree2.adaptGlobalRefine();
185
187 VolOctree *patch_2D = new VolOctree(std::move(treePointer2), &treePointer2);
188
189 patch_2D->initializeAdjacencies();
190 patch_2D->initializeInterfaces();
191
192#if BITPIT_ENABLE_MPI==1
193 patch_2D->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
194
196 patch_2D->partition(true);
197#endif
198
200 for (int k = 0; k < 4; ++k) {
201 long nCells = patch_2D->getCellCount();
202 log::cout() << std::endl;
203 log::cout() << ">> Marking the cells to adapt... " << std::endl;
204
205 for (int i = 0; i < 100; ++i) {
206 long cellId = rand() % nCells * 2;
207 if (!patch_2D->getCells().exists(cellId)) {
208 continue;
209 }
210
211 for (auto neighId : patch_2D->findCellNeighs(cellId)) {
212 patch_2D->markCellForRefinement(neighId);
213 }
214 }
215
216 for (int i = 0; i < 50; ++i) {
217 long cellId = rand() % nCells * 2;
218 if (!patch_2D->getCells().exists(cellId)) {
219 continue;
220 }
221
222 patch_2D->markCellForCoarsening(cellId);
223 for (auto neighId : patch_2D->findCellNeighs(cellId)) {
224 patch_2D->markCellForCoarsening(neighId);
225 }
226 }
227
228 log::cout() << std::endl;
229 log::cout() << ">> Initial number of cells... " << nCells << std::endl;
230
231 patch_2D->update();
232
233 nCells = patch_2D->getCellCount();
234 log::cout() << ">> Final number of cells... " << nCells << std::endl;
235 }
236
238 log::cout() << "Cell count: " << patch_2D->getCellCount() << std::endl;
239 log::cout() << "Vertex count: " << patch_2D->getVertexCount() << std::endl;
240
242#if BITPIT_ENABLE_MPI==1
243 VolOctreeMapper mapobject(patch_2D, patch_2D_original, patch_2D->getCommunicator());
244#else
245 VolOctreeMapper mapobject(patch_2D, patch_2D_original);
246#endif
247
249 mapobject.initialize(true);
250
252 PiercedStorage<double> data2(1, &patch_2D->getCells());
253 {
254 const PiercedStorage<mapping::Info> & mapper = mapobject.getMapping();
255 std::vector<double> vdata2(patch_2D->getInternalCellCount());
256 count = 0;
257 for (Cell & cell : patch_2D->getCells()){
258 if (cell.isInterior()){
259 long id = cell.getId();
260 if (mapper[id].type == mapping::Type::TYPE_RENUMBERING){
261 data2[id] = data[mapper[id].ids[0]];
262 vdata2[count] = data2[id];
263 }
264 else if (mapper[id].type == mapping::Type::TYPE_COARSENING){
265 data2[id] = 0.0;
266 int n = mapper[id].ids.size();
267 for (long idd : mapper[id].ids){
268 data2[id] += data[idd] / n;
269 }
270 vdata2[count] = data2[id];
271 }
272 else if (mapper[id].type == mapping::Type::TYPE_REFINEMENT){
273 data2[id] = data[mapper[id].ids[0]];
274 vdata2[count] = data2[id];
275 }
276 count++;
277 }
278 }
279
280 patch_2D->getVTK().setName("mesh_random.0");
281 patch_2D->getVTK().addData("data", VTKFieldType::SCALAR, VTKLocation::CELL, vdata2);
282 patch_2D->write();
283 patch_2D->getVTK().setName("mesh_random.1");
284 patch_2D->write();
285
286 }
287
289 {
290 const PiercedStorage<mapping::Info> & invmapper = mapobject.getInverseMapping();
291 PiercedStorage<double> data3(1, &patch_2D_original->getCells());
292 std::vector<double> vdata3(patch_2D_original->getInternalCellCount());
293 count = 0;
294 for (Cell & cell : patch_2D_original->getCells()){
295 if (cell.isInterior()){
296 long id = cell.getId();
297 if (invmapper[id].type == mapping::Type::TYPE_RENUMBERING){
298 data3[id] = data2[invmapper[id].ids[0]];
299 vdata3[count] = data3[id];
300 }
301 else if (invmapper[id].type == mapping::Type::TYPE_COARSENING){
302 data3[id] = 0.0;
303 int n = invmapper[id].ids.size();
304 for (long idd : invmapper[id].ids){
305 data3[id] += data2[idd] / n;
306 }
307 vdata3[count] = data3[id];
308 }
309 else if (invmapper[id].type == mapping::Type::TYPE_REFINEMENT){
310 data3[id] = data2[invmapper[id].ids[0]];
311 vdata3[count] = data3[id];
312 }
313 count++;
314 }
315 }
316
317 patch_2D_original->getVTK().setName("mesh_original.1");
318 patch_2D_original->getVTK().addData("data", VTKFieldType::SCALAR, VTKLocation::CELL, vdata3);
319 patch_2D_original->write();
320
321 }
322
323}
324
329int main(int argc, char *argv[])
330{
331#if BITPIT_ENABLE_MPI==1
332 MPI_Init(&argc,&argv);
333#endif
334
336 try {
337 run();
338 } catch (const std::exception &exception) {
339 log::cout() << exception.what();
340 exit(1);
341 }
342
343#if BITPIT_ENABLE_MPI==1
344 MPI_Finalize();
345#endif
346
347}
The Cell class defines the cells.
Definition cell.hpp:42
PABLO Uniform is an example of user class derived from ParaTree to map ParaTree in a uniform (square/...
uint32_t getLocalIdx(uint64_t gidx) const
bool adaptGlobalRefine(bool mapper_flag=false)
int getOwnerRank(uint64_t globalIdx) const
void initializeAdjacencies(AdjacenciesBuildStrategy strategy=ADJACENCIES_AUTOMATIC)
void markCellForRefinement(long id)
std::vector< adaption::Info > update(bool trackAdaption=true, bool squeezeStorage=false)
PiercedVector< Cell > & getCells()
virtual long getVertexCount() const
VTKUnstructuredGrid & getVTK()
std::vector< adaption::Info > partition(MPI_Comm communicator, const std::unordered_map< long, int > &cellRanks, bool trackPartitioning, bool squeezeStorage=false, std::size_t haloSize=1)
void markCellForCoarsening(long id)
const MPI_Comm & getCommunicator() const
void initializeInterfaces(InterfacesBuildStrategy strategy=INTERFACES_AUTOMATIC)
void setVTKWriteTarget(WriteTarget targetCells)
virtual long getCellCount() const
void write(VTKWriteMode mode=VTKWriteMode::DEFAULT)
long getInternalCellCount() const
Metafunction for generating a pierced storage.
VTKField & addData(VTKField &&field)
Definition VTK.cpp:281
void setName(const std::string &)
Definition VTK.cpp:119
The VolOctreeMapper is the class to map two meshes of class VolOctree.
The VolOctree defines a Octree patch.
Definition voloctree.hpp:37
int getCellLevel(long id) const
PabloUniform & getTree()
Gets a reference to the octree associated with the patch.
long getOctantId(const OctantInfo &octantInfo) const
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
Definition logger.cpp:1705
--- layout: doxygen_footer ---