mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-24 04:50:34 +05:00
Merge branch 'parallel_meshing' into 'master'
Parallel meshing of 3d domains See merge request jschoeberl/netgen!393
This commit is contained in:
commit
d20a297cf1
@ -235,13 +235,14 @@ namespace ngcore
|
||||
const function<void(TaskInfo&)> * func;
|
||||
int mynr;
|
||||
int total;
|
||||
int producing_thread;
|
||||
atomic<int> * endcnt;
|
||||
|
||||
TNestedTask () { ; }
|
||||
TNestedTask (const function<void(TaskInfo&)> & _func,
|
||||
int _mynr, int _total,
|
||||
atomic<int> & _endcnt)
|
||||
: func(&_func), mynr(_mynr), total(_total), endcnt(&_endcnt)
|
||||
atomic<int> & _endcnt, int prod_tid)
|
||||
: func(&_func), mynr(_mynr), total(_total), endcnt(&_endcnt), producing_thread(prod_tid)
|
||||
{
|
||||
;
|
||||
}
|
||||
@ -260,12 +261,14 @@ namespace ngcore
|
||||
TPToken ptoken(taskqueue);
|
||||
|
||||
int num = endcnt;
|
||||
auto tid = TaskManager::GetThreadId();
|
||||
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()
|
||||
{
|
||||
static Timer t("process task");
|
||||
TNestedTask task;
|
||||
TCToken ctoken(taskqueue);
|
||||
|
||||
@ -282,8 +285,14 @@ namespace ngcore
|
||||
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.endcnt;
|
||||
|
||||
if(trace && task.producing_thread != ti.thread_nr)
|
||||
trace->StopTask (ti.thread_nr, t);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
51
libsrc/meshing/debugging.hpp
Normal file
51
libsrc/meshing/debugging.hpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -235,9 +235,11 @@ namespace netgen
|
||||
NgArray<int> & freelist, SphereList & list,
|
||||
IndexSet & insphere, IndexSet & closesphere, Array<DelaunayTet> & newels)
|
||||
{
|
||||
static Timer t("Meshing3::AddDelaunayPoint");// RegionTimer reg(t);
|
||||
// static Timer tsearch("addpoint, search");
|
||||
// static Timer tinsert("addpoint, insert");
|
||||
static Timer t("Meshing3::AddDelaunayPoint", NoTracing, NoTiming); RegionTimer reg(t);
|
||||
static Timer tsearch("addpoint, search", NoTracing, NoTiming);
|
||||
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
|
||||
@ -277,7 +279,7 @@ namespace netgen
|
||||
}
|
||||
*/
|
||||
|
||||
// tsearch.Start();
|
||||
tsearch.Start();
|
||||
double minquot{1e20};
|
||||
tettree.GetFirstIntersecting
|
||||
(newp, newp, [&](const auto pi)
|
||||
@ -300,7 +302,7 @@ namespace netgen
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
// tsearch.Stop();
|
||||
tsearch.Stop();
|
||||
|
||||
if (cfelind == -1)
|
||||
{
|
||||
@ -308,6 +310,7 @@ namespace netgen
|
||||
return;
|
||||
}
|
||||
|
||||
tfind.Start();
|
||||
/*
|
||||
insphere: point is in sphere -> delete element
|
||||
closesphere: point is close to sphere -> considered for same center
|
||||
@ -399,6 +402,8 @@ namespace netgen
|
||||
}
|
||||
} // while (changed)
|
||||
|
||||
tfind.Stop();
|
||||
tnewtets.Start();
|
||||
newels.SetSize(0);
|
||||
|
||||
Element2d face(TRIG);
|
||||
@ -553,10 +558,11 @@ namespace netgen
|
||||
tpmax.SetToMax (*pp[k]);
|
||||
}
|
||||
tpmax = tpmax + 0.01 * (tpmax - tpmin);
|
||||
// tinsert.Start();
|
||||
tinsert.Start();
|
||||
tettree.Insert (tpmin, tpmax, nelind);
|
||||
// tinsert.Stop();
|
||||
tinsert.Stop();
|
||||
}
|
||||
tnewtets.Stop();
|
||||
}
|
||||
|
||||
|
||||
@ -1627,20 +1633,20 @@ namespace netgen
|
||||
// tempmesh.Save ("tempmesh.vol");
|
||||
|
||||
{
|
||||
MeshOptimize3d meshopt(mp);
|
||||
tempmesh.Compress();
|
||||
tempmesh.FindOpenElements ();
|
||||
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());
|
||||
tempmesh.CalcSurfacesOfNode ();
|
||||
|
||||
tempmesh.FreeOpenElementsEnvironment (1);
|
||||
if(i%5==0)
|
||||
tempmesh.FreeOpenElementsEnvironment (1);
|
||||
|
||||
MeshOptimize3d meshopt(mp);
|
||||
// tempmesh.CalcSurfacesOfNode();
|
||||
meshopt.SwapImprove(tempmesh, OPT_CONFORM);
|
||||
}
|
||||
tempmesh.Compress();
|
||||
}
|
||||
|
||||
MeshQuality3d (tempmesh);
|
||||
|
@ -1,15 +1,42 @@
|
||||
#ifndef 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>
|
||||
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 constexpr int tetedges[6][2] =
|
||||
{ { 0, 1 }, { 0, 2 }, { 0, 3 },
|
||||
{ 1, 2 }, { 1, 3 }, { 2, 3 } };
|
||||
|
||||
int ntasks = 4*ngcore::TaskManager::GetMaxThreads();
|
||||
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];
|
||||
if (elem.IsDeleted()) continue;
|
||||
|
||||
static_assert(is_same_v<TINDEX, ElementIndex>||is_same_v<TINDEX,SurfaceElementIndex>, "Invalid type for TINDEX");
|
||||
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));
|
||||
}
|
||||
}
|
||||
AppendEdges(elem, pi, local_edges);
|
||||
}
|
||||
QuickSort(local_edges);
|
||||
|
||||
|
@ -2717,8 +2717,24 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
|
||||
int ne = mesh.GetNE();
|
||||
|
||||
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;
|
||||
|
||||
@ -2736,7 +2752,7 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
|
||||
const Element2d & hel = mesh.OpenElement(i);
|
||||
INDEX_3 face(hel[0], hel[1], hel[2]);
|
||||
face.Sort();
|
||||
faces.Set (face, 1);
|
||||
faces.Set (face, i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2755,6 +2771,8 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
|
||||
|
||||
tloop.Start();
|
||||
|
||||
auto num_elements_before = mesh.VolumeElements().Range().Next();
|
||||
|
||||
ParallelForRange(Range(edges), [&] (auto myrange)
|
||||
{
|
||||
for(auto i : myrange)
|
||||
@ -2786,6 +2804,30 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal,
|
||||
|
||||
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 ();
|
||||
|
||||
multithread.task = savetask;
|
||||
|
@ -91,6 +91,45 @@ namespace netgen
|
||||
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;
|
||||
}
|
||||
|
||||
void LocalH :: Delete ()
|
||||
{
|
||||
root->DeleteChilds();
|
||||
@ -405,8 +444,8 @@ namespace netgen
|
||||
void LocalH :: FindInnerBoxes (AdFront3 * adfront,
|
||||
int (*testinner)(const Point3d & p1))
|
||||
{
|
||||
static int timer = NgProfiler::CreateTimer ("LocalH::FindInnerBoxes");
|
||||
NgProfiler::RegionTimer reg (timer);
|
||||
static Timer timer("LocalH::FindInnerBoxes");
|
||||
RegionTimer reg (timer);
|
||||
|
||||
|
||||
int nf = adfront->GetNF();
|
||||
@ -812,6 +851,7 @@ namespace netgen
|
||||
|
||||
void LocalH :: GetOuterPoints (NgArray<Point<3> > & points)
|
||||
{
|
||||
static Timer t("LocalH::GetOuterPoints"); RegionTimer rt(t);
|
||||
for (int i = 0; i < boxes.Size(); i++)
|
||||
if (!boxes[i]->flags.isinner && !boxes[i]->flags.cutboundary)
|
||||
points.Append ( boxes[i] -> PMid());
|
||||
|
@ -98,6 +98,8 @@ namespace netgen
|
||||
|
||||
~LocalH();
|
||||
///
|
||||
unique_ptr<LocalH> Copy();
|
||||
///
|
||||
void Delete();
|
||||
///
|
||||
void DoArchive(Archive& ar);
|
||||
|
@ -384,6 +384,8 @@ namespace netgen
|
||||
volelements.Append (el);
|
||||
}
|
||||
volelements.Last().flags.illegal_valid = 0;
|
||||
volelements.Last().flags.fixed = 0;
|
||||
volelements.Last().flags.deleted = 0;
|
||||
|
||||
// while (volelements.Size() > eltyps.Size())
|
||||
// eltyps.Append (FREEELEMENT);
|
||||
@ -405,6 +407,8 @@ namespace netgen
|
||||
|
||||
volelements[ei] = el;
|
||||
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
|
||||
{
|
||||
static Timer timer("Mesh::Save"); RegionTimer rt(timer);
|
||||
int i, j;
|
||||
|
||||
double scale = 1; // globflags.GetNumFlag ("scale", 1);
|
||||
@ -2910,6 +2915,7 @@ namespace netgen
|
||||
|
||||
void Mesh :: FreeOpenElementsEnvironment (int layers)
|
||||
{
|
||||
static Timer timer("FreeOpenElementsEnvironment"); RegionTimer rt(timer);
|
||||
int i, j, k;
|
||||
PointIndex pi;
|
||||
const int large = 9999;
|
||||
@ -6570,6 +6576,8 @@ namespace netgen
|
||||
[&](auto & table, ElementIndex ei)
|
||||
{
|
||||
const auto & el = (*this)[ei];
|
||||
if(el.IsDeleted())
|
||||
return;
|
||||
|
||||
for (PointIndex pi : el.PNums())
|
||||
if(free_points[pi])
|
||||
@ -6581,6 +6589,8 @@ namespace netgen
|
||||
[&](auto & table, ElementIndex ei)
|
||||
{
|
||||
const auto & el = (*this)[ei];
|
||||
if(el.IsDeleted())
|
||||
return;
|
||||
|
||||
for (PointIndex pi : el.PNums())
|
||||
table.Add (pi, ei);
|
||||
|
@ -486,6 +486,8 @@ namespace netgen
|
||||
{ return openelements.Get(i); }
|
||||
|
||||
auto & OpenElements() const { return openelements; }
|
||||
|
||||
auto & OpenElements() { return openelements; }
|
||||
|
||||
/// are also quads open elements
|
||||
bool HasOpenQuads () const;
|
||||
@ -510,6 +512,11 @@ namespace netgen
|
||||
return boundaryedges->Used (i2);
|
||||
}
|
||||
|
||||
void DeleteBoundaryEdges ()
|
||||
{
|
||||
boundaryedges = nullptr;
|
||||
}
|
||||
|
||||
bool IsSegment (PointIndex pi1, PointIndex pi2) const
|
||||
{
|
||||
INDEX_2 i2 (pi1, pi2);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1094,11 +1094,10 @@ static int TestSameSide (const Point3d & p1, const Point3d & p2)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void Meshing3 :: BlockFillLocalH (Mesh & mesh,
|
||||
void Meshing3 :: PrepareBlockFillLocalH (Mesh & mesh,
|
||||
const MeshingParameters & mp)
|
||||
{
|
||||
static Timer t("Mesing3::BlockFillLocalH"); RegionTimer reg(t);
|
||||
static Timer t("Mesing3::PrepareBlockFillLocalH"); RegionTimer reg(t);
|
||||
|
||||
double filldist = mp.filldist;
|
||||
|
||||
@ -1107,10 +1106,95 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
|
||||
PrintMessage (3, "blockfill local h");
|
||||
|
||||
|
||||
NgArray<Point<3> > npoints;
|
||||
|
||||
adfront -> CreateTrees();
|
||||
|
||||
double maxh = 0;
|
||||
|
||||
for (int i = 1; i <= adfront->GetNF(); i++)
|
||||
{
|
||||
const MiniElement2d & el = adfront->GetFace(i);
|
||||
for (int j = 1; j <= 3; j++)
|
||||
{
|
||||
const Point3d & p1 = adfront->GetPoint (el.PNumMod(j));
|
||||
const Point3d & p2 = adfront->GetPoint (el.PNumMod(j+1));
|
||||
|
||||
double hi = Dist (p1, p2);
|
||||
if (hi > maxh) maxh = hi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mp.maxh < maxh) maxh = mp.maxh;
|
||||
|
||||
// auto loch_ptr = mesh.LocalHFunction().Copy();
|
||||
// auto & loch = *loch_ptr;
|
||||
auto & loch = mesh.LocalHFunction();
|
||||
|
||||
bool changed;
|
||||
static Timer t1("loop1");
|
||||
t1.Start();
|
||||
do
|
||||
{
|
||||
loch.ClearFlags();
|
||||
|
||||
static Timer tbox("adfront-bbox");
|
||||
tbox.Start();
|
||||
for (int i = 1; i <= adfront->GetNF(); i++)
|
||||
{
|
||||
const MiniElement2d & el = adfront->GetFace(i);
|
||||
|
||||
Box<3> bbox (adfront->GetPoint (el[0]));
|
||||
bbox.Add (adfront->GetPoint (el[1]));
|
||||
bbox.Add (adfront->GetPoint (el[2]));
|
||||
|
||||
|
||||
double filld = filldist * bbox.Diam();
|
||||
bbox.Increase (filld);
|
||||
|
||||
loch.CutBoundary (bbox); // .PMin(), bbox.PMax());
|
||||
}
|
||||
tbox.Stop();
|
||||
|
||||
// locadfront = adfront;
|
||||
loch.FindInnerBoxes (adfront, NULL);
|
||||
|
||||
npoints.SetSize(0);
|
||||
loch.GetInnerPoints (npoints);
|
||||
|
||||
changed = false;
|
||||
for (int i = 1; i <= npoints.Size(); i++)
|
||||
{
|
||||
if (loch.GetH(npoints.Get(i)) > 1.5 * maxh)
|
||||
{
|
||||
loch.SetH (npoints.Get(i), maxh);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (changed);
|
||||
t1.Stop();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Meshing3 :: BlockFillLocalH (Mesh & mesh,
|
||||
const MeshingParameters & mp)
|
||||
{
|
||||
static Timer t("Mesing3::BlockFillLocalH"); RegionTimer reg(t);
|
||||
|
||||
if (!mesh.HasLocalHFunction())
|
||||
{
|
||||
mesh.CalcLocalH(mp.grading);
|
||||
PrepareBlockFillLocalH(mesh, mp);
|
||||
}
|
||||
|
||||
double filldist = mp.filldist;
|
||||
|
||||
// (*testout) << "blockfill local h" << endl;
|
||||
// (*testout) << "rel filldist = " << filldist << endl;
|
||||
PrintMessage (3, "blockfill local h");
|
||||
|
||||
Box<3> bbox ( Box<3>::EMPTY_BOX );
|
||||
double maxh = 0;
|
||||
|
||||
@ -1144,44 +1228,6 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
|
||||
|
||||
if (mp.maxh < maxh) maxh = mp.maxh;
|
||||
|
||||
bool changed;
|
||||
do
|
||||
{
|
||||
mesh.LocalHFunction().ClearFlags();
|
||||
|
||||
for (int i = 1; i <= adfront->GetNF(); i++)
|
||||
{
|
||||
const MiniElement2d & el = adfront->GetFace(i);
|
||||
|
||||
Box<3> bbox (adfront->GetPoint (el[0]));
|
||||
bbox.Add (adfront->GetPoint (el[1]));
|
||||
bbox.Add (adfront->GetPoint (el[2]));
|
||||
|
||||
|
||||
double filld = filldist * bbox.Diam();
|
||||
bbox.Increase (filld);
|
||||
|
||||
mesh.LocalHFunction().CutBoundary (bbox); // .PMin(), bbox.PMax());
|
||||
}
|
||||
|
||||
// locadfront = adfront;
|
||||
mesh.LocalHFunction().FindInnerBoxes (adfront, NULL);
|
||||
|
||||
npoints.SetSize(0);
|
||||
mesh.LocalHFunction().GetInnerPoints (npoints);
|
||||
|
||||
changed = false;
|
||||
for (int i = 1; i <= npoints.Size(); i++)
|
||||
{
|
||||
if (mesh.LocalHFunction().GetH(npoints.Get(i)) > 1.5 * maxh)
|
||||
{
|
||||
mesh.LocalHFunction().SetH (npoints.Get(i), maxh);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (changed);
|
||||
|
||||
if (debugparam.slowchecks)
|
||||
(*testout) << "Blockfill with points: " << endl;
|
||||
for (int i = 1; i <= npoints.Size(); i++)
|
||||
@ -1208,6 +1254,8 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
|
||||
|
||||
// find outer points
|
||||
|
||||
static Timer tloch2("build loch2");
|
||||
tloch2.Start();
|
||||
loch2.ClearFlags();
|
||||
|
||||
for (int i = 1; i <= adfront->GetNF(); i++)
|
||||
@ -1245,6 +1293,7 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh,
|
||||
// loch2.CutBoundary (pmin, pmax);
|
||||
loch2.CutBoundary (Box<3> (pmin, pmax)); // pmin, pmax);
|
||||
}
|
||||
tloch2.Stop();
|
||||
|
||||
// locadfront = adfront;
|
||||
loch2.FindInnerBoxes (adfront, NULL);
|
||||
|
@ -28,6 +28,7 @@ class Meshing3
|
||||
NgArray<char*> problems;
|
||||
/// tolerance criterion
|
||||
double tolfak;
|
||||
NgArray<Point<3> > npoints;
|
||||
public:
|
||||
///
|
||||
Meshing3 (const string & rulefilename);
|
||||
@ -63,6 +64,7 @@ public:
|
||||
///
|
||||
void BlockFill (Mesh & mesh, double gh);
|
||||
///
|
||||
void PrepareBlockFillLocalH (Mesh & mesh, const MeshingParameters & mp);
|
||||
void BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp);
|
||||
|
||||
/// uses points of adfront, and puts new elements into mesh
|
||||
|
@ -852,13 +852,24 @@ namespace netgen
|
||||
{ _np = np; _typ = typ; _curved = is_curved; }
|
||||
// ar & _np & _typ & index & _curved;
|
||||
ar.DoPacked (_np, _typ, index, _curved);
|
||||
if (ar.Input())
|
||||
{ np = _np; typ = ELEMENT_TYPE(_typ); is_curved = _curved; }
|
||||
|
||||
/*
|
||||
for (size_t i = 0; i < np; i++)
|
||||
ar & pnum[i];
|
||||
*/
|
||||
if (ar.Input())
|
||||
{
|
||||
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));
|
||||
ar.Do( (int*)&pnum[0], np);
|
||||
}
|
||||
|
@ -134,6 +134,7 @@ void ResetStatus()
|
||||
|
||||
void PushStatus(const MyStr& s)
|
||||
{
|
||||
return;
|
||||
msgstatus_stack.Append(new MyStr (s));
|
||||
SetStatMsg(s);
|
||||
threadpercent_stack.Append(0);
|
||||
@ -141,6 +142,7 @@ void PushStatus(const MyStr& s)
|
||||
|
||||
void PushStatusF(const MyStr& s)
|
||||
{
|
||||
return;
|
||||
msgstatus_stack.Append(new MyStr (s));
|
||||
SetStatMsg(s);
|
||||
threadpercent_stack.Append(0);
|
||||
@ -149,6 +151,7 @@ void PushStatusF(const MyStr& s)
|
||||
|
||||
void PopStatus()
|
||||
{
|
||||
return;
|
||||
if (msgstatus_stack.Size())
|
||||
{
|
||||
if (msgstatus_stack.Size() > 1)
|
||||
|
@ -15,7 +15,6 @@ def readData(a, files):
|
||||
file=[]
|
||||
for f in files:
|
||||
for t in a[f]:
|
||||
file.append(f)
|
||||
if t['ne1d']>0:
|
||||
ne1d.append(t['ne1d'])
|
||||
if t['ne2d']>0:
|
||||
@ -24,6 +23,7 @@ def readData(a, files):
|
||||
ne3d.append(t['ne3d'])
|
||||
if t['total_badness']>0.0:
|
||||
bad.append(t['total_badness'])
|
||||
file.append(f)
|
||||
if 'angles_tet' in t:
|
||||
amin.append(t['angles_tet'][0])
|
||||
amax.append(t['angles_tet'][1])
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -87,19 +87,23 @@ def test_pickle_geom2d():
|
||||
|
||||
def test_pickle_mesh():
|
||||
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))
|
||||
mesh = geo.GenerateMesh(maxh=0.2)
|
||||
assert geo == mesh.GetGeometry()
|
||||
dump = pickle.dumps([geo,mesh])
|
||||
geo2, mesh2 = pickle.loads(dump)
|
||||
assert geo2 == mesh2.GetGeometry()
|
||||
mesh.Save("msh1.vol.gz")
|
||||
mesh2.Save("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")
|
||||
geo2.Add(brick)
|
||||
|
||||
for geo in [geo1, geo2]:
|
||||
mesh = geo.GenerateMesh(maxh=2)
|
||||
assert geo == mesh.GetGeometry()
|
||||
dump = pickle.dumps([geo,mesh])
|
||||
geo2, mesh2 = pickle.loads(dump)
|
||||
assert geo2 == mesh2.GetGeometry()
|
||||
mesh.Save("msh1.vol.gz")
|
||||
mesh2.Save("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__":
|
||||
test_pickle_mesh()
|
||||
|
Loading…
Reference in New Issue
Block a user