CalculateTendency_ECDGModel2D Subroutine

public subroutine CalculateTendency_ECDGModel2D(this)

GPU implementation of the EC-DG 2-D tendency.

TwoPointFluxMethod is computed on the host (user Fortran function) and uploaded before the GPU kernel sequence. The surface term uses the dedicated ECDGSurfaceContribution_2D_gpu kernel which applies the Jacobian weighting consistently with the volume term.

Arguments

TypeIntentOptionalAttributesName
class(ECDGModel2D), intent(inout) :: this

Calls

proc~~calculatetendency_ecdgmodel2d~~CallsGraph proc~calculatetendency_ecdgmodel2d CalculateTendency_ECDGModel2D interface~ecdgsurfacecontribution_2d_gpu ECDGSurfaceContribution_2D_gpu proc~calculatetendency_ecdgmodel2d->interface~ecdgsurfacecontribution_2d_gpu interface~calculatedsdt_gpu CalculateDSDt_gpu proc~calculatetendency_ecdgmodel2d->interface~calculatedsdt_gpu

Contents


Source Code

  subroutine CalculateTendency_ECDGModel2D(this)
    !! GPU implementation of the EC-DG 2-D tendency.
    !!
    !! TwoPointFluxMethod is computed on the host (user Fortran function) and
    !! uploaded before the GPU kernel sequence.  The surface term uses the
    !! dedicated ECDGSurfaceContribution_2D_gpu kernel which applies the
    !! Jacobian weighting consistently with the volume term.
    implicit none
    class(ECDGModel2D),intent(inout) :: this
    ! Local
    integer :: ndof

    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()
    ! Two-point flux: concrete GPU models (e.g. ECAdvection2D) override
    ! TwoPointFluxMethod to run entirely on device.  Models that compute
    ! on the host should call twoPointFlux%UpdateDevice() at the end of
    ! their TwoPointFluxMethod override.
    call this%TwoPointFluxMethod()

    ! EC volume divergence (uses MappedTwoPointVectorDivergence_2D_gpu)
    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()

    ! Add (1/J) * M^{-1} B^T f_Riemann
    call ECDGSurfaceContribution_2D_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)

    ! dSdt = source - fluxDivergence
    ndof = this%solution%nVar* &
           this%mesh%nElem* &
           (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_ECDGModel2D