OOFEM 3.0
Loading...
Searching...
No Matches
fei2dtrlin.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 "fei2dtrlin.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
46FEI2dTrLin :: evalN(const FloatArrayF<2> &lcoords)
47{
48 return {lcoords[0], lcoords[1], 1. - lcoords[0] - lcoords[1]};
49}
50
51void
52FEI2dTrLin :: evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
53{
54 answer = Vec3(
55 lcoords.at(1),
56 lcoords.at(2),
57 1. - lcoords.at(1) - lcoords.at(2)
58 );
59}
60
61std::pair<double, FloatMatrixF<2,3>>
62FEI2dTrLin :: evaldNdx(const FEICellGeometry &cellgeo) const
63{
64 double x1 = cellgeo.giveVertexCoordinates(1).at(xind);
65 double x2 = cellgeo.giveVertexCoordinates(2).at(xind);
66 double x3 = cellgeo.giveVertexCoordinates(3).at(xind);
67 double y1 = cellgeo.giveVertexCoordinates(1).at(yind);
68 double y2 = cellgeo.giveVertexCoordinates(2).at(yind);
69 double y3 = cellgeo.giveVertexCoordinates(3).at(yind);
70 double detJ = x1 * ( y2 - y3 ) + x2 * ( y3 - y1 ) + x3 * ( y1 - y2 );
71
72 FloatMatrixF<2,3> ans = {
73 y2 - y3, x3 - x2,
74 y3 - y1, x1 - x3,
75 y1 - y2, x2 - x1,
76 };
77
78 return {detJ, ans * (1./detJ)};
79}
80
81
82double
83FEI2dTrLin :: evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
84{
85 double x1, x2, x3, y1, y2, y3, detJ;
86
87 x1 = cellgeo.giveVertexCoordinates(1).at(xind);
88 x2 = cellgeo.giveVertexCoordinates(2).at(xind);
89 x3 = cellgeo.giveVertexCoordinates(3).at(xind);
90
91 y1 = cellgeo.giveVertexCoordinates(1).at(yind);
92 y2 = cellgeo.giveVertexCoordinates(2).at(yind);
93 y3 = cellgeo.giveVertexCoordinates(3).at(yind);
94
95 detJ = x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 );
96
97 answer.resize(3, 2);
98 answer.at(1, 1) = ( y2 - y3 ) / detJ;
99 answer.at(1, 2) = ( x3 - x2 ) / detJ;
100
101 answer.at(2, 1) = ( y3 - y1 ) / detJ;
102 answer.at(2, 2) = ( x1 - x3 ) / detJ;
103
104 answer.at(3, 1) = ( y1 - y2 ) / detJ;
105 answer.at(3, 2) = ( x2 - x1 ) / detJ;
106
107 return detJ;
108}
109
110void
111FEI2dTrLin :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
112{
113 double l1 = lcoords.at(1);
114 double l2 = lcoords.at(2);
115 double l3 = 1.0 - l1 - l2;
116
117 answer.resize(3);
118 answer.zero();
119 answer.at(1) = l1 * cellgeo.giveVertexCoordinates(1).at(xind) +
120 l2 * cellgeo.giveVertexCoordinates(2).at(xind) +
121 l3 * cellgeo.giveVertexCoordinates(3).at(xind);
122 answer.at(2) = l1 * cellgeo.giveVertexCoordinates(1).at(yind) +
123 l2 * cellgeo.giveVertexCoordinates(2).at(yind) +
124 l3 * cellgeo.giveVertexCoordinates(3).at(yind);
125}
126
127#define POINT_TOL 1.e-3
128
129int
130FEI2dTrLin :: global2local(FloatArray &answer, const FloatArray &coords, const FEICellGeometry &cellgeo) const
131{
132 double x1 = cellgeo.giveVertexCoordinates(1).at(xind);
133 double x2 = cellgeo.giveVertexCoordinates(2).at(xind);
134 double x3 = cellgeo.giveVertexCoordinates(3).at(xind);
135
136 double y1 = cellgeo.giveVertexCoordinates(1).at(yind);
137 double y2 = cellgeo.giveVertexCoordinates(2).at(yind);
138 double y3 = cellgeo.giveVertexCoordinates(3).at(yind);
139
140 double detJ = x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 );
141
142 answer.resize(3);
143 answer.at(1) = ( ( x2 * y3 - x3 * y2 ) + ( y2 - y3 ) * coords.at(xind) + ( x3 - x2 ) * coords.at(yind) ) / detJ;
144 answer.at(2) = ( ( x3 * y1 - x1 * y3 ) + ( y3 - y1 ) * coords.at(xind) + ( x1 - x3 ) * coords.at(yind) ) / detJ;
145
146 // check if point is inside
147 bool inside = true;
148 for ( int i = 1; i <= 2; i++ ) {
149 if ( answer.at(i) < ( 0. - POINT_TOL ) ) {
150 answer.at(i) = 0.;
151 inside = false;
152 } else if ( answer.at(i) > ( 1. + POINT_TOL ) ) {
153 answer.at(i) = 1.;
154 inside = false;
155 }
156 }
157
158 if( ( answer.at(1) + answer.at(2)) > 1.0 ) {
159 const double temp = 0.5*( answer.at(1) + answer.at(2) - 1.);
160 answer.at(1) -= temp;
161 answer.at(2) -= temp;
162 inside = false;
163 }
164
165 answer.at(3) = 1. - answer.at(1) - answer.at(2);
166
167 return inside;
168}
169
170
171double
172FEI2dTrLin :: giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
173{
174 double x1 = cellgeo.giveVertexCoordinates(1).at(xind);
175 double x2 = cellgeo.giveVertexCoordinates(2).at(xind);
176 double x3 = cellgeo.giveVertexCoordinates(3).at(xind);
177
178 double y1 = cellgeo.giveVertexCoordinates(1).at(yind);
179 double y2 = cellgeo.giveVertexCoordinates(2).at(yind);
180 double y3 = cellgeo.giveVertexCoordinates(3).at(yind);
181
182 return ( x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 ) );
183}
184
185bool FEI2dTrLin :: inside(const FloatArray &lcoords) const
186{
187 const double point_tol = 1.0e-3;
188 bool inside = true;
189 for ( int i = 1; i <= 2; i++ ) {
190 if ( lcoords.at(i) < - point_tol ) {
191 inside = false;
192 } else if ( lcoords.at(i) > ( 1. + point_tol ) ) {
193 inside = false;
194 }
195 }
196
197 if ( 1. - lcoords.at(1) - lcoords.at(2) < - point_tol ) {
198 inside = false;
199 } else if ( 1. - lcoords.at(1) - lcoords.at(2) > ( 1. + point_tol ) ) {
200 inside = false;
201 }
202
203 return inside;
204}
205
206void
207FEI2dTrLin :: edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
208{
209 double ksi = lcoords.at(1);
210 answer = Vec2( ( 1. - ksi ) * 0.5, ( 1. + ksi ) * 0.5 );
211}
212
213void
214FEI2dTrLin :: edgeEvaldNds(FloatArray &answer, int iedge,
215 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
216{
217 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
218 double l = this->edgeComputeLength(edgeNodes, cellgeo);
219
220 answer = Vec2( -1.0 / l, 1.0 / l );
221}
222
223double FEI2dTrLin :: edgeEvalNormal(FloatArray &normal, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
224{
225 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
226 normal = Vec2(
227 cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(yind) - cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(yind),
228 cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(xind) - cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(xind)
229 );
230 return normal.normalize_giveNorm() * 0.5;
231}
232
233void
234FEI2dTrLin :: edgeLocal2global(FloatArray &answer, int iedge,
235 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
236{
237 FloatArray n;
238 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
239 this->edgeEvalN(n, iedge, lcoords, cellgeo);
240
241 answer.resize(2);
242 answer.at(1) = ( n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(xind) +
243 n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(xind) );
244 answer.at(2) = ( n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(yind) +
245 n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(yind) );
246}
247
248
250FEI2dTrLin :: computeLocalEdgeMapping(int iedge) const
251{
252 if ( iedge == 1 ) { // edge between nodes 1 2
253 return {1, 2};
254 } else if ( iedge == 2 ) { // edge between nodes 2 3
255 return {2, 3};
256 } else if ( iedge == 3 ) { // edge between nodes 2 3
257 return {3, 1};
258 } else {
259 throw std::range_error("invalid edge number");
260 //return {};
261 }
262}
263
264double
265FEI2dTrLin :: edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
266{
267 int nodeA = edgeNodes.at(1);
268 int nodeB = edgeNodes.at(2);
269
270 double dx = cellgeo.giveVertexCoordinates(nodeB).at(xind) - cellgeo.giveVertexCoordinates(nodeA).at(xind);
271 double dy = cellgeo.giveVertexCoordinates(nodeB).at(yind) - cellgeo.giveVertexCoordinates(nodeA).at(yind);
272 return sqrt(dx * dx + dy * dy);
273}
274
275double
276FEI2dTrLin :: giveArea(const FEICellGeometry &cellgeo) const
277{
278 const auto &p1 = cellgeo.giveVertexCoordinates(1);
279 double x1 = p1.at(xind);
280 double y1 = p1.at(yind);
281 const auto &p2 = cellgeo.giveVertexCoordinates(2);
282 double x2 = p2.at(xind);
283 double y2 = p2.at(yind);
284 const auto &p3 = cellgeo.giveVertexCoordinates(3);
285 double x3 = p3.at(xind);
286 double y3 = p3.at(yind);
287
288 return fabs( 0.5 * ( x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 ) ) );
289}
290
291double
292FEI2dTrLin :: evalNXIntegral(int iEdge, const FEICellGeometry &cellgeo) const
293{
294 const auto &eNodes = this->computeLocalEdgeMapping(iEdge);
295
296 const auto &node1 = cellgeo.giveVertexCoordinates( eNodes.at(1) );
297 double x1 = node1.at(xind);
298 double y1 = node1.at(yind);
299
300 const auto &node2 = cellgeo.giveVertexCoordinates( eNodes.at(2) );
301 double x2 = node2.at(xind);
302 double y2 = node2.at(yind);
303
304 return -( x2 * y1 - x1 * y2 );
305}
306
307std::unique_ptr<IntegrationRule>
308FEI2dTrLin :: giveIntegrationRule(int order, Element_Geometry_Type egt) const
309{
310 auto iRule = std::make_unique<GaussIntegrationRule>(1, nullptr);
311 int points = iRule->getRequiredNumberOfIntegrationPoints(_Triangle, order + 0);
312 iRule->SetUpPointsOnTriangle(points, _Unknown);
313 return std::move(iRule);
314}
315
316// FEI2dTrLinAxi element
317
318double
319FEI2dTrLinAxi :: giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
320{
322 this->evalN( N, lcoords, cellgeo);
323
324 double r = 0.0;
325 for ( int i = 1; i <= 3; i++ ) {
326 double x = cellgeo.giveVertexCoordinates(i).at(1);
327 r += x * N.at(i);
328 }
329
330 return r * FEI2dTrLin::giveTransformationJacobian(lcoords, cellgeo);
331}
332
333double
335 const FEICellGeometry &cellgeo) const
336{
337 FloatArray n;
338 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
339 this->edgeEvalN(n, iedge, lcoords, cellgeo);
340
341 double r = n.at(1)*cellgeo.giveVertexCoordinates(edgeNodes.at(1)).at(1) + n.at(2)*cellgeo.giveVertexCoordinates(edgeNodes.at(2)).at(1);
342 return r * FEI2dTrLin::edgeGiveTransformationJacobian(iedge, lcoords, cellgeo);
343
344}
345
346double
348{
349 return this->edgeGiveTransformationJacobian(boundary, lcoords, cellgeo);
350}
351
352double
353FEI2dTrLinAxi::boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
354{
355 return this->edgeGiveTransformationJacobian(boundary, lcoords, cellgeo);
356}
357
358} // end namespace oofem
#define N(a, b)
double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei2dtrlin.C:334
double boundaryEdgeGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei2dtrlin.C:347
double boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei2dtrlin.C:353
static FloatArrayF< 3 > evalN(const FloatArrayF< 2 > &lcoords)
Definition fei2dtrlin.C:46
IntArray computeLocalEdgeMapping(int iedge) const override
Definition fei2dtrlin.C:250
double edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
Definition fei2dtrlin.C:265
bool inside(const FloatArray &lcoords) const override
Definition fei2dtrlin.C:185
void edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei2dtrlin.C:207
double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei2dtrlin.C:172
virtual const FloatArray giveVertexCoordinates(int i) const =0
virtual double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
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
double normalize_giveNorm()
Definition floatarray.C:850
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 POINT_TOL
static FloatArray Vec2(const double &a, const double &b)
Definition floatarray.h:606
static FloatArray Vec3(const double &a, const double &b, const double &c)
Definition floatarray.h:607

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