imexQ_oc_sweep Subroutine

public subroutine imexQ_oc_sweep(this, pf, level_index, t0, dt, nsweeps, flags)

Uses

  • proc~~imexq_oc_sweep~~UsesGraph proc~imexq_oc_sweep imexQ_oc_sweep module~pf_mod_hooks pf_mod_hooks proc~imexq_oc_sweep->module~pf_mod_hooks module~pf_mod_timer pf_mod_timer proc~imexq_oc_sweep->module~pf_mod_timer module~pf_mod_dtype pf_mod_dtype module~pf_mod_hooks->module~pf_mod_dtype module~pf_mod_timer->module~pf_mod_dtype iso_c_binding iso_c_binding module~pf_mod_dtype->iso_c_binding

Assign level pointer

Loop over sweeps

Arguments

Type IntentOptional AttributesName
class(pf_imexQ_oc_t), intent(inout) :: this
type(pf_pfasst_t), intent(inout), target:: pf

PFASST structure

integer, intent(in) :: level_index

which level this is

real(kind=pfdp), intent(in) :: t0

Time at beginning of time step

real(kind=pfdp), intent(in) :: dt

time step size

integer, intent(in) :: nsweeps

number of sweeps to do

integer, intent(in), optional :: flags

Calls

proc~~imexq_oc_sweep~~CallsGraph proc~imexq_oc_sweep imexQ_oc_sweep proc~call_hooks call_hooks proc~imexq_oc_sweep->proc~call_hooks proc~pf_residual pf_residual proc~imexq_oc_sweep->proc~pf_residual proc~start_timer start_timer proc~imexq_oc_sweep->proc~start_timer proc~end_timer end_timer proc~imexq_oc_sweep->proc~end_timer proc~call_hooks->proc~start_timer proc~call_hooks->proc~end_timer proc~pf_residual->proc~start_timer proc~pf_residual->proc~end_timer

Contents

Source Code


Source Code

  subroutine imexQ_oc_sweep(this, pf, level_index, t0, dt, nsweeps, flags)
    use pf_mod_timer
    use pf_mod_hooks

    class(pf_imexQ_oc_t), intent(inout) :: this
    type(pf_pfasst_t), intent(inout),target :: pf  !!  PFASST structure
    real(pfdp),        intent(in   ) :: t0         !!  Time at beginning of time step
    real(pfdp),        intent(in   ) :: dt     !!  time step size
    integer,             intent(in)    :: level_index  !!  which level this is
    integer,             intent(in)    :: nsweeps      !!  number of sweeps to do
    integer, optional, intent(in   ) :: flags    

    class(pf_level_t), pointer :: lev    !!  points to current level
    
    ! indicate if sweep on both (0, default; might skip y or p if tolerance satisfied), just y (1), just p (2)
    
    integer     :: k, m, n,Nnodes, which
    real(pfdp)  :: t,tend

    logical     :: sweep_y, sweep_p
    real(pfdp), allocatable  :: norms_y(:) !, norms_p(Lev%nnodes-1)
    integer     ::step
    
    lev => pf%levels(level_index)   !!  Assign level pointer
        
    step = pf%state%step+1
!     print *, 'sweep on step', step


    which = 0
    if (present(flags)) which = flags
    if (.not.present(flags)) stop "IMEXQ_OC SWEEPER WITHOUT FLAGS"
!     print *, "IMEXQ_OC SWEEP", which    
    
    Nnodes = lev%nnodes
    tend = t0+dt


    call start_timer(pf, TLEVEL+lev%index-1)

    if (which .eq. 1) then
        sweep_y = .true.
        sweep_p = .false.
    else if (which .eq. 2) then
        sweep_y = .false.
        sweep_p = .true.
    else
       sweep_y = .true.
       sweep_p = .true.
       allocate(norms_y(lev%nnodes-1))
       do m = 1, Nnodes-1
          norms_y(m) = lev%R(m)%norm(1)
       end do
       if ( maxval(abs(norms_y)) < pf%abs_res_tol ) then 
         sweep_y = .false.
         if (level_index == pf%nlevels) pf%state%skippedy = pf%state%skippedy + 1
       end if
       deallocate(norms_y)
       !if ( maxval(abs(norms_p)) < pf%abs_res_tol ) sweep_p = .false.
    end if

