Merge branch 'parallel_meshing' into 'master'

Parallel meshing

See merge request jschoeberl/netgen!398
This commit is contained in:
Joachim Schöberl 2021-07-20 05:40:19 +00:00
commit ee0bca464f
15 changed files with 1175 additions and 1066 deletions

View File

@ -235,13 +235,14 @@ namespace ngcore
const function<void(TaskInfo&)> * func; const function<void(TaskInfo&)> * func;
int mynr; int mynr;
int total; int total;
int producing_thread;
atomic<int> * endcnt; atomic<int> * endcnt;
TNestedTask () { ; } TNestedTask () { ; }
TNestedTask (const function<void(TaskInfo&)> & _func, TNestedTask (const function<void(TaskInfo&)> & _func,
int _mynr, int _total, int _mynr, int _total,
atomic<int> & _endcnt) atomic<int> & _endcnt, int prod_tid)
: func(&_func), mynr(_mynr), total(_total), endcnt(&_endcnt) : func(&_func), mynr(_mynr), total(_total), endcnt(&_endcnt), producing_thread(prod_tid)
{ {
; ;
} }
@ -260,12 +261,14 @@ namespace ngcore
TPToken ptoken(taskqueue); TPToken ptoken(taskqueue);
int num = endcnt; int num = endcnt;
auto tid = TaskManager::GetThreadId();
for (int i = 0; i < num; i++) for (int i = 0; i < num; i++)
taskqueue.enqueue (ptoken, { afunc, i, num, endcnt }); taskqueue.enqueue (ptoken, { afunc, i, num, endcnt, tid });
} }
bool TaskManager :: ProcessTask() bool TaskManager :: ProcessTask()
{ {
static Timer t("process task");
TNestedTask task; TNestedTask task;
TCToken ctoken(taskqueue); TCToken ctoken(taskqueue);
@ -282,8 +285,14 @@ namespace ngcore
cout << "process nested, nr = " << ti.task_nr << "/" << ti.ntasks << endl; cout << "process nested, nr = " << ti.task_nr << "/" << ti.ntasks << endl;
} }
*/ */
if(trace && task.producing_thread != ti.thread_nr)
trace->StartTask (ti.thread_nr, t, PajeTrace::Task::ID_TIMER, task.producing_thread);
(*task.func)(ti); (*task.func)(ti);
--*task.endcnt; --*task.endcnt;
if(trace && task.producing_thread != ti.thread_nr)
trace->StopTask (ti.thread_nr, t);
return true; return true;
} }
return false; return false;

View File

@ -0,0 +1,51 @@
#include <meshclass.hpp>
namespace netgen
{
inline unique_ptr<Mesh> GetOpenElements( const Mesh & m, int dom = 0 )
{
static Timer t("GetOpenElements"); RegionTimer rt(t);
auto mesh = make_unique<Mesh>();
*mesh = m;
Array<bool, PointIndex> interesting_points(mesh->GetNP());
interesting_points = false;
mesh->FindOpenElements(dom);
NgArray<Element2d> openelements;
openelements = mesh->OpenElements();
for (auto & el : openelements)
for (auto i : el.PNums())
interesting_points[i] = true;
for (auto & el : mesh->VolumeElements())
{
int num_interesting_points = 0;
for (auto pi : el.PNums())
if(interesting_points[pi])
num_interesting_points++;
if(num_interesting_points==0)
el.Delete();
el.SetIndex(num_interesting_points);
}
mesh->SetMaterial(1, "1_point");
mesh->SetMaterial(2, "2_points");
mesh->SetMaterial(3, "3_points");
mesh->SetMaterial(4, "4_points");
mesh->Compress();
mesh->ClearSurfaceElements();
for (auto & el : openelements)
mesh->AddSurfaceElement( el );
return mesh;
}
}

View File

