OOFEM 3.0
Loading...
Searching...
No Matches
fei3dhexaconst.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 "fei3dhexaconst.h"
36#include "mathfem.h"
37#include "floatmatrix.h"
38#include "floatarray.h"
40#include "floatarrayf.h"
41#include "floatmatrixf.h"
42
43namespace oofem {
44
45
46
47void
48FEI3dHexaConst :: evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
49{
50
51 answer = Vec1(1.0);
52}
53
54double
55FEI3dHexaConst :: evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
56{
57 answer.resize(1,3);
58 answer.zero();
59 return 0.;
60}
61
62void
63FEI3dHexaConst :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
64{
65 FloatArray n;
66 this->evalN(n, lcoords, cellgeo);
67
68 answer.clear();
69 for ( int i = 1; i <= 8; i++ ) {
70 answer.add( n.at(i), cellgeo.giveVertexCoordinates(i) );
71 }
72}
73
74#define POINT_TOL 1.e-3
75
76int
77FEI3dHexaConst :: global2local(FloatArray &answer, const FloatArray &coords, const FEICellGeometry &cellgeo) const
78{
79 double x1, x2, x3, x4, x5, x6, x7, x8, a1, a2, a3, a4, a5, a6, a7, a8;
80 double y1, y2, y3, y4, y5, y6, y7, y8, b1, b2, b3, b4, b5, b6, b7, b8;
81 double z1, z2, z3, z4, z5, z6, z7, z8, c1, c2, c3, c4, c5, c6, c7, c8;
82 double xp, yp, zp, u, v, w;
83 FloatMatrix p(3, 3);
84 FloatArray r(3), delta;
85 int nite = 0;
86
87 x1 = cellgeo.giveVertexCoordinates(1).at(1);
88 x2 = cellgeo.giveVertexCoordinates(2).at(1);
89 x3 = cellgeo.giveVertexCoordinates(3).at(1);
90 x4 = cellgeo.giveVertexCoordinates(4).at(1);
91 x5 = cellgeo.giveVertexCoordinates(5).at(1);
92 x6 = cellgeo.giveVertexCoordinates(6).at(1);
93 x7 = cellgeo.giveVertexCoordinates(7).at(1);
94 x8 = cellgeo.giveVertexCoordinates(8).at(1);
95
96 y1 = cellgeo.giveVertexCoordinates(1).at(2);
97 y2 = cellgeo.giveVertexCoordinates(2).at(2);
98 y3 = cellgeo.giveVertexCoordinates(3).at(2);
99 y4 = cellgeo.giveVertexCoordinates(4).at(2);
100 y5 = cellgeo.giveVertexCoordinates(5).at(2);
101 y6 = cellgeo.giveVertexCoordinates(6).at(2);
102 y7 = cellgeo.giveVertexCoordinates(7).at(2);
103 y8 = cellgeo.giveVertexCoordinates(8).at(2);
104
105 z1 = cellgeo.giveVertexCoordinates(1).at(3);
106 z2 = cellgeo.giveVertexCoordinates(2).at(3);
107 z3 = cellgeo.giveVertexCoordinates(3).at(3);
108 z4 = cellgeo.giveVertexCoordinates(4).at(3);
109 z5 = cellgeo.giveVertexCoordinates(5).at(3);
110 z6 = cellgeo.giveVertexCoordinates(6).at(3);
111 z7 = cellgeo.giveVertexCoordinates(7).at(3);
112 z8 = cellgeo.giveVertexCoordinates(8).at(3);
113
114 xp = coords.at(1);
115 yp = coords.at(2);
116 zp = coords.at(3);
117
118 a1 = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8;
119 a2 = -x1 - x2 + x3 + x4 - x5 - x6 + x7 + x8;
120 a3 = -x1 + x2 + x3 - x4 - x5 + x6 + x7 - x8;
121 a4 = x1 + x2 + x3 + x4 - x5 - x6 - x7 - x8;
122 a5 = x1 - x2 + x3 - x4 + x5 - x6 + x7 - x8;
123 a6 = -x1 - x2 + x3 + x4 + x5 + x6 - x7 - x8;
124 a7 = -x1 + x2 + x3 - x4 + x5 - x6 - x7 + x8;
125 a8 = x1 - x2 + x3 - x4 - x5 + x6 - x7 + x8;
126
127 b1 = y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8;
128 b2 = -y1 - y2 + y3 + y4 - y5 - y6 + y7 + y8;
129 b3 = -y1 + y2 + y3 - y4 - y5 + y6 + y7 - y8;
130 b4 = y1 + y2 + y3 + y4 - y5 - y6 - y7 - y8;
131 b5 = y1 - y2 + y3 - y4 + y5 - y6 + y7 - y8;
132 b6 = -y1 - y2 + y3 + y4 + y5 + y6 - y7 - y8;
133 b7 = -y1 + y2 + y3 - y4 + y5 - y6 - y7 + y8;
134 b8 = y1 - y2 + y3 - y4 - y5 + y6 - y7 + y8;
135
136 c1 = z1 + z2 + z3 + z4 + z5 + z6 + z7 + z8;
137 c2 = -z1 - z2 + z3 + z4 - z5 - z6 + z7 + z8;
138 c3 = -z1 + z2 + z3 - z4 - z5 + z6 + z7 - z8;
139 c4 = z1 + z2 + z3 + z4 - z5 - z6 - z7 - z8;
140 c5 = z1 - z2 + z3 - z4 + z5 - z6 + z7 - z8;
141 c6 = -z1 - z2 + z3 + z4 + z5 + z6 - z7 - z8;
142 c7 = -z1 + z2 + z3 - z4 + z5 - z6 - z7 + z8;
143 c8 = z1 - z2 + z3 - z4 - z5 + z6 - z7 + z8;
144
145 // setup initial guess
146 answer.resize(3);
147 answer.zero();
148
149 // apply Newton-Raphson to solve the problem
150 for ( ;; ) {
151 if ( ( ++nite ) > 10 ) {
152 answer.zero();
153 return false;
154 }
155
156 u = answer.at(1);
157 v = answer.at(2);
158 w = answer.at(3);
159
160 // compute the residual
161 r.at(1) = a1 + u * a2 + v * a3 + w * a4 + u * v * a5 + u * w * a6 + v * w * a7 + u * v * w * a8 - 8.0 * xp;
162 r.at(2) = b1 + u * b2 + v * b3 + w * b4 + u * v * b5 + u * w * b6 + v * w * b7 + u * v * w * b8 - 8.0 * yp;
163 r.at(3) = c1 + u * c2 + v * c3 + w * c4 + u * v * c5 + u * w * c6 + v * w * c7 + u * v * w * c8 - 8.0 * zp;
164
165 // check for convergence
166 if ( r.computeSquaredNorm() < 1.e-20 ) {
167 break; // sqrt(1.e-20) = 1.e-10
168 }
169
170 p.at(1, 1) = a2 + v * a5 + w * a6 + v * w * a8;
171 p.at(1, 2) = a3 + u * a5 + w * a7 + u * w * a8;
172 p.at(1, 3) = a4 + u * a6 + v * a7 + u * v * a8;
173
174 p.at(2, 1) = b2 + v * b5 + w * b6 + v * w * b8;
175 p.at(2, 2) = b3 + u * b5 + w * b7 + u * w * b8;
176 p.at(2, 3) = b4 + u * b6 + v * b7 + u * v * b8;
177
178 p.at(3, 1) = c2 + v * c5 + w * c6 + v * w * c8;
179 p.at(3, 2) = c3 + u * c5 + w * c7 + u * w * c8;
180 p.at(3, 3) = c4 + u * c6 + v * c7 + u * v * c8;
181
182 // solve for corrections
183 p.solveForRhs(r, delta);
184
185 // update guess
186 answer.subtract(delta);
187 }
188
189 // test if inside
190 bool inside = true;
191 for ( int i = 1; i <= 3; i++ ) {
192 if ( answer.at(i) < ( -1. - POINT_TOL ) ) {
193 answer.at(i) = -1.;
194 inside = false;
195 } else if ( answer.at(i) > ( 1. + POINT_TOL ) ) {
196 answer.at(i) = 1.;
197 inside = false;
198 }
199 }
200
201 return inside;
202}
203
204void
205FEI3dHexaConst :: edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
206{
207 answer = Vec1(1.);
208}
209
210void
211FEI3dHexaConst :: edgeEvaldNdx(FloatMatrix &answer, int iedge,
212 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
213{
214 answer.resize(2, 1);
215 answer.zero();
216}
217
218
219void
220FEI3dHexaConst :: edgeEvaldNdxi(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
221{
222 answer.resize(2);
223 answer(0) = -0.5;
224 answer(1) = 0.5;
225}
226
227
228void
229FEI3dHexaConst :: edgeLocal2global(FloatArray &answer, int iedge,
230 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
231{
232 OOFEM_ERROR("not implemented");
233}
234
235
236double
237FEI3dHexaConst :: edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
238{
239 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
240 return 0.5 * this->edgeComputeLength(edgeNodes, cellgeo);
241}
242
243
245FEI3dHexaConst :: computeLocalEdgeMapping(int iedge) const
246{
247 if ( iedge == 1 ) { // edge between nodes 1 2
248 return {1, 2};
249 } else if ( iedge == 2 ) { // edge between nodes 2 3
250 return {2, 3};
251 } else if ( iedge == 3 ) { // edge between nodes 3 4
252 return {3, 4};
253 } else if ( iedge == 4 ) { // edge between nodes 4 1
254 return {4, 1};
255 } else if ( iedge == 5 ) { // edge between nodes 1 5
256 return {1, 5};
257 } else if ( iedge == 6 ) { // edge between nodes 2 6
258 return {2, 6};
259 } else if ( iedge == 7 ) { // edge between nodes 3 7
260 return {3, 7};
261 } else if ( iedge == 8 ) { // edge between nodes 4 8
262 return {4, 8};
263 } else if ( iedge == 9 ) { // edge between nodes 5 6
264 return {5, 6};
265 } else if ( iedge == 10 ) { // edge between nodes 6 7
266 return {6, 7};
267 } else if ( iedge == 11 ) { // edge between nodes 7 8
268 return {7, 8};
269 } else if ( iedge == 12 ) { // edge between nodes 8 5
270 return {8, 5};
271 } else {
272 throw std::range_error("invalid edge number");
273 //return {};
274 }
275}
276
277double
278FEI3dHexaConst :: edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
279{
280 return distance(cellgeo.giveVertexCoordinates( edgeNodes.at(2) ), cellgeo.giveVertexCoordinates( edgeNodes.at(1) ));
281}
282
283void
284FEI3dHexaConst :: surfaceEvalN(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
285{
286 answer = {};
287}
288
289void
290FEI3dHexaConst :: surfaceEvaldNdx(FloatMatrix &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
291{
292 answer.resize(1, 3);
293 answer.zero();
294}
295
296void
297FEI3dHexaConst :: surfaceLocal2global(FloatArray &answer, int iedge,
298 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
299{
300 OOFEM_ERROR("not implemented");
301}
302
303double
304FEI3dHexaConst :: surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
305{
306 OOFEM_ERROR("not implemented");
307}
308
309double
310FEI3dHexaConst :: surfaceGiveTransformationJacobian(int isurf, const FloatArray &lcoords,
311 const FEICellGeometry &cellgeo) const
312{
313 OOFEM_ERROR("not implemented");
314}
315
317FEI3dHexaConst :: computeLocalSurfaceMapping(int isurf) const
318{
319 if ( isurf == 1 ) { // surface 1 - nodes 1 4 3 2
320 return {1, 4, 3, 2};
321 } else if ( isurf == 2 ) { // surface 2 - nodes 5 6 7 8
322 return {5, 6, 7, 8};
323 } else if ( isurf == 3 ) { // surface 3 - nodes 1 2 6 5
324 return {1, 2, 6, 5};
325 } else if ( isurf == 4 ) { // surface 4 - nodes 2 3 7 6
326 return {2, 3, 7, 6};
327 } else if ( isurf == 5 ) { // surface 5 - nodes 3 4 8 7
328 return {3, 4, 8, 7};
329 } else if ( isurf == 6 ) { // surface 6 - nodes 4 1 5 8
330 return {4, 1, 5, 8};
331 } else {
332 throw std::runtime_error("invalid surface number");
333 }
334}
335
336std::unique_ptr<IntegrationRule>
337FEI3dHexaConst :: giveIntegrationRule(int order, Element_Geometry_Type egt) const
338{
339 auto iRule = std::make_unique<GaussIntegrationRule>(1, nullptr);
340 int points = iRule->getRequiredNumberOfIntegrationPoints(_Cube, order + 0);
341 iRule->SetUpPointsOnCube(points, _Unknown);
342 return std::move(iRule);
343}
344
345std::unique_ptr<IntegrationRule>
346FEI3dHexaConst :: giveBoundaryIntegrationRule(int order, int boundary, Element_Geometry_Type egt) const
347{
348 auto iRule = std::make_unique<GaussIntegrationRule>(1, nullptr);
349 int points = iRule->getRequiredNumberOfIntegrationPoints(_Square, order + 0);
350 iRule->SetUpPointsOnSquare(points, _Unknown);
351 return std::move(iRule);
352}
353
354
355} // end namespace oofem
void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
IntArray computeLocalEdgeMapping(int iedge) const override
double edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
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 zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void add(const FloatArray &src)
Definition floatarray.C:218
void subtract(const FloatArray &src)
Definition floatarray.C:320
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
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)
static FloatArray Vec1(const double &a)
Definition floatarray.h:605

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