m_qbmm.f90 Source File


This file depends on

sourcefile~~m_qbmm.f90~~EfferentGraph sourcefile~m_qbmm.f90 m_qbmm.f90 sourcefile~m_global_parameters.f90 m_global_parameters.f90 sourcefile~m_qbmm.f90->sourcefile~m_global_parameters.f90 sourcefile~m_variables_conversion.f90 m_variables_conversion.f90 sourcefile~m_qbmm.f90->sourcefile~m_variables_conversion.f90 sourcefile~m_mpi_proxy.f90 m_mpi_proxy.f90 sourcefile~m_qbmm.f90->sourcefile~m_mpi_proxy.f90 sourcefile~m_variables_conversion.f90->sourcefile~m_global_parameters.f90 sourcefile~m_variables_conversion.f90->sourcefile~m_mpi_proxy.f90 sourcefile~nvtx.f90 nvtx.f90 sourcefile~m_variables_conversion.f90->sourcefile~nvtx.f90 sourcefile~m_mpi_proxy.f90->sourcefile~m_global_parameters.f90

Files dependent on this one

sourcefile~~m_qbmm.f90~~AfferentGraph sourcefile~m_qbmm.f90 m_qbmm.f90 sourcefile~m_rhs.f90 m_rhs.f90 sourcefile~m_rhs.f90->sourcefile~m_qbmm.f90 sourcefile~p_main.f90 p_main.f90 sourcefile~p_main.f90->sourcefile~m_qbmm.f90 sourcefile~p_main.f90->sourcefile~m_rhs.f90 sourcefile~m_time_steppers.f90 m_time_steppers.f90 sourcefile~p_main.f90->sourcefile~m_time_steppers.f90 sourcefile~m_derived_variables.f90 m_derived_variables.f90 sourcefile~p_main.f90->sourcefile~m_derived_variables.f90 sourcefile~m_time_steppers.f90->sourcefile~m_rhs.f90 sourcefile~m_derived_variables.f90->sourcefile~m_time_steppers.f90

Contents

Source Code


Source Code

!>
!! @file m_qbmm.f90
!! @brief Contains module m_qbmm
!! @author S. Bryngelson
!! @version 1.0
!! @date MAY 28, 2020

!> @brief This module is used to compute moment inversion via qbmm
module m_qbmm

    ! Dependencies =============================================================

    use m_derived_types        !< Definitions of the derived types

    use m_global_parameters    !< Definitions of the global parameters

    use m_mpi_proxy            !< Message passing interface (MPI) module proxy

    use m_variables_conversion !< State variables type conversion procedures

    ! ==========================================================================

    implicit none

    private; public :: s_initialize_qbmm_module, s_mom_inv, s_coeff

    real(kind(0d0)), parameter :: verysmall = 1.d-12
    real(kind(0d0)), allocatable, dimension(:, :, :, :, :)  :: momrhs
    integer :: nterms  !< Number of rhs terms in each moment transport equations
    type(int_bounds_info) :: is1, is2, is3

    integer :: momxb, momxe
    integer :: contxb, contxe
    integer :: bubxb, bubxe
    integer :: advxb, advxe
    real(kind(0d0)),allocatable, dimension(:) :: gammas, pi_infs 
    integer ,allocatable, dimension(:) :: bubrs
    integer, allocatable, dimension(:, :) :: bubmoms

!$acc declare create(momrhs, nterms, is1, is2, is3)
!$acc declare create(momxb, momxe, bubxb, bubxe, contxb, contxe, advxb, advxe, gammas, pi_infs, bubrs, bubmoms)


