void MappingExtrapolate::v_CorrectPressureBCs(
        const Array<OneD, NekDouble>  &pressure)
    {
        if(m_HBCdata.num_elements()>0)
        {
            int cnt, n;
            int physTot = m_fields[0]->GetTotPoints();
            int nvel = m_fields.num_elements()-1;
            
            Array<OneD, NekDouble> Vals;
            // Remove previous correction
            for(cnt = n = 0; n < m_PBndConds.num_elements(); ++n)
            {
                if(m_PBndConds[n]->GetUserDefined() == "H")
                {
                    int nq = m_PBndExp[n]->GetNcoeffs();
                    Vmath::Vsub(nq, &(m_PBndExp[n]->GetCoeffs()[0]),  1,
                                    &(m_bcCorrection[cnt]), 1, 
                                    &(m_PBndExp[n]->UpdateCoeffs()[0]), 1);
                    cnt += nq;
                }
            }
            
            // Calculate new correction
            Array<OneD, NekDouble> Jac(physTot, 0.0);
            m_mapping->GetJacobian(Jac);
            
            Array<OneD, Array<OneD, NekDouble> > correction(nvel);
            Array<OneD, Array<OneD, NekDouble> > gradP(nvel);
            Array<OneD, Array<OneD, NekDouble> > wk(nvel);
            Array<OneD, Array<OneD, NekDouble> > wk2(nvel);
            for (int i=0; i<nvel; i++)
            {
                wk[i] = Array<OneD, NekDouble> (physTot, 0.0);
                gradP[i] = Array<OneD, NekDouble> (physTot, 0.0);
                correction[i] = Array<OneD, NekDouble> (physTot, 0.0);
            }

            // Calculate G(p)
            for(int i = 0; i < nvel; ++i)
            {
                m_fields[0]->PhysDeriv(MultiRegions::DirCartesianMap[i], pressure, gradP[i]);
                if(m_fields[0]->GetWaveSpace())
                {
                    m_fields[0]->HomogeneousBwdTrans(gradP[i], wk[i]);
                }
                else
                {
                    Vmath::Vcopy(physTot, gradP[i], 1, wk[i], 1);
                }
            }
            m_mapping->RaiseIndex(wk, correction);   // G(p)

            // alpha*J*(G(p))
            if (!m_mapping->HasConstantJacobian())
            {
                for(int i = 0; i < nvel; ++i)
                {
                    Vmath::Vmul(physTot, correction[i], 1, Jac, 1, correction[i], 1);
                }                
            }   
            for(int i = 0; i < nvel; ++i)
            {
                Vmath::Smul(physTot, m_pressureRelaxation, correction[i], 1, correction[i], 1); 
            }
            
            if(m_pressure->GetWaveSpace())
            {
                for(int i = 0; i < nvel; ++i)
                {
                    m_pressure->HomogeneousFwdTrans(correction[i], correction[i]);
                }
            }            
            // p_i - alpha*J*div(G(p))    
            for (int i = 0; i < nvel; ++i)
            {
                Vmath::Vsub(physTot, gradP[i], 1, correction[i], 1, correction[i], 1);
            }
            
            // Get value at boundary and calculate Inner product
            StdRegions::StdExpansionSharedPtr Pbc;
            StdRegions::StdExpansionSharedPtr elmt;
            Array<OneD, Array<OneD, const NekDouble> > correctionElmt(m_bnd_dim);
            Array<OneD, Array<OneD, NekDouble> > BndValues(m_bnd_dim);
            for(int i = 0; i < m_bnd_dim; i++)
            {
                BndValues[i] = Array<OneD, NekDouble> (m_pressureBCsMaxPts,0.0);
            }
            for(int j = 0 ; j < m_HBCdata.num_elements() ; j++)
            {
                /// Casting the boundary expansion to the specific case
                Pbc =  boost::dynamic_pointer_cast<StdRegions::StdExpansion> 
                            (m_PBndExp[m_HBCdata[j].m_bndryID]
                                ->GetExp(m_HBCdata[j].m_bndElmtID));

                /// Picking up the element where the HOPBc is located
                elmt = m_pressure->GetExp(m_HBCdata[j].m_globalElmtID);

                /// Assigning
                for(int i = 0; i < m_bnd_dim; i++)
                {
                    correctionElmt[i]  = correction[i] + m_HBCdata[j].m_physOffset;
                }
                Vals = m_bcCorrection + m_HBCdata[j].m_coeffOffset;
                // Getting values on the edge and filling the correction
                switch(m_pressure->GetExpType())
                {
                    case MultiRegions::e2D:
                    case MultiRegions::e3DH1D:
                    {                                                         
                        elmt->GetEdgePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[0], BndValues[0]);                    
                        elmt->GetEdgePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[1], BndValues[1]);

                        // InnerProduct 
                        Pbc->NormVectorIProductWRTBase(BndValues[0], BndValues[1],
                                                       Vals);
                    }
                    break;

                    case MultiRegions::e3D:
                    {
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc, 
                                              correctionElmt[0], BndValues[0]);
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[1], BndValues[1]);
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[2], BndValues[2]);
                        Pbc->NormVectorIProductWRTBase(BndValues[0], BndValues[1],
                                              BndValues[2], Vals);
                    }
                    break;
                default:
                    ASSERTL0(0,"Dimension not supported");
                    break;
                }
            }      
            
            // Apply new correction
            for(cnt = n = 0; n < m_PBndConds.num_elements(); ++n)
            {
                if(m_PBndConds[n]->GetUserDefined() == "H")
                {
                    int nq = m_PBndExp[n]->GetNcoeffs();
                    Vmath::Vadd(nq, &(m_PBndExp[n]->GetCoeffs()[0]),  1,
                                    &(m_bcCorrection[cnt]), 1, 
                                    &(m_PBndExp[n]->UpdateCoeffs()[0]), 1);
                    cnt += nq;
                }
            }                
        }        
    }
