ngsolve 6.2.2506.post74.dev0__cp314-cp314-macosx_10_15_universal2.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ngsolve might be problematic. Click here for more details.

Files changed (315) hide show
  1. netgen/include/analytic_integrals.hpp +10 -0
  2. netgen/include/arnoldi.hpp +55 -0
  3. netgen/include/bandmatrix.hpp +334 -0
  4. netgen/include/basematrix.hpp +957 -0
  5. netgen/include/basevector.hpp +1268 -0
  6. netgen/include/bdbequations.hpp +2805 -0
  7. netgen/include/bdbintegrator.hpp +1660 -0
  8. netgen/include/bem_diffops.hpp +475 -0
  9. netgen/include/bessel.hpp +1064 -0
  10. netgen/include/bilinearform.hpp +963 -0
  11. netgen/include/bla.hpp +29 -0
  12. netgen/include/blockalloc.hpp +95 -0
  13. netgen/include/blockjacobi.hpp +328 -0
  14. netgen/include/bspline.hpp +116 -0
  15. netgen/include/calcinverse.hpp +141 -0
  16. netgen/include/cg.hpp +368 -0
  17. netgen/include/chebyshev.hpp +44 -0
  18. netgen/include/cholesky.hpp +720 -0
  19. netgen/include/clapack.h +7254 -0
  20. netgen/include/code_generation.hpp +296 -0
  21. netgen/include/coefficient.hpp +2033 -0
  22. netgen/include/coefficient_impl.hpp +19 -0
  23. netgen/include/coefficient_stdmath.hpp +167 -0
  24. netgen/include/commutingAMG.hpp +106 -0
  25. netgen/include/comp.hpp +79 -0
  26. netgen/include/compatibility.hpp +41 -0
  27. netgen/include/complex_wrapper.hpp +73 -0
  28. netgen/include/compressedfespace.hpp +110 -0
  29. netgen/include/contact.hpp +235 -0
  30. netgen/include/diagonalmatrix.hpp +154 -0
  31. netgen/include/differentialoperator.hpp +276 -0
  32. netgen/include/diffop.hpp +1286 -0
  33. netgen/include/diffop_impl.hpp +328 -0
  34. netgen/include/diffopwithfactor.hpp +123 -0
  35. netgen/include/discontinuous.hpp +84 -0
  36. netgen/include/dump.hpp +949 -0
  37. netgen/include/ectypes.hpp +121 -0
  38. netgen/include/eigen.hpp +60 -0
  39. netgen/include/eigensystem.hpp +18 -0
  40. netgen/include/elasticity_equations.hpp +595 -0
  41. netgen/include/elementbyelement.hpp +195 -0
  42. netgen/include/elementtopology.hpp +1760 -0
  43. netgen/include/elementtransformation.hpp +339 -0
  44. netgen/include/evalfunc.hpp +405 -0
  45. netgen/include/expr.hpp +1686 -0
  46. netgen/include/facetfe.hpp +175 -0
  47. netgen/include/facetfespace.hpp +180 -0
  48. netgen/include/facethofe.hpp +111 -0
  49. netgen/include/facetsurffespace.hpp +112 -0
  50. netgen/include/fe_interfaces.hpp +32 -0
  51. netgen/include/fem.hpp +87 -0
  52. netgen/include/fesconvert.hpp +14 -0
  53. netgen/include/fespace.hpp +1449 -0
  54. netgen/include/finiteelement.hpp +286 -0
  55. netgen/include/globalinterfacespace.hpp +77 -0
  56. netgen/include/globalspace.hpp +115 -0
  57. netgen/include/gridfunction.hpp +525 -0
  58. netgen/include/h1amg.hpp +124 -0
  59. netgen/include/h1hofe.hpp +188 -0
  60. netgen/include/h1hofe_impl.hpp +1262 -0
  61. netgen/include/h1hofefo.hpp +148 -0
  62. netgen/include/h1hofefo_impl.hpp +185 -0
  63. netgen/include/h1hofespace.hpp +167 -0
  64. netgen/include/h1lofe.hpp +1240 -0
  65. netgen/include/h1lumping.hpp +41 -0
  66. netgen/include/hcurl_equations.hpp +1381 -0
  67. netgen/include/hcurlcurlfe.hpp +2241 -0
  68. netgen/include/hcurlcurlfespace.hpp +78 -0
  69. netgen/include/hcurlfe.hpp +259 -0
  70. netgen/include/hcurlfe_utils.hpp +107 -0
  71. netgen/include/hcurlhdiv_dshape.hpp +857 -0
  72. netgen/include/hcurlhdivfes.hpp +308 -0
  73. netgen/include/hcurlhofe.hpp +175 -0
  74. netgen/include/hcurlhofe_impl.hpp +1871 -0
  75. netgen/include/hcurlhofespace.hpp +193 -0
  76. netgen/include/hcurllofe.hpp +1146 -0
  77. netgen/include/hdiv_equations.hpp +880 -0
  78. netgen/include/hdivdivfe.hpp +2923 -0
  79. netgen/include/hdivdivsurfacespace.hpp +76 -0
  80. netgen/include/hdivfe.hpp +206 -0
  81. netgen/include/hdivfe_utils.hpp +717 -0
  82. netgen/include/hdivfes.hpp +75 -0
  83. netgen/include/hdivhofe.hpp +447 -0
  84. netgen/include/hdivhofe_impl.hpp +1107 -0
  85. netgen/include/hdivhofefo.hpp +229 -0
  86. netgen/include/hdivhofespace.hpp +177 -0
  87. netgen/include/hdivhosurfacefespace.hpp +106 -0
  88. netgen/include/hdivlofe.hpp +773 -0
  89. netgen/include/hidden.hpp +74 -0
  90. netgen/include/householder.hpp +181 -0
  91. netgen/include/hypre_ams_precond.hpp +123 -0
  92. netgen/include/hypre_precond.hpp +73 -0
  93. netgen/include/integrator.hpp +2012 -0
  94. netgen/include/integratorcf.hpp +253 -0
  95. netgen/include/interpolate.hpp +49 -0
  96. netgen/include/intrule.hpp +2542 -0
  97. netgen/include/intrules_SauterSchwab.hpp +25 -0
  98. netgen/include/irspace.hpp +49 -0
  99. netgen/include/jacobi.hpp +153 -0
  100. netgen/include/kernels.hpp +762 -0
  101. netgen/include/l2hofe.hpp +194 -0
  102. netgen/include/l2hofe_impl.hpp +564 -0
  103. netgen/include/l2hofefo.hpp +542 -0
  104. netgen/include/l2hofespace.hpp +344 -0
  105. netgen/include/la.hpp +38 -0
  106. netgen/include/linearform.hpp +266 -0
  107. netgen/include/matrix.hpp +2140 -0
  108. netgen/include/memusage.hpp +41 -0
  109. netgen/include/meshaccess.hpp +1359 -0
  110. netgen/include/mgpre.hpp +204 -0
  111. netgen/include/mp_coefficient.hpp +145 -0
  112. netgen/include/mptools.hpp +2281 -0
  113. netgen/include/multigrid.hpp +42 -0
  114. netgen/include/multivector.hpp +447 -0
  115. netgen/include/mumpsinverse.hpp +187 -0
  116. netgen/include/mycomplex.hpp +361 -0
  117. netgen/include/ng_lapack.hpp +1661 -0
  118. netgen/include/ngblas.hpp +1232 -0
  119. netgen/include/ngs_defines.hpp +30 -0
  120. netgen/include/ngs_stdcpp_include.hpp +106 -0
  121. netgen/include/ngs_utils.hpp +121 -0
  122. netgen/include/ngsobject.hpp +1019 -0
  123. netgen/include/ngsstream.hpp +113 -0
  124. netgen/include/ngstd.hpp +72 -0
  125. netgen/include/nodalhofe.hpp +96 -0
  126. netgen/include/nodalhofe_impl.hpp +141 -0
  127. netgen/include/normalfacetfe.hpp +223 -0
  128. netgen/include/normalfacetfespace.hpp +98 -0
  129. netgen/include/normalfacetsurfacefespace.hpp +84 -0
  130. netgen/include/order.hpp +251 -0
  131. netgen/include/parallel_matrices.hpp +222 -0
  132. netgen/include/paralleldofs.hpp +340 -0
  133. netgen/include/parallelngs.hpp +23 -0
  134. netgen/include/parallelvector.hpp +269 -0
  135. netgen/include/pardisoinverse.hpp +200 -0
  136. netgen/include/periodic.hpp +129 -0
  137. netgen/include/plateaufespace.hpp +25 -0
  138. netgen/include/pml.hpp +275 -0
  139. netgen/include/pmltrafo.hpp +631 -0
  140. netgen/include/postproc.hpp +142 -0
  141. netgen/include/potentialtools.hpp +22 -0
  142. netgen/include/precomp.hpp +60 -0
  143. netgen/include/preconditioner.hpp +602 -0
  144. netgen/include/prolongation.hpp +377 -0
  145. netgen/include/python_comp.hpp +107 -0
  146. netgen/include/python_fem.hpp +89 -0
  147. netgen/include/python_linalg.hpp +58 -0
  148. netgen/include/python_ngstd.hpp +386 -0
  149. netgen/include/recursive_pol.hpp +4896 -0
  150. netgen/include/recursive_pol_tet.hpp +395 -0
  151. netgen/include/recursive_pol_trig.hpp +492 -0
  152. netgen/include/reorderedfespace.hpp +81 -0
  153. netgen/include/sample_sort.hpp +105 -0
  154. netgen/include/scalarfe.hpp +335 -0
  155. netgen/include/shapefunction_utils.hpp +113 -0
  156. netgen/include/simd_complex.hpp +329 -0
  157. netgen/include/smoother.hpp +253 -0
  158. netgen/include/solve.hpp +89 -0
  159. netgen/include/sparsecholesky.hpp +313 -0
  160. netgen/include/sparsematrix.hpp +1038 -0
  161. netgen/include/sparsematrix_dyn.hpp +90 -0
  162. netgen/include/sparsematrix_impl.hpp +1013 -0
  163. netgen/include/special_matrix.hpp +463 -0
  164. netgen/include/specialelement.hpp +125 -0
  165. netgen/include/statushandler.hpp +33 -0
  166. netgen/include/stringops.hpp +12 -0
  167. netgen/include/superluinverse.hpp +136 -0
  168. netgen/include/symbolicintegrator.hpp +850 -0
  169. netgen/include/symmetricmatrix.hpp +144 -0
  170. netgen/include/tangentialfacetfe.hpp +224 -0
  171. netgen/include/tangentialfacetfespace.hpp +91 -0
  172. netgen/include/tensor.hpp +522 -0
  173. netgen/include/tensorcoefficient.hpp +446 -0
  174. netgen/include/tensorproductintegrator.hpp +113 -0
  175. netgen/include/thcurlfe.hpp +128 -0
  176. netgen/include/thcurlfe_impl.hpp +380 -0
  177. netgen/include/thdivfe.hpp +80 -0
  178. netgen/include/thdivfe_impl.hpp +492 -0
  179. netgen/include/tpdiffop.hpp +461 -0
  180. netgen/include/tpfes.hpp +133 -0
  181. netgen/include/tpintrule.hpp +224 -0
  182. netgen/include/triangular.hpp +465 -0
  183. netgen/include/tscalarfe.hpp +245 -0
  184. netgen/include/tscalarfe_impl.hpp +1029 -0
  185. netgen/include/umfpackinverse.hpp +148 -0
  186. netgen/include/vector.hpp +1273 -0
  187. netgen/include/voxelcoefficientfunction.hpp +41 -0
  188. netgen/include/vtkoutput.hpp +198 -0
  189. netgen/include/vvector.hpp +208 -0
  190. netgen/include/webgui.hpp +92 -0
  191. netgen/libngbla.dylib +0 -0
  192. netgen/libngcomp.dylib +0 -0
  193. netgen/libngfem.dylib +0 -0
  194. netgen/libngla.dylib +0 -0
  195. netgen/libngsbem.dylib +0 -0
  196. netgen/libngsolve.dylib +0 -0
  197. netgen/libngstd.dylib +0 -0
  198. ngsolve/TensorProductTools.py +210 -0
  199. ngsolve/__console.py +94 -0
  200. ngsolve/__expr.py +181 -0
  201. ngsolve/__init__.py +148 -0
  202. ngsolve/__init__.pyi +233 -0
  203. ngsolve/_scikit_build_core_dependencies.py +30 -0
  204. ngsolve/bla.pyi +1153 -0
  205. ngsolve/bvp.py +78 -0
  206. ngsolve/bvp.pyi +32 -0
  207. ngsolve/cmake/NGSolveConfig.cmake +102 -0
  208. ngsolve/cmake/ngsolve-targets-release.cmake +79 -0
  209. ngsolve/cmake/ngsolve-targets.cmake +163 -0
  210. ngsolve/comp/__init__.pyi +5449 -0
  211. ngsolve/comp/pml.pyi +89 -0
  212. ngsolve/config/__init__.py +1 -0
  213. ngsolve/config/__init__.pyi +43 -0
  214. ngsolve/config/__main__.py +4 -0
  215. ngsolve/config/config.py +60 -0
  216. ngsolve/config/config.pyi +45 -0
  217. ngsolve/demos/TensorProduct/__init__.py +0 -0
  218. ngsolve/demos/TensorProduct/tp_dg_1d_1d.py +80 -0
  219. ngsolve/demos/TensorProduct/tp_dg_1d_2d.py +73 -0
  220. ngsolve/demos/TensorProduct/tp_dg_2d_1d.py +72 -0
  221. ngsolve/demos/TensorProduct/tp_dg_2d_2d.py +66 -0
  222. ngsolve/demos/__init__.py +0 -0
  223. ngsolve/demos/howto/__init__.py +0 -0
  224. ngsolve/demos/howto/hhj.py +44 -0
  225. ngsolve/demos/howto/hybrid_dg.py +53 -0
  226. ngsolve/demos/howto/mixed.py +30 -0
  227. ngsolve/demos/howto/nonlin.py +29 -0
  228. ngsolve/demos/howto/pickling.py +26 -0
  229. ngsolve/demos/howto/pml.py +31 -0
  230. ngsolve/demos/howto/taskmanager.py +20 -0
  231. ngsolve/demos/howto/tdnns.py +47 -0
  232. ngsolve/demos/howto/timeDG-skeleton.py +45 -0
  233. ngsolve/demos/howto/timeDG.py +38 -0
  234. ngsolve/demos/howto/timeDGlap.py +42 -0
  235. ngsolve/demos/howto/timeDGwave.py +61 -0
  236. ngsolve/demos/intro/__init__.py +0 -0
  237. ngsolve/demos/intro/adaptive.py +123 -0
  238. ngsolve/demos/intro/cmagnet.py +59 -0
  239. ngsolve/demos/intro/elasticity.py +76 -0
  240. ngsolve/demos/intro/navierstokes.py +74 -0
  241. ngsolve/demos/intro/poisson.ipynb +170 -0
  242. ngsolve/demos/intro/poisson.py +41 -0
  243. ngsolve/demos/mpi/__init__.py +0 -0
  244. ngsolve/demos/mpi/mpi_cmagnet.py +87 -0
  245. ngsolve/demos/mpi/mpi_navierstokes.py +117 -0
  246. ngsolve/demos/mpi/mpi_poisson.py +89 -0
  247. ngsolve/demos/mpi/mpi_timeDG.py +82 -0
  248. ngsolve/directsolvers.py +26 -0
  249. ngsolve/directsolvers.pyi +15 -0
  250. ngsolve/eigenvalues.py +364 -0
  251. ngsolve/eigenvalues.pyi +30 -0
  252. ngsolve/fem.pyi +1647 -0
  253. ngsolve/internal.py +89 -0
  254. ngsolve/krylovspace.py +1013 -0
  255. ngsolve/krylovspace.pyi +298 -0
  256. ngsolve/la.pyi +1230 -0
  257. ngsolve/meshes.py +748 -0
  258. ngsolve/ngs2petsc.py +310 -0
  259. ngsolve/ngscxx.py +42 -0
  260. ngsolve/ngslib.so +0 -0
  261. ngsolve/ngstd.pyi +59 -0
  262. ngsolve/nonlinearsolvers.py +203 -0
  263. ngsolve/nonlinearsolvers.pyi +95 -0
  264. ngsolve/preconditioners.py +11 -0
  265. ngsolve/preconditioners.pyi +7 -0
  266. ngsolve/solve.pyi +109 -0
  267. ngsolve/solve_implementation.py +168 -0
  268. ngsolve/solve_implementation.pyi +42 -0
  269. ngsolve/solvers.py +7 -0
  270. ngsolve/solvers.pyi +14 -0
  271. ngsolve/timestepping.py +185 -0
  272. ngsolve/timestepping.pyi +28 -0
  273. ngsolve/timing.py +108 -0
  274. ngsolve/timing.pyi +54 -0
  275. ngsolve/utils.py +167 -0
  276. ngsolve/utils.pyi +273 -0
  277. ngsolve/webgui.py +670 -0
  278. ngsolve-6.2.2506.post74.dev0.data/data/Netgen.icns +0 -0
  279. ngsolve-6.2.2506.post74.dev0.data/data/bin/ngscxx +17 -0
  280. ngsolve-6.2.2506.post74.dev0.data/data/bin/ngsld +13 -0
  281. ngsolve-6.2.2506.post74.dev0.data/data/bin/ngsolve.tcl +648 -0
  282. ngsolve-6.2.2506.post74.dev0.data/data/bin/ngspy +2 -0
  283. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/beam.geo +17 -0
  284. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/beam.vol +240 -0
  285. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/chip.in2d +41 -0
  286. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/chip.vol +614 -0
  287. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coil.geo +12 -0
  288. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coil.vol +2560 -0
  289. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coilshield.geo +24 -0
  290. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coilshield.vol +3179 -0
  291. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/cube.geo +19 -0
  292. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/cube.vol +1832 -0
  293. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d10_DGdoubleglazing.pde +50 -0
  294. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d11_chip_nitsche.pde +40 -0
  295. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d1_square.pde +43 -0
  296. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d2_chip.pde +35 -0
  297. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d3_helmholtz.pde +22 -0
  298. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d4_cube.pde +46 -0
  299. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d5_beam.pde +74 -0
  300. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d6_shaft.pde +73 -0
  301. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d7_coil.pde +50 -0
  302. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d8_coilshield.pde +49 -0
  303. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d9_hybridDG.pde +72 -0
  304. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/doubleglazing.in2d +27 -0
  305. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/doubleglazing.vol +737 -0
  306. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/piezo2d40round4.vol.gz +0 -0
  307. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/shaft.geo +73 -0
  308. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/shaft.vol +4291 -0
  309. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/square.in2d +17 -0
  310. ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/square.vol +149 -0
  311. ngsolve-6.2.2506.post74.dev0.dist-info/METADATA +13 -0
  312. ngsolve-6.2.2506.post74.dev0.dist-info/RECORD +315 -0
  313. ngsolve-6.2.2506.post74.dev0.dist-info/WHEEL +5 -0
  314. ngsolve-6.2.2506.post74.dev0.dist-info/licenses/LICENSE +504 -0
  315. ngsolve-6.2.2506.post74.dev0.dist-info/top_level.txt +2 -0