contains

    subroutine s_initialize_qbmm_module()

        integer :: i1, i2, q, i, j
        
        if (bubble_model == 2) then
            ! Keller-Miksis without viscosity/surface tension
            nterms = 12
        else if (bubble_model == 3) then
            ! Rayleigh-Plesset with viscosity/surface tension
            nterms = 6
        end if

        !$acc update device(nterms)

        allocate (momrhs(3, 0:2, 0:2, nterms, nb))
        momrhs = 0d0

        ! Assigns the required RHS moments for moment transport equations
        ! The rhs%(:,3) is only to be used for R0 quadrature, not for computing X/Y indices
        do q = 1, nb
            do i1 = 0, 2; do i2 = 0, 2
                    if ((i1 + i2) <= 2) then
                        if (bubble_model == 3) then
                            momrhs(1, i1, i2,  1, q) = -1.d0 + i1
                            momrhs(2, i1, i2,  1, q) = -1.d0 + i2
                            momrhs(3, i1, i2,  1, q) = 0d0

                            momrhs(1, i1, i2,  2, q) = -1.d0 + i1
                            momrhs(2, i1, i2,  2, q) = 1.d0 + i2
                            momrhs(3, i1, i2,  2, q) = 0d0

                            momrhs(1, i1, i2,  3, q) = -1.d0 + i1 - 3.d0*gam
                            momrhs(2, i1, i2,  3, q) = -1.d0 + i2
                            momrhs(3, i1, i2,  3, q) = 3.d0*gam

                            momrhs(1, i1, i2,  4, q) = -1.d0 + i1
                            momrhs(2, i1, i2,  4, q) = 1.d0 + i2
                            momrhs(3, i1, i2,  4, q) = 0d0

                            if (Re_inv .ne. dflt_real) then
                                ! add viscosity
                                momrhs(1, i1, i2,  5, q) = -2.d0 + i1
                                momrhs(2, i1, i2,  5, q) = i2
                                momrhs(3, i1, i2,  5, q) = 0d0
                            end if

                            if (Web .ne. dflt_real) then
                                ! add surface tension
                                momrhs(1, i1, i2,  6, q) = -2.d0 + i1
                                momrhs(2, i1, i2,  6, q) = -1.d0 + i2
                                momrhs(3, i1, i2,  6, q) = 0d0
                            end if
                        else if (bubble_model == 2) then
                            ! KM with approximation of 1/(1-V/C) = 1+V/C
                            momrhs(1, i1, i2,  1, q) = -1d0 + i1
                            momrhs(2, i1, i2,  1, q) = 1d0 + i2
                            momrhs(3, i1, i2,  1, q) = 0d0

                            momrhs(1, i1, i2,  2, q) = -1d0 + i1
                            momrhs(2, i1, i2,  2, q) = 2d0 + i2
                            momrhs(3, i1, i2,  2, q) = 0d0

                            momrhs(1, i1, i2,  3, q) = -1d0 + i1
                            momrhs(2, i1, i2,  3, q) = 3d0 + i2
                            momrhs(3, i1, i2,  3, q) = 0d0

                            momrhs(1, i1, i2,  4, q) = -1d0 + i1
                            momrhs(2, i1, i2,  4, q) = -1d0 + i2
                            momrhs(3, i1, i2,  4, q) = 0d0

                            momrhs(1, i1, i2,  5, q) = -1d0 + i1
                            momrhs(2, i1, i2,  5, q) = i2
                            momrhs(3, i1, i2,  5, q) = 0d0

                            momrhs(1, i1, i2,  6, q) = -1d0 + i1
                            momrhs(2, i1, i2,  6, q) = 1d0 + i2
                            momrhs(3, i1, i2,  6, q) = 0d0

                            momrhs(1, i1, i2,  7, q) = -1d0 + i1 - 3d0*gam
                            momrhs(2, i1, i2,  7, q) = -1d0 + i2
                            momrhs(3, i1, i2,  7, q) = 3d0*gam

                            momrhs(1, i1, i2,  8, q) = -1d0 + i1 - 3d0*gam
                            momrhs(2, i1, i2,  8, q) = i2
                            momrhs(3, i1, i2,  8, q) = 3d0*gam

                            momrhs(1, i1, i2,  9, q) = -1d0 + i1 - 3d0*gam
                            momrhs(2, i1, i2,  9, q) = 1d0 + i2
                            momrhs(3, i1, i2,  9, q) = 3d0*gam

                            momrhs(1, i1, i2,  10, q) = -1d0 + i1 - 3d0*gam
                            momrhs(2, i1, i2,  10, q) = i2
                            momrhs(3, i1, i2,  10, q) = 3d0*gam

                            momrhs(1, i1, i2,  11, q) = -1d0 + i1 - 3d0*gam
                            momrhs(2, i1, i2,  11, q) = 1d0 + i2
                            momrhs(3, i1, i2,  11, q) = 3d0*gam

                            momrhs(1, i1, i2,  12, q) = -1d0 + i1
                            momrhs(2, i1, i2,  12, q) = 1d0 + i2
                            momrhs(3, i1, i2,  12, q) = 0d0
                        end if
                    end if
                end do; end do
        end do

        !$acc update device(momrhs)

        momxb = mom_idx%beg; momxe = mom_idx%end
        bubxb = bub_idx%beg; bubxe = bub_idx%end
        advxb = adv_idx%beg; advxe = adv_idx%end
        contxb = cont_idx%beg; contxe = cont_idx%end
