Merge remote-tracking branch 'origin/master' into test_refactoring_meshing_design

This commit is contained in:
Matthias Hochsteger 2019-10-18 11:53:05 +02:00
commit 17dfd45609
22 changed files with 1835 additions and 1648 deletions

View File

@ -167,6 +167,11 @@ namespace ngcore
static void ngcore_signal_handler(int sig) static void ngcore_signal_handler(int sig)
{ {
static bool first_call = true;
if(!first_call)
exit(1); // avoid endless recursions if signals are caused by this handler
first_call = false;
switch(sig) switch(sig)
{ {
case SIGABRT: case SIGABRT:

View File

@ -15,7 +15,7 @@ namespace ngcore
{ {
std::ostream* testout = new std::ostream(nullptr); // NOLINT std::ostream* testout = new std::ostream(nullptr); // NOLINT
level::level_enum Logger::global_level; level::level_enum Logger::global_level = level::warn;
void Logger::log(level::level_enum level, std::string && s) void Logger::log(level::level_enum level, std::string && s)
{ {

View File

@ -15,6 +15,7 @@
#include "array.hpp" #include "array.hpp"
#include "paje_trace.hpp" #include "paje_trace.hpp"
#include "profiler.hpp"
namespace ngcore namespace ngcore
{ {
@ -1059,6 +1060,7 @@ public:
template <typename Tmask> template <typename Tmask>
int ComputeColoring( FlatArray<int> colors, size_t ndofs, Tmask const & getDofs) int ComputeColoring( FlatArray<int> colors, size_t ndofs, Tmask const & getDofs)
{ {
static Timer timer("ComputeColoring - "+Demangle(typeid(Tmask).name())); RegionTimer rt(timer);
static_assert(sizeof(unsigned int)==4, "Adapt type of mask array"); static_assert(sizeof(unsigned int)==4, "Adapt type of mask array");
auto n = colors.Size(); auto n = colors.Size();

View File

@ -15,10 +15,22 @@ namespace ngcore
// windows does demangling in typeid(T).name() // windows does demangling in typeid(T).name()
NGCORE_API std::string Demangle(const char* typeinfo) { return typeinfo; } NGCORE_API std::string Demangle(const char* typeinfo) { return typeinfo; }
#else #else
NGCORE_API std::string Demangle(const char* typeinfo) { int status; return abi::__cxa_demangle(typeinfo, NGCORE_API std::string Demangle(const char* typeinfo)
nullptr, {
nullptr, int status=0;
&status); } try
{
char *s = abi::__cxa_demangle(typeinfo, nullptr, nullptr, &status);
std::string result{s};
free(s);
return result;
}
catch( const std::exception & e )
{
GetLogger("utils")->warn("{}:{} cannot demangle {}, status: {}, error:{}", __FILE__, __LINE__, typeinfo, status, e.what());
}
return typeinfo;
}
#endif #endif
double seconds_per_tick = [] () noexcept double seconds_per_tick = [] () noexcept

View File

@ -96,12 +96,6 @@ void ParallelFor( int first, int next, const TFunc & f )
template<typename T>
inline atomic<T> & AsAtomic (T & d)
{
return reinterpret_cast<atomic<T>&> (d);
}
typedef void (*TaskManager)(std::function<void(int,int)>); typedef void (*TaskManager)(std::function<void(int,int)>);
typedef void (*Tracer)(string, bool); // false .. start, true .. stop typedef void (*Tracer)(string, bool); // false .. start, true .. stop

View File

@ -1,9 +1,289 @@
#include <mystdlib.h> #include <mystdlib.h>
#include "meshing.hpp" #include "meshing.hpp"
namespace netgen namespace netgen
{ {
template<int dim, typename T=INDEX, typename TSCAL=double>
class DelaunayTree
{
public:
// Number of entries per leaf
static constexpr int N = 100;
struct Node;
struct Leaf
{
Point<2*dim, TSCAL> p[N];
T index[N];
int n_elements;
int nr;
Leaf() : n_elements(0)
{ }
void Add( Array<Leaf*> &leaves, Array<T> &leaf_index, const Point<2*dim> &ap, T aindex )
{
p[n_elements] = ap;
index[n_elements] = aindex;
n_elements++;
if(leaf_index.Size()<aindex+1)
leaf_index.SetSize(aindex+1);
leaf_index[aindex] = nr;
}
};
struct Node
{
union
{
Node *children[2];
Leaf *leaf;
};
double sep;
int level;
Node()
: children{nullptr,nullptr}
{ }
~Node()
{ }
Leaf *GetLeaf() const
{
return children[1] ? nullptr : leaf;
}
};
private:
Node root;
Array<Leaf*> leaves;
Array<T> leaf_index;
Point<dim> global_min, global_max;
double tol;
size_t n_leaves;
size_t n_nodes;
BlockAllocator ball_nodes;
BlockAllocator ball_leaves;
public:
DelaunayTree (const Point<dim> & pmin, const Point<dim> & pmax)
: global_min(pmin), global_max(pmax), n_leaves(1), n_nodes(1), ball_nodes(sizeof(Node)), ball_leaves(sizeof(Leaf))
{
root.leaf = (Leaf*) ball_leaves.Alloc(); new (root.leaf) Leaf();
root.leaf->nr = 0;
leaves.Append(root.leaf);
root.level = 0;
tol = 1e-7 * Dist(pmax, pmin);
}
DelaunayTree (const Box<dim> & box)
: DelaunayTree(box.PMin(), box.PMax())
{ }
size_t GetNLeaves()
{
return n_leaves;
}
size_t GetNNodes()
{
return n_nodes;
}
template<typename TFunc>
void GetFirstIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
TFunc func=[](auto pi){return false;}) const
{
// static Timer timer("DelaunayTree::GetIntersecting"); RegionTimer rt(timer);
// static Timer timer1("DelaunayTree::GetIntersecting-LinearSearch");
ArrayMem<const Node*, 100> stack;
ArrayMem<int, 100> dir_stack;
Point<2*dim> tpmin, tpmax;
for (size_t i : IntRange(dim))
{
tpmin(i) = global_min(i);
tpmax(i) = pmax(i)+tol;
tpmin(i+dim) = pmin(i)-tol;
tpmax(i+dim) = global_max(i);
}
stack.SetSize(0);
stack.Append(&root);
dir_stack.SetSize(0);
dir_stack.Append(0);
while(stack.Size())
{
const Node *node = stack.Last();
stack.DeleteLast();
int dir = dir_stack.Last();
dir_stack.DeleteLast();
if(Leaf *leaf = node->GetLeaf())
{
// RegionTimer rt1(timer1);
for (auto i : IntRange(leaf->n_elements))
{
bool intersect = true;
const auto p = leaf->p[i];
for (int d = 0; d < dim; d++)
if (p[d] > tpmax[d])
intersect = false;
for (int d = dim; d < 2*dim; d++)
if (p[d] < tpmin[d])
intersect = false;
if(intersect)
if(func(leaf->index[i])) return;
}
}
else
{
int newdir = dir+1;
if(newdir==2*dim) newdir = 0;
if (tpmin[dir] <= node->sep)
{
stack.Append(node->children[0]);
dir_stack.Append(newdir);
}
if (tpmax[dir] >= node->sep)
{
stack.Append(node->children[1]);
dir_stack.Append(newdir);
}
}
}
}
void GetIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
NgArray<T> & pis) const
{
pis.SetSize(0);
GetFirstIntersecting(pmin, pmax, [&pis](auto pi) { pis.Append(pi); return false;});
}
void Insert (const Box<dim> & box, T pi)
{
Insert (box.PMin(), box.PMax(), pi);
}
void Insert (const Point<dim> & pmin, const Point<dim> & pmax, T pi)
{
// static Timer timer("DelaunayTree::Insert"); RegionTimer rt(timer);
int dir = 0;
Point<2*dim> p;
for (auto i : IntRange(dim))
{
p(i) = pmin[i];
p(i+dim) = pmax[i];
}
Node * node = &root;
Leaf * leaf = node->GetLeaf();
// search correct leaf to add point
while(!leaf)
{
node = p[dir] < node->sep ? node->children[0] : node->children[1];
dir++;
if(dir==2*dim) dir = 0;
leaf = node->GetLeaf();
}
// add point to leaf
if(leaf->n_elements < N)
leaf->Add(leaves, leaf_index, p,pi);
else // assume leaf->n_elements == N
{
// add two new nodes and one new leaf
int n_elements = leaf->n_elements;
ArrayMem<TSCAL, N> coords(n_elements);
ArrayMem<int, N> order(n_elements);
// separate points in two halves, first sort all coordinates in direction dir
for (auto i : IntRange(n_elements))
{
order[i] = i;
coords[i] = leaf->p[i][dir];
}
QuickSortI(coords, order);
int isplit = N/2;
Leaf *leaf1 = (Leaf*) ball_leaves.Alloc(); new (leaf1) Leaf();
Leaf *leaf2 = (Leaf*) ball_leaves.Alloc(); new (leaf2) Leaf();
leaf1->nr = leaf->nr;
leaf2->nr = leaves.Size();
leaves.Append(leaf2);
leaves[leaf1->nr] = leaf1;
for (auto i : order.Range(isplit))
leaf1->Add(leaves, leaf_index, leaf->p[i], leaf->index[i] );
for (auto i : order.Range(isplit, N))
leaf2->Add(leaves, leaf_index, leaf->p[i], leaf->index[i] );
Node *node1 = (Node*) ball_nodes.Alloc(); new (node1) Node();
node1->leaf = leaf1;
node1->level = node->level+1;
Node *node2 = (Node*) ball_nodes.Alloc(); new (node2) Node();
node2->leaf = leaf2;
node2->level = node->level+1;
node->children[0] = node1;
node->children[1] = node2;
node->sep = 0.5 * (leaf->p[order[isplit-1]][dir] + leaf->p[order[isplit]][dir]);
// add new point to one of the new leaves
if (p[dir] < node->sep)
leaf1->Add( leaves, leaf_index, p, pi );
else
leaf2->Add( leaves, leaf_index, p, pi );
ball_leaves.Free(leaf);
n_leaves++;
n_nodes+=2;
}
}
void DeleteElement (T pi)
{
// static Timer timer("DelaunayTree::DeleteElement"); RegionTimer rt(timer);
Leaf *leaf = leaves[leaf_index[pi]];
leaf_index[pi] = -1;
auto & n_elements = leaf->n_elements;
auto & index = leaf->index;
auto & p = leaf->p;
for (auto i : IntRange(n_elements))
{
if(index[i] == pi)
{
n_elements--;
if(i!=n_elements)
{
index[i] = index[n_elements];
p[i] = p[n_elements];
}
return;
}
}
}
};
// typedef BoxTree<3> DTREE;
typedef DelaunayTree<3> DTREE;
static const int deltetfaces[][3] = static const int deltetfaces[][3] =
{ { 1, 2, 3 }, { { 1, 2, 3 },
@ -227,14 +507,14 @@ namespace netgen
void AddDelaunayPoint (PointIndex newpi, const Point3d & newp, void AddDelaunayPoint (PointIndex newpi, const Point3d & newp,
NgArray<DelaunayTet> & tempels, NgArray<DelaunayTet> & tempels,
Mesh & mesh, Mesh & mesh,
BoxTree<3> & tettree, DTREE & tettree,
MeshNB & meshnb, MeshNB & meshnb,
NgArray<Point<3> > & centers, NgArray<double> & radi2, NgArray<Point<3> > & centers, NgArray<double> & radi2,
NgArray<int> & connected, NgArray<int> & treesearch, NgArray<int> & connected, NgArray<int> & treesearch,
NgArray<int> & freelist, SphereList & list, NgArray<int> & freelist, SphereList & list,
IndexSet & insphere, IndexSet & closesphere) IndexSet & insphere, IndexSet & closesphere)
{ {
static Timer t("Meshing3::AddDelaunayPoint"); RegionTimer reg(t); static Timer t("Meshing3::AddDelaunayPoint");// RegionTimer reg(t);
// static Timer tsearch("addpoint, search"); // static Timer tsearch("addpoint, search");
// static Timer tinsert("addpoint, insert"); // static Timer tinsert("addpoint, insert");
@ -635,7 +915,7 @@ namespace netgen
pmin2 = pmin2 + 0.1 * (pmin2 - pmax2); pmin2 = pmin2 + 0.1 * (pmin2 - pmax2);
pmax2 = pmax2 + 0.1 * (pmax2 - pmin2); pmax2 = pmax2 + 0.1 * (pmax2 - pmin2);
BoxTree<3> tettree(pmin2, pmax2); DTREE tettree(pmin2, pmax2);
tempels.Append (startel); tempels.Append (startel);
@ -798,6 +1078,7 @@ namespace netgen
tempmesh.AddVolumeElement (el); tempmesh.AddVolumeElement (el);
} }
tempels.DeleteAll();
MeshQuality3d (tempmesh); MeshQuality3d (tempmesh);
@ -852,6 +1133,7 @@ namespace netgen
MeshQuality3d (tempmesh); MeshQuality3d (tempmesh);
tempels.SetSize(tempmesh.GetNE());
tempels.SetSize(0); tempels.SetSize(0);
for (auto & el : tempmesh.VolumeElements()) for (auto & el : tempmesh.VolumeElements())
tempels.Append (el); tempels.Append (el);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,76 @@
#ifndef FILE_IMPROVE2 #ifndef FILE_IMPROVE2
#define FILE_IMPROVE2 #define FILE_IMPROVE2
template<typename TINDEX>
void BuildEdgeList( const Mesh & mesh, const Table<TINDEX, PointIndex> & elementsonnode, Array<std::tuple<PointIndex, PointIndex>> & 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 = 2*ngcore::TaskManager::GetMaxThreads();
Array<Array<std::tuple<PointIndex,PointIndex>>> task_edges(ntasks);
ParallelFor(IntRange(ntasks), [&] (int ti)
{
auto myrange = mesh.Points().Range().Split(ti, ntasks);
ArrayMem<std::tuple<PointIndex,PointIndex>, 100> local_edges;
for (auto pi : myrange)
{
local_edges.SetSize(0);
for(auto ei : elementsonnode[pi])
{
const auto & elem = mesh[ei];
if (elem.IsDeleted()) continue;
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);
auto edge_prev = std::make_tuple<PointIndex, PointIndex>(-1,-1);
for(auto edge : local_edges)
if(edge != edge_prev)
{
task_edges[ti].Append(edge);
edge_prev = edge;
}
}
}, ntasks);
int num_edges = 0;
for (auto & edg : task_edges)
num_edges += edg.Size();
edges.SetAllocSize(num_edges);
for (auto & edg : task_edges)
edges.Append(edg);
}
class Neighbour
{
int nr[3];
int orient[3];
public:
Neighbour () { ; }
void SetNr (int side, int anr) { nr[side] = anr; }
int GetNr (int side) { return nr[side]; }
void SetOrientation (int side, int aorient) { orient[side] = aorient; }
int GetOrientation (int side) { return orient[side]; }
};
/// ///
class MeshOptimize2d class MeshOptimize2d
@ -24,6 +93,8 @@ public:
void ProjectBoundaryPoints(NgArray<int> & surfaceindex, void ProjectBoundaryPoints(NgArray<int> & surfaceindex,
const NgArray<Point<3>* > & from, NgArray<Point<3>* > & dest); const NgArray<Point<3>* > & from, NgArray<Point<3>* > & dest);
bool EdgeSwapping (const int usemetric, Array<Neighbour> &neighbors, Array<bool> &swapped,
const SurfaceElementIndex t1, const int edge, const int t, Array<int,PointIndex> &pdef, const bool check_only=false);
void EdgeSwapping (int usemetric); void EdgeSwapping (int usemetric);
void CombineImprove (); void CombineImprove ();
void SplitImprove (); void SplitImprove ();

View File

@ -21,6 +21,7 @@ namespace netgen
void MeshOptimize2d :: GenericImprove () void MeshOptimize2d :: GenericImprove ()
{ {
static Timer timer("MeshOptimize2d::GenericImprove"); RegionTimer reg(timer);
if (!faceindex) if (!faceindex)
{ {
if (writestatus) if (writestatus)

View File

@ -409,60 +409,6 @@ void MeshOptimize3d :: CombineImproveSequential (Mesh & mesh,
multithread.task = savetask; multithread.task = savetask;
} }
void MeshOptimize3d :: BuildEdgeList( const Mesh & mesh, const Table<ElementIndex, PointIndex> & elementsonnode, Array<std::tuple<PointIndex, PointIndex>> & 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 = 2*ngcore::TaskManager::GetMaxThreads();
Array<Array<std::tuple<PointIndex,PointIndex>>> task_edges(ntasks);
ParallelFor(IntRange(ntasks), [&] (int ti)
{
auto myrange = mesh.Points().Range().Split(ti, ntasks);
ArrayMem<std::tuple<PointIndex,PointIndex>, 100> local_edges;
for (auto pi : myrange)
{
local_edges.SetSize(0);
for(auto ei : elementsonnode[pi])
{
const Element & elem = mesh[ei];
if (elem.IsDeleted()) continue;
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);
auto edge_prev = std::make_tuple<PointIndex, PointIndex>(-1,-1);
for(auto edge : local_edges)
if(edge != edge_prev)
{
task_edges[ti].Append(edge);
edge_prev = edge;
}
}
}, ntasks);
int num_edges = 0;
for (auto & edg : task_edges)
num_edges += edg.Size();
edges.SetAllocSize(num_edges);
for (auto & edg : task_edges)
edges.Append(edg);
}
void MeshOptimize3d :: CombineImprove (Mesh & mesh, void MeshOptimize3d :: CombineImprove (Mesh & mesh,
OPTIMIZEGOAL goal) OPTIMIZEGOAL goal)
{ {

View File

@ -12,8 +12,6 @@ class MeshOptimize3d
{ {
const MeshingParameters & mp; const MeshingParameters & mp;
void BuildEdgeList( const Mesh & mesh, const Table<ElementIndex, PointIndex> & elementsonnode, Array<std::tuple<PointIndex, PointIndex>> & edges );
public: public:
MeshOptimize3d (const MeshingParameters & amp) : mp(amp) { ; } MeshOptimize3d (const MeshingParameters & amp) : mp(amp) { ; }

View File

@ -6205,22 +6205,41 @@ namespace netgen
{ {
for (PointIndex pi : myrange) for (PointIndex pi : myrange)
QuickSort(elementsonnode[pi]); QuickSort(elementsonnode[pi]);
}); }, ngcore::TasksPerThread(4));
return move(elementsonnode); return move(elementsonnode);
} }
Table<SurfaceElementIndex, PointIndex> Mesh :: CreatePoint2SurfaceElementTable() const Table<SurfaceElementIndex, PointIndex> Mesh :: CreatePoint2SurfaceElementTable( int faceindex ) const
{ {
static Timer timer("Mesh::CreatePoint2SurfaceElementTable"); RegionTimer rt(timer);
TableCreator<SurfaceElementIndex, PointIndex> creator(GetNP()); TableCreator<SurfaceElementIndex, PointIndex> creator(GetNP());
for ( ; !creator.Done(); creator++)
ngcore::ParallelForRange if(faceindex==0)
(Range(surfelements), [&] (auto myrange) {
{ for ( ; !creator.Done(); creator++)
for (SurfaceElementIndex ei : myrange) ngcore::ParallelForRange
for (PointIndex pi : (*this)[ei].PNums()) (Range(surfelements), [&] (auto myrange)
creator.Add (pi, ei); {
}); for (SurfaceElementIndex ei : myrange)
for (PointIndex pi : (*this)[ei].PNums())
creator.Add (pi, ei);
}, ngcore::TasksPerThread(4));
}
else
{
Array<SurfaceElementIndex> face_els;
GetSurfaceElementsOfFace(faceindex, face_els);
for ( ; !creator.Done(); creator++)
ngcore::ParallelForRange
(Range(face_els), [&] (auto myrange)
{
for (auto i : myrange)
for (PointIndex pi : (*this)[face_els[i]].PNums())
creator.Add (pi, face_els[i]);
}, ngcore::TasksPerThread(4));
}
auto elementsonnode = creator.MoveTable(); auto elementsonnode = creator.MoveTable();
ngcore::ParallelForRange ngcore::ParallelForRange

View File

@ -762,7 +762,7 @@ namespace netgen
Table<ElementIndex, PointIndex> CreatePoint2ElementTable() const; Table<ElementIndex, PointIndex> CreatePoint2ElementTable() const;
Table<SurfaceElementIndex, PointIndex> CreatePoint2SurfaceElementTable() const; Table<SurfaceElementIndex, PointIndex> CreatePoint2SurfaceElementTable( int faceindex=0 ) const;
DLL_HEADER bool PureTrigMesh (int faceindex = 0) const; DLL_HEADER bool PureTrigMesh (int faceindex = 0) const;
DLL_HEADER bool PureTetMesh () const; DLL_HEADER bool PureTetMesh () const;

View File

@ -3,7 +3,7 @@
namespace netgen namespace netgen
{ {
int printmessage_importance = 5; int printmessage_importance = 3;
int printwarnings = 1; int printwarnings = 1;
int printerrors = 1; int printerrors = 1;
int printdots = 1; int printdots = 1;

View File

@ -690,119 +690,95 @@ namespace netgen
void MeshOptimize2d :: ImproveMesh (const MeshingParameters & mp) void MeshOptimize2d :: ImproveMesh (const MeshingParameters & mp)
{ {
if (!faceindex) static Timer timer("MeshSmoothing 2D"); RegionTimer reg (timer);
{
PrintMessage (3, "Smoothing");
for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) PrintMessage (3, "Smoothing");
{
ImproveMesh (mp);
if (multithread.terminate)
throw NgException ("Meshing stopped");
}
faceindex = 0;
return;
}
static Timer timer("MeshSmoothing 2D");
// static int timer1 = NgProfiler::CreateTimer ("MeshSmoothing 2D start");
// static int timer2 = NgProfiler::CreateTimer ("MeshSmoothing 2D - BFGS");
RegionTimer reg (timer);
// NgProfiler::StartTimer (timer1);
CheckMeshApproximation (mesh); CheckMeshApproximation (mesh);
Opti2dLocalData ld; int ncolors;
Array<int> colors;
bool mixed = false;
Array<SurfaceElementIndex> seia; auto elementsonpoint = mesh.CreatePoint2SurfaceElementTable( faceindex );
mesh.GetSurfaceElementsOfFace (faceindex, seia);
bool mixed = 0;
for (auto sei : seia)
if (mesh[sei].GetNP() != 3)
{
mixed = true;
break;
}
Vector x(2);
NgArray<MeshPoint, PointIndex::BASE> savepoints(mesh.GetNP()); NgArray<MeshPoint, PointIndex::BASE> savepoints(mesh.GetNP());
ld.uselocalh = mp.uselocalh; Table<PointIndex> color_table;
if(faceindex)
{
Array<SurfaceElementIndex> seia;
mesh.GetSurfaceElementsOfFace (faceindex, seia);
for (auto sei : seia)
if (mesh[sei].GetNP() != 3)
{
mixed = true;
break;
}
NgArray<int, PointIndex::BASE> compress(mesh.GetNP()); Array<int, PointIndex> compress(mesh.GetNP());
NgArray<PointIndex> icompress; NgArray<PointIndex> icompress;
for (int i = 0; i < seia.Size(); i++) for (int i = 0; i < seia.Size(); i++)
{ {
const Element2d & el = mesh[seia[i]]; const Element2d & el = mesh[seia[i]];
for (int j = 0; j < el.GetNP(); j++) for (int j = 0; j < el.GetNP(); j++)
compress[el[j]] = -1; compress[el[j]] = -1;
} }
for (int i = 0; i < seia.Size(); i++) for (int i = 0; i < seia.Size(); i++)
{ {
const Element2d & el = mesh[seia[i]]; const Element2d & el = mesh[seia[i]];
for (int j = 0; j < el.GetNP(); j++) for (int j = 0; j < el.GetNP(); j++)
if (compress[el[j]] == -1) if (compress[el[j]] == -1)
{ {
compress[el[j]] = icompress.Size(); compress[el[j]] = icompress.Size();
icompress.Append(el[j]); icompress.Append(el[j]);
} }
} }
NgArray<int> cnta(icompress.Size());
cnta = 0;
for (int i = 0; i < seia.Size(); i++)
{
const Element2d & el = mesh[seia[i]];
for (int j = 0; j < el.GetNP(); j++)
cnta[compress[el[j]]]++;
}
TABLE<SurfaceElementIndex> elementsonpoint(cnta);
for (int i = 0; i < seia.Size(); i++)
{
const Element2d & el = mesh[seia[i]];
for (int j = 0; j < el.GetNP(); j++)
elementsonpoint.Add (compress[el[j]], seia[i]);
}
const auto & getDofs = [&] (int i)
{
return elementsonpoint[icompress[i]];
};
colors.SetSize(icompress.Size());
ncolors = ngcore::ComputeColoring( colors, mesh.GetNSE(), getDofs );
TableCreator<PointIndex> creator(ncolors);
for ( ; !creator.Done(); creator++)
ParallelForRange( Range(colors), [&](auto myrange)
{
for(auto i : myrange)
creator.Add(colors[i], icompress[i]);
});
color_table = creator.MoveTable();
}
else
{
for (auto & se : mesh.SurfaceElements())
if (se.GetNP() != 3)
{
mixed = true;
break;
}
const auto & getDofs = [&] (int i)
{
return elementsonpoint[i+PointIndex::BASE];
};
colors.SetSize(mesh.GetNP());
ncolors = ngcore::ComputeColoring( colors, mesh.GetNSE(), getDofs );
TableCreator<PointIndex> creator(ncolors);
for ( ; !creator.Done(); creator++)
ParallelForRange( Range(colors), [&](auto myrange)
{
for(auto i : myrange)
creator.Add(colors[i], PointIndex(i+PointIndex::BASE));
});
color_table = creator.MoveTable();
}
/*
NgArray<int, PointIndex::BASE> nelementsonpoint(mesh.GetNP());
nelementsonpoint = 0;
for (int i = 0; i < seia.Size(); i++)
{
const Element2d & el = mesh[seia[i]];
for (int j = 0; j < el.GetNP(); j++)
nelementsonpoint[el[j]]++;
}
TABLE<SurfaceElementIndex,PointIndex::BASE> elementsonpoint(nelementsonpoint);
for (int i = 0; i < seia.Size(); i++)
{
const Element2d & el = mesh[seia[i]];
for (int j = 0; j < el.GetNP(); j++)
elementsonpoint.Add (el[j], seia[i]);
}
*/
ld.loch = mp.maxh;
ld.locmetricweight = metricweight;
ld.meshthis = this;
Opti2SurfaceMinFunction surfminf(mesh, ld);
Opti2EdgeMinFunction edgeminf(mesh, ld);
Opti2SurfaceMinFunctionJacobian surfminfj(mesh, ld);
OptiParameters par;
par.maxit_linsearch = 8;
par.maxit_bfgs = 5;
/* /*
int i, j, k; int i, j, k;
Vector xedge(1); Vector xedge(1);
@ -872,27 +848,6 @@ namespace netgen
*/ */
bool printeddot = 0;
char plotchar = '.';
int modplot = 1;
if (mesh.GetNP() > 1000)
{
plotchar = '+';
modplot = 100;
}
if (mesh.GetNP() > 10000)
{
plotchar = 'o';
modplot = 1000;
}
if (mesh.GetNP() > 100000)
{
plotchar = 'O';
modplot = 10000;
}
int cnt = 0;
// NgProfiler::StopTimer (timer1); // NgProfiler::StopTimer (timer1);
/* /*
@ -902,28 +857,39 @@ namespace netgen
static Timer tloop("MeshSmooting 2D - loop"); static Timer tloop("MeshSmooting 2D - loop");
tloop.Start(); tloop.Start();
for (int hi = 0; hi < icompress.Size(); hi++) for (auto icolor : Range(color_table))
{ {
PointIndex pi = icompress[hi]; if (multithread.terminate)
break;
ParallelForRange( Range(color_table[icolor].Size()), [&](auto myrange)
{
Opti2dLocalData ld;
ld.uselocalh = mp.uselocalh;
ld.loch = mp.maxh;
ld.locmetricweight = metricweight;
ld.meshthis = this;
Opti2SurfaceMinFunction surfminf(mesh, ld);
Opti2SurfaceMinFunctionJacobian surfminfj(mesh, ld);
MinFunction & minfunc = mixed ? static_cast<MinFunction&>(surfminfj) : surfminf;
OptiParameters par;
par.maxit_linsearch = 8;
par.maxit_bfgs = 5;
for (auto i : myrange)
{
PointIndex pi = color_table[icolor][i];
if (mesh[pi].Type() == SURFACEPOINT) if (mesh[pi].Type() == SURFACEPOINT)
{ {
if (multithread.terminate) if (multithread.terminate)
throw NgException ("Meshing stopped"); return;
cnt++; if (elementsonpoint[pi].Size() == 0) continue;
if (cnt % modplot == 0 && writestatus)
{
printeddot = 1;
PrintDot (plotchar);
}
// if (elementsonpoint[pi].Size() == 0) continue;
if (elementsonpoint[hi].Size() == 0) continue;
ld.sp1 = mesh[pi]; ld.sp1 = mesh[pi];
// Element2d & hel = mesh[elementsonpoint[pi][0]]; Element2d & hel = mesh[elementsonpoint[pi][0]];
Element2d & hel = mesh[elementsonpoint[hi][0]];
int hpi = 0; int hpi = 0;
for (int j = 1; j <= hel.GetNP(); j++) for (int j = 1; j <= hel.GetNP(); j++)
@ -942,9 +908,9 @@ namespace netgen
ld.loc_pnts2.SetSize (0); ld.loc_pnts2.SetSize (0);
ld.loc_pnts3.SetSize (0); ld.loc_pnts3.SetSize (0);
for (int j = 0; j < elementsonpoint[hi].Size(); j++) for (int j = 0; j < elementsonpoint[pi].Size(); j++)
{ {
SurfaceElementIndex sei = elementsonpoint[hi][j]; SurfaceElementIndex sei = elementsonpoint[pi][j];
const Element2d & bel = mesh[sei]; const Element2d & bel = mesh[sei];
ld.surfi = mesh.GetFaceDescriptor(bel.GetIndex()).SurfNr(); ld.surfi = mesh.GetFaceDescriptor(bel.GetIndex()).SurfNr();
@ -971,38 +937,35 @@ namespace netgen
ld.t1 = ld.normal.GetNormal (); ld.t1 = ld.normal.GetNormal ();
ld.t2 = Cross (ld.normal, ld.t1); ld.t2 = Cross (ld.normal, ld.t1);
// save points, and project to tangential plane if(mixed)
for (int j = 0; j < ld.locelements.Size(); j++) {
{ // save points, and project to tangential plane (only for optimization with Opti2SurfaceMinFunctionJacobian in mixed element meshes)
const Element2d & el = mesh[ld.locelements[j]]; for (int j = 0; j < ld.locelements.Size(); j++)
for (int k = 0; k < el.GetNP(); k++) {
savepoints[el[k]] = mesh[el[k]]; const Element2d & el = mesh[ld.locelements[j]];
} for (int k = 0; k < el.GetNP(); k++)
savepoints[el[k]] = mesh[el[k]];
}
for (int j = 0; j < ld.locelements.Size(); j++) for (int j = 0; j < ld.locelements.Size(); j++)
{ {
const Element2d & el = mesh[ld.locelements[j]]; const Element2d & el = mesh[ld.locelements[j]];
for (int k = 0; k < el.GetNP(); k++) for (int k = 0; k < el.GetNP(); k++)
{ {
PointIndex hhpi = el[k]; PointIndex hhpi = el[k];
double lam = ld.normal * (mesh[hhpi] - ld.sp1); double lam = ld.normal * (mesh[hhpi] - ld.sp1);
mesh[hhpi] -= lam * ld.normal; mesh[hhpi] -= lam * ld.normal;
} }
} }
}
Vector x(2);
x = 0; x = 0;
par.typx = 0.3*ld.lochs[0]; par.typx = 0.3*ld.lochs[0];
// NgProfiler::StartTimer (timer2); // NgProfiler::StartTimer (timer2);
if (mixed) BFGS (x, minfunc, par, 1e-6);
{
BFGS (x, surfminfj, par, 1e-6);
}
else
{
BFGS (x, surfminf, par, 1e-6);
}
// NgProfiler::StopTimer (timer2); // NgProfiler::StopTimer (timer2);
@ -1011,16 +974,19 @@ namespace netgen
double fact = 1; double fact = 1;
int moveisok = 0; int moveisok = 0;
// restore other points if(mixed)
for (int j = 0; j < ld.locelements.Size(); j++) {
{ // restore other points
const Element2d & el = mesh[ld.locelements[j]]; for (int j = 0; j < ld.locelements.Size(); j++)
for (int k = 0; k < el.GetNP(); k++) {
{ const Element2d & el = mesh[ld.locelements[j]];
PointIndex hhpi = el[k]; for (int k = 0; k < el.GetNP(); k++)
if (hhpi != pi) mesh[hhpi] = savepoints[hhpi]; {
} PointIndex hhpi = el[k];
} if (hhpi != pi) mesh[hhpi] = savepoints[hhpi];
}
}
}
//optimizer loop (if whole distance is not possible, move only a bit!!!!) //optimizer loop (if whole distance is not possible, move only a bit!!!!)
@ -1059,13 +1025,12 @@ namespace netgen
} }
} }
} }
} }
}, mixed ? 1 : ngcore::TasksPerThread(4)); // mixed element smoothing not parallel yet
}
tloop.Stop(); tloop.Stop();
if (printeddot)
PrintDot ('\n');
CheckMeshApproximation (mesh); CheckMeshApproximation (mesh);
mesh.SetNextTimeStamp(); mesh.SetNextTimeStamp();
} }

View File

@ -371,6 +371,7 @@ namespace netgen
void OCCSurface :: Project (Point<3> & ap, PointGeomInfo & gi) void OCCSurface :: Project (Point<3> & ap, PointGeomInfo & gi)
{ {
static Timer t("OccSurface::Project"); RegionTimer reg(t); static Timer t("OccSurface::Project"); RegionTimer reg(t);
static Timer t2("OccSurface::Project actural");
// try Newton's method ... // try Newton's method ...
@ -475,7 +476,10 @@ namespace netgen
Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface ); Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface );
auto toltool = BRep_Tool::Tolerance( topods_face ); auto toltool = BRep_Tool::Tolerance( topods_face );
gp_Pnt2d suval = su->ValueOfUV ( pnt, toltool); // gp_Pnt2d suval = su->ValueOfUV ( pnt, toltool);
t2.Start();
gp_Pnt2d suval = su->NextValueOfUV (gp_Pnt2d(u,v), pnt, toltool);
t2.Stop();
suval.Coord( u, v); suval.Coord( u, v);
pnt = occface->Value( u, v ); pnt = occface->Value( u, v );

View File

@ -305,9 +305,8 @@ int STLSurfaceMeshing (STLGeometry & geom, class Mesh & mesh, const MeshingParam
optmesh.SetMetricWeight (0); optmesh.SetMetricWeight (0);
mesh.CalcSurfacesOfNode(); mesh.CalcSurfacesOfNode();
optmesh.EdgeSwapping(0); optmesh.EdgeSwapping (0);
mesh.CalcSurfacesOfNode(); optmesh.ImproveMesh (mparam);
optmesh.ImproveMesh(mparam);
} }
mesh.Compress(); mesh.Compress();

View File

@ -1029,8 +1029,11 @@ namespace netgen
else else
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol);
static Point<3> xa[129];
static Vec<3> na[129];
for (int hi = 0; hi < seia.Size(); hi++) for (int hi = 0; hi < seia.Size(); hi++)
{ {
SurfaceElementIndex sei = seia[hi]; SurfaceElementIndex sei = seia[hi];
@ -1058,8 +1061,6 @@ namespace netgen
if (curv.IsHighOrder()) // && curv.IsSurfaceElementCurved(sei)) if (curv.IsHighOrder()) // && curv.IsSurfaceElementCurved(sei))
{ {
if (hoplotn > 128) hoplotn = 128; if (hoplotn > 128) hoplotn = 128;
Point<3> xa[129];
Vec<3> na[129];
for (int i = 0; i < hoplotn; i++) for (int i = 0; i < hoplotn; i++)
{ {

View File

@ -29,6 +29,11 @@ namespace netgen
// vssolution.AddUserVisualizationObject (vis); // vssolution.AddUserVisualizationObject (vis);
GetVSSolution().AddUserVisualizationObject (vis); GetVSSolution().AddUserVisualizationObject (vis);
} }
void DeleteUserVisualizationObject (UserVisualizationObject * vis)
{
// vssolution.AddUserVisualizationObject (vis);
GetVSSolution().DeleteUserVisualizationObject (vis);
}
VisualSceneSolution :: SolData :: SolData () VisualSceneSolution :: SolData :: SolData ()

View File

@ -233,7 +233,12 @@ public:
{ {
user_vis.Append (vis); user_vis.Append (vis);
} }
void DeleteUserVisualizationObject (UserVisualizationObject * vis)
{
int pos = user_vis.Pos(vis);
if (pos >= 0)
user_vis.Delete(pos);
}
private: private:
void GetClippingPlaneTrigs (NgArray<ClipPlaneTrig> & trigs, NgArray<ClipPlanePoint> & pts); void GetClippingPlaneTrigs (NgArray<ClipPlaneTrig> & trigs, NgArray<ClipPlanePoint> & pts);

File diff suppressed because it is too large Load Diff

View File

@ -58,6 +58,10 @@ def getMeshingparameters(filename):
return standard[:3] # this gets too big for finer meshsizes return standard[:3] # this gets too big for finer meshsizes
if filename == "screw.step": if filename == "screw.step":
return standard[3:] # coarser meshes don't work here return standard[3:] # coarser meshes don't work here
if filename == "cylsphere.geo":
return standard[0:2] + standard[3:] # coarse gives inconsistent reults (other mesh on MacOS)
if filename == "part1.stl":
return standard[0:1] + standard[2:] # very coarse does not work
return standard return standard
_geofiles = [f for f in getFiles(".geo")] + [f for f in getFiles(".stl")] _geofiles = [f for f in getFiles(".geo")] + [f for f in getFiles(".stl")]