diff --git a/amr-wind/core/FieldBCOps.H b/amr-wind/core/FieldBCOps.H index 98b605e4a0..bdd2f43121 100644 --- a/amr-wind/core/FieldBCOps.H +++ b/amr-wind/core/FieldBCOps.H @@ -49,7 +49,7 @@ struct FieldBCNoOp AMREX_GPU_HOST constexpr explicit FieldBCNoOp(const Field& /*unused*/) {} - FunctorType operator()() const { return *this; } + FunctorType operator()(const int /*face_dir*/ = -1) const { return *this; } AMREX_GPU_DEVICE void operator()( @@ -120,24 +120,28 @@ struct DirichletOp amrex::GpuArray m_bc_type; const InflowOpType m_inflow_op; const WallOpType m_wall_op; + const int m_face_dir; AMREX_GPU_HOST - constexpr explicit DirichletOp(const Field& fld) + constexpr explicit DirichletOp(const Field& fld, const int face_dir) : m_ncomp(fld.num_comp()) , m_bc_type(fld.bc_type()) , m_inflow_op(fld) , m_wall_op(fld) + , m_face_dir(face_dir) {} AMREX_GPU_HOST DirichletOp( const Field& fld, const InflowOpType& inflow_op, - const WallOpType& wall_op) + const WallOpType& wall_op, + const int face_dir) : m_ncomp(fld.num_comp()) , m_bc_type(fld.bc_type()) , m_inflow_op(inflow_op) , m_wall_op(wall_op) + , m_face_dir{face_dir} {} AMREX_GPU_DEVICE @@ -169,9 +173,11 @@ struct DirichletOp } // Check if the point in question is on the boundary + const int big_end = + domain_box.bigEnd(idir) + ((idir == m_face_dir) ? 1 : 0); const bool is_bndry = (ori.isLow() ? (iv[idir] < domain_box.smallEnd(idir)) - : (iv[idir] > domain_box.bigEnd(idir))); + : (iv[idir] > big_end)); if (!is_bndry) { continue; } @@ -207,7 +213,10 @@ struct FieldBCDirichlet explicit FieldBCDirichlet(const Field& fld) : m_field(fld) {} - inline FunctorType operator()() const { return FunctorType(m_field); } + inline FunctorType operator()(const int face_dir = -1) const + { + return FunctorType(m_field, face_dir); + } const Field& m_field; }; @@ -228,11 +237,11 @@ struct BCOpCreator : m_field(fld), m_inflow_op(inflow_op), m_wall_op(wall_op) {} - inline FunctorType operator()() const + inline FunctorType operator()(const int face_dir = -1) const { return FunctorType{ - m_field, m_inflow_op.device_instance(), - m_wall_op.device_instance()}; + m_field, m_inflow_op.device_instance(), m_wall_op.device_instance(), + face_dir}; } const Field& m_field; diff --git a/amr-wind/core/FieldFillPatchOps.H b/amr-wind/core/FieldFillPatchOps.H index c2870d07ff..7f8b3fb98e 100644 --- a/amr-wind/core/FieldFillPatchOps.H +++ b/amr-wind/core/FieldFillPatchOps.H @@ -270,29 +270,39 @@ public: { if (lev == 0) { - amrex::PhysBCFunct> physbc( - m_mesh.Geom(lev), bcrec, bc_functor()); for (int i = 0; i < static_cast(mfabs.size()); i++) { + amrex::PhysBCFunct> physbc( + m_mesh.Geom(lev), bcrec, bc_functor_face(i)); amrex::FillPatchSingleLevel( *mfabs[i], nghost, time, {ffabs[i]}, {time}, 0, 0, 1, m_mesh.Geom(lev), physbc, i); } } else { - amrex::PhysBCFunct> cphysbc( - m_mesh.Geom(lev - 1), bcrec, bc_functor()); - - amrex::PhysBCFunct> fphysbc( - m_mesh.Geom(lev), bcrec, bc_functor()); + AMREX_D_TERM( + amrex::PhysBCFunct> cphysbcx( + m_mesh.Geom(lev - 1), bcrec, bc_functor_face(0)); + , amrex::PhysBCFunct> cphysbcy( + m_mesh.Geom(lev - 1), bcrec, bc_functor_face(1)); + , amrex::PhysBCFunct> cphysbcz( + m_mesh.Geom(lev - 1), bcrec, bc_functor_face(2));); + + AMREX_D_TERM( + amrex::PhysBCFunct> fphysbcx( + m_mesh.Geom(lev), bcrec, bc_functor_face(0)); + , amrex::PhysBCFunct> fphysbcy( + m_mesh.Geom(lev), bcrec, bc_functor_face(1)); + , amrex::PhysBCFunct> fphysbcz( + m_mesh.Geom(lev), bcrec, bc_functor_face(2));); amrex::Array< amrex::PhysBCFunct>, AMREX_SPACEDIM> - cphysbc_arr = {AMREX_D_DECL(cphysbc, cphysbc, cphysbc)}; + cphysbc_arr = {AMREX_D_DECL(cphysbcx, cphysbcy, cphysbcz)}; amrex::Array< amrex::PhysBCFunct>, AMREX_SPACEDIM> - fphysbc_arr = {AMREX_D_DECL(fphysbc, fphysbc, fphysbc)}; + fphysbc_arr = {AMREX_D_DECL(fphysbcx, fphysbcy, fphysbcz)}; amrex::Array idx = {AMREX_D_DECL(0, 1, 2)}; const amrex::Array, AMREX_SPACEDIM> @@ -387,6 +397,8 @@ public: protected: Functor bc_functor() { return m_op(); } + Functor bc_functor_face(const int face_dir) { return m_op(face_dir); } + void check_face_mapper() { if (std::any_of( diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 030c3d2330..c368057145 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -241,6 +241,7 @@ add_test_re(vortex_dipole_wall_collision) add_test_re(burggraf_flow) add_test_re(abl_godunov_rayleigh_damping) add_test_re(rankine) +add_test_re(rankine-sym) if(NOT AMR_WIND_ENABLE_CUDA) add_test_re(ctv_godunov_plm) diff --git a/test/test_files/rankine-sym/rankine-sym.inp b/test/test_files/rankine-sym/rankine-sym.inp new file mode 100644 index 0000000000..60ca17bb27 --- /dev/null +++ b/test/test_files/rankine-sym/rankine-sym.inp @@ -0,0 +1,80 @@ +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +time.stop_time = 450.0 # vort init at -1250; domain length = 2000; to travel 4500 at 10 m/s, need 450 s +time.max_step = 100000 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +time.fixed_dt = 1.0 # Use this constant dt if > 0 +time.cfl = 0.95 # CFL factor +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +time.plot_interval = 1 # Steps between plot files +time.checkpoint_interval = -1 # Steps between checkpoint files +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +incflo.gravity = 0. 0. -9.81 # Gravitational force (3D) +incflo.density = 1.0 # Reference density +incflo.use_godunov = 1 +incflo.diffusion_type = 2 +incflo.do_initial_proj = false +incflo.initial_iterations = 0 +transport.viscosity = 1.0e-5 +transport.laminar_prandtl = 0.7 +transport.turbulent_prandtl = 0.3333 +turbulence.model = Smagorinsky +Smagorinsky_coeffs.Cs = 0.135 +incflo.physics = ABL +#ICNS.source_terms = CoriolisForcing +#CoriolisForcing.east_vector = 1.0 0.0 0.0 +#CoriolisForcing.north_vector = 0.0 1.0 0.0 +#CoriolisForcing.latitude = 90.0 +#CoriolisForcing.rotational_time_period = 125663.706143592 +incflo.velocity = 10.0 0.0 0.0 +ABL.reference_temperature = 300.0 +ABL.temperature_heights = 0.0 2000.0 +ABL.temperature_values = 300.0 300.0 +ABL.perturb_temperature = false +ABL.perturb_velocity = false +#ABL.cutoff_height = 50.0 +#ABL.perturb_ref_height = 50.0 +#ABL.Uperiods = 4.0 +#ABL.Vperiods = 4.0 +#ABL.deltaU = 1.0 +#ABL.deltaV = 1.0 +#ABL.kappa = .41 +#ABL.surface_roughness_z0 = 0.01 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 40 60 4 # Grid cells at coarsest AMRlevel +amr.max_level = 0 # Max AMR level in hierarchy +amr.blocking_factor = 4 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. -1500. 0. # Lo corner coordinates +geometry.prob_hi = 2000. 1500. 200. # Hi corner coordinates +geometry.is_periodic = 0 0 0 # Periodicity x y z (0/1) + +# Boundary conditions +xlo.type = "mass_inflow" +xlo.density = 1.0 +xlo.velocity.inflow_type = Rankine +xlo.temperature = 300.0 +xhi.type = "mass_inflow" +xhi.density = 1.0 +xhi.velocity.inflow_type = Rankine +xhi.temperature = 300.0 +ylo.type = "slip_wall" +yhi.type = "slip_wall" +zlo.type = "slip_wall" +zhi.type = "slip_wall" +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +incflo.verbose = 0 # incflo_level