!$acc update device(momxb, momxe, bubxb, bubxe, advxb, advxe, contxb, contxe)

        allocate(gammas(1:num_fluids))
        allocate(pi_infs(1:num_fluids))

        allocate(bubrs(1:nb))

        allocate(bubmoms(1:nb, 1:nmom))

        do i = 1, num_fluids
            gammas(i) = fluid_pp(i)%gamma
            pi_infs(i) = fluid_pp(i)%pi_inf
        end do
!$acc update device(gammas, pi_infs)

        do i = 1, nb
            bubrs(i) = bub_idx%rs(i)
        end do
!$acc update device(bubrs)

        do j = 1, nmom
            do i = 1, nb
                bubmoms(i,j) = bub_idx%moms(i,j)
            end do
        end do
!$acc update device(bubmoms)


    end subroutine s_initialize_qbmm_module

    subroutine s_coeff(pres, rho, c, coeffs)
!$acc routine seq
        real(kind(0.d0)), intent(IN) :: pres, rho, c
        real(kind(0.d0)), dimension(:, 0:, 0:), intent(OUT) :: coeffs
        integer :: i1, i2

        coeffs = 0d0

        do i1 = 0, 2; do i2 = 0, 2
                if ((i1 + i2) <= 2) then
                    if (bubble_model == 3) then
                        ! RPE
                        coeffs(1, i1, i2) = -1d0*i2*pres/rho
                        coeffs(2, i1, i2) = -3d0*i2/2d0
                        coeffs(3, i1, i2) = i2/rho
                        coeffs(4, i1, i2) = i1
                        if (Re_inv /= dflt_real) coeffs(5, i1, i2) = -4d0*i2*Re_inv/rho
                        if (Web /= dflt_real) coeffs(6, i1, i2) = -2d0*i2/Web/rho
                    else if (bubble_model == 2) then
                        ! KM with approximation of 1/(1-V/C) = 1+V/C
                        coeffs(1, i1, i2) = -3d0*i2/2d0
                        coeffs(2, i1, i2) = -i2/c
                        coeffs(3, i1, i2) = i2/(2d0*c*c)
                        coeffs(4, i1, i2) = -i2*pres/rho
                        coeffs(5, i1, i2) = -2d0*i2*pres/(c*rho)
                        coeffs(6, i1, i2) = -i2*pres/(c*c*rho)
                        coeffs(7, i1, i2) = i2/rho
                        coeffs(8, i1, i2) = 2d0*i2/(c*rho)
                        coeffs(9, i1, i2) = i2/(c*c*rho)
                        coeffs(10, i1, i2) = -3d0*i2*gam/(c*rho)
                        coeffs(11, i1, i2) = -3d0*i2*gam/(c*c*rho)
                        coeffs(12, i1, i2) = i1
                    end if
                end if
            end do; end do

    end subroutine s_coeff

    subroutine s_mom_inv(q_prim_vf, momsp, moms3d, ix, iy, iz)

        type(scalar_field), dimension(:), intent(IN) :: q_prim_vf
        type(scalar_field), dimension(:), intent(INOUT) :: momsp
        type(scalar_field), dimension(0:, 0:, :), intent(INOUT) :: moms3d
        type(int_bounds_info), intent(IN) :: ix, iy, iz

        real(kind(0d0)), dimension(nmom) :: moms
        real(kind(0d0)), dimension(nb) :: Rvec
        real(kind(0d0)), dimension(nnode, nb) :: wght, abscX, abscY
        real(kind(0d0)), dimension(nterms, 0:2, 0:2) :: mom3d_terms, coeff
        real(kind(0d0)) :: pres, rho, nbub, c, alf
        real(kind(0d0)) :: n_tait, B_tait
        real(kind(0d0)), dimension(3) :: momrhs_vec

        integer :: j, k, l, q, r, s !< Loop variables
        integer :: id1, id2, id3
        integer :: i1, i2

        is1 = ix; is2 = iy; is3 = iz

        !$acc update device(is1, is2, is3)


