diff --git a/libsrc/core/hashtable.hpp b/libsrc/core/hashtable.hpp index 7d24b97b..da74a50c 100644 --- a/libsrc/core/hashtable.hpp +++ b/libsrc/core/hashtable.hpp @@ -1099,6 +1099,106 @@ namespace ngcore return ost; } + + + + + + + + + template + class CompressedTable + { + Table table; + ClosedHashTable idmap; + + public: + CompressedTable (Table && atable, ClosedHashTable && aidmap) + : table(std::move(atable)), idmap(std::move(aidmap)) { } + + FlatArray operator[](IndexType id) const + { + if (auto nr = idmap.GetIfUsed(id)) + return table[*nr]; + else + return { 0, nullptr }; + } + auto & Table() { return table; } + }; + + + template + class CompressedTableCreator + { + protected: + int mode; // 1 .. cnt, 2 .. cnt entries, 3 .. fill table + size_t nd; // number of entries; + ClosedHashTable idmap; + Array cnt; + Table table; + public: + CompressedTableCreator() + { nd = 0; mode = 1; } + + CompressedTable MoveTable() + { + return { std::move(table), std::move(idmap) }; + } + + bool Done () { return mode > 3; } + void operator++(int) { SetMode (mode+1); } + + int GetMode () const { return mode; } + void SetMode (int amode) + { + mode = amode; + if (mode == 2) + { + cnt.SetSize(nd); + cnt = 0; + } + if (mode == 3) + { + table = Table (cnt); + cnt = 0; + } + } + + void Add (IndexType blocknr, const T & data) + { + switch (mode) + { + case 1: + { + if (!idmap.Used (blocknr)) + idmap[blocknr] = nd++; + break; + } + case 2: + cnt[idmap.Get(blocknr)]++; + break; + case 3: + size_t cblock = idmap.Get(blocknr); + int ci = cnt[cblock]++; + table[cblock][ci] = data; + break; + } + } + }; + + + + + + + + + + + + + } // namespace ngcore diff --git a/libsrc/core/table.hpp b/libsrc/core/table.hpp index 4476a331..d2326c26 100644 --- a/libsrc/core/table.hpp +++ b/libsrc/core/table.hpp @@ -17,6 +17,7 @@ #include "ngcore_api.hpp" #include "profiler.hpp" + namespace ngcore { @@ -406,7 +407,7 @@ namespace ngcore pcreator = std::make_unique>(*cnt); else pcreator = std::make_unique>(); - + auto & creator = *pcreator; for ( ; !creator.Done(); creator++) @@ -452,7 +453,9 @@ namespace ngcore void Add (size_t blocknr, FlatArray dofs); }; + + /** A dynamic table class. diff --git a/libsrc/meshing/improve2.cpp b/libsrc/meshing/improve2.cpp index 97b7a02c..a9d7f258 100644 --- a/libsrc/meshing/improve2.cpp +++ b/libsrc/meshing/improve2.cpp @@ -212,7 +212,7 @@ namespace netgen } Array neighbors(mesh.GetNSE()); - auto elements_on_node = mesh.CreatePoint2SurfaceElementTable(faceindex); + auto elements_on_node = mesh.CreateCompressedPoint2SurfaceElementTable(faceindex); Array swapped(mesh.GetNSE()); Array pdef(mesh.GetNP()); @@ -366,9 +366,9 @@ namespace netgen - + template double CombineImproveEdge( Mesh & mesh, - const Table & elementsonnode, + const T_PI2SEI & elementsonnode, Array, PointIndex> & normals, Array & fixed, PointIndex pi1, PointIndex pi2, @@ -601,7 +601,7 @@ namespace netgen int np = mesh.GetNP(); - auto elementsonnode = mesh.CreatePoint2SurfaceElementTable(faceindex); + auto elementsonnode = mesh.CreateCompressedPoint2SurfaceElementTable(faceindex); // int ntasks = ngcore::TaskManager::GetMaxThreads(); Array> edges; diff --git a/libsrc/meshing/improve2.hpp b/libsrc/meshing/improve2.hpp index 1cd74707..ebecdc2e 100644 --- a/libsrc/meshing/improve2.hpp +++ b/libsrc/meshing/improve2.hpp @@ -36,10 +36,10 @@ inline void AppendEdges( const Element & elem, PointIndex pi, Array -void BuildEdgeList( const Mesh & mesh, const Table & elementsonnode, Array> & edges ) +template +void BuildEdgeList( const Mesh & mesh, const T_PI2SEI & elementsonnode, Array> & edges ) { - static_assert(is_same_v||is_same_v, "Invalid type for TINDEX"); + // static_assert(is_same_v||is_same_v, "Invalid type for TINDEX"); static Timer tbuild_edges("Build edges"); RegionTimer reg(tbuild_edges); int ntasks = 4*ngcore::TaskManager::GetMaxThreads(); diff --git a/libsrc/meshing/meshclass.cpp b/libsrc/meshing/meshclass.cpp index 84e70af5..da16b3cb 100644 --- a/libsrc/meshing/meshclass.cpp +++ b/libsrc/meshing/meshclass.cpp @@ -7016,6 +7016,8 @@ namespace netgen Table Mesh :: CreatePoint2ElementTable(std::optional points, int domain) const { + static Timer timer("Mesh::CreatePoint2VolumeElementTable"); RegionTimer rt(timer); + if(points) { const auto & free_points = *points; @@ -7074,6 +7076,42 @@ namespace netgen }, GetNP()); } + + CompressedTable Mesh :: CreateCompressedPoint2SurfaceElementTable( int faceindex ) const + { + static Timer timer("Mesh::CreatePoint2SurfaceElementTable"); RegionTimer rt(timer); + + CompressedTableCreator creator; + + if(faceindex==0) + { + for ( ; !creator.Done(); creator++) + for (auto sei : SurfaceElements().Range()) + for (auto pi : (*this)[sei].PNums()) + creator.Add(pi, sei); + } + else + { + Array face_els; + GetSurfaceElementsOfFace(faceindex, face_els); + + for ( ; !creator.Done(); creator++) + for (auto sei : face_els) + for (auto pi : (*this)[sei].PNums()) + creator.Add(pi, sei); + } + + + auto compressed_table = creator.MoveTable(); + + for (auto row : compressed_table.Table()) + QuickSort (row); + + return compressed_table; + } + + + /* diff --git a/libsrc/meshing/meshclass.hpp b/libsrc/meshing/meshclass.hpp index 7a244a3d..f8b407ab 100644 --- a/libsrc/meshing/meshclass.hpp +++ b/libsrc/meshing/meshclass.hpp @@ -845,7 +845,9 @@ namespace netgen DLL_HEADER Table CreatePoint2ElementTable(std::optional points = std::nullopt, int domain = 0) const; + // DLL_HEADER Table CreatePoint2SurfaceElementTable( int faceindex=0 ) const; DLL_HEADER Table CreatePoint2SurfaceElementTable( int faceindex=0 ) const; + DLL_HEADER CompressedTable CreateCompressedPoint2SurfaceElementTable( int faceindex=0 ) const; DLL_HEADER bool PureTrigMesh (int faceindex = 0) const; DLL_HEADER bool PureTetMesh () const; diff --git a/libsrc/meshing/smoothing2.cpp b/libsrc/meshing/smoothing2.cpp index 0e6db78a..b5413f6e 100644 --- a/libsrc/meshing/smoothing2.cpp +++ b/libsrc/meshing/smoothing2.cpp @@ -699,7 +699,8 @@ namespace netgen int ncolors; Array colors; bool mixed = false; - auto elementsonpoint = mesh.CreatePoint2SurfaceElementTable( faceindex ); + // auto elementsonpoint = mesh.CreatePoint2SurfaceElementTable( faceindex ); + auto elementsonpoint = mesh.CreateCompressedPoint2SurfaceElementTable( faceindex ); NgArray savepoints(mesh.GetNP()); Table color_table;