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
@@ -0,0 +1,1262 @@
1
+ #ifndef FILE_H1HOFE_IMPL
2
+ #define FILE_H1HOFE_IMPL
3
+
4
+ /*********************************************************************/
5
+ /* File: h1hofe_impl.hpp */
6
+ /* Author: Start */
7
+ /* Date: 6. Feb. 2003 */
8
+ /*********************************************************************/
9
+
10
+ #include "recursive_pol.hpp"
11
+ #include "h1hofe.hpp"
12
+
13
+
14
+ namespace ngfem
15
+ {
16
+
17
+ template <ELEMENT_TYPE ET>
18
+ class H1HighOrderFE_Shape : public H1HighOrderFE<ET, H1HighOrderFE_Shape<ET>>
19
+ {
20
+ using H1HighOrderFE<ET>::order;
21
+ using H1HighOrderFE<ET>::order_edge;
22
+ using H1HighOrderFE<ET>::order_face;
23
+ using H1HighOrderFE<ET>::order_cell;
24
+
25
+ using H1HighOrderFE<ET>::N_VERTEX;
26
+ using H1HighOrderFE<ET>::N_EDGE;
27
+ using H1HighOrderFE<ET>::N_FACE;
28
+
29
+ static constexpr int DIM = ngfem::Dim(ET);
30
+
31
+ // typedef LegendrePolynomial EdgeOrthoPol;
32
+ typedef IntLegNoBubble EdgeOrthoPol; // Integrated Legendre divided by bubble
33
+ // typedef ChebyPolynomial EdgeOrthoPol;
34
+
35
+ // typedef ChebyPolynomial QuadOrthoPol;
36
+ typedef IntLegNoBubble QuadOrthoPol;
37
+
38
+ // typedef DubinerBasis TrigOrthoPol;
39
+ typedef DubinerBasisOrthoBub TrigOrthoPol; // for bi-orthogonal dual shapes
40
+
41
+ public:
42
+ template<typename Tx, typename TFA>
43
+ INLINE void T_CalcShape (TIP<DIM,Tx> ip, TFA & shape) const;
44
+
45
+ template<typename Tx, typename TFA>
46
+ INLINE void T_CalcDualShape (const TIP<DIM,Tx> ip, TFA & shape) const
47
+ { throw Exception ("T_dual shape not implemented, H1Ho"+ToString(ET)); }
48
+
49
+ /*
50
+ void CalcDualShape2 (const BaseMappedIntegrationPoint & mip, SliceVector<> shape) const
51
+ {
52
+ double imeas = 1.0/mip.GetMeasure();
53
+ shape = 0.0;
54
+ T_CalcDualShape (GetTIP<DIM>(mip.IP()), SBLambda ( [&](int j, double val) { shape(j) = imeas * val; }));
55
+ // throw Exception ("dual shape not implemented, H1Ho");
56
+ }
57
+ */
58
+
59
+ bool GetDiagDualityMassInverse2 (FlatVector<> diag) const { return false; }
60
+ };
61
+
62
+
63
+
64
+ /* *********************** Point **********************/
65
+
66
+ template<> template<typename Tx, typename TFA>
67
+ void H1HighOrderFE_Shape<ET_POINT> :: T_CalcShape (TIP<0,Tx> ip, TFA & shape) const
68
+ {
69
+ shape[0] = Tx(1.0);
70
+ }
71
+
72
+ template<> template<typename Tx, typename TFA>
73
+ void H1HighOrderFE_Shape<ET_POINT> :: T_CalcDualShape (TIP<0,Tx> ip, TFA & shape) const
74
+ {
75
+ shape[0] = Tx(1.0);
76
+ }
77
+ /*
78
+ template<>
79
+ inline void H1HighOrderFE_Shape<ET_POINT> ::CalcDualShape2 (const BaseMappedIntegrationPoint & mip, SliceVector<> shape) const
80
+ {
81
+ shape[0] = 1.0;
82
+ }
83
+ */
84
+
85
+ /* *********************** Segment **********************/
86
+
87
+ template <> template<typename Tx, typename TFA>
88
+ void H1HighOrderFE_Shape<ET_SEGM> :: T_CalcShape (TIP<1,Tx> ip, TFA & shape) const
89
+ {
90
+ Tx lam[2] = { ip.x, 1-ip.x };
91
+
92
+ shape[0] = lam[0];
93
+ shape[1] = lam[1];
94
+
95
+ if (order_edge[0] >= 2)
96
+ {
97
+ IVec<2> e = GetVertexOrientedEdge (0);
98
+ EdgeOrthoPol::
99
+ EvalMult (order_edge[0]-2,
100
+ lam[e[1]]-lam[e[0]], lam[e[0]]*lam[e[1]], shape+2);
101
+ }
102
+ }
103
+
104
+ template<> template<typename Tx, typename TFA>
105
+ void H1HighOrderFE_Shape<ET_SEGM> :: T_CalcDualShape(TIP<1,Tx> ip, TFA& shape) const
106
+ {
107
+ Tx lam[2] = { ip.x, 1. - ip.x };
108
+
109
+ if (ip.vb == BND)
110
+ {
111
+ for (size_t i = 0; i < 2; i++)
112
+ shape[i] = (i == ip.facetnr) ? 1 : 0;
113
+ }
114
+
115
+ // edge-based shapes
116
+ if ( (ip.vb == VOL) && (order_edge[0] >= 2) )
117
+ {
118
+ IVec<2> e = GetVertexOrientedEdge(0);
119
+ EdgeOrthoPol::Eval (order_edge[0]-2, lam[e[1]]-lam[e[0]], shape+2);
120
+ }
121
+ }
122
+
123
+ #ifdef NONE
124
+ template<>
125
+ inline void H1HighOrderFE_Shape<ET_SEGM> ::CalcDualShape2 (const BaseMappedIntegrationPoint & mip, SliceVector<> shape) const
126
+ {
127
+ auto & ip = mip.IP();
128
+ shape = 0.0;
129
+ double lam[2] = { ip(0), 1 - ip(0) };
130
+
131
+ if (ip.VB() == BND)
132
+ {
133
+ for (size_t i = 0; i < 2; i++)
134
+ shape[i] = (i == ip.FacetNr()) ? 1 : 0;
135
+ }
136
+
137
+ // edge-based shapes
138
+ if ( (ip.VB() == VOL) && (order_edge[0] >= 2) )
139
+ {
140
+ IVec<2> e = GetVertexOrientedEdge(0);
141
+ EdgeOrthoPol::
142
+ EvalScaledMult (order_edge[0]-2,
143
+ lam[e[1]]-lam[e[0]], lam[e[0]]+lam[e[1]],
144
+ 1.0/mip.GetMeasure() /* *lam[e[0]]*lam[e[1]]*/, shape+2);
145
+ }
146
+ }
147
+ #endif
148
+
149
+ /* *********************** Triangle **********************/
150
+
151
+ template<> template<typename Tx, typename TFA>
152
+ void H1HighOrderFE_Shape<ET_TRIG> :: T_CalcShape (TIP<2,Tx> ip, TFA & shape) const
153
+ {
154
+ Tx lam[3] = { ip.x, ip.y, 1-ip.x-ip.y };
155
+
156
+ for (int i = 0; i < 3; i++) shape[i] = lam[i];
157
+
158
+ int ii = 3;
159
+
160
+ // edge-based shapes
161
+ for (int i = 0; i < N_EDGE; i++)
162
+ if (order_edge[i] >= 2)
163
+ {
164
+ IVec<2> e = GetVertexOrientedEdge(i);
165
+ EdgeOrthoPol::
166
+ EvalScaledMult (order_edge[i]-2,
167
+ lam[e[1]]-lam[e[0]], lam[e[0]]+lam[e[1]],
168
+ lam[e[0]]*lam[e[1]], shape+ii);
169
+ ii += order_edge[i]-1;
170
+ }
171
+
172
+ // inner shapes
173
+ if (order_face[0][0] >= 3)
174
+ {
175
+ // IVec<4> f = GetFaceSort (0, vnums);
176
+ IVec<4> f = GetVertexOrientedFace (0);
177
+ TrigOrthoPol::EvalMult (order_face[0][0]-3,
178
+ lam[f[0]], lam[f[1]],
179
+ lam[f[0]]*lam[f[1]]*lam[f[2]], shape+ii);
180
+ }
181
+ }
182
+
183
+
184
+ template<> template<typename Tx, typename TFA>
185
+ void H1HighOrderFE_Shape<ET_TRIG> :: T_CalcDualShape (TIP<2,Tx> ip, TFA & shape) const
186
+ {
187
+ Tx lam[3] = { ip.x, ip.y, 1.0-ip.x-ip.y };
188
+
189
+ size_t ii = 3;
190
+
191
+ if (ip.vb == BBND)
192
+ {
193
+ shape[ip.facetnr] = 1.0;
194
+ return;
195
+ }
196
+
197
+ // edge-based shapes
198
+ for (int i = 0; i < N_EDGE; i++)
199
+ if (order_edge[i] >= 2)
200
+ {
201
+ if (ip.vb == BND && ip.facetnr == i)
202
+ {
203
+ IVec<2> e = GetVertexOrientedEdge(i);
204
+ EdgeOrthoPol::Eval (order_edge[i]-2, lam[e[1]]-lam[e[0]], shape+ii);
205
+ }
206
+ ii += order_edge[i]-1;
207
+ }
208
+
209
+ // inner shapes
210
+ if (ip.vb == VOL && order_face[0][0] >= 3)
211
+ {
212
+ IVec<4> f = GetVertexOrientedFace (0);
213
+ TrigOrthoPol::Eval(order_face[0][0]-3,
214
+ lam[f[0]], lam[f[1]], shape+ii);
215
+ }
216
+ }
217
+
218
+ #ifdef NONE
219
+ template<>
220
+ inline void H1HighOrderFE_Shape<ET_TRIG> ::CalcDualShape2 (const BaseMappedIntegrationPoint & mip, SliceVector<> shape) const
221
+ {
222
+ auto & ip = mip.IP();
223
+ shape = 0.0;
224
+ double lam[3] = { ip(0), ip(1), 1-ip(0)-ip(1) };
225
+ size_t ii = 3;
226
+
227
+ if (ip.VB() == BBND)
228
+ {
229
+ for (size_t i = 0; i < 3; i++)
230
+ shape[i] = (i == ip.FacetNr()) ? 1 : 0;
231
+ }
232
+
233
+
234
+ // edge-based shapes
235
+ for (int i = 0; i < N_EDGE; i++)
236
+ if (order_edge[i] >= 2)
237
+ {
238
+ if (ip.VB() == BND && ip.FacetNr() == i)
239
+ {
240
+ IVec<2> e = GetVertexOrientedEdge(i);
241
+ EdgeOrthoPol::
242
+ EvalScaledMult (order_edge[i]-2,
243
+ lam[e[1]]-lam[e[0]], lam[e[0]]+lam[e[1]],
244
+ 1.0/mip.GetMeasure() /* *lam[e[0]]*lam[e[1]]*/, shape+ii);
245
+ }
246
+ ii += order_edge[i]-1;
247
+ }
248
+
249
+ // inner shapes
250
+ if (ip.VB() == VOL && order_face[0][0] >= 3)
251
+ {
252
+ IVec<4> f = GetVertexOrientedFace (0);
253
+ TrigOrthoPol::EvalMult(order_face[0][0]-3,
254
+ lam[f[0]], lam[f[1]],1.0/mip.GetMeasure(), shape+ii);
255
+ }
256
+ }
257
+ #endif
258
+
259
+ /* *********************** Quadrilateral **********************/
260
+
261
+ template<> template<typename Tx, typename TFA>
262
+ void H1HighOrderFE_Shape<ET_QUAD> :: T_CalcShape (TIP<2,Tx> ip, TFA & shape) const
263
+ {
264
+ Tx x = ip.x, y = ip.y;
265
+ Tx hx[2] = { x, y };
266
+ Tx lam[4] = {(1-x)*(1-y),x*(1-y),x*y,(1-x)*y};
267
+
268
+ // vertex shapes
269
+ for(int i=0; i < N_VERTEX; i++) shape[i] = lam[i];
270
+ int ii = 4;
271
+
272
+ // edge-based shapes
273
+ for (int i = 0; i < N_EDGE; i++)
274
+ if (order_edge[i] >= 2)
275
+ {
276
+ int p = order_edge[i];
277
+
278
+ Tx xi = ET_trait<ET_QUAD>::XiEdge(i, hx, this->vnums);
279
+ Tx lam_e = ET_trait<ET_QUAD>::LamEdge(i, hx);
280
+
281
+ Tx bub = 0.25 * lam_e * (1 - xi*xi);
282
+ EdgeOrthoPol::EvalMult (p-2, xi, bub, shape+ii);
283
+ ii += p-1;
284
+ }
285
+
286
+ // inner shapes
287
+ IVec<2> p = order_face[0];
288
+ if (p[0] >= 2 && p[1] >= 2)
289
+ {
290
+ Vec<2,Tx> xi = ET_trait<ET_QUAD>::XiFace(0, hx, this->vnums);
291
+
292
+ Tx bub = 1.0/16 * (1-xi(0)*xi(0))*(1-xi(1)*xi(1));
293
+
294
+ /*
295
+ ArrayMem<Tx,20> polxi(order+1), poleta(order+1);
296
+
297
+ LegendrePolynomial::EvalMult(p[0]-2, xi(0), bub, polxi);
298
+ LegendrePolynomial::Eval(p[1]-2, xi(1), poleta);
299
+
300
+ for (int k = 0; k <= p[0]-2; k++)
301
+ for (int j = 0; j <= p[1]-2; j++)
302
+ shape[ii++] = polxi[k] * poleta[j];
303
+ */
304
+
305
+ QuadOrthoPol::EvalMult1Assign(p[0]-2, xi(0), bub,
306
+ SBLambda ([&](int i, Tx val) LAMBDA_INLINE
307
+ {
308
+ QuadOrthoPol::EvalMult (p[1]-2, xi(1), val, shape+ii);
309
+ ii += p[1]-1;
310
+ }));
311
+ }
312
+ }
313
+
314
+ template<> template<typename Tx, typename TFA>
315
+ void H1HighOrderFE_Shape<ET_QUAD> :: T_CalcDualShape (TIP<2,Tx> ip, TFA & shape) const
316
+ {
317
+ Tx x = ip.x, y = ip.y;
318
+ Tx hx[2] = { x, y };
319
+ size_t ii = 4;
320
+ /*
321
+ auto & ip = mip.IP();
322
+ shape = 0.0;
323
+ double hx[2] = { ip(0), ip(1) };
324
+ */
325
+
326
+ if (ip.vb == BBND)
327
+ {
328
+ shape[ip.facetnr] = 1.0;
329
+ return;
330
+ }
331
+
332
+ // edge-based shapes
333
+ for (int i = 0; i < N_EDGE; i++)
334
+ if (order_edge[i] >= 2)
335
+ {
336
+ if (ip.vb == BND && ip.facetnr == i)
337
+ {
338
+ auto xi = ET_trait<ET_QUAD>::XiEdge(i, hx, this->vnums);
339
+ EdgeOrthoPol::Eval (order_edge[i]-2, xi, shape+ii);
340
+ }
341
+ ii += order_edge[i]-1;
342
+ }
343
+
344
+ IVec<2> p = order_face[0];
345
+ if (ip.vb == VOL && p[0] >= 2 && p[1] >= 2)
346
+ {
347
+ auto xi = ET_trait<ET_QUAD>::XiFace(0, hx, this->vnums);
348
+
349
+ QuadOrthoPol::Eval1Assign(p[0]-2, xi(0),
350
+ SBLambda ([&](int i, auto val) LAMBDA_INLINE
351
+ {
352
+ QuadOrthoPol::EvalMult (p[1]-2, xi(1), val, shape+ii);
353
+ ii += p[1]-1;
354
+ }));
355
+ }
356
+ }
357
+
358
+ #ifdef FILE_H1HOFE_TRIG_CPP
359
+ template <>
360
+ bool H1HighOrderFE_Shape<ET_TRIG> :: GetDiagDualityMassInverse2 (FlatVector<> diag) const
361
+ {
362
+ diag.Range(0,3) = 1.0;
363
+ int ii = 3;
364
+ for (int i = 0; i < N_EDGE; i++)
365
+ for (int j = 2; j <= order_edge[i]; j++)
366
+ diag(ii++) = (2*j-1)*(2*j)*(2*j-2);
367
+ IVec<2> p = order_face[0];
368
+ for (int i = 0; i <= p[0]-3; i++)
369
+ for (int j = 0; j <= p[0]-i-3; j++)
370
+ diag(ii++) = 0.5*(5+2*i+2*j)*(4+2*i+j)*(j+1) * (2*i+3)*(2*i+4) / (i+1);
371
+ // cout << "trig duality diag = " << diag << endl;
372
+ return true;
373
+ }
374
+ #endif
375
+
376
+
377
+ #ifdef FILE_H1HOFE_CPP
378
+
379
+ template <>
380
+ bool H1HighOrderFE_Shape<ET_QUAD> :: GetDiagDualityMassInverse2 (FlatVector<> diag) const
381
+ {
382
+ diag.Range(0,4) = 1.0;
383
+ int ii = 4;
384
+ for (int i = 0; i < N_EDGE; i++)
385
+ for (int j = 2; j <= order_edge[i]; j++)
386
+ diag(ii++) = (2*j-1)*(2*j)*(2*j-2);
387
+ IVec<2> p = order_face[0];
388
+ for (int i = 2; i <= p[0]; i++)
389
+ for (int j = 2; j <= p[1]; j++)
390
+ diag(ii++) = 1.0*(2*j-1)*(2*j)*(2*j-2) * (2*i-1)*(2*i)*(2*i-2);
391
+
392
+ // cout << "quad duality diag = " << diag << endl;
393
+ return true;
394
+ }
395
+
396
+
397
+ template <>
398
+ bool H1HighOrderFE_Shape<ET_TET> :: GetDiagDualityMassInverse2 (FlatVector<> diag) const
399
+ {
400
+ diag.Range(0,4) = 1.0;
401
+ int ii = 4;
402
+ for (int i = 0; i < N_EDGE; i++)
403
+ for (int j = 2; j <= order_edge[i]; j++)
404
+ diag(ii++) = (2*j-1)*(2*j)*(2*j-2);
405
+ for (int f = 0; f < N_FACE; f++)
406
+ if (int p = order_face[f][0]; p >= 3)
407
+ ii += DubinerBasisOrthoBub::CalcNormInv (p-3, diag+ii);
408
+ if (int p = order_cell[0][0]; p >= 4)
409
+ DubinerBasis3DOrthoBub::CalcNormInv(p-4, diag+ii);
410
+ return true;
411
+ }
412
+
413
+
414
+
415
+ template <>
416
+ bool H1HighOrderFE_Shape<ET_HEX> :: GetDiagDualityMassInverse2 (FlatVector<> diag) const
417
+ {
418
+ diag.Range(0,8) = 1.0;
419
+ int ii = 8;
420
+ for (int i = 0; i < N_EDGE; i++)
421
+ for (int j = 2; j <= order_edge[i]; j++)
422
+ diag(ii++) = (2*j-1)*(2*j)*(2*j-2);
423
+ for (int f = 0; f < N_FACE; f++)
424
+ {
425
+ IVec<2> p = order_face[f];
426
+ for (int i = 2; i <= p[0]; i++)
427
+ for (int j = 2; j <= p[1]; j++)
428
+ diag(ii++) = 1.0*(2*j-1)*(2*j)*(2*j-2) * (2*i-1)*(2*i)*(2*i-2);
429
+ }
430
+ IVec<3> p = order_cell[0];
431
+ for (int i = 2; i <= p[0]; i++)
432
+ for (int j = 2; j <= p[1]; j++)
433
+ for (int k = 2; k <= p[2]; k++)
434
+ diag(ii++) = 1.0*(2*j-1)*(2*j)*(2*j-2) * (2*i-1)*(2*i)*(2*i-2) * (2*k-1)*(2*k)*(2*k-2);
435
+
436
+ return true;
437
+ }
438
+ #endif
439
+
440
+ #ifdef NONE
441
+ template<>
442
+ inline void H1HighOrderFE_Shape<ET_QUAD> ::CalcDualShape2 (const BaseMappedIntegrationPoint & mip, SliceVector<> shape) const
443
+ {
444
+ auto & ip = mip.IP();
445
+ shape = 0.0;
446
+ size_t ii = 4;
447
+ double hx[2] = { ip(0), ip(1) };
448
+
449
+ if (ip.VB() == BBND)
450
+ {
451
+ for (size_t i = 0; i < 4; i++)
452
+ shape[i] = (i == ip.FacetNr()) ? 1 : 0;
453
+ }
454
+
455
+
456
+ // edge-based shapes
457
+ for (int i = 0; i < N_EDGE; i++)
458
+ if (order_edge[i] >= 2)
459
+ {
460
+ if (ip.VB() == BND && ip.FacetNr() == i)
461
+ {
462
+ auto xi = ET_trait<ET_QUAD>::XiEdge(i, hx, this->vnums);
463
+
464
+ EdgeOrthoPol::EvalMult (order_edge[i]-2, xi, 1.0/mip.GetMeasure(), shape+ii);
465
+ }
466
+ ii += order_edge[i]-1;
467
+ }
468
+
469
+ IVec<2> p = order_face[0];
470
+ if (ip.VB() == VOL && p[0] >= 2 && p[1] >= 2)
471
+ {
472
+ Vec<2,double> xi = ET_trait<ET_QUAD>::XiFace(0, hx, this->vnums);
473
+
474
+ QuadOrthoPol::EvalMult1Assign(p[0]-2, xi(0), 1.0/mip.GetMeasure(),
475
+ SBLambda ([&](int i, auto val) LAMBDA_INLINE
476
+ {
477
+ QuadOrthoPol::EvalMult (p[1]-2, xi(1), val, shape+ii);
478
+ ii += p[1]-1;
479
+ }));
480
+ }
481
+ }
482
+ #endif
483
+
484
+
485
+ /* *********************** Tetrahedron **********************/
486
+
487
+ template<> template<typename Tx, typename TFA>
488
+ INLINE void H1HighOrderFE_Shape<ET_TET> :: T_CalcShape (TIP<3,Tx> ip, TFA & shape) const
489
+ {
490
+ Tx lam[4] = { ip.x, ip.y, ip.z, 1-ip.x-ip.y-ip.z };
491
+
492
+ // vertex shapes
493
+ //for (int i = 0; i < 4; i++) shape[i] = lam[i];
494
+ if (!nodalp2)
495
+ for (int i = 0; i < 4; i++)
496
+ shape[i] = lam[i];
497
+ else
498
+ for (int i = 0; i < 4; i++)
499
+ shape[i] = 0.25*lam[i]*(2*lam[i]-1);
500
+
501
+ int ii = 4;
502
+
503
+ // edge dofs
504
+ if(!nodalp2) {
505
+ for (int i = 0; i < N_EDGE; i++)
506
+ if (order_edge[i] >= 2)
507
+ {
508
+ // IVec<2> e = GetEdgeSort (i, vnums);
509
+ IVec<2> e = GetVertexOrientedEdge (i);
510
+ EdgeOrthoPol::EvalScaledMult (order_edge[i]-2,
511
+ lam[e[1]]-lam[e[0]], lam[e[0]]+lam[e[1]],
512
+ lam[e[0]]*lam[e[1]], shape+ii);
513
+ ii += order_edge[i]-1;
514
+ }
515
+ }
516
+ else {
517
+ for (int i = 0; i < N_EDGE; i++)
518
+ if (order_edge[i] >= 2)
519
+ {
520
+ // IVec<2> e = GetEdgeSort (i, vnums);
521
+ IVec<2> e = GetVertexOrientedEdge (i);
522
+ LegendrePolynomial::EvalScaledMult (order_edge[i]-2,
523
+ lam[e[1]]-lam[e[0]], lam[e[0]]+lam[e[1]],
524
+ lam[e[0]]*lam[e[1]], shape+ii);
525
+ ii += order_edge[i]-1;
526
+ }
527
+ }
528
+
529
+ // face dofs
530
+ for (int i = 0; i < N_FACE; i++)
531
+ if (order_face[i][0] >= 3)
532
+ {
533
+ // IVec<4> f = GetFaceSort (i, vnums);
534
+ IVec<4> f = GetVertexOrientedFace (i);
535
+ int vop = 6 - f[0] - f[1] - f[2];
536
+
537
+ int p = order_face[i][0];
538
+ TrigOrthoPol::EvalScaledMult (p-3, lam[f[0]], lam[f[1]], 1-lam[vop],
539
+ lam[f[0]]*lam[f[1]]*lam[f[2]], shape+ii);
540
+ ii += (p-2)*(p-1)/2;
541
+ }
542
+
543
+ // interior shapes
544
+ if (order_cell[0][0] >= 4)
545
+
546
+ DubinerBasis3DOrthoBub::EvalMult
547
+ (order_cell[0][0]-4, lam[0], lam[1], lam[2],
548
+ lam[0]*lam[1]*lam[2]*lam[3], shape+ii);
549
+
550
+ // if (order_cell[0][0] >= 4)
551
+ // ii += TetShapesInnerLegendre::
552
+ // Calc (order_cell[0][0],
553
+ // lam[0]-lam[3], lam[1], lam[2],
554
+ // shape+ii);
555
+ }
556
+
557
+ #ifdef NONE
558
+ template<>
559
+ inline void H1HighOrderFE_Shape<ET_TET> ::
560
+ CalcDualShape2 (const BaseMappedIntegrationPoint & mip, SliceVector<> shape) const
561
+ {
562
+ auto & ip = mip.IP();
563
+ shape = 0.0;
564
+ double lam[4] = { ip(0), ip(1), ip(2), 1-ip(0)-ip(1)-ip(2) };
565
+ size_t ii = 4;
566
+
567
+ if (ip.VB() == BBBND)
568
+ {
569
+ for (size_t i = 0; i < 4; i++)
570
+ shape[i] = (i == ip.FacetNr()) ? 1 : 0;
571
+ }
572
+ // edge-based shapes
573
+ for (int i = 0; i < N_EDGE; i++)
574
+ {
575
+ if (order_edge[i] >= 2 && ip.FacetNr() == i && ip.VB() == BBND)
576
+ {
577
+ IVec<2> e = GetVertexOrientedEdge(i);
578
+ EdgeOrthoPol::
579
+ EvalScaledMult (order_edge[i]-2,
580
+ lam[e[1]]-lam[e[0]], lam[e[0]]+lam[e[1]],
581
+ 1.0/mip.GetMeasure() /* *lam[e[0]]*lam[e[1]] */, shape+ii);
582
+ }
583
+
584
+ ii += order_edge[i]-1;
585
+ }
586
+ // face shapes
587
+ for (int i = 0; i < N_FACE; i++)
588
+ {
589
+ if (order_face[i][0] >= 3 && ip.FacetNr() == i && ip.VB() == BND)
590
+ {
591
+ IVec<4> f = GetVertexOrientedFace (i);
592
+ TrigOrthoPol::EvalMult (order_face[i][0]-3,
593
+ lam[f[0]], lam[f[1]], 1.0/mip.GetMeasure(), shape+ii);
594
+ }
595
+ ii += (order_face[i][0]-2)*(order_face[i][0]-1)/2;
596
+ }
597
+ //inner shapes
598
+ if (ip.VB() == VOL && order_cell[0][0] >= 4)
599
+ DubinerBasis3DOrthoBub::EvalMult (order_cell[0][0]-4, lam[0], lam[1], lam[2], 1.0/mip.GetMeasure(), shape+ii);
600
+ }
601
+ #endif
602
+
603
+
604
+ template<> template<typename Tx, typename TFA>
605
+ void H1HighOrderFE_Shape<ET_TET> :: T_CalcDualShape (TIP<3,Tx> ip, TFA & shape) const
606
+ {
607
+ Tx lam[4] = { ip.x, ip.y, ip.z, 1-ip.x-ip.y-ip.z };
608
+ size_t ii = 4;
609
+
610
+ if (ip.vb == BBBND)
611
+ {
612
+ shape[ip.facetnr] = 1;
613
+ return;
614
+ }
615
+
616
+ // edge-based shapes
617
+ for (int i = 0; i < N_EDGE; i++)
618
+ if (int p = order_edge[i]; p >= 2)
619
+ {
620
+ if (ip.facetnr == i && ip.vb == BBND)
621
+ {
622
+ IVec<2> e = GetVertexOrientedEdge(i);
623
+ EdgeOrthoPol::
624
+ EvalScaled (p-2,
625
+ lam[e[1]]-lam[e[0]], lam[e[0]]+lam[e[1]],
626
+ shape+ii);
627
+ return;
628
+ }
629
+ ii += p-1;
630
+ }
631
+
632
+ // face shapes
633
+ for (int i = 0; i < N_FACE; i++)
634
+ if (int p = order_face[i][0]; p >= 3)
635
+ {
636
+ if (ip.facetnr == i && ip.vb == BND)
637
+ {
638
+ IVec<4> f = GetVertexOrientedFace (i);
639
+ TrigOrthoPol::Eval (p-3, lam[f[0]], lam[f[1]], shape+ii);
640
+ return;
641
+ }
642
+ ii += (p-2)*(p-1)/2;
643
+ }
644
+
645
+ //inner shapes
646
+ if (ip.vb == VOL && order_cell[0][0] >= 4)
647
+ DubinerBasis3DOrthoBub::Eval (order_cell[0][0]-4, lam[0], lam[1], lam[2], shape+ii);
648
+ }
649
+
650
+
651
+
652
+
653
+ /* *********************** Prism **********************/
654
+
655
+ template<> template<typename Tx, typename TFA>
656
+ void H1HighOrderFE_Shape<ET_PRISM> :: T_CalcShape (TIP<3,Tx> ip, TFA & shape) const
657
+ {
658
+ Tx x = ip.x, y = ip.y, z = ip.z;
659
+ Tx lam[6] = { x, y, 1-x-y, x, y, 1-x-y };
660
+ Tx muz[6] = { 1-z, 1-z, 1-z, z, z, z };
661
+
662
+ Tx sigma[6];
663
+ for (int i = 0; i < 6; i++) sigma[i] = lam[i] + muz[i];
664
+
665
+ // vertex shapes
666
+ for (int i = 0; i < 6; i++) shape[i] = lam[i] * muz[i];
667
+
668
+ int ii = 6;
669
+
670
+ // horizontal edge dofs
671
+ for (int i = 0; i < 6; i++)
672
+ if (order_edge[i] >= 2)
673
+ {
674
+ // IVec<2> e = GetEdgeSort (i, vnums);
675
+ IVec<2> e = GetVertexOrientedEdge (i);
676
+
677
+ Tx xi = lam[e[1]]-lam[e[0]];
678
+ Tx eta = lam[e[0]]+lam[e[1]];
679
+ Tx bub = lam[e[0]]*lam[e[1]]*muz[e[1]];
680
+
681
+ EdgeOrthoPol::
682
+ EvalScaledMult (order_edge[i]-2, xi, eta, bub, shape+ii);
683
+ ii += order_edge[i]-1;
684
+ }
685
+
686
+ // vertical edges
687
+ for (int i = 6; i < 9; i++)
688
+ if (order_edge[i] >= 2)
689
+ {
690
+ // IVec<2> e = GetEdgeSort (i, vnums);
691
+ IVec<2> e = GetVertexOrientedEdge (i);
692
+
693
+ EdgeOrthoPol::
694
+ EvalMult (order_edge[i]-2,
695
+ muz[e[1]]-muz[e[0]],
696
+ muz[e[0]]*muz[e[1]]*lam[e[1]], shape+ii);
697
+
698
+ ii += order_edge[i]-1;
699
+ }
700
+
701
+
702
+ ArrayMem<Tx,20> polx(order+1), poly(order+1), polz(order+1);
703
+
704
+ // trig face dofs
705
+ for (int i = 0; i < 2; i++)
706
+ if (order_face[i][0] >= 3)
707
+ {
708
+ // IVec<4> f = GetFaceSort (i, vnums);
709
+ IVec<4> f = GetVertexOrientedFace (i);
710
+ int p = order_face[i][0];
711
+
712
+ Tx bub = lam[0]*lam[1]*lam[2]*muz[f[2]];
713
+
714
+ TrigOrthoPol::
715
+ EvalMult (p-3, lam[f[0]], lam[f[1]], bub, shape+ii);
716
+
717
+ ii += (p-2)*(p-1)/2;
718
+ }
719
+
720
+ // quad face dofs
721
+ for (int i = 2; i < 5; i++)
722
+ if (order_face[i][0] >= 2 && order_face[i][1] >= 2)
723
+ {
724
+ IVec<2> p = order_face[i];
725
+ // IVec<4> f = GetFaceSort (i, vnums);
726
+ IVec<4> f = GetVertexOrientedFace (i);
727
+
728
+ Tx xi = sigma[f[0]] - sigma[f[1]];
729
+ Tx eta = sigma[f[0]] - sigma[f[3]];
730
+
731
+ Tx scalexi(1.0), scaleeta(1.0);
732
+ if (f[0] / 3 == f[1] / 3)
733
+ scalexi = lam[f[0]]+lam[f[1]]; // xi is horizontal
734
+ else
735
+ scaleeta = lam[f[0]]+lam[f[3]];
736
+
737
+ Tx bub = (1.0/16)*(scaleeta*scaleeta-eta*eta)*(scalexi*scalexi-xi*xi);
738
+ QuadOrthoPol::EvalScaled (p[0]-2, xi, scalexi, polx);
739
+ QuadOrthoPol::EvalScaledMult (p[1]-2, eta, scaleeta, bub, poly);
740
+
741
+ for (int k = 0; k < p[0]-1; k++)
742
+ for (int j = 0; j < p[1]-1; j++)
743
+ shape[ii++] = polx[k] * poly[j];
744
+ }
745
+
746
+ // volume dofs:
747
+ IVec<3> p = order_cell[0];
748
+ if (p[0] > 2 && p[2] > 1)
749
+ {
750
+ int nf = (p[0]-1)*(p[0]-2)/2;
751
+ ArrayMem<Tx,20> pol_trig(nf);
752
+
753
+ DubinerBasis::EvalMult (p[0]-3, x, y, x*y*(1-x-y),pol_trig);
754
+ LegendrePolynomial::EvalMult (p[2]-2, 2*z-1, z*(1-z), polz);
755
+
756
+ for (int i = 0; i < nf; i++)
757
+ for (int k = 0; k < p[2]-1; k++)
758
+ shape[ii++] = pol_trig[i] * polz[k];
759
+ }
760
+ }
761
+
762
+ template<> template<typename Tx, typename TFA>
763
+ void H1HighOrderFE_Shape<ET_PRISM> :: T_CalcDualShape (TIP<3,Tx> ip, TFA & shape) const
764
+ {
765
+ // auto & ip = mip.IP();
766
+ // shape = 0.0;
767
+
768
+ if(order > 1)
769
+ throw Exception("H1Ho prism dual shapes only implemented for order==1!");
770
+
771
+ if(ip.vb == BBBND)
772
+ {
773
+ shape[ip.facetnr] = 1;
774
+ return;
775
+ }
776
+ }
777
+
778
+ #ifdef NONE
779
+ template<>
780
+ inline void H1HighOrderFE_Shape<ET_PRISM> ::
781
+ CalcDualShape2 (const BaseMappedIntegrationPoint & mip, SliceVector<> shape) const
782
+ {
783
+ auto & ip = mip.IP();
784
+ shape = 0.0;
785
+
786
+ if(order > 1)
787
+ throw Exception("H1Ho prism dual shapes only implemented for order==1!");
788
+
789
+ if(ip.VB() == BBBND)
790
+ for(auto i : Range(6))
791
+ shape[i] = (i == ip.FacetNr()) ? 1 : 0;
792
+
793
+ }
794
+ #endif
795
+
796
+
797
+ /* *********************** Hex **********************/
798
+
799
+ template<> template<typename Tx, typename TFA>
800
+ void H1HighOrderFE_Shape<ET_HEX> :: T_CalcShape (TIP<3,Tx> ip, TFA & shape) const
801
+ {
802
+ Tx x = ip.x, y = ip.y, z = ip.z;
803
+
804
+ Tx lam[8]={(1-x)*(1-y)*(1-z),x*(1-y)*(1-z),x*y*(1-z),(1-x)*y*(1-z),
805
+ (1-x)*(1-y)*z,x*(1-y)*z,x*y*z,(1-x)*y*z};
806
+ Tx sigma[8]={(1-x)+(1-y)+(1-z),x+(1-y)+(1-z),x+y+(1-z),(1-x)+y+(1-z),
807
+ (1-x)+(1-y)+z,x+(1-y)+z,x+y+z,(1-x)+y+z};
808
+
809
+ // vertex shapes
810
+ for (int i = 0; i < 8; i++) shape[i] = lam[i];
811
+ int ii = 8;
812
+
813
+ ArrayMem<Tx,30> polx(order+1), poly(order+1), polz(order+1);
814
+
815
+ // edge dofs
816
+ for (int i = 0; i < N_EDGE; i++)
817
+ if (order_edge[i] >= 2)
818
+ {
819
+ int p = order_edge[i];
820
+
821
+ // IVec<2> e = GetEdgeSort (i, vnums);
822
+ IVec<2> e = GetVertexOrientedEdge (i);
823
+ Tx xi = sigma[e[1]]-sigma[e[0]];
824
+ Tx lam_e = lam[e[0]]+lam[e[1]];
825
+ Tx bub = 0.25 * lam_e * (1 - xi*xi);
826
+
827
+ EdgeOrthoPol::EvalMult (p-2, xi, bub, shape+ii);
828
+ ii += p-1;
829
+ }
830
+
831
+ for (int i = 0; i < N_FACE; i++)
832
+ if (order_face[i][0] >= 2 && order_face[i][1] >= 2)
833
+ {
834
+ IVec<2> p = order_face[i];
835
+ // IVec<4> f = GetFaceSort (i, vnums);
836
+ IVec<4> f = GetVertexOrientedFace (i);
837
+ Tx lam_f(0.0);
838
+ for (int j = 0; j < 4; j++) lam_f += lam[f[j]];
839
+
840
+ Tx xi = sigma[f[0]] - sigma[f[1]];
841
+ Tx eta = sigma[f[0]] - sigma[f[3]];
842
+
843
+ Tx bub = 1.0/16 * (1-xi*xi)*(1-eta*eta) * lam_f;
844
+ QuadOrthoPol::EvalMult(p[0]-2, xi, bub, polx);
845
+ QuadOrthoPol::Eval(p[1]-2, eta, poly);
846
+
847
+ for (int k = 0; k < p[0]-1; k++)
848
+ for (int j = 0; j < p[1]-1; j++)
849
+ shape[ii++]= polx[k] * poly[j];
850
+ }
851
+
852
+ // volume dofs:
853
+ IVec<3> p = order_cell[0];
854
+ if (p[0] >= 2 && p[1] >= 2 && p[2] >= 2)
855
+ {
856
+ QuadOrthoPol::EvalMult (p[0]-2, 2*x-1, x*(1-x), polx);
857
+ QuadOrthoPol::EvalMult (p[1]-2, 2*y-1, y*(1-y), poly);
858
+ QuadOrthoPol::EvalMult (p[2]-2, 2*z-1, z*(1-z), polz);
859
+
860
+ for (int i = 0; i < p[0]-1; i++)
861
+ for (int j = 0; j < p[1]-1; j++)
862
+ {
863
+ Tx pxy = polx[i] * poly[j];
864
+ for (int k = 0; k < p[2]-1; k++)
865
+ shape[ii++] = pxy * polz[k];
866
+ }
867
+ }
868
+ }
869
+
870
+
871
+ template<> template<typename Tx, typename TFA>
872
+ void H1HighOrderFE_Shape<ET_HEX> :: T_CalcDualShape (TIP<3,Tx> ip, TFA & shape) const
873
+ {
874
+ Tx x = ip.x, y = ip.y, z = ip.z;
875
+ Tx sigma[8]={(1-x)+(1-y)+(1-z),x+(1-y)+(1-z),x+y+(1-z),(1-x)+y+(1-z),
876
+ (1-x)+(1-y)+z,x+(1-y)+z,x+y+z,(1-x)+y+z};
877
+
878
+
879
+ size_t ii = 8;
880
+
881
+ if (ip.vb == BBBND)
882
+ {
883
+ shape[ip.facetnr] = 1.0;
884
+ return;
885
+ }
886
+
887
+ // edge-based shapes
888
+ for (int i = 0; i < N_EDGE; i++)
889
+ if (order_edge[i] >= 2)
890
+ {
891
+ if (ip.vb == BBND && ip.facetnr == i)
892
+ {
893
+ // auto xi = ET_trait<ET_HEX>::XiEdge(i, hx, this->vnums);
894
+ IVec<2> e = GetVertexOrientedEdge (i);
895
+ Tx xi = sigma[e[1]]-sigma[e[0]];
896
+
897
+ EdgeOrthoPol::Eval (order_edge[i]-2, xi, shape+ii);
898
+ }
899
+ ii += order_edge[i]-1;
900
+ }
901
+
902
+ ArrayMem<Tx,30> polx(order+1), poly(order+1), polz(order+1);
903
+
904
+
905
+ for (int i = 0; i < N_FACE; i++)
906
+ {
907
+ IVec<2> p = order_face[0];
908
+ if (p[0] >= 2 && p[1] >= 2)
909
+ {
910
+ if (ip.vb == BND && ip.facetnr == i)
911
+ {
912
+ // auto xi = ET_trait<ET_HEX>::XiFace(0, hx, this->vnums);
913
+ IVec<4> f = GetVertexOrientedFace (i);
914
+ Tx xi = sigma[f[0]] - sigma[f[1]];
915
+ Tx eta = sigma[f[0]] - sigma[f[3]];
916
+ QuadOrthoPol::Eval(p[0]-2, xi, polx);
917
+ QuadOrthoPol::Eval(p[1]-2, eta, poly);
918
+
919
+ for (int k = 0; k < p[0]-1; k++)
920
+ for (int j = 0; j < p[1]-1; j++)
921
+ shape[ii++]= polx[k] * poly[j];
922
+ }
923
+ else
924
+ ii += (p[0]-1)*(p[1]-1);
925
+ }
926
+ }
927
+
928
+
929
+
930
+ // volume dofs:
931
+ if (ip.vb == VOL)
932
+ {
933
+ IVec<3> p = order_cell[0];
934
+ if (p[0] >= 2 && p[1] >= 2 && p[2] >= 2)
935
+ {
936
+ QuadOrthoPol::Eval (p[0]-2, 2*x-1, polx);
937
+ QuadOrthoPol::Eval (p[1]-2, 2*y-1, poly);
938
+ QuadOrthoPol::Eval (p[2]-2, 2*z-1, polz);
939
+
940
+ for (int i = 0; i < p[0]-1; i++)
941
+ for (int j = 0; j < p[1]-1; j++)
942
+ {
943
+ Tx pxy = polx[i] * poly[j];
944
+ for (int k = 0; k < p[2]-1; k++)
945
+ shape[ii++] = pxy * polz[k];
946
+ }
947
+ }
948
+ }
949
+ }
950
+
951
+
952
+
953
+ /* ******************************** Pyramid ************************************ */
954
+
955
+ template<> template<typename Tx, typename TFA>
956
+ void H1HighOrderFE_Shape<ET_PYRAMID> :: T_CalcShape (TIP<3,Tx> ip, TFA & shape) const
957
+ {
958
+ Tx x = ip.x, y = ip.y, z = ip.z;
959
+
960
+ // if (z == 1.) z -= 1e-10;
961
+ z *= (1-1e-10);
962
+
963
+ Tx xt = x / (1-z);
964
+ Tx yt = y / (1-z);
965
+
966
+ Tx sigma[4] = { (1-xt)+(1-yt), xt+(1-yt), xt+yt, (1-xt)+yt };
967
+ Tx lambda[4] = { (1-xt)*(1-yt), xt*(1-yt), xt*yt, (1-xt)*yt };
968
+ Tx lambda3d[5];
969
+
970
+ for (int i = 0; i < 4; i++)
971
+ lambda3d[i] = lambda[i] * (1-z);
972
+ lambda3d[4] = z;
973
+
974
+
975
+ for (int i = 0; i < 5; i++)
976
+ shape[i] = lambda3d[i];
977
+
978
+ int ii = 5;
979
+
980
+
981
+ // horizontal edge dofs
982
+ for (int i = 0; i < 4; i++)
983
+ if (order_edge[i] >= 2)
984
+ {
985
+ int p = order_edge[i];
986
+ // IVec<2> e = GetEdgeSort (i, vnums);
987
+ IVec<2> e = GetVertexOrientedEdge (i);
988
+
989
+ Tx xi = sigma[e[1]]-sigma[e[0]];
990
+ Tx lam_e = lambda[e[0]]+lambda[e[1]];
991
+ Tx bub = 0.25 * lam_e * (1 - xi*xi)*(1-z)*(1-z);
992
+ Tx ximz = xi*(1-z);
993
+ EdgeOrthoPol::
994
+ EvalScaledMult (p-2, ximz, 1-z, bub, shape+ii);
995
+ ii += p-1;
996
+ }
997
+
998
+ // vertical edges
999
+ for (int i = 4; i < 8; i++)
1000
+ if (order_edge[i] >= 2)
1001
+ {
1002
+ int p = order_edge[i];
1003
+ // IVec<2> e = GetEdgeSort (i, vnums);
1004
+ IVec<2> e = GetVertexOrientedEdge (i);
1005
+
1006
+ Tx xi = lambda3d[e[1]]-lambda3d[e[0]];
1007
+ Tx lam_e = lambda3d[e[0]]+lambda3d[e[1]];
1008
+ Tx bub = 0.25 * (lam_e*lam_e-xi*xi);
1009
+
1010
+ EdgeOrthoPol::
1011
+ EvalScaledMult (p-2, xi, lam_e, bub, shape+ii);
1012
+ ii += p-1;
1013
+ }
1014
+
1015
+
1016
+ ArrayMem<Tx,20> polx(order+1), poly(order+1), polz(order+1);
1017
+ const FACE * faces = ElementTopology::GetFaces (ET_PYRAMID);
1018
+
1019
+ // trig face dofs
1020
+ for (int i = 0; i < 4; i++)
1021
+ if (order_face[i][0] >= 3)
1022
+ {
1023
+ int p = order_face[i][0];
1024
+ Tx lam_face = lambda[faces[i][0]] + lambda[faces[i][1]]; // vertices on quad
1025
+
1026
+ Tx bary[5] =
1027
+ {(sigma[0]-lam_face)*(1-z), (sigma[1]-lam_face)*(1-z),
1028
+ (sigma[2]-lam_face)*(1-z), (sigma[3]-lam_face)*(1-z), z };
1029
+
1030
+ // IVec<4> f = GetFaceSort (i, vnums);
1031
+ IVec<4> f = GetVertexOrientedFace (i);
1032
+
1033
+ Tx bub = lam_face * bary[f[0]]*bary[f[1]]*bary[f[2]];
1034
+
1035
+ TrigOrthoPol::
1036
+ EvalMult (p-3, bary[f[0]], bary[f[1]], bub, shape+ii);
1037
+ ii += (p-2)*(p-1)/2;
1038
+ }
1039
+
1040
+ // quad face dof
1041
+ if (order_face[4][0] >= 2 && order_face[4][1] >= 2)
1042
+ {
1043
+ IVec<2> p = order_face[4];
1044
+
1045
+ int pmax = max2(p[0], p[1]);
1046
+ Tx fac(1.0);
1047
+ for (int k = 1; k <= pmax; k++)
1048
+ fac *= (1-z);
1049
+
1050
+ // IVec<4> f = GetFaceSort (4, vnums);
1051
+ IVec<4> f = GetVertexOrientedFace (4);
1052
+
1053
+ Tx xi = sigma[f[0]] - sigma[f[1]];
1054
+ Tx eta = sigma[f[0]] - sigma[f[3]];
1055
+
1056
+ QuadOrthoPol::EvalMult (p[0]-2, xi, 0.25*(1-xi*xi), polx);
1057
+ QuadOrthoPol::EvalMult (p[1]-2, eta, 0.25*(1-eta*eta), poly);
1058
+ for (int k = 0; k < p[0]-1; k++)
1059
+ for (int j = 0; j < p[1]-1; j++)
1060
+ shape[ii++] = polx[k] * poly[j] * fac;
1061
+ }
1062
+
1063
+
1064
+ if (order_cell[0][0] >= 3)
1065
+ {
1066
+ LegendrePolynomial::EvalMult (order_cell[0][0]-2, 2*xt-1, xt*(1-xt), polx);
1067
+ LegendrePolynomial::EvalMult (order_cell[0][0]-2, 2*yt-1, yt*(1-yt), poly);
1068
+
1069
+ Tx pz = z*(1-z)*(1-z);
1070
+
1071
+ for(int k = 0; k <= order_cell[0][0]-3; k++)
1072
+ {
1073
+ for(int i = 0; i <= k; i++)
1074
+ {
1075
+ Tx bubpik = pz * polx[i];
1076
+ for (int j = 0; j <= k; j++)
1077
+ shape[ii++] = bubpik * poly[j];
1078
+ }
1079
+ pz *= 1-z;
1080
+ }
1081
+ }
1082
+ }
1083
+
1084
+
1085
+
1086
+ /* ******************************** Hexamid ************************************ */
1087
+
1088
+ template<> template<typename Tx, typename TFA>
1089
+ void H1HighOrderFE_Shape<ET_HEXAMID> :: T_CalcShape (TIP<3,Tx> ip, TFA & shape) const
1090
+ {
1091
+ Tx y = ip.y;
1092
+ Tx z = ip.z;
1093
+ // Tx den = (1-y)*(1-z);
1094
+ Tx den = (1-y*z);
1095
+ den += Tx(1e-12);
1096
+ Tx x = ip.x / den;
1097
+
1098
+ Tx lam[7] =
1099
+ {
1100
+ (1-x)*(1-y)*(1-z),
1101
+ ( x)*(1-y)*(1-z),
1102
+ ( x)*( y)*(1-z),
1103
+ (1-x)*( y)*(1-z),
1104
+ (1-x)*(1-y)*( z),
1105
+ ( x)*(1-y)*( z),
1106
+ ( y)*( z)
1107
+ };
1108
+
1109
+ Tx sigma[7] =
1110
+ {
1111
+ (1-x)+(1-y)+(1-z),
1112
+ ( x)+(1-y)+(1-z),
1113
+ ( x)+( y)+(1-z),
1114
+ (1-x)+( y)+(1-z),
1115
+ (1-x)+(1-y)+( z),
1116
+ ( x)+(1-y)+( z),
1117
+ ( y)+( z)
1118
+ };
1119
+
1120
+ Tx sigmayz[7] =
1121
+ {
1122
+ (1-y)+(1-z),
1123
+ (1-y)+(1-z),
1124
+ ( y)+(1-z),
1125
+ ( y)+(1-z),
1126
+ (1-y)+( z),
1127
+ (1-y)+( z),
1128
+ ( y)+( z)
1129
+ };
1130
+
1131
+ Tx lamf[6] =
1132
+ {
1133
+ 1-z, z,
1134
+ 1-y, x,
1135
+ y, 1-x
1136
+ };
1137
+
1138
+ for (int i = 0; i < 7; i++)
1139
+ shape[i] = lam[i];
1140
+ bool edge_between_quads[11] = {
1141
+ true, false, true, true,
1142
+ false, false, false, true,
1143
+ true, false, false
1144
+ };
1145
+
1146
+ /*
1147
+ Tx lam_etrig[11] = {
1148
+ Tx(0), 1-z, Tx(0), Tx(0),
1149
+ 1-y, 1-x, x, Tx(0),
1150
+ Tx(0), x, 1-x
1151
+ };
1152
+ */
1153
+
1154
+ Tx lam_equad[11] = {
1155
+ Tx(0), y, Tx(0), Tx(0),
1156
+ z, z, z, Tx(0),
1157
+ Tx(0), y, y
1158
+ };
1159
+
1160
+
1161
+
1162
+ int ii = 7;
1163
+
1164
+ for (int i = 0; i < N_EDGE; i++)
1165
+ if (int p = order_edge[i]; p >= 2)
1166
+ {
1167
+ IVec<2> e = GetVertexOrientedEdge (i);
1168
+ if (edge_between_quads[i])
1169
+ {
1170
+ Tx xi = sigma[e[1]]-sigma[e[0]];
1171
+ Tx lam_e = lam[e[0]]+lam[e[1]];
1172
+ Tx bub = 0.25 * lam_e * (1 - xi*xi);
1173
+ EdgeOrthoPol::EvalMult (p-2, xi, bub, shape+ii);
1174
+ }
1175
+ else
1176
+ {
1177
+ Tx lamq = lam_equad[i]+Tx(1e-12);
1178
+ Tx xi = (lam[e[1]]-lam[e[0]])/lamq;
1179
+ Tx lame = (lam[e[1]]+lam[e[0]]) / lamq;
1180
+ Tx bub = 0.25 * (lame*lame - xi*xi) * lamq;
1181
+ EdgeOrthoPol::EvalScaledMult (p-2, xi, lame, bub, shape+ii);
1182
+ }
1183
+ ii += p-1;
1184
+ }
1185
+
1186
+ Array<Tx> polx(order+3), poly(order+3), polz(order+3);
1187
+ for (int i = 0; i < N_FACE; i++)
1188
+ {
1189
+ IVec<2> p = order_face[i];
1190
+ if (order_face[i][0] >= 2)
1191
+ {
1192
+ IVec<4> f = GetVertexOrientedFace (i);
1193
+ if (f[3] >= 0)
1194
+ {
1195
+ Tx xi, eta;
1196
+ if (f.Contains(6))
1197
+ {
1198
+ xi = sigmayz[f[0]] - sigmayz[f[1]];
1199
+ eta = sigmayz[f[0]] - sigmayz[f[3]];
1200
+ }
1201
+ else
1202
+ {
1203
+ xi = sigma[f[0]] - sigma[f[1]];
1204
+ eta = sigma[f[0]] - sigma[f[3]];
1205
+ }
1206
+ /*
1207
+ Tx l0 = lam[f[0]], l1 = lam[f[1]], l3 = lam[f[3]];
1208
+ Tx xi = (l0-l1)/(l0+l1+Tx(1e-12));
1209
+ Tx eta = (l0-l3)/(l0+l3+Tx(1e-12));
1210
+ */
1211
+ // Tx lamface = lam[f[0]]+lam[f[1]]+lam[f[2]]+lam[f[3]];
1212
+ Tx lamface = lamf[i];
1213
+ QuadOrthoPol::EvalMult (p[0]-2, xi, 0.25*(1-xi*xi), polx);
1214
+ QuadOrthoPol::EvalMult (p[1]-2, eta, 0.25*(1-eta*eta), poly);
1215
+ for (int k = 0; k < p[0]-1; k++)
1216
+ for (int j = 0; j < p[1]-1; j++)
1217
+ shape[ii++] = polx[k] * poly[j] * lamface;
1218
+ }
1219
+ else
1220
+ {
1221
+ int p = order_face[i][0];
1222
+ if (p >= 3)
1223
+ {
1224
+ Tx lamface = lam[f[0]]+lam[f[1]]+lam[f[2]];
1225
+ lamface += Tx(1e-12);
1226
+ Tx xi = lam[f[0]]/lamface;
1227
+ Tx eta = lam[f[1]]/lamface;
1228
+ Tx zeta = lam[f[2]]/lamface;
1229
+ TrigOrthoPol::EvalMult (p-3, xi, eta, xi*eta*zeta*lamface, shape+ii);
1230
+ /*
1231
+ int vop = 6 - f[0] - f[1] - f[2];
1232
+ TrigOrthoPol::EvalScaledMult (p-3, lam[f[0]], lam[f[1]], 1-lam[vop],
1233
+ lam[f[0]]*lam[f[1]]*lam[f[2]], shape+ii);
1234
+ */
1235
+ ii += (p-2)*(p-1)/2;
1236
+ }
1237
+ }
1238
+ }
1239
+ }
1240
+
1241
+ // volume dofs:
1242
+ IVec<3> p = order_cell[0];
1243
+ if (p[0] >= 2 && p[1] >= 2 && p[2] >= 2)
1244
+ {
1245
+ QuadOrthoPol::EvalMult (p[0]-2, 2*x-1, x*(1-x), polx);
1246
+ QuadOrthoPol::EvalMult (p[1]-2, 2*y-1, y*(1-y), poly);
1247
+ QuadOrthoPol::EvalMult (p[2]-2, 2*z-1, z*(1-z), polz);
1248
+
1249
+ for (int i = 0; i < p[0]-1; i++)
1250
+ for (int j = 0; j < p[1]-1; j++)
1251
+ {
1252
+ Tx pxy = polx[i] * poly[j];
1253
+ for (int k = 0; k < p[2]-1; k++)
1254
+ shape[ii++] = pxy * polz[k];
1255
+ }
1256
+ }
1257
+
1258
+ // cout << "ii = " << ii << " =?= " << ndof << endl;
1259
+ }
1260
+
1261
+ }
1262
+ #endif