!$acc parallel loop collapse(3) gang vector default(present) private(moms, Rvec, wght, abscX, abscY, mom3d_terms, coeff, momrhs_vec)
        do id3 = is3%beg, is3%end 
            do id2 = is2%beg, is2%end 
                do id1 = is1%beg, is1%end

                alf = q_prim_vf(alf_idx)%sf(id1, id2, id3)
                pres = q_prim_vf(E_idx)%sf(id1, id2, id3)
                rho = q_prim_vf(contxb)%sf(id1, id2, id3)
                if (bubble_model == 2) then
                    n_tait = gammas(1)
                    n_tait = 1.d0/n_tait + 1.d0 !make this the usual little 'gamma'
                    B_tait = pi_infs(1)
                    c = n_tait*(pres + B_tait)/(rho*(1.d0 - alf))
                    if (c > 0.d0) then
                        c = DSQRT(c)
                    else
                        c = sgm_eps
                    end if
                end if

                call s_coeff(pres, rho, c, coeff)



                ! SHB: Manually adjusted pressure here for no-coupling case
                ! pres = 1d0/0.3d0

                if (alf > small_alf) then

                    !$acc loop seq
                    do q = 1, nb
                        Rvec(q) = q_prim_vf(bubrs(q))%sf(id1, id2, id3)
                    end do

                    call s_comp_n_from_prim(alf, Rvec, nbub)

                    !$acc loop seq
                    do q = 1, nb
                        !$acc loop seq
                        do r = 1, nmom
                            moms(r) = q_prim_vf(bubmoms(q, r))%sf(id1, id2, id3)
                        end do

                        ! IF(id1==0) THEN
                        !     PRINT*, 'pres: ', pres
                        !     PRINT*, 'nb : ', nbub
                        !     PRINT*, 'alf: ', alf
                        !     DO s = 1,nmom
                        !         PRINT*, 'mom: ', moms(s)
                        !     END DO
                        ! END IF

                        call s_chyqmom(moms, wght(:, q), abscX(:, q), abscY(:, q))



                        !$acc loop seq
                        do j = 1, nterms
                            !$acc loop seq
                            do i2 = 0, 2 
                                !$acc loop seq
                                do i1 = 0, 2
                                    if ((i1 + i2) <= 2) then

                                        mom3d_terms(j, i1, i2) = coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2,  j, q)) &
                                                                 *f_quad2D(abscX(:, q), abscY(:, q), wght(:, q), momrhs(:, i1, i2, j, q))
                                    end if
                                end do 
                            end do
                        end do

                        !$acc loop seq
                        do i1 = 0, 2
                            !$acc loop seq
                             do i2 = 0, 2
                                if ((i1 + i2) <= 2) then
                                    moms3d(i1, i2, q)%sf(id1, id2, id3) = nbub*sum(mom3d_terms(:, i1, i2))
                                    ! IF (moms3d(i1,i2,q)%sf(id1,id2,id3) .NE. moms3d(i1,i2,q)%sf(id1,id2,id3)) THEN
                                    !     PRINT*, 'nan in mom3d', i1,i2,id1
                                    !     PRINT*, 'nbu: ', nbub
                                    !     PRINT*, 'alf: ', alf
                                    !     PRINT*, 'moms: ', moms(:)
                                    !     CALL s_mpi_abort()
                                    ! END IF
                                end if
                            end do
                        end do
                    end do

                    momsp(1)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght, 3d0, 0d0, 0d0)
                    momsp(2)%sf(id1, id2, id3) = 4.d0*pi*nbub*f_quad(abscX, abscY, wght, 2d0, 1d0, 0d0)
                    momsp(3)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght, 3d0, 2d0, 0d0)
                    if (abs(gam - 1.d0) <= 1.d-4) then
                        ! Gam \approx 1, don't risk imaginary quadrature
                        momsp(4)%sf(id1, id2, id3) = 1.d0
                    else
                        momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght, 3d0*(1d0 - gam), 0d0, 3d0*gam)
                    end if

                    !!$acc loop seq
                    !do i1 = 1, 4
                       ! if (momsp(i1)%sf(id1, id2, id3) /= momsp(i1)%sf(id1, id2, id3)) then
                       !     print *, 'NaN in sp moment', i1, 'location', id1, id2, id3
                       !     print *, 'Rs', Rvec(:)
                       !     print *, 'alpha', alf
                       !     print *, 'nbub', nbub
                       !     print *, 'abscX', abscX(:, :)
                       !     print *, 'abscY', abscY(:, :)
                       !     print *, 'wght', wght(:, :)
                        !    call s_mpi_abort()
                        !end if
                    !end do
                else
                    !$acc loop seq
                    do q = 1, nb
                        !$acc loop seq
                        do i1 = 0, 2
                            !$acc loop seq 
                            do i2 = 0, 2
                                moms3d(i1, i2, q)%sf(id1, id2, id3) = 0d0
                            end do 
                        end do
                    end do

                    momsp(1)%sf(id1, id2, id3) = 0d0
                    momsp(2)%sf(id1, id2, id3) = 0d0
                    momsp(3)%sf(id1, id2, id3) = 0d0
                    momsp(4)%sf(id1, id2, id3) = 0d0

                end if

            end do
         end do
      end do

    end subroutine s_mom_inv

    subroutine s_chyqmom(momin, wght, abscX, abscY)