Exemplo n.º 2
0
void tet_basis::proj2d(FLT *lin1, FLT *f1, FLT *dx1, FLT *dy1, int stride) {
	Array<FLT,2> wk0(gpy,3+em);
	Array<FLT,2> wk1(gpy,3+em);
	Array<FLT,2> wk2(gpy,3+em);
   const int be2 = em+3, be3 = 2*em+3, bint = 3+3*em;
   const int lgpx = gpx, lgpy = gpy, lnmodx = nmodx;  
   FLT lcl0, lcl1, lcl2;
   FLT xp1,oeta; 
   int sign;
#ifdef BZ_DEBUG
   Array<FLT,1> lin(lin1, shape(3+3*em+fm), neverDeleteData);
   Array<FLT,2> f(f1, shape(gpx,stride), neverDeleteData);
   Array<FLT,2> dx(dx1, shape(gpx,stride), neverDeleteData);
   Array<FLT,2> dy(dy1, shape(gpx,stride), neverDeleteData);
#endif
   
   /* DETERMINE U VALUES, GRAD U VALUES
      AT COLLOCATION POINTS
      SUM HAT(U) FOR DU/DX AND DU/DY
   */
   
   /* GENERAL FORMULA
   	dg/dr = 2.0/(1-n) g(s) dg/dx
   	dg/ds = g(x)dg/dn +(1+x)/2 dg/dr = g(x)dg/dn +(1+x)/(1-s) g(s) dg/dx 
   */

   /* PART I - sum u*g_mn for each n, s_j   */
	for(int j = 0; j < lgpy; ++j ) {
		oeta = y0(j);
      
		/* VERTEX 1 */
		wk0(j,0) = lin(0)*gy(j,1);
		wk1(j,0) = lin(0)*dgy(j,1);
		wk2(j,0) = wk0(j,0)*oeta;

		/* VERTEX 2, EDGE 3 */
		sign = 1;
		lcl0 = lin(1)*gy(j,2);
		lcl1 = lin(1)*dgy(j,2);
		for(int i = 0; i < em; ++i){
			lcl0 += sign*lin(be3+i)*gy(j,3+em+i);	
			lcl1 += sign*lin(be3+i)*dgy(j,3+em+i);
			sign*=-1;
		}
		wk0(j,1) = lcl0;
		wk1(j,1) = lcl1;
		wk2(j,1) = wk0(j,1)*oeta;

		/* VERTEX 3, EDGE 2 */
		lcl0 = lin(2)*gy(j,2);
		lcl1 = lin(2)*dgy(j,2);
		for(int i = 0; i < em; ++i){
			lcl0 += lin(be2+i)*gy(j,3+em+i);	
			lcl1 += lin(be2+i)*dgy(j,3+em+i);
		}
		wk0(j,2) = lcl0;
		wk1(j,2) = lcl1;
		wk2(j,2) = wk0(j,2)*oeta;
		
		/* EDGE 1, FACE 0 */		
		int ind2 = 0;		
		for(int p = 3; p < em+3; ++p){
			lcl0=lin(p)*gy(j,p);	
			lcl1=lin(p)*gy(j,p);		
			for(int i = 1; i <= em-p+2; ++i){	
				lcl0 += lin(bint+ind2)*gy(j,3+2*em+ind2);
				lcl1 += lin(bint+ind2)*gy(j,3+2*em+ind2);
				++ind2;
			}			
			wk0(j,p) = lcl0;
			wk1(j,p) = lcl1;
			wk2(j,p) = wk0(j,p)*oeta;
		}
	}
		
		
	/* SUM OVER N AT EACH I,J POINT   */  
	for (int i = 0; i < lgpx; ++i ) {
		xp1 = x0(i);
		for (int j = 0; j < lgpy; ++j) {
			lcl0 = wk0(j,0)*gx(i,0);
			lcl1 = wk1(j,0)*gx(i,0);
			lcl2 = wk2(j,0)*dgx(i,0);
			
			for(int n = 1; n < lnmodx; ++n ) {     
				lcl0 += wk0(j,n)*gx(i,n);
				lcl1 += wk1(j,n)*gx(i,n);
				lcl2 += wk2(j,n)*dgx(i,n);
			}
			f(i,j)  = lcl0;
			dy(i,j) = lcl1 +xp1*lcl2;
			dx(i,j) = lcl2;
		}
	}

   return;
}