OOFEM 3.0
Loading...
Searching...
No Matches
fei3dtetlin.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "fei3dtetlin.h"
36#include "mathfem.h"
37#include "floatmatrix.h"
38#include "floatarray.h"
39#include "floatarrayf.h"
40#include "floatmatrixf.h"
42
43namespace oofem {
44
46FEI3dTetLin :: evalN(const FloatArrayF<3> &lcoords)
47{
48 return {
49 lcoords[0],
50 lcoords[1],
51 lcoords[2],
52 1.0 - lcoords[0] - lcoords[1] - lcoords[2]
53 };
54}
55
56void
57FEI3dTetLin :: evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
58{
59#if 0
60 answer = evalN(lcoords);
61#else
62 answer.resize(4);
63
64 answer.at(1) = lcoords.at(1);
65 answer.at(2) = lcoords.at(2);
66 answer.at(3) = lcoords.at(3);
67 answer.at(4) = 1. - lcoords.at(1) - lcoords.at(2) - lcoords.at(3);
68#endif
69}
70
71std::pair<double, FloatMatrixF<3,4>>
72FEI3dTetLin :: evaldNdx(const FEICellGeometry &cellgeo)
73{
74 //auto [x1, y1, z1] = cellgeo.giveVertexCoordinates(1);
75 //auto [x2, y2, z2] = cellgeo.giveVertexCoordinates(2);
76 //auto [x3, y3, z3] = cellgeo.giveVertexCoordinates(3);
77 //auto [x4, y4, z4] = cellgeo.giveVertexCoordinates(4);
78
79 double x1 = cellgeo.giveVertexCoordinates(1).at(1);
80 double x2 = cellgeo.giveVertexCoordinates(2).at(1);
81 double x3 = cellgeo.giveVertexCoordinates(3).at(1);
82 double x4 = cellgeo.giveVertexCoordinates(4).at(1);
83
84 double y1 = cellgeo.giveVertexCoordinates(1).at(2);
85 double y2 = cellgeo.giveVertexCoordinates(2).at(2);
86 double y3 = cellgeo.giveVertexCoordinates(3).at(2);
87 double y4 = cellgeo.giveVertexCoordinates(4).at(2);
88
89 double z1 = cellgeo.giveVertexCoordinates(1).at(3);
90 double z2 = cellgeo.giveVertexCoordinates(2).at(3);
91 double z3 = cellgeo.giveVertexCoordinates(3).at(3);
92 double z4 = cellgeo.giveVertexCoordinates(4).at(3);
93
94 double detJ = ( ( x4 - x1 ) * ( y2 - y1 ) * ( z3 - z1 ) - ( x4 - x1 ) * ( y3 - y1 ) * ( z2 - z1 ) +
95 ( x3 - x1 ) * ( y4 - y1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( y4 - y1 ) * ( z3 - z1 ) +
96 ( x2 - x1 ) * ( y3 - y1 ) * ( z4 - z1 ) - ( x3 - x1 ) * ( y2 - y1 ) * ( z4 - z1 ) );
97
98 FloatMatrixF<3,4> ans = {
99 -( ( y3 - y2 ) * ( z4 - z2 ) - ( y4 - y2 ) * ( z3 - z2 ) ),
100 -( ( x4 - x2 ) * ( z3 - z2 ) - ( x3 - x2 ) * ( z4 - z2 ) ),
101 -( ( x3 - x2 ) * ( y4 - y2 ) - ( x4 - x2 ) * ( y3 - y2 ) ),
102 ( y4 - y3 ) * ( z1 - z3 ) - ( y1 - y3 ) * ( z4 - z3 ),
103 ( x1 - x3 ) * ( z4 - z3 ) - ( x4 - x3 ) * ( z1 - z3 ),
104 ( x4 - x3 ) * ( y1 - y3 ) - ( x1 - x3 ) * ( y4 - y3 ),
105 -( ( y1 - y4 ) * ( z2 - z4 ) - ( y2 - y4 ) * ( z1 - z4 ) ),
106 -( ( x2 - x4 ) * ( z1 - z4 ) - ( x1 - x4 ) * ( z2 - z4 ) ),
107 -( ( x1 - x4 ) * ( y2 - y4 ) - ( x2 - x4 ) * ( y1 - y4 ) ),
108 ( y2 - y1 ) * ( z3 - z1 ) - ( y3 - y1 ) * ( z2 - z1 ),
109 ( x3 - x1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( z3 - z1 ),
110 ( x2 - x1 ) * ( y3 - y1 ) - ( x3 - x1 ) * ( y2 - y1 ),
111 };
112 return {detJ, ans * (1. / detJ)};
113}
114
115double
116FEI3dTetLin :: evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
117{
118#if 0
119 auto tmp = evaldNdx(lcoords, cellgeo);
120 answer = tmp.second;
121 return tmp.first;
122#else
123 double x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, detJ;
124 answer.resize(4, 3);
125
126 x1 = cellgeo.giveVertexCoordinates(1).at(1);
127 x2 = cellgeo.giveVertexCoordinates(2).at(1);
128 x3 = cellgeo.giveVertexCoordinates(3).at(1);
129 x4 = cellgeo.giveVertexCoordinates(4).at(1);
130
131 y1 = cellgeo.giveVertexCoordinates(1).at(2);
132 y2 = cellgeo.giveVertexCoordinates(2).at(2);
133 y3 = cellgeo.giveVertexCoordinates(3).at(2);
134 y4 = cellgeo.giveVertexCoordinates(4).at(2);
135
136 z1 = cellgeo.giveVertexCoordinates(1).at(3);
137 z2 = cellgeo.giveVertexCoordinates(2).at(3);
138 z3 = cellgeo.giveVertexCoordinates(3).at(3);
139 z4 = cellgeo.giveVertexCoordinates(4).at(3);
140
141 detJ = ( ( x4 - x1 ) * ( y2 - y1 ) * ( z3 - z1 ) - ( x4 - x1 ) * ( y3 - y1 ) * ( z2 - z1 ) +
142 ( x3 - x1 ) * ( y4 - y1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( y4 - y1 ) * ( z3 - z1 ) +
143 ( x2 - x1 ) * ( y3 - y1 ) * ( z4 - z1 ) - ( x3 - x1 ) * ( y2 - y1 ) * ( z4 - z1 ) );
144
145 if ( detJ <= 0.0 ) {
146 OOFEM_ERROR("negative volume");
147 }
148
149 answer.at(1, 1) = -( ( y3 - y2 ) * ( z4 - z2 ) - ( y4 - y2 ) * ( z3 - z2 ) );
150 answer.at(2, 1) = ( y4 - y3 ) * ( z1 - z3 ) - ( y1 - y3 ) * ( z4 - z3 );
151 answer.at(3, 1) = -( ( y1 - y4 ) * ( z2 - z4 ) - ( y2 - y4 ) * ( z1 - z4 ) );
152 answer.at(4, 1) = ( y2 - y1 ) * ( z3 - z1 ) - ( y3 - y1 ) * ( z2 - z1 );
153
154 answer.at(1, 2) = -( ( x4 - x2 ) * ( z3 - z2 ) - ( x3 - x2 ) * ( z4 - z2 ) );
155 answer.at(2, 2) = ( x1 - x3 ) * ( z4 - z3 ) - ( x4 - x3 ) * ( z1 - z3 );
156 answer.at(3, 2) = -( ( x2 - x4 ) * ( z1 - z4 ) - ( x1 - x4 ) * ( z2 - z4 ) );
157 answer.at(4, 2) = ( x3 - x1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( z3 - z1 );
158
159 answer.at(1, 3) = -( ( x3 - x2 ) * ( y4 - y2 ) - ( x4 - x2 ) * ( y3 - y2 ) );
160 answer.at(2, 3) = ( x4 - x3 ) * ( y1 - y3 ) - ( x1 - x3 ) * ( y4 - y3 );
161 answer.at(3, 3) = -( ( x1 - x4 ) * ( y2 - y4 ) - ( x2 - x4 ) * ( y1 - y4 ) );
162 answer.at(4, 3) = ( x2 - x1 ) * ( y3 - y1 ) - ( x3 - x1 ) * ( y2 - y1 );
163
164 answer.times(1. / detJ);
165
166 return detJ;
167#endif
168}
169
170void
171FEI3dTetLin :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
172{
173 FloatArray n;
174 this->evalN(n, lcoords, cellgeo);
175
176 answer.clear();
177 for ( int i = 1; i <= 4; i++ ) {
178 answer.add( n.at(i), cellgeo.giveVertexCoordinates(i) );
179 }
180}
181
182#define POINT_TOL 1.e-3
183
184int
185FEI3dTetLin :: global2local(FloatArray &answer, const FloatArray &coords, const FEICellGeometry &cellgeo) const
186{
187 double x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, xp, yp, zp, volume;
188 answer.resize(4);
189
190 x1 = cellgeo.giveVertexCoordinates(1).at(1);
191 x2 = cellgeo.giveVertexCoordinates(2).at(1);
192 x3 = cellgeo.giveVertexCoordinates(3).at(1);
193 x4 = cellgeo.giveVertexCoordinates(4).at(1);
194
195 y1 = cellgeo.giveVertexCoordinates(1).at(2);
196 y2 = cellgeo.giveVertexCoordinates(2).at(2);
197 y3 = cellgeo.giveVertexCoordinates(3).at(2);
198 y4 = cellgeo.giveVertexCoordinates(4).at(2);
199
200 z1 = cellgeo.giveVertexCoordinates(1).at(3);
201 z2 = cellgeo.giveVertexCoordinates(2).at(3);
202 z3 = cellgeo.giveVertexCoordinates(3).at(3);
203 z4 = cellgeo.giveVertexCoordinates(4).at(3);
204
205 xp = coords.at(1);
206 yp = coords.at(2);
207 zp = coords.at(3);
208
209 volume = ( ( x4 - x1 ) * ( y2 - y1 ) * ( z3 - z1 ) - ( x4 - x1 ) * ( y3 - y1 ) * ( z2 - z1 ) +
210 ( x3 - x1 ) * ( y4 - y1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( y4 - y1 ) * ( z3 - z1 ) +
211 ( x2 - x1 ) * ( y3 - y1 ) * ( z4 - z1 ) - ( x3 - x1 ) * ( y2 - y1 ) * ( z4 - z1 ) ) / 6.;
212
213 answer.resize(4);
214
215 answer.at(1) = ( ( x3 - x2 ) * ( yp - y2 ) * ( z4 - z2 ) - ( xp - x2 ) * ( y3 - y2 ) * ( z4 - z2 ) +
216 ( x4 - x2 ) * ( y3 - y2 ) * ( zp - z2 ) - ( x4 - x2 ) * ( yp - y2 ) * ( z3 - z2 ) +
217 ( xp - x2 ) * ( y4 - y2 ) * ( z3 - z2 ) - ( x3 - x2 ) * ( y4 - y2 ) * ( zp - z2 ) ) / 6. / volume;
218
219 answer.at(2) = ( ( x4 - x1 ) * ( yp - y1 ) * ( z3 - z1 ) - ( xp - x1 ) * ( y4 - y1 ) * ( z3 - z1 ) +
220 ( x3 - x1 ) * ( y4 - y1 ) * ( zp - z1 ) - ( x3 - x1 ) * ( yp - y1 ) * ( z4 - z1 ) +
221 ( xp - x1 ) * ( y3 - y1 ) * ( z4 - z1 ) - ( x4 - x1 ) * ( y3 - y1 ) * ( zp - z1 ) ) / 6. / volume;
222
223 answer.at(3) = ( ( x2 - x1 ) * ( yp - y1 ) * ( z4 - z1 ) - ( xp - x1 ) * ( y2 - y1 ) * ( z4 - z1 ) +
224 ( x4 - x1 ) * ( y2 - y1 ) * ( zp - z1 ) - ( x4 - x1 ) * ( yp - y1 ) * ( z2 - z1 ) +
225 ( xp - x1 ) * ( y4 - y1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( y4 - y1 ) * ( zp - z1 ) ) / 6. / volume;
226
227 // test if inside + clamping
228 bool inside = true;
229 for ( int i = 1; i <= 3; i++ ) {
230 if ( answer.at(i) < ( 0. - POINT_TOL ) ) {
231 answer.at(i) = 0.;
232 inside = false;
233 } else if ( answer.at(i) > ( 1. + POINT_TOL ) ) {
234 answer.at(i) = 1.;
235 inside = false;
236 }
237 }
238
239 answer.at(4) = 1.0 - answer.at(1) - answer.at(2) - answer.at(3);
240
241 return inside;
242}
243
244
245double
246FEI3dTetLin :: giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
247{
248 double detJ, x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4;
249
250 x1 = cellgeo.giveVertexCoordinates(1).at(1);
251 x2 = cellgeo.giveVertexCoordinates(2).at(1);
252 x3 = cellgeo.giveVertexCoordinates(3).at(1);
253 x4 = cellgeo.giveVertexCoordinates(4).at(1);
254
255 y1 = cellgeo.giveVertexCoordinates(1).at(2);
256 y2 = cellgeo.giveVertexCoordinates(2).at(2);
257 y3 = cellgeo.giveVertexCoordinates(3).at(2);
258 y4 = cellgeo.giveVertexCoordinates(4).at(2);
259
260 z1 = cellgeo.giveVertexCoordinates(1).at(3);
261 z2 = cellgeo.giveVertexCoordinates(2).at(3);
262 z3 = cellgeo.giveVertexCoordinates(3).at(3);
263 z4 = cellgeo.giveVertexCoordinates(4).at(3);
264
265 detJ = ( ( x4 - x1 ) * ( y2 - y1 ) * ( z3 - z1 ) - ( x4 - x1 ) * ( y3 - y1 ) * ( z2 - z1 ) +
266 ( x3 - x1 ) * ( y4 - y1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( y4 - y1 ) * ( z3 - z1 ) +
267 ( x2 - x1 ) * ( y3 - y1 ) * ( z4 - z1 ) - ( x3 - x1 ) * ( y2 - y1 ) * ( z4 - z1 ) );
268
269 return detJ;
270}
271
272
273void
274FEI3dTetLin :: edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
275{
276 double ksi = lcoords.at(1);
277 answer.resize(2);
278
279 answer.at(1) = ( 1. - ksi ) * 0.5;
280 answer.at(2) = ( 1. + ksi ) * 0.5;
281}
282
283void
284FEI3dTetLin :: edgeEvaldNdx(FloatMatrix &answer, int iedge,
285 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
286{
287 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
288 double l = this->edgeComputeLength(edgeNodes, cellgeo);
289 double coeff = 1.0 / l / l;
290
291 double x1 = cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(1);
292 double y1 = cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(2);
293 double z1 = cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(3);
294 double x2 = cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(1);
295 double y2 = cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(2);
296 double z2 = cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(3);
297
298 answer.resize(2, 3);
299 answer.at(1, 1) = ( x1 - x2 ) * coeff;
300 answer.at(1, 2) = ( y1 - y2 ) * coeff;
301 answer.at(1, 3) = ( z1 - z2 ) * coeff;
302
303 answer.at(2, 1) = ( x2 - x1 ) * coeff;
304 answer.at(2, 2) = ( y2 - y1 ) * coeff;
305 answer.at(2, 3) = ( z2 - z1 ) * coeff;
306}
307
308void
309FEI3dTetLin :: edgeLocal2global(FloatArray &answer, int iedge,
310 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
311{
312 FloatArray n;
313 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
314 this->edgeEvalN(n, iedge, lcoords, cellgeo);
315
316 answer.resize(3);
317 answer.at(1) = n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(1) +
318 n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(1);
319 answer.at(2) = n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(2) +
320 n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(2);
321 answer.at(3) = n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(3) +
322 n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(3);
323}
324
325
326double
327FEI3dTetLin :: edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
328{
329 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
330 return 0.5 * this->edgeComputeLength(edgeNodes, cellgeo);
331}
332
333
335FEI3dTetLin :: computeLocalEdgeMapping(int iedge) const
336{
337 if ( iedge == 1 ) { // edge between nodes 1 2
338 return {1, 2};
339 } else if ( iedge == 2 ) { // edge between nodes 2 3
340 return {2, 3};
341 } else if ( iedge == 3 ) { // edge between nodes 3 1
342 return {3, 1};
343 } else if ( iedge == 4 ) { // edge between nodes 1 4
344 return {1, 4};
345 } else if ( iedge == 5 ) { // edge between nodes 2 4
346 return {2, 4};
347 } else if ( iedge == 6 ) { // edge between nodes 3 4
348 return {3, 4};
349 } else {
350 throw std::range_error("invalid edge number");
351 }
352}
353
354double
355FEI3dTetLin :: edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
356{
357 return distance(cellgeo.giveVertexCoordinates( edgeNodes.at(2) ), cellgeo.giveVertexCoordinates( edgeNodes.at(1) ));
358}
359
360void
361FEI3dTetLin :: surfaceEvalN(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
362{
363 answer.resize(3);
364
365 answer.at(1) = lcoords.at(1);
366 answer.at(2) = lcoords.at(2);
367 answer.at(3) = 1. - lcoords.at(1) - lcoords.at(2);
368}
369
370void
371FEI3dTetLin :: surfaceLocal2global(FloatArray &answer, int iedge,
372 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
373{
374 const auto &nodes = computeLocalSurfaceMapping(iedge);
375
376 double l1 = lcoords.at(1);
377 double l2 = lcoords.at(2);
378 double l3 = 1.0 - l1 - l2;
379
380 answer.resize(3);
381 answer.at(1) = l1 * cellgeo.giveVertexCoordinates( nodes.at(1) ).at(1) +
382 l2 * cellgeo.giveVertexCoordinates( nodes.at(2) ).at(1) +
383 l3 * cellgeo.giveVertexCoordinates( nodes.at(3) ).at(1);
384 answer.at(2) = l1 * cellgeo.giveVertexCoordinates( nodes.at(1) ).at(2) +
385 l2 * cellgeo.giveVertexCoordinates( nodes.at(2) ).at(2) +
386 l3 * cellgeo.giveVertexCoordinates( nodes.at(3) ).at(2);
387 answer.at(3) = l1 * cellgeo.giveVertexCoordinates( nodes.at(1) ).at(3) +
388 l2 * cellgeo.giveVertexCoordinates( nodes.at(2) ).at(3) +
389 l3 * cellgeo.giveVertexCoordinates( nodes.at(3) ).at(3);
390}
391
392void
393FEI3dTetLin :: surfaceEvaldNdx(FloatMatrix &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
394{
395 // Note, this must be in correct order, not just the correct nodes, therefore we must use snodes;
396 const auto &snodes = this->computeLocalSurfaceMapping(isurf);
397
398 FloatArray lcoords_tet(4);
399 lcoords_tet.at(snodes.at(1)) = lcoords.at(1);
400 lcoords_tet.at(snodes.at(2)) = lcoords.at(2);
401 lcoords_tet.at(snodes.at(3)) = 1. - lcoords.at(1) - lcoords.at(2);
402
403 FloatMatrix fullB;
404 this->evaldNdx(fullB, lcoords_tet, cellgeo);
405 answer.resize(snodes.giveSize(), 3);
406 for ( int i = 1; i <= snodes.giveSize(); ++i ) {
407 for ( int j = 1; j <= 3; ++j ) {
408 answer.at(i, j) = fullB.at(snodes.at(i), j);
409 }
410 }
411}
412
413double
414FEI3dTetLin :: surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
415{
416 const auto &snodes = this->computeLocalSurfaceMapping(isurf);
417
418 FloatArray a, b;
419 a.beDifferenceOf( cellgeo.giveVertexCoordinates( snodes.at(2) ), cellgeo.giveVertexCoordinates( snodes.at(1) ) );
420 b.beDifferenceOf( cellgeo.giveVertexCoordinates( snodes.at(3) ), cellgeo.giveVertexCoordinates( snodes.at(1) ) );
421 answer.beVectorProductOf(a, b);
422
423 return answer.normalize_giveNorm();
424}
425
426double
427FEI3dTetLin :: surfaceGiveTransformationJacobian(int isurf, const FloatArray &lcoords,
428 const FEICellGeometry &cellgeo) const
429{
430 FloatArray c;
431 return this->surfaceEvalNormal(c, isurf, lcoords, cellgeo);
432}
433
435FEI3dTetLin :: computeLocalSurfaceMapping(int isurf) const
436{
437 int aNode = 0, bNode = 0, cNode = 0;
438
439 if ( isurf == 1 ) { // surface 1 - nodes 1 3 2
440 aNode = 1;
441 bNode = 3;
442 cNode = 2;
443 } else if ( isurf == 2 ) { // surface 2 - nodes 1 2 4
444 aNode = 1;
445 bNode = 2;
446 cNode = 4;
447 } else if ( isurf == 3 ) { // surface 3 - nodes 2 3 4
448 aNode = 2;
449 bNode = 3;
450 cNode = 4;
451 } else if ( isurf == 4 ) { // surface 4 - nodes 1 4 3
452 aNode = 1;
453 bNode = 4;
454 cNode = 3;
455 } else {
456 OOFEM_ERROR("wrong surface number (%d)", isurf);
457 }
458
459 return {aNode, bNode, cNode};
460}
461
462double
463FEI3dTetLin :: evalNXIntegral(int iEdge, const FEICellGeometry &cellgeo) const
464{
465 auto fNodes = this->computeLocalSurfaceMapping(iEdge);
466
467 const FloatArray &c1 = cellgeo.giveVertexCoordinates( fNodes.at(1) );
468 const FloatArray &c2 = cellgeo.giveVertexCoordinates( fNodes.at(2) );
469 const FloatArray &c3 = cellgeo.giveVertexCoordinates( fNodes.at(3) );
470
471 return ( ( c2.at(1) * c3.at(2) - c3.at(1) * c2.at(2) ) * c1.at(3) +
472 ( c3.at(1) * c1.at(2) - c1.at(1) * c3.at(2) ) * c2.at(3) +
473 ( c1.at(1) * c2.at(2) - c2.at(1) * c1.at(2) ) * c3.at(3) ) * 0.5;
474}
475
476std::unique_ptr<IntegrationRule>
477FEI3dTetLin :: giveIntegrationRule(int order, Element_Geometry_Type egt) const
478{
479 auto iRule = std::make_unique<GaussIntegrationRule>(1, nullptr);
480 int points = iRule->getRequiredNumberOfIntegrationPoints(_Tetrahedra, order + 0);
481 iRule->SetUpPointsOnTetrahedra(points, _Unknown);
482 return std::move(iRule);
483}
484
485std::unique_ptr<IntegrationRule>
486FEI3dTetLin :: giveBoundaryIntegrationRule(int order, int boundary, Element_Geometry_Type egt) const
487{
488 auto iRule = std::make_unique<GaussIntegrationRule>(1, nullptr);
489 int points = iRule->getRequiredNumberOfIntegrationPoints(_Triangle, order + 0);
490 iRule->SetUpPointsOnTriangle(points, _Unknown);
491 return std::move(iRule);
492}
493} // end namespace oofem
IntArray computeLocalSurfaceMapping(int iedge) const override
static FloatArrayF< 4 > evalN(const FloatArrayF< 3 > &lcoords)
Definition fei3dtetlin.C:46
void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei3dtetlin.C:57
void edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
double surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
static std::pair< double, FloatMatrixF< 3, 4 > > evaldNdx(const FEICellGeometry &cellgeo)
Definition fei3dtetlin.C:72
double edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
IntArray computeLocalEdgeMapping(int iedge) const override
virtual const FloatArray giveVertexCoordinates(int i) const =0
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
double normalize_giveNorm()
Definition floatarray.C:850
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
Definition floatarray.C:476
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double f)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
double at(std::size_t i, std::size_t j) const
int & at(std::size_t i)
Definition intarray.h:104
#define OOFEM_ERROR(...)
Definition error.h:79
#define POINT_TOL
double distance(const FloatArray &x, const FloatArray &y)

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011