From 75c0ad6ef735f8b54b23f51b03808705b68d3f53 Mon Sep 17 00:00:00 2001 From: ssherw Date: Tue, 7 Mar 2017 15:11:42 +0000 Subject: [PATCH 01/27] Added Modified_C basis that can be used with pyramids and also works with a modified and orothoogonal expansion. Currently orthogonal expansion produced diagonal but with non-unit values --- library/Demos/StdRegions/StdProject3D.cpp | 17 +- library/LibUtilities/BasicUtils/ShapeType.hpp | 15 +- library/LibUtilities/Foundations/Basis.cpp | 161 +++++++++++++- library/LibUtilities/Foundations/Basis.h | 5 +- library/LibUtilities/Foundations/BasisType.h | 2 + .../LibUtilities/Foundations/Foundations.hpp | 2 + library/StdRegions/StdPyrExp.cpp | 200 ++++++++++++++++-- 7 files changed, 358 insertions(+), 44 deletions(-) diff --git a/library/Demos/StdRegions/StdProject3D.cpp b/library/Demos/StdRegions/StdProject3D.cpp index 2cc73797e..9d3a58f64 100644 --- a/library/Demos/StdRegions/StdProject3D.cpp +++ b/library/Demos/StdRegions/StdProject3D.cpp @@ -66,6 +66,9 @@ int main(int argc, char *argv[]){ fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); fprintf(stderr,"\t Modified_C = 6\n"); + fprintf(stderr,"\t Ortho_C = 7\n"); + fprintf(stderr,"\t Modified_C = 8\n"); + fprintf(stderr,"\t Fourier = 7\n"); fprintf(stderr,"\t Lagrange = 8\n"); fprintf(stderr,"\t Gauss Lagrange = 9\n"); @@ -162,23 +165,23 @@ int main(int argc, char *argv[]){ } break; case LibUtilities::ePyramid: - if((btype1 == eOrtho_B) || (btype1 == eOrtho_C) - || (btype1 == eModified_B) || (btype1 == eModified_C)) + if((btype1 == eOrtho_B) || (btype1 == eOrtho_C) || (btype1 == eOrthoPyr_C) + || (btype1 == eModified_B) || (btype1 == eModified_C) || (btype1 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, "Basis 1 cannot be of type Ortho_B, " "Ortho_C, Modified_B or Modified_C"); } - if((btype2 == eOrtho_B) || (btype2 == eOrtho_C) - || (btype2 == eModified_B) || (btype2 == eModified_C)) + if((btype2 == eOrtho_B) || (btype2 == eOrtho_C) || (btype1 == eOrthoPyr_C) + || (btype2 == eModified_B) || (btype2 == eModified_C) || (btype1 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, "Basis 2 cannot be of type Ortho_B, " "Ortho_C, Modified_B or Modified_C"); } - if((btype3 == eOrtho_A) || (btype3 == eOrtho_B) - || (btype3 == eModified_A) || (btype3 == eModified_B)) + if((btype3 == eOrtho_A) || (btype3 == eOrtho_B) || (btype3 == eOrtho_C) + || (btype3 == eModified_A) || (btype3 == eModified_B) || (btype3 == eModified_C)) { NEKERROR(ErrorUtil::efatal, "Basis 3 cannot be of type Ortho_A, " - "Ortho_B, Modified_A or Modified_B"); + "Ortho_B, Ortho_C, Modified_A, Modified_B or Modified_C"); } break; case LibUtilities::ePrism: diff --git a/library/LibUtilities/BasicUtils/ShapeType.hpp b/library/LibUtilities/BasicUtils/ShapeType.hpp index e62add3bb..b7ab7169f 100644 --- a/library/LibUtilities/BasicUtils/ShapeType.hpp +++ b/library/LibUtilities/BasicUtils/ShapeType.hpp @@ -240,26 +240,19 @@ namespace Nektar "than order in 'c' direction."); // Count number of coefficients explicitly. - const int Pi = Na - 2, Qi = Nb - 2, Ri = Nc - 2; - int nCoeff = - 5 + // vertices - Pi * 2 + Qi * 2 + Ri * 4 + // base edges - Pi * Qi + // base quad - Pi * (2*Ri - Pi - 1) + // p-r triangles; - Qi * (2*Ri - Qi - 1); // q-r triangles; + int nCoeff = 0; // Count number of interior tet modes - for (int a = 0; a < Pi - 1; ++a) + for (int a = 0; a < Na; ++a) { - for (int b = 0; b < Qi - a - 1; ++b) + for (int b = 0; b < Nb; ++b) { - for (int c = 0; c < Ri - a - b -1; ++c) + for (int c = 0; c < Nc - std::max(a,b); ++c) { ++nCoeff; } } } - return nCoeff; } diff --git a/library/LibUtilities/Foundations/Basis.cpp b/library/LibUtilities/Foundations/Basis.cpp index 5a7e73518..163e742a2 100644 --- a/library/LibUtilities/Foundations/Basis.cpp +++ b/library/LibUtilities/Foundations/Basis.cpp @@ -328,6 +328,47 @@ namespace Nektar } break; + /** \brief Orthogonal basis C for Pyramid expansion (which is richer than tets) + + \f$\tilde \psi_{pqr}^c = \left ( {1 - \eta_3} \over 2 \right)^{p+q} P_r^{2p+2q+2, 0}(\eta_3)\f$ \\ + + */ + + // This is tilde psi_pqr in Spen's book, page 105 + // The 4-dimensional array is laid out in memory such that + // 1) Eta_z values are the changing the fastest, then r, q, and finally p. + // 2) r index increases by the stride of numPoints. + case eOrthoPyr_C: + { + int P = numModes - 1, Q = numModes - 1, R = numModes - 1; + NekDouble *mode = m_bdata.data(); + + for( int p = 0; p <= P; ++p ) + { + for( int q = 0; q <= Q; ++q ) + { + for( int r = 0; r <= R - max(p,q); ++r, mode += numPoints ) + { + Polylib::jacobfd(numPoints, z.data(), mode, NULL, r, 2*p + 2*q + 2.0, 0.0); + for( int k = 0; k < numPoints; ++k ) + { + // Note factor of 0.5 is part of normalisation + mode[k] *= pow(0.5*(1.0 - z[k]), p+q); + + // finish normalisation + mode[k] *= sqrt(r+p+q+1.5); + } + } + } + } + + // Define derivative basis + Blas::Dgemm('n','n',numPoints,numModes*(numModes+1)* + (numModes+2)/6,numPoints,1.0, D, numPoints, + m_bdata.data(),numPoints,0.0,m_dbdata.data(),numPoints); + } + break; + case eModified_A: // Note the following packing deviates from the @@ -452,13 +493,13 @@ namespace Nektar case eModified_C: { // Note the following packing deviates from the - // definition in the Book by Karniadakis in two - // ways. 1) We put the vertex degrees of freedom - // at the lower index range to follow a more - // hierarchic structure. 2) We do not duplicate - // the singular vertex definition (or the - // duplicated face information in the book ) so - // that only a tetrahedral number + // definition in the Book by Karniadakis & + // Sherwin in two ways. 1) We put the vertex + // degrees of freedom at the lower index range to + // follow a more hierarchic structure. 2) We do + // not duplicate the singular vertex definition + // (or the duplicated face information in the book + // ) so that only a tetrahedral number // (i.e. (modes)*(modes+1)*(modes+2)/6) of modes // are required consistent with the orthogonal // basis. @@ -505,6 +546,110 @@ namespace Nektar } break; + case eModifiedPyr_C: + { + // Note the following packing deviates from the + // definition in the Book by Karniadakis & + // Sherwin in two ways. 1) We put the vertex + // degrees of freedom at the lower index range to + // follow a more hierarchic structure. 2) We do + // not duplicate the singular vertex definition + // so that only a pyramidic number + // (i.e. (modes)*(modes+1)*(2*modes+1)/6) of modes + // are required consistent with the orthogonal + // basis. + + // In the current structure the r index runs + // fastest rollowed by q and than the p index so + // that the matrix has a more compact structure + + // Generate Modified_B basis; + BasisKey ModBKey(eModified_B,m_basisKey.GetNumModes(), + m_basisKey.GetPointsKey()); + BasisSharedPtr ModB = BasisManager()[ModBKey]; + + Array ModB_data = ModB->GetBdata(); + + // Copy Modified_B basis into first + // (numModes*(numModes+1)/2)*numPoints entires of + // bdata. + + + int N; + int B_offset = 0; + int offset = 0; + + // Vertex 0,3,4, edges 3,4,7, face 4 + N = numPoints*(numModes)*(numModes+1)/2; + Vmath::Vcopy(N, &ModB_data[0],1,&m_bdata[0],1); + offset += N; + + B_offset += numPoints*(numModes); + // Vertex 1 edges 5 + N = numPoints*(numModes-1); + Vmath::Vcopy(N, &ModB_data[0]+B_offset,1,&m_bdata[0]+offset,1); + offset += N; + + // Vertex 2 edges 1,6, face 2 + N = numPoints*(numModes-1)*(numModes)/2; + Vmath::Vcopy(N, &ModB_data[0]+B_offset,1,&m_bdata[0]+offset,1); + offset += N; + + B_offset += numPoints*(numModes-1); + + NekDouble *one_m_z_pow, *one_p_z; + NekDouble *mode; + + mode = m_bdata.data() + offset; + + for(p = 2; p < numModes; ++p) + { + // edges 0 2, faces 1 3 + N = numPoints*(numModes-p); + Vmath::Vcopy(N, &ModB_data[0]+B_offset,1,mode,1); + mode += N; + Vmath::Vcopy(N, &ModB_data[0]+B_offset,1,mode,1); + mode += N; + B_offset += N; + + one_m_z_pow = m_bdata.data(); + one_p_z = m_bdata.data()+numPoints; + + for(q = 2; q < numModes; ++q) + { + // face 0 + for(i = 0; i < numPoints; ++i) + { + mode[i] = pow(one_m_z_pow[i],p+q); // [(1-z)/2]^{p+q} + } + + one_m_z_pow = mode; + mode += numPoints; + + // interior + for(int r = 1; r < numModes-max(p,q); ++r, mode+=numPoints) + { + Polylib::jacobfd(numPoints,z.data(),mode,NULL,r-1,2*p+2*q-1,1.0); + + for(i = 0; i < numPoints; ++i) + { + mode[i] *= one_m_z_pow[i]*one_p_z[i]; + } + mode += numPoints; + } + } + + } + + // set up derivative of basis. + Blas::Dgemm('n','n',numPoints, + numModes*(numModes+1)*(2*numModes+1)/6, + numPoints,1.0,D,numPoints, + m_bdata.data(),numPoints,0.0, + m_dbdata.data(),numPoints); + } + break; + case eGLL_Lagrange: { mode = m_bdata.data(); @@ -523,7 +668,7 @@ namespace Nektar Blas::Dgemm('n', 'n', numPoints, numModes, numPoints, 1.0, D, numPoints, m_bdata.data(), numPoints, 0.0, m_dbdata.data(), numPoints); - + }//end scope break; case eGauss_Lagrange: diff --git a/library/LibUtilities/Foundations/Basis.h b/library/LibUtilities/Foundations/Basis.h index 5c73df2a7..5bb1568f2 100644 --- a/library/LibUtilities/Foundations/Basis.h +++ b/library/LibUtilities/Foundations/Basis.h @@ -102,7 +102,10 @@ namespace Nektar case eOrtho_C: value = m_nummodes*(m_nummodes+1)*(m_nummodes+2)/6; break; - + case eModifiedPyr_C: + case eOrthoPyr_C: + value = m_nummodes*(m_nummodes+1)*(2*m_nummodes+1)/6; + break; case eOrtho_A: case eModified_A: case eFourier: diff --git a/library/LibUtilities/Foundations/BasisType.h b/library/LibUtilities/Foundations/BasisType.h index 3e240ad7f..f24010b50 100644 --- a/library/LibUtilities/Foundations/BasisType.h +++ b/library/LibUtilities/Foundations/BasisType.h @@ -49,6 +49,8 @@ namespace Nektar eModified_A, //!< Principle Modified Functions \f$ \phi^a_p(z_i) \f$ eModified_B, //!< Principle Modified Functions \f$ \phi^b_{pq}(z_i) \f$ eModified_C, //!< Principle Modified Functions \f$ \phi^c_{pqr}(z_i) \f$ + eOrthoPyr_C, //!< Principle Orthogonal Functions \f$\widetilde{\psi}^c_{pqr}(z_i) for Pyramids\f$ + eModifiedPyr_C, //!< Principle Modified Functions \f$ \phi^c_{pqr}(z_i) for Pyramids\f$ eFourier, //!< Fourier Expansion \f$ \exp(i p\pi z_i)\f$ eGLL_Lagrange, //!< Lagrange for SEM basis \f$ h_p(z_i) \f$ eGauss_Lagrange, //!< Lagrange Polynomials using the Gauss points \f$ h_p(z_i) \f$ diff --git a/library/LibUtilities/Foundations/Foundations.hpp b/library/LibUtilities/Foundations/Foundations.hpp index ec1cd55df..80a54b4bc 100644 --- a/library/LibUtilities/Foundations/Foundations.hpp +++ b/library/LibUtilities/Foundations/Foundations.hpp @@ -53,6 +53,8 @@ namespace Nektar "Modified_A", "Modified_B", "Modified_C", + "OrthoPyr_C", + "ModifiedPyr_C", "Fourier", "GLL_Lagrange", "Gauss_Lagrange", diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index c71f02550..dcbb1a38e 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -61,17 +61,13 @@ namespace Nektar Bc.GetNumModes()), Ba, Bb, Bc) { - if (Ba.GetNumModes() > Bc.GetNumModes()) - { - ASSERTL0(false, "order in 'a' direction is higher " - "than order in 'c' direction"); - } - if (Bb.GetNumModes() > Bc.GetNumModes()) - { - ASSERTL0(false, "order in 'b' direction is higher " - "than order in 'c' direction"); - } + ASSERTL0(Ba.GetNumModes() <= Bc.GetNumModes(), "order in 'a' direction is higher " + "than order in 'c' direction"); + ASSERTL0(Bb.GetNumModes() <= Bc.GetNumModes(), "order in 'b' direction is higher " + "than order in 'c' direction"); + +#if 0 // Set up mode mapping which takes 0\leq i\leq N_coeffs -> (p,q,r) // of the 3D tensor product const int P = Ba.GetNumModes() - 1; @@ -79,6 +75,7 @@ namespace Nektar const int R = Bc.GetNumModes() - 1; int cnt = 0; + // Vertices m_map[Mode(0, 0, 0, 0)] = cnt++; m_map[Mode(1, 0, 0, 0)] = cnt++; @@ -218,6 +215,7 @@ namespace Nektar m_idxMap[p][q][r] = pair(it->second, rp); } } +#endif } StdPyrExp::StdPyrExp(const StdPyrExp &T) @@ -391,7 +389,14 @@ namespace Nektar const Array& inarray, Array& outarray) { - Array wsp; + int nquad1 = m_base[1]->GetNumPoints(); + int nquad2 = m_base[2]->GetNumPoints(); + int order0 = m_base[0]->GetNumModes(); + int order1 = m_base[1]->GetNumModes(); + + Array wsp(nquad2*order0*order1+ + nquad2*nquad1*order0); + v_BwdTrans_SumFacKernel(m_base[0]->GetBdata(), m_base[1]->GetBdata(), m_base[2]->GetBdata(), @@ -410,6 +415,7 @@ namespace Nektar bool doCheckCollDir1, bool doCheckCollDir2) { +#if 0 const int Qx = m_base[0]->GetNumPoints(); const int Qy = m_base[1]->GetNumPoints(); const int Qz = m_base[2]->GetNumPoints(); @@ -483,6 +489,80 @@ namespace Nektar } } } +#else + int nquad0 = m_base[0]->GetNumPoints(); + int nquad1 = m_base[1]->GetNumPoints(); + int nquad2 = m_base[2]->GetNumPoints(); + + int order0 = m_base[0]->GetNumModes(); + int order1 = m_base[1]->GetNumModes(); + int order2 = m_base[2]->GetNumModes(); + + Array tmp = wsp; + Array tmp1 = tmp + nquad2*order0*order1; + + int i, j, mode, mode1, cnt; + + // Perform summation over '2' direction + mode = mode1 = cnt = 0; + for(i = 0; i < order0; ++i) + { + for(j = 0; j < order1; ++j, ++cnt) + { + int ijmax = max(i,j); + Blas::Dgemv('N', nquad2, order2-ijmax, + 1.0, base2.get()+mode*nquad2, nquad2, + inarray.get()+mode1, 1, + 0.0, tmp.get()+cnt*nquad2, 1); + mode += order2-ijmax; + mode1 += order2-ijmax; + } + //increment mode in case order1!=order2 + for(j = order1; j < order2-i; ++j) + { + int ijmax = max(i,j); + mode += order2-ijmax; + } + } + + // fix for modified basis by adding split of top singular + // vertex mode - currently (1+c)/2 x (1-b)/2 x (1-a)/2 + // component is evaluated + if(m_base[0]->GetBasisType() == LibUtilities::eModified_A) + { + + // Not sure why we could not use basis as 1.0 + // top singular vertex - (1+c)/2 x (1+b)/2 x (1-a)/2 component + Blas::Daxpy(nquad2,inarray[1],base2.get()+nquad2,1, + &tmp[0]+nquad2,1); + + // top singular vertex - (1+c)/2 x (1-b)/2 x (1+a)/2 component + Blas::Daxpy(nquad2,inarray[1],base2.get()+nquad2,1, + &tmp[0]+order1*nquad2,1); + + // top singular vertex - (1+c)/2 x (1+b)/2 x (1+a)/2 component + Blas::Daxpy(nquad2,inarray[1],base2.get()+nquad2,1, + &tmp[0]+order1*nquad2+nquad2,1); +} + + // Perform summation over '1' direction + mode = 0; + for(i = 0; i < order0; ++i) + { + Blas::Dgemm('N', 'T', nquad1, nquad2, order1, + 1.0, base1.get(), nquad1, + tmp.get()+mode*nquad2, nquad2, + 0.0, tmp1.get()+i*nquad1*nquad2, nquad1); + mode += order1; + } + + // Perform summation over '0' direction + Blas::Dgemm('N', 'T', nquad0, nquad1*nquad2, order0, + 1.0, base0.get(), nquad0, + tmp1.get(), nquad1*nquad2, + 0.0, outarray.get(), nquad0); + +#endif } /** \brief Forward transform from physical quadrature space @@ -504,14 +584,20 @@ namespace Nektar v_IProductWRTBase(inarray,outarray); // get Mass matrix inverse - StdMatrixKey masskey(eInvMass,DetShapeType(),*this); + StdMatrixKey masskey(eMass,DetShapeType(),*this); DNekMatSharedPtr matsys = GetStdMatrix(masskey); + cout << *matsys << endl; + + // get Mass matrix inverse + StdMatrixKey imasskey(eInvMass,DetShapeType(),*this); + DNekMatSharedPtr imatsys = GetStdMatrix(imasskey); + // copy inarray in case inarray == outarray DNekVec in (m_ncoeffs, outarray); DNekVec out(m_ncoeffs, outarray, eWrapper); - out = (*matsys)*in; + out = (*imatsys)*in; } @@ -554,7 +640,14 @@ namespace Nektar Array& outarray, bool multiplybyweights) { - Array wsp; + + int nquad1 = m_base[1]->GetNumPoints(); + int nquad2 = m_base[2]->GetNumPoints(); + int order0 = m_base[0]->GetNumModes(); + int order1 = m_base[1]->GetNumModes(); + + Array wsp(nquad1*nquad2*order0 + + nquad2*order0*order1); if(multiplybyweights) { @@ -589,6 +682,7 @@ namespace Nektar bool doCheckCollDir1, bool doCheckCollDir2) { +#if 0 int i, j, k, s; int Qx = m_base[0]->GetNumPoints(); int Qy = m_base[1]->GetNumPoints(); @@ -665,6 +759,78 @@ namespace Nektar } } } +#else + int nquad0 = m_base[0]->GetNumPoints(); + int nquad1 = m_base[1]->GetNumPoints(); + int nquad2 = m_base[2]->GetNumPoints(); + + int order0 = m_base[0]->GetNumModes(); + int order1 = m_base[1]->GetNumModes(); + int order2 = m_base[2]->GetNumModes(); + + Array tmp1 = wsp; + Array tmp2 = wsp + nquad1*nquad2*order0; + + int i,j, mode,mode1, cnt; + + // Inner product with respect to the '0' direction + Blas::Dgemm('T', 'N', nquad1*nquad2, order0, nquad0, + 1.0, inarray.get(), nquad0, + base0.get(), nquad0, + 0.0, tmp1.get(), nquad1*nquad2); + + // Inner product with respect to the '1' direction + for(mode=i=0; i < order0; ++i) + { + Blas::Dgemm('T', 'N', nquad2, order1, nquad1, + 1.0, tmp1.get()+i*nquad1*nquad2, nquad1, + base1.get(), nquad1, + 0.0, tmp2.get()+mode*nquad2, nquad2); + mode += order1; + } + + + // Inner product with respect to the '2' direction + mode = mode1 = cnt = 0; + for(i = 0; i < order0; ++i) + { + for(j = 0; j < order1; ++j, ++cnt) + { + int ijmax = max(i,j); + + Blas::Dgemv('T', nquad2, order2-ijmax, + 1.0, base2.get()+mode*nquad2, nquad2, + tmp2.get()+cnt*nquad2, 1, + 0.0, outarray.get()+mode1, 1); + mode += order2-ijmax; + mode1 += order2-ijmax; + } + + //increment mode in case order1!=order2 + for(j = order1; j < order2; ++j) + { + int ijmax = max(i,j); + mode += order2-ijmax; + } + } + + // fix for modified basis for top singular vertex component + // Already have evaluated (1+c)/2 (1-b)/2 (1-a)/2 + if(m_base[0]->GetBasisType() == LibUtilities::eModified_A) + { + // add in (1+c)/2 (1+b)/2 (1-a)/2 component + outarray[1] += Blas::Ddot(nquad2,base2.get()+nquad2,1, + &tmp2[nquad2],1); + + // add in (1+c)/2 (1-b)/2 (1+a)/2 component + outarray[1] += Blas::Ddot(nquad2,base2.get()+nquad2,1, + &tmp2[nquad2*order1],1); + + // add in (1+c)/2 (1+b)/2 (1+a)/2 component + outarray[1] += Blas::Ddot(nquad2,base2.get()+nquad2,1, + &tmp2[nquad2*order1+nquad2],1); + } +#endif } void StdPyrExp::v_IProductWRTDerivBase( @@ -940,7 +1106,7 @@ namespace Nektar ASSERTL1(GetBasisType(1) == LibUtilities::eModified_A || GetBasisType(1) == LibUtilities::eGLL_Lagrange, "BasisType is not a boundary interior form"); - ASSERTL1(GetBasisType(2) == LibUtilities::eModified_C || + ASSERTL1(GetBasisType(2) == LibUtilities::eModifiedPyr_C || GetBasisType(2) == LibUtilities::eGLL_Lagrange, "BasisType is not a boundary interior form"); @@ -1119,9 +1285,9 @@ namespace Nektar "Method only implemented if BasisType is identical" "in x and y directions"); ASSERTL1(GetEdgeBasisType(0) == LibUtilities::eModified_A && - GetEdgeBasisType(4) == LibUtilities::eModified_C, + GetEdgeBasisType(4) == LibUtilities::eModifiedPyr_C, "Method only implemented for Modified_A BasisType" - "(x and y direction) and Modified_C BasisType (z " + "(x and y direction) and ModifiedPyr_C BasisType (z " "direction)"); int i, j, k, p, q, r, nFaceCoeffs; -- GitLab From 754a31db9598666222425b0404024c84d44739cd Mon Sep 17 00:00:00 2001 From: ssherw Date: Wed, 8 Mar 2017 16:27:53 +0000 Subject: [PATCH 02/27] Updated regressiont tests to account for the introduction of two new bases types OrthoPyr_C and ModifeidPyr_C --- library/Demos/StdRegions/StdProject2D.cpp | 24 +++---- library/Demos/StdRegions/StdProject3D.cpp | 67 +++++++++++++------ .../Demos/StdRegions/StdProject_Diff2D.cpp | 22 +++--- .../Demos/StdRegions/StdProject_Diff3D.cpp | 20 +++--- .../Tests/StdProject2D_Quad_Fourier_P6_Q8.tst | 2 +- .../Tests/StdProject2D_Tri_Nodal_P6_Q7.tst | 2 +- .../Tests/StdProject3D_Hex_Lagrange_P6_Q7.tst | 2 +- .../Tests/StdProject3D_Pyr_Mod_P6_Q7.tst | 2 +- .../StdProject_Diff2D_Quad_Fourier_P6_Q8.tst | 2 +- .../StdProject_Diff2D_Quad_Lagrange_P6_Q7.tst | 2 +- .../StdProject_Diff2D_Tri_Nodal_P6_Q7.tst | 2 +- .../StdProject_Diff3D_Hex_Lagrange_P6_Q7.tst | 2 +- .../Tests/StdProject_Diff3D_Pyr_Mod_P6_Q7.tst | 2 +- library/LibUtilities/Foundations/Basis.cpp | 5 +- library/StdRegions/StdExpansion.cpp | 9 ++- library/StdRegions/StdPyrExp.cpp | 5 -- 16 files changed, 101 insertions(+), 69 deletions(-) diff --git a/library/Demos/StdRegions/StdProject2D.cpp b/library/Demos/StdRegions/StdProject2D.cpp index fdb413f5e..1237677d9 100644 --- a/library/Demos/StdRegions/StdProject2D.cpp +++ b/library/Demos/StdRegions/StdProject2D.cpp @@ -51,17 +51,17 @@ int main(int argc, char *argv[]) fprintf(stderr,"\t Ortho_B = 2\n"); fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t FourierSingleMode = 12\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 13\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 14\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t FourierSingleMode = 14\n"); + fprintf(stderr,"\t Nodal tri (Electro) = 15\n"); + fprintf(stderr,"\t Nodal tri (Fekete) = 16\n"); - fprintf(stderr,"Note type = 3,6 are for three-dimensional basis\n"); + fprintf(stderr,"Note type = 3,6,7,8 are for three-dimensional basis\n"); exit(1); } @@ -77,17 +77,17 @@ int main(int argc, char *argv[]) int btype1_val = atoi(argv[2]); int btype2_val = atoi(argv[3]); - if(( btype1_val <= 12)&&( btype2_val <= 12)) + if(( btype1_val <= 14)&&( btype2_val <= 14)) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; } - else if(( btype1_val >=13)&&(btype2_val <= 14)) + else if(( btype1_val >=15)&&(btype2_val <= 16)) { btype1 = LibUtilities::eOrtho_A; btype2 = LibUtilities::eOrtho_B; - if(btype1_val == 13) + if(btype1_val == 15) { NodalType = LibUtilities::eNodalTriElec; } diff --git a/library/Demos/StdRegions/StdProject3D.cpp b/library/Demos/StdRegions/StdProject3D.cpp index 9d3a58f64..35425bc3e 100644 --- a/library/Demos/StdRegions/StdProject3D.cpp +++ b/library/Demos/StdRegions/StdProject3D.cpp @@ -21,6 +21,10 @@ using namespace Nektar::StdRegions; NekDouble Tet_sol(NekDouble x, NekDouble y, NekDouble z, int order1, int order2, int order3); +/// Defines a solution which excites all modes in a StdPyr expansion. +NekDouble Pyr_sol(NekDouble x, NekDouble y, NekDouble z, + int order1, int order2, int order3); + /// Defines a solution which excites all modes in a StdPrism expansion. NekDouble Prism_sol(NekDouble x, NekDouble y, NekDouble z, int order1, int order2, int order3); @@ -69,16 +73,16 @@ int main(int argc, char *argv[]){ fprintf(stderr,"\t Ortho_C = 7\n"); fprintf(stderr,"\t Modified_C = 8\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 12\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 13\n"); - fprintf(stderr,"\t Nodal tet (Electro) = 14\n"); - fprintf(stderr,"\t Nodal tet (Even) = 15\n"); - fprintf(stderr,"\t Nodal prism (Even) = 16\n"); + fprintf(stderr,"\t Fourier = 8\n"); + fprintf(stderr,"\t Lagrange = 9\n"); + fprintf(stderr,"\t Gauss Lagrange = 10\n"); + fprintf(stderr,"\t Legendre = 11\n"); + fprintf(stderr,"\t Chebyshev = 12\n"); + fprintf(stderr,"\t Nodal tri (Electro) = 13\n"); + fprintf(stderr,"\t Nodal tri (Fekete) = 14\n"); + fprintf(stderr,"\t Nodal tet (Electro) = 15\n"); + fprintf(stderr,"\t Nodal tet (Even) = 16\n"); + fprintf(stderr,"\t Nodal prism (Even) = 17\n"); exit(1); } @@ -98,13 +102,13 @@ int main(int argc, char *argv[]){ int btype2_val = atoi(argv[3]); int btype3_val = atoi(argv[4]); - if (btype1_val <= 11 && btype2_val <= 11) + if (btype1_val <= 13 && btype2_val <= 13) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; btype3 = (LibUtilities::BasisType) btype3_val; } - else if(btype1_val >=12 && btype2_val <= 16) + else if(btype1_val >=14 && btype2_val <= 18) { if (regionshape == LibUtilities::eTetrahedron) { @@ -119,19 +123,19 @@ int main(int argc, char *argv[]){ btype3 = LibUtilities::eOrtho_B; } - if(btype1_val == 12) + if(btype1_val == 14) { NodalType = LibUtilities::eNodalTriElec; } - else if (btype1_val == 13) + else if (btype1_val == 15) { NodalType = LibUtilities::eNodalTriFekete; } - else if (btype1_val == 14) + else if (btype1_val == 16) { NodalType = LibUtilities::eNodalTetElec; } - else if (btype1_val == 15) + else if (btype1_val == 17) { NodalType = LibUtilities::eNodalTetEvenlySpaced; } @@ -335,7 +339,7 @@ int main(int argc, char *argv[]){ // Define solution to be projected for(i = 0; i < nq1*nq2*nq3; ++i) { - sol[i] = Tet_sol(x[i],y[i],z[i],order1,order2,order3); + sol[i] = Pyr_sol(x[i],y[i],z[i],order1,order2,order3); } //---------------------------------------------- } @@ -425,11 +429,14 @@ int main(int argc, char *argv[]){ t[1] = -0.25; t[2] = -0.3; - if(regionshape == LibUtilities::eTetrahedron || - regionshape == LibUtilities::ePyramid) + if(regionshape == LibUtilities::eTetrahedron) { sol[0] = Tet_sol(t[0], t[1], t[2], order1, order2, order3); } + else if (regionshape == LibUtilities::ePyramid) + { + sol[0] = Pyr_sol(t[0], t[1], t[2], order1, order2, order3); + } else if (regionshape == LibUtilities::ePrism) { sol[0] = Prism_sol(t[0], t[1], t[2], order1, order2, order3); @@ -469,6 +476,28 @@ NekDouble Tet_sol(NekDouble x, NekDouble y, NekDouble z, return sol; } +NekDouble Pyr_sol(NekDouble x, NekDouble y, NekDouble z, + int order1, int order2, int order3) +{ + int l,k,m; + NekDouble sol = 0.0; + + for(k = 0; k < order1; ++k) + { + for(l = 0; l < order2-k; ++l) + { + for(m = 0; m < order3-k-l; ++m) + { + sol += pow(x,k)*pow(y,l)*pow(z,m); + } + } + } + + return sol; +} + + + NekDouble Prism_sol(NekDouble x, NekDouble y, NekDouble z, int order1, int order2, int order3) { diff --git a/library/Demos/StdRegions/StdProject_Diff2D.cpp b/library/Demos/StdRegions/StdProject_Diff2D.cpp index b87677644..da8bbac17 100644 --- a/library/Demos/StdRegions/StdProject_Diff2D.cpp +++ b/library/Demos/StdRegions/StdProject_Diff2D.cpp @@ -56,15 +56,15 @@ int main(int argc, char *argv[]) fprintf(stderr,"\t Ortho_B = 2\n"); fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 13\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 14\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Nodal tri (Electro) = 14\n"); + fprintf(stderr,"\t Nodal tri (Fekete) = 15\n"); - fprintf(stderr,"Note type = 3,6 are for three-dimensional basis\n"); + fprintf(stderr,"Note type = 3,6,7,8 are for three-dimensional basis\n"); exit(1); } @@ -80,17 +80,17 @@ int main(int argc, char *argv[]) int btype1_val = atoi(argv[2]); int btype2_val = atoi(argv[3]); - if(( btype1_val <= 11)&&( btype2_val <= 11)) + if(( btype1_val <= 13)&&( btype2_val <= 13)) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; } - else if(( btype1_val >=13)&&(btype2_val <= 14)) + else if(( btype1_val >=15)&&(btype2_val <= 16)) { btype1 = LibUtilities::eOrtho_A; btype2 = LibUtilities::eOrtho_B; - if(btype1_val == 13) + if(btype1_val == 15) { NodalType = LibUtilities::eNodalTriElec; } diff --git a/library/Demos/StdRegions/StdProject_Diff3D.cpp b/library/Demos/StdRegions/StdProject_Diff3D.cpp index 5f70101e6..504c831bd 100644 --- a/library/Demos/StdRegions/StdProject_Diff3D.cpp +++ b/library/Demos/StdRegions/StdProject_Diff3D.cpp @@ -87,13 +87,15 @@ int main(int argc, char *argv[]){ fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); fprintf(stderr,"\t Modified_C = 6\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 12\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 13\n"); + fprintf(stderr,"\t OrthoPyr_C = 7\n"); + fprintf(stderr,"\t ModifiedPyr_C = 8\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Nodal tri (Electro) = 14\n"); + fprintf(stderr,"\t Nodal tri (Fekete) = 15\n"); exit(1); } @@ -112,13 +114,13 @@ int main(int argc, char *argv[]){ int btype1_val = atoi(argv[2]); int btype2_val = atoi(argv[3]); int btype3_val = atoi(argv[4]); - if(( btype1_val <= 11)&&( btype2_val <= 11)) + if(( btype1_val <= 13)&&( btype2_val <= 13)) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; btype3 = (LibUtilities::BasisType) btype3_val; } - else if(( btype1_val >=12)&&(btype2_val <= 13)) + else if(( btype1_val >=14)&&(btype2_val <= 15)) { btype1 = LibUtilities::eOrtho_A; btype2 = LibUtilities::eOrtho_B; diff --git a/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_P6_Q8.tst b/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_P6_Q8.tst index 191178fc3..747189f01 100644 --- a/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_P6_Q8.tst +++ b/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_P6_Q8.tst @@ -2,7 +2,7 @@ StdProject2D Quadrilateral Fourier basis P=6 Q=8 StdProject2D - 4 7 7 6 6 8 8 + 4 9 9 6 6 8 8 1.06892e-15 diff --git a/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst index 6744d3561..426661fd6 100644 --- a/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject2D Triangle Nodal basis P=6 Q=7 StdProject2D - 3 13 12 6 6 7 7 + 3 15 14 6 6 7 7 1.78107e-15 diff --git a/library/Demos/StdRegions/Tests/StdProject3D_Hex_Lagrange_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject3D_Hex_Lagrange_P6_Q7.tst index a2d94ce7f..94bd7b535 100644 --- a/library/Demos/StdRegions/Tests/StdProject3D_Hex_Lagrange_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject3D_Hex_Lagrange_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject3D Hexahedron Lagrange basis P=6 Q=7 StdProject3D - 8 8 8 8 6 6 6 7 7 7 + 8 10 10 10 6 6 6 7 7 7 3.06382e-14 diff --git a/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst index 7a48e8eba..467780c01 100644 --- a/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject3D Pyramid Modified basis P=6 Q=7 StdProject3D - 6 4 4 6 6 6 6 7 7 6 + 6 4 4 8 6 6 6 7 7 6 1.35652e-12 diff --git a/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Fourier_P6_Q8.tst b/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Fourier_P6_Q8.tst index d5452aa58..1e67d3f39 100644 --- a/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Fourier_P6_Q8.tst +++ b/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Fourier_P6_Q8.tst @@ -2,7 +2,7 @@ StdProject_Diff2D Quadrilateral Fourier basis P=6 Q=8 StdProject_Diff2D - 4 7 7 6 6 8 8 + 4 9 9 6 6 8 8 1.54556e-14 diff --git a/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Lagrange_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Lagrange_P6_Q7.tst index 3c98b2d74..5bf430ff4 100644 --- a/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Lagrange_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject_Diff2D_Quad_Lagrange_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject_Diff2D Quadrilateral Lagrange basis P=6 Q=7 StdProject_Diff2D - 4 8 8 6 6 7 7 + 4 10 10 6 6 7 7 4.14376e-14 diff --git a/library/Demos/StdRegions/Tests/StdProject_Diff2D_Tri_Nodal_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject_Diff2D_Tri_Nodal_P6_Q7.tst index 2a3f56e29..34cdab88d 100644 --- a/library/Demos/StdRegions/Tests/StdProject_Diff2D_Tri_Nodal_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject_Diff2D_Tri_Nodal_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject_Diff2D Triangle Nodal basis P=6 Q=7 StdProject_Diff2D - 3 13 12 6 6 7 7 + 3 15 14 6 6 7 7 1.06405e-14 diff --git a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Lagrange_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Lagrange_P6_Q7.tst index 4dbc53600..1d4515f57 100644 --- a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Lagrange_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Lagrange_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject_Diff3D Hexahedron Lagrange basis P=6 Q=7 StdProject_Diff3D - 8 8 8 8 6 6 6 7 7 7 + 8 10 10 10 6 6 6 7 7 7 5.11314e-13 diff --git a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Pyr_Mod_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Pyr_Mod_P6_Q7.tst index c1de0289c..38981d8ae 100644 --- a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Pyr_Mod_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Pyr_Mod_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject_Diff3D Pyramid Modified basis P=6 Q=7 StdProject_Diff3D - 6 4 4 6 6 6 6 7 7 6 + 6 4 4 8 6 6 6 7 7 6 4.99628e-12 diff --git a/library/LibUtilities/Foundations/Basis.cpp b/library/LibUtilities/Foundations/Basis.cpp index 163e742a2..ef5d0e627 100644 --- a/library/LibUtilities/Foundations/Basis.cpp +++ b/library/LibUtilities/Foundations/Basis.cpp @@ -612,7 +612,6 @@ namespace Nektar mode += N; B_offset += N; - one_m_z_pow = m_bdata.data(); one_p_z = m_bdata.data()+numPoints; for(q = 2; q < numModes; ++q) @@ -620,14 +619,14 @@ namespace Nektar // face 0 for(i = 0; i < numPoints; ++i) { - mode[i] = pow(one_m_z_pow[i],p+q); // [(1-z)/2]^{p+q} + mode[i] = pow(m_bdata[i],p+q); // [(1-z)/2]^{p+q} } one_m_z_pow = mode; mode += numPoints; // interior - for(int r = 1; r < numModes-max(p,q); ++r, mode+=numPoints) + for(int r = 1; r < numModes-max(p,q); ++r) { Polylib::jacobfd(numPoints,z.data(),mode,NULL,r-1,2*p+2*q-1,1.0); diff --git a/library/StdRegions/StdExpansion.cpp b/library/StdRegions/StdExpansion.cpp index 04d4ecbcb..ebf2a2a2c 100644 --- a/library/StdRegions/StdExpansion.cpp +++ b/library/StdRegions/StdExpansion.cpp @@ -671,13 +671,20 @@ namespace Nektar int nq = GetTotPoints(); Array tmp(nq); + static int cnt = 0; + cnt++; + if(cnt == 84) + { + std::cout << "Start" << std::endl; + } + v_BwdTrans(inarray,tmp); if(mkey.HasVarCoeff(eVarCoeffMass)) { Vmath::Vmul(nq, mkey.GetVarCoeff(eVarCoeffMass), 1, tmp, 1, tmp, 1); } - + v_IProductWRTBase(tmp, outarray); } diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index dcbb1a38e..3c51416d4 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -583,11 +583,6 @@ namespace Nektar { v_IProductWRTBase(inarray,outarray); - // get Mass matrix inverse - StdMatrixKey masskey(eMass,DetShapeType(),*this); - DNekMatSharedPtr matsys = GetStdMatrix(masskey); - cout << *matsys << endl; - // get Mass matrix inverse StdMatrixKey imasskey(eInvMass,DetShapeType(),*this); DNekMatSharedPtr imatsys = GetStdMatrix(imasskey); -- GitLab From a89c8db26a0f955db1bf92fd61f84eb573f04d37 Mon Sep 17 00:00:00 2001 From: ssherw Date: Wed, 8 Mar 2017 16:36:54 +0000 Subject: [PATCH 03/27] Added Ortho Pyramid regression test --- library/Demos/StdRegions/CMakeLists.txt | 1 + .../Tests/StdProject3D_Pyr_Mod_P6_Q7.tst | 4 ++-- .../Tests/StdProject3D_Pyr_Ortho_P6_Q7.tst | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 library/Demos/StdRegions/Tests/StdProject3D_Pyr_Ortho_P6_Q7.tst diff --git a/library/Demos/StdRegions/CMakeLists.txt b/library/Demos/StdRegions/CMakeLists.txt index 62fd0e10f..8b73a63eb 100644 --- a/library/Demos/StdRegions/CMakeLists.txt +++ b/library/Demos/StdRegions/CMakeLists.txt @@ -65,6 +65,7 @@ ADD_NEKTAR_TEST(StdProject3D_Tet_Orth_P6_Q7) ADD_NEKTAR_TEST(StdProject3D_Tet_Mod_P6_Q7) ADD_NEKTAR_TEST(StdProject3D_Prism_Orth_P6_Q7) ADD_NEKTAR_TEST(StdProject3D_Prism_Mod_P6_Q7) +ADD_NEKTAR_TEST(StdProject3D_Pyr_Ortho_P6_Q7) ADD_NEKTAR_TEST(StdProject3D_Pyr_Mod_P6_Q7) ADD_NEKTAR_TEST(StdProject3D_Hex_Orth_P6_Q7) ADD_NEKTAR_TEST(StdProject3D_Hex_Mod_P6_Q7) diff --git a/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst index 467780c01..8e047fb04 100644 --- a/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Mod_P6_Q7.tst @@ -5,10 +5,10 @@ 6 4 4 8 6 6 6 7 7 6 - 1.35652e-12 + 3.2756e-12 - 3.8245e-12 + 9.72786e-13 diff --git a/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Ortho_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Ortho_P6_Q7.tst new file mode 100644 index 000000000..4d22f0bf3 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdProject3D_Pyr_Ortho_P6_Q7.tst @@ -0,0 +1,14 @@ + + + StdProject3D Pyramid Orthogonal basis P=6 Q=7 + StdProject3D + 6 1 1 7 6 6 6 7 7 6 + + + 5.32907e-15 + + + 5.32907e-15 + + + -- GitLab From 4b7010f8dbfdd613f5480bd9d8d59b8f8fd74344 Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 13 Mar 2017 18:24:22 +0000 Subject: [PATCH 04/27] Possible mistake for variable p in that we were using P instead of Q to swap edges --- library/StdRegions/StdPrismExp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/StdRegions/StdPrismExp.cpp b/library/StdRegions/StdPrismExp.cpp index b68a2b3bd..ad8182e05 100644 --- a/library/StdRegions/StdPrismExp.cpp +++ b/library/StdRegions/StdPrismExp.cpp @@ -1238,10 +1238,10 @@ namespace Nektar // direction reversed); swap edge modes. if ((int)faceOrient == 7) { - swap(maparray[0], maparray[P]); - for (i = 1; i < P-1; ++i) + swap(maparray[0], maparray[Q]); + for (i = 1; i < Q-1; ++i) { - swap(maparray[i+1], maparray[P+i]); + swap(maparray[i+1], maparray[Q+i]); } } } @@ -1782,7 +1782,7 @@ namespace Nektar { for (q = 0; q <= Q; ++q) { - for (r = 0; r <= R-p; ++r) + for (r = 0; r <= R-p; ++r) { maparray[idx++] = GetMode(p,q,r); } -- GitLab From a03207ba4184d3885ec83abd5400b9e21b196ba3 Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 13 Mar 2017 18:24:57 +0000 Subject: [PATCH 05/27] Version which now passes all the library regression tests locally --- .../MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst | 4 +- .../Tests/Helmholtz3D_CG_Pyr_Deformed.tst | 2 +- library/LibUtilities/Foundations/Basis.cpp | 8 +- library/SpatialDomains/MeshGraph.cpp | 2 +- library/SpatialDomains/PyrGeom.cpp | 6 +- library/StdRegions/StdExpansion3D.cpp | 2 + library/StdRegions/StdPyrExp.cpp | 1030 ++++++----------- library/StdRegions/StdPyrExp.h | 5 +- 8 files changed, 368 insertions(+), 691 deletions(-) diff --git a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst index 04cc5f8d4..2520c8281 100644 --- a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst +++ b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst @@ -8,10 +8,10 @@ - 5.36868e-07 + 5.22808e-07 - 3.78881e-06 + 4.16465e-06 diff --git a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst index 72d45a52f..203b00ce1 100644 --- a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst +++ b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst @@ -8,7 +8,7 @@ - 4.61818e-05 + 4.1907e-05 0.000329233 diff --git a/library/LibUtilities/Foundations/Basis.cpp b/library/LibUtilities/Foundations/Basis.cpp index ef5d0e627..615295e7c 100644 --- a/library/LibUtilities/Foundations/Basis.cpp +++ b/library/LibUtilities/Foundations/Basis.cpp @@ -619,7 +619,11 @@ namespace Nektar // face 0 for(i = 0; i < numPoints; ++i) { - mode[i] = pow(m_bdata[i],p+q); // [(1-z)/2]^{p+q} + // [(1-z)/2]^{p+q-2} Note in book it + // seems to suggest p+q-1 but that + // does not seem to give complete + // polynomial space for pyramids + mode[i] = pow(m_bdata[i],p+q-2); } one_m_z_pow = mode; @@ -628,7 +632,7 @@ namespace Nektar // interior for(int r = 1; r < numModes-max(p,q); ++r) { - Polylib::jacobfd(numPoints,z.data(),mode,NULL,r-1,2*p+2*q-1,1.0); + Polylib::jacobfd(numPoints,z.data(),mode,NULL,r-1,2*p+2*q-3,1.0); for(i = 0; i < numPoints; ++i) { diff --git a/library/SpatialDomains/MeshGraph.cpp b/library/SpatialDomains/MeshGraph.cpp index 6314bce2f..8076e07a4 100644 --- a/library/SpatialDomains/MeshGraph.cpp +++ b/library/SpatialDomains/MeshGraph.cpp @@ -3306,7 +3306,7 @@ namespace Nektar returnval.push_back(bkey); const LibUtilities::PointsKey pkey1(nummodes+quadoffset-1, LibUtilities::eGaussRadauMAlpha2Beta0); - LibUtilities::BasisKey bkey1(LibUtilities::eModified_C, nummodes, pkey1); + LibUtilities::BasisKey bkey1(LibUtilities::eModifiedPyr_C, nummodes, pkey1); returnval.push_back(bkey1); } break; diff --git a/library/SpatialDomains/PyrGeom.cpp b/library/SpatialDomains/PyrGeom.cpp index 5363f5956..cba16e61a 100644 --- a/library/SpatialDomains/PyrGeom.cpp +++ b/library/SpatialDomains/PyrGeom.cpp @@ -600,7 +600,7 @@ namespace Nektar if (fabs(elementAaxis_length*faceBaxis_length - fabs(dotproduct1)) > NekConstants::kNekZeroTol) { - cout << "Warning: Prism axes not parallel" << endl; + cout << "Warning: Pyramid axes not parallel" << endl; } // if the result is negative, both axis point in reverse @@ -621,7 +621,7 @@ namespace Nektar if (fabs(elementBaxis_length*faceAaxis_length - fabs(dotproduct2)) > NekConstants::kNekZeroTol) { - cout << "Warning: Prism axes not parallel" << endl; + cout << "Warning: Pyramid axes not parallel" << endl; } if( dotproduct2 < 0.0 ) @@ -710,7 +710,7 @@ namespace Nektar LibUtilities::PointsKey( order1+1, LibUtilities::eGaussLobattoLegendre)); const LibUtilities::BasisKey C( - LibUtilities::eModified_C, order2, + LibUtilities::eModifiedPyr_C, order2, LibUtilities::PointsKey( order2, LibUtilities::eGaussRadauMAlpha2Beta0)); diff --git a/library/StdRegions/StdExpansion3D.cpp b/library/StdRegions/StdExpansion3D.cpp index ede5943dd..00c93fef4 100644 --- a/library/StdRegions/StdExpansion3D.cpp +++ b/library/StdRegions/StdExpansion3D.cpp @@ -422,6 +422,7 @@ namespace Nektar } case LibUtilities::eModified_B: case LibUtilities::eModified_C: + case LibUtilities::eModifiedPyr_C: { switch (facedir) { @@ -484,6 +485,7 @@ namespace Nektar case LibUtilities::eOrtho_A: case LibUtilities::eOrtho_B: case LibUtilities::eOrtho_C: + case LibUtilities::eOrthoPyr_C: { switch (facedir) { diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index 3c51416d4..7874cd54f 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -29,7 +29,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // -// Description: pyramadic routines built upon StdExpansion3D +// Description: pyramidic routines built upon StdExpansion3D // /////////////////////////////////////////////////////////////////////////////// @@ -66,156 +66,10 @@ namespace Nektar "than order in 'c' direction"); ASSERTL0(Bb.GetNumModes() <= Bc.GetNumModes(), "order in 'b' direction is higher " "than order in 'c' direction"); - -#if 0 - // Set up mode mapping which takes 0\leq i\leq N_coeffs -> (p,q,r) - // of the 3D tensor product - const int P = Ba.GetNumModes() - 1; - const int Q = Bb.GetNumModes() - 1; - const int R = Bc.GetNumModes() - 1; - int cnt = 0; - - - // Vertices - m_map[Mode(0, 0, 0, 0)] = cnt++; - m_map[Mode(1, 0, 0, 0)] = cnt++; - m_map[Mode(1, 1, 0, 0)] = cnt++; - m_map[Mode(0, 1, 0, 0)] = cnt++; - m_map[Mode(0, 0, 1, 1)] = cnt++; - - // Edge 0 - for (int i = 2; i <= P; ++i) - { - m_map[Mode(i, 0, 0, GetTetMode(i, 0, 0))] = cnt++; - } - - // Edge 1 - for (int i = 2; i <= Q; ++i) - { - m_map[Mode(1, i, 0, GetTetMode(0, i, 0))] = cnt++; - } - - // Edge 2 - for (int i = 2; i <= P; ++i) - { - m_map[Mode(i, 1, 0, GetTetMode(i, 0, 0))] = cnt++; - } - - // Edge 3 - for (int i = 2; i <= Q; ++i) - { - m_map[Mode(0, i, 0, GetTetMode(0, i, 0))] = cnt++; - } - - // Edge 4 - for (int i = 2; i <= R; ++i) - { - m_map[Mode(0, 0, i, i)] = cnt++; - } - - // Edge 5 - for (int i = 2; i <= R; ++i) - { - m_map[Mode(1, 0, i, i)] = cnt++; - } - - // Edge 6 - for (int i = 2; i <= R; ++i) - { - m_map[Mode(1, 1, i, i)] = cnt++; - } - - // Edge 7 - for (int i = 2; i <= R; ++i) - { - m_map[Mode(0, 1, i, i)] = cnt++; - } - - // Face 0 - TODO check this - for (int j = 2; j <= Q; ++j) - { - for (int i = 2; i <= P; ++i) - { - m_map[Mode(i, j, 0, GetTetMode((i-2+j-2) % (Q-1) + 2, 0, 0))] = cnt++; - } - } - - // Face 1 - for (int i = 2; i <= P; ++i) - { - for (int j = 1; j <= R-i; ++j) - { - m_map[Mode(i, 0, j, GetTetMode(i, 0, j))] = cnt++; - } - } - - // Face 2 - for (int i = 2; i <= Q; ++i) - { - for (int j = 1; j <= R-i; ++j) - { - m_map[Mode(1, i, j, GetTetMode(0, i, j))] = cnt++; - } - } - - // Face 3 - for (int i = 2; i <= P; ++i) - { - for (int j = 1; j <= R-i; ++j) - { - m_map[Mode(i, 1, j, GetTetMode(i, 0, j))] = cnt++; - } - } - - // Face 4 - for (int i = 2; i <= Q; ++i) - { - for (int j = 1; j <= R-i; ++j) - { - m_map[Mode(0, i, j, GetTetMode(0, i, j))] = cnt++; - } - } - - // Interior (tetrahedral modes) - for (int i = 2; i <= P+1; ++i) - { - for (int j = 1; j <= Q-i+1; ++j) - { - for (int k = 1; k <= R-i-j+1; ++k) - { - // need to go to j+1-th mode in the 'b' direction to - // select correct modified_a mode - m_map[Mode(i, j+1, k, GetTetMode(i-1, j, k))] = cnt++; - } - } - } - - ASSERTL0(m_map.size() == m_ncoeffs, - "Duplicate coefficient entries in map"); - - map::iterator it; - for (it = m_map.begin(); it != m_map.end(); ++it) - { - const int p = it->first.get<0>(); - const int q = it->first.get<1>(); - const int r = it->first.get<2>(); - const int rp = it->first.get<3>(); - if (m_idxMap.find(p) == m_idxMap.end()) - { - m_idxMap[p] = map > >(); - } - - if (m_idxMap[p].find(q) == m_idxMap[p].end()) - { - m_idxMap[p][q] = map >(); - } - - if (m_idxMap[p][q].find(r) == m_idxMap[p][q].end()) - { - m_idxMap[p][q][r] = pair(it->second, rp); - } - } -#endif + ASSERTL1(Bc.GetBasisType() == LibUtilities::eModifiedPyr_C || + Bc.GetBasisType() == LibUtilities::eOrthoPyr_C, + "Expected basis type in 'c' direction to be ModifiedPyr_C or OrthoPyr_C"); + } StdPyrExp::StdPyrExp(const StdPyrExp &T) @@ -389,13 +243,14 @@ namespace Nektar const Array& inarray, Array& outarray) { + int nquad0 = m_base[0]->GetNumPoints(); int nquad1 = m_base[1]->GetNumPoints(); int nquad2 = m_base[2]->GetNumPoints(); int order0 = m_base[0]->GetNumModes(); int order1 = m_base[1]->GetNumModes(); Array wsp(nquad2*order0*order1+ - nquad2*nquad1*order0); + nquad2*nquad1*nquad0); v_BwdTrans_SumFacKernel(m_base[0]->GetBdata(), m_base[1]->GetBdata(), @@ -415,81 +270,6 @@ namespace Nektar bool doCheckCollDir1, bool doCheckCollDir2) { -#if 0 - const int Qx = m_base[0]->GetNumPoints(); - const int Qy = m_base[1]->GetNumPoints(); - const int Qz = m_base[2]->GetNumPoints(); - - const NekDouble *bx = base0.get(); - const NekDouble *by = base1.get(); - const NekDouble *bz = base2.get(); - - // Need to count coeffs for storage... - map > > >::iterator it_p; - map > > ::iterator it_q; - map > ::iterator it_r; - - int pqcnt = 0; - for (it_p = m_idxMap.begin(); it_p != m_idxMap.end(); ++it_p) - { - for (it_q = it_p->second.begin(); it_q != it_p->second.end(); ++it_q) - { - pqcnt++; - } - } - - Array fpq(pqcnt); - Array fp (m_base[0]->GetNumModes()); - int i ,j, k, s = 0, cnt = 0, cnt2 = 0; - - for (k = 0; k < Qz; ++k) - { - NekDouble bz1 = bz[k+Qz]; - - cnt = 0; - for (it_p = m_idxMap.begin(); it_p != m_idxMap.end(); ++it_p) - { - for (it_q = it_p->second.begin(); it_q != it_p->second.end(); ++it_q) - { - NekDouble sum = 0.0; - for (it_r = it_q->second.begin(); it_r != it_q->second.end(); ++it_r) - { - sum += inarray[it_r->second.first] * bz[k + Qz*it_r->second.second]; - } - fpq[cnt++] = sum; - } - } - - for (j = 0; j < Qy; ++j) - { - NekDouble by0 = bz1*by[j]; - NekDouble by1 = bz1*by[j+Qy]; - - cnt = cnt2 = 0; - for (it_p = m_idxMap.begin(); it_p != m_idxMap.end(); ++it_p) - { - NekDouble sum = 0.0; - for (it_q = it_p->second.begin(); it_q != it_p->second.end(); ++it_q) - { - sum += by[j + Qy*it_q->first] * fpq[cnt++]; - } - fp[cnt2++] = sum; - } - - for (i = 0; i < Qx; ++i, ++s) - { - cnt2 = 0; - NekDouble sum = 0.0; - for (it_p = m_idxMap.begin(); it_p != m_idxMap.end(); ++it_p) - { - sum += bx[i + Qx*it_p->first] * fp[cnt2++]; - } - sum += inarray[4]*(by1*(bx[i] + bx[i+Qx]) + by0*bx[i+Qx]); - outarray[s] = sum; - } - } - } -#else int nquad0 = m_base[0]->GetNumPoints(); int nquad1 = m_base[1]->GetNumPoints(); int nquad2 = m_base[2]->GetNumPoints(); @@ -562,7 +342,6 @@ namespace Nektar tmp1.get(), nquad1*nquad2, 0.0, outarray.get(), nquad0); -#endif } /** \brief Forward transform from physical quadrature space @@ -677,84 +456,6 @@ namespace Nektar bool doCheckCollDir1, bool doCheckCollDir2) { -#if 0 - int i, j, k, s; - int Qx = m_base[0]->GetNumPoints(); - int Qy = m_base[1]->GetNumPoints(); - int Qz = m_base[2]->GetNumPoints(); - - const NekDouble *bx = base0.get(); - const NekDouble *by = base1.get(); - const NekDouble *bz = base2.get(); - - map > > >::iterator it_p; - map > > ::iterator it_q; - map > ::iterator it_r; - - Array f (Qy*Qz); - Array fb(Qz); - - for (it_p = m_idxMap.begin(); it_p != m_idxMap.end(); ++it_p) - { - const int p = it_p->first; - s = 0; - for (k = 0; k < Qz; ++k) - { - for (j = 0; j < Qy; ++j) - { - NekDouble sum = 0.0; - for (i = 0; i < Qx; ++i, ++s) - { - sum += bx[i + Qx*p]*inarray[s]; - } - f[j+Qy*k] = sum; - } - } - - for (it_q = it_p->second.begin(); it_q != it_p->second.end(); ++it_q) - { - const int q = it_q->first; - - for (k = 0; k < Qz; ++k) - { - NekDouble sum = 0.0; - for (j = 0; j < Qy; ++j) - { - sum += by[j + Qy*q]*f[j+Qy*k]; - } - fb[k] = sum; - } - - for (it_r = it_q->second.begin(); it_r != it_q->second.end(); ++it_r) - { - const int rpqr = it_r->second.second; - NekDouble sum = 0.0; - for (k = 0; k < Qz; ++k) - { - sum += bz[k + Qz*rpqr]*fb[k]; - } - - outarray[it_r->second.first] = sum; - } - } - } - - // Correct for top mode - s = 0; - for (k = 0; k < Qz; ++k) - { - for (j = 0; j < Qy; ++j) - { - for (i = 0; i < Qx; ++i, ++s) - { - outarray[4] += inarray[s] * bz[k+Qz]*( - bx[i+Qx]*by[j+Qy] + - bx[i+Qx]*by[j ] + - bx[i ]*by[j+Qy]); - } - } - } -#else int nquad0 = m_base[0]->GetNumPoints(); int nquad1 = m_base[1]->GetNumPoints(); int nquad2 = m_base[2]->GetNumPoints(); @@ -825,7 +526,6 @@ namespace Nektar outarray[1] += Blas::Ddot(nquad2,base2.get()+nquad2,1, &tmp2[nquad2*order1+nquad2],1); } -#endif } void StdPyrExp::v_IProductWRTDerivBase( @@ -857,7 +557,13 @@ namespace Nektar Array gfac1(nquad1); Array gfac2(nquad2); Array tmp0 (nqtot); - Array wsp; + + + int order0 = m_base[0]->GetNumModes(); + int order1 = m_base[1]->GetNumModes(); + + Array wsp(nquad1*nquad2*order0 + + nquad2*order0*order1); const Array& z0 = m_base[0]->GetZ(); const Array& z1 = m_base[1]->GetZ(); @@ -1285,7 +991,7 @@ namespace Nektar "(x and y direction) and ModifiedPyr_C BasisType (z " "direction)"); - int i, j, k, p, q, r, nFaceCoeffs; + int i, j, k, p, q, r, nFaceCoeffs, idx = 0; int nummodesA=0, nummodesB=0; int order0 = m_base[0]->GetNumModes(); @@ -1368,299 +1074,95 @@ namespace Nektar // Set up ordering inside each 2D face. Also for triangular faces, // populate signarray. - int cnt = 0, cnt2; switch (fid) { - case 0: // Bottom quad - - // Fill in vertices - maparray[arrayindx[0]] = 0; - maparray[arrayindx[1]] = 1; - maparray[arrayindx[P+1]] = 2; - maparray[arrayindx[P]] = 3; - - // Edge 0 - cnt = 5; - for (p = 2; p < P; ++p) - { - maparray[arrayindx[p]] = p-2 + cnt; - } - - // Edge 1 - cnt += P-2; - for (q = 2; q < Q; ++q) - { - maparray[arrayindx[q*P+1]] = q-2 + cnt; - } - - // Edge 2 - cnt += Q-2; - for (p = 2; p < P; ++p) - { - maparray[arrayindx[P+p]] = p-2 + cnt; - } - - // Edge 3 - cnt += P-2; - for (q = 2; q < Q; ++q) - { - maparray[arrayindx[q*P]] = q-2 + cnt; - } - - // Interior - cnt += Q-2 + 4*(P-2); - for (q = 2; q < Q; ++q) - { - for (p = 2; p < P; ++p) - { - maparray[arrayindx[q*P+p]] = cnt + (q-2)*P+(p-2); - } - } - - - break; - - case 1: // Left triangle - // Vertices - maparray[0] = 0; - maparray[1] = 4; - maparray[Q] = 1; - - // Edge 0 (pyramid edge 0) - cnt = 5; - q = 2*Q-1; - for (p = 2; p < P; q += Q-p, ++p) - { - maparray[q] = cnt++; - if ((int)faceOrient == 7) - { - signarray[q] = p % 2 ? -1 : 1; - } - } - - // Edge 1 (pyramid edge 5) - cnt = 5 + 2*(order0-2) + 2*(order1-2) + (order2-2); - for (q = 2; q < Q; ++q) - { - maparray[q] = cnt++; - if ((int)faceOrient == 7) - { - signarray[q] = q % 2 ? -1 : 1; - } - } - - // Edge 2 (pyramid edge 4) - cnt = 5 + 2*(order0-2) + 2*(order1-2); - for (q = 2; q < Q; ++q) - { - maparray[Q+q-1] = cnt++; - if ((int)faceOrient == 7) - { - signarray[Q+q-1] = q % 2 ? -1 : 1; - } - } - - // Interior - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 4*(order2-2) - + v_GetFaceIntNcoeffs(0); - cnt2 = 2*Q + 1; - for (p = 2; p < P; ++p) - { - for (r = 2; r < Q-p; ++r) - { - maparray[cnt2] = cnt++; - if ((int)faceOrient == 7 && p > 1) - { - signarray[cnt2++] = p % 2 ? -1 : 1; - } - } - cnt2++; - } - break; - - case 2: - // Vertices - maparray[0] = 1; - maparray[1] = 4; - maparray[Q] = 2; - - // Edge 0 (pyramid edge 1) - cnt = 5 + (order0-2); - q = 2*Q-1; - for (p = 2; p < P; q += Q-p, ++p) - { - maparray[q] = cnt++; - if ((int)faceOrient == 7) - { - signarray[q] = p % 2 ? -1 : 1; - } - } - - // Edge 1 (pyramid edge 6) - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 2*(order2-2); - for (q = 2; q < Q; ++q) - { - maparray[q] = cnt++; - if ((int)faceOrient == 7) - { - signarray[q] = q % 2 ? -1 : 1; - } - } - - // Edge 2 (pyramid edge 5) - cnt = 5 + 2*(order0-2) + 2*(order1-2) + (order2-2); - for (q = 2; q < Q; ++q) - { - maparray[Q+q-1] = cnt++; - if ((int)faceOrient == 7) - { - signarray[Q+q-1] = q % 2 ? -1 : 1; - } - } - - // Interior - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 4*(order2-2) - + v_GetFaceIntNcoeffs(0) + v_GetFaceIntNcoeffs(1); - cnt2 = 2*Q + 1; - for (p = 2; p < P; ++p) - { - for (r = 2; r < Q-p; ++r) - { - maparray[cnt2] = cnt++; - if ((int)faceOrient == 7 && p > 1) - { - signarray[cnt2++] = p % 2 ? -1 : 1; - } - } - cnt2++; - } - break; - - case 3: // Right triangle - // Vertices - maparray[0] = 3; - maparray[1] = 4; - maparray[Q] = 2; - - // Edge 0 (pyramid edge 2) - cnt = 5 + (order0-2) + (order1-2); - q = 2*Q-1; - for (p = 2; p < P; q += Q-p, ++p) - { - maparray[q] = cnt++; - if ((int)faceOrient == 7) - { - signarray[q] = p % 2 ? -1 : 1; - } - } - - // Edge 1 (pyramid edge 6) - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 2*(order2-2); - for (q = 2; q < Q; ++q) - { - maparray[q] = cnt++; - if ((int)faceOrient == 7) - { - signarray[q] = q % 2 ? -1 : 1; - } - } + case 0: // Bottom quad - // Edge 2 (pyramid edge 7) - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 3*(order2-2); - for (q = 2; q < Q; ++q) + for (q = 0; q < Q; ++q) + { + for (p = 0; p < P; ++p) { - maparray[Q+q-1] = cnt++; - if ((int)faceOrient == 7) - { - signarray[Q+q-1] = q % 2 ? -1 : 1; - } + maparray[arrayindx[q*P+p]] = GetMode(p,q,0); } - - // Interior - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 4*(order2-2) - + v_GetFaceIntNcoeffs(0) + v_GetFaceIntNcoeffs(1) - + v_GetFaceIntNcoeffs(2); - cnt2 = 2*Q + 1; - for (p = 2; p < P; ++p) + } + break; + + case 1: // Front triangle + for (p = 0; p < P; ++p) + { + for (r = 0; r < Q-p; ++r) { - for (r = 2; r < Q-p; ++r) + if ((int)faceOrient == 7 && p > 1) { - maparray[cnt2] = cnt++; - if ((int)faceOrient == 7 && p > 1) - { - signarray[cnt2++] = p % 2 ? -1 : 1; - } + signarray[idx] = p % 2 ? -1 : 1; } - cnt2++; + maparray[idx++] = GetMode(p,0,r); } - break; - - case 4: // Rear tri - // Vertices - maparray[0] = 0; - maparray[1] = 4; - maparray[Q] = 3; + } + break; + + case 2: // Right triangle + maparray[idx++] = GetMode(1,0,0); + maparray[idx++] = GetMode(0,0,1); + for (r = 1; r < Q-1; ++r) + { + maparray[idx++] = GetMode(1,0,r); + } - // Edge 0 (pyramid edge 3) - cnt = 5 + 2*(order0-2) + (order1-2); - q = 2*Q-1; - for (p = 2; p < P; q += Q-p, ++p) + for (q = 1; q < P; ++q) + { + for (r = 0; r < Q-q; ++r) { - maparray[q] = cnt++; - if ((int)faceOrient == 7) + if ((int)faceOrient == 7 && q > 1) { - signarray[q] = p % 2 ? -1 : 1; + signarray[idx] = q % 2 ? -1 : 1; } + maparray[idx++] = GetMode(1,q,r); } + } + break; - // Edge 1 (pyramid edge 7) - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 3*(order2-2); - for (q = 2; q < Q; ++q) - { - maparray[q] = cnt++; - if ((int)faceOrient == 7) - { - signarray[q] = q % 2 ? -1 : 1; - } - } + case 3: // Rear triangle + maparray[idx++] = GetMode(0,1,0); + maparray[idx++] = GetMode(0,0,1); + for (r = 1; r < Q-1; ++r) + { + maparray[idx++] = GetMode(0,1,r); + } - // Edge 2 (pyramid edge 4) - cnt = 5 + 2*(order0-2) + 2*(order1-2); - for (q = 2; q < Q; ++q) + for (p = 1; p < P; ++p) + { + for (r = 0; r < Q-p; ++r) { - maparray[Q+q-1] = cnt++; - if ((int)faceOrient == 7) + if ((int)faceOrient == 7 && p > 1) { - signarray[Q+q-1] = q % 2 ? -1 : 1; + signarray[idx] = p % 2 ? -1 : 1; } + maparray[idx++] = GetMode(p, 1, r); } - - // Interior - cnt = 5 + 2*(order0-2) + 2*(order1-2) + 4*(order2-2) - + v_GetFaceIntNcoeffs(0) + v_GetFaceIntNcoeffs(1) - + v_GetFaceIntNcoeffs(2) + v_GetFaceIntNcoeffs(3); - cnt2 = 2*Q + 1; - for (p = 2; p < P; ++p) + } + break; + + case 4: // Left triangle + for (q = 0; q < P; ++q) + { + for (r = 0; r < Q-q; ++r) { - for (r = 2; r < Q-p; ++r) + if ((int)faceOrient == 7 && q > 1) { - maparray[cnt2] = cnt++; - if ((int)faceOrient == 7 && p > 1) - { - signarray[cnt2++] = p % 2 ? -1 : 1; - } + signarray[idx] = q % 2 ? -1 : 1; } - cnt2++; + maparray[idx++] = GetMode(0,q,r); } - break; + } + break; - default: - ASSERTL0(false, "Face to element map unavailable."); + default: + ASSERTL0(false, "Face to element map unavailable."); } if (fid > 0) { - if(CheckForZeroedModes) { // zero signmap and set maparray to zero if elemental @@ -1690,10 +1192,10 @@ namespace Nektar // direction reversed); swap edge modes. if ((int)faceOrient == 7) { - swap(maparray[0], maparray[P]); - for (i = 1; i < P-1; ++i) + swap(maparray[0], maparray[Q]); + for (i = 1; i < Q-1; ++i) { - swap(maparray[i+1], maparray[P+i]); + swap(maparray[i+1], maparray[Q+i]); } } } @@ -1806,9 +1308,61 @@ namespace Nektar { ASSERTL0(GetEdgeBasisType(vId) == LibUtilities::eModified_A || GetEdgeBasisType(vId) == LibUtilities::eModified_A || - GetEdgeBasisType(vId) == LibUtilities::eModified_C, + GetEdgeBasisType(vId) == LibUtilities::eModifiedPyr_C, "Mapping not defined for this type of basis"); - return vId; + + + + int l = 0; + + if(useCoeffPacking == true) // follow packing of coefficients i.e q,r,p + { + switch (vId) + { + case 0: + l = GetMode(0,0,0); + break; + case 1: + l = GetMode(0,0,1); + break; + case 2: + l = GetMode(0,1,0); + break; + case 3: + l = GetMode(1,0,0); + break; + case 4: + l = GetMode(1,1,0); + break; + default: + ASSERTL0(false, "local vertex id must be between 0 and 4"); + } + } + else + { + switch (vId) + { + case 0: + l = GetMode(0,0,0); + break; + case 1: + l = GetMode(1,0,0); + break; + case 2: + l = GetMode(1,1,0); + break; + case 3: + l = GetMode(0,1,0); + break; + case 4: + l = GetMode(0,0,1); + break; + default: + ASSERTL0(false, "local vertex id must be between 0 and 4"); + } + } + + return l; } void StdPyrExp::v_GetEdgeInteriorMap( @@ -1819,9 +1373,9 @@ namespace Nektar { int i; bool signChange; - const int P = m_base[0]->GetNumModes() - 2; - const int Q = m_base[1]->GetNumModes() - 2; - const int R = m_base[2]->GetNumModes() - 2; + const int P = m_base[0]->GetNumModes() - 1; + const int Q = m_base[1]->GetNumModes() - 1; + const int R = m_base[2]->GetNumModes() - 1; const int nEdgeIntCoeffs = v_GetEdgeNcoeffs(eid) - 2; if (maparray.num_elements() != nEdgeIntCoeffs) @@ -1842,43 +1396,65 @@ namespace Nektar // degree 2n+1, n >= 1. signChange = edgeOrient == eBackwards; - int offset = 5; - switch (eid) { - case 0: - break; - case 1: - offset += P; - break; - case 2: - offset += P+Q; - break; - case 3: - offset += 2*P+Q; - break; - case 4: - offset += 2*(P+Q); - break; - case 5: - offset += 2*(P+Q)+R; - break; - case 6: - offset += 2*(P+Q+R); - break; - case 7: - offset += 2*(P+Q)+3*R; - break; - default: - ASSERTL0(false, "Edge not defined."); - break; - } - - for (i = 0; i < nEdgeIntCoeffs; ++i) - { - maparray[i] = offset + i; + case 0: + for (i = 2; i <= P; ++i) + { + maparray[i-2] = GetMode(i,0,0); + } + break; + + case 1: + for (i = 2; i <= Q; ++i) + { + maparray[i-2] = GetMode(1,i,0); + } + break; + case 2: + for (i = 2; i <= P; ++i) + { + maparray[i-2] = GetMode(i,1,0); + } + break; + + case 3: + for (i = 2; i <= Q; ++i) + { + maparray[i-2] = GetMode(0,i,0); + } + break; + case 4: + for (i = 2; i <= R; ++i) + { + maparray[i-2] = GetMode(0,0,i); + } + break; + + case 5: + for (i = 1; i <= R-1; ++i) + { + maparray[i-1] = GetMode(1,0,i); + } + break; + case 6: + for (i = 1; i <= R-1; ++i) + { + maparray[i-1] = GetMode(1,1,i); + } + break; + + case 7: + for (i = 1; i <= R-1; ++i) + { + maparray[i-1] = GetMode(0,1,i); + } + break; + default: + ASSERTL0(false, "Edge not defined."); + break; } - + if (signChange) { for (i = 1; i < nEdgeIntCoeffs; i += 2) @@ -1941,60 +1517,75 @@ namespace Nektar } } - int offset = 5 + 2*(P-1) + 2*(Q-1) + 4*(R-1); - - for (i = 0; i < fid; ++i) - { - offset += v_GetFaceIntNcoeffs(i); - } - switch (fid) { - case 0: - for (q = 2; q <= Q; ++q) + case 0: // Bottom quad + for (q = 2; q <= Q; ++q) + { + for (p = 2; p <= P; ++p) + { + maparray[arrayindx[(q-2)*nummodesA+(p-2)]] = GetMode(p,q,0); + } + } + break; + case 1: // Front triangle + for (p = 2; p <= P; ++p) + { + for (r = 1; r <= R-p; ++r) { - for (p = 2; p <= P; ++p) + if ((int)faceOrient == 7) { - maparray[arrayindx[(q-2)*nummodesA+(p-2)]] - = offset + (q-2)*nummodesA+(p-2); + signarray[idx] = p % 2 ? -1 : 1; } + maparray[idx++] = GetMode(p,0,r); } - break; - - case 1: - case 3: - for (p = 2; p <= P; ++p) + } + break; + case 2: // Right triangle + for (q = 2; q <= Q; ++q) + { + for (r = 1; r <= R-q; ++r) { - for (r = 1; r <= R-p; ++r, ++idx) + if ((int)faceOrient == 7) { - if ((int)faceOrient == 7) - { - signarray[idx] = p % 2 ? -1 : 1; - } - maparray[idx] = offset + idx; + signarray[idx] = q % 2 ? -1 : 1; } + maparray[idx++] = GetMode(1, q, r); } + } break; - - case 2: - case 4: - for (q = 2; q <= Q; ++q) + + case 3: // Rear triangle + for (p = 2; p <= P; ++p) + { + for (r = 1; r <= R-p; ++r) { - for (r = 1; r <= R-q; ++r, ++idx) + if ((int)faceOrient == 7) { - if ((int)faceOrient == 7) - { - signarray[idx] = q % 2 ? -1 : 1; - } - maparray[idx] = offset + idx; + signarray[idx] = p % 2 ? -1 : 1; } + maparray[idx++] = GetMode(p, 1, r); } - break; - - default: - ASSERTL0(false, "Face interior map not available."); + } + break; + + case 4: // Left triangle + for (q = 2; q <= Q; ++q) + { + for (r = 1; r <= R-q; ++r) + { + if ((int)faceOrient == 7) + { + signarray[idx] = q % 2 ? -1 : 1; + } + maparray[idx++] = GetMode(0, q, r); + } + } + break; + default: + ASSERTL0(false, "Face interior map not available."); } - + // Triangular faces are processed in the above switch loop; for // remaining quad faces, set up orientation if necessary. if (fid > 0) @@ -2061,23 +1652,35 @@ namespace Nektar ASSERTL1(GetBasisType(1) == LibUtilities::eModified_A || GetBasisType(1) == LibUtilities::eGLL_Lagrange, "BasisType is not a boundary interior form"); - ASSERTL1(GetBasisType(2) == LibUtilities::eModified_C || + ASSERTL1(GetBasisType(2) == LibUtilities::eModifiedPyr_C || GetBasisType(2) == LibUtilities::eGLL_Lagrange, "BasisType is not a boundary interior form"); - const int nBndCoeffs = v_NumBndryCoeffs(); - const int nIntCoeffs = m_ncoeffs - NumBndryCoeffs(); - if (outarray.num_elements() != nIntCoeffs) + int P = m_base[0]->GetNumModes() - 1, p; + int Q = m_base[1]->GetNumModes() - 1, q; + int R = m_base[2]->GetNumModes() - 1, r; + + int nIntCoeffs = m_ncoeffs - NumBndryCoeffs(); + + if(outarray.num_elements()!=nIntCoeffs) { outarray = Array(nIntCoeffs); } + int idx = 0; + // Loop over all interior modes. - int p, idx = 0; - for (p = nBndCoeffs; p < m_ncoeffs; ++p) + for (p = 2; p <= P; ++p) { - outarray[idx++] = p; + for (q = 2; q <= Q; ++q) + { + int maxpq = max(p,q); + for (r = 1; r <= R-maxpq; ++r) + { + outarray[idx++] = GetMode(p,q,r); + } + } } } @@ -2089,15 +1692,56 @@ namespace Nektar ASSERTL1(GetBasisType(1) == LibUtilities::eModified_A || GetBasisType(1) == LibUtilities::eGLL_Lagrange, "BasisType is not a boundary interior form"); - ASSERTL1(GetBasisType(2) == LibUtilities::eModified_C || + ASSERTL1(GetBasisType(2) == LibUtilities::eModifiedPyr_C || GetBasisType(2) == LibUtilities::eGLL_Lagrange, "BasisType is not a boundary interior form"); - int idx = 0, nBndry = v_NumBndryCoeffs(); + int P = m_base[0]->GetNumModes() - 1, p; + int Q = m_base[1]->GetNumModes() - 1, q; + int R = m_base[2]->GetNumModes() - 1, r; + int idx = 0; + + int nBnd = NumBndryCoeffs(); - for (idx = 0; idx < nBndry; ++idx) + if (maparray.num_elements() != nBnd) { - maparray[idx] = idx; + maparray = Array(nBnd); + } + + // Loop over all boundary modes (in ascending order). + for (p = 0; p <= P; ++p) + { + // First two q-r planes are entirely boundary modes. + if (p <= 1) + { + for (q = 0; q <= Q; ++q) + { + int maxpq = max(p,q); + for (r = 0; r <= R-maxpq; ++r) + { + maparray[idx++] = GetMode(p,q,r); + } + } + } + else + { + // Remaining q-r planes contain boundary modes on the two + // front and back sides and edges 0 2. + for (q = 0; q <= Q; ++q) + { + if (q <= 1) + { + for (r = 0; r <= R-p; ++r) + { + maparray[idx++] = GetMode(p,q,r); + } + } + else + { + maparray[idx++] = GetMode(p,q,0); + } + } + } } } @@ -2115,30 +1759,60 @@ namespace Nektar return v_GenMatrix(mkey); } + /** - * @brief Number tetrahedral modes in r-direction. Much the same as - * StdTetExp::GetTetMode but slightly simplified since we know that the - * polynomial order is the same in each direction. + * @brief Compute the mode number in the expansion for a + * particular tensorial combination. + * + * Modes are numbered with the r index travelling fastest, + * followed by q and then p, and each q-r plane is of size + * + * (R+1-p)*(Q+1) - l(l+1)/2 where l = max(0,Q-p) + * + * For example, when P=2, Q=3 and R=4 the indexing inside each + * q-r plane (with r increasing upwards and q to the right) + * is: + * + * p = 0: p = 1: p = 2: + * ---------------------------------- + * 4 + * 3 8 17 21 + * 2 7 11 16 20 24 29 32 35 + * 1 6 10 13 15 19 23 26 28 31 34 37 + * 0 5 9 12 14 18 22 25 27 30 33 36 + * + * Note that in this element, we must have that \f$ P,Q \leq + * R\f$. */ - int StdPyrExp::GetTetMode(const int I, const int J, const int K) + int StdPyrExp::GetMode(const int I, const int J, const int K) { - const int R = m_base[2]->GetNumModes(); - int i, j, cnt = 0; + const int Q = m_base[1]->GetNumModes()-1; + const int R = m_base[2]->GetNumModes()-1; + + int i,j,l; + int cnt = 0; + + // Traverse to q-r plane number I for (i = 0; i < I; ++i) { - cnt += (R-i)*(R-i+1)/2; + // Size of triangle part + l = max(0,Q-i); + + // Size of rectangle part + cnt += (R+1-i)*(Q+1) - l*(l+1)/2; } - i = R-I; - for (j = 0; j < J; ++j) - { - cnt += i; - i--; - } + // Traverse to q column J (Pretend this is a face of width J) + l = max(0,J-1-I); + cnt += (R+1-I)*J - l*(l+1)/2; + + // Traverse up stacks to K + cnt += K; - return cnt + K; + return cnt; } + void StdPyrExp::v_MultiplyByStdQuadratureMetric( const Array& inarray, Array& outarray) diff --git a/library/StdRegions/StdPyrExp.h b/library/StdRegions/StdPyrExp.h index 4b93af8ef..62891dc28 100644 --- a/library/StdRegions/StdPyrExp.h +++ b/library/StdRegions/StdPyrExp.h @@ -98,8 +98,6 @@ namespace Nektar STD_REGIONS_EXPORT ~StdPyrExp(); - STD_REGIONS_EXPORT int GetTetMode(int I, int J, int K); - protected: //--------------------------------------- // Differentiation/integration Methods @@ -257,8 +255,7 @@ namespace Nektar //--------------------------------------- // Private helper functions //--------------------------------------- - std::map m_map; - std::map > > > m_idxMap; + STD_REGIONS_EXPORT int GetMode(int I, int J, int K); }; typedef boost::shared_ptr StdPyrExpSharedPtr; } //end of namespace -- GitLab From 12e5682c39c8e719817401263dd2743a015ca6fa Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 13 Mar 2017 23:44:16 +0000 Subject: [PATCH 06/27] Modified LocProject3D tests to be consistent with introduction of Pyramid expansion. All seem OK except Hex and Lagrange changes which were rather large in a relative sense if or order 10e-11 --- library/Demos/LocalRegions/LocProject3D.cpp | 31 +++++++++++-------- .../Demos/LocalRegions/LocProject_Diff3D.cpp | 28 +++++++++++------ .../LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst | 4 +-- .../LocProject3D_Pyr_Mod_Basis_P6_Q7.tst | 6 ++-- ..._Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst | 4 +-- ...Project_Diff3D_Reg_Pyr_Mod_Basis_P6_Q7.tst | 6 ++-- 6 files changed, 46 insertions(+), 33 deletions(-) diff --git a/library/Demos/LocalRegions/LocProject3D.cpp b/library/Demos/LocalRegions/LocProject3D.cpp index 81607d1be..11456c9fb 100644 --- a/library/Demos/LocalRegions/LocProject3D.cpp +++ b/library/Demos/LocalRegions/LocProject3D.cpp @@ -88,10 +88,12 @@ int main(int argc, char *argv[]){ fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); fprintf(stderr,"\t Modified_C = 6\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Legendre = 9\n"); - fprintf(stderr,"\t Chebyshev = 10\n"); + fprintf(stderr,"\t OrthoPyr_C = 7\n"); + fprintf(stderr,"\t ModifiedPyr_C = 8\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Legendre = 11\n"); + fprintf(stderr,"\t Chebyshev = 12\n"); exit(1); } @@ -142,25 +144,28 @@ int main(int argc, char *argv[]){ break; case LibUtilities::ePyramid: if((btype1 == eOrtho_B) || (btype1 == eOrtho_C) - || (btype1 == eModified_B) || (btype1 == eModified_C)) + || (btype1 == eModified_B) || (btype1 == eModified_C) + || (btype1 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, - "Basis 1 cannot be of type Ortho_B, Ortho_C, Modified_B " - "or Modified_C"); + "Basis 1 cannot be of type Ortho_B, Ortho_C, Modified_B, " + "Modified_C or ModifiedPyr_C"); } if((btype2 == eOrtho_B) || (btype2 == eOrtho_C) - || (btype2 == eModified_B) || (btype2 == eModified_C)) + || (btype2 == eModified_B) || (btype2 == eModified_C) + || (btype2 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, - "Basis 2 cannot be of type Ortho_B, Ortho_C, Modified_B " - "or Modified_C"); + "Basis 2 cannot be of type Ortho_B, Ortho_C, Modified_B, " + "Modified_C or ModifiedPyr_C"); } if((btype3 == eOrtho_A) || (btype3 == eOrtho_B) - || (btype3 == eModified_A) || (btype3 == eModified_B)) + || (btype3 == eModified_A) || (btype3 == eModified_B) + || (btype3 == eModified_C)) { NEKERROR(ErrorUtil::efatal, - "Basis 3 cannot be of type Ortho_A, Ortho_B, Modified_A " - "or Modified_B"); + "Basis 3 cannot be of type Ortho_A, Ortho_B, Modified_A, " + "Modified_B or ModifiedPyr_C"); } break; case LibUtilities::ePrism: diff --git a/library/Demos/LocalRegions/LocProject_Diff3D.cpp b/library/Demos/LocalRegions/LocProject_Diff3D.cpp index 7948d7d8c..2e290d54c 100644 --- a/library/Demos/LocalRegions/LocProject_Diff3D.cpp +++ b/library/Demos/LocalRegions/LocProject_Diff3D.cpp @@ -104,10 +104,12 @@ int main(int argc, char *argv[]){ fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); fprintf(stderr,"\t Modified_C = 6\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Legendre = 9\n"); - fprintf(stderr,"\t Chebyshev = 10\n"); + fprintf(stderr,"\t OrthoPyr_C = 7\n"); + fprintf(stderr,"\t ModifiedPyr_C = 8\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Legendre = 11\n"); + fprintf(stderr,"\t Chebyshev = 12\n"); exit(1); } @@ -136,21 +138,24 @@ int main(int argc, char *argv[]){ { case LibUtilities::eTetrahedron: if((btype1 == eOrtho_B) || (btype1 == eOrtho_C) - || (btype1 == eModified_B) || (btype1 == eModified_C)) + || (btype1 == eModified_B) || (btype1 == eModified_C) + || (btype1 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, "Basis 1 cannot be of type Ortho_B, " "Ortho_C, Modified_B or Modified_C"); } if((btype2 == eOrtho_A) || (btype2 == eOrtho_C) - || (btype2 == eModified_A) || (btype2 == eModified_C)) + || (btype2 == eModified_A) || (btype2 == eModified_C) + || (btype1 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, "Basis 2 cannot be of type Ortho_A, " "Ortho_C, Modified_A or Modified_C"); } if((btype3 == eOrtho_A) || (btype3 == eOrtho_B) - || (btype3 == eModified_A) || (btype3 == eModified_B)) + || (btype3 == eModified_A) || (btype3 == eModified_B) + || (btype1 == eModified_C)) { NEKERROR(ErrorUtil::efatal, "Basis 3 cannot be of type Ortho_A, " @@ -159,21 +164,24 @@ int main(int argc, char *argv[]){ break; case LibUtilities::ePyramid: if((btype1 == eOrtho_B) || (btype1 == eOrtho_C) - || (btype1 == eModified_B) || (btype1 == eModified_C)) + || (btype1 == eModified_B) || (btype1 == eModified_C) + || (btype1 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, "Basis 1 cannot be of type Ortho_B, " "Ortho_C, Modified_B or Modified_C"); } if((btype2 == eOrtho_B) || (btype2 == eOrtho_C) - || (btype2 == eModified_B) || (btype2 == eModified_C)) + || (btype2 == eModified_B) || (btype2 == eModified_C) + || (btype1 == eModifiedPyr_C)) { NEKERROR(ErrorUtil::efatal, "Basis 2 cannot be of type Ortho_B, " "Ortho_C, Modified_B or Modified_C"); } if((btype3 == eOrtho_A) || (btype3 == eOrtho_B) - || (btype3 == eModified_A) || (btype3 == eModified_B)) + || (btype3 == eModified_A) || (btype3 == eModified_B) + || (btype1 == eModified_C)) { NEKERROR(ErrorUtil::efatal, "Basis 3 cannot be of type Ortho_A, " diff --git a/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst index ceb3bea75..63effdf09 100644 --- a/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst @@ -5,10 +5,10 @@ 8 8 8 8 6 6 6 7 7 7 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 - 1.7955e-14 + 3.83739e-11 - 8.81073e-13 + 9.15321e-11 diff --git a/library/Demos/LocalRegions/Tests/LocProject3D_Pyr_Mod_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject3D_Pyr_Mod_Basis_P6_Q7.tst index 040db5484..9298084a7 100644 --- a/library/Demos/LocalRegions/Tests/LocProject3D_Pyr_Mod_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject3D_Pyr_Mod_Basis_P6_Q7.tst @@ -2,13 +2,13 @@ Project3D Pyramid Modified basis P=6 Q=7 LocProject3D - 6 4 4 6 6 6 6 7 7 6 0 0 0 1 0 0 1 1 0 0 1 0 0.5 0.5 0.866 + 6 4 4 8 6 6 6 7 7 6 0 0 0 1 0 0 1 1 0 0 1 0 0.5 0.5 0.866 - 1.80317e-12 + 1.15445e-12 - 1.20881e-11 + 8.91376e-12 diff --git a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst index 119a70346..6bed10434 100644 --- a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst @@ -5,10 +5,10 @@ 4 8 8 6 6 7 7 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 - 6.14629e-14 + 1.82817e-12 - 4.83169e-13 + 4.12292e-12 diff --git a/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Pyr_Mod_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Pyr_Mod_Basis_P6_Q7.tst index 5ff49b888..0e4218d0a 100644 --- a/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Pyr_Mod_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Pyr_Mod_Basis_P6_Q7.tst @@ -2,13 +2,13 @@ LocProject_Diff3D Reg. Prism Modified Basis, P=6, Q=7 LocProject_Diff3D - 6 4 4 6 6 6 6 7 7 6 0 0 0 1 0 0 1 1 0 0 1 0 0.5 0 1 0.5 0.5 0.866 + 6 4 4 8 6 6 6 7 7 6 0 0 0 1 0 0 1 1 0 0 1 0 0.5 0 1 0.5 0.5 0.866 - 5.9107e-12 + 4.64852e-12 - 3.81348e-11 + 2.413e-11 -- GitLab From 5cb1a2f7af75947b8857022454736af579f7f7a5 Mon Sep 17 00:00:00 2001 From: ssherw Date: Tue, 14 Mar 2017 11:32:51 +0000 Subject: [PATCH 07/27] Updated Asserts to check for ModifiedPyr_C definition --- library/MultiRegions/AssemblyMap/AssemblyMapCG.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/MultiRegions/AssemblyMap/AssemblyMapCG.cpp b/library/MultiRegions/AssemblyMap/AssemblyMapCG.cpp index 390be6f2f..7d26a85bc 100644 --- a/library/MultiRegions/AssemblyMap/AssemblyMapCG.cpp +++ b/library/MultiRegions/AssemblyMap/AssemblyMapCG.cpp @@ -1359,8 +1359,9 @@ namespace Nektar { ASSERTL0( (exp->GetEdgeBasisType(j) == LibUtilities::eModified_A) || (exp->GetEdgeBasisType(j) == LibUtilities::eModified_B) || - (exp->GetEdgeBasisType(j) == LibUtilities::eModified_C), - "CG with variable order only available with modal expansion"); + (exp->GetEdgeBasisType(j) == LibUtilities::eModified_C) || + (exp->GetEdgeBasisType(j) == LibUtilities::eModifiedPyr_C), + "CG with variable order only available with modal expansion"); } dofs[1][exp->GetGeom()->GetEid(j)] = min(dofs[1][exp->GetGeom()->GetEid(j)], -- GitLab From 18659d42233643c5a4437379eff574d968d69c72 Mon Sep 17 00:00:00 2001 From: ssherw Date: Thu, 16 Mar 2017 18:18:19 +0000 Subject: [PATCH 08/27] Updates to add in SVV capability to Pyramids using the modified expansion. This also required the introduction of IProductWRTDerivBasis into PyrExp.cpp. A regression test was also included --- library/Demos/StdRegions/StdProject3D.cpp | 17 +- library/LibUtilities/Foundations/Basis.cpp | 33 ++- library/LocalRegions/PyrExp.cpp | 235 +++++++++++++++++- library/LocalRegions/PyrExp.h | 18 ++ library/SpatialDomains/MeshGraph.cpp | 2 +- library/StdRegions/StdPyrExp.cpp | 139 ++++++++++- library/StdRegions/StdPyrExp.h | 10 + solvers/IncNavierStokesSolver/CMakeLists.txt | 1 + .../Tests/Pyr_channel_SVV.tst | 24 ++ .../Tests/Pyr_channel_SVV.xml | 167 +++++++++++++ 10 files changed, 626 insertions(+), 20 deletions(-) create mode 100644 solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst create mode 100644 solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.xml diff --git a/library/Demos/StdRegions/StdProject3D.cpp b/library/Demos/StdRegions/StdProject3D.cpp index 35425bc3e..aec8eed86 100644 --- a/library/Demos/StdRegions/StdProject3D.cpp +++ b/library/Demos/StdRegions/StdProject3D.cpp @@ -335,6 +335,21 @@ int main(int argc, char *argv[]){ E = F; E->GetCoords(x,y,z); + const LibUtilities::BasisKey OBkey1(eModified_A,order1,Pkey1); + const LibUtilities::BasisKey OBkey2(eModified_A,order2,Pkey2); + const LibUtilities::BasisKey OBkey3(eModifiedPyr_C,order3,Pkey3); + + StdRegions::StdPyrExp *F1 = new StdRegions::StdPyrExp(OBkey1,OBkey2,OBkey3); + + Array coeffs1(order1*order2*order3,0.0); + coeffs1[0] = 0.0; + coeffs1[4] = 1.0; + F1->BwdTrans(coeffs1,sol); + + E->FwdTrans(sol,coeffs1); + E->BwdTrans(coeffs1,sol); + + //---------------------------------------------- // Define solution to be projected for(i = 0; i < nq1*nq2*nq3; ++i) @@ -486,7 +501,7 @@ NekDouble Pyr_sol(NekDouble x, NekDouble y, NekDouble z, { for(l = 0; l < order2-k; ++l) { - for(m = 0; m < order3-k-l; ++m) + for(m = 0; m < order3-k-l-1; ++m) { sol += pow(x,k)*pow(y,l)*pow(z,m); } diff --git a/library/LibUtilities/Foundations/Basis.cpp b/library/LibUtilities/Foundations/Basis.cpp index 615295e7c..a74874ccf 100644 --- a/library/LibUtilities/Foundations/Basis.cpp +++ b/library/LibUtilities/Foundations/Basis.cpp @@ -289,7 +289,7 @@ namespace Nektar /** \brief Orthogonal basis C - \f$\tilde \psi_{pqr}^c = \left ( {1 - \eta_3} \over 2 \right)^{p+q} P_r^{2p+2q+2, 0}(\eta_3)\f$ \\ + \f$\tilde \psi_{pqr}^c = \left ( {1 - \eta_3} \over 2 \right)^{p+q} P_r^{2p+2q+2, 0}(\eta_3)\f$ \ \ */ @@ -329,15 +329,13 @@ namespace Nektar break; /** \brief Orthogonal basis C for Pyramid expansion (which is richer than tets) - - \f$\tilde \psi_{pqr}^c = \left ( {1 - \eta_3} \over 2 \right)^{p+q} P_r^{2p+2q+2, 0}(\eta_3)\f$ \\ - - */ - - // This is tilde psi_pqr in Spen's book, page 105 - // The 4-dimensional array is laid out in memory such that - // 1) Eta_z values are the changing the fastest, then r, q, and finally p. - // 2) r index increases by the stride of numPoints. + + \f$\tilde \psi_{pqr}^c = \left ( {1 - \eta_3} \over 2\right)^{pq} P_r^{2pq+2, 0}(\eta_3)\f$ + \f$ \mbox{where }pq = max(p+q-1,0) \f$ + + */ + // 1) Eta_z values are the changing the fastest, then r, q, and finally p. + // 2) r index increases by the stride of numPoints. case eOrthoPyr_C: { int P = numModes - 1, Q = numModes - 1, R = numModes - 1; @@ -349,14 +347,23 @@ namespace Nektar { for( int r = 0; r <= R - max(p,q); ++r, mode += numPoints ) { - Polylib::jacobfd(numPoints, z.data(), mode, NULL, r, 2*p + 2*q + 2.0, 0.0); + // this offset allows for orthogonal + // expansion to span linear FE space + // of modified basis but means that + // the cartesian polynomial space + // spanned by the expansion is one + // order lower. + //int pq = max(p + q -1,0); + int pq = max(p + q,0); + + Polylib::jacobfd(numPoints, z.data(), mode, NULL, r, 2*pq + 2.0, 0.0); for( int k = 0; k < numPoints; ++k ) { // Note factor of 0.5 is part of normalisation - mode[k] *= pow(0.5*(1.0 - z[k]), p+q); + mode[k] *= pow(0.5*(1.0 - z[k]), pq); // finish normalisation - mode[k] *= sqrt(r+p+q+1.5); + mode[k] *= sqrt(r+pq+1.5); } } } diff --git a/library/LocalRegions/PyrExp.cpp b/library/LocalRegions/PyrExp.cpp index 400626292..9c94b138e 100644 --- a/library/LocalRegions/PyrExp.cpp +++ b/library/LocalRegions/PyrExp.cpp @@ -273,6 +273,51 @@ namespace Nektar * \sum_{k=0}^{nq_0} \psi_{p}^a (\xi_{3k}) g_{pq} (\xi_{3k}) = {\bf * B_1 G} \f$ */ + + void PyrExp::v_IProductWRTBase( + const Array& inarray, + Array& outarray) + { + v_IProductWRTBase_SumFac(inarray, outarray); + } + + void PyrExp::v_IProductWRTBase_SumFac( + const Array& inarray, + Array& outarray, + bool multiplybyweights) + { + const int nquad0 = m_base[0]->GetNumPoints(); + const int nquad1 = m_base[1]->GetNumPoints(); + const int nquad2 = m_base[2]->GetNumPoints(); + const int order0 = m_base[0]->GetNumModes(); + const int order1 = m_base[1]->GetNumModes(); + + Array wsp(order0*nquad2*(nquad1+order1)); + + if(multiplybyweights) + { + Array tmp(nquad0*nquad1*nquad2); + + MultiplyByQuadratureMetric(inarray, tmp); + + IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(), + m_base[1]->GetBdata(), + m_base[2]->GetBdata(), + tmp,outarray,wsp, + true,true,true); + } + else + { + IProductWRTBase_SumFacKernel(m_base[0]->GetBdata(), + m_base[1]->GetBdata(), + m_base[2]->GetBdata(), + inarray,outarray,wsp, + true,true,true); + } + } + + +#if 0 void PyrExp::v_IProductWRTBase( const Array &inarray, Array &outarray) @@ -295,8 +340,165 @@ namespace Nektar StdPyrExp::v_IProductWRTBase(tmp,outarray); } - +#endif + + + + /** + * @brief Calculates the inner product \f$ I_{pqr} = (u, + * \partial_{x_i} \phi_{pqr}) \f$. + * + * The derivative of the basis functions is performed using the chain + * rule in order to incorporate the geometric factors. Assuming that + * the basis functions are a tensor product + * \f$\phi_{pqr}(\eta_1,\eta_2,\eta_3) = + * \phi_1(\eta_1)\phi_2(\eta_2)\phi_3(\eta_3)\f$, this yields the + * result + * + * \f[ + * I_{pqr} = \sum_{j=1}^3 \left(u, \frac{\partial u}{\partial \eta_j} + * \frac{\partial \eta_j}{\partial x_i}\right) + * \f] + * + * In the pyramid element, we must also incorporate a second set + * of geometric factors which incorporate the collapsed co-ordinate + * system, so that + * + * \f[ \frac{\partial\eta_j}{\partial x_i} = \sum_{k=1}^3 + * \frac{\partial\eta_j}{\partial\xi_k}\frac{\partial\xi_k}{\partial + * x_i} \f] + * + * These derivatives can be found on p152 of Sherwin & Karniadakis. + * + * @param dir Direction in which to take the derivative. + * @param inarray The function \f$ u \f$. + * @param outarray Value of the inner product. + */ + void PyrExp::v_IProductWRTDerivBase( + const int dir, + const Array &inarray, + Array &outarray) + { + v_IProductWRTDerivBase_SumFac(dir, inarray, outarray); + } + + void PyrExp::v_IProductWRTDerivBase_SumFac( + const int dir, + const Array &inarray, + Array &outarray) + { + const int nquad0 = m_base[0]->GetNumPoints(); + const int nquad1 = m_base[1]->GetNumPoints(); + const int nquad2 = m_base[2]->GetNumPoints(); + const int order0 = m_base[0]->GetNumModes (); + const int order1 = m_base[1]->GetNumModes (); + const int nqtot = nquad0*nquad1*nquad2; + int i; + + const Array &z0 = m_base[0]->GetZ(); + const Array &z1 = m_base[1]->GetZ(); + const Array &z2 = m_base[2]->GetZ(); + + Array gfac0(nquad0 ); + Array gfac1(nquad1 ); + Array gfac2(nquad2 ); + Array tmp1 (nqtot ); + Array tmp2 (nqtot ); + Array tmp3 (nqtot ); + Array tmp4 (nqtot ); + Array tmp5 (nqtot ); + Array tmp6 (m_ncoeffs); + Array wsp (std::max(nqtot,order0*nquad2*(nquad1+order1))); + + const Array& df = + m_metricinfo->GetDerivFactors(GetPointsKeys()); + + MultiplyByQuadratureMetric(inarray, tmp1); + + if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed) + { + Vmath::Vmul(nqtot,&df[3*dir][0], 1,tmp1.get(),1,tmp2.get(),1); + Vmath::Vmul(nqtot,&df[3*dir+1][0],1,tmp1.get(),1,tmp3.get(),1); + Vmath::Vmul(nqtot,&df[3*dir+2][0],1,tmp1.get(),1,tmp4.get(),1); + } + else + { + Vmath::Smul(nqtot, df[3*dir][0], tmp1.get(),1,tmp2.get(), 1); + Vmath::Smul(nqtot, df[3*dir+1][0],tmp1.get(),1,tmp3.get(), 1); + Vmath::Smul(nqtot, df[3*dir+2][0],tmp1.get(),1,tmp4.get(), 1); + } + + // set up geometric factor: (1+z0)/2 + for (i = 0; i < nquad0; ++i) + { + gfac0[i] = 0.5*(1+z0[i]); + } + + // set up geometric factor: (1+z1)/2 + for(i = 0; i < nquad1; ++i) + { + gfac1[i] = 0.5*(1+z1[i]); + } + + // Set up geometric factor: 2/(1-z2) + for (i = 0; i < nquad2; ++i) + { + gfac2[i] = 2.0/(1-z2[i]); + } + + const int nq01 = nquad0*nquad1; + + for (i = 0; i < nquad2; ++i) + { + Vmath::Smul(nq01,gfac2[i],&tmp2[0]+i*nq01,1,&tmp2[0]+i*nq01,1); // 2/(1-z2) for d/dxi_0 + Vmath::Smul(nq01,gfac2[i],&tmp3[0]+i*nq01,1,&tmp3[0]+i*nq01,1); // 2/(1-z2) for d/dxi_1 + Vmath::Smul(nq01,gfac2[i],&tmp4[0]+i*nq01,1,&tmp5[0]+i*nq01,1); // 2/(1-z2) for d/dxi_2 + } + + // (1+z0)/(1-z2) for d/d eta_0 + for(i = 0; i < nquad1*nquad2; ++i) + { + Vmath::Vmul(nquad0,&gfac0[0],1, + &tmp5[0]+i*nquad0,1, + &wsp[0]+i*nquad0,1); + } + Vmath::Vadd(nqtot, &tmp2[0], 1, &wsp[0], 1, &tmp2[0], 1); + + // (1+z1)/(1-z2) for d/d eta_1 + for(i = 0; i < nquad1*nquad2; ++i) + { + Vmath::Smul(nquad0,gfac1[i%nquad1], + &tmp5[0]+i*nquad0,1, + &tmp5[0]+i*nquad0,1); + } + Vmath::Vadd(nqtot, &tmp3[0], 1, &tmp5[0], 1, &tmp3[0], 1); + + + IProductWRTBase_SumFacKernel(m_base[0]->GetDbdata(), + m_base[1]->GetBdata (), + m_base[2]->GetBdata (), + tmp2,outarray,wsp, + false,true,true); + + IProductWRTBase_SumFacKernel(m_base[0]->GetBdata (), + m_base[1]->GetDbdata(), + m_base[2]->GetBdata (), + tmp3,tmp6,wsp, + true,false,true); + + Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1); + + IProductWRTBase_SumFacKernel(m_base[0]->GetBdata (), + m_base[1]->GetBdata (), + m_base[2]->GetDbdata(), + tmp4,tmp6,wsp, + true,true,false); + + Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1); + } + + //--------------------------------------- // Evaluation functions //--------------------------------------- @@ -743,6 +945,36 @@ namespace Nektar } } + void PyrExp::v_SVVLaplacianFilter( + Array &array, + const StdRegions::StdMatrixKey &mkey) + { + int nq = GetTotPoints(); + + // Calculate sqrt of the Jacobian + Array jac = + m_metricinfo->GetJac(GetPointsKeys()); + Array sqrt_jac(nq); + if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed) + { + Vmath::Vsqrt(nq,jac,1,sqrt_jac,1); + } + else + { + Vmath::Fill(nq,sqrt(jac[0]),sqrt_jac,1); + } + + // Multiply array by sqrt(Jac) + Vmath::Vmul(nq,sqrt_jac,1,array,1,array,1); + + // Apply std region filter + StdPyrExp::v_SVVLaplacianFilter( array, mkey); + + // Divide by sqrt(Jac) + Vmath::Vdiv(nq,array,1,sqrt_jac,1,array,1); + } + + //--------------------------------------- // Matrix creation functions //--------------------------------------- @@ -1027,7 +1259,6 @@ namespace Nektar returnval->SetBlock(0,1,Atmp = MemoryManager::AllocateSharedPtr(one,B)); returnval->SetBlock(1,0,Atmp = MemoryManager::AllocateSharedPtr(factor,C)); returnval->SetBlock(1,1,Atmp = MemoryManager::AllocateSharedPtr(invfactor,D)); - } } return returnval; diff --git a/library/LocalRegions/PyrExp.h b/library/LocalRegions/PyrExp.h index 4c02c5108..dc536e1ab 100644 --- a/library/LocalRegions/PyrExp.h +++ b/library/LocalRegions/PyrExp.h @@ -96,6 +96,18 @@ namespace Nektar LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( const Array& inarray, Array& outarray); + LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + const Array& inarray, + Array& outarray, + bool multiplybyweights = true); + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase( + const int dir, + const Array& inarray, + Array& outarray); + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( + const int dir, + const Array& inarray, + Array& outarray); //--------------------------------------- @@ -131,6 +143,12 @@ namespace Nektar Array &outarray); LOCAL_REGIONS_EXPORT void v_ComputeFaceNormal(const int face); + + + LOCAL_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( + Array &array, + const StdRegions::StdMatrixKey &mkey); + //--------------------------------------- // Matrix creation functions //--------------------------------------- diff --git a/library/SpatialDomains/MeshGraph.cpp b/library/SpatialDomains/MeshGraph.cpp index 8076e07a4..84725366c 100644 --- a/library/SpatialDomains/MeshGraph.cpp +++ b/library/SpatialDomains/MeshGraph.cpp @@ -3305,7 +3305,7 @@ namespace Nektar returnval.push_back(bkey); returnval.push_back(bkey); - const LibUtilities::PointsKey pkey1(nummodes+quadoffset-1, LibUtilities::eGaussRadauMAlpha2Beta0); + const LibUtilities::PointsKey pkey1(nummodes+quadoffset, LibUtilities::eGaussRadauMAlpha2Beta0); LibUtilities::BasisKey bkey1(LibUtilities::eModifiedPyr_C, nummodes, pkey1); returnval.push_back(bkey1); } diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index 7874cd54f..b2558cea6 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -420,8 +420,7 @@ namespace Nektar int order0 = m_base[0]->GetNumModes(); int order1 = m_base[1]->GetNumModes(); - Array wsp(nquad1*nquad2*order0 + - nquad2*order0*order1); + Array wsp(order0*nquad1*(nquad2 + order1)); if(multiplybyweights) { @@ -1789,7 +1788,7 @@ namespace Nektar const int Q = m_base[1]->GetNumModes()-1; const int R = m_base[2]->GetNumModes()-1; - int i,j,l; + int i,l; int cnt = 0; // Traverse to q-r plane number I @@ -1869,5 +1868,139 @@ namespace Nektar break; } } + + + void StdPyrExp::v_SVVLaplacianFilter(Array &array, + const StdMatrixKey &mkey) + { + // Generate an orthonogal expansion + int qa = m_base[0]->GetNumPoints(); + int qb = m_base[1]->GetNumPoints(); + int qc = m_base[2]->GetNumPoints(); + int nmodes_a = m_base[0]->GetNumModes(); + int nmodes_b = m_base[1]->GetNumModes(); + int nmodes_c = m_base[2]->GetNumModes(); + // Declare orthogonal basis. + LibUtilities::PointsKey pa(qa,m_base[0]->GetPointsType()); + LibUtilities::PointsKey pb(qb,m_base[1]->GetPointsType()); + LibUtilities::PointsKey pc(qc,m_base[2]->GetPointsType()); + + LibUtilities::BasisKey Ba(LibUtilities::eOrtho_A,nmodes_a,pa); + LibUtilities::BasisKey Bb(LibUtilities::eOrtho_A,nmodes_b,pb); + LibUtilities::BasisKey Bc(LibUtilities::eOrthoPyr_C,nmodes_c,pc); + StdPyrExp OrthoExp(Ba,Bb,Bc); + + Array orthocoeffs(OrthoExp.GetNcoeffs()); + int i,j,k,cnt = 0; + + //SVV filter paramaters (how much added diffusion relative to physical one + // and fraction of modes from which you start applying this added diffusion) + // + NekDouble SvvDiffCoeff = mkey.GetConstFactor(StdRegions::eFactorSVVDiffCoeff); + NekDouble SVVCutOff = mkey.GetConstFactor(StdRegions::eFactorSVVCutoffRatio); + + //Defining the cut of mode + int cutoff_a = (int) (SVVCutOff*nmodes_a); + int cutoff_b = (int) (SVVCutOff*nmodes_b); + int cutoff_c = (int) (SVVCutOff*nmodes_c); + //To avoid the fac[j] from blowing up + NekDouble epsilon = 1; + + // project onto modal space. + OrthoExp.FwdTrans(array,orthocoeffs); + int nmodes = min(min(nmodes_a,nmodes_b),nmodes_c); + NekDouble cutoff = min(min(cutoff_a,cutoff_b),cutoff_c); + + for(i = 0; i < nmodes_a; ++i)//P + { + for(j = 0; j < nmodes_b; ++j) //Q + { + int maxij = max(i,j); + for(k = 0; k < nmodes_c-maxij; ++k) //R + { + if(j + k >= cutoff || i + k >= cutoff) + { + orthocoeffs[cnt] *= (SvvDiffCoeff*exp(-(i+k-nmodes)*(i+k-nmodes)/((NekDouble)((i+k-cutoff+epsilon)*(i+k-cutoff+epsilon))))*exp(-(j-nmodes)*(j-nmodes)/((NekDouble)((j-cutoff+epsilon)*(j-cutoff+epsilon))))); + } + else + { + orthocoeffs[cnt] *= 0.0; + } + cnt++; + } + } + } + + // backward transform to physical space + OrthoExp.BwdTrans(orthocoeffs,array); + } + + + + void StdPyrExp::v_ReduceOrderCoeffs( + int numMin, + const Array &inarray, + Array &outarray) + { + int nquad0 = m_base[0]->GetNumPoints(); + int nquad1 = m_base[1]->GetNumPoints(); + int nquad2 = m_base[2]->GetNumPoints(); + int nqtot = nquad0*nquad1*nquad2; + int nmodes0 = m_base[0]->GetNumModes(); + int nmodes1 = m_base[1]->GetNumModes(); + int nmodes2 = m_base[2]->GetNumModes(); + int numMax = nmodes0; + + Array coeff (m_ncoeffs); + Array coeff_tmp1(m_ncoeffs, 0.0); + Array phys_tmp (nqtot, 0.0); + Array tmp, tmp2, tmp3, tmp4; + + + const LibUtilities::PointsKey Pkey0 = m_base[0]->GetPointsKey(); + const LibUtilities::PointsKey Pkey1 = m_base[1]->GetPointsKey(); + const LibUtilities::PointsKey Pkey2 = m_base[2]->GetPointsKey(); + + LibUtilities::BasisKey bortho0( + LibUtilities::eOrtho_A, nmodes0, Pkey0); + LibUtilities::BasisKey bortho1( + LibUtilities::eOrtho_A, nmodes1, Pkey1); + LibUtilities::BasisKey bortho2( + LibUtilities::eOrthoPyr_C, nmodes2, Pkey2); + + int cnt = 0; + int u = 0; + int i = 0; + StdRegions::StdPyrExpSharedPtr OrthoPyrExp; + + OrthoPyrExp = MemoryManager + ::AllocateSharedPtr(bortho0, bortho1, bortho2); + + BwdTrans(inarray,phys_tmp); + OrthoPyrExp->FwdTrans(phys_tmp, coeff); + + // filtering + for (u = 0; u < numMin; ++u) + { + for (i = 0; i < numMin; ++i) + { + + int maxui = max(u,i); + Vmath::Vcopy(numMin - maxui, tmp = coeff + cnt, 1, + tmp2 = coeff_tmp1 + cnt, 1); + cnt += nmodes2 - maxui; + } + + for (i = numMin; i < nmodes1; ++i) + { + int maxui = max(u,i); + cnt += numMax - maxui; + } + } + + OrthoPyrExp->BwdTrans(coeff_tmp1, phys_tmp); + StdPyrExp::FwdTrans(phys_tmp, outarray); + } + } } diff --git a/library/StdRegions/StdPyrExp.h b/library/StdRegions/StdPyrExp.h index 62891dc28..404052cc2 100644 --- a/library/StdRegions/StdPyrExp.h +++ b/library/StdRegions/StdPyrExp.h @@ -251,6 +251,16 @@ namespace Nektar STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( const StdMatrixKey &mkey); + STD_REGIONS_EXPORT virtual void v_SVVLaplacianFilter(Array &array, + const StdMatrixKey &mkey); + + //--------------------------------------- + // Method for applying sensors + //--------------------------------------- + STD_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + int numMin, + const Array &inarray, + Array &outarray); private: //--------------------------------------- // Private helper functions diff --git a/solvers/IncNavierStokesSolver/CMakeLists.txt b/solvers/IncNavierStokesSolver/CMakeLists.txt index cc6e70f40..95fbc441d 100644 --- a/solvers/IncNavierStokesSolver/CMakeLists.txt +++ b/solvers/IncNavierStokesSolver/CMakeLists.txt @@ -58,6 +58,7 @@ IF( NEKTAR_SOLVER_INCNAVIERSTOKES ) ADD_NEKTAR_TEST(Hex_channel_varP) ADD_NEKTAR_TEST(Pyr_channel_m3) ADD_NEKTAR_TEST(Pyr_channel_varP) + ADD_NEKTAR_TEST(Pyr_channel_SVV) ADD_NEKTAR_TEST(Hex_channel_m6_nodalRestart) ADD_NEKTAR_TEST_LENGTHY(Hex_channel_m8) ADD_NEKTAR_TEST_LENGTHY(Hex_channel_m8_srhs) diff --git a/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst b/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst new file mode 100644 index 000000000..1d8e22859 --- /dev/null +++ b/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst @@ -0,0 +1,24 @@ + + + 3D channel flow, Pyramidic elements, using SVV + IncNavierStokesSolver + Pyr_channel_SVV.xml + + Pyr_channel_SVV.xml + + + + 2.6682e-10 + 2.67015e-10 + 1.15296e-09 + 2.8591e-08 + + + 1.838e-09 + 1.90318e-09 + 1.42728e-08 + 1.0353e-06 + + + + diff --git a/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.xml b/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.xml new file mode 100644 index 000000000..1a9de7c28 --- /dev/null +++ b/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + +

