Commit b73dc746 by Kirill Terekhov

Huge update

Huge update involving update of underlying data representation and
elements management. Different interaction with iterators. New
ElementSet representation.  Some annotation for documentation is added.
New data structures. Examples require update. (check
examples/CMakeLists.txt)
parent b214f48f
......@@ -20,7 +20,9 @@ set(SOURCE solver.cpp
element.cpp
mesh_parallel.cpp
modify.cpp
autodiff.cpp)
earray.cpp
comparator.cpp
autodiff.cpp)
set(HEADER inmost.h
inmost_options_cmake.h
inmost_common.h
......
......@@ -35,7 +35,7 @@ namespace INMOST
hi = (char *) base + width * (num - 1);
recurse:
size = (hi - lo) / width + 1;
size = static_cast<unsigned>((hi - lo) / width) + 1;
if (size <= CUTOFF)
{
......
#include "inmost_mesh.h"
#if defined(USE_MESH)
namespace INMOST
{
int Mesh::CentroidComparator::Compare(const real * a, const real * b)
{
real e = m->GetEpsilon();
for(integer i = 0; i < m->GetDimensions(); i++)
if( fabs(a[i]-b[i]) > e )
{
if( a[i] < b[i] )
return -1;
else
return 1;
}
return 0;
}
bool Mesh::CentroidComparator::operator () (HandleType a, HandleType b)
{
if( a == InvalidHandle() || b == InvalidHandle() ) return a > b;
real ca[3] = {0,0,0}, cb[3] = {0,0,0};
m->GetGeometricData(a,CENTROID,ca);
m->GetGeometricData(b,CENTROID,ca);
return Compare(ca,cb) <= 0;
}
bool Mesh::CentroidComparator::operator () (HandleType a, const real * cb)
{
if( a == InvalidHandle() ) return true;
real ca[3] = {0,0,0};
m->GetGeometricData(a,CENTROID,ca);
return Compare(ca,cb) <= 0;
}
int Mesh::IerarhyComparator::CompareNodes(HandleType a, HandleType b)
{
real_array ca = m->RealArrayDF(a,m->CoordsTag());
real_array cb = m->RealArrayDF(b,m->CoordsTag());
real e = m->GetEpsilon();
for(integer i = 0; i < m->GetDimensions(); ++i)
if( fabs(ca[i]-cb[i]) > e )
{
if( ca[i] > cb[i] )
return 1;
else
return -1;
}
return 0;
}
int Mesh::IerarhyComparator::CompareElements(HandleType a, HandleType b)
{
integer ia = GetHandleElementNum(a);
integer ib = GetHandleElementNum(b);
if( ia == ib )
{
if( ia == 0 ) return CompareNodes(a,b);
Element::adj_type const & adja = m->LowConn(a);
Element::adj_type const & adjb = m->LowConn(b);
if( adja.size() == adjb.size() )
{
for(Element::adj_type::size_type k = 0; k < adja.size(); ++k)
{
int ret = CompareElements(adja[k],adjb[k]);
if( ret != 0 ) return ret;
}
return 0;
}
else return static_cast<int>(adja.size()) - static_cast<int>(adjb.size());
}
else return ia - ib;
}
void Mesh::SortByGlobalID(HandleType * h, enumerator n)
{
if( sizeof(integer) == 4 && n > 64 )
{
Element::adj_type::size_type i, num = static_cast<Element::adj_type::size_type>(n);
array<HandleType> tmp(num);
HandleType * ptra = h;
HandleType * ptrb = tmp.data();
const unsigned int kHist = 256;
unsigned int b0[kHist * 4];
unsigned int *b1 = b0 + kHist;
unsigned int *b2 = b0 + kHist*2;
unsigned int *b3 = b0 + kHist*3;
memset(b0,0,sizeof(unsigned int)*kHist*4);
for (i = 0; i < num; i++)
{
unsigned char * rec = reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]));
++b0[rec[0]];
++b1[rec[1]];
++b2[rec[2]];
++b3[rec[3]];
}
unsigned int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, tsum;
for (i = 0; i < kHist; i++)
{
tsum = b0[i] + sum0; b0[i] = sum0 - 1; sum0 = tsum;
tsum = b1[i] + sum1; b1[i] = sum1 - 1; sum1 = tsum;
tsum = b2[i] + sum2; b2[i] = sum2 - 1; sum2 = tsum;
tsum = b3[i] + sum3; b3[i] = sum3 - 1; sum3 = tsum;
}
for (i = 0; i < num; i++) ptrb[++b0[reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]))[0]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b1[reinterpret_cast<unsigned char *>(&GlobalID(ptrb[i]))[1]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b2[reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]))[2]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b3[reinterpret_cast<unsigned char *>(&GlobalID(ptrb[i]))[3]]] = ptrb[i];
}
else if( sizeof(integer) == 8 && n > 128 )
{
Element::adj_type::size_type i, num = static_cast<Element::adj_type::size_type>(n);
array<HandleType> tmp(num);
HandleType * ptra = h;
HandleType * ptrb = tmp.data();
const unsigned int kHist = 256;
unsigned int b0[kHist * 8];
unsigned int *b1 = b0 + kHist;
unsigned int *b2 = b0 + kHist*2;
unsigned int *b3 = b0 + kHist*3;
unsigned int *b4 = b0 + kHist*4;
unsigned int *b5 = b0 + kHist*5;
unsigned int *b6 = b0 + kHist*6;
unsigned int *b7 = b0 + kHist*7;
memset(b0,0,sizeof(unsigned int)*kHist*8);
for (i = 0; i < num; i++)
{
unsigned char * rec = reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]));
++b0[rec[0]];
++b1[rec[1]];
++b2[rec[2]];
++b3[rec[3]];
++b4[rec[4]];
++b5[rec[5]];
++b6[rec[6]];
++b7[rec[7]];
}
unsigned int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, tsum;
unsigned int sum4 = 0, sum5 = 0, sum6 = 0, sum7 = 0;
for (i = 0; i < kHist; i++)
{
tsum = b0[i] + sum0; b0[i] = sum0 - 1; sum0 = tsum;
tsum = b1[i] + sum1; b1[i] = sum1 - 1; sum1 = tsum;
tsum = b2[i] + sum2; b2[i] = sum2 - 1; sum2 = tsum;
tsum = b3[i] + sum3; b3[i] = sum3 - 1; sum3 = tsum;
tsum = b4[i] + sum4; b4[i] = sum4 - 1; sum4 = tsum;
tsum = b5[i] + sum5; b5[i] = sum5 - 1; sum5 = tsum;
tsum = b6[i] + sum6; b6[i] = sum6 - 1; sum6 = tsum;
tsum = b7[i] + sum7; b7[i] = sum7 - 1; sum7 = tsum;
}
for (i = 0; i < num; i++) ptrb[++b0[reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]))[0]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b1[reinterpret_cast<unsigned char *>(&GlobalID(ptrb[i]))[1]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b2[reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]))[2]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b3[reinterpret_cast<unsigned char *>(&GlobalID(ptrb[i]))[3]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b4[reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]))[4]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b5[reinterpret_cast<unsigned char *>(&GlobalID(ptrb[i]))[5]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b6[reinterpret_cast<unsigned char *>(&GlobalID(ptra[i]))[6]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b7[reinterpret_cast<unsigned char *>(&GlobalID(ptrb[i]))[7]]] = ptrb[i];
}
else std::sort(h,h+n,Mesh::GlobalIDComparator(this));
}
void Mesh::SortHandles(HandleType * h, enumerator n)
{
if( sizeof(HandleType) == 4 && n > 32 )
{
Element::adj_type::size_type i, num = static_cast<Element::adj_type::size_type>(n);
array<HandleType> tmp(num);
HandleType * ptra = h;
HandleType * ptrb = tmp.data();
//make so that invalid handles appear at he end
for (i = 0; i < num; i++) if( ptra[i] == InvalidHandle() ) ptra[i] = ENUMUNDEF;
const unsigned int kHist = 256;
unsigned int b0[kHist * 4];
unsigned int *b1 = b0 + kHist;
unsigned int *b2 = b0 + kHist*2;
unsigned int *b3 = b0 + kHist*3;
unsigned char * l1 = reinterpret_cast<unsigned char *>(ptra);
unsigned char * l2 = reinterpret_cast<unsigned char *>(ptrb);
memset(b0,0,sizeof(unsigned int)*kHist*4);
for (i = 0; i < num; i++)
{
++b0[l1[4*i+0]];
++b1[l1[4*i+1]];
++b2[l1[4*i+2]];
++b3[l1[4*i+3]];
}
unsigned int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, tsum;
for (i = 0; i < kHist; i++)
{
tsum = b0[i] + sum0; b0[i] = sum0 - 1; sum0 = tsum;
tsum = b1[i] + sum1; b1[i] = sum1 - 1; sum1 = tsum;
tsum = b2[i] + sum2; b2[i] = sum2 - 1; sum2 = tsum;
tsum = b3[i] + sum3; b3[i] = sum3 - 1; sum3 = tsum;
}
for (i = 0; i < num; i++) ptrb[++b0[l1[4*i+0]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b1[l2[4*i+1]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b2[l1[4*i+2]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b3[l2[4*i+3]]] = ptrb[i];
for (i = 0; i < num; i++) if( ptra[i] == ENUMUNDEF ) ptra[i] = InvalidHandle();
}
else if( sizeof(HandleType) == 8 && n > 64 )
{
Element::adj_type::size_type i, num = static_cast<Element::adj_type::size_type>(n);
array<HandleType> tmp(num);
HandleType * ptra = h;
HandleType * ptrb = tmp.data();
//make so that invalid handles appear at he end
for (i = 0; i < num; i++) if( ptra[i] == InvalidHandle() ) ptra[i] = ENUMUNDEF;
const unsigned int kHist = 256;
unsigned int b0[kHist * 8];
unsigned int *b1 = b0 + kHist;
unsigned int *b2 = b0 + kHist*2;
unsigned int *b3 = b0 + kHist*3;
unsigned int *b4 = b0 + kHist*4;
unsigned int *b5 = b0 + kHist*5;
unsigned int *b6 = b0 + kHist*6;
unsigned int *b7 = b0 + kHist*7;
unsigned char * l1 = reinterpret_cast<unsigned char *>(ptra);
unsigned char * l2 = reinterpret_cast<unsigned char *>(ptrb);
memset(b0,0,sizeof(unsigned int)*kHist*8);
for (i = 0; i < num; i++)
{
++b0[l1[8*i+0]];
++b1[l1[8*i+1]];
++b2[l1[8*i+2]];
++b3[l1[8*i+3]];
++b4[l1[8*i+4]];
++b5[l1[8*i+5]];
++b6[l1[8*i+6]];
++b7[l1[8*i+7]];
}
unsigned int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, tsum;
unsigned int sum4 = 0, sum5 = 0, sum6 = 0, sum7 = 0;
for (i = 0; i < kHist; i++)
{
tsum = b0[i] + sum0; b0[i] = sum0 - 1; sum0 = tsum;
tsum = b1[i] + sum1; b1[i] = sum1 - 1; sum1 = tsum;
tsum = b2[i] + sum2; b2[i] = sum2 - 1; sum2 = tsum;
tsum = b3[i] + sum3; b3[i] = sum3 - 1; sum3 = tsum;
tsum = b4[i] + sum4; b4[i] = sum4 - 1; sum4 = tsum;
tsum = b5[i] + sum5; b5[i] = sum5 - 1; sum5 = tsum;
tsum = b6[i] + sum6; b6[i] = sum6 - 1; sum6 = tsum;
tsum = b7[i] + sum7; b7[i] = sum7 - 1; sum7 = tsum;
}
for (i = 0; i < num; i++) ptrb[++b0[l1[8*i+0]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b1[l2[8*i+1]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b2[l1[8*i+2]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b3[l2[8*i+3]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b4[l1[8*i+4]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b5[l2[8*i+5]]] = ptrb[i];
for (i = 0; i < num; i++) ptrb[++b6[l1[8*i+6]]] = ptra[i];
for (i = 0; i < num; i++) ptra[++b7[l2[8*i+7]]] = ptrb[i];
for (i = 0; i < num; i++) if( ptra[i] == ENUMUNDEF ) ptra[i] = InvalidHandle();
}
else std::sort(h,h+n);
}
}
#endif
\ No newline at end of file
#include "inmost_mesh.h"
#if defined(USE_MESH)
namespace INMOST
{
template<typename StorageType>
void ElementArray<StorageType>::Unite(const HandleType * h, INMOST_DATA_ENUM_TYPE num)
{
assert(GetMeshLink() == other.GetMeshLink());
if( empty() ) container.insert(container.end(),h,h+num);
else
{
Mesh * m = GetMeshLink();
size_type s = size();
MarkerType mrk = m->CreateMarker();
SetMarker(mrk);
for(INMOST_DATA_ENUM_TYPE it = 0; it < num; it++)
if( !m->GetMarker(h[it],mrk) )
{
container.push_back(h[it]);
m->SetMarker(h[it],mrk);
}
RemMarker(mrk);
m->ReleaseMarker(mrk);
}
}
template<typename StorageType>
void ElementArray<StorageType>::Subtract(const HandleType * h, INMOST_DATA_ENUM_TYPE num)
{
assert(GetMeshLink() == other.GetMeshLink());
if( !empty() )
{
Mesh * mesh = GetMeshLink();
MarkerType mrk = mesh->CreateMarker();
//other.SetMarker(mrk);
mesh->SetMarkerArray(h,num,mrk);
{
size_type m = 0, n = 0;
while( m < size() )
{
if( !mesh->GetMarker(container[m],mrk) )
container[n++] = container[m];
m++;
}
container.resize(n);
}
//other.RemMarker(mrk);
mesh->RemMarkerArray(h,num,mrk);
mesh->ReleaseMarker(mrk);
}
}
template <typename StorageType>
void ElementArray<StorageType>::Intersect(const HandleType * h, INMOST_DATA_ENUM_TYPE num)
{
if( !empty() )
{
Mesh * mesh = GetMeshLink();
MarkerType mrk = mesh->CreateMarker();
//other.SetMarker(mrk);
mesh->SetMarkerArray(h,num,mrk);
{
size_type m = 0, n = 0;
while( m < size() )
{
if( mesh->GetMarker(container[m],mrk) )
container[n++] = container[m];
m++;
}
container.resize(n);
}
//other.RemMarker(mrk);
mesh->RemMarkerArray(h,num,mrk);
mesh->ReleaseMarker(mrk);
}
}
template <typename StorageType>
void ElementArray<StorageType>::SetMarker(MarkerType m) const
{
Mesh * mesh = GetMeshLink();
for(size_type it = 0; it < size(); it++) mesh->SetMarker(container[it],m);
}
template <typename StorageType>
void ElementArray<StorageType>::RemMarker(MarkerType m) const
{
Mesh * mesh = GetMeshLink();
for(size_type it = 0; it < size(); it++) mesh->RemMarker(container[it],m);
}
//all possible templates
template class ElementArray<Element>;
template class ElementArray<Node>;
template class ElementArray<Edge>;
template class ElementArray<Face>;
template class ElementArray<Cell>;
template class ElementArray<Storage>;
}
#endif
\ No newline at end of file
add_subdirectory(DrawGrid)
#add_subdirectory(DrawGrid)
add_subdirectory(OldDrawGrid)
add_subdirectory(DrawMatrix)
add_subdirectory(MatSolve)
add_subdirectory(GridGen)
add_subdirectory(FVDiscr)
add_subdirectory(OctreeCutcell)
add_subdirectory(Solver)
#add_subdirectory(DrawMatrix)
#add_subdirectory(MatSolve)
#add_subdirectory(GridGen)
#add_subdirectory(FVDiscr)
#add_subdirectory(OctreeCutcell)
#add_subdirectory(Solver)
......@@ -20,6 +20,7 @@ Mesh * ParallelCubeGenerator(INMOST_MPI_Comm comm, int nx, int ny, int nz)
m->SetCommunicator(comm); // Set the MPI communicator, usually MPI_COMM_WORLD
#if defined(USE_MPI)
MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);
//MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS);
#endif
......@@ -125,6 +126,7 @@ Mesh * ParallelCubePrismGenerator(INMOST_MPI_Comm comm, int nx, int ny, int nz)
m->SetCommunicator(comm); // Set the MPI communicator, usually MPI_COMM_WORLD
#if defined(USE_MPI)
MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);
//MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS);
#endif
......
......@@ -19,7 +19,7 @@
//#define USE_SOLVER_ANI
#define USE_AUTODIFF
#define USE_AUTODIFF_ASMJIT
//#define USE_AUTODIFF_ASMJIT
//#define USE_AUTODIFF_OPENCL
//#define USE_AUTODIFF_EXPRESSION_TEMPLATES
......@@ -28,17 +28,22 @@
#endif //INMOST_OPTIONS_CMAKE_INCLUDED
#define USE_QSORT //use qsort instead of std::sort
// a very expensive check for debug purposes,
// when you release marker checks all the elements
// that no element is marked by released marker
//#define CHECKS_MARKERS
// use additional sets to store elements for parallel
// exchanges, otherwise it will recompute those elements
// which is quite expensive
#define USE_PARALLEL_STORAGE
// output xml files for debugging of parallel algorithms
// search for style.xsl within examples for comfortable
// view of generated xml files
#define USE_PARALLEL_WRITE_TIME
#define USE_COMPARE CompareElementsPointer
//#define USE_COMPARE CompareElementsCentroid
//#define USE_COMPARE CompareElementsUnique
//#define USE_COMPARE CompareElementsHybrid
// this will revert Mesh::PrepareReceiveInner to always
// use MPI-2 functionality disregarding problem type
// read comments in Mesh::SetParallelStrategy for more info
//#define PREFFER_MPI2
#define __INLINE inline
......@@ -88,7 +93,8 @@
#define INMOST_MPI_Win MPI_Win
#endif
#define INMOST_MPI_SIZE int //in case MPI standard changes and compiler gives tons of warning
#define INMOST_DATA_INTEGER_TYPE int
#define INMOST_DATA_REAL_TYPE double
#define INMOST_DATA_BULK_TYPE unsigned char //this should be one byte long
......@@ -111,8 +117,9 @@
/// Cross-platform timer that return current time in seconds.
/// The timer is similar to MPI_Wtime() and omp_get_wtime() but is independent on both flags USE_MPI and USE_OMP.
///
/// double seconds = Timer(); @n
/// ...some code... @n
/// double seconds = Timer();
/// ...some code...
/// seconds = Timer() - seconds;
/// std::cout << "Time spent is " << seconds << " seconds." << std::endl;
long double Timer();
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -263,7 +263,7 @@ namespace INMOST
//return data[i];
//for dynarray or array
for(unsigned it = 0; it < data.size(); ++it)
for(Entries::size_type it = 0; it < data.size(); ++it)
if( data[it].first == i ) return data[it].second;
entry new_entry;
new_entry.first = i;
......@@ -279,7 +279,7 @@ namespace INMOST
//for sparse data type
//return data[i];
for (unsigned it = 0; it < data.size(); ++it) if (data[it].first == i) return data[it].second;
for (Entries::size_type it = 0; it < data.size(); ++it) if (data[it].first == i) return data[it].second;
//you should not come here
assert(false);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,179 +3,170 @@
namespace INMOST
{
Node::Node(Mesh * m) :Element(m,NODE)
{
}
Node::Node(Mesh * m, INMOST_DATA_ENUM_TYPE lid, const Node & other) :Element(m,lid,other){}
Node::Node(const Node & other) :Element(other){}
Node & Node::operator =(Node const & other)
{
Element::operator =(other);
return *this;
}
Node::~Node()
ElementArray<Edge> Node::getEdges() const
{
}
adjacent<Edge> Node::getEdges()
{
if( !GetMeshLink()->HideMarker() )
assert(GetHandleElementType(GetHandle())==NODE);
Mesh * m = GetMeshLink();
if( !m->HideMarker() )
{
adj_type const & hc = HighConn();
return adjacent<Edge>(hc.data(),hc.data()+hc.size());
adj_type const & hc = m->HighConn(GetHandle());
return ElementArray<Edge>(m,hc.data(),hc.data()+hc.size());
}
else
{
MarkerType hm = GetMeshLink()->HideMarker();
adjacent<Edge> aret;
adj_type const & hc = HighConn();
for(adj_type::enumerator it = 0; it < hc.size(); ++it)
if( !hc[it]->GetMarker(hm) ) aret.push_back(hc[it]);
MarkerType hm = m->HideMarker();
ElementArray<Edge> aret(m);
adj_type const & hc = m->HighConn(GetHandle());
for(adj_type::size_type it = 0; it < hc.size(); ++it)
if( !m->GetMarker(hc[it],hm) ) aret.push_back(hc[it]);
return aret;
}
}
adjacent<Edge> Node::getEdges(MarkerType mask, bool invert)
ElementArray<Edge> Node::getEdges(MarkerType mask, bool invert) const
{
adjacent<Edge> aret;
if( !GetMeshLink()->HideMarker() )
assert(GetHandleElementType(GetHandle())==NODE);
Mesh * m = GetMeshLink();
ElementArray<Edge> aret(m);
if( !m->HideMarker() )
{
adj_type const & hc = HighConn();
for(adj_type::enumerator it = 0; it < hc.size(); ++it)
if( invert ^ hc[it]->GetMarker(mask) ) aret.push_back(hc[it]);
adj_type const & hc = m->HighConn(GetHandle());
for(adj_type::size_type it = 0; it < hc.size(); ++it)
if( invert ^ m->GetMarker(hc[it],mask) ) aret.push_back(hc[it]);
}
else
{
MarkerType hm = GetMeshLink()->HideMarker();
adj_type const & hc = HighConn();
for(adj_type::enumerator it = 0; it < hc.size(); ++it)
if( (invert ^ hc[it]->GetMarker(mask)) && !hc[it]->GetMarker(hm) ) aret.push_back(hc[it]);
MarkerType hm = m->HideMarker();
adj_type const & hc = m->HighConn(GetHandle());
for(adj_type::size_type it = 0; it < hc.size(); ++it)
if( (invert ^ m->GetMarker(hc[it],mask)) && !m->GetMarker(hc[it],hm) ) aret.push_back(hc[it]);
}
return aret;
}
adjacent<Face> Node::getFaces()
ElementArray<Face> Node::getFaces() const
{
adjacent<Face> aret;
assert(GetHandleElementType(GetHandle())==NODE);
Mesh * m = GetMeshLink();
ElementArray<Face> aret(m);
MarkerType mrk = m->CreateMarker();
if( !GetMeshLink()->HideMarker() )
if( !m->HideMarker() )
{
adj_type const & hc = HighConn();
for(adj_type::enumerator it = 0; it < hc.size(); it++) //edges
adj_type const & hc = m->HighConn(GetHandle());
for(adj_type::size_type it = 0; it < hc.size(); it++) //edges
{
adj_type const & ihc = hc[it]->HighConn();
for(adj_type::enumerator jt = 0; jt < ihc.size(); jt++) //faces
if( !ihc[jt]->GetMarker(mrk))
adj_type const & ihc = m->HighConn(hc[it]);
for(adj_type::size_type jt = 0; jt < ihc.size(); jt++) //faces
if( !m->GetMarker(ihc[jt],mrk))
{
aret.push_back(ihc[jt]);
ihc[jt]->SetMarker(mrk);
m->SetMarker(ihc[jt],mrk);
}
}
}
else
{
MarkerType hm = GetMeshLink()->HideMarker();
adj_type const & hc = HighConn();
for(adj_type::enumerator it = 0; it < hc.size(); it++) if( !hc[it]->GetMarker(hm) )//edges
MarkerType hm = m->HideMarker();
adj_type const & hc = m->HighConn(GetHandle());
for(adj_type::size_type it = 0; it < hc.size(); it++) if( !m->GetMarker(hc[it],hm) )//edges
{
adj_type const & ihc = hc[it]->HighConn();
for(adj_type::enumerator jt = 0; jt < ihc.size(); jt++) if( !ihc[jt]->GetMarker(hm) ) //faces
if( !ihc[jt]->GetMarker(mrk))
adj_type const & ihc = m->HighConn(hc[it]);
for(adj_type::size_type jt = 0; jt < ihc.size(); jt++) if( !m->GetMarker(ihc[jt],hm) ) //faces
if( !m->GetMarker(ihc[jt],mrk))
{
aret.push_back(ihc[jt]);
ihc[jt]->SetMarker(mrk);
m->SetMarker(ihc[jt],mrk);
}
}
}
for(adjacent<Face>::enumerator it = 0; it < aret.size(); it++) aret[it].RemMarker(mrk);
for(ElementArray<Face>::size_type it = 0; it < aret.size(); it++) m->RemMarker(aret.at(it),mrk);
m->ReleaseMarker(mrk);
return aret;
}
adjacent<Face> Node::getFaces(MarkerType mask, bool invert)
ElementArray<Face> Node::getFaces(MarkerType mask, bool invert) const
{
adjacent<Face> aret;
assert(GetHandleElementType(GetHandle())==NODE);
Mesh * m = GetMeshLink();
ElementArray<Face> aret(m);
MarkerType mrk = m->CreateMarker();
if( !GetMeshLink()->HideMarker() )
if( !m->HideMarker() )
{
adj_type const & hc = HighConn();