LCOV - code coverage report
Current view: top level - src - mo_cost.f90 (source / functions) Hit Total Coverage
Test: forces coverage Lines: 22 71 31.0 %
Date: 2024-03-13 19:03:28 Functions: 2 7 28.6 %

          Line data    Source code
       1             : !> \file mo_cost.f90
       2             : !> \brief \copybrief mo_cost
       3             : !> \details \copydetails mo_cost
       4             : 
       5             : !>  \brief Added for testing purposes of test_mo_anneal
       6             : !> \copyright Copyright 2005-\today, the CHS Developers, Sabine Attinger: All rights reserved.
       7             : !! FORCES is released under the LGPLv3+ license \license_note
       8             : Module mo_cost
       9             : 
      10             :   use mo_kind, only: sp, dp
      11             : 
      12             :   IMPLICIT NONE
      13             : 
      14             :   PRIVATE
      15             : 
      16             :   PUBLIC :: cost_sp,  cost_dp
      17             :   PUBLIC :: cost_valid_sp,  cost_valid_dp
      18             :   PUBLIC :: range_sp, range_dp
      19             :   public :: cost_objective
      20             : 
      21             : CONTAINS
      22             : 
      23             :   !> \brief function: `f(x) = ax^3 + bx^2 + cx + d`
      24           0 :   FUNCTION cost_sp (paraset)
      25             : 
      26             :     implicit none
      27             : 
      28             :     REAL(SP), DIMENSION(:), INTENT(IN)  :: paraset
      29             :     REAL(SP)                            :: cost_sp
      30           0 :     REAL(SP), DIMENSION(6,2)            :: meas
      31           0 :     REAL(SP), DIMENSION(6)              :: calc
      32             : 
      33             :     ! function: f(x) = ax^3 + bx^2 + cx + d
      34             :     ! measurements: (0.5,5.725), (1.0, 21.7), (1.5, 49.175), (2.0, 88.9), (2.5, 141.625), (3.0, 208.1)
      35             :     ! --> a=1.0, b=20.0, c=0.2, d=0.5
      36             : 
      37           0 :     meas(:,1) = (/0.5_sp, 1.0_sp, 1.5_sp, 2.0_sp, 2.5_sp, 3.0_sp/)
      38           0 :     meas(:,2) = (/5.7250_sp, 21.7000_sp, 49.1750_sp, 88.9000_sp, 141.6250_sp, 208.1000_sp/)
      39             : 
      40           0 :     calc(:) = paraset(1)*meas(:,1)**3+paraset(2)*meas(:,1)**2+paraset(3)*meas(:,1)+paraset(4)
      41             : 
      42             :     ! MAE  Mean Absolute Error
      43           0 :     cost_sp = sum(abs( meas(:,2)-calc(:) ))/size(meas,1)
      44             : 
      45             :     RETURN
      46           0 :   END FUNCTION cost_sp
      47             : 
      48             :   !> \brief function: `f(x) = ax^3 + bx^2 + cx + d`
      49           0 :   FUNCTION cost_dp (paraset)
      50             : 
      51             :     implicit none
      52             : 
      53             :     REAL(DP), DIMENSION(:), INTENT(IN)  :: paraset
      54             :     REAL(DP)                            :: cost_dp
      55           0 :     REAL(DP), DIMENSION(6,2)            :: meas
      56           0 :     REAL(DP), DIMENSION(6)              :: calc
      57             : 
      58             :     ! function: f(x) = ax^3 + bx^2 + cx + d
      59             :     ! measurements: (0.5,5.725), (1.0, 21.7), (1.5, 49.175), (2.0, 88.9), (2.5, 141.625), (3.0, 208.1)
      60             :     ! --> a=1.0, b=20.0, c=0.2, d=0.5
      61             : 
      62           0 :     meas(:,1) = (/0.5_dp, 1.0_dp, 1.5_dp, 2.0_dp, 2.5_dp, 3.0_dp/)
      63           0 :     meas(:,2) = (/5.7250_dp, 21.7000_dp, 49.1750_dp, 88.9000_dp, 141.6250_dp, 208.1000_dp/)
      64             : 
      65           0 :     calc(:) = paraset(1)*meas(:,1)**3+paraset(2)*meas(:,1)**2+paraset(3)*meas(:,1)+paraset(4)
      66             : 
      67             :     ! MAE  Mean Absolute Error
      68           0 :     cost_dp = sum(abs( meas(:,2)-calc(:) ))/size(meas,1)
      69             : 
      70             :     RETURN
      71           0 :   END FUNCTION cost_dp
      72             : 
      73             :   !> \brief function: `f(x) = ax^3 + bx^2 + cx + d`
      74           0 :   FUNCTION cost_valid_sp (paraset,status_in)
      75             : 
      76             :     implicit none
      77             : 
      78             :     REAL(SP), DIMENSION(:), INTENT(IN)  :: paraset
      79             :     LOGICAL,  OPTIONAL,     INTENT(OUT) :: status_in
      80             :     REAL(SP)                            :: cost_valid_sp
      81           0 :     REAL(SP), DIMENSION(6,2)            :: meas
      82           0 :     REAL(SP), DIMENSION(6)              :: calc
      83             : 
      84             :     ! function: f(x) = ax^3 + bx^2 + cx + d
      85             :     ! measurements: (0.5,5.725), (1.0, 21.7), (1.5, 49.175), (2.0, 88.9), (2.5, 141.625), (3.0, 208.1)
      86             :     ! --> a=1.0, b=20.0, c=0.2, d=0.5
      87             : 
      88           0 :     meas(:,1) = (/0.5_sp, 1.0_sp, 1.5_sp, 2.0_sp, 2.5_sp, 3.0_sp/)
      89           0 :     meas(:,2) = (/5.7250_sp, 21.7000_sp, 49.1750_sp, 88.9000_sp, 141.6250_sp, 208.1000_sp/)
      90             : 
      91           0 :     calc(:) = paraset(1)*meas(:,1)**3+paraset(2)*meas(:,1)**2+paraset(3)*meas(:,1)+paraset(4)
      92             : 
      93           0 :     if (present(status_in)) then
      94           0 :        status_in = .true.
      95             :        ! Define a status .false. if calculation of "calc" was not successful
      96             :     end if
      97             : 
      98             :     ! MAE  Mean Absolute Error
      99           0 :     cost_valid_sp = sum(abs( meas(:,2)-calc(:) ))/size(meas,1)
     100             : 
     101             :     RETURN
     102           0 :   END FUNCTION cost_valid_sp
     103             : 
     104             :   !> \brief function: `f(x) = ax^3 + bx^2 + cx + d`
     105           0 :   FUNCTION cost_valid_dp (paraset,status_in)
     106             : 
     107             :     implicit none
     108             : 
     109             :     REAL(DP), DIMENSION(:), INTENT(IN)  :: paraset
     110             :     LOGICAL,  OPTIONAL,     INTENT(OUT) :: status_in
     111             :     REAL(DP)                            :: cost_valid_dp
     112           0 :     REAL(DP), DIMENSION(6,2)            :: meas
     113           0 :     REAL(DP), DIMENSION(6)              :: calc
     114             : 
     115             :     ! function: f(x) = ax^3 + bx^2 + cx + d
     116             :     ! measurements: (0.5,5.725), (1.0, 21.7), (1.5, 49.175), (2.0, 88.9), (2.5, 141.625), (3.0, 208.1)
     117             :     ! --> a=1.0, b=20.0, c=0.2, d=0.5
     118             : 
     119           0 :     meas(:,1) = (/0.5_dp, 1.0_dp, 1.5_dp, 2.0_dp, 2.5_dp, 3.0_dp/)
     120           0 :     meas(:,2) = (/5.7250_dp, 21.7000_dp, 49.1750_dp, 88.9000_dp, 141.6250_dp, 208.1000_dp/)
     121             : 
     122           0 :     calc(:) = paraset(1)*meas(:,1)**3+paraset(2)*meas(:,1)**2+paraset(3)*meas(:,1)+paraset(4)
     123             : 
     124           0 :     if (present(status_in)) then
     125           0 :        status_in = .true.
     126             :        ! Define a status .false. if calculation of "calc" was not successful
     127             :     end if
     128             : 
     129             :     ! MAE  Mean Absolute Error
     130           0 :     cost_valid_dp = sum(abs( meas(:,2)-calc(:) ))/size(meas,1)
     131             : 
     132             :     RETURN
     133           0 :   END FUNCTION cost_valid_dp
     134             : 
     135             :   !> \brief dummy range
     136     1287500 :   SUBROUTINE range_dp(paraset, iPar, rangePar)
     137           0 :     use mo_kind
     138             :     REAL(DP), DIMENSION(:), INTENT(IN)  :: paraset
     139             :     INTEGER(I4),            INTENT(IN)  :: iPar
     140             :     REAL(DP), DIMENSION(2), INTENT(OUT) :: rangePar
     141             : 
     142             :     ! Range does not depend on parameter set
     143             :     ! select case(iPar)
     144             :     !    case(1_i4)
     145             :     !       rangePar(1) =  0.0_dp
     146             :     !       rangePar(2) = 10.0_dp
     147             :     !    case(2_i4)
     148             :     !       rangePar(1) =  0.0_dp
     149             :     !       rangePar(2) = 40.0_dp
     150             :     !    case(3_i4)
     151             :     !       rangePar(1) =  0.0_dp
     152             :     !       rangePar(2) = 10.0_dp
     153             :     !    case(4_i4)
     154             :     !       rangePar(1) =  0.0_dp
     155             :     !       rangePar(2) =  5.0_dp
     156             :     ! end select
     157             : 
     158             :     ! Range of parameter 2 depends on value of parameter 1:
     159             :     !    parameter 2 at most 40* parameter 1 :
     160             :     !       0 <= p2 <= 40p1
     161             :     !       0 <= p1 <= 0.025p2
     162     1610002 :     select case(iPar)
     163             :     case(1_i4)
     164      322502 :        rangePar(1) =  0.025_dp*paraset(2)
     165      322502 :        rangePar(2) =  10.0_dp
     166             :     case(2_i4)
     167      321474 :        rangePar(1) =  0.0_dp
     168      321474 :        rangePar(2) =  40.0_dp*paraset(1)
     169             :     case(3_i4)
     170      321610 :        rangePar(1) =  0.0_dp
     171      321610 :        rangePar(2) = 10.0_dp
     172             :     case(4_i4)
     173      321914 :        rangePar(1) =  0.0_dp
     174     1287500 :        rangePar(2) =  5.0_dp
     175             :     end select
     176             : 
     177     1287500 :   END SUBROUTINE range_dp
     178             : 
     179             :   !> \brief dummy range
     180           0 :   SUBROUTINE range_sp(paraset, iPar, rangePar)
     181     1287500 :     use mo_kind
     182             :     REAL(SP), DIMENSION(:), INTENT(IN)  :: paraset
     183             :     INTEGER(I4),            INTENT(IN)  :: iPar
     184             :     REAL(SP), DIMENSION(2), INTENT(OUT) :: rangePar
     185             : 
     186             :     ! Range does not depend on parameter set
     187             :     ! select case(iPar)
     188             :     !    case(1_i4)
     189             :     !       rangePar(1) =  0.0_sp
     190             :     !       rangePar(2) = 10.0_sp
     191             :     !    case(2_i4)
     192             :     !       rangePar(1) =  0.0_sp
     193             :     !       rangePar(2) = 40.0_sp
     194             :     !    case(3_i4)
     195             :     !       rangePar(1) =  0.0_sp
     196             :     !       rangePar(2) = 10.0_sp
     197             :     !    case(4_i4)
     198             :     !       rangePar(1) =  0.0_sp
     199             :     !       rangePar(2) =  5.0_sp
     200             :     ! end select
     201             : 
     202             :     ! Range of parameter 2 depends on value of parameter 1:
     203             :     !    parameter 2 at most 4* parameter 1 :
     204             :     !       0     <= p2 <= 4p1
     205             :     !       0.25p2 <= p1 <= 10.0
     206           0 :     select case(iPar)
     207             :     case(1_i4)
     208           0 :        rangePar(1) =  0.025_sp*paraset(2)
     209           0 :        rangePar(2) = 10.0_sp
     210             :     case(2_i4)
     211           0 :        rangePar(1) =  0.0_sp
     212           0 :        rangePar(2) =  40.0_sp*paraset(1)
     213             :     case(3_i4)
     214           0 :        rangePar(1) =  0.0_sp
     215           0 :        rangePar(2) = 10.0_sp
     216             :     case(4_i4)
     217           0 :        rangePar(1) =  0.0_sp
     218           0 :        rangePar(2) =  5.0_sp
     219             :     end select
     220             : 
     221           0 :   END SUBROUTINE range_sp
     222             : 
     223             :   !> \brief dummy cost objective function
     224     1287511 :   FUNCTION cost_objective(parameterset, eval, arg1, arg2, arg3)
     225             : 
     226           0 :     use mo_kind, only: dp
     227             :     use mo_optimization_utils, only: eval_interface
     228             :     use mo_optimization_types, only : optidata_sim
     229             : 
     230             :     implicit none
     231             : 
     232             :     real(dp), intent(in), dimension(:) :: parameterset
     233             :     procedure(eval_interface), INTENT(IN), pointer :: eval
     234             :     real(dp), optional, intent(in) :: arg1
     235             :     real(dp), optional, intent(out) :: arg2
     236             :     real(dp), optional, intent(out) :: arg3
     237             :     real(dp) :: cost_objective
     238             : 
     239     1287511 :     type(optidata_sim), dimension(:), allocatable :: et_opti
     240    19312665 :     REAL(DP), DIMENSION(6,2)            :: meas
     241     9012577 :     REAL(DP), DIMENSION(6)              :: calc
     242             : 
     243     1287511 :     call eval(parameterset, etOptiSim=et_opti)
     244             : 
     245             :     ! function: f(x) = ax^3 + bx^2 + cx + d
     246             :     ! measurements: (0.5,5.725), (1.0, 21.7), (1.5, 49.175), (2.0, 88.9), (2.5, 141.625), (3.0, 208.1)
     247             :     ! --> a=1.0, b=20.0, c=0.2, d=0.5
     248             : 
     249     9012577 :     meas(:,1) = (/0.5_dp, 1.0_dp, 1.5_dp, 2.0_dp, 2.5_dp, 3.0_dp/)
     250     9012577 :     meas(:,2) = (/5.7250_dp, 21.7000_dp, 49.1750_dp, 88.9000_dp, 141.6250_dp, 208.1000_dp/)
     251             : 
     252     9012577 :     calc(:) = parameterset(1)*meas(:,1)**3+parameterset(2)*meas(:,1)**2+parameterset(3)*meas(:,1)+parameterset(4)
     253             : 
     254             :     ! MAE  Mean Absolute Error
     255     9012577 :     cost_objective = sum(abs( meas(:,2)-calc(:) ))/size(meas,1)
     256             : 
     257             :     RETURN
     258     1287511 :   END FUNCTION cost_objective
     259             : 
     260             : 
     261             : END MODULE mo_cost

Generated by: LCOV version 1.16