TimeStep = 0.001

+

NumSteps = 50

+

IO_InfoSteps = 100

+

Kinvis = 1

+

SVVCutOffRatio = 0.0

+

SVVDiffCoeff = 1

+
+ + + u + v + w + p + + + + C[1] + C[6] + C[2] + C[3] + C[4] + C[5] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + 0.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 + 5.00000000e-01 5.00000000e-01 5.00000000e-01 + 0.00000000e+00 0.00000000e+00 1.00000000e+00 + 1.00000000e+00 0.00000000e+00 1.00000000e+00 + 1.00000000e+00 1.00000000e+00 1.00000000e+00 + 0.00000000e+00 1.00000000e+00 1.00000000e+00 + + + 0 1 + 1 2 + 3 2 + 0 3 + 0 4 + 1 4 + 2 4 + 3 4 + 0 5 + 5 6 + 1 6 + 5 4 + 6 4 + 6 7 + 2 7 + 7 4 + 7 8 + 3 8 + 8 4 + 8 5 + + + 0 1 2 3 + 0 5 4 + 1 6 5 + 2 6 7 + 3 7 4 + 8 9 10 0 + 8 11 4 + 9 12 11 + 10 12 5 + 10 13 14 1 + 13 15 12 + 14 15 6 + 14 16 17 2 + 16 18 15 + 17 18 7 + 17 19 8 3 + 19 11 18 + 19 16 13 9 + + +

