mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 13:50:33 +05:00
Parallelize ImproveMesh
This commit is contained in:
parent
7e7a1bb98b
commit
c075cfb9c6
@ -542,6 +542,7 @@ namespace netgen
|
|||||||
DLL_HEADER void DoArchive (Archive & archive);
|
DLL_HEADER void DoArchive (Archive & archive);
|
||||||
///
|
///
|
||||||
DLL_HEADER void ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal = OPT_QUALITY);
|
DLL_HEADER void ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal = OPT_QUALITY);
|
||||||
|
DLL_HEADER void ImproveMeshSequential (const MeshingParameters & mp, OPTIMIZEGOAL goal = OPT_QUALITY);
|
||||||
|
|
||||||
///
|
///
|
||||||
void ImproveMeshJacobian (const MeshingParameters & mp, OPTIMIZEGOAL goal = OPT_QUALITY, const NgBitArray * usepoint = NULL);
|
void ImproveMeshJacobian (const MeshingParameters & mp, OPTIMIZEGOAL goal = OPT_QUALITY, const NgBitArray * usepoint = NULL);
|
||||||
|
@ -5,10 +5,13 @@
|
|||||||
#include <csg.hpp>
|
#include <csg.hpp>
|
||||||
#endif
|
#endif
|
||||||
#include <opti.hpp>
|
#include <opti.hpp>
|
||||||
|
#include <core/array.hpp>
|
||||||
|
#include <core/taskmanager.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
{
|
{
|
||||||
|
using namespace ngcore;
|
||||||
|
|
||||||
|
|
||||||
double MinFunctionSum :: Func (const Vector & x) const
|
double MinFunctionSum :: Func (const Vector & x) const
|
||||||
@ -301,7 +304,8 @@ namespace netgen
|
|||||||
public:
|
public:
|
||||||
Mesh::T_POINTS & points;
|
Mesh::T_POINTS & points;
|
||||||
const Array<Element> & elements;
|
const Array<Element> & elements;
|
||||||
TABLE<int,PointIndex::BASE> elementsonpoint;
|
TABLE<int,PointIndex::BASE> &elementsonpoint;
|
||||||
|
bool own_elementsonpoint;
|
||||||
const MeshingParameters & mp;
|
const MeshingParameters & mp;
|
||||||
PointIndex actpind;
|
PointIndex actpind;
|
||||||
double h;
|
double h;
|
||||||
@ -310,10 +314,12 @@ namespace netgen
|
|||||||
PointFunction (Mesh::T_POINTS & apoints,
|
PointFunction (Mesh::T_POINTS & apoints,
|
||||||
const Array<Element> & aelements,
|
const Array<Element> & aelements,
|
||||||
const MeshingParameters & amp);
|
const MeshingParameters & amp);
|
||||||
virtual ~PointFunction () { ; }
|
PointFunction (const PointFunction & pf);
|
||||||
|
virtual ~PointFunction () { if(own_elementsonpoint) delete &elementsonpoint; }
|
||||||
virtual void SetPointIndex (PointIndex aactpind);
|
virtual void SetPointIndex (PointIndex aactpind);
|
||||||
void SetLocalH (double ah) { h = ah; }
|
void SetLocalH (double ah) { h = ah; }
|
||||||
double GetLocalH () const { return h; }
|
double GetLocalH () const { return h; }
|
||||||
|
const TABLE<int,PointIndex::BASE> & GetPointToElementTable() { return elementsonpoint; };
|
||||||
virtual double PointFunctionValue (const Point<3> & pp) const;
|
virtual double PointFunctionValue (const Point<3> & pp) const;
|
||||||
virtual double PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const;
|
virtual double PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const;
|
||||||
virtual double PointFunctionValueDeriv (const Point<3> & pp, const Vec<3> & dir, double & deriv) const;
|
virtual double PointFunctionValueDeriv (const Point<3> & pp, const Vec<3> & dir, double & deriv) const;
|
||||||
@ -322,11 +328,16 @@ namespace netgen
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PointFunction :: PointFunction (const PointFunction & pf)
|
||||||
|
: points(pf.points), elements(pf.elements), elementsonpoint(pf.elementsonpoint), own_elementsonpoint(false), mp(pf.mp)
|
||||||
|
{ }
|
||||||
|
|
||||||
PointFunction :: PointFunction (Mesh::T_POINTS & apoints,
|
PointFunction :: PointFunction (Mesh::T_POINTS & apoints,
|
||||||
const Array<Element> & aelements,
|
const Array<Element> & aelements,
|
||||||
const MeshingParameters & amp)
|
const MeshingParameters & amp)
|
||||||
: points(apoints), elements(aelements), elementsonpoint(apoints.Size()), mp(amp)
|
: points(apoints), elements(aelements), elementsonpoint(* new TABLE<int,PointIndex::BASE>(apoints.Size())), own_elementsonpoint(true), mp(amp)
|
||||||
{
|
{
|
||||||
|
static Timer tim("PointFunction - build elementsonpoint table"); RegionTimer reg(tim);
|
||||||
for (int i = 0; i < elements.Size(); i++)
|
for (int i = 0; i < elements.Size(); i++)
|
||||||
if (elements[i].NP() == 4)
|
if (elements[i].NP() == 4)
|
||||||
for (int j = 0; j < elements[i].NP(); j++)
|
for (int j = 0; j < elements[i].NP(); j++)
|
||||||
@ -1359,7 +1370,7 @@ void Mesh :: ImproveMesh (const CSG eometry & geometry, OPTIMIZEGOAL goal)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal)
|
void Mesh :: ImproveMeshSequential (const MeshingParameters & mp, OPTIMIZEGOAL goal)
|
||||||
{
|
{
|
||||||
static Timer t("Mesh::ImproveMesh"); RegionTimer reg(t);
|
static Timer t("Mesh::ImproveMesh"); RegionTimer reg(t);
|
||||||
|
|
||||||
@ -1480,6 +1491,151 @@ void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal)
|
||||||
|
{
|
||||||
|
static Timer t("Mesh::ImproveMesh"); RegionTimer reg(t);
|
||||||
|
static Timer tcoloring("coloring");
|
||||||
|
static Timer tcalcbadmax("Calc badmax");
|
||||||
|
static Timer topt("optimize");
|
||||||
|
static Timer trange("range");
|
||||||
|
|
||||||
|
// return ImproveMeshSequential(mp, goal);
|
||||||
|
|
||||||
|
(*testout) << "Improve Mesh" << "\n";
|
||||||
|
PrintMessage (3, "ImproveMesh");
|
||||||
|
|
||||||
|
int np = GetNP();
|
||||||
|
int ne = GetNE();
|
||||||
|
|
||||||
|
PointFunction pf_glob(points, volelements, mp);
|
||||||
|
|
||||||
|
auto & elementsonpoint = pf_glob.GetPointToElementTable();
|
||||||
|
|
||||||
|
const auto & getDofs = [&] (int i)
|
||||||
|
{
|
||||||
|
i += PointIndex::BASE;
|
||||||
|
return FlatArray<int>(elementsonpoint[i].Size(), &elementsonpoint[i][0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Array<int> colors(points.Size());
|
||||||
|
|
||||||
|
tcoloring.Start();
|
||||||
|
int ncolors = ngcore::ComputeColoring( colors, ne, getDofs );
|
||||||
|
TableCreator<int> creator(ncolors);
|
||||||
|
for ( ; !creator.Done(); creator++)
|
||||||
|
{
|
||||||
|
ParallelForRange( Range(colors), [&](auto myrange)
|
||||||
|
{
|
||||||
|
for(auto i : myrange)
|
||||||
|
creator.Add(colors[i], i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto color_table = creator.MoveTable();
|
||||||
|
tcoloring.Stop();
|
||||||
|
|
||||||
|
if (goal == OPT_QUALITY)
|
||||||
|
{
|
||||||
|
double bad1 = CalcTotalBad (points, volelements, mp);
|
||||||
|
(*testout) << "Total badness = " << bad1 << endl;
|
||||||
|
PrintMessage (5, "Total badness = ", bad1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
(*testout) << setprecision(8);
|
||||||
|
|
||||||
|
NgArray<double, PointIndex::BASE> pointh (points.Size());
|
||||||
|
|
||||||
|
if(lochfunc)
|
||||||
|
{
|
||||||
|
for (PointIndex pi : points.Range())
|
||||||
|
pointh[pi] = GetH(points[pi]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointh = 0;
|
||||||
|
for (Element & el : VolumeElements())
|
||||||
|
{
|
||||||
|
double h = pow(el.Volume(points),1./3.);
|
||||||
|
for (PointIndex pi : el.PNums())
|
||||||
|
if (h > pointh[pi])
|
||||||
|
pointh[pi] = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * savetask = multithread.task;
|
||||||
|
multithread.task = "Smooth Mesh";
|
||||||
|
|
||||||
|
topt.Start();
|
||||||
|
int counter = 0;
|
||||||
|
for (int color : Range(color_table.Size()))
|
||||||
|
{
|
||||||
|
if (multithread.terminate)
|
||||||
|
throw NgException ("Meshing stopped");
|
||||||
|
|
||||||
|
ParallelForRange( Range(color_table[color].Size()), [&](auto myrange)
|
||||||
|
{
|
||||||
|
RegionTracer reg(ngcore::TaskManager::GetThreadId(), trange, myrange.Size());
|
||||||
|
Vector x(3);
|
||||||
|
|
||||||
|
PointFunction pf{pf_glob};
|
||||||
|
|
||||||
|
Opti3FreeMinFunction freeminf(pf);
|
||||||
|
|
||||||
|
OptiParameters par;
|
||||||
|
par.maxit_linsearch = 20;
|
||||||
|
par.maxit_bfgs = 20;
|
||||||
|
|
||||||
|
for (auto i : myrange)
|
||||||
|
{
|
||||||
|
PointIndex pi(color_table[color][i]+PointIndex::BASE);
|
||||||
|
if ( (*this)[pi].Type() == INNERPOINT )
|
||||||
|
{
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
double lh = pointh[pi];
|
||||||
|
pf.SetLocalH (lh);
|
||||||
|
par.typx = lh;
|
||||||
|
|
||||||
|
freeminf.SetPoint (points[pi]);
|
||||||
|
pf.SetPointIndex (pi);
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
int pok;
|
||||||
|
pok = freeminf.Func (x) < 1e10;
|
||||||
|
|
||||||
|
if (!pok)
|
||||||
|
{
|
||||||
|
pok = pf.MovePointToInner ();
|
||||||
|
|
||||||
|
freeminf.SetPoint (points[pi]);
|
||||||
|
pf.SetPointIndex (pi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pok)
|
||||||
|
{
|
||||||
|
//*testout << "start BFGS, pok" << endl;
|
||||||
|
BFGS (x, freeminf, par);
|
||||||
|
//*testout << "BFGS complete, pok" << endl;
|
||||||
|
points[pi](0) += x(0);
|
||||||
|
points[pi](1) += x(1);
|
||||||
|
points[pi](2) += x(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 4*ngcore::TaskManager::GetNumThreads());
|
||||||
|
}
|
||||||
|
topt.Stop();
|
||||||
|
|
||||||
|
multithread.task = savetask;
|
||||||
|
|
||||||
|
if (goal == OPT_QUALITY)
|
||||||
|
{
|
||||||
|
double bad1 = CalcTotalBad (points, volelements, mp);
|
||||||
|
(*testout) << "Total badness = " << bad1 << endl;
|
||||||
|
PrintMessage (5, "Total badness = ", bad1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user