@@ -652,6 +652,16 @@ struct InitDataOp<W2AWaves>
652
652
const bool has_beach = wdata.has_beach && multiphase_mode;
653
653
const bool init_wave_field = wdata.init_wave_field || !multiphase_mode;
654
654
655
+ amrex::MultiFab phi_tmp_fab (
656
+ velocity (level).boxArray (), velocity (level).DistributionMap (), 1 ,
657
+ 3 );
658
+ amrex::MultiFab vel_tmp_fab (
659
+ velocity (level).boxArray (), velocity (level).DistributionMap (),
660
+ AMREX_SPACEDIM, 3 );
661
+
662
+ const auto & phi_tmp = phi_tmp_fab.arrays ();
663
+ const auto & vel_tmp = vel_tmp_fab.arrays ();
664
+
655
665
amrex::ParallelFor (
656
666
velocity (level), amrex::IntVect (3 ),
657
667
[=] AMREX_GPU_DEVICE (int nbx, int i, int j, int k) noexcept {
@@ -673,17 +683,13 @@ struct InitDataOp<W2AWaves>
673
683
x, problo[0 ], gen_length, probhi[0 ], beach_length, wave_sol,
674
684
bulk, outlet);
675
685
676
- const amrex::Real phi = local_profile[3 ] - z;
677
- const amrex::Real cell_length_2D =
678
- std::sqrt (dx[0 ] * dx[0 ] + dx[2 ] * dx[2 ]);
679
- if (phi + cell_length_2D >= 0 ) {
680
- vel[nbx](i, j, k, 0 ) = local_profile[0 ];
681
- vel[nbx](i, j, k, 1 ) = local_profile[1 ];
682
- vel[nbx](i, j, k, 2 ) = local_profile[2 ];
683
- }
686
+ phi_tmp[nbx](i, j, k) = local_profile[3 ] - z;
687
+ vel_tmp[nbx](i, j, k, 0 ) = local_profile[0 ];
688
+ vel_tmp[nbx](i, j, k, 1 ) = local_profile[1 ];
689
+ vel_tmp[nbx](i, j, k, 2 ) = local_profile[2 ];
684
690
685
691
if (multiphase_mode) {
686
- phi_arrs[nbx](i, j, k) = phi ;
692
+ phi_arrs[nbx](i, j, k) = phi_tmp[nbx](i, j, k) ;
687
693
}
688
694
689
695
// Default w2a values matter for where no updates happen
@@ -693,6 +699,39 @@ struct InitDataOp<W2AWaves>
693
699
w2a_vel[nbx](i, j, k, 2 ) = quiescent[0 ];
694
700
});
695
701
amrex::Gpu::streamSynchronize ();
702
+
703
+ amrex::ParallelFor (
704
+ velocity (level), amrex::IntVect (2 ),
705
+ [=] AMREX_GPU_DEVICE (int nbx, int i, int j, int k) noexcept {
706
+ const amrex::Real eps = 2 . * std::cbrt (dx[0 ] * dx[1 ] * dx[2 ]);
707
+ const amrex::Real vof_local =
708
+ multiphase::levelset_to_vof (i, j, k, eps, phi_tmp[nbx]);
709
+
710
+ if (vof_local > 1 . - constants::TIGHT_TOL) {
711
+ // Entire cell is liquid
712
+ vel[nbx](i, j, k, 0 ) = vel_tmp[nbx](i, j, k, 0 );
713
+ vel[nbx](i, j, k, 1 ) = vel_tmp[nbx](i, j, k, 1 );
714
+ vel[nbx](i, j, k, 2 ) = vel_tmp[nbx](i, j, k, 2 );
715
+ } else if (vof_local > 1e-3 ) {
716
+ // Velocity of liquid becomes velocity of entire cell
717
+ // Interpolate using cell-centered values to liquid centroid
718
+ // Consider only z-direction to find centroid
719
+ const amrex::Real z_cell = problo[2 ] + (k + 0.5 ) * dx[2 ];
720
+ const amrex::Real z_cell_below = z_cell - dx[2 ];
721
+ const amrex::Real z_cell_bottom = z_cell - 0.5 * dx[2 ];
722
+ const amrex::Real z_liq_center =
723
+ z_cell_bottom + 0.5 * vof_local * dx[2 ];
724
+ for (int n = 0 ; n < AMREX_SPACEDIM; ++n) {
725
+ vel[nbx](i, j, k, n) =
726
+ vel_tmp[nbx](i, j, k - 1 , n) +
727
+ (vel_tmp[nbx](i, j, k, n) -
728
+ vel_tmp[nbx](i, j, k - 1 , n)) *
729
+ ((z_liq_center - z_cell_below) /
730
+ (z_cell - z_cell_below + constants::EPS));
731
+ }
732
+ }
733
+ });
734
+ amrex::Gpu::streamSynchronize ();
696
735
#else
697
736
amrex::ignore_unused (data, level, geom, multiphase_mode);
698
737
#endif
0 commit comments