Пример #1
0
void PointExp::v_GetCoords(Array<OneD,NekDouble> &coords_0,
                           Array<OneD, NekDouble> &coords_1,
                           Array<OneD, NekDouble> &coords_2)
{
    ASSERTL1(coords_0.num_elements() > 0,
             "Coords_0 is of insufficient size.");
    ASSERTL1(GetCoordim() < 2 || coords_1.num_elements() > 0,
             "Coords_1 is of insufficient size.");
    ASSERTL1(GetCoordim() < 3 || coords_2.num_elements() > 0,
             "Coords_2 is of insufficient size.");

    SpatialDomains::PointGeomSharedPtr v = boost::dynamic_pointer_cast<SpatialDomains::PointGeom>(m_geom);
    NekDouble tmp;
    switch(GetCoordim())
    {
    case 1:
        v->GetCoords(coords_0[0], tmp, tmp);
        break;
    case 2:
        v->GetCoords(coords_0[0], coords_1[0], tmp);
        break;
    case 3:
        v->GetCoords(coords_0[0], coords_1[0], coords_2[0]);
        break;
    }
}
Пример #2
0
 /// \brief  BLAS level 1: y = alpha \a x plus \a y
 static inline void Daxpy (const int& n, const double& alpha, const Nektar::Array <Nektar::OneD,const double> &x, const int& incx,  Nektar::Array<Nektar::OneD,double> &y, const int& incy)
 {
     ASSERTL1(static_cast<unsigned int>(n*incx) <= x.num_elements()+x.GetOffset(),"Array out of bounds");
     ASSERTL1(static_cast<unsigned int>(n*incy) <= y.num_elements()+y.GetOffset(),"Array out of bounds");
     
     F77NAME(daxpy)(n,alpha,&x[0],incx,&y[0],incy);
 }
Пример #3
0
 GlobalLinSysSharedPtr ContField1D::GenGlobalLinSys(
                         const GlobalLinSysKey &mkey)
 {
     ASSERTL1(mkey.LocToGloMapIsDefined(),
              "To use method must have a AssemblyMap "
              "attached to key");
     return ExpList::GenGlobalLinSys(mkey, m_locToGloMap);
 }
Пример #4
0
    void SubtractEqualNegatedLhs(NekMatrix<DataType, StandardMatrixTag>& result,
                          const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
    {
        ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts  ") + 
            boost::lexical_cast<std::string>(result.GetRows()) + std::string(" and ") +
            boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be subtracted."));
        ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts  ") + 
            boost::lexical_cast<std::string>(result.GetColumns()) + std::string(" and ") +
            boost::lexical_cast<std::string>(rhs.GetColumns()) + std::string(" can't be subtracted."));

        for(unsigned int i = 0; i < rhs.GetRows(); ++i)
        {
            for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
            {
                result(i,j) = -result(i,j) - rhs(i,j);
            }
        }
    }
Пример #5
0
    void Add(NekMatrix<DataType, StandardMatrixTag>& result,
                const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
                const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
    {
        ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts  ") + 
            boost::lexical_cast<std::string>(lhs.GetRows()) + std::string(" and ") +
            boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be added."));
        ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts  ") + 
            boost::lexical_cast<std::string>(lhs.GetColumns()) + std::string(" and ") +
            boost::lexical_cast<std::string>(rhs.GetColumns()) + std::string(" can't be added."));

        for(unsigned int i = 0; i < lhs.GetRows(); ++i)
        {
            for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
            {
                result(i,j) = lhs(i,j) + rhs(i,j);
            }
        }
    }
Пример #6
0
 void Multiply(NekVector<DataType>& result,
               const NekMatrix<LhsDataType, MatrixType>& lhs,
               const NekVector<DataType>& rhs)
 {
                    
     ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") + 
         boost::lexical_cast<std::string>(lhs.GetColumns()) + 
         std::string(" and a right side vector with row count ") + 
         boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be multiplied."));
     Multiply(result.GetRawPtr(), lhs, rhs.GetRawPtr());
 }
