diff -Nru ngsolve-6.2.2102/basiclinalg/CMakeLists.txt ngsolve-6.2.2103/basiclinalg/CMakeLists.txt --- ngsolve-6.2.2102/basiclinalg/CMakeLists.txt 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/basiclinalg/CMakeLists.txt 2021-06-04 23:31:19.000000000 +0000 @@ -11,9 +11,17 @@ target_link_libraries(kernel_generator PUBLIC ${NETGEN_PYTHON_LIBRARIES}) endif() +if(WIN32) + # run kernel genrator in NETGEN_BINARY_DIR on Windows to find linked .dll files + set(cwd ${NETGEN_BINARY_DIR}) +else() + set(cwd .) +endif() + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/matkernel.hpp - COMMAND kernel_generator + COMMAND kernel_generator "${CMAKE_CURRENT_BINARY_DIR}/matkernel.hpp" DEPENDS kernel_generator + WORKING_DIRECTORY ${cwd} ) add_custom_target(kernel_generated DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/matkernel.hpp) diff -Nru ngsolve-6.2.2102/basiclinalg/expr.hpp ngsolve-6.2.2103/basiclinalg/expr.hpp --- ngsolve-6.2.2102/basiclinalg/expr.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/basiclinalg/expr.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -1928,6 +1928,33 @@ } + template + INLINE Mat<4,4,T> Cof (Mat<4,4,T> m) + { + Mat<4,4,T> cof; + cof(0,0) = (m(1,1)*m(2,2)*m(3,3)+m(1,2)*m(2,3)*m(3,1)+m(1,3)*m(2,1)*m(3,2) - m(1,1)*m(3,2)*m(2,3) - m(2,1)*m(1,2)*m(3,3) - m(3,1)*m(2,2)*m(1,3)); + cof(0,1) = -(m(1,0)*m(2,2)*m(3,3)+m(1,2)*m(2,3)*m(3,0)+m(1,3)*m(2,0)*m(3,2) - m(1,0)*m(3,2)*m(2,3) - m(2,0)*m(1,2)*m(3,3) - m(3,0)*m(2,2)*m(1,3)); + cof(0,2) = (m(1,0)*m(2,1)*m(3,3)+m(1,1)*m(2,3)*m(3,0)+m(1,3)*m(2,0)*m(3,1) - m(1,0)*m(3,1)*m(2,3) - m(2,0)*m(1,1)*m(3,3) - m(3,0)*m(2,1)*m(1,3)); + cof(0,3) = -(m(1,0)*m(2,1)*m(3,2)+m(1,1)*m(2,2)*m(3,0)+m(1,2)*m(2,0)*m(3,1) - m(1,0)*m(3,1)*m(2,2) - m(2,0)*m(1,1)*m(3,2) - m(3,0)*m(2,1)*m(1,2)); + + cof(1,0) = -(m(0,1)*m(2,2)*m(3,3)+m(0,2)*m(2,3)*m(3,1)+m(0,3)*m(2,1)*m(3,2) - m(0,1)*m(3,2)*m(2,3) - m(2,1)*m(0,2)*m(3,3) - m(3,1)*m(2,2)*m(0,3)); + cof(1,1) = (m(0,0)*m(2,2)*m(3,3)+m(0,2)*m(2,3)*m(3,0)+m(0,3)*m(2,0)*m(3,2) - m(0,0)*m(3,2)*m(2,3) - m(2,0)*m(0,2)*m(3,3) - m(3,0)*m(2,2)*m(0,3)); + cof(1,2) = -(m(0,0)*m(2,1)*m(3,3)+m(0,1)*m(2,3)*m(3,0)+m(0,3)*m(2,0)*m(3,1) - m(0,0)*m(3,1)*m(2,3) - m(2,0)*m(0,1)*m(3,3) - m(3,0)*m(2,1)*m(0,3)); + cof(1,3) = (m(0,0)*m(2,1)*m(3,2)+m(0,1)*m(2,2)*m(3,0)+m(0,2)*m(2,0)*m(3,1) - m(0,0)*m(3,1)*m(2,2) - m(2,0)*m(0,1)*m(3,2) - m(3,0)*m(2,1)*m(0,2)); + + cof(2,0) = (m(0,1)*m(1,2)*m(3,3)+m(0,2)*m(1,3)*m(3,1)+m(0,3)*m(1,1)*m(3,2) - m(0,1)*m(3,2)*m(1,3) - m(1,1)*m(0,2)*m(3,3) - m(3,1)*m(1,2)*m(0,3)); + cof(2,1) = -(m(0,0)*m(1,2)*m(3,3)+m(0,2)*m(1,3)*m(3,0)+m(0,3)*m(1,0)*m(3,2) - m(0,0)*m(3,2)*m(1,3) - m(1,0)*m(0,2)*m(3,3) - m(3,0)*m(1,2)*m(0,3)); + cof(2,2) = (m(0,0)*m(1,1)*m(3,3)+m(0,1)*m(1,3)*m(3,0)+m(0,3)*m(1,0)*m(3,1) - m(0,0)*m(3,1)*m(1,3) - m(1,0)*m(0,1)*m(3,3) - m(3,0)*m(1,1)*m(0,3)); + cof(2,3) = -(m(0,0)*m(1,1)*m(3,2)+m(0,1)*m(1,2)*m(3,0)+m(0,2)*m(1,0)*m(3,1) - m(0,0)*m(3,1)*m(1,2) - m(1,0)*m(0,1)*m(3,2) - m(3,0)*m(1,1)*m(0,2)); + + cof(3,0) = -(m(0,1)*m(1,2)*m(2,3)+m(0,2)*m(1,3)*m(2,1)+m(0,3)*m(1,1)*m(2,2) - m(0,1)*m(2,2)*m(1,3) - m(1,1)*m(0,2)*m(2,3) - m(2,1)*m(1,2)*m(0,3)); + cof(3,1) = (m(0,0)*m(1,2)*m(2,3)+m(0,2)*m(1,3)*m(2,0)+m(0,3)*m(1,0)*m(2,2) - m(0,0)*m(2,2)*m(1,3) - m(1,0)*m(0,2)*m(2,3) - m(2,0)*m(1,2)*m(0,3)); + cof(3,2) = -(m(0,0)*m(1,1)*m(2,3)+m(0,1)*m(1,3)*m(2,0)+m(0,3)*m(1,0)*m(2,1) - m(0,0)*m(2,1)*m(1,3) - m(1,0)*m(0,1)*m(2,3) - m(2,0)*m(1,1)*m(0,3)); + cof(3,3) = (m(0,0)*m(1,1)*m(2,2)+m(0,1)*m(1,2)*m(2,0)+m(0,2)*m(1,0)*m(2,1) - m(0,0)*m(2,1)*m(1,2) - m(1,0)*m(0,1)*m(2,2) - m(2,0)*m(1,1)*m(0,2)); + return cof; + } + + diff -Nru ngsolve-6.2.2102/basiclinalg/generate_mat_kernels.cpp ngsolve-6.2.2103/basiclinalg/generate_mat_kernels.cpp --- ngsolve-6.2.2102/basiclinalg/generate_mat_kernels.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/basiclinalg/generate_mat_kernels.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -2307,9 +2307,9 @@ -int main () +int main (int argn, char **argv) { - ofstream out("matkernel.hpp"); + ofstream out(argv[1]); out << "template \n" "void FMAnonasm (SIMD a, SIMD b, SIMD & sum)\n" diff -Nru ngsolve-6.2.2102/basiclinalg/matrix.hpp ngsolve-6.2.2103/basiclinalg/matrix.hpp --- ngsolve-6.2.2102/basiclinalg/matrix.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/basiclinalg/matrix.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -1511,6 +1511,9 @@ INLINE T* Data() const noexcept { return data; } + using CMCPMatExpr::Rows; + using CMCPMatExpr::Cols; + INLINE const SliceMatrix Rows (size_t first, size_t next) const { return SliceMatrix (next-first, w, dist, data+first*dist); @@ -2282,6 +2285,28 @@ }); return res; } + + + + template + INLINE Mat operator+ (const Mat & ma, const Mat & mb) + { + Mat res; + Iterate ([&] (auto i) { + res(i.value) = ma(i.value) + mb(i.value); + }); + return res; + } + + template + INLINE Mat operator- (const Mat & ma, const Mat & mb) + { + Mat res; + Iterate ([&] (auto i) { + res(i.value) = ma(i.value) - mb(i.value); + }); + return res; + } template INLINE Mat operator* (T scal, const Mat & mat) diff -Nru ngsolve-6.2.2102/basiclinalg/ng_lapack.hpp ngsolve-6.2.2103/basiclinalg/ng_lapack.hpp --- ngsolve-6.2.2102/basiclinalg/ng_lapack.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/basiclinalg/ng_lapack.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -108,7 +108,7 @@ integer m = a.Width(); integer n = a.Height(); double alpha = 1; - integer lda = a.Width(); + integer lda = max(size_t(1), a.Width()); integer incx = 1; double beta = 0; integer incy = 1; @@ -123,7 +123,7 @@ integer m = a.Width(); integer n = a.Height(); Complex alpha(1,0); - integer lda = a.Width(); + integer lda = max(size_t(1), a.Width()); integer incx = 1; Complex beta(0, 0); integer incy = 1; @@ -140,7 +140,7 @@ integer m = a.Width(); integer n = a.Height(); double alpha = 1; - integer lda = a.Width(); + integer lda = max(size_t(1), a.Width()); integer incx = 1; double beta = 0; integer incy = 1; @@ -156,7 +156,7 @@ integer m = a.Width(); integer n = a.Height(); double alpha = fac; - integer lda = a.Width(); + integer lda = max(size_t(1), a.Width()); integer incx = 1; integer incy = 1; @@ -181,9 +181,9 @@ integer k = transa ? a.Height() : a.Width(); SCAL alpha = 1.0; SCAL beta = 0; - integer lda = a.Dist(); - integer ldb = b.Dist(); - integer ldc = c.Dist(); + integer lda = max(size_t(1), a.Dist()); + integer ldb = max(size_t(1), b.Dist()); + integer ldc = max(size_t(1), c.Dist()); gemm (&transb_, &transa_, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); @@ -205,9 +205,9 @@ integer k = transa ? a.Height() : a.Width(); SCAL alpha = aalpha; SCAL beta = abeta; - integer lda = a.Dist(); - integer ldb = b.Dist(); - integer ldc = c.Dist(); + integer lda = max(size_t(1), a.Dist()); + integer ldb = max(size_t(1), b.Dist()); + integer ldc = max(size_t(1), c.Dist()); gemm (&transb_, &transa_, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); @@ -512,9 +512,9 @@ integer k = a.Width(); double alpha = 1.0; double beta = 0; - integer lda = a.Dist(); - integer ldb = b.Dist(); - integer ldc = c.Dist(); + integer lda = max(size_t(1), a.Dist()); + integer ldb = max(size_t(1), b.Dist()); + integer ldc = max(size_t(1), c.Dist()); dgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); } @@ -531,9 +531,9 @@ integer k = a.Width(); double alpha = 1.0; double beta = 0; - integer lda = a.Dist(); - integer ldb = b.Dist(); - integer ldc = c.Dist(); + integer lda = max(size_t(1), a.Dist()); + integer ldb = max(size_t(1), b.Dist()); + integer ldc = max(size_t(1), c.Dist()); dgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); } @@ -548,9 +548,9 @@ integer k = a.Height(); double alpha = 1.0; double beta = 0; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Dist(); // c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Dist()); // c.Width(); dgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); } @@ -566,9 +566,9 @@ integer k = a.Height(); double alpha = 1.0; double beta = 0; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); dgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); } @@ -586,9 +586,9 @@ integer k = a.Width(); Complex alpha(1,0); // double alpha[2] = { 1.0, 0.0 }; Complex beta(0,0); // double beta[2] = { 0.0, 0.0 }; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); zgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, @@ -611,9 +611,9 @@ integer k = a.Width(); double alpha = fac; double beta = 1.0; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); dgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); } @@ -631,9 +631,9 @@ integer k = a.Width(); double alpha = fac; double beta = 1.0; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); dgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); } @@ -650,9 +650,9 @@ integer k = a.Height(); double alpha = fac; double beta = 1.0; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); dgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, &a(0,0), &lda, &beta, &c(0,0), &ldc); } @@ -671,9 +671,9 @@ integer k = a.Width(); Complex alpha(fac, 0); Complex beta(1,0); - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); zgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, @@ -696,9 +696,9 @@ integer k = a.Height(); Complex alpha(fac, 0); // double alpha[2] = { fac, 0 }; Complex beta(1,0); // double beta[2] = { 1.0, 0 }; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); zgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, @@ -721,9 +721,9 @@ integer k = a.Width(); Complex alpha(fac, 0); // double alpha[2] = { fac, 0 }; Complex beta(1,0); // double beta[2] = { 1.0, 0 }; - integer lda = a.Width(); - integer ldb = b.Width(); - integer ldc = c.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); + integer ldc = max(size_t(1), c.Width()); zgemm (&transa, &transb, &n, &m, &k, &alpha, &b(0,0), &ldb, @@ -767,7 +767,7 @@ integer m = a.Height(); if (m == 0) return; integer n = a.Width(); - integer lda = a.Dist(); + integer lda = max(size_t(1), a.Dist()); ArrayMem ipiv(n); integer info; @@ -789,7 +789,7 @@ { integer n = a.Width(); if (n == 0) return; - integer lda = a.Dist(); + integer lda = max(size_t(1), a.Dist()); integer info; char uplo = 'U'; @@ -822,8 +822,8 @@ { integer m = a.Height(); integer n = a.Width(); - integer lda = a.Width(); - integer ldb = b.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); integer nrhs = b.Height(); ArrayMem ipiv(n); @@ -913,8 +913,8 @@ { integer m = a.Height(); integer n = a.Width(); - integer lda = a.Width(); - integer ldb = b.Width(); + integer lda = max(size_t(1), a.Width()); + integer ldb = max(size_t(1), b.Width()); integer nrhs = b.Height(); integer * ipiv = new integer[n]; integer lwork = 100*n; diff -Nru ngsolve-6.2.2102/basiclinalg/tensor.hpp ngsolve-6.2.2103/basiclinalg/tensor.hpp --- ngsolve-6.2.2102/basiclinalg/tensor.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/basiclinalg/tensor.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -188,9 +188,18 @@ FlatTensor (LocalHeap & lh, ARG ... args) : FlatTensor (args...) { - size_t totsize = this->GetTotalSize(); + size_t totsize = this->GetTotalSize(); + // TODO: why this call instead of lh.Alloc as in FlatMatrix? this->Data() = new(lh) T[totsize]; - } + } + + template + FlatTensor (T * data, ARG ... args) + : FlatTensor (args...) + { + this->Data() = data; + } + FlatTensor (size_t as, size_t ad, FlatTensor asub) : size(as), dist(ad), sub(asub) { ; } @@ -251,6 +260,48 @@ T *& Data () { return sub.Data(); } T * Data () const { return sub.Data(); } + + + + template + INLINE void SetSize (size_t s, ARG ... args) throw () + { + size = s; + sub.SetSize(args...); + } + + /// TODO: Still problems! + /// copy data and sub pointers + INLINE FlatTensor & Assign (const FlatTensor & m) throw() + { + sub.Assign(m.sub); + dist = m.dist; + size = m.size; + return *this; + } + + //TODO: is this feasible? Still problems! + /// set size, and assign mem + template + INLINE void AssignMemory (LocalHeap & lh, size_t s, ARG ... args) throw () + { + FlatTensor tmp{lh, s, args...}; + Assign(tmp); +// FlatTensor tmp{args...}; +// Assign(tmp); +// size_t totsize = tmp->GetTotalSize(); +// this->Data() = lh.Alloc(totsize); + } + + /// set size, and assign mem + template + INLINE void AssignMemory (T * mem, size_t s, ARG ... args) throw() + { + FlatTensor tmp{mem, s, args...}; + Assign(tmp); +// FlatTensor tmp{args...}; +// this->Data() = mem; + } }; @@ -280,6 +331,31 @@ T & operator= (double d) { *data = d; return *data; } T & operator-= (double d) { *data -= d; return *data; } T & operator+= (double d) { *data += d; return *data; } + + template + INLINE void SetSize (ARG ... args) throw () + { + } + + INLINE void Assign (const FlatTensor& m) throw () + { + this->data = m.data; + } + +// //TODO: is this required? +// /// set size, and assign mem +// template +// INLINE void AssignMemory (LocalHeap & lh, size_t s, ARG ... args) throw () +// { +// this->Data() = lh.Alloc(this->GetSize()); +// } +// +// /// set size, and assign mem +// template +// INLINE void AssignMemory (T * mem, size_t s, ARG ... args) throw() +// { +// this->Data() = mem; +// } }; diff -Nru ngsolve-6.2.2102/cmake/SuperBuild.cmake ngsolve-6.2.2103/cmake/SuperBuild.cmake --- ngsolve-6.2.2102/cmake/SuperBuild.cmake 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/cmake/SuperBuild.cmake 2021-06-04 23:31:19.000000000 +0000 @@ -39,7 +39,7 @@ if(${CMAKE_GENERATOR} STREQUAL "Unix Makefiles") set(COMMON_BUILD_COMMAND $(MAKE) --silent ) else() - set(COMMON_BUILD_COMMAND ${CMAKE_COMMAND} --config ${CMAKE_BUILD_TYPE} --build .) + set(COMMON_BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE} ) endif() ####################################################################### @@ -239,13 +239,16 @@ INTEL_MIC ENABLE_UNIT_TESTS BUILD_STUB_FILES - BUILD_JUPYTER_WIDGETS ) set_flags_vars(NGSOLVE_CMAKE_ARGS CMAKE_CXX_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_LINKER_FLAGS) set(NGSOLVE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX} ${CMAKE_PREFIX_PATH}) +if(DEFINED ENV{CI} AND WIN32) + set(log_output LOG_BUILD ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON) +endif() + ExternalProject_Add (ngsolve DEPENDS ${DEPENDENCIES} ${LAPACK_PROJECTS} SOURCE_DIR ${PROJECT_SOURCE_DIR} @@ -253,6 +256,7 @@ INSTALL_COMMAND "" BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/ngsolve BUILD_COMMAND ${COMMON_BUILD_COMMAND} + ${log_output} ) diff -Nru ngsolve-6.2.2102/CMakeLists.txt ngsolve-6.2.2103/CMakeLists.txt --- ngsolve-6.2.2102/CMakeLists.txt 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/CMakeLists.txt 2021-06-04 23:31:19.000000000 +0000 @@ -24,7 +24,6 @@ option( INSTALL_DEPENDENCIES "install dependencies like netgen or solver libs, useful for packaging" OFF ) option( ENABLE_UNIT_TESTS "Enable Catch unit tests") option( BUILD_STUB_FILES "Build stub files for better autocompletion" ON) -option( BUILD_JUPYTER_WIDGETS "Build javscript widgets library for jupyter" OFF) set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_modules") set(NETGEN_DIR "" CACHE PATH "Path to Netgen, leave empty to build Netgen automatically") @@ -436,6 +435,15 @@ file(RELATIVE_PATH BIN_TO_LIB_RELPATH ${NETGEN_BINARY_DIR} ${NETGEN_LIBRARY_DIR}) elseif(WIN32) set(ngsld_flags "${ngsld_flags} /LIBPATH:\"%NGSCXX_DIR%/${BIN_TO_LIB_RELPATH}\" nglib.lib ngcore.lib libngsolve.lib" ) + set(ngsld_header +"set PYTHON_LIBRARY=${NETGEN_PYTHON_LIBRARIES} +") + if(NETGEN_USE_PYTHON) + set(ngsld_header +"for /f %%a in ('python -c \"import sys,os; print(os.path.join(sys.base_prefix, 'libs'))\"') do set PYTHON_LIBDIR=\"%%a\" +") + set(ngsld_flags "${ngsld_flags} /LIBPATH:\"%PYTHON_LIBDIR%\"") + endif() else() set(ngsld_flags "${ngsld_flags} -L\$NGSCXX_DIR/${BIN_TO_LIB_RELPATH} -Wl,--rpath=\$NGSCXX_DIR/${BIN_TO_LIB_RELPATH}" ) set(ngscxx_header @@ -457,7 +465,7 @@ CONDITION $ ) file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ngsld.bat - CONTENT "${ngscxx_set_script_dir}\n call \"${VCVARSALL}\" amd64\nlink /DLL %* ${ngsld_flags}\n") + CONTENT "${ngscxx_set_script_dir}\n call \"${VCVARSALL}\" amd64\n${ngsld_header}\nlink /DLL %* ${ngsld_flags}\n") install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/ngscxx.bat DESTINATION ${NGSOLVE_INSTALL_DIR_BIN} COMPONENT ngsolve_devel ) install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/ngsld.bat DESTINATION ${NGSOLVE_INSTALL_DIR_BIN} COMPONENT ngsolve_devel ) else(WIN32) diff -Nru ngsolve-6.2.2102/comp/bilinearform.cpp ngsolve-6.2.2103/comp/bilinearform.cpp --- ngsolve-6.2.2102/comp/bilinearform.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/bilinearform.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -6685,13 +6685,11 @@ if ( !low_order_bilinear_form ) for (int finelevel = ma->GetNLevels()-1; finelevel>0; finelevel--) { - SparseMatrix * prolMat = prol->CreateProlongationMatrix (finelevel); + auto prolMat = prol->CreateProlongationMatrix (finelevel); if (prolMat) mats[finelevel-1] = dynamic_cast< const BaseSparseMatrix& >(GetMatrix(finelevel)). Restrict(*prolMat,dynamic_pointer_cast(GetMatrixPtr(finelevel-1))); - - delete prolMat; } } @@ -6986,4 +6984,6 @@ template class T_BilinearForm; template class T_BilinearFormSymmetric; + + template class T_BilinearForm; } diff -Nru ngsolve-6.2.2102/comp/CMakeLists.txt ngsolve-6.2.2103/comp/CMakeLists.txt --- ngsolve-6.2.2102/comp/CMakeLists.txt 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/CMakeLists.txt 2021-06-04 23:31:19.000000000 +0000 @@ -15,7 +15,10 @@ numberfespace.cpp irspace.cpp bddc.cpp h1amg.cpp hypre_precond.cpp hdivdivfespace.cpp hdivdivsurfacespace.cpp hcurlcurlfespace.cpp tpfes.cpp hcurldivfespace.cpp fesconvert.cpp python_comp.cpp python_comp_mesh.cpp ../fem/python_fem.cpp basenumproc.cpp pde.cpp pdeparser.cpp vtkoutput.cpp - periodic.cpp discontinuous.cpp hidden.cpp reorderedfespace.cpp hypre_ams_precond.cpp facetsurffespace.cpp compressedfespace.cpp + periodic.cpp discontinuous.cpp hidden.cpp reorderedfespace.cpp + hypre_ams_precond.cpp facetsurffespace.cpp + compressedfespace.cpp + globalinterfacespace.cpp ../multigrid/mgpre.cpp ../multigrid/prolongation.cpp ../multigrid/smoother.cpp contact.cpp localsolve.cpp interpolate.cpp ) @@ -38,7 +41,9 @@ postproc.hpp preconditioner.hpp vectorfacetfespace.hpp normalfacetfespace.hpp normalfacetsurfacefespace.hpp hypre_precond.hpp h1amg.hpp pde.hpp numproc.hpp irspace.hpp vtkoutput.hpp pmltrafo.hpp periodic.hpp - discontinuous.hpp hidden.hpp reorderedfespace.hpp hypre_ams_precond.hpp facetsurffespace.hpp compressedfespace.hpp + discontinuous.hpp hidden.hpp reorderedfespace.hpp + hypre_ams_precond.hpp facetsurffespace.hpp + compressedfespace.hpp python_comp.hpp fesconvert.hpp contact.hpp interpolate.hpp DESTINATION ${NGSOLVE_INSTALL_DIR_INCLUDE} COMPONENT ngsolve_devel diff -Nru ngsolve-6.2.2102/comp/compressedfespace.cpp ngsolve-6.2.2103/comp/compressedfespace.cpp --- ngsolve-6.2.2102/comp/compressedfespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/compressedfespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -23,6 +23,9 @@ // we need it to update the space after refinement. // space should set dofs only in first update on level + // for dirichlet_vertex/edge/face. should we get the freedofs from base space instead? + FESpace::Update(); + const int ndofall = space->GetNDof(); all2comp.SetSize(ndofall); comp2all.SetSize(ndofall); @@ -68,6 +71,11 @@ return space->GetFE(ei,lh); } + FlatArray CompressedFESpace::GetDualShapeNodes (VorB vb) const + { + return space->GetDualShapeNodes(vb); + } + void CompressedFESpace::GetDofNrs (ElementId ei, Array & dnums) const { space->GetDofNrs(ei,dnums); diff -Nru ngsolve-6.2.2102/comp/compressedfespace.hpp ngsolve-6.2.2103/comp/compressedfespace.hpp --- ngsolve-6.2.2102/comp/compressedfespace.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/compressedfespace.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -41,6 +41,8 @@ virtual FiniteElement & GetFE (ElementId ei, Allocator & lh) const override; + FlatArray GetDualShapeNodes (VorB vb) const override; + virtual void GetDofNrs (ElementId ei, Array & dnums) const override; virtual void GetDofNrs (NodeId ni, Array & dnums) const override; diff -Nru ngsolve-6.2.2102/comp/contact.cpp ngsolve-6.2.2103/comp/contact.cpp --- ngsolve-6.2.2102/comp/contact.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/contact.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -51,15 +51,18 @@ d0 = L2Norm2(dist); } - Vec CalcMinimumOnSegment( Vec x1, Vec x2 ) + bool CalcMinimumOnSegment( Vec x1, Vec x2, Vec & res ) { auto v = x2-x1; Vec va = a*v; - double lam = InnerProduct(v,b) - InnerProduct(va,x2+x0); + double lam = - InnerProduct(v,b) - InnerProduct(va,x1-x0); lam /= InnerProduct(va,v); - lam = min(lam,1.0); - lam = max(lam,0.0); - return lam*x1 + (1-lam)*x2; + + if(lam<0 || lam>1.0) + return false; + + res = lam*x2 + (1-lam)*x1; + return true; } Vec CalcMinimum( ) @@ -116,12 +119,19 @@ if constexpr (DIMS==2) { // TODO: Handle quad elements + auto getDist = [&] ( auto l ) + { + Vec p; + trafo.CalcPoint( {l}, p ); + return L2Norm2( p-pmaster ); + }; // check corner points ArrayMem, 5> points{ {0,0}, {0,1}, {1,0} }; for (Vec lam : points) { - auto d = t2(lam); + // auto d = t2(lam); + auto d = getDist(lam); if(is_front && d < min_dist) { min_dist = d; @@ -129,38 +139,38 @@ } } - ArrayMem, 5> lam; - ArrayMem dist; + auto checkLam = [&]( auto lam ) + { + if(!is_front) + return; + auto dist = getDist(lam); + + if(dist < min_dist) + { + min_dist = dist; + min_lam = lam; + } + }; auto l = t2.CalcMinimum(); + if(l[0]>0 && l[1]>0 && l[0]<1 && l[1]<1 && l[0]+l[1]<1) - { - lam.Append(l); - dist.Append(t2(lam.Last())); - } + checkLam(l); -// lam.Append(t2.CalcMinimumOnSegment( {0,0}, {1,0} )); -// dist.Append(t2(lam.Last())); -// -// lam.Append(t2.CalcMinimumOnSegment( {1,0}, {0,1} )); -// dist.Append(t2(lam.Last())); -// -// lam.Append(t2.CalcMinimumOnSegment( {0,1}, {0,0} )); -// dist.Append(t2(lam.Last())); + if(t2.CalcMinimumOnSegment( {0,0}, {1,0}, l )) + checkLam(l); + + if(t2.CalcMinimumOnSegment( {1,0}, {0,1}, l )) + checkLam(l); + + if(t2.CalcMinimumOnSegment( {0,1}, {0,0}, l )) + checkLam(l); - for(auto i : Range(lam.Size())) - { - if(is_front && dist[i] h) - return min_dist; + if(min_dist > h*h) + return sqrt(min_dist); ip = min_lam; trafo.CalcPoint( ip, p ); diff -Nru ngsolve-6.2.2102/comp/discontinuous.hpp ngsolve-6.2.2103/comp/discontinuous.hpp --- ngsolve-6.2.2102/comp/discontinuous.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/discontinuous.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -31,6 +31,12 @@ FESpace::FinalizeUpdate(); } + virtual FlatArray GetDualShapeNodes (VorB vb) const override + { + return space->GetDualShapeNodes(vb); + } + + virtual string GetClassName() const override { return "Discontinuous" + space->GetClassName(); } shared_ptr GetBaseSpace() const { return space; } diff -Nru ngsolve-6.2.2102/comp/facetfespace.cpp ngsolve-6.2.2103/comp/facetfespace.cpp --- ngsolve-6.2.2102/comp/facetfespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/facetfespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -98,12 +98,55 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdFacet"); return ZeroCF(Array()); } - }; + }; + + + template + class DiffOpGradFacet : public DiffOp > + { + public: + enum { DIM = 1 }; + enum { DIM_SPACE = D }; + enum { DIM_ELEMENT = D }; + enum { DIM_DMAT = D }; + enum { DIFFORDER = 1 }; + + static string Name() { return "grad"; } + + template + static void GenerateMatrix (const FEL & bfel, const MIP & mip, + MAT & mat, LocalHeap & lh) + { + int facetnr = mip.IP().FacetNr(); + if (facetnr >= 0) + { + HeapReset hr(lh); + + const FacetVolumeFiniteElement & fel_facet = static_cast&> (bfel); + auto r = fel_facet.GetFacetDofs(facetnr); + + FlatMatrix<> dshaperef(r.Size(), DIM_ELEMENT, lh); + mat = 0.0; + /* + fel_facet.Facet(facetnr).CalcDShape(mip.IP(), + mat.Row(0).Range(fel_facet.GetFacetDofs(facetnr))); + */ + fel_facet.Facet(facetnr).CalcDShape(mip.IP(), dshaperef); + mat.Cols(r) = Trans(mip.GetJacobianInverse()) * Trans(dshaperef); + } + else + { + throw Exception("cannot evaluate facet-fe inside element"); + } + } + }; @@ -186,12 +229,15 @@ evaluator[VOL] = make_shared>>(); evaluator[BND] = make_shared>>(); integrator[BND] = make_shared> (one); + flux_evaluator[VOL] = make_shared>>(); + } else { evaluator[VOL] = make_shared>>(); evaluator[BND] = make_shared>>(); integrator[BND] = make_shared> (one); + flux_evaluator[VOL] = make_shared>>(); } if (dimension > 1) @@ -651,6 +697,7 @@ */ case BND: { + /* DGFiniteElement<1> * fe1d = 0; DGFiniteElement<2> * fe2d = 0; @@ -663,7 +710,7 @@ throw Exception (string("FacetFESpace::GetSFE: unsupported element ")+ ElementTopology::GetElementName(ma->GetElType(ei))); } - + */ // ArrayMem ednums; auto vnums = ma->GetElVertices(ei); @@ -671,6 +718,7 @@ { case ET_SEGM: { + auto fe1d = new (lh) L2HighOrderFE (); fe1d -> SetVertexNumbers (vnums); auto ednums = ma->GetElEdges(ei); int p = order_facet[ednums[0]][0]; @@ -678,23 +726,31 @@ fe1d -> SetOrder (p); fe1d -> ComputeNDof(); return *fe1d; - break; } case ET_TRIG: + { + auto fe2d = new (lh) L2HighOrderFE (); + fe2d -> SetVertexNumbers (vnums); + int p = order_facet[ma->GetSElFace(ei.Nr())][0]; + if (highest_order_dc) p--; + fe2d -> SetOrder (p); // SZ not yet anisotropic order for facet fe !!! + fe2d -> ComputeNDof(); + return *fe2d; + } case ET_QUAD: { + auto fe2d = new (lh) L2HighOrderFE (); fe2d -> SetVertexNumbers (vnums); int p = order_facet[ma->GetSElFace(ei.Nr())][0]; if (highest_order_dc) p--; fe2d -> SetOrder (p); // SZ not yet anisotropic order for facet fe !!! fe2d -> ComputeNDof(); return *fe2d; - break; } default: - break; + throw Exception("Undefined BND GetFE of FacetFESpace"); } - return *fe2d; + // return *fe2d; } case BBND: throw Exception("No BBND GetFE implemented for FacetFESpace"); diff -Nru ngsolve-6.2.2102/comp/facetsurffespace.cpp ngsolve-6.2.2103/comp/facetsurffespace.cpp --- ngsolve-6.2.2102/comp/facetsurffespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/facetsurffespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -55,8 +55,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdFacet_"); return ZeroCF(Array()); } @@ -143,8 +145,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdFacetSurface"); return ZeroCF(Array()); } @@ -175,8 +179,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdFacetSurface"); return ZeroCF(Array()); } @@ -489,20 +495,20 @@ } case BBND: { - DGFiniteElement<1> * fe1d = 0; - switch (ma->GetElType(ei)) { - case ET_SEGM: fe1d = new (lh) L2HighOrderFE (); break; + case ET_SEGM: + { + auto fe1d = new (lh) L2HighOrderFE (); + fe1d -> SetVertexNumbers (vnums); + fe1d -> SetOrder (order); + fe1d -> ComputeNDof(); + return *fe1d; + } default: throw Exception (string("FacetSurfaceFESpace::GetFE: unsupported element ")+ ElementTopology::GetElementName(ma->GetElType(ei))); } - - fe1d -> SetVertexNumbers (vnums); - fe1d -> SetOrder (order); - fe1d -> ComputeNDof(); - return *fe1d; break; } case BBBND: diff -Nru ngsolve-6.2.2102/comp/fesconvert.cpp ngsolve-6.2.2103/comp/fesconvert.cpp --- ngsolve-6.2.2102/comp/fesconvert.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/fesconvert.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -124,9 +124,9 @@ ElementId eid(vb, i); Ngs_Element el = ma->GetElement(eid); if ( (!space_a->DefinedOn(vb, el.GetIndex())) || (!space_b->DefinedOn(vb, el.GetIndex())) ) - { return; } + { continue; } if ( reg && !reg->Mask().Test(el.GetIndex()) ) - { return; } + { continue; } space_a->GetDofNrs(eid, dnums_a, ANY_DOF); // get rid of UNUSED DOFs maxdsa = max2(maxdsa, int(dnums_a.Size())); for (auto da : dnums_a) @@ -377,17 +377,23 @@ /** actual class nrs **/ Array classnr(ma->GetNE(vb)); ma->IterateElements - (vb, lh, [&] (auto el, LocalHeap & llh) { - classnr[el.Nr()] = - SwitchET - (el.GetType(), - [&] (auto et) { return et_firsti[int(et)] + ET_trait::GetClassNr(el.Vertices()); }); + (vb, lh, [&] (auto el, LocalHeap & llh) + { + if ( (space_a->DefinedOn(vb, el.GetIndex())) && (space_b->DefinedOn(vb, el.GetIndex())) ) + { + classnr[el.Nr()] = + SwitchET + (el.GetType(), + [&] (auto et) { return et_firsti[int(et)] + ET_trait::GetClassNr(el.Vertices()); }); + } + else + {classnr[el.Nr()] = -1;} }); TableCreator creator; for ( ; !creator.Done(); creator++) for (auto i : Range(classnr)) - { creator.Add (classnr[i], i); } + { if (classnr[i] != -1){creator.Add (classnr[i], i);} } //{ creator.Add (classnr[i], i); } Table table = creator.MoveTable(); /** assemble element matrix for every equivalence class **/ diff -Nru ngsolve-6.2.2102/comp/fespace.cpp ngsolve-6.2.2103/comp/fespace.cpp --- ngsolve-6.2.2102/comp/fespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/fespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -159,7 +159,8 @@ if (flags.NumListFlagDefined("definedon") || flags.NumFlagDefined("definedon") || - flags.StringListFlagDefined("definedon")) + flags.StringListFlagDefined("definedon") || + flags.AnyFlagDefined("definedon")) { definedon[VOL].SetSize (ma->GetNDomains()); definedon[VOL] = false; @@ -200,6 +201,37 @@ // fespace only defined on boundaries matching definedon-domains definedon[BND].SetSize (ma->GetNBoundaries()); definedon[BND] = false; + + if(flags.AnyFlagDefined("definedon")) + { + std::any anydefon = flags.GetAnyFlag("definedon"); + if(anydefon.type() == typeid(std::map)) + { + auto map = std::any_cast>(anydefon); + for(const auto& [vb, reg] : map) + { + if(vb == BBND || vb == BBBND) + definedon[vb].SetSize(ma->GetNRegions(vb)); + for(auto i : Range(definedon[vb])) + definedon[vb][i] = reg.Mask().Test(i); + } + // if vol is not in map then definedon vol = empty + if(map.find(VOL) == map.end()) + definedon[VOL] = false; + } + else if(anydefon.type() == typeid(Region)) + { + auto reg = std::any_cast(anydefon); + definedon[reg.VB()].SetSize(reg.Mask().Size()); + for(auto i : Range(definedon[reg.VB()])) + definedon[reg.VB()][i] = reg.Mask().Test(i); + for(auto vb = VOL; vb < reg.VB(); vb++) + definedon[vb] = false; + } + else + throw Exception("definedon with wrong argument type!"); + } + for (int sel = 0; sel < ma->GetNSE(); sel++) { ElementId sei(BND, sel); @@ -1908,17 +1940,28 @@ shared_ptr FESpace :: ConvertL2Operator (shared_ptr l2space) const { - LocalHeap lh(10000000); - Array classnr(ma->GetNE()); + LocalHeap lh(100000000); + + Array classnr(ma->GetNE()); + + FlatArray vertex_map; + if (const PeriodicFESpace * periodic = dynamic_cast (this)) + vertex_map.Assign (periodic->GetVertexMap()); + ma->IterateElements (VOL, lh, [&] (auto el, LocalHeap & llh) { classnr[el.Nr()] = - SwitchET + SwitchET (el.GetType(), - [el] (auto et) { return ET_trait::GetClassNr(el.Vertices()); }); + [el, vertex_map] (auto et) { + if (vertex_map.Size()) + return ET_trait::GetClassNr(vertex_map[el.Vertices()]); + else + return ET_trait::GetClassNr(el.Vertices()); + }); }); - + TableCreator creator; for ( ; !creator.Done(); creator++) for (auto i : Range(classnr)) @@ -1941,12 +1984,8 @@ ElementId ei(VOL,elclass_inds[0]); auto & fel = GetFE (ei, lh); auto & fel_l2 = l2space->GetFE (ei, lh); - // auto & trafo = GetMeshAccess()->GetTrafo(ei, lh); - FE_ElementTransformation<2,2> trafo2d(ET_TRIG); - FE_ElementTransformation<3,3> trafo3d(ET_TET); - ElementTransformation & trafo = (fel.Dim() == 2) ? - (ElementTransformation&)trafo2d : - (ElementTransformation&)trafo3d; + + auto & trafo = GetFEElementTransformation(fel.ElementType()); MixedFiniteElement fel_mixed(fel, fel_l2); auto evaluator = GetEvaluator(VOL); auto l2evaluator = l2space->GetEvaluator(VOL); @@ -1967,6 +2006,7 @@ Matrix<> mass_l2(fel_l2.GetNDof(), fel_l2.GetNDof()); Matrix<> mass_mixed(fel_l2.GetNDof(), fel.GetNDof()); + bfi_mass_l2->CalcElementMatrix (fel_l2, trafo, mass_l2, lh); bfi_mass_mixed->CalcElementMatrix (fel_mixed, trafo, mass_mixed, lh); @@ -2113,7 +2153,7 @@ paralleldofs -> GetNDofGlobal() : GetNDof(); } - BitArray FESpace :: GetDofs (Region reg) const + BitArray FESpace :: GetDofs (const Region & reg) const { BitArray ba(GetNDof()); ba.Clear(); @@ -2322,6 +2362,31 @@ FESpace::Update(); if (low_order_space) low_order_space -> Update(); + bool first_update = GetTimeStamp() < ma->GetTimeStamp(); + if (first_update) timestamp = NGS_Object::GetNextTimeStamp(); + + if (first_update) + { + used_vertex.SetSize(ma->GetNV()); + used_vertex = false; + used_edge.SetSize(ma->GetNEdges()); + used_edge = false; + + for (auto vb : { VOL, BND }) + ParallelFor + (ma->GetNE(vb), [&] (size_t nr) + { + ElementId ei(vb, nr); + Ngs_Element el = (*ma)[ei]; + + if (!DefinedOn (el)) return; + + used_vertex[el.Vertices()] = true; + if (order > 1) + used_edge[el.Edges()] = true; + }); + } + // if (ma->GetNLevels() > ndlevel.Size()) { size_t ndof = ma->GetNV(); @@ -2351,6 +2416,25 @@ for (DofId d : el.GetDofs()) if (IsRegularDof(d)) dirichlet_dofs.SetBit (d); } + + UpdateCouplingDofArray(); + } + + void NodalFESpace :: UpdateCouplingDofArray() + { + ctofdof.SetSize(GetNDof()); + ParallelFor + (ma->GetNV(), [&] (size_t i) + { + ctofdof[i] = used_vertex[i] ? WIREBASKET_DOF : UNUSED_DOF; + }); + + if(order > 1 && GetNDof() > ma->GetNV()) + ParallelFor + (ma->GetNEdges(), [&] (size_t i) + { + ctofdof[ma->GetNV() + i] = used_edge[i] ? INTERFACE_DOF : UNUSED_DOF; + }); } void NodalFESpace :: DoArchive (Archive & archive) @@ -3023,7 +3107,8 @@ cummulative_nd[0] = 0; for (int i = 0; i < spaces.Size(); i++) { - spaces[i] -> Update(); + if(do_subspace_update) + spaces[i] -> Update(); cummulative_nd[i+1] = cummulative_nd[i] + spaces[i]->GetNDof(); } @@ -3111,7 +3196,8 @@ void CompoundFESpace :: FinalizeUpdate() { for (int i = 0; i < spaces.Size(); i++) - spaces[i] -> FinalizeUpdate(); + if(do_subspace_update) + spaces[i] -> FinalizeUpdate(); FESpace::FinalizeUpdate(); @@ -3562,8 +3648,12 @@ : CompoundFESpace (space->GetMeshAccess(), flags), vdim(avdim) { symmetric = flags.GetDefineFlag("symmetric"); + deviatoric = flags.GetDefineFlag("deviatoric"); + + if (deviatoric && !symmetric) throw Exception ("non-symmetric and deviatoric not supported"); int dim = symmetric ? vdim*(vdim+1)/2 : sqr(vdim); + if (deviatoric) dim--; for (int i = 0; i < dim; i++) AddSpace (space); @@ -3572,7 +3662,12 @@ if (auto eval = spaces[0] -> GetEvaluator(vb)) { if (symmetric) - evaluator[vb] = make_shared (eval, vdim); + { + if (deviatoric) + evaluator[vb] = make_shared (eval, vdim); + else + evaluator[vb] = make_shared (eval, vdim); + } else evaluator[vb] = make_shared (eval, vdim); } @@ -3586,15 +3681,19 @@ additional_evaluators.Set (additional.GetName(i), make_shared(additional[i], dim)); */ + /* if (symmetric) - type = "SymMatrix"+(*this)[0]->type; + type = "Sym"+Matrix"+(*this)[0]->type; else type = "Matrix"+(*this)[0]->type; + */ + type = string((symmetric) ? "Sym" : "") + (deviatoric ? "Dev" : "") + "Matrix" + (*this)[0]->type; } string MatrixFESpace :: GetClassName () const { - return ( symmetric ? "SymMatrix" : "Matrix" ) + (*this)[0]->GetClassName(); + // return ( symmetric ? "SymMatrix" : "Matrix" ) + (*this)[0]->GetClassName(); + return string(symmetric ? "Sym" : "") + (deviatoric ? "Dev" : "") + "Matrix" + (*this)[0]->GetClassName(); } @@ -3605,7 +3704,7 @@ else { const FiniteElement & fe0 = spaces[0]->GetFE(ei, alloc); - return *new (alloc) SymMatrixFiniteElement(fe0, vdim); + return *new (alloc) SymMatrixFiniteElement(fe0, vdim, deviatoric); } } diff -Nru ngsolve-6.2.2102/comp/fespace.hpp ngsolve-6.2.2103/comp/fespace.hpp --- ngsolve-6.2.2102/comp/fespace.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/fespace.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -454,7 +454,7 @@ virtual void GetDofNrs (ElementId ei, Array & dnums) const = 0; virtual void GetDofNrs (NodeId ni, Array & dnums) const; - BitArray GetDofs (Region reg) const; + BitArray GetDofs (const Region & reg) const; Table CreateDofTable (VorB vorb) const; /// get coupling types of dofs @@ -512,6 +512,17 @@ return definedon[el.VB()][el.GetIndex()]; } + xbool DefinedOnX (Ngs_Element el) const + { + // a temporary workaround, + // clean solution will be to set definedon[BND] correctly + if (el.VB() <= BND) return DefinedOn(el); + + if (!definedon[el.VB()].Size()) return maybe; + return definedon[el.VB()][el.GetIndex()]; + } + + virtual void SetDefinedOn (VorB vb, const BitArray& defon); /// //[[deprecated("Use SetDefinedOn(VorB, const Bitarray&)")]] @@ -983,6 +994,8 @@ /// // Array ndlevel; bool hb_defined; + Array used_vertex; + Array used_edge; public: @@ -999,6 +1012,7 @@ /// void Update () override; + void UpdateCouplingDofArray() override; virtual void DoArchive (Archive & archive) override; @@ -1154,6 +1168,7 @@ /// dofs on each multigrid level /// Array ndlevel; bool all_the_same; + bool do_subspace_update = true; public: /// generates a compound space. /// components will be added later @@ -1248,7 +1263,10 @@ SliceVector vec, TRANSFORM_TYPE tt) const override; /// number of component spaces - inline int GetNSpaces () const { return spaces.Size(); } + inline int GetNSpaces () const { return spaces.Size(); } + + void SetDoSubspaceUpdate(bool _do_subspace_update) + { do_subspace_update = _do_subspace_update; } }; @@ -1270,6 +1288,7 @@ class NGS_DLL_HEADER MatrixFESpace : public CompoundFESpace { bool symmetric; + bool deviatoric; int vdim; public: MatrixFESpace (shared_ptr space, int avdim, const Flags & flags, diff -Nru ngsolve-6.2.2102/comp/globalinterfacespace.cpp ngsolve-6.2.2103/comp/globalinterfacespace.cpp --- ngsolve-6.2.2102/comp/globalinterfacespace.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/comp/globalinterfacespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -0,0 +1,477 @@ +#include +#include "globalinterfacespace.hpp" + +namespace ngcomp +{ + template + void GlobalInterfaceSpace::VolDiffOp::CalcMatrix + (const FiniteElement & bfel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const + { + auto & ip = mip.IP(); + auto & fel = dynamic_cast (bfel); + mat = 0; + + int fnr = ip.FacetNr(); + + if (fnr != -1 && fel.bndels[fnr]) + { + dynamic_cast (*fel.bndels[fnr]).CalcShape(mip, mat.Row(0)); + return; + } + if(fnr == -1) + { + fel.CalcShape(mip, mat.Row(0)); + } + } + + template + void GlobalInterfaceSpace::InterfaceDiffOp::CalcMatrix + (const FiniteElement & fel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const + { + if (fel.GetNDof() > 0) + dynamic_cast (fel).CalcShape(mip, mat.Row(0)); + } + + GlobalInterfaceSpace::GlobalInterfaceSpace(shared_ptr ama, + const Flags& flags) + : FESpace(ama, flags) + { + order = int(flags.GetNumFlag("order", 3)); + periodic[0] = periodic[1] = false; + if(flags.GetDefineFlag("periodic")) + periodic[0] = periodic[1] = true; + if(flags.GetDefineFlag("periodicu")) + periodic[0] = true; + if(flags.GetDefineFlag("periodicv")) + periodic[1] = true; + try + { + mapping = std::any_cast>(flags.GetAnyFlag("mapping")); + } + catch(std::bad_any_cast ex) + { + throw Exception("No mapping or wrong mapping given!\nGlobalInterfacespace needs kwarg: mapping=CoefficientFunction"); + } + } + + class GlobalInterfaceSpace1D : public GlobalInterfaceSpace + { + Array nitsche_facet; + + class InterfaceFE : public FiniteElement + { + const GlobalInterfaceSpace1D * fes; + public: + InterfaceFE (const GlobalInterfaceSpace1D * afes) + : FiniteElement(afes->GetNDof(), afes->order), fes(afes) { ; } + + virtual ELEMENT_TYPE ElementType() const override { return ET_SEGM; } + + virtual void CalcShape (const BaseMappedIntegrationPoint & mip, + SliceVector shapes) const + { + int order = fes->order; + double phi = fes->mapping -> Evaluate(mip); + + if(fes->periodic[0]) + { + shapes(0) = 1; + for (int i = 1; i <= order; i++) + { + shapes(2*i-1) = cos(i*phi); + shapes(2*i ) = sin(i*phi); + } + } + else + { + LegendrePolynomial (order, -1 + 2 * phi, shapes); + } + } + }; + + class VolFE : public FiniteElement + { + const GlobalInterfaceSpace1D * fes; + public: + VolFE (const GlobalInterfaceSpace1D * afes, int order) + : FiniteElement(afes->GetNDof(), order), fes(afes) { ; } + using INTERFACEFE = InterfaceFE; + InterfaceFE *bndels[3] = { nullptr, nullptr, nullptr }; + + void ComputeNDof() + { + if(order > 0) + { + if(fes->periodic[0]) + ndof = 2*order+1; + else + ndof = order+1; + } + else + ndof = 0; + for (int i = 0; i < 3; i++) + if (bndels[i]) + { + ndof = bndels[i] -> GetNDof(); + order = bndels[i]->Order(); + } + } + + void CalcShape(const BaseMappedIntegrationPoint& mip, + SliceVector shapes) const + { + int order = fes->order; + double phi = fes->mapping->Evaluate(mip); + if(fes->periodic[0]) + { + shapes(0) = 1.; + for (int i = 1; i <= order; i++) + { + shapes(2*i-1) = cos(i*phi); + shapes(2*i ) = sin(i*phi); + } + } + else + { + LegendrePolynomial (order, -1 + 2 * phi, shapes); + } + } + + virtual ELEMENT_TYPE ElementType() const override { return ET_TRIG; } + }; + + public: + GlobalInterfaceSpace1D (shared_ptr ama, const Flags & flags) + : GlobalInterfaceSpace(ama, flags) + { + if(periodic[0]) + SetNDof(2*order+1); + else + SetNDof(order+1); + + evaluator[VOL] = make_shared>(); + evaluator[BND] = make_shared>(); + } + + void Update() override + { + GlobalInterfaceSpace::Update(); + + nitsche_facet.SetSize(ma->GetNNodes(NT_FACET)); + nitsche_facet = false; + + if(definedon[BND].Size() == 0) + nitsche_facet = true; + else + { + for (auto el : ma->Elements(BND)) + if(definedon[BND][el.GetIndex()]) + nitsche_facet[el.Facets()] = true; + } + } + + void GetDofNrs (ElementId ei, Array & dofs) const override + { + dofs.SetSize0(); + switch (ei.VB()) + { + case VOL: + { + auto ngel = ma->GetElement(ei); + if(definedon[VOL].Size() == 0 || definedon[VOL][ngel.GetIndex()]) + { + dofs += IntRange(GetNDof()); + } + else + { + for (auto f : ngel.Facets()) + if (nitsche_facet[f]) + { + dofs += IntRange(GetNDof()); + break; + } + } + break; + } + + case BND: + { + //if (ma->GetElement(ei).GetIndex() == bc) + if (nitsche_facet[ma->GetElement(ei).Facets()[0]]) + dofs += IntRange(GetNDof()); + break; + } + default: + ; + } + } + + FiniteElement & GetFE (ElementId ei, Allocator & alloc) const override + { + switch (ei.VB()) + { + case VOL: + { + auto ngel = ma->GetElement(ei); + auto & fe = * new (alloc) VolFE(this, DefinedOn(ei) ? order : 0); + for (size_t i = 0; i < 3; i++) + { + auto f = ngel.Facets()[i]; + if (nitsche_facet[f]) + fe.bndels[i] = new (alloc) InterfaceFE(this); + } + fe.ComputeNDof(); + return fe; + } + case BND: + { + // if (ma->GetElement(ei).GetIndex() == bc) + if (nitsche_facet[ma->GetElement(ei).Facets()[0]]) + { + return * new (alloc) InterfaceFE(this); + } + return * new (alloc) DummyFE(); + } + default: + throw Exception ("Nitsche::GetFE(): no other elements"); + } + + } + + static DocInfo GetDocu() + { + auto docu = FESpace::GetDocu(); + docu.Arg("mapping") = "Mapping for global interface space."; + docu.Arg("periodic") = "Periodic global interface space (in 2d in x and y direction)."; + docu.Arg("periodicu") = "Periodic u-dir (local coordinate system) global interface space."; + docu.Arg("periodicv") = "Periodic v-dir (local coordinate system) global interface space."; + return docu; + } + }; + + /* + + // old code for cylinder + + // scalar cylinder + class NitscheSpaceCylinder : public FESpace + { + int order; + int bc; + Vec<3> pa, pb; + double r; + Array nitsche_face; + + class NitscheFE : public FiniteElement + { + const NitscheSpaceCylinder * fes; + public: + NitscheFE (const NitscheSpaceCylinder * afes) + : FiniteElement(afes->GetNDof(), afes->order), fes(afes) { ; } + + virtual ELEMENT_TYPE ElementType() const { return ET_TRIG; } + + virtual void CalcShape (const BaseMappedIntegrationPoint & mip, + SliceVector shapes) const + { + int order = fes->order; + double x = mip.GetPoint()(0); + double y = mip.GetPoint()(1); + double z = mip.GetPoint()(2); + double zr = -1 + 2*z; + double phi = atan2 (x,y); + Vector<> shapez(order+1), shapephi(2*order+1); + LegendrePolynomial (order, zr, shapez); + shapephi(0) = 1; + for (int i = 1; i <= order; i++) + { + shapephi(2*i-1) = cos(i*phi); + shapephi(2*i ) = sin(i*phi); + } + + for (int i = 0, ii = 0; i < shapez.Size(); i++) + for (int j = 0; j < shapephi.Size(); j++, ii++) + shapes(ii) = shapez(i)*shapephi(j); + } + }; + + class NitscheDiffOp : public DifferentialOperator + { + public: + NitscheDiffOp () + : DifferentialOperator(1, 1, BND, 0) { ; } + + virtual void + CalcMatrix (const FiniteElement & fel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const + { + if (fel.GetNDof() > 0) + dynamic_cast (fel).CalcShape(mip, mat.Row(0)); + } + }; + + + class NitscheVolFE : public FiniteElement + { + public: + NitscheFE *bndels[4] = { nullptr, nullptr, nullptr, nullptr }; + + void ComputeNDof() + { + ndof = 0; + order = 0; + for (int i = 0; i < 4; i++) + if (bndels[i]) + { + ndof += bndels[i] -> GetNDof(); + order = max2 (order, bndels[i]->Order()); + } + } + + virtual ELEMENT_TYPE ElementType() const { return ET_TET; } + }; + + + class NitscheVolDiffOp : public DifferentialOperator + { + public: + NitscheVolDiffOp () + : DifferentialOperator(1, 1, BND, 0) { ; } + + virtual void + CalcMatrix (const FiniteElement & bfel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const + { + auto & ip = mip.IP(); + + auto & fel = dynamic_cast (bfel); + mat = 0; + + int fnr = ip.FacetNr(); + if (fnr != -1 && fel.bndels[fnr]) + dynamic_cast (*fel.bndels[fnr]).CalcShape(mip, mat.Row(0)); + } + }; + + + + public: + NitscheSpaceCylinder (shared_ptr ama, const Flags & flags) + : FESpace(ama, flags) + { + cout << "nitsche flags = " << endl << flags << endl; + order = int(flags.GetNumFlag("order", 3)); + bc = int(flags.GetNumFlag("bc", 1)) - 1; + + SetNDof( (order+1) * (2*order+1) ); + + evaluator[VOL] = make_shared(); + evaluator[BND] = make_shared(); + } + + + virtual void Update() + { + FESpace::Update(); + nitsche_face.SetSize(ma->GetNNodes(NT_FACE)); + nitsche_face = false; + for (auto el : ma->Elements(BND)) + if (el.GetIndex() == bc) + nitsche_face[el.Faces()] = true; + } + + virtual void GetDofNrs (ElementId ei, Array & dofs) const + { + dofs.SetSize0(); + switch (ei.VB()) + { + case VOL: + { + auto ngel = ma->GetElement(ei); + for (size_t i = 0; i < 4; i++) + { + auto f = ngel.Faces()[i]; + if (nitsche_face[f]) + dofs += IntRange(0, GetNDof()); + } + break; + } + + case BND: + { + if (ma->GetElement(ei).GetIndex() == bc) + dofs += IntRange(0, GetNDof()); + break; + } + default: + ; + } + } + + virtual FiniteElement & GetFE (ElementId ei, Allocator & alloc) const + { + switch (ei.VB()) + { + case VOL: + { + auto ngel = ma->GetElement(ei); + auto & fe = * new (alloc) NitscheVolFE(); + for (size_t i = 0; i < 4; i++) + { + auto f = ngel.Faces()[i]; + if (nitsche_face[f]) + fe.bndels[i] = new (alloc) NitscheFE(this); + } + fe.ComputeNDof(); + return fe; + } + case BND: + { + if (ma->GetElement(ei).GetIndex() == bc) + return * new (alloc) NitscheFE(this); + return * new (alloc) DummyFE(); + } + default: + throw Exception ("Nitsche::GetFE(): no other elements"); + } + + } + + + + }; + + static RegisterFESpace initifes ("NitscheSpaceCylinder"); + */ + + shared_ptr CreateGlobalInterfaceSpace + (shared_ptr ma, shared_ptr mapping, + optional definedon, bool periodic, bool periodicu, + bool periodicv, int order) + { + Flags flags; + flags.SetFlag("mapping", mapping); + if(periodic) + flags.SetFlag("periodic"); + if(periodicu) + flags.SetFlag("periodicu"); + if(periodicv) + flags.SetFlag("periodicv"); + if(definedon.has_value()) + flags.SetFlag("definedon", definedon.value()); + flags.SetFlag("order", order); + if(ma->GetDimension() == 2) + return make_shared(ma, flags); + throw Exception("this space is not yet implemented!"); + } +} // namespace ngcomp diff -Nru ngsolve-6.2.2102/comp/globalinterfacespace.hpp ngsolve-6.2.2103/comp/globalinterfacespace.hpp --- ngsolve-6.2.2102/comp/globalinterfacespace.hpp 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/comp/globalinterfacespace.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -0,0 +1,49 @@ +#ifndef NGSOLVE_GLOBALINTERFACESPACE_HPP +#define NGSOLVE_GLOBALINTERFACESPACE_HPP + +namespace ngcomp +{ + class GlobalInterfaceSpace : public FESpace + { + protected: + shared_ptr mapping; + int order; + bool periodic[2]; // periodic x/ periodic y + + template + class VolDiffOp : public DifferentialOperator + { + public: + VolDiffOp () + : DifferentialOperator(1, 1, VOL, 0) { ; } + + void CalcMatrix (const FiniteElement & bfel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const override; + }; + + template + class InterfaceDiffOp : public DifferentialOperator + { + public: + InterfaceDiffOp () + : DifferentialOperator(1, 1, BND, 0) { ; } + + void CalcMatrix (const FiniteElement & fel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const override; + }; + + public: + GlobalInterfaceSpace(shared_ptr ama, const Flags& flags); + }; + + shared_ptr CreateGlobalInterfaceSpace + (shared_ptr ma, shared_ptr mapping, + optional definedon, bool periodic, bool periodicu, + bool periodicv, int order); +} // namespace ngcomp + +#endif // NGSOLVE_GLOBALINTERFACESPACE_HPP diff -Nru ngsolve-6.2.2102/comp/gridfunction.cpp ngsolve-6.2.2103/comp/gridfunction.cpp --- ngsolve-6.2.2102/comp/gridfunction.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/gridfunction.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -237,6 +237,17 @@ Array cnti(fes->GetNDof()); cnti = 0; + auto tempvec = GetVector(mdcomp).CreateVector(); + + if (reg) + { + auto regdofs = make_shared (fes->GetDofs(*reg)); + Projector proj(regdofs, false); + tempvec = proj * GetVector(mdcomp); + } + else + tempvec = 0.0; + auto vb = reg ? reg->VB() : VOL; IterateElements (*fes, vb, clh, @@ -251,23 +262,32 @@ const ElementTransformation & eltrans = ma->GetTrafo (el, lh); FlatVector<> elvec(ndof, lh), elvec1(ndof, lh); + + // GetElementVector (mdcomp, el.GetDofs(), elvec1); + // cout << "elvec, before: " << endl << elvec1 << endl; + // fel.Interpolate (eltrans, cf, elvec.AsMatrix(ndof/dimcf, dimcf), lh); fel.Interpolate (eltrans, cf, elvec.AsMatrix(ndof, 1), lh); + // cout << "elvec, minmizer: " << endl << elvec << endl; fes->TransformVec (el, elvec, TRANSFORM_SOL_INVERSE); - GetElementVector (mdcomp, el.GetDofs(), elvec1); + // GetElementVector (mdcomp, el.GetDofs(), elvec1); + tempvec.GetIndirect (el.GetDofs(), elvec1); elvec1 += elvec; - SetElementVector (mdcomp, el.GetDofs(), elvec); - + // SetElementVector (mdcomp, el.GetDofs(), elvec1); + tempvec.SetIndirect (el.GetDofs(), elvec1); + for (auto d : el.GetDofs()) if (IsRegularDof(d)) cnti[d]++; }); #ifdef PARALLEL AllReduceDofData (cnti, MPI_SUM, fes->GetParallelDofs()); - GetVector(mdcomp).SetParallelStatus(DISTRIBUTED); - GetVector(mdcomp).Cumulate(); + // GetVector(mdcomp).SetParallelStatus(DISTRIBUTED); + // GetVector(mdcomp).Cumulate(); + (*tempvec).SetParallelStatus(DISTRIBUTED); + (*tempvec).Cumulate(); #endif ParallelForRange @@ -280,11 +300,15 @@ if (cnti[i]) { dnums[0] = i; - GetElementVector (mdcomp, dnums, fluxi); + // GetElementVector (mdcomp, dnums, fluxi); + tempvec.GetIndirect (dnums, fluxi); fluxi /= double (cnti[i]); - SetElementVector (mdcomp, dnums, fluxi); + tempvec.SetIndirect (dnums, fluxi); + // SetElementVector (mdcomp, dnums, fluxi); } }); + + GetVector(mdcomp) = tempvec; } @@ -1667,11 +1691,15 @@ shared_ptr GridFunctionCoefficientFunction :: Diff (const CoefficientFunction * var, shared_ptr dir) const { - if (var == shape.get()) + // if (var == shape.get()) + if (auto diffshape = dynamic_cast(var)) { + const CoefficientFunction * me = this; + bool Eulerian = diffshape->Eulerian_gridfunctions.Contains(me); + cout << "diff GF is " << (Eulerian ? "Eulrian" : "Lagrange") << endl; for (int i = 0; i < 4; i++) if (diffop[i]) - return diffop[i]->DiffShape (const_cast(this)->shared_from_this(), dir); + return diffop[i]->DiffShape (const_cast(this)->shared_from_this(), dir, Eulerian); throw Exception("don't have any diffop for shape-derivative"); } diff -Nru ngsolve-6.2.2102/comp/h1hofespace.cpp ngsolve-6.2.2103/comp/h1hofespace.cpp --- ngsolve-6.2.2102/comp/h1hofespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/h1hofespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -446,18 +446,21 @@ // for (FESpace::Element el : Elements (VOL)) - for (auto vb : { VOL, BND }) - ParallelFor - (ma->GetNE(vb), [&] (size_t nr) - { - ElementId ei(vb, nr); - Ngs_Element el = (*ma)[ei]; - - if (!DefinedOn (el)) return; + // for (auto vb : { VOL, BND, BBND }) + for (auto vb : Range(VOL, VorB(dim+1))) + ParallelFor + (ma->GetNE(vb), [&] (size_t nr) + { + ElementId ei(vb, nr); + Ngs_Element el = (*ma)[ei]; - used_vertex[el.Vertices()] = true; - if (dim >= 2) used_edge[el.Edges()] = true; - if (dim == 3) used_face[el.Faces()] = true; + // if (!DefinedOn (el)) return; + if (DefinedOnX (el).IsTrue()) + { + used_vertex[el.Vertices()] = true; + if (dim >= 2) used_edge[el.Edges()] = true; + if (dim == 3) used_face[el.Faces()] = true; + } }); /* @@ -641,7 +644,8 @@ if (low_order_space) low_order_embedding = make_shared (GetNDof(), - IntRange(low_order_space->GetNDof())); + IntRange(low_order_space->GetNDof()), + IsComplex()); // timer3.Stop(); } @@ -2331,8 +2335,8 @@ auto dir = flags.GetStringFlag(dirnames[i]); if(flags.StringFlagDefined("dirichlet")) dir += "|" + flags.GetStringFlag("dirichlet"); - cout << "dirichlet = " << dir << endl; - cout << "dirichlet flag = " << flags.GetStringFlag("dirichlet") << endl; + // cout << "dirichlet = " << dir << endl; + // cout << "dirichlet flag = " << flags.GetStringFlag("dirichlet") << endl; tmpflags.SetFlag ("dirichlet", dir); } if (flags.StringFlagDefined(dirnames[i]+"_bbnd")) diff -Nru ngsolve-6.2.2102/comp/hcurlcurlfespace.cpp ngsolve-6.2.2103/comp/hcurlcurlfespace.cpp --- ngsolve-6.2.2102/comp/hcurlcurlfespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hcurlcurlfespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -152,45 +152,22 @@ static auto & Cast (const FiniteElement & fel) { return static_cast&> (fel); } - template - static void GenerateMatrix (const FEL & bfel, - const MIP & mip, - MAT && mat, LocalHeap & lh) - { - - GenerateMatrix2 (bfel, mip, SliceIfPossible (mat), lh); - } - template - static void GenerateMatrix2 (const FEL & fel, const MIP & mip, - MAT && mat, LocalHeap & lh) - { - HeapReset hr(lh); - auto refmat = Cast(fel).GetShape(mip.IP(), lh); - Mat refmati, physmati; - for (size_t i = 0; i < Cast(fel).ndof; i++) - { - for (int j = 0; j < D; j++) - for (int k = 0; k < D; k++) - refmati(j,k) = refmat.Row(i)(j*D+k); - physmati = Trans(mip.GetJacobianInverse())*refmati*mip.GetJacobianInverse(); - for (int j = 0; j < D; j++) - for (int k = 0; k < D; k++) - mat.Col(i)(j*D+k) = physmati(j,k); - - // physmat = refmat.Row(i); - // mat.Col(i) = Trans(mip.GetJacobianInverse())*physmat*mip.GetJacobianInverse(); - } - } - - template - static void GenerateMatrix2 (const FEL & fel, - const MappedIntegrationPoint & mip, - SliceMatrix<> mat, LocalHeap & lh) + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const MIP & mip, + MAT & mat, LocalHeap & lh) { Cast(fel).CalcMappedShape (mip,Trans(mat)); } + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const MIP & mip, + MAT & mat, LocalHeap & lh) + { + throw Exception(string("DiffOpIdHCurlCurl not available for mat ")+typeid(mat).name()); + } static void GenerateMatrixSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & mir, @@ -300,6 +277,132 @@ } }; + + template + class DiffOpIncHCurlCurl: public DiffOp > + { + }; + + + template<> + class DiffOpIncHCurlCurl<2>: public DiffOp > + { + public: + enum { DIM = 1 }; + enum { DIM_SPACE = 2 }; + enum { DIM_ELEMENT = 2 }; + enum { DIM_DMAT = 1 }; + enum { DIFFORDER = 2 }; + + + static string Name() { return "inc"; } + + template + static void GenerateMatrix(const FEL & bfel,const SIP & sip, + SliceMatrix mat,LocalHeap & lh) + { + const HCurlCurlFiniteElement<2> & fel = static_cast&> (bfel); + + fel.CalcMappedIncShape (sip, Trans(mat)); + } + + + template + static void Apply (const AFEL & fel, const MIP & mip, + const TVX & x, TVY & y, + LocalHeap & lh) + { + const HCurlCurlFiniteElement<2> & bfel = static_cast&> (fel); + typedef typename TVX::TSCAL TSCAL; + if constexpr (std::is_same()) + bfel.EvaluateMappedIncShape (mip, x, y); + } + + + static void GenerateMatrixSIMDIR (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & mir, + BareSliceMatrix> mat) + { + const HCurlCurlFiniteElement<2> & fel = static_cast&> (bfel); + fel.CalcMappedIncShape (mir, mat); + } + + + + using DiffOp >::ApplySIMDIR; + static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & mir, + BareSliceVector x, BareSliceMatrix> y) + { + dynamic_cast&> (bfel).EvaluateIncShape (mir, x, y); + } + + using DiffOp >::AddTransSIMDIR; + static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & mir, + BareSliceMatrix> y, BareSliceVector x) + { + dynamic_cast&> (bfel).AddTransIncShape (mir, y, x); + } + }; + + template<> + class DiffOpIncHCurlCurl<3>: public DiffOp > + { + public: + enum { DIM = 1 }; + enum { DIM_SPACE = 3 }; + enum { DIM_ELEMENT = 3 }; + enum { DIM_DMAT = 9 }; + enum { DIFFORDER = 2 }; + + static Array GetDimensions() { return Array ({3,3}); } + + static string Name() { return "inc"; } + + template + static void GenerateMatrix(const FEL & bfel,const SIP & sip, + SliceMatrix mat,LocalHeap & lh) + { + const HCurlCurlFiniteElement<3> & fel = static_cast&> (bfel); + + fel.CalcMappedIncShape (sip, Trans(mat)); + } + + + template + static void Apply (const AFEL & fel, const MIP & mip, + const TVX & x, TVY & y, + LocalHeap & lh) + { + const HCurlCurlFiniteElement<3> & bfel = static_cast&> (fel); + typedef typename TVX::TSCAL TSCAL; + if constexpr (std::is_same()) + bfel.EvaluateMappedIncShape (mip, x, y); + } + + static void GenerateMatrixSIMDIR (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & mir, + BareSliceMatrix> mat) + { + const HCurlCurlFiniteElement<3> & fel = static_cast&> (bfel); + fel.CalcMappedIncShape (mir, mat); + } + + using DiffOp >::ApplySIMDIR; + static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & mir, + BareSliceVector x, BareSliceMatrix> y) + { + dynamic_cast&> (bfel).EvaluateIncShape (mir, x, y); + } + + using DiffOp >::AddTransSIMDIR; + static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & mir, + BareSliceMatrix> y, BareSliceVector x) + { + dynamic_cast&> (bfel).AddTransIncShape (mir, y, x); + } + + }; + /*class DiffOpCurlHCurlCurlBoundary : public DiffOp { @@ -394,8 +497,11 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdBoundaryHCurlCurl"); + int dim = dir->Dimension(); auto n = NormalVectorCF(dim); n -> SetDimensions( Array ( { dim, 1 } ) ); @@ -517,7 +623,7 @@ const ElementTransformation & eltrans = mir[i].GetTransformation(); // double eps = 1e-4; - for (int j = 0; j < D; j++) // d / dxj + for (size_t j = 0; j < D; j++) // d / dxj { HeapReset hr(lh); SIMD ipts[4]; @@ -585,6 +691,8 @@ }; /// Christoffel Symbol of first kind for HCurlCurl + // Gamma_ijk saved in offset order k*D*D+j*D+i + // Christoffel Symbol of first kind is symmetric w.r.t. first two indices: Gamma_ijk=Gamma_jik template > class DiffOpChristoffelHCurlCurl : public DiffOp > { @@ -594,7 +702,7 @@ enum { DIM_ELEMENT = D }; enum { DIM_DMAT = D*D*D }; enum { DIFFORDER = 1 }; - static Array GetDimensions() { return Array ( { D,D*D } ); }; + static Array GetDimensions() { return Array ( { D,D,D } ); }; static constexpr double eps() { return 1e-4; } /// template (static_cast(fel), mip, bmat, lh, eps()); - for (int i=0; i & bfel = dynamic_cast&> (fel); - + const HCurlCurlFiniteElement & bfel = static_cast&> (fel); typedef typename TVX::TSCAL TSCAL; - int nd_u = bfel.GetNDof(); - FlatMatrixFixWidth bmat(nd_u, lh); - CalcDShapeFE(static_cast(fel), mip, bmat, lh, eps()); - - Vec hdv = Trans(bmat) * x; + Vec hdv; + + if constexpr (std::is_same()) + { + ApplyDShapeFE(static_cast(fel), mip, x, hdv, lh, eps()); + // hdv = y; + } + else + { + int nd_u = bfel.GetNDof(); + FlatMatrixFixWidth bmat(nd_u, lh); + CalcDShapeFE(static_cast(fel), mip, bmat, lh, eps()); + hdv = Trans(bmat) * x; + } + - for (int i=0; i> mat) - { - size_t nd_u = static_cast(fel).GetNDof(); - auto & mir = static_cast&> (bmir); - - STACK_ARRAY(SIMD, mem1, mir.Size()*D*D*D*nd_u); - FlatMatrix> bmat(mir.Size()*nd_u*D*D*D, 1, &mem1[0]); - DiffOpGradientHCurlCurl::GenerateMatrixSIMDIR(bfel,bmr, bmat); - }*/ - - // using DiffOp>::ApplySIMDIR; - // static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, - // BareSliceVector x, BareSliceMatrix> y) + // static void GenerateMatrixSIMDIR (const FiniteElement & bfel, + // const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> mat) // { - // const HCurlCurlFiniteElement & bfel = dynamic_cast&> (fel); - // cout << "apply simd" << endl; - // //typedef typename TVX::TSCAL TSCAL; - // //int nd_u = bfel.GetNDof(); - // //FlatMatrixFixWidth bmat(nd_u, lh); - - // //CalcDShapeFE(static_cast(fel), mip, bmat, lh, eps()); - - // //BareSliceMatrix> hdv = Trans(bmat) * x; - // size_t size = (bmir.Size()+1)*SIMD::Size()*D*D*D; - // STACK_ARRAY(char, data, size); - // LocalHeap lh(data, size); - // FlatMatrix> hdv(D*D*D, bmir.Size(), lh); - // ApplySIMDDShapeFE(static_cast(fel), bmir, x, hdv, eps()); - - - // for (int i=0; i(bfel).GetNDof(); + // auto & mir = static_cast&> (bmir); + + // STACK_ARRAY(SIMD, mem1, mir.Size()*D*D*D*nd_u); + // FlatMatrix> bmat(nd_u*D*D*D, mir.Size(), &mem1[0]); + + // /* + // no known conversion from 'SIMD >' to 'const ngfem::BaseMappedIntegrationPoint' for 1st argument + // virtual void CalcMappedShape (const BaseMappedIntegrationPoint & bmip, + // */ + // CalcSIMDDShapeFE(static_cast(bfel), mir, bmat, eps()); + + // for (size_t i=0; i x, BareSliceMatrix> y) + { + throw ExceptionNOSIMD("ApplySIMDIR for Complex not implemented in Christoffel1 DiffOp"); + } + + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + size_t size = bmir.Size()*SIMD::Size()*D*D*D; + STACK_ARRAY(SIMD, mem, size); + FlatMatrix> hdv(D*D*D, bmir.Size(), mem); + + ApplySIMDDShapeFE(static_cast(fel), bmir, x, hdv, eps()); + + for (size_t i=0; i>::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, @@ -707,6 +830,8 @@ /// Christoffel Symbol of second kind for HCurlCurl + // Gamma_ij^k=g^kl Gamma_ijl saved in offset order k*D*D+j*D+i + // Christoffel Symbol of second kind is symmetric w.r.t. first two indices: Gamma_ij^k=Gamma_ji^k template > class DiffOpChristoffel2HCurlCurl : public DiffOp > { @@ -716,7 +841,7 @@ enum { DIM_ELEMENT = D }; enum { DIM_DMAT = D*D*D }; enum { DIFFORDER = 1 }; - static Array GetDimensions() { return Array ( { D,D*D } ); }; + static Array GetDimensions() { return Array ( { D,D,D } ); }; /// template @@ -744,42 +869,86 @@ { HeapReset hr(lh); const HCurlCurlFiniteElement & bfel = dynamic_cast&> (fel); - typedef typename TVX::TSCAL TSCAL; - int nd_u = bfel.GetNDof(); - FlatMatrixFixWidth bmat(nd_u, lh); - bfel.CalcMappedShape (mip, bmat); - - Vec hv = Trans(bmat) * x; - Mat defmat; - defmat.AsVector() = hv; - Mat invmat = Inv(defmat); - + + Mat G; + if constexpr (std::is_same()) + bfel.EvaluateMappedShape (mip, x, G); + else + { + int nd_u = bfel.GetNDof(); + FlatMatrixFixWidth bmat(nd_u, lh); + bfel.CalcMappedShape (mip, bmat); + Vec hv = Trans(bmat) * x; + G.AsVector() = hv; + } + Mat invmat = Inv(G); + Vec hdv; DiffOpChristoffelHCurlCurl::Apply(fel, mip, x, hdv, lh); - for (int i=0; i> mat) - //{ - //} - // - //using DiffOp>::ApplySIMDIR; - //static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, - // BareSliceVector x, BareSliceMatrix> y) - //{ - // - //} - // + static void GenerateMatrixSIMDIR (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> mat) + { + throw Exception("Christoffel symbol of second kind is a nonlinear operator! Use only apply!"); + } + + + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + throw ExceptionNOSIMD("ApplySIMDIR for Complex not implemented in Christoffel2 DiffOp"); + } + + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + + const HCurlCurlFiniteElement & bfel = dynamic_cast&> (fel); + + size_t size = bmir.Size()*SIMD::Size()*D*D*D; + STACK_ARRAY(SIMD, mem, size); + FlatMatrix> hchristoffel1(D*D*D, bmir.Size(), &mem[0]); + + DiffOpChristoffelHCurlCurl::ApplySIMDIR(fel, bmir, x, hchristoffel1); + + STACK_ARRAY(SIMD, mem2, D*D*bmir.Size()*SIMD::Size()); + FlatMatrix> G(D*D, bmir.Size(), &mem2[0]); + bfel.Evaluate (bmir, x, G); + + for (int m = 0; m < bmir.Size(); m++) + { + Mat> G_m; + for (size_t j = 0; j < D*D; j++) + G_m(j) = G(j,m); + Mat> invG = Inv(G_m); + + auto christoffel1_m = hchristoffel1.Col(m); + + for (size_t i=0; i sum(0); + for (size_t p=0; p>::AddTransSIMDIR; //static void AddTransSIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, // BareSliceMatrix> x, BareSliceVector y) @@ -787,8 +956,10 @@ //} }; + template > + class DiffOpCurvatureHCurlCurl; - /// Riemann curvature tensor for HCurlCurl + /// Riemann curvature tensor for HCurlCurl template > class DiffOpRiemannHCurlCurl : public DiffOp > { @@ -798,7 +969,7 @@ enum { DIM_ELEMENT = D }; enum { DIM_DMAT = D*D*D*D }; enum { DIFFORDER = 2 }; - static Array GetDimensions() { return Array ( { D*D,D*D } ); }; + static Array GetDimensions() { return Array ( { D,D,D,D } ); }; static constexpr double eps() { return 1e-4; } @@ -826,112 +997,235 @@ const TVX & x, TVY & y, LocalHeap & lh) { - HeapReset hr(lh); - const HCurlCurlFiniteElement & bfel = dynamic_cast&> (fel); - typedef typename TVX::TSCAL TSCAL; - int nd_u = bfel.GetNDof(); - FlatMatrixFixWidth bmat(nd_u, lh); - bfel.CalcMappedShape (mip, bmat); - - Vec hv = Trans(bmat) * x; - Mat defmat; - defmat.AsVector() = hv; - // Mat invmat = Inv(defmat); + if constexpr (!std::is_same()) + { + throw Exception("Riemann diffop Apply only implemented for TSCAL == double"); + } + else + { + Vec Q; + DiffOpCurvatureHCurlCurl::Apply(fel, mip, x, Q, lh); - FlatMatrix shape_ul(nd_u,D*D*D, lh); - FlatMatrix shape_ur(nd_u,D*D*D, lh); - FlatMatrix shape_ull(nd_u,D*D*D, lh); - FlatMatrix shape_urr(nd_u,D*D*D, lh); - FlatMatrix dshape_u_ref(nd_u,D*D*D, lh); + y = TSCAL(0.0); - FlatMatrix bmatu(nd_u,D*D*D*D, lh); - FlatMatrixFixWidth dshape_u_ref_comp(nd_u, lh); - FlatMatrixFixWidth dshape_u(nd_u, lh); - - DiffOpChristoffelHCurlCurl::GenerateMatrix(fel, mip, Trans(shape_ul), lh); - Vec hchristoffel1; - Vec hchristoffel2; - DiffOpChristoffelHCurlCurl::Apply(fel, mip, x, hchristoffel1, lh); - DiffOpChristoffel2HCurlCurl::Apply(fel, mip, x, hchristoffel2, lh); + if constexpr (D==2) + { + y(0*D*D*D+1*D*D+0*D+1) = -Q(0); + + // R1212 = -R2112 = -R1221 = R2121 + y(1*D*D*D+0*D*D+0*D+1) = y(0*D*D*D+1*D*D+1*D+0) = -y(0*D*D*D+1*D*D+0*D+1); + y(1*D*D*D+0*D*D+1*D+0) = y(0*D*D*D+1*D*D+0*D+1); + } + else + { + // Q_xx = = -R_yzyz + // Q_xy = = R_xzyz + // Q_xz = = -R_xyyz + // Q_yy = = -R_xzxz + // Q_yz = = R_xyxz + // Q_zz = = -R_xyxy + + y(0*D*D*D+1*D*D+0*D+1) = -Q(2*D+2); + y(0*D*D*D+1*D*D+0*D+2) = Q(1*D+2); + y(0*D*D*D+1*D*D+1*D+2) = -Q(0*D+2); + y(0*D*D*D+2*D*D+0*D+2) = -Q(1*D+1); + y(0*D*D*D+2*D*D+1*D+2) = Q(0*D+1); + y(1*D*D*D+2*D*D+1*D+2) = -Q(0*D+0); + + // R1212 = -R2112 = -R1221 = R2121 + // R1213 = R1312 = -R2113 = -R1231 = -R3112 = -R1321 = R2131 = R3121 + // R1223 = -R2123 = -R1232 = R2312 = -R2321 = -R3212 = R2132 = R3221 + // R1313 = -R3113 = -R1331 = R3131 + // R1323 = -R3123 = -R1332 = R2313 = -R2331 = -R3213 = R3231 = R3132 + // R2323 = -R3223 = -R2332 = R3232 + y(1*D*D*D+0*D*D+0*D+1) = y(0*D*D*D+1*D*D+1*D+0) = -y(0*D*D*D+1*D*D+0*D+1); + y(1*D*D*D+0*D*D+1*D+0) = y(0*D*D*D+1*D*D+0*D+1); + + y(1*D*D*D+0*D*D+0*D+2) = y(0*D*D*D+1*D*D+2*D+0) = y(2*D*D*D+0*D*D+0*D+1) = y(0*D*D*D+2*D*D+1*D+0) = -y(0*D*D*D+1*D*D+0*D+2); + y(0*D*D*D+2*D*D+0*D+1) = y(1*D*D*D+0*D*D+2*D+0) = y(2*D*D*D+0*D*D+1*D+0) = y(0*D*D*D+1*D*D+0*D+2); + + y(1*D*D*D+0*D*D+1*D+2) = y(0*D*D*D+1*D*D+2*D+1) = y(1*D*D*D+2*D*D+1*D+0) = y(2*D*D*D+1*D*D+0*D+1) = -y(0*D*D*D+1*D*D+1*D+2); + y(1*D*D*D+2*D*D+0*D+1) = y(1*D*D*D+0*D*D+2*D+1) = y(2*D*D*D+1*D*D+1*D+0) = y(0*D*D*D+1*D*D+1*D+2); + + y(2*D*D*D+0*D*D+0*D+2) = y(0*D*D*D+2*D*D+2*D+0) = -y(0*D*D*D+2*D*D+0*D+2); + y(2*D*D*D+0*D*D+2*D+0) = y(0*D*D*D+2*D*D+0*D+2); + + y(2*D*D*D+0*D*D+1*D+2) = y(0*D*D*D+2*D*D+2*D+1) = y(1*D*D*D+2*D*D+2*D+0) = y(2*D*D*D+1*D*D+0*D+2) = -y(0*D*D*D+2*D*D+1*D+2); + y(1*D*D*D+2*D*D+0*D+2) = y(2*D*D*D+1*D*D+2*D+0) = y(2*D*D*D+0*D*D+2*D+1) = y(0*D*D*D+2*D*D+1*D+2); + + y(2*D*D*D+1*D*D+1*D+2) = y(1*D*D*D+2*D*D+2*D+1) = -y(1*D*D*D+2*D*D+1*D+2); + y(2*D*D*D+1*D*D+2*D+1) = y(1*D*D*D+2*D*D+1*D+2); + } + } + } + + static void GenerateMatrixSIMDIR (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> mat) + { + throw Exception("Riemann curvature tensor is a nonlinear operator! Use only apply!"); + } + + + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + throw ExceptionNOSIMD("ApplySIMDIR for Complex not implemented in Riemann DiffOp"); + } + + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + size_t size = (bmir.Size()+1)*SIMD::Size()*D*(D-1)/2*D*(D-1)/2; + STACK_ARRAY(SIMD, mem, size); + FlatMatrix> Q(D*(D-1)/2*D*(D-1)/2, bmir.Size(), mem); + DiffOpCurvatureHCurlCurl::ApplySIMDIR(fel, bmir, x, Q); - const IntegrationPoint& ip = mip.IP(); - const ElementTransformation & eltrans = mip.GetTransformation(); - for (int j = 0; j < D; j++) // d / dxj + //set zero, can this be improved? + for (size_t i = 0; i < D*D*D*D; i++) + y.Row(i).Range(bmir.Size()) = SIMD(0.0); + + if constexpr (D==2) { - IntegrationPoint ipl(ip); - ipl(j) -= eps(); - IntegrationPoint ipr(ip); - ipr(j) += eps(); - IntegrationPoint ipll(ip); - ipll(j) -= 2*eps(); - IntegrationPoint iprr(ip); - iprr(j) += 2*eps(); + y.Row(0*D*D*D+1*D*D+0*D+1).Range(bmir.Size()) = -Q.Row(0); - MappedIntegrationPoint mipl(ipl, eltrans); - MappedIntegrationPoint mipr(ipr, eltrans); - MappedIntegrationPoint mipll(ipll, eltrans); - MappedIntegrationPoint miprr(iprr, eltrans); - - DiffOpChristoffelHCurlCurl::GenerateMatrix(fel, mipl, Trans(shape_ul), lh); - DiffOpChristoffelHCurlCurl::GenerateMatrix(fel, mipr, Trans(shape_ur), lh); - DiffOpChristoffelHCurlCurl::GenerateMatrix(fel, mipll, Trans(shape_ull), lh); - DiffOpChristoffelHCurlCurl::GenerateMatrix(fel, miprr, Trans(shape_urr), lh); + // R1212 = -R2112 = -R1221 = R2121 + y.Row(1*D*D*D+0*D*D+0*D+1).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+1*D+0).Range(bmir.Size()) = -y.Row(0*D*D*D+1*D*D+0*D+1); + y.Row(1*D*D*D+0*D*D+1*D+0).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+0*D+1); + } + else + { + // Q_xx = = -R_yzyz + // Q_xy = = R_xzyz + // Q_xz = = -R_xyyz + // Q_yy = = -R_xzxz + // Q_yz = = R_xyxz + // Q_zz = = -R_xyxy + + y.Row(0*D*D*D+1*D*D+0*D+1).Range(bmir.Size()) = -Q.Row(2*D+2); + y.Row(0*D*D*D+1*D*D+0*D+2).Range(bmir.Size()) = Q.Row(1*D+2); + y.Row(0*D*D*D+1*D*D+1*D+2).Range(bmir.Size()) = -Q.Row(0*D+2); + y.Row(0*D*D*D+2*D*D+0*D+2).Range(bmir.Size()) = -Q.Row(1*D+1); + y.Row(0*D*D*D+2*D*D+1*D+2).Range(bmir.Size()) = Q.Row(0*D+1); + y.Row(1*D*D*D+2*D*D+1*D+2).Range(bmir.Size()) = -Q.Row(0*D+0); + + // R1212 = -R2112 = -R1221 = R2121 + // R1213 = R1312 = -R2113 = -R1231 = -R3112 = -R1321 = R2131 = R3121 + // R1223 = -R2123 = -R1232 = R2312 = -R2321 = -R3212 = R2132 = R3221 + // R1313 = -R3113 = -R1331 = R3131 + // R1323 = -R3123 = -R1332 = R2313 = -R2331 = -R3213 = R3231 = R3132 + // R2323 = -R3223 = -R2332 = R3232 + y.Row(1*D*D*D+0*D*D+0*D+1).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+1*D+0).Range(bmir.Size()) = -y.Row(0*D*D*D+1*D*D+0*D+1); + y.Row(1*D*D*D+0*D*D+1*D+0).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+0*D+1); + + y.Row(1*D*D*D+0*D*D+0*D+2).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+2*D+0).Range(bmir.Size()) = y.Row(2*D*D*D+0*D*D+0*D+1).Range(bmir.Size()) = y.Row(0*D*D*D+2*D*D+1*D+0).Range(bmir.Size()) = -y.Row(0*D*D*D+1*D*D+0*D+2); + y.Row(0*D*D*D+2*D*D+0*D+1).Range(bmir.Size()) = y.Row(1*D*D*D+0*D*D+2*D+0).Range(bmir.Size()) = y.Row(2*D*D*D+0*D*D+1*D+0).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+0*D+2); - dshape_u_ref = (1.0/(12.0*eps())) * (8.0*shape_ur-8.0*shape_ul-shape_urr+shape_ull); + y.Row(1*D*D*D+0*D*D+1*D+2).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+2*D+1).Range(bmir.Size()) = y.Row(1*D*D*D+2*D*D+1*D+0).Range(bmir.Size()) = y.Row(2*D*D*D+1*D*D+0*D+1).Range(bmir.Size()) = -y.Row(0*D*D*D+1*D*D+1*D+2); + y.Row(1*D*D*D+2*D*D+0*D+1).Range(bmir.Size()) = y.Row(1*D*D*D+0*D*D+2*D+1).Range(bmir.Size()) = y.Row(2*D*D*D+1*D*D+1*D+0).Range(bmir.Size()) = y.Row(0*D*D*D+1*D*D+1*D+2); + + y.Row(2*D*D*D+0*D*D+0*D+2).Range(bmir.Size()) = y.Row(0*D*D*D+2*D*D+2*D+0).Range(bmir.Size()) = -y.Row(0*D*D*D+2*D*D+0*D+2); + y.Row(2*D*D*D+0*D*D+2*D+0).Range(bmir.Size()) = y.Row(0*D*D*D+2*D*D+0*D+2); + + y.Row(2*D*D*D+0*D*D+1*D+2).Range(bmir.Size()) = y.Row(0*D*D*D+2*D*D+2*D+1).Range(bmir.Size()) = y.Row(1*D*D*D+2*D*D+2*D+0).Range(bmir.Size()) = y.Row(2*D*D*D+1*D*D+0*D+2).Range(bmir.Size()) = -y.Row(0*D*D*D+2*D*D+1*D+2); + y.Row(1*D*D*D+2*D*D+0*D+2).Range(bmir.Size()) = y.Row(2*D*D*D+1*D*D+2*D+0).Range(bmir.Size()) = y.Row(2*D*D*D+0*D*D+2*D+1).Range(bmir.Size()) = y.Row(0*D*D*D+2*D*D+1*D+2); + + y.Row(2*D*D*D+1*D*D+1*D+2).Range(bmir.Size()) = y.Row(1*D*D*D+2*D*D+2*D+1).Range(bmir.Size()) = -y.Row(1*D*D*D+2*D*D+1*D+2); + y.Row(2*D*D*D+1*D*D+2*D+1).Range(bmir.Size()) = y.Row(1*D*D*D+2*D*D+1*D+2); + } + } + + // using DiffOp>::AddTransSIMDIR; + // static void AddTransSIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + // BareSliceMatrix> x, BareSliceVector y) + // { + // } + }; + + - for (int l = 0; l < D*D*D; l++) - bmatu.Col(j*D*D*D+l) = dshape_u_ref.Col(l); - } + /// Riemann curvature tensor for HCurlCurl + template > + class DiffOpRicciHCurlCurl : public DiffOp > + { + public: + enum { DIM = 1 }; + enum { DIM_SPACE = D }; + enum { DIM_ELEMENT = D }; + enum { DIM_DMAT = D*D }; + enum { DIFFORDER = 2 }; + static Array GetDimensions() { return Array ( { D,D } ); }; + static constexpr double eps() { return 1e-4; } + + + /// + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const SIP & sip, + MAT & mat, LocalHeap & lh) + { + cout << "nicht gut" << endl; + cout << "type(fel) = " << typeid(fel).name() << ", sip = " << typeid(sip).name() + << ", mat = " << typeid(mat).name() << endl; + } + + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const MIP & mip, + MAT mat, LocalHeap & lh) + { + throw Exception("Ricci curvature tensor is a nonlinear operator! Use only apply!"); + } - for (int j = 0; j < D*D*D; j++) + template + static void Apply (const AFEL & fel, const MIP & mip, + const TVX & x, TVY & y, + LocalHeap & lh) + { + HeapReset hr(lh); + const HCurlCurlFiniteElement & bfel = dynamic_cast&> (fel); + + typedef typename TVX::TSCAL TSCAL; + if constexpr (!std::is_same()) + { + throw Exception("Ricci diffop only implemented for TSCAL == double"); + } + else { - for (int k = 0; k < nd_u; k++) - for (int l = 0; l < D; l++) - dshape_u_ref_comp(k,l) = bmatu(k, l*D*D*D+j); + Mat Qmat; + FlatVector Q(D*D,Qmat.Data()); + DiffOpCurvatureHCurlCurl::Apply(fel, mip, x, Q, lh); + Mat g; - dshape_u = dshape_u_ref_comp * mip.GetJacobianInverse(); - - for (int k = 0; k < nd_u; k++) - for (int l = 0; l < D; l++) - bmatu(k, l*D*D*D+j) = dshape_u(k,l); - } + bfel.EvaluateMappedShape (mip, x, g); - Vec hchristoffel1_der = Trans(bmatu)*x; + Mat ginv = Inv(g); - if constexpr (D==2) // exploit that in two dimensions the Riemann curvature tensor consists only of one independent number - { - y = TSCAL(0.0); - //R1212 - y(0*D*D*D+1*D*D+0*D+1) = hchristoffel1_der(0*D*D*D+0*D*D+1*D+1)-hchristoffel1_der(1*D*D*D+0*D*D+0*D+1); - for (int q=0; q Riemann; + // DiffOpRiemannHCurlCurl::Apply(fel, mip, x, Riemann, lh); + // for (size_t i = 0; i < D; i++) + // for (size_t j = 0; j < D; j++) + // { + // TSCAL sum = 0.0; + // for (size_t k = 0; k < D; k++) + // for (size_t l = 0; l < D; l++) + // sum += ginv(k,l) * Riemann(((k*D+i)*D+l)*D+j); + // y(i*D+j) = sum; + // } } } @@ -941,19 +1235,279 @@ //} // //using DiffOp>::ApplySIMDIR; - //static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, - // BareSliceVector x, BareSliceMatrix> y) - //{ - // - //} - // + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + throw ExceptionNOSIMD("ApplySIMDIR for Complex not implemented in Ricci DiffOp"); + } + + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + const HCurlCurlFiniteElement & bfel = dynamic_cast&> (fel); + + + size_t size = (bmir.Size()+1)*SIMD::Size()*D*(D-1)/2*D*(D-1)/2; + STACK_ARRAY(SIMD, mem, size); + FlatMatrix> Q(D*(D-1)/2*D*(D-1)/2, bmir.Size(), mem); + DiffOpCurvatureHCurlCurl::ApplySIMDIR(fel, bmir, x, Q); + + STACK_ARRAY(SIMD, mem2, D*D*bmir.Size()*SIMD::Size()); + FlatMatrix> G(D*D, bmir.Size(), &mem2[0]); + bfel.Evaluate (bmir, x, G); + + for (size_t m = 0; m < bmir.Size(); m++) + { + Mat> G_m; + for (size_t j = 0; j < D*D; j++) + G_m(j) = G(j,m); + Mat> invG = Inv(G_m); + + + if constexpr (D==2) + { + // maybe wrong sign, see curvature diffop! + y.Col(m).Range(0,D*D) = Q(0,m)*Cof(invG).AsVector(); + } + else + { + Mat> Qmat_m; + for (size_t j = 0; j < D*D; j++) + Qmat_m(j) = Q(j,m); + //sign? + y.Col(m).Range(0,D*D) = -TensorCrossProduct(invG,Qmat_m).AsVector(); + } + } + } + //using DiffOp>::AddTransSIMDIR; //static void AddTransSIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, // BareSliceMatrix> x, BareSliceVector y) //{ //} }; + + + /// Curvature operator for HCurlCurl + template + class DiffOpCurvatureHCurlCurl : public DiffOp > + { + public: + enum { DIM = 1 }; + enum { DIM_SPACE = D }; + enum { DIM_ELEMENT = D }; + enum { DIM_DMAT = (D*(D-1)/2)*(D*(D-1)/2) }; + enum { DIFFORDER = 2 }; + static Array GetDimensions() { return Array ( { (D*(D-1)/2),(D*(D-1)/2) } ); }; + + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const SIP & sip, + MAT & mat, LocalHeap & lh) + { + cout << "nicht gut" << endl; + cout << "type(fel) = " << typeid(fel).name() << ", sip = " << typeid(sip).name() + << ", mat = " << typeid(mat).name() << endl; + } + + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const MIP & mip, + MAT mat, LocalHeap & lh) + { + throw Exception("Curvature curvature tensor is a nonlinear operator! Use only apply!"); + } + + template + static void Apply (const AFEL & fel, const MIP & mip, + const TVX & x, TVY & y, + LocalHeap & lh) + { + typedef typename TVX::TSCAL TSCAL; + if constexpr (!std::is_same()) + { + throw Exception("Riemann diffop only implemented for TSCAL == double"); + } + else + { + HeapReset hr(lh); + const HCurlCurlFiniteElement & bfel = dynamic_cast&> (fel); + + Vec hchristoffel1; + Vec hchristoffel2; + DiffOpChristoffelHCurlCurl::Apply(fel, mip, x, hchristoffel1, lh); + + Mat G; + bfel.EvaluateMappedShape (mip, x, G); + Mat invG = Inv(G); + + for (size_t i=0; i = -R_yzyz + // Q_xy = = R_xzyz + // Q_xz = = -R_xyyz + // Q_yy = = -R_xzxz + // Q_yz = = R_xyxz + // Q_zz = = -R_xyxy + + + //nonlinear christoffelpart + for (size_t q=0; q x, BareSliceMatrix> y) + { + throw ExceptionNOSIMD("ApplySIMDIR for Complex not implemented in Curvature DiffOp"); + } + + static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, BareSliceMatrix> y) + { + const HCurlCurlFiniteElement & bfel = static_cast&> (fel); + size_t size = (bmir.Size()+1)*SIMD::Size()*D*D*D; + STACK_ARRAY(SIMD, mem, 2*size); + FlatMatrix> hchristoffel1(D*D*D, bmir.Size(), &mem[0]); + FlatMatrix> hchristoffel2(D*D*D, bmir.Size(), &mem[size]); + + DiffOpChristoffelHCurlCurl::ApplySIMDIR(fel, bmir, x, hchristoffel1); + + STACK_ARRAY(SIMD, mem2, D*D*bmir.Size()*SIMD::Size()); + FlatMatrix> G(D*D, bmir.Size(), &mem2[0]); + bfel.Evaluate (bmir, x, G); + + //inner? + for (size_t m = 0; m < bmir.Size(); m++) + { + Mat> G_m; + for (size_t j = 0; j < D*D; j++) + G_m(j) = G(j,m); + Mat> invG = Inv(G_m); + + auto christoffel1_m = hchristoffel1.Col(m); + for (size_t i=0; i sum = 0; + for (size_t p=0; p = -R_yzyz + // Q_xy = = R_xzyz + // Q_xz = = -R_xyyz + // Q_yy = = -R_xzxz + // Q_yz = = R_xyxz + // Q_zz = = -R_xyxy + + //nonlinear christoffelpart + for (size_t q=0; q ama,const Flags & flags,bool checkflags) : FESpace(ama,flags), issurfacespace(false) @@ -995,6 +1549,9 @@ additional_evaluators.Set ("christoffel2", make_shared>> ()); additional_evaluators.Set ("dual", make_shared>> ()); additional_evaluators.Set ("Riemann", make_shared>> ()); + additional_evaluators.Set ("Ricci", make_shared>> ()); + additional_evaluators.Set ("inc", make_shared>> ()); + additional_evaluators.Set ("curvature", make_shared>> ()); break; case 3: additional_evaluators.Set ("grad", make_shared>> ()); @@ -1003,6 +1560,9 @@ additional_evaluators.Set ("dual", make_shared>> ()); additional_evaluators.Set ("dualbnd", make_shared>> ()); additional_evaluators.Set ("Riemann", make_shared>> ()); + additional_evaluators.Set ("Ricci", make_shared>> ()); + additional_evaluators.Set ("inc", make_shared>> ()); + additional_evaluators.Set ("curvature", make_shared>> ()); break; default: ; diff -Nru ngsolve-6.2.2102/comp/hcurlhdivfes.cpp ngsolve-6.2.2103/comp/hcurlhdivfes.cpp --- ngsolve-6.2.2102/comp/hcurlhdivfes.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hcurlhdivfes.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -764,7 +764,7 @@ virtual ~EdgeP1Prolongation() { } virtual void Update (const FESpace & fes) { ; } - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const { return nullptr; } virtual void ProlongateInline (int finelevel, BaseVector & v) const @@ -774,21 +774,22 @@ auto fv = v.FV(); fv.Range(2*nf, fv.Size()) = 0; + for (size_t i = nc; i < nf; i++) { auto [info, nrs] = ma->GetParentEdges(i); - int pa1 = nrs[0]; - int pa2 = nrs[1]; - int pa3 = nrs[2]; - + int pa1 = nrs[0]; + int pa2 = nrs[1]; + int pa3 = nrs[2]; + if (pa2 == -1) { double fac0 = (info & 1) ? 0.5 : -0.5; fv(2*i) = fac0 * fv(2*pa1) - 0.125 * fv(2*pa1+1); fv(2*i+1) = 0.25 * fv(2*pa1+1); } - else + else if (info<8)//bisecting edge { double fac1 = (info&1) ? 0.5 : -0.5; double fac2 = (info&2) ? 0.5 : -0.5; @@ -796,6 +797,15 @@ fv(2*i) = fac1 * fv(2*pa1) + fac2 * fv(2*pa2) + fac3 * fv(2*pa3+1); fv(2*i+1) = 0.5 * (fv(2*pa1+1)+fv(2*pa2+1)) - 0.25*fv(2*pa3+1); } + else // info>=8: red edge + { + double fac1 = (info&1) ? 0.25 : -0.25; + double fac2 = (info&2) ? 0.25 : -0.25; + double fac3 = (info&4) ? 0.25 : -0.25; + fv(2*i) = fac1 * fv(2*pa1) + fac2 * fv(2*pa2) + fac3 * fv(2*pa3) + + 0.125 * fv(2*pa1+1) - 0.125 * fv(2*pa2+1); + fv(2*i+1) = 0.25*fv(2*pa3+1); + } } // every edge from coarse level got split @@ -843,7 +853,7 @@ fv(2*pa1) += fac0 * fv(2*i); fv(2*pa1+1) += -0.125 * fv(2*i) + 0.25 * fv(2*i+1); } - else + else if (info<8)//bisecting edge { double fac1 = (info&1) ? 0.5 : -0.5; double fac2 = (info&2) ? 0.5 : -0.5; @@ -854,6 +864,18 @@ fv(2*pa2+1) += 0.5 * fv(2*i+1); fv(2*pa3+1) += fac3 * fv(2*i) - 0.25 * fv(2*i+1); } + else // info>=8: red edge + { + double fac1 = (info&1) ? 0.25 : -0.25; + double fac2 = (info&2) ? 0.25 : -0.25; + double fac3 = (info&4) ? 0.25 : -0.25; + fv(2*pa1) += fac1 * fv(2*i); + fv(2*pa1+1) += 0.125 * fv(2*i); + fv(2*pa2) += fac2 * fv(2*i); + fv(2*pa2+1) -= 0.125 * fv(2*i); + fv(2*pa3) += fac3 * fv(2*i); + fv(2*pa3+1) += 0.25*fv(2*i+1); + } } } diff -Nru ngsolve-6.2.2102/comp/hcurlhofespace.cpp ngsolve-6.2.2103/comp/hcurlhofespace.cpp --- ngsolve-6.2.2102/comp/hcurlhofespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hcurlhofespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -477,6 +477,12 @@ UpdateDofTables(); UpdateCouplingDofArray(); + if (low_order_space) + low_order_embedding = + make_shared (GetNDof(), + IntRange(low_order_space->GetNDof()), + IsComplex()); + } void HCurlHighOrderFESpace :: DoArchive(Archive & archive) diff -Nru ngsolve-6.2.2102/comp/hdivdivfespace.cpp ngsolve-6.2.2103/comp/hdivdivfespace.cpp --- ngsolve-6.2.2102/comp/hdivdivfespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hdivdivfespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -170,8 +170,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdDivDiv"); return -2*TraceCF(dir->Operator("Grad"))*proxy + 2*SymmetricCF(dir->Operator("Grad") * proxy); } }; diff -Nru ngsolve-6.2.2102/comp/hdivdivsurfacespace.cpp ngsolve-6.2.2103/comp/hdivdivsurfacespace.cpp --- ngsolve-6.2.2102/comp/hdivdivsurfacespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hdivdivsurfacespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -239,8 +239,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdHDivSurface"); return -2*TraceCF(dir->Operator("Gradboundary"))*proxy + 2*SymmetricCF(dir->Operator("Gradboundary") * proxy); } diff -Nru ngsolve-6.2.2102/comp/hdivfes.cpp ngsolve-6.2.2103/comp/hdivfes.cpp --- ngsolve-6.2.2102/comp/hdivfes.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hdivfes.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -273,7 +273,7 @@ shared_ptr ma; const FESpace & space; - array, 16> boundaryprol; + array, 20> boundaryprol; // 16 + 4 // array, 6+3+1> innerprol; array, 120> innerprol; @@ -286,7 +286,8 @@ // v3 ... subdivision vertex ma->EnableTable("parentfaces"); - // boundary prol (only 8 cases are actually used) + // boundary prol (only 8 cases are actually used) + // add 4 more cases for tet red refinement for (int classnr = 0; classnr < 16; classnr++) { int verts[4] = { 1, 2, 3, 4 }; @@ -325,7 +326,32 @@ } CalcInverse (massf); boundaryprol[classnr] = 0.5 * massf * massfc; - // cout << "boundarypol[" << classnr << "] = " << endl << FlatMatrix(boundaryprol[classnr]) << endl; + //cout << "boundarypol[" << classnr << "] = " << endl << FlatMatrix(boundaryprol[classnr]) << endl; + } + + // 4 red refinement boundary faces + for (int classnr =16; classnr < 20; classnr++) + { + Matrix<> bprol(3,3); + if (classnr==16){ + bprol(0,0) = 0.25; bprol(0,1) = 0.0625; bprol(0,2) = -0.125; + bprol(1,0) = 0; bprol(1,1) = 0.125; bprol(1,2) = 0; + bprol(2,0) = 0; bprol(2,1) = 0.; bprol(2,2) = 0.125; + }else if (classnr==17){ + bprol(0,0) = -0.25; bprol(0,1) = 0.0625; bprol(0,2) = 0.125; + bprol(1,0) = 0; bprol(1,1) = 0.125; bprol(1,2) = 0; + bprol(2,0) = 0; bprol(2,1) = 0.; bprol(2,2) = -0.125; + }else if (classnr==18){ + bprol(0,0) = 0.25; bprol(0,1) = 0; bprol(0,2) = 0.25; + bprol(1,0) = 0; bprol(1,1) = -0.0625; bprol(1,2) = 0.375; + bprol(2,0) = 0; bprol(2,1) = -0.03125; bprol(2,2) = -0.0625; + }else{ + bprol(0,0) = -0.25; bprol(0,1) = 0; bprol(0,2) = 0; + bprol(1,0) = 0; bprol(1,1) = 0.0625; bprol(1,2) = 0.375; + bprol(2,0) = 0; bprol(2,1) = 0.03125; bprol(2,2) = -0.0625; + } + boundaryprol[classnr] = bprol; + //cout << "boundarypol[" << classnr << "] = " << endl << FlatMatrix(boundaryprol[classnr]) << endl; } @@ -484,7 +510,7 @@ virtual ~BDM1Prolongation() { } virtual void Update (const FESpace & fes) { ; } - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const { return nullptr; } virtual shared_ptr GetInnerDofs (int finelevel) const @@ -499,7 +525,7 @@ for (size_t i = nc; i < nf; i++) { auto [info, nrs] = ma->GetParentFaces(i); - if (nrs[1] != -1) + if (nrs[1] != -1 || info==20) for (int j = 0; j < 3; j++) if (freedofs->Test(3*i+j)) inner.SetBit(3*i+j); @@ -531,9 +557,12 @@ if (pa2 == -1) { - Vec<3> fvecc = fv.Range(3*pa1, 3*pa1+3); - Vec<3> fvecf = boundaryprol[info%16] * fvecc; - fv.Range(3*i, 3*i+3) = fvecf; + if (info==20) ;// interior face:: do nothing + else{ // bisect or red face + Vec<3> fvecc = fv.Range(3*pa1, 3*pa1+3); + Vec<3> fvecf = boundaryprol[info] * fvecc; + fv.Range(3*i, 3*i+3) = fvecf; + } } else { @@ -591,10 +620,13 @@ if (pa2 == -1) { - Vec<3> fvecf = fv.Range(3*i, 3*i+3); - Vec<3> fvecc = Trans(boundaryprol[info%16]) * fvecf; - fv.Range(3*pa1, 3*pa1+3) += fvecc; - fv.Range(3*i, 3*i+3) = 0.0; + if (info==20) ;// interior face:: do nothing + else{ // bisect or red face + Vec<3> fvecf = fv.Range(3*i, 3*i+3); + Vec<3> fvecc = Trans(boundaryprol[info]) * fvecf; + fv.Range(3*pa1, 3*pa1+3) += fvecc; + fv.Range(3*i, 3*i+3) = 0.0; + } } else { @@ -627,7 +659,7 @@ virtual ~BDM1ProlongationTRIG() { } virtual void Update (const FESpace & fes) { ; } - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const { return nullptr; } virtual void ProlongateInline (int finelevel, BaseVector & v) const @@ -651,7 +683,7 @@ fv(2*i) = fac0 * fv(2*pa1) + 0.125 * fv(2*pa1+1); fv(2*i+1) = 0.25 * fv(2*pa1+1); } - else + else if (info<8)//bisecting edge { double fac1 = (info&1) ? 0.5 : -0.5; double fac2 = (info&2) ? 0.5 : -0.5; @@ -659,6 +691,15 @@ fv(2*i) = fac1 * fv(2*pa1) + fac2 * fv(2*pa2) + fac3 * fv(2*pa3+1); fv(2*i+1) = 0.5 * (fv(2*pa1+1)+fv(2*pa2+1)) - 0.25*fv(2*pa3+1); } + else // info>=8: red edge + { + double fac1 = (info&1) ? 0.25 : -0.25; + double fac2 = (info&2) ? 0.25 : -0.25; + double fac3 = (info&4) ? 0.25 : -0.25; + fv(2*i) = fac1 * fv(2*pa1) + fac2 * fv(2*pa2) + fac3 * fv(2*pa3) + - 0.125 * fv(2*pa1+1) + 0.125 * fv(2*pa2+1); + fv(2*i+1) = 0.25*fv(2*pa3+1); + } } // every edge from coarse level got split @@ -706,7 +747,7 @@ fv(2*pa1) += fac0 * fv(2*i); fv(2*pa1+1) += 0.125 * fv(2*i) + 0.25 * fv(2*i+1); } - else + else if (info<8)//bisecting edge { double fac1 = (info&1) ? 0.5 : -0.5; double fac2 = (info&2) ? 0.5 : -0.5; @@ -717,6 +758,18 @@ fv(2*pa2+1) += 0.5 * fv(2*i+1); fv(2*pa3+1) += fac3 * fv(2*i) - 0.25 * fv(2*i+1); } + else // info>=8: red edge + { + double fac1 = (info&1) ? 0.25 : -0.25; + double fac2 = (info&2) ? 0.25 : -0.25; + double fac3 = (info&4) ? 0.25 : -0.25; + fv(2*pa1) += fac1 * fv(2*i); + fv(2*pa1+1) -= 0.125 * fv(2*i); + fv(2*pa2) += fac2 * fv(2*i); + fv(2*pa2+1) += 0.125 * fv(2*i); + fv(2*pa3) += fac3 * fv(2*i); + fv(2*pa3+1) += 0.25*fv(2*i+1); + } } } @@ -740,6 +793,7 @@ evaluator[BND] = make_shared>>(); flux_evaluator[VOL] = make_shared>>(); additional_evaluators.Set ("grad", make_shared>> ()); + additional_evaluators.Set ("dual", make_shared>> ()); prol = make_shared (*this); } else if(ma->GetDimension() == 3) @@ -748,7 +802,8 @@ evaluator[BND] = make_shared>>(); flux_evaluator[VOL] = make_shared>>(); additional_evaluators.Set ("grad", make_shared>> ()); - prol = make_shared (*this); + additional_evaluators.Set ("dual", make_shared>> ()); + prol = make_shared (*this); } } diff -Nru ngsolve-6.2.2102/comp/hdivhosurfacefespace.cpp ngsolve-6.2.2103/comp/hdivhosurfacefespace.cpp --- ngsolve-6.2.2102/comp/hdivhosurfacefespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hdivhosurfacefespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -71,8 +71,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpDivHDivSurface"); return -TraceCF(dir->Operator("Gradboundary"))*proxy; } @@ -199,6 +201,7 @@ flux_evaluator[BND] = make_shared>>(); additional_evaluators.Set ("grad", make_shared>> ()); + additional_evaluators.Set ("dual", make_shared>> ()); } highest_order_dc = flags.GetDefineFlag("highest_order_dc"); diff -Nru ngsolve-6.2.2102/comp/hdivhosurfacefespace.hpp ngsolve-6.2.2103/comp/hdivhosurfacefespace.hpp --- ngsolve-6.2.2102/comp/hdivhosurfacefespace.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/hdivhosurfacefespace.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -48,6 +48,12 @@ { return "HDivHighOrderSurfaceFESpace"; } + + virtual FlatArray GetDualShapeNodes (VorB vb) const override + { + static VorB nodes[] = { VOL, BND }; + return FlatArray (2, &nodes[0]); + } void Average (BaseVector & vec) const; diff -Nru ngsolve-6.2.2102/comp/irspace.cpp ngsolve-6.2.2103/comp/irspace.cpp --- ngsolve-6.2.2102/comp/irspace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/irspace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -17,7 +17,7 @@ ELEMENT_TYPE ElementType() const override { return et; } void Interpolate (const ElementTransformation & trafo, - const CoefficientFunction & func, BareSliceMatrix<> coefs, LocalHeap & lh) const override + const CoefficientFunction & func, SliceMatrix<> coefs, LocalHeap & lh) const override { HeapReset hr(lh); BaseMappedIntegrationRule & mir = trafo(ir, lh); @@ -161,6 +161,78 @@ return irs; } + + + + IntegrationRuleSpaceSurface::IntegrationRuleSpaceSurface (shared_ptr ama, const Flags & flags, bool checkflags) + : FESpace (ama, flags) + { + type = "irspacesurface"; + evaluator[VOL] = make_shared>(); + evaluator[BND] = make_shared>(); + + if (dimension > 1) + { + evaluator[VOL] = make_shared (evaluator[VOL], dimension); + evaluator[BND] = make_shared (evaluator[BND], dimension); + } + } + + void IntegrationRuleSpaceSurface::Update() + { + //cout << "update irspace" << endl; + firsteldof.SetSize(ma->GetNSE()+1); + size_t ndof = 0; + for (auto i : Range(ma->GetNSE())) + { + firsteldof[i] = ndof; + IntegrationRule ir(ma->GetElType( { BND, i } ), 2*order); + ndof += ir.Size(); + } + firsteldof.Last() = ndof; + //cout << "firstel = " << firsteldof << endl; + SetNDof(ndof); + + UpdateCouplingDofArray(); + } + + void IntegrationRuleSpaceSurface::UpdateCouplingDofArray() + { + // all dofs are local dofs + ctofdof.SetSize(ndof); + ctofdof = LOCAL_DOF; + } + + + FiniteElement & IntegrationRuleSpaceSurface::GetFE (ElementId ei, Allocator & lh) const + { + if (ei.VB() == BND && DefinedOn(ei)) + return *new (lh) IRFiniteElement(ma->GetElType(ei), order); + else + return SwitchET (ma->GetElType(ei), [&] (auto et) -> FiniteElement& + { + return *new (lh) DummyFE (); + }); + } + + void IntegrationRuleSpaceSurface::GetDofNrs (ElementId ei, Array & dnums) const + { + if (ei.VB() == BND) + dnums = IntRange(firsteldof[ei.Nr()], firsteldof[ei.Nr()+1]); + else + dnums.SetSize0(); + } + + std::map IntegrationRuleSpaceSurface::GetIntegrationRules() const + { + std::map irs; + irs[ET_SEGM] = IntegrationRule(ET_SEGM, 2*order); + irs[ET_TRIG] = IntegrationRule(ET_TRIG, 2*order); + irs[ET_QUAD] = IntegrationRule(ET_QUAD, 2*order); + return irs; + } + static RegisterFESpace init ("irspace"); + static RegisterFESpace initsurf ("irspacesurface"); } diff -Nru ngsolve-6.2.2102/comp/irspace.hpp ngsolve-6.2.2103/comp/irspace.hpp --- ngsolve-6.2.2102/comp/irspace.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/irspace.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -27,5 +27,22 @@ std::map GetIntegrationRules() const; }; + + class IntegrationRuleSpaceSurface : public FESpace + { + Array firsteldof; + public: + IntegrationRuleSpaceSurface (shared_ptr ama, const Flags & flags, bool checkflags=false); + void Update() override; + + virtual void UpdateCouplingDofArray() override; + + virtual FiniteElement & GetFE (ElementId ei, Allocator & lh) const override; + + virtual void GetDofNrs (ElementId ei, Array & dnums) const override; + + std::map GetIntegrationRules() const; + }; + } #endif diff -Nru ngsolve-6.2.2102/comp/l2hofespace.cpp ngsolve-6.2.2103/comp/l2hofespace.cpp --- ngsolve-6.2.2102/comp/l2hofespace.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/l2hofespace.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -24,7 +24,7 @@ virtual void Apply (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & mir, - BareSliceVector x, + BareSliceVector x, BareSliceMatrix> flux) const { if (comp == -1) @@ -40,12 +40,12 @@ BareSliceVector x) const { if (comp == -1) - static_cast (fel). + static_cast (fel). AddTrans(mir.IR(), flux, SliceMatrix (fel.GetNDof(), dim, dim, &x(0))); else diffop->AddTrans(fel, mir, flux.RowSlice(comp,dim), x.Slice(comp,dim)); } - + }; @@ -61,15 +61,15 @@ enum { DIM_DMAT = 1 }; enum { DIFFORDER = 0 }; static INT<0> GetDimensions() { return INT<0>(); }; - + static bool SupportsVB (VorB checkvb) { return true; } - + static string Name() { return "IdDual"; } // static constexpr bool SUPPORT_PML = true; - - static const BaseScalarFiniteElement & Cast (const FiniteElement & fel) + + static const BaseScalarFiniteElement & Cast (const FiniteElement & fel) { return static_cast (fel); } - + template static void GenerateMatrix (const FiniteElement & fel, const MIP & mip, MAT && mat, LocalHeap & lh) @@ -79,30 +79,30 @@ } #ifdef UNUSED template - static void GenerateMatrixIR (const FiniteElement & fel, + static void GenerateMatrixIR (const FiniteElement & fel, const BaseMappedIntegrationRule & mir, MAT & mat, LocalHeap & lh) { Cast(fel).CalcShape (mir.IR(), Trans(mat)); for (int i = 0; i < mir.Size(); i++) - mat.Row(i) /= mir[i].GetMeasure(); + mat.Row(i) /= mir[i].GetMeasure(); } #endif - + static void GenerateMatrixSIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & mir, BareSliceMatrix> mat) { - Cast(fel).CalcShape (mir.IR(), mat); + Cast(fel).CalcShape (mir.IR(), mat); for (int i = 0; i < mir.Size(); i++) - mat.Col(i).Range(0,fel.GetNDof()) /= mir[i].GetMeasure(); + mat.Col(i).Range(0,fel.GetNDof()) /= mir[i].GetMeasure(); } - + #ifdef UNSUED template static void Apply (const FiniteElement & fel, const MIP & mip, const TVX & x, TVY & y, - LocalHeap & lh) + LocalHeap & lh) { HeapReset hr(lh); y = Trans (Cast(fel).GetShape (mip.IP(), lh)) * x; @@ -111,7 +111,7 @@ static void Apply (const FiniteElement & fel, const MappedIntegrationPoint & mip, BareSliceVector x, FlatVector y, - LocalHeap & lh) + LocalHeap & lh) { y(0) = Cast(fel).Evaluate(mip.IP(), x); y(0) /= mip.GetMeasure(); @@ -131,21 +131,21 @@ // using ApplySIMDIR; - using DiffOp::ApplySIMDIR; + using DiffOp::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & mir, BareSliceVector x, BareSliceMatrix> y) { Cast(fel).Evaluate (mir.IR(), x, y.Row(0)); for (int i = 0; i < mir.Size(); i++) y(0,i) /= mir[i].GetMeasure(); - + } template static void ApplyTrans (const FiniteElement & fel, const MIP & mip, const TVX & x, TVY & y, - LocalHeap & lh) + LocalHeap & lh) { HeapReset hr(lh); y.Range(0,fel.GetNDof()) = (x(0)/mip.GetMeasure()) * Cast(fel).GetShape (mip.IP(), lh); @@ -154,7 +154,7 @@ /* // using DiffOp >::ApplyTransIR; template - static void ApplyTransIR (const FiniteElement & fel, + static void ApplyTransIR (const FiniteElement & fel, const MIR & mir, FlatMatrix x, BareSliceVector y, LocalHeap & lh) @@ -163,15 +163,15 @@ } template - static void ApplyTransIR (const FiniteElement & fel, + static void ApplyTransIR (const FiniteElement & fel, const MIR & mir, FlatMatrix x, BareSliceVector y, LocalHeap & lh) { - DiffOp > :: ApplyTransIR (fel, mir, x, y, lh); + DiffOp > :: ApplyTransIR (fel, mir, x, y, lh); } - using DiffOp >::AddTransSIMDIR; + using DiffOp >::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & mir, BareSliceMatrix> y, BareSliceVector x) { @@ -185,7 +185,7 @@ } */ - + /* static shared_ptr DiffShape (shared_ptr proxy, @@ -202,17 +202,17 @@ - - - - L2HighOrderFESpace :: + + + + L2HighOrderFESpace :: L2HighOrderFESpace (shared_ptr ama, const Flags & flags, bool parseflags) : FESpace (ama, flags) { name="L2HighOrderFESpace(l2ho)"; type = "l2ho"; - + // defined flags DefineNumFlag("relorder"); DefineDefineFlag("l2ho"); @@ -221,25 +221,25 @@ if (parseflags) CheckFlags(flags); - var_order = 0; - + var_order = 0; + if (flags.NumFlagDefined("order")) order = int (flags.GetNumFlag("order",0)); - else + else { if(flags.NumFlagDefined("relorder")) { - order=0; - var_order = 1; + order=0; + var_order = 1; rel_order = int (flags.GetNumFlag("relorder",0)); } - else - order = 0; + else + order = 0; } - + if(flags.GetDefineFlag("variableorder") ) { - throw Exception ("Flag 'variableorder' for l2ho is obsolete. \n Either choose uniform order by -order= .. \n -relorder=.. for relative mesh order "); + throw Exception ("Flag 'variableorder' for l2ho is obsolete. \n Either choose uniform order by -order= .. \n -relorder=.. for relative mesh order "); } /* @@ -278,7 +278,7 @@ break; } } - if (dimension > 1) + if (dimension > 1) { evaluator[VOL] = make_shared (evaluator[VOL], dimension); // evaluator[VOL] = make_shared (evaluator[VOL], dimension); @@ -286,7 +286,7 @@ flux_evaluator[VOL] = make_shared (flux_evaluator[VOL], dimension); // evaluator[BND] = make_shared (evaluator[BND], dimension); /* - boundary_flux_evaluator = + boundary_flux_evaluator = make_shared (boundary_flux_evaluator, dimension); */ } @@ -323,7 +323,7 @@ additional_evaluators.Set ("hesse", make_shared>> ()); break; case 2: - additional_evaluators.Set ("hesse", make_shared>> ()); + additional_evaluators.Set ("hesse", make_shared>> ()); break; case 3: additional_evaluators.Set ("hesse", make_shared>> ()); @@ -332,7 +332,7 @@ ; } - needs_transform_vec = false; + needs_transform_vec = false; } L2HighOrderFESpace :: ~L2HighOrderFESpace () @@ -340,7 +340,7 @@ DocInfo L2HighOrderFESpace :: GetDocu () { - DocInfo docu = FESpace::GetDocu(); + DocInfo docu = FESpace::GetDocu(); docu.short_docu = "An L2-conforming finite element space."; docu.long_docu = R"raw_string(The L2 finite element space consists of element-wise polynomials, @@ -360,7 +360,7 @@ All dofs can be hidden. Then the basis functions don't show up in the global system. )raw_string"; - + docu.Arg("all_dofs_together") = "bool = True\n" " Change ordering of dofs. If this flag ist set,\n" " all dofs of an element are ordered successively.\n" @@ -375,8 +375,8 @@ return docu; } - - shared_ptr L2HighOrderFESpace :: + + shared_ptr L2HighOrderFESpace :: Create (shared_ptr ma, const Flags & flags) { int order = int(flags.GetNumFlag ("order", 0)); @@ -384,9 +384,9 @@ return make_shared (ma, flags); else return make_shared (ma, flags, true); - } + } + - void L2HighOrderFESpace :: Update() { FESpace::Update(); @@ -399,15 +399,15 @@ if (first_update) { - order_inner.SetSize(nel); - + order_inner.SetSize(nel); + order_inner = INT<3>(order); - - if(var_order) - for(int i = 0; i < nel; i++) + + if(var_order) + for(int i = 0; i < nel; i++) order_inner[i] = ma->GetElOrders(i)+INT<3>(rel_order); - - for(int i = 0; i < nel; i++) + + for(int i = 0; i < nel; i++) { ElementId ei(VOL,i); order_inner[i] = order_inner[i] + INT<3> (et_bonus_order[ma->GetElType(ei)]); @@ -415,7 +415,7 @@ if (!DefinedOn (ei)) order_inner[i] = 0; } - if(print) + if(print) *testout << " order_inner (l2ho) " << order_inner << endl; } @@ -427,8 +427,8 @@ if(low_order_space) prol->Update(*this); UpdateCouplingDofArray(); - } - + } + void L2HighOrderFESpace :: UpdateCouplingDofArray() { auto ct_local = hide_all_dofs ? HIDDEN_DOF : LOCAL_DOF; @@ -439,12 +439,12 @@ bool definedon = DefinedOn(ElementId(VOL,i)); auto r = GetElementDofs(i); ctofdof[r] = definedon ? ct_local : UNUSED_DOF; - + if (!all_dofs_together) ctofdof[i] = definedon ? ct_lowest_order : UNUSED_DOF; else if (r.Size() != 0) - ctofdof[r.First()] = definedon ? ct_lowest_order : UNUSED_DOF; + ctofdof[r.First()] = definedon ? ct_lowest_order : UNUSED_DOF; } } @@ -455,7 +455,7 @@ for (int i = 0; i < nel; i++) { first_element_dof[i] = ndof; - INT<3> pi = order_inner[i]; + INT<3> pi = order_inner[i]; switch (ma->GetElType(ElementId(VOL,i))) { case ET_SEGM: @@ -474,7 +474,7 @@ ndof += (pi[0]+1)*(pi[0]+2)*(pi[2]+1)/2; break; case ET_PYRAMID: - ndof += 5 + 8*(pi[0]-1) + 2*(pi[0]-1)*(pi[0]-2) + (pi[0]-1)*(pi[0]-1) + ndof += 5 + 8*(pi[0]-1) + 2*(pi[0]-1)*(pi[0]-2) + (pi[0]-1)*(pi[0]-1) + (pi[0]-1)*(pi[0]-2)*(2*pi[0]-3)/6; break; case ET_HEX: @@ -484,12 +484,12 @@ break; } if (!all_dofs_together) - ndof--; // subtract constant + ndof--; // subtract constant } first_element_dof[nel] = ndof; - - if(print) - *testout << " first_element dof (l2hofe) " << first_element_dof << endl; + + if(print) + *testout << " first_element dof (l2hofe) " << first_element_dof << endl; while (ma->GetNLevels() > ndlevel.Size()) ndlevel.Append (ndof); @@ -499,7 +499,7 @@ } - + FiniteElement & L2HighOrderFESpace :: GetFE (ElementId ei, Allocator & alloc) const { @@ -509,7 +509,7 @@ if (ei.IsVolume()) { int elnr = ei.Nr(); - + if (!DefinedOn (ngel)) { /* @@ -530,7 +530,7 @@ { return *new(alloc) ScalarDummyFE(); }); } - if (eltype == ET_TRIG && order_policy == CONSTANT_ORDER) + if (eltype == ET_TRIG && order_policy == CONSTANT_ORDER) return *CreateL2HighOrderFE (order, INT<3>(ngel.Vertices()), alloc); if (tensorproduct) @@ -542,7 +542,7 @@ if (eltype == ET_HEX) return * new (alloc) L2HighOrderFETP (order, ngel.Vertices(), alloc); } - if (eltype == ET_TET && order_policy == CONSTANT_ORDER) + if (eltype == ET_TET && order_policy == CONSTANT_ORDER) return *CreateL2HighOrderFE (order, INT<4>(ngel.Vertices()), alloc); /* @@ -565,12 +565,12 @@ case ET_TRIG: return T_GetFE (elnr, alloc); case ET_QUAD: return T_GetFE (elnr, alloc); - + case ET_TET: return T_GetFE (elnr, alloc); case ET_PRISM: return T_GetFE (elnr, alloc); case ET_PYRAMID: return T_GetFE (elnr, alloc); case ET_HEX: return T_GetFE (elnr, alloc); - + default: throw Exception ("illegal element in L2HoFeSpace::GetFE"); } @@ -591,15 +591,15 @@ /* switch (eltype) { - case ET_POINT: return *new (alloc) DummyFE; + case ET_POINT: return *new (alloc) DummyFE; case ET_SEGM: return *new (alloc) DummyFE; case ET_TRIG: return *new (alloc) DummyFE; case ET_QUAD: return *new (alloc) DummyFE; - + default: stringstream str; - str << "FESpace " << GetClassName() - << ", undefined surface eltype " << ma->GetElType(ei) + str << "FESpace " << GetClassName() + << ", undefined surface eltype " << ma->GetElType(ei) << ", order = " << order << endl; throw Exception (str.str()); } @@ -610,10 +610,10 @@ // const FiniteElement & L2HighOrderFESpace :: GetFE (int elnr, LocalHeap & lh) const // { // try - // { + // { // Ngs_Element ngel = ma->GetElement(elnr); // ELEMENT_TYPE eltype = ngel.GetType(); - + // if (!DefinedOn (ngel.GetIndex())) // { // switch (eltype) @@ -629,7 +629,7 @@ // } // } - // if (ngel.GetType() == ET_TRIG) + // if (ngel.GetType() == ET_TRIG) // { // int ia[3]; // FlatArray vnums(3, &ia[0]); @@ -637,7 +637,7 @@ // return *CreateL2HighOrderFE (order, vnums, lh); // } - // if (eltype == ET_TET) + // if (eltype == ET_TET) // return *CreateL2HighOrderFE (order, INT<4>(ngel.Vertices()), lh); // switch (eltype) @@ -646,25 +646,25 @@ // case ET_TRIG: return T_GetFE (elnr, lh); // case ET_QUAD: return T_GetFE (elnr, lh); - + // case ET_TET: return T_GetFE (elnr, lh); // case ET_PRISM: return T_GetFE (elnr, lh); // case ET_PYRAMID: return T_GetFE (elnr, lh); // case ET_HEX: return T_GetFE (elnr, lh); - + // default: // throw Exception ("illegal element in L2HoFeSpace::GetFE"); // } - // } + // } // catch (Exception & e) // { // e.Append ("in L2HoFESpace::GetElement"); // e.Append ("\n"); - // throw; + // throw; // } // } - + template FiniteElement & L2HighOrderFESpace :: T_GetFE (int elnr, Allocator & lh) const { @@ -683,31 +683,35 @@ const FiniteElement & L2HighOrderFESpace :: GetFacetFE (int fnr, LocalHeap & lh) const { - DGFiniteElement<2> * fe2d = NULL; + // DGFiniteElement<2> * fe2d = NULL; ArrayMem vnums; ma->GetFacetPNums (fnr, vnums); switch (vnums.Size()) { - case 1: return *new (lh) L2HighOrderFE (0); + case 1: return *new (lh) L2HighOrderFE (0); case 2: return *CreateL2HighOrderFE (order, vnums, lh); - case 3: fe2d = new (lh) L2HighOrderFE (); break; - case 4: fe2d = new (lh) L2HighOrderFE (); break; + case 3: return *CreateL2HighOrderFE (order, vnums, lh); + case 4: return *CreateL2HighOrderFE (order, vnums, lh); + // case 3: fe2d = new (lh) L2HighOrderFE (); break; + // case 4: fe2d = new (lh) L2HighOrderFE (); break; default: { stringstream str; - str << "L2HighOrderFESpace " << GetClassName() + str << "L2HighOrderFESpace " << GetClassName() << ", undefined facet-eltype" << endl; throw Exception (str.str()); } } - - fe2d-> SetVertexNumbers (vnums); + /* + fe2d-> SetVertexNumbers (vnums); fe2d-> SetOrder(order); - fe2d-> ComputeNDof(); + fe2d-> ComputeNDof(); return *fe2d; - } + */ + } + @@ -715,20 +719,19 @@ - // const FiniteElement & L2HighOrderFESpace :: GetSFE (int elnr, LocalHeap & lh) const // { // switch (ma->GetSElType(elnr)) // { - // case ET_POINT: return *new (lh) DummyFE; + // case ET_POINT: return *new (lh) DummyFE; // case ET_SEGM: return *new (lh) DummyFE; break; // case ET_TRIG: return *new (lh) DummyFE; break; // case ET_QUAD: return *new (lh) DummyFE; break; // default: // stringstream str; - // str << "FESpace " << GetClassName() - // << ", undefined surface eltype " << ma->GetSElType(elnr) + // str << "FESpace " << GetClassName() + // << ", undefined surface eltype " << ma->GetSElType(elnr) // << ", order = " << order << endl; // throw Exception (str.str()); // } @@ -751,7 +754,7 @@ if (!ei.IsVolume()) return; if (!DefinedOn (ei)) return; - + if (!all_dofs_together) dranges.Append (IntRange (ei.Nr(), ei.Nr()+1)); dranges.Append (GetElementDofs(ei.Nr())); @@ -772,7 +775,7 @@ dnums.Range(base, size) = eldofs; /* if (!all_dofs_together) - dnums.Append (elnr); // lowest_order + dnums.Append (elnr); // lowest_order dnums += GetElementDofs(elnr); */ } @@ -783,7 +786,7 @@ throw Exception("In L2HighOrderFESpace::SetOrder. Order policy is constant or node-type!"); else if (order_policy == OLDSTYLE_ORDER) order_policy = VARIABLE_ORDER; - + if (order < 0) order = 0; @@ -802,7 +805,7 @@ else throw Exception ("L2HighOrderFESpace::SetOrder requires NodeType of codimension 0!"); } - + int L2HighOrderFESpace :: GetOrder (NodeId ni) const { if (CoDimension(ni.GetType(), ma->GetDimension()) == 0) @@ -817,10 +820,10 @@ else if (ni.GetNr() < order_inner.Size()) return order_inner[ni.GetNr()][0]; } - + return 0; } - + FlatArray L2HighOrderFESpace :: GetDualShapeNodes (VorB vb) const { @@ -831,7 +834,7 @@ { return FlatArray (0, nullptr); } } - shared_ptr> L2HighOrderFESpace :: + shared_ptr> L2HighOrderFESpace :: CreateSmoothingBlocks (const Flags & precflags) const { int i, j, first; @@ -839,9 +842,9 @@ cnt = 0; for (i = 0; i < nel; i++) cnt[i] = first_element_dof[i+1]-first_element_dof[i]; - + Table table(cnt); - + for (i = 0; i < nel; i++) { first = first_element_dof[i]; @@ -852,23 +855,23 @@ } void L2HighOrderFESpace :: GetVertexDofNrs (int vnr, Array & dnums) const - { + { dnums.SetSize0(); } - + void L2HighOrderFESpace ::GetEdgeDofNrs (int ednr, Array & dnums) const - { - dnums.SetSize0(); + { + dnums.SetSize0(); } - + void L2HighOrderFESpace ::GetFaceDofNrs (int fanr, Array & dnums) const - { - dnums.SetSize0(); + { + dnums.SetSize0(); } - + void L2HighOrderFESpace ::GetInnerDofNrs (int elnr, Array & dnums) const - { - GetDofNrs (elnr, dnums); + { + GetDofNrs (elnr, dnums); } @@ -886,9 +889,9 @@ { return make_shared (dynamic_pointer_cast(const_cast(this)->shared_from_this()), - rho, defon, lh); + rho, defon, lh); } - + return FESpace::GetMassOperator(rho, defon, lh); } @@ -902,8 +905,8 @@ } */ - - + + void L2HighOrderFESpace :: SolveM (CoefficientFunction * rho, BaseVector & vec, Region * def, LocalHeap & lh) const { @@ -915,7 +918,7 @@ { auto & fel = static_cast(el.GetFE()); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el.Nr(), dnums); @@ -927,7 +930,7 @@ vec.SetIndirect (dnums, elx); return; } - + vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(fel.GetNDof(),dimension); @@ -954,7 +957,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -966,7 +969,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -976,15 +979,15 @@ vec.SetIndirect(dnums, elx); }); } - + void L2HighOrderFESpace :: ApplyM (CoefficientFunction * rho, BaseVector & vec, Region * def, LocalHeap & lh) const { static Timer t("ApplyM"); RegionTimer reg(t); static Timer tall("ApplyM - all"); - static Timer tel("ApplyM - el"); - static Timer ttrafo("ApplyM - trafo"); + static Timer tel("ApplyM - el"); + static Timer ttrafo("ApplyM - trafo"); static Timer tdofs("ApplyM - getdofs"); static Timer tgetx("ApplyM - getx"); static Timer tsety("ApplyM - sety"); @@ -996,22 +999,22 @@ throw Exception("L2HighOrderFESpace::ApplyM needs a scalar density"); auto fv = vec.FV(); - + IterateElements (*this, VOL, lh, [&rho, &vec, fv, def, this] (FESpace::Element el, LocalHeap & lh) { auto tid = TaskManager::GetThreadId(); - NgProfiler::StartThreadTimer(tall, tid); + NgProfiler::StartThreadTimer(tall, tid); NgProfiler::StartThreadTimer(tel, tid); - + auto & fel = static_cast(el.GetFE()); NgProfiler::StopThreadTimer(tel, tid); - NgProfiler::AddThreadFlops(tel, tid, 1); - NgProfiler::StartThreadTimer(ttrafo, tid); + NgProfiler::AddThreadFlops(tel, tid, 1); + NgProfiler::StartThreadTimer(ttrafo, tid); const ElementTransformation & trafo = el.GetTrafo(); NgProfiler::StopThreadTimer(ttrafo, tid); NgProfiler::StartThreadTimer(tdofs, tid); - + Array dnums(fel.GetNDof(), lh); auto dofrange = GetElementDofs(el.Nr()); FlatVector elx(fel.GetNDof()*dimension, lh); @@ -1025,12 +1028,12 @@ else { elx = 0.0; - GetDofNrs (el, dnums); + GetDofNrs (el, dnums); vec.SetIndirect(dnums, elx); } return; } - + if (!lindofs) { GetDofNrs (el, dnums); @@ -1038,15 +1041,15 @@ } else elx = fv.Range(dofrange); - + NgProfiler::StopThreadTimer(tdofs, tid); NgProfiler::StartThreadTimer(tgetx, tid); - + auto melx = elx.AsMatrix(fel.GetNDof(),dimension); - + NgProfiler::StopThreadTimer(tgetx, tid); - - NgProfiler::StartThreadTimer(tsetup, tid); + + NgProfiler::StartThreadTimer(tsetup, tid); FlatVector diag_mass(fel.GetNDof(), lh); fel.GetDiagMassMatrix (diag_mass); @@ -1054,16 +1057,16 @@ if (rho && !rho->ElementwiseConstant()) curved = true; NgProfiler::StopThreadTimer(tsetup, tid); - NgProfiler::StartThreadTimer(tcalc, tid); + NgProfiler::StartThreadTimer(tcalc, tid); if (!curved) { - NgProfiler::StartThreadTimer(tcalc1, tid); + NgProfiler::StartThreadTimer(tcalc1, tid); IntegrationRule ir(fel.ElementType(), 0); BaseMappedIntegrationRule & mir = trafo(ir, lh); double jac = mir[0].GetMeasure(); if (rho) jac *= rho->Evaluate(mir[0]); - - + + NgProfiler::StopThreadTimer(tcalc1, tid); NgProfiler::StartThreadTimer(tcalc2, tid); @@ -1073,7 +1076,7 @@ else for (size_t i = 0; i < melx.Height(); i++) melx.Row(i) *= jac*diag_mass(i); - NgProfiler::StopThreadTimer(tcalc2, tid); + NgProfiler::StopThreadTimer(tcalc2, tid); } else { @@ -1084,7 +1087,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -1096,7 +1099,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -1104,24 +1107,24 @@ melx.Row(i) /= diag_mass(i); } NgProfiler::StopThreadTimer(tcalc, tid); - + NgProfiler::StartThreadTimer(tsety, tid); - + if (!lindofs) vec.SetIndirect(dnums, elx); else fv.Range(dofrange) = elx; - + NgProfiler::StopThreadTimer(tsety, tid); - NgProfiler::StopThreadTimer(tall, tid); + NgProfiler::StopThreadTimer(tall, tid); }); } Matrix<> GetTraceMatrix (const FiniteElement & fel) { - auto * dgfel2 = dynamic_cast*> (&fel); - if (dgfel2) + // auto * dgfel2 = dynamic_cast*> (&fel); + if (auto dgfel2 = dynamic_cast*> (&fel)) { int order = fel.Order(); Matrix<> trace(3*(order+1), fel.GetNDof()); @@ -1129,8 +1132,8 @@ dgfel2->CalcTraceMatrix(j, trace.Rows(j*(order+1), (j+1)*(order+1))); return trace; } - auto * dgfel3 = dynamic_cast*> (&fel); - if (dgfel3) + // auto * dgfel3 = dynamic_cast*> (&fel); + if (auto dgfel3 = dynamic_cast*> (&fel)) { int order = fel.Order(); int nd2d = (order+1)*(order+2)/2; @@ -1151,12 +1154,12 @@ ma->IterateElements (VOL, lh, [&] (auto el, LocalHeap & llh) { - classnr[el.Nr()] = + classnr[el.Nr()] = SwitchET (el.GetType(), [el] (auto et) { return ET_trait::GetClassNr(el.Vertices()); }); }); - + TableCreator creator; for ( ; !creator.Done(); creator++) for (auto i : Range(classnr)) @@ -1164,17 +1167,17 @@ Table table = creator.MoveTable(); shared_ptr sum; - + // size_t ne = ma->GetNE(); - + for (auto elclass_inds : table) { if (elclass_inds.Size() == 0) continue; - + ElementId ei(VOL,elclass_inds[0]); auto & felx = GetFE (ei, lh); //auto & trafo = GetMeshAccess()->GetTrafo(ei, lh); - + Matrix<> trace_op_x = GetTraceMatrix (felx); @@ -1203,10 +1206,10 @@ return sum; } - + void L2HighOrderFESpace :: GetTrace (const FESpace & tracespace, const BaseVector & in, BaseVector & out, bool avg, - LocalHeap & lh) const + LocalHeap & lh) const { static Timer t("GetTrace"); RegionTimer reg(t); @@ -1215,12 +1218,12 @@ ma->IterateElements (VOL, lh, [&] (auto el, LocalHeap & llh) { - classnr[el.Nr()] = + classnr[el.Nr()] = SwitchET (el.GetType(), [el] (auto et) { return ET_trait::GetClassNr(el.Vertices()); }); }); - + TableCreator creator; for ( ; !creator.Done(); creator++) for (auto i : Range(classnr)) @@ -1229,17 +1232,17 @@ // size_t ne = ma->GetNE(); - + for (auto elclass_inds : table) { if (elclass_inds.Size() == 0) continue; - + ElementId ei(VOL,elclass_inds[0]); auto & felx = GetFE (ei, lh); // auto & trafo = GetMeshAccess()->GetTrafo(ei, lh); - + Matrix<> trace_op_x = GetTraceMatrix (felx); - + Matrix<> temp_x(elclass_inds.Size(), trace_op_x.Width()); Matrix<> temp_trace(elclass_inds.Size(), trace_op_x.Height()); @@ -1248,7 +1251,7 @@ [&] (IntRange myrange) { Array dofs; - + // int tid = TaskManager::GetThreadId(); { for (auto i : myrange) @@ -1257,13 +1260,13 @@ in.GetIndirect(dofs, temp_x.Row(i)); } } - + { - temp_trace.Rows(myrange) = 0; + temp_trace.Rows(myrange) = 0; // RegionTracer t(tid, tmulttracex, 0, temp_x.Width()); AddABt(temp_x.Rows(myrange), trace_op_x, temp_trace.Rows(myrange)); } - + { for (auto i : myrange) { @@ -1274,7 +1277,7 @@ }); } } - + void L2HighOrderFESpace :: GetTraceTrans (const FESpace & tracespace, const BaseVector & in, BaseVector & out, bool avg, LocalHeap & lh) const @@ -1286,12 +1289,12 @@ ma->IterateElements (VOL, lh, [&] (auto el, LocalHeap & llh) { - classnr[el.Nr()] = + classnr[el.Nr()] = SwitchET (el.GetType(), [el] (auto et) { return ET_trait::GetClassNr(el.Vertices()); }); }); - + TableCreator creator; for ( ; !creator.Done(); creator++) for (auto i : Range(classnr)) @@ -1300,17 +1303,17 @@ // size_t ne = ma->GetNE(); - + for (auto elclass_inds : table) { if (elclass_inds.Size() == 0) continue; - + ElementId ei(VOL,elclass_inds[0]); auto & felx = GetFE (ei, lh); // auto & trafo = GetMeshAccess()->GetTrafo(ei, lh); - + Matrix<> trace_op_x = GetTraceMatrix (felx); - + Matrix<> temp_x(elclass_inds.Size(), trace_op_x.Width()); Matrix<> temp_trace(elclass_inds.Size(), trace_op_x.Height()); @@ -1319,7 +1322,7 @@ [&] (IntRange myrange) { Array dofs; - + // int tid = TaskManager::GetThreadId(); { for (auto i : myrange) @@ -1328,13 +1331,13 @@ in.GetIndirect(dofs, temp_trace.Row(i)); } } - + { - // temp_trace.Rows(myrange) = 0; + // temp_trace.Rows(myrange) = 0; // AddABt(temp_x.Rows(myrange), trace_op_x, temp_trace.Rows(myrange)); temp_x.Rows(myrange) = temp_trace.Rows(myrange) * trace_op_x; } - + { for (auto i : myrange) { @@ -1362,7 +1365,7 @@ static void GenerateMatrix (const AFEL & fel, const MIP & mip, MAT & mat, LocalHeap & lh) { - mat = Trans (mip.GetJacobianInverse ()) * + mat = Trans (mip.GetJacobianInverse ()) * Trans (static_cast(fel).GetDShape(mip.IP(),lh)); } @@ -1370,17 +1373,17 @@ const SIMD_BaseMappedIntegrationRule & mir, BareSliceMatrix> mat) { - static_cast(fel).CalcMappedDShape (mir, mat); + static_cast(fel).CalcMappedDShape (mir, mat); } - using DiffOp >::ApplySIMDIR; + using DiffOp >::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & mir, BareSliceVector x, BareSliceMatrix> y) { static_cast(fel).EvaluateGrad (mir, x, y); } - using DiffOp >::AddTransSIMDIR; + using DiffOp >::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & fel, const SIMD_BaseMappedIntegrationRule & mir, BareSliceMatrix> y, BareSliceVector x) { @@ -1391,19 +1394,19 @@ }; - L2SurfaceHighOrderFESpace :: + L2SurfaceHighOrderFESpace :: L2SurfaceHighOrderFESpace (shared_ptr ama, const Flags & flags, bool parseflags) : FESpace (ama, flags) { type = "l2surf"; name="L2SurfaceHighOrderFESpace(l2surf)"; - // defined flags + // defined flags DefineDefineFlag("l2surf"); if(parseflags) CheckFlags(flags); - + if(flags.NumFlagDefined("relorder")) - throw Exception("Variable order not implemented for L2SurfaceHighOrderFESpace"); + throw Exception("Variable order not implemented for L2SurfaceHighOrderFESpace"); lowest_order_wb = flags.GetDefineFlagX ("lowest_order_wb").IsTrue(); @@ -1417,7 +1420,7 @@ { if (ma->GetDimension() == 2) { - integrator[BND] = + integrator[BND] = make_shared>(make_shared(1)); evaluator[BND] = make_shared>>(); evaluator[VOL] = make_shared>>(); // for dimension @@ -1427,7 +1430,7 @@ } else { - integrator[BND] = + integrator[BND] = make_shared> (make_shared(1)); evaluator[BND] = make_shared>>(); flux_evaluator[VOL] = make_shared>>(); // to avoid exception "grad does not exist" @@ -1440,16 +1443,16 @@ { if (ma->GetDimension() == 2) { - evaluator[VOL] = make_shared>>(); // for dimension + evaluator[VOL] = make_shared>>(); // for dimension evaluator[BND] = make_shared>>(); } if (ma->GetDimension() == 3) { - evaluator[VOL] = make_shared>>(); // for dimension + evaluator[VOL] = make_shared>>(); // for dimension evaluator[BND] = make_shared>>(); } } - + if (dimension > 1) { integrator[BND] = make_shared (integrator[BND], dimension); @@ -1458,7 +1461,7 @@ if (evaluator[vb]) evaluator[vb] = make_shared (evaluator[vb], dimension); if (flux_evaluator[vb]) - flux_evaluator[vb] = make_shared (flux_evaluator[vb], dimension); + flux_evaluator[vb] = make_shared (flux_evaluator[vb], dimension); } } @@ -1474,14 +1477,14 @@ { static VorB nodes[] = { VOL }; if (vb == BND) - return FlatArray (1, &nodes[0]); + return FlatArray (1, &nodes[0]); else - return FlatArray (0, nullptr); + return FlatArray (0, nullptr); } DocInfo L2SurfaceHighOrderFESpace :: GetDocu () { - DocInfo docu = FESpace::GetDocu(); + DocInfo docu = FESpace::GetDocu(); docu.short_docu = "An L2-conforming finite element space."; docu.long_docu = R"raw_string(The L2 finite element space on surfaces consists of element-wise polynomials, @@ -1507,27 +1510,27 @@ } /* - shared_ptr L2SurfaceHighOrderFESpace :: + shared_ptr L2SurfaceHighOrderFESpace :: Create (shared_ptr ma, const Flags & flags) { return make_shared (ma, flags, true); } */ - + void L2SurfaceHighOrderFESpace :: Update() { size_t nel = ma->GetNE(BND); bool first_update = GetTimeStamp() < ma->GetTimeStamp(); if (first_update) timestamp = NGS_Object::GetNextTimeStamp(); - - + + if (first_update) { order_inner.SetSize(nel); order_inner = INT<3>(order); - for (size_t i = 0; i < nel; i++) + for (size_t i = 0; i < nel; i++) { ElementId ei(BND,i); order_inner[i] = order_inner[i] + INT<3> (et_bonus_order[ma->GetElType(ei)]); @@ -1535,11 +1538,11 @@ if (!DefinedOn (ei)) order_inner[i] = 0; } - - if(print) + + if(print) *testout << " order_inner (l2surf) " << order_inner << endl; } - + size_t ndof = 0; first_element_dof.SetSize(nel+1); for (int i = 0; i < nel; i++) @@ -1563,9 +1566,9 @@ } first_element_dof[nel] = ndof; SetNDof(ndof); - if(print) + if(print) *testout << " first_element dof (l2surf) " << first_element_dof << endl; - + UpdateCouplingDofArray(); } @@ -1573,13 +1576,13 @@ { ctofdof.SetSize(ndof); ctofdof = UNUSED_DOF; - + for (auto i : Range(ma->GetNSE())) if (DefinedOn({BND,i})) { auto r = GetElementDofs(i); ctofdof[r] = (discontinuous || lowest_order_wb) ? LOCAL_DOF : WIREBASKET_DOF; - + if (lowest_order_wb && r.Size() != 0) ctofdof[r.First()] = WIREBASKET_DOF; } @@ -1592,7 +1595,7 @@ throw Exception("In L2SurfaceHighOrderFESpace::SetOrder. Order policy is constant or node-type!"); else if (order_policy == OLDSTYLE_ORDER) order_policy = VARIABLE_ORDER; - + if (order < 0) order = 0; @@ -1611,7 +1614,7 @@ else throw Exception ("L2SurfaceHighOrderFESpace::SetOrder requires NodeType of codimension 1!"); } - + int L2SurfaceHighOrderFESpace ::GetOrder (NodeId ni) const { if (CoDimension(ni.GetType(), ma->GetDimension()) == 1) @@ -1626,10 +1629,10 @@ else if (ni.GetNr() < order_inner.Size()) return order_inner[ni.GetNr()][0]; } - + return 0; } - + FiniteElement & L2SurfaceHighOrderFESpace :: GetFE (ElementId ei, Allocator & lh) const { @@ -1637,8 +1640,8 @@ { if (ma->GetDimension() == 2) { - DGFiniteElement<1> * fe1d = 0; - + DGFiniteElement * fe1d = 0; + Ngs_Element ngel = ma->GetElement<1,BND> (ei.Nr()); switch (ngel.GetType()) @@ -1650,30 +1653,33 @@ fe1d -> SetVertexNumbers (ngel.vertices); fe1d -> SetOrder (order_inner[ei.Nr()]); - fe1d -> ComputeNDof(); + fe1d -> ComputeNDof(); return *fe1d; } else { - DGFiniteElement<2> * fe2d = 0; - - Ngs_Element ngel = ma->GetElement<2,BND> (ei.Nr()); - - switch (ngel.GetType()) - { - case ET_TRIG: fe2d = new (lh) L2HighOrderFE (); break; - case ET_QUAD: fe2d = new (lh) L2HighOrderFE (); break; - default: - ; - } - - fe2d -> SetVertexNumbers (ngel.vertices); - fe2d -> SetOrder (order_inner[ei.Nr()]); - fe2d -> ComputeNDof(); - return *fe2d; + Ngs_Element ngel = ma->GetElement<2,BND> (ei.Nr()); + // SwitchET generates an "internal compiler error" on MSVC 2019 14.28.29910 + if(ngel.GetType()==ET_TRIG) + { + auto fe2d = new (lh) L2HighOrderFE (); + fe2d -> SetVertexNumbers (ngel.vertices); + fe2d -> SetOrder (order_inner[ei.Nr()]); + fe2d -> ComputeNDof(); + return *fe2d; + } + else if(ngel.GetType()==ET_QUAD) + { + auto fe2d = new (lh) L2HighOrderFE (); + fe2d -> SetVertexNumbers (ngel.vertices); + fe2d -> SetOrder (order_inner[ei.Nr()]); + fe2d -> ComputeNDof(); + return *fe2d; + } + throw Exception("Unknown eltype for L2SurfaceHighOrderFESpace " + ToString(ngel.GetType())); } } - + else return * SwitchET (ma->GetElement(ei).GetType(), @@ -1681,7 +1687,7 @@ { return new (lh) ScalarDummyFE(); }); - + } /* @@ -1690,8 +1696,8 @@ return ndof; } */ - - void L2SurfaceHighOrderFESpace :: + + void L2SurfaceHighOrderFESpace :: GetDofNrs (ElementId ei, Array & dnums) const { dnums.SetSize0(); @@ -1709,14 +1715,14 @@ shared_ptr> dofs; Matrix<> elbmat; Vector eldiag; - + public: /// ApplyL2Mass (shared_ptr afes, shared_ptr arho, bool ainverse, shared_ptr adefinedon, - Matrix aelbmat, Vector aeldiag, Vector arho_jac, + Matrix aelbmat, Vector aeldiag, Vector arho_jac, shared_ptr> adofs, LocalHeap & alh) : ApplyMass (afes, arho, ainverse, adefinedon, alh), @@ -1744,7 +1750,7 @@ for (size_t i = 0; i < rho_jac.Size(); i++) inv_rhojac(i) = 1.0/rho_jac(i); return make_shared (fes, rho, !inverse, definedon, - scaled_elbmat, eldiag, inv_rhojac, dofs, + scaled_elbmat, eldiag, inv_rhojac, dofs, lh); } @@ -1753,7 +1759,7 @@ prod = 0.0; MultAdd (1, v, prod); } - + void MultAdd (double val, const BaseVector & v, BaseVector & prod) const override { auto fx = v.FV(); @@ -1764,12 +1770,12 @@ constexpr size_t BS = 128; Matrix<> hx(BS, elbmat.Width()); Matrix<> tmp(BS, elbmat.Height()); - + for (size_t bi = r.First(); bi < r.Next(); bi+= BS) { size_t li = min2(bi+BS, r.Next()); size_t num = li-bi; - + for (size_t i = 0; i < num; i++) hx.Row(i) = fx( (*dofs)[bi+i]); @@ -1778,26 +1784,26 @@ size_t base = r.First()*tmp.Width(); for (size_t i : Range(num*tmp.Width())) tmp(i) *= rho_jac(base+i); - + hx.Rows(0, num) = tmp.Rows(0,num) * elbmat; for (size_t i = 0; i < num; i++) fy( (*dofs)[bi+i]) += val * hx.Row(i); } }); } - - + + }; - + shared_ptr L2SurfaceHighOrderFESpace :: GetMassOperator (shared_ptr rho, shared_ptr defon, - LocalHeap & lh) const + LocalHeap & lh) const { // return FESpace::GetMassOperator(rho, defon, lh); - + auto dofs = make_shared> (CreateDofTable(BND)); Matrix<> bmat; Vector rho_jac; @@ -1810,13 +1816,13 @@ { auto & fel = static_cast(el.GetFE()); const ElementTransformation & trafo = el.GetTrafo(); - + IntegrationRule ir1(fel.ElementType(), 2*fel.Order()); Array verts { el.Vertices() }; Facet2SurfaceElementTrafo f2s(fel.ElementType(), verts); auto & ir = f2s(ir1, lh); auto & mir = trafo(ir, lh); - + FlatMatrix<> rhovals(ir.Size(), 1, lh); if (rho) rho->Evaluate (mir, rhovals); @@ -1828,7 +1834,7 @@ else for (size_t i = 0; i < ir.Size(); i++) rhovals.Row(i) /= mir[i].GetMeasure(); - + Matrix<> shapes(fel.GetNDof(), ir.Size()); bmat.SetSize(ir.Size(), fel.GetNDof()); @@ -1837,7 +1843,7 @@ { firsttime = false; bmat = Trans(shapes); - + eldiag.SetSize(fel.GetNDof()); fel.GetDiagMassMatrix (eldiag); @@ -1854,7 +1860,7 @@ } rho_jac.Range ( rhovals.Height() * IntRange(el.Nr(), el.Nr()+1) ) = rhovals.Col(0); } - + // cout << "doftable = " << doftable << endl; // cout << "eldiag = " << eldiag << endl; @@ -1863,10 +1869,10 @@ return make_shared (dynamic_pointer_cast(const_cast< L2SurfaceHighOrderFESpace*>(this)->shared_from_this()), rho, false, defon, bmat, eldiag, rho_jac, dofs, - lh); + lh); } - - + + void L2SurfaceHighOrderFESpace :: SolveM (CoefficientFunction * rho, BaseVector & vec, Region * def, LocalHeap & lh) const { @@ -1879,7 +1885,7 @@ auto & fel = static_cast(el.GetFE()); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (ElementId(BND,el.Nr()), dnums); @@ -1890,7 +1896,7 @@ vec.SetIndirect (dnums, elx); return; } - + vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(fel.GetNDof(),dimension); @@ -1917,7 +1923,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -1929,7 +1935,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -1948,14 +1954,14 @@ throw Exception("L2HighOrderFESpace::ApplyM needs a scalar density"); // auto fv = vec.FV(); - + IterateElements (*this, BND, lh, [&rho, &vec, /* fv, */ def, this] (FESpace::Element el, LocalHeap & lh) { // auto tid = TaskManager::GetThreadId(); auto & fel = static_cast(el.GetFE()); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); // auto dofrange = GetElementDofs(el.Nr()); FlatVector elx(fel.GetNDof()*dimension, lh); @@ -1969,12 +1975,12 @@ else {*/ elx = 0.0; - GetDofNrs (el, dnums); + GetDofNrs (el, dnums); vec.SetIndirect(dnums, elx); //} return; } - + /*if (!lindofs) {*/ GetDofNrs (el, dnums); @@ -1983,9 +1989,9 @@ else elx = fv.Range(dofrange); */ - + auto melx = elx.AsMatrix(fel.GetNDof(),dimension); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; if (!curved) @@ -1996,8 +2002,8 @@ BaseMappedIntegrationRule & mir = trafo(ir, lh); double jac = mir[0].GetMeasure(); if (rho) jac *= rho->Evaluate(mir[0]); - - + + if (dimension == 1) for (size_t i = 0; i < elx.Size(); i++) @@ -2013,7 +2019,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int comp = 0; comp < dimension; comp++) { fel.Evaluate (ir, melx.Col(comp), pntvals); @@ -2023,22 +2029,22 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() * mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } } - + //if (!lindofs) vec.SetIndirect(dnums, elx); //else // fv.Range(dofrange) = elx; - + }); } - shared_ptr> L2SurfaceHighOrderFESpace :: + shared_ptr> L2SurfaceHighOrderFESpace :: // CreateSmoothingBlocks ( int type) const - CreateSmoothingBlocks (const Flags & precflags) const + CreateSmoothingBlocks (const Flags & precflags) const { int i, j, first; size_t nel = ma->GetNE(BND); @@ -2046,9 +2052,9 @@ cnt = 0; for (i = 0; i < nel; i++) cnt[i] = first_element_dof[i+1]-first_element_dof[i]; - + Table table(cnt); - + for (i = 0; i < nel; i++) { first = first_element_dof[i]; @@ -2061,13 +2067,13 @@ void L2SurfaceHighOrderFESpace :: GetVertexDofNrs (int vnr, Array & dnums) const { dnums.SetSize0(); return; } - + void L2SurfaceHighOrderFESpace ::GetEdgeDofNrs (int ednr, Array & dnums) const { dnums.SetSize0(); return; } - + void L2SurfaceHighOrderFESpace ::GetFaceDofNrs (int fanr, Array & dnums) const { GetDofNrs ( fanr, dnums ); return; } - + void L2SurfaceHighOrderFESpace ::GetInnerDofNrs (int elnr, Array & dnums) const { GetDofNrs ( elnr, dnums ); return; } @@ -2095,11 +2101,11 @@ { Vec hv = mat.Col(i); mat.Col(i) = trafo * hv; - } + } } static void GenerateMatrixSIMDIR (const FiniteElement & bfel, - const SIMD_BaseMappedIntegrationRule & bmir, + const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> mat) { auto & mir = static_cast&> (bmir); @@ -2109,7 +2115,7 @@ size_t ndofi = feli.GetNDof(); auto scalmat = mat.Rows( (DIM_SPC*DIM_ELEMENT-1)*ndofi, DIM_SPC*DIM_ELEMENT*ndofi); feli.CalcShape (mir.IR(), scalmat); - + for (auto i_ip : Range(mir)) { auto & mip = mir[i_ip]; @@ -2124,28 +2130,28 @@ col.Range(base, base+DIM_SPACE) = scalcol(i) * trafo.Col(k); } } - - using DiffOp>::ApplySIMDIR; + + using DiffOp>::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector x, BareSliceMatrix> y) { // cout << "apply simdir" << endl; // static Timer t("DiffOpIdVectorL2Piola::ApplySIMDIR"); // RegionTracer rt(TaskManager::GetThreadId(), t); - + auto & mir = static_cast&> (bmir); auto & fel = static_cast (bfel); auto & feli = static_cast (fel[0]); size_t ndofi = feli.GetNDof(); - + STACK_ARRAY(double, memx, DIM_ELEMENT*ndofi); FlatMatrixFixWidth matx(ndofi, &memx[0]); for (size_t k = 0; k < DIM_ELEMENT; k++) matx.Col(k) = x.Range(k*ndofi, (k+1)*ndofi); { - // RegionTracer rt(TaskManager::GetThreadId(), t); + // RegionTracer rt(TaskManager::GetThreadId(), t); feli.Evaluate(mir.IR(), matx, y); } for (size_t i = 0; i < mir.Size(); i++) @@ -2155,22 +2161,22 @@ val *= 1/mir[i].GetJacobiDet(); y.Col(i).Range(0,DIM_SPACE) = jac * val; } - } - - - using DiffOp>::AddTransSIMDIR; + } + + + using DiffOp>::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> y, BareSliceVector x) { //static Timer t("DiffpIdVectorL2Piola::AddTransSIMD"); // static Timer tc("DiffpIdVectorL2Piola::AddTransSIMD calc"); - // RegionTracer rt(TaskManager::GetThreadId(), t); + // RegionTracer rt(TaskManager::GetThreadId(), t); auto & mir = static_cast&> (bmir); auto & fel = static_cast (bfel); auto & feli = static_cast (fel[0]); size_t ndofi = feli.GetNDof(); - + STACK_ARRAY(SIMD, mempt, mir.Size()*DIM_SPACE); FlatMatrix> hy(DIM_SPACE, mir.Size(), &mempt[0]); @@ -2181,7 +2187,7 @@ val *= 1/mir[i].GetJacobiDet(); hy.Col(i).Range(0,DIM_SPACE) = Trans(jac) * val; } - + STACK_ARRAY(double, memx, DIM_ELEMENT*ndofi); FlatMatrixFixWidth matx(ndofi, &memx[0]); @@ -2192,12 +2198,12 @@ for (size_t k = 0; k < DIM_ELEMENT; k++) x.Range(k*ndofi, (k+1)*ndofi) = matx.Col(k); - } + } - -/* - using DiffOp>::ApplySIMDIR; +/* + + using DiffOp>::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & mir, BareSliceVector x, BareSliceMatrix> y) { @@ -2209,7 +2215,7 @@ } } - using DiffOp>::AddTransSIMDIR; + using DiffOp>::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & mir, BareSliceMatrix> y, BareSliceVector x) { @@ -2219,7 +2225,7 @@ auto & feli = static_cast (fel[i]); feli.AddTrans (mir.IR(), y.Row(i), x.Range(fel.GetRange(i))); } - } + } */ }; @@ -2237,14 +2243,14 @@ enum { DIFFORDER = 1 }; static string Name() { return "div"; } - + template static void GenerateMatrix (const FEL & fel, const MIP & mip, MAT & mat, LocalHeap & lh) { auto & bfel = static_cast (fel); auto & feli = static_cast (bfel[0]); - + int ndofi = feli.GetNDof(); FlatMatrix<> grad (ndofi, DIM_SPC, lh); feli.CalcDShape(mip.IP(), grad); @@ -2256,7 +2262,7 @@ static void GenerateMatrixSIMDIR (const FiniteElement & bfel, - const SIMD_BaseMappedIntegrationRule & bmir, + const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> mat) { auto & mir = static_cast&> (bmir); @@ -2272,7 +2278,7 @@ { auto col = mat.Col(i_ip); auto & mip = mir[i_ip]; - + for (size_t i = 0; i < ndofi; i++) for (size_t k = 0; k < DIM_SPC; k++) tmp(i, k) = col(i*DIM_SPC+k); @@ -2285,10 +2291,10 @@ } } - + /* - using DiffOp::ApplySIMDIR; + using DiffOp::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector x, BareSliceMatrix> y) { @@ -2311,10 +2317,10 @@ Vec<3,SIMD> hv = Cross(gi, tek); y.Col(i).AddSize(3) += hv; } - } - } - - using DiffOp::AddTransSIMDIR; + } + } + + using DiffOp::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> y, BareSliceVector x) { @@ -2335,13 +2341,13 @@ Vec<3,SIMD> hv = Cross(cy, tek); grad.Col(i) = -hv; } - + feli.AddGradTrans (mir, grad, x.Range(k*ndofi, (k+1)*ndofi)); - } - } + } + } */ }; - + template @@ -2357,14 +2363,14 @@ static string Name() { return "grad"; } static Array GetDimensions() { return Array ( { DIM_SPC, DIM_SPC } ); }; - + template static void GenerateMatrix (const FEL & fel, const MIP & mip, MAT & mat, LocalHeap & lh) { auto & bfel = static_cast (fel); auto & feli = static_cast (bfel[0]); - + int ndofi = feli.GetNDof(); FlatMatrix<> grad (ndofi, DIM_SPC, lh); feli.CalcMappedDShape(mip, grad); @@ -2379,7 +2385,7 @@ FlatVector<> val (ndofi, lh); feli.CalcShape(mip.IP(), val); - // 1/J ( H - (F^{-T}:H) F ) + // 1/J ( H - (F^{-T}:H) F ) if (!mip.GetTransformation().IsCurvedElement()) return; @@ -2392,13 +2398,13 @@ Vec> invjac_hesse; for (int i = 0; i < DIM_SPC; i++) invjac_hesse(i) = Trans(inv) * hesse(i); - + Vec inv_hesse = 0.0; for (int i = 0; i < DIM_SPC; i++) for (int j = 0; j < DIM_SPC; j++) inv_hesse(i) += invjac_hesse(j)(j,i); inv_hesse = Trans(inv) * inv_hesse; - + for (int i = 0; i < DIM_SPC; i++) for (int j = 0; j < DIM_SPC; j++) for (int k = 0; k < DIM_SPC; k++) @@ -2408,7 +2414,7 @@ /* static void GenerateMatrixSIMDIR (const FiniteElement & bfel, - const SIMD_BaseMappedIntegrationRule & bmir, + const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> mat) { auto & mir = static_cast&> (bmir); @@ -2424,7 +2430,7 @@ { auto col = mat.Col(i_ip); auto & mip = mir[i_ip]; - + for (size_t i = 0; i < ndofi; i++) for (size_t k = 0; k < DIM_SPC; k++) tmp(i, k) = col(i*DIM_SPC+k); @@ -2438,35 +2444,41 @@ } */ - - /* - using DiffOp::ApplySIMDIR; + using DiffOp::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector x, BareSliceMatrix> y) { - auto & mir = static_cast&> (bmir); + auto & mir = static_cast&> (bmir); auto & fel = static_cast (bfel); auto & feli = static_cast (fel[0]); size_t ndofi = feli.GetNDof(); - y.AddSize(3,mir.Size()) = SIMD(0.0); - STACK_ARRAY(SIMD, mem, 3*mir.Size()); - FlatMatrix> grad(3, mir.Size(), &mem[0]); - for (size_t k = 0; k < 3; k++) - { - feli.EvaluateGrad (mir, x.Range(k*ndofi, (k+1)*ndofi), grad); - for (size_t i = 0; i < mir.Size(); i++) - { - auto trafo = Trans(mir[i].GetJacobianInverse()); - Vec<3,SIMD> gi = grad.Col(i); - Vec<3,SIMD> tek = trafo.Col(k); - Vec<3,SIMD> hv = Cross(gi, tek); - y.Col(i).AddSize(3) += hv; - } - } - } - */ - using DiffOp::AddTransSIMDIR; + STACK_ARRAY(SIMD, mem, DIM_SPC*DIM_SPC*mir.Size()); + FlatMatrix> grad(DIM_SPC*DIM_SPC, mir.Size(), &mem[0]); + grad = SIMD(0.0); + + for (size_t k = 0; k < DIM_SPC; k++) + feli.EvaluateGrad (mir, x.Range(k*ndofi, (k+1)*ndofi), grad.Rows(k*DIM_SPC, (k+1)*DIM_SPC)); + + for (size_t i = 0; i < mir.Size(); i++) + for (int j = 0; j < (DIM_SPC*DIM_SPC); j++) + y(j, i) = SIMD(0.0); + + for (size_t i = 0; i < mir.Size(); i++) { + auto trans = 1/(mir[i].GetJacobiDet())*mir[i].GetJacobian(); + for (int j = 0; j < DIM_SPC; j++) + for (int k = 0; k < DIM_SPC; k++) + for (int l = 0; l < DIM_SPC; l++) + y(j*DIM_SPC+k, i) += trans(j,l)*grad(l*DIM_SPC+k, i); + } + + if (!mir.GetTransformation().IsCurvedElement()) + return; + + // For curved elements part is still missing + } + + using DiffOp::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> y, BareSliceVector x) { @@ -2482,12 +2494,12 @@ for (size_t i = 0; i < mir.Size(); i++) { auto trans = 1/(mir[i].GetJacobiDet())*mir[i].GetJacobian(); - for (int j = 0; j < DIM_SPC; j++) + for (int j = 0; j < DIM_SPC; j++) for (int k = 0; k < DIM_SPC; k++) for (int l = 0; l < DIM_SPC; l++) grad(j*DIM_SPC+k, i) += trans(l,j)*y(k*DIM_SPC+l, i); } - + for (size_t k = 0; k < DIM_SPC; k++) feli.AddGradTrans (mir, grad.Rows(k*DIM_SPC, (k+1)*DIM_SPC), x.Range(k*ndofi, (k+1)*ndofi)); @@ -2505,17 +2517,17 @@ auto invJ = 1/mir[ip].GetJacobiDet(); Vec>> hesse; mir[ip].CalcHesse(hesse); - + Vec>> invjac_hesse; for (int i = 0; i < DIM_SPC; i++) invjac_hesse(i) = Trans(inv) * hesse(i); - + Vec> inv_hesse = SIMD(0.0); for (int i = 0; i < DIM_SPC; i++) for (int j = 0; j < DIM_SPC; j++) inv_hesse(i) += invjac_hesse(j)(j,i); inv_hesse = Trans(inv) * inv_hesse; - + for (int i = 0; i < DIM_SPC; i++) for (int j = 0; j < DIM_SPC; j++) for (int k = 0; k < DIM_SPC; k++) @@ -2526,13 +2538,13 @@ for (size_t k = 0; k < DIM_SPC; k++) feli.AddTrans (mir.IR(), val.Row(k), x.Range(k*ndofi, (k+1)*ndofi)); - } + } }; - + template class DiffOpIdVectorL2Covariant : public DiffOp > { @@ -2557,17 +2569,17 @@ { Vec hv = mat.Col(i); mat.Col(i) = Trans(trafo) * hv; - } + } } - + static void GenerateMatrixSIMDIR (const FiniteElement & bfel, - const SIMD_BaseMappedIntegrationRule & mir, + const SIMD_BaseMappedIntegrationRule & mir, BareSliceMatrix> mat) { auto & fel = static_cast (bfel); auto & feli = static_cast (fel[0]); size_t ndofi = feli.GetNDof(); - + STACK_ARRAY(SIMD, mem, ndofi*mir.Size()); FlatMatrix> shapes(ndofi, mir.Size(), &mem[0]); feli.CalcShape (mir.IR(), shapes); @@ -2577,7 +2589,7 @@ auto col = mat.Col(i_ip); auto & mip = static_cast>&>(mir[i_ip]); auto trafo = mip.GetJacobianInverse(); - + for (int k = 0; k < DIM_SPACE; k++) { size_t offset = DIM_SPACE*k*ndofi; @@ -2588,7 +2600,7 @@ } - using DiffOp>::ApplySIMDIR; + using DiffOp>::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector x, BareSliceMatrix> y) { @@ -2596,12 +2608,12 @@ auto & fel = static_cast (bfel); auto & feli = static_cast (fel[0]); size_t ndofi = feli.GetNDof(); - + STACK_ARRAY(double, memx, DIM_SPACE*ndofi); FlatMatrix matx(ndofi, DIM_SPACE, &memx[0]); for (size_t k = 0; k < DIM_SPACE; k++) matx.Col(k) = x.Range(k*ndofi, (k+1)*ndofi); - + feli.Evaluate(mir.IR(), matx, y); for (size_t i = 0; i < mir.Size(); i++) @@ -2610,10 +2622,10 @@ Vec> val = y.Col(i); y.Col(i).Range(0,DIM_SPACE) = Trans(jacinv) * val; } - } - + } - using DiffOp>::AddTransSIMDIR; + + using DiffOp>::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> y, BareSliceVector x) { @@ -2621,7 +2633,7 @@ auto & fel = static_cast (bfel); auto & feli = static_cast (fel[0]); size_t ndofi = feli.GetNDof(); - + STACK_ARRAY(SIMD, mempt, mir.Size()*DIM_SPACE); FlatMatrix> hy(DIM_SPACE, mir.Size(), &mempt[0]); @@ -2631,7 +2643,7 @@ Vec> val = y.Col(i); hy.Col(i) = jacinv * val; } - + STACK_ARRAY(double, memx, DIM_SPACE*ndofi); FlatMatrix matx(ndofi, DIM_SPACE, &memx[0]); @@ -2642,7 +2654,7 @@ for (size_t k = 0; k < DIM_SPACE; k++) x.Range(k*ndofi, (k+1)*ndofi) = matx.Col(k); - } + } }; @@ -2656,7 +2668,7 @@ enum { DIFFORDER = 1 }; static string Name() { return "curl"; } - + template static void GenerateMatrix (const FEL & fel, const MIP & mip, MAT & mat, LocalHeap & lh) @@ -2664,7 +2676,7 @@ auto & bfel = static_cast (fel); auto & feli = static_cast (bfel[0]); mat = 0; - + int ndofi = feli.GetNDof(); FlatMatrix<> grad (ndofi, 3, lh); feli.CalcDShape(mip.IP(), grad); @@ -2680,7 +2692,7 @@ } } - using DiffOp::ApplySIMDIR; + using DiffOp::ApplySIMDIR; static void ApplySIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector x, BareSliceMatrix> y) { @@ -2703,10 +2715,10 @@ Vec<3,SIMD> hv = Cross(gi, tek); y.Col(i).Range(0,3) += hv; } - } - } - - using DiffOp::AddTransSIMDIR; + } + } + + using DiffOp::AddTransSIMDIR; static void AddTransSIMDIR (const FiniteElement & bfel, const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> y, BareSliceVector x) { @@ -2727,12 +2739,12 @@ Vec<3,SIMD> hv = Cross(cy, tek); grad.Col(i) = -hv; } - + feli.AddGradTrans (mir, grad, x.Range(k*ndofi, (k+1)*ndofi)); - } - } + } + } }; - + /*class DiffOpCurlVectorL2Covariant : public DiffOp { public: @@ -2752,7 +2764,7 @@ for (int i = 0; i < 2; i++) feli.CalcMappedDShape(mip.IP(), Trans(mat.Row(i).Range(fel.GetRange(i)))); //~ int nd = fel.GetNDof(); - + //~ mat = 0; for (int i = 0; i < nd; i++) { @@ -2765,7 +2777,7 @@ DocInfo VectorL2FESpace :: GetDocu () { - DocInfo docu = FESpace::GetDocu(); + DocInfo docu = FESpace::GetDocu(); docu.short_docu = "A vector-valued L2-conforming finite element space."; docu.long_docu = R"raw_string(The Vector-L2 finite element space is a product-space of L2 spaces, @@ -2785,11 +2797,11 @@ " dofs within one scalar component are together."; docu.Arg("hide_all_dofs") = "bool = False\n" " all dofs are condensed without a global dofnr"; - + return docu; } - VectorL2FESpace::VectorL2FESpace (shared_ptr ama, const Flags & flags, + VectorL2FESpace::VectorL2FESpace (shared_ptr ama, const Flags & flags, bool checkflags) : CompoundFESpace(ama, flags) { @@ -2883,7 +2895,7 @@ bool curved = false; for (auto el : ma->Elements(VOL)) if (el.is_curved) curved = true; - + /* cout << "VectorL2, GetMassOp" << endl << "rho = " << *rho << endl @@ -2898,21 +2910,21 @@ case 1: return make_shared> (dynamic_pointer_cast(const_cast(this)->shared_from_this()), - rho, defon, lh); + rho, defon, lh); case 2: return make_shared> (dynamic_pointer_cast(const_cast(this)->shared_from_this()), - rho, defon, lh); + rho, defon, lh); case 3: return make_shared> (dynamic_pointer_cast(const_cast(this)->shared_from_this()), - rho, defon, lh); + rho, defon, lh); } } return FESpace::GetMassOperator(rho, defon, lh); } - + /* shared_ptr VectorL2FESpace :: GetMassOperator (shared_ptr rho, @@ -2922,8 +2934,8 @@ return FESpace::GetMassOperator(rho, defon, lh); } */ - - + + void VectorL2FESpace :: SolveM (CoefficientFunction * rho, BaseVector & vec, Region * def, LocalHeap & lh) const { @@ -2938,7 +2950,7 @@ } return; } - + for (size_t i = 0; i < spaces.Size(); i++) { auto veci = vec.Range (GetRange(i)); @@ -2947,8 +2959,8 @@ } - - + + void VectorL2FESpace :: ApplyM (CoefficientFunction * rho, BaseVector & vec, Region * defon, LocalHeap & lh) const @@ -3019,10 +3031,10 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el.Nr(), dnums); - + FlatVector elx(feli.GetNDof()*DIM, lh); if (def && !def->Mask()[ma->GetElIndex(el)]) @@ -3034,14 +3046,14 @@ vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; // curved = false; // curved not implemented - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); @@ -3054,17 +3066,17 @@ rhoi = rho->Evaluate(mir[0]) * Identity(DIM); else rho -> Evaluate(mir[0], FlatVector<> (DIM*DIM, &rhoi(0,0))); - + Mat trans(0.0); if (piola) trans = (1/mir[0].GetMeasure()) * Trans(mir[0].GetJacobian()) * rhoi * mir[0].GetJacobian(); else if (covariant) - trans = mir[0].GetMeasure() * mir[0].GetJacobianInverse() * rhoi * Trans(mir[0].GetJacobianInverse()); + trans = mir[0].GetMeasure() * mir[0].GetJacobianInverse() * rhoi * Trans(mir[0].GetJacobianInverse()); else trans = mir[0].GetMeasure() * rhoi; Mat invtrans = Inv(trans); - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3086,14 +3098,14 @@ if (rho->Dimension() == DIM*DIM) rho->Evaluate (mir, rhovals); } - + for (int i = 0; i < melx.Width(); i++) melx.Col(i) /= diag_mass(i); for (int comp = 0; comp < DIM; comp++) feli.Evaluate (ir, melx.Row(comp), pntvals.Row(comp)); Mat> rhoi(0.0); - + for (int i = 0; i < ir.Size(); i++) { if (!rho) @@ -3110,7 +3122,7 @@ trans = Trans(mir[i].GetJacobianInverse()); rhoi = Trans(trans)*rhoi*trans; rhoi *= mir[i].GetMeasure(); - + rhoi = Inv(rhoi); rhoi *= mir[i].IP().Weight(); @@ -3130,7 +3142,7 @@ }); } - + #ifdef OLD template void VectorL2FESpace :: @@ -3138,7 +3150,7 @@ LocalHeap & lh) const { static Timer t("SolveM - Piola"); RegionTimer reg(t); - + IterateElements (*this, VOL, lh, [&rho, &vec,this] (FESpace::Element el, LocalHeap & lh) @@ -3146,32 +3158,32 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el.Nr(), dnums); - + FlatVector elx(feli.GetNDof()*DIM, lh); vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; curved = false; // curved not implemented - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); BaseMappedIntegrationRule & mir = trafo(ir, lh); Mat trans = (1/mir[0].GetMeasure()) * Trans(mir[0].GetJacobian()) * mir[0].GetJacobian(); Mat invtrans = Inv(trans); - + // double jac = mir[0].GetMeasure(); // if (rho) jac *= rho->Evaluate(mir[0]); // diag_mass *= jac; - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3187,7 +3199,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -3199,7 +3211,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -3225,26 +3237,26 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el.Nr(), dnums); - + FlatVector elx(feli.GetNDof()*DIM, lh); vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; curved = false; // curved not implemented - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); MappedIntegrationRule mir(ir, trafo, lh); - + Mat rhoi(0.0); if (!rho) rhoi = Identity(DIM); @@ -3252,15 +3264,15 @@ rhoi = rho->Evaluate(mir[0]) * Identity(DIM); else rho -> Evaluate(mir[0], FlatVector<> (DIM*DIM, &rhoi(0,0))); - + // Mat trans = (1/mir[0].GetMeasure()) * Trans(mir[0].GetJacobian()) * mir[0].GetJacobian(); Mat trans = mir[0].GetMeasure() * mir[0].GetJacobianInverse() * rhoi * Trans(mir[0].GetJacobianInverse()); Mat invtrans = Inv(trans); - + // double jac = mir[0].GetMeasure(); // if (rho) jac *= rho->Evaluate(mir[0]); // diag_mass *= jac; - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3276,7 +3288,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -3288,7 +3300,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -3300,7 +3312,7 @@ }); } #endif - + template void VectorL2FESpace :: ApplyM_Dim (CoefficientFunction * rho, BaseVector & vec, Region * def, @@ -3314,27 +3326,27 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el.Nr(), dnums); - + FlatVector elx(feli.GetNDof()*DIM, lh); vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; curved = false; // curved not implemented - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); MappedIntegrationRule mir(ir, trafo, lh); - + Mat rhoi(0.0); if (!rho) rhoi = Identity(DIM); @@ -3342,9 +3354,9 @@ rhoi = rho->Evaluate(mir[0]) * Identity(DIM); else rho -> Evaluate(mir[0], FlatVector<> (DIM*DIM, &rhoi(0,0))); - + Mat trans = mir[0].GetMeasure() * rhoi; - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3360,7 +3372,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -3372,7 +3384,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -3384,10 +3396,10 @@ elx = 0.0; vec.SetIndirect(dnums, elx); }); - + } - + template void VectorL2FESpace :: @@ -3402,27 +3414,27 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el.Nr(), dnums); - + FlatVector elx(feli.GetNDof()*DIM, lh); vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; curved = false; // curved not implemented - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); MappedIntegrationRule mir(ir, trafo, lh); - + Mat rhoi(0.0); if (!rho) rhoi = Identity(DIM); @@ -3430,9 +3442,9 @@ rhoi = rho->Evaluate(mir[0]) * Identity(DIM); else rho -> Evaluate(mir[0], FlatVector<> (DIM*DIM, &rhoi(0,0))); - + Mat trans = 1/mir[0].GetMeasure() * Trans(mir[0].GetJacobian()) * rhoi * mir[0].GetJacobian(); - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3448,7 +3460,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -3460,7 +3472,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -3472,7 +3484,7 @@ elx = 0.0; vec.SetIndirect(dnums, elx); }); - + } @@ -3489,26 +3501,26 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el.Nr(), dnums); - + FlatVector elx(feli.GetNDof()*DIM, lh); vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; curved = false; // curved not implemented - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); MappedIntegrationRule mir(ir, trafo, lh); - + Mat rhoi(0.0); if (!rho) rhoi = Identity(DIM); @@ -3516,9 +3528,9 @@ rhoi = rho->Evaluate(mir[0]) * Identity(DIM); else rho -> Evaluate(mir[0], FlatVector<> (DIM*DIM, &rhoi(0,0))); - + Mat trans = mir[0].GetMeasure() * mir[0].GetJacobianInverse() * rhoi * Trans(mir[0].GetJacobianInverse()); - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3534,7 +3546,7 @@ FlatVector> pntvals(ir.Size(), lh); FlatMatrix> rhovals(1, ir.Size(), lh); if (rho) rho->Evaluate (mir, rhovals); - + for (int i = 0; i < melx.Height(); i++) melx.Row(i) /= diag_mass(i); for (int comp = 0; comp < dimension; comp++) @@ -3546,7 +3558,7 @@ else for (size_t i = 0; i < ir.Size(); i++) pntvals(i) *= ir[i].Weight() / mir[i].GetMeasure(); - + melx.Col(comp) = 0.0; fel.AddTrans (ir, pntvals, melx.Col(comp)); } @@ -3565,7 +3577,7 @@ DocInfo TangentialSurfaceL2FESpace :: GetDocu () { - DocInfo docu = FESpace::GetDocu(); + DocInfo docu = FESpace::GetDocu(); docu.short_docu = "An tangential, L2-conforming finite element space."; docu.long_docu = R"raw_string( (tbd) @@ -3593,7 +3605,7 @@ TangentialSurfaceL2FESpace :: - TangentialSurfaceL2FESpace (shared_ptr ama, const Flags & flags, + TangentialSurfaceL2FESpace (shared_ptr ama, const Flags & flags, bool checkflags) : CompoundFESpace(ama, flags) { @@ -3606,18 +3618,18 @@ piola = flags.GetDefineFlag ("piola"); piola = true; // for the moment ... - + if (piola) { switch (ma->GetDimension()) { case 2: - evaluator[VOL] = make_shared>>(); // dummy + evaluator[VOL] = make_shared>>(); // dummy evaluator[BND] = make_shared>>(); break; case 3: - evaluator[VOL] = make_shared>>(); // dummy - evaluator[BND] = make_shared>>(); + evaluator[VOL] = make_shared>>(); // dummy + evaluator[BND] = make_shared>>(); break; } } @@ -3645,11 +3657,11 @@ shared_ptr TangentialSurfaceL2FESpace :: GetMassOperator (shared_ptr rho, shared_ptr defon, - LocalHeap & lh) const + LocalHeap & lh) const { if (ma->GetDimension() != 2) return FESpace::GetMassOperator(rho, defon, lh); - + auto dofs = make_shared> (CreateDofTable(BND)); Matrix<> bmat; Vector rho_jac; @@ -3665,21 +3677,21 @@ auto & fel = static_cast(cfel[0]); // auto & fel = static_cast(el.GetFE()); const ElementTransformation & trafo = el.GetTrafo(); - + IntegrationRule ir1(fel.ElementType(), 2*fel.Order()); Array verts { el.Vertices() }; Facet2SurfaceElementTrafo f2s(fel.ElementType(), verts); auto & ir = f2s(ir1, lh); // auto & mir = trafo(ir, lh); MappedIntegrationRule mir(ir, trafo, lh); - - + + FlatMatrix<> rhovals(ir.Size(), 1, lh); if (rho) rho->Evaluate (mir, rhovals); else rhovals = 1; - + for (size_t i = 0; i < ir.Size(); i++) { Mat trans; @@ -3694,9 +3706,9 @@ { firsttime = false; bmat = Trans(shapes); - + eldiag.SetSize(fel.GetNDof()); - fel.GetDiagMassMatrix (eldiag); + fel.GetDiagMassMatrix (eldiag); weights.SetSize(ir.Size()); for (int i = 0; i < ir.Size(); i++) @@ -3711,7 +3723,7 @@ } rho_jac.Range ( rhovals.Height() * IntRange(el.Nr(), el.Nr()+1) ) = rhovals.Col(0); } - + // cout << "doftable = " << doftable << endl; // cout << "eldiag = " << eldiag << endl; @@ -3720,11 +3732,11 @@ return make_shared (dynamic_pointer_cast(const_cast< TangentialSurfaceL2FESpace*>(this)->shared_from_this()), rho, false, defon, bmat, eldiag, rho_jac, dofs, - lh); + lh); } - - + + void TangentialSurfaceL2FESpace :: SolveM (CoefficientFunction * rho, BaseVector & vec, Region * def, LocalHeap & lh) const { @@ -3760,7 +3772,7 @@ } - + template void TangentialSurfaceL2FESpace :: SolveM_Dim (CoefficientFunction * rho, BaseVector & vec, Region * def, @@ -3775,10 +3787,10 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el, dnums); - + FlatVector elx(feli.GetNDof()*(DIM-1), lh); if (def && !def->Mask()[ma->GetElIndex(el)]) @@ -3790,14 +3802,14 @@ vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM-1, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; // curved = false; // curved not implemented - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); @@ -3810,19 +3822,19 @@ rhoi = rho->Evaluate(mir[0]) * Identity(DIM); else rho -> Evaluate(mir[0], FlatVector<> (DIM*DIM, &rhoi(0,0))); - + Mat trans(0.0); if (piola) trans = (1/mir[0].GetMeasure()) * Trans(mir[0].GetJacobian()) * rhoi * mir[0].GetJacobian(); /* else if (covariant) - trans = mir[0].GetMeasure() * mir[0].GetJacobianInverse() * rhoi * Trans(mir[0].GetJacobianInverse()); + trans = mir[0].GetMeasure() * mir[0].GetJacobianInverse() * rhoi * Trans(mir[0].GetJacobianInverse()); else trans = mir[0].GetMeasure() * rhoi; */ Mat invtrans = Inv(trans); - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3836,7 +3848,7 @@ SIMD_MappedIntegrationRule mir(ir, trafo, lh); FlatMatrix> pntvals(DIM-1, ir.Size(), lh); FlatMatrix> rhovals1(1, ir.Size(), lh); - FlatMatrix> rhovals(DIM*DIM, ir.Size(), lh); + FlatMatrix> rhovals(DIM*DIM, ir.Size(), lh); if (rho) { if (rho->Dimension() == 1) @@ -3851,7 +3863,7 @@ feli.Evaluate (ir, melx.Row(comp), pntvals.Row(comp)); Mat> rhoi(0.0); - + for (int i = 0; i < ir.Size(); i++) { if (!rho) @@ -3867,7 +3879,7 @@ Mat> rhoitrans = Trans(trans)*rhoi*trans; rhoitrans *= mir[i].GetMeasure(); - + rhoitrans = Inv(rhoitrans); rhoitrans *= mir[i].IP().Weight(); @@ -3882,7 +3894,7 @@ for (int i = 0; i < melx.Width(); i++) melx.Col(i) /= diag_mass(i); } - + vec.SetIndirect(dnums, elx); }); @@ -3902,26 +3914,26 @@ auto & fel = static_cast(el.GetFE()); auto & feli = static_cast(fel[0]); const ElementTransformation & trafo = el.GetTrafo(); - + Array dnums(fel.GetNDof(), lh); GetDofNrs (el, dnums); - + FlatVector elx(feli.GetNDof()*(DIM-1), lh); vec.GetIndirect(dnums, elx); auto melx = elx.AsMatrix(DIM-1, feli.GetNDof()); - + FlatVector diag_mass(feli.GetNDof(), lh); feli.GetDiagMassMatrix (diag_mass); - + bool curved = trafo.IsCurvedElement(); if (rho && !rho->ElementwiseConstant()) curved = true; - + if (!curved) { IntegrationRule ir(fel.ElementType(), 0); MappedIntegrationRule mir(ir, trafo, lh); - + Mat rhoi(0.0); if (!rho) rhoi = Identity(DIM); @@ -3929,13 +3941,13 @@ rhoi = rho->Evaluate(mir[0]) * Identity(DIM); else rho -> Evaluate(mir[0], FlatVector<> (DIM*DIM, &rhoi(0,0))); - + Mat trans = mir[0].GetMeasure() * rhoi; if (piola) trans = (1/mir[0].GetMeasure()) * Trans(mir[0].GetJacobian()) * rhoi * mir[0].GetJacobian(); - + for (int i = 0; i < melx.Width(); i++) { Vec hv = melx.Col(i); @@ -3949,7 +3961,7 @@ SIMD_MappedIntegrationRule mir(ir, trafo, lh); FlatMatrix> pntvals(DIM-1, ir.Size(), lh); FlatMatrix> rhovals1(1, ir.Size(), lh); - FlatMatrix> rhovals(DIM*DIM, ir.Size(), lh); + FlatMatrix> rhovals(DIM*DIM, ir.Size(), lh); if (rho) { if (rho->Dimension() == 1) @@ -3957,12 +3969,12 @@ if (rho->Dimension() == DIM*DIM) rho->Evaluate (mir, rhovals); } - + for (int comp = 0; comp < DIM-1; comp++) feli.Evaluate (ir, melx.Row(comp), pntvals.Row(comp)); Mat> rhoi(0.0); - + for (int i = 0; i < ir.Size(); i++) { if (!rho) @@ -3978,7 +3990,7 @@ Mat> rhoitrans = Trans(trans)*rhoi*trans; rhoitrans *= mir[i].GetMeasure(); - + rhoitrans *= mir[i].IP().Weight(); Vec> rhopval = rhoitrans * pntvals.Col(i); @@ -3994,32 +4006,32 @@ elx = 0.0; vec.SetIndirect(dnums, elx); }); - + } - + static RegisterFESpace initvecl2 ("VectorL2"); static RegisterFESpace initsurfl2 ("l2surf"); - + // register FESpaces namespace l2hofespace_cpp { class Init - { - public: + { + public: Init (); }; - + Init::Init() { GetFESpaceClasses().AddFESpace ("l2", L2HighOrderFESpace::Create, L2HighOrderFESpace::GetDocu); GetFESpaceClasses().AddFESpace ("l2ho", L2HighOrderFESpace::CreateHO, L2HighOrderFESpace::GetDocu); // GetFESpaceClasses().AddFESpace ("l2surf", L2SurfaceHighOrderFESpace::Create, L2SurfaceHighOrderFESpace::GetDocu); } - + Init init; } } diff -Nru ngsolve-6.2.2102/comp/meshaccess.cpp ngsolve-6.2.2103/comp/meshaccess.cpp --- ngsolve-6.2.2102/comp/meshaccess.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/meshaccess.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -2466,7 +2466,7 @@ #endif - function cleanup_func; + function cleanup_func = ProgressOutput :: SumUpLocal; ProgressOutput :: ProgressOutput (shared_ptr ama, string atask, size_t atotal) : ma(ama), comm(ama->GetCommunicator()), task(atask), total(atotal) @@ -2484,7 +2484,7 @@ done_called = false; cnt = 0; thd_cnt = 0; - cleanup_func = [this] () { this->SumUpLocal(); }; + // cleanup_func = [this] () { this->SumUpLocal(); }; TaskManager::SetCleanupFunction(cleanup_func); } diff -Nru ngsolve-6.2.2102/comp/periodic.cpp ngsolve-6.2.2103/comp/periodic.cpp --- ngsolve-6.2.2102/comp/periodic.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/periodic.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -79,6 +79,18 @@ { auto & fe = space->GetFE(ei,alloc); const auto & ngel = ma->GetElement(ei); + + /* + SwitchET (ngel.GetType(), [&](auto et) + { + if (auto hofe = dynamic_cast*>(&fe)) + hofe->SetVertexNumbers(vertex_map[ngel.Vertices()]); + }); + */ + + fe.SetVertexNumbers( ArrayMem (vertex_map[ngel.Vertices()]) ); + + /* switch (ngel.GetType()) { case ET_TRIG: @@ -126,6 +138,7 @@ default: throw Exception("ElementType not implemented for PeriodicFESpace::GetFE"); } + */ return fe; } diff -Nru ngsolve-6.2.2102/comp/periodic.hpp ngsolve-6.2.2103/comp/periodic.hpp --- ngsolve-6.2.2102/comp/periodic.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/periodic.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -76,6 +76,7 @@ SliceVector vec, TRANSFORM_TYPE tt) const override { space->VTransformVC(ei, vec, tt); } + auto & GetVertexMap() const { return vertex_map; } protected: // overload in quasiperiodic space virtual void DofMapped(size_t from, size_t to, size_t idnr) { ; } diff -Nru ngsolve-6.2.2102/comp/postproc.cpp ngsolve-6.2.2103/comp/postproc.cpp --- ngsolve-6.2.2102/comp/postproc.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/postproc.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -496,8 +496,12 @@ { /** Calc RHS **/ elflux = SCAL(0.0); + auto [nv,ne,nf,nc] = fel.GetNDofVEFC(); + int nvefc[] = {nv,ne,nf,nc}; for (auto el_vb : fes->GetDualShapeNodes(vb)) { + if (!nvefc[ma->GetDimension()-el_vb-vb]) + continue; Facet2ElementTrafo f2el (fel.ElementType(), el_vb); for (int locfnr : Range(f2el.GetNFacets())) { @@ -569,8 +573,13 @@ */ elflux = SCAL(0.0); + auto [nv,ne,nf,nc] = fel.GetNDofVEFC(); + int nvefc[] = {nv,ne,nf,nc}; for (auto el_vb : fes->GetDualShapeNodes(vb)) { + if (!nvefc[ma->GetDimension()-el_vb-vb]) + continue; + Facet2ElementTrafo f2el (fel.ElementType(), el_vb); for (int locfnr : Range(f2el.GetNFacets())) { @@ -1514,6 +1523,7 @@ ma.IterateElements (this->dx.vb, glh, [&] (Ngs_Element el, LocalHeap & lh) { + if (this->dx.definedonelements && !this->dx.definedonelements->Test(el.Nr())) return; // if(!mask.Test(el.GetIndex())) return; auto & trafo1 = ma.GetTrafo (el, lh); auto & trafo = trafo1.AddDeformation(this->dx.deformation.get(), lh); @@ -1571,15 +1581,20 @@ bool has_other = false; cf->TraverseTree ([&has_other] (CoefficientFunction & cf) { + if (IsOtherCoefficientFunction (cf)) has_other = true; + /* + // not allowed here if (dynamic_cast (&cf)) if (dynamic_cast (cf).IsOther()) has_other = true; + */ }); if (!has_other) ma.IterateElements (this->dx.vb, glh, [&] (Ngs_Element el, LocalHeap & lh) { + if (this->dx.definedonelements && !this->dx.definedonelements->Test(el.Nr())) return; // if(!mask.Test(el.GetIndex())) return; auto & trafo1 = ma.GetTrafo (el, lh); auto & trafo = trafo1.AddDeformation(this->dx.deformation.get(), lh); @@ -1647,6 +1662,7 @@ ma.IterateElements (this->dx.vb, glh, [&] (Ngs_Element el, LocalHeap & lh) { + if (this->dx.definedonelements && !this->dx.definedonelements->Test(el.Nr())) return; auto & htrafo1 = ma.GetTrafo (el, lh); auto & trafo1 = htrafo1.AddDeformation(this->dx.deformation.get(), lh); auto eltype = trafo1.GetElementType(); diff -Nru ngsolve-6.2.2102/comp/preconditioner.cpp ngsolve-6.2.2103/comp/preconditioner.cpp --- ngsolve-6.2.2102/comp/preconditioner.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/preconditioner.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -538,6 +538,12 @@ blocksmoother->SetDirectSolverCluster(cluster); } + void MGPreconditioner::SetCoarsePreconditioner(shared_ptr prec) + { + coarse_pre = prec; + mgp->SetCoarseType (MultigridPreconditioner::USER_COARSE); + } + // ****************************** DirectPreconditioner ************************** @@ -663,6 +669,7 @@ string ct; shared_ptr coarse_pre; + function>(FESpace&)> blockcreator; public: /// LocalPreconditioner (const PDE & pde, const Flags & aflags, @@ -700,6 +707,15 @@ // bbct = DIRECT_COARSE; break; // } + if (blockcreator) + { + shared_ptr> blocks = blockcreator(*bfa->GetFESpace()); + // cout << "created blocks: " << *blocks << endl; + jacobi = dynamic_cast (bfa->GetMatrix()) + .CreateBlockJacobiPrecond(blocks, 0, parallel, bfa->GetFESpace()->GetFreeDofs()); + return; + } + if ( block && blocktype == -1 ) blocktype = 0; if ( blocktype >= 0 ) { @@ -812,6 +828,12 @@ // coarse-grid preconditioner only used in parallel!! ct = "NO_COARSE"; + + if(flags.AnyFlagDefined("blockcreator")) + { + blockcreator = std::any_cast>(const FESpace&)>>(flags.GetAnyFlag("blockcreator")); + cout << "local pre, got blockcreator" << endl; + } } diff -Nru ngsolve-6.2.2102/comp/preconditioner.hpp ngsolve-6.2.2103/comp/preconditioner.hpp --- ngsolve-6.2.2102/comp/preconditioner.hpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/preconditioner.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -302,6 +302,7 @@ void MgTest () const; void SetDirectSolverCluster(shared_ptr> cluster); + void SetCoarsePreconditioner(shared_ptr prec); }; class CommutingAMGPreconditioner : public Preconditioner diff -Nru ngsolve-6.2.2102/comp/python_comp.cpp ngsolve-6.2.2103/comp/python_comp.cpp --- ngsolve-6.2.2102/comp/python_comp.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/python_comp.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -1,11 +1,11 @@ #ifdef NGS_PYTHON - #include #include "../ngstd/python_ngstd.hpp" #include "python_comp.hpp" #include #include +#include #include "hdivdivfespace.hpp" #include "hcurldivfespace.hpp" @@ -18,6 +18,7 @@ #include "compressedfespace.hpp" #include "../fem/integratorcf.hpp" #include "contact.hpp" +#include "globalinterfacespace.hpp" using namespace ngcomp; using ngfem::ELEMENT_TYPE; @@ -31,14 +32,6 @@ shared_ptr lf, shared_ptr gf, LocalHeap & lh); - - - - - - - - } @@ -150,6 +143,61 @@ static size_t global_heapsize = 10000000; static LocalHeap glh(global_heapsize, "python-comp lh", true); + class LocalHeapProvider + { + Array heaps; + std::mutex m; + + class BorrowedLocalHeap + { + LocalHeap * lh; + LocalHeapProvider * provider; + public: + BorrowedLocalHeap (LocalHeap * alh, LocalHeapProvider * aprovider) + : lh(alh), provider(aprovider) { } + + ~BorrowedLocalHeap() + { + // cout << "returns lh to provider" << endl; + provider -> ReturnLH(lh); + } + + LocalHeap & LH() { return *lh; } + operator LocalHeap& () { return *lh; } + }; + + + public: + BorrowedLocalHeap GetLH() + { + std::lock_guard lock(m); + if (heaps.Size()) + { + auto tmp = heaps.Last(); + heaps.SetSize(heaps.Size()-1); + // cout << "reuse existing lh" << endl; + return BorrowedLocalHeap (tmp, this); + } + + // cout << "create new lh" << endl; + return BorrowedLocalHeap(new LocalHeap(global_heapsize, "python-comp lh"), this); + } + + void ReturnLH (LocalHeap * lh) + { + std::lock_guard lock(m); + heaps.Append (lh); + } + void Clear() + { + for (auto lh : heaps) + delete lh; + heaps.SetSize(0); + } + }; + static LocalHeapProvider lhp; + + ////////////////////////////////////////////////////////////////////////////////////////// py::enum_ (m, "COUPLING_TYPE", docu_string(R"raw_string( @@ -388,6 +436,7 @@ { global_heapsize = heapsize; glh = LocalHeap (heapsize, "python-comp lh", true); + lhp.Clear(); } }, py::arg("size"), docu_string(R"raw_string( Set a new heapsize. @@ -600,24 +649,38 @@ if (py::isinstance (definedon)) flags->SetFlag ("definedon", makeCArray (definedon)); - py::extract definedon_reg(definedon); - if (definedon_reg.check() && definedon_reg().IsVolume()) + try { - Array defonlist; - for (int i = 0; i < definedon_reg().Mask().Size(); i++) - if (definedon_reg().Mask().Test(i)) - defonlist.Append(i+1); - flags->SetFlag ("definedon", defonlist); + auto reg = py::cast(definedon); + flags->SetFlag("definedon", reg); } - if (definedon_reg.check() && definedon_reg().VB()==BND) + catch(py::cast_error) + {} + try { - Array defonlist; - flags->SetFlag("definedon", defonlist); //empty - for (auto i : Range(definedon_reg().Mask().Size())) - if(definedon_reg().Mask().Test(i)) - defonlist.Append(i+1); - flags->SetFlag("definedonbound", defonlist); + auto map = py::cast>(definedon); + flags->SetFlag("definedon", map); } + catch(py::cast_error) + {} + // py::extract definedon_reg(definedon); + // if (definedon_reg.check() && definedon_reg().IsVolume()) + // { + // Array defonlist; + // for (int i = 0; i < definedon_reg().Mask().Size(); i++) + // if (definedon_reg().Mask().Test(i)) + // defonlist.Append(i+1); + // flags->SetFlag ("definedon", defonlist); + // } + // if (definedon_reg.check() && definedon_reg().VB()==BND) + // { + // Array defonlist; + // flags->SetFlag("definedon", defonlist); //empty + // for (auto i : Range(definedon_reg().Mask().Size())) + // if(definedon_reg().Mask().Test(i)) + // defonlist.Append(i+1); + // flags->SetFlag("definedonbound", defonlist); + // } }), py::arg("order_policy") = py::cpp_function ([] (ORDER_POLICY op, Flags* flags, py::list info) @@ -1034,6 +1097,8 @@ if (is_complex) flags.SetFlag("complex"); flags.SetFlag ("dim", dim); flags.SetFlag ("dgjumps", space1->UsesDGCoupling() || space2->UsesDGCoupling()); + if(space1->LowOrderFESpacePtr() && space2->LowOrderFESpacePtr()) + flags.SetFlag("low_order_space"); auto productspace = make_shared (space1->GetMeshAccess(), flags); for (auto s : { space1, space2 }) @@ -1045,8 +1110,10 @@ else productspace->AddSpace (s); } + productspace->SetDoSubspaceUpdate(false); productspace->Update(); productspace->FinalizeUpdate(); + productspace->SetDoSubspaceUpdate(true); return productspace; }) @@ -1057,10 +1124,29 @@ if (is_complex) flags.SetFlag("complex"); flags.SetFlag ("dim", dim); auto productspace = make_shared (space, p, flags); + productspace->SetDoSubspaceUpdate(false); productspace->Update(); productspace->FinalizeUpdate(); + productspace->SetDoSubspaceUpdate(true); return productspace; }) + + // not working because shared_ptr> cannot be pybind return type? + // TODO CL: Find out why... + // .def("CreateDirectSolverCluster", &FESpace::CreateDirectSolverClusters) + .def("CreateDirectSolverCluster", [](FESpace& self, py::kwargs kwargs) + { + auto flags = CreateFlagsFromKwArgs(kwargs); + auto cluster = self.CreateDirectSolverClusters(flags); + py::list pycluster(self.GetNDof()); + if(cluster) + for(auto i : Range(self.GetNDof())) + pycluster[i] = (*cluster)[i]; + else + for(auto i : Range(self.GetNDof())) + pycluster[i] = 0; + return pycluster; + }) ; py::class_, FESpace> @@ -1090,8 +1176,10 @@ flags.SetFlag ("complex"); auto fes = make_shared (spaces[0]->GetMeshAccess(), spaces, flags); + fes->SetDoSubspaceUpdate(false); fes->Update(); fes->FinalizeUpdate(); + fes->SetDoSubspaceUpdate(true); return fes; })) .def(py::pickle([] (py::object pyfes) @@ -1165,19 +1253,7 @@ return Array>(self->Spaces()); }, "Return a list of the components of a product space") - - // not working because shared_ptr> cannot be pybind return type? - // TODO CL: Find out why... - // .def("CreateDirectSolverCluster", &FESpace::CreateDirectSolverClusters) - .def("CreateDirectSolverCluster", [](FESpace& self, py::kwargs kwargs) - { - auto flags = CreateFlagsFromKwArgs(kwargs); - auto cluster = self.CreateDirectSolverClusters(flags); - py::list pycluster(cluster->Size()); - for(auto i : Range(*cluster)) - pycluster[i] = (*cluster)[i]; - return pycluster; - }) + .def("SetDoSubspaceUpdate", &CompoundFESpace::SetDoSubspaceUpdate) ; py::class_, CompoundFESpace> @@ -1186,28 +1262,16 @@ py::class_, CompoundFESpace> (m,"MatrixValued") - .def(py::init([] (shared_ptr space, int dim, bool symmetric) { + .def(py::init([] (shared_ptr space, optional optdim, bool symmetric, bool deviatoric) { Flags flags; if (symmetric) flags.SetFlag("symmetric"); - auto matspace = make_shared (space, dim, flags); + if (deviatoric) flags.SetFlag("deviatoric"); + int sdim = optdim.value_or (space->GetSpatialDimension()); + auto matspace = make_shared (space, sdim, flags); matspace->Update(); matspace->FinalizeUpdate(); return matspace; - /* - flags.SetFlag ("dim", dim); - bool is_complex = spaces[0]->IsComplex(); - for (auto space : spaces) - if (space->IsComplex() != is_complex) - throw Exception("Product space of spaces with complex and real spaces is not allowed"); - if (is_complex) - flags.SetFlag ("complex"); - - auto fes = make_shared (spaces[0]->GetMeshAccess(), spaces, flags); - fes->Update(); - fes->FinalizeUpdate(); - return fes; - */ - }),py::arg("space"), py::arg("dim"), py::arg("symmetric")) + }),py::arg("space"), py::arg("dim")=nullopt, py::arg("symmetric")=false, py::arg("deviatoric")=false) ; ExportFESpace (m, "HCurl") @@ -1237,6 +1301,9 @@ ExportFESpace (m, "IntegrationRuleSpace") .def("GetIntegrationRules", &IntegrationRuleSpace::GetIntegrationRules) ; + ExportFESpace (m, "IntegrationRuleSpaceSurface") + .def("GetIntegrationRules", &IntegrationRuleSpaceSurface::GetIntegrationRules) + ; ExportFESpace (m, "L2"); @@ -1270,10 +1337,6 @@ ExportFESpace (m, "NodalFESpace"); ExportFESpace> (m, "VectorNodalFESpace"); - - - - // py::class_, FESpace> // (m, "CompoundFESpace") @@ -1617,7 +1680,25 @@ } }, py::arg("fespace"), py::arg("active_dofs")=DummyArgument()); - + py::class_, + FESpace> + (m, "GlobalInterfaceSpace") + .def(py::init([](shared_ptr ma, + shared_ptr mapping, + optional definedon, + bool periodic, bool periodicu, bool periodicv, + int order) + { + auto fes = CreateGlobalInterfaceSpace(ma, mapping, definedon, + periodic, periodicu, + periodicv, order); + fes->Update(); + fes->FinalizeUpdate(); + return fes; + }), "mesh"_a, "mapping"_a, "definedon"_a = nullopt, + "periodic"_a = false, "periodicu"_a = false, + "periodicv"_a = false, "order"_a = 3) + ; /////////////////////////////// GridFunctionCoefficientFunction ///////////// @@ -2396,7 +2477,8 @@ .def("Assemble", [](shared_ptr self, bool reallocate) { - self->ReAssemble(glh,reallocate); + // self->ReAssemble(glh,reallocate); + self->ReAssemble(lhp.GetLH(),reallocate); return self; }, py::call_guard(), py::arg("reallocate")=false, docu_string(R"raw_string( @@ -2679,7 +2761,11 @@ { return MakePyTuple (self->Integrators()); }, "returns tuple of integrators of the linear form") .def("Assemble", [](shared_ptr self) - { self->Assemble(glh); return self; }, + { + // self->Assemble(glh); + self->Assemble(lhp.GetLH()); + return self; + }, py::call_guard(), "Assemble linear form") .def_property_readonly("components", [](shared_ptr self) @@ -2707,6 +2793,12 @@ py::class_> (m, "Prolongation") .def ("Prolongate", &Prolongation::ProlongateInline, py::arg("finelevel"), py::arg("vec")) .def ("Restrict", &Prolongation::RestrictInline, py::arg("finelevel"), py::arg("vec")) + .def ("CreateMatrix", &Prolongation::CreateProlongationMatrix, py::arg("finelevel")) + .def ("LevelDofs", &Prolongation::LevelDofs, py::arg("level")) + .def ("Operator", [](shared_ptr prol, int level) -> shared_ptr + { + return make_shared(prol, level); + }, py::arg("finelevel")) ; /////////////////////////////// Preconditioner ///////////////////////////////////////////// @@ -2716,6 +2808,66 @@ .def(py::init([prec_class](shared_ptr bfa, const string & type, py::kwargs kwargs) { auto flags = CreateFlagsFromKwArgs(kwargs, prec_class); + + if (kwargs.contains("blockcreator")) + { + auto bc = kwargs["blockcreator"]; + py::print("createor: ", bc); + // if it is a compiled C++ user-function we should stay within C++ + // if (auto func = py::cast>(const FESpace&)>>(bc)) + if (py::function pyf=bc; pyf.is_cpp_function()) + { + cout << "it's a C++ function" << endl; + auto func = py::cast>(const FESpace&)>>(pyf.cpp_function()); + cout << "have func object, type(func) = " << typeid(func).name() << endl; + cout << "type cppfunc = " << typeid(pyf.cpp_function()).name() << endl; + typedef shared_ptr>(*callbackfunc)(const FESpace &); + cout << "func-ptr = " << func.target() << endl; + // cout << "function pointer " << (void*)(*func.target()) << endl; + + flags.SetFlag("blockcreator", func); + } + else + { + cout << "could not extract C++ function" << endl; + // cout << "create a wrapper" << endl; + function>(const FESpace&)> lam = + [bc](const FESpace & fes) -> shared_ptr> + { + py::gil_scoped_acquire aq; + py::object blocks = bc(py::cast(fes)); + + if (py::isinstance>(blocks)) + return py::cast>>(blocks); + + // not yet working: + // print ("blocks:", blocks); + // py::cast>> (blocks); + // cout << "cast did work" << endl; + // return py::cast>>(blocks); + + size_t size = py::len(blocks); + Array cnt(size); + size_t i = 0; + for (auto block : blocks) + cnt[i++] = py::len(block); + + i = 0; + auto blocktable = make_shared>(cnt); + for (auto block : blocks) + { + auto row = (*blocktable)[i++]; + size_t j = 0; + for (auto val : block) + row[j++] = val.cast(); + } + // cout << "blocktable = " << *blocktable << endl; + return blocktable; + }; + flags.SetFlag("blockcreator", lam); + } + } + auto creator = GetPreconditionerClasses().GetPreconditioner(type); if (creator == nullptr) throw Exception(string("nothing known about preconditioner '") + type + "'"); @@ -2745,11 +2897,14 @@ auto prec_multigrid = py::class_, Preconditioner> (m,"MultiGridPreconditioner"); prec_multigrid - .def(py::init([prec_multigrid](shared_ptr bfa, const string& name, py::kwargs kwargs) + .def(py::init([prec_multigrid](shared_ptr bfa, const string& name, optional> lo_precond, py::kwargs kwargs) { auto flags = CreateFlagsFromKwArgs(kwargs, prec_multigrid); - return make_shared(bfa,flags, name); - }), py::arg("bf"), "name"_a = "multigrid") + auto mgpre = make_shared(bfa,flags, name); + if(lo_precond.has_value()) + mgpre->SetCoarsePreconditioner(lo_precond.value()); + return mgpre; + }), py::arg("bf"), "name"_a = "multigrid", "lo_preconditioner"_a = nullopt) .def_static("__flags_doc__", [prec_class] () { auto mg_flags = py::cast(prec_class.attr("__flags_doc__")()); @@ -3361,7 +3516,11 @@ { bool iscomplex = false; for (auto & ci : igls) - iscomplex |= ci->cf->IsComplex(); + { + iscomplex |= ci->cf->IsComplex(); + if (ci->cf->Dimension() > 1) + throw Exception("Integrate(cf*dx) needs scalar-valued CoefficientFunction"); + } auto integrate = [&] (auto tscal) { diff -Nru ngsolve-6.2.2102/comp/python_comp_mesh.cpp ngsolve-6.2.2103/comp/python_comp_mesh.cpp --- ngsolve-6.2.2102/comp/python_comp_mesh.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/python_comp_mesh.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -337,6 +337,7 @@ auto range = self.GetElements(); return py::make_iterator(range.begin(), range.end()); }, py::keep_alive<0,1>()) + .def_property_readonly("mesh", &Region::Mesh) .def("__hash__", &Region::Hash) .def("__eq__", &Region::operator==) .def(py::self + py::self) @@ -434,7 +435,7 @@ .def ("nnodes", &MeshAccess::GetNNodes, "number of nodes given type") .def_property_readonly ("dim", &MeshAccess::GetDimension, "mesh dimension") .def_property_readonly ("ngmesh", &MeshAccess::GetNetgenMesh, "the Netgen mesh") - + .def_property_readonly ("levels", &MeshAccess::GetNLevels, "multigrid levels") .def_property_readonly ("vertices", [] (shared_ptr mesh) { @@ -551,7 +552,7 @@ "Return list of pml transformations" ) .def("GetPMLTrafo", [](MeshAccess & ma, int domnr) { - if (ma.GetPMLTrafos()[domnr]) + if (ma.GetPMLTrafos()[domnr-1]) return ma.GetPMLTrafos()[domnr-1]; else throw Exception("No PML Trafo set"); @@ -790,23 +791,48 @@ }, py::arg("x") = 0.0, py::arg("y") = 0.0, py::arg("z") = 0.0 ,"Check if the point (x,y,z) is in the meshed domain (is inside a volume element)") - .def("MapToAllElements", [](MeshAccess* self, IntegrationRule& rule, VorB vb) + .def("MapToAllElements", [](MeshAccess* self, IntegrationRule& rule, std::variant vb_or_reg) -> py::array_t { Array points; - points.SetAllocSize(self->GetNE() * rule.Size()); - for(auto el : self->Elements(vb)) - for(const auto& p : rule) - points.Append({p(0), p(1), p(2), self, vb, int(el.Nr())}); + + if (auto vb = get_if(&vb_or_reg); vb) + { + points.SetAllocSize(self->Elements(*vb).Size() * rule.Size()); + for(auto el : self->Elements(*vb)) + for(const auto& p : rule) + points.Append({p(0), p(1), p(2), self, *vb, int(el.Nr())}); + } + + if (auto reg = get_if(&vb_or_reg); reg) + { + for(auto el : self->Elements(reg->VB())) + if (reg->Mask().Test(el.GetIndex())) + for(const auto& p : rule) + points.Append({p(0), p(1), p(2), self, reg->VB(), int(el.Nr())}); + } + return MoveToNumpyArray(points); }) - .def("MapToAllElements", [](MeshAccess* self, std::map rules, VorB vb) + .def("MapToAllElements", [](MeshAccess* self, std::map rules, std::variant vb_or_reg) -> py::array_t { Array points; - for(auto el : self->Elements(vb)) - for(const auto& p : rules[el.GetType()]) - points.Append({p(0), p(1), p(2), self, vb, int(el.Nr())}); + + if (auto vb = get_if(&vb_or_reg); vb) + { + for(auto el : self->Elements(*vb)) + for(const auto& p : rules[el.GetType()]) + points.Append({p(0), p(1), p(2), self, *vb, int(el.Nr())}); + } + + if (auto reg = get_if(&vb_or_reg); reg) + { + for(auto el : self->Elements(reg->VB())) + if (reg->Mask().Test(el.GetIndex())) + for(const auto& p : rules[el.GetType()]) + points.Append({p(0), p(1), p(2), self, reg->VB(), int(el.Nr())}); + } return MoveToNumpyArray(points); }) ; diff -Nru ngsolve-6.2.2102/comp/tpfes.cpp ngsolve-6.2.2103/comp/tpfes.cpp --- ngsolve-6.2.2102/comp/tpfes.cpp 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/comp/tpfes.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -427,6 +427,7 @@ if (!xtrafo.IsCurvedElement()) { FlatVector diag_mass(ndofx, lh); + /* switch (meshx->GetDimension()) { case 1: @@ -436,6 +437,8 @@ case 3: static_cast&> (felx).GetDiagMassMatrix (diag_mass); } + */ + static_cast(felx).GetDiagMassMatrix (diag_mass); IntegrationRule ir(felx.ElementType(), 0); BaseMappedIntegrationRule & mir = xtrafo(ir, lh); diag_mass *= mir[0].GetMeasure(); @@ -469,6 +472,7 @@ if (!ytrafo.IsCurvedElement()) { FlatVector diag_mass(ndofy, lh); + /* switch (meshy->GetDimension()) { case 1: @@ -477,7 +481,8 @@ static_cast&> (fely).GetDiagMassMatrix (diag_mass); case 3: static_cast&> (fely).GetDiagMassMatrix (diag_mass); - } + }*/ + static_cast(fely).GetDiagMassMatrix (diag_mass); IntegrationRule ir(fely.ElementType(), 0); BaseMappedIntegrationRule & mir = ytrafo(ir, lh); diag_mass *= mir[0].GetMeasure(); @@ -603,6 +608,7 @@ else { FlatVector diag_mass(fel.GetNDof(), lh); + /* switch (fes->GetMeshAccess()->GetDimension()) { case 1: @@ -611,7 +617,9 @@ static_cast&> (fel).GetDiagMassMatrix (diag_mass); case 3: static_cast&> (fel).GetDiagMassMatrix (diag_mass); - } + }*/ + static_cast(fel).GetDiagMassMatrix (diag_mass); + IntegrationRule ir(fel.ElementType(), 0); BaseMappedIntegrationRule & mir = trafo(ir, lh); diag_mass *= mir[0].GetMeasure(); diff -Nru ngsolve-6.2.2102/debian/changelog ngsolve-6.2.2103/debian/changelog --- ngsolve-6.2.2102/debian/changelog 2021-03-19 06:19:17.000000000 +0000 +++ ngsolve-6.2.2103/debian/changelog 2021-06-04 23:37:12.000000000 +0000 @@ -1,10 +1,10 @@ -ngsolve (6.2.2102-0~ubuntu20.10.1) groovy; urgency=low +ngsolve (6.2.2103-0~ubuntu20.10.1) groovy; urgency=low * Auto build. - -- Launchpad Package Builder Fri, 19 Mar 2021 06:19:17 +0000 + -- Launchpad Package Builder Fri, 04 Jun 2021 23:37:12 +0000 -ngsolve (6.2.2102-0) xenial; urgency=low +ngsolve (6.2.2103-0) xenial; urgency=low * Initial release (Closes: #nnnn) diff -Nru ngsolve-6.2.2102/debian/git-build-recipe.manifest ngsolve-6.2.2103/debian/git-build-recipe.manifest --- ngsolve-6.2.2102/debian/git-build-recipe.manifest 2021-03-19 06:19:17.000000000 +0000 +++ ngsolve-6.2.2103/debian/git-build-recipe.manifest 2021-06-04 23:37:12.000000000 +0000 @@ -1,5 +1,5 @@ # git-build-recipe format 0.4 deb-version {debversion} -lp:~mhochsteger/+git/ngsolve git-commit:55200cf61b717f95be02f281ed15340d200e3412 -nest ppa lp:~mhochsteger/+git/ngsolve debian git-commit:16c16aa93f80428551ada75179e8b613b79d0397 -nest netgen lp:~mhochsteger/+git/netgen external_dependencies/netgen git-commit:ab4359c3431dff442ace6a8449df621fb765bed2 +lp:~mhochsteger/+git/ngsolve git-commit:4b57cac9da265f2d1d5c86ccd364f51ac67f8221 +nest ppa lp:~mhochsteger/+git/ngsolve debian git-commit:30e53dfffa536d5b75bbac7fcb075683d4551b54 +nest netgen lp:~mhochsteger/+git/netgen external_dependencies/netgen git-commit:ca6d6e8ca727cb6d9ee4726f2456d4249685a912 nest pybind lp:~mhochsteger/+git/pybind11 external_dependencies/netgen/external_dependencies/pybind11 git-commit:c16da993094988141101ac4d96a9b2c92f9ac714 diff -Nru ngsolve-6.2.2102/debian/netgen_version.txt ngsolve-6.2.2103/debian/netgen_version.txt --- ngsolve-6.2.2102/debian/netgen_version.txt 2021-03-19 06:18:43.000000000 +0000 +++ ngsolve-6.2.2103/debian/netgen_version.txt 2021-06-04 23:35:31.000000000 +0000 @@ -1 +1 @@ -v6.2.2102-0-gab4359c3 +v6.2.2103-0-gca6d6e8c diff -Nru ngsolve-6.2.2102/debian/version.txt ngsolve-6.2.2103/debian/version.txt --- ngsolve-6.2.2102/debian/version.txt 2021-03-19 06:18:43.000000000 +0000 +++ ngsolve-6.2.2103/debian/version.txt 2021-06-04 23:35:31.000000000 +0000 @@ -1 +1 @@ -v6.2.2102-0-g55200cf6 +v6.2.2103-0-g4b57cac9 diff -Nru ngsolve-6.2.2102/docs/install/usejupyter.rst ngsolve-6.2.2103/docs/install/usejupyter.rst --- ngsolve-6.2.2102/docs/install/usejupyter.rst 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/install/usejupyter.rst 2021-06-04 23:31:19.000000000 +0000 @@ -21,11 +21,15 @@ pip install --upgrade jupyter pip install --upgrade ipykernel -To install the NGSolve Jupyter notebook extension, run +To install the WebGUI Jupyter notebook extension, run .. code:: bash - jupyter nbextension install --user --py ngsolve + pip3 install webgui_jupyter_widgets + jupyter nbextension install --user --py widgetsnbextension + jupyter nbextension enable --user --py widgetsnbextension + jupyter nbextension install --user --py webgui_jupyter_widgets + jupyter nbextension enable --user --py webgui_jupyter_widgets Now, download the first NGSolve Jupyter notebook :download:`poisson.ipynb`, and start @@ -34,13 +38,3 @@ jupyter notebook poisson.ipynb Step though the notebook by pressing "Shift-Enter" for every cell. A separate visualization window will pop up showing the generated mesh and computed solution. - - -Using Jupyter lab -====================== - -The command needed to install the NGSolve Jupyter lab extension depends on the system and is generated with the following code: - -.. code:: bash - - python3 -c 'import ngsolve.webgui; ngsolve.webgui.howtoInstallJupyterLabextension()' diff -Nru ngsolve-6.2.2102/docs/i-tutorials/index.rst ngsolve-6.2.2103/docs/i-tutorials/index.rst --- ngsolve-6.2.2102/docs/i-tutorials/index.rst 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/index.rst 2021-06-04 23:31:19.000000000 +0000 @@ -34,18 +34,21 @@ To use the webgui visualization within jupyter you need -- pip3 install ipywidgets -- jupyter nbextension install --py widgetsnbextension -- jupyter nbextension enable --py widgetsnbextension -- jupyter nbextension install --user --py ngsolve -- jupyter nbextension enable --user --py ngsolve +.. code-block:: bash + + pip3 install webgui_jupyter_widgets + jupyter nbextension install --user --py widgetsnbextension + jupyter nbextension enable --user --py widgetsnbextension + jupyter nbextension install --user --py webgui_jupyter_widgets + jupyter nbextension enable --user --py webgui_jupyter_widgets Some of the tutorials require packages from scipy and matplotlib, so it is a good idea to install them as well: -- pip3 install scipy -- pip3 install matplotlib +.. code-block:: bash + + pip3 install scipy matplotlib matplotlib i-tutorials on Youtube ---------------------- diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.1-poisson/poisson.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.1-poisson/poisson.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.1-poisson/poisson.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.1-poisson/poisson.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -40,8 +40,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import unit_square" ] }, @@ -256,6 +256,13 @@ " You can then ask for a python shell from the GUI's menu options (`Solve -> Python shell`).\n", " " ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -274,7 +281,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.2-coefficient/coefficientfunction.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.2-coefficient/coefficientfunction.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.2-coefficient/coefficientfunction.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.2-coefficient/coefficientfunction.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -29,9 +29,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.geom2d import unit_square\n", "import matplotlib.pyplot as plt\n", "mesh = Mesh (unit_square.GenerateMesh(maxh=0.2))" ] @@ -566,7 +566,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.3-dirichlet/dirichlet.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.3-dirichlet/dirichlet.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.3-dirichlet/dirichlet.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.3-dirichlet/dirichlet.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -47,8 +47,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import unit_square\n", "\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))\n", @@ -323,7 +323,7 @@ "outputs": [], "source": [ "gfu.vec.data += a.mat.Inverse(freedofs=fes.FreeDofs()) * r \n", - "Redraw()" + "Draw(gfu)" ] }, { @@ -348,8 +348,15 @@ "#c = Preconditioner(a,\"direct\") #<- sparse direct solver\n", "c.Update()\n", "solvers.BVP(bf=a, lf=f, gf=gfu, pre=c)\n", - "Redraw()" + "Draw(gfu)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.4-staticcond/staticcond.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.4-staticcond/staticcond.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.4-staticcond/staticcond.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.4-staticcond/staticcond.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -27,8 +27,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import unit_square\n", "\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.4))\n", @@ -433,7 +433,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.5-subdomains/subdomains.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.5-subdomains/subdomains.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.5-subdomains/subdomains.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.5-subdomains/subdomains.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -37,9 +37,9 @@ }, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.geom2d import *\n", - "from ngsolve import *" + "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.geom2d import *" ] }, { @@ -789,7 +789,7 @@ "outputs": [], "source": [ "g.Set(cf, definedon=mesh.Boundaries('b|r'))\n", - "Redraw()" + "Draw(g, max=2, min=0)" ] }, { @@ -819,7 +819,7 @@ "source": [ "g.Set(cf, definedon=mesh.Boundaries('b'))\n", "g.Set(cf, definedon=mesh.Boundaries('r'))\n", - "Redraw()" + "Draw(g, max=2, min=0)" ] }, { @@ -921,7 +921,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" }, "name": "subdomains.ipynb" }, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.6-adaptivity/adaptivity.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.6-adaptivity/adaptivity.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.6-adaptivity/adaptivity.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.6-adaptivity/adaptivity.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -23,8 +23,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import SplineGeometry\n", "import matplotlib.pyplot as plt" ] @@ -151,8 +151,7 @@ " a.Assemble()\n", " f.Assemble()\n", " inv = CGSolver(a.mat, c.mat)\n", - " gfu.vec.data = inv * f.vec\n", - " Redraw (blocking=True)" + " gfu.vec.data = inv * f.vec" ] }, { @@ -161,7 +160,8 @@ "metadata": {}, "outputs": [], "source": [ - "SolveBVP()" + "SolveBVP()\n", + "Draw(gfu)" ] }, { @@ -242,9 +242,7 @@ "print (\"maxerr = \", maxerr)\n", "\n", "for el in mesh.Elements():\n", - " mesh.SetRefinementFlag(el, eta2[el.nr] > 0.25*maxerr)\n", - " \n", - "Draw(gfu)" + " mesh.SetRefinementFlag(el, eta2[el.nr] > 0.25*maxerr)" ] }, { @@ -264,7 +262,7 @@ "source": [ "mesh.Refine()\n", "SolveBVP()\n", - "Redraw()" + "Draw(gfu)" ] }, { @@ -327,6 +325,7 @@ "source": [ "while fes.ndof < 50000: \n", " SolveBVP()\n", + " Draw(gfu)\n", " CalcError()\n", " mesh.Refine()" ] @@ -354,6 +353,13 @@ "plt.ion()\n", "plt.show()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -372,7 +378,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.7-helmholtz/helmholtz.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.7-helmholtz/helmholtz.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.7-helmholtz/helmholtz.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.7-helmholtz/helmholtz.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -31,8 +31,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import SplineGeometry" ] }, @@ -162,7 +162,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.7-helmholtz/pml.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.7-helmholtz/pml.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.7-helmholtz/pml.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.7-helmholtz/pml.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -19,9 +19,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.geom2d import SplineGeometry\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.geom2d import SplineGeometry\n", "import matplotlib.pyplot as plt" ] }, @@ -306,7 +306,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-1.8-meshtopology/meshtopology.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-1.8-meshtopology/meshtopology.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-1.8-meshtopology/meshtopology.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-1.8-meshtopology/meshtopology.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -22,8 +22,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.csg import unit_cube" ] }, @@ -33,7 +33,8 @@ "metadata": {}, "outputs": [], "source": [ - "mesh = Mesh(unit_cube.GenerateMesh(maxh=1))" + "mesh = Mesh(unit_cube.GenerateMesh(maxh=1))\n", + "Draw(mesh)" ] }, { @@ -374,7 +375,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.10-dualbasis/dualbasis.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.10-dualbasis/dualbasis.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.10-dualbasis/dualbasis.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.10-dualbasis/dualbasis.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -28,8 +28,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import unit_square\n", "import matplotlib.pylab as plt\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=2))" @@ -166,10 +166,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import unit_square\n", - "\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))\n", "\n", "fesh1 = VectorH1(mesh, order=2)\n", @@ -384,7 +383,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.4" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.11-matrixfree/matrixfree.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.11-matrixfree/matrixfree.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.11-matrixfree/matrixfree.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.11-matrixfree/matrixfree.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -44,9 +44,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.geom2d import unit_square\n", "from ngsolve.fem import MixedFE\n", "\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.3))\n", @@ -288,7 +288,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.1.1-preconditioners/preconditioner.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.1.1-preconditioners/preconditioner.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.1.1-preconditioners/preconditioner.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.1.1-preconditioners/preconditioner.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -284,7 +284,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.1.2-blockjacobi/blockjacobi.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.1.2-blockjacobi/blockjacobi.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.1.2-blockjacobi/blockjacobi.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.1.2-blockjacobi/blockjacobi.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -21,9 +21,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.geom2d import unit_square\n", "from ngsolve.la import EigenValues_Preconditioner" ] }, @@ -581,7 +581,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.0" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.1.3-bddc/bddc.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.1.3-bddc/bddc.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.1.3-bddc/bddc.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.1.3-bddc/bddc.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -39,8 +39,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from ngsolve.la import EigenValues_Preconditioner\n", "from netgen.csg import unit_cube\n", "from netgen.geom2d import unit_square\n", @@ -291,8 +291,15 @@ " + (uho-ulo)*lam*dx(element_vb=BBND))\n", "gfu = GridFunction(fes)\n", "solvers.Newton(a=a, u=gfu)\n", - "Draw(gfu.components[0])" + "Draw(gfu.components[0],deformation=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -311,7 +318,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.2-eigenvalues/pinvit.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.2-eigenvalues/pinvit.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.2-eigenvalues/pinvit.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.2-eigenvalues/pinvit.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -23,9 +23,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.geom2d import unit_square\n", "import math\n", "import scipy.linalg\n", "from scipy import random\n", diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.3-hcurlhdiv/hcurlhdiv.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.3-hcurlhdiv/hcurlhdiv.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.3-hcurlhdiv/hcurlhdiv.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.3-hcurlhdiv/hcurlhdiv.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -62,8 +62,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import unit_square\n", "from netgen.csg import unit_cube\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.3))" @@ -85,7 +85,7 @@ "order=3\n", "fes = H1(mesh, order=order)\n", "gfu = GridFunction(fes)\n", - "Draw(gfu, sd=4)" + "Draw(gfu)" ] }, { @@ -101,11 +101,10 @@ "metadata": {}, "outputs": [], "source": [ - "SetVisualization(min=0, max=1)\n", "gfu.vec[:] = 0\n", "# vertex nr:\n", "gfu.vec[17] = 1\n", - "Redraw()" + "Draw(gfu, min=0, max=1, deformation=True)" ] }, { @@ -124,10 +123,9 @@ "# basis functions on edge nr:\n", "edge_dofs = fes.GetDofNrs(NodeId(EDGE,10))\n", "print(\"edge_dofs =\", edge_dofs)\n", - "SetVisualization(min=-0.05, max=0.05)\n", "gfu.vec[:] = 0\n", "gfu.vec[edge_dofs[0]] = 1\n", - "Redraw()" + "Draw(gfu, order=3, min=-0.05, max=0.05, deformation=True)" ] }, { @@ -145,10 +143,9 @@ "source": [ "trig_dofs = fes.GetDofNrs(NodeId(FACE,0))\n", "print(\"trig_dofs = \", trig_dofs)\n", - "SetVisualization(min=0, max=0.03)\n", "gfu.vec[:] = 0\n", "gfu.vec[trig_dofs[0]] = 1\n", - "Redraw()" + "Draw(gfu, order=3, min=0, max=0.03, deformation=True)" ] }, { @@ -212,10 +209,7 @@ "outputs": [], "source": [ "fes = HCurl(mesh, order=2)\n", - "uc = GridFunction(fes, name=\"uc\")\n", - "Draw (uc)\n", - "Draw (curl(uc), mesh, \"curl\")\n", - "Draw (Norm(uc), mesh, \"norm-uc\")" + "uc = GridFunction(fes, name=\"uc\")" ] }, { @@ -228,8 +222,9 @@ "print (\"edgedofs: \", edge_dofs)\n", "uc.vec[:] = 0\n", "uc.vec[edge_dofs[0]] = 1\n", - "SetVisualization(min=0, max=3)\n", - "Redraw()" + "Draw (uc, min=0, max=3)\n", + "Draw (curl(uc), mesh, \"curl\", min=0, max=3)\n", + "Draw (Norm(uc), mesh, \"norm-uc\", min=0, max=3)" ] }, { @@ -249,8 +244,9 @@ "print (\"facedofs: \", face_dofs)\n", "uc.vec[:] = 0\n", "uc.vec[face_dofs[0]] = 1\n", - "SetVisualization(min=0, max=1)\n", - "Redraw()" + "Draw (uc, min=0, max=1)\n", + "Draw (curl(uc), mesh, \"curl\", min=0, max=1)\n", + "Draw (Norm(uc), mesh, \"norm-uc\", min=0, max=1)" ] }, { @@ -332,6 +328,13 @@ "source": [ "Draw (grad(ud)[0,1], mesh, \"gradud\")" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -350,7 +353,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" }, "nbsphinx": { "allow_errors": true diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.4-Maxwell/Maxwellevp.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.4-Maxwell/Maxwellevp.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.4-Maxwell/Maxwellevp.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.4-Maxwell/Maxwellevp.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -30,9 +30,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.csg import *\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.csg import *\n", "\n", "geom = CSGeometry()\n", "\n", @@ -122,11 +122,10 @@ "metadata": {}, "outputs": [], "source": [ - "Draw (mesh)\n", "gfu = GridFunction(fes, multidim=len(evecs))\n", "for i in range(len(evecs)):\n", " gfu.vecs[i].data = evecs[i]\n", - "Draw (Norm(gfu), mesh, \"u\", sd=4)" + "Draw (Norm(gfu), mesh, \"u\")" ] }, { @@ -153,7 +152,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.4-Maxwell/Maxwell.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.4-Maxwell/Maxwell.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.4-Maxwell/Maxwell.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.4-Maxwell/Maxwell.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -52,8 +52,8 @@ "outputs": [], "source": [ "from ngsolve import *\n", - "from netgen.csg import *\n", - "import netgen.gui" + "from ngsolve.webgui import Draw\n", + "from netgen.csg import *" ] }, { @@ -166,11 +166,18 @@ "outputs": [], "source": [ "# the vector potential is not supposed to look nice\n", - "Draw (gfu, mesh, \"vector-potential\", draw_surf=False)\n", + "Draw (gfu, mesh, \"vector-potential\", draw_surf=False, clipping=True)\n", "\n", - "Draw (curl(gfu), mesh, \"B-field\", draw_surf=False)\n", - "Draw (1/(mu0*mur)*curl(gfu)-mag, mesh, \"H-field\", draw_surf=False)" + "Draw (curl(gfu), mesh, \"B-field\", draw_surf=False, clipping=True)\n", + "Draw (1/(mu0*mur)*curl(gfu)-mag, mesh, \"H-field\", draw_surf=False, clipping=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -189,7 +196,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.5-mixed/mixed.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.5-mixed/mixed.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.5-mixed/mixed.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.5-mixed/mixed.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -68,7 +68,7 @@ "source": [ "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", - "import netgen.gui\n", + "from ngsolve.webgui import Draw\n", "\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.1))" ] @@ -256,7 +256,8 @@ "# fm.vec.data -= am.mat * gfm.vec\n", "# gfm.vec.data += am.mat.Inverse(freedofs=fesm.FreeDofs(), inverse=\"umfpack\") * fm.vec\n", "solvers.BVP(bf=am, lf=fm, gf=gfm)\n", - "Redraw()" + "Draw (gfsigma, mesh, \"flux-mixed\")\n", + "Draw (gfu, mesh, \"u-mixed\")" ] }, { @@ -347,7 +348,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.6-stokes/stokes.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.6-stokes/stokes.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.6-stokes/stokes.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.6-stokes/stokes.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -36,7 +36,7 @@ "outputs": [], "source": [ "from ngsolve import *\n", - "import netgen.gui\n", + "from ngsolve.webgui import Draw\n", "\n", "from netgen.geom2d import SplineGeometry\n", "geo = SplineGeometry()\n", @@ -107,7 +107,6 @@ "gfu.components[0].Set(uin, definedon=mesh.Boundaries(\"inlet\"))\n", "velocity = CoefficientFunction(gfu.components[0:2])\n", "Draw(velocity, mesh, \"vel\")\n", - "Draw(Norm(velocity), mesh, \"|vel|\")\n", "SetVisualization(max=2)" ] }, @@ -128,7 +127,7 @@ "res.data = -a.mat * gfu.vec\n", "inv = a.mat.Inverse(freedofs=X.FreeDofs(), inverse=\"umfpack\")\n", "gfu.vec.data += inv * res\n", - "Redraw()" + "Draw(velocity, mesh, \"vel\")" ] }, { @@ -423,13 +422,6 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.7-hybrid/hybrid.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.7-hybrid/hybrid.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.7-hybrid/hybrid.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.7-hybrid/hybrid.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -39,7 +39,7 @@ "source": [ "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", - "import netgen.gui\n", + "from ngsolve.webgui import Draw\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))" ] }, @@ -205,7 +205,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.8-DG/DG.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.8-DG/DG.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.8-DG/DG.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.8-DG/DG.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -43,9 +43,9 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", - "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", + "from netgen.geom2d import unit_square\n", "mesh = Mesh(unit_square.GenerateMesh(maxh=0.3))" ] }, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-2.9-fourthorder/fourthorder.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-2.9-fourthorder/fourthorder.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-2.9-fourthorder/fourthorder.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-2.9-fourthorder/fourthorder.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -49,8 +49,8 @@ "metadata": {}, "outputs": [], "source": [ - "import netgen.gui\n", "from ngsolve import *\n", + "from ngsolve.webgui import Draw\n", "from netgen.geom2d import unit_square\n", "mesh = Mesh (unit_square.GenerateMesh(maxh=0.1))" ] @@ -227,13 +227,6 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.1-parabolic/parabolic.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.1-parabolic/parabolic.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.1-parabolic/parabolic.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.1-parabolic/parabolic.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -26,9 +26,9 @@ }, "outputs": [], "source": [ - "from netgen import gui\n", - "from math import pi\n", "from ngsolve import *\n", + "import netgen.gui\n", + "from math import pi\n", "from netgen.geom2d import SplineGeometry" ] }, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.2-navierstokes/navierstokes.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.2-navierstokes/navierstokes.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.2-navierstokes/navierstokes.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.2-navierstokes/navierstokes.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -29,8 +29,8 @@ }, "outputs": [], "source": [ - "from netgen import gui\n", "from ngsolve import *\n", + "import netgen.gui\n", "from netgen.geom2d import SplineGeometry" ] }, @@ -558,7 +558,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.3.1-wavedg/wavedg.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.3.1-wavedg/wavedg.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.3.1-wavedg/wavedg.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.3.1-wavedg/wavedg.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -47,8 +47,8 @@ }, "outputs": [], "source": [ - "from netgen import gui\n", "from ngsolve import *\n", + "import netgen.gui\n", "from netgen.geom2d import SplineGeometry\n", "geo = SplineGeometry()\n", "geo.AddRectangle( (-1, -1), (1, 1), bcs = (\"bottom\", \"right\", \"top\", \"left\"))\n", @@ -541,7 +541,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.3-scalardg/scalardg.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.3-scalardg/scalardg.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.3-scalardg/scalardg.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.3-scalardg/scalardg.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -28,7 +28,7 @@ "outputs": [], "source": [ "from ngsolve import *\n", - "from netgen import gui" + "import netgen.gui" ] }, { @@ -678,7 +678,8 @@ "t = 0; gfu.vec[:] = 0\n", "while t < tend-0.5*dt:\n", " gfu.vec.data -= dt * (r + invm @ c * gfu.vec)\n", - " t += dt; Redraw(blocking=True)" + " t += dt; \n", + " Redraw(blocking=True)" ] }, { @@ -708,7 +709,8 @@ "while t < tend-0.5*dt:\n", " tmp.data = r + invm @ c * gfu.vec\n", " gfu.vec.data -= dt * tmp\n", - " t += dt; Redraw(blocking=True)" + " t += dt; \n", + " Redraw(blocking=True)" ] }, { @@ -830,6 +832,13 @@ " t += dt\n", " Redraw(blocking=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -848,7 +857,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.4-simplehyp/shallow2D.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.4-simplehyp/shallow2D.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.4-simplehyp/shallow2D.ipynb 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.4-simplehyp/shallow2D.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -82,7 +82,7 @@ "outputs": [], "source": [ "from ngsolve import * # sloppy\n", - "from netgen import gui" + "import netgen.gui" ] }, { @@ -511,7 +511,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.5-surfacehdg/surfacehdg.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.5-surfacehdg/surfacehdg.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.5-surfacehdg/surfacehdg.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.5-surfacehdg/surfacehdg.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -28,9 +28,9 @@ }, "outputs": [], "source": [ - "from netgen import gui\n", - "from math import pi\n", - "from ngsolve import *" + "from ngsolve import *\n", + "import netgen.gui\n", + "from math import pi" ] }, { diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.6-opsplit/opsplit.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.6-opsplit/opsplit.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.6-opsplit/opsplit.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.6-opsplit/opsplit.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -72,8 +72,8 @@ }, "outputs": [], "source": [ - "from netgen import gui\n", "from ngsolve import *\n", + "import netgen.gui\n", "from netgen.geom2d import SplineGeometry\n", "geo = SplineGeometry()\n", "geo.AddRectangle((0, 0), (2, 0.41), bcs = (\"wall\", \"outlet\", \"wall\", \"inlet\"))\n", @@ -218,7 +218,7 @@ "outputs": [], "source": [ "m = BilinearForm(V , symmetric=True)\n", - "m += u * v *dx\n", + "m += u * v * dx\n", "m.Assemble()" ] }, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.7-nonlinear/nonlinear.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.7-nonlinear/nonlinear.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.7-nonlinear/nonlinear.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.7-nonlinear/nonlinear.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -42,9 +42,9 @@ }, "outputs": [], "source": [ - "from netgen import gui\n", - "from netgen.geom2d import unit_square\n", "from ngsolve import *\n", + "import netgen.gui\n", + "from netgen.geom2d import unit_square\n", "\n", "mesh = Mesh (unit_square.GenerateMesh(maxh=0.3))" ] @@ -360,7 +360,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-3.8-nonlmin/nonlmin.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-3.8-nonlmin/nonlmin.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-3.8-nonlmin/nonlmin.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-3.8-nonlmin/nonlmin.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -24,8 +24,8 @@ }, "outputs": [], "source": [ - "from netgen import gui\n", - "from ngsolve import *" + "from ngsolve import *\n", + "import netgen.gui" ] }, { @@ -415,7 +415,6 @@ "outputs": [], "source": [ "from ngsolve import *\n", - "\n", "from netgen.geom2d import *\n", "\n", "periodic = SplineGeometry()\n", @@ -559,6 +558,13 @@ " u(v) = u^{lo}(v) \\quad \\text{ for all vertices } v \\in V(T) \\text{ for all } T.\n", "$$" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-4.2-csg/csg.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-4.2-csg/csg.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-4.2-csg/csg.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-4.2-csg/csg.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -169,8 +169,7 @@ "source": [ "geo = CSGeometry()\n", "geo.Add(sphere)\n", - "geo.Draw()\n", - "Redraw()" + "geo.Draw()" ] }, { diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-4.3-manualmesh/manualmeshing.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-4.3-manualmesh/manualmeshing.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-4.3-manualmesh/manualmeshing.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-4.3-manualmesh/manualmeshing.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -379,7 +379,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.4" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-6.1.1-surfacemeshes/surface_meshes.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-6.1.1-surfacemeshes/surface_meshes.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-6.1.1-surfacemeshes/surface_meshes.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-6.1.1-surfacemeshes/surface_meshes.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -395,7 +395,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.5" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/docs/i-tutorials/unit-6.1.3-rmplate/Reissner_Mindlin_plate.ipynb ngsolve-6.2.2103/docs/i-tutorials/unit-6.1.3-rmplate/Reissner_Mindlin_plate.ipynb --- ngsolve-6.2.2102/docs/i-tutorials/unit-6.1.3-rmplate/Reissner_Mindlin_plate.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/docs/i-tutorials/unit-6.1.3-rmplate/Reissner_Mindlin_plate.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -425,7 +425,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.5" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/cmake/SuperBuild.cmake ngsolve-6.2.2103/external_dependencies/netgen/cmake/SuperBuild.cmake --- ngsolve-6.2.2102/external_dependencies/netgen/cmake/SuperBuild.cmake 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/cmake/SuperBuild.cmake 2021-06-04 23:36:22.000000000 +0000 @@ -166,6 +166,10 @@ set(NETGEN_BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/netgen --config ${CMAKE_BUILD_TYPE}) endif() +if(DEFINED ENV{CI} AND WIN32) + set(log_output LOG_BUILD ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON) +endif() + ExternalProject_Add (netgen DEPENDS ${NETGEN_DEPENDENCIES} SOURCE_DIR ${PROJECT_SOURCE_DIR} @@ -174,6 +178,7 @@ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/netgen BUILD_COMMAND ${NETGEN_BUILD_COMMAND} STEP_TARGETS build + ${log_output} ) # Check if the git submodules (i.e. pybind11) are up to date diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/archive.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/archive.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/archive.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/archive.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -153,6 +153,7 @@ virtual void NeedsVersion(const std::string& /*unused*/, const std::string& /*unused*/) {} // Pure virtual functions that have to be implemented by In-/OutArchive + virtual Archive & operator & (float & d) = 0; virtual Archive & operator & (double & d) = 0; virtual Archive & operator & (int & i) = 0; virtual Archive & operator & (long & i) = 0; @@ -678,6 +679,8 @@ BinaryOutArchive& operator=(BinaryOutArchive&&) = delete; using Archive::operator&; + Archive & operator & (float & f) override + { return Write(f); } Archive & operator & (double & d) override { return Write(d); } Archive & operator & (int & i) override @@ -685,7 +688,11 @@ Archive & operator & (short & i) override { return Write(i); } Archive & operator & (long & i) override - { return Write(i); } + { + // for platform independence + int64_t tmp = i; + return Write(tmp); + } Archive & operator & (size_t & i) override { return Write(i); } Archive & operator & (unsigned char & i) override @@ -723,14 +730,13 @@ template Archive & Write (T x) { + static_assert(sizeof(T) < BUFFERSIZE, "Cannot write large types with this function!"); if (unlikely(ptr > BUFFERSIZE-sizeof(T))) { stream->write(&buffer[0], ptr); - *reinterpret_cast(&buffer[0]) = x; // NOLINT - ptr = sizeof(T); - return *this; + ptr = 0; } - *reinterpret_cast(&buffer[ptr]) = x; // NOLINT + memcpy(&buffer[ptr], &x, sizeof(T)); ptr += sizeof(T); return *this; } @@ -749,6 +755,8 @@ : BinaryInArchive(std::make_shared(filename)) { ; } using Archive::operator&; + Archive & operator & (float & f) override + { Read(f); return *this; } Archive & operator & (double & d) override { Read(d); return *this; } Archive & operator & (int & i) override @@ -756,7 +764,12 @@ Archive & operator & (short & i) override { Read(i); return *this; } Archive & operator & (long & i) override - { Read(i); return *this; } + { + int64_t tmp; + Read(tmp); + i = tmp; + return *this; + } Archive & operator & (size_t & i) override { Read(i); return *this; } Archive & operator & (unsigned char & i) override @@ -813,6 +826,8 @@ TextOutArchive(std::make_shared(filename)) { } using Archive::operator&; + Archive & operator & (float & f) override + { *stream << f << '\n'; return *this; } Archive & operator & (double & d) override { *stream << d << '\n'; return *this; } Archive & operator & (int & i) override @@ -864,6 +879,8 @@ : TextInArchive(std::make_shared(filename)) {} using Archive::operator&; + Archive & operator & (float & f) override + { *stream >> f; return *this; } Archive & operator & (double & d) override { *stream >> d; return *this; } Archive & operator & (int & i) override @@ -924,6 +941,7 @@ { h = (char*)&hash_value; } using Archive::operator&; + Archive & operator & (float & f) override { return ApplyHash(f); } Archive & operator & (double & d) override { return ApplyHash(d); } Archive & operator & (int & i) override { return ApplyHash(i); } Archive & operator & (short & i) override { return ApplyHash(i); } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/array.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/array.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/array.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/array.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -212,6 +212,20 @@ template constexpr T IndexBASE () { return T(0); } + + class IndexFromEnd + { + ptrdiff_t i; + public: + constexpr IndexFromEnd (ptrdiff_t ai) : i(ai) { } + IndexFromEnd operator+ (ptrdiff_t inc) const { return i+inc; } + IndexFromEnd operator- (ptrdiff_t dec) const { return i-dec; } + // operator ptrdiff_t () const { return i; } + ptrdiff_t Value() const { return i; } + }; + + constexpr IndexFromEnd END(0); + template class FlatArray; @@ -422,9 +436,9 @@ protected: static constexpr IndexType BASE = IndexBASE(); /// the size - size_t size; + size_t size = 0; /// the data - T * __restrict data; + T * __restrict data = nullptr; public: typedef T value_type; typedef IndexType index_type; @@ -561,6 +575,12 @@ } /// takes range starting from position start of end-start elements + NETGEN_INLINE FlatArray Range (size_t start, IndexFromEnd indend) const + { + return this->Range(start, size_t(Size()+indend.Value())); + } + + /// takes range starting from position start of end-start elements NETGEN_INLINE FlatArray Range (T_Range range) const { return FlatArray (range.Size(), data+range.First()); @@ -593,8 +613,10 @@ return Pos(elem) != ILLEGAL_POSITION; } - auto begin() const { return ArrayIterator (*this, BASE); } - auto end() const { return ArrayIterator (*this, size+BASE); } + //auto begin() const { return ArrayIterator (*this, BASE); } + // auto end() const { return ArrayIterator (*this, size+BASE); } + auto begin() const { return data; } + auto end() const { return data+Size(); } }; template @@ -772,8 +794,9 @@ /// if responsible, deletes memory NETGEN_INLINE ~Array() { + if(mem_to_delete) + mt.Free(sizeof(T)*allocsize); delete [] mem_to_delete; - mt.Free(sizeof(T)*allocsize); } // Only provide this function if T is archivable @@ -827,8 +850,9 @@ /// assigns memory from local heap NETGEN_INLINE const Array & Assign (size_t asize, LocalHeap & lh) { + if(mem_to_delete) + mt.Free(sizeof(T)*allocsize); delete [] mem_to_delete; - mt.Free(sizeof(T)*allocsize); size = allocsize = asize; data = lh.Alloc (asize); mem_to_delete = nullptr; @@ -935,8 +959,9 @@ /// Deallocate memory NETGEN_INLINE void DeleteAll () { + if(mem_to_delete) + mt.Free(sizeof(T)*allocsize); delete [] mem_to_delete; - mt.Free(sizeof(T)*allocsize); mem_to_delete = NULL; data = 0; size = allocsize = 0; @@ -1088,8 +1113,9 @@ else for (size_t i = 0; i < mins; i++) data[i] = std::move(hdata[i]); #endif + if(mem_to_delete) + mt.Free(sizeof(T) * allocsize); delete [] mem_to_delete; - mt.Free(sizeof(T) * allocsize); } mem_to_delete = data; @@ -1172,6 +1198,14 @@ data[cnt++] = val; } + template + ArrayMem (const BaseArrayObject & a2) + : ArrayMem (a2.Size()) + { + for (size_t i : ngcore::Range(size)) + data[i] = a2[i]; + } + ArrayMem & operator= (const T & val) { diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/python_ngcore_export.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/python_ngcore_export.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/python_ngcore_export.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/python_ngcore_export.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -19,6 +19,8 @@ ExportArray(m); ExportArray(m); + ExportTable(m); + py::class_> (m, "BitArray") .def(py::init([] (size_t n) { return make_shared(n); }),py::arg("n")) .def(py::init([] (const BitArray& a) { return make_shared(a); } ), py::arg("ba")) diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/python_ngcore.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/python_ngcore.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/python_ngcore.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/python_ngcore.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -8,6 +8,7 @@ #include #include "array.hpp" +#include "table.hpp" #include "archive.hpp" #include "flags.hpp" #include "ngcore_api.hpp" @@ -60,6 +61,23 @@ : ngcore_list_caster, Type> { }; + /* + template struct type_caster>> + { + template + static handle cast(T &&src, return_value_policy policy, handle parent) + { + std::cout << "handle called with type src = " << typeid(src).name() << std::endl; + + return handle(); // what so ever + } + + PYBIND11_TYPE_CASTER(Type, _("Table[") + make_caster::name + _("]")); + }; + */ + + + } // namespace detail } // namespace pybind11 //////////////////////////////////////////////////////////////////////////////// @@ -240,6 +258,48 @@ ; } + template + void ExportTable (py::module &m) + { + py::class_, std::shared_ptr>> (m, ("Table_"+GetPyName()).c_str()) + .def(py::init([] (py::list blocks) + { + size_t size = py::len(blocks); + Array cnt(size); + size_t i = 0; + for (auto block : blocks) + cnt[i++] = py::len(block); + + i = 0; + Table blocktable(cnt); + for (auto block : blocks) + { + auto row = blocktable[i++]; + size_t j = 0; + for (auto val : block) + row[j++] = val.cast(); + } + // cout << "blocktable = " << *blocktable << endl; + return blocktable; + + }), py::arg("blocks"), "a list of lists") + + .def ("__len__", [] (Table &self ) { return self.Size(); } ) + .def ("__getitem__", + [](Table & self, size_t i) -> FlatArray + { + if (i >= self.Size()) + throw py::index_error(); + return self[i]; + }) + .def("__str__", [](Table & self) + { + return ToString(self); + }) + ; + } + + void NGCORE_API SetFlag(Flags &flags, std::string s, py::object value); // Parse python kwargs to flags Flags NGCORE_API CreateFlagsFromKwArgs(const py::kwargs& kwargs, py::object pyclass = py::none(), diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/ranges.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/ranges.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/ranges.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/ranges.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -32,7 +32,7 @@ FUNC f; public: FilterIterator(FUNC af, Iterator aiter, Iterator aend) - : f(af), iter(aiter), end(aend) + : iter(aiter), end(aend), f(af) { while(iter!=end && !f(*iter)) ++iter; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/table.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/table.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/table.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/table.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -9,6 +9,7 @@ #include #include +#include #include "array.hpp" #include "bitarray.hpp" @@ -347,6 +348,49 @@ } }; + template + Table CreateTable( const TRange & range, const TFunc & func, std::optional< size_t > cnt ) + { + static Timer timer("CreateTable"); + RegionTimer rt(timer); + std::unique_ptr> pcreator; + + if(cnt) + pcreator = std::make_unique>(*cnt); + else + pcreator = std::make_unique>(); + + auto & creator = *pcreator; + + for ( ; !creator.Done(); creator++) + ParallelForRange + (range, [&] (auto myrange) + { + for (auto i : myrange) + func(creator, i); + }, TasksPerThread(4) + ); + + return creator.MoveTable(); + } + + template + Table CreateSortedTable( const TRange & range, const TFunc & func, std::optional< size_t > cnt ) + { + static Timer timer("CreateSortedTable"); + RegionTimer rt(timer); + Table table = CreateTable(range, func, cnt); + ParallelForRange + (table.Range(), [&] (auto myrange) + { + for (auto i : myrange) + QuickSort(table[i]); + }, TasksPerThread(4) + ); + + return table; + } + class NGCORE_API FilteredTableCreator : public TableCreator { protected: diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/utils.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/utils.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/core/utils.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/core/utils.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -13,7 +13,15 @@ #ifdef WIN32 // 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) { + std::string name = typeinfo; + // remove "class " and "struct " at beginning of type names to be consistent with demangled names of gcc/clang + if(name.find("class ") == 0) + name.erase(0,6); + if(name.find("struct ") == 0) + name.erase(0,7); + return name; + } #else NGCORE_API std::string Demangle(const char* typeinfo) { diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/csgeom.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/csgeom.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/csgeom.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/csgeom.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -176,9 +176,8 @@ solids.DeleteAll (); - for (int i = 0; i < splinecurves2d.Size(); i++) - delete splinecurves2d[i]; splinecurves2d.DeleteAll(); + splinecurves3d.DeleteAll(); /* for (int i = 0; i < surfaces.Size(); i++) @@ -712,24 +711,24 @@ - void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<2> * spl) + void CSGeometry :: SetSplineCurve (const char * name, shared_ptr> spl) { splinecurves2d.Set(name,spl); } - void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<3> * spl) + void CSGeometry :: SetSplineCurve (const char * name, shared_ptr> spl) { splinecurves3d.Set(name,spl); } - const SplineGeometry<2> * CSGeometry :: GetSplineCurve2d (const string & name) const + shared_ptr> CSGeometry :: GetSplineCurve2d (const string & name) const { if (splinecurves2d.Used(name)) return splinecurves2d[name]; else return NULL; } - const SplineGeometry<3> * CSGeometry :: GetSplineCurve3d (const string & name) const + shared_ptr> CSGeometry :: GetSplineCurve3d (const string & name) const { if (splinecurves3d.Used(name)) return splinecurves3d[name]; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/csgeom.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/csgeom.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/csgeom.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/csgeom.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -115,9 +115,9 @@ SymbolTable solids; /// all 2d splinecurves - SymbolTable< SplineGeometry<2>* > splinecurves2d; + SymbolTable>> splinecurves2d; /// all 3d splinecurves - SymbolTable< SplineGeometry<3>* > splinecurves3d; + SymbolTable>> splinecurves3d; /// all top level objects: solids and surfaces NgArray toplevelobjects; @@ -232,10 +232,10 @@ const SymbolTable & GetSolids () const { return solids; } - void SetSplineCurve (const char * name, SplineGeometry<2> * spl); - void SetSplineCurve (const char * name, SplineGeometry<3> * spl); - const SplineGeometry<2> * GetSplineCurve2d (const string & name) const; - const SplineGeometry<3> * GetSplineCurve3d (const string & name) const; + void SetSplineCurve (const char * name, shared_ptr> spl); + void SetSplineCurve (const char * name, shared_ptr> spl); + shared_ptr> GetSplineCurve2d (const string & name) const; + shared_ptr> GetSplineCurve3d (const string & name) const; void DoArchive(Archive& archive) override; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/csgparser.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/csgparser.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/csgparser.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/csgparser.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -511,8 +511,8 @@ break; } - Primitive * nprim = new Extrusion(*(geom->GetSplineCurve3d(epath)), - *(geom->GetSplineCurve2d(profile)), + Primitive * nprim = new Extrusion(geom->GetSplineCurve3d(epath), + geom->GetSplineCurve2d(profile), z_dir); geom->AddSurfaces (nprim); return new Solid(nprim); @@ -1186,7 +1186,7 @@ ParseChar (scan, '='); ParseChar (scan, '('); - SplineGeometry<2> * newspline = new SplineGeometry<2>; + auto newspline = make_shared>(); // newspline->CSGLoad(scan); LoadSpline (*newspline, scan); @@ -1212,7 +1212,7 @@ ParseChar (scan, '='); ParseChar (scan, '('); - SplineGeometry<3> * newspline = new SplineGeometry<3>; + auto newspline = make_shared>(); // newspline->CSGLoad(scan); LoadSpline (*newspline, scan); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/extrusion.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/extrusion.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/extrusion.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/extrusion.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -41,6 +41,18 @@ loc_z_dir[i] = glob_z_direction; } } + + double cum_angle = 0.; + for(auto i : Range(path->GetSplines())) + { + const auto& sp = path->GetSpline(i); + auto t1 = sp.GetTangent(0.); + t1.Normalize(); + auto t2 = sp.GetTangent(1.); + t2.Normalize(); + cum_angle += acos(t1 * t2); + angles.Append(cum_angle); + } profile->GetCoeff(profile_spline_coeff); latest_point3d = -1.111e30; @@ -656,20 +668,35 @@ dez /= lenz; dez -= (dez * ez) * ez; } - - Extrusion :: Extrusion(const SplineGeometry<3> & path_in, - const SplineGeometry<2> & profile_in, + void ExtrusionFace :: DefineTangentialPlane(const Point<3>& ap1, + const Point<3>& ap2) + { + Surface::DefineTangentialPlane(ap1, ap2); + tangential_plane_seg = latest_seg; + } + + void ExtrusionFace :: ToPlane(const Point<3>& p3d, Point<2>& p2d, + double h, int& zone) const + { + Surface::ToPlane(p3d, p2d, h, zone); + double angle = angles[tangential_plane_seg] - angles[latest_seg]; + if(fabs(angle) > 3.14/2.) + zone = -1; + } + + Extrusion :: Extrusion(shared_ptr> path_in, + shared_ptr> profile_in, const Vec<3> & z_dir) : - path(&path_in), profile(&profile_in), z_direction(z_dir) + path(path_in), profile(profile_in), z_direction(z_dir) { surfaceactive.SetSize(0); surfaceids.SetSize(0); for(int j=0; jGetNSplines(); j++) { - ExtrusionFace * face = new ExtrusionFace(&((*profile).GetSpline(j)), - path, + ExtrusionFace * face = new ExtrusionFace(&(profile->GetSpline(j)), + path.get(), z_direction); faces.Append(face); surfaceactive.Append(true); @@ -856,7 +883,7 @@ return retval; if(latestfacenum >= 0) - return faces[latestfacenum]->VecInFace(p,v2,0); + return faces[latestfacenum]->VecInFace(p,v2,eps); else return VecInSolid(p,v2,eps); } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/extrusion.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/extrusion.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/extrusion.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/extrusion.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -12,8 +12,10 @@ const SplineSeg<2> * profile; const SplineGeometry<3> * path; Vec<3> glob_z_direction; + Array angles; bool deletable; + int tangential_plane_seg; NgArray< const SplineSeg3<3> * > spline3_path; NgArray< const LineSeg<3> * > line_path; @@ -54,7 +56,7 @@ ~ExtrusionFace(); - virtual void DoArchive(Archive& ar) + void DoArchive(Archive& ar) override { Surface::DoArchive(ar); ar & profile & path & glob_z_direction & deletable & spline3_path & line_path & @@ -62,25 +64,25 @@ profile_spline_coeff & latest_seg & latest_t & latest_point2d & latest_point3d; } - virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + int IsIdentic (const Surface & s2, int & inv, double eps) const override; - virtual double CalcFunctionValue (const Point<3> & point) const; - virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; - virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; - virtual double HesseNorm () const; + double CalcFunctionValue (const Point<3> & point) const override; + void CalcGradient (const Point<3> & point, Vec<3> & grad) const override; + void CalcHesse (const Point<3> & point, Mat<3> & hesse) const override; + double HesseNorm () const override; - virtual double MaxCurvature () const; + double MaxCurvature () const override; //virtual double MaxCurvatureLoc (const Point<3> & /* c */ , // double /* rad */) const; - virtual void Project (Point<3> & p) const; + void Project (Point<3> & p) const override; - virtual Point<3> GetSurfacePoint () const; - virtual void Print (ostream & str) const; + Point<3> GetSurfacePoint () const override; + void Print (ostream & str) const override; - virtual void GetTriangleApproximation (TriangleApproximation & tas, + void GetTriangleApproximation (TriangleApproximation & tas, const Box<3> & boundingbox, - double facets) const; + double facets) const override; const SplineGeometry<3> & GetPath(void) const {return *path;} const SplineSeg<2> & GetProfile(void) const {return *profile;} @@ -114,6 +116,11 @@ Vec<3> & ex, Vec<3> & ey, Vec<3> & ez, Vec<3> & dex, Vec<3> & dey, Vec<3> & dez) const; + void DefineTangentialPlane(const Point<3>& ap1, + const Point<3>& ap2) override; + void ToPlane(const Point<3>& p3d, Point<2>& p2d, + double h, int& zone) const override; + }; @@ -121,8 +128,8 @@ class Extrusion : public Primitive { private: - const SplineGeometry<3>* path; - const SplineGeometry<2>* profile; // closed, clockwise oriented curve + shared_ptr> path; + shared_ptr> profile; // closed, clockwise oriented curve Vec<3> z_direction; @@ -131,47 +138,46 @@ mutable int latestfacenum; public: - Extrusion(const SplineGeometry<3> & path_in, - const SplineGeometry<2> & profile_in, + Extrusion(shared_ptr> path_in, + shared_ptr> profile_in, const Vec<3> & z_dir); // default constructor for archive Extrusion() {} ~Extrusion(); - virtual void DoArchive(Archive& ar) + void DoArchive(Archive& ar) override { Primitive::DoArchive(ar); ar & path & profile & z_direction & faces & latestfacenum; } - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - virtual INSOLID_TYPE PointInSolid (const Point<3> & p, - double eps) const; + INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const override; + INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const override; INSOLID_TYPE PointInSolid (const Point<3> & p, double eps, NgArray * const facenums) const; - virtual void GetTangentialSurfaceIndices (const Point<3> & p, - NgArray & surfind, double eps) const; + void GetTangentialSurfaceIndices (const Point<3> & p, + NgArray & surfind, double eps) const override; - virtual INSOLID_TYPE VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const; + INSOLID_TYPE VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const override; // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid - virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, - const Vec<3> & v1, - const Vec<3> & v2, - double eps) const; + INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const override; - virtual int GetNSurfaces() const; - virtual Surface & GetSurface (int i = 0); - virtual const Surface & GetSurface (int i = 0) const; - + int GetNSurfaces() const override; + Surface & GetSurface (int i = 0) override; + const Surface & GetSurface (int i = 0) const override; - virtual void Reduce (const BoxSphere<3> & box); - virtual void UnReduce (); + void Reduce (const BoxSphere<3> & box) override; + void UnReduce () override; }; } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/python_csg.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/python_csg.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/csg/python_csg.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/csg/python_csg.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -170,7 +170,8 @@ DLL_HEADER void ExportCSG(py::module &m) { - py::class_> (m, "SplineCurve2d") + py::class_, shared_ptr>> + (m, "SplineCurve2d") .def(py::init<>()) .def ("AddPoint", FunctionPointer ([] (SplineGeometry<2> & self, double x, double y) @@ -329,14 +330,31 @@ Solid * sol = new Solid(rev); return make_shared (sol); })); - m.def ("Extrusion", FunctionPointer([](const SplineGeometry<3> & path, - const SplineGeometry<2> & profile, - Vec<3> n) - { - Extrusion * extr = new Extrusion (path,profile,n); - Solid * sol = new Solid(extr); - return make_shared (sol); - })); + m.def ("Extrusion", [](shared_ptr> path, + shared_ptr> profile, + Vec<3> d) + { + Extrusion * extr = new Extrusion (path,profile,d); + Solid * sol = new Solid(extr); + return make_shared (sol); + }, py::arg("path"), py::arg("profile"), py::arg("d"), + R"delimiter(A body of extrusion is defined by its profile +(which has to be a closed, clockwiseoriented 2D curve), + by a path (a 3D curve) and a vector d. It is constructed + as follows: Take a point p on the path and denote the + (unit-)tangent of the path in this point by t. If we cut + the body by the plane given by p and t as normal vector, + the cut is the profile. The profile is oriented by the + (local) y-direction `y:=d−(d·t)t` and the (local) x-direction + `x:=t \times y`. +The following points have to be noticed: + * If the path is not closed, then also the body is NOT closed. + In this case e.g. planes or orthobricks have to be used to + construct a closed body. + * The path has to be smooth, i.e. the tangents at the end- resp. + start-point of two consecutive spline or line patches have to + have the same directions. +)delimiter"); m.def("EllipticCone", [](const Point<3>& a, const Vec<3>& v, const Vec<3>& w, double h, double r) { diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/general/ngarray.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/general/ngarray.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/general/ngarray.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/general/ngarray.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -242,7 +242,7 @@ using NgFlatArray::data; /// physical size of array - size_t allocsize; + size_t allocsize = 0; /// memory is responsibility of container bool ownmem; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/geom2d/csg2d.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/geom2d/csg2d.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/geom2d/csg2d.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/geom2d/csg2d.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -804,8 +804,8 @@ { for (Edge edgeQ : l2.Edges(SOURCE)) { - double alpha = -1; - double beta = -1; + double alpha = -EPSILON; + double beta = -EPSILON; IntersectionType i = intersect(edgeP, edgeQ, alpha, beta); AddIntersectionPoint(edgeP, edgeQ, i, alpha, beta); if(i==X_INTERSECTION && (edgeP.v0->spline || edgeQ.v0->spline)) @@ -2216,6 +2216,8 @@ seg->reffak = 1; seg->copyfrom = -1; seg->hmax = ls.maxh; + seg->hpref_left = 0.; + seg->hpref_right = 0.; geo->AppendSegment(seg); } t_segments.Stop(); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/geom2d/genmesh2d.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/geom2d/genmesh2d.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/geom2d/genmesh2d.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/geom2d/genmesh2d.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -271,6 +271,7 @@ // add point elements for (auto & point : geompoints) + if (point.name.length()) { Point<3> newp(point(0), point(1), 0); PointIndex npi = mesh2d.AddPoint (newp, 1, FIXEDPOINT); @@ -301,6 +302,11 @@ { npi = mesh2d.AddPoint (newp, layer); searchtree.Insert (newp, npi); + mesh2d.AddLockedPoint(npi); + Element0d el(npi, npi); + el.name = ""; + mesh2d.SetCD2Name(npi, ""); + mesh2d.pointelements.Append (el); } } } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/include/nginterface_v2.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/include/nginterface_v2.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/include/nginterface_v2.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/include/nginterface_v2.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -358,8 +358,8 @@ int GetParentSElement (int ei) const; bool HasParentEdges() const; - tuple> GetParentEdges (int enr) const; - tuple> GetParentFaces (int fnr) const; + std::tuple> GetParentEdges (int enr) const; + std::tuple> GetParentFaces (int fnr) const; int GetNIdentifications() const; int GetIdentificationType(int idnr) const; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/include/nginterface_v2_impl.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/include/nginterface_v2_impl.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/include/nginterface_v2_impl.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/include/nginterface_v2_impl.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -256,35 +256,35 @@ { case 3: { - NgFlatArray ia = mesh->GetTopology().GetVertexElements(vnr); + auto ia = mesh->GetTopology().GetVertexElements(vnr); node.elements.ne = ia.Size(); - node.elements.ptr = (int*)&ia[0]; + node.elements.ptr = (int*)ia.Data(); - NgFlatArray bia = mesh->GetTopology().GetVertexSurfaceElements(vnr); + auto bia = mesh->GetTopology().GetVertexSurfaceElements(vnr); node.bnd_elements.ne = bia.Size(); - node.bnd_elements.ptr = (int*)&bia[0]; + node.bnd_elements.ptr = (int*)bia.Data(); break; } case 2: { - NgFlatArray ia = mesh->GetTopology().GetVertexSurfaceElements(vnr); + auto ia = mesh->GetTopology().GetVertexSurfaceElements(vnr); node.elements.ne = ia.Size(); - node.elements.ptr = (int*)&ia[0]; + node.elements.ptr = (int*)ia.Data(); - NgFlatArray bia = mesh->GetTopology().GetVertexSegments(vnr); + auto bia = mesh->GetTopology().GetVertexSegments(vnr); node.bnd_elements.ne = bia.Size(); - node.bnd_elements.ptr = (int*)&bia[0]; + node.bnd_elements.ptr = (int*)bia.Data(); break; } case 1: { - NgFlatArray ia = mesh->GetTopology().GetVertexSegments(vnr); + auto ia = mesh->GetTopology().GetVertexSegments(vnr); node.elements.ne = ia.Size(); - node.elements.ptr = (int*)&ia[0]; + node.elements.ptr = (int*)ia.Data(); - NgFlatArray bia = mesh->GetTopology().GetVertexPointElements(vnr); + auto bia = mesh->GetTopology().GetVertexPointElements(vnr); node.bnd_elements.ne = bia.Size(); - node.bnd_elements.ptr = (int*)&bia[0]; + node.bnd_elements.ptr = (int*)bia.Data(); break; } default: diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/interface/nginterface.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/interface/nginterface.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/interface/nginterface.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/interface/nginterface.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -1641,19 +1641,19 @@ { case 3: { - NgFlatArray ia = mesh->GetTopology().GetVertexElements(vnr); + auto ia = mesh->GetTopology().GetVertexElements(vnr); for (int i = 0; i < ia.Size(); i++) els[i] = ia[i]+1; break; } case 2: { - NgFlatArray ia = mesh->GetTopology().GetVertexSurfaceElements(vnr); + auto ia = mesh->GetTopology().GetVertexSurfaceElements(vnr); for (int i = 0; i < ia.Size(); i++) els[i] = ia[i]+1; break; } case 1: { - NgFlatArray ia = mesh->GetTopology().GetVertexSegments(vnr); + auto ia = mesh->GetTopology().GetVertexSegments(vnr); for (int i = 0; i < ia.Size(); i++) els[i] = ia[i]+1; break; /* @@ -1933,7 +1933,7 @@ int Ng_GetVertex_Elements( int vnr, int* elems ) { const MeshTopology& topology = mesh->GetTopology(); - NgArrayMem indexArray; + ArrayMem indexArray; topology.GetVertexElements( vnr, indexArray ); for( int i=0; iGetTopology(); - NgArrayMem indexArray; + ArrayMem indexArray; topology.GetVertexSurfaceElements( vnr, indexArray ); for( int i=0; iGetTopology(); - NgArrayMem indexArray; + ArrayMem indexArray; topology.GetVertexElements( vnr, indexArray ); return indexArray.Size(); @@ -1996,7 +1996,7 @@ case 3: { const MeshTopology& topology = mesh->GetTopology(); - NgArrayMem indexArray; + ArrayMem indexArray; topology.GetVertexSurfaceElements( vnr, indexArray ); return indexArray.Size(); } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/interface/nginterface_v2.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/interface/nginterface_v2.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/interface/nginterface_v2.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/interface/nginterface_v2.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -1035,6 +1035,14 @@ case 2: { Point<3> p(hp[0], hp[1],0); + try + { + auto ind = mesh->GetSurfaceElementOfPoint(p, lami, nullptr, + build_searchtree); + return ind - 1; + } + catch(NgException e) // quads not implemented curved yet + { for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) { auto & seg = (*mesh)[si]; @@ -1058,6 +1066,7 @@ return si; } } + } } break; case 3: diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/adfront3.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/adfront3.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/adfront3.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/adfront3.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -787,6 +787,7 @@ bool AdFront3 :: Inside (const Point<3> & p) const { + static Timer timer("AdFront3::Inside"); RegionTimer rt(timer); int cnt; Vec3d n, v1, v2; DenseMatrix a(3), ainv(3); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/boundarylayer.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/boundarylayer.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/boundarylayer.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/boundarylayer.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -743,8 +743,10 @@ } - void GenerateBoundaryLayer2 (Mesh & mesh, int domain, const Array & boundaries, const Array & thicknesses) + int GenerateBoundaryLayer2 (Mesh & mesh, int domain, const Array & thicknesses, bool should_make_new_domain, const Array & boundaries) { + SegmentIndex first_new_seg = mesh.LineSegments().Range().Next(); + int np = mesh.GetNP(); int nseg = mesh.GetNSeg(); int ne = mesh.GetNSE(); @@ -760,12 +762,6 @@ BitArray segs_done(nseg); segs_done.Clear(); - // map for all segments with same points - // points to pair of SegmentIndex, int - // int is type of other segment, either: - // TODO: recognize "end points" of boundary layer and implement closure properly - Array>, SegmentIndex> segmap(mesh.GetNSeg()); - // moved segments Array moved_segs; @@ -806,6 +802,8 @@ max_domain = seg.si; } + int new_domain = max_domain+1; + BitArray active_boundaries(max_edge_nr+1); BitArray active_segments(nseg); active_boundaries.Clear(); @@ -835,12 +833,12 @@ if(!active_segments.Test(segi)) continue; - int new_si = mesh.GetNFD()+1; - FaceDescriptor new_fd(-1, 0, 0, -1); - new_fd.SetBCProperty(new_si); - mesh.AddFaceDescriptor(new_fd); - si_map[si] = new_si; - mesh.SetBCName(new_si-1, "mapped_" + mesh.GetBCName(si-1)); + FaceDescriptor new_fd(0, 0, 0, -1); + new_fd.SetBCProperty(new_domain); + int new_fd_index = mesh.AddFaceDescriptor(new_fd); + si_map[si] = new_domain; + if(should_make_new_domain) + mesh.SetBCName(new_domain-1, "mapped_" + mesh.GetBCName(si-1)); } for(auto si : Range(mesh.LineSegments())) @@ -851,20 +849,7 @@ if(si_map[segi.si] == -1) continue; if(!active_boundaries.Test(segi.epgeominfo[0].edgenr)) continue; - segmap[si].Append(make_pair(si, 0)); moved_segs.Append(si); - for(auto sj : Range(mesh.LineSegments())) - { - if(segs_done.Test(sj)) continue; - const auto& segj = mesh[sj]; - if((segi[0] == segj[0] && segi[1] == segj[1]) || - (segi[0] == segj[1] && segi[1] == segj[0])) - { - segs_done.SetBit(sj); - int type = 0; - segmap[si].Append(make_pair(sj, type)); - } - } } // calculate growth vectors (average normal vectors of adjacent segments at each point) @@ -924,6 +909,127 @@ AddDirection(growthvectors[seg[1]], n); } + ////////////////////////////////////////////////////////////////////////// + // average growthvectors along straight lines to avoid overlaps in corners + BitArray points_done(np+1); + points_done.Clear(); + + for(auto si : moved_segs) + { + auto current_seg = mesh[si]; + auto current_si = si; + + auto first = current_seg[0]; + auto current = -1; + auto next = current_seg[1]; + + if(points_done.Test(first)) + continue; + + Array chain; + chain.Append(first); + + // first find closed loops of segments + while(next != current && next != first) + { + current = next; + points_done.SetBit(current); + chain.Append(current); + for(auto sj : meshtopo.GetVertexSegments( current )) + { + if(!active_segments.Test(sj)) + continue; + + if(sj!=current_si) + { + current_si = sj; + current_seg = mesh[sj]; + + next = current_seg[0] + current_seg[1] - current; + break; + } + } + } + + auto ifirst = 0; + auto n = chain.Size(); + + // angle of adjacent segments at points a[i-1], a[i], a[i+1] + auto getAngle = [&mesh, &growthvectors] (FlatArray a, size_t i) + { + auto n = a.Size(); + auto v0 = growthvectors[a[(i+n-1)%n]]; + auto v1 = growthvectors[a[i]]; + auto v2 = growthvectors[a[(i+1)%n]]; + + auto p0 = mesh[a[(i+n-1)%n]]; + auto p1 = mesh[a[i]]; + auto p2 = mesh[a[(i+1)%n]]; + + v0 = p1-p0; + v1 = p2-p1; + + auto angle = abs(atan2(v1[0], v1[1]) - atan2(v0[0], v0[1])); + if(angle>M_PI) + angle = 2*M_PI-angle; + + return angle; + }; + + // find first corner point + while(getAngle(chain, ifirst) < 1e-5 ) + ifirst = (ifirst+1)%n; + + // Copy points of closed loop in correct order, starting with a corner + Array pis(n+1); + pis.Range(0, n-ifirst) = chain.Range(ifirst, n); + pis.Range(n-ifirst, n) = chain.Range(0, n-ifirst); + pis[n] = pis[0]; + + Array lengths(n); + + for(auto i : Range(n)) + lengths[i] = (mesh[pis[(i+1)%n]] - mesh[pis[i]]).Length(); + + auto averageGrowthVectors = [&] (size_t first, size_t last) + { + if(first+1 >= last) + return; + + double total_len = 0.0; + for(auto l : lengths.Range(first, last)) + total_len += l; + + double len = lengths[first]; + auto v0 = growthvectors[pis[first]]; + auto v1 = growthvectors[pis[last]]; + + for(auto i : Range(first+1, last)) + { + auto pi = pis[i]; + growthvectors[pi] = (len/total_len)*v1 + (1.0-len/total_len)*v0; + len += lengths[i]; + } + }; + + auto icurrent = 0; + + while(icurrent average growth vectors between end points + if(icurrent!=ilast) + averageGrowthVectors(icurrent, ilast); + + icurrent = ilast; + } + } + + ////////////////////////////////////////////////////////////////////// // reduce growthvectors where necessary to avoid overlaps/slim regions const auto getSegmentBox = [&] (SegmentIndex segi) { @@ -969,10 +1075,6 @@ if(Dot(n1, growthvectors[seg1[0]])<0) n1 = -n; if(Dot(n1, growthvectors[seg1[1]])<0) n1 = -n; - // check if angle between normal vectors is less than 180 degrees (cant overlap for opposing directions) -// if(n[0]*n1[1]-n[1]*n1[0]<0.0) -// return; - auto p10 = mesh[seg1[0]]; auto p11 = mesh[seg1[1]]; @@ -1112,22 +1214,22 @@ auto newindex = si_map[seg.si]; - { - Segment s = seg; - s[0] = pm0.Last(); - s[1] = pm1.Last(); - s[2] = PointIndex::INVALID; - auto pair = s[0] < s[1] ? make_pair(s[0], s[1]) : make_pair(s[1], s[0]); - if(seg2edge.find(pair) == seg2edge.end()) - seg2edge[pair] = ++max_edge_nr; - s.edgenr = seg2edge[pair]; - s.si = seg.si; - mesh.AddSegment(s); - - Swap(s[0], s[1]); - s.si = newindex; - mesh.AddSegment(s); - } + Segment s = seg; + s.geominfo[0] = {}; + s.geominfo[1] = {}; + s[0] = pm0.Last(); + s[1] = pm1.Last(); + s[2] = PointIndex::INVALID; + auto pair = s[0] < s[1] ? make_pair(s[0], s[1]) : make_pair(s[1], s[0]); + if(seg2edge.find(pair) == seg2edge.end()) + seg2edge[pair] = ++max_edge_nr; + s.edgenr = seg2edge[pair]; + s.si = seg.si; + mesh.AddSegment(s); + + Swap(s[0], s[1]); + s.si = newindex; + mesh.AddSegment(s); for ( auto i : Range(thicknesses)) { @@ -1167,6 +1269,7 @@ newel[2] = pi2; newel[3] = pi3; newel.SetIndex(si_map[seg.si]); + newel.GeomInfo() = PointGeomInfo{}; // if(swap) // { @@ -1186,9 +1289,7 @@ if(mapto[pi].Size() == 0) continue; auto pnew = mapto[pi].Last(); - NgArray old_els; - meshtopo.GetVertexSurfaceElements( pi, old_els); - for(auto old_sei : old_els) + for(auto old_sei : meshtopo.GetVertexSurfaceElements( pi )) { if(mesh[old_sei].GetIndex() == domain) { @@ -1208,6 +1309,30 @@ mesh.CalcSurfacesOfNode(); Generate2dMesh(mesh, domain); + + // even without new domain, we need temporarily a new domain to mesh the remaining area, without confusing the meshes with quads -> add segments temporarily and reset domain number and segments afterwards + if(!should_make_new_domain) + { + // map new domain back to old one + for(auto & sel : mesh.SurfaceElements()) + if(sel.GetIndex()==new_domain) + sel.SetIndex(domain); + + // remove (temporary) inner segments + for(auto segi : Range(first_new_seg, mesh.LineSegments().Range().Next())) + { + mesh[segi][0].Invalidate(); + mesh[segi][1].Invalidate(); + } + + for(auto segi : moved_segs) + mesh[segi].si = domain; + + mesh.Compress(); + mesh.CalcSurfacesOfNode(); + } + + return new_domain; } } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/boundarylayer.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/boundarylayer.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/boundarylayer.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/boundarylayer.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -24,6 +24,6 @@ DLL_HEADER void GenerateBoundaryLayer (Mesh & mesh, const BoundaryLayerParameters & blp); -DLL_HEADER void GenerateBoundaryLayer2 (Mesh & mesh, int domain, const Array & boundaries, const Array & thicknesses); +DLL_HEADER int /* new_domain_number */ GenerateBoundaryLayer2 (Mesh & mesh, int domain, const Array & thicknesses, bool should_make_new_domain=true, const Array & boundaries=Array{}); #endif diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/clusters.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/clusters.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/clusters.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/clusters.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -16,13 +16,13 @@ ; } - void AnisotropicClusters :: Update(NgTaskManager tm, NgTracer tracer) + void AnisotropicClusters :: Update() { - static int timer = NgProfiler::CreateTimer ("clusters"); + static Timer timer("clusters"); // static int timer1 = NgProfiler::CreateTimer ("clusters1"); // static int timer2 = NgProfiler::CreateTimer ("clusters2"); // static int timer3 = NgProfiler::CreateTimer ("clusters3"); - NgProfiler::RegionTimer reg (timer); + RegionTimer reg (timer); const MeshTopology & top = mesh.GetTopology(); @@ -81,13 +81,14 @@ cluster_reps.Elem(nnums[j]) = nnums[j]; } */ - ParallelForRange - (tm, ne, - [&] (size_t begin, size_t end) + ngcore::ParallelForRange + (mesh.VolumeElements().Range(), + [&] (auto myrange) { NgArray nnums, ednums, fanums; - for (int i = begin+1; i <= end; i++) + for (int i_ : myrange) { + int i = i_+1; const Element & el = mesh.VolumeElement(i); ELEMENT_TYPE typ = el.GetType(); @@ -110,7 +111,7 @@ for (int j = 0; j < nnums.Size(); j++) cluster_reps.Elem(nnums[j]) = nnums[j]; } - }); + }, ngcore::TasksPerThread(4)); // NgProfiler::StopTimer(timer1); // NgProfiler::StartTimer(timer2); @@ -137,13 +138,14 @@ cluster_reps.Elem(nnums[j]) = nnums[j]; } */ - ParallelForRange - (tm, nse, - [&] (size_t begin, size_t end) + ngcore::ParallelForRange + (mesh.SurfaceElements().Range(), + [&] (auto myrange) { NgArrayMem nnums, ednums; - for (int i = begin+1; i <= end; i++) + for (int i_ : myrange) { + int i = i_+1; const Element2d & el = mesh.SurfaceElement(i); ELEMENT_TYPE typ = el.GetType(); @@ -163,7 +165,7 @@ for (int j = 0; j < nnums.Size(); j++) cluster_reps.Elem(nnums[j]) = nnums[j]; } - }); + }, ngcore::TasksPerThread(4)); // NgProfiler::StopTimer(timer2); @@ -215,7 +217,8 @@ do { - (*tracer) ("update cluster, identify", false); + static Timer t("update cluster, identify"); + RegionTimer rtr(t); cnt++; changed = 0; @@ -338,7 +341,6 @@ } */ } - (*tracer) ("update cluster, identify", true); } while (changed); // NgProfiler::StopTimer(timer3); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/clusters.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/clusters.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/clusters.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/clusters.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -27,7 +27,7 @@ AnisotropicClusters (const Mesh & amesh); ~AnisotropicClusters(); - void Update(NgTaskManager tm = &DummyTaskManager, NgTracer trace = &DummyTracer); + void Update(); int GetVertexRepresentant (int vnr) const { return cluster_reps.Get(vnr); } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/CMakeLists.txt ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/CMakeLists.txt --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/CMakeLists.txt 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/CMakeLists.txt 2021-06-04 23:36:22.000000000 +0000 @@ -1,3 +1,19 @@ +# generate .cpp files containing the string of the .rls meshing rule files +add_executable(makerls ${CMAKE_CURRENT_SOURCE_DIR}/../../rules/makerlsfile.cpp) + +set(rules hexrules prismrules2 pyramidrules pyramidrules2 quadrules tetrules triarules) + +foreach(rule ${rules}) + list(APPEND rules_sources rule_${rule}.cpp) + set(rule_file ${CMAKE_CURRENT_SOURCE_DIR}/../../rules/${rule}.rls) + + add_custom_command(OUTPUT rule_${rule}.cpp + COMMAND makerls ${rule_file} rule_${rule}.cpp ${rule} + DEPENDS makerls ${rule_file} + ) +endforeach() + + add_definitions(-DNGINTERFACE_EXPORTS) add_library(mesh ${NG_LIB_TYPE} adfront2.cpp adfront3.cpp bisect.cpp boundarylayer.cpp @@ -6,14 +22,14 @@ improve2gen.cpp improve3.cpp localh.cpp meshclass.cpp meshfunc.cpp meshfunc2d.cpp meshing2.cpp meshing3.cpp meshtool.cpp meshtype.cpp msghandler.cpp netrule2.cpp - netrule3.cpp parser2.cpp parser3.cpp prism2rls.cpp - pyramid2rls.cpp pyramidrls.cpp quadrls.cpp refine.cpp + netrule3.cpp parser2.cpp parser3.cpp refine.cpp ruler2.cpp ruler3.cpp secondorder.cpp smoothing2.5.cpp - smoothing2.cpp smoothing3.cpp specials.cpp tetrarls.cpp - topology.cpp triarls.cpp validate.cpp bcfunctions.cpp + smoothing2.cpp smoothing3.cpp specials.cpp + topology.cpp validate.cpp bcfunctions.cpp parallelmesh.cpp paralleltop.cpp paralleltop.hpp basegeom.cpp - python_mesh.cpp hexarls.cpp surfacegeom.cpp + python_mesh.cpp surfacegeom.cpp ../../ng/onetcl.cpp + ${rules_sources} ${mesh_object_libs} ) diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/delaunay.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/delaunay.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/delaunay.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/delaunay.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -737,136 +737,13 @@ } - - - - - void Meshing3 :: Delaunay (Mesh & mesh, int domainnr, const MeshingParameters & mp) + void DelaunayRemoveDegenerated( const Mesh::T_POINTS & points, NgArray & tempels, int np ) { - static Timer t("Meshing3::Delaunay"); RegionTimer reg(t); - - int np, ne; + static Timer tdegenerated("Delaunay - remove degenerated"); RegionTimer rt(tdegenerated); - PrintMessage (1, "Delaunay meshing"); - PrintMessage (3, "number of points: ", mesh.GetNP()); - PushStatus ("Delaunay meshing"); - - - NgArray tempels; - Point3d pmin, pmax; - - DelaunayTet startel; - - int oldnp = mesh.GetNP(); - if (mp.blockfill) - { - BlockFillLocalH (mesh, mp); - PrintMessage (3, "number of points: ", mesh.GetNP()); - } - - np = mesh.GetNP(); - - Delaunay1 (mesh, mp, adfront, tempels, oldnp, startel, pmin, pmax); - - { - // improve delaunay - mesh by swapping !!!! - - Mesh tempmesh; - tempmesh.GetMemoryTracer().SetName("delaunay-tempmesh"); - - for (auto & meshpoint : mesh.Points()) - tempmesh.AddPoint (meshpoint); - - for (auto & tempel : tempels) - { - Element el(4); - for (int j = 0; j < 4; j++) - el[j] = tempel[j]; - - el.SetIndex (1); - - const Point<3> & lp1 = mesh.Point (el[0]); - const Point<3> & lp2 = mesh.Point (el[1]); - const Point<3> & lp3 = mesh.Point (el[2]); - const Point<3> & lp4 = mesh.Point (el[3]); - Vec<3> v1 = lp2-lp1; - Vec<3> v2 = lp3-lp1; - Vec<3> v3 = lp4-lp1; - - Vec<3> n = Cross (v1, v2); - double vol = n * v3; - if (vol > 0) swap (el[2], el[3]); - - tempmesh.AddVolumeElement (el); - } - - tempels.DeleteAll(); - - MeshQuality3d (tempmesh); - - tempmesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0)); - tempmesh.AddFaceDescriptor (FaceDescriptor (2, 1, 0, 0)); - - - - for (int i = 1; i <= mesh.GetNOpenElements(); i++) - { - Element2d sel = mesh.OpenElement(i); - sel.SetIndex(1); - tempmesh.AddSurfaceElement (sel); - swap (sel[1], sel[2]); - tempmesh.AddSurfaceElement (sel); - } - - - for (int i = 1; i <= 4; i++) - { - Element2d self(TRIG); - self.SetIndex (1); - startel.GetFace (i-1, self); - tempmesh.AddSurfaceElement (self); - } - - - // for (i = mesh.GetNP() - 3; i <= mesh.GetNP(); i++) - // tempmesh.AddLockedPoint (i); - for (auto pi : tempmesh.Points().Range()) - tempmesh.AddLockedPoint (pi); - - // tempmesh.PrintMemInfo(cout); - // tempmesh.Save ("tempmesh.vol"); - - { - RegionTaskManager rtm(mp.parallel_meshing ? mp.nthreads : 0); - for (int i = 1; i <= 4; i++) - { - tempmesh.FindOpenElements (); - - PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); - tempmesh.CalcSurfacesOfNode (); - - tempmesh.FreeOpenElementsEnvironment (1); - - MeshOptimize3d meshopt(mp); - // tempmesh.CalcSurfacesOfNode(); - meshopt.SwapImprove(tempmesh, OPT_CONFORM); - } - } - - MeshQuality3d (tempmesh); - - tempels.SetSize(tempmesh.GetNE()); - tempels.SetSize(0); - for (auto & el : tempmesh.VolumeElements()) - tempels.Append (el); - } - - - - // remove degenerated - - NgBitArray badnode(mesh.GetNP()); + NgBitArray badnode(points.Size()); badnode.Clear(); + int ndeg = 0; for (int i = 1; i <= tempels.Size(); i++) { @@ -874,10 +751,10 @@ for (int j = 0; j < 4; j++) el[j] = tempels.Elem(i)[j]; // Element & el = tempels.Elem(i); - const Point3d & lp1 = mesh.Point (el[0]); - const Point3d & lp2 = mesh.Point (el[1]); - const Point3d & lp3 = mesh.Point (el[2]); - const Point3d & lp4 = mesh.Point (el[3]); + const Point3d & lp1 = points[el[0]]; + const Point3d & lp2 = points[el[1]]; + const Point3d & lp3 = points[el[2]]; + const Point3d & lp4 = points[el[3]]; Vec3d v1(lp1, lp2); Vec3d v2(lp1, lp3); Vec3d v3(lp1, lp4); @@ -901,7 +778,7 @@ Swap (el[2], el[3]); } - ne = tempels.Size(); + auto ne = tempels.Size(); for (int i = ne; i >= 1; i--) { const DelaunayTet & el = tempels.Get(i); @@ -914,166 +791,177 @@ PrintMessage (3, ndeg, " degenerated elements removed"); + } + + // Remove flat tets containing two adjacent surface trigs + void DelaunayRemoveTwoTriaTets( const Mesh & mesh, NgArray & tempels, NgArray & openels ) + { + static Timer topenel("Delaunay - find openel"); RegionTimer rt(topenel); // find surface triangles which are no face of any tet + BitArray bnd_points( mesh.GetNP() + PointIndex::BASE ); + bnd_points.Clear(); - INDEX_3_HASHTABLE openeltab(mesh.GetNOpenElements()+3); - NgArray openels; for (int i = 1; i <= mesh.GetNOpenElements(); i++) { - const Element2d & tri = mesh.OpenElement(i); - INDEX_3 i3(tri[0], tri[1], tri[2]); - i3.Sort(); - openeltab.Set (i3, i); - } + const Element2d & tri = mesh.OpenElement(i); + bnd_points.SetBit(tri[0]); + bnd_points.SetBit(tri[1]); + bnd_points.SetBit(tri[2]); + } + + auto ne = tempels.Size(); + Array tets_with_3_bnd_points(ne); + atomic cnt = 0; + + // table of tets with >= 2 boundary points, store in extra array tets with >=3 boundary points + auto p2el = ngcore::CreateSortedTable( ne, + [&](auto & table, int ei) + { + const auto & el = tempels[ei]; + int num_bnd_points = 0; + + for( auto i : Range(4) ) + if(bnd_points[el[i]]) + num_bnd_points++; + + if(num_bnd_points>1) + { + table.Add (el[0], ei); + table.Add (el[1], ei); + table.Add (el[2], ei); + table.Add (el[3], ei); + } + + // table creator is running this code 2 times, only store tets on last run + if(table.GetMode()==3 && num_bnd_points>2) + tets_with_3_bnd_points[cnt++] = ei; + }, mesh.GetNP()); + + tets_with_3_bnd_points.SetSize(cnt); + + static Timer t1("Build face table"); t1.Start(); + ngcore::ClosedHashTable< ngcore::INT<3>, int > face_table( 4*cnt + 3 ); + for(auto ei : tets_with_3_bnd_points) + for(auto j : Range(4)) + { + auto i3_ = tempels[ei].GetFace (j); + ngcore::INT<3> i3 = {i3_[0], i3_[1], i3_[2]}; + if(bnd_points[i3[0]] && bnd_points[i3[1]] && bnd_points[i3[2]]) + { + i3.Sort(); + face_table.Set( i3, true ); + } + } + t1.Stop(); - for (int i = 1; i <= tempels.Size(); i++) + static Timer t2("check faces"); t2.Start(); + + openels.SetSize(0); + for (int i = 1; i <= mesh.GetNOpenElements(); i++) { - for (int j = 0; j < 4; j++) - { - INDEX_3 i3 = tempels.Get(i).GetFace (j); - i3.Sort(); - if (openeltab.Used(i3)) - openeltab.Set (i3, 0); - } + const Element2d & tri = mesh.OpenElement(i); + ngcore::INT<3> i3(tri[0], tri[1], tri[2]); + i3.Sort(); + if(!face_table.Used(i3)) + openels.Append(i); } - - // and store them in openels - for (int i = 1; i <= openeltab.GetNBags(); i++) - for (int j = 1; j <= openeltab.GetBagSize(i); j++) - { - INDEX_3 i3; - int fnr; - openeltab.GetData (i, j, i3, fnr); - if (fnr) - openels.Append (fnr); - } - - + t2.Stop(); + auto p2sel = ngcore::CreateSortedTable( Range(openels.Size()), + [&](auto & table, int i) + { + auto openel_i = openels[i]; + const Element2d & tri = mesh.OpenElement(openel_i); + table.Add(tri[0], openel_i); + table.Add(tri[1], openel_i); + table.Add(tri[2], openel_i); + }, mesh.GetNP()); - // find open triangle with close edge (from halfening of surface squares) - - INDEX_2_HASHTABLE twotrias(mesh.GetNOpenElements()+5); - // for (i = 1; i <= mesh.GetNOpenElements(); i++) - for (int ii = 1; ii <= openels.Size(); ii++) - { - int i = openels.Get(ii); - const Element2d & el = mesh.OpenElement(i); - for (int j = 1; j <= 3; j++) - { - INDEX_2 hi2 (el.PNumMod (j), el.PNumMod(j+1)); - hi2.Sort(); - if (twotrias.Used(hi2)) - { - INDEX_2 hi3; - hi3 = twotrias.Get (hi2); - hi3.I2() = el.PNumMod (j+2); - twotrias.Set (hi2, hi3); - } - else - { - INDEX_2 hi3(el.PNumMod (j+2), 0); - twotrias.Set (hi2, hi3); - } - } - } - - INDEX_2_HASHTABLE tetedges(tempels.Size() + 5); - for (int i = 1; i <= tempels.Size(); i++) - { - const DelaunayTet & el = tempels.Get(i); - INDEX_2 i2; - for (int j = 1; j <= 6; j++) - { - switch (j) - { - case 1: i2.I1()=el[0]; i2.I2()=el[1]; break; - case 2: i2.I1()=el[0]; i2.I2()=el[2]; break; - case 3: i2.I1()=el[0]; i2.I2()=el[3]; break; - case 4: i2.I1()=el[1]; i2.I2()=el[2]; break; - case 5: i2.I1()=el[1]; i2.I2()=el[3]; break; - case 6: i2.I1()=el[2]; i2.I2()=el[3]; break; - default: i2.I1()=i2.I2()=0; break; - } - i2.Sort(); - tetedges.Set (i2, 1); - } - } - // cout << "tetedges:"; - // tetedges.PrintMemInfo (cout); - + ngcore::BitArray badnode(mesh.GetNP()+PointIndex::BASE); + badnode.Clear(); - for (INDEX_2_HASHTABLE::Iterator it = twotrias.Begin(); - it != twotrias.End(); it++) - { - INDEX_2 hi2, hi3; - twotrias.GetData (it, hi2, hi3); - hi3.Sort(); - if (tetedges.Used (hi3)) - { - const Point3d & p1 = mesh.Point ( PointIndex (hi2.I1())); - const Point3d & p2 = mesh.Point ( PointIndex (hi2.I2())); - const Point3d & p3 = mesh.Point ( PointIndex (hi3.I1())); - const Point3d & p4 = mesh.Point ( PointIndex (hi3.I2())); - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - Vec3d v3(p1, p4); - Vec3d n = Cross (v1, v2); - double vol = n * v3; - - double h = v1.Length() + v2.Length() + v3.Length(); - if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12 - { - badnode.Set(hi3.I1()); - badnode.Set(hi3.I2()); - } - } - } + ngcore::ParallelForRange(openels.Size(), [&] (auto myrange) { + for (auto i_ : myrange) + { + auto i = openels[i_]; + const Element2d & tri = mesh.OpenElement(i); - /* - for (i = 1; i <= twotrias.GetNBags(); i++) - for (j = 1; j <= twotrias.GetBagSize (i); j++) - { - INDEX_2 hi2, hi3; - twotrias.GetData (i, j, hi2, hi3); - hi3.Sort(); - if (tetedges.Used (hi3)) - { - const Point3d & p1 = mesh.Point (hi2.I1()); - const Point3d & p2 = mesh.Point (hi2.I2()); - const Point3d & p3 = mesh.Point (hi3.I1()); - const Point3d & p4 = mesh.Point (hi3.I2()); - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - Vec3d v3(p1, p4); - Vec3d n = Cross (v1, v2); - double vol = n * v3; - - double h = v1.Length() + v2.Length() + v3.Length(); - if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12 - { - badnode.Set(hi3.I1()); - badnode.Set(hi3.I2()); - } - } - } - */ + for( auto edge : Range(3) ) + { + auto pi0 = tri[edge]; + auto pi1 = tri[(edge+1)%3]; + if(pi0>pi1) + Swap(pi0, pi1); + + // find other trig with edge pi0, pi1 + int i_other = -1; + for(auto ii : p2sel[pi0]) + { + if(ii==i) + continue; + auto & tri_other = mesh.OpenElement(ii); + if(tri_other[0]==pi1 || tri_other[1]==pi1 || tri_other[2]==pi1) + { + i_other = ii; + break; + } + } + + if(i_other>i) + { + auto & tri_other = mesh.OpenElement(i_other); + PointIndex pi2 = tri[(edge+2)%3]; + PointIndex pi3 = tri_other[0]+tri_other[1]+tri_other[2] - pi0 - pi1; + if(pi2>pi3) + Swap(pi2, pi3); + + // search for tet with edge pi2-pi3 + for(auto ei : p2el[pi2]) + { + auto & el = tempels[ei]; + + if(el[0]==pi3 || el[1]==pi3 || el[2]==pi3 || el[3]==pi3) + { + const Point3d & p1 = mesh[pi0]; + const Point3d & p2 = mesh[pi1]; + const Point3d & p3 = mesh[pi2]; + const Point3d & p4 = mesh[pi3]; + Vec3d v1(p1, p2); + Vec3d v2(p1, p3); + Vec3d v3(p1, p4); + Vec3d n = Cross (v1, v2); + double vol = n * v3; + + double h = v1.Length() + v2.Length() + v3.Length(); + if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12 + { + badnode.SetBitAtomic(pi2); + badnode.SetBitAtomic(pi3); + } + break; + } + } + } + } + } + }); - ne = tempels.Size(); for (int i = ne; i >= 1; i--) { const DelaunayTet & el = tempels.Get(i); - if (badnode.Test(el[0]) || - badnode.Test(el[1]) || - badnode.Test(el[2]) || - badnode.Test(el[3]) ) + if (badnode[el[0]] || + badnode[el[1]] || + badnode[el[2]] || + badnode[el[3]] ) tempels.DeleteElement(i); } + } - - + void DelaunayRemoveIntersecting( const Mesh & mesh, NgArray & tempels, NgArray & openels, Point3d pmin, Point3d pmax ) + { + static Timer trem_intersect("Delaunay - remove intersecting"); RegionTimer rt(trem_intersect); // find intersecting: PrintMessage (3, "Remove intersecting"); @@ -1188,8 +1076,11 @@ } } } - + } + void DelaunayRemoveOuter( const Mesh & mesh, NgArray & tempels, AdFront3 * adfront ) + { + static Timer trem_outer("Delaunay - remove outer"); RegionTimer rt(trem_outer); PrintMessage (3, "Remove outer"); @@ -1379,7 +1270,7 @@ PrintMessage (5, "tables filled"); - ne = tempels.Size(); + auto ne = tempels.Size(); NgBitArray inner(ne), outer(ne); inner.Clear(); outer.Clear(); @@ -1400,15 +1291,17 @@ } */ + int lowest_undefined_el = 1; while (1) { int inside; bool done = 1; int i; - for (i = 1; i <= ne; i++) + for (i = lowest_undefined_el; i <= ne; i++) if (!inner.Test(i) && !outer.Test(i)) { + lowest_undefined_el = i+1; done = 0; break; } @@ -1633,6 +1526,139 @@ // mesh.points.SetSize(mesh.points.Size()-4); + PrintMessage (5, "outer removed"); + + } + + + + void Meshing3 :: Delaunay (Mesh & mesh, int domainnr, const MeshingParameters & mp) + { + static Timer t("Meshing3::Delaunay"); RegionTimer reg(t); + + int np, ne; + + PrintMessage (1, "Delaunay meshing"); + PrintMessage (3, "number of points: ", mesh.GetNP()); + PushStatus ("Delaunay meshing"); + + + NgArray tempels; + Point3d pmin, pmax; + + DelaunayTet startel; + + int oldnp = mesh.GetNP(); + if (mp.blockfill) + { + BlockFillLocalH (mesh, mp); + PrintMessage (3, "number of points: ", mesh.GetNP()); + } + + np = mesh.GetNP(); + + Delaunay1 (mesh, mp, adfront, tempels, oldnp, startel, pmin, pmax); + + { + // improve delaunay - mesh by swapping !!!! + + Mesh tempmesh; + tempmesh.GetMemoryTracer().SetName("delaunay-tempmesh"); + + for (auto & meshpoint : mesh.Points()) + tempmesh.AddPoint (meshpoint); + + for (auto & tempel : tempels) + { + Element el(4); + for (int j = 0; j < 4; j++) + el[j] = tempel[j]; + + el.SetIndex (1); + + const Point<3> & lp1 = mesh.Point (el[0]); + const Point<3> & lp2 = mesh.Point (el[1]); + const Point<3> & lp3 = mesh.Point (el[2]); + const Point<3> & lp4 = mesh.Point (el[3]); + Vec<3> v1 = lp2-lp1; + Vec<3> v2 = lp3-lp1; + Vec<3> v3 = lp4-lp1; + + Vec<3> n = Cross (v1, v2); + double vol = n * v3; + if (vol > 0) swap (el[2], el[3]); + + tempmesh.AddVolumeElement (el); + } + + tempels.DeleteAll(); + + MeshQuality3d (tempmesh); + + tempmesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0)); + tempmesh.AddFaceDescriptor (FaceDescriptor (2, 1, 0, 0)); + + + + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + { + Element2d sel = mesh.OpenElement(i); + sel.SetIndex(1); + tempmesh.AddSurfaceElement (sel); + swap (sel[1], sel[2]); + tempmesh.AddSurfaceElement (sel); + } + + + for (int i = 1; i <= 4; i++) + { + Element2d self(TRIG); + self.SetIndex (1); + startel.GetFace (i-1, self); + tempmesh.AddSurfaceElement (self); + } + + + // for (i = mesh.GetNP() - 3; i <= mesh.GetNP(); i++) + // tempmesh.AddLockedPoint (i); + for (auto pi : tempmesh.Points().Range()) + tempmesh.AddLockedPoint (pi); + + // tempmesh.PrintMemInfo(cout); + // tempmesh.Save ("tempmesh.vol"); + + { + RegionTaskManager rtm(mp.parallel_meshing ? mp.nthreads : 0); + for (int i = 1; i <= 4; i++) + { + tempmesh.FindOpenElements (); + + PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); + tempmesh.CalcSurfacesOfNode (); + + tempmesh.FreeOpenElementsEnvironment (1); + + MeshOptimize3d meshopt(mp); + // tempmesh.CalcSurfacesOfNode(); + meshopt.SwapImprove(tempmesh, OPT_CONFORM); + } + } + + MeshQuality3d (tempmesh); + + tempels.SetSize(tempmesh.GetNE()); + tempels.SetSize(0); + for (auto & el : tempmesh.VolumeElements()) + tempels.Append (el); + } + + DelaunayRemoveDegenerated(mesh.Points(), tempels, np); + + NgArray openels; + DelaunayRemoveTwoTriaTets(mesh, tempels, openels); + DelaunayRemoveIntersecting(mesh, tempels, openels, pmin, pmax); + DelaunayRemoveOuter(mesh, tempels, adfront); + for (int i = 0; i < tempels.Size(); i++) { Element el(4); @@ -1641,8 +1667,6 @@ mesh.AddVolumeElement (el); } - PrintMessage (5, "outer removed"); - mesh.FindOpenElements(domainnr); mesh.Compress(); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/hexarls.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/hexarls.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/hexarls.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/hexarls.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -namespace netgen -{ -const char * hexrules[] = { -"rule \"Hexa left-right-top\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"flags t;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 } ;\n",\ -"(1, 1, 0) { 1 } ;\n",\ -"(0, 1, 0) { 1 } ;\n",\ -"(0, 0, 1) { 1 } ;\n",\ -"(1, 0, 1) { 1 } ;\n",\ -"(1, 1, 1) { 1 } ;\n",\ -"(0, 1, 1) { 1 } ;\n",\ -"\n",\ -"mapfaces\n",\ -"(4, 3, 2, 1) del;\n",\ -"(3, 7, 6, 2) del;\n",\ -"(7, 8, 5, 6) del;\n",\ -"(8, 4, 1, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 6, 2, 1);\n",\ -"(7, 8, 4, 3);\n",\ -"\n",\ -"elements\n",\ -"(4, 3, 2, 1, 8, 7, 6, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 0.3 P1, 0.3 P2, 0.3 P5, 0.3 P6, -0.05 P3, -0.05 P4, -0.05 P7, -0.05 P8 };\n",\ -"{ 0.3 P3, 0.3 P4, 0.3 P7, 0.3 P8, -0.05 P1, -0.05 P2, -0.05 P5, -0.05 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 0.25 P1, 0.25 P2, 0.25 P5, 0.25 P6, -0.0 P3, -0.0 P4, -0.0 P7, -0.0 P8 };\n",\ -"{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 };\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Hexa left-right-top (10)\"\n",\ -"\n",\ -"quality 10\n",\ -"\n",\ -"flags t;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 } ;\n",\ -"(1, 1, 0) { 1 } ;\n",\ -"(0, 1, 0) { 1 } ;\n",\ -"(0, 0, 1) { 1 } ;\n",\ -"(1, 0, 1) { 1 } ;\n",\ -"(1, 1, 1) { 1 } ;\n",\ -"(0, 1, 1) { 1 } ;\n",\ -"\n",\ -"mapfaces\n",\ -"(4, 3, 2, 1) del;\n",\ -"(3, 7, 6, 2) del;\n",\ -"(7, 8, 5, 6) del;\n",\ -"(8, 4, 1, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 6, 2, 1);\n",\ -"(7, 8, 4, 3);\n",\ -"\n",\ -"elements\n",\ -"(4, 3, 2, 1, 8, 7, 6, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 0.251 P1, 0.251 P2, 0.251 P5, 0.251 P6, -0.05 P3, -0.001 P4, -0.001 P7, -0.001 P8 };\n",\ -"{ 0.251 P3, 0.251 P4, 0.251 P7, 0.251 P8, -0.05 P1, -0.001 P2, -0.001 P5, -0.001 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 0.25 P1, 0.25 P2, 0.25 P5, 0.25 P6, -0.0 P3, -0.0 P4, -0.0 P7, -0.0 P8 };\n",\ -"{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 };\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Hexa left-right-top-front\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"flags t;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 } ;\n",\ -"(1, 1, 0) { 1 } ;\n",\ -"(0, 1, 0) { 1 } ;\n",\ -"(0, 0, 1) { 1 } ;\n",\ -"(1, 0, 1) { 1 } ;\n",\ -"(1, 1, 1) { 1 } ;\n",\ -"(0, 1, 1) { 1 } ;\n",\ -"\n",\ -"mapfaces\n",\ -"(4, 3, 2, 1) del;\n",\ -"(3, 7, 6, 2) del;\n",\ -"(7, 8, 5, 6) del;\n",\ -"(8, 4, 1, 5) del;\n",\ -"(1, 2, 6, 5) del;\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(7, 8, 4, 3);\n",\ -"\n",\ -"elements\n",\ -"(4, 3, 2, 1, 8, 7, 6, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 0.3 P3, 0.3 P4, 0.3 P7, 0.3 P8, -0.05 P1, -0.05 P2, -0.05 P5, -0.05 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 };\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Hexa fill\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"flags t;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 } ;\n",\ -"(1, 1, 0) { 1 } ;\n",\ -"(0, 1, 0) { 1 } ;\n",\ -"(0, 0, 1) { 1 } ;\n",\ -"(1, 0, 1) { 1 } ;\n",\ -"(1, 1, 1) { 1 } ;\n",\ -"(0, 1, 1) { 1 } ;\n",\ -"\n",\ -"mapfaces\n",\ -"(4, 3, 2, 1) del;\n",\ -"(3, 7, 6, 2) del;\n",\ -"(7, 8, 5, 6) del;\n",\ -"(8, 4, 1, 5) del;\n",\ -"(1, 2, 6, 5) del;\n",\ -"(3, 4, 8, 7) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"\n",\ -"elements\n",\ -"(4, 3, 2, 1, 8, 7, 6, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P3 };\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -0}; -} diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/improve2.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/improve2.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/improve2.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/improve2.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -453,7 +453,6 @@ nv, -1, loch); illegal1 += 1-mesh.LegalTrig(el); } - bad1 /= (hasonepi.Size()+hasbothpi.Size()); double bad2 = 0; for (int k = 0; k < hasonepi.Size(); k++) @@ -483,7 +482,6 @@ illegal2 += 1-mesh.LegalTrig(el); } - bad2 /= hasonepi.Size(); if (debugflag) { diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/improve2.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/improve2.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/improve2.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/improve2.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -10,7 +10,7 @@ { { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 1, 3 }, { 2, 3 } }; - int ntasks = 2*ngcore::TaskManager::GetMaxThreads(); + int ntasks = 4*ngcore::TaskManager::GetMaxThreads(); Array>> task_edges(ntasks); ParallelFor(IntRange(ntasks), [&] (int ti) diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/improve3.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/improve3.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/improve3.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/improve3.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -2768,7 +2768,7 @@ candidate_edges[index] = make_tuple(d_badness, i); } } - }); + }, TasksPerThread (4)); auto edges_with_improvement = candidate_edges.Part(0, improvement_counter.load()); QuickSort(edges_with_improvement); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/localh.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/localh.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/localh.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/localh.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -23,6 +23,13 @@ hopt = 2 * h2; } + void GradingBox :: DoArchive(Archive& ar) + { + ar & xmid[0] & xmid[1] & xmid[2] & h2 & father & hopt & + flags.cutboundary & flags.isinner & flags.oldcell & flags.pinner; + for(auto i : Range(8)) + ar & childs[i]; + } BlockAllocator GradingBox :: ball(sizeof (GradingBox)); @@ -93,6 +100,11 @@ root->DeleteChilds(); } + void LocalH :: DoArchive(Archive& ar) + { + ar & root & grading & boxes & boundingbox & dimension; + } + void LocalH :: SetH (Point<3> p, double h) { if (dimension == 2) diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/localh.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/localh.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/localh.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/localh.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -44,10 +44,14 @@ /// GradingBox (const double * ax1, const double * ax2); + /// default constructor for Archive + GradingBox() = default; /// void DeleteChilds(); /// + void DoArchive(Archive& ar); + Point<3> PMid() const { return Point<3> (xmid[0], xmid[1], xmid[2]); } double H2() const { return h2; } @@ -78,7 +82,7 @@ /// double grading; /// - NgArray boxes; + Array boxes; /// Box<3> boundingbox; /// octree or quadtree @@ -89,11 +93,15 @@ /// LocalH (const Box<3> & box, double grading, int adimension = 3) : LocalH (box.PMin(), box.PMax(), grading, adimension) { ; } - /// + /// Default ctor for archive + LocalH() = default; + ~LocalH(); /// void Delete(); /// + void DoArchive(Archive& ar); + /// void SetGrading (double agrading) { grading = agrading; } /// void SetH (Point<3> x, double h); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/meshclass.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/meshclass.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/meshclass.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/meshclass.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -413,6 +413,13 @@ void Mesh :: Save (const string & filename) const { + if (filename.find(".vol.bin") != string::npos) + { + BinaryOutArchive in(filename); + in & const_cast(*this); + return; + } + ostream * outfile; if (filename.find(".vol.gz")!=string::npos) outfile = new ogzstream(filename.c_str()); @@ -872,6 +879,14 @@ void Mesh :: Load (const string & filename) { cout << "filename = " << filename << endl; + + if (filename.find(".vol.bin") != string::npos) + { + BinaryInArchive in(filename); + in & (*this); + return; + } + istream * infile = NULL; if (filename.find(".vol.gz") != string::npos) @@ -916,6 +931,7 @@ void Mesh :: Load (istream & infile) { + static Timer timer("Mesh::Load"); RegionTimer rt(timer); if (! (infile.good()) ) { cout << "cannot load mesh" << endl; @@ -956,6 +972,7 @@ if (strcmp (str, "surfaceelements") == 0 || strcmp (str, "surfaceelementsgi")==0 || strcmp (str, "surfaceelementsuv") == 0) { + static Timer t1("read surface elements"); RegionTimer rt1(t1); infile >> n; PrintMessage (3, n, " surface elements"); @@ -1020,6 +1037,7 @@ if (strcmp (str, "volumeelements") == 0) { + static Timer t1("read volume elements"); RegionTimer rt1(t1); infile >> n; PrintMessage (3, n, " volume elements"); for (i = 1; i <= n; i++) @@ -1045,6 +1063,7 @@ if (strcmp (str, "edgesegments") == 0) { + static Timer t1("read edge segments"); RegionTimer rt1(t1); infile >> n; for (i = 1; i <= n; i++) { @@ -1059,6 +1078,7 @@ if (strcmp (str, "edgesegmentsgi") == 0) { + static Timer t1("read edge segmentsgi"); RegionTimer rt1(t1); infile >> n; for (i = 1; i <= n; i++) { @@ -1073,6 +1093,7 @@ if (strcmp (str, "edgesegmentsgi2") == 0) { + static Timer t1("read edge segmentsgi2"); RegionTimer rt1(t1); int a; infile >> a; n=a; @@ -1106,6 +1127,7 @@ if (strcmp (str, "points") == 0) { + static Timer t1("read points"); RegionTimer rt1(t1); infile >> n; PrintMessage (3, n, " points"); for (i = 1; i <= n; i++) @@ -1122,6 +1144,7 @@ if (strcmp (str, "pointelements") == 0) { + static Timer t1("read point elements"); RegionTimer rt1(t1); infile >> n; PrintMessage (3, n, " pointelements"); for (i = 1; i <= n; i++) @@ -2092,38 +2115,28 @@ t_table.Start(); - TableCreator creator(np); + auto elsonpoint = ngcore::CreateSortedTable( volelements.Range(), + [&](auto & table, ElementIndex ei) + { + const Element & el = (*this)[ei]; + if (dom == 0 || dom == el.GetIndex()) + { + if (el.GetNP() == 4) + { + INDEX_4 i4(el[0], el[1], el[2], el[3]); + i4.Sort(); + table.Add (PointIndex(i4.I1()), ei); + table.Add (PointIndex(i4.I2()), ei); + } + else + { + for (PointIndex pi : el.PNums()) + table.Add(pi, ei); + } + } + }, GetNP()); - for ( ; !creator.Done(); creator++) - // for (ElementIndex ei : Range(VolumeElements())) - ParallelFor - (Range(VolumeElements()), [&] (ElementIndex ei) - { - const Element & el = (*this)[ei]; - if (dom == 0 || dom == el.GetIndex()) - { - if (el.GetNP() == 4) - { - INDEX_4 i4(el[0], el[1], el[2], el[3]); - i4.Sort(); - creator.Add (PointIndex(i4.I1()), ei); - creator.Add (PointIndex(i4.I2()), ei); - } - else - { - for (PointIndex pi : el.PNums()) - creator.Add(pi, ei); - } - } - }); - - auto elsonpoint = creator.MoveTable(); - ParallelFor (Range(elsonpoint), [&] (auto i) - { - QuickSort(elsonpoint[i]); - }); - NgArray numonpoint(np); /* numonpoint = 0; @@ -2373,7 +2386,7 @@ */ - size_t numtasks = ngcore::TaskManager::GetNumThreads(); + size_t numtasks = 4*ngcore::TaskManager::GetNumThreads(); Array> thread_openelements(numtasks); ParallelJob ( [&](TaskInfo & ti) @@ -2498,7 +2511,7 @@ thread_openelements[ti.task_nr].Append (tri); } } - }}); + }}, numtasks); for (auto & a : thread_openelements) for (auto & el : a) @@ -5268,7 +5281,7 @@ //(*testout) << "col1 " << col1 << " col2 " << col2 << " col3 " << col3 << " rhs " << rhs << endl; //(*testout) << "sol " << sol << endl; - if (SurfaceElement(element).GetType() ==TRIG6) + if (SurfaceElement(element).GetType() ==TRIG6 || curvedelems->IsSurfaceElementCurved(element-1)) { netgen::Point<2> lam(1./3,1./3); Vec<3> rhs; @@ -5303,6 +5316,14 @@ sol.X() = lam(0); sol.Y() = lam(1); + + if (SurfaceElement(element).GetType() !=TRIG6 ) + { + sol.Z() = sol.X(); + sol.X() = sol.Y(); + sol.Y() = 1.0 - sol.Z() - sol.X(); + } + } if (sol.X() >= -eps && sol.Y() >= -eps && sol.X() + sol.Y() <= 1+eps) @@ -5679,6 +5700,47 @@ { if (dimension == 2) { + double vlam[3]; + int velement = GetElementOfPoint(p, vlam, NULL, build_searchtree, allowindex); + if(velement == 0) + return 0; + + vlam[2] = 1.-vlam[0] - vlam[1]; + NgArray edges; + topology.GetSurfaceElementEdges(velement, edges); + Array segs(edges.Size()); + for(auto i : Range(edges)) + segs[i] = topology.GetSegmentOfEdge(edges[i]); + + for(auto i : Range(segs)) + { + if(IsInvalid(segs[i])) + continue; + auto& el = SurfaceElement(velement); + if(el.GetType() == TRIG) + { + double seg_lam; + double lam; + auto seg = LineSegment(segs[i]); + for(auto k : Range(3)) + { + if(seg[0] == el[k]) + lam = vlam[k]; + if(seg[1] == el[k]) + seg_lam = vlam[k]; + } + if(1.- seg_lam - lam < 1e-5) + { + // found point close to segment -> use barycentric coordinates directly + lami[0] = lam; + return int(segs[i])+1; + } + } + else + throw NgException("Quad not implemented yet!"); + } + + return 0; throw NgException("GetSurfaceElementOfPoint not yet implemented for 2D meshes"); } else @@ -6483,72 +6545,54 @@ } - Table Mesh :: CreatePoint2ElementTable() const + Table Mesh :: CreatePoint2ElementTable(std::optional points) const { - TableCreator creator(GetNP()); - for ( ; !creator.Done(); creator++) - ngcore::ParallelForRange - (Range(volelements), [&] (auto myrange) - { - for (ElementIndex ei : myrange) - for (PointIndex pi : (*this)[ei].PNums()) - creator.Add (pi, ei); - }); - - auto elementsonnode = creator.MoveTable(); - ngcore::ParallelForRange - (elementsonnode.Range(), [&] (auto myrange) - { - for (PointIndex pi : myrange) - QuickSort(elementsonnode[pi]); - }, ngcore::TasksPerThread(4)); - - return move(elementsonnode); + if(points) + { + const auto & free_points = *points; + return ngcore::CreateSortedTable( volelements.Range(), + [&](auto & table, ElementIndex ei) + { + const auto & el = (*this)[ei]; + + for (PointIndex pi : el.PNums()) + if(free_points[pi]) + table.Add (pi, ei); + }, GetNP()); + } + else + return ngcore::CreateSortedTable( volelements.Range(), + [&](auto & table, ElementIndex ei) + { + const auto & el = (*this)[ei]; + + for (PointIndex pi : el.PNums()) + table.Add (pi, ei); + }, GetNP()); } Table Mesh :: CreatePoint2SurfaceElementTable( int faceindex ) const { static Timer timer("Mesh::CreatePoint2SurfaceElementTable"); RegionTimer rt(timer); - TableCreator creator(GetNP()); - if(faceindex==0) { - for ( ; !creator.Done(); creator++) - ngcore::ParallelForRange - (Range(surfelements), [&] (auto myrange) - { - for (SurfaceElementIndex ei : myrange) + return ngcore::CreateSortedTable( surfelements.Range(), + [&](auto & table, SurfaceElementIndex ei) + { for (PointIndex pi : (*this)[ei].PNums()) - creator.Add (pi, ei); - }, - // ngcore::TasksPerThread(4)); - (surfelements.Size()>100) ? ngcore::TasksPerThread(4) : 1); + table.Add (pi, ei); + }, GetNP()); } - else - { - Array 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(); - ngcore::ParallelForRange - (elementsonnode.Range(), [&] (auto myrange) - { - for (PointIndex pi : myrange) - QuickSort(elementsonnode[pi]); - }, - (surfelements.Size()>100) ? ngcore::TasksPerThread(1) : 1); - return move(elementsonnode); + Array face_els; + GetSurfaceElementsOfFace(faceindex, face_els); + return ngcore::CreateSortedTable( face_els.Range(), + [&](auto & table, size_t i) + { + for (PointIndex pi : (*this)[face_els[i]].PNums()) + table.Add (pi, face_els[i]); + }, GetNP()); } @@ -6683,7 +6727,7 @@ static Timer t("Update Topology"); RegionTimer reg(t); topology.Update(tm, tracer); (*tracer)("call update clusters", false); - clusters->Update(tm, tracer); + clusters->Update(); (*tracer)("call update clusters", true); #ifdef PARALLEL if (paralleltop) diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/meshclass.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/meshclass.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/meshclass.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/meshclass.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -772,7 +772,7 @@ - Table CreatePoint2ElementTable() const; + Table CreatePoint2ElementTable(std::optional points = std::nullopt) const; Table CreatePoint2SurfaceElementTable( int faceindex=0 ) const; DLL_HEADER bool PureTrigMesh (int faceindex = 0) const; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/meshtype.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/meshtype.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/meshtype.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/meshtype.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -406,7 +406,7 @@ PointGeomInfo geominfo[ELEMENT2D_MAXPOINTS]; /// surface nr - short int index; + int index; /// ELEMENT_TYPE typ; /// number of points @@ -446,7 +446,7 @@ pnum[cnt++] = val; return *this; } - Element2d & operator= (initializer_list> list) + Element2d & operator= (initializer_list> list) { size_t cnt = 0; for (auto val : list) @@ -738,7 +738,7 @@ }; /// sub-domain index - short int index; + int index; /// order for hp-FEM unsigned int orderx:6; unsigned int ordery:6; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/parallelmesh.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/parallelmesh.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/parallelmesh.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/parallelmesh.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -628,7 +628,7 @@ bool has_ided_sels = false; if(GetNE() && has_periodic) //we can only have identified surf-els if we have vol-els (right?) { - NgArray os1, os2; + Array os1, os2; for(SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) { if(ided_sel[sei]!=-1) continue; @@ -647,7 +647,7 @@ os2.Append(GetTopology().GetVertexSurfaceElements(ided2[l])); for (int m = 0; m buf; // for distributing geometry! int strs; if( id == 0) { - - if (filename.substr (filename.length()-3, 3) == ".gz") + if (filename.substr (filename.length()-8, 8) == ".vol.bin") + mesh -> Load(filename); + else if (filename.substr (filename.length()-3, 3) == ".gz") infile = new igzstream (filename.c_str()); else infile = new ifstream (filename.c_str()); - mesh -> Load(*infile); - // make string from rest of file (for geometry info!) - // (this might be empty, in which case we take the global ng_geometry) - stringstream geom_part; - geom_part << infile->rdbuf(); - string geom_part_string = geom_part.str(); - strs = geom_part_string.size(); - // buf = new char[strs]; - buf.SetSize(strs); - memcpy(&buf[0], geom_part_string.c_str(), strs*sizeof(char)); + if(infile) + { + mesh -> Load(*infile); + // make string from rest of file (for geometry info!) + // (this might be empty, in which case we take the global ng_geometry) + stringstream geom_part; + geom_part << infile->rdbuf(); + string geom_part_string = geom_part.str(); + strs = geom_part_string.size(); + // buf = new char[strs]; + buf.SetSize(strs); + memcpy(&buf[0], geom_part_string.c_str(), strs*sizeof(char)); + delete infile; + } - delete infile; if (ntasks > 1) { @@ -1127,22 +1131,14 @@ )delimiter") + .def_static ("EnableTableClass", [] (string name, bool set) + { + MeshTopology::EnableTableStatic(name, set); + }, + py::arg("name"), py::arg("set")=true) .def ("EnableTable", [] (Mesh & self, string name, bool set) { const_cast(self.GetTopology()).EnableTable(name, set); - /* - if (name == "edges") - const_cast(self.GetTopology()).SetBuildEdges(set); - else if (name == "faces") - const_cast(self.GetTopology()).SetBuildFaces(set); - else if (name == "parentedges") - const_cast(self.GetTopology()).SetBuildParentEdges(set); - else if (name == "parentfaces") - const_cast(self.GetTopology()).SetBuildParentFaces(set); - else - throw Exception ("noting known about table "+name +"\n" - "knwon are 'edges', 'faces', 'parentedges', 'parentfaces'"); - */ }, py::arg("name"), py::arg("set")=true) @@ -1300,7 +1296,7 @@ SetGlobalMesh (mesh); mesh->SetGeometry(geo); ng_geometry = geo; - auto result = geo->GenerateMesh (mesh, quads, nx, ny, flip_triangles, bbbpts, bbbname, hppts, hpptsfac, hpbnd, hpbndfac); + auto result = geo->GenerateStructuredMesh (mesh, quads, nx, ny, flip_triangles, bbbpts, bbbname, hppts, hpptsfac, hpbnd, hpbndfac); if(result != 0) throw Exception("SurfaceGeometry: Meshing failed!"); return mesh; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/quadrls.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/quadrls.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/quadrls.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/quadrls.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,887 +0,0 @@ -namespace netgen -{ -const char * quadrules[] = { -"rule \"Free Quad (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2 } { };\n",\ -"(0, 1) { } { };\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"(4, 3);\n",\ -"(1, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2 } { };\n",\ -"(-0.5, 1.5) { -0.5 X2 } { };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Quad (5)\"\n",\ -"\n",\ -"quality 5\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2 } { };\n",\ -"(0, 1) { } { };\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"(4, 3);\n",\ -"(1, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2 } { };\n",\ -"(-0.5, 1.5) { -0.5 X2 } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X2 } { };\n",\ -"(0, 1) { } { };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Quad Right (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 1) { } { 1 y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.5, 1.5) { } { 1.5 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Quad P Right (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 1) { -1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { -1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Quad P Right (150)\"\n",\ -"\n",\ -"quality 150\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4)\n;",\ -"(4, 3)\n;",\ -"(3, 2)\n;",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Quad Right PL (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(-0.2, 0.5) { -0.1 X2, -0.1 X3, 0.6 X4 } { -0.1 Y2, -0.1 Y3, 0.6 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3);\n",\ -"(1, 3, 4);\n",\ -"(1, 2, 4);\n",\ -"(4, 2, 3);\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Quad (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left P Quad (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 0.5) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left P Quad (150)\"\n",\ -"\n",\ -"quality 150\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 0.5) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Quad RP (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0, 1);\n",\ -"(1, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.5) { 0.6 X2, 0.6 X4, -0.1 X3 } { 0.6 Y2, 0.6 Y4, -0.1 Y3 };\n",\ -"(1, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X4 } { 0.5 Y2, 0.5 Y4 };\n",\ -"(1, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 4);\n",\ -"(1, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Two left (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"(4, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Two Right (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 120 (1)\"\n",\ -"\n",\ -"quality 1000\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left 120 (1)\"\n",\ -"\n",\ -"quality 1000\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(-0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { -1 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Right (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(4, 1) del;\n",\ -"\n",\ -"\n",\ -"newlines\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1.5) { -0.25 X2, 0.75 X3, 0.75 X4 } { 0.75 Y3, 0.75 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Fill Quad\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 4) del;\n",\ -"(4, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Fill Triangle\"\n",\ -"\n",\ -"quality 10\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.86);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(0.5, 0.86) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 60 (1)\"\n",\ -"\n",\ -"quality 10\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 0.5, 0, 1.0 };\n",\ -"(0.5, 0.866) { 0.6, 0, 0.8 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Vis A Vis (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"orientations\n",\ -"(1, 3, 4);\n",\ -"(2, 3, 4);\n",\ -"(1, 2, 3);\n",\ -"(1, 2, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Triangle Vis A Vis (200)\"\n",\ -"\n",\ -"quality 200\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"2 h Vis A Vis (1)\"\n",\ -"\n",\ -"quality 3000\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1.732);\n",\ -"(0, 1.732);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 5);\n",\ -"(5, 4);\n",\ -"(3, 5);\n",\ -"(5, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1.732) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1.732) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 5);\n",\ -"(3, 4, 5);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -0}; -} diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/refine.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/refine.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/refine.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/refine.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -34,6 +34,9 @@ mesh.mlbetweennodes = INDEX_2(PointIndex::BASE-1,PointIndex::BASE-1); } + if (mesh.level_nv.Size() == 0) + mesh.level_nv.Append (mesh.GetNV()); + INDEX_2_HASHTABLE between(mesh.GetNP() + 5); @@ -74,6 +77,32 @@ } break; } + case QUAD: + { + static int betw[5][3] = + { { 0, 1, 4 }, + { 1, 2, 5 }, + { 2, 3, 6 }, + { 0, 3, 7 }, + { 0, 2, 8 } }; // one diagonal of the quad. should change later to mid-point of edge mid-points + for (int j = 0; j < 5; j++) + { + auto i2 = PointIndices<2>::Sort(el[betw[j][0]],el[betw[j][1]]); + if (j == 4) + { + auto i2a = PointIndices<2>::Sort(el[0], el[2]); + auto i2b = PointIndices<2>::Sort(el[1], el[3]); + i2 = i2a[0] < i2b[0] ? i2a : i2b; + } + if (!between.Used(i2)) + { + between.Set (i2, 0); + parents.Append(i2); + } + } + break; + } + default: throw NgException ("currently refinement for quad-elements is not supported"); } @@ -122,7 +151,7 @@ between.Set (parents[i], mesh.GetNV()+i+PointIndex::BASE); mesh.mlbetweennodes[mesh.GetNV()+i+PointIndex::BASE] = parents[i]; } - + mesh.SetNP(mesh.GetNV() + parents.Size()); NgArray pointset(mesh.GetNP()); pointset = false; @@ -278,70 +307,76 @@ case QUAD6: case QUAD8: { - NgArrayMem pnums(9); - NgArrayMem pgis(9); + PointIndex pnums[9]; + PointGeomInfo pgis[9]; static int betw[5][3] = - { { 1, 2, 5 }, + { { 0, 1, 4 }, + { 1, 2, 5 }, { 2, 3, 6 }, - { 3, 4, 7 }, - { 1, 4, 8 }, - { 5, 7, 9 } }; - - for (int j = 1; j <= 4; j++) + { 0, 3, 7 }, + { 0, 2, 8 } }; + + for (int j = 0; j < 4; j++) { - pnums.Elem(j) = el.PNum(j); - pgis.Elem(j) = el.GeomInfoPi(j); + pnums[j] = el[j]; + pgis[j] = el.GeomInfoPi(j+1); } for (int j = 0; j < 5; j++) { - int pi1 = pnums.Elem(betw[j][0]); - int pi2 = pnums.Elem(betw[j][1]); + int pi1 = pnums[betw[j][0]]; + int pi2 = pnums[betw[j][1]]; INDEX_2 i2 (pi1, pi2); i2.Sort(); + + if (j == 4) + { + auto i2a = PointIndices<2>::Sort(el[0], el[2]); + auto i2b = PointIndices<2>::Sort(el[1], el[3]); + i2 = i2a[0] < i2b[0] ? i2a : i2b; + } - if (between.Used(i2)) - { - pnums.Elem(5+j) = between.Get(i2); - pgis.Elem(5+j) = surfgi.Get(pnums.Elem(4+j)); - } - else - { - Point<3> pb; - geo.PointBetween(mesh.Point (pi1), - mesh.Point (pi2), 0.5, - mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), - el.GeomInfoPi (betw[j][0]), - el.GeomInfoPi (betw[j][1]), - pb, pgis.Elem(5+j)); - - pnums.Elem(5+j) = mesh.AddPoint (pb); - - between.Set (i2, pnums.Get(5+j)); - - if (surfgi.Size() < pnums.Elem(5+j)) - surfgi.SetSize (pnums.Elem(5+j)); - surfgi.Elem(pnums.Elem(5+j)) = pgis.Elem(5+j); - } - } + Point<3> pb; + PointGeomInfo pgi; + geo.PointBetween(mesh.Point (pi1), mesh.Point (pi2), 0.5, + mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), + el.GeomInfoPi (betw[j][0]+1 ), + el.GeomInfoPi (betw[j][1]+1 ), + pb, pgi); + + pgis[4+j] = pgi; + PointIndex pinew = between.Get(i2); + pnums[4+j] = pinew; + + if (!pointset[pinew]) + { + pointset[pinew] = true; + mesh.Point(pinew) = pb; + } + + if (surfgi.Size() < pnums[4+j]) + surfgi.SetSize (pnums[4+j]); + surfgi.Elem(pnums[4+j]) = pgis[4+j]; + } static int reftab[4][4] = { - { 1, 5, 9, 8 }, - { 5, 2, 6, 9 }, - { 8, 9, 7, 4 }, - { 9, 6, 3, 7 } }; + { 0, 4, 8, 7 }, + { 4, 1, 5, 8 }, + { 7, 8, 6, 3 }, + { 8, 5, 2, 6 } }; + int ind = el.GetIndex(); for (int j = 0; j < 4; j++) { Element2d nel(QUAD); - for (int k = 1; k <= 4; k++) + for (int k = 0; k < 4; k++) { - nel.PNum(k) = pnums.Get(reftab[j][k-1]); - nel.GeomInfoPi(k) = pgis.Get(reftab[j][k-1]); + nel[k] = pnums[reftab[j][k]]; + nel.GeomInfoPi(k+1) = pgis[reftab[j][k]]; } nel.SetIndex(ind); @@ -739,6 +774,7 @@ mesh.ComputeNVertices(); mesh.RebuildSurfaceElementLists(); + mesh.level_nv.Append (mesh.GetNV()); #ifdef PARALLEL if (mesh.GetCommunicator().Size() > 1) @@ -748,7 +784,7 @@ mesh.GetParallelTopology().EnumeratePointsGlobally(); } #endif - + PrintMessage (5, "mesh updates complete"); return; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/surfacegeom.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/surfacegeom.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/surfacegeom.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/surfacegeom.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -223,7 +223,7 @@ //ProjectPointGI(surfi, newp, newgi); } - int SurfaceGeometry :: GenerateMesh(shared_ptr & mesh, bool quads, int nx, int ny, bool flip_triangles, const Array>& bbbpts, const Array& bbbnames, const Array>& hppoints, const Array& hpptsfac, const Array& hpbnd, const Array& hpbndfac) + int SurfaceGeometry :: GenerateStructuredMesh(shared_ptr & mesh, bool quads, int nx, int ny, bool flip_triangles, const Array>& bbbpts, const Array& bbbnames, const Array>& hppoints, const Array& hpptsfac, const Array& hpbnd, const Array& hpbndfac) { mesh->SetDimension(3); diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/surfacegeom.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/surfacegeom.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/surfacegeom.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/surfacegeom.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -62,7 +62,7 @@ const PointGeomInfo & gi2, Point<3> & newp, PointGeomInfo & newgi) const override; - int GenerateMesh(shared_ptr & mesh, bool quads, int nx, int ny, bool flip_triangles, const Array>& bbbpts, const Array& bbbnames, const Array>& hppoints, const Array& hpptsfac, const Array& hpbnd, const Array& hpbndfac); + int GenerateStructuredMesh(shared_ptr & mesh, bool quads, int nx, int ny, bool flip_triangles, const Array>& bbbpts, const Array& bbbnames, const Array>& hppoints, const Array& hpptsfac, const Array& hpbnd, const Array& hpbndfac); }; diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/tetrarls.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/tetrarls.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/tetrarls.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/tetrarls.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1466 +0,0 @@ -namespace netgen -{ -const char * tetrules[] = { -"tolfak 0.5\n",\ -"\n",\ -"rule \"Free Tetrahedron\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(0.5, 0.866, 0);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.816)\n",\ -" { 0.333 X1, 0.333 X2, 0.333 X3 }\n",\ -" { 0.333 Y1, 0.333 Y2, 0.333 Y3 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(4, 1, 2);\n",\ -"(4, 2, 3);\n",\ -"(4, 3, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1.6 P4, -0.2 P1, -0.2 P2, -0.2 P3 };\n",\ -"{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 60\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"flags c;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 } ;\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"(4, 2, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ -"\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.65 P3, 0.35 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 60 with edge(1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"flags c;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.8 };\n",\ -"(0.5, 0.866, 0) { 0.8 };\n",\ -"(0.5, 0.288, -0.816) { 0.8 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"mapedges\n",\ -"(3, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"(4, 2, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 };\n",\ -"{ 0.4 P2, 0.4 P4, 0.4 P3, -0.2 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P4, 0.3334 P3 };\n",\ -"{ 0.3333 P2, 0.3333 P4, 0.3334 P3 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point (1)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 };\n",\ -"{ 0.8 P1, -0.1 P2, -0.1 P3, 0.4 P4 };\n",\ -"{ -0.1 P1, 0.8 P2, -0.1 P3, 0.4 P4 };\n",\ -"{ -0.1 P1, -0.1 P2, 0.8 P3, 0.4 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"{ 0.7 P1, 0.3 P4 };\n",\ -"{ 0.7 P2, 0.3 P4 };\n",\ -"{ 0.7 P3, 0.3 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point with edge(1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"mapedges\n",\ -"(1, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ -"{ -0.05 P1, 0.7 P2, -0.05 P3, 0.4 P4 };\n",\ -"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"{ 0.65 P2, 0.35 P4 };\n",\ -"{ 0.65 P3, 0.35 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point with 2 edges (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"mapedges\n",\ -"(1, 4);\n",\ -"(2, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ -"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"{ 0.65 P3, 0.35 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point with 3 edges (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"mapedges\n",\ -"(1, 4);\n",\ -"(2, 4);\n",\ -"(3, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Triangle (1)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0, 0, -0.816) { 0.5 };\n",\ -"(1, 0, -0.816) { 0.5 };\n",\ -"(0.5, 0.866, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(4, 6, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 4);\n",\ -"(2, 5, 4);\n",\ -"(2, 3, 6);\n",\ -"(2, 6, 5);\n",\ -"(3, 1, 4);\n",\ -"(3, 4, 6);\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"(4, 2, 3, 6);\n",\ -"(4, 2, 6, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ -0.2 P1, 0.35 P2, 0.35 P3, -0.2 P4, 0.35 P5, 0.35 P6 };\n",\ -"{ 0.35 P1, -0.2 P2, 0.35 P3, 0.35 P4, -0.2 P5, 0.35 P6 };\n",\ -"{ 0.35 P1, 0.35 P2, -0.2 P3, 0.35 P4, 0.35 P5, -0.2 P6 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Octaeder 1\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.95 };\n",\ -"(0.5, 0.866, 0) { 0.95 };\n",\ -"(0.5, -0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(2, 3, 5);\n",\ -"(3, 1, 6);\n",\ -"(3, 6, 5);\n",\ -"(2, 5, 4);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 4, 1, 2);\n",\ -"(3, 4, 2, 5);\n",\ -"(3, 4, 5, 6);\n",\ -"(3, 4, 6, 1);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 };\n",\ -"( 1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Octaeder 2\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.95 };\n",\ -"(0.5, 0.866, 0) { 0.95 };\n",\ -"(0.5, -0.288, -0.816) { 0.5 };\n",\ -"(1, 0.578, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(2, 3, 5);\n",\ -"(3, 1, 6);\n",\ -"(3, 6, 5);\n",\ -"(2, 5, 4);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 4, 1, 2);\n",\ -"(3, 4, 2, 5);\n",\ -"(3, 4, 5, 6);\n",\ -"(3, 4, 6, 1);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ -"\n",\ -"(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 }\n",\ -" { 0.333 Y2, 0.333 Y4, 0.333 Y5 }\n",\ -" { 0.333 Z2, 0.333 Z4, 0.333 Z5 };\n",\ -"(0.9, 0.481, -0.272) { 0.333 X2, 0.333 X3, 0.333 X5 }\n",\ -" { 0.333 Y2, 0.333 Y3, 0.333 Y5 }\n",\ -" { 0.333 Z2, 0.333 Z3, 0.333 Z5 };\n",\ -"\n",\ -"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Octaeder 2a\"\n",\ -"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.95 };\n",\ -"(0.5, 0.866, 0) { 0.95 };\n",\ -"(0.5, -0.288, -0.816) { 0.5 };\n",\ -"(1, 0.578, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(3, 2, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 0.578, -0.816)\n",\ -" { -1 X2, 1 X3, 1 X4 }\n",\ -" { -1 Y2, 1 Y3, 1 Y4 }\n",\ -" { -1 Z2, 1 Z3, 1 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 4);\n",\ -"(3, 1, 6);\n",\ -"(3, 6, 5);\n",\ -"(2, 5, 4);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 4, 1, 2);\n",\ -"(3, 4, 2, 5);\n",\ -"(3, 4, 5, 6);\n",\ -"(3, 4, 6, 1);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ -"\n",\ -"(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 }\n",\ -" { 0.333 Y2, 0.333 Y4, 0.333 Y5 }\n",\ -" { 0.333 Z2, 0.333 Z4, 0.333 Z5 };\n",\ -"\n",\ -"(0.5, -0.097, -0.272) { 0.333 X2, 0.333 X4, 0.333 X1 }\n",\ -" { 0.333 Y2, 0.333 Y4, 0.333 Y1 }\n",\ -" { 0.333 Z2, 0.333 Z4, 0.333 Z1 };\n",\ -"\n",\ -"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Pyramid 1\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.288, -0.816) { 1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"(2, 3, 5);\n",\ -"(2, 5, 4);\n",\ -"(4, 5, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"(4, 2, 3, 5);\n",\ -"\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(0, 1, -1) { 0.5 X3, 0.5 X4 } { 1 Y3 } { 1 Z4 };\n",\ -"(1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 2 times 60\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.3 };\n",\ -"(0.5, 0.866, 0) { 0.3 };\n",\ -"(0.5, 0.288, -0.816) { 0.3 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(2, 4, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Fill Tetrahedron (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.2 };\n",\ -"(0.5, 0.866, 0) { 0.2 };\n",\ -"(0.5, 0.288, -0.816) { 0.2 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(2, 4, 3) del;\n",\ -"(3, 4, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.674, -0.544) { 1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.816)\n",\ -" { -0.5 X1, -0.5 X2, 1 X3, 1 X4 }\n",\ -" { -0.5 Y1, -0.5 Y2, 1 Y3, 1 Y4}\n",\ -" { -0.5 Z1, -0.5 Z2, 1 Z3, 1 Z4};\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 3);\n",\ -"(3, 5, 2);\n",\ -"(1, 4, 5);\n",\ -"(2, 5, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 4, 2, 5);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.3 P5, -0.3 P1 };\n",\ -"{ 1.3 P5, -0.3 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P5 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 2 times 120 (1)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.674, -0.544) { 0.8 };\n",\ -"(1.334, 0.77, -0.544) { 0.8 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(3, 2, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.816) { 0.25 X1, -0.5 X2, 0.25 X3, 0.5 X4, 0.5 X5 }\n",\ -" { 0.25 Y1, -0.5 Y2, 0.25 Y3, 0.5 Y4, 0.5 Y5 }\n",\ -" { 0.25 Z1, -0.5 Z2, 0.25 Z3, 0.5 Z4, 0.5 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(6, 3, 1);\n",\ -"(6, 1, 4);\n",\ -"(6, 4, 2);\n",\ -"(6, 2, 5);\n",\ -"(6, 5, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(2, 5, 3, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.4 P6, -0.4 P2 };\n",\ -"{ 1.4 P6, -0.4 P1 };\n",\ -"{ 1.4 P6, -0.4 P3 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (4)\"\n",\ -"\n",\ -"quality 4\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.1 };\n",\ -"(0.5, 1, 0) { 0.1 };\n",\ -"(0.5, 0, -1) { 0.1 };\n",\ -"(0.5, 0.3, -0.3) { 0.1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 5, 4) del;\n",\ -"(1, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.1, -0.1)\n",\ -" { 0.333 X1, 0.333 X2, 0.334 X5 }\n",\ -" { 0.333 Y1, 0.333 Y2, 0.334 Y5 }\n",\ -" { 0.333 Z1, 0.333 Z2, 0.334 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(6, 2, 3) del;\n",\ -"(6, 4, 2) del;\n",\ -"(6, 5, 4) del;\n",\ -"(6, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(1, 5, 4, 6);\n",\ -"(1, 3, 5, 6);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.5 P6, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 6 2 3;\n",\ -"\n",\ -"freeset\n",\ -"1 6 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 6 5 4;\n",\ -"\n",\ -"freeset\n",\ -"1 6 4 2;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"five Tetrahedron non convex (4)\"\n",\ -"\n",\ -"quality 4\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0, 0.8, -0.2) { 0.5 };\n",\ -"(0, 0.2, -0.8) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 3, 4) del;\n",\ -"(1, 4, 5) del;\n",\ -"(1, 5, 6) del;\n",\ -"(1, 6, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.1, 0.1, -0.1)\n",\ -" { 0.75 X1, 0.05 X2, 0.05 X3, 0.05 X4, 0.05 X5, 0.05 X6 }\n",\ -" { 0.75 Y1, 0.05 Y2, 0.05 Y3, 0.05 Y4, 0.05 Y5, 0.05 Y6 }\n",\ -" { 0.75 Z1, 0.05 Z2, 0.05 Z3, 0.05 Z4, 0.05 Z5, 0.05 Z6 };\n",\ -"\n",\ -"newfaces\n",\ -"(7, 2, 3);\n",\ -"(7, 3, 4);\n",\ -"(7, 4, 5);\n",\ -"(7, 5, 6);\n",\ -"(7, 6, 2);\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 7);\n",\ -"(1, 3, 4, 7);\n",\ -"(1, 4, 5, 7);\n",\ -"(1, 5, 6, 7);\n",\ -"(1, 6, 2, 7);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1.5 P7, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P7 };\n",\ -"\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 7 2 3;\n",\ -"\n",\ -"freeset\n",\ -"1 7 3 4;\n",\ -"\n",\ -"freeset\n",\ -"1 7 4 5;\n",\ -"\n",\ -"freeset\n",\ -"1 7 5 6;\n",\ -"\n",\ -"freeset\n",\ -"1 7 6 2;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 6\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"(0.5, 0.3, -0.3) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 5, 4) del;\n",\ -"(1, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"newpoints\n",\ -"(0.095, 0.003, -0.003)\n",\ -" { 0.9 X1, 0.09 X2, 0.01 X5 }\n",\ -" { 0.9 Y1, 0.09 Y2, 0.01 Y5 }\n",\ -" { 0.9 Z1, 0.09 Z2, 0.01 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(6, 2, 3) del;\n",\ -"(6, 4, 2) del;\n",\ -"(6, 5, 4) del;\n",\ -"(6, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(1, 5, 4, 6);\n",\ -"(1, 3, 5, 6);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.499 P6, -0.5 P1, 0.001 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 6 2 3;\n",\ -"\n",\ -"freeset\n",\ -"1 6 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 6 5 4;\n",\ -"\n",\ -"freeset\n",\ -"1 6 4 2;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"(0.5, 0.4, -0.4) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(4, 5, 2) del;\n",\ -"(5, 3, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.925, 0.02, -0.02)\n",\ -" { 0.05 X1, 0.9 X2, 0.05 X5 }\n",\ -" { 0.05 Y1, 0.9 Y2, 0.05 Y5 }\n",\ -" { 0.05 Z1, 0.9 Z2, 0.05 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(3, 1, 6);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"(5, 3, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 1, 2, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(4, 5, 2, 6);\n",\ -"(5, 3, 2, 6);\n",\ -"\n",\ -"orientations\n",\ -"(3, 1, 2, 5);\n",\ -"(1, 4, 2, 5);\n",\ -"(2, 4, 5, 1);\n",\ -"(3, 2, 5, 1);\n",\ -"(5, 4, 2, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.5 P6, -0.5 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"freeset\n",\ -"3 1 2 6;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 6;\n",\ -"\n",\ -"freeset\n",\ -"4 5 2 6;\n",\ -"\n",\ -"freeset\n",\ -"5 3 2 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"three Tetrahedron non convex (4)\"\n",\ -"\n",\ -"quality 4\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.25, -0.25)\n",\ -" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 }\n",\ -" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 }\n",\ -" { 0.25 Z1, 0.25 Z2, 0.25 Z3, 0.25 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3);\n",\ -"(5, 4, 2);\n",\ -"(5, 3, 4);\n",\ -"\n",\ -"elements\n",\ -"(2, 3, 1, 5);\n",\ -"(3, 4, 1, 5);\n",\ -"(4, 2, 1, 5;\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.5 P5, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"three Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.2, 0.1, -0.1)\n",\ -" { 0.7 X1, 0.1 X2, 0.1 X3, 0.1 X4 }\n",\ -" { 0.7 Y1, 0.1 Y2, 0.1 Y3, 0.1 Y4 }\n",\ -" { 0.7 Z1, 0.1 Z2, 0.1 Z3, 0.1 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3);\n",\ -"(5, 4, 2);\n",\ -"(5, 3, 4);\n",\ -"\n",\ -"elements\n",\ -"(2, 3, 1, 5);\n",\ -"(3, 4, 1, 5);\n",\ -"(4, 2, 1, 5;\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.5 P5, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"(0.5, 0.4, -0.4) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(4, 5, 2) del;\n",\ -"(5, 3, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.7, 0.08, -0.08) { 0.6 X2, 0.2 X5 } { 0.2 Y5 } { 0.2 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(3, 1, 6);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"(5, 3, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 1, 2, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(4, 5, 2, 6);\n",\ -"(5, 3, 2, 6);\n",\ -"\n",\ -"\n",\ -"orientations\n",\ -"(3, 1, 2, 5);\n",\ -"(5, 1, 2, 4);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 1, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, 0, -1) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(0.5, 0.4, -0.4) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ -"(0.55, 0.12, -0.12) { 0.4 X2, 0.3 X5 } { 0.3 Y5 } { 0.3 Z5 };\n",\ -"\n",\ -"freeset\n",\ -"3 1 2 6;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 6;\n",\ -"\n",\ -"freeset\n",\ -"4 5 2 6;\n",\ -"\n",\ -"freeset\n",\ -"5 3 2 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 2 in 60 (12)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.1, -0.1)\n",\ -" { 0.4 X1, 0.4 X2, 0.1 X3, 0.1 X4 }\n",\ -" { 0.4 Y1, 0.4 Y2, 0.1 Y3, 0.1 Y4 }\n",\ -" { 0.4 Z1, 0.4 Z2, 0.1 Z3, 0.1 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3);\n",\ -"(5, 3, 1);\n",\ -"(5, 4, 2);\n",\ -"(5, 1, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 2, 5, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.5 P5, -0.25 P1, -0.25 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 120, but more than 180 (13)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.866, 0) { 1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2);\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0, -0.3) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 3);\n",\ -"(3, 5, 2);\n",\ -"(2, 5, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5);\n",\ -"\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.1, -0.4) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Tetrahedron (14)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1.0 };\n",\ -"(0.5, 0.866, 0) { 1.0 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.2) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(4, 1, 2);\n",\ -"(4, 2, 3);\n",\ -"(4, 3, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, 0.288, -0.25) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Tetrahedron (15)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1.0 };\n",\ -"(0.5, 0.866, 0) { 1.0 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.1) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(4, 1, 2);\n",\ -"(4, 2, 3);\n",\ -"(4, 3, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, 0.288, -0.15) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"endrule\n", -0}; -} diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/topology.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/topology.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/topology.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/topology.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -5,6 +5,7 @@ { using ngcore::ParallelForRange; using ngcore::INT; + using ngcore::TasksPerThread; template void QuickSortRec (NgFlatArray data, @@ -41,12 +42,12 @@ - + MeshTopology :: MeshTopology (const Mesh & amesh) : mesh(&amesh) { - buildedges = true; - buildfaces = true; + buildedges = static_buildedges; + buildfaces = static_buildfaces; timestamp = -1; } @@ -71,6 +72,19 @@ "knwon are 'edges', 'faces', 'parentedges', 'parentfaces'"); } + bool MeshTopology :: static_buildedges = true; + bool MeshTopology :: static_buildfaces = true; + + void MeshTopology :: EnableTableStatic (string name, bool set) + { + if (name == "edges") + static_buildedges = set; + else if (name == "faces") + static_buildfaces = set; + else + throw Exception ("noting known about table "+name +"\n" + "knwon are 'edges', 'faces'"); + } template @@ -354,6 +368,7 @@ void MeshTopology :: Update (NgTaskManager tm_unused, NgTracer tracer) { static Timer timer("Topology::Update"); + static Timer timer_tables("Build vertex to element table"); RegionTimer reg (timer); #ifdef PARALLEL @@ -391,132 +406,35 @@ vertex to surface element vertex to segment */ - cnt = 0; - /* - for (ElementIndex ei = 0; ei < ne; ei++) - { - const Element & el = (*mesh)[ei]; - for (int j = 0; j < el.GetNV(); j++) - cnt[el[j]]++; - } - */ - ParallelForRange - (ne, [&] (IntRange r) - { - for (ElementIndex ei : r) - { - const Element & el = (*mesh)[ei]; - for (int j = 0; j < el.GetNV(); j++) - AsAtomic(cnt[el[j]])++; - } - }); - - vert2element = TABLE (cnt); - for (ElementIndex ei = 0; ei < ne; ei++) - { - const Element & el = (*mesh)[ei]; - for (int j = 0; j < el.GetNV(); j++) - vert2element.AddSave (el[j], ei); - } - - /* - ParallelForRange - (tm, ne, - [&] (size_t begin, size_t end) - { - for (ElementIndex ei = begin; ei < end; ei++) - { - const Element & el = (*mesh)[ei]; - for (int j = 0; j < el.GetNV(); j++) - vert2element.ParallelAdd (el[j], ei); - } - }); - requires sorting !!!! - */ - - cnt = 0; - /* - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - { - const Element2d & el = (*mesh)[sei]; - for (int j = 0; j < el.GetNV(); j++) - cnt[el[j]]++; - } - */ - ParallelForRange - (nse, - [&] (IntRange r) - { - for (SurfaceElementIndex ei : r) - { - const Element2d & el = (*mesh)[ei]; - for (int j = 0; j < el.GetNV(); j++) - AsAtomic(cnt[el[j]])++; - } - }); - - - vert2surfelement = TABLE (cnt); + timer_tables.Start(); + vert2element = mesh->CreatePoint2ElementTable(); + vert2surfelement = mesh->CreatePoint2SurfaceElementTable(0); - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - { - const Element2d & el = (*mesh)[sei]; - for (int j = 0; j < el.GetNV(); j++) - vert2surfelement.AddSave (el[j], sei); - } - /* - ParallelForRange - (tm, nse, - [&] (size_t begin, size_t end) - { - for (SurfaceElementIndex sei = begin; sei < end; sei++) + vert2segment = ngcore::CreateSortedTable( mesh->LineSegments().Range(), + [&](auto & table, SegmentIndex segi) { - const Element2d & el = (*mesh)[sei]; - for (int j = 0; j < el.GetNV(); j++) - vert2surfelement.ParallelAdd (el[j], sei); - } - }); - requires sorting !!! - */ + const Segment & seg = (*mesh)[segi]; + table.Add (seg[0], segi); + table.Add (seg[1], segi); + }, np); - cnt = 0; - for (SegmentIndex si = 0; si < nseg; si++) - { - const Segment & seg = mesh->LineSegment(si); - cnt[seg[0]]++; - cnt[seg[1]]++; - } - - vert2segment = TABLE (cnt); - for (SegmentIndex si = 0; si < nseg; si++) - { - const Segment & seg = mesh->LineSegment(si); - vert2segment.AddSave (seg[0], si); - vert2segment.AddSave (seg[1], si); - } + vert2pointelement = ngcore::CreateSortedTable( mesh->pointelements.Range(), + [&](auto & table, int pei) + { + const Element0d & pointel = mesh->pointelements[pei]; + table.Add(pointel.pnum, pei); + }, np); + timer_tables.Stop(); - cnt = 0; - for (int pei = 0; pei < mesh->pointelements.Size(); pei++) - { - const Element0d & pointel = mesh->pointelements[pei]; - cnt[pointel.pnum]++; - } - - vert2pointelement = TABLE (cnt); - for (int pei = 0; pei < mesh->pointelements.Size(); pei++) - { - const Element0d & pointel = mesh->pointelements[pei]; - vert2pointelement.AddSave (pointel.pnum, pei); - } (*tracer) ("Topology::Update setup tables", true); if (buildedges) { - static int timer1 = NgProfiler::CreateTimer ("topology::buildedges"); - NgProfiler::RegionTimer reg1 (timer1); + static Timer timer1("topology::buildedges"); + RegionTimer reg1(timer1); if (id == 0) PrintMessage (5, "Update edges "); @@ -607,7 +525,7 @@ }); cnt[v] = cnti; } - } ); + }, TasksPerThread(4) ); // accumulate number of edges int ned = edge2vert.Size(); @@ -620,7 +538,8 @@ ned += hv; } edge2vert.SetSize(ned); - + edge2segment.SetSize(ned); + edge2segment = -1; // INDEX_CLOSED_HASHTABLE v2eht(2*max_edge_on_vertex+10); // NgArray vertex2; @@ -689,204 +608,277 @@ break; case 1: segedges[elnr].nr = edgenum; + edge2segment[edgenum] = elnr; // segedges[elnr].orient = edgedir; break; } }); } - } ); + }, TasksPerThread(4) ); - if (build_parent_edges) - { - static Timer t("build_hierarchy"); RegionTimer reg(t); - cnt = 0; - for (auto verts : edge2vert) cnt[verts[0]]++; - TABLE vert2edge (cnt); - for (auto i : edge2vert.Range()) - vert2edge.AddSave (edge2vert[i][0], i); - - // build edge hierarchy: - parent_edges.SetSize (ned); - parent_edges = { -1, { -1, -1, -1 } }; + if (build_parent_edges) + { + static Timer t("build_hierarchy"); RegionTimer reg(t); + cnt = 0; + for (auto verts : edge2vert) cnt[verts[0]]++; + TABLE vert2edge (cnt); + for (auto i : edge2vert.Range()) + vert2edge.AddSave (edge2vert[i][0], i); + + // build edge hierarchy: + parent_edges.SetSize (ned); + parent_edges = { -1, { -1, -1, -1 } }; - for (size_t i = 0; i < ned; i++) - { - auto verts = edge2vert[i]; // 2 vertices of edge + for (size_t i = 0; i < ned; i++) + { + auto verts = edge2vert[i]; // 2 vertices of edge - if (verts[0] >= mesh->mlbetweennodes.Size()+PointIndex::BASE || - verts[1] >= mesh->mlbetweennodes.Size()+PointIndex::BASE) - continue; - - auto pa0 = mesh->mlbetweennodes[verts[0]]; // two parent vertices of v0 - auto pa1 = mesh->mlbetweennodes[verts[1]]; // two parent vertices of v1 + if (verts[0] >= mesh->mlbetweennodes.Size()+PointIndex::BASE || + verts[1] >= mesh->mlbetweennodes.Size()+PointIndex::BASE) + continue; + + auto pa0 = mesh->mlbetweennodes[verts[0]]; // two parent vertices of v0 + auto pa1 = mesh->mlbetweennodes[verts[1]]; // two parent vertices of v1 + + // both vertices are on coarsest mesh + if (!pa0[0].IsValid() && !pa1[0].IsValid()) + continue; + + int issplitedge = 0; + if (pa0[0] == verts[1] || pa0[1] == verts[1]) + issplitedge = 1; + if (pa1[0] == verts[0] || pa1[1] == verts[0]) + issplitedge = 2; - // both vertices are on coarsest mesh - if (!pa0[0].IsValid() && !pa1[0].IsValid()) - continue; - - int issplitedge = 0; - if (pa0[0] == verts[1] || pa0[1] == verts[1]) - issplitedge = 1; - if (pa1[0] == verts[0] || pa1[1] == verts[0]) - issplitedge = 2; - - if (issplitedge) - { - // cout << "split edge " << endl; - // edge is obtained by splitting one edge into two parts: - auto paedge = issplitedge == 1 ? pa0 : pa1; - - if (paedge[0] > paedge[1]) - Swap (paedge[0], paedge[1]); - - for (int ednr : vert2edge[paedge[0]]) - if (auto cverts = edge2vert[ednr]; cverts[1] == paedge[1]) - { - int orient = (paedge[0] == verts[0] || paedge[1] == verts[1]) ? 1 : 0; - parent_edges[i] = { orient, { ednr, -1, -1 } }; - } - } - else - { - // edge is splitting edge in middle of triangle: - for (int j = 1; j <= 2; j++) - { - INT<2> paedge1, paedge2, paedge3; - int orient_inner = 0; - if (j == 1) - { - paedge1 = INT<2> (pa0[0], verts[1]); - paedge2 = INT<2> (pa0[1], verts[1]); - paedge3 = INT<2> (pa0[0], pa0[1]); - orient_inner = 0; - } - else - { - paedge1 = INT<2> (pa1[0], verts[0]); - paedge2 = INT<2> (pa1[1], verts[0]); - paedge3 = INT<2> (pa1[0], pa1[1]); - orient_inner = 1; - } - if (paedge1[0] > paedge1[1]) - Swap (paedge1[0], paedge1[1]); - if (paedge2[0] > paedge2[1]) - Swap (paedge2[0], paedge2[1]); - if (paedge3[0] > paedge3[1]) - Swap (paedge3[0], paedge3[1]); - - // if first vertex number is -1, then don't try to find entry in node2edge hash table - if ( paedge1[0] == PointIndex::BASE-1 || paedge2[0] == PointIndex::BASE-1 ) - continue; - - int paedgenr1=-1, paedgenr2=-1, paedgenr3=-1, orient1 = 0, orient2 = 0; - for (int ednr : vert2edge[paedge1[0]]) - if (auto cverts = edge2vert[ednr]; cverts[1] == paedge1[1]) - { - paedgenr1 = ednr; - orient1 = (paedge1[0] == verts[0] || paedge1[1] == verts[1]) ? 1 : 0; - } - for (int ednr : vert2edge[paedge2[0]]) - if (auto cverts = edge2vert[ednr]; cverts[1] == paedge2[1]) - { - paedgenr2 = ednr; - orient2 = (paedge2[0] == verts[0] || paedge2[1] == verts[1]) ? 1 : 0; - } - - for (int ednr : vert2edge[paedge3[0]]) - if (auto cverts = edge2vert[ednr]; cverts[1] == paedge3[1]) - paedgenr3 = ednr; - - if (paedgenr1 != -1 && paedgenr2 != -1) - parent_edges[i] = { orient1+2*orient2+4*orient_inner, { paedgenr1, paedgenr2, paedgenr3 } }; - } + if (issplitedge) + { + // cout << "split edge " << endl; + // edge is obtained by splitting one edge into two parts: + auto paedge = issplitedge == 1 ? pa0 : pa1; + if (paedge[0] > paedge[1]) + Swap (paedge[0], paedge[1]); - // TODO: quad edges - /* - if (parentedges[i][0] == -1) - { - // quad split - if (pa1[0] != pa2[0] && - pa1[0] != pa2[1] && - pa1[1] != pa2[0] && - pa1[1] != pa2[1]) - for (int j = 1; j <= 2; j++) - { - INT<2> paedge1, paedge2; - if (j == 1) - { - paedge1 = INT<2> (pa1[0], pa2[0]); - paedge2 = INT<2> (pa1[1], pa2[1]); - } - else - { - paedge1 = INT<2> (pa1[0], pa2[1]); - paedge2 = INT<2> (pa1[1], pa2[0]); - } - - int paedgenr1 = 0, paedgenr2 = 0; - int orient1 = 1, orient2 = 1; - - if (paedge1[0] > paedge1[1]) - { - Swap (paedge1[0], paedge1[1]); - orient1 = 0; - } - if (paedge2[0] > paedge2[1]) - { - Swap (paedge2[0], paedge2[1]); - orient2 = 0; - } - - if ( paedge1[0] == -1 || paedge2[0] == -1 ) - continue; - - if (node2edge.Used (paedge1) && node2edge.Used (paedge2)) - { - paedgenr1 = node2edge.Get (paedge1); - paedgenr2 = node2edge.Get (paedge2); - parentedges[i][0] = 2 * paedgenr1 + orient1; - parentedges[i][1] = 2 * paedgenr2 + orient2; - } - } - } - - if (parentedges[i][0] == -1) - { - // triangle split into quad+trig (from anisotropic pyramids) - for (int j = 0; j < 2; j++) - for (int k = 0; k < 2; k++) - { - INT<2> paedge (pa1[1-j], pa2[1-k]); - int orientpa = 1; - if (paedge[0] > paedge[1]) - { - Swap (paedge[0], paedge[1]); - orientpa = 0; - } - if (pa1[j] == pa2[k] && node2edge.Used(paedge)) - { - int paedgenr = node2edge.Get (paedge); - parentedges[i][0] = 2 * paedgenr + orientpa; - } - } - - } - */ + for (int ednr : vert2edge[paedge[0]]) + if (auto cverts = edge2vert[ednr]; cverts[1] == paedge[1]) + { + int orient = (paedge[0] == verts[0] || paedge[1] == verts[1]) ? 1 : 0; + parent_edges[i] = { orient, { ednr, -1, -1 } }; + } + } + else + { + bool bisect_edge = false; + // edge is splitting edge in middle of triangle: + for (int j = 1; j <= 2; j++) + { + INT<2> paedge1, paedge2, paedge3; + int orient_inner = 0; + if (j == 1) + { + paedge1 = INT<2> (pa0[0], verts[1]); + paedge2 = INT<2> (pa0[1], verts[1]); + paedge3 = INT<2> (pa0[0], pa0[1]); + orient_inner = 0; + } + else + { + paedge1 = INT<2> (pa1[0], verts[0]); + paedge2 = INT<2> (pa1[1], verts[0]); + paedge3 = INT<2> (pa1[0], pa1[1]); + orient_inner = 1; + } + if (paedge1[0] > paedge1[1]) + Swap (paedge1[0], paedge1[1]); + if (paedge2[0] > paedge2[1]) + Swap (paedge2[0], paedge2[1]); + if (paedge3[0] > paedge3[1]) + Swap (paedge3[0], paedge3[1]); + + // if first vertex number is -1, then don't try to find entry in node2edge hash table + if ( paedge1[0] == PointIndex::BASE-1 || paedge2[0] == PointIndex::BASE-1 ) + continue; + + int paedgenr1=-1, paedgenr2=-1, paedgenr3=-1, orient1 = 0, orient2 = 0; + for (int ednr : vert2edge[paedge1[0]]) + if (auto cverts = edge2vert[ednr]; cverts[1] == paedge1[1]) + { + paedgenr1 = ednr; + orient1 = (paedge1[0] == verts[0] || paedge1[1] == verts[1]) ? 1 : 0; + } + for (int ednr : vert2edge[paedge2[0]]) + if (auto cverts = edge2vert[ednr]; cverts[1] == paedge2[1]) + { + paedgenr2 = ednr; + orient2 = (paedge2[0] == verts[0] || paedge2[1] == verts[1]) ? 1 : 0; + } - } - - } + for (int ednr : vert2edge[paedge3[0]]) + if (auto cverts = edge2vert[ednr]; cverts[1] == paedge3[1]) + paedgenr3 = ednr; + + if (paedgenr1 != -1 && paedgenr2 != -1){ + bisect_edge = true; + parent_edges[i] = { orient1+2*orient2+4*orient_inner, { paedgenr1, paedgenr2, paedgenr3 } }; + } + } - /* - for (int i : Range(parent_edges)) - { - auto [info, nrs] = parent_edges[i]; - cout << "edge " << i << " has " << info << ", nrs = " << nrs[0] << " " << nrs[1] << endl; - } - */ - } + if (!bisect_edge) // not a bisect edge (then a red edge) + { + INT<2> paedge1, paedge2, paedge3; + int orient1 = 0, orient2 = 0, orient3=0; + int orient_inner = 0; + paedge1 = INT<2> (pa0[0], pa0[1]); + paedge2 = INT<2> (pa1[0], pa1[1]); + // find common vertex and the thrid pa edge + if (pa0[0]==pa1[0]){// 00 + //orient1 = 0; + orient2 = 1; + if (pa0[1] (pa0[1], pa1[1]); + }else{ + //orient3 = 0; + paedge3 = INT<2> (pa1[1], pa0[1]); + } + } + else if (pa0[0]==pa1[1]){//01 + //orient1 = 0; + //orient2 = 0; + if (pa0[1] (pa0[1], pa1[0]); + }else{ + //orient3 = 0; + paedge3 = INT<2> (pa1[0], pa0[1]); + } + } + else if (pa0[1]==pa1[0]){//10 + orient1 = 1; + orient2 = 1; + if (pa0[0] (pa0[0], pa1[1]); + }else{ + //orient3 = 0; + paedge3 = INT<2> (pa1[1], pa0[0]); + } + } + else if (pa0[1]==pa1[1]){//11 + orient1 = 1; + //orient2 = 0; + if (pa0[0] (pa0[0], pa1[0]); + }else{ + //orient3 = 0; + paedge3 = INT<2> (pa1[0], pa0[0]); + } + } + + int paedgenr1=-1, paedgenr2=-1, paedgenr3=-1; + for (int ednr : vert2edge[paedge1[0]]) + if (auto cverts = edge2vert[ednr]; cverts[1] == paedge1[1]) + paedgenr1 = ednr; + for (int ednr : vert2edge[paedge2[0]]) + if (auto cverts = edge2vert[ednr]; cverts[1] == paedge2[1]) + paedgenr2 = ednr; + + for (int ednr : vert2edge[paedge3[0]]) + if (auto cverts = edge2vert[ednr]; cverts[1] == paedge3[1]) + paedgenr3 = ednr; + + parent_edges[i] = { 8+orient1+2*orient2+4*orient3, { paedgenr1, paedgenr2, paedgenr3 } }; + + //cout <<8+orient1+2*orient2+4*orient3 <<":"< paedge1, paedge2; + if (j == 1) + { + paedge1 = INT<2> (pa1[0], pa2[0]); + paedge2 = INT<2> (pa1[1], pa2[1]); + } + else + { + paedge1 = INT<2> (pa1[0], pa2[1]); + paedge2 = INT<2> (pa1[1], pa2[0]); + } + + int paedgenr1 = 0, paedgenr2 = 0; + int orient1 = 1, orient2 = 1; + + if (paedge1[0] > paedge1[1]) + { + Swap (paedge1[0], paedge1[1]); + orient1 = 0; + } + if (paedge2[0] > paedge2[1]) + { + Swap (paedge2[0], paedge2[1]); + orient2 = 0; + } + + if ( paedge1[0] == -1 || paedge2[0] == -1 ) + continue; + + if (node2edge.Used (paedge1) && node2edge.Used (paedge2)) + { + paedgenr1 = node2edge.Get (paedge1); + paedgenr2 = node2edge.Get (paedge2); + parentedges[i][0] = 2 * paedgenr1 + orient1; + parentedges[i][1] = 2 * paedgenr2 + orient2; + } + } + } + + if (parentedges[i][0] == -1) + { + // triangle split into quad+trig (from anisotropic pyramids) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 2; k++) + { + INT<2> paedge (pa1[1-j], pa2[1-k]); + int orientpa = 1; + if (paedge[0] > paedge[1]) + { + Swap (paedge[0], paedge[1]); + orientpa = 0; + } + if (pa1[j] == pa2[k] && node2edge.Used(paedge)) + { + int paedgenr = node2edge.Get (paedge); + parentedges[i][0] = 2 * paedgenr + orientpa; + } + } + + } + */ + } + + } + + /* + for (int i : Range(parent_edges)) + { + auto [info, nrs] = parent_edges[i]; + cout << "edge " << i << " has " << info << ", nrs = " << nrs[0] << " " << nrs[1] << endl; + } + */ + } } @@ -905,12 +897,12 @@ // generate faces if (buildfaces) { - static int timer2 = NgProfiler::CreateTimer ("topology::buildfaces"); + static Timer timer2("topology::buildfaces"); // static int timer2a = NgProfiler::CreateTimer ("topology::buildfacesa"); // static int timer2b = NgProfiler::CreateTimer ("topology::buildfacesb"); // static int timer2b1 = NgProfiler::CreateTimer ("topology::buildfacesb1"); // static int timer2c = NgProfiler::CreateTimer ("topology::buildfacesc"); - NgProfiler::RegionTimer reg2 (timer2); + RegionTimer reg2 (timer2); if (id == 0) PrintMessage (5, "Update faces "); @@ -1049,7 +1041,7 @@ }); cnt[v] = cnti; } - } ); + }, TasksPerThread(4) ); // NgProfiler::StopTimer (timer2b1); // accumulate number of faces @@ -1154,7 +1146,7 @@ } }); } - }); + }, TasksPerThread(4) ); /* int oldnfa = face2vert.Size(); @@ -1483,7 +1475,7 @@ for (auto f : hfaces) AsAtomic(face_els[f-1])++; } - }); + }, TasksPerThread(4)); for (int i = 1; i <= nse; i++) face_surfels[GetSurfaceElementFace (i)-1]++; (*tracer) ("Topology::Update count face_els", true); @@ -1519,7 +1511,7 @@ (*testout) << (*mesh)[(PointIndex)face2vert[i].I(j+1)] << " "; (*testout) << endl; - NgFlatArray vertels = GetVertexElements (face2vert[i].I(1)); + FlatArray vertels = GetVertexElements (face2vert[i].I(1)); for (int k = 0; k < vertels.Size(); k++) { int elfaces[10], orient[10]; @@ -1804,8 +1796,46 @@ } auto [info, nrs] = parent_faces[i]; - if (nrs[0] == -1) - cout << "************************** unhandled parent-face case **********************" << endl; + if (nrs[0] == -1){ + // hacking for tet red refinements + PointIndex v0 = f3[0]; + auto pa0 = mesh->mlbetweennodes[v0]; + auto pa1 = mesh->mlbetweennodes[f3[1]]; + auto pa2 = mesh->mlbetweennodes[f3[2]]; + // v0 is a coarse vertex ==> f3 is a boundary face + if (v0==pa1[0] || v0==pa1[1]){ + if (pa1[0]==v0){// type 0: bottom left corner + INT<3> parentverts(v0, pa1[1], pa2[1]); + int pafacenr = v2f[parentverts]; + parent_faces[i] = { 16, { pafacenr, -1, -1, -1} }; + //cout << "f "< parentverts(pa1[0], v0, pa2[1]); + int pafacenr = v2f[parentverts]; + parent_faces[i] = { 17, { pafacenr, -1, -1, -1} }; + //cout << "f "< parentverts(pa1[0], pa2[0], v0); + int pafacenr = v2f[parentverts]; + parent_faces[i] = { 18, { pafacenr, -1, -1, -1} }; + //cout << "f "< parentverts(pa0[0], pa0[1], pa1[1]); + int pafacenr = v2f[parentverts]; + parent_faces[i] = { 19, { pafacenr, -1, -1, -1} }; + //cout << "f "< els = GetVertexElements (pi[0]); + FlatArray els = GetVertexElements (pi[0]); // find one element having all vertices of the face for (int i = 0; i < els.Size(); i++) @@ -2489,15 +2519,10 @@ */ - void MeshTopology :: GetVertexElements (int vnr, NgArray & elements) const + void MeshTopology :: GetVertexElements (int vnr, Array & elements) const { if (vert2element.Size()) - { - int ne = vert2element.EntrySize(vnr); - elements.SetSize(ne); - for (int i = 1; i <= ne; i++) - elements.Elem(i) = vert2element.Get(vnr, i); - } + elements = vert2element[vnr]; } /* @@ -2524,22 +2549,16 @@ */ void MeshTopology :: GetVertexSurfaceElements( int vnr, - NgArray & elements ) const + Array & elements ) const { if (vert2surfelement.Size()) - { - int i; - int ne = vert2surfelement.EntrySize(vnr); - elements.SetSize(ne); - for (i = 1; i <= ne; i++) - elements.Elem(i) = vert2surfelement.Get(vnr, i); - } + elements = vert2surfelement[vnr]; } int MeshTopology :: GetVerticesEdge ( int v1, int v2 ) const { - NgArray elements_v1; + Array elements_v1; NgArray elementedges; GetVertexElements ( v1, elements_v1); int edv1, edv2; @@ -2565,14 +2584,13 @@ { int v1, v2; GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 ); - NgArray volels1, volels2; - GetVertexElements ( v1, volels1 ); - GetVertexElements ( v2, volels2 ); + auto volels1 = GetVertexElements ( v1 ); + auto volels2 = GetVertexElements ( v2 ); volels.SetSize(0); - for ( int eli1=1; eli1 <= volels1.Size(); eli1++) - if ( volels2.Contains( volels1.Elem(eli1) ) ) - volels.Append ( volels1.Elem(eli1) ); + for ( auto volel1 : volels1 ) + if ( volels2.Contains( volel1 ) ) + volels.Append ( volel1 ); } void MeshTopology :: @@ -2580,14 +2598,13 @@ { int v1, v2; GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 ); - NgArray els1, els2; - GetVertexSurfaceElements ( v1, els1 ); - GetVertexSurfaceElements ( v2, els2 ); + auto els1 = GetVertexSurfaceElements ( v1 ); + auto els2 = GetVertexSurfaceElements ( v2 ); els.SetSize(0); - for ( int eli1=1; eli1 <= els1.Size(); eli1++) - if ( els2.Contains( els1.Elem(eli1) ) ) - els.Append ( els1.Elem(eli1) ); + for ( auto el1 : els1 ) + if ( els2.Contains( el1 ) ) + els.Append ( el1 ); } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/topology.hpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/topology.hpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/topology.hpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/topology.hpp 2021-06-04 23:36:22.000000000 +0000 @@ -47,6 +47,7 @@ bool buildfaces; bool build_parent_edges = false; // may be changed to default = false bool build_parent_faces = false; // may be changed to default = false + static bool static_buildedges, static_buildfaces; NgArray edge2vert; NgArray face2vert; @@ -63,10 +64,11 @@ NgArray surffaces; NgArray surf2volelement; NgArray face2surfel; - TABLE vert2element; - TABLE vert2surfelement; - TABLE vert2segment; - TABLE vert2pointelement; + Array edge2segment; + Table vert2element; + Table vert2surfelement; + Table vert2segment; + Table vert2pointelement; int timestamp; public: int GetNSurfedges() const {return surfedges.Size();} @@ -85,6 +87,7 @@ void SetBuildParentFaces (bool bh) { build_parent_faces = bh; } void EnableTable (string name, bool set); + static void EnableTableStatic (string name, bool set); bool HasEdges () const { return buildedges; } bool HasFaces () const { return buildfaces; } @@ -169,19 +172,21 @@ } int GetFace2SurfaceElement (int fnr) const { return face2surfel[fnr-1]; } + + SegmentIndex GetSegmentOfEdge(int edgenr) const { return edge2segment[edgenr-1]; } - void GetVertexElements (int vnr, NgArray & elements) const; - NgFlatArray GetVertexElements (int vnr) const + void GetVertexElements (int vnr, Array & elements) const; + FlatArray GetVertexElements (int vnr) const { return vert2element[vnr]; } - void GetVertexSurfaceElements( int vnr, NgArray& elements ) const; - NgFlatArray GetVertexSurfaceElements(PointIndex vnr) const + void GetVertexSurfaceElements( int vnr, Array& elements ) const; + FlatArray GetVertexSurfaceElements(PointIndex vnr) const { return vert2surfelement[vnr]; } - NgFlatArray GetVertexSegments (int vnr) const + FlatArray GetVertexSegments (int vnr) const { return vert2segment[vnr]; } - NgFlatArray GetVertexPointElements (int vnr) const + FlatArray GetVertexPointElements (int vnr) const { return vert2pointelement[vnr]; } int GetVerticesEdge ( int v1, int v2) const; @@ -190,10 +195,10 @@ private: - Array>> parent_edges; + Array>> parent_edges; void BuildParentEdges (); - Array>> parent_faces; + Array>> parent_faces; void BuildParentFaces (); public: auto GetParentEdges (int enr) const { return parent_edges[enr]; } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/triarls.cpp ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/triarls.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/libsrc/meshing/triarls.cpp 2021-03-19 06:19:11.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/libsrc/meshing/triarls.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,468 +0,0 @@ -namespace netgen -{ -const char * triarules[] = { -"rule \"Free Triangle (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.7) { 0.5 X2 } { };\n",\ -"(0.5, 1.5) { 0.5 X2 } { };\n",\ -"(-0.5, 0.7) { 0.5 X2 } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Free Triangle (5)\"\n",\ -"\n",\ -"quality 5\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.5) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.7) { 1 X2 } { };\n",\ -"(0, 0.7) { } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.5) { 0.5 X2 } { };\n",\ -"(0.5, 0.5) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Triangle (10)\"\n",\ -"\n",\ -"quality 10\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.3) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 1 X2 } { };\n",\ -"(0, 0.5) { } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.3) { 0.5 X2 } { };\n",\ -"(0.5, 0.3) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Triangle (20)\"\n",\ -"\n",\ -"quality 20\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.1) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.2) { 1 X2 } { };\n",\ -"(0, 0.2) { } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.1) { 0.5 X2 } { };\n",\ -"(0.5, 0.1) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 60 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 0.5, 0, 1.0 };\n",\ -"(0.5, 0.866) { 0.6, 0, 0.8 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left 60 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.125, 0.6495) { 0.75 X2, 0.75 X3 } { 0.75 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(-0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { 1 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(1, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Right 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(-0.5, 0.866);\n",\ -"(1.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"(2, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 5);\n",\ -"(5, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 1 X4 } { 1 Y4 };\n",\ -"(1, 1.299) { -0.5 X2, 0.375 X3, 1.125 X4 } { -0.5 Y2, 0.375 Y3, 1.125 Y4 };\n",\ -"(0, 1.299) { 1.125 X3, 0.375 X4 } { 1.125 Y3, 0.375 Y4 };\n",\ -"(-0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 5);\n",\ -"(3, 1, 5);\n",\ -"(2, 4, 5);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Fill Triangle\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Vis A Vis (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"2 h Vis A Vis (1)\"\n",\ -"\n",\ -"quality 3\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1.732);\n",\ -"(0, 1.732);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.25 X2, 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 5);\n",\ -"(5, 4);\n",\ -"(3, 5);\n",\ -"(5, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1.732) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1.732) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 5);\n",\ -"(3, 4, 5);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -0}; -} diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/python/gui.py ngsolve-6.2.2103/external_dependencies/netgen/python/gui.py --- ngsolve-6.2.2102/external_dependencies/netgen/python/gui.py 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/python/gui.py 2021-06-04 23:36:22.000000000 +0000 @@ -19,11 +19,12 @@ pass if not netgen.libngpy._meshing._netgen_executable_started: - # catch exception for building html docu on server without display - try: - StartGUI() - except: - pass + import os + if not "NETGEN_DOCUMENTATION_RST_FORMAT" in os.environ: + try: + StartGUI() + except: + pass def Snapshot(w,h, filename=None): netgen.Redraw(blocking=True) diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/hexa.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/hexa.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/hexa.rls 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/hexa.rls 1970-01-01 00:00:00.000000000 +0000 @@ -1,203 +0,0 @@ -rule "Hexa left-right-top" - -quality 1 - -flags t; - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 } ; -(1, 1, 0) { 1 } ; -(0, 1, 0) { 1 } ; -(0, 0, 1) { 1 } ; -(1, 0, 1) { 1 } ; -(1, 1, 1) { 1 } ; -(0, 1, 1) { 1 } ; - -mapfaces -(4, 3, 2, 1) del; -(3, 7, 6, 2) del; -(7, 8, 5, 6) del; -(8, 4, 1, 5) del; - -newpoints - -newfaces -(5, 6, 2, 1); -(7, 8, 4, 3); - -elements -(4, 3, 2, 1, 8, 7, 6, 5); - -freezone2 -{ 1 P5 }; -{ 1 P6 }; -{ 1 P2 }; -{ 1 P3 }; -{ 0.3 P1, 0.3 P2, 0.3 P5, 0.3 P6, -0.05 P3, -0.05 P4, -0.05 P7, -0.05 P8 }; -{ 0.3 P3, 0.3 P4, 0.3 P7, 0.3 P8, -0.05 P1, -0.05 P2, -0.05 P5, -0.05 P6 }; - -freezonelimit -{ 1 P5 }; -{ 1 P6 }; -{ 1 P2 }; -{ 1 P3 }; -{ 0.25 P1, 0.25 P2, 0.25 P5, 0.25 P6, -0.0 P3, -0.0 P4, -0.0 P7, -0.0 P8 }; -{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 }; - - -endrule - - - -rule "Hexa left-right-top (10)" - -quality 10 - -flags t; - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 } ; -(1, 1, 0) { 1 } ; -(0, 1, 0) { 1 } ; -(0, 0, 1) { 1 } ; -(1, 0, 1) { 1 } ; -(1, 1, 1) { 1 } ; -(0, 1, 1) { 1 } ; - -mapfaces -(4, 3, 2, 1) del; -(3, 7, 6, 2) del; -(7, 8, 5, 6) del; -(8, 4, 1, 5) del; - -newpoints - -newfaces -(5, 6, 2, 1); -(7, 8, 4, 3); - -elements -(4, 3, 2, 1, 8, 7, 6, 5); - -freezone2 -{ 1 P5 }; -{ 1 P6 }; -{ 1 P2 }; -{ 1 P3 }; -{ 0.251 P1, 0.251 P2, 0.251 P5, 0.251 P6, -0.05 P3, -0.001 P4, -0.001 P7, -0.001 P8 }; -{ 0.251 P3, 0.251 P4, 0.251 P7, 0.251 P8, -0.05 P1, -0.001 P2, -0.001 P5, -0.001 P6 }; - -freezonelimit -{ 1 P5 }; -{ 1 P6 }; -{ 1 P2 }; -{ 1 P3 }; -{ 0.25 P1, 0.25 P2, 0.25 P5, 0.25 P6, -0.0 P3, -0.0 P4, -0.0 P7, -0.0 P8 }; -{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 }; - - -endrule - - - - - -rule "Hexa left-right-top-front" - -quality 1 - -flags t; - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 } ; -(1, 1, 0) { 1 } ; -(0, 1, 0) { 1 } ; -(0, 0, 1) { 1 } ; -(1, 0, 1) { 1 } ; -(1, 1, 1) { 1 } ; -(0, 1, 1) { 1 } ; - -mapfaces -(4, 3, 2, 1) del; -(3, 7, 6, 2) del; -(7, 8, 5, 6) del; -(8, 4, 1, 5) del; -(1, 2, 6, 5) del; -newpoints - -newfaces -(7, 8, 4, 3); - -elements -(4, 3, 2, 1, 8, 7, 6, 5); - -freezone2 -{ 1 P5 }; -{ 1 P6 }; -{ 1 P2 }; -{ 1 P3 }; -{ 0.3 P3, 0.3 P4, 0.3 P7, 0.3 P8, -0.05 P1, -0.05 P2, -0.05 P5, -0.05 P6 }; - -freezonelimit -{ 1 P5 }; -{ 1 P6 }; -{ 1 P2 }; -{ 1 P3 }; -{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 }; - - -endrule - - - - - - - -rule "Hexa fill" - -quality 1 - -flags t; - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 } ; -(1, 1, 0) { 1 } ; -(0, 1, 0) { 1 } ; -(0, 0, 1) { 1 } ; -(1, 0, 1) { 1 } ; -(1, 1, 1) { 1 } ; -(0, 1, 1) { 1 } ; - -mapfaces -(4, 3, 2, 1) del; -(3, 7, 6, 2) del; -(7, 8, 5, 6) del; -(8, 4, 1, 5) del; -(1, 2, 6, 5) del; -(3, 4, 8, 7) del; - -newpoints - -newfaces - -elements -(4, 3, 2, 1, 8, 7, 6, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P5 }; -{ 1 P3 }; - - -endrule - - - - - diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/hexrules.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/hexrules.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/hexrules.rls 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/hexrules.rls 2021-06-04 23:36:22.000000000 +0000 @@ -0,0 +1,203 @@ +rule "Hexa left-right-top" + +quality 1 + +flags t; + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 } ; +(1, 1, 0) { 1 } ; +(0, 1, 0) { 1 } ; +(0, 0, 1) { 1 } ; +(1, 0, 1) { 1 } ; +(1, 1, 1) { 1 } ; +(0, 1, 1) { 1 } ; + +mapfaces +(4, 3, 2, 1) del; +(3, 7, 6, 2) del; +(7, 8, 5, 6) del; +(8, 4, 1, 5) del; + +newpoints + +newfaces +(5, 6, 2, 1); +(7, 8, 4, 3); + +elements +(4, 3, 2, 1, 8, 7, 6, 5); + +freezone2 +{ 1 P5 }; +{ 1 P6 }; +{ 1 P2 }; +{ 1 P3 }; +{ 0.3 P1, 0.3 P2, 0.3 P5, 0.3 P6, -0.05 P3, -0.05 P4, -0.05 P7, -0.05 P8 }; +{ 0.3 P3, 0.3 P4, 0.3 P7, 0.3 P8, -0.05 P1, -0.05 P2, -0.05 P5, -0.05 P6 }; + +freezonelimit +{ 1 P5 }; +{ 1 P6 }; +{ 1 P2 }; +{ 1 P3 }; +{ 0.25 P1, 0.25 P2, 0.25 P5, 0.25 P6, -0.0 P3, -0.0 P4, -0.0 P7, -0.0 P8 }; +{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 }; + + +endrule + + + +rule "Hexa left-right-top (10)" + +quality 10 + +flags t; + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 } ; +(1, 1, 0) { 1 } ; +(0, 1, 0) { 1 } ; +(0, 0, 1) { 1 } ; +(1, 0, 1) { 1 } ; +(1, 1, 1) { 1 } ; +(0, 1, 1) { 1 } ; + +mapfaces +(4, 3, 2, 1) del; +(3, 7, 6, 2) del; +(7, 8, 5, 6) del; +(8, 4, 1, 5) del; + +newpoints + +newfaces +(5, 6, 2, 1); +(7, 8, 4, 3); + +elements +(4, 3, 2, 1, 8, 7, 6, 5); + +freezone2 +{ 1 P5 }; +{ 1 P6 }; +{ 1 P2 }; +{ 1 P3 }; +{ 0.251 P1, 0.251 P2, 0.251 P5, 0.251 P6, -0.05 P3, -0.001 P4, -0.001 P7, -0.001 P8 }; +{ 0.251 P3, 0.251 P4, 0.251 P7, 0.251 P8, -0.05 P1, -0.001 P2, -0.001 P5, -0.001 P6 }; + +freezonelimit +{ 1 P5 }; +{ 1 P6 }; +{ 1 P2 }; +{ 1 P3 }; +{ 0.25 P1, 0.25 P2, 0.25 P5, 0.25 P6, -0.0 P3, -0.0 P4, -0.0 P7, -0.0 P8 }; +{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 }; + + +endrule + + + + + +rule "Hexa left-right-top-front" + +quality 1 + +flags t; + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 } ; +(1, 1, 0) { 1 } ; +(0, 1, 0) { 1 } ; +(0, 0, 1) { 1 } ; +(1, 0, 1) { 1 } ; +(1, 1, 1) { 1 } ; +(0, 1, 1) { 1 } ; + +mapfaces +(4, 3, 2, 1) del; +(3, 7, 6, 2) del; +(7, 8, 5, 6) del; +(8, 4, 1, 5) del; +(1, 2, 6, 5) del; +newpoints + +newfaces +(7, 8, 4, 3); + +elements +(4, 3, 2, 1, 8, 7, 6, 5); + +freezone2 +{ 1 P5 }; +{ 1 P6 }; +{ 1 P2 }; +{ 1 P3 }; +{ 0.3 P3, 0.3 P4, 0.3 P7, 0.3 P8, -0.05 P1, -0.05 P2, -0.05 P5, -0.05 P6 }; + +freezonelimit +{ 1 P5 }; +{ 1 P6 }; +{ 1 P2 }; +{ 1 P3 }; +{ 0.25 P3, 0.25 P4, 0.25 P7, 0.25 P8, -0.0 P1, -0.0 P1, -0.0 P5, -0.0 P6 }; + + +endrule + + + + + + + +rule "Hexa fill" + +quality 1 + +flags t; + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 } ; +(1, 1, 0) { 1 } ; +(0, 1, 0) { 1 } ; +(0, 0, 1) { 1 } ; +(1, 0, 1) { 1 } ; +(1, 1, 1) { 1 } ; +(0, 1, 1) { 1 } ; + +mapfaces +(4, 3, 2, 1) del; +(3, 7, 6, 2) del; +(7, 8, 5, 6) del; +(8, 4, 1, 5) del; +(1, 2, 6, 5) del; +(3, 4, 8, 7) del; + +newpoints + +newfaces + +elements +(4, 3, 2, 1, 8, 7, 6, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P5 }; +{ 1 P3 }; + + +endrule + + + + + diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/makerlsfile.cpp ngsolve-6.2.2103/external_dependencies/netgen/rules/makerlsfile.cpp --- ngsolve-6.2.2102/external_dependencies/netgen/rules/makerlsfile.cpp 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/makerlsfile.cpp 2021-06-04 23:36:22.000000000 +0000 @@ -1,6 +1,7 @@ #include #include #include +#include using namespace std; @@ -8,9 +9,9 @@ int main (int argc, char ** argv) { - if (argc != 3) + if (argc != 4) { - cout << "use: makerlsfile infile outfile" << endl; + cout << "use: makerlsfile infile outfile rulename" << endl; exit(1); } @@ -28,8 +29,10 @@ ifstream inf (argv[1]); ofstream outf (argv[2]); + string rulename = argv[3]; - outf << "const char * ngscript[] = {" << endl; + outf << "namespace netgen" << endl << '{' << endl; + outf << "const char * " << rulename << "[] = {" << endl; while (inf.good()) { i = 0; @@ -57,9 +60,10 @@ inf.get(ch); } line[i] = 0; - cout << line << endl; + // cout << line << endl; outf << "\"" << line << "\\n\",\\" << endl; } outf << "0};" << endl; + outf << '}' << endl; return 0; } diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/prismrules2.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/prismrules2.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/prismrules2.rls 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/prismrules2.rls 2021-06-04 23:36:22.000000000 +0000 @@ -0,0 +1,451 @@ +tolfak 0.5 + +rule "prism on quad" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0, -0.86); +(0.5, 1, -0.86); + +mapfaces +(1, 2, 3, 4) del; +(1, 5, 2) del; +(4, 3, 6) del; + +newpoints + +newfaces +(5, 2, 3, 6); +(1, 5, 6, 4); + +elements +(1, 5, 2, 4, 6, 3); + +orientations +(1, 2, 3, 5); +(1, 3, 4, 6); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; +{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; +{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 }; + +freeset +1 2 4 5 6 7; + +freeset +2 3 4 5 6 8; + +endrule + + + + + +rule "prism on quad, one trig" + +quality 2 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0, -0.86); +(0.5, 1, -0.86); + +mapfaces +(1, 2, 3, 4) del; +(1, 5, 2) del; + +newpoints + +newfaces +(5, 2, 3, 6); +(1, 5, 6, 4); +(4, 6, 3); + +elements +(1, 5, 2, 4, 6, 3); + +orientations +(1, 2, 3, 5); +(1, 3, 4, 6); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; +{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; +{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 }; + +freeset +1 2 4 5 6 7; + +freeset +2 3 4 5 6 8; + + +endrule + + + + + + + + +rule "prism on 2 quad" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0, -0.86); +(0.5, 1, -0.86); + +mapfaces +(1, 2, 3, 4) del; +(2, 5, 6, 3) del; +(1, 5, 2) del; +(4, 3, 6) del; + +newpoints + +newfaces +(1, 5, 6, 4); + +elements +(1, 5, 2, 4, 6, 3); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; + +freeset +1 2 4 5 6 7; + +freeset +2 3 4 6; + + +endrule + + + + + + + + +rule "prism on 2 quad, one trig" + +quality 2 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0, -0.86); +(0.5, 1, -0.86); + +mapfaces +(1, 2, 3, 4) del; +(2, 5, 6, 3) del; +(1, 5, 2) del; + +newpoints + +newfaces +(1, 5, 6, 4); +(4, 6, 3); + +elements +(1, 5, 2, 4, 6, 3); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; + +freeset +1 2 4 5 6 7; + +freeset +2 3 4 6; + + +endrule + + + + + + + + + + + +rule "prism on 2 quada" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0, -0.86); +(0.5, 1, -0.86); + +mapfaces +(1, 2, 3, 4) del; +(5, 1, 4, 6) del; +(1, 5, 2) del; +(4, 3, 6) del; + +newpoints + +newfaces +(5, 2, 3, 6); + +elements +(1, 5, 2, 4, 6, 3); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 }; + +freeset +1 2 3 5 6 7; + +freeset +1 3 4 6; + + +endrule + + + + + +rule "fill prism" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0, -0.86); +(0.5, 1, -0.86); + +mapfaces +(1, 2, 3, 4) del; +(2, 5, 6, 3) del; +(5, 1, 4, 6) del; +(1, 5, 2) del; +(4, 3, 6) del; + +newpoints + +newfaces + + +elements +(1, 5, 2, 4, 6, 3); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; + +freeset +1 2 4 5; + +freeset +2 3 4 6; + +endrule + + + + + +rule "prism on 3 quad, one trig" + +quality 2 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0, -0.86); +(0.5, 1, -0.86); + +mapfaces +(1, 2, 3, 4) del; +(2, 5, 6, 3) del; +(5, 1, 4, 6) del; +(1, 5, 2) del; + +newpoints + +newfaces +(4, 6, 3); + + +elements +(1, 5, 2, 4, 6, 3); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; + +freeset +1 2 4 5; + +freeset +2 3 4 6; + +endrule + + + + + + + + + + + + + + +rule "flat prism" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0); +(0.5, 0.866, 0); +(0, 0, -1); +(1, 0, -1); +(0.5, 0.866, -1); + + +mapfaces +(1, 2, 3) del; +(5, 4, 6) del; + +newpoints + +newfaces +(1, 2, 4); +(4, 2, 5); +(2, 3, 5); +(5, 3, 6); +(3, 1, 6); +(6, 1, 4); + + + +elements +(1, 2, 3, 5, 4, 6); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P5 }; +{ 1 P6 }; +endrule diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/prisms2.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/prisms2.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/prisms2.rls 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/prisms2.rls 1970-01-01 00:00:00.000000000 +0000 @@ -1,451 +0,0 @@ -tolfak 0.5 - -rule "prism on quad" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0, -0.86); -(0.5, 1, -0.86); - -mapfaces -(1, 2, 3, 4) del; -(1, 5, 2) del; -(4, 3, 6) del; - -newpoints - -newfaces -(5, 2, 3, 6); -(1, 5, 6, 4); - -elements -(1, 5, 2, 4, 6, 3); - -orientations -(1, 2, 3, 5); -(1, 3, 4, 6); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; -{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; -{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 }; - -freeset -1 2 4 5 6 7; - -freeset -2 3 4 5 6 8; - -endrule - - - - - -rule "prism on quad, one trig" - -quality 2 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0, -0.86); -(0.5, 1, -0.86); - -mapfaces -(1, 2, 3, 4) del; -(1, 5, 2) del; - -newpoints - -newfaces -(5, 2, 3, 6); -(1, 5, 6, 4); -(4, 6, 3); - -elements -(1, 5, 2, 4, 6, 3); - -orientations -(1, 2, 3, 5); -(1, 3, 4, 6); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; -{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; -{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 }; - -freeset -1 2 4 5 6 7; - -freeset -2 3 4 5 6 8; - - -endrule - - - - - - - - -rule "prism on 2 quad" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0, -0.86); -(0.5, 1, -0.86); - -mapfaces -(1, 2, 3, 4) del; -(2, 5, 6, 3) del; -(1, 5, 2) del; -(4, 3, 6) del; - -newpoints - -newfaces -(1, 5, 6, 4); - -elements -(1, 5, 2, 4, 6, 3); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; - -freeset -1 2 4 5 6 7; - -freeset -2 3 4 6; - - -endrule - - - - - - - - -rule "prism on 2 quad, one trig" - -quality 2 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0, -0.86); -(0.5, 1, -0.86); - -mapfaces -(1, 2, 3, 4) del; -(2, 5, 6, 3) del; -(1, 5, 2) del; - -newpoints - -newfaces -(1, 5, 6, 4); -(4, 6, 3); - -elements -(1, 5, 2, 4, 6, 3); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 }; - -freeset -1 2 4 5 6 7; - -freeset -2 3 4 6; - - -endrule - - - - - - - - - - - -rule "prism on 2 quada" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0, -0.86); -(0.5, 1, -0.86); - -mapfaces -(1, 2, 3, 4) del; -(5, 1, 4, 6) del; -(1, 5, 2) del; -(4, 3, 6) del; - -newpoints - -newfaces -(5, 2, 3, 6); - -elements -(1, 5, 2, 4, 6, 3); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 }; - -freeset -1 2 3 5 6 7; - -freeset -1 3 4 6; - - -endrule - - - - - -rule "fill prism" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0, -0.86); -(0.5, 1, -0.86); - -mapfaces -(1, 2, 3, 4) del; -(2, 5, 6, 3) del; -(5, 1, 4, 6) del; -(1, 5, 2) del; -(4, 3, 6) del; - -newpoints - -newfaces - - -elements -(1, 5, 2, 4, 6, 3); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; - -freeset -1 2 4 5; - -freeset -2 3 4 6; - -endrule - - - - - -rule "prism on 3 quad, one trig" - -quality 2 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0, -0.86); -(0.5, 1, -0.86); - -mapfaces -(1, 2, 3, 4) del; -(2, 5, 6, 3) del; -(5, 1, 4, 6) del; -(1, 5, 2) del; - -newpoints - -newfaces -(4, 6, 3); - - -elements -(1, 5, 2, 4, 6, 3); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; - -freeset -1 2 4 5; - -freeset -2 3 4 6; - -endrule - - - - - - - - - - - - - - -rule "flat prism" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0); -(0.5, 0.866, 0); -(0, 0, -1); -(1, 0, -1); -(0.5, 0.866, -1); - - -mapfaces -(1, 2, 3) del; -(5, 4, 6) del; - -newpoints - -newfaces -(1, 2, 4); -(4, 2, 5); -(2, 3, 5); -(5, 3, 6); -(3, 1, 6); -(6, 1, 4); - - - -elements -(1, 2, 3, 5, 4, 6); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P5 }; -{ 1 P6 }; -endrule diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramidrules2.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramidrules2.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramidrules2.rls 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramidrules2.rls 2021-06-04 23:36:22.000000000 +0000 @@ -0,0 +1,303 @@ +tolfak 0.5 + +rule "Pyramid on quad" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); + +mapfaces +(1, 2, 3, 4) del; + +newpoints +(0.5, 0.5, -0.5) + { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } + { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; + +newfaces +(1, 2, 5); +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + +rule "small Pyramid on quad" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); + +mapfaces +(1, 2, 3, 4) del; + +newpoints +(0.5, 0.5, -0.1 ) + { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } + { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; + +newfaces +(1, 2, 5); +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + + + +rule "connect pyramid" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0.5, -0.5); + +mapfaces +(1, 2, 3, 4) del; + +newpoints + +newfaces +(1, 2, 5); +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + + + + + +rule "pyramid with one trig" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0.5, -0.5); + +mapfaces +(1, 2, 3, 4) del; +(2, 1, 5) del; + +newpoints + +newfaces +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 }; +{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 }; +{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P2 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 }; +{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 }; +{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P2 }; + +orientations +(1, 2, 3, 5); +(1, 3, 4, 5); + + +freeset +1 2 3 5; +freeset +1 3 4 5; +freeset +2 3 5 6; +freeset +3 4 5 7; +freeset +1 4 5 8; +endrule + + + + + + +rule "pyramid with two trig" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0.5, -0.5); + +mapfaces +(1, 2, 3, 4) del; +(2, 1, 5) del; +(3, 2, 5) del; +newpoints + +newfaces +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + + + + + + +rule "pyramid with two trig, left" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0.5, -0.5); + +mapfaces +(1, 2, 3, 4) del; +(2, 1, 5) del; +(1, 4, 5) del; +newpoints + +newfaces +(3, 4, 5); +(2, 3, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + + + diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramidrules.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramidrules.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramidrules.rls 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramidrules.rls 2021-06-04 23:36:22.000000000 +0000 @@ -0,0 +1,257 @@ +tolfak 0.5 + +rule "Pyramid on quad" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); + +mapfaces +(1, 2, 3, 4) del; + +newpoints +(0.5, 0.5, -0.5) + { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } + { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; + +newfaces +(1, 2, 5); +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + +rule "small Pyramid on quad" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); + +mapfaces +(1, 2, 3, 4) del; + +newpoints +(0.5, 0.5, -0.1 ) + { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } + { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; + +newfaces +(1, 2, 5); +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + + + +rule "connect pyramid" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0.5, -0.5); + +mapfaces +(1, 2, 3, 4) del; + +newpoints + +newfaces +(1, 2, 5); +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + + + + + +rule "pyramid with one trig" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0.5, -0.5); + +mapfaces +(1, 2, 3, 4) del; +(2, 1, 5) del; + +newpoints + +newfaces +(2, 3, 5); +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 }; +{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 }; +{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P3 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 }; +{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 }; +{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P3 }; + +orientations +(1, 2, 3, 5); +(1, 3, 4, 5); + + +freeset +1 2 3 5; +freeset +1 3 4 5; +freeset +2 3 5 6; +freeset +3 4 5 7; +freeset +1 4 5 8; +endrule + + + + + + +rule "pyramid with two trig" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(1, 1, 0); +(0, 1, 0); +(0.5, 0.5, -0.5); + +mapfaces +(1, 2, 3, 4) del; +(2, 1, 5) del; +(3, 2, 5) del; +newpoints + +newfaces +(3, 4, 5); +(4, 1, 5); + +elements +(1, 2, 3, 4, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +endrule + + + diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramids2.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramids2.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramids2.rls 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramids2.rls 1970-01-01 00:00:00.000000000 +0000 @@ -1,303 +0,0 @@ -tolfak 0.5 - -rule "Pyramid on quad" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); - -mapfaces -(1, 2, 3, 4) del; - -newpoints -(0.5, 0.5, -0.5) - { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } - { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; - -newfaces -(1, 2, 5); -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - -rule "small Pyramid on quad" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); - -mapfaces -(1, 2, 3, 4) del; - -newpoints -(0.5, 0.5, -0.1 ) - { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } - { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; - -newfaces -(1, 2, 5); -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - - - -rule "connect pyramid" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0.5, -0.5); - -mapfaces -(1, 2, 3, 4) del; - -newpoints - -newfaces -(1, 2, 5); -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - - - - - -rule "pyramid with one trig" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0.5, -0.5); - -mapfaces -(1, 2, 3, 4) del; -(2, 1, 5) del; - -newpoints - -newfaces -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 }; -{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 }; -{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P2 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 }; -{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 }; -{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P2 }; - -orientations -(1, 2, 3, 5); -(1, 3, 4, 5); - - -freeset -1 2 3 5; -freeset -1 3 4 5; -freeset -2 3 5 6; -freeset -3 4 5 7; -freeset -1 4 5 8; -endrule - - - - - - -rule "pyramid with two trig" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0.5, -0.5); - -mapfaces -(1, 2, 3, 4) del; -(2, 1, 5) del; -(3, 2, 5) del; -newpoints - -newfaces -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - - - - - - -rule "pyramid with two trig, left" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0.5, -0.5); - -mapfaces -(1, 2, 3, 4) del; -(2, 1, 5) del; -(1, 4, 5) del; -newpoints - -newfaces -(3, 4, 5); -(2, 3, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - - - diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramids.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramids.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/pyramids.rls 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/pyramids.rls 1970-01-01 00:00:00.000000000 +0000 @@ -1,257 +0,0 @@ -tolfak 0.5 - -rule "Pyramid on quad" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); - -mapfaces -(1, 2, 3, 4) del; - -newpoints -(0.5, 0.5, -0.5) - { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } - { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; - -newfaces -(1, 2, 5); -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - -rule "small Pyramid on quad" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); - -mapfaces -(1, 2, 3, 4) del; - -newpoints -(0.5, 0.5, -0.1 ) - { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } - { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { }; - -newfaces -(1, 2, 5); -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - - - -rule "connect pyramid" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0.5, -0.5); - -mapfaces -(1, 2, 3, 4) del; - -newpoints - -newfaces -(1, 2, 5); -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - - - - - -rule "pyramid with one trig" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0.5, -0.5); - -mapfaces -(1, 2, 3, 4) del; -(2, 1, 5) del; - -newpoints - -newfaces -(2, 3, 5); -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 }; -{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 }; -{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P3 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 }; -{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 }; -{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P3 }; - -orientations -(1, 2, 3, 5); -(1, 3, 4, 5); - - -freeset -1 2 3 5; -freeset -1 3 4 5; -freeset -2 3 5 6; -freeset -3 4 5 7; -freeset -1 4 5 8; -endrule - - - - - - -rule "pyramid with two trig" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(1, 1, 0); -(0, 1, 0); -(0.5, 0.5, -0.5); - -mapfaces -(1, 2, 3, 4) del; -(2, 1, 5) del; -(3, 2, 5) del; -newpoints - -newfaces -(3, 4, 5); -(4, 1, 5); - -elements -(1, 2, 3, 4, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -endrule - - - diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/quad.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/quad.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/quad.rls 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/quad.rls 1970-01-01 00:00:00.000000000 +0000 @@ -1,759 +0,0 @@ -rule "Free Quad (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); - -maplines -(1, 2) del; - -newpoints -(1, 1) { 1 X2 } { }; -(0, 1) { } { }; - -newlines -(3, 2); -(4, 3); -(1, 4); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 1.5) { 1.5 X2 } { }; -(-0.5, 1.5) { -0.5 X2 } { }; - -elements -(1, 2, 3, 4); - -endrule - - - - -rule "Free Quad (5)" - -quality 5 - -mappoints -(0, 0); -(1, 0); - -maplines -(1, 2) del; - -newpoints -(1, 1) { 1 X2 } { }; -(0, 1) { } { }; - -newlines -(3, 2); -(4, 3); -(1, 4); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 1.5) { 1.5 X2 } { }; -(-0.5, 1.5) { -0.5 X2 } { }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X2 } { }; -(0, 1) { } { }; - -elements -(1, 2, 3, 4); - -endrule - - - - - - - - -rule "Quad Right (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(1, 1); - -maplines -(1, 2) del; -(2, 3) del; - -newpoints -(0, 1) { } { 1 y3 }; - -newlines -(1, 4); -(4, 3); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(-0.5, 1.5) { } { 1.5 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { } { 1 Y3 }; - -elements -(1, 2, 3, 4); - -endrule - - - -rule "Quad P Right (2)" - -quality 2 - -mappoints -(0, 0); -(1, 0); -(1, 1); - -maplines -(1, 2) del; - -newpoints -(0, 1) { -1 X2, 1 X3 } { 1 Y3 }; - -newlines -(1, 4); -(4, 3); -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 }; -(1, 1) { 1 X3 } { 1 Y3 }; -(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { -1 X2, 1 X3 } { 1 Y3 }; - -elements -(1, 2, 3, 4); - - -orientations -(1, 2, 3); - - -endrule - - -rule "Quad Right PL (2)" - -quality 2 - -mappoints -(0, 0); -(1, 0); -(1, 1); -(0, 1); - -maplines -(1, 2) del; -(2, 3) del; - -newpoints - -newlines -(1, 4); -(4, 3); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 }; -(0, 1) { 1 X4 } { 1 Y4 }; -(-0.2, 0.5) { -0.1 X2, -0.1 X3, 0.6 X4 } { -0.1 Y2, -0.1 Y3, 0.6 Y4 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; -(0, 1) { 1 X4 } { 1 Y4 }; -(0, 0.5) { 0.5 X4 } { 0.5 Y4 }; - -elements -(1, 2, 3, 4); - -orientations -(1, 2, 3); -(1, 3, 4); -(1, 2, 4); -(4, 2, 3); - - -endrule - - - - - - - - - -rule "Left Quad (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(0, 1); - -maplines -(1, 2) del; -(3, 1) del; - -newpoints -(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; - -newlines -(3, 4); -(4, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 }; -(0, 1) { 1 X3 } { 1 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; -(0, 1) { 1 X3 } { 1 Y3 }; - -elements -(1, 2, 4, 3); - -endrule - - - -rule "Left P Quad (2)" - -quality 2 - -mappoints -(0, 0); -(1, 0); -(0, 1); - -maplines -(1, 2) del; - -newpoints -(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; - -newlines -(1, 3); -(3, 4); -(4, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 }; -(0, 1) { 1 X3 } { 1 Y3 }; -(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; -(0, 1) { 1 X3 } { 1 Y3 }; -(0, 0.5) { 0.5 X3 } { 0.5 Y3 }; - -elements -(1, 2, 4, 3); - -endrule - - - - - -rule "Left Quad RP (2)" - -quality 2 - -mappoints -(0, 0); -(1, 0); -(0, 1); -(1, 1); - -maplines -(1, 2) del; -(3, 1) del; - -newpoints - -newlines -(3, 4); -(4, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.2, 0.5) { 0.6 X2, 0.6 X4, -0.1 X3 } { 0.6 Y2, 0.6 Y4, -0.1 Y3 }; -(1, 1) { 1 X4 } { 1 Y4 }; -(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 }; -(0, 1) { 1 X3 } { 1 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 0.5) { 0.5 X2, 0.5 X4 } { 0.5 Y2, 0.5 Y4 }; -(1, 1) { 1 X4 } { 1 Y4 }; -(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; -(0, 1) { 1 X3 } { 1 Y3 }; - -elements -(1, 2, 4, 3); - -orientations -(1, 2, 4); -(1, 4, 3); - -endrule - - - - - - -rule "Two left (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(1, 1); -(0, 1); - -maplines -(1, 2) del; -(3, 4) del; -(4, 1) del; - -newpoints - -newlines -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { 1 X4 } { 1 Y4 }; - - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { 1 X4 } { 1 Y4 }; - -elements -(1, 2, 3, 4); - -endrule - - - - -rule "Two Right (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(1, 1); -(0, 1); - -maplines -(1, 2) del; -(2, 3) del; -(3, 4) del; - -newpoints - -newlines -(1, 4); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { 1 X4 } { 1 Y4 }; -(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { 1 X4 } { 1 Y4 }; -(0, 0.5) { 0.5 X4 } { 0.5 Y4 }; - -elements -(1, 2, 3, 4); - -endrule - - - - - - - - - - - - - - - - -rule "Right 120 (1)" - -quality 1000 - -mappoints -(0, 0); -(1, 0); -(1.5, 0.866); - -maplines -(1, 2) del; -(2, 3) del; - -newpoints -(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 }; - -newlines -(1, 4); -(4, 3); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.866) { 1 X3 } { 1 Y3 }; -(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 }; -(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 }; -(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 }; - -elements -(1, 2, 4); -(2, 3, 4); - -endrule - - - - -rule "Left 120 (1)" - -quality 1000 - -mappoints -(0, 0); -(1, 0); -(-0.5, 0.866); - -maplines -(1, 2) del; -(3, 1) del; - -newpoints -(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 }; - -newlines -(3, 4); -(4, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 }; -(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 }; -(0, 1.732) { -1 X2, 2 X3 } { 2 Y3 }; -(-0.5, 0.866) { 1 X3 } {1 Y3 }; - -elements -(1, 2, 4); -(2, 3, 4); - -endrule - - - - -rule "Left Right (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(1, 1); -(0, 1); - -maplines -(1, 2) del; -(2, 3) del; -(4, 1) del; - - -newlines -(4, 3); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0.5, 1.5) { -0.25 X2, 0.75 X3, 0.75 X4 } { 0.75 Y3, 0.75 Y4 }; -(0, 1) { 1 X4 } { 1 Y4 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; -(0, 1) { 1 X4 } { 1 Y4 }; - - -elements -(1, 2, 3, 4); - -endrule - - - - - -rule "Fill Quad" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(1, 1); -(0, 1); - -maplines -(1, 2) del; -(2, 3) del; -(3, 4) del; -(4, 1) del; - -newpoints - -newlines - -freearea -(0, 0); -(1, 0) { 1 X2 } { 1 Y2 }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { 1 X4 } { 1 Y4 }; - -elements -(1, 2, 3, 4); - -endrule - - - - -rule "Fill Triangle" - -quality 10 - -mappoints -(0, 0); -(1, 0); -(0.5, 0.86); - -maplines -(1, 2) del; -(2, 3) del; -(3, 1) del; - -newpoints - -newlines - -freearea -(0, 0); -(1, 0) { 1 X2 } { 1 Y2 }; -(0.5, 0.86) { 1 X3 } { 1 Y3 }; - -elements -(1, 2, 3); - -endrule - - - -rule "Right 60 (1)" - -quality 10 - -mappoints -(0, 0); -(1, 0) { 0.5, 0, 1.0 }; -(0.5, 0.866) { 0.6, 0, 0.8 }; - -maplines -(1, 2) del; -(2, 3) del; - -newpoints - -newlines -(1, 3); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; -(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; -(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 }; - -elements -(1, 2, 3); - -endrule - - - - -rule "Vis A Vis (2)" - -quality 2 - -mappoints -(0, 0); -(1, 0); -(1, 1); -(0, 1); - -maplines -(1, 2) del; -(3, 4) del; - -newpoints - -newlines -(1, 4); -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { 1 X4 } { 1 Y4 }; -(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 }; -(1, 1) { 1 X3 } { 1 Y3 }; -(0, 1) { 1 X4 } { 1 Y4 }; -(0, 0.5) { 0.5 X4 } { 0.5 Y4 }; - -elements -(1, 2, 3, 4); - -orientations -(1, 3, 4); -(2, 3, 4); -(1, 2, 3); -(1, 2, 4); - -endrule - - - - - - -rule "2 h Vis A Vis (1)" - -quality 3000 - -mappoints -(0, 0); -(1, 0); -(1, 1.732); -(0, 1.732); - -maplines -(1, 2) del; -(3, 4) del; - -newpoints -(0.5, 0.866) { 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 }; - -newlines -(1, 5); -(5, 4); -(3, 5); -(5, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { 1 Y2 }; -(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 }; -(1, 1.732) { 1 X3 } { 1 Y3 }; -(0, 1.732) { 1 X4 } { 1 Y4 }; -(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 }; - -elements -(1, 2, 5); -(3, 4, 5); - -endrule - - - - - diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/quadrules.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/quadrules.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/quadrules.rls 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/quadrules.rls 2021-06-04 23:36:22.000000000 +0000 @@ -0,0 +1,881 @@ +rule "Free Quad (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); + +maplines +(1, 2) del; + +newpoints +(1, 1) { 1 X2 } { }; +(0, 1) { } { }; + +newlines +(3, 2); +(4, 3); +(1, 4); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 1.5) { 1.5 X2 } { }; +(-0.5, 1.5) { -0.5 X2 } { }; + +elements +(1, 2, 3, 4); + +endrule + + + + +rule "Free Quad (5)" + +quality 5 + +mappoints +(0, 0); +(1, 0); + +maplines +(1, 2) del; + +newpoints +(1, 1) { 1 X2 } { }; +(0, 1) { } { }; + +newlines +(3, 2); +(4, 3); +(1, 4); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 1.5) { 1.5 X2 } { }; +(-0.5, 1.5) { -0.5 X2 } { }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X2 } { }; +(0, 1) { } { }; + +elements +(1, 2, 3, 4); + +endrule + + + + + + + + +rule "Quad Right (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(1, 1); + +maplines +(1, 2) del; +(2, 3) del; + +newpoints +(0, 1) { } { 1 y3 }; + +newlines +(1, 4); +(4, 3); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(-0.5, 1.5) { } { 1.5 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { } { 1 Y3 }; + +elements +(1, 2, 3, 4); + +endrule + + + +rule "Quad P Right (2)" + +quality 2 + +mappoints +(0, 0); +(1, 0); +(1, 1); + +maplines +(1, 2) del; + +newpoints +(0, 1) { -1 X2, 1 X3 } { 1 Y3 }; + +newlines +(1, 4); +(4, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { -1 X2, 1 X3 } { 1 Y3 }; + +elements +(1, 2, 3, 4); + + +orientations +(1, 2, 3); + + +endrule + + +rule "Quad P Right (150)" + +quality 150 + +mappoints +(0, 0); +(1, 0); +(1, 1); + +maplines +(1, 2) del; + +newpoints +(0, 1) { 1 X2, -1 X3 } { 1 Y3 }; + +newlines +(1, 4); +(4, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X2, -1 X3 } { 1 Y3 }; + +elements +(1, 2, 3, 4); + +orientations +(1, 2, 3); + +endrule + + +rule "Quad Right PL (2)" + +quality 2 + +mappoints +(0, 0); +(1, 0); +(1, 1); +(0, 1); + +maplines +(1, 2) del; +(2, 3) del; + +newpoints + +newlines +(1, 4); +(4, 3); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 }; +(0, 1) { 1 X4 } { 1 Y4 }; +(-0.2, 0.5) { -0.1 X2, -0.1 X3, 0.6 X4 } { -0.1 Y2, -0.1 Y3, 0.6 Y4 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; +(0, 1) { 1 X4 } { 1 Y4 }; +(0, 0.5) { 0.5 X4 } { 0.5 Y4 }; + +elements +(1, 2, 3, 4); + +orientations +(1, 2, 3); +(1, 3, 4); +(1, 2, 4); +(4, 2, 3); + + +endrule + + + + + + + + + +rule "Left Quad (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(0, 1); + +maplines +(1, 2) del; +(3, 1) del; + +newpoints +(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; + +newlines +(3, 4); +(4, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 }; +(0, 1) { 1 X3 } { 1 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; +(0, 1) { 1 X3 } { 1 Y3 }; + +elements +(1, 2, 4, 3); + +endrule + + + +rule "Left P Quad (2)" + +quality 2 + +mappoints +(0, 0); +(1, 0); +(0, 1); + +maplines +(1, 2) del; + +newpoints +(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; + +newlines +(1, 3); +(3, 4); +(4, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 }; +(0, 1) { 1 X3 } { 1 Y3 }; +(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X2, 1 X3 } { 1 Y3 }; +(0, 1) { 1 X3 } { 1 Y3 }; +(0, 0.5) { 0.5 X3 } { 0.5 Y3 }; + +elements +(1, 2, 4, 3); + +endrule + + + + +rule "Left P Quad (150)" + +quality 150 + +mappoints +(0, 0); +(1, 0); +(0, 1); + +maplines +(1, 2) del; + +newpoints +(1, 1) { 1 X2, -1 X3 } { 1 Y3 }; + +newlines +(1, 3); +(3, 4); +(4, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 }; +(0, 1) { 1 X3 } { 1 Y3 }; +(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X2, -1 X3 } { 1 Y3 }; +(0, 1) { 1 X3 } { 1 Y3 }; +(0, 0.5) { 0.5 X3 } { 0.5 Y3 }; + +elements +(1, 2, 4, 3); + +endrule + + + + + +rule "Left Quad RP (2)" + +quality 2 + +mappoints +(0, 0); +(1, 0); +(0, 1); +(1, 1); + +maplines +(1, 2) del; +(3, 1) del; + +newpoints + +newlines +(3, 4); +(4, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.2, 0.5) { 0.6 X2, 0.6 X4, -0.1 X3 } { 0.6 Y2, 0.6 Y4, -0.1 Y3 }; +(1, 1) { 1 X4 } { 1 Y4 }; +(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 }; +(0, 1) { 1 X3 } { 1 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.5) { 0.5 X2, 0.5 X4 } { 0.5 Y2, 0.5 Y4 }; +(1, 1) { 1 X4 } { 1 Y4 }; +(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; +(0, 1) { 1 X3 } { 1 Y3 }; + +elements +(1, 2, 4, 3); + +orientations +(1, 2, 4); +(1, 4, 3); + +endrule + + + + + + +rule "Two left (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(1, 1); +(0, 1); + +maplines +(1, 2) del; +(3, 4) del; +(4, 1) del; + +newpoints + +newlines +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X4 } { 1 Y4 }; + + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X4 } { 1 Y4 }; + +elements +(1, 2, 3, 4); + +endrule + + + + +rule "Two Right (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(1, 1); +(0, 1); + +maplines +(1, 2) del; +(2, 3) del; +(3, 4) del; + +newpoints + +newlines +(1, 4); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X4 } { 1 Y4 }; +(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X4 } { 1 Y4 }; +(0, 0.5) { 0.5 X4 } { 0.5 Y4 }; + +elements +(1, 2, 3, 4); + +endrule + + + + + + + + + + + + + + + + +rule "Right 120 (1)" + +quality 1000 + +mappoints +(0, 0); +(1, 0); +(1.5, 0.866); + +maplines +(1, 2) del; +(2, 3) del; + +newpoints +(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 }; + +newlines +(1, 4); +(4, 3); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.866) { 1 X3 } { 1 Y3 }; +(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 }; +(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 }; +(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 }; + +elements +(1, 2, 4); +(2, 3, 4); + +endrule + + + + +rule "Left 120 (1)" + +quality 1000 + +mappoints +(0, 0); +(1, 0); +(-0.5, 0.866); + +maplines +(1, 2) del; +(3, 1) del; + +newpoints +(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 }; + +newlines +(3, 4); +(4, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 }; +(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 }; +(0, 1.732) { -1 X2, 2 X3 } { 2 Y3 }; +(-0.5, 0.866) { 1 X3 } {1 Y3 }; + +elements +(1, 2, 4); +(2, 3, 4); + +endrule + + + + +rule "Left Right (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(1, 1); +(0, 1); + +maplines +(1, 2) del; +(2, 3) del; +(4, 1) del; + + +newlines +(4, 3); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0.5, 1.5) { -0.25 X2, 0.75 X3, 0.75 X4 } { 0.75 Y3, 0.75 Y4 }; +(0, 1) { 1 X4 } { 1 Y4 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; +(0, 1) { 1 X4 } { 1 Y4 }; + + +elements +(1, 2, 3, 4); + +endrule + + + + + +rule "Fill Quad" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(1, 1); +(0, 1); + +maplines +(1, 2) del; +(2, 3) del; +(3, 4) del; +(4, 1) del; + +newpoints + +newlines + +freearea +(0, 0); +(1, 0) { 1 X2 } { 1 Y2 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X4 } { 1 Y4 }; + +elements +(1, 2, 3, 4); + +endrule + + + + +rule "Fill Triangle" + +quality 10 + +mappoints +(0, 0); +(1, 0); +(0.5, 0.86); + +maplines +(1, 2) del; +(2, 3) del; +(3, 1) del; + +newpoints + +newlines + +freearea +(0, 0); +(1, 0) { 1 X2 } { 1 Y2 }; +(0.5, 0.86) { 1 X3 } { 1 Y3 }; + +elements +(1, 2, 3); + +endrule + + + +rule "Right 60 (1)" + +quality 10 + +mappoints +(0, 0); +(1, 0) { 0.5, 0, 1.0 }; +(0.5, 0.866) { 0.6, 0, 0.8 }; + +maplines +(1, 2) del; +(2, 3) del; + +newpoints + +newlines +(1, 3); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 }; + +elements +(1, 2, 3); + +endrule + + + + +rule "Vis A Vis (2)" + +quality 2 + +mappoints +(0, 0); +(1, 0); +(1, 1); +(0, 1); + +maplines +(1, 2) del; +(3, 4) del; + +newpoints + +newlines +(1, 4); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X4 } { 1 Y4 }; +(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 }; +(1, 1) { 1 X3 } { 1 Y3 }; +(0, 1) { 1 X4 } { 1 Y4 }; +(0, 0.5) { 0.5 X4 } { 0.5 Y4 }; + +elements +(1, 2, 3, 4); + +orientations +(1, 3, 4); +(2, 3, 4); +(1, 2, 3); +(1, 2, 4); + +endrule + + + + +rule "Triangle Vis A Vis (200)" + +quality 200 + +mappoints +(0, 0); +(1, 0); +(0.5, 0.866); + +maplines +(1, 2) del; + +newpoints + +newlines +(1, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 }; + +elements +(1, 2, 3); + +endrule + + + +rule "2 h Vis A Vis (1)" + +quality 3000 + +mappoints +(0, 0); +(1, 0); +(1, 1.732); +(0, 1.732); + +maplines +(1, 2) del; +(3, 4) del; + +newpoints +(0.5, 0.866) { 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 }; + +newlines +(1, 5); +(5, 4); +(3, 5); +(5, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { 1 Y2 }; +(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 }; +(1, 1.732) { 1 X3 } { 1 Y3 }; +(0, 1.732) { 1 X4 } { 1 Y4 }; +(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 }; + +elements +(1, 2, 5); +(3, 4, 5); + +endrule + + + + + diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/tetra.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/tetra.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/tetra.rls 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/tetra.rls 1970-01-01 00:00:00.000000000 +0000 @@ -1,1462 +0,0 @@ -tolfak 0.5 - -rule "Free Tetrahedron" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0); -(0.5, 0.866, 0); - -mapfaces -(1, 2, 3) del; - -newpoints -(0.5, 0.288, -0.816) - { 0.333 X1, 0.333 X2, 0.333 X3 } - { 0.333 Y1, 0.333 Y2, 0.333 Y3 } { }; - -newfaces -(4, 1, 2); -(4, 2, 3); -(4, 3, 1); - -elements -(1, 2, 3, 4); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1.6 P4, -0.2 P1, -0.2 P2, -0.2 P3 }; -{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 }; -{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 }; -{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 }; -endrule - - - - - - -rule "Tetrahedron 60" - -quality 1 - -flags c; - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 } ; -(0.5, 0.866, 0) { 0.5 }; -(0.5, 0.288, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; - -newpoints - -newfaces -(1, 4, 3); -(4, 2, 3); - -elements -(1, 2, 3, 4); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; -{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; -{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 }; - - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; -{ 0.65 P3, 0.35 P4 }; -endrule - - - - -rule "Tetrahedron 60 with edge(1)" - -quality 1 - -flags c; - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.8 }; -(0.5, 0.866, 0) { 0.8 }; -(0.5, 0.288, -0.816) { 0.8 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; - -mapedges -(3, 4); - -newpoints - -newfaces -(1, 4, 3); -(4, 2, 3); - -elements -(1, 2, 3, 4); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 }; -{ 0.4 P2, 0.4 P4, 0.4 P3, -0.2 P1 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.3333 P1, 0.3333 P4, 0.3334 P3 }; -{ 0.3333 P2, 0.3333 P4, 0.3334 P3 }; -endrule - - - - -rule "Tetrahedron Vis a Vis Point (1)" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 0.866, 0) { 0.5 }; -(0.5, 0.288, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; - -newpoints - -newfaces -(4, 3, 1); -(4, 2, 3); -(4, 1, 2); - -elements -(1, 2, 3, 4); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 }; -{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 }; -{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 }; -{ 0.8 P1, -0.1 P2, -0.1 P3, 0.4 P4 }; -{ -0.1 P1, 0.8 P2, -0.1 P3, 0.4 P4 }; -{ -0.1 P1, -0.1 P2, 0.8 P3, 0.4 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; -{ 0.7 P1, 0.3 P4 }; -{ 0.7 P2, 0.3 P4 }; -{ 0.7 P3, 0.3 P4 }; -endrule - - - -rule "Tetrahedron Vis a Vis Point with edge(1)" - -quality 1 - - - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 0.866, 0) { 0.5 }; -(0.5, 0.288, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; - -mapedges -(1, 4); - -newpoints - -newfaces -(4, 3, 1); -(4, 2, 3); -(4, 1, 2); - -elements -(1, 2, 3, 4); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; -{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; -{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 }; -{ -0.05 P1, 0.7 P2, -0.05 P3, 0.4 P4 }; -{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; -{ 0.65 P2, 0.35 P4 }; -{ 0.65 P3, 0.35 P4 }; -endrule - - - -rule "Tetrahedron Vis a Vis Point with 2 edges (1)" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 0.866, 0) { 0.5 }; -(0.5, 0.288, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; - -mapedges -(1, 4); -(2, 4); - -newpoints - -newfaces -(4, 3, 1); -(4, 2, 3); -(4, 1, 2); - -elements -(1, 2, 3, 4); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; -{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; -{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 }; -{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; -{ 0.65 P3, 0.35 P4 }; -endrule - - - - -rule "Tetrahedron Vis a Vis Point with 3 edges (1)" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 0.866, 0) { 0.5 }; -(0.5, 0.288, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; - -mapedges -(1, 4); -(2, 4); -(3, 4); - -newpoints - -newfaces -(4, 3, 1); -(4, 2, 3); -(4, 1, 2); - -elements -(1, 2, 3, 4); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; -{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; -{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; -{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; -endrule - - - - - - -rule "Tetrahedron Vis a Vis Triangle (1)" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 0.866, 0) { 0.5 }; -(0, 0, -0.816) { 0.5 }; -(1, 0, -0.816) { 0.5 }; -(0.5, 0.866, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(4, 6, 5) del; - -newpoints - -newfaces -(1, 2, 4); -(2, 5, 4); -(2, 3, 6); -(2, 6, 5); -(3, 1, 4); -(3, 4, 6); - - -elements -(1, 2, 3, 4); -(4, 2, 3, 6); -(4, 2, 6, 5); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ -0.2 P1, 0.35 P2, 0.35 P3, -0.2 P4, 0.35 P5, 0.35 P6 }; -{ 0.35 P1, -0.2 P2, 0.35 P3, 0.35 P4, -0.2 P5, 0.35 P6 }; -{ 0.35 P1, 0.35 P2, -0.2 P3, 0.35 P4, 0.35 P5, -0.2 P6 }; -endrule - - - - -rule "Octaeder 1" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.95 }; -(0.5, 0.866, 0) { 0.95 }; -(0.5, -0.288, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; - -newpoints -(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; -(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; - -newfaces -(2, 3, 5); -(3, 1, 6); -(3, 6, 5); -(2, 5, 4); -(1, 4, 6); -(4, 5, 6); - -elements -(3, 4, 1, 2); -(3, 4, 2, 5); -(3, 4, 5, 6); -(3, 4, 6, 1); - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; -(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 }; -( 1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 }; - -endrule - - - -rule "Octaeder 2" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.95 }; -(0.5, 0.866, 0) { 0.95 }; -(0.5, -0.288, -0.816) { 0.5 }; -(1, 0.578, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; - -newpoints -(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; - -newfaces -(2, 3, 5); -(3, 1, 6); -(3, 6, 5); -(2, 5, 4); -(1, 4, 6); -(4, 5, 6); - -elements -(3, 4, 1, 2); -(3, 4, 2, 5); -(3, 4, 5, 6); -(3, 4, 6, 1); - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; -(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 }; - -(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 } - { 0.333 Y2, 0.333 Y4, 0.333 Y5 } - { 0.333 Z2, 0.333 Z4, 0.333 Z5 }; -(0.9, 0.481, -0.272) { 0.333 X2, 0.333 X3, 0.333 X5 } - { 0.333 Y2, 0.333 Y3, 0.333 Y5 } - { 0.333 Z2, 0.333 Z3, 0.333 Z5 }; - -(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 }; - -endrule - - -rule "Octaeder 2a" - - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.95 }; -(0.5, 0.866, 0) { 0.95 }; -(0.5, -0.288, -0.816) { 0.5 }; -(1, 0.578, -0.816) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(3, 2, 5) del; - -newpoints -(0, 0.578, -0.816) - { -1 X2, 1 X3, 1 X4 } - { -1 Y2, 1 Y3, 1 Y4 } - { -1 Z2, 1 Z3, 1 Z4 }; - -newfaces -(1, 2, 4); -(3, 1, 6); -(3, 6, 5); -(2, 5, 4); -(1, 4, 6); -(4, 5, 6); - -elements -(3, 4, 1, 2); -(3, 4, 2, 5); -(3, 4, 5, 6); -(3, 4, 6, 1); - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; -(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 }; - -(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 } - { 0.333 Y2, 0.333 Y4, 0.333 Y5 } - { 0.333 Z2, 0.333 Z4, 0.333 Z5 }; - -(0.5, -0.097, -0.272) { 0.333 X2, 0.333 X4, 0.333 X1 } - { 0.333 Y2, 0.333 Y4, 0.333 Y1 } - { 0.333 Z2, 0.333 Z4, 0.333 Z1 }; - -(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 }; - -endrule - - - - -rule "Pyramid 1" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 }; -(0.5, 0.866, 0) { 1 }; -(0.5, -0.288, -0.816) { 1 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; - -newpoints -(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; - -newfaces -(1, 4, 3); -(2, 3, 5); -(2, 5, 4); -(4, 5, 3); - -elements -(1, 2, 3, 4); -(4, 2, 3, 5); - - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; -(0, 1, -1) { 0.5 X3, 0.5 X4 } { 1 Y3 } { 1 Z4 }; -(1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; - -endrule - - - - - - - - -rule "Tetrahedron 2 times 60" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.3 }; -(0.5, 0.866, 0) { 0.3 }; -(0.5, 0.288, -0.816) { 0.3 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(2, 4, 3) del; - -newpoints - -newfaces -(1, 4, 3); - -elements -(1, 2, 3, 4); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; -endrule - - - -rule "Fill Tetrahedron (1)" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.2 }; -(0.5, 0.866, 0) { 0.2 }; -(0.5, 0.288, -0.816) { 0.2 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(2, 4, 3) del; -(3, 4, 1) del; - -newpoints - -newfaces - -elements -(1, 2, 3, 4); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -endrule - - - - - - - - - - -rule "Tetrahedron 120 (1)" - -quality 1 - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 }; -(0.5, 0.866, 0) { 1 }; -(0.5, -0.674, -0.544) { 1 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; - -newpoints -(0.5, 0.288, -0.816) - { -0.5 X1, -0.5 X2, 1 X3, 1 X4 } - { -0.5 Y1, -0.5 Y2, 1 Y3, 1 Y4} - { -0.5 Z1, -0.5 Z2, 1 Z3, 1 Z4}; - -newfaces -(1, 5, 3); -(3, 5, 2); -(1, 4, 5); -(2, 5, 4); - -elements -(1, 2, 3, 5); -(1, 4, 2, 5); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.3 P5, -0.3 P1 }; -{ 1.3 P5, -0.3 P2 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P5 }; -endrule - - - - - -rule "Tetrahedron 2 times 120 (1)" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 }; -(0.5, 0.866, 0) { 1 }; -(0.5, -0.674, -0.544) { 0.8 }; -(1.334, 0.77, -0.544) { 0.8 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(3, 2, 5) del; - -newpoints -(0.5, 0.288, -0.816) { 0.25 X1, -0.5 X2, 0.25 X3, 0.5 X4, 0.5 X5 } - { 0.25 Y1, -0.5 Y2, 0.25 Y3, 0.5 Y4, 0.5 Y5 } - { 0.25 Z1, -0.5 Z2, 0.25 Z3, 0.5 Z4, 0.5 Z5 }; - -newfaces -(6, 3, 1); -(6, 1, 4); -(6, 4, 2); -(6, 2, 5); -(6, 5, 3); - -elements -(1, 2, 3, 6); -(1, 4, 2, 6); -(2, 5, 3, 6); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1.4 P6, -0.4 P2 }; -{ 1.4 P6, -0.4 P1 }; -{ 1.4 P6, -0.4 P3 }; -endrule - - - - -rule "four Tetrahedron non convex (4)" - -quality 4 -flags l; - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.1 }; -(0.5, 1, 0) { 0.1 }; -(0.5, 0, -1) { 0.1 }; -(0.5, 0.3, -0.3) { 0.1 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(1, 5, 4) del; -(1, 3, 5) del; - - -newpoints -(0.5, 0.1, -0.1) - { 0.333 X1, 0.333 X2, 0.334 X5 } - { 0.333 Y1, 0.333 Y2, 0.334 Y5 } - { 0.333 Z1, 0.333 Z2, 0.334 Z5 }; - -newfaces -(6, 2, 3) del; -(6, 4, 2) del; -(6, 5, 4) del; -(6, 3, 5) del; - - -elements -(1, 2, 3, 6); -(1, 4, 2, 6); -(1, 5, 4, 6); -(1, 3, 5, 6); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1.5 P6, -0.5 P1 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; - - - -freeset -1 6 2 3; - -freeset -1 6 3 5; - -freeset -1 6 5 4; - -freeset -1 6 4 2; - -endrule - - - - - - -rule "five Tetrahedron non convex (4)" - -quality 4 -flags l; - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 1, 0) { 0.5 }; -(0, 0.8, -0.2) { 0.5 }; -(0, 0.2, -0.8) { 0.5 }; -(0.5, 0, -1) { 0.5 }; - - -mapfaces -(1, 2, 3) del; -(1, 3, 4) del; -(1, 4, 5) del; -(1, 5, 6) del; -(1, 6, 2) del; - -newpoints -(0.1, 0.1, -0.1) - { 0.75 X1, 0.05 X2, 0.05 X3, 0.05 X4, 0.05 X5, 0.05 X6 } - { 0.75 Y1, 0.05 Y2, 0.05 Y3, 0.05 Y4, 0.05 Y5, 0.05 Y6 } - { 0.75 Z1, 0.05 Z2, 0.05 Z3, 0.05 Z4, 0.05 Z5, 0.05 Z6 }; - -newfaces -(7, 2, 3); -(7, 3, 4); -(7, 4, 5); -(7, 5, 6); -(7, 6, 2); - - -elements -(1, 2, 3, 7); -(1, 3, 4, 7); -(1, 4, 5, 7); -(1, 5, 6, 7); -(1, 6, 2, 7); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 1.5 P7, -0.5 P1 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; -{ 1 P7 }; - - - -freeset -1 7 2 3; - -freeset -1 7 3 4; - -freeset -1 7 4 5; - -freeset -1 7 5 6; - -freeset -1 7 6 2; - -endrule - - - - - - - -rule "four Tetrahedron non convex (6)" - -quality 6 -flags l; - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 1, 0) { 0.5 }; -(0.5, 0, -1) { 0.5 }; -(0.5, 0.3, -0.3) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(1, 5, 4) del; -(1, 3, 5) del; - - -newpoints -(0.095, 0.003, -0.003) - { 0.9 X1, 0.09 X2, 0.01 X5 } - { 0.9 Y1, 0.09 Y2, 0.01 Y5 } - { 0.9 Z1, 0.09 Z2, 0.01 Z5 }; - -newfaces -(6, 2, 3) del; -(6, 4, 2) del; -(6, 5, 4) del; -(6, 3, 5) del; - - -elements -(1, 2, 3, 6); -(1, 4, 2, 6); -(1, 5, 4, 6); -(1, 3, 5, 6); - - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1.499 P6, -0.5 P1, 0.001 P2 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; - - - -freeset -1 6 2 3; - -freeset -1 6 3 5; - -freeset -1 6 5 4; - -freeset -1 6 4 2; - -endrule - - - - - - - - - - - - - - - - - -rule "four Tetrahedron non convex (6)" - -quality 100 - - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 1, 0) { 0.5 }; -(0.5, 0, -1) { 0.5 }; -(0.5, 0.4, -0.4) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(4, 5, 2) del; -(5, 3, 2) del; - -newpoints -(0.925, 0.02, -0.02) - { 0.05 X1, 0.9 X2, 0.05 X5 } - { 0.05 Y1, 0.9 Y2, 0.05 Y5 } - { 0.05 Z1, 0.9 Z2, 0.05 Z5 }; - -newfaces -(3, 1, 6); -(1, 4, 6); -(4, 5, 6); -(5, 3, 6); - -elements -(3, 1, 2, 6); -(1, 4, 2, 6); -(4, 5, 2, 6); -(5, 3, 2, 6); - -orientations -(3, 1, 2, 5); -(1, 4, 2, 5); -(2, 4, 5, 1); -(3, 2, 5, 1); -(5, 4, 2, 3); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1.5 P6, -0.5 P2 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; -{ 1 P6 }; - -freeset -3 1 2 6; - -freeset -1 4 2 6; - -freeset -4 5 2 6; - -freeset -5 3 2 6; - -endrule - - - - - - - - - - -rule "three Tetrahedron non convex (4)" - -quality 4 -flags l; - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 1, 0) { 0.5 }; -(0.5, 0, -1) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(1, 3, 4) del; - -newpoints -(0.5, 0.25, -0.25) - { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } - { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } - { 0.25 Z1, 0.25 Z2, 0.25 Z3, 0.25 Z4 }; - -newfaces -(5, 2, 3); -(5, 4, 2); -(5, 3, 4); - -elements -(2, 3, 1, 5); -(3, 4, 1, 5); -(4, 2, 1, 5; - -orientations -(1, 2, 4, 3); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.5 P5, -0.5 P1 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -freeset -1 4 2 5; - -endrule - - - - - -rule "three Tetrahedron non convex (6)" - -quality 100 - - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 1, 0) { 0.5 }; -(0.5, 0, -1) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(1, 3, 4) del; - -newpoints -(0.2, 0.1, -0.1) - { 0.7 X1, 0.1 X2, 0.1 X3, 0.1 X4 } - { 0.7 Y1, 0.1 Y2, 0.1 Y3, 0.1 Y4 } - { 0.7 Z1, 0.1 Z2, 0.1 Z3, 0.1 Z4 }; - -newfaces -(5, 2, 3); -(5, 4, 2); -(5, 3, 4); - -elements -(2, 3, 1, 5); -(3, 4, 1, 5); -(4, 2, 1, 5; - -orientations -(1, 2, 3, 4); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.5 P5, -0.5 P1 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 3 4 5; - -freeset -1 4 2 5; - -endrule - - - - - - - - - - -rule "four Tetrahedron non convex (6)" - -quality 100 - - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 1, 0) { 0.5 }; -(0.5, 0, -1) { 0.5 }; -(0.5, 0.4, -0.4) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; -(4, 5, 2) del; -(5, 3, 2) del; - -newpoints -(0.7, 0.08, -0.08) { 0.6 X2, 0.2 X5 } { 0.2 Y5 } { 0.2 Z5 }; - -newfaces -(3, 1, 6); -(1, 4, 6); -(4, 5, 6); -(5, 3, 6); - -elements -(3, 1, 2, 6); -(1, 4, 2, 6); -(4, 5, 2, 6); -(5, 3, 2, 6); - - -orientations -(3, 1, 2, 5); -(5, 1, 2, 4); - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 1, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, 0, -1) { 1 X4 } { 1 Y4 } { 1 Z4 }; -(0.5, 0.4, -0.4) { 1 X5 } { 1 Y5 } { 1 Z5 }; -(0.55, 0.12, -0.12) { 0.4 X2, 0.3 X5 } { 0.3 Y5 } { 0.3 Z5 }; - -freeset -3 1 2 6; - -freeset -1 4 2 6; - -freeset -4 5 2 6; - -freeset -5 3 2 6; - -endrule - - - - - - - - - - - -rule "Tetrahedron 2 in 60 (12)" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 0.5 }; -(0.5, 1, 0) { 0.5 }; -(0.5, 0, -1) { 0.5 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2) del; - -newpoints -(0.5, 0.1, -0.1) - { 0.4 X1, 0.4 X2, 0.1 X3, 0.1 X4 } - { 0.4 Y1, 0.4 Y2, 0.1 Y3, 0.1 Y4 } - { 0.4 Z1, 0.4 Z2, 0.1 Z3, 0.1 Z4 }; - -newfaces -(5, 2, 3); -(5, 3, 1); -(5, 4, 2); -(5, 1, 4); - -elements -(1, 2, 3, 5); -(1, 2, 5, 4); - -freezone2 -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1.5 P5, -0.25 P1, -0.25 P2 }; - -freezonelimit -{ 1 P1 }; -{ 1 P2 }; -{ 1 P3 }; -{ 1 P4 }; -{ 1 P5 }; - -freeset -1 2 3 5; - -freeset -1 2 4 5; - -endrule - - - - -rule "Tetrahedron 120, but more than 180 (13)" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 1 }; -(0.5, 0.866, 0) { 1 }; -(0.5, -0.866, 0) { 1 }; - -mapfaces -(1, 2, 3) del; -(1, 4, 2); - -newpoints -(0.5, 0, -0.3) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; - -newfaces -(1, 5, 3); -(3, 5, 2); -(2, 5, 1); - -elements -(1, 2, 3, 5); - - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, -0.1, -0.4) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; - -endrule - - - - - -rule "Free Tetrahedron (14)" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 1.0 }; -(0.5, 0.866, 0) { 1.0 }; - -mapfaces -(1, 2, 3) del; - -newpoints -(0.5, 0.288, -0.2) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; - -newfaces -(4, 1, 2); -(4, 2, 3); -(4, 3, 1); - -elements -(1, 2, 3, 4); - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, 0.288, -0.25) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; - -endrule - - - -rule "Free Tetrahedron (15)" - -quality 100 - -mappoints -(0, 0, 0); -(1, 0, 0) { 1.0 }; -(0.5, 0.866, 0) { 1.0 }; - -mapfaces -(1, 2, 3) del; - -newpoints -(0.5, 0.288, -0.1) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; - -newfaces -(4, 1, 2); -(4, 2, 3); -(4, 3, 1); - -elements -(1, 2, 3, 4); - -freezone -(0, 0, 0); -(1, 0, 0) { 1 X2 } { } { }; -(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; -(0.5, 0.288, -0.15) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; - -endrule - diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/tetrules.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/tetrules.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/tetrules.rls 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/tetrules.rls 2021-06-04 23:36:22.000000000 +0000 @@ -0,0 +1,1461 @@ +tolfak 0.5 + +rule "Free Tetrahedron" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0); +(0.5, 0.866, 0); + +mapfaces +(1, 2, 3) del; + +newpoints +(0.5, 0.288, -0.816) + { 0.333 X1, 0.333 X2, 0.333 X3 } + { 0.333 Y1, 0.333 Y2, 0.333 Y3 } { }; + +newfaces +(4, 1, 2); +(4, 2, 3); +(4, 3, 1); + +elements +(1, 2, 3, 4); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1.6 P4, -0.2 P1, -0.2 P2, -0.2 P3 }; +{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 }; +{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 }; +{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 }; +endrule + + + + + + +rule "Tetrahedron 60" + +quality 1 + +flags c; + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 } ; +(0.5, 0.866, 0) { 0.5 }; +(0.5, 0.288, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; + +newpoints + +newfaces +(1, 4, 3); +(4, 2, 3); + +elements +(1, 2, 3, 4); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; +{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; +{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 }; + + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; +{ 0.65 P3, 0.35 P4 }; +endrule + + + + +rule "Tetrahedron 60 with edge(1)" + +quality 1 + +flags c; + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.8 }; +(0.5, 0.866, 0) { 0.8 }; +(0.5, 0.288, -0.816) { 0.8 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; + +mapedges +(3, 4); + +newpoints + +newfaces +(1, 4, 3); +(4, 2, 3); + +elements +(1, 2, 3, 4); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 }; +{ 0.4 P2, 0.4 P4, 0.4 P3, -0.2 P1 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.3333 P1, 0.3333 P4, 0.3334 P3 }; +{ 0.3333 P2, 0.3333 P4, 0.3334 P3 }; +endrule + + + + +rule "Tetrahedron Vis a Vis Point (1)" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 0.866, 0) { 0.5 }; +(0.5, 0.288, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; + +newpoints + +newfaces +(4, 3, 1); +(4, 2, 3); +(4, 1, 2); + +elements +(1, 2, 3, 4); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 }; +{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 }; +{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 }; +{ 0.8 P1, -0.1 P2, -0.1 P3, 0.4 P4 }; +{ -0.1 P1, 0.8 P2, -0.1 P3, 0.4 P4 }; +{ -0.1 P1, -0.1 P2, 0.8 P3, 0.4 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; +{ 0.7 P1, 0.3 P4 }; +{ 0.7 P2, 0.3 P4 }; +{ 0.7 P3, 0.3 P4 }; +endrule + + + +rule "Tetrahedron Vis a Vis Point with edge(1)" + +quality 1 + + + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 0.866, 0) { 0.5 }; +(0.5, 0.288, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; + +mapedges +(1, 4); + +newpoints + +newfaces +(4, 3, 1); +(4, 2, 3); +(4, 1, 2); + +elements +(1, 2, 3, 4); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; +{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; +{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 }; +{ -0.05 P1, 0.7 P2, -0.05 P3, 0.4 P4 }; +{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; +{ 0.65 P2, 0.35 P4 }; +{ 0.65 P3, 0.35 P4 }; +endrule + + + +rule "Tetrahedron Vis a Vis Point with 2 edges (1)" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 0.866, 0) { 0.5 }; +(0.5, 0.288, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; + +mapedges +(1, 4); +(2, 4); + +newpoints + +newfaces +(4, 3, 1); +(4, 2, 3); +(4, 1, 2); + +elements +(1, 2, 3, 4); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; +{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; +{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 }; +{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; +{ 0.65 P3, 0.35 P4 }; +endrule + + + + +rule "Tetrahedron Vis a Vis Point with 3 edges (1)" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 0.866, 0) { 0.5 }; +(0.5, 0.288, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; + +mapedges +(1, 4); +(2, 4); +(3, 4); + +newpoints + +newfaces +(4, 3, 1); +(4, 2, 3); +(4, 1, 2); + +elements +(1, 2, 3, 4); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 }; +{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 }; +{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.3333 P2, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; +{ 0.3333 P1, 0.3333 P2, 0.3334 P4 }; +endrule + + + + + + +rule "Tetrahedron Vis a Vis Triangle (1)" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 0.866, 0) { 0.5 }; +(0, 0, -0.816) { 0.5 }; +(1, 0, -0.816) { 0.5 }; +(0.5, 0.866, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(4, 6, 5) del; + +newpoints + +newfaces +(1, 2, 4); +(2, 5, 4); +(2, 3, 6); +(2, 6, 5); +(3, 1, 4); +(3, 4, 6); + + +elements +(1, 2, 3, 4); +(4, 2, 3, 6); +(4, 2, 6, 5); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ -0.2 P1, 0.35 P2, 0.35 P3, -0.2 P4, 0.35 P5, 0.35 P6 }; +{ 0.35 P1, -0.2 P2, 0.35 P3, 0.35 P4, -0.2 P5, 0.35 P6 }; +{ 0.35 P1, 0.35 P2, -0.2 P3, 0.35 P4, 0.35 P5, -0.2 P6 }; +endrule + + + + +rule "Octaeder 1" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.95 }; +(0.5, 0.866, 0) { 0.95 }; +(0.5, -0.288, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; + +newpoints +(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; +(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; + +newfaces +(2, 3, 5); +(3, 1, 6); +(3, 6, 5); +(2, 5, 4); +(1, 4, 6); +(4, 5, 6); + +elements +(3, 4, 1, 2); +(3, 4, 2, 5); +(3, 4, 5, 6); +(3, 4, 6, 1); + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; +(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 }; +( 1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 }; + +endrule + + + +rule "Octaeder 2" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.95 }; +(0.5, 0.866, 0) { 0.95 }; +(0.5, -0.288, -0.816) { 0.5 }; +(1, 0.578, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; + +newpoints +(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; + +newfaces +(2, 3, 5); +(3, 1, 6); +(3, 6, 5); +(2, 5, 4); +(1, 4, 6); +(4, 5, 6); + +elements +(3, 4, 1, 2); +(3, 4, 2, 5); +(3, 4, 5, 6); +(3, 4, 6, 1); + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; +(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 }; + +(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 } + { 0.333 Y2, 0.333 Y4, 0.333 Y5 } + { 0.333 Z2, 0.333 Z4, 0.333 Z5 }; +(0.9, 0.481, -0.272) { 0.333 X2, 0.333 X3, 0.333 X5 } + { 0.333 Y2, 0.333 Y3, 0.333 Y5 } + { 0.333 Z2, 0.333 Z3, 0.333 Z5 }; + +(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 }; + +endrule + + +rule "Octaeder 2a" + + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.95 }; +(0.5, 0.866, 0) { 0.95 }; +(0.5, -0.288, -0.816) { 0.5 }; +(1, 0.578, -0.816) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(3, 2, 5) del; + +newpoints +(0, 0.578, -0.816) + { -1 X2, 1 X3, 1 X4 } + { -1 Y2, 1 Y3, 1 Y4 } + { -1 Z2, 1 Z3, 1 Z4 }; + +newfaces +(1, 2, 4); +(3, 1, 6); +(3, 6, 5); +(2, 5, 4); +(1, 4, 6); +(4, 5, 6); + +elements +(3, 4, 1, 2); +(3, 4, 2, 5); +(3, 4, 5, 6); +(3, 4, 6, 1); + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; +(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 }; + +(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 } + { 0.333 Y2, 0.333 Y4, 0.333 Y5 } + { 0.333 Z2, 0.333 Z4, 0.333 Z5 }; + +(0.5, -0.097, -0.272) { 0.333 X2, 0.333 X4, 0.333 X1 } + { 0.333 Y2, 0.333 Y4, 0.333 Y1 } + { 0.333 Z2, 0.333 Z4, 0.333 Z1 }; + +(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 }; + +endrule + + + + +rule "Pyramid 1" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 }; +(0.5, 0.866, 0) { 1 }; +(0.5, -0.288, -0.816) { 1 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; + +newpoints +(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; + +newfaces +(1, 4, 3); +(2, 3, 5); +(2, 5, 4); +(4, 5, 3); + +elements +(1, 2, 3, 4); +(4, 2, 3, 5); + + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 }; +(0, 1, -1) { 0.5 X3, 0.5 X4 } { 1 Y3 } { 1 Z4 }; +(1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; + +endrule + + + + + + + + +rule "Tetrahedron 2 times 60" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.3 }; +(0.5, 0.866, 0) { 0.3 }; +(0.5, 0.288, -0.816) { 0.3 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(2, 4, 3) del; + +newpoints + +newfaces +(1, 4, 3); + +elements +(1, 2, 3, 4); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 0.3333 P1, 0.3333 P3, 0.3334 P4 }; +endrule + + + +rule "Fill Tetrahedron (1)" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.2 }; +(0.5, 0.866, 0) { 0.2 }; +(0.5, 0.288, -0.816) { 0.2 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(2, 4, 3) del; +(3, 4, 1) del; + +newpoints + +newfaces + +elements +(1, 2, 3, 4); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +endrule + + + + + + + + + + +rule "Tetrahedron 120 (1)" + +quality 1 + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 }; +(0.5, 0.866, 0) { 1 }; +(0.5, -0.674, -0.544) { 1 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; + +newpoints +(0.5, 0.288, -0.816) + { -0.5 X1, -0.5 X2, 1 X3, 1 X4 } + { -0.5 Y1, -0.5 Y2, 1 Y3, 1 Y4} + { -0.5 Z1, -0.5 Z2, 1 Z3, 1 Z4}; + +newfaces +(1, 5, 3); +(3, 5, 2); +(1, 4, 5); +(2, 5, 4); + +elements +(1, 2, 3, 5); +(1, 4, 2, 5); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.3 P5, -0.3 P1 }; +{ 1.3 P5, -0.3 P2 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P5 }; +endrule + + + + + +rule "Tetrahedron 2 times 120 (1)" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 }; +(0.5, 0.866, 0) { 1 }; +(0.5, -0.674, -0.544) { 0.8 }; +(1.334, 0.77, -0.544) { 0.8 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(3, 2, 5) del; + +newpoints +(0.5, 0.288, -0.816) { 0.25 X1, -0.5 X2, 0.25 X3, 0.5 X4, 0.5 X5 } + { 0.25 Y1, -0.5 Y2, 0.25 Y3, 0.5 Y4, 0.5 Y5 } + { 0.25 Z1, -0.5 Z2, 0.25 Z3, 0.5 Z4, 0.5 Z5 }; + +newfaces +(6, 3, 1); +(6, 1, 4); +(6, 4, 2); +(6, 2, 5); +(6, 5, 3); + +elements +(1, 2, 3, 6); +(1, 4, 2, 6); +(2, 5, 3, 6); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1.4 P6, -0.4 P2 }; +{ 1.4 P6, -0.4 P1 }; +{ 1.4 P6, -0.4 P3 }; +endrule + + + + +rule "four Tetrahedron non convex (4)" + +quality 4 +flags l; + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.1 }; +(0.5, 1, 0) { 0.1 }; +(0.5, 0, -1) { 0.1 }; +(0.5, 0.3, -0.3) { 0.1 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(1, 5, 4) del; +(1, 3, 5) del; + + +newpoints +(0.5, 0.1, -0.1) + { 0.333 X1, 0.333 X2, 0.334 X5 } + { 0.333 Y1, 0.333 Y2, 0.334 Y5 } + { 0.333 Z1, 0.333 Z2, 0.334 Z5 }; + +newfaces +(6, 2, 3) del; +(6, 4, 2) del; +(6, 5, 4) del; +(6, 3, 5) del; + + +elements +(1, 2, 3, 6); +(1, 4, 2, 6); +(1, 5, 4, 6); +(1, 3, 5, 6); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1.5 P6, -0.5 P1 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; + + + +freeset +1 6 2 3; + +freeset +1 6 3 5; + +freeset +1 6 5 4; + +freeset +1 6 4 2; + +endrule + + + + + + +rule "five Tetrahedron non convex (4)" + +quality 4 +flags l; + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 1, 0) { 0.5 }; +(0, 0.8, -0.2) { 0.5 }; +(0, 0.2, -0.8) { 0.5 }; +(0.5, 0, -1) { 0.5 }; + + +mapfaces +(1, 2, 3) del; +(1, 3, 4) del; +(1, 4, 5) del; +(1, 5, 6) del; +(1, 6, 2) del; + +newpoints +(0.1, 0.1, -0.1) + { 0.75 X1, 0.05 X2, 0.05 X3, 0.05 X4, 0.05 X5, 0.05 X6 } + { 0.75 Y1, 0.05 Y2, 0.05 Y3, 0.05 Y4, 0.05 Y5, 0.05 Y6 } + { 0.75 Z1, 0.05 Z2, 0.05 Z3, 0.05 Z4, 0.05 Z5, 0.05 Z6 }; + +newfaces +(7, 2, 3); +(7, 3, 4); +(7, 4, 5); +(7, 5, 6); +(7, 6, 2); + + +elements +(1, 2, 3, 7); +(1, 3, 4, 7); +(1, 4, 5, 7); +(1, 5, 6, 7); +(1, 6, 2, 7); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 1.5 P7, -0.5 P1 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; +{ 1 P7 }; + + + +freeset +1 7 2 3; + +freeset +1 7 3 4; + +freeset +1 7 4 5; + +freeset +1 7 5 6; + +freeset +1 7 6 2; + +endrule + + + + + + + +rule "four Tetrahedron non convex (6)" + +quality 6 +flags l; + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 1, 0) { 0.5 }; +(0.5, 0, -1) { 0.5 }; +(0.5, 0.3, -0.3) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(1, 5, 4) del; +(1, 3, 5) del; + + +newpoints +(0.095, 0.003, -0.003) + { 0.9 X1, 0.09 X2, 0.01 X5 } + { 0.9 Y1, 0.09 Y2, 0.01 Y5 } + { 0.9 Z1, 0.09 Z2, 0.01 Z5 }; + +newfaces +(6, 2, 3) del; +(6, 4, 2) del; +(6, 5, 4) del; +(6, 3, 5) del; + + +elements +(1, 2, 3, 6); +(1, 4, 2, 6); +(1, 5, 4, 6); +(1, 3, 5, 6); + + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1.499 P6, -0.5 P1, 0.001 P2 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; + + + +freeset +1 6 2 3; + +freeset +1 6 3 5; + +freeset +1 6 5 4; + +freeset +1 6 4 2; + +endrule + + + + + + + + + + + + + + + + + +rule "four Tetrahedron non convex (6)" + +quality 100 + + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 1, 0) { 0.5 }; +(0.5, 0, -1) { 0.5 }; +(0.5, 0.4, -0.4) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(4, 5, 2) del; +(5, 3, 2) del; + +newpoints +(0.925, 0.02, -0.02) + { 0.05 X1, 0.9 X2, 0.05 X5 } + { 0.05 Y1, 0.9 Y2, 0.05 Y5 } + { 0.05 Z1, 0.9 Z2, 0.05 Z5 }; + +newfaces +(3, 1, 6); +(1, 4, 6); +(4, 5, 6); +(5, 3, 6); + +elements +(3, 1, 2, 6); +(1, 4, 2, 6); +(4, 5, 2, 6); +(5, 3, 2, 6); + +orientations +(3, 1, 2, 5); +(1, 4, 2, 5); +(2, 4, 5, 1); +(3, 2, 5, 1); +(5, 4, 2, 3); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1.5 P6, -0.5 P2 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; +{ 1 P6 }; + +freeset +3 1 2 6; + +freeset +1 4 2 6; + +freeset +4 5 2 6; + +freeset +5 3 2 6; + +endrule + + + + + + + + + + +rule "three Tetrahedron non convex (4)" + +quality 4 +flags l; + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 1, 0) { 0.5 }; +(0.5, 0, -1) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(1, 3, 4) del; + +newpoints +(0.5, 0.25, -0.25) + { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } + { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } + { 0.25 Z1, 0.25 Z2, 0.25 Z3, 0.25 Z4 }; + +newfaces +(5, 2, 3); +(5, 4, 2); +(5, 3, 4); + +elements +(2, 3, 1, 5); +(3, 4, 1, 5); +(4, 2, 1, 5; + +orientations +(1, 2, 4, 3); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.5 P5, -0.5 P1 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +freeset +1 4 2 5; + +endrule + + + + + +rule "three Tetrahedron non convex (6)" + +quality 100 + + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 1, 0) { 0.5 }; +(0.5, 0, -1) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(1, 3, 4) del; + +newpoints +(0.2, 0.1, -0.1) + { 0.7 X1, 0.1 X2, 0.1 X3, 0.1 X4 } + { 0.7 Y1, 0.1 Y2, 0.1 Y3, 0.1 Y4 } + { 0.7 Z1, 0.1 Z2, 0.1 Z3, 0.1 Z4 }; + +newfaces +(5, 2, 3); +(5, 4, 2); +(5, 3, 4); + +elements +(2, 3, 1, 5); +(3, 4, 1, 5); +(4, 2, 1, 5; + +orientations +(1, 2, 3, 4); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.5 P5, -0.5 P1 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 3 4 5; + +freeset +1 4 2 5; + +endrule + + + + + + + + + + +rule "four Tetrahedron non convex (6)" + +quality 100 + + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 1, 0) { 0.5 }; +(0.5, 0, -1) { 0.5 }; +(0.5, 0.4, -0.4) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; +(4, 5, 2) del; +(5, 3, 2) del; + +newpoints +(0.7, 0.08, -0.08) { 0.6 X2, 0.2 X5 } { 0.2 Y5 } { 0.2 Z5 }; + +newfaces +(3, 1, 6); +(1, 4, 6); +(4, 5, 6); +(5, 3, 6); + +elements +(3, 1, 2, 6); +(1, 4, 2, 6); +(4, 5, 2, 6); +(5, 3, 2, 6); + + +orientations +(3, 1, 2, 5); +(5, 1, 2, 4); + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 1, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, 0, -1) { 1 X4 } { 1 Y4 } { 1 Z4 }; +(0.5, 0.4, -0.4) { 1 X5 } { 1 Y5 } { 1 Z5 }; +(0.55, 0.12, -0.12) { 0.4 X2, 0.3 X5 } { 0.3 Y5 } { 0.3 Z5 }; + +freeset +3 1 2 6; + +freeset +1 4 2 6; + +freeset +4 5 2 6; + +freeset +5 3 2 6; + +endrule + + + + + + + + + + + +rule "Tetrahedron 2 in 60 (12)" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 0.5 }; +(0.5, 1, 0) { 0.5 }; +(0.5, 0, -1) { 0.5 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2) del; + +newpoints +(0.5, 0.1, -0.1) + { 0.4 X1, 0.4 X2, 0.1 X3, 0.1 X4 } + { 0.4 Y1, 0.4 Y2, 0.1 Y3, 0.1 Y4 } + { 0.4 Z1, 0.4 Z2, 0.1 Z3, 0.1 Z4 }; + +newfaces +(5, 2, 3); +(5, 3, 1); +(5, 4, 2); +(5, 1, 4); + +elements +(1, 2, 3, 5); +(1, 2, 5, 4); + +freezone2 +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1.5 P5, -0.25 P1, -0.25 P2 }; + +freezonelimit +{ 1 P1 }; +{ 1 P2 }; +{ 1 P3 }; +{ 1 P4 }; +{ 1 P5 }; + +freeset +1 2 3 5; + +freeset +1 2 4 5; + +endrule + + + + +rule "Tetrahedron 120, but more than 180 (13)" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 1 }; +(0.5, 0.866, 0) { 1 }; +(0.5, -0.866, 0) { 1 }; + +mapfaces +(1, 2, 3) del; +(1, 4, 2); + +newpoints +(0.5, 0, -0.3) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; + +newfaces +(1, 5, 3); +(3, 5, 2); +(2, 5, 1); + +elements +(1, 2, 3, 5); + + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, -0.1, -0.4) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 }; + +endrule + + + + + +rule "Free Tetrahedron (14)" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 1.0 }; +(0.5, 0.866, 0) { 1.0 }; + +mapfaces +(1, 2, 3) del; + +newpoints +(0.5, 0.288, -0.2) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; + +newfaces +(4, 1, 2); +(4, 2, 3); +(4, 3, 1); + +elements +(1, 2, 3, 4); + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, 0.288, -0.25) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; + +endrule + + + +rule "Free Tetrahedron (15)" + +quality 100 + +mappoints +(0, 0, 0); +(1, 0, 0) { 1.0 }; +(0.5, 0.866, 0) { 1.0 }; + +mapfaces +(1, 2, 3) del; + +newpoints +(0.5, 0.288, -0.1) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; + +newfaces +(4, 1, 2); +(4, 2, 3); +(4, 3, 1); + +elements +(1, 2, 3, 4); + +freezone +(0, 0, 0); +(1, 0, 0) { 1 X2 } { } { }; +(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { }; +(0.5, 0.288, -0.15) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { }; + +endrule diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/triangle.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/triangle.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/triangle.rls 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/triangle.rls 1970-01-01 00:00:00.000000000 +0000 @@ -1,462 +0,0 @@ -rule "Free Triangle (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0) { 1.0, 0, 1.0 }; - -maplines -(1, 2) del; - -newpoints -(0.5, 0.866) { 0.5 X2 } { }; - -newlines -(1, 3); -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.7) { 0.5 X2 } { }; -(0.5, 1.5) { 0.5 X2 } { }; -(-0.5, 0.7) { 0.5 X2 } { }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.866) { 0.5 X2 } { }; -(0.5, 0.866) { 0.5 X2 } { }; -(0.5, 0.866) { 0.5 X2 } { }; - - -elements -(1, 2, 3); - -endrule - - -rule "Free Triangle (5)" - -quality 5 - -mappoints -(0, 0); -(1, 0) { 1.0, 0, 1.0 }; - -maplines -(1, 2) del; - -newpoints -(0.5, 0.5) { 0.5 X2 } { }; - -newlines -(1, 3); -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 0.7) { 1 X2 } { }; -(0, 0.7) { } { }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.5) { 0.5 X2 } { }; -(0.5, 0.5) { 0.5 X2 } { }; - - -elements -(1, 2, 3); - -endrule - - - - -rule "Free Triangle (10)" - -quality 10 - -mappoints -(0, 0); -(1, 0) { 1.0, 0, 1.0 }; - -maplines -(1, 2) del; - -newpoints -(0.5, 0.3) { 0.5 X2 } { }; - -newlines -(1, 3); -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 0.5) { 1 X2 } { }; -(0, 0.5) { } { }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.3) { 0.5 X2 } { }; -(0.5, 0.3) { 0.5 X2 } { }; - - -elements -(1, 2, 3); - -endrule - - - - -rule "Free Triangle (20)" - -quality 20 - -mappoints -(0, 0); -(1, 0) { 1.0, 0, 1.0 }; - -maplines -(1, 2) del; - -newpoints -(0.5, 0.1) { 0.5 X2 } { }; - -newlines -(1, 3); -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1, 0.2) { 1 X2 } { }; -(0, 0.2) { } { }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.1) { 0.5 X2 } { }; -(0.5, 0.1) { 0.5 X2 } { }; - - -elements -(1, 2, 3); - -endrule - - - - - - - - - -rule "Right 60 (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0) { 0.5, 0, 1.0 }; -(0.5, 0.866) { 0.6, 0, 0.8 }; - -maplines -(1, 2) del; -(2, 3) del; - -newpoints - -newlines -(1, 3); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; -(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; -(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 }; - -elements -(1, 2, 3); - -endrule - - - -rule "Left 60 (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(0.5, 0.866); - -maplines -(1, 2) del; -(3, 1) del; - -newpoints - -newlines -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.125, 0.6495) { 0.75 X2, 0.75 X3 } { 0.75 Y3 }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; - -elements -(1, 2, 3); - -endrule - - - - -rule "Right 120 (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(1.5, 0.866); - -maplines -(1, 2) del; -(2, 3) del; - -newpoints -(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 }; - -newlines -(1, 4); -(4, 3); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.866) { 1 X3 } { 1 Y3 }; -(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 }; -(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 }; -(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 }; - -elements -(1, 2, 4); -(2, 3, 4); - -endrule - - - - -rule "Left 120 (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(-0.5, 0.866); - -maplines -(1, 2) del; -(3, 1) del; - -newpoints -(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 }; - -newlines -(3, 4); -(4, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 }; -(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 }; -(0, 1.732) { 1 X2, 2 X3 } { 2 Y3 }; -(-0.5, 0.866) { 1 X3 } {1 Y3 }; - -elements -(1, 2, 4); -(1, 4, 3); - -endrule - - - - -rule "Left Right 120 (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(-0.5, 0.866); -(1.5, 0.866); - -maplines -(1, 2) del; -(3, 1) del; -(2, 4) del; - -newpoints -(0.5, 0.866) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; - -newlines -(3, 5); -(5, 4); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.5, 0.866) { 1 X4 } { 1 Y4 }; -(1, 1.299) { -0.5 X2, 0.375 X3, 1.125 X4 } { -0.5 Y2, 0.375 Y3, 1.125 Y4 }; -(0, 1.299) { 1.125 X3, 0.375 X4 } { 1.125 Y3, 0.375 Y4 }; -(-0.5, 0.866) { 1 X3 } { 1 Y3 }; - -elements -(1, 2, 5); -(3, 1, 5); -(2, 4, 5); - -endrule - - -rule "Fill Triangle" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(0.5, 0.866); - -maplines -(1, 2) del; -(2, 3) del; -(3, 1) del; - -newpoints - -newlines - -freearea -(0, 0); -(1, 0) { 1 X2 } { 1 Y2 }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; - -elements -(1, 2, 3); - -endrule - - - - -rule "Vis A Vis (1)" - -quality 1 - -mappoints -(0, 0); -(1, 0); -(0.5, 0.866); - -maplines -(1, 2) del; - -newpoints - -newlines -(1, 3); -(3, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { }; -(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; -(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 }; - -freearea2 -(0, 0); -(1, 0) { 1 X2 } { }; -(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 }; -(0.5, 0.866) { 1 X3 } { 1 Y3 }; -(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 }; - -elements -(1, 2, 3); - -endrule - - - - - - -rule "2 h Vis A Vis (1)" - -quality 3 - -mappoints -(0, 0); -(1, 0); -(1, 1.732); -(0, 1.732); - -maplines -(1, 2) del; -(3, 4) del; - -newpoints -(0.5, 0.866) { 0.25 X2, 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 }; - -newlines -(1, 5); -(5, 4); -(3, 5); -(5, 2); - -freearea -(0, 0); -(1, 0) { 1 X2 } { 1 Y2 }; -(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 }; -(1, 1.732) { 1 X3 } { 1 Y3 }; -(0, 1.732) { 1 X4 } { 1 Y4 }; -(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 }; - -elements -(1, 2, 5); -(3, 4, 5); - -endrule - - - - - diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/rules/triarules.rls ngsolve-6.2.2103/external_dependencies/netgen/rules/triarules.rls --- ngsolve-6.2.2102/external_dependencies/netgen/rules/triarules.rls 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/rules/triarules.rls 2021-06-04 23:36:22.000000000 +0000 @@ -0,0 +1,462 @@ +rule "Free Triangle (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0) { 1.0, 0, 1.0 }; + +maplines +(1, 2) del; + +newpoints +(0.5, 0.866) { 0.5 X2 } { }; + +newlines +(1, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.7) { 0.5 X2 } { }; +(0.5, 1.5) { 0.5 X2 } { }; +(-0.5, 0.7) { 0.5 X2 } { }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.866) { 0.5 X2 } { }; +(0.5, 0.866) { 0.5 X2 } { }; +(0.5, 0.866) { 0.5 X2 } { }; + + +elements +(1, 2, 3); + +endrule + + +rule "Free Triangle (5)" + +quality 5 + +mappoints +(0, 0); +(1, 0) { 1.0, 0, 1.0 }; + +maplines +(1, 2) del; + +newpoints +(0.5, 0.5) { 0.5 X2 } { }; + +newlines +(1, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.7) { 1 X2 } { }; +(0, 0.7) { } { }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.5) { 0.5 X2 } { }; +(0.5, 0.5) { 0.5 X2 } { }; + + +elements +(1, 2, 3); + +endrule + + + + +rule "Free Triangle (10)" + +quality 10 + +mappoints +(0, 0); +(1, 0) { 1.0, 0, 1.0 }; + +maplines +(1, 2) del; + +newpoints +(0.5, 0.3) { 0.5 X2 } { }; + +newlines +(1, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.5) { 1 X2 } { }; +(0, 0.5) { } { }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.3) { 0.5 X2 } { }; +(0.5, 0.3) { 0.5 X2 } { }; + + +elements +(1, 2, 3); + +endrule + + + + +rule "Free Triangle (20)" + +quality 20 + +mappoints +(0, 0); +(1, 0) { 1.0, 0, 1.0 }; + +maplines +(1, 2) del; + +newpoints +(0.5, 0.1) { 0.5 X2 } { }; + +newlines +(1, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1, 0.2) { 1 X2 } { }; +(0, 0.2) { } { }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.1) { 0.5 X2 } { }; +(0.5, 0.1) { 0.5 X2 } { }; + + +elements +(1, 2, 3); + +endrule + + + + + + + + + +rule "Right 60 (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0) { 0.5, 0, 1.0 }; +(0.5, 0.866) { 0.6, 0, 0.8 }; + +maplines +(1, 2) del; +(2, 3) del; + +newpoints + +newlines +(1, 3); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 }; + +elements +(1, 2, 3); + +endrule + + + +rule "Left 60 (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(0.5, 0.866); + +maplines +(1, 2) del; +(3, 1) del; + +newpoints + +newlines +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.125, 0.6495) { 0.75 X2, 0.75 X3 } { 0.75 Y3 }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; + +elements +(1, 2, 3); + +endrule + + + + +rule "Right 120 (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(1.5, 0.866); + +maplines +(1, 2) del; +(2, 3) del; + +newpoints +(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 }; + +newlines +(1, 4); +(4, 3); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.866) { 1 X3 } { 1 Y3 }; +(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 }; +(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 }; +(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 }; + +elements +(1, 2, 4); +(2, 3, 4); + +endrule + + + + +rule "Left 120 (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(-0.5, 0.866); + +maplines +(1, 2) del; +(3, 1) del; + +newpoints +(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 }; + +newlines +(3, 4); +(4, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 }; +(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 }; +(0, 1.732) { 1 X2, 2 X3 } { 2 Y3 }; +(-0.5, 0.866) { 1 X3 } {1 Y3 }; + +elements +(1, 2, 4); +(1, 4, 3); + +endrule + + + + +rule "Left Right 120 (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(-0.5, 0.866); +(1.5, 0.866); + +maplines +(1, 2) del; +(3, 1) del; +(2, 4) del; + +newpoints +(0.5, 0.866) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 }; + +newlines +(3, 5); +(5, 4); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.5, 0.866) { 1 X4 } { 1 Y4 }; +(1, 1.299) { -0.5 X2, 0.375 X3, 1.125 X4 } { -0.5 Y2, 0.375 Y3, 1.125 Y4 }; +(0, 1.299) { 1.125 X3, 0.375 X4 } { 1.125 Y3, 0.375 Y4 }; +(-0.5, 0.866) { 1 X3 } { 1 Y3 }; + +elements +(1, 2, 5); +(3, 1, 5); +(2, 4, 5); + +endrule + + +rule "Fill Triangle" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(0.5, 0.866); + +maplines +(1, 2) del; +(2, 3) del; +(3, 1) del; + +newpoints + +newlines + +freearea +(0, 0); +(1, 0) { 1 X2 } { 1 Y2 }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; + +elements +(1, 2, 3); + +endrule + + + + +rule "Vis A Vis (1)" + +quality 1 + +mappoints +(0, 0); +(1, 0); +(0.5, 0.866); + +maplines +(1, 2) del; + +newpoints + +newlines +(1, 3); +(3, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { }; +(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 }; + +freearea2 +(0, 0); +(1, 0) { 1 X2 } { }; +(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 }; +(0.5, 0.866) { 1 X3 } { 1 Y3 }; +(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 }; + +elements +(1, 2, 3); + +endrule + + + + + + +rule "2 h Vis A Vis (1)" + +quality 3 + +mappoints +(0, 0); +(1, 0); +(1, 1.732); +(0, 1.732); + +maplines +(1, 2) del; +(3, 4) del; + +newpoints +(0.5, 0.866) { 0.25 X2, 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 }; + +newlines +(1, 5); +(5, 4); +(3, 5); +(5, 2); + +freearea +(0, 0); +(1, 0) { 1 X2 } { 1 Y2 }; +(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 }; +(1, 1.732) { 1 X3 } { 1 Y3 }; +(0, 1.732) { 1 X4 } { 1 Y4 }; +(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 }; + +elements +(1, 2, 5); +(3, 4, 5); + +endrule + + + + + diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/tests/pytest/results.json ngsolve-6.2.2103/external_dependencies/netgen/tests/pytest/results.json --- ngsolve-6.2.2102/external_dependencies/netgen/tests/pytest/results.json 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/tests/pytest/results.json 2021-06-04 23:36:22.000000000 +0000 @@ -2,18 +2,18 @@ "boundarycondition.geo": [ { "angles_tet": [ - 27.914, - 137.69 + 27.291, + 136.38 ], "angles_trig": [ - 29.255, - 99.865 + 23.577, + 123.09 ], "ne1d": 74, - "ne2d": 54, - "ne3d": 46, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 6, 15, 3, 7, 5, 0, 0, 0]", - "total_badness": 70.019644222 + "ne2d": 52, + "ne3d": 48, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 7, 7, 16, 3, 6, 1, 1, 0, 1]", + "total_badness": 74.651719788 }, { "angles_tet": [ @@ -47,80 +47,80 @@ }, { "angles_tet": [ - 27.914, - 137.69 + 27.292, + 136.38 ], "angles_trig": [ - 29.255, - 99.865 + 23.578, + 123.09 ], "ne1d": 74, - "ne2d": 54, - "ne3d": 46, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 6, 15, 3, 7, 5, 0, 0, 0]", - "total_badness": 70.019644216 + "ne2d": 52, + "ne3d": 48, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 7, 7, 16, 3, 6, 1, 1, 0, 1]", + "total_badness": 74.651710944 }, { "angles_tet": [ - 22.611, - 132.85 + 28.952, + 132.08 ], "angles_trig": [ - 23.939, - 104.77 + 23.632, + 109.31 ], "ne1d": 118, - "ne2d": 140, - "ne3d": 165, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 9, 13, 23, 20, 31, 25, 21, 14, 6, 1]", - "total_badness": 233.73328915 + "ne2d": 124, + "ne3d": 136, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 18, 14, 20, 33, 17, 10, 10, 9, 0]", + "total_badness": 193.08725988 }, { "angles_tet": [ - 25.801, - 134.97 + 24.309, + 138.49 ], "angles_trig": [ 24.858, - 111.88 + 104.73 ], "ne1d": 181, - "ne2d": 325, - "ne3d": 520, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 14, 39, 52, 64, 79, 98, 93, 57, 15]", - "total_badness": 673.37179433 + "ne2d": 313, + "ne3d": 506, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 13, 25, 47, 64, 85, 94, 100, 51, 17]", + "total_badness": 650.35553279 } ], "boxcyl.geo": [ { "angles_tet": [ - 22.391, - 135.51 + 21.801, + 141.86 ], "angles_trig": [ - 22.547, + 22.551, 121.98 ], "ne1d": 190, - "ne2d": 468, - "ne3d": 845, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 29, 90, 89, 74, 95, 96, 93, 98, 99, 60, 21]", - "total_badness": 1218.9142866 + "ne2d": 466, + "ne3d": 853, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 2, 29, 91, 82, 81, 79, 105, 104, 102, 104, 55, 18]", + "total_badness": 1230.3136604 }, { "angles_tet": [ - 14.829, - 146.41 + 11.507, + 151.32 ], "angles_trig": [ 16.491, 127.01 ], "ne1d": 94, - "ne2d": 114, - "ne3d": 122, - "quality_histogram": "[0, 0, 0, 0, 1, 2, 4, 9, 19, 14, 12, 10, 10, 7, 11, 4, 2, 14, 3, 0]", - "total_badness": 231.46662286 + "ne2d": 112, + "ne3d": 117, + "quality_histogram": "[0, 0, 0, 0, 1, 2, 4, 4, 15, 17, 12, 12, 7, 7, 9, 7, 4, 14, 2, 0]", + "total_badness": 215.67528767 }, { "angles_tet": [ @@ -139,140 +139,140 @@ }, { "angles_tet": [ - 22.392, - 135.93 + 21.799, + 141.86 ], "angles_trig": [ - 22.547, + 22.551, 121.98 ], "ne1d": 190, - "ne2d": 468, - "ne3d": 838, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 30, 88, 87, 63, 105, 87, 95, 98, 101, 59, 24]", - "total_badness": 1206.145501 + "ne2d": 466, + "ne3d": 853, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 2, 29, 90, 82, 83, 76, 104, 104, 101, 106, 59, 16]", + "total_badness": 1228.8621753 }, { "angles_tet": [ - 26.449, - 140.15 + 23.059, + 142.42 ], "angles_trig": [ - 24.477, - 114.57 + 24.422, + 114.76 ], "ne1d": 284, - "ne2d": 938, - "ne3d": 3808, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 12, 47, 117, 277, 497, 641, 782, 746, 506, 177]", - "total_badness": 4753.2608558 + "ne2d": 932, + "ne3d": 3796, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 25, 57, 141, 242, 514, 663, 741, 700, 533, 173]", + "total_badness": 4762.1753552 }, { "angles_tet": [ - 28.839, + 28.81, 136.82 ], "angles_trig": [ 24.852, - 123.06 + 115.45 ], "ne1d": 456, "ne2d": 2496, - "ne3d": 18745, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 27, 92, 267, 746, 1634, 2890, 4017, 4509, 3387, 1173]", - "total_badness": 22615.490176 + "ne3d": 18764, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 22, 93, 266, 749, 1636, 2864, 4077, 4527, 3369, 1158]", + "total_badness": 22641.283691 } ], "circle_on_cube.geo": [ { "angles_tet": [ - 21.273, - 137.67 + 19.96, + 140.64 ], "angles_trig": [ - 24.517, - 113.53 + 24.944, + 113.33 ], "ne1d": 94, - "ne2d": 170, - "ne3d": 631, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 12, 30, 55, 76, 104, 120, 97, 70, 49, 10]", - "total_badness": 851.6214528 + "ne2d": 166, + "ne3d": 612, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 1, 6, 14, 21, 40, 63, 91, 107, 124, 82, 47, 15]", + "total_badness": 811.78938044 }, { "angles_tet": [ - 17.203, - 146.18 + 18.23, + 141.37 ], "angles_trig": [ - 16.937, - 127.21 + 19.788, + 128.96 ], "ne1d": 40, - "ne2d": 38, - "ne3d": 46, - "quality_histogram": "[0, 0, 0, 0, 0, 2, 2, 4, 8, 8, 6, 7, 5, 1, 2, 1, 0, 0, 0, 0]", - "total_badness": 97.323158326 + "ne2d": 34, + "ne3d": 48, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 2, 7, 7, 7, 10, 5, 3, 2, 2, 1, 1, 0, 0]", + "total_badness": 90.934962923 }, { "angles_tet": [ - 26.568, - 131.32 + 24.365, + 137.33 ], "angles_trig": [ - 23.604, - 115.75 + 26.464, + 113.36 ], "ne1d": 62, - "ne2d": 96, - "ne3d": 196, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 13, 31, 32, 43, 33, 18, 6, 9, 0]", - "total_badness": 281.47956507 + "ne2d": 92, + "ne3d": 183, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 7, 16, 29, 27, 31, 21, 19, 21, 10, 0]", + "total_badness": 259.3323397 }, { "angles_tet": [ - 27.256, - 136.88 + 20.414, + 140.15 ], "angles_trig": [ - 25.056, - 112.86 + 24.831, + 113.52 ], "ne1d": 94, - "ne2d": 170, - "ne3d": 617, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 8, 24, 45, 83, 93, 110, 109, 75, 54, 12]", - "total_badness": 818.76482812 + "ne2d": 166, + "ne3d": 612, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 1, 5, 13, 24, 41, 62, 90, 109, 116, 83, 51, 16]", + "total_badness": 810.99503348 }, { "angles_tet": [ - 28.642, - 131.64 + 18.834, + 142.08 ], "angles_trig": [ - 27.582, - 112.81 + 25.801, + 111.08 ], "ne1d": 138, - "ne2d": 384, - "ne3d": 1988, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 11, 49, 142, 225, 336, 439, 417, 280, 85]", - "total_badness": 2458.7297408 + "ne2d": 380, + "ne3d": 2041, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 10, 25, 60, 140, 228, 332, 469, 418, 279, 78]", + "total_badness": 2539.1609328 }, { "angles_tet": [ - 26.261, - 136.67 + 25.405, + 141.15 ], "angles_trig": [ - 24.333, - 115.58 + 27.134, + 116.9 ], "ne1d": 224, - "ne2d": 944, - "ne3d": 11884, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 15, 67, 187, 504, 1104, 1766, 2553, 2772, 2223, 688]", - "total_badness": 14368.116024 + "ne2d": 932, + "ne3d": 11771, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 13, 60, 170, 453, 1079, 1794, 2397, 2758, 2350, 696]", + "total_badness": 14181.937809 } ], "cone.geo": [ @@ -308,18 +308,18 @@ }, { "angles_tet": [ - 5.6575, - 169.44 + 3.8299, + 169.8 ], "angles_trig": [ - 7.092, - 155.41 + 7.7658, + 155.67 ], "ne1d": 48, - "ne2d": 428, - "ne3d": 763, - "quality_histogram": "[0, 1, 12, 30, 35, 44, 39, 49, 82, 100, 68, 81, 55, 44, 49, 23, 22, 19, 8, 2]", - "total_badness": 1832.2349397 + "ne2d": 424, + "ne3d": 783, + "quality_histogram": "[0, 3, 5, 27, 40, 43, 49, 44, 84, 74, 78, 84, 60, 52, 48, 24, 32, 19, 15, 2]", + "total_badness": 1824.4335331 }, { "angles_tet": [ @@ -445,50 +445,50 @@ }, { "angles_tet": [ - 21.865, - 136.72 + 20.477, + 142.85 ], "angles_trig": [ - 22.37, - 121.17 + 22.403, + 121.04 ], "ne1d": 72, - "ne2d": 116, - "ne3d": 169, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 4, 8, 13, 12, 20, 28, 33, 27, 11, 6]", - "total_badness": 228.41837612 + "ne2d": 106, + "ne3d": 158, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 4, 3, 4, 16, 22, 32, 25, 26, 14, 8]", + "total_badness": 207.4915712 } ], "cubeandring.geo": [ { "angles_tet": [ - 5.2065, - 170.27 + 5.3682, + 165.74 ], "angles_trig": [ - 10.96, - 154.62 + 11.3, + 154.12 ], "ne1d": 262, - "ne2d": 726, - "ne3d": 2167, - "quality_histogram": "[0, 4, 17, 35, 75, 117, 114, 112, 77, 51, 58, 86, 115, 177, 248, 293, 239, 204, 118, 27]", - "total_badness": 4176.9284057 + "ne2d": 702, + "ne3d": 2099, + "quality_histogram": "[0, 0, 12, 32, 71, 94, 120, 96, 80, 58, 45, 67, 130, 209, 229, 261, 252, 190, 121, 32]", + "total_badness": 3918.4348785 }, { "angles_tet": [ - 16.741, - 140.94 + 29.146, + 134.34 ], "angles_trig": [ - 19.264, - 120.29 + 25.65, + 116.54 ], "ne1d": 134, - "ne2d": 164, - "ne3d": 252, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 4, 2, 3, 11, 30, 31, 34, 40, 38, 33, 17, 7, 1]", - "total_badness": 369.95189237 + "ne2d": 160, + "ne3d": 245, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 25, 37, 40, 42, 43, 30, 15, 3, 2]", + "total_badness": 349.09002466 }, { "angles_tet": [ @@ -500,55 +500,55 @@ 131.52 ], "ne1d": 190, - "ne2d": 300, - "ne3d": 632, - "quality_histogram": "[0, 0, 0, 0, 2, 0, 0, 4, 8, 26, 45, 62, 80, 96, 90, 84, 65, 46, 22, 2]", - "total_badness": 947.91494351 + "ne2d": 282, + "ne3d": 589, + "quality_histogram": "[0, 0, 0, 0, 2, 0, 0, 5, 2, 13, 40, 46, 62, 105, 90, 94, 60, 46, 20, 4]", + "total_badness": 862.89134979 }, { "angles_tet": [ - 5.9887, - 161.33 + 7.6936, + 166.0 ], "angles_trig": [ - 13.133, - 150.46 + 12.773, + 154.12 ], "ne1d": 262, - "ne2d": 726, - "ne3d": 2060, - "quality_histogram": "[0, 2, 5, 15, 46, 103, 106, 104, 71, 36, 48, 67, 99, 165, 253, 287, 287, 195, 136, 35]", - "total_badness": 3642.1604728 + "ne2d": 702, + "ne3d": 2003, + "quality_histogram": "[0, 0, 2, 10, 38, 80, 114, 93, 69, 29, 54, 52, 121, 183, 222, 268, 284, 211, 139, 34]", + "total_badness": 3430.228346 }, { "angles_tet": [ - 24.1, - 141.88 + 21.834, + 143.22 ], "angles_trig": [ - 23.859, - 119.8 + 23.385, + 115.43 ], "ne1d": 378, - "ne2d": 1412, - "ne3d": 7670, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 7, 36, 112, 284, 477, 845, 1308, 1555, 1517, 1168, 359]", - "total_badness": 9545.7933664 + "ne2d": 1400, + "ne3d": 7678, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 11, 30, 118, 264, 475, 859, 1311, 1567, 1623, 1081, 337]", + "total_badness": 9555.5911544 }, { "angles_tet": [ - 24.428, - 143.27 + 19.725, + 150.28 ], "angles_trig": [ - 24.968, - 121.61 + 22.53, + 115.61 ], "ne1d": 624, - "ne2d": 3944, - "ne3d": 38337, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 5, 12, 70, 233, 701, 1858, 3746, 6011, 8031, 8828, 6611, 2231]", - "total_badness": 46629.830149 + "ne2d": 3922, + "ne3d": 37844, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 0, 2, 13, 73, 237, 689, 1700, 3616, 5845, 8140, 8772, 6595, 2161]", + "total_badness": 45961.097134 } ], "cubeandspheres.geo": [ @@ -573,14 +573,14 @@ 137.5 ], "angles_trig": [ - 28.935, - 109.27 + 30.884, + 106.1 ], "ne1d": 144, - "ne2d": 150, - "ne3d": 100, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, 10, 16, 18, 15, 17, 6, 5, 4, 0]", - "total_badness": 146.6468601 + "ne2d": 140, + "ne3d": 86, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, 5, 23, 16, 12, 16, 1, 3, 1, 0]", + "total_badness": 129.5899229 }, { "angles_tet": [ @@ -588,14 +588,14 @@ 137.32 ], "angles_trig": [ - 29.702, - 106.44 + 30.054, + 105.76 ], "ne1d": 144, - "ne2d": 148, - "ne3d": 98, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 6, 6, 19, 21, 12, 18, 5, 4, 4, 0]", - "total_badness": 145.14580879 + "ne2d": 142, + "ne3d": 89, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 6, 4, 23, 19, 9, 18, 3, 2, 2, 0]", + "total_badness": 134.24463081 }, { "angles_tet": [ @@ -614,217 +614,217 @@ }, { "angles_tet": [ - 17.481, - 142.47 + 19.282, + 139.8 ], "angles_trig": [ - 23.755, - 116.95 + 23.342, + 126.8 ], "ne1d": 264, - "ne2d": 390, - "ne3d": 369, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 4, 5, 19, 26, 42, 46, 49, 41, 53, 45, 27, 10, 2]", - "total_badness": 554.2809713 + "ne2d": 368, + "ne3d": 335, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 1, 1, 18, 20, 42, 50, 47, 34, 43, 43, 18, 15, 2]", + "total_badness": 499.78585873 }, { "angles_tet": [ - 13.221, - 154.37 + 10.474, + 157.47 ], "angles_trig": [ 19.317, 128.1 ], "ne1d": 428, - "ne2d": 926, - "ne3d": 1086, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 3, 22, 44, 37, 108, 133, 101, 117, 167, 161, 67, 71, 33, 21]", - "total_badness": 1684.0903817 + "ne2d": 920, + "ne3d": 1072, + "quality_histogram": "[0, 0, 0, 0, 1, 1, 2, 22, 45, 28, 112, 122, 103, 115, 177, 153, 68, 71, 33, 19]", + "total_badness": 1661.9258066 } ], "cubemcyl.geo": [ { "angles_tet": [ - 19.095, - 148.41 + 17.446, + 151.7 ], "angles_trig": [ - 19.819, - 130.08 + 19.856, + 129.2 ], "ne1d": 142, - "ne2d": 2488, - "ne3d": 20377, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 3, 13, 54, 165, 390, 900, 1554, 2429, 3089, 3513, 3446, 2730, 1633, 458]", - "total_badness": 27224.35447 + "ne2d": 2480, + "ne3d": 20397, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 5, 15, 56, 162, 388, 873, 1515, 2416, 3102, 3532, 3509, 2655, 1704, 465]", + "total_badness": 27221.131002 }, { "angles_tet": [ - 19.437, - 141.17 + 20.409, + 143.04 ], "angles_trig": [ - 17.771, - 130.84 + 17.822, + 126.28 ], "ne1d": 64, - "ne2d": 642, - "ne3d": 3305, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 11, 21, 62, 135, 236, 368, 452, 577, 512, 439, 311, 151, 29]", - "total_badness": 4674.6678046 + "ne2d": 626, + "ne3d": 3285, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 11, 13, 29, 65, 108, 230, 334, 508, 490, 550, 424, 337, 153, 32]", + "total_badness": 4649.9190359 }, { "angles_tet": [ - 20.675, - 143.54 + 20.792, + 142.3 ], "angles_trig": [ - 14.769, - 129.61 + 16.821, + 121.95 ], "ne1d": 102, - "ne2d": 1402, - "ne3d": 8209, - "quality_histogram": "[0, 0, 0, 0, 0, 2, 4, 4, 26, 56, 216, 420, 704, 1026, 1323, 1412, 1302, 954, 587, 173]", - "total_badness": 11118.365255 + "ne2d": 1396, + "ne3d": 8170, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 2, 16, 62, 196, 410, 708, 1083, 1337, 1335, 1256, 994, 584, 186]", + "total_badness": 11044.804929 }, { "angles_tet": [ - 21.997, - 146.77 + 20.02, + 144.25 ], "angles_trig": [ - 23.524, - 123.14 + 21.547, + 129.2 ], "ne1d": 142, - "ne2d": 2488, - "ne3d": 19366, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 7, 43, 115, 406, 1004, 1806, 2745, 3564, 3751, 3220, 2125, 577]", - "total_badness": 24813.005671 + "ne2d": 2480, + "ne3d": 19278, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 2, 8, 31, 123, 394, 900, 1837, 2690, 3501, 3809, 3243, 2102, 638]", + "total_badness": 24636.746715 }, { "angles_tet": [ - 22.179, - 143.28 + 20.38, + 143.54 ], "angles_trig": [ - 22.998, - 122.28 + 22.192, + 122.97 ], "ne1d": 210, - "ne2d": 5508, - "ne3d": 89117, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 7, 64, 213, 756, 2149, 5056, 9540, 14533, 18572, 19573, 14246, 4408]", - "total_badness": 109473.41917 + "ne2d": 5500, + "ne3d": 89273, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 9, 57, 256, 780, 2195, 5118, 9739, 14853, 18700, 19471, 13926, 4168]", + "total_badness": 109900.35464 }, { "angles_tet": [ - 22.072, - 141.68 + 22.631, + 143.92 ], "angles_trig": [ - 23.818, - 123.89 + 23.11, + 126.59 ], "ne1d": 362, - "ne2d": 15122, - "ne3d": 525200, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 6, 82, 526, 2296, 7742, 21372, 47326, 79983, 111877, 125226, 97896, 30868]", - "total_badness": 633738.01761 + "ne2d": 15110, + "ne3d": 520222, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 7, 95, 553, 2159, 7249, 20810, 46662, 79858, 109825, 124263, 97909, 30832]", + "total_badness": 627268.3468 } ], "cubemsphere.geo": [ { "angles_tet": [ - 18.937, - 145.89 + 19.119, + 146.55 ], "angles_trig": [ - 21.407, - 128.79 + 19.026, + 125.8 ], "ne1d": 90, - "ne2d": 702, - "ne3d": 4814, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 4, 10, 55, 89, 206, 386, 582, 723, 808, 801, 647, 392, 111]", - "total_badness": 6443.9958085 + "ne2d": 698, + "ne3d": 4776, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 4, 16, 51, 98, 209, 398, 528, 705, 811, 784, 640, 411, 120]", + "total_badness": 6388.8286556 }, { "angles_tet": [ - 17.436, - 150.08 + 17.007, + 143.72 ], "angles_trig": [ - 14.077, - 130.7 + 14.293, + 127.98 ], "ne1d": 44, - "ne2d": 274, - "ne3d": 769, - "quality_histogram": "[0, 0, 0, 0, 1, 3, 9, 15, 28, 41, 69, 78, 114, 88, 96, 95, 62, 35, 31, 4]", - "total_badness": 1221.5992458 + "ne2d": 246, + "ne3d": 735, + "quality_histogram": "[0, 0, 0, 0, 1, 1, 4, 17, 19, 42, 61, 80, 110, 117, 102, 73, 58, 27, 15, 8]", + "total_badness": 1161.4977052 }, { "angles_tet": [ - 20.966, - 149.27 + 20.529, + 148.73 ], "angles_trig": [ - 22.441, - 124.17 + 20.178, + 127.02 ], "ne1d": 68, - "ne2d": 402, - "ne3d": 1570, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 2, 10, 25, 53, 109, 194, 185, 264, 251, 214, 153, 94, 16]", - "total_badness": 2195.1465077 + "ne2d": 396, + "ne3d": 1561, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 4, 14, 18, 57, 119, 168, 225, 245, 243, 239, 150, 65, 14]", + "total_badness": 2194.1567943 }, { "angles_tet": [ - 22.975, - 142.5 + 21.744, + 144.7 ], "angles_trig": [ - 21.962, - 120.34 + 23.409, + 120.39 ], "ne1d": 90, - "ne2d": 702, - "ne3d": 4601, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 21, 45, 92, 246, 466, 682, 801, 899, 738, 477, 130]", - "total_badness": 5937.2722105 + "ne2d": 698, + "ne3d": 4573, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 5, 11, 38, 124, 244, 437, 627, 796, 871, 807, 498, 114]", + "total_badness": 5883.7028961 }, { "angles_tet": [ - 25.354, - 139.69 + 22.863, + 138.41 ], "angles_trig": [ - 24.508, - 122.25 + 23.26, + 121.85 ], "ne1d": 146, - "ne2d": 1492, - "ne3d": 17953, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 15, 49, 186, 416, 1010, 1922, 3086, 3851, 3738, 2822, 857]", - "total_badness": 22102.299848 + "ne2d": 1482, + "ne3d": 17978, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 45, 148, 430, 972, 1910, 3013, 3819, 4010, 2787, 839]", + "total_badness": 22078.910603 }, { "angles_tet": [ - 23.515, - 140.76 + 24.702, + 143.19 ], "angles_trig": [ - 24.908, - 125.3 + 25.471, + 126.09 ], "ne1d": 248, - "ne2d": 4354, - "ne3d": 113864, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 21, 137, 566, 1806, 4993, 10776, 18228, 24232, 26678, 20186, 6238]", - "total_badness": 138017.18455 + "ne2d": 4340, + "ne3d": 112801, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 21, 120, 474, 1663, 4885, 10633, 17731, 23919, 26274, 20590, 6489]", + "total_badness": 136439.77655 } ], "cylinder.geo": [ @@ -937,18 +937,18 @@ }, { "angles_tet": [ - 10.144, - 167.27 + 12.765, + 164.21 ], "angles_trig": [ - 13.416, - 150.52 + 14.86, + 145.49 ], "ne1d": 48, - "ne2d": 142, - "ne3d": 150, - "quality_histogram": "[0, 0, 0, 5, 27, 32, 16, 4, 0, 2, 1, 1, 4, 5, 3, 17, 16, 7, 10, 0]", - "total_badness": 409.78409193 + "ne2d": 130, + "ne3d": 142, + "quality_histogram": "[0, 0, 0, 5, 9, 38, 20, 6, 0, 0, 2, 3, 0, 10, 7, 20, 17, 3, 2, 0]", + "total_badness": 370.48768997 }, { "angles_tet": [ @@ -1014,18 +1014,18 @@ }, { "angles_tet": [ - 5.6074, - 169.95 + 5.7901, + 170.17 ], "angles_trig": [ - 7.5945, - 159.99 + 7.4711, + 159.43 ], "ne1d": 0, - "ne2d": 192, - "ne3d": 748, - "quality_histogram": "[0, 0, 30, 62, 87, 77, 80, 61, 72, 38, 54, 43, 34, 27, 27, 20, 18, 10, 7, 1]", - "total_badness": 2287.1659209 + "ne2d": 190, + "ne3d": 815, + "quality_histogram": "[0, 3, 30, 74, 82, 71, 72, 78, 57, 63, 56, 51, 46, 42, 25, 26, 18, 12, 6, 3]", + "total_badness": 2455.5742667 }, { "angles_tet": [ @@ -1059,18 +1059,18 @@ }, { "angles_tet": [ - 19.838, - 144.66 + 25.826, + 139.09 ], "angles_trig": [ - 24.559, - 116.15 + 25.414, + 117.11 ], "ne1d": 0, - "ne2d": 1618, - "ne3d": 5582, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 1, 1, 18, 48, 133, 269, 450, 670, 884, 1028, 1098, 753, 228]", - "total_badness": 7078.3419995 + "ne2d": 1616, + "ne3d": 5547, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 53, 131, 290, 453, 688, 906, 1032, 1025, 755, 204]", + "total_badness": 7050.1376548 }, { "angles_tet": [ @@ -1091,18 +1091,18 @@ "ellipticcone.geo": [ { "angles_tet": [ - 17.699, - 148.03 + 18.792, + 149.93 ], "angles_trig": [ - 23.943, - 122.76 + 23.417, + 122.63 ], "ne1d": 174, - "ne2d": 1562, - "ne3d": 5212, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 1, 8, 32, 89, 187, 328, 534, 719, 937, 969, 775, 458, 174]", - "total_badness": 6834.3167615 + "ne2d": 1538, + "ne3d": 5190, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 2, 13, 25, 93, 201, 315, 524, 751, 949, 929, 755, 462, 170]", + "total_badness": 6819.6745001 }, { "angles_tet": [ @@ -1121,80 +1121,80 @@ }, { "angles_tet": [ - 16.597, + 16.709, 149.96 ], "angles_trig": [ - 18.553, + 18.695, 135.0 ], "ne1d": 130, - "ne2d": 864, - "ne3d": 1652, - "quality_histogram": "[0, 0, 0, 0, 0, 2, 12, 28, 40, 57, 56, 113, 146, 183, 206, 245, 268, 166, 103, 27]", - "total_badness": 2393.1339621 + "ne2d": 860, + "ne3d": 1672, + "quality_histogram": "[0, 0, 0, 0, 1, 1, 10, 25, 48, 50, 77, 113, 148, 176, 215, 240, 232, 187, 125, 24]", + "total_badness": 2423.5331187 }, { "angles_tet": [ - 21.766, - 144.03 + 23.81, + 139.91 ], "angles_trig": [ - 25.696, - 119.99 + 26.156, + 122.63 ], "ne1d": 174, - "ne2d": 1562, - "ne3d": 5072, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 11, 54, 93, 228, 440, 641, 935, 1026, 892, 544, 204]", - "total_badness": 6463.5570559 + "ne2d": 1538, + "ne3d": 5006, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 40, 107, 214, 415, 674, 949, 1001, 869, 530, 199]", + "total_badness": 6372.9824232 }, { "angles_tet": [ - 20.935, - 144.66 + 22.554, + 144.63 ], "angles_trig": [ - 18.719, - 132.57 + 22.397, + 124.81 ], "ne1d": 258, - "ne2d": 3468, - "ne3d": 13471, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 8, 18, 67, 132, 305, 570, 999, 1594, 2335, 2604, 2480, 1787, 572]", - "total_badness": 17093.610502 + "ne2d": 3410, + "ne3d": 13272, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 12, 55, 120, 254, 518, 968, 1620, 2296, 2667, 2472, 1724, 566]", + "total_badness": 16769.34242 }, { "angles_tet": [ - 19.932, - 144.83 + 20.995, + 145.62 ], "angles_trig": [ - 21.622, + 24.496, 126.14 ], "ne1d": 432, - "ne2d": 9544, - "ne3d": 69846, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 7, 30, 71, 221, 652, 1560, 3667, 7028, 11234, 14630, 15524, 11810, 3411]", - "total_badness": 85625.275421 + "ne2d": 9416, + "ne3d": 69489, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 6, 15, 61, 185, 564, 1558, 3457, 7080, 11088, 14508, 15416, 11903, 3647]", + "total_badness": 84992.684091 } ], "ellipticcyl.geo": [ { "angles_tet": [ - 16.526, - 149.46 + 18.27, + 146.04 ], "angles_trig": [ - 21.243, - 122.35 + 21.368, + 124.04 ], "ne1d": 156, - "ne2d": 996, - "ne3d": 2250, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 3, 10, 54, 75, 108, 223, 245, 334, 397, 328, 264, 157, 51]", - "total_badness": 3092.4590274 + "ne2d": 988, + "ne3d": 2245, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 7, 14, 43, 75, 120, 183, 280, 343, 372, 323, 268, 180, 37]", + "total_badness": 3082.4279481 }, { "angles_tet": [ @@ -1228,48 +1228,125 @@ }, { "angles_tet": [ - 18.67, - 144.62 + 20.945, + 138.99 ], "angles_trig": [ - 23.115, - 121.16 + 22.422, + 121.69 ], "ne1d": 156, - "ne2d": 996, - "ne3d": 2228, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 2, 7, 26, 55, 99, 185, 230, 332, 401, 349, 286, 208, 48]", - "total_badness": 2986.6628685 + "ne2d": 988, + "ne3d": 2191, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 9, 25, 53, 97, 140, 243, 333, 354, 377, 308, 188, 61]", + "total_badness": 2925.6156836 }, { "angles_tet": [ - 24.468, - 138.03 + 25.967, + 140.07 ], "angles_trig": [ - 25.275, - 115.12 + 24.34, + 120.72 ], "ne1d": 232, - "ne2d": 2212, - "ne3d": 8292, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 15, 37, 90, 258, 586, 955, 1411, 1668, 1703, 1209, 359]", - "total_badness": 10319.810588 + "ne2d": 2192, + "ne3d": 8183, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 38, 98, 254, 525, 969, 1398, 1694, 1665, 1180, 351]", + "total_badness": 10178.24296 }, { "angles_tet": [ - 21.266, - 143.66 + 22.977, + 141.29 ], "angles_trig": [ - 23.958, - 119.8 + 27.075, + 122.59 ], "ne1d": 388, - "ne2d": 6142, - "ne3d": 54704, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 66, 248, 717, 2138, 4854, 8219, 11632, 13173, 10210, 3428]", - "total_badness": 65897.969985 + "ne2d": 6074, + "ne3d": 55148, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 75, 229, 780, 2108, 4933, 8391, 11779, 13136, 10280, 3420]", + "total_badness": 66472.771501 + } + ], + "extrusion.geo": [ + { + "angles_tet": [ + 6.6841, + 171.53 + ], + "angles_trig": [ + 11.293, + 152.07 + ], + "ne1d": 172, + "ne2d": 286, + "ne3d": 241, + "quality_histogram": "[0, 0, 7, 56, 39, 22, 0, 0, 0, 0, 2, 0, 5, 18, 18, 29, 21, 10, 9, 5]", + "total_badness": 775.80779693 + }, + { + "angles_tet": [ + 16.097, + 160.17 + ], + "angles_trig": [ + 15.327, + 149.09 + ], + "ne1d": 104, + "ne2d": 152, + "ne3d": 124, + "quality_histogram": "[0, 0, 0, 0, 10, 19, 39, 26, 9, 3, 1, 1, 5, 1, 3, 2, 3, 2, 0, 0]", + "total_badness": 353.53219387 + }, + { + "angles_tet": [ + 11.341, + 166.54 + ], + "angles_trig": [ + 14.821, + 145.63 + ], + "ne1d": 134, + "ne2d": 192, + "ne3d": 163, + "quality_histogram": "[0, 0, 0, 1, 3, 23, 36, 13, 5, 21, 11, 9, 10, 11, 7, 3, 5, 3, 1, 1]", + "total_badness": 396.98127414 + }, + { + "angles_tet": [ + 6.6841, + 171.53 + ], + "angles_trig": [ + 11.293, + 152.07 + ], + "ne1d": 172, + "ne2d": 286, + "ne3d": 241, + "quality_histogram": "[0, 0, 7, 56, 39, 22, 0, 0, 0, 0, 2, 0, 5, 18, 18, 29, 21, 10, 9, 5]", + "total_badness": 775.80779693 + }, + { + "angles_tet": [ + 19.623, + 139.4 + ], + "angles_trig": [ + 18.715, + 118.98 + ], + "ne1d": 276, + "ne2d": 564, + "ne3d": 639, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 2, 13, 34, 37, 63, 58, 80, 75, 72, 64, 74, 46, 14, 7]", + "total_badness": 1004.3868118 } ], "fichera.geo": [ @@ -1335,50 +1412,50 @@ }, { "angles_tet": [ - 25.061, - 136.16 + 29.869, + 133.14 ], "angles_trig": [ 29.251, - 110.29 + 107.49 ], "ne1d": 96, - "ne2d": 120, - "ne3d": 205, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 4, 13, 17, 26, 36, 40, 31, 22, 10]", - "total_badness": 264.77766512 + "ne2d": 110, + "ne3d": 178, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 15, 16, 31, 30, 36, 28, 12, 7]", + "total_badness": 231.15151713 }, { "angles_tet": [ - 26.621, - 137.76 + 23.0, + 138.2 ], "angles_trig": [ - 22.737, - 128.54 + 23.639, + 116.88 ], "ne1d": 144, - "ne2d": 274, - "ne3d": 489, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 20, 29, 59, 75, 95, 77, 74, 43, 13]", - "total_badness": 639.78974791 + "ne2d": 268, + "ne3d": 497, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 14, 29, 49, 74, 106, 91, 75, 43, 13]", + "total_badness": 643.8604751 } ], "frame.step": [ { "angles_tet": [ - 2.9158, + 2.8491, 171.1 ], "angles_trig": [ - 2.6092, - 172.05 + 3.7733, + 169.05 ], "ne1d": 10108, - "ne2d": 30160, - "ne3d": 152932, - "quality_histogram": "[0, 3, 1, 3, 6, 20, 60, 151, 543, 1312, 2940, 5874, 10445, 16338, 21809, 26075, 26405, 22854, 14351, 3742]", - "total_badness": 202658.67088 + "ne2d": 29958, + "ne3d": 152591, + "quality_histogram": "[0, 3, 1, 3, 8, 19, 67, 166, 526, 1268, 2848, 5750, 10287, 16353, 21624, 25759, 26679, 22815, 14557, 3858]", + "total_badness": 201926.65352 }, { "angles_tet": [ @@ -1386,46 +1463,46 @@ 175.61 ], "angles_trig": [ - 1.8443, + 2.0087, 175.57 ], "ne1d": 5988, - "ne2d": 11102, - "ne3d": 29140, - "quality_histogram": "[3, 4, 3, 10, 18, 43, 114, 248, 669, 1026, 1563, 2467, 3073, 3886, 4389, 4179, 3406, 2403, 1317, 319]", - "total_badness": 43201.580215 + "ne2d": 10976, + "ne3d": 29065, + "quality_histogram": "[3, 4, 3, 11, 16, 45, 110, 221, 664, 978, 1581, 2526, 3121, 3891, 4274, 4114, 3456, 2388, 1312, 347]", + "total_badness": 43056.520137 }, { "angles_tet": [ - 2.1788, + 2.171, 174.11 ], "angles_trig": [ - 2.2053, + 1.6035, 174.13 ], "ne1d": 9622, - "ne2d": 23964, - "ne3d": 80884, - "quality_histogram": "[2, 15, 4, 18, 16, 39, 98, 222, 478, 1114, 2389, 4532, 7510, 10291, 12685, 13114, 12137, 9102, 5641, 1477]", - "total_badness": 111769.66842 + "ne2d": 23596, + "ne3d": 80062, + "quality_histogram": "[2, 15, 4, 18, 14, 35, 84, 189, 432, 1005, 2118, 4194, 7190, 10267, 12556, 13449, 12163, 9311, 5588, 1428]", + "total_badness": 110028.28336 } ], "hinge.stl": [ { "angles_tet": [ - 16.835, - 148.75 + 16.119, + 155.5 ], "angles_trig": [ 18.101, 139.79 ], "ne1d": 456, - "ne2d": 1220, - "ne3d": 1985, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 0, 9, 20, 38, 65, 129, 172, 240, 303, 297, 268, 263, 138, 42]", - "total_badness": 2749.9093553 + "ne2d": 1212, + "ne3d": 1997, + "quality_histogram": "[0, 0, 0, 0, 0, 2, 3, 13, 16, 45, 74, 128, 187, 237, 290, 279, 264, 264, 149, 46]", + "total_badness": 2785.3969831 }, { "angles_tet": [ @@ -1444,63 +1521,63 @@ }, { "angles_tet": [ - 10.751, - 157.43 + 6.3759, + 164.51 ], "angles_trig": [ 12.656, 152.72 ], "ne1d": 370, - "ne2d": 856, - "ne3d": 1134, - "quality_histogram": "[0, 0, 0, 2, 4, 5, 14, 25, 38, 56, 78, 119, 136, 137, 152, 151, 98, 66, 45, 8]", - "total_badness": 1795.6519937 + "ne2d": 850, + "ne3d": 1124, + "quality_histogram": "[0, 0, 1, 1, 7, 6, 14, 27, 38, 52, 69, 112, 142, 138, 163, 145, 96, 62, 43, 8]", + "total_badness": 1789.6525041 }, { "angles_tet": [ - 13.485, + 13.442, 156.97 ], "angles_trig": [ - 19.521, + 21.175, 135.02 ], "ne1d": 516, - "ne2d": 1574, - "ne3d": 2592, - "quality_histogram": "[0, 0, 0, 0, 0, 4, 3, 4, 24, 49, 98, 174, 224, 322, 378, 396, 333, 317, 216, 50]", - "total_badness": 3599.8559259 + "ne2d": 1570, + "ne3d": 2567, + "quality_histogram": "[0, 0, 0, 0, 0, 4, 3, 5, 22, 47, 97, 152, 226, 318, 382, 403, 346, 303, 207, 52]", + "total_badness": 3558.447444 }, { "angles_tet": [ - 19.877, - 146.81 + 19.878, + 145.14 ], "angles_trig": [ - 21.493, + 22.16, 131.22 ], "ne1d": 722, - "ne2d": 2866, - "ne3d": 6672, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 1, 24, 30, 67, 169, 331, 632, 870, 1040, 1173, 1200, 874, 260]", - "total_badness": 8558.9452401 + "ne2d": 2856, + "ne3d": 6740, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 3, 20, 38, 63, 161, 381, 636, 854, 1077, 1143, 1240, 851, 272]", + "total_badness": 8654.5076132 }, { "angles_tet": [ - 20.701, - 141.98 + 19.377, + 142.75 ], "angles_trig": [ - 22.443, - 122.07 + 19.877, + 128.48 ], "ne1d": 1862, - "ne2d": 19474, - "ne3d": 136547, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 8, 60, 274, 868, 2525, 6456, 12982, 21266, 29083, 31162, 24018, 7844]", - "total_badness": 165951.25229 + "ne2d": 19428, + "ne3d": 136241, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 21, 85, 308, 898, 2566, 6394, 12973, 21289, 28986, 31392, 23775, 7551]", + "total_badness": 165729.88879 } ], "lense.in2d": [ @@ -1514,7 +1591,7 @@ 0.0 ], "ne1d": 81, - "ne2d": 442, + "ne2d": 436, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -1529,7 +1606,7 @@ 0.0 ], "ne1d": 86, - "ne2d": 464, + "ne2d": 452, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -1544,7 +1621,7 @@ 0.0 ], "ne1d": 86, - "ne2d": 466, + "ne2d": 450, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -1559,7 +1636,7 @@ 0.0 ], "ne1d": 81, - "ne2d": 442, + "ne2d": 436, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -1658,80 +1735,80 @@ }, { "angles_tet": [ - 31.641, - 125.43 + 26.688, + 123.84 ], "angles_trig": [ - 32.108, - 97.676 + 28.101, + 94.214 ], "ne1d": 80, - "ne2d": 76, - "ne3d": 88, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 24, 21, 11, 5, 1, 5]", - "total_badness": 119.51330947 + "ne2d": 70, + "ne3d": 80, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 11, 7, 14, 21, 12, 3, 1, 6]", + "total_badness": 108.61313976 }, { "angles_tet": [ 25.888, - 130.75 + 134.08 ], "angles_trig": [ - 26.255, + 26.787, 106.78 ], "ne1d": 122, - "ne2d": 204, - "ne3d": 326, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 12, 19, 39, 41, 73, 58, 41, 29, 11]", - "total_badness": 425.73873607 + "ne2d": 202, + "ne3d": 330, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 10, 15, 44, 41, 55, 65, 53, 31, 11]", + "total_badness": 428.23859625 } ], "manyholes.geo": [ { "angles_tet": [ - 14.551, - 155.18 + 14.55, + 155.04 ], "angles_trig": [ - 16.38, - 141.4 + 18.117, + 139.37 ], "ne1d": 5886, - "ne2d": 48052, - "ne3d": 178844, - "quality_histogram": "[0, 0, 0, 0, 0, 5, 11, 71, 288, 829, 2312, 6198, 10948, 18856, 27414, 30640, 31333, 26927, 18474, 4538]", - "total_badness": 233920.54177 + "ne2d": 47960, + "ne3d": 178644, + "quality_histogram": "[0, 0, 0, 0, 0, 3, 13, 65, 309, 829, 2249, 6172, 11069, 18932, 27032, 30759, 31519, 26938, 18336, 4419]", + "total_badness": 233705.64122 }, { "angles_tet": [ - 11.536, - 149.67 + 11.11, + 150.31 ], "angles_trig": [ - 15.246, - 137.87 + 12.689, + 138.1 ], "ne1d": 2746, - "ne2d": 13866, - "ne3d": 29391, - "quality_histogram": "[0, 0, 0, 0, 13, 14, 37, 136, 380, 846, 1453, 2331, 3276, 4281, 4196, 3749, 3317, 2686, 1967, 709]", - "total_badness": 42208.382479 + "ne2d": 13702, + "ne3d": 29135, + "quality_histogram": "[0, 0, 0, 0, 15, 18, 43, 126, 369, 780, 1378, 2288, 3194, 4318, 4061, 3733, 3348, 2748, 1989, 727]", + "total_badness": 41713.598662 }, { "angles_tet": [ - 11.183, - 153.89 + 11.184, + 153.75 ], "angles_trig": [ 12.194, - 138.76 + 138.75 ], "ne1d": 4106, - "ne2d": 27994, - "ne3d": 70789, - "quality_histogram": "[0, 0, 0, 1, 31, 72, 171, 344, 668, 1440, 2602, 4089, 6675, 9290, 10472, 10751, 9903, 7620, 4876, 1784]", - "total_badness": 99059.754776 + "ne2d": 27824, + "ne3d": 70201, + "quality_histogram": "[0, 0, 0, 1, 27, 76, 199, 309, 649, 1436, 2566, 3992, 6615, 9029, 10226, 10693, 9895, 7793, 4854, 1841]", + "total_badness": 98065.083443 } ], "manyholes2.geo": [ @@ -1741,106 +1818,106 @@ 152.51 ], "angles_trig": [ - 15.466, - 135.27 + 16.05, + 134.75 ], "ne1d": 10202, - "ne2d": 55380, - "ne3d": 128239, - "quality_histogram": "[0, 0, 0, 0, 4, 28, 79, 241, 721, 1932, 4433, 7722, 11698, 17421, 18591, 18340, 17271, 15154, 10934, 3670]", - "total_badness": 176223.54068 + "ne2d": 54864, + "ne3d": 127476, + "quality_histogram": "[0, 0, 0, 0, 3, 26, 67, 253, 706, 2016, 4264, 7581, 11687, 16856, 18247, 18310, 17519, 15264, 10990, 3687]", + "total_badness": 174923.26093 } ], "matrix.geo": [ { "angles_tet": [ - 9.8227, - 167.77 + 6.3942, + 171.62 ], "angles_trig": [ - 10.647, - 154.14 + 8.6593, + 160.8 ], "ne1d": 174, - "ne2d": 1198, - "ne3d": 5070, - "quality_histogram": "[0, 0, 11, 117, 166, 59, 60, 113, 98, 185, 297, 374, 498, 658, 620, 577, 494, 424, 240, 79]", - "total_badness": 8804.2621534 + "ne2d": 1190, + "ne3d": 5100, + "quality_histogram": "[0, 0, 15, 128, 183, 43, 56, 114, 127, 183, 297, 369, 495, 599, 625, 611, 547, 412, 235, 61]", + "total_badness": 8961.2205551 }, { "angles_tet": [ - 9.3063, - 165.3 + 3.4677, + 173.13 ], "angles_trig": [ - 7.9174, + 9.2392, 161.29 ], "ne1d": 106, - "ne2d": 610, - "ne3d": 1659, - "quality_histogram": "[0, 1, 13, 49, 81, 155, 190, 149, 159, 132, 135, 145, 137, 107, 66, 37, 33, 40, 26, 4]", - "total_badness": 4094.4605262 + "ne2d": 564, + "ne3d": 1498, + "quality_histogram": "[0, 2, 15, 56, 89, 130, 198, 136, 138, 115, 110, 107, 116, 99, 71, 34, 36, 25, 15, 6]", + "total_badness": 3831.0654483 }, { "angles_tet": [ - 6.3111, - 169.7 + 7.6687, + 169.26 ], "angles_trig": [ - 10.116, - 150.34 + 8.6573, + 161.61 ], "ne1d": 132, - "ne2d": 830, - "ne3d": 2488, - "quality_histogram": "[0, 0, 3, 37, 71, 155, 161, 102, 158, 211, 284, 276, 249, 203, 195, 139, 108, 79, 42, 15]", - "total_badness": 5146.3098762 + "ne2d": 812, + "ne3d": 2514, + "quality_histogram": "[0, 0, 7, 63, 69, 154, 134, 117, 148, 199, 247, 286, 257, 214, 177, 162, 120, 92, 45, 23]", + "total_badness": 5239.4475113 }, { "angles_tet": [ - 9.8227, - 167.77 + 6.3942, + 171.62 ], "angles_trig": [ - 10.647, - 154.14 + 8.6592, + 160.8 ], "ne1d": 174, - "ne2d": 1198, - "ne3d": 5012, - "quality_histogram": "[0, 0, 7, 101, 161, 60, 53, 107, 93, 172, 281, 320, 519, 570, 616, 653, 509, 445, 260, 85]", - "total_badness": 8527.4907589 + "ne2d": 1190, + "ne3d": 5054, + "quality_histogram": "[0, 0, 14, 117, 182, 41, 51, 115, 112, 153, 269, 315, 481, 581, 632, 634, 561, 474, 247, 75]", + "total_badness": 8725.1829981 }, { "angles_tet": [ - 12.758, - 148.17 + 12.76, + 147.23 ], "angles_trig": [ - 15.825, + 15.824, 143.02 ], "ne1d": 248, - "ne2d": 2324, - "ne3d": 16371, - "quality_histogram": "[0, 0, 0, 0, 0, 5, 22, 53, 115, 192, 297, 621, 1022, 1479, 2137, 2601, 2778, 2625, 1890, 534]", - "total_badness": 21627.026306 + "ne2d": 2320, + "ne3d": 16409, + "quality_histogram": "[0, 0, 0, 0, 0, 4, 20, 55, 119, 192, 288, 630, 958, 1489, 2106, 2552, 2926, 2613, 1913, 544]", + "total_badness": 21635.781365 }, { "angles_tet": [ 18.203, - 145.38 + 144.68 ], "angles_trig": [ 17.821, - 129.69 + 130.51 ], "ne1d": 418, - "ne2d": 5968, - "ne3d": 101113, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 4, 7, 51, 102, 349, 993, 2550, 5563, 10196, 16090, 20698, 22258, 16911, 5341]", - "total_badness": 124155.81178 + "ne2d": 5958, + "ne3d": 102414, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 4, 6, 45, 124, 368, 1028, 2576, 5782, 10622, 16119, 21223, 22353, 16809, 5354]", + "total_badness": 125921.99427 } ], "ortho.geo": [ @@ -1921,18 +1998,18 @@ }, { "angles_tet": [ - 26.39, - 132.21 + 26.004, + 135.33 ], "angles_trig": [ - 26.945, - 100.27 + 28.064, + 108.07 ], "ne1d": 72, - "ne2d": 116, - "ne3d": 179, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 9, 9, 26, 31, 39, 31, 13, 12]", - "total_badness": 229.03446012 + "ne2d": 104, + "ne3d": 157, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 10, 8, 19, 19, 24, 24, 34, 8, 8]", + "total_badness": 206.14578364 } ], "part1.stl": [ @@ -1957,76 +2034,76 @@ 157.41 ], "angles_trig": [ - 12.077, - 146.08 + 16.503, + 144.04 ], "ne1d": 134, - "ne2d": 288, - "ne3d": 524, - "quality_histogram": "[0, 0, 0, 2, 4, 2, 4, 7, 16, 28, 38, 46, 52, 62, 72, 70, 55, 40, 24, 2]", - "total_badness": 820.9371699 + "ne2d": 286, + "ne3d": 529, + "quality_histogram": "[0, 0, 0, 2, 4, 2, 4, 5, 13, 31, 36, 45, 51, 81, 71, 56, 62, 43, 20, 3]", + "total_badness": 824.2762646 }, { "angles_tet": [ - 21.121, - 143.15 + 19.623, + 148.63 ], "angles_trig": [ - 24.417, - 116.27 + 19.446, + 132.67 ], "ne1d": 194, - "ne2d": 594, - "ne3d": 1693, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 5, 3, 28, 53, 113, 172, 250, 278, 293, 284, 173, 40]", - "total_badness": 2213.1235108 + "ne2d": 590, + "ne3d": 1629, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 1, 2, 7, 11, 31, 56, 119, 210, 240, 245, 292, 235, 140, 39]", + "total_badness": 2170.2820961 }, { "angles_tet": [ - 22.044, - 141.38 + 21.731, + 138.73 ], "angles_trig": [ - 25.297, - 120.13 + 24.944, + 119.75 ], "ne1d": 266, - "ne2d": 986, - "ne3d": 4106, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 5, 11, 28, 57, 139, 316, 492, 706, 817, 813, 570, 151]", - "total_badness": 5157.0222907 + "ne2d": 980, + "ne3d": 4128, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 1, 5, 20, 83, 161, 326, 494, 640, 851, 800, 593, 153]", + "total_badness": 5188.8712057 }, { "angles_tet": [ - 23.336, - 138.08 + 21.099, + 146.09 ], "angles_trig": [ - 24.552, - 127.25 + 24.61, + 127.03 ], "ne1d": 674, - "ne2d": 6854, - "ne3d": 82721, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 3, 16, 118, 414, 1347, 3658, 7624, 12768, 17708, 19580, 14908, 4576]", - "total_badness": 100175.28811 + "ne2d": 6832, + "ne3d": 82647, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 4, 17, 101, 396, 1391, 3605, 7593, 12586, 17573, 19510, 15047, 4823]", + "total_badness": 99991.989263 } ], "period.geo": [ { "angles_tet": [ - 11.121, - 150.16 + 13.348, + 152.73 ], "angles_trig": [ - 18.736, - 133.1 + 15.314, + 135.35 ], "ne1d": 344, - "ne2d": 1136, - "ne3d": 3269, - "quality_histogram": "[0, 0, 0, 0, 2, 4, 13, 24, 57, 92, 181, 260, 351, 430, 482, 454, 417, 280, 179, 43]", - "total_badness": 4762.4191481 + "ne2d": 1118, + "ne3d": 3303, + "quality_histogram": "[0, 0, 0, 0, 1, 3, 19, 26, 62, 80, 167, 270, 341, 414, 475, 449, 428, 344, 170, 54]", + "total_badness": 4786.8429022 }, { "angles_tet": [ @@ -2034,326 +2111,326 @@ 162.28 ], "angles_trig": [ - 14.714, - 141.01 + 14.767, + 140.96 ], "ne1d": 160, - "ne2d": 286, - "ne3d": 598, - "quality_histogram": "[0, 0, 0, 0, 3, 2, 13, 17, 35, 62, 59, 74, 66, 57, 56, 49, 39, 43, 19, 4]", - "total_badness": 1009.5773389 + "ne2d": 280, + "ne3d": 601, + "quality_histogram": "[0, 0, 0, 0, 3, 6, 10, 21, 33, 57, 65, 81, 72, 40, 61, 53, 34, 48, 13, 4]", + "total_badness": 1021.3669479 }, { "angles_tet": [ - 11.356, - 162.52 + 13.869, + 161.3 ], "angles_trig": [ - 16.741, + 16.622, 141.37 ], "ne1d": 232, - "ne2d": 598, - "ne3d": 1418, - "quality_histogram": "[0, 0, 0, 2, 9, 14, 27, 47, 66, 97, 109, 150, 161, 159, 147, 133, 119, 96, 66, 16]", - "total_badness": 2344.2576172 + "ne2d": 566, + "ne3d": 1302, + "quality_histogram": "[0, 0, 0, 1, 4, 17, 29, 39, 64, 86, 116, 123, 148, 143, 127, 134, 119, 83, 58, 11]", + "total_badness": 2151.3919236 }, { "angles_tet": [ - 11.121, - 150.16 + 14.824, + 146.25 ], "angles_trig": [ - 19.085, - 134.23 + 15.314, + 135.03 ], "ne1d": 344, - "ne2d": 1136, - "ne3d": 3234, - "quality_histogram": "[0, 0, 0, 0, 2, 4, 12, 25, 48, 85, 148, 219, 353, 420, 468, 466, 428, 322, 182, 52]", - "total_badness": 4649.5043488 + "ne2d": 1118, + "ne3d": 3261, + "quality_histogram": "[0, 0, 0, 0, 1, 2, 14, 23, 47, 67, 152, 225, 319, 424, 475, 458, 420, 389, 183, 62]", + "total_badness": 4647.8518467 }, { "angles_tet": [ - 20.737, - 141.73 + 21.808, + 142.31 ], "angles_trig": [ - 23.506, - 122.66 + 23.022, + 128.64 ], "ne1d": 480, - "ne2d": 2256, - "ne3d": 11548, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 28, 90, 222, 484, 867, 1460, 1999, 2324, 2067, 1547, 456]", - "total_badness": 14596.906314 + "ne2d": 2248, + "ne3d": 11618, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 8, 29, 90, 215, 539, 874, 1483, 1964, 2225, 2201, 1553, 437]", + "total_badness": 14695.782197 }, { "angles_tet": [ - 21.56, - 145.28 + 22.578, + 141.63 ], "angles_trig": [ - 22.722, - 129.08 + 22.146, + 120.55 ], "ne1d": 820, - "ne2d": 6226, - "ne3d": 68692, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 11, 49, 185, 510, 1531, 3657, 6895, 10997, 14320, 15199, 11644, 3694]", - "total_badness": 84012.009025 + "ne2d": 6206, + "ne3d": 68506, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 6, 49, 164, 556, 1500, 3472, 6624, 10942, 14570, 15222, 11736, 3665]", + "total_badness": 83683.476233 } ], "plane.stl": [ { "angles_tet": [ - 1.2026, - 166.97 + 1.3791, + 166.17 ], "angles_trig": [ - 3.5084, + 1.7725, 158.16 ], "ne1d": 886, - "ne2d": 2592, - "ne3d": 8292, - "quality_histogram": "[5, 9, 29, 46, 37, 51, 44, 46, 94, 160, 257, 412, 647, 899, 1265, 1378, 1157, 1002, 611, 143]", - "total_badness": 12343.24347 + "ne2d": 2528, + "ne3d": 8236, + "quality_histogram": "[5, 8, 33, 42, 41, 52, 40, 53, 84, 115, 226, 410, 616, 890, 1226, 1335, 1291, 1015, 601, 153]", + "total_badness": 12202.367974 }, { "angles_tet": [ - 1.0841, - 174.05 + 1.181, + 174.03 ], "angles_trig": [ - 3.4703, + 2.5404, 170.0 ], "ne1d": 570, - "ne2d": 1202, - "ne3d": 1795, - "quality_histogram": "[2, 20, 39, 51, 70, 80, 102, 131, 157, 158, 176, 170, 145, 140, 122, 84, 67, 50, 26, 5]", - "total_badness": 4436.3977005 + "ne2d": 1126, + "ne3d": 1625, + "quality_histogram": "[3, 23, 42, 49, 57, 79, 92, 122, 133, 143, 160, 125, 136, 136, 122, 67, 62, 43, 27, 4]", + "total_badness": 4132.7009693 }, { "angles_tet": [ - 1.1033, - 171.77 + 1.1, + 172.16 ], "angles_trig": [ - 3.728, - 165.5 + 2.2863, + 165.88 ], "ne1d": 724, - "ne2d": 1730, - "ne3d": 3290, - "quality_histogram": "[3, 18, 29, 53, 45, 38, 53, 72, 116, 168, 230, 257, 328, 415, 424, 399, 334, 189, 92, 27]", - "total_badness": 6051.57684 + "ne2d": 1662, + "ne3d": 3079, + "quality_histogram": "[2, 13, 28, 54, 52, 45, 53, 71, 110, 127, 187, 249, 337, 394, 368, 357, 294, 200, 113, 25]", + "total_badness": 5638.801451 }, { "angles_tet": [ - 1.2134, - 169.94 + 1.2152, + 169.91 ], "angles_trig": [ - 2.0839, - 163.08 + 1.1526, + 158.98 ], "ne1d": 956, - "ne2d": 2828, - "ne3d": 8481, - "quality_histogram": "[3, 8, 38, 49, 47, 50, 55, 57, 96, 137, 195, 343, 515, 792, 1200, 1366, 1417, 1181, 742, 190]", - "total_badness": 12456.662988 + "ne2d": 2742, + "ne3d": 8675, + "quality_histogram": "[3, 11, 40, 47, 45, 52, 53, 57, 84, 132, 177, 326, 500, 771, 1187, 1468, 1538, 1257, 742, 185]", + "total_badness": 12664.774403 }, { "angles_tet": [ - 1.1518, - 168.3 + 1.1486, + 168.27 ], "angles_trig": [ - 1.7811, - 158.38 + 5.1964, + 153.78 ], "ne1d": 1554, - "ne2d": 6372, - "ne3d": 31605, - "quality_histogram": "[2, 8, 13, 9, 26, 53, 51, 69, 87, 191, 315, 647, 1221, 2378, 3853, 5328, 6181, 5935, 4068, 1170]", - "total_badness": 40844.172563 + "ne2d": 6276, + "ne3d": 30191, + "quality_histogram": "[2, 8, 13, 8, 27, 48, 54, 67, 94, 163, 310, 595, 1224, 2288, 3706, 5135, 6007, 5525, 3828, 1089]", + "total_badness": 39089.872515 }, { "angles_tet": [ - 1.2315, - 163.84 + 1.2348, + 163.1 ], "angles_trig": [ - 1.2724, - 158.0 + 1.8992, + 156.49 ], "ne1d": 2992, - "ne2d": 23322, - "ne3d": 281946, - "quality_histogram": "[4, 10, 12, 10, 9, 21, 29, 60, 99, 245, 724, 2133, 5538, 13549, 27663, 44504, 60069, 63936, 48457, 14874]", - "total_badness": 344547.37835 + "ne2d": 23260, + "ne3d": 281899, + "quality_histogram": "[4, 10, 11, 10, 10, 23, 27, 58, 100, 257, 753, 2012, 5557, 13696, 27894, 44772, 59147, 64039, 48573, 14946]", + "total_badness": 344505.69105 } ], "revolution.geo": [ { "angles_tet": [ - 17.33, - 146.89 + 17.744, + 147.59 ], "angles_trig": [ - 16.848, - 130.37 + 14.696, + 141.88 ], "ne1d": 320, - "ne2d": 3110, - "ne3d": 8379, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 3, 27, 90, 212, 461, 680, 967, 1096, 1153, 1170, 1080, 802, 520, 118]", - "total_badness": 11967.150699 + "ne2d": 3036, + "ne3d": 8332, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 6, 14, 93, 181, 405, 666, 868, 1013, 1163, 1292, 1106, 859, 537, 128]", + "total_badness": 11773.570067 }, { "angles_tet": [ - 8.7903, - 155.06 + 11.882, + 146.86 ], "angles_trig": [ - 15.518, - 131.14 + 14.214, + 130.13 ], "ne1d": 160, - "ne2d": 822, - "ne3d": 1234, - "quality_histogram": "[0, 0, 0, 1, 0, 10, 62, 86, 121, 132, 145, 139, 147, 99, 95, 67, 61, 38, 23, 8]", - "total_badness": 2290.4515055 + "ne2d": 810, + "ne3d": 1203, + "quality_histogram": "[0, 0, 0, 0, 1, 9, 46, 90, 113, 123, 137, 153, 142, 117, 77, 60, 66, 44, 22, 3]", + "total_badness": 2211.7606301 }, { "angles_tet": [ - 16.888, - 145.04 + 18.06, + 148.6 ], "angles_trig": [ - 17.592, - 134.95 + 18.172, + 136.2 ], "ne1d": 240, - "ne2d": 1830, - "ne3d": 3886, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 3, 27, 70, 177, 288, 405, 522, 502, 496, 407, 393, 336, 210, 49]", - "total_badness": 5799.4091506 + "ne2d": 1784, + "ne3d": 3829, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 6, 14, 53, 116, 264, 371, 515, 519, 502, 434, 425, 344, 212, 54]", + "total_badness": 5608.194789 }, { "angles_tet": [ - 18.416, - 144.94 + 18.169, + 146.68 ], "angles_trig": [ - 18.352, - 126.94 + 19.015, + 128.63 ], "ne1d": 320, - "ne2d": 3110, - "ne3d": 8258, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 2, 13, 48, 141, 339, 627, 829, 1041, 1149, 1209, 1156, 945, 605, 154]", - "total_badness": 11481.414846 + "ne2d": 3036, + "ne3d": 8213, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 3, 49, 124, 291, 550, 780, 982, 1146, 1315, 1218, 939, 652, 163]", + "total_badness": 11293.441654 }, { "angles_tet": [ - 19.038, - 140.94 + 18.467, + 147.96 ], "angles_trig": [ - 22.544, - 132.58 + 24.032, + 125.58 ], "ne1d": 480, - "ne2d": 6864, - "ne3d": 33174, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 185, 571, 1253, 2563, 4038, 5675, 6688, 6259, 4556, 1330]", - "total_badness": 41696.548838 + "ne2d": 6742, + "ne3d": 32904, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 0, 6, 46, 185, 550, 1205, 2424, 4071, 5672, 6538, 6374, 4491, 1341]", + "total_badness": 41305.051414 }, { "angles_tet": [ - 21.902, - 143.83 + 21.528, + 144.92 ], "angles_trig": [ - 19.492, - 121.07 + 23.268, + 123.02 ], "ne1d": 800, - "ne2d": 17934, - "ne3d": 201307, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 4, 11, 83, 359, 1237, 3580, 9039, 19000, 30994, 42542, 46628, 36256, 11574]", - "total_badness": 244220.94708 + "ne2d": 17594, + "ne3d": 201135, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 15, 66, 375, 1180, 3460, 8980, 18968, 31265, 42578, 46860, 36085, 11302]", + "total_badness": 243964.93671 } ], "screw.step": [ { "angles_tet": [ - 15.139, - 148.36 + 17.752, + 142.33 ], "angles_trig": [ - 17.363, - 140.59 + 19.029, + 137.96 ], "ne1d": 400, - "ne2d": 1436, - "ne3d": 2342, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 16, 61, 92, 165, 209, 246, 307, 280, 262, 272, 182, 148, 84, 18]", - "total_badness": 3718.1755695 + "ne2d": 1390, + "ne3d": 2336, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 2, 54, 79, 137, 200, 257, 265, 306, 286, 263, 221, 140, 104, 22]", + "total_badness": 3622.1771287 }, { "angles_tet": [ - 19.077, + 19.834, 146.38 ], "angles_trig": [ - 17.221, - 126.09 + 14.76, + 127.82 ], "ne1d": 528, - "ne2d": 2792, - "ne3d": 8126, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 4, 11, 33, 98, 190, 299, 553, 796, 1040, 1329, 1446, 1294, 795, 237]", - "total_badness": 10753.750681 + "ne2d": 2724, + "ne3d": 8021, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 3, 10, 28, 70, 148, 286, 485, 757, 1058, 1331, 1509, 1230, 840, 265]", + "total_badness": 10517.478669 }, { "angles_tet": [ - 20.515, - 144.03 + 20.122, + 143.27 ], "angles_trig": [ - 24.891, - 120.48 + 23.794, + 129.76 ], "ne1d": 666, - "ne2d": 4922, - "ne3d": 31546, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 5, 29, 94, 294, 701, 1778, 3224, 4988, 6720, 6967, 5142, 1603]", - "total_badness": 38702.936245 + "ne2d": 4792, + "ne3d": 31253, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 2, 5, 23, 101, 240, 652, 1499, 3037, 4927, 6557, 7202, 5289, 1719]", + "total_badness": 38131.596693 } ], "sculpture.geo": [ { "angles_tet": [ - 17.362, - 152.2 + 17.385, + 152.17 ], "angles_trig": [ 25.459, - 115.78 + 116.96 ], "ne1d": 192, - "ne2d": 414, - "ne3d": 476, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 2, 5, 16, 21, 32, 60, 64, 94, 100, 42, 25, 12, 2]", - "total_badness": 693.83910484 + "ne2d": 410, + "ne3d": 475, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 2, 3, 7, 11, 21, 29, 61, 75, 95, 88, 43, 27, 12, 1]", + "total_badness": 694.76962476 }, { "angles_tet": [ - 28.072, + 28.299, 137.6 ], "angles_trig": [ @@ -2361,40 +2438,40 @@ 109.61 ], "ne1d": 102, - "ne2d": 146, - "ne3d": 142, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 6, 11, 19, 18, 35, 29, 17, 2]", - "total_badness": 181.04521663 + "ne2d": 144, + "ne3d": 139, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 4, 11, 22, 21, 29, 28, 19, 1]", + "total_badness": 175.93959257 }, { "angles_tet": [ 23.253, - 139.76 + 133.46 ], "angles_trig": [ - 28.457, - 103.35 + 30.283, + 102.14 ], "ne1d": 144, - "ne2d": 250, - "ne3d": 264, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 5, 9, 13, 27, 29, 52, 47, 46, 25, 7]", - "total_badness": 345.68732003 + "ne2d": 236, + "ne3d": 237, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 7, 5, 20, 35, 43, 52, 46, 21, 3]", + "total_badness": 305.10160433 }, { "angles_tet": [ - 17.362, - 152.2 + 17.385, + 152.17 ], "angles_trig": [ 25.459, - 115.78 + 116.96 ], "ne1d": 192, - "ne2d": 414, - "ne3d": 476, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 2, 5, 16, 21, 32, 60, 64, 94, 100, 42, 25, 12, 2]", - "total_badness": 693.83910484 + "ne2d": 410, + "ne3d": 475, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 2, 3, 7, 11, 21, 29, 61, 75, 95, 88, 43, 27, 12, 1]", + "total_badness": 694.76962627 }, { "angles_tet": [ @@ -2406,72 +2483,72 @@ 127.3 ], "ne1d": 288, - "ne2d": 962, - "ne3d": 1325, - "quality_histogram": "[0, 0, 0, 0, 1, 3, 6, 25, 50, 85, 117, 137, 126, 139, 114, 144, 146, 127, 86, 19]", - "total_badness": 2043.076343 + "ne2d": 960, + "ne3d": 1321, + "quality_histogram": "[0, 0, 0, 0, 1, 3, 5, 25, 51, 84, 114, 135, 125, 139, 115, 140, 150, 133, 86, 15]", + "total_badness": 2032.8935475 }, { "angles_tet": [ - 14.743, - 147.57 + 15.031, + 155.59 ], "angles_trig": [ - 17.184, - 119.06 + 16.998, + 125.02 ], "ne1d": 480, - "ne2d": 2394, - "ne3d": 6711, - "quality_histogram": "[0, 0, 0, 0, 2, 2, 7, 8, 21, 26, 61, 123, 262, 462, 722, 1073, 1348, 1317, 960, 317]", - "total_badness": 8476.8430085 + "ne2d": 2362, + "ne3d": 6743, + "quality_histogram": "[0, 0, 0, 0, 2, 6, 7, 16, 24, 34, 66, 83, 239, 395, 735, 1164, 1348, 1328, 975, 321]", + "total_badness": 8504.962138 } ], "shaft.geo": [ { "angles_tet": [ - 8.3078, + 9.0272, 162.65 ], "angles_trig": [ - 9.3916, - 147.77 + 9.4742, + 149.97 ], "ne1d": 708, - "ne2d": 1722, - "ne3d": 2734, - "quality_histogram": "[0, 0, 2, 4, 8, 15, 30, 41, 85, 143, 291, 393, 333, 284, 246, 293, 248, 190, 101, 27]", - "total_badness": 4392.4206713 + "ne2d": 1702, + "ne3d": 2702, + "quality_histogram": "[0, 0, 1, 3, 11, 21, 27, 39, 97, 138, 279, 414, 309, 306, 236, 278, 234, 193, 92, 24]", + "total_badness": 4366.515194 }, { "angles_tet": [ - 15.154, - 159.78 + 13.761, + 159.41 ], "angles_trig": [ 17.101, - 134.17 + 121.48 ], "ne1d": 410, - "ne2d": 606, - "ne3d": 791, - "quality_histogram": "[0, 0, 0, 0, 2, 3, 4, 7, 33, 42, 54, 61, 88, 86, 118, 92, 89, 72, 29, 11]", - "total_badness": 1208.0644901 + "ne2d": 592, + "ne3d": 758, + "quality_histogram": "[0, 0, 0, 0, 1, 4, 2, 7, 27, 35, 40, 57, 81, 83, 95, 90, 90, 82, 51, 13]", + "total_badness": 1126.5212658 }, { "angles_tet": [ - 12.907, - 158.51 + 11.675, + 157.57 ], "angles_trig": [ - 11.963, - 148.8 + 17.149, + 140.0 ], "ne1d": 510, - "ne2d": 1004, - "ne3d": 1859, - "quality_histogram": "[0, 0, 0, 3, 7, 29, 43, 74, 68, 95, 115, 158, 153, 213, 250, 232, 206, 107, 81, 25]", - "total_badness": 3021.4076425 + "ne2d": 996, + "ne3d": 1816, + "quality_histogram": "[0, 0, 0, 0, 6, 19, 34, 69, 83, 108, 123, 159, 163, 197, 236, 222, 211, 84, 77, 25]", + "total_badness": 2937.5679156 }, { "angles_tet": [ @@ -2479,61 +2556,61 @@ 162.65 ], "angles_trig": [ - 15.512, - 147.17 + 15.173, + 147.47 ], "ne1d": 708, - "ne2d": 1722, - "ne3d": 2708, - "quality_histogram": "[0, 0, 0, 1, 3, 1, 11, 22, 50, 108, 258, 412, 344, 299, 275, 311, 271, 203, 108, 31]", - "total_badness": 4149.681437 + "ne2d": 1702, + "ne3d": 2677, + "quality_histogram": "[0, 0, 0, 1, 3, 1, 9, 25, 50, 119, 274, 411, 334, 300, 263, 298, 260, 208, 94, 27]", + "total_badness": 4129.758993 }, { "angles_tet": [ - 19.192, - 146.58 + 19.018, + 146.87 ], "angles_trig": [ - 19.637, - 120.23 + 20.005, + 121.85 ], "ne1d": 1138, - "ne2d": 4220, - "ne3d": 11314, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 31, 71, 185, 327, 551, 977, 1446, 1854, 2226, 1947, 1281, 415]", - "total_badness": 14598.782663 + "ne2d": 4170, + "ne3d": 11024, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 31, 70, 182, 338, 557, 913, 1365, 1807, 2087, 1935, 1366, 370]", + "total_badness": 14215.80019 }, { "angles_tet": [ - 22.61, - 139.73 + 23.078, + 140.0 ], "angles_trig": [ - 22.297, - 118.87 + 23.507, + 113.96 ], "ne1d": 1792, - "ne2d": 10600, - "ne3d": 63839, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 22, 130, 424, 1292, 3122, 6208, 9992, 13576, 14305, 11041, 3723]", - "total_badness": 77729.577133 + "ne2d": 10558, + "ne3d": 63759, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 23, 119, 452, 1273, 2950, 6107, 10188, 13395, 14439, 11137, 3672]", + "total_badness": 77561.90794 } ], "sphere.geo": [ { "angles_tet": [ - 42.957, - 93.227 + 42.043, + 88.484 ], "angles_trig": [ - 20.575, - 79.713 + 20.502, + 79.749 ], "ne1d": 0, - "ne2d": 126, - "ne3d": 126, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 6, 25, 47, 33, 12, 1, 2, 0, 0, 0, 0, 0]", - "total_badness": 237.42979301 + "ne2d": 124, + "ne3d": 124, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 26, 49, 28, 11, 4, 0, 2, 0, 0, 0, 0]", + "total_badness": 231.6979717 }, { "angles_tet": [ @@ -2552,33 +2629,33 @@ }, { "angles_tet": [ - 51.677, - 84.991 + 42.168, + 87.886 ], "angles_trig": [ - 28.501, - 75.749 + 28.464, + 75.768 ], "ne1d": 0, - "ne2d": 72, - "ne3d": 72, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14, 27, 22, 7, 0, 0, 0]", - "total_badness": 97.572347502 + "ne2d": 70, + "ne3d": 70, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 11, 29, 16, 9, 2, 0, 0]", + "total_badness": 94.413874623 }, { "angles_tet": [ - 42.957, - 93.227 + 42.043, + 88.484 ], "angles_trig": [ - 20.575, - 79.713 + 20.502, + 79.749 ], "ne1d": 0, - "ne2d": 126, - "ne3d": 126, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 6, 25, 47, 33, 12, 1, 2, 0, 0, 0, 0, 0]", - "total_badness": 237.42979301 + "ne2d": 124, + "ne3d": 124, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 4, 26, 49, 28, 11, 4, 0, 2, 0, 0, 0, 0]", + "total_badness": 231.6979717 }, { "angles_tet": [ @@ -2597,18 +2674,18 @@ }, { "angles_tet": [ - 25.093, - 140.27 + 27.682, + 137.56 ], "angles_trig": [ - 24.971, - 118.43 + 26.982, + 116.02 ], "ne1d": 0, - "ne2d": 660, - "ne3d": 2290, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 6, 21, 55, 155, 246, 393, 499, 453, 343, 116]", - "total_badness": 2832.4661091 + "ne2d": 658, + "ne3d": 2312, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, 22, 55, 136, 287, 383, 459, 515, 342, 104]", + "total_badness": 2855.6969029 } ], "sphereincube.geo": [ @@ -2644,18 +2721,18 @@ }, { "angles_tet": [ - 9.1579, - 165.65 + 8.4226, + 166.75 ], "angles_trig": [ - 8.211, - 143.3 + 7.4251, + 143.95 ], "ne1d": 30, - "ne2d": 116, - "ne3d": 264, - "quality_histogram": "[0, 0, 7, 21, 33, 55, 37, 14, 20, 15, 10, 6, 13, 10, 6, 7, 5, 3, 2, 0]", - "total_badness": 850.25370446 + "ne2d": 114, + "ne3d": 270, + "quality_histogram": "[0, 0, 6, 14, 25, 64, 31, 17, 22, 17, 13, 14, 11, 10, 8, 8, 5, 3, 2, 0]", + "total_badness": 818.97155597 }, { "angles_tet": [ @@ -2675,32 +2752,32 @@ { "angles_tet": [ 14.196, - 141.07 + 139.9 ], "angles_trig": [ - 15.659, - 128.46 + 17.059, + 126.31 ], "ne1d": 74, - "ne2d": 418, - "ne3d": 1737, - "quality_histogram": "[0, 0, 0, 0, 0, 5, 5, 10, 28, 29, 64, 81, 147, 223, 267, 259, 251, 200, 126, 42]", - "total_badness": 2428.2600478 + "ne2d": 412, + "ne3d": 1681, + "quality_histogram": "[0, 0, 0, 0, 0, 5, 5, 17, 18, 30, 48, 94, 133, 194, 249, 242, 240, 204, 159, 43]", + "total_badness": 2334.8383469 }, { "angles_tet": [ - 25.662, - 141.31 + 25.029, + 138.94 ], "angles_trig": [ - 22.482, - 131.58 + 22.069, + 127.5 ], "ne1d": 122, - "ne2d": 1082, - "ne3d": 13915, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 89, 213, 396, 802, 1392, 2185, 2853, 2977, 2228, 757]", - "total_badness": 17194.535821 + "ne2d": 1076, + "ne3d": 14037, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 24, 84, 179, 418, 822, 1431, 2256, 2852, 2929, 2328, 711]", + "total_badness": 17344.477334 } ], "square.in2d": [ @@ -2714,7 +2791,7 @@ 0.0 ], "ne1d": 31, - "ne2d": 99, + "ne2d": 97, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2729,7 +2806,7 @@ 0.0 ], "ne1d": 27, - "ne2d": 75, + "ne2d": 71, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2759,7 +2836,7 @@ 0.0 ], "ne1d": 31, - "ne2d": 99, + "ne2d": 97, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2774,7 +2851,7 @@ 0.0 ], "ne1d": 41, - "ne2d": 177, + "ne2d": 173, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2821,7 +2898,7 @@ 0.0 ], "ne1d": 32, - "ne2d": 140, + "ne2d": 132, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2836,7 +2913,7 @@ 0.0 ], "ne1d": 32, - "ne2d": 148, + "ne2d": 134, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2913,7 +2990,7 @@ 0.0 ], "ne1d": 32, - "ne2d": 116, + "ne2d": 108, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2928,7 +3005,7 @@ 0.0 ], "ne1d": 32, - "ne2d": 124, + "ne2d": 110, "ne3d": 0, "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", "total_badness": 0.0 @@ -2997,18 +3074,18 @@ }, { "angles_tet": [ - 1.9786, - 173.68 + 1.7223, + 174.0 ], "angles_trig": [ - 3.8198, - 165.45 + 3.7302, + 165.76 ], "ne1d": 0, - "ne2d": 692, - "ne3d": 2726, - "quality_histogram": "[19, 190, 366, 339, 352, 304, 237, 182, 157, 143, 110, 86, 53, 46, 34, 43, 30, 24, 10, 1]", - "total_badness": 13096.6735 + "ne2d": 690, + "ne3d": 2721, + "quality_histogram": "[20, 156, 335, 321, 371, 280, 203, 227, 159, 137, 138, 86, 58, 55, 40, 41, 41, 27, 23, 3]", + "total_badness": 12443.089915 }, { "angles_tet": [ @@ -3042,33 +3119,33 @@ }, { "angles_tet": [ - 22.543, - 142.87 + 21.326, + 146.04 ], "angles_trig": [ - 22.771, - 121.22 + 23.262, + 121.87 ], "ne1d": 0, - "ne2d": 5894, - "ne3d": 25261, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 11, 44, 119, 414, 855, 1696, 2860, 4123, 4940, 5200, 3813, 1186]", - "total_badness": 31467.735079 + "ne2d": 5890, + "ne3d": 25271, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 10, 41, 108, 355, 777, 1656, 2789, 4110, 5146, 5263, 3910, 1105]", + "total_badness": 31387.456922 }, { "angles_tet": [ - 23.144, - 144.46 + 23.264, + 141.1 ], "angles_trig": [ - 22.932, - 121.88 + 25.356, + 121.98 ], "ne1d": 0, - "ne2d": 16296, - "ne3d": 175488, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 9, 59, 275, 907, 2675, 7276, 15893, 27102, 37072, 41339, 32333, 10547]", - "total_badness": 212080.25891 + "ne2d": 16290, + "ne3d": 174928, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 71, 256, 868, 2763, 7163, 15703, 26959, 37225, 41474, 32186, 10257]", + "total_badness": 211389.4278 } ], "trafo.geo": [ @@ -3079,13 +3156,13 @@ ], "angles_trig": [ 14.916, - 132.02 + 130.79 ], "ne1d": 690, - "ne2d": 1684, - "ne3d": 5178, - "quality_histogram": "[0, 0, 1, 0, 1, 8, 29, 37, 107, 193, 284, 368, 461, 566, 670, 689, 621, 536, 462, 145]", - "total_badness": 7465.8398023 + "ne2d": 1670, + "ne3d": 5169, + "quality_histogram": "[0, 0, 1, 0, 0, 8, 32, 37, 105, 200, 283, 367, 447, 560, 691, 707, 596, 539, 460, 136]", + "total_badness": 7461.9317917 }, { "angles_tet": [ @@ -3098,9 +3175,9 @@ ], "ne1d": 390, "ne2d": 522, - "ne3d": 1347, - "quality_histogram": "[0, 0, 4, 14, 14, 41, 75, 117, 125, 145, 169, 126, 140, 107, 82, 87, 54, 34, 11, 2]", - "total_badness": 2735.6699238 + "ne3d": 1351, + "quality_histogram": "[0, 0, 4, 10, 15, 42, 76, 120, 122, 145, 170, 128, 141, 108, 82, 86, 54, 35, 11, 2]", + "total_badness": 2733.6025132 }, { "angles_tet": [ @@ -3112,10 +3189,10 @@ 148.05 ], "ne1d": 512, - "ne2d": 874, - "ne3d": 2395, - "quality_histogram": "[0, 0, 0, 3, 9, 13, 42, 68, 129, 146, 191, 209, 315, 390, 343, 236, 134, 94, 49, 24]", - "total_badness": 3955.4970644 + "ne2d": 866, + "ne3d": 2357, + "quality_histogram": "[0, 0, 0, 3, 9, 15, 43, 72, 120, 149, 193, 201, 308, 384, 335, 230, 139, 84, 49, 23]", + "total_badness": 3906.7263127 }, { "angles_tet": [ @@ -3124,13 +3201,13 @@ ], "angles_trig": [ 14.916, - 132.02 + 130.79 ], "ne1d": 690, - "ne2d": 1684, - "ne3d": 5095, - "quality_histogram": "[0, 0, 1, 0, 0, 4, 19, 34, 101, 181, 263, 354, 439, 548, 689, 696, 611, 547, 467, 141]", - "total_badness": 7282.7477811 + "ne2d": 1670, + "ne3d": 5111, + "quality_histogram": "[0, 0, 1, 0, 0, 3, 21, 38, 107, 192, 269, 348, 432, 542, 664, 707, 611, 564, 471, 141]", + "total_badness": 7317.6330247 }, { "angles_tet": [ @@ -3142,25 +3219,25 @@ 126.69 ], "ne1d": 1050, - "ne2d": 3812, - "ne3d": 18028, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 3, 15, 34, 62, 183, 573, 1437, 2190, 2345, 2680, 2713, 2701, 2419, 673]", - "total_badness": 23515.317943 + "ne2d": 3784, + "ne3d": 17722, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 3, 14, 36, 67, 187, 548, 1407, 2109, 2399, 2596, 2679, 2730, 2285, 662]", + "total_badness": 23125.468501 }, { "angles_tet": [ - 15.34, - 149.41 + 15.321, + 149.42 ], "angles_trig": [ - 19.234, + 20.032, 129.78 ], "ne1d": 1722, - "ne2d": 10042, - "ne3d": 84906, - "quality_histogram": "[0, 0, 0, 0, 0, 2, 49, 1422, 720, 370, 704, 1186, 2437, 5535, 8984, 13266, 16409, 16882, 12872, 4068]", - "total_badness": 108652.77514 + "ne2d": 10022, + "ne3d": 85092, + "quality_histogram": "[0, 0, 0, 0, 0, 3, 50, 1423, 715, 400, 647, 1222, 2399, 5628, 9024, 13434, 16387, 16909, 12811, 4040]", + "total_badness": 108920.32258 } ], "twobricks.geo": [ @@ -3226,33 +3303,33 @@ }, { "angles_tet": [ - 24.085, - 131.06 + 22.355, + 137.97 ], "angles_trig": [ - 27.682, - 109.51 + 31.051, + 106.4 ], "ne1d": 116, - "ne2d": 134, - "ne3d": 176, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 11, 13, 17, 37, 23, 30, 17, 17, 7]", - "total_badness": 234.86129156 + "ne2d": 122, + "ne3d": 151, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 7, 10, 25, 9, 32, 28, 14, 11, 8, 4]", + "total_badness": 212.98760584 }, { "angles_tet": [ - 26.468, - 134.05 + 28.752, + 130.07 ], "angles_trig": [ - 27.418, - 109.77 + 25.5, + 109.19 ], "ne1d": 186, - "ne2d": 346, - "ne3d": 595, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 23, 40, 55, 95, 101, 105, 99, 60, 8]", - "total_badness": 777.63275434 + "ne2d": 334, + "ne3d": 596, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 21, 35, 49, 93, 105, 118, 99, 54, 17]", + "total_badness": 770.34262233 } ], "twocubes.geo": [ @@ -3318,33 +3395,33 @@ }, { "angles_tet": [ - 24.085, - 131.06 + 22.355, + 137.97 ], "angles_trig": [ - 27.682, - 109.51 + 31.051, + 106.4 ], "ne1d": 116, - "ne2d": 134, - "ne3d": 176, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 11, 13, 17, 37, 23, 30, 17, 17, 7]", - "total_badness": 234.86129156 + "ne2d": 122, + "ne3d": 151, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 7, 10, 25, 9, 32, 28, 14, 11, 8, 4]", + "total_badness": 212.98760584 }, { "angles_tet": [ - 26.468, - 134.05 + 28.752, + 130.07 ], "angles_trig": [ - 27.418, - 109.77 + 25.5, + 109.19 ], "ne1d": 186, - "ne2d": 346, - "ne3d": 595, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 23, 40, 55, 95, 101, 105, 99, 60, 8]", - "total_badness": 777.63275434 + "ne2d": 334, + "ne3d": 596, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 21, 35, 49, 93, 105, 118, 99, 54, 17]", + "total_badness": 770.34262233 } ], "twocyl.geo": [ @@ -3439,4 +3516,4 @@ "total_badness": 16428.083882 } ] -} \ No newline at end of file +} diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/tests/pytest/test_tutorials.py ngsolve-6.2.2103/external_dependencies/netgen/tests/pytest/test_tutorials.py --- ngsolve-6.2.2102/external_dependencies/netgen/tests/pytest/test_tutorials.py 2021-03-19 06:19:12.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/tests/pytest/test_tutorials.py 2021-06-04 23:36:22.000000000 +0000 @@ -63,12 +63,12 @@ standard = [MeshingParameters()] + [MeshingParameters(ms) for ms in (meshsize.very_coarse, meshsize.coarse, meshsize.moderate, meshsize.fine, meshsize.very_fine)] if filename == "shell.geo": return [] # do not test this example cause it needs so long... - if filename == "extrusion.geo": - return [] # this segfaults right now if filename == "manyholes2.geo": return [standard[1]] # this gets too big for finer meshsizes if filename in ("manyholes.geo", "frame.step"): return standard[:3] # this gets too big for finer meshsizes + if filename == "extrusion.geo": + return standard[:-1] if filename == "screw.step": return standard[3:] # coarser meshes don't work here if filename == "cylsphere.geo": @@ -142,7 +142,11 @@ continue meshdata = [] for mp in mps: - mesh = generateMesh(_file, mp) + try: + mesh = generateMesh(_file, mp) + except Exception as e: + print("Meshingparameters: ", mp) + raise e meshdata.append( getData(mesh, mp) ) data[_file] = meshdata print("needed", time.time() - start, "seconds") diff -Nru ngsolve-6.2.2102/external_dependencies/netgen/version.txt ngsolve-6.2.2103/external_dependencies/netgen/version.txt --- ngsolve-6.2.2102/external_dependencies/netgen/version.txt 2021-03-19 06:19:17.000000000 +0000 +++ ngsolve-6.2.2103/external_dependencies/netgen/version.txt 2021-06-04 23:37:12.000000000 +0000 @@ -1 +1 @@ -v6.2.2102-0-gab4359c3 +v6.2.2103-0-gca6d6e8c diff -Nru ngsolve-6.2.2102/fem/bdbequations.hpp ngsolve-6.2.2103/fem/bdbequations.hpp --- ngsolve-6.2.2102/fem/bdbequations.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/bdbequations.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -156,7 +156,8 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir); + shared_ptr dir, + bool Eulerian); }; @@ -214,7 +215,8 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir); + shared_ptr dir, + bool Eulerian); }; @@ -230,6 +232,10 @@ enum { DIM_DMAT = D }; enum { DIFFORDER = 1 }; + static string Name() { return "gradbboundary"; } + static constexpr bool SUPPORT_PML = true; + + static const FEL & Cast (const FiniteElement & fel) { return static_cast (fel); } @@ -447,7 +453,8 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir); + shared_ptr dir, + bool Eulerian); }; @@ -514,6 +521,9 @@ enum { DIM_ELEMENT = D-1 }; enum { DIM_DMAT = 1 }; enum { DIFFORDER = 0 }; + + static string Name() { return "IdBoundary"; } + static constexpr bool SUPPORT_PML = true; static INT<0> GetDimensions() { return INT<0>(); }; static const FEL & Cast (const FiniteElement & fel) @@ -1731,6 +1741,9 @@ enum { DIM_ELEMENT = DIM_SPC-VB }; enum { DIM_DMAT = DIM_SPC }; enum { DIFFORDER = 0 }; + + static string Name() { return "Id"; } + static constexpr bool SUPPORT_PML = true; static bool SupportsVB (VorB checkvb) { return true; } template @@ -1785,7 +1798,8 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir); + shared_ptr dir, + bool Eulerian); }; @@ -1804,9 +1818,10 @@ typedef DiffOpGradBoundaryVectorH1 DIFFOP_TRACE; + static string Name() { return "grad"; } + static constexpr bool SUPPORT_PML = true; static INT<2> GetDimensions() { return { DIM_SPC, DIM_SPC }; } - static string Name() { return "grad"; } template static void GenerateMatrix (const FEL & bfel, const MIP & mip, @@ -1881,7 +1896,8 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir); + shared_ptr dir, + bool Eulerian); }; @@ -1896,7 +1912,7 @@ enum { DIFFORDER = 1 }; static INT<2> GetDimensions() { return { DIM_SPC, DIM_SPC }; } - + static constexpr bool SUPPORT_PML = true; static string Name() { return "gradbnd"; } typedef void DIFFOP_TRACE; @@ -1966,7 +1982,8 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir); + shared_ptr dir, + bool Eulerian); }; @@ -1983,7 +2000,7 @@ enum { DIFFORDER = 1 }; typedef DiffOpDivBoundaryVectorH1 DIFFOP_TRACE; - + static constexpr bool SUPPORT_PML = true; static string Name() { return "div"; } template @@ -2030,6 +2047,7 @@ enum { DIM_DMAT = 1 }; enum { DIFFORDER = 1 }; + static constexpr bool SUPPORT_PML = true; static string Name() { return "divbnd"; } template diff -Nru ngsolve-6.2.2102/fem/code_generation.cpp ngsolve-6.2.2103/fem/code_generation.cpp --- ngsolve-6.2.2102/fem/code_generation.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/code_generation.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -57,11 +57,14 @@ cout << IM(3) << "linking..." << endl; tlink.Start(); #ifdef WIN32 - string slink = "cmd /C \"ngsld.bat /OUT:" + prefix+".dll " + object_files + "\""; + string slink = "cmd /C \"ngsld.bat /OUT:" + prefix+".dll " + object_files; + for (auto flag : link_flags) + slink += " "+flag; + slink += " \""; #else - string slink = "ngsld -shared " + object_files + " -o " + prefix + ".so -lngstd -lngbla -lngfem -lngcore"; - for (auto flag : link_flags) - slink += " "+flag; + string slink = "ngsld -shared " + object_files + " -o " + prefix + ".so -lngstd -lngbla -lngfem -lngcomp -lngcore"; + for (auto flag : link_flags) + slink += " "+flag; #endif int err = system(slink.c_str()); if (err) throw Exception ("problem calling linker"); diff -Nru ngsolve-6.2.2102/fem/coefficient.cpp ngsolve-6.2.2103/fem/coefficient.cpp --- ngsolve-6.2.2102/fem/coefficient.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/coefficient.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -157,7 +157,7 @@ { static bool firsttime = true; if (firsttime) - { + { cerr << "Eval1 not implemented for class " << typeid(*this).name() << endl; firsttime = false; } @@ -220,7 +220,7 @@ values = AutoDiffDiff<1,bool> (true); } - shared_ptr shape = make_shared(1); + // shared_ptr shape = make_shared(1); @@ -267,6 +267,7 @@ values.AddSize(ir.Size(), 1) = val; } + /* template void ConstantCoefficientFunction :: T_Evaluate (const MIR & ir, BareSliceMatrix values) const @@ -276,6 +277,7 @@ for (size_t i = 0; i < np; i++) values(0,i) = val; } + */ void ConstantCoefficientFunction :: GenerateCode(Code &code, FlatArray inputs, int index) const { @@ -1091,10 +1093,9 @@ virtual void GenerateCode(Code &code, FlatArray inputs, int index) const override { - FlatArray hdims = Dimensions(); - for (int i : Range(hdims[0])) - for (int j : Range(hdims[1])) + TraverseDimensions( Dimensions(), [&](int ind, int i, int j) { code.body += Var(index,i,j).Assign(string("0.0")); + }); } using T_CoefficientFunction::Evaluate; @@ -1661,7 +1662,7 @@ { auto in0 = input[0]; auto in1 = input[1]; - size_t dim = Dimension(); + size_t dim = dim1; size_t np = ir.Size(); for (size_t i = 0; i < np; i++) @@ -2654,13 +2655,15 @@ { auto dims_c1 = c1 -> Dimensions(); auto dims_c2 = c2 -> Dimensions(); - if (dims_c1.Size() != 2 || dims_c2.Size() != 1) + if (dims_c1.Size() < 2 || dims_c2.Size() != 1) throw Exception("Not a mat-vec multiplication"); - if (dims_c1[1] != dims_c2[0]) + if (dims_c1.Last() != dims_c2[0]) throw Exception(string ("Matrix dimensions don't fit: mat is ") + ToLiteral(dims_c1[0]) + " x " + ToLiteral(dims_c1[1]) + ", vec is " + ToLiteral(dims_c2[0])); - SetDimensions (ngstd::INT<1>(dims_c1[0])); - inner_dim = dims_c1[1]; + // SetDimensions (ngstd::INT<1>(dims_c1[0])); + // SetDimensions (dims_c1.Range(0, dims_c1.Size()-1)); // ngstd::INT<1>(dims_c1[0])); + SetDimensions (dims_c1.Range(0, END-1)); + inner_dim = dims_c1.Last(); // [1]; } void DoArchive(Archive& ar) override @@ -2725,14 +2728,14 @@ virtual void NonZeroPattern (const class ProxyUserData & ud, FlatVector> values) const override { - FlatArray hdims = Dimensions(); - Vector> va(hdims[0]*inner_dim), vb(inner_dim); + // FlatArray hdims = Dimensions(); + Vector> va(Dimension()*inner_dim), vb(inner_dim); c1->NonZeroPattern (ud, va); c2->NonZeroPattern (ud, vb); values = false; - for (size_t i = 0; i < hdims[0]; i++) + for (size_t i = 0; i < Dimension(); i++) for (size_t j = 0; j < inner_dim; j++) values(i) += va(i*inner_dim+j) * vb(j); } @@ -2744,10 +2747,10 @@ auto va = input[0]; auto vb = input[1]; - FlatArray hdims = Dimensions(); + // FlatArray hdims = Dimensions(); values = false; - for (size_t i = 0; i < hdims[0]; i++) + for (size_t i = 0; i < Dimension(); i++) for (size_t j = 0; j < inner_dim; j++) values(i) += va(i*inner_dim+j) * vb(j); } @@ -2757,6 +2760,7 @@ throw Exception ("MultMatVecCF:: scalar evaluate for matrix called"); } + /* virtual void Evaluate (const BaseMappedIntegrationPoint & ip, FlatVector<> result) const override { @@ -2787,20 +2791,21 @@ result = a * vb; //cout << "MultMatMat: complex not implemented" << endl; } - + */ template void T_Evaluate (const MIR & ir, BareSliceMatrix values) const { - FlatArray hdims = Dimensions(); - STACK_ARRAY(T, hmem1, ir.Size()*hdims[0]*inner_dim); + // FlatArray hdims = Dimensions(); + int dim = Dimension(); + STACK_ARRAY(T, hmem1, ir.Size()*dim*inner_dim); STACK_ARRAY(T, hmem2, ir.Size()*inner_dim); - FlatMatrix temp1(hdims[0]*inner_dim, ir.Size(), &hmem1[0]); + FlatMatrix temp1(dim*inner_dim, ir.Size(), &hmem1[0]); FlatMatrix temp2(inner_dim, ir.Size(), &hmem2[0]); c1->Evaluate (ir, temp1); c2->Evaluate (ir, temp2); values.AddSize(Dimension(),ir.Size()) = T(0.0); - for (size_t i = 0; i < hdims[0]; i++) + for (size_t i = 0; i < dim; i++) for (size_t j = 0; j < inner_dim; j++) for (size_t k = 0; k < ir.Size(); k++) values(i,k) += temp1(i*inner_dim+j, k) * temp2(j,k); @@ -2814,10 +2819,11 @@ auto va = input[0]; auto vb = input[1]; - FlatArray hdims = Dimensions(); + // FlatArray hdims = Dimensions(); + int dim = Dimension(); values.AddSize(Dimension(),ir.Size()) = T(0.0); - for (size_t i = 0; i < hdims[0]; i++) + for (size_t i = 0; i < dim; i++) for (size_t j = 0; j < inner_dim; j++) for (size_t k = 0; k < ir.Size(); k++) values(i,k) += va(i*inner_dim+j, k) * vb(j,k); @@ -3689,7 +3695,7 @@ //Cofactor Matrix linear in 2d (in 1d Cofactor Matrix = 0) return CofactorCF(c1->Diff(var,dir)); } - else //3d + else if (this->Dimensions()[0] == 3) //3d { //formula follows from Cayley–Hamilton //Cof(A) = 0.5*(tr(A)**2 - tr(A**2))I - tr(A)A^T +(AA)^T @@ -3697,6 +3703,8 @@ //return (0.5*(TraceCF(c1)*TraceCF(c1) - TraceCF(c1*c1))*IdentityCF(3) - TraceCF(c1)*TransposeCF(c1) + TransposeCF(c1*c1))->Diff(var,dir); return 0.5*(2*TraceCF(c1)*TraceCF(c1->Diff(var,dir)) - TraceCF(c1->Diff(var,dir)*c1 + c1 * c1->Diff(var,dir)))*IdentityCF(3)- TraceCF(c1->Diff(var,dir))*TransposeCF(c1) - TraceCF(c1)*TransposeCF(c1->Diff(var,dir)) + TransposeCF(c1->Diff(var,dir)*c1 + c1 * c1->Diff(var,dir)); } + else + throw Exception("CofactorCF diff only implemented for dim <=3"); } }; @@ -4286,7 +4294,7 @@ } if (c1->Dimensions().Size() == 2 && c2->Dimensions().Size() == 2) return make_shared (c1, c2); - if (c1->Dimensions().Size() == 2 && c2->Dimensions().Size() == 1) + if (c1->Dimensions().Size() >= 2 && c2->Dimensions().Size() == 1) return make_shared (c1, c2); if (c1->Dimension() > 1 && c2->Dimension() > 1) { @@ -4510,6 +4518,7 @@ case 1: return make_shared> (coef); case 2: return make_shared> (coef); case 3: return make_shared> (coef); + case 4: return make_shared> (coef); default: throw Exception("Cofactor of matrix of size "+ToString(dims[0]) + " not available"); } @@ -4706,6 +4715,198 @@ } +// ********************** SubTensorCoefficientFunction ********************** + + +class SubTensorCoefficientFunction : public T_CoefficientFunction +{ + shared_ptr c1; + int dim1; + int first; + Array num, dist; + typedef T_CoefficientFunction BASE; +public: + SubTensorCoefficientFunction() = default; + SubTensorCoefficientFunction (shared_ptr ac1, + int afirst, Array anum, Array adist) + : BASE(1, ac1->IsComplex()), c1(ac1), first(afirst), num(anum), dist(adist) + { + SetDimensions(anum); + dim1 = c1->Dimension(); + elementwise_constant = c1->ElementwiseConstant(); + } + + void DoArchive(Archive& ar) override + { + BASE::DoArchive(ar); + ar.Shallow(c1) & dim1 & first & num & dist; + } + + virtual void GenerateCode(Code &code, FlatArray inputs, int index) const override + { + auto dims1 = c1->Dimensions(); + + if(num.Size()==1) + { + for (int i = 0; i < num[0]; i++) + { + int i1,k1; + auto comp = first+i*dist[0]; + GetIndex(dims1, comp, i1, k1); + code.body += Var(index, i).Assign( Var(inputs[0], i1, k1 )); + } + } + + if(num.Size()==2) + { + for (int i = 0; i < num[0]; i++) + for (int j = 0; j < num[1]; j++) + { + int i1,j1; + auto comp = first+i*dist[0]+j*dist[1]; + GetIndex(dims1, comp, i1, j1); + code.body += Var(index, i, j).Assign( Var(inputs[0], i1, j1 )); + } + } + } + + virtual void TraverseTree (const function & func) override + { + c1->TraverseTree (func); + func(*this); + } + + virtual Array> InputCoefficientFunctions() const override + { return Array>({ c1 }); } + + + using BASE::Evaluate; + + /* + virtual void Evaluate (const BaseMappedIntegrationRule & ir, + BareSliceMatrix result) const override + { + // int dim1 = c1->Dimension(); + STACK_ARRAY(double, hmem, 2*ir.Size()*dim1); + FlatMatrix temp(ir.Size(), dim1, (Complex*)hmem); + c1->Evaluate (ir, temp); + result.Col(0).Range(0,ir.Size()) = temp.Col(comp); + } + */ + + + template + void T_Evaluate (const MIR & ir, BareSliceMatrix values) const + { + STACK_ARRAY(T, hmem, ir.Size()*dim1); + FlatMatrix temp(dim1, ir.Size(), &hmem[0]); + + c1->Evaluate (ir, temp); + size_t nv = ir.Size(); + switch (num.Size()) + { + case 1: + for (int i = 0; i < num[0]; i++) + for (size_t k = 0; k < nv; k++) + values(i,k) = temp(first+i*dist[0], k); + break; + case 2: + for (int i = 0, ii = 0; i < num[0]; i++) + for (int j = 0; j < num[1]; j++, ii++) + for (size_t k = 0; k < nv; k++) + values(ii,k) = temp(first+i*dist[0]+j*dist[1], k); + break; + + default: + throw Exception("subtensor of order "+ToString(num.Size())+" not supported"); + } + } + + template + void T_Evaluate (const MIR & ir, + FlatArray> input, + BareSliceMatrix values) const + { + auto in0 = input[0]; + switch (num.Size()) + { + case 1: + for (int i = 0; i < num[0]; i++) + values.Row(i).Range(ir.Size()) = in0.Row(first+i*dist[0]); + break; + case 2: + for (int i = 0, ii = 0; i < num[0]; i++) + for (int j = 0; j < num[1]; j++, ii++) + values.Row(ii).Range(ir.Size()) = in0.Row(first+i*dist[0]+j*dist[1]); + break; + + default: + throw Exception("subtensor of order "+ToString(num.Size())+" not supported"); + } + } + + shared_ptr Diff (const CoefficientFunction * var, + shared_ptr dir) const override + { + if (this == var) return dir; + return MakeSubTensorCoefficientFunction (c1->Diff(var, dir), first, Array (num), Array (dist)); + } + + virtual void NonZeroPattern (const class ProxyUserData & ud, + FlatVector> values) const override + { + Vector> v1(c1->Dimension()); + c1->NonZeroPattern (ud, v1); + switch (num.Size()) + { + case 1: + for (int i = 0; i < num[0]; i++) + values(i) = v1(first+i*dist[0]); + break; + case 2: + for (int i = 0, ii = 0; i < num[0]; i++) + for (int j = 0; j < num[1]; j++, ii++) + values(ii) = v1(first+i*dist[0]+j*dist[1]); + break; + + default: + throw Exception("subtensor of order "+ToString(num.Size())+" not supported"); + } + } + + virtual void NonZeroPattern (const class ProxyUserData & ud, + FlatArray>> input, + FlatVector> values) const override + { + c1->NonZeroPattern (ud, values); + switch (num.Size()) + { + case 1: + for (int i = 0; i < num[0]; i++) + values(i) = values(first+i*dist[0]); + break; + case 2: + for (int i = 0, ii = 0; i < num[0]; i++) + for (int j = 0; j < num[1]; j++, ii++) + values(ii) = values(first+i*dist[0]+j*dist[1]); + break; + default: + throw Exception("subtensor of order "+ToString(num.Size())+" not supported"); + } + + } +}; + +shared_ptr +MakeSubTensorCoefficientFunction (shared_ptr c1, int first, Array num, Array dist) +{ + return make_shared (c1, first, move(num), move(dist)); +} + + + + + // ************************ DomainWiseCoefficientFunction ************************************* @@ -5090,6 +5291,10 @@ return make_shared (me); } +bool IsOtherCoefficientFunction (CoefficientFunction & coef) +{ + return (dynamic_cast (&coef) != nullptr); +} @@ -5523,6 +5728,8 @@ shared_ptr cf_then, shared_ptr cf_else) { + if(cf_if->Dimension() != 1) + throw Exception("Dimension of first component in IfPos must be 1!"); return make_shared (cf_if, cf_then, cf_else); } @@ -5875,7 +6082,7 @@ throw Exception ("cannot apply operator "+name+" for coordinate"); Array> funcs(spacedim); - funcs = make_shared (0); + funcs = ZeroCF(Array()); funcs[dir] = make_shared (1); return MakeVectorialCoefficientFunction (move(funcs)); } @@ -5885,7 +6092,8 @@ shared_ptr Diff (const CoefficientFunction * var, shared_ptr dirdiff) const override { - if (var == shape.get()) + // if (var == shape.get()) + if (dynamic_cast(var)) return MakeComponentCoefficientFunction (dirdiff, dir); // return BASE::Diff (var, dirdiff); @@ -6307,7 +6515,8 @@ void TraverseTree (const function & func) override { cf -> TraverseTree (func); - func(*cf); + // func(*cf); + func(*this); } // virtual bool IsComplex() const { return cf->IsComplex(); } @@ -6927,7 +7136,14 @@ void GenerateCode(Code &code, FlatArray inputs, int index) const override { - return cf->GenerateCode(code, inputs, index); + TraverseDimensions( cf->Dimensions(), [&](int ind, int i, int j) { + code.body += Var(index,i,j).Assign( Var(inputs[0],i,j).S() ); + }); + } + + virtual Array> InputCoefficientFunctions() const override + { + return Array>({ cf }); } }; @@ -7117,7 +7333,8 @@ shared_ptr Compile (shared_ptr c, bool realcompile, int maxderiv, bool wait) { - auto cf = make_shared (c); + auto compiledcf = dynamic_pointer_cast(c); + auto cf = compiledcf ? compiledcf : make_shared (c); if(realcompile) cf->RealCompile(maxderiv, wait); return cf; @@ -7348,7 +7565,7 @@ } -void PrecomputeCacheCF (Array & cachecfs, BaseMappedIntegrationRule & mir, +void PrecomputeCacheCF (const Array & cachecfs, BaseMappedIntegrationRule & mir, LocalHeap & lh) { // static Timer t("Precompute CacheCF"); @@ -7383,7 +7600,7 @@ -void PrecomputeCacheCF (Array & cachecfs, SIMD_BaseMappedIntegrationRule & mir, +void PrecomputeCacheCF (const Array & cachecfs, SIMD_BaseMappedIntegrationRule & mir, LocalHeap & lh) { auto & trafo = mir.GetTransformation(); diff -Nru ngsolve-6.2.2102/fem/coefficient_geo.cpp ngsolve-6.2.2103/fem/coefficient_geo.cpp --- ngsolve-6.2.2102/fem/coefficient_geo.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/coefficient_geo.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -157,7 +157,8 @@ virtual shared_ptr Diff (const CoefficientFunction * var, shared_ptr dir) const override { - if (var == shape.get()) + // if (var == shape.get()) + if (dynamic_cast(var)) return -TransposeCF(dir->Operator("Gradboundary")) * const_cast(this)->shared_from_this(); return CoefficientFunctionNoDerivative::Diff(var, dir); } @@ -252,7 +253,8 @@ Diff (const CoefficientFunction * var, shared_ptr dir) const override { //d/dt tang|t=0 = dX*tang - ((dX*tang)*tang)*tang - if (var == shape.get()) + // if (var == shape.get()) + if (dynamic_cast(var)) return dir->Operator("Gradboundary") * const_cast(this)->shared_from_this() - InnerProduct(dir->Operator("Gradboundary")*const_cast(this)->shared_from_this(),const_cast(this)->shared_from_this())*const_cast(this)->shared_from_this(); return CoefficientFunctionNoDerivative::Diff(var, dir); } @@ -311,7 +313,8 @@ virtual shared_ptr Diff (const CoefficientFunction * var, shared_ptr dir) const override { - if (var == shape.get()) + // if (var == shape.get()) + if (dynamic_cast(var)) throw Exception("Shape derivative not implemented yet for JacobianMatrixCF"); return CoefficientFunctionNoDerivative::Diff(var, dir); } @@ -449,7 +452,8 @@ virtual shared_ptr Diff (const CoefficientFunction * var, shared_ptr dir) const override { - if (var == shape.get()) + // if (var == shape.get()) + if (dynamic_cast(var)) { int dim = dir->Dimension(); auto n = NormalVectorCF(dim); @@ -496,6 +500,7 @@ SetDimensions(Array ( { D, 2 } )); } + using CoefficientFunctionNoDerivative::Evaluate; virtual double Evaluate (const BaseMappedIntegrationPoint & ip) const override { return 0; @@ -511,9 +516,9 @@ if (ip.IP().VB() == BBND) { auto F = ip.GetJacobian(); - auto & trafo = ip.GetTransformation(); + // auto & trafo = ip.GetTransformation(); int vnr = ip.IP().FacetNr(); - auto pnt = ip.IP().Point(); + // auto pnt = ip.IP().Point(); //ELEMENT_TYPE et = trafo.GetElementType(); //int iavnums[] = { 0, 1, 2, 3 }; //FlatArray vnums(4, &iavnums[0]); @@ -529,7 +534,7 @@ Vec<2> tv_ref_v [] = { -tv_ref[0], tv_ref[2], -tv_ref[2], -tv_ref[1], tv_ref[1], tv_ref[0] }; FlatMatrix phys_tv(D,2,&res[0]); - Vec<3> tmp = F*tv_ref_v[2*vnr+0]; + Vec tmp = F*tv_ref_v[2*vnr+0]; phys_tv.Col(0) = 1/L2Norm(tmp)*tmp; tmp = F*tv_ref_v[2*vnr+1]; phys_tv.Col(1) = 1/L2Norm(tmp)*tmp; @@ -559,6 +564,112 @@ } + + + + template + class cl_EdgeFaceTangentialVectorsCF : public CoefficientFunctionNoDerivative + { + public: + cl_EdgeFaceTangentialVectorsCF () : CoefficientFunctionNoDerivative(2*D,false) + { + SetDimensions(Array ( { D, 2 } )); + } + + using CoefficientFunctionNoDerivative::Evaluate; + virtual double Evaluate (const BaseMappedIntegrationPoint & ip) const override + { + return 0; + } + + virtual void Evaluate (const BaseMappedIntegrationPoint & ip, FlatVector<> res) const override + { + if (ip.DimSpace() != D) + throw Exception("illegal dim of EdgeFaceTangentialVector"); + + //cout << "in EdgeFaceTangentialVectorsCF, VB = " << ip.IP().VB() << endl; + // assume tets !!! + + if (ip.IP().VB() == BBND) + { + auto F = ip.GetJacobian(); + int edgenr = ip.IP().FacetNr(); + + /* + edge -> vertex is + static const int tet_edges[6][2] = + { { 3, 0 }, + { 3, 1 }, + { 3, 2 }, + { 0, 1 }, + { 0, 2 }, + { 1, 2 }}; + + face -> vertex is + { { 3, 1, 2, -1 }, + { 3, 2, 0, -1 }, + { 3, 0, 1, -1 }, + { 0, 2, 1, -1 } }; // all faces point into interior! + + from this we get edge -> face + */ + static int edge2face[6][2] = + { { 1, 2 }, + { 0, 2 }, + { 0, 1 }, + { 2, 3 }, + { 1, 3 }, + { 0, 3 } + }; + + + FlatVector> normals = ElementTopology::GetNormals<3>(ET_TET); + const EDGE * edge = ElementTopology::GetEdges(ET_TET) + edgenr; + auto [v1x, v1y, v1z] = ElementTopology::GetVertices(ET_TET)[(*edge)[0]]; + Vec<3> v1(v1x, v1y, v1z); + auto [v2x, v2y, v2z] = ElementTopology::GetVertices(ET_TET)[(*edge)[1]]; + Vec<3> v2(v2x, v2y, v2z); + + Vec<3> nref1 = normals[edge2face[edgenr][0]]; + Vec<3> nref2 = normals[edge2face[edgenr][1]]; + Vec<3> tref = v2-v1; + + Vec<3> tref1 = Cross(tref, nref1); + Vec<3> tref2 = -Cross(tref, nref2); + + Vec<3> t1 = F * tref1; + Vec<3> t2 = F * tref2; + Vec<3> t = F * tref; + + t /= L2Norm(t); + t1 -= InnerProduct(t1,t)*t; + t2 -= InnerProduct(t2,t)*t; + + t1 /= L2Norm(t1); + t2 /= L2Norm(t2); + + FlatMatrix phys_tv(D,2,&res[0]); + phys_tv.Col(0) = t1; + phys_tv.Col(1) = t2; + } + else + throw Exception("EdgeFaceTangentialVector only makes sense on edges"); + } + + }; + + + shared_ptr EdgeFaceTangentialVectorsCF (int dim) + { + if (dim == 3) + return make_shared>(); + throw Exception ("EdgeFaceTangentialVectors available only in 3D"); + } + + + + + template class cl_EdgeCurvatureCF : public CoefficientFunctionNoDerivative @@ -566,6 +677,7 @@ public: cl_EdgeCurvatureCF () : CoefficientFunctionNoDerivative(D,false) { ; } + using CoefficientFunctionNoDerivative :: Evaluate; virtual double Evaluate (const BaseMappedIntegrationPoint & ip) const override { return 0; @@ -577,10 +689,10 @@ throw Exception("illegal dim of EdgeCurvatureCF"); - // (nabla_t t)circ\phi = Ptau\circ\phi*nabla(t\circ\phi) F^-1 t\circ\phi - // = Ptau\circ\phi*nabla(t\circ\phi) F^-1 1/|F t_ref| F t_ref - // = 1/|F t_ref| * Ptau\circ\phi*nabla(t\circ\phi) t_ref - // = 1/|F t_ref| * F(F^TF)^-1F^T * nabla(t\circ\phi) t_ref + // (nabla_t t)circ\phi = nabla(t\circ\phi) F^-1 t\circ\phi + // = nabla(t\circ\phi) F^-1 1/|F t_ref| F t_ref + // = 1/|F t_ref|*nabla(t\circ\phi) t_ref + // = 1/|F t_ref|*nabla(t\circ\phi) t_ref if (bmip.IP().VB() == BND) @@ -604,7 +716,7 @@ tv_ref /= L2Norm(tv_ref); // compute |F t_ref| - Vec<3> tv_phys = F*tv_ref; + Vec tv_phys = F*tv_ref; double measure = L2Norm(tv_phys); // compute nabla(t\circ\phi) t_ref numerically @@ -623,13 +735,13 @@ iprr(0) += 2*tv_ref[0]*eps; iprr(1) += 2*tv_ref[1]*eps; - MappedIntegrationPoint sipl(ipl, eltrans); - MappedIntegrationPoint sipr(ipr, eltrans); - MappedIntegrationPoint sipll(ipll, eltrans); - MappedIntegrationPoint siprr(iprr, eltrans); + MappedIntegrationPoint<2,D> sipl(ipl, eltrans); + MappedIntegrationPoint<2,D> sipr(ipr, eltrans); + MappedIntegrationPoint<2,D> sipll(ipll, eltrans); + MappedIntegrationPoint<2,D> siprr(iprr, eltrans); // Need unit tangent vectors at the stencil points, not directly computed in MappedIntegrationPoint - Mat<3,2> Ft = sipr.GetJacobian(); + Mat Ft = sipr.GetJacobian(); Vec tangr = Ft*tv_ref; tangr /= L2Norm(tangr); Ft = sipl.GetJacobian(); @@ -644,16 +756,9 @@ // nabla(t\circ\phi) t_ref dshape = (1.0/(12.0*eps)) * (8.0*tangr-8.0*tangl-tangrr+tangll); + - // Ptau\circ\phi = F(F^TF)^-1F^T = (I - nsurf\circ\phi \otimes nsurf\circ\phi) - Mat Ptau=0; - for (int i=0; i < D; i++) - { - Ptau(i,i) = 1.0; - Ptau.Col(i) -= mip.GetNV()[i]*mip.GetNV(); - } - - res = 1/measure*Ptau*dshape; + res = 1/measure*dshape; } else //throw Exception(); res = 0.0; diff -Nru ngsolve-6.2.2102/fem/coefficient.hpp ngsolve-6.2.2103/fem/coefficient.hpp --- ngsolve-6.2.2102/fem/coefficient.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/coefficient.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -245,9 +245,7 @@ }; - - extern shared_ptr shape; // for shape derivative - + inline ostream & operator<< (ostream & ost, const CoefficientFunction & cf) { cf.PrintReport (ost); @@ -484,6 +482,12 @@ virtual void Evaluate (const BaseMappedIntegrationRule & ir, BareSliceMatrix values) const override { static_cast(this) -> /* template */ T_Evaluate (ir, Trans(values)); } + + virtual void Evaluate (const BaseMappedIntegrationRule & ir, + FlatArray> input, + BareSliceMatrix values) const override + { static_cast(this) -> T_Evaluate (ir, input, values); } + virtual void Evaluate (const BaseMappedIntegrationRule & ir, BareSliceMatrix values) const override { static_cast(this) -> /* template */ T_Evaluate (ir, Trans(values)); } @@ -565,7 +569,14 @@ virtual void Evaluate (const BaseMappedIntegrationRule & ir, BareSliceMatrix values) const override; template - void T_Evaluate (const MIR & ir, BareSliceMatrix values) const; + void T_Evaluate (const MIR & ir, BareSliceMatrix values) const + { + size_t np = ir.Size(); + __assume (np > 0); + for (size_t i = 0; i < np; i++) + values(0,i) = val; + } + template void T_Evaluate (const MIR & ir, FlatArray> input, @@ -1674,6 +1685,22 @@ } }; + + + // extern shared_ptr shape; // for shape derivative + // information howto treat GridFunctions (and maybe other stuff) for shape-derivatives + class DiffShapeCF : public ConstantCoefficientFunction + { + public: + DiffShapeCF() : ConstantCoefficientFunction(1) { } + Array Eulerian_gridfunctions; + }; + + + + + + template INLINE shared_ptr BinaryOpCF(shared_ptr c1, shared_ptr c2, @@ -1693,12 +1720,17 @@ MakeVectorialCoefficientFunction (Array> aci); NGS_DLL_HEADER shared_ptr + MakeSubTensorCoefficientFunction (shared_ptr c1, + int first, Array num, Array dist); + + + NGS_DLL_HEADER shared_ptr MakeCoordinateCoefficientFunction (int comp); // for DG jump terms NGS_DLL_HEADER shared_ptr MakeOtherCoefficientFunction (shared_ptr me); - + NGS_DLL_HEADER bool IsOtherCoefficientFunction (CoefficientFunction & coef); NGS_DLL_HEADER shared_ptr @@ -1790,8 +1822,30 @@ shared_ptr Freeze (shared_ptr cf); NGS_DLL_HEADER shared_ptr - CreateMinimizationCF (shared_ptr expression, - shared_ptr startingpoint); + CreateMinimizationCF(shared_ptr expression, + shared_ptr startingpoint, + std::optional atol, std::optional rtol, + std::optional maxiter); + + NGS_DLL_HEADER shared_ptr + CreateMinimizationCF(shared_ptr expression, + const Array> &startingpoints, + std::optional tol, std::optional rtol, + std::optional maxiter); + + NGS_DLL_HEADER shared_ptr + CreateNewtonCF (shared_ptr expression, + shared_ptr startingpoint, + std::optional atol, + std::optional rtol, + std::optional maxiter); + + NGS_DLL_HEADER shared_ptr + CreateNewtonCF (shared_ptr expression, + const Array> &startingpoints, + std::optional tol, + std::optional rtol, + std::optional maxiter); NGS_DLL_HEADER shared_ptr Compile (shared_ptr c, bool realcompile=false, int maxderiv=2, bool wait=false); @@ -1808,10 +1862,10 @@ NGS_DLL_HEADER Array FindCacheCF (CoefficientFunction & func); NGS_DLL_HEADER - void PrecomputeCacheCF (Array & cachecfs, BaseMappedIntegrationRule & mir, + void PrecomputeCacheCF (const Array & cachecfs, BaseMappedIntegrationRule & mir, LocalHeap & lh); NGS_DLL_HEADER - void PrecomputeCacheCF (Array & cachecfs, SIMD_BaseMappedIntegrationRule & mir, + void PrecomputeCacheCF (const Array & cachecfs, SIMD_BaseMappedIntegrationRule & mir, LocalHeap & lh); @@ -1826,6 +1880,8 @@ NGS_DLL_HEADER shared_ptr VertexTangentialVectorsCF (int dim); NGS_DLL_HEADER + shared_ptr EdgeFaceTangentialVectorsCF (int dim); + NGS_DLL_HEADER shared_ptr EdgeCurvatureCF (int dim); template diff -Nru ngsolve-6.2.2102/fem/diffop.cpp ngsolve-6.2.2103/fem/diffop.cpp --- ngsolve-6.2.2102/fem/diffop.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/diffop.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -596,11 +596,12 @@ shared_ptr BlockDifferentialOperator :: DiffShape (shared_ptr proxy, - shared_ptr dir) const + shared_ptr dir, + bool Eulerian) const { // assume it's a grad ... // return (-1)*dir->Operator("grad") * proxy; - return diffop->DiffShape(proxy, dir); + return diffop->DiffShape(proxy, dir, Eulerian); } @@ -809,9 +810,10 @@ shared_ptr BlockDifferentialOperatorTrans :: DiffShape (shared_ptr proxy, - shared_ptr dir) const + shared_ptr dir, + bool Eulerian) const { - return TransposeCF (diffop->DiffShape(TransposeCF(proxy), dir)); + return TransposeCF (diffop->DiffShape(TransposeCF(proxy), dir, Eulerian)); } @@ -963,10 +965,11 @@ diffop->AddTrans(fel, mir, flux.Rows(k*dimi, (k+1)*dimi), x.Range(k*ndi, (k+1)*ndi)); } - + shared_ptr VectorDifferentialOperator :: DiffShape (shared_ptr proxy, - shared_ptr dir) const + shared_ptr dir, + bool Eulerian) const { int ddim = diffop->Dim(); Array> proxys(dim); @@ -981,7 +984,7 @@ Array> cflist(dim); for (int i = 0; i < dim; i++) - cflist[i] = diffop->DiffShape(proxys[i], dir); + cflist[i] = diffop->DiffShape(proxys[i], dir, Eulerian); auto result = MakeVectorialCoefficientFunction(move(cflist)); result->SetDimensions( Array({dim,diffop->Dim()}) ); @@ -1064,6 +1067,7 @@ mat.Row(i*vdim+j).Range(ii*ndi, (ii+1)*ndi) = mat.Row(0).Range(ndi); mat.Row(j*vdim+i).Range(ii*ndi, (ii+1)*ndi) = mat.Row(0).Range(ndi); } + // cout << "symmat, bmat = " << mat << endl; } void SymMatrixDifferentialOperator :: @@ -1080,6 +1084,8 @@ diffop->CalcMatrix (fel, mip, mat.Rows(dimi).Cols(ndi), lh); for (int i = 1; i < VSDim(); i++) mat.Rows(i*dimi, (i+1)*dimi).Cols(i*ndi, (i+1)*ndi) = mat.Rows(dimi).Cols(ndi); + + // cout << "symmat, bmat vs = " << mat << endl; } void SymMatrixDifferentialOperator :: @@ -1108,7 +1114,8 @@ tens(ii,STAR,vdim*i+j,STAR) = smat; tens(ii,STAR,vdim*j+i,STAR) = smat; } - // throw ExceptionNOSIMD("VectorDifferentialOperator::CalcMatrix not yet tested for SIMD support"); + + // cout << "symmat, SIMD bmat tensor = " << tens << endl; } @@ -1134,6 +1141,7 @@ flux.Row(j*vdim+i).Range(0, mir.Size()) = hflux.Row(ii); } + // cout << "symmat, apply, x = " << x.Range(bfel.GetNDof()) << ", y = " << flux.AddSize(vdim*vdim, mir.Size()) << endl; } @@ -1156,15 +1164,192 @@ for (int j = 0; j <= i; j++, ii++) { hflux.Row(ii) += flux.Row(i*vdim+j).Range(0, mir.Size()); + if (i != j) + hflux.Row(ii) += flux.Row(j*vdim+i).Range(0, mir.Size()); + } + + for (int k = 0; k < hflux.Height(); k++) + diffop->AddTrans(fel, mir, hflux.Rows(k,k+1), y.Range(k*ndi, (k+1)*ndi)); + } + + + + + + SymDevMatrixDifferentialOperator :: + SymDevMatrixDifferentialOperator (shared_ptr adiffop, + int avdim) + : DifferentialOperator(sqr(avdim)*adiffop->Dim(), adiffop->BlockDim(), + adiffop->VB(), adiffop->DiffOrder()), + diffop(adiffop), vdim(avdim) + { + if (adiffop->Dimensions().Size() == 0) + { + SetDimensions ( { avdim, avdim } ); + Matrix<> vsembedding(sqr(vdim), vdim*(vdim+1)/2-1); + vsembedding = 0.0; + for (int i = 0, ii = 0; i < vdim; i++) + for (int j = 0; j <= i; j++, ii++) + if (ii < vsembedding.Width()) + { + vsembedding(i*vdim+j, ii) = 1; + vsembedding(j*vdim+i, ii) = 1; + } + for (int i = 0; i < vdim-1; i++) + vsembedding.Row(vdim*vdim-1) -= vsembedding.Row(i*(vdim+1)); + cout << "SymDev vsembedding = " << vsembedding << endl; + SetVectorSpaceEmbedding(vsembedding); + } + else + throw Exception("no matrix-valued of vector-valued possible"); + } + + + SymDevMatrixDifferentialOperator :: ~SymDevMatrixDifferentialOperator () { ; } + + + void SymDevMatrixDifferentialOperator :: + CalcMatrix (const FiniteElement & bfel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const + { + auto & fel = static_cast (bfel).ScalFE(); + + size_t ndi = fel.GetNDof(); + size_t dimi = 1; // diffop->Dim(); + + mat = 0.0; + diffop->CalcMatrix (fel, mip, mat.Rows(dimi).Cols(ndi), lh); + for (int i = 0, ii = 0; i < vdim; i++) + for (int j = 0; j <= i; j++, ii++) + if (ii != 0) + { + if (j+1 < vdim) + { + mat.Row(i*vdim+j).Range(ii*ndi, (ii+1)*ndi) = mat.Row(0).Range(ndi); + mat.Row(j*vdim+i).Range(ii*ndi, (ii+1)*ndi) = mat.Row(0).Range(ndi); + } + else + { + for (int k = 0; k < vdim-1; k++) + mat.Row(i*vdim+j) -= mat.Row(k*(vdim+1)); + } + } + + /* + cout << "CalcMatrix, mat = " << endl << mat << endl; + Matrix hmat( (*GetVSEmbedding()).Height(), mat.Width()); + + CalcMatrixVS (bfel, mip, hmat, lh); + Matrix<> m2 = (*GetVSEmbedding()) * hmat; + cout << "m2 = " << m2 << endl; + cout << "DIFF = " << L2Norm(m2-mat) << endl; + */ + } + + void SymDevMatrixDifferentialOperator :: + CalcMatrixVS (const FiniteElement & bfel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const + { + auto & fel = static_cast (bfel).ScalFE(); + size_t ndi = fel.GetNDof(); + size_t dimi = 1; // diffop->Dim(); + + mat = 0.0; + diffop->CalcMatrix (fel, mip, mat.Rows(dimi).Cols(ndi), lh); + for (int i = 1; i < VSDim(); i++) + mat.Rows(i*dimi, (i+1)*dimi).Cols(i*ndi, (i+1)*ndi) = mat.Rows(dimi).Cols(ndi); + } + + /* + void SymDevMatrixDifferentialOperator :: + CalcMatrix (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & mir, + BareSliceMatrix> bmat) const + { + auto & fel = static_cast (bfel); + auto & feli = fel.ScalFE(); + + size_t ndi = feli.GetNDof(); + // size_t dimi = diffop->Dim(); + + auto mat = bmat.AddSize(sqr(vdim)*bfel.GetNDof(), mir.Size()); + mat = 0.0; + + STACK_ARRAY(SIMD, mem, ndi*mir.Size()); + FlatMatrix> smat(ndi, mir.Size(), &mem[0]); + + diffop->CalcMatrix (feli, mir, smat); + FlatTensor<4,SIMD> tens(vdim*(vdim+1)/2, ndi, sqr(vdim), mir.Size(), bmat.Data()); + + for (int i = 0, ii = 0; i < vdim; i++) + for (int j = 0; j <= i; j++, ii++) + { + tens(ii,STAR,vdim*i+j,STAR) = smat; + tens(ii,STAR,vdim*j+i,STAR) = smat; + } + // throw ExceptionNOSIMD("VectorDifferentialOperator::CalcMatrix not yet tested for SIMD support"); + } + + + void SymDevMatrixDifferentialOperator :: + Apply (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & mir, + BareSliceVector x, + BareSliceMatrix> flux) const + { + auto & fel = static_cast (bfel).ScalFE(); + size_t ndi = fel.GetNDof(); + + STACK_ARRAY(SIMD, mem, vdim*(vdim+1)/2*mir.Size()); + FlatMatrix> hflux(vdim*(vdim+1)/2, mir.Size(), &mem[0]); + + for (int k = 0; k < hflux.Height(); k++) + diffop->Apply(fel, mir, x.Range(k*ndi, (k+1)*ndi), hflux.Rows(k,k+1)); + + for (int i = 0, ii = 0; i < vdim; i++) + for (int j = 0; j <= i; j++, ii++) + { + flux.Row(i*vdim+j).Range(0, mir.Size()) = hflux.Row(ii); + flux.Row(j*vdim+i).Range(0, mir.Size()) = hflux.Row(ii); + } + + } + + + + void SymDevMatrixDifferentialOperator :: + AddTrans (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & mir, + BareSliceMatrix> flux, + BareSliceVector y) const + { + auto & fel = static_cast (bfel).ScalFE(); + size_t ndi = fel.GetNDof(); + + STACK_ARRAY(SIMD, mem, vdim*(vdim+1)/2*mir.Size()); + FlatMatrix> hflux(vdim*(vdim+1)/2, mir.Size(), &mem[0]); + + hflux = SIMD (0.0); + + for (int i = 0, ii = 0; i < vdim; i++) + for (int j = 0; j <= i; j++, ii++) + { + hflux.Row(ii) += flux.Row(i*vdim+j).Range(0, mir.Size()); hflux.Row(ii) += flux.Row(j*vdim+i).Range(0, mir.Size()); } for (int k = 0; k < hflux.Height(); k++) diffop->AddTrans(fel, mir, hflux.Rows(k,k+1), y.Range(k*ndi, (k+1)*ndi)); } + */ + /* diff -Nru ngsolve-6.2.2102/fem/diffop_grad.cpp ngsolve-6.2.2103/fem/diffop_grad.cpp --- ngsolve-6.2.2102/fem/diffop_grad.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/diffop_grad.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -8,8 +8,10 @@ template shared_ptr DiffOpGradient :: DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpGradient"); return -TransposeCF(dir->Operator("Grad")) * proxy; // return -dir->Operator("grad") * proxy; } @@ -17,8 +19,10 @@ template shared_ptr DiffOpGradientBoundary :: DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpGradientBoundary"); int dim = dir->Dimension(); auto n = NormalVectorCF(dim); n -> SetDimensions( Array ( { dim, 1 } ) ); @@ -32,8 +36,10 @@ template shared_ptr DiffOpGradVectorH1 :: DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpGradVectorH1"); return -proxy*dir->Operator("Grad"); } @@ -41,8 +47,10 @@ template shared_ptr DiffOpGradBoundaryVectorH1 :: DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpGradBoundaryVectorH1"); int dim = dir->Dimension(); auto n = NormalVectorCF(dim); n -> SetDimensions( Array ( { dim, 1 } ) ); diff -Nru ngsolve-6.2.2102/fem/diffop.hpp ngsolve-6.2.2103/fem/diffop.hpp --- ngsolve-6.2.2102/fem/diffop.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/diffop.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -160,7 +160,8 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { throw Exception (string("shape derivative not implemented for DifferentialOperator")+Name()); } @@ -401,7 +402,8 @@ virtual shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) const + shared_ptr dir, + bool Eulerian = false) const { throw Exception (string("shape derivative not implemented for DifferentialOperator")+typeid(*this).name()); } @@ -422,7 +424,11 @@ int adim, int acomp = -1) : DifferentialOperator(adim*adiffop->Dim(), adim*adiffop->BlockDim(), adiffop->VB(), adiffop->DiffOrder()), - diffop(adiffop), dim(adim), comp(acomp) { ; } + diffop(adiffop), dim(adim), comp(acomp) + { + if(adiffop->Dimensions().Size()==0) + SetDimensions( { BlockDim() } ); + } NGS_DLL_HEADER virtual ~BlockDifferentialOperator (); @@ -507,7 +513,8 @@ shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) const override; + shared_ptr dir, + bool Eulerian) const override; }; @@ -601,7 +608,8 @@ shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) const override; + shared_ptr dir, + bool Eulerian) const override; }; @@ -693,7 +701,8 @@ BareSliceVector x) const override; shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) const override; + shared_ptr dir, + bool Eulerian) const override; }; @@ -795,6 +804,66 @@ BareSliceVector x) const override; }; + + + + class SymDevMatrixDifferentialOperator : public DifferentialOperator + { + protected: + shared_ptr diffop; + int vdim; + public: + NGS_DLL_HEADER SymDevMatrixDifferentialOperator (shared_ptr adiffop, + int avdim); + + NGS_DLL_HEADER virtual ~SymDevMatrixDifferentialOperator (); + + virtual string Name() const override { return diffop->Name(); } + shared_ptr BaseDiffOp() const { return diffop; } + virtual bool SupportsVB (VorB checkvb) const override { return diffop->SupportsVB(checkvb); } + + virtual IntRange UsedDofs(const FiniteElement & fel) const override + { return IntRange(0, fel.GetNDof()); } + + shared_ptr GetTrace() const override + { + if (auto diffoptrace = diffop->GetTrace()) + return make_shared (diffoptrace, vdim); + else + return nullptr; + } + + NGS_DLL_HEADER virtual void + CalcMatrix (const FiniteElement & fel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const override; + + NGS_DLL_HEADER virtual void + CalcMatrixVS (const FiniteElement & fel, + const BaseMappedIntegrationPoint & mip, + SliceMatrix mat, + LocalHeap & lh) const override; + /* + NGS_DLL_HEADER virtual void + CalcMatrix (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & mir, + BareSliceMatrix> bmat) const override; + + NGS_DLL_HEADER virtual void + Apply (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector x, + BareSliceMatrix> flux) const override; + + NGS_DLL_HEADER virtual void + AddTrans (const FiniteElement & bfel, + const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceMatrix> flux, + BareSliceVector x) const override; + */ + }; + @@ -941,9 +1010,10 @@ #endif shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) const override + shared_ptr dir, + bool Eulerian) const override { - return DIFFOP::DiffShape(proxy, dir); + return DIFFOP::DiffShape(proxy, dir, Eulerian); } }; diff -Nru ngsolve-6.2.2102/fem/diffop_id.cpp ngsolve-6.2.2103/fem/diffop_id.cpp --- ngsolve-6.2.2102/fem/diffop_id.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/diffop_id.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -7,16 +7,23 @@ template shared_ptr DiffOpId :: DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { - return ZeroCF(Array()); + if (Eulerian) + // return dir->Deriv() * proxy; + return proxy->Operator(make_shared>>()) * dir; + else + return ZeroCF(Array()); } template shared_ptr DiffOpIdVectorH1 :: DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdVectorH1"); return ZeroCF(Array( {DIM_SPC} )); } @@ -25,8 +32,10 @@ template <> shared_ptr DiffOpIdVectorH1<3,BBND> :: DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdVectorH1"); return ZeroCF(Array( {3} )); } diff -Nru ngsolve-6.2.2102/fem/elementtopology.hpp ngsolve-6.2.2103/fem/elementtopology.hpp --- ngsolve-6.2.2102/fem/elementtopology.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/elementtopology.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -94,7 +94,8 @@ enum VorB : uint8_t { VOL, BND, BBND, BBBND }; - inline void operator++(VorB & vb, int) { vb = VorB(vb+1); } + inline VorB operator++(VorB & vb, int) { VorB vbo = vb; vb = VorB(vb+1); return vbo; } + inline VorB & operator++(VorB & vb) { vb = VorB(vb+1); return vb; } inline ostream & operator<< (ostream & ost, VorB vb) { if (vb == VOL) ost << "VOL"; @@ -1517,7 +1518,22 @@ template static int GetClassNr (const TVN & vnums) { - return 0; + int verts[8]; + for (int j = 0; j < 8; j++) + verts[j] = vnums[j]; + + int classnr = 0; + for (int j = 0; j < 7; j++) + { + int maxk = 0; + for (int k = 0; k < 8-j; k++) + if (verts[k] > verts[maxk]) maxk = k; + // compress + for (int k = maxk; k < 7-j; k++) + verts[k] = verts[k+1]; + classnr = maxk + (8-j) * classnr; + } + return classnr; } template diff -Nru ngsolve-6.2.2102/fem/elementtransformation.cpp ngsolve-6.2.2103/fem/elementtransformation.cpp --- ngsolve-6.2.2102/fem/elementtransformation.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/elementtransformation.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -211,7 +211,30 @@ mir[i].Compute(); } - + const ElementTransformation & GetFEElementTransformation (ELEMENT_TYPE et) + { + static FE_ElementTransformation<0,0> trafo_point(ET_POINT); + static FE_ElementTransformation<1,1> trafo_segm(ET_SEGM); + static FE_ElementTransformation<2,2> trafo_trig(ET_TRIG); + static FE_ElementTransformation<2,2> trafo_quad(ET_QUAD); + static FE_ElementTransformation<3,3> trafo_tet(ET_TET); + static FE_ElementTransformation<3,3> trafo_prism(ET_PRISM); + static FE_ElementTransformation<3,3> trafo_pyramid(ET_PYRAMID); + static FE_ElementTransformation<3,3> trafo_hex(ET_HEX); + + switch (et) + { + case ET_POINT: return trafo_point; + case ET_SEGM: return trafo_segm; + case ET_TRIG: return trafo_trig; + case ET_QUAD: return trafo_quad; + case ET_TET: return trafo_tet; + case ET_PRISM: return trafo_prism; + case ET_PYRAMID: return trafo_pyramid; + case ET_HEX: return trafo_hex; + } + } + template class FE_ElementTransformation<1,1>; template class FE_ElementTransformation<2,2>; diff -Nru ngsolve-6.2.2102/fem/elementtransformation.hpp ngsolve-6.2.2103/fem/elementtransformation.hpp --- ngsolve-6.2.2102/fem/elementtransformation.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/elementtransformation.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -320,10 +320,7 @@ }; - - - - + extern NGS_DLL_HEADER const ElementTransformation & GetFEElementTransformation (ELEMENT_TYPE et); } diff -Nru ngsolve-6.2.2102/fem/finiteelement.cpp ngsolve-6.2.2103/fem/finiteelement.cpp --- ngsolve-6.2.2102/fem/finiteelement.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/finiteelement.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -20,6 +20,16 @@ { return "FiniteElement"; } + + void FiniteElement :: SetVertexNumbers (FlatArray vnums) + { + SwitchET (ElementType(), [&](auto et) + { + if (auto vofe = dynamic_cast*>(this)) + vofe->SetVertexNumbers(vnums); + }); + } + IntegrationRule FiniteElement :: GetIR (int order) const { @@ -32,7 +42,7 @@ } void FiniteElement :: Interpolate (const ElementTransformation & trafo, - const class CoefficientFunction & func, BareSliceMatrix<> coefs, + const class CoefficientFunction & func, SliceMatrix<> coefs, LocalHeap & lh) const { throw Exception(string("Element ") + typeid(*this).name() + " does not support interpolation"); @@ -91,7 +101,7 @@ void CompoundFiniteElement :: Interpolate (const ElementTransformation & trafo, - const CoefficientFunction & func, BareSliceMatrix<> coefs, + const CoefficientFunction & func, SliceMatrix<> coefs, LocalHeap & lh) const { // assume all elements are the same, and match with dim func @@ -109,8 +119,10 @@ - SymMatrixFiniteElement :: SymMatrixFiniteElement (const FiniteElement & ascalfe, int avdim) - : vdim(avdim), dim(avdim*(avdim+1)/2), scalfe(ascalfe) + SymMatrixFiniteElement :: SymMatrixFiniteElement (const FiniteElement & ascalfe, int avdim, bool adeviatoric) + : vdim(avdim), deviatoric(adeviatoric), + dim(avdim*(avdim+1)/2 - (adeviatoric ? 1 : 0)), + scalfe(ascalfe) { ndof = dim*scalfe.GetNDof(); order = scalfe.Order(); @@ -119,26 +131,30 @@ void SymMatrixFiniteElement :: Print (ostream & ost) const { - ost << "SymMatrixFiniteElement" << endl; + ost << string("Sym") + (deviatoric ? "Dev" : "") + "MatrixFiniteElement" << endl; scalfe.Print (ost); } void SymMatrixFiniteElement :: Interpolate (const ElementTransformation & trafo, - const CoefficientFunction & func, BareSliceMatrix<> coefs, + const CoefficientFunction & func, SliceMatrix<> coefs, LocalHeap & lh) const { size_t scalndof = scalfe.GetNDof(); - size_t dim = vdim*vdim; - STACK_ARRAY(double, mem, ndof*dim); - FlatMatrix temp(scalndof, dim, &mem[0]); + size_t fulldim = vdim*vdim; + STACK_ARRAY(double, mem, ndof*fulldim); + FlatMatrix temp(scalndof, fulldim, &mem[0]); scalfe.Interpolate (trafo, func, temp, lh); + // cout << "interpol, temp = " << temp << endl; // now we need to transpose, not sure if we stay with that for (int i = 0, ii = 0; i < vdim; i++) for (int j = 0; j <= i; j++, ii++) - for (int k = 0; k < scalndof; k++) - coefs(ii*scalndof+k, 0) = 0.5 * (temp(k,i*vdim+j)+temp(k,j*vdim+i)); + if (ii < dim) + for (int k = 0; k < scalndof; k++) + coefs(ii*scalndof+k, 0) = 0.5 * (temp(k,i*vdim+j)+temp(k,j*vdim+i)); + + // cout << "interpol, coefs = " << coefs << endl; } } diff -Nru ngsolve-6.2.2102/fem/finiteelement.hpp ngsolve-6.2.2103/fem/finiteelement.hpp --- ngsolve-6.2.2102/fem/finiteelement.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/finiteelement.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -43,6 +43,9 @@ /// Number of degrees-of-freedom INLINE int GetNDof () const { return ndof; } + HD virtual tuple GetNDofVEFC () const { return { 1, 1, 1, 1 }; } + + /// maximal polynomial order INLINE int Order () const { return order; } @@ -59,6 +62,8 @@ /// the name of the element family virtual string ClassName() const; + virtual void SetVertexNumbers (FlatArray vnums); + virtual IntegrationRule GetIR (int order) const; /// precomputes shape for integrationrule @@ -68,7 +73,7 @@ virtual void Print (ostream & ost) const; virtual void Interpolate (const ElementTransformation & trafo, - const class CoefficientFunction & func, BareSliceMatrix<> coefs, + const class CoefficientFunction & func, SliceMatrix<> coefs, LocalHeap & lh) const; virtual bool SolveDuality (SliceVector<> rhs, SliceVector<> u, LocalHeap & lh) const { return false; } @@ -113,11 +118,17 @@ /// the name of the element family virtual string ClassName() const override { return "CompoundFiniteElement"; } - + + virtual void SetVertexNumbers (FlatArray vnums) override + { + for (auto pfel : fea) + const_cast(pfel) -> SetVertexNumbers(vnums); + } + virtual void Print (ostream & ost) const override; virtual void Interpolate (const ElementTransformation & trafo, - const class CoefficientFunction & func, BareSliceMatrix<> coefs, + const class CoefficientFunction & func, SliceMatrix<> coefs, LocalHeap & lh) const override; }; @@ -141,11 +152,12 @@ { protected: int vdim; + bool deviatoric; int dim; const FiniteElement & scalfe; public: /// initialize with pointers to components, copy pointers - SymMatrixFiniteElement (const FiniteElement & ascalfe, int avdim); + SymMatrixFiniteElement (const FiniteElement & ascalfe, int avdim, bool adeviatoric); virtual ELEMENT_TYPE ElementType() const override { return scalfe.ElementType(); } /// number of components @@ -161,7 +173,7 @@ virtual void Print (ostream & ost) const override; virtual void Interpolate (const ElementTransformation & trafo, - const class CoefficientFunction & func, BareSliceMatrix<> coefs, + const class CoefficientFunction & func, SliceMatrix<> coefs, LocalHeap & lh) const override; }; diff -Nru ngsolve-6.2.2102/fem/h1hofe.hpp ngsolve-6.2.2103/fem/h1hofe.hpp --- ngsolve-6.2.2102/fem/h1hofe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/h1hofe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -64,7 +64,7 @@ bool nodalp2 = false; public: - + using VertexOrientedFE::SetVertexNumbers; using ET_trait::ElementType; // using VertexOrientedFE::SetVertexNumbers; // using VertexOrientedFE::SetVertexNumber; diff -Nru ngsolve-6.2.2102/fem/hcurlcurlfe.hpp ngsolve-6.2.2103/fem/hcurlcurlfe.hpp --- ngsolve-6.2.2102/fem/hcurlcurlfe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hcurlcurlfe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -10,6 +10,97 @@ namespace ngfem { + //Assuming i,j,k \in [0,1,2] + template + constexpr int LeviCivitaSymbol(int i, int j, int k) + { + if (i==j || i==k || j==k) + return T(0); + else if ( (i==0 && j==1) || (i==1 && j==2) || (i==2 && j==0) ) + return T(1); + else + return -T(1); + } + + template + Mat<3,3,T> TensorCrossProduct(Mat<3,3,T> A, Mat<3,3,T> B) + { + /*Mat<3,3,T> result; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + { + result(i,j) = T(0); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int m=0; m<3; m++) + for (int n=0; n<3; n++) + { + result(i,j) += LeviCivitaSymbol(i,k,l)*LeviCivitaSymbol(j,m,n)*A(k,m)*B(l,n); + } + } + + + // A x B = 0.5*(cof(A+B) - cof(A-B)) + //ikl +123 -132 +231 -213 +312 -321 others=0 + //jmn +123 -132 +231 -213 +312 -321 others=0 + //result(0,0) = + return result;*/ + // return 0.5 * ( Cof(Mat<3,3,T>(A+B)) - Cof(Mat<3,3,T>(A-B)) ); + // return 0.5 * ( Cof(A+B) - Cof(A-B) ); + + Mat<3,3,T> prod; + prod.Col(0) = Cross(Vec<3,T>(A.Col(1)), Vec<3,T>(B.Col(2))) - Cross(Vec<3,T>(A.Col(2)), Vec<3,T>(B.Col(1))); + prod.Col(1) = Cross(Vec<3,T>(A.Col(2)), Vec<3,T>(B.Col(0))) - Cross(Vec<3,T>(A.Col(0)), Vec<3,T>(B.Col(2))); + prod.Col(2) = Cross(Vec<3,T>(A.Col(0)), Vec<3,T>(B.Col(1))) - Cross(Vec<3,T>(A.Col(1)), Vec<3,T>(B.Col(0))); + return prod; + } + + template + Mat<3,3,T> TensorCrossProduct(Vec<3,T> v, Mat<3,3,T> A) + { + /*Mat<3,3,T> result; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + { + result(i,j) = T(0); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + { + result(i,j) += LeviCivitaSymbol(i,k,l)*v(k)*A(l,j); + } + } + return result;*/ + + Mat<3,3,T> result; + for (int j = 0; j < 3; j++) + result.Col(j) = Cross(v, Vec<3,T>(A.Col(j))); + return result; + } + + template + Mat<3,3,T> TensorCrossProduct(Mat<3,3,T> A, Vec<3,T> v) + { + /*Mat<3,3,T> result; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + { + result(i,j) = T(0); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + { + result(i,j) += LeviCivitaSymbol(j,k,l)*A(i,k)*v(l); + } + } + return result;*/ + + Mat<3,3,T> result; + for (int j = 0; j < 3; j++) + result.Row(j) = Cross(Vec<3,T>(A.Row(j)),v); + return result; + } + + + template class HCurlCurlFiniteElement : public FiniteElement { @@ -22,11 +113,34 @@ SliceMatrix<> shape) const = 0; virtual void CalcMappedShape (const BaseMappedIntegrationPoint & bmip, - BareSliceMatrix shape) const = 0; + BareSliceMatrix shape) const = 0; + + virtual void EvaluateMappedShape (const BaseMappedIntegrationPoint & bmip, + BareSliceVector coefs, + BareSliceMatrix shape) const = 0; virtual void CalcMappedCurlShape (const BaseMappedIntegrationPoint & bmip, BareSliceMatrix shape) const = 0; + virtual void CalcMappedIncShape (const BaseMappedIntegrationPoint & bmip, + BareSliceMatrix shape) const = 0; + + virtual void EvaluateMappedIncShape (const BaseMappedIntegrationPoint & bmip, + BareSliceVector coefs, + BareSliceVector inc) const = 0; + + virtual void CalcMappedIncShape (const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceMatrix> shape) const = 0; + + virtual void EvaluateIncShape (const SIMD_BaseMappedIntegrationRule & ir, + BareSliceVector<> coefs, + BareSliceMatrix> values) const = 0; + + virtual void AddTransIncShape (const SIMD_BaseMappedIntegrationRule & ir, + BareSliceMatrix> values, + BareSliceVector<> coefs) const = 0; + + virtual void CalcMappedShape (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix> shapes) const = 0; @@ -45,6 +159,8 @@ + + const FlatMatrixFixWidth GetShape (const IntegrationPoint & ip, LocalHeap & lh) const { @@ -79,6 +195,7 @@ } } + template Vec SymMatToVec(MAT & mat) { @@ -107,6 +224,11 @@ { return Matrix( {{2*a(0)*b(0), a(0)*b(1)+a(1)*b(0), a(0)*b(2)+a(2)*b(0)}, {a(1)*b(0) + a(0)*b(1), 2*a(1)*b(1), a(1)*b(2) + a(2)*b(1)}, {a(2)*b(0) + a(0)*b(2), a(2)*b(1) + a(1)*b(2), 2*a(2)*b(2)}} ); } + template + Mat<2,2,T> SymDyadProd(Vec<2,T> a, Vec<2,T> b) + { + return Matrix( {{2*a(0)*b(0), a(0)*b(1)+a(1)*b(0)}, {a(1)*b(0) + a(0)*b(1), 2*a(1)*b(1)}} ); + } template @@ -270,7 +392,304 @@ template auto vEpsGradu (AutoDiffDiff au, AutoDiffDiff av) { return T_vEpsGradu(au, av); } + + + template + class ReggeAD + { + Mat value; + + public: + ReggeAD () + { + value = T(0); + } + ReggeAD (AutoDiff a, AutoDiff b) + { + Vec Da, Db; + for(int i=0; i & Value() { return value; } + }; + + template + auto MakeReggeAD(AutoDiff a, AutoDiff b) + { + return ReggeAD(a, b); + } + + + + template + ReggeAD operator* (AutoDiff s, ReggeAD A) + { + ReggeAD result; + result.Value() = s.Value()*A.Value(); + return result; + } + + + template + ReggeAD operator* (T s, ReggeAD A) + { + ReggeAD result = A; + result.Value() *= s; + return result; + } + + template + ReggeAD operator+ (ReggeAD A, ReggeAD B) + { + ReggeAD result = A; + result.Value() += B.Value(); + return result; + } + + template + ReggeAD operator- (ReggeAD A, ReggeAD B) + { + ReggeAD result = A; + result.Value() -= B.Value(); + return result; + } + + template class ReggeADD; + + template + class ReggeADD<3,T> + { + Mat<3,3,T> value; + Mat<3,3,T> curl; + Mat<3,3,T> inc; + + public: + ReggeADD () + { + value = T(0); + curl = T(0); + inc = T(0); + } + + ReggeADD (AutoDiffDiff<3,T> a, AutoDiffDiff<3,T> b) + { + auto Da = Vec<3,T>(a.DValue(0),a.DValue(1),a.DValue(2)); + auto Db = Vec<3,T>(b.DValue(0),b.DValue(1),b.DValue(2)); + value = SymDyadProd(Da,Db); + // curl(s*v) = nabla s x v + s curl(v) in 3D + // | nabla a_1 x b + a_1 curl(b) | + // curl(a \otimes b) = | nabla a_2 x b + a_2 curl(b) | + // | nabla a_3 x b + a_3 curl(b) | + + // curl( nabla s ) = 0 + // | nabla d_x a x nabla b | + // -> curl( nabla a \otimes nabla b) = | nabla d_y a x nabla b | + // | nabla d_z a x nabla b | + + Vec<3,T> Ddai [3] = { Vec<3,T>(a.DDValue(0,0), a.DDValue(0,1), a.DDValue(0,2)), Vec<3,T>(a.DDValue(1,0), a.DDValue(1,1), a.DDValue(1,2)), Vec<3,T>(a.DDValue(2,0), a.DDValue(2,1), a.DDValue(2,2)) }; + Vec<3,T> Ddbi [3] = { Vec<3,T>(b.DDValue(0,0), b.DDValue(0,1), b.DDValue(0,2)), Vec<3,T>(b.DDValue(1,0), b.DDValue(1,1), b.DDValue(1,2)), Vec<3,T>(b.DDValue(2,0), b.DDValue(2,1), b.DDValue(2,2)) }; + + for (int i = 0; i < 3; i++) + curl.Row(i) = Cross(Ddai[i], Db) + Cross(Ddbi[i], Da); + + + // | nabla d_x a x nabla b | + // curl( nabla a \otimes nabla b) = | nabla d_y a x nabla b | + // | nabla d_z a x nabla b | + + + // curl T curl ( nabla a \otimes nabla b): + //11: d_yd_z(a) d_yd_z(b) - d^2_z(a) d^2_y(b) - d_y^2(a) d^2_z(b) + d_yd_z(a)d_yd_z(b) + //12: d_xd_y(a) d_z^2(b) - d_xd_z(a) d_yd_z(b) - d_yd_z(a) d_xd_z(b) + d_z^2(a)d_xd_y(b) + //13: d^2_y(a) d_xd_z(b) - d_yd_z(a) d_xd_y(b) - d_xd_y(a) d_yd_z(b) + d_xd_z(a)d^2_y(b) + //22: d_xd_z(a) d_xd_z(b) - d^2_x(a) d^2_z(b) - d^2_z(a) d^2_x(b) + d_xd_z(a)d_xd_z(b) + //23: d_yd_z(a) d^2_x(b) - d_xd_y(a) d_xd_z(b) - d_xd_z(a) d_xd_y(b) + d^2_x(a)d_yd_z(b) + //33: d^2_x(a) d^2_y(b) - d_xd_y(a) d_xd_y(b) - d_xd_y(a) d_xd_y(b) + d^2_y(a)d^2_x(b) + + // = - hesse(a) x hesse(b) = -eps_imn eps_jlk d_md_l(a) d_nd_k b ?? + + /*inc(0,0) = a.DDValue(1,2)*b.DDValue(1,2) - a.DDValue(2,2)*b.DDValue(1,1) - a.DDValue(1,1)*b.DDValue(2,2) + a.DDValue(1,2)*b.DDValue(1,2); + inc(0,1) = a.DDValue(0,1)*b.DDValue(2,2) - a.DDValue(0,2)*b.DDValue(1,2) - a.DDValue(1,2)*b.DDValue(0,2) + a.DDValue(2,2)*b.DDValue(0,1); + inc(0,2) = a.DDValue(1,1)*b.DDValue(0,2) - a.DDValue(1,2)*b.DDValue(0,1) - a.DDValue(0,1)*b.DDValue(1,2) + a.DDValue(0,2)*b.DDValue(1,1); + inc(1,1) = a.DDValue(0,2)*b.DDValue(0,2) - a.DDValue(0,0)*b.DDValue(2,2) - a.DDValue(2,2)*b.DDValue(0,0) + a.DDValue(0,2)*b.DDValue(0,2); + inc(1,2) = a.DDValue(1,2)*b.DDValue(0,0) - a.DDValue(0,1)*b.DDValue(0,2) - a.DDValue(0,2)*b.DDValue(0,1) + a.DDValue(0,0)*b.DDValue(1,2); + inc(2,2) = a.DDValue(0,0)*b.DDValue(1,1) - a.DDValue(0,1)*b.DDValue(0,1) - a.DDValue(0,1)*b.DDValue(0,1) + a.DDValue(1,1)*b.DDValue(0,0); + // curl T curl ( nabla b \otimes nabla a): + inc(0,0) += b.DDValue(1,2)*a.DDValue(1,2) - b.DDValue(2,2)*a.DDValue(1,1) - b.DDValue(1,1)*a.DDValue(2,2) + b.DDValue(1,2)*a.DDValue(1,2); + inc(0,1) += b.DDValue(0,1)*a.DDValue(2,2) - b.DDValue(0,2)*a.DDValue(1,2) - b.DDValue(1,2)*a.DDValue(0,2) + b.DDValue(2,2)*a.DDValue(0,1); + inc(0,2) += b.DDValue(1,1)*a.DDValue(0,2) - b.DDValue(1,2)*a.DDValue(0,1) - b.DDValue(0,1)*a.DDValue(1,2) + b.DDValue(0,2)*a.DDValue(1,1); + inc(1,1) += b.DDValue(0,2)*a.DDValue(0,2) - b.DDValue(0,0)*a.DDValue(2,2) - b.DDValue(2,2)*a.DDValue(0,0) + b.DDValue(0,2)*a.DDValue(0,2); + inc(1,2) += b.DDValue(1,2)*a.DDValue(0,0) - b.DDValue(0,1)*a.DDValue(0,2) - b.DDValue(0,2)*a.DDValue(0,1) + b.DDValue(0,0)*a.DDValue(1,2); + inc(2,2) += b.DDValue(0,0)*a.DDValue(1,1) - b.DDValue(0,1)*a.DDValue(0,1) - b.DDValue(0,1)*a.DDValue(0,1) + b.DDValue(1,1)*a.DDValue(0,0); + // symmetry + inc(1,0) = inc(0,1); + inc(2,0) = inc(0,2); + inc(2,1) = inc(1,2);*/ + + Mat<3,3,T> hesse1, hesse2; + a.StoreHessian(hesse1.Data()); + b.StoreHessian(hesse2.Data()); + inc = -2*TensorCrossProduct(hesse1,hesse2); + } + + auto Value() const { return value; } + auto Curl() const { return curl; } + auto Inc() const { return inc; } + + Mat<3,3,T> & Value() { return value; } + Mat<3,3,T> & Curl() { return curl; } + Mat<3,3,T> & Inc() { return inc; } + }; + + + template + class ReggeADD<2,T> + { + Mat<2,2,T> value; + Vec<2,T> curl; + T inc; + + public: + ReggeADD () + { + value = T(0); + curl = T(0); + inc = T(0); + } + + ReggeADD (AutoDiffDiff<2,T> a, AutoDiffDiff<2,T> b) + { + auto Da = Vec<2,T>(a.DValue(0),a.DValue(1)); + auto Db = Vec<2,T>(b.DValue(0),b.DValue(1)); + value = SymDyadProd(Da,Db); + // curl(s*v) = v* nabla s^perp + s curl(v) in 2D + // | b * nabla a_1^perp + a_1 curl(b) | + // curl(a \otimes b) = | b * nabla a_2^perp + a_2 curl(b) | + + // curl( nabla s ) = 0 + // | Db * nabla d_x a^perp | + // -> curl( nabla a \otimes nabla b) = | Db * nabla d_y a^perp | + + Vec<2,T> Ddai_p [2] = { Vec<2,T>(-a.DDValue(0,1), a.DDValue(0,0)), Vec<2,T>(-a.DDValue(1,1), a.DDValue(1,0)) }; + Vec<2,T> Ddbi_p [2] = { Vec<2,T>(-b.DDValue(0,1), b.DDValue(0,0)), Vec<2,T>(-b.DDValue(1,1), b.DDValue(1,0)) }; + + for (int i=0; i<2; i++) + curl(i) = InnerProduct(Db,Ddai_p[i]) + InnerProduct(Da,Ddbi_p[i]); + + // | Db * nabla d_x a^perp | + // curl( nabla a \otimes nabla b) = | Db * nabla d_y a^perp | + + + // curl T curl ( nabla a \otimes nabla b) = d_x(Db * nabla d_y a^perp) - d_y(Db * nabla d_x a^perp) + // = (d_x Db) * nabla(d_y a)^perp - (d_y Db) * nabla(d_x a)^perp + + inc = InnerProduct(Vec<2,T>(b.DDValue(0,0), b.DDValue(0,1)),Ddai_p[1]) - InnerProduct(Vec<2,T>(b.DDValue(1,0), b.DDValue(1,1)),Ddai_p[0]) + InnerProduct(Vec<2,T>(a.DDValue(0,0), a.DDValue(0,1)),Ddbi_p[1]) - InnerProduct(Vec<2,T>(a.DDValue(1,0), a.DDValue(1,1)),Ddbi_p[0]); + } + + auto Value() const { return value; } + auto Curl() const { return curl; } + auto Inc() const { return inc; } + + Mat<2,2,T> & Value() { return value; } + Vec<2,T> & Curl() { return curl; } + T & Inc() { return inc; } + }; + + template + auto MakeReggeAD(AutoDiffDiff a, AutoDiffDiff b) + { + return ReggeADD(a, b); + } + + template + ReggeADD<3,T> operator* (AutoDiffDiff<3,T> s, ReggeADD<3,T> A) + { + ReggeADD<3,T> result; + result.Value() = s.Value()*A.Value(); + + // s scalar, v vector + // curl(s*v) = nabla s x v + s curl(v) in 3D + Vec<3,T> gradient; + s.StoreGradient(gradient.Data()); + + result.Curl() = s.Value()*A.Curl(); + for (int i = 0; i < 3; i++) + result.Curl().Row(i) += Cross(gradient, Vec<3,T>(A.Value().Row(i))); + + // inc(s A) = s inc(A) + 2sym(grad(s) x curl A) + hesse(s) x A, x...Tensor-Cross-Product + Mat<3,3,T> hesse; + s.StoreHessian(hesse.Data()); + + result.Inc() = s.Value()*A.Inc() + TensorCrossProduct(gradient,A.Curl()) + Trans(TensorCrossProduct(gradient,A.Curl())) + TensorCrossProduct(hesse,A.Value()); + + return result; + } + + + template + ReggeADD operator* (T s, ReggeADD A) + { + ReggeADD result = A; + result.Value() *= s; + result.Curl() *= s; + result.Inc() *= s; + return result; + } + + template + ReggeADD operator+ (ReggeADD A, ReggeADD B) + { + ReggeADD result = A; + result.Value() += B.Value(); + result.Curl() += B.Curl(); + result.Inc() += B.Inc(); + return result; + } + + template + ReggeADD operator- (ReggeADD A, ReggeADD B) + { + ReggeADD result = A; + result.Value() -= B.Value(); + result.Curl() -= B.Curl(); + result.Inc() -= B.Inc(); + return result; + } + + + template + ReggeADD<2,T> operator* (AutoDiffDiff<2,T> s, ReggeADD<2,T> A) + { + ReggeADD<2,T> result; + result.Value() = s.Value()*A.Value(); + + // s scalar, v vector + // curl(s*v) = v* nabla s^perp + s curl(v) in 2D + result.Curl() = A.Value()*Vec<2,T>(-s.DValue(1),s.DValue(0)) + s.Value()*A.Curl(); + + // inc(sA) = A:( dydy s & -dxdy s \\ -dxdy s & dxdx s) + 2*nabla s^\perp*curl(A) + s*inc(A) + Mat<2,2,T> hesse; + hesse(0,0) = s.DDValue(1,1); + hesse(1,0) = -s.DDValue(1,0); + hesse(0,1) = -s.DDValue(0,1); + hesse(1,1) = s.DDValue(0,0); + + result.Inc() = s.Value()*A.Inc() + InnerProduct(hesse,A.Value()) + 2*InnerProduct(Vec<2,T>(-s.DValue(1),s.DValue(0)),A.Curl()); + + return result; + } + + + + template class HCurlCurlFE; @@ -282,6 +701,7 @@ static constexpr int DIM = ET_trait::DIM; enum { DIM_STRESS = (DIM*(DIM+1))/2 }; enum { DIM_DMAT = 7*DIM-12 }; + enum { DIM_DDMAT = 8*DIM-15 }; using VertexOrientedFE::vnums; using HCurlCurlFiniteElement::DIM>::ndof; @@ -327,9 +747,8 @@ } virtual void CalcMappedShape (const BaseMappedIntegrationPoint & bmip, - BareSliceMatrix shapes) const override + BareSliceMatrix shapes) const override { - /* Here I would need GetTIP for AutoDiffDiffRec Switch<4-DIM> @@ -344,14 +763,175 @@ });*/ auto & mip = static_cast&> (bmip); - Vec> adp = mip; - Cast() -> T_CalcShape (TIP> (adp),SBLambda([shapes](int nr,auto val) + if constexpr (ET == ET_TET || ET == ET_TRIG) + { + Cast() -> T_CalcShape2 (GetTIP(mip),SBLambda([shapes](int nr,auto val) + { + shapes.Row(nr).AddSize(DIM*DIM) = val.Value().AsVector(); + })); + } + else + { + Cast() -> T_CalcShape (GetTIP(mip),SBLambda([shapes](int nr,auto val) { VecToSymMat (val.Shape(), shapes.Row(nr)); })); + } + } + + + + virtual void EvaluateMappedShape (const BaseMappedIntegrationPoint & bmip, + BareSliceVector coefs, + BareSliceMatrix shape) const override + { + auto & mip = static_cast&> (bmip); + Vec sum = 0.0; + Cast() -> T_CalcShape (GetTIP(mip),SBLambda([coefs, &sum](int nr,auto val) + { + sum += coefs(nr) * val.Shape(); + })); + VecToSymMat (sum, shape); + } + + virtual void CalcMappedIncShape (const BaseMappedIntegrationPoint & bmip, + BareSliceMatrix shapes) const override + { + auto & mip = static_cast&> (bmip); + if constexpr (ET == ET_TET || ET == ET_TRIG) + Cast() -> T_CalcShape2 (GetTIPHesse(mip),SBLambda([shapes](int nr,auto val) + { + if constexpr (DIM==3) + shapes.Row(nr).AddSize(DIM_DDMAT) = val.Inc().AsVector(); + else + shapes.Row(nr).AddSize(DIM_DDMAT) = val.Inc(); + })); } + + virtual void EvaluateMappedIncShape (const BaseMappedIntegrationPoint & bmip, + BareSliceVector coefs, + BareSliceVector inc) const override + { + auto & mip = static_cast&> (bmip); + + Mat sum = 0.0; + if constexpr (ET == ET_TET || ET == ET_TRIG) + Cast() -> T_CalcShape2 (GetTIPHesse(mip),SBLambda([coefs, &sum](int nr,auto val) + { + sum += coefs(nr) * Mat(val.Inc()); + })); + inc.Range(0,DIM_DDMAT) = sum.AsVector(); + } + + virtual void CalcMappedIncShape (const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceMatrix> shapes) const override + { + auto & mir = static_cast&> (bmir); + for (size_t i = 0; i < mir.Size(); i++) + { + if constexpr (ET == ET_TET || ET == ET_TRIG) + { + Cast() -> T_CalcShape2 (GetTIPHesse(mir[i]),SBLambda([shapes,i](int j,auto val) + { + if constexpr (DIM==3) + shapes.Rows(j*sqr(DIM), (j+1)*sqr(DIM)).Col(i).Range(0,DIM_DDMAT) = val.Inc().AsVector(); + else + shapes.Rows(j,j+1).Col(i).Range(0,DIM_DDMAT) = val.Inc(); + })); + } + } + } + + void EvaluateIncShape (const SIMD_BaseMappedIntegrationRule & bmir, + BareSliceVector<> coefs, + BareSliceMatrix> values) const override + { + auto & mir = static_cast&> (bmir); + for (size_t i = 0; i < bmir.Size(); i++) + { + double *pcoefs = &coefs(0); + const size_t dist = coefs.Dist(); + if constexpr (ET == ET_TET && DIM == 3) + { + Mat> summat(0); + Cast() -> T_CalcShape2 (GetTIPHesse(mir[i]), + SBLambda ([&summat,&pcoefs,dist] (size_t j, auto val) + { + summat += (*pcoefs)*val.Inc(); + pcoefs += dist; + })); + for (size_t k = 0; k < sqr(DIM); k++) + values(k,i) = summat(k); + } + if constexpr (ET == ET_TRIG && DIM == 2) + { + SIMD summat(0); + Cast() -> T_CalcShape2 (GetTIPHesse(mir[i]), + SBLambda ([&summat,&pcoefs,dist] (size_t j, auto val) + { + summat += (*pcoefs)*val.Inc(); + pcoefs += dist; + })); + values(0,i) = summat; + } + } + + /*if constexpr (ET == ET_TET || ET == ET_TRIG) + { + Switch<1> + (bmir.DimSpace()-DIM,[values,&bmir,coefs,this](auto CODIM) + { + constexpr auto DIMSPACE = DIM+CODIM.value; + auto & mir = static_cast&> (bmir); + for (size_t i = 0; i < bmir.Size(); i++) + { + double *pcoefs = &coefs(0); + const size_t dist = coefs.Dist(); + + + if constexpr (DIMSPACE==3) + { + Mat> summat(0); + Cast() -> T_CalcShape2 (GetTIPHesse(mir[i]), + SBLambda ([&summat,&pcoefs,dist] (size_t j, auto val) + { + summat += (*pcoefs)*val.Inc(); + pcoefs += dist; + })); + for (size_t k = 0; k < sqr(DIMSPACE); k++) + values(k,i) = summat(k); + } + if constexpr (DIMSPACE==2) + { + SIMD summat(0); + Cast() -> T_CalcShape2 (GetTIPHesse(mir[i]), + SBLambda ([&summat,&pcoefs,dist] (size_t j, auto val) + { + summat += (*pcoefs)*val.Inc(); + pcoefs += dist; + })); + values(0,i) = summat; + } + + } + }); + }*/ + } + void AddTransIncShape (const SIMD_BaseMappedIntegrationRule & ir, + BareSliceMatrix> values, + BareSliceVector<> coefs) const override + { + // auto & mir = static_cast&> (ir); + if constexpr (ET == ET_TET || ET == ET_TRIG) + { + cout << "nothing here" << endl; + } + } + + + virtual void CalcDualShape (const BaseMappedIntegrationPoint & bmip, SliceMatrix<> shape) const override { shape = 0.0; @@ -431,20 +1011,34 @@ BareSliceMatrix shape) const override { auto mip = static_cast &>(bmip); - Vec> adp = mip; - TIP> addp(adp); - if (!mip.GetTransformation().IsCurvedElement()) // non-curved element - { - Cast() -> T_CalcShape (addp, SBLambda([&](int nr,auto val) + + + if constexpr (ET == ET_TET || ET == ET_TRIG) + Cast() -> T_CalcShape2 (GetTIPHesse(mip),SBLambda([shape](int nr,auto val) + { + if constexpr (DIM==3) + shape.Row(nr).AddSize(DIM_DMAT) = val.Curl().AsVector(); + else + shape.Row(nr).AddSize(DIM_DMAT) = val.Curl(); + })); + else { - shape.Row(nr).AddSize(DIM_DMAT) = val.CurlShape(); - })); - } - else // curved element - { - throw Exception("CalcMappedCurlShape not implemented for curved elements!"); - } + Vec> adp = mip; + TIP> addp(adp); + + if (!mip.GetTransformation().IsCurvedElement()) // non-curved element + { + Cast() -> T_CalcShape (addp, SBLambda([&](int nr,auto val) + { + shape.Row(nr).AddSize(DIM_DMAT) = val.CurlShape(); + })); + } + else // curved element + { + throw Exception("CalcMappedCurlShape not implemented for curved elements!"); + } + } } template @@ -453,9 +1047,18 @@ { for (size_t i = 0; i < mir.Size(); i++) { - auto jacI = mir[i].GetJacobianInverse(); - + if constexpr (ET == ET_TET || ET == ET_TRIG) + { + this->Cast() -> T_CalcShape2 (GetTIP(mir[i]), + SBLambda ([i,shapes] (size_t j, auto val) + { + shapes.Rows(j*sqr(DIMSPACE), (j+1)*sqr(DIMSPACE)).Col(i).Range(0,sqr(DIMSPACE)) = val.Value().AsVector(); + })); + } + else + { + auto jacI = mir[i].GetJacobianInverse(); Vec> hv; Mat> mat; SIMD mem[DIMSPACE*DIMSPACE*DIM_STRESS]; @@ -469,7 +1072,6 @@ trans.Col(k) = physmat.AsVector(); } - Vec>> adp = mir.IR()[i]; TIP>> addp(adp); @@ -477,7 +1079,8 @@ SBLambda ([i,shapes,trans] (size_t j, auto val) { shapes.Rows(j*sqr(DIMSPACE), (j+1)*sqr(DIMSPACE)).Col(i).Range(0,sqr(DIMSPACE)) = trans * val.Shape(); - })); + })); + } } } @@ -499,36 +1102,51 @@ BareSliceVector<> coefs, BareSliceMatrix> values) const override { - for (size_t i = 0; i < bmir.Size(); i++) - { - double *pcoefs = &coefs(0); - const size_t dist = coefs.Dist(); - - Vec> sum(0.0); - Vec>> adp = bmir.IR()[i]; - TIP>> addp(adp); - - Cast() -> T_CalcShape (addp, - SBLambda ([&sum,&pcoefs,dist] (size_t j, auto val) - { - sum += (*pcoefs)*val.Shape(); - pcoefs += dist; - })); + Switch<4-DIM> + (bmir.DimSpace()-DIM,[values,&bmir, coefs,this](auto CODIM) + { + constexpr auto DIMSPACE = DIM+CODIM.value; + auto & mir = static_cast&> (bmir); + for (size_t i = 0; i < bmir.Size(); i++) + { + double *pcoefs = &coefs(0); + const size_t dist = coefs.Dist(); - Mat> summat; - VecToSymMat (sum, summat); - - Switch<4-DIM> - (bmir.DimSpace()-DIM,[values,&bmir,i,summat](auto CODIM) - { - constexpr auto DIMSPACE = DIM+CODIM.value; - auto & mir = static_cast&> (bmir); - auto jacI = mir[i].GetJacobianInverse(); - Mat> physmat = Trans(jacI) * summat * jacI; - for (size_t k = 0; k < sqr(DIMSPACE); k++) - values(k,i) = physmat(k); - }); - } + if constexpr (ET == ET_TET || ET == ET_TRIG) + { + Mat> summat(0); + Cast() -> T_CalcShape2 (GetTIP(mir[i]), + SBLambda ([&summat,&pcoefs,dist] (size_t j, auto val) + { + summat += (*pcoefs)*val.Value(); + pcoefs += dist; + })); + for (size_t k = 0; k < sqr(DIMSPACE); k++) + values(k,i) = summat(k); + } + else + { + Vec> sum(0.0); + Vec>> adp = bmir.IR()[i]; + TIP>> addp(adp); + + Cast() -> T_CalcShape (addp, + SBLambda ([&sum,&pcoefs,dist] (size_t j, auto val) + { + sum += (*pcoefs)*val.Shape(); + pcoefs += dist; + })); + + Mat> summat; + VecToSymMat (sum, summat); + + auto jacI = mir[i].GetJacobianInverse(); + Mat> physmat = Trans(jacI) * summat * jacI; + for (size_t k = 0; k < sqr(DIMSPACE); k++) + values(k,i) = physmat(k); + } + } + }); } virtual void AddTrans (const SIMD_BaseMappedIntegrationRule & bmir, @@ -712,6 +1330,48 @@ }; + template + void T_CalcShape2 (TIP<2,Tx> ip, TFA & shape) const + { + Tx x = ip.x, y = ip.y; + Tx lami[3] ={ x, y, 1-x-y }; + int ii = 0; + + for (int i = 0; i < 3; i++) + { + INT<2> e = ET_trait::GetEdgeSort (i, vnums); + Tx ls = lami[e[1]], le = lami[e[0]]; + + auto symdyadic = MakeReggeAD(ls, le); + + LegendrePolynomial::EvalScaled(order_facet[i][0], ls-le,ls+le, SBLambda([symdyadic, &ii, shape] (size_t nr, auto val) + { + shape[ii++] = -val*symdyadic; + })); + } + + + if (order_inner[0] > 0) + { + INT<4> f = ET_trait::GetFaceSort(0, vnums); + Tx ls = lami[f[0]], le = lami[f[1]], lt = lami[f[2]]; + + auto symdyadic1 = lt*MakeReggeAD(ls, le); + auto symdyadic2 = ls*MakeReggeAD(lt, le); + auto symdyadic3 = le*MakeReggeAD(ls, lt); + + + DubinerBasis::Eval(order_inner[0]-1, ls,le, + SBLambda([symdyadic1,symdyadic2,symdyadic3, &ii, shape] (size_t nr, auto val) + { + shape[ii++] = 2*val*symdyadic1; + shape[ii++] = 2*val*symdyadic2; + shape[ii++] = 2*val*symdyadic3; + })); + } + + }; + template void CalcDualShape2 (const MIP & mip, TFA & shape) const { @@ -1414,9 +2074,79 @@ shape[ii++] = T_REGGE_Shape<3,T>(val*symdyadic4); shape[ii++] = T_REGGE_Shape<3,T>(val*symdyadic5); shape[ii++] = T_REGGE_Shape<3,T>(val*symdyadic6); })); - } + } }; + + + template + void T_CalcShape2 (TIP<3,Tx> ip, TFA & shape) const + { + Tx x = ip.x, y = ip.y, z = ip.z; + Tx lam[4] = {x, y, z, 1-x-y-z}; + int ii = 0; + + for (int i = 0; i < 6; i++) + { + INT<2> e = ET_trait::GetEdgeSort (i, vnums); + Tx ls = lam[e[1]], le = lam[e[0]]; + + auto symdyadic = MakeReggeAD(ls, le); + LegendrePolynomial::EvalScaled(order_edge[i], ls-le,ls+le, SBLambda([symdyadic, &ii, shape] (size_t nr, auto val) + { + shape[ii++] = -val*symdyadic; + })); + } + + + for(int fa = 0; fa < 4; fa++) + { + if (order_facet[fa][0] > 0) + { + INT<4> f = ET_trait::GetFaceSort(fa, vnums); + Tx ls = lam[f[0]], le = lam[f[1]], lt = lam[f[2]]; + + auto symdyadic1 = lt*MakeReggeAD(ls, le); + auto symdyadic2 = ls*MakeReggeAD(lt, le); + auto symdyadic3 = le*MakeReggeAD(ls, lt); + + DubinerBasis::Eval(order_facet[fa][0]-1, ls,le, + SBLambda([symdyadic1,symdyadic2,symdyadic3, &ii, shape] (size_t nr, auto val) + { + shape[ii++] = val*symdyadic1; + shape[ii++] = val*symdyadic2; + shape[ii++] = val*symdyadic3; + })); + } + } + + if (order_inner[0] > 1) + { + Tx li = lam[0], lj = lam[1], lk = lam[2], ll = lam[3]; + + auto symdyadic1 = li*lj*MakeReggeAD(lk, ll); + auto symdyadic2 = lj*lk*MakeReggeAD(ll, li); + auto symdyadic3 = lk*ll*MakeReggeAD(li, lj); + auto symdyadic4 = ll*li*MakeReggeAD(lj, lk); + auto symdyadic5 = li*lk*MakeReggeAD(lj, ll); + auto symdyadic6 = lj*ll*MakeReggeAD(li, lk); + + + DubinerBasis3D::Eval (order_inner[0]-2, lam[0], lam[1], lam[2], SBLambda([&ii, shape, symdyadic1, symdyadic2, symdyadic3, symdyadic4, symdyadic5, symdyadic6](size_t j, auto val) + { + shape[ii++] = val*symdyadic1; + shape[ii++] = val*symdyadic2; + shape[ii++] = val*symdyadic3; + shape[ii++] = val*symdyadic4; + shape[ii++] = val*symdyadic5; + shape[ii++] = val*symdyadic6; + })); + } + + } + + + template void CalcDualShape2 (const MIP & mip, TFA & shape) const { diff -Nru ngsolve-6.2.2102/fem/hcurl_equations.hpp ngsolve-6.2.2103/fem/hcurl_equations.hpp --- ngsolve-6.2.2102/fem/hcurl_equations.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hcurl_equations.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -155,8 +155,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdEdge"); return -TransposeCF(dir->Operator("Grad")) * proxy; } }; @@ -230,8 +232,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpCurlEdge"); auto grad = dir->Operator("Grad"); return -TraceCF(grad) * proxy; } @@ -334,8 +338,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpCurlEdge"); auto grad = dir->Operator("Grad"); return grad * proxy - TraceCF(grad) * proxy; } @@ -561,8 +567,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdBoundaryEdge"); int dim = dir->Dimension(); auto n = NormalVectorCF(dim); n -> SetDimensions( Array ( { dim, 1 } ) ); @@ -667,8 +675,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpCurlBoundaryEdge"); auto grad = dir->Operator("Gradboundary"); return -TraceCF(grad)*proxy + grad * proxy; } @@ -1083,6 +1093,8 @@ enum { DIM_DMAT = D*D }; enum { DIFFORDER = 1 }; + static string Name() { return "grad"; } + static Array GetDimensions() { return Array ( { DIM_SPACE, DIM_SPACE } ); } static constexpr double eps() { return 1e-4; } @@ -1166,6 +1178,8 @@ enum { DIM_DMAT = D*D }; enum { DIFFORDER = 1 }; + static string Name() { return "gradboundary"; } + static Array GetDimensions() { return Array ( { DIM_SPACE, DIM_SPACE } ); } static constexpr double eps() { return 1e-6; } diff -Nru ngsolve-6.2.2102/fem/hcurlfe.cpp ngsolve-6.2.2103/fem/hcurlfe.cpp --- ngsolve-6.2.2102/fem/hcurlfe.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hcurlfe.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -255,6 +255,105 @@ } + + template + list> HCurlFiniteElement :: Timing () const + { + list>timings; + IntegrationRule ir(ElementType(), 2*Order()); + SIMD_IntegrationRule simdir(ElementType(), 2*Order()); + + constexpr int DIMC = D*(D-1)/2; + Matrix<> shape(GetNDof(),D); + Vector<> coefs(GetNDof()); + Vector<> values(ir.Size()); + Matrix<> dvalues(ir.Size(), DIMC); + Matrix> avalues(D,simdir.Size()); + Matrix> advalues(DIMC, simdir.Size()); + Matrix> simd_shapes(DIMC*GetNDof(), simdir.Size()); + FE_ElementTransformation trafo(ElementType()); + static LocalHeap lh (10000000, "FE - Timing"); + HeapReset hr(lh); + // auto & mir = trafo(ir, lh); + auto & simdmir = trafo(simdir, lh); + + coefs = 1; + + double maxtime = 0.5; + double time; + + constexpr size_t steps = 1000; + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> CalcShape(ir[0], shape); + }); + timings.push_back(make_tuple("CalcShape", time/D/steps*1e9/GetNDof())); + + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> CalcMappedShape(simdmir, simd_shapes); + }); + timings.push_back(make_tuple("CalcShape (SIMD)", time/D/steps*1e9/(simdir.GetNIP()*GetNDof()))); + + /* + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> Evaluate(ir, coefs, values); + }, maxtime); + timings.push_back(make_tuple("Evaluate",time/steps*1e9/(GetNDof()*ir.GetNIP()))); + */ + + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> Evaluate(simdmir, coefs, avalues); + }, maxtime); + timings.push_back(make_tuple("Evaluate(SIMD)", time/D/steps*1e9/(GetNDof()*ir.GetNIP()))); + + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> EvaluateCurl(ir, coefs, dvalues); + }, maxtime); + timings.push_back(make_tuple("Evaluate Curl", time/DIMC/steps*1e9/(D*GetNDof()*ir.GetNIP()))); + + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> EvaluateCurl(simdmir, coefs, advalues); + }, maxtime); + timings.push_back(make_tuple("Evaluate Curl(SIMD)", time/DIMC/steps*1e9/(D*GetNDof()*ir.GetNIP()))); + + /* + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> EvaluateTrans(ir, values, coefs); + }, maxtime); + timings.push_back(make_tuple("Evaluate Trans", time/steps*1e9/(GetNDof()*ir.GetNIP()))); + */ + + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> AddTrans(simdmir, avalues, coefs); + }, maxtime); + timings.push_back(make_tuple("Evaluate Trans (SIMD)", time/D/steps*1e9/(GetNDof()*ir.GetNIP()))); + + /* + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> EvaluateCurlTrans(ir, dvalues, coefs); + }, maxtime); + timings.push_back(make_tuple("Evaluate Trans Curl", time/steps*1e9/(D*GetNDof()*ir.GetNIP()))); + */ + + time = RunTiming([&]() { + for (size_t i = 0; i < steps; i++) + this -> AddCurlTrans(simdmir, advalues, coefs); + }, maxtime); + timings.push_back(make_tuple("Evaluate Trans Curl(SIMD)", time/DIMC/steps*1e9/(D*GetNDof()*ir.GetNIP()))); + + return timings; + } + + + template void HCurlFiniteElement :: ComputeEdgeMoments (int enr, ScalarFiniteElement<1> & testfe, diff -Nru ngsolve-6.2.2102/fem/hcurlfe.hpp ngsolve-6.2.2103/fem/hcurlfe.hpp --- ngsolve-6.2.2102/fem/hcurlfe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hcurlfe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -212,6 +212,9 @@ /// void ComputeVolMoments (HDivFiniteElement<3> & testfe, FlatMatrix<> moments, int order, int shape = 1) const; + + + NGS_DLL_HEADER virtual std::list> Timing () const override; }; diff -Nru ngsolve-6.2.2102/fem/hcurlhdiv_dshape.hpp ngsolve-6.2.2103/fem/hcurlhdiv_dshape.hpp --- ngsolve-6.2.2102/fem/hcurlhdiv_dshape.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hcurlhdiv_dshape.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -74,6 +74,60 @@ } } + + template + void ApplyDShapeFE(const FEL & fel, const MappedIntegrationPoint& mip, const TVX & x, TVY & y, LocalHeap& lh, double eps = 1e-4) + { + const IntegrationPoint& ip = mip.IP(); + const ElementTransformation & eltrans = mip.GetTransformation(); + Mat shape_ul; + Mat shape_ur; + Mat shape_ull; + Mat shape_urr; + Mat dshape_u_ref; + + Vec dshape_u_ref_comp; + Vec dshape_u; + + for (int j = 0; j < DIM; j++) // d / dxj + { + IntegrationPoint ipl(ip); + ipl(j) -= eps; + IntegrationPoint ipr(ip); + ipr(j) += eps; + IntegrationPoint ipll(ip); + ipll(j) -= 2*eps; + IntegrationPoint iprr(ip); + iprr(j) += 2*eps; + + MappedIntegrationPoint mipl(ipl, eltrans); + MappedIntegrationPoint mipr(ipr, eltrans); + MappedIntegrationPoint mipll(ipll, eltrans); + MappedIntegrationPoint miprr(iprr, eltrans); + + fel.EvaluateMappedShape (mipl, x, shape_ul); + fel.EvaluateMappedShape (mipr, x, shape_ur); + fel.EvaluateMappedShape (mipll, x, shape_ull); + fel.EvaluateMappedShape (miprr, x, shape_urr); + + dshape_u_ref = (1.0/(12.0*eps)) * (8.0*shape_ur-8.0*shape_ul-shape_urr+shape_ull); + + for (int l = 0; l < DIM_STRESS; l++) + y(j*DIM_STRESS+l) = dshape_u_ref(l); + } + + for (int j = 0; j < DIM_STRESS; j++) + { + for (int l = 0; l < DIM; l++) + dshape_u_ref_comp(l) = y(l*DIM_STRESS+j); + + dshape_u = Trans(mip.GetJacobianInverse()) * dshape_u_ref_comp; + + for (int l = 0; l < DIMSPACE; l++) + y(l*DIM_STRESS+j) = dshape_u(l); + } + } + template void ApplyTransDShapeFE(const FEL & fel_u, const MappedIntegrationPoint& mip, const TVX & x, TVY & by, LocalHeap & lh, double eps = 1e-4) { @@ -195,7 +249,7 @@ { constexpr size_t BS = 64; // number of simd-points size_t maxnp = min2(BS, bmir.Size()); - size_t size = (maxnp+1)*SIMD::Size()*500; + size_t size = (maxnp+1)*SIMD::Size()*500 + 5*DIM_STRESS*BS*sizeof(SIMD); STACK_ARRAY(char, data, size); LocalHeap lh(data, size); diff -Nru ngsolve-6.2.2102/fem/hcurlhofe_impl.hpp ngsolve-6.2.2103/fem/hcurlhofe_impl.hpp --- ngsolve-6.2.2102/fem/hcurlhofe_impl.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hcurlhofe_impl.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -140,7 +140,7 @@ //Nedelec low order edge shape function shape[0] = uDv_minus_vDu (lam[e[0]], lam[e[1]]); - int p = order_cell[0]; + int p = order_edge[0]; //order_cell[0]; //HO-Edge shapes (Gradient Fields) if(p > 0 && usegrad_cell) { diff -Nru ngsolve-6.2.2102/fem/hdiv_equations.hpp ngsolve-6.2.2103/fem/hdiv_equations.hpp --- ngsolve-6.2.2102/fem/hdiv_equations.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hdiv_equations.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -135,8 +135,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdHDiv"); return -TraceCF(dir->Operator("Grad"))*proxy + dir->Operator("Grad") * proxy; } }; @@ -202,8 +204,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpIdHDivSurface"); return -TraceCF(dir->Operator("Gradboundary"))*proxy + dir->Operator("Gradboundary") * proxy; } @@ -291,8 +295,10 @@ static shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) + shared_ptr dir, + bool Eulerian) { + if (Eulerian) throw Exception("DiffShape Eulerian not implemented for DiffOpDivHDiv"); return -TraceCF(dir->Operator("Grad"))*proxy; } @@ -456,6 +462,41 @@ }; +template +class DiffOpHDivDualSurface : public DiffOp > +{ +public: + enum { DIM = 1 }; + enum { DIM_SPACE = D }; + enum { DIM_ELEMENT = D-1 }; + enum { DIM_DMAT = D }; + enum { DIFFORDER = 0 }; + + typedef DiffOpHDivDualSurface DIFFOP_TRACE; + + + static auto & Cast (const FiniteElement & fel) + { return static_cast&> (fel); } + + + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const MIP & mip, + MAT & mat, LocalHeap & lh) + { + Cast(fel).CalcDualShape (mip, Trans(mat)); + } + template >::value, int>::type = 0> + static void GenerateMatrix (const AFEL & fel, const MIP & mip, + MAT & mat, LocalHeap & lh) + { + throw Exception(string("DiffOpHDivDualSurface not available for mat ")+typeid(mat).name()); + } + + +}; + diff -Nru ngsolve-6.2.2102/fem/hdivfe.cpp ngsolve-6.2.2103/fem/hdivfe.cpp --- ngsolve-6.2.2102/fem/hdivfe.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hdivfe.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -447,7 +447,7 @@ template void HDivFiniteElement :: - CalcDualShape (const MappedIntegrationPoint & mip, SliceMatrix<> shape) const + CalcDualShape (const BaseMappedIntegrationPoint & bmip, SliceMatrix<> shape) const { // throw Exception(string("CalcDualShape not implemented for H(div) element ")+typeid(*this).name()); static bool first = true; diff -Nru ngsolve-6.2.2102/fem/hdivfe.hpp ngsolve-6.2.2103/fem/hdivfe.hpp --- ngsolve-6.2.2102/fem/hdivfe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hdivfe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -140,7 +140,7 @@ virtual void GetFacetDofs(int i, Array & dnums) const; // { cout << " GetFacetDofs for nothing " << endl; dnums.SetSize(0);}; - virtual void CalcDualShape (const MappedIntegrationPoint & mip, SliceMatrix<> shape) const; + virtual void CalcDualShape (const BaseMappedIntegrationPoint & bmip, SliceMatrix<> shape) const; protected: diff -Nru ngsolve-6.2.2102/fem/hdivhofe.cpp ngsolve-6.2.2103/fem/hdivhofe.cpp --- ngsolve-6.2.2102/fem/hdivhofe.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hdivhofe.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -597,8 +597,135 @@ } + template + tuple HDivHighOrderFE :: + GetNDofVEFC() const + { + int nv=0, ne = 0, nf = 0, nc = 0; + if (DIM == 2) + { + // if (only_ho_div) + // { + // if (ET == ET_TRIG) + // { + // ndof = order_inner[0]*(order_inner[0]+1)/2 - 1; + // order = order_inner[0]; + // } + // else + // { + // ndof = order_inner[0]*order_inner[1] + order_inner[0] + order_inner[1]; + // order = max2(order_inner[0], order_inner[1])+1; + // } + // return; + // } + // else + { + ne = ET_trait::N_EDGE; + + for(int i = 0; i < ET_trait::N_EDGE; i++) + ne += order_facet[i][0]; + + if (ET == ET_TRIG) + { + if (order_inner[0] > 1) + { + if (ho_div_free) + nf += order_inner[0]*(order_inner[0]-1)/2; + else + nf += order_inner[0]*order_inner[0]-1; + } + if (RT && order_inner[0] > 0) + nf += order_inner[0] + 1; + } + else + { // quad + INT<2> p(order_inner[0], order_inner[1]); + + int ni = ho_div_free + ? p[0]*p[1] + : 2*p[0]*p[1] + p[0] + p[1]; + + nf += ni; + } + } + } + else + { + + int p = order_inner[0]; + int pc = order_inner[0]; // should be order_inner_curl!!! + int pz = p; // order_inner[2]; + + // if (only_ho_div){ + // switch (ET) + // { + // case ET_TRIG: case ET_QUAD: // for the compiler + // break; + // case ET_TET: + // ndof = p*(p+1)*(p-1)/6 + p*(p-1)/2 + p-1; + // break; + // case ET_PRISM: + // if (order_inner[0]>0 ) + // ndof = (p+1)*(p+2)*(pz+1)/2 - 1; + // /* + // // inner_dof horizontal + // ndof += (order_inner[0]+1)*(3*(order_inner[0]-1)+(order_inner[0]-2)*(order_inner[0]-1)); + // // inner dof vertical + // ndof += (order_inner[0]-1)*(order_inner[0]+1)*(order_inner[0]+2)/2; + // */ + // break; + // case ET_HEX: + // ndof = 3*(p+1)*(p+1)*p; + // break; + // } + // } + // else + { + nf = ET_trait::N_FACE; + + for(int i = 0; i < ET_trait::N_FACE; i++) + { + INT<2> p = order_facet[i]; + if (ET_trait::FaceType(i) == ET_TRIG) + nf += (p[0]*p[0]+3*p[0])/2; + else + nf += p[0]*p[1] + p[0] + p[1]; + } + + switch (ET) + { + case ET_TRIG: case ET_QUAD: // for the compiler + break; + + case ET_TET: + if(pc > 1) + nc += pc*(pc+1)*(pc-1)/3 + pc*(pc-1)/2; + if(p > 1 && !ho_div_free) + nc += p*(p+1)*(p-1)/6 + p*(p-1)/2 + p-1; + if(RT && p >= 1) + nc += (p+1)*(p+2)/2; + break; + + case ET_PRISM: + // SZ: ATTENTION PRISM up to now only using for order_inner[0] !! + if (order_inner[0]>0 ) + { + nc += (p+2)*p*(pz+1) + (p+1)*(p+2)*pz/2; + if (ho_div_free) + nc -= (p+1)*(p+2)*(pz+1)/2 - 1; + } + break; + case ET_HEX: + nc += 3*(p+1)*(p+1)*p; + if (ho_div_free) + nc -= p*p*p+3*p*p+3*p; + break; + } + } + } - + return { nv, ne, nf, nc }; + } template diff -Nru ngsolve-6.2.2102/fem/hdivhofe.hpp ngsolve-6.2.2103/fem/hdivhofe.hpp --- ngsolve-6.2.2102/fem/hdivhofe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hdivhofe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -46,6 +46,8 @@ using VertexOrientedFE::vnums; using VertexOrientedFE::GetVertexOrientedFace; public: + using VertexOrientedFE::SetVertexNumbers; + T_HDivHighOrderNormalFiniteElement () { for (int i = 0; i < ET_trait::N_VERTEX; i++) @@ -402,7 +404,9 @@ virtual void CalcNormalShape (const IntegrationPoint & ip, SliceVector<> nshape) const override; - virtual void CalcDualShape (const MappedIntegrationPoint & mip, SliceMatrix<> shape) const override; + virtual void CalcDualShape (const BaseMappedIntegrationPoint & bmip, SliceMatrix<> shape) const override; + + virtual tuple GetNDofVEFC () const override; }; diff -Nru ngsolve-6.2.2102/fem/hdivhofe_impl.hpp ngsolve-6.2.2103/fem/hdivhofe_impl.hpp --- ngsolve-6.2.2102/fem/hdivhofe_impl.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/hdivhofe_impl.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -220,15 +220,17 @@ INT<2> e = GetEdgeSort (i, vnums); T xi = lam[e[1]]-lam[e[0]]; Vec<2,T> tauref = pnts[e[1]] - pnts[e[0]]; - + Vec<2,T> nvref = Vec<2,T>(tauref[1],-tauref[0]); // Vec<2,T> nv = Trans(mip.GetJacobianInverse())*nvref; // original version - broken with curved elements - Vec<2,T> nv = L2Norm(tauref) / L2Norm(mip.GetJacobian()*tauref) * Cof(mip.GetJacobian()) * nvref; // new version + // Vec<2,T> nv = L2Norm(tauref) / L2Norm(mip.GetJacobian()*tauref) * Cof(mip.GetJacobian()) * nvref; // new version + auto nv = L2Norm(nvref) / L2Norm(Trans(mip.GetJacobianInverse())*nvref) * Trans(mip.GetJacobianInverse())*nvref; // latest version, see TET for derivation + LegendrePolynomial::Eval (p, xi, SBLambda([&] (size_t nr, T val) { - Vec<2,T> vshape = val * nv; + auto vshape = val * nv; if (nr==0) shape[i] = vshape; else @@ -543,11 +545,20 @@ T eta = lam[fav[1]]-lam[fav[2]]; Vec<3,T> tauref1 = pnts[fav[1]] - pnts[fav[0]]; Vec<3,T> tauref2 = pnts[fav[2]] - pnts[fav[0]]; - - - Vec<3,T> nvref = Cross(tauref1,tauref2); - // Vec<3,T> nv = Trans(mip.GetJacobianInverse())*nvref; // old version - broken with curved elements - Vec<3,T> nv = L2Norm(nvref) / L2Norm(Cross(mip.GetJacobian()*tauref1, mip.GetJacobian()*tauref2)) * Cof(mip.GetJacobian()) * nvref; // new version + Vec<3,T> nvref = Cross(tauref1,tauref2); + + //Vec<3,T> nv = Trans(mip.GetJacobianInverse())*nvref; // old version - broken with curved elements + //Vec<3,T> nv = L2Norm(nvref) / L2Norm(Cross(mip.GetJacobian()*tauref1, mip.GetJacobian()*tauref2)) * Cof(mip.GetJacobian()) * nvref; // new version + + // Rewrite new version: use often that Cof(F) = Det(F)*F^{-T} + // Cross(F*tauref1, F*tauref2): Cross(F*tauref1,F*tauref2)*v = Det(F*tauref1,F*tauref2,v) = Det(F)*Det(tauref1,tauref2,F^{-1}v) = Det(F)F^{-T}Cross(tauref1,tauref2)*v = Cof(F)*nvref*v + // -> Cross(F*tauref1, F*tauref2) = Cof(F)*nvref + // -> nv = L2Norm(nvref) / L2Norm(Cof(F)*nvref) * Cof(F) * nvref; + // 1/L2Norm(Cof(F)*nvref) * Cof(F)*nvref = Det(F)/Det(F) * 1/L2Norm(Cof(F)*nvref) * Cof(F)*nvref = 1/L2Norm(1/Det(F)*Cof(F)*nvref) * 1/Det(F)*Cof(F)*nvref + // = 1/L2Norm(F^{-T}*nvref) * F^{-T}*nvref + // -> nv = L2Norm(nvref)/L2Norm(F^{-T}*nvref) * F^{-T}*nvref + Vec<3,T> nv = L2Norm(nvref) / L2Norm(Trans(mip.GetJacobianInverse())*nvref) * Trans(mip.GetJacobianInverse())*nvref; // latest version + DubinerBasis::Eval(order_facet[i][0], xi, eta, SBLambda([&] (size_t nr, auto val) { @@ -1076,11 +1087,20 @@ template void HDivHighOrderFE :: - CalcDualShape (const MappedIntegrationPoint & mip, SliceMatrix<> shape) const + CalcDualShape (const BaseMappedIntegrationPoint & bmip, SliceMatrix<> shape) const { shape = 0.0; - static_cast*> (this) - -> CalcDualShape2 (mip, SBLambda([shape] (size_t i, Vec val) { shape.Row(i) = val; })); + Switch<4-DIM> + (bmip.DimSpace()-DIM,[this,&bmip,shape](auto CODIM) + { + auto & mip = static_cast&> (bmip); + + static_cast*> (this) + -> CalcDualShape2 (mip, SBLambda([shape] (size_t i, auto val) + { + shape.Row(i) = val; + })); + }); } diff -Nru ngsolve-6.2.2102/fem/integratorcf.hpp ngsolve-6.2.2103/fem/integratorcf.hpp --- ngsolve-6.2.2102/fem/integratorcf.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/integratorcf.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -99,6 +99,9 @@ auto tang = TangentialVectorCF(dir->Dimension(), false); tang -> SetDimensions( Array ( { dir->Dimension(), 1 } ) ); auto bsdivdir = InnerProduct(sgrad*tang,tang); + + DiffShapeCF shape; + cout << "should add Eulerian here" << endl; for (auto & icf : icfs) { @@ -106,17 +109,17 @@ { case VOL: if (icf->dx.element_vb == VOL) - deriv->icfs += make_shared ( icf->cf->Diff(shape.get(), dir) + divdir*icf->cf, icf->dx); + deriv->icfs += make_shared ( icf->cf->Diff(&shape, dir) + divdir*icf->cf, icf->dx); else throw Exception("In DiffShape: for vb=VOL only element_vb=VOL implemented!"); break; case BND: if (icf->dx.element_vb == VOL) - deriv->icfs += make_shared ( icf->cf->Diff(shape.get(), dir) + sdivdir*icf->cf, icf->dx); + deriv->icfs += make_shared ( icf->cf->Diff(&shape, dir) + sdivdir*icf->cf, icf->dx); else if (icf->dx.element_vb == BND && dir->Dimension() == 3) - deriv->icfs += make_shared ( icf->cf->Diff(shape.get(), dir) + bsdivdir*icf->cf, icf->dx); + deriv->icfs += make_shared ( icf->cf->Diff(&shape, dir) + bsdivdir*icf->cf, icf->dx); else if (icf->dx.element_vb == BND && dir->Dimension() == 2) - deriv->icfs += make_shared ( icf->cf->Diff(shape.get(), dir), icf->dx); + deriv->icfs += make_shared ( icf->cf->Diff(&shape, dir), icf->dx); else throw Exception("In DiffShape: for vb=BND something went wrong!"); break; diff -Nru ngsolve-6.2.2102/fem/intrule.cpp ngsolve-6.2.2103/fem/intrule.cpp --- ngsolve-6.2.2102/fem/intrule.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/intrule.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -509,6 +509,8 @@ auto & mip = hmips[i]; Vec<3> tau = mip.GetJacobian() * tau_ref; mip.SetMeasure(L2Norm(tau)); + tau /= L2Norm(tau); + mip.SetTV(tau); } return; } @@ -4126,6 +4128,9 @@ template class SIMD>; template class SIMD>; + template class SIMD>; + template class SIMD>; + template class SIMD>; } diff -Nru ngsolve-6.2.2102/fem/l2hofe.cpp ngsolve-6.2.2103/fem/l2hofe.cpp --- ngsolve-6.2.2102/fem/l2hofe.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofe.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -15,7 +15,7 @@ template<> ScalarFiniteElement<2> * CreateL2HighOrderFE (int order, FlatArray vnums, Allocator & lh) { - DGFiniteElement<2> * hofe = new (lh) L2HighOrderFE (order); + DGFiniteElement * hofe = new (lh) L2HighOrderFE (order); for (int j = 0; j < 4; j++) hofe->SetVertexNumber (j, vnums[j]); return hofe; diff -Nru ngsolve-6.2.2102/fem/l2hofefo.hpp ngsolve-6.2.2103/fem/l2hofefo.hpp --- ngsolve-6.2.2102/fem/l2hofefo.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofefo.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -162,7 +162,7 @@ using ScalarFiniteElement::ndof; using ScalarFiniteElement::order; - using DGFiniteElement::vnums; + using DGFiniteElement::vnums; public: diff -Nru ngsolve-6.2.2102/fem/l2hofe.hpp ngsolve-6.2.2103/fem/l2hofe.hpp --- ngsolve-6.2.2102/fem/l2hofe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -44,7 +44,7 @@ template , - class BASE = T_ScalarFiniteElement::DIM> > > + class BASE = T_ScalarFiniteElement > > class L2HighOrderFE : public BASE, public ET_trait { @@ -58,7 +58,7 @@ using ET_trait::PolDimension; using ScalarFiniteElement::ndof; using ScalarFiniteElement::order; - using DGFiniteElement::vnums; + using DGFiniteElement::vnums; INT order_inner; @@ -216,27 +216,27 @@ namespace ngfem { L2HOFE_EXTERN template class L2HighOrderFE; - L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_POINT, DGFiniteElement<0> >; + L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_POINT, DGFiniteElement >; extern template class L2HighOrderFE; - extern template class T_ScalarFiniteElement, ET_SEGM, DGFiniteElement<1> >; + extern template class T_ScalarFiniteElement, ET_SEGM, DGFiniteElement >; extern template class L2HighOrderFE; - extern template class T_ScalarFiniteElement, ET_TRIG, DGFiniteElement<2> >; + extern template class T_ScalarFiniteElement, ET_TRIG, DGFiniteElement >; L2HOFE_EXTERN template class L2HighOrderFE; - L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_QUAD, DGFiniteElement<2> >; + L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_QUAD, DGFiniteElement >; extern template class L2HighOrderFE; - extern template class T_ScalarFiniteElement, ET_TET, DGFiniteElement<3> >; + extern template class T_ScalarFiniteElement, ET_TET, DGFiniteElement >; L2HOFE_EXTERN template class L2HighOrderFE; L2HOFE_EXTERN template class L2HighOrderFE; L2HOFE_EXTERN template class L2HighOrderFE; - L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_PRISM, DGFiniteElement<3> >; - L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_PYRAMID, DGFiniteElement<3> >; - L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_HEX, DGFiniteElement<3> >; + L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_PRISM, DGFiniteElement >; + L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_PYRAMID, DGFiniteElement >; + L2HOFE_EXTERN template class T_ScalarFiniteElement, ET_HEX, DGFiniteElement >; } #endif diff -Nru ngsolve-6.2.2102/fem/l2hofe_impl.hpp ngsolve-6.2.2103/fem/l2hofe_impl.hpp --- ngsolve-6.2.2102/fem/l2hofe_impl.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofe_impl.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -51,7 +51,7 @@ } Matrix<> * trace = new Matrix<>(nf, ndof); - DGFiniteElement::CalcTraceMatrix (f, *trace); + DGFiniteElement::CalcTraceMatrix (f, *trace); precomp_trace.Set (INT<2> (order, classnr), trace); } #endif @@ -69,7 +69,7 @@ return; Matrix<> * gmat = new Matrix<>(ndof*DIM, ndof); - DGFiniteElement::CalcGradientMatrix (*gmat); + DGFiniteElement::CalcGradientMatrix (*gmat); precomp_grad.Set (INT<2> (order, classnr), gmat); #endif } @@ -180,7 +180,7 @@ } else #endif - DGFiniteElement::GetGradient (coefs, grad); + DGFiniteElement::GetGradient (coefs, grad); } template @@ -199,7 +199,7 @@ } else #endif - DGFiniteElement::GetGradientTrans (grad, coefs); + DGFiniteElement::GetGradientTrans (grad, coefs); } @@ -225,7 +225,7 @@ } else #endif - DGFiniteElement::GetTrace (facet, coefs, fcoefs); + DGFiniteElement::GetTrace (facet, coefs, fcoefs); } template @@ -242,7 +242,7 @@ } else #endif - DGFiniteElement::GetTraceTrans (facet, fcoefs, coefs); + DGFiniteElement::GetTraceTrans (facet, fcoefs, coefs); } @@ -288,7 +288,7 @@ break; default: - DGFiniteElement::DIM>::GetDiagMassMatrix (mass); + DGFiniteElement::GetDiagMassMatrix (mass); } } @@ -321,7 +321,8 @@ template INLINE void T_CalcDualShape (TIP::DIM,Tx> ip, TFA & shape) const { - T_CalcShape (ip, shape); + if (ip.vb == VOL) + T_CalcShape (ip, shape); } /* diff -Nru ngsolve-6.2.2102/fem/l2hofe_segm.cpp ngsolve-6.2.2103/fem/l2hofe_segm.cpp --- ngsolve-6.2.2102/fem/l2hofe_segm.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofe_segm.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -14,12 +14,12 @@ namespace ngfem { template class L2HighOrderFE; - template class T_ScalarFiniteElement, ET_SEGM, DGFiniteElement<1> >; + template class T_ScalarFiniteElement, ET_SEGM, DGFiniteElement >; template<> ScalarFiniteElement<1> * CreateL2HighOrderFE (int order, FlatArray vnums, Allocator & lh) { - DGFiniteElement<1> * hofe = 0; + DGFiniteElement * hofe = 0; switch (order) { case 0: hofe = new (lh) L2HighOrderFEFO (); break; diff -Nru ngsolve-6.2.2102/fem/l2hofe_tet.cpp ngsolve-6.2.2103/fem/l2hofe_tet.cpp --- ngsolve-6.2.2102/fem/l2hofe_tet.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofe_tet.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -26,14 +26,14 @@ */ template class L2HighOrderFE; - template class T_ScalarFiniteElement, ET_TET, DGFiniteElement<3> >; + template class T_ScalarFiniteElement, ET_TET, DGFiniteElement >; template<> ScalarFiniteElement<3> * CreateL2HighOrderFE (int order, FlatArray vnums, Allocator & lh) { - DGFiniteElement<3> * hofe = nullptr; + DGFiniteElement * hofe = nullptr; if (vnums[0] < vnums[1] && vnums[1] < vnums[2] && vnums[1] < vnums[3]) // if (false) { // new standard orientation diff -Nru ngsolve-6.2.2102/fem/l2hofetp.cpp ngsolve-6.2.2103/fem/l2hofetp.cpp --- ngsolve-6.2.2102/fem/l2hofetp.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofetp.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -336,7 +336,7 @@ // template class L2HighOrderFETP; - template class T_ScalarFiniteElement, ET_QUAD, DGFiniteElement::DIM>>; + template class T_ScalarFiniteElement, ET_QUAD, DGFiniteElement>; // ********************************** HEX **************** diff -Nru ngsolve-6.2.2102/fem/l2hofetp.hpp ngsolve-6.2.2103/fem/l2hofetp.hpp --- ngsolve-6.2.2102/fem/l2hofetp.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofetp.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -824,7 +824,7 @@ template <> // ELEMENT_TYPE ET> class L2HighOrderFETP : - public T_ScalarFiniteElementTP, L2HighOrderFE_Shape, ET_TET, DGFiniteElement::DIM>>, + public T_ScalarFiniteElementTP, L2HighOrderFE_Shape, ET_TET, DGFiniteElement>, public ET_trait { enum { DIM = ET_trait::DIM }; @@ -1047,11 +1047,11 @@ template <> class L2HighOrderFETP : - public T_ScalarFiniteElement, ET_QUAD, DGFiniteElement::DIM>>, + public T_ScalarFiniteElement, ET_QUAD, DGFiniteElement>, public ET_trait { enum { DIM = ET_trait::DIM }; - typedef T_ScalarFiniteElement, ET_QUAD, DGFiniteElement::DIM>> TBASE; + typedef T_ScalarFiniteElement, ET_QUAD, DGFiniteElement> TBASE; public: template L2HighOrderFETP (int aorder, const TA & avnums, Allocator & lh) diff -Nru ngsolve-6.2.2102/fem/l2hofe_trig.cpp ngsolve-6.2.2103/fem/l2hofe_trig.cpp --- ngsolve-6.2.2102/fem/l2hofe_trig.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/l2hofe_trig.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -26,14 +26,14 @@ template class L2HighOrderFE; - template class T_ScalarFiniteElement, ET_TRIG, DGFiniteElement<2> >; + template class T_ScalarFiniteElement, ET_TRIG, DGFiniteElement >; //constexpr int MAX_FO_TRIG = 2; template<> ScalarFiniteElement<2> * CreateL2HighOrderFE (int order, FlatArray vnums, Allocator & lh) { - DGFiniteElement<2> * hofe = nullptr; + DGFiniteElement * hofe = nullptr; // now we orient trigs such that the first vertex is the lowest if (vnums[0] < vnums[1] && vnums[0] < vnums[2] ) diff -Nru ngsolve-6.2.2102/fem/newtonCF.cpp ngsolve-6.2.2103/fem/newtonCF.cpp --- ngsolve-6.2.2102/fem/newtonCF.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/newtonCF.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -1,215 +1,1127 @@ /*********************************************************************/ /* File: newtonCF.cpp */ -/* Author: Joachim Schoeberl */ +/* Authors: Joachim Schoeberl, Matthias Rambausek */ /* Date: Feb 2021 */ /*********************************************************************/ +#include #include +#include -namespace ngfem -{ +namespace ngfem { - class MinimizationCF : public CoefficientFunction - { - shared_ptr expression; - shared_ptr startingpoint; - - ProxyFunction * proxy = nullptr; - Array cachecf; - public: - MinimizationCF (shared_ptr aexpression, - shared_ptr astartingpoint) - : expression(aexpression), startingpoint(astartingpoint) - { - SetDimensions (startingpoint->Dimensions()); - - expression->TraverseTree - ( [&] (CoefficientFunction & nodecf) - { - auto nodeproxy = dynamic_cast (&nodecf); - if (nodeproxy) - { - if (!nodeproxy->IsTestFunction()) - { - if (proxy && proxy != nodeproxy) throw Exception("MinimizeCF: only one proxy allowed"); - proxy = nodeproxy; - } +namespace { +template auto LInfNorm(const T &array) -> auto { + using number_t = remove_reference_t>; + number_t s = 0; + for (const number_t item : array) { + if (isnan(item)) + return numeric_limits::quiet_NaN(); + s = abs(item) > s ? abs(item) : s; + } + return s; +} + +bool has_vs_embedding(const ProxyFunction *proxy) { + return proxy->Evaluator()->GetVSEmbedding().has_value(); +} + +auto get_vs_embedding(const ProxyFunction *proxy) { + return proxy->Evaluator()->GetVSEmbedding(); +} + +int proxy_dof_dimension(const ProxyFunction *proxy) { + if (const auto vsemb = get_vs_embedding(proxy)) + return vsemb->Width(); + else + return proxy->Dimension(); +} + +} // namespace + +// TODO: (general) +// * Interpolation into generic compound spaces does not work as expected +// (only one component is respected) +// * How to handle consistent linearizations? This is probably a bigger topic +// because there is also no support for nonlinear equations at the FEM level +// (only nonlinear energies...). One could mix the linearization from an +// incremental variational principle with the evolution of via a general +// nonlinear equation. The effect on the convergence might not be huge in +// most cases. If it is, a smaller time step might be a good idea anyway. + +class NewtonCF : public CoefficientFunction { + shared_ptr expression; + Array> startingpoints{}; + + Array proxies{}; + Array cachecf{}; + + // The total dimension of the linear system (because of VS embeddings, this + // can be different from this->Dimension()) + int numeric_dim = 0; + int full_dim = 0; + Array proxy_dims{}; + + // Same parameters as for scipy's newton + // Alternatively, could one think of ParameterCFs here? + double tol{1e-8}; + double rtol{0.0}; + int maxiter{10}; + +public: + NewtonCF(shared_ptr aexpression, + shared_ptr astartingpoint, + std::optional atol, std::optional artol, + std::optional amaxiter) + : NewtonCF{aexpression, + Array>{astartingpoint}, atol, + artol, amaxiter} {} + + NewtonCF(shared_ptr aexpression, + const Array> &astartingpoints, + std::optional atol, std::optional artol, + std::optional amaxiter) + : expression(aexpression) { + + // NOTES: + + // All proxies must originate from one FE space. However, there is no way to + // check this. Available information for proxies: + // - block index: via Proxy Evaluator if this can be cast to a + // CompoundDifferentialOperator + // - block size: via Proxy Evaluator + // - dimension: should be the same as block size? + // - dims: array with dimensions for each axis + + // For the CF (starting point): + // - dim, dims (misleading for GF of CompoundFESpace) + // - components (CFs) for GF of CompoundFESpace + // --> provide a sequence of stps or use components of a GF + + // Strategy: + // 1. If more that one proxy has been found, sort proxies by block index; + // only allow each block index appear exactly once. + // IOW, two different proxies with for some reason same block index are + // forbidden. + // 2. Determine cumulated dimensions of collected proxies and compare + // them with dimensions of startingpoints. + // 4. Call SetDimensions with the appropriate information. + + // NOTE: GFs on generic CompoundSpaces do not provide useful/usable + // dimension data! They are currently not supported. For that, newtonCF.cpp + // would have to be part of "comp" instead of "fem" + + expression->TraverseTree([&](CoefficientFunction &nodecf) { + auto nodeproxy = dynamic_cast(&nodecf); + if (nodeproxy) { + if (!nodeproxy->IsTestFunction()) { + if (std::find(cbegin(proxies), cend(proxies), nodeproxy) == + cend(proxies)) + proxies.Append(nodeproxy); + } + } else if (nodecf.StoreUserData() && !cachecf.Contains(&nodecf)) + cachecf.Append(&nodecf); + }); + if (proxies.Size() == 0) + throw Exception("NewtonCF: don't have a proxy"); + else if (proxies.Size() > 1) { + // Check whether all proxies belong to a compound FE space and put them in + // order + Array sorted_proxies(proxies.Size()); + sorted_proxies = nullptr; + Array diffops(proxies.Size()); + diffops = nullptr; + // cout << "\n" << "sorted proxies " << sorted_proxies + // << "\n" << "diffops " << diffops << endl; + + for (const auto proxy : proxies) { + const auto evaluator = + dynamic_cast( + proxy->Evaluator().get()); + if (!evaluator) { + throw Exception( + "NewtonCF: More than one proxy has been found but not all proxy " + "evaluators are of type CompoundDifferentialOperator"); + } else { + if (sorted_proxies[evaluator->Component()] || + std::find(cbegin(diffops), cend(diffops), evaluator) != + cend(diffops)) + throw Exception("NewtonCF: A proxy evaluator (component) has been " + "detected twice"); + diffops[evaluator->Component()] = evaluator; + sorted_proxies[evaluator->Component()] = proxy; + } + } + // Copy over... + std::copy(begin(sorted_proxies), end(sorted_proxies), begin(proxies)); + } + + // Process proxy dimensions + for (const auto proxy : proxies) { + numeric_dim += proxy_dof_dimension(proxy); + full_dim += proxy->Dimension(); + const auto pdims = proxy->Dimensions(); + if (pdims.Size() > 0) + for (auto dim : pdims) + proxy_dims.Append(dim); + else + proxy_dims.Append(proxy->Dimension()); + } + + if (expression->Dimension() != full_dim) + throw Exception(string("NewtonCF: dimension of residual expression (=") + + to_string(expression->Dimension()) + + ") does not match the accumulated dimension of detected " + "trial functions (=" + + to_string(full_dim) + ")"); + + // Process startingpoints + + /* + // if we want that we should move it to comp - level ??? + // Handle GF on CompoundFESpace + if (astartingpoints.Size() == 1 && astartingpoints[0]->Dimension() == 1 && + proxies.Size() > 1) { + const auto startingpoint_gf = + dynamic_pointer_cast(astartingpoints[0]); + if (!startingpoint_gf) + throw Exception("NewtonCF: number of trial functions greater than one " + "requires a GridFunction with corresponding components " + "as starting point"); + + if (proxies.Size() != startingpoint_gf->GetNComponents()) + throw Exception(string("NewtonCF: number of proxies (=") + + to_string(proxies.Size()) + + ") does not match the number " + "of components of the 'startingpoint' (=" + + to_string(startingpoint_gf->GetNComponents()) + ")"); + + startingpoints.DeleteAll(); + for (int i : Range(startingpoint_gf->GetNComponents())) + startingpoints.Append(startingpoint_gf->GetComponent(i)); + + } else + */ + startingpoints = astartingpoints; + + // Check dimensions and/or fill empty startingpoints + if (startingpoints.Size() == 0) { + for (const auto proxy : proxies) + startingpoints.Append(ZeroCF(proxy->Dimensions())); + } else if (startingpoints.Size() == proxies.Size()) { + for (int i : Range(proxies)) { + if (!startingpoints[i]) + startingpoints[i] = ZeroCF(proxies[i]->Dimensions()); + else if (!(proxies[i]->Dimensions() == startingpoints[i]->Dimensions())) + throw Exception(std::string("NewtonCF: Dimensions of component ") + + std::to_string(i) + " do not agree"); + } + } else if (startingpoints.Size() == 1) { + if (startingpoints[0]->Dimension() != full_dim) + throw Exception( + string("NewtonCF: Total dimension of startingpoints (=") + + to_string(startingpoints[0]->Dimension()) + + ") does not match the accumulated dimension of trial " + "functions (=" + + to_string(full_dim) + ")"); + } else + throw Exception(string("NewtonCF: Number of given startingpoints (=") + + to_string(startingpoints.Size()) + + ") does not match " + "number of detected proxies (=" + + to_string(proxies.Size()) + ")"); + + if (proxies.Size() == 1) + CoefficientFunction::SetDimensions( + FlatArray{proxy_dims.Size(), proxy_dims.Data()}); + else { + Array dims; + dims.Append(full_dim); + CoefficientFunction::SetDimensions(dims); + } + + // Process options + if (atol) + tol = *atol; + if (artol) + rtol = *artol; + if (amaxiter) + maxiter = *amaxiter; + } + + double Evaluate(const BaseMappedIntegrationPoint &ip) const override { + cout << "pw eval not overloaded" << endl; + return 0; + } + + void Evaluate(const BaseMappedIntegrationRule &mir, + BareSliceMatrix values) const override { + // static Timer t("NewtonCF::Eval", 2); + // static Timer t1("NewtonCF::Eval get Jac", 2); + // static Timer t2("NewtonCF::Eval solve", 2); + // ThreadRegionTimer reg(t, TaskManager::GetThreadId()); + // RegionTracer regtr(TaskManager::GetThreadId(), t); + + // cout << "eval minimization" << endl; + + LocalHeap lh(1000000); + + // startingpoint -> Evaluate (mir, values); + // cout << "starting: " << endl << values.AddSize(Dimension(), ir.Size()) << + // endl; + + const ElementTransformation &trafo = mir.GetTransformation(); + auto saved_ud = trafo.PushUserData(); + + ProxyUserData ud(proxies.Size(), cachecf.Size(), lh); + for (CoefficientFunction *cf : cachecf) + ud.AssignMemory(cf, mir.Size(), cf->Dimension(), lh); + + const_cast(trafo).userdata = &ud; + + for (ProxyFunction *proxy : proxies) + ud.AssignMemory(proxy, mir.Size(), proxy->Dimension(), lh); + + // Prepare data structures for blocks + const auto nblocks = proxies.Size(); + FlatArray> xk_blocks(nblocks, lh); + FlatArray> w_blocks(nblocks, lh); + FlatArray> xold_blocks(nblocks, lh); + FlatArray> val_blocks(nblocks, lh); + FlatArray>> dval_blocks(nblocks, lh); + FlatArray> deriv_blocks(nblocks, lh); + FlatArray> res_blocks(nblocks, lh); + FlatArray> lin_blocks(nblocks * nblocks, lh); + + // These are only "independent" for blocks having "vsemb"; otherwise just + // views + FlatArray> rhs_blocks(nblocks, lh); + FlatArray> lhs_blocks(nblocks * nblocks, lh); + + for (int i : Range(nblocks)) { + const auto proxy = proxies[i]; + xk_blocks[i].Assign(ud.GetMemory(proxy)); + xold_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + w_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + val_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + dval_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + deriv_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + res_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + + if (has_vs_embedding(proxy)) + rhs_blocks[i].AssignMemory(mir.Size(), proxy_dof_dimension(proxy), lh); + else + rhs_blocks[i].AssignMemory(mir.Size(), proxy_dof_dimension(proxy), + res_blocks[i].Data()); + + for (int j : Range(nblocks)) { + const auto ij = i * nblocks + j; + lin_blocks[ij].AssignMemory(lh, mir.Size(), proxies[i]->Dimension(), + proxies[j]->Dimension()); + if (has_vs_embedding(proxies[i]) || has_vs_embedding(proxies[j])) + lhs_blocks[ij].AssignMemory(lh, mir.Size(), + proxy_dof_dimension(proxies[i]), + proxy_dof_dimension(proxies[j])); + else + lhs_blocks[ij].Assign(lin_blocks[ij]); + } + } + + // Block-agnostic data structures + FlatMatrix<> xk(mir.Size(), full_dim, lh); + FlatMatrix<> xold(mir.Size(), full_dim, lh); + FlatMatrix<> w(mir.Size(), full_dim, lh); + FlatMatrix<> val(mir.Size(), full_dim, lh); + FlatMatrix> dval(mir.Size(), full_dim, lh); + + FlatVector<> rhs(numeric_dim, lh); + FlatVector<> sol(numeric_dim, lh); + FlatMatrix<> lhs(numeric_dim, numeric_dim, lh); + + const auto converged = [&](const auto &rhs_vec, double res_0 = 0) { + const auto res = LInfNorm(rhs_vec); + return res <= tol || (res_0 > 0 && (res / res_0) <= rtol); + }; + + const auto all_converged = [&](const auto &rhs_blocks, double res_0 = 0) { + return std::all_of(begin(rhs_blocks), end(rhs_blocks), + [=](const auto &block) { + return converged(block.AsVector(), res_0); + }); + }; + + const auto distribute_vec_to_blocks = [&](const auto &src, + auto &dest) -> void { + for (size_t qi : Range(mir)) { + auto src_qi = src.Row(qi); + int offset = 0; + for (int block : Range(nblocks)) { + auto dest_qi = dest[block].Row(qi); + dest_qi = src_qi.Range(offset, offset + dest_qi.Size()); + offset += dest_qi.Size(); + } + } + }; + + const auto calc_residuals = [&]() -> void { + // RegionTracer regtr1(TaskManager::GetThreadId(), t1); + expression->Evaluate(mir, val); + distribute_vec_to_blocks(val, val_blocks); + + for (int block : Range(nblocks)) { + auto proxy = proxies[block]; + auto &res = res_blocks[block]; + auto &rhs = rhs_blocks[block]; + auto &valb = val_blocks[block]; + + for (int k : Range(proxy->Dimension())) + for (size_t qi : Range(mir)) + res(qi, k) = valb(qi, k); + + // The actual rhs (respecting VS embeddings) + if (auto vsemb = get_vs_embedding(proxy); vsemb) + for (size_t qi : Range(mir)) + rhs.Row(qi) = Trans(vsemb.value()) * res.Row(qi); + + // cout << "res block " << block << " = " << res << endl; + } + }; + + const auto calc_linearizations = [&]() -> void { + // RegionTracer regtr2(TaskManager::GetThreadId(), t2); + for (int block2 : Range(nblocks)) { + auto proxy2 = proxies[block2]; + + for (int l : Range(proxy2->Dimension())) { + // This means, the derivative is taken wrt proxy 2 + ud.trialfunction = proxy2; + ud.trial_comp = l; + expression->Evaluate(mir, dval); + distribute_vec_to_blocks(dval, dval_blocks); + + for (int block1 : Range(nblocks)) { + auto proxy1 = proxies[block1]; + auto &dvalb = dval_blocks[block1]; + auto &deriv = deriv_blocks[block1]; + auto &lin = lin_blocks[block1 * nblocks + block2]; + for (int k : Range(proxy1->Dimension())) { + for (size_t qi : Range(mir)) { + deriv(qi, k) = dvalb(qi, k).DValue(0); } - else if (nodecf.StoreUserData() && !cachecf.Contains(&nodecf)) - cachecf.Append (&nodecf); - }); - if (!proxy) throw Exception("MinimizedCF: don't have a proxy"); - } - - - double Evaluate (const BaseMappedIntegrationPoint & ip) const override - { - cout << "pw eval not overloaded" << endl; - return 0; - } - - void Evaluate (const BaseMappedIntegrationRule & mir, - BareSliceMatrix values) const override - { - // static Timer t("MinimizationCF::Eval", 2); - // static Timer t1("MinimizationCF::Eval get Jac", 2); - // static Timer t2("MinimizationCF::Eval solve", 2); - // ThreadRegionTimer reg(t, TaskManager::GetThreadId()); - // RegionTracer regtr(TaskManager::GetThreadId(), t); - - // cout << "eval minimizatin" << endl; - LocalHeap lh(1000000); - - // startingpoint -> Evaluate (mir, values); - // cout << "starting: " << endl << values.AddSize(Dimension(), ir.Size()) << endl; - - const ElementTransformation & trafo = mir.GetTransformation(); - - ProxyUserData ud(1, cachecf.Size(), lh); - for (CoefficientFunction * cf : cachecf) - ud.AssignMemory (cf, mir.Size(), cf->Dimension(), lh); - - const_cast(trafo).userdata = &ud; - // ud.fel = &fel; // how do I get that ? looks like we don't need it anymore ??? - ud.AssignMemory (proxy, mir.Size(), proxy->Dimension(), lh); - - FlatMatrix xk { ud.GetMemory(proxy) }; - - startingpoint -> Evaluate (mir, xk); - // cout << "starting value = " << ud.GetMemory(proxy) << endl; - - - FlatMatrix<> dderiv(mir.Size(), 1,lh); - FlatMatrix> ddval(mir.Size(), 1, lh); - - FlatMatrix<> diags(mir.Size(), proxy->Dimension(), lh); - FlatMatrix<> dWdB(mir.Size(), proxy->Dimension(), lh); - - FlatMatrix<> w(mir.Size(), proxy->Dimension(), lh); - FlatMatrix<> xold(mir.Size(), proxy->Dimension(), lh); - - for (int step = 0; step < 5; step++) - { - double energy = 0; - - auto proxy1 = proxy; - auto proxy2 = proxy; - FlatTensor<3> proxyvalues(lh, mir.Size(), proxy2->Dimension(), proxy1->Dimension()); - - - { - // RegionTracer regtr1(TaskManager::GetThreadId(), t1); - for (int k = 0; k < proxy->Dimension(); k++) - { - ud.trialfunction = proxy; - ud.trial_comp = k; - ud.testfunction = proxy; - ud.test_comp = k; - expression -> Evaluate (mir, ddval); - for (size_t i = 0; i < mir.Size(); i++) - diags(i,k) = ddval(i,0).DDValue(0); - for (size_t i = 0; i < mir.Size(); i++) - dWdB(i,k) = ddval(i,0).DValue(0); - - if (k == 0) - for (size_t i = 0; i < mir.Size(); i++) - energy += ddval(i,0).Value(); } - - for (int k = 0; k < proxy1->Dimension(); k++) - for (int l = 0; l < proxy2->Dimension(); l++) - { - ud.trialfunction = proxy1; - ud.trial_comp = k; + lin(STAR, STAR, l) = deriv; + // cout << "lin block (" << block1 << ", " << block2 << ")[*, *, " + // << l << "] = " << lin(STAR, STAR, l) << endl; + } + // cout << "lin block (" << block1 << ", " << block2 + // << ") = " << lin << endl; + } + } + }; + + const auto compute_increments = [&]() -> void { + for (size_t qi : Range(mir)) { + + // NOTE: when to skip something because of convergence? + // -> the current approach assumes that evaluation of "expression" + // for all qpoints at once is beneficial! + + int offset1 = 0; + for (int block1 : Range(proxies)) { + const auto proxy1 = proxies[block1]; + const auto &rhsb = rhs_blocks[block1].Row(qi); + + for (int k : Range(rhsb.Size())) + rhs[offset1 + k] = rhsb[k]; + + int offset2 = 0; + for (int block2 : Range(proxies)) { + const auto proxy2 = proxies[block2]; + const auto &linb = + lin_blocks[block1 * nblocks + block2](qi, STAR, STAR); + const auto &lhsb = + lhs_blocks[block1 * nblocks + block2](qi, STAR, STAR); + if (auto vsemb1 = get_vs_embedding(proxy1); vsemb1) + if (auto vsemb2 = get_vs_embedding(proxy2); vsemb2) { + lhsb = Trans(vsemb1.value()) * linb * vsemb2.value(); + } else { + lhsb = Trans(vsemb1.value()) * linb; + } + else if (auto vsemb2 = get_vs_embedding(proxy2); vsemb2) { + lhsb = linb * vsemb2.value(); + } else { + // nothing to do + } + + // cout << "lhs block (" << block1 << ", " << block2 << ") = " + // << lhsb << endl; + for (int k : Range(lhsb.Height())) + for (int l : Range(lhsb.Width())) + lhs(offset1 + k, offset2 + l) = lhsb(k, l); + + offset2 += lhsb.Width(); + } + offset1 += rhsb.Size(); + } + + if (converged(rhs)) { + w.Row(qi) = 0; + continue; + } + + // cout << "RHS: " << rhs << endl; + // cout << "LHS: " << lhs << endl; + CalcInverse(lhs); + sol = lhs * rhs; + + // Handle VS-embedding + auto &wi = w.Row(qi); + int offset_w = 0; + int offset_sol = 0; + for (int block : Range(proxies)) { + const auto proxy = proxies[block]; + if (const auto vsemb = get_vs_embedding(proxy); vsemb) + wi.Range(offset_w, offset_w + proxy->Dimension()) = + vsemb.value() * + sol.Range(offset_sol, offset_sol + proxy_dof_dimension(proxy)); + else + wi.Range(offset_w, offset_w + proxy->Dimension()) = + sol.Range(offset_sol, offset_sol + proxy_dof_dimension(proxy)); + offset_w += proxy->Dimension(); + offset_sol += proxy_dof_dimension(proxy); + } + } + }; + + const auto merge_xk_blocks = [&]() -> void { + for (size_t qi : Range(mir)) { + auto xk_qi = xk.Row(qi); + int offset = 0; + for (int block : Range(this->proxies)) { + auto xkb_qi = xk_blocks[block].Row(qi); + xk_qi.Range(offset, offset + xkb_qi.Size()) = xkb_qi; + offset += xkb_qi.Size(); + } + } + }; + + // Evaluate starting point + if (startingpoints.Size() == proxies.Size()) { + for (int i : Range(startingpoints)) + startingpoints[i]->Evaluate(mir, xk_blocks[i]); + merge_xk_blocks(); + } else { + // This is the only case when we should end up here (checked in + // constructor) + assert(startingpoints.Size() == 1); + + startingpoints[0]->Evaluate(mir, xk); + distribute_vec_to_blocks(xk, xk_blocks); + } + + // cout << "starting value = " << xk << endl; + // cout << "blocks:" << endl; + // for (int i : Range(proxies)) + // cout << i << " -> " << ud.GetMemory(proxies[i]) << endl; + // cout << endl; + + // The actual algorithm + // cout << + // "\n\n------------------------START------------------------------" + // "\n"; + + calc_residuals(); + + // cout << "(pre) rhs blocks: " << rhs_blocks; + + for (int step : Range(maxiter)) { + if (all_converged(rhs_blocks)) + break; + + calc_linearizations(); + compute_increments(); + + xk -= w; + // cout << "xk: " << xk << endl; + distribute_vec_to_blocks(xk, xk_blocks); + calc_residuals(); + // cout << "\nstep: " << step << "\n" + // << "rhs blocks: " << rhs_blocks; + } + + // cout << "rhs blocks (final): " << rhs_blocks; + // cout << "xk (final): " << xk << endl; + + if (!all_converged(rhs_blocks)) + xk = numeric_limits::quiet_NaN(); + + // cout << "result = " << xk << endl; + values.AddSize(mir.Size(), full_dim) = xk; + // cout << + // "\n--------------------- NewtonCF done ---------------------------\n"; + } +}; + +class MinimizationCF : public CoefficientFunction { + + shared_ptr expression; + Array> startingpoints{}; + + Array proxies{}; + Array cachecf{}; + + // The total dimension of the linear system (because of VS embeddings, this + // can be different from this->Dimension()). + int numeric_dim = 0; + int full_dim = 0; + Array proxy_dims{}; + + // Same parameters as for scipy's newton + // Alternatively, could one think of ParameterCFs here? + double tol{1e-8}; + double rtol{0.0}; + int maxiter{10}; + +public: + MinimizationCF(shared_ptr aexpression, + shared_ptr astartingpoint, + std::optional atol, std::optional artol, + std::optional amaxiter) + : MinimizationCF{aexpression, + Array>{astartingpoint}, + atol, artol, amaxiter} {} + + MinimizationCF(shared_ptr aexpression, + const Array> &astartingpoints, + std::optional atol, std::optional artol, + std::optional amaxiter) + : expression(aexpression) { + + expression->TraverseTree([&](CoefficientFunction &nodecf) { + auto nodeproxy = dynamic_cast(&nodecf); + if (nodeproxy) { + if (!nodeproxy->IsTestFunction()) { + if (std::find(cbegin(proxies), cend(proxies), nodeproxy) == + cend(proxies)) + proxies.Append(nodeproxy); + } + } else if (nodecf.StoreUserData() && !cachecf.Contains(&nodecf)) + cachecf.Append(&nodecf); + }); + if (proxies.Size() == 0) + throw Exception("MinimizationCF: don't have a proxy"); + else if (proxies.Size() > 1) { + // Check whether all proxies belong to a compound FE space and put them in + // order + Array sorted_proxies(proxies.Size()); + sorted_proxies = nullptr; + Array diffops(proxies.Size()); + diffops = nullptr; + // cout << "\n" << "sorted proxies " << sorted_proxies + // << "\n" << "diffops " << diffops << endl; + + for (const auto proxy : proxies) { + const auto evaluator = + dynamic_cast( + proxy->Evaluator().get()); + if (!evaluator) { + throw Exception( + "MinimizationCF: More than one proxy has been found but not all " + "proxy " + "evaluators are of type CompoundDifferentialOperator"); + } else { + if (sorted_proxies[evaluator->Component()] || + std::find(cbegin(diffops), cend(diffops), evaluator) != + cend(diffops)) + throw Exception( + "MinimizationCF: A proxy evaluator (component) has been " + "detected twice"); + diffops[evaluator->Component()] = evaluator; + sorted_proxies[evaluator->Component()] = proxy; + } + } + // Copy over... + std::copy(begin(sorted_proxies), end(sorted_proxies), begin(proxies)); + } + + // Process proxy dimensions + for (const auto proxy : proxies) { + numeric_dim += proxy_dof_dimension(proxy); + full_dim += proxy->Dimension(); + const auto pdims = proxy->Dimensions(); + if (pdims.Size() > 0) + for (auto dim : pdims) + proxy_dims.Append(dim); + else + proxy_dims.Append(proxy->Dimension()); + } + + if (expression->Dimension() != 1) + throw Exception(string("MinimizationCF: only scalar expressions are allowed")); + + // Process startingpoints + + /* + // then we shold move to to comp level ??? + // Handle GF on CompoundFESpace + if (astartingpoints.Size() == 1 && astartingpoints[0]->Dimension() == 1 && + proxies.Size() > 1) { + const auto startingpoint_gf = + dynamic_pointer_cast(astartingpoints[0]); + if (!startingpoint_gf) + throw Exception( + "MinimizationCF: number of trial functions greater than one " + "requires a GridFunction with corresponding components " + "as starting point"); + + if (proxies.Size() != startingpoint_gf->GetNComponents()) + throw Exception(string("MinimizationCF: number of proxies (=") + + to_string(proxies.Size()) + + ") does not match the number " + "of components of the 'startingpoint' (=" + + to_string(startingpoint_gf->GetNComponents()) + ")"); + + startingpoints.DeleteAll(); + for (int i : Range(startingpoint_gf->GetNComponents())) + startingpoints.Append(startingpoint_gf->GetComponent(i)); + + } else + */ + startingpoints = astartingpoints; + + // Check dimensions and/or fill empty startingpoints + if (startingpoints.Size() == 0) { + for (const auto proxy : proxies) + startingpoints.Append(ZeroCF(proxy->Dimensions())); + } else if (startingpoints.Size() == proxies.Size()) { + for (int i : Range(proxies)) { + if (!startingpoints[i]) + startingpoints[i] = ZeroCF(proxies[i]->Dimensions()); + else if (!(proxies[i]->Dimensions() == + startingpoints[i]->Dimensions())) + throw Exception( + std::string("MinimizationCF: Dimensions of startingpoint " + "and proxy component ") + + std::to_string(i) + " do not agree"); + } + } else if (startingpoints.Size() == 1) { + if (startingpoints[0]->Dimension() != full_dim) + throw Exception( + string("MinimizationCF: Total dimension of startingpoints (=") + + to_string(startingpoints[0]->Dimension()) + + ") does not match the accumulated dimension of trial " + "functions (=" + + to_string(full_dim) + ")"); + } else + throw Exception(string("MinimizationCF: Number of given startingpoints (=") + + to_string(startingpoints.Size()) + + ") does not match " + "number of detected proxies (=" + + to_string(proxies.Size()) + ")"); + + if (proxies.Size() == 1) + CoefficientFunction::SetDimensions( + FlatArray{proxy_dims.Size(), proxy_dims.Data()}); + else { + Array dims; + dims.Append(full_dim); + CoefficientFunction::SetDimensions(dims); + } + + // Process options + if (atol) + tol = *atol; + if (artol) + rtol = *artol; + if (amaxiter) + maxiter = *amaxiter; + } + + double Evaluate(const BaseMappedIntegrationPoint &ip) const override { + cout << "pw eval not overloaded" << endl; + return 0; + } + + void Evaluate(const BaseMappedIntegrationRule &mir, + BareSliceMatrix values) const override { + // static Timer t("MinimizationCF::Eval", 2); + // static Timer t1("MinimizationCF::Eval get Jac", 2); + // static Timer t2("MinimizationCF::Eval solve", 2); + // ThreadRegionTimer reg(t, TaskManager::GetThreadId()); + // RegionTracer regtr(TaskManager::GetThreadId(), t); + + // cout << "eval minimization" << endl; + + LocalHeap lh(1000000); + + const ElementTransformation &trafo = mir.GetTransformation(); + auto saved_ud = trafo.PushUserData(); + + ProxyUserData ud(proxies.Size(), cachecf.Size(), lh); + for (CoefficientFunction *cf : cachecf) + ud.AssignMemory(cf, mir.Size(), cf->Dimension(), lh); + + const_cast(trafo).userdata = &ud; + + for (ProxyFunction *proxy : proxies) + ud.AssignMemory(proxy, mir.Size(), proxy->Dimension(), lh); + + // Prepare data structures for blocks + const auto nblocks = proxies.Size(); + FlatArray> xk_blocks(nblocks, lh); + FlatArray> w_blocks(nblocks, lh); + FlatArray> xold_blocks(nblocks, lh); + FlatArray> diags_blocks(nblocks, lh); + FlatArray> res_blocks(nblocks, lh); + FlatArray> lin_blocks(nblocks * nblocks, lh); + + // These are only "independent" for blocks having "vsemb"; otherwise just + // views + FlatArray> rhs_blocks(nblocks, lh); + FlatArray> lhs_blocks(nblocks * nblocks, lh); + + for (int i : Range(nblocks)) { + const auto proxy = proxies[i]; + xk_blocks[i].Assign(ud.GetMemory(proxy)); + xold_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + w_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + diags_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + res_blocks[i].AssignMemory(mir.Size(), proxy->Dimension(), lh); + + if (has_vs_embedding(proxy)) + rhs_blocks[i].AssignMemory(mir.Size(), proxy_dof_dimension(proxy), lh); + else + rhs_blocks[i].AssignMemory(mir.Size(), proxy_dof_dimension(proxy), + res_blocks[i].Data()); + + for (int j : Range(nblocks)) { + const auto ij = i * nblocks + j; + lin_blocks[ij].AssignMemory(lh, mir.Size(), proxies[i]->Dimension(), + proxies[j]->Dimension()); + if (has_vs_embedding(proxies[i]) || has_vs_embedding(proxies[j])) + lhs_blocks[ij].AssignMemory(lh, mir.Size(), + proxy_dof_dimension(proxies[i]), + proxy_dof_dimension(proxies[j])); + else + lhs_blocks[ij].Assign(lin_blocks[ij]); + } + } + + // Block-agnostic data structures + double energy = 0; + FlatMatrix<> dderiv(mir.Size(), 1, lh); + FlatMatrix> ddval(mir.Size(), 1, lh); + FlatMatrix<> xk(mir.Size(), full_dim, lh); + FlatMatrix<> xold(mir.Size(), full_dim, lh); + FlatMatrix<> w(mir.Size(), full_dim, lh); + FlatVector<> rhs(numeric_dim, lh); + FlatVector<> sol(numeric_dim, lh); + FlatMatrix<> lhs(numeric_dim, numeric_dim, lh); + + const auto converged = [&](const auto &rhs_vec, double res_0 = 0) { + const auto res = LInfNorm(rhs_vec); + return res <= tol || (res_0 > 0 && (res / res_0) <= rtol); + }; + + const auto all_converged = [&](const auto &rhs_blocks, double res_0 = 0) { + return std::all_of(begin(rhs_blocks), end(rhs_blocks), + [=](const auto &block) { + return converged(block.AsVector(), res_0); + }); + }; + + const auto distribute_vec_to_blocks = [&](const auto &src, + auto &dest) -> void { + for (size_t qi : Range(mir)) { + auto src_qi = src.Row(qi); + int offset = 0; + for (int block : Range(nblocks)) { + auto dest_qi = dest[block].Row(qi); + dest_qi = src_qi.Range(offset, offset + dest_qi.Size()); + offset += dest_qi.Size(); + } + } + }; + + + const auto calc_energy_rhs_and_diags = [&]() -> void { + energy = 0; + for (int block : Range(nblocks)) { + auto proxy = proxies[block]; + auto &res = res_blocks[block]; + auto &rhsb = rhs_blocks[block]; + auto &diags = diags_blocks[block]; + + for (int k : Range(proxy->Dimension())) { + ud.trialfunction = proxy; + ud.trial_comp = k; + ud.testfunction = proxy; + ud.test_comp = k; + + expression->Evaluate(mir, ddval); + for (size_t qi : Range(mir)) + diags(qi, k) = ddval(qi, 0).DDValue(0); + for (size_t qi : Range(mir)) + res(qi, k) = ddval(qi, 0).DValue(0); + + if (k == 0 && block == 0) + for (size_t qi : Range(mir)) + energy += mir[qi].GetWeight() * ddval(qi, 0).Value(); + } + + // The actual rhs (respecting VS embeddings) + if (auto vsemb = get_vs_embedding(proxy); vsemb) + for (size_t qi : Range(mir)) + rhsb.Row(qi) = Trans(vsemb.value()) * res.Row(qi); + + // cout << "res block " << block << " = " << res << endl; + } + }; + + + const auto calc_off_diagonals = [&]() -> void { + // NOTE: this computes only one triangle of the matrix, whereby the diagonal + // blocks are fully set if there is a VS embedding! + for (auto l1 : Range(nblocks)) { + for (auto k1 : Range(l1, nblocks)) { + + auto proxy1 = proxies[k1]; + auto proxy2 = proxies[l1]; + auto &lin = lin_blocks[l1 * nblocks + k1]; +// auto &linT = lin_blocks[k1 * nblocks + l1]; + + for (auto l : Range(proxy2->Dimension())) { + + for (auto k : Range(proxy1 == proxy2 ? l : 0, proxy1->Dimension())) { + + if (proxy1 == proxy2 && k == l) + lin(STAR, k, k) = diags_blocks[k1].Col(k); + else { // computed mixed second derivatives ud.testfunction = proxy2; ud.test_comp = l; - - { - expression -> Evaluate (mir, ddval); - for (size_t i = 0; i < mir.Size(); i++) - dderiv(i,0) = ddval(i,0).DDValue(0); - } - proxyvalues(STAR,l,k) = dderiv.Col(0); - - if (proxy1 != proxy2 || k != l) // computed mixed second derivatives - { - proxyvalues(STAR,l,k) -= diags.Col(k); - proxyvalues(STAR,l,k) -= diags.Col(l); - proxyvalues(STAR,l,k) *= 0.5; - } + ud.trialfunction = proxy1; + ud.trial_comp = k; + + expression->Evaluate(mir, ddval); + for (size_t qi : Range(mir)) + dderiv(qi, 0) = ddval(qi, 0).DDValue(0); + + lin(STAR, l, k) = dderiv.Col(0); + lin(STAR, l, k) -= diags_blocks[k1].Col(k); + lin(STAR, l, k) -= diags_blocks[l1].Col(l); + lin(STAR, l, k) *= 0.5; + + if (proxy1 == proxy2 && get_vs_embedding(proxy1)) + lin(STAR, k, l) = lin(STAR, l, k); } + // cout << "lin block (" << k1 << ", " << l1 << ")[*, *, " + // << l << "] = " << lin(STAR, STAR, l) << endl; + } } - // cout << "hessions = " << proxyvalues << endl; - // cout << "gradients = " << dWdB << endl; - - // newton step - // RegionTracer regtr2(TaskManager::GetThreadId(), t2); - // cout << "proxy diffop = " << typeid(* (proxy->Evaluator())).name() << endl; - if (auto vsemb = proxy->Evaluator()->GetVSEmbedding(); vsemb) - { - for (int i = 0; i < mir.Size(); i++) - { - Matrix mat = proxyvalues(i, STAR,STAR); - Vector rhs = dWdB.Row(i); - - Vector proj_rhs = Trans(*vsemb) * rhs; - Matrix proj_mat = Trans(*vsemb) * mat * *vsemb; - Vector proj_sol(proj_rhs.Size()); - - // cout << "mat = " << mat << ", projmat = " << proj_mat << endl; - CalcInverse (proj_mat); - proj_sol = proj_mat * proj_rhs; - w.Row(i) = *vsemb * proj_sol; - // cout << "sol = " << proj_sol << endl; +// cout << "lin block (" << l1 << ", " << k1 +// << ") = " << lin << endl; + } + } + }; + + const auto compute_newton_step = [&]() -> void { + for (size_t qi : Range(mir)) { + + // NOTE: when to skip something because of convergence? + // -> the current approach assumes that evaluation of "expression" + // for all qpoints at once is beneficial! + + int offset1 = 0; + for (size_t block1 : Range(nblocks)) { + const auto proxy1 = proxies[block1]; + const auto &rhsb = rhs_blocks[block1].Row(qi); + + for (int k : Range(rhsb.Size())) + rhs[offset1 + k] = rhsb[k]; + + int offset2 = offset1; + for (size_t block2 : Range(block1, nblocks)) { + const auto proxy2 = proxies[block2]; + const auto &linb = + lin_blocks[block1 * nblocks + block2](qi, STAR, STAR); + const auto &lhsb = + lhs_blocks[block1 * nblocks + block2](qi, STAR, STAR); + + if (auto vsemb1 = get_vs_embedding(proxy1); vsemb1) + if (auto vsemb2 = get_vs_embedding(proxy2); vsemb2) { + lhsb = Trans(vsemb1.value()) * linb * vsemb2.value(); + } else { + lhsb = Trans(vsemb1.value()) * linb; + } + else if (auto vsemb2 = get_vs_embedding(proxy2); vsemb2) { + lhsb = linb * vsemb2.value(); + } else { + // nothing to do + } + +// cout << "lhs block (" << block1 << ", " << block2 << ") = " +// << lhsb << endl; + // Fill q-point LHS with exploitation of symmetry. Unfortunately, + // CalcInverse does not respect symmetry yet. + for (auto k : Range(lhsb.Height())) { + if (offset1 == offset2) { + lhs(offset1 + k, offset1 + k) = lhsb(k, k); + for (auto l : Range(k + 1, lhsb.Width())) { + lhs(offset1 + k, offset2 + l) = lhsb(k, l); + lhs(offset2 + l, offset1 + k) = lhsb(k, l); } + } else { + for (auto l : Range(lhsb.Width())) { + lhs(offset1 + k, offset2 + l) = lhsb(k, l); + lhs(offset2 + l, offset1 + k) = lhsb(k, l); + } + } } - + + offset2 += lhsb.Width(); + } + offset1 += rhsb.Size(); + } + + if (converged(rhs)) { + w.Row(qi) = 0; + continue; + } + +// cout << "RHS: " << rhs << endl; +// cout << "LHS: " << lhs << endl; + CalcInverse(lhs); + sol = lhs * rhs; + + // Handle VS-embedding + auto &wi = w.Row(qi); + int offset_w = 0; + int offset_sol = 0; + for (int block : Range(proxies)) { + const auto proxy = proxies[block]; + if (const auto vsemb = get_vs_embedding(proxy); vsemb) + wi.Range(offset_w, offset_w + proxy->Dimension()) = + vsemb.value() * + sol.Range(offset_sol, offset_sol + proxy_dof_dimension(proxy)); else - - for (int i = 0; i < mir.Size(); i++) - { - Matrix mat = proxyvalues(i, STAR,STAR); - Vector rhs = dWdB.Row(i); - Vector sol(rhs.Size()); - CalcInverse (mat); - w.Row(i) = mat * rhs; - // cout << "sol = " << sol << endl; - } + wi.Range(offset_w, offset_w + proxy->Dimension()) = + sol.Range(offset_sol, offset_sol + proxy_dof_dimension(proxy)); + offset_w += proxy->Dimension(); + offset_sol += proxy_dof_dimension(proxy); + } + } + }; - xold = xk; - double alpha = 1; - // linesearch - double newenergy = energy + 1; - - while (newenergy > energy && alpha > 1e-10) - { - xk = xold - alpha * w; - alpha /= 2; - - newenergy = 0; - ud.trialfunction = proxy; - ud.trial_comp = 0; - ud.testfunction = proxy; - ud.test_comp = 0; - expression -> Evaluate (mir, ddval); - for (size_t i = 0; i < mir.Size(); i++) - newenergy += ddval(i,0).Value(); - } + const auto linesearch = [&](auto &ud) -> void { + xold = xk;// linesearch + double alpha = 1; + double newenergy = energy + 1; + + auto proxy = proxies[0]; + ud.trialfunction = proxy; + ud.trial_comp = 0; + ud.testfunction = proxy; + ud.test_comp = 0; + + // cout << "w = " << endl << w << endl; + while (newenergy > energy && alpha > 1e-10) { + xk = xold - alpha * w; + distribute_vec_to_blocks(xk, xk_blocks); + + newenergy = 0; + expression->Evaluate(mir, ddval); + for (size_t qi : Range(mir)) { + newenergy += mir[qi].GetWeight() * ddval(qi, 0).Value(); + } + + // cout << "alpha = " << alpha << ", newen = " << newenergy << endl; + alpha /= 2; + } + }; + + const auto merge_xk_blocks = [&]() -> void { + for (size_t qi : Range(mir)) { + auto xk_qi = xk.Row(qi); + int offset = 0; + for (int block : Range(this->proxies)) { + auto xkb_qi = xk_blocks[block].Row(qi); + xk_qi.Range(offset, offset + xkb_qi.Size()) = xkb_qi; + offset += xkb_qi.Size(); } + } + }; + + // Evaluate starting point + if (startingpoints.Size() == proxies.Size()) { + for (int i : Range(startingpoints)) + startingpoints[i]->Evaluate(mir, xk_blocks[i]); + merge_xk_blocks(); + } else { + // This is the only case when we should end up here (checked in + // constructor) + assert(startingpoints.Size() == 1); - // cout << "result = " << xk << endl; - values.AddSize(mir.Size(), Dimension()) = xk; + startingpoints[0]->Evaluate(mir, xk); + distribute_vec_to_blocks(xk, xk_blocks); } - - }; - + // The actual algorithm +// cout << "\n" << "start newton loop" << "\n"; + calc_energy_rhs_and_diags(); + for (int step = 0; step < maxiter; step++) { + if (all_converged(rhs_blocks)) + break; + + calc_off_diagonals(); + compute_newton_step(); + linesearch(ud); + calc_energy_rhs_and_diags(); +// cout << "newton step " << step + 1 << endl; + } + +// for (int block1 : Range(proxies)) +// cout << "RHS block " << to_string(block1) << ": " << rhs_blocks[block1] << endl; +// +// cout << "MinimizationCF done" << "\n\n"; + if (!all_converged(rhs_blocks)) + xk = numeric_limits::quiet_NaN(); - shared_ptr - CreateMinimizationCF (shared_ptr expression, - shared_ptr startingpoint) - { - return make_shared (expression, startingpoint); + // cout << "result = " << xk << endl; + values.AddSize(mir.Size(), Dimension()) = xk; } +}; + +shared_ptr +CreateMinimizationCF(shared_ptr expression, + shared_ptr startingpoint, + std::optional atol, std::optional rtol, + std::optional maxiter) { + return make_shared(expression, startingpoint, atol, rtol, maxiter); } + +shared_ptr +CreateMinimizationCF(shared_ptr expression, + const Array> &startingpoints, + std::optional tol, std::optional rtol, + std::optional maxiter) { + return make_shared(expression, startingpoints, tol, rtol, maxiter); +} + +shared_ptr +CreateNewtonCF(shared_ptr expression, + shared_ptr startingpoint, + std::optional atol, std::optional rtol, + std::optional maxiter) { + return make_shared(expression, startingpoint, atol, rtol, maxiter); +} + +shared_ptr +CreateNewtonCF(shared_ptr expression, + const Array> &startingpoints, + std::optional tol, std::optional rtol, + std::optional maxiter) { + return make_shared(expression, startingpoints, tol, rtol, maxiter); +} + +} // namespace ngfem diff -Nru ngsolve-6.2.2102/fem/normalfacetfe.cpp ngsolve-6.2.2103/fem/normalfacetfe.cpp --- ngsolve-6.2.2102/fem/normalfacetfe.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/normalfacetfe.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -1129,10 +1129,15 @@ } template - void NormalFacetVolumeFE :: CalcDualShape (const MappedIntegrationPoint & mip, SliceMatrix<> shape) const + void NormalFacetVolumeFE :: CalcDualShape (const BaseMappedIntegrationPoint & bmip, SliceMatrix<> shape) const { shape = 0.0; - this -> CalcDualShape2 (mip, mip.IP().FacetNr(), SBLambda([shape] (size_t i, Vec val) { shape.Row(i) = val; })); + Switch<4-DIM> + (bmip.DimSpace()-DIM,[this,&bmip,shape](auto CODIM) + { + auto & mip = static_cast&> (bmip); + this -> CalcDualShape2 (mip, mip.IP().FacetNr(), SBLambda([shape] (size_t i, auto val) { shape.Row(i) = val; })); + }); } diff -Nru ngsolve-6.2.2102/fem/normalfacetfe.hpp ngsolve-6.2.2103/fem/normalfacetfe.hpp --- ngsolve-6.2.2102/fem/normalfacetfe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/normalfacetfe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -161,7 +161,7 @@ virtual void CalcShape (const IntegrationPoint & ip, int facet, SliceMatrix<> shape) const; using TBASE::CalcDualShape; - virtual void CalcDualShape (const MappedIntegrationPoint & mip, SliceMatrix<> shape) const override; + virtual void CalcDualShape (const BaseMappedIntegrationPoint & bmip, SliceMatrix<> shape) const override; virtual int GetNExtraShapes( int facet) const {return 0;} virtual void CalcExtraShape (const IntegrationPoint & ip, int facet, FlatMatrixFixWidth xshape) const {xshape = 0.0;} diff -Nru ngsolve-6.2.2102/fem/python_fem.cpp ngsolve-6.2.2103/fem/python_fem.cpp --- ngsolve-6.2.2102/fem/python_fem.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/python_fem.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -645,6 +645,11 @@ return VertexTangentialVectorsCF(dim); } + shared_ptr GetEdgeFaceTangentialVectorsCF (int dim) + { + return EdgeFaceTangentialVectorsCF(dim); + } + shared_ptr GetEdgeCurvatureCF (int dim) { return EdgeCurvatureCF(dim); @@ -705,6 +710,9 @@ .def("VertexTangentialVectors", &SpecialCoefficientFunctions::GetVertexTangentialVectorsCF, py::arg("dim"), "VertexTangentialVectors \n" "space-dimension must be provided") + .def("EdgeFaceTangentialVectors", &SpecialCoefficientFunctions::GetEdgeFaceTangentialVectorsCF, py::arg("dim"), + "EdgeFaceTangentialVectors \n" + "space-dimension must be provided") .def("EdgeCurvature", &SpecialCoefficientFunctions::GetEdgeCurvatureCF, py::arg("dim"), "EdgeCurvature \n" "space-dimension must be provided") @@ -755,6 +763,11 @@ if(dims.has_value()) { auto cdims = makeCArray (*dims); + int dimension = 1; + for (int d : cdims) dimension *= d; + if (coef->Dimension() != dimension) + throw Exception("dims does not fit to dimension of CoefficientFunction"); + coef->SetDimensions(cdims); } return coef; @@ -848,6 +861,25 @@ }, py::arg("comp"), "returns component comp of vectorial CF") + .def("__getitem__", [](shared_ptr self, py::slice inds) + { + FlatArray dims = self->Dimensions(); + if (dims.Size() != 1) + throw py::index_error(); + + size_t start, step, n; + InitSlice( inds, dims[0], start, step, n ); + int first = start; + Array num = { int(n) }; + Array dist = { int(step) }; + /* + if (c1 < 0 || c2 < 0 || c1 >= dims[0] || c2 >= dims[1]) + throw py::index_error(); + */ + return MakeSubTensorCoefficientFunction (self, first, move(num), move(dist)); + }, py::arg("components")) + + /* .def("__getitem__", [](shared_ptr self, py::tuple comps) { if (py::len(comps) != 2) @@ -864,6 +896,116 @@ int comp = c1 * dims[1] + c2; return MakeComponentCoefficientFunction (self, comp); }, py::arg("components")) + */ + .def("__getitem__", [](shared_ptr self, tuple comps) + { + FlatArray dims = self->Dimensions(); + if (dims.Size() != 2) + throw py::index_error(); + + auto [c1,c2] = comps; + if (c1 < 0 || c2 < 0 || c1 >= dims[0] || c2 >= dims[1]) + throw py::index_error(); + + int comp = c1 * dims[1] + c2; + return MakeComponentCoefficientFunction (self, comp); + }, py::arg("components")) + + .def("__getitem__", [](shared_ptr self, tuple comps) + { + FlatArray dims = self->Dimensions(); + if (dims.Size() != 2) + throw py::index_error(); + + auto [inds,c2] = comps; + size_t start, step, n; + InitSlice( inds, dims[0], start, step, n ); + int first = start*dims[1]+c2; + Array num = { int(n) }; + Array dist = { int(step)*dims[1] }; + /* + if (c1 < 0 || c2 < 0 || c1 >= dims[0] || c2 >= dims[1]) + throw py::index_error(); + */ + return MakeSubTensorCoefficientFunction (self, first, move(num), move(dist)); + }, py::arg("components")) + + .def("__getitem__", [](shared_ptr self, tuple comps) + { + FlatArray dims = self->Dimensions(); + if (dims.Size() != 2) + throw py::index_error(); + + auto [c1,inds] = comps; + size_t start, step, n; + InitSlice( inds, dims[1], start, step, n ); + // cout << "get row " << c1 << ", start=" << start << ", step = " << step << ", n = " << n << endl; + int first = start+c1*dims[1]; + Array num = { int(n) }; + Array dist = { int(step) }; + /* + if (c1 < 0 || c2 < 0 || c1 >= dims[0] || c2 >= dims[1]) + throw py::index_error(); + */ + return MakeSubTensorCoefficientFunction (self, first, move(num), move(dist)); + }, py::arg("components")) + + .def("__getitem__", [](shared_ptr self, tuple comps) + { + FlatArray dims = self->Dimensions(); + if (dims.Size() != 2) + throw py::index_error(); + + auto [inds1,inds2] = comps; + size_t start1, step1, n1; + InitSlice( inds1, dims[0], start1, step1, n1 ); + size_t start2, step2, n2; + InitSlice( inds2, dims[1], start2, step2, n2 ); + + int first = start1*dims[1]+start2; + Array num = { int(n1), int(n2) }; + Array dist = { int(step1)*dims[1], int(step2) }; + /* + if (c1 < 0 || c2 < 0 || c1 >= dims[0] || c2 >= dims[1]) + throw py::index_error(); + */ + return MakeSubTensorCoefficientFunction (self, first, move(num), move(dist)); + }, py::arg("components")) + + + .def("__getitem__", [](shared_ptr self, tuple comps) + { + FlatArray dims = self->Dimensions(); + if (dims.Size() != 3) + throw py::index_error(); + + auto [c1,c2,c3] = comps; + if (c1 < 0 || c2 < 0 || c3 < 0 || + c1 >= dims[0] || c2 >= dims[1] || c3 >= dims[2]) + throw py::index_error(); + + int comp = (c1 * dims[1] + c2) * dims[2] + c3; + return MakeComponentCoefficientFunction (self, comp); + }, py::arg("components")) + + + .def("__getitem__", [](shared_ptr self, tuple comps) + { + FlatArray dims = self->Dimensions(); + if (dims.Size() != 4) + throw py::index_error(); + + auto [c1,c2,c3,c4] = comps; + if (c1 < 0 || c2 < 0 || c3 < 0 || c4 < 0 || + c1 >= dims[0] || c2 >= dims[1] || c3 >= dims[2] || c4 >= dims[3]) + throw py::index_error(); + + int comp = ((c1 * dims[1] + c2) * dims[2] + c3) * dims[3] + c4; + return MakeComponentCoefficientFunction (self, comp); + }, py::arg("components")) + + + // coefficient expressions .def ("__add__", [] (shared_ptr c1, shared_ptr c2) { return c1+c2; }, py::arg("cf") ) @@ -981,12 +1123,17 @@ "Compute directional derivative with respect to variable", py::arg("variable"), py::arg("direction")=nullptr) - .def ("DiffShape", [] (shared_ptr coef, shared_ptr dir) + .def ("DiffShape", [] (shared_ptr coef, shared_ptr dir, std::vector> Eulerian) { - return coef->Diff (shape.get(), dir); + DiffShapeCF shape; + for (auto gf : Eulerian) + shape.Eulerian_gridfunctions.Append(gf.get()); + return coef->Diff (&shape, dir); + + // return coef->Diff (shape.get(), dir); }, "Compute shape derivative in direction", - py::arg("direction")=1.0) + py::arg("direction")=1.0, py::arg("Eulerian")=std::vector> ()) // it's using the complex functions anyway ... // it seems to take the double-version now @@ -1097,10 +1244,154 @@ m.def("Inv", [] (shared_ptr cf) { return InverseCF(cf); }); m.def("Cof", [] (shared_ptr cf) { return CofactorCF(cf); }); m.def("Det", [] (shared_ptr cf) { return DeterminantCF(cf); }); - m.def("Conj", [] (shared_ptr cf) { return ConjCF(cf); }, "complex-conjugate"); + m.def("Conj", [] (shared_ptr cf) { return ConjCF(cf); }, "complex-conjugate"); + + m.def("MinimizationCF", [](shared_ptr expr, py::object startingpoint, optional tol, + optional rtol, optional maxiter){ + + // First check for a GridFunction. This case is important for GFs on + // (abstract) compound spaces. + py::extract> egf(startingpoint); + if (egf.check()) { + const auto gf = egf(); + if (gf->GetFESpace()->GetEvaluator()) + return CreateMinimizationCF(expr, gf, tol, rtol, maxiter); + else { + // Probably a GF on a generic compound space + Array> stps(gf->GetNComponents()); + for (int comp : Range(stps)) + stps[comp] = gf->GetComponent(comp); + return CreateMinimizationCF(expr, stps, tol, rtol, maxiter); + } + } + + // If the given value is a list or a tuple... This must be handled + // explicitly to prevent implicit conversion to a CoefficientFunction, + // which is problematic when a list of GridFunctions is given. + if (py::isinstance(startingpoint) || py::isinstance(startingpoint)) + { + Array> stps{}; + for (auto val : startingpoint) + { + py::extract> vcf(val); + if (vcf.check()) + stps.Append(vcf()); + else + throw std::invalid_argument( + string("Cannot make CoefficientFunction from ") + + string(py::str(val)) + " of type " + + string(py::str(val.get_type()))); + } + return CreateMinimizationCF(expr, stps, tol, rtol, maxiter); + } + + // Attemp std. conversion to a CoefficientFunction + py::extract> ecf(startingpoint); + if (ecf.check()) + return CreateMinimizationCF(expr, ecf(), tol, rtol, maxiter); + + throw std::invalid_argument( + string("Failed to convert startingpoint ") + + string(py::str(startingpoint)) + + " to a CoefficientFunction"); + }, + py::arg("expression"), py::arg("startingpoint"), py::arg("tol") = 1e-8, + py::arg("rtol") = 0.0, py::arg("maxiter") = 10, docu_string(R"raw_string( +Creates a CoefficientFunction that returns the solution to a minimization problem. +Convergence failure is indicated by returning NaN(s). + +Parameters: + +expression : CoefficientFunction + the objective function to be minimized + +startingpoint: CoefficientFunction, list/tuple of CoefficientFunctions + the initial guess for the iterative solution of the nonlinear problem + +tol: double + absolute tolerance + +rtol: double + relative tolerance + +maxiter: int + maximum iterations + +)raw_string")); + + m.def("NewtonCF", [](shared_ptr expr, py::object startingpoint, optional tol, + optional rtol, optional maxiter){ + + // First check for a GridFunction. This case is important for GFs on + // generic compound spaces. + py::extract> egf(startingpoint); + if (egf.check()) { + const auto gf = egf(); + if (gf->GetFESpace()->GetEvaluator()) + return CreateNewtonCF(expr, gf, tol, rtol, maxiter); + else { + // Probably a GF on a generic compound space + Array> stps(gf->GetNComponents()); + for (int comp : Range(stps)) + stps[comp] = gf->GetComponent(comp); + return CreateNewtonCF(expr, stps, tol, rtol, maxiter); + } + } + + // If the given value is a list or a tuple... This must be handled + // explicitly to prevent implicit conversion to a CoefficientFunction, + // which is problematic when a list of GridFunctions is given. + if (py::isinstance(startingpoint) || py::isinstance(startingpoint)) + { + Array> stps{}; + for (auto val : startingpoint) + { + py::extract> vcf(val); + if (vcf.check()) + stps.Append(vcf()); + else + throw std::invalid_argument( + string("Cannot make CoefficientFunction from ") + + string(py::str(val)) + " of type " + + string(py::str(val.get_type()))); + } + return CreateNewtonCF(expr, stps, tol, rtol, maxiter); + } + + // Attemp std. conversion to a CoefficientFunction + py::extract> ecf(startingpoint); + if (ecf.check()) + return CreateNewtonCF(expr, ecf(), tol, rtol, maxiter); + + throw std::invalid_argument( + string("Failed to convert startingpoint ") + + string(py::str(startingpoint)) + + " to a CoefficientFunction"); + }, + py::arg("expression"), py::arg("startingpoint"), py::arg("tol") = 1e-8, + py::arg("rtol") = 0.0, py::arg("maxiter") = 10, docu_string(R"raw_string( +Creates a CoefficientFunction that returns the solution to a nonlinear problem. +Convergence failure is indicated by returning NaN(s). + +Parameters: + +expression : CoefficientFunction + the residual of the nonlinear equation + +startingpoint: CoefficientFunction, list/tuple of CoefficientFunctions + the initial guess for the iterative solution of the nonlinear problem + +tol: double + absolute tolerance + +rtol: double + relative tolerance + +maxiter: int + maximum iterations + +)raw_string")); - m.def("MinimizationCF", &CreateMinimizationCF); - py::implicitly_convertible(); py::implicitly_convertible(); py::implicitly_convertible(); @@ -2133,7 +2424,7 @@ try { const MixedFiniteElement * mixedfe = dynamic_cast (&fe); - const FiniteElement & fe_trial = mixedfe ? mixedfe->FETrial() : fe; + // const FiniteElement & fe_trial = mixedfe ? mixedfe->FETrial() : fe; const FiniteElement & fe_test = mixedfe ? mixedfe->FETest() : fe; Vector<> vecy(fe_test.GetNDof() * self->GetDimension()); self->ApplyElementMatrix (fe, trafo, vec, vecy, 0, lh); @@ -2451,6 +2742,68 @@ )delimiter"); + const string header = R"CODE( +#include +#include + +using namespace ngcomp; + +extern "C" { + + NGCORE_API_EXPORT void init(py::object & res) + { + static py::module::module_def def; + py::module m = py::module::create_extension_module("", "", &def); + + // BEGIN USER DEFINED CODE + +)CODE"; + const string footer = R"CODE( + // END USER DEFINED CODE + res = m; + } +} +)CODE"; + const string docu = R"raw_string( +Utility function to compile c++ code with python bindings at run-time. + +Parameters: + +code: c++ code snippet ( add_header=True ) or a complete .cpp file ( add_header=False ) + +init_function_name (default = "init"): Function, which is called after the compiled code is loaded. The prototype must match: +extern "C" void init_function_name(py::object & res); + +add_header (default = True): wrap the code snippet with the template +)raw_string" + header + footer; + + m.def("CompilePythonModule", + [header, footer](string code, string init_function_name, bool add_header) + { + py::object result; + typedef void (*init_function_type)(py::object & res); + + if(add_header) + code = header + code + footer; + + std::vector libraries; +#ifdef WIN32 + libraries.push_back("%PYTHON_LIBRARY%"); +#endif + auto library = CompileCode( {code}, {""} ); + auto func = library->GetFunction(init_function_name); + func(result); + library.release(); // TODO: bind lifetime of "library" to python object "result" + return result; + }, + py::arg("code"), + py::arg("init_function_name")="init", + py::arg("add_header")=true, + docu.c_str() + ); + + + } #endif diff -Nru ngsolve-6.2.2102/fem/scalarfe.cpp ngsolve-6.2.2103/fem/scalarfe.cpp --- ngsolve-6.2.2102/fem/scalarfe.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/scalarfe.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -431,6 +431,65 @@ AddGradTrans (ir, values.Rows(i*dim, (i+1)*dim), coefs.Col(i)); } + + + + template + void ScalarFiniteElement :: Interpolate (const ElementTransformation & trafo, + const CoefficientFunction & func, SliceMatrix<> coefs, + LocalHeap & lh) const + { + HeapReset hr(lh); + + FlatMatrix<> elflux(GetNDof(), coefs.Width(), lh); + elflux = 0.0; + + for (int el_vb = D; el_vb >= 0; el_vb--) + { + Facet2ElementTrafo f2el (ElementType(), VorB(el_vb)); + for (int locfnr : Range(f2el.GetNFacets())) + { + SIMD_IntegrationRule irfacet(f2el.FacetType(locfnr), 2 * Order()); + auto & irvol = f2el(locfnr, irfacet, lh); + auto & mir = trafo(irvol, lh); + + FlatMatrix> mfluxi(coefs.Width(), mir.IR().Size(), lh); + func.Evaluate (mir, mfluxi); + + for (size_t j : Range(mir)) + mfluxi.Col(j) *= mir[j].IP().Weight(); + + for (int i = 0; i < coefs.Width(); i++) + AddDualTrans (mir.IR(), mfluxi.Row(i), elflux.Col(i)); + } + } + + for (int i = 0; i < coefs.Width(); i++) + if (!SolveDuality (elflux.Col(i), coefs.Col(i), lh)) + throw Exception("scalar interpolate need solveduality"); + + /* + ... otherwise + { + // Calc Element Matrix + FlatMatrix elmat(fel.GetNDof(), lh); elmat = 0.0; + bool symmetric_so_far = true; + for (auto sbfi : single_bli) + { sbfi->CalcElementMatrixAdd (fel, eltrans, elmat, symmetric_so_far, lh); } + + // Invert Element Matrix and Solve for RHS + CalcInverse(elmat); // Not Symmetric ! + + if (dim > 1) { + for (int j = 0; j < dim; j++) + { elfluxi.Slice (j,dim) = elmat * elflux.Slice (j,dim); } + } + else + { elfluxi = elmat * elflux; } + } + */ + } + template @@ -648,8 +707,6 @@ - - void BaseScalarFiniteElement :: GetDiagMassMatrix (FlatVector<> mass) const @@ -662,8 +719,8 @@ - template - void DGFiniteElement:: + template + void DGFiniteElement:: GetDiagMassMatrix (FlatVector<> mass) const { #ifndef __CUDA_ARCH__ @@ -680,8 +737,8 @@ } - template - void DGFiniteElement:: + template + void DGFiniteElement:: CalcTraceMatrix (int facet, FlatMatrix<> trace) const { ELEMENT_TYPE ftype = ElementTopology::GetFacetType (this->ElementType(), facet); @@ -732,8 +789,8 @@ delete facetfe2; } - template - void DGFiniteElement:: + template + void DGFiniteElement:: CalcGradientMatrix (FlatMatrix<> gmat) const { IntegrationRule ir (this->ElementType(), 2*order); @@ -762,8 +819,8 @@ } - template - void DGFiniteElement:: + template + void DGFiniteElement:: GetGradient (FlatVector<> coefs, FlatMatrixFixWidth grad) const { Matrix<> gmat(D*grad.Height(), coefs.Size()); @@ -771,9 +828,9 @@ FlatVector<> vgrad(gmat.Height(), &grad(0,0)); vgrad = gmat * coefs; } - - template - void DGFiniteElement:: + + template + void DGFiniteElement:: GetGradientTrans (FlatMatrixFixWidth grad, FlatVector<> coefs) const { Matrix<> gmat(D*grad.Height(), coefs.Size()); @@ -781,9 +838,10 @@ FlatVector<> vgrad(gmat.Height(), &grad(0,0)); coefs = Trans (gmat) * vgrad; } + - template - void DGFiniteElement:: + template + void DGFiniteElement:: GetTrace (int facet, FlatVector<> coefs, FlatVector<> fcoefs) const { Matrix<> trace(fcoefs.Size(), coefs.Size()); @@ -791,8 +849,8 @@ fcoefs = trace * coefs; } - template - void DGFiniteElement:: + template + void DGFiniteElement:: GetTraceTrans (int facet, FlatVector<> fcoefs, FlatVector<> coefs) const { Matrix<> trace(fcoefs.Size(), coefs.Size()); @@ -807,12 +865,20 @@ template class ScalarFiniteElement<2>; template class ScalarFiniteElement<3>; - + template class DGFiniteElement; + template class DGFiniteElement; + template class DGFiniteElement; + template class DGFiniteElement; + template class DGFiniteElement; + template class DGFiniteElement; + template class DGFiniteElement; + template class DGFiniteElement; + /* template class DGFiniteElement<0>; template class DGFiniteElement<1>; template class DGFiniteElement<2>; template class DGFiniteElement<3>; - + */ template class T_ScalarFiniteElement,ET_POINT>; diff -Nru ngsolve-6.2.2102/fem/scalarfe.hpp ngsolve-6.2.2103/fem/scalarfe.hpp --- ngsolve-6.2.2102/fem/scalarfe.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/scalarfe.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -123,7 +123,6 @@ HD NGS_DLL_HEADER virtual void GetDiagMassMatrix (FlatVector<> mass) const; NGS_DLL_HEADER virtual bool GetDiagDualityMassInverse (FlatVector<> diag) const { return false; } NGS_DLL_HEADER virtual bool DualityMassDiagonal () const { return false; } - NGS_DLL_HEADER virtual tuple GetNDofVEFC () const { return { 0, 0, 0, 0 }; } }; /** @@ -205,6 +204,10 @@ HD NGS_DLL_HEADER virtual void EvaluateGradTrans (const IntegrationRule & ir, SliceMatrix<> values, SliceMatrix<> coefs) const; + NGS_DLL_HEADER virtual void Interpolate (const ElementTransformation & trafo, + const class CoefficientFunction & func, SliceMatrix<> coefs, + LocalHeap & lh) const override; + public: NGS_DLL_HEADER virtual std::list> Timing () const override; NGS_DLL_HEADER virtual bool SolveDuality (SliceVector<> rhs, SliceVector<> u, LocalHeap & lhr) const override; @@ -229,15 +232,18 @@ - template - class DGFiniteElement : public ScalarFiniteElement + template + class DGFiniteElement : public ScalarFiniteElement::DIM>, + public VertexOrientedFE { protected: - int vnums[1<::DIM }; + using ScalarFiniteElement::ndof; using ScalarFiniteElement::order; - + using VertexOrientedFE::vnums; + public: /// global vertex numbers define ordering of vertices template @@ -280,10 +286,14 @@ SCALARFE_EXTERN template class ScalarFiniteElement<2>; SCALARFE_EXTERN template class ScalarFiniteElement<3>; - SCALARFE_EXTERN template class DGFiniteElement<0>; - SCALARFE_EXTERN template class DGFiniteElement<1>; - SCALARFE_EXTERN template class DGFiniteElement<2>; - SCALARFE_EXTERN template class DGFiniteElement<3>; + SCALARFE_EXTERN template class DGFiniteElement; + SCALARFE_EXTERN template class DGFiniteElement; + SCALARFE_EXTERN template class DGFiniteElement; + SCALARFE_EXTERN template class DGFiniteElement; + SCALARFE_EXTERN template class DGFiniteElement; + SCALARFE_EXTERN template class DGFiniteElement; + SCALARFE_EXTERN template class DGFiniteElement; + SCALARFE_EXTERN template class DGFiniteElement; #endif } diff -Nru ngsolve-6.2.2102/fem/symbolicintegrator.cpp ngsolve-6.2.2103/fem/symbolicintegrator.cpp --- ngsolve-6.2.2102/fem/symbolicintegrator.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/symbolicintegrator.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -781,7 +781,8 @@ shared_ptr ProxyFunction :: Diff (const CoefficientFunction * var, shared_ptr dir) const { - if (var == shape.get()) + //if (var == shape.get()) + if (dynamic_cast(var)) return evaluator->DiffShape (const_cast(this)->shared_from_this(), dir); else if (var == this) return dir; @@ -831,9 +832,14 @@ cf->TraverseTree ([&] (CoefficientFunction & nodecf) { - auto proxy = dynamic_cast (&nodecf); - if (proxy && !proxies.Contains(proxy)) - proxies.Append (proxy); + if (auto proxy = dynamic_cast (&nodecf)) + { + if (!proxies.Contains(proxy)) + proxies.Append (proxy); + } + else + if (nodecf.StoreUserData() && !gridfunction_cfs.Contains(&nodecf)) + gridfunction_cfs.Append (&nodecf); }); for (auto proxy : proxies) @@ -916,7 +922,10 @@ IntegrationRule & ir_facet_vol = transform(k, ir_facet, lh); BaseMappedIntegrationRule & mir = trafo(ir_facet_vol, lh); - ProxyUserData ud; + ProxyUserData ud(0, gridfunction_cfs.Size(), lh); + for (CoefficientFunction * cf : gridfunction_cfs) + ud.AssignMemory (cf, ir_facet.GetNIP(), cf->Dimension(), lh); + const_cast(trafo).userdata = &ud; // mir.ComputeNormalsAndMeasure (eltype, k); @@ -1006,8 +1015,10 @@ FlatVector elvec1(elvec.Size(), lh); FlatMatrix values(ir.Size(), 1, lh); - ProxyUserData ud; + ProxyUserData ud(0, gridfunction_cfs.Size(), lh); const_cast(trafo).userdata = &ud; + for (CoefficientFunction * cf : gridfunction_cfs) + ud.AssignMemory (cf, ir.GetNIP(), cf->Dimension(), lh); elvec = 0; for (auto proxy : proxies) @@ -1099,6 +1110,8 @@ } }); + cache_cfs = FindCacheCF(*cf); + for (auto proxy : trial_proxies) if (!proxy->Evaluator()->SupportsVB(vb)) throw Exception ("Trialfunction does not support "+ToString(vb)+"-forms, maybe a Trace() operator is missing, type = "+proxy->Evaluator()->Name()); @@ -1381,6 +1394,7 @@ ProxyUserData ud; const_cast(trafo).userdata = &ud; + PrecomputeCacheCF(cache_cfs, mir, lh); // bool symmetric_so_far = true; int k1 = 0; diff -Nru ngsolve-6.2.2102/fem/symbolicintegrator.hpp ngsolve-6.2.2103/fem/symbolicintegrator.hpp --- ngsolve-6.2.2102/fem/symbolicintegrator.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/fem/symbolicintegrator.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -602,9 +602,9 @@ virtual shared_ptr DiffShape (shared_ptr proxy, - shared_ptr dir) const override + shared_ptr dir, bool Eulerian) const override { - return diffop->DiffShape(proxy,dir); + return diffop->DiffShape(proxy,dir,Eulerian); } }; @@ -617,6 +617,7 @@ protected: shared_ptr cf; Array proxies; + Array gridfunction_cfs; VorB vb; // bool element_boundary; VorB element_vb; @@ -656,6 +657,7 @@ shared_ptr cf; Array trial_proxies, test_proxies; Array gridfunction_cfs; + Array cache_cfs; Array trial_cum, test_cum; // cumulated dimension of proxies VorB vb; // on the boundary of the domain ? // bool element_boundary; diff -Nru ngsolve-6.2.2102/.gitlab-ci.yml ngsolve-6.2.2103/.gitlab-ci.yml --- ngsolve-6.2.2102/.gitlab-ci.yml 2021-03-19 06:18:08.000000000 +0000 +++ ngsolve-6.2.2103/.gitlab-ci.yml 2021-06-04 23:31:19.000000000 +0000 @@ -128,6 +128,10 @@ stage: build script: - source tests/gitlab-ci/ubuntu/build.sh + artifacts: + when: always + paths: + - logs/ ubuntu_avx_build: <<: *ubuntu_avx diff -Nru ngsolve-6.2.2102/linalg/basematrix.cpp ngsolve-6.2.2103/linalg/basematrix.cpp --- ngsolve-6.2.2102/linalg/basematrix.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/basematrix.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -95,12 +95,19 @@ void BaseMatrix :: Mult (const BaseVector & x, BaseVector & y) const { // y = 0; + if(safety_check & 1) + throw Exception("Mult or MultAdd must be implemented for BaseMatrix!"); y.SetZero(); MultAdd (1, x, y); } void BaseMatrix :: MultTrans (const BaseVector & x, BaseVector & y) const { + if(IsSymmetric().IsTrue()) + { Mult(x, y); return; } + if(safety_check & 2) + throw Exception("MultTransAdd or MultTrans must be implemented for (maybe) not symmetric BaseMatrix!"); + // y = 0; y.SetZero(); MultTransAdd (1, x, y); @@ -110,6 +117,7 @@ { // cout << "Warning: BaseMatrix::MultAdd(double), this = " << typeid(*this).name() << endl; auto temp = y.CreateVector(); + safety_check |= 1; Mult (x, *temp); y += s * *temp; } @@ -123,13 +131,18 @@ throw Exception (err.str()); */ auto temp = y.CreateVector(); + safety_check |= 1; Mult (x, *temp); y += s * *temp; } void BaseMatrix :: MultTransAdd (double s, const BaseVector & x, BaseVector & y) const { + if(IsSymmetric().IsTrue()) + { MultAdd(s, x, y); return; } + auto temp = y.CreateVector(); + safety_check |= 2; MultTrans (x, *temp); y += s * *temp; /* @@ -148,6 +161,10 @@ void BaseMatrix :: MultTransAdd (Complex s, const BaseVector & x, BaseVector & y) const { + if(IsSymmetric().IsTrue()) + { MultAdd(s, x, y); return; } + + safety_check |= 2; auto temp = y.CreateVector(); MultTrans (x, *temp); y += s * *temp; diff -Nru ngsolve-6.2.2102/linalg/basematrix.hpp ngsolve-6.2.2103/linalg/basematrix.hpp --- ngsolve-6.2.2102/linalg/basematrix.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/basematrix.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -23,6 +23,7 @@ { protected: shared_ptr paralleldofs; + mutable char safety_check = 0; protected: /// @@ -51,6 +52,8 @@ return VWidth(); } + virtual xbool IsSymmetric() const { return maybe; } + /// is matrix complex ? virtual bool IsComplex() const { return false; } diff -Nru ngsolve-6.2.2102/linalg/basevector.hpp ngsolve-6.2.2103/linalg/basevector.hpp --- ngsolve-6.2.2102/linalg/basevector.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/basevector.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -86,7 +86,7 @@ /** Base vector for linalg */ - class NGS_DLL_HEADER BaseVector + class NGS_DLL_HEADER BaseVector : public enable_shared_from_this_virtual { protected: /// size of vector @@ -376,13 +376,15 @@ class NGS_DLL_HEADER AutoVector // : public BaseVector { - unique_ptr vec; + shared_ptr vec; public: AutoVector () { ; } AutoVector (AutoVector && av2) : vec(move(av2.vec)) { } // { size = av2.Size(), entrysize = av2.EntrySize(); } + AutoVector (shared_ptr hvec) : vec(hvec) { } + AutoVector (unique_ptr hvec) : vec(move(hvec)) { } // { size = vec->Size(), entrysize = vec->EntrySize(); } @@ -493,9 +495,10 @@ vec->SetScalar (s); return *this; } - - operator unique_ptr () && { return move(vec); } - operator shared_ptr () && { return move(vec); } + + // operator unique_ptr () && { return move(vec); } + // operator shared_ptr () && { return move(vec); } + operator shared_ptr () { return vec; } BaseVector & operator* () { return *vec; } const BaseVector & operator* () const { return *vec; } operator BaseVector & () { return *vec; } @@ -592,16 +595,35 @@ void GetIndirect (FlatArray ind, - FlatVector v) const + FlatVector v) const { vec -> GetIndirect (ind, v); } void GetIndirect (FlatArray ind, - FlatVector v) const + FlatVector v) const { vec -> GetIndirect (ind, v); } + void SetIndirect (FlatArray ind, FlatVector v) + { + vec->SetIndirect (ind,v); + } + void SetIndirect (FlatArray ind, FlatVector v) + { + vec->SetIndirect (ind,v); + } + + void AddIndirect (FlatArray ind, FlatVector v, bool use_atomic = false) + { + vec->AddIndirect (ind, v, use_atomic); + } + void AddIndirect (FlatArray ind, FlatVector v, bool use_atomic = false) + { + vec->AddIndirect (ind, v, use_atomic); + } + + void Cumulate () const { vec -> Cumulate(); } diff -Nru ngsolve-6.2.2102/linalg/paralleldofs.hpp ngsolve-6.2.2103/linalg/paralleldofs.hpp --- ngsolve-6.2.2102/linalg/paralleldofs.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/paralleldofs.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -377,6 +377,7 @@ { shared_ptr pardofs; public: + DofRange () { } DofRange (T_Range range, shared_ptr apardofs) : T_Range(range), pardofs(apardofs) { ; } shared_ptr GetParallelDofs() const { return pardofs; } diff -Nru ngsolve-6.2.2102/linalg/pardisoinverse.cpp ngsolve-6.2.2103/linalg/pardisoinverse.cpp --- ngsolve-6.2.2102/linalg/pardisoinverse.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/pardisoinverse.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -551,7 +551,10 @@ void PardisoInverse :: MultTrans (const BaseVector & x, BaseVector & y) const { - const_cast(hparams[11]) = 1; // Solve transposed matrix + const_cast(hparams[11]) = 2; // Solve transposed matrix + + // See https://software.intel.com/content/www/us/en/develop/documentation/onemkl-developer-reference-c/top/sparse-solver-routines/onemkl-pardiso-parallel-direct-sparse-solver-interface/pardiso-iparm-parameter.html + Mult(x,y); const_cast(hparams[11]) = 0; } diff -Nru ngsolve-6.2.2102/linalg/python_linalg.cpp ngsolve-6.2.2103/linalg/python_linalg.cpp --- ngsolve-6.2.2102/linalg/python_linalg.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/python_linalg.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -317,9 +317,13 @@ .def("__len__", [] (BaseVector &self) { return self.Size(); }) .def_property_readonly("is_complex", &BaseVector::IsComplex) - .def("CreateVector", [] (BaseVector & self) - { return shared_ptr(self.CreateVector()); }, - "creates a new vector of same type, contents is undefined") + .def("CreateVector", [] (BaseVector & self, bool copy) + { + auto newvec = self.CreateVector(); + if (copy) newvec = self; + return shared_ptr(newvec); + }, py::arg("copy")=false, + "creates a new vector of same type, contents is undefined if copy is false") .def("Copy", [] (BaseVector & self) { @@ -439,6 +443,27 @@ throw Exception ("slices with non-unit distance not allowed"); self.Range(start,start+n) = z; }, py::arg("inds"), py::arg("value"), "Set value at given positions" ) + .def("__setitem__", [](BaseVector & self, py::slice inds, shared_ptr v ) + { + size_t start, step, n; + InitSlice( inds, self.Size(), start, step, n ); + if (step != 1) + throw Exception ("slices with non-unit distance not allowed"); + self.Range(start, start+n) = *v; + }, py::arg("inds"), py::arg("vec") ) + .def("__setitem__", [](BaseVector & self, py::slice inds, DynamicVectorExpression expr) + { + size_t start, step, n; + InitSlice( inds, self.Size(), start, step, n ); + if (step != 1) + throw Exception ("slices with non-unit distance not allowed"); + // self.Range(start, start+n) = *v; + expr.AssignTo (1, self.Range(start, start+n)); + }, py::arg("inds"), py::arg("vec") ) + .def("__setitem__", [](BaseVector & self, DofRange range, DynamicVectorExpression expr) + { + expr.AssignTo (1, self.Range(range)); + }, py::arg("inds"), py::arg("vec") ) .def("__setitem__", [](BaseVector & self, IntRange range, double d ) { self.Range(range) = d; @@ -494,7 +519,10 @@ [](shared_ptr self) { return self; }, [](shared_ptr self, DynamicVectorExpression v2) - { v2.AssignTo(1, *self); }) + { + py::gil_scoped_release rel; + v2.AssignTo(1, *self); + }) .def("__add__", [] (shared_ptr a, DynamicVectorExpression b) { return a+b; }) @@ -587,6 +615,14 @@ { return -e1; }) .def("__sub__", [](shared_ptr e1, shared_ptr e2) { return e1-e2; }) + .def("Evaluate", [](shared_ptr exp) + { + auto vec = exp->CreateVector(); + auto mv = make_shared (vec, exp->Size()); + Vector<> ones(exp->Size()); ones = 1.0; + exp->AssignTo(ones, *mv); + return mv; + }) ; py::class_> (m, "MultiVector") @@ -763,7 +799,8 @@ IsComplex, /* Name of function */ ); } - + +#ifdef NONE int VHeight() const override { PYBIND11_OVERLOAD_PURE( int, /* Return type */ @@ -779,14 +816,45 @@ Width, /* Name of function */ ); } +#endif + tuple Shape() const + { + pybind11::gil_scoped_acquire gil; + pybind11::function overload = pybind11::get_overload(this, "Shape"); + if(overload) + return py::cast>(overload()); + else + { + auto height = pybind11::get_overload(this, "Height"); + auto width = pybind11::get_overload(this, "Width"); + if(!height || !width) + throw Exception("Shape must be overloaded in BaseMatrix!"); + return { py::cast(height()), py::cast(width()) }; + } + } + + int VHeight() const override { + return get<0>(Shape()); + } + + int VWidth() const override { + return get<1>(Shape()); + } AutoVector CreateRowVector () const override { py::gil_scoped_acquire gil; + /* pybind11::function overload = pybind11::get_overload(this, "CreateRowVector"); if (overload) { auto vec = py::cast> (overload()); - return vec->CreateVector(); + return vec; // vec->CreateVector(); } + */ + if (auto overload = pybind11::get_overload(this, "CreateRowVector")) + return py::cast> (overload()); + if (auto overload = pybind11::get_overload(this, "CreateVector")) + return py::cast> (overload(false)); + throw Exception ("CreateRowVector not overloaded from python"); // python can only create shared_ptr, create another unique_ptr from C++ #ifdef NONE @@ -800,11 +868,11 @@ AutoVector CreateColVector () const override { py::gil_scoped_acquire gil; - pybind11::function overload = pybind11::get_overload(this, "CreateColVector"); - if (overload) { - auto vec = py::cast> (overload()); - return vec->CreateVector(); - } + // pybind11::function overload = pybind11::get_overload(this, "CreateColVector"); + if (auto overload = pybind11::get_overload(this, "CreateColVector")) + return py::cast> (overload()); + if (auto overload = pybind11::get_overload(this, "CreateVector")) + return py::cast> (overload(true)); throw Exception ("CreateColVector not overloaded from python"); #ifdef NONE PYBIND11_OVERLOAD_PURE( @@ -827,14 +895,14 @@ void Mult (const BaseVector & x, BaseVector & y) const override { pybind11::gil_scoped_acquire gil; - pybind11::function overload = pybind11::get_overload(this, "Mult"); - if (overload) { - const AutoVector * avecx = dynamic_cast(&x); - auto sx = shared_ptr(const_cast((avecx!=NULL)?&(**avecx):&x), - NOOP_Deleter); - const AutoVector * avecy = dynamic_cast(&y); - auto sy = shared_ptr(const_cast((avecy!=NULL)?&(**avecy):&y), - NOOP_Deleter); + if (auto overload = pybind11::get_overload(this, "Mult")) { + auto sx = x.shared_from_this(); + auto sy = y.shared_from_this(); + /* + this version works also, IFF we used enable_shared_from_this + shared_ptr sx(const_cast(&x), NOOP_Deleter); + shared_ptr sy(&y, NOOP_Deleter); + */ overload(sx,sy); } else @@ -843,32 +911,30 @@ void MultTrans (const BaseVector & x, BaseVector & y) const override { pybind11::gil_scoped_acquire gil; - pybind11::function overload = pybind11::get_overload(this, "MultTrans"); - if (overload) { - const AutoVector * avecx = dynamic_cast(&x); - auto sx = shared_ptr(const_cast((avecx!=NULL)?&(**avecx):&x), - NOOP_Deleter); - const AutoVector * avecy = dynamic_cast(&y); - auto sy = shared_ptr(const_cast((avecy!=NULL)?&(**avecy):&y), - NOOP_Deleter); - overload(sx,sy); - } + + if (auto overload = pybind11::get_overload(this, "MultTrans")) + overload(x.shared_from_this(), y.shared_from_this()); else BaseMatrix::MultTrans(x,y); } void MultAdd (double s, const BaseVector & x, BaseVector & y) const override { pybind11::gil_scoped_acquire gil; + /* pybind11::function overload = pybind11::get_overload(this, "MultAdd"); if (overload) { + cout << "trampoline multadd" << endl; + const AutoVector * avecx = dynamic_cast(&x); auto sx = shared_ptr(const_cast((avecx!=NULL)?&(**avecx):&x), NOOP_Deleter); const AutoVector * avecy = dynamic_cast(&y); auto sy = shared_ptr(const_cast((avecy!=NULL)?&(**avecy):&y), NOOP_Deleter); - overload(s, sx,sy); - } + + */ + if (auto overload = pybind11::get_overload(this, "MultAdd")) + overload(s, x.shared_from_this(), y.shared_from_this()); else BaseMatrix::MultAdd(s, x, y); } @@ -876,7 +942,10 @@ void MultTransAdd (double s, const BaseVector & x, BaseVector & y) const override { pybind11::gil_scoped_acquire gil; pybind11::function overload = pybind11::get_overload(this, "MultTransAdd"); + /* if (overload) { + cout << "trampoline multtransadd" << endl; + const AutoVector * avecx = dynamic_cast(&x); auto sx = shared_ptr(const_cast((avecx!=NULL)?&(**avecx):&x), NOOP_Deleter); @@ -885,6 +954,9 @@ NOOP_Deleter); overload(s, sx,sy); } + */ + if (auto overload = pybind11::get_overload(this, "MultTransAdd")) + overload(s, x.shared_from_this(), y.shared_from_this()); else BaseMatrix::MultTransAdd(s, x, y); } @@ -892,6 +964,7 @@ void MultAdd (Complex s, const BaseVector & x, BaseVector & y) const override { pybind11::gil_scoped_acquire gil; + /* pybind11::function overload = pybind11::get_overload(this, "MultAdd"); if (overload) { const AutoVector * avecx = dynamic_cast(&x); @@ -902,11 +975,15 @@ NOOP_Deleter); overload(s, sx,sy); } + */ + if (auto overload = pybind11::get_overload(this, "MultAdd")) + overload(s, x.shared_from_this(), y.shared_from_this()); else BaseMatrix::MultAdd(s, x, y); } void MultTransAdd (Complex s, const BaseVector & x, BaseVector & y) const override { pybind11::gil_scoped_acquire gil; + /* pybind11::function overload = pybind11::get_overload(this, "MultTransAdd"); if (overload) { const AutoVector * avecx = dynamic_cast(&x); @@ -917,6 +994,9 @@ NOOP_Deleter); overload(s, sx,sy); } + */ + if (auto overload = pybind11::get_overload(this, "MultTransAdd")) + overload(s, x.shared_from_this(), y.shared_from_this()); else BaseMatrix::MultTransAdd(s, x, y); } @@ -935,6 +1015,12 @@ ) */ .def(py::init<> ()) + .def(py::init<>([] (shared_ptr vec) + { return make_shared (vec); })) + .def(py::init<>([] (shared_ptr vec) + { return make_shared (vec); })) + .def(py::init<>([] (Matrix<> mat) + { return make_shared (move(mat)); })) .def(py::init<>([] (py::object pyob) { return make_shared (pyob); })) .def("__str__", [](BaseMatrix &self) { return ToString(self); } ) @@ -964,6 +1050,13 @@ { return shared_ptr(self.CreateRowVector()); } ) .def("CreateColVector", [] ( BaseMatrix & self) { return shared_ptr(self.CreateColVector()); } ) + .def("CreateVector", [] ( BaseMatrix & self, bool colvec) + { + if (colvec) + return shared_ptr(self.CreateColVector()); + else + return shared_ptr(self.CreateRowVector()); + }, py::arg("colvector") ) .def("AsVector", [] (BM & m) { @@ -1363,7 +1456,19 @@ .def(py::init,bool>(), py::arg("mask"), py::arg("range"), "Linear operator projecting to true/false bits of BitArray mask, depending on argument range") - .def("Project", &Projector::Project, "project vector inline") + .def("Project", [](const Projector & proj, shared_ptr v) + { + proj.Project(*v); + return v; + }, + "project vector inline") + .def("Project", [](const Projector & proj, shared_ptr mv) + { + for (auto i : Range(*mv)) + proj.Project(*(*mv)[i]); + return mv; + }, + "project vector inline") ; py::class_, BaseMatrix> (m, "IdentityMatrix") @@ -1372,6 +1477,13 @@ py::arg("size"), py::arg("complex")=false) ; + py::class_, shared_ptr>, BaseMatrix> (m, "DiagonalMatrix") + .def(py::init([](shared_ptr vec) + { + return make_shared> (dynamic_pointer_cast>(vec)); + })) + ; + py::class_, shared_ptr>, BaseMatrix> (m, "Real2ComplexMatrix") .def(py::init>()) diff -Nru ngsolve-6.2.2102/linalg/special_matrix.cpp ngsolve-6.2.2103/linalg/special_matrix.cpp --- ngsolve-6.2.2102/linalg/special_matrix.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/special_matrix.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -177,20 +177,21 @@ auto sx = x.FV(); auto sy = y.FV(); - + auto sd = this->diag->FV(); ParallelForRange - (Range(diag), [sx,sy,s,this] (IntRange myrange) + (Range(*diag), [sx,sy,sd,s] (IntRange myrange) { for (size_t i : myrange) - sy(i) += s * this->diag(i)*sx(i); + sy(i) += s * sd(i)*sx(i); + // sy(i) += s * this->diag(i)*sx(i); }); } else { auto sx = x.SV(); auto sy = y.SV(); - for (size_t i : Range(diag)) - sy(i) += s * diag(i)*sx(i); + for (size_t i : Range(*diag)) + sy(i) += s * (*diag)(i)*sx(i); } } @@ -203,26 +204,26 @@ template AutoVector DiagonalMatrix :: CreateRowVector () const { - return CreateBaseVector(diag.Size(), mat_traits::IS_COMPLEX, mat_traits::WIDTH); + return CreateBaseVector(diag->Size(), mat_traits::IS_COMPLEX, mat_traits::WIDTH); } template AutoVector DiagonalMatrix :: CreateColVector () const { - return CreateBaseVector(diag.Size(), mat_traits::IS_COMPLEX, mat_traits::HEIGHT); + return CreateBaseVector(diag->Size(), mat_traits::IS_COMPLEX, mat_traits::HEIGHT); } template shared_ptr DiagonalMatrix :: InverseMatrix (shared_ptr subset) const { - VVector v2(diag.Size()); + VVector v2(diag->Size()); if (subset) { - for (size_t i = 0; i < diag.Size(); i++) + for (size_t i = 0; i < diag->Size(); i++) if (subset->Test(i)) { - v2(i) = diag(i); + v2(i) = (*diag)(i); CalcInverse(v2(i)); } else @@ -230,9 +231,9 @@ } else { - for (size_t i = 0; i < diag.Size(); i++) + for (size_t i = 0; i < diag->Size(); i++) { - v2(i) = diag(i); + v2(i) = (*diag)(i); CalcInverse(v2(i)); } } @@ -871,6 +872,104 @@ } + + + + BaseMatrixFromVector :: BaseMatrixFromVector (shared_ptr avec) + : vec(avec) { } + + void BaseMatrixFromVector :: MultAdd (double s, const BaseVector & x, BaseVector & y) const + { + y += s * x.FV()(0) * (*vec); + } + + void BaseMatrixFromVector :: MultTransAdd (double s, const BaseVector & x, BaseVector & y) const + { + y.FV()(0) += s * InnerProduct(x, *vec); + } + + AutoVector BaseMatrixFromVector :: CreateRowVector () const + { + // missing parallel: 1 dof for all + shared_ptr sp = make_shared>(1); + return sp; + } + + AutoVector BaseMatrixFromVector :: CreateColVector () const + { + return vec->CreateVector(); + } + + + + + + + BaseMatrixFromMultiVector :: BaseMatrixFromMultiVector (shared_ptr avec) + : vec(avec) { } + + void BaseMatrixFromMultiVector :: MultAdd (double s, const BaseVector & x, BaseVector & y) const + { + // y += s * x.FV()(0) * (*vec); + Vector<> tmp = x.FV(); + tmp *= s; + vec->AddTo(tmp, y); + } + + void BaseMatrixFromMultiVector :: MultTransAdd (double s, const BaseVector & x, BaseVector & y) const + { + Vector<> tmp = vec->InnerProductD(x); + y.FV() += s * tmp; + } + + AutoVector BaseMatrixFromMultiVector :: CreateRowVector () const + { + // missing parallel: 1 dof for all + shared_ptr sp = make_shared>(vec->Size()); + return sp; + } + + AutoVector BaseMatrixFromMultiVector :: CreateColVector () const + { + return vec->RefVec()->CreateVector(); + } + + + + + BaseMatrixFromMatrix :: BaseMatrixFromMatrix (Matrix<> amat) + : mat(move(amat)) { } + + void BaseMatrixFromMatrix :: MultAdd (double s, const BaseVector & x, BaseVector & y) const + { + y.FV() += s * mat * x.FV(); + } + + void BaseMatrixFromMatrix :: MultTransAdd (double s, const BaseVector & x, BaseVector & y) const + { + y.FV() += s * Trans(mat) * x.FV(); + } + + AutoVector BaseMatrixFromMatrix :: CreateRowVector () const + { + // missing parallel: 1 dof for all + shared_ptr sp = make_shared>(mat.Width()); + return sp; + } + + AutoVector BaseMatrixFromMatrix :: CreateColVector () const + { + shared_ptr sp = make_shared>(mat.Height()); + return sp; + } + + + + + + + + string PS(PARALLEL_STATUS stat) { switch (stat) @@ -913,18 +1012,18 @@ AutoVector LoggingMatrix :: CreateRowVector () const { - unique_ptr vec = mat->CreateRowVector(); + auto vec = mat->CreateRowVector(); *out << "matrix '" << label << "' CreateRowVector " - << "size: " << vec->Size() << " " << PS(vec->GetParallelStatus()) << endl; - return move(vec); + << "size: " << vec.Size() << " " << PS(vec.GetParallelStatus()) << endl; + return vec; } AutoVector LoggingMatrix :: CreateColVector () const { - unique_ptr vec = mat->CreateColVector(); + auto vec = mat->CreateColVector(); *out << "matrix '" << label << "' CreateColVector " - << "size: " << vec->Size() << " " << PS(vec->GetParallelStatus()) << endl; - return move(vec); + << "size: " << vec.Size() << " " << PS(vec.GetParallelStatus()) << endl; + return vec; } diff -Nru ngsolve-6.2.2102/linalg/special_matrix.hpp ngsolve-6.2.2103/linalg/special_matrix.hpp --- ngsolve-6.2.2102/linalg/special_matrix.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/linalg/special_matrix.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -43,24 +43,26 @@ template class DiagonalMatrix : public BaseMatrix { - VVector diag; + shared_ptr> diag; public: // typedef typename mat_traits::TV_ROW TV_ROW; // typedef typename mat_traits::TV_COL TV_COL; typedef typename mat_traits::TSCAL TSCAL; DiagonalMatrix(size_t h) - : diag(h) { } + : diag(make_shared>(h)) { } DiagonalMatrix(const VVector & diag_) + : diag(make_shared>(diag_)) { } + DiagonalMatrix(shared_ptr> diag_) : diag(diag_) { } - + bool IsComplex() const override { return false; } - TM & operator() (size_t i) { return diag(i); } - const TM & operator() (size_t i) const { return diag(i); } - int VHeight() const override { return diag.Size(); } - int VWidth() const override { return diag.Size(); } + TM & operator() (size_t i) { return (*diag)(i); } + const TM & operator() (size_t i) const { return (*diag)(i); } + int VHeight() const override { return diag->Size(); } + int VWidth() const override { return diag->Size(); } - BaseVector & AsVector() override { return diag; } + BaseVector & AsVector() override { return *diag; } ostream & Print (ostream & ost) const override; AutoVector CreateRowVector () const override; @@ -336,6 +338,64 @@ virtual AutoVector CreateRowVector () const override; virtual AutoVector CreateColVector () const override; + }; + + + + class BaseMatrixFromVector : public BaseMatrix + { + shared_ptr vec; + + public: + BaseMatrixFromVector (shared_ptr avec); + + bool IsComplex() const override { return vec->IsComplex(); } + virtual void MultAdd (double s, const BaseVector & x, BaseVector & y) const override; + virtual void MultTransAdd (double s, const BaseVector & x, BaseVector & y) const override; + + virtual int VHeight() const override { return vec->Size(); } + virtual int VWidth() const override { return 1; } + + virtual AutoVector CreateRowVector () const override; + virtual AutoVector CreateColVector () const override; + }; + + + class BaseMatrixFromMultiVector : public BaseMatrix + { + shared_ptr vec; + + public: + BaseMatrixFromMultiVector (shared_ptr avec); + + bool IsComplex() const override { return vec->IsComplex(); } + virtual void MultAdd (double s, const BaseVector & x, BaseVector & y) const override; + virtual void MultTransAdd (double s, const BaseVector & x, BaseVector & y) const override; + + virtual int VHeight() const override { return vec->RefVec()->Size(); } + virtual int VWidth() const override { return vec->Size(); } + + virtual AutoVector CreateRowVector () const override; + virtual AutoVector CreateColVector () const override; + }; + + + class BaseMatrixFromMatrix : public BaseMatrix + { + Matrix<> mat; + + public: + BaseMatrixFromMatrix (Matrix<> amat); + + bool IsComplex() const override { return false; } + virtual void MultAdd (double s, const BaseVector & x, BaseVector & y) const override; + virtual void MultTransAdd (double s, const BaseVector & x, BaseVector & y) const override; + + virtual int VHeight() const override { return mat.Height(); } + virtual int VWidth() const override { return mat.Width(); } + + virtual AutoVector CreateRowVector () const override; + virtual AutoVector CreateColVector () const override; }; diff -Nru ngsolve-6.2.2102/multigrid/mgpre.cpp ngsolve-6.2.2103/multigrid/mgpre.cpp --- ngsolve-6.2.2102/multigrid/mgpre.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/multigrid/mgpre.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -242,14 +242,14 @@ //(*testout) << "u.Size() " << u.Size() << " d.Size() " << d.Size() // << " w.Size() " << w.Size() << endl; - // smoother->PreSmooth (level, u, f, smoothingsteps * incsm); - smoother->PreSmoothResiduum (level, u, f, *d, smoothingsteps * incsm); + smoother->PreSmooth (level, u, f, smoothingsteps * incsm); + //smoother->PreSmoothResiduum (level, u, f, *d, smoothingsteps * incsm); auto dt = d.Range (0, fespace.GetNDofLevel(level-1)); auto wt = w.Range (0, fespace.GetNDofLevel(level-1)); - // smoother->Residuum (level, u, f, d); + smoother->Residuum (level, u, f, d); // cout << "level = " << level << ", prolproj = " << endl << prol_projection << endl; if (harmonic_extension_prolongation) if (level < he_prolongation.Size() && he_prolongation[level]) @@ -261,9 +261,13 @@ prolongation->RestrictInline (level, d); w = 0; - for (int j = 1; j <= cycle; j++) - MGM (level-1, wt, dt, incsm * incsmooth); - + if (level == 1) + MGM (level-1, wt, dt, incsm * incsmooth); + else{ + for (int j = 1; j <= cycle; j++) + MGM (level-1, wt, dt, incsm * incsmooth); + } + prolongation->ProlongateInline (level, w); u += w; diff -Nru ngsolve-6.2.2102/multigrid/prolongation.cpp ngsolve-6.2.2103/multigrid/prolongation.cpp --- ngsolve-6.2.2102/multigrid/prolongation.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/multigrid/prolongation.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -23,6 +23,21 @@ ; } + void Prolongation :: Update (const FESpace & fes) + { + if (leveldofs.Size() < fes.GetMeshAccess()->GetNLevels()) + leveldofs.Append (DofRange(fes.GetNDof(), fes.GetParallelDofs())); + } + + + DofRange Prolongation :: LevelDofs (int level) const + { + if (level < 0 || level >= leveldofs.Size()) + throw Exception("Illegal level " + ToString(level) + " num levels = " + ToString(leveldofs.Size())); + return leveldofs[level]; + } + + LinearProlongation :: ~LinearProlongation() { ; } @@ -32,6 +47,8 @@ if (ma->GetNLevels() > nvlevel.Size()) nvlevel.Append (ma->GetNV()); */ + Prolongation::Update(fes); + nvlevel.SetSize(ma->GetNLevels()); for (auto i : Range(nvlevel)) nvlevel[i] = ma->GetNVLevel(i); @@ -131,7 +148,7 @@ } - SparseMatrix< double >* LinearProlongation :: CreateProlongationMatrix( int finelevel ) const + shared_ptr> LinearProlongation :: CreateProlongationMatrix( int finelevel ) const { int i; int parents[2]; @@ -181,7 +198,7 @@ } // write prolongation matrix - SparseMatrix< double >* prol = new SparseMatrix< double >( mg, 1 ); + shared_ptr> prol = make_shared> ( mg, 1 ); for( i=0; i leveldofs; + public: /// Prolongation(); @@ -22,10 +24,12 @@ virtual ~Prolongation(); /// - virtual void Update (const FESpace & fes) = 0; + virtual void Update (const FESpace & fes); + virtual size_t GetNDofLevel (int level) { throw Exception("Prolongation::GetNDofLevel not overloaded"); } + DofRange LevelDofs (int level) const; /// - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const = 0; + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const = 0; /// virtual void ProlongateInline (int finelevel, BaseVector & v) const = 0; /// @@ -35,6 +39,39 @@ }; + class ProlongationOperator : public BaseMatrix + { + shared_ptr prol; + int level; + public: + ProlongationOperator (shared_ptr aprol, int alevel) + : prol(aprol), level(alevel) { } + + virtual bool IsComplex() const override { return false; } + + virtual int VHeight() const override { return prol->GetNDofLevel(level); } + virtual int VWidth() const override { return prol->GetNDofLevel(level-1); } + + virtual void Mult (const BaseVector & x, BaseVector & y) const override + { + y.Range(0, VWidth()) = x; + prol->ProlongateInline (level, y); + } + virtual void MultTrans (const BaseVector & x, BaseVector & y) const override + { + auto tmp = x.CreateVector(); + tmp = x; + prol->RestrictInline (level, tmp); + y = tmp.Range(0, VWidth()); + } + + AutoVector CreateRowVector() const override { return make_unique> (VWidth()); } + AutoVector CreateColVector() const override { return make_unique> (VHeight()); } + }; + + + + /** Standard Prolongation. Child nodes between 2 parent nodes. @@ -51,8 +88,9 @@ virtual ~LinearProlongation(); virtual void Update (const FESpace & fes) override; - - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const override; + virtual size_t GetNDofLevel (int level) override { return nvlevel[level]; } + + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const override; virtual void ProlongateInline (int finelevel, BaseVector & v) const override; virtual void RestrictInline (int finelevel, BaseVector & v) const override; }; @@ -106,7 +144,7 @@ { ; } /// - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const override + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const override { return NULL; } /// @@ -168,7 +206,7 @@ virtual void Update (const FESpace & fes) override; /// - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const override + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const override { return NULL; } /// virtual void ProlongateInline (int finelevel, BaseVector & v) const override; @@ -197,7 +235,7 @@ virtual void Update (const FESpace & fes) override { ; } /// - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const override + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const override { return NULL; } /// @@ -231,7 +269,7 @@ { ; } /// - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const override + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const override { return NULL; } /// @@ -274,7 +312,7 @@ } /// - virtual SparseMatrix< double >* CreateProlongationMatrix( int finelevel ) const override + virtual shared_ptr> CreateProlongationMatrix( int finelevel ) const override { return NULL; } diff -Nru ngsolve-6.2.2102/ngstd/ngs_utils.hpp ngsolve-6.2.2103/ngstd/ngs_utils.hpp --- ngsolve-6.2.2102/ngstd/ngs_utils.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/ngstd/ngs_utils.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -155,6 +155,8 @@ { return base_type::shared_from_this(); } + public: + virtual ~enable_shared_from_this_virtual_base() { } }; template diff -Nru ngsolve-6.2.2102/ngstd/python_ngstd.cpp ngsolve-6.2.2103/ngstd/python_ngstd.cpp --- ngsolve-6.2.2102/ngstd/python_ngstd.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/ngstd/python_ngstd.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -93,6 +93,8 @@ .def("__iter__", [] (ngstd::IntRange & i) { return py::make_iterator(i.begin(), i.end()); }, py::keep_alive<0,1>()) + .def("__contains__", [] (const IntRange & self, int i) + { return i >= self.begin() && i < self.end(); }) .def_property_readonly("start", [](IntRange& self) { return self.First();}) .def_property_readonly("stop", [](IntRange& self) { return self.Next();}) .def_property_readonly("step", [](IntRange& self) { return 1; }) diff -Nru ngsolve-6.2.2102/ngstd/python_ngstd.hpp ngsolve-6.2.2103/ngstd/python_ngstd.hpp --- ngsolve-6.2.2102/ngstd/python_ngstd.hpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/ngstd/python_ngstd.hpp 2021-06-04 23:31:19.000000000 +0000 @@ -182,7 +182,8 @@ template< typename T, typename TELEM, typename TCLASS = py::class_> void PyDefROBracketOperator( py::module &m, TCLASS &c ) { - auto Get = [](T& self, int i) { + auto Get = [](T& self, int i) { + if (i < 0) i += self.Size(); if( i=0 ) return self[i]; throw py::index_error(); @@ -198,6 +199,7 @@ { PyDefROBracketOperator(m, c); auto Set = [](T& self, int i, TELEM val) { + if (i < 0) i += self.Size(); if( i=0 ) self[i] = val; else diff -Nru ngsolve-6.2.2102/ngstd/statushandler.cpp ngsolve-6.2.2103/ngstd/statushandler.cpp --- ngsolve-6.2.2102/ngstd/statushandler.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/ngstd/statushandler.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -4,13 +4,16 @@ namespace ngstd { + static mutex m; void BaseStatusHandler::PushStatus (const char * str) const { + lock_guard lock(m); Ng_PushStatus(str); } void BaseStatusHandler::PopStatus () const { + lock_guard lock(m); Ng_PopStatus(); } diff -Nru ngsolve-6.2.2102/python/CMakeLists.txt ngsolve-6.2.2103/python/CMakeLists.txt --- ngsolve-6.2.2102/python/CMakeLists.txt 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/CMakeLists.txt 2021-06-04 23:31:19.000000000 +0000 @@ -1,6 +1,6 @@ if(NETGEN_USE_PYTHON) install (FILES - __expr.py internal.py __console.py + __expr.py internal.py __console.py webgui.py __init__.py utils.py solvers.py eigenvalues.py meshes.py krylovspace.py nonlinearsolvers.py bvp.py timing.py TensorProductTools.py ngs2petsc.py @@ -21,6 +21,4 @@ endif() endif(BUILD_STUB_FILES) -add_subdirectory(webgui) - endif(NETGEN_USE_PYTHON) diff -Nru ngsolve-6.2.2102/python/__init__.py ngsolve-6.2.2103/python/__init__.py --- ngsolve-6.2.2102/python/__init__.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/__init__.py 2021-06-04 23:31:19.000000000 +0000 @@ -19,7 +19,7 @@ from .bla import Matrix, Vector, InnerProduct, Norm from .la import BaseMatrix, BaseVector, BlockVector, MultiVector, BlockMatrix, \ CreateVVector, CGSolver, QMRSolver, GMRESSolver, ArnoldiSolver, \ - Projector, IdentityMatrix, Embedding, PermutationMatrix, \ + Projector, DiagonalMatrix, IdentityMatrix, Embedding, PermutationMatrix, \ ConstEBEMatrix, ParallelMatrix, PARALLEL_STATUS from .fem import BFI, LFI, CoefficientFunction, Parameter, ParameterC, ET, \ POINT, SEGM, TRIG, QUAD, TET, PRISM, PYRAMID, HEX, CELL, FACE, EDGE, \ diff -Nru ngsolve-6.2.2102/python/krylovspace.py ngsolve-6.2.2103/python/krylovspace.py --- ngsolve-6.2.2102/python/krylovspace.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/krylovspace.py 2021-06-04 23:31:19.000000000 +0000 @@ -1,31 +1,89 @@ from ngsolve import Projector, Norm, TimeFunction, BaseMatrix, Preconditioner, InnerProduct, \ Norm, sqrt, Vector, Matrix, BaseVector, BitArray -from typing import Optional, Callable +from typing import Optional, Callable, Union import logging from netgen.libngpy._meshing import _PushStatus, _GetStatus, _SetThreadPercentage from math import log -class CGSolver(BaseMatrix): - def __init__(self, mat : BaseMatrix, pre : Optional[Preconditioner] = None, +linear_solver_param_doc = """ +mat : BaseMatrix + The left hand side of the equation to solve. + +pre : Preconditioner, BaseMatrix = None + If provided, the preconditioner for the system. + +freedofs : BitArray = None + If no preconditioner is provided, the BitArray of the FESpace freedofs must be given. + +tol : double = 1e-12 + Relative tolerance for the residuum reduction. + +maxiter : int = 100 + Maximum number of iterations, if reached solver will emit a warning. + +callback : Callable[[int, float], None] = None + Callback function that is called with iteration number and residual in each iteration step. + +callback_sol : Callable[[BaseVector], None] = None + Callback function that is called with solution x_k in each iteration step. + +printrates : bool = False + Print iterations to stdout. One can give a string to be passed as an `end` + argument to the print function, for example: + >>> printrates="\r" + will call + >>> print("iteration = 1, residual = 1e-3", end="\r") + if "\r" is passed, a final output will also be printed. +""" + +class LinearSolver(BaseMatrix): + """Base class for linear solvers. +""" + linear_solver_param_doc + name = "LinearSolver" + def __init__(self, mat : BaseMatrix, + pre : Optional[Preconditioner] = None, freedofs : Optional[BitArray] = None, - conjugate : bool = False, tol : float = 1e-12, maxsteps : int = 100, + tol : float = None, + maxiter : int = 100, + atol : float = None, callback : Optional[Callable[[int, float], None]] = None, - printing=False, abstol=None): + callback_sol : Optional[Callable[[BaseVector], None]] = None, + printrates : bool = False): super().__init__() + if atol is None and tol is None: + tol = 1e-12 self.mat = mat assert (freedofs is None) != (pre is None) # either pre or freedofs must be given self.pre = pre if pre else Projector(freedofs, True) - self.conjugate = conjugate self.tol = tol - self.abstol = abstol - self.maxsteps = maxsteps + self.atol = atol + self.maxiter = maxiter self.callback = callback - self._tmp_vecs = [self.mat.CreateRowVector() for i in range(3)] + self.callback_sol = callback_sol + self.printrates = printrates + self.residuals = [] + self.iterations = 0 - self.printing = printing - self.errors = [] + @TimeFunction + def Solve(self, rhs : BaseVector, sol : Optional[BaseVector] = None, + initialize : bool = True) -> BaseVector: self.iterations = 0 + self.residuals = [] + old_status = _GetStatus() + _PushStatus(self.name + " Solve") + _SetThreadPercentage(0) + if sol is None: + sol = rhs.CreateVector() + initialize = True + if initialize: + sol[:] = 0 + self.sol = sol + self._SolveImpl(rhs=rhs, sol=sol) + if old_status[0] != "idle": + _PushStatus(old_status[0]) + _SetThreadPercentage(old_status[1]) + return sol def Height(self) -> int: return self.mat.width @@ -43,73 +101,101 @@ if hasattr(self.pre, "Update"): self.pre.Update() - @TimeFunction - def Solve(self, rhs : BaseVector, sol : Optional[BaseVector] = None, - initialize : bool = True) -> None: - old_status = _GetStatus() - _PushStatus("CG Solve") - _SetThreadPercentage(0) - self.sol = sol if sol is not None else self.mat.CreateRowVector() - d, w, s = self._tmp_vecs - u, mat, pre, conjugate, tol, maxsteps, callback = self.sol, self.mat, self.pre, self.conjugate, \ - self.tol, self.maxsteps, self.callback - if initialize: - u[:] = 0 - d.data = rhs + def CheckResidual(self, residual): + self.iterations += 1 + self.residuals.append(residual) + if len(self.residuals) == 1: + if self.tol is None: + self._final_residual = self.atol + else: + self._final_residual = residual * self.tol + if self.atol is not None: + self._final_residual = max(self._final_residual, self.atol) else: - d.data = rhs - mat * u - w.data = pre * d + if self.callback is not None: + self.callback(self.iterations, residual) + if self.callback_sol is not None: + self.callback_sol(self.sol) + if self.residuals[0] != 0: + logerrstop = log(self._final_residual) + logerrfirst = log(self.residuals[0]) + _SetThreadPercentage(100.*max(self.iterations/self.maxiter, + (log(residual)-logerrfirst)/(logerrstop - logerrfirst))) + if self.printrates: + print("\33[2K{} iteration {}, residual = {}".format(self.name, self.iterations, residual), end="\n" if isinstance(self.printrates, bool) else self.printrates) + if self.iterations == self.maxiter and residual > self._final_residual: + print("\33[2KWARNING: {} did not converge to TOL".format(self.name)) + is_converged = self.iterations >= self.maxiter or residual <= self._final_residual + if is_converged and self.printrates == "\r": + print("\33[2K{} {}converged in {} iterations to residual {}".format(self.name, "NOT " if residual >= self._final_residual else "", self.iterations, residual)) + return is_converged + +class CGSolver(LinearSolver): + """Preconditioned conjugate gradient method + + Parameters + ---------- + +""" + linear_solver_param_doc + """ + +conjugate : bool = False + If set to True, then the complex inner product is used, else a pseudo inner product that makes CG work with complex symmetric matrices. +""" + name = "CG" + + def __init__(self, *args, + conjugate : bool = False, + abstol : float = None, + maxsteps : int = None, + printing : bool = False, + **kwargs): + if printing: + print("WARNING: printing is deprecated, use printrates instead!") + kwargs["printrates"] = printing + if abstol is not None: + print("WARNING: abstol is deprecated, use atol instead!") + kwargs["abstol"] = abstol + if maxsteps is not None: + print("WARNING: maxsteps is deprecated, use maxiter instead!") + kwargs["maxiter"] = maxsteps + super().__init__(*args, **kwargs) + self.conjugate = conjugate + + # for backward compatibility + @property + def errors(self): + return self.residuals + + def _SolveImpl(self, rhs : BaseVector, sol : BaseVector): + d, w, s = [sol.CreateVector() for i in range(3)] + conjugate = self.conjugate + d.data = rhs - self.mat * sol + w.data = self.pre * d s.data = w wdn = w.InnerProduct(d, conjugate=conjugate) - if wdn == 0: - wdn = 1. - err0 = sqrt(abs(wdn)) - - self.errors = [err0] - if wdn==err0: - return u - lwstart = log(err0) - errstop = err0 * tol - if self.abstol is not None: - errstop = max(errstop, self.abstol) - logerrstop = log(errstop) - - for it in range(maxsteps): - self.iterations = it+1 - w.data = mat * s + if self.CheckResidual(sqrt(abs(wdn))): + return + + while True: + w.data = self.mat * s wd = wdn as_s = s.InnerProduct(w, conjugate=conjugate) if as_s == 0 or wd == 0: break alpha = wd / as_s - u.data += alpha * s + sol.data += alpha * s d.data += (-alpha) * w - w.data = pre*d + w.data = self.pre * d wdn = w.InnerProduct(d, conjugate=conjugate) - beta = wdn / wd + if self.CheckResidual(sqrt(abs(wdn))): + return + beta = wdn / wd s *= beta s.data += w - err = sqrt(abs(wd)) - self.errors.append(err) - if self.printing: - print("iteration " + str(it) + " error = " + str(err)) - if callback is not None: - callback(it,err) - _SetThreadPercentage(100.*max(it/maxsteps, (log(err)-lwstart)/(logerrstop - lwstart))) - if err < errstop: break - else: - if self.printing: - print("CG did not converge to tol") - if old_status[0] != "idle": - _PushStatus(old_status[0]) - _SetThreadPercentage(old_status[1]) - - - def CG(mat, rhs, pre=None, sol=None, tol=1e-12, maxsteps = 100, printrates = True, initialize = True, conjugate=False, callback=None): """preconditioned conjugate gradient method @@ -118,7 +204,7 @@ ---------- mat : Matrix - The left hand side of the equation to solve. The matrix has to be spd or hermitsch. + The left hand side of the equation to solve. The matrix has to be spd o hermitsch. rhs : Vector The right hand side of the equation. @@ -152,13 +238,158 @@ """ solver = CGSolver(mat=mat, pre=pre, conjugate=conjugate, tol=tol, maxsteps=maxsteps, - callback=callback, printing=printrates) + callback=callback, printrates=printrates) solver.Solve(rhs=rhs, sol=sol, initialize=initialize) return solver.sol +class QMRSolver(LinearSolver): + """Quasi Minimal Residuum method + + Parameters + ---------- +""" + linear_solver_param_doc + """ + +pre2 : Preconditioner = None + Second preconditioner, if provided. + +ep : double + Start epsilon. +""" + + name = "QMR" + + def __init__(self, *args, pre2 : Preconditioner = None, + ep : float = 1., **kwargs): + super().__init__(*args, **kwargs) + self.pre2 = pre2 + self.ep = ep + + def _SolveImpl(self, rhs : BaseVector, sol : BaseVector): + u, mat, ep, pre1, pre2 = sol, self.mat, self.ep, self.pre, self.pre2 + r = rhs.CreateVector() + v = rhs.CreateVector() + v_tld = rhs.CreateVector() + w = rhs.CreateVector() + w_tld = rhs.CreateVector() + y = rhs.CreateVector() + y_tld = rhs.CreateVector() + z = rhs.CreateVector() + z_tld = rhs.CreateVector() + p = rhs.CreateVector() + p_tld = rhs.CreateVector() + q = rhs.CreateVector() + d = rhs.CreateVector() + s = rhs.CreateVector() + + r.data = rhs - mat * u + v_tld.data = r + y.data = pre1 * v_tld + + rho = InnerProduct(y,y) + rho = sqrt(rho) + + w_tld.data = r + z.data = pre2.T * w_tld if pre2 else w_tld + + xi = InnerProduct(z,z) + xi = sqrt(xi) + + gamma = 1.0 + eta = -1.0 + theta = 0.0 + + for i in range(1,self.maxiter+1): + if (rho == 0.0): + print('Breakdown in rho') + return + if (xi == 0.0): + print('Breakdown in xi') + return + v.data = (1.0/rho) * v_tld + y.data = (1.0/rho) * y + + w.data = (1.0/xi) * w_tld + z.data = (1.0/xi) * z + + delta = InnerProduct(z,y) + if (delta == 0.0): + print('Breakdown in delta') + return + + y_tld.data = pre2 * y if pre2 else y + z_tld.data = pre1.T * z + + if (i > 1): + p.data = (-xi*delta / ep) * p + p.data += y_tld + + q.data = (-rho * delta / ep) * q + q.data += z_tld + else: + p.data = y_tld + q.data = z_tld + + p_tld.data = mat * p + ep = InnerProduct(q, p_tld) + if (ep == 0.0): + print('Breakdown in epsilon') + return + + beta = ep/delta + if (beta == 0.0): + print('Breakdown in beta') + return + + v_tld.data = p_tld - beta * v; + + y.data = pre1 * v_tld + + rho_1 = rho + rho = InnerProduct(y,y) + rho = sqrt(rho) + + w_tld.data = mat.T * q + w_tld.data -= beta * w + + z.data = pre2.T * w_tld if pre2 else w_tld + + xi = InnerProduct(z,z) + xi = sqrt(xi) + + gamma_1 = gamma + theta_1 = theta + + theta = rho/(gamma_1 * abs(beta)) + gamma = 1.0 / sqrt(1.0 + theta * theta) + if (gamma == 0.0): + print('Breakdown in gamma') + return + + eta = -eta * rho_1 * gamma * gamma / (beta * gamma_1 * gamma_1); + + if (i > 1): + d.data = (theta_1 * theta_1 * gamma * gamma) * d + d.data += eta * p + + s.data = (theta_1 * theta_1 * gamma * gamma) * s + s.data += eta * p_tld + + else: + d.data = eta * p + s.data = eta * p_tld + + u.data += d + r.data -= s + + #Projected residuum: Better terminating condition necessary? + v.data = self.pre * r + ResNorm = sqrt(InnerProduct(r,v)) + # ResNorm = sqrt( np.dot(r.FV().NumPy()[fdofs],r.FV().NumPy()[fdofs])) + #ResNorm = sqrt(InnerProduct(r,r)) + if self.CheckResidual(ResNorm): + return -@TimeFunction def QMR(mat, rhs, fdofs, pre1=None, pre2=None, sol=None, maxsteps = 100, printrates = True, initialize = True, ep = 1.0, tol = 1e-7): """Quasi Minimal Residuum method @@ -206,147 +437,114 @@ Solution vector of the QMR method. """ - u = sol if sol else rhs.CreateVector() - - r = rhs.CreateVector() - v = rhs.CreateVector() - v_tld = rhs.CreateVector() - w = rhs.CreateVector() - w_tld = rhs.CreateVector() - y = rhs.CreateVector() - y_tld = rhs.CreateVector() - z = rhs.CreateVector() - z_tld = rhs.CreateVector() - p = rhs.CreateVector() - p_tld = rhs.CreateVector() - q = rhs.CreateVector() - d = rhs.CreateVector() - s = rhs.CreateVector() - - if (initialize): u[:] = 0.0 - - r.data = rhs - mat * u - v_tld.data = r - y.data = pre1 * v_tld if pre1 else v_tld - - rho = InnerProduct(y,y) - rho = sqrt(rho) - - w_tld.data = r - z.data = pre2.T * w_tld if pre2 else w_tld - - xi = InnerProduct(z,z) - xi = sqrt(xi) - - gamma = 1.0 - eta = -1.0 - theta = 0.0 + # backwards compatibility, but freedofs are not needed then. + if pre1 is not None: + fdofs = None + return QMRSolver(mat=mat, freedofs=fdofs, pre=pre1, + pre2=pre2, maxiter=maxsteps, + printrates=printrates, ep=ep, + tol=tol).Solve(rhs=rhs, sol=sol, initialize=initialize) - - for i in range(1,maxsteps+1): - if (rho == 0.0): - print('Breakdown in rho') - return - if (xi == 0.0): - print('Breakdown in xi') - return - v.data = (1.0/rho) * v_tld - y.data = (1.0/rho) * y - w.data = (1.0/xi) * w_tld - z.data = (1.0/xi) * z - delta = InnerProduct(z,y) - if (delta == 0.0): - print('Breakdown in delta') - return - - y_tld.data = pre2 * y if pre2 else y - z_tld.data = pre1.T * z if pre1 else z - if (i > 1): - p.data = (-xi*delta / ep) * p - p.data += y_tld - - q.data = (-rho * delta / ep) * q - q.data += z_tld - else: - p.data = y_tld - q.data = z_tld - - p_tld.data = mat * p - ep = InnerProduct(q, p_tld) - if (ep == 0.0): - print('Breakdown in epsilon') - return +#Source: Michael Kolmbauer https://www.numa.uni-linz.ac.at/Teaching/PhD/Finished/kolmbauer-diss.pdf +class MinResSolver(LinearSolver): + """Minimal Residuum method - beta = ep/delta - if (beta == 0.0): - print('Breakdown in beta') - return - - v_tld.data = p_tld - beta * v; + Parameters + ---------- +""" + linear_solver_param_doc + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def _SolveImpl(self, rhs: BaseVector, sol : BaseVector): + pre, mat, u = self.pre, self.mat, sol + v_new = rhs.CreateVector() + v = rhs.CreateVector() + v_old = rhs.CreateVector() + w_new = rhs.CreateVector() + w = rhs.CreateVector() + w_old = rhs.CreateVector() + z_new = rhs.CreateVector() + z = rhs.CreateVector() + mz = rhs.CreateVector() - y.data = pre1 * v_tld if pre1 else v_tld - - rho_1 = rho - rho = InnerProduct(y,y) - rho = sqrt(rho) - - - w_tld.data = mat.T * q - w_tld.data -= beta * w - - z.data = pre2.T * w_tld if pre2 else w_tld - - xi = InnerProduct(z,z) - xi = sqrt(xi) + v.data = rhs - mat * u - gamma_1 = gamma - theta_1 = theta + z.data = pre * v - theta = rho/(gamma_1 * abs(beta)) - gamma = 1.0 / sqrt(1.0 + theta * theta) - if (gamma == 0.0): - print('Breakdown in gamma') - return - - eta = -eta * rho_1 * gamma * gamma / (beta * gamma_1 * gamma_1); + #First Step + gamma = sqrt(InnerProduct(z,v)) + gamma_new = 0 + z.data = 1/gamma * z + v.data = 1/gamma * v - if (i > 1): - d.data = (theta_1 * theta_1 * gamma * gamma) * d - d.data += eta * p - - s.data = (theta_1 * theta_1 * gamma * gamma) * s - s.data += eta * p_tld - - else: - d.data = eta * p - s.data = eta * p_tld - - - u.data += d - r.data -= s + ResNorm = gamma + ResNorm_old = gamma - #Projected residuum: Better terminating condition necessary? - ResNorm = sqrt( np.dot(r.FV().NumPy()[fdofs],r.FV().NumPy()[fdofs])) - #ResNorm = sqrt(InnerProduct(r,r)) - - if (printrates): - print ("it = ", i, " err = ", ResNorm) - - if (ResNorm <= tol): - break - else: - print("Warning: QMR did not converge to TOL") + if self.CheckResidual(ResNorm): + return - return u + eta_old = gamma + c_old = 1 + c = 1 + s_new = 0 + s = 0 + s_old = 0 + + v_old[:] = 0.0 + w_old[:] = 0.0 + w[:] = 0.0 + + k = 1 + while True: + mz.data = mat*z + delta = InnerProduct(mz,z) + v_new.data = mz - delta*v - gamma * v_old + + z_new.data = pre * v_new + + gamma_new = sqrt(InnerProduct(z_new, v_new)) + z_new *= 1/gamma_new + v_new *= 1/gamma_new + + alpha0 = c*delta - c_old*s*gamma + alpha1 = sqrt(alpha0*alpha0 + gamma_new*gamma_new) #** + alpha2 = s*delta + c_old*c*gamma + alpha3 = s_old * gamma + + c_new = alpha0/alpha1 + s_new = gamma_new/alpha1 + + w_new.data = z - alpha3*w_old - alpha2*w + w_new.data = 1/alpha1 * w_new + + u.data += c_new*eta_old * w_new + eta = -s_new * eta_old + + #update of residuum + ResNorm = abs(s_new) * ResNorm_old + if self.CheckResidual(ResNorm): + return + k += 1 + + # shift vectors by renaming + v_old, v, v_new = v, v_new, v_old + w_old, w, w_new = w, w_new, w_old + z, z_new = z_new, z + + eta_old = eta + s_old = s + s = s_new + c_old = c + c = c_new + gamma = gamma_new + ResNorm_old = ResNorm -#Source: Michael Kolmbauer https://www.numa.uni-linz.ac.at/Teaching/PhD/Finished/kolmbauer-diss.pdf -@TimeFunction def MinRes(mat, rhs, pre=None, sol=None, maxsteps = 100, printrates = True, initialize = True, tol = 1e-7): """Minimal Residuum method @@ -385,106 +583,46 @@ Solution vector of the MinRes method. """ - u = sol if sol else rhs.CreateVector() - - v_new = rhs.CreateVector() - v = rhs.CreateVector() - v_old = rhs.CreateVector() - w_new = rhs.CreateVector() - w = rhs.CreateVector() - w_old = rhs.CreateVector() - z_new = rhs.CreateVector() - z = rhs.CreateVector() - mz = rhs.CreateVector() - - - if (initialize): - u[:] = 0.0 - v.data = rhs - else: - v.data = rhs - mat * u - - z.data = pre * v if pre else v - - #First Step - gamma = sqrt(InnerProduct(z,v)) - gamma_new = 0 - z.data = 1/gamma * z - v.data = 1/gamma * v - - ResNorm = gamma - ResNorm_old = gamma - - if (printrates): - print("it = ", 0, " err = ", ResNorm) - - eta_old = gamma - c_old = 1 - c = 1 - s_new = 0 - s = 0 - s_old = 0 - - v_old[:] = 0.0 - w_old[:] = 0.0 - w[:] = 0.0 - - k = 1 - while (k < maxsteps+1 and ResNorm > tol): - mz.data = mat*z - delta = InnerProduct(mz,z) - v_new.data = mz - delta*v - gamma * v_old - - z_new.data = pre * v_new if pre else v_new - - gamma_new = sqrt(InnerProduct(z_new, v_new)) - z_new *= 1/gamma_new - v_new *= 1/gamma_new - - alpha0 = c*delta - c_old*s*gamma - alpha1 = sqrt(alpha0*alpha0 + gamma_new*gamma_new) #** - alpha2 = s*delta + c_old*c*gamma - alpha3 = s_old * gamma + return MinResSolver(mat=mat, pre=pre, maxiter=maxsteps, + printrates=printrates, + tol=tol).Solve(rhs=rhs, sol=sol, + initialize=initialize) - c_new = alpha0/alpha1 - s_new = gamma_new/alpha1 - w_new.data = z - alpha3*w_old - alpha2*w - w_new.data = 1/alpha1 * w_new - - u.data += c_new*eta_old * w_new - eta = -s_new * eta_old - - - #update of residuum - ResNorm = abs(s_new) * ResNorm_old - if (printrates): - print("it = ", k, " err = ", ResNorm) - if ResNorm < tol: break - k += 1 - - # shift vectors by renaming - v_old, v, v_new = v, v_new, v_old - w_old, w, w_new = w, w_new, w_old - z, z_new = z_new, z - - eta_old = eta - - s_old = s - s = s_new +class RichardsonSolver(LinearSolver): + """ Preconditioned Richardson Iteration - c_old = c - c = c_new +Parameters +---------- +""" + linear_solver_param_doc + """ - gamma = gamma_new - ResNorm_old = ResNorm - else: - print("Warning: MinRes did not converge to TOL") +dampfactor : float = 1. + Set the damping factor for the Richardson iteration. If it is 1 then no damping is done. Values greater than 1 are allowed. +""" + name = "Richardson" + def __init__(self, *args, dampfactor = 1., **kwargs): + super().__init__(*args, **kwargs) + self.dampfactor = dampfactor + + def _SolveImpl(self, rhs : BaseVector, sol : BaseVector): + r = rhs.CreateVector() + d = sol.CreateVector() + r.data = rhs - self.mat*sol + d.data = self.pre * r + res_norm = abs(InnerProduct(d,r)) + if self.CheckResidual(res_norm): + return - return u + while True: + sol.data += self.dampfactor * d + r.data = rhs - self.mat * sol + d.data = self.pre * r + + res_norm = abs(InnerProduct(d,r)) + if self.CheckResidual(res_norm): + return -@TimeFunction def PreconditionedRichardson(a, rhs, pre=None, freedofs=None, maxit=100, tol=1e-8, dampfactor=1.0, printing=True): """ Preconditioned Richardson Iteration @@ -520,7 +658,6 @@ Solution vector of the Preconditioned Richardson iteration. """ - u = rhs.CreateVector() r = rhs.CreateVector() u[:] = 0 @@ -548,13 +685,150 @@ else: print("Warning: Preconditioned Richardson did not converge to TOL") - return u + return u + +class GMResSolver(LinearSolver): + """Preconditioned GMRes solver. Minimizes the preconditioned residuum pre * (b-A*x) + +Parameters +---------- +""" + linear_solver_param_doc + """ + +innerproduct : Callable[[BaseVector, BaseVector], Union[float, complex]] = None + Innerproduct to be used in iteration, all orthogonalizations/norms are computed with respect to that inner product. + +restart : int = None + If given, GMRes is restarted with the current solution x every 'restart' steps. +""" + name = "GMRes" + + def __init__(self, *args, + innerproduct : Optional[Callable[[BaseVector, BaseVector], + Union[float, complex]]] = None, + restart : Optional[int] = None, + **kwargs): + super().__init__(*args, **kwargs) + if innerproduct is not None: + self.innnerproduct = innerproduct + self.norm = lambda x: sqrt(innerproduct(x,x).real) + else: + self.innerproduct = lambda x, y: y.InnerProduct(x, conjugate=True) + self.norm = Norm + self.restart = restart + + def _SolveImpl(self, rhs : BaseVector, sol : BaseVector): + is_complex = rhs.is_complex + A, pre, innerproduct, norm = self.mat, self.pre, self.innerproduct, self.norm + n = len(rhs) + m = self.maxiter + sn = Vector(m, is_complex) + cs = Vector(m, is_complex) + sn[:] = 0 + cs[:] = 0 + if self.callback_sol is not None: + sol_start = sol.CreateVector() + sol_start.data = sol + r = rhs.CreateVector() + tmp = rhs.CreateVector() + tmp.data = rhs - A * sol + r.data = pre * tmp + Q = [] + H = [] + Q.append(rhs.CreateVector()) + r_norm = norm(r) + if self.CheckResidual(abs(r_norm)): + return sol + Q[0].data = 1./r_norm * r + beta = Vector(m+1, is_complex) + beta[:] = 0 + beta[0] = r_norm + + def arnoldi(A,Q,k): + q = rhs.CreateVector() + tmp.data = A * Q[k] + q.data = pre * tmp + h = Vector(m+1, is_complex) + h[:] = 0 + for i in range(k+1): + h[i] = innerproduct(Q[i],q) + q.data += (-1)* h[i] * Q[i] + h[k+1] = norm(q) + if abs(h[k+1]) < 1e-12: + return h, None + q *= 1./h[k+1].real + return h, q + + def givens_rotation(v1,v2): + if v2 == 0: + return 1,0 + elif v1 == 0: + return 0,v2/abs(v2) + else: + t = sqrt((v1.conjugate()*v1+v2.conjugate()*v2).real) + cs = abs(v1)/t + sn = v1/abs(v1) * v2.conjugate()/t + return cs,sn + + def apply_givens_rotation(h, cs, sn, k): + for i in range(k): + temp = cs[i] * h[i] + sn[i] * h[i+1] + h[i+1] = -sn[i].conjugate() * h[i] + cs[i].conjugate() * h[i+1] + h[i] = temp + cs[k], sn[k] = givens_rotation(h[k], h[k+1]) + h[k] = cs[k] * h[k] + sn[k] * h[k+1] + h[k+1] = 0 + + def calcSolution(k): + # if callback_sol is set we need to recompute solution in every step + if self.callback_sol is not None: + sol.data = sol_start + mat = Matrix(k+1,k+1, is_complex) + for i in range(k+1): + mat[:,i] = H[i][:k+1] + rs = Vector(k+1, is_complex) + rs[:] = beta[:k+1] + y = mat.I * rs + for i in range(k+1): + sol.data += y[i] * Q[i] + + for k in range(m): + h,q = arnoldi(A,Q,k) + H.append(h) + if q is None: + break + Q.append(q) + apply_givens_rotation(h, cs, sn, k) + beta[k+1] = -sn[k].conjugate() * beta[k] + beta[k] = cs[k] * beta[k] + error = abs(beta[k+1]) + if self.callback_sol is not None: + calcSolution(k) + if self.CheckResidual(error): + break + if self.restart is not None and (k+1 == self.restart and not (self.restart == self.maxiter)): + calcSolution(k) + del Q + restarted_solver = GMResSolver(mat=self.mat, + pre=self.pre, + tol=0, + atol=self._final_residual, + callback=self.callback, + callback_sol=self.callback_sol, + maxiter=self.maxiter, + restart=self.restart, + printrates=self.printrates) + restarted_solver.iterations = self.iterations + sol = restarted_solver.Solve(rhs = rhs, sol = sol, initialize=False) + self.residuals += restarted_solver.residuals + self.iterations = restarted_solver.iterations + return sol + calcSolution(k) + return sol def GMRes(A, b, pre=None, freedofs=None, x=None, maxsteps = 100, tol = None, innerproduct=None, callback=None, restart=None, startiteration=0, printrates=True, reltol=None): - """ Restarting preconditioned gmres solver for A*x=b. Minimizes the preconditioned -residuum pre*(b-A*x) + """Restarting preconditioned gmres solver for A*x=b. Minimizes the preconditioned residuum pre*(b-A*x). Parameters ---------- @@ -580,7 +854,6 @@ Maximum iteration steps. tol : float = 1e-7 - Tolerance to be computed to. Gmres breaks if norm(pre*(b-A*x)) < tol. innerproduct : function = None Innerproduct to be used in iteration, all orthogonalizations/norms are computed with @@ -588,7 +861,6 @@ callback : function = None If given, this function is called with the solution vector x in each step. Only for debugging - purposes, since it requires the overhead of computing x in every step. restart : int = None If given, gmres is restarted with the current solution x every 'restart' steps. @@ -600,125 +872,9 @@ printrates : bool = True Print norm of preconditioned residual in each step. """ - - if not innerproduct: - innerproduct = lambda x,y: y.InnerProduct(x, conjugate=True) - norm = Norm - else: - norm = lambda x: sqrt(innerproduct(x,x).real) - is_complex = b.is_complex - if not pre: - assert freedofs is not None - pre = Projector(freedofs, True) - n = len(b) - m = maxsteps - if not x: - x = b.CreateVector() - x[:] = 0 - - if callback: - xstart = x.CreateVector() - xstart.data = x - else: - xstart = None - sn = Vector(m, is_complex) - cs = Vector(m, is_complex) - sn[:] = 0 - cs[:] = 0 - - r = b.CreateVector() - tmp = b.CreateVector() - tmp.data = b - A * x - r.data = pre * tmp - - Q = [] - H = [] - Q.append(b.CreateVector()) - r_norm = norm(r) - if printrates: - print("Step 0, error = ", r_norm) - if reltol is not None and r_norm != 0: - rtol = reltol * abs(r_norm) - tol = rtol if tol is None else max(rtol, tol) - if tol is None: - tol = 1e-7 - if abs(r_norm) < tol: - return x - Q[0].data = 1./r_norm * r - beta = Vector(m+1, is_complex) - beta[:] = 0 - beta[0] = r_norm - - def arnoldi(A,Q,k): - q = b.CreateVector() - tmp.data = A * Q[k] - q.data = pre * tmp - h = Vector(m+1, is_complex) - h[:] = 0 - for i in range(k+1): - h[i] = innerproduct(Q[i],q) - q.data += (-1)* h[i] * Q[i] - h[k+1] = norm(q) - if abs(h[k+1]) < 1e-12: - return h, None - q *= 1./h[k+1].real - return h, q - - def givens_rotation(v1,v2): - if v2 == 0: - return 1,0 - elif v1 == 0: - return 0,v2/abs(v2) - else: - t = sqrt((v1.conjugate()*v1+v2.conjugate()*v2).real) - cs = abs(v1)/t - sn = v1/abs(v1) * v2.conjugate()/t - return cs,sn - - def apply_givens_rotation(h, cs, sn, k): - for i in range(k): - temp = cs[i] * h[i] + sn[i] * h[i+1] - h[i+1] = -sn[i].conjugate() * h[i] + cs[i].conjugate() * h[i+1] - h[i] = temp - cs[k], sn[k] = givens_rotation(h[k], h[k+1]) - h[k] = cs[k] * h[k] + sn[k] * h[k+1] - h[k+1] = 0 - - def calcSolution(k): - mat = Matrix(k+1,k+1, is_complex) - for i in range(k+1): - mat[:,i] = H[i][:k+1] - rs = Vector(k+1, is_complex) - rs[:] = beta[:k+1] - y = mat.I * rs - if xstart: - x.data = xstart - for i in range(k+1): - x.data += y[i] * Q[i] - - for k in range(m): - startiteration += 1 - h,q = arnoldi(A,Q,k) - H.append(h) - if q is None: - break - Q.append(q) - apply_givens_rotation(h, cs, sn, k) - beta[k+1] = -sn[k].conjugate() * beta[k] - beta[k] = cs[k] * beta[k] - error = abs(beta[k+1]) - if printrates: - print("Step", startiteration, ", error = ", error) - if callback: - calcSolution(k) - callback(x) - if error < tol: - break - if restart and k+1 == restart and not (restart == maxsteps): - calcSolution(k) - del Q - return GMRes(A, b, freedofs=freedofs, pre=pre, x=x, maxsteps=maxsteps-restart, callback=callback, - tol=tol, innerproduct=innerproduct, - restart=restart, startiteration=startiteration, printrates=printrates) - calcSolution(k) - return x + solver = GMResSolver(mat=A, pre=pre, freedofs=freedofs, + maxiter=maxsteps, tol=reltol, atol=tol, + innerproduct=innerproduct, + callback_sol=callback, restart=restart, + printrates=printrates) + return solver.Solve(rhs=b, sol=x) diff -Nru ngsolve-6.2.2102/python/webgui/build.py ngsolve-6.2.2103/python/webgui/build.py --- ngsolve-6.2.2102/python/webgui/build.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/build.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -from glob import glob -import sys, os -from base64 import b64encode -import json -sdir = sys.argv[1]+'/' -bdir = sys.argv[2]+'/' -code = open(sdir+"webgui_template.py","r").read() - -jscode = open(bdir+"standalone.js","r").read() -code = code.replace('render_js_code = ""', 'render_js_code = r"""'+ jscode + '"""') - -widgets_version = '^'+json.load(open(sdir+'/js/package.json'))['version'] -code = code.replace('widgets_version = ""', 'widgets_version = "'+ widgets_version + '"') - -open("webgui.py","w").write(code) diff -Nru ngsolve-6.2.2102/python/webgui/build_shaders.py ngsolve-6.2.2103/python/webgui/build_shaders.py --- ngsolve-6.2.2102/python/webgui/build_shaders.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/build_shaders.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -from glob import glob -import sys, os -from base64 import b64encode -import json -p = sys.argv[1]+'/' - -shader_codes = {} -for f in glob(p+"shader/*"): - name = os.path.basename(f) - source = b64encode(open(f,"r").read().encode("ascii")).decode("ascii") - shader_codes[name] = source - -source = "export const shaders = " + json.dumps(shader_codes) -open(p+"/js/src/shaders.ts","w").write(source) diff -Nru ngsolve-6.2.2102/python/webgui/bump_js_package_version.py ngsolve-6.2.2103/python/webgui/bump_js_package_version.py --- ngsolve-6.2.2102/python/webgui/bump_js_package_version.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/bump_js_package_version.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -#! /usr/bin/python3 - -# 1) set new version in package.json -# 2) build ngsolve js package -> generates .tgz with new package -# 3) release widgets package with 'npm publish' -# 4) update SHA1 value in ngsolve_jupyter_widgets.sha1sum -# 5) commit changes in ngsolve_jupyter_widgets and package.json (done manually) - -import sys, json, subprocess -package_json = json.load(open("js/package.json")) -old_version = package_json['version'] - -if len(sys.argv) < 2: - print("Usage: {} new_version".format(sys.argv[0])) - print("Current version: "+old_version) - exit(1) - -new_version = sys.argv[1] - -def onError(): - package_json['version'] = old_version - json.dump(package_json, open("js/package.json", "w"), indent=2) - exit(1) - -def runCommand(cmd): - proc = subprocess.run(cmd, capture_output=True, cwd="js") - if proc.returncode!=0: - print('ERROR:') - print(proc.stdout.decode()) - print(proc.stderr.decode()) - onError() - - return proc.stdout.decode() - -answer = '' -while answer not in ['y','n']: - answer = input('bumping version from {} to {}, are you sure? [y/n] '.format(old_version, new_version)) - -if new_version <= old_version: - print("error: cannot decrease version number") - exit(1) - -if answer == 'y': - package_json['version'] = new_version - json.dump(package_json, open("js/package.json", "w"), indent=2) - print("new version set to {}".format(new_version)) - print("building js package...", end=" ", flush=True) - runCommand(['npm', 'run', 'build']) - runCommand(['npm', 'pack']) - print("done") - print("publishing js package...", end=" ", flush=True) - runCommand(['npm', 'publish']) - print("done") - print("update SHA1 sum in CMakeLists.txt...") - sha1sum = runCommand(["sha1sum", "ngsolve_jupyter_widgets-{}.tgz".format(new_version)]) - open("js/ngsolve_jupyter_widgets.sha1sum","w").write(sha1sum.split(' ')[0]) - print("git add package.json ngsolve_jupyter_widgets.sha1sum") - runCommand(["git", "add", "package.json", "ngsolve_jupyter_widgets.sha1sum"]) - print("Done! Run git commit to commit the version bump") - diff -Nru ngsolve-6.2.2102/python/webgui/CMakeLists.txt ngsolve-6.2.2103/python/webgui/CMakeLists.txt --- ngsolve-6.2.2102/python/webgui/CMakeLists.txt 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -include (ExternalProject) - -set(sdir ${CMAKE_CURRENT_SOURCE_DIR}) -set(bdir ${CMAKE_CURRENT_SOURCE_DIR}/js/package) - -if(BUILD_JUPYTER_WIDGETS) - find_program(NPM NAMES npm) - add_custom_command(OUTPUT ${sdir}/js/src/shaders.ts - COMMAND ${NETGEN_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/build_shaders.py ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS - build_shaders.py - shader/clipping_vectors.vert - shader/function.frag - shader/splines.frag - shader/splines.vert - shader/trigsplines.vert - shader/utils.h - shader/vector_function.vert - ) - - add_custom_command( - OUTPUT - ${bdir}/standalone.js - DEPENDS - js/package.json - js/tsconfig.json - js/webpack.config.js - js/src/extension.ts - js/src/index.ts - js/src/plugin.ts - js/src/scene.ts - js/src/shaders.ts - js/src/version.ts - js/src/widget.ts - COMMAND ${NPM} run build - COMMAND ${CMAKE_COMMAND} -E remove -f "*.tgz" - COMMAND ${NPM} pack - COMMAND ${CMAKE_COMMAND} -E tar xvf "*.tgz" - COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${bdir}/standalone.js" - COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${bdir}/standalone.js" - COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${bdir}/nbextension/static/index.js.map" - COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${bdir}/nbextension/static/index.js" - COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${bdir}/labextension/plugin.js.map" - COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${bdir}/labextension/plugin.js" - - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/js - ) - - else(BUILD_JUPYTER_WIDGETS) - # download prebuild widgets library - - # read lib version from package.json - execute_process(COMMAND ${NETGEN_PYTHON_EXECUTABLE} -c - "import json;print(json.load(open('package.json'))['version'])" - OUTPUT_VARIABLE WIDGETS_VERSION - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/js - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - file(READ ${sdir}/js/ngsolve_jupyter_widgets.sha1sum NGS_JSPACKAGE_SHA1SUM) - - ExternalProject_Add( - download_widgets - URL "https://registry.npmjs.org/ngsolve_jupyter_widgets/-/ngsolve_jupyter_widgets-${WIDGETS_VERSION}.tgz" - URL_HASH SHA1=${NGS_JSPACKAGE_SHA1SUM} - DOWNLOAD_NO_PROGRESS ON - SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/js/package - DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/external_dependencies/ - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory "${bdir}" - BUILD_COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${bdir}/standalone.js" - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory . "${bdir}" - UPDATE_COMMAND "" - TEST_COMMAND "" - ) - - # adds dependency to behave like the content was compiled - add_custom_command(OUTPUT ${bdir}/standalone.js COMMAND ; DEPENDS download_widgets) -endif(BUILD_JUPYTER_WIDGETS) - -add_custom_command(OUTPUT webgui.py - COMMAND ${NETGEN_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/build.py ${sdir} ${bdir} - DEPENDS - build.py - webgui_template.py - ${bdir}/standalone.js - ) - -add_custom_target(js_widgets ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/webgui.py) - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/webgui.py DESTINATION ${NGSOLVE_INSTALL_DIR_PYTHON}/ngsolve COMPONENT ngsolve) - -# jupyter notebook extension -install(DIRECTORY ${bdir}/nbextension DESTINATION ${NGSOLVE_INSTALL_DIR_PYTHON}/ngsolve COMPONENT ngsolve) -install(FILES js/extension.js DESTINATION ${NGSOLVE_INSTALL_DIR_PYTHON}/ngsolve/nbextension/static COMPONENT ngsolve) - -# jupyter lab extension -install(DIRECTORY ${bdir}/labextension DESTINATION ${NGSOLVE_INSTALL_DIR_PYTHON}/ngsolve/labextension COMPONENT ngsolve) -install(FILES js/package/package.json DESTINATION ${NGSOLVE_INSTALL_DIR_PYTHON}/ngsolve/labextension COMPONENT ngsolve) - -find_program(JUPYTER_NBEXTENSION NAMES jupyter-nbextension) -if(JUPYTER_NBEXTENSION) - install(CODE "execute_process(COMMAND ${JUPYTER_NBEXTENSION} install --user --py ngsolve)") - install(CODE "execute_process(COMMAND ${JUPYTER_NBEXTENSION} enable --user --py ngsolve)") - message(STATUS "Found jupyter nbextension: ${JUPYTER_NBEXTENSION} -- ngsolve extension will be installed") -endif(JUPYTER_NBEXTENSION) - diff -Nru ngsolve-6.2.2102/python/webgui/js/extension.js ngsolve-6.2.2103/python/webgui/js/extension.js --- ngsolve-6.2.2102/python/webgui/js/extension.js 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/extension.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// Entry point for the notebook bundle containing custom model definitions. -// -define(function() { - "use strict"; - - window['requirejs'].config({ - map: { - '*': { - 'ngsolve_jupyter_widgets': 'nbextensions/ngsolve_jupyter_widgets/index', - }, - } - }); - // Export the required load_ipython_extension function - return { - load_ipython_extension : function() {} - }; -}); diff -Nru ngsolve-6.2.2102/python/webgui/js/ngsolve_jupyter_widgets.sha1sum ngsolve-6.2.2103/python/webgui/js/ngsolve_jupyter_widgets.sha1sum --- ngsolve-6.2.2102/python/webgui/js/ngsolve_jupyter_widgets.sha1sum 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/ngsolve_jupyter_widgets.sha1sum 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -95168b262c0de04e32aab06876f5ff8edfe94565 \ No newline at end of file diff -Nru ngsolve-6.2.2102/python/webgui/js/package.json ngsolve-6.2.2103/python/webgui/js/package.json --- ngsolve-6.2.2102/python/webgui/js/package.json 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/package.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -{ - "name": "ngsolve_jupyter_widgets", - "version": "2.2.1", - "description": "NGSolve Jupyter Widget Library", - "keywords": [ - "netgen", - "ngsolve", - "jupyter", - "jupyterlab", - "jupyterlab-extension", - "widgets" - ], - "files": [ - "tsconfig.json", - "webpack.config.js", - "src/*.ts", - "standalone.js*", - "nbextension/", - "labextension/", - "dist/", - "docs/", - "lib/**/*.js", - "dist/*.js" - ], - "homepage": "https://github.com/NGSolve/ngsolve", - "bugs": { - "url": "https://github.com/NGSolve/ngsolve/issues" - }, - "license": "BSD-3-Clause", - "author": { - "name": "Matthias Hochsteger", - "email": "mhochsteger@cerbsim.com" - }, - "main": "lib/index.js", - "types": "./lib/index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/NGSolve/ngsolve" - }, - "scripts": { - "build": "npm install && npm run build:lib && npm run build:nbextension", - "build:lib": "tsc", - "build:nbextension": "webpack -p", - "clean": "rimraf package", - "prepack": "npm run build:lib", - "prepublishOnly": "npm run clean && npm run build" - }, - "dependencies": { - "@jupyter-widgets/base": "^2||^3" - }, - "devDependencies": { - "@lumino/application": "^1.6.0", - "@lumino/widgets": "^1.6.0", - "@types/expect.js": "^0.3.29", - "@types/node": "^12.6.9", - "@types/webpack-env": "^1.13.6", - "dat.gui": "^0.7.7", - "npm-run-all": "^4.1.3", - "source-map-loader": "^0.2.4", - "three": "^0.115", - "ts-loader": "^6.0.4", - "typescript": "~3.5.3", - "webpack": "^4.39.1", - "webpack-cli": "^3.3.6" - }, - "jupyterlab": { - "extension": "labextension/plugin" - } -} diff -Nru ngsolve-6.2.2102/python/webgui/js/src/extension.ts ngsolve-6.2.2103/python/webgui/js/src/extension.ts --- ngsolve-6.2.2102/python/webgui/js/src/extension.ts 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/src/extension.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -// Copyright (c) Jupyter Development Team. -// Distributed under the terms of the Modified BSD License. - -// Entry point for the notebook bundle containing custom model definitions. -// -// Setup notebook base URL -// -// Some static assets may be required by the custom widget javascript. The base -// url for the notebook is not known at build time and is therefore computed -// dynamically. -(window as any).__webpack_public_path__ = document.querySelector('body')!.getAttribute('data-base-url') + 'nbextensions/ngsolve_jupyter_widgets'; - -export * from './index'; diff -Nru ngsolve-6.2.2102/python/webgui/js/src/index.ts ngsolve-6.2.2103/python/webgui/js/src/index.ts --- ngsolve-6.2.2102/python/webgui/js/src/index.ts 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/src/index.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -// Copyright (c) Matthias Hochsteger -// Distributed under the terms of the Modified BSD License. - -export * from './version'; -export * from './scene'; -export * from './widget'; diff -Nru ngsolve-6.2.2102/python/webgui/js/src/plugin.ts ngsolve-6.2.2103/python/webgui/js/src/plugin.ts --- ngsolve-6.2.2102/python/webgui/js/src/plugin.ts 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/src/plugin.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// Copyright (c) Matthias Hochsteger -// Distributed under the terms of the Modified BSD License. - -import { - Application, IPlugin -} from '@lumino/application'; - -import { - Widget -} from '@lumino/widgets'; - -import { - IJupyterWidgetRegistry - } from '@jupyter-widgets/base'; - -import * as widgetExports from './widget'; - -import { - MODULE_NAME, MODULE_VERSION -} from './version'; - -const EXTENSION_ID = 'ngsolve_jupyter_widgets:plugin'; - -/** - * The example plugin. - */ -const plugin: IPlugin, void> = { - id: EXTENSION_ID, - requires: [IJupyterWidgetRegistry], - activate: activateWidgetExtension, - autoStart: true -}; - -export default plugin; - - -/** - * Activate the widget extension. - */ -function activateWidgetExtension(app: Application, registry: IJupyterWidgetRegistry): void { - registry.registerWidget({ - name: MODULE_NAME, - version: MODULE_VERSION, - exports: widgetExports, - }); -} diff -Nru ngsolve-6.2.2102/python/webgui/js/src/scene.ts ngsolve-6.2.2103/python/webgui/js/src/scene.ts --- ngsolve-6.2.2102/python/webgui/js/src/scene.ts 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/src/scene.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,1918 +0,0 @@ -import { - MODULE_NAME, MODULE_VERSION -} from './version'; - -import { - shaders -} from './shaders'; - -import * as THREE from 'three'; -// import Stats from "https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min"; -import dat from 'dat.gui'; - - -function readB64(base64) { - var binary_string = window.atob(base64); - var len = binary_string.length; - var bytes = new Uint8Array(len); - for (var i = 0; i < len; i++) { - bytes[i] = binary_string.charCodeAt(i); - } - return new Float32Array( bytes.buffer ); -} - -function setKeys (dst, src) { - for(var key in dst) { - if(typeof(dst[key])=="object" && src[key] !== undefined) - setKeys(dst[key], src[key]); - else - { - dst[key] = src[key]; - } - } -} - -function getShader(name, defines = {}, user_eval_function = null) -{ - defines = {...defines}; // copy dictionary - if(name.endsWith(".vert")) - defines["VERTEX_SHADER"] = true; - if(name.endsWith(".frag")) - defines["FRAGMENT_SHADER"] = true; - - if(user_eval_function) - defines["USER_FUNCTION"] = user_eval_function; - - var s =""; - var nl = String.fromCharCode(10); // avoid escape characters - for(var key in defines) - s += "#define " + key + " " + defines[key] + nl; - - - var utils = window.atob(shaders['utils.h']); - var shader = window.atob(shaders[name]).trim(); - return s + "// START FILE: utils.h"+nl + utils +nl+"// START FILE: " + name + nl + shader; -} - - -function getCookie(cname) { - var name = cname + "="; - var decodedCookie = decodeURIComponent(document.cookie); - var ca = decodedCookie.split(';'); - for(var i = 0; i { - scope.transmat.identity(); - scope.rotmat.identity(); - scope.centermat.identity(); - scope.transformationmat.identity(); - scope.scale = 1.0/this.mesh_radius; - scope.center.copy(scene.mesh_center); - scope.centermat.makeTranslation(-this.center.x, -this.center.y, -this.center.z); - scope.update(); - scope.scene.setCenterTag(); - } - - this.update = function () { - var scale_vec = new THREE.Vector3(); - return function update() { - scale_vec.setScalar(scope.scale); - scope.pivotObject.matrix.copy(scope.transmat).multiply(scope.rotmat).scale(scale_vec).multiply(scope.centermat); - const aspect = this.domElement.offsetWidth/this.domElement.offsetHeight; - this.scene.axes_object.matrixWorld.makeTranslation(-0.85*aspect, -0.85, 0).multiply(scope.rotmat); - scope.dispatchEvent( changeEvent ); - }; - }() - - this.rotateObject = function () { - var mat = new THREE.Matrix4(); - return function(axis, rad) { - mat.makeRotationAxis(axis, rad); - scope.rotmat.premultiply(mat); - }; - }(); - - this.panObject = function () { - var mat = new THREE.Matrix4(); - return function(dir, dist) { - mat.makeTranslation(dist*dir.x, dist*dir.y, dist*dir.z); - scope.transmat.premultiply(mat); - }; - }(); - - this.updateCenter = function () { - return function() { - console.log("set mesh center to", scope.center); - scope.centermat.makeTranslation(-scope.center.x, -scope.center.y, -scope.center.z); - scope.transmat.identity(); - scope.scene.setCenterTag(); - scope.update(); - }; - }(); - - function keydown(event) { - var needs_update = false; - - if (event.shiftKey){ // pan - if (event.keyCode == scope.keys.DOWN) { - needs_update = true; - scope.panObject(new THREE.Vector3(0, -1, 0), scope.pan_step) - } else if (event.keyCode == scope.keys.UP) { - needs_update = true; - scope.panObject(new THREE.Vector3(0, 1, 0), scope.pan_step) - } else if (event.keyCode == scope.keys.LEFT) { - needs_update = true; - scope.panObject(new THREE.Vector3(-1, 0, 0), scope.pan_step) - } else if (event.keyCode == scope.keys.RIGHT) { - needs_update = true; - scope.panObject(new THREE.Vector3(1, 0, 0), scope.pan_step) - } - - } else { // rotate - if (event.keyCode == scope.keys.DOWN) { - needs_update = true; - scope.rotateObject(new THREE.Vector3(1, 0, 0), scope.rotation_step_degree) - } else if (event.keyCode == scope.keys.UP) { - needs_update = true; - scope.rotateObject(new THREE.Vector3(-1, 0, 0), scope.rotation_step_degree) - } else if (event.keyCode == scope.keys.LEFT) { - needs_update = true; - scope.rotateObject(new THREE.Vector3(0, -1, 0), scope.rotation_step_degree) - } else if (event.keyCode == scope.keys.RIGHT) { - needs_update = true; - scope.rotateObject(new THREE.Vector3(0, 1, 0), scope.rotation_step_degree) - } else if (event.keyCode == scope.keys.CLOCKWISE) { - needs_update = true; - scope.rotateObject(new THREE.Vector3(0, 0, 1), scope.rotation_step_degree) - } else if (event.keyCode == scope.keys.COUNTERCLOCKWISE) { - needs_update = true; - scope.rotateObject(new THREE.Vector3(0, 0, -1), scope.rotation_step_degree) - } - } - - if(needs_update) { - event.preventDefault(); - scope.update(); - } - - } - - function onMouseDown(event) { - if(event.button==0) { - event.preventDefault(); - scope.mode = "rotate"; - } - if(event.button==2) { - event.preventDefault(); - scope.mode = "move"; - } - event.stopPropagation(); - } - - function onMouseUp(event) { - scope.mode = null; - scope.dispatchEvent( changeEvent ); - } - - - function onMouseMove(event) { - var needs_update = false; - - if(scope.mode=="rotate") - { - needs_update = true; - scope.rotateObject(new THREE.Vector3(1, 0, 0), 0.01*event.movementY); - scope.rotateObject(new THREE.Vector3(0, 1, 0), 0.01*event.movementX); - } - - if(scope.mode=="move") - { - needs_update = true; - scope.panObject(new THREE.Vector3(1, 0, 0), 0.004*event.movementX); - scope.panObject(new THREE.Vector3(0, -1, 0), 0.004*event.movementY); - } - - if(needs_update) { - event.preventDefault(); - scope.update(); - } - } - - var oldtouch = new THREE.Vector2(0,0); - var olddelta = 0; - var touchfirst = true; - - function onTouchStart(event) { - touchfirst = true; - } - - function onTouchMove(event) { - - event.preventDefault(); - - switch ( event.touches.length ) { - case 1: - var pos = new THREE.Vector2(event.touches[0].pageX, event.touches[0].pageY); - if (!touchfirst) { - scope.rotateObject(new THREE.Vector3(1, 0, 0), 0.01*(pos.y-oldtouch.y)); - scope.rotateObject(new THREE.Vector3(0, 1, 0), 0.01*(pos.x-oldtouch.x)); - } - oldtouch = pos; - touchfirst = false; - scope.update(); - break; - - default: // 2 or more - var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; - var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; - var delta = Math.sqrt( dx * dx + dy * dy ); - if (!touchfirst) { - var s = Math.exp(0.01*(delta-olddelta)); - scope.scale *= s; - if( scope.scene.center_tag ) - scope.scene.center_tag.scale.multiplyScalar(1.0/s); - } - touchfirst = false; - scope.update(); - olddelta = delta; - break; - } - } - - - - function wheel(event) { - event.preventDefault(); - event.stopPropagation(); - - let dy = event.deltaY; - if(event.deltaMode==1) // 1==DOM_DELTA_LINE -> scroll in lines, not pixels - dy *= 30; - - var s = Math.exp(-0.001*dy); - scope.scale *= s ; - if( scope.scene.center_tag ) - scope.scene.center_tag.scale.multiplyScalar(1.0/s); - scope.update(); - } - - function contextmenu( event ) { - event.preventDefault(); - } - - function getPixel(scene, mouse){ - - } - - function onDblClick( event ){ - event.preventDefault(); - var rect = scope.domElement.getBoundingClientRect(); - scope.scene.mouse.set(event.clientX-rect.left, event.clientY-rect.top); - scene.get_pixel = true; - scope.dispatchEvent( changeEvent ); - - } - - scope.domElement.addEventListener('dblclick', onDblClick, false); - - // scope.domElement.addEventListener( 'mouseup', onMouseUp, false ); - window.addEventListener( 'mouseup', onMouseUp, false ); - scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); - scope.domElement.addEventListener( 'contextmenu', contextmenu, false ); - window.addEventListener( 'mousemove', onMouseMove, false ); - - scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); - scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); - - // window.addEventListener( 'keydown', keydown, false ); - scope.domElement.addEventListener( 'wheel', wheel, false ); - - - // make sure element can receive keys. - - if ( scope.domElement.tabIndex === - 1 ) { - - scope.domElement.tabIndex = 0; - - } - - this.reset(); -}; - - - -export class Scene { - render_data: any; - scene: THREE.Scene; - renderer: THREE.WebGLRenderer; - camera: THREE.PerspectiveCamera; - ortho_camera: THREE.OrthographicCamera; - clipping_plane: THREE.Vector4; - three_clipping_plane: THREE.Plane; - world_clipping_plane: THREE.Plane; - light_dir: THREE.Vector3; - colormap_divs: any; - colormap_labels: any; - container: any; - stats: any; - event_handlers: any; - - gui: any; - gui_status_default: any; - gui_status: any; - gui_functions: any; - gui_container: any; - uniforms: any; - - colormap_object: any; - edges_object: THREE.Line; - wireframe_object: THREE.Line; - mesh_object: THREE.Mesh; - clipping_function_object: THREE.Mesh; - clipping_vectors_object: THREE.Mesh; - axes_object: any; - center_tag: any; - - is_complex: boolean; - context: any; - trafo: any; - render_target: any; - mouse: THREE.Vector2; - get_pixel: boolean; - - last_frame_time: number; - - multidim_controller: any; - - phase_controller: any; - c_cmin: any; - c_cmax: any; - - buffer_scene: THREE.Scene; - buffer_object: THREE.Mesh; - buffer_camera: THREE.OrthographicCamera; - buffer_texture: any; - - mesh_center: THREE.Vector3; - mesh_radius: number; - - requestId: number; - have_webgl2: boolean; - - pivot: THREE.Group; - - have_deformation: boolean; - have_z_deformation: boolean; - label_style: string; - - controls: any; - element: any; - - funcdim: number; - mesh_only: boolean; - - version_object: any; - c_autoscale: any; - c_eval: any; - - colormap_texture: any; - - constructor() { - this.have_webgl2 = false; - - this.label_style = '-moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; onselectstart="return false;'; - this.label_style += 'onmousedown="return false; user-select:none;-o-user-select:none;unselectable="on";'; - this.label_style += 'position: absolute; z-index: 1; display:block;'; - this.requestId = 0; - this.event_handlers = {}; - } - - on( event_name, handler ) { - if(this.event_handlers[event_name] == undefined) - this.event_handlers[event_name] = []; - - this.event_handlers[event_name].push( handler ); - } - - handleEvent( event_name, args ) - { - let handlers = this.event_handlers[event_name]; - if(handlers == undefined) - return; - - for(var i=0; i=cmax) - return 1e-8; - const step = Math.pow(10, -4+Math.floor(Math.log10(cmax-cmin))); - const prec = 10; - this.c_cmin.step(step); - this.c_cmax.step(step); - this.c_cmin.__precision = prec; - this.c_cmax.__precision = prec; - } - - - onResize() { - const w = this.element.parentNode.clientWidth; - const h = this.element.parentNode.clientHeight; - - const aspect = w/h; - this.ortho_camera = new THREE.OrthographicCamera( -aspect, aspect, 1.0, -1.0, -100, 100 ); - if(this.colormap_object) - { - const x0 = -aspect*0.93; - const y0 = 0.93; - this.colormap_object.position.set(x0, 0.95, 0.0); - this.colormap_object.updateWorldMatrix( false, false ); - - const n = this.colormap_labels.length; - const y = Math.round(0.5*(0.05+0.07)*h); - for(var i=0; ithis.clipping_vectors_object.geometry; - var arrowid = new Float32Array(2*n * n); - for(var i=0; i min is 0 - { - s.colormap_min = 0.0; - s.colormap_max = Math.max(def.colormap_max, def.colormap_min); - } - else - { - s.colormap_min = def.colormap_min; - s.colormap_max = def.colormap_max; - } - this.c_cmin.updateDisplay(); - this.c_cmax.updateDisplay(); - this.updateColormapLabels(); - this.animate(); - } - - initCanvas (element, webgl_args) - { - this.element = element; - var canvas = document.createElement( 'canvas' ); - - var gl2 = canvas.getContext('webgl2'); - - if (gl2) { - console.log('webgl2 is supported!'); - this.context = canvas.getContext( 'webgl2', { alpha: false, ...webgl_args } ); - this.have_webgl2 = true; - } - else - { - console.log('your browser/OS/drivers do not support WebGL2'); - this.context = canvas.getContext( 'webgl', { alpha: false, ...webgl_args } ); - } - - this.renderer = new THREE.WebGLRenderer( { canvas: canvas, context: this.context } ); - this.renderer.autoClear = false; - console.log("Renderer", this.renderer); - - this.render_target = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight ); - this.render_target.texture.format = THREE.RGBAFormat; - this.render_target.texture.type = THREE.FloatType; - - //this is to get the correct pixel detail on portable devices - this.renderer.setPixelRatio( window.devicePixelRatio ); - // renderer.domElement.addEventListener("click", console.log, true) - - //and this sets the canvas' size. - this.renderer.setSize( this.element.offsetWidth, this.element.offsetHeight ); - this.renderer.setClearColor( 0xffffff, 1 ); - - this.container = document.createElement( 'div' ); - element.appendChild( this.container ); - - this.container.appendChild( this.renderer.domElement ); - - // label with NGSolve version at right lower corner - this.version_object = document.createElement("div"); - var style = 'bottom: 10px; right: 10px'; - this.version_object.setAttribute("style",this.label_style+style); - this.container.appendChild(this.version_object); - - window.addEventListener( 'resize', ()=>this.onResize(), false ); - } - - initRenderData (render_data) - { - if(this.gui_container!=undefined) - this.container.removeChild(this.gui_container); - - this.uniforms = {}; - this.gui_status_default = { - eval: 0, - subdivision: 5, - edges: true, - mesh: true, - elements: true, - autoscale: true, - colormap_ncolors: 8, - colormap_min: -1.0, - colormap_max: 1.0, - deformation: 0.0, - Multidim: { t: 0.0, multidim: 0, animate: false, speed: 2 }, - Complex: { phase: 0.0, deform: 0.0, animate: false, speed: 2 }, - Clipping: { enable: false, function: true, x: 0.0, y: 0.0, z: 1.0, dist: 0.0 }, - Light: { ambient: 0.3, diffuse: 0.7, shininess: 10, specularity: 0.3}, - Vectors: { show: false, grid_size: 10, offset: 0.0 }, - Misc: { stats: "-1", reduce_subdivision: false, "version": true, "axes": true, "colormap": true }, - }; - this.gui_status = JSON.parse(JSON.stringify(this.gui_status_default)); // deep-copy settings - this.gui_functions = { }; - - this.colormap_object = null; - - - this.colormap_object = null; - this.edges_object = null; - this.wireframe_object = null; - this.mesh_object = null; - this.clipping_function_object = null; - this.clipping_vectors_object = null; - this.axes_object = null; - this.buffer_scene = null; - this.buffer_object = null; - this.buffer_camera = null; - this.buffer_texture = null; - - this.last_frame_time = new Date().getTime(); - this.render_data = render_data; - this.funcdim = render_data.funcdim; - this.is_complex = render_data.is_complex; - console.log("THREE", THREE); - console.log("dat", dat); - // console.log("Stats", Stats); - - CameraControls.prototype = Object.create( THREE.EventDispatcher.prototype ); - CameraControls.prototype.constructor = CameraControls; - - this.have_deformation = render_data.mesh_dim == render_data.funcdim && !render_data.is_complex; - this.have_z_deformation = render_data.mesh_dim == 2 && render_data.funcdim>0; - this.mesh_only = render_data.funcdim==0; - - this.mesh_center = new THREE.Vector3().fromArray(render_data.mesh_center); - this.mesh_radius = render_data.mesh_radius; - - var version_text = document.createTextNode("NGSolve " + render_data.ngsolve_version); - this.version_object.innerHTML = ''; - this.version_object.appendChild(version_text) - - this.scene = new THREE.Scene(); - // if(window.matchMedia('(prefers-color-scheme: dark)').matches) - // this.scene.background = new THREE.Color(0x292c2e); - this.axes_object = new THREE.AxesHelper(0.15); - this.axes_object.matrixAutoUpdate = false; - - this.pivot = new THREE.Group(); - this.pivot.matrixAutoUpdate = false; - - this.buffer_scene = new THREE.Scene(); - - this.camera = new THREE.PerspectiveCamera( - 40, //FOV - this.element.offsetWidth/ this.element.offsetHeight, // aspect - 1, //near clipping plane - 100 //far clipping plane - ); - - this.camera.position.set( 0.0, 0.0, 3 ); - - this.clipping_plane = new THREE.Vector4(0,0,1,0); - let uniforms = this.uniforms; - uniforms.clipping_plane = new THREE.Uniform( this.clipping_plane ); - // should cliping plane in pivot world be calculated in shader insted of passing it? - //currently not done because it is needed here anyways - - this.three_clipping_plane = new THREE.Plane( ); - - var light_dir = new THREE.Vector3(0.5,0.5,1.5); - light_dir.normalize(); - uniforms.light_dir = new THREE.Uniform(light_dir); - var light_mat = new THREE.Vector4(0.3, 0.7, 10, 0.3); // ambient, diffuse, shininess, specularity - uniforms.light_mat = new THREE.Uniform(light_mat); - - uniforms.do_clipping = new THREE.Uniform( false ); - uniforms.render_depth = new THREE.Uniform( false ); - this.trafo = new THREE.Vector2(1.0/2.0/(this.mesh_center.length()+this.mesh_radius), 1.0/2.0); - uniforms.trafo = new THREE.Uniform(this.trafo); - - this.get_pixel = false; - this.mouse = new THREE.Vector2(0.0, 0.0); - this.center_tag = null; - - let gui = new dat.GUI({autoplace: false, closeOnTop: true, scrollable: true, closed: true}); - gui.closed = true; - let gui_container = document.createElement( 'div' ); - gui_container.setAttribute("style", 'position: absolute; z-index: 2; display:block; right: 0px; top: 0px'); - gui_container.appendChild(gui.domElement); - this.container.appendChild(gui_container); - this.gui_container = gui_container; - - this.gui = gui; - console.log("GUI", gui); - let gui_status = this.gui_status; - console.log("gui_status", gui_status); - let animate = ()=>this.animate(); - - if(render_data.show_wireframe) - { - this.edges_object = this.createCurvedWireframe(render_data); - this.pivot.add(this.edges_object); - this.wireframe_object = this.createCurvedWireframe(render_data); - this.pivot.add(this.wireframe_object); - uniforms.n_segments = new THREE.Uniform(5); - gui.add(gui_status, "subdivision", 1,20,1).onChange(animate); - gui.add(gui_status, "edges").onChange(animate); - gui.add(gui_status, "mesh").onChange(animate); - } - - if(render_data.show_mesh) - { - this.mesh_object = this.createCurvedMesh(render_data); - this.pivot.add( this.mesh_object ); - gui.add(gui_status, "elements").onChange(animate); - } - - - if(this.have_z_deformation || this.have_deformation) - { - this.gui_status_default.deformation = render_data.deformation ? 1.0 : 0.0; - gui_status.deformation = this.gui_status_default.deformation; - gui.add(gui_status, "deformation", 0.0, 1.0, 0.0001).onChange(animate); - uniforms.deformation = new THREE.Uniform( gui_status.deformation ); - } - - if(render_data.is_complex) - { - this.gui_status_default.eval = 5; - gui_status.eval = 5; - this.c_eval = gui.add(gui_status, "eval", {"real": 5,"imag":6,"norm":3}).onChange(animate); - - let cgui = gui.addFolder("Complex"); - this.phase_controller = cgui.add(gui_status.Complex, "phase", 0, 2*Math.PI, 0.001).onChange(animate); - cgui.add(gui_status.Complex, "animate").onChange(()=> {this.last_frame_time = new Date().getTime(); this.animate() }); - cgui.add(gui_status.Complex, "speed", 0.0, 10, 0.0001).onChange(animate); - uniforms.complex_scale = new THREE.Uniform( new THREE.Vector2(1, 0) ); - } - else if(render_data.funcdim==2) - { - gui_status.eval = 3; - this.c_eval = gui.add(gui_status, "eval", {"0": 0,"1":1,"norm":3}).onChange(animate); - } - else if(render_data.funcdim==3) - { - gui_status.eval = 3; - this.c_eval = gui.add(gui_status, "eval", {"0": 0,"1":1,"2":2,"norm":3}).onChange(animate); - } - - if(this.c_eval) - { - if(render_data.eval != undefined) - { - this.gui_status_default.eval = render_data.eval; - this.c_eval.setValue(render_data.eval); - } - this.c_eval.onChange(()=> { - if(gui_status.autoscale) - this.updateColormapToAutoscale(); - }); - } - - - if(render_data.mesh_dim == 3) - { - let gui_clipping = gui.addFolder("Clipping"); - if(render_data.draw_vol) - { - if(render_data.clipping_function != undefined) - { - this.gui_status_default.Clipping.function = render_data.clipping_function; - gui_status.Clipping.function = render_data.clipping_function; - } - - this.clipping_function_object = this.createClippingPlaneMesh(render_data); - this.pivot.add(this.clipping_function_object); - gui_clipping.add(gui_status.Clipping, "function").onChange(animate); - } - - if(render_data.clipping) - { - console.log("render data clipping found"); - this.gui_status_default.Clipping.enable = true; - gui_status.Clipping.enable = true; - if(render_data.clipping_x != undefined) - { - this.gui_status_default.Clipping.x = render_data.clipping_x; - gui_status.Clipping.x = render_data.clipping_x; - } - if(render_data.clipping_y != undefined) - { - this.gui_status_default.Clipping.y = render_data.clipping_y; - gui_status.Clipping.y = render_data.clipping_y; - } - if(render_data.clipping_z != undefined) - { - this.gui_status_default.Clipping.z = render_data.clipping_z; - gui_status.Clipping.z = render_data.clipping_z; - } - if(render_data.clipping_dist != undefined) - { - this.gui_status_default.Clipping.dist = render_data.clipping_dist; - gui_status.Clipping.dist = render_data.clipping_dist; - } - } - else - console.log("render data not clipping found!!!"); - - gui_clipping.add(gui_status.Clipping, "enable").onChange(animate); - gui_clipping.add(gui_status.Clipping, "x", -1.0, 1.0).onChange(animate); - gui_clipping.add(gui_status.Clipping, "y", -1.0, 1.0).onChange(animate); - gui_clipping.add(gui_status.Clipping, "z", -1.0, 1.0).onChange(animate); - gui_clipping.add(gui_status.Clipping, "dist", -1.2*this.mesh_radius, 1.2*this.mesh_radius).onChange(animate); - } - - uniforms.function_mode = new THREE.Uniform( 0 ); - let draw_vectors = render_data.funcdim>1 && !render_data.is_complex; - draw_vectors = draw_vectors && (render_data.draw_surf && render_data.mesh_dim==2 || render_data.draw_vol && render_data.mesh_dim==3); - if(draw_vectors) - { - if(render_data.vectors) - { - this.gui_status_default.Vectors.show = true; - gui_status.Vectors.show = true; - if(render_data.vectors_grid_size) - { - this.gui_status_default.Vectors.grid_size = render_data.vectors_grid_size; - gui_status.Vectors.grid_size = render_data.vectors_grid_size; - } - if(render_data.vectors_offset) - { - this.gui_status_default.Vectors.offset = render_data.vectors_offset; - gui_status.Vectors.offset = render_data.vectors_offset; - } - } - - let gui_vec = gui.addFolder("Vectors"); - gui_vec.add(gui_status.Vectors, "show").onChange(animate); - gui_vec.add(gui_status.Vectors, "grid_size", 1, 100, 1).onChange(()=>this.updateGridsize()); - gui_vec.add(gui_status.Vectors, "offset", -1.0, 1.0, 0.001).onChange(animate); - - - if(render_data.mesh_dim==2) - this.buffer_object = this.mesh_object.clone(); - else - this.buffer_object = this.clipping_function_object.clone(); - - this.buffer_scene.add(this.buffer_object); - - uniforms.clipping_plane_c = new THREE.Uniform( new THREE.Vector3() ); - uniforms.clipping_plane_t1 = new THREE.Uniform( new THREE.Vector3() ); - uniforms.clipping_plane_t2 = new THREE.Uniform( new THREE.Vector3() ); - uniforms.vectors_offset = new THREE.Uniform( gui_status.Vectors.offset ); - uniforms.grid_size = new THREE.Uniform( gui_status.Vectors.grid_size ); - - this.clipping_vectors_object = this.createClippingVectors(render_data); - this.pivot.add(this.clipping_vectors_object); - this.updateGridsize(); - } - - if(render_data.draw_vol || render_data.draw_surf) - { - const cmin = render_data.funcmin; - const cmax = render_data.funcmax; - gui_status.colormap_min = cmin; - gui_status.colormap_max = cmax; - this.gui_status_default.colormap_min = cmin; - this.gui_status_default.colormap_max = cmax; - this.gui_status_default.autoscale = render_data.autoscale || false; - - gui_status.autoscale = this.gui_status_default.autoscale; - this.c_autoscale = gui.add(gui_status, "autoscale"); - this.c_cmin = gui.add(gui_status, "colormap_min"); - this.c_cmin.onChange(()=>this.updateColormapLabels()); - this.c_cmax = gui.add(gui_status, "colormap_max"); - this.c_cmax.onChange(()=>this.updateColormapLabels()); - - this.c_autoscale.onChange((checked)=> { - if(checked) - this.updateColormapToAutoscale(); - }); - - if(cmax>cmin) - this.setStepSize(cmin, cmax); - - gui.add(gui_status, "colormap_ncolors", 2, 32,1).onChange(()=>{this.updateColormap(); this.animate();}); - this.updateColormap(); - } - - if(this.mesh_only) - { - gui_status.colormap_min = -0.5; - gui_status.colormap_max = render_data.mesh_regions_2d-0.5; - this.setSelectedFaces(); - } - uniforms.colormap_min = new THREE.Uniform( gui_status.colormap_min ); - uniforms.colormap_max = new THREE.Uniform( gui_status.colormap_max ); - - if(render_data.multidim_data) - { - const md = render_data.multidim_data.length; - - if(render_data.multidim_interpolate) - { - if(render_data.multidim_animate) - { - this.gui_status_default.Multidim.animate = true; - gui_status.Multidim.animate = true; - } - - let gui_md = gui.addFolder("Multidim"); - this.multidim_controller = gui_md.add(gui_status.Multidim, "t", 0, md, 0.01).onChange( () => - { - let s = gui_status.Multidim.t; - const n = Math.floor(s); - const t = s - n; - if(n==0) - this.interpolateRenderData(this.render_data,this.render_data.multidim_data[0], t); - else if(s==md) - this.setRenderData(this.render_data.multidim_data[md-1]); - else - this.interpolateRenderData(this.render_data.multidim_data[n-1],this.render_data.multidim_data[n], t); - - }); - gui_md.add(gui_status.Multidim, "animate").onChange(()=> {this.last_frame_time = new Date().getTime(); this.animate() }); - gui_md.add(gui_status.Multidim, "speed", 0.0, 10, 0.001).onChange(animate); - } - else - { - gui.add(gui_status.Multidim, "multidim", 0, md, 1).onChange( () => - { - const n = gui_status.Multidim.multidim; - if(n==0) - this.setRenderData(this.render_data); - else - this.setRenderData(this.render_data.multidim_data[n-1]); - }); - } - } - - let gui_light = gui.addFolder("Light"); - gui_light.add(gui_status.Light, "ambient", 0.0, 1.0).onChange(animate); - gui_light.add(gui_status.Light, "diffuse", 0.0, 1.0).onChange(animate); - gui_light.add(gui_status.Light, "shininess", 0.0, 100.0).onChange(animate); - gui_light.add(gui_status.Light, "specularity", 0.0, 1.0).onChange(animate); - - let gui_misc = gui.addFolder("Misc"); - // gui_misc.add(gui_status.Misc, "stats", {"none":-1, "FPS":0, "ms":1, "memory":2}).onChange(function(show_fps) { - // stats.showPanel( parseInt(show_fps) ); - // }); - let gui_functions = this.gui_functions; - gui_functions['reset settings'] = () =>{ - this.setGuiSettings(this.gui_status_default); - }; - gui_functions['store settings'] = () => { - document.cookie = "gui_status="+btoa(JSON.stringify(gui_status)); - }; - gui_functions['load settings'] = () =>{ - var name = "gui_status=" - var decodedCookie = decodeURIComponent(document.cookie); - var ca = decodedCookie.split(';'); - for(var i = 0; i this.updateColormapLabels()); - - gui_misc.add(gui_status.Misc, "axes").onChange(animate); - gui_misc.add(gui_status.Misc, "version").onChange(value => { - this.version_object.style.visibility = value ? "visible" : "hidden"; - }); - - gui_functions['fullscreen'] = () =>{ - let elem = this.element.parentNode; - - if (elem.requestFullscreen) { - elem.requestFullscreen(); - } else if(elem.webkitRequestFullScreen) { - // Webkit (works in Safari and Chrome Canary) - elem.webkitRequestFullScreen(); - }else if(elem.mozRequestFullScreen) { - // Firefox - elem.mozRequestFullScreen(); - } - }; - gui.add(gui_functions, "fullscreen"); - - gui_functions['reset'] = ()=> { - this.controls.reset(); - }; - gui.add(gui_functions, "reset").onChange(animate); - - gui_functions['update center'] = ()=> { - this.controls.updateCenter(); - }; - gui.add(gui_functions, "update center").onChange(animate); - - this.scene.add( this.pivot ); - - this.controls = new CameraControls(this.camera, this, this.renderer.domElement ); - this.controls.addEventListener('change', animate); - - this.updateRenderData(render_data); - setTimeout(()=> this.onResize(), 0); - console.log("Scene init done", this); - if(render_data.on_init) { - var on_init = Function("scene", "render_data", render_data.on_init); - on_init(this, render_data); - } - this.animate(); - } - - init(element, render_data, webgl_args = {}) - { - this.initCanvas(element, webgl_args); - this.initRenderData(render_data); - } - - setSelectedFaces( bnds = [], col_selected = [0,0.5,1.0], col_default = [0,1,0] ) - { - var n_colors = this.render_data.mesh_regions_2d; - var colormap_data = new Float32Array(3*n_colors); - - for (var i=0; i0 && this.colormap_object == null) - { - var geo = new THREE.Geometry(); - geo.vertices.push(new THREE.Vector3( 0, 0, 0.0)); - geo.vertices.push(new THREE.Vector3( 0,-0.07, 0.0)); - geo.vertices.push(new THREE.Vector3( 1,-0.07, 0.0)); - geo.vertices.push(new THREE.Vector3( 1, 0, 0.0)); - geo.faces.push(new THREE.Face3(0, 1, 2)); - geo.faces.push(new THREE.Face3(2, 3, 0)); - - geo.faceVertexUvs[0] = []; - geo.faceVertexUvs[0].push([ - new THREE.Vector2(0, 0), - new THREE.Vector2(0, 0), - new THREE.Vector2(1, 0) - ]); - geo.faceVertexUvs[0].push([ - new THREE.Vector2(1, 0), - new THREE.Vector2(1, 0), - new THREE.Vector2(0, 0) - ]); - - geo.uvsNeedUpdate = true; - var material = new THREE.MeshBasicMaterial({depthTest: false, map: this.colormap_texture, side: THREE.DoubleSide, wireframe: false}); - this.colormap_object = new THREE.Mesh( geo, material ); - - // Create 5 html div/text elements for numbers - this.colormap_labels = []; - this.colormap_divs = []; - var labels_object = document.createElement("div"); - for(var i=0; i<5; i++) - { - var label = document.createElement("div"); - var t = document.createTextNode(""); - label.appendChild(t) - this.colormap_divs.push(label); - this.colormap_labels.push(t); - labels_object.appendChild(label); - } - this.container.appendChild(labels_object); - this.updateColormapLabels(); - } - - if(this.colormap_object != null) - { - let material = this.colormap_object.material; - material.map = this.colormap_texture; - } - } - - - createCurvedMesh(data) - { - var geo = new THREE.InstancedBufferGeometry(); - var position = new Float32Array(6*20*20); // 20*20 triangles - - // subdivision mesh - var ii = 0; - for (var i=0; i<20; i++) { - for (var j=0; j<=i; j++) { - position[ii++] = j; - position[ii++] = i-j; - position[ii++] = j+1; - position[ii++] = i-j; - position[ii++] = j; - position[ii++] = i-j+1; - } - for (var j=0; j2 hexes fit into subdivided tets, add tet with point (1,1,1) in hex - for (var j=0; j<=i-2; j++) { - for (var k=0; k<=i-2-j; k++) { - for (var l = 0; l < 6; l++) { - vertid[4*kk+0] = 5*6 + l; - vertid[4*kk+1] = j+1; - vertid[4*kk+2] = k+1; - vertid[4*kk+3] = i-1-j-k; - kk++; - } - - } - } - - } - - var geo = new THREE.InstancedBufferGeometry(); - geo.setAttribute( 'position', new THREE.Float32BufferAttribute( vertid, 4 )); - geo.setAttribute( 'vertid', new THREE.Float32BufferAttribute( vertid, 4 )); - - return new THREE.Mesh( geo, material ); - } - - // called on scene.Redraw() from Python - updateRenderData(render_data) - { - this.render_data = render_data; - this.setRenderData(render_data); - } - - setRenderData(render_data) - { - if(this.edges_object != null) - { - let geo = this.edges_object.geometry; - - let pnames = []; - let vnames = []; - const o = render_data.order2d; - for(let i=0; ithis.wireframe_object.geometry; - - let pnames = []; - let vnames = []; - const o = render_data.order2d; - for(let i=0; i1) - for (let i=0;ithis.mesh_object.geometry; - const data = render_data.Bezier_trig_points; - const order = render_data.order2d; - - var names; - if(order == 1) { - names = ['p0', 'p1', 'p2'] - if(render_data.draw_surf && render_data.funcdim>1) - names = names.concat(['v0', 'v1', 'v2' ]); - } - if(order == 2) { - names = ['p00', 'p01', 'p02', 'p10', 'p11', 'p20']; - if(render_data.draw_surf && render_data.funcdim>1) - names = names.concat([ 'vec00_01', 'vec02_10', 'vec11_20' ]); - } - if(order == 3) { - names = [ 'p00', 'p01', 'p02', 'p03', 'p10', 'p11', 'p12', 'p20', 'p21', 'p30']; - if(render_data.draw_surf && render_data.funcdim>1) - names = names.concat([ 'vec00_01', 'vec02_03', 'vec10_11', 'vec12_20', 'vec21_30']); - } - - for (var i in names) - geo.setAttribute( names[i], new THREE.InstancedBufferAttribute( readB64(data[i]), 4 ) ); - geo.boundingSphere = new THREE.Sphere(this.mesh_center, this.mesh_radius); - geo.maxInstancedCount = readB64(data[0]).length/4; - } - - if(this.clipping_function_object != null) - { - let geo = this.clipping_function_object.geometry; - - let names = [ 'p0', 'p1', 'p2', 'p3' ]; - if(render_data.order3d==2) - names = names.concat(['p03', 'p13', 'p23', 'p01', 'p02', 'p12' ]); - - if(render_data.funcdim>1 && render_data.draw_vol) - { - names = names.concat(['v0_1', 'v2_3']); - if(render_data.order3d==2) - names = names.concat(['v03_13', 'v23_01', 'v02_12']); - } - - for (var i in names) - geo.setAttribute( names[i], new THREE.InstancedBufferAttribute( readB64(render_data.points3d[i]), 4 ) ); - } - - if(render_data.draw_surf || render_data.draw_vol) - { - const cmin = render_data.funcmin; - const cmax = render_data.funcmax; - this.gui_status_default.colormap_min = cmin; - this.gui_status_default.colormap_max = cmax; - - if(this.gui_status.autoscale) - { - if(this.gui_status.eval == 3) // norm of vector-valued function - { - this.gui_status.colormap_min = 0; - this.gui_status.colormap_max = Math.max(Math.abs(cmin), Math.abs(cmax)); - } - else - { - this.gui_status.colormap_min = cmin; - this.gui_status.colormap_max = cmax; - } - this.c_cmin.updateDisplay(); - this.c_cmax.updateDisplay(); - this.updateColormapLabels(); - - } - - if(cmax>cmin) - this.setStepSize(cmin, cmax); - } - - this.animate(); - } - - interpolateRenderData(rd, rd2, t) - { - const t1 = 1.0-t; - const mix = (a,b)=> t1*a + t*b; - const mixB64 = (a,b)=> { - let d1 = readB64(a); - let d2 = readB64(b); - - for (let i=0; ithis.edges_object.geometry; - - let pnames = []; - let vnames = []; - const o = rd.order2d; - for(let i=0; ithis.wireframe_object.geometry; - - let pnames = []; - let vnames = []; - const o = rd.order2d; - for(let i=0; i1) - for (let i=0;ithis.mesh_object.geometry; - const data = rd.Bezier_trig_points; - const data2 = rd2.Bezier_trig_points; - const order = rd.order2d; - - var names; - if(order == 1) { - names = ['p0', 'p1', 'p2'] - if(rd.draw_surf && rd.funcdim>1) - names = names.concat(['v0', 'v1', 'v2' ]); - } - if(order == 2) { - names = ['p00', 'p01', 'p02', 'p10', 'p11', 'p20']; - if(rd.draw_surf && rd.funcdim>1) - names = names.concat([ 'vec00_01', 'vec02_10', 'vec11_20' ]); - } - if(order == 3) { - names = [ 'p00', 'p01', 'p02', 'p03', 'p10', 'p11', 'p12', 'p20', 'p21', 'p30']; - if(rd.draw_surf && rd.funcdim>1) - names = names.concat([ 'vec00_01', 'vec02_03', 'vec10_11', 'vec12_20', 'vec21_30']); - } - - for (var i in names) - geo.setAttribute( names[i], new THREE.InstancedBufferAttribute( mixB64(data[i], data2[i]), 4 ) ); - geo.boundingSphere = new THREE.Sphere(this.mesh_center, this.mesh_radius); - geo.maxInstancedCount = readB64(data[0]).length/4; - } - - if(this.clipping_function_object != null) - { - let geo = this.clipping_function_object.geometry; - - let names = [ 'p0', 'p1', 'p2', 'p3' ]; - if(rd.order3d==2) - names = names.concat(['p03', 'p13', 'p23', 'p01', 'p02', 'p12' ]); - - if(rd.funcdim>1 && rd.draw_vol) - { - names = names.concat(['v0_1', 'v2_3']); - if(rd.order3d==2) - names = names.concat(['v03_13', 'v23_01', 'v02_12']); - } - - for (var i in names) - geo.setAttribute( names[i], new THREE.InstancedBufferAttribute( mixB64(rd.points3d[i], rd2.points3d[i]), 4 ) ); - } - - if(rd.draw_surf || rd.draw_vol) - { - const cmin = mix(rd.funcmin, rd2.funcmin); - const cmax = mix(rd.funcmax, rd2.funcmax); - this.gui_status_default.colormap_min = cmin; - this.gui_status_default.colormap_max = cmax; - - if(this.gui_status.autoscale) - { - this.gui_status.colormap_min = cmin; - this.gui_status.colormap_max = cmax; - this.c_cmin.updateDisplay(); - this.c_cmax.updateDisplay(); - this.updateColormapLabels(); - - } - - if(cmax>cmin) - this.setStepSize(cmin, cmax); - } - - this.animate(); - } - - setCenterTag(position = null) { - if (this.center_tag != null) { - this.pivot.remove(this.center_tag); - this.center_tag = null; - } - if (position != null) { - const n = 101; - const size = n * n; - const data = new Uint8Array(4*n*n); - - for(var i=0; i0.0) - { - for(var k=0; k<3; k++) - data[4*(i*n+j)+k] = 128; - data[4*(i*n+j)+3] = 255; - } - else - { - for(var k=0; k<3; k++) - data[4*(i*n+j)+k] = 0; - } - } - - let texture = new THREE.DataTexture( data, n, n, THREE.RGBAFormat); - - texture.magFilter = THREE.LinearFilter; - texture.minFilter = THREE.LinearFilter; - texture.needsUpdate = true; - - // disable depthTest and set renderOrder to make the tag always visible - let material = new THREE.SpriteMaterial( { map: texture, sizeAttenuation: false, color: 0xffffff, depthTest: false } ); - - this.center_tag = new THREE.Sprite( material ); - const s = 0.01/this.controls.scale; - - this.center_tag.scale.set(s,s,s); - this.center_tag.position.copy(position); - this.center_tag.renderOrder = 1; - this.pivot.add(this.center_tag); - } - } - - - animate () { - // Don't request a frame if another one is currently in the pipeline - if(this.requestId === 0) - this.requestId = requestAnimationFrame( ()=>this.render() ); - - // stats.update(); - } - - render() { - let now = new Date().getTime(); - let frame_time = 0.001*(new Date().getTime() - this.last_frame_time ); - - if (this.get_pixel) { - this.uniforms.render_depth.value = true; - this.camera.setViewOffset( this.renderer.domElement.width, this.renderer.domElement.height, - this.mouse.x * window.devicePixelRatio | 0, this.mouse.y * window.devicePixelRatio | 0, 1, 1 ); - this.renderer.setRenderTarget(this.render_target); - this.renderer.setClearColor( new THREE.Color(1.0,1.0,1.0)); - this.renderer.clear(true, true, true); - this.renderer.render( this.scene, this.camera ); - this.camera.clearViewOffset(); - this.uniforms.render_depth.value= false; - - let pixel_buffer = new Float32Array( 4 ); - this.context.readPixels(0, 0, 1, 1, this.context.RGBA, this.context.FLOAT, pixel_buffer); - if (pixel_buffer[3]==1){ - this.controls.center.copy(this.mesh_center); - }else{ - for (var i=0; i<3; i++){ - this.controls.center.setComponent(i, (pixel_buffer[i]-this.trafo.y)/this.trafo.x); - } - } - this.setCenterTag(this.controls.center); - this.handleEvent('selectpoint', [this, this.controls.center] ); - this.mouse.set(0.0, 0.0); - this.get_pixel = false; - } - - this.requestId = 0; - - if(this.ortho_camera === undefined) - return; // not fully initialized yet - - this.handleEvent('beforerender', [this, frame_time]); - - let gui_status = this.gui_status; - let uniforms = this.uniforms; - - this.axes_object.visible = gui_status.Misc.axes; - var subdivision = gui_status.subdivision; - if(gui_status.Misc.reduce_subdivision && this.controls.mode != null) - subdivision = Math.ceil(subdivision/2); - - if( this.edges_object != null ) - { - this.edges_object.visible = gui_status.edges; - if(gui_status.subdivision !== undefined) - { - uniforms.n_segments.value = subdivision; - let geo = this.edges_object.geometry; - geo.setDrawRange(0, subdivision+1); - } - } - - if( this.wireframe_object != null ) - { - this.wireframe_object.visible = gui_status.mesh; - if(gui_status.subdivision !== undefined) - { - uniforms.n_segments.value = subdivision; - let geo = this.wireframe_object.geometry; - geo.setDrawRange(0, subdivision+1); - } - } - - if( this.mesh_object != null ) - { - this.mesh_object.visible = gui_status.elements; - if(gui_status.subdivision !== undefined) - { - uniforms.n_segments.value = subdivision; - let geo = this.mesh_object.geometry; - geo.setDrawRange(0, 3*subdivision*subdivision) - } - } - - - if( this.clipping_function_object != null ) - { - uniforms.n_segments.value = subdivision; - const sd = subdivision; - let geo = this.clipping_function_object.geometry; - geo.setDrawRange(0, 6*sd*sd*sd); - this.clipping_function_object.visible = gui_status.Clipping.function && gui_status.Clipping.enable; - } - - let three_clipping_plane = this.three_clipping_plane; - three_clipping_plane.normal.set(gui_status.Clipping.x, gui_status.Clipping.y, gui_status.Clipping.z); - three_clipping_plane.normal.normalize(); - three_clipping_plane.constant = gui_status.Clipping.dist-three_clipping_plane.normal.dot(this.mesh_center); - - // console.log("three_clipping_plane normal and const", three_clipping_plane.normal, three_clipping_plane.constant); - - this.clipping_plane.set( - three_clipping_plane.normal.x, - three_clipping_plane.normal.y, - three_clipping_plane.normal.z, - three_clipping_plane.constant); - this.renderer.clippingPlanes = []; - - let world_clipping_plane = three_clipping_plane.clone(); - - world_clipping_plane.constant = gui_status.Clipping.dist; - world_clipping_plane.applyMatrix4( this.pivot.matrix) - - uniforms.do_clipping.value = gui_status.Clipping.enable; - - if(this.have_deformation || this.have_z_deformation) - uniforms.deformation.value = gui_status.deformation; - - if(gui_status.Clipping.enable) - this.renderer.clippingPlanes = [world_clipping_plane]; - - if(gui_status.colormap_ncolors) - { - uniforms.colormap_min.value = gui_status.colormap_min; - uniforms.colormap_max.value = gui_status.colormap_max; - } - - if(this.clipping_vectors_object != null) - { - this.clipping_vectors_object.visible = gui_status.Vectors.show; - uniforms.vectors_offset.value = gui_status.Vectors.offset; - } - - if(this.is_complex) - { - uniforms.complex_scale.value.x = Math.cos(gui_status.Complex.phase); - uniforms.complex_scale.value.y = Math.sin(gui_status.Complex.phase); - } - - if(gui_status.Vectors.show) - { - this.updateClippingPlaneCamera(); - uniforms.function_mode.value = 4; - this.renderer.setRenderTarget(this.buffer_texture); - this.renderer.setClearColor( new THREE.Color(0.0,0.0,0.0) ); - this.renderer.clear(true, true, true); - this.renderer.render(this.buffer_scene, this.buffer_camera); - } - - - uniforms.function_mode.value = parseInt(gui_status.eval); - uniforms.light_mat.value.x = gui_status.Light.ambient; - uniforms.light_mat.value.y = gui_status.Light.diffuse; - uniforms.light_mat.value.z = gui_status.Light.shininess; - uniforms.light_mat.value.w = gui_status.Light.specularity; - - this.renderer.setRenderTarget(null); - this.renderer.setClearColor( new THREE.Color(1.0,1.0,1.0)); - this.renderer.clear(true, true, true); - this.renderer.render( this.scene, this.camera ); - - this.renderer.clippingPlanes = []; - - // render after clipping - if(this.center_tag != null){ - this.renderer.render(this.center_tag, this.camera); - } - - if(this.colormap_object && gui_status.Misc.colormap) - this.renderer.render( this.colormap_object, this.ortho_camera ); - - if(this.axes_object && gui_status.Misc.axes) - this.renderer.render( this.axes_object, this.ortho_camera ); - - - if(gui_status.Complex.animate) - { - gui_status.Complex.phase += frame_time * gui_status.Complex.speed; - if(gui_status.Complex.phase>2*Math.PI) - gui_status.Complex.phase -= 2*Math.PI; - - this.phase_controller.updateDisplay(); - this.animate(); - } - if(gui_status.Multidim.animate) - { - gui_status.Multidim.t += frame_time * gui_status.Multidim.speed; - if(gui_status.Multidim.t > this.render_data.multidim_data.length) - gui_status.Multidim.t = 0.0; - - this.multidim_controller.updateDisplay(); - this.multidim_controller.__onChange(); - this.animate(); - } - this.last_frame_time = now; - this.handleEvent('afterrender', [this, frame_time]); - } - - renderToImage() - { - var img = new Image(); - var toimage = () => { - img.src = this.renderer.domElement.toDataURL("image/png"); - }; - this.on("afterrender", toimage); - this.render(); - this.event_handlers["afterrender"].pop(toimage); - return img; - } -} diff -Nru ngsolve-6.2.2102/python/webgui/js/src/version.ts ngsolve-6.2.2103/python/webgui/js/src/version.ts --- ngsolve-6.2.2102/python/webgui/js/src/version.ts 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/src/version.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// Copyright (c) Matthias Hochsteger -// Distributed under the terms of the Modified BSD License. - -const data = require('../package.json'); - -/** - * The _model_module_version/_view_module_version this package implements. - * - * The html widget manager assumes that this is the same as the npm package - * version number. - */ -export const MODULE_VERSION = data.version; - -/* - * The current package name. - */ -export const MODULE_NAME = data.name; diff -Nru ngsolve-6.2.2102/python/webgui/js/src/widget.ts ngsolve-6.2.2103/python/webgui/js/src/widget.ts --- ngsolve-6.2.2102/python/webgui/js/src/widget.ts 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/src/widget.ts 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -// Copyright (c) Matthias Hochsteger -// Distributed under the terms of the Modified BSD License. - -import { - DOMWidgetView -} from '@jupyter-widgets/base'; - -import { - Scene -} from './scene'; - -export class NGSolveView extends DOMWidgetView { - scene: Scene; - - render() { - console.log("Render NGSView"); - let render_data = this.model.get("value"); - console.log("render data", render_data); - this.scene = new Scene(); - let container = document.createElement( 'div' ); - container.setAttribute("style", "height: 50vw; width: 100vw;"); - this.el.appendChild(container); - setTimeout(()=> { - this.scene.init(container, render_data); - this.scene.render(); - } , 0); - this.model.on('change:value', this.data_changed, this); - } - data_changed() { - let render_data = this.model.get("value"); - this.scene.updateRenderData(render_data); - } -} - -export class NGSolveDocuView extends DOMWidgetView { - scene: Scene; - container: any; - - render() { - // show preview image, a text message on hover - // load real render data on click and start webgui - let files = this.model.get("value"); - const image = files['preview']; - this.container = $(` -
- -
- Click to load interactive WebGUI -
-
`); - let div = document.createElement( 'div' ); - this.container.click( el=> this.onClickImage(el) ) - this.container.appendTo(div); - this.el.appendChild(div); - this.model.on('change:value', this.data_changed, this); - } - onClickImage(el) { - document.body.style.cursor = "wait"; - let files = this.model.get("value"); - $.get(files['render_data'], (render_data) => { - this.container.remove(); - this.container = null; - document.body.style.cursor = ""; - let pel = this.el.children[0]; - pel.innerHTML = ""; - let scene = new Scene(); - scene.init(pel, render_data); - }); - } - - data_changed() { - let render_data = this.model.get("value"); - this.scene.updateRenderData(render_data); - } -} - - diff -Nru ngsolve-6.2.2102/python/webgui/js/tsconfig.json ngsolve-6.2.2103/python/webgui/js/tsconfig.json --- ngsolve-6.2.2102/python/webgui/js/tsconfig.json 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/tsconfig.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "declaration": false, - "esModuleInterop":true, - "lib": ["es2015", "dom"], - "module": "commonjs", - "moduleResolution": "node", - "noEmitOnError": true, - "noUnusedLocals": false, - "outDir": "lib", - "resolveJsonModule": true, - "rootDir": "src", - "skipLibCheck": true, - "sourceMap": true, - "strict": false, - "strictPropertyInitialization": false, - "target": "es2015" - }, - "include": [ - "src/**/*.ts", - "src/**/*.tsx" - ] -} diff -Nru ngsolve-6.2.2102/python/webgui/js/webpack.config.js ngsolve-6.2.2103/python/webgui/js/webpack.config.js --- ngsolve-6.2.2102/python/webgui/js/webpack.config.js 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/js/webpack.config.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ -const path = require('path'); -const version = require('./package.json').version; - -// Custom webpack rules -const rules = [ - { test: /\.ts$/, loader: 'ts-loader' }, - { test: /\.js$/, loader: 'source-map-loader' }, - { test: /\.css$/, use: ['style-loader', 'css-loader']} -]; - -// Packages that shouldn't be bundled but loaded at runtime -const externals = ['@jupyter-widgets/base']; -const externals1 = { -'three': "https://cdn.jsdelivr.net/npm/three@0.115.0/build/three.min.js", -'dat.gui': "https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.js" -}; - - -const resolve = { - // Add '.ts' and '.tsx' as resolvable extensions. - extensions: [".webpack.js", ".web.js", ".ts", ".js"] -}; - -module.exports = function(env, argv) -{ - const build_dir = path.resolve(__dirname); - return [ - /** - * Notebook extension - * - * This bundle only contains the part of the JavaScript that is run on load of - * the notebook. - */ - { - target: 'web', - entry: './src/extension.ts', - output: { - filename: 'index.js', - path: path.resolve(build_dir, 'nbextension', 'static'), - libraryTarget: 'amd' - }, - module: { - rules: rules - }, - devtool: 'source-map', - externals, - resolve, - }, - - /** - * Embeddable ngsolve_jupyter_widgets bundle - * - * This bundle is almost identical to the notebook extension bundle. The only - * difference is in the configuration of the webpack public path for the - * static assets. - * - * The target bundle is always `dist/index.js`, which is the path required by - * the custom widget embedder. - */ - { - target: 'web', - entry: './src/index.ts', - output: { - filename: 'index.js', - path: path.resolve(build_dir, 'dist'), - libraryTarget: 'amd', - library: "ngsolve_jupyter_widgets", - publicPath: 'https://unpkg.com/ngsolve_jupyter_widgets@' + version + '/dist/' - }, - devtool: 'source-map', - module: { - rules: rules - }, - externals, - resolve, - }, - - - - /** - * JupyterLab extension bundle - * - * This bundle is used to embed widgets in jupyter lab the - */ - { - target: 'web', - entry: './src/plugin.ts', - output: { - filename: 'plugin.js', - path: path.resolve(build_dir, 'labextension'), - library: "ngsolve_jupyter_widgets", - libraryTarget: 'amd' - }, - module: { - rules: rules - }, - devtool: 'source-map', - externals, - resolve, - }, - - /** - * Documentation widget bundle - * - * This bundle is used to embed widgets in the package documentation. - */ - { - target: 'web', - entry: './src/index.ts', - output: { - filename: 'embed-bundle.js', - path: path.resolve(build_dir, 'docs', 'source', '_static'), - library: "ngsolve_jupyter_widgets", - libraryTarget: 'amd' - }, - module: { - rules: rules - }, - devtool: 'source-map', - externals, - resolve, - }, - - /** - * Standalone html bundle - * - * This bundle is used to create html output files directly from python console - */ - { - target: 'web', - entry: './src/scene.ts', - output: { - filename: 'standalone.js', - path: path.resolve(build_dir), - library: "ngsolve_jupyter_widgets", - libraryTarget: 'amd' - }, - module: { - rules: rules - }, - devtool: 'source-map', - externals, - resolve, - } - -] }; diff -Nru ngsolve-6.2.2102/python/webgui/shader/clipping_vectors.vert ngsolve-6.2.2103/python/webgui/shader/clipping_vectors.vert --- ngsolve-6.2.2102/python/webgui/shader/clipping_vectors.vert 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/shader/clipping_vectors.vert 1970-01-01 00:00:00.000000000 +0000 @@ -1,213 +0,0 @@ -uniform int n_segments; -uniform bool render_depth; - -varying vec3 p_; -varying vec3 normal_; -varying vec3 value_; - -attribute vec4 p0; -attribute vec4 p1; -attribute vec4 p2; -attribute vec4 p3; -attribute vec4 p03; -attribute vec4 p13; -attribute vec4 p23; -attribute vec4 p01; -attribute vec4 p02; -attribute vec4 p12; - -attribute vec4 v0_1; -attribute vec4 v2_3; -attribute vec4 v03_13; -attribute vec4 v23_01; -attribute vec4 v02_12; - -attribute vec4 vertid; - -void CalcIntersection( float d0, float d1, vec4 x0, vec4 x1, vec3 val0, vec3 val1) -{ - float a = d0/(d0-d1); - vec4 position = mix(x0, x1, a); - p_ = position.xyz; - value_ = mix(val0, val1, a); - //vec4 modelViewPosition = viewMatrix * vec4(position.xyz, 1.0); - // gl_Position = projectionMatrix * modelViewPosition; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xyz, 1.0); -} - - -void CutElement3d() -{ - - int sumback = 0; - if (dot(clipping_plane, vec4(p0.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p1.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p2.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p3.xyz,1.0)) > 0.0) sumback++; - -#if ORDER==1 - if (sumback == 0 || sumback == 4) - return; -#else // ORDER==1 - if (dot(clipping_plane, vec4(p03.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p13.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p23.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p01.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p02.xyz,1.0)) > 0.0) sumback++; - if (dot(clipping_plane, vec4(p12.xyz,1.0)) > 0.0) sumback++; - if (sumback == 0 || sumback == 10) return; -#endif - - - float dx = 1.0/float(n_segments); - - int ivertid = int(vertid.x); - vec3 anchor = vertid.yzw * dx; - - int vert = ivertid - (ivertid/3)*3; - int trig = ivertid/3; - trig = trig - (trig/2)*2; - int classnr = ivertid/6; - - - vec4 psub[4]; - if (classnr == 0) { - psub[0].xyz = anchor; - psub[1].xyz = anchor+vec3(dx,0.0,0.0); - psub[2].xyz = anchor+vec3(0.0,dx,0.0); - psub[3].xyz = anchor+vec3(0.0,0.0,dx); - } else if (classnr == 1) { - psub[0].xyz = anchor+vec3(dx,0.0,0.0); - psub[1].xyz = anchor+vec3(0.0,dx,dx); - psub[2].xyz = anchor+vec3(0.0,0.0,dx); - psub[3].xyz = anchor+vec3(dx,0.0,dx); - } else if (classnr == 2) { - psub[0].xyz = anchor+vec3(dx,0.0,0.0); - psub[1].xyz = anchor+vec3(0.0,dx,dx); - psub[2].xyz = anchor+vec3(dx,0.0,dx); - psub[3].xyz = anchor+vec3(dx,dx,0.0); - } else if (classnr == 3) { - psub[0].xyz = anchor+vec3(dx,0.0,0.0); - psub[1].xyz = anchor+vec3(0.0,dx,dx); - psub[2].xyz = anchor+vec3(dx,dx,0.0); - psub[3].xyz = anchor+vec3(0.0,dx,0.0); - } else if (classnr == 4) { - psub[0].xyz = anchor+vec3(dx,0.0,0.0); - psub[1].xyz = anchor+vec3(0.0,dx,dx); - psub[2].xyz = anchor+vec3(0.0,dx,0.0); - psub[3].xyz = anchor+vec3(0.0,0.0,dx); - } else if (classnr == 5) { - psub[0].xyz = anchor; - psub[1].xyz = anchor+vec3(-dx,0.0,0.0); - psub[2].xyz = anchor+vec3(0.0,-dx,0.0); - psub[3].xyz = anchor+vec3(0.0,0.0,-dx); - } - - for (int i=0; i<4; ++i) - psub[i].w = 1.0-psub[i].x-psub[i].y-psub[i].z; - - - int n_back = 0; - int n_front = 0; - vec4 p[4]; - vec4 p4; - vec3 v[4]; - -#if ORDER==1 - for (int i=0; i<4; ++i) - { - p[i] = psub[i].x*p0 + psub[i].y*p1 + psub[i].z*p2 + psub[i].w*p3; - v[i].x = p[i].w; - } - - v[0].yz = v0_1.xy; - v[1].yz = v0_1.zw; - v[2].yz = v2_3.xy; - v[3].yz = v2_3.zw; -#else // ORDER==1 - for (int i=0; i<4; ++i) - { - float l0 = psub[i].x; - float l1 = psub[i].y; - float l2 = psub[i].z; - float l3 = psub[i].w; - p[i] = l0*(2.*l0-1.) * p0 + l1*(2.*l1-1.) * p1 - + l2*(2.*l2-1.) * p2 + l3*(2.*l3-1.) * p3 - + 4. * l0*l1 * p01 + 4. * l0*l2 * p02 - + 4. * l0*l3 * p03 + 4. * l1*l2 * p12 - + 4. * l1*l3 * p13 + 4. * l2*l3 * p23; - - v[i].x = p[i].w; - v[i].yz = l0*(2.*l0-1.) * v0_1.xy + l1*(2.*l1-1.) * v0_1.zw - + l2*(2.*l2-1.) * v2_3.xy + l3*(2.*l3-1.) * v2_3.zw - + 4. * l0*l1 * v23_01.zw + 4. * l0*l2 * v02_12.xy - + 4. * l0*l3 * v03_13.xy + 4. * l1*l2 * v02_12.zw - + 4. * l1*l3 * v03_13.zw + 4. * l2*l3 * v23_01.xy; - } -#endif // ORDER==1 - - // front/back: shift-register - // ending v: ther v-th front/back point - float distf, distb, distfv, distbv, distf2, distb2; - vec4 pf, pb, pfv, pbv, pf2, pb2; - vec3 vf, vb, vfv, vbv, vf2, vb2; - - for (int i=0; i<4; ++i) { - float dist = dot(clipping_plane, vec4(p[i].xyz,1.0)); - if(dist>0.) { - distb2 = distb; - pb2 = pb; - vb2 = vb; - distb = dist; - pb = p[i]; - vb = v[i]; - if (n_back == vert) { - distbv = dist; - pbv = p[i]; - vbv = v[i]; - } - n_back++; - } else { - distf2 = distf; - pf2 = pf; - vf2 = vf; - distf = dist; - pf = p[i]; - vf = v[i]; - if (n_front == vert) { - distfv = dist; - pfv = p[i]; - vfv = v[i]; - } - n_front++; - } - } - - if( n_back==0 || n_back==4 ) return; - if( trig==0 && n_back==3 ) - CalcIntersection( distf, distbv, pf, pbv, vf, vbv); - if( trig==0 && n_back==1 ) - CalcIntersection( distfv, distb, pfv, pb, vfv, vb); - - if( n_back==2 ) { - if(trig==0 && vert==0) - CalcIntersection(distf2, distb, pf2, pb, vf2, vb); - - if(vert == 1) - CalcIntersection(distf, distb, pf, pb, vf, vb); - - if(vert==2) - CalcIntersection(distf2, distb2, pf2, pb2, vf2, vb2); - - if(trig==1 && vert==0) - CalcIntersection(distf, distb2, pf, pb2, vf, vb2); - } -} - -void main() -{ - normal_ = normalMatrix*vec3(-1.0*clipping_plane.xyz); - gl_Position = vec4(0,0,0,1); - // value_ = 0.0; - CutElement3d(); -} diff -Nru ngsolve-6.2.2102/python/webgui/shader/function.frag ngsolve-6.2.2103/python/webgui/shader/function.frag --- ngsolve-6.2.2102/python/webgui/shader/function.frag 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/shader/function.frag 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -varying vec3 p_; -varying vec3 normal_; -varying vec3 value_; - -uniform bool render_depth; - -#ifdef USER_FUNCTION -vec3 userFunction( vec3 value, vec3 p, vec3 normal ) -{ - return vec3(USER_FUNCTION); -} -#endif // USER_FUNCTION - -void main() -{ - vec3 value = value_; -#ifdef USER_FUNCTION - value = userFunction(value_, p_, normal_); -#endif // USER_FUNCTION - - if(function_mode == 4.0) - { - gl_FragColor = vec4(value, 1.0); - return; - } - - if( isBehindClippingPlane(p_) ) - discard; - - if (render_depth) { - gl_FragColor = getPositionAsColor(p_); - return; - } - - - vec3 norm = normal_; - bool inside = false; -#ifndef SKIP_FACE_CHECK - if (gl_FrontFacing == false) { - norm = (-1.0)*normal_; - inside = true; - } -#endif // SKIP_FACE_CHECK - -#ifdef NO_FUNCTION_VALUES - vec4 color = vec4(.7,.7,.7,1); -#else - vec4 color = getColor(GetValue(value)); -#endif - - gl_FragColor = calcLight( color, p_, norm, inside); -} diff -Nru ngsolve-6.2.2102/python/webgui/shader/splines.frag ngsolve-6.2.2103/python/webgui/shader/splines.frag --- ngsolve-6.2.2102/python/webgui/shader/splines.frag 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/shader/splines.frag 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -varying vec3 p_; -uniform bool render_depth; - -void main() -{ - if (render_depth) { - gl_FragColor = getPositionAsColor(p_); - return; - } - if( isBehindClippingPlane(p_) ) - discard; - - gl_FragColor = vec4(0,0,0, 1); -} diff -Nru ngsolve-6.2.2102/python/webgui/shader/splines.vert ngsolve-6.2.2103/python/webgui/shader/splines.vert --- ngsolve-6.2.2102/python/webgui/shader/splines.vert 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/shader/splines.vert 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -varying vec3 p_; -// varying vec3 normal_; - -uniform int n_segments; - -attribute vec4 p0; -attribute vec4 p1; -attribute vec4 p2; -attribute vec4 p3; - -attribute vec2 v0; -attribute vec2 v1; -attribute vec2 v2; -attribute vec2 v3; - -attribute float position; - -void main() -{ - float t = (position)/float(n_segments); - vec3 value = vec3(0,0,0); - vec4 position = vec4(0,0,0,0); - -#if ORDER==1 - position = t*p0 + (1.0-t)*p1; - value.x = position.w; - value.yz = t*v0 + (1.0-t)*v1; -#endif // ORDER==1 - -#if ORDER==2 - float b0 = (1.0-t)*(1.0-t); - float b1 = 2.0*t*(1.0-t); - float b2 = t*t; - - position = b0*p0+b1*p1+b2*p2; - value.x = position.w; - value.yz = b0*v0+b1*v1+b2*v2; -#endif // ORDER==2 - -#if ORDER==3 - float b0 = (1.0-t)*(1.0-t)*(1.0-t); - float b1 = 3.0*t*(1.0-t)*(1.0-t); - float b2 = 3.0*t*t*(1.0-t); - float b3 = t*t*t; - position = b0*p0+b1*p1+b2*p2+b3*p3; - value.x = position.w; - value.yz = b0*v0+b1*v1+b2*v2+b3*v3; -#endif // ORDER==3 - -#ifdef DEFORMATION - position.xyz += deformation*value; -#endif -#ifdef DEFORMATION_2D - position.z += GetValue(deformation*value); -#endif - - vec4 p = vec4(position.xyz,1); - p_ = p.xyz; - - vec4 modelViewPosition = modelViewMatrix * p; - gl_Position = projectionMatrix * modelViewPosition; -} diff -Nru ngsolve-6.2.2102/python/webgui/shader/trigsplines.vert ngsolve-6.2.2103/python/webgui/shader/trigsplines.vert --- ngsolve-6.2.2102/python/webgui/shader/trigsplines.vert 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/shader/trigsplines.vert 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -varying vec3 p_; -varying vec3 normal_; -varying vec3 value_; -uniform int n_segments; - -attribute vec2 position; - -void main() -{ - float u = (position.x)/float(n_segments); - float v = (position.y)/float(n_segments); - - float w = 1.0-u-v; - - vec4 position = GetPositionAndScalar(u,v); - value_.x = position.w; - value_.yz = GetVectorValues(u,v); - normal_ = GetNormal(u,v); - -#ifdef DEFORMATION - position.xyz += deformation*value_; -#endif -#ifdef DEFORMATION_2D - position.z += GetValue(deformation*value_); -#endif - - vec4 p = vec4(position.xyz,1); - p_ = p.xyz; - vec4 modelViewPosition = modelViewMatrix * vec4(position.xyz, 1.0); //0.. dir, 1.. pos - normal_ = normalMatrix*normal_; - - gl_Position = projectionMatrix * modelViewPosition; -} diff -Nru ngsolve-6.2.2102/python/webgui/shader/utils.h ngsolve-6.2.2103/python/webgui/shader/utils.h --- ngsolve-6.2.2102/python/webgui/shader/utils.h 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/shader/utils.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,305 +0,0 @@ -precision highp float; - -uniform mat4 viewMatrix; -uniform mat4 modelViewMatrix; -uniform mat4 modelMatrix; -uniform mat4 projectionMatrix; -uniform mat3 normalMatrix; - -uniform vec4 clipping_plane; -uniform bool do_clipping; - -uniform sampler2D tex_colormap; -uniform float colormap_min; -uniform float colormap_max; - -uniform vec3 light_dir; -uniform vec4 light_mat; // x=ambient, y=diffuse, z=shininess, w=specularity - -// 0-2 ... function component -// 3 ... norm -// 4 ... all 3 components (as rgb) -// 5 ... real part -// 6 ... imag part - -uniform float function_mode; -uniform vec2 complex_scale; -uniform float complex_deform; -uniform float deformation; - -uniform vec2 trafo; - -float GetValue( vec3 value ) -{ - if(function_mode==0.0) return value.x; - if(function_mode==1.0) return value.y; - if(function_mode==2.0) return value.z; - if(function_mode==3.0) return length(value); - if(function_mode==5.0) return value.x*complex_scale.x - value.y*complex_scale.y; - if(function_mode==6.0) return value.x*complex_scale.y + value.y*complex_scale.x; - return 0.0; -} - -/////////////////////////////////////////////////////////////////////////////// -#ifdef VERTEX_SHADER -#ifdef MESH_2D - -///////////////////////////////////////////// -#if ORDER==1 -attribute vec4 p0; -attribute vec4 p1; -attribute vec4 p2; - -attribute vec2 v0; -attribute vec2 v1; -attribute vec2 v2; - - -vec4 GetPositionAndScalar(float u, float v) -{ - float w = 1.0-u-v; - return u*p0 + v*p1 + w*p2; -} - -vec3 GetNormal(float u, float v) -{ - vec4 du = p1-p0; - vec4 dv = p2-p0; - return normalize(cross(du.xyz, dv.xyz)); -} - -vec2 GetVectorValues(float u, float v) -{ - float w = 1.0-u-v; - return u*v0 + v*v1 + w*v2; -} - -#endif // ORDER==1 - -///////////////////////////////////////////// -#if ORDER==2 - -attribute vec4 p00; -attribute vec4 p01; -attribute vec4 p02; -attribute vec4 p10; -attribute vec4 p11; -attribute vec4 p20; - -attribute vec4 vec00_01; -attribute vec4 vec02_10; -attribute vec4 vec11_20; - -vec4 GetPositionAndScalar(float u, float v) -{ - float w = 1.0-u-v; - - float b00 = u*u; - float b01 = 2.0*u*v; - float b02 = v*v; - float b10 = 2.0*u*w; - float b11 = 2.0*v*w; - float b20 = w*w; - - vec4 position = b00*p00+b01*p01+b02*p02 + - b10*p10+b11*p11 + - b20*p20; - return position; -} - -vec3 GetNormal(float u, float v) -{ - float w = 1.0-u-v; - - float B00 = 2.0*u; - float B01 = 2.0*v; - float B10 = 2.0*w; - - vec4 du = B00*(p00-p10) + B01*(p01-p11) + B10*(p10-p20); - vec4 dv = B00*(p01-p10) + B01*(p02-p11) + B10*(p11-p20); - return normalize(cross(du.xyz, dv.xyz)); -} - -vec2 GetVectorValues(float u, float v) -{ - float w = 1.0-u-v; - - float b00 = u*u; - float b01 = 2.0*u*v; - float b02 = v*v; - float b10 = 2.0*u*w; - float b11 = 2.0*v*w; - float b20 = w*w; - - vec2 v00 = vec00_01.xy; - vec2 v01 = vec00_01.zw; - vec2 v02 = vec02_10.xy; - vec2 v10 = vec02_10.zw; - vec2 v11 = vec11_20.xy; - vec2 v20 = vec11_20.zw; - - vec2 values = b00*v00+b01*v01+b02*v02 + - b10*v10+b11*v11 + - b20*v20; - return values; -} - -#endif // ORDER==2 - -///////////////////////////////////////////// -#if ORDER==3 -attribute vec4 p00; -attribute vec4 p01; -attribute vec4 p02; -attribute vec4 p03; -attribute vec4 p10; -attribute vec4 p11; -attribute vec4 p12; -attribute vec4 p20; -attribute vec4 p21; -attribute vec4 p30; - -attribute vec4 vec00_01; -attribute vec4 vec02_03; -attribute vec4 vec10_11; -attribute vec4 vec12_20; -attribute vec4 vec21_30; - -vec4 GetPositionAndScalar(float u, float v) -{ - float w = 1.0-u-v; - - float b00 = u*u*u; - float b01 = 3.0*u*u*v; - float b02 = 3.0*u*v*v; - float b03 = v*v*v; - float b10 = 3.0*u*u*w; - float b11 = 6.0*u*v*w; - float b12 = 3.0*v*v*w; - float b20 = 3.0*u*w*w; - float b21 = 3.0*v*w*w; - float b30 = w*w*w; - - vec4 position = b00*p00+b01*p01+b02*p02+b03*p03 + - b10*p10+b11*p11+b12*p12 + - b20*p20+b21*p21 + - b30*p30; - - return position; -} - -vec3 GetNormal(float u, float v) -{ - float w = 1.0-u-v; - - float B00 = 3.0*u*u; - float B01 = 6.0*u*v; - float B02 = 3.0*v*v; - float B10 = 6.0*u*w; - float B11 = 6.0*v*w; - float B20 = 3.0*w*w; - - vec4 du = B00*(p00-p10) + B01*(p01-p11) + B02*(p02-p12) + - B10*(p10-p20) + B11*(p11-p21) + - B20*(p20-p30); - vec4 dv = B00*(p01-p10) + B01*(p02-p11) + B02*(p03-p12) + - B10*(p11-p20) + B11*(p12-p21) + - B20*(p21-p30); - return normalize(cross(du.xyz, dv.xyz)); -} - -vec2 GetVectorValues(float u, float v) -{ - float w = 1.0-u-v; - - vec2 v00 = vec00_01.xy; - vec2 v01 = vec00_01.zw; - vec2 v02 = vec02_03.xy; - vec2 v03 = vec02_03.zw; - vec2 v10 = vec10_11.xy; - vec2 v11 = vec10_11.zw; - vec2 v12 = vec12_20.xy; - vec2 v20 = vec12_20.zw; - vec2 v21 = vec21_30.xy; - vec2 v30 = vec21_30.zw; - - float b00 = u*u*u; - float b01 = 3.0*u*u*v; - float b02 = 3.0*u*v*v; - float b03 = v*v*v; - float b10 = 3.0*u*u*w; - float b11 = 6.0*u*v*w; - float b12 = 3.0*v*v*w; - float b20 = 3.0*u*w*w; - float b21 = 3.0*v*w*w; - float b30 = w*w*w; - - vec2 values = b00*v00+b01*v01+b02*v02+b03*v03 + - b10*v10+b11*v11+b12*v12 + - b20*v20+b21*v21 + - b30*v30; - - return values; -} - -float GetImagValue(float u, float v) { - return GetVectorValues(u,v).x; -} - -#endif // ODER==3 -#endif // MESH_2D -#endif // VERTEX_SHADER -/////////////////////////////////////////////////////////////////////////////// -vec4 getPositionAsColor(vec3 pos){ - vec4 ret_val = vec4(0.0,0.0,0.0,0.0); - ret_val.x = pos.x*trafo.x+trafo.y; - ret_val.y = pos.y*trafo.x+trafo.y; - ret_val.z = pos.z*trafo.x+trafo.y; - - return ret_val; -} - -bool isBehindClippingPlane(vec3 pos) -{ -#ifdef NO_CLIPPING - return false; -#else // NO_CLIPPING - return do_clipping && dot(clipping_plane, vec4(pos, 1.0)) < 0.0; -#endif // NO_CLIPPING -} - -vec4 getColor(float value) -{ - float x = (value-colormap_min)/(colormap_max-colormap_min); - vec3 color = texture2D(tex_colormap, vec2(x, 0.5)).xyz; - return vec4(color, 1.0); -} - -vec4 calcLight(vec4 color, vec3 position, vec3 norm, bool inside) -{ - vec3 n = normalize(norm); - vec3 s = light_dir; - vec4 p = modelViewMatrix * vec4( position, 1); - vec3 v = normalize( -p.xyz ); - vec3 r = reflect( -s, n ); - - float light_ambient = light_mat.x; - float light_diffuse = light_mat.y; - float light_shininess = light_mat.z; - float light_spec = light_mat.w; - - float sDotN; - float dimm = 1.0; - if (inside) { - dimm = 0.5; - } - - sDotN = max( dot( s, n ), 0.0 ); - - float diffuse = light_diffuse * sDotN; - - // spec = Light[lightIndex].Ls * Material.Ks * pow( max( dot(r,v) , 0.0 ), Material.Shininess ); - float spec = pow( max( dot(r,v) , 0.0 ), light_shininess ); - if(diffuse==0.0) spec = 0.0; - return vec4(dimm*(color.xyz*(light_ambient+diffuse) + spec*light_spec*vec3(1,1,1)), color.w); -} diff -Nru ngsolve-6.2.2102/python/webgui/shader/vector_function.vert ngsolve-6.2.2103/python/webgui/shader/vector_function.vert --- ngsolve-6.2.2102/python/webgui/shader/vector_function.vert 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/shader/vector_function.vert 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -uniform sampler2D tex_values; -uniform float grid_size; -uniform vec3 clipping_plane_c; -uniform vec3 clipping_plane_t1; -uniform vec3 clipping_plane_t2; -uniform float vectors_offset; - -// default attributes (from arrow-geometry) -attribute vec3 position; -attribute vec3 normal; - -// instance attributes -// attribute vec3 position_buffer; -// attribute vec3 rotation_buffer; - -// attribute float vertid; -attribute vec2 arrowid; - -varying vec3 p_; -varying vec3 normal_; -varying vec3 value_; - -// TODO: dont call for every vertex of an instance -vec4 quaternion(vec3 vTo){ - vec3 vFrom = vec3(0.0, 1.0, 0.0); - float EPS = 0.000001; - // assume that vectors are not normalized - float n = length(vTo); - float r = n + dot(vFrom, vTo); - vec3 tmp; - - if ( r < EPS ) { - r = 0.0; - if ( abs(vFrom.x) > abs(vFrom.z) ) { - tmp = vec3(-vFrom.y, vFrom.x, 0.0); - } else { - tmp = vec3(0, -vFrom.z, vFrom.y); - } - } else { - tmp = cross(vFrom, vTo); - //tmp.x = vFrom.y * vTo.z - vFrom.z * vTo.y; - //tmp.y = vFrom.z * vTo.x - vFrom.x * vTo.z; - //tmp.z = vFrom.x * vTo.y - vFrom.y * vTo.x; - } - return normalize(vec4(tmp.x, tmp.y, tmp.z, r)); -} - -// apply a rotation-quaternion to the given vector -// (source: https://goo.gl/Cq3FU0) -vec3 rotate(const vec3 v, const vec4 q) { -vec3 t = 2.0 * cross(q.xyz, v); -return v + q.w * t + cross(q.xyz, t); -} - -void main() { - value_ = texture2D(tex_values, arrowid).xyz; - if(length(value_)==0.0) - { - gl_Position = vec4(0,0,0,1); - return; - } - - vec4 quat = quaternion(value_); - float size = 0.5*length(clipping_plane_t1); - p_ = clipping_plane_c; - p_ += grid_size* (arrowid.x-0.5) * clipping_plane_t1; - p_ += grid_size* (arrowid.y-0.5) * clipping_plane_t2; - p_ += size*rotate(position, quat); - p_ += vectors_offset*size*clipping_plane.xyz; - - - // diffuse-shading - normal_ = rotate(normalMatrix * normal, quat); - - // instance-transform, mesh-transform and projection - gl_Position = projectionMatrix * modelViewMatrix * vec4(p_, 1.0); -} diff -Nru ngsolve-6.2.2102/python/webgui/webgui_template.py ngsolve-6.2.2103/python/webgui/webgui_template.py --- ngsolve-6.2.2102/python/webgui/webgui_template.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui/webgui_template.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,657 +0,0 @@ -import math -import numpy as np -from time import time -import ngsolve as ngs -import os - -# the build script fills the contents of the variables below -render_js_code = "" -widgets_version = "" - -try: - __IPYTHON__ - _IN_IPYTHON = True -except NameError: - _IN_IPYTHON = False - -try: - import google.colab - _IN_GOOGLE_COLAB = True -except ImportError: - _IN_GOOGLE_COLAB = False - -# -# -# -# -html_template = """ - - - - NGSolve WebGUI - - - - - - - - -""" -screenshot_html_template = html_template.replace("preserveDrawingBuffer: false", "preserveDrawingBuffer: true") - - -class WebGLScene: - def __init__(self, cf, mesh, order, min_, max_, draw_vol, draw_surf, autoscale, deformation, interpolate_multidim, animate, clipping, vectors, on_init, eval_function, eval_): - from IPython.display import display, Javascript - import threading - self.cf = cf - self.mesh = mesh - self.order = order - self.min = min_ - self.max = max_ - self.draw_vol = draw_vol - self.draw_surf = draw_surf - self.autoscale = autoscale - self.interpolate_multidim = interpolate_multidim - self.animate = animate - self.clipping = clipping - self.vectors = vectors - self.on_init = on_init - self.eval_function = eval_function - self.eval_ = eval_ - - self.deformation = deformation - - def GetData(self, set_minmax=True): - import json - d = BuildRenderData(self.mesh, self.cf, self.order, draw_surf=self.draw_surf, draw_vol=self.draw_vol, deformation=self.deformation) - - if isinstance(self.cf, ngs.GridFunction) and len(self.cf.vecs)>1: - # multidim gridfunction - generate data for each component - gf = ngs.GridFunction(self.cf.space) - dim = len(self.cf.vecs) - - if isinstance(self.deformation, ngs.GridFunction) and len(self.deformation.vecs)==dim: - md_deformation = True - deformation = ngs.GridFunction(self.deformation.space) - else: - md_deformation = False - deformation = self.deformation - - data = [] - for i in range(1,dim): - gf.vec.data = self.cf.vecs[i] - - if md_deformation: - deformation.vec.data = self.deformation.vecs[i] - - data.append(BuildRenderData(self.mesh, gf, self.order, draw_surf=self.draw_surf, draw_vol=self.draw_vol, deformation=deformation)) - d['multidim_data'] = data - d['multidim_interpolate'] = self.interpolate_multidim - d['multidim_animate'] = self.animate - - - if set_minmax: - if self.min is not None: - d['funcmin'] = self.min - if self.max is not None: - d['funcmax'] = self.max - d['autoscale'] = self.autoscale - - if self.clipping is not None: - d['clipping'] = True - if isinstance(self.clipping, dict): - allowed_args = ("x", "y", "z", "dist", "function", "pnt", "vec") - if "vec" in self.clipping: - vec = self.clipping["vec"] - self.clipping["x"] = vec[0] - self.clipping["y"] = vec[1] - self.clipping["z"] = vec[2] - if "pnt" in self.clipping: - d['mesh_center'] = list(self.clipping["pnt"]) - for name, val in self.clipping.items(): - if not (name in allowed_args): - raise Exception('Only {} allowed as arguments for clipping!'.format(", ".join(allowed_args))) - d['clipping_' + name] = val - - if self.vectors is not None: - d['vectors'] = True - if isinstance(self.vectors, dict): - for name, val in self.vectors.items(): - if not (name in ("grid_size", "offset")): - raise Exception('Only "grid_size" and "offset" allowed as arguments for vectors!') - d['vectors_' + name] = val - - if self.on_init: - d['on_init'] = self.on_init - - if self.eval_function: - d['user_eval_function'] = self.eval_function - - # see shaders/utils.h for value explanation (function_mode) - eval_ = self.eval_ - if eval_ is not None: - if isinstance(eval_, int): - d['eval'] = eval_ - elif eval_ == 'norm': - d['eval'] = 3 - elif eval_ == 'real': - d['eval'] = 5 - elif eval_ == 'imag': - d['eval'] = 6 - - return d - - def GenerateHTML(self, filename=None, template=html_template): - import json - d = self.GetData() - - data = json.dumps(d) - - html = template.replace('{data}', data ) - jscode = "var render_data = {}\n".format(data) + render_js_code - html = html.replace('{render}', jscode ) - - if filename is not None: - open(filename,'w').write( html ) - return html - - def MakeScreenshot(self, filename, width=1200, height=600): - html_file = filename+".html" - self.GenerateHTML(html_file, screenshot_html_template) - - # start headless browser to render html - from selenium import webdriver - from selenium.webdriver.common.desired_capabilities import DesiredCapabilities - - options = webdriver.ChromeOptions() - options.add_argument('--headless') - options.add_argument('--no-sandbox') - # https://stackoverflow.com/questions/54297559/getting-cannot-activate-web-view - options.add_argument("--disable-infobars") - options.add_argument("--disable-dev-shm-usage") - options.add_argument("--disable-browser-side-navigation") - #options.add_argument("--disable-gpu") - options.add_argument("--disable-features=VizDisplayCompositor") - - options.add_argument('window-size=1200x600') - - - driver = webdriver.Chrome(options=options) - fpath = 'file://'+os.path.join(os.path.abspath('.'), html_file) - driver.get(fpath) - driver.implicitly_wait(10) - - import time - time.sleep(2) - driver.get_screenshot_as_file(filename) - os.remove(html_file) - - - def Draw(self): - self.widget = NGSWebGuiWidget() - d = self.GetData() - self.widget.value = d - display(self.widget) - - def Redraw(self): - d = self.GetData(set_minmax=False) - self.widget.value = d - - def __repr__(self): - return "" - - -bezier_trig_trafos = { } # cache trafos for different orders - -timer = ngs.Timer("BuildRenderData") -timer2 = ngs.Timer("edges") -timermult = ngs.Timer("timer2 - mult") -timer3 = ngs.Timer("els") -timer3Bvals = ngs.Timer("timer3, bezier") -timer3minmax = ngs.Timer("els minmax") -timer2list = ngs.Timer("timer2 - make list") -timer3list = ngs.Timer("timer3 - make list") -timer4 = ngs.Timer("func") - - -def BuildRenderData(mesh, func, order=2, draw_surf=True, draw_vol=True, deformation=None): - timer.Start() - - if isinstance(deformation, ngs.CoefficientFunction) and deformation.dim==2: - deformation = ngs.CoefficientFunction((deformation, 0.0)) - - #TODO: handle quads and non-smooth functions - #TODO: subdivision - - d = {} - d['ngsolve_version'] = ngs.__version__ - d['mesh_dim'] = mesh.dim - # order = order or mesh.GetCurveOrder() - if (not func) and (mesh.GetCurveOrder()==1): - order=1 - order2d = min(order, 3) - order3d = min(order, 2) - d['order2d'] = order2d - d['order3d'] = order3d - - d['draw_vol'] = func and mesh.dim==3 and draw_vol and mesh.ne>0 - d['draw_surf'] = func and draw_surf - - if isinstance(deformation, bool): - d['deformation'] = deformation - deformation = None - - func2 = None - if func and func.is_complex: - d['is_complex'] = True - func1 = func[0].real - func2 = ngs.CoefficientFunction( (func[0].imag, 0.0) ) - d['funcdim'] = 2 - elif func and func.dim>1: - func1 = func[0] - func2 = ngs.CoefficientFunction( tuple(func[i] if i we are just drawing a mesh, eval mesh element index instead - mats = mesh.GetMaterials() - bnds = mesh.GetBoundaries() - nmats = len(mesh.GetMaterials()) - nbnds = len(mesh.GetBoundaries()) - n = max(nmats, nbnds) - func1 = ngs.CoefficientFunction(list(range(n))) - n_regions = [0, 0, nmats, nbnds] - d['mesh_regions_2d'] = n_regions[mesh.dim] - d['mesh_regions_3d'] = nmats if mesh.dim==3 else 0 - d['funcdim'] = 0 - func1 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, func1 ) ) - func0 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, 0.0 ) ) - if deformation is not None: - func1 += ngs.CoefficientFunction((deformation, 0.0)) - func0 += ngs.CoefficientFunction((deformation, 0.0)) - - d['show_wireframe'] = False - d['show_mesh'] = False - if order2d>0: - og = order2d - d['show_wireframe'] = True - d['show_mesh'] = True - timer2.Start() - - timer3Bvals.Start() - - # transform point-values to Bernsteinbasis - def Binomial(n,i): return math.factorial(n) / math.factorial(i) / math.factorial(n-i) - def Bernstein(x, i, n): return Binomial(n,i) * x**i*(1-x)**(n-i) - Bvals = ngs.Matrix(og+1,og+1) - for i in range(og+1): - for j in range(og+1): - Bvals[i,j] = Bernstein(i/og, j, og) - iBvals = Bvals.I - timer3Bvals.Stop() - # print (Bvals) - # print (iBvals) - - - Bezier_points = [] - - # TODO: Quads - ipts = [(i/og,0) for i in range(og+1)] + [(0, i/og) for i in range(og+1)] + [(i/og,1.0-i/og) for i in range(og+1)] - ir_trig = ngs.IntegrationRule(ipts, [0,]*len(ipts)) - ipts = [(i/og,0) for i in range(og+1)] + [(0, i/og) for i in range(og+1)] + [(i/og,1.0) for i in range(og+1)] + [(1.0, i/og) for i in range(og+1)] - ir_quad = ngs.IntegrationRule(ipts, [0,]*len(ipts)) - - vb = [ngs.VOL, ngs.BND][mesh.dim-2] - cf = func1 if draw_surf else func0 - pts = mesh.MapToAllElements({ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad}, vb) - pmat = cf(pts) - - timermult.Start() - pmat = pmat.reshape(-1, og+1, 4) - BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1)) - timermult.Stop() - - timer2list.Start() - for i in range(og+1): - Bezier_points.append(encodeData(BezierPnts[i])) - timer2list.Stop() - - if func2 and draw_surf: - pmat = func2(pts) - pmat = pmat.reshape(-1, og+1, 2) - timermult.Start() - BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1)) - timermult.Stop() - timer2list.Start() - for i in range(og+1): - Bezier_points.append(encodeData(BezierPnts[i])) - timer2list.Stop() - - d['Bezier_points'] = Bezier_points - - ipts = [(i/og,0) for i in range(og+1)] - ir_seg = ngs.IntegrationRule(ipts, [0,]*len(ipts)) - vb = [ngs.VOL, ngs.BND, ngs.BBND][mesh.dim-1] - pts = mesh.MapToAllElements(ir_seg, vb) - pmat = func0(pts) - pmat = pmat.reshape(-1, og+1, 4) - edge_data = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1)) - edges = [] - for i in range(og+1): - edges.append(encodeData(edge_data[i])) - d['edges'] = edges - - timer2.Stop() - timer3.Start() - - ndtrig = int((og+1)*(og+2)/2) - - if og in bezier_trig_trafos.keys(): - iBvals_trig = bezier_trig_trafos[og] - else: - def BernsteinTrig(x, y, i, j, n): - return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \ - * x**i*y**j*(1-x-y)**(n-i-j) - Bvals = ngs.Matrix(ndtrig, ndtrig) - ii = 0 - for ix in range(og+1): - for iy in range(og+1-ix): - jj = 0 - for jx in range(og+1): - for jy in range(og+1-jx): - Bvals[ii,jj] = BernsteinTrig(ix/og, iy/og, jx, jy, og) - jj += 1 - ii += 1 - iBvals_trig = Bvals.I - bezier_trig_trafos[og] = iBvals_trig - - - # Bezier_points = [ [] for i in range(ndtrig) ] - Bezier_points = [] - - ipts = [(i/og,j/og) for j in range(og+1) for i in range(og+1-j)] - ir_trig = ngs.IntegrationRule(ipts, [0,]*len(ipts)) - ipts = ([(i/og,j/og) for j in range(og+1) for i in range(og+1-j)] + - [(1-i/og,1-j/og) for j in range(og+1) for i in range(og+1-j)]) - ir_quad = ngs.IntegrationRule(ipts, [0,]*len(ipts)) - - vb = [ngs.VOL, ngs.BND][mesh.dim-2] - pts = mesh.MapToAllElements({ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad}, vb) - - pmat = ngs.CoefficientFunction( func1 if draw_surf else func0 ) (pts) - timer3minmax.Start() - funcmin = np.min(pmat[:,3]) - funcmax = np.max(pmat[:,3]) - pmin = np.min(pmat[:,0:3], axis=0) - pmax = np.max(pmat[:,0:3], axis=0) - mesh_center = (pmin+pmax)/2 - mesh_radius = np.linalg.norm(pmax-pmin)/2 - timer3minmax.Stop() - - pmat = pmat.reshape(-1, len(ir_trig), 4) - BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1,1)) - - timer3list.Start() - for i in range(ndtrig): - Bezier_points.append(encodeData(BezierPnts[i])) - timer3list.Stop() - - if func2 and draw_surf: - pmat = ngs.CoefficientFunction( func2 ) (pts) - - pmat = pmat.reshape(-1, len(ir_trig), 2) - - funcmin = min(funcmin, np.min(pmat)) - funcmax = max(funcmax, np.max(pmat)) - BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1,1)) - if og==1: - for i in range(ndtrig): - Bezier_points.append(encodeData(BezierPnts[i])) - else: - BezierPnts = BezierPnts.transpose((1,0,2)).reshape(-1, len(ir_trig)//2, 4).transpose((1,0,2)) - - for i in range(ndtrig//2): - Bezier_points.append(encodeData(BezierPnts[i])) - - d['Bezier_trig_points'] = Bezier_points - d['mesh_center'] = list(mesh_center) - d['mesh_radius'] = mesh_radius - timer3.Stop() - - - - timer4.Start() - - if d['draw_vol']: - p0 = [] - p1 = [] - p2 = [] - p3 = [] - values = [] - tets = [] - - if order3d==1: - ipts = [(1,0,0), (0,1,0), (0,0,1), (0,0,0)] - ir_tet = ngs.IntegrationRule( ipts, [0]*len(ipts) ) - - - ipts = ([(1,0,0), (0,1,0), (0,0,1), (0,0,0)] + - [(0,0,1), (0,1,0), (0,1,1), (1,0,0)] + - [(1,0,1), (0,1,1), (1,0,0), (0,0,1)]) - ir_prism = ngs.IntegrationRule( ipts, [0]*len(ipts) ) - - - # ipts_cube = ([(1,0,0), (0,1,0), (0,0,1), (0,0,0)] + - # [(0,1,1), (1,1,1), (1,1,0), (1,0,1)] + - # [(1,0,1), (0,1,1), (1,0,0), (0,0,1)] + - # [(0,1,1), (1,1,0), (0,1,0), (1,0,0)] + - # [(0,0,1), (0,1,0), (0,1,1), (1,0,0)] + - # [(1,0,1), (1,1,0), (0,1,1), (1,0,0)] ) - pts = mesh.MapToAllElements({ngs.ET.TET: ir_tet, ngs.ET.PRISM: ir_prism}, ngs.VOL) - - - else: - # TODO: make prism - ir_tet = ngs.IntegrationRule( [ - (1,0,0), - (0,1,0), - (0,0,1), - (0,0,0), - (0.5,0,0), - (0,0.5,0), - (0,0,0.5), - (0.5,0.5,0), - (0.5,0,0.5), - (0,0.5,0.5) ], - [0]*10 ) - pts = mesh.MapToAllElements({ngs.ET.TET: ir_tet}, ngs.VOL) - - pmat = func1(pts) - - ne = mesh.GetNE(ngs.VOL) - pmat = pmat.reshape(-1, len(ir_tet), 4) - - funcmin = min(funcmin, np.min(pmat[:,:,3])) - funcmax = max(funcmax, np.max(pmat[:,:,3])) - points3d = [] - for i in range(len(ir_tet)): - points3d.append(encodeData(pmat[:,i,:])) - - if func2: - pmat = func2(pts).reshape(-1, len(ir_tet)//2, 4) - funcmin = min(funcmin, np.min(pmat)) - funcmax = max(funcmax, np.max(pmat)) - for i in range(len(ir_tet)//2): - points3d.append(encodeData(pmat[:,i,:])) - d['points3d'] = points3d - if func: - d['funcmin'] = funcmin - d['funcmax'] = funcmax - timer4.Stop() - timer.Stop() - return d - -def Draw(mesh_or_func, mesh_or_none=None, name='function', order=2, min=None, max=None, draw_vol=True, draw_surf=True, autoscale=True, deformation=False, interpolate_multidim=False, animate=False, clipping=None, vectors=None, js_code=None, eval_function=None, eval=None, filename=""): - if isinstance(mesh_or_func, ngs.Mesh): - mesh = mesh_or_func - func = None - - if isinstance(mesh_or_func, ngs.CoefficientFunction): - func = mesh_or_func - mesh = mesh_or_none - - if isinstance(mesh_or_func, ngs.GridFunction): - func = mesh_or_func - mesh = mesh_or_none or func.space.mesh - - scene = WebGLScene(func, mesh, order, min_=min, max_=max, draw_vol=draw_vol, draw_surf=draw_surf, autoscale=autoscale, deformation=deformation, interpolate_multidim=interpolate_multidim, animate=animate, clipping=clipping, vectors=vectors, on_init=js_code, eval_function=eval_function, eval_=eval) - if _IN_IPYTHON: - if _IN_GOOGLE_COLAB: - from IPython.display import display, HTML - html = scene.GenerateHTML() - display(HTML(html)) - else: - # render scene using widgets.DOMWidget - scene.Draw() - return scene - else: - if filename: - scene.GenerateHTML(filename=filename) - return scene - - -from ipywidgets import DOMWidget, register -from traitlets import Unicode - -@register -class NGSWebGuiWidget(DOMWidget): - from traitlets import Dict, Unicode - _view_name = Unicode('NGSolveView').tag(sync=True) - _view_module = Unicode('ngsolve_jupyter_widgets').tag(sync=True) - _view_module_version = Unicode(widgets_version).tag(sync=True) - value = Dict({"ngsolve_version":'0.0.0'}).tag(sync=True) - -tencode = ngs.Timer("encode") -def encodeData( array ): - from base64 import b64encode - tencode.Start() - values = np.array(array.flatten(), dtype=np.float32) - res = b64encode(values).decode("ascii") - tencode.Stop() - return res - -_jupyter_lab_extension_path = os.path.join(os.path.dirname(ngs.__file__), "labextension") - -def howtoInstallJupyterLabextension(): - import ngsolve, os - d = os.path.dirname(ngsolve.__file__) - labdir = os.path.join(d, "labextension") - print("""# To install jupyter lab extension: -jupyter labextension install --clean {labdir} -""".format(labdir=_jupyter_lab_extension_path)) - -@register -class NGSDocuWebGuiWidget(DOMWidget): - from traitlets import Dict, Unicode - _view_name = Unicode('NGSolveDocuView').tag(sync=True) - _view_module = Unicode('ngsolve_jupyter_widgets').tag(sync=True) - _view_module_version = Unicode(widgets_version).tag(sync=True) - value = Dict({"ngsolve_version":'0.0.0'}).tag(sync=True) - -# counter for each directory to name preview.png and render_data.json files -# __docu_file_counter = -1 - -def _DrawDocu(mesh_or_func, mesh_or_none=None, name='function', order=2, min=None, max=None, draw_vol=True, draw_surf=True, autoscale=True, deformation=False, interpolate_multidim=False, animate=False, clipping=None, vectors=None, js_code=None, eval_function=None, eval=None, filename=""): - if isinstance(mesh_or_func, ngs.Mesh): - mesh = mesh_or_func - func = None - - if isinstance(mesh_or_func, ngs.CoefficientFunction): - func = mesh_or_func - mesh = mesh_or_none - - if isinstance(mesh_or_func, ngs.GridFunction): - func = mesh_or_func - mesh = mesh_or_none or func.space.mesh - - scene = WebGLScene(func, mesh, order, min_=min, max_=max, draw_vol=draw_vol, draw_surf=draw_surf, autoscale=autoscale, deformation=deformation, interpolate_multidim=interpolate_multidim, animate=animate, clipping=clipping, vectors=vectors, on_init=js_code, eval_function=eval_function, eval_=eval) - import json - - docu_path = os.environ['NETGEN_DOCUMENTATION_OUT_DIR'] - src_path = os.environ['NETGEN_DOCUMENTATION_SRC_DIR'] - cwd_path = os.path.abspath('.') - rel_path = os.path.relpath('.', src_path) - path = os.path.join(docu_path, rel_path) - - if not os.path.exists(path): - os.makedirs(path) - counter_file = os.path.join(docu_path, '.counter') - if os.path.exists(counter_file): - file_counter = int(open(counter_file,'r').read())+1 - else: - file_counter = 0 - - open(counter_file,'w').write(str(file_counter)) - -# file_counter = __docu_file_counter[path] -# __docu_file_counter[path] += 1 - - data_file = 'render_data_{}.json'.format(file_counter) - data_file_abs = os.path.join(path, data_file) - preview_file = 'preview_{}.png'.format(file_counter) - preview_file_abs = os.path.join(path, preview_file) - - - widget = NGSDocuWebGuiWidget() - widget.value = {'render_data' : data_file, 'preview' : preview_file } - scene.widget = widget - data = scene.GetData() - json.dump(data, open(data_file_abs, "w")) - scene.MakeScreenshot(preview_file_abs, 1200, 600) - scene.Redraw = lambda : None - display(widget) - return scene - -if 'NETGEN_DOCUMENTATION_SRC_DIR' in os.environ: - # we are buiding the documentation, some things are handled differently: - # 1) Draw() is generating a .png (using headless chromium via selenium) and a render_data.json - # to show a preview image and load the render_data only when requested by user - # 2) return a NGSDocuWebGuiWidget instead of NGSWebGuiWidget implementing the preview/load on demand of webgui - - _Draw = Draw - Draw = _DrawDocu - - - - - - - - diff -Nru ngsolve-6.2.2102/python/webgui.py ngsolve-6.2.2103/python/webgui.py --- ngsolve-6.2.2102/python/webgui.py 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/python/webgui.py 2021-06-04 23:31:19.000000000 +0000 @@ -0,0 +1,504 @@ +import math +import numpy as np +from time import time +import ngsolve as ngs +import os + +from webgui_jupyter_widgets import BaseWebGuiScene, encodeData, WebGuiDocuWidget +import webgui_jupyter_widgets.widget as wg + +class WebGLScene(BaseWebGuiScene): + def __init__(self, cf, mesh, order, min_, max_, draw_vol, draw_surf, autoscale, deformation, interpolate_multidim, animate, clipping, vectors, on_init, eval_function, eval_): + from IPython.display import display, Javascript + import threading + self.cf = cf + self.mesh = mesh + self.order = order + self.min = min_ + self.max = max_ + self.draw_vol = draw_vol + self.draw_surf = draw_surf + self.autoscale = autoscale + self.interpolate_multidim = interpolate_multidim + self.animate = animate + self.clipping = clipping + self.vectors = vectors + self.on_init = on_init + self.eval_function = eval_function + self.eval_ = eval_ + + self.deformation = deformation + + if isinstance(mesh, ngs.comp.Region): + self.region = mesh + self.mesh = self.region.mesh + else: + self.region = None + + def GetData(self, set_minmax=True): + import json + d = BuildRenderData(self.mesh, self.cf, self.order, draw_surf=self.draw_surf, draw_vol=self.draw_vol, deformation=self.deformation, region=self.region) + + if isinstance(self.cf, ngs.GridFunction) and len(self.cf.vecs)>1: + # multidim gridfunction - generate data for each component + gf = ngs.GridFunction(self.cf.space) + dim = len(self.cf.vecs) + + if isinstance(self.deformation, ngs.GridFunction) and len(self.deformation.vecs)==dim: + md_deformation = True + deformation = ngs.GridFunction(self.deformation.space) + else: + md_deformation = False + deformation = self.deformation + + data = [] + for i in range(1,dim): + gf.vec.data = self.cf.vecs[i] + + if md_deformation: + deformation.vec.data = self.deformation.vecs[i] + + data.append(BuildRenderData(self.mesh, gf, self.order, draw_surf=self.draw_surf, draw_vol=self.draw_vol, deformation=deformation, region=self.region)) + d['multidim_data'] = data + d['multidim_interpolate'] = self.interpolate_multidim + d['multidim_animate'] = self.animate + + + if set_minmax: + if self.min is not None: + d['funcmin'] = self.min + if self.max is not None: + d['funcmax'] = self.max + d['autoscale'] = self.autoscale + + if self.clipping is not None: + d['clipping'] = True + if isinstance(self.clipping, dict): + allowed_args = ("x", "y", "z", "dist", "function", "pnt", "vec") + if "vec" in self.clipping: + vec = self.clipping["vec"] + self.clipping["x"] = vec[0] + self.clipping["y"] = vec[1] + self.clipping["z"] = vec[2] + if "pnt" in self.clipping: + d['mesh_center'] = list(self.clipping["pnt"]) + for name, val in self.clipping.items(): + if not (name in allowed_args): + raise Exception('Only {} allowed as arguments for clipping!'.format(", ".join(allowed_args))) + d['clipping_' + name] = val + + if self.vectors is not None: + d['vectors'] = True + if isinstance(self.vectors, dict): + for name, val in self.vectors.items(): + if not (name in ("grid_size", "offset")): + raise Exception('Only "grid_size" and "offset" allowed as arguments for vectors!') + d['vectors_' + name] = val + + if self.on_init: + d['on_init'] = self.on_init + + if self.eval_function: + d['user_eval_function'] = self.eval_function + + # see shaders/utils.h for value explanation (function_mode) + eval_ = self.eval_ + if eval_ is not None: + if isinstance(eval_, int): + d['eval'] = eval_ + elif eval_ == 'norm': + d['eval'] = 3 + elif eval_ == 'real': + d['eval'] = 5 + elif eval_ == 'imag': + d['eval'] = 6 + + return d + + +bezier_trig_trafos = { } # cache trafos for different orders + +timer = ngs.Timer("BuildRenderData") +timer2 = ngs.Timer("edges") +timermult = ngs.Timer("timer2 - mult") +timer3 = ngs.Timer("els") +timer3Bvals = ngs.Timer("timer3, bezier") +timer3minmax = ngs.Timer("els minmax") +timer2list = ngs.Timer("timer2 - make list") +timer3list = ngs.Timer("timer3 - make list") +timer4 = ngs.Timer("func") + + +def BuildRenderData(mesh, func, order=2, draw_surf=True, draw_vol=True, deformation=None, region=True): + timer.Start() + + if isinstance(deformation, ngs.CoefficientFunction) and deformation.dim==2: + deformation = ngs.CoefficientFunction((deformation, 0.0)) + + #TODO: handle quads and non-smooth functions + #TODO: subdivision + + d = {} + d['ngsolve_version'] = ngs.__version__ + d['mesh_dim'] = mesh.dim + # order = order or mesh.GetCurveOrder() + if (not func) and (mesh.GetCurveOrder()==1): + order=1 + order2d = min(order, 3) + order3d = min(order, 2) + d['order2d'] = order2d + d['order3d'] = order3d + + d['draw_vol'] = func and mesh.dim==3 and draw_vol and mesh.ne>0 + d['draw_surf'] = func and draw_surf + + if isinstance(deformation, bool): + d['deformation'] = deformation + deformation = None + + func2 = None + if func and func.is_complex: + d['is_complex'] = True + func1 = func[0].real + func2 = ngs.CoefficientFunction( (func[0].imag, 0.0) ) + d['funcdim'] = 2 + elif func and func.dim>1: + func1 = func[0] + func2 = ngs.CoefficientFunction( tuple(func[i] if i we are just drawing a mesh, eval mesh element index instead + mats = mesh.GetMaterials() + bnds = mesh.GetBoundaries() + nmats = len(mesh.GetMaterials()) + nbnds = len(mesh.GetBoundaries()) + n = max(nmats, nbnds) + func1 = ngs.CoefficientFunction(list(range(n))) + n_regions = [0, 0, nmats, nbnds] + d['mesh_regions_2d'] = n_regions[mesh.dim] + d['mesh_regions_3d'] = nmats if mesh.dim==3 else 0 + d['funcdim'] = 0 + func1 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, func1 ) ) + func0 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, 0.0 ) ) + if deformation is not None: + func1 += ngs.CoefficientFunction((deformation, 0.0)) + func0 += ngs.CoefficientFunction((deformation, 0.0)) + + d['show_wireframe'] = False + d['show_mesh'] = False + if order2d>0: + og = order2d + d['show_wireframe'] = True + d['show_mesh'] = True + timer2.Start() + + timer3Bvals.Start() + + # transform point-values to Bernsteinbasis + def Binomial(n,i): return math.factorial(n) / math.factorial(i) / math.factorial(n-i) + def Bernstein(x, i, n): return Binomial(n,i) * x**i*(1-x)**(n-i) + Bvals = ngs.Matrix(og+1,og+1) + for i in range(og+1): + for j in range(og+1): + Bvals[i,j] = Bernstein(i/og, j, og) + iBvals = Bvals.I + timer3Bvals.Stop() + # print (Bvals) + # print (iBvals) + + + Bezier_points = [] + + # TODO: Quads + ipts = [(i/og,0) for i in range(og+1)] + [(0, i/og) for i in range(og+1)] + [(i/og,1.0-i/og) for i in range(og+1)] + ir_trig = ngs.IntegrationRule(ipts, [0,]*len(ipts)) + ipts = [(i/og,0) for i in range(og+1)] + [(0, i/og) for i in range(og+1)] + [(i/og,1.0) for i in range(og+1)] + [(1.0, i/og) for i in range(og+1)] + ir_quad = ngs.IntegrationRule(ipts, [0,]*len(ipts)) + + vb = [ngs.VOL, ngs.BND][mesh.dim-2] + if region and region.VB() == vb: + vb = region + cf = func1 if draw_surf else func0 + pts = mesh.MapToAllElements({ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad}, vb) + pmat = cf(pts) + + timermult.Start() + pmat = pmat.reshape(-1, og+1, 4) + BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1)) + timermult.Stop() + + timer2list.Start() + for i in range(og+1): + Bezier_points.append(encodeData(BezierPnts[i])) + timer2list.Stop() + + if func2 and draw_surf: + pmat = func2(pts) + pmat = pmat.reshape(-1, og+1, 2) + timermult.Start() + BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1)) + timermult.Stop() + timer2list.Start() + for i in range(og+1): + Bezier_points.append(encodeData(BezierPnts[i])) + timer2list.Stop() + + d['Bezier_points'] = Bezier_points + + ipts = [(i/og,0) for i in range(og+1)] + ir_seg = ngs.IntegrationRule(ipts, [0,]*len(ipts)) + vb = [ngs.VOL, ngs.BND, ngs.BBND][mesh.dim-1] + if region and region.VB() == vb: + vb = region + pts = mesh.MapToAllElements(ir_seg, vb) + pmat = func0(pts) + pmat = pmat.reshape(-1, og+1, 4) + edge_data = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1)) + edges = [] + for i in range(og+1): + edges.append(encodeData(edge_data[i])) + d['edges'] = edges + + timer2.Stop() + timer3.Start() + + ndtrig = int((og+1)*(og+2)/2) + + if og in bezier_trig_trafos.keys(): + iBvals_trig = bezier_trig_trafos[og] + else: + def BernsteinTrig(x, y, i, j, n): + return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \ + * x**i*y**j*(1-x-y)**(n-i-j) + Bvals = ngs.Matrix(ndtrig, ndtrig) + ii = 0 + for ix in range(og+1): + for iy in range(og+1-ix): + jj = 0 + for jx in range(og+1): + for jy in range(og+1-jx): + Bvals[ii,jj] = BernsteinTrig(ix/og, iy/og, jx, jy, og) + jj += 1 + ii += 1 + iBvals_trig = Bvals.I + bezier_trig_trafos[og] = iBvals_trig + + + # Bezier_points = [ [] for i in range(ndtrig) ] + Bezier_points = [] + + ipts = [(i/og,j/og) for j in range(og+1) for i in range(og+1-j)] + ir_trig = ngs.IntegrationRule(ipts, [0,]*len(ipts)) + ipts = ([(i/og,j/og) for j in range(og+1) for i in range(og+1-j)] + + [(1-i/og,1-j/og) for j in range(og+1) for i in range(og+1-j)]) + ir_quad = ngs.IntegrationRule(ipts, [0,]*len(ipts)) + + vb = [ngs.VOL, ngs.BND][mesh.dim-2] + if region and region.VB() == vb: + vb = region + pts = mesh.MapToAllElements({ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad}, vb) + + pmat = ngs.CoefficientFunction( func1 if draw_surf else func0 ) (pts) + timer3minmax.Start() + funcmin = np.min(pmat[:,3]) + funcmax = np.max(pmat[:,3]) + pmin = np.min(pmat[:,0:3], axis=0) + pmax = np.max(pmat[:,0:3], axis=0) + mesh_center = (pmin+pmax)/2 + mesh_radius = np.linalg.norm(pmax-pmin)/2 + timer3minmax.Stop() + + pmat = pmat.reshape(-1, len(ir_trig), 4) + BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1,1)) + + timer3list.Start() + for i in range(ndtrig): + Bezier_points.append(encodeData(BezierPnts[i])) + timer3list.Stop() + + if func2 and draw_surf: + pmat = ngs.CoefficientFunction( func2 ) (pts) + + pmat = pmat.reshape(-1, len(ir_trig), 2) + + funcmin = min(funcmin, np.min(pmat)) + funcmax = max(funcmax, np.max(pmat)) + BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1,1)) + if og==1: + for i in range(ndtrig): + Bezier_points.append(encodeData(BezierPnts[i])) + else: + BezierPnts = BezierPnts.transpose((1,0,2)).reshape(-1, len(ir_trig)//2, 4).transpose((1,0,2)) + + for i in range(ndtrig//2): + Bezier_points.append(encodeData(BezierPnts[i])) + + d['Bezier_trig_points'] = Bezier_points + d['mesh_center'] = list(mesh_center) + d['mesh_radius'] = mesh_radius + timer3.Stop() + + + + timer4.Start() + + if d['draw_vol']: + p0 = [] + p1 = [] + p2 = [] + p3 = [] + values = [] + tets = [] + + if order3d==1: + ipts = [(1,0,0), (0,1,0), (0,0,1), (0,0,0)] + ir_tet = ngs.IntegrationRule( ipts, [0]*len(ipts) ) + + + ipts = ([(1,0,0), (0,1,0), (0,0,1), (0,0,0)] + + [(0,0,1), (0,1,0), (0,1,1), (1,0,0)] + + [(1,0,1), (0,1,1), (1,0,0), (0,0,1)]) + ir_prism = ngs.IntegrationRule( ipts, [0]*len(ipts) ) + + + ipts_hex = ([(1,0,0), (0,1,0), (0,0,1), (0,0,0)] + + [(0,1,1), (1,1,1), (1,1,0), (1,0,1)] + + [(1,0,1), (0,1,1), (1,0,0), (0,0,1)] + + [(0,1,1), (1,1,0), (0,1,0), (1,0,0)] + + [(0,0,1), (0,1,0), (0,1,1), (1,0,0)] + + [(1,0,1), (1,1,0), (0,1,1), (1,0,0)] ) + ir_hex = ngs.IntegrationRule( ipts_hex, [0]*len(ipts_hex) ) + pts = mesh.MapToAllElements({ngs.ET.TET: ir_tet, ngs.ET.PRISM: ir_prism, ngs.ET.HEX: ir_hex }, ngs.VOL) + + + else: + # TODO: make prism + ir_tet = ngs.IntegrationRule( [ + (1,0,0), + (0,1,0), + (0,0,1), + (0,0,0), + (0.5,0,0), + (0,0.5,0), + (0,0,0.5), + (0.5,0.5,0), + (0.5,0,0.5), + (0,0.5,0.5) ], + [0]*10 ) + pts = mesh.MapToAllElements({ngs.ET.TET: ir_tet}, ngs.VOL) + + pmat = func1(pts) + + ne = mesh.GetNE(ngs.VOL) + pmat = pmat.reshape(-1, len(ir_tet), 4) + + funcmin = min(funcmin, np.min(pmat[:,:,3])) + funcmax = max(funcmax, np.max(pmat[:,:,3])) + points3d = [] + for i in range(len(ir_tet)): + points3d.append(encodeData(pmat[:,i,:])) + + if func2: + pmat = func2(pts).reshape(-1, len(ir_tet)//2, 4) + funcmin = min(funcmin, np.min(pmat)) + funcmax = max(funcmax, np.max(pmat)) + for i in range(len(ir_tet)//2): + points3d.append(encodeData(pmat[:,i,:])) + d['points3d'] = points3d + if func: + d['funcmin'] = funcmin + d['funcmax'] = funcmax + timer4.Stop() + timer.Stop() + return d + +def Draw(mesh_or_func, mesh_or_none=None, name='function', order=2, min=None, max=None, draw_vol=True, draw_surf=True, autoscale=True, deformation=False, interpolate_multidim=False, animate=False, clipping=None, vectors=None, js_code=None, eval_function=None, eval=None, filename=""): + if isinstance(mesh_or_func, ngs.Mesh): + mesh = mesh_or_func + func = None + + if isinstance(mesh_or_func, ngs.CoefficientFunction): + func = mesh_or_func + mesh = mesh_or_none + + if isinstance(mesh_or_func, ngs.GridFunction): + func = mesh_or_func + mesh = mesh_or_none or func.space.mesh + + scene = WebGLScene(func, mesh, order, min_=min, max_=max, draw_vol=draw_vol, draw_surf=draw_surf, autoscale=autoscale, deformation=deformation, interpolate_multidim=interpolate_multidim, animate=animate, clipping=clipping, vectors=vectors, on_init=js_code, eval_function=eval_function, eval_=eval) + if wg._IN_IPYTHON: + if wg._IN_GOOGLE_COLAB: + from IPython.display import display, HTML + html = scene.GenerateHTML() + display(HTML(html)) + else: + # render scene using widgets.DOMWidget + scene.Draw() + return scene + else: + if filename: + scene.GenerateHTML(filename=filename) + return scene + + +def _DrawDocu(mesh_or_func, mesh_or_none=None, name='function', order=2, min=None, max=None, draw_vol=True, draw_surf=True, autoscale=True, deformation=False, interpolate_multidim=False, animate=False, clipping=None, vectors=None, js_code=None, eval_function=None, eval=None, filename=""): + if isinstance(mesh_or_func, ngs.Mesh): + mesh = mesh_or_func + func = None + + if isinstance(mesh_or_func, ngs.CoefficientFunction): + func = mesh_or_func + mesh = mesh_or_none + + if isinstance(mesh_or_func, ngs.GridFunction): + func = mesh_or_func + mesh = mesh_or_none or func.space.mesh + + scene = WebGLScene(func, mesh, order, min_=min, max_=max, draw_vol=draw_vol, draw_surf=draw_surf, autoscale=autoscale, deformation=deformation, interpolate_multidim=interpolate_multidim, animate=animate, clipping=clipping, vectors=vectors, on_init=js_code, eval_function=eval_function, eval_=eval) + import json + + docu_path = os.environ['NETGEN_DOCUMENTATION_OUT_DIR'] + src_path = os.environ['NETGEN_DOCUMENTATION_SRC_DIR'] + cwd_path = os.path.abspath('.') + rel_path = os.path.relpath('.', src_path) + path = os.path.join(docu_path, rel_path) + + if not os.path.exists(path): + os.makedirs(path) + counter_file = os.path.join(docu_path, '.counter') + if os.path.exists(counter_file): + file_counter = int(open(counter_file,'r').read())+1 + else: + file_counter = 0 + + open(counter_file,'w').write(str(file_counter)) + + data_file = 'render_data_{}.json'.format(file_counter) + data_file_abs = os.path.join(path, data_file) + preview_file = 'preview_{}.png'.format(file_counter) + preview_file_abs = os.path.join(path, preview_file) + + + widget = WebGuiDocuWidget() + widget.value = {'render_data' : data_file, 'preview' : preview_file } + scene.widget = widget + data = scene.GetData() + json.dump(data, open(data_file_abs, "w")) + scene.MakeScreenshot(preview_file_abs, 1200, 600) + scene.Redraw = lambda : None + from IPython.display import display, HTML + display(widget) + return scene + +if 'NETGEN_DOCUMENTATION_SRC_DIR' in os.environ: + # we are buiding the documentation, some things are handled differently: + # 1) Draw() is generating a .png (using headless chromium via selenium) and a render_data.json + # to show a preview image and load the render_data only when requested by user + # 2) return a NGSDocuWebGuiWidget instead of NGSWebGuiWidget implementing the preview/load on demand of webgui + + _Draw = Draw + Draw = _DrawDocu + diff -Nru ngsolve-6.2.2102/py_tutorials/blocksmoothing.py ngsolve-6.2.2103/py_tutorials/blocksmoothing.py --- ngsolve-6.2.2102/py_tutorials/blocksmoothing.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/blocksmoothing.py 2021-06-04 23:31:19.000000000 +0000 @@ -7,11 +7,11 @@ u,v = fes.TrialFunction(), fes.TestFunction() a = BilinearForm(fes) -a += SymbolicBFI (grad(u)*grad(v)+u*v) +a += (grad(u)*grad(v)+u*v)*dx a.Assemble() f = LinearForm(fes) -f += SymbolicLFI (v) +f += v*dx f.Assemble() blocks = [set() for x in range(mesh.nv)] diff -Nru ngsolve-6.2.2102/py_tutorials/DG/nitsche.py ngsolve-6.2.2103/py_tutorials/DG/nitsche.py --- ngsolve-6.2.2102/py_tutorials/DG/nitsche.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/DG/nitsche.py 2021-06-04 23:31:19.000000000 +0000 @@ -15,14 +15,14 @@ udir = CoefficientFunction(x*y) -a = BilinearForm(V) -a += SymbolicBFI (grad(u)*grad(v)) -a += SymbolicBFI (-n*grad(u)*v - n*grad(v)*u + penalty/h*u*v, BND, skeleton=True) +a = BilinearForm(V, symmetric=True) +a += grad(u)*grad(v)*dx +a += (-n*grad(u)*v - n*grad(v)*u + penalty/h*u*v)*ds(skeleton=True) a.Assemble() f = LinearForm(V) -f += SymbolicLFI ( 1 * v) -f += SymbolicLFI ( -n*grad(v)*udir + penalty/h*udir*v, BND, skeleton=True) +f += 1 * v * dx +f += ( -n*grad(v)*udir + penalty/h*udir*v)*ds(skeleton=True) f.Assemble() u = GridFunction(V) diff -Nru ngsolve-6.2.2102/py_tutorials/DG/periodic.py ngsolve-6.2.2103/py_tutorials/DG/periodic.py --- ngsolve-6.2.2102/py_tutorials/DG/periodic.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/DG/periodic.py 2021-06-04 23:31:19.000000000 +0000 @@ -33,16 +33,16 @@ alpha = 4 h = specialcf.mesh_size -a = BilinearForm(fes) -a += SymbolicBFI(grad(u)*grad(v)) -a += SymbolicBFI(alpha*order**2/h*jump_u*jump_v, skeleton=True) -a += SymbolicBFI(-mean_dudn*jump_v -mean_dvdn*jump_u, skeleton=True) -a += SymbolicBFI(alpha*order**2/h*u*v, BND, skeleton=True, definedon=mesh.Boundaries("outer")) -a += SymbolicBFI(-n*grad(u)*v-n*grad(v)*u, BND, skeleton=True, definedon=mesh.Boundaries("outer")) +a = BilinearForm(fes, symmetric=True) +a += grad(u)*grad(v)*dx +a += alpha*order**2/h*jump_u*jump_v*dx(skeleton=True) +a += (-mean_dudn*jump_v -mean_dvdn*jump_u)*dx(skeleton=True) +a += alpha*order**2/h*u*v*ds("outer", skeleton=True) +a += (-n*grad(u)*v-n*grad(v)*u)*ds("outer", skeleton=True) a.Assemble() f = LinearForm(fes) -f += SymbolicLFI(1*v) +f += 1*v*dx f.Assemble() gfu = GridFunction(fes, name="uDG") diff -Nru ngsolve-6.2.2102/py_tutorials/DG/timeDGlap.py ngsolve-6.2.2103/py_tutorials/DG/timeDGlap.py --- ngsolve-6.2.2102/py_tutorials/DG/timeDGlap.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/DG/timeDGlap.py 2021-06-04 23:31:19.000000000 +0000 @@ -15,11 +15,11 @@ h = specialcf.mesh_size a = BilinearForm(fes) -a += SymbolicBFI ( grad(u) * grad(v) ) +a += grad(u) * grad(v) * dx cf1 = -0.5 * InnerProduct(grad(u), n)*(v-v.Other(bnd=0)) cf2 = -0.5 * InnerProduct(grad(v), n)*(u-u.Other(bnd=u0)) cf3 = 2*( (order+1)**2)/h * (u-u.Other(bnd=u0)) * v -a += SymbolicBFI (cf1+cf2+cf3, element_boundary=True) +a += (cf1+cf2+cf3)*dx(element_boundary=True) u = GridFunction(fes) u.Set(u0) diff -Nru ngsolve-6.2.2102/py_tutorials/DG/timeDG.py ngsolve-6.2.2103/py_tutorials/DG/timeDG.py --- ngsolve-6.2.2102/py_tutorials/DG/timeDG.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/DG/timeDG.py 2021-06-04 23:31:19.000000000 +0000 @@ -14,8 +14,8 @@ ubnd = CoefficientFunction(0) a = BilinearForm(fes) -a += SymbolicBFI (-u * b*grad(v)) -a += SymbolicBFI (bn*IfPos(bn, u, u.Other(bnd=ubnd)) * v, element_boundary=True) +a += -u * b*grad(v) * dx +a += bn*IfPos(bn, u, u.Other(bnd=ubnd)) * v * dx(element_boundary=True) u = GridFunction(fes) u.Set(exp (-40 * ( (x-0.7)*(x-0.7) + (y-0.7)*(y-0.7) ))) diff -Nru ngsolve-6.2.2102/py_tutorials/DG/timeDG-skeleton.py ngsolve-6.2.2103/py_tutorials/DG/timeDG-skeleton.py --- ngsolve-6.2.2102/py_tutorials/DG/timeDG-skeleton.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/DG/timeDG-skeleton.py 2021-06-04 23:31:19.000000000 +0000 @@ -14,15 +14,15 @@ ubnd = CoefficientFunction(0) a = BilinearForm(fes) -a += SymbolicBFI ( (-u * b*grad(v)) .Compile() ) +a += (-u * b*grad(v)) .Compile()*dx # the skeleton-formulation, sum over edges: -a += SymbolicBFI ( bn*IfPos(bn, u, u.Other()) * (v-v.Other()), VOL, skeleton=True) -a += SymbolicBFI ( bn*IfPos(bn, u, ubnd) * v, BND, skeleton=True) +a += bn*IfPos(bn, u, u.Other()) * (v-v.Other()) * dx(skeleton=True) +a += bn*IfPos(bn, u, ubnd) * v * ds(skeleton=True) # or the element-boundary formulation # note the bnd-value in the .Other operator -# a += SymbolicBFI ( (bn*IfPos(bn, u, u.Other(bnd=ubnd)) * v), element_boundary=True) +# a += bn*IfPos(bn, u, u.Other(bnd=ubnd)) * v * dx(element_boundary=True) u = GridFunction(fes) u.Set(exp (-40 * ( (x-0.7)*(x-0.7) + (y-0.7)*(y-0.7) ))) diff -Nru ngsolve-6.2.2102/py_tutorials/DG/timeDGwave.py ngsolve-6.2.2103/py_tutorials/DG/timeDGwave.py --- ngsolve-6.2.2102/py_tutorials/DG/timeDGwave.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/DG/timeDGwave.py 2021-06-04 23:31:19.000000000 +0000 @@ -5,7 +5,7 @@ order=4 fes1 = L2(mesh, order=order) -fes = FESpace ([fes1,fes1,fes1]) +fes = fes1*fes1*fes1 p,ux,uy = fes.TrialFunction() q,vx,vy = fes.TestFunction() @@ -18,12 +18,12 @@ u = CoefficientFunction( (ux, uy) ) a1 = BilinearForm(fes) -a1 += SymbolicBFI ( grad(p) * v ) -a1 += SymbolicBFI ( -0.5 * (p - p.Other()) * (v*n), element_boundary = True) +a1 += grad(p) * v * dx +a1 += -0.5 * (p - p.Other()) * (v*n) * dx(element_boundary = True) a2 = BilinearForm(fes) -a2 += SymbolicBFI ( -grad(q) * u ) -a2 += SymbolicBFI ( 0.5 * (q - q.Other()) * (u*n), element_boundary = True) +a2 += -grad(q) * u * dx +a2 += 0.5 * (q - q.Other()) * (u*n) * dx(element_boundary = True) u = GridFunction(fes) diff -Nru ngsolve-6.2.2102/py_tutorials/hdivdiv/hhj.py ngsolve-6.2.2103/py_tutorials/hdivdiv/hhj.py --- ngsolve-6.2.2102/py_tutorials/hdivdiv/hhj.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/hdivdiv/hhj.py 2021-06-04 23:31:19.000000000 +0000 @@ -12,8 +12,8 @@ order = 3 V = HDivDiv(mesh, order=order-1) -Q = H1(mesh, order=order, dirichlet=[1,2,3,4]) -X = FESpace([V,Q]) +Q = H1(mesh, order=order, dirichlet="left|right|top|bottom") +X = V*Q print ("ndof-V:", V.ndof, ", ndof-Q:", Q.ndof) @@ -25,13 +25,13 @@ def tang(u): return u-(u*n)*n a = BilinearForm(X, symmetric=True) -a += SymbolicBFI ( InnerProduct (sigma, tau) + div(sigma)*grad(v) + div(tau)*grad(u) - 1e-10*u*v ) -a += SymbolicBFI ( -(sigma*n) * tang(grad(v)) - (tau*n)*tang(grad(u)), element_boundary=True) +a += (InnerProduct (sigma, tau) + div(sigma)*grad(v) + div(tau)*grad(u) - 1e-10*u*v)*dx +a += (-(sigma*n) * tang(grad(v)) - (tau*n)*tang(grad(u)))*dx(element_boundary=True) a.Assemble() f = LinearForm(X) -f += SymbolicLFI ( 1 * v ) -# f += SymbolicLFI (tau.Trace(), BND, definedon=[1]) +f += 1 * v * dx +# f += Trace(tau.Trace()) * ds("bottom") f.Assemble() u = GridFunction(X) diff -Nru ngsolve-6.2.2102/py_tutorials/hdivdiv/tdnns.py ngsolve-6.2.2103/py_tutorials/hdivdiv/tdnns.py --- ngsolve-6.2.2102/py_tutorials/hdivdiv/tdnns.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/hdivdiv/tdnns.py 2021-06-04 23:31:19.000000000 +0000 @@ -16,7 +16,7 @@ order = 3 V = HDivDiv(mesh, order=order-1, dirichlet="bottom|right|top", plus = True) Q = HCurl(mesh, order=order, dirichlet="left", type1 = True) -X = FESpace([V,Q]) +X = V*Q print ("ndof-V:", V.ndof, ", ndof-Q:", Q.ndof) @@ -28,12 +28,12 @@ def tang(u): return u-(u*n)*n a = BilinearForm(X, symmetric=True) -a += SymbolicBFI ( InnerProduct (sigma, tau) + div(sigma)*v + div(tau)*u - 1e-10 * u*v ) -a += SymbolicBFI ( -(sigma*n) * tang(v) - (tau*n)*tang(u), element_boundary=True) +a += (InnerProduct (sigma, tau) + div(sigma)*v + div(tau)*u - 1e-10 * u*v)*dx +a += (-(sigma*n) * tang(v) - (tau*n)*tang(u))*dx(element_boundary=True) a.Assemble() f = LinearForm(X) -f += SymbolicLFI ( 1 * v[1] ) +f += 1 * v[1] * dx f.Assemble() u = GridFunction(X) diff -Nru ngsolve-6.2.2102/py_tutorials/hybrid_dg.py ngsolve-6.2.2103/py_tutorials/hybrid_dg.py --- ngsolve-6.2.2102/py_tutorials/hybrid_dg.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/hybrid_dg.py 2021-06-04 23:31:19.000000000 +0000 @@ -10,24 +10,22 @@ order = 3 fes1 = L2(mesh, order=order) -fes2 = FacetFESpace(mesh, order=order, dirichlet=[1,2,3]) +fes2 = FacetFESpace(mesh, order=order, dirichlet="bottom|right|top") print ("element dofs: ", fes1.ndof) print ("facet dofs: ", fes2.ndof) -fes = FESpace([fes1,fes2]) +fes = fes1*fes2 u,uhat = fes.TrialFunction() v,vhat = fes.TestFunction() -grad_u = u.Deriv() -grad_v = v.Deriv() n = specialcf.normal(mesh.dim) h = specialcf.mesh_size -a = BilinearForm(fes, symmetric=True, eliminate_internal = True) -a += SymbolicBFI(grad(u) * grad(v)) -a += SymbolicBFI(grad(u)*n*(vhat-v)+grad(v)*n*(uhat-u)+10*order*order/h*(u-uhat)*(v-vhat), element_boundary=True) +a = BilinearForm(fes, symmetric=True, condense = True) +a += grad(u) * grad(v) * dx +a += (grad(u)*n*(vhat-v)+grad(v)*n*(uhat-u)+10*order*order/h*(u-uhat)*(v-vhat))*dx(element_boundary=True) c = Preconditioner(type="direct", bf=a, inverse = "sparsecholesky") # c = Preconditioner(type="bddc", bf=a) @@ -37,7 +35,7 @@ ainv = CGSolver(a.mat, c.mat) f = LinearForm(fes) -f += SymbolicLFI(1*v) +f += 1*v*dx f.Assemble() u = GridFunction(fes) diff -Nru ngsolve-6.2.2102/py_tutorials/hybrid_mixed.py ngsolve-6.2.2103/py_tutorials/hybrid_mixed.py --- ngsolve-6.2.2102/py_tutorials/hybrid_mixed.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/hybrid_mixed.py 2021-06-04 23:31:19.000000000 +0000 @@ -10,18 +10,18 @@ order = 2 fes1 = HDiv(mesh, order=order, discontinuous=True) fes2 = L2(mesh, order=order-1) -fes3 = FacetFESpace(mesh, order=order, dirichlet=[1,2,3]) +fes3 = FacetFESpace(mesh, order=order, dirichlet="top|bottom|right") -fes = FESpace([fes1,fes2,fes3]) +fes = fes1*fes2*fes3 sigma,u,uhat = fes.TrialFunction() tau,v,vhat = fes.TestFunction() n = specialcf.normal(mesh.dim) -a = BilinearForm(fes, symmetric=False, eliminate_internal = True) -a += SymbolicBFI(sigma*tau + div(sigma)*v + div(tau)*u) -a += SymbolicBFI(sigma*n*vhat+tau*n*uhat, element_boundary=True) +a = BilinearForm(fes, symmetric=False, condense = True) +a += (sigma*tau + div(sigma)*v + div(tau)*u)*dx +a += (sigma*n*vhat+tau*n*uhat)*dx(element_boundary=True) # c = Preconditioner(type="direct", bf=a, inverse = sparsecholesky) # c = Preconditioner(type="direct", bf=a, inverse = pardiso) @@ -32,7 +32,7 @@ a.Assemble() f = LinearForm(fes) -f += SymbolicLFI(-1*v) +f += -1*v*dx f.Assemble() u = GridFunction(fes) diff -Nru ngsolve-6.2.2102/py_tutorials/mixed.py ngsolve-6.2.2103/py_tutorials/mixed.py --- ngsolve-6.2.2102/py_tutorials/mixed.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/mixed.py 2021-06-04 23:31:19.000000000 +0000 @@ -9,18 +9,18 @@ fes1 = HDiv(mesh, order=order) fes2 = L2(mesh, order=order-1) -fes = FESpace([fes1,fes2]) +fes = fes1*fes2 sigma,u = fes.TrialFunction() tau,v = fes.TestFunction() a = BilinearForm(fes) -a += SymbolicBFI(sigma*tau + div(sigma)*v + div(tau)*u - 1e-10*u*v) +a += (sigma*tau + div(sigma)*v + div(tau)*u - 1e-10*u*v)*dx # (regularization needed for direct solver) a.Assemble() f = LinearForm(fes) -f += SymbolicLFI(-v) +f += -v*dx f.Assemble() u = GridFunction(fes) diff -Nru ngsolve-6.2.2102/py_tutorials/navierstokes.py ngsolve-6.2.2103/py_tutorials/navierstokes.py --- ngsolve-6.2.2102/py_tutorials/navierstokes.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/navierstokes.py 2021-06-04 23:31:19.000000000 +0000 @@ -18,13 +18,13 @@ V = VectorH1(mesh,order=3, dirichlet="wall|cyl|inlet") Q = H1(mesh,order=2) -X = FESpace([V,Q]) +X = V*Q u,p = X.TrialFunction() v,q = X.TestFunction() stokes = nu*InnerProduct(grad(u), grad(v))+div(u)*q+div(v)*p - 1e-10*p*q -a = BilinearForm(X) +a = BilinearForm(X, symmetric=True) a += stokes*dx a.Assemble() @@ -48,8 +48,8 @@ # matrix for implicit Euler -mstar = BilinearForm(X) -mstar += SymbolicBFI(u*v + tau*stokes) +mstar = BilinearForm(X, symmetric=True) +mstar += (u*v + tau*stokes)*dx mstar.Assemble() inv = mstar.mat.Inverse(X.FreeDofs(), inverse="sparsecholesky") diff -Nru ngsolve-6.2.2102/py_tutorials/nonlin.py ngsolve-6.2.2103/py_tutorials/nonlin.py --- ngsolve-6.2.2102/py_tutorials/nonlin.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/nonlin.py 2021-06-04 23:31:19.000000000 +0000 @@ -3,12 +3,12 @@ m = Mesh (unit_square.GenerateMesh(maxh=0.3)) -V = H1(m, order=3, dirichlet=[1,2,3,4]) +V = H1(m, order=3, dirichlet="left|right|top|bottom") u = V.TrialFunction() v = V.TestFunction() a = BilinearForm(V) -a += SymbolicBFI( grad(u) * grad(v) + 5*u*u*v- 1 * v) +a += ( grad(u) * grad(v) + 5*u*u*v- 1 * v)*dx u = GridFunction(V) r = u.vec.CreateVector() diff -Nru ngsolve-6.2.2102/py_tutorials/pml.py ngsolve-6.2.2103/py_tutorials/pml.py --- ngsolve-6.2.2102/py_tutorials/pml.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/pml.py 2021-06-04 23:31:19.000000000 +0000 @@ -17,10 +17,10 @@ omega = 10 a = BilinearForm(fes) -a += SymbolicBFI(grad(u)*grad(v)-omega*omega*u*v) +a += (grad(u)*grad(v)-omega*omega*u*v)*dx f = LinearForm(fes) -f += SymbolicLFI(exp(-20**2*((x-0.3)*(x-0.3)+y*y))*v) +f += exp(-20**2*((x-0.3)*(x-0.3)+y*y))*v*dx a.Assemble() f.Assemble() diff -Nru ngsolve-6.2.2102/py_tutorials/poisson.ipynb ngsolve-6.2.2103/py_tutorials/poisson.ipynb --- ngsolve-6.2.2102/py_tutorials/poisson.ipynb 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/poisson.ipynb 2021-06-04 23:31:19.000000000 +0000 @@ -18,9 +18,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "from ngsolve import *\n", @@ -39,9 +37,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))\n", @@ -82,10 +78,10 @@ "v = fes.TestFunction()\n", "\n", "f = LinearForm(fes)\n", - "f += SymbolicLFI(32 * (y*(1-y)+x*(1-x)) * v)\n", + "f += 32 * (y*(1-y)+x*(1-x)) * v * dx\n", "\n", "a = BilinearForm(fes)\n", - "a += SymbolicBFI(grad(u)*grad(v))\n", + "a += grad(u)*grad(v)*dx\n", "\n", "a.Assemble()\n", "f.Assemble()" @@ -118,9 +114,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "Draw (gfu)\n", @@ -140,18 +134,14 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [] } @@ -172,7 +162,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.2" + "version": "3.8.5" } }, "nbformat": 4, diff -Nru ngsolve-6.2.2102/py_tutorials/scattering.py ngsolve-6.2.2103/py_tutorials/scattering.py --- ngsolve-6.2.2102/py_tutorials/scattering.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/scattering.py 2021-06-04 23:31:19.000000000 +0000 @@ -27,8 +27,8 @@ uscat.Set (uin, definedon=mesh.Boundaries("scatterer")) a = BilinearForm (fes, symmetric=True) -a += SymbolicBFI (grad(u)*grad(v) ) -a += SymbolicBFI (-k*k*u*v) +a += grad(u)*grad(v)*dx +a += -k*k*u*v*dx f = LinearForm (fes) diff -Nru ngsolve-6.2.2102/py_tutorials/symbolic_energy.py ngsolve-6.2.2103/py_tutorials/symbolic_energy.py --- ngsolve-6.2.2102/py_tutorials/symbolic_energy.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/symbolic_energy.py 2021-06-04 23:31:19.000000000 +0000 @@ -4,12 +4,12 @@ mesh = Mesh (unit_square.GenerateMesh(maxh=0.2)) -V = H1(mesh, order=4, dirichlet=[1,2,3,4]) +V = H1(mesh, order=4, dirichlet="left|right|top|bottom") u = V.TrialFunction() a = BilinearForm (V, symmetric=False) -a += SymbolicEnergy (0.05*grad(u)*grad(u) + u*u*u*u - 100*u) +a += Variation( (0.05*grad(u)*grad(u) + u*u*u*u - 100*u)*dx ) u = GridFunction (V) u.vec[:] = 0 diff -Nru ngsolve-6.2.2102/py_tutorials/symbolic.py ngsolve-6.2.2103/py_tutorials/symbolic.py --- ngsolve-6.2.2102/py_tutorials/symbolic.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/symbolic.py 2021-06-04 23:31:19.000000000 +0000 @@ -12,19 +12,19 @@ u = V.TrialFunction() v = V.TestFunction() -gradu = u.Deriv() -gradv = v.Deriv() +gradu = Grad(u) +gradv = Grad(v) dvdx = gradv[0] dvdy = gradv[1] dvdz = gradv[2] a = BilinearForm (V, symmetric=True) -a += SymbolicBFI (u*v+gradu*gradv) -a.Assemble(heapsize=10000000) +a += (u*v+gradu*gradv)*dx +a.Assemble() f = LinearForm (V) -f += SymbolicLFI (x*v) +f += x*v*dx f.Assemble() print (a.mat) diff -Nru ngsolve-6.2.2102/py_tutorials/timeDGlap.py ngsolve-6.2.2103/py_tutorials/timeDGlap.py --- ngsolve-6.2.2102/py_tutorials/timeDGlap.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/py_tutorials/timeDGlap.py 2021-06-04 23:31:19.000000000 +0000 @@ -53,16 +53,16 @@ cf2 = -0.5 * InnerProduct(grad(v), n)*(u-u.Other(bnd=0)) cf3 = 2 * ( (order+1)**2)/h * (u-u.Other(bnd=0)) * v -a += SymbolicBFI ( grad(u) * grad(v) ) -a += SymbolicBFI ( cf1+cf2+cf3,VOL, element_boundary=True) -a += SymbolicBFI ( -cf1-cf2-cf3,BND, skeleton=True) -#a += SymbolicBFI ( -cf1-cf2-cf3, skeleton=True,definedon=mesh.Boundaries("top|bottom")) -#a += SymbolicBFI( h*u*v ) +a += grad(u) * grad(v) * dx +a += (cf1+cf2+cf3)*dx(element_boundary=True) +a += (-cf1-cf2-cf3)*ds(skeleton=True) +#a += (-cf1-cf2-cf3)*ds("top|bottom", skeleton=True) +#a += h*u*v*dx l = LinearForm(fes) -l += SymbolicLFI ( 8.0*pi*pi*uex*v ) # volume force -#l += SymbolicLFI ( 1e-1*uex*v,skeleton=True,definedon=mesh.Boundaries("left")) # dirichlet data -l += SymbolicLFI ( n*grad(uex)*v,BND,skeleton=True) # neumann data +l += 8.0*pi*pi*uex*v*dx # volume force +#l += 1e-1*uex*v*ds("left",skeleton=True) # dirichlet data +l += n*grad(uex)*v*ds(skeleton=True) # neumann data diff = GridFunction(fes) ddiff = GridFunction(fes) diff -Nru ngsolve-6.2.2102/solve/ngsolve.cpp ngsolve-6.2.2103/solve/ngsolve.cpp --- ngsolve-6.2.2102/solve/ngsolve.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/solve/ngsolve.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -217,6 +217,11 @@ { return GetLibraryVersions().at(library); } using Archive::operator&; + virtual Archive & operator & (float & f) + { + sock.Tsend(f); + return *this; + } virtual Archive & operator & (double & d) { sock.Tsend(d); @@ -276,6 +281,11 @@ { return vinfo[library]; } using Archive::operator&; + virtual Archive & operator & (float & f) + { + sock.Trecv (f); + return *this; + } virtual Archive & operator & (double & d) { sock.Trecv (d); @@ -335,6 +345,10 @@ public: WorkerOutArchive () : Archive(true) { ; } + virtual Archive & operator & (float & f) + { + return *this; + } virtual Archive & operator & (double & d) { return *this; diff -Nru ngsolve-6.2.2102/tests/catch/finiteelement.cpp ngsolve-6.2.2103/tests/catch/finiteelement.cpp --- ngsolve-6.2.2102/tests/catch/finiteelement.cpp 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/tests/catch/finiteelement.cpp 2021-06-04 23:31:19.000000000 +0000 @@ -28,7 +28,7 @@ T_ScalarFiniteElement< L2HighOrderFE_Shape, ET, - DGFiniteElement::DIM> + DGFiniteElement > >; diff -Nru ngsolve-6.2.2102/tests/gitlab-ci/conda/ngsolve/build.sh ngsolve-6.2.2103/tests/gitlab-ci/conda/ngsolve/build.sh --- ngsolve-6.2.2102/tests/gitlab-ci/conda/ngsolve/build.sh 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/tests/gitlab-ci/conda/ngsolve/build.sh 2021-06-04 23:31:19.000000000 +0000 @@ -36,7 +36,6 @@ -DLAPACK_LIBRARIES=${PREFIX}/lib/libmkl_rt.${SHARED_EXT} \ -DUSE_UMFPACK=OFF \ -DBUILD_STUB_FILES=OFF \ - -DBUILD_JUPYTER_WIDGETS=ON \ ${SRC_DIR} make -j$CPU_COUNT diff -Nru ngsolve-6.2.2102/tests/gitlab-ci/ubuntu/build_in_docker.sh ngsolve-6.2.2103/tests/gitlab-ci/ubuntu/build_in_docker.sh --- ngsolve-6.2.2102/tests/gitlab-ci/ubuntu/build_in_docker.sh 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/tests/gitlab-ci/ubuntu/build_in_docker.sh 2021-06-04 23:31:19.000000000 +0000 @@ -38,6 +38,39 @@ cd mkdir -p build/ngsolve cd build/ngsolve + +pip3 install numpy scipy matplotlib + +if [ "$IMAGE_NAME" == "avx" ] +then + apt-get upgrade -y + apt-get install -y software-properties-common + add-apt-repository -y ppa:saiarcot895/chromium-beta + apt-get update + apt-get install -y rsync chromium-browser chromium-chromedriver + ln -s /usr/lib/chromium-browser/chromedriver /usr/local/bin/chromedriver + + pip3 install \ + sphinx \ + sphinx_rtd_theme \ + ipython \ + nbsphinx \ + jupyter \ + jupyter-client \ + nbstripout \ + ipykernel \ + widgetsnbextension \ + ipyparallel \ + selenium \ + webgui_jupyter_widgets \ + pybind11-stubgen==0.5 \ + docutils==0.16 \ + Jinja2==2.11.3 \ + +fi + +pip3 freeze > /logs/pip_freeze.log + cmake ../../src/ngsolve \ -DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS" \ -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \ @@ -62,23 +95,17 @@ if [ "$IMAGE_NAME" == "avx" ] then ## build and upload docu to server - apt install -y software-properties-common - add-apt-repository -y ppa:saiarcot895/chromium-beta - apt update - apt-get install -y rsync chromium-browser chromium-chromedriver - ln -s /usr/lib/chromium-browser/chromedriver /usr/local/bin/chromedriver export NGS_NUM_THREADS=4 echo "build docu" - pip3 install --upgrade jupyter widgetsnbextension ipyparallel selenium ipython profile create --parallel --profile=mpi echo 'c.MPILauncher.mpi_args = ["--allow-run-as-root"]' >> ~/.ipython/profile_mpi/ipcluster_config.py jupyter nbextension install --py widgetsnbextension jupyter nbextension enable --py widgetsnbextension - jupyter nbextension install --py ngsolve - jupyter nbextension enable --py ngsolve - make docs > out + jupyter nbextension install --py webgui_jupyter_widgets + jupyter nbextension enable --py webgui_jupyter_widgets + make docs > /logs/build_docs.log 2>&1 find ~/src/ngsolve/docs/i-tutorials -name '*.ipynb' -print0 | xargs -0 nbstripout cp -r ~/src/ngsolve/docs/i-tutorials docs/html/jupyter-files zip -r docs/html/i-tutorials.zip docs/html/jupyter-files diff -Nru ngsolve-6.2.2102/tests/gitlab-ci/ubuntu/build.sh ngsolve-6.2.2103/tests/gitlab-ci/ubuntu/build.sh --- ngsolve-6.2.2102/tests/gitlab-ci/ubuntu/build.sh 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/tests/gitlab-ci/ubuntu/build.sh 2021-06-04 23:31:19.000000000 +0000 @@ -3,6 +3,8 @@ rm -f ngsolve_${CI_PIPELINE_ID}_${IMAGE_NAME}.id +mkdir logs + docker run \ --cidfile ngsolve_${CI_PIPELINE_ID}_${IMAGE_NAME}.id \ -e MKLROOT=/opt/intel/mkl \ @@ -17,6 +19,7 @@ -e LD_LIBRARY_PATH=/opt/intel/mkl/lib/intel64 \ -e RUN_SLOW_TESTS="$RUN_SLOW_TESTS" \ -v /opt/intel:/opt/intel \ + -v `pwd`/logs:/logs \ -v /mnt/ccache:/ccache ngsolve_${CI_PIPELINE_ID}:${IMAGE_NAME} \ bash /root/src/ngsolve/tests/gitlab-ci/ubuntu/build_in_docker.sh diff -Nru ngsolve-6.2.2102/tests/gitlab-ci/ubuntu/docker_template ngsolve-6.2.2103/tests/gitlab-ci/ubuntu/docker_template --- ngsolve-6.2.2102/tests/gitlab-ci/ubuntu/docker_template 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/tests/gitlab-ci/ubuntu/docker_template 2021-06-04 23:31:19.000000000 +0000 @@ -5,8 +5,6 @@ RUN apt-get update && apt-get -y install libxmu-dev tk-dev tcl-dev cmake git g++ libglu1-mesa-dev ccache openssh-client RUN apt-get update && apt-get -y install python3 libpython3-dev python3-pytest python3-numpy python3-pip RUN apt-get update && apt-get -y install liboce-ocaf-dev libsuitesparse-dev python3-tk pandoc zip libcgns-dev libhdf5-dev -RUN pip3 install --upgrade sphinx sphinx_rtd_theme ipython nbsphinx jupyter-client nbstripout ipykernel numpy scipy matplotlib -RUN pip3 install pybind11-stubgen==0.5 ENV PATH="/opt/netgen/bin:${PATH}" ADD . /root/src/ngsolve diff -Nru ngsolve-6.2.2102/tests/pytest/test_code_generation.py ngsolve-6.2.2103/tests/pytest/test_code_generation.py --- ngsolve-6.2.2102/tests/pytest/test_code_generation.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/tests/pytest/test_code_generation.py 2021-06-04 23:31:19.000000000 +0000 @@ -8,8 +8,11 @@ fes = L2(unit_mesh_3d, order=5) gfu = GridFunction(fes) + cfvec = CF((1,)*10) + cf10 = InnerProduct(cfvec, cfvec) + # piecewise polynomials - also test interpolation on L2 space and the resulting GridFunction - functions = [x,y,x*y, specialcf.mesh_size, CoefficientFunction((x,y)).Norm()**2] + functions = [x,y,x*y, specialcf.mesh_size, CoefficientFunction((x,y)).Norm()**2, Id(3)[:,2][2], cf10][-1:] for cf in functions: gfu.Set(cf) @@ -19,11 +22,12 @@ for f in cfs: assert Integrate( (cf-f)*(cf-f), unit_mesh_3d) == approx(0) - functions = [sin(x)*y, exp(x)+y*y*y, (1+x)**(1+y)] + cf8x8 = CoefficientFunction( tuple(range(8*8)), dims=(8,8) ) + functions = [sin(x)*y, exp(x)+y*y*y, (1+x)**(1+y), cf8x8[1::3, 2:6], cf8x8[:,3], cf8x8[:,1:8:2]] for cf in functions: cfs = [ cf.Compile(), cf.Compile(True, wait=True)] for f in cfs: - assert Integrate( (cf-f)*(cf-f), unit_mesh_3d) == approx(0) + assert Integrate( Norm(cf-f), unit_mesh_3d) == approx(0) cf = atan2(1+x,1+y) cfs = [ cf.Compile(), cf.Compile(True, wait=True, maxderiv=0)] @@ -81,6 +85,20 @@ vals -= vals_ref assert Norm(vals) == approx(0) +def test_code_generation_python_module(unit_mesh_3d): + from ngsolve.fem import CompilePythonModule + + m = CompilePythonModule(""" + m.def("mysquare", [](double x) {return x*x;}); + m.def("refine", [](shared_ptr ma) { ma->Refine(false); }); + """) + + assert m.mysquare(10) == 10*10 + ne_before = unit_mesh_3d.ne + m.refine(unit_mesh_3d) + ne_after = unit_mesh_3d.ne + assert 8*ne_before==ne_after + if __name__ == "__main__": test_code_generation_derivatives() test_code_generation_volume_terms() diff -Nru ngsolve-6.2.2102/tests/pytest/test_newton_cf.py ngsolve-6.2.2103/tests/pytest/test_newton_cf.py --- ngsolve-6.2.2102/tests/pytest/test_newton_cf.py 1970-01-01 00:00:00.000000000 +0000 +++ ngsolve-6.2.2103/tests/pytest/test_newton_cf.py 2021-06-04 23:31:19.000000000 +0000 @@ -0,0 +1,352 @@ +#!/usr/bin/env python +# coding: utf-8 + +import numpy as np +from ngsolve import * +from ngsolve.comp import IntegrationRuleSpace +from ngsolve.fem import MinimizationCF, NewtonCF +from netgen.csg import * +import netgen + +import pytest + + +@pytest.fixture +def fes_ir(): + # 'minimal' mesh + m = netgen.meshing.Mesh(dim=1) + + N = 1 + pnums = [] + for i in range(0, N+1): + pnums.append(m.Add (netgen.meshing.MeshPoint (Pnt(2*i/N, 0, 0)))) + + idx = m.AddRegion("material", dim=1) + for i in range(0,N): + m.Add(netgen.meshing.Element1D ([pnums[i],pnums[i+1]], index=idx)) + + idx_left = m.AddRegion("left", dim=0) + idx_right = m.AddRegion("right", dim=0) + + m.Add(netgen.meshing.Element0D(pnums[0], index=idx_left)) + m.Add(netgen.meshing.Element0D(pnums[N], index=idx_right)) + + mesh = Mesh(m) + + int_order = 0 + + fes_ir = IntegrationRuleSpace(mesh, order=int_order) + return fes_ir + + +def test_scalar_linear_minimization(fes_ir): + u = GridFunction(fes_ir) + du = fes_ir.TrialFunction() + + pot = du**2 - du/2 + eq = 2*du - 1/2 + + expected = np.array([1/4]) + + u.Interpolate(CoefficientFunction(3)) + ncf = NewtonCF(eq, u) + u.Interpolate(ncf) + assert np.allclose(u.vec.FV().NumPy(), expected, atol=1e-14, rtol=0) + + u.Interpolate(CoefficientFunction(3)) + mcf = MinimizationCF(pot, u) + u.Interpolate(mcf) + assert np.allclose(u.vec.FV().NumPy(), expected, atol=1e-14, rtol=0) + + +def test_scalar_nonlinear_minimization(fes_ir): + u = GridFunction(fes_ir) + du = fes_ir.TrialFunction() + + pot = du**3 - du**2/2 + eq = 3*du**2 - du + + expected = np.array([1/3]) + + u.Interpolate(CoefficientFunction(3)) + ncf = NewtonCF(eq, u) + u.Interpolate(ncf) + assert np.allclose(u.vec.FV().NumPy(), expected, atol=1e-10, rtol=0) + + u.Interpolate(CoefficientFunction(3)) + mcf = MinimizationCF(pot, u) + u.Interpolate(mcf) + assert np.allclose(u.vec.FV().NumPy(), expected, atol=1e-10, rtol=0) + + +def test_2d_compound_minimization(fes_ir): + fes = fes_ir * fes_ir + fes_vec = fes_ir**2 + u = GridFunction(fes) + du1, du2 = fes.TrialFunction() + + uvec = GridFunction(fes_vec) + duvec = fes_vec.TrialFunction() + + du = CoefficientFunction((du1, du2)) + a = CoefficientFunction((2/3, 1)) + M = CoefficientFunction((2, 1/2, 1/2, 4), dims=(2, 2)) + + def pot_func(u): + return 1/2 * InnerProduct(M, OuterProduct(u, u)) + 4 * InnerProduct(u, a) + + def res_func(u): + return M * u + 4 * a + + eq = res_func(du) + eq_vec = res_func(duvec) + check = res_func(uvec) + pot = pot_func(duvec) + + expected = np.array([-1.11827957, -0.86021505]) + + u.Interpolate(CoefficientFunction((3, 3))) + uvec.Interpolate(CoefficientFunction((3, 3))) + ncf = NewtonCF(eq, u, maxiter=1) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + u.Interpolate(CoefficientFunction((3, 3))) + uvec.Interpolate(CoefficientFunction((3, 3))) + ncf = NewtonCF(eq, u.components, maxiter=1) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + uvec.Interpolate(CoefficientFunction((3, 3))) + ncf = NewtonCF(eq_vec, uvec, maxiter=1) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + uvec.Interpolate(CoefficientFunction((3, 3))) + mcf = MinimizationCF(pot, uvec, maxiter=1) + uvec.Interpolate(mcf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + uvec2 = GridFunction(uvec.space) + uvec2.Interpolate(check) + assert np.allclose(uvec2.vec.FV().NumPy(), 0) + + +def test_2d_compound_linear_nonsymmetric(fes_ir): + fes = fes_ir * fes_ir + u = GridFunction(fes) + du1, du2 = fes.TrialFunction() + + fes_vec = fes_ir**2 + uvec = GridFunction(fes_vec) + duvec = fes_vec.TrialFunction() + + du = CoefficientFunction((du1, du2)) + a = CoefficientFunction((2/3, 1)) + M = CoefficientFunction((2, 1/2, 1, 4), dims=(2, 2)) + + def res_func(u): + return InnerProduct(M, OuterProduct(u, u)) * (u + a) + 4 * a + + eq = res_func(du) + eq_vec = res_func(duvec) + check = res_func(uvec) + + expected = np.array([-0.90980601, -1.36470902]) + + u.Interpolate(CoefficientFunction((-1, -1))) + ncf = NewtonCF(eq, u) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + uvec.Interpolate(CoefficientFunction((-1, -1))) + ncf = NewtonCF(eq_vec, uvec) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + uvec2 = GridFunction(uvec.space) + uvec2.Interpolate(check) + assert np.allclose(uvec2.vec.FV().NumPy(), 0) + + +def test_compound_advanced_linear_nonsymmetric(fes_ir): + fes_M = MatrixValued(fes_ir, dim=3, symmetric=True) + fes_compound = fes_ir * fes_M * (fes_ir**2) + + u = GridFunction(fes_compound) + u1, u2, u3 = u.components + du1, du2, du3 = fes_compound.TrialFunction() + + fes_vec = fes_ir**12 + uvec = GridFunction(fes_vec) + + cf1 = CoefficientFunction(1/2) + cf2 = CoefficientFunction(tuple(range(1, 10)), dims=(3, 3)) + cf3 = CoefficientFunction((2/3, 3/4)) + u1.Interpolate(cf1) + u2.Interpolate(1/2 * (cf2 + cf2.trans)) + u3.Interpolate(cf3) + + a = CoefficientFunction((2/3, 4/9)) + M22 = CoefficientFunction((2, 1/2, + 1/6, 4), dims=(2, 2)) + M33 = CoefficientFunction((2, 1/2, 1/3, + 1/2, 4, 0, + 1/3, 0, 2), dims=(3, 3)) + + # scalar eq component + def res_func_1(u1, u2, u3): + return 4 * u1 + 2 * u2[0, 1] + 5 * u2[1,2] + (M22 * u3) * a + + # matrix eq component + def res_func_2(u1, u2, u3): + return (M33 * u2 + M33 + + CoefficientFunction((M33[0], 0, 0, 0, 0, 0, 0, 0, 0), dims=(3, 3)) + + CoefficientFunction((u1, u3[0], u3[1]/3, + 0, 0, 0, + 0, 0, 0), dims=(3, 3)) + ) + + # vector eq component + def res_func_3(u1, u2, u3): + return a * u1 + M22 * u3 + 2 * a * u3[0] + M22 * a / 2 + M22 * CoefficientFunction((u2[0, 0], u2[2,2])) + + def res_func(u1, u2, u3): + return CoefficientFunction( + (res_func_1(u1, u2, u3), + res_func_2(u1, u2, u3), + res_func_3(u1, u2, u3))) + + eq = res_func(du1, du2, du3) + + uv1 = CoefficientFunction(uvec[0]) + uv2 = CoefficientFunction(tuple([uvec[i] for i in range(1, 10)]), dims=(3,3)) + uv3 = CoefficientFunction(tuple([uvec[i] for i in range(10, 12)])) + check = res_func(uv1, uv2, uv3) + + expected = np.array([-6.32030540e-01, -1.65811403e+00, -1.03161645e-01, -4.81744750e-04, + -1.03161645e-01, -9.87104794e-01, 5.77134791e-03, -4.81744750e-04, + 5.77134791e-03, -9.99919709e-01, 9.39655500e-01, 6.55157652e-01]) + + u1.Interpolate(cf1) + u2.Interpolate(1/2 * (cf2 + cf2.trans)) + u3.Interpolate(cf3) + ncf = NewtonCF(eq, u.components, maxiter=1) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + # different starting point styles + u1.Interpolate(cf1) + u2.Interpolate(1/2 * (cf2 + cf2.trans)) + u3.Interpolate(cf3) + ncf = NewtonCF(eq, u, maxiter=1) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + u1.Interpolate(cf1) + u2.Interpolate(1/2 * (cf2 + cf2.trans)) + u3.Interpolate(cf3) + ncf = NewtonCF(eq, CoefficientFunction((u1, u2, u3)), maxiter=1) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + u1.Interpolate(cf1) + u2.Interpolate(1/2 * (cf2 + cf2.trans)) + u3.Interpolate(cf3) + ncf = NewtonCF(eq, [u1, u2, u3], maxiter=1) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + # Solution check + uvec_check = GridFunction(uvec.space) + uvec_check.Interpolate(check) + nvec = uvec_check.vec.FV().NumPy() + allres = nvec.reshape((12, int(nvec.size/12))).T + # Only the symmetric part of the error for u2 is relevant and indeed vanishes + _res = allres[0][1:10].reshape((3,3)) + assert np.allclose(1/2 * (_res + _res.T), 0) + + +def test_compound_advanced_nonlinear_symmetric(fes_ir): + fes_M = MatrixValued(fes_ir, dim=3, symmetric=True) + fes_compound = fes_ir * fes_M * (fes_ir**2) + + u = GridFunction(fes_compound) + u1, u2, u3 = u.components + du1, du2, du3 = fes_compound.TrialFunction() + + fes_vec = fes_ir**12 + uvec = GridFunction(fes_vec) + + d = CoefficientFunction(3) + a = CoefficientFunction((2/3, 4/9)) + M22 = CoefficientFunction((1/8, 1/5, + 1/5, 3), dims=(2, 2)) + M33 = CoefficientFunction((2, 1/2, 1/3, + 1/2, 4, 1/2, + 1/3, 1/2, 2), dims=(3, 3)) + + wc1 = CoefficientFunction(1) + wc2 = CoefficientFunction(1) + wd = CoefficientFunction(50) + + def pot_func(u1, u2, u3): + return d * (u1**4 + u1**2) + wc1 * u1 * Det(u2) + wd * (sqrt(Det(u2)) - 1)**2 + 10 * InnerProduct(u2, u2) + wc2 * InnerProduct(u3, u3) * Trace(u2) + InnerProduct(u3, M22 * u3) + 2 * u1 + 4 * InnerProduct(M33, u2) + InnerProduct(u3, a) + + def res_func(u1, u2, u3): + return CoefficientFunction(( + 4 * d *u1**3 + 2 * d * u1 + wc1 * Det(u2) + 2, + (wc1 * u1 * Det(u2) + 2 * wd * (sqrt(Det(u2)) - 1) * (1/2 * sqrt(Det(u2)))) * Inv(u2) + + 20 * u2 + wc2 * InnerProduct(u3, u3) * Id(3) + 4 * M33, + 2 * wc2 * Trace(u2) * u3 + 2 * M22 * u3 + a + )) + + pot = pot_func(du1, du2, du3) + res = res_func(du1, du2, du3) + + uv1 = CoefficientFunction(uvec[0]) + uv2 = CoefficientFunction(tuple([uvec[i] for i in range(1, 10)]), dims=(3,3)) + uv3 = CoefficientFunction(tuple([uvec[i] for i in range(10, 12)])) + check_res = res_func(uv1, uv2, uv3) + + expected = np.array([-0.30564104, 0.60862982, -0.03132745, -0.02373416, -0.03132745, + 0.48047082, -0.03132745, -0.02373416, -0.03132745, 0.60862982, + -0.17851929, -0.03970393]) + + u1.Interpolate(CoefficientFunction(0)) + u2.Interpolate(Id(3)) + u3.Interpolate(CoefficientFunction((0, 0))) + mcf = MinimizationCF(pot, u.components) + uvec.Interpolate(mcf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + uvec_check = GridFunction(uvec.space) + uvec_check.Interpolate(check_res) + nvec = uvec_check.vec.FV().NumPy() + allres = nvec.reshape((12, int(nvec.size/12))).T + + assert np.allclose(allres[0][0], 0) + assert np.allclose(allres[0][10:], 0) + # Only the symmetric part of the error for u2 is relevant and indeed vanishes + _res = allres[0][1:10].reshape((3,3)) + assert np.allclose(1/2 * (_res + _res.T), 0) + + u1.Interpolate(CoefficientFunction(0)) + u2.Interpolate(Id(3)) + u3.Interpolate(CoefficientFunction((0, 0))) + ncf = NewtonCF(res, u.components) + uvec.Interpolate(ncf) + assert np.allclose(uvec.vec.FV().NumPy(), expected, atol=1e-8, rtol=0) + + uvec_check = GridFunction(uvec.space) + uvec_check.Interpolate(check_res) + nvec = uvec_check.vec.FV().NumPy() + allres = nvec.reshape((12, int(nvec.size/12))).T + assert np.allclose(allres[0][0], 0) + + assert np.allclose(allres[0][10:], 0) + # Only the symmetric part of the error for u2 is relevant and indeed vanishes + _res = allres[0][1:10].reshape((3,3)) + assert np.allclose(1/2 * (_res + _res.T), 0) + + diff -Nru ngsolve-6.2.2102/tests/pytest/test_solvers.py ngsolve-6.2.2103/tests/pytest/test_solvers.py --- ngsolve-6.2.2102/tests/pytest/test_solvers.py 2021-03-19 06:18:09.000000000 +0000 +++ ngsolve-6.2.2103/tests/pytest/test_solvers.py 2021-06-04 23:31:19.000000000 +0000 @@ -1,6 +1,7 @@ from netgen.geom2d import unit_square from ngsolve import * import pytest +from ngsolve.krylovspace import * def test_arnoldi(): SetHeapSize (10*1000*1000) @@ -54,5 +55,29 @@ newton = solvers.Newton(a, gfu, dirichletvalues=dirichlet.vec) +def test_krylovspace_solvers(): + solvers = [CGSolver, GMResSolver, MinResSolver] # , QMRSolver] + mesh = Mesh(unit_square.GenerateMesh(maxh=0.2)) + fes = H1(mesh, order=4, dirichlet=".*") + u,v = fes.TnT() + f = LinearForm(32 * (y*(1-y)+x*(1-x)) * v * dx).Assemble() + a = BilinearForm(grad(u)*grad(v)*dx) + c = Preconditioner(a, type="bddc") + a.Assemble() + u = GridFunction(fes) + exact = 16*x*(1-x)*y*(1-y) + for solver in solvers: + inv = solver(mat=a.mat, pre=c) + u.vec.data = inv * f.vec + error = sqrt(Integrate((u-exact)*(u-exact), mesh)) + print(solver.name, ": iterations = ", inv.iterations) + print("Error = ", error) + assert inv.iterations < 40 + # p4 should be exact + assert error < 1e-12 + + + if __name__ == "__main__": - test_arnoldi() + # test_arnoldi() + test_krylovspace_solvers() diff -Nru ngsolve-6.2.2102/version.txt ngsolve-6.2.2103/version.txt --- ngsolve-6.2.2102/version.txt 2021-03-19 06:19:17.000000000 +0000 +++ ngsolve-6.2.2103/version.txt 2021-06-04 23:37:12.000000000 +0000 @@ -1 +1 @@ -v6.2.2102-0-g55200cf6 +v6.2.2103-0-g4b57cac9