Commit 84f42dc6 authored by Kirill Terekhov's avatar Kirill Terekhov
Browse files

fix wgtflag value in parmetis; balancing based on work in refinement and coarsement in AdaptiveMesh

parent a307067a
......@@ -63,6 +63,11 @@ namespace INMOST
(void) size;
element->Integer(tag) = std::min(element->Integer(tag),*((const INMOST_DATA_INTEGER_TYPE *)data));
}
void ReduceSum(const Tag & tag, const Element & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
(void) size;
element.Real(tag) += *((const INMOST_DATA_REAL_TYPE *)data);
}
void ReduceUnion(const Tag & tag, const Element & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
......@@ -1682,4 +1687,44 @@ namespace INMOST
return ret != 0;
}
void AdaptiveMesh::ComputeWeightCoarse(TagInteger indicator, TagReal wgt)
{
for(Mesh::iteratorCell it = m->BeginCell(); it != m->EndCell(); ++it) wgt[*it] = 0;
for(Mesh::iteratorCell it = m->BeginCell(); it != m->EndCell(); ++it) if( it->GetStatus() != Element::Ghost )
{
if( indicator[*it] )
{
ElementSet parent(m,parent_set[*it]);
for(ElementSet::iterator jt = parent.Begin(); jt != parent.End(); ++jt)
if( jt->GetStatus() != Element::Ghost )
wgt[*it]+=20;
}
else wgt[*it] = 1;
}
m->ReduceData(wgt,CELL,0,ReduceSum);
m->ExchangeData(wgt,CELL,0);
}
void AdaptiveMesh::ComputeWeightRefine(TagInteger indicator, TagReal wgt)
{
for(Mesh::iteratorCell it = m->BeginCell(); it != m->EndCell(); ++it)
{
if( indicator[*it] )
{
Storage::reference_array hanging;
ElementArray<Node> nodes = it->getNodes();
ElementArray<Face> faces = it->getFaces();
hanging = hanging_nodes[*it];
nodes.Subtract(hanging.data(),hanging.size());
for(ElementArray<Face>::iterator jt = faces.begin(); jt != faces.end(); ++jt)
{
Storage::reference_array hanging = hanging_nodes[*jt];
nodes.Subtract(hanging.data(),hanging.size());
}
wgt[*it] = nodes.size()*20;
}
else wgt[*it] = 1;
}
}
}
......@@ -38,6 +38,11 @@ namespace INMOST
void ClearData();
void PrintSet(std::ostream & fout, ElementSet set);
void SetModel(Model * mm) {model = mm;}
//the work on each cell is supposed to be proportional to the number of cells refined
//this number is equal to number of original nodes
void ComputeWeightRefine(TagInteger indicator, TagReal weight);
//the work on each cell is supposed to be proportional to the number of cells united
void ComputeWeightCoarse(TagInteger indicator, TagReal weight);
//void Test();
//void PrintMesh(std::ostream& os, int cell = 0, int face = 0, int edge = 0, int node = 0);
//void PrintSet();
......
......@@ -2,6 +2,10 @@
using namespace INMOST;
bool output_file = false;
bool balance_mesh = true;
bool balance_mesh_refine = true;
bool balance_mesh_coarse = false;
std::string file_format = ".pmf";
int main(int argc, char ** argv)
......@@ -26,18 +30,20 @@ int main(int argc, char ** argv)
// | ADJACENT_DUPLICATE | ADJACENT_HIDDEN | ADJACENT_VALID | ADJACENT_DIMENSION);
//m.RemTopologyCheck(THROW_EXCEPTION);
#if defined(USE_PARTITIONER)
std::vector<Storage::integer> nc(m.GetProcessorsNumber());
Partitioner p(&m);
if( true )
{
m.Barrier();
std::cout << "before on " << m.GetProcessorRank() << " " << m.NumberOfCells() << std::endl;
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "init before "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
//p.SetMethod(Partitioner::INNER_KMEANS,Partitioner::Partition);
p.SetMethod(Partitioner::Parmetis,Partitioner::Partition);
//p.SetMethod(Partitioner::Parmetis,Partitioner::Refine);
p.Evaluate();
m.Redistribute();
m.ReorderEmpty(CELL|FACE|EDGE|NODE);
std::cout << "after on " << m.GetProcessorRank() << " " << m.NumberOfCells() << std::endl;
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "init after "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
m.Barrier();
p.SetMethod(Partitioner::Parmetis,Partitioner::Repartition);
}
#endif
......@@ -47,6 +53,10 @@ int main(int argc, char ** argv)
//m.SetTopologyCheck(PROHIBIT_MULTILINE);
//m.SetTopologyCheck(PROHIBIT_MULTIPOLYGON);
TagInteger indicator = m.CreateTag("INDICATOR",DATA_INTEGER,CELL,NONE,1);
TagReal wgt = m.CreateTag("WEIGHT",DATA_REAL,CELL,NONE,1);
#if defined(USE_PARTITIONER)
p.SetWeight(wgt);
#endif
/*
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it)
indicator[*it] = 1;
......@@ -93,6 +103,9 @@ int main(int argc, char ** argv)
m.ClearFile();
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "start "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
int numref;
int refcnt = 0;
do
......@@ -120,6 +133,21 @@ int main(int argc, char ** argv)
numref = m.Integrate(numref);
if( numref )
{
#if defined(USE_PARTITIONER)
if( balance_mesh_refine && refcnt == 0)
{
m.Barrier();
am.ComputeWeightRefine(indicator,wgt);
p.SetWeight(wgt);
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "refine before "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
p.Evaluate();
m.Redistribute();
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "refine after "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
m.Barrier();
}
#endif
ncells = m.TotalNumberOf(CELL);
nfaces = m.TotalNumberOf(FACE);
nedges = m.TotalNumberOf(EDGE);
......@@ -179,6 +207,20 @@ int main(int argc, char ** argv)
numref = m.Integrate(numref);
if( numref )
{
#if defined(USE_PARTITIONER)
if( balance_mesh_coarse && refcnt == 0)
{
m.Barrier();
am.ComputeWeightCoarse(indicator,wgt);
p.SetWeight(wgt);
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "coarse before "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
p.Evaluate();
m.Redistribute();
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "coarse after "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
m.Barrier();
}
#endif
ncells = m.TotalNumberOf(CELL);
nfaces = m.TotalNumberOf(FACE);
nedges = m.TotalNumberOf(EDGE);
......@@ -215,25 +257,24 @@ int main(int argc, char ** argv)
#if defined(USE_PARTITIONER)
if( true )
if( balance_mesh )
{
m.Barrier();
std::cout << "before on " << m.GetProcessorRank() << " " << m.NumberOfCells() << std::endl;
p.SetWeight(Tag());
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "finish before "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
p.Evaluate();
//am.CheckParentSet(__FILE__,__LINE__);
//am.Repartition();
m.Redistribute();
//std::fstream fout("sets"+std::to_string(m.GetProcessorRank())+".txt",std::ios::out);
//am.ReportSets(fout);
//am.CheckParentSet(__FILE__,__LINE__);
std::cout << "after on " << m.GetProcessorRank() << " " << m.NumberOfCells() << std::endl;
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "finish after "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
m.Barrier();
}
#endif
std::fill(nc.begin(),nc.end(),0); nc[m.GetProcessorRank()] = m.NumberOfCells(); m.Integrate(&nc[0],nc.size()); if( !m.GetProcessorRank() ) {std::cout << "finish "; for(unsigned q = 0; q < nc.size(); ++q) std::cout << nc[q] << " "; std::cout << std::endl;}
if( true )
if( output_file )
{
TagInteger tag_owner = m.CreateTag("OWN",DATA_INTEGER,CELL,NONE,1);
TagInteger tag_owner0 = m.GetTag("OWNER_PROCESSOR");
......
......@@ -54,7 +54,7 @@
// 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_PARALLEL_WRITE_TIME
// this will revert Mesh::PrepareReceiveInner to always
// use MPI point to point functionality disregarding problem type
......
......@@ -679,7 +679,8 @@ namespace INMOST
}
wgtflag = have_vwgt + have_adjwgt*2;
wgtflag = have_vwgt*2 + have_adjwgt;
//std::cout << "wgtflag: " <<wgtflag << std::endl;
//debug_output = true;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment