Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/post/src/elements/10node_triangle.c
3203 views
1
/*****************************************************************************
2
*
3
* Elmer, A Finite Element Software for Multiphysical Problems
4
*
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
*
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2
10
* of the License, or (at your option) any later version.
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program (in file fem/GPL-2); if not, write to the
19
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
* Boston, MA 02110-1301, USA.
21
*
22
*****************************************************************************/
23
24
/*******************************************************************************
25
*
26
* Definition of ten node triangle element.
27
*
28
*******************************************************************************
29
*
30
* Author: Juha Ruokolainen
31
*
32
* Address: CSC - IT Center for Science Ltd.
33
* Keilaranta 14, P.O. BOX 405
34
* 02101 Espoo, Finland
35
* Tel. +358 0 457 2723
36
* Telefax: +358 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 20 Sep 1995
40
*
41
*
42
* Modification history:
43
*
44
******************************************************************************/
45
46
#include "../elmerpost.h"
47
#include <elements.h>
48
49
50
/*
51
* TEN NODE TRIANGLE ELEMENT
52
*
53
*/
54
55
static double N[10][10],A[10][10];
56
57
static double NodeU[] = { 0.0, 1.0, 0.0, 1./3., 2./3., 2./3., 1./3., 0.0, 0.0, 1./3. };
58
static double NodeV[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1./3., 2./3., 2./3, 1./3., 1./3. };
59
60
/*******************************************************************************
61
*
62
* Name: elm_10node_triangle_shape_functions( )
63
*
64
* Purpose: Initialize element shape function array. Internal only.
65
*
66
* Parameters:
67
*
68
* Input: Global (filewise) variables NodeU,NodeV,NodeW
69
*
70
* Output: Global (filewise) variable N[10][10], will contain
71
* shape function coefficients
72
*
73
* Return value: void
74
*
75
******************************************************************************/
76
static void elm_10node_triangle_shape_functions()
77
{
78
double u,v;
79
80
int i,j;
81
82
for( i=0; i<10; i++ )
83
{
84
u = NodeU[i];
85
v = NodeV[i];
86
87
88
A[i][0] = 1;
89
A[i][1] = u;
90
A[i][2] = v;
91
A[i][3] = u*v;
92
A[i][4] = u*u;
93
A[i][5] = v*v;
94
A[i][6] = u*u*v;
95
A[i][7] = u*v*v;
96
A[i][8] = u*u*u;
97
A[i][9] = v*v*v;
98
99
}
100
101
lu_mtrinv( (double *)A,10 );
102
103
for( i=0; i<10; i++ )
104
for( j=0; j<10; j++ ) N[i][j] = A[j][i];
105
}
106
107
/*******************************************************************************
108
*
109
* Name: elm_10node_triangle_triangulate( geometry_t *,element_t * )
110
*
111
* Purpose: Triangulate an element. The process also builds up an edge
112
* table and adds new nodes to node table. The triangulation
113
* and edge table is stored in geometry_t *geom-structure.
114
*
115
* Parameters:
116
*
117
* Input: (geometry_t *) pointer to structure holding triangulation
118
* (element_t *) element to triangulate
119
*
120
* Output: (geometry_t *) structure is modified
121
*
122
* Return value: FALSE if malloc() fails, TRUE otherwise
123
*
124
******************************************************************************/
125
int elm_10node_triangle_triangulate( geometry_t *geom, element_t *Elm )
126
{
127
double u,v,w,s;
128
129
static int map[9][3] =
130
{
131
{ 0,3,8 }, { 3,4,9 }, { 3,9,8 },
132
{ 4,5,9 }, { 4,1,5 }, { 5,6,9 },
133
{ 8,9,7 }, { 9,6,7 }, { 7,6,2 }
134
};
135
static int edge_map[9][3] =
136
{
137
{ 1,0,1 }, { 1,0,0 }, { 0,0,0 },
138
{ 0,0,0 }, { 1,1,0 }, { 1,0,0 },
139
{ 0,0,1 }, { 0,0,0 }, { 0,1,1 }
140
};
141
142
int i,j;
143
144
triangle_t triangle;
145
146
triangle.Element = Elm;
147
for( i=0; i<9; i++ )
148
{
149
triangle.v[0] = Elm->Topology[map[i][0]];
150
triangle.v[1] = Elm->Topology[map[i][1]];
151
triangle.v[2] = Elm->Topology[map[i][2]];
152
153
triangle.Edge[0] = edge_map[i][0];
154
triangle.Edge[1] = edge_map[i][1];
155
triangle.Edge[2] = edge_map[i][2];
156
157
if ( !geo_add_triangle( geom,&triangle ) ) return FALSE;
158
}
159
160
return TRUE;
161
}
162
163
/*******************************************************************************
164
*
165
* Name: elm_10node_triangle_point_inside(
166
* double *nx,double *ny,double *nz,
167
* double px, double py, double pz,
168
* double *u,double *v,double *w )
169
*
170
* Purpose: Find if point (px,py,pz) is inside the element, and return
171
* element coordinates of the point.
172
*
173
* Parameters:
174
*
175
* Input: (double *) nx,ny,nz node coordinates
176
* (double) px,py,pz point to consider
177
*
178
* Output: (double *) u,v,w point in element coordinates if inside
179
*
180
* Return value: in/out status
181
*
182
* NOTES: the goal here can be hard for more involved element types. kind of
183
* trivial for this one... (TODO: this is for xy-plane tri only)
184
*
185
******************************************************************************/
186
int elm_10node_triangle_point_inside
187
(
188
double *nx, double *ny, double *nz,
189
double px, double py, double pz, double *u,double *v,double *w
190
)
191
{
192
int elm_3node_triangle_point_inside();
193
return elm_3node_triangle_point_inside( nx,ny,nz,px,py,pz,u,v,w );
194
}
195
196
/*******************************************************************************
197
*
198
* Name: elm_10node_triangle_fvalue( double *,double,double )
199
*
200
* Purpose: return value of a quantity given on nodes at point (u,v)
201
*
202
*
203
* Parameters:
204
*
205
* Input: (double *) quantity values at nodes
206
* (double u,double v) point where value is evaluated
207
*
208
* Output: none
209
*
210
* Return value: quantity value
211
*
212
******************************************************************************/
213
static double elm_10node_triangle_fvalue( double *F,double u,double v )
214
{
215
double R=0.0,uv=u*v,u2=u*u,v2=v*v;
216
int i;
217
218
219
for( i=0; i<10; i++ )
220
{
221
R += F[i]*( N[i][0] +
222
N[i][1]*u +
223
N[i][2]*v +
224
N[i][3]*uv +
225
N[i][4]*u2 +
226
N[i][5]*v2 +
227
N[i][6]*u2*v +
228
N[i][7]*u*v2 +
229
N[i][8]*u2*u +
230
N[i][9]*v2*v );
231
}
232
233
return R;
234
}
235
236
/*******************************************************************************
237
*
238
* Name: elm_10node_triangle_dndu_fvalue( double *,double,double )
239
*
240
* Purpose: return value of a first partial derivate in (u) of a
241
* quantity given on nodes at point (u,v)
242
*
243
*
244
* Parameters:
245
*
246
* Input: (double *) quantity values at nodes
247
* (double u,double v) point where value is evaluated
248
*
249
* Output: none
250
*
251
* Return value: quantity value
252
*
253
******************************************************************************/
254
static double elm_10node_triangle_dndu_fvalue(double *F,double u,double v)
255
{
256
double R=0.0;
257
int i;
258
259
for( i=0; i<10; i++ )
260
{
261
R += F[i]*( N[i][1] + N[i][3]*v + 2*N[i][4]*u +
262
N[i][6]*2*u*v + N[i][7]*v*v + 3*N[i][8]*u*u );
263
}
264
265
return R;
266
}
267
268
/*******************************************************************************
269
*
270
* Name: elm_10node_triangle_dndv_fvalue( double *,double,double )
271
*
272
* Purpose: return value of a first partial derivate in (v) of a
273
* quantity given on nodes at point (u,v)
274
*
275
*
276
* Parameters:
277
*
278
* Input: (double *) quantity values at nodes
279
* (double u,double v) point where value is evaluated
280
*
281
* Output: none
282
*
283
* Return value: quantity value
284
*
285
******************************************************************************/
286
static double elm_10node_triangle_dndv_fvalue(double *F,double u,double v)
287
{
288
double R=0.0;
289
int i;
290
291
for( i=0; i<10; i++ )
292
{
293
R += F[i]*( N[i][2] + N[i][3]*u + 2*N[i][5]*v + N[i][6]*u*u +
294
N[i][7]*2*u*v + 3*N[i][9]*v*v);
295
}
296
297
return R;
298
}
299
300
/*******************************************************************************
301
*
302
* Name: elm_10node_triangle_isoline
303
*
304
* Purpose: Extract a iso line from triangle with given threshold
305
*
306
* Parameters:
307
*
308
* Input: (double) K, contour threshold
309
* (double *) F, contour quantity
310
* (double *) C, color quantity
311
* (double *) X,Y,Z vertex coords.
312
*
313
* Output: (line_t *) place to store the line
314
*
315
* Return value: number of lines generated (0,...,6)
316
*
317
******************************************************************************/
318
int elm_10node_triangle_isoline
319
(
320
double K, double *F, double *C,double *X,double *Y,double *Z,line_t *Line
321
)
322
{
323
double f[3],c[3],x[3],y[3],z[3];
324
325
int i, j, k, n=0, above=0;
326
327
static int map[9][3] =
328
{
329
{ 0,3,8 }, { 3,4,9 }, { 3,9,8 },
330
{ 4,5,9 }, { 4,1,5 }, { 5,6,9 },
331
{ 8,9,7 }, { 9,6,7 }, { 7,6,2 }
332
};
333
334
for( i=0; i<10; i++ ) above += F[i]>K;
335
if ( above == 0 || above == 10 ) return 0;
336
337
for( i=0; i<9; i++ )
338
{
339
int elm_3node_triangle_isoline();
340
for( j=0; j<3; j++ )
341
{
342
k = map[i][j-1];
343
f[j] = F[k];
344
c[j] = C[k];
345
x[j] = X[k];
346
y[j] = Y[k];
347
z[j] = Z[k];
348
}
349
n += elm_3node_triangle_isoline( K,f,c,x,y,z,&Line[n] );
350
}
351
352
return n;
353
}
354
355
356
/*******************************************************************************
357
*
358
* Name: elm_10node_triangle_initialize( )
359
*
360
* Purpose: Register the element type
361
*
362
* Parameters:
363
*
364
* Input: (char *) description of the element
365
* (int) numeric code for the element
366
*
367
* Output: Global list of element types is modified
368
*
369
* Return value: malloc() success
370
*
371
******************************************************************************/
372
int elm_10node_triangle_initialize()
373
{
374
static char *Name = "ELM_10NODE_TRIANGLE";
375
376
element_type_t ElementDef;
377
378
int elm_add_element_type();
379
380
elm_10node_triangle_shape_functions();
381
382
ElementDef.ElementName = Name;
383
ElementDef.ElementCode = 310;
384
385
ElementDef.NumberOfNodes = 10;
386
387
ElementDef.NodeU = NodeU;
388
ElementDef.NodeV = NodeV;
389
ElementDef.NodeW = NULL;
390
391
ElementDef.PartialU = (double (*)())elm_10node_triangle_dndu_fvalue;
392
ElementDef.PartialV = (double (*)())elm_10node_triangle_dndv_fvalue;
393
ElementDef.PartialW = (double (*)())NULL;
394
395
ElementDef.FunctionValue = (double (*)())elm_10node_triangle_fvalue;
396
ElementDef.Triangulate = (int (*)())elm_10node_triangle_triangulate;
397
ElementDef.PointInside = (int (*)())elm_10node_triangle_point_inside;
398
ElementDef.IsoLine = (int (*)())elm_10node_triangle_isoline;
399
ElementDef.IsoSurface = (int (*)())NULL;
400
401
return elm_add_element_type( &ElementDef ) ;
402
}
403
404