Пример #7
0
    void IncNavierStokes::v_GetFluxVector(const int i, 
                                          Array<OneD, Array<OneD, NekDouble> > &physfield,
                                            Array<OneD, Array<OneD, NekDouble> > &flux)
    {
        ASSERTL1(flux.num_elements() == m_velocity.num_elements(),"Dimension of flux array and velocity array do not match");

        for(int j = 0; j < flux.num_elements(); ++j)
        {
            Vmath::Vmul(GetNpoints(), physfield[i], 1, m_fields[m_velocity[j]]->GetPhys(), 1, flux[j], 1);
        }
    }
Пример #8
0
    void EigenValuesAdvection::v_GetFluxVector(const int i, Array<OneD, Array<OneD, NekDouble> > &physfield,
											Array<OneD, Array<OneD, NekDouble> > &flux)
    {
        ASSERTL1(flux.num_elements() == m_velocity.num_elements(),"Dimension of flux array and velocity array do not match");
		
        for(int j = 0; j < flux.num_elements(); ++j)
        {
            Vmath::Vmul(GetNpoints(),physfield[i],1,
						m_velocity[j],1,flux[j],1);
        }
    }
Пример #9
0
/**
 * @brief Upwind Riemann solver
 *
 * @param pL     Perturbation pressure left state
 * @param rhoL   Perturbation density left state
 * @param pR     Perturbation pressure right state
 * @param rhoR   Perturbation density right state
 * @param uL     x perturbation velocity component left state
 * @param uR     x perturbation velocity component right state
 * @param vL     y perturbation velocity component left state
 * @param vR     y perturbation velocity component right state
 * @param wL     z perturbation velocity component left state
 * @param wR     z perturbation velocity component right state
 * @param p0     Base pressure
 * @param rho0   Base density
 * @param u0     Base x velocity component
 * @param v0     Base y velocity component
 * @param w0     Base z velocity component
 * @param pF     Computed Riemann flux for perturbation pressure
 * @param rhoF   Computed Riemann flux for perturbation density
 * @param uF     Computed Riemann flux for x perturbation velocity component
 * @param vF     Computed Riemann flux for y perturbation velocity component
 * @param wF     Computed Riemann flux for z perturbation velocity component
 */
void UpwindSolver::v_PointSolve(
    NekDouble  pL, NekDouble  rhoL, NekDouble  uL, NekDouble  vL, NekDouble  wL,
    NekDouble  pR, NekDouble  rhoR, NekDouble  uR, NekDouble  vR, NekDouble  wR,
    NekDouble  p0, NekDouble  rho0, NekDouble  u0, NekDouble  v0, NekDouble  w0,
    NekDouble &pF, NekDouble &rhoF, NekDouble &uF, NekDouble &vF, NekDouble &wF)
{
    // fetch params
    ASSERTL1(CheckParams("Gamma"), "Gamma not defined.");
    const NekDouble &gamma = m_params["Gamma"]();

    // Speed of sound
    NekDouble c = sqrt(gamma * p0 / rho0);

    Array<OneD, NekDouble> characteristic(4);
    Array<OneD, NekDouble> W(2);
    Array<OneD, NekDouble> lambda(2);

    // compute the wave speeds
    lambda[0] = u0 + c;
    lambda[1] = u0 - c;

    // calculate the caracteristic variables
    //left characteristics
    characteristic[0] = pL/2 + uL*c*rho0/2;
    characteristic[1] = pL/2 - uL*c*rho0/2;
    //right characteristics
    characteristic[2] = pR/2 + uR*c*rho0/2;
    characteristic[3] = pR/2 - uR*c*rho0/2;

    //take left or right value of characteristic variable
    for (int j = 0; j < 2; j++)
    {
        if (lambda[j] >= 0)
        {
            W[j] = characteristic[j];
        }
        if (lambda[j] < 0)
        {
            W[j] = characteristic[j+2];
        }
    }

    //calculate conservative variables from characteristics
    NekDouble p = W[0] + W[1];
    NekDouble u = (W[0] - W[1])/(c*rho0);

    // assemble the fluxes
    pF = rho0*u + u0*p/(c*c);
    uF = p/rho0 + u0*u + v0*vL + w0*wL;
    vF = 0.0;
    wF = 0.0;
}
Пример #10
0
 void DriverArnoldi::WriteFld(std::string file, std::vector<Array<OneD, NekDouble> > coeffs)
 {
 
     std::vector<std::string>  variables(m_nfields);
 
     ASSERTL1(coeffs.size() >= m_nfields, "coeffs is not of the correct length");
     for(int i = 0; i < m_nfields; ++i)
     {
         variables[i] = m_equ[0]->GetVariable(i);
     }
 
     m_equ[0]->WriteFld(file,m_equ[0]->UpdateFields()[0], coeffs, variables);
 }
