OOFEM 3.0
Loading...
Searching...
No Matches
patchintegrationrule.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
37//#include "patch.h"
38#include "integrationrule.h"
40#include "geometry.h"
41#include "classfactory.h"
42#include "contextioerr.h"
43#include "datastream.h"
44#include "gausspoint.h"
45#include "fei2dtrlin.h"
46#include "fei3dtrquad.h"
47#include "XFEMDebugTools.h"
48
49#include "timestep.h"
50#include "engngm.h"
51
52namespace oofem {
53PatchIntegrationRule :: PatchIntegrationRule(int n, Element *e, const std :: vector< Triangle > &iTriangles) :
55 mTriangles(iTriangles)
56{ }
57
58PatchIntegrationRule :: ~PatchIntegrationRule()
59{ }
60
61FEI2dTrLin PatchIntegrationRule :: mTriInterp(1, 2);
62FEI3dTrQuad PatchIntegrationRule :: mTriInterpQuad;
63
64int
65PatchIntegrationRule :: SetUpPointsOnTriangle(int nPoints, MaterialMode mode)
66{
67 int pointsPassed = 0;
68
69 // TODO: set properly
72
73
75 // Allocate Gauss point array
76
77
78 // It may happen that the patch contains triangles with
79 // zero area. This does no harm, since their weights in
80 // the quadrature will be zero. However, they invoke additional
81 // computational cost and therefore we want to avoid them.
82 // Thus, count the number of triangles with finite area
83 // and keep only those triangles.
84
85 double totArea = 0.0;
86 for ( size_t i = 0; i < mTriangles.size(); i++ ) {
87 totArea += mTriangles [ i ].getArea();
88 }
89
90 std :: vector< int >triToKeep;
91 const double triTol = ( 1.0e-6 ) * totArea;
92
93 for ( size_t i = 0; i < mTriangles.size(); i++ ) {
94 if ( mTriangles [ i ].getArea() > triTol ) {
95 triToKeep.push_back(i);
96 }
97 }
98
99 int nPointsTot = nPoints * triToKeep.size();
100 FloatArray coords_xi1, coords_xi2, weights;
101 this->giveTriCoordsAndWeights(nPoints, coords_xi1, coords_xi2, weights);
102 this->gaussPoints.resize(nPointsTot);
104
105
106 std :: vector< FloatArray >newGPCoord;
107
108 double parentArea = this->elem->computeArea();
109
110 // Loop over triangles
111 for ( int tri: triToKeep ) {
112 // TODO: Probably unnecessary to allocate here
113 std :: vector< FloatArray >coords( mTriangles [ tri ].giveNrVertices() );
114 // this we should put into the function before
115 for ( int k = 1; k <= mTriangles [ tri ].giveNrVertices(); k++ ) {
116 coords [ k - 1 ] = mTriangles [ tri ].giveVertex(k);
117 }
118
119 // Can not be used because it writes to the start of the array instead of appending.
120 //int nPointsTri = GaussIntegrationRule :: SetUpPointsOnTriangle(nPoints, mode);
121
122 for ( int j = 0; j < nPoints; j++ ) {
123 FloatArray global;
124 GaussPoint * &gp = this->gaussPoints [ pointsPassed ];
125
126 gp = new GaussPoint(this, pointsPassed + 1,
127 Vec2(coords_xi1.at(j + 1), coords_xi2.at(j + 1)),
128 weights.at(j + 1), mode);
129
130
131
132 mTriInterp.local2global( global, gp->giveNaturalCoordinates(),
133 FEIVertexListGeometryWrapper(coords, EGT_triangle_1) );
134
135 newGPCoord.push_back(global);
136
137
138 FloatArray local;
139 this->elem->computeLocalCoordinates(local, global);
140
141 gp->setGlobalCoordinates(global);
142 gp->setNaturalCoordinates(local);
143 gp->setSubPatchCoordinates(local);
144
145
146
147
148 double refElArea = this->elem->giveParentElSize();
149
150 gp->setWeight(2.0 * refElArea * gp->giveWeight() * mTriangles [ tri ].getArea() / parentArea); // update integration weight
151
152
153 pointsPassed++;
154 }
155 }
156
157 XfemManager *xMan = elem->giveDomain()->giveXfemManager();
158 if ( xMan ) {
159 if ( xMan->giveVtkDebug() ) {
160 double time = 0.0;
161
162 Element *el = this->elem;
163 if ( el ) {
164 Domain *dom = el->giveDomain();
165 if ( dom ) {
166 EngngModel *em = dom->giveEngngModel();
167 if ( em ) {
168 TimeStep *ts = em->giveCurrentStep();
169 if ( ts ) {
170 time = ts->giveTargetTime();
171 }
172 }
173 }
174 }
175
176 int elIndex = this->elem->giveGlobalNumber();
177 std :: stringstream str;
178 str << "GaussPointsTime" << time << "El" << elIndex << ".vtk";
179 std :: string name = str.str();
180
181 XFEMDebugTools :: WritePointsToVTK(name, newGPCoord);
182 }
183 }
184
185 return this->giveNumberOfIntegrationPoints();
186}
187
188
189
190
191int
192PatchIntegrationRule :: SetUpPointsOnWedge(int nPointsTri, int nPointsDepth, MaterialMode mode)
193{
194 //int pointsPassed = 0;
195
196 // TODO: set properly
199
200 double totArea = 0.0;
201 for ( size_t i = 0; i < mTriangles.size(); i++ ) {
202 totArea += mTriangles [ i ].getArea();
203 }
204
205 std :: vector< int >triToKeep;
206 const double triTol = ( 1.0e-6 ) * totArea;
207
208 for ( size_t i = 0; i < mTriangles.size(); i++ ) {
209 if ( mTriangles [ i ].getArea() > triTol ) {
210 triToKeep.push_back(i);
211 }
212 }
213
214 int nPointsTot = nPointsTri * nPointsDepth * triToKeep.size();
215 FloatArray coords_xi1, coords_xi2, coords_xi3, weightsTri, weightsDepth;
216 this->giveTriCoordsAndWeights(nPointsTri, coords_xi1, coords_xi2, weightsTri);
217 this->giveLineCoordsAndWeights(nPointsDepth, coords_xi3, weightsDepth);
218 this->gaussPoints.resize(nPointsTot);
219
220 std :: vector< FloatArray >newGPCoord;
221
222 double parentArea = this->elem->computeArea();
223 int count = 0;
224
225 // Loop over triangles
226 for ( int i = 0; i < int( triToKeep.size() ); i++ ) {
227 Triangle triangle = mTriangles [ triToKeep [ i ] ];
228
229 // global coords of the the triangle verticies
230 std :: vector< FloatArray >gCoords( triangle.giveNrVertices() );
231 for ( int j = 0; j < triangle.giveNrVertices(); j++ ) {
232 gCoords [ j ] = ( triangle.giveVertex(j + 1) );
233 }
234
235
236 for ( int k = 1; k <= nPointsTri; k++ ) {
237 for ( int m = 1; m <= nPointsDepth; m++ ) {
238 // local coords in the parent triangle
239
240 double refElArea = 0.5;
241 double oldWeight = weightsTri.at(k) * weightsDepth.at(m);
242 double newWeight = 2.0 * refElArea * oldWeight * triangle.getArea() / parentArea;
243
244 GaussPoint *gp = new GaussPoint(this, count + 1,
245 Vec3(coords_xi1.at(k), coords_xi2.at(k), coords_xi3.at(m)),
246 newWeight, mode);
247 this->gaussPoints [ count ] = gp;
248 count++;
249
250
251 // Compute global gp coordinate in the element from local gp coord in the sub triangle
252 FloatArray global;
253 mTriInterp.local2global( global, gp->giveNaturalCoordinates(),
254 FEIVertexListGeometryWrapper(gCoords, EGT_triangle_1) );
255
256
257 // Compute local gp coordinate in the element from global gp coord in the element
258 FloatArray local;
259 this->elem->computeLocalCoordinates(local, global);
260 local.at(3) = coords_xi3.at(m); // manually set third coordinate
261 // compute global coords again, since interpolator dosn't give the z-coord
262 this->elem->computeGlobalCoordinates(global, local);
263
264 gp->setGlobalCoordinates(global);
265 gp->setNaturalCoordinates(local);
266 gp->setSubPatchCoordinates(local);
267
268 // Store new global gp coord for vtk output
269 newGPCoord.push_back(global);
270 }
271 }
272 }
273
274 XfemManager *xMan = elem->giveDomain()->giveXfemManager();
275 if ( xMan ) {
276 if ( xMan->giveVtkDebug() ) {
277 double time = 0.0;
278
279 Element *el = this->elem;
280 if ( el ) {
281 Domain *dom = el->giveDomain();
282 if ( dom ) {
283 EngngModel *em = dom->giveEngngModel();
284 if ( em ) {
285 TimeStep *ts = em->giveCurrentStep();
286 if ( ts ) {
287 time = ts->giveTargetTime();
288 }
289 }
290 }
291 }
292
293 int elIndex = this->elem->giveGlobalNumber();
294 std :: stringstream str;
295 str << "GaussPointsTime" << time << "El" << elIndex << ".vtk";
296 std :: string name = str.str();
297
298 XFEMDebugTools :: WritePointsToVTK(name, newGPCoord);
299 }
300 }
301
302
303 return this->giveNumberOfIntegrationPoints();
304}
305
306
307void
308PatchIntegrationRule :: saveContext(DataStream &stream, ContextMode mode)
309{
311 IntegrationRule :: saveContext(stream, mode);
312
313#if 0
314 // save patch data
315 if ( this->patch ) {
316 // store patch type
317 int _type = this->patch->givePatchType();
318 if ( !stream.write(_type) ) {
320 }
321 patch->saveContext(stream, mode);
322 } else {
323 OOFEM_ERROR("can't store NULL patch");
324 }
325#endif
326}
327
328void
329PatchIntegrationRule :: restoreContext(DataStream &stream, ContextMode mode)
330{
332 IntegrationRule :: restoreContext(stream, mode);
333
334 int _ptype;
335 if ( !stream.read(_ptype) ) {
337 }
338}
339} // end namespace oofem
const FloatArray & giveVertex(int n) const
Definition geometry.h:124
int giveNrVertices() const
Returns number of Geometry vertices.
Definition geometry.h:144
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
EngngModel * giveEngngModel()
Definition domain.C:419
virtual TimeStep * giveCurrentStep(bool force=false)
Definition engngm.h:717
Domain * giveDomain() const
Definition femcmpnn.h:97
double & at(Index i)
Definition floatarray.h:202
static void giveTriCoordsAndWeights(int nPoints, FloatArray &coords_xi1, FloatArray &coords_xi2, FloatArray &weights)
GaussIntegrationRule(int n, Element *e, int startIndx, int endIndx, bool dynamic=false)
static void giveLineCoordsAndWeights(int nPoints, FloatArray &coords_xi, FloatArray &weights)
void setNaturalCoordinates(const FloatArray &c)
Definition gausspoint.h:139
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
void setSubPatchCoordinates(const FloatArray &c)
Definition gausspoint.h:150
void setWeight(double w)
Definition gausspoint.h:181
double giveWeight()
Returns integration weight of receiver.
Definition gausspoint.h:180
void setGlobalCoordinates(const FloatArray &iCoord)
Definition gausspoint.h:170
Element * elem
Element which integration rule is coupled to.
int giveNumberOfIntegrationPoints() const
std::vector< GaussPoint * > gaussPoints
Array containing integration points.
std ::vector< Triangle > mTriangles
double giveTargetTime()
Returns target time.
Definition timestep.h:164
double getArea()
Definition geometry.C:410
bool giveVtkDebug() const
#define THROW_CIOERR(e)
#define OOFEM_ERROR(...)
Definition error.h:79
static FloatArray Vec2(const double &a, const double &b)
Definition floatarray.h:606
long ContextMode
Definition contextmode.h:43
@ CIO_IOERR
General IO error.
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