$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

triangleBoundary3D.h

Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00025 #ifndef INNER_FLOW_BOUNDARY_3D_H
00026 #define INNER_FLOW_BOUNDARY_3D_H
00027 
00028 #include "core/globalDefs.h"
00029 #include "offLattice/boundaryShapes3D.h"
00030 #include "offLattice/triangleSet.h"
00031 #include "offLattice/triangularSurfaceMesh.h"
00032 #include "offLattice/offLatticeBoundaryProfiles3D.h"
00033 #include "particles/multiParticleField3D.h"
00034 #include "multiBlock/redistribution3D.h"
00035 #include "multiBlock/multiDataField3D.h"
00036 #include "atomicBlock/atomicContainerBlock3D.h"
00037 #include "multiBlock/multiContainerBlock3D.h"
00038 #include <stack>
00039 
00040 namespace plb {
00041 
00042 template<typename T>
00043 class DEFscaledMesh {
00044 public:
00045     DEFscaledMesh(TriangleSet<T> const& triangleSet_);
00046     DEFscaledMesh (
00047         TriangleSet<T> const& triangleSet_,
00048         plint resolution_, plint referenceDirection_,
00049         plint margin_, plint extraLayer );
00050     DEFscaledMesh (
00051         TriangleSet<T> const& triangleSet_,
00052         plint resolution_, plint referenceDirection_,
00053         plint margin_, Dot3D location );
00054     DEFscaledMesh(DEFscaledMesh<T> const& rhs);
00055     ~DEFscaledMesh();
00056     DEFscaledMesh<T>& operator=(DEFscaledMesh<T> const& rhs);
00057     void swap(DEFscaledMesh<T>& rhs);
00058 public: // Mesh usage interface.
00060     TriangularSurfaceMesh<T>& getMesh();
00062     TriangularSurfaceMesh<T> const& getMesh() const;
00063     plint getMargin() const;
00064     std::vector<Array<T,3> > const& getVertexList() const {
00065         return vertexList;
00066     }
00067     std::vector<plint> const& getEmanatingEdgeList() const {
00068         return emanatingEdgeList;
00069     }
00070     std::vector<typename TriangularSurfaceMesh<T>::Edge> const&
00071         getEdgeList() const {
00072             return edgeList;
00073         }
00074     Array<T,3> getPhysicalLocation() const {
00075         return physicalLocation;
00076     }
00077     T getDx() const {
00078         return dx;
00079     }
00080     void setPhysicalLocation(Array<T,3> physicalLocation_) {
00081         physicalLocation = physicalLocation_;
00082     }
00083     void setDx(T dx_) {
00084         dx = dx_;
00085     }
00086 private:
00087     void initialize (
00088         TriangleSet<T> const& triangleSet_, plint resolution_,
00089         plint referenceDirection_, Dot3D location );
00090 private:
00091     std::vector<Array<T,3> > vertexList;
00094     std::vector<plint> emanatingEdgeList;
00096     std::vector<typename TriangularSurfaceMesh<T>::Edge> edgeList;
00097     TriangularSurfaceMesh<T>* mesh;
00098     plint margin;
00099     Array<T,3> physicalLocation;
00100     T dx;
00101 };
00102 
00103 template<typename T>
00104 struct VertexProperty3D {
00105     virtual ~VertexProperty3D() { }
00106     // Wall portions which should not follow the laws of elasticity are rigid.
00107     virtual bool isRigid() const =0;
00108     // Inlet/outlet nodes are for example not part of the wall.
00109     virtual bool isWall() const =0;
00110     virtual VertexProperty3D<T>* clone() const =0;
00111 };
00112 
00113 template<typename T>
00114 struct RigidWallProperty3D : public VertexProperty3D<T> {
00115     virtual bool isRigid() const { return true; }
00116     virtual bool isWall() const { return true; }
00117     virtual RigidWallProperty3D<T>* clone() const {
00118         return new RigidWallProperty3D<T>(*this);
00119     }
00120 };
00121 
00122 template<typename T>
00123 struct InletOutletProperty3D : public VertexProperty3D<T> {
00124     virtual bool isRigid() const { return true; }
00125     virtual bool isWall() const { return false; }
00126     virtual InletOutletProperty3D<T>* clone() const {
00127         return new InletOutletProperty3D<T>(*this);
00128     }
00129 };
00130 
00131 template<typename T>
00132 bool isRigid(VertexProperty3D<T> const* property) {
00133     if (property) {
00134         return property->isRigid();
00135     }
00136     else {
00137         return false;
00138     }
00139 }
00140 
00141 template<typename T>
00142 bool isWall(VertexProperty3D<T> const* property) {
00143     if (property) {
00144         return property->isWall();
00145     }
00146     else {
00147         return true;
00148     }
00149 }
00150 
00151 template<typename T> class TriangleBoundary3D;
00152 
00153 template<typename T, class SurfaceData>
00154 class BoundaryProfiles3D {
00155 public:    
00156     BoundaryProfiles3D();
00157     ~BoundaryProfiles3D();
00158     BoundaryProfiles3D(BoundaryProfiles3D<T,SurfaceData> const& rhs);
00159     BoundaryProfiles3D<T,SurfaceData>& operator=(BoundaryProfiles3D<T,SurfaceData> const& rhs);
00160     void swap(BoundaryProfiles3D<T,SurfaceData>& rhs);
00161     void defineProfile(plint tag, BoundaryProfile3D<T,SurfaceData>* profile);
00162     void resetProfiles(std::map<plint,BoundaryProfile3D<T,SurfaceData>*> profiles_);
00163     void defineInletOutletTags(TriangleBoundary3D<T> const& boundary, plint sortDirection);
00164     void setWallProfile(BoundaryProfile3D<T,SurfaceData>* wallProfile_);
00165     void setInletOutlet( std::vector<BoundaryProfile3D<T,SurfaceData>*> inletOutlets );
00166     void setInletOutlet( BoundaryProfile3D<T,SurfaceData>* profile1, BoundaryProfile3D<T,SurfaceData>* profile2 );
00167     void setInletOutlet( BoundaryProfile3D<T,SurfaceData>* profile1, BoundaryProfile3D<T,SurfaceData>* profile2,
00168                          BoundaryProfile3D<T,SurfaceData>* profile3 );
00169     void setInletOutlet( BoundaryProfile3D<T,SurfaceData>* profile1, BoundaryProfile3D<T,SurfaceData>* profile2,
00170                          BoundaryProfile3D<T,SurfaceData>* profile3, BoundaryProfile3D<T,SurfaceData>* profile4 );
00171     void adjustInletOutlet(TriangleBoundary3D<T> const& boundary, plint sortDirection);
00172     BoundaryProfile3D<T,SurfaceData> const& getProfile (
00173             TriangleBoundary3D<T> const& boundary, plint iTriangle ) const;
00174 private:
00175     void replaceProfile(plint id, BoundaryProfile3D<T,SurfaceData>* newProfile);
00176     void clearProfiles();
00177 private:
00178     BoundaryProfile3D<T,SurfaceData>* wallProfile;
00179     std::map<plint,BoundaryProfile3D<T,SurfaceData>*> profiles;
00180     std::vector<plint> inletOutletIds;
00181     std::vector<Array<T,3> > lidNormal;
00182     std::vector<Array<T,3> > lidCenter;
00183     std::vector<T> lidRadius;
00184 };
00185 
00186 template<typename T>
00187 class TriangleBoundary3D {
00188 public:
00189     TriangleBoundary3D(DEFscaledMesh<T> const& defMesh, bool automaticCloseHoles=true);
00190     ~TriangleBoundary3D();
00191     TriangleBoundary3D(TriangleBoundary3D<T> const& rhs);
00192     TriangleBoundary3D<T>& operator=(TriangleBoundary3D<T> const& rhs);
00193     void swap(TriangleBoundary3D<T>& rhs);
00194 public: // Mesh usage interface.
00197     TriangleBoundary3D<T> const& select (
00198             plint whichTopology, plint whichVertices ) const;
00202     TriangleBoundary3D<T> const& pushSelect (
00203             plint whichTopology, plint whichVertices ) const;
00206     TriangleBoundary3D<T> const& popSelect() const;
00207     void getSelection(plint& whichTopology, plint& whichVertices) const;
00209     TriangularSurfaceMesh<T>& getMesh();
00211     TriangularSurfaceMesh<T> const& getMesh() const;
00215     VertexProperty3D<T> const* getVertexProperty(plint iVertex) const;
00219     bool intersectSegment (
00220             plint iTriangle, AtomicBlock3D* boundaryArg,
00221             Array<T,3> const& fromPoint, Array<T,3> const& direction,
00222             Array<T,3>& locatedPoint, T& distance, Array<T,3>& wallNormal ) const;
00226     Array<T,3> computeContinuousNormal (
00227             Array<T,3> const& p, plint iTriangle, bool isAreaWeighted = false ) const;
00229     void cloneVertexSet(plint whichVertexSet);
00231     Array<T,3> getPhysicalLocation() const {
00232         return physicalLocation;
00233     }
00235     T getDx() const {
00236         return dx;
00237     }
00238 public: // Mesh preparation interface.
00240     std::vector<typename TriangularSurfaceMesh<T>::Lid> const& getInletOutlet() const;
00242 
00246     std::vector<typename TriangularSurfaceMesh<T>::Lid> getInletOutlet(plint sortDirection) const;
00247     template<typename DomainFunctional> plint tagDomain(DomainFunctional functional);
00248     template<typename DomainFunctional> plint tagDomain(DomainFunctional functional, Array<T,3> normal, T angleTolerance, plint previousTag=-1);
00249     std::vector<plint> getInletOutletIds(plint sortDirection) const;
00250     void getLidProperties (
00251         plint sortDirection, std::vector<Array<T,3> >& normal,
00252         std::vector<Array<T,3> >& center, std::vector<T>& radius ) const;
00255 
00256     template<typename DomainFunctional>
00257     plint setVertexProperty (
00258             VertexProperty3D<T> const& property, DomainFunctional functional );
00259     plint getMargin() const;
00262     plint getTag(plint iTriangle) const;
00263     std::vector<plint> const& getTriangleTags() const { return triangleTagList; }
00264     std::vector<plint> const& getVertexTags() const { return vertexTagList; }
00265 private:
00266     plint currentMesh() const;
00267     void defineMeshes();
00271     void closeHoles();
00272     void assignLidVertexProperty();
00273 private:
00277     void tagInletOutlet (
00278         std::vector<typename TriangularSurfaceMesh<T>::Lid> const& newLids );
00282     std::vector< std::vector<Array<T,3> > > vertexLists;
00285     std::vector<plint> emanatingEdgeLists[2];
00288     std::vector<typename TriangularSurfaceMesh<T>::Edge> edgeLists[2];
00292     std::vector<TriangularSurfaceMesh<T> > meshes;
00295     std::vector<plint> triangleTagList;
00296     plint currentTagNum;
00299     std::vector<plint> vertexTagList;
00301     std::vector<VertexProperty3D<T>*> vertexProperties;
00303     std::vector<typename TriangularSurfaceMesh<T>::Lid> lids;
00304     plint margin;
00305     Array<T,3> physicalLocation;
00306     T dx;
00307     mutable std::stack<plint> topology;
00308     mutable std::stack<plint> vertexSet;
00309 };
00310 
00311 template< typename T, class SurfaceData >
00312 class TriangleFlowShape3D : public BoundaryShape3D<T,SurfaceData> {
00313 public:
00314     TriangleFlowShape3D (
00315             TriangleBoundary3D<T> const& boundary_,
00316             BoundaryProfiles3D<T,SurfaceData> const& profiles_ );
00317     virtual bool isInside(Dot3D const& location) const;
00318     virtual bool pointOnSurface (
00319             Array<T,3> const& fromPoint, Array<T,3> const& direction,
00320             Array<T,3>& locatedPoint, T& distance,
00321             Array<T,3>& wallNormal, SurfaceData& surfaceData,
00322             OffBoundary::Type& bdType, plint& id ) const;
00323     virtual Array<T,3> computeContinuousNormal (
00324             Array<T,3> const& p, plint id, bool isAreaWeighted = false ) const;
00325     virtual bool intersectsSurface (
00326             Array<T,3> const& p1, Array<T,3> const& p2, plint& id ) const;
00327     virtual plint getTag(plint id) const;
00328     virtual bool distanceToSurface( Array<T,3> const& point,
00329                                     T& distance, bool& isBehind ) const;
00330     virtual TriangleFlowShape3D<T,SurfaceData>* clone() const;
00332 
00339     virtual TriangleFlowShape3D<T,SurfaceData>*
00340                 clone(std::vector<AtomicBlock3D*> args) const;
00341 private:
00342     TriangleBoundary3D<T> const& boundary;
00343     BoundaryProfiles3D<T,SurfaceData> const& profiles;
00345     ScalarField3D<int>* voxelFlags;
00347     AtomicContainerBlock3D* hashContainer;
00348     AtomicBlock3D* boundaryArg;
00349 };
00350 
00351 template<typename T>
00352 class VoxelizedDomain3D {
00353 public:
00354     VoxelizedDomain3D(TriangleBoundary3D<T> const& boundary_,
00355                       int flowType_, plint extraLayer_, plint borderWidth_,
00356                       plint envelopeWidth_, plint blockSize_,
00357                       plint gridLevel_=0, bool dynamicMesh_ = false);
00358     VoxelizedDomain3D(TriangleBoundary3D<T> const& boundary_,
00359                       int flowType_, Box3D const& boundingBox, plint borderWidth_,
00360                       plint envelopeWidth_, plint blockSize_,
00361                       plint gridLevel_=0, bool dynamicMesh_ = false);
00362     VoxelizedDomain3D(VoxelizedDomain3D<T> const& rhs);
00363     ~VoxelizedDomain3D();
00364     MultiScalarField3D<int>& getVoxelMatrix();
00365     MultiScalarField3D<int> const& getVoxelMatrix() const;
00366     MultiContainerBlock3D& getTriangleHash();
00367     MultiBlockManagement3D const& getMultiBlockManagement() const;
00368     template<class ParticleFieldT>
00369     void adjustVoxelization(MultiParticleField3D<ParticleFieldT>& particles, bool dynamicMesh);
00370     void reparallelize(MultiBlockRedistribute3D const& redistribute);
00371     TriangleBoundary3D<T> const& getBoundary() const { return boundary; }
00372     int getFlowType() const { return flowType; }
00373 private:
00374     VoxelizedDomain3D<T>& operator=(VoxelizedDomain3D<T> const& rhs) { }
00375     void createSparseVoxelMatrix (
00376         MultiScalarField3D<int>& fullVoxelMatrix,
00377         plint blockSize_, plint envelopeWidth_ );
00378     void computeSparseVoxelMatrix (
00379             MultiScalarField3D<int>& fullVoxelMatrix,
00380             plint blockSize, plint envelopeWidth );
00381     void extendEnvelopeWidth (
00382             MultiScalarField3D<int>& fullVoxelMatrix, plint envelopeWidth );
00383     void createTriangleHash();
00384     template<class ParticleFieldT>
00385     void reCreateTriangleHash(MultiParticleField3D<ParticleFieldT>& particles);
00386     void computeOuterMask();
00387 private:
00388     int flowType;
00389     plint borderWidth;
00390     TriangleBoundary3D<T> const& boundary;
00391     MultiScalarField3D<int>* voxelMatrix;
00392     MultiContainerBlock3D* triangleHash;
00393 };
00394 
00395 template<typename T>
00396 void addLayer(MultiScalarField3D<T>& matrix, Box3D const& domain,
00397               T previousLayer);
00398 
00399 template<typename T>
00400 class AddLayerFunctional3D : public BoxProcessingFunctional3D_S<T> {
00401 public:
00402     AddLayerFunctional3D(T previousLayer_);
00403     virtual void process(Box3D domain, ScalarField3D<T>& voxels);
00404     virtual AddLayerFunctional3D<T>* clone() const;
00405     virtual void getTypeOfModification(std::vector<modif::ModifT>& modified) const;
00406     virtual BlockDomain::DomainT appliesTo() const;
00407 private:
00408     T previousLayer;
00409 };
00410 
00411 }  // namespace plb
00412 
00413 #endif  // INNER_FLOW_BOUNDARY_3D_H