OOFEM 3.0
Loading...
Searching...
No Matches
unstructuredgridfield.h
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#ifndef unstructuredgridfield_h
36#define unstructuredgridfield_h
37
38#include "field.h"
39#include "floatarray.h"
40#include "intarray.h"
41#include "elementgeometrytype.h"
42#include "feinterpol.h"
43#include "fei2dlinelin.h"
44#include "fei2dlinequad.h"
45#include "fei2dtrlin.h"
46#include "fei2dtrquad.h"
47#include "fei2dquadlin.h"
48#include "fei2dquadquad.h"
49#include "fei3dtetlin.h"
50#include "fei3dhexalin.h"
51#include "octreelocalizert.h"
52#include "error.h"
53
54namespace oofem {
63{
64protected:
65 class Vertex
66 {
68public:
69 Vertex() : coords() {}
71 Vertex &operator=(const Vertex &v) {
72 coords = v.coords;
73 return * this;
74 }
75 const FloatArray &getCoordinates() const { return coords; }
76 };
77
78 /* Auxiliary class to represent interpolation cell, basically holding vertices defining its shape and interpolation type */
79 class Cell
80 {
84
85 // array of interpolation instances used for supported ElementGeometryTypes
88 static FEI2dTrLin i3;
94
96
97
102 {
103protected:
104 const Cell *cell;
105public:
107 this->cell = c;
108 }
110
111 int giveNumberOfVertices() const override {
112 return this->cell->giveNumberOfVertices();
113 }
114
115 const FloatArray giveVertexCoordinates(int i) const override
116 {
117 return ( ( cell->getVertex(i) )->getCoordinates() );
118 }
120 return cell->itype;
121 }
122 };
123
124public:
126 itype = EGT_unknown;
127 mesh = NULL;
128 }
130 itype = t;
131 vertices = v;
132 mesh = m;
133 }
134
135 Cell &operator=(const Cell &c) {
136 itype = c.itype;
137 vertices = c.vertices;
138 mesh = c.mesh;
139 return * this;
140 }
141
142 int giveNumberOfVertices() const { return vertices.giveSize(); }
143 bool containsPoint(const FloatArray &coords) const {
144 FloatArray tmp;
145 BoundingBox b;
146 this->giveBoundingBox(b);
147 if ( b.contains(coords) ) {
149 return ( this->getInterpolation()->global2local(tmp, coords, cgw) );
150 }
151 return false;
152 }
153
154 void giveBoundingBox(BoundingBox &bb) const {
155 double size;
156 FloatArray bb0, bb1;
157 bb1 = bb0 = this->getVertex(1)->getCoordinates();
158
159 for ( int i = 2; i <= this->giveNumberOfVertices(); i++ ) {
160 const auto &coordinates = this->getVertex(i)->getCoordinates();
161 bb0.beMinOf(bb0, coordinates);
162 bb1.beMaxOf(bb1, coordinates);
163 }
164 bb1.subtract(bb0);
165 int nsd = bb1.giveSize();
166 IntArray mask(3);
167 size = bb1.at(1);
168 for ( int i = 1; i < nsd; i++ ) { size = max(size, bb1 [ i ]); }
169 for ( int i = 0; i < nsd; i++ ) { mask [ i ] = 1; }
170 bb.init(bb0, size, mask);
171 }
172
173 double giveClosestPoint(FloatArray &lcoords, FloatArray &closest, const FloatArray &gcoords) {
174 FEInterpolation *interp = this->getInterpolation();
175
176 if ( !interp->global2local(lcoords, gcoords, FEICellGeometryWrapper(this) ) ) { // Outside element
177 interp->local2global(closest, lcoords, FEICellGeometryWrapper(this) );
178 return distance(closest, gcoords);
179 } else {
180 closest = gcoords;
181 return 0.0;
182 }
183 }
184
186 if ( this->itype == EGT_line_1 ) { return interpTable [ 0 ]; } else if ( this->itype == EGT_line_2 ) { return interpTable [ 1 ]; } else if ( this->itype == EGT_triangle_1 ) { return interpTable [ 2 ]; } else if ( this->itype == EGT_triangle_2 ) { return interpTable [ 3 ]; } else if ( this->itype == EGT_quad_1 ) { return interpTable [ 4 ]; } else if ( this->itype == EGT_quad_2 ) { return interpTable [ 5 ]; } else if ( this->itype == EGT_tetra_1 ) { return interpTable [ 6 ]; } else if ( this->itype == EGT_hexa_1 ) { return interpTable [ 7 ]; } else {
187 OOFEM_LOG_ERROR("UnstructuredGridField.Cell:: Unsupported cell type");
188 return NULL;
189 }
190 }
191 const Vertex *getVertex(int i) const {//1-based
192 return mesh->getVertex(vertices [ i - 1 ]);
193 }
194
195 int interpolate(FloatArray &answer, const FloatArray &pos, FloatArray **vertexVals) {
196 int i, j, size = vertexVals [ 0 ]->giveSize();
197 FloatArray N, lcoords;
198
199 FEInterpolation *it = this->getInterpolation();
200 FEICellGeometryWrapper cw(this);
201 it->global2local(lcoords, pos, cw);
202 it->evalN(N, lcoords, cw);
203
204 answer.resize(size);
205 answer.zero();
206 for ( i = 0; i < giveNumberOfVertices(); i++ ) {
207 for ( j = 0; j < size; j++ ) {
208 answer(j) += N(i) * vertexVals [ i ]->at(j + 1);
209 }
210 }
211 return 1;
212 }
213
214 int getVertexNum(int i) { //1-based
215 return this->vertices [ i - 1 ];
216 }
217 };
218
219
221 {
222private:
223public:
225 bool evaluate(Cell &member, OctantRecT< Cell > *cell) override {
226 BoundingBox b;
227 member.giveBoundingBox(b);
229 if ( ( s == OctantRec::BBS_InsideCell ) || ( s == OctantRec::BBS_ContainsCell ) ) {
230 return true;
231 } else {
232 return false;
233 }
234 }
235
236 void registerInsertion(Cell &member, LocalInsertionData< Cell >lidata) override {}
237 std::list< LocalInsertionData< Cell > > *giveInsertionList(Cell &m) override { return nullptr; }
238 };
239
241 {
242protected:
244 std::list< Cell >cells;
245public:
253
259 bool evaluate(Cell &c) override
260 {
261 if ( c.containsPoint(position) ) {
262 cells.push_back(c);
263 return true;
264 } else {
265 return false;
266 }
267 }
268
273 void giveStartingPosition(FloatArray &answer) override
274 {
275 answer = position;
276 }
277
282 void giveResult(std::list< Cell > &answer) override
283 { answer = cells; }
284
285 bool isBBXStage1Defined(BoundingBox &BBXStage1) override { return true; }
286 bool isBBXStage2Defined(BoundingBox &BBXStage2) override { return false; }
287 };
288
289
290 std::vector< Cell >cellList;
291 std::vector< Vertex >vertexList;
292 std::vector< FloatArray >valueList;
301 long int timeStamp;
304public:
308 UnstructuredGridField(int nvert, int ncells, double octreeOriginShift = 0.0) : Field(FieldType::FT_Unknown), spatialLocalizer()
309 {
310 this->timeStamp = this->octreeTimeStamp = 0;
311 this->vertexList.resize(nvert);
312 this->cellList.resize(ncells);
313 this->valueList.resize(nvert);
314 this->octreeOriginShift = octreeOriginShift;
315 }
317
318 void initialize(int nvert, int ncells, double _octreeOriginShift = 0.0)
319 {
320 this->timeStamp = this->octreeTimeStamp = 0;
321 this->vertexList.resize(nvert);
322 this->cellList.resize(ncells);
323 this->valueList.resize(nvert);
324 this->octreeOriginShift = _octreeOriginShift;
325 }
326 int giveNumberOfVertices() const { return (int)vertexList.size(); }
327 int giveNumberOfCells() const { return (int)cellList.size(); }
328
329 void setVertexValue(int num, const FloatArray &vv) {
330 valueList [ num - 1 ] = vv;
331 }
332
333 void addVertex(int num, FloatArray &coords) {//1-based
334 vertexList [ num - 1 ] = Vertex(coords);
335 this->timeStamp++;
336 }
337
338 const FloatArray &getVertexCoordinates(int num) const
339 {
340 return ( this->vertexList [ num - 1 ].getCoordinates() );
341 }
342
343 Vertex *getVertex(int num) { //1-based
344 return & this->vertexList [ num - 1 ];
345 }
346
347 void addCell(int num, const Element_Geometry_Type type, IntArray &vertices) { //1-based
348 cellList [ num - 1 ] = Cell(type, vertices, this);
349 this->timeStamp++;
350 }
351
352 int evaluateAt(FloatArray &answer, const FloatArray &coords,
353 ValueModeType mode, TimeStep *tStep) override {
354 std::list< Cell >elist;
355 if ( ( mode == VM_Total ) || ( mode == VM_TotalIntrinsic ) ) {
356 if ( this->cellList.size() > 0 ) {
357 this->initOctree();
359 this->spatialLocalizer.giveDataOnFilter(elist, f);
360 if ( elist.size() ) {
361 Cell &c = elist.front(); // take first
362 // colect vertex values
363 int size = c.giveNumberOfVertices();
364 FloatArray **vertexValues = new FloatArray * [ size ];
365 for ( int i = 0; i < size; i++ ) {
366 vertexValues [ i ] = & ( this->valueList [ c.getVertexNum(i + 1) - 1 ] );
367 }
368 c.interpolate(answer, coords, vertexValues);
369 //answer.printYourself();
370 return 0;
371 } else {
372 coords.printYourself();
373 OOFEM_ERROR("No cells defined");
374 return 1;
375 }
376 } else {
377 if ( !this->vertexList.size() ) {
378 OOFEM_ERROR("No vertices defined");
379 return 1;
380 }
381 // alternative method - we use the value of the closest point
382 double minDist = 0., dist = 0.;
383
384 int idOfClosestPoint = -1;
385 for ( int i = 0; i < ( int ) this->vertexList.size(); i++ ) {
386 const auto &pcoords = this->vertexList [ i ].getCoordinates();
387 dist = sqrt(pow(coords [ 0 ] - pcoords.at(1), 2) + pow(coords [ 1 ] - pcoords.at(2), 2) + pow(coords [ 2 ] - pcoords.at(3), 2) );
388 if ( ( dist < minDist ) || ( !i ) ) {
389 minDist = dist;
390 idOfClosestPoint = i;
391 }
392 }
393 answer = this->valueList [ idOfClosestPoint ];
394 //printf("closest point is %d\n",idOfClosestPoint);
395 return 0;
396 }
397 } else {
398 OOFEM_ERROR("Unsupported ValueModeType");
399 }
400 }
401
405 int evaluateAt(FloatArray &answer, DofManager *dman,
406 ValueModeType mode, TimeStep *tStep) override {
407 const auto &coords = dman->giveCoordinates();
408 return this->evaluateAt(answer, coords, mode, tStep);
409 }
410
411 void saveContext(DataStream &stream) override { }
412 void restoreContext(DataStream &stream) override { }
413
415 const char *giveClassName() const override { return "UnstructuredGridField"; }
416
417protected:
418 void initOctree() {
419 if ( this->timeStamp != this->octreeTimeStamp ) {
420 // rebuild octree
421 this->spatialLocalizer.clear();
422 // get octree bbox
423 std::vector< Vertex >::iterator it = vertexList.begin();
424 FloatArray cmax, cmin;
425 cmax = cmin = ( * it ).getCoordinates();
426 int nsd = cmin.giveSize();
427 ++it;
428 for ( ; it != vertexList.end(); ++it ) {
429 const auto &vc = ( * it ).getCoordinates();
430 for ( int j = 0; j < nsd; j++ ) {
431 cmax(j) = max(cmax(j), vc(j) );
432 cmin(j) = min(cmin(j), vc(j) );
433 }
434 }
435 // introduce origin shift (if set up)
436 for ( int j = 0; j < nsd; j++ ) {
437 cmin(j) -= octreeOriginShift;
438 }
439 double size = 0.0;
440 IntArray mask(3);
441 for ( int j = 0; j < nsd; j++ ) {
442 size = max(size, cmax(j) - cmin(j) );
443 mask [ j ] = 1;
444 }
445 BoundingBox bb;
446 bb.init(cmin, size, mask);
447 this->spatialLocalizer.init(bb);
448 std::vector< Cell >::iterator cit;
450 //int cellcount = 1;
451 for ( cit = this->cellList.begin(); cit != this->cellList.end(); ++cit ) {
452 /*
453 * BoundingBox b; (*cit).giveBoundingBox(b);
454 * FloatArray o;
455 * b.giveOrigin(o);
456 * printf ("Inserting cell %d, Origin, Size:", cellcount++);
457 * o.printYourself();
458 * printf("%lf\n", b.giveSize());
459 */
460 this->spatialLocalizer.insertMemberIntoOctree(* cit, cf);
461 }
462
463 // update timestamp
464 this->octreeTimeStamp = this->timeStamp;
465 }
466 }
467};
468} // end namespace oofem
469#endif // unstructuredgridfield_h
#define N(a, b)
void init(FloatArray &_origin, double _size, IntArray &mask)
bool contains(const FloatArray &coords) const
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
virtual int global2local(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo) const =0
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual void local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
Field(FieldType b=FieldType::FT_Unknown)
Definition field.h:95
FieldType type
Definition field.h:88
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
virtual void printYourself() const
Definition floatarray.C:762
void beMinOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:377
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beMaxOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:350
void subtract(const FloatArray &src)
Definition floatarray.C:320
OctantRec::BoundingBoxStatus testBoundingBox(BoundingBox &A)
void giveDataOnFilter(std ::list< T > &answer, SL_Evaluation_Functor< T > &filter)
Evalutes the search accoring used functor a fills the list with results - NOT IN USE.
int insertMemberIntoOctree(T &memberID, SL_Insertion_Functor< T > &functor)
Inserts member into the octree using functor for the evaluation.
int init(BoundingBox &BBX, int initialDivision=0)
Initilizes the octree structure.
void registerInsertion(Cell &member, LocalInsertionData< Cell >lidata) override
bool evaluate(Cell &member, OctantRecT< Cell > *cell) override
std::list< LocalInsertionData< Cell > > * giveInsertionList(Cell &m) override
const Element_Geometry_Type giveGeometryType() const override
Cell(const Element_Geometry_Type t, IntArray &v, UnstructuredGridField *m)
void giveBoundingBox(BoundingBox &bb) const
const Vertex * getVertex(int i) const
int interpolate(FloatArray &answer, const FloatArray &pos, FloatArray **vertexVals)
bool containsPoint(const FloatArray &coords) const
static FEInterpolation * interpTable[]
FEInterpolation * getInterpolation() const
double giveClosestPoint(FloatArray &lcoords, FloatArray &closest, const FloatArray &gcoords)
const FloatArray & getCoordinates() const
void addVertex(int num, FloatArray &coords)
int evaluateAt(FloatArray &answer, const FloatArray &coords, ValueModeType mode, TimeStep *tStep) override
void saveContext(DataStream &stream) override
const char * giveClassName() const override
void setVertexValue(int num, const FloatArray &vv)
int evaluateAt(FloatArray &answer, DofManager *dman, ValueModeType mode, TimeStep *tStep) override
double octreeOriginShift
octree origin shift
void restoreContext(DataStream &stream) override
void addCell(int num, const Element_Geometry_Type type, IntArray &vertices)
OctreeSpatialLocalizerT< Cell > spatialLocalizer
const FloatArray & getVertexCoordinates(int num) const
long int octreeTimeStamp
octree build time stamp
UnstructuredGridField(int nvert, int ncells, double octreeOriginShift=0.0)
std::vector< FloatArray > valueList
long int timeStamp
receiver timestamp
void initialize(int nvert, int ncells, double _octreeOriginShift=0.0)
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_ERROR(...)
Definition logger.h:138
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FieldType
Physical type of field.
Definition field.h:64
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
double distance(const FloatArray &x, const FloatArray &y)
#define OOFEM_EXPORT
Definition oofemcfg.h:7

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