Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/meshgen2d/src/BGGridMesh.cpp
3196 views
1
#include "BGMesh.h"
2
#include "BGVertex.h"
3
#include <math.h>
4
#include <algorithm>
5
#include "coreGeometry.h"
6
7
void BGGridMesh::
8
initialize(std::vector< GeometryNode* >& nodes, std::vector< GeometryEdge* >& edges)
9
{
10
initialized = true;
11
12
std::cout << "Calculating background mesh" << std::endl;
13
14
int i;
15
int len = nodes.size();
16
17
double mean = MAP(nodes[0]->delta);
18
double mindelta = nodes[0]->delta;
19
double minx = nodes[0]->x, maxx = minx, miny = nodes[0]->y, maxy = miny;
20
21
for( i = 1; i < len; ++i )
22
{
23
mean += MAP(nodes[i]->delta);
24
25
if (nodes[i]->delta < mindelta)
26
mindelta = nodes[i]->delta;
27
28
if (nodes[i]->x < minx)
29
minx = nodes[i]->x;
30
if (nodes[i]->x > maxx)
31
maxx = nodes[i]->x;
32
if (nodes[i]->y < miny)
33
miny = nodes[i]->y;
34
if (nodes[i]->y > maxy)
35
maxy = nodes[i]->y;
36
}
37
38
mean /= len;
39
40
width = maxx - minx;
41
height = maxy - miny;
42
ox = minx;
43
oy = miny;
44
45
cellsize = mindelta * cellsize;
46
nh = (int)ceil(width / cellsize) + 1;
47
width = (nh - 1) * cellsize;
48
nv = (int)ceil(height / cellsize) + 1;
49
height = (nv - 1) * cellsize;
50
51
nh += 2;
52
nv += 2;
53
ox -= cellsize;
54
oy -= cellsize;
55
width += 2.0 * cellsize;
56
height += 2.0 * cellsize;
57
58
grid = new double[nh * nv];
59
bool *mask = new bool[nh * nv];
60
61
for (i = 0; i < nh * nv; i++)
62
{
63
grid[i] = mean;
64
mask[i] = false;
65
}
66
67
for (i = 0; i < len; i++)
68
{
69
int h = (int)((nodes[i]->x - ox) / cellsize + 0.5);
70
int v = (int)((nodes[i]->y - oy) / cellsize + 0.5);
71
grid[v*nh+h] = MAP(nodes[i]->delta);
72
mask[v*nh+h] = true;
73
}
74
75
len = edges.size();
76
for (i = 0; i < len; i++)
77
{
78
std::vector<int> x, y;
79
std::vector<double> delta;
80
edges[i]->getGridPoints(ox, oy, cellsize, x, y, delta);
81
for (int j = 0; j < x.size(); j++)
82
{
83
grid[y[j]*nh+x[j]] = delta[j];
84
mask[y[j]*nh+x[j]] = true;
85
}
86
}
87
88
std::vector<std::pair<int, int> > stack;
89
stack.push_back(std::make_pair(0, 0));
90
while (!stack.empty())
91
{
92
std::pair<int, int> p = stack.back();
93
stack.pop_back();
94
95
int h = p.first, v = p.second;
96
mask[v*nh+h] = true;
97
98
if (h > 0 && !mask[v*nh+h-1])
99
stack.push_back(std::make_pair(h-1, v));
100
if (h < nh - 1 && !mask[v*nh+h+1])
101
stack.push_back(std::make_pair(h+1, v));
102
if (v > 0 && !mask[(v-1)*nh+h])
103
stack.push_back(std::make_pair(h, v-1));
104
if (v < nv - 1 && !mask[(v+1)*nh+h])
105
stack.push_back(std::make_pair(h, v+1));
106
}
107
108
int niters = 0;
109
double error = 1e100, last;
110
do
111
{
112
niters++;
113
last = error;
114
error = 0.0;
115
116
int i, j;
117
118
for (int c = 0; c < 200; c++)
119
{
120
for (j = 0; j < nv; j++)
121
{
122
for (i = 0; i < nh; i++)
123
{
124
if (mask[j*nh+i]) continue;
125
126
double v = 0.0;
127
int n = 0;
128
129
if (i > 0)
130
{
131
v += grid[j*nh+i-1];
132
n++;
133
}
134
if (i < nh - 1)
135
{
136
v += grid[j*nh+i+1];
137
n++;
138
}
139
if (j > 0)
140
{
141
v += grid[(j-1)*nh+i];
142
n++;
143
}
144
if (j < nv - 1)
145
{
146
v += grid[(j+1)*nh+i];
147
n++;
148
}
149
150
grid[j*nh+i] = v / n;
151
}
152
}
153
}
154
155
for (j = 0; j < nv; j++)
156
{
157
for (i = 0; i < nh; i++)
158
{
159
if (mask[j*nh+i]) continue;
160
161
double residual = 0.0;
162
163
double v = grid[j*nh+i];
164
if (i > 0)
165
residual += grid[j*nh+i-1] - v;
166
if (i < nh - 1)
167
residual += grid[j*nh+i+1] - v;
168
if (j > 0)
169
residual += grid[(j-1)*nh+i] - v;
170
if (j < nv - 1)
171
residual += grid[(j+1)*nh+i] - v;
172
173
residual /= cellsize;
174
175
double e = fabs(residual);
176
if (e > error)
177
error = e;
178
}
179
}
180
} while (error > 0.00001);
181
}
182
183
double BGGridMesh::
184
interpolate( const double ix, const double iy )
185
{
186
int h = (int)((ix - ox) / cellsize);
187
int v = (int)((iy - oy) / cellsize);
188
189
if (h < 0) h = 0;
190
if (h > nh - 1) h = nh - 1;
191
if (v < 0) v = 0;
192
if (v > nv - 1) v = nv - 1;
193
194
double xoff = (ix - (ox + h * cellsize)) / cellsize,
195
yoff = (iy - (oy + v * cellsize)) / cellsize;
196
197
return UNMAP((1.0 - xoff) * (1.0 - yoff) * grid[v*nh+h] +
198
xoff * (1.0 - yoff) * grid[v*nh+h+1] +
199
(1.0 - xoff) * yoff * grid[(v+1)*nh+h] +
200
xoff * yoff * grid[(v+1)*nh+h+1]);
201
}
202
203