Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/curvedelems.cpp
3206 views
#include <mystdlib.h>12#include "meshing.hpp"3#ifndef CURVEDELEMS_NEW45namespace netgen6{789// computes Gaussean integration formula on (0,1) with n points10// in: Numerical algs in C (or, was it the Fortran book ?)11void ComputeGaussRule (int n, ARRAY<double> & xi, ARRAY<double> & wi)12{13xi.SetSize (n);14wi.SetSize (n);1516int m = (n+1)/2;17double p1, p2, p3;18double pp, z, z1;19for (int i = 1; i <= m; i++)20{21z = cos ( M_PI * (i - 0.25) / (n + 0.5));22while(1)23{24p1 = 1; p2 = 0;25for (int j = 1; j <= n; j++)26{27p3 = p2; p2 = p1;28p1 = ((2 * j - 1) * z * p2 - (j - 1) * p3) / j;29}30// p1 is legendre polynomial3132pp = n * (z*p1-p2) / (z*z - 1);33z1 = z;34z = z1-p1/pp;3536if (fabs (z - z1) < 1e-14) break;37}3839xi[i-1] = 0.5 * (1 - z);40xi[n-i] = 0.5 * (1 + z);41wi[i-1] = wi[n-i] = 1.0 / ( (1 - z * z) * pp * pp);42}43}44454647// ----------------------------------------------------------------------------48// PolynomialBasis49// ----------------------------------------------------------------------------505152void PolynomialBasis :: CalcLegendrePolynomials (double x)53{54double p1 = 1.0, p2 = 0.0, p3;5556lp[0] = 1.0;5758for (int j=1; j<=order; j++)59{60p3=p2; p2=p1;61p1=((2.0*j-1.0)*(2*x-1)*p2-(j-1.0)*p3)/j;62lp[j] = p1;63}64}656667void PolynomialBasis :: CalcScaledLegendrePolynomials (double x, double t)68{69double p1 = 1.0, p2 = 0.0, p3;7071lp[0] = 1.0;7273double x2mt = 2*x-t;74double t2 = t*t;7576for (int j=1; j<=order; j++)77{78p3=p2; p2=p1;79p1=((2.0*j-1.0)*x2mt*p2-t2*(j-1.0)*p3)/j;80lp[j] = p1;81}82}838485void PolynomialBasis :: CalcDLegendrePolynomials (double x)86{87double p1 = 0., p2 = 0., p3;8889dlp[0] = 0.;9091for (int j = 1; j <= order-1; j++)92{93p3=p2; p2=p1;94p1=((2.*j-1.)*(2*lp[j-1]+(2*x-1)*p2)-(j-1.)*p3)/j;95dlp[j] = p1;96}97}9899100void PolynomialBasis :: CalcF (double x)101{102CalcLegendrePolynomials (x);103104for (int j = 0; j<=order-2; j++)105f[j] = (lp[j+2]-lp[j])/(2.0*(j+1)+1)/2.0;106}107108109void PolynomialBasis :: CalcDf (double x)110{111CalcLegendrePolynomials (x);112113for (int j = 0; j <= order-2; j++)114df[j] = lp[j+1];115}116117118void PolynomialBasis :: CalcFDf (double x)119{120CalcLegendrePolynomials (x);121122for (int j = 0; j<=order-2; j++)123{124f[j] = (lp[j+2]-lp[j])/(2.0*(j+1)+1)/2.0;125df[j] = lp[j+1];126}127}128129130void PolynomialBasis :: CalcDDf (double x)131{132CalcLegendrePolynomials (x);133CalcDLegendrePolynomials (x);134135for (int j = 0; j <= order-2; j++) ddf[j] = dlp[j+1];136}137138139void PolynomialBasis :: CalcFScaled (double x, double t)140{141double tt = t*t;142double x2mt = 2*x-t;143144145146147double p1 = 0.5*x2mt, p2 = -0.5, p3 = 0.0;148for (int j=2; j<=order; j++)149{150p3=p2; p2=p1;151p1=((2.0*j-3.0) * x2mt * p2 - tt*(j-3.0)*p3)/j;152f[j-2] = p1;153}154155/*156CalcF (x/t);157double fac = t*t;158for (int j = 0; j<=order-2; j++, fac*=t)159f[j] *= fac;160*/161}162163void PolynomialBasis :: CalcFScaled (int p, double x, double t, double * values)164{165double tt = t*t;166double x2mt = 2*x-t;167168double p1 = 0.5*x2mt, p2 = -0.5, p3 = 0.0;169for (int j=2; j<=p; j++)170{171p3=p2; p2=p1;172p1=((2.0*j-3.0) * x2mt * p2 - tt*(j-3.0)*p3)/j;173values[j-2] = p1;174}175176/*177CalcF (x/t);178double fac = t*t;179for (int j = 0; j<=order-2; j++, fac*=t)180f[j] *= fac;181*/182}183184185186187// ----------------------------------------------------------------------------188// BaseFiniteElement1D189// ----------------------------------------------------------------------------190191192void BaseFiniteElement1D :: CalcVertexShapes ()193{194vshape[0] = xi(0);195vshape[1] = 1-xi(0);196197vdshape[0] = 1;198vdshape[1] = -1;199200/*201if (edgeorient == -1)202{203Swap (vshape[0], vshape[1]);204Swap (vdshape[0], vdshape[1]);205}206*/207208}209210211void BaseFiniteElement1D :: CalcEdgeShapes ()212{213b.SetOrder (edgeorder);214if (edgeorient == 1)215b.CalcFDf( 1-xi(0) );216else217b.CalcFDf( xi(0) );218219for (int k = 2; k <= edgeorder; k++)220{221eshape[k-2] = b.GetF(k);222edshape[k-2] = -b.GetDf(k);223}224}225226227void BaseFiniteElement1D :: CalcEdgeLaplaceShapes ()228{229b.SetOrder (edgeorder);230if (edgeorient == 1)231b.CalcDDf( 1-xi(0) );232else233b.CalcDDf( xi(0) );234235for (int k = 2; k <= edgeorder; k++)236eddshape[k-2] = b.GetDDf(k);237}238239240241242// ----------------------------------------------------------------------------243// BaseFiniteElement2D244// ----------------------------------------------------------------------------245246247void BaseFiniteElement2D :: SetElementNumber (int aelnr)248{249int locmaxedgeorder = -1;250251BaseFiniteElement<2> :: SetElementNumber (aelnr);252const Element2d & elem = mesh[(SurfaceElementIndex) (elnr-1)];253top.GetSurfaceElementEdges (elnr, &(edgenr[0]), &(edgeorient[0]));254facenr = top.GetSurfaceElementFace (elnr);255faceorient = top.GetSurfaceElementFaceOrientation (elnr);256257for (int v = 0; v < nvertices; v++)258vertexnr[v] = elem[v];259260for (int e = 0; e < nedges; e++)261{262edgeorder[e] = curv.GetEdgeOrder (edgenr[e]-1); // 1-based263locmaxedgeorder = max2 (edgeorder[e], locmaxedgeorder);264}265266faceorder = curv.GetFaceOrder (facenr-1); // 1-based267CalcNFaceShapes ();268269if (locmaxedgeorder > maxedgeorder)270{271maxedgeorder = locmaxedgeorder;272eshape.SetSize(nedges * (maxedgeorder-1));273edshape.SetSize(nedges * (maxedgeorder-1));274}275276if (faceorder > maxfaceorder)277{278maxfaceorder = faceorder;279fshape.SetSize( nfaceshapes ); // number of face shape functions280fdshape.SetSize( nfaceshapes );281fddshape.SetSize ( nfaceshapes );282}283};284285286// ----------------------------------------------------------------------------287// BaseFiniteElement3D288// ----------------------------------------------------------------------------289290291void BaseFiniteElement3D :: SetElementNumber (int aelnr)292{293int locmaxedgeorder = -1;294int locmaxfaceorder = -1;295int v, f, e;296297BaseFiniteElement<3> :: SetElementNumber (aelnr);298Element elem = mesh[(ElementIndex) (elnr-1)];299top.GetElementEdges (elnr, &(edgenr[0]), &(edgeorient[0]));300top.GetElementFaces (elnr, &(facenr[0]), &(faceorient[0]));301302for (v = 0; v < nvertices; v++)303vertexnr[v] = elem[v];304305for (f = 0; f < nfaces; f++)306{307surfacenr[f] = top.GetFace2SurfaceElement (facenr[f]);308// surfaceorient[f] = top.GetSurfaceElementFaceOrientation (surfacenr[f]);309}310311for (e = 0; e < nedges; e++)312{313edgeorder[e] = curv.GetEdgeOrder (edgenr[e]-1); // 1-based314locmaxedgeorder = max (edgeorder[e], locmaxedgeorder);315}316317for (f = 0; f < nfaces; f++)318{319faceorder[f] = curv.GetFaceOrder (facenr[f]-1); // 1-based320locmaxfaceorder = max (faceorder[f], locmaxfaceorder);321}322323CalcNFaceShapes ();324325if (locmaxedgeorder > maxedgeorder)326{327maxedgeorder = locmaxedgeorder;328eshape.SetSize(nedges * (maxedgeorder-1));329edshape.SetSize(nedges * (maxedgeorder-1));330}331332if (locmaxfaceorder > maxfaceorder)333{334maxfaceorder = locmaxfaceorder;335fshape.SetSize( nfaces * (maxfaceorder-1) * (maxfaceorder-1)); // number of face shape functions336fdshape.SetSize( nfaces * (maxfaceorder-1) * (maxfaceorder-1));337}338};339340341342343// ----------------------------------------------------------------------------344// FETrig345// ----------------------------------------------------------------------------346347348void FETrig :: SetReferencePoint (Point<2> axi)349{350BaseFiniteElement2D :: SetReferencePoint (axi);351lambda(0) = xi(0);352lambda(1) = xi(1);353lambda(2) = 1-xi(0)-xi(1);354355dlambda(0,0) = 1; dlambda(0,1) = 0;356dlambda(1,0) = 0; dlambda(1,1) = 1;357dlambda(2,0) = -1; dlambda(2,1) = -1;358}359360361void FETrig :: SetVertexSingularity (int v, int exponent)362{363int i;364if (1-lambda(v) < EPSILON) return;365366Point<3> lamold = lambda;367368Vec<2> dfac;369370double fac = pow(1-lambda(v),exponent-1);371372for (i = 0; i < 2; i++)373{374dfac(i) = -(exponent-1)*pow(1-lambda(v),exponent-2)*dlambda(v,i);375dlambda(v,i) *= exponent * pow(1-lambda(v),exponent-1);376}377378lambda(v) = 1-pow(1-lambda(v),exponent);379380for (i = 0; i < nvertices; i++)381{382if (i == v) continue;383for (int j = 0; j < 2; j++)384dlambda(i,j) = dlambda(i,j) * fac + lamold(i) * dfac(j);385386lambda(i) *= fac;387}388}389390391392void FETrig :: CalcVertexShapes ()393{394for (int v = 0; v < nvertices; v++)395{396vshape[v] = lambda(v);397vdshape[v](0) = dlambda(v,0);398vdshape[v](1) = dlambda(v,1);399}400}401402403void FETrig :: CalcEdgeShapes ()404{405int index = 0;406for (int e = 0; e < nedges; e++)407{408if (edgeorder[e] <= 1) continue;409410int i0 = eledge[e][0]-1;411int i1 = eledge[e][1]-1;412413double arg = lambda(i0) + lambda(i1); // = 1-lambda[i2];414415if (fabs(arg) < EPSILON) // division by 0416{417for (int k = 2; k <= edgeorder[e]; k++)418{419eshape[index] = 0;420edshape[index] = Vec<2>(0,0);421index++;422}423continue;424}425426if (edgeorient[e] == -1) Swap (i0, i1); // reverse orientation427428double xi = lambda(i1)/arg;429430b1.SetOrder (edgeorder[e]);431b1.CalcFDf (xi);432433double decay = arg;434double ddecay;435436double l0 = lambda(i0);437double l0x = dlambda(i0,0);438double l0y = dlambda(i0,1);439440double l1 = lambda(i1);441double l1x = dlambda(i1,0);442double l1y = dlambda(i1,1);443444for (int k = 2; k <= edgeorder[e]; k++)445{446ddecay = k*decay;447decay *= arg;448449eshape[index] = b1.GetF (k) * decay;450edshape[index] = Vec<2>451(b1.GetDf(k) * (l1x*arg - l1*(l0x+l1x)) *452decay / (arg * arg) + b1.GetF(k) * ddecay * (l0x+l1x),453b1.GetDf(k) * (l1y*arg - l1*(l0y+l1y)) *454decay / (arg * arg) + b1.GetF(k) * ddecay * (l0y+l1y));455index++;456}457}458// (*testout) << "index = " << index << endl;459// (*testout) << "eshape = " << eshape << ", edshape = " << edshape << endl;460461462// eshape = 0.0;463// edshape = 0.0;464465/*466int index = 0;467for (int e = 0; e < nedges; e++)468{469if (edgeorder[e] <= 1) continue;470471int i0 = eledge[e][0]-1;472int i1 = eledge[e][1]-1;473474if (edgeorient[e] == -1) Swap (i0, i1); // reverse orientation475476double x = lambda(i1)-lambda(i0);477double y = 1-lambda(i0)-lambda(i1);478double fy = (1-y)*(1-y);479480// double p3 = 0, p3x = 0, p3y = 0;481// double p2 = -1, p2x = 0, p2y = 0;482// double p1 = x, p1x = 1, p1y = 0;483484double p3 = 0, p3x = 0, p3y = 0;485double p2 = -0.5, p2x = 0, p2y = 0;486double p1 = 0.5*x, p1x = 0.5, p1y = 0;487488for (int j=2; j<= edgeorder[e]; j++)489{490p3=p2; p3x = p2x; p3y = p2y;491p2=p1; p2x = p1x; p2y = p1y;492double c1 = (2.0*j-3) / j;493double c2 = (j-3.0) / j;494495p1 = c1 * x * p2 - c2 * fy * p3;496p1x = c1 * p2 + c1 * x * p2x - c2 * fy * p3x;497p1y = c1 * x * p2y - (c2 * 2 * (y-1) * p3 + c2 * fy * p3y);498499eshape[index] = p1;500for (int k = 0; k < 2; k++)501edshape[index](k) =502p1x * ( dlambda(i1,k) - dlambda(i0,k) ) +503p1y * (-dlambda(i1,k) - dlambda(i0,k) );504index++;505}506507}508// (*testout) << "eshape = " << eshape << ", edshape = " << edshape << endl;509*/510}511512513void FETrig :: CalcFaceShapes ()514{515int index = 0;516517int i0 = elface[0][0]-1;518int i1 = elface[0][1]-1;519int i2 = elface[0][2]-1;520521// sort lambda_i's by the corresponing vertex numbers522523if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1);524if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2);525if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2);526527double arg = lambda(i1) + lambda(i2);528529if (fabs(arg) < EPSILON) // division by 0530{531for (int k = 0; k < nfaceshapes; k++)532{533fshape[index] = 0;534fdshape[index] = Vec<2>(0,0);535index++;536}537return;538}539540b1.SetOrder (faceorder);541b2.SetOrder (faceorder);542543b1.CalcFDf (lambda(i0));544b2.CalcFDf (lambda(i2)/arg);545546double decay = 1;547double ddecay;548549double l0 = lambda(i0);550double l1 = lambda(i1);551double l2 = lambda(i2);552double dl0x = dlambda(i0,0);553double dl0y = dlambda(i0,1);554double dl1x = dlambda(i1,0);555double dl1y = dlambda(i1,1);556double dl2x = dlambda(i2,0);557double dl2y = dlambda(i2,1);558559double dargx = dl1x + dl2x;560double dargy = dl1y + dl2y;561562for (int n1 = 2; n1 < faceorder; n1++)563{564ddecay = (n1-1)*decay;565decay *= arg;566567for (int n0 = 2; n0 < faceorder-n1+2; n0++)568{569fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay;570fdshape[index] = Vec<2>571(b1.GetDf(n0) * dl0x * b2.GetF(n1) * decay +572b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay +573b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx,574b1.GetDf(n0) * dl0y * b2.GetF(n1) * decay +575b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay +576b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy);577index++;578}579}580}581582583584void FETrig :: CalcFaceLaplaceShapes ()585{586int index = 0;587588int i0 = elface[0][0]-1;589int i1 = elface[0][1]-1;590int i2 = elface[0][2]-1;591592if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1);593if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2);594if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2);595596double arg = lambda(i1) + lambda(i2);597598if (fabs(arg) < EPSILON) // division by 0599{600for (int k = 0; k < nfaceshapes; k++)601fddshape[k] = 0;602return;603}604605b1.SetOrder (faceorder);606b2.SetOrder (faceorder);607608b1.CalcFDf (lambda(i0));609b1.CalcDDf (lambda(i0));610b2.CalcFDf (lambda(i2)/arg);611b2.CalcDDf (lambda(i2)/arg);612613double decay = 1;614double ddecay = 0;615double dddecay;616617double l0 = lambda(i0);618double l1 = lambda(i1);619double l2 = lambda(i2);620double dl0x = dlambda(i0,0);621double dl0y = dlambda(i0,1);622double dl1x = dlambda(i1,0);623double dl1y = dlambda(i1,1);624double dl2x = dlambda(i2,0);625double dl2y = dlambda(i2,1);626627double dargx = dl1x + dl2x;628double dargy = dl1y + dl2y;629630for (int n1 = 2; n1 < faceorder; n1++)631{632dddecay = (n1-1)*ddecay;633ddecay = (n1-1)*decay;634decay *= arg;635636for (int n0 = 2; n0 < faceorder-n1+2; n0++)637{638fddshape[index] =639640// b1.GetDf(n0) * dl0x * b2.GetF(n1) * decay .... derived641642b1.GetDDf(n0) * dl0x * dl0x * b2.GetF(n1) * decay +643b1.GetDf(n0) * dl0x * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay +644b1.GetDf(n0) * dl0x * b2.GetF(n1) * ddecay * dargx +645646647// b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay ... derived648649b1.GetDf(n0) * dl0x * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay +650b1.GetF(n0) * b2.GetDDf(n1) * pow((dl2x * arg - l2 * dargx)/(arg*arg),2) * decay +651b1.GetF(n0) * b2.GetDf(n1) * (-2*dargx/arg) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay +652b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * ddecay * dargx +653654655// b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx ... derived656657b1.GetDf(n0) * dl0x * b2.GetF(n1) * ddecay * dargx +658b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * ddecay * dargx +659b1.GetF(n0) * b2.GetF(n1) * dddecay * dargx * dargx +660661662// b1.GetDf(n0) * dl0y * b2.GetF(n1) * decay ... derived663664b1.GetDDf(n0) * dl0y * dl0y * b2.GetF(n1) * decay +665b1.GetDf(n0) * dl0y * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay +666b1.GetDf(n0) * dl0y * b2.GetF(n1) * ddecay * dargy +667668669// b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay ... derived670671b1.GetDf(n0) * dl0y * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay +672b1.GetF(n0) * b2.GetDDf(n1) * pow((dl2y * arg - l2 * dargy)/(arg*arg),2) * decay +673b1.GetF(n0) * b2.GetDf(n1) * (-2*dargy/arg) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay +674b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * ddecay * dargy +675676677// b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy ... derived678679b1.GetDf(n0) * dl0y * b2.GetF(n1) * ddecay * dargy +680b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * ddecay * dargy +681b1.GetF(n0) * b2.GetF(n1) * dddecay * dargy * dargy;682683index++;684}685}686}687688689690// ----------------------------------------------------------------------------691// FEQuad692// ----------------------------------------------------------------------------693694695void FEQuad :: CalcVertexShapes ()696{697vshape[0] = (1-xi(0)) * (1-xi(1));698vshape[1] = ( xi(0)) * (1-xi(1));699vshape[2] = ( xi(0)) * ( xi(1));700vshape[3] = (1-xi(0)) * ( xi(1));701702vdshape[0] = Vec<2> ( -(1-xi(1)), -(1-xi(0)) );703vdshape[1] = Vec<2> ( (1-xi(1)), -( xi(0)) );704vdshape[2] = Vec<2> ( ( xi(1)), ( xi(0)) );705vdshape[3] = Vec<2> ( -( xi(1)), (1-xi(0)) );706}707708709void FEQuad :: CalcEdgeShapes ()710{711int index = 0;712713double arg0[4] = { xi(0), 1-xi(0), 1-xi(1), xi(1) };714double arg1[4] = { 1-xi(1), xi(1), 1-xi(0), xi(0) };715double darg0[4] = { 1, -1, -1, 1 };716double darg1[4] = { -1, 1, -1, 1 };717718for (int e = 0; e < nedges; e++)719{720b1.SetOrder (edgeorder[e]);721b1.CalcFDf (edgeorient[e] == 1 ? arg0[e] : 1-arg0[e]);722723double decay = arg1[e];724double ddecay;725726for (int k = 2; k <= edgeorder[e]; k++, index++)727{728ddecay = k*decay;729decay *= arg1[e];730// linear decay731eshape[index] = b1.GetF(k) * arg1[e];732733if (e < 2)734edshape[index] = Vec<2>735(darg0[e] * edgeorient[e] * b1.GetDf(k) * arg1[e],736b1.GetF(k) * darg1[e]);737else738edshape[index] = Vec<2>739(b1.GetF(k) * darg1[e],740darg0[e] * edgeorient[e] * b1.GetDf(k) * arg1[e]);741742// exponential decay743/* eshape[index] = b1.GetF(k) * decay;744745if (e < 2)746edshape[index] = Vec<2>747(darg0[e] * edgeorient[e] * b1.GetDf(k) * decay,748b1.GetF(k) * ddecay * darg1[e]);749else750edshape[index] = Vec<2>751(b1.GetF(k) * ddecay * darg1[e],752darg0[e] * edgeorient[e] * b1.GetDf(k) * decay);753*/754}755}756}757758759void FEQuad :: CalcFaceShapes ()760{761int index = 0;762763// find index of point with smallest number764765int i0 = 0;766for (int i = 1; i < 4; i++)767if (vertexnr[elface[0][i]-1] < vertexnr[elface[0][i0]-1]) i0 = i;768769double x;770double y;771double dxx;772double dxy;773double dyx;774double dyy;775776switch (i0)777{778case 0:779x = xi(0); y = xi(1);780dxx = 1; dxy = 0;781dyx = 0; dyy = 1;782break;783case 1:784x = xi(1); y = 1-xi(0);785dxx = 0; dxy = 1;786dyx = -1; dyy = 0;787break;788case 2:789x = 1-xi(0); y = 1-xi(1);790dxx = -1; dxy = 0;791dyx = 0; dyy = -1;792break;793case 3:794x = 1-xi(1); y = xi(0);795dxx = 0; dxy =-1;796dyx = 1; dyy = 0;797break;798}799800if (vertexnr[elface[0][(i0+1) % 4]-1] > vertexnr[elface[0][(i0+3) % 4]-1])801{802Swap (x,y);803Swap (dxx, dyx);804Swap (dxy, dyy);805}806807b1.SetOrder (faceorder);808b2.SetOrder (faceorder);809810b1.CalcFDf (x);811b2.CalcFDf (y);812813for (int n0 = 2; n0 <= faceorder; n0++)814for (int n1 = 2; n1 <= faceorder; n1++)815{816fshape[index] = b1.GetF(n0) * b2.GetF(n1);817fdshape[index] = Vec<2> (b1.GetDf(n0) * dxx * b2.GetF(n1) + b1.GetF(n0) * b2.GetDf(n1) * dyx,818b1.GetDf(n0) * dxy * b2.GetF(n1) + b1.GetF(n0) * b2.GetDf(n1) * dyy);819index++;820}821}822823824void FEQuad :: CalcFaceLaplaceShapes ()825{826int index = 0;827828// find index of point with smallest number829830int i0 = 0;831for (int i = 1; i < 4; i++)832if (vertexnr[elface[0][i]-1] < vertexnr[elface[0][i0]-1]) i0 = i;833834double x;835double y;836double dxx;837double dxy;838double dyx;839double dyy;840841switch (i0)842{843case 0:844x = xi(0); y = xi(1);845dxx = 1; dxy = 0;846dyx = 0; dyy = 1;847break;848case 1:849x = xi(1); y = 1-xi(0);850dxx = 0; dxy = 1;851dyx = -1; dyy = 0;852break;853case 2:854x = 1-xi(0); y = 1-xi(1);855dxx = -1; dxy = 0;856dyx = 0; dyy = -1;857break;858case 3:859x = 1-xi(1); y = xi(0);860dxx = 0; dxy =-1;861dyx = 1; dyy = 0;862break;863}864865if (vertexnr[elface[0][(i0+1) % 4]-1] > vertexnr[elface[0][(i0+3) % 4]-1])866{867Swap (x,y);868Swap (dxx, dyx);869Swap (dxy, dyy);870}871872b1.SetOrder (faceorder);873b2.SetOrder (faceorder);874875b1.CalcFDf (x);876b1.CalcDDf (x);877b2.CalcFDf (y);878b2.CalcDDf (y);879880for (int n0 = 2; n0 <= faceorder; n0++)881for (int n1 = 2; n1 <= faceorder; n1++)882{883fddshape[index] =884b1.GetDDf(n0) * dxx * dxx * b2.GetF(n1) +8852* b1.GetDf(n0) * dxx * b2.GetDf(n1) * dyx +886b1.GetF(n0) * b2.GetDDf(n1) * dyx * dyx +887888b1.GetDDf(n0) * dxy * dxy * b2.GetF(n1) +8892* b1.GetDf(n0) * dxy * b2.GetDf(n1) * dyy +890b1.GetF(n0) * b2.GetDDf(n1) * dyy * dyy;891892index++;893}894}895896897898// ----------------------------------------------------------------------------899// FETet900// ----------------------------------------------------------------------------901902903void FETet :: SetReferencePoint (Point<3> axi)904{905BaseFiniteElement3D :: SetReferencePoint (axi);906907lambda(0) = xi(0);908lambda(1) = xi(1);909lambda(2) = xi(2);910lambda(3) = 1-xi(0)-xi(1)-xi(2);911912dlambda(0,0) = 1; dlambda(0,1) = 0; dlambda(0,2) = 0;913dlambda(1,0) = 0; dlambda(1,1) = 1; dlambda(1,2) = 0;914dlambda(2,0) = 0; dlambda(2,1) = 0; dlambda(2,2) = 1;915dlambda(3,0) = -1; dlambda(3,1) = -1; dlambda(3,2) = -1;916}917918919void FETet :: CalcVertexShapes ()920{921for (int v = 0; v < nvertices; v++)922{923vshape[v] = lambda(v);924vdshape[v](0) = dlambda(v,0);925vdshape[v](1) = dlambda(v,1);926vdshape[v](2) = dlambda(v,2);927}928}929930void FETet :: CalcVertexShapesOnly ()931{932for (int v = 0; v < nvertices; v++)933vshape[v] = lambda(v);934}935936937void FETet :: CalcEdgeShapes ()938{939int index = 0;940941for (int e = 0; e < nedges; e++)942{943int i0 = eledge[e][0]-1;944int i1 = eledge[e][1]-1;945946double arg = lambda(i0)+lambda(i1);947948if (fabs(arg) < EPSILON) // division by 0949{950for (int k = 2; k <= edgeorder[e]; k++)951{952eshape[index] = 0;953edshape[index] = Vec<3>(0,0,0);954index++;955}956continue;957}958959if (edgeorient[e] == -1) Swap (i0, i1);960961double xi = lambda[i1]/arg;962963b1.SetOrder (edgeorder[e]);964b1.CalcFDf (xi);965966double decay = arg;967double ddecay;968969double l0 = lambda(i0);970double dl0x = dlambda(i0,0);971double dl0y = dlambda(i0,1);972double dl0z = dlambda(i0,2);973974double l1 = lambda(i1);975double dl1x = dlambda(i1,0);976double dl1y = dlambda(i1,1);977double dl1z = dlambda(i1,2);978979double dargx = dl0x + dl1x;980double dargy = dl0y + dl1y;981double dargz = dl0z + dl1z;982983for (int k = 2; k <= edgeorder[e]; k++)984{985ddecay = k*decay;986decay *= arg;987988eshape[index] = b1.GetF (k) * decay;989edshape[index] = Vec<3>990(b1.GetDf(k) * (dl1x*arg - l1*dargx) *991decay / (arg * arg) + b1.GetF(k) * ddecay * dargx,992b1.GetDf(k) * (dl1y*arg - l1*dargy) *993decay / (arg * arg) + b1.GetF(k) * ddecay * dargy,994b1.GetDf(k) * (dl1z*arg - l1*dargz) *995decay / (arg * arg) + b1.GetF(k) * ddecay * dargz);996997index++;998}999}1000100110021003/*1004int index = 0;1005for (int e = 0; e < nedges; e++)1006{1007if (edgeorder[e] <= 1) continue;10081009int i0 = eledge[e][0]-1;1010int i1 = eledge[e][1]-1;10111012if (edgeorient[e] == -1) Swap (i0, i1); // reverse orientation10131014double x = lambda(i1)-lambda(i0);1015double y = 1-lambda(i0)-lambda(i1);1016double fy = (1-y)*(1-y);10171018// double p3 = 0, p3x = 0, p3y = 0;1019// double p2 = -1, p2x = 0, p2y = 0;1020// double p1 = x, p1x = 1, p1y = 0;10211022double p3 = 0, p3x = 0, p3y = 0;1023double p2 = -0.5, p2x = 0, p2y = 0;1024double p1 = 0.5*x, p1x = 0.5, p1y = 0;10251026for (int j=2; j<= edgeorder[e]; j++)1027{1028p3=p2; p3x = p2x; p3y = p2y;1029p2=p1; p2x = p1x; p2y = p1y;1030double c1 = (2.0*j-3) / j;1031double c2 = (j-3.0) / j;10321033p1 = c1 * x * p2 - c2 * fy * p3;1034p1x = c1 * p2 + c1 * x * p2x - c2 * fy * p3x;1035p1y = c1 * x * p2y - (c2 * 2 * (y-1) * p3 + c2 * fy * p3y);10361037eshape[index] = p1;1038for (int k = 0; k < 3; k++)1039edshape[index](k) =1040p1x * ( dlambda(i1,k) - dlambda(i0,k) ) +1041p1y * (-dlambda(i1,k) - dlambda(i0,k) );1042index++;1043}10441045}10461047*/10481049105010511052}10531054105510561057void FETet :: CalcEdgeShapesOnly ()1058{1059int index = 0;10601061for (int e = 0; e < nedges; e++)1062{1063int i0 = eledge[e][0]-1;1064int i1 = eledge[e][1]-1;10651066if (edgeorient[e] == -1) Swap (i0, i1);10671068double arg = lambda(i0)+lambda(i1);1069double xi = lambda[i1];10701071/*1072b1.SetOrder (edgeorder[e]);1073b1.CalcFScaled (xi, arg);10741075for (int k = 2; k <= edgeorder[e]; k++, index++)1076eshape[index] = b1.GetF (k);1077*/1078b1.CalcFScaled (edgeorder[e], xi, arg, &eshape[index]);1079index += edgeorder[e]-1;1080}1081}1082108310841085108610871088void FETet :: CalcFaceShapes ()1089{1090int index = 0;10911092for (int f = 0; f < nfaces; f++)1093{1094if (faceorder[f] <= 2) continue;10951096int i0 = elface[f][0]-1;1097int i1 = elface[f][1]-1;1098int i2 = elface[f][2]-1;10991100if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1);1101if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2);1102if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2);11031104double arg = lambda(i1) + lambda(i2);1105double arg2 = lambda(i0) + lambda(i1) + lambda(i2);11061107if (fabs(arg) < EPSILON || fabs(arg2) < EPSILON) // division by 01108{1109for (int k = 0; k < nfaceshapes[f]; k++)1110{1111fshape[index] = 0;1112fdshape[index] = Vec<3>(0,0,0);1113index++;1114}1115continue;1116}11171118b1.SetOrder (faceorder[f]);1119b2.SetOrder (faceorder[f]);11201121b1.CalcFDf (lambda(i0)/arg2);1122b2.CalcFDf (lambda(i2)/arg);11231124double decay = 1;1125double ddecay;11261127double l0 = lambda(i0);1128double l1 = lambda(i1);1129double l2 = lambda(i2);1130double dl0x = dlambda(i0,0);1131double dl0y = dlambda(i0,1);1132double dl0z = dlambda(i0,2);1133double dl1x = dlambda(i1,0);1134double dl1y = dlambda(i1,1);1135double dl1z = dlambda(i1,2);1136double dl2x = dlambda(i2,0);1137double dl2y = dlambda(i2,1);1138double dl2z = dlambda(i2,2);11391140double dargx = dl1x + dl2x;1141double dargy = dl1y + dl2y;1142double dargz = dl1z + dl2z;1143double darg2x = dl0x + dl1x + dl2x;1144double darg2y = dl0y + dl1y + dl2y;1145double darg2z = dl0z + dl1z + dl2z;11461147for (int n1 = 2; n1 < faceorder[f]; n1++)1148{1149ddecay = (n1-1)*decay;1150decay *= arg;11511152double decay2 = arg2;1153double ddecay2;11541155for (int n0 = 2; n0 < faceorder[f]-n1+2; n0++)1156{1157ddecay2 = n0*decay2;1158decay2 *= arg2;11591160fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay * decay2;1161fdshape[index] = Vec<3>1162(b1.GetDf(n0) * (dl0x * arg2 - l0 * darg2x)/(arg2*arg2) * b2.GetF(n1) * decay * decay2 +1163b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay * decay2 +1164b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx * decay2 +1165b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2x,11661167b1.GetDf(n0) * (dl0y * arg2 - l0 * darg2y)/(arg2*arg2) * b2.GetF(n1) * decay * decay2 +1168b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay * decay2 +1169b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy * decay2 +1170b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2y,11711172b1.GetDf(n0) * (dl0z * arg2 - l0 * darg2z)/(arg2*arg2) * b2.GetF(n1) * decay * decay2 +1173b1.GetF(n0) * b2.GetDf(n1) * (dl2z * arg - l2 * dargz)/(arg*arg) * decay * decay2 +1174b1.GetF(n0) * b2.GetF(n1) * ddecay * dargz * decay2 +1175b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2z);11761177index++;1178}1179}1180}1181}11821183118411851186// ----------------------------------------------------------------------------1187// FEPrism1188// ----------------------------------------------------------------------------118911901191void FEPrism :: SetReferencePoint (Point<3> axi)1192{1193BaseFiniteElement3D :: SetReferencePoint (axi);11941195lambda(0) = xi(0);1196lambda(1) = xi(1);1197lambda(2) = 1-xi(0)-xi(1);1198lambda(3) = xi(2);11991200dlambda(0,0) = 1; dlambda(0,1) = 0; dlambda(0,2) = 0;1201dlambda(1,0) = 0; dlambda(1,1) = 1; dlambda(1,2) = 0;1202dlambda(2,0) = -1; dlambda(2,1) = -1; dlambda(2,2) = 0;1203dlambda(3,0) = 0; dlambda(3,1) = 0; dlambda(3,2) = 1;1204}120512061207void FEPrism :: CalcVertexShapes ()1208{1209double zcomp = 1-lambda(3);12101211for (int v = 0; v < nvertices; v++)1212{1213if (v == 3) zcomp = 1-zcomp;12141215vshape[v] = lambda(v % 3) * zcomp;1216vdshape[v](0) = dlambda(v % 3,0) * zcomp;1217vdshape[v](1) = dlambda(v % 3,1) * zcomp;1218vdshape[v](2) = lambda(v % 3) * (-dlambda(3,2));12191220if (v >= 3) vdshape[v](2) *= -1;1221}1222}122312241225void FEPrism :: CalcEdgeShapes ()1226{1227int index = 0;1228int e;1229// triangle edge shapes12301231for (e = 0; e < 6; e++)1232{1233int i0 = (eledge[e][0]-1) % 3;1234int i1 = (eledge[e][1]-1) % 3;12351236double arg = lambda[i0]+lambda[i1];12371238if (fabs(arg) < EPSILON) // division by 01239{1240for (int k = 2; k <= edgeorder[e]; k++)1241{1242eshape[index] = 0;1243edshape[index] = Vec<3>(0,0,0);1244index++;1245}1246continue;1247}12481249if (edgeorient[e] == -1) Swap (i0, i1);12501251double xi = lambda[i1]/arg;12521253b1.SetOrder (edgeorder[e]);1254b1.CalcFDf (xi);12551256double decay = arg;1257double ddecay;12581259double zarg = e < 3 ? (1-lambda(3)) : lambda(3);1260double zcomp = zarg;1261double dzcomp;12621263double l0 = lambda(i0);1264double dl0x = dlambda(i0,0);1265double dl0y = dlambda(i0,1);12661267double l1 = lambda(i1);1268double dl1x = dlambda(i1,0);1269double dl1y = dlambda(i1,1);12701271double dargx = dl0x + dl1x;1272double dargy = dl0y + dl1y;127312741275/*12761277for (int k = 2; k <= edgeorder[e]; k++)1278{1279ddecay = k*decay;1280decay *= arg;12811282dzcomp = k*zcomp;1283zcomp *= zarg;12841285eshape[index] = b1.GetF (k) * decay * zcomp;1286edshape[index] = Vec<3>1287((b1.GetDf(k) * (dl1x*arg - l1*dargx) *1288decay / (arg * arg) + b1.GetF(k) * ddecay * dargx) * zcomp,1289(b1.GetDf(k) * (dl1y*arg - l1*dargy) *1290decay / (arg * arg) + b1.GetF(k) * ddecay * dargy) * zcomp,1291b1.GetF(k) * decay * dzcomp * (e < 3 ? -1 : 1));1292index++;1293}1294*/12951296// JS linear in z-direction (for thin plates !)1297for (int k = 2; k <= edgeorder[e]; k++)1298{1299ddecay = k*decay;1300decay *= arg;13011302// dzcomp = k*zcomp;1303// zcomp *= zarg;1304dzcomp = 1;1305zcomp = zarg;13061307eshape[index] = b1.GetF (k) * decay * zcomp;1308edshape[index] = Vec<3>1309((b1.GetDf(k) * (dl1x*arg - l1*dargx) *1310decay / (arg * arg) + b1.GetF(k) * ddecay * dargx) * zcomp,1311(b1.GetDf(k) * (dl1y*arg - l1*dargy) *1312decay / (arg * arg) + b1.GetF(k) * ddecay * dargy) * zcomp,1313b1.GetF(k) * decay * dzcomp * (e < 3 ? -1 : 1));1314index++;1315}1316131713181319}13201321// rectangle edge shapes13221323for (e = 6; e < nedges; e++)1324{1325int i0 = eledge[e][0]-1;13261327double arg = lambda[i0];13281329if (fabs(arg) < EPSILON) // division by 01330{1331for (int k = 2; k <= edgeorder[e]; k++)1332{1333eshape[index] = 0.;1334edshape[index] = Vec<3>(0.,0.,0.);1335index++;1336}1337continue;1338}13391340double xi = lambda[3];13411342if (edgeorient[e] == -1) xi = 1-xi;13431344b1.SetOrder (edgeorder[e]);1345b1.CalcFDf (xi);13461347double decay = arg;1348double ddecay;13491350double l0 = lambda(i0);1351double l0x = dlambda(i0,0);1352double l0y = dlambda(i0,1);13531354for (int k = 2; k <= edgeorder[e]; k++)1355{1356ddecay = k*decay;1357decay *= arg;13581359eshape[index] = b1.GetF (k) * decay;1360edshape[index] = Vec<3>1361(b1.GetF(k) * ddecay * l0x,1362b1.GetF(k) * ddecay * l0y,1363b1.GetDf(k) * edgeorient[e] * decay);1364index++;1365}1366}1367}136813691370void FEPrism :: CalcFaceShapes ()1371{1372int index = 0;1373int f;13741375// triangle face parts13761377for (f = 0; f < 2; f++)1378{1379int i0 = elface[f][0]-1;1380int i1 = elface[f][1]-1;1381int i2 = elface[f][2]-1;13821383if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1);1384if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2);1385if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2);13861387i0 = i0 % 3;1388i1 = i1 % 3;1389i2 = i2 % 3;13901391double arg = lambda(i1) + lambda(i2);13921393if (fabs(arg) < EPSILON) // division by 01394{1395for (int k = 0; k < nfaceshapes[f]; k++)1396{1397fshape[index] = 0;1398fdshape[index] = Vec<3>(0,0,0);1399index++;1400}1401continue;1402}14031404b1.SetOrder (faceorder[f]);1405b2.SetOrder (faceorder[f]);14061407b1.CalcFDf (lambda(i0));1408b2.CalcFDf (lambda(i2)/arg);14091410double decay = 1;1411double ddecay;14121413double l0 = lambda(i0);1414double l1 = lambda(i1);1415double l2 = lambda(i2);1416double dl0x = dlambda(i0,0);1417double dl0y = dlambda(i0,1);1418double dl0z = dlambda(i0,2);1419double dl1x = dlambda(i1,0);1420double dl1y = dlambda(i1,1);1421double dl1z = dlambda(i1,2);1422double dl2x = dlambda(i2,0);1423double dl2y = dlambda(i2,1);1424double dl2z = dlambda(i2,2);14251426double dargx = dl1x + dl2x;1427double dargy = dl1y + dl2y;1428double dargz = dl1z + dl2z;14291430double arg2 = f == 0 ? 1-xi(2) : xi(2);1431double darg2z = f == 0 ? -1 : 1;14321433for (int n1 = 2; n1 < faceorder[f]; n1++)1434{1435ddecay = (n1-1)*decay;1436decay *= arg;14371438double decay2 = arg2;1439double ddecay2;14401441for (int n0 = 2; n0 < faceorder[f]-n1+2; n0++)1442{1443ddecay2 = n0*decay2;1444decay2 *= arg2;14451446fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay * decay2;1447fdshape[index] = Vec<3>1448(b1.GetDf(n0) * dl0x * b2.GetF(n1) * decay * decay2 +1449b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay * decay2 +1450b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx * decay2,14511452b1.GetDf(n0) * dl0y * b2.GetF(n1) * decay * decay2 +1453b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay * decay2 +1454b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy * decay2,14551456b1.GetDf(n0) * dl0z * b2.GetF(n1) * decay * decay2 +1457b1.GetF(n0) * b2.GetDf(n1) * (dl2z * arg - l2 * dargz)/(arg*arg) * decay * decay2 +1458b1.GetF(n0) * b2.GetF(n1) * ddecay * dargz * decay2 +1459b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2z);14601461index++;1462}1463}1464}146514661467// quad parts14681469for (f = 2; f < nfaces; f++)1470{1471// find index of point with smallest number14721473int i, i0 = 0;1474for (i = 1; i < 4; i++)1475if (vertexnr[elface[f][i]-1] < vertexnr[elface[f][i0]-1]) i0 = i;14761477double arg = 0;1478double dargx = 0;1479double dargy = 0;1480double dargz = 0;1481for (i = 0; i < 4; i++)1482{1483arg += lambda((elface[f][i]-1) % 3)/2.0;1484dargx += dlambda((elface[f][i]-1) % 3,0)/2.0;1485dargy += dlambda((elface[f][i]-1) % 3,1)/2.0;1486dargz += dlambda((elface[f][i]-1) % 3,2)/2.0;1487}14881489if (fabs(arg) < EPSILON) // division by 01490{1491for (int k = 0; k < nfaceshapes[f]; k++)1492{1493fshape[index] = 0;1494fdshape[index] = Vec<3>(0,0,0);1495index++;1496}1497continue;1498}14991500int i1 = (i0+3) % 4;1501int j = (elface[f][i0]-1) % 3;15021503double lam = lambda(j)/arg;1504double dlamx = (dlambda(j,0)*arg-lambda(j)*dargx)/(arg*arg);1505double dlamy = (dlambda(j,1)*arg-lambda(j)*dargy)/(arg*arg);1506double dlamz = (dlambda(j,2)*arg-lambda(j)*dargz)/(arg*arg);15071508double x;1509double z;1510double dxx;1511double dxy;1512double dxz;1513double dzx;1514double dzy;1515double dzz;15161517int ratvar;1518/*1519switch (i0)1520{1521case 0:1522x = xi(2); z = lam;15231524dxx = 0; dxy = 0; dxz = 1;1525dzx = dlamx; dzy = dlamy; dzz = dlamz;1526ratvar = 1;1527break;1528case 1:1529x = 1-lam; z = xi(2);1530dxx = -dlamx; dxy = -dlamy; dxz = -dlamz;1531dzx = 0; dzy = 0; dzz = 1;1532ratvar = 0;1533break;1534case 2:1535x = 1-xi(2); z = 1-lam;1536dxx = 0; dxy = 0; dxz = -1;1537dzx = -dlamx; dzy = -dlamy; dzz = -dlamz;1538ratvar = 1;1539break;1540case 3:1541x = lam; z = 1-xi(2);1542dxx = dlamx; dxy = dlamy; dxz = dlamz;1543dzx = 0; dzy = 0; dzz = -1;1544ratvar = 0;1545break;1546}1547*/15481549ratvar = 0;1550x = 1-lam;1551dxx = -dlamx; dxy = -dlamy; dxz = -dlamz;1552if (i0 == 0 || i0 == 1)1553{1554z = xi(2);1555dzx = 0; dzy = 0; dzz = 1;1556}1557else1558{1559z = 1-xi(2);1560dzx = 0; dzy = 0; dzz = -1;1561}15621563int ix = i0 ^ 1;1564int iz = 3-i0;15651566if (vertexnr[elface[f][ix]-1] > vertexnr[elface[f][iz]-1])1567{1568Swap (x,z);1569Swap (dxx, dzx);1570Swap (dxy, dzy);1571Swap (dxz, dzz);1572ratvar = 1-ratvar;1573}15741575b1.SetOrder (faceorder[f]);1576b2.SetOrder (faceorder[f]);15771578b1.CalcFDf (x);1579b2.CalcFDf (z);15801581double decay = arg;1582double ddecay;15831584for (int n0 = 2; n0 <= faceorder[f]; n0++)1585{1586ddecay = n0*decay;1587decay *= arg;15881589if (ratvar == 1) decay = arg;15901591for (int n1 = 2; n1 <= faceorder[f]; n1++)1592{1593if (ratvar == 1)1594{1595ddecay = n1*decay;1596decay *= arg;1597}15981599fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay;1600fdshape[index] = Vec<3>1601(b1.GetDf(n0) * dxx * b2.GetF(n1) * decay +1602b1.GetF(n0) * b2.GetDf(n1) * dzx * decay +1603b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx,16041605b1.GetDf(n0) * dxy * b2.GetF(n1) * decay +1606b1.GetF(n0) * b2.GetDf(n1) * dzy * decay +1607b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy,16081609b1.GetDf(n0) * dxz * b2.GetF(n1) * decay +1610b1.GetF(n0) * b2.GetDf(n1) * dzz * decay +1611b1.GetF(n0) * b2.GetF(n1) * ddecay * dargz);16121613index++;1614}1615}1616}1617}1618161916201621// ----------------------------------------------------------------------------1622// FEPyramid1623// ----------------------------------------------------------------------------162416251626void FEPyramid :: SetReferencePoint (Point<3> axi)1627{1628BaseFiniteElement3D :: SetReferencePoint (axi);1629}163016311632void FEPyramid :: CalcVertexShapes ()1633{1634double x = xi(0);1635double y = xi(1);1636double z = xi(2);16371638if (z == 1.) z = 1-1e-10;1639vshape[0] = (1-z-x)*(1-z-y) / (1-z);1640vshape[1] = x*(1-z-y) / (1-z);1641vshape[2] = x*y / (1-z);1642vshape[3] = (1-z-x)*y / (1-z);1643vshape[4] = z;16441645double z1 = 1-z;1646double z2 = z1*z1;16471648vdshape[0] = Vec<3>( -(z1-y)/z1, -(z1-x)/z1, ((x+y+2*z-2)*z1+(z1-y)*(z1-x))/z2 );1649vdshape[1] = Vec<3>( (z1-y)/z1, -x/z1, (-x*z1+x*(z1-y))/z2 );1650vdshape[2] = Vec<3>( y/z1, x/z1, x*y/z2 );1651vdshape[3] = Vec<3>( -y/z1, (z1-x)/z1, (-y*z1+y*(z1-x))/z2 );1652vdshape[4] = Vec<3>( 0, 0, 1 );1653}165416551656void FEPyramid :: CalcEdgeShapes ()1657{1658int index = 0;16591660for (int e = 0; e < GetNEdges(); e++)1661{1662for (int k = 2; k <= edgeorder[e]; k++)1663{1664eshape[index] = 0;1665edshape[index] = Vec<3>(0,0,0);1666index++;1667}1668}1669}167016711672void FEPyramid :: CalcFaceShapes ()1673{1674int index = 0;16751676for (int f = 0; f < GetNFaces(); f++)1677{1678for (int k = 0; k < nfaceshapes[f]; k++)1679{1680fshape[index] = 0;1681fdshape[index] = Vec<3>(0,0,0);1682index++;1683}1684}1685}168616871688168916901691// ----------------------------------------------------------------------------1692// FEHex1693// ----------------------------------------------------------------------------169416951696void FEHex :: SetReferencePoint (Point<3> axi)1697{1698BaseFiniteElement3D :: SetReferencePoint (axi);1699}170017011702void FEHex :: CalcVertexShapes ()1703{1704double x = xi(0);1705double y = xi(1);1706double z = xi(2);17071708vshape[0] = (1-x)*(1-y)*(1-z);1709vshape[1] = x *(1-y)*(1-z);1710vshape[2] = x * y *(1-z);1711vshape[3] = (1-x)* y *(1-z);1712vshape[4] = (1-x)*(1-y)* z;1713vshape[5] = x *(1-y)* z;1714vshape[6] = x * y * z;1715vshape[7] = (1-x)* y * z;17161717vdshape[0] = Vec<3>(-(1-y)*(1-z), -(1-x)*(1-z), -(1-x)*(1-y));1718vdshape[1] = Vec<3>( (1-y)*(1-z), -x *(1-z), -x *(1-y));1719vdshape[2] = Vec<3>( y *(1-z), x *(1-z), -x * y);1720vdshape[3] = Vec<3>( -y *(1-z), (1-x)*(1-z), -(1-x)*y);1721vdshape[4] = Vec<3>(-(1-y)* z, -(1-x)* z, (1-x)*(1-y));1722vdshape[5] = Vec<3>( (1-y)* z, -x * z, x *(1-y));1723vdshape[6] = Vec<3>( y * z, x * z, x * y);1724vdshape[7] = Vec<3>( -y * z, (1-x)* z, (1-x)*y);17251726}172717281729void FEHex :: CalcEdgeShapes ()1730{1731int index = 0;17321733for (int e = 0; e < GetNEdges(); e++)1734{1735for (int k = 2; k <= edgeorder[e]; k++)1736{1737eshape[index] = 0;1738edshape[index] = Vec<3>(0,0,0);1739index++;1740}1741}1742}174317441745void FEHex :: CalcFaceShapes ()1746{1747int index = 0;17481749for (int f = 0; f < GetNFaces(); f++)1750{1751for (int k = 0; k < nfaceshapes[f]; k++)1752{1753fshape[index] = 0;1754fdshape[index] = Vec<3>(0,0,0);1755index++;1756}1757}1758}1759176017611762176317641765176617671768int CurvedElements :: IsSurfaceElementCurved (int elnr) const1769{1770if (mesh.coarsemesh)1771{1772const HPRefElement & hpref_el =1773(*mesh.hpelements) [ mesh[(SurfaceElementIndex) elnr].hp_elnr];17741775return mesh.coarsemesh->GetCurvedElements().IsSurfaceElementCurved (hpref_el.coarse_elnr);1776}17771778177917801781Element2d elem = mesh[(SurfaceElementIndex) elnr];17821783switch (elem.GetType())1784{1785case TRIG:1786{1787FETrig fe2d(*this);1788fe2d.SetElementNumber (elnr+1);1789return (fe2d.IsCurved());1790break;1791}17921793case QUAD:1794{1795FEQuad fe2d(*this);1796fe2d.SetElementNumber (elnr+1);1797return (fe2d.IsCurved());1798break;1799}18001801}1802return 0;1803}1804180518061807int CurvedElements :: IsElementCurved (int elnr) const1808{1809if (mesh.coarsemesh)1810{1811const HPRefElement & hpref_el =1812(*mesh.hpelements) [ mesh[(ElementIndex) elnr].hp_elnr];18131814return mesh.coarsemesh->GetCurvedElements().IsElementCurved (hpref_el.coarse_elnr);1815}1816181718181819Element elem = mesh[(ElementIndex) elnr];18201821switch (elem.GetType())1822{1823case TET:1824{1825FETet fe3d(*this);1826fe3d.SetElementNumber (elnr+1);1827return (fe3d.IsCurved());1828break;1829}18301831case PRISM:1832{1833FEPrism fe3d(*this);1834fe3d.SetElementNumber (elnr+1);1835return (fe3d.IsCurved());1836break;1837}18381839case PYRAMID:1840{1841FEPyramid fe3d(*this);1842fe3d.SetElementNumber (elnr+1);1843return (fe3d.IsCurved());1844break;1845}18461847case HEX:1848{1849FEHex fe3d(*this);1850fe3d.SetElementNumber (elnr+1);1851return (fe3d.IsCurved());1852break;1853}18541855}18561857return 0;1858}185918601861void CurvedElements :: CalcSegmentTransformation (double xi, int segnr,1862Point<3> * x, Vec<3> * dxdxi)1863{1864if (mesh.coarsemesh)1865{1866const HPRefElement & hpref_el =1867(*mesh.hpelements) [ mesh[(SegmentIndex) segnr].hp_elnr];18681869// xi umrechnen1870double lami[2];1871lami[0] = xi;1872lami[1] = 1-xi;18731874double coarse_xi = 0;1875for (int i = 0; i < 2; i++)1876coarse_xi += hpref_el.param[i][0] * lami[i];18771878mesh.coarsemesh->GetCurvedElements().CalcSegmentTransformation (coarse_xi, hpref_el.coarse_elnr, x, dxdxi);1879return;1880}188118821883// xi = 1-xi; // or, this way ????? JS1884FESegm segm (*this);1885segm.SetElementNumber (segnr+1);1886segm.SetReferencePoint (Point<1>(xi));18871888// segm.CalcVertexShapes (x != NULL, dxdxi != NULL);1889segm.CalcVertexShapes ();18901891if (x)1892{1893(*x) = Point<3>(0,0,0);1894for (int v = 0; v < 2; v++)1895(*x) = (*x) + segm.GetVertexShape(v) * mesh.Point(segm.GetVertexNr(v));1896}18971898if (dxdxi)1899{1900(*dxdxi) = Vec<3>(0,0,0);1901for (int v = 0; v < 2; v++)1902(*dxdxi) = (*dxdxi) + segm.GetVertexDShape(v) * mesh.Point(segm.GetVertexNr(v));1903}19041905if (segm.GetEdgeOrder() > 1)1906{1907// segm.CalcEdgeShapes (x != NULL, dxdxi != NULL);1908segm.CalcEdgeShapes ();19091910if (x)1911{1912int gindex = edgecoeffsindex[segm.GetEdgeNr()-1];1913for (int k = 2; k <= segm.GetEdgeOrder(); k++, gindex++)1914(*x) = (*x) + segm.GetEdgeShape(k-2) * edgecoeffs[gindex];1915}19161917if (dxdxi)1918{1919int gindex = edgecoeffsindex[segm.GetEdgeNr()-1];1920for (int k = 2; k <= segm.GetEdgeOrder(); k++, gindex++)1921(*dxdxi) = (*dxdxi) + segm.GetEdgeDShape(k-2) * edgecoeffs[gindex];1922}1923}1924}1925192619271928void CurvedElements :: CalcMultiPointSegmentTransformation (ARRAY<double> * xi, int segnr,1929ARRAY<Point<3> > * x,1930ARRAY<Vec<3> > * dxdxi)1931{1932int size = xi->Size();19331934if (mesh.coarsemesh)1935{1936const HPRefElement & hpref_el =1937(*mesh.hpelements) [ mesh[(SegmentIndex) segnr].hp_elnr];19381939// xi umrechnen1940ARRAY< Point<2> > lami;1941lami.SetSize (size);1942for (int i = 0; i<size; i++)1943{1944lami[i](0) = (*xi)[i];1945lami[i](1) = 1-(*xi)[i];1946}19471948ARRAY<double> coarse_xi;1949coarse_xi.SetSize (size);1950coarse_xi = 0;195119521953for (int j = 0; j < 2; j++)1954for (int i = 0; i<size; i++)1955coarse_xi[i] += hpref_el.param[j][0] * lami[i](j);19561957mesh.coarsemesh->GetCurvedElements().CalcMultiPointSegmentTransformation1958(&coarse_xi, hpref_el.coarse_elnr, x, dxdxi);1959return;1960}1961196219631964FESegm segm (*this);1965segm.SetElementNumber (segnr+1);1966x->SetSize (size);1967dxdxi->SetSize (size);19681969for (int i = 0; i < size; i++)1970{1971segm.SetReferencePoint (Point<1>((*xi)[i]));19721973// segm.CalcVertexShapes (x != NULL, dxdxi != NULL);1974segm.CalcVertexShapes ();19751976(*x)[i] = Point<3>(0,0,0);1977(*dxdxi)[i] = Vec<3>(0,0,0);19781979for (int v = 0; v < 2; v++)1980{1981(*x)[i] = (*x)[i] + segm.GetVertexShape(v) * mesh.Point(segm.GetVertexNr(v));1982(*dxdxi)[i] = (*dxdxi)[i] + segm.GetVertexDShape(v) * mesh.Point(segm.GetVertexNr(v));1983}19841985if (segm.GetEdgeOrder() > 1)1986{1987// segm.CalcEdgeShapes (x != NULL, dxdxi != NULL);1988segm.CalcEdgeShapes ();19891990int gindex = edgecoeffsindex[segm.GetEdgeNr()-1];1991for (int k = 2; k <= segm.GetEdgeOrder(); k++, gindex++)1992{1993(*x)[i] = (*x)[i] + segm.GetEdgeShape(k-2) * edgecoeffs[gindex];1994(*dxdxi)[i] = (*dxdxi)[i] + segm.GetEdgeDShape(k-2) * edgecoeffs[gindex];1995}1996}1997}1998}199920002001200220032004void CurvedElements :: CalcSurfaceTransformation (Point<2> xi, int elnr,2005Point<3> * x, Mat<3,2> * dxdxi)2006{2007if (mesh.coarsemesh)2008{2009const HPRefElement & hpref_el =2010(*mesh.hpelements) [ mesh[(SurfaceElementIndex) elnr].hp_elnr];20112012// xi umrechnen2013double lami[4];2014FlatVector vlami(4, lami);2015vlami = 0;2016mesh[(SurfaceElementIndex) elnr] . GetShapeNew (xi, vlami);20172018Mat<2,2> trans;2019Mat<3,2> dxdxic;2020if (dxdxi)2021{2022MatrixFixWidth<2> dlami(4);2023dlami = 0;2024mesh[(SurfaceElementIndex) elnr] . GetDShapeNew (xi, dlami);20252026trans = 0;2027for (int k = 0; k < 2; k++)2028for (int l = 0; l < 2; l++)2029{2030double sum = 0;2031for (int i = 0; i < 4; i++)2032sum += hpref_el.param[i][l] * dlami(i, k);2033trans(l,k) = sum;2034}2035}20362037Point<2> coarse_xi(0,0);2038for (int i = 0; i < 4; i++)2039{2040coarse_xi(0) += hpref_el.param[i][0] * lami[i];2041coarse_xi(1) += hpref_el.param[i][1] * lami[i];2042}2043mesh.coarsemesh->GetCurvedElements().CalcSurfaceTransformation (coarse_xi, hpref_el.coarse_elnr, x, &dxdxic);20442045if (dxdxi)2046*dxdxi = dxdxic * trans;20472048return;2049}20502051205220532054const Element2d & elem = mesh[(SurfaceElementIndex) elnr];20552056BaseFiniteElement2D * fe2d;20572058// char locmem[max2(sizeof(FEQuad), sizeof(FETrig))];2059char locmemtrig[sizeof(FETrig)];2060char locmemquad[sizeof(FEQuad)];2061switch (elem.GetType())2062{2063case TRIG: fe2d = new (locmemtrig) FETrig (*this); break;2064case QUAD: fe2d = new (locmemquad) FEQuad (*this); break;2065}20662067// fe2d->SetElementNumber (elnr+1);2068fe2d->SetReferencePoint (xi);2069fe2d->CalcVertexShapes ();20702071if (x)2072{2073(*x) = Point<3>(0,0,0);2074for (int v = 0; v < fe2d->GetNVertices(); v++)2075(*x) = (*x) + fe2d->GetVertexShape(v) * mesh.Point(elem[v]);2076// (*x) = (*x) + fe2d->GetVertexShape(v) * mesh.Point(fe2d->GetVertexNr(v));2077}20782079if (dxdxi)2080{2081for (int i = 0; i < 3; i++)2082for (int j = 0; j < 2; j++)2083(*dxdxi)(i,j) = 0;20842085for (int v = 0; v < elem.GetNV(); v++)2086for (int i = 0; i < 3; i++)2087for (int j = 0; j < 2; j++)2088(*dxdxi)(i,j) += fe2d->GetVertexDShape(v)(j) * mesh.Point(elem[v]).X(i+1);2089// (*dxdxi)(i,j) += fe2d->GetVertexDShape(v)(j) * mesh.Point(fe2d->GetVertexNr(v)).X(i+1);2090}20912092if (IsHighOrder())2093{2094fe2d->SetElementNumber (elnr+1);20952096// fe2d->CalcEdgeShapes (x != NULL, dxdxi != NULL);2097fe2d->CalcEdgeShapes ();2098if (x)2099{2100int index = 0;2101for (int e = 0; e < fe2d->GetNEdges(); e++)2102{2103int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1];21042105for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++)2106(*x) = (*x) + fe2d->GetEdgeShape(index) * edgecoeffs[gindex];2107}2108}21092110if (dxdxi)2111{2112int index = 0;2113for (int e = 0; e < fe2d->GetNEdges(); e++)2114{2115int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1];2116for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++)2117for (int i = 0; i < 3; i++)2118for (int j = 0; j < 2; j++)2119(*dxdxi)(i,j) += fe2d->GetEdgeDShape(index)(j) * edgecoeffs[gindex](i);2120}2121}21222123if (mesh.GetDimension() == 3)2124{2125// fe2d->CalcFaceShapes (x != NULL, dxdxi != NULL);2126fe2d->CalcFaceShapes ();21272128if (x)2129{2130int gindex = facecoeffsindex[fe2d->GetFaceNr()-1];2131for (int index = 0; index < fe2d->GetNFaceShapes(); index++, gindex++)2132{2133(*x) = (*x) + fe2d->GetFaceShape(index) * facecoeffs[gindex];2134}2135}21362137if (dxdxi)2138{2139int gindex = facecoeffsindex[fe2d->GetFaceNr()-1];2140for (int index = 0; index < fe2d->GetNFaceShapes(); index++, gindex++)2141for (int i = 0; i < 3; i++)2142for (int j = 0; j < 2; j++)2143(*dxdxi)(i,j) += fe2d->GetFaceDShape(index)(j) * facecoeffs[gindex](i);2144}2145}2146}21472148fe2d -> ~BaseFiniteElement2D();2149}215021512152215321542155215621572158void CurvedElements :: CalcMultiPointSurfaceTransformation (ARRAY< Point<2> > * xi, int elnr,2159ARRAY< Point<3> > * x,2160ARRAY< Mat<3,2> > * dxdxi)2161{21622163int size = xi->Size();21642165if (mesh.coarsemesh)2166{2167const HPRefElement & hpref_el =2168(*mesh.hpelements) [ mesh[(SurfaceElementIndex) elnr].hp_elnr];21692170// xi umrechnen2171ARRAY< Point<2> > coarse_xi;2172ARRAY< Mat<2,2> > trans;2173ARRAY< Mat<3,2> > dxdxic;21742175coarse_xi.SetSize (size);2176coarse_xi = 0;2177trans.SetSize (size);2178dxdxic.SetSize (size);21792180for (int mp = 0; mp<size; mp++)2181{2182double lami[4];2183FlatVector vlami(4, lami);2184vlami = 0;2185mesh[(SurfaceElementIndex) elnr] . GetShapeNew ((*xi)[mp], vlami);21862187MatrixFixWidth<2> dlami(4);2188dlami = 0;2189mesh[(SurfaceElementIndex) elnr] . GetDShapeNew ((*xi)[mp], dlami);21902191trans[mp] = 0;2192for (int k = 0; k < 2; k++)2193for (int l = 0; l < 2; l++)2194{2195double sum = 0;2196for (int i = 0; i < 4; i++)2197sum += hpref_el.param[i][l] * dlami(i, k);2198trans[mp](l,k) = sum;2199}22002201for (int i = 0; i < 4; i++)2202{2203coarse_xi[mp](0) += hpref_el.param[i][0] * lami[i];2204coarse_xi[mp](1) += hpref_el.param[i][1] * lami[i];2205}2206}22072208mesh.coarsemesh->GetCurvedElements().CalcMultiPointSurfaceTransformation (&coarse_xi, hpref_el.coarse_elnr, x, &dxdxic);22092210for (int mp = 0; mp < size; mp++)2211{2212(*dxdxi)[mp] = dxdxic[mp] * trans[mp];2213}22142215return;2216}221722182219x->SetSize (size);2220dxdxi->SetSize (size);22212222const Element2d & elem = mesh[(SurfaceElementIndex) elnr];22232224BaseFiniteElement2D * fe2d;22252226// char locmem[max2(sizeof(FEQuad), sizeof(FETrig))];2227char locmemtrig[sizeof(FETrig)];2228char locmemquad[sizeof(FEQuad)];2229switch (elem.GetType())2230{2231case TRIG: fe2d = new (locmemtrig) FETrig (*this); break;2232case QUAD: fe2d = new (locmemquad) FEQuad (*this); break;2233}22342235fe2d->SetElementNumber (elnr+1);22362237for (int mp = 0; mp < size; mp++)2238{2239fe2d->SetReferencePoint ((*xi)[mp]);2240fe2d->CalcVertexShapes ();22412242(*x)[mp] = Point<3>(0,0,0);22432244for (int i = 0; i < 3; i++)2245for (int j = 0; j < 2; j++)2246(*dxdxi)[mp](i,j) = 0;22472248for (int v = 0; v < fe2d->GetNVertices(); v++)2249{2250(*x)[mp] = (*x)[mp] + fe2d->GetVertexShape(v) * mesh.Point(fe2d->GetVertexNr(v));2251for (int i = 0; i < 3; i++)2252for (int j = 0; j < 2; j++)2253(*dxdxi)[mp](i,j) += fe2d->GetVertexDShape(v)(j) * mesh.Point(fe2d->GetVertexNr(v)).X(i+1);2254}22552256if (IsHighOrder())2257{2258// fe2d->CalcEdgeShapes (x != NULL, dxdxi != NULL);2259fe2d->CalcEdgeShapes ();22602261int index = 0;2262for (int e = 0; e < fe2d->GetNEdges(); e++)2263{2264int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1];22652266for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++)2267{2268(*x)[mp] = (*x)[mp] + fe2d->GetEdgeShape(index) * edgecoeffs[gindex];2269for (int i = 0; i < 3; i++)2270for (int j = 0; j < 2; j++)2271(*dxdxi)[mp](i,j) += fe2d->GetEdgeDShape(index)(j) * edgecoeffs[gindex](i);2272}2273}227422752276if (mesh.GetDimension() == 3)2277{2278// fe2d->CalcFaceShapes (x != NULL, dxdxi != NULL);2279fe2d->CalcFaceShapes ();22802281int gindex = facecoeffsindex[fe2d->GetFaceNr()-1];2282for (int index = 0; index < fe2d->GetNFaceShapes(); index++, gindex++)2283{2284(*x)[mp] = (*x)[mp] + fe2d->GetFaceShape(index) * facecoeffs[gindex];2285for (int i = 0; i < 3; i++)2286for (int j = 0; j < 2; j++)2287(*dxdxi)[mp](i,j) += fe2d->GetFaceDShape(index)(j) * facecoeffs[gindex](i);2288}2289}2290}2291}22922293fe2d -> ~BaseFiniteElement2D();2294}22952296229722982299230023012302230323042305230623072308230923102311231223132314void CurvedElements :: CalcElementTransformation (Point<3> xi, int elnr,2315Point<3> * x, Mat<3,3> * dxdxi)2316{23172318if (mesh.coarsemesh)2319{2320const HPRefElement & hpref_el =2321(*mesh.hpelements) [ mesh[(ElementIndex) elnr].hp_elnr];232223232324/*2325*testout << " Curved Element " << elnr << endl;2326*testout << " hpref_el.coarse_elnr " << hpref_el.coarse_elnr << endl;2327*testout << " hpref_el.param = " << endl;2328for(int j=0;j< hpref_el.np; j++)2329{2330for(int k=0;k<3;k++)2331*testout << hpref_el.param[j][k] << "\t";2332*testout << endl;2333}2334*/23352336double lami[8];2337FlatVector vlami(8, lami);2338vlami = 0;2339mesh[(ElementIndex) elnr] . GetShapeNew (xi, vlami);23402341Point<3> coarse_xi(0,0,0);2342for (int i = 0; i < hpref_el.np; i++)2343for (int l = 0; l < 3; l++)2344coarse_xi(l) += hpref_el.param[i][l] * lami[i];23452346Mat<3,3> trans, dxdxic;2347if (dxdxi)2348{2349MatrixFixWidth<3> dlami(8);2350dlami = 0;2351mesh[(ElementIndex) elnr] . GetDShapeNew (xi, dlami);23522353trans = 0;2354for (int k = 0; k < 3; k++)2355for (int l = 0; l < 3; l++)2356{2357double sum = 0;2358for (int i = 0; i < hpref_el.np; i++)2359sum += hpref_el.param[i][l] * dlami(i, k);2360trans(l,k) = sum;2361}2362}2363/*2364*testout << " x " << x << endl;2365// << "\t" << x.X(2) << "\t" << x.X(3) << endl;2366*testout << " Element Trafo " << coarse_xi(0) << " \t " << coarse_xi(1) << " \t " << coarse_xi(2) << endl;2367*/2368236923702371mesh.coarsemesh->GetCurvedElements().CalcElementTransformation (coarse_xi, hpref_el.coarse_elnr, x, &dxdxic);23722373if (dxdxi)2374*dxdxi = dxdxic * trans;2375return;2376}2377237823792380238123822383238423852386Element elem = mesh[(ElementIndex) elnr];2387BaseFiniteElement3D * fe3d;23882389// char locmem[max2(sizeof(FETet), sizeof(FEPrism))];2390char locmemtet[sizeof(FETet)];2391char locmemprism[sizeof(FEPrism)];2392char locmempyramid[sizeof(FEPyramid)];2393char locmemhex[sizeof(FEHex)];2394switch (elem.GetType())2395{2396case TET: fe3d = new (locmemtet) FETet (*this); break;2397case PRISM: fe3d = new (locmemprism) FEPrism (*this); break;2398case PYRAMID: fe3d = new (locmempyramid) FEPyramid (*this); break;2399case HEX: fe3d = new (locmemhex) FEHex (*this); break;2400}24012402// fe3d->SetElementNumber (elnr+1);2403fe3d->SetReferencePoint (xi);24042405fe3d->CalcVertexShapes ();2406// fe3d->CalcVertexShapes (x != NULL, dxdxi != NULL);240724082409if (x)2410{2411(*x) = Point<3>(0,0,0);2412for (int v = 0; v < fe3d->GetNVertices(); v++)2413(*x) += fe3d->GetVertexShape(v) * Vec<3> (mesh.Point(elem[v]));2414}24152416if (dxdxi)2417{2418for (int i = 0; i < 3; i++)2419for (int j = 0; j < 3; j++)2420(*dxdxi)(i,j) = 0;24212422for (int v = 0; v < fe3d->GetNVertices(); v++)2423for (int i = 0; i < 3; i++)2424for (int j = 0; j < 3; j++)2425(*dxdxi)(i,j) += fe3d->GetVertexDShape(v)(j) * mesh.Point(elem[v]).X(i+1);2426}24272428if (IsHighOrder())2429{2430fe3d->SetElementNumber (elnr+1);2431// fe3d->CalcEdgeShapes (x != NULL, dxdxi != NULL);2432fe3d->CalcEdgeShapes ();243324342435if (x)2436{2437int index = 0;2438for (int e = 0; e < fe3d->GetNEdges(); e++)2439{2440int gindex = edgecoeffsindex[fe3d->GetEdgeNr(e)-1];2441for (int k = 2; k <= fe3d->GetEdgeOrder(e); k++, index++, gindex++)2442(*x) += fe3d->GetEdgeShape(index) * edgecoeffs[gindex];2443}2444}24452446if (dxdxi)2447{2448int index = 0;2449for (int e = 0; e < fe3d->GetNEdges(); e++)2450{2451int gindex = edgecoeffsindex[fe3d->GetEdgeNr(e)-1];2452for (int k = 2; k <= fe3d->GetEdgeOrder(e); k++, index++, gindex++)2453for (int i = 0; i < 3; i++)2454for (int j = 0; j < 3; j++)2455(*dxdxi)(i,j) += fe3d->GetEdgeDShape(index)(j) * edgecoeffs[gindex](i);2456}2457}245824592460// cout << "switched off face mapping" << endl;2461if (mesh.GetDimension() == 3) // JS2462{2463fe3d->CalcFaceShapes ();2464// fe3d->CalcFaceShapes (x != NULL, dxdxi != NULL);24652466if (x)2467{2468int index = 0;2469for (int f = 0; f < fe3d->GetNFaces(); f++)2470{2471int gindex = facecoeffsindex[fe3d->GetFaceNr(f)-1];2472for (int k = 0; k < fe3d->GetNFaceShapes(f); k++, index++, gindex++)2473(*x) += fe3d->GetFaceShape(index) * facecoeffs[gindex];2474}2475}24762477if (dxdxi)2478{2479int index = 0;2480for (int f = 0; f < fe3d->GetNFaces(); f++)2481{2482int gindex = facecoeffsindex[fe3d->GetFaceNr(f)-1];2483for (int k = 0; k < fe3d->GetNFaceShapes(f); k++, index++, gindex++)2484for (int i = 0; i < 3; i++)2485for (int j = 0; j < 3; j++)2486(*dxdxi)(i,j) += fe3d->GetFaceDShape(index)(j) * facecoeffs[gindex](i);2487}2488}2489}2490}24912492fe3d -> ~BaseFiniteElement3D();2493}2494249524962497249824992500250125022503#ifdef ROBERT25042505void CurvedElements :: CalcMultiPointElementTransformation (ARRAY< Point<3> > * xi, int elnr,2506ARRAY< Point<3> > * x,2507ARRAY< Mat<3,3> > * dxdxi)2508{2509int size = (*xi).Size();2510x->SetSize (size);25112512if (dxdxi) dxdxi->SetSize (size);25132514if (mesh.coarsemesh)2515{2516const HPRefElement & hpref_el =2517(*mesh.hpelements) [ mesh[(ElementIndex) elnr].hp_elnr];25182519ARRAY< Mat<3,3> > trans, dxdxic;2520if (dxdxi)2521{2522trans.SetSize (size);2523dxdxic.SetSize (size);2524}25252526ARRAY<Point<3> > coarse_xi(size);25272528double lami[8];2529FlatVector vlami(8, lami);2530const Element & el = mesh[(ElementIndex) elnr];2531int el_np = el.GetNP();25322533for (int mp = 0; mp < size; mp++)2534{2535el.GetShapeNew ((*xi)[mp], vlami);25362537Point<3> pc(0,0,0);2538for (int i = 0; i < el_np; i++)2539for (int l = 0; l < 3; l++)2540pc(l) += hpref_el.param[i][l] * lami[i];25412542coarse_xi[mp] = pc;25432544if (dxdxi)2545{2546MatrixFixWidth<3> dlami(8);2547dlami = 0;2548mesh[(ElementIndex) elnr] . GetDShapeNew ((*xi)[mp], dlami);25492550trans[mp] = 0;2551for (int k = 0; k < 3; k++)2552for (int l = 0; l < 3; l++)2553{2554double sum = 0;2555for (int i = 0; i < 8; i++)2556sum += hpref_el.param[i][l] * dlami(i, k);2557trans[mp](l,k) = sum;2558}2559}2560}25612562if (dxdxi)2563mesh.coarsemesh->GetCurvedElements().CalcMultiPointElementTransformation (&coarse_xi, hpref_el.coarse_elnr, x, &dxdxic);2564else2565mesh.coarsemesh->GetCurvedElements().CalcMultiPointElementTransformation (&coarse_xi, hpref_el.coarse_elnr, x, 0);25662567if (dxdxi)2568for (int mp = 0; mp < size; mp++)2569(*dxdxi)[mp] = dxdxic[mp] * trans[mp];25702571return;2572}2573257425752576257725782579258025812582Element elem = mesh[(ElementIndex) elnr];2583BaseFiniteElement3D * fe3d;25842585// char locmem[max2(sizeof(FETet), sizeof(FEPrism))];2586char locmemtet[sizeof(FETet)];2587char locmemprism[sizeof(FEPrism)];2588char locmempyramid[sizeof(FEPyramid)];2589char locmemhex[sizeof(FEHex)];2590switch (elem.GetType())2591{2592case TET: fe3d = new (locmemtet) FETet (*this); break;2593case PRISM: fe3d = new (locmemprism) FEPrism (*this); break;2594case PYRAMID: fe3d = new (locmempyramid) FEPyramid (*this); break;2595case HEX: fe3d = new (locmemhex) FEHex (*this); break;2596}25972598fe3d->SetElementNumber (elnr+1);259926002601for (int mp = 0; mp < size; mp++)2602{2603fe3d->SetReferencePoint ((*xi)[mp]);26042605fe3d->CalcVertexShapes ();2606// fe3d->CalcVertexShapes (x != NULL, dxdxi != NULL);26072608(*x)[mp] = Point<3>(0,0,0);2609if (dxdxi)2610for (int i = 0; i < 3; i++)2611for (int j = 0; j < 3; j++)2612(*dxdxi)[mp](i,j) = 0;26132614for (int v = 0; v < fe3d->GetNVertices(); v++)2615{2616(*x)[mp] += fe3d->GetVertexShape(v) * Vec<3> (mesh.Point(fe3d->GetVertexNr(v)));2617if (dxdxi)2618for (int i = 0; i < 3; i++)2619for (int j = 0; j < 3; j++)2620(*dxdxi)[mp](i,j) += fe3d->GetVertexDShape(v)(j) * mesh.Point(fe3d->GetVertexNr(v)).X(i+1);2621}262226232624if (IsHighOrder())2625{2626// fe3d->CalcEdgeShapes (x != NULL, dxdxi != NULL);2627fe3d->CalcEdgeShapes ();26282629int index = 0;2630for (int e = 0; e < fe3d->GetNEdges(); e++)2631{2632int gindex = edgecoeffsindex[fe3d->GetEdgeNr(e)-1];2633for (int k = 2; k <= fe3d->GetEdgeOrder(e); k++, index++, gindex++)2634{2635(*x)[mp] += fe3d->GetEdgeShape(index) * edgecoeffs[gindex];2636if (dxdxi)2637for (int i = 0; i < 3; i++)2638for (int j = 0; j < 3; j++)2639(*dxdxi)[mp](i,j) += fe3d->GetEdgeDShape(index)(j) * edgecoeffs[gindex](i);2640}2641}26422643if (mesh.GetDimension() == 3)2644{2645fe3d->CalcFaceShapes ();2646// fe3d->CalcFaceShapes (x != NULL, dxdxi != NULL);26472648int index = 0;2649for (int f = 0; f < fe3d->GetNFaces(); f++)2650{2651int gindex = facecoeffsindex[fe3d->GetFaceNr(f)-1];2652for (int k = 0; k < fe3d->GetNFaceShapes(f); k++, index++, gindex++)2653{2654(*x)[mp] += fe3d->GetFaceShape(index) * facecoeffs[gindex];2655if (dxdxi)2656for (int i = 0; i < 3; i++)2657for (int j = 0; j < 3; j++)2658(*dxdxi)[mp](i,j) += fe3d->GetFaceDShape(index)(j) * facecoeffs[gindex](i);2659}2660}2661}2662}2663}26642665fe3d -> ~BaseFiniteElement3D();2666}26672668#endif2669267026712672267326742675void CurvedElements :: CalcMultiPointElementTransformation (ARRAY< Point<3> > * xi, int elnr,2676ARRAY< Point<3> > * x,2677ARRAY< Mat<3,3> > * dxdxi)2678{2679int size = (*xi).Size();2680x->SetSize (size);26812682if (dxdxi) dxdxi->SetSize (size);26832684if (mesh.coarsemesh)2685{2686const HPRefElement & hpref_el =2687(*mesh.hpelements) [ mesh[(ElementIndex) elnr].hp_elnr];26882689ARRAY< Mat<3,3> > trans, dxdxic;2690if (dxdxi)2691{2692trans.SetSize (size);2693dxdxic.SetSize (size);2694}26952696ARRAY<Point<3> > coarse_xi(size);26972698double lami[8];2699FlatVector vlami(8, lami);2700const Element & el = mesh[(ElementIndex) elnr];2701int el_np = el.GetNP();27022703for (int mp = 0; mp < size; mp++)2704{2705el.GetShapeNew ((*xi)[mp], vlami);27062707Point<3> pc(0,0,0);2708for (int i = 0; i < el_np; i++)2709for (int l = 0; l < 3; l++)2710pc(l) += hpref_el.param[i][l] * lami[i];27112712coarse_xi[mp] = pc;27132714if (dxdxi)2715{2716MatrixFixWidth<3> dlami(8);2717dlami = 0;2718mesh[(ElementIndex) elnr] . GetDShapeNew ((*xi)[mp], dlami);27192720trans[mp] = 0;2721for (int k = 0; k < 3; k++)2722for (int l = 0; l < 3; l++)2723{2724double sum = 0;2725for (int i = 0; i < 8; i++)2726sum += hpref_el.param[i][l] * dlami(i, k);2727trans[mp](l,k) = sum;2728}2729}2730}27312732if (dxdxi)2733mesh.coarsemesh->GetCurvedElements().CalcMultiPointElementTransformation (&coarse_xi, hpref_el.coarse_elnr, x, &dxdxic);2734else2735mesh.coarsemesh->GetCurvedElements().CalcMultiPointElementTransformation (&coarse_xi, hpref_el.coarse_elnr, x, 0);27362737if (dxdxi)2738for (int mp = 0; mp < size; mp++)2739(*dxdxi)[mp] = dxdxic[mp] * trans[mp];27402741return;2742}2743274427452746274727482749275027512752Element elem = mesh[(ElementIndex) elnr];2753BaseFiniteElement3D * fe3d;27542755// char locmem[max2(sizeof(FETet), sizeof(FEPrism))];2756char locmemtet[sizeof(FETet)];2757char locmemprism[sizeof(FEPrism)];2758char locmempyramid[sizeof(FEPyramid)];2759char locmemhex[sizeof(FEHex)];2760switch (elem.GetType())2761{2762case TET: fe3d = new (locmemtet) FETet (*this); break;2763case PRISM: fe3d = new (locmemprism) FEPrism (*this); break;2764case PYRAMID: fe3d = new (locmempyramid) FEPyramid (*this); break;2765case HEX: fe3d = new (locmemhex) FEHex (*this); break;2766}27672768fe3d->SetElementNumber (elnr+1);27692770if (dxdxi)2771for (int mp = 0; mp < size; mp++)2772(*dxdxi)[mp] = 0.0;27732774Vec<3> vertices[8];2775ArrayMem<Vec<3>, 100> loc_edgecoefs(0);2776ArrayMem<Vec<3>, 100> loc_facecoefs(0);27772778for (int v = 0; v < fe3d->GetNVertices(); v++)2779vertices[v] = Vec<3> (mesh.Point(fe3d->GetVertexNr(v)));27802781if (IsHighOrder())2782{2783for (int e = 0; e < fe3d->GetNEdges(); e++)2784{2785int gindex = edgecoeffsindex[fe3d->GetEdgeNr(e)-1];2786for (int k = 2; k <= fe3d->GetEdgeOrder(e); k++, gindex++)2787loc_edgecoefs.Append (edgecoeffs[gindex]);2788}27892790if (mesh.GetDimension() == 3)2791for (int f = 0; f < fe3d->GetNFaces(); f++)2792{2793int gindex = facecoeffsindex[fe3d->GetFaceNr(f)-1];2794for (int k = 0; k < fe3d->GetNFaceShapes(f); k++, gindex++)2795loc_facecoefs.Append (facecoeffs[gindex]);2796}2797}2798279928002801if (!dxdxi)28022803for (int mp = 0; mp < size; mp++)2804{2805fe3d->SetReferencePoint ((*xi)[mp]);2806fe3d->CalcVertexShapesOnly ();28072808if (IsHighOrder())2809{2810fe3d->CalcEdgeShapesOnly ();2811if (mesh.GetDimension() == 3)2812fe3d->CalcFaceShapes ();2813}28142815Point<3> hp (0,0,0);2816for (int v = 0; v < fe3d->GetNVertices(); v++)2817hp += fe3d->GetVertexShape(v) * vertices[v];2818for (int index = 0; index < loc_edgecoefs.Size(); index++)2819hp += fe3d->GetEdgeShape(index) * loc_edgecoefs[index];2820for (int index = 0; index < loc_facecoefs.Size(); index++)2821hp += fe3d->GetFaceShape(index) * loc_facecoefs[index]; // edgecoeffs[gindex];2822(*x)[mp] = hp;2823}28242825else28262827for (int mp = 0; mp < size; mp++)2828{2829fe3d->SetReferencePoint ((*xi)[mp]);2830fe3d->CalcVertexShapes ();28312832if (IsHighOrder())2833{2834fe3d->CalcEdgeShapes ();2835if (mesh.GetDimension() == 3)2836fe3d->CalcFaceShapes ();2837}28382839Point<3> hp (0,0,0);2840for (int v = 0; v < fe3d->GetNVertices(); v++)2841hp += fe3d->GetVertexShape(v) * vertices[v];2842for (int index = 0; index < loc_edgecoefs.Size(); index++)2843hp += fe3d->GetEdgeShape(index) * loc_edgecoefs[index];2844for (int index = 0; index < loc_facecoefs.Size(); index++)2845hp += fe3d->GetFaceShape(index) * loc_facecoefs[index]; // edgecoeffs[gindex];2846(*x)[mp] = hp;284728482849for (int v = 0; v < fe3d->GetNVertices(); v++)2850for (int i = 0; i < 3; i++)2851for (int j = 0; j < 3; j++)2852(*dxdxi)[mp](i,j) += fe3d->GetVertexDShape(v)(j) * vertices[v](i);28532854for (int index = 0; index < loc_edgecoefs.Size(); index++)2855for (int i = 0; i < 3; i++)2856for (int j = 0; j < 3; j++)2857(*dxdxi)[mp](i,j) += fe3d->GetEdgeDShape(index)(j) * loc_edgecoefs[index](i);28582859for (int index = 0; index < loc_facecoefs.Size(); index++)2860for (int i = 0; i < 3; i++)2861for (int j = 0; j < 3; j++)2862(*dxdxi)[mp](i,j) += fe3d->GetFaceDShape(index)(j) * loc_facecoefs[index](i);2863}28642865fe3d -> ~BaseFiniteElement3D();2866}2867286828692870/*2871class Init2872{2873PolynomialBasis b;2874public:2875Init ();2876};28772878Init :: Init()2879{2880ofstream edge("edge.out");2881b.SetOrder(10);2882for (double x = 0; x <= 1; x += 0.01)2883{2884b.CalcFScaled(x, 1);2885edge << x;2886for (int j = 2; j <= 5; j++)2887edge << " " << b.GetF(j);2888edge << endl;2889}2890}28912892Init in;2893*/28942895} // namespace netgen289628972898#endif289929002901