Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/post/src/elements/5node_quad.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 5 node quad 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. +355 0 457 2723
36
* Telefax: +355 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 20 Sep 1995
40
*
41
* Modification history:
42
*
43
* 25 Sep 1995, changed call to elm_triangle_normal to geo_triangle normal
44
* routine elm_... doesn't exist anymore
45
* Juha R
46
*
47
*
48
******************************************************************************/
49
50
#include "../elmerpost.h"
51
#include <elements.h>
52
53
/*
54
*
55
*/
56
57
static double N[5][5],A[5][5];
58
59
static double NodeU[] = { -1.0, 1.0, 1.0, -1.0, 0.0 };
60
static double NodeV[] = { -1.0, -1.0, 1.0, 1.0, 0.0,};
61
62
/*******************************************************************************
63
*
64
* Name: elm_5node_quad_shape_functions( )
65
*
66
* Purpose: Initialize element shape function array. Internal only.
67
*
68
* Parameters:
69
*
70
* Input: Global (filewise) variables NodeU,NodeV,NodeW
71
*
72
* Output: Global (filewise) variable N[6][6], will contain
73
* shape function coefficients
74
*
75
* Return value: void
76
*
77
******************************************************************************/
78
static void elm_5node_quad_shape_functions()
79
{
80
double u,v;
81
82
int i,j;
83
84
for( i=0; i<5; i++ )
85
{
86
u = NodeU[i];
87
v = NodeV[i];
88
89
A[i][0] = 1;
90
A[i][1] = u;
91
A[i][2] = v;
92
A[i][3] = u*v;
93
A[i][4] = u*u*v*v;
94
}
95
96
lu_mtrinv( (double *)A,5 );
97
98
for( i=0; i<5; i++ )
99
for( j=0; j<5; j++ ) N[i][j] = A[j][i];
100
}
101
102
103
/*******************************************************************************
104
*
105
* Name: elm_5node_quad_triangulate( geometry_t *,element_t * )
106
*
107
* Purpose: Triangulate an element. The process also builds up an edge
108
* table and adds new nodes to node table. The triangulation
109
* and edge table is stored in geometry_t *geom-structure.
110
*
111
* Parameters:
112
*
113
* Input: (geometry_t *) pointer to structure holding triangulation
114
* (element_t *) element to triangulate
115
*
116
* Output: (geometry_t *) structure is modified
117
*
118
* Return value: FALSE if malloc() fails, TRUE otherwise
119
*
120
******************************************************************************/
121
int elm_5node_quad_triangulate( geometry_t *geom,element_t *Elm )
122
{
123
triangle_t triangle;
124
125
triangle.Element = Elm;
126
127
triangle.v[0] = Elm->Topology[0];
128
triangle.v[1] = Elm->Topology[1];
129
triangle.v[2] = Elm->Topology[4];
130
131
triangle.Edge[0] = TRUE;
132
triangle.Edge[1] = FALSE;
133
triangle.Edge[2] = FALSE;
134
135
if ( !geo_add_triangle( geom,&triangle ) ) return FALSE;
136
137
triangle.v[0] = Elm->Topology[1];
138
triangle.v[1] = Elm->Topology[2];
139
triangle.v[2] = Elm->Topology[4];
140
141
triangle.Edge[0] = TRUE;
142
triangle.Edge[1] = FALSE;
143
triangle.Edge[2] = FALSE;
144
145
if ( !geo_add_triangle( geom,&triangle ) ) return FALSE;
146
147
triangle.v[0] = Elm->Topology[2];
148
triangle.v[1] = Elm->Topology[3];
149
triangle.v[2] = Elm->Topology[4];
150
151
triangle.Edge[0] = TRUE;
152
triangle.Edge[1] = FALSE;
153
triangle.Edge[2] = FALSE;
154
155
if ( !geo_add_triangle( geom,&triangle ) ) return FALSE;
156
157
triangle.v[0] = Elm->Topology[3];
158
triangle.v[1] = Elm->Topology[0];
159
triangle.v[2] = Elm->Topology[4];
160
161
triangle.Edge[0] = TRUE;
162
triangle.Edge[1] = FALSE;
163
triangle.Edge[2] = FALSE;
164
165
if ( !geo_add_triangle( geom,&triangle ) ) return FALSE;
166
167
return TRUE;
168
}
169
170
/*******************************************************************************
171
*
172
* Name: elm_5node_quad_fvalue( double *,double,double )
173
*
174
* Purpose: return value of a quantity given on nodes at point (u,v)
175
*
176
*
177
*
178
* Parameters:
179
*
180
* Input: (double *) quantity values at nodes
181
* (double u,double v) point where values are evaluated
182
*
183
* Output: none
184
*
185
* Return value: quantity value
186
*
187
******************************************************************************/
188
static double elm_5node_quad_fvalue( double *F, double u, double v )
189
{
190
double R,uv=u*v,uu=u*u,vv=v*v,uuv=uu*v,uvv=u*vv;
191
int i;
192
193
R = 0.0;
194
for( i=0; i<5; i++ )
195
{
196
R += F[i]*(N[i][0] +
197
N[i][1]*u +
198
N[i][2]*v +
199
N[i][3]*uv +
200
N[i][4]*uu*vv );
201
}
202
203
return R;
204
}
205
206
/*******************************************************************************
207
*
208
* Name: elm_5node_quad_dndu_fvalue( double *,double,double )
209
*
210
* Purpose: return value of a first partial derivate in (u) of a
211
* quantity given on nodes at point (u,v)
212
*
213
*
214
* Parameters:
215
*
216
* Input: (double *) quantity values at nodes
217
* (double u,double v) point where values are evaluated
218
*
219
* Output: none
220
*
221
* Return value: quantity value
222
*
223
******************************************************************************/
224
static double elm_5node_quad_dndu_fvalue( double *F, double u, double v )
225
{
226
double R=0.0,uv=u*v,vv=v*v;
227
int i;
228
229
for( i=0; i<5; i++ )
230
{
231
R += F[i]*(N[i][1]+N[i][3]*v+2*N[i][4]*u*v*v );
232
}
233
234
return R;
235
}
236
237
/*******************************************************************************
238
*
239
* Name: elm_5node_quad_dndv_fvalue( double *,double,double )
240
*
241
* Purpose: return value of a first partial derivate in (v) of a
242
* quantity given on nodes at point (u,v)
243
*
244
*
245
* Parameters:
246
*
247
* Input: (double *) quantity values at nodes
248
* (double u,double v) point where values are evaluated
249
*
250
* Output: none
251
*
252
* Return value: quantity value
253
*
254
******************************************************************************/
255
static double elm_5node_quad_dndv_fvalue( double *F, double u, double v )
256
{
257
double R=0.0,uu=u*u,uv=u*v;
258
259
int i;
260
261
for( i=0; i<5; i++ )
262
{
263
R += F[i]*(N[i][2]+N[i][3]*u+2*N[i][4]*uu*v );
264
}
265
266
return R;
267
}
268
269
/*******************************************************************************
270
*
271
* Name: elm_5node_quad_dd(double *F,double *u,double *v,double *Values)
272
*
273
* Purpose: Return matrix of second partial derivates of given quantity
274
* at given point u,v.
275
*
276
* Parameters:
277
*
278
* Input: (double *)F: quantity values at nodes
279
* (double)u,v: point of evaluation
280
*
281
* Output: (double *)Values: 2x2 matrix of partial derivates
282
*
283
* Return value: void
284
*
285
*******************************************************************************/
286
static void elm_5node_quad_ddu( double *F,double u,double v,double *Values )
287
{
288
double ddu = 0.0, dudv=0.0, ddv = 0.0;
289
290
int i;
291
292
for( i=0; i<5; i++ )
293
{
294
ddu += F[i]*( 2*N[i][4]*v*v );
295
ddv += F[i]*( 2*N[i][4]*u*u );
296
dudv += F[i]*( N[i][3] + 4*N[i][4]*u*v );
297
}
298
299
Values[0] = ddu;
300
Values[1] = dudv;
301
Values[2] = dudv;
302
Values[3] = ddv;
303
}
304
305
/*******************************************************************************
306
*
307
* Name: elm_5node_quad_point_inside(
308
* double *nx,double *ny,double *nz,
309
* double px, double py, double pz,
310
* double *u,double *v,double *w )
311
*
312
* Purpose: Find if point (px,py,pz) is inside the element, and return
313
* element coordinates of the point.
314
*
315
* Parameters:
316
*
317
* Input: (double *) nx,ny,nz n coordinates
318
* (double) px,py,pz point to consider
319
*
320
* Output: (double *) u,v,w point in element coordinates if inside
321
*
322
* Return value: in/out status
323
*
324
* NOTES: the goal here can be hard for more involved element types. kind of
325
* trivial for this one... TODO: FIX THIS....
326
*
327
******************************************************************************/
328
int elm_5node_quad_point_inside
329
(
330
double *nx, double *ny, double *nz,
331
double px, double py, double pz, double *u,double *v,double *w
332
)
333
{
334
int elm_4node_quad_point_inside();
335
return elm_4node_quad_point_inside( nx,ny,nz,px,py,pz,u,v,w );
336
}
337
338
/*******************************************************************************
339
*
340
* Name: elm_5node_quad_isoline
341
*
342
* Purpose: Extract a iso line from triangle with given threshold
343
*
344
* Parameters:
345
*
346
* Input: (double) K, contour threshold
347
* (double *) F, contour quantity
348
* (double *) C, color quantity
349
* (double *) X,Y,Z vertex coords.
350
*
351
* Output: (line_t *) place to store the line
352
*
353
* Return value: number of lines generated (0,...,4)
354
*
355
******************************************************************************/
356
int elm_5node_quad_isoline
357
(
358
double K, double *F, double *C,double *X,double *Y,double *Z,line_t *Line
359
)
360
{
361
double f[4],c[4],x[4],y[4],z[4];
362
363
int i, j, k, n=0, above=0;
364
365
static int map[4][2] =
366
{
367
{ 0,1 }, { 1,2 }, { 2,3 }, { 3,0 }
368
};
369
370
int elm_3node_triangle_isoline();
371
372
for( i=0; i<5; i++ ) above += F[i]>K;
373
if ( above == 0 || above == 5 ) return 0;
374
375
f[2] = F[4];
376
c[2] = C[4];
377
x[2] = X[4];
378
y[2] = Y[4];
379
z[2] = Z[4];
380
381
for( i=0; i<4; i++ )
382
{
383
for( j=1; j<2; j++ )
384
{
385
k = map[i][j];
386
f[j] = F[k];
387
c[j] = C[k];
388
x[j] = X[k];
389
y[j] = Y[k];
390
z[j] = Z[k];
391
}
392
n += elm_3node_triangle_isoline( K,f,c,x,y,z,&Line[n] );
393
}
394
395
return n;
396
}
397
398
399
/******************************************************************************
400
*
401
* Name: elm_5node_quad_initialize( )
402
*
403
* Purpose: Register the element type
404
*
405
* Parameters:
406
*
407
* Input: (char *) description of the element
408
* (int) numeric code for the element
409
*
410
* Output: Global list of element types is modified
411
*
412
* Return value: malloc() success
413
*
414
******************************************************************************/
415
int elm_5node_quad_initialize()
416
{
417
element_type_t ElementDef;
418
419
static char *Name = "ELM_5NODE_QUAD";
420
421
int elm_add_element_type();
422
423
elm_5node_quad_shape_functions();
424
425
ElementDef.ElementName = Name;
426
ElementDef.ElementCode = 405;
427
428
ElementDef.NumberOfNodes = 5;
429
ElementDef.NodeU = NodeU;
430
ElementDef.NodeV = NodeV;
431
ElementDef.NodeW = NULL;
432
433
ElementDef.PartialU = (double (*)())elm_5node_quad_dndu_fvalue;
434
ElementDef.PartialV = (double (*)())elm_5node_quad_dndv_fvalue;
435
ElementDef.PartialW = NULL;
436
ElementDef.SecondPartials = (double (*)())elm_5node_quad_ddu;
437
438
ElementDef.FunctionValue = (double (*)())elm_5node_quad_fvalue;
439
440
ElementDef.Triangulate = (int (*)())elm_5node_quad_triangulate;
441
ElementDef.PointInside = (int (*)())elm_5node_quad_point_inside;
442
ElementDef.IsoLine = (int (*)())elm_5node_quad_isoline;
443
ElementDef.IsoSurface = (int (*)())NULL;
444
445
return elm_add_element_type( &ElementDef );
446
}
447
448