ngsolve/webgui.py ADDED
@@ -0,0 +1,670 @@
1
+ import math
2
+ import numpy as np
3
+ import ngsolve as ngs
4
+ from typing import Optional
5
+ from netgen.webgui import Draw, register_draw_type, WebGLScene, encodeData
6
+
7
+ np.seterr(all='ignore', divide='ignore', invalid='ignore') # , over='ignore')
8
+
9
+ def updatePMinMax( pmat, pmima=None ):
10
+ pmima_new = [ngs.Vector(pmat[:,i], copy=False).MinMax(ignore_inf=True) for i in range(3)]
11
+
12
+ if pmima is not None:
13
+ for i in range(3):
14
+ minmax = ( min(pmima[i][0], pmima_new[i][0]), max(pmima[i][1], pmima_new[i][1]) )
15
+ pmima_new[i] = minmax
16
+
17
+ return pmima_new
18
+
19
+ def getMinMax( vals, fmin=None, fmax=None ):
20
+ funcmin,funcmax = ngs.Vector(vals, copy=False).MinMax(True)
21
+ if fmin is not None:
22
+ funcmin = min(funcmin, fmin)
23
+ if fmax is not None:
24
+ funcmax = max(funcmax, fmax)
25
+ return funcmin, funcmax
26
+
27
+
28
+ def _make_trig(N, x0=0, y0=0, dx=1, dy=1):
29
+ return [(x0+i*dx/N,y0+j*dy/N) for j in range(N+1) for i in range(N+1-j)]
30
+
31
+ def _make_quad(N, x0=0, y0=0, dx=1, dy=1):
32
+ return [(x0+i*dx/N,y0+j*dy/N) for j in range(N+1) for i in range(N+1-j)] + [(x0+dx-i*dx/N,1-(y0+j*dy/N)) for j in range(N+1) for i in range(N+1-j)]
33
+
34
+ _intrules = {}
35
+ def get_intrules(dim:int, order: int):
36
+ if (dim,order) in _intrules:
37
+ return _intrules[(dim, order)]
38
+
39
+ rules = {}
40
+ if dim == 2:
41
+ if order > 3:
42
+ n = (order+2)//3
43
+
44
+ trig_points = []
45
+ h = 1/n
46
+ for i in range(n):
47
+ for j in range(n-i):
48
+ trig_points += _make_trig(3, i*h, j*h, h, h)
49
+
50
+ for i in range(n-1):
51
+ for j in range(n-i-1):
52
+ trig_points += _make_trig(3, (i+1)*h, (j+1)*h, -h, -h)
53
+
54
+ quad_points = []
55
+ for i in range(n):
56
+ for j in range(n):
57
+ quad_points += _make_quad(3, i*h, j*h, h, h)
58
+
59
+ else:
60
+ trig_points = _make_trig(order)
61
+ quad_points = _make_quad(order)
62
+
63
+ rules[ngs.ET.TRIG] = ngs.IntegrationRule(trig_points, [0,]*len(trig_points))
64
+ rules[ngs.ET.QUAD] = ngs.IntegrationRule(quad_points, [0,]*len(quad_points))
65
+
66
+ elif dim == 3:
67
+ if order > 2:
68
+ raise RuntimeError("only order 1 and 2 supported in 3D")
69
+
70
+ p1_tets = {}
71
+ p1_tets[ngs.ET.TET] = [[(1,0,0), (0,1,0), (0,0,1), (0,0,0)]]
72
+ p1_tets[ngs.ET.PYRAMID]=[[(1,0,0), (0,1,0), (0,0,1), (0,0,0)],
73
+ [(1,0,0), (0,1,0), (0,0,1), (1,1,0)]]
74
+ p1_tets[ngs.ET.PRISM] = [[(1,0,0), (0,1,0), (0,0,1), (0,0,0)],
75
+ [(0,0,1), (0,1,0), (0,1,1), (1,0,0)],
76
+ [(1,0,1), (0,1,1), (1,0,0), (0,0,1)]]
77
+ p1_tets[ngs.ET.HEX] = [[(1,0,0), (0,1,0), (0,0,1), (0,0,0)],
78
+ [(0,1,1), (1,1,1), (1,1,0), (1,0,1)],
79
+ [(1,0,1), (0,1,1), (1,0,0), (0,0,1)],
80
+ [(0,1,1), (1,1,0), (0,1,0), (1,0,0)],
81
+ [(0,0,1), (0,1,0), (0,1,1), (1,0,0)],
82
+ [(1,0,1), (1,1,0), (0,1,1), (1,0,0)]]
83
+
84
+ def makeP2Tets( p1_tets ):
85
+ midpoint = lambda p0, p1: tuple((0.5*(p0[i]+p1[i]) for i in range(3)))
86
+ p2_tets = []
87
+ for tet in p1_tets:
88
+ tet.append( midpoint(tet[0], tet[3]) )
89
+ tet.append( midpoint(tet[1], tet[3]) )
90
+ tet.append( midpoint(tet[2], tet[3]) )
91
+ tet.append( midpoint(tet[0], tet[1]) )
92
+ tet.append( midpoint(tet[0], tet[2]) )
93
+ tet.append( midpoint(tet[1], tet[2]) )
94
+ p2_tets.append(tet)
95
+ return p2_tets
96
+ for eltype in p1_tets:
97
+ points = p1_tets[eltype]
98
+ if order == 2:
99
+ points = makeP2Tets( points )
100
+ rules[eltype] = ngs.IntegrationRule( sum(points, []) )
101
+ else:
102
+ raise RuntimeError(f"invalid dimension: {dim}")
103
+ _intrules[(dim, order)] = rules
104
+ return rules
105
+
106
+ @register_draw_type(ngs.Mesh, ngs.CoefficientFunction, ngs.GridFunction, ngs.comp.GridFunctionCoefficientFunction)
107
+ def GetData(obj, args, kwargs):
108
+ regions = {}
109
+
110
+ cf = None
111
+ if isinstance(obj, ngs.GridFunction):
112
+ cf = obj
113
+ mesh = obj.space.mesh
114
+ if len(args) and isinstance(args[0], (ngs.Region, ngs.Mesh)):
115
+ mesh = args[0]
116
+ elif isinstance(obj, ngs.CoefficientFunction):
117
+ cf = obj
118
+ if len(args)<1:
119
+ raise RuntimeError("Cannot draw CoefficientFunction without mesh")
120
+ mesh = args[0]
121
+ else:
122
+ # assume, mesh is given
123
+ mesh = obj
124
+
125
+ # got one region as input: draw only on region and region.Boundaries()
126
+ if isinstance(mesh, ngs.comp.Region):
127
+ region = mesh
128
+ mesh = region.mesh
129
+ regions[region.VB()] = region
130
+ while region.VB() != ngs.BBND:
131
+ bnd_reg = region.Boundaries()
132
+ regions[bnd_reg.VB()] = bnd_reg
133
+ region = bnd_reg
134
+
135
+ # draw exactly on given list of regions (no regions.Boundaries())
136
+ elif isinstance(mesh, list):
137
+ regions = {}
138
+ list_ = mesh
139
+ mesh = None
140
+ for reg in list_:
141
+ if isinstance(reg, ngs.comp.Region):
142
+ mesh = reg.mesh
143
+ regions[reg.VB()] = reg
144
+ if isinstance(reg, ngs.comp.VorB):
145
+ regions[reg] = reg
146
+ if mesh is None:
147
+ raise RuntimeError("missing mesh/region")
148
+
149
+ # draw on whole mesh
150
+ elif isinstance(mesh, ngs.comp.Mesh):
151
+ for vb in [ngs.VOL, ngs.BND, ngs.BBND]:
152
+ regions[vb] = vb
153
+ else:
154
+ raise RuntimeError("invalid input mesh")
155
+
156
+ # fill with empty regions
157
+ for vb in [ngs.VOL, ngs.BND, ngs.BBND]:
158
+ if vb not in regions:
159
+ regions[vb] = mesh.Region(vb, None)
160
+
161
+ if 'intpoints' not in kwargs:
162
+ kwargs['intpoints'] = None
163
+ d = BuildRenderData(mesh, cf, order=kwargs['order'], draw_surf=kwargs['draw_surf'], draw_vol=kwargs['draw_vol'], intpoints=kwargs['intpoints'], deformation=kwargs['deformation'], regions=regions, objects=kwargs['objects'], nodal_p1=kwargs['nodal_p1'], settings=kwargs['settings'])
164
+
165
+ if isinstance(cf, ngs.GridFunction) and len(cf.vecs)>1:
166
+ # multidim gridfunction - generate data for each component
167
+ gf = ngs.GridFunction(cf.space)
168
+ dim = len(cf.vecs)
169
+
170
+ md_deformation = False;
171
+ if 'deformation' in kwargs:
172
+ deformation = kwargs['deformation']
173
+ if isinstance(deformation, ngs.GridFunction) and len(deformation.vecs)==dim:
174
+ md_deformation = True
175
+ deformation_gf = ngs.GridFunction(deformation.space)
176
+ else:
177
+ deformation_gf = deformation
178
+
179
+ data = []
180
+ for i in range(1,dim):
181
+ gf.vec.data = cf.vecs[i]
182
+
183
+ if md_deformation:
184
+ deformation_gf.vec.data = deformation.vecs[i]
185
+
186
+ data.append(BuildRenderData(mesh, gf, order=kwargs['order'], draw_surf=kwargs['draw_surf'], draw_vol=kwargs['draw_vol'], intpoints=kwargs['intpoints'], deformation=deformation_gf, regions=regions, objects=kwargs['objects'], nodal_p1=kwargs['nodal_p1'], settings=kwargs['settings']))
187
+ d['multidim_data'] = data
188
+ d['multidim_interpolate'] = kwargs.get('interpolate_multidim', False)
189
+ d['multidim_animate'] = kwargs.get('animate', False)
190
+
191
+ d['deformation_scale'] = kwargs.get('scale', 1.0)
192
+
193
+ if 'is_complex' in d and d['is_complex'] or 'animate_complex' in kwargs:
194
+ s = d['gui_settings']
195
+ if 'Complex' not in s:
196
+ s['Complex'] = dict(phase= 0.0, speed=1, animate=False)
197
+ s['Complex']['animate'] = kwargs.get('animate_complex', False)
198
+
199
+ if 'colors' in kwargs:
200
+ d['colors'] = kwargs['colors']
201
+
202
+
203
+ return d
204
+
205
+
206
+ bezier_trig_trafos = { } # cache trafos for different orders
207
+
208
+ timer = ngs.Timer("BuildRenderData")
209
+ timerp1 = ngs.Timer("GetNodalP1Data")
210
+ timer2map = ngs.Timer("edges map")
211
+ timer2 = ngs.Timer("edges")
212
+ timermult = ngs.Timer("timer2 - mult")
213
+ timer3 = ngs.Timer("els")
214
+ timer3Bvals = ngs.Timer("timer3, bezier")
215
+ timer3minmax = ngs.Timer("els minmax")
216
+ timer2list = ngs.Timer("timer2 - make list")
217
+ timer3list = ngs.Timer("timer3 - make list")
218
+ timer4 = ngs.Timer("func")
219
+
220
+ timer3multnumpy = ngs.Timer("timer3 mul numpy")
221
+ timer3multngs = ngs.Timer("timer3 mul ngs")
222
+
223
+ def GetNodalP1Data(encode, mesh, cf, cf2=None):
224
+ if cf2 is not None:
225
+ cf = ngs.CF((cf,cf2))
226
+ timerp1.Start()
227
+ fes = ngs.NodalFESpace(mesh, order=1)**cf.dim
228
+ gfu = ngs.GridFunction(fes)
229
+ gfu.Interpolate(cf, ngs.BND)
230
+ function_values = gfu.vec.FV().NumPy()
231
+ nvert = mesh.nv
232
+ function_values = function_values.reshape(-1, nvert).transpose().flatten()
233
+ fmin, fmax = ngs.Vector(function_values, copy=False).MinMax(True)
234
+ vertices = np.array(mesh.ngmesh._getVertices(), dtype=np.float32)
235
+
236
+ pmat = vertices.reshape(-1, 3)
237
+ pmin = pmat.min(axis=0)
238
+ pmax = pmat.max(axis=0)
239
+ mesh_center = list(np.array(0.5*(pmin+pmax), dtype=np.float64))
240
+ mesh_radius = float(np.linalg.norm(pmax-pmin)/2)
241
+
242
+ segments = mesh.ngmesh._getSegments()
243
+
244
+ d = {}
245
+ d['vertices'] = encode(vertices, dtype=np.float32)
246
+ d['nodal_function_values'] = encode(function_values, dtype=np.float32)
247
+ d['trigs'] = encode(np.array(mesh.ngmesh._get2dElementsAsTriangles(), dtype=np.int32))
248
+ d['tets'] = encode(np.array(mesh.ngmesh._get3dElementsAsTets(), dtype=np.int32))
249
+ d['segs'] = encode(np.array(segments, dtype=np.int32))
250
+ d['mesh_center'] = mesh_center
251
+ d['mesh_radius'] = mesh_radius
252
+ d['funcmin'] = fmin
253
+ d['funcmax'] = fmax
254
+
255
+ timerp1.Stop()
256
+ return d
257
+
258
+
259
+ def BuildRenderData(mesh, func, order=2, draw_surf=True, draw_vol=True, intpoints=None, deformation=None, regions=None, objects=[], nodal_p1=False, encoding='b64', settings={}):
260
+ timer.Start()
261
+
262
+ import inspect
263
+ # stay backwards-compatible with older verisons of webgui_jupyter_widgets
264
+ if 'encoding' in inspect.signature(encodeData).parameters:
265
+ def encode(*args, **kwargs):
266
+ return encodeData(*args, **kwargs, encoding=encoding)
267
+ else:
268
+ def encode(*args, **kwargs):
269
+ return encodeData(*args, **kwargs)
270
+
271
+ if isinstance(deformation, ngs.CoefficientFunction) and deformation.dim==2:
272
+ deformation = ngs.CoefficientFunction((deformation, 0.0))
273
+
274
+ #TODO: handle quads and non-smooth functions
275
+ #TODO: subdivision
276
+
277
+ d = {}
278
+ d['gui_settings'] = settings
279
+ d['ngsolve_version'] = ngs.__version__
280
+ d['mesh_dim'] = mesh.dim
281
+ # order = order or mesh.GetCurveOrder()
282
+ if (not func) and (mesh.GetCurveOrder()==1) and (mesh.nv==len(mesh.ngmesh.Points())):
283
+ order=1
284
+ order2d = min(order, 3)
285
+ order3d = min(order, 2)
286
+ d['order2d'] = order2d
287
+ d['order3d'] = order3d
288
+
289
+ d['draw_vol'] = func and mesh.dim==3 and draw_vol and mesh.ne>0
290
+ d['draw_surf'] = func and draw_surf
291
+
292
+ d['objects'] = []
293
+ for obj in objects:
294
+ if isinstance(obj, dict):
295
+ d['objects'].append(obj)
296
+ else:
297
+ d['objects'].append(obj._GetWebguiData())
298
+
299
+ if isinstance(deformation, bool):
300
+ d['deformation'] = deformation
301
+ deformation = None
302
+
303
+ func0 = None
304
+ func2 = None
305
+ if func and func.is_complex:
306
+ d['is_complex'] = True
307
+ func1 = func[0].real
308
+ func2 = ngs.CoefficientFunction( (func[0].imag, 0.0) )
309
+ d['funcdim'] = 2
310
+ elif func and func.dim>1:
311
+ func1 = func[0]
312
+ func2 = ngs.CoefficientFunction( tuple(func[i] if i<func.dim else 0.0 for i in range(1,3)) ) # max 3-dimensional functions
313
+ d['funcdim'] = func.dim
314
+ elif func:
315
+ func1 = func
316
+ d['funcdim'] = 1
317
+ else:
318
+ # no function at all -> we are just drawing a mesh, eval mesh element index instead
319
+ mats = mesh.GetMaterials()
320
+ bnds = mesh.GetBoundaries()
321
+ bbnds = mesh.GetBBoundaries()
322
+ nmats = len(mesh.GetMaterials())
323
+ nbnds = len(mesh.GetBoundaries())
324
+ n = max(nmats, nbnds, len(bbnds))
325
+ func1 = ngs.CoefficientFunction(list(range(n)))
326
+ n_regions = [0, 0, nmats, nbnds]
327
+ d['mesh_regions_2d'] = n_regions[mesh.dim]
328
+ d['mesh_regions_3d'] = nmats if mesh.dim==3 else 0
329
+ d['names'] = bnds if mesh.dim==3 else mats
330
+ d['edge_names'] = bbnds if mesh.dim==3 else bnds
331
+ d['funcdim'] = 0
332
+ fds = mesh.ngmesh.FaceDescriptors()
333
+ d["colors"] = [fd.color + (fd.transparency,) for fd in fds]
334
+
335
+ func0 = func1
336
+
337
+ if func0 is None:
338
+ func0 = ngs.CoefficientFunction( 0.0 )
339
+
340
+ d['show_wireframe'] = order2d>0
341
+ d['show_mesh'] = order2d>0
342
+
343
+ if order==1 and nodal_p1:
344
+ d.update(GetNodalP1Data(encode, mesh, func1, func2))
345
+ if '_override_data' in settings:
346
+ d.update(settings['_override_data'])
347
+ timer.Stop()
348
+ return d
349
+
350
+ func1 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, func1 ) )
351
+ func0 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, func0 ) )
352
+
353
+ if deformation is not None:
354
+ func1 += ngs.CoefficientFunction((deformation, 0.0))
355
+ func0 += ngs.CoefficientFunction((deformation, 0.0))
356
+
357
+ if order2d>0:
358
+ og = order2d
359
+ timer2.Start()
360
+
361
+ timer3Bvals.Start()
362
+
363
+ # transform point-values to Bernsteinbasis
364
+ def Binomial(n,i): return math.factorial(n) / math.factorial(i) / math.factorial(n-i)
365
+ def Bernstein(x, i, n): return Binomial(n,i) * x**i*(1-x)**(n-i)
366
+ Bvals = ngs.Matrix(og+1,og+1)
367
+ for i in range(og+1):
368
+ for j in range(og+1):
369
+ Bvals[i,j] = Bernstein(i/og, j, og)
370
+ iBvals = Bvals.I
371
+ timer3Bvals.Stop()
372
+ # print (Bvals)
373
+ # print (iBvals)
374
+
375
+
376
+ Bezier_points = []
377
+
378
+ # TODO: Quads
379
+ 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)]
380
+ ir_trig = ngs.IntegrationRule(ipts, [0,]*len(ipts))
381
+ 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)]
382
+ ir_quad = ngs.IntegrationRule(ipts, [0,]*len(ipts))
383
+
384
+ vb = [ngs.VOL, ngs.BND][mesh.dim-2]
385
+ reg = regions[vb]
386
+ cf = func1 if draw_surf else func0
387
+ timer2map.Start()
388
+ pts = mesh.MapToAllElements({ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad}, reg)
389
+ timer2map.Stop()
390
+ pmat = cf(pts)
391
+
392
+ pmima = updatePMinMax(pmat)
393
+
394
+ timermult.Start()
395
+ pmat = pmat.reshape(-1, og+1, 4)
396
+ if False:
397
+ BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1))
398
+ else:
399
+ BezierPnts = np.zeros( (og+1, pmat.shape[0], 4) )
400
+ for i in range(4):
401
+ ngsmat = ngs.Matrix(pmat[:,:,i].transpose())
402
+ BezierPnts[:,:,i] = iBvals * ngsmat
403
+ timermult.Stop()
404
+
405
+ timer2list.Start()
406
+ for i in range(og+1):
407
+ Bezier_points.append(encode(BezierPnts[i], dtype=np.float32))
408
+ timer2list.Stop()
409
+
410
+ if func2 and draw_surf:
411
+ pmat = func2(pts)
412
+ pmat = pmat.reshape(-1, og+1, 2)
413
+ timermult.Start()
414
+ BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1))
415
+ timermult.Stop()
416
+ timer2list.Start()
417
+ for i in range(og+1):
418
+ Bezier_points.append(encode(BezierPnts[i], dtype=np.float32))
419
+ timer2list.Stop()
420
+
421
+ d['Bezier_points'] = Bezier_points
422
+
423
+ ipts = [(i/og,0) for i in range(og+1)]
424
+ ir_seg = ngs.IntegrationRule(ipts, [0,]*len(ipts))
425
+ vb = [ngs.VOL, ngs.BND, ngs.BBND][mesh.dim-1]
426
+ reg = regions[vb]
427
+ pts = mesh.MapToAllElements(ir_seg, reg)
428
+ pmat = func0(pts)
429
+ pmima = updatePMinMax(pmat)
430
+ pmat = pmat.reshape(-1, og+1, 4)
431
+ edge_data = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1))
432
+ edges = []
433
+ for i in range(og+1):
434
+ edges.append(encode(edge_data[i], dtype=np.float32))
435
+ d['edges'] = edges
436
+
437
+ timer2.Stop()
438
+ timer3.Start()
439
+
440
+ ndtrig = int((og+1)*(og+2)/2)
441
+
442
+ if og in bezier_trig_trafos.keys():
443
+ iBvals_trig = bezier_trig_trafos[og]
444
+ else:
445
+ def BernsteinTrig(x, y, i, j, n):
446
+ return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \
447
+ * x**i*y**j*(1-x-y)**(n-i-j)
448
+ Bvals = ngs.Matrix(ndtrig, ndtrig)
449
+ ii = 0
450
+ for ix in range(og+1):
451
+ for iy in range(og+1-ix):
452
+ jj = 0
453
+ for jx in range(og+1):
454
+ for jy in range(og+1-jx):
455
+ Bvals[ii,jj] = BernsteinTrig(ix/og, iy/og, jx, jy, og)
456
+ jj += 1
457
+ ii += 1
458
+ iBvals_trig = Bvals.I
459
+ bezier_trig_trafos[og] = iBvals_trig
460
+
461
+
462
+ # Bezier_points = [ [] for i in range(ndtrig) ]
463
+ Bezier_points = []
464
+
465
+ vb = [ngs.VOL, ngs.BND][mesh.dim-2]
466
+ reg = regions[vb]
467
+ if intpoints is not None:
468
+ pts = mesh.MapToAllElements(intpoints, reg)
469
+ else:
470
+ pts = mesh.MapToAllElements(get_intrules(2, order), reg)
471
+
472
+ pmat = ngs.CoefficientFunction( func1 if draw_surf else func0 ) (pts)
473
+
474
+
475
+ n_points_per_trig = len(get_intrules(2, order2d)[ngs.ET.TRIG])
476
+
477
+ timer3minmax.Start()
478
+ pmima = updatePMinMax(pmat, pmima)
479
+ funcmin,funcmax = getMinMax(pmat[:,3])
480
+ timer3minmax.Stop()
481
+
482
+ pmin, pmax = [ngs.Vector(p) for p in zip(*pmima)]
483
+ mesh_center = 0.5*(pmin+pmax)
484
+ mesh_radius = float(np.linalg.norm(pmax-pmin)/2)
485
+
486
+ pmat = pmat.reshape(-1, n_points_per_trig, 4)
487
+
488
+ if False:
489
+ timer3multnumpy.Start()
490
+ BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1,1))
491
+ timer3multnumpy.Stop()
492
+ else:
493
+ timer3multngs.Start()
494
+ BezierPnts = np.zeros( (n_points_per_trig, pmat.shape[0], 4) )
495
+ for i in range(4):
496
+ ngsmat = ngs.Matrix(pmat[:,:,i].transpose())
497
+ BezierPnts[:,:,i] = iBvals_trig * ngsmat
498
+ timer3multngs.Stop()
499
+
500
+ timer3list.Start()
501
+ for i in range(ndtrig):
502
+ Bezier_points.append(encode(BezierPnts[i], dtype=np.float32))
503
+ timer3list.Stop()
504
+
505
+ if func2 and draw_surf:
506
+ pmat = ngs.CoefficientFunction( func2 ) (pts)
507
+
508
+ pmat = pmat.reshape(-1, n_points_per_trig, 2)
509
+
510
+ funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax)
511
+ BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1,1))
512
+ if og==1:
513
+ for i in range(ndtrig):
514
+ Bezier_points.append(encode(BezierPnts[i], dtype=np.float32))
515
+ else:
516
+ BezierPnts = BezierPnts.transpose((1,0,2)).reshape(-1, n_points_per_trig//2, 4).transpose((1,0,2))
517
+
518
+ for i in range(ndtrig//2):
519
+ Bezier_points.append(encode(BezierPnts[i], dtype=np.float32))
520
+
521
+ d['Bezier_trig_points'] = Bezier_points
522
+ d['mesh_center'] = list(mesh_center)
523
+ d['mesh_radius'] = mesh_radius
524
+ timer3.Stop()
525
+
526
+
527
+
528
+ timer4.Start()
529
+
530
+ if d['draw_vol']:
531
+ p0 = []
532
+ p1 = []
533
+ p2 = []
534
+ p3 = []
535
+ values = []
536
+ tets = []
537
+
538
+ intrules = get_intrules(3, order3d)
539
+
540
+ if intpoints is not None:
541
+ pts = mesh.MapToAllElements(intpoints, regions[ngs.VOL])
542
+ else:
543
+ pts = mesh.MapToAllElements(get_intrules(3, order3d), regions[ngs.VOL])
544
+
545
+ pmat = func1(pts)
546
+
547
+ np_per_tet = len(intrules[ngs.ET.TET])
548
+
549
+ ne = mesh.GetNE(ngs.VOL)
550
+ pmat = pmat.reshape(-1, np_per_tet, 4)
551
+
552
+ funcmin, funcmax = getMinMax(pmat[:,:,3].flatten(), funcmin, funcmax)
553
+ points3d = []
554
+ for i in range(np_per_tet):
555
+ points3d.append(encode(pmat[:,i,:], dtype=np.float32))
556
+
557
+ if func2:
558
+ pmat = func2(pts).reshape(-1, np_per_tet//2, 4)
559
+ funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax)
560
+ for i in range(np_per_tet//2):
561
+ points3d.append(encode(pmat[:,i,:], dtype=np.float32))
562
+ d['points3d'] = points3d
563
+ if func:
564
+ d['funcmin'] = funcmin
565
+ d['funcmax'] = funcmax
566
+ if '_override_data' in settings:
567
+ d.update(settings['_override_data'])
568
+ timer4.Stop()
569
+ timer.Stop()
570
+ return d
571
+
572
+ def AddFieldLines(data: dict, add_data: dict):
573
+ if "num_points" not in data:
574
+ data["num_points"] = [len(data["value"])]
575
+
576
+ data["num_points"].append(len(add_data["value"]))
577
+ data["pstart"] += add_data["pstart"]
578
+ data["pend"] += add_data["pend"]
579
+ data["value"] += add_data["value"]
580
+
581
+ return data
582
+
583
+ def FieldLines(
584
+ function: ngs.CoefficientFunction,
585
+ start_region: Optional[ngs.Region] = None,
586
+ mesh: Optional[ngs.Mesh] = None,
587
+ start_points: Optional[list] = None,
588
+ num_lines: int = 100,
589
+ length: float = 0.5,
590
+ name: str = "fieldlines",
591
+ max_points_per_line: float = 500,
592
+ thickness: float = 0.0015,
593
+ tolerance: float = 0.0005,
594
+ direction: int = 0,
595
+ ):
596
+ assert start_region or (mesh and start_points), "Either start_region or mesh and start_points must be provided"
597
+ rules = {}
598
+ # use 5th order integration rule for all element types as potential starting points
599
+ for et in [
600
+ ngs.ET.TRIG,
601
+ ngs.ET.QUAD,
602
+ ngs.ET.TET,
603
+ ngs.ET.HEX,
604
+ ngs.ET.PRISM,
605
+ ngs.ET.PYRAMID,
606
+ ]:
607
+ rules[et] = ngs.IntegrationRule(et, 5)
608
+
609
+ if function.is_complex:
610
+ num_lines = num_lines // 10
611
+
612
+ if start_points is not None:
613
+ all_mapped_points = mesh(start_points[:,0], start_points[:,1], start_points[:,2])
614
+ else:
615
+ mesh = start_region.mesh
616
+ all_mapped_points = mesh.MapToAllElements(rules, start_region)
617
+
618
+ num_angles = 100 if function.is_complex else 1
619
+ for a in range(num_angles):
620
+ phi = 2 * np.pi * a / num_angles
621
+
622
+ if function.is_complex:
623
+ cf = ngs.cos(phi) * function.real - ngs.sin(phi) * function.imag
624
+ else:
625
+ cf = function
626
+
627
+ # randomize starting points to choose approx num_lines, higher function values increase selection probability
628
+ values = ngs.Norm(cf)(all_mapped_points).flatten()
629
+ sum_values = sum(values)
630
+
631
+ rand_values = np.random.rand(len(values))
632
+ selection = np.where(values > sum_values/num_lines * rand_values)
633
+ mapped_points = all_mapped_points[selection]
634
+
635
+ # generate raw staring point coordinates and call low_level interface routing
636
+ points = ngs.CF((ngs.x, ngs.y, ngs.z))(mapped_points)
637
+
638
+ data = cf._BuildFieldLines(
639
+ mesh,
640
+ points,
641
+ len(points),
642
+ length,
643
+ max_points_per_line,
644
+ thickness,
645
+ tolerance,
646
+ direction,
647
+ False,
648
+ )
649
+ if a == 0:
650
+ global_data = data
651
+ global_data["min"] = min(values)
652
+ global_data["max"] = max(values)
653
+ if function.is_complex:
654
+ global_data["max_phase_dist"] = np.pi / 180 * 15
655
+ global_data["phase"] = [phi]
656
+ global_data["offset"] = [0]
657
+ else:
658
+ global_data["max_phase_dist"] = 0.5
659
+ else:
660
+ AddFieldLines(global_data, data)
661
+ global_data["phase"].append(phi)
662
+ global_data["min"] = min(global_data["min"], min(values))
663
+ global_data["max"] = max(global_data["max"], max(values))
664
+
665
+ global_data["fade_dist"] = 0.0
666
+ global_data["name"] = name
667
+ return global_data
668
+
669
+
670
+ __all__ = ["Draw", "FieldLines", "AddFieldLines"]
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ NGSCXX_DIR=$( cd $(dirname $0); pwd )
3
+ PY_INCLUDE_FLAGS=-I$(python3 -c"import sysconfig;print(sysconfig.get_path('include'))")
4
+ if [ -f /Library/Developer/CommandLineTools/usr/bin/c++ ]
5
+ then NGSCXX=/Library/Developer/CommandLineTools/usr/bin/c++
6
+ else NGSCXX=c++
7
+ fi
8
+ export CCACHE_NOHASHDIR=1
9
+
10
+ Netgen_BUNDLE="`echo "$0" | sed -e 's/\/Contents\/MacOS\/ngscxx//'`"
11
+ Netgen_MACOS="$Netgen_BUNDLE/Contents/MacOS"
12
+
13
+
14
+ if [ -f /usr/local/bin/ccache ]
15
+ then /usr/local/bin/ccache $NGSCXX -O3 -DNDEBUG -DHAVE_NETGEN_SOURCES -DHAVE_DLFCN_H -DHAVE_CXA_DEMANGLE -DUSE_TIMEOFDAY -DMSG_NOSIGNAL=0 -DTCL -DLAPACK -DNGS_PYTHON -DUSE_UMFPACK -DNETGEN_PYTHON -DNG_PYTHON -DPYBIND11_SIMPLE_GIL_MANAGEMENT -DPARALLEL -DNG_MPI_WRAPPER -std=c++17 -Wno-undefined-var-template -Wno-vla-extension -DMAX_SYS_DIM=3 -Xarch_x86_64 -march=core-avx2 -fPIC -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk -I/Library/Frameworks/Python.framework/Versions/3.14/include/python3.14 -I$NGSCXX_DIR/../netgen/include -I$NGSCXX_DIR/../netgen/include/include $PY_INCLUDE_FLAGS -I$Netgen_BUNDLE/Contents/Resources/include $*
16
+ else $NGSCXX -O3 -DNDEBUG -DHAVE_NETGEN_SOURCES -DHAVE_DLFCN_H -DHAVE_CXA_DEMANGLE -DUSE_TIMEOFDAY -DMSG_NOSIGNAL=0 -DTCL -DLAPACK -DNGS_PYTHON -DUSE_UMFPACK -DNETGEN_PYTHON -DNG_PYTHON -DPYBIND11_SIMPLE_GIL_MANAGEMENT -DPARALLEL -DNG_MPI_WRAPPER -std=c++17 -Wno-undefined-var-template -Wno-vla-extension -DMAX_SYS_DIM=3 -Xarch_x86_64 -march=core-avx2 -fPIC -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk -I/Library/Frameworks/Python.framework/Versions/3.14/include/python3.14 -I$NGSCXX_DIR/../netgen/include -I$NGSCXX_DIR/../netgen/include/include $PY_INCLUDE_FLAGS -I$Netgen_BUNDLE/Contents/Resources/include $*
17
+ fi