!$acc routine seq
        real(kind(0d0)), dimension(:), intent(INOUT) :: wght, abscX, abscY
        real(kind(0d0)), dimension(:), intent(IN) :: momin

        real(kind(0d0)), dimension(0:nmom, 0:nmom) :: moms
        real(kind(0d0)), dimension(3) :: M1, M3
        real(kind(0d0)), dimension(2) :: myrho, myrho3, up, up3, Vf
        real(kind(0d0)) :: bu, bv, d20, d11, d02, c20, c11, c02
        real(kind(0d0)) :: mu2avg, mu2, vp21, vp22, rho21, rho22

        moms(0, 0) = momin(1)
        moms(1, 0) = momin(2)
        moms(0, 1) = momin(3)
        moms(2, 0) = momin(4)
        moms(1, 1) = momin(5)
        moms(0, 2) = momin(6)

        bu = moms(1, 0)/moms(0, 0)
        bv = moms(0, 1)/moms(0, 0)
        d20 = moms(2, 0)/moms(0, 0)
        d11 = moms(1, 1)/moms(0, 0)
        d02 = moms(0, 2)/moms(0, 0)
        c20 = d20 - bu**2d0; 
        c11 = d11 - bu*bv; 
        c02 = d02 - bv**2d0; 
        M1 = (/1d0, 0d0, c20/)
        call s_hyqmom(myrho, up, M1)
        Vf = c11*up/c20

        mu2avg = c02 - sum(myrho(:)*(Vf(:)**2d0))
        mu2avg = maxval((/mu2avg, 0d0/))
        mu2 = mu2avg
        M3 = (/1d0, 0d0, mu2/)
        call s_hyqmom(myrho3, up3, M3)

        vp21 = up3(1)
        vp22 = up3(2)
        rho21 = myrho3(1)
        rho22 = myrho3(2)

        wght(1) = myrho(1)*rho21
        wght(2) = myrho(1)*rho22
        wght(3) = myrho(2)*rho21
        wght(4) = myrho(2)*rho22
        wght = moms(0, 0)*wght

        abscX(1) = up(1)
        abscX(2) = up(1)
        abscX(3) = up(2)
        abscX(4) = up(2)
        abscX = bu + abscX

        abscY(1) = Vf(1) + vp21
        abscY(2) = Vf(1) + vp22
        abscY(3) = Vf(2) + vp21
        abscY(4) = Vf(2) + vp22
        abscY = bv + abscY

    end subroutine s_chyqmom

    subroutine s_hyqmom(frho, fup, fmom)
    !$acc routine seq
        real(kind(0d0)), dimension(2), intent(INOUT) :: frho, fup
        real(kind(0d0)), dimension(3), intent(IN) :: fmom
        real(kind(0d0)) :: bu, d2, c2

        bu = fmom(2)/fmom(1)
        d2 = fmom(3)/fmom(1)
        c2 = d2 - bu**2d0
        frho(1) = fmom(1)/2d0; 
        frho(2) = fmom(1)/2d0; 
        c2 = maxval((/c2, verysmall/))
        fup(1) = bu - DSQRT(c2)
        fup(2) = bu + DSQRT(c2)

    end subroutine s_hyqmom

    function f_quad(abscX, abscY, wght, q, r, s)
    !$acc routine seq
        real(kind(0.d0)), dimension(:, :), intent(IN) :: abscX, abscY, wght
        real(kind(0.d0)), intent(IN) :: q, r, s
        real(kind(0.d0)) :: f_quad_RV, f_quad
        integer :: i

        f_quad = 0d0
        do i = 1, nb
            f_quad_RV = sum(wght(:, i)*(abscX(:, i)**q)*(abscY(:, i)**r))
            f_quad = f_quad + weight(i)*(R0(i)**s)*f_quad_RV
        end do

    end function f_quad

    function f_quad2D(abscX, abscY, wght, pow)
    !$acc routine seq
        real(kind(0.d0)), dimension(:), intent(IN) :: abscX, abscY, wght
        real(kind(0.d0)), dimension(:), intent(IN) :: pow
        real(kind(0.d0)) :: f_quad2D

        f_quad2D = sum(wght(:)*(abscX(:)**pow(1))*(abscY(:)**pow(2)))
    end function f_quad2D

end module m_qbmm