From 32e0026128d2566d257bc3122cdbdabeaafec445 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Mon, 2 Dec 2024 19:35:49 +0100 Subject: [PATCH 1/4] Some memory tracer fixes/features If range checks are enabled: - Trace all objects - Check if memory usage never gets negative - Check if memory usage is 0 in destructor - Track total memory usage (use pyngcore.GetTotalMemory()) --- libsrc/core/array.hpp | 26 ++++--- libsrc/core/bitarray.cpp | 5 +- libsrc/core/bitarray.hpp | 9 ++- libsrc/core/exception.cpp | 6 +- libsrc/core/exception.hpp | 19 ++--- libsrc/core/memtracer.hpp | 102 ++++++++++++++++++++------- libsrc/core/profiler.cpp | 1 + libsrc/core/python_ngcore_export.cpp | 2 + libsrc/core/table.hpp | 9 ++- 9 files changed, 126 insertions(+), 53 deletions(-) diff --git a/libsrc/core/array.hpp b/libsrc/core/array.hpp index 51ed0d10..462f56b2 100644 --- a/libsrc/core/array.hpp +++ b/libsrc/core/array.hpp @@ -687,6 +687,7 @@ namespace ngcore size_t allocsize; /// that's the data we have to delete, nullptr for not owning the memory T * mem_to_delete; + MemoryTracer mt; using FlatArray::size; @@ -708,6 +709,7 @@ namespace ngcore { allocsize = asize; mem_to_delete = data; + mt.Alloc(sizeof(T)*asize); } @@ -717,7 +719,10 @@ namespace ngcore { allocsize = asize; if(ownMemory) + { mem_to_delete = adata; + mt.Alloc(sizeof(T)*asize); + } else mem_to_delete = nullptr; } @@ -733,8 +738,7 @@ namespace ngcore NETGEN_INLINE Array (Array && a2) { - mt.Swap(0., a2.mt, sizeof(T) * a2.allocsize); - + mt = std::move(a2.mt); size = a2.size; data = a2.data; allocsize = a2.allocsize; @@ -753,6 +757,7 @@ namespace ngcore { allocsize = size; mem_to_delete = data; + mt.Alloc(sizeof(T)*size); for (size_t i = 0; i < size; i++) data[i] = a2.data[i]; } @@ -772,6 +777,7 @@ namespace ngcore { allocsize = size; mem_to_delete = data; + mt.Alloc(sizeof(T)*size); /* for (size_t i = 0; i < size; i++) data[i] = a2[i]; @@ -788,6 +794,7 @@ namespace ngcore { allocsize = size; mem_to_delete = data; + mt.Alloc(sizeof(T)*size); size_t cnt = 0; for (auto val : list) data[cnt++] = val; @@ -800,6 +807,7 @@ namespace ngcore { allocsize = size; mem_to_delete = data; + mt.Alloc(sizeof(T)*size); for(size_t i = 0; i < a2.Size(); i++) data[i] = a2[i]; for (size_t i = a2.Size(), j=0; i < size; i++,j++) @@ -1011,8 +1019,7 @@ namespace ngcore /// steal array NETGEN_INLINE Array & operator= (Array && a2) { - mt.Swap(sizeof(T)*allocsize, a2.mt, sizeof(T)*a2.allocsize); - + mt = std::move(a2.mt); ngcore::Swap (size, a2.size); ngcore::Swap (data, a2.data); ngcore::Swap (allocsize, a2.allocsize); @@ -1086,8 +1093,7 @@ namespace ngcore NETGEN_INLINE void Swap (Array & b) { - mt.Swap(sizeof(T) * allocsize, b.mt, sizeof(T) * b.allocsize); - + mt = std::move(b.mt); ngcore::Swap (size, b.size); ngcore::Swap (data, b.data); ngcore::Swap (allocsize, b.allocsize); @@ -1096,7 +1102,8 @@ namespace ngcore NETGEN_INLINE void StartMemoryTracing () const { - mt.Alloc(sizeof(T) * allocsize); + if(mem_to_delete) + mt.Alloc(sizeof(T) * allocsize); } const MemoryTracer& GetMemoryTracer() const { return mt; } @@ -1105,7 +1112,6 @@ namespace ngcore /// resize array, at least to size minsize. copy contents NETGEN_INLINE void ReSize (size_t minsize); - MemoryTracer mt; }; @@ -1158,6 +1164,7 @@ namespace ngcore using Array::allocsize; using Array::data; using Array::mem_to_delete; + using Array::mt; // using Array::ownmem; public: @@ -1171,6 +1178,7 @@ namespace ngcore data = new T[asize]; allocsize = size; mem_to_delete = data; + mt.Alloc(sizeof(T)*asize); } } @@ -1191,6 +1199,7 @@ namespace ngcore ArrayMem(ArrayMem && a2) : Array (a2.Size(), (T*)mem) { + mt = std::move(a2.mt); if (a2.mem_to_delete) { mem_to_delete = a2.mem_to_delete; @@ -1233,6 +1242,7 @@ namespace ngcore ArrayMem & operator= (ArrayMem && a2) { + mt = std::move(a2.mt); ngcore::Swap (mem_to_delete, a2.mem_to_delete); ngcore::Swap (allocsize, a2.allocsize); ngcore::Swap (size, a2.size); diff --git a/libsrc/core/bitarray.cpp b/libsrc/core/bitarray.cpp index 8c76ba90..1c6f6ec4 100644 --- a/libsrc/core/bitarray.cpp +++ b/libsrc/core/bitarray.cpp @@ -40,12 +40,13 @@ namespace ngcore if (owns_data) { delete [] data; - mt.Free(Addr(size)+1); + mt.Free(GetMemoryUsage()); } size = asize; data = new unsigned char [Addr (size)+1]; - mt.Alloc(Addr(size)+1); + owns_data = true; + mt.Alloc(GetMemoryUsage()); } BitArray & BitArray :: Set () throw() diff --git a/libsrc/core/bitarray.hpp b/libsrc/core/bitarray.hpp index 8ae32e3c..91259e91 100644 --- a/libsrc/core/bitarray.hpp +++ b/libsrc/core/bitarray.hpp @@ -49,6 +49,7 @@ public: { ba2.owns_data = false; ba2.data = nullptr; + mt = std::move(ba2.mt); } template @@ -59,13 +60,17 @@ public: int cnt = 0; for (auto i = list.begin(); i < list.end(); i++, cnt++) if (*i) SetBit(cnt); + StartMemoryTracing(); } /// delete data ~BitArray () { if (owns_data) + { delete [] data; + mt.Free(GetMemoryUsage()); + } } /// Set size, loose values @@ -150,11 +155,11 @@ public: NGCORE_API auto * Data() const { return data; } + const size_t GetMemoryUsage() const { return owns_data ? (size+CHAR_BIT-1)/CHAR_BIT : 0; } const MemoryTracer& GetMemoryTracer() const { return mt; } void StartMemoryTracing() const { - if(owns_data) - mt.Alloc(Addr(size)+1); + mt.Alloc(GetMemoryUsage()); } private: diff --git a/libsrc/core/exception.cpp b/libsrc/core/exception.cpp index 8e2f251e..1411b25e 100644 --- a/libsrc/core/exception.cpp +++ b/libsrc/core/exception.cpp @@ -50,7 +50,7 @@ namespace ngcore RangeException :: RangeException (// const std::string & where, const char * where, - int ind, int imin, int imax) : Exception("") + ptrdiff_t ind, ptrdiff_t imin, ptrdiff_t imax) : Exception("") { std::stringstream str; str << where << ": index " << ind << " out of range [" << imin << "," << imax << ")\n"; @@ -59,7 +59,7 @@ namespace ngcore } - void ThrowRangeException(const char * s, int ind, int imin, int imax) + void ThrowRangeException(const char * s, ptrdiff_t ind, ptrdiff_t imin, ptrdiff_t imax) { throw RangeException(s, ind, imin, imax); } @@ -75,7 +75,7 @@ namespace ngcore } - void ThrowNotTheSameException(const char * s, long int a, long int b) + void ThrowNotTheSameException(const char * s, ptrdiff_t a, ptrdiff_t b) { throw ngcore::Exception(std::string(s) + ", a="+ToString(a) + ", b="+ToString(b) + GetBackTrace()); } diff --git a/libsrc/core/exception.hpp b/libsrc/core/exception.hpp index 72d0ce9c..8615afc1 100644 --- a/libsrc/core/exception.hpp +++ b/libsrc/core/exception.hpp @@ -1,6 +1,7 @@ #ifndef NETGEN_CORE_EXCEPTION_HPP #define NETGEN_CORE_EXCEPTION_HPP +#include #include // for stringstream #include // for exception #include // for string @@ -66,7 +67,7 @@ namespace ngcore /// where it occurs, index, minimal and maximal indices RangeException (// const std::string & where, const char * where, - int ind, int imin, int imax); + ptrdiff_t ind, ptrdiff_t imin, ptrdiff_t imax); /* : Exception("") { @@ -85,8 +86,8 @@ namespace ngcore } }; - [[noreturn]] NGCORE_API void ThrowRangeException(const char * s, int ind, int imin, int imax); - [[noreturn]] NGCORE_API void ThrowNotTheSameException(const char * s, long int a, long int b); + [[noreturn]] NGCORE_API void ThrowRangeException(const char * s, ptrdiff_t ind, ptrdiff_t imin, ptrdiff_t imax); + [[noreturn]] NGCORE_API void ThrowNotTheSameException(const char * s, ptrdiff_t a, ptrdiff_t b); // Exception used if no simd implementation is available to fall back to standard evaluation @@ -98,12 +99,12 @@ namespace ngcore constexpr operator bool() const { return false; } }; namespace detail { - template - inline static void CheckRange(const char * s, const T& n, int first, int next) + template + inline static void CheckRange(const char * s, const T& n, Tmin first, Tmax next) { if constexpr (!IsSafe()) if (n=next) - ThrowRangeException(s, int(n), first, next); + ThrowRangeException(s, ptrdiff_t(n), ptrdiff_t(first), ptrdiff_t(next)); } template @@ -112,10 +113,10 @@ namespace ngcore if constexpr (!IsSafe() || !IsSafe()) if(a != b) { - if constexpr(std::is_same() && std::is_same()) + if constexpr(std::is_integral_v && std::is_same_v) ThrowNotTheSameException(s, long(a), long(b)); \ else - throw Exception(std::string(s) + "\t: not the same"+ToString(a) + ", b="+ngcore::ToString(b) + GetBackTrace()); + throw Exception(std::string(s) + "\t: not the same, a="+ToString(a) + ", b="+ngcore::ToString(b) + GetBackTrace()); } } } // namespace detail @@ -128,7 +129,7 @@ namespace ngcore #define NG_EXCEPTION(s) ngcore::Exception(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t"+std::string(s)) #if defined(NETGEN_ENABLE_CHECK_RANGE) && !defined(__CUDA_ARCH__) -#define NETGEN_CHECK_RANGE(value, min, max_plus_one) ngcore::detail::CheckRange(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", value, int(min), int(max_plus_one)); +#define NETGEN_CHECK_RANGE(value, min, max_plus_one) ngcore::detail::CheckRange(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", value, min, max_plus_one); #define NETGEN_CHECK_SAME(a,b) ngcore::detail::CheckSame(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", a, b); #define NETGEN_NOEXCEPT diff --git a/libsrc/core/memtracer.hpp b/libsrc/core/memtracer.hpp index 2e5a0e30..757e6405 100644 --- a/libsrc/core/memtracer.hpp +++ b/libsrc/core/memtracer.hpp @@ -35,11 +35,16 @@ namespace ngcore class MemoryTracer { - #if defined(NETGEN_TRACE_MEMORY) && !defined(__CUDA_ARCH__) +#if defined(NETGEN_TRACE_MEMORY) && !defined(__CUDA_ARCH__) NGCORE_API static std::vector names; NGCORE_API static std::vector parents; - static int CreateId(const std::string& name) + #if defined(NETGEN_CHECK_RANGE) + NGCORE_API static std::atomic total_memory; + mutable size_t allocated_memory = 0; + #endif // NETGEN_CHECK_RANGE + + static int CreateId(const std::string& name = "") { int id = names.size(); names.push_back(name); @@ -48,7 +53,7 @@ namespace ngcore std::cerr << "Allocated " << id << " MemoryTracer objects" << std::endl; return id; } - int id; + mutable int id = 0; public: @@ -57,8 +62,33 @@ namespace ngcore id = CreateId(name); } - // not tracing - MemoryTracer() : id(0) {} + MemoryTracer() { } + + MemoryTracer(const MemoryTracer & tracer) + { + (*this) = tracer; + } + + MemoryTracer(MemoryTracer && tracer) + { + (*this) = std::move(tracer); + } + + MemoryTracer & operator=(const MemoryTracer & tracer) { + if(tracer.id) + id = CreateId(names[tracer.id]); + return *this; + } + + MemoryTracer & operator=(MemoryTracer && tracer) { + ngcore::Swap(id, tracer.id); + + #if defined(NETGEN_CHECK_RANGE) + ngcore::Swap(allocated_memory, tracer.allocated_memory); + #endif // NETGEN_CHECK_RANGE + + return *this; + } template MemoryTracer( std::string name, TRest & ... rest ) @@ -67,38 +97,48 @@ namespace ngcore Track(rest...); } + #if defined(NETGEN_CHECK_RANGE) + // check if all memory was freed when object is destroyed + ~MemoryTracer() + { + NETGEN_CHECK_SAME(allocated_memory, 0); + } + #endif // NETGEN_CHECK_RANGE + NETGEN_INLINE void Alloc(size_t size) const { + #if defined(NETGEN_CHECK_RANGE) + // Trace also nameless Memtracer objects if range checks are active + if(!id && size) + id = CreateId(); + #endif // NETGEN_CHECK_RANGE + if(id && trace) trace->AllocMemory(id, size); + + #if defined(NETGEN_CHECK_RANGE) + if(id) + { + allocated_memory += size; + total_memory += size; + } + #endif // NETGEN_CHECK_RANGE } void Free(size_t size) const { if(id && trace) trace->FreeMemory(id, size); - } - void Swap(size_t mysize, MemoryTracer& other, size_t other_size) const - { - if(!trace || (id == 0 && other.id == 0)) - return; - if(id == 0) - return trace->ChangeMemory(other.id, mysize - other_size); - if(other.id == 0) - return trace->ChangeMemory(id, other_size - mysize); - - // first decrease memory, otherwise have artificial/wrong high peak memory usage - if(mysizeChangeMemory(other.id, mysize-other_size); - trace->ChangeMemory(id, other_size-mysize); - } - else - { - trace->ChangeMemory(id, other_size-mysize); - trace->ChangeMemory(other.id, mysize-other_size); - } + #if defined(NETGEN_CHECK_RANGE) + if(id) + { + // check if we have at least size bytes of memory currently allocated (such that allocated_memory doesn't get negative) + NETGEN_CHECK_RANGE(allocated_memory, static_cast(size), std::numeric_limits::max()); + allocated_memory -= size; + total_memory -= size; + #endif // NETGEN_CHECK_RANGE + } } int GetId() const { return id; } @@ -148,6 +188,14 @@ namespace ngcore static const std::vector & GetNames() { return names; } static const std::vector & GetParents() { return parents; } + static size_t GetTotalMemory() + { + #if defined(NETGEN_CHECK_RANGE) + return total_memory; + #else + return 0; + #endif // NETGEN_CHECK_RANGE + } #else // defined(NETGEN_TRACE_MEMORY) && !defined(__CUDA_ARCH__) public: MemoryTracer() {} @@ -157,7 +205,6 @@ namespace ngcore void Alloc(size_t /* size */) const {} void Free(size_t /* size */) const {} - void Swap(...) const {} int GetId() const { return 0; } template @@ -166,6 +213,7 @@ namespace ngcore static std::string GetName(int /* id */) { return ""; } std::string GetName() const { return ""; } void SetName(std::string /* name */) const {} + static size_t GetTotalMemory() { return 0; } #endif // NETGEN_TRACE_MEMORY }; } // namespace ngcore diff --git a/libsrc/core/profiler.cpp b/libsrc/core/profiler.cpp index cf49654b..6f257cfb 100644 --- a/libsrc/core/profiler.cpp +++ b/libsrc/core/profiler.cpp @@ -116,6 +116,7 @@ namespace ngcore #ifdef NETGEN_TRACE_MEMORY std::vector MemoryTracer::names{"all"}; std::vector MemoryTracer::parents{-1}; + std::atomic MemoryTracer::total_memory{0}; #endif // NETGEN_TRACE_MEMORY } // namespace ngcore diff --git a/libsrc/core/python_ngcore_export.cpp b/libsrc/core/python_ngcore_export.cpp index eea84619..cc9f5a70 100644 --- a/libsrc/core/python_ngcore_export.cpp +++ b/libsrc/core/python_ngcore_export.cpp @@ -324,6 +324,8 @@ threads : int #endif // NETGEN_TRACE_MEMORY ; + m.def("GetTotalMemory", MemoryTracer::GetTotalMemory); + py::class_> (m, "Timer") .def(py::init()) .def("Start", static_cast::*)()const>(&Timer<>::Start), "start timer") diff --git a/libsrc/core/table.hpp b/libsrc/core/table.hpp index 47893ed5..134ed8a9 100644 --- a/libsrc/core/table.hpp +++ b/libsrc/core/table.hpp @@ -130,6 +130,7 @@ namespace ngcore { for (size_t i : IntRange(size+1)) index[i] = i*entrysize; + mt.Alloc(GetMemUsage()); } /// Construct table of variable entrysize @@ -141,6 +142,7 @@ namespace ngcore index = TablePrefixSum (FlatArray (entrysize.Size(), entrysize.Data())); size_t cnt = index[size]; data = new T[cnt]; + mt.Alloc(GetMemUsage()); } explicit NETGEN_INLINE Table (const FlatTable & tab2) @@ -157,6 +159,7 @@ namespace ngcore size_t cnt = index[size]; data = new T[cnt]; this->AsArray() = tab2.AsArray(); + mt.Alloc(GetMemUsage()); /* for (size_t i = 0; i < cnt; i++) data[i] = tab2.data[i]; @@ -177,12 +180,14 @@ namespace ngcore data = new T[cnt]; for (size_t i = 0; i < cnt; i++) data[i] = tab2.data[i]; + + mt.Alloc(GetMemUsage()); } NETGEN_INLINE Table (Table && tab2) : FlatTable(0, nullptr, nullptr) { - tab2.mt.Free(tab2.GetMemUsage()); + mt = std::move(tab2.mt); Swap (size, tab2.size); Swap (index, tab2.index); Swap (data, tab2.data); @@ -210,7 +215,7 @@ namespace ngcore NETGEN_INLINE Table & operator= (Table && tab2) { - mt.Swap(GetMemUsage(), tab2.mt, tab2.GetMemUsage()); + mt = std::move(tab2.mt); Swap (size, tab2.size); Swap (index, tab2.index); Swap (data, tab2.data); From 0c1943c77b6d85187a9f62f7408655a4551144d5 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 3 Dec 2024 12:50:14 +0100 Subject: [PATCH 2/4] Fix bug in nginterface (discovered by gcc -Wall) --- libsrc/interface/nginterface.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libsrc/interface/nginterface.cpp b/libsrc/interface/nginterface.cpp index 5181be4c..1c79ff78 100644 --- a/libsrc/interface/nginterface.cpp +++ b/libsrc/interface/nginterface.cpp @@ -2246,11 +2246,8 @@ int Ng_GetClosureNodes (int nt, int nodenr, int nodeset, int * nodes) if (nodeset & 2) // Edges { - int edges[12]; - // int ned; - // ned = mesh->GetTopology().GetElementEdges (nodenr+1, edges, 0); - int ned = mesh->GetTopology().GetEdges (ElementIndex(nodenr)).Size(); - for (int i = 0; i < ned; i++) + auto edges = mesh->GetTopology().GetEdges (ElementIndex(nodenr)); + for (int i = 0; i < edges.Size(); i++) { nodes[cnt++] = 1; nodes[cnt++] = edges[i]-1; From 3bfa6c19fa8964700c08c0b92c99558523671761 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 3 Dec 2024 13:05:33 +0100 Subject: [PATCH 3/4] Fix build warnings (found with gcc -Wall) --- libsrc/core/array.hpp | 3 ++ libsrc/csg/csgeom.cpp | 2 +- libsrc/general/table.cpp | 2 +- libsrc/interface/nginterface_v2.cpp | 2 +- libsrc/interface/readuser.cpp | 4 +-- libsrc/interface/rw_medit.cpp | 26 ++++++++-------- libsrc/interface/writeuser.cpp | 2 +- libsrc/linalg/densemat.cpp | 4 +-- libsrc/meshing/boundarylayer.cpp | 6 ++-- libsrc/meshing/improve3.cpp | 5 +-- libsrc/meshing/meshclass.cpp | 4 +-- libsrc/meshing/meshfunc.cpp | 48 ++++++++++++++--------------- libsrc/meshing/meshtype.hpp | 3 +- libsrc/meshing/python_mesh.cpp | 2 +- libsrc/stlgeom/python_stl.cpp | 2 +- libsrc/visualization/vsmesh.cpp | 4 +-- libsrc/visualization/vssolution.cpp | 4 +-- ng/ngpkg.cpp | 10 +++--- 18 files changed, 68 insertions(+), 65 deletions(-) diff --git a/libsrc/core/array.hpp b/libsrc/core/array.hpp index 462f56b2..e5afa3a5 100644 --- a/libsrc/core/array.hpp +++ b/libsrc/core/array.hpp @@ -842,6 +842,9 @@ namespace ngcore NETGEN_INLINE void NothingToDelete () { mem_to_delete = nullptr; + + // this memory is not managed by the Array anymore, so set the memory usage to 0 + mt.Free(sizeof(T)*allocsize); } /// Change logical size. If necessary, do reallocation. Keeps contents. diff --git a/libsrc/csg/csgeom.cpp b/libsrc/csg/csgeom.cpp index 2d5dcfef..dcc6c666 100644 --- a/libsrc/csg/csgeom.cpp +++ b/libsrc/csg/csgeom.cpp @@ -1211,7 +1211,7 @@ namespace netgen PrintMessage (2, "Object ", i, " has ", tams->GetNT(), " triangles"); } } - catch (exception) + catch (const std::exception &) { cerr << "*************************************************************" << endl << "**** out of memory problem in CSG visualization ****" << endl diff --git a/libsrc/general/table.cpp b/libsrc/general/table.cpp index 18d9cf7e..dad727ac 100644 --- a/libsrc/general/table.cpp +++ b/libsrc/general/table.cpp @@ -109,7 +109,7 @@ namespace netgen { void * p = new char [(line.maxsize+5) * elsize]; - if (line.maxsize*elsize) + if (line.maxsize && elsize) memcpy (p, line.col, line.maxsize * elsize); delete [] (char*)line.col; diff --git a/libsrc/interface/nginterface_v2.cpp b/libsrc/interface/nginterface_v2.cpp index 970070b6..a6fb2c0a 100644 --- a/libsrc/interface/nginterface_v2.cpp +++ b/libsrc/interface/nginterface_v2.cpp @@ -1041,7 +1041,7 @@ namespace netgen build_searchtree); return ind - 1; } - catch(NgException e) // quads not implemented curved yet + catch(const NgException & e) // quads not implemented curved yet { for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) { diff --git a/libsrc/interface/readuser.cpp b/libsrc/interface/readuser.cpp index 3ad4a33d..f74f55a4 100644 --- a/libsrc/interface/readuser.cpp +++ b/libsrc/interface/readuser.cpp @@ -301,7 +301,7 @@ namespace netgen in >> name; cout << IM(3) << len << " element are in group " << name << endl; int hi, index; - int fdnr, ednr; + int fdnr=-1, ednr=-1; in >> hi >> index >> hi >> hi; int codim = get<1>(element_map[index]); @@ -712,7 +712,7 @@ namespace netgen if(!UserFormatRegister::HaveFormat(format)) throw Exception("Unknown format: " + format); - const auto & entry = UserFormatRegister::Get(format); + const auto entry = UserFormatRegister::Get(format); if(!entry.read) throw Exception("Reading format " + format + " is not implemented"); diff --git a/libsrc/interface/rw_medit.cpp b/libsrc/interface/rw_medit.cpp index e2d63854..d952d344 100644 --- a/libsrc/interface/rw_medit.cpp +++ b/libsrc/interface/rw_medit.cpp @@ -53,8 +53,8 @@ void ReadMeditFormat (Mesh & mesh, const filesystem::path & filename, map> p[i]; - fin >> index; - mesh.AddPoint(p); + fin >> index; + mesh.AddPoint(p); } } else if(token == "Edges") { @@ -64,10 +64,10 @@ void ReadMeditFormat (Mesh & mesh, const filesystem::path & filename, map> seg[i]; - fin >> seg.edgenr; - seg.edgenr = getIndex(1, seg.edgenr); - seg.si = seg.edgenr; - mesh.AddSegment(seg); + fin >> seg.edgenr; + seg.edgenr = getIndex(1, seg.edgenr); + seg.si = seg.edgenr; + mesh.AddSegment(seg); } } else if(token == "Triangles") { @@ -77,9 +77,9 @@ void ReadMeditFormat (Mesh & mesh, const filesystem::path & filename, map> sel[i]; - fin >> index; - sel.SetIndex(getIndex(2, index)); - mesh.AddSurfaceElement(sel); + fin >> index; + sel.SetIndex(getIndex(2, index)); + mesh.AddSurfaceElement(sel); } } else if(token == "Tetrahedra") { @@ -89,10 +89,10 @@ void ReadMeditFormat (Mesh & mesh, const filesystem::path & filename, map> el[i]; - fin >> index; - el.SetIndex(getIndex(3, index)); - el.Invert(); - mesh.AddVolumeElement(el); + fin >> index; + el.SetIndex(getIndex(3, index)); + el.Invert(); + mesh.AddVolumeElement(el); } } else if(token == "Corners") { diff --git a/libsrc/interface/writeuser.cpp b/libsrc/interface/writeuser.cpp index 04f3780f..bfab7fbb 100644 --- a/libsrc/interface/writeuser.cpp +++ b/libsrc/interface/writeuser.cpp @@ -39,7 +39,7 @@ bool WriteUserFormat (const string & format, if(!UserFormatRegister::HaveFormat(format)) return true; - const auto & entry = UserFormatRegister::Get(format); + const auto entry = UserFormatRegister::Get(format); if(!entry.write) return true; diff --git a/libsrc/linalg/densemat.cpp b/libsrc/linalg/densemat.cpp index 06b8c257..4dd316e0 100644 --- a/libsrc/linalg/densemat.cpp +++ b/libsrc/linalg/densemat.cpp @@ -49,7 +49,7 @@ namespace netgen { data = NULL; height = width = 0; SetSize (m2.Height(), m2.Width()); - if (Height()*Width()) + if (Height() && Width()) memcpy (data, m2.data, sizeof(double) * (Height() * Width())); } @@ -70,7 +70,7 @@ namespace netgen delete[] data; - if (h*w) + if (h && w) data = new double[h*w]; else data = NULL; diff --git a/libsrc/meshing/boundarylayer.cpp b/libsrc/meshing/boundarylayer.cpp index dcadf9c9..b8f442be 100644 --- a/libsrc/meshing/boundarylayer.cpp +++ b/libsrc/meshing/boundarylayer.cpp @@ -788,9 +788,9 @@ namespace netgen if(fabs(mat.Det()) > 1e-6) break; } - int maxpos1; - int maxpos2; - double val = 0; + int maxpos1 = 0; + int maxpos2 = 1; + double val = ns[0] * ns[1]; for (auto i : Range(ns)) { for (auto j : Range(i + 1, ns.Size())) diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index 7e323dfd..f0f566ef 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -1066,7 +1066,8 @@ double MeshOptimize3d :: SwapImproveEdge ( bad3 += GetLegalPenalty(); } - bool swap2, swap3; + bool swap2=false; + bool swap3=false; if (goal == OPT_CONFORM) { @@ -2608,7 +2609,7 @@ double MeshOptimize3d :: SplitImprove2Element ( // search for very flat tets, with two disjoint edges nearly crossing, like a rectangle with diagonals int minedge = -1; double mindist = 1e99; - double minlam0, minlam1; + double minlam0=0, minlam1=0; for (int i : Range(3)) { diff --git a/libsrc/meshing/meshclass.cpp b/libsrc/meshing/meshclass.cpp index 7fa8bfb1..798d737a 100644 --- a/libsrc/meshing/meshclass.cpp +++ b/libsrc/meshing/meshclass.cpp @@ -196,8 +196,8 @@ namespace netgen auto& el = mesh.SurfaceElement(velement); if(el.GetType() == TRIG) { - double seg_lam; - double lam; + double seg_lam=-1; + double lam=-1; auto seg = mesh.LineSegment(segs[i]); for(auto k : Range(3)) { diff --git a/libsrc/meshing/meshfunc.cpp b/libsrc/meshing/meshfunc.cpp index 097dc56e..9a1cf028 100644 --- a/libsrc/meshing/meshfunc.cpp +++ b/libsrc/meshing/meshfunc.cpp @@ -396,8 +396,8 @@ namespace netgen for (int i = 1; i <= mesh.GetNOpenElements(); i++) md.meshing->AddBoundaryElement (mesh.OpenElement(i)); - if (mp.delaunay && mesh.GetNOpenElements()) - { + if (mp.delaunay && mesh.GetNOpenElements()) + { int oldne = mesh.GetNE(); md.meshing->Delaunay (mesh, domain, mp); @@ -408,22 +408,22 @@ namespace netgen PrintMessage (3, mesh.GetNP(), " points, ", mesh.GetNE(), " elements"); mesh.FindOpenElements(domain); - } + } - Box<3> domain_bbox( Box<3>::EMPTY_BOX ); + Box<3> domain_bbox( Box<3>::EMPTY_BOX ); - for (auto & sel : mesh.SurfaceElements()) + for (auto & sel : mesh.SurfaceElements()) { if (sel.IsDeleted() ) continue; for (auto pi : sel.PNums()) domain_bbox.Add (mesh[pi]); } - domain_bbox.Increase (0.01 * domain_bbox.Diam()); + domain_bbox.Increase (0.01 * domain_bbox.Diam()); - int cntsteps = 0; - int meshed; - if (mesh.GetNOpenElements()) + int cntsteps = 0; + int meshed; + if (mesh.GetNOpenElements()) do { if (multithread.terminate) @@ -515,24 +515,22 @@ namespace netgen PrintMessage (1, "Success !"); } } - while (!meshed); - - { - PrintMessage (3, "Check subdomain ", domain, " / ", mesh.GetNDomains()); + while (!meshed); - mesh.FindOpenElements(domain); + PrintMessage (3, "Check subdomain ", domain, " / ", mesh.GetNDomains()); - bool res = (mesh.CheckConsistentBoundary() != 0); - if (res) - { - if(debugparam.write_mesh_on_error) - md.mesh->Save("inconsistent_surface_domain_"+ToString(md.domain)+".vol.gz"); - PrintError ("Surface mesh not consistent"); - throw NgException ("Stop meshing since surface mesh not consistent"); - } - } - RemoveIllegalElements (mesh, domain); - ConformToFreeSegments (mesh, domain); + mesh.FindOpenElements(domain); + + bool res = (mesh.CheckConsistentBoundary() != 0); + if (res) + { + if(debugparam.write_mesh_on_error) + md.mesh->Save("inconsistent_surface_domain_"+ToString(md.domain)+".vol.gz"); + PrintError ("Surface mesh not consistent"); + throw NgException ("Stop meshing since surface mesh not consistent"); + } + RemoveIllegalElements (mesh, domain); + ConformToFreeSegments (mesh, domain); } void MergeMeshes( Mesh & mesh, Array & md ) diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp index c874e6fb..bb09d193 100644 --- a/libsrc/meshing/meshtype.hpp +++ b/libsrc/meshing/meshtype.hpp @@ -175,7 +175,8 @@ namespace netgen } constexpr PointIndex (t_invalid inv) : i(PointIndex::BASE-1) { ; } // PointIndex & operator= (const PointIndex &ai) { i = ai.i; return *this; } - constexpr operator int () const { return i; } + constexpr operator const int& () const { return i; } + explicit constexpr operator int& () { return i; } PointIndex operator++ (int) { PointIndex hi(*this); i++; return hi; } PointIndex operator-- (int) { PointIndex hi(*this); i--; return hi; } PointIndex & operator++ () { i++; return *this; } diff --git a/libsrc/meshing/python_mesh.cpp b/libsrc/meshing/python_mesh.cpp index 0500ac5c..a771ba18 100644 --- a/libsrc/meshing/python_mesh.cpp +++ b/libsrc/meshing/python_mesh.cpp @@ -267,7 +267,7 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) .def(py::init()) .def("__repr__", &ToString) .def("__str__", &ToString) - .def_property_readonly("nr", &PointIndex::operator int) + .def_property_readonly("nr", &PointIndex::operator const int&) .def("__eq__" , FunctionPointer( [](PointIndex &self, PointIndex &other) { return static_cast(self)==static_cast(other); }) ) .def("__hash__" , FunctionPointer( [](PointIndex &self ) { return static_cast(self); }) ) diff --git a/libsrc/stlgeom/python_stl.cpp b/libsrc/stlgeom/python_stl.cpp index f25d347c..a56c0eed 100644 --- a/libsrc/stlgeom/python_stl.cpp +++ b/libsrc/stlgeom/python_stl.cpp @@ -224,7 +224,7 @@ NGCORE_API_EXPORT void ExportSTL(py::module & m) .def("GetVicinity", [] (shared_ptr self, int node, int size, string type) { NgArray vic; - int trig; + int trig=-1; if(type == "trig") trig = node; diff --git a/libsrc/visualization/vsmesh.cpp b/libsrc/visualization/vsmesh.cpp index 17139387..ab9f64a9 100644 --- a/libsrc/visualization/vsmesh.cpp +++ b/libsrc/visualization/vsmesh.cpp @@ -266,7 +266,7 @@ namespace netgen } - catch (bad_weak_ptr e) + catch (const bad_weak_ptr & e) { // cout << "don't have a mesh to visualize" << endl; VisualScene::DrawScene(); @@ -895,7 +895,7 @@ namespace netgen vstimestamp = meshtimestamp; } - catch (bad_weak_ptr e) + catch (const bad_weak_ptr & e) { PrintMessage (3, "vsmesh::buildscene: don't have a mesh to visualize"); VisualScene::BuildScene (zoomall); diff --git a/libsrc/visualization/vssolution.cpp b/libsrc/visualization/vssolution.cpp index 16dd17d0..fadf1eca 100644 --- a/libsrc/visualization/vssolution.cpp +++ b/libsrc/visualization/vssolution.cpp @@ -641,7 +641,7 @@ namespace netgen // delete lock; // mem_lock.UnLock(); } - catch (bad_weak_ptr e) + catch (const bad_weak_ptr & e) { // cout << "don't have a mesh to visualize" << endl; VisualScene::DrawScene(); @@ -1120,7 +1120,7 @@ namespace netgen clipplanetimestamp = max2 (vispar.clipping.timestamp, solutiontimestamp); } - catch (bad_weak_ptr e) + catch (const bad_weak_ptr & e) { PrintMessage (3, "vssolution::buildscene: don't have a mesh to visualize"); VisualScene::BuildScene (zoomall); diff --git a/ng/ngpkg.cpp b/ng/ngpkg.cpp index 8b6a245b..139685c5 100644 --- a/ng/ngpkg.cpp +++ b/ng/ngpkg.cpp @@ -194,7 +194,7 @@ namespace netgen if(mesh->GetGeometry()) ng_geometry = mesh->GetGeometry(); } - catch (NgException e) + catch (const NgException & e) { PrintMessage (3, e.What()); return TCL_ERROR; @@ -269,7 +269,7 @@ namespace netgen geometry -> LoadSurfaces(infile); } } - catch (NgException e) + catch (const NgException & e) { PrintMessage (3, e.What()); return TCL_ERROR; @@ -551,7 +551,7 @@ namespace netgen } } - catch (NgException e) + catch (const NgException & e) { Tcl_SetResult (interp, const_cast (e.What().c_str()), TCL_VOLATILE); return TCL_ERROR; @@ -582,7 +582,7 @@ namespace netgen { ng_geometry -> Save (string (cfilename)); } - catch (NgException e) + catch (const NgException & e) { Tcl_SetResult (interp, const_cast (e.What().c_str()), TCL_VOLATILE); return TCL_ERROR; @@ -1440,7 +1440,7 @@ namespace netgen PrintMessage (1, "Meshing done, time = ", GetTime(), " sec"); } - catch (NgException e) + catch (const NgException & e) { cout << e.What() << endl; } From 519490eceec35ca1862c85eca698c22279fc8b63 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 3 Dec 2024 17:44:08 +0100 Subject: [PATCH 4/4] Workaround to use webgui interface from command line --- python/webgui.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/python/webgui.py b/python/webgui.py index 6fd92eeb..7d5ce705 100644 --- a/python/webgui.py +++ b/python/webgui.py @@ -8,6 +8,9 @@ try: from webgui_jupyter_widgets import BaseWebGuiScene, WebGuiDocuWidget import webgui_jupyter_widgets.widget as wg except ImportError: + class BaseWebGuiScene: + pass + wg = None def encodeData( data, dtype=None, encoding='b64' ): @@ -214,9 +217,13 @@ def GetData(mesh, args, kwargs): d[name] = pnew return d -base = object if wg is None else BaseWebGuiScene -class WebGLScene(base): +class WebGLScene(BaseWebGuiScene): + class Widget: + def __init__(self): + self.value = {} + def __init__(self, obj, args=[], kwargs={}): + self.widget = self.Widget() self.obj = obj self.args = args self.kwargs = kwargs