OpenLB 1.7
Loading...
Searching...
No Matches
cuboidGeometryMinimizer.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2007, 2014 Mathias J. Krause
4 * 2022 Adrian Kummerlaender
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
25#ifndef CUBOID_GEOMETRY_MINIMIZER_H
26#define CUBOID_GEOMETRY_MINIMIZER_H
27
28namespace olb {
29
30template <typename T> class CuboidGeometry3D;
31template <typename T> class IndicatorF3D;
32template <typename T> class Cuboid3D;
33
35template <typename T>
37{
38 cGeometry.shrink(indicatorF);
39
40 while (cGeometry.getNc() < nC) {
41 // Search for the largest child cuboid
42 T iCVolume[cGeometry.getNc()];
43 int maxiC = 0;
44 for (int iC = 0; iC < cGeometry.getNc(); iC++) {
45 iCVolume[iC] = cGeometry.get(iC).getLatticeVolume();
46 if ( iCVolume[iC] > iCVolume[maxiC] ) {
47 maxiC = iC;
48 }
49 }
50
51 // looking for largest extend, because halfing the cuboid by its largest extend will result in the smallest surface and therfore in the least comminication cells
52 auto& largest = cGeometry.get(maxiC);
53 if (largest.getNx() >= largest.getNy() && largest.getNx() >= largest.getNz()) {
54 // clout << "Cut in x direction!" << std::endl;
55 largest.divide(2,1,1, cGeometry.cuboids());
56 }
57 else if (largest.getNy() >= largest.getNx() && largest.getNy() >= largest.getNz()) {
58 // clout << "Cut in y direction!" << std::endl;
59 largest.divide(1,2,1, cGeometry.cuboids());
60 }
61 else {
62 // clout << "Cut in z direction!" << std::endl;
63 largest.divide(1,1,2, cGeometry.cuboids());
64 }
65 cGeometry.remove(maxiC);
66 // shrink the two new cuboids
67 cGeometry.shrink(cGeometry.cuboids().size()-2, indicatorF);
68 cGeometry.shrink(cGeometry.cuboids().size()-1, indicatorF);
69 }
70}
71
73template <typename T>
74void minimizeByVolume(CuboidGeometry3D<T>& cGeometry, IndicatorF3D<T>& indicatorF, int nC)
75{
76 // Search for the largest multiplier not dividable by two
77 int initalNc = nC;
78 while ( initalNc % 2 == 0 ) {
79 initalNc /= 2;
80 }
81
82 // Split evenly in initalNc many cuboids and shrink all
83 cGeometry.split(0, initalNc);
84 cGeometry.shrink(indicatorF);
85
86 continueMinimizeByVolume(cGeometry, indicatorF, nC);
87}
88
89template <typename T>
90void minimizeByWeight(CuboidGeometry3D<T>& cGeometry, IndicatorF3D<T>& indicatorF, int nC)
91{
92 cGeometry.setWeights(indicatorF);
93
94 // conduct a prime factorisation for the number of cuboids nC
95 std::vector<int> factors;
96 int initalNc = nC;
97 // iterate over the prime numbes from 0 to 100 (may have to be extended)
98 for (int i : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71}) {
99 while (initalNc % i == 0) {
100 initalNc /= i;
101 factors.push_back(i);
102 }
103 }
104
105 // recursively split the current cuboids by each prime factor
106 for (int i = factors.size() - 1; i >= 0; i--) {
107 int currentNc = cGeometry.cuboids().size();
108 for (int iC = 0; iC < currentNc; iC++) {
109 // clout << "split cuboid number #" << iC << " in " << factors[i] << " parts" << std::endl;
110 cGeometry.splitByWeight(iC, factors[i], indicatorF);
111 cGeometry.shrink(indicatorF);
112 }
113 for (int iC = 0; iC < currentNc; iC++) {
114 // clout << "delet cuboid number #" << iC << std::endl;
115 cGeometry.remove(0);
116 }
117 }
118}
119
120}
121
122#endif
A cuboid geometry represents a voxel mesh.
void splitByWeight(int iC, int p, IndicatorF3D< T > &indicatorF)
Splits cuboid iC, removes it and adds p cuboids of same weight.
Cuboid3D< T > & get(int iC)
Read and write access to a single cuboid.
void shrink(int iC, IndicatorF3D< T > &indicatorF)
Shrink cuboid iC so that no empty planes are left.
std::vector< Cuboid3D< T > > & cuboids()
void split(int iC, int p)
Splits cuboid iC, removes it and adds p cuboids of same volume.
void remove(int iC)
Removes the cuboid iC.
int getNc() const
Returns the number of cuboids in the structure.
void setWeights(IndicatorF3D< T > &indicatorF)
Sets the number of full cells of each cuboid.
IndicatorF3D is an application from .
Top level namespace for all of OpenLB.
void minimizeByVolume(CuboidGeometry3D< T > &cGeometry, IndicatorF3D< T > &indicatorF, int nC)
Splits into nC cuboids by-volume.
void continueMinimizeByVolume(CuboidGeometry3D< T > &cGeometry, IndicatorF3D< T > &indicatorF, int nC)
Splits largest cuboid by-volume until there are nC cuboids.
void minimizeByWeight(CuboidGeometry3D< T > &cGeometry, IndicatorF3D< T > &indicatorF, int nC)