Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/post/src/elements/6node_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 six 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
* SIX NODE TRIANGLE ELEMENT
52
*
53
* shape functions: N0 = (1-u-v)(1-2u-2v) 2 v=1
54
* N1 = u(2u-1) / \
55
* N2 = v(2v-1) / \
56
* N3 = 4u(1-u-v) 5 4
57
* N4 = 4uv / \
58
* N5 = 4v(1-u-v) 0-----3-----1 u=1
59
*
60
*/
61
62
static double N[6][6],A[6][6];
63
64
static double NodeU[] = { 0.0, 1.0, 0.0, 0.5, 0.5, 0.0 };
65
static double NodeV[] = { 0.0, 0.0, 1.0, 0.0, 0.5, 0.5 };
66
67
/*******************************************************************************
68
*
69
* Name: elm_6node_triangle_shape_functions( )
70
*
71
* Purpose: Initialize element shape function array. Internal only.
72
*
73
* Parameters:
74
*
75
* Input: Global (filewise) variables NodeU,NodeV,NodeW
76
*
77
* Output: Global (filewise) variable N[6][6], will contain
78
* shape function coefficients
79
*
80
* Return value: void
81
*
82
******************************************************************************/
83
static void elm_6node_triangle_shape_functions()
84
{
85
double u,v;
86
87
int i,j;
88
89
for( i=0; i<6; i++ )
90
{
91
u = NodeU[i];
92
v = NodeV[i];
93
94
A[i][0] = 1;
95
A[i][1] = u;
96
A[i][2] = v;
97
A[i][3] = u*v;
98
A[i][4] = u*u;
99
A[i][5] = v*v;
100
}
101
102
lu_mtrinv( (double *)A,6 );
103
104
for( i=0; i<6; i++ )
105
for( j=0; j<6; j++ ) N[i][j] = A[j][i];
106
}
107
108
/*******************************************************************************
109
*
110
* Name: elm_6node_triangle_triangulate( geometry_t *,element_t * )
111
*
112
* Purpose: Triangulate an element. The process also builds up an edge
113
* table and adds new nodes to node table. The triangulation
114
* and edge table is stored in geometry_t *geom-structure.
115
*
116
* Parameters:
117
*
118
* Input: (geometry_t *) pointer to structure holding triangulation
119
* (element_t *) element to triangulate
120
*
121
* Output: (geometry_t *) structure is modified
122
*
123
* Return value: FALSE if malloc() fails, TRUE otherwise
124
*
125
******************************************************************************/
126
int elm_6node_triangle_triangulate( geometry_t *geom, element_t *Elm, element_t *Parent )
127
{
128
double u,v,w,s;
129
130
static int map[4][3] =
131
{
132
{ 0,3,5 }, { 3,1,4 }, { 3,4,5 }, { 4,2,5 }
133
};
134
static int edge_map[4][3] =
135
{
136
{ 1,0,1 }, { 1,1,0 }, { 0,0,0 }, { 1,1,0 }
137
};
138
139
int i,j;
140
141
triangle_t triangle;
142
143
triangle.Element = Parent;
144
for( i=0; i<4; i++ )
145
{
146
triangle.v[0] = Elm->Topology[map[i][0]];
147
triangle.v[1] = Elm->Topology[map[i][1]];
148
triangle.v[2] = Elm->Topology[map[i][2]];
149
150
triangle.Edge[0] = edge_map[i][0];
151
triangle.Edge[1] = edge_map[i][1];
152
triangle.Edge[2] = edge_map[i][2];
153
154
if ( !geo_add_triangle( geom,&triangle ) ) return FALSE;
155
}
156
157
return TRUE;
158
}
159
160
/*******************************************************************************
161
*
162
* Name: elm_6node_triangle_point_inside(
163
* double *nx,double *ny,double *nz,
164
* double px, double py, double pz,
165
* double *u,double *v,double *w )
166
*
167
* Purpose: Find if point (px,py,pz) is inside the element, and return
168
* element coordinates of the point.
169
*
170
* Parameters:
171
*
172
* Input: (double *) nx,ny,nz node coordinates
173
* (double) px,py,pz point to consider
174
*
175
* Output: (double *) u,v,w point in element coordinates if inside
176
*
177
* Return value: in/out status
178
*
179
* NOTES: the goal here can be hard for more involved element types. kind of
180
* trivial for this one... (TODO: this is for xy-plane tri only)
181
*
182
******************************************************************************/
183
int elm_6node_triangle_point_inside
184
(
185
double *nx, double *ny, double *nz,
186
double px, double py, double pz, double *u,double *v,double *w
187
)
188
{
189
int elm_3node_triangle_point_inside();
190
return elm_3node_triangle_point_inside( nx,ny,nz,px,py,pz,u,v,w );
191
}
192
193
/*******************************************************************************
194
*
195
* Name: elm_6node_triangle_fvalue( double *,double,double )
196
*
197
* Purpose: return value of a quantity given on nodes at point (u,v)
198
*
199
*
200
* Parameters:
201
*
202
* Input: (double *) quantity values at nodes
203
* (double u,double v) point where value is evaluated
204
*
205
* Output: none
206
*
207
* Return value: quantity value
208
*
209
******************************************************************************/
210
static double elm_6node_triangle_fvalue( double *F,double u,double v )
211
{
212
double R=0.0,uv=u*v,u2=u*u,v2=v*v;
213
int i;
214
215
for( i=0; i<6; i++ )
216
{
217
R += F[i]*( N[i][0] +
218
N[i][1]*u +
219
N[i][2]*v +
220
N[i][3]*uv +
221
N[i][4]*u2 +
222
N[i][5]*v2 );
223
}
224
225
return R;
226
}
227
228
/*******************************************************************************
229
*
230
* Name: elm_6node_triangle_dndu_fvalue( double *,double,double )
231
*
232
* Purpose: return value of a first partial derivate in (u) of a
233
* quantity given on nodes at point (u,v)
234
*
235
*
236
* Parameters:
237
*
238
* Input: (double *) quantity values at nodes
239
* (double u,double v) point where value is evaluated
240
*
241
* Output: none
242
*
243
* Return value: quantity value
244
*
245
******************************************************************************/
246
static double elm_6node_triangle_dndu_fvalue(double *F,double u,double v)
247
{
248
double R=0.0,u2=2*u;
249
int i;
250
251
for( i=0; i<6; i++ )
252
{
253
R += F[i]*( N[i][1] + N[i][3]*v + N[i][4]*u2 );
254
}
255
256
return R;
257
}
258
259
/*******************************************************************************
260
*
261
* Name: elm_6node_triangle_dndv_fvalue( double *,double,double )
262
*
263
* Purpose: return value of a first partial derivate in (v) of a
264
* quantity given on nodes at point (u,v)
265
*
266
*
267
* Parameters:
268
*
269
* Input: (double *) quantity values at nodes
270
* (double u,double v) point where value is evaluated
271
*
272
* Output: none
273
*
274
* Return value: quantity value
275
*
276
******************************************************************************/
277
static double elm_6node_triangle_dndv_fvalue(double *F,double u,double v)
278
{
279
double R=0.0,v2=2*v;
280
int i;
281
282
for( i=0; i<6; i++ )
283
{
284
R += F[i]*(N[i][2]+N[i][3]*u+N[i][5]*v2);
285
}
286
287
return R;
288
}
289
290
/*******************************************************************************
291
*
292
* Name: elm_6node_triangle_isoline
293
*
294
* Purpose: Extract a iso line from triangle with given threshold
295
*
296
* Parameters:
297
*
298
* Input: (double) K, contour threshold
299
* (double *) F, contour quantity
300
* (double *) C, color quantity
301
* (double *) X,Y,Z vertex coords.
302
*
303
* Output: (line_t *) place to store the line
304
*
305
* Return value: number of lines generated (0,...,6)
306
*
307
******************************************************************************/
308
int elm_6node_triangle_isoline
309
(
310
double K, double *F, double *C,double *X,double *Y,double *Z,line_t *Line
311
)
312
{
313
double f[3],c[3],x[3],y[3],z[3];
314
315
int i, j, k, n=0, above=0;
316
317
static int map[6][2] =
318
{
319
{ 0,3 }, { 3,1 }, { 1,4 }, { 4,2 }, { 2,5 }, { 5,0 }
320
};
321
322
int elm_3node_triangle_isoline();
323
324
for( i=0; i<6; i++ ) above += F[i]>K;
325
if ( above == 0 || above == 6 ) return 0;
326
327
f[0] = elm_6node_triangle_fvalue( F,1.0/3.0,1.0/3.0 );
328
c[0] = elm_6node_triangle_fvalue( C,1.0/3.0,1.0/3.0 );
329
x[0] = elm_6node_triangle_fvalue( X,1.0/3.0,1.0/3.0 );
330
y[0] = elm_6node_triangle_fvalue( Y,1.0/3.0,1.0/3.0 );
331
z[0] = elm_6node_triangle_fvalue( Z,1.0/3.0,1.0/3.0 );
332
333
for( i=0; i<6; i++ )
334
{
335
for( j=1; j<3; j++ )
336
{
337
k = map[i][j-1];
338
f[j] = F[k];
339
c[j] = C[k];
340
x[j] = X[k];
341
y[j] = Y[k];
342
z[j] = Z[k];
343
}
344
n += elm_3node_triangle_isoline( K,f,c,x,y,z,&Line[n] );
345
}
346
347
return n;
348
}
349
350
351
/*******************************************************************************
352
*
353
* Name: elm_6node_triangle_initialize( )
354
*
355
* Purpose: Register the element type
356
*
357
* Parameters:
358
*
359
* Input: (char *) description of the element
360
* (int) numeric code for the element
361
*
362
* Output: Global list of element types is modified
363
*
364
* Return value: malloc() success
365
*
366
******************************************************************************/
367
int elm_6node_triangle_initialize()
368
{
369
static char *Name = "ELM_6NODE_TRIANGLE";
370
371
element_type_t ElementDef;
372
int elm_add_element_type();
373
374
elm_6node_triangle_shape_functions();
375
376
ElementDef.ElementName = Name;
377
ElementDef.ElementCode = 306;
378
379
ElementDef.NumberOfNodes = 6;
380
381
ElementDef.NodeU = NodeU;
382
ElementDef.NodeV = NodeV;
383
ElementDef.NodeW = NULL;
384
385
ElementDef.PartialU = (double (*)())elm_6node_triangle_dndu_fvalue;
386
ElementDef.PartialV = (double (*)())elm_6node_triangle_dndv_fvalue;
387
ElementDef.PartialW = (double (*)())NULL;
388
389
ElementDef.FunctionValue = (double (*)())elm_6node_triangle_fvalue;
390
ElementDef.Triangulate = (int (*)())elm_6node_triangle_triangulate;
391
ElementDef.PointInside = (int (*)())elm_6node_triangle_point_inside;
392
ElementDef.IsoLine = (int (*)())elm_6node_triangle_isoline;
393
ElementDef.IsoSurface = (int (*)())NULL;
394
395
return elm_add_element_type( &ElementDef ) ;
396
}
397
398