예제 #1
0
SpatialDomains::HexGeomSharedPtr CreateHexGeom(int argc, char *argv[])
{
    if (argc != 35)
    {
        cout << "Insufficient points for a hex!" << endl;
    }

    // /////////////////////////////////////////////////////////////////////
    // Set up Hexahedron vertex coordinates
    // PointGeom (const int coordim, const int vid, double x, double y,
    //   double z)

    const int nVerts = 8;
    const double point[][3] = {
        {atof(argv[11]),atof(argv[12]),atof(argv[13])},
        {atof(argv[14]),atof(argv[15]),atof(argv[16])},
        {atof(argv[17]),atof(argv[18]),atof(argv[19])},
        {atof(argv[20]),atof(argv[21]),atof(argv[22])},
        {atof(argv[23]),atof(argv[24]),atof(argv[25])},
        {atof(argv[26]),atof(argv[27]),atof(argv[28])},
        {atof(argv[29]),atof(argv[30]),atof(argv[31])},
        {atof(argv[32]),atof(argv[33]),atof(argv[34])}
    };

    // Populate the list of verts
    PointGeomSharedPtr verts[8];
    const int three = 3;

    for( int i = 0; i < nVerts; ++i ) {
        verts[i] = MemoryManager<PointGeom>
            ::AllocateSharedPtr( three,  i,   point[i][0],
                                 point[i][1], point[i][2] );
    }

    // /////////////////////////////////////////////////////////////////////
    // Set up Hexahedron Edges
    // SegGeom (int id, const int coordim), EdgeComponent(id, coordim)
    const int nEdges = 12;
    const int vertexConnectivity[][2] = {
        {0,1}, {1,2}, {2,3}, {0,3}, {0,4}, {1,5},
        {2,6}, {3,7}, {4,5}, {5,6}, {6,7}, {4,7}
    };

    // Populate the list of edges
    SegGeomSharedPtr edges[nEdges];
    for( int i = 0; i < nEdges; ++i ) {
        PointGeomSharedPtr vertsArray[2];
        for( int j = 0; j < 2; ++j ) {
            vertsArray[j] = verts[vertexConnectivity[i][j]];
        }
        edges[i] = MemoryManager<SegGeom>::
            AllocateSharedPtr( i, three, vertsArray);
    }

    // //////////////////////////////////////////////////////////////////////
    // Set up Hexahedron faces
    const int nFaces = 6;
    const int edgeConnectivity[][4] = {
        {0,1,2,3}, {0,5,8,4}, {1,6,9,5},
        {2,7,10,6}, {3,7,11,4}, {8,9,10,11}
    };
    const bool   isEdgeFlipped[][4] = {
        {0,0,0,1}, {0,0,1,1}, {0,0,1,1},
        {0,0,1,1}, {0,0,1,1}, {0,0,0,1}
    };

    // Populate the list of faces
    QuadGeomSharedPtr faces[nFaces];
    for( int i = 0; i < nFaces; ++i ) {
        SegGeomSharedPtr edgeArray[4];
        Orientation eorientArray[4];
        for( int j = 0; j < 4; ++j ) {
            edgeArray[j]    = edges[edgeConnectivity[i][j]];
            eorientArray[j] = isEdgeFlipped[i][j]  ?  eBackwards  :  eForwards;
        }
        faces[i] = MemoryManager<QuadGeom>
            ::AllocateSharedPtr( i, edgeArray, eorientArray);
    }

    SpatialDomains::HexGeomSharedPtr geom =
        MemoryManager<SpatialDomains::HexGeom>::AllocateSharedPtr(faces);
    geom->SetOwnData();

    return geom;
}
예제 #2
0
int main(int argc, char *argv[])
{
    if( argc != 10 ) {
        cerr << "Usage: HexDemo Type_x Type_y Type_z numModes_x numModes_y "
                "numModes_z Qx Qy Qz" << endl;
        cerr << "Where type is an interger value which dictates the basis as:"
             << endl;
        cerr << "\t Ortho_A    = 1\n";
        cerr << "\t Modified_A = 4\n";
        cerr << "\t Fourier    = 7\n";
        cerr << "\t Lagrange   = 8\n";
        cerr << "\t Legendre   = 9\n";
        cerr << "\t Chebyshev  = 10\n";
        cerr << "\n\n" << "Example: " << argv[0] << " 4 4 4 3 3 3 5 5 5"
             << endl;
        cerr << endl;

        exit(1);
    }

    // Set up the region shape and expansion types
    int bType_x_val = atoi(argv[1]);
    int bType_y_val = atoi(argv[2]);
    int bType_z_val = atoi(argv[3]);

    BasisType   bType_x   = static_cast<BasisType>( bType_x_val );
    BasisType   bType_y   = static_cast<BasisType>( bType_y_val );
    BasisType   bType_z   = static_cast<BasisType>( bType_z_val );

    if( (bType_x_val == 13) || (bType_y_val == 13) || (bType_z_val == 13) )
    {
        bType_x =   LibUtilities::eOrtho_A;
        bType_y =   LibUtilities::eOrtho_B;
        bType_z =   LibUtilities::eOrtho_C;
    }

    if( (bType_x == eOrtho_B) || (bType_x == eModified_B) ) {
        NEKERROR(ErrorUtil::efatal,
                 "Basis 1 cannot be of type Ortho_B or Modified_B");
    }
    if( (bType_x == eOrtho_C) || (bType_x == eModified_C) ) {
        NEKERROR(ErrorUtil::efatal,
                 "Basis 1 cannot be of type Ortho_C or Modified_C");
    }
    if( (bType_y == eOrtho_C) || (bType_y == eModified_C) ) {
        NEKERROR(ErrorUtil::efatal,
                 "Basis 2 cannot be of type Ortho_C or Modified_C");
    }

    // Set up the number of quadrature points, order of bases, etc
    int xModes   = atoi(argv[4]);
    int yModes   = atoi(argv[5]);
    int zModes   = atoi(argv[6]);
    int Qx       = atoi(argv[7]);
    int Qy       = atoi(argv[8]);
    int Qz       = atoi(argv[9]);
    int P        = xModes - 1;
    int Q        = yModes - 1;
    int R        = zModes - 1;
    const int three = 3;

    Array<OneD, NekDouble> solution( Qx * Qy * Qz );

    LibUtilities::PointsType    Qtype_x, Qtype_y, Qtype_z;

    Array<OneD,NekDouble> x = Array<OneD,NekDouble>( Qx * Qy * Qz );
    Array<OneD,NekDouble> y = Array<OneD,NekDouble>( Qx * Qy * Qz );
    Array<OneD,NekDouble> z = Array<OneD,NekDouble>( Qx * Qy * Qz );

    if(bType_x != LibUtilities::eFourier)
    {
        Qtype_x = LibUtilities::eGaussLobattoLegendre;
    }
    else
    {
        Qtype_x = LibUtilities::eFourierEvenlySpaced;
    }

    if(bType_y != LibUtilities::eFourier)
    {
        Qtype_y = LibUtilities::eGaussLobattoLegendre;
    }
    else
    {
        Qtype_y = LibUtilities::eFourierEvenlySpaced;
    }

    if(bType_z != LibUtilities::eFourier)
    {
        Qtype_z = LibUtilities::eGaussLobattoLegendre;
    }
    else
    {
        Qtype_z = LibUtilities::eFourierEvenlySpaced;
    }


    //-----------------------------------------------
    // Define a 3D expansion based on basis definition
    StdRegions::StdExpansion3D *lhe = 0;

    // ////////////////////////////////////////////////////////////////
    // Set up Hexahedron vertex coordinates
    // PointGeom (const int coordim, const int vid, double x,
    //    double y, double z)

    const int nVerts = 8;
    const double point[][3] = {
        {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0},
        {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}
    };

    // Populate the list of verts
    PointGeomSharedPtr verts[8];
    for( int i = 0; i < nVerts; ++i ) {
        verts[i] = MemoryManager<PointGeom>
                            ::AllocateSharedPtr(three,  i,   point[i][0],
                                                point[i][1], point[i][2]);
    }

    // ////////////////////////////////////////////////////////////////
    // Set up Hexahedron Edges
    // SegGeom (int id, const int coordim), EdgeComponent(id, coordim)
    const int nEdges = 12;
    const int vertexConnectivity[][2] = {
        {0,1}, {1,2}, {2,3}, {0,3}, {0,4}, {1,5},
        {2,6}, {3,7}, {4,5}, {5,6}, {6,7}, {4,7}
    };

    // Populate the list of edges
    SegGeomSharedPtr edges[nEdges];
    for( int i = 0; i < nEdges; ++i ) {
        PointGeomSharedPtr vertsArray[2];
        for( int j = 0; j < 2; ++j ) {
            vertsArray[j] = verts[vertexConnectivity[i][j]];
        }
        edges[i] = MemoryManager<SegGeom>::
            AllocateSharedPtr( i, three, vertsArray);
    }

    // ////////////////////////////////////////////////////////////////
    // Set up Hexahedron faces
    const int nFaces = 6;
    const int edgeConnectivity[][4] = {
          {0,1,2,3}, {0,5,8,4}, {1,6,9,5},
          {2,7,10,6}, {3,7,11,4}, {8,9,10,11}
    };
    const bool isEdgeFlipped[][4] = {
          {0,0,0,1}, {0,0,1,1}, {0,0,1,1},
          {0,0,1,1}, {0,0,1,1}, {0,0,0,1}
    };

    // Populate the list of faces
    QuadGeomSharedPtr faces[nFaces];
    for( int i = 0; i < nFaces; ++i ) {
        SegGeomSharedPtr edgeArray[4];
        Orientation eorientArray[4];
        for( int j = 0; j < 4; ++j ) {
            edgeArray[j]    = edges[edgeConnectivity[i][j]];
            eorientArray[j] = isEdgeFlipped[i][j] ? eBackwards : eForwards;
        }
        faces[i] = MemoryManager<QuadGeom>::AllocateSharedPtr(i, edgeArray,
                                                              eorientArray);
    }


    const LibUtilities::PointsKey   pkey1( Qx, Qtype_x );
    const LibUtilities::PointsKey   pkey2( Qy, Qtype_y );
    const LibUtilities::PointsKey   pkey3( Qz, Qtype_z );

    const LibUtilities::BasisKey    bkey1( bType_x, xModes, pkey1 );
    const LibUtilities::BasisKey    bkey2( bType_y, yModes, pkey2 );
    const LibUtilities::BasisKey    bkey3( bType_z, zModes, pkey3 );

    Array<OneD, StdRegions::StdExpansion3DSharedPtr> xMap(3);
    for(int i = 0; i < 3; ++i) {
        xMap[i] = MemoryManager<StdRegions::StdHexExp>
                                ::AllocateSharedPtr(bkey1, bkey2, bkey3);
    }

    SpatialDomains::HexGeomSharedPtr geom
            = MemoryManager<SpatialDomains::HexGeom>::AllocateSharedPtr(faces);
    geom->SetOwnData();


    if( bType_x_val < 10 ) {
        lhe = new LocalRegions::HexExp( bkey1, bkey2, bkey3, geom );
    }

    lhe->GetCoords(x,y,z);

    //----------------------------------------------
    // Define solution to be projected
    for(int n = 0; n < Qx * Qy * Qz; ++n) {
        solution[n]  = Hex_sol( x[n], y[n], z[n], P, Q, R,
                                bType_x, bType_y, bType_z );
    }
    //----------------------------------------------

    //---------------------------------------------
    // Project onto Expansion
    Array<OneD, NekDouble> phys  (Qx * Qy * Qz);
    Array<OneD, NekDouble> coeffs(lhe->GetNcoeffs());
    lhe->FwdTrans( solution, coeffs );
    //---------------------------------------------

    //-------------------------------------------
    // Backward Transform Solution to get projected values
    lhe->BwdTrans( coeffs, phys );
    //-------------------------------------------

    //--------------------------------------------
    // Calculate L_p error
    cout << "L infinity error: " << lhe->Linf(phys, solution) << endl;
    cout << "L 2 error:        " << lhe->L2  (phys, solution) << endl;
    //--------------------------------------------

    //-------------------------------------------
    // Evaulate solution at x = y = z = 0  and print error
    Array<OneD, NekDouble> t = Array<OneD, NekDouble>(3);
    t[0] =  0.5;
    t[1] =  0.5;
    t[2] =  0.5;

    NekDouble numericSolution = lhe->PhysEvaluate(t, phys);

    solution[0] = Hex_sol( t[0], t[1], t[2], P, Q, R,
                           bType_x, bType_y, bType_z );

    cout << "Solution = " << solution[0] << endl;
    cout << "Numeric  = " << numericSolution << endl;
    cout << "Interpolation difference from actual solution at x = ( "
         << t[0] << ", " << t[1] << ", " << t[2] << " ): "
         << numericSolution - solution[0] << endl;
    //-------------------------------------------

    return 0;
}