Commit 199f5aaa authored by Kirill Terekhov's avatar Kirill Terekhov

Fixes and lib for general adaptive mesh

Fixes for mesh modification algorithms

A lib for general adaptive mesh
parent d02be56a
#include "agrid.h"
#include <math.h>
Storage::integer min_nonzero(Storage::integer a, Storage::integer b)
{
Storage::integer get_max = std::max(a,b);
Storage::integer get_min = std::min(a,b);
if( get_min == 0 ) return get_max; else return get_min;
}
void AdaptiveGrid
void AdaptiveGrid::Refine(const TagInteger & indicator)
{
int schedule_counter = 1;
bool scheduled = true;
//0. Extend indicator for edges and faces
indicator = CreateTag(indicator.GetTagName(),DATA_INTEGER,FACE|EDGE,NONE,1);
while(scheduled)
{
//1.Communicate indicator - it may be not synced
ExchangeTag(indicator,0,CELL);
//2.Propogate indicator down to the faces,edges
// select latest schedule for them
//
//possible problem - a cell needs all it's elements to be splitted in the same schedule
//so the cell must mark all it's elements without hanging nodes into the same schedule,
//unless there is an even earlier cell
//
//should we select earliest possible for elements without hanging nodes and
//latest possible for elements with hanging nodes?
//
//with loop over cells we would mark elements without hanging nodes of the cells
//in current schedule
for(ElementType etype = FACE; etype >= EDGE; etype = PrevElementType(etype))
{
#if defined(USE_OMP)
#pragma omp parallel for
#endif
for(Storage::integer it = 0; it < LastLocalID(etype); ++it) if( isValidElement(etype,it) )
{
Element e = ElementByLocalID(etype,it);
ElementArray<Element> adj = f.getAdjElements(NextElementType(etype));
//here latest schedule is selected
if( e->nbAdjElements(NODE,hanging_node,0) > 0 ) //latest possible schedule
{
for(ElementArray<Element>::size_type kt = 0; kt < adj.size(); ++kt)
if( indicator[adj[kt]] )
indicator[f] = indicator[f] ? std::min(indicator[f],indicator[adj[kt]]) : indicator[adj[kt]];
}
else //earliest possible schedule
{
for(ElementArray<Element>::size_type kt = 0; kt < adj.size(); ++kt)
indicator[f] = std::max(indicator[f],indicator[adj[kt]]);
}
}
}
//3.Communicate indicator on faces and edges
ExchangeTag(indicator,0,FACE|EDGE);
//4.Check for each cell without indicator if there is
// any hanging node with adjacent in a need to refine,
// schedule for refinement earlier.
scheduled = false;
#if defined(USE_OMP)
#pragma omp parallel for
#endif
for(Storage::integer it = 0; it < CellLastLocalID(); ++it) if( isValidCell(it) )
{
Cell c = CellByLocalID(it);
if( indicator[c] == 0 )
{
bool scheduled_c = false;
//retrive only hanging nodes, this may be empty
ElementArray<Node> hanging = c->getNodes(hanging_node,0);
for(ElementArray<Node>::size_type kt = 0; kt < hanging.size() && !scheduled_c; ++kt)
{
//adjacent edges may be scheduled for refinement
ElementArray<Edge> adj = hanging[kt].getEdges();
for(ElementArray<Edge>::size_type lt = 0; lt < adj.size() && !scheduled_c; ++lt)
if( indicator[adj[lt]] != 0 )
{
indicator[c] = schedulde_counter+1;
scheduled = scheduled_c = true;
}
}
}
}
//5.Go back to 1 until no new elements scheduled
if( scheduled ) schedulde_counter++;
}
//5.Refine
BeginModification();
while(scheduled_counter)
{
scheduled_counter--;
}
ResolveModification();
//Let the user update their data
ApplyModification();
EndModification();
}
void AdaptiveGrid::Coarse(const TagInteger & indicator)
{
}
#ifndef _AGRID_H
#define _AGRID_H
#include "inmost.h"
class AdaptiveMesh : public Mesh
{
MarkerType hanging_node;
void SplitFace();
public:
AdaptiveMesh() : Mesh() {}
~AdaptiveMesh() {}
/// Indicator must be 1 on cells to be refined
/// and 0 on all other cells
void Refine(const TagInteger & indicator);
void Coarse(const TagInteger & indicator);
};
#endif //_AGRID_H
project(AdaptiveMesh)
set(LIBSOURCE amesh.cpp amesh.h)
set(SOURCE main.cpp)
add_library(AdaptiveMeshLib ${LIBSOURCE})
add_executable(AdaptiveMesh ${SOURCE})
target_link_libraries(AdaptiveMesh inmost AdaptiveMeshLib)
if(USE_MPI)
message("linking AdaptiveMesh with MPI")
target_link_libraries(AdaptiveMesh ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(AdaptiveMesh PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
set_property(TARGET AdaptiveMeshLib PROPERTY PUBLIC_HEADER "${PROJECT_BINARY_DIR}/Examples/AdaptiveMesh/amesh.h")
install(TARGETS AdaptiveMeshLib EXPORT inmost-targets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include)
install(TARGETS AdaptiveMesh EXPORT inmost-targets RUNTIME DESTINATION bin)
\ No newline at end of file
This diff is collapsed.
#ifndef _AMESH_H
#define _AMESH_H
#include "inmost.h"
namespace INMOST
{
class AdaptiveMesh : public Mesh
{
ElementSet root; //< Root set that links all the other sets for coarsements
TagInteger level; //< Refinement level of the cell
TagReference parent_set; //<Link to the set that contains an element.
TagReferenceArray hanging_nodes; //< Link to current hanging nodes of the cell.
/// Prepare sets for coarsements.
/// Do not do this in constructor, since mesh may contain no cells.
void PrepareSet();
public:
Storage::integer GetLevel(const Storage & e) {return level[e];}
AdaptiveMesh();
~AdaptiveMesh();
/// Indicator must be 1 on cells to be refined
/// and 0 on all other cells
bool Refine(TagInteger & indicator);
bool Coarse(TagInteger & indicator);
/// Delete all data related to mesh refinement-coarsement.
void ClearData();
};
}
#endif //_AMESH_H
#include "amesh.h"
using namespace INMOST;
int main(int argc, char ** argv)
{
Mesh::Initialize(&argc,&argv);
if( argc > 1 )
{
AdaptiveMesh m;
m.Load(argv[1]);
//m.SetTopologyCheck(NEED_TEST_CLOSURE);
//m.SetTopologyCheck(PROHIBIT_MULTILINE);
//m.SetTopologyCheck(PROHIBIT_MULTIPOLYGON);
TagInteger indicator = m.CreateTag("INDICATOR",DATA_INTEGER,CELL,NONE,1);
int max_levels = 2;
if( argc > 2 ) max_levels = atoi(argv[2]);
//bounding box around mesh
Storage::real cmax[3] = {-1.0e20,-1.0e20,-1.0e20};
Storage::real cmin[3] = {+1.0e20,+1.0e20,+1.0e20};
Storage::real xyz[3], r, q, cnt[3];
//find bounding box around mesh
for(Mesh::iteratorNode it = m.BeginNode(); it != m.EndNode(); ++it)
{
for(int d = 0; d < 3; ++d)
{
if( it->Coords()[d] > cmax[d] ) cmax[d] = it->Coords()[d];
if( it->Coords()[d] < cmin[d] ) cmin[d] = it->Coords()[d];
}
}
r = 1;
for(int d = 0; d < 3; ++d)
{
r *= cmax[d]-cmin[d];
cnt[d] = (cmax[d]+cmin[d])*0.5;
}
r = pow(r,1.0/3.0)/20.0;
for(int k = 0; k < 16; ++k)
{
int numref;
int refcnt = 0;
do
{
numref = 0;
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it) if( m.GetLevel(it->self()) < max_levels )
{
it->Centroid(xyz);
//refine a circle
q = 0;
for(int d = 0; d < 3; ++d)
q += (xyz[d]-cnt[d])*(xyz[d]-cnt[d]);
q = sqrt(q);
if( q < r*(k+1) && q > r*k)
{
indicator[it->self()] = 1;
numref++;
}
}
if( numref )
{
std::cout << "k " << k << " refcnt " << refcnt << " " << r*k << " < r < " << r*(k+1) << " numref " << numref << " cells " << m.NumberOfCells() << std::endl;
/*
{
std::stringstream file;
file << "indicator_" << k << "_" << refcnt << "r.pmf";
m.Save(file.str());
}
*/
if( !m.Refine(indicator) ) break;
{
std::stringstream file;
file << "dump_" << k << "_" << refcnt << "r.pmf";
m.Save(file.str());
}
//cleanup indicator
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it) indicator[it->self()] = 0;
}
refcnt++;
}
while(numref);
refcnt = 0;
do
{
numref = 0;
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it) if( m.GetLevel(it->self()) > 0 )
{
it->Centroid(xyz);
//refine a circle
q = 0;
for(int d = 0; d < 3; ++d)
q += (xyz[d]-cnt[d])*(xyz[d]-cnt[d]);
q = sqrt(q);
if( q < r*k)
{
indicator[it->self()] = 1;
numref++;
}
}
if( numref )
{
std::cout << "k " << k << " crscnt " << refcnt << " " << r*k << " < r < " << r*(k+1) << " numcrs " << numref << " cells " << m.NumberOfCells() << std::endl;
/*
{
std::stringstream file;
file << "indicator_" << k << "_" << refcnt << "c.pmf";
m.Save(file.str());
}
*/
if( !m.Coarse(indicator) ) break;
{
std::stringstream file;
file << "dump_" << k << "_" << refcnt << "c.pmf";
m.Save(file.str());
}
//cleanup indicator
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it) indicator[it->self()] = 0;
}
//return -1;
refcnt++;
}
while(numref);
{
std::stringstream file;
file << "step_" << k << ".vtk";
m.Save(file.str());
}
{
std::stringstream file;
file << "step_" << k << ".pmf";
m.Save(file.str());
}
}
}
else std::cout << "Usage: " << argv[0] << " mesh_file [max_levels=2]" << std::endl;
}
\ No newline at end of file
if(USE_MESH)
add_subdirectory(AdaptiveMesh)
add_subdirectory(DrawGrid)
add_subdirectory(OldDrawGrid)
add_subdirectory(GridGen)
......
......@@ -106,7 +106,7 @@ void printtext(const char * fmt, ... )
{
unsigned int i;
char stext[4096];
char stext[1048576];
va_list ap;
if ( fmt == NULL ) return;
va_start(ap,fmt);
......@@ -4102,13 +4102,14 @@ double display_elem_info(Element e, double top, double left, double interval)
top -= interval;
glRasterPos2f(left,top);
printtext("%s %d",ElementTypeName(e->GetElementType()),e->LocalID());
if( e->GetElementType() == ESET ) printtext(" size %d",e->getAsSet().Size());
glColor3f(0.2,0.2,0.2);
for(Mesh::iteratorTag t = mesh->BeginTag(); t != mesh->EndTag(); ++t) if( t->isDefined(e->GetElementType()) )
{
if( e->HaveData(*t) )
{
char str[4096];
char temp[4096];
char str[1048576];
char temp[1048576];
str[0] = '\0';
int dsize;
switch(t->GetDataType())
......@@ -4475,7 +4476,7 @@ void draw_screen()
for(int k = 0; k < (int)orphans.size(); ++k)
DrawElement(orphans[k],color_t(1,0,1),color_t(0,1,1),color_t(0,0,1));
if( disp_e.isValid() )
if( disp_e.isValid() && disp_e.GetElementType() != ESET)
DrawElement(disp_e,color_t(1,1,0),color_t(1,0,0),color_t(0,0,1));
......@@ -4588,6 +4589,7 @@ void draw_screen()
else if ( stype == "edge" ) visualization_type = EDGE;
else if ( stype == "face" ) visualization_type = FACE;
else if ( stype == "cell" ) visualization_type = CELL;
else if ( stype == "eset" ) visualization_type = ESET;
if( visualization_type == NONE )
printf("unknown element type %s\n",typen);
if( !mesh->isValidElement(visualization_type,comp) )
......@@ -4596,9 +4598,12 @@ void draw_screen()
if( mesh->isValidElement(visualization_type,comp) )
{
disp_e = mesh->ElementByLocalID(visualization_type,comp);
disp_e->Centroid(shift);
for(int r = 0; r < 3; ++r)
shift[r] = -shift[r];
if( disp_e.GetElementType() != ESET )
{
disp_e->Centroid(shift);
for(int r = 0; r < 3; ++r)
shift[r] = -shift[r];
}
}
}
......
......@@ -41,6 +41,9 @@
// a very expensive check for debug purposes,
// when you release marker checks all the elements
// that no element is marked by released marker
// in Mesh::Init function change two variables:
// check_shared_mrk - check shared markers.
// check_private_mrk - check private markers.
//#define CHECKS_MARKERS
// use additional sets to store elements for parallel
......
......@@ -622,7 +622,8 @@ namespace INMOST
TagReal(const Tag & b) : Tag(b) {}
TagReal & operator = (TagReal const & b) {Tag::operator =(b); return *this;}
TagReal & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::real & operator [](const Storage & arg) const {return arg.Real(*static_cast<const Tag*>(this));}
__INLINE Storage::real & operator [](const Storage & arg) const {return arg.Real(*static_cast<const Tag*>(this));}
__INLINE Storage::real & operator [](HandleType h) const;
};
class TagInteger : public Tag
......@@ -633,7 +634,8 @@ namespace INMOST
TagInteger(const Tag & b) : Tag(b) {}
TagInteger & operator = (TagInteger const & b) {Tag::operator =(b); return *this;}
TagInteger & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::integer & operator [](const Storage & arg) const {return arg.Integer(*static_cast<const Tag*>(this));}
__INLINE Storage::integer & operator [](const Storage & arg) const {return arg.Integer(*static_cast<const Tag*>(this));}
__INLINE Storage::integer & operator [](HandleType h) const;
};
class TagBulk : public Tag
......@@ -644,7 +646,8 @@ namespace INMOST
TagBulk(const Tag & b) : Tag(b) {}
TagBulk & operator = (TagBulk const & b) {Tag::operator =(b); return *this;}
TagBulk & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::bulk & operator [](const Storage & arg) const {return arg.Bulk(*static_cast<const Tag*>(this));}
__INLINE Storage::bulk & operator [](const Storage & arg) const {return arg.Bulk(*static_cast<const Tag*>(this));}
__INLINE Storage::bulk & operator [](HandleType h) const;
};
class TagReference : public Tag
......@@ -655,7 +658,8 @@ namespace INMOST
TagReference(const Tag & b) : Tag(b) {}
TagReference & operator = (TagReference const & b) {Tag::operator =(b); return *this;}
TagReference & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::reference & operator [](const Storage & arg) const {return arg.Reference(*static_cast<const Tag*>(this));}
__INLINE Storage::reference & operator [](const Storage & arg) const {return arg.Reference(*static_cast<const Tag*>(this));}
__INLINE Storage::reference & operator [](HandleType h) const;
};
......@@ -667,7 +671,8 @@ namespace INMOST
TagRealArray(const Tag & b) : Tag(b) {}
TagRealArray & operator = (TagRealArray const & b) {Tag::operator =(b); return *this;}
TagRealArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::real_array operator [](const Storage & arg) const {return arg.RealArray(*static_cast<const Tag*>(this));}
__INLINE Storage::real_array operator [](const Storage & arg) const {return arg.RealArray(*static_cast<const Tag*>(this));}
__INLINE Storage::real_array operator [](HandleType h) const;
};
class TagIntegerArray : public Tag
......@@ -678,7 +683,8 @@ namespace INMOST
TagIntegerArray(const Tag & b) : Tag(b) {}
TagIntegerArray & operator = (TagIntegerArray const & b) {Tag::operator =(b); return *this;}
TagIntegerArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::integer_array operator [](const Storage & arg) const {return arg.IntegerArray(*static_cast<const Tag*>(this));}
__INLINE Storage::integer_array operator [](const Storage & arg) const {return arg.IntegerArray(*static_cast<const Tag*>(this));}
__INLINE Storage::integer_array operator [](HandleType h) const;
};
class TagBulkArray : public Tag
......@@ -689,7 +695,8 @@ namespace INMOST
TagBulkArray(const Tag & b) : Tag(b) {}
TagBulkArray & operator = (TagBulkArray const & b) {Tag::operator =(b); return *this;}
TagBulkArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::bulk_array operator [](const Storage & arg) const {return arg.BulkArray(*static_cast<const Tag*>(this));}
__INLINE Storage::bulk_array operator [](const Storage & arg) const {return arg.BulkArray(*static_cast<const Tag*>(this));}
__INLINE Storage::bulk_array operator [](HandleType h) const;
};
class TagReferenceArray : public Tag
......@@ -700,7 +707,8 @@ namespace INMOST
TagReferenceArray(const Tag & b) : Tag(b) {}
TagReferenceArray & operator = (TagReferenceArray const & b) {Tag::operator =(b); return *this;}
TagReferenceArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::reference_array operator [](const Storage & arg) const {return arg.ReferenceArray(*static_cast<const Tag*>(this));}
__INLINE Storage::reference_array operator [](const Storage & arg) const {return arg.ReferenceArray(*static_cast<const Tag*>(this));}
__INLINE Storage::reference_array operator [](HandleType h) const;
};
#if defined(USE_AUTODIFF)
......@@ -712,7 +720,8 @@ namespace INMOST
TagVariable(const Tag & b) : Tag(b) {}
TagVariable & operator = (TagVariable const & b) {Tag::operator =(b); return *this;}
TagVariable & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::var & operator [](const Storage & arg) const {return arg.Variable(*static_cast<const Tag*>(this));}
__INLINE Storage::var & operator [](const Storage & arg) const {return arg.Variable(*static_cast<const Tag*>(this));}
__INLINE Storage::var & operator [](HandleType h) const;
};
class TagVariableArray : public Tag
......@@ -723,7 +732,8 @@ namespace INMOST
TagVariableArray(const Tag & b) : Tag(b) {}
TagVariableArray & operator = (TagVariableArray const & b) {Tag::operator =(b); return *this;}
TagVariableArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
Storage::var_array operator [](const Storage & arg) const {return arg.VariableArray(*static_cast<const Tag*>(this));}
__INLINE Storage::var_array operator [](const Storage & arg) const {return arg.VariableArray(*static_cast<const Tag*>(this));}
__INLINE Storage::var_array operator [](HandleType h) const;
};
#endif //USE_AUTODIFF
......
......@@ -1310,6 +1310,9 @@ namespace INMOST
void AllocateSparseData (void * & q, const Tag & t);
void Init (std::string name);
public:
/// Go through all elements and detect presence of prescribed element in
/// any reference data tag.
void ReportConnection(HandleType h);
/// Test whether global identificator was set on certain type of elements.
/// This function does not validate correctness of global identificators.
/// @param type Single type of elements on which to test presence of global identificators.
......@@ -1318,8 +1321,6 @@ namespace INMOST
/// Remove all data and all elements from the mesh
/// Reset geometry service and topology check flags
void Clear ();
/// For debug purposes
integer HandleDataPos (HandleType h) {return links[GetHandleElementNum(h)][GetHandleID(h)];}
/// For parmetis
/// return total number in bytes of occupied memory by element and its data
enumerator MemoryUsage (HandleType h);
......@@ -1459,7 +1460,7 @@ namespace INMOST
bool isValidEdge (integer lid) const {return links[ElementNum(EDGE)][lid] != -1;}
bool isValidNode (integer lid) const {return links[ElementNum(NODE)][lid] != -1;}
bool isValidElementSet (integer lid) const {return links[ElementNum(ESET)][lid] != -1;}
bool isValidElement (HandleType h) const {return isValidHandle(h) && isValidElementNum(GetHandleElementNum(h),GetHandleID(h));}
bool isValidElement (HandleType h) const {return isValidHandleRange(h) && isValidElementNum(GetHandleElementNum(h),GetHandleID(h));}
/// Retrieve upper adjacent that is shared by multiple lower adjacencies.
/// @return handle of found element or InvalidHandle()
HandleType FindSharedAdjacency(const HandleType * arr, enumerator num) const;
......@@ -3438,6 +3439,38 @@ namespace INMOST
{
return GetMeshLink()->RemoteReferenceDV(GetHandle(),tag);
}
__INLINE Storage::real & TagReal::operator [](HandleType h) const
{
return GetMeshLink()->Real(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::integer & TagInteger::operator [](HandleType h) const
{
return GetMeshLink()->Integer(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::bulk & TagBulk::operator [](HandleType h) const
{
return GetMeshLink()->Bulk(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::reference & TagReference::operator [](HandleType h) const
{
return GetMeshLink()->Reference(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::real_array TagRealArray::operator [](HandleType h) const
{
return GetMeshLink()->RealArray(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::integer_array TagIntegerArray::operator [](HandleType h) const
{
return GetMeshLink()->IntegerArray(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::bulk_array TagBulkArray::operator [](HandleType h) const
{
return GetMeshLink()->BulkArray(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::reference_array TagReferenceArray::operator [](HandleType h) const
{
return GetMeshLink()->ReferenceArray(h,*static_cast<const Tag*>(this));
}
#if defined(USE_AUTODIFF)
__INLINE Storage::var & Storage::Variable(const Tag & tag) const
{
......@@ -3463,17 +3496,25 @@ namespace INMOST
{
return GetMeshLink()->VariableArrayDV(GetHandle(),tag);
}
__INLINE Storage::var & TagVariable::operator [](HandleType h) const
{
return GetMeshLink()->Variable(h,*static_cast<const Tag*>(this));
}
__INLINE Storage::var_array TagVariableArray::operator [](HandleType h) const
{
return GetMeshLink()->VariableArray(h,*static_cast<const Tag*>(this));
}
#endif
__INLINE bool Storage::HaveData(const Tag & tag) const
{
assert(isValid());
return GetMeshLink()->HaveData(GetHandle(),tag);
}
__INLINE INMOST_DATA_ENUM_TYPE Storage::GetDataSize(const Tag & tag) const
__INLINE INMOST_DATA_ENUM_TYPE Storage::GetDataSize(const Tag & tag) const
{
return GetMeshLink()->GetDataSize(GetHandle(),tag);
}
__INLINE INMOST_DATA_ENUM_TYPE Storage::GetDataCapacity(const Tag & tag) const
__INLINE INMOST_DATA_ENUM_TYPE Storage::GetDataCapacity(const Tag & tag) const
{
return GetMeshLink()->GetDataCapacity(GetHandle(),tag);
}
......@@ -3481,15 +3522,15 @@ namespace INMOST
{
GetMeshLink()->SetDataSize(GetHandle(),tag,new_size);
}
__INLINE ElementType Storage::GetElementType() const
{
return GetHandleElementType(handle);
}
__INLINE Storage::integer Storage::GetElementNum () const
{
return GetHandleElementNum(handle);
}
__INLINE void Storage::GetData(const Tag & tag,INMOST_DATA_ENUM_TYPE shift, INMOST_DATA_ENUM_TYPE size, void * data_out) const
__INLINE ElementType Storage::GetElementType() const
{
return GetHandleElementType(handle);
}
__INLINE Storage::integer Storage::GetElementNum () const
{
return GetHandleElementNum(handle);
}
__INLINE void Storage::GetData(const Tag & tag,INMOST_DATA_ENUM_TYPE shift, INMOST_DATA_ENUM_TYPE size, void * data_out) const
{
GetMeshLink()->GetData(GetHandle(),tag,shift,size,data_out);
}
......@@ -3504,7 +3545,7 @@ namespace INMOST
__INLINE void Storage::DelDenseData(const Tag & tag) const
{
GetMeshLink()->DelDenseData(GetHandle(),tag);
}
}
__INLINE void Storage::DelSparseData(const Tag & tag) const
{
GetMeshLink()->DelSparseData(GetHandle(),tag);
......@@ -3514,7 +3555,7 @@ namespace INMOST
assert( isValid() );
GetMeshLink()->SetMarker(GetHandle(),n);
}
__INLINE bool Storage::GetMarker(MarkerType n) const
__INLINE bool Storage::GetMarker(MarkerType n) const
{
assert( isValid() );
return GetMeshLink()->GetMarker(GetHandle(),n);
......@@ -3524,12 +3565,12 @@ namespace INMOST
assert( isValid() );
GetMeshLink()->RemMarker(GetHandle(),n);
}
__INLINE void Storage::SetPrivateMarker(MarkerType n) const
__INLINE void Storage::SetPrivateMarker(MarkerType n) const
{
assert( isValid() );
GetMeshLink()->SetPrivateMarker(GetHandle(),n);
}
__INLINE bool Storage::GetPrivateMarker(MarkerType n) const
__INLINE bool Storage::GetPrivateMarker(MarkerType n) const
{
assert( isValid() );
return GetMeshLink()->GetPrivateMarker(GetHandle(),n);
......@@ -3543,7 +3584,7 @@ namespace INMOST
{
GetMeshLink()->ClearMarkerSpace(GetHandle());
}
__INLINE void Storage::GetMarkerSpace(Storage::bulk copy[MarkerFields]) const
__INLINE void Storage::GetMarkerSpace(Storage::bulk copy[MarkerFields]) const
{
GetMeshLink()->GetMarkerSpace(GetHandle(),copy);
}
......@@ -3551,56 +3592,58 @@ namespace INMOST
{
GetMeshLink()->SetMarkerSpace(GetHandle(),source);
}
__INLINE bool Storage::isValid() const
__INLINE bool Storage::isValid() const
{
return handle != InvalidHandle() && GetMeshLink() != NULL && GetMeshLink()->isValidElement(handle);
}
__INLINE Storage::integer Storage::LocalID() const
{
return GetHandleID(handle);
}
__INLINE Storage::integer Storage::DataLocalID() const
__INLINE Storage::integer Storage::LocalID() const
{
return GetHandleID(handle);
}
__INLINE Storage::integer Storage::DataLocalID() const
{
return GetMeshLink()->DataLocalID(GetHandle());
}
__INLINE Element Storage::getAsElement() const
{
assert(GetElementType() & (NODE | EDGE | FACE | CELL | ESET) );
return Element(GetMeshLink(), GetHandle());
}
__INLINE Node Storage::getAsNode() const
{
assert(GetElementType() == NODE);
return Node(GetMeshLink(),GetHandle());
}
__INLINE Edge Storage::getAsEdge() const
{