Exemple #1
0
doublereal LiquidTransport::getElectricConduct()
{
    vector_fp gradT(m_nDim,0.0);
    vector_fp gradX(m_nDim * m_nsp);
    vector_fp gradV(m_nDim);
    for (size_t i = 0; i < m_nDim; i++) {
        for (size_t k = 0; k < m_nsp; k++) {
            gradX[ i*m_nDim + k] = 0.0;
        }
        gradV[i] = 1.0;
    }

    set_Grad_T(&gradT[0]);
    set_Grad_X(&gradX[0]);
    set_Grad_V(&gradV[0]);

    vector_fp fluxes(m_nsp * m_nDim);
    doublereal current;
    getSpeciesFluxesExt(m_nDim, &fluxes[0]);

    //sum over species charges, fluxes, Faraday to get current
    // Since we want the scalar conductivity, we need only consider one-dim
    for (size_t i = 0; i < 1; i++) {
        current = 0.0;
        for (size_t k = 0; k < m_nsp; k++) {
            current += m_chargeSpecies[k] * Faraday * fluxes[k] / m_mw[k];
        }
        //divide by unit potential gradient
        current /= - gradV[i];
    }
    return current;
}
Exemple #2
0
void softAbsMetric::fPrepareSpatialGradients()
{
    
    // Compute the discrete Jacobian of the SoftAbs transform
    double delta = 0;
    double lambda = 0;
    double alphaLambda = 0;
    double sdx = 0;
    
    for(int i = 0; i < mDim; ++i)
    {
        
        for(int j = 0; j <= i; ++j)
        {
  
            delta = mEigenDeco.eigenvalues()(i) - mEigenDeco.eigenvalues()(j);
            
            if(fabs(delta) < 1e-10)
            {
                
                lambda = mEigenDeco.eigenvalues()(i);
                alphaLambda = mSoftAbsAlpha * lambda;
                
                if(fabs(alphaLambda) < 1e-4)
                {
                    mPseudoJ(i, j) = (2.0 / 3.0) * alphaLambda * (1.0 - (2.0 / 15.0) * alphaLambda * alphaLambda);
                }
                else if(fabs(alphaLambda) > 18)
                {
                    mPseudoJ(i, j) = lambda > 0 ? 1 : -1;
                }
                else
                {
                    sdx = sinh(mSoftAbsAlpha * lambda) / lambda;
                    mPseudoJ(i, j) = (mSoftAbsLambda(i) - mSoftAbsAlpha / (sdx * sdx) ) / lambda;
                }
                
            }
            else
            {
                mPseudoJ(i, j) = ( mSoftAbsLambda(i) - mSoftAbsLambda(j) ) / delta;
            }
                
        }
        
    }

    // And make sure the gradient has been calculated
    gradV();
    
    // Along with the third-derivative tensor
    for(int i = 0; i < mDim; ++i) fComputeGradH(i);
    
}
Exemple #3
0
void constMetric::fEvolveP(const double epsilon) 
{
    mP -= epsilon * gradV();
}
Exemple #4
0
        void FilterAeroForces::v_Update(
            const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
            const NekDouble &time)
        {
            // Only output every m_outputFrequency.
            if ((m_index++) % m_outputFrequency)
            {
                return;
            }

            int n, cnt, elmtid, nq, offset, nt, boundary;
            nt = pFields[0]->GetNpoints();
            int dim = pFields.num_elements()-1;

            StdRegions::StdExpansionSharedPtr elmt;
            Array<OneD, int> BoundarytoElmtID;
            Array<OneD, int> BoundarytoTraceID;
            Array<OneD, MultiRegions::ExpListSharedPtr>  BndExp;

            Array<OneD, const NekDouble> P(nt);
            Array<OneD, const NekDouble> U(nt);
            Array<OneD, const NekDouble> V(nt);
            Array<OneD, const NekDouble> W(nt);

            Array<OneD, Array<OneD, NekDouble> > gradU(dim);
            Array<OneD, Array<OneD, NekDouble> > gradV(dim);
            Array<OneD, Array<OneD, NekDouble> > gradW(dim);

            Array<OneD, Array<OneD, NekDouble> > fgradU(dim);
            Array<OneD, Array<OneD, NekDouble> > fgradV(dim);
            Array<OneD, Array<OneD, NekDouble> > fgradW(dim);

            Array<OneD, NekDouble> values;
            LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm();

            NekDouble Fx,Fy,Fz,Fxp,Fxv,Fyp,Fyv,Fzp,Fzv;

            Fxp = 0.0; // x-component of the force due to pressure difference
            Fxv = 0.0; // x-component of the force due to viscous stress
            Fx = 0.0;  // x-component of the force (total) Fx = Fxp + Fxv (Drag) 

            Fyp = 0.0; // y-component of the force due to pressure difference
            Fyv = 0.0; // y-component of the force due to viscous stress
            Fy = 0.0;  // y-component of the force (total) Fy = Fyp + Fyv (Lift)

            Fzp = 0.0; // z-component of the force due to pressure difference
            Fzv = 0.0; // z-component of the force due to viscous stress
            Fz = 0.0;  // z-component of the force (total) Fz = Fzp + Fzv (Side)

            NekDouble rho = (m_session->DefinesParameter("rho"))
                    ? (m_session->GetParameter("rho"))
                    : 1;
            NekDouble mu = rho*m_session->GetParameter("Kinvis");
            
            for(int i = 0; i < pFields.num_elements(); ++i)
            {
                pFields[i]->SetWaveSpace(false);
                pFields[i]->BwdTrans(pFields[i]->GetCoeffs(),
                                     pFields[i]->UpdatePhys());
                pFields[i]->SetPhysState(true);
            }

            // Homogeneous 1D case  Compute forces on all WALL boundaries
            // This only has to be done on the zero (mean) Fourier mode.
            if(m_isHomogeneous1D)
            {
                if(vComm->GetColumnComm()->GetRank() == 0)
                {
                    pFields[0]->GetPlane(0)->GetBoundaryToElmtMap(
                                         BoundarytoElmtID,BoundarytoTraceID);
                    BndExp = pFields[0]->GetPlane(0)->GetBndCondExpansions();
                    StdRegions::StdExpansion1DSharedPtr bc;

                    // loop over the types of boundary conditions
                    for(cnt = n = 0; n < BndExp.num_elements(); ++n)
                    {
                        if(m_boundaryRegionIsInList[n] == 1)
                        {
                            for(int i = 0; i <  BndExp[n]->GetExpSize(); 
                                    ++i, cnt++)
                            {
                                // find element of this expansion.
                                elmtid = BoundarytoElmtID[cnt];
                                elmt   = pFields[0]->GetPlane(0)->GetExp(elmtid);
                                nq     = elmt->GetTotPoints();
                                offset = pFields[0]->GetPlane(0)->GetPhys_Offset(elmtid);
                            
                                // Initialise local arrays for the velocity
                                // gradients size of total number of quadrature
                                // points for each element (hence local).
                                for(int j = 0; j < dim; ++j)
                                {
                                    gradU[j] = Array<OneD, NekDouble>(nq,0.0);
                                    gradV[j] = Array<OneD, NekDouble>(nq,0.0);
                                    gradW[j] = Array<OneD, NekDouble>(nq,0.0);
                                }

                                // identify boundary of element
                                boundary = BoundarytoTraceID[cnt];

                                // Extract  fields
                                U = pFields[0]->GetPlane(0)->GetPhys() + offset;
                                V = pFields[1]->GetPlane(0)->GetPhys() + offset;
                                P = pFields[3]->GetPlane(0)->GetPhys() + offset;

                                // compute the gradients
                                elmt->PhysDeriv(U,gradU[0],gradU[1]);
                                elmt->PhysDeriv(V,gradV[0],gradV[1]);

                                // Get face 1D expansion from element expansion
                                bc =  boost::dynamic_pointer_cast<LocalRegions
                                            ::Expansion1D> (BndExp[n]->GetExp(i));

                                // number of points on the boundary
                                int nbc = bc->GetTotPoints();

                                // several vectors for computing the forces
                                Array<OneD, NekDouble> Pb(nbc,0.0);

                                for(int j = 0; j < dim; ++j)
                                {
                                    fgradU[j] = Array<OneD, NekDouble>(nbc,0.0);
                                    fgradV[j] = Array<OneD, NekDouble>(nbc,0.0);
                                }

                                Array<OneD, NekDouble>  drag_t(nbc,0.0);
                                Array<OneD, NekDouble>  lift_t(nbc,0.0);
                                Array<OneD, NekDouble>  drag_p(nbc,0.0);
                                Array<OneD, NekDouble>  lift_p(nbc,0.0);
                                Array<OneD, NekDouble>  temp(nbc,0.0);
                                Array<OneD, NekDouble>  temp2(nbc,0.0);

                                // identify boundary of element .
                                boundary = BoundarytoTraceID[cnt];

                                // extraction of the pressure and wss on the
                                // boundary of the element
                                elmt->GetEdgePhysVals(boundary,bc,P,Pb);

                                for(int j = 0; j < dim; ++j)
                                {
                                    elmt->GetEdgePhysVals(boundary,bc,gradU[j],
                                                          fgradU[j]);
                                    elmt->GetEdgePhysVals(boundary,bc,gradV[j],
                                                          fgradV[j]);
                                }

                                //normals of the element
                                const Array<OneD, Array<OneD, NekDouble> > &normals
                                            = elmt->GetEdgeNormal(boundary);

                                //
                                // Compute viscous tractive forces on wall from
                                //
                                //  t_i  = - T_ij * n_j  (minus sign for force 
                                //                        exerted BY fluid ON wall),
                                //
                                // where
                                //
                                //  T_ij = viscous stress tensor (here in Cartesian
                                //         coords)
                                //                          dU_i    dU_j
                                //       = RHO * KINVIS * ( ----  + ---- ) .
                                //                          dx_j    dx_i

                                //a) DRAG TERMS
                                //-rho*kinvis*(2*du/dx*nx+(du/dy+dv/dx)*ny

                                Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1);
                                Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1);

                                Vmath::Smul(nbc,2.0,fgradU[0],1,fgradU[0],1);
                                Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp2,1);
                                Vmath::Smul(nbc,0.5,fgradU[0],1,fgradU[0],1);

                                Vmath::Vadd(nbc,temp2,1,drag_t,1,drag_t,1);
                                Vmath::Smul(nbc,-mu,drag_t,1,drag_t,1);

                                //zero temporary storage vector
                                Vmath::Zero(nbc,temp,0);
                                Vmath::Zero(nbc,temp2,0);


                                //b) LIFT TERMS
                                //-rho*kinvis*(2*dv/dy*nx+(du/dy+dv/dx)*nx

                                Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1);
                                Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1);

                                Vmath::Smul(nbc,2.0,fgradV[1],1,fgradV[1],1);
                                Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp2,1);
                                Vmath::Smul(nbc,-0.5,fgradV[1],1,fgradV[1],1);


                                Vmath::Vadd(nbc,temp2,1,lift_t,1,lift_t,1);
                                Vmath::Smul(nbc,-mu,lift_t,1,lift_t,1);

                                // Compute normal tractive forces on all WALL
                                // boundaries

                                Vmath::Vvtvp(nbc,Pb,1,normals[0],1,
                                                drag_p,1,drag_p, 1);
                                Vmath::Vvtvp(nbc,Pb,1,normals[1],1,
                                                lift_p,1,lift_p,1);

                                //integration over the boundary
                                Fxv += bc->Integral(drag_t);
                                Fyv += bc->Integral(lift_t);

                                Fxp += bc->Integral(drag_p);
                                Fyp += bc->Integral(lift_p);
                            }
                        }
                        else
                        {
                                cnt += BndExp[n]->GetExpSize();
                        }
                    }
                }
                
                for(int i = 0; i < pFields.num_elements(); ++i)
                {
                    pFields[i]->SetWaveSpace(true);
                    pFields[i]->BwdTrans(pFields[i]->GetCoeffs(),
                                         pFields[i]->UpdatePhys());
                    pFields[i]->SetPhysState(false);
                }
            }
            //3D WALL case
            else if(dim==3 && !m_isHomogeneous1D)
            {
                pFields[0]->GetBoundaryToElmtMap(BoundarytoElmtID,
                                                 BoundarytoTraceID);
                BndExp = pFields[0]->GetBndCondExpansions();
                LocalRegions::Expansion2DSharedPtr bc;

                // loop over the types of boundary conditions
                for(cnt = n = 0; n < BndExp.num_elements(); ++n)
                {
                    if(m_boundaryRegionIsInList[n] == 1)
                    {
                        for(int i = 0; i <  BndExp[n]->GetExpSize(); ++i, cnt++)
                        {
                            // find element of this expansion.
                            elmtid = BoundarytoElmtID[cnt];
                            elmt   = pFields[0]->GetExp(elmtid);
                            nq     = elmt->GetTotPoints();
                            offset = pFields[0]->GetPhys_Offset(elmtid);

                            // Initialise local arrays for the velocity
                            // gradients size of total number of quadrature
                            // points for each element (hence local).
                            for(int j = 0; j < dim; ++j)
                            {
                                gradU[j] = Array<OneD, NekDouble>(nq,0.0);
                                gradV[j] = Array<OneD, NekDouble>(nq,0.0);
                                gradW[j] = Array<OneD, NekDouble>(nq,0.0);
                            }

                            //identify boundary of element
                            boundary = BoundarytoTraceID[cnt];

                            //Extract  fields
                            U = pFields[0]->GetPhys() + offset;
                            V = pFields[1]->GetPhys() + offset;
                            W = pFields[2]->GetPhys() + offset;
                            P = pFields[3]->GetPhys() + offset;

                            //compute the gradients
                            elmt->PhysDeriv(U,gradU[0],gradU[1],gradU[2]);
                            elmt->PhysDeriv(V,gradV[0],gradV[1],gradV[2]);
                            elmt->PhysDeriv(W,gradW[0],gradW[1],gradW[2]);

                            // Get face 2D expansion from element expansion
                            bc =  boost::dynamic_pointer_cast<LocalRegions
                                        ::Expansion2D> (BndExp[n]->GetExp(i));

                            //number of points on the boundary
                            int nbc = bc->GetTotPoints();

                            //several vectors for computing the forces
                            Array<OneD, NekDouble> Pb(nbc,0.0);

                            for(int j = 0; j < dim; ++j)
                            {
                                fgradU[j] = Array<OneD, NekDouble>(nbc,0.0);
                                fgradV[j] = Array<OneD, NekDouble>(nbc,0.0);
                                fgradW[j] = Array<OneD, NekDouble>(nbc,0.0);

                            }

                            Array<OneD, NekDouble>  drag_t(nbc,0.0);
                            Array<OneD, NekDouble>  lift_t(nbc,0.0);
                            Array<OneD, NekDouble>  side_t(nbc,0.0);
                            Array<OneD, NekDouble>  drag_p(nbc,0.0);
                            Array<OneD, NekDouble>  lift_p(nbc,0.0);
                            Array<OneD, NekDouble>  side_p(nbc,0.0);
                            Array<OneD, NekDouble>  temp(nbc,0.0);
                            Array<OneD, NekDouble>  temp2(nbc,0.0);

                            // identify boundary of element .
                            boundary = BoundarytoTraceID[cnt];

                            // extraction of the pressure and wss on the
                            // boundary of the element
                            elmt->GetFacePhysVals(boundary,bc,P,Pb);

                            for(int j = 0; j < dim; ++j)
                            {
                                elmt->GetFacePhysVals(boundary,bc,gradU[j],
                                                      fgradU[j]);
                                elmt->GetFacePhysVals(boundary,bc,gradV[j],
                                                      fgradV[j]);
                                elmt->GetFacePhysVals(boundary,bc,gradW[j],
                                                      fgradW[j]);
                            }

                            // normals of the element
                            const Array<OneD, Array<OneD, NekDouble> > &normals
                                                = elmt->GetFaceNormal(boundary);

                            //
                            // Compute viscous tractive forces on wall from
                            //
                            //  t_i  = - T_ij * n_j  (minus sign for force
                            //                        exerted BY fluid ON wall),
                            //
                            // where
                            //
                            //  T_ij = viscous stress tensor (here in Cartesian
                            //         coords)
                            //                          dU_i    dU_j
                            //       = RHO * KINVIS * ( ----  + ---- ) .
                            //                          dx_j    dx_i

                            //a) DRAG TERMS
                            //-rho*kinvis*
                            //    (2*du/dx*nx+(du/dy+dv/dx)*ny+(du/dz+dw/dx)*nz)
                            Vmath::Vadd(nbc,fgradU[2],1,fgradW[0],1,temp,1);
                            Vmath::Neg(nbc,temp,1);
                            Vmath::Vmul(nbc,temp,1,normals[2],1,temp,1);
                            
                            Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1);
                            Vmath::Neg(nbc,drag_t,1);
                            Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1);
                            
                            Vmath::Smul(nbc,-2.0,fgradU[0],1,fgradU[0],1);
                            Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp2,1);
                            Vmath::Smul(nbc,-0.5,fgradU[0],1,fgradU[0],1);
                            
                            Vmath::Vadd(nbc,temp,1,temp2,1,temp,1);
                            Vmath::Vadd(nbc,temp,1,drag_t,1,drag_t,1);
                            Vmath::Smul(nbc,mu,drag_t,1,drag_t,1);
                            
                            //zero temporary storage vector
                            Vmath::Zero(nbc,temp,0);
                            Vmath::Zero(nbc,temp2,0);
                            
                            
                            //b) LIFT TERMS
                            //-rho*kinvis*
                            //    (2*dv/dy*nx+(du/dy+dv/dx)*nx+(dv/dz+dw/dy)*nz)
                            Vmath::Vadd(nbc,fgradV[2],1,fgradW[1],1,temp,1);
                            Vmath::Neg(nbc,temp,1);
                            Vmath::Vmul(nbc,temp,1,normals[2],1,temp,1);
                            
                            Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1);
                            Vmath::Neg(nbc,lift_t,1);
                            Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1);
                            
                            Vmath::Smul(nbc,-2.0,fgradV[1],1,fgradV[1],1);
                            Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp2,1);
                            Vmath::Smul(nbc,-0.5,fgradV[1],1,fgradV[1],1);
                            
                            Vmath::Vadd(nbc,temp,1,temp2,1,temp,1);
                            Vmath::Vadd(nbc,temp,1,lift_t,1,lift_t,1);
                            Vmath::Smul(nbc,mu,lift_t,1,lift_t,1);
                            
                            //zero temporary storage vector
                            Vmath::Zero(nbc,temp,0);
                            Vmath::Zero(nbc,temp2,0);
                            
                            //b) SIDE TERMS
                            //-rho*kinvis*
                            //    (2*dv/dy*nx+(du/dy+dv/dx)*nx+(dv/dz+dw/dy)*nz)
                            Vmath::Vadd(nbc,fgradV[2],1,fgradW[1],1,temp,1);
                            Vmath::Neg(nbc,temp,1);
                            Vmath::Vmul(nbc,temp,1,normals[1],1,temp,1);
                            
                            Vmath::Vadd(nbc,fgradU[2],1,fgradW[0],1,side_t,1);
                            Vmath::Neg(nbc,side_t,1);
                            Vmath::Vmul(nbc,side_t,1,normals[0],1,side_t,1);
                            
                            Vmath::Smul(nbc,-2.0,fgradW[2],1,fgradW[2],1);
                            Vmath::Vmul(nbc,fgradW[2],1,normals[2],1,temp2,1);
                            Vmath::Smul(nbc,-0.5,fgradW[2],1,fgradW[2],1);
                            
                            Vmath::Vadd(nbc,temp,1,temp2,1,temp,1);
                            Vmath::Vadd(nbc,temp,1,side_t,1,side_t,1);
                            Vmath::Smul(nbc,mu,side_t,1,side_t,1);


                            // Compute normal tractive forces on all WALL
                            // boundaries
                            Vmath::Vvtvp(nbc,Pb,1,normals[0],1,
                                             drag_p,1,drag_p,1);
                            Vmath::Vvtvp(nbc,Pb,1,normals[1],1,
                                             lift_p,1,lift_p,1);
                            Vmath::Vvtvp(nbc,Pb,1,normals[2],1,
                                         side_p,1,side_p,1);

                            //integration over the boundary
                            Fxv += bc->Expansion::Integral(drag_t);
                            Fyv += bc->Expansion::Integral(lift_t);
                            Fzv += bc->Expansion::Integral(side_t);

                            Fxp += bc->Expansion::Integral(drag_p);
                            Fyp += bc->Expansion::Integral(lift_p);
                            Fzp += bc->Expansion::Integral(side_p);
                        }
                    }
                    else
                    {
                        cnt += BndExp[n]->GetExpSize();
                    }
                }
            }
            //2D WALL Condition
            else
            {
                pFields[0]->GetBoundaryToElmtMap(BoundarytoElmtID,
                                                 BoundarytoTraceID);
                BndExp = pFields[0]->GetBndCondExpansions();
                StdRegions::StdExpansion1DSharedPtr bc;

                // loop over the types of boundary conditions
                for(cnt = n = 0; n < BndExp.num_elements(); ++n)
                {
                    if(m_boundaryRegionIsInList[n] == 1)
                    {
                        for(int i = 0; i <  BndExp[n]->GetExpSize(); ++i, cnt++)
                        {

                            elmtid = BoundarytoElmtID[cnt];
                            elmt   = pFields[0]->GetExp(elmtid);
                            nq     = elmt->GetTotPoints();
                            offset = pFields[0]->GetPhys_Offset(elmtid);

                            for(int j = 0; j < dim; ++j)
                            {
                                gradU[j] = Array<OneD, NekDouble>(nq,0.0);
                                gradV[j] = Array<OneD, NekDouble>(nq,0.0);
                            }

                            boundary = BoundarytoTraceID[cnt];

                            U = pFields[0]->GetPhys() + offset;
                            V = pFields[1]->GetPhys() + offset;
                            P = pFields[2]->GetPhys() + offset;

                            elmt->PhysDeriv(U,gradU[0],gradU[1]);
                            elmt->PhysDeriv(V,gradV[0],gradV[1]);

                            bc =  boost::dynamic_pointer_cast<LocalRegions
                                ::Expansion1D> (BndExp[n]->GetExp(i));

                            int nbc = bc->GetTotPoints();
                            Array<OneD, NekDouble> Pb(nbc,0.0);

                            Array<OneD, NekDouble>  drag_t(nbc,0.0);
                            Array<OneD, NekDouble>  lift_t(nbc,0.0);
                            Array<OneD, NekDouble>  drag_p(nbc,0.0);
                            Array<OneD, NekDouble>  lift_p(nbc,0.0);
                            Array<OneD, NekDouble>  temp(nbc,0.0);

                            boundary = BoundarytoTraceID[cnt];

                            elmt->GetEdgePhysVals(boundary,bc,P,Pb);

                            for(int j = 0; j < dim; ++j)
                            {
                                fgradU[j] = Array<OneD, NekDouble>(nbc,0.0);
                                fgradV[j] = Array<OneD, NekDouble>(nbc,0.0);

                            }

                            for(int j = 0; j < dim; ++j)
                            {
                                elmt->GetEdgePhysVals(boundary,bc,gradU[j],
                                                      fgradU[j]);
                                elmt->GetEdgePhysVals(boundary,bc,gradV[j],
                                                      fgradV[j]);
                            }

                            const Array<OneD, Array<OneD, NekDouble> > &normals
                                                = elmt->GetEdgeNormal(boundary);

                            Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1);
                            Vmath::Neg(nbc,drag_t,1);
                            Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1);

                            Vmath::Smul(nbc,-2.0,fgradU[0],1,fgradU[0],1);
                            Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp,1);
                            Vmath::Vadd(nbc,temp,1,drag_t,1,drag_t,1);
                            Vmath::Smul(nbc,mu,drag_t,1,drag_t,1);

                            Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1);
                            Vmath::Neg(nbc,lift_t,1);
                            Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1);
                            Vmath::Smul(nbc,-2.0,fgradV[1],1,fgradV[1],1);
                            Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp,1);
                            Vmath::Vadd(nbc,temp,1,lift_t,1,lift_t,1);
                            Vmath::Smul(nbc,mu,lift_t,1,lift_t,1);

                            Vmath::Vvtvp(nbc,Pb,1,normals[0],1,
                                             drag_p,1,drag_p,1);
                            Vmath::Vvtvp(nbc,Pb,1,normals[1],1,
                                             lift_p,1,lift_p,1);

                            Fxp += bc->Integral(drag_p);
                            Fyp += bc->Integral(lift_p);

                            Fxv += bc->Integral(drag_t);
                            Fyp += bc->Integral(lift_t);
                        }
                    }
                    else
                    {
                        cnt += BndExp[n]->GetExpSize();
                    }

                }

            }

            vComm->AllReduce(Fxp, LibUtilities::ReduceSum);
            vComm->AllReduce(Fxv, LibUtilities::ReduceSum);
            Fx = Fxp + Fxv;
            
            vComm->AllReduce(Fyp, LibUtilities::ReduceSum);
            vComm->AllReduce(Fyv, LibUtilities::ReduceSum);
            Fy = Fyp + Fyv;
            
            vComm->AllReduce(Fzp, LibUtilities::ReduceSum);
            vComm->AllReduce(Fzv, LibUtilities::ReduceSum);
            Fz = Fzp + Fzv;
            

            if (vComm->GetRank() == 0)
            {
                m_outputStream.width(8);
                m_outputStream << setprecision(6) << time;

                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fxp;
                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fxv;
                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fx;

                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fyp;
                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fyv;
                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fy;

                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fzp;
                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fzv;
                m_outputStream.width(25);
                m_outputStream << setprecision(8) << Fz;

                m_outputStream << endl;
            }
        }
