OOFEM 3.0
Loading...
Searching...
No Matches
fei3dquadlin.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 "fei3dquadlin.h"
36
37#include "mathfem.h"
38#include "floatmatrix.h"
39#include "floatarray.h"
41#include <stdexcept>
42
43namespace oofem {
44void
45FEI3dQuadLin :: evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
46{
47 this->surfaceEvalN(answer, 1, lcoords, cellgeo);
48}
49
50double
51FEI3dQuadLin :: evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
52{
53 OOFEM_ERROR("FEI3dQuadLin :: evaldNdx - Not supported");
54 //return 0.;
55}
56
57
58void
59FEI3dQuadLin :: evaldNdxi(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
60{
61 this->surfaceEvaldNdxi(answer, lcoords);
62}
63
64
65void
66FEI3dQuadLin :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
67{
68 FloatArray n;
69 this->evalN(n, lcoords, cellgeo);
70 answer.resize(0);
71 for ( int i = 1; i <= 4; ++i ) {
72 answer.add( n.at(i), cellgeo.giveVertexCoordinates(i) );
73 }
74}
75
76#define POINT_TOL 1.e-3
77int
78FEI3dQuadLin :: global2local(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo) const
79{
80 OOFEM_ERROR("FEI3dQuadLin :: global2local - Not supported");
81 //return -1;
82
83}
84
85double
86FEI3dQuadLin :: giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
87{
88 FloatArray normal;
89 return this->surfaceEvalNormal(normal, 1, lcoords, cellgeo);
90}
91
92void
93FEI3dQuadLin :: giveJacobianMatrixAt(FloatMatrix &jacobianMatrix, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
94{
95 OOFEM_ERROR("FEI3dQuadLin :: giveJacobianMatrixAt - Not supported");
96}
97
98
99void
100FEI3dQuadLin :: edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
101{
102 double xi = lcoords.at(1);
103 answer.resize(2);
104 answer.at(1) = ( 1. - xi ) * 0.5;
105 answer.at(2) = ( 1. + xi ) * 0.5;
106}
107
108
109
110void
111FEI3dQuadLin :: edgeEvaldNdx(FloatMatrix &answer, int iedge,
112 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
113{
114 OOFEM_ERROR("FEI3dQuadLin :: edgeEvaldNdx - Not supported");
115}
116
117void
118FEI3dQuadLin :: edgeEvaldNdxi(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
119{
120 answer.resize(2);
121 answer(0) = -0.5;
122 answer(1) = 0.5;
123}
124
125void
126FEI3dQuadLin :: edgeLocal2global(FloatArray &answer, int iedge,
127 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
128{
130 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
131 this->edgeEvalN(N, iedge, lcoords, cellgeo);
132
133 answer.resize(0);
134 for ( int i = 0; i < N.giveSize(); ++i ) {
135 answer.add( N[i], cellgeo.giveVertexCoordinates( edgeNodes[i] ) );
136 }
137}
138
139
140double
141FEI3dQuadLin :: edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
142{
143 // const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
145 OOFEM_ERROR("FEI3dQuadLin :: edgeGiveTransformationJacobian - Not supported");
146 return -1;
147}
148
149
151FEI3dQuadLin :: computeLocalEdgeMapping(int iedge) const
152{
153 if ( iedge == 1 ) { // edge between nodes 1 2
154 return { 1, 2 };
155 } else if ( iedge == 2 ) { // edge between nodes 2 3
156 return { 2, 3 };
157 } else if ( iedge == 3 ) { // edge between nodes 3 4
158 return { 3, 4 };
159 } else if ( iedge == 4 ) { // edge between nodes 4 1
160 return { 4, 1 };
161 } else {
162 throw std::range_error("invalid edge number");
163 // return {};
164 }
165}
166
167double
168FEI3dQuadLin :: edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
169{
171 OOFEM_ERROR("FEI3dQuadLin :: edgeComputeLength - Not supported");
172 //return -1;
173}
174
175void
176FEI3dQuadLin :: surfaceEvalN(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
177{
178 double ksi = lcoords[0];
179 double eta = lcoords[1];
180
181 answer.resize(4);
182 answer.at(1) = ( 1. + ksi ) * ( 1. + eta ) * 0.25;
183 answer.at(2) = ( 1. - ksi ) * ( 1. + eta ) * 0.25;
184 answer.at(3) = ( 1. - ksi ) * ( 1. - eta ) * 0.25;
185 answer.at(4) = ( 1. + ksi ) * ( 1. - eta ) * 0.25;
186}
187
188void
189FEI3dQuadLin :: surfaceEvaldNdxi(FloatMatrix &answer, const FloatArray &lcoords) const
190{
191 const double ksi = lcoords[0];
192 const double eta = lcoords[1];
193
194 answer.resize(4,2);
195 // dn/dxi
196 answer.at(1, 1) = 0.25 * ( 1. + eta );
197 answer.at(2, 1) = -0.25 * ( 1. + eta );
198 answer.at(3, 1) = -0.25 * ( 1. - eta );
199 answer.at(4, 1) = 0.25 * ( 1. - eta );
200
201 // dn/deta
202 answer.at(1, 2) = 0.25 * ( 1. + ksi );
203 answer.at(2, 2) = 0.25 * ( 1. - ksi );
204 answer.at(3, 2) = -0.25 * ( 1. - ksi );
205 answer.at(4, 2) = -0.25 * ( 1. + ksi );
206}
207
208
209
210void
211FEI3dQuadLin :: surfaceEvald2Ndxi2(FloatMatrix &answer, const FloatArray &lcoords) const
212{
213
214 answer.resize(4, 3);
215 // d2n/dxidxi
216 answer.at(1, 1) = 0.;
217 answer.at(2, 1) = 0.;
218 answer.at(3, 1) = 0.;
219 answer.at(4, 1) = 0.;
220
221 // d2n/detadeta
222 answer.at(1, 2) = 0.;
223 answer.at(2, 2) = 0.;
224 answer.at(3, 2) = 0.;
225 answer.at(4, 2) = 0.;
226
227 // d2n/dxideta
228 answer.at(1, 3) = 0.25;
229 answer.at(2, 3) = -0.25;
230 answer.at(3, 3) = 0.25;
231 answer.at(4, 3) = -0.25;
232
233
234}
235
236
237
238void
239FEI3dQuadLin :: surfaceLocal2global(FloatArray &answer, int isurf,
240 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
241{
242 //Note: This gives the coordinate in the reference system
244 this->surfaceEvalN(N, isurf, lcoords, cellgeo);
245
246 answer.resize(0);
247 for ( int i = 1; i <= N.giveSize(); ++i ) {
248 answer.add( N.at(i), cellgeo.giveVertexCoordinates(i) );
249 }
250}
251
252void
253FEI3dQuadLin :: surfaceEvaldNdx(FloatMatrix &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
254{
256 OOFEM_ERROR("FEI3dQuadLin :: surfaceEvaldNdx - Not supported");
257}
258
259void
260FEI3dQuadLin :: surfaceEvalBaseVectorsAt(FloatArray &G1, FloatArray &G2, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
261{
262 // Note: These are not normalized. Returns the two tangent vectors to the surface.
263 FloatMatrix dNdxi;
264 this->surfaceEvaldNdxi(dNdxi, lcoords);
265
266 G1.resize(0);
267 G2.resize(0);
268 for ( int i = 0; i < 4; ++i ) {
269 G1.add( dNdxi(i, 0), cellgeo.giveVertexCoordinates(i+1) );
270 G2.add( dNdxi(i, 1), cellgeo.giveVertexCoordinates(i+1) );
271 }
272}
273
274double
275FEI3dQuadLin :: surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
276{
277 FloatArray G1, G2; // local curvilinear base vectors
278 this->surfaceEvalBaseVectorsAt(G1, G2, lcoords, cellgeo);
279 answer.beVectorProductOf(G1, G2);
280 double J = answer.computeNorm();
281 answer.times(1 / J);
282 return J;
283}
284
285void
286FEI3dQuadLin :: surfaceGiveJacobianMatrixAt(FloatMatrix &jacobianMatrix, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
287{
288 // Jacobian matrix consists of the three curvilinear base vectors. The third is taken as the normal to the surface.
289 // Note! The base vectors are not normalized except the third (normal)
290 FloatArray G1, G2, G3;
291 this->surfaceEvalBaseVectorsAt(G1, G2, lcoords, cellgeo);
292 G3.beVectorProductOf(G1, G2);
293
294 jacobianMatrix.resize(3, 3);
295 jacobianMatrix.at(1, 1) = G1.at(1);
296 jacobianMatrix.at(1, 2) = G2.at(1);
297 jacobianMatrix.at(1, 3) = G3.at(1);
298 jacobianMatrix.at(2, 1) = G1.at(2);
299 jacobianMatrix.at(2, 2) = G2.at(2);
300 jacobianMatrix.at(2, 3) = G3.at(2);
301 jacobianMatrix.at(3, 1) = G1.at(3);
302 jacobianMatrix.at(3, 2) = G2.at(3);
303 jacobianMatrix.at(3, 3) = G3.at(3);
304}
305
306double
307FEI3dQuadLin :: surfaceGiveTransformationJacobian(int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
308{
309 OOFEM_ERROR("FEI3dQuadLin :: surfaceGiveTransformationJacobian - Not supported yet");
310 //return 0;
311}
312
314FEI3dQuadLin :: computeLocalSurfaceMapping(int isurf) const
315{
316 //surfNodes.setValues(3, 1, 2, 3);
317 //return computeLocalEdgeMapping(isurf);
318 return {1,2,3,4};
319
320}
321
322std::unique_ptr<IntegrationRule>
323FEI3dQuadLin :: giveIntegrationRule(int order, Element_Geometry_Type egt) const
324{
325 auto iRule = std::make_unique<GaussIntegrationRule>(1, nullptr);
326 int points = iRule->getRequiredNumberOfIntegrationPoints(_Square, order);
327 iRule->SetUpPointsOnSquare(points, _Unknown);
328 return std::move(iRule);
329}
330
331std::unique_ptr<IntegrationRule>
332FEI3dQuadLin :: giveBoundaryIntegrationRule(int order, int boundary, Element_Geometry_Type egt) const
333{
335 OOFEM_ERROR("FEI3dQuadLin :: giveBoundaryIntegrationRule - Not supported");
336 //return nullptr;
337}
338
339
340double
341FEI3dQuadLin :: giveArea(const FEICellGeometry &cellgeo) const
342{
344 OOFEM_ERROR("FEI3dQuadLin :: giveArea - Not supported");
345 //return 0.;
346
347}
348} // end namespace oofem
#define N(a, b)
void surfaceEvalBaseVectorsAt(FloatArray &G1, FloatArray &G2, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
void edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
void surfaceEvalN(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
void surfaceEvaldNdxi(FloatMatrix &answer, const FloatArray &lcoords) const override
double surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
IntArray computeLocalEdgeMapping(int iedge) const override
void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
virtual const FloatArray giveVertexCoordinates(int i) const =0
double computeNorm() const
Definition floatarray.C:861
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
Definition floatarray.C:476
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
double at(std::size_t i, std::size_t j) const
#define OOFEM_ERROR(...)
Definition error.h:79

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