0 1 2 3 4

+

5 6 7 8 1

+

9 8 10 11 2

+

12 11 13 14 3

+

15 14 16 6 4

+

17 16 13 10 7

+
+ + P[0-5] + F[0] + F[5] + F[9] + F[12] + F[15] + F[17] + + C[0] +
+
-- GitLab From 7dc15c2908eff8e8688cc5f94bfd36181539d0a9 Mon Sep 17 00:00:00 2001 From: ssherw Date: Thu, 16 Mar 2017 18:20:18 +0000 Subject: [PATCH 09/27] Removed debugging code --- library/Demos/StdRegions/StdProject3D.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/library/Demos/StdRegions/StdProject3D.cpp b/library/Demos/StdRegions/StdProject3D.cpp index aec8eed86..231a0e95c 100644 --- a/library/Demos/StdRegions/StdProject3D.cpp +++ b/library/Demos/StdRegions/StdProject3D.cpp @@ -335,21 +335,6 @@ int main(int argc, char *argv[]){ E = F; E->GetCoords(x,y,z); - const LibUtilities::BasisKey OBkey1(eModified_A,order1,Pkey1); - const LibUtilities::BasisKey OBkey2(eModified_A,order2,Pkey2); - const LibUtilities::BasisKey OBkey3(eModifiedPyr_C,order3,Pkey3); - - StdRegions::StdPyrExp *F1 = new StdRegions::StdPyrExp(OBkey1,OBkey2,OBkey3); - - Array coeffs1(order1*order2*order3,0.0); - coeffs1[0] = 0.0; - coeffs1[4] = 1.0; - F1->BwdTrans(coeffs1,sol); - - E->FwdTrans(sol,coeffs1); - E->BwdTrans(coeffs1,sol); - - //---------------------------------------------- // Define solution to be projected for(i = 0; i < nq1*nq2*nq3; ++i) -- GitLab From 231f989df81af06b6ac61de9b8a2e36f6509476f Mon Sep 17 00:00:00 2001 From: ssherw Date: Thu, 16 Mar 2017 18:55:01 +0000 Subject: [PATCH 10/27] Updaed change log --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4fc01577..f2fbd9bdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ v4.5.0 **NekMesh**: - Adjust boundary layer thickness in corners in 2D (!739) +**Library** +- Added in sum factorisation version for pyramid expnasions and orthogonal expansion in pyramids (!750) + v4.4.0 ------ **Library**: -- GitLab From 7582e5f173ec39a750efc558212bb84377167caa Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 18 Mar 2017 10:30:13 +0000 Subject: [PATCH 11/27] Updated the StdRegions demos and regression tests to be consistent with new numbering of Basis Types --- library/Demos/StdRegions/StdProject1D.cpp | 16 ++++----- library/Demos/StdRegions/StdProject2D.cpp | 13 +++---- library/Demos/StdRegions/StdProject3D.cpp | 35 +++++++------------ .../Demos/StdRegions/StdProject_Diff1D.cpp | 16 ++++----- .../Demos/StdRegions/StdProject_Diff3D.cpp | 35 ++++++++++++------- ...oject2D_Quad_Fourier_Single_Mode_P2_Q6.tst | 4 +-- .../StdProject2D_Quad_Lagrange_P6_Q7.tst | 2 +- .../Tests/StdProject2D_Tri_Nodal_P6_Q7.tst | 2 +- .../StdProject3D_Hex_Chebyshev_P6_Q7.tst | 2 +- .../Tests/StdProject3D_Hex_Legendre_P6_Q7.tst | 2 +- .../StdProject_Diff3D_Hex_Chebyshev_P6_Q7.tst | 2 +- .../StdProject_Diff3D_Hex_Legendre_P6_Q7.tst | 2 +- 12 files changed, 67 insertions(+), 64 deletions(-) diff --git a/library/Demos/StdRegions/StdProject1D.cpp b/library/Demos/StdRegions/StdProject1D.cpp index 50073b752..5cf37efb2 100644 --- a/library/Demos/StdRegions/StdProject1D.cpp +++ b/library/Demos/StdRegions/StdProject1D.cpp @@ -26,15 +26,15 @@ int main(int argc, char *argv[]) "dictates the basis as:\n"); fprintf(stderr,"\t Ortho_A = 1\n"); fprintf(stderr,"\t Modified_A = 4\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Monomial = 12\n"); - fprintf(stderr,"\t FourierSingleMode = 13\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 14\n"); + fprintf(stderr,"\t FourierSingleMode = 15\n"); - fprintf(stderr,"Note type = 1,2,4,5 are for higher dimensional basis\n"); + fprintf(stderr,"Note type = 1,2,4,5,7,8 are for higher dimensional basis\n"); exit(1); } diff --git a/library/Demos/StdRegions/StdProject2D.cpp b/library/Demos/StdRegions/StdProject2D.cpp index 1237677d9..c828b8112 100644 --- a/library/Demos/StdRegions/StdProject2D.cpp +++ b/library/Demos/StdRegions/StdProject2D.cpp @@ -56,9 +56,10 @@ int main(int argc, char *argv[]) fprintf(stderr,"\t Gauss Lagrange = 11\n"); fprintf(stderr,"\t Legendre = 12\n"); fprintf(stderr,"\t Chebyshev = 13\n"); - fprintf(stderr,"\t FourierSingleMode = 14\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 15\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 16\n"); + fprintf(stderr,"\t Monomial = 14\n"); + fprintf(stderr,"\t FourierSingleMode = 15\n"); + fprintf(stderr,"\t Nodal tri (Electro) = 18\n"); + fprintf(stderr,"\t Nodal tri (Fekete) = 19\n"); fprintf(stderr,"Note type = 3,6,7,8 are for three-dimensional basis\n"); @@ -77,17 +78,17 @@ int main(int argc, char *argv[]) int btype1_val = atoi(argv[2]); int btype2_val = atoi(argv[3]); - if(( btype1_val <= 14)&&( btype2_val <= 14)) + if(( btype1_val <= 15)&&( btype2_val <= 15)) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; } - else if(( btype1_val >=15)&&(btype2_val <= 16)) + else if(( btype1_val >=18)&&(btype2_val <= 19)) { btype1 = LibUtilities::eOrtho_A; btype2 = LibUtilities::eOrtho_B; - if(btype1_val == 15) + if(btype1_val == 18) { NodalType = LibUtilities::eNodalTriElec; } diff --git a/library/Demos/StdRegions/StdProject3D.cpp b/library/Demos/StdRegions/StdProject3D.cpp index 231a0e95c..8d560e9ce 100644 --- a/library/Demos/StdRegions/StdProject3D.cpp +++ b/library/Demos/StdRegions/StdProject3D.cpp @@ -70,16 +70,15 @@ int main(int argc, char *argv[]){ fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); fprintf(stderr,"\t Modified_C = 6\n"); - fprintf(stderr,"\t Ortho_C = 7\n"); - fprintf(stderr,"\t Modified_C = 8\n"); - - fprintf(stderr,"\t Fourier = 8\n"); - fprintf(stderr,"\t Lagrange = 9\n"); - fprintf(stderr,"\t Gauss Lagrange = 10\n"); - fprintf(stderr,"\t Legendre = 11\n"); - fprintf(stderr,"\t Chebyshev = 12\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 13\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 14\n"); + fprintf(stderr,"\t OrthoPyr_C = 7\n"); + fprintf(stderr,"\t ModifiedPyr_C = 8\n"); + + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 14\n"); fprintf(stderr,"\t Nodal tet (Electro) = 15\n"); fprintf(stderr,"\t Nodal tet (Even) = 16\n"); fprintf(stderr,"\t Nodal prism (Even) = 17\n"); @@ -102,13 +101,13 @@ int main(int argc, char *argv[]){ int btype2_val = atoi(argv[3]); int btype3_val = atoi(argv[4]); - if (btype1_val <= 13 && btype2_val <= 13) + if (btype1_val <= 14 && btype2_val <= 14) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; btype3 = (LibUtilities::BasisType) btype3_val; } - else if(btype1_val >=14 && btype2_val <= 18) + else if(btype1_val >=15 && btype2_val <= 17) { if (regionshape == LibUtilities::eTetrahedron) { @@ -123,19 +122,11 @@ int main(int argc, char *argv[]){ btype3 = LibUtilities::eOrtho_B; } - if(btype1_val == 14) - { - NodalType = LibUtilities::eNodalTriElec; - } - else if (btype1_val == 15) - { - NodalType = LibUtilities::eNodalTriFekete; - } - else if (btype1_val == 16) + if (btype1_val == 15) { NodalType = LibUtilities::eNodalTetElec; } - else if (btype1_val == 17) + else if (btype1_val == 16) { NodalType = LibUtilities::eNodalTetEvenlySpaced; } diff --git a/library/Demos/StdRegions/StdProject_Diff1D.cpp b/library/Demos/StdRegions/StdProject_Diff1D.cpp index 736aaf6ce..4c7d8b1d7 100644 --- a/library/Demos/StdRegions/StdProject_Diff1D.cpp +++ b/library/Demos/StdRegions/StdProject_Diff1D.cpp @@ -26,15 +26,15 @@ int main(int argc, char *argv[]) "dictates the basis as:\n"); fprintf(stderr,"\t Ortho_A = 1\n"); fprintf(stderr,"\t Modified_A = 4\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Monomial = 12\n"); - fprintf(stderr,"\t FourierSingleMode = 13\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 14\n"); + fprintf(stderr,"\t FourierSingleMode = 15\n"); - fprintf(stderr,"Note type = 1,2,4,5 are for higher dimensional basis\n"); + fprintf(stderr,"Note type = 1,2,4,5,7,8 are for higher dimensional basis\n"); exit(1); } diff --git a/library/Demos/StdRegions/StdProject_Diff3D.cpp b/library/Demos/StdRegions/StdProject_Diff3D.cpp index 504c831bd..6d5d7919a 100644 --- a/library/Demos/StdRegions/StdProject_Diff3D.cpp +++ b/library/Demos/StdRegions/StdProject_Diff3D.cpp @@ -89,13 +89,15 @@ int main(int argc, char *argv[]){ fprintf(stderr,"\t Modified_C = 6\n"); fprintf(stderr,"\t OrthoPyr_C = 7\n"); fprintf(stderr,"\t ModifiedPyr_C = 8\n"); - fprintf(stderr,"\t Fourier = 9\n"); - fprintf(stderr,"\t Lagrange = 10\n"); - fprintf(stderr,"\t Gauss Lagrange = 11\n"); - fprintf(stderr,"\t Legendre = 12\n"); - fprintf(stderr,"\t Chebyshev = 13\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 14\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 15\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 14\n"); + fprintf(stderr,"\t Nodal tet (Electro) = 15\n"); + fprintf(stderr,"\t Nodal tet (Even) = 16\n"); + fprintf(stderr,"\t Nodal prism (Even) = 17\n"); exit(1); } @@ -114,17 +116,26 @@ int main(int argc, char *argv[]){ int btype1_val = atoi(argv[2]); int btype2_val = atoi(argv[3]); int btype3_val = atoi(argv[4]); - if(( btype1_val <= 13)&&( btype2_val <= 13)) + if(( btype1_val <= 15)&&( btype2_val <= 15)) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; btype3 = (LibUtilities::BasisType) btype3_val; } - else if(( btype1_val >=14)&&(btype2_val <= 15)) + else if(( btype1_val >=15)&&(btype2_val <= 17)) { - btype1 = LibUtilities::eOrtho_A; - btype2 = LibUtilities::eOrtho_B; - btype3 = LibUtilities::eOrtho_C; + if (regionshape == LibUtilities::eTetrahedron) + { + btype1 = LibUtilities::eOrtho_A; + btype2 = LibUtilities::eOrtho_B; + btype3 = LibUtilities::eOrtho_C; + } + else if (regionshape == LibUtilities::ePrism) + { + btype1 = LibUtilities::eOrtho_A; + btype2 = LibUtilities::eOrtho_A; + btype3 = LibUtilities::eOrtho_B; + } } // Check to see that correct Expansions are used diff --git a/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_Single_Mode_P2_Q6.tst b/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_Single_Mode_P2_Q6.tst index 446bad552..bd3c7eff5 100644 --- a/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_Single_Mode_P2_Q6.tst +++ b/library/Demos/StdRegions/Tests/StdProject2D_Quad_Fourier_Single_Mode_P2_Q6.tst @@ -1,8 +1,8 @@ - StdProject2D Quadrilateral Fourier Single Mode basis P=2 Q=6 + StdProject2D Quadrilateral Fourier Single Mode basis P=2 Q=2 StdProject2D - 4 12 12 2 2 6 6 + 4 15 15 2 2 2 2 3.59678e-16 diff --git a/library/Demos/StdRegions/Tests/StdProject2D_Quad_Lagrange_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject2D_Quad_Lagrange_P6_Q7.tst index 1a491f8a7..a64a66b03 100644 --- a/library/Demos/StdRegions/Tests/StdProject2D_Quad_Lagrange_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject2D_Quad_Lagrange_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject2D Quadrilateral Lagrange basis P=6 Q=7 StdProject2D - 4 8 8 6 6 7 7 + 4 10 10 6 6 7 7 4.62859e-15 diff --git a/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst index 426661fd6..1b50f912d 100644 --- a/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject2D_Tri_Nodal_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject2D Triangle Nodal basis P=6 Q=7 StdProject2D - 3 15 14 6 6 7 7 + 3 18 18 6 6 7 7 1.78107e-15 diff --git a/library/Demos/StdRegions/Tests/StdProject3D_Hex_Chebyshev_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject3D_Hex_Chebyshev_P6_Q7.tst index 28aa55368..26e7f966d 100644 --- a/library/Demos/StdRegions/Tests/StdProject3D_Hex_Chebyshev_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject3D_Hex_Chebyshev_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject3D Hexahedron Chebyshev basis P=6 Q=7 StdProject3D - 8 10 10 10 6 6 6 7 7 7 + 8 13 13 13 6 6 6 7 7 7 4.11256e-14 diff --git a/library/Demos/StdRegions/Tests/StdProject3D_Hex_Legendre_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject3D_Hex_Legendre_P6_Q7.tst index ebb17fab3..0fccab2b0 100644 --- a/library/Demos/StdRegions/Tests/StdProject3D_Hex_Legendre_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject3D_Hex_Legendre_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject3D Hexahedron Legendre basis P=6 Q=7 StdProject3D - 8 10 10 10 6 6 6 7 7 7 + 8 12 12 12 6 6 6 7 7 7 2.20528e-14 diff --git a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Chebyshev_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Chebyshev_P6_Q7.tst index 41fc53974..15adf255a 100644 --- a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Chebyshev_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Chebyshev_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject_Diff3D Hexahedron Chebyshev basis P=6 Q=7 StdProject_Diff3D - 8 10 10 10 6 6 6 7 7 7 + 8 13 13 13 6 6 6 7 7 7 5.62024e-13 diff --git a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Legendre_P6_Q7.tst b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Legendre_P6_Q7.tst index 9fce2b246..af7ef4d22 100644 --- a/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Legendre_P6_Q7.tst +++ b/library/Demos/StdRegions/Tests/StdProject_Diff3D_Hex_Legendre_P6_Q7.tst @@ -2,7 +2,7 @@ StdProject_Diff3D Hexahedron Legendre basis P=6 Q=7 StdProject_Diff3D - 8 10 10 10 6 6 6 7 7 7 + 8 12 12 12 6 6 6 7 7 7 4.88883e-13 -- GitLab From c26b202e3adce63e7b145cadb72cf945c77eefc2 Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 18 Mar 2017 14:39:13 +0000 Subject: [PATCH 12/27] Updated LocRegions regression test to be consistent with new basis list definition --- library/Demos/LocalRegions/LocProject1D.cpp | 16 +++++------ library/Demos/LocalRegions/LocProject2D.cpp | 25 ++++++++--------- .../Demos/LocalRegions/LocProject_Diff1D.cpp | 18 ++++++------- .../Demos/LocalRegions/LocProject_Diff2D.cpp | 27 +++++++++---------- ...roject2D_Def_Quad_Lagrange_Basis_P6_Q7.tst | 2 +- ...LocProject2D_Quad_Lagrange_Basis_P6_Q7.tst | 2 +- .../LocProject2D_Tri_Nodal_Basis_P6_Q7.tst | 2 +- ...Project3D_Def_Hex_Lagrange_Basis_P6_Q7.tst | 2 +- .../LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst | 6 ++--- ...Lin_Deformed_Quad_Lagrange_Basis_P6_Q7.tst | 2 +- ..._Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst | 6 ++--- ...ocProject_Diff2D_Tri_Nodal_Basis_P6_Q7.tst | 2 +- ..._Lin_Deformed_Hex_Lagrange_Basis_P6_Q7.tst | 2 +- ...ct_Diff3D_Reg_Hex_Lagrange_Basis_P6_Q7.tst | 2 +- 14 files changed, 57 insertions(+), 57 deletions(-) diff --git a/library/Demos/LocalRegions/LocProject1D.cpp b/library/Demos/LocalRegions/LocProject1D.cpp index ef237a49a..e7bd76862 100644 --- a/library/Demos/LocalRegions/LocProject1D.cpp +++ b/library/Demos/LocalRegions/LocProject1D.cpp @@ -31,15 +31,15 @@ int main(int argc, char *argv[]) "dictates the basis as:\n"); fprintf(stderr,"\t Ortho_A = 1\n"); fprintf(stderr,"\t Modified_A = 4\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Monomial = 12\n"); - fprintf(stderr,"\t FourierSingleMode = 13\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 14\n"); + fprintf(stderr,"\t FourierSingleMode = 15\n"); - fprintf(stderr,"Note type = 1,2,4,5 are for higher dimensional basis\n"); + fprintf(stderr,"Note type = 1,2,4,5,7,8 are for higher dimensional basis\n"); exit(1); } diff --git a/library/Demos/LocalRegions/LocProject2D.cpp b/library/Demos/LocalRegions/LocProject2D.cpp index caf8bf298..e4bf248bd 100644 --- a/library/Demos/LocalRegions/LocProject2D.cpp +++ b/library/Demos/LocalRegions/LocProject2D.cpp @@ -53,15 +53,16 @@ int main(int argc, char *argv[]) fprintf(stderr,"\t Ortho_B = 2\n"); fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 13\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 14\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 14\n"); + fprintf(stderr,"\t Nodal tri (Electro) = 15\n"); + fprintf(stderr,"\t Nodal tri (Fekete) = 16\n"); - fprintf(stderr,"Note type = 3,6 are for three-dimensional basis\n"); + fprintf(stderr,"Note type = 3,6,7,8 are for three-dimensional basis\n"); fprintf(stderr,"The last series of values are the coordinates\n"); exit(1); @@ -78,17 +79,17 @@ int main(int argc, char *argv[]) int btype1_val = atoi(argv[2]); int btype2_val = atoi(argv[3]); - if(( btype1_val <= 11)&&( btype2_val <= 11)) + if(( btype1_val <= 14)&&( btype2_val <= 14)) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; } - else if(( btype1_val >=13)&&(btype2_val <= 14)) + else if(( btype1_val >=15)&&(btype2_val <= 16)) { btype1 = LibUtilities::eOrtho_A; btype2 = LibUtilities::eOrtho_B; - if(btype1_val == 13) + if(btype1_val == 15) { NodalType = LibUtilities::eNodalTriElec; } @@ -204,7 +205,7 @@ int main(int argc, char *argv[]) const LibUtilities::BasisKey Bkey1(btype1,order1,Pkey1); const LibUtilities::BasisKey Bkey2(btype2,order2,Pkey2); - if(btype1_val >= 11) + if(btype1_val >= 15) { E = new LocalRegions::NodalTriExp(Bkey1,Bkey2,NodalType,geom); } diff --git a/library/Demos/LocalRegions/LocProject_Diff1D.cpp b/library/Demos/LocalRegions/LocProject_Diff1D.cpp index 0347fedf3..17f2ad822 100644 --- a/library/Demos/LocalRegions/LocProject_Diff1D.cpp +++ b/library/Demos/LocalRegions/LocProject_Diff1D.cpp @@ -34,15 +34,15 @@ int main(int argc, char *argv[]) "dictates the basis as:\n"); fprintf(stderr,"\t Ortho_A = 1\n"); fprintf(stderr,"\t Modified_A = 4\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Monomial = 12\n"); - fprintf(stderr,"\t FourierSingleMode = 13\n"); - - fprintf(stderr,"Note type = 1,2,4,5 are for higher dimensional basis\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 14\n"); + fprintf(stderr,"\t FourierSingleMode = 15\n"); + + fprintf(stderr,"Note type = 1,2,4,5,7,8 are for higher dimensional basis\n"); exit(1); } diff --git a/library/Demos/LocalRegions/LocProject_Diff2D.cpp b/library/Demos/LocalRegions/LocProject_Diff2D.cpp index ea06fedff..2bde183f8 100644 --- a/library/Demos/LocalRegions/LocProject_Diff2D.cpp +++ b/library/Demos/LocalRegions/LocProject_Diff2D.cpp @@ -63,16 +63,17 @@ int main(int argc, char *argv[]) fprintf(stderr,"\t Ortho_B = 2\n"); fprintf(stderr,"\t Modified_A = 4\n"); fprintf(stderr,"\t Modified_B = 5\n"); - fprintf(stderr,"\t Fourier = 7\n"); - fprintf(stderr,"\t Lagrange = 8\n"); - fprintf(stderr,"\t Gauss Lagrange = 9\n"); - fprintf(stderr,"\t Legendre = 10\n"); - fprintf(stderr,"\t Chebyshev = 11\n"); - fprintf(stderr,"\t Nodal tri (Electro) = 13\n"); - fprintf(stderr,"\t Nodal tri (Fekete) = 14\n"); + fprintf(stderr,"\t Fourier = 9\n"); + fprintf(stderr,"\t Lagrange = 10\n"); + fprintf(stderr,"\t Gauss Lagrange = 11\n"); + fprintf(stderr,"\t Legendre = 12\n"); + fprintf(stderr,"\t Chebyshev = 13\n"); + fprintf(stderr,"\t Monomial = 13\n"); + fprintf(stderr,"\t Nodal tri (Electro) = 15\n"); + fprintf(stderr,"\t Nodal tri (Fekete) = 16\n"); - fprintf(stderr,"Note type = 3,6 are for three-dimensional basis\n"); + fprintf(stderr,"Note type = 3,6,7,8 are for three-dimensional basis\n"); fprintf(stderr,"The last series of values are the coordinates\n"); exit(1); @@ -90,17 +91,17 @@ int main(int argc, char *argv[]) int btype1_val = atoi(argv[2]); int btype2_val = atoi(argv[3]); - if(( btype1_val <= 11)&&( btype2_val <= 11)) + if(( btype1_val <= 14)&&( btype2_val <= 14)) { btype1 = (LibUtilities::BasisType) btype1_val; btype2 = (LibUtilities::BasisType) btype2_val; } - else if(( btype1_val >=13)&&(btype2_val <= 14)) + else if(( btype1_val >=15)&&(btype2_val <= 16)) { btype1 = LibUtilities::eOrtho_A; btype2 = LibUtilities::eOrtho_B; - if(btype1_val == 13) + if(btype1_val == 15) { NodalType = LibUtilities::eNodalTriElec; } @@ -108,10 +109,8 @@ int main(int argc, char *argv[]) { NodalType = LibUtilities::eNodalTriFekete; } - } - // Check to see that correct Expansions are used switch(regionshape) { @@ -224,7 +223,7 @@ int main(int argc, char *argv[]) const LibUtilities::BasisKey Bkey1(btype1,order1,Pkey1); const LibUtilities::BasisKey Bkey2(btype2,order2,Pkey2); - if(btype1_val >= 11) + if(btype1_val >= 15) { E = new LocalRegions::NodalTriExp(Bkey1,Bkey2,NodalType,geom); } diff --git a/library/Demos/LocalRegions/Tests/LocProject2D_Def_Quad_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject2D_Def_Quad_Lagrange_Basis_P6_Q7.tst index aa336d92a..23daae93f 100644 --- a/library/Demos/LocalRegions/Tests/LocProject2D_Def_Quad_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject2D_Def_Quad_Lagrange_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ Project2D Deformed Quad Lagrange basis P=6 Q=7 LocProject2D - 4 8 8 6 6 7 7 0.0 0.0 1.0 0.0 1.5 1.5 0.0 1.0 + 4 10 10 6 6 7 7 0.0 0.0 1.0 0.0 1.5 1.5 0.0 1.0 0.0970116 diff --git a/library/Demos/LocalRegions/Tests/LocProject2D_Quad_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject2D_Quad_Lagrange_Basis_P6_Q7.tst index 59cc4a882..1f35b5126 100644 --- a/library/Demos/LocalRegions/Tests/LocProject2D_Quad_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject2D_Quad_Lagrange_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ Project2D Quad Lagrange basis P=6 Q=7 LocProject2D - 4 8 8 6 6 7 7 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 + 4 10 10 6 6 7 7 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 1.81771e-15 diff --git a/library/Demos/LocalRegions/Tests/LocProject2D_Tri_Nodal_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject2D_Tri_Nodal_Basis_P6_Q7.tst index aaabb3c68..8ae595c1c 100644 --- a/library/Demos/LocalRegions/Tests/LocProject2D_Tri_Nodal_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject2D_Tri_Nodal_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ Project2D Triangle Nodal basis P=6 Q=7 LocProject2D - 3 13 13 6 6 7 7 0.0 0.0 1.0 1.0 0.5 1.0 + 3 15 15 6 6 7 7 0.0 0.0 1.0 1.0 0.5 1.0 1.84567e-15 diff --git a/library/Demos/LocalRegions/Tests/LocProject3D_Def_Hex_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject3D_Def_Hex_Lagrange_Basis_P6_Q7.tst index 7625ca350..3e698cebd 100644 --- a/library/Demos/LocalRegions/Tests/LocProject3D_Def_Hex_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject3D_Def_Hex_Lagrange_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ Project3D Deformed Hex Lagrange basis P=6 Q=7 LocProject3D - 8 8 8 8 6 6 6 7 7 7 0 0 0 1 0 0 1 1.5 0 0 1 0 0 0 1 1.5 0 1 1 1 1 0 1 1.5 + 8 10 10 10 6 6 6 7 7 7 0 0 0 1 0 0 1 1.5 0 0 1 0 0 0 1 1.5 0 1 1 1 1 0 1 1.5 0.00820104 diff --git a/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst index 63effdf09..565a8b552 100644 --- a/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject3D_Hex_Lagrange_Basis_P6_Q7.tst @@ -2,13 +2,13 @@ Project3D Hex Lagrange basis P=6 Q=7 LocProject3D - 8 8 8 8 6 6 6 7 7 7 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 + 8 10 10 10 6 6 6 7 7 7 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 - 3.83739e-11 + 2.04616e-14 - 9.15321e-11 + 8.52651e-13 diff --git a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Lin_Deformed_Quad_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Lin_Deformed_Quad_Lagrange_Basis_P6_Q7.tst index ec1835c35..0a388ec49 100644 --- a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Lin_Deformed_Quad_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Lin_Deformed_Quad_Lagrange_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ LocProject_Diff2D Lin. Deformed Quad Lagrange Basis P=6, Q=7 LocProject_Diff2D - 4 8 8 6 6 7 7 0.0 0.0 1.0 0.0 1.5 1.5 0.0 1.0 + 4 10 10 6 6 7 7 0.0 0.0 1.0 0.0 1.5 1.5 0.0 1.0 0.288711 diff --git a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst index 6bed10434..de7568a06 100644 --- a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Reg_Quad_Lagrange_Basis_P6_Q=7.tst @@ -2,13 +2,13 @@ LocProject_Diff2D Reg. Quad Lagrange Basis P=6, Q=7 LocProject_Diff2D - 4 8 8 6 6 7 7 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 + 4 10 10 6 6 7 7 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 - 1.82817e-12 + 6.80298e-14 - 4.12292e-12 + 4.83169e-13 diff --git a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Tri_Nodal_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Tri_Nodal_Basis_P6_Q7.tst index 408ac25c7..0c13f888d 100644 --- a/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Tri_Nodal_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject_Diff2D_Tri_Nodal_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ LocProject_Diff2D Tri Nodal Basis P=6, Q=7 LocProject_Diff2D - 3 13 13 6 6 7 7 0.0 0.0 1.0 1.0 0.5 1.0 + 3 15 15 6 6 7 7 0.0 0.0 1.0 1.0 0.5 1.0 2.99203e-14 diff --git a/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Lin_Deformed_Hex_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Lin_Deformed_Hex_Lagrange_Basis_P6_Q7.tst index 264683b6f..c400e8404 100644 --- a/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Lin_Deformed_Hex_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Lin_Deformed_Hex_Lagrange_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ LocProject_Diff3D Lin. Deformed Hex Lagrange Basis, P=6, Q=7 LocProject_Diff3D - 8 8 8 8 6 6 6 7 7 7 0 0 0 1 0 0 1 1.5 0 0 1 0 0 0 1 1.5 0 1 1 1 1 0 1 1.5 + 8 10 10 10 6 6 6 7 7 7 0 0 0 1 0 0 1 1.5 0 0 1 0 0 0 1 1.5 0 1 1 1 1 0 1 1.5 0.0353098 diff --git a/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Hex_Lagrange_Basis_P6_Q7.tst b/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Hex_Lagrange_Basis_P6_Q7.tst index 81d42e2a7..2a951277a 100644 --- a/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Hex_Lagrange_Basis_P6_Q7.tst +++ b/library/Demos/LocalRegions/Tests/LocProject_Diff3D_Reg_Hex_Lagrange_Basis_P6_Q7.tst @@ -2,7 +2,7 @@ LocProject_Diff3D Reg. Hex Lagrange Basis, P=6, Q=7 LocProject_Diff3D - 8 8 8 8 6 6 6 7 7 7 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 + 8 10 10 10 6 6 6 7 7 7 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 5.89495e-13 -- GitLab From cbaf28a707f3c0ab56203d852adbc1b319db88bb Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 18 Mar 2017 14:54:06 +0000 Subject: [PATCH 13/27] Updated results since seem to have slighly lower errror now --- library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst | 4 ++-- .../Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst index 2520c8281..99abb9820 100644 --- a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst +++ b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr.tst @@ -8,10 +8,10 @@ - 5.22808e-07 + 5.00954e-07 - 4.16465e-06 + 4.36308e-06 diff --git a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst index 203b00ce1..794878f0c 100644 --- a/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst +++ b/library/Demos/MultiRegions/Tests/Helmholtz3D_CG_Pyr_Deformed.tst @@ -8,10 +8,10 @@ - 4.1907e-05 + 2.04919e-05 - 0.000329233 + 0.000165154 -- GitLab From 4ffa760664269bf481559b60c35b8952980bdd0e Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 18 Mar 2017 15:39:02 +0000 Subject: [PATCH 14/27] Tweak of tolerances for buildbot resilience --- .../Tests/Pyr_channel_SVV.tst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst b/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst index 1d8e22859..d6ea89dd1 100644 --- a/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst +++ b/solvers/IncNavierStokesSolver/Tests/Pyr_channel_SVV.tst @@ -8,16 +8,16 @@ - 2.6682e-10 - 2.67015e-10 - 1.15296e-09 + 2.6682e-10 + 2.67015e-10 + 1.15296e-09 2.8591e-08 - 1.838e-09 - 1.90318e-09 - 1.42728e-08 - 1.0353e-06 + 1.838e-09 + 1.90318e-09 + 1.42728e-08 + 1.0353e-06 -- GitLab From 74d545804293eab397d77381401702879a182c01 Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 20 Mar 2017 13:33:58 +0000 Subject: [PATCH 15/27] Added in Collection methods for BwdTrans and PhysDeriv and setup unit test --- library/Collections/BwdTrans.cpp | 165 +- library/Collections/PhysDeriv.cpp | 223 ++ library/StdRegions/StdPyrExp.cpp | 50 +- library/UnitTests/Collections/CMakeLists.txt | 1 + .../Collections/TestPyrCollection.cpp | 1990 +++++++++++++++++ 5 files changed, 2418 insertions(+), 11 deletions(-) create mode 100644 library/UnitTests/Collections/TestPyrCollection.cpp diff --git a/library/Collections/BwdTrans.cpp b/library/Collections/BwdTrans.cpp index fbc0683d8..8dc637bec 100644 --- a/library/Collections/BwdTrans.cpp +++ b/library/Collections/BwdTrans.cpp @@ -918,7 +918,7 @@ class BwdTrans_SumFac_Prism : public Operator { Blas::Dgemm('N', 'N', m_nquad2, m_numElmt, m_nmodes2-i, 1.0, m_base2.get()+mode*m_nquad2, m_nquad2, - &input[0]+mode1, totmodes, 0.0, + input.get()+mode1, totmodes, 0.0, &wsp[j*m_nquad2*m_numElmt*m_nmodes0+ cnt], m_nquad2); mode1 += m_nmodes2-i; @@ -1018,5 +1018,168 @@ OperatorKey BwdTrans_SumFac_Prism::m_type = GetOperatorFactory(). OperatorKey(ePrism, eBwdTrans, eSumFac,false), BwdTrans_SumFac_Prism::create, "BwdTrans_SumFac_Prism"); +/** + * @brief Backward transform operator using sum-factorisation (Pyr) + */ +class BwdTrans_SumFac_Pyr : public Operator +{ + public: + OPERATOR_CREATE(BwdTrans_SumFac_Pyr) + + virtual ~BwdTrans_SumFac_Pyr() + { + } + + virtual void operator()( + const Array &input, + Array &output, + Array &output1, + Array &output2, + Array &wsp) + { + ASSERTL1(wsp.num_elements() == m_wspSize, + "Incorrect workspace size"); + + // Assign second half of workspace for 2nd DGEMM operation. + int totmodes = m_stdExp->GetNcoeffs(); + + Array wsp2 + = wsp + m_nmodes0*m_nmodes1*m_nquad2*m_numElmt; + + Vmath::Zero(m_nmodes0*m_nmodes1*m_nquad2*m_numElmt, wsp, 1); + int i = 0; + int j = 0; + int mode = 0; + int mode1 = 0; + int cnt = 0; + for (i = mode = mode1 = 0; i < m_nmodes0; ++i) + { + for (j = 0; j < m_nmodes1; ++j, ++cnt) + { + int ijmax = max(i,j); + Blas::Dgemm('N', 'N', m_nquad2, m_numElmt, m_nmodes2-ijmax, + 1.0, m_base2.get()+mode*m_nquad2, m_nquad2, + input.get()+mode1, totmodes, 0.0, + wsp.get() + cnt*m_nquad2*m_numElmt, m_nquad2); + mode += m_nmodes2-ijmax; + mode1 += m_nmodes2-ijmax; + } + + //increment mode in case order1!=order2 + for(j = m_nmodes1; j < m_nmodes2-i; ++j) + { + int ijmax = max(i,j); + mode += m_nmodes2-ijmax; + } + } + + // vertex mode - currently (1+c)/2 x (1-b)/2 x (1-a)/2 + // component is evaluated + if(m_sortTopVertex) + { + for(i = 0; i < m_numElmt; ++i) + { + // top singular vertex + // (1+c)/2 x (1+b)/2 x (1-a)/2 component + Blas::Daxpy(m_nquad2, input[1+i*totmodes], + m_base2.get() + m_nquad2, 1, + &wsp[m_nquad2*m_numElmt] + i*m_nquad2, 1); + + // top singular vertex + // (1+c)/2 x (1-b)/2 x (1+a)/2 component + Blas::Daxpy(m_nquad2, input[1+i*totmodes], + m_base2.get() + m_nquad2, 1, + &wsp[m_nmodes1*m_nquad2*m_numElmt] + + i*m_nquad2, 1); + + // top singular vertex + // (1+c)/2 x (1+b)/2 x (1+a)/2 component + Blas::Daxpy(m_nquad2, input[1+i*totmodes], + m_base2.get() + m_nquad2, 1, + &wsp[(m_nmodes1+1)*m_nquad2*m_numElmt] + + i*m_nquad2, 1); + + } + } + + // Perform summation over '1' direction + mode = 0; + for(i = 0; i < m_nmodes0; ++i) + { + Blas::Dgemm('N', 'T', m_nquad1, m_nquad2*m_numElmt, m_nmodes1, + 1.0, m_base1.get(), m_nquad1, + wsp.get() + mode*m_nquad2*m_numElmt, + m_nquad2*m_numElmt, + 0.0, wsp2.get() + i*m_nquad1*m_nquad2*m_numElmt, + m_nquad1); + mode += m_nmodes1; + } + + // Perform summation over '0' direction + Blas::Dgemm('N', 'T', m_nquad0, m_nquad1*m_nquad2*m_numElmt, + m_nmodes0, 1.0, m_base0.get(), m_nquad0, + wsp2.get(), m_nquad1*m_nquad2*m_numElmt, + 0.0, output.get(), m_nquad0); + } + + virtual void operator()( + int dir, + const Array &input, + Array &output, + Array &wsp) + { + ASSERTL0(false, "Not valid for this operator."); + } + + + protected: + const int m_nquad0; + const int m_nquad1; + const int m_nquad2; + const int m_nmodes0; + const int m_nmodes1; + const int m_nmodes2; + Array m_base0; + Array m_base1; + Array m_base2; + bool m_sortTopVertex; + + private: + BwdTrans_SumFac_Pyr( + vector pCollExp, + CoalescedGeomDataSharedPtr pGeomData) + : Operator (pCollExp, pGeomData), + m_nquad0 (m_stdExp->GetNumPoints(0)), + m_nquad1 (m_stdExp->GetNumPoints(1)), + m_nquad2 (m_stdExp->GetNumPoints(2)), + m_nmodes0 (m_stdExp->GetBasisNumModes(0)), + m_nmodes1 (m_stdExp->GetBasisNumModes(1)), + m_nmodes2 (m_stdExp->GetBasisNumModes(2)), + m_base0 (m_stdExp->GetBasis(0)->GetBdata()), + m_base1 (m_stdExp->GetBasis(1)->GetBdata()), + m_base2 (m_stdExp->GetBasis(2)->GetBdata()) + { + m_wspSize = m_numElmt*m_nmodes0*m_nquad2*(m_nmodes1 + m_nquad1); + + if(m_stdExp->GetBasis(0)->GetBasisType() + == LibUtilities::eModified_A) + { + m_sortTopVertex = true; + } + else + { + m_sortTopVertex = false; + } + + } +}; + +/// Factory initialisation for the BwdTrans_SumFac_Pyr operator +OperatorKey BwdTrans_SumFac_Pyr::m_type = GetOperatorFactory(). + RegisterCreatorFunction( + OperatorKey(ePyramid, eBwdTrans, eSumFac,false), + BwdTrans_SumFac_Pyr::create, "BwdTrans_SumFac_Pyr"); + } + } diff --git a/library/Collections/PhysDeriv.cpp b/library/Collections/PhysDeriv.cpp index da8eb7363..e2c8b4f98 100644 --- a/library/Collections/PhysDeriv.cpp +++ b/library/Collections/PhysDeriv.cpp @@ -1537,5 +1537,228 @@ OperatorKey PhysDeriv_SumFac_Prism::m_typeArr[] = { }; +/** + * @brief Phys deriv operator using sum-factorisation (Pyramid) + */ +class PhysDeriv_SumFac_Pyr : public Operator +{ + public: + OPERATOR_CREATE(PhysDeriv_SumFac_Pyr) + + virtual ~PhysDeriv_SumFac_Pyr() + { + } + + virtual void operator()( + const Array &input, + Array &output0, + Array &output1, + Array &output2, + Array &wsp) + { + int nPhys = m_stdExp->GetTotPoints(); + int ntot = m_numElmt*nPhys; + Array tmp0,tmp1,tmp2; + Array > Diff(3); + Array > out(3); + out[0] = output0; out[1] = output1; out[2] = output2; + + for(int i = 0; i < m_dim; ++i) + { + Diff[i] = wsp + i*ntot; + } + + // dEta0 + Blas::Dgemm('N','N', m_nquad0,m_nquad1*m_nquad2*m_numElmt, + m_nquad0,1.0, m_Deriv0,m_nquad0,&input[0], + m_nquad0,0.0,&Diff[0][0],m_nquad0); + + int cnt = 0; + for(int i = 0; i < m_numElmt; ++i) + { + + // dEta 1 + for (int j = 0; j < m_nquad2; ++j) + { + Blas::Dgemm('N', 'T', m_nquad0, m_nquad1, m_nquad1, + 1.0, &input[i*nPhys+j*m_nquad0*m_nquad1], + m_nquad0, m_Deriv1, m_nquad1, 0.0, + &Diff[1][i*nPhys+j*m_nquad0*m_nquad1], + m_nquad0); + } + + // dEta 2 + Blas::Dgemm('N','T',m_nquad0*m_nquad1,m_nquad2,m_nquad2, + 1.0, &input[i*nPhys],m_nquad0*m_nquad1, + m_Deriv2,m_nquad2, 0.0,&Diff[2][i*nPhys], + m_nquad0*m_nquad1); + + // dxi0 = 2/(1-eta_2) d Eta_0 + Vmath::Vmul(nPhys,&m_fac0[0],1,Diff[0].get()+cnt,1, + Diff[0].get()+cnt,1); + + // dxi1 = 2/(1-eta_2) d Eta_1 + Vmath::Vmul(nPhys,&m_fac0[0],1,Diff[1].get()+cnt,1, + Diff[1].get()+cnt,1); + + // dxi2 = (1+eta0)/(1-eta_2) d Eta_0 + d/dEta2; + Vmath::Vvtvp(nPhys,&m_fac1[0],1,Diff[0].get()+cnt,1, + Diff[2].get()+cnt,1,Diff[2].get()+cnt,1); + // dxi2 += (1+eta1)/(1-eta_2) d Eta_1 + Vmath::Vvtvp(nPhys,&m_fac2[0],1,Diff[1].get()+cnt,1, + Diff[2].get()+cnt,1,Diff[2].get()+cnt,1); + cnt += nPhys; + } + + // calculate full derivative + for(int i = 0; i < m_coordim; ++i) + { + Vmath::Vmul(ntot,m_derivFac[i*m_dim],1,Diff[0],1,out[i],1); + for(int j = 1; j < m_dim; ++j) + { + Vmath::Vvtvp (ntot, m_derivFac[i*m_dim+j], 1, + Diff[j], 1, out[i], 1, out[i], 1); + } + } + } + + virtual void operator()( + int dir, + const Array &input, + Array &output, + Array &wsp) + { + int nPhys = m_stdExp->GetTotPoints(); + int ntot = m_numElmt*nPhys; + Array tmp0,tmp1,tmp2; + Array > Diff(3); + + for(int i = 0; i < m_dim; ++i) + { + Diff[i] = wsp + i*ntot; + } + + // dEta0 + Blas::Dgemm('N','N', m_nquad0,m_nquad1*m_nquad2*m_numElmt, + m_nquad0,1.0, m_Deriv0,m_nquad0,&input[0], + m_nquad0,0.0,&Diff[0][0],m_nquad0); + + int cnt = 0; + for(int i = 0; i < m_numElmt; ++i) + { + // dEta 1 + for (int j = 0; j < m_nquad2; ++j) + { + Blas::Dgemm('N', 'T', m_nquad0, m_nquad1, m_nquad1, + 1.0, &input[i*nPhys+j*m_nquad0*m_nquad1], + m_nquad0, m_Deriv1, m_nquad1, 0.0, + &Diff[1][i*nPhys+j*m_nquad0*m_nquad1], + m_nquad0); + } + + // dEta 2 + Blas::Dgemm('N','T',m_nquad0*m_nquad1,m_nquad2,m_nquad2, + 1.0, &input[i*nPhys],m_nquad0*m_nquad1, + m_Deriv2,m_nquad2, 0.0,&Diff[2][i*nPhys], + m_nquad0*m_nquad1); + + // dxi0 = 2/(1-eta_2) d Eta_0 + Vmath::Vmul(nPhys,&m_fac0[0],1,Diff[0].get()+cnt,1, + Diff[0].get()+cnt,1); + + // dxi1 = 2/(1-eta_2) d Eta_1 + Vmath::Vmul(nPhys,&m_fac0[0],1,Diff[1].get()+cnt,1, + Diff[1].get()+cnt,1); + + // dxi2 = (1+eta0)/(1-eta_2) d Eta_0 + d/dEta2; + Vmath::Vvtvp(nPhys,&m_fac1[0],1,Diff[0].get()+cnt,1, + Diff[2].get()+cnt,1,Diff[2].get()+cnt,1); + // dxi2 = (1+eta1)/(1-eta_2) d Eta_1 + d/dEta2; + Vmath::Vvtvp(nPhys,&m_fac2[0],1,Diff[1].get()+cnt,1, + Diff[2].get()+cnt,1,Diff[2].get()+cnt,1); + cnt += nPhys; + } + + // calculate full derivative + Vmath::Vmul(ntot,m_derivFac[dir*m_dim],1,Diff[0],1,output,1); + for(int j = 1; j < m_dim; ++j) + { + Vmath::Vvtvp (ntot, m_derivFac[dir*m_dim+j], 1, + Diff[j], 1, output, 1, output, 1); + } + } + + protected: + Array m_derivFac; + int m_dim; + int m_coordim; + const int m_nquad0; + const int m_nquad1; + const int m_nquad2; + NekDouble *m_Deriv0; + NekDouble *m_Deriv1; + NekDouble *m_Deriv2; + Array m_fac0; + Array m_fac1; + Array m_fac2; + + private: + PhysDeriv_SumFac_Pyr( + vector pCollExp, + CoalescedGeomDataSharedPtr pGeomData) + : Operator(pCollExp, pGeomData), + m_nquad0 (m_stdExp->GetNumPoints(0)), + m_nquad1 (m_stdExp->GetNumPoints(1)), + m_nquad2 (m_stdExp->GetNumPoints(2)) + { + LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys(); + + m_dim = PtsKey.size(); + m_coordim = m_stdExp->GetCoordim(); + + m_derivFac = pGeomData->GetDerivFactors(pCollExp); + + const Array& z0 + = m_stdExp->GetBasis(0)->GetZ(); + const Array& z1 + = m_stdExp->GetBasis(1)->GetZ(); + const Array& z2 + = m_stdExp->GetBasis(2)->GetZ(); + m_fac0 = Array(m_nquad0*m_nquad1*m_nquad2); + m_fac1 = Array(m_nquad0*m_nquad1*m_nquad2); + m_fac2 = Array(m_nquad0*m_nquad1*m_nquad2); + + for (int i = 0; i < m_nquad0; ++i) + { + for(int j = 0; j < m_nquad1; ++j) + { + for(int k = 0; k < m_nquad2; ++k) + { + m_fac0[i+j*m_nquad0 + k*m_nquad0*m_nquad1] = + 2.0/(1-z2[k]); + m_fac1[i+j*m_nquad0 + k*m_nquad0*m_nquad1] = + 0.5*(1+z0[i]); + m_fac2[i+j*m_nquad0 + k*m_nquad0*m_nquad1] = + 0.5*(1+z1[j]); + } + } + } + + m_Deriv0 = &((m_stdExp->GetBasis(0)->GetD())->GetPtr())[0]; + m_Deriv1 = &((m_stdExp->GetBasis(1)->GetD())->GetPtr())[0]; + m_Deriv2 = &((m_stdExp->GetBasis(2)->GetD())->GetPtr())[0]; + + m_wspSize = 3*m_nquad0*m_nquad1*m_nquad2*m_numElmt; + } +}; + +/// Factory initialisation for the PhysDeriv_SumFac_Pyr operators +OperatorKey PhysDeriv_SumFac_Pyr::m_typeArr[] = { + GetOperatorFactory().RegisterCreatorFunction( + OperatorKey(ePyramid, ePhysDeriv, eSumFac, false), + PhysDeriv_SumFac_Pyr::create, "PhysDeriv_SumFac_Pyr") +}; + + } } diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index b2558cea6..3cebba2ad 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -124,20 +124,50 @@ namespace Nektar eta_z = m_base[2]->GetZ(); int i, j, k, n; + + if (out_dxi1.num_elements() > 0) + { + for (k = 0, n = 0; k < Qz; ++k) + { + NekDouble fac = 2.0/(1.0 - eta_z[k]); + for (j = 0; j < Qy; ++j) + { + for (i = 0; i < Qx; ++i, ++n) + { + out_dxi1[n] = fac * dEta_bar1[n]; + } + } + } + } + + if (out_dxi2.num_elements() > 0) + { + for (k = 0, n = 0; k < Qz; ++k) + { + NekDouble fac = 2.0/(1.0 - eta_z[k]); + for (j = 0; j < Qy; ++j) + { + for (i = 0; i < Qx; ++i, ++n) + { + out_dxi2[n] = fac * dXi2[n]; + } + } + } + } - for (k = 0, n = 0; k < Qz; ++k) + if (out_dxi3.num_elements() > 0) { - for (j = 0; j < Qy; ++j) + for (k = 0, n = 0; k < Qz; ++k) { - for (i = 0; i < Qx; ++i, ++n) + NekDouble fac = 1.0/(1.0 - eta_z[k]); + for (j = 0; j < Qy; ++j) { - if (out_dxi1.num_elements() > 0) - out_dxi1[n] = 2.0/(1.0 - eta_z[k]) * dEta_bar1[n]; - if (out_dxi2.num_elements() > 0) - out_dxi2[n] = 2.0/(1.0 - eta_z[k]) * dXi2[n]; - if (out_dxi3.num_elements() > 0) - out_dxi3[n] = (1.0+eta_x[i])/(1.0-eta_z[k])*dEta_bar1[n] + - (1.0+eta_y[j])/(1.0-eta_z[k])*dXi2[n] + dEta3[n]; + NekDouble fac1 = (1.0+eta_y[j]); + for (i = 0; i < Qx; ++i, ++n) + { + out_dxi3[n] = (1.0+eta_x[i])*fac*dEta_bar1[n] + + fac1*fac*dXi2[n] + dEta3[n]; + } } } } diff --git a/library/UnitTests/Collections/CMakeLists.txt b/library/UnitTests/Collections/CMakeLists.txt index 59ac1f63a..bc56e27e0 100644 --- a/library/UnitTests/Collections/CMakeLists.txt +++ b/library/UnitTests/Collections/CMakeLists.txt @@ -3,6 +3,7 @@ SET(Sources TestHexCollection.cpp TestQuadCollection.cpp TestPrismCollection.cpp + TestPyrCollection.cpp TestSegCollection.cpp TestTetCollection.cpp TestTriCollection.cpp diff --git a/library/UnitTests/Collections/TestPyrCollection.cpp b/library/UnitTests/Collections/TestPyrCollection.cpp new file mode 100644 index 000000000..5559290c4 --- /dev/null +++ b/library/UnitTests/Collections/TestPyrCollection.cpp @@ -0,0 +1,1990 @@ +/////////////////////////////////////////////////////////////////////////////// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Nektar +{ + namespace PyrCollectionTests + { + SpatialDomains::SegGeomSharedPtr CreateSegGeom(unsigned int id, + SpatialDomains::PointGeomSharedPtr v0, + SpatialDomains::PointGeomSharedPtr v1) + { + SpatialDomains::PointGeomSharedPtr vertices[] = {v0, v1}; + SpatialDomains::SegGeomSharedPtr result(new SpatialDomains::SegGeom(id, 3, vertices)); + return result; + } + + SpatialDomains::PyrGeomSharedPtr CreatePyr( + SpatialDomains::PointGeomSharedPtr v0, + SpatialDomains::PointGeomSharedPtr v1, + SpatialDomains::PointGeomSharedPtr v2, + SpatialDomains::PointGeomSharedPtr v3, + SpatialDomains::PointGeomSharedPtr v4) + { + Nektar::SpatialDomains::SegGeomSharedPtr e0 = CreateSegGeom(0, v0, v1); + Nektar::SpatialDomains::SegGeomSharedPtr e1 = CreateSegGeom(1, v1, v2); + Nektar::SpatialDomains::SegGeomSharedPtr e2 = CreateSegGeom(2, v2, v3); + Nektar::SpatialDomains::SegGeomSharedPtr e3 = CreateSegGeom(3, v3, v0); + Nektar::SpatialDomains::SegGeomSharedPtr e4 = CreateSegGeom(4, v0, v4); + Nektar::SpatialDomains::SegGeomSharedPtr e5 = CreateSegGeom(5, v1, v4); + Nektar::SpatialDomains::SegGeomSharedPtr e6 = CreateSegGeom(6, v2, v4); + Nektar::SpatialDomains::SegGeomSharedPtr e7 = CreateSegGeom(7, v3, v4); + + Nektar::SpatialDomains::SegGeomSharedPtr edgesF0[Nektar::SpatialDomains::QuadGeom::kNedges] = + { + e0, e1, e2, e3 + }; + + Nektar::SpatialDomains::SegGeomSharedPtr edgesF1[Nektar::SpatialDomains::TriGeom::kNedges] = + { + e0, e4, e5 + }; + + Nektar::SpatialDomains::SegGeomSharedPtr edgesF2[Nektar::SpatialDomains::TriGeom::kNedges] = + { + e1, e6, e5 + }; + + Nektar::SpatialDomains::SegGeomSharedPtr edgesF3[Nektar::SpatialDomains::TriGeom::kNedges] = + { + e2, e6, e7 + }; + + Nektar::SpatialDomains::SegGeomSharedPtr edgesF4[Nektar::SpatialDomains::TriGeom::kNedges] = + { + e3, e4, e7 + }; + + Nektar::StdRegions::Orientation edgeorientF0[Nektar::SpatialDomains::QuadGeom::kNedges] = + { + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF0[0], *edgesF0[1]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF0[1], *edgesF0[2]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF0[2], *edgesF0[3]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF0[3], *edgesF0[0]) + }; + + Nektar::StdRegions::Orientation edgeorientF1[Nektar::SpatialDomains::TriGeom::kNedges] = + { + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF1[0], *edgesF1[1]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF1[1], *edgesF1[2]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF1[2], *edgesF1[0]) + }; + + Nektar::StdRegions::Orientation edgeorientF2[Nektar::SpatialDomains::TriGeom::kNedges] = + { + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF2[0], *edgesF2[1]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF2[1], *edgesF2[2]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF2[2], *edgesF2[0]) + }; + + Nektar::StdRegions::Orientation edgeorientF3[Nektar::SpatialDomains::TriGeom::kNedges] = + { + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF3[0], *edgesF3[1]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF3[1], *edgesF3[2]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF3[2], *edgesF3[0]) + }; + + + Nektar::StdRegions::Orientation edgeorientF4[Nektar::SpatialDomains::TriGeom::kNedges] = + { + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF4[0], *edgesF4[1]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF4[1], *edgesF4[2]), + Nektar::SpatialDomains::SegGeom::GetEdgeOrientation(*edgesF4[2], *edgesF4[0]) + }; + + Nektar::SpatialDomains::QuadGeomSharedPtr face0(new SpatialDomains::QuadGeom(0, edgesF0, edgeorientF0)); + Nektar::SpatialDomains::TriGeomSharedPtr face1(new SpatialDomains::TriGeom (1, edgesF1, edgeorientF1)); + Nektar::SpatialDomains::TriGeomSharedPtr face2(new SpatialDomains::TriGeom (2, edgesF2, edgeorientF2)); + Nektar::SpatialDomains::TriGeomSharedPtr face3(new SpatialDomains::TriGeom (3, edgesF3, edgeorientF3)); + Nektar::SpatialDomains::TriGeomSharedPtr face4(new SpatialDomains::TriGeom (4, edgesF4, edgeorientF4)); + + Nektar::SpatialDomains::Geometry2DSharedPtr faces[] = {face0, face1, face2, face3, face4}; + SpatialDomains::PyrGeomSharedPtr pyrGeom(new SpatialDomains::PyrGeom(faces)); + return pyrGeom; + } + + BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_IterPerExp_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + Array coeffs(nelmts*Exp->GetNcoeffs(), 1.0), tmp; + Array phys1(nelmts*Exp->GetTotPoints()); + Array phys2(nelmts*Exp->GetTotPoints()); + + for(int i = 0; i < nelmts; ++i) + { + Exp->BwdTrans(coeffs + i*Exp->GetNcoeffs(), + tmp = phys1+i*Exp->GetTotPoints()); + } + c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2); + + double epsilon = 1.0e-8; + for(int i = 0; i < phys1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(phys1[i],phys2[i], epsilon); + } + + } + + + BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_StdMat_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(5, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eStdMat); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + Array coeffs(nelmts*Exp->GetNcoeffs(), 1.0); + Array phys1 (nelmts*Exp->GetTotPoints(), 0.0); + Array phys2 (nelmts*Exp->GetTotPoints(), 0.0); + Array tmp; + + for(int i = 0; i < nelmts; ++i) + { + Exp->BwdTrans(coeffs + i*Exp->GetNcoeffs(), tmp = phys1+i*Exp->GetTotPoints()); + } + c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2); + + double epsilon = 1.0e-8; + for(int i = 0; i < phys1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(phys1[i],phys2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_SumFac_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(5, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::OperatorImpMap impTypes; + impTypes[Collections::eBwdTrans] = Collections::eSumFac; + Collections::Collection c(CollExp, impTypes); + + Array coeffs(nelmts*Exp->GetNcoeffs(), 1.0); + Array phys1(nelmts*Exp->GetTotPoints(), 0.0); + Array phys2(nelmts*Exp->GetTotPoints(), 0.0); + Array tmp; + + for(int i = 0; i < nelmts; ++i) + { + Exp->BwdTrans(coeffs + i*Exp->GetNcoeffs(), tmp = phys1+i*Exp->GetTotPoints()); + } + c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2); + + double epsilon = 1.0e-8; + for(int i = 0; i < phys1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(phys1[i],phys2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_IterPerExp_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + Array coeffs(nelmts*Exp->GetNcoeffs(), 1.0); + Array phys1(nelmts*Exp->GetTotPoints(), 0.0); + Array phys2(nelmts*Exp->GetTotPoints(), 0.0); + Array tmp; + + for(int i = 0; i < nelmts; ++i) + { + Exp->BwdTrans(coeffs + i*Exp->GetNcoeffs(), tmp = phys1+i*Exp->GetTotPoints()); + } + c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2); + + double epsilon = 1.0e-8; + for(int i = 0; i < phys1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(phys1[i],phys2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_StdMat_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eStdMat); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + Array coeffs(nelmts*Exp->GetNcoeffs(), 1.0); + Array phys1(nelmts*Exp->GetTotPoints(), 0.0); + Array phys2(nelmts*Exp->GetTotPoints(), 0.0); + Array tmp; + + for(int i = 0; i < nelmts; ++i) + { + Exp->BwdTrans(coeffs + i*Exp->GetNcoeffs(), tmp = phys1+i*Exp->GetTotPoints()); + } + c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2); + + double epsilon = 1.0e-8; + for(int i = 0; i < phys1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(phys1[i],phys2[i], epsilon); + } + } + + BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_SumFac_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::OperatorImpMap impTypes; + impTypes[Collections::eBwdTrans] = Collections::eSumFac; + Collections::Collection c(CollExp, impTypes); + + Array coeffs(nelmts*Exp->GetNcoeffs(), 1.0); + Array phys1(nelmts*Exp->GetTotPoints(), 0.0); + Array phys2(nelmts*Exp->GetTotPoints(), 0.0); + Array tmp; + + for(int i = 0; i < nelmts; ++i) + { + Exp->BwdTrans(coeffs + i*Exp->GetNcoeffs(), tmp = phys1+i*Exp->GetTotPoints()); + } + c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2); + + double epsilon = 1.0e-8; + for(int i = 0; i < phys1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(phys1[i],phys2[i], epsilon); + } + + } + + + BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_IterPerExp_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array xc(nq), yc(nq), zc(nq); + Array phys(nelmts*nq),tmp,tmp1,tmp2; + Array diff1(3*nelmts*nq); + Array diff2(3*nelmts*nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->PhysDeriv(phys, diff1, + tmp1 = diff1+(nelmts)*nq, + tmp2 = diff1+(2*nelmts)*nq); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys,1,tmp = phys+i*nq,1); + Exp->PhysDeriv(phys, tmp = diff1+i*nq, + tmp1 = diff1+(nelmts+i)*nq, + tmp2 = diff1+(2*nelmts+i)*nq); + } + + c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, + tmp = diff2 + nelmts*nq, + tmp2 = diff2+2*nelmts*nq); + + double epsilon = 1.0e-8; + for(int i = 0; i < diff1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(diff1[i],diff2[i], epsilon); + } + } + + BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_StdMat_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eStdMat); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array xc(nq), yc(nq), zc(nq); + Array phys(nelmts*nq),tmp,tmp1,tmp2; + Array diff1(3*nelmts*nq); + Array diff2(3*nelmts*nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->PhysDeriv(phys, diff1, + tmp1 = diff1+(nelmts)*nq, + tmp2 = diff1+(2*nelmts)*nq); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys,1,tmp = phys+i*nq,1); + Exp->PhysDeriv(phys, tmp = diff1+i*nq, + tmp1 = diff1+(nelmts+i)*nq, + tmp2 = diff1+(2*nelmts+i)*nq); + } + + c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, + tmp = diff2 + nelmts*nq, + tmp2 = diff2+2*nelmts*nq); + + double epsilon = 1.0e-8; + for(int i = 0; i < diff1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + diff1[i] = (fabs(diff1[i]) < 1e-14)? 0.0: diff1[i]; + diff2[i] = (fabs(diff2[i]) < 1e-14)? 0.0: diff2[i]; + BOOST_CHECK_CLOSE(diff1[i],diff2[i], epsilon); + } + } + + BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_SumFac_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + int nelmts = 2; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::OperatorImpMap impTypes; + impTypes[Collections::ePhysDeriv] = Collections::eSumFac; + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array xc(nq), yc(nq), zc(nq); + Array phys(nelmts*nq),tmp,tmp1,tmp2; + Array diff1(3*nelmts*nq); + Array diff2(3*nelmts*nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->PhysDeriv(phys, diff1, + tmp1 = diff1+(nelmts)*nq, + tmp2 = diff1+(2*nelmts)*nq); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys,1,tmp = phys+i*nq,1); + Exp->PhysDeriv(phys, tmp = diff1+i*nq, + tmp1 = diff1+(nelmts+i)*nq, + tmp2 = diff1+(2*nelmts+i)*nq); + } + + c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, + tmp = diff2 + nelmts*nq, + tmp2 = diff2+2*nelmts*nq); + + double epsilon = 1.0e-8; + for(int i = 0; i < diff1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(diff1[i],diff2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_IterPerExp_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array xc(nq), yc(nq), zc(nq); + Array phys(nelmts*nq),tmp,tmp1,tmp2; + Array diff1(3*nelmts*nq); + Array diff2(3*nelmts*nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->PhysDeriv(phys, diff1, + tmp1 = diff1+(nelmts)*nq, + tmp2 = diff1+(2*nelmts)*nq); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys,1,tmp = phys+i*nq,1); + Exp->PhysDeriv(phys, tmp = diff1+i*nq, + tmp1 = diff1+(nelmts+i)*nq, + tmp2 = diff1+(2*nelmts+i)*nq); + } + + c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, + tmp = diff2 + nelmts*nq, + tmp2 = diff2+2*nelmts*nq); + + double epsilon = 1.0e-8; + for(int i = 0; i < diff1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + diff1[i] = (fabs(diff1[i]) < 1e-14)? 0.0: diff1[i]; + diff2[i] = (fabs(diff2[i]) < 1e-14)? 0.0: diff2[i]; + BOOST_CHECK_CLOSE(diff1[i],diff2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_SumFac_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::OperatorImpMap impTypes; + impTypes[Collections::ePhysDeriv] = Collections::eSumFac; + + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array xc(nq), yc(nq), zc(nq); + Array phys(nelmts*nq),tmp,tmp1,tmp2; + Array diff1(3*nelmts*nq); + Array diff2(3*nelmts*nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->PhysDeriv(phys, tmp = diff1, + tmp1 = diff1+(nelmts)*nq, + tmp2 = diff1+(2*nelmts)*nq); + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys,1,tmp = phys+i*nq,1); + Exp->PhysDeriv(phys, tmp = diff1+i*nq, + tmp1 = diff1+(nelmts+i)*nq, + tmp2 = diff1+(2*nelmts+i)*nq); + } + + c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, + tmp = diff2 + nelmts*nq, + tmp2 = diff2+2*nelmts*nq); + + double epsilon = 1.0e-8; + for(int i = 0; i < diff1.num_elements(); ++i) + { + BOOST_CHECK_CLOSE(diff1[i],diff2[i], epsilon); + } + } +#if 0 + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_IterPerExp_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array phys(nelmts*nq, 0.0); + Array coeffs1(nelmts*Exp->GetNcoeffs(), 0.0); + Array coeffs2(nelmts*Exp->GetNcoeffs(), 0.0); + Array tmp; + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->IProductWRTBase(phys, coeffs1); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,&phys[0],1,&phys[i*nq],1); + Exp->IProductWRTBase(phys +i*nq, tmp = coeffs1 + i*Exp->GetNcoeffs()); + } + + c.ApplyOperator(Collections::eIProductWRTBase, phys, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_StdMat_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eStdMat); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array phys(nelmts*nq, 0.0); + Array coeffs1(nelmts*Exp->GetNcoeffs(), 0.0); + Array coeffs2(nelmts*Exp->GetNcoeffs(), 0.0); + Array tmp; + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->IProductWRTBase(phys, coeffs1); + + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,&phys[0],1,&phys[i*nq],1); + Exp->IProductWRTBase(phys +i*nq, tmp = coeffs1 + i*Exp->GetNcoeffs()); + } + + c.ApplyOperator(Collections::eIProductWRTBase, phys, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_SumFac_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array phys(nelmts*nq, 0.0); + Array coeffs1(nelmts*Exp->GetNcoeffs(), 0.0); + Array coeffs2(nelmts*Exp->GetNcoeffs(), 0.0); + Array tmp; + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->IProductWRTBase(phys, coeffs1); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,&phys[0],1,&phys[i*nq],1); + Exp->IProductWRTBase(phys +i*nq, tmp = coeffs1 + i*Exp->GetNcoeffs()); + } + + c.ApplyOperator(Collections::eIProductWRTBase, phys, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_IterPerExp_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array phys(nelmts*nq, 0.0); + Array coeffs1(nelmts*Exp->GetNcoeffs(), 0.0); + Array coeffs2(nelmts*Exp->GetNcoeffs(), 0.0); + Array tmp; + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->IProductWRTBase(phys, coeffs1); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,&phys[0],1,&phys[i*nq],1); + Exp->IProductWRTBase(phys +i*nq, tmp = coeffs1 + i*Exp->GetNcoeffs()); + } + + c.ApplyOperator(Collections::eIProductWRTBase, phys, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_StdMat_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eStdMat); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array phys(nelmts*nq, 0.0); + Array coeffs1(nelmts*Exp->GetNcoeffs(), 0.0); + Array coeffs2(nelmts*Exp->GetNcoeffs(), 0.0); + Array tmp; + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->IProductWRTBase(phys, coeffs1); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,&phys[0],1,&phys[i*nq],1); + Exp->IProductWRTBase(phys +i*nq, tmp = coeffs1 + i*Exp->GetNcoeffs()); + } + + c.ApplyOperator(Collections::eIProductWRTBase, phys, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_SumFac_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + Array phys(nelmts*nq, 0.0); + Array coeffs1(nelmts*Exp->GetNcoeffs(), 0.0); + Array coeffs2(nelmts*Exp->GetNcoeffs(), 0.0); + Array tmp; + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + } + Exp->IProductWRTBase(phys, coeffs1); + + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,&phys[0],1,&phys[i*nq],1); + Exp->IProductWRTBase(phys +i*nq, tmp = coeffs1 + i*Exp->GetNcoeffs()); + } + + c.ApplyOperator(Collections::eIProductWRTBase, phys, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + // clamp values below 1e-14 to zero + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_IterPerExp_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + const int nm = Exp->GetNcoeffs(); + Array phys1(nelmts*nq),tmp; + Array phys2(nelmts*nq); + Array phys3(nelmts*nq); + Array coeffs1(nelmts*nm); + Array coeffs2(nelmts*nm); + + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys1[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + phys2[i] = cos(xc[i])*sin(yc[i])*cos(zc[i]); + phys3[i] = cos(xc[i])*sin(yc[i])*sin(zc[i]); + } + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys1,1,tmp = phys1+i*nq,1); + Vmath::Vcopy(nq,phys2,1,tmp = phys2+i*nq,1); + Vmath::Vcopy(nq,phys3,1,tmp = phys3+i*nq,1); + } + + // Standard routines + for(int i = 0; i < nelmts; ++i) + { + Exp->IProductWRTDerivBase(0, phys1 + i*nq, tmp = coeffs1 + i*nm); + Exp->IProductWRTDerivBase(1, phys2 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + Exp->IProductWRTDerivBase(2, phys3 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + } + + c.ApplyOperator(Collections::eIProductWRTDerivBase, phys1, + phys2, phys3, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_StdMat_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eStdMat); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + const int nm = Exp->GetNcoeffs(); + Array phys1(nelmts*nq),tmp; + Array phys2(nelmts*nq); + Array phys3(nelmts*nq); + Array coeffs1(nelmts*nm); + Array coeffs2(nelmts*nm); + + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys1[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + phys2[i] = cos(xc[i])*sin(yc[i])*cos(zc[i]); + phys3[i] = cos(xc[i])*sin(yc[i])*sin(zc[i]); + } + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys1,1,tmp = phys1+i*nq,1); + Vmath::Vcopy(nq,phys2,1,tmp = phys2+i*nq,1); + Vmath::Vcopy(nq,phys3,1,tmp = phys3+i*nq,1); + } + + // Standard routines + for(int i = 0; i < nelmts; ++i) + { + Exp->IProductWRTDerivBase(0, phys1 + i*nq, tmp = coeffs1 + i*nm); + Exp->IProductWRTDerivBase(1, phys2 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + Exp->IProductWRTDerivBase(2, phys3 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + } + + c.ApplyOperator(Collections::eIProductWRTDerivBase, phys1, + phys2, phys3, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_SumFac_UniformP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + const int nm = Exp->GetNcoeffs(); + Array phys1(nelmts*nq),tmp; + Array phys2(nelmts*nq); + Array phys3(nelmts*nq); + Array coeffs1(nelmts*nm); + Array coeffs2(nelmts*nm); + + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys1[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + phys2[i] = cos(xc[i])*sin(yc[i])*cos(zc[i]); + phys3[i] = cos(xc[i])*sin(yc[i])*sin(zc[i]); + } + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys1,1,tmp = phys1+i*nq,1); + Vmath::Vcopy(nq,phys2,1,tmp = phys2+i*nq,1); + Vmath::Vcopy(nq,phys3,1,tmp = phys3+i*nq,1); + } + + // Standard routines + for(int i = 0; i < nelmts; ++i) + { + Exp->IProductWRTDerivBase(0, phys1 + i*nq, tmp = coeffs1 + i*nm); + Exp->IProductWRTDerivBase(1, phys2 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + Exp->IProductWRTDerivBase(2, phys3 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + } + + c.ApplyOperator(Collections::eIProductWRTDerivBase, phys1, + phys2, phys3, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_IterPerExp_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eIterPerExp); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + const int nm = Exp->GetNcoeffs(); + Array phys1(nelmts*nq),tmp; + Array phys2(nelmts*nq); + Array phys3(nelmts*nq); + Array coeffs1(nelmts*nm); + Array coeffs2(nelmts*nm); + + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys1[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + phys2[i] = cos(xc[i])*sin(yc[i])*cos(zc[i]); + phys3[i] = cos(xc[i])*sin(yc[i])*sin(zc[i]); + } + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys1,1,tmp = phys1+i*nq,1); + Vmath::Vcopy(nq,phys2,1,tmp = phys2+i*nq,1); + Vmath::Vcopy(nq,phys3,1,tmp = phys3+i*nq,1); + } + + // Standard routines + for(int i = 0; i < nelmts; ++i) + { + Exp->IProductWRTDerivBase(0, phys1 + i*nq, tmp = coeffs1 + i*nm); + Exp->IProductWRTDerivBase(1, phys2 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + Exp->IProductWRTDerivBase(2, phys3 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + } + + c.ApplyOperator(Collections::eIProductWRTDerivBase, phys1, + phys2, phys3, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_StdMat_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eStdMat); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + const int nm = Exp->GetNcoeffs(); + Array phys1(nelmts*nq),tmp; + Array phys2(nelmts*nq); + Array phys3(nelmts*nq); + Array coeffs1(nelmts*nm); + Array coeffs2(nelmts*nm); + + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys1[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + phys2[i] = cos(xc[i])*sin(yc[i])*cos(zc[i]); + phys3[i] = cos(xc[i])*sin(yc[i])*sin(zc[i]); + } + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys1,1,tmp = phys1+i*nq,1); + Vmath::Vcopy(nq,phys2,1,tmp = phys2+i*nq,1); + Vmath::Vcopy(nq,phys3,1,tmp = phys3+i*nq,1); + } + + // Standard routines + for(int i = 0; i < nelmts; ++i) + { + Exp->IProductWRTDerivBase(0, phys1 + i*nq, tmp = coeffs1 + i*nm); + Exp->IProductWRTDerivBase(1, phys2 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + Exp->IProductWRTDerivBase(2, phys3 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + } + + c.ApplyOperator(Collections::eIProductWRTDerivBase, phys1, + phys2, phys3, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } + + BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_SumFac_VariableP_MultiElmt) + { + SpatialDomains::PointGeomSharedPtr v0(new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5)); + SpatialDomains::PointGeomSharedPtr v1(new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); + SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); + SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); + + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + + Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); + Nektar::LibUtilities::BasisType basisTypeDir1 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1,4,PointsKeyDir1); + + Nektar::LibUtilities::PointsType PointsTypeDir2 = Nektar::LibUtilities::eGaussLobattoLegendre; + const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2); + Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; + const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); + + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; + const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); + Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; + const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); + + + + Nektar::LocalRegions::PyrExpSharedPtr Exp = + MemoryManager::AllocateSharedPtr(basisKeyDir1, + basisKeyDir2, + basisKeyDir3, + pyrGeom); + + int nelmts = 10; + + std::vector CollExp; + for(int i = 0; i < nelmts; ++i) + { + CollExp.push_back(Exp); + } + + LibUtilities::SessionReaderSharedPtr dummySession; + Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); + Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::Collection c(CollExp, impTypes); + + const int nq = Exp->GetTotPoints(); + const int nm = Exp->GetNcoeffs(); + Array phys1(nelmts*nq),tmp; + Array phys2(nelmts*nq); + Array phys3(nelmts*nq); + Array coeffs1(nelmts*nm); + Array coeffs2(nelmts*nm); + + Array xc(nq), yc(nq), zc(nq); + + Exp->GetCoords(xc, yc, zc); + + for (int i = 0; i < nq; ++i) + { + phys1[i] = sin(xc[i])*cos(yc[i])*sin(zc[i]); + phys2[i] = cos(xc[i])*sin(yc[i])*cos(zc[i]); + phys3[i] = cos(xc[i])*sin(yc[i])*sin(zc[i]); + } + for(int i = 1; i < nelmts; ++i) + { + Vmath::Vcopy(nq,phys1,1,tmp = phys1+i*nq,1); + Vmath::Vcopy(nq,phys2,1,tmp = phys2+i*nq,1); + Vmath::Vcopy(nq,phys3,1,tmp = phys3+i*nq,1); + } + + // Standard routines + for(int i = 0; i < nelmts; ++i) + { + Exp->IProductWRTDerivBase(0, phys1 + i*nq, tmp = coeffs1 + i*nm); + Exp->IProductWRTDerivBase(1, phys2 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + Exp->IProductWRTDerivBase(2, phys3 + i*nq, tmp = coeffs2 + i*nm); + Vmath::Vadd(nm,coeffs1+i*nm ,1,coeffs2+i*nm ,1,tmp = coeffs1 + i*nm,1); + } + + c.ApplyOperator(Collections::eIProductWRTDerivBase, phys1, + phys2, phys3, coeffs2); + + double epsilon = 1.0e-8; + for(int i = 0; i < coeffs1.num_elements(); ++i) + { + coeffs1[i] = (fabs(coeffs1[i]) < 1e-14)? 0.0: coeffs1[i]; + coeffs2[i] = (fabs(coeffs2[i]) < 1e-14)? 0.0: coeffs2[i]; + BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); + } + } +#endif + + } +} -- GitLab From 2bde118c1e3d51c2387b63c01a2b657d91ac4f5c Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 20 Mar 2017 14:38:28 +0000 Subject: [PATCH 16/27] Added IproductWRTBase into Collections and associated UnitTests --- library/Collections/IProduct.cpp | 95 +++++++++++++++++++ library/Collections/IProduct.h | 13 +++ library/Collections/IProductWRTBase.cpp | 94 ++++++++++++++++++ library/StdRegions/StdPyrExp.cpp | 4 + .../Collections/TestPyrCollection.cpp | 40 ++++---- 5 files changed, 225 insertions(+), 21 deletions(-) diff --git a/library/Collections/IProduct.cpp b/library/Collections/IProduct.cpp index c33d5e48b..ec2cd3309 100644 --- a/library/Collections/IProduct.cpp +++ b/library/Collections/IProduct.cpp @@ -422,6 +422,101 @@ void PrismIProduct(bool sortTopVertex, int numElmt, } +/** + * + */ +void PyrIProduct(bool sortTopVertex, int numElmt, + int nquad0, int nquad1, int nquad2, + int nmodes0, int nmodes1, int nmodes2, + const Array &base0, + const Array &base1, + const Array &base2, + const Array &jac, + const Array &input, + Array &output, + Array &wsp) +{ + int totmodes = LibUtilities::StdPyrData::getNumberOfCoefficients( + nmodes0,nmodes1,nmodes2); + int totpoints = nquad0*nquad1*nquad2; + int cnt; + int mode, mode1; + + ASSERTL1(wsp.num_elements() >= numElmt*(nquad1*nquad2*nmodes0 + + nquad2*max(nquad0*nquad1,nmodes0*nmodes1)), + "Insufficient workspace size"); + + Vmath::Vmul(numElmt*totpoints,jac,1,input,1,wsp,1); + + Array wsp1 = wsp + numElmt * nquad2 + * (max(nquad0*nquad1, + nmodes0*nmodes1)); + + // Perform iproduct with respect to the '0' direction + Blas::Dgemm('T', 'N', nquad1*nquad2*numElmt, nmodes0, nquad0, + 1.0, wsp.get(), nquad0, base0.get(), + nquad0, 0.0, wsp1.get(), nquad1*nquad2*numElmt); + + // Inner product with respect to the '1' direction + mode = 0; + for(int i=0; i < nmodes0; ++i) + { + Blas::Dgemm('T', 'N', nquad2*numElmt, nmodes1, nquad1, + 1.0, wsp1.get()+ i*nquad1*nquad2*numElmt, nquad1, + base1.get(), nquad1, + 0.0, wsp.get() + mode*nquad2*numElmt,nquad2*numElmt); + mode += nmodes1; + } + + // Inner product with respect to the '2' direction + mode = mode1 = cnt = 0; + for(int i = 0; i < nmodes0; ++i) + { + for(int j = 0; j < nmodes1; ++j, ++cnt) + { + int ijmax = max(i,j); + Blas::Dgemm('T', 'N', nmodes2-ijmax, numElmt, nquad2, + 1.0, base2.get()+mode*nquad2, nquad2, + wsp.get()+cnt*nquad2*numElmt, nquad2, + 0.0, output.get()+mode1, totmodes); + mode += nmodes2-ijmax; + mode1 += nmodes2-ijmax; + } + + //increment mode in case order1!=order2 + for(int j = nmodes1; j < nmodes2; ++j) + { + int ijmax = max(i,j); + mode += nmodes2-ijmax; + } + } + + // fix for modified basis for top singular vertex component + // Already have evaluated (1+c)/2 (1-b)/2 (1-a)/2 + if(sortTopVertex) + { + for(int n = 0; n < numElmt; ++n) + { + // add in (1+c)/2 (1+b)/2 component + output[1+n*totmodes] += Blas::Ddot(nquad2, + base2.get()+nquad2,1, + &wsp[nquad2*numElmt + n*nquad2],1); + + // add in (1+c)/2 (1-b)/2 (1+a)/2 component + output[1+n*totmodes] += Blas::Ddot(nquad2, + base2.get()+nquad2,1, + &wsp[nquad2*nmodes1*numElmt+n*nquad2],1); + + // add in (1+c)/2 (1+b)/2 (1+a)/2 component + output[1+n*totmodes] += Blas::Ddot(nquad2, + base2.get()+nquad2,1, + &wsp[nquad2*(nmodes1+1)*numElmt+n*nquad2],1); + } + } +} + + + /** * */ diff --git a/library/Collections/IProduct.h b/library/Collections/IProduct.h index 6aa96ca3b..792021340 100644 --- a/library/Collections/IProduct.h +++ b/library/Collections/IProduct.h @@ -82,6 +82,19 @@ void PrismIProduct(bool sortTopVert, int numElmt, Array &output, Array &wsp); + +void PyrIProduct(bool sortTopVert, int numElmt, + int nquad0, int nquad1, int nquad2, + int nmodes0, int nmodes1, int nmodes2, + const Array &base0, + const Array &base1, + const Array &base2, + const Array &jac, + const Array &input, + Array &output, + Array &wsp); + + void TetIProduct(bool sortTopEdge, int numElmt, int nquad0, int nquad1, int nquad2, int nmodes0, int nmodes1, int nmodes2, diff --git a/library/Collections/IProductWRTBase.cpp b/library/Collections/IProductWRTBase.cpp index 87e3e1877..73ed03989 100644 --- a/library/Collections/IProductWRTBase.cpp +++ b/library/Collections/IProductWRTBase.cpp @@ -856,5 +856,99 @@ OperatorKey IProductWRTBase_SumFac_Prism::m_type = GetOperatorFactory(). OperatorKey(ePrism, eIProductWRTBase, eSumFac,false), IProductWRTBase_SumFac_Prism::create, "IProductWRTBase_SumFac_Prism"); + +/** + * @brief Backward transform operator using sum-factorisation (Pyr) + */ +class IProductWRTBase_SumFac_Pyr : public Operator +{ + public: + OPERATOR_CREATE(IProductWRTBase_SumFac_Pyr) + + virtual ~IProductWRTBase_SumFac_Pyr() + { + } + + virtual void operator()( + const Array &input, + Array &output, + Array &output1, + Array &output2, + Array &wsp) + { + + ASSERTL1(wsp.num_elements() == m_wspSize, + "Incorrect workspace size"); + + PyrIProduct(m_sortTopVertex, m_numElmt, + m_nquad0, m_nquad1, m_nquad2, + m_nmodes0, m_nmodes1, m_nmodes2, + m_base0, m_base1, m_base2, + m_jac,input,output,wsp); + } + + virtual void operator()( + int dir, + const Array &input, + Array &output, + Array &wsp) + { + ASSERTL0(false, "Not valid for this operator."); + } + + protected: + const int m_nquad0; + const int m_nquad1; + const int m_nquad2; + const int m_nmodes0; + const int m_nmodes1; + const int m_nmodes2; + Array m_jac; + Array m_base0; + Array m_base1; + Array m_base2; + bool m_sortTopVertex; + + private: + IProductWRTBase_SumFac_Pyr( + vector pCollExp, + CoalescedGeomDataSharedPtr pGeomData) + : Operator (pCollExp, pGeomData), + m_nquad0 (m_stdExp->GetNumPoints(0)), + m_nquad1 (m_stdExp->GetNumPoints(1)), + m_nquad2 (m_stdExp->GetNumPoints(2)), + m_nmodes0 (m_stdExp->GetBasisNumModes(0)), + m_nmodes1 (m_stdExp->GetBasisNumModes(1)), + m_nmodes2 (m_stdExp->GetBasisNumModes(2)), + m_base0 (m_stdExp->GetBasis(0)->GetBdata()), + m_base1 (m_stdExp->GetBasis(1)->GetBdata()), + m_base2 (m_stdExp->GetBasis(2)->GetBdata()) + + { + m_jac = pGeomData->GetJacWithStdWeights(pCollExp); + + m_wspSize = m_numElmt * m_nquad2 + *(max(m_nquad0*m_nquad1,m_nmodes0*m_nmodes1)) + + m_nquad1*m_nquad2*m_numElmt*m_nmodes0; + + if(m_stdExp->GetBasis(0)->GetBasisType() + == LibUtilities::eModified_A) + { + m_sortTopVertex = true; + } + else + { + m_sortTopVertex = false; + } + } +}; + +/// Factory initialisation for the IProductWRTBase_SumFac_Pyr operator +OperatorKey IProductWRTBase_SumFac_Pyr::m_type = GetOperatorFactory(). + RegisterCreatorFunction( + OperatorKey(ePyramid, eIProductWRTBase, eSumFac,false), + IProductWRTBase_SumFac_Pyr::create, "IProductWRTBase_SumFac_Pyr"); + + } } diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index 3cebba2ad..91234df9a 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -493,6 +493,10 @@ namespace Nektar int order1 = m_base[1]->GetNumModes(); int order2 = m_base[2]->GetNumModes(); + ASSERTL1(wsp.num_elements() >= nquad1*nquad2*order0 + + nquad2*order0*order1, + "Insufficient workspace size"); + Array tmp1 = wsp; Array tmp2 = wsp + nquad1*nquad2*order0; diff --git a/library/UnitTests/Collections/TestPyrCollection.cpp b/library/UnitTests/Collections/TestPyrCollection.cpp index 5559290c4..afa456d0e 100644 --- a/library/UnitTests/Collections/TestPyrCollection.cpp +++ b/library/UnitTests/Collections/TestPyrCollection.cpp @@ -935,7 +935,6 @@ namespace Nektar BOOST_CHECK_CLOSE(diff1[i],diff2[i], epsilon); } } -#if 0 BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_IterPerExp_UniformP_MultiElmt) { @@ -944,9 +943,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -958,7 +956,7 @@ namespace Nektar Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); - Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); @@ -1024,9 +1022,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1038,7 +1035,7 @@ namespace Nektar Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); - Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); @@ -1105,9 +1102,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1119,7 +1115,7 @@ namespace Nektar Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,4,PointsKeyDir2); - Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3); Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,4,PointsKeyDir3); @@ -1142,7 +1138,9 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::OperatorImpMap impTypes; + impTypes[Collections::eIProductWRTBase] = Collections::eSumFac; Collections::Collection c(CollExp, impTypes); const int nq = Exp->GetTotPoints(); @@ -1186,9 +1184,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1200,7 +1197,7 @@ namespace Nektar Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); - Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); @@ -1267,9 +1264,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1281,7 +1277,7 @@ namespace Nektar Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); - Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); @@ -1348,9 +1344,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1362,7 +1357,7 @@ namespace Nektar Nektar::LibUtilities::BasisType basisTypeDir2 = Nektar::LibUtilities::eModified_A; const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2,6,PointsKeyDir2); - Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussLobattoLegendre; + Nektar::LibUtilities::PointsType PointsTypeDir3 = Nektar::LibUtilities::eGaussRadauMAlpha2Beta0; const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3); Nektar::LibUtilities::BasisType basisTypeDir3 = Nektar::LibUtilities::eModifiedPyr_C; const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3,8,PointsKeyDir3); @@ -1385,7 +1380,9 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); + Collections::OperatorImpMap impTypes; + impTypes[Collections::eIProductWRTBase] = Collections::eSumFac; Collections::Collection c(CollExp, impTypes); const int nq = Exp->GetTotPoints(); @@ -1421,6 +1418,7 @@ namespace Nektar } } +#if 0 BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_IterPerExp_UniformP_MultiElmt) { -- GitLab From 53ae6c4d10940054e49f09917621d12c3ebfcd63 Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 20 Mar 2017 18:59:04 +0000 Subject: [PATCH 17/27] Added check for memory in IprodctWRTBase and found error in one of the setup of htis memory --- library/StdRegions/StdPyrExp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index 91234df9a..982e61f3d 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -450,7 +450,7 @@ namespace Nektar int order0 = m_base[0]->GetNumModes(); int order1 = m_base[1]->GetNumModes(); - Array wsp(order0*nquad1*(nquad2 + order1)); + Array wsp(order0*nquad2*(nquad1 + order1)); if(multiplybyweights) { -- GitLab From 14e3e2f19dabae90dee3d061a27b38d9b85049dd Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 20 Mar 2017 18:59:32 +0000 Subject: [PATCH 18/27] Added collection routien for IProductWRTDerivBase and associated regression tests --- library/Collections/IProductWRTDerivBase.cpp | 231 ++++++++++++++++++ .../Collections/TestPyrCollection.cpp | 27 +- 2 files changed, 237 insertions(+), 21 deletions(-) diff --git a/library/Collections/IProductWRTDerivBase.cpp b/library/Collections/IProductWRTDerivBase.cpp index ee1557a11..211d9ee11 100644 --- a/library/Collections/IProductWRTDerivBase.cpp +++ b/library/Collections/IProductWRTDerivBase.cpp @@ -1453,5 +1453,236 @@ OperatorKey IProductWRTDerivBase_SumFac_Prism::m_type = GetOperatorFactory(). IProductWRTDerivBase_SumFac_Prism::create, "IProductWRTDerivBase_SumFac_Prism"); + + +/** + * @brief Inner product WRT deriv base operator using sum-factorisation (Pyr) + */ +class IProductWRTDerivBase_SumFac_Pyr : public Operator +{ + public: + OPERATOR_CREATE(IProductWRTDerivBase_SumFac_Pyr) + + virtual ~IProductWRTDerivBase_SumFac_Pyr() + { + } + + virtual void operator()( + const Array &entry0, + Array &entry1, + Array &entry2, + Array &entry3, + Array &wsp) + { + unsigned int nPhys = m_stdExp->GetTotPoints(); + unsigned int ntot = m_numElmt*nPhys; + unsigned int nmodes = m_stdExp->GetNcoeffs(); + unsigned int nmax = max(ntot,m_numElmt*nmodes); + Array > in(3); + Array output, wsp1; + Array > tmp(3); + + in[0] = entry0; in[1] = entry1; + in[2] = entry2; + + output = entry3; + + for(int i = 0; i < 3; ++i) + { + tmp[i] = wsp + i*nmax; + } + + // calculate (dphi/dx,in[0]) = ((dphi/dxi_0 dxi_0/dx + + // dphi/dxi_1 dxi_1/dx),in[0]) + // + (dphi/dy,in[1]) = ((dphi/dxi_0 dxi_0/dy + + // dphi/dxi_1 dxi_1/dy),in[1]) + // + (dphi/dz,in[2]) = ((dphi/dxi_0 dxi_0/dz + + // dphi/dxi_1 dxi_1/dz),in[2]) + // + // Note dphi/dxi_0 = + // dphi/deta_0 deta_0/dxi_0 = dphi/deta_0 2/(1-eta_2) + // + // Note dphi/dxi_1 = + // dphi/deta_1 deta_1/dxi_1 = dphi/deta_1 2/(1-eta_2) + // + // dphi/dxi_2 = + // dphi/deta_0 deta_0/dxi_2 + dphi/deta_1 deta_1/dxi_2 + + // + dphi/deta_2 deta_2/dxi_2 = + // dphi/deta_0 (1+eta_0)/(1-eta_2) + + // dphi/deta_1 (1+eta_1)/(1-eta_2) + dphi/deta_2 + // + // and so the full inner products are + // + // (dphi/dx,in[0]) + (dphi/dy,in[1]) + (dphi/dz,in[2]) + // = (dphi/deta_0, ((2/(1-eta_2) (dxi_0/dx in[0] + dxi_0/dy in[1] + // + dxi_0/dz in[2]) + // + (1_eta_0)/(1-eta_2) (dxi_2/dx in[0] + dxi_2/dy in[1] + // + dxi_2/dz in[2] )) + // + (dphi/deta_1, ((2/(1-eta_2) (dxi_1/dx in[0] + dxi_0/dy in[1] + // + dxi_0/dz in[2]) + // + (1_eta_1)/(1-eta_2) (dxi_2/dx in[0] + dxi_2/dy in[1] + // + dxi_2/dz in[2] )) + // + (dphi/deta_2, (dxi_2/dx in[0] + dxi_2/dy in[1] + // + dxi_2/dz in[2])) + + + for(int i = 0; i < 3; ++i) + { + Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1, tmp[i],1); + for(int j = 1; j < 3; ++j) + { + Vmath::Vvtvp (ntot,m_derivFac[i+3*j],1, + in[j],1, tmp[i], 1, tmp[i],1); + } + } + wsp1 = wsp + 3*nmax; + + // Sort into eta factors + for (int i = 0; i < m_numElmt; ++i) + { + // scale tmp[0] by fac0 + Vmath::Vmul(nPhys,&m_fac0[0],1,tmp[0].get()+i*nPhys,1, + tmp[0].get()+i*nPhys,1); + + // scale tmp[2] by fac1 and add to tmp0 + Vmath::Vvtvp(nPhys,&m_fac1[0],1,tmp[2].get()+i*nPhys,1, + tmp[0].get()+i*nPhys,1,tmp[0].get()+i*nPhys,1); + + // scale tmp[1] by fac0 + Vmath::Vmul(nPhys,&m_fac0[0],1,tmp[1].get()+i*nPhys,1, + tmp[1].get()+i*nPhys,1); + + // scale tmp[2] by fac2 and add to tmp1 + Vmath::Vvtvp(nPhys,&m_fac2[0],1,tmp[2].get()+i*nPhys,1, + tmp[1].get()+i*nPhys,1,tmp[1].get()+i*nPhys,1); + } + + // calculate Iproduct WRT Std Deriv + PyrIProduct(m_sortTopVertex, m_numElmt, + m_nquad0, m_nquad1, m_nquad2, + m_nmodes0, m_nmodes1, m_nmodes2, + m_derbase0, m_base1, m_base2, + m_jac,tmp[0],output,wsp1); + + PyrIProduct(m_sortTopVertex, m_numElmt, + m_nquad0, m_nquad1, m_nquad2, + m_nmodes0, m_nmodes1, m_nmodes2, + m_base0, m_derbase1, m_base2, + m_jac,tmp[1],tmp[0],wsp1); + Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1); + + PyrIProduct(m_sortTopVertex, m_numElmt, + m_nquad0, m_nquad1, m_nquad2, + m_nmodes0, m_nmodes1, m_nmodes2, + m_base0, m_base1, m_derbase2, + m_jac,tmp[2],tmp[0],wsp1); + Vmath::Vadd(m_numElmt*nmodes,tmp[0],1,output,1,output,1); + } + + virtual void operator()( + int dir, + const Array &input, + Array &output, + Array &wsp) + { + ASSERTL0(false, "Not valid for this operator."); + } + + + protected: + const int m_nquad0; + const int m_nquad1; + const int m_nquad2; + const int m_nmodes0; + const int m_nmodes1; + const int m_nmodes2; + Array m_jac; + Array m_base0; + Array m_base1; + Array m_base2; + Array m_derbase0; + Array m_derbase1; + Array m_derbase2; + Array m_derivFac; + Array m_fac0; + Array m_fac1; + Array m_fac2; + bool m_sortTopVertex; + + private: + IProductWRTDerivBase_SumFac_Pyr( + vector pCollExp, + CoalescedGeomDataSharedPtr pGeomData) + : Operator (pCollExp, pGeomData), + m_nquad0 (m_stdExp->GetNumPoints(0)), + m_nquad1 (m_stdExp->GetNumPoints(1)), + m_nquad2 (m_stdExp->GetNumPoints(2)), + m_nmodes0 (m_stdExp->GetBasisNumModes(0)), + m_nmodes1 (m_stdExp->GetBasisNumModes(1)), + m_nmodes2 (m_stdExp->GetBasisNumModes(2)), + m_base0 (m_stdExp->GetBasis(0)->GetBdata()), + m_base1 (m_stdExp->GetBasis(1)->GetBdata()), + m_base2 (m_stdExp->GetBasis(2)->GetBdata()), + m_derbase0(m_stdExp->GetBasis(0)->GetDbdata()), + m_derbase1(m_stdExp->GetBasis(1)->GetDbdata()), + m_derbase2(m_stdExp->GetBasis(2)->GetDbdata()) + + { + m_jac = pGeomData->GetJacWithStdWeights(pCollExp); + m_wspSize = 6 * m_numElmt * (max(m_nquad0*m_nquad1*m_nquad2, + m_nmodes0*m_nmodes1*m_nmodes2)); + m_derivFac = pGeomData->GetDerivFactors(pCollExp); + + if(m_stdExp->GetBasis(0)->GetBasisType() + == LibUtilities::eModified_A) + { + m_sortTopVertex = true; + } + else + { + m_sortTopVertex = false; + } + + const Array& z0 + = m_stdExp->GetBasis(0)->GetZ(); + const Array& z1 + = m_stdExp->GetBasis(1)->GetZ(); + const Array& z2 + = m_stdExp->GetBasis(2)->GetZ(); + + m_fac0 = Array(m_nquad0*m_nquad1*m_nquad2); + m_fac1 = Array(m_nquad0*m_nquad1*m_nquad2); + m_fac2 = Array(m_nquad0*m_nquad1*m_nquad2); + + for (int i = 0; i < m_nquad0; ++i) + { + for(int j = 0; j < m_nquad1; ++j) + { + for(int k = 0; k < m_nquad2; ++k) + { + // set up geometric factor: 2/(1-z2) + m_fac0[i + j*m_nquad0 + k*m_nquad0*m_nquad1] + = 2.0/(1-z2[k]); + // set up geometric factor: (1+z0)/(1-z2) + m_fac1[i + j*m_nquad0 + k*m_nquad0*m_nquad1] + = (1+z0[i])/(1-z2[k]); + // set up geometric factor: (1+z1)/(1-z2) + m_fac2[i + j*m_nquad0 + k*m_nquad0*m_nquad1] + = (1+z1[j])/(1-z2[k]); + + } + } + } + } +}; + +/// Factory initialisation for the IProductWRTDerivBase_SumFac_Pyr operator +OperatorKey IProductWRTDerivBase_SumFac_Pyr::m_type = GetOperatorFactory(). + RegisterCreatorFunction( + OperatorKey(ePyramid, eIProductWRTDerivBase, eSumFac, false), + IProductWRTDerivBase_SumFac_Pyr::create, + "IProductWRTDerivBase_SumFac_Pyr"); + + } } diff --git a/library/UnitTests/Collections/TestPyrCollection.cpp b/library/UnitTests/Collections/TestPyrCollection.cpp index afa456d0e..1808d0843 100644 --- a/library/UnitTests/Collections/TestPyrCollection.cpp +++ b/library/UnitTests/Collections/TestPyrCollection.cpp @@ -308,7 +308,6 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); Collections::OperatorImpMap impTypes; impTypes[Collections::eBwdTrans] = Collections::eSumFac; Collections::Collection c(CollExp, impTypes); @@ -497,7 +496,6 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); Collections::OperatorImpMap impTypes; impTypes[Collections::eBwdTrans] = Collections::eSumFac; Collections::Collection c(CollExp, impTypes); @@ -727,7 +725,6 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); Collections::OperatorImpMap impTypes; impTypes[Collections::ePhysDeriv] = Collections::eSumFac; Collections::Collection c(CollExp, impTypes); @@ -896,7 +893,6 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); Collections::OperatorImpMap impTypes; impTypes[Collections::ePhysDeriv] = Collections::eSumFac; @@ -1138,7 +1134,6 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); Collections::OperatorImpMap impTypes; impTypes[Collections::eIProductWRTBase] = Collections::eSumFac; Collections::Collection c(CollExp, impTypes); @@ -1380,7 +1375,6 @@ namespace Nektar LibUtilities::SessionReaderSharedPtr dummySession; Collections::CollectionOptimisation colOpt(dummySession, Collections::eSumFac); - //Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp); Collections::OperatorImpMap impTypes; impTypes[Collections::eIProductWRTBase] = Collections::eSumFac; Collections::Collection c(CollExp, impTypes); @@ -1418,7 +1412,6 @@ namespace Nektar } } -#if 0 BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_IterPerExp_UniformP_MultiElmt) { @@ -1427,9 +1420,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1520,9 +1512,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1612,9 +1603,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1707,9 +1697,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1802,9 +1791,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1896,9 +1884,8 @@ namespace Nektar SpatialDomains::PointGeomSharedPtr v2(new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v3(new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0)); SpatialDomains::PointGeomSharedPtr v4(new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0)); - SpatialDomains::PointGeomSharedPtr v5(new SpatialDomains::PointGeom(3u, 5u, -1.0, 1.0, 1.0)); - SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4, v5); + SpatialDomains::PyrGeomSharedPtr pyrGeom = CreatePyr(v0, v1, v2, v3, v4); Nektar::LibUtilities::PointsType PointsTypeDir1 = Nektar::LibUtilities::eGaussLobattoLegendre; const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1); @@ -1982,7 +1969,5 @@ namespace Nektar BOOST_CHECK_CLOSE(coeffs1[i],coeffs2[i], epsilon); } } -#endif - } } -- GitLab From 42c7bd3861f959bbed768963e807d2925efe2b38 Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 20 Mar 2017 19:09:25 +0000 Subject: [PATCH 19/27] Updated the comment to OrthoPyr_C to reflect issue of the space of the orthogonal expansion with regard to the modified expansion --- library/LibUtilities/Foundations/Basis.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/library/LibUtilities/Foundations/Basis.cpp b/library/LibUtilities/Foundations/Basis.cpp index a74874ccf..94d5d1a52 100644 --- a/library/LibUtilities/Foundations/Basis.cpp +++ b/library/LibUtilities/Foundations/Basis.cpp @@ -328,14 +328,25 @@ namespace Nektar } break; - /** \brief Orthogonal basis C for Pyramid expansion (which is richer than tets) + /** \brief Orthogonal basis C for Pyramid expansion + (which is richer than tets) - \f$\tilde \psi_{pqr}^c = \left ( {1 - \eta_3} \over 2\right)^{pq} P_r^{2pq+2, 0}(\eta_3)\f$ - \f$ \mbox{where }pq = max(p+q-1,0) \f$ + \f$\tilde \psi_{pqr}^c = \left ( {1 - \eta_3} \over + 2\right)^{pq} P_r^{2pq+2, 0}(\eta_3)\f$ \f$ \mbox{where + }pq = max(p+q,0) \f$ + This orthogonal expansion has modes that are + always in the Cartesian space, however the + equivalent ModifiedPyr_C has vertex modes that do + not lie in this space. If one chooses \f$pq = + max(p+q-1,0)\f$ then the expansion will space the + same space as the vertices but the order of the + expanion in 'r' is reduced by one. + + 1) Eta_z values are the changing the fastest, then + r, q, and finally p. 2) r index increases by the + stride of numPoints. */ - // 1) Eta_z values are the changing the fastest, then r, q, and finally p. - // 2) r index increases by the stride of numPoints. case eOrthoPyr_C: { int P = numModes - 1, Q = numModes - 1, R = numModes - 1; -- GitLab From 2307d9dbd049923e94da6e5fdc1bd81c29ad2875 Mon Sep 17 00:00:00 2001 From: ssherw Date: Mon, 3 Apr 2017 21:07:38 +0100 Subject: [PATCH 20/27] Tidy up suggestions from Dave --- library/LocalRegions/PyrExp.cpp | 27 --------------------------- library/StdRegions/StdExpansion.cpp | 7 ------- library/StdRegions/StdPyrExp.cpp | 8 +++++++- 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/library/LocalRegions/PyrExp.cpp b/library/LocalRegions/PyrExp.cpp index 9c94b138e..90a298705 100644 --- a/library/LocalRegions/PyrExp.cpp +++ b/library/LocalRegions/PyrExp.cpp @@ -317,33 +317,6 @@ namespace Nektar } -#if 0 - void PyrExp::v_IProductWRTBase( - const Array &inarray, - Array &outarray) - { - int nquad0 = m_base[0]->GetNumPoints(); - int nquad1 = m_base[1]->GetNumPoints(); - int nquad2 = m_base[2]->GetNumPoints(); - Array jac = m_metricinfo->GetJac(GetPointsKeys()); - Array tmp(nquad0*nquad1*nquad2); - - // multiply inarray with Jacobian - if(m_metricinfo->GetGtype() == SpatialDomains::eDeformed) - { - Vmath::Vmul(nquad0*nquad1*nquad2,&jac[0],1,(NekDouble*)&inarray[0],1,&tmp[0],1); - } - else - { - Vmath::Smul(nquad0*nquad1*nquad2,jac[0],(NekDouble*)&inarray[0],1,&tmp[0],1); - } - - StdPyrExp::v_IProductWRTBase(tmp,outarray); - } -#endif - - - /** * @brief Calculates the inner product \f$ I_{pqr} = (u, * \partial_{x_i} \phi_{pqr}) \f$. diff --git a/library/StdRegions/StdExpansion.cpp b/library/StdRegions/StdExpansion.cpp index ebf2a2a2c..46f9ff1a8 100644 --- a/library/StdRegions/StdExpansion.cpp +++ b/library/StdRegions/StdExpansion.cpp @@ -671,13 +671,6 @@ namespace Nektar int nq = GetTotPoints(); Array tmp(nq); - static int cnt = 0; - cnt++; - if(cnt == 84) - { - std::cout << "Start" << std::endl; - } - v_BwdTrans(inarray,tmp); if(mkey.HasVarCoeff(eVarCoeffMass)) diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index 982e61f3d..3830aa967 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -1954,7 +1954,13 @@ namespace Nektar { if(j + k >= cutoff || i + k >= cutoff) { - orthocoeffs[cnt] *= (SvvDiffCoeff*exp(-(i+k-nmodes)*(i+k-nmodes)/((NekDouble)((i+k-cutoff+epsilon)*(i+k-cutoff+epsilon))))*exp(-(j-nmodes)*(j-nmodes)/((NekDouble)((j-cutoff+epsilon)*(j-cutoff+epsilon))))); + orthocoeffs[cnt] *= + (SvvDiffCoeff*exp(-(i+k-nmodes)*(i+k-nmodes)/ + ((NekDouble)((i+k-cutoff+epsilon)* + (i+k-cutoff+epsilon))))* + exp(-(j-nmodes)*(j-nmodes)/ + ((NekDouble)((j-cutoff+epsilon)* + (j-cutoff+epsilon))))); } else { -- GitLab From 9bac580d28acf32a009d25ef1f9de5864fa7e8f3 Mon Sep 17 00:00:00 2001 From: ssherw Date: Wed, 5 Apr 2017 23:21:24 +0100 Subject: [PATCH 21/27] Address comments from Chris --- docs/doxygen/Doxyfile.in | 1 + library/Collections/BwdTrans.cpp | 2 +- library/Collections/IProductWRTDerivBase.cpp | 307 +++++++++++-------- library/Collections/PhysDeriv.cpp | 80 +++-- 4 files changed, 226 insertions(+), 164 deletions(-) diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 7555aee0a..13f6460e1 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -757,6 +757,7 @@ INPUT = @CMAKE_SOURCE_DIR@/docs/doxygen/ \ @CMAKE_SOURCE_DIR@/library/LibUtilities/ \ @CMAKE_SOURCE_DIR@/library/StdRegions/ \ @CMAKE_SOURCE_DIR@/library/SpatialDomains/ \ + @CMAKE_SOURCE_DIR@/library/Collections/ \ @CMAKE_SOURCE_DIR@/library/LocalRegions/ \ @CMAKE_SOURCE_DIR@/library/MultiRegions/ \ @CMAKE_SOURCE_DIR@/library/GlobalMapping/ \ diff --git a/library/Collections/BwdTrans.cpp b/library/Collections/BwdTrans.cpp index 8dc637bec..5791af435 100644 --- a/library/Collections/BwdTrans.cpp +++ b/library/Collections/BwdTrans.cpp @@ -1052,7 +1052,7 @@ class BwdTrans_SumFac_Pyr : public Operator int mode = 0; int mode1 = 0; int cnt = 0; - for (i = mode = mode1 = 0; i < m_nmodes0; ++i) + for (i = 0; i < m_nmodes0; ++i) { for (j = 0; j < m_nmodes1; ++j, ++cnt) { diff --git a/library/Collections/IProductWRTDerivBase.cpp b/library/Collections/IProductWRTDerivBase.cpp index 211d9ee11..a18228423 100644 --- a/library/Collections/IProductWRTDerivBase.cpp +++ b/library/Collections/IProductWRTDerivBase.cpp @@ -697,7 +697,38 @@ class IProductWRTDerivBase_SumFac_Tri : public Operator { } - virtual void operator()( + /** + * This method calculates: + * + * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) \f] + * + * which can be represented in terms of local cartesian + * derivaties as: + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dx + + * d\phi/d\xi_1\, d\xi_1/dx),in[0]) + \f] + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dy + + * d\phi/d\xi_1\, d\xi_1/dy),in[1]) + \f] + * + * where we note that + * + * \f[ d\phi/d\xi_0 = d\phi/d\eta_0\, d\eta_0/d\xi_0 = + * d\phi/d\eta_0 2/(1-\eta_1) \f] + * + * \f[ d\phi/d\xi_1 = d\phi/d\eta_1\, d\eta_1/d\xi_1 + + * d\phi/d\eta_1\, d\eta_1/d\xi_1 = d\phi/d\eta_0 (1+\eta_0)/(1-\eta_1) + * + d\phi/d\eta_1 \f] + * + * and so the full inner products are + * + * \f[ (d\phi/dx,in[0]) + (dphi/dy,in[1]) = + * (d\phi/d\eta_0, ((2/(1-\eta_1) (d\xi_0/dx in[0] + d\xi_0/dy in[1]) + * + (1-\eta_0)/(1-\eta_1) (d\xi_1/dx in[0]+d\xi_1/dy in[1])) + * + (d\phi/d\eta_1, (d\xi_1/dx in[0] + d\xi_1/dy in[1])) \f] + * + */ + virtual void operator()( const Array &entry0, Array &entry1, Array &entry2, @@ -719,26 +750,6 @@ class IProductWRTDerivBase_SumFac_Tri : public Operator tmp[0] = wsp; tmp[1] = wsp + nmax; wsp1 = wsp + 2*nmax; - - // calculate (dphi/dx,in[0]) = ((dphi/dxi_0 dxi_0/dx + - // dphi/dxi_1 dxi_1/dx),in[0]) - // + (dphi/dy,in[1]) = ((dphi/dxi_0 dxi_0/dy + - // dphi/dxi_1 dxi_1/dy),in[1]) - // - // Note dphi/dxi_0 = - // dphi/deta_0 deta_0/dxi_0 = dphi/deta_0 2/(1-eta_1) - // - // dphi/dxi_1 = - // dphi/deta_1 deta_1/dxi_1 + dphi/deta_1 deta_1/dxi_1 = - // dphi/deta_0 (1+eta_0)/(1-eta_1) + dphi/deta_1 - // - // and so the full inner products are - // - // (dphi/dx,in[0]) + (dphi/dy,in[1]) - // = (dphi/deta_0, ((2/(1-eta_1) (dxi_0/dx in[0]+dxi_0/dy in[1]) - // + (1_eta_0)/(1-eta_1) (dxi_1/dx in[0]+dxi_1/dy in[1])) - // + (dphi/deta_1, (dxi_1/dx in[0] + dxi_1/dy in[1])) - for(int i = 0; i < 2; ++i) { Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1, tmp[i],1); @@ -1017,6 +1028,60 @@ class IProductWRTDerivBase_SumFac_Tet : public Operator public: OPERATOR_CREATE(IProductWRTDerivBase_SumFac_Tet) + + /** + * This method calculates: + * + * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) \f] + * + * which can be represented in terms of local cartesian + * derivaties as: + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dx + + * d\phi/d\xi_1\, d\xi_1/dx + + * d\phi/d\xi_2\, d\xi_2/dx),in[0]) + \f] + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dy + + * d\phi/d\xi_1\, d\xi_1/dy + + * d\phi/d\xi_2\, d\xi_2/dy),in[1]) + \f] + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dz + + * d\phi/d\xi_1\, d\xi_1/dz + + * d\phi/d\xi_2\, d\xi_2/dz),in[2]) \, \f] + * + * where we note that + * + * \f[ d\phi/d\xi_0 = d\phi/d\eta_0 4/((1-\eta_1)(1-\eta_2)) /f] + * + * \f[ d\phi/d\xi_1 = d\phi/d\eta_0 2(1+\eta_0)/((1-\eta_1)(1-\eta_2)) + * + d\phi/d\eta_1 2/(1-\eta_2) \f] + * + * \f[ d\phi/d\xi_2 = d\phi/d\eta_0 2(1+\eta_0)/((1-\eta_1)(1-\eta_2)) + * + d\phi/d\eta_1 (1+\eta_1)/(1-\eta_2) + d\phi/d\eta_2 \f] + * + * and so the full inner products are + * + * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) = \f] + * + * \f[ (d\phi/d\eta_0, fac0 (tmp0 + fac1(tmp1 + tmp2))) + * + (d\phi/d\eta_1, fac2 (tmp1 + fac3 tmp2)) + * + (d\phi/d\eta_2, tmp2) \f] + * + * where + * + * \f[ \begin{array}{lcl} + * tmp0 &=& (d\xi_0/dx in[0] + d\xi_0/dy in[1] + d\xi_0/dz in[2]) \\ + * tmp1 &=& (d\xi_1/dx in[0] + d\xi_1/dy in[1] + d\xi_1/dz in[2]) \\ + * tmp2 &=& (d\xi_2/dx in[0] + d\xi_2/dy in[1] + d\xi_2/dz in[2]) + * \end{array} \f] + * + * \f[ \begin{array}{lcl} + * fac0 &= & 4/((1-\eta_1)(1-\eta_2)) \\ + * fac1 &= & (1+\eta_0)/2 \\ + * fac2 &= & 2/(1-\eta_2) \\ + * fac3 &= & (1+\eta_1)/2 \end{array} \f] + * + */ virtual void operator()( const Array &entry0, Array &entry1, @@ -1042,44 +1107,6 @@ class IProductWRTDerivBase_SumFac_Tet : public Operator tmp[i] = wsp + i*nmax; } - - // calculate (dphi/dx,in[0]) = ((dphi/dxi_0 dxi_0/dx + - // dphi/dxi_1 dxi_1/dx + - // dphi/dxi_2 dxi_2/dx),in[0]) - // + (dphi/dy,in[1]) = ((dphi/dxi_0 dxi_0/dy + - // dphi/dxi_1 dxi_1/dy + - // dphi/dxi_2 dxi_2/dy),in[1]) - // + (dphi/dz,in[2]) = ((dphi/dxi_0 dxi_0/dz + - // dphi/dxi_1 dxi_1/dz + - // dphi/dxi_2 dxi_2/dz),in[1]) - // - // Note dphi/dxi_0 = - // dphi/deta_0 4/((1-eta_1)(1-eta2)) - // - // dphi/dxi_1 = - // dphi/deta_0 2(1+eta_0)/((1-eta_1)(1-eta_2)) + - // dphi/deta_1 2/(1-eta_2) - // - // dphi/dxi_2 = - // dphi/deta_0 2(1+eta_0)/((1-eta_1)(1-eta_2)) + - // dphi/deta_1 (1+eta_1)/(1-eta_2) + dphi/deta_2 - // - // and so the full inner products are - // - // (dphi/dx,in[0]) + (dphi/dy,in[1]) + (dphi/dz,in[2]) - // = (dphi/deta_0, fac0 (tmp0 + fac1(tmp1 + tmp2))) - // + (dphi/deta_1, fac2 (tmp1 + fac3 tmp2)) - // + (dphi/deta_2, tmp2) - // - // tmp0 = (dxi_0/dx in[0] + dxi_0/dy in[1] + dxi_0/dz in[2]) - // tmp1 = (dxi_1/dx in[0] + dxi_1/dy in[1] + dxi_1/dz in[2]) - // tmp2 = (dxi_2/dx in[0] + dxi_2/dy in[1] + dxi_2/dz in[2]) - - // fac0 = 4/((1-eta_1)(1-eta2)) - // fac1 = (1+eta_0)/2 - // fac2 = 2/(1-eta_2) - // fac3 = (1+eta_1)/2 - for(int i = 0; i < 3; ++i) { Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1,tmp[i],1); @@ -1259,6 +1286,52 @@ class IProductWRTDerivBase_SumFac_Prism : public Operator { } + /** + * This method calculates: + * + * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) \f] + * + * which can be represented in terms of local cartesian + * derivaties as: + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dx + + * d\phi/d\xi_1\, d\xi_1/dx + + * d\phi/d\xi_2\, d\xi_2/dx),in[0]) + \f] + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dy + + * d\phi/d\xi_1\, d\xi_1/dy + + * d\phi/d\xi_2\, d\xi_2/dy),in[1]) + \f] + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dz + + * d\phi/d\xi_1\, d\xi_1/dz + + * d\phi/d\xi_2\, d\xi_2/dz),in[2]) \, \f] + * + * where we note that + * + * \f[ d\phi/d\xi_0 = + * d\phi/d\eta_0 d\eta_0/d\xi_0 = d\phi/d\eta_0 2/(1-\eta_2) \f] + * + * \f[ d\phi/d\xi_2 = + * d\phi/d\eta_0 d\eta_0/d\xi_2 + d\phi/d\eta_2 d\eta_2/d\xi_2 = + * d\phi/d\eta_0 (1+\eta_0)/(1-\eta_2) + d\phi/d\eta_2 \f] + * + * + * and so the full inner products are + * + * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) = \f] + * + * \f[ (d\phi/d\eta_0, ((2/(1-\eta_2) (d\xi_0/dx in[0] + d\xi_0/dy in[1] + * + d\xi_0/dz in[2]) + * + (1-\eta_0)/(1-\eta_2) (d\xi_2/dx in[0] + d\xi_2/dy in[1] + * + d\xi_2/dz in[2] )) + \f] + * + * \f[ (d\phi/d\eta_1, (d\xi_1/dx in[0] + d\xi_1/dy in[1] + * + d\xi_1/dz in[2])) + \f] + * + * \f[ (d\phi/d\eta_2, (d\xi_2/dx in[0] + d\xi_2/dy in[1] + * + d\xi_2/dz in[2])) \f] + * + */ virtual void operator()( const Array &entry0, Array &entry1, @@ -1284,32 +1357,6 @@ class IProductWRTDerivBase_SumFac_Prism : public Operator tmp[i] = wsp + i*nmax; } - // calculate (dphi/dx,in[0]) = ((dphi/dxi_0 dxi_0/dx + - // dphi/dxi_1 dxi_1/dx),in[0]) - // + (dphi/dy,in[1]) = ((dphi/dxi_0 dxi_0/dy + - // dphi/dxi_1 dxi_1/dy),in[1]) - // + (dphi/dz,in[2]) = ((dphi/dxi_0 dxi_0/dz + - // dphi/dxi_1 dxi_1/dz),in[2]) - // - // Note dphi/dxi_0 = - // dphi/deta_0 deta_0/dxi_0 = dphi/deta_0 2/(1-eta_2) - // - // dphi/dxi_2 = - // dphi/deta_0 deta_0/dxi_2 + dphi/deta_2 deta_2/dxi_2 = - // dphi/deta_0 (1+eta_0)/(1-eta_2) + dphi/deta_2 - // - // and so the full inner products are - // - // (dphi/dx,in[0]) + (dphi/dy,in[1]) + (dphi/dz,in[2]) - // = (dphi/deta_0, ((2/(1-eta_2) (dxi_0/dx in[0] + dxi_0/dy in[1] - // + dxi_0/dz in[2]) - // + (1_eta_0)/(1-eta_2) (dxi_2/dx in[0] + dxi_2/dy in[1] - // + dxi_2/dz in[2] )) - // + (dphi/deta_1, (dxi_1/dx in[0] + dxi_1/dy in[1] - // + dxi_1/dz in[2])) - // + (dphi/deta_2, (dxi_2/dx in[0] + dxi_2/dy in[1] - // + dxi_2/dz in[2])) - for(int i = 0; i < 3; ++i) { Vmath::Vmul (ntot,m_derivFac[i],1, in[0],1, @@ -1467,7 +1514,61 @@ class IProductWRTDerivBase_SumFac_Pyr : public Operator { } - virtual void operator()( + + /** + * This method calculates: + * + * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) \f] + * + * which can be represented in terms of local cartesian + * derivaties as: + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dx + + * d\phi/d\xi_1\, d\xi_1/dx + + * d\phi/d\xi_2\, d\xi_2/dx),in[0]) + \f] + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dy + + * d\phi/d\xi_1\, d\xi_1/dy + + * d\phi/d\xi_2\, d\xi_2/dy),in[1]) + \f] + * + * \f[ ((d\phi/d\xi_0\, d\xi_0/dz + + * d\phi/d\xi_1\, d\xi_1/dz + + * d\phi/d\xi_2\, d\xi_2/dz),in[2]) \, \f] + * + * where we note that + * + * \f[ d\phi/d\xi_0 = + * d\phi/d\eta_0\, d\eta_0/d\xi_0 = + * d\phi/d\eta_0\, 2/(1-\eta_2). \f] + * + * \f[ d\phi/d\xi_1 = + * d\phi/d\eta_1\, d\eta_1/d\xi_1 = + * d\phi/d\eta_1\, 2/(1-\eta_2) \f] + * + * \f[ d\phi/d\xi_2 = + * d\phi/d\eta_0\, d\eta_0/d\xi_2 + + * d\phi/d\eta_1\, d\eta_1/d\xi_2 + + * d\phi/d\eta_2\, d\eta_2/d\xi_2 = + * d\phi/d\eta_0 (1+\eta_0)/(1-\eta_2) + + * d\phi/d\eta_1 (1+\eta_1)/(1-\eta_2) + d\phi/d\eta_2 \f] + * + * and so the full inner products are + * + * \f[ (d\phi/dx,in[0]) + (d\phi/dy,in[1]) + (d\phi/dz,in[2]) = \f] + * + * \f[ (d\phi/d\eta_0, ((2/(1-\eta_2) (d\xi_0/dx in[0] + + * d\xi_0/dy in[1] + + * (1-\eta_0)/(1-\eta_2) (d\xi_2/dx in[0] + d\xi_2/dy in[1] + * + d\xi_2/dz in[2] )) + \f] + * \f[ (d\phi/d\eta_1, ((2/(1-\eta_2) (d\xi_1/dx in[0] + + * d\xi_0/dy in[1] + d\xi_0/dz in[2]) + + * (1-\eta_1)/(1-\eta_2) (d\xi_2/dx in[0] + d\xi_2/dy in[1] + + * d\xi_2/dz in[2] )) \f] + * + * \f[ (d\phi/d\eta_2, (d\xi_2/dx in[0] + d\xi_2/dy in[1] + + * d\xi_2/dz in[2])) \f] + */ + virtual void operator()( const Array &entry0, Array &entry1, Array &entry2, @@ -1491,40 +1592,6 @@ class IProductWRTDerivBase_SumFac_Pyr : public Operator { tmp[i] = wsp + i*nmax; } - - // calculate (dphi/dx,in[0]) = ((dphi/dxi_0 dxi_0/dx + - // dphi/dxi_1 dxi_1/dx),in[0]) - // + (dphi/dy,in[1]) = ((dphi/dxi_0 dxi_0/dy + - // dphi/dxi_1 dxi_1/dy),in[1]) - // + (dphi/dz,in[2]) = ((dphi/dxi_0 dxi_0/dz + - // dphi/dxi_1 dxi_1/dz),in[2]) - // - // Note dphi/dxi_0 = - // dphi/deta_0 deta_0/dxi_0 = dphi/deta_0 2/(1-eta_2) - // - // Note dphi/dxi_1 = - // dphi/deta_1 deta_1/dxi_1 = dphi/deta_1 2/(1-eta_2) - // - // dphi/dxi_2 = - // dphi/deta_0 deta_0/dxi_2 + dphi/deta_1 deta_1/dxi_2 + - // + dphi/deta_2 deta_2/dxi_2 = - // dphi/deta_0 (1+eta_0)/(1-eta_2) + - // dphi/deta_1 (1+eta_1)/(1-eta_2) + dphi/deta_2 - // - // and so the full inner products are - // - // (dphi/dx,in[0]) + (dphi/dy,in[1]) + (dphi/dz,in[2]) - // = (dphi/deta_0, ((2/(1-eta_2) (dxi_0/dx in[0] + dxi_0/dy in[1] - // + dxi_0/dz in[2]) - // + (1_eta_0)/(1-eta_2) (dxi_2/dx in[0] + dxi_2/dy in[1] - // + dxi_2/dz in[2] )) - // + (dphi/deta_1, ((2/(1-eta_2) (dxi_1/dx in[0] + dxi_0/dy in[1] - // + dxi_0/dz in[2]) - // + (1_eta_1)/(1-eta_2) (dxi_2/dx in[0] + dxi_2/dy in[1] - // + dxi_2/dz in[2] )) - // + (dphi/deta_2, (dxi_2/dx in[0] + dxi_2/dy in[1] - // + dxi_2/dz in[2])) - for(int i = 0; i < 3; ++i) { diff --git a/library/Collections/PhysDeriv.cpp b/library/Collections/PhysDeriv.cpp index e2c8b4f98..74bc05732 100644 --- a/library/Collections/PhysDeriv.cpp +++ b/library/Collections/PhysDeriv.cpp @@ -938,7 +938,7 @@ class PhysDeriv_SumFac_Hex : public Operator Array > out(3); out[0] = output0; out[1] = output1; out[2] = output2; - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -967,10 +967,10 @@ class PhysDeriv_SumFac_Hex : public Operator // calculate full derivative for(int i = 0; i < m_coordim; ++i) { - Vmath::Vmul(ntot,m_derivFac[i*m_dim],1,Diff[0],1,out[i],1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[i*3],1,Diff[0],1,out[i],1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[i*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[i*3+j], 1, Diff[j], 1, out[i], 1, out[i], 1); @@ -989,7 +989,7 @@ class PhysDeriv_SumFac_Hex : public Operator Array tmp0,tmp1,tmp2; Array > Diff(3); - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -1016,10 +1016,10 @@ class PhysDeriv_SumFac_Hex : public Operator } // calculate full derivative - Vmath::Vmul(ntot,m_derivFac[dir*m_dim],1,Diff[0],1,output,1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[dir*3],1,Diff[0],1,output,1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[dir*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[dir*3+j], 1, Diff[j], 1, output, 1, output, 1); @@ -1028,7 +1028,6 @@ class PhysDeriv_SumFac_Hex : public Operator protected: Array m_derivFac; - int m_dim; int m_coordim; const int m_nquad0; const int m_nquad1; @@ -1048,7 +1047,6 @@ class PhysDeriv_SumFac_Hex : public Operator { LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys(); - m_dim = PtsKey.size(); m_coordim = m_stdExp->GetCoordim(); m_derivFac = pGeomData->GetDerivFactors(pCollExp); @@ -1096,7 +1094,7 @@ class PhysDeriv_SumFac_Tet : public Operator Array > out(3); out[0] = output0; out[1] = output1; out[2] = output2; - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -1161,10 +1159,10 @@ class PhysDeriv_SumFac_Tet : public Operator // calculate full derivative for(int i = 0; i < m_coordim; ++i) { - Vmath::Vmul(ntot,m_derivFac[i*m_dim],1,Diff[0],1,out[i],1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[i*3],1,Diff[0],1,out[i],1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[i*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[i*3+j], 1, Diff[j], 1, out[i], 1, out[i], 1); } } @@ -1181,7 +1179,7 @@ class PhysDeriv_SumFac_Tet : public Operator Array tmp0,tmp1,tmp2; Array > Diff(3); - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -1244,17 +1242,16 @@ class PhysDeriv_SumFac_Tet : public Operator } // calculate full derivative - Vmath::Vmul(ntot,m_derivFac[dir*m_dim],1,Diff[0],1,output,1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[dir*3],1,Diff[0],1,output,1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[dir*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[dir*3+j], 1, Diff[j], 1, output, 1, output, 1); } } protected: Array m_derivFac; - int m_dim; int m_coordim; const int m_nquad0; const int m_nquad1; @@ -1278,7 +1275,6 @@ class PhysDeriv_SumFac_Tet : public Operator { LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys(); - m_dim = PtsKey.size(); m_coordim = m_stdExp->GetCoordim(); m_derivFac = pGeomData->GetDerivFactors(pCollExp); @@ -1358,7 +1354,7 @@ class PhysDeriv_SumFac_Prism : public Operator Array > out(3); out[0] = output0; out[1] = output1; out[2] = output2; - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -1401,10 +1397,10 @@ class PhysDeriv_SumFac_Prism : public Operator // calculate full derivative for(int i = 0; i < m_coordim; ++i) { - Vmath::Vmul(ntot,m_derivFac[i*m_dim],1,Diff[0],1,out[i],1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[i*3],1,Diff[0],1,out[i],1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[i*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[i*3+j], 1, Diff[j], 1, out[i], 1, out[i], 1); } } @@ -1421,7 +1417,7 @@ class PhysDeriv_SumFac_Prism : public Operator Array tmp0,tmp1,tmp2; Array > Diff(3); - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -1462,17 +1458,16 @@ class PhysDeriv_SumFac_Prism : public Operator } // calculate full derivative - Vmath::Vmul(ntot,m_derivFac[dir*m_dim],1,Diff[0],1,output,1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[dir*3],1,Diff[0],1,output,1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[dir*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[dir*3+j], 1, Diff[j], 1, output, 1, output, 1); } } protected: Array m_derivFac; - int m_dim; int m_coordim; const int m_nquad0; const int m_nquad1; @@ -1494,7 +1489,6 @@ class PhysDeriv_SumFac_Prism : public Operator { LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys(); - m_dim = PtsKey.size(); m_coordim = m_stdExp->GetCoordim(); m_derivFac = pGeomData->GetDerivFactors(pCollExp); @@ -1563,7 +1557,7 @@ class PhysDeriv_SumFac_Pyr : public Operator Array > out(3); out[0] = output0; out[1] = output1; out[2] = output2; - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -1613,10 +1607,10 @@ class PhysDeriv_SumFac_Pyr : public Operator // calculate full derivative for(int i = 0; i < m_coordim; ++i) { - Vmath::Vmul(ntot,m_derivFac[i*m_dim],1,Diff[0],1,out[i],1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[i*3],1,Diff[0],1,out[i],1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[i*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[i*3+j], 1, Diff[j], 1, out[i], 1, out[i], 1); } } @@ -1633,7 +1627,7 @@ class PhysDeriv_SumFac_Pyr : public Operator Array tmp0,tmp1,tmp2; Array > Diff(3); - for(int i = 0; i < m_dim; ++i) + for(int i = 0; i < 3; ++i) { Diff[i] = wsp + i*ntot; } @@ -1680,17 +1674,16 @@ class PhysDeriv_SumFac_Pyr : public Operator } // calculate full derivative - Vmath::Vmul(ntot,m_derivFac[dir*m_dim],1,Diff[0],1,output,1); - for(int j = 1; j < m_dim; ++j) + Vmath::Vmul(ntot,m_derivFac[dir*3],1,Diff[0],1,output,1); + for(int j = 1; j < 3; ++j) { - Vmath::Vvtvp (ntot, m_derivFac[dir*m_dim+j], 1, + Vmath::Vvtvp (ntot, m_derivFac[dir*3+j], 1, Diff[j], 1, output, 1, output, 1); } } protected: Array m_derivFac; - int m_dim; int m_coordim; const int m_nquad0; const int m_nquad1; @@ -1713,7 +1706,6 @@ class PhysDeriv_SumFac_Pyr : public Operator { LibUtilities::PointsKeyVector PtsKey = m_stdExp->GetPointsKeys(); - m_dim = PtsKey.size(); m_coordim = m_stdExp->GetCoordim(); m_derivFac = pGeomData->GetDerivFactors(pCollExp); @@ -1728,17 +1720,19 @@ class PhysDeriv_SumFac_Pyr : public Operator m_fac1 = Array(m_nquad0*m_nquad1*m_nquad2); m_fac2 = Array(m_nquad0*m_nquad1*m_nquad2); + int nq0_nq1 = m_nquad0*m_nquad1; for (int i = 0; i < m_nquad0; ++i) { for(int j = 0; j < m_nquad1; ++j) { + int ifac = i+j*m_nquad0; for(int k = 0; k < m_nquad2; ++k) { - m_fac0[i+j*m_nquad0 + k*m_nquad0*m_nquad1] = + m_fac0[ifac + k*nq0_nq1] = 2.0/(1-z2[k]); - m_fac1[i+j*m_nquad0 + k*m_nquad0*m_nquad1] = + m_fac1[ifac + k*nq0_nq1] = 0.5*(1+z0[i]); - m_fac2[i+j*m_nquad0 + k*m_nquad0*m_nquad1] = + m_fac2[ifac + k*nq0_nq1] = 0.5*(1+z1[j]); } } -- GitLab From 6d90815564049fcb8d6e3ca8f880ea03849a6d0e Mon Sep 17 00:00:00 2001 From: ssherw Date: Thu, 6 Apr 2017 12:02:54 +0100 Subject: [PATCH 22/27] Updated doxygen comments from backward transforms to inner products --- library/Collections/IProductWRTBase.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/Collections/IProductWRTBase.cpp b/library/Collections/IProductWRTBase.cpp index 73ed03989..3badeea37 100644 --- a/library/Collections/IProductWRTBase.cpp +++ b/library/Collections/IProductWRTBase.cpp @@ -586,7 +586,7 @@ OperatorKey IProductWRTBase_SumFac_Tri::m_type = GetOperatorFactory(). /** - * @brief Backward transform operator using sum-factorisation (Hex) + * @brief Inner Product operator using sum-factorisation (Hex) */ class IProductWRTBase_SumFac_Hex : public Operator { @@ -765,7 +765,7 @@ OperatorKey IProductWRTBase_SumFac_Tet::m_type = GetOperatorFactory(). /** - * @brief Backward transform operator using sum-factorisation (Prism) + * @brief Inner Product operator using sum-factorisation (Prism) */ class IProductWRTBase_SumFac_Prism : public Operator { @@ -858,7 +858,7 @@ OperatorKey IProductWRTBase_SumFac_Prism::m_type = GetOperatorFactory(). /** - * @brief Backward transform operator using sum-factorisation (Pyr) + * @brief Inner Product operator using sum-factorisation (Pyr) */ class IProductWRTBase_SumFac_Pyr : public Operator { -- GitLab From 95dac78a7dd62067e666e642f0c9cef835ecce70 Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 8 Apr 2017 09:49:39 +0100 Subject: [PATCH 23/27] Increased tolerance on this parallel test to see if it made it more robust in Buildbot --- .../Tests/ChanFlow_m8_BodyForce.xml | 1 + .../Tests/ChanFlow_m8_BodyForce_par.tst | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce.xml b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce.xml index c5196de8e..e368f63bf 100644 --- a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce.xml +++ b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce.xml @@ -21,6 +21,7 @@

NumSteps = 1000

IO_CheckSteps = 1000

IO_InfoSteps = 1000

+

IterativeSolverTolerance = 1e-10

Kinvis = 1

diff --git a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst index 6da3dd783..5c2750e48 100644 --- a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst +++ b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst @@ -9,14 +9,14 @@ - 9.9054e-06 - 2.96756e-10 - 2.55815e-08 + 9.90432-06 + 2.82461-11 + 3.91926e-09 - 1.40541e-05 - 8.20843e-10 - 2.34497e-07 + 1.40069-05 + 6.84991e-11 + 1.21984e-08 -
+ -- GitLab From 4cfe42e3fa4749d3ed7b7a64877354f26d3242f6 Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 8 Apr 2017 10:11:05 +0100 Subject: [PATCH 24/27] Seeing if using namespace rather than std::max sorts out windows error --- library/LibUtilities/BasicUtils/ShapeType.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/LibUtilities/BasicUtils/ShapeType.hpp b/library/LibUtilities/BasicUtils/ShapeType.hpp index b7ab7169f..58cd68fb2 100644 --- a/library/LibUtilities/BasicUtils/ShapeType.hpp +++ b/library/LibUtilities/BasicUtils/ShapeType.hpp @@ -43,6 +43,8 @@ #undef min #endif +using namespace std; + namespace Nektar { namespace LibUtilities @@ -247,7 +249,7 @@ namespace Nektar { for (int b = 0; b < Nb; ++b) { - for (int c = 0; c < Nc - std::max(a,b); ++c) + for (int c = 0; c < Nc - max(a,b); ++c) { ++nCoeff; } -- GitLab From 3f34b8d093ef91bda5ef9bb7e9c8a683c797daee Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 8 Apr 2017 18:56:20 +0100 Subject: [PATCH 25/27] Mucked up end xml tag hopefully now corrected --- .../IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst index 5c2750e48..5ec4e7d3a 100644 --- a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst +++ b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst @@ -19,4 +19,4 @@ 1.21984e-08
- +
-- GitLab From f265759f2d0f12683b93f3ce5eaeb896f9da44c1 Mon Sep 17 00:00:00 2001 From: ssherw Date: Sat, 8 Apr 2017 20:19:31 +0100 Subject: [PATCH 26/27] Missing 'e' factors this time! --- .../Tests/ChanFlow_m8_BodyForce_par.tst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst index 5ec4e7d3a..3db709293 100644 --- a/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst +++ b/solvers/IncNavierStokesSolver/Tests/ChanFlow_m8_BodyForce_par.tst @@ -9,12 +9,12 @@ - 9.90432-06 - 2.82461-11 + 9.90432e-06 + 2.82461e-11 3.91926e-09 - 1.40069-05 + 1.40069e-05 6.84991e-11 1.21984e-08 -- GitLab From 9d6a34239af395f05e942cb99c30f546cb3a72bb Mon Sep 17 00:00:00 2001 From: David Moxey Date: Mon, 10 Apr 2017 22:39:28 +0100 Subject: [PATCH 27/27] Fix typo in CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 728a7b005..b9679fe2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ v4.5.0 - Adjust boundary layer thickness in corners in 2D (!739) **Library** -- Added in sum factorisation version for pyramid expnasions and orthogonal expansion in pyramids (!750) +- Added in sum factorisation version for pyramid expansions and orthogonal + expansion in pyramids (!750) **Documentation**: - Added the developer-guide repository as a submodule (!751) -- GitLab