Commit f3de6b96 authored by Kirill Terekhov's avatar Kirill Terekhov
Browse files

Fixes

Cleaned bugs; added features.
parent 4792fc70
......@@ -45,7 +45,7 @@ add_library(inmost STATIC ${SOURCE} ${HEADER})
option(USE_MPI "Compile with MPI support" ON)
option(USE_MPI_P2P "Use MPI point to point functionality, may be faster with hardware support" ON)
option(USE_MPI_FILE "Use MPI extension to work with files, may save a lot of memory" ON)
option(USE_MPI2 "Use MPI-2 extensions, useful if your MPI library produces warnings to use new functions" ON)
option(USE_MPI2 "Use MPI-2 extensions, useful if your MPI library warns you to use new functions" ON)
option(USE_OMP "Compile with OpenMP support (experimental)" OFF)
option(USE_MESH "Compile mesh capabilities" ON)
......
......@@ -12,6 +12,7 @@
#include <cmath>
#include <assert.h>
#include <limits>
#include "inmost_common.h"
//#define OUT_OF_RANGE
......@@ -43,7 +44,9 @@ namespace INMOST
template<> struct make_unsigned<unsigned long long> {typedef unsigned long long type;};
#define USE_OPTIMIZED_ARRAY_ALLOCATION
#if defined(PACK_ARRAY)
#pragma pack(push,r1,4)
#endif
// notice: array class would not properly support classes that contain self-references
// like std::map
// notice: next class shell have to implement same algorithms as array
......@@ -129,8 +132,10 @@ namespace INMOST
typedef _reverse_iterator<element> reverse_iterator;
typedef _reverse_iterator<const element> const_reverse_iterator;
private:
element * m_arr;
size_type m_size;
//notice: push_back, pop_back, insert, erase are optimized for current growth_formula
__INLINE static size_type growth_formula(size_type future_size)
{
......@@ -503,7 +508,9 @@ namespace INMOST
}
template<class> friend class shell;
};
#if defined(PACK_ARRAY)
#pragma pack(pop,r1)
#endif
template<typename element>
class shell
{
......@@ -677,7 +684,7 @@ namespace INMOST
*m_arr = static_cast<element *>(realloc(*m_arr,sizeof(element)*(++(*m_size))));
else if( (((*m_size)+1) & ((*m_size)-1)) == 1 )
*m_arr = static_cast<element *>(realloc(*m_arr,sizeof(element)*((*m_size)++ << 1)));
else ++m_size;
else ++(*m_size);
#endif
assert((*m_arr) != NULL);
new ((*m_arr)+(*m_size)-1) element(e);
......
......@@ -797,7 +797,7 @@ namespace INMOST
ElementArray<Element> Element::BridgeAdjacencies(ElementType Bridge, ElementType Dest, MarkerType mask, bool invert)
ElementArray<Element> Element::BridgeAdjacencies(ElementType Bridge, ElementType Dest, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -822,7 +822,7 @@ namespace INMOST
}
ElementArray<Node> Element::BridgeAdjacencies2Node(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Node> Element::BridgeAdjacencies2Node(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -846,7 +846,7 @@ namespace INMOST
return adjcells;
}
ElementArray<Edge> Element::BridgeAdjacencies2Edge(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Edge> Element::BridgeAdjacencies2Edge(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -870,7 +870,7 @@ namespace INMOST
return adjcells;
}
ElementArray<Face> Element::BridgeAdjacencies2Face(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Face> Element::BridgeAdjacencies2Face(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -894,7 +894,7 @@ namespace INMOST
return adjcells;
}
ElementArray<Cell> Element::BridgeAdjacencies2Cell(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Cell> Element::BridgeAdjacencies2Cell(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......
......@@ -1627,6 +1627,16 @@ namespace INMOST
Element::adj_type & hc = m->HighConn(GetHandle());
return (lc.size() - (hc.size() - high_conn_reserved));
}
void ElementSet::Clear() const
{
Mesh * m = GetMeshLink();
Element::adj_type & lc = m->LowConn(GetHandle());
Element::adj_type & hc = m->HighConn(GetHandle());
hc.resize(ElementSet::high_conn_reserved);
lc.clear();
BulkDF(m->SetComparatorTag()) = UNSORTED_COMPARATOR;
}
}
#endif
......@@ -505,7 +505,7 @@ namespace INMOST
case 0: *ret = 0; break;
case 1: //length of edge
{
ElementArray<Node> nodes = Element(this,e)->getNodes(NODE);
ElementArray<Node> nodes = Element(this,e)->getNodes();
Storage::real c[3];
vec_diff(nodes[0]->Coords().data(),nodes[1]->Coords().data(),c,mdim);
*ret = vec_len(c,mdim);
......@@ -514,7 +514,7 @@ namespace INMOST
}
case 2: //area of face
{
ElementArray<Node> nodes = Element(this,e)->getNodes(NODE);
ElementArray<Node> nodes = Element(this,e)->getNodes();
real x[3] = {0,0,0};
Storage::real_array x0 = nodes[0].Coords();
for(ElementArray<Node>::size_type i = 1; i < nodes.size()-1; i++)
......
......@@ -34,22 +34,36 @@
// 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
// this will revert Mesh::PrepareReceiveInner to always
// use MPI point to point functionality disregarding problem type
// read comments in Mesh::SetParallelStrategy for more info
// USE_MPI_P2P must be enabled for feature to work
//#define PREFFER_MPI_P2P
// this will write out shared set of elements that lay between processors in GMV format
//#define DEBUG_COMPUTE_SHARED_SKIN_SET
// this controls how sparse data will be allocated,
// when difinition is not commented memory will be always consumed
// by data structure needed to support sparse data,
// otherwise data structure will be allocated only when
// sparse data is presenet
//#define LAZY_SPARSE_ALLOCATION
// this will force array class to use 12 bytes instead of 16 bytes
#define PACK_ARRAY
#define __INLINE inline
#if defined(USE_OMP)
......
This diff is collapsed.
......@@ -73,7 +73,6 @@ namespace INMOST
memset(remember,0,sizeof(remember));
tag_coords = CreateTag("COORD",DATA_REAL, NODE,NONE,dim);
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
tag_high_conn = CreateTag("HIGH_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_low_conn = CreateTag("LOW_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_markers = CreateTag("MARKERS",DATA_BULK,CELL|FACE|EDGE|NODE|ESET|MESH,NONE,MarkerFields);
......@@ -154,7 +153,6 @@ namespace INMOST
//setup system tags shortcuts
dim = other.dim;
tag_coords = CreateTag("COORD",DATA_REAL, NODE,NONE,dim);
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
tag_high_conn = CreateTag("HIGH_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_low_conn = CreateTag("LOW_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_markers = CreateTag("MARKERS",DATA_BULK,CELL|FACE|EDGE|NODE|ESET|MESH,NONE,MarkerFields);
......@@ -262,7 +260,6 @@ namespace INMOST
//setup system tags shortcuts
dim = other.dim;
tag_coords = CreateTag("COORD",DATA_REAL, NODE,NONE,dim);
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
tag_high_conn = CreateTag("HIGH_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_low_conn = CreateTag("LOW_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_markers = CreateTag("MARKERS",DATA_BULK,CELL|FACE|EDGE|NODE|ESET|MESH,NONE,MarkerFields);
......@@ -1439,7 +1436,7 @@ namespace INMOST
}
else
{
ADDR = static_cast<integer>(links[etypenum].size() - empty_links[etypenum].size());
ADDR = static_cast<integer>(links[etypenum].size());
}
if( !empty_links[etypenum].empty() )
{
......@@ -1472,7 +1469,7 @@ namespace INMOST
back_links[etypenum][old_addr] = -1;
back_links[etypenum][new_addr] = ID;
links[etypenum][ID] = new_addr;
sparse_data[etypenum][new_addr].swap(sparse_data[etypenum][new_addr]);
sparse_data[etypenum][new_addr].swap(sparse_data[etypenum][old_addr]);
for(Mesh::iteratorTag t = BeginTag(); t != EndTag(); t++)
{
if( !t->isSparseNum(etypenum) )
......@@ -1498,24 +1495,25 @@ namespace INMOST
{
for(int etypenum = 0; etypenum < ElementNum(MESH); etypenum++) if( ElementTypeFromDim(etypenum) & etype )
{
int cend = static_cast<int>(back_links[etypenum].size())-1;
integer cend = static_cast<integer>(back_links[etypenum].size())-1;
//Very likely we have leading free space
while( cend >= 0 && back_links[etypenum][cend] == -1 )
cend--;
while( cend >= 0 && !empty_space[etypenum].empty() )
{
if( empty_space[etypenum].back() >= cend )
integer last = empty_space[etypenum].back();
if( last >= cend )
empty_space[etypenum].pop_back();
else if( back_links[etypenum][cend] != -1 )
{
MoveStorage(etypenum,cend,empty_space[etypenum].back());
MoveStorage(etypenum,cend,last);
empty_space[etypenum].pop_back();
}
else cend--;
}
while( cend >= 0 && back_links[etypenum][cend] == -1 )
cend--;
back_links[etypenum].resize(cend); //those should not be needed
//back_links[etypenum].resize(cend); //those should not be needed
empty_space[etypenum].clear();
ReallocateData(etypenum,GetArrayCapacity(etypenum));
}
......@@ -1786,7 +1784,7 @@ namespace INMOST
void Mesh::DelData(HandleType h,const Tag & tag)
{
assert( tag.GetMeshLink() == this );
if( tag.isSparse(GetElementType()) )
if( tag.isSparse(GetHandleElementType(h)) )
DelSparseData(h,tag);
else
DelDenseData(h,tag);
......@@ -1843,5 +1841,18 @@ namespace INMOST
}
return ret;
}
void Mesh::SetTopologyCheck (TopologyCheck mask)
{
checkset = checkset | mask;
if( mask & MARK_ON_ERROR )
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
}
void Mesh::RemTopologyCheck (TopologyCheck mask)
{
checkset = checkset & ~mask;
if( mask & MARK_ON_ERROR )
tag_topologyerror = DeleteTag(tag_topologyerror);
}
}
#endif
......@@ -1945,7 +1945,7 @@ ecl_exit_loop:
fflush(stdout);
}
}
ReorderEmpty(FACE | EDGE);
//ReorderEmpty(FACE | EDGE);
state = R_ATTRIBUTES;
}
for(i = 0; i < ncells; i++)
......@@ -3717,7 +3717,12 @@ read_elem_num_link:
fprintf(f,"file is written by INMOST\n");
fprintf(f,"ASCII\n");
fprintf(f,"DATASET UNSTRUCTURED_GRID\n");
ReorderEmpty(CELL | NODE);
//ReorderEmpty(CELL | NODE);
Tag set_id = CreateTag("TEMPORARY_ELEMENT_ID",DATA_INTEGER,CELL | NODE,NONE,1);
Storage::integer cur_num = 0;
for(Mesh::iteratorNode it = BeginNode(); it != EndNode(); ++it) it->IntegerDF(set_id) = cur_num++;
cur_num = 0;
for(Mesh::iteratorCell it = BeginCell(); it != EndCell(); ++it) it->IntegerDF(set_id) = cur_num++;
fprintf(f,"POINTS %u double\n",NumberOfNodes());
for(Mesh::iteratorNode it = BeginNode(); it != EndNode(); it++)
{
......@@ -3746,7 +3751,7 @@ read_elem_num_link:
ElementArray<Node> nodes = it->getNodes();
values.push_back(static_cast<integer>(nodes.size()));
for(ElementArray<Node>::iterator jt = nodes.begin(); jt != nodes.end(); jt++)
values.push_back(jt->LocalID());
values.push_back(jt->IntegerDF(set_id));
break;
}
case Element::Prism:
......@@ -3754,12 +3759,12 @@ read_elem_num_link:
ElementArray<Node> nodes = it->getNodes();
if( nodes.size() != 6 ) goto safe_output;
values.push_back(static_cast<integer>(nodes.size()));
values.push_back(nodes[0].LocalID());
values.push_back(nodes[2].LocalID());
values.push_back(nodes[1].LocalID());
values.push_back(nodes[3].LocalID());
values.push_back(nodes[5].LocalID());
values.push_back(nodes[4].LocalID());
values.push_back(nodes[0].IntegerDF(set_id));
values.push_back(nodes[2].IntegerDF(set_id));
values.push_back(nodes[1].IntegerDF(set_id));
values.push_back(nodes[3].IntegerDF(set_id));
values.push_back(nodes[5].IntegerDF(set_id));
values.push_back(nodes[4].IntegerDF(set_id));
break;
}
case Element::Hex:
......@@ -3767,14 +3772,14 @@ read_elem_num_link:
ElementArray<Node> nodes = it->getNodes();
if( nodes.size() != 8 ) goto safe_output;
values.push_back(static_cast<integer>(nodes.size()));
values.push_back(nodes[0].LocalID());
values.push_back(nodes[3].LocalID());
values.push_back(nodes[2].LocalID());
values.push_back(nodes[1].LocalID());
values.push_back(nodes[4].LocalID());
values.push_back(nodes[7].LocalID());
values.push_back(nodes[6].LocalID());
values.push_back(nodes[5].LocalID());
values.push_back(nodes[0].IntegerDF(set_id));
values.push_back(nodes[3].IntegerDF(set_id));
values.push_back(nodes[2].IntegerDF(set_id));
values.push_back(nodes[1].IntegerDF(set_id));
values.push_back(nodes[4].IntegerDF(set_id));
values.push_back(nodes[7].IntegerDF(set_id));
values.push_back(nodes[6].IntegerDF(set_id));
values.push_back(nodes[5].IntegerDF(set_id));
break;
}
case Element::Pyramid:
......@@ -3782,11 +3787,11 @@ read_elem_num_link:
ElementArray<Node> nodes = it->getNodes();
if( nodes.size() != 5 ) goto safe_output;
values.push_back(static_cast<integer>(nodes.size()));
values.push_back(nodes[0].LocalID());
values.push_back(nodes[3].LocalID());
values.push_back(nodes[2].LocalID());
values.push_back(nodes[1].LocalID());
values.push_back(nodes[4].LocalID());
values.push_back(nodes[0].IntegerDF(set_id));
values.push_back(nodes[3].IntegerDF(set_id));
values.push_back(nodes[2].IntegerDF(set_id));
values.push_back(nodes[1].IntegerDF(set_id));
values.push_back(nodes[4].IntegerDF(set_id));
break;
}
case Element::Polyhedron:
......@@ -3807,10 +3812,10 @@ safe_output:
values.push_back(static_cast<integer>(nodes.size()));
if( jt->FaceOrientedOutside(it->self()) )
for(ElementArray<Node>::iterator kt = nodes.begin(); kt != nodes.end(); kt++)
values.push_back(kt->LocalID());
values.push_back(kt->IntegerDF(set_id));
else
for(ElementArray<Node>::reverse_iterator kt = nodes.rbegin(); kt != nodes.rend(); kt++)
values.push_back(kt->LocalID());
values.push_back(kt->IntegerDF(set_id));
}
break;
}
......@@ -3834,7 +3839,7 @@ safe_output:
else //number of nodes mismatch with expected - some topology checks must be off
fprintf(f,"%d\n",VtkElementType(Element::MultiPolygon));
}
DeleteTag(set_id);
{
std::vector<std::string> tag_names;
std::vector<Tag> tags;
......@@ -3948,7 +3953,7 @@ safe_output:
{
Storage::integer keynum;
Storage::real keyval;
ReorderEmpty(CELL | FACE | NODE | ESET);
//ReorderEmpty(CELL | FACE | NODE | ESET);
FILE * file = fopen(File.c_str(),"wb");
char keyword[2048];
sprintf(keyword,"gmvinput"); fwrite(keyword,1,8,file);
......@@ -3970,6 +3975,13 @@ safe_output:
sprintf(keyword,"faces"); fwrite(keyword,1,8,file);
keynum = static_cast<Storage::integer>(NumberOfFaces()); fwrite(&keynum,sizeof(Storage::integer),1,file);
keynum = static_cast<Storage::integer>(NumberOfCells()); fwrite(&keynum,sizeof(Storage::integer),1,file);
Tag set_id = CreateTag("TEMPORARY_ELEMENT_ID",DATA_INTEGER,CELL|FACE|NODE,NONE,1);
Storage::integer cur_num = 0;
for(Mesh::iteratorNode it = BeginNode(); it != EndNode(); ++it) it->IntegerDF(set_id) = cur_num++;
cur_num = 0;
for(Mesh::iteratorFace it = BeginFace(); it != EndFace(); ++it) it->IntegerDF(set_id) = cur_num++;
cur_num = 0;
for(Mesh::iteratorCell it = BeginCell(); it != EndCell(); ++it) it->IntegerDF(set_id) = cur_num++;
for(Mesh::iteratorFace f = BeginFace(); f != EndFace(); f++)
{
ElementArray<Node> fnodes = f->getNodes();
......@@ -3978,15 +3990,15 @@ safe_output:
//sprintf(keyword,"vertex_ids"); fwrite(keyword,1,8,file);
for(ElementArray<Node>::iterator fn = fnodes.begin(); fn != fnodes.end(); fn++)
{
keynum = fn->LocalID()+1;
keynum = fn->IntegerDF(set_id)+1;
fwrite(&keynum,sizeof(Storage::integer),1,file);
}
ElementArray<Cell> fcells = f->getCells();
//sprintf(keyword,"cellno1"); fwrite(keyword,1,8,file);
keynum = fcells.size() > 0 ? fcells[0].LocalID()+1 : 0;
keynum = fcells.size() > 0 ? fcells[0].IntegerDF(set_id)+1 : 0;
fwrite(&keynum,sizeof(Storage::integer),1,file);
//sprintf(keyword,"cellno2"); fwrite(keyword,1,8,file);
keynum = fcells.size() > 1 ? fcells[1].LocalID()+1 : 0;
keynum = fcells.size() > 1 ? fcells[1].IntegerDF(set_id)+1 : 0;
fwrite(&keynum,sizeof(Storage::integer),1,file);
}
......@@ -4075,7 +4087,7 @@ safe_output:
for(Mesh::iteratorElement e = BeginElement(etype); e != EndElement(); e++)
if( e->HaveData(*t) )
{
keynum = e->LocalID()+1;
keynum = e->IntegerDF(set_id)+1;
fwrite(&keynum,sizeof(Storage::integer),1,file);
}
for(Mesh::iteratorElement e = BeginElement(etype); e != EndElement(); e++)
......@@ -4116,7 +4128,7 @@ safe_output:
case CELL: temp = 0; break;
default: throw NotImplemented;
}
//sprintf(keyword,"set%d_%s\n",set->LocalID()+1,ElementTypeName(etype));
//sprintf(keyword,"set%d_%s\n",set->IntegerDF(set_id)+1,ElementTypeName(etype));
sprintf(keyword,"%s",set->GetName().c_str());
fwrite(keyword,1,8,file);
fwrite(&temp,sizeof(Storage::integer),1,file);
......@@ -4124,7 +4136,7 @@ safe_output:
for(ElementSet::iterator it = set->Begin(); it != set->End(); it++)
if( it->GetElementType() == etype )
{
keynum = it->LocalID()+1;
keynum = it->IntegerDF(set_id)+1;
fwrite(&keynum,sizeof(Storage::integer),1,file);
}
}
......@@ -4215,10 +4227,25 @@ safe_output:
iconv.write_fByteOrder(out);
iconv.write_fByteSize(out);
INMOST_DATA_ENUM_TYPE header[9] = {GetDimensions(), NumberOfNodes(), NumberOfEdges(), NumberOfFaces(), NumberOfCells(), NumberOfSets(), NumberOfTags(), m_state, GetProcessorRank()},k;
INMOST_DATA_ENUM_TYPE header[9] = {GetDimensions(), NumberOfNodes(), NumberOfEdges(), NumberOfFaces(), NumberOfCells(), NumberOfSets(), NumberOfTags()-3, m_state, GetProcessorRank()},k;
for(k = 0; k < 9; k++) uconv.write_iValue(out,header[k]);
out.write(reinterpret_cast<char *>(remember),sizeof(remember));
Tag set_id = CreateTag("TEMPORARY_ELEMENT_ID",DATA_INTEGER,ESET|CELL|FACE|EDGE|NODE,NONE,1);
{
Storage::integer cur_num = 0;
for(Mesh::iteratorNode it = BeginNode(); it != EndNode(); ++it) it->IntegerDF(set_id) = cur_num++;
cur_num = 0;
for(Mesh::iteratorEdge it = BeginEdge(); it != EndEdge(); ++it) it->IntegerDF(set_id) = cur_num++;
cur_num = 0;
for(Mesh::iteratorFace it = BeginFace(); it != EndFace(); ++it) it->IntegerDF(set_id) = cur_num++;
cur_num = 0;
for(Mesh::iteratorCell it = BeginCell(); it != EndCell(); ++it) it->IntegerDF(set_id) = cur_num++;
cur_num = 0;
for(Mesh::iteratorSet it = BeginSet(); it != EndSet(); ++it) it->IntegerDF(set_id) = cur_num++;
}
// Tags
out << INMOST::TagsHeader;
uconv.write_iValue(out,header[6]);
......@@ -4226,6 +4253,10 @@ safe_output:
REPORT_VAL("tag_size",header[6]);
for(Mesh::iteratorTag it = BeginTag(); it != EndTag(); it++)
{
if( *it == set_id ) continue;
if( *it == HighConnTag() ) continue;
if( *it == LowConnTag() ) continue;
std::string name = it->GetTagName();
INMOST_DATA_ENUM_TYPE namesize = static_cast<INMOST_DATA_BULK_TYPE>(name.size());
INMOST_DATA_BULK_TYPE datatype = static_cast<INMOST_DATA_BULK_TYPE>(it->GetDataType());
......@@ -4270,7 +4301,7 @@ safe_output:
uconv.write_iValue(out,nlow);
for(Element::adj_type::size_type kt = 0; kt < lc.size(); ++kt)
{
lid = GetHandleID(lc[kt]);
lid = IntegerDF(lc[kt],set_id);
uconv.write_iValue(out,lid);
}
}
......@@ -4287,7 +4318,7 @@ safe_output:
uconv.write_iValue(out,nlow);
for(Element::adj_type::size_type kt = 0; kt < lc.size(); ++kt)
{
lid = GetHandleID(lc[kt]);
lid = IntegerDF(lc[kt],set_id);
uconv.write_iValue(out,lid);
}
}
......@@ -4304,7 +4335,7 @@ safe_output:
uconv.write_iValue(out,nlow);
for(Element::adj_type::size_type kt = 0; kt < lc.size(); ++kt)
{
lid = GetHandleID(lc[kt]);
lid = IntegerDF(lc[kt],set_id);
uconv.write_iValue(out,lid);
}
Element::adj_type & hc = HighConn(*it);
......@@ -4312,7 +4343,7 @@ safe_output:
uconv.write_iValue(out,nhigh);
for(Element::adj_type::size_type kt = 0; kt < hc.size(); ++kt)
{
lid = GetHandleID(hc[kt]);
lid = IntegerDF(hc[kt],set_id);
uconv.write_iValue(out,lid);
}
}
......@@ -4337,7 +4368,7 @@ safe_output:
{
wetype = GetHandleElementType(*kt);
out.put(wetype);
lid = GetHandleID(*kt);
lid = IntegerDF(*kt,set_id);
uconv.write_iValue(out,lid);
}
else out.put(NONE);
......@@ -4351,7 +4382,7 @@ safe_output:
{
wetype = GetHandleElementType(*kt);
out.put(wetype);
lid = GetHandleID(*kt);
lid = IntegerDF(*kt,set_id);
uconv.write_iValue(out,lid);
}
else out.put(NONE);
......@@ -4363,7 +4394,7 @@ safe_output:
{
wetype = GetHandleElementType(*kt);
out.put(wetype);
lid = GetHandleID(*kt);
lid = IntegerDF(*kt,set_id);
uconv.write_iValue(out,lid);
}
else out.put(NONE);
......@@ -4373,8 +4404,12 @@ safe_output:
out << INMOST::MeshDataHeader;
REPORT_STR("MeshDataHeader");
for(Mesh::iteratorTag jt = BeginTag(); jt != EndTag(); jt++)
for(Mesh::iteratorTag jt = BeginTag(); jt != EndTag(); jt++)
{
std::string tagname = jt->GetTagName();
if( *jt == set_id ) continue;
if( *jt == HighConnTag() ) continue;
if( *jt == LowConnTag() ) continue;
REPORT_VAL("TagName",jt->GetTagName());
for(ElementType etype = NODE; etype <= MESH; etype = etype << 1)
if( jt->isDefined(etype) )
......@@ -4420,7 +4455,7 @@ safe_output:
{
wetype = arr[k].GetElementType();
out.put(wetype);
lid = GetHandleID(arr[k].LocalID());
lid = IntegerDF(arr[k]->GetHandle(),set_id);
uconv.write_iValue(out,lid);
}
else out.put(NONE);
......@@ -4433,7 +4468,7 @@ safe_output:
if( sparse ) uconv.write_iValue(out,q);
}
}
DeleteTag(set_id);
out << INMOST::EoMHeader;
#if defined(USE_MPI)
......
......@@ -31,26 +31,143 @@ static INMOST_DATA_BIG_ENUM_TYPE pmid = 0;
namespace INMOST
{
//////////////////////////////
/// REDUCTION FUNCTIONS ///
//////////////////////////////
void DefaultUnpack(const Tag & tag, const Element & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size == 0 )
{
if( tag.isDefined(element->GetElementType()) )
{
if( tag.isSparse(element->GetElementType()) )
{
if( element->HaveData(tag) )
element->DelData(tag);
}
else if( tag.GetSize() == ENUMUNDEF )
element->SetDataSize(tag,size);
else
{