IntPt *getGQHPts(int order) { if(order<2)return GQH[order]; if(order == 2)return GQH[3]; if(order == 3)return GQH[3]; int n = (order+3)/2; int index = n-2 + 4; if(!GQH[index]) { double *pt,*wt; // printf("o = %d n = %d i = %d\n",order,n*n*n,index); gmshGaussLegendre1D(n,&pt,&wt); GQH[index] = new IntPt[n*n*n]; int l = 0; for(int i=0; i < n; i++) { for(int j=0; j < n; j++) { for(int k=0; k < n; k++) { GQH[index][l].pt[0] = pt[i]; GQH[index][l].pt[1] = pt[j]; GQH[index][l].pt[2] = pt[k]; GQH[index][l++].weight = wt[i]*wt[j]*wt[k]; // printf ("%f %f %f %f\n",pt[i],pt[j],pt[k],wt[i]*wt[j]*wt[k]); } } } } return GQH[index]; }
IntPt *getGQPriPts(int order) { int nLin = (order+3)/2; int nTri = getNGQTPts(order); int n = nLin*nTri; int index = order; if (order >= (int)(sizeof(GQP) / sizeof(IntPt*))) Msg::Fatal("Increase size of GQP in gauss quadrature prism"); if(!GQP[index]){ double *linPt,*linWt; IntPt *triPts = getGQTPts(order); gmshGaussLegendre1D(nLin,&linPt,&linWt); GQP[index] = new IntPt[n]; int l = 0; for(int i=0; i < nTri; i++) { for(int j=0; j < nLin; j++) { GQP[index][l].pt[0] = triPts[i].pt[0]; GQP[index][l].pt[1] = triPts[i].pt[1]; GQP[index][l].pt[2] = linPt[j]; GQP[index][l++].weight = triPts[i].weight*linWt[j]; } } } return GQP[index]; }
IntPt *getGQQPts(int order) { if(order<2)return GQQ[order]; if(order==2)return GQQ[3]; if(order==3)return GQQ[3]; int n = (order+3)/2; int index = n-2 + 7; if(!GQQ[index]) { double *pt,*wt; gmshGaussLegendre1D(n,&pt,&wt); GQQ[index] = new IntPt[n*n]; int k = 0; for(int i=0; i < n; i++) { for(int j=0; j < n; j++) { GQQ[index][k].pt[0] = pt[i]; GQQ[index][k].pt[1] = pt[j]; GQQ[index][k].pt[2] = 0.0; GQQ[index][k++].weight = wt[i]*wt[j]; // printf ("%f %f %f\n",pt[i],pt[j],wt[i]*wt[j]); } } } return GQQ[index]; }
int GaussLegendreTri(int n1,int n2,IntPt *pts) { /* get degenerate n1Xn2 Gauss-Legendre scheme to integrate over a tri */ int i,j,index=0; double *pt1,*pt2,*wt1,*wt2,dJ; //const double two = 2.0000000000000000; gmshGaussLegendre1D(n1,&pt1,&wt1); gmshGaussLegendre1D(n2,&pt2,&wt2); for(i=0; i < n1; i++) { for(j=0; j < n2; j++) { quadToTri(pt1[i],pt2[j],&(pts[index].pt[0]),&(pts[index].pt[1]),&dJ); pts[index].pt[2] = 0; pts[index++].weight = dJ*wt1[i]*wt2[j]; } } return index; }
int GaussLegendreTet(int n1, int n2, int n3, IntPt *pts) { /* get degenerate n1Xn2Xn3 Gauss-Legendre scheme to integrate over a tet */ int i,j,k,index=0; double *pt1,*pt2,*pt3,*wt1,*wt2,*wt3,dJ; gmshGaussLegendre1D(n1,&pt1,&wt1); gmshGaussLegendre1D(n2,&pt2,&wt2); gmshGaussLegendre1D(n3,&pt3,&wt3); for(i=0; i < n1; i++) { for(j=0; j < n2; j++) { for(k=0; k < n3; k++) { brickToTet(pt1[i],pt2[j],pt3[k],&(pts[index].pt[0]), &(pts[index].pt[1]),&(pts[index].pt[2]),&dJ); pts[index++].weight = dJ*wt1[i]*wt2[j]*wt3[k]; } } } return index; }
IntPt *getGQPyrPts(int order) { int index = order; if(index >= (int)(sizeof(GQPyr) / sizeof(IntPt*))){ Msg::Error("Increase size of GQPyr in gauss quadrature pyr"); index = 0; } if(!GQPyr[index]) { int nbPtUV = order/2 + 1; int nbPtW = order/2 + 1; int nbPtUV2 = nbPtUV * nbPtUV; double *linPt,*linWt; gmshGaussLegendre1D(nbPtUV,&linPt,&linWt); double *GJ20Pt, *GJ20Wt; getGaussJacobiQuadrature(2, 0, nbPtW, &GJ20Pt, &GJ20Wt); GQPyr[index] = new IntPt[getNGQPyrPts(order)]; int l = 0; for (int i = 0; i < getNGQPyrPts(order); i++) { // compose an integration rule for (1-w)^2 f(u,v,w) on the standard hexahedron int iW = i / (nbPtUV2); int iU = (i - iW*nbPtUV2)/nbPtUV; int iV = (i - iW*nbPtUV2 - iU*nbPtUV); // std::cout << "Points " << iU << " " << iV << " " << iW << std::endl; int wt = linWt[iU]*linWt[iV]*GJ20Wt[iW]; double up = linPt[iU]; double vp = linPt[iV]; double wp = GJ20Pt[iW]; // now incorporate the Duffy transformation from pyramid to hexahedron GQPyr[index][l].pt[0] = 0.5*(1-wp)*up; GQPyr[index][l].pt[1] = 0.5*(1-wp)*vp; GQPyr[index][l].pt[2] = 0.5*(1+wp); wt *= 0.125; GQPyr[index][l++].weight = wt; } } return GQPyr[index]; }
double GEdge::length(const double &u0, const double &u1, const int nbQuadPoints) { double *t = 0, *w = 0; gmshGaussLegendre1D(nbQuadPoints, &t, &w); double L = 0.0; const double rapJ = (u1 - u0) * .5; for (int i = 0; i < nbQuadPoints; i++){ const double ui = u0 * 0.5 * (1. - t[i]) + u1 * 0.5 * (1. + t[i]); SVector3 der = firstDer(ui); const double d = norm(der); L += d * w[i] * rapJ; } return L; }
IntPt *getGQLPts(int order) { // Number of Gauss Point: // (order + 1) / 2 *ROUNDED UP* int n = (order + 1) / (double)2 + 0.5; int index = n; if(index >= (int)(sizeof(GQL) / sizeof(IntPt*))){ Msg::Error("Increase size of GQL in gauss quadrature line"); index = 0; } if(!GQL[index]) { double *pt,*wt; gmshGaussLegendre1D(n,&pt,&wt); GQL[index] = new IntPt[n]; for(int i=0; i < n; i++) { GQL[index][i].pt[0] = pt[i]; GQL[index][i].pt[1] = 0.0; GQL[index][i].pt[2] = 0.0; GQL[index][i].weight = wt[i]; } } return GQL[index]; }