void denseFisherMetric::checkEvolution(const double epsilon)
{
    
    baseHamiltonian::checkEvolution(epsilon);
    
    // Metric
    std::cout.precision(6);
    int width = 12;
    int nColumn = 6;
    
    std::cout << "Gradient of the Fisher-Rao metric (dG^{jk}/dq^{i}):" << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "Component"
              << std::setw(width) << std::left << "Row" 
              << std::setw(width) << std::left << "Column" 
              << std::setw(width) << std::left << "Analytic"
              << std::setw(width) << std::left << "Finite"
              << std::setw(width) << std::left << "Delta /"
              << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "(i)"
              << std::setw(width) << std::left << "(j)"
              << std::setw(width) << std::left << "(k)"
              << std::setw(width) << std::left << "Derivative"
              << std::setw(width) << std::left << "Difference"
              << std::setw(width) << std::left << "Stepsize^{2}"
              << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    
    for(int k = 0; k < mDim; ++k)
    {
        
        fComputeG();
        fComputeGradG(k);
            
        MatrixXd temp = MatrixXd::Zero(mDim, mDim);        
        
        mQ(k) += epsilon;
        fComputeG();
        temp += mG;
        mQ(k) -= 2.0 * epsilon;
        fComputeG();
        temp -= mG;
        mQ(k ) += epsilon;
        
        temp /= 2.0 * epsilon;
            
        for(int i = 0; i < mDim; ++i)
        {
        
            for(int j = 0; j < mDim; ++j)
            {
                
                std::cout << "    "
                << std::setw(width) << std::left << k
                << std::setw(width) << std::left << i
                << std::setw(width) << std::left << j 
                << std::setw(width) << std::left << mGradG(i, j)
                << std::setw(width) << std::left << temp(i, j)
                << std::setw(width) << std::left << (mGradG(i, j) - temp(i, j)) / (epsilon * epsilon)
                << std::endl;
                
            }
            
        }
    
    }
    
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << std::endl;
    
    // Hamiltonian
    fComputeCholeskyG();
    mC = mGL.solve(mP);
    
    gradV();
    
    std::cout << "pDot (-dH/dq^{i}):" << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "Component"
              << std::setw(width) << std::left << "Analytic"
              << std::setw(width) << std::left << "Finite"
              << std::setw(width) << std::left << "Delta /"
              << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "(i)"
              << std::setw(width) << std::left << "Derivative"
              << std::setw(width) << std::left << "Difference"
              << std::setw(width) << std::left << "Stepsize^{2}"
              << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    
    for(int i = 0; i < mDim; ++i)
    {
        
        // Finite Differences
        double temp = 0.0;        
        
        mQ(i) += epsilon;
        temp -= H();
        mQ(i) -= 2.0 * epsilon;
        temp += H();
        mQ(i) += epsilon;
        
        temp /= 2.0 * epsilon;
        
        // Exact
        fComputeGradG(i);
        
        double minusGradH = -0.5 * mGL.solve(mGradG).trace();

        mAuxVector = mGradG * mC;
        minusGradH += 0.5 * mC.dot(mAuxVector);
        
        minusGradH -= mGradV(i);
        
        std::cout << "    "
                  << std::setw(width) << std::left << i 
                  << std::setw(width) << std::left << minusGradH
                  << std::setw(width) << std::left << temp
                  << std::setw(width) << std::left << (minusGradH - temp) / (epsilon * epsilon)
                  << std::endl;
        
    }
    
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << std::endl;
    
}
Exemple #6
0
void softAbsMetric::checkEvolution(const double epsilon)
{
    
    baseHamiltonian::checkEvolution(epsilon);
    
    // Hessian
    std::cout.precision(6);
    int width = 12;
    int nColumn = 5;

    std::cout << "Potential Hessian (d^{2}V/dq^{i}dq^{j}):" << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "Row" 
              << std::setw(width) << std::left << "Column" 
              << std::setw(width) << std::left << "Analytic"
              << std::setw(width) << std::left << "Finite"
              << std::setw(width) << std::left << "Delta / "
              << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "(i)"
              << std::setw(width) << std::left << "(j)"
              << std::setw(width) << std::left << "Derivative"
              << std::setw(width) << std::left << "Difference"
              << std::setw(width) << std::left << "Stepsize^{2}"
              << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    
    fComputeH();
    
    for(int i = 0; i < mDim; ++i)
    {
        
        VectorXd temp = VectorXd::Zero(mDim);        
        
        mQ(i) += epsilon;
        temp += gradV();
        mQ(i) -= 2.0 * epsilon;
        temp -= gradV();
        mQ(i) += epsilon;
        
        temp /= 2.0 * epsilon;
        
        for(int j = 0; j < mDim; ++j)
        {
            
            std::cout << "    "
                      << std::setw(width) << std::left << i
                      << std::setw(width) << std::left << j 
                      << std::setw(width) << std::left << mH(i, j)
                      << std::setw(width) << std::left << temp(j)
                      << std::setw(width) << std::left << (mH(i, j) - temp(j)) / (epsilon * epsilon)
                      << std::endl;
            
        }
        
    }
    
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << std::endl;
    
    // Gradient of the Hessian
    std::cout.precision(6);
    width = 12;
    nColumn = 6;
    
    std::cout << "Gradient of the Hessian (d^{3}V/dq^{i}dq^{j}dq^{k}):" << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "Component"
              << std::setw(width) << std::left << "Row" 
              << std::setw(width) << std::left << "Column" 
              << std::setw(width) << std::left << "Analytic"
              << std::setw(width) << std::left << "Finite"
              << std::setw(width) << std::left << "Delta /"
              << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "(i)"
              << std::setw(width) << std::left << "(j)"
              << std::setw(width) << std::left << "(k)"
              << std::setw(width) << std::left << "Derivative"
              << std::setw(width) << std::left << "Difference"
              << std::setw(width) << std::left << "Stepsize^{2}"
              << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    
    for(int k = 0; k < mDim; ++k)
    {
        
        mAuxMatrixOne.setZero();        
        
        mQ(k) += epsilon;
        fComputeH();
        mAuxMatrixOne += mH;
        mQ(k) -= 2.0 * epsilon;
        fComputeH();
        mAuxMatrixOne -= mH;
        mQ(k) += epsilon;
        
        mAuxMatrixOne /= 2.0 * epsilon;
        
        fComputeGradH(k);
        
        for(int i = 0; i < mDim; ++i)
        {
            
            for(int j = 0; j < mDim; ++j)
            {
                
                std::cout << "    "
                << std::setw(width) << std::left << k
                << std::setw(width) << std::left << i
                << std::setw(width) << std::left << j 
                << std::setw(width) << std::left << mGradH.block(0, k * mDim, mDim, mDim)(i, j)
                << std::setw(width) << std::left << mAuxMatrixOne(i, j)
                << std::setw(width) << std::left << (mGradH.block(0, k * mDim, mDim, mDim)(i, j) - mAuxMatrixOne(i, j)) / (epsilon * epsilon)
                << std::endl;
                
            }
            
        }
        
    }
    
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << std::endl;
    
    // Metric
    std::cout.precision(6);
    width = 12;
    nColumn = 6;
    
    std::cout << "Gradient of the metric (dLambda^{jk}/dq^{i}):" << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "Component"
              << std::setw(width) << std::left << "Row" 
              << std::setw(width) << std::left << "Column" 
              << std::setw(width) << std::left << "Analytic"
              << std::setw(width) << std::left << "Finite"
              << std::setw(width) << std::left << "Delta /"
              << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "(i)"
              << std::setw(width) << std::left << "(j)"
              << std::setw(width) << std::left << "(k)"
              << std::setw(width) << std::left << "Derivative"
              << std::setw(width) << std::left << "Difference"
              << std::setw(width) << std::left << "Epsilon^{2}"
              << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    
    fComputeMetric();
    fPrepareSpatialGradients();
    
    for(int k = 0; k < mDim; ++k)
    {
        
        // Approximate metric gradient
        MatrixXd temp = MatrixXd::Zero(mDim, mDim);        
        MatrixXd G = MatrixXd::Zero(mDim, mDim);

        mQ(k) += epsilon;
        fComputeMetric();
        G.noalias() = mEigenDeco.eigenvectors() * mSoftAbsLambda.asDiagonal() * mEigenDeco.eigenvectors().transpose();
        temp += G;
        mQ(k) -= 2.0 * epsilon;
        fComputeMetric();
        G.noalias() = mEigenDeco.eigenvectors() * mSoftAbsLambda.asDiagonal() * mEigenDeco.eigenvectors().transpose();
        temp -= G;
        mQ(k) += epsilon;
        
        temp /= 2.0 * epsilon;

        // Exact metric gradient
        fComputeMetric();
        fComputeGradH(k);
        
        mAuxMatrixOne.noalias() = mGradH.block(0, k * mDim, mDim, mDim) * mEigenDeco.eigenvectors();
        mAuxMatrixTwo.noalias() = mEigenDeco.eigenvectors().transpose() * mAuxMatrixOne;
        mAuxMatrixOne.noalias() = mPseudoJ.cwiseProduct(mAuxMatrixTwo);
        mCacheMatrix.noalias() = mAuxMatrixOne * mEigenDeco.eigenvectors().transpose();
        
        MatrixXd gradG = mEigenDeco.eigenvectors() * mCacheMatrix;
        
        // Compare
        for(int i = 0; i < mDim; ++i)
        {
            
            for(int j = 0; j < mDim; ++j)
            {
                
                std::cout << "    "
                          << std::setw(width) << std::left << k
                          << std::setw(width) << std::left << i
                          << std::setw(width) << std::left << j 
                          << std::setw(width) << std::left << gradG(i, j)
                          << std::setw(width) << std::left << temp(i, j)
                          << std::setw(width) << std::left << (gradG(i, j) - temp(i, j)) / (epsilon * epsilon)
                          << std::endl;
                
            }
            
        }
        
    }
    
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << std::endl;
    
    // Hamiltonian
    VectorXd gradH = dTaudq();
    gradH += dPhidq();
    
    std::cout << "pDot (-dH/dq^{i}):" << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "Component"
              << std::setw(width) << std::left << "Analytic"
              << std::setw(width) << std::left << "Finite"
              << std::setw(width) << std::left << "Delta /"
              << std::endl;
    std::cout << "    "
              << std::setw(width) << std::left << "(i)"
              << std::setw(width) << std::left << "Derivative"
              << std::setw(width) << std::left << "Difference"
              << std::setw(width) << std::left << "Epsilon^{2}"
              << std::endl;
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    
    for(int i = 0; i < mDim; ++i)
    {
        
        // Finite Differences
        double temp = 0.0;        
        
        mQ(i) += epsilon;
        temp -= H();
        mQ(i) -= 2.0 * epsilon;
        temp += H();
        mQ(i) += epsilon;
        
        temp /= 2.0 * epsilon;
        
        // Exact
        double minusGradH = -gradH(i);

        std::cout << "    "
                  << std::setw(width) << std::left << i 
                  << std::setw(width) << std::left << minusGradH
                  << std::setw(width) << std::left << temp
                  << std::setw(width) << std::left << (minusGradH - temp) / (epsilon * epsilon)
                  << std::endl;
        
    }
    
    std::cout << "    " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl;
    std::cout << std::endl;
    
}