Commit 306da91a authored by Kirill Terekhov's avatar Kirill Terekhov

Organization of unknowns into blocks for Automatizator

parent 049af67d
......@@ -149,7 +149,7 @@ int main(int argc,char ** argv)
Automatizator aut;
Automatizator::MakeCurrent(&aut);
INMOST_DATA_ENUM_TYPE iphi = aut.RegisterTag(phi,CELL);
aut.EnumerateTags();
aut.EnumerateEntries();
// Set the indeces intervals for the matrix and vectors
R.SetInterval(aut.GetFirstIndex(),aut.GetLastIndex());
......@@ -329,4 +329,4 @@ int main(int argc,char ** argv)
#endif
Solver::Finalize(); // Finalize solver and close MPI activity
return 0;
}
\ No newline at end of file
}
......@@ -427,7 +427,7 @@ int main(int argc,char ** argv)
Automatizator aut; // declare class to help manage unknowns
Automatizator::MakeCurrent(&aut);
dynamic_variable P(aut,aut.RegisterTag(tag_P,CELL|(hybrid?FACE:NONE))); //register pressure as primary unknown
aut.EnumerateTags(); //enumerate all primary variables
aut.EnumerateEntries(); //enumerate all primary variables
std::cout << "Enumeration done, size " << aut.GetLastIndex() - aut.GetFirstIndex() << std::endl;
......
......@@ -480,7 +480,7 @@ int main(int argc,char ** argv)
Automatizator aut; // declare class to help manage unknowns
dynamic_variable Q(aut,aut.RegisterTag(tag_Q,two_point ? CELL : (CELL|FACE))); //register pressure as primary unknown
aut.EnumerateTags(); //enumerate all primary variables
aut.EnumerateEntries(); //enumerate all primary variables
std::cout << "Enumeration done, size " << aut.GetLastIndex() - aut.GetFirstIndex() << std::endl;
......
......@@ -120,7 +120,7 @@ void ps_inmost (Sparse::Matrix & A, const std::string file)
ps_ij (row,jt->first);
row++;
}
ps_file (file, NULL, NULL);
ps_file (file, 0, NULL);
}
#endif
......
......@@ -2227,7 +2227,7 @@ int main(int argc, char ** argv)
num_orphans[it->GetElementType()]++;
}
printf("number of orphan elements: %d\n",orphans.size());
printf("number of orphan elements: %lu\n",orphans.size());
for(std::map<ElementType,int>::iterator it = num_orphans.begin(); it != num_orphans.end(); ++it)
printf("%s %d\n",ElementTypeName(it->first),it->second);
int was = orphans.size();
......@@ -2239,7 +2239,7 @@ int main(int argc, char ** argv)
orphans.push_back(it->self());
num_topo[it->GetElementType()]++;
}
printf("number of elements with topology error: %d\n",orphans.size()-was);
printf("number of elements with topology error: %lu\n",orphans.size()-was);
for(std::map<ElementType,int>::iterator it = num_topo.begin(); it != num_topo.end(); ++it)
printf("%s %d\n",ElementTypeName(it->first),it->second);
for(int k = was; k < orphans.size(); ++k)
......
......@@ -168,7 +168,7 @@ namespace INMOST
}
}
printf("done from boundary faces, total streamlines = %d\n", output.size());
printf("done from boundary faces, total streamlines = %lu\n", output.size());
printf("started building streamlines from unvisited cells\n");
tot = 0;
......@@ -196,13 +196,13 @@ namespace INMOST
fflush(stdout);
}
}
printf("done from unvisited cells, total streamlines = %d\n", output.size());
printf("done from unvisited cells, total streamlines = %lu\n", output.size());
mesh->ReleaseMarker(visited,vel_def);
}
mesh->DeleteTag(cell_size);
printf("done, total streamlines = %d\n", output.size());
printf("done, total streamlines = %lu\n", output.size());
printf("killing octree, was sets %d\n", mesh->NumberOfSets());
octsearch.Destroy();
printf("done, sets %d\n", mesh->NumberOfSets());
......@@ -299,4 +299,4 @@ namespace INMOST
file << "</g>" << std::endl;
}
}
}
\ No newline at end of file
}
......@@ -318,7 +318,7 @@ namespace INMOST
if (q%pace == 0) faces.back().set_flag(true);
q++;
}
printf("number of faces %d\n", faces.size());
printf("number of faces %lu\n", faces.size());
}
void volumetric2::camera(double pos[3], int interactive)
......
......@@ -56,145 +56,131 @@ namespace INMOST
#if defined(USE_MESH)
Automatizator::Automatizator(const Automatizator & b) : name(b.name+"_copy")
{
std::vector<INMOST_DATA_ENUM_TYPE> regs = b.ListRegisteredTags();
std::vector<INMOST_DATA_ENUM_TYPE> regs = b.ListRegisteredEntries();
for(std::vector<INMOST_DATA_ENUM_TYPE>::iterator kt = regs.begin(); kt != regs.end(); ++kt)
RegisterTag(b.GetValueTag(*kt),b.GetElementType(*kt),b.GetMask(*kt));
if( b.last_num != 0 ) EnumerateTags();
RegisterEntry(b.GetEntry(*kt));
if( b.last_num != 0 ) EnumerateEntries();
}
Automatizator & Automatizator::operator =(Automatizator const & b)
{
if( &b != this )
{
name = b.name+"_copy";
del_tags.clear();
reg_tags.clear();
std::vector<INMOST_DATA_ENUM_TYPE> regs = b.ListRegisteredTags();
for (unsigned k = 0; k < reg_blocks.size(); k++)
if( isRegisteredEntry(k) ) UnregisterEntry(k);
del_blocks.clear();
reg_blocks.clear();
act_blocks.clear();
std::vector<INMOST_DATA_ENUM_TYPE> regs = b.ListRegisteredEntries();
for(std::vector<INMOST_DATA_ENUM_TYPE>::iterator kt = regs.begin(); kt != regs.end(); ++kt)
RegisterTag(b.GetValueTag(*kt),b.GetElementType(*kt),b.GetMask(*kt));
if( b.last_num != 0 ) EnumerateTags();
RegisterEntry(b.GetEntry(*kt));
if( b.last_num != 0 ) EnumerateEntries();
}
return *this;
}
Automatizator::Automatizator(std::string _name) :name(_name), first_num(0), last_num(0) {}
Automatizator::~Automatizator()
{
del_tags.clear();
for (unsigned k = 0; k < reg_tags.size(); k++) if( reg_tags[k].active )
reg_tags[k].indices = reg_tags[k].indices.GetMeshLink()->DeleteTag(reg_tags[k].indices);
for (unsigned k = 0; k < reg_blocks.size(); k++)
if( isRegisteredEntry(k) ) UnregisterEntry(k);
del_blocks.clear();
act_blocks.clear();
reg_blocks.clear();
}
INMOST_DATA_ENUM_TYPE Automatizator::RegisterTag(Tag t, ElementType typemask, MarkerType domain_mask)
{
tagdata p;
p.domain_mask = domain_mask;
p.t = t;
ElementType def = NONE, sparse = NONE;
for (ElementType q = NODE; q <= MESH; q = q << 1) if (q & typemask)
if( t.GetSize() == ENUMUNDEF )
return RegisterEntry(VectorEntry(typemask,domain_mask,t));
else if( t.GetSize() == 1 )
return RegisterEntry(SingleEntry(typemask,domain_mask,t,0));
else
{
BlockEntry b(typemask,domain_mask);
for(int k = 0; k < t.GetSize(); ++k)
b.AddTag(t,k);
return RegisterEntry(b);
}
}
INMOST_DATA_ENUM_TYPE Automatizator::RegisterEntry(const AbstractEntry & b)
{
Mesh * m = b.GetMeshLink();
ElementType sparse = b.GetElementType();
for (ElementType q = NODE; q <= MESH; q = NextElementType(q)) if (q & b.GetElementType())
{
if (t.isDefined(q)) def |= q;
if (t.isSparse(q)) sparse |= q;
for(unsigned unk = 0; unk < b.Size(); ++unk)
sparse &= b.GetValueTag(unk).isSparse(q);
}
p.indices = t.GetMeshLink()->CreateTag(t.GetTagName() + "_index_" + name, DATA_INTEGER, def, sparse, t.GetSize());
p.active = true;
INMOST_DATA_ENUM_TYPE ret;
if( del_tags.empty() )
INMOST_DATA_ENUM_TYPE ret = ENUMUNDEF;
if( del_blocks.empty() )
{
ret = static_cast<INMOST_DATA_ENUM_TYPE>(reg_tags.size());
reg_tags.push_back(p);
ret = static_cast<INMOST_DATA_ENUM_TYPE>(reg_blocks.size());
reg_blocks.push_back(b.Copy());
act_blocks.push_back(true);
}
else
{
ret = del_tags.back();
assert(!reg_tags[ret].active);
del_tags.pop_back();
reg_tags[ret] = p;
ret = del_blocks.back();
assert(!act_blocks[ret]);
del_blocks.pop_back();
reg_blocks[ret] = b.Copy();
act_blocks[ret] = true;
}
reg_blocks[ret]->reg_index = ret;
{
std::stringstream tag_name;
tag_name << name << "_BLK_" << ret << "_Offset";
reg_blocks[ret]->SetOffsetTag(m->CreateTag(tag_name.str(),DATA_INTEGER,b.GetElementType(),sparse,1));
}
return ret;
}
void Automatizator::UnregisterTag(INMOST_DATA_ENUM_TYPE ind)
void Automatizator::UnregisterEntry(INMOST_DATA_ENUM_TYPE ind)
{
assert(reg_tags[ind].active);
del_tags.push_back(ind);
reg_tags[ind].active = false;
assert(act_blocks[ind]);
if( reg_blocks[ind]->GetOffsetTag().isValid() )
reg_blocks[ind]->GetOffsetTag().GetMeshLink()->DeleteTag(reg_blocks[ind]->GetOffsetTag());
delete reg_blocks[ind];
reg_blocks[ind] = NULL;
del_blocks.push_back(ind);
act_blocks[ind] = false;
}
void Automatizator::EnumerateTags()
void Automatizator::EnumerateEntries()
{
first_num = last_num = 0;
const ElementType paralleltypes = NODE | EDGE | FACE | CELL;
for (tag_enum::iterator it = reg_tags.begin(); it != reg_tags.end(); ++it) if( it->active )
for (unsigned it = 0; it < reg_blocks.size(); ++it) if( act_blocks[it] )
{
Mesh * m = it->indices.GetMeshLink();
AbstractEntry & b = *reg_blocks[it];
TagInteger offset_tag = b.GetOffsetTag();
Mesh * m = offset_tag.GetMeshLink();
for (ElementType etype = NODE; etype <= MESH; etype = etype << 1)
if (it->indices.isDefined(etype) && it->indices.isSparse(etype))
if (offset_tag.isDefined(etype) && offset_tag.isSparse(etype))
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
jt->DelData(it->indices);
for(int kt = 0; kt < m->LastLocalID(etype); ++kt) if( m->isValidElement(etype,kt) )
m->ElementByLocalID(etype,kt).DelData(offset_tag);
}
}
for (tag_enum::iterator it = reg_tags.begin(); it != reg_tags.end(); ++it) if( it->active )
for (unsigned it = 0; it < reg_blocks.size(); ++it) if( act_blocks[it] )
{
Mesh * m = it->indices.GetMeshLink();
for (ElementType etype = MESH; etype >= NODE; etype = PrevElementType(etype))
AbstractEntry & b = *reg_blocks[it];
TagInteger offset_tag = b.GetOffsetTag();
Mesh * m = offset_tag.GetMeshLink();
for (ElementType etype = MESH; etype >= NODE; etype = PrevElementType(etype)) if( b.GetElementType() & etype )
{
if (it->indices.isDefined(etype))
for(int kt = 0; kt < m->LastLocalID(etype); ++kt) if( m->isValidElement(etype,kt) )
{
if (it->indices.GetSize() == ENUMUNDEF)
Element jt = m->ElementByLocalID(etype,kt);
if ((!(etype & paralleltypes) || (jt.GetStatus() != Element::Ghost)) && b.isValid(jt) && b.Size(jt))
{
if (!it->indices.isSparse(etype))
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask)))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
indarr.resize(jt->RealArray(it->t).size());
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt = last_num++;
}
}
}
else
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (jt->HaveData(it->t) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask))))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
indarr.resize(jt->RealArray(it->t).size());
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt = last_num++;
}
}
}
}
else
{
if (!it->indices.isSparse(etype))
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask)))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt = last_num++;
}
}
}
else
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (jt->HaveData(it->t) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask))))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt = last_num++;
}
}
}
offset_tag[jt] = last_num;
last_num += b.Size(jt);
}
}
}
......@@ -207,198 +193,271 @@ namespace INMOST
{
MPI_Scan(&last_num, &first_num, 1, INMOST_MPI_DATA_ENUM_TYPE, MPI_SUM, MPI_COMM_WORLD);
first_num -= last_num;
last_num += first_num;
ElementType exch_mask = NONE;
for (tag_enum::iterator it = reg_tags.begin(); it != reg_tags.end(); ++it) if( it->active )
for (unsigned it = 0; it < reg_blocks.size(); ++it) if( act_blocks[it] )
{
Mesh * m = it->indices.GetMeshLink();
for (ElementType etype = NODE; etype <= MESH; etype = NextElementType(etype))
AbstractEntry & b = *reg_blocks[it];
TagInteger offset_tag = b.GetOffsetTag();
Mesh * m = offset_tag.GetMeshLink();
for (ElementType etype = MESH; etype >= NODE; etype = PrevElementType(etype)) if( b.GetElementType() & etype )
{
if (it->indices.isDefined(etype))
exch_mask |= etype;
for(int kt = 0; kt < m->LastLocalID(etype); ++kt) if( m->isValidElement(etype,kt) )
{
exch_mask |= etype;
if (it->indices.GetSize() == ENUMUNDEF)
{
if (!it->indices.isSparse(etype))
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask)))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt += first_num;
}
}
}
else
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (jt->HaveData(it->t) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask))))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
indarr.resize(jt->RealArray(it->t).size());
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt += first_num;
}
}
}
}
else
{
if (!it->indices.isSparse(etype))
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask)))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt += first_num;
}
}
}
else
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() != Element::Ghost)) && (jt->HaveData(it->t) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask))))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
*qt += first_num;
}
}
}
}
Element jt = m->ElementByLocalID(etype,kt);
if ((!(etype & paralleltypes) || (jt.GetStatus() != Element::Ghost)) && b.isValid(jt) && b.Size(jt))
offset_tag[jt] += first_num;
}
}
}
//synchronize indices
last_num += first_num;
{
std::map<Mesh *,std::vector<Tag> > exch_tags;
for (tag_enum::iterator it = reg_tags.begin(); it != reg_tags.end(); ++it) if( it->active )
exch_tags[it->indices.GetMeshLink()].push_back(it->indices);
for (unsigned it = 0; it < reg_blocks.size(); ++it) if( act_blocks[it] )
exch_tags[reg_blocks[it]->GetOffsetTag().GetMeshLink()].push_back(reg_blocks[it]->GetOffsetTag());
for(std::map<Mesh *,std::vector<Tag> >::iterator it = exch_tags.begin(); it != exch_tags.end(); ++it)
it->first->ExchangeData(it->second, exch_mask,0);
}
//compute out-of-bounds indices
for (tag_enum::iterator it = reg_tags.begin(); it != reg_tags.end(); ++it) if( it->active )
for (unsigned it = 0; it < reg_blocks.size(); ++it) if( act_blocks[it] )
{
Mesh * m = it->indices.GetMeshLink();
for (ElementType etype = NODE; etype <= MESH; etype = NextElementType(etype))
AbstractEntry & b = *reg_blocks[it];
TagInteger offset_tag = b.GetOffsetTag();
Mesh * m = offset_tag.GetMeshLink();
for (ElementType etype = NODE; etype <= MESH; etype = NextElementType(etype)) if( b.GetElementType() & etype )
{
if (it->indices.isDefined(etype))
for(int kt = 0; kt < m->LastLocalID(etype); ++kt) if( m->isValidElement(etype,kt) )
{
exch_mask |= etype;
if (it->indices.GetSize() == ENUMUNDEF)
Element jt = m->ElementByLocalID(etype,kt);
if ((!(etype & paralleltypes) || (jt.GetStatus() == Element::Ghost)) && b.isValid(jt) && b.Size(jt))
{
if (!it->indices.isSparse(etype))
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() == Element::Ghost)) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask)))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
{
if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) < first_num ) Pre.insert(*qt);
else if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) >= last_num ) Post.insert(*qt);
}
}
}
}
else
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() == Element::Ghost)) && (jt->HaveData(it->t) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask))))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
indarr.resize(jt->RealArray(it->t).size());
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
{
if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) < first_num ) Pre.insert(*qt);
else if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) >= last_num ) Post.insert(*qt);
}
}
}
}
if( offset_tag[jt] < first_num )
for(unsigned q = 0; q < b.Size(jt); ++q) Pre.insert(b.Index(jt,q));
else if( offset_tag[jt] > last_num )
for(unsigned q = 0; q < b.Size(jt); ++q) Post.insert(b.Index(jt,q));
}
else //getsize
{
if (!it->indices.isSparse(etype))
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() == Element::Ghost)) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask)))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
{
if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) < first_num ) Pre.insert(*qt);
else if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) >= last_num ) Post.insert(*qt);
}
}
}
}
else
{
for (Mesh::iteratorStorage jt = m->Begin(etype); jt != m->End(); ++jt)
{
if ((!(etype & paralleltypes) || ((etype & paralleltypes) && jt->getAsElement()->GetStatus() == Element::Ghost)) && (jt->HaveData(it->t) && (it->domain_mask == 0 || jt->GetMarker(it->domain_mask))))
{
Storage::integer_array indarr = jt->IntegerArray(it->indices);
for (Storage::integer_array::iterator qt = indarr.begin(); qt != indarr.end(); ++qt)
{
if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) < first_num ) Pre.insert(*qt);
else if( static_cast<INMOST_DATA_ENUM_TYPE>(*qt) >= last_num ) Post.insert(*qt);
}
}
}
}
} //getsize
} //isdefined
}
} //etype
} //it
// after cycle
}
#endif
// this version will fail in parallel
//merger.Resize(first_num,last_num,false);
// use this version until there is a way to define multiple intervals in RowMerger
//INMOST_DATA_INTEGER_TYPE max_unknowns = m->AggregateMax(static_cast<INMOST_DATA_INTEGER_TYPE>(last_num));
//std::cout << "Proc " << m->GetProcessorRank() << " size " << last_num-first_num << " pre " << Pre.size() << " post " << Post.size() << " max " << max_unknowns << std::endl;
#if defined(USE_OMP)
#pragma omp parallel
#endif //USE_OMP
{
#if defined(USE_OMP)
#pragma omp single
#endif //USE_OMP
{
merger.resize(omp_get_num_procs());
merger.resize(MAX_THREADS);
}
merger[omp_get_thread_num()].Resize(first_num,last_num,std::vector<INMOST_DATA_ENUM_TYPE>(Pre.begin(),Pre.end()),std::vector<INMOST_DATA_ENUM_TYPE>(Post.begin(),Post.end()),false);
merger[OMP_THREAD].Resize(first_num,last_num,std::vector<INMOST_DATA_ENUM_TYPE>(Pre.begin(),Pre.end()),std::vector<INMOST_DATA_ENUM_TYPE>(Post.begin(),Post.end()),false);
}
#else
merger.Resize(first_num,last_num,std::vector<INMOST_DATA_ENUM_TYPE>(Pre.begin(),Pre.end()),std::vector<INMOST_DATA_ENUM_TYPE>(Post.begin(),Post.end()),false);
#endif
}
std::vector<INMOST_DATA_ENUM_TYPE> Automatizator::ListRegisteredTags() const
std::vector<INMOST_DATA_ENUM_TYPE> Automatizator::ListRegisteredEntries() const
{
std::vector<INMOST_DATA_ENUM_TYPE> ret;
for(tag_enum::size_type it = 0; it < reg_tags.size(); ++it) if( reg_tags[it].active )
for(blk_enum::size_type it = 0; it < reg_blocks.size(); ++it) if( isRegisteredEntry(it) )
ret.push_back(static_cast<INMOST_DATA_ENUM_TYPE>(it));
return ret;
}
ElementType Automatizator::GetElementType(INMOST_DATA_ENUM_TYPE ind) const
void BlockEntry::AddTag(Tag value, INMOST_DATA_ENUM_TYPE comp)
{
assert(unknown_tags.empty() || GetMeshLink() == value.GetMeshLink());
if( comp == ENUMUNDEF )
{
if( value.GetSize() != ENUMUNDEF )
{
for(unsigned k = 0; k < value.GetSize(); ++k)
{
unknown_tags.push_back(value);
unknown_comp.push_back(k);
}
}
else throw "Cannot add variable-sized tag to block";
}
else
{
unknown_tags.push_back(value);
unknown_comp.push_back(comp);
}
}
INMOST_DATA_ENUM_TYPE MultiEntry::MatrixSize(const Storage & e) const
{
INMOST_DATA_ENUM_TYPE ret = 0;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
ret += entries[k]->MatrixSize(e);
return ret;
}
INMOST_DATA_REAL_TYPE MultiEntry::Value(const Storage & e, INMOST_DATA_ENUM_TYPE unk) const
{
unsigned pos = 0, k = 0;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
unsigned s = entries[k]->MatrixSize(e);
if( pos + s > unk )
return entries[k]->Value(e,unk-pos);
else pos += s;
}
throw Impossible;
}
INMOST_DATA_REAL_TYPE & MultiEntry::Value(const Storage & e, INMOST_DATA_ENUM_TYPE unk)
{
unsigned pos = 0, k = 0;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
unsigned s = entries[k]->MatrixSize(e);
if( pos + s > unk )
return entries[k]->Value(e,unk-pos);
else pos += s;
}
throw Impossible;
}
INMOST_DATA_ENUM_TYPE MultiEntry::Index(const Storage & e, INMOST_DATA_ENUM_TYPE unk) const
{
unsigned pos = 0, k = 0;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
unsigned s = entries[k]->MatrixSize(e);
if( pos + s > unk )
return entries[k]->Index(e,unk-pos);
else pos += s;
}
throw Impossible;
}
unknown MultiEntry::Unknown(const Storage & e, INMOST_DATA_ENUM_TYPE unk) const
{
unsigned pos = 0, k = 0;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
unsigned s = entries[k]->MatrixSize(e);
if( pos + s > unk )
return entries[k]->Unknown(e,unk-pos);
else pos += s;
}
throw Impossible;
}
rMatrix MultiEntry::Value(const Storage & e) const
{
vMatrix ret(MatrixSize(e),1);
unsigned l = 0, r, t;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
t = entries[k]->MatrixSize(e);
for(r = 0; r < t; ++r)
ret(l++,0) = entries[k]->Value(e,r);
}
return ret;
}