Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/meshgen2d/src/QuadLayer.cpp
3196 views
1
#include "QuadLayer.h"
2
#include "QuadElement.h"
3
#include "coreGeometry.h"
4
#include <iostream>
5
6
void getGridline(NodeMap& allNodes, std::vector<Node*> &strip, MeshNode** grid, int offset, double *places)
7
{
8
double prevx = strip[0]->x, prevy = strip[0]->y, totLength = 0.0;
9
int len = strip.size(), i;
10
for (i = 0; i < len; i++)
11
{
12
totLength += distance(prevx, prevy, strip[i]->x, strip[i]->y);
13
places[i] = totLength;
14
prevx = strip[i]->x;
15
prevy = strip[i]->y;
16
grid[i * offset] = static_cast< MeshNode * >(strip[i]);
17
allNodes[strip[i]->tag] = strip[i];
18
}
19
20
for (i = 0; i < len; i++)
21
places[i] /= totLength;
22
}
23
24
// grid generation changed for curved bodies by Reino Ruusu 24.1.2000
25
void QuadLayer::
26
makeGrid( NodeMap& allNodes, const int m, const int n)
27
{
28
int i,j;
29
30
grid = new MeshNode*[m*n];
31
32
// relative place of nodes on edges (0..1)
33
double *places[4];
34
places[0] = new double[n];
35
places[1] = new double[m];
36
places[2] = new double[n];
37
places[3] = new double[m];
38
39
std::vector<Node*> strip;
40
41
// edge 0 is the column m
42
edges[0]->exportNodes(strip, directions[0]);
43
getGridline(allNodes, strip, &grid[m-1], m, places[0]);
44
strip.clear();
45
46
// edge 1 is the row n (reversed)
47
edges[1]->exportNodes(strip, -directions[1]);
48
getGridline(allNodes, strip, &grid[(n-1)*m], 1, places[1]);
49
strip.clear();
50
51
// edge 2 is the column 1 (reversed)
52
edges[2]->exportNodes(strip, -directions[2]);
53
getGridline(allNodes, strip, &grid[0], m, places[2]);
54
strip.clear();
55
56
// edge 3 is the row 1
57
edges[3]->exportNodes(strip, directions[3]);
58
getGridline(allNodes, strip, &grid[0], 1, places[3]);
59
strip.clear();
60
61
double *_offh = new double[8*m],
62
*_offv = new double[8*n];
63
double *xhll = _offh+0*m, *xhlr = _offh+1*m, *xhul = _offh+2*m, *xhur = _offh+3*m;
64
double *yhll = _offh+4*m, *yhlr = _offh+5*m, *yhul = _offh+6*m, *yhur = _offh+7*m;
65
double *xvll = _offv+0*n, *xvlr = _offv+1*n, *xvul = _offv+2*n, *xvur = _offv+3*n;
66
double *yvll = _offv+4*n, *yvlr = _offv+5*n, *yvul = _offv+6*n, *yvur = _offv+7*n;
67
68
// Precalculate offsets from corner points
69
// rows
70
for (i = 0; i < m; i++)
71
{
72
// LL
73
xhll[i] = grid[i]->x - grid[0]->x;
74
yhll[i] = grid[i]->y - grid[0]->y;
75
// LR
76
xhlr[i] = grid[i]->x - grid[m-1]->x;
77
yhlr[i] = grid[i]->y - grid[m-1]->y;
78
// UL
79
xhul[i] = grid[(n-1)*m+i]->x - grid[(n-1)*m]->x;
80
yhul[i] = grid[(n-1)*m+i]->y - grid[(n-1)*m]->y;
81
// UR
82
xhur[i] = grid[(n-1)*m+i]->x - grid[(n-1)*m+m-1]->x;
83
yhur[i] = grid[(n-1)*m+i]->y - grid[(n-1)*m+m-1]->y;
84
}
85
86
// columns
87
for (j = 0; j < n; j++)
88
{
89
// LL
90
xvll[j] = grid[j*m]->x - grid[0]->x;
91
yvll[j] = grid[j*m]->y - grid[0]->y;
92
// UL
93
xvul[j] = grid[j*m]->x - grid[(n-1)*m]->x;
94
yvul[j] = grid[j*m]->y - grid[(n-1)*m]->y;
95
// LR
96
xvlr[j] = grid[j*m+m-1]->x - grid[m-1]->x;
97
yvlr[j] = grid[j*m+m-1]->y - grid[m-1]->y;
98
// UR
99
xvur[j] = grid[j*m+m-1]->x - grid[(n-1)*m+m-1]->x;
100
yvur[j] = grid[j*m+m-1]->y - grid[(n-1)*m+m-1]->y;
101
}
102
103
for( j = 1; j < (n - 1); ++j)
104
{
105
for( i = 1; i < (m - 1); ++i)
106
{
107
double pl = places[2][j],
108
pr = places[0][j],
109
pb = places[3][i],
110
pt = places[1][i];
111
112
/* Calculate weights for interpolation
113
wt = wl * pl + wr * pr
114
wb = 1 - wt
115
wr = wb * pb + wt * pt
116
wl = 1 - wr
117
*/
118
double wt = ((pr - pl) * pb + pl) / (1.0 - (pr - pl) * (pt - pb));
119
double wb = 1.0 - wt;
120
double wr = wb * pb + wt * pt;
121
double wl = 1.0 - wr;
122
123
// Interpolate coordinates from the four gridline endpoints
124
Node *left = grid[j*m], *right = grid[j*m+m-1],
125
*bottom = grid[i], *top = grid[(n-1)*m+i];
126
127
double x, y;
128
x = ((wl * (left->x + wb * xhll[i] + wt * xhul[i]) +
129
wr * (right->x + wb * xhlr[i] + wt * xhur[i])) +
130
(wb * (bottom->x + wl * xvll[j] + wr * xvlr[j]) +
131
wt * (top->x + wl * xvul[j] + wr * xvur[j]))) / 2.0;
132
133
y = ((wl * (left->y + wb * yhll[i] + wt * yhul[i]) +
134
wr * (right->y + wb * yhlr[i] + wt * yhur[i])) +
135
(wb * (bottom->y + wl * yvll[j] + wr * yvlr[j]) +
136
wt * (top->y + wl * yvul[j] + wr * yvur[j]))) / 2.0;
137
138
grid[ j*m+i ] = new MeshNode( x, y );
139
allNodes[grid[ j*m+i ]->tag] = grid[ j*m+i ];
140
}
141
}
142
143
delete[] _offh;
144
delete[] _offv;
145
for (i = 0; i < 4; i++)
146
delete[] places[i];
147
}
148
149
void QuadLayer::
150
discretize(NodeMap& fixedNodes, NodeMap& allNodes, std::list< Element* >& allElements)
151
{
152
int i, j;
153
154
int m = edges[1]->size();
155
int n = edges[0]->size();
156
157
QuadElement **elements = new QuadElement*[(n-1)*(m-1)];
158
159
makeGrid( allNodes, m, n );
160
for( j = 0; j < (n - 1); ++j)
161
for( i = 0; i < (m - 1); ++i)
162
{
163
QuadElement *el = new QuadElement( grid[j*m+i+1], grid[(j+1)*m+i+1], grid[(j+1)*m+i], grid[j*m+i]);
164
elements[j*(m-1)+i] = el;
165
allElements.push_back(el);
166
}
167
168
// set boundary element relations
169
std::vector<BoundaryElement*> bels;
170
// edge 0 is the column m
171
edges[0]->elements(bels, directions[0]);
172
for (j = 0; j < n - 1; j++)
173
{
174
bels[j]->setLeft(elements[j*(m-1)+m-2]->elementId());
175
}
176
177
bels.clear();
178
// edge 1 is the row n (reversed)
179
edges[1]->elements(bels, -directions[1]);
180
for (i = 0; i < m - 1; i++)
181
{
182
bels[i]->setRight(elements[(n-2)*(m-1)+i]->elementId());
183
}
184
185
bels.clear();
186
// edge 2 is the column 1 (reversed)
187
edges[2]->elements(bels, -directions[2]);
188
for (j = 0; j < n - 1; j++)
189
{
190
bels[j]->setRight(elements[j*(m-1)]->elementId());
191
}
192
193
bels.clear();
194
// edge 3 is the row 1
195
edges[3]->elements(bels, directions[3]);
196
for (i = 0; i < m - 1; i++)
197
{
198
bels[i]->setLeft(elements[i]->elementId());
199
}
200
201
delete [] grid;
202
delete [] elements;
203
}
204
205