Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/post/src/elements/13node_pyramid.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 6 node pyramid 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: 4 Oct 1995
40
*
41
******************************************************************************/
42
43
#include "../elmerpost.h"
44
#include <elements.h>
45
46
/*
47
* Five node pyramid volume element.
48
*
49
*/
50
51
static double A[13][13],N[13][13];
52
53
static double NodeU[] = { -1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0, -1.0, -0.5, 0.5, 0.5, -0.5 };
54
static double NodeV[] = { -1.0,-1.0, 1.0, 1.0, 0.0,-1.0, 0.0, 1.0, 0.0, -0.5, -0.5, 0.5, 0.5 };
55
static double NodeW[] = { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5 };
56
57
/*******************************************************************************
58
*
59
* Name: elm_13node_pyramid_triangulate
60
*
61
* Purpose: Triangulate an element. The process also builds up an edge
62
* table and adds new nodes to node table. The triangulation
63
* and edge table is stored in geometry_t *geom-structure.
64
*
65
* Parameters:
66
*
67
* Input: (geometry_t *) pointer to structure holding triangulation
68
* (element_t *) element to triangulate
69
*
70
* Output: (geometry_t *) structure is modified
71
*
72
* Return value: FALSE if malloc() fails, TRUE otherwise
73
*
74
******************************************************************************/
75
static int elm_13node_pyramid_triangulate( geometry_t *geom,element_t *pyramid )
76
{
77
element_t element;
78
int i,j;
79
80
int PrismFace[5][8] = { { 0,1,2,3,5,6,7,8 }, { 0,1,4,5,10, 9, 0, 0 },
81
{ 1,2,4,6,11,10, 0, 0 },
82
{ 2,3,4,7,12,11, 0, 0 },
83
{ 3,0,4,8, 9,12, 0, 0 } };
84
85
int elm_8node_quad_triangulate();
86
int geo_add_edge();
87
int elm_6node_triangle_triangulate();
88
89
if ( GlobalOptions.VolumeSides )
90
{
91
int topo[8];
92
93
element.DisplayFlag = TRUE;
94
element.Topology = topo;
95
for( i=0; i<MAX_GROUP_IDS; i++ ) element.GroupIds[i] = pyramid->GroupIds[i];
96
97
for( j=0; j<8; j++ )
98
{
99
element.Topology[j] = pyramid->Topology[PrismFace[0][j]];
100
}
101
if ( !elm_8node_quad_triangulate( geom, &element, pyramid ) ) return FALSE;
102
103
for( i=1; i<5; i++ )
104
{
105
for( j=0; j<6; j++ )
106
{
107
element.Topology[j] = pyramid->Topology[PrismFace[i][j]];
108
}
109
if ( !elm_6node_triangle_triangulate( geom, &element, pyramid ) ) return FALSE;
110
}
111
} else {
112
if ( !geo_add_edge( geom, pyramid->Topology[0], pyramid->Topology[1],pyramid ) ) return FALSE;
113
if ( !geo_add_edge( geom, pyramid->Topology[1], pyramid->Topology[2],pyramid ) ) return FALSE;
114
if ( !geo_add_edge( geom, pyramid->Topology[2], pyramid->Topology[3],pyramid ) ) return FALSE;
115
if ( !geo_add_edge( geom, pyramid->Topology[3], pyramid->Topology[0],pyramid ) ) return FALSE;
116
if ( !geo_add_edge( geom, pyramid->Topology[0], pyramid->Topology[4],pyramid ) ) return FALSE;
117
if ( !geo_add_edge( geom, pyramid->Topology[1], pyramid->Topology[4],pyramid ) ) return FALSE;
118
if ( !geo_add_edge( geom, pyramid->Topology[2], pyramid->Topology[4],pyramid ) ) return FALSE;
119
if ( !geo_add_edge( geom, pyramid->Topology[3], pyramid->Topology[4],pyramid ) ) return FALSE;
120
}
121
122
return TRUE;
123
}
124
125
/*******************************************************************************
126
*
127
* Name: elm_13node_pyramid_shape_functions
128
*
129
* Purpose: Initialize element shape function array. Internal only.
130
*
131
* Parameters:
132
*
133
* Input: Global (filewise) variables NodeU,NodeV,NodeW
134
*
135
* Output: Global (filewise) variable N[6][6], will contain
136
* shape function coefficients
137
*
138
* Return value: void
139
* Return value: void
140
*
141
******************************************************************************/
142
static void elm_13node_pyramid_shape_functions()
143
{
144
double u,v,w;
145
int i,j;
146
147
#if 0
148
for( i=0; i<13; i++ )
149
{
150
u = NodeU[i];
151
v = NodeV[i];
152
w = NodeW[i];
153
154
A[i][0] = 1;
155
A[i][1] = u;
156
A[i][2] = u*u;
157
A[i][3] = v;
158
A[i][4] = u*v;
159
A[i][5] = u*u*v;
160
A[i][6] = v*v;
161
A[i][7] = u*v*v;
162
A[i][8] = w;
163
A[i][9] = u*w;
164
A[i][10] = v*w;
165
A[i][11] = u*v*w;
166
A[i][12] = w*w;
167
}
168
169
lu_mtrinv( (double *)A,13 );
170
171
for( i=0; i<13; i++ )
172
for( j=0; j<13; j++ ) N[i][j] = A[j][i];
173
#endif
174
}
175
176
/*******************************************************************************
177
*
178
* Name: elm_13node_pyramid_fvalue
179
*
180
* Purpose: return value of a quantity given on nodes at point (u,v)
181
* Use trough (element_type_t *) structure.
182
*
183
* Parameters:
184
*
185
* Input: (double *) quantity values at nodes
186
* (double u,double v) point where values are evaluated
187
*
188
* Output: none
189
*
190
* Return value: quantity value
191
*
192
******************************************************************************/
193
static double elm_13node_pyramid_fvalue(double *F,double u,double v,double w)
194
{
195
double R=0.0,s;
196
int i;
197
198
if ( w == 1 ) w = 1.0-1.0e-12;
199
s = 1.0 / (1-w);
200
201
R = R + F[0] * (-u-v-1) * ( (1-u) * (1-v) - w + u*v*w * s ) / 4;
202
R = R + F[1] * ( u-v-1) * ( (1+u) * (1-v) - w - u*v*w * s ) / 4;
203
R = R + F[2] * ( u+v-1) * ( (1+u) * (1+v) - w + u*v*w * s ) / 4;
204
R = R + F[3] * (-u+v-1) * ( (1-u) * (1+v) - w - u*v*w * s ) / 4;
205
R = R + F[4] * w*(2*w-1);
206
R = R + F[5] * (1+u-w)*(1-u-w)*(1-v-w) * s / 2;
207
R = R + F[6] * (1+v-w)*(1-v-w)*(1+u-w) * s / 2;
208
R = R + F[7] * (1+u-w)*(1-u-w)*(1+v-w) * s / 2;
209
R = R + F[8] * (1+v-w)*(1-v-w)*(1-u-w) * s / 2;
210
R = R + F[9] * w * (1-u-w) * (1-v-w) * s;
211
R = R + F[10] * w * (1+u-w) * (1-v-w) * s;
212
R = R + F[11] * w * (1+u-w) * (1+v-w) * s;
213
R = R + F[12] * w * (1-u-w) * (1+v-w) * s;
214
215
216
return R;
217
}
218
219
/*******************************************************************************
220
*
221
* Name: elm_13node_pyramid_dndu_fvalue
222
*
223
* Purpose: return value of a first partial derivate in (v) of a
224
* quantity given on nodes at point (u,v).
225
* Use trough (element_type_t *) structure.
226
*
227
*
228
* Parameters:
229
*
230
* Input: (double *) quantity values at nodes
231
* (double u,double v,double w) point where values are evaluated
232
*
233
* Output: none
234
*
235
* Return value: quantity value
236
*
237
******************************************************************************/
238
static double elm_13node_pyramid_dndu_fvalue(double *F,double u,double v,double w)
239
{
240
double R=0.0,s;
241
int i;
242
243
if ( w == 1 ) w = 1.0-1.0e-12;
244
s = 1.0 / (1-w);
245
246
R = R + F[0] * ( -( (1-u) * (1-v) - w + u*v*w * s ) +
247
(-u-v-1) * ( -(1-v) + v*w * s ) ) / 4;
248
249
R = R + F[1] * ( ( (1+u) * (1-v) - w - u*v*w * s ) +
250
( u-v-1) * ( (1-v) - v*w * s ) ) / 4;
251
252
R = R + F[2] * ( ( (1+u) * (1+v) - w + u*v*w * s ) +
253
( u+v-1) * ( (1+v) + v*w * s ) ) / 4;
254
255
R = R + F[3] * ( -( (1-u) * (1+v) - w - u*v*w * s ) +
256
(-u+v-1) * ( -(1+v) - v*w * s ) ) / 4;
257
258
R = R + F[4] * 0.0;
259
260
R = R + F[5] * ( (1-u-w)*(1-v-w) - (1+u-w)*(1-v-w) ) * s / 2;
261
R = R + F[6] * ( (1+v-w)*(1-v-w) ) * s / 2;
262
R = R + F[7] * ( (1-u-w)*(1+v-w) - (1+u-w)*(1+v-w) ) * s / 2;
263
R = R + F[8] * ( -(1+v-w)*(1-v-w) ) * s / 2;
264
265
R = R - F[ 9] * w * (1-v-w) * s;
266
R = R + F[10] * w * (1-v-w) * s;
267
R = R + F[11] * w * (1+v-w) * s;
268
R = R - F[12] * w * (1+v-w) * s;
269
270
return R;
271
}
272
273
/*******************************************************************************
274
*
275
* Name: elm_13node_pyramid_dndv_fvalue
276
*
277
* Purpose: return value of a first partial derivate in (v) of a
278
* quantity given on nodes at point (u,v,w).
279
* Use trough (element_type_t *) structure.
280
*
281
*
282
* Parameters:
283
*
284
* Input: (double *) quantity values at nodes
285
* (double u,double v,double w) point where values are evaluated
286
*
287
* Output: none
288
*
289
* Return value: quantity value
290
*
291
******************************************************************************/
292
static double elm_13node_pyramid_dndv_fvalue(double *F,double u,double v,double w)
293
{
294
double R=0.0,s;
295
int i;
296
297
if ( w == 1 ) w = 1.0-1.0e-12;
298
s = 1.0 / (1-w);
299
300
R = R + F[0] * ( -( (1-u) * (1-v) - w + u*v*w * s ) +
301
(-u-v-1) * ( -(1-u) + u*w * s ) ) / 4;
302
303
R = R + F[1] * ( -( (1+u) * (1-v) - w - u*v*w * s ) +
304
( u-v-1) * ( -(1+u) - u*w * s ) ) / 4;
305
306
R = R + F[2] * ( ( (1+u) * (1+v) - w + u*v*w * s ) +
307
( u+v-1) * ( (1+u) + u*w * s ) ) / 4;
308
309
R = R + F[3] * ( ( (1-u) * (1+v) - w - u*v*w * s ) +
310
(-u+v-1) * ( (1-u) - u*w * s ) ) / 4;
311
312
R = R + F[4] * 0.0;
313
314
R = R - F[5] * (1+u-w)*(1-u-w) * s / 2;
315
R = R + F[6] * ( (1-v-w)*(1+u-w) - (1+v-w)*(1+u-w) ) * s / 2;
316
R = R + F[7] * (1+u-w)*(1-u-w) * s / 2;
317
R = R + F[8] * ( (1-v-w)*(1-u-w) - (1+v-w)*(1-u-w) ) * s / 2;
318
319
R = R - F[9] * w * (1-u-w) * s;
320
R = R - F[10] * w * (1+u-w) * s;
321
R = R + F[11] * w * (1+u-w) * s;
322
R = R + F[12] * w * (1-u-w) * s;
323
324
return R;
325
}
326
327
/*******************************************************************************
328
*
329
* Name: elm_13node_pyramid_dndw_fvalue
330
*
331
* Purpose: return value of a first partial derivate in (w) of a
332
* quantity given on nodes at point (u,v,w)
333
* Use trough (element_type_t *) structure.
334
*
335
*
336
* Parameters:
337
*
338
* Input: (double *) quantity values at nodes
339
* (double u,double v,double w) point where values are evaluated
340
*
341
* Output: none
342
*
343
* Return value: quantity value
344
*
345
******************************************************************************/
346
static double elm_13node_pyramid_dndw_fvalue(double *F,double u,double v,double w)
347
{
348
double R=0.0,s;
349
int i;
350
351
if ( w == 1 ) w = 1.0-1.0e-12;
352
s = 1.0 / (1-w);
353
354
R = R + F[0] * (-u-v-1) * ( -1 + u*v*s*s ) / 4;
355
R = R + F[1] * ( u-v-1) * ( -1 - u*v*s*s ) / 4;
356
R = R + F[2] * ( u+v-1) * ( -1 + u*v*s*s ) / 4;
357
R = R + F[3] * (-u+v-1) * ( -1 - u*v*s*s ) / 4;
358
359
R = R + F[4] * (4*w-1);
360
361
R = R + F[5] * ( ( -(1-u-w)*(1-v-w) - (1+u-w)*(1-v-w) - (1+u-w)*(1-u-w) ) * s +
362
( 1+u-w)*(1-u-w)*(1-v-w) * s*s ) / 2;
363
364
R = R + F[6] * ( ( -(1-v-w)*(1+u-w) - (1+v-w)*(1+u-w) - (1+v-w)*(1-v-w) ) * s +
365
( 1+v-w)*(1-v-w)*(1+u-w) * s*s ) / 2;
366
367
R = R + F[7] * ( ( -(1-u-w)*(1+v-w) - (1+u-w)*(1+v-w) - (1+u-w)*(1-u-w) ) * s +
368
( 1+u-w)*(1-u-w)*(1+v-w) * s*s ) / 2;
369
370
R = R + F[8] * ( ( -(1-v-w)*(1-u-w) - (1+v-w)*(1-u-w) - (1+v-w)*(1-v-w) ) * s +
371
( 1+v-w)*(1-v-w)*(1-u-w) * s*s ) / 2;
372
373
R = R + F[ 9] * ( ( (1-u-w) * (1-v-w) - w * (1-v-w) - w * (1-u-w) ) * s +
374
w * (1-u-w) * (1-v-w) * s*s );
375
376
R = R + F[10] * ( ( (1+u-w) * (1-v-w) - w * (1-v-w) - w * (1+u-w) ) * s +
377
w * (1+u-w) * (1-v-w) * s*s );
378
379
R = R + F[11] * ( ( (1+u-w) * (1+v-w) - w * (1+v-w) - w * (1+u-w) ) * s +
380
w * (1+u-w) * (1+v-w) * s*s );
381
382
R = R + F[12] * ( ( (1-u-w) * (1+v-w) - w * (1+v-w) - w * (1-u-w) ) * s +
383
w * (1-u-w) * (1+v-w) * s*s );
384
385
386
return R;
387
}
388
389
/******************************************************************************
390
*
391
* Name: elm_13node_pyramid_initialize
392
*
393
* Purpose: Register the element type
394
*
395
* Parameters:
396
*
397
* Input: (char *) description of the element
398
* (int) numeric code for the element
399
*
400
* Output: Global list of element types is modified
401
*
402
* Return value: malloc() success
403
*
404
******************************************************************************/
405
int elm_13node_pyramid_initialize()
406
{
407
static char *Name = "ELM_13NODE_PYRAMID";
408
409
element_type_t ElementDef;
410
411
int elm_add_element_type();
412
413
elm_13node_pyramid_shape_functions();
414
415
ElementDef.ElementName = Name;
416
ElementDef.ElementCode = 613;
417
418
ElementDef.NumberOfNodes = 13;
419
420
ElementDef.NodeU = NodeU;
421
ElementDef.NodeV = NodeV;
422
ElementDef.NodeW = NodeW;
423
424
ElementDef.PartialU = (double (*)())elm_13node_pyramid_dndu_fvalue;
425
ElementDef.PartialV = (double (*)())elm_13node_pyramid_dndv_fvalue;
426
ElementDef.PartialW = (double (*)())elm_13node_pyramid_dndw_fvalue;
427
428
ElementDef.FunctionValue = (double (*)())elm_13node_pyramid_fvalue;
429
ElementDef.Triangulate = (int (*)())elm_13node_pyramid_triangulate;
430
ElementDef.PointInside = (int (*)())NULL;
431
432
return elm_add_element_type( &ElementDef );
433
}
434
435