MODULE Generic_GetRHS ! ---- Computes the RHS as the derivative of the flux vector ! ---- as the derivate of the x (1) and y (2) and z (3) directions and ! ---- saves them seperately in rhs(nvars,direction,:,:,:) ! ! ---- The locations where WENO is used are stored in the feild ! ---- 'dcflag' INTERFACE GetRHS MODULE PROCEDURE OneDGetRHS MODULE PROCEDURE TwoDGetRHS MODULE PROCEDURE ThreeDGetRHS END INTERFACE CONTAINS SUBROUTINE OneDGetRHS(rk, ux,vx,rhs,fxi,dcflag,ifilter) ! ---- Shared Variables USE mesh USE array_bounds USE method_parms use cles_interfaces ! ---- Shared Procedures USE Generic_GetFlux USE Generic_AcousticBC USE Generic_CellWallFlux USE Generic_Transport USE Generic_ViscousAtCellWalls USE Generic_FDFluxInterps USE Generic_FDInterpFlux USE Generic_Source IMPLICIT NONE include 'cles.i' INTEGER, INTENT(IN) :: rk, ifilter DOUBLE PRECISION, INTENT(IN) :: ux(ncomps,ixlo:ixhi) DOUBLE PRECISION, INTENT(OUT) :: vx(nvars,ixlo:ixhi) DOUBLE PRECISION, INTENT(OUT) :: rhs(nvars,1:nx) DOUBLE PRECISION, INTENT(OUT) :: fxi(ncomps,ixlo:ixhi,1) INTEGER, INTENT(INOUT) :: dcflag(1:nx+1,1) DOUBLE PRECISION, ALLOCATABLE :: fx(:,:) INTEGER :: direction INTEGER :: iret INTEGER :: i ALLOCATE ( fx(nvars,ixlo:ixhi) , stat = iret ) if ( iret .ne. 0 ) then call cleslog_error(CLESLOG_ERROR_ALLOCATE, & 'OneDGetRHS/fx', iret) endif ! ---- initialize flux interpolates and mask fxi = 0.0D0 rhs = 0.0D0 ! ---- Convert conserved variables to Primative vx(1,:) = ux(1,:) do i=2,nvars vx(i,:) = ux(i,:)/ux(1,:) enddo call cles_eqstate(ux, ncomps, vx, nvars, mx, CLES_FALSE) ! ---- compute the transport terms IF (useViscous.eq.CLES_TRUE) CALL GetTransport(ux, vx) ! ---- Initialize dcflag if ( rk .eq. 1 ) then DO direction = 1,1,1 call cles_dcflag(ux,vx,dcflag,ncomps,nvars, & ixlo,ixhi, nx, dx, direction, enoOrder) enddo endif ! ---- Add body force source term IF(useSource.eq.CLES_TRUE) CALL AddSource(ux,vx,rhs) ! ---- compute the flux interpolates in ! ---- the x (1) direction DO direction = 1,1,1 ! ---- compute the flux vector for this direction CALL GetFlux(ux,vx,fx,direction) ! ---- compute the interpolated fluxes on the cell walls CALL CellWallFlux(ux,vx,fx,fxi,dcflag,direction,ifilter) enddo ! ---- apply the characteristic boundary conditions CALL AcousticBC(fxi, ux, vx, rhs, dcflag) ! the RHS must be computed outside of the previouse loop to ! give a chance to the characteristic boundary conditions to ! perform the decomposition and cancel incoming contributions ! from possible source terms do direction = 1, 1, 1 IF (useViscous.eq.CLES_TRUE) THEN ! ---- Modify the flux at the cell wall to include ! ---- the viscous terms. CALL ViscousFluxModification(fxi, ux, vx, direction) END IF ! ---- Compute the flux derivatives from the interpolates ! ---- note this is only done for the interior (not Ghost) ! ---- cells. CALL AccumulateFluxDiffs(rhs, fxi, direction) ! ---- finish the 'direction' loop END DO DEALLOCATE(fx, stat=iret ) if ( iret .ne. 0 ) then call cleslog_error(CLESLOG_ERROR_DEALLOCATE, & 'OneDGetRHS/fx', iret) endif END SUBROUTINE OneDGetRHS SUBROUTINE TwoDGetRHS(rk, ux,vx,rhs,fxi,dcflag, ifilter) ! ---- Shared Variables USE mesh USE array_bounds USE method_parms use cles_interfaces ! ---- Shared Procedures USE Generic_GetFlux USE Generic_AcousticBC USE Generic_CellWallFlux USE Generic_Transport USE Generic_ViscousAtCellWalls USE Generic_FDFluxInterps USE Generic_FDInterpFlux USE Generic_Source IMPLICIT NONE include 'cles.i' INTEGER, INTENT(IN) :: rk, ifilter DOUBLE PRECISION, INTENT(IN) :: ux(ncomps,ixlo:ixhi,iylo:iyhi) DOUBLE PRECISION, INTENT(OUT) :: vx(nvars,ixlo:ixhi,iylo:iyhi) DOUBLE PRECISION, INTENT(OUT) :: rhs(nvars,1:nx,1:ny) DOUBLE PRECISION, INTENT(OUT) :: fxi(ncomps,ixlo:ixhi,iylo:iyhi,2) INTEGER, INTENT(INOUT) :: dcflag(1:nx+1,1:ny+1,2) DOUBLE PRECISION, ALLOCATABLE :: fx(:,:,:) INTEGER :: iret INTEGER :: direction INTEGER :: i,n ALLOCATE ( fx(nvars,ixlo:ixhi,iylo:iyhi), stat=iret ) if ( iret .ne. 0 ) then call cleslog_error(CLESLOG_ERROR_ALLOCATE, & 'TwoDGetRHS/fx', iret) endif ! ---- initialize flux interpolates and mask fxi = 0.0D0 rhs = 0.0D0 ! ---- Convert conserved variables to Primative vx(1,:,:) = ux(1,:,:) do i=2,nvars vx(i,:,:) = ux(i,:,:)/ux(1,:,:) enddo n = mx*my call cles_eqstate(ux, ncomps, vx, nvars, n, CLES_FALSE) ! --- compute the transport terms IF (useViscous.eq.CLES_TRUE) CALL GetTransport(ux, vx) ! ---- Initialize dcflag if ( rk .eq. 1 ) then DO direction = 1,2,1 call cles_dcflag(ux,vx,dcflag,ncomps,nvars, & ixlo,ixhi,iylo,iyhi, nx, ny, dx, dy, & direction, enoOrder) enddo endif ! ---- Add body force source term IF(useSource.eq.CLES_TRUE) CALL AddSource(ux,vx,rhs) ! ---- compute the flux interpolates in ! ---- the x (1) direction, and then in the y (2) direction DO direction = 1,2,1 ! ---- compute the inviscid flux vector for this direction CALL GetFlux(ux,vx,fx,direction) ! ---- compute the interpolated fluxes on the cell walls CALL CellWallFlux(ux,vx,fx,fxi,dcflag,direction,ifilter) enddo ! ---- apply the characteristic boundary conditions CALL AcousticBC(fxi, ux, vx, rhs, dcflag) ! the RHS must be computed outside of the previouse loop to ! give a chance to the characteristic boundary conditions to ! perform the decomposition and cancel incoming contributions ! from possible source terms do direction = 1, 2, 1 IF (useViscous.eq.CLES_TRUE) THEN ! ---- Modify the flux at the cell wall to include ! ---- the viscous terms. CALL ViscousFluxModification(fxi, ux, vx, direction) END IF ! ---- Compute the flux derivatives from the interpolates ! ---- note this is only done for the interior (not Ghost) ! ---- cells. CALL AccumulateFluxDiffs(rhs, fxi, direction) END DO DEALLOCATE ( fx , stat=iret ) if ( iret .ne. 0 ) then call cleslog_error(CLESLOG_ERROR_DEALLOCATE, & 'TwoDGetRHS/fx', iret) endif END SUBROUTINE TwoDGetRHS SUBROUTINE ThreeDGetRHS(rk, ux,vx,rhs,fxi,dcflag, ifilter) ! ---- Shared Variables USE mesh USE array_bounds USE method_parms use cles_interfaces ! ---- Shared Procedures USE Generic_GetFlux USE Generic_AcousticBC USE Generic_CellWallFlux USE Generic_Transport USE Generic_ViscousAtCellWalls USE Generic_FDFluxInterps USE Generic_FDInterpFlux USE Generic_Source IMPLICIT NONE include 'cles.i' INTEGER, INTENT(IN) :: rk, ifilter DOUBLE PRECISION, INTENT(INOUT) :: ux(ncomps,ixlo:ixhi,iylo:iyhi,izlo:izhi) DOUBLE PRECISION, INTENT(OUT) :: vx(nvars,ixlo:ixhi,iylo:iyhi,izlo:izhi) DOUBLE PRECISION, INTENT(OUT) :: rhs(nvars,1:nx,1:ny,1:nz) DOUBLE PRECISION, INTENT(OUT) :: fxi(ncomps,ixlo:ixhi,iylo:iyhi,izlo:izhi,3) INTEGER, INTENT(INOUT) :: dcflag(1:nx+1,1:ny+1,1:nz+1,3) DOUBLE PRECISION, ALLOCATABLE :: fx(:,:,:,:) INTEGER :: iret INTEGER :: direction INTEGER :: i,n call cleslog_log_enter('ThreeDGetRHS') ALLOCATE ( fx(nvars,ixlo:ixhi,iylo:iyhi,izlo:izhi), stat=iret ) if ( iret .ne. 0 ) then call cleslog_error(CLESLOG_ERROR_ALLOCATE, & 'ThreeDGetRHS/fx', iret) endif ! ---- initialize flux interpolates and mask fxi(:,:,:,:,:) = 0.0D0 rhs(:,:,:,:) = 0.0D0 ! ---- Convert conserved variables to primitive vx(1,:,:,:) = ux(1,:,:,:) do i=2,nvars vx(i,:,:,:) = ux(i,:,:,:)/ux(1,:,:,:) enddo ! ---- set up viscous terms if needed (only temperature is required) ! ---- we assume that the viscosity does not depend explicitly on the ! ---- pressure. Because it is not defined at this point. We determine ! ---- it after sgs terms are computed so the actual temperature and ! ---- pressure contain the effect of the sgs kinetic energy IF (useViscous.eq.CLES_TRUE) CALL GetTransport(ux, vx) ! ---- Computes the model terms, and makes the ! ---- SGS fix to the pressure ! ---- also stores the scalar variance in ! ---- the extended vector of state if (useLES.eq.CLES_TRUE) then call InitializeLES(ux,vx) ! need to fix the values of sgskin on the ghost cells. ! this is required for consistency since the users have ! no control over what will live there. Only the LES module ! is capable of determining the state here. call FixSgsBoundaries(ux, vx) endif ! ---- now the primatives have the sgs correction n = mx*my*mz ! compute the pressure and temperature from updated sgske call cles_eqstate(ux, ncomps, vx, nvars, n, useLES) ! ---- Initialize dcflag if ( rk .eq. 1 ) then DO direction = 1,3,1 call cles_dcflag(ux,vx,dcflag,ncomps,nvars, & ixlo,ixhi,iylo,iyhi,izlo,izhi,nx,ny,nz, & dx,dy,dz,direction,enoOrder) enddo endif ! ---- Add body force source term IF(useSource.eq.CLES_TRUE) CALL AddSource(ux,vx,rhs) ! ---- compute the flux interpolates in ! ---- the x (1) direction, the y (2) direction, the z (3) direction DO direction = 1,3,1 ! ---- compute the inviscid flux vector for this direction CALL GetFlux(ux,vx,fx,direction) ! ---- compute the interpolated fluxes on the cell walls CALL CellWallFlux(ux,vx,fx,fxi,dcflag,direction,ifilter) enddo ! ---- apply the characteristic boundary conditions CALL AcousticBC(fxi, ux, vx, rhs, dcflag) ! the RHS must be computed outside of the previouse loop to ! give a chance to the characteristic boundary conditions to ! perform the decomposition and cancel incoming contributions ! from possible source terms DO direction = 1,3,1 if (useViscous.eq.CLES_TRUE) THEN ! ---- Modify the flux at the cell wall to include ! ---- the viscous terms. CALL ViscousFluxModification(fxi, ux, vx, direction) endif ! ---- modify the flux at the cell walls to account for viscousity ! ---- the subgrid controbution to the fluxes IF (useLES.eq.CLES_TRUE) CALL AddSgsFlux(fxi,ux,vx,direction) ! ---- Compute the flux derivatives from the interpolates ! ---- note this is only done for the interior (not Ghost) ! ---- cells. CALL AccumulateFluxDiffs(rhs, fxi, direction) END DO DEALLOCATE ( fx ,stat=iret ) if ( iret .ne. 0 ) then call cleslog_error(CLESLOG_ERROR_DEALLOCATE, & 'ThreeDGetRHS/fx', iret) endif call cleslog_log_exit('ThreeDGetRHS') END SUBROUTINE ThreeDGetRHS SUBROUTINE FixSgsBoundaries(ux, vx) USE mesh USE array_bounds USE method_parms implicit none include 'cles.i' DOUBLE PRECISION, INTENT(INOUT) :: ux(ncomps,ixlo:ixhi,iylo:iyhi,izlo:izhi) DOUBLE PRECISION, INTENT(INOUT) :: vx(nvars,ixlo:ixhi,iylo:iyhi,izlo:izhi) INTEGER :: i,j,k if ( useLES .eq. CLES_FALSE ) return if ( bc_ixlow .ne. CLES_PATCH_CORE ) then do k=1,nz do j=1,ny do i=ixlo+1,1-bc_ixlow ! retreive original pressure call cles_eqstate(ux(:,i,j,k), ncomps, vx(:,i,j,k), & nvars, 1, CLES_FALSE) ! add sgs term to total energy call cles_inveqst(ux(:,i,j,k),ncomps,vx(:,i,j,k), & nvars,1,useLES) enddo enddo enddo endif if ( bc_ixup .ne. CLES_PATCH_CORE ) then do k=1,nz do j=1,ny do i=nx+bc_ixup,ixhi-1 ! retreive original pressure call cles_eqstate(ux(:,i,j,k), ncomps, vx(:,i,j,k), & nvars, 1, CLES_FALSE) ! add sgs term to total energy call cles_inveqst(ux(:,i,j,k),ncomps,vx(:,i,j,k), & nvars,1,useLES) enddo enddo enddo endif if ( bc_iylow .ne. CLES_PATCH_CORE ) then do k=1,nz do j=iylo+1,1-bc_iylow do i=1,nx ! retreive original pressure call cles_eqstate(ux(:,i,j,k), ncomps, vx(:,i,j,k), & nvars, 1, CLES_FALSE) ! add sgs term to total energy call cles_inveqst(ux(:,i,j,k),ncomps,vx(:,i,j,k), & nvars,1,useLES) enddo enddo enddo endif if ( bc_iyup .ne. CLES_PATCH_CORE ) then do k=1,nz do j=ny+bc_iyup,iyhi-1 do i=1,nx ! retreive original pressure call cles_eqstate(ux(:,i,j,k), ncomps, vx(:,i,j,k), & nvars, 1, CLES_FALSE) ! add sgs term to total energy call cles_inveqst(ux(:,i,j,k),ncomps,vx(:,i,j,k), & nvars,1,useLES) enddo enddo enddo endif if ( bc_izlow .ne. CLES_PATCH_CORE ) then do k=izlo+1,1-bc_izlow do j=1,ny do i=1,nx ! retreive original pressure call cles_eqstate(ux(:,i,j,k), ncomps, vx(:,i,j,k), & nvars, 1, CLES_FALSE) ! add sgs term to total energy call cles_inveqst(ux(:,i,j,k),ncomps,vx(:,i,j,k), & nvars,1,useLES) enddo enddo enddo endif if ( bc_izup .ne. CLES_PATCH_CORE ) then do k=nz+bc_izup,izhi-1 do j=1,ny do i=1,nx ! retreive original pressure call cles_eqstate(ux(:,i,j,k), ncomps, vx(:,i,j,k), & nvars, 1, CLES_FALSE) ! add sgs term to total energy call cles_inveqst(ux(:,i,j,k),ncomps,vx(:,i,j,k), & nvars,1,useLES) enddo enddo enddo endif END SUBROUTINE FixSgsBoundaries END MODULE Generic_GetRHS