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.
- netgen/include/analytic_integrals.hpp +10 -0
- netgen/include/arnoldi.hpp +55 -0
- netgen/include/bandmatrix.hpp +334 -0
- netgen/include/basematrix.hpp +957 -0
- netgen/include/basevector.hpp +1268 -0
- netgen/include/bdbequations.hpp +2805 -0
- netgen/include/bdbintegrator.hpp +1660 -0
- netgen/include/bem_diffops.hpp +475 -0
- netgen/include/bessel.hpp +1064 -0
- netgen/include/bilinearform.hpp +963 -0
- netgen/include/bla.hpp +29 -0
- netgen/include/blockalloc.hpp +95 -0
- netgen/include/blockjacobi.hpp +328 -0
- netgen/include/bspline.hpp +116 -0
- netgen/include/calcinverse.hpp +141 -0
- netgen/include/cg.hpp +368 -0
- netgen/include/chebyshev.hpp +44 -0
- netgen/include/cholesky.hpp +720 -0
- netgen/include/clapack.h +7254 -0
- netgen/include/code_generation.hpp +296 -0
- netgen/include/coefficient.hpp +2033 -0
- netgen/include/coefficient_impl.hpp +19 -0
- netgen/include/coefficient_stdmath.hpp +167 -0
- netgen/include/commutingAMG.hpp +106 -0
- netgen/include/comp.hpp +79 -0
- netgen/include/compatibility.hpp +41 -0
- netgen/include/complex_wrapper.hpp +73 -0
- netgen/include/compressedfespace.hpp +110 -0
- netgen/include/contact.hpp +235 -0
- netgen/include/diagonalmatrix.hpp +154 -0
- netgen/include/differentialoperator.hpp +276 -0
- netgen/include/diffop.hpp +1286 -0
- netgen/include/diffop_impl.hpp +328 -0
- netgen/include/diffopwithfactor.hpp +123 -0
- netgen/include/discontinuous.hpp +84 -0
- netgen/include/dump.hpp +949 -0
- netgen/include/ectypes.hpp +121 -0
- netgen/include/eigen.hpp +60 -0
- netgen/include/eigensystem.hpp +18 -0
- netgen/include/elasticity_equations.hpp +595 -0
- netgen/include/elementbyelement.hpp +195 -0
- netgen/include/elementtopology.hpp +1760 -0
- netgen/include/elementtransformation.hpp +339 -0
- netgen/include/evalfunc.hpp +405 -0
- netgen/include/expr.hpp +1686 -0
- netgen/include/facetfe.hpp +175 -0
- netgen/include/facetfespace.hpp +180 -0
- netgen/include/facethofe.hpp +111 -0
- netgen/include/facetsurffespace.hpp +112 -0
- netgen/include/fe_interfaces.hpp +32 -0
- netgen/include/fem.hpp +87 -0
- netgen/include/fesconvert.hpp +14 -0
- netgen/include/fespace.hpp +1449 -0
- netgen/include/finiteelement.hpp +286 -0
- netgen/include/globalinterfacespace.hpp +77 -0
- netgen/include/globalspace.hpp +115 -0
- netgen/include/gridfunction.hpp +525 -0
- netgen/include/h1amg.hpp +124 -0
- netgen/include/h1hofe.hpp +188 -0
- netgen/include/h1hofe_impl.hpp +1262 -0
- netgen/include/h1hofefo.hpp +148 -0
- netgen/include/h1hofefo_impl.hpp +185 -0
- netgen/include/h1hofespace.hpp +167 -0
- netgen/include/h1lofe.hpp +1240 -0
- netgen/include/h1lumping.hpp +41 -0
- netgen/include/hcurl_equations.hpp +1381 -0
- netgen/include/hcurlcurlfe.hpp +2241 -0
- netgen/include/hcurlcurlfespace.hpp +78 -0
- netgen/include/hcurlfe.hpp +259 -0
- netgen/include/hcurlfe_utils.hpp +107 -0
- netgen/include/hcurlhdiv_dshape.hpp +857 -0
- netgen/include/hcurlhdivfes.hpp +308 -0
- netgen/include/hcurlhofe.hpp +175 -0
- netgen/include/hcurlhofe_impl.hpp +1871 -0
- netgen/include/hcurlhofespace.hpp +193 -0
- netgen/include/hcurllofe.hpp +1146 -0
- netgen/include/hdiv_equations.hpp +880 -0
- netgen/include/hdivdivfe.hpp +2923 -0
- netgen/include/hdivdivsurfacespace.hpp +76 -0
- netgen/include/hdivfe.hpp +206 -0
- netgen/include/hdivfe_utils.hpp +717 -0
- netgen/include/hdivfes.hpp +75 -0
- netgen/include/hdivhofe.hpp +447 -0
- netgen/include/hdivhofe_impl.hpp +1107 -0
- netgen/include/hdivhofefo.hpp +229 -0
- netgen/include/hdivhofespace.hpp +177 -0
- netgen/include/hdivhosurfacefespace.hpp +106 -0
- netgen/include/hdivlofe.hpp +773 -0
- netgen/include/hidden.hpp +74 -0
- netgen/include/householder.hpp +181 -0
- netgen/include/hypre_ams_precond.hpp +123 -0
- netgen/include/hypre_precond.hpp +73 -0
- netgen/include/integrator.hpp +2012 -0
- netgen/include/integratorcf.hpp +253 -0
- netgen/include/interpolate.hpp +49 -0
- netgen/include/intrule.hpp +2542 -0
- netgen/include/intrules_SauterSchwab.hpp +25 -0
- netgen/include/irspace.hpp +49 -0
- netgen/include/jacobi.hpp +153 -0
- netgen/include/kernels.hpp +762 -0
- netgen/include/l2hofe.hpp +194 -0
- netgen/include/l2hofe_impl.hpp +564 -0
- netgen/include/l2hofefo.hpp +542 -0
- netgen/include/l2hofespace.hpp +344 -0
- netgen/include/la.hpp +38 -0
- netgen/include/linearform.hpp +266 -0
- netgen/include/matrix.hpp +2140 -0
- netgen/include/memusage.hpp +41 -0
- netgen/include/meshaccess.hpp +1359 -0
- netgen/include/mgpre.hpp +204 -0
- netgen/include/mp_coefficient.hpp +145 -0
- netgen/include/mptools.hpp +2281 -0
- netgen/include/multigrid.hpp +42 -0
- netgen/include/multivector.hpp +447 -0
- netgen/include/mumpsinverse.hpp +187 -0
- netgen/include/mycomplex.hpp +361 -0
- netgen/include/ng_lapack.hpp +1661 -0
- netgen/include/ngblas.hpp +1232 -0
- netgen/include/ngs_defines.hpp +30 -0
- netgen/include/ngs_stdcpp_include.hpp +106 -0
- netgen/include/ngs_utils.hpp +121 -0
- netgen/include/ngsobject.hpp +1019 -0
- netgen/include/ngsstream.hpp +113 -0
- netgen/include/ngstd.hpp +72 -0
- netgen/include/nodalhofe.hpp +96 -0
- netgen/include/nodalhofe_impl.hpp +141 -0
- netgen/include/normalfacetfe.hpp +223 -0
- netgen/include/normalfacetfespace.hpp +98 -0
- netgen/include/normalfacetsurfacefespace.hpp +84 -0
- netgen/include/order.hpp +251 -0
- netgen/include/parallel_matrices.hpp +222 -0
- netgen/include/paralleldofs.hpp +340 -0
- netgen/include/parallelngs.hpp +23 -0
- netgen/include/parallelvector.hpp +269 -0
- netgen/include/pardisoinverse.hpp +200 -0
- netgen/include/periodic.hpp +129 -0
- netgen/include/plateaufespace.hpp +25 -0
- netgen/include/pml.hpp +275 -0
- netgen/include/pmltrafo.hpp +631 -0
- netgen/include/postproc.hpp +142 -0
- netgen/include/potentialtools.hpp +22 -0
- netgen/include/precomp.hpp +60 -0
- netgen/include/preconditioner.hpp +602 -0
- netgen/include/prolongation.hpp +377 -0
- netgen/include/python_comp.hpp +107 -0
- netgen/include/python_fem.hpp +89 -0
- netgen/include/python_linalg.hpp +58 -0
- netgen/include/python_ngstd.hpp +386 -0
- netgen/include/recursive_pol.hpp +4896 -0
- netgen/include/recursive_pol_tet.hpp +395 -0
- netgen/include/recursive_pol_trig.hpp +492 -0
- netgen/include/reorderedfespace.hpp +81 -0
- netgen/include/sample_sort.hpp +105 -0
- netgen/include/scalarfe.hpp +335 -0
- netgen/include/shapefunction_utils.hpp +113 -0
- netgen/include/simd_complex.hpp +329 -0
- netgen/include/smoother.hpp +253 -0
- netgen/include/solve.hpp +89 -0
- netgen/include/sparsecholesky.hpp +313 -0
- netgen/include/sparsematrix.hpp +1038 -0
- netgen/include/sparsematrix_dyn.hpp +90 -0
- netgen/include/sparsematrix_impl.hpp +1013 -0
- netgen/include/special_matrix.hpp +463 -0
- netgen/include/specialelement.hpp +125 -0
- netgen/include/statushandler.hpp +33 -0
- netgen/include/stringops.hpp +12 -0
- netgen/include/superluinverse.hpp +136 -0
- netgen/include/symbolicintegrator.hpp +850 -0
- netgen/include/symmetricmatrix.hpp +144 -0
- netgen/include/tangentialfacetfe.hpp +224 -0
- netgen/include/tangentialfacetfespace.hpp +91 -0
- netgen/include/tensor.hpp +522 -0
- netgen/include/tensorcoefficient.hpp +446 -0
- netgen/include/tensorproductintegrator.hpp +113 -0
- netgen/include/thcurlfe.hpp +128 -0
- netgen/include/thcurlfe_impl.hpp +380 -0
- netgen/include/thdivfe.hpp +80 -0
- netgen/include/thdivfe_impl.hpp +492 -0
- netgen/include/tpdiffop.hpp +461 -0
- netgen/include/tpfes.hpp +133 -0
- netgen/include/tpintrule.hpp +224 -0
- netgen/include/triangular.hpp +465 -0
- netgen/include/tscalarfe.hpp +245 -0
- netgen/include/tscalarfe_impl.hpp +1029 -0
- netgen/include/umfpackinverse.hpp +148 -0
- netgen/include/vector.hpp +1273 -0
- netgen/include/voxelcoefficientfunction.hpp +41 -0
- netgen/include/vtkoutput.hpp +198 -0
- netgen/include/vvector.hpp +208 -0
- netgen/include/webgui.hpp +92 -0
- netgen/libngbla.dylib +0 -0
- netgen/libngcomp.dylib +0 -0
- netgen/libngfem.dylib +0 -0
- netgen/libngla.dylib +0 -0
- netgen/libngsbem.dylib +0 -0
- netgen/libngsolve.dylib +0 -0
- netgen/libngstd.dylib +0 -0
- ngsolve/TensorProductTools.py +210 -0
- ngsolve/__console.py +94 -0
- ngsolve/__expr.py +181 -0
- ngsolve/__init__.py +148 -0
- ngsolve/__init__.pyi +233 -0
- ngsolve/_scikit_build_core_dependencies.py +30 -0
- ngsolve/bla.pyi +1153 -0
- ngsolve/bvp.py +78 -0
- ngsolve/bvp.pyi +32 -0
- ngsolve/cmake/NGSolveConfig.cmake +102 -0
- ngsolve/cmake/ngsolve-targets-release.cmake +79 -0
- ngsolve/cmake/ngsolve-targets.cmake +163 -0
- ngsolve/comp/__init__.pyi +5449 -0
- ngsolve/comp/pml.pyi +89 -0
- ngsolve/config/__init__.py +1 -0
- ngsolve/config/__init__.pyi +43 -0
- ngsolve/config/__main__.py +4 -0
- ngsolve/config/config.py +60 -0
- ngsolve/config/config.pyi +45 -0
- ngsolve/demos/TensorProduct/__init__.py +0 -0
- ngsolve/demos/TensorProduct/tp_dg_1d_1d.py +80 -0
- ngsolve/demos/TensorProduct/tp_dg_1d_2d.py +73 -0
- ngsolve/demos/TensorProduct/tp_dg_2d_1d.py +72 -0
- ngsolve/demos/TensorProduct/tp_dg_2d_2d.py +66 -0
- ngsolve/demos/__init__.py +0 -0
- ngsolve/demos/howto/__init__.py +0 -0
- ngsolve/demos/howto/hhj.py +44 -0
- ngsolve/demos/howto/hybrid_dg.py +53 -0
- ngsolve/demos/howto/mixed.py +30 -0
- ngsolve/demos/howto/nonlin.py +29 -0
- ngsolve/demos/howto/pickling.py +26 -0
- ngsolve/demos/howto/pml.py +31 -0
- ngsolve/demos/howto/taskmanager.py +20 -0
- ngsolve/demos/howto/tdnns.py +47 -0
- ngsolve/demos/howto/timeDG-skeleton.py +45 -0
- ngsolve/demos/howto/timeDG.py +38 -0
- ngsolve/demos/howto/timeDGlap.py +42 -0
- ngsolve/demos/howto/timeDGwave.py +61 -0
- ngsolve/demos/intro/__init__.py +0 -0
- ngsolve/demos/intro/adaptive.py +123 -0
- ngsolve/demos/intro/cmagnet.py +59 -0
- ngsolve/demos/intro/elasticity.py +76 -0
- ngsolve/demos/intro/navierstokes.py +74 -0
- ngsolve/demos/intro/poisson.ipynb +170 -0
- ngsolve/demos/intro/poisson.py +41 -0
- ngsolve/demos/mpi/__init__.py +0 -0
- ngsolve/demos/mpi/mpi_cmagnet.py +87 -0
- ngsolve/demos/mpi/mpi_navierstokes.py +117 -0
- ngsolve/demos/mpi/mpi_poisson.py +89 -0
- ngsolve/demos/mpi/mpi_timeDG.py +82 -0
- ngsolve/directsolvers.py +26 -0
- ngsolve/directsolvers.pyi +15 -0
- ngsolve/eigenvalues.py +364 -0
- ngsolve/eigenvalues.pyi +30 -0
- ngsolve/fem.pyi +1647 -0
- ngsolve/internal.py +89 -0
- ngsolve/krylovspace.py +1013 -0
- ngsolve/krylovspace.pyi +298 -0
- ngsolve/la.pyi +1230 -0
- ngsolve/meshes.py +748 -0
- ngsolve/ngs2petsc.py +310 -0
- ngsolve/ngscxx.py +42 -0
- ngsolve/ngslib.so +0 -0
- ngsolve/ngstd.pyi +59 -0
- ngsolve/nonlinearsolvers.py +203 -0
- ngsolve/nonlinearsolvers.pyi +95 -0
- ngsolve/preconditioners.py +11 -0
- ngsolve/preconditioners.pyi +7 -0
- ngsolve/solve.pyi +109 -0
- ngsolve/solve_implementation.py +168 -0
- ngsolve/solve_implementation.pyi +42 -0
- ngsolve/solvers.py +7 -0
- ngsolve/solvers.pyi +14 -0
- ngsolve/timestepping.py +185 -0
- ngsolve/timestepping.pyi +28 -0
- ngsolve/timing.py +108 -0
- ngsolve/timing.pyi +54 -0
- ngsolve/utils.py +167 -0
- ngsolve/utils.pyi +273 -0
- ngsolve/webgui.py +670 -0
- ngsolve-6.2.2506.post74.dev0.data/data/Netgen.icns +0 -0
- ngsolve-6.2.2506.post74.dev0.data/data/bin/ngscxx +17 -0
- ngsolve-6.2.2506.post74.dev0.data/data/bin/ngsld +13 -0
- ngsolve-6.2.2506.post74.dev0.data/data/bin/ngsolve.tcl +648 -0
- ngsolve-6.2.2506.post74.dev0.data/data/bin/ngspy +2 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/beam.geo +17 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/beam.vol +240 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/chip.in2d +41 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/chip.vol +614 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coil.geo +12 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coil.vol +2560 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coilshield.geo +24 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/coilshield.vol +3179 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/cube.geo +19 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/cube.vol +1832 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d10_DGdoubleglazing.pde +50 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d11_chip_nitsche.pde +40 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d1_square.pde +43 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d2_chip.pde +35 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d3_helmholtz.pde +22 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d4_cube.pde +46 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d5_beam.pde +74 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d6_shaft.pde +73 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d7_coil.pde +50 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d8_coilshield.pde +49 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/d9_hybridDG.pde +72 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/doubleglazing.in2d +27 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/doubleglazing.vol +737 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/piezo2d40round4.vol.gz +0 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/shaft.geo +73 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/shaft.vol +4291 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/square.in2d +17 -0
- ngsolve-6.2.2506.post74.dev0.data/data/share/ngsolve/square.vol +149 -0
- ngsolve-6.2.2506.post74.dev0.dist-info/METADATA +13 -0
- ngsolve-6.2.2506.post74.dev0.dist-info/RECORD +315 -0
- ngsolve-6.2.2506.post74.dev0.dist-info/WHEEL +5 -0
- ngsolve-6.2.2506.post74.dev0.dist-info/licenses/LICENSE +504 -0
- ngsolve-6.2.2506.post74.dev0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,2923 @@
|
|
|
1
|
+
#ifndef FILE_HDIVDIVFE
|
|
2
|
+
#define FILE_HDIVDIVFE
|
|
3
|
+
|
|
4
|
+
/*********************************************************************/
|
|
5
|
+
/* File: hdivdivfe.hpp */
|
|
6
|
+
/* Author: Astrid Pechstein, Joachim Schoeberl */
|
|
7
|
+
/* Date: orig 2006, redesign Dec 2016 */
|
|
8
|
+
/*********************************************************************/
|
|
9
|
+
|
|
10
|
+
#include "finiteelement.hpp"
|
|
11
|
+
#include "fe_interfaces.hpp"
|
|
12
|
+
|
|
13
|
+
#include "hcurlfe.hpp" // for Cross (AD,AD)
|
|
14
|
+
#include "recursive_pol.hpp"
|
|
15
|
+
#include "recursive_pol_trig.hpp"
|
|
16
|
+
#include "recursive_pol_tet.hpp"
|
|
17
|
+
#include "shapefunction_utils.hpp"
|
|
18
|
+
|
|
19
|
+
namespace ngfem
|
|
20
|
+
{
|
|
21
|
+
|
|
22
|
+
class BaseHDivDivFiniteElement : public FiniteElement
|
|
23
|
+
{
|
|
24
|
+
public:
|
|
25
|
+
|
|
26
|
+
using FiniteElement::ndof;
|
|
27
|
+
using FiniteElement::order;
|
|
28
|
+
bool algebraic_mapping = true;
|
|
29
|
+
|
|
30
|
+
INLINE BaseHDivDivFiniteElement () { ; }
|
|
31
|
+
INLINE BaseHDivDivFiniteElement (int andof, int aorder)
|
|
32
|
+
: FiniteElement (andof, aorder) { ; }
|
|
33
|
+
|
|
34
|
+
void SetAlgebraicMapping (bool am) { algebraic_mapping = am; }
|
|
35
|
+
|
|
36
|
+
virtual void CalcShape (const IntegrationPoint & ip,
|
|
37
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
38
|
+
|
|
39
|
+
virtual void CalcDivShape (const IntegrationPoint & ip,
|
|
40
|
+
BareSliceMatrix<double> divshape) const = 0;
|
|
41
|
+
};
|
|
42
|
+
template <int DIM>
|
|
43
|
+
class HDivDivFiniteElement : public BaseHDivDivFiniteElement
|
|
44
|
+
{
|
|
45
|
+
public:
|
|
46
|
+
using BaseHDivDivFiniteElement::BaseHDivDivFiniteElement;
|
|
47
|
+
using BaseHDivDivFiniteElement::ndof;
|
|
48
|
+
using BaseHDivDivFiniteElement::order;
|
|
49
|
+
|
|
50
|
+
// old style
|
|
51
|
+
virtual void CalcShape (const IntegrationPoint & ip,
|
|
52
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
53
|
+
|
|
54
|
+
virtual void CalcDivShape (const IntegrationPoint & ip,
|
|
55
|
+
BareSliceMatrix<double> divshape) const = 0;
|
|
56
|
+
|
|
57
|
+
// new implementation
|
|
58
|
+
virtual void CalcMappedShape_Matrix (const MappedIntegrationPoint<DIM,DIM> & mip,
|
|
59
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
virtual void CalcDDMappedShape_Matrix (const MappedIntegrationPoint<DIM,DIM> & mip,
|
|
63
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
virtual void CalcMappedShape_Vector (const MappedIntegrationPoint<DIM,DIM> & mip,
|
|
67
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
68
|
+
|
|
69
|
+
virtual void CalcMappedDivShape (const BaseMappedIntegrationPoint & mip,
|
|
70
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
virtual void CalcMappedShape_Matrix (const SIMD_BaseMappedIntegrationRule & mir,
|
|
74
|
+
BareSliceMatrix<SIMD<double>> shapes) const = 0;
|
|
75
|
+
|
|
76
|
+
virtual void Evaluate_Matrix (const SIMD_BaseMappedIntegrationRule & ir,
|
|
77
|
+
BareSliceVector<> coefs,
|
|
78
|
+
BareSliceMatrix<SIMD<double>> values) const = 0;
|
|
79
|
+
|
|
80
|
+
virtual void AddTrans_Matrix (const SIMD_BaseMappedIntegrationRule & ir,
|
|
81
|
+
BareSliceMatrix<SIMD<double>> values,
|
|
82
|
+
BareSliceVector<> coefs) const = 0;
|
|
83
|
+
|
|
84
|
+
virtual void CalcDualShape (const BaseMappedIntegrationPoint & bmip, BareSliceMatrix<> shape) const = 0;
|
|
85
|
+
virtual void CalcDualShape (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix<SIMD<double>> shape) const = 0;
|
|
86
|
+
virtual void EvaluateDual (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector<> coefs, BareSliceMatrix<SIMD<double>> values) const = 0;
|
|
87
|
+
virtual void AddDualTrans (const SIMD_BaseMappedIntegrationRule& bmir, BareSliceMatrix<SIMD<double>> values, BareSliceVector<double> coefs) const = 0;
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
virtual void CalcMappedDivShape (const SIMD_BaseMappedIntegrationRule & bmir,
|
|
91
|
+
BareSliceMatrix<SIMD<double>> divshapes) const = 0;
|
|
92
|
+
|
|
93
|
+
virtual void EvaluateDiv (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector<> coefs,
|
|
94
|
+
BareSliceMatrix<SIMD<double>> values) const = 0;
|
|
95
|
+
|
|
96
|
+
virtual void AddDivTrans (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix<SIMD<double>> values,
|
|
97
|
+
BareSliceVector<> coefs) const=0;
|
|
98
|
+
|
|
99
|
+
virtual void CalcShape_NormalComponent (const SIMD_BaseMappedIntegrationRule & mir,
|
|
100
|
+
BareSliceMatrix<SIMD<double>> shapes) const = 0;
|
|
101
|
+
|
|
102
|
+
virtual list<tuple<string,double>> Timing () const;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
template <int D,typename VEC,typename MAT>
|
|
106
|
+
void VecToSymMat(const VEC & vec,MAT && mat)
|
|
107
|
+
{
|
|
108
|
+
switch(D)
|
|
109
|
+
{
|
|
110
|
+
case 2:
|
|
111
|
+
mat(0) = vec(0);
|
|
112
|
+
mat(3) = vec(1);
|
|
113
|
+
mat(1) = mat(2) = vec(2);
|
|
114
|
+
break;
|
|
115
|
+
case 3:
|
|
116
|
+
auto v0 = vec(0);
|
|
117
|
+
auto v1 = vec(1);
|
|
118
|
+
auto v2 = vec(2);
|
|
119
|
+
auto v3 = vec(3);
|
|
120
|
+
auto v4 = vec(4);
|
|
121
|
+
auto v5 = vec(5);
|
|
122
|
+
mat(0) = v0;
|
|
123
|
+
mat(1) = v5;
|
|
124
|
+
mat(2) = v4;
|
|
125
|
+
mat(3) = v5;
|
|
126
|
+
mat(4) = v1;
|
|
127
|
+
mat(5) = v3;
|
|
128
|
+
mat(6) = v4;
|
|
129
|
+
mat(7) = v3;
|
|
130
|
+
mat(8) = v2;
|
|
131
|
+
/*
|
|
132
|
+
mat(0) = vec(0);
|
|
133
|
+
mat(4) = vec(1);
|
|
134
|
+
mat(8) = vec(2);
|
|
135
|
+
mat(1) = mat(3) = vec(5);
|
|
136
|
+
mat(2) = mat(6) = vec(4);
|
|
137
|
+
mat(5) = mat(7) = vec(3);
|
|
138
|
+
*/
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
template <typename T>
|
|
144
|
+
auto SymMatToVecDual (const Mat<2,2,T> & mat)
|
|
145
|
+
{
|
|
146
|
+
return Vec<3,T> { mat(0,0), mat(1,1), mat(0,1)+mat(1,0) };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
template <typename T>
|
|
150
|
+
auto SymMatToVecDual (const Mat<3,3,T> & mat)
|
|
151
|
+
{
|
|
152
|
+
return Vec<6,T> { mat(0,0), mat(1,1), mat(2,2), mat(1,2)+mat(2,1), mat(0,2)+mat(2,0), mat(0,1)+mat(1,0) };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
template <typename T>
|
|
157
|
+
Mat<2,2,T> DyadProd(Vec<2,T> a, Vec<2,T> b)
|
|
158
|
+
{
|
|
159
|
+
// return Matrix<T>({{a(0)*b(0), a(0)*b(1)}, {a(1)*b(0), a(1)*b(1)}} );
|
|
160
|
+
return { a(0)*b(0), a(0)*b(1), a(1)*b(0), a(1)*b(1) };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
template <typename T>
|
|
164
|
+
Mat<3,3,T> DyadProd(Vec<3,T> a, Vec<3,T> b)
|
|
165
|
+
{
|
|
166
|
+
// return Matrix<T>( {{a(0)*b(0), a(0)*b(1), a(0)*b(2)}, {a(1)*b(0), a(1)*b(1), a(1)*b(2)}, {a(2)*b(0), a(2)*b(1), a(2)*b(2)}} );
|
|
167
|
+
return { a(0)*b(0), a(0)*b(1), a(0)*b(2), a(1)*b(0), a(1)*b(1), a(1)*b(2), a(2)*b(0), a(2)*b(1), a(2)*b(2) };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
template <ELEMENT_TYPE ET> class HDivDivFE;
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
template <ELEMENT_TYPE ET, typename SHAPES = HDivDivFE<ET>>
|
|
174
|
+
class T_HDivDivFE : public HDivDivFiniteElement<ET_trait<ET>::DIM>,
|
|
175
|
+
public VertexOrientedFE<ET>
|
|
176
|
+
{
|
|
177
|
+
protected:
|
|
178
|
+
enum { DIM = ET_trait<ET>::DIM };
|
|
179
|
+
enum { DIM_STRESS = (DIM*(DIM+1))/2 };
|
|
180
|
+
|
|
181
|
+
using VertexOrientedFE<ET>::vnums;
|
|
182
|
+
using HDivDivFiniteElement<ET_trait<ET>::DIM>::ndof;
|
|
183
|
+
using HDivDivFiniteElement<ET_trait<ET>::DIM>::order;
|
|
184
|
+
|
|
185
|
+
//enum { N_VERTEX = ET_trait<ET>::N_VERTEX };
|
|
186
|
+
//enum { N_FACET = ET_trait<ET>::N_FACET };
|
|
187
|
+
//
|
|
188
|
+
//size_t vnums[N_VERTEX];
|
|
189
|
+
IVec<DIM-1> order_facet[ET_trait<ET>::N_FACET];
|
|
190
|
+
IVec<DIM> order_inner;
|
|
191
|
+
|
|
192
|
+
// additional div-div free bubbles
|
|
193
|
+
bool plus;
|
|
194
|
+
|
|
195
|
+
public:
|
|
196
|
+
using VertexOrientedFE<ET>::SetVertexNumbers;
|
|
197
|
+
|
|
198
|
+
T_HDivDivFE (int aorder, bool _plus = false)
|
|
199
|
+
: plus(_plus)
|
|
200
|
+
{
|
|
201
|
+
order = aorder;
|
|
202
|
+
for (auto & of : order_facet) of = aorder;
|
|
203
|
+
order_inner = aorder;
|
|
204
|
+
//ndof = DIM*(DIM+1)/2 * ET_trait<ET>::PolDimension(aorder);
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
virtual ELEMENT_TYPE ElementType() const override { return ET; }
|
|
209
|
+
// const HDivDivFE<ET> * Cast() const { return static_cast<const HDivDivFE<ET>*> (this); }
|
|
210
|
+
auto * Cast() const { return static_cast<const SHAPES*> (this); }
|
|
211
|
+
|
|
212
|
+
INLINE void SetOrderFacet (int nr, IVec<DIM-1,int> order) { order_facet[nr] = order; }
|
|
213
|
+
INLINE void SetOrderInner (IVec<DIM,int> order) { order_inner = order; }
|
|
214
|
+
|
|
215
|
+
virtual void ComputeNDof()
|
|
216
|
+
{
|
|
217
|
+
cout << "Error, T_HDivDivFE<ET>:: ComputeNDof not available, only for ET == TRIG" << endl;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
template <typename T, typename TFA>
|
|
221
|
+
void T_CalcShape (TIP<DIM,AutoDiff<DIM,T>> tip, TFA & shape) const
|
|
222
|
+
{
|
|
223
|
+
if constexpr (DIM == 2)
|
|
224
|
+
Cast() -> T_CalcShape (TIP<DIM,AutoDiffDiff<DIM,T>> (tip), shape);
|
|
225
|
+
else
|
|
226
|
+
Cast() -> T_CalcShape (tip, shape);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
template <typename T, typename TFA>
|
|
230
|
+
void T_CalcShape (TIP<DIM,AutoDiffDiff<DIM,T>> tip, TFA & shape) const
|
|
231
|
+
{
|
|
232
|
+
if constexpr (DIM == 2)
|
|
233
|
+
Cast() -> T_CalcShape (tip, shape);
|
|
234
|
+
else
|
|
235
|
+
throw Exception ("dd shapes are not supported in 3D");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
// old style
|
|
240
|
+
virtual void CalcShape (const IntegrationPoint & ip,
|
|
241
|
+
BareSliceMatrix<double> shape) const override
|
|
242
|
+
{
|
|
243
|
+
// Vec<DIM, AutoDiff<DIM> > adp = ip;
|
|
244
|
+
/*
|
|
245
|
+
Vec<DIM, AutoDiff<DIM>> adp;
|
|
246
|
+
for ( int i=0; i<DIM; i++)
|
|
247
|
+
adp(i) = AutoDiff<DIM>(ip(i),i);
|
|
248
|
+
auto tip = TIP<DIM, AutoDiff<DIM>> (adp, ip.FacetNr(), ip.VB());
|
|
249
|
+
*/
|
|
250
|
+
/* Cast() -> */ T_CalcShape (GetTIPGrad<DIM>(ip),
|
|
251
|
+
SBLambda([&] (int nr, auto val)
|
|
252
|
+
{
|
|
253
|
+
shape.Row(nr).Range(0,DIM_STRESS) = val.Shape();
|
|
254
|
+
}));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
virtual void CalcDualShape (const BaseMappedIntegrationPoint & bmip, BareSliceMatrix<> shape) const override
|
|
258
|
+
{
|
|
259
|
+
shape.AddSize(ndof, sqr(bmip.DimSpace())) = 0.0;
|
|
260
|
+
Switch<4-DIM>
|
|
261
|
+
(bmip.DimSpace()-DIM,[this, &bmip, shape](auto CODIM)
|
|
262
|
+
{
|
|
263
|
+
auto & mip = static_cast<const MappedIntegrationPoint<DIM,DIM+CODIM.value>&> (bmip);
|
|
264
|
+
|
|
265
|
+
Cast() -> CalcDualShape2 (mip, SBLambda([&] (size_t nr, auto val)
|
|
266
|
+
{
|
|
267
|
+
shape.Row(nr) = val.AsVector();
|
|
268
|
+
}));
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
virtual void CalcDualShape (const SIMD_BaseMappedIntegrationRule& bmir, BareSliceMatrix<SIMD<double>> shapes) const override
|
|
274
|
+
{
|
|
275
|
+
Switch<4-DIM>
|
|
276
|
+
(bmir.DimSpace()-DIM,[this, &bmir, shapes](auto CODIM)
|
|
277
|
+
{
|
|
278
|
+
constexpr int DIMSPACE = DIM+CODIM.value;
|
|
279
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM+CODIM.value>&> (bmir);
|
|
280
|
+
|
|
281
|
+
shapes.AddSize(ndof*sqr(DIMSPACE), mir.Size()) = 0.0;
|
|
282
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
283
|
+
{
|
|
284
|
+
Cast() -> CalcDualShape2 (mir[i], SBLambda([shapes,i,DIMSPACE] (size_t j, auto val)
|
|
285
|
+
{
|
|
286
|
+
shapes.Rows(j*sqr(DIMSPACE), (j+1)*sqr(DIMSPACE)).Col(i).Range(0,sqr(DIMSPACE)) = val.AsVector();
|
|
287
|
+
}));
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
virtual void EvaluateDual (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector<> coefs, BareSliceMatrix<SIMD<double>> values) const override
|
|
293
|
+
{
|
|
294
|
+
Switch<4-DIM>
|
|
295
|
+
(bmir.DimSpace()-DIM,[this,&bmir,coefs,values](auto CODIM)
|
|
296
|
+
{
|
|
297
|
+
constexpr int DIMSPACE = DIM+CODIM.value;
|
|
298
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM+CODIM.value>&> (bmir);
|
|
299
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
300
|
+
{
|
|
301
|
+
Mat<DIMSPACE,DIMSPACE,SIMD<double>> sum (SIMD<double>(0.0));
|
|
302
|
+
Cast() -> CalcDualShape2 (mir[i], SBLambda([&sum, coefs] (size_t j, auto val)
|
|
303
|
+
{
|
|
304
|
+
sum += coefs(j) * val;
|
|
305
|
+
}));
|
|
306
|
+
for (size_t k = 0; k < sqr(DIMSPACE); k++)
|
|
307
|
+
values(k, i) = sum(k);
|
|
308
|
+
}});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
virtual void AddDualTrans (const SIMD_BaseMappedIntegrationRule& bmir, BareSliceMatrix<SIMD<double>> values, BareSliceVector<double> coefs) const override
|
|
312
|
+
{
|
|
313
|
+
Switch<4-DIM>
|
|
314
|
+
(bmir.DimSpace()-DIM,[this,&bmir,coefs,values](auto CODIM)
|
|
315
|
+
{
|
|
316
|
+
constexpr int DIMSPACE = DIM+CODIM.value;
|
|
317
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM+CODIM.value>&> (bmir);
|
|
318
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
319
|
+
{
|
|
320
|
+
Mat<DIMSPACE,DIMSPACE,SIMD<double>> value;
|
|
321
|
+
for (size_t k = 0; k < sqr(DIMSPACE); k++)
|
|
322
|
+
value(k) = values(k, i);
|
|
323
|
+
|
|
324
|
+
Cast()-> CalcDualShape2 (mir[i], SBLambda([value, coefs] (size_t j, auto val)
|
|
325
|
+
{
|
|
326
|
+
coefs(j) += HSum(InnerProduct(val,value));
|
|
327
|
+
}));
|
|
328
|
+
}});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
virtual void CalcDivShape (const IntegrationPoint & ip,
|
|
333
|
+
BareSliceMatrix<double> shape) const override
|
|
334
|
+
{
|
|
335
|
+
// MSVC internal compiler error
|
|
336
|
+
// Vec<DIM, AutoDiff<DIM> > adp = ip;
|
|
337
|
+
// TIP<DIM,AutoDiffDiff<DIM>> addp(adp);
|
|
338
|
+
Vec<DIM, AutoDiff<DIM>> adp;
|
|
339
|
+
for (int i = 0; i < DIM; i++)
|
|
340
|
+
adp[i] = AutoDiff<DIM>(ip(i),i);
|
|
341
|
+
|
|
342
|
+
/* Cast() -> */ T_CalcShape (TIP<DIM, AutoDiff<DIM>> (adp, ip.FacetNr(), ip.VB()),
|
|
343
|
+
SBLambda([shape] (int nr, auto val)
|
|
344
|
+
{
|
|
345
|
+
shape.Row(nr).Range(0,DIM) = val.DivShape();
|
|
346
|
+
}));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// new style
|
|
350
|
+
virtual void CalcMappedShape_Vector (const MappedIntegrationPoint<DIM,DIM> & mip,
|
|
351
|
+
BareSliceMatrix<double> shape) const override
|
|
352
|
+
{
|
|
353
|
+
Vec<DIM, AutoDiff<DIM>> adp = mip;
|
|
354
|
+
/*
|
|
355
|
+
Vec<DIM, AutoDiffDiff<DIM>> addp;
|
|
356
|
+
for (int i=0; i<DIM; i++)
|
|
357
|
+
{
|
|
358
|
+
addp[i] = adp[i].Value();
|
|
359
|
+
addp[i].LoadGradient(&adp[i].DValue(0));
|
|
360
|
+
}
|
|
361
|
+
*/
|
|
362
|
+
/* Cast() -> */ T_CalcShape (TIP<DIM, AutoDiff<DIM>> (adp, mip.IP().FacetNr(), mip.IP().VB()),
|
|
363
|
+
SBLambda([&] (int nr, auto val)
|
|
364
|
+
{
|
|
365
|
+
shape.Row(nr).Range(0,DIM_STRESS) = val.Shape();
|
|
366
|
+
}));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
virtual void CalcMappedShape_Matrix (const MappedIntegrationPoint<DIM,DIM> & mip,
|
|
371
|
+
BareSliceMatrix<double> shape) const override
|
|
372
|
+
{
|
|
373
|
+
/*
|
|
374
|
+
auto tip = this->algebraic_mapping ? TIP<DIM, AutoDiffDiff<DIM>>(GetTIP(mip)) : GetTIPHesse(mip);
|
|
375
|
+
T_CalcShape (tip,
|
|
376
|
+
SBLambda([&](int nr,auto val)
|
|
377
|
+
{
|
|
378
|
+
VecToSymMat<DIM> (val.Shape(), shape.Row(nr));
|
|
379
|
+
}));
|
|
380
|
+
*/
|
|
381
|
+
if (this->algebraic_mapping)
|
|
382
|
+
T_CalcShape (GetTIP(mip),
|
|
383
|
+
SBLambda([&](int nr,auto val)
|
|
384
|
+
{
|
|
385
|
+
VecToSymMat<DIM> (val.Shape(), shape.Row(nr));
|
|
386
|
+
}));
|
|
387
|
+
else
|
|
388
|
+
T_CalcShape (GetTIPHesse(mip),
|
|
389
|
+
SBLambda([&](int nr,auto val)
|
|
390
|
+
{
|
|
391
|
+
VecToSymMat<DIM> (val.Shape(), shape.Row(nr));
|
|
392
|
+
}));
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/*
|
|
396
|
+
virtual void CalcDDMappedShape_Matrix (const MappedIntegrationPoint<DIM,DIM> & mip,
|
|
397
|
+
BareSliceMatrix<double> shape) const override
|
|
398
|
+
{
|
|
399
|
+
T_CalcShape (GetTIPHesse(mip),
|
|
400
|
+
SBLambda([&](int nr,auto val)
|
|
401
|
+
{
|
|
402
|
+
VecToSymMat<DIM> (val.Shape(), shape.Row(nr));
|
|
403
|
+
}));
|
|
404
|
+
}
|
|
405
|
+
*/
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
virtual void CalcMappedDivShape (const BaseMappedIntegrationPoint & bmip,
|
|
409
|
+
BareSliceMatrix<double> shape) const override
|
|
410
|
+
{
|
|
411
|
+
auto & mip = static_cast<const MappedIntegrationPoint<DIM,DIM>&> (bmip);
|
|
412
|
+
if (!this->algebraic_mapping)
|
|
413
|
+
{
|
|
414
|
+
T_CalcShape (GetTIPHesse(mip),
|
|
415
|
+
SBLambda([&](int nr,auto val)
|
|
416
|
+
{
|
|
417
|
+
shape.Row(nr).Range(0,DIM) = val.DivShape();
|
|
418
|
+
}));
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (!mip.GetTransformation().IsCurvedElement()) // non-curved element
|
|
423
|
+
{
|
|
424
|
+
T_CalcShape (GetTIP(mip),
|
|
425
|
+
SBLambda([&](int nr,auto val)
|
|
426
|
+
{
|
|
427
|
+
shape.Row(nr).Range(0,DIM) = val.DivShape();
|
|
428
|
+
}));
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
// curved element
|
|
432
|
+
|
|
433
|
+
if (false) // eval on physical element
|
|
434
|
+
{
|
|
435
|
+
Mat<DIM> inv = mip.GetJacobianInverse();
|
|
436
|
+
|
|
437
|
+
Vec<DIM,Mat<DIM>> hesse, hesse_inv;
|
|
438
|
+
mip.CalcHesse (hesse);
|
|
439
|
+
|
|
440
|
+
/*
|
|
441
|
+
|
|
442
|
+
div ( 1/J F sigma_ref F^T 1/J )
|
|
443
|
+
= deriv (1/J F) sigma_ref F^T 1/J + 1/J F div(sigma_ref F^T 1/J) = I + II
|
|
444
|
+
|
|
445
|
+
I ... Hessian : sigma + grad(1/J) sigma
|
|
446
|
+
II ... by DivShape of SigmaGrad templates, as for non-curved elements
|
|
447
|
+
|
|
448
|
+
*/
|
|
449
|
+
|
|
450
|
+
/*
|
|
451
|
+
for (int k = 0; k < DIM; k++)
|
|
452
|
+
hesse_inv(k) = Trans(inv) * hesse(k) * inv;
|
|
453
|
+
|
|
454
|
+
Vec<DIM> gradJ_xi;
|
|
455
|
+
for (int k = 0; k < DIM; k++)
|
|
456
|
+
{
|
|
457
|
+
double sum = 0;
|
|
458
|
+
for (int i = 0; i < DIM; i++)
|
|
459
|
+
for (int j = 0; j < DIM; j++)
|
|
460
|
+
sum += inv(j,i) * hesse(i)(j,k);
|
|
461
|
+
gradJ_xi(k) = sum;
|
|
462
|
+
}
|
|
463
|
+
Vec<DIM> gradJ = Trans(inv) * gradJ_xi;
|
|
464
|
+
for (int k = 0; k < DIM; k++)
|
|
465
|
+
for (int l = 0; l < DIM; l++)
|
|
466
|
+
hesse_inv(k)(l,k) -= gradJ(l);
|
|
467
|
+
*/
|
|
468
|
+
|
|
469
|
+
// saving a view operations ...
|
|
470
|
+
Vec<DIM, Mat<DIM>> hesse_inv1;
|
|
471
|
+
|
|
472
|
+
for (int k = 0; k < DIM; k++)
|
|
473
|
+
hesse_inv1(k) = hesse(k) * inv;
|
|
474
|
+
|
|
475
|
+
Vec<DIM> gradJ_xi = 0.0;
|
|
476
|
+
for (int i = 0; i < DIM; i++)
|
|
477
|
+
gradJ_xi += hesse_inv1(i).Col(i);
|
|
478
|
+
|
|
479
|
+
for (int k = 0; k < DIM; k++)
|
|
480
|
+
hesse_inv1(k).Col(k) -= gradJ_xi;
|
|
481
|
+
|
|
482
|
+
for (int k = 0; k < DIM; k++)
|
|
483
|
+
hesse_inv(k) = Trans(inv) * hesse_inv1(k);
|
|
484
|
+
|
|
485
|
+
Mat<DIM,DIM_STRESS> hesse_inv_vec;
|
|
486
|
+
for (int k = 0; k < DIM; k++)
|
|
487
|
+
hesse_inv_vec.Row(k) = SymMatToVecDual(hesse_inv(k));
|
|
488
|
+
|
|
489
|
+
T_CalcShape (GetTIP(mip),
|
|
490
|
+
SBLambda([&] (int nr,auto val)
|
|
491
|
+
{
|
|
492
|
+
shape.Row(nr).Range(0,DIM) = val.DivShape() + hesse_inv_vec * val.Shape();
|
|
493
|
+
}));
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
if (true)
|
|
499
|
+
{
|
|
500
|
+
// eval on reference element
|
|
501
|
+
|
|
502
|
+
Mat<DIM> inv = mip.GetJacobianInverse();
|
|
503
|
+
Mat<DIM> jac = mip.GetJacobian();
|
|
504
|
+
double det = Det(jac);
|
|
505
|
+
|
|
506
|
+
Vec<DIM,Mat<DIM>> hesse = mip.CalcHesse();
|
|
507
|
+
|
|
508
|
+
Vec<DIM> gradJ_xi = 0.0;
|
|
509
|
+
for (int i = 0; i < DIM; i++)
|
|
510
|
+
for (int j = 0; j < DIM; j++)
|
|
511
|
+
gradJ_xi += inv(j,i) * hesse(i).Col(j);
|
|
512
|
+
|
|
513
|
+
for (int i = 0; i < DIM; i++)
|
|
514
|
+
for (int j = 0; j < DIM; j++)
|
|
515
|
+
hesse(i).Col(j) -= jac(i,j) * gradJ_xi;
|
|
516
|
+
|
|
517
|
+
Mat<DIM,DIM_STRESS> hesse_inv_vec;
|
|
518
|
+
for (int k = 0; k < DIM; k++)
|
|
519
|
+
hesse_inv_vec.Row(k) = 1/(det*det) * SymMatToVecDual(hesse(k));
|
|
520
|
+
Mat<DIM> trans_div = 1/(det*det) * jac;
|
|
521
|
+
|
|
522
|
+
T_CalcShape (GetTIPGrad<DIM>(mip.IP()),
|
|
523
|
+
SBLambda([&] (int nr,auto val) LAMBDA_INLINE
|
|
524
|
+
{
|
|
525
|
+
shape.Row(nr).Range(0,DIM) = trans_div * val.DivShape() + hesse_inv_vec * val.Shape();
|
|
526
|
+
}));
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
/*
|
|
534
|
+
Mat<DIM> jac = mip.GetJacobian();
|
|
535
|
+
Mat<DIM> inv_jac = mip.GetJacobianInverse();
|
|
536
|
+
Mat<DIM> hesse[3],finvT_h_tilde_finv[3];
|
|
537
|
+
mip.CalcHesse (hesse[0],hesse[1],hesse[2]);
|
|
538
|
+
|
|
539
|
+
Mat<DIM,DIM,AutoDiff<DIM> > f_tilde;
|
|
540
|
+
for(int i = 0; i < DIM; i++)
|
|
541
|
+
{
|
|
542
|
+
for(int j = 0; j < DIM; j++)
|
|
543
|
+
{
|
|
544
|
+
f_tilde(i,j).Value() = jac(i,j);
|
|
545
|
+
for(int k = 0; k < DIM; k++)
|
|
546
|
+
f_tilde(i,j).DValue(k) = hesse[i](j,k);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
AutoDiff<DIM> ad_det = Det (f_tilde);
|
|
551
|
+
AutoDiff<DIM> iad_det = 1.0 / ad_det;
|
|
552
|
+
f_tilde *= iad_det;
|
|
553
|
+
|
|
554
|
+
for(int i=0; i<DIM; i++)
|
|
555
|
+
{
|
|
556
|
+
finvT_h_tilde_finv[i] = 0;
|
|
557
|
+
for(int alpha=0; alpha<DIM; alpha++)
|
|
558
|
+
for(int beta=0; beta<DIM; beta++)
|
|
559
|
+
for(int gamma=0; gamma<DIM; gamma++)
|
|
560
|
+
for(int delta=0; delta<DIM; delta++)
|
|
561
|
+
finvT_h_tilde_finv[i](alpha,beta) += inv_jac(gamma,alpha)*f_tilde(i,gamma).DValue(delta)*inv_jac(delta,beta);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
T_CalcShape (GetTIP(mip), // TIP<DIM,AutoDiff<DIM>> (adp),
|
|
565
|
+
SBLambda([&](int nr,auto val)
|
|
566
|
+
{
|
|
567
|
+
shape.Row(nr).Range(0,DIM) = val.DivShape();
|
|
568
|
+
BareVector<double> divshape = shape.Row(nr);
|
|
569
|
+
Vec<DIM_STRESS> vecshape = val.Shape();
|
|
570
|
+
Vec<DIM*DIM> matshape;
|
|
571
|
+
VecToSymMat<DIM> (vecshape, matshape);
|
|
572
|
+
|
|
573
|
+
for(int k=0; k<DIM; k++)
|
|
574
|
+
{
|
|
575
|
+
for(int j=0; j<DIM*DIM; j++)
|
|
576
|
+
{
|
|
577
|
+
divshape(k) += mip.GetJacobiDet() * finvT_h_tilde_finv[k](j) * matshape(j);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
}));
|
|
582
|
+
}
|
|
583
|
+
*/
|
|
584
|
+
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
template <int DIMSPACE>
|
|
588
|
+
void CalcMappedShape_Matrix2 (const SIMD_MappedIntegrationRule<DIM,DIMSPACE> & mir,
|
|
589
|
+
BareSliceMatrix<SIMD<double>> shapes) const
|
|
590
|
+
{
|
|
591
|
+
// static Timer t("HDivDivFE - Matrix2", NoTracing);
|
|
592
|
+
// RegionTracer regtr(TaskManager::GetThreadId(), t);
|
|
593
|
+
|
|
594
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
595
|
+
{
|
|
596
|
+
if (DIM == DIMSPACE)
|
|
597
|
+
{
|
|
598
|
+
const SIMD_BaseMappedIntegrationRule & bmir = mir;
|
|
599
|
+
auto & mir2 = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM>&>(bmir);
|
|
600
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = mir2[i];
|
|
601
|
+
auto shapesi = shapes.Col(i);
|
|
602
|
+
/* this->Cast() -> */ T_CalcShape (GetTIP(mir2[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
603
|
+
SBLambda ([shapesi] (size_t j, auto val)
|
|
604
|
+
{
|
|
605
|
+
auto shapeij = shapesi.Range(j*sqr(DIMSPACE),(j+1)*sqr(DIMSPACE));
|
|
606
|
+
// VecToSymMat<DIM> (val.Shape(), shapeij);
|
|
607
|
+
Mat<DIM,DIM,SIMD<double>> shapemat;
|
|
608
|
+
VecToSymMat<DIM> (val.Shape(), shapemat);
|
|
609
|
+
for (size_t i = 0; i < DIMSPACE*DIMSPACE; i++)
|
|
610
|
+
shapeij(i) = shapemat(i);
|
|
611
|
+
}));
|
|
612
|
+
}
|
|
613
|
+
else
|
|
614
|
+
{
|
|
615
|
+
auto jac = mir[i].GetJacobian();
|
|
616
|
+
auto d2 = sqr(mir[i].GetJacobiDet());
|
|
617
|
+
Vec<DIM_STRESS,SIMD<double>> hv;
|
|
618
|
+
Mat<DIM,DIM,SIMD<double>> mat;
|
|
619
|
+
SIMD<double> mem[DIMSPACE*DIMSPACE*DIM_STRESS];
|
|
620
|
+
// FlatMatrix<SIMD<double>> trans(DIMSPACE*DIMSPACE,DIM_STRESS,&mem[0]);
|
|
621
|
+
FlatMatrixFixWidth<DIM_STRESS, SIMD<double>> trans(DIMSPACE*DIMSPACE,&mem[0]);
|
|
622
|
+
for (int k = 0; k < DIM_STRESS; k++)
|
|
623
|
+
{
|
|
624
|
+
hv = SIMD<double>(0.0);
|
|
625
|
+
hv(k) = SIMD<double>(1.0);
|
|
626
|
+
VecToSymMat<DIM> (hv, mat);
|
|
627
|
+
Mat<DIMSPACE,DIMSPACE,SIMD<double>> physmat = 1/d2*(jac * mat * Trans(jac));
|
|
628
|
+
trans.Col(k) = physmat.AsVector();
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = mir.IR()[i];
|
|
633
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
634
|
+
|
|
635
|
+
/* this->Cast() -> */ T_CalcShape (GetTIPGrad<DIM> (mir.IR()[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
636
|
+
SBLambda ([i,shapes,trans] (size_t j, auto val)
|
|
637
|
+
{
|
|
638
|
+
shapes.Rows(j*sqr(DIMSPACE),(j+1)*sqr(DIMSPACE)).Col(i).Range(0,sqr(DIMSPACE)) = trans * val.Shape();
|
|
639
|
+
}));
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
virtual void CalcShape_NormalComponent (const SIMD_BaseMappedIntegrationRule & bmir,
|
|
645
|
+
BareSliceMatrix<SIMD<double>> shapes) const override
|
|
646
|
+
{
|
|
647
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM>&> (bmir);
|
|
648
|
+
|
|
649
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
650
|
+
{
|
|
651
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = mir[i];
|
|
652
|
+
Vec<DIM,SIMD<double>> nv = mir[i].GetNV();
|
|
653
|
+
auto shapesi = shapes.Col(i);
|
|
654
|
+
/* this->Cast() -> */ T_CalcShape (GetTIP(mir[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
655
|
+
SBLambda ([shapesi, nv] (size_t j, auto val)
|
|
656
|
+
{
|
|
657
|
+
auto shapeij = shapesi.Range(j*DIM,(j+1)*DIM);
|
|
658
|
+
Mat<DIM,DIM,SIMD<double>> shapemat;
|
|
659
|
+
VecToSymMat<DIM> (val.Shape(), shapemat);
|
|
660
|
+
Vec<DIM,SIMD<double>> mnv = shapemat * nv;
|
|
661
|
+
for (size_t i = 0; i < DIM; i++)
|
|
662
|
+
shapeij(i) = mnv(i);
|
|
663
|
+
}));
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
virtual void CalcMappedShape_Matrix (const SIMD_BaseMappedIntegrationRule & bmir,
|
|
668
|
+
BareSliceMatrix<SIMD<double>> shapes) const override
|
|
669
|
+
{
|
|
670
|
+
Iterate<4-DIM>
|
|
671
|
+
([this, &bmir, shapes](auto CODIM) LAMBDA_INLINE
|
|
672
|
+
{
|
|
673
|
+
constexpr int CD = CODIM.value;
|
|
674
|
+
constexpr int DIMSPACE = DIM+CD;
|
|
675
|
+
if (bmir.DimSpace() == DIMSPACE)
|
|
676
|
+
{
|
|
677
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIMSPACE>&> (bmir);
|
|
678
|
+
this->CalcMappedShape_Matrix2 (mir, shapes);
|
|
679
|
+
#ifdef XXX
|
|
680
|
+
|
|
681
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
682
|
+
{
|
|
683
|
+
auto jac = mir[i].GetJacobian();
|
|
684
|
+
auto d2 = sqr(mir[i].GetJacobiDet());
|
|
685
|
+
|
|
686
|
+
Vec<DIM_STRESS,SIMD<double>> hv;
|
|
687
|
+
Mat<DIM,DIM,SIMD<double>> mat;
|
|
688
|
+
// Mat<DIMSPACE*DIMSPACE, DIM_STRESS,SIMD<double>> trans;
|
|
689
|
+
SIMD<double> mem[DIMSPACE*DIMSPACE*DIM_STRESS];
|
|
690
|
+
FlatMatrix<SIMD<double>> trans(DIMSPACE*DIMSPACE,DIM_STRESS,&mem[0]);
|
|
691
|
+
for (int k = 0; k < DIM_STRESS; k++)
|
|
692
|
+
{
|
|
693
|
+
hv = SIMD<double>(0.0);
|
|
694
|
+
hv(k) = SIMD<double>(1.0);
|
|
695
|
+
VecToSymMat<DIM> (hv, mat);
|
|
696
|
+
Mat<DIMSPACE,DIMSPACE,SIMD<double>> physmat =
|
|
697
|
+
1/d2 * (jac * mat * Trans(jac));
|
|
698
|
+
for (int j = 0; j < DIMSPACE*DIMSPACE; j++)
|
|
699
|
+
trans(j,k) = physmat(j);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = bmir.IR()[i];
|
|
704
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
705
|
+
|
|
706
|
+
this->Cast() -> T_CalcShape (adp,
|
|
707
|
+
SBLambda ([i,shapes,trans] (size_t j, auto val) LAMBDA_INLINE
|
|
708
|
+
{
|
|
709
|
+
/*
|
|
710
|
+
Mat<DIM,DIM,SIMD<double>> mat;
|
|
711
|
+
VecToSymMat<DIM> (val.Shape(), mat);
|
|
712
|
+
Mat<DIMSPACE,DIMSPACE,SIMD<double>> physmat =
|
|
713
|
+
1/d2 * (jac * mat * Trans(jac));
|
|
714
|
+
for (size_t k = 0; k < sqr(DIMSPACE); k++)
|
|
715
|
+
shapes(j*sqr(DIMSPACE)+k,i) = physmat(k);
|
|
716
|
+
*/
|
|
717
|
+
Vec<DIMSPACE*DIMSPACE,SIMD<double>> transvec;
|
|
718
|
+
transvec = (trans * val.Shape()).AsVector();
|
|
719
|
+
for (size_t k = 0; k < sqr(DIMSPACE); k++)
|
|
720
|
+
shapes(j*sqr(DIMSPACE)+k,i) = transvec(k);
|
|
721
|
+
}));
|
|
722
|
+
}
|
|
723
|
+
#endif
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
virtual void Evaluate_Matrix (const SIMD_BaseMappedIntegrationRule & bmir,
|
|
729
|
+
BareSliceVector<> coefs,
|
|
730
|
+
BareSliceMatrix<SIMD<double>> values) const override
|
|
731
|
+
{
|
|
732
|
+
if (this->algebraic_mapping == false)
|
|
733
|
+
{
|
|
734
|
+
if (bmir.DimSpace() != DIM)
|
|
735
|
+
throw Exception ("sequential mapping only for volume space");
|
|
736
|
+
|
|
737
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM>&> (bmir);
|
|
738
|
+
for (size_t i = 0; i < bmir.Size(); i++)
|
|
739
|
+
{
|
|
740
|
+
double *pcoefs = &coefs(0);
|
|
741
|
+
const size_t dist = coefs.Dist();
|
|
742
|
+
|
|
743
|
+
Vec<DIM_STRESS,SIMD<double>> sum(0.0);
|
|
744
|
+
T_CalcShape (GetTIPHesse(mir[i]),
|
|
745
|
+
SBLambda ([&sum,&pcoefs,dist] (size_t j, auto val)
|
|
746
|
+
{
|
|
747
|
+
sum += (*pcoefs)*val.Shape();
|
|
748
|
+
pcoefs += dist;
|
|
749
|
+
}));
|
|
750
|
+
for (size_t k = 0; k < DIM_STRESS; k++)
|
|
751
|
+
values(k,i) = sum(k);
|
|
752
|
+
}
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
for (size_t i = 0; i < bmir.Size(); i++)
|
|
757
|
+
{
|
|
758
|
+
double *pcoefs = &coefs(0);
|
|
759
|
+
const size_t dist = coefs.Dist();
|
|
760
|
+
|
|
761
|
+
Vec<DIM_STRESS,SIMD<double>> sum(0.0);
|
|
762
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = bmir.IR()[i];
|
|
763
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
764
|
+
|
|
765
|
+
/* Cast() -> */ T_CalcShape (GetTIPGrad<DIM>(bmir.IR()[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
766
|
+
SBLambda ([&sum,&pcoefs,dist] (size_t j, auto val)
|
|
767
|
+
{
|
|
768
|
+
sum += (*pcoefs)*val.Shape();
|
|
769
|
+
pcoefs += dist;
|
|
770
|
+
}));
|
|
771
|
+
|
|
772
|
+
Mat<DIM,DIM,SIMD<double>> summat;
|
|
773
|
+
VecToSymMat<DIM> (sum, summat);
|
|
774
|
+
|
|
775
|
+
Iterate<4-DIM>
|
|
776
|
+
([values,&bmir,i,summat](auto CODIM)
|
|
777
|
+
{
|
|
778
|
+
constexpr auto DIMSPACE = DIM+CODIM.value;
|
|
779
|
+
if (bmir.DimSpace() == DIMSPACE)
|
|
780
|
+
{
|
|
781
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIMSPACE>&> (bmir);
|
|
782
|
+
auto jac = mir[i].GetJacobian();
|
|
783
|
+
auto d2 = sqr(mir[i].GetJacobiDet());
|
|
784
|
+
Mat<DIMSPACE,DIMSPACE,SIMD<double>> physmat = 1/d2 * (jac * summat * Trans(jac));
|
|
785
|
+
for (size_t k = 0; k < sqr(DIMSPACE); k++)
|
|
786
|
+
values(k,i) = physmat(k);
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
virtual void AddTrans_Matrix (const SIMD_BaseMappedIntegrationRule & bmir,
|
|
793
|
+
BareSliceMatrix<SIMD<double>> values,
|
|
794
|
+
BareSliceVector<> coefs) const override
|
|
795
|
+
{
|
|
796
|
+
for (size_t i = 0; i < bmir.Size(); i++)
|
|
797
|
+
{
|
|
798
|
+
Mat<DIM,DIM,SIMD<double>> mat;
|
|
799
|
+
|
|
800
|
+
Iterate<4-DIM>
|
|
801
|
+
([&bmir,i,&mat,values](auto CODIM)
|
|
802
|
+
{
|
|
803
|
+
constexpr auto DIMSPACE = DIM+CODIM.value;
|
|
804
|
+
if (bmir.DimSpace() == DIMSPACE)
|
|
805
|
+
{
|
|
806
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIMSPACE>&> (bmir);
|
|
807
|
+
|
|
808
|
+
auto jac = mir[i].GetJacobian();
|
|
809
|
+
auto d2 = sqr(mir[i].GetJacobiDet());
|
|
810
|
+
|
|
811
|
+
Mat<DIMSPACE,DIMSPACE,SIMD<double>> physmat{};
|
|
812
|
+
// physmat = values.Col(i);
|
|
813
|
+
physmat.AsVector() = values.Col(i);
|
|
814
|
+
mat = 1/d2 * Trans(jac) * physmat * jac;
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = bmir.IR()[i];
|
|
819
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
820
|
+
double *pcoefs = &coefs(0);
|
|
821
|
+
const size_t dist = coefs.Dist();
|
|
822
|
+
|
|
823
|
+
/* Cast() -> */ T_CalcShape (GetTIPGrad<DIM>(bmir.IR()[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>> (adp),
|
|
824
|
+
SBLambda ([mat,&pcoefs,dist] (size_t j, auto val)
|
|
825
|
+
{
|
|
826
|
+
Mat<DIM,DIM,SIMD<double>> mat2;
|
|
827
|
+
VecToSymMat<DIM> (val.Shape(), mat2);
|
|
828
|
+
|
|
829
|
+
*pcoefs += HSum(InnerProduct(mat,mat2));
|
|
830
|
+
pcoefs += dist;
|
|
831
|
+
}));
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
virtual void CalcMappedDivShape (const SIMD_BaseMappedIntegrationRule & bmir,
|
|
837
|
+
BareSliceMatrix<SIMD<double>> divshapes) const override
|
|
838
|
+
{
|
|
839
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM>&> (bmir);
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
if(!mir.GetTransformation().IsCurvedElement()) // non-curved element
|
|
843
|
+
{
|
|
844
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
845
|
+
{
|
|
846
|
+
auto jac = mir[i].GetJacobian();
|
|
847
|
+
auto d2 = sqr(mir[i].GetJacobiDet());
|
|
848
|
+
|
|
849
|
+
Vec<DIM,SIMD<double>> vec;
|
|
850
|
+
SIMD<double> mem[DIM*DIM_STRESS];
|
|
851
|
+
FlatMatrix<SIMD<double>> trans(DIM,DIM,&mem[0]);
|
|
852
|
+
trans = 1/d2 * jac;
|
|
853
|
+
/*
|
|
854
|
+
{
|
|
855
|
+
vec = SIMD<double>(0.0);
|
|
856
|
+
vec(k) = SIMD<double>(1.0);
|
|
857
|
+
Vec<DIM,SIMD<double>> physvec = 1/d2 * (jac * vec);
|
|
858
|
+
trans.Col(k) = physvec;
|
|
859
|
+
}
|
|
860
|
+
*/
|
|
861
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = mir.IR()[i];
|
|
862
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
863
|
+
/* Cast() -> */ T_CalcShape
|
|
864
|
+
(GetTIPGrad<DIM>(mir.IR()[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
865
|
+
SBLambda([divshapes,i,trans](int j,auto val)
|
|
866
|
+
{
|
|
867
|
+
divshapes.Rows(j*DIM,(j+1)*DIM).Col(i).Range(0,DIM) = trans * val.DivShape();
|
|
868
|
+
}));
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
else
|
|
872
|
+
{
|
|
873
|
+
// throw ExceptionNOSIMD(string("HDivDiv - CalcMappedDivShape SIMD only for noncurved elements"));
|
|
874
|
+
for (size_t i = 0; i < mir.Size(); i++)
|
|
875
|
+
{
|
|
876
|
+
// static Timer t0("HDivDivFE - hesse", NoTracing);
|
|
877
|
+
// static Timer t1("HDivDivFE - prepare div", NoTracing);
|
|
878
|
+
// static Timer t2("HDivDivFE - calc div", NoTracing);
|
|
879
|
+
|
|
880
|
+
Mat<DIM,DIM,SIMD<double>> jac = mir[i].GetJacobian();
|
|
881
|
+
Mat<DIM,DIM,SIMD<double>> inv_jac = mir[i].GetJacobianInverse();
|
|
882
|
+
Mat<DIM,DIM,SIMD<double>> finvT_h_tilde_finv[DIM];
|
|
883
|
+
|
|
884
|
+
// RegionTracer reg0(TaskManager::GetThreadId(), t0);
|
|
885
|
+
|
|
886
|
+
Vec<DIM, Mat<DIM,DIM,SIMD<double>>> hesse;
|
|
887
|
+
mir.GetTransformation().CalcHesse (mir.IR()[i], hesse);
|
|
888
|
+
|
|
889
|
+
// RegionTracer reg1(TaskManager::GetThreadId(), t1);
|
|
890
|
+
|
|
891
|
+
Mat<DIM,DIM,AutoDiff<DIM,SIMD<double>> > f_tilde;
|
|
892
|
+
for(int i = 0; i < DIM; i++)
|
|
893
|
+
for(int j = 0; j < DIM; j++)
|
|
894
|
+
{
|
|
895
|
+
f_tilde(i,j).Value() = jac(i,j);
|
|
896
|
+
for(int k = 0; k < DIM; k++)
|
|
897
|
+
f_tilde(i,j).DValue(k) = hesse[i](j,k);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
AutoDiff<DIM,SIMD<double>> ad_det = Det (f_tilde);
|
|
901
|
+
AutoDiff<DIM, SIMD<double>> iad_det = 1.0 / ad_det;
|
|
902
|
+
f_tilde *= iad_det;
|
|
903
|
+
|
|
904
|
+
for(int i=0; i<DIM; i++)
|
|
905
|
+
{
|
|
906
|
+
finvT_h_tilde_finv[i] = 0;
|
|
907
|
+
for(int alpha=0; alpha<DIM; alpha++)
|
|
908
|
+
for(int beta=0; beta<DIM; beta++)
|
|
909
|
+
for(int gamma=0; gamma<DIM; gamma++)
|
|
910
|
+
for(int delta=0; delta<DIM; delta++)
|
|
911
|
+
finvT_h_tilde_finv[i](alpha,beta) += inv_jac(gamma,alpha)*f_tilde(i,gamma).DValue(delta)*inv_jac(delta,beta);
|
|
912
|
+
}
|
|
913
|
+
for (int j = 0; j < DIM; j++)
|
|
914
|
+
finvT_h_tilde_finv[j] *= mir[i].GetJacobiDet();
|
|
915
|
+
|
|
916
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = mir[i];
|
|
917
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
918
|
+
// TIP<DIM,AutoDiff<DIM,SIMD<double>>> addp(adp);
|
|
919
|
+
// RegionTracer reg2(TaskManager::GetThreadId(), t2);
|
|
920
|
+
/* Cast() -> */ T_CalcShape
|
|
921
|
+
(GetTIP(mir[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
922
|
+
SBLambda([&](int nr,auto val)
|
|
923
|
+
{
|
|
924
|
+
BareSliceVector<SIMD<double>> divshape = divshapes.Rows(nr*DIM,(nr+1)*DIM).Col(i);
|
|
925
|
+
|
|
926
|
+
Vec<DIM,SIMD<double>> div1 = val.DivShape();
|
|
927
|
+
Vec<DIM_STRESS,SIMD<double>> vecshape = val.Shape();
|
|
928
|
+
Vec<DIM*DIM,SIMD<double>> matshape;
|
|
929
|
+
VecToSymMat<DIM> (vecshape, matshape);
|
|
930
|
+
|
|
931
|
+
for(size_t k = 0; k < DIM; k++)
|
|
932
|
+
{
|
|
933
|
+
SIMD<double> sum = div1(k);
|
|
934
|
+
for(size_t j = 0; j < DIM*DIM; j++)
|
|
935
|
+
sum += finvT_h_tilde_finv[k](j) * matshape(j);
|
|
936
|
+
divshape(k) = sum;
|
|
937
|
+
}
|
|
938
|
+
}));
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
virtual void EvaluateDiv (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceVector<> coefs,
|
|
944
|
+
BareSliceMatrix<SIMD<double>> values) const override
|
|
945
|
+
{
|
|
946
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM>&> (bmir);
|
|
947
|
+
if(!mir.GetTransformation().IsCurvedElement()) // non-curved element
|
|
948
|
+
{
|
|
949
|
+
for (size_t i = 0; i < bmir.Size(); i++)
|
|
950
|
+
{
|
|
951
|
+
double *pcoefs = &coefs(0);
|
|
952
|
+
const size_t dist = coefs.Dist();
|
|
953
|
+
|
|
954
|
+
Vec<DIM,SIMD<double>> sum(0.0);
|
|
955
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = bmir.IR()[i];
|
|
956
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
957
|
+
|
|
958
|
+
/* Cast() -> */ T_CalcShape (GetTIPGrad<DIM>(bmir.IR()[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
959
|
+
SBLambda ([&sum,&pcoefs,dist] (size_t j, auto val)
|
|
960
|
+
{
|
|
961
|
+
sum += (*pcoefs)*val.DivShape();
|
|
962
|
+
pcoefs += dist;
|
|
963
|
+
}));
|
|
964
|
+
|
|
965
|
+
Iterate<4-DIM>
|
|
966
|
+
([values,&bmir,i,sum](auto CODIM)
|
|
967
|
+
{
|
|
968
|
+
constexpr auto DIMSPACE = DIM+CODIM.value;
|
|
969
|
+
if (bmir.DimSpace() == DIMSPACE)
|
|
970
|
+
{
|
|
971
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIMSPACE>&> (bmir);
|
|
972
|
+
auto jac = mir[i].GetJacobian();
|
|
973
|
+
auto d2 = sqr(mir[i].GetJacobiDet());
|
|
974
|
+
Vec<DIMSPACE,SIMD<double>> physvec = 1/d2 * (jac * sum);
|
|
975
|
+
for (size_t k=0; k < DIMSPACE; k++)
|
|
976
|
+
values(k,i) = physvec(k);
|
|
977
|
+
}
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
else
|
|
982
|
+
{
|
|
983
|
+
throw ExceptionNOSIMD(string("HDivDiv - EvaluateDiv SIMD only for noncurved elements"));
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
virtual void AddDivTrans (const SIMD_BaseMappedIntegrationRule & bmir, BareSliceMatrix<SIMD<double>> values,
|
|
988
|
+
BareSliceVector<> coefs) const override
|
|
989
|
+
{
|
|
990
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIM>&> (bmir);
|
|
991
|
+
if(!mir.GetTransformation().IsCurvedElement()) // non-curved element
|
|
992
|
+
{
|
|
993
|
+
for (size_t i = 0; i < bmir.Size(); i++)
|
|
994
|
+
{
|
|
995
|
+
Vec<DIM,SIMD<double>> vec;
|
|
996
|
+
|
|
997
|
+
Iterate<4-DIM>
|
|
998
|
+
([&bmir,i,&vec,values](auto CODIM)
|
|
999
|
+
{
|
|
1000
|
+
constexpr auto DIMSPACE = DIM+CODIM.value;
|
|
1001
|
+
if (bmir.DimSpace() == DIMSPACE)
|
|
1002
|
+
{
|
|
1003
|
+
auto & mir = static_cast<const SIMD_MappedIntegrationRule<DIM,DIMSPACE>&> (bmir);
|
|
1004
|
+
|
|
1005
|
+
auto jac = mir[i].GetJacobian();
|
|
1006
|
+
auto d2 = sqr(mir[i].GetJacobiDet());
|
|
1007
|
+
|
|
1008
|
+
Vec<DIMSPACE,SIMD<double>> physvec{};
|
|
1009
|
+
for (size_t k = 0; k < DIMSPACE; k++)
|
|
1010
|
+
physvec(k) = values(k,i);
|
|
1011
|
+
vec = 1/d2 * Trans(jac) * physvec;
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
|
|
1015
|
+
// Vec<DIM,AutoDiff<DIM,SIMD<double>>> adp = bmir.IR()[i];
|
|
1016
|
+
// TIP<DIM,AutoDiffDiff<DIM,SIMD<double>>> addp(adp);
|
|
1017
|
+
double *pcoefs = &coefs(0);
|
|
1018
|
+
const size_t dist = coefs.Dist();
|
|
1019
|
+
|
|
1020
|
+
/* Cast() -> */ T_CalcShape (GetTIPGrad<DIM> (bmir.IR()[i]), // TIP<DIM,AutoDiff<DIM,SIMD<double>>>(adp),
|
|
1021
|
+
SBLambda ([vec,&pcoefs,dist] (size_t j, auto val)
|
|
1022
|
+
{
|
|
1023
|
+
*pcoefs += HSum(InnerProduct(vec,val.DivShape()));
|
|
1024
|
+
pcoefs += dist;
|
|
1025
|
+
}));
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
else
|
|
1029
|
+
{
|
|
1030
|
+
throw ExceptionNOSIMD(string("HDivDiv - AddTrans SIMD only for noncurved elements"));
|
|
1031
|
+
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
};
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
#ifdef FILE_HDIVDIVFE_CPP
|
|
1040
|
+
#define HDIVDIVFE_EXTERN
|
|
1041
|
+
#else
|
|
1042
|
+
#define HDIVDIVFE_EXTERN extern
|
|
1043
|
+
#endif
|
|
1044
|
+
|
|
1045
|
+
extern template class HDivDivFiniteElement<2>;
|
|
1046
|
+
extern template class HDivDivFiniteElement<3>;
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
// ***************** SigmaGrad ****************************** */
|
|
1050
|
+
// sigma (nabla u)
|
|
1051
|
+
|
|
1052
|
+
template <int D, typename T> class T_SigmaGrad;
|
|
1053
|
+
template <typename T> class T_SigmaGrad<2,T>
|
|
1054
|
+
{
|
|
1055
|
+
AutoDiffDiff<2,T> u;
|
|
1056
|
+
public:
|
|
1057
|
+
T_SigmaGrad (AutoDiffDiff<2,T> au) : u(au) { ; }
|
|
1058
|
+
Vec<3,T> Shape() { return Vec<3,T> (u.DDValue(1,1), u.DDValue(0,0), -u.DDValue(1,0)); }
|
|
1059
|
+
Vec<2,T> DivShape() { return Vec<2,T> (0.0, 0.0); }
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
template <int D, typename T>
|
|
1063
|
+
auto SigmaGrad (AutoDiffDiff<D,T> au) { return T_SigmaGrad<D,T>(au); }
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
// ***************** Sigma_u_Gradv ****************************** */
|
|
1067
|
+
// sigma (u nabla v)
|
|
1068
|
+
|
|
1069
|
+
template <int D, typename T> class T_Sigma_u_Gradv;
|
|
1070
|
+
template <typename T> class T_Sigma_u_Gradv<2,T>
|
|
1071
|
+
{
|
|
1072
|
+
AutoDiffDiff<2,T> u, v;
|
|
1073
|
+
public:
|
|
1074
|
+
T_Sigma_u_Gradv (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av) : u(au), v(av) { ; }
|
|
1075
|
+
Vec<3,T> Shape() { return Vec<3,T> ((u.Value()*v.DDValue(1,1) + u.DValue(1)*v.DValue(1)),
|
|
1076
|
+
(u.Value()*v.DDValue(0,0) + u.DValue(0)*v.DValue(0)),
|
|
1077
|
+
-u.Value()*v.DDValue(1,0) - 0.5 * (u.DValue(0)*v.DValue(1)+u.DValue(1)*v.DValue(0))); }
|
|
1078
|
+
Vec<2,T> DivShape()
|
|
1079
|
+
{
|
|
1080
|
+
T uxx = u.DDValue(0,0), uyy = u.DDValue(1,1), uxy = u.DDValue(0,1);
|
|
1081
|
+
T ux = u.DValue(0), uy = u.DValue(1);
|
|
1082
|
+
T vxx = v.DDValue(0,0), vyy = v.DDValue(1,1), vxy = v.DDValue(0,1);
|
|
1083
|
+
T vx = v.DValue(0), vy = v.DValue(1);
|
|
1084
|
+
|
|
1085
|
+
return -0.5 * Vec<2,T> (uyy*vx - uxy*vy + uy*vxy - ux*vyy,
|
|
1086
|
+
-uxy*vx + uxx*vy - uy*vxx + ux*vxy);
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
|
|
1090
|
+
template <int D, typename T>
|
|
1091
|
+
auto Sigma_u_Gradv (AutoDiffDiff<D,T> au, AutoDiffDiff<D,T> av) { return T_Sigma_u_Gradv<D,T>(au, av); }
|
|
1092
|
+
|
|
1093
|
+
// ***************** Type2 ****************************** */
|
|
1094
|
+
// ????
|
|
1095
|
+
|
|
1096
|
+
template <int D, typename T> class T_Type2;
|
|
1097
|
+
template <typename T> class T_Type2<2,T>
|
|
1098
|
+
{
|
|
1099
|
+
AutoDiffDiff<2,T> u,v;
|
|
1100
|
+
public:
|
|
1101
|
+
T_Type2 (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av) : u(au), v(av) { ; }
|
|
1102
|
+
Vec<3,T> Shape() { return Vec<3,T> (u.DDValue(1,1)*v.Value() - 2*u.DValue(1)*v.DValue(1) + u.Value()*v.DDValue(1,1),
|
|
1103
|
+
u.DDValue(0,0)*v.Value() - 2*u.DValue(0)*v.DValue(0) + u.Value()*v.DDValue(0,0),
|
|
1104
|
+
-(u.DDValue(0,1)*v.Value() - u.DValue(0)*v.DValue(1) -
|
|
1105
|
+
u.DValue(1)*v.DValue(0) + u.Value()*v.DDValue(1,0))); }
|
|
1106
|
+
|
|
1107
|
+
Vec<2,T> DivShape()
|
|
1108
|
+
{
|
|
1109
|
+
T uxx = u.DDValue(0,0), uyy = u.DDValue(1,1), uxy = u.DDValue(0,1);
|
|
1110
|
+
T ux = u.DValue(0), uy = u.DValue(1);
|
|
1111
|
+
T vxx = v.DDValue(0,0), vyy = v.DDValue(1,1), vxy = v.DDValue(0,1);
|
|
1112
|
+
T vx = v.DValue(0), vy = v.DValue(1);
|
|
1113
|
+
|
|
1114
|
+
return Vec<2,T> (2*uyy*vx + 2*ux*vyy - 2*uxy*vy - 2*uy*vxy, 2*uxx*vy + 2*uy*vxx - 2*uxy*vx - 2*ux*vxy);
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
|
|
1118
|
+
template <int D, typename T>
|
|
1119
|
+
auto Type2 (AutoDiffDiff<D,T> au, AutoDiffDiff<D,T> av) { return T_Type2<D,T>(au, av); }
|
|
1120
|
+
|
|
1121
|
+
// ***************** Type3 ****************************** */
|
|
1122
|
+
// ????
|
|
1123
|
+
|
|
1124
|
+
template <int D, typename T> class T_Type3;
|
|
1125
|
+
template <typename T> class T_Type3<2,T>
|
|
1126
|
+
{
|
|
1127
|
+
AutoDiffDiff<2,T> u,v;
|
|
1128
|
+
public:
|
|
1129
|
+
T_Type3 (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av) : u(au), v(av) { ; }
|
|
1130
|
+
Vec<3,T> Shape() { return Vec<3,T> (u.DDValue(1,1)*v.Value() - u.Value()*v.DDValue(1,1),
|
|
1131
|
+
u.DDValue(0,0)*v.Value() - u.Value()*v.DDValue(0,0),
|
|
1132
|
+
-(u.DDValue(0,1)*v.Value() - u.Value()*v.DDValue(1,0))); }
|
|
1133
|
+
Vec<2,T> DivShape()
|
|
1134
|
+
{
|
|
1135
|
+
T uxx = u.DDValue(0,0), uyy = u.DDValue(1,1), uxy = u.DDValue(0,1);
|
|
1136
|
+
T ux = u.DValue(0), uy = u.DValue(1);
|
|
1137
|
+
T vxx = v.DDValue(0,0), vyy = v.DDValue(1,1), vxy = v.DDValue(0,1);
|
|
1138
|
+
T vx = v.DValue(0), vy = v.DValue(1);
|
|
1139
|
+
|
|
1140
|
+
return Vec<2,T> (uyy*vx - uxy*vy - ux*vyy + uy*vxy, uxx*vy - uxy*vx - uy*vxx + ux*vxy);
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
template <int D, typename T>
|
|
1145
|
+
auto Type3 (AutoDiffDiff<D,T> au, AutoDiffDiff<D,T> av) { return T_Type3<D,T>(au, av); }
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
template <int D, typename T> class T_vSigmaGradu;
|
|
1149
|
+
template <typename T> class T_vSigmaGradu<2,T>
|
|
1150
|
+
{
|
|
1151
|
+
AutoDiffDiff<2,T> u,v;
|
|
1152
|
+
public:
|
|
1153
|
+
T_vSigmaGradu (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av) : u(au), v(av) { ; }
|
|
1154
|
+
Vec<3,T> Shape() { return Vec<3,T> (u.DDValue(1,1)*v.Value(),
|
|
1155
|
+
u.DDValue(0,0)*v.Value(), -(u.DDValue(0,1)*v.Value()));}
|
|
1156
|
+
Vec<2,T> DivShape()
|
|
1157
|
+
{
|
|
1158
|
+
T uxx = u.DDValue(0,0), uyy = u.DDValue(1,1), uxy = u.DDValue(0,1);
|
|
1159
|
+
// T ux = u.DValue(0), uy = u.DValue(1);
|
|
1160
|
+
// T vxx = v.DDValue(0,0), vyy = v.DDValue(1,1), vxy = v.DDValue(0,1);
|
|
1161
|
+
T vx = v.DValue(0), vy = v.DValue(1);
|
|
1162
|
+
|
|
1163
|
+
return Vec<2,T> (uyy*vx- uxy*vy, uxx*vy- uxy*vx);
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
|
|
1167
|
+
template <int D, typename T>
|
|
1168
|
+
auto vSigmaGradu (AutoDiffDiff<D,T> au, AutoDiffDiff<D,T> av) { return T_vSigmaGradu<D,T>(au, av); }
|
|
1169
|
+
|
|
1170
|
+
// ***************** Sigma ((vDu - uDv) w) ****************************** */
|
|
1171
|
+
// where u, v are NOW POSSIBLY NON-linear hat basis functions (i.e. vDu - uDv is Nedelec0 edge basis function)
|
|
1172
|
+
template <int D, typename T> class T_Sigma_Duv_minus_uDv_w;
|
|
1173
|
+
template <typename T> class T_Sigma_Duv_minus_uDv_w<2,T>
|
|
1174
|
+
{
|
|
1175
|
+
AutoDiffDiff<2,T> u,v,w;
|
|
1176
|
+
public:
|
|
1177
|
+
T_Sigma_Duv_minus_uDv_w (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av, AutoDiffDiff<2,T> aw) : u(au), v(av), w(aw) { ; }
|
|
1178
|
+
Vec<3,T> Shape() { return Vec<3,T> (w.DValue(1)*(v.DValue(1)*u.Value()-u.DValue(1)*v.Value()),
|
|
1179
|
+
w.DValue(0)*(v.DValue(0)*u.Value()-u.DValue(0)*v.Value()),
|
|
1180
|
+
-0.5*( w.DValue(0)*(v.DValue(1)*u.Value()-u.DValue(1)*v.Value()) +
|
|
1181
|
+
w.DValue(1)*(v.DValue(0)*u.Value()-u.DValue(0)*v.Value()) )
|
|
1182
|
+
); }
|
|
1183
|
+
|
|
1184
|
+
Vec<2,T> DivShape()
|
|
1185
|
+
{
|
|
1186
|
+
T uxx = u.DDValue(0,0), uyy = u.DDValue(1,1), uxy = u.DDValue(0,1);
|
|
1187
|
+
T ux = u.DValue(0), uy = u.DValue(1);
|
|
1188
|
+
T vxx = v.DDValue(0,0), vyy = v.DDValue(1,1), vxy = v.DDValue(0,1);
|
|
1189
|
+
T vx = v.DValue(0), vy = v.DValue(1);
|
|
1190
|
+
T wxx = w.DDValue(0,0), wyy = w.DDValue(1,1), wxy = w.DDValue(0,1);
|
|
1191
|
+
T wx = w.DValue(0), wy = w.DValue(1);
|
|
1192
|
+
|
|
1193
|
+
return Vec<2,T> (0.5*wxy*(vy*u.Value() - uy*v.Value())
|
|
1194
|
+
-0.5*wyy*(vx*u.Value() - ux*v.Value())
|
|
1195
|
+
+1.5*wy*(vy*ux - uy*vx) + 0.5*wy*(vxy*u.Value()-uxy*v.Value())
|
|
1196
|
+
-0.5*wx*(vyy*u.Value()-uyy*v.Value()),
|
|
1197
|
+
0.5*wxy*(vx*u.Value() - ux*v.Value())
|
|
1198
|
+
-0.5*wxx*(vy*u.Value() - uy*v.Value())
|
|
1199
|
+
+1.5*wx*(vx*uy - ux*vy) + 0.5*wx*(vxy*u.Value()-uxy*v.Value())
|
|
1200
|
+
-0.5*wy*(vxx*u.Value()-uxx*v.Value())
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
class T_SymRotRot_Dl2xDl1_v
|
|
1210
|
+
{
|
|
1211
|
+
AutoDiff<2> l1,l2,v;
|
|
1212
|
+
public:
|
|
1213
|
+
T_SymRotRot_Dl2xDl1_v (AutoDiff<2> lam1, AutoDiff<2> lam2, AutoDiff<2> av) : l1(lam1), l2(lam2), v(av) { ; }
|
|
1214
|
+
Vec<3> Shape() { return Vec<3> (v.Value()*(l1.DValue(1)*l2.DValue(1)),
|
|
1215
|
+
v.Value()*(l1.DValue(0)*l2.DValue(0)),
|
|
1216
|
+
-0.5*v.Value()*(l1.DValue(1)*l2.DValue(0) + l1.DValue(0)*l2.DValue(1))
|
|
1217
|
+
); }
|
|
1218
|
+
|
|
1219
|
+
Vec<2> DivShape()
|
|
1220
|
+
{
|
|
1221
|
+
// todo
|
|
1222
|
+
// double lam1 = l1.Value();
|
|
1223
|
+
double lam1x = l1.DValue(0);
|
|
1224
|
+
double lam1y = l1.DValue(1);
|
|
1225
|
+
// double lam2 = l2.Value();
|
|
1226
|
+
double lam2x = l2.DValue(0);
|
|
1227
|
+
double lam2y = l2.DValue(1);
|
|
1228
|
+
return Vec<2> (
|
|
1229
|
+
v.DValue(0)*(lam1y*lam2y) - 0.5*v.DValue(1)*(lam1x*lam2y+lam1y*lam2x),
|
|
1230
|
+
-0.5*v.DValue(0)*(lam1x*lam2y+lam1y*lam2x) + v.DValue(1)*(lam1x*lam2x)
|
|
1231
|
+
);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
};
|
|
1235
|
+
|
|
1236
|
+
template <int D, typename T>
|
|
1237
|
+
auto Sigma_Duv_minus_uDv_w (AutoDiffDiff<D,T> au, AutoDiffDiff<D,T> av, AutoDiffDiff<D,T> aw)
|
|
1238
|
+
{ return T_Sigma_Duv_minus_uDv_w<D,T>(au, av, aw); }
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
template <ELEMENT_TYPE ET> class HDivDivFE : public T_HDivDivFE<ET>
|
|
1242
|
+
{
|
|
1243
|
+
protected:
|
|
1244
|
+
using T_HDivDivFE<ET> :: order;
|
|
1245
|
+
using T_HDivDivFE<ET> :: ndof;
|
|
1246
|
+
public:
|
|
1247
|
+
template <typename T, typename TFA>
|
|
1248
|
+
void T_CalcShape (TIP<ET_trait<ET>::DIM,AutoDiffDiff<ET_trait<ET>::DIM,T>> ip, TFA & shape) const
|
|
1249
|
+
{
|
|
1250
|
+
throw Exception ("Hdivdivfe not implementend for element type");
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
template <typename MIP, typename TFA>
|
|
1254
|
+
void CalcDualShape2 (const MIP & mip, TFA & shape) const
|
|
1255
|
+
{
|
|
1256
|
+
throw Exception ("Hdivdivfe not implementend for element type");
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
template <> class HDivDivFE<ET_TRIG> : public T_HDivDivFE<ET_TRIG>
|
|
1262
|
+
{
|
|
1263
|
+
|
|
1264
|
+
public:
|
|
1265
|
+
using T_HDivDivFE<ET_TRIG> :: T_HDivDivFE;
|
|
1266
|
+
|
|
1267
|
+
virtual void ComputeNDof()
|
|
1268
|
+
{
|
|
1269
|
+
order = 0;
|
|
1270
|
+
ndof = 0;
|
|
1271
|
+
for (int i=0; i<3; i++)
|
|
1272
|
+
{
|
|
1273
|
+
ndof += order_facet[i][0]+1;
|
|
1274
|
+
order = max2(order, order_facet[i][0]);
|
|
1275
|
+
}
|
|
1276
|
+
int ninner = 3*order_inner[0]*(order_inner[0]+1)/2 ;
|
|
1277
|
+
order = max2(order, order_inner[0]);
|
|
1278
|
+
if (plus)
|
|
1279
|
+
{
|
|
1280
|
+
order ++;
|
|
1281
|
+
ninner += 2*order_inner[0];
|
|
1282
|
+
}
|
|
1283
|
+
ndof += ninner;
|
|
1284
|
+
|
|
1285
|
+
}
|
|
1286
|
+
template <typename T, typename TFA>
|
|
1287
|
+
void T_CalcShape (TIP<2,AutoDiffDiff<2,T>> ip, TFA & shape) const
|
|
1288
|
+
{
|
|
1289
|
+
// typedef decltype(ip.x.Value()+ip.x.Value()) T;
|
|
1290
|
+
typedef AutoDiffDiff<2, T> Tx;
|
|
1291
|
+
Tx x = ip.x, y = ip.y;
|
|
1292
|
+
Tx ddlami[3] ={ x, y, 1-x-y };
|
|
1293
|
+
|
|
1294
|
+
int ii = 0;
|
|
1295
|
+
|
|
1296
|
+
int maxorder_facet =
|
|
1297
|
+
max2(order_facet[0][0],max2(order_facet[1][0],order_facet[2][0]));
|
|
1298
|
+
|
|
1299
|
+
const EDGE * edges = ElementTopology::GetEdges(ET_TRIG);
|
|
1300
|
+
|
|
1301
|
+
ArrayMem<Tx,20> ha(maxorder_facet+1);
|
|
1302
|
+
ArrayMem<Tx,20> u(order_inner[0]+2), v(order_inner[0]+2);
|
|
1303
|
+
|
|
1304
|
+
for (int i = 0; i < 3; i++)
|
|
1305
|
+
{
|
|
1306
|
+
int es = edges[i][0], ee = edges[i][1];
|
|
1307
|
+
if (vnums[es] > vnums[ee]) swap (es,ee);
|
|
1308
|
+
|
|
1309
|
+
Tx ls = ddlami[es], le = ddlami[ee];
|
|
1310
|
+
|
|
1311
|
+
// edge functions are all div-free!
|
|
1312
|
+
IntegratedLegendreMonomialExt::CalcTrigExt(maxorder_facet+2,
|
|
1313
|
+
le-ls, 1-le-ls, ha);
|
|
1314
|
+
|
|
1315
|
+
//ScaledLegendrePolynomial(maxorder_facet,le-ls, 1-le-ls,ha);
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
for (int l = 0; l <= order_facet[i][0]; l++)
|
|
1319
|
+
shape[ii++] = SigmaGrad (ha[l]);
|
|
1320
|
+
//shape[ii++] = SymRotRot_Dl2xDl1_v_diffdiff(le, ls, ha[l]);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
int es = 0; int ee = 1; int et = 2;
|
|
1324
|
+
Tx ls = ddlami[es];
|
|
1325
|
+
Tx le = ddlami[ee];
|
|
1326
|
+
Tx lt = ddlami[et];
|
|
1327
|
+
|
|
1328
|
+
int oi=order_inner[0];
|
|
1329
|
+
int oi_plus = oi; //plus ? oi+1 : oi;
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
IntegratedLegendreMonomialExt::CalcTrigExt(oi_plus+3,le-ls,1-le-ls,u);
|
|
1333
|
+
LegendrePolynomial::EvalMult(oi_plus+1, 2*lt-1, lt, v);
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
for(int i = 0; i <= oi-1; i++)
|
|
1337
|
+
{
|
|
1338
|
+
for(int j = 0; j+i <= oi-1; j++)
|
|
1339
|
+
{
|
|
1340
|
+
shape[ii++] = SigmaGrad(u[i]*v[j]);
|
|
1341
|
+
shape[ii++] = Type2(u[i],v[j]);
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
for(int i = 0; i <= oi_plus-1; i++)
|
|
1345
|
+
{
|
|
1346
|
+
for(int j = 0; j+i <= oi_plus-1; j++)
|
|
1347
|
+
{
|
|
1348
|
+
if(j > 0)
|
|
1349
|
+
shape[ii++] = Type3(u[i],v[j]);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
for (int i = 0; i < oi_plus; i++)
|
|
1354
|
+
shape[ii++] = Sigma_Duv_minus_uDv_w (le, -ls, v[i]);
|
|
1355
|
+
|
|
1356
|
+
//// element bubbles for Sigma+ space
|
|
1357
|
+
if (plus)
|
|
1358
|
+
for (int i = 0; i <= oi-1; i++)
|
|
1359
|
+
{
|
|
1360
|
+
Tx bubble = u[i]*v[oi-1-i];
|
|
1361
|
+
shape[ii++] = Sigma_u_Gradv(bubble, x);
|
|
1362
|
+
shape[ii++] = Sigma_u_Gradv(bubble, y);
|
|
1363
|
+
}
|
|
1364
|
+
};
|
|
1365
|
+
|
|
1366
|
+
template <typename MIP, typename TFA>
|
|
1367
|
+
void CalcDualShape2 (const MIP & mip, TFA & shape) const
|
|
1368
|
+
{
|
|
1369
|
+
auto & ip = mip.IP();
|
|
1370
|
+
typedef typename std::remove_const<typename std::remove_reference<decltype(mip.IP()(0))>::type>::type T;
|
|
1371
|
+
T x = ip(0), y = ip(1);
|
|
1372
|
+
T lam[3] = { x, y, 1-x-y };
|
|
1373
|
+
Vec<2,T> pnts[3] = { { 1, 0 }, { 0, 1 } , { 0, 0 } };
|
|
1374
|
+
int facetnr = ip.FacetNr();
|
|
1375
|
+
|
|
1376
|
+
int ii = 0;
|
|
1377
|
+
|
|
1378
|
+
// const EDGE * edges = ElementTopology::GetEdges(ET_TRIG);
|
|
1379
|
+
|
|
1380
|
+
if (ip.VB() == BND)
|
|
1381
|
+
{ // facet shapes
|
|
1382
|
+
for (int i = 0; i < 3; i++)
|
|
1383
|
+
{
|
|
1384
|
+
int p = order_facet[i][0];
|
|
1385
|
+
|
|
1386
|
+
if (i == facetnr)
|
|
1387
|
+
{
|
|
1388
|
+
IVec<2> e = ET_trait<ET_TRIG>::GetEdgeSort (i, vnums);
|
|
1389
|
+
|
|
1390
|
+
T xi = lam[e[0]]-lam[e[1]];
|
|
1391
|
+
Vec<2,T> tauref = pnts[e[0]] - pnts[e[1]];
|
|
1392
|
+
|
|
1393
|
+
Vec<2,T> nvref = Vec<2,T>(tauref[1],-tauref[0]);
|
|
1394
|
+
auto nv = Trans(mip.GetJacobianInverse())*nvref;
|
|
1395
|
+
auto nn = DyadProd(nv,nv);
|
|
1396
|
+
|
|
1397
|
+
LegendrePolynomial::Eval
|
|
1398
|
+
(p, xi,
|
|
1399
|
+
SBLambda([&] (size_t nr, T val)
|
|
1400
|
+
{
|
|
1401
|
+
shape[nr+ii] = mip.GetMeasure()*val*nn;
|
|
1402
|
+
}));
|
|
1403
|
+
}
|
|
1404
|
+
ii += (p+1);
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
else
|
|
1408
|
+
{
|
|
1409
|
+
for (int i = 0; i < 3; i++)
|
|
1410
|
+
ii += order_facet[i][0]+1;
|
|
1411
|
+
}
|
|
1412
|
+
if (ip.VB() == VOL)
|
|
1413
|
+
{
|
|
1414
|
+
auto p = order_inner[0]-1;
|
|
1415
|
+
if( p >= 0 )
|
|
1416
|
+
{
|
|
1417
|
+
DubinerBasis::Eval (p, lam[0], lam[1],
|
|
1418
|
+
SBLambda([&] (size_t nr, T val)
|
|
1419
|
+
{
|
|
1420
|
+
shape[ii++] = val*mip.GetMeasure()*mip.GetJacobian()*Mat<2,2>({{1,0},{0,0}})*Trans(mip.GetJacobian());
|
|
1421
|
+
shape[ii++] = val*mip.GetMeasure()*mip.GetJacobian()*Mat<2,2>({{0,0},{0,1}})*Trans(mip.GetJacobian());
|
|
1422
|
+
shape[ii++] = val*mip.GetMeasure()*mip.GetJacobian()*Mat<2,2>({{0,1},{1,0}})*Trans(mip.GetJacobian());
|
|
1423
|
+
}));
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
};
|
|
1429
|
+
|
|
1430
|
+
template <> class HDivDivFE<ET_QUAD> : public T_HDivDivFE<ET_QUAD>
|
|
1431
|
+
{
|
|
1432
|
+
|
|
1433
|
+
public:
|
|
1434
|
+
using T_HDivDivFE<ET_QUAD> :: T_HDivDivFE;
|
|
1435
|
+
|
|
1436
|
+
enum {incsg = -1};
|
|
1437
|
+
enum {incsugv = -1};
|
|
1438
|
+
|
|
1439
|
+
virtual void ComputeNDof()
|
|
1440
|
+
{
|
|
1441
|
+
order = 0;
|
|
1442
|
+
ndof = 0;
|
|
1443
|
+
for (int i=0; i<4; i++)
|
|
1444
|
+
{
|
|
1445
|
+
ndof += order_facet[i][0]+1;
|
|
1446
|
+
order = max2(order, order_facet[i][0]);
|
|
1447
|
+
}
|
|
1448
|
+
int ninner = (order_inner[0]+1+incsg)*(order_inner[0]+1+incsg) +
|
|
1449
|
+
(order_inner[0]+2)*(order_inner[0]) *2 +
|
|
1450
|
+
2*(order_inner[0]+1+incsugv) +1;
|
|
1451
|
+
|
|
1452
|
+
/*
|
|
1453
|
+
int ninner = (order_inner[0]+1+incsg)*(order_inner[0]+1+incsg) +
|
|
1454
|
+
(order_inner[0]+1)*(order_inner[0]) *2 +
|
|
1455
|
+
2*(order_inner[0]+1+incsugv) +2;
|
|
1456
|
+
if (plus) ninner += order_inner[0]*2;
|
|
1457
|
+
*/
|
|
1458
|
+
order = max2(order, order_inner[0]);
|
|
1459
|
+
order += 1;
|
|
1460
|
+
ndof += ninner;
|
|
1461
|
+
|
|
1462
|
+
}
|
|
1463
|
+
template <typename T, typename TFA>
|
|
1464
|
+
void T_CalcShape (TIP<2,AutoDiffDiff<2,T>> ip, TFA & shape) const
|
|
1465
|
+
{
|
|
1466
|
+
// typedef decltype(ip.x.Value()+ip.x.Value()) T;
|
|
1467
|
+
typedef AutoDiffDiff<2, T> Tx;
|
|
1468
|
+
|
|
1469
|
+
Tx x = ip.x, y = ip.y;
|
|
1470
|
+
Tx lx[4] ={1-x, x, x, 1-x};
|
|
1471
|
+
Tx ly[4] = {1-y, 1-y, y, y};
|
|
1472
|
+
|
|
1473
|
+
int ii = 0;
|
|
1474
|
+
|
|
1475
|
+
const EDGE * edges = ElementTopology::GetEdges(ET_QUAD);
|
|
1476
|
+
|
|
1477
|
+
ArrayMem<Tx,20> u(order+2), v(order+2);
|
|
1478
|
+
|
|
1479
|
+
for (int i = 0; i < 4; i++)
|
|
1480
|
+
{
|
|
1481
|
+
int es = edges[i][0], ee = edges[i][1];
|
|
1482
|
+
if (vnums[es] > vnums[ee]) swap (es,ee);
|
|
1483
|
+
|
|
1484
|
+
Tx xi = lx[ee]+ly[ee]-lx[es]-ly[es];
|
|
1485
|
+
Tx eta = lx[es]*ly[es]+lx[ee]*ly[ee];
|
|
1486
|
+
|
|
1487
|
+
IntegratedLegendreMonomialExt::Calc(order_facet[i][0]+2,xi,u);
|
|
1488
|
+
|
|
1489
|
+
|
|
1490
|
+
for (int l = 0; l <= order_facet[i][0]; l++)
|
|
1491
|
+
// shape[ii++] = SigmaGrad (eta*u[l]);
|
|
1492
|
+
shape[ii++] = Sigma_u_Gradv (eta, u[l]);
|
|
1493
|
+
// shape[ii++] = vSigmaGradu(u[i],eta);
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
int oi=order_inner[0];
|
|
1498
|
+
|
|
1499
|
+
IntegratedLegendreMonomialExt::Calc(oi+3,lx[0]-lx[1],u);
|
|
1500
|
+
IntegratedLegendreMonomialExt::Calc(oi+3,ly[0]-ly[2],v);
|
|
1501
|
+
|
|
1502
|
+
// original
|
|
1503
|
+
for(int i = 0; i <= oi+incsg; i++)
|
|
1504
|
+
{
|
|
1505
|
+
for(int j = 0; j <= oi+incsg; j++)
|
|
1506
|
+
{
|
|
1507
|
+
shape[ii++] = SigmaGrad(u[i]*v[j]);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
for(int i = 0; i <= oi+1; i++)
|
|
1511
|
+
{
|
|
1512
|
+
for(int j = 0; j <= oi-1; j++)
|
|
1513
|
+
{
|
|
1514
|
+
shape[ii++] = vSigmaGradu(u[i],v[j]);
|
|
1515
|
+
shape[ii++] = vSigmaGradu(v[i],u[j]);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
shape[ii++] = Sigma_u_Gradv(lx[0], ly[0]);
|
|
1520
|
+
|
|
1521
|
+
for(int i = 0; i <= oi+incsugv; i++)
|
|
1522
|
+
{
|
|
1523
|
+
shape[ii++] = Sigma_u_Gradv(u[i], ly[0]);
|
|
1524
|
+
shape[ii++] = Sigma_u_Gradv(v[i], lx[0]); //
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
return;
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
|
|
1531
|
+
for (int i = 0; i <= oi+incsg+1; i++)
|
|
1532
|
+
for (int j = 0; j <= oi+incsg+1; j++)
|
|
1533
|
+
shape[ii++] = SigmaGrad(u[i]*v[j]);
|
|
1534
|
+
|
|
1535
|
+
/*
|
|
1536
|
+
for (int j = 0; j <= oi-1; j++)
|
|
1537
|
+
{
|
|
1538
|
+
shape[ii++] = SigmaGrad(u[oi+incsg+1]*v[j]);
|
|
1539
|
+
shape[ii++] = SigmaGrad(v[oi+incsg+1]*u[j]);
|
|
1540
|
+
}
|
|
1541
|
+
*/
|
|
1542
|
+
|
|
1543
|
+
for (int i = 0; i <= oi-1; i++)
|
|
1544
|
+
for (int j = 0; j <= oi-1; j++)
|
|
1545
|
+
{
|
|
1546
|
+
shape[ii++] = vSigmaGradu(u[i],v[j]);
|
|
1547
|
+
shape[ii++] = vSigmaGradu(v[i],u[j]);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
if (plus)
|
|
1551
|
+
for (int j = 0; j <= oi-1; j++)
|
|
1552
|
+
{
|
|
1553
|
+
// shape[ii++] = vSigmaGradu(u[oi+1],v[j]);
|
|
1554
|
+
// shape[ii++] = vSigmaGradu(v[oi+1],u[j]);
|
|
1555
|
+
|
|
1556
|
+
shape[ii++] = Sigma_u_Gradv(v[j], u[oi]);
|
|
1557
|
+
shape[ii++] = Sigma_u_Gradv(u[j], v[oi]);
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
// shape[ii++] = Sigma_u_Gradv(lx[0], ly[0]);
|
|
1561
|
+
shape[ii++] = SigmaGrad((2*x-1)*(2*y-1));
|
|
1562
|
+
|
|
1563
|
+
for (int i = 0; i <= oi+incsugv; i++)
|
|
1564
|
+
{
|
|
1565
|
+
shape[ii++] = Sigma_u_Gradv(u[i], ly[0]);
|
|
1566
|
+
shape[ii++] = Sigma_u_Gradv(v[i], lx[0]); //
|
|
1567
|
+
}
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
template <typename MIP, typename TFA>
|
|
1571
|
+
void CalcDualShape2 (const MIP & mip, TFA & shape) const
|
|
1572
|
+
{
|
|
1573
|
+
throw Exception ("Hdivdivfe not implementend for element type");
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
|
|
1580
|
+
class HDivDivFE_QuadFullPol : public T_HDivDivFE<ET_QUAD, HDivDivFE_QuadFullPol>
|
|
1581
|
+
{
|
|
1582
|
+
|
|
1583
|
+
public:
|
|
1584
|
+
using T_HDivDivFE<ET_QUAD,HDivDivFE_QuadFullPol> :: T_HDivDivFE;
|
|
1585
|
+
|
|
1586
|
+
virtual void ComputeNDof()
|
|
1587
|
+
{
|
|
1588
|
+
order = 0;
|
|
1589
|
+
ndof = 0;
|
|
1590
|
+
for (int i=0; i<4; i++)
|
|
1591
|
+
{
|
|
1592
|
+
ndof += order_facet[i][0]+1;
|
|
1593
|
+
order = max2(order, order_facet[i][0]);
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
int ninner = 1 // sigma grad(xy)
|
|
1597
|
+
+ 2 * (order_inner[0]+1)*(order_inner[0]+2) // inner nedelec
|
|
1598
|
+
+ sqr(order_inner[0]+1)
|
|
1599
|
+
;
|
|
1600
|
+
if (plus)
|
|
1601
|
+
ninner += 4*order_inner[0] + 4;
|
|
1602
|
+
order = max2(order, order_inner[0]);
|
|
1603
|
+
order += 2;
|
|
1604
|
+
if (plus) order++;
|
|
1605
|
+
ndof += ninner;
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
template <typename T, typename TFA>
|
|
1609
|
+
void T_CalcShape (TIP<2,AutoDiffDiff<2,T>> ip, TFA & shape) const
|
|
1610
|
+
{
|
|
1611
|
+
typedef AutoDiffDiff<2, T> Tx;
|
|
1612
|
+
|
|
1613
|
+
Tx x = ip.x, y = ip.y;
|
|
1614
|
+
Tx lx[4] ={1-x, x, x, 1-x};
|
|
1615
|
+
Tx ly[4] = {1-y, 1-y, y, y};
|
|
1616
|
+
|
|
1617
|
+
int ii = 0;
|
|
1618
|
+
|
|
1619
|
+
const EDGE * edges = ElementTopology::GetEdges(ET_QUAD);
|
|
1620
|
+
|
|
1621
|
+
ArrayMem<Tx,20> u(order+2), v(order+2);
|
|
1622
|
+
|
|
1623
|
+
for (int i = 0; i < 4; i++)
|
|
1624
|
+
{
|
|
1625
|
+
int es = edges[i][0], ee = edges[i][1];
|
|
1626
|
+
if (vnums[es] > vnums[ee]) swap (es,ee);
|
|
1627
|
+
|
|
1628
|
+
Tx xi = lx[ee]+ly[ee]-lx[es]-ly[es];
|
|
1629
|
+
Tx eta = lx[es]*ly[es]+lx[ee]*ly[ee];
|
|
1630
|
+
|
|
1631
|
+
IntegratedLegendreMonomialExt::Calc(order_facet[i][0]+2,xi,u);
|
|
1632
|
+
|
|
1633
|
+
for (int l = 0; l <= order_facet[i][0]; l++)
|
|
1634
|
+
// shape[ii++] = SigmaGrad (eta*u[l]);
|
|
1635
|
+
shape[ii++] = Sigma_u_Gradv (eta, u[l]);
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// shape[ii++] = SigmaGrad((2*x-1)*(2*y-1));
|
|
1639
|
+
shape[ii++] = Sigma_u_Gradv((2*x-1),(2*y-1));
|
|
1640
|
+
|
|
1641
|
+
int oi=order_inner[0];
|
|
1642
|
+
|
|
1643
|
+
LegendrePolynomial (oi+1, 2*x-1, u);
|
|
1644
|
+
LegendrePolynomial (oi+1, 2*y-1, v);
|
|
1645
|
+
auto bubx = x*(1-x);
|
|
1646
|
+
auto buby = y*(1-y);
|
|
1647
|
+
for (int i = 0; i <= oi; i++)
|
|
1648
|
+
for (int j = 0; j <= oi+1; j++)
|
|
1649
|
+
{
|
|
1650
|
+
shape[ii++] = Sigma_u_Gradv(bubx*u[i]*v[j], 2*y-1);
|
|
1651
|
+
shape[ii++] = Sigma_u_Gradv(buby*u[j]*v[i], 2*x-1);
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
if (plus)
|
|
1655
|
+
{
|
|
1656
|
+
for (int i = 0; i <= oi; i++)
|
|
1657
|
+
{
|
|
1658
|
+
shape[ii++] = Sigma_u_Gradv(bubx*buby*u[i]*v[oi], 2*y-1);
|
|
1659
|
+
shape[ii++] = Sigma_u_Gradv(bubx*buby*u[oi]*v[i], 2*x-1);
|
|
1660
|
+
shape[ii++] = Sigma_u_Gradv(bubx*buby*u[i]*v[oi+1], 2*y-1);
|
|
1661
|
+
shape[ii++] = Sigma_u_Gradv(bubx*buby*u[oi+1]*v[i], 2*x-1);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
for (int i = 0; i <= oi; i++)
|
|
1666
|
+
for (int j = 0; j <= oi; j++)
|
|
1667
|
+
shape[ii++] = vSigmaGradu(bubx,u[i]*v[j]*buby);
|
|
1668
|
+
|
|
1669
|
+
|
|
1670
|
+
if (ii != ndof)
|
|
1671
|
+
cerr << "Hdivdivfe, full quad, ndof = " << ndof << " != ii = " << ii << endl;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
|
|
1675
|
+
template <typename MIP, typename TFA>
|
|
1676
|
+
void CalcDualShape2 (const MIP & mip, TFA & shape) const
|
|
1677
|
+
{
|
|
1678
|
+
throw Exception ("Hdivdivfe not implementend for quadfullpol");
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
};
|
|
1682
|
+
|
|
1683
|
+
|
|
1684
|
+
|
|
1685
|
+
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
|
|
1690
|
+
|
|
1691
|
+
|
|
1692
|
+
|
|
1693
|
+
// ***************** S_zz(uvw) ****************************** */
|
|
1694
|
+
// write uvw into zz component
|
|
1695
|
+
template <int D> class T_S_zz;
|
|
1696
|
+
template <> class T_S_zz<3>
|
|
1697
|
+
{
|
|
1698
|
+
AutoDiff<2> u, v;
|
|
1699
|
+
AutoDiff<1> w;
|
|
1700
|
+
public:
|
|
1701
|
+
T_S_zz ( AutoDiff<2> au, AutoDiff<2> av, AutoDiff<1> aw) : u(au), v(av), w(aw) { ; }
|
|
1702
|
+
Vec<6> Shape()
|
|
1703
|
+
{
|
|
1704
|
+
Vec<6> sigma(0.);
|
|
1705
|
+
sigma[2] = u.Value()*v.Value()*w.Value();
|
|
1706
|
+
return sigma;
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
Vec<3> DivShape()
|
|
1710
|
+
{
|
|
1711
|
+
return Vec<3> (0., 0., u.Value()*v.Value()*w.DValue(0));
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
};
|
|
1715
|
+
|
|
1716
|
+
template <int D>
|
|
1717
|
+
auto S_zz (AutoDiff<D> au, AutoDiff<D> av, AutoDiff<1> aw)
|
|
1718
|
+
{ return T_S_zz<D+1>(au, av, aw); }
|
|
1719
|
+
|
|
1720
|
+
// ***************** S_xz ****************************** */
|
|
1721
|
+
template <int D, typename T> class T_S_xz;
|
|
1722
|
+
template <typename T> class T_S_xz<3,T>
|
|
1723
|
+
{
|
|
1724
|
+
AutoDiff<2,T> uv;
|
|
1725
|
+
AutoDiff<1,T> w;
|
|
1726
|
+
|
|
1727
|
+
int comp;
|
|
1728
|
+
public:
|
|
1729
|
+
T_S_xz ( int acomp, AutoDiff<2,T> auv, AutoDiff<1,T> aw) : uv(auv), w(aw), comp(acomp) { ; }
|
|
1730
|
+
Vec<6,T> Shape()
|
|
1731
|
+
{
|
|
1732
|
+
Vec<6,T> sigma;
|
|
1733
|
+
sigma = 0.;
|
|
1734
|
+
if (comp==0)
|
|
1735
|
+
sigma[4] = uv.Value()*w.Value();
|
|
1736
|
+
else
|
|
1737
|
+
sigma[3] = uv.Value()*w.Value();
|
|
1738
|
+
return sigma;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
Vec<3,T> DivShape()
|
|
1742
|
+
{
|
|
1743
|
+
if (comp == 0)
|
|
1744
|
+
return Vec<3,T> (uv.Value()*w.DValue(0), 0, uv.DValue(0)*w.Value() );
|
|
1745
|
+
else
|
|
1746
|
+
return Vec<3,T> (0, uv.Value()*w.DValue(0), uv.DValue(1)*w.Value() );
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
};
|
|
1750
|
+
|
|
1751
|
+
template <int D, typename T>
|
|
1752
|
+
auto S_xz (int comp, AutoDiff<D,T> auv, AutoDiff<1,T> aw)
|
|
1753
|
+
{ return T_S_xz<D+1,T>(comp,auv, aw); }
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
template <typename T>
|
|
1758
|
+
class T_Prism_wSigmaGradu
|
|
1759
|
+
{
|
|
1760
|
+
AutoDiffDiff<2,T> u;
|
|
1761
|
+
AutoDiff<1,T> w;
|
|
1762
|
+
public:
|
|
1763
|
+
T_Prism_wSigmaGradu ( AutoDiffDiff<2,T> au, AutoDiff<1,T> aw) : u(au), w(aw) { ; }
|
|
1764
|
+
Vec<6,T> Shape()
|
|
1765
|
+
{
|
|
1766
|
+
Vec<3,T> sigma2d = T_SigmaGrad<2,T>(u).Shape();
|
|
1767
|
+
Vec<6,T> sigma(0.);
|
|
1768
|
+
sigma[0] = w.Value()*sigma2d[0];
|
|
1769
|
+
sigma[1] = w.Value()*sigma2d[1];
|
|
1770
|
+
sigma[5] = w.Value()*sigma2d[2];
|
|
1771
|
+
return sigma;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
Vec<3,T> DivShape()
|
|
1775
|
+
{
|
|
1776
|
+
return Vec<3,T> (0., 0., 0);
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
};
|
|
1780
|
+
|
|
1781
|
+
template <typename T>
|
|
1782
|
+
auto Prism_wSigmaGradu ( AutoDiffDiff<2,T> au, AutoDiff<1,T> aw)
|
|
1783
|
+
{ return T_Prism_wSigmaGradu<T>(au, aw); }
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
template <typename T>
|
|
1787
|
+
class T_Prism_wType2
|
|
1788
|
+
{
|
|
1789
|
+
AutoDiffDiff<2,T> u, v;
|
|
1790
|
+
AutoDiff<1,T> w;
|
|
1791
|
+
public:
|
|
1792
|
+
T_Prism_wType2 ( AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av, AutoDiff<1,T> aw) : u(au), v(av), w(aw) { ; }
|
|
1793
|
+
Vec<6,T> Shape()
|
|
1794
|
+
{
|
|
1795
|
+
Vec<3,T> sigma2d = T_Type2<2,T>(u,v).Shape();
|
|
1796
|
+
Vec<6,T> sigma(0.);
|
|
1797
|
+
sigma[0] = w.Value()*sigma2d[0];
|
|
1798
|
+
sigma[1] = w.Value()*sigma2d[1];
|
|
1799
|
+
sigma[5] = w.Value()*sigma2d[2];
|
|
1800
|
+
return sigma;
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
Vec<3,T> DivShape()
|
|
1804
|
+
{
|
|
1805
|
+
Vec<2> divsigma2d = w.Value()*T_Type2<2,T>(u,v).DivShape();
|
|
1806
|
+
return Vec<3,T> (divsigma2d[0], divsigma2d[1], 0);
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
};
|
|
1810
|
+
|
|
1811
|
+
template <typename T>
|
|
1812
|
+
auto Prism_wType2 (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av, AutoDiff<1,T> aw)
|
|
1813
|
+
{ return T_Prism_wType2<T>(au, av, aw); }
|
|
1814
|
+
|
|
1815
|
+
|
|
1816
|
+
template <typename T>
|
|
1817
|
+
class T_Prism_wType3
|
|
1818
|
+
{
|
|
1819
|
+
AutoDiffDiff<2,T> u, v;
|
|
1820
|
+
AutoDiff<1,T> w;
|
|
1821
|
+
public:
|
|
1822
|
+
T_Prism_wType3 ( AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av, AutoDiff<1,T> aw) : u(au), v(av), w(aw) { ; }
|
|
1823
|
+
Vec<6> Shape()
|
|
1824
|
+
{
|
|
1825
|
+
Vec<3,T> sigma2d = T_Type3<2,T>(u,v).Shape();
|
|
1826
|
+
Vec<6,T> sigma(0.);
|
|
1827
|
+
sigma[0] = w.Value()*sigma2d[0];
|
|
1828
|
+
sigma[1] = w.Value()*sigma2d[1];
|
|
1829
|
+
sigma[5] = w.Value()*sigma2d[2];
|
|
1830
|
+
return sigma;
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
Vec<3,T> DivShape()
|
|
1834
|
+
{
|
|
1835
|
+
Vec<2,T> divsigma2d = w.Value()*T_Type3<2,T>(u,v).DivShape();
|
|
1836
|
+
return Vec<3,T> (divsigma2d[0], divsigma2d[1], 0);
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1839
|
+
|
|
1840
|
+
template <typename T>
|
|
1841
|
+
auto Prism_wType3 (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av, AutoDiff<1,T> aw)
|
|
1842
|
+
{ return T_Prism_wType3<T>(au, av, aw); }
|
|
1843
|
+
|
|
1844
|
+
|
|
1845
|
+
template <typename T>
|
|
1846
|
+
class T_Prism_wType4
|
|
1847
|
+
{
|
|
1848
|
+
AutoDiffDiff<2,T> u, v, w;
|
|
1849
|
+
AutoDiff<1,T> wz;
|
|
1850
|
+
public:
|
|
1851
|
+
T_Prism_wType4 ( AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av, AutoDiffDiff<2,T> aw, AutoDiff<1,T> awz) : u(au), v(av), w(aw), wz(awz) { ; }
|
|
1852
|
+
Vec<6,T> Shape()
|
|
1853
|
+
{
|
|
1854
|
+
Vec<3,T> sigma2d = wz.Value()*T_Sigma_Duv_minus_uDv_w<2,T>(u,v,w).Shape();
|
|
1855
|
+
Vec<6,T> sigma(0.);
|
|
1856
|
+
sigma[0] = sigma2d[0];
|
|
1857
|
+
sigma[1] = sigma2d[1];
|
|
1858
|
+
sigma[5] = sigma2d[2];
|
|
1859
|
+
return sigma;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
Vec<3,T> DivShape()
|
|
1863
|
+
{
|
|
1864
|
+
Vec<2,T> divsigma2d = wz.Value()*T_Sigma_Duv_minus_uDv_w<2,T>(u,v,w).DivShape();
|
|
1865
|
+
return Vec<3,T> (divsigma2d[0], divsigma2d[1], 0);
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
};
|
|
1869
|
+
|
|
1870
|
+
template <typename T>
|
|
1871
|
+
auto Prism_wType4 (AutoDiffDiff<2,T> au, AutoDiffDiff<2,T> av, AutoDiffDiff<2,T> aw, AutoDiff<1,T> awz)
|
|
1872
|
+
{ return T_Prism_wType4<T>(au, av, aw, awz); }
|
|
1873
|
+
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
class Prism_SymRotRot_Dl2xDl1_vw
|
|
1877
|
+
{
|
|
1878
|
+
AutoDiff<2> l1,l2,v;
|
|
1879
|
+
AutoDiff<1> wz;
|
|
1880
|
+
public:
|
|
1881
|
+
Prism_SymRotRot_Dl2xDl1_vw ( AutoDiff<2> lam1, AutoDiff<2> lam2, AutoDiff<2> av, AutoDiff<1> awz) : l1(lam1), l2(lam2), v(av), wz(awz) { ; }
|
|
1882
|
+
Vec<6> Shape()
|
|
1883
|
+
{
|
|
1884
|
+
Vec<3> sigma2d = wz.Value()*T_SymRotRot_Dl2xDl1_v(l1,l2,v).Shape();
|
|
1885
|
+
Vec<6> sigma(0.);
|
|
1886
|
+
sigma[0] = sigma2d[0];
|
|
1887
|
+
sigma[1] = sigma2d[1];
|
|
1888
|
+
sigma[5] = sigma2d[2];
|
|
1889
|
+
return sigma;
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
Vec<3> DivShape()
|
|
1893
|
+
{
|
|
1894
|
+
Vec<2> divsigma2d = wz.Value()*T_SymRotRot_Dl2xDl1_v(l1,l2,v).DivShape();
|
|
1895
|
+
return Vec<3> (divsigma2d[0], divsigma2d[1], 0);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
};
|
|
1899
|
+
|
|
1900
|
+
template <typename T>
|
|
1901
|
+
class Prism_Dl1xDl3_symtensor_Dl2xDl4_u
|
|
1902
|
+
{
|
|
1903
|
+
AutoDiff<3,T> l1,l2,l3, l4;
|
|
1904
|
+
AutoDiff<3,T> u;
|
|
1905
|
+
public:
|
|
1906
|
+
Prism_Dl1xDl3_symtensor_Dl2xDl4_u ( AutoDiff<3,T> lam1, AutoDiff<3,T> lam2, AutoDiff<3,T> alz1, AutoDiff<3,T> alz2, AutoDiff<3,T> av)
|
|
1907
|
+
: l1(lam1), l2(lam2), l3(alz1), l4(alz2), u(av) { ; }
|
|
1908
|
+
INLINE Vec<6,T> Shape()
|
|
1909
|
+
{
|
|
1910
|
+
auto rotlam1 = Cross(l1, l3);
|
|
1911
|
+
auto rotlam2 = Cross(l2, l4);
|
|
1912
|
+
|
|
1913
|
+
Vec<6,T> sigma(0.);
|
|
1914
|
+
sigma[0] = u.Value()*rotlam1.DValue(0)*rotlam2.DValue(0);
|
|
1915
|
+
sigma[1] = u.Value()*rotlam1.DValue(1)*rotlam2.DValue(1);
|
|
1916
|
+
sigma[2] = u.Value()*rotlam1.DValue(2)*rotlam2.DValue(2);
|
|
1917
|
+
sigma[3] = 0.5*u.Value()*(rotlam1.DValue(2)*rotlam2.DValue(1) + rotlam2.DValue(2)*rotlam1.DValue(1));
|
|
1918
|
+
sigma[4] = 0.5*u.Value()*(rotlam1.DValue(2)*rotlam2.DValue(0) + rotlam2.DValue(2)*rotlam1.DValue(0));
|
|
1919
|
+
sigma[5] = 0.5*u.Value()*(rotlam1.DValue(0)*rotlam2.DValue(1) + rotlam2.DValue(0)*rotlam1.DValue(1));
|
|
1920
|
+
return sigma;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
INLINE AutoDiff<3,T> Cross (const AutoDiff<3,T> & x,
|
|
1924
|
+
const AutoDiff<3,T> & y)
|
|
1925
|
+
{
|
|
1926
|
+
T hv[3];
|
|
1927
|
+
hv[0] = x.DValue(1)*y.DValue(2)-x.DValue(2)*y.DValue(1);
|
|
1928
|
+
hv[1] = x.DValue(2)*y.DValue(0)-x.DValue(0)*y.DValue(2);
|
|
1929
|
+
hv[2] = x.DValue(0)*y.DValue(1)-x.DValue(1)*y.DValue(0);
|
|
1930
|
+
return AutoDiff<3,T> (0,hv);
|
|
1931
|
+
}
|
|
1932
|
+
Vec<3,T> DivShape()
|
|
1933
|
+
{
|
|
1934
|
+
auto lam1 = Cross(l1, l3);
|
|
1935
|
+
auto lam2 = Cross(l2, l4);
|
|
1936
|
+
return Vec<3,T> (u.DValue(0)*lam1.DValue(0)*lam2.DValue(0) +
|
|
1937
|
+
0.5*(u.DValue(1)*(lam1.DValue(0)*lam2.DValue(1)+lam2.DValue(0)*lam1.DValue(1)) + u.DValue(2)*(lam1.DValue(0)*lam2.DValue(2)+lam2.DValue(0)*lam1.DValue(2))),
|
|
1938
|
+
u.DValue(1)*lam1.DValue(1)*lam2.DValue(1) +
|
|
1939
|
+
0.5*(u.DValue(0)*(lam1.DValue(0)*lam2.DValue(1)+lam2.DValue(0)*lam1.DValue(1)) + u.DValue(2)*(lam1.DValue(1)*lam2.DValue(2)+lam2.DValue(1)*lam1.DValue(2))),
|
|
1940
|
+
u.DValue(2)*lam1.DValue(2)*lam2.DValue(2) +
|
|
1941
|
+
0.5*(u.DValue(0)*(lam1.DValue(0)*lam2.DValue(2)+lam2.DValue(0)*lam1.DValue(2)) + u.DValue(1)*(lam1.DValue(1)*lam2.DValue(2)+lam2.DValue(1)*lam1.DValue(2)))
|
|
1942
|
+
);
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
};
|
|
1946
|
+
|
|
1947
|
+
|
|
1948
|
+
template <typename T>
|
|
1949
|
+
class t1_symtensor_t2_u
|
|
1950
|
+
{
|
|
1951
|
+
AutoDiff<3,T> t1, t2;
|
|
1952
|
+
AutoDiff<3,T> u;
|
|
1953
|
+
public:
|
|
1954
|
+
t1_symtensor_t2_u (AutoDiff<3,T> at1, AutoDiff<3,T> at2, AutoDiff<3,T> au)
|
|
1955
|
+
: t1(at1), t2(at2), u(au) { ; }
|
|
1956
|
+
INLINE Vec<6,T> Shape()
|
|
1957
|
+
{
|
|
1958
|
+
//auto rotlam1 = t1;
|
|
1959
|
+
//auto rotlam2 = t2;
|
|
1960
|
+
|
|
1961
|
+
Vec<6,T> sigma(0.);
|
|
1962
|
+
sigma[0] = t1.DValue(0)*t2.DValue(0);
|
|
1963
|
+
sigma[1] = t1.DValue(1)*t2.DValue(1);
|
|
1964
|
+
sigma[2] = t1.DValue(2)*t2.DValue(2);
|
|
1965
|
+
sigma[3] = 0.5*(t1.DValue(2)*t2.DValue(1) + t2.DValue(2)*t1.DValue(1));
|
|
1966
|
+
sigma[4] = 0.5*(t1.DValue(2)*t2.DValue(0) + t2.DValue(2)*t1.DValue(0));
|
|
1967
|
+
sigma[5] = 0.5*(t1.DValue(0)*t2.DValue(1) + t2.DValue(0)*t1.DValue(1));
|
|
1968
|
+
return u.Value()*sigma;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
Vec<3,T> DivShape()
|
|
1972
|
+
{
|
|
1973
|
+
T ut1 = 0.5*(u.DValue(0)*t1.DValue(0) + u.DValue(1)*t1.DValue(1) + u.DValue(2)*t1.DValue(2));
|
|
1974
|
+
T ut2 = 0.5*(u.DValue(0)*t2.DValue(0) + u.DValue(1)*t2.DValue(1) + u.DValue(2)*t2.DValue(2));
|
|
1975
|
+
return Vec<3,T> (ut1*t2.DValue(0) + ut2*t1.DValue(0),
|
|
1976
|
+
ut1*t2.DValue(1) + ut2*t1.DValue(1),
|
|
1977
|
+
ut1*t2.DValue(2) + ut2*t1.DValue(2));
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
};
|
|
1981
|
+
|
|
1982
|
+
|
|
1983
|
+
|
|
1984
|
+
|
|
1985
|
+
template <> class HDivDivFE<ET_PRISM> : public T_HDivDivFE<ET_PRISM>
|
|
1986
|
+
{
|
|
1987
|
+
public:
|
|
1988
|
+
// order k+1 for certain components, for inner and boundary shapes
|
|
1989
|
+
// analysis from TDNNS paper for case xx1=0, zz1=xx2=zz2=1 for inner and boundary shapes
|
|
1990
|
+
// however, works also when boundary order is not increased.. check
|
|
1991
|
+
enum { incrorder_xx1 = 0};
|
|
1992
|
+
enum { incrorder_zz1 = 1};
|
|
1993
|
+
enum { incrorder_xx2 = 1};
|
|
1994
|
+
enum { incrorder_zz2 = 1};
|
|
1995
|
+
enum { incrorder_xx1_bd = 0};
|
|
1996
|
+
enum { incrorder_zz1_bd = 0};
|
|
1997
|
+
enum { incrorder_xx2_bd = 0};
|
|
1998
|
+
enum { incrorder_zz2_bd = 0};
|
|
1999
|
+
using T_HDivDivFE<ET_PRISM> :: T_HDivDivFE;
|
|
2000
|
+
|
|
2001
|
+
virtual void ComputeNDof()
|
|
2002
|
+
{
|
|
2003
|
+
order = 0;
|
|
2004
|
+
ndof = 0;
|
|
2005
|
+
for (int i=0; i<2; i++)
|
|
2006
|
+
{
|
|
2007
|
+
ndof += (order_facet[i][0]+1+incrorder_zz1_bd)*(order_facet[i][0]+2+incrorder_zz1_bd)/2;
|
|
2008
|
+
order = max2(order, order_facet[i][0]+incrorder_zz1_bd);
|
|
2009
|
+
}
|
|
2010
|
+
for (int i=2; i<5; i++)
|
|
2011
|
+
{
|
|
2012
|
+
ndof += (order_facet[i][0]+1+incrorder_xx1_bd)*(order_facet[i][1]+1+incrorder_xx2_bd);
|
|
2013
|
+
order = max2(order, order_facet[i][0]+incrorder_xx2_bd);
|
|
2014
|
+
}
|
|
2015
|
+
int oi0 = order_inner[0];
|
|
2016
|
+
int oi2 = order_inner[2];
|
|
2017
|
+
int ninner = 3*((oi0+1+incrorder_xx1)*(oi0+incrorder_xx1))/2 *(oi2+1+incrorder_xx2)
|
|
2018
|
+
+ (oi0+1)*(oi0+2)*(oi2+1)
|
|
2019
|
+
+ (oi0+1+incrorder_zz1)*(oi0+2+incrorder_zz1)*(oi2-1+incrorder_zz2)/2;
|
|
2020
|
+
ndof += ninner;
|
|
2021
|
+
|
|
2022
|
+
order = max3(order, oi0+incrorder_zz1, oi2+incrorder_zz2);
|
|
2023
|
+
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
// works only with old-style Transformation
|
|
2027
|
+
// does not work with CalcMappedShape
|
|
2028
|
+
template <typename Tx, typename TFA>
|
|
2029
|
+
void T_CalcShape_Complex (TIP<3,Tx> ip, TFA & shape) const
|
|
2030
|
+
{
|
|
2031
|
+
AutoDiffDiff<2> x(ip.x.Value(),0);
|
|
2032
|
+
AutoDiffDiff<2> y(ip.y.Value(),1);
|
|
2033
|
+
AutoDiff<2> xd(ip.x.Value(),0);
|
|
2034
|
+
AutoDiff<2> yd(ip.y.Value(),1);
|
|
2035
|
+
AutoDiff<1> z(ip.z.Value(), 0);
|
|
2036
|
+
AutoDiffDiff<2> lami[6] ={ x,y,1-x-y,x,y,1-x-y };
|
|
2037
|
+
AutoDiff<2> lamid[6] ={ xd,yd,1-xd-yd,xd,yd,1-xd-yd };
|
|
2038
|
+
AutoDiff<1> lamiz[6] ={ 1-z,1-z,1-z,z,z,z };
|
|
2039
|
+
|
|
2040
|
+
int ii = 0;
|
|
2041
|
+
|
|
2042
|
+
int maxorder_facet =
|
|
2043
|
+
max2(order_facet[0][0],max2(order_facet[1][0],order_facet[2][0]));
|
|
2044
|
+
|
|
2045
|
+
const FACE * faces = ElementTopology::GetFaces(ET_PRISM);
|
|
2046
|
+
|
|
2047
|
+
ArrayMem<AutoDiffDiff<2>,20> ha(maxorder_facet+2);
|
|
2048
|
+
ArrayMem<AutoDiffDiff<2>,20> u(order+2), v(order+3);
|
|
2049
|
+
ArrayMem<AutoDiff<2>,20> leg_u(order+2), leg_v(order+3);
|
|
2050
|
+
ArrayMem<AutoDiff<1>,20> leg_w(order+2);
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
// Trig faces, (p+1)(p+2)/2
|
|
2054
|
+
for (int fa=0; fa<2; fa++)
|
|
2055
|
+
{
|
|
2056
|
+
int fav[3] ={faces[fa][0],faces[fa][1],faces[fa][2]};
|
|
2057
|
+
|
|
2058
|
+
//Sort vertices first edge op minimal vertex
|
|
2059
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0],fav[1]);
|
|
2060
|
+
if(vnums[fav[1]] > vnums[fav[2]]) swap(fav[1],fav[2]);
|
|
2061
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0],fav[1]);
|
|
2062
|
+
|
|
2063
|
+
leg_u.SetSize(order_facet[fa][0]+incrorder_zz1_bd+1);
|
|
2064
|
+
leg_v.SetSize(order_facet[fa][0]+incrorder_zz1_bd+1);
|
|
2065
|
+
ScaledLegendrePolynomial(order_facet[fa][0]+incrorder_zz1_bd,lamid[fav[0]]-lamid[fav[1]],1-lamid[fav[0]]-lamid[fav[1]],leg_u);
|
|
2066
|
+
LegendrePolynomial::Eval(order_facet[fa][0]+incrorder_zz1_bd,2 * lamid[fav[2]] - 1,leg_v);
|
|
2067
|
+
|
|
2068
|
+
for(int j = 0; j <= order_facet[fa][0]+incrorder_zz1_bd; j++)
|
|
2069
|
+
for(int k = 0; k <= order_facet[fa][0]+incrorder_zz1_bd-j; k++)
|
|
2070
|
+
shape[ii++] = S_zz(leg_u[j],leg_v[k],lamiz[fav[0]]);
|
|
2071
|
+
}
|
|
2072
|
+
// quad faces -- use face bubbles of trig multiplied by leg_w
|
|
2073
|
+
// (px+1)(pz+1)
|
|
2074
|
+
for(int fa = 2; fa < 5; fa++)
|
|
2075
|
+
{
|
|
2076
|
+
int fmax = 0;
|
|
2077
|
+
for(int j = 1; j < 4; j++)
|
|
2078
|
+
if(vnums[faces[fa][j]] > vnums[faces[fa][fmax]]) fmax = j;
|
|
2079
|
+
|
|
2080
|
+
int fz,ftrig;
|
|
2081
|
+
|
|
2082
|
+
fz = 3 - fmax;
|
|
2083
|
+
ftrig = fmax^1;
|
|
2084
|
+
|
|
2085
|
+
fmax = faces[fa][fmax];
|
|
2086
|
+
fz = faces[fa][fz];
|
|
2087
|
+
ftrig = faces[fa][ftrig];
|
|
2088
|
+
|
|
2089
|
+
|
|
2090
|
+
// int orderz = order_facet[fa][1];
|
|
2091
|
+
|
|
2092
|
+
bool rotate = false;
|
|
2093
|
+
if(vnums[fz] > vnums[ftrig]) rotate = true;
|
|
2094
|
+
leg_w.SetSize(order_facet[fa][1]+incrorder_xx2_bd+1);
|
|
2095
|
+
ha.SetSize(order_facet[fa][0]+incrorder_xx1_bd+1);
|
|
2096
|
+
LegendrePolynomial::Eval(order_facet[fa][1]+incrorder_xx2_bd,lamiz[fmax]*2-1,leg_w);
|
|
2097
|
+
|
|
2098
|
+
|
|
2099
|
+
// edge functions are all div-free!
|
|
2100
|
+
IntegratedLegendreMonomialExt::CalcTrigExt(order_facet[fa][0]+incrorder_xx1_bd+2,
|
|
2101
|
+
lami[fmax]-lami[ftrig],1-lami[fmax]-lami[ftrig],ha);
|
|
2102
|
+
|
|
2103
|
+
if(rotate)
|
|
2104
|
+
for(int k = 0; k <= order_facet[fa][1]+incrorder_xx2_bd; k++)
|
|
2105
|
+
for(int l = 0; l <= order_facet[fa][0]+incrorder_xx1_bd; l++)
|
|
2106
|
+
{
|
|
2107
|
+
shape[ii++] = Prism_wSigmaGradu(ha[l],leg_w[k]);
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
else
|
|
2111
|
+
for(int l = 0; l <= order_facet[fa][0]+incrorder_xx1_bd; l++)
|
|
2112
|
+
for(int k = 0; k <= order_facet[fa][1]+incrorder_xx2_bd; k++)
|
|
2113
|
+
{
|
|
2114
|
+
shape[ii++] = Prism_wSigmaGradu(ha[l],leg_w[k]);
|
|
2115
|
+
}
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
|
|
2121
|
+
|
|
2122
|
+
int oi = order_inner[0];
|
|
2123
|
+
leg_u.SetSize(oi+incrorder_zz1+1);
|
|
2124
|
+
leg_v.SetSize(oi+incrorder_zz1+1);
|
|
2125
|
+
leg_w.SetSize(oi+incrorder_xx2+1);
|
|
2126
|
+
u.SetSize(oi-1+incrorder_xx1+1);
|
|
2127
|
+
v.SetSize(oi-1+incrorder_xx1+1);
|
|
2128
|
+
|
|
2129
|
+
ScaledLegendrePolynomial(oi+incrorder_zz1, lamid[0]-lamid[1], 1-lamid[0]-lamid[1], leg_u);
|
|
2130
|
+
LegendrePolynomial::Eval(oi+incrorder_zz1, 2*lamid[2]-1, leg_v);
|
|
2131
|
+
LegendrePolynomial::Eval(oi+incrorder_xx2, 2*lamiz[0]-1, leg_w);
|
|
2132
|
+
|
|
2133
|
+
// ------------------------------------
|
|
2134
|
+
// based on elasticity-complex-based triangle shapes
|
|
2135
|
+
IntegratedLegendreMonomialExt::CalcTrigExt(oi-1+incrorder_xx1+2,lami[0]-lami[1],1-lami[0]-lami[1],u);
|
|
2136
|
+
LegendrePolynomial::EvalMult(oi-1+incrorder_xx1,2*lami[2]-1, lami[2], v);
|
|
2137
|
+
for(int k=0; k<=oi+incrorder_xx2; k++)
|
|
2138
|
+
{
|
|
2139
|
+
for(int i = 0; i <= oi-1+incrorder_xx1; i++)
|
|
2140
|
+
{
|
|
2141
|
+
for(int j = 0; j+i <= oi-1+incrorder_xx1; j++)
|
|
2142
|
+
{
|
|
2143
|
+
shape[ii++] = Prism_wSigmaGradu(u[i]*v[j],leg_w[k]);
|
|
2144
|
+
shape[ii++] = Prism_wType2(u[i],v[j],leg_w[k]);
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
for(int i = 0; i <= oi-1+incrorder_xx1; i++)
|
|
2148
|
+
{
|
|
2149
|
+
for(int j = 0; j+i <= oi-1+incrorder_xx1; j++)
|
|
2150
|
+
{
|
|
2151
|
+
if(j > 0)
|
|
2152
|
+
{
|
|
2153
|
+
shape[ii++] = Prism_wType3(u[i],v[j],leg_w[k]);
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
for (int i = 0; i < oi+incrorder_xx1; i++)
|
|
2158
|
+
{
|
|
2159
|
+
shape[ii++] = Prism_wType4 (lami[0], -lami[1], v[i],leg_w[k]);
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
// S_xz
|
|
2165
|
+
for (int i=0; i<=oi; i++)
|
|
2166
|
+
{
|
|
2167
|
+
for (int j=0; j+i<=oi; j++)
|
|
2168
|
+
{
|
|
2169
|
+
AutoDiff<2> uv = leg_u[i]*leg_v[j];
|
|
2170
|
+
for (int k=0; k<=oi; k++)
|
|
2171
|
+
{
|
|
2172
|
+
shape[ii++] = S_xz(0,uv, leg_w[k]);
|
|
2173
|
+
shape[ii++] = S_xz(1,uv, leg_w[k]);
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
// S_zz
|
|
2179
|
+
for(int k=0; k<=oi-2+incrorder_zz2; k++)
|
|
2180
|
+
{
|
|
2181
|
+
AutoDiff<1> bubw = leg_w[k]*lamiz[0]*(1-lamiz[0]);
|
|
2182
|
+
for(int i=0; i<=oi+incrorder_zz1; i++)
|
|
2183
|
+
{
|
|
2184
|
+
for(int j=0; j<=oi+incrorder_zz1-i; j++)
|
|
2185
|
+
{
|
|
2186
|
+
shape[ii++] = S_zz(leg_u[i],leg_v[j],bubw);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
};
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
|
|
2196
|
+
|
|
2197
|
+
// alternative to T_CalcShape, with "simpler" shape functions,
|
|
2198
|
+
// that are described in anisotropic paper
|
|
2199
|
+
// works with CalcMappedShape etc. routines, also for curved elements
|
|
2200
|
+
template <typename T, typename TFA>
|
|
2201
|
+
void T_CalcShape/*_nocomplex*/ (TIP<3,AutoDiff<3,T>> ip, TFA & shape) const
|
|
2202
|
+
{
|
|
2203
|
+
// Tx x = ip.x, y = ip.y, z = ip.z;
|
|
2204
|
+
AutoDiffDiff<3,T> x = ip.x, y = ip.y, z = ip.z;
|
|
2205
|
+
// typedef decltype(x.Value()+x.Value()) T;
|
|
2206
|
+
AutoDiff<3,T> xx(x.Value(), &x.DValue(0));
|
|
2207
|
+
AutoDiff<3,T> yy(y.Value(), &y.DValue(0));
|
|
2208
|
+
AutoDiff<3,T> zz(z.Value(), &z.DValue(0));
|
|
2209
|
+
AutoDiff<3,T> lx[6] ={ xx, yy, 1-xx-yy, xx, yy, 1-xx-yy };
|
|
2210
|
+
AutoDiff<3,T> lz[6] ={ 1-zz,1-zz,1-zz,zz,zz,zz };
|
|
2211
|
+
int ii = 0;
|
|
2212
|
+
|
|
2213
|
+
// int maxorder_facet =
|
|
2214
|
+
// max2(order_facet[0][0],max2(order_facet[1][0],order_facet[2][0]));
|
|
2215
|
+
|
|
2216
|
+
const FACE * faces = ElementTopology::GetFaces(ET_PRISM);
|
|
2217
|
+
|
|
2218
|
+
ArrayMem<AutoDiff<3,T>,20> leg_u(order+2), leg_v(order+3);
|
|
2219
|
+
ArrayMem<AutoDiff<3,T>,20> leg_w(order+2);
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
// Trig faces, (p+1)(p+2)/2
|
|
2223
|
+
for (int fa=0; fa<2; fa++)
|
|
2224
|
+
{
|
|
2225
|
+
int fav[3] ={faces[fa][0],faces[fa][1],faces[fa][2]};
|
|
2226
|
+
|
|
2227
|
+
//Sort vertices first edge op minimal vertex
|
|
2228
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0],fav[1]);
|
|
2229
|
+
if(vnums[fav[1]] > vnums[fav[2]]) swap(fav[1],fav[2]);
|
|
2230
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0],fav[1]);
|
|
2231
|
+
|
|
2232
|
+
leg_u.SetSize(order_facet[fa][0]+incrorder_zz1_bd+1);
|
|
2233
|
+
leg_v.SetSize(order_facet[fa][0]+incrorder_zz1_bd+1);
|
|
2234
|
+
ScaledLegendrePolynomial(order_facet[fa][0]+incrorder_zz1_bd,lx[fav[0]]-lx[fav[1]],lx[fav[0]]+lx[fav[1]],leg_u);
|
|
2235
|
+
LegendrePolynomial::Eval(order_facet[fa][0]+incrorder_zz1_bd,2 * lx[fav[2]] - 1,leg_v);
|
|
2236
|
+
|
|
2237
|
+
for(int j = 0; j <= order_facet[fa][0]+incrorder_zz1_bd; j++)
|
|
2238
|
+
for(int k = 0; k <= order_facet[fa][0]+incrorder_zz1_bd-j; k++)
|
|
2239
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[fav[0]], lx[fav[1]], lx[fav[2]], lx[fav[2]], leg_u[j]*leg_v[k]*lz[fav[0]]);
|
|
2240
|
+
}
|
|
2241
|
+
// quad faces -- use face bubbles of trig multiplied by leg_w
|
|
2242
|
+
// (px+1)(pz+1)
|
|
2243
|
+
for(int fa = 2; fa < 5; fa++)
|
|
2244
|
+
{
|
|
2245
|
+
int fmax = 0;
|
|
2246
|
+
for(int j = 1; j < 4; j++)
|
|
2247
|
+
if(vnums[faces[fa][j]] > vnums[faces[fa][fmax]]) fmax = j;
|
|
2248
|
+
|
|
2249
|
+
int fz,ftrig;
|
|
2250
|
+
|
|
2251
|
+
fz = 3 - fmax;
|
|
2252
|
+
ftrig = fmax^1;
|
|
2253
|
+
|
|
2254
|
+
fmax = faces[fa][fmax];
|
|
2255
|
+
fz = faces[fa][fz];
|
|
2256
|
+
ftrig = faces[fa][ftrig];
|
|
2257
|
+
|
|
2258
|
+
|
|
2259
|
+
// int orderz = order_facet[fa][1];
|
|
2260
|
+
|
|
2261
|
+
bool rotate = false;
|
|
2262
|
+
if(vnums[fz] > vnums[ftrig]) rotate = true;
|
|
2263
|
+
leg_w.SetSize(order_facet[fa][1]+incrorder_xx2_bd+1);
|
|
2264
|
+
LegendrePolynomial::Eval(order_facet[fa][1]+incrorder_xx2_bd,lz[fmax]*2-1,leg_w);
|
|
2265
|
+
|
|
2266
|
+
|
|
2267
|
+
ScaledLegendrePolynomial(order_facet[fa][0]+incrorder_xx1_bd, lx[fmax]-lx[ftrig], lx[fmax]+lx[ftrig], leg_u);
|
|
2268
|
+
|
|
2269
|
+
if(rotate)
|
|
2270
|
+
for(int k = 0; k <= order_facet[fa][1]+incrorder_xx2_bd; k++)
|
|
2271
|
+
for(int l = 0; l <= order_facet[fa][0]+incrorder_xx1_bd; l++)
|
|
2272
|
+
{
|
|
2273
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lz[fmax], lz[fz], lx[fmax], lx[ftrig], leg_u[l]* leg_w[k]);
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
else
|
|
2277
|
+
for(int l = 0; l <= order_facet[fa][0]+incrorder_xx1_bd; l++)
|
|
2278
|
+
for(int k = 0; k <= order_facet[fa][1]+incrorder_xx2_bd; k++)
|
|
2279
|
+
{
|
|
2280
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[fmax], lx[ftrig], lz[fmax], lz[fz], leg_u[l]* leg_w[k]);
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
|
|
2288
|
+
int oi = order_inner[0];
|
|
2289
|
+
leg_u.SetSize(oi+incrorder_zz1+1);
|
|
2290
|
+
leg_v.SetSize(oi+incrorder_zz1+1);
|
|
2291
|
+
leg_w.SetSize(oi+incrorder_xx2+1);
|
|
2292
|
+
|
|
2293
|
+
ScaledLegendrePolynomial(oi+incrorder_zz1, lx[0]-lx[1], lx[0]+lx[1], leg_u);
|
|
2294
|
+
LegendrePolynomial::Eval(oi+incrorder_zz1, 2*lx[2]-1, leg_v);
|
|
2295
|
+
LegendrePolynomial::Eval(oi+incrorder_xx2, 2*lz[0]-1, leg_w);
|
|
2296
|
+
|
|
2297
|
+
for(int k=0; k<=oi+incrorder_xx2; k++)
|
|
2298
|
+
{
|
|
2299
|
+
for(int i = 0; i <= oi-1+incrorder_xx1; i++)
|
|
2300
|
+
{
|
|
2301
|
+
for(int j = 0; j+i <= oi-1+incrorder_xx1; j++)
|
|
2302
|
+
{
|
|
2303
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[0], lx[1], lz[0], lz[0], lx[2]*leg_u[i]*leg_v[j]* leg_w[k]);
|
|
2304
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[2], lx[0], lz[0], lz[0], lx[1]*leg_u[i]*leg_v[j]* leg_w[k]);
|
|
2305
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[1], lx[2], lz[0], lz[0], lx[0]*leg_u[i]*leg_v[j]* leg_w[k]);
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
|
|
2311
|
+
// S_xz
|
|
2312
|
+
for (int i=0; i<=oi; i++)
|
|
2313
|
+
{
|
|
2314
|
+
for (int j=0; j+i<=oi; j++)
|
|
2315
|
+
{
|
|
2316
|
+
for (int k=0; k<=oi; k++)
|
|
2317
|
+
{
|
|
2318
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lz[0], lx[1], lx[0], lx[0], leg_u[i]*leg_v[j]*leg_w[k]);
|
|
2319
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lz[0], lx[0], lx[1], lx[1], leg_u[i]*leg_v[j]*leg_w[k]);
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
// S_zz
|
|
2325
|
+
for(int k=0; k<=oi-2+incrorder_zz2; k++)
|
|
2326
|
+
{
|
|
2327
|
+
AutoDiff<3,T> bubw = leg_w[k]*lz[0]*(1-lz[0]);
|
|
2328
|
+
for(int i=0; i<=oi+incrorder_zz1; i++)
|
|
2329
|
+
{
|
|
2330
|
+
for(int j=0; j<=oi+incrorder_zz1-i; j++)
|
|
2331
|
+
{
|
|
2332
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[0], lx[2], lx[1], lx[1], leg_u[i]*leg_v[j]*bubw);
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
|
|
2338
|
+
};
|
|
2339
|
+
|
|
2340
|
+
template <typename MIP, typename TFA>
|
|
2341
|
+
void CalcDualShape2 (const MIP & mip, TFA & shape) const
|
|
2342
|
+
{
|
|
2343
|
+
throw Exception ("Hdivdivfe not implementend for element type");
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
|
|
2347
|
+
};
|
|
2348
|
+
|
|
2349
|
+
|
|
2350
|
+
template <> class HDivDivFE<ET_TET> : public T_HDivDivFE<ET_TET>
|
|
2351
|
+
{
|
|
2352
|
+
public:
|
|
2353
|
+
using T_HDivDivFE<ET_TET> :: T_HDivDivFE;
|
|
2354
|
+
|
|
2355
|
+
virtual void ComputeNDof()
|
|
2356
|
+
{
|
|
2357
|
+
order = 0;
|
|
2358
|
+
ndof = 0;
|
|
2359
|
+
for (int i=0; i<4; i++)
|
|
2360
|
+
{
|
|
2361
|
+
ndof += (order_facet[i][0]+1)*(order_facet[i][0]+2)/2;
|
|
2362
|
+
order = max2(order, order_facet[i][0]);
|
|
2363
|
+
}
|
|
2364
|
+
int p = order_inner[0];
|
|
2365
|
+
int ninner = (p+1)*(p+2)*(p+1);
|
|
2366
|
+
ndof += ninner;
|
|
2367
|
+
|
|
2368
|
+
order = max2(order, p);
|
|
2369
|
+
if (plus)
|
|
2370
|
+
{
|
|
2371
|
+
ndof += 2*(p+1)*(p+2);
|
|
2372
|
+
order = max2(order, p+1);
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
|
|
2377
|
+
template <typename T, typename TFA>
|
|
2378
|
+
void T_CalcShape (TIP<3,AutoDiff<3,T>> ip, TFA & shape) const
|
|
2379
|
+
{
|
|
2380
|
+
AutoDiff<3,T> lam[4] = { ip.x, ip.y, ip.z, 1.0-ip.x-ip.y-ip.z };
|
|
2381
|
+
size_t ii = 0;
|
|
2382
|
+
|
|
2383
|
+
//const FACE * faces = ElementTopology::GetFaces(ET_TET);
|
|
2384
|
+
|
|
2385
|
+
/*
|
|
2386
|
+
ArrayMem<AutoDiff<3,T>,20> leg_u(order+2), leg_v(order+3);
|
|
2387
|
+
ArrayMem<AutoDiff<3,T>,20> leg_w(order+2);
|
|
2388
|
+
*/
|
|
2389
|
+
|
|
2390
|
+
typedef AutoDiff<3,T> ADT;
|
|
2391
|
+
STACK_ARRAY(ADT, leg_u, order+2);
|
|
2392
|
+
STACK_ARRAY(ADT, leg_v, order+3);
|
|
2393
|
+
|
|
2394
|
+
for(int fa = 0; fa < 4; fa++)
|
|
2395
|
+
{
|
|
2396
|
+
int p = order_facet[fa][0];
|
|
2397
|
+
/*
|
|
2398
|
+
// int fav[3] = {faces[fa][0], faces[fa][1], faces[fa][2]};
|
|
2399
|
+
//Sort vertices first edge op minimal vertex
|
|
2400
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0], fav[1]);
|
|
2401
|
+
if(vnums[fav[1]] > vnums[fav[2]]) swap(fav[1], fav[2]);
|
|
2402
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0], fav[1]);
|
|
2403
|
+
*/
|
|
2404
|
+
|
|
2405
|
+
IVec<4> fav = GetVertexOrientedFace (fa);
|
|
2406
|
+
|
|
2407
|
+
ScaledLegendrePolynomial(p+1, lam[fav[0]]-lam[fav[1]],lam[fav[0]]+lam[fav[1]], &leg_u[0]);
|
|
2408
|
+
LegendrePolynomial::Eval(p+1, 2 * lam[fav[2]] - 1, &leg_v[0]);
|
|
2409
|
+
|
|
2410
|
+
auto t1 = Cross(lam[fav[0]], lam[fav[2]]);
|
|
2411
|
+
auto t2 = Cross(lam[fav[1]], lam[fav[2]]);
|
|
2412
|
+
for(int j = 0; j <= p; j++)
|
|
2413
|
+
for(int k = 0; k+j <= p; k++)
|
|
2414
|
+
{
|
|
2415
|
+
/*
|
|
2416
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[fav[0]], lam[fav[1]],
|
|
2417
|
+
lam[fav[2]], lam[fav[2]],leg_u[j]* leg_v[k]);
|
|
2418
|
+
*/
|
|
2419
|
+
shape[ii++] = t1_symtensor_t2_u<T>(t1, t2, leg_u[j]* leg_v[k]);
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
int oi = order_inner[0];
|
|
2424
|
+
/*
|
|
2425
|
+
leg_u.SetSize(oi+1);
|
|
2426
|
+
leg_v.SetSize(oi+1);
|
|
2427
|
+
leg_w.SetSize(oi+1);
|
|
2428
|
+
|
|
2429
|
+
ScaledLegendrePolynomial(oi+1,lam[0]-lam[1],lam[0]+lam[1],leg_u);
|
|
2430
|
+
ScaledLegendrePolynomial(oi+1,lam[2]-lam[0]-lam[1],lam[0]+lam[1]+lam[2],leg_v);
|
|
2431
|
+
LegendrePolynomial::Eval(oi+1,2 * lam[3] - 1,leg_w);
|
|
2432
|
+
|
|
2433
|
+
|
|
2434
|
+
for(int k=0; k<=oi; k++)
|
|
2435
|
+
{
|
|
2436
|
+
for(int i = 0; i+k <= oi; i++)
|
|
2437
|
+
{
|
|
2438
|
+
for(int j = 0; j+i+k <= oi; j++)
|
|
2439
|
+
{
|
|
2440
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[0], lam[1], lam[2], lam[3], leg_u[i]*leg_v[k]* leg_w[j]);
|
|
2441
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[0], lam[2], lam[1], lam[3], leg_u[i]*leg_v[j]* leg_w[k]);
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
for(int fa = 0; fa < 4; fa++)
|
|
2447
|
+
{
|
|
2448
|
+
int fav[3] = {faces[fa][0], faces[fa][1], faces[fa][2]};
|
|
2449
|
+
for(int k=0; k<=oi-1; k++)
|
|
2450
|
+
{
|
|
2451
|
+
for(int i = 0; i+k <= oi-1; i++)
|
|
2452
|
+
{
|
|
2453
|
+
for(int j = 0; j+i+k <= oi-1; j++)
|
|
2454
|
+
{
|
|
2455
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[fav[0]],lam[fav[0]],lam[fav[1]],lam[fav[2]],
|
|
2456
|
+
(1-lam[fav[0]]-lam[fav[1]]-lam[fav[2]])*leg_u[i]*leg_v[k]* leg_w[j]);
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
}
|
|
2462
|
+
*/
|
|
2463
|
+
auto l0 = lam[0];
|
|
2464
|
+
auto l1 = lam[1];
|
|
2465
|
+
auto l2 = lam[2];
|
|
2466
|
+
auto l3 = lam[3];
|
|
2467
|
+
auto t01 = Cross(lam[0], lam[1]);
|
|
2468
|
+
auto t02 = Cross(lam[0], lam[2]);
|
|
2469
|
+
auto t03 = Cross(lam[0], lam[3]);
|
|
2470
|
+
auto t12 = Cross(lam[1], lam[2]);
|
|
2471
|
+
auto t13 = Cross(lam[1], lam[3]);
|
|
2472
|
+
auto t23 = Cross(lam[2], lam[3]);
|
|
2473
|
+
DubinerBasis3D::Eval
|
|
2474
|
+
(oi, lam[0], lam[1], lam[2],
|
|
2475
|
+
SBLambda([shape, &ii, t02, t13, t01, t23] (size_t nr, auto val) LAMBDA_INLINE
|
|
2476
|
+
{
|
|
2477
|
+
/*
|
|
2478
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[0], lam[1], lam[2], lam[3], val);
|
|
2479
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[0], lam[2], lam[1], lam[3], val);
|
|
2480
|
+
*/
|
|
2481
|
+
shape[ii++] = t1_symtensor_t2_u<T>(t02, t13, val);
|
|
2482
|
+
shape[ii++] = t1_symtensor_t2_u<T>(t01, t23, val);
|
|
2483
|
+
}));
|
|
2484
|
+
|
|
2485
|
+
DubinerBasis3D::Eval
|
|
2486
|
+
(oi-1 + (plus?1:0), lam[0], lam[1], lam[2],
|
|
2487
|
+
SBLambda([shape, &ii, t02, t03, t12, t13, t01, t23, l0,l1,l2,l3] (size_t nr, auto val) LAMBDA_INLINE
|
|
2488
|
+
{
|
|
2489
|
+
shape[ii++] = t1_symtensor_t2_u<T>(t01, t02, l3*val);
|
|
2490
|
+
shape[ii++] = t1_symtensor_t2_u<T>(t03, t13, l2*val);
|
|
2491
|
+
shape[ii++] = t1_symtensor_t2_u<T>(t23, t02, l1*val);
|
|
2492
|
+
shape[ii++] = t1_symtensor_t2_u<T>(t12, t13, l0*val);
|
|
2493
|
+
/*
|
|
2494
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[0], lam[0], lam[1], lam[2], lam[3]*val);
|
|
2495
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[3], lam[3], lam[0], lam[1], lam[2]*val);
|
|
2496
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[2], lam[2], lam[3], lam[0], lam[1]*val);
|
|
2497
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lam[1], lam[1], lam[2], lam[3], lam[0]*val);
|
|
2498
|
+
*/
|
|
2499
|
+
}));
|
|
2500
|
+
|
|
2501
|
+
/*
|
|
2502
|
+
if (plus)
|
|
2503
|
+
{
|
|
2504
|
+
// needs AutoDiffDiff !!!
|
|
2505
|
+
auto l0 = lam[0];
|
|
2506
|
+
auto l1 = lam[1];
|
|
2507
|
+
auto l2 = lam[2];
|
|
2508
|
+
auto l3 = lam[3];
|
|
2509
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l0, l1, l1*l2*l3, l2, AutoDiff<3,T>(1.0));
|
|
2510
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l0, l1, l1*l2*l3, l3, AutoDiff<3,T>(1.0));
|
|
2511
|
+
|
|
2512
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l1, l2, l0*l2*l3, l0, AutoDiff<3,T>(1.0));
|
|
2513
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l1, l2, l0*l2*l3, l3, AutoDiff<3,T>(1.0));
|
|
2514
|
+
|
|
2515
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l2, l3, l1*l0*l3, l0, AutoDiff<3,T>(1.0));
|
|
2516
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l2, l3, l1*l0*l3, l1, AutoDiff<3,T>(1.0));
|
|
2517
|
+
|
|
2518
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l3, l0, l1*l2*l0, l1, AutoDiff<3,T>(1.0));
|
|
2519
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T> (l3, l0, l1*l2*l0, l2, AutoDiff<3,T>(1.0));
|
|
2520
|
+
}
|
|
2521
|
+
*/
|
|
2522
|
+
};
|
|
2523
|
+
|
|
2524
|
+
template <typename MIP, typename TFA>
|
|
2525
|
+
void CalcDualShape2 (const MIP & mip, TFA & shape) const
|
|
2526
|
+
{
|
|
2527
|
+
throw Exception ("Hdivdivfe not implementend for element type");
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
};
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
template <> class HDivDivFE<ET_HEX> : public T_HDivDivFE<ET_HEX>
|
|
2535
|
+
{
|
|
2536
|
+
public:
|
|
2537
|
+
using T_HDivDivFE<ET_HEX> :: T_HDivDivFE;
|
|
2538
|
+
|
|
2539
|
+
virtual void ComputeNDof()
|
|
2540
|
+
{
|
|
2541
|
+
order = 0;
|
|
2542
|
+
ndof = 0;
|
|
2543
|
+
for (int i=0; i<6; i++)
|
|
2544
|
+
{
|
|
2545
|
+
ndof += (order_facet[i][0]+1)*(order_facet[i][0]+1);
|
|
2546
|
+
order = max2(order, order_facet[i][0]+1);
|
|
2547
|
+
}
|
|
2548
|
+
int p = order_inner[0];
|
|
2549
|
+
int ninner = 3*p*(p+2)*(p+2) + 3*(p+2)*(p+1)*(p+1);
|
|
2550
|
+
ndof += ninner;
|
|
2551
|
+
|
|
2552
|
+
order = max2(order, p+1);
|
|
2553
|
+
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
|
|
2557
|
+
template <typename T, typename TFA>
|
|
2558
|
+
void T_CalcShape (TIP<3,AutoDiff<3,T>> ip, TFA & shape) const
|
|
2559
|
+
{
|
|
2560
|
+
AutoDiffDiff<3,T> x = ip.x, y = ip.y, z = ip.z;
|
|
2561
|
+
// typedef decltype(x.Value()+x.Value()) T;
|
|
2562
|
+
AutoDiff<3,T> xx(x.Value(), &x.DValue(0));
|
|
2563
|
+
AutoDiff<3,T> yy(y.Value(), &y.DValue(0));
|
|
2564
|
+
AutoDiff<3,T> zz(z.Value(), &z.DValue(0));
|
|
2565
|
+
AutoDiff<3,T> lx[2] ={ 1-xx, xx};
|
|
2566
|
+
AutoDiff<3,T> ly[2] ={ 1-yy, yy};
|
|
2567
|
+
AutoDiff<3,T> lz[2] ={ 1-zz, zz};
|
|
2568
|
+
AutoDiff<3,T> sigma[8] = {1-xx + 1-yy + 1-zz,
|
|
2569
|
+
xx + 1-yy + 1-zz,
|
|
2570
|
+
xx + yy + 1-zz,
|
|
2571
|
+
1-xx + yy + 1-zz,
|
|
2572
|
+
1-xx + 1-yy + zz,
|
|
2573
|
+
xx + 1-yy + zz,
|
|
2574
|
+
xx + yy + zz,
|
|
2575
|
+
1-xx + yy + zz};
|
|
2576
|
+
int ii = 0;
|
|
2577
|
+
|
|
2578
|
+
// int maxorder_facet =
|
|
2579
|
+
// max2(order_facet[0][0],max2(order_facet[1][0],order_facet[2][0]));
|
|
2580
|
+
|
|
2581
|
+
const FACE * faces = ElementTopology::GetFaces(ET_HEX);
|
|
2582
|
+
|
|
2583
|
+
ArrayMem<AutoDiff<3,T>,20> leg_u(order+2), leg_v(order+3);
|
|
2584
|
+
ArrayMem<AutoDiff<3,T>,20> leg_w(order+2);
|
|
2585
|
+
AutoDiff<3,T> lam_face;
|
|
2586
|
+
|
|
2587
|
+
for(int fa = 0; fa < 6; fa++)
|
|
2588
|
+
{
|
|
2589
|
+
int fmax = 0;
|
|
2590
|
+
lam_face = -1 + 0.25*sigma[faces[fa][0]];
|
|
2591
|
+
for(int j = 1; j < 4; j++)
|
|
2592
|
+
{
|
|
2593
|
+
if(vnums[faces[fa][j]] > vnums[faces[fa][fmax]]) fmax = j;
|
|
2594
|
+
lam_face += sigma[faces[fa][j]]*0.25;
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
int fz,ftrig;
|
|
2598
|
+
|
|
2599
|
+
fz = 3 - fmax;
|
|
2600
|
+
ftrig = fmax^1;
|
|
2601
|
+
|
|
2602
|
+
fmax = faces[fa][fmax];
|
|
2603
|
+
fz = faces[fa][fz];
|
|
2604
|
+
ftrig = faces[fa][ftrig];
|
|
2605
|
+
|
|
2606
|
+
|
|
2607
|
+
// int orderz = order_facet[fa][1];
|
|
2608
|
+
|
|
2609
|
+
if(vnums[fz] < vnums[ftrig]) swap(fz, ftrig);
|
|
2610
|
+
int p = order_facet[fa][0];
|
|
2611
|
+
LegendrePolynomial::Eval(p, sigma[fmax] - sigma[ftrig],leg_u);
|
|
2612
|
+
LegendrePolynomial::Eval(p, sigma[fmax] - sigma[fz],leg_v);
|
|
2613
|
+
|
|
2614
|
+
for(int k = 0; k <= p; k++)
|
|
2615
|
+
for(int l = 0; l <= p; l++)
|
|
2616
|
+
{
|
|
2617
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(0.5*(sigma[fmax] - sigma[fz]),-0.5*(sigma[fmax] - sigma[fz]),
|
|
2618
|
+
0.5*(sigma[fmax] - sigma[ftrig]),-0.5*(sigma[fmax] - sigma[ftrig]),leg_u[l]* leg_v[k]*lam_face);
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
|
|
2622
|
+
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2625
|
+
|
|
2626
|
+
|
|
2627
|
+
int oi = order_inner[0];
|
|
2628
|
+
leg_u.SetSize(oi+2);
|
|
2629
|
+
leg_v.SetSize(oi+2);
|
|
2630
|
+
leg_w.SetSize(oi+2);
|
|
2631
|
+
|
|
2632
|
+
LegendrePolynomial::Eval(oi+1,sigma[0] - sigma[1],leg_u);
|
|
2633
|
+
LegendrePolynomial::Eval(oi+1,sigma[0] - sigma[3],leg_v);
|
|
2634
|
+
LegendrePolynomial::Eval(oi+1,sigma[0] - sigma[4],leg_w);
|
|
2635
|
+
|
|
2636
|
+
for(int k=0; k<=oi-1; k++)
|
|
2637
|
+
{
|
|
2638
|
+
for(int i = 0; i <= oi+1; i++)
|
|
2639
|
+
{
|
|
2640
|
+
for(int j = 0; j <= oi+1; j++)
|
|
2641
|
+
{
|
|
2642
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[0], lx[1], lz[0], lz[1], ly[0]*ly[1]*leg_u[i]*leg_v[k]* leg_w[j]);
|
|
2643
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[0], lx[1], ly[0], ly[1], lz[0]*lz[1]*leg_u[i]*leg_v[j]* leg_w[k]);
|
|
2644
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(ly[0], ly[1], lz[0], lz[1], lx[0]*lx[1]*leg_u[k]*leg_v[j]* leg_w[i]);
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2649
|
+
|
|
2650
|
+
// S_xz
|
|
2651
|
+
for (int i=0; i<=oi; i++)
|
|
2652
|
+
{
|
|
2653
|
+
for (int j=0; j<=oi; j++)
|
|
2654
|
+
{
|
|
2655
|
+
for (int k=0; k<=oi+1; k++)
|
|
2656
|
+
{
|
|
2657
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[0], lx[0], ly[0], lz[0], leg_u[k]*leg_v[j]*leg_w[i]);
|
|
2658
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(ly[0], ly[0], lx[0], lz[0], leg_u[i]*leg_v[k]*leg_w[j]);
|
|
2659
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lz[0], lz[0], lx[0], ly[0], leg_u[i]*leg_v[j]*leg_w[k]);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
|
|
2665
|
+
};
|
|
2666
|
+
|
|
2667
|
+
template <typename MIP, typename TFA>
|
|
2668
|
+
void CalcDualShape2 (const MIP & mip, TFA & shape) const
|
|
2669
|
+
{
|
|
2670
|
+
throw Exception ("Hdivdivfe not implementend for element type");
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
|
|
2674
|
+
};
|
|
2675
|
+
|
|
2676
|
+
|
|
2677
|
+
|
|
2678
|
+
|
|
2679
|
+
////////////////////// SURFACE ////////////////////////////
|
|
2680
|
+
template <int DIM>
|
|
2681
|
+
class HDivDivSurfaceFiniteElement : public FiniteElement
|
|
2682
|
+
{
|
|
2683
|
+
public:
|
|
2684
|
+
using FiniteElement::FiniteElement;
|
|
2685
|
+
using FiniteElement::ndof;
|
|
2686
|
+
using FiniteElement::order;
|
|
2687
|
+
|
|
2688
|
+
virtual void CalcMappedShape_Matrix (const MappedIntegrationPoint<DIM,DIM+1> & mip,
|
|
2689
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
2690
|
+
|
|
2691
|
+
virtual void CalcMappedShape_Vector (const MappedIntegrationPoint<DIM,DIM+1> & mip,
|
|
2692
|
+
BareSliceMatrix<double> shape) const = 0;
|
|
2693
|
+
|
|
2694
|
+
};
|
|
2695
|
+
|
|
2696
|
+
|
|
2697
|
+
template <ELEMENT_TYPE ET> class HDivDivSurfaceFE;
|
|
2698
|
+
|
|
2699
|
+
|
|
2700
|
+
template <ELEMENT_TYPE ET>
|
|
2701
|
+
class T_HDivDivSurfaceFE : public HDivDivSurfaceFiniteElement<ET_trait<ET>::DIM>,
|
|
2702
|
+
public VertexOrientedFE<ET>
|
|
2703
|
+
{
|
|
2704
|
+
protected:
|
|
2705
|
+
enum { DIM = ET_trait<ET>::DIM };
|
|
2706
|
+
enum { DIM_STRESS = ((DIM+2)*(DIM+1))/2 };
|
|
2707
|
+
|
|
2708
|
+
using VertexOrientedFE<ET>::vnums;
|
|
2709
|
+
using HDivDivSurfaceFiniteElement<ET_trait<ET>::DIM>::ndof;
|
|
2710
|
+
using HDivDivSurfaceFiniteElement<ET_trait<ET>::DIM>::order;
|
|
2711
|
+
|
|
2712
|
+
IVec<DIM> order_inner;
|
|
2713
|
+
|
|
2714
|
+
|
|
2715
|
+
public:
|
|
2716
|
+
using VertexOrientedFE<ET>::SetVertexNumbers;
|
|
2717
|
+
|
|
2718
|
+
T_HDivDivSurfaceFE (int aorder)
|
|
2719
|
+
{
|
|
2720
|
+
order = aorder;
|
|
2721
|
+
order_inner = aorder;
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
virtual ELEMENT_TYPE ElementType() const { return ET; }
|
|
2725
|
+
const HDivDivSurfaceFE<ET> * Cast() const { return static_cast<const HDivDivSurfaceFE<ET>*> (this); }
|
|
2726
|
+
|
|
2727
|
+
INLINE void SetOrderInner (IVec<DIM,int> order) { order_inner = order; }
|
|
2728
|
+
|
|
2729
|
+
virtual void ComputeNDof()
|
|
2730
|
+
{
|
|
2731
|
+
cout << "Error, T_HDivDivSurfaceFE<ET>:: ComputeNDof not available for base class" << endl;
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
virtual void CalcMappedShape_Vector (const MappedIntegrationPoint<DIM,DIM+1> & mip,
|
|
2735
|
+
BareSliceMatrix<double> shape) const
|
|
2736
|
+
{
|
|
2737
|
+
Vec<DIM, AutoDiff<DIM+1>> adp = mip;
|
|
2738
|
+
TIP<DIM, AutoDiffDiff<DIM+1>> addp(adp, mip.IP().FacetNr(), mip.IP().VB());
|
|
2739
|
+
|
|
2740
|
+
Cast() -> T_CalcShape (addp, SBLambda([&] (int nr, auto val)
|
|
2741
|
+
{
|
|
2742
|
+
shape.Row(nr).Range(0,DIM_STRESS) = val.Shape();
|
|
2743
|
+
}));
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
|
|
2747
|
+
virtual void CalcMappedShape_Matrix (const MappedIntegrationPoint<DIM,DIM+1> & mip,
|
|
2748
|
+
BareSliceMatrix<double> shape) const
|
|
2749
|
+
{
|
|
2750
|
+
Vec<DIM, AutoDiff<DIM+1>> adp = mip;
|
|
2751
|
+
TIP<DIM, AutoDiffDiff<DIM+1>> addp(adp, mip.IP().FacetNr(), mip.IP().VB());
|
|
2752
|
+
|
|
2753
|
+
Cast() -> T_CalcShape (addp, SBLambda([&](int nr,auto val)
|
|
2754
|
+
{
|
|
2755
|
+
Vec<DIM_STRESS> vecshape = val.Shape();
|
|
2756
|
+
BareVector<double> matshape = shape.Row(nr);
|
|
2757
|
+
VecToSymMat<DIM+1> (vecshape, matshape);
|
|
2758
|
+
}));
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
|
|
2762
|
+
};
|
|
2763
|
+
|
|
2764
|
+
template <> class HDivDivSurfaceFE<ET_SEGM> : public T_HDivDivSurfaceFE<ET_SEGM>
|
|
2765
|
+
{
|
|
2766
|
+
|
|
2767
|
+
public:
|
|
2768
|
+
using T_HDivDivSurfaceFE<ET_SEGM> :: T_HDivDivSurfaceFE;
|
|
2769
|
+
|
|
2770
|
+
virtual void ComputeNDof()
|
|
2771
|
+
{
|
|
2772
|
+
order = 0;
|
|
2773
|
+
ndof = 0;
|
|
2774
|
+
ndof += order_inner[0]+1;
|
|
2775
|
+
order = max2(order,order_inner[0]);
|
|
2776
|
+
|
|
2777
|
+
}
|
|
2778
|
+
template <typename Tx, typename TFA>
|
|
2779
|
+
void T_CalcShape (TIP<1,Tx> ip/*AutoDiffDiff<2> hx[2]*/, TFA & shape) const
|
|
2780
|
+
{
|
|
2781
|
+
auto x = ip.x;
|
|
2782
|
+
AutoDiffDiff<2> ddlami[2] ={ x, 1-x };
|
|
2783
|
+
|
|
2784
|
+
int ii = 0;
|
|
2785
|
+
|
|
2786
|
+
ArrayMem<AutoDiffDiff<2>,20> u(order_inner[0]+2);
|
|
2787
|
+
|
|
2788
|
+
int es = 0,ee = 1;
|
|
2789
|
+
if(vnums[es] > vnums[ee]) swap (es,ee);
|
|
2790
|
+
|
|
2791
|
+
AutoDiffDiff<2> ls = ddlami[es],le = ddlami[ee];
|
|
2792
|
+
|
|
2793
|
+
IntegratedLegendreMonomialExt::Calc(order_inner[0]+2, le-ls,u);
|
|
2794
|
+
|
|
2795
|
+
for(int l = 0; l <= order_inner[0]; l++)
|
|
2796
|
+
shape[ii++] = SigmaGrad (u[l]);
|
|
2797
|
+
|
|
2798
|
+
|
|
2799
|
+
};
|
|
2800
|
+
};
|
|
2801
|
+
|
|
2802
|
+
|
|
2803
|
+
template <> class HDivDivSurfaceFE<ET_TRIG> : public T_HDivDivSurfaceFE<ET_TRIG>
|
|
2804
|
+
{
|
|
2805
|
+
|
|
2806
|
+
public:
|
|
2807
|
+
using T_HDivDivSurfaceFE<ET_TRIG> :: T_HDivDivSurfaceFE;
|
|
2808
|
+
|
|
2809
|
+
virtual void ComputeNDof()
|
|
2810
|
+
{
|
|
2811
|
+
order = 0;
|
|
2812
|
+
ndof = 0;
|
|
2813
|
+
ndof += (order_inner[0]+1+HDivDivFE<ET_PRISM>::incrorder_zz1_bd)*(order_inner[0]+2+HDivDivFE<ET_PRISM>::incrorder_zz1_bd)/2;
|
|
2814
|
+
order = max2(order, order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_zz1_bd);
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
|
|
2818
|
+
template <typename Tx, typename TFA>
|
|
2819
|
+
void T_CalcShape (TIP<2,Tx> ip, TFA & shape) const
|
|
2820
|
+
{
|
|
2821
|
+
Tx x = ip.x, y = ip.y;
|
|
2822
|
+
typedef decltype(x.Value()+x.Value()) T;
|
|
2823
|
+
AutoDiff<3,T> xx(x.Value(), &x.DValue(0));
|
|
2824
|
+
AutoDiff<3,T> yy(y.Value(), &y.DValue(0));
|
|
2825
|
+
AutoDiff<3,T> lx[6] ={ xx, yy, 1-xx-yy};
|
|
2826
|
+
int ii = 0;
|
|
2827
|
+
|
|
2828
|
+
ArrayMem<AutoDiff<3,T>,20> leg_u(order_inner[0]+2), leg_v(order_inner[0]+3);
|
|
2829
|
+
|
|
2830
|
+
|
|
2831
|
+
int fav[3] ={0,1,2};
|
|
2832
|
+
|
|
2833
|
+
//Sort vertices first edge op minimal vertex
|
|
2834
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0],fav[1]);
|
|
2835
|
+
if(vnums[fav[1]] > vnums[fav[2]]) swap(fav[1],fav[2]);
|
|
2836
|
+
if(vnums[fav[0]] > vnums[fav[1]]) swap(fav[0],fav[1]);
|
|
2837
|
+
|
|
2838
|
+
leg_u.SetSize(order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_zz1_bd+1);
|
|
2839
|
+
leg_v.SetSize(order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_zz1_bd+1);
|
|
2840
|
+
ScaledLegendrePolynomial(order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_zz1_bd,lx[fav[0]]-lx[fav[1]],lx[fav[0]]+lx[fav[1]],leg_u);
|
|
2841
|
+
LegendrePolynomial::Eval(order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_zz1_bd,2 * lx[fav[2]] - 1,leg_v);
|
|
2842
|
+
|
|
2843
|
+
for(int j = 0; j <= order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_zz1_bd; j++)
|
|
2844
|
+
for(int k = 0; k <= order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_zz1_bd-j; k++)
|
|
2845
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(lx[fav[0]], lx[fav[1]], lx[fav[2]], lx[fav[2]], leg_u[j]*leg_v[k]);
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
|
|
2849
|
+
|
|
2850
|
+
template <> class HDivDivSurfaceFE<ET_QUAD> : public T_HDivDivSurfaceFE<ET_QUAD>
|
|
2851
|
+
{
|
|
2852
|
+
|
|
2853
|
+
public:
|
|
2854
|
+
using T_HDivDivSurfaceFE<ET_QUAD> :: T_HDivDivSurfaceFE;
|
|
2855
|
+
|
|
2856
|
+
virtual void ComputeNDof()
|
|
2857
|
+
{
|
|
2858
|
+
order = 0;
|
|
2859
|
+
ndof = 0;
|
|
2860
|
+
ndof += (order_inner[0]+1+HDivDivFE<ET_PRISM>::incrorder_xx1_bd)*(order_inner[1]+1+HDivDivFE<ET_PRISM>::incrorder_xx2_bd);
|
|
2861
|
+
order = max2(order, order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_xx1_bd);
|
|
2862
|
+
order = max2(order, order_inner[1]+HDivDivFE<ET_PRISM>::incrorder_xx2_bd);
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
|
|
2866
|
+
template <typename Tx, typename TFA>
|
|
2867
|
+
void T_CalcShape (TIP<2,Tx> ip, TFA & shape) const
|
|
2868
|
+
{
|
|
2869
|
+
AutoDiffDiff<3> x = ip.x, z = ip.y;
|
|
2870
|
+
typedef decltype(x.Value()+x.Value()) T;
|
|
2871
|
+
AutoDiff<3> xx(x.Value(), &x.DValue(0));
|
|
2872
|
+
AutoDiff<3> zz(z.Value(), &z.DValue(0));
|
|
2873
|
+
AutoDiff<3> sigma[4] = {1-xx+1-zz, xx+1-zz, xx+zz, 1-xx+zz};
|
|
2874
|
+
int ii = 0;
|
|
2875
|
+
|
|
2876
|
+
|
|
2877
|
+
ArrayMem<AutoDiff<3>,20> leg_u(order_inner[0]+2);
|
|
2878
|
+
ArrayMem<AutoDiff<3>,20> leg_w(order_inner[1]+2);
|
|
2879
|
+
|
|
2880
|
+
|
|
2881
|
+
int fmax = 0;
|
|
2882
|
+
for(int j = 1; j < 4; j++)
|
|
2883
|
+
if(vnums[j] > vnums[fmax]) fmax = j;
|
|
2884
|
+
|
|
2885
|
+
int f1, f2;
|
|
2886
|
+
f1 = (fmax+1)%4;
|
|
2887
|
+
f2 = (fmax+3)%4;
|
|
2888
|
+
|
|
2889
|
+
|
|
2890
|
+
if(vnums[f1] > vnums[f2])
|
|
2891
|
+
{
|
|
2892
|
+
swap(f1,f2);
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
LegendrePolynomial::Eval(order_inner[0],sigma[fmax] - sigma[f1],leg_u);
|
|
2896
|
+
LegendrePolynomial::Eval(order_inner[0],sigma[fmax] - sigma[f2],leg_w);
|
|
2897
|
+
|
|
2898
|
+
for(int k = 0; k <= order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_xx2_bd; k++)
|
|
2899
|
+
for(int l = 0; l <= order_inner[0]+HDivDivFE<ET_PRISM>::incrorder_xx1_bd; l++)
|
|
2900
|
+
{
|
|
2901
|
+
shape[ii++] = Prism_Dl1xDl3_symtensor_Dl2xDl4_u<T>(0.5*(sigma[fmax]-sigma[f2]),-0.5*(sigma[fmax]-sigma[f2]),
|
|
2902
|
+
0.5*(sigma[fmax]-sigma[f1]),-0.5*(sigma[fmax]-sigma[f1]),leg_u[l]* leg_w[k]);
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2905
|
+
|
|
2906
|
+
}
|
|
2907
|
+
};
|
|
2908
|
+
|
|
2909
|
+
|
|
2910
|
+
HDIVDIVFE_EXTERN template class T_HDivDivFE<ET_TRIG>;
|
|
2911
|
+
HDIVDIVFE_EXTERN template class T_HDivDivFE<ET_QUAD>;
|
|
2912
|
+
HDIVDIVFE_EXTERN template class T_HDivDivFE<ET_TET>;
|
|
2913
|
+
HDIVDIVFE_EXTERN template class T_HDivDivFE<ET_PRISM>;
|
|
2914
|
+
HDIVDIVFE_EXTERN template class T_HDivDivFE<ET_HEX>;
|
|
2915
|
+
HDIVDIVFE_EXTERN template class T_HDivDivSurfaceFE<ET_SEGM>;
|
|
2916
|
+
HDIVDIVFE_EXTERN template class T_HDivDivSurfaceFE<ET_QUAD>;
|
|
2917
|
+
HDIVDIVFE_EXTERN template class T_HDivDivSurfaceFE<ET_TRIG>;
|
|
2918
|
+
|
|
2919
|
+
}
|
|
2920
|
+
|
|
2921
|
+
|
|
2922
|
+
#endif
|
|
2923
|
+
|