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; } } } }
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; }