Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/geomsearch.cpp
3206 views
1
#include <mystdlib.h>
2
#include "meshing.hpp"
3
4
5
namespace netgen
6
{
7
GeomSearch3d :: GeomSearch3d()
8
{
9
size.i1 = 0; size.i2 = 0; size.i3 = 0;
10
};
11
12
GeomSearch3d :: ~GeomSearch3d()
13
{
14
//delete old Hashtable:
15
if (size.i1 != 0)
16
{
17
for (int i = 0; i < size.i1*size.i2*size.i3; i++)
18
delete hashtable[i];
19
}
20
}
21
22
void GeomSearch3d :: Init (ARRAY <FrontPoint3,PointIndex::BASE> *pointsi, ARRAY <FrontFace> *facesi)
23
{
24
points = pointsi;
25
faces = facesi;
26
size.i1 = 0; size.i2 = 0; size.i3 = 0;
27
reset = 1;
28
hashcount = 1;
29
}
30
31
void GeomSearch3d :: ElemMaxExt(Point3d& minp, Point3d& maxp, const MiniElement2d& elem)
32
{
33
maxp.X()=(*points)[elem.PNum(1)].P()(0);
34
maxp.Y()=(*points)[elem.PNum(1)].P()(1);
35
maxp.Z()=(*points)[elem.PNum(1)].P()(2);
36
minp.X()=(*points)[elem.PNum(1)].P()(0);
37
minp.Y()=(*points)[elem.PNum(1)].P()(1);
38
minp.Z()=(*points)[elem.PNum(1)].P()(2);
39
40
for (int i=2; i <= 3; i++)
41
{
42
maxp.X()=max2((*points)[elem.PNum(i)].P()(0),maxp.X());
43
maxp.Y()=max2((*points)[elem.PNum(i)].P()(1),maxp.Y());
44
maxp.Z()=max2((*points)[elem.PNum(i)].P()(2),maxp.Z());
45
minp.X()=min2((*points)[elem.PNum(i)].P()(0),minp.X());
46
minp.Y()=min2((*points)[elem.PNum(i)].P()(1),minp.Y());
47
minp.Z()=min2((*points)[elem.PNum(i)].P()(2),minp.Z());
48
}
49
}
50
51
void GeomSearch3d :: MinCoords(const Point3d& p1, Point3d& p2)
52
{
53
p2.X()=min2(p1.X(),p2.X());
54
p2.Y()=min2(p1.Y(),p2.Y());
55
p2.Z()=min2(p1.Z(),p2.Z());
56
}
57
58
void GeomSearch3d :: MaxCoords(const Point3d& p1, Point3d& p2)
59
{
60
p2.X()=max2(p1.X(),p2.X());
61
p2.Y()=max2(p1.Y(),p2.Y());
62
p2.Z()=max2(p1.Z(),p2.Z());
63
}
64
65
void GeomSearch3d :: Create()
66
{
67
INDEX i,j,k;
68
if (reset)
69
{
70
const double hashelemsizefactor = 4;
71
reset = 0;
72
/*
73
minext=Point3d(MAXDOUBLE, MAXDOUBLE, MAXDOUBLE);
74
maxext=Point3d(MINDOUBLE, MINDOUBLE, MINDOUBLE);
75
*/
76
ElemMaxExt(minext, maxext, faces->Get(1).Face());
77
Point3d maxp, minp;
78
Vec3d midext(0,0,0);
79
80
//get max Extension of Frontfaces
81
for (i = 1; i <= faces->Size(); i++)
82
{
83
ElemMaxExt(minp, maxp, faces->Get(i).Face());
84
MinCoords(minp, minext);
85
MaxCoords(maxp, maxext);
86
midext+=maxp-minp;
87
}
88
89
90
maxextreal = maxext;
91
maxext = maxext + 1e-4 * (maxext - minext);
92
93
midext*=1./faces->Size();
94
Vec3d boxext = maxext - minext;
95
96
//delete old Hashtable:
97
if (size.i1 != 0)
98
{
99
for (i = 1; i <= size.i1*size.i2*size.i3; i++)
100
{
101
delete hashtable.Get(i);
102
}
103
}
104
105
size.i1 = int (boxext.X()/midext.X()/hashelemsizefactor+1);
106
size.i2 = int (boxext.Y()/midext.Y()/hashelemsizefactor+1);
107
size.i3 = int (boxext.Z()/midext.Z()/hashelemsizefactor+1);
108
// PrintMessage (5, "hashsizes = ", size.i1, ", ", size.i2, ", ", size.i3);
109
110
elemsize.X()=boxext.X()/size.i1;
111
elemsize.Y()=boxext.Y()/size.i2;
112
elemsize.Z()=boxext.Z()/size.i3;
113
114
//create Hasharrays:
115
hashtable.SetSize(size.i1*size.i2*size.i3);
116
for (i = 1; i <= size.i1; i++)
117
{
118
for (j = 1; j <= size.i2; j++)
119
{
120
for (k = 1; k <= size.i3; k++)
121
{
122
INDEX ind=i+(j-1)*size.i1+(k-1)*size.i2*size.i1;
123
hashtable.Elem(ind) = new ARRAY <int> ();
124
}
125
}
126
}
127
}
128
else
129
{
130
//Clear all Hash-Arrays
131
for (i = 1; i <= size.i1; i++)
132
{
133
for (j = 1; j <= size.i2; j++)
134
{
135
for (k = 1; k <= size.i3; k++)
136
{
137
INDEX ind=i+(j-1)*size.i1+(k-1)*size.i2*size.i1;
138
hashtable.Elem(ind)->SetSize(0);
139
}
140
}
141
}
142
}
143
144
//Faces in Hashtable einfuegen:
145
for (i = 1; i <= faces->Size(); i++)
146
{
147
AddElem(faces->Get(i).Face(),i);
148
}
149
150
}
151
152
void GeomSearch3d :: AddElem(const MiniElement2d& elem, INDEX elemnum)
153
{
154
Point3d minp, maxp;
155
ElemMaxExt(minp, maxp, elem);
156
int sx = int ((minp.X()-minext.X())/elemsize.X()+1.);
157
int ex = int ((maxp.X()-minext.X())/elemsize.X()+1.);
158
int sy = int ((minp.Y()-minext.Y())/elemsize.Y()+1.);
159
int ey = int ((maxp.Y()-minext.Y())/elemsize.Y()+1.);
160
int sz = int ((minp.Z()-minext.Z())/elemsize.Z()+1.);
161
int ez = int ((maxp.Z()-minext.Z())/elemsize.Z()+1.);
162
163
for (int ix = sx; ix <= ex; ix++)
164
for (int iy = sy; iy <= ey; iy++)
165
for (int iz = sz; iz <= ez; iz++)
166
{
167
INDEX ind=ix+(iy-1)*size.i1+(iz-1)*size.i2*size.i1;
168
if (ind < 1 || ind > size.i1 * size.i2 * size.i3)
169
{
170
cerr << "Illegal hash-position";
171
cerr << "Position: " << ix << "," << iy << "," << iz << endl;
172
throw NgException ("Illegal position in Geomsearch");
173
}
174
hashtable.Elem(ind)->Append(elemnum);
175
}
176
}
177
178
void GeomSearch3d :: GetLocals(ARRAY<MiniElement2d> & locfaces, ARRAY<INDEX> & findex,
179
INDEX fstind, const Point3d& p0, double xh)
180
{
181
hashcount++;
182
183
Point3d minp, maxp, midp;
184
185
minp=p0-Vec3d(xh,xh,xh); //lay cube over sphere
186
maxp=p0+Vec3d(xh,xh,xh);
187
188
MaxCoords(minext,minp); //cube may not be out of hash-region
189
MinCoords(maxextreal,maxp);
190
191
192
int cluster = faces->Get(fstind).Cluster();
193
194
int sx = int((minp.X()-minext.X())/elemsize.X()+1.);
195
int ex = int((maxp.X()-minext.X())/elemsize.X()+1.);
196
int sy = int((minp.Y()-minext.Y())/elemsize.Y()+1.);
197
int ey = int((maxp.Y()-minext.Y())/elemsize.Y()+1.);
198
int sz = int((minp.Z()-minext.Z())/elemsize.Z()+1.);
199
int ez = int((maxp.Z()-minext.Z())/elemsize.Z()+1.);
200
int ix,iy,iz,i,k;
201
202
int cnt1 = 0; // test, how efficient hashtable is
203
int cnt2 = 0;
204
int cnt3 = 0;
205
206
for (ix = sx; ix <= ex; ix++)
207
{
208
for (iy = sy; iy <= ey; iy++)
209
{
210
for (iz = sz; iz <= ez; iz++)
211
{
212
INDEX ind=ix+(iy-1)*size.i1+(iz-1)*size.i2*size.i1;
213
214
//go through all elements in one hash area
215
const ARRAY <int> & area = *hashtable.Elem(ind);
216
for (k = 1; k <= area.Size(); k++)
217
{
218
cnt2++;
219
i = area.Get(k);
220
if (faces->Get(i).Cluster() == cluster &&
221
faces->Get(i).Valid() &&
222
faces->Get(i).HashValue() != hashcount &&
223
i != fstind)
224
{
225
cnt1++;
226
const MiniElement2d & face = faces->Get(i).Face();
227
228
const Point3d & p1 = (*points)[face.PNum(1)].P();
229
const Point3d & p2 = (*points)[face.PNum(2)].P();
230
const Point3d & p3 = (*points)[face.PNum(3)].P();
231
232
midp = Center (p1, p2, p3);
233
234
// if (Dist2 (midp, p0) <= xh*xh)
235
if((Dist2 (p1, p0) <= xh*xh) ||
236
(Dist2 (p2, p0) <= xh*xh) ||
237
(Dist2 (p3, p0) <= xh*xh) ||
238
(Dist2 (midp, p0) <= xh*xh) ) // by Jochen Wild
239
{
240
cnt3++;
241
locfaces.Append(faces->Get(i).Face());
242
findex.Append(i);
243
faces->Elem(i).SetHashValue(hashcount);
244
}
245
}
246
}
247
}
248
}
249
}
250
/*
251
if (faces->Size() != 0 && hashcount % 200 == 0)
252
{
253
(*mycout) << "n.o.f= " << faces->Size();
254
(*mycout) << ", n.o.lf= " << locfaces.Size();
255
(*mycout) << ", hashf= " << (double)cnt2/(double)faces->Size();
256
(*mycout) << " (" << (double)cnt1/(double)faces->Size();
257
(*mycout) << ", " << (double)cnt3/(double)faces->Size() << ")" << endl;
258
}
259
*/
260
261
}
262
263
}
264
265