Loading...
Searching...
No Matches
voloctree_mapper_example_00002.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
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
91 std::unique_ptr<PabloUniform> treePointer2 = std::unique_ptr<PabloUniform>(new PabloUniform(x_0, y_0, z_0, l, 2));
92 PabloUniform &octree2 = *treePointer2;
93
95 octree2.adaptGlobalRefine();
96 octree2.adaptGlobalRefine();
97 octree2.adaptGlobalRefine();
98 octree2.adaptGlobalRefine();
99
101 VolOctree *patch_2D = new VolOctree(std::move(treePointer2), &treePointer2);
102
103 patch_2D->initializeAdjacencies();
104 patch_2D->initializeInterfaces();
105
106 patch_2D->update();
107
108#if BITPIT_ENABLE_MPI==1
109 patch_2D->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
110
112 patch_2D->partition(true);
113#endif
114
115 std::srand(0);
116
118 for (int k = 0; k < 4; ++k) {
119 long nCells = patch_2D->getCellCount();
120 log::cout() << std::endl;
121 log::cout() << ">> Marking the cells to adapt... " << std::endl;
122
123 for (int i = 0; i < 100; ++i) {
124 long cellId = rand() % nCells * 2;
125 if (!patch_2D->getCells().exists(cellId)) {
126 continue;
127 }
128
129 patch_2D->markCellForRefinement(cellId);
130 for (auto neighId : patch_2D->findCellNeighs(cellId)) {
131 patch_2D->markCellForRefinement(neighId);
132 }
133 }
134
135 for (int i = 0; i < 50; ++i) {
136 long cellId = rand() % nCells * 2;
137 if (!patch_2D->getCells().exists(cellId)) {
138 continue;
139 }
140
141 patch_2D->markCellForCoarsening(cellId);
142 for (auto neighId : patch_2D->findCellNeighs(cellId)) {
143 patch_2D->markCellForCoarsening(neighId);
144 }
145 }
146
147 log::cout() << std::endl;
148 log::cout() << ">> Initial number of cells... " << nCells << std::endl;
149
150 patch_2D->update();
151
152 nCells = patch_2D->getCellCount();
153 log::cout() << ">> Final number of cells... " << nCells << std::endl;
154 }
155
157 log::cout() << "Cell count: " << patch_2D->getCellCount() << std::endl;
158 log::cout() << "Vertex count: " << patch_2D->getVertexCount() << std::endl;
159
160 patch_2D->getVTK().setName("mesh_random.0");
161#if BITPIT_ENABLE_MPI==1
162 patch_2D->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
163#endif
164 patch_2D->write();
165
167#if BITPIT_ENABLE_MPI==1
168 VolOctreeMapper mapobject(patch_2D_original, patch_2D, patch_2D_original->getCommunicator());
169#else
170 VolOctreeMapper mapobject(patch_2D_original, patch_2D);
171#endif
172
174 mapobject.initialize(true);
175
176 patch_2D_original->getVTK().setName("mesh_original.0");
177#if BITPIT_ENABLE_MPI==1
178 patch_2D_original->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
179#endif
180 patch_2D_original->write();
181
182 std::vector<uint64_t> refineList;
183 refineList.push_back( 7);
184 refineList.push_back( 13);
185 refineList.push_back( 15);
186 refineList.push_back( 26);
187 refineList.push_back( 27);
188 refineList.push_back( 31);
189 refineList.push_back( 37);
190 refineList.push_back( 39);
191 refineList.push_back( 49);
192 refineList.push_back( 50);
193 refineList.push_back( 51);
194 refineList.push_back( 53);
195 refineList.push_back( 55);
196 refineList.push_back( 63);
197 refineList.push_back( 78);
198 refineList.push_back(100);
199 refineList.push_back(102);
200 refineList.push_back(105);
201 refineList.push_back(108);
202 refineList.push_back(109);
203 refineList.push_back(110);
204 refineList.push_back(135);
205 refineList.push_back(141);
206 refineList.push_back(143);
207 refineList.push_back(146);
208 refineList.push_back(147);
209 refineList.push_back(151);
210 refineList.push_back(153);
211 refineList.push_back(154);
212 refineList.push_back(155);
213 refineList.push_back(157);
214 refineList.push_back(159);
215 refineList.push_back(165);
216 refineList.push_back(167);
217 refineList.push_back(183);
218 refineList.push_back(198);
219 refineList.push_back(204);
220 refineList.push_back(206);
221 refineList.push_back(225);
222 refineList.push_back(228);
223 refineList.push_back(229);
224 refineList.push_back(230);
225
226 for (uint64_t ind : refineList) {
227#if BITPIT_ENABLE_MPI==1
228 int owner = patch_2D_original->getTree().getOwnerRank(ind);
229 if (patch_2D_original->getRank() == owner){
230 uint32_t lind = patch_2D_original->getTree().getLocalIdx(ind, owner);
231#else
232 uint32_t lind = patch_2D_original->getTree().getLocalIdx(ind);
233#endif
234 VolOctree::OctantInfo octinfo(lind, true);
235 long id = patch_2D_original->getOctantId(octinfo);
236 patch_2D_original->markCellForRefinement(id);
237#if BITPIT_ENABLE_MPI==1
238 }
239#endif
240 }
241
242 std::vector<adaption::Info> infoAdapt = patch_2D_original->adaptionPrepare(true);
243
244 mapobject.adaptionPrepare(infoAdapt, true);
245
246 infoAdapt = patch_2D_original->adaptionAlter(true);
247
248 mapobject.adaptionAlter(infoAdapt, true, true);
249
250 patch_2D_original->adaptionCleanup();
251
252 mapobject.adaptionCleanup();
253
255 log::cout() << "Cell count: " << patch_2D_original->getCellCount() << std::endl;
256 log::cout() << "Vertex count: " << patch_2D_original->getVertexCount() << std::endl;
257
259 PiercedStorage<double> data(1, &patch_2D_original->getCells());
260 std::vector<double> vdata(patch_2D_original->getInternalCellCount());
261 int count = 0;
262 for (Cell & cell : patch_2D_original->getCells()){
263 if (cell.isInterior()){
264 long id = cell.getId();
265 data[id] = double(patch_2D_original->getCellLevel(id));
266 vdata[count] = data[id];
267 count++;
268 }
269 }
270
271 patch_2D_original->getVTK().setName("mesh_original.0");
272 patch_2D_original->getVTK().addData("data", VTKFieldType::SCALAR, VTKLocation::CELL, vdata);
273#if BITPIT_ENABLE_MPI==1
274 patch_2D_original->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
275#endif
276 patch_2D_original->write();
277
279 PiercedStorage<double> data2(1, &patch_2D->getCells());
280 data2.fill(0.0);
281 {
282 const PiercedStorage<mapping::Info> & mapper = mapobject.getInverseMapping();
283 std::vector<double> vdata2(patch_2D->getInternalCellCount());
284 count = 0;
285 for (Cell & cell : patch_2D->getCells()){
286 if (cell.isInterior()){
287 long id = cell.getId();
288 if (mapper[id].type == mapping::Type::TYPE_RENUMBERING){
289 data2[id] = data[mapper[id].ids[0]];
290 vdata2[count] = data2[id];
291 }
292 else if (mapper[id].type == mapping::Type::TYPE_COARSENING){
293 data2[id] = 0.0;
294 int n = mapper[id].ids.size();
295 for (long idd : mapper[id].ids){
296 data2[id] += data[idd] / n;
297 }
298 vdata2[count] = data2[id];
299 }
300 else if (mapper[id].type == mapping::Type::TYPE_REFINEMENT){
301 data2[id] = data[mapper[id].ids[0]];
302 vdata2[count] = data2[id];
303 }
304 count++;
305 }
306 }
307
308 patch_2D->getVTK().setName("mesh_random.0");
309 patch_2D->getVTK().addData("data", VTKFieldType::SCALAR, VTKLocation::CELL, vdata2);
310 patch_2D->write();
311 patch_2D->getVTK().setName("mesh_random.1");
312 patch_2D->write();
313
314 }
315
317 {
318 const PiercedStorage<mapping::Info> & invmapper = mapobject.getMapping();
319 PiercedStorage<double> data3(1, &patch_2D_original->getCells());
320 std::vector<double> vdata3(patch_2D_original->getInternalCellCount());
321 count = 0;
322 for (Cell & cell : patch_2D_original->getCells()){
323 if (cell.isInterior()){
324 long id = cell.getId();
325 if (invmapper[id].type == mapping::Type::TYPE_RENUMBERING){
326 data3[id] = data2[invmapper[id].ids[0]];
327 vdata3[count] = data3[id];
328 }
329 else if (invmapper[id].type == mapping::Type::TYPE_COARSENING){
330 data3[id] = 0.0;
331 int n = invmapper[id].ids.size();
332 for (long idd : invmapper[id].ids){
333 data3[id] += data2[idd] / n;
334 }
335 vdata3[count] = data3[id];
336 }
337 else if (invmapper[id].type == mapping::Type::TYPE_REFINEMENT){
338 data3[id] = data2[invmapper[id].ids[0]];
339 vdata3[count] = data3[id];
340 }
341 count++;
342 }
343 }
344
345 patch_2D_original->getVTK().setName("mesh_original.1");
346 patch_2D_original->getVTK().addData("data", VTKFieldType::SCALAR, VTKLocation::CELL, vdata3);
347 patch_2D_original->write();
348
349 }
350
351}
352
357int main(int argc, char *argv[])
358{
359#if BITPIT_ENABLE_MPI
360 MPI_Init(&argc,&argv);
361#endif
362
364 try {
365 run();
366 } catch (const std::exception &exception) {
367 log::cout() << exception.what();
368 exit(1);
369 }
370
371#if BITPIT_ENABLE_MPI
372 MPI_Finalize();
373#endif
374
375}
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
std::vector< adaption::Info > adaptionPrepare(bool trackAdaption=true)
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
std::vector< adaption::Info > adaptionAlter(bool trackAdaption=true, bool squeezeStorage=false)
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 ---