more general ClosedHashTable, e.g. hash for tuples

This commit is contained in:
Joachim Schoeberl 2024-12-29 15:42:21 +01:00
parent 55474772cd
commit a2ea0c407a
16 changed files with 156 additions and 69 deletions

View File

@ -223,8 +223,9 @@ private:
void Clear (IndexType i) { BitArray::Clear(i-IndexBASE<IndexType>()); } void Clear (IndexType i) { BitArray::Clear(i-IndexBASE<IndexType>()); }
void SetBitAtomic (IndexType i) { BitArray::SetBitAtomic(i-IndexBASE<IndexType>()); } void SetBitAtomic (IndexType i) { BitArray::SetBitAtomic(i-IndexBASE<IndexType>()); }
bool Test (IndexType i) const { return BitArray::Test(i-IndexBASE<IndexType>()); } bool Test (IndexType i) const { return BitArray::Test(i-IndexBASE<IndexType>()); }
bool operator[] (IndexType i) const { return Test(i); } bool operator[] (IndexType i) const { return Test(i); }
T_Range<IndexType> Range() const { return { IndexBASE<IndexType>(), IndexBASE<IndexType>()+Size() }; }
NGCORE_API TBitArray & Or (const TBitArray & ba2) NGCORE_API TBitArray & Or (const TBitArray & ba2)
{ {
BitArray::Or(ba2); BitArray::Or(ba2);

View File

@ -591,10 +591,28 @@ namespace ngcore
return res; return res;
} }
template <typename T> template <typename T>
constexpr inline T InvalidHash() { return T(-1); } constexpr inline T InvalidHash() { return T(-1); }
template <typename T_HASH>
struct CHT_trait
{
constexpr static inline T_HASH Invalid() { return InvalidHash<T_HASH>(); }
constexpr static inline size_t HashValue (const T_HASH & hash, size_t mask) { return HashValue2(hash, mask); }
};
template <typename T1, typename T2>
struct CHT_trait<std::tuple<T1,T2>>
{
constexpr static inline std::tuple<T1,T2> Invalid() { return { CHT_trait<T1>::Invalid(), CHT_trait<T2>::Invalid() } ; }
constexpr static inline size_t HashValue (const std::tuple<T1,T2> & hash, size_t mask)
{
return (CHT_trait<T1>::HashValue(std::get<0>(hash), mask) + CHT_trait<T2>::HashValue(std::get<1>(hash),mask)) & mask;
}
};
/** /**
A closed hash-table. A closed hash-table.
All information is stored in one fixed array. All information is stored in one fixed array.
@ -615,7 +633,8 @@ namespace ngcore
Array<T> cont; Array<T> cont;
/// ///
// T_HASH invalid = -1; // T_HASH invalid = -1;
static constexpr T_HASH invalid = InvalidHash<T_HASH>(); // static constexpr T_HASH invalid = InvalidHash<T_HASH>();
static constexpr T_HASH invalid = CHT_trait<T_HASH>::Invalid();
public: public:
/// ///
ClosedHashTable (size_t asize = 128) ClosedHashTable (size_t asize = 128)
@ -623,7 +642,8 @@ namespace ngcore
{ {
mask = size-1; mask = size-1;
// hash = T_HASH(invalid); // hash = T_HASH(invalid);
hash = InvalidHash<T_HASH>(); // hash = InvalidHash<T_HASH>();
hash = CHT_trait<T_HASH>::Invalid();
} }
ClosedHashTable (ClosedHashTable && ht2) = default; ClosedHashTable (ClosedHashTable && ht2) = default;
@ -658,7 +678,8 @@ namespace ngcore
size_t Position (const T_HASH ind) const size_t Position (const T_HASH ind) const
{ {
size_t i = HashValue2(ind, mask); // size_t i = HashValue2(ind, mask);
size_t i = CHT_trait<T_HASH>::HashValue(ind, mask);
while (true) while (true)
{ {
if (hash[i] == ind) return i; if (hash[i] == ind) return i;
@ -680,7 +701,8 @@ namespace ngcore
{ {
if (UsedElements()*2 > Size()) DoubleSize(); if (UsedElements()*2 > Size()) DoubleSize();
size_t i = HashValue2 (ind, mask); // size_t i = HashValue2 (ind, mask);
size_t i = CHT_trait<T_HASH>::HashValue (ind, mask);
while (true) while (true)
{ {

View File

@ -53,7 +53,7 @@ void SingularEdge :: FindPointsOnEdge (class Mesh & mesh)
for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++)
{ {
INDEX_2 i2 (mesh[si][0], mesh[si][1]); PointIndices<2> i2 (mesh[si][0], mesh[si][1]);
/* /*
bool onedge = 1; bool onedge = 1;
@ -93,8 +93,8 @@ void SingularEdge :: FindPointsOnEdge (class Mesh & mesh)
{ {
segms.Append (i2); segms.Append (i2);
// PrintMessage (5, "sing segment ", i2.I1(), " - ", i2.I2()); // PrintMessage (5, "sing segment ", i2.I1(), " - ", i2.I2());
points.Append (mesh[ PointIndex (i2.I1())]); points.Append (mesh[i2.I1()]);
points.Append (mesh[ PointIndex (i2.I2())]); points.Append (mesh[i2.I2()]);
mesh[si].singedge_left = factor; mesh[si].singedge_left = factor;
mesh[si].singedge_right = factor; mesh[si].singedge_right = factor;
} }

View File

@ -476,17 +476,30 @@ void MergeSort (int size, T * data, T * help);
namespace ngcore namespace ngcore
{ {
// template <>
// constexpr inline netgen::INDEX_2 InvalidHash<netgen::INDEX_2> () { return netgen::INDEX_2{-1,-1}; }
template <> template <>
constexpr inline netgen::INDEX_2 InvalidHash<netgen::INDEX_2> () { return netgen::INDEX_2{-1,-1}; } struct CHT_trait<netgen::INDEX_2>
{
constexpr static inline netgen::INDEX_2 Invalid() { return { -1, -1 } ; }
constexpr static inline size_t HashValue (const netgen::INDEX_2 & hash, size_t mask)
{ return HashValue2(IVec<2,netgen::INDEX>(hash[0], hash[1]), mask); }
};
} }
namespace netgen namespace netgen
{ {
/*
inline size_t HashValue2 (const netgen::INDEX_2 & ind, size_t mask) inline size_t HashValue2 (const netgen::INDEX_2 & ind, size_t mask)
{ {
return HashValue2(IVec<2,netgen::INDEX>(ind[0], ind[1]), mask); return HashValue2(IVec<2,netgen::INDEX>(ind[0], ind[1]), mask);
} }
*/
inline size_t HashValue2 (const netgen::INDEX_3 & ind, size_t mask) inline size_t HashValue2 (const netgen::INDEX_3 & ind, size_t mask)
{ {
return HashValue2(IVec<3,netgen::INDEX>(ind[0], ind[1], ind[2]), mask); return HashValue2(IVec<3,netgen::INDEX>(ind[0], ind[1], ind[2]), mask);

View File

@ -523,8 +523,8 @@ namespace netgen
{ // tensor product mesh { // tensor product mesh
RegionTimer rt(t_tensor); RegionTimer rt(t_tensor);
NgArray<PointIndex, PointIndex::BASE> nextpi(bnp); Array<PointIndex, PointIndex> nextpi(bnp);
NgArray<int, PointIndex::BASE> si1(bnp), si2(bnp); Array<int, PointIndex> si1(bnp), si2(bnp);
// PointIndex firstpi; // PointIndex firstpi;
nextpi = -1; nextpi = -1;
@ -553,7 +553,8 @@ namespace netgen
PointIndex c1(0), c2, c3, c4; // 4 corner points PointIndex c1(0), c2, c3, c4; // 4 corner points
int nex = 1, ney = 1; int nex = 1, ney = 1;
for (PointIndex pi = 1; pi <= si2.Size(); pi++) // for (PointIndex pi = 1; pi <= si2.Size(); pi++)
for (PointIndex pi : si2.Range())
if (si2[pi] != -1) if (si2[pi] != -1)
{ c1 = pi; break; } { c1 = pi; break; }

View File

@ -131,7 +131,8 @@ void BoundaryLayerTool ::InterpolateGrowthVectors()
{ {
auto& seg = *p_seg; auto& seg = *p_seg;
faces.SetSize(0); faces.SetSize(0);
if (seg[0] <= p2sel.Size()) // if (seg[0] <= p2sel.Size())
if (seg[0] < IndexBASE<PointIndex>()+p2sel.Size())
{ {
for (auto sei : p2sel[seg[0]]) for (auto sei : p2sel[seg[0]])
if (moved_surfaces.Test(mesh[sei].GetIndex()) && p2sel[seg[1]].Contains(sei)) if (moved_surfaces.Test(mesh[sei].GetIndex()) && p2sel[seg[1]].Contains(sei))
@ -154,7 +155,8 @@ void BoundaryLayerTool ::InterpolateGrowthVectors()
{ {
for (auto* p_seg : edgenr2seg[edgenr]) for (auto* p_seg : edgenr2seg[edgenr])
for (auto pi : p_seg->PNums()) for (auto pi : p_seg->PNums())
if (pi <= np && point_types[pi] == EDGEPOINT) // if (pi <= np && point_types[pi] == EDGEPOINT)
if (pi < npi && point_types[pi] == EDGEPOINT)
point_types[pi] = SURFACEPOINT; point_types[pi] = SURFACEPOINT;
continue; continue;
} }

View File

@ -1,4 +1,8 @@
HPREF_ELEMENT_TYPE ClassifyTet(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, // typename INDEX_2_HASHTABLE<int> HT_EDGEPOINT_DOM;
typedef ClosedHashTable<tuple<int, PointIndex>, int> HT_EDGEPOINT_DOM;
HPREF_ELEMENT_TYPE ClassifyTet(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint)
{ {
@ -586,7 +590,7 @@ HPREF_ELEMENT_TYPE ClassifyTet(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges
HPREF_ELEMENT_TYPE ClassifyPrism(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, HPREF_ELEMENT_TYPE ClassifyPrism(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint)
{ {
@ -823,8 +827,10 @@ HPREF_ELEMENT_TYPE ClassifyPrism(HPRefElement & el, INDEX_2_HASHTABLE<int> & edg
} }
// #ifdef SABINE // #ifdef SABINE
HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom,
HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int dim, const FaceDescriptor & fd) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int dim, const FaceDescriptor & fd)
@ -930,10 +936,10 @@ HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE<int> & edge
if(edges.Used(i2)) if(edges.Used(i2))
{ {
if(edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep1-1])) || if(edgepoint_dom.Used( { fd.SurfNr(),pnums[ep1-1] } ) ||
edgepoint_dom.Used(INDEX_2(-1,pnums[ep1-1])) || edgepoint_dom.Used( { -1,pnums[ep1-1] } ) ||
edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep2-1])) || edgepoint_dom.Used( { fd.SurfNr(), pnums[ep2-1]} ) ||
edgepoint_dom.Used(INDEX_2(-1,pnums[ep2-1]))) edgepoint_dom.Used( { -1,pnums[ep2-1] } ))
{ {
edge_sing[k]=2; edge_sing[k]=2;
point_sing[ep1-1] = 2; point_sing[ep1-1] = 2;
@ -948,7 +954,7 @@ HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE<int> & edge
for (int k=0;k<3;k++) for (int k=0;k<3;k++)
if (edgepoint.Test(pnums[k]) && if (edgepoint.Test(pnums[k]) &&
(dim==3 || edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[k])) || edgepoint_dom.Used(INDEX_2(-1,pnums[k])))) (dim==3 || edgepoint_dom.Used( { fd.SurfNr(),pnums[k] } ) || edgepoint_dom.Used( { -1,pnums[k] } )))
//edgepoint, but not member of sing_edge on trig -> cp //edgepoint, but not member of sing_edge on trig -> cp
{ {
PointIndices<2> i2a = PointIndices<2>::Sort(el.PNum(p[k]), el.PNum(p[(k+1)%3])); PointIndices<2> i2a = PointIndices<2>::Sort(el.PNum(p[k]), el.PNum(p[(k+1)%3]));
@ -1301,7 +1307,7 @@ HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE<int> & edge
return(type); return(type);
} }
#endif #endif
HPREF_ELEMENT_TYPE ClassifyQuad(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, HPREF_ELEMENT_TYPE ClassifyQuad(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int dim, const FaceDescriptor & fd) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int dim, const FaceDescriptor & fd)
{ {
@ -1321,10 +1327,10 @@ HPREF_ELEMENT_TYPE ClassifyQuad(HPRefElement & el, INDEX_2_HASHTABLE<int> & edge
if (dim == 2) if (dim == 2)
{ {
ep1 = edgepoint_dom.Used (PointIndices<2>(el.GetIndex(), el.PNumMod(j))); ep1 = edgepoint_dom.Used ( { el.GetIndex(), el.PNumMod(j) } );
ep2 = edgepoint_dom.Used (PointIndices<2>(el.GetIndex(), el.PNumMod(j+1))); ep2 = edgepoint_dom.Used ( { el.GetIndex(), el.PNumMod(j+1) } );
ep3 = edgepoint_dom.Used (PointIndices<2>(el.GetIndex(), el.PNumMod(j+2))); ep3 = edgepoint_dom.Used ( { el.GetIndex(), el.PNumMod(j+2) });
ep4 = edgepoint_dom.Used (PointIndices<2>(el.GetIndex(), el.PNumMod(j+3))); ep4 = edgepoint_dom.Used ( { el.GetIndex(), el.PNumMod(j+3) });
} }
cp1 = cornerpoint.Test (el.PNumMod (j)); cp1 = cornerpoint.Test (el.PNumMod (j));
@ -1337,7 +1343,7 @@ HPREF_ELEMENT_TYPE ClassifyQuad(HPRefElement & el, INDEX_2_HASHTABLE<int> & edge
ep3 |= cp3; ep3 |= cp3;
ep4 |= cp4; ep4 |= cp4;
int p[4] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2), el.PNumMod(j+4)}; PointIndex p[4] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2), el.PNumMod(j+4)};
//int epp[4] = { ep1, ep2, ep3, ep4}; //int epp[4] = { ep1, ep2, ep3, ep4};
int cpp[4] = { cp1, cp2, cp3, cp4}; int cpp[4] = { cp1, cp2, cp3, cp4};
for(int k=0;k<0;k++) for(int k=0;k<0;k++)
@ -1650,7 +1656,7 @@ HPREF_ELEMENT_TYPE ClassifyQuad(HPRefElement & el, INDEX_2_HASHTABLE<int> & edge
} }
HPREF_ELEMENT_TYPE ClassifyHex(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, HPREF_ELEMENT_TYPE ClassifyHex(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint)
{ {
@ -1755,7 +1761,7 @@ HPREF_ELEMENT_TYPE ClassifyHex(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges
HPREF_ELEMENT_TYPE ClassifyHex7 (HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, HPREF_ELEMENT_TYPE ClassifyHex7 (HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint,
INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint)
@ -1795,7 +1801,7 @@ HPREF_ELEMENT_TYPE ClassifyHex7 (HPRefElement & el, INDEX_2_HASHTABLE<int> & edg
HPREF_ELEMENT_TYPE ClassifySegm(HPRefElement & hpel, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, HPREF_ELEMENT_TYPE ClassifySegm(HPRefElement & hpel, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint,
INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint)
@ -1839,7 +1845,7 @@ HPREF_ELEMENT_TYPE ClassifySegm(HPRefElement & hpel, INDEX_2_HASHTABLE<int> & ed
} }
HPREF_ELEMENT_TYPE ClassifyPyramid(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, HPREF_ELEMENT_TYPE ClassifyPyramid(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint,
INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint)

View File

@ -603,7 +603,8 @@ namespace netgen
return hps; return hps;
} }
bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoiclt_dom, template <typename HT_EDGEPOINT_DOM>
bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoiclt_dom,
NgBitArray & cornerpoint, NgBitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, NgBitArray & cornerpoint, NgBitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int & levels, int & act_ref); INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int & levels, int & act_ref);
@ -1632,7 +1633,8 @@ namespace netgen
} }
} }
bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, template <typename HT_EDGEPOINT_DOM>
bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE<int> & edges, HT_EDGEPOINT_DOM & edgepoint_dom,
TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, TBitArray<PointIndex> & cornerpoint, TBitArray<PointIndex> & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,
INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int & levels, int & act_ref) INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex> & facepoint, int & levels, int & act_ref)
{ {
@ -1808,16 +1810,16 @@ namespace netgen
*testout << " singleft " << endl; *testout << " singleft " << endl;
*testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl; *testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl;
*testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl; *testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl;
edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I1()), 1); edgepoint_dom.Set ( { mesh.LineSegment(i).domin, i2.I1() }, 1);
edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I2()), 1); edgepoint_dom.Set ( { mesh.LineSegment(i).domin, i2.I2() }, 1);
sing = 1; sing = 1;
} }
if (seg.singedge_right * levels >= act_ref) if (seg.singedge_right * levels >= act_ref)
{ {
INDEX_2 i2 = INDEX_2::Sort(mesh.LineSegment(i)[1], PointIndices<2> i2 = INDEX_2::Sort(mesh.LineSegment(i)[1],
mesh.LineSegment(i)[0]); mesh.LineSegment(i)[0]);
edges.Set (i2, 1); edges.Set (i2, 1);
edgepoint.SetBit(i2.I1()); edgepoint.SetBit(i2.I1());
edgepoint.SetBit(i2.I2()); edgepoint.SetBit(i2.I2());
@ -1826,8 +1828,8 @@ namespace netgen
*testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl; *testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl;
*testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl; *testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl;
edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I1()), 1); edgepoint_dom.Set ( { mesh.LineSegment(i).domout, i2.I1() }, 1);
edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I2()), 1); edgepoint_dom.Set ( { mesh.LineSegment(i).domout, i2.I2() }, 1);
sing = 1; sing = 1;
} }
@ -1891,8 +1893,10 @@ namespace netgen
{ {
INDEX_2_HASHTABLE<int> edges(mesh.GetNSeg()+1); INDEX_2_HASHTABLE<int> edges(mesh.GetNSeg()+1);
TBitArray<PointIndex> edgepoint(mesh.GetNP()); TBitArray<PointIndex> edgepoint(mesh.GetNP());
INDEX_2_HASHTABLE<int> edgepoint_dom(mesh.GetNSeg()+1); // INDEX_2_HASHTABLE<int> edgepoint_dom(mesh.GetNSeg()+1);
HT_EDGEPOINT_DOM edgepoint_dom;
edgepoint.Clear(); edgepoint.Clear();
TBitArray<PointIndex> cornerpoint(mesh.GetNP()); TBitArray<PointIndex> cornerpoint(mesh.GetNP());
cornerpoint.Clear(); cornerpoint.Clear();
@ -1918,7 +1922,7 @@ namespace netgen
NgArray<int> misses(10000); NgArray<int> misses(10000);
misses = 0; misses = 0;
(*testout) << "edgepoint_dom = " << endl << edgepoint_dom << endl; // (*testout) << "edgepoint_dom = " << endl << edgepoint_dom << endl;
for( int i = 0; i<elements.Size(); i++) for( int i = 0; i<elements.Size(); i++)

View File

@ -3705,14 +3705,14 @@ namespace netgen
for (i = 1; i <= GetNSeg(); i++) for (i = 1; i <= GetNSeg(); i++)
{ {
const Segment & seg = LineSegment(i); const Segment & seg = LineSegment(i);
INDEX_2 i2(seg[0], seg[1]); PointIndices<2> i2(seg[0], seg[1]);
i2.Sort(); i2.Sort();
bedges.Set (i2, 1); bedges.Set (i2, 1);
} }
for (i = 1; i <= GetNSE(); i++) for (i = 1; i <= GetNSE(); i++)
{ {
const Element2d & sel = SurfaceElement(i); const Element2d & sel = SurfaceElement(i);
if (!sel.PNum(1)) if (!sel.PNum(1).IsValid())
continue; continue;
for (j = 1; j <= 3; j++) for (j = 1; j <= 3; j++)
{ {

View File

@ -217,7 +217,7 @@ namespace netgen
return; return;
idmap_type map; idmap_type map;
std::set<std::tuple<int,int,int>> hex_faces; std::set<std::tuple<PointIndex,PointIndex,PointIndex>> hex_faces;
for(auto identnr : Range(1,nmax+1)) for(auto identnr : Range(1,nmax+1))
{ {
if(identifications.GetType(identnr) != Identifications::CLOSESURFACES) if(identifications.GetType(identnr) != Identifications::CLOSESURFACES)
@ -248,7 +248,7 @@ namespace netgen
// insert prism/hex // insert prism/hex
auto np = sel.GetNP(); auto np = sel.GetNP();
Element el(2*np); Element el(2*np);
std::set<int> pis; std::set<PointIndex> pis;
for(auto i : Range(np)) for(auto i : Range(np))
{ {
el[i] = sel[i]; el[i] = sel[i];

View File

@ -858,7 +858,8 @@ namespace netgen
const Element2d & el = locelements.Get(i); const Element2d & el = locelements.Get(i);
for (int j = 1; j <= el.GetNP(); j++) for (int j = 1; j <= el.GetNP(); j++)
if (el.PNum(j) <= oldnp && pindex.Get(el.PNum(j)) == -1) // if (el.PNum(j) <= oldnp && pindex.Get(el.PNum(j)) == -1)
if (el.PNum(j) < IndexBASE<PointIndex>()+oldnp && pindex.Get(el.PNum(j)) == -1)
{ {
found = 0; found = 0;
PrintSysError ("meshing2, index missing"); PrintSysError ("meshing2, index missing");

View File

@ -237,7 +237,7 @@ namespace netgen
{ {
for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++)
{ {
pnum[i] = 0; pnum[i].Invalidate();
geominfo[i].trignum = 0; geominfo[i].trignum = 0;
} }
np = 3; np = 3;
@ -331,8 +331,8 @@ namespace netgen
np = 4; np = 4;
typ = QUAD; typ = QUAD;
pnum[4] = 0; pnum[4].Invalidate();
pnum[5] = 0; pnum[5].Invalidate();
for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++)
geominfo[i].trignum = 0; geominfo[i].trignum = 0;
@ -1038,7 +1038,7 @@ namespace netgen
{ {
s << "np = " << el.GetNP(); s << "np = " << el.GetNP();
for (int j = 0; j < el.GetNP(); j++) for (int j = 0; j < el.GetNP(); j++)
s << " " << int(el[j]); s << " " << el[j];
return s; return s;
} }

View File

@ -232,6 +232,7 @@ namespace netgen
friend bool operator< (PointIndex a, PointIndex b); friend bool operator< (PointIndex a, PointIndex b);
friend bool operator> (PointIndex a, PointIndex b); friend bool operator> (PointIndex a, PointIndex b);
friend bool operator>= (PointIndex a, PointIndex b); friend bool operator>= (PointIndex a, PointIndex b);
friend bool operator<= (PointIndex a, PointIndex b);
friend constexpr bool operator== (PointIndex a, PointIndex b); friend constexpr bool operator== (PointIndex a, PointIndex b);
friend constexpr bool operator!= (PointIndex a, PointIndex b); friend constexpr bool operator!= (PointIndex a, PointIndex b);
@ -268,6 +269,7 @@ namespace netgen
inline bool operator< (PointIndex a, PointIndex b) { return a.i-b.i < 0; } inline bool operator< (PointIndex a, PointIndex b) { return a.i-b.i < 0; }
inline bool operator> (PointIndex a, PointIndex b) { return a.i-b.i > 0; } inline bool operator> (PointIndex a, PointIndex b) { return a.i-b.i > 0; }
inline bool operator>= (PointIndex a, PointIndex b) { return a.i-b.i >= 0; } inline bool operator>= (PointIndex a, PointIndex b) { return a.i-b.i >= 0; }
inline bool operator<= (PointIndex a, PointIndex b) { return a.i-b.i <= 0; }
inline constexpr bool operator== (PointIndex a, PointIndex b) { return a.i == b.i; } inline constexpr bool operator== (PointIndex a, PointIndex b) { return a.i == b.i; }
inline constexpr bool operator!= (PointIndex a, PointIndex b) { return a.i != b.i; } inline constexpr bool operator!= (PointIndex a, PointIndex b) { return a.i != b.i; }
} }
@ -387,32 +389,66 @@ namespace netgen
{ Sort(); } { Sort(); }
}; };
constexpr inline size_t HashValue2 (const PointIndex & ind, size_t mask) // constexpr inline size_t HashValue2 (const PointIndex & ind, size_t mask)
{ return (ind-IndexBASE<PointIndex>()) & mask; } // { return (ind-IndexBASE<PointIndex>()) & mask; }
} }
namespace ngcore namespace ngcore
{ {
template <typename T> constexpr inline T InvalidHash();
template <>
struct CHT_trait<netgen::PointIndex>
{
constexpr static inline netgen::PointIndex Invalid() { return netgen::PointIndex::INVALID; }
constexpr static inline size_t HashValue (const netgen::PointIndex & hash, size_t mask)
{ return (hash-IndexBASE<netgen::PointIndex>()) & mask; }
};
template <> template <>
constexpr inline netgen::PointIndex InvalidHash<netgen::PointIndex> () struct CHT_trait<netgen::PointIndices<2>>
{ return netgen::PointIndex::INVALID; } {
constexpr static inline netgen::PointIndices<2> Invalid() { return { netgen::PointIndex::INVALID, netgen::PointIndex::INVALID} ; }
constexpr static inline size_t HashValue (const netgen::PointIndices<2> & hash, size_t mask)
{ return HashValue2(IVec<2>(hash[0]-IndexBASE<netgen::PointIndex>(),
hash[1]-IndexBASE<netgen::PointIndex>()), mask); }
};
template <> template <>
constexpr inline netgen::PointIndices<2> InvalidHash<netgen::PointIndices<2>> () struct CHT_trait<netgen::SortedPointIndices<2>>
{ return netgen::PointIndices<2>{netgen::PointIndex::INVALID, netgen::PointIndex::INVALID}; } {
constexpr static inline netgen::SortedPointIndices<2> Invalid() { return { netgen::PointIndex::INVALID, netgen::PointIndex::INVALID} ; }
constexpr static inline size_t HashValue (const netgen::SortedPointIndices<2> & hash, size_t mask)
// { return HashValue2(IVec<2,netgen::INDEX>(hash[0], hash[1]), mask); }
{ return CHT_trait<netgen::PointIndices<2>>::HashValue (hash, mask); }
};
// template <typename T> constexpr inline T InvalidHash();
// template <>
// constexpr inline netgen::PointIndex InvalidHash<netgen::PointIndex> ()
// { return netgen::PointIndex::INVALID; }
// template <>
// constexpr inline netgen::PointIndices<2> InvalidHash<netgen::PointIndices<2>> ()
// { return netgen::PointIndices<2>{netgen::PointIndex::INVALID, netgen::PointIndex::INVALID}; }
template <> template <>
constexpr inline netgen::PointIndices<3> InvalidHash<netgen::PointIndices<3>> () constexpr inline netgen::PointIndices<3> InvalidHash<netgen::PointIndices<3>> ()
{ return netgen::PointIndices<3>{netgen::PointIndex::INVALID, netgen::PointIndex::INVALID, netgen::PointIndex::INVALID}; } { return netgen::PointIndices<3>{netgen::PointIndex::INVALID, netgen::PointIndex::INVALID, netgen::PointIndex::INVALID}; }
/*
template <> template <>
constexpr inline netgen::SortedPointIndices<2> InvalidHash<netgen::SortedPointIndices<2>> () constexpr inline netgen::SortedPointIndices<2> InvalidHash<netgen::SortedPointIndices<2>> ()
{ return InvalidHash<netgen::PointIndices<2>>(); } // { return InvalidHash<netgen::PointIndices<2>>(); }
{ return CHT_trait<netgen::PointIndices<2>>::Invalid(); }
*/
} }

View File

@ -376,7 +376,7 @@ int Meshing3 :: ApplyRules
{ {
PointIndex locpi = locface->PNumMod(j+locfr); PointIndex locpi = locface->PNumMod(j+locfr);
if (rule->GetPointNr (nfok, j) <= 3 && if (rule->GetPointNr (nfok, j) < IndexBASE<PointIndex>()+3 &&
pmap.Get(rule->GetPointNr(nfok, j)) != locpi) pmap.Get(rule->GetPointNr(nfok, j)) != locpi)
(*testout) << "change face1 point, mark1" << endl; (*testout) << "change face1 point, mark1" << endl;
@ -797,9 +797,9 @@ int Meshing3 :: ApplyRules
hc = 0; hc = 0;
for (int k = rule->GetNOldF() + 1; k <= rule->GetNF(); k++) for (int k = rule->GetNOldF() + 1; k <= rule->GetNF(); k++)
{ {
if (rule->GetPointNr(k, 1) <= rule->GetNOldP() && if (rule->GetPointNr(k, 1) < IndexBASE<PointIndex>()+rule->GetNOldP() &&
rule->GetPointNr(k, 2) <= rule->GetNOldP() && rule->GetPointNr(k, 2) < IndexBASE<PointIndex>()+rule->GetNOldP() &&
rule->GetPointNr(k, 3) <= rule->GetNOldP()) rule->GetPointNr(k, 3) < IndexBASE<PointIndex>()+rule->GetNOldP())
{ {
for (int j = 1; j <= 3; j++) for (int j = 1; j <= 3; j++)
if (lfaces[i-1].PNumMod(j ) == pmap.Get(rule->GetPointNr(k, 1)) && if (lfaces[i-1].PNumMod(j ) == pmap.Get(rule->GetPointNr(k, 1)) &&

View File

@ -584,7 +584,7 @@ namespace netgen
// meshthis -> ProjectPoint (surfi, pp1); // meshthis -> ProjectPoint (surfi, pp1);
// meshthis -> GetNormalVector (surfi, pp1, n); // meshthis -> GetNormalVector (surfi, pp1, n);
static NgArray<Point<2>> pts2d; static NgArray<Point<2>> pts2d; // better: use hashtable
pts2d.SetSize(mesh.GetNP()); pts2d.SetSize(mesh.GetNP());
grad = 0; grad = 0;

View File

@ -126,7 +126,8 @@ void CutOffAndCombine (Mesh & mesh, const Mesh & othermesh)
for (j = 1; j <= 3; j++) for (j = 1; j <= 3; j++)
locked.Clear (mesh.OpenElement(i).PNum(j)); locked.Clear (mesh.OpenElement(i).PNum(j));
for (PointIndex i (1); i <= locked.Size(); i++) // for (PointIndex i (1); i <= locked.Size(); i++)
for (PointIndex i : locked.Range())
if (locked.Test(i)) if (locked.Test(i))
{ {
mesh.AddLockedPoint (i); mesh.AddLockedPoint (i);