OOFEM 3.0
Loading...
Searching...
No Matches
feinterpol2d.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 "feinterpol2d.h"
36#include "floatarray.h"
37#include "floatarrayf.h"
39
40namespace oofem {
41IntArray FEInterpolation2d :: boundaryEdgeGiveNodes(int boundary, Element_Geometry_Type egt, bool includeHierarchical) const
42{
43 return this->computeLocalEdgeMapping(boundary);
44}
45
46void FEInterpolation2d :: boundaryEdgeEvalN(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
47{
48 this->edgeEvalN(answer, boundary, lcoords, cellgeo);
49}
50
51double FEInterpolation2d :: boundaryEdgeGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
52{
53 return this->edgeGiveTransformationJacobian(boundary, lcoords, cellgeo);
54}
55
56void FEInterpolation2d :: boundaryEdgeLocal2Global(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
57{
58 this->edgeLocal2global(answer, boundary, lcoords, cellgeo);
59}
60
61double FEInterpolation2d :: boundaryEdgeEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
62{
63 return this->edgeEvalNormal(answer, isurf, lcoords, cellgeo);
64
65}
66
67double FEInterpolation2d :: giveArea(const FEICellGeometry &cellgeo) const
68{
69 OOFEM_ERROR("Not implemented in subclass.");
70}
71
72#define POINT_TOL 1.e-3
73
74int FEInterpolation2d :: global2local(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo) const
75{
76 FloatArray res, delta, guess, lcoords_guess;
77 FloatMatrix jac;
78 double convergence_limit, error = 0.0;
79
80 // find a suitable convergence limit
81 convergence_limit = 1e-6 * this->giveCharacteristicLength(cellgeo);
82
83 // setup initial guess
84 lcoords_guess.resize( 2 );
85 lcoords_guess.zero();
86
87 // apply Newton-Raphson to solve the problem
88 for ( int nite = 0; nite < 10; nite++ ) {
89 // compute the residual
90 this->local2global(guess, lcoords_guess, cellgeo);
91 res = Vec2(gcoords(0) - guess(0), gcoords(1) - guess(1));
92
93 // check for convergence
94 error = res.computeNorm();
95 if ( error < convergence_limit ) {
96 break;
97 }
98
99 // compute the corrections
100 this->giveJacobianMatrixAt(jac, lcoords_guess, cellgeo);
101 jac.solveForRhs(res, delta);
102
103 // update guess
104 lcoords_guess.add(delta);
105 }
106 if ( error > convergence_limit ) { // Imperfect, could give false negatives.
107 OOFEM_WARNING("Failed convergence");
108 answer = Vec2(1. / 3., 1. / 3.);
109 return false;
110 }
111
112 answer = Vec2( lcoords_guess(0), lcoords_guess(1) );
113
114 return inside(answer);
115}
116
117void
118FEInterpolation2d :: giveJacobianMatrixAt(FloatMatrix &jacobianMatrix, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
119// Returns the jacobian matrix J (x,y)/(ksi,eta) of the receiver.
120{
121 FloatMatrix dn;
122
123 jacobianMatrix.resize(2, 2);
124 jacobianMatrix.zero();
125
126 this->evaldNdxi(dn, lcoords, cellgeo );
127
128 for ( int i = 1; i <= dn.giveNumberOfRows(); i++ ) {
129 double x = cellgeo.giveVertexCoordinates(i).at(xind);
130 double y = cellgeo.giveVertexCoordinates(i).at(yind);
131
132 jacobianMatrix.at(1, 1) += dn.at(i, 1) * x;
133 jacobianMatrix.at(2, 1) += dn.at(i, 1) * y;
134 jacobianMatrix.at(1, 2) += dn.at(i, 2) * x;
135 jacobianMatrix.at(2, 2) += dn.at(i, 2) * y;
136 }
137}
138
139bool FEInterpolation2d ::inside(const FloatArray &lcoords) const
140{
141 OOFEM_ERROR("Not implemented.")
142}
143
144IntArray FEInterpolation2d :: boundaryGiveNodes(int boundary, Element_Geometry_Type egt) const
145{
146 return this->computeLocalEdgeMapping(boundary);
147}
148
149void FEInterpolation2d :: boundaryEvalN(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
150{
151 this->edgeEvalN(answer, boundary, lcoords, cellgeo);
152}
153
154double FEInterpolation2d :: boundaryEvalNormal(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
155{
156 return this->edgeEvalNormal(answer, boundary, lcoords, cellgeo);
157}
158
159double FEInterpolation2d :: boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
160{
161 return this->edgeGiveTransformationJacobian(boundary, lcoords, cellgeo);
162}
163
164void FEInterpolation2d :: boundaryLocal2Global(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
165{
166 return this->edgeLocal2global(answer, boundary, lcoords, cellgeo);
167}
168
169IntArray FEInterpolation2d :: computeEdgeMapping(const IntArray &elemNodes, int iedge) const
170{
171 const auto& ln = this->computeLocalEdgeMapping(iedge);
172 int size = ln.giveSize();
173 IntArray edgeNodes(size);
174 for ( int i = 1; i <= size; i++ ) {
175 edgeNodes.at(i) = elemNodes.at( ln.at(i) );
176 }
177 return edgeNodes;
178}
179
180double FEInterpolation2d :: edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
181{
182 FloatArray normal;
183 return this->edgeEvalNormal(normal, iedge, lcoords, cellgeo);
184}
185
186void FEInterpolation2d::boundarySurfaceEvalN(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
187{
188 this->evalN(answer, lcoords, cellgeo);
189}
190
192 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
193{
194 this->evaldNdx(answer, lcoords, cellgeo);
195}
196
198 const FEICellGeometry &cellgeo) const
199{
200 answer = Vec3(0, 0, 1);
201 return this->giveTransformationJacobian(lcoords, cellgeo);
202}
203
204
206{
207 //Adapted from FEI3dQuadLin
208 // Note: These are not normalized. Returns the two tangent vectors to the surface.
209 FloatMatrix dNdxi;
210 this->surfaceEvaldNdxi(dNdxi, lcoords);
211
212 //Get nodes which correspond to the surface in question
213 auto nodeIndices = this->computeLocalEdgeMapping(isurf);
215 for (int i = 0; i < nodeIndices.giveSize(); ++i) {
216 G1 += dNdxi(i, 0) * FloatArrayF<2>(cellgeo.giveVertexCoordinates(nodeIndices(i)));
217 }
218 return G1;
219}
220
221void FEInterpolation2d::surfaceEvaldNdxi(FloatMatrix & answer, const FloatArray & lcoords) const
222{
223 OOFEM_ERROR("Not implemented");
224}
225
227{
228 OOFEM_ERROR("Not implemented");
229}
230
231
232
233
234
236 const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
237{
238 this->local2global(answer, lcoords, cellgeo);
239}
240
242 const FEICellGeometry &cellgeo) const
243{
244 return this->giveTransformationJacobian(lcoords, cellgeo);
245}
246
247IntArray FEInterpolation2d::boundarySurfaceGiveNodes(int boundary, Element_Geometry_Type egt, bool includeHierarchical) const
248{
249 int nnode = this->giveNumberOfNodes(egt);
250 IntArray answer(nnode);
251 answer.enumerate(nnode);
252 return answer;
253}
254
255
256} // end namespace oofem
virtual const FloatArray giveVertexCoordinates(int i) const =0
double boundarySurfaceGiveTransformationJacobian(int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
void giveJacobianMatrixAt(FloatMatrix &jacobianMatrix, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
void boundarySurfaceLocal2global(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
double boundarySurfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
virtual void edgeLocal2global(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
IntArray boundarySurfaceGiveNodes(int boundary, const Element_Geometry_Type, bool includeHierarchical=false) const override
virtual bool inside(const FloatArray &lcoords) const
virtual IntArray computeLocalEdgeMapping(int iedge) const =0
virtual void edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual void surfaceEvaldNdxi(FloatMatrix &answer, const FloatArray &lcoords) const override
virtual double edgeEvalNormal(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
virtual FloatArrayF< 2 > surfaceEvalBaseVectorsAt(int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
virtual void surfaceEvald2Ndxi2(FloatMatrix &answer, const FloatArray &lcoords) const override
virtual double giveCharacteristicLength(const FEICellGeometry &cellgeo) const
void boundarySurfaceEvaldNdx(FloatMatrix &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
void boundarySurfaceEvalN(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
virtual int giveNumberOfNodes(const Element_Geometry_Type) const
Definition feinterpol.h:557
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
Definition feinterpol.C:81
virtual void evaldNdxi(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
Definition feinterpol.h:243
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual void local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
double computeNorm() const
Definition floatarray.C:861
void resize(Index s)
Definition floatarray.C:94
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void add(const FloatArray &src)
Definition floatarray.C:218
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
void enumerate(int maxVal)
Definition intarray.C:85
int & at(std::size_t i)
Definition intarray.h:104
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
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