!     if( sweep_p .and. pf%rank == 0)  print *, "sweep on p with which = ", which

    
  do k = 1,nsweeps   !!  Loop over sweeps
    call call_hooks(pf, level_index, PF_PRE_SWEEP)    

    ! compute integrals from previous iteration and add fas correction
!     do m = 1, Nnodes-1
!        call Lev%encap%setval(Lev%S(m), 0.0_pfdp, 1)
!        call Lev%encap%setval(Lev%S(m), 0.0_pfdp, 2)

     if( sweep_y ) then
        do m = 1, Nnodes-1
          call lev%I(m)%setval(0.0_pfdp, 1)
          !  Forward in y
          if (this%explicit) then
             do n = 1, Nnodes
                call lev%I(m)%axpy(dt*this%QdiffE(m,n), lev%F(n,1),1)
!                 call Lev%encap%axpy(Lev%S(m), dt*imexQ_oc%QdiffE(m,n), Lev%F(n,1),1)
             end do
          end if
          if (this%implicit) then
             do n = 1, lev%nnodes
                call lev%I(m)%axpy(dt*this%QdiffI(m,n), lev%F(n,2), 1)
!                 call Lev%encap%axpy(Lev%S(m), dt*imexQ_oc%QdiffI(m,n), Lev%F(n,2),1)
             end do
          end if
          if (allocated(lev%tauQ)) then
            call lev%I(m)%axpy(1.0_pfdp, lev%tauQ(m), 1)
!              call Lev%encap%axpy(Lev%S(m), 1.0_pfdp, Lev%tauQ(m),1)
          end if
        end do
      end if

       if( sweep_p ) then
         do m =  Nnodes-1,1,-1
          call lev%I(m)%setval(0.0_pfdp, 2)

          !  Backward in p, note S(m) goes backward now
!2          do n =  1,Nnodes
!2             call Lev%encap%axpy(Lev%S(Nnodes-m), dt*imexQ_oc%QdiffE(m,n), Lev%F(Nnodes+1-n,1),2)
!2             call Lev%encap%axpy(Lev%S(Nnodes-m), dt*imexQ_oc%QdiffI(m,n), Lev%F(Nnodes+1-n,2),2)
!2          end do
          if (this%explicit) then
            do n =  Nnodes,1,-1
              call lev%I(m)%axpy(dt*this%QdiffE(Nnodes-m,Nnodes+1-n), lev%F(n,1), 2)
              !call Lev%encap%axpy(Lev%S(m), dt*imexQ_oc%QdiffE(Nnodes-m,Nnodes+1-n), Lev%F(n,1),2)
            end do
          end if
          if (this%implicit) then
            do n =  Nnodes,1,-1
              call lev%I(m)%axpy(dt*this%QdiffI(Nnodes-m,Nnodes+1-n), lev%F(n,2), 2)
!               call Lev%encap%axpy(Lev%S(m), dt*imexQ_oc%QdiffI(Nnodes-m,Nnodes+1-n), Lev%F(n,2),2)
            end do
          end if
          if (allocated(lev%tauQ)) then
             call lev%I(m)%axpy(1.0_pfdp, lev%tauQ(m), 2)
          end if
         end do
       end if

    ! Reload the newest initial values
    ! Recompute first function values
    if (sweep_y) then
      if (k .eq. 1) then
        call lev%Q(1)%copy(lev%q0, 1)
        if (this%explicit) &
          call this%f_eval(lev%Q(1), t0, lev%index, lev%F(1,1), 1, 1, 1, step)
        if (this%implicit) &
          call this%f_eval(lev%Q(1), t0, lev%index, lev%F(1,2), 2, 1, 1, step)
      end if
!        call Lev%encap%copy(Lev%Q(1), Lev%q0, 1)
!        call imexQ_oc%f1eval(Lev%Q(1), t0, Lev%level, Lev%ctx, Lev%F(1,1), 1, 1, step)
!        call imexQ_oc%f2eval(Lev%Q(1), t0, Lev%level, Lev%ctx, Lev%F(1,2), 1)
    end if
    !else 
