OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
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 - 2013 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 "gaussintegrationrule.h"
40 
41 namespace oofem {
42 void
43 FEI2dTrLin :: evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
44 {
45  answer = {
46  lcoords.at(1),
47  lcoords.at(2),
48  1. - lcoords.at(1) - lcoords.at(2)
49  };
50 }
51 
52 double
53 FEI2dTrLin :: evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
54 {
55  double x1, x2, x3, y1, y2, y3, detJ;
56 
57  x1 = cellgeo.giveVertexCoordinates(1)->at(xind);
58  x2 = cellgeo.giveVertexCoordinates(2)->at(xind);
59  x3 = cellgeo.giveVertexCoordinates(3)->at(xind);
60 
61  y1 = cellgeo.giveVertexCoordinates(1)->at(yind);
62  y2 = cellgeo.giveVertexCoordinates(2)->at(yind);
63  y3 = cellgeo.giveVertexCoordinates(3)->at(yind);
64 
65  detJ = x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 );
66 
67  answer.resize(3, 2);
68  answer.at(1, 1) = ( y2 - y3 ) / detJ;
69  answer.at(1, 2) = ( x3 - x2 ) / detJ;
70 
71  answer.at(2, 1) = ( y3 - y1 ) / detJ;
72  answer.at(2, 2) = ( x1 - x3 ) / detJ;
73 
74  answer.at(3, 1) = ( y1 - y2 ) / detJ;
75  answer.at(3, 2) = ( x2 - x1 ) / detJ;
76 
77  return detJ;
78 }
79 
80 void
81 FEI2dTrLin :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
82 {
83  double l1, l2, l3;
84 
85  l1 = lcoords.at(1);
86  l2 = lcoords.at(2);
87  l3 = 1.0 - l1 - l2;
88 
89  //answer.resize(2);
90  answer.resize(3);
91  answer.zero();
92  answer.at(1) = ( l1 * cellgeo.giveVertexCoordinates(1)->at(xind) +
93  l2 * cellgeo.giveVertexCoordinates(2)->at(xind) +
94  l3 * cellgeo.giveVertexCoordinates(3)->at(xind) );
95  answer.at(2) = ( l1 * cellgeo.giveVertexCoordinates(1)->at(yind) +
96  l2 * cellgeo.giveVertexCoordinates(2)->at(yind) +
97  l3 * cellgeo.giveVertexCoordinates(3)->at(yind) );
98 }
99 
100 #define POINT_TOL 1.e-3
101 
102 int
103 FEI2dTrLin :: global2local(FloatArray &answer, const FloatArray &coords, const FEICellGeometry &cellgeo)
104 {
105  double detJ, x1, x2, x3, y1, y2, y3;
106 
107  x1 = cellgeo.giveVertexCoordinates(1)->at(xind);
108  x2 = cellgeo.giveVertexCoordinates(2)->at(xind);
109  x3 = cellgeo.giveVertexCoordinates(3)->at(xind);
110 
111  y1 = cellgeo.giveVertexCoordinates(1)->at(yind);
112  y2 = cellgeo.giveVertexCoordinates(2)->at(yind);
113  y3 = cellgeo.giveVertexCoordinates(3)->at(yind);
114 
115  detJ = x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 );
116 
117  answer.resize(3);
118  answer.at(1) = ( ( x2 * y3 - x3 * y2 ) + ( y2 - y3 ) * coords.at(xind) + ( x3 - x2 ) * coords.at(yind) ) / detJ;
119  answer.at(2) = ( ( x3 * y1 - x1 * y3 ) + ( y3 - y1 ) * coords.at(xind) + ( x1 - x3 ) * coords.at(yind) ) / detJ;
120 
121  // check if point is inside
122  bool inside = true;
123  for ( int i = 1; i <= 2; i++ ) {
124  if ( answer.at(i) < ( 0. - POINT_TOL ) ) {
125  answer.at(i) = 0.;
126  inside = false;
127  } else if ( answer.at(i) > ( 1. + POINT_TOL ) ) {
128  answer.at(i) = 1.;
129  inside = false;
130  }
131  }
132 
133  if( ( answer.at(1) + answer.at(2)) > 1.0 ) {
134  const double temp = 0.5*( answer.at(1) + answer.at(2) - 1.);
135  answer.at(1) -= temp;
136  answer.at(2) -= temp;
137  inside = false;
138  }
139 
140  answer.at(3) = 1. - answer.at(1) - answer.at(2);
141 
142  return inside;
143 }
144 
145 
146 double
148 {
149  double x1, x2, x3, y1, y2, y3;
150 
151  x1 = cellgeo.giveVertexCoordinates(1)->at(xind);
152  x2 = cellgeo.giveVertexCoordinates(2)->at(xind);
153  x3 = cellgeo.giveVertexCoordinates(3)->at(xind);
154 
155  y1 = cellgeo.giveVertexCoordinates(1)->at(yind);
156  y2 = cellgeo.giveVertexCoordinates(2)->at(yind);
157  y3 = cellgeo.giveVertexCoordinates(3)->at(yind);
158 
159  return ( x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 ) );
160 }
161 
162 bool FEI2dTrLin :: inside(const FloatArray &lcoords) const
163 {
164  const double point_tol = 1.0e-3;
165  bool inside = true;
166  for ( int i = 1; i <= 2; i++ ) {
167  if ( lcoords.at(i) < - point_tol ) {
168  inside = false;
169  } else if ( lcoords.at(i) > ( 1. + point_tol ) ) {
170  inside = false;
171  }
172  }
173 
174  if ( 1. - lcoords.at(1) - lcoords.at(2) < - point_tol ) {
175  inside = false;
176  } else if ( 1. - lcoords.at(1) - lcoords.at(2) > ( 1. + point_tol ) ) {
177  inside = false;
178  }
179 
180  return inside;
181 }
182 
183 void
184 FEI2dTrLin :: edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
185 {
186  double ksi = lcoords.at(1);
187  answer = { ( 1. - ksi ) * 0.5, ( 1. + ksi ) * 0.5 };
188 }
189 
190 void
192  const FloatArray &lcoords, const FEICellGeometry &cellgeo)
193 {
194  IntArray edgeNodes;
195  this->computeLocalEdgeMapping(edgeNodes, iedge);
196  double l = this->edgeComputeLength(edgeNodes, cellgeo);
197 
198  answer = { -1.0 / l, 1.0 / l };
199 }
200 
201 double FEI2dTrLin :: edgeEvalNormal(FloatArray &normal, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
202 {
203  IntArray edgeNodes;
204  this->computeLocalEdgeMapping(edgeNodes, iedge);
205  normal = {
206  cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(yind) - cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(yind),
207  cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(xind) - cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(xind)
208  };
209  return normal.normalize() * 0.5;
210 }
211 
212 void
214  const FloatArray &lcoords, const FEICellGeometry &cellgeo)
215 {
216  IntArray edgeNodes;
217  FloatArray n;
218  this->computeLocalEdgeMapping(edgeNodes, iedge);
219  this->edgeEvalN(n, iedge, lcoords, cellgeo);
220 
221  answer.resize(2);
222  answer.at(1) = ( n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(xind) +
223  n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(xind) );
224  answer.at(2) = ( n.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(yind) +
225  n.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(yind) );
226 }
227 
228 
229 void
231 {
232  int aNode = 0, bNode = 0;
233  edgeNodes.resize(2);
234 
235  if ( iedge == 1 ) { // edge between nodes 1 2
236  aNode = 1;
237  bNode = 2;
238  } else if ( iedge == 2 ) { // edge between nodes 2 3
239  aNode = 2;
240  bNode = 3;
241  } else if ( iedge == 3 ) { // edge between nodes 2 3
242  aNode = 3;
243  bNode = 1;
244  } else {
245  OOFEM_ERROR("wrong egde number (%d)", iedge);
246  }
247 
248  edgeNodes.at(1) = aNode;
249  edgeNodes.at(2) = bNode;
250 }
251 
252 double
254 {
255  double dx, dy;
256  int nodeA, nodeB;
257 
258  nodeA = edgeNodes.at(1);
259  nodeB = edgeNodes.at(2);
260 
261  dx = cellgeo.giveVertexCoordinates(nodeB)->at(xind) - cellgeo.giveVertexCoordinates(nodeA)->at(xind);
262  dy = cellgeo.giveVertexCoordinates(nodeB)->at(yind) - cellgeo.giveVertexCoordinates(nodeA)->at(yind);
263  return sqrt(dx * dx + dy * dy);
264 }
265 
266 double
268 {
269  const FloatArray *p;
270  double x1, x2, x3, y1, y2, y3;
271 
272  p = cellgeo.giveVertexCoordinates(1);
273  x1 = p->at(1);
274  y1 = p->at(2);
275  p = cellgeo.giveVertexCoordinates(2);
276  x2 = p->at(1);
277  y2 = p->at(2);
278  p = cellgeo.giveVertexCoordinates(3);
279  x3 = p->at(1);
280  y3 = p->at(2);
281 
282  return fabs( 0.5 * ( x1 * ( y2 - y3 ) + x2 * ( -y1 + y3 ) + x3 * ( y1 - y2 ) ) );
283 }
284 
285 double
287 {
288  IntArray eNodes;
289  const FloatArray *node;
290  double x1, x2, y1, y2;
291 
292  this->computeLocalEdgeMapping(eNodes, iEdge);
293 
294  node = cellgeo.giveVertexCoordinates( eNodes.at(1) );
295  x1 = node->at(xind);
296  y1 = node->at(yind);
297 
298  node = cellgeo.giveVertexCoordinates( eNodes.at(2) );
299  x2 = node->at(xind);
300  y2 = node->at(yind);
301 
302  return -( x2 * y1 - x1 * y2 );
303 }
304 
307 {
308  IntegrationRule *iRule = new GaussIntegrationRule(1, NULL);
309  int points = iRule->getRequiredNumberOfIntegrationPoints(_Triangle, order + 0);
310  iRule->SetUpPointsOnTriangle(points, _Unknown);
311  return iRule;
312 }
313 
314 
315 
316 
317 
318 // FEI2dTrLinAxi element
319 
320 
321 double
323 {
324  FloatArray N;
325  this->evalN( N, lcoords, cellgeo);
326 
327  double r = 0.0;
328  for ( int i = 1; i <= 3; i++ ) {
329  double x = cellgeo.giveVertexCoordinates(i)->at(1);
330  r += x * N.at(i);
331  }
332 
333  return r * FEI2dTrLin::giveTransformationJacobian(lcoords, cellgeo);
334 }
335 
336 double
338  const FEICellGeometry &cellgeo)
339 {
340  IntArray edgeNodes;
341  FloatArray n;
342  this->computeLocalEdgeMapping(edgeNodes, iedge);
343  this->edgeEvalN(n, iedge, lcoords, cellgeo);
344 
345  double r = n.at(1)*cellgeo.giveVertexCoordinates(edgeNodes.at(1))->at(1) + n.at(2)*cellgeo.giveVertexCoordinates(edgeNodes.at(2))->at(1);
346  return r * FEI2dTrLin::edgeGiveTransformationJacobian(iedge, lcoords, cellgeo);
347 
348 }
349 
350 double
352 {
353  return this->edgeGiveTransformationJacobian(boundary, lcoords, cellgeo);
354 }
355 
356 double
358 {
359  return this->edgeGiveTransformationJacobian(boundary, lcoords, cellgeo);
360 }
361 
362 
363 
364 } // end namespace oofem
virtual void edgeLocal2global(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates edge global coordinates from given local ones.
Definition: fei2dtrlin.C:213
virtual void edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of edge interpolation functions (shape functions) at given point.
Definition: fei2dtrlin.C:184
virtual double boundaryEdgeGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation Jacobian on the requested boundary.
Definition: fei2dtrlin.C:351
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation.
Definition: fei2dtrlin.C:322
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
Definition: fei2dtrlin.C:53
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of interpolation functions (shape functions) at given point.
Definition: fei2dtrlin.C:43
virtual void computeLocalEdgeMapping(IntArray &edgeNodes, int iedge)
Definition: fei2dtrlin.C:230
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
virtual const FloatArray * giveVertexCoordinates(int i) const =0
Class representing a general abstraction for cell geometry.
Definition: feinterpol.h:62
virtual IntegrationRule * giveIntegrationRule(int order)
Sets up a suitable integration rule for numerical integrating over volume.
Definition: fei2dtrlin.C:306
virtual double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the edge Jacobian of transformation between local and global coordinates.
Definition: feinterpol2d.C:175
#define POINT_TOL
Definition: fei2dtrlin.C:100
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
Abstract base class representing integration rule.
virtual double giveArea(const FEICellGeometry &cellgeo) const
Computes the exact area.
Definition: fei2dtrlin.C:267
virtual double edgeEvalNormal(FloatArray &normal, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the normal on the given edge.
Definition: fei2dtrlin.C:201
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual double evalNXIntegral(int iEdge, const FEICellGeometry &cellgeo)
Computes the integral .
Definition: fei2dtrlin.C:286
virtual void edgeEvaldNds(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of edge interpolation functions (shape functions) at given point...
Definition: fei2dtrlin.C:191
#define N(p, q)
Definition: mdm.C:367
virtual int global2local(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Default implementation using Newton&#39;s method to find the local coordinates.
Definition: fei2dtrlin.C:103
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
double edgeComputeLength(IntArray &edgeNodes, const FEICellGeometry &cellgeo)
Definition: fei2dtrlin.C:253
virtual void local2global(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo)
Evaluates global coordinates from given local ones.
Definition: fei2dtrlin.C:81
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation.
Definition: fei2dtrlin.C:147
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
virtual int getRequiredNumberOfIntegrationPoints(integrationDomain dType, int approxOrder)
Abstract service.
virtual double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the edge Jacobian of transformation between local and global coordinates.
Definition: fei2dtrlin.C:337
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual int SetUpPointsOnTriangle(int, MaterialMode mode)
Sets up receiver&#39;s integration points on triangular (area coords) integration domain.
virtual double boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation Jacobian on the requested boundary.
Definition: fei2dtrlin.C:357
virtual bool inside(const FloatArray &lcoords) const
Definition: fei2dtrlin.C:162
the oofem namespace is to define a context or scope in which all oofem names are defined.
double normalize()
Normalizes receiver.
Definition: floatarray.C:828
Class representing Gaussian-quadrature integration rule.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:28 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011