@ -235,9 +235,11 @@ namespace netgen
NgArray<int> & freelist, SphereList & list, NgArray<int> & freelist, SphereList & list,
IndexSet & insphere, IndexSet & closesphere, Array<DelaunayTet> & newels) IndexSet & insphere, IndexSet & closesphere, Array<DelaunayTet> & newels)
{ {
static Timer t("Meshing3::AddDelaunayPoint");// RegionTimer reg(t); static Timer t("Meshing3::AddDelaunayPoint", NoTracing, NoTiming); RegionTimer reg(t);
// static Timer tsearch("addpoint, search"); static Timer tsearch("addpoint, search", NoTracing, NoTiming);
// static Timer tinsert("addpoint, insert"); static Timer tfind("addpoint, find all tets", NoTracing, NoTiming);
static Timer tnewtets("addpoint, build new tets", NoTracing, NoTiming);
static Timer tinsert("addpoint, insert", NoTracing, NoTiming);
/* /*
find any sphere, such that newp is contained in find any sphere, such that newp is contained in
@ -277,7 +279,7 @@ namespace netgen
} }
*/ */
// tsearch.Start(); tsearch.Start();
double minquot{1e20}; double minquot{1e20};
tettree.GetFirstIntersecting tettree.GetFirstIntersecting
(newp, newp, [&](const auto pi) (newp, newp, [&](const auto pi)
@ -300,7 +302,7 @@ namespace netgen
} }
return false; return false;
} ); } );
// tsearch.Stop(); tsearch.Stop();
if (cfelind == -1) if (cfelind == -1)
{ {
@ -308,6 +310,7 @@ namespace netgen
return; return;
} }
tfind.Start();
/* /*
insphere: point is in sphere -> delete element insphere: point is in sphere -> delete element
closesphere: point is close to sphere -> considered for same center closesphere: point is close to sphere -> considered for same center
@ -399,6 +402,8 @@ namespace netgen
} }
} // while (changed) } // while (changed)
tfind.Stop();
tnewtets.Start();
newels.SetSize(0); newels.SetSize(0);
Element2d face(TRIG); Element2d face(TRIG);
@ -553,10 +558,11 @@ namespace netgen
tpmax.SetToMax (*pp[k]); tpmax.SetToMax (*pp[k]);
} }
tpmax = tpmax + 0.01 * (tpmax - tpmin); tpmax = tpmax + 0.01 * (tpmax - tpmin);
// tinsert.Start(); tinsert.Start();
tettree.Insert (tpmin, tpmax, nelind); tettree.Insert (tpmin, tpmax, nelind);
// tinsert.Stop(); tinsert.Stop();
} }
tnewtets.Stop();
} }
@ -1539,7 +1545,7 @@ namespace netgen
PrintMessage (1, "Delaunay meshing"); PrintMessage (1, "Delaunay meshing");
PrintMessage (3, "number of points: ", mesh.GetNP()); PrintMessage (3, "number of points: ", mesh.GetNP());
PushStatus ("Delaunay meshing"); // PushStatus ("Delaunay meshing");
NgArray<DelaunayTet> tempels; NgArray<DelaunayTet> tempels;
@ -1627,20 +1633,20 @@ namespace netgen
// tempmesh.Save ("tempmesh.vol"); // tempmesh.Save ("tempmesh.vol");
{ {
MeshOptimize3d meshopt(mp);
tempmesh.Compress();
tempmesh.FindOpenElements ();
RegionTaskManager rtm(mp.parallel_meshing ? mp.nthreads : 0); RegionTaskManager rtm(mp.parallel_meshing ? mp.nthreads : 0);
for (int i = 1; i <= 4; i++) for (auto i : Range(10))
{ {
tempmesh.FindOpenElements ();
PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements());
tempmesh.CalcSurfacesOfNode ();
tempmesh.FreeOpenElementsEnvironment (1); if(i%5==0)
tempmesh.FreeOpenElementsEnvironment (1);
MeshOptimize3d meshopt(mp);
// tempmesh.CalcSurfacesOfNode();
meshopt.SwapImprove(tempmesh, OPT_CONFORM); meshopt.SwapImprove(tempmesh, OPT_CONFORM);
} }
tempmesh.Compress();
} }
MeshQuality3d (tempmesh); MeshQuality3d (tempmesh);
@ -1669,6 +1675,6 @@ namespace netgen
mesh.FindOpenElements(domainnr); mesh.FindOpenElements(domainnr);
mesh.Compress(); mesh.Compress();
PopStatus (); // PopStatus ();
} }
} }

View File

@ -1,15 +1,42 @@
#ifndef FILE_IMPROVE2 #ifndef FILE_IMPROVE2
#define FILE_IMPROVE2 #define FILE_IMPROVE2
inline void AppendEdges( const Element2d & elem, PointIndex pi, Array<std::tuple<PointIndex,PointIndex>> & edges )
{
for (int j = 0; j < 3; j++)
{
PointIndex pi0 = elem[j];
PointIndex pi1 = elem[(j+1)%3];
if (pi1 < pi0) Swap(pi0, pi1);
if(pi0==pi)
edges.Append(std::make_tuple(pi0, pi1));
}
}
inline void AppendEdges( const Element & elem, PointIndex pi, Array<std::tuple<PointIndex,PointIndex>> & edges )
{
static constexpr int tetedges[6][2] =
{ { 0, 1 }, { 0, 2 }, { 0, 3 },
{ 1, 2 }, { 1, 3 }, { 2, 3 } };
if(elem.flags.fixed)
return;
for (int j = 0; j < 6; j++)
{
PointIndex pi0 = elem[tetedges[j][0]];
PointIndex pi1 = elem[tetedges[j][1]];
if (pi1 < pi0) Swap(pi0, pi1);
if(pi0==pi)
edges.Append(std::make_tuple(pi0, pi1));
}
}
template<typename TINDEX> template<typename TINDEX>
void BuildEdgeList( const Mesh & mesh, const Table<TINDEX, PointIndex> & elementsonnode, Array<std::tuple<PointIndex, PointIndex>> & edges ) void BuildEdgeList( const Mesh & mesh, const Table<TINDEX, PointIndex> & elementsonnode, Array<std::tuple<PointIndex, PointIndex>> & edges )
{ {
static_assert(is_same_v<TINDEX, ElementIndex>||is_same_v<TINDEX,SurfaceElementIndex>, "Invalid type for TINDEX");
static Timer tbuild_edges("Build edges"); RegionTimer reg(tbuild_edges); static Timer tbuild_edges("Build edges"); RegionTimer reg(tbuild_edges);
static constexpr int tetedges[6][2] =
{ { 0, 1 }, { 0, 2 }, { 0, 3 },
{ 1, 2 }, { 1, 3 }, { 2, 3 } };
int ntasks = 4*ngcore::TaskManager::GetMaxThreads(); int ntasks = 4*ngcore::TaskManager::GetMaxThreads();
Array<Array<std::tuple<PointIndex,PointIndex>>> task_edges(ntasks); Array<Array<std::tuple<PointIndex,PointIndex>>> task_edges(ntasks);
@ -26,29 +53,7 @@ void BuildEdgeList( const Mesh & mesh, const Table<TINDEX, PointIndex> & element
const auto & elem = mesh[ei]; const auto & elem = mesh[ei];
if (elem.IsDeleted()) continue; if (elem.IsDeleted()) continue;
static_assert(is_same_v<TINDEX, ElementIndex>||is_same_v<TINDEX,SurfaceElementIndex>, "Invalid type for TINDEX"); AppendEdges(elem, pi, local_edges);
if constexpr(is_same_v<TINDEX, SurfaceElementIndex>)
{
for (int j = 0; j < 3; j++)
{
PointIndex pi0 = elem[j];
PointIndex pi1 = elem[(j+1)%3];
if (pi1 < pi0) Swap(pi0, pi1);
if(pi0==pi)
local_edges.Append(std::make_tuple(pi0, pi1));
}
}
else if constexpr(is_same_v<TINDEX, ElementIndex>)
{
for (int j = 0; j < 6; j++)
{
PointIndex pi0 = elem[tetedges[j][0]];
PointIndex pi1 = elem[tetedges[j][1]];
if (pi1 < pi0) Swap(pi0, pi1);
if(pi0==pi)
local_edges.Append(std::make_tuple(pi0, pi1));
}
}
} }
QuickSort(local_edges); QuickSort(local_edges);

View File

@ -2717,8 +2717,24 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
int ne = mesh.GetNE(); int ne = mesh.GetNE();
mesh.BuildBoundaryEdges(false); mesh.BuildBoundaryEdges(false);
BitArray free_points(mesh.GetNP()+PointIndex::BASE);
free_points.Clear();
auto elementsonnode = mesh.CreatePoint2ElementTable(); ParallelForRange(mesh.VolumeElements().Range(), [&] (auto myrange)
{
for (ElementIndex eli : myrange)
{
const auto & el = mesh[eli];
if(el.flags.fixed)
continue;
for (auto pi : el.PNums())
if(!free_points[pi])
free_points.SetBitAtomic(pi);
}
});
auto elementsonnode = mesh.CreatePoint2ElementTable(free_points);
NgArray<ElementIndex> hasbothpoints; NgArray<ElementIndex> hasbothpoints;
@ -2736,7 +2752,7 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
const Element2d & hel = mesh.OpenElement(i); const Element2d & hel = mesh.OpenElement(i);
INDEX_3 face(hel[0], hel[1], hel[2]); INDEX_3 face(hel[0], hel[1], hel[2]);
face.Sort(); face.Sort();
faces.Set (face, 1); faces.Set (face, i);
} }
} }
@ -2755,6 +2771,8 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
tloop.Start(); tloop.Start();
auto num_elements_before = mesh.VolumeElements().Range().Next();
ParallelForRange(Range(edges), [&] (auto myrange) ParallelForRange(Range(edges), [&] (auto myrange)
{ {
for(auto i : myrange) for(auto i : myrange)
@ -2786,6 +2804,30 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
PrintMessage (5, cnt, " swaps performed"); PrintMessage (5, cnt, " swaps performed");
if(goal == OPT_CONFORM)
{
// Remove open elements that were closed by new tets
auto & open_els = mesh.OpenElements();
for (auto & el : mesh.VolumeElements().Range( num_elements_before, mesh.VolumeElements().Range().Next() ))
{
for (auto i : Range(1,5))
{
Element2d sel;
el.GetFace(i, sel);
INDEX_3 face(sel[0], sel[1], sel[2]);
face.Sort();
if(faces.Used(face))
open_els[faces.Get(face)-1].Delete();
}
}
for(int i=open_els.Size()-1; i>=0; i--)
if(open_els[i].IsDeleted())
open_els.Delete(i);
mesh.DeleteBoundaryEdges();
}
mesh.Compress (); mesh.Compress ();
multithread.task = savetask; multithread.task = savetask;

View File

@ -91,6 +91,93 @@ namespace netgen
delete root; delete root;
} }
unique_ptr<LocalH> LocalH :: Copy ()
{
static Timer t("LocalH::Copy"); RegionTimer rt(t);
auto lh = make_unique<LocalH>(boundingbox, grading, dimension);
std::map<GradingBox*, GradingBox*> mapping;
lh->boxes.SetSize(boxes.Size());
for(auto i : boxes.Range())
{
lh->boxes[i] = new GradingBox();
auto & bnew = *lh->boxes[i];
auto & b = *boxes[i];
bnew.xmid[0] = b.xmid[0];
bnew.xmid[1] = b.xmid[1];
bnew.xmid[2] = b.xmid[2];
bnew.h2 = b.h2;
bnew.hopt = b.hopt;
bnew.flags = b.flags;
mapping[&b] = &bnew;
}
for(auto i : boxes.Range())
{
auto & bnew = *lh->boxes[i];
auto & b = *boxes[i];
for(auto k : Range(8))
{
if(b.childs[k])
bnew.childs[k] = mapping[b.childs[k]];
}
if(b.father)
bnew.father = mapping[b.father];
}
lh->root = mapping[root];
return lh;
}
unique_ptr<LocalH> LocalH :: Copy( const Box<3> & bbox )
{
static Timer t("LocalH::Copy with bounding box"); RegionTimer rt(t);
auto lh = make_unique<LocalH>(boundingbox, grading, dimension);
std::map<GradingBox*, GradingBox*> mapping;
lh->boxes.SetAllocSize(boxes.Size());
for(auto i : boxes.Range())
{
auto & b = *boxes[i];
auto h = b.H2();
Vec<3> vh = {h,h,h};
Box<3> box( b.PMid() - vh, b.PMid() + vh);
if(!box.Intersect(bbox))
continue;
lh->boxes.Append(new GradingBox());
auto & bnew = *lh->boxes.Last();
bnew.xmid[0] = b.xmid[0];
bnew.xmid[1] = b.xmid[1];
bnew.xmid[2] = b.xmid[2];
bnew.h2 = b.h2;
bnew.hopt = b.hopt;
bnew.flags = b.flags;
mapping[&b] = &bnew;
}
for(auto i : boxes.Range())
{
auto & b = *boxes[i];
if(mapping.count(&b)==0)
continue;
auto & bnew = *mapping[&b];
for(auto k : Range(8))
{
if(b.childs[k] && mapping.count(b.childs[k]))
bnew.childs[k] = mapping[b.childs[k]];
}
if(b.father && mapping.count(b.father))
bnew.father = mapping[b.father];
}
lh->root = mapping[root];
return lh;
}
void LocalH :: Delete () void LocalH :: Delete ()
{ {
root->DeleteChilds(); root->DeleteChilds();
@ -405,8 +492,8 @@ namespace netgen
void LocalH :: FindInnerBoxes (AdFront3 * adfront, void LocalH :: FindInnerBoxes (AdFront3 * adfront,
int (*testinner)(const Point3d & p1)) int (*testinner)(const Point3d & p1))
{ {
static int timer = NgProfiler::CreateTimer ("LocalH::FindInnerBoxes"); static Timer timer("LocalH::FindInnerBoxes");
NgProfiler::RegionTimer reg (timer); RegionTimer reg (timer);
int nf = adfront->GetNF(); int nf = adfront->GetNF();
@ -812,6 +899,7 @@ namespace netgen
void LocalH :: GetOuterPoints (NgArray<Point<3> > & points) void LocalH :: GetOuterPoints (NgArray<Point<3> > & points)
{ {
static Timer t("LocalH::GetOuterPoints"); RegionTimer rt(t);
for (int i = 0; i < boxes.Size(); i++) for (int i = 0; i < boxes.Size(); i++)
if (!boxes[i]->flags.isinner && !boxes[i]->flags.cutboundary) if (!boxes[i]->flags.isinner && !boxes[i]->flags.cutboundary)
points.Append ( boxes[i] -> PMid()); points.Append ( boxes[i] -> PMid());

View File

@ -98,6 +98,9 @@ namespace netgen
~LocalH(); ~LocalH();
/// ///
unique_ptr<LocalH> Copy();
unique_ptr<LocalH> Copy( const Box<3> & bbox );
///
void Delete(); void Delete();
/// ///
void DoArchive(Archive& ar); void DoArchive(Archive& ar);
@ -189,6 +192,8 @@ namespace netgen
/// ///
void ConvexifyRec (GradingBox * box); void ConvexifyRec (GradingBox * box);
unique_ptr<LocalH> CopyRec( const Box<3> & bbox, GradingBox * current );
friend ostream & operator<< (ostream & ost, const LocalH & loch); friend ostream & operator<< (ostream & ost, const LocalH & loch);
}; };

View File

@ -384,6 +384,8 @@ namespace netgen
volelements.Append (el); volelements.Append (el);
} }
volelements.Last().flags.illegal_valid = 0; volelements.Last().flags.illegal_valid = 0;
volelements.Last().flags.fixed = 0;
volelements.Last().flags.deleted = 0;
// while (volelements.Size() > eltyps.Size()) // while (volelements.Size() > eltyps.Size())
// eltyps.Append (FREEELEMENT); // eltyps.Append (FREEELEMENT);
@ -405,6 +407,8 @@ namespace netgen
volelements[ei] = el; volelements[ei] = el;
volelements[ei].flags.illegal_valid = 0; volelements[ei].flags.illegal_valid = 0;
volelements[ei].flags.fixed = 0;
volelements[ei].flags.deleted = 0;
} }
@ -436,6 +440,7 @@ namespace netgen
void Mesh :: Save (ostream & outfile) const void Mesh :: Save (ostream & outfile) const
{ {
static Timer timer("Mesh::Save"); RegionTimer rt(timer);
int i, j; int i, j;
double scale = 1; // globflags.GetNumFlag ("scale", 1); double scale = 1; // globflags.GetNumFlag ("scale", 1);
@ -2910,6 +2915,7 @@ namespace netgen
void Mesh :: FreeOpenElementsEnvironment (int layers) void Mesh :: FreeOpenElementsEnvironment (int layers)
{ {
static Timer timer("FreeOpenElementsEnvironment"); RegionTimer rt(timer);
int i, j, k; int i, j, k;
PointIndex pi; PointIndex pi;
const int large = 9999; const int large = 9999;
@ -6570,6 +6576,8 @@ namespace netgen
[&](auto & table, ElementIndex ei) [&](auto & table, ElementIndex ei)
{ {
const auto & el = (*this)[ei]; const auto & el = (*this)[ei];
if(el.IsDeleted())
return;
for (PointIndex pi : el.PNums()) for (PointIndex pi : el.PNums())
if(free_points[pi]) if(free_points[pi])
@ -6581,6 +6589,8 @@ namespace netgen
[&](auto & table, ElementIndex ei) [&](auto & table, ElementIndex ei)
{ {
const auto & el = (*this)[ei]; const auto & el = (*this)[ei];
if(el.IsDeleted())
return;
for (PointIndex pi : el.PNums()) for (PointIndex pi : el.PNums())
table.Add (pi, ei); table.Add (pi, ei);

View File

@ -487,6 +487,8 @@ namespace netgen
auto & OpenElements() const { return openelements; } auto & OpenElements() const { return openelements; }
auto & OpenElements() { return openelements; }
/// are also quads open elements /// are also quads open elements
bool HasOpenQuads () const; bool HasOpenQuads () const;
@ -510,6 +512,11 @@ namespace netgen
return boundaryedges->Used (i2); return boundaryedges->Used (i2);
} }
void DeleteBoundaryEdges ()
{
boundaryedges = nullptr;
}
bool IsSegment (PointIndex pi1, PointIndex pi2) const bool IsSegment (PointIndex pi1, PointIndex pi2) const
{ {
INDEX_2 i2 (pi1, pi2); INDEX_2 i2 (pi1, pi2);

File diff suppressed because it is too large Load Diff

View File

@ -1144,11 +1144,18 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
if (mp.maxh < maxh) maxh = mp.maxh; if (mp.maxh < maxh) maxh = mp.maxh;
auto loch_ptr = mesh.LocalHFunction().Copy(bbox);
auto & loch = *loch_ptr;
bool changed; bool changed;
static Timer t1("loop1");
t1.Start();
do do
{ {
mesh.LocalHFunction().ClearFlags(); loch.ClearFlags();
static Timer tbox("adfront-bbox");
tbox.Start();
for (int i = 1; i <= adfront->GetNF(); i++) for (int i = 1; i <= adfront->GetNF(); i++)
{ {
const MiniElement2d & el = adfront->GetFace(i); const MiniElement2d & el = adfront->GetFace(i);
@ -1161,26 +1168,28 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
double filld = filldist * bbox.Diam(); double filld = filldist * bbox.Diam();
bbox.Increase (filld); bbox.Increase (filld);
mesh.LocalHFunction().CutBoundary (bbox); // .PMin(), bbox.PMax()); loch.CutBoundary (bbox); // .PMin(), bbox.PMax());
} }
tbox.Stop();
// locadfront = adfront; // locadfront = adfront;
mesh.LocalHFunction().FindInnerBoxes (adfront, NULL); loch.FindInnerBoxes (adfront, NULL);
npoints.SetSize(0); npoints.SetSize(0);
mesh.LocalHFunction().GetInnerPoints (npoints); loch.GetInnerPoints (npoints);
changed = false; changed = false;
for (int i = 1; i <= npoints.Size(); i++) for (int i = 1; i <= npoints.Size(); i++)
{ {
if (mesh.LocalHFunction().GetH(npoints.Get(i)) > 1.5 * maxh) if (loch.GetH(npoints.Get(i)) > 1.5 * maxh)
{ {
mesh.LocalHFunction().SetH (npoints.Get(i), maxh); loch.SetH (npoints.Get(i), maxh);
changed = true; changed = true;
} }
} }
} }
while (changed); while (changed);
t1.Stop();
if (debugparam.slowchecks) if (debugparam.slowchecks)
(*testout) << "Blockfill with points: " << endl; (*testout) << "Blockfill with points: " << endl;
@ -1208,6 +1217,8 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
// find outer points // find outer points
static Timer tloch2("build loch2");
tloch2.Start();
loch2.ClearFlags(); loch2.ClearFlags();
for (int i = 1; i <= adfront->GetNF(); i++) for (int i = 1; i <= adfront->GetNF(); i++)
@ -1245,6 +1256,7 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
// loch2.CutBoundary (pmin, pmax); // loch2.CutBoundary (pmin, pmax);
loch2.CutBoundary (Box<3> (pmin, pmax)); // pmin, pmax); loch2.CutBoundary (Box<3> (pmin, pmax)); // pmin, pmax);
} }
tloch2.Stop();
// locadfront = adfront; // locadfront = adfront;
loch2.FindInnerBoxes (adfront, NULL); loch2.FindInnerBoxes (adfront, NULL);

View File

@ -852,13 +852,24 @@ namespace netgen
{ _np = np; _typ = typ; _curved = is_curved; } { _np = np; _typ = typ; _curved = is_curved; }
// ar & _np & _typ & index & _curved; // ar & _np & _typ & index & _curved;
ar.DoPacked (_np, _typ, index, _curved); ar.DoPacked (_np, _typ, index, _curved);
if (ar.Input())
{ np = _np; typ = ELEMENT_TYPE(_typ); is_curved = _curved; }
/* if (ar.Input())
for (size_t i = 0; i < np; i++) {
ar & pnum[i]; np = _np;
*/ typ = ELEMENT_TYPE(_typ);
is_curved = _curved;
flags.marked = 1;
flags.badel = 0;
flags.reverse = 0;
flags.illegal = 0;
flags.illegal_valid = 0;
flags.badness_valid = 0;
flags.refflag = 1;
flags.strongrefflag = false;
flags.deleted = 0;
flags.fixed = 0;
}
static_assert(sizeof(int) == sizeof (PointIndex)); static_assert(sizeof(int) == sizeof (PointIndex));
ar.Do( (int*)&pnum[0], np); ar.Do( (int*)&pnum[0], np);
} }