Пример #11
0
    /**
     *  Riemann solver for upwinding at an interface between two
     *  elements. Uses the characteristic variables for calculating
     *  the upwinded state \f$(A_u,u_u)\f$ from the left
     *  \f$(A_L,u_L)\f$ and right state \f$(A_R,u_R)\f$.  Returns the
     *  upwinded flux $\mathbf{F}^u$ needed for the weak formulation
     *  (1). Details can be found in "Pulse wave propagation in the
     *  human vascular system", section 3.3
     *
     */
    void PulseWavePropagation::RiemannSolverUpwind(NekDouble AL,NekDouble uL,
                                                   NekDouble AR,NekDouble uR, 
                                                   NekDouble &Aflux, 
                                                   NekDouble &uflux, 
                                                   NekDouble A_0, 
                                                   NekDouble beta,
                                                   NekDouble n)
    {
        Array<OneD, NekDouble> W(2);
        Array<OneD, NekDouble> upwindedphysfield(2);
        NekDouble cL = 0.0;
        NekDouble cR = 0.0;
        NekDouble rho = m_rho; 
        NekDouble pext = m_pext; 
        NekDouble p = 0.0;
        NekDouble p_t = 0.0;
        
        // Compute the wave speeds. The use of the normal here allows
        // for the definition of the characteristics to be inverted
        // (and hence the left and right state) if n is in the -ve
        // x-direction. This means we end up with the positive
        // defintion of the flux which has to therefore be multiplied
        // by the normal at the end of the methods This is a bit of a
        // mind twister but is efficient from a coding perspective.
        cL = sqrt(beta*sqrt(AL)/(2*rho))*n;
        cR = sqrt(beta*sqrt(AR)/(2*rho))*n;

        ASSERTL1(fabs(cL+cR) > fabs(uL+uR),"Conditions are not sub-sonic");

        // If upwinding from left and right for subsonic domain
        // then know characteristics immediately
        W[0] = uL + 4*cL;
        W[1] = uR - 4*cR;

        // Calculate conservative variables from characteristics
        NekDouble w0mw1 = 0.25*(W[0]-W[1]);
        NekDouble fac = rho/(2*beta);
        w0mw1 *= w0mw1; // squared
        w0mw1 *= w0mw1; // fourth power
        fac *= fac;     // squared
        upwindedphysfield[0]= w0mw1*fac;
        upwindedphysfield[1]= 0.5*(W[0] + W[1]);

        // Compute the fluxes multipled by the normal. 
        Aflux = upwindedphysfield[0] * upwindedphysfield[1]*n;
        p = pext + beta*(sqrt(upwindedphysfield[0]) - sqrt(A_0));
        p_t = 0.5*(upwindedphysfield[1]*upwindedphysfield[1]) + p/rho;				
        uflux =  p_t*n;
    }    
Пример #12
0
        void DriverArnoldi::WriteFld(std::string file, Array<OneD, NekDouble> coeffs)
        {
        
            std::vector<std::string>  variables(m_nfields);
            std::vector<Array<OneD, NekDouble> > fieldcoeffs(m_nfields);
        
            int ncoeffs = m_equ[0]->UpdateFields()[0]->GetNcoeffs();
            ASSERTL1(coeffs.num_elements() >= ncoeffs*m_nfields,"coeffs is not of sufficient size");

            for(int i = 0; i < m_nfields; ++i)
            {
                variables[i] = m_equ[0]->GetVariable(i);
                fieldcoeffs[i] = coeffs + i*ncoeffs;
            }
        
            m_equ[0]->WriteFld(file,m_equ[0]->UpdateFields()[0], fieldcoeffs, variables);
        }
