The simple adjoint model

From Interactive System for Ice sheet Simulation
Jump to: navigation, search

The driver routine for running the adjoint model

program driver_adm
 
implicit none
 
real(8), dimension(2) :: xvec, adxvec
real(8) :: fc, adfc
real(8) :: alpha, beta
 
! initialize	
	adfc  = 1.
	adxvec(1)  = 0.
	adxvec(2)  = 0.
        fc = 0.
        xvec(1)    = 10.
	xvec(2)    = 30.
        alpha = 5.
        beta = 2.
 
! call adjoint model
	call adsimple(alpha,beta,xvec,adxvec,fc,adfc)
 
! write output
	print *, 'alpha, beta = ', alpha, beta
	print *, 'x1, x2 = ', xvec(1), xvec(2)
	print *, 'fc, adfc = ', fc, adfc
	print *, 'adx1, adx2 = ', adxvec(1), adxvec(2)
 
	end

Basic command to invoke AD tool in reverse mode

Invoking the AD tool (here TAF) needs to specify

  • what are the independent / control variables (here \mathbf{x} = \texttt{xvec})
  • what are the dependent variables or cost function (here J_0 = \texttt{fc})
  • what is the top-level routines where the actual model starts (different from program driver
  • list of routines to be differentiated
taf     -reverse \
        -toplevel simple \
	-input 'xvec' \
	-output 'fc' \
	simple.f90

The adjoint code, generated via the AD tool TAF

!                           DISCLAIMER
!
!   This file was generated by TAF version 1.9.54
!
module     adsimple_variables
!******************************************************************
!******************************************************************
!** This routine was generated by Automatic differentiation.     **
!** FastOpt: Transformation of Algorithm in Fortran, TAF 1.9.54  **
!******************************************************************
!******************************************************************
!==============================================
! referencing used modules
!==============================================
use simple_variables
 
!==============================================
! all entries are defined explicitly
!==============================================
implicit none
 
!==============================================
! declare local variables
!==============================================
real(kind=8) adyvec(2)
 
contains
subroutine adsimple_variables_constructor
!******************************************************************
!******************************************************************
!** This routine was generated by Automatic differentiation.     **
!** FastOpt: Transformation of Algorithm in Fortran, TAF 1.9.54  **
!******************************************************************
!******************************************************************
!==============================================
! all entries are defined explicitly
!==============================================
implicit none
 
!----------------------------------------------
! RESET ADJOINT MODULE VARIABLES
!----------------------------------------------
adyvec(:) = 0._8
 
end subroutine adsimple_variables_constructor
 
 
end module     adsimple_variables
 
 
module     adsimple_functions
!******************************************************************
!******************************************************************
!** This routine was generated by Automatic differentiation.     **
!** FastOpt: Transformation of Algorithm in Fortran, TAF 1.9.54  **
!******************************************************************
!******************************************************************
!==============================================
! referencing used modules
!==============================================
use simple_functions
 
!==============================================
! all entries are defined explicitly
!==============================================
implicit none
 
contains
subroutine adhcostfunction( adcostfunction, yvec, adyvec )
!******************************************************************
!******************************************************************
!** This routine was generated by Automatic differentiation.     **
!** FastOpt: Transformation of Algorithm in Fortran, TAF 1.9.54  **
!******************************************************************
!******************************************************************
!==============================================
! all entries are defined explicitly
!==============================================
implicit none
 
!==============================================
! declare parameters
!==============================================
real(kind=8) d1
parameter ( d1 = 55. )
real(kind=8) d2
parameter ( d2 = 65. )
real(kind=8) var1
parameter ( var1 = 1 )
 
!==============================================
! declare arguments
!==============================================
real(kind=8), intent(inout) :: adcostfunction
real(kind=8) adyvec(2)
real(kind=8) yvec(2)
 
!----------------------------------------------
! ROUTINE BODY
!----------------------------------------------
adyvec(2) = adyvec(2)+2*adcostfunction*1.d0/var1*(yvec(2)-d2)
adyvec(1) = adyvec(1)+2*adcostfunction*1.d0/var1*(yvec(1)-d1)
adcostfunction = 0._8
 
end subroutine adhcostfunction
 
 
end module     adsimple_functions
 
 
subroutine adsimple( alpha, beta, xvec, adxvec, fc, adfc )
!******************************************************************
!******************************************************************
!** This routine was generated by Automatic differentiation.     **
!** FastOpt: Transformation of Algorithm in Fortran, TAF 1.9.54  **
!******************************************************************
!******************************************************************
!==============================================
! referencing used modules
!==============================================
use simple_variables
use adsimple_variables
use simple_functions
use adsimple_functions
 
!==============================================
! all entries are defined explicitly
!==============================================
implicit none
 
!==============================================
! declare arguments
!==============================================
real(kind=8), intent(inout) :: adfc
real(kind=8), intent(inout) :: adxvec(2)
real(kind=8), intent(in) :: alpha
real(kind=8), intent(in) :: beta
real(kind=8), intent(out) :: fc
real(kind=8), intent(in) :: xvec(2)
 
!----------------------------------------------
! RESET GLOBAL ADJOINT VARIABLES
!----------------------------------------------
call adzero
 
!----------------------------------------------
! ROUTINE BODY
!----------------------------------------------
!----------------------------------------------
! FUNCTION AND TAPE COMPUTATIONS
!----------------------------------------------
yvec(1) = alpha*xvec(1)
yvec(2) = -(beta*xvec(2))
fc = costfunction(yvec)
 
!----------------------------------------------
! ADJOINT COMPUTATIONS
!----------------------------------------------
call adhcostfunction( adfc,yvec,adyvec )
adfc = 0._8
adxvec(2) = adxvec(2)-adyvec(2)*beta
adyvec(2) = 0._8
adxvec(1) = adxvec(1)+adyvec(1)*alpha
adyvec(1) = 0._8
 
 
end subroutine adsimple
 
 
subroutine adzero
!******************************************************************
!******************************************************************
!** This routine was generated by Automatic differentiation.     **
!** FastOpt: Transformation of Algorithm in Fortran, TAF 1.9.54  **
!******************************************************************
!******************************************************************
!==============================================
! referencing used modules
!==============================================
use simple_variables
use simple_functions
use adsimple_variables, only : adsimple_variables_constructor
 
!==============================================
! all entries are defined explicitly
!==============================================
implicit none
 
 
!----------------------------------------------
! reset adjoint module variables
!----------------------------------------------
call adsimple_variables_constructor
 
end subroutine adzero