//called by projection solve for irreg x domain void InflowOutflowPoissonDomainBC::getInhomFaceFlux(Real& a_faceFlux, const VolIndex& a_vof, const int& a_comp, const EBCellFAB& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time) { bool isOutflow= (a_side==Side::Hi) && (a_idir==m_flowDir); if (!isOutflow) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time); } else { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time); // diriBC.getHigherOrderFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, // a_dx, a_idir, a_side, a_dit, a_time); } }
//called by macEnforceGradientBC, useAreaFrac = false void InflowOutflowPoissonDomainBC::getFaceGradPhi(Real& a_faceFlux, const FaceIndex& a_face, const int& a_comp, const EBCellFAB& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useAreaFrac, const RealVect& a_centroid, const bool& a_useHomogeneous) { bool isOutflow= (a_side==Side::Hi) && (a_idir==m_flowDir); if (!isOutflow) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getFaceGradPhi(a_faceFlux, a_face, a_comp,a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time,a_useAreaFrac,a_centroid,a_useHomogeneous); } else { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.getFaceGradPhi(a_faceFlux, a_face, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time,a_useAreaFrac,a_centroid,a_useHomogeneous); } }
//////called by MAC projection solver for domain bc on phi void InflowOutflowPoissonDomainBC::getFaceFlux(BaseFab<Real>& a_faceFlux, const BaseFab<Real>& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useHomogeneous) { //for phi: outflow dirichlet. inflow neumann bool isOutflow= (a_side==Side::Hi) && (a_idir==m_flowDir); if (!isOutflow) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); // diriBC.getHigherOrderFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } }
//called by macEnforceGradientBC, useAreaFrac = false void InflowOutflowPoissonDomainBC::getFaceGradPhi(Real& a_faceFlux, const FaceIndex& a_face, const int& a_comp, const EBCellFAB& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useAreaFrac, const RealVect& a_centroid, const bool& a_useHomogeneous) { bool isInsideTube = false; if ((m_doJet2) && (a_side==Side::Hi) && (a_idir == m_flowDir)) { RealVect probLo = RealVect::Zero; RealVect loc = EBArith::getFaceLocation(a_face,a_dx,probLo); const RealVect tubeCenter = m_jet2PoiseInflowFunc->getTubeCenter(); Real tubeRadius = m_jet2PoiseInflowFunc->getTubeRadius(); Real radius = m_jet2PoiseInflowFunc->getRadius(loc); CH_assert(loc[m_flowDir] == tubeCenter[m_flowDir]); // start hardwire Real wallThickness = 0.075; Real bcFactor = 0.5; // % of outflow face to be set to inflow condition ParmParse pp; pp.get("wall_thickness",wallThickness); tubeRadius += wallThickness * bcFactor /2.0; // end hardwire if (radius <= tubeRadius) { isInsideTube = true; } } bool isOutflow = (a_side==Side::Hi) && (a_idir==m_flowDir) && (!(isInsideTube)); // bool isOutflow= (a_side==Side::Hi) && (a_idir==m_flowDir); if (!isOutflow) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getFaceGradPhi(a_faceFlux, a_face, a_comp,a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time,a_useAreaFrac,a_centroid,a_useHomogeneous); } else { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.getFaceGradPhi(a_faceFlux, a_face, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time,a_useAreaFrac,a_centroid,a_useHomogeneous); } }
//velocity stencil void InflowOutflowHelmholtzDomainBC::getFluxStencil( VoFStencil& a_stencil, const VolIndex& a_vof, const int& a_comp, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const EBISBox& a_ebisBox) { bool isInsideTube = false; if ((m_doJet2) && (a_side==Side::Hi) && (a_idir == m_flowDir)) { RealVect probLo = RealVect::Zero; RealVect loc = EBArith::getVofLocation(a_vof,a_dx,probLo); loc[a_idir] += 0.5*a_dx[a_idir]; // loc at face center const RealVect tubeCenter = m_jet2PoiseInflowFunc->getTubeCenter(); Real tubeRadius = m_jet2PoiseInflowFunc->getTubeRadius(); Real radius = m_jet2PoiseInflowFunc->getRadius(loc); CH_assert(loc[m_flowDir] == tubeCenter[m_flowDir]); // start hardwire Real wallThickness = 0.075; Real bcFactor = 0.5; // % of outflow face to be set to inflow condition ParmParse pp; pp.get("wall_thickness",wallThickness); tubeRadius += wallThickness * bcFactor /2.0; // end hardwire if (radius <= tubeRadius) { isInsideTube = true; } } bool isOutflow = (a_side==Side::Hi) && (a_idir==m_flowDir) && (!(isInsideTube)); // bool isOutflow = (a_side==Side::Hi) && (a_idir==m_flowDir); bool isSlipWall= ((a_idir!=m_flowDir) && (a_idir != a_comp) && ((m_doSlipWallsHi[a_idir]==1 && a_side == Side::Hi)||(m_doSlipWallsLo[a_idir]==1 && a_side == Side::Lo))); if (isOutflow || isSlipWall) { NeumannPoissonDomainBC neumannBC; neumannBC.getFluxStencil(a_stencil, a_vof, a_comp, a_dx, a_idir, a_side, a_ebisBox); } else { DirichletPoissonDomainBC diriBC; diriBC.setEBOrder(2); diriBC.getFluxStencil(a_stencil, a_vof, a_comp, a_dx, a_idir, a_side, a_ebisBox); } }
//pressure stencil void InflowOutflowPoissonDomainBC::getFluxStencil( VoFStencil& a_stencil, const VolIndex& a_vof, const int& a_comp, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const EBISBox& a_ebisBox) { bool isOutflow= (a_side==Side::Hi) && (a_idir==m_flowDir); if (!isOutflow) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getFluxStencil(a_stencil, a_vof, a_comp, a_dx, a_idir, a_side, a_ebisBox); } else { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.setEBOrder(1); diriBC.getFluxStencil(a_stencil, a_vof, a_comp, a_dx, a_idir, a_side, a_ebisBox); } }
//velocity stencil void InflowOutflowHelmholtzDomainBC::getFluxStencil( VoFStencil& a_stencil, const VolIndex& a_vof, const int& a_comp, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const EBISBox& a_ebisBox) { bool isOutflow = (a_side==Side::Hi) && (a_idir==m_flowDir); bool isSlipWall= ((a_idir!=m_flowDir) && (a_idir != a_comp) && ((m_doSlipWallsHi[a_idir]==1 && a_side == Side::Hi)||(m_doSlipWallsLo[a_idir]==1 && a_side == Side::Lo))); if (isOutflow || isSlipWall) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getFluxStencil(a_stencil, a_vof, a_comp, a_dx, a_idir, a_side, a_ebisBox); } else { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.setEBOrder(2); diriBC.getFluxStencil(a_stencil, a_vof, a_comp, a_dx, a_idir, a_side, a_ebisBox); } }
//called by EBAMRPoissonOp::applyOp for viscous Helmholtz EB x domain void InflowOutflowHelmholtzDomainBC::getInhomFaceFlux(Real& a_faceFlux, const VolIndex& a_vof, const int& a_comp, const EBCellFAB& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time) { //vel: outflow is Neumann. all others Dirichlet int velcomp = DirichletPoissonEBBC::s_velComp; bool isOutflow = ((a_side==Side::Hi) && (a_idir==m_flowDir)); bool isInflow = ((a_side==Side::Lo) && (a_idir==m_flowDir)); bool isSlipWall = ((a_idir!=m_flowDir) && (a_idir != velcomp) && ((m_doSlipWallsHi[a_idir]==1 && a_side == Side::Hi)||(m_doSlipWallsLo[a_idir]==1 && a_side == Side::Lo))); bool isVelNeum = (isOutflow || isSlipWall); if (isVelNeum) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } else if (isInflow) { DirichletPoissonDomainBC diriBC; if (velcomp==m_flowDir) { if (!m_doPoiseInflow && !m_doWomersleyInflow) { diriBC.setValue(m_inflowVel); } else if (m_doPoiseInflow) { diriBC.setFunction(m_poiseInflowFunc); } else if (m_doWomersleyInflow) { double PI = 3.1416; int freq[10] = { 1,2,3,4,5,6,7,8 }; double Vp[10] = { 0.33,0.24,0.24,0.12,0.11,0.13,0.06,0.04 }; double Theta[10] = { 74,79,121,146,147,179,233,218 }; double AmpXsi[10] = { 1.7639,1.4363,1.2517,1.1856,1.1603,1.1484,1.1417,1.1214 }; double AngXsi[10] = { -0.2602,-0.3271,-0.2799,-0.2244,-0.1843,-0.1576,-0.1439,-0.1195 }; Real VelMult = 2; int Maxp = 8; for (int p=0;p<Maxp;p++) VelMult += Vp[p] * AmpXsi[p] * cos (2 * PI * freq[p] * g_simulationTime - Theta[p]*PI/180 + AngXsi[p]); diriBC.setValue(m_inflowVel*VelMult/2); } } else { diriBC.setValue(0.0); } //called by EBAMRPoissonOp::applyOp for viscous Helmholtz EB x domain if (s_higherOrderHelmBC) { diriBC.getHigherOrderInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time); } else { diriBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } } else { //wall bc no slip DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); if (s_higherOrderHelmBC) { diriBC.getHigherOrderInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time); } else { diriBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } } }
//called by EBAMRPoissonOp::applyOp for viscous Helmholtz EB x domain void InflowOutflowHelmholtzDomainBC::getInhomFaceFlux(Real& a_faceFlux, const VolIndex& a_vof, const int& a_comp, const EBCellFAB& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time) { //vel: outflow is Neumann. all others Dirichlet int velcomp = DirichletPoissonEBBC::s_velComp; bool isOutflow = ((a_side==Side::Hi) && (a_idir==m_flowDir)); bool isInflow = ((a_side==Side::Lo) && (a_idir==m_flowDir)); bool isSlipWall = ((a_idir!=m_flowDir) && (a_idir != velcomp) && ((m_doSlipWallsHi[a_idir]==1 && a_side == Side::Hi)||(m_doSlipWallsLo[a_idir]==1 && a_side == Side::Lo))); // bool isVelNeum = (isOutflow || isSlipWall); if (isSlipWall) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } else if (isInflow) { DirichletPoissonDomainBC diriBC; if (velcomp==m_flowDir) { if (!m_doJet1PoiseInflow) { diriBC.setValue(m_jet1inflowVel); } else if (m_doJet1PoiseInflow) { diriBC.setFunction(m_jet1PoiseInflowFunc); } } else { diriBC.setValue(0.0); } //called by EBAMRPoissonOp::applyOp for viscous Helmholtz EB x domain if (s_higherOrderHelmBC) { diriBC.getHigherOrderInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time); } else { diriBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } } else if (isOutflow) { if (!m_doJet2) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } else if (m_doJet2) { const IntVect& iv = a_vof.gridIndex(); RealVect loc = EBArith::getIVLocation(iv,a_dx,a_probLo); loc[a_idir] += 0.5*a_dx[a_idir]; // loc is face centered const RealVect tubeCenter = m_jet2PoiseInflowFunc->getTubeCenter(); Real tubeRadius = m_jet2PoiseInflowFunc->getTubeRadius(); CH_assert(loc[m_flowDir] == tubeCenter[m_flowDir]); bool isInsideTube = false; Real radius = m_jet2PoiseInflowFunc->getRadius(loc); // start hardwire Real wallThickness = 0.075; Real bcFactor = 0.5; // % of outflow face to be set to inflow condition ParmParse pp; pp.get("wall_thickness",wallThickness); tubeRadius += wallThickness * bcFactor /2.0; // end hardwire if (radius <= tubeRadius) { isInsideTube = true; } if (!(isInsideTube)) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } else if (isInsideTube) { DirichletPoissonDomainBC diriBC; if (velcomp==m_flowDir) { if (!m_doJet2PoiseInflow) { diriBC.setValue(m_jet2inflowVel); } else if (m_doJet2PoiseInflow) { diriBC.setFunction(m_jet2PoiseInflowFunc); } } else { diriBC.setValue(0.0); } //called by EBAMRPoissonOp::applyOp for viscous Helmholtz EB x domain if (s_higherOrderHelmBC) { diriBC.getHigherOrderInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time); } else { diriBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } } } } else { //wall bc no slip DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); if (s_higherOrderHelmBC) { diriBC.getHigherOrderInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time); } else { diriBC.getInhomFaceFlux(a_faceFlux, a_vof, a_comp, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit,a_time); } } }
/** This is called by EBAMRPoissonOp::applyDomainFlux in EBAMRPoissonOp::applyOp for reg cells. For boundary conditions on velocity in viscous operator. */ void InflowOutflowHelmholtzDomainBC::getFaceFlux(BaseFab<Real>& a_faceFlux, const BaseFab<Real>& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useHomogeneous) { //vel: outflow is neumann. all others dirichlet. inflow uses inflow vel as the value int velcomp = DirichletPoissonEBBC::s_velComp; bool isOutflow = ((a_side==Side::Hi) && (a_idir==m_flowDir)); bool isInflow = ((a_side==Side::Lo) && (a_idir==m_flowDir)); bool isSlipWall = ((a_idir!=m_flowDir) && (a_idir != velcomp) && ((m_doSlipWallsHi[a_idir]==1 && a_side == Side::Hi)||(m_doSlipWallsLo[a_idir]==1 && a_side == Side::Lo))); // bool isVelNeum = (isOutflow || isSlipWall); if (isSlipWall) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else if (isInflow) { DirichletPoissonDomainBC diriBC; if (velcomp==m_flowDir) { if (!m_doJet1PoiseInflow) { diriBC.setValue(m_jet1inflowVel); } else if (m_doJet1PoiseInflow) { diriBC.setFunction(m_jet1PoiseInflowFunc); } } else { diriBC.setValue(0.0); } //basefab flux--EBAMRPoissonOp::applyDomainFlux calls this directly for viscous operator if (s_higherOrderHelmBC) { diriBC.getHigherOrderFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else { diriBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } } else if (isOutflow) { if (!m_doJet2) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else if (m_doJet2) { const RealVect tubeCenter = m_jet2PoiseInflowFunc->getTubeCenter(); Real tubeRadius = m_jet2PoiseInflowFunc->getTubeRadius(); CH_assert(a_phi.nComp() == 1); // start hardwire Real wallThickness = 0.075; Real bcFactor = 0.5; // % of outflow face to be set to inflow condition ParmParse pp; pp.get("wall_thickness",wallThickness); tubeRadius += wallThickness * bcFactor /2.0; // end hardwire for (int comp=0; comp<a_phi.nComp(); comp++) { const Box& box = a_faceFlux.box(); int iside = -1; //a_side == Side::Hi BoxIterator bit(box); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); RealVect loc = EBArith::getIVLocation(iv,a_dx,a_probLo); loc[a_idir] -= iside * 0.5 * a_dx[a_idir];//point is now at the face center CH_assert(loc[m_flowDir] == tubeCenter[m_flowDir]); bool isInsideTube = false; Real radius = m_jet2PoiseInflowFunc->getRadius(loc); if (radius <= tubeRadius) { isInsideTube = true; } if (isInsideTube) // Dirichlet { Real value = 0.0; // takes care of tangential comps if (velcomp == m_flowDir) { if (m_doJet2PoiseInflow) { value = m_jet2PoiseInflowFunc->getVel(radius)[m_flowDir]; } else if (!(m_doJet2PoiseInflow)) { value = m_jet2inflowVel; } } if (s_higherOrderHelmBC) { IntVect iv1 = bit(); Real phi0 = a_phi(iv1,comp); iv1[a_idir] += iside; Real phi1 = a_phi(iv1,comp); iv1[a_idir] -= iside; a_faceFlux(iv,comp) = -iside*(8.0*value + phi1 - 9.0*phi0)/(3.0*a_dx[a_idir]); } else if (!s_higherOrderHelmBC) { Real ihdx = 2.0 / a_dx[a_idir]; Real phiVal = a_phi(iv,comp); a_faceFlux(iv,comp) = iside * ihdx * (phiVal - value); } } else if (!isInsideTube) // Neumann { Real value = 0.0; a_faceFlux(iv,comp) = iside * value; } } } } } else { //wall bc no slip DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); if (s_higherOrderHelmBC) { diriBC.getHigherOrderFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else { diriBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } } }
//////called by MAC projection solver for domain bc on phi void InflowOutflowPoissonDomainBC::getFaceFlux(BaseFab<Real>& a_faceFlux, const BaseFab<Real>& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useHomogeneous) { //for phi: outflow dirichlet. inflow neumann bool isOutflow= (a_side==Side::Hi) && (a_idir==m_flowDir); if (!isOutflow) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else { if (!(m_doJet2)) { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); // diriBC.getHigherOrderFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else if (m_doJet2) { const RealVect tubeCenter = m_jet2PoiseInflowFunc->getTubeCenter(); Real tubeRadius = m_jet2PoiseInflowFunc->getTubeRadius(); // start hardwire Real wallThickness = 0.075; Real bcFactor = 0.5; // % of outflow face to be set to inflow condition ParmParse pp; pp.get("wall_thickness",wallThickness); tubeRadius += wallThickness * bcFactor /2.0; // end hardwire CH_assert(a_phi.nComp() == 1); for (int comp=0; comp<a_phi.nComp(); comp++) { const Box& box = a_faceFlux.box(); int iside = -1; // a_side == Side::Hi in this loop Real value = 0.0; BoxIterator bit(box); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); RealVect loc = EBArith::getIVLocation(iv,a_dx,a_probLo); loc[a_idir] -= iside * 0.5 * a_dx[a_idir]; //loc is now at the face center CH_assert(loc[m_flowDir] == tubeCenter[m_flowDir]); bool isInsideTube = false; Real radius = m_jet2PoiseInflowFunc->getRadius(loc); if (radius <= tubeRadius) { isInsideTube = true; } if (isInsideTube) { a_faceFlux(iv,comp) = iside * value; //Neumann } else if (!(isInsideTube)) { Real ihdx = 2.0 / a_dx[a_idir]; Real phiVal = a_phi(iv,comp); a_faceFlux(iv,comp) = iside * ihdx * (phiVal - value); //Dirichlet } } } } } }
int main(int argc,char **argv) { #ifdef CH_MPI MPI_Init(&argc, &argv); #endif // registerDebugger(); // begin forever present scoping trick { pout()<<std::endl; Vector<std::string> names0(1, "phi"); Vector<int> refRatio(3,2); Vector<Real> coveredVal(1,3.0); const char* in_file = "sphere.inputs"; // read in an input file or use default file // if (argc > 1) // { // in_file = argv[1]; // } //parse input file ParmParse pp(0,NULL,NULL,in_file); RealVect center; Real radius; RealVect origin; RealVect dx; Box domain; ProblemDomain pDomain(domain); int eekflag = 0; LevelData<EBCellFAB> fine, med, coarse; LevelData<EBCellFAB> fineRHS, medRHS, coarseRHS; LevelData<EBCellFAB> fineResidual, mediumResidual, coarseResidual; Vector<LevelData<EBCellFAB>* > ebvector(3,NULL); Vector<LevelData<EBCellFAB>* > vresidual(3,NULL); Vector<LevelData<EBCellFAB>* > rhsvector(3,NULL); ebvector[0]=&coarse; ebvector[1]=&med; ebvector[2]=&fine; vresidual[0]=&coarseResidual; vresidual[1]=&mediumResidual; vresidual[2]=&fineResidual; rhsvector[0] = &coarseRHS; rhsvector[1] = &medRHS; rhsvector[2] = &fineRHS; readGeometryInfo(domain, dx, origin, center, radius); Box domainFine(domain), domainMedi, domainCoar; ProblemDomain pFine(domain); RealVect dxFine(dx), dxMedi, dxCoar; CH_assert(eekflag == 0); domainMedi = coarsen(domainFine, 2); domainCoar = coarsen(domainMedi, 2); dxMedi = 2.0*dxFine; dxCoar = 2.0*dxMedi; Vector<RealVect> xVec(3, IntVect::Unit); xVec[0]*= dxCoar; xVec[1]*= dxMedi; xVec[2]*= dxFine; Vector<DisjointBoxLayout> grids(3); ProblemDomain baseDomain(domainCoar); ProblemDomain pMed(domainMedi); Vector<ProblemDomain> pd(3); pd[0] = baseDomain; pd[1] = pMed; pd[2] = ProblemDomain(domainFine); RefCountedPtr<BaseBCValue>value(new DirichletBC()); DirichletPoissonDomainBC* domainBC = new DirichletPoissonDomainBC(); domainBC->setFunction(value); RefCountedPtr<BaseDomainBC> bc(domainBC); //make data holders Vector<int> comps(2,1); int steps= 5; int step = 0; while (step < steps) { eekflag = makeGeometry( domain, dx, origin, center, radius); //make grids //IntVectSet tags = mfIndexSpace->interfaceRegion(2); IntVectSet tags(domainCoar); tags.grow(1); makeHierarchy(grids, baseDomain, tags); const CH_XD::EBIndexSpace* ebisPtr = Chombo_EBIS::instance(); Vector<EBISLayout> layouts(3); EBISLayout& fineLayout = layouts[2]; ebisPtr->fillEBISLayout(fineLayout, grids[2], domainFine, 2); EBCellFactory fineFactory(fineLayout); ebvector[2]->define(grids[2], 1, IntVect::Unit, fineFactory); rhsvector[2]->define(grids[2], 1, IntVect::Zero, fineFactory); EBISLayout& medLayout = layouts[1]; ebisPtr->fillEBISLayout(medLayout, grids[1], domainMedi, 2); EBCellFactory medFactory(medLayout); ebvector[1]->define(grids[1], 1, IntVect::Unit, medFactory); rhsvector[1]->define(grids[1], 1, IntVect::Zero, medFactory); EBISLayout& coarseLayout = layouts[0]; ebisPtr->fillEBISLayout(coarseLayout, grids[0], domainCoar, 2); EBCellFactory coarseFactory(coarseLayout); ebvector[0]->define(grids[0], 1, IntVect::Unit, coarseFactory); rhsvector[0]->define(grids[0], 1, IntVect::Zero, coarseFactory); for (int lev=0; lev<3; lev++) { setValue(*rhsvector[lev], RHS(), pd[lev].domainBox(), xVec[lev], origin, true); } Vector<int> refRatio(3,2); int max_iter = 40; pp.get("max_iter", max_iter); Real eps = 1.e-6; pp.get("eps", eps); int relaxType; pp.get("relaxType",relaxType); DirichletPoissonDomainBCFactory* domDirBC = new DirichletPoissonDomainBCFactory(); domDirBC->setFunction(value); RefCountedPtr<BaseDomainBCFactory> domBC( domDirBC ); DirichletPoissonEBBCFactory* ebDirBC = new DirichletPoissonEBBCFactory(); ebDirBC->setFunction(value); RefCountedPtr<BaseEBBCFactory> ebBC( ebDirBC ); Vector<EBLevelGrid> eblgs(3); Vector<RefCountedPtr<EBQuadCFInterp> > quadCFI(3, RefCountedPtr<EBQuadCFInterp>()); for (int i=0; i<3; i++) { eblgs[i] = EBLevelGrid(grids[i], layouts[i], pd[i]); if (i > 0) { quadCFI[i] = RefCountedPtr<EBQuadCFInterp>( new EBQuadCFInterp(grids[i], grids[i-1], layouts[i], layouts[i-1], pd[i-1], refRatio[i-1], 1, *eblgs[i].getCFIVS())); } } EBAMRPoissonOpFactory opFact(eblgs, refRatio, quadCFI, xVec[0], RealVect::Zero, 4, relaxType, domBC, ebBC, 0.0, 1.0, 0.0, IntVect::Unit, IntVect::Zero); for (int i=0; i<3; i++) { LevelData<EBCellFAB> &phi=*ebvector[i], &rhs=*rhsvector[i], &residual=*vresidual[i]; LevelData<EBCellFAB> correction; DisjointBoxLayout dblMGCoar; EBISLayout ebislMGCoar; EBAMRPoissonOp* opPtr = opFact.AMRnewOp(pd[i]); EBAMRPoissonOp& op = *opPtr; RelaxSolver<LevelData<EBCellFAB> > solver; solver.define(&op, false); solver.m_imax = max_iter; solver.m_eps = eps; op.create(residual, rhs); op.create(correction, phi); op.setToZero(residual); op.setToZero(phi); op.residual(residual, phi, rhs); Real r2norm = op.norm(residual, 2); Real r0norm = op.norm(residual, 0); pout()<<indent<<"Residual L2 norm "<<r2norm<<"Residual max norm = " <<r0norm<<std::endl; solver.solve(phi, rhs); op.residual(residual, phi, rhs); r2norm = op.norm(residual, 2); r0norm = op.norm(residual, 0); pout()<<indent2<<"Residual L2 norm "<<r2norm<<" Residual max norm = " <<r0norm<<std::endl; delete opPtr; } #ifdef CH_USE_HDF5 sprintf(iter_str, "residual.%03d.%dd.hdf5",step, SpaceDim); Vector<std::string> names(1); names[0]="residual"; writeEBHDF5(iter_str, grids, vresidual, names, domainCoar, dxCoar[0], 1, step, refRatio, 3, true, coveredVal); sprintf(iter_str, "phi.%03d.%dd.hdf5",step, SpaceDim); names[0]="phi"; writeEBHDF5(iter_str, grids, ebvector ,names, domainCoar, dxCoar[0], 1, step, refRatio, 3, true, coveredVal); #endif step++; center[0]-= dx[0]/3.0; center[1]-= dx[1]/2.0; radius += dx[0]/6.0; Chombo_EBIS::instance()->clear(); pout()<<step<<std::endl; } pout() <<"\n "<<indent2<<pgmname<<" test passed " << endl; } // end scoping trick #ifdef CH_MPI MPI_Finalize(); #endif return 0; }