OOFEM 3.0
Loading...
Searching...
No Matches
fei2dtrconst.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 "fei2dtrconst.h"
36#include "mathfem.h"
38#include "floatmatrix.h"
39#include "floatarray.h"
40
41namespace oofem {
42void
43FEI2dTrConst :: evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
44{
45 answer = Vec1(1.);
46}
47
48double
49FEI2dTrConst :: evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
50{
51 answer.resize(1, 2);
52 answer.zero();
53
54 return 0.0;
55}
56
57void
58FEI2dTrConst :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
59{
60 double l1 = lcoords.at(1);
61 double l2 = lcoords.at(2);
62 double l3 = 1.0 - l1 - l2;
63
64 answer.resize(2);
65 answer.at(1) = ( l1 * cellgeo.giveVertexCoordinates(1).at(xind) +
66 l2 * cellgeo.giveVertexCoordinates(2).at(xind) +
67 l3 * cellgeo.giveVertexCoordinates(3).at(xind) );
68 answer.at(2) = ( l1 * cellgeo.giveVertexCoordinates(1).at(yind) +
69 l2 * cellgeo.giveVertexCoordinates(2).at(yind) +
70 l3 * cellgeo.giveVertexCoordinates(3).at(yind) );
71}
72
73#define POINT_TOL 1.e-3
74
75int
76FEI2dTrConst :: global2local(FloatArray &answer, const FloatArray &coords, const FEICellGeometry &cellgeo) const
77{
78 double x1 = cellgeo.giveVertexCoordinates(1).at(xind);
79 double x2 = cellgeo.giveVertexCoordinates(2).at(xind);
80 double x3 = cellgeo.giveVertexCoordinates(3).at(xind);
81
82 double y1 = cellgeo.giveVertexCoordinates(1).at(yind);
83 double y2 = cellgeo.giveVertexCoordinates(2).at(yind);
84 double y3 = cellgeo.giveVertexCoordinates(3).at(yind);
85
86 double detJ = ( x2 * y3 + x1 * y2 + y1 * x3 - x2 * y1 - x3 * y2 - x1 * y3 );
87
88 answer.resize(3);
89 answer.at(1) = ( ( x2 * y3 - x3 * y2 ) + ( y2 - y3 ) * coords.at(xind) + ( x3 - x2 ) * coords.at(yind) ) / detJ;
90 answer.at(2) = ( ( x3 * y1 - x1 * y3 ) + ( y3 - y1 ) * coords.at(xind) + ( x1 - x3 ) * coords.at(yind) ) / detJ;
91 //answer.at(3) = ( ( x1 * y2 - x2 * y1 ) + ( y1 - y2 ) * coords.at(xind) + ( x2 - x1 ) * coords.at(yind) ) / detJ;
92
93 // check if point is inside
94 bool inside = true;
95 for ( int i = 1; i <= 2; i++ ) {
96 if ( answer.at(i) < ( 0. - POINT_TOL ) ) {
97 answer.at(i) = 0.;
98 inside = false;
99 } else if ( answer.at(i) > ( 1. + POINT_TOL ) ) {
100 answer.at(i) = 1.;
101 inside = false;
102 }
103 }
104 answer.at(3) = 1. - answer.at(1) - answer.at(2);
105
106 return inside;
107}
108
109
110double
111FEI2dTrConst :: giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
112{
113 double x1 = cellgeo.giveVertexCoordinates(1).at(xind);
114 double x2 = cellgeo.giveVertexCoordinates(2).at(xind);
115 double x3 = cellgeo.giveVertexCoordinates(3).at(xind);
116
117 double y1 = cellgeo.giveVertexCoordinates(1).at(yind);
118 double y2 = cellgeo.giveVertexCoordinates(2).at(yind);
119 double y3 = cellgeo.giveVertexCoordinates(3).at(yind);
120
121 return x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 );
122}
123
124
125void
126FEI2dTrConst :: edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
127{
128 answer.resize(1);
129 answer.at(1) = 1.;
130}
131
132double
133FEI2dTrConst :: edgeEvalNormal(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
134{
135 OOFEM_ERROR("Not applicable to constant interpolation");
136 return 0.;
137}
138
139void
140FEI2dTrConst :: edgeEvaldNds(FloatArray &answer, int iedge,
141 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
142{
143 answer = Vec2( 0., 0. );
144}
145
146void
147FEI2dTrConst :: edgeLocal2global(FloatArray &answer, int iedge,
148 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
149{
150 FloatArray n = Vec2( ( 1 - lcoords(0) ) * 0.5, ( 1 + lcoords(0) ) * 0.5 );
151 const auto &edgeNodes = this->computeLocalEdgeMapping(iedge);
152
153 answer.resize(2);
154 answer.at(1) = ( n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(xind) +
155 n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(xind) );
156 answer.at(2) = ( n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) ).at(yind) +
157 n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) ).at(yind) );
158}
159
161FEI2dTrConst :: computeLocalEdgeMapping(int iedge) const
162{
163 if ( iedge == 1 ) { // edge between nodes 1 2
164 return {1, 2};
165 } else if ( iedge == 2 ) { // edge between nodes 2 3
166 return {2, 3};
167 } else if ( iedge == 3 ) { // edge between nodes 2 3
168 return {3, 1};
169 } else {
170 throw std::range_error("invalid edge number");
171 return {};
172 }
173}
174
175double
176FEI2dTrConst :: edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
177{
178 auto nodeA = edgeNodes.at(1);
179 auto nodeB = edgeNodes.at(2);
180
181 double dx = cellgeo.giveVertexCoordinates(nodeB).at(xind) - cellgeo.giveVertexCoordinates(nodeA).at(xind);
182 double dy = cellgeo.giveVertexCoordinates(nodeB).at(yind) - cellgeo.giveVertexCoordinates(nodeA).at(yind);
183 return sqrt(dx * dx + dy * dy);
184}
185
186std::unique_ptr<IntegrationRule>
187FEI2dTrConst :: giveIntegrationRule(int order, Element_Geometry_Type egt) const
188{
189 auto iRule = std::make_unique<GaussIntegrationRule>(1, nullptr);
190 int points = iRule->getRequiredNumberOfIntegrationPoints(_Triangle, order + 0);
191 iRule->SetUpPointsOnTriangle(points, _Unknown);
192 return std::move(iRule);
193}
194} // end namespace oofem
IntArray computeLocalEdgeMapping(int iedge) const override
virtual const FloatArray giveVertexCoordinates(int i) const =0
virtual bool inside(const FloatArray &lcoords) const
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void zero()
Zeroes all coefficient of receiver.
int & at(std::size_t i)
Definition intarray.h:104
#define OOFEM_ERROR(...)
Definition error.h:79
#define POINT_TOL
static FloatArray Vec2(const double &a, const double &b)
Definition floatarray.h:606
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