!     if( sweep_p ) then
!       if (k .eq. 1) then
!         call lev%Q(Nnodes)%copy(lev%qend, 2)
!         if (this%explicit) &
!           call this%f_eval(lev%Q(Nnodes), tend, lev%index, lev%F(Nnodes,1), 1, 2, Nnodes, step)
!         if (this%implicit) &
!           call this%f_eval(lev%Q(Nnodes), tend, lev%index, lev%F(Nnodes,2), 2, 2, Nnodes, step)
!       end if
! !        call Lev%encap%copy(Lev%Q(Nnodes), Lev%qend, 2)
! !        call imexQ_oc%f1eval(Lev%Q(Nnodes), tend, Lev%level, Lev%ctx, Lev%F(Nnodes,1), 2, Nnodes, step)
! !        call imexQ_oc%f2eval(Lev%Q(Nnodes), tend, Lev%level, Lev%ctx, Lev%F(Nnodes,2), 2)
!     end if
    
!     if (sweep_p) then
!    !  Backward  sweep on p
!       t = tend
!       do m =  Nnodes-1,1,-1
!          t = t - dt*this%dtsdc(m)
! 
!          ! Do the dirk parts
!          call this%rhs%setval(0.0_pfdp, 2)
!          do n = Nnodes, m+1,-1
!             if (this%explicit) &
!               call this%rhs%axpy(dt*this%QtilE(Nnodes-m,Nnodes-n+1), lev%F(n,1), 2)  
!             if (this%implicit) &
!               call this%rhs%axpy(dt*this%QtilI(Nnodes-m,Nnodes-n+1), lev%F(n,2), 2)
!          end do
!        
!          call this%rhs%axpy(1.0_pfdp, lev%I(m), 2)
!          call this%rhs%axpy(1.0_pfdp, lev%Q(Nnodes), 2)
! 
!          !  Do implicit solve  
!          if (this%implicit) then
!            call this%f_comp(lev%Q(m), t, dt*this%QtilI(Nnodes-m,Nnodes-m+1), this%rhs, lev%index, lev%F(m,2), 2, 2)
!          else
!             call lev%Q(m)%copy(this%rhs,2)
!          end if
!          if (this%explicit) &
!            call this%f_eval(lev%Q(m), t, lev%index, lev%F(m,1), 1, 2, m, step) 
!       end do
!       ! reset first value
!       call lev%q0%copy(lev%Q(1), 2)
!       call pf_residual(pf, lev, dt, 2)
! !       call pf_residual(pf, lev, dt, which)
!     end if


    !  Make some space
!     call Lev%encap%create(rhs, Lev%level, SDC_KIND_SOL_FEVAL, Lev%nvars, Lev%shape, Lev%ctx)

    if (sweep_y) then
      !  Forward sweep on y
      t = t0
      do m = 1, Nnodes-1
         t = t + dt*this%dtsdc(m)  !  forward running time

         !  Form rhs with all explicit terms
         call this%rhs%setval(0.0_pfdp,1)
         do n = 1, m
            if (this%explicit) &
              call this%rhs%axpy(dt*this%QtilE(m,n), lev%F(n,1), 1)  
            if (this%implicit) &
              call this%rhs%axpy(dt*this%QtilI(m,n), lev%F(n,2), 1)  
         end do
         
         call this%rhs%axpy(1.0_pfdp, lev%I(m), 1)
         call this%rhs%axpy(1.0_pfdp, lev%Q(1), 1)
       
        ! Do implicit solve  
         if (this%implicit) then
            call this%f_comp(lev%Q(m+1), t, dt*this%QtilI(m,m+1), this%rhs, lev%index, lev%F(m+1,2), 2, 1)
         else
            call lev%Q(m+1)%copy(this%rhs,1)            
         end if
          !  Compute explicit piece on new value
         if (this%explicit) &
            call this%f_eval(lev%Q(m+1), t, lev%index, lev%F(m+1,1), 1, 1, m+1, step)
      end do
      !  Reset last values
      call lev%qend%copy(lev%Q(Nnodes), 1)
!       call pf_residual(pf, lev, dt, 1)
!       call pf_residual(pf, lev, dt, which)
    end if
    
    if( sweep_p ) then
