5.13.2-dev0
mHM
The mesoscale Hydrological Model
Loading...
Searching...
No Matches
mo_optimization.F90
Go to the documentation of this file.
1!> \file mo_optimization.f90
2!> \brief \copybrief mo_optimization
3!> \details \copydetails mo_optimization
4
5!> \brief Wrapper subroutine for optimization against runoff and sm.
6!> \details This module provides a wrapper subroutine for optimization of mRM/mHM against runoff or soil moisture.
7!> \authors Stephan Thober
8!> \date Oct 2015
9!> \copyright Copyright 2005-\today, the mHM Developers, Luis Samaniego, Sabine Attinger: All rights reserved.
10!! mHM is released under the LGPLv3+ license \license_note
11!> \ingroup f_common
13 use mo_kind, only : i4, i8, dp
14 use mo_optimization_utils, only : eval_interface, objective_interface
15 implicit none
16 private
17 public :: optimization
18
19contains
20 ! ------------------------------------------------------------------
21
22 ! NAME
23 ! optimization
24
25 ! PURPOSE
26 !> \brief Wrapper for optimization.
27
28 !> \details This subroutine selects the optimization defined in a namelist,
29 !> i.e. the global variable \e opti\_method.
30 !> It return the objective function value for a specific parameter set.
31
32 ! INTENT(IN)
33 !> \param[in] "procedure(eval_interface) :: eval"
34 !> \param[in] "procedure(objective_interface) :: objective" - objective function used in the optimization
35 !> \param[in] "character(len = *) :: dirConfigOut" - directory where to write ascii output
36
37 ! INTENT(OUT)
38 !> \param[out] "real(dp) :: funcbest" - best objective function value obtained during optimization
39 !> \param[out] "logical, dimension(:) :: maskpara" true = parameter will be optimized = parameter(i,4) = 1
40 !> false = parameter will not be optimized = parameter(i,4) = 0
41
42 ! HISTORY
43 !> \authors Matthias Cuntz, Luis Samaniego, Juliane Mai, Matthias Zink and Stephan Thober
44
45 !> \date Oct 2015
46
47 ! Modifications:
48
49 subroutine optimization(eval, objective, dirConfigOut, funcBest, maskpara)
50
51 use mo_anneal, only : anneal
55#ifdef MPI
57#endif
58 use mo_dds, only : dds
59 use mo_mcmc, only : mcmc, mcmc_stddev
60 use mo_message, only : message, error_message
61 use mo_sce, only : sce
62 use mo_string_utils, only : num2str
63 use mo_timer, only : timer_get, timer_start, &
64 timer_stop
65 use mo_xor4096, only : get_timeseed
66
67 implicit none
68
69 procedure(eval_interface), intent(in), pointer :: eval
70
71 ! - objective function used in the optimization
72 procedure(objective_interface), intent(in), pointer :: objective
73
74 ! - directory where to write ascii output
75 character(len = *), intent(in) :: dirconfigout
76
77 ! - best objective function value obtained during optimization
78 real(dp), intent(out) :: funcbest
79
80 ! true = parameter will be optimized = parameter(i,4) = 1
81 ! false = parameter will not be optimized = parameter(i,4) = 0
82 logical, intent(out), allocatable, dimension(:) :: maskpara
83
84 integer(i4) :: ii
85
86 ! current timer number
87 integer(i4) :: itimer
88
89 ! parameter sets sampled during burnin
90 real(dp), allocatable, dimension(:, :) :: burnin_paras
91
92 ! parameter sets sampled during proper mcmc
93 real(dp), allocatable, dimension(:, :) :: mcmc_paras
94
95 ! pre-determined stepsize
96 ! real(dp), dimension(:), allocatable :: step
97
98 integer(i4) :: npara
99
100 ! global_parameters but includes a and b for likelihood
101 real(dp), allocatable, dimension(:, :) :: local_parameters
102
103 ! maskpara but includes a and b for likelihood
104 logical, allocatable, dimension(:) :: local_maskpara
105
106 ! local seed used for optimization
107 integer(i8) :: iseed
108
109 ! file for temporal optimization outputs
110 character(256) :: tfile
111
112 ! file for temporal SCE optimization outputs
113 character(256) :: pfile
114
115
116 ! -------------------------------------------------------------------------
117 ! START
118 ! -------------------------------------------------------------------------
119 call message(' Start optimization')
120 itimer = 1
121 call timer_start(itimer)
122
123 ! mask parameter which have a FLAG=0 in mhm_parameter.nml
124 ! maskpara = true : parameter will be optimized
125 ! maskpara = false : parameter is discarded during optimization
126 npara = size(global_parameters, 1)
127 allocate(maskpara(npara))
128 maskpara = .true.
129 do ii = 1, npara
130 if (nint(global_parameters(ii, 4), i4) .eq. 0_i4) then
131 maskpara(ii) = .false.
132 end if
133 end do
134
135 ! add two extra parameter for optimisation of likelihood
136 if (opti_function == 8) then
137 allocate(local_parameters(npara + 2, size(global_parameters, 2)))
138 allocate(local_maskpara(npara + 2))
139 ! setting step sizes manually
140 ! allocate(step(npara+2))
141 local_parameters(1 : npara, :) = global_parameters(:, :)
142 local_maskpara(1 : npara) = maskpara(:)
143 local_parameters(npara + 1, 1) = 0.001_dp
144 local_parameters(npara + 1, 2) = 100._dp
145 local_parameters(npara + 1, 3) = 1._dp
146 local_parameters(npara + 1, 4) = 1._dp
147 local_parameters(npara + 1, 5) = 0._dp
148 local_parameters(npara + 2, 1) = 0.001_dp
149 local_parameters(npara + 2, 2) = 10._dp
150 local_parameters(npara + 2, 3) = 0.1_dp
151 local_parameters(npara + 2, 4) = 1._dp
152 local_parameters(npara + 2, 5) = 0._dp
153 local_maskpara(npara + 1 :) = .true.
154 if ((opti_method == 0) .and. (.not. mcmc_opti)) then ! MCMC but only for parameter uncertainties
155 local_parameters(npara + 1, 3) = mcmc_error_params(1)
156 local_parameters(npara + 2, 3) = mcmc_error_params(2)
157 local_maskpara(npara + 1 :) = .false.
158 end if
159 else
160 allocate(local_parameters(npara, size(global_parameters, 2)))
161 allocate(local_maskpara(npara))
162 local_parameters = global_parameters
163 local_maskpara = maskpara
164 end if
165
166 ! Seed for random numbers in optimisation
167 if (seed .gt. 0_i8) then ! fixed user-defined seed
168 iseed = seed
169 else ! flexible clock-time seed
170 call get_timeseed(iseed)
171 end if
172
173 select case (opti_method)
174 case (0)
175 call message(' Use MCMC')
176
177 tfile = trim(adjustl(dirconfigout)) // 'mcmc_tmp_parasets.nc'
178
179 ! setting step sizes manually
180 ! step=(/ 1.00000000000000, ... , /)
181
182 select case (opti_function)
183 case (8)
184 call message(' Use MCMC')
185 call mcmc(eval, objective, local_parameters(:, 3), local_parameters(:, 1 : 2), mcmc_paras, burnin_paras, &
186 paraselectmode_in = 2_i4, tmp_file = tfile, &
187 maskpara_in = local_maskpara, &
188 restart = optimize_restart, restart_file = 'mo_mcmc.restart', &
189 ! stepsize_in=step, &
190 seed_in = iseed, loglike_in = .true., printflag_in = .true.)
191 case (4)
192 if (optimize_restart) then
193 call error_message('ERROR: A restart of this optimization method is not implemented yet!')
194 end if
195 call message(' Use MCMC_STDDEV')
196 call mcmc_stddev(eval, objective, local_parameters(:, 3), local_parameters(:, 1 : 2), mcmc_paras, burnin_paras, &
197 paraselectmode_in = 2_i4, tmp_file = tfile, &
198 maskpara_in = local_maskpara, &
199 seed_in = iseed, loglike_in = .true., printflag_in = .true.)
200 case default
201 call error_message("Error objective: This opti_function is either not implemented yet.")
202 end select
203
204 case (1)
205 call message(' Use DDS')
206
207 tfile = trim(adjustl(dirconfigout)) // 'dds_results.out'
208
209 if (optimize_restart) then
210 call error_message('ERROR: A restart of this optimization method is not implemented yet!')
211 end if
212 ! use fixed user-defined seed
213#ifdef MPI
214 local_parameters(:, 3) = dds(eval, objective, local_parameters(:, 3), local_parameters(:, 1 : 2), &
215 maxiter = int(niterations, i8), r = dds_r, seed = iseed, &
216 tmp_file = tfile, comm = domainmeta%comMaster, mask = local_maskpara, &
217 funcbest = funcbest)
218#else
219 local_parameters(:, 3) = dds(eval, objective, local_parameters(:, 3), local_parameters(:, 1 : 2), &
220 maxiter = int(niterations, i8), r = dds_r, seed = iseed, &
221 tmp_file = tfile, mask = local_maskpara, &
222 funcbest = funcbest)
223#endif
224
225 case (2)
226 call message(' Use Simulated Annealing')
227
228 tfile = trim(adjustl(dirconfigout)) // 'anneal_results.out'
229
230 if (optimize_restart) then
231 call error_message('ERROR: A restart of this optimization method is not implemented yet!')
232 end if
233
234 if (sa_temp .gt. 0.0_dp) then
235 ! use fixed user-defined seed and user-defined initial temperature
236 local_parameters(:, 3) = anneal(eval, objective, local_parameters(:, 3), local_parameters(:, 1 : 2), &
237 temp = sa_temp, seeds = (/iseed, iseed + 1000_i8, iseed + 2000_i8/), nitermax = niterations, &
238 tmp_file = tfile, maskpara = local_maskpara, &
239 funcbest = funcbest)
240 else
241 ! use fixed user-defined seed and adaptive initial temperature
242 local_parameters(:, 3) = anneal(eval, objective, local_parameters(:, 3), local_parameters(:, 1 : 2), &
243 seeds = (/iseed, iseed + 1000_i8, iseed + 2000_i8/), nitermax = niterations, &
244 tmp_file = tfile, maskpara = local_maskpara, &
245 funcbest = funcbest)
246 end if
247 case (3)
248 call message(' Use SCE')
249
250 tfile = trim(adjustl(dirconfigout)) // 'sce_results.out'
251 pfile = trim(adjustl(dirconfigout)) // 'sce_population.out'
252
253 ! use fixed user-defined seed
254 local_parameters(:, 3) = sce(eval, objective, local_parameters(:, 3), local_parameters(:, 1 : 2), &
255 mymaxn = int(niterations, i8), myseed = iseed, myngs = sce_ngs, mynpg = sce_npg, mynps = sce_nps, &
256 parallel = .false., mymask = local_maskpara, &
257 restart = optimize_restart, restart_file = 'mo_sce.restart', &
258#ifdef MPI
259 comm = domainmeta%comMaster, &
260#endif
261 tmp_file = tfile, popul_file = pfile, &
262 bestf = funcbest)
263 case default
264 call error_message('mRM', 'This optimization method is not implemented.')
265 end select
266 call timer_stop(itimer)
267 call message(' in ', trim(num2str(timer_get(itimer), '(F9.3)')), ' seconds.')
268
269 global_parameters(:, :) = local_parameters(1 : npara, :)
270 maskpara(:) = local_maskpara(1 : npara)
271
272 deallocate(local_parameters)
273 deallocate(local_maskpara)
274
275 end subroutine optimization
276
277end module mo_optimization
Provides structures needed by mHM, mRM and/or mpr.
real(dp), dimension(nerror_model), public mcmc_error_params
Provides structures needed by mHM, mRM and/or mpr.
real(dp), dimension(:, :), allocatable, target, public global_parameters
type(domain_meta), public domainmeta
character(256), public dirconfigout
Wrapper subroutine for optimization against runoff and sm.
subroutine, public optimization(eval, objective, dirconfigout, funcbest, maskpara)
Wrapper for optimization.