Forked from
gmsh / gmsh
16299 commits behind the upstream repository.
-
Stefen Guzik authoredStefen Guzik authored
MZoneBoundary.h 8.35 KiB
// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
//
// MZoneBoundary.h - Copyright (C) 2008 S. Guzik, C. Geuzaine, J.-F. Remacle
#ifndef _MZONEBOUNDARY_H_
#define _MZONEBOUNDARY_H_
/*******************************************************************************
*
* - The classes in this file are used to determine connectivity between
* multiple zones and, eventually, the domain boundary vertices
*
******************************************************************************/
#include "MZone.h"
/*==============================================================================
* Required types
*============================================================================*/
/*--------------------------------------------------------------------*
* Internal zone connectivity
*--------------------------------------------------------------------*/
//--Interface between two zones for connectivity
struct ZonePair
{
int zone1;
int zone2;
ZonePair(const int _zone1, const int _zone2)
{
if(_zone1 < zone2) {
zone1 = _zone1;
zone2 = _zone2;
}
else {
zone1 = _zone2;
zone2 = _zone1;
}
}
};
inline bool operator==(const ZonePair &zpA, const ZonePair &zpB)
{
return (zpA.zone1 == zpB.zone1 && zpA.zone2 == zpB.zone2);
}
// Less than for std::map
struct Less_ZonePair
: public std::binary_function<ZonePair, ZonePair, bool>
{
bool operator()(const ZonePair &zpA, const ZonePair &zpB) const
{
if(zpA.zone1 < zpB.zone1) return true;
if(zpA.zone1 > zpB.zone1) return false;
if(zpA.zone2 < zpB.zone2) return true;
return false;
}
};
//--Definition of the zone connectivity (a vector of vertex pairs for 2 zones).
struct ZoneConnectivity
{
// Internal structures
struct VertexPair // Pairs of vertices. Ordered based on
// zone indices.
{
MVertex *vertex;
int vertexIndex1;
int vertexIndex2;
// Constructors
VertexPair()
: vertex(0), vertexIndex1(0), vertexIndex2(0)
{ }
VertexPair(MVertex *const _vertex,
const unsigned zone1, const unsigned zone2,
const unsigned _vertexIndex1, const unsigned _vertexIndex2)
: vertex(_vertex)
{
if(zone1 < zone2) {
vertexIndex1 = _vertexIndex1;
vertexIndex2 = _vertexIndex2;
}
else {
vertexIndex1 = _vertexIndex2;
vertexIndex2 = _vertexIndex1;
}
}
};
// Data
std::vector<VertexPair> vertexPairVec;
// Constructor
ZoneConnectivity()
{
vertexPairVec.reserve(32); // Avoid small reallocations
}
};
//--Output type for zone connectivity
typedef std::map<ZonePair, ZoneConnectivity, Less_ZonePair> ZoneConnMap;
/*--------------------------------------------------------------------*
* Boundaries at the domain extent
*--------------------------------------------------------------------*/
struct VertexBoundary
{
int zoneIndex;
int bcPatchIndex;
SVector3 normal;
MVertex *vertex;
int vertexIndex;
// Constructors
VertexBoundary()
: vertex(0), vertexIndex(0)
{ }
VertexBoundary(const int _zoneIndex, const int _bcPatchIndex,
const SVector3 &_normal, MVertex *const _vertex,
const int _vertexIndex)
: zoneIndex(_zoneIndex), bcPatchIndex(_bcPatchIndex), normal(_normal),
vertex(_vertex), vertexIndex(_vertexIndex)
{ }
};
typedef std::vector<VertexBoundary> ZoneBoVec;
//--Function object for sorting the ZoneBoVec vector by zone and then BC patch
//--index
struct ZoneBoVecSort
{
bool operator()(const int i0, const int i1)
{
if(zoneBoVec[i0].zoneIndex == zoneBoVec[i1].zoneIndex)
return zoneBoVec[i0].bcPatchIndex < zoneBoVec[i1].bcPatchIndex;
return zoneBoVec[i0].zoneIndex < zoneBoVec[i1].zoneIndex;
}
ZoneBoVecSort(const ZoneBoVec &_zoneBoVec)
: zoneBoVec(_zoneBoVec)
{ }
private:
const ZoneBoVec &zoneBoVec;
};
/*******************************************************************************
*
* class: MZoneBoundary
*
* Purpose
* =======
*
* Determines the connectivity between zones (internal boundaries) and
* vertices/elements at the extent of the domain (external boundaries)
*
* Template parameters:
* DIM - dimension of the problem
*
* Notes
* =====
*
* - explicitly instantiated in 'MZoneBoundary.cpp'
* - this class uses some explicit memory management. Call preInit() before
* constructing any class MZoneBoundary and postDestroy() after all
* MZoneBoundary classes have been destroyed.
*
******************************************************************************/
template <unsigned DIM>
class MZoneBoundary
{
/*==============================================================================
* Internal types
*============================================================================*/
private:
//--Type of face (MEdge or MFace)
typedef typename DimTr<DIM>::FaceT FaceT;
//--Data stored for connectivity of vertices
template<typename FaceT>
struct GlobalVertexData
{
struct FaceDataB
{
FaceT face;
MElement *parentElement;
int parentFace;
int faceIndex;
int zoneIndex;
FaceDataB(const int _zoneIndex,
const typename MZone<DIM>::BoFaceMap::const_iterator bFMapIt)
: face(bFMapIt->first), parentElement(bFMapIt->second.parentElement),
parentFace(bFMapIt->second.parentFace),
faceIndex(bFMapIt->second.faceIndex), zoneIndex(_zoneIndex)
{ }
// private: // Default constructor should be private ... but currently
// fails on some compilers (earlier versions of g++?)
// The default constructor is required by 'set_offsets()' in
// class 'FaceAllocator'. This is invoked by preInit() below.
FaceDataB();
friend class CCon::FaceAllocator<FaceDataB>;
};
struct ZoneData
{
int vertexIndex;
int zoneIndex;
ZoneData(const int _vertexIndex, const int _zoneIndex)
: vertexIndex(_vertexIndex), zoneIndex(_zoneIndex)
{ }
// private: // Default constructor should be private ... but currently
// fails on some compilers (earlier versions of g++?)
// The default constructor is required by 'set_offsets()' in
// class 'FaceAllocator'. This is invoked by preInit() below.
ZoneData() { };
friend class CCon::FaceAllocator<ZoneData>;
};
CCon::FaceVector<FaceDataB> faces;
CCon::FaceVector<ZoneData> zoneData;
// A 'FaceVector' is not strictly
// optimized for the vertices but should
// still work quite well.
// Constructor
GlobalVertexData() { }
};
typedef std::map<const MVertex*, GlobalVertexData<FaceT>,
std::less<const MVertex*> > GlobalBoVertexMap;
/*==============================================================================
* Member functions
*============================================================================*/
public:
//--Reset the database
void clear()
{
globalBoVertMap.clear();
}
//--Add a zone to the global map of boundary vertices and return connectivity
//--between zones.
int interiorBoundaryVertices(const int newZoneIndex, const MZone<DIM> &mZone,
ZoneConnMap &zoneConnMap);
//--Return exterior boundary vertices (unconnected vertices at the extent of the
//--domain
int exteriorBoundaryVertices(ZoneBoVec &zoneBoVec);
//--Memory management
static void preInit()
{
CCon::FaceVector<typename GlobalVertexData<FaceT>::FaceDataB>
::init_memory();
CCon::FaceVector<typename GlobalVertexData<FaceT>::ZoneData>::init_memory();
}
static void postDestroy()
{
CCon::FaceVector<typename GlobalVertexData<FaceT>::FaceDataB>
::release_memory();
CCon::FaceVector<typename GlobalVertexData<FaceT>::ZoneData>
::release_memory();
}
/*==============================================================================
* Member data
*============================================================================*/
private:
//--Data members
GlobalBoVertexMap globalBoVertMap; // Map of unconnected boundary vertices
// for the entire domain
};
#endif