Пример #13
0
 /**
  * @brief Implementation of the upwind solver.
  * 
  * The upwind solver assumes that a scalar field Vn is defined, which
  * corresponds with the dot product \f$\mathbf{V}\cdot\mathbf{n}\f$,
  * where \f$\mathbf{V}\f$ is the advection velocity and \f$\mathbf{n}\f$
  * defines the normal of a vertex, edge or face at each quadrature point
  * of the trace space.
  * 
  * @param Fwd   Forwards trace space.
  * @param Bwd   Backwards trace space.
  * @param flux  Resulting flux.
  */
 void UpwindSolver::v_Solve(
     const Array<OneD, const Array<OneD, NekDouble> > &Fwd,
     const Array<OneD, const Array<OneD, NekDouble> > &Bwd,
           Array<OneD,       Array<OneD, NekDouble> > &flux)
 {
     ASSERTL1(CheckScalars("Vn"), "Vn not defined.");
     const Array<OneD, NekDouble> &traceVel = m_scalars["Vn"]();
     
     for (int j = 0; j < traceVel.num_elements(); ++j)
     {
         const Array<OneD, const Array<OneD, NekDouble> > &tmp = 
             traceVel[j] >= 0 ? Fwd : Bwd;
         for (int i = 0; i < Fwd.num_elements(); ++i)
         {
             flux[i][j] = traceVel[j]*tmp[i][j];
         }
     }
 }
Пример #14
0
    /**
     * @brief Return the flux vector for the linear advection equation.
     *
     * @param i           Component of the flux vector to calculate.
     * @param physfield   Fields.
     * @param flux        Resulting flux.
     */
    void UnsteadyAdvection::GetFluxVector(
        const Array<OneD, Array<OneD, NekDouble> >               &physfield,
              Array<OneD, Array<OneD, Array<OneD, NekDouble> > > &flux)
    {
        ASSERTL1(flux[0].num_elements() == m_velocity.num_elements(),
                 "Dimension of flux array and velocity array do not match");

        int i , j;
        int nq = physfield[0].num_elements();

        for (i = 0; i < flux.num_elements(); ++i)
        {
            for (j = 0; j < flux[0].num_elements(); ++j)
            {
                Vmath::Vmul(nq, physfield[i], 1, m_velocity[j], 1,
                            flux[i][j], 1);
            }
        }
    }
