diff --git a/src/mo_cost.f90 b/src/mo_cost.f90 index 1f7792195b048a5467cf507f570ed67a40cf8125..d9bbf65f289fd16fdb4418a78fe5dc359568002b 100644 --- a/src/mo_cost.f90 +++ b/src/mo_cost.f90 @@ -223,9 +223,9 @@ CONTAINS !> \brief dummy cost objective function FUNCTION cost_objective(parameterset, eval, arg1, arg2, arg3) - use mo_kind, only: dp + use mo_kind, only: dp, i4 use mo_optimization_utils, only: eval_interface - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t implicit none @@ -236,11 +236,15 @@ CONTAINS real(dp), optional, intent(out) :: arg3 real(dp) :: cost_objective - type(variables_optidata_sim) :: et_opti + type(opti_sim_t), dimension(:), pointer :: opti_sim + type(config_t) :: config REAL(DP), DIMENSION(6,2) :: meas REAL(DP), DIMENSION(6) :: calc - call eval(parameterset, et_opti) + config%parameters = parameterset + allocate(opti_sim(1)) + call opti_sim(1)%add(name='et', dim=2_i4) + call eval(config, opti_sim) ! function: f(x) = ax^3 + bx^2 + cx + d ! 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) @@ -254,6 +258,8 @@ CONTAINS ! MAE Mean Absolute Error cost_objective = sum(abs( meas(:,2)-calc(:) ))/size(meas,1) + deallocate(opti_sim) + RETURN END FUNCTION cost_objective diff --git a/src/mo_likelihood.f90 b/src/mo_likelihood.f90 index 4a7b70ea6b7e760b183e6b253a2327d8b4eeba37..74d33fd8f055bf71d826ced34f4549dc4e63e315 100644 --- a/src/mo_likelihood.f90 +++ b/src/mo_likelihood.f90 @@ -47,7 +47,7 @@ CONTAINS ! ------------------------------- !> \brief A Likelihood function: "real" likelihood (sigma is an error model or given) function likelihood_dp(paraset, eval, stddev_in, stddev_new, likeli_new) - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t REAL(DP), DIMENSION(:), INTENT(IN) :: paraset ! parameter set procedure(eval_interface), INTENT(IN), pointer :: eval REAL(DP), INTENT(IN), optional :: stddev_in ! standard deviation of data @@ -58,18 +58,26 @@ CONTAINS ! local REAL(DP), DIMENSION(size(meas,1)) :: errors - type(variables_optidata_sim) :: runoff + real(dp), pointer :: runoff(:, :) + type(opti_sim_t), dimension(:), pointer :: opti_sim + type(config_t) :: config - call eval(paraset, runoff) - errors(:) = runoff%runoff(:,1)-data() + config%parameters = paraset + + allocate(opti_sim(1)) + call opti_sim(1)%add(name="runoff", dim=2_i4) + call eval(config, opti_sim=opti_sim) + call opti_sim(1)%set_pointer(ptr=runoff, name="runoff") + errors(:) = runoff(:,1)-data() likelihood_dp = exp(-0.5_dp * sum( errors(:) * errors(:) / stddev_global**2 )) + deallocate(opti_sim) end function likelihood_dp ! ------------------------------- !> \brief A Log-Likelihood function: "real" likelihood (sigma is an error model or given) function loglikelihood_dp(paraset, eval, stddev_in, stddev_new, likeli_new) - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t REAL(DP), DIMENSION(:), INTENT(IN) :: paraset ! parameter set procedure(eval_interface), INTENT(IN), pointer :: eval REAL(DP), INTENT(IN), optional :: stddev_in ! standard deviation of data @@ -80,18 +88,26 @@ CONTAINS ! local REAL(DP), DIMENSION(size(meas,1)) :: errors - type(variables_optidata_sim) :: runoff + real(dp), pointer :: runoff(:, :) + type(opti_sim_t), dimension(:), pointer :: opti_sim + type(config_t) :: config + + config%parameters = paraset - call eval(paraset, runoff) - errors(:) = runoff%runoff(:,1)-data() + allocate(opti_sim(1)) + call opti_sim(1)%add(name="runoff", dim=2_i4) + call eval(config, opti_sim=opti_sim) + call opti_sim(1)%set_pointer(ptr=runoff, name="runoff") + errors(:) = runoff(:,1)-data() loglikelihood_dp = -0.5_dp * sum( errors(:) * errors(:) / stddev_global**2 ) + deallocate(opti_sim) end function loglikelihood_dp ! ------------------------------- !> \brief A Likelihood function: "faked" likelihood (sigma is computed by obs vs model) function likelihood_stddev_dp(paraset, eval, stddev_in, stddev_new, likeli_new) - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t REAL(DP), DIMENSION(:), INTENT(IN) :: paraset ! parameter set procedure(eval_interface), INTENT(IN), pointer :: eval REAL(DP), INTENT(IN), optional :: stddev_in ! standard deviation of data @@ -103,11 +119,19 @@ CONTAINS ! local REAL(DP), DIMENSION(size(meas,1)) :: errors REAL(DP) :: stddev_err - type(variables_optidata_sim) :: runoff + real(dp), pointer :: runoff(:, :) + type(opti_sim_t), dimension(:), pointer :: opti_sim + type(config_t) :: config - call eval(paraset, runoff) - errors(:) = runoff%runoff(:,1)-data() + config%parameters = paraset + + allocate(opti_sim(1)) + call opti_sim(1)%add(name="runoff", dim=2_i4) + call eval(config, opti_sim=opti_sim) + call opti_sim(1)%set_pointer(ptr=runoff, name="runoff") + errors(:) = runoff(:,1)-data() likelihood_stddev_dp = exp(-0.5_dp * sum( errors(:) * errors(:) / stddev_in**2 )) + deallocate(opti_sim) ! optional out stddev_err = stddev(errors) @@ -123,7 +147,7 @@ CONTAINS ! ------------------------------- !> \brief A Log-Likelihood_stddev function: "faked" likelihood (sigma is computed by obs vs model) function loglikelihood_stddev_dp(paraset, eval, stddev_in, stddev_new, likeli_new) - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t REAL(DP), DIMENSION(:), INTENT(IN) :: paraset ! parameter set procedure(eval_interface), INTENT(IN), pointer :: eval REAL(DP), INTENT(IN), optional :: stddev_in ! standard deviation of data @@ -135,11 +159,19 @@ CONTAINS ! local REAL(DP), DIMENSION(size(meas,1)) :: errors REAL(DP) :: stddev_err - type(variables_optidata_sim) :: runoff + real(dp), pointer :: runoff(:, :) + type(opti_sim_t), dimension(:), pointer :: opti_sim + type(config_t) :: config + + config%parameters = paraset - call eval(paraset, runoff) - errors(:) = runoff%runoff(:,1)-data() + allocate(opti_sim(1)) + call opti_sim(1)%add(name="runoff", dim=2_i4) + call eval(config, opti_sim=opti_sim) + call opti_sim(1)%set_pointer(ptr=runoff, name="runoff") + errors(:) = runoff(:,1)-data() loglikelihood_stddev_dp = -0.5_dp * sum( errors(:) * errors(:) / stddev_in**2 ) + deallocate(opti_sim) ! optional out stddev_err = stddev(errors) @@ -154,21 +186,28 @@ CONTAINS ! ------------------------------- !> \brief A Model: p1*x^2 + p2*x + p3 - subroutine model_dp(parameterset, varsOptidataSim) + subroutine model_dp(config, opti_sim) use mo_kind, only: dp - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t !! !$ USE omp_lib, only: OMP_GET_THREAD_NUM - real(dp), dimension(:), intent(in) :: parameterset - type(variables_optidata_sim), intent(inout) :: varsOptidataSim + type(config_t), intent(in) :: config + type(opti_sim_t), dimension(:), pointer, optional, intent(inout) :: opti_sim + real(dp), pointer :: runoff(:, :) integer(i4) :: i, n ! for OMP !! !$ integer(i4) :: n_threads, is_thread n = size(meas,1) - allocate(varsOptidataSim%runoff(n, 1)) + + do i = 1 , size(opti_sim) + if (opti_sim(i)%has('runoff')) then + call opti_sim(i)%allocate(name="runoff", dim1=n, dim2=1) + call opti_sim(i)%set_pointer(ptr=runoff, name="runoff") + end if + end do !! !$ is_thread = OMP_GET_THREAD_NUM() !! !$ write(*,*) 'OMP_thread: ', is_thread @@ -178,11 +217,11 @@ CONTAINS !$OMP do do i=1, n !! !$ if (is_thread /= 0) write(*,*) ' OMP_thread-1: ', is_thread - varsOptidataSim%runoff(i,1) = parameterset(1) * meas(i,1) * meas(i,1) + parameterset(2) * meas(i,1) + parameterset(3) + runoff(i,1) = config%parameters(1) * meas(i,1) * meas(i,1) + config%parameters(2) * meas(i,1) + config%parameters(3) end do !$OMP end do !$OMP end parallel - + end subroutine model_dp function data_dp() diff --git a/src/mo_opt_functions.f90 b/src/mo_opt_functions.f90 index 4a74802cc146bd486d842120bcb2f58a8be5fb1d..6a9fb664fd2d1ff0069a1560c81096da2a152c04 100644 --- a/src/mo_opt_functions.f90 +++ b/src/mo_opt_functions.f90 @@ -5623,7 +5623,7 @@ CONTAINS function ackley_objective(parameterset, eval, arg1, arg2, arg3) use mo_constants, only: pi_dp - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t implicit none @@ -5639,21 +5639,27 @@ CONTAINS real(dp), parameter :: b = 0.2_dp real(dp), parameter :: c = 2.0_dp*pi_dp real(dp) :: s1, s2 - type(variables_optidata_sim) :: et_opti + type(opti_sim_t), pointer, dimension(:) :: opti_sim + type(config_t) :: config - call eval(parameterset, et_opti) + allocate(opti_sim(1)) + config%parameters = parameterset + call opti_sim(1)%add(name='et', dim=2_i4) + call eval(config, opti_sim) n = size(parameterset) s1 = sum(parameterset**2) s2 = sum(cos(c*parameterset)) ackley_objective = -a * exp(-b*sqrt(1.0_dp/real(n,dp)*s1)) - exp(1.0_dp/real(n,dp)*s2) + a + exp(1.0_dp) + deallocate(opti_sim) + end function ackley_objective function griewank_objective(parameterset, eval, arg1, arg2, arg3) use mo_kind, only: i4, dp - use mo_optimization_types, only : variables_optidata_sim + use mo_optimization_types, only : opti_sim_t, config_t implicit none @@ -5667,9 +5673,13 @@ CONTAINS integer(i4) :: nopt integer(i4) :: j real(dp) :: d, u1, u2 - type(variables_optidata_sim) :: et_opti + type(opti_sim_t), pointer, dimension(:) :: opti_sim + type(config_t) :: config - call eval(parameterset, et_opti) + config%parameters = parameterset + allocate(opti_sim(1)) + call opti_sim(1)%add(name='et', dim=2_i4) + call eval(config, opti_sim) nopt = size(parameterset) if (nopt .eq. 2) then @@ -5683,69 +5693,110 @@ CONTAINS u2 = u2 * cos(parameterset(j)/sqrt(real(j,dp))) end do griewank_objective = u1 - u2 + 1.0_dp + + deallocate(opti_sim) ! end function griewank_objective - subroutine eval_dummy(parameterset, varsOptidataSim) + subroutine eval_dummy(config, opti_sim) use mo_kind, only : dp - use mo_optimization_types, only : variables_optidata_sim, optidata + use mo_optimization_types, only : opti_sim_t, config_t, optidata implicit none - real(dp), dimension(:), intent(in) :: parameterset - type(variables_optidata_sim), intent(inout) :: varsOptidataSim + type(config_t), intent(in) :: config + type(opti_sim_t), dimension(:), pointer, optional, intent(inout) :: opti_sim - type(optidata) :: dummyData - integer(i4) :: i + real(dp), dimension(:, :), pointer :: dummyDataPtr_2d + real(dp), dimension(:), pointer :: dummyDataPtr_1d + integer(i4) :: iDomain, nDomains - allocate(dummyData%dataObs(1, 1)) - dummyData%dataObs = 0.0_dp + nDomains = size(opti_sim) - if (allocated(varsOptidataSim%etOptiSim)) then - do i=1, size(varsOptidataSim%etOptiSim) - call varsOptidataSim%etOptiSim(i)%init(dummyData) - end do - end if + allocate(dummyDataPtr_2d(1, 1)) + allocate(dummyDataPtr_1d(1)) + dummyDataPtr_2d = 0.0_dp + dummyDataPtr_1d = 0.0_dp - if (allocated(varsOptidataSim%neutronsOptiSim)) then - do i=1, size(varsOptidataSim%neutronsOptiSim) - call varsOptidataSim%neutronsOptiSim(1)%init(dummyData) - end do - end if + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('et')) then + call opti_sim(iDomain)%allocate(name="et", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="et") + end if + end do - if (allocated(varsOptidataSim%twsOptiSim)) then - do i=1, size(varsOptidataSim%twsOptiSim) - call varsOptidataSim%twsOptiSim(1)%init(dummyData) - end do - end if + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('neutrons')) then + call opti_sim(iDomain)%allocate(name="neutrons", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="neutrons") + end if + end do - if (allocated(varsOptidataSim%smOptiSim)) then - do i=1, size(varsOptidataSim%smOptiSim) - call varsOptidataSim%smOptiSim(1)%init(dummyData) - end do - end if + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('tws')) then + call opti_sim(iDomain)%allocate(name="tws", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="tws") + end if + end do - allocate(varsOptidataSim%runoff(1, 1)) - varsOptidataSim%runoff(:, :) = 0.0_dp + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('sm')) then + call opti_sim(iDomain)%allocate(name="sm", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="sm") + end if + end do - allocate(varsOptidataSim%BFI(1)) - varsOptidataSim%BFI(:) = 0.0_dp + ! ToDo: runoff and all other variables were handled differently: Created wether + ! optional or not. Why? Should it be changed? + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('runoff')) then + call opti_sim(iDomain)%allocate(name="runoff", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="runoff") + end if + end do - allocate(varsOptidataSim%lake_level(1, 1)) - varsOptidataSim%lake_level(:, :) = 0.0_dp + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('BFI')) then + call opti_sim(iDomain)%allocate(name="BFI", dim1=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_1d, name="BFI") + end if + end do - allocate(varsOptidataSim%lake_volume(1, 1)) - varsOptidataSim%lake_volume(:, :) = 0.0_dp + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('lake_level')) then + call opti_sim(iDomain)%allocate(name="lake_level", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="lake_level") + end if + end do - allocate(varsOptidataSim%lake_area(1, 1)) - varsOptidataSim%lake_area(:, :) = 0.0_dp + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('lake_volume')) then + call opti_sim(iDomain)%allocate(name="lake_volume", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="lake_volume") + end if + end do - allocate(varsOptidataSim%lake_spill(1, 1)) - varsOptidataSim%lake_spill(:, :) = 0.0_dp + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('lake_area')) then + call opti_sim(iDomain)%allocate(name="lake_area", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="lake_area") + end if + end do + + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('lake_spill')) then + call opti_sim(iDomain)%allocate(name="lake_spill", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="lake_spill") + end if + end do - allocate(varsOptidataSim%lake_outflow(1, 1)) - varsOptidataSim%lake_outflow(:, :) = 0.0_dp + do iDomain = 1 , nDomains + if (opti_sim(iDomain)%has('lake_outflow')) then + call opti_sim(iDomain)%allocate(name="lake_outflow", dim1=1, dim2=1) + call opti_sim(iDomain)%set_pointer(ptr=dummyDataPtr_2d, name="lake_outflow") + end if + end do end subroutine eval_dummy diff --git a/src/mo_optimization_types.f90 b/src/mo_optimization_types.f90 index b7db5545c11ea5d0b9dde82dc9303a1be881f636..abe0caa53262def283f116813bd5d929a213eb95 100644 --- a/src/mo_optimization_types.f90 +++ b/src/mo_optimization_types.f90 @@ -12,24 +12,68 @@ MODULE mo_optimization_types IMPLICIT NONE - public :: optidata, optidata_sim, variables_optidata_sim + public :: optidata, optidata_sim, config_t, opti_sim_t private - type variables_optidata_sim - integer(i4), public, dimension(:), allocatable :: opti_domain_indices - real(dp), public, dimension(:, :), allocatable :: runoff !< dim1=time dim2=gauge - type(optidata_sim), public, dimension(:), allocatable :: smOptiSim !< dim1=ncells, dim2=time - type(optidata_sim), public, dimension(:), allocatable :: neutronsOptiSim !< dim1=ncells, dim2=time - type(optidata_sim), public, dimension(:), allocatable :: etOptiSim !< dim1=ncells, dim2=time - type(optidata_sim), public, dimension(:), allocatable :: twsOptiSim !< dim1=ncells, dim2=time - real(dp), public, dimension(:, :), allocatable :: lake_level !< dim1=time dim2=lake - real(dp), public, dimension(:, :), allocatable :: lake_volume !< dim1=time dim2=lake - real(dp), public, dimension(:, :), allocatable :: lake_area !< dim1=time dim2=lake - real(dp), public, dimension(:, :), allocatable :: lake_spill !< dim1=time dim2=lake - real(dp), public, dimension(:, :), allocatable :: lake_outflow !< dim1=time dim2=lake - real(dp), public, dimension(:), allocatable :: BFI !< baseflow index, dim1=domainID - end type variables_optidata_sim + ! type variables_optidata_sim + ! integer(i4), public, dimension(:), allocatable :: opti_domain_indices + ! real(dp), public, dimension(:, :), allocatable :: runoff !< dim1=time dim2=gauge + ! type(optidata_sim), public, dimension(:), allocatable :: smOptiSim !< dim1=ncells, dim2=time + ! type(optidata_sim), public, dimension(:), allocatable :: neutronsOptiSim !< dim1=ncells, dim2=time + ! type(optidata_sim), public, dimension(:), allocatable :: etOptiSim !< dim1=ncells, dim2=time + ! type(optidata_sim), public, dimension(:), allocatable :: twsOptiSim !< dim1=ncells, dim2=time + ! real(dp), public, dimension(:, :), allocatable :: lake_level !< dim1=time dim2=lake + ! real(dp), public, dimension(:, :), allocatable :: lake_volume !< dim1=time dim2=lake + ! real(dp), public, dimension(:, :), allocatable :: lake_area !< dim1=time dim2=lake + ! real(dp), public, dimension(:, :), allocatable :: lake_spill !< dim1=time dim2=lake + ! real(dp), public, dimension(:, :), allocatable :: lake_outflow !< dim1=time dim2=lake + ! real(dp), public, dimension(:), allocatable :: BFI !< baseflow index, dim1=domainID + ! end type variables_optidata_sim + + type config_t + real(dp), dimension(:), allocatable :: parameters + integer(i4), dimension(:), allocatable :: opti_indices + end type config_t + +! type opti_sim_t +! type(optidata_sim), target, dimension(:), allocatable :: data +! character(256) :: name +! end type opti_sim_t + type opti_sim_t + type(opti_sim_single_t), dimension(:), allocatable :: opti_vars + contains + procedure :: has => opti_sim_t_has + procedure :: add => opti_sim_t_add + procedure :: opti_sim_t_allocate_1d + procedure :: opti_sim_t_allocate_2d + procedure :: opti_sim_t_allocate_3d + procedure :: opti_sim_t_allocate_4d + procedure :: opti_sim_t_allocate_5d + procedure :: opti_sim_t_set_pointer_1d + procedure :: opti_sim_t_set_pointer_2d + procedure :: opti_sim_t_set_pointer_3d + procedure :: opti_sim_t_set_pointer_4d + procedure :: opti_sim_t_set_pointer_5d + generic :: set_pointer => opti_sim_t_set_pointer_1d, opti_sim_t_set_pointer_2d, & + opti_sim_t_set_pointer_3d, opti_sim_t_set_pointer_4d, opti_sim_t_set_pointer_5d + generic :: allocate => opti_sim_t_allocate_1d, opti_sim_t_allocate_2d, & + opti_sim_t_allocate_3d, opti_sim_t_allocate_4d, opti_sim_t_allocate_5d + end type opti_sim_t + + type opti_sim_single_t + real(dp), dimension(:), allocatable :: data_1d + real(dp), dimension(:, :), allocatable :: data_2d + real(dp), dimension(:, :, :), allocatable :: data_3d + real(dp), dimension(:, :, :, :), allocatable :: data_4d + real(dp), dimension(:, :, :, :, :), allocatable :: data_5d + character(256) :: name + integer(i4) :: dimen + integer(i4) :: time_avg_selector = 1_i4 !< time averaging: -3 yearly, -2 monthly, -1 daily, + !< 0 total, n every n timestep + ! contains + ! procedure :: add => opti_sim_single_t_add + end type opti_sim_single_t !> \brief optional data, such as sm, neutrons, et, tws @@ -64,6 +108,194 @@ MODULE mo_optimization_types contains + ! ToDo: When to charater(*) and character(256)? + pure logical function opti_sim_t_has(this, name) + class(opti_sim_t), intent(in) :: this + character(*), intent(in) :: name + + integer(i4) :: i + + opti_sim_t_has = .false. + + do i = 1, size(this%opti_vars) + if (trim(this%opti_vars(i)%name) == trim(name)) opti_sim_t_has = .true. + end do + end function opti_sim_t_has + + subroutine opti_sim_t_add(this, name, dim, time_avg_selector) + class(opti_sim_t), intent(inout) :: this + character(*), intent(in) :: name + integer(i4), intent(in) :: dim + integer(i4), optional, intent(in) :: time_avg_selector + + type(opti_sim_single_t) :: add_data + + ! ToDo: Why name in type 256 and in input var *? + add_data%name = name + add_data%dimen = dim + if (present(time_avg_selector)) add_data%time_avg_selector = time_avg_selector + ! ToDo: is the if case needed? + if (allocated(this%opti_vars)) then + this%opti_vars = [this%opti_vars, add_data] + else + allocate(this%opti_vars(1)) + this%opti_vars(1)=add_data + end if + + end subroutine opti_sim_t_add + + subroutine opti_sim_t_allocate_1d(this, name, dim1) + class(opti_sim_t), target, intent(inout) :: this + character(*), intent(in) :: name + integer(i4), intent(in) :: dim1 + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + allocate(this%opti_vars(i)%data_1d(dim1)) + end if + end do + end subroutine opti_sim_t_allocate_1d + + subroutine opti_sim_t_allocate_2d(this, name, dim1, dim2) + class(opti_sim_t), target, intent(inout) :: this + character(*), intent(in) :: name + integer(i4), intent(in) :: dim1 + integer(i4), intent(in) :: dim2 + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + allocate(this%opti_vars(i)%data_2d(dim1, dim2)) + end if + end do + end subroutine opti_sim_t_allocate_2d + + subroutine opti_sim_t_allocate_3d(this, name, dim1, dim2, dim3) + class(opti_sim_t), target, intent(inout) :: this + character(*), intent(in) :: name + integer(i4), intent(in) :: dim1 + integer(i4), intent(in) :: dim2 + integer(i4), intent(in) :: dim3 + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + allocate(this%opti_vars(i)%data_3d(dim1, dim2, dim3)) + end if + end do + end subroutine opti_sim_t_allocate_3d + + subroutine opti_sim_t_allocate_4d(this, name, dim1, dim2, dim3, dim4) + class(opti_sim_t), target, intent(inout) :: this + character(*), intent(in) :: name + integer(i4), intent(in) :: dim1 + integer(i4), intent(in) :: dim2 + integer(i4), intent(in) :: dim3 + integer(i4), intent(in) :: dim4 + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + allocate(this%opti_vars(i)%data_4d(dim1, dim2, dim3, dim4)) + end if + end do + end subroutine opti_sim_t_allocate_4d + + subroutine opti_sim_t_allocate_5d(this, name, dim1, dim2, dim3, dim4, dim5) + class(opti_sim_t), target, intent(inout) :: this + character(*), intent(in) :: name + integer(i4), intent(in) :: dim1 + integer(i4), intent(in) :: dim2 + integer(i4), intent(in) :: dim3 + integer(i4), intent(in) :: dim4 + integer(i4), intent(in) :: dim5 + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + allocate(this%opti_vars(i)%data_5d(dim1, dim2, dim3, dim4, dim5)) + end if + end do + end subroutine opti_sim_t_allocate_5d + + ! ToDo: generate with fypp + subroutine opti_sim_t_set_pointer_1d(this, ptr, name) + class(opti_sim_t), target, intent(in) :: this + real(dp), dimension(:), pointer, intent(inout) :: ptr + character(*), intent(in) :: name + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + ptr => this%opti_vars(i)%data_1d + end if + end do + end subroutine opti_sim_t_set_pointer_1d + + subroutine opti_sim_t_set_pointer_2d(this, ptr, name) + class(opti_sim_t), target, intent(in) :: this + real(dp), dimension(:,:), pointer :: ptr + character(*), intent(in) :: name + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + ptr => this%opti_vars(i)%data_2d + end if + end do + end subroutine opti_sim_t_set_pointer_2d + + subroutine opti_sim_t_set_pointer_3d(this, ptr, name) + class(opti_sim_t), target, intent(in) :: this + real(dp), dimension(:,:,:), pointer, intent(inout) :: ptr + character(*), intent(in) :: name + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + ptr => this%opti_vars(i)%data_3d + end if + end do + end subroutine opti_sim_t_set_pointer_3d + + subroutine opti_sim_t_set_pointer_4d(this, ptr, name) + class(opti_sim_t), target, intent(in) :: this + real(dp), dimension(:,:,:,:), pointer, intent(inout) :: ptr + character(*), intent(in) :: name + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + ptr => this%opti_vars(i)%data_4d + end if + end do + end subroutine opti_sim_t_set_pointer_4d + + subroutine opti_sim_t_set_pointer_5d(this, ptr, name) + class(opti_sim_t), target, intent(in) :: this + real(dp), dimension(:,:,:,:,:), pointer, intent(inout) :: ptr + character(*), intent(in) :: name + + integer(i4) :: i + + do i = 1, size(this%opti_vars) + if (this%opti_vars(i)%name == name) then + ptr => this%opti_vars(i)%data_5d + end if + end do + end subroutine opti_sim_t_set_pointer_5d + + ! ToDo: Pass only shape instead of optidataObs subroutine optidata_sim_init(this, optidataObs) class(optidata_sim), intent(inout) :: this type(optidata), intent(in) :: optidataObs diff --git a/src/mo_optimization_utils.f90 b/src/mo_optimization_utils.f90 index 3abe0f7fdb66c8632b93fdeb70b874b73408cb7c..827f0c35fb08508792af711f27db35a3057677b3 100644 --- a/src/mo_optimization_utils.f90 +++ b/src/mo_optimization_utils.f90 @@ -11,13 +11,21 @@ module mo_optimization_utils implicit none - !> \brief Interface for evaluation routine. + ! !> \brief Interface for evaluation routine. + ! abstract interface + ! subroutine eval_interface(parameterset, varsOptidataSim) + ! use mo_kind, only : dp, i4 + ! use mo_optimization_types, only : variables_optidata_sim + ! real(dp), dimension(:), intent(in) :: parameterset + ! type(variables_optidata_sim), intent(inout) :: varsOptidataSim + ! end subroutine + ! end interface + abstract interface - subroutine eval_interface(parameterset, varsOptidataSim) - use mo_kind, only : dp, i4 - use mo_optimization_types, only : variables_optidata_sim - real(dp), dimension(:), intent(in) :: parameterset - type(variables_optidata_sim), intent(inout) :: varsOptidataSim + subroutine eval_interface(config, opti_sim) + use mo_optimization_types, only : config_t, opti_sim_t + type(config_t), intent(in) :: config + type(opti_sim_t), dimension(:), pointer, optional, intent(inout) :: opti_sim end subroutine end interface