!        do m=1, Nnodes-1
!           call lev%I(m)%setval(0.0_pfdp, 2)
! 
!           !  Backward in p, note S(m) goes backward now
! !2          do n =  1,Nnodes
! !2             call Lev%encap%axpy(Lev%S(Nnodes-m), dt*imexQ_oc%QdiffE(m,n), Lev%F(Nnodes+1-n,1),2)
! !2             call Lev%encap%axpy(Lev%S(Nnodes-m), dt*imexQ_oc%QdiffI(m,n), Lev%F(Nnodes+1-n,2),2)
! !2          end do
!           if (this%explicit) then
!             do n =  Nnodes,1,-1
!               call lev%I(m)%axpy(dt*this%QdiffE(Nnodes-m,Nnodes+1-n), lev%F(n,1), 2)
!               !call Lev%encap%axpy(Lev%S(m), dt*imexQ_oc%QdiffE(Nnodes-m,Nnodes+1-n), Lev%F(n,1),2)
!             end do
!           end if
!           if (this%implicit) then
!             do n =  Nnodes,1,-1
!               call lev%I(m)%axpy(dt*this%QdiffI(Nnodes-m,Nnodes+1-n), lev%F(n,2), 2)
! !               call Lev%encap%axpy(Lev%S(m), dt*imexQ_oc%QdiffI(Nnodes-m,Nnodes+1-n), Lev%F(n,2),2)
!             end do
!           end if
!           if (allocated(lev%tauQ)) then
!              call lev%I(m)%axpy(1.0_pfdp, lev%tauQ(m), 2)
!           end if
!       end do
    
      if (k .eq. 1) then
        call lev%Q(Nnodes)%copy(lev%qend, 2)
        if (this%explicit) &
          call this%f_eval(lev%Q(Nnodes), tend, lev%index, lev%F(Nnodes,1), 1, 2, Nnodes, step)
        if (this%implicit) &
          call this%f_eval(lev%Q(Nnodes), tend, lev%index, lev%F(Nnodes,2), 2, 2, Nnodes, step)
      end if
!        call Lev%encap%copy(Lev%Q(Nnodes), Lev%qend, 2)
!        call imexQ_oc%f1eval(Lev%Q(Nnodes), tend, Lev%level, Lev%ctx, Lev%F(Nnodes,1), 2, Nnodes, step)
!        call imexQ_oc%f2eval(Lev%Q(Nnodes), tend, Lev%level, Lev%ctx, Lev%F(Nnodes,2), 2)
    end if

   if (sweep_p) then
   !  Backward  sweep on p
      t = tend
      do m =  Nnodes-1,1,-1
         t = t - dt*this%dtsdc(m)

         ! Do the dirk parts
         call this%rhs%setval(0.0_pfdp, 2)
         do n = Nnodes, m+1,-1
            if (this%explicit) &
              call this%rhs%axpy(dt*this%QtilE(Nnodes-m,Nnodes-n+1), lev%F(n,1), 2)  
            if (this%implicit) &
              call this%rhs%axpy(dt*this%QtilI(Nnodes-m,Nnodes-n+1), lev%F(n,2), 2)
         end do
       
         call this%rhs%axpy(1.0_pfdp, lev%I(m), 2)
         call this%rhs%axpy(1.0_pfdp, lev%Q(Nnodes), 2)

         !  Do implicit solve  
         if (this%implicit) then
           call this%f_comp(lev%Q(m), t, dt*this%QtilI(Nnodes-m,Nnodes-m+1), this%rhs, lev%index, lev%F(m,2), 2, 2)
         else
            call lev%Q(m)%copy(this%rhs,2)
         end if
         if (this%explicit) &
           call this%f_eval(lev%Q(m), t, lev%index, lev%F(m,1), 1, 2, m, step) 
      end do
      ! reset first value
      call lev%q0%copy(lev%Q(1), 2)
!       call pf_residual(pf, lev, dt, 2)
    end if
!     if(sweep_p) &
!       call this%evaluate_all(lev, t0 + dt*lev%nodes, 2, step)

    if( sweep_p .and. sweep_y ) then
      call pf_residual(pf, lev, dt, 0)
    else if( sweep_y ) then
      call pf_residual(pf, lev, dt, 1)
    else if (sweep_p ) then
      call pf_residual(pf, lev, dt, 2)
    else
      stop "neither sweep on p nor on y : that should not happen"
    end if
    ! done
    call call_hooks(pf, level_index, PF_POST_SWEEP)

   end do !nsweeps
   
   call end_timer(pf, TLEVEL+lev%index-1)
  end subroutine imexQ_oc_sweep