Пример #15
0
    void Multiply(NekMatrix<DataType, StandardMatrixTag>& result,
                     const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
                     const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
    {
        ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") + 
            boost::lexical_cast<std::string>(lhs.GetColumns()) + 
            std::string(" and a right side matrix with row count ") + 
            boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be multiplied."));

        result.SetSize(lhs.GetRows(), rhs.GetColumns());
        if( lhs.GetType() == eFULL && rhs.GetType() == eFULL)
        {
            NekMultiplyFullMatrixFullMatrix(result, lhs, rhs);
        }
        else
        {
            NekMultiplyDefaultImpl(result, lhs, rhs);
        }
    }
Пример #16
0
    void NekMultiplyDefaultImpl(NekMatrix<ResultType, StandardMatrixTag>& result,
                                         const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
                                         const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
    {
        ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") + 
            boost::lexical_cast<std::string>(lhs.GetColumns()) + 
            std::string(" and a right side matrix with row count ") + 
            boost::lexical_cast<std::string>(rhs.GetRows()) + std::string(" can't be multiplied."));

        for(unsigned int i = 0; i < result.GetRows(); ++i)
        {
            for(unsigned int j = 0; j < result.GetColumns(); ++j)
            {
                ResultType t = ResultType(0);

                // Set the result(i,j) element.
                for(unsigned int k = 0; k < lhs.GetColumns(); ++k)
                {
                    t += lhs(i,k)*rhs(k,j);
                }
                result(i,j) = t;
            }
        }
    }
Пример #17
0
        /**
         * Allocates a new DNekSparseMat object from the given specification.
         * @param   rows        Number of rows in matrix.
         * @param   columns     Number of columns in matrix.
         * @param   cooMat      ?
         */
        GlobalMatrix::GlobalMatrix(
                                   const LibUtilities::SessionReaderSharedPtr& pSession,
                                   unsigned int rows, 
                                   unsigned int columns,
                                   const COOMatType &cooMat,
                                   const MatrixStorage& matStorage):
            m_smvbsrmatrix(),
            m_rows(rows),
            m_mulCallsCounter(0)
        {
            MatrixStorageType storageType = pSession->
                GetSolverInfoAsEnum<MatrixStorageType>("GlobalMatrixStorageType");

            unsigned int brows, bcols;

            // Size of dense matrix sub-blocks
            int block_size = 1;

            BCOMatType bcoMat;

            // assuming current sparse format allows
            // block-sparse data representation

            if(pSession->DefinesParameter("SparseBlockSize"))
            {
                pSession->LoadParameter("SparseBlockSize", block_size);
                ASSERTL1(block_size > 0,"SparseBlockSize parameter must to be positive");
            }

            brows = rows / block_size + (rows % block_size > 0);
            bcols = columns / block_size + (columns % block_size > 0);

            if (rows % block_size > 0)  m_copyOp = true;

            if (m_copyOp)
            {
                m_tmpin  = Array<OneD, NekDouble> (brows*block_size, 0.0);
                m_tmpout = Array<OneD, NekDouble> (brows*block_size, 0.0);
            }

            convertCooToBco(brows, bcols, block_size, cooMat, bcoMat);

            size_t matBytes;
            switch(storageType)
            {
                case eSmvBSR:
                    {

                    // Create zero-based Smv-multiply BSR sparse storage holder
                    DNekSmvBsrMat::SparseStorageSharedPtr sparseStorage =
                            MemoryManager<DNekSmvBsrMat::StorageType>::
                                    AllocateSharedPtr(
                                        brows, bcols, block_size, bcoMat, matStorage );

                    // Create sparse matrix
                    m_smvbsrmatrix = MemoryManager<DNekSmvBsrMat>::
                                            AllocateSharedPtr( sparseStorage );

                    matBytes = m_smvbsrmatrix->GetMemoryFootprint();

                    }
                    break;

                default:
                    NEKERROR(ErrorUtil::efatal,"Unsupported sparse storage type chosen");
            }

            cout << "Global matrix storage type: " 
                    << MatrixStorageTypeMap[storageType] << endl;
            std::cout << "Global matrix memory, bytes = " << matBytes;
            if (matBytes/(1024*1024) > 0)
            {
                std::cout << " ("<< matBytes/(1024*1024) <<" MB)" << std::endl;
            }
            else
            {
                std::cout << " ("<< matBytes/1024 <<" KB)" << std::endl;
            }
            std::cout << "Sparse storage block size = " << block_size << std::endl;
        }
Пример #18
0
 static DataType& reference(const boost::shared_ptr<DataType>& o) { ASSERTL1(o, "Can't dereference null pointer."); return *o; }
Пример #19
0
/**
 * @brief Return the flux vector for the APE equations.
 *
 * @param physfield   Fields.
 * @param flux        Resulting flux. flux[eq][dir][pt]
 */
void APE::GetFluxVector(
        const Array<OneD, Array<OneD, NekDouble> > &physfield,
        Array<OneD, Array<OneD, Array<OneD, NekDouble> > > &flux)
{
    UpdateBasefield();

    int nq = physfield[0].num_elements();
    Array<OneD, NekDouble> tmp1(nq);
    Array<OneD, NekDouble> tmp2(nq);

    ASSERTL1(flux[0].num_elements() == m_spacedim,
                 "Dimension of flux array and velocity array do not match");

    // F_{adv,p',j} = \rho_0 u'_j + p' \bar{u}_j / c^2
    for (int j = 0; j < m_spacedim; ++j)
    {
        Vmath::Zero(nq, flux[0][j], 1);

        // construct rho_0 u'_j term
        Vmath::Vmul(nq, m_basefield[1], 1, physfield[j + 1], 1, flux[0][j], 1);

        // construct p' \bar{u}_j / c^2 term
        // c^2
        Vmath::Vdiv(nq, m_basefield[0], 1, m_basefield[1], 1, tmp1, 1);
        Vmath::Smul(nq, m_gamma, tmp1, 1, tmp1, 1);

        // p' \bar{u}_j / c^2 term
        Vmath::Vmul(nq, physfield[0], 1, m_basefield[j + 2], 1, tmp2, 1);
        Vmath::Vdiv(nq, tmp2, 1, tmp1, 1, tmp2, 1);

        // \rho_0 u'_j + p' \bar{u}_j / c^2
        Vmath::Vadd(nq, flux[0][j], 1, tmp2, 1, flux[0][j], 1);
    }

    for (int i = 1; i < flux.num_elements(); ++i)
    {
        ASSERTL1(flux[i].num_elements() == m_spacedim,
                 "Dimension of flux array and velocity array do not match");

        // F_{adv,u'_i,j} = (p'/ \bar{rho} + \bar{u}_k u'_k) \delta_{ij}
        for (int j = 0; j < m_spacedim; ++j)
        {
            Vmath::Zero(nq, flux[i][j], 1);

            if (i - 1 == j)
            {
                // contruct p'/ \bar{rho} term
                Vmath::Vdiv(nq, physfield[0], 1, m_basefield[1], 1, flux[i][j], 1);

                // construct \bar{u}_k u'_k term
                Vmath::Zero(nq, tmp1, 1);
                for (int k = 0; k < m_spacedim; ++k)
                {
                    Vmath::Vvtvp(nq, physfield[k + 1], 1, m_basefield[k + 2], 1, tmp1, 1, tmp1, 1);
                }

                // add terms
                Vmath::Vadd(nq, flux[i][j], 1, tmp1, 1, flux[i][j], 1);
            }
        }
    }
}
Пример #20
0
    /**
     * @brief Return the flux vector for the linear advection equation using
     * the dealiasing technique.
     *
     * @param i           Component of the flux vector to calculate.
     * @param physfield   Fields.
     * @param flux        Resulting flux.
     */
    void UnsteadyAdvection::GetFluxVectorDeAlias(
        const Array<OneD, Array<OneD, NekDouble> >               &physfield,
              Array<OneD, Array<OneD, Array<OneD, NekDouble> > > &flux)
    {
        ASSERTL1(flux[0].num_elements() == m_velocity.num_elements(),
                 "Dimension of flux array and velocity array do not match");

        int i, j;
        int nq = physfield[0].num_elements();
        int nVariables = physfield.num_elements();

        // Factor to rescale 1d points in dealiasing
        NekDouble OneDptscale = 2;

        Array<OneD, Array<OneD, NekDouble> >
            advVel_plane(m_velocity.num_elements());

        // Get number of points to dealias a cubic non-linearity
        nq = m_fields[0]->Get1DScaledTotPoints(OneDptscale);

        // Initialisation of higher-space variables
        Array<OneD, Array<OneD, NekDouble> >physfieldInterp(nVariables);
        Array<OneD, Array<OneD, NekDouble> >velocityInterp(m_expdim);
        Array<OneD, Array<OneD, Array<OneD, NekDouble> > >fluxInterp(nVariables);

        // Interpolation to higher space of physfield
        for (i = 0; i < nVariables; ++i)
        {
            physfieldInterp[i] = Array<OneD, NekDouble>(nq);
            fluxInterp[i] = Array<OneD, Array<OneD, NekDouble> >(m_expdim);
            for (j = 0; j < m_expdim; ++j)
            {
                fluxInterp[i][j] = Array<OneD, NekDouble>(nq);
            }

            m_fields[0]->PhysInterp1DScaled(
                OneDptscale, physfield[i], physfieldInterp[i]);
        }

        // Interpolation to higher space of velocity
        for (j = 0; j < m_expdim; ++j)
        {
            velocityInterp[j] = Array<OneD, NekDouble>(nq);

            m_fields[0]->PhysInterp1DScaled(
                OneDptscale, m_velocity[j], velocityInterp[j]);
        }

        // Evaluation of flux vector in the higher space
        for (i = 0; i < flux.num_elements(); ++i)
        {
            for (j = 0; j < flux[0].num_elements(); ++j)
            {
                Vmath::Vmul(nq, physfieldInterp[i], 1, velocityInterp[j], 1,
                            fluxInterp[i][j], 1);
            }
        }

        // Galerkin project solution back to original space
        for (i = 0; i < nVariables; ++i)
        {
            for (j = 0; j < m_spacedim; ++j)
            {
                m_fields[0]->PhysGalerkinProjection1DScaled(
                    OneDptscale, fluxInterp[i][j], flux[i][j]);
            }
        }
    }
Пример #21
0
        void PreconditionerLinear::v_DoPreconditionerWithNonVertOutput(
            const Array<OneD, NekDouble>& pInput,
            Array<OneD, NekDouble>& pOutput,
            const Array<OneD, NekDouble>& pNonVertOutput,
            Array<OneD, NekDouble>& pVertForce)
            {
            GlobalSysSolnType solvertype=m_locToGloMap->GetGlobalSysSolnType();
            switch(solvertype)
            {
                case MultiRegions::eIterativeStaticCond:
                {
                    int i,val;
                    int nloc = m_vertLocToGloMap->GetNumLocalCoeffs();
                    int nglo = m_vertLocToGloMap->GetNumGlobalCoeffs();
                    // mapping from full space to vertices
                    Array<OneD, int> LocToGloBnd = m_vertLocToGloMap->GetLocalToGlobalBndMap();

                    // Global to local for linear solver (different from above)
                    Array<OneD, int> LocToGlo = m_vertLocToGloMap->GetLocalToGlobalMap();
                    
                    // number of Dir coeffs in from full problem
                    int nDirFull = m_locToGloMap->GetNumGlobalDirBndCoeffs();
                    
                    Array<OneD,NekDouble> In(nglo,0.0);
                    Array<OneD,NekDouble> Out(nglo,0.0);

                    // Gather rhs
                    for(i = 0; i < nloc; ++i)
                    {
                        val = LocToGloBnd[i];
                        if(val >= nDirFull)
                        {
                            In[LocToGlo[i]] = pInput[val-nDirFull];
                        }
                    }
                    
                    // Do solve without enforcing any boundary conditions. 
                    m_vertLinsys->SolveLinearSystem(
                        m_vertLocToGloMap->GetNumGlobalCoeffs(),
                        In,Out,m_vertLocToGloMap,
                        m_vertLocToGloMap->GetNumGlobalDirBndCoeffs());
                    
                    
                    if(pNonVertOutput != NullNekDouble1DArray)
                    {
                        ASSERTL1(pNonVertOutput.num_elements() >= pOutput.num_elements(),"Non Vert output is not of sufficient length");
                        Vmath::Vcopy(pOutput.num_elements(),pNonVertOutput,1,pOutput,1);
                    }
                    else
                    {
                        //Copy input to output as a unit preconditioner on
                        //any other value
                        Vmath::Vcopy(pInput.num_elements(),pInput,1,pOutput,1);
                    }
                    
                    if(pVertForce != NullNekDouble1DArray)
                    {
                        Vmath::Zero(pVertForce.num_elements(),pVertForce,1);
                        // Scatter back soln from linear solve
                        for(i = 0; i < nloc; ++i)
                        {
                            val = LocToGloBnd[i];
                            if(val >= nDirFull)
                            {
                                pOutput[val-nDirFull] = Out[LocToGlo[i]];
                                // copy vertex forcing into this vector
                                pVertForce[val-nDirFull] = In[LocToGlo[i]];
                            }
                        }
                    }
                    else
                    {
                        // Scatter back soln from linear solve
                        for(i = 0; i < nloc; ++i)
                        {
                            val = LocToGloBnd[i];
                            if(val >= nDirFull)
                            {
                                pOutput[val-nDirFull] = Out[LocToGlo[i]];
                            }
                        }
                    }
                }
                break;
            default:
                ASSERTL0(0,"Unsupported solver type");
                break;
	    }
        }
Пример #22
0
 static DataType& reference(DataType* o) { ASSERTL1(o != 0, "Can't dereference null pointer."); return *o; }