GPU-resident tendency for ESAtmo3D. The inviscid pipeline is identical to ECDGModel3D's GPU CalculateTendency; if either nu or kappa is positive, the constant-coefficient Laplacian divergence (BR1 weak-form) is then accumulated into fluxDivergence before forming dSdt.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ESAtmo3D), | intent(inout) | :: | this |
subroutine CalculateTendency_ESAtmo3D(this)
!! GPU-resident tendency for ESAtmo3D. The inviscid pipeline is
!! identical to ECDGModel3D's GPU CalculateTendency; if either nu
!! or kappa is positive, the constant-coefficient Laplacian
!! divergence (BR1 weak-form) is then accumulated into
!! fluxDivergence before forming dSdt.
implicit none
class(ESAtmo3D),intent(inout) :: this
! Local
integer :: ndof,ndof_diff
call this%solution%BoundaryInterp()
! Post the halo exchange for the prognostic variables; the MPI messages
! are in flight while the hooks, boundary conditions, source, and the
! two-point volume flux and its divergence below execute.
call this%solution%SideExchangeStart(this%mesh,this%nstepped)
call this%PreTendencyHook()
call this%SetBoundaryCondition()
if(this%gradient_enabled) then
! The BR gradient consumes extBoundary (through the side averages), so
! the exchange must complete before the gradient is computed.
call this%solution%SideExchangeFinish(this%mesh)
call this%CalculateSolutionGradient()
call this%SetGradientBoundaryCondition()
call this%solutionGradient%AverageSides()
endif
call this%SourceMethod()
call this%TwoPointFluxMethod()
call this%twoPointFlux%MappedDivergence(this%fluxDivergence%interior_gpu)
! BoundaryFlux is the first consumer of extBoundary; the two-point volume
! flux and its divergence above overlap with the halo exchange (a no-op
! wait when gradients already finished it). BoundaryFlux writes only the
! Riemann trace (flux boundarynormal), disjoint from the volume-term
! outputs, so this reordering does not change any floating-point results.
call this%solution%SideExchangeFinish(this%mesh)
call this%BoundaryFlux()
call ECDGSurfaceContribution_3D_gpu( &
this%flux%boundarynormal_gpu, &
this%geometry%J%interior_gpu, &
this%solution%interp%bMatrix_gpu, &
this%solution%interp%qWeights_gpu, &
this%fluxDivergence%interior_gpu, &
this%solution%interp%N,this%solution%nVar,this%mesh%nElem)
if(this%nu > 0.0_prec .or. this%kappa > 0.0_prec) then
call this%DiffusiveFluxMethod()
call this%DiffusiveBoundaryFlux()
call this%diffFlux%MappedDGDivergence(this%diffDiv%interior_gpu)
ndof_diff = this%solution%nVar* &
this%mesh%nElem* &
(this%solution%interp%N+1)* &
(this%solution%interp%N+1)* &
(this%solution%interp%N+1)
call AccumulateField_gpu(this%fluxDivergence%interior_gpu, &
this%diffDiv%interior_gpu, &
ndof_diff)
endif
ndof = this%solution%nVar* &
this%mesh%nElem* &
(this%solution%interp%N+1)* &
(this%solution%interp%N+1)* &
(this%solution%interp%N+1)
call CalculateDSDt_gpu(this%fluxDivergence%interior_gpu, &
this%source%interior_gpu, &
this%dSdt%interior_gpu,ndof)
endsubroutine CalculateTendency_ESAtmo3D