View File

@ -15,7 +15,6 @@ def readData(a, files):
file=[] file=[]
for f in files: for f in files:
for t in a[f]: for t in a[f]:
file.append(f)
if t['ne1d']>0: if t['ne1d']>0:
ne1d.append(t['ne1d']) ne1d.append(t['ne1d'])
if t['ne2d']>0: if t['ne2d']>0:
@ -24,6 +23,7 @@ def readData(a, files):
ne3d.append(t['ne3d']) ne3d.append(t['ne3d'])
if t['total_badness']>0.0: if t['total_badness']>0.0:
bad.append(t['total_badness']) bad.append(t['total_badness'])
file.append(f)
if 'angles_tet' in t: if 'angles_tet' in t:
amin.append(t['angles_tet'][0]) amin.append(t['angles_tet'][0])
amax.append(t['angles_tet'][1]) amax.append(t['angles_tet'][1])

File diff suppressed because it is too large Load Diff

View File

@ -87,19 +87,23 @@ def test_pickle_geom2d():
def test_pickle_mesh(): def test_pickle_mesh():
import netgen.csg as csg import netgen.csg as csg
geo = csg.CSGeometry() geo1 = csg.CSGeometry()
geo2 = csg.CSGeometry()
brick = csg.OrthoBrick(csg.Pnt(-3,-3,-3), csg.Pnt(3,3,3)) brick = csg.OrthoBrick(csg.Pnt(-3,-3,-3), csg.Pnt(3,3,3))
mesh = geo.GenerateMesh(maxh=0.2) geo2.Add(brick)
assert geo == mesh.GetGeometry()
dump = pickle.dumps([geo,mesh]) for geo in [geo1, geo2]:
geo2, mesh2 = pickle.loads(dump) mesh = geo.GenerateMesh(maxh=2)
assert geo2 == mesh2.GetGeometry() assert geo == mesh.GetGeometry()
mesh.Save("msh1.vol.gz") dump = pickle.dumps([geo,mesh])
mesh2.Save("msh2.vol.gz") geo2, mesh2 = pickle.loads(dump)
import filecmp, os assert geo2 == mesh2.GetGeometry()
assert filecmp.cmp("msh1.vol.gz", "msh2.vol.gz") mesh.Save("msh1.vol.gz")
os.remove("msh1.vol.gz") mesh2.Save("msh2.vol.gz")
os.remove("msh2.vol.gz") import filecmp, os
assert filecmp.cmp("msh1.vol.gz", "msh2.vol.gz")
os.remove("msh1.vol.gz")
os.remove("msh2.vol.gz")
if __name__ == "__main__": if __name__ == "__main__":
test_pickle_mesh() test_pickle_mesh()