Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/post/src/elements/5node_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[5][5],N[5][5];
52
53
static double NodeU[] = { -1.0, 1.0, 1.0, -1.0, 0.0 };
54
static double NodeV[] = { -1.0,-1.0, 1.0, 1.0, 0.0 };
55
static double NodeW[] = { 0.0, 0.0, 0.0, 0.0, 1.0};
56
57
/*******************************************************************************
58
*
59
* Name: elm_5node_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_5node_pyramid_triangulate( geometry_t *geom,element_t *pyramid )
76
{
77
element_t element;
78
int i,j;
79
80
int PyramidFace[5][4] = { { 0,1,2,3 }, { 0,1,4,0 }, { 1,2,4,0 }, { 2,3,4,0 }, { 3,0,4,0 } };
81
82
int elm_4node_quad_triangulate();
83
int geo_add_edge();
84
int elm_3node_triangle_triangulate();
85
86
if ( GlobalOptions.VolumeSides )
87
{
88
int topo[4];
89
90
element.DisplayFlag = TRUE;
91
element.Topology = topo;
92
for( i=0; i<MAX_GROUP_IDS; i++ ) element.GroupIds[i] = pyramid->GroupIds[i];
93
94
for( j=0; j<4; j++ )
95
{
96
element.Topology[j] = pyramid->Topology[PyramidFace[0][j]];
97
}
98
if ( !elm_4node_quad_triangulate( geom, &element, pyramid ) ) return FALSE;
99
100
for( i=1; i<5; i++ )
101
{
102
for( j=0; j<3; j++ )
103
{
104
element.Topology[j] = pyramid->Topology[PyramidFace[i][j]];
105
}
106
}
107
if ( !elm_3node_triangle_triangulate( geom, &element, pyramid ) ) return FALSE;
108
} else {
109
if ( !geo_add_edge( geom, pyramid->Topology[0], pyramid->Topology[1],pyramid ) ) return FALSE;
110
if ( !geo_add_edge( geom, pyramid->Topology[1], pyramid->Topology[2],pyramid ) ) return FALSE;
111
if ( !geo_add_edge( geom, pyramid->Topology[2], pyramid->Topology[3],pyramid ) ) return FALSE;
112
if ( !geo_add_edge( geom, pyramid->Topology[3], pyramid->Topology[0],pyramid ) ) return FALSE;
113
if ( !geo_add_edge( geom, pyramid->Topology[0], pyramid->Topology[4],pyramid ) ) return FALSE;
114
if ( !geo_add_edge( geom, pyramid->Topology[1], pyramid->Topology[4],pyramid ) ) return FALSE;
115
if ( !geo_add_edge( geom, pyramid->Topology[2], pyramid->Topology[4],pyramid ) ) return FALSE;
116
if ( !geo_add_edge( geom, pyramid->Topology[3], pyramid->Topology[4],pyramid ) ) return FALSE;
117
}
118
119
return TRUE;
120
}
121
122
/*******************************************************************************
123
*
124
* Name: elm_5node_pyramid_shape_functions
125
*
126
* Purpose: Initialize element shape function array. Internal only.
127
*
128
* Parameters:
129
*
130
* Input: Global (filewise) variables NodeU,NodeV,NodeW
131
*
132
* Output: Global (filewise) variable N[6][6], will contain
133
* shape function coefficients
134
*
135
* Return value: void
136
* Return value: void
137
*
138
******************************************************************************/
139
static void elm_5node_pyramid_shape_functions()
140
{
141
double u,v,w;
142
int i,j;
143
144
#if 0
145
for( i=0; i<5; i++ )
146
{
147
u = NodeU[i];
148
v = NodeV[i];
149
w = NodeW[i];
150
151
A[i][0] = 1;
152
A[i][1] = u;
153
A[i][2] = v;
154
A[i][3] = w;
155
A[i][4] = u*v;
156
}
157
158
lu_mtrinv( (double *)A,5 );
159
160
for( i=0; i<5; i++ )
161
for( j=0; j<5; j++ ) N[i][j] = A[j][i];
162
#endif
163
}
164
165
/*******************************************************************************
166
*
167
* Name: elm_5node_pyramid_fvalue
168
*
169
* Purpose: return value of a quantity given on nodes at point (u,v)
170
* Use trough (element_type_t *) structure.
171
*
172
* Parameters:
173
*
174
* Input: (double *) quantity values at nodes
175
* (double u,double v) point where values are evaluated
176
*
177
* Output: none
178
*
179
* Return value: quantity value
180
*
181
******************************************************************************/
182
static double elm_5node_pyramid_fvalue(double *F,double u,double v,double w)
183
{
184
double R=0.0, s;
185
int i;
186
187
if ( w == 1 ) w = 1-1.0e-12;
188
s = 1.0 / (1-w);
189
190
R = R + F[0] * ( (1-u) * (1-v) - w + u*v*w * s ) / 4;
191
R = R + F[1] * ( (1+u) * (1-v) - w - u*v*w * s ) / 4;
192
R = R + F[2] * ( (1+u) * (1+v) - w + u*v*w * s ) / 4;
193
R = R + F[3] * ( (1-u) * (1+v) - w - u*v*w * s ) / 4;
194
R = R + F[4] * w;
195
196
return R;
197
}
198
199
/*******************************************************************************
200
*
201
* Name: elm_5node_pyramid_dndu_fvalue
202
*
203
* Purpose: return value of a first partial derivate in (v) of a
204
* quantity given on nodes at point (u,v).
205
* Use trough (element_type_t *) structure.
206
*
207
*
208
* Parameters:
209
*
210
* Input: (double *) quantity values at nodes
211
* (double u,double v,double w) point where values are evaluated
212
*
213
* Output: none
214
*
215
* Return value: quantity value
216
*
217
******************************************************************************/
218
static double elm_5node_pyramid_dndu_fvalue(double *F,double u,double v,double w)
219
{
220
double R=0.0,s;
221
int i;
222
223
if ( w == 1 ) w = 1-1.0e-12;
224
s = 1.0 / (1-w);
225
226
R = R + F[0] * ( -(1-v) + v*w * s ) / 4;
227
R = R + F[1] * ( (1-v) - v*w * s ) / 4;
228
R = R + F[2] * ( (1+v) + v*w * s ) / 4;
229
R = R + F[3] * ( -(1+v) - v*w * s ) / 4;
230
231
return R;
232
}
233
234
/*******************************************************************************
235
*
236
* Name: elm_5node_pyramid_dndv_fvalue
237
*
238
* Purpose: return value of a first partial derivate in (v) of a
239
* quantity given on nodes at point (u,v,w).
240
* Use trough (element_type_t *) structure.
241
*
242
*
243
* Parameters:
244
*
245
* Input: (double *) quantity values at nodes
246
* (double u,double v,double w) point where values are evaluated
247
*
248
* Output: none
249
*
250
* Return value: quantity value
251
*
252
******************************************************************************/
253
static double elm_5node_pyramid_dndv_fvalue(double *F,double u,double v,double w)
254
{
255
double R=0.0,s;
256
int i;
257
258
if ( w == 1 ) w = 1-1.0e-12;
259
s = 1.0 / (1-w);
260
261
R = R + F[0] * ( -(1-u) + u*w * s ) / 4;
262
R = R + F[1] * ( -(1+u) - u*w * s ) / 4;
263
R = R + F[2] * ( (1+u) + u*w * s ) / 4;
264
R = R + F[3] * ( (1-u) - u*w * s ) / 4;
265
266
return R;
267
}
268
269
/*******************************************************************************
270
*
271
* Name: elm_5node_pyramid_dndw_fvalue
272
*
273
* Purpose: return value of a first partial derivate in (w) of a
274
* quantity given on nodes at point (u,v,w)
275
* Use trough (element_type_t *) structure.
276
*
277
*
278
* Parameters:
279
*
280
* Input: (double *) quantity values at nodes
281
* (double u,double v,double w) point where values are evaluated
282
*
283
* Output: none
284
*
285
* Return value: quantity value
286
*
287
******************************************************************************/
288
static double elm_5node_pyramid_dndw_fvalue(double *F,double u,double v,double w)
289
{
290
double R=0.0,s;
291
int i;
292
293
if ( w == 1 ) w = 1.0-1.0e-12;
294
s = 1.0 / (1-w);
295
296
R = R + F[0] * ( -1 + u*v*(2-w) * s*s ) / 4;
297
R = R + F[1] * ( -1 - u*v*(2-w) * s*s ) / 4;
298
R = R + F[2] * ( -1 + u*v*(2-w) * s*s ) / 4;
299
R = R + F[3] * ( -1 - u*v*(2-w) * s*s ) / 4;
300
R = R + F[4];
301
302
return R;
303
}
304
305
/******************************************************************************
306
*
307
* Name: elm_5node_pyramid_initialize
308
*
309
* Purpose: Register the element type
310
*
311
* Parameters:
312
*
313
* Input: (char *) description of the element
314
* (int) numeric code for the element
315
*
316
* Output: Global list of element types is modified
317
*
318
* Return value: malloc() success
319
*
320
******************************************************************************/
321
int elm_5node_pyramid_initialize()
322
{
323
static char *Name = "ELM_5NODE_PYRAMID";
324
325
element_type_t ElementDef;
326
int elm_add_element_type();
327
328
elm_5node_pyramid_shape_functions();
329
330
ElementDef.ElementName = Name;
331
ElementDef.ElementCode = 605;
332
333
ElementDef.NumberOfNodes = 5;
334
335
ElementDef.NodeU = NodeU;
336
ElementDef.NodeV = NodeV;
337
ElementDef.NodeW = NodeW;
338
339
ElementDef.PartialU = (double (*)())elm_5node_pyramid_dndu_fvalue;
340
ElementDef.PartialV = (double (*)())elm_5node_pyramid_dndv_fvalue;
341
ElementDef.PartialW = (double (*)())elm_5node_pyramid_dndw_fvalue;
342
343
ElementDef.FunctionValue = (double (*)())elm_5node_pyramid_fvalue;
344
ElementDef.Triangulate = (int (*)())elm_5node_pyramid_triangulate;
345
ElementDef.PointInside = (int (*)())NULL;
346
347
return elm_add_element_type( &ElementDef );
348
}
349
350