53 USE mo_kind,
ONLY : i4, dp
55 use mo_message,
only : message, error_message
63 PUBLIC :: objective_master, objective_subprocess
106 FUNCTION objective(parameterset, eval, arg1, arg2, arg3)
113 REAL(dp),
DIMENSION(:),
INTENT(IN) :: parameterset
117 real(dp),
optional,
intent(in) :: arg1
119 real(dp),
optional,
intent(out) :: arg2
121 real(dp),
optional,
intent(out) :: arg3
125 real(dp),
dimension(6) :: multiple_objective
128 if (
present(arg1) .or.
present(arg2) .or.
present(arg3))
then
129 call error_message(
"Error mo_objective_function: Received unexpected argument, check optimization settings")
133 if (
present(arg2))
then
136 if (
present(arg3))
then
218 call error_message(
"Error objective: opti_function not implemented yet.")
259 FUNCTION objective_master(parameterset, eval, arg1, arg2, arg3)
265 use mo_string_utils,
only : num2str
270 REAL(dp),
DIMENSION(:),
INTENT(IN) :: parameterset
274 real(dp),
optional,
intent(in) :: arg1
276 real(dp),
optional,
intent(out) :: arg2
278 real(dp),
optional,
intent(out) :: arg3
280 REAL(dp) :: objective_master
282 REAL(dp) :: partial_objective
284 real(dp),
dimension(6) :: multiple_partial_objective
286 real(dp),
dimension(6) :: multiple_master_objective
289 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
291 integer(i4) :: iproc, nproc
293 integer(i4) :: ierror
295 type(mpi_status) :: status
298 if (
present(arg1) .or.
present(arg2) .or.
present(arg3))
then
299 call error_message(
"Error mo_objective_function: Received unexpected argument, check optimization settings")
303 if (
present(arg2))
then
306 if (
present(arg3))
then
310 call distribute_parameterset(parameterset)
312 case (10 : 13, 17, 27 : 29)
313 call mpi_comm_size(
domainmeta%comMaster, nproc, ierror)
314 objective_master = 0.0_dp
315 do iproc = 1, nproc - 1
316 call mpi_recv(partial_objective, 1, mpi_double_precision, iproc, 0,
domainmeta%comMaster, status, ierror)
317 objective_master = objective_master + partial_objective
319 objective_master = objective_master**onesixth
322 call error_message(
"case 15, objective_kge_q_rmse_tws not implemented in parallel yet")
326 call message(
"case 30, objective_kge_q_rmse_et not implemented in parallel yet")
328 call mpi_comm_size(
domainmeta%comMaster, nproc, ierror)
329 objective_master = 0.0_dp
330 multiple_master_objective(:) = 0.0_dp
331 do iproc = 1, nproc - 1
332 call mpi_recv(multiple_partial_objective, 6, mpi_double_precision, iproc, 0,
domainmeta%comMaster, status, ierror)
333 multiple_master_objective = multiple_master_objective + multiple_partial_objective
335 objective_master = objective_master + &
336 (multiple_master_objective(1)+multiple_master_objective(2)+multiple_master_objective(3))
337 objective_master = (objective_master/multiple_master_objective(4))**onesixth
340 call error_message(
"Error objective_master: opti_function not implemented yet.")
345 call message(
' objective_sm_kge_catchment_avg = ', num2str(objective_master,
'(F9.5)'))
347 call message(
' objective_sm_pd = ', num2str(objective_master,
'(F9.5)'))
349 call message(
' objective_sm_sse_standard_score = ', num2str(objective_master,
'(E12.5)'))
351 call message(
' objective_sm_corr = ', num2str(objective_master,
'(F9.5)'))
353 call message(
' objective_neutrons_kge_catchment_avg = ', num2str(objective_master,
'(F9.5)'))
355 call message(
' objective_et_kge_catchment_avg = ', num2str(objective_master,
'(F9.5)'))
357 call message(
' objective_kge_q_sm_corr = ', num2str(objective_master,
'(F9.5)'))
359 call message(
' objective_kge_q_et = ', num2str(objective_master,
'(F9.5)'))
361 call message(
' objective_q_et_tws_kge_catchment_avg = ', num2str(objective_master,
'(F9.5)'))
363 call message(
' objective_spaef_sm = ', num2str(objective_master,
'(F9.5)'))
365 call message(
' objective_spaef_et = ', num2str(objective_master,
'(F9.5)'))
367 call message(
' objective_spaef_sm_spaef_et = ', num2str(objective_master,
'(F9.5)'))
369 call message(
' objective_spaef_sm_kge_q = ', num2str(objective_master,
'(F9.5)'))
371 call message(
' objective_spaef_et_kge_q = ', num2str(objective_master,
'(F9.5)'))
373 call message(
' objective_spaef_sm_spaef_et_kge_q = ', num2str(objective_master,
'(F9.5)'))
375 call message(
' objective_pd_et = ', num2str(objective_master,
'(F9.5)'))
377 call message(
' objective_pd_sm_pd_et = ', num2str(objective_master,
'(F9.5)'))
379 call message(
' objective_pd_sm_kge_q = ', num2str(objective_master,
'(F9.5)'))
381 call message(
' objective_pd_et_kge_q = ', num2str(objective_master,
'(F9.5)'))
383 call message(
' objective_pd_sm_pd_et_kge_q = ', num2str(objective_master,
'(F9.5)'))
385 call message(
' objective_ca_spf = ', num2str(objective_master,
'(F9.5)'))
387 call message(
' objective_ca_spf_kge_q = ', num2str(objective_master,
'(F9.5)'))
389 call error_message(
"Error objective_master: opti_function not implemented yet, this part of the code should never execute.")
392 END FUNCTION objective_master
432 subroutine objective_subprocess(eval, arg1, arg2, arg3)
444 real(dp),
optional,
intent(in) :: arg1
446 real(dp),
optional,
intent(out) :: arg2
448 real(dp),
optional,
intent(out) :: arg3
450 REAL(dp) :: partial_objective
452 real(dp),
dimension(6) :: multiple_partial_objective
454 REAL(dp),
DIMENSION(:),
allocatable :: parameterset
456 integer(i4) :: ierror
458 type(mpi_status) :: status
460 logical :: do_obj_loop
463 call mpi_recv(do_obj_loop, 1, mpi_logical, 0, 0,
domainmeta%comMaster, status, ierror)
465 if (.not. do_obj_loop)
exit
467 if (
present(arg1) .or.
present(arg2) .or.
present(arg3))
then
468 call error_message(
"Error mo_objective_function: Received unexpected argument, check optimization settings")
472 if (
present(arg2))
then
475 if (
present(arg3))
then
478 call get_parameterset(parameterset)
495 call error_message(
"Error objective_subprocess: case 15 not supported with MPI.")
511 call error_message(
"Error objective_subprocess: case 30 not supported with MPI.")
554 call error_message(
"Error objective_subprocess: opti_function not implemented yet.")
558 case (10 : 13, 17, 27 : 29, 35 : 47)
559 call mpi_send(partial_objective,1, mpi_double_precision,0,0,
domainmeta%comMaster,ierror)
561 call mpi_send(multiple_partial_objective, 6, mpi_double_precision,0,0,
domainmeta%comMaster,ierror)
563 call error_message(
"Error objective_subprocess: this part should not be executed -> error in the code.")
566 deallocate(parameterset)
569 END subroutine objective_subprocess
622 use mo_errormeasures,
only : kge
624 use mo_moment,
only : average
625 use mo_string_utils,
only : num2str
629 real(dp),
dimension(:),
intent(in) :: parameterset
636 integer(i4) :: idomain
642 integer(i4) :: n_time_steps
645 integer(i4) :: ncells1
648 real(dp) :: invalid_times
651 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
655 real(dp),
dimension(:),
allocatable :: sm_catch_avg_domain
658 real(dp),
dimension(:),
allocatable :: sm_opti_catch_avg_domain
660 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
663 logical,
dimension(:),
allocatable :: mask_times
667 call eval(parameterset, smoptisim = smoptisim)
676 ncells1 =
level1(idomain)%ncells
679 allocate(mask_times(
size(smoptisim(idomain)%dataSim, dim = 2)))
680 allocate(sm_catch_avg_domain(
size(smoptisim(idomain)%dataSim, dim = 2)))
681 allocate(sm_opti_catch_avg_domain(
size(smoptisim(idomain)%dataSim, dim = 2)))
688 invalid_times = 0.0_dp
690 n_time_steps =
size(smoptisim(idomain)%dataSim, dim = 2)
691 do itime = 1, n_time_steps
695 if (count(
l1_smobs(idomain)%maskObs(:, itime)) .LE. (0.10_dp * real(ncells1, dp)))
then
696 invalid_times = invalid_times + 1.0_dp
697 mask_times(itime) = .false.
700 sm_catch_avg_domain(itime) = average(
l1_smobs(idomain)%dataObs(:, itime), mask =
l1_smobs(idomain)%maskObs(:, itime))
701 sm_opti_catch_avg_domain(itime) = average(smoptisim(idomain)%dataSim(:, itime), mask =
l1_smobs(idomain)%maskObs(:, itime))
705 if (invalid_times .GT. 0.5_dp)
then
706 call message(.LT.
' WARNING: objective_sm: Detected invalid timesteps ( 10 valid data points).')
707 call message(
' Fraction of invalid timesteps: ', &
708 num2str(invalid_times / real(n_time_steps, dp),
'(F4.2)'))
715 ((1.0_dp - kge(sm_catch_avg_domain, sm_opti_catch_avg_domain, mask = mask_times)) / &
716 real(
domainmeta%overallnumberofdomains, dp))**6
719 deallocate(mask_times)
720 deallocate(sm_catch_avg_domain)
721 deallocate(sm_opti_catch_avg_domain)
722 call smoptisim(idomain)%destroy()
724 deallocate(smoptisim)
767 use mo_errormeasures,
only : kge
768 use mo_moment,
only : average
769 use mo_string_utils,
only : num2str
775 real(dp),
dimension(:),
intent(in) :: parameterset
783 integer(i4) :: idomain
789 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
794 real(dp),
allocatable,
dimension(:, :) :: runoff
796 integer(i4) :: ngaugestotal
799 real(dp),
dimension(:),
allocatable :: runoff_agg
802 real(dp),
dimension(:),
allocatable :: runoff_obs
805 logical,
dimension(:),
allocatable :: runoff_obs_mask
811 integer(i4) :: gg, icell
814 integer(i4) :: nqdomains
817 integer(i4) :: netdomains
820 integer(i4) :: ntwsdomains
823 integer(i4) :: nettwsdomains
826 integer(i4),
dimension(:),
allocatable :: opti_domain_indices_et
829 integer(i4),
dimension(:),
allocatable :: opti_domain_indices_tws
832 integer(i4),
dimension(:),
allocatable :: opti_domain_indices_et_tws
835 integer(i4),
dimension(:),
allocatable :: opti_domain_indices_q
838 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
841 type(
optidata_sim),
dimension(:),
allocatable :: twsoptisim
844 type(
optidata_sim),
dimension(:),
allocatable :: twsaoptisim
850 integer(i4) :: numberofsummands
866 if (nettwsdomains > 0)
then
870 call eval(parameterset, opti_domain_indices = opti_domain_indices_et_tws, &
871 twsoptisim = twsoptisim, etoptisim = etoptisim)
873 do i = 1,
size(opti_domain_indices_et_tws)
874 idomain = opti_domain_indices_et_tws(i)
876 do icell = 1,
size(
l1_etobs(idomain)%maskObs(:, :), dim = 1)
878 (1.0_dp - kge(
l1_etobs(idomain)%dataObs(icell, :), etoptisim(idomain)%dataSim(icell, :),&
879 mask =
l1_etobs(idomain)%maskObs(icell, :)))**6
880 numberofsummands = numberofsummands + 1
882 do icell = 1,
size(
l1_twsaobs(idomain)%maskObs(:, :), dim = 1)
883 kge_tws = kge_tws + &
884 (1.0_dp - kge(
l1_twsaobs(idomain)%dataObs(icell, :), twsaoptisim(idomain)%dataSim(icell, :),&
885 mask =
l1_twsaobs(idomain)%maskObs(icell, :)))**6
886 numberofsummands = numberofsummands + 1
889 call etoptisim(idomain)%destroy()
890 call twsoptisim(idomain)%destroy()
891 call twsaoptisim(idomain)%destroy()
893 deallocate(etoptisim)
894 deallocate(twsoptisim)
895 deallocate(twsaoptisim)
906 if (ntwsdomains > 0)
then
909 call eval(parameterset, opti_domain_indices = opti_domain_indices_tws, twsoptisim = twsoptisim)
911 do i = 1,
size(opti_domain_indices_tws)
912 idomain = opti_domain_indices_tws(i)
914 do icell = 1,
size(
l1_twsaobs(idomain)%maskObs(:, :), dim = 1)
915 kge_tws = kge_tws + &
916 (1.0_dp - kge(
l1_twsaobs(idomain)%dataObs(icell, :), twsaoptisim(idomain)%dataSim(icell, :),&
917 mask =
l1_twsaobs(idomain)%maskObs(icell, :)))**6
918 numberofsummands = numberofsummands + 1
920 call twsoptisim(idomain)%destroy()
922 deallocate(twsoptisim)
934 if (netdomains > 0)
then
936 call eval(parameterset, opti_domain_indices = opti_domain_indices_et, etoptisim = etoptisim)
938 do i = 1,
size(opti_domain_indices_et)
939 idomain = opti_domain_indices_et(i)
940 do icell = 1,
size(
l1_etobs(idomain)%maskObs(:, :), dim = 1)
942 (1.0_dp - kge(
l1_etobs(idomain)%dataObs(icell, :), etoptisim(idomain)%dataSim(icell, :),&
943 mask =
l1_etobs(idomain)%maskObs(icell, :)))**6
944 numberofsummands = numberofsummands + 1
946 call etoptisim(idomain)%destroy()
948 deallocate(etoptisim)
963 if (nqdomains > 0)
then
964 call eval(parameterset, opti_domain_indices = opti_domain_indices_q, runoff = runoff)
965 ngaugestotal =
size(runoff, dim = 2)
966 do gg = 1, ngaugestotal
969 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
972 (1.0_dp - kge(runoff_obs, runoff_agg, mask = runoff_obs_mask))**6
973 numberofsummands = numberofsummands + 1
974 deallocate (runoff_agg, runoff_obs, runoff_obs_mask)
986 call message(
' objective_q_et_tws_kge_catchment_avg = ', &
1024 integer(i4),
intent(in) :: optidataOption
1026 integer(i4),
intent(out) :: nOptiDomains
1028 integer(i4),
dimension(:),
allocatable,
intent(out) :: opti_domain_indices
1031 integer(i4) :: iDomain, i
1033 if (
allocated(opti_domain_indices))
deallocate(opti_domain_indices)
1036 do idomain = 1, domainmeta%nDomains
1037 if (domainmeta%optidata(idomain) == optidataoption) noptidomains = noptidomains + 1
1040 if (noptidomains > 0)
then
1041 allocate(opti_domain_indices(noptidomains))
1043 do idomain = 1, domainmeta%nDomains
1044 if (domainmeta%optidata(idomain) == optidataoption)
then
1046 opti_domain_indices(i) = idomain
1101 use mo_moment,
only : correlation
1102 use mo_string_utils,
only : num2str
1106 real(dp),
dimension(:),
intent(in) :: parameterset
1113 integer(i4) :: idomain
1116 integer(i4) :: icell
1119 integer(i4) :: ncells1
1122 real(dp) :: invalid_cells
1125 real(dp) :: objective_sm_corr_domain
1128 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
1131 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
1135 call eval(parameterset, smoptisim = smoptisim)
1144 objective_sm_corr_domain = 0.0_dp
1146 ncells1 =
level1(idomain)%ncells
1148 invalid_cells = 0.0_dp
1151 do icell = 1,
size(
l1_smobs(idomain)%maskObs(:, :), dim = 1)
1154 if (count(
l1_smobs(idomain)%maskObs(icell, :)) .LE. 0.10_dp * real(
size(
l1_smobs(idomain)%dataObs(:, :), dim = 2), dp))
then
1155 invalid_cells = invalid_cells + 1.0_dp
1158 objective_sm_corr_domain = objective_sm_corr_domain + &
1159 correlation(
l1_smobs(idomain)%dataObs(icell, :), smoptisim(idomain)%dataSim(icell, :), &
1160 mask =
l1_smobs(idomain)%maskObs(icell, :))
1164 if (invalid_cells .GT. 0.5_dp)
then
1165 call message(.LT.
' WARNING: objective_sm: Detected invalid cells in study area ( 10 valid data points).')
1166 call message(
' Fraction of invalid cells: ', &
1167 num2str(invalid_cells / real(ncells1, dp),
'(F4.2)'))
1174 ((1.0_dp - objective_sm_corr_domain / real(ncells1, dp)) / real(
domainmeta%overallNumberOfDomains, dp))**6
1235 use mo_spatialsimilarity,
only : pd
1236 use mo_string_utils,
only : num2str
1240 real(dp),
dimension(:),
intent(in) :: parameterset
1248 integer(i4) :: idomain
1251 integer(i4) :: itime
1254 integer(i4) :: nrows1, ncols1
1258 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
1262 real(dp),
dimension(:, :),
allocatable :: mat1, mat2
1265 real(dp),
dimension(:),
allocatable :: pd_time_series
1268 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
1271 logical,
dimension(:, :),
allocatable :: mask1
1274 logical,
dimension(:, :),
allocatable :: mask_sm
1277 logical,
dimension(:),
allocatable :: mask_times
1281 call eval(parameterset, smoptisim = smoptisim)
1290 mask1 =
level1(idomain)%mask
1291 ncols1 =
level1(idomain)%ncols
1292 nrows1 =
level1(idomain)%nrows
1295 allocate(mask_times(
size(smoptisim(idomain)%dataSim, dim = 2)))
1296 allocate(pd_time_series(
size(smoptisim(idomain)%dataSim, dim = 2)))
1297 allocate(mat1(nrows1, ncols1))
1298 allocate(mat2(nrows1, ncols1))
1299 allocate(mask_sm(nrows1, ncols1))
1302 mask_times = .false.
1303 pd_time_series = 0.0_dp
1306 do itime = 1,
size(smoptisim(idomain)%dataSim, dim = 2)
1308 mat2 = unpack(smoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
1309 mask_sm = unpack(
l1_smobs(idomain)%maskObs(:, itime), mask1, .false.)
1310 pd_time_series = pd(mat1, mat2, mask = mask_sm, valid = mask_times(itime))
1313 if (count(mask_times) > 0_i4)
then
1316 ((1.0_dp - sum(pd_time_series, mask = mask_times) / real(count(mask_times), dp)) / &
1317 real(
domainmeta%overallnumberofdomains, dp))**6
1319 call error_message(
'***ERROR: mo_objective_funtion: objective_sm_pd: No soil moisture observations available!')
1323 deallocate(mask_times)
1324 deallocate(pd_time_series)
1328 call smoptisim(idomain)%destroy()
1330 deallocate(smoptisim)
1335 call message(
' objective_sm_pd = ', num2str(
objective_sm_pd,
'(F9.5)'))
1387 use mo_errormeasures,
only : sse
1389 use mo_standard_score,
only : standard_score
1390 use mo_string_utils,
only : num2str
1394 real(dp),
dimension(:),
intent(in) :: parameterset
1401 integer(i4) :: idomain
1404 integer(i4) :: icell
1407 integer(i4) :: ncells1
1410 real(dp) :: invalid_cells
1413 real(dp) :: objective_sm_sse_standard_score_domain
1416 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
1420 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
1423 call eval(parameterset, smoptisim = smoptisim)
1432 objective_sm_sse_standard_score_domain = 0.0_dp
1434 ncells1 =
level1(idomain)%nCells
1436 invalid_cells = 0.0_dp
1438 do icell = 1,
size(
l1_smobs(idomain)%maskObs(:, :), dim = 1)
1441 if (count(
l1_smobs(idomain)%maskObs(icell, :)) .LE. (0.10_dp * real(
size(
l1_smobs(idomain)%dataObs, dim = 2), dp)))
then
1442 invalid_cells = invalid_cells + 1.0_dp
1445 objective_sm_sse_standard_score_domain = objective_sm_sse_standard_score_domain + &
1446 sse(standard_score(
l1_smobs(idomain)%dataObs(icell, :), mask =
l1_smobs(idomain)%maskObs(icell, :)), &
1447 standard_score(smoptisim(idomain)%dataSim(icell, :), mask =
l1_smobs(idomain)%maskObs(icell, :)), &
1448 mask =
l1_smobs(idomain)%maskObs(icell, :))
1453 if (invalid_cells .GT. 0.5_dp)
then
1454 call message(.LT.
' WARNING: objective_sm: Detected invalid cells in study area ( 10 valid data points).')
1455 call message(
' Fraction of invalid cells: ', &
1456 num2str(invalid_cells / real(ncells1, dp),
'(F4.2)'))
1462 (objective_sm_sse_standard_score_domain / real(
domainmeta%overallNumberOfDomains, dp))**6
1509 use mo_errormeasures,
only : rmse
1510 use mo_julian,
only : caldat
1511 use mo_moment,
only : mean
1512 use mo_standard_score,
only : classified_standard_score
1513 use mo_string_utils,
only : num2str
1514 use mo_temporal_aggregation,
only : day2mon_average
1515 use mo_errormeasures,
only : kge
1520 real(dp),
dimension(:),
intent(in) :: parameterset
1528 real(dp),
allocatable,
dimension(:, :) :: runoff
1531 type(
optidata_sim),
dimension(:),
allocatable :: twsoptisim
1534 integer(i4) :: domainid, idomain, pp, mmm
1536 integer(i4) :: year, month, day
1538 real(dp),
dimension(domainMeta%nDomains) :: inittime
1541 real(dp),
dimension(:),
allocatable :: tws_catch_avg_domain
1544 real(dp),
dimension(:),
allocatable :: tws_opti_catch_avg_domain
1547 logical,
dimension(:),
allocatable :: tws_obs_mask
1550 integer(i4) :: nmonths
1553 integer(i4),
dimension(:),
allocatable :: month_classes
1556 real(dp),
DIMENSION(:),
allocatable :: tws_sim_m_anom, tws_obs_m_anom
1559 real(dp),
dimension(:),
allocatable :: rmse_tws
1562 real(dp) :: rmse_tws_avg, kge_q_avg
1564 integer(i4) :: ngaugestotal
1567 real(dp),
dimension(:),
allocatable :: runoff_agg
1570 real(dp),
dimension(:),
allocatable :: runoff_obs
1573 logical,
dimension(:),
allocatable :: runoff_obs_mask
1576 real(dp),
dimension(:),
allocatable :: kge_q
1583 call eval(parameterset, runoff = runoff, twsoptisim = twsoptisim)
1594 if (.not. (
l1_twsaobs(idomain)%timeStepInput == -2))
then
1595 call message(
'objective_kge_q_rmse_tws: current implementation of this subroutine only allows monthly timesteps')
1602 call create_domain_avg_tws(idomain, twsoptisim, tws_catch_avg_domain, tws_opti_catch_avg_domain, tws_obs_mask)
1605 if (count(tws_obs_mask) .lt. 12 * 2)
then
1606 call message(
'objective_kge_q_rmse_tws: Length of TWS data of domain ', trim(adjustl(num2str(domainid))), &
1607 ' less than 2 years: this is not recommended')
1611 inittime(idomain) = real(
evalper(idomain)%julStart, dp)
1614 call caldat(int(inittime(idomain)), yy = year, mm = month, dd = day)
1616 nmonths =
size(tws_obs_mask)
1618 allocate (month_classes(nmonths))
1619 allocate (tws_obs_m_anom(nmonths))
1620 allocate (tws_sim_m_anom(nmonths))
1622 month_classes(:) = 0
1629 month_classes(pp) = mmm
1630 if (mmm .LT. 12)
then
1638 tws_obs_m_anom = classified_standard_score(tws_opti_catch_avg_domain, month_classes, mask = tws_obs_mask)
1639 tws_sim_m_anom = classified_standard_score(tws_catch_avg_domain, month_classes, mask = tws_obs_mask)
1640 rmse_tws(idomain) = rmse(tws_sim_m_anom, tws_obs_m_anom, mask = tws_obs_mask)
1642 deallocate (month_classes)
1643 deallocate (tws_sim_m_anom)
1644 deallocate (tws_obs_m_anom)
1645 deallocate (tws_catch_avg_domain, tws_opti_catch_avg_domain, tws_obs_mask)
1647 call twsoptisim(idomain)%destroy()
1650 rmse_tws_avg = sum(rmse_tws(:), abs(rmse_tws -
nodata_dp) .gt.
eps_dp) / &
1652 deallocate(rmse_tws)
1653 deallocate(twsoptisim)
1659 ngaugestotal =
size(runoff, dim = 2)
1660 allocate(kge_q(ngaugestotal))
1663 do gg = 1, ngaugestotal
1666 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
1669 pp = count(runoff_agg .ge. 0.0_dp)
1670 if (pp .lt. 365 * 2)
then
1671 call message(
'objective_kge_q_rmse_tws: The simulation at gauge ', trim(adjustl(num2str(gg))), &
1672 ' is not long enough. Please provide at least 730 days of data.')
1675 kge_q(gg) = kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
1676 deallocate (runoff_agg, runoff_obs, runoff_obs_mask)
1743 use mo_errormeasures,
only : kge
1745 use mo_moment,
only : average
1746 use mo_string_utils,
only : num2str
1750 real(dp),
dimension(:),
intent(in) :: parameterset
1757 integer(i4) :: idomain
1760 integer(i4) :: itime
1764 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
1768 real(dp),
dimension(:),
allocatable :: neutrons_catch_avg_domain
1771 real(dp),
dimension(:),
allocatable :: neutrons_opti_catch_avg_domain
1774 type(
optidata_sim),
dimension(:),
allocatable :: neutronsoptisim
1777 logical,
dimension(:),
allocatable :: mask_times
1780 allocate(neutronsoptisim(
domainmeta%nDomains))
1781 call eval(parameterset, neutronsoptisim = neutronsoptisim)
1790 allocate(mask_times(
size(neutronsoptisim(idomain)%dataSim, dim = 2)))
1791 allocate(neutrons_catch_avg_domain(
size(neutronsoptisim(idomain)%dataSim, dim = 2)))
1792 allocate(neutrons_opti_catch_avg_domain(
size(neutronsoptisim(idomain)%dataSim, dim = 2)))
1797 neutrons_opti_catch_avg_domain =
nodata_dp
1800 do itime = 1,
size(neutronsoptisim(idomain)%dataSim, dim = 2)
1804 call message(
'WARNING: neutrons data at time ', num2str(itime,
'(I10)'),
' is empty.')
1807 mask_times(itime) = .false.
1810 neutrons_catch_avg_domain(itime) = average(
l1_neutronsobs(idomain)%dataObs(:, itime), &
1812 neutrons_opti_catch_avg_domain(itime) = average(neutronsoptisim(idomain)%dataSim(:, itime), &
1819 ((1.0_dp - kge(neutrons_catch_avg_domain, neutrons_opti_catch_avg_domain, mask = mask_times)) / &
1820 real(
domainmeta%overallnumberofdomains, dp))**6
1823 deallocate(mask_times)
1824 deallocate(neutrons_catch_avg_domain)
1825 deallocate(neutrons_opti_catch_avg_domain)
1827 call neutronsoptisim(idomain)%destroy()
1829 deallocate(neutronsoptisim)
1889 use mo_errormeasures,
only : kge
1890 use mo_moment,
only : average
1891 use mo_string_utils,
only : num2str
1895 real(dp),
dimension(:),
intent(in) :: parameterset
1902 integer(i4) ::idomain
1906 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
1910 real(dp),
dimension(:),
allocatable :: et_catch_avg_domain
1913 real(dp),
dimension(:),
allocatable :: et_opti_catch_avg_domain
1916 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
1919 logical,
dimension(:),
allocatable :: mask_times
1922 call eval(parameterset, etoptisim = etoptisim)
1933 et_opti_catch_avg_domain, mask_times)
1938 ((1.0_dp - kge(et_catch_avg_domain, et_opti_catch_avg_domain, mask = mask_times)) / &
1939 real(
domainmeta%overallnumberofdomains, dp))**6
1942 deallocate(mask_times)
1943 deallocate(et_catch_avg_domain)
1944 deallocate(et_opti_catch_avg_domain)
1945 call etoptisim(idomain)%destroy()
1947 deallocate(etoptisim)
1990 use mo_moment,
only : correlation
1991 use mo_string_utils,
only : num2str
1992 use mo_errormeasures,
only : kge
1997 real(dp),
dimension(:),
intent(in) :: parameterset
2003 real(dp) :: objective_sm
2008 real(dp) :: invalid_cells
2012 real(dp),
allocatable,
dimension(:, :) :: runoff
2015 integer(i4) :: idomain
2018 integer(i4) :: icell
2021 integer(i4) :: ncells1
2024 real(dp) :: objective_sm_domain
2027 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
2029 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
2034 integer(i4) :: ngaugestotal
2037 real(dp),
dimension(:),
allocatable :: runoff_agg
2040 real(dp),
dimension(:),
allocatable :: runoff_obs
2043 logical,
dimension(:),
allocatable :: runoff_obs_mask
2047 call eval(parameterset, runoff = runoff, smoptisim = smoptisim)
2054 objective_sm = 0.0_dp
2060 objective_sm_domain = 0.0_dp
2062 ncells1 =
level1(idomain)%nCells
2065 invalid_cells = 0.0_dp
2066 do icell = 1,
size(
l1_smobs(idomain)%maskObs(:, :), dim = 1)
2069 if (count(
l1_smobs(idomain)%maskObs(icell, :)) .LE. (0.10_dp * real(
size(
l1_smobs(idomain)%dataObs, dim = 2), dp)))
then
2070 invalid_cells = invalid_cells + 1.0_dp
2075 objective_sm_domain = objective_sm_domain + &
2076 correlation(
l1_smobs(idomain)%dataObs(icell, :), smoptisim(idomain)%dataSim(icell, :), &
2077 mask =
l1_smobs(idomain)%maskObs(icell, :))
2081 if (invalid_cells .GT. 0.5_dp)
then
2082 call message(.LT.
' WARNING: objective_sm: Detected invalid cells in study area ( 10 valid data points).')
2083 call message(
' Fraction of invalid cells: ', &
2084 num2str(invalid_cells / real(ncells1, dp),
'(F4.2)'))
2089 objective_sm = objective_sm + &
2090 ((1.0_dp - objective_sm_domain / real(ncells1, dp)) / real(
domainmeta%overallNumberOfDomains, dp))**6
2091 call smoptisim(idomain)%destroy()
2093 deallocate(smoptisim)
2096 objective_sm = objective_sm**onesixth
2102 ngaugestotal =
size(runoff, dim = 2)
2104 do gg = 1, ngaugestotal
2107 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
2111 ((1.0_dp - kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)) / real(ngaugestotal, dp))**6
2115 deallocate(runoff_agg, runoff_obs, runoff_obs_mask)
2168 use mo_errormeasures,
only : kge
2170 use mo_string_utils,
only : num2str
2175 real(dp),
dimension(:),
intent(in) :: parameterset
2181 real(dp) :: objective_et
2183 real(dp) :: objective_q
2186 real(dp) :: invalid_cells
2190 real(dp),
allocatable,
dimension(:, :) :: runoff
2193 integer(i4) :: idomain
2196 integer(i4) :: icell
2199 integer(i4) :: ncells1
2202 real(dp) :: objective_et_domain
2205 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
2207 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
2212 integer(i4) :: ngaugestotal
2215 real(dp),
dimension(:),
allocatable :: runoff_agg
2218 real(dp),
dimension(:),
allocatable :: runoff_obs
2221 logical,
dimension(:),
allocatable :: runoff_obs_mask
2225 call eval(parameterset, runoff = runoff, etoptisim = etoptisim)
2232 objective_et = 0.0_dp
2238 objective_et_domain = 0.0_dp
2240 ncells1 =
level1(idomain)%nCells
2243 invalid_cells = 0.0_dp
2244 do icell = 1,
size(
l1_etobs(idomain)%maskObs, dim = 1)
2247 if (count(
l1_etobs(idomain)%maskObs(icell, :)) .LE. &
2248 (0.10_dp * real(
size(
l1_etobs(idomain)%dataObs(:, :), dim = 2), dp)))
then
2249 invalid_cells = invalid_cells + 1.0_dp
2254 objective_et_domain = objective_et_domain + &
2255 kge(
l1_etobs(idomain)%dataObs(icell, :), etoptisim(idomain)%dataSim(icell, :), &
2256 mask =
l1_etobs(idomain)%maskObs(icell, :))
2260 if (invalid_cells .GT. 0.5_dp)
then
2261 call message(.LT.
' WARNING: objective_et: Detected invalid cells in study area ( 10 valid data points).')
2262 call message(
' Fraction of invalid cells: ', &
2263 num2str(invalid_cells / real(ncells1, dp),
'(F4.2)'))
2268 objective_et = objective_et + &
2269 ((1.0_dp - objective_et_domain / real(ncells1, dp)) / real(
domainmeta%overallNumberOfDomains, dp))**6
2270 call etoptisim(idomain)%destroy()
2272 deallocate(etoptisim)
2275 objective_et = objective_et**onesixth
2280 objective_q = 0.0_dp
2281 ngaugestotal =
size(runoff, dim = 2)
2283 do gg = 1, ngaugestotal
2286 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
2289 objective_q = objective_q + &
2290 ((1.0_dp - kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)) / real(ngaugestotal, dp))**6
2294 deallocate(runoff_agg, runoff_obs, runoff_obs_mask)
2297 objective_q = objective_q**onesixth
2344 use mo_errormeasures,
only : kge
2346 use mo_string_utils,
only : num2str
2351 real(dp),
dimension(:),
intent(in) :: parameterset
2356 real(dp) :: objective_bfi
2357 real(dp) :: objective_q
2359 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
2362 real(dp) :: invalid_cells
2366 real(dp),
allocatable,
dimension(:, :) :: runoff
2369 integer(i4) :: idomain
2372 real(dp),
dimension(:),
allocatable :: bfi
2375 integer(i4) :: gg, i
2377 integer(i4) :: ngaugestotal
2380 integer(i4),
dimension(:),
allocatable :: domain_ids, domain_ids_pack
2383 real(dp),
dimension(:),
allocatable :: runoff_agg
2386 real(dp),
dimension(:),
allocatable :: runoff_obs
2389 logical,
dimension(:),
allocatable :: runoff_obs_mask
2393 call eval(parameterset, runoff = runoff, bfi = bfi)
2400 objective_bfi = 0.0_dp
2402 if ( any(
bfi_obs < 0.0_dp) )
then
2404 allocate(domain_ids_pack(count(
bfi_obs < 0.0_dp)))
2405 domain_ids = [(i, i=1,
size(domain_ids))]
2406 domain_ids_pack = pack(domain_ids, mask=(
bfi_obs < 0.0_dp))
2407 call error_message( &
2408 "objective_kge_q_BFI: missing BFI values for domain ", &
2409 trim(adjustl(num2str(domain_ids_pack(1)))) &
2415 objective_bfi = objective_bfi + abs(bfi(idomain) -
bfi_obs(idomain)) /
domainmeta%nDomains
2421 objective_q = 0.0_dp
2422 ngaugestotal =
size(runoff, dim = 2)
2424 do gg = 1, ngaugestotal
2427 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
2430 objective_q = objective_q + &
2431 ((1.0_dp - kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)) / real(ngaugestotal, dp))**6
2435 deallocate(runoff_agg, runoff_obs, runoff_obs_mask)
2438 objective_q = objective_q**onesixth
2478 use mo_errormeasures,
only : rmse
2480 use mo_julian,
only : caldat
2481 use mo_moment,
only : average, mean
2482 use mo_standard_score,
only : classified_standard_score
2483 use mo_string_utils,
only : num2str
2484 use mo_temporal_aggregation,
only : day2mon_average
2485 use mo_errormeasures,
only : kge
2490 real(dp),
dimension(:),
intent(in) :: parameterset
2498 real(dp),
allocatable,
dimension(:, :) :: runoff
2501 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
2504 integer(i4) :: itime
2507 integer(i4) :: idomain, pp, mmm
2509 integer(i4) :: year, month, day
2511 real(dp),
dimension(domainMeta%nDomains) :: inittime
2514 integer(i4) :: nmonths
2517 integer(i4),
dimension(:),
allocatable :: month_classes
2520 real(dp),
dimension(:),
allocatable :: et_sim_m, et_obs_m
2523 real(dp),
dimension(:),
allocatable :: et_sim_m_anom, et_obs_m_anom
2525 logical,
dimension(:),
allocatable :: et_obs_m_mask
2528 real(dp),
dimension(:),
allocatable :: rmse_et
2531 real(dp) :: rmse_et_avg, kge_q_avg
2534 real(dp),
dimension(:),
allocatable :: et_catch_avg_domain
2537 real(dp),
dimension(:),
allocatable :: et_opti_catch_avg_domain
2540 logical,
dimension(:),
allocatable :: mask_times
2543 real(dp),
dimension(:),
allocatable :: kge_q
2548 integer(i4) :: ngaugestotal
2551 real(dp),
dimension(:),
allocatable :: runoff_agg
2554 real(dp),
dimension(:),
allocatable :: runoff_obs
2557 logical,
dimension(:),
allocatable :: runoff_obs_mask
2563 call eval(parameterset, runoff = runoff, etoptisim = etoptisim)
2576 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
2577 allocate(et_catch_avg_domain(
size(etoptisim(idomain)%dataSim, dim = 2)))
2578 allocate(et_opti_catch_avg_domain(
size(etoptisim(idomain)%dataSim, dim = 2)))
2586 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
2588 if (all(.NOT.
l1_etobs(idomain)%maskObs(:, itime)))
then
2592 mask_times(itime) = .false.
2596 et_catch_avg_domain(itime) = average(
l1_etobs(idomain)%dataObs(:, itime), &
2597 mask =
l1_etobs(idomain)%maskObs(:, itime))
2599 et_opti_catch_avg_domain(itime) = average(etoptisim(idomain)%dataSim(:, itime), &
2600 mask =
l1_etobs(idomain)%maskObs(:, itime))
2604 inittime(idomain) = real(
evalper(idomain)%julStart, dp)
2607 call caldat(int(inittime(idomain)), yy = year, mm = month, dd = day)
2610 select case(
l1_etobs(idomain)%timeStepInput)
2615 call day2mon_average(et_opti_catch_avg_domain, year, month, day, et_sim_m, misval =
nodata_dp)
2617 call day2mon_average(et_catch_avg_domain, year, month, day, et_obs_m, misval =
nodata_dp)
2622 allocate(et_sim_m(
size(etoptisim(idomain)%dataSim, dim = 2)))
2623 et_sim_m = et_opti_catch_avg_domain
2625 allocate(et_obs_m(
size(etoptisim(idomain)%dataSim, dim = 2)))
2626 et_obs_m = et_catch_avg_domain
2630 call error_message(
'***ERROR: objective_kge_q_rmse_et: time step of evapotranspiration yearly.')
2633 et_sim_m(:) = et_sim_m(:) - mean(et_sim_m(:))
2635 et_obs_m(:) = et_obs_m(:) - mean(et_obs_m(:))
2637 nmonths =
size(et_obs_m)
2638 allocate (month_classes(nmonths))
2639 allocate (et_obs_m_mask(nmonths))
2640 allocate (et_obs_m_anom(nmonths))
2641 allocate (et_sim_m_anom(nmonths))
2643 month_classes(:) = 0
2644 et_obs_m_mask(:) = .true.
2651 month_classes(pp) = mmm
2652 if (mmm .LT. 12)
then
2663 et_obs_m_anom = classified_standard_score(et_obs_m, month_classes, mask = et_obs_m_mask)
2664 et_sim_m_anom = classified_standard_score(et_sim_m, month_classes, mask = et_obs_m_mask)
2665 rmse_et(idomain) = rmse(et_sim_m_anom, et_obs_m_anom, mask = et_obs_m_mask)
2667 deallocate (month_classes)
2668 deallocate (et_obs_m)
2669 deallocate (et_sim_m)
2670 deallocate (et_obs_m_mask)
2671 deallocate (et_sim_m_anom)
2672 deallocate (et_obs_m_anom)
2675 call etoptisim(idomain)%destroy()
2678 rmse_et_avg = sum(rmse_et(:), abs(rmse_et -
nodata_dp) .gt.
eps_dp) / &
2681 deallocate(etoptisim)
2687 ngaugestotal =
size(runoff, dim = 2)
2688 allocate(kge_q(ngaugestotal))
2691 do gg = 1, ngaugestotal
2694 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
2704 kge_q(gg) = kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
2705 deallocate (runoff_agg, runoff_obs, runoff_obs_mask)
2761 use mo_message,
only : message
2762 use mo_errormeasures,
only : spaef
2763 use mo_string_utils,
only : num2str
2767 real(dp),
dimension(:),
intent(in) :: parameterset
2775 integer(i4) :: idomain
2778 integer(i4) :: itime
2782 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
2786 real(dp),
dimension(:),
allocatable :: vec1, vec2
2789 real(dp),
dimension(:),
allocatable :: spaef_time_series
2792 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
2795 logical,
dimension(:),
allocatable :: mask_sm
2798 logical,
dimension(:),
allocatable :: mask_times
2802 call eval(parameterset, smoptisim = smoptisim)
2811 allocate(mask_times(
size(smoptisim(idomain)%dataSim, dim = 2)))
2812 allocate(spaef_time_series(
size(smoptisim(idomain)%dataSim, dim = 2)))
2813 allocate(vec1(
size(smoptisim(idomain)%dataSim, dim = 1)))
2814 allocate(vec2(
size(smoptisim(idomain)%dataSim, dim = 1)))
2815 allocate(mask_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
2818 mask_times = .false.
2819 spaef_time_series = 0.0_dp
2822 do itime = 1,
size(smoptisim(idomain)%dataSim, dim = 2)
2823 vec1 =
l1_smobs(idomain)%dataObs(:, itime)
2824 vec2 = smoptisim(idomain)%dataSim(:, itime)
2825 mask_sm =
l1_smobs(idomain)%maskObs(:, itime)
2826 if (count(mask_sm) > 1_i4)
then
2827 mask_times(itime) = .true.
2828 spaef_time_series(itime) = spaef(vec1, vec2, mask = mask_sm)
2832 if (count(mask_times) > 0_i4)
then
2835 ((1.0_dp - sum(spaef_time_series, mask = mask_times) / real(count(mask_times), dp)) / &
2836 real(
domainmeta%overallnumberofdomains, dp))**6
2838 call message(
'***ERROR: mo_objective_funtion: objective_spaef_sm: No soil moisture observations available!')
2843 deallocate(mask_times)
2844 deallocate(spaef_time_series)
2848 call smoptisim(idomain)%destroy()
2850 deallocate(smoptisim)
2900 use mo_message,
only : message
2901 use mo_errormeasures,
only : spaef
2902 use mo_string_utils,
only : num2str
2906 real(dp),
dimension(:),
intent(in) :: parameterset
2914 integer(i4) :: idomain
2917 integer(i4) :: itime
2921 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
2925 real(dp),
dimension(:),
allocatable :: vec1, vec2
2928 real(dp),
dimension(:),
allocatable :: spaef_time_series
2931 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
2934 logical,
dimension(:),
allocatable :: mask_et
2937 logical,
dimension(:),
allocatable :: mask_times
2941 call eval(parameterset, etoptisim = etoptisim)
2950 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
2951 allocate(spaef_time_series(
size(etoptisim(idomain)%dataSim, dim = 2)))
2952 allocate(vec1(
size(etoptisim(idomain)%dataSim, dim = 1)))
2953 allocate(vec2(
size(etoptisim(idomain)%dataSim, dim = 1)))
2954 allocate(mask_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
2957 mask_times = .false.
2958 spaef_time_series = 0.0_dp
2961 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
2962 vec1 =
l1_etobs(idomain)%dataObs(:, itime)
2963 vec2 = etoptisim(idomain)%dataSim(:, itime)
2964 mask_et =
l1_etobs(idomain)%maskObs(:, itime)
2965 if (count(mask_et) > 1_i4)
then
2966 mask_times(itime) = .true.
2967 spaef_time_series(itime) = spaef(vec1, vec2, mask = mask_et)
2971 if (count(mask_times) > 0_i4)
then
2974 ((1.0_dp - sum(spaef_time_series, mask = mask_times) / real(count(mask_times), dp)) / &
2975 real(
domainmeta%overallnumberofdomains, dp))**6
2977 call message(
'***ERROR: mo_objective_funtion: objective_spaef_et: No ET observations available!')
2982 deallocate(mask_times)
2983 deallocate(spaef_time_series)
2987 call etoptisim(idomain)%destroy()
2989 deallocate(etoptisim)
3039 use mo_message,
only : message
3040 use mo_errormeasures,
only : spaef
3041 use mo_string_utils,
only : num2str
3045 real(dp),
dimension(:),
intent(in) :: parameterset
3053 integer(i4) :: idomain
3056 integer(i4) :: itime
3060 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
3064 real(dp),
dimension(:),
allocatable :: vec1_sm, vec2_sm, vec1_et, vec2_et
3067 real(dp),
dimension(:),
allocatable :: spaef_time_series_sm, spaef_time_series_et
3070 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
3073 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
3076 logical,
dimension(:),
allocatable :: mask_et, mask_sm
3079 logical,
dimension(:),
allocatable :: mask_times
3084 call eval(parameterset, smoptisim = smoptisim, etoptisim = etoptisim)
3093 if (
size(etoptisim(idomain)%dataSim, dim = 2) /=
size(smoptisim(idomain)%dataSim, dim = 2))
then
3094 call message(
'***ERROR: mo_objective_funtion: objective_spaef_sm_spaef_et: The time dimension of SM (', &
3095 trim(num2str(
size(smoptisim(idomain)%dataSim, dim = 2))),
') and ET (', &
3096 trim(num2str(
size(etoptisim(idomain)%dataSim, dim = 2))),
') are not equal for domain ', &
3097 trim(num2str(idomain)), &
3098 '. Are both of them at same temporal resolution?')
3103 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
3104 allocate(spaef_time_series_sm(
size(etoptisim(idomain)%dataSim, dim = 2)))
3105 allocate(spaef_time_series_et(
size(etoptisim(idomain)%dataSim, dim = 2)))
3107 allocate(vec1_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3108 allocate(vec2_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3109 allocate(mask_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3111 allocate(vec1_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3112 allocate(vec2_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3113 allocate(mask_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3116 mask_times = .false.
3117 spaef_time_series_sm = 0.0_dp
3118 spaef_time_series_et = 0.0_dp
3121 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
3123 vec1_et =
l1_etobs(idomain)%dataObs(:, itime)
3124 vec2_et = etoptisim(idomain)%dataSim(:, itime)
3125 mask_et =
l1_etobs(idomain)%maskObs(:, itime)
3127 vec1_sm =
l1_smobs(idomain)%dataObs(:, itime)
3128 vec2_sm = smoptisim(idomain)%dataSim(:, itime)
3129 mask_sm =
l1_smobs(idomain)%maskObs(:, itime)
3131 if (count(mask_et) > 1_i4 .and. count(mask_sm) > 1_i4)
then
3132 mask_times(itime) = .true.
3133 spaef_time_series_sm(itime) = spaef(vec1_sm, vec2_sm, mask = mask_sm)
3134 spaef_time_series_et(itime) = spaef(vec1_et, vec2_et, mask = mask_et)
3138 if (count(mask_times) > 0_i4)
then
3143 0.5 * sum(spaef_time_series_sm, mask = mask_times) + &
3144 0.5 * sum(spaef_time_series_et, mask = mask_times) &
3145 ) / real(count(mask_times), dp) &
3146 ) / real(
domainmeta%overallNumberOfDomains, dp) &
3148 call message(
' spaef_sm = ', &
3149 & num2str(sum(spaef_time_series_sm, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
3150 &
' for domain ', num2str(idomain))
3151 call message(
' spaef_et = ', &
3152 & num2str(sum(spaef_time_series_et, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
3153 &
' for domain ', num2str(idomain))
3155 call message(
'***ERROR: mo_objective_funtion: objective_spaef_sm_spaef_et: No SM and/or ET observations available!')
3160 deallocate(mask_times)
3161 deallocate(spaef_time_series_sm, spaef_time_series_et)
3162 deallocate(vec1_sm, vec1_et)
3163 deallocate(vec2_sm, vec2_et)
3164 deallocate(mask_et, mask_sm)
3165 call smoptisim(idomain)%destroy()
3166 call etoptisim(idomain)%destroy()
3168 deallocate(etoptisim)
3169 deallocate(smoptisim)
3218 use mo_message,
only : message
3219 use mo_errormeasures,
only : spaef, kge
3220 use mo_string_utils,
only : num2str
3226 real(dp),
dimension(:),
intent(in) :: parameterset
3232 real(dp) :: objective_kgestreamflow
3235 integer(i4) :: idomain, jdomain
3238 integer(i4) :: itime
3242 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
3246 real(dp),
dimension(:),
allocatable :: vec1_sm, vec2_sm
3249 real(dp),
dimension(:),
allocatable :: spaef_time_series_sm
3253 real(dp),
allocatable,
dimension(:, :) :: runoff
3256 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
3259 logical,
dimension(:),
allocatable :: mask_sm
3262 logical,
dimension(:),
allocatable :: mask_times
3269 real(dp),
dimension(:),
allocatable :: runoff_obs
3272 real(dp),
dimension(:),
allocatable :: runoff_agg
3275 logical,
dimension(:),
allocatable :: runoff_obs_mask
3280 call eval(parameterset, smoptisim = smoptisim, runoff = runoff)
3290 allocate(mask_times(
size(smoptisim(idomain)%dataSim, dim = 2)))
3291 allocate(spaef_time_series_sm(
size(smoptisim(idomain)%dataSim, dim = 2)))
3293 allocate(vec1_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3294 allocate(vec2_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3295 allocate(mask_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3298 mask_times = .false.
3299 spaef_time_series_sm = 0.0_dp
3300 objective_kgestreamflow = 0.0_dp
3303 do itime = 1,
size(smoptisim(idomain)%dataSim, dim = 2)
3305 vec1_sm =
l1_smobs(idomain)%dataObs(:, itime)
3306 vec2_sm = smoptisim(idomain)%dataSim(:, itime)
3307 mask_sm =
l1_smobs(idomain)%maskObs(:, itime)
3309 if (count(mask_sm) > 1_i4)
then
3310 mask_times(itime) = .true.
3311 spaef_time_series_sm(itime) = spaef(vec1_sm, vec2_sm, mask = mask_sm)
3318 jdomain =
gauge%domainId(gg)
3320 if (idomain == jdomain)
then
3322 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
3324 objective_kgestreamflow = objective_kgestreamflow + &
3325 kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
3328 objective_kgestreamflow = objective_kgestreamflow / real(
ngaugestotal, dp)
3331 if (count(mask_times) > 0_i4)
then
3336 wt_for_optional_data * sum(spaef_time_series_sm, mask = mask_times) / real(count(mask_times), dp) + &
3338 ) / real(
domainmeta%overallNumberOfDomains, dp) &
3340 call message(
' spaef_sm = ', &
3341 & num2str(sum(spaef_time_series_sm, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
3342 &
' for domain ', num2str(idomain))
3343 call message(
' kge_q = ', num2str(objective_kgestreamflow,
'(F9.5)'),
' for domain ', num2str(idomain))
3345 call message(
'***ERROR: mo_objective_funtion: objective_spaef_sm_kge_q: No SM observations available!')
3350 deallocate(mask_times)
3351 deallocate(spaef_time_series_sm)
3355 deallocate(runoff_agg, runoff_obs, runoff_obs_mask)
3356 call smoptisim(idomain)%destroy()
3358 deallocate(smoptisim)
3409 use mo_message,
only : message
3410 use mo_errormeasures,
only : spaef, kge
3411 use mo_string_utils,
only : num2str
3417 real(dp),
dimension(:),
intent(in) :: parameterset
3423 real(dp) :: objective_kgestreamflow
3426 integer(i4) :: idomain, jdomain
3429 integer(i4) :: itime
3433 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
3437 real(dp),
dimension(:),
allocatable :: vec1_et, vec2_et
3440 real(dp),
dimension(:),
allocatable :: spaef_time_series_et
3444 real(dp),
allocatable,
dimension(:, :) :: runoff
3447 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
3450 logical,
dimension(:),
allocatable :: mask_et
3453 logical,
dimension(:),
allocatable :: mask_times
3460 real(dp),
dimension(:),
allocatable :: runoff_obs
3463 real(dp),
dimension(:),
allocatable :: runoff_agg
3466 logical,
dimension(:),
allocatable :: runoff_obs_mask
3471 call eval(parameterset, etoptisim = etoptisim, runoff = runoff)
3481 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
3482 allocate(spaef_time_series_et(
size(etoptisim(idomain)%dataSim, dim = 2)))
3484 allocate(vec1_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3485 allocate(vec2_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3486 allocate(mask_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3489 mask_times = .false.
3490 spaef_time_series_et = 0.0_dp
3491 objective_kgestreamflow = 0.0_dp
3492 ngaugesdomain = 0._i4
3495 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
3497 vec1_et =
l1_etobs(idomain)%dataObs(:, itime)
3498 vec2_et = etoptisim(idomain)%dataSim(:, itime)
3499 mask_et =
l1_etobs(idomain)%maskObs(:, itime)
3501 if (count(mask_et) > 1_i4)
then
3502 mask_times(itime) = .true.
3503 spaef_time_series_et(itime) = spaef(vec1_et, vec2_et, mask = mask_et)
3510 jdomain =
gauge%domainId(gg)
3512 if (idomain == jdomain)
then
3514 ngaugesdomain = ngaugesdomain + 1_i4
3516 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
3518 objective_kgestreamflow = objective_kgestreamflow + &
3519 kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
3522 objective_kgestreamflow = objective_kgestreamflow / real(ngaugesdomain, dp)
3525 if (count(mask_times) > 0_i4)
then
3530 wt_for_optional_data * sum(spaef_time_series_et, mask = mask_times) / real(count(mask_times), dp) + &
3532 ) / real(
domainmeta%overallNumberOfDomains, dp) &
3534 call message(
' spaef_et = ', &
3535 & num2str(sum(spaef_time_series_et, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
3536 &
' for domain ', num2str(idomain))
3537 call message(
' kge_q = ', num2str(objective_kgestreamflow,
'(F9.5)'),
' for domain ', num2str(idomain))
3539 call message(
'***ERROR: mo_objective_funtion: objective_spaef_et_kge_q: No ET observations available!')
3544 deallocate(mask_times)
3545 deallocate(spaef_time_series_et)
3549 deallocate(runoff_agg, runoff_obs, runoff_obs_mask)
3550 call etoptisim(idomain)%destroy()
3552 deallocate(etoptisim)
3602 use mo_message,
only : message
3603 use mo_errormeasures,
only : spaef, kge
3604 use mo_string_utils,
only : num2str
3610 real(dp),
dimension(:),
intent(in) :: parameterset
3616 real(dp) :: objective_kgestreamflow
3619 integer(i4) :: idomain, jdomain
3622 integer(i4) :: itime
3626 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
3630 real(dp),
dimension(:),
allocatable :: vec1_et, vec2_et, vec1_sm, vec2_sm
3633 real(dp),
dimension(:),
allocatable :: spaef_time_series_et, spaef_time_series_sm
3637 real(dp),
allocatable,
dimension(:, :) :: runoff
3640 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim, smoptisim
3643 logical,
dimension(:),
allocatable :: mask_et, mask_sm
3646 logical,
dimension(:),
allocatable :: mask_times
3653 real(dp),
dimension(:),
allocatable :: runoff_obs
3656 real(dp),
dimension(:),
allocatable :: runoff_agg
3659 logical,
dimension(:),
allocatable :: runoff_obs_mask
3665 call eval(parameterset, smoptisim = smoptisim, etoptisim = etoptisim, runoff = runoff)
3675 if (
size(etoptisim(idomain)%dataSim, dim = 2) /=
size(smoptisim(idomain)%dataSim, dim = 2))
then
3676 call message(
'***ERROR: mo_objective_funtion: objective_spaef_sm_spaef_et: The time dimension of SM (', &
3677 trim(num2str(
size(smoptisim(idomain)%dataSim, dim = 2))),
') and ET (', &
3678 trim(num2str(
size(etoptisim(idomain)%dataSim, dim = 2))),
') are not equal for domain ', &
3679 trim(num2str(idomain)), &
3680 '. Are both of them at same temporal resolution?')
3685 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
3686 allocate(spaef_time_series_et(
size(etoptisim(idomain)%dataSim, dim = 2)))
3687 allocate(spaef_time_series_sm(
size(smoptisim(idomain)%dataSim, dim = 2)))
3689 allocate(vec1_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3690 allocate(vec2_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3691 allocate(mask_et(
size(etoptisim(idomain)%dataSim, dim = 1)))
3693 allocate(vec1_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3694 allocate(vec2_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3695 allocate(mask_sm(
size(smoptisim(idomain)%dataSim, dim = 1)))
3698 mask_times = .false.
3699 spaef_time_series_sm = 0.0_dp
3700 spaef_time_series_et = 0.0_dp
3701 objective_kgestreamflow = 0.0_dp
3702 ngaugesdomain = 0._i4
3705 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
3707 vec1_sm =
l1_smobs(idomain)%dataObs(:, itime)
3708 vec2_sm = smoptisim(idomain)%dataSim(:, itime)
3709 mask_sm =
l1_smobs(idomain)%maskObs(:, itime)
3711 vec1_et =
l1_etobs(idomain)%dataObs(:, itime)
3712 vec2_et = etoptisim(idomain)%dataSim(:, itime)
3713 mask_et =
l1_etobs(idomain)%maskObs(:, itime)
3715 if (count(mask_sm) > 1_i4 .and. count(mask_et) > 1_i4)
then
3716 mask_times(itime) = .true.
3717 spaef_time_series_sm(itime) = spaef(vec1_sm, vec2_sm, mask = mask_sm)
3718 spaef_time_series_et(itime) = spaef(vec1_et, vec2_et, mask = mask_et)
3725 jdomain =
gauge%domainId(gg)
3727 if (idomain == jdomain)
then
3729 ngaugesdomain = ngaugesdomain + 1_i4
3731 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
3733 objective_kgestreamflow = objective_kgestreamflow + &
3734 kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
3737 objective_kgestreamflow = objective_kgestreamflow / real(ngaugesdomain, dp)
3740 if (count(mask_times) > 0_i4)
then
3745 0.5 *
wt_for_optional_data * sum(spaef_time_series_sm, mask = mask_times) / real(count(mask_times), dp) + &
3746 0.5 *
wt_for_optional_data * sum(spaef_time_series_et, mask = mask_times) / real(count(mask_times), dp) + &
3748 ) / real(
domainmeta%overallNumberOfDomains, dp) &
3750 call message(
' spaef_sm = ', &
3751 & num2str(sum(spaef_time_series_sm, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
3752 &
' for domain ', num2str(idomain))
3753 call message(
' spaef_et = ', &
3754 & num2str(sum(spaef_time_series_et, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
3755 &
' for domain ', num2str(idomain))
3756 call message(
' kge_q = ', num2str(objective_kgestreamflow,
'(F9.5)'),
' for domain ', num2str(idomain))
3759 call message(
'***ERROR: mo_objective_funtion: objective_spaef_sm_spaef_et_kge_q: No SM and/or ET observations available!')
3764 deallocate(mask_times)
3765 deallocate(spaef_time_series_et, spaef_time_series_sm)
3766 deallocate(vec1_et, vec1_sm)
3767 deallocate(vec2_et, vec2_sm)
3768 deallocate(mask_et, mask_sm)
3769 deallocate(runoff_agg, runoff_obs, runoff_obs_mask)
3770 call smoptisim(idomain)%destroy()
3771 call etoptisim(idomain)%destroy()
3773 deallocate(smoptisim)
3774 deallocate(etoptisim)
3837 use mo_message,
only : message
3838 use mo_spatialsimilarity,
only : pd
3839 use mo_string_utils,
only : num2str
3843 real(dp),
dimension(:),
intent(in) :: parameterset
3851 integer(i4) :: idomain
3854 integer(i4) :: itime
3857 integer(i4) :: nrows1, ncols1
3861 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
3865 real(dp),
dimension(:, :),
allocatable :: mat1, mat2
3868 real(dp),
dimension(:),
allocatable :: pd_time_series
3871 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
3874 logical,
dimension(:, :),
allocatable :: mask1
3877 logical,
dimension(:, :),
allocatable :: mask_et
3880 logical,
dimension(:),
allocatable :: mask_times
3884 call eval(parameterset, etoptisim = etoptisim)
3893 mask1 =
level1(idomain)%mask
3894 ncols1 =
level1(idomain)%ncols
3895 nrows1 =
level1(idomain)%nrows
3898 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
3899 allocate(pd_time_series(
size(etoptisim(idomain)%dataSim, dim = 2)))
3900 allocate(mat1(nrows1, ncols1))
3901 allocate(mat2(nrows1, ncols1))
3902 allocate(mask_et(nrows1, ncols1))
3905 mask_times = .false.
3906 pd_time_series = 0.0_dp
3909 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
3911 mat2 = unpack(etoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
3912 mask_et = unpack(
l1_etobs(idomain)%maskObs(:, itime), mask1, .false.)
3913 pd_time_series = pd(mat1, mat2, mask = mask_et, valid = mask_times(itime))
3916 if (count(mask_times) > 0_i4)
then
3919 ((1.0_dp - sum(pd_time_series, mask = mask_times) / real(count(mask_times), dp)) / &
3920 real(
domainmeta%overallnumberofdomains, dp))**6
3922 call message(
'***ERROR: mo_objective_funtion: objective_pd_et: No ET observations available!')
3927 deallocate(mask_times)
3928 deallocate(pd_time_series)
3932 call etoptisim(idomain)%destroy()
3934 deallocate(etoptisim)
3939 call message(
' objective_pd_et = ', num2str(
objective_pd_et,
'(F9.5)'))
3981 use mo_message,
only : message
3982 use mo_spatialsimilarity,
only : pd
3983 use mo_string_utils,
only : num2str
3987 real(dp),
dimension(:),
intent(in) :: parameterset
3995 integer(i4) :: idomain
3998 integer(i4) :: itime
4001 integer(i4) :: nrows1, ncols1
4005 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
4009 real(dp),
dimension(:, :),
allocatable :: mat1_sm, mat2_sm, mat1_et, mat2_et
4012 real(dp),
dimension(:),
allocatable :: pd_time_series_sm, pd_time_series_et
4015 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
4018 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
4021 logical,
dimension(:, :),
allocatable :: mask1
4024 logical,
dimension(:, :),
allocatable :: mask_et, mask_sm
4027 logical,
dimension(:),
allocatable :: mask_times
4032 call eval(parameterset, smoptisim = smoptisim, etoptisim = etoptisim)
4041 if (
size(etoptisim(idomain)%dataSim, dim = 2) /=
size(smoptisim(idomain)%dataSim, dim = 2))
then
4042 call message(
'***ERROR: mo_objective_funtion: objective_pd_sm_pd_et: The time dimension of SM (', &
4043 trim(num2str(
size(smoptisim(idomain)%dataSim, dim = 2))),
') and ET (', &
4044 trim(num2str(
size(etoptisim(idomain)%dataSim, dim = 2))),
') are not equal for domain ', &
4045 trim(num2str(idomain)), &
4046 '. Are both of them at same temporal resolution?')
4051 mask1 =
level1(idomain)%mask
4052 ncols1 =
level1(idomain)%ncols
4053 nrows1 =
level1(idomain)%nrows
4056 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
4057 allocate(pd_time_series_sm(
size(smoptisim(idomain)%dataSim, dim = 2)))
4058 allocate(pd_time_series_et(
size(etoptisim(idomain)%dataSim, dim = 2)))
4060 allocate(mat1_sm(nrows1, ncols1))
4061 allocate(mat2_sm(nrows1, ncols1))
4062 allocate(mask_sm(nrows1, ncols1))
4064 allocate(mat1_et(nrows1, ncols1))
4065 allocate(mat2_et(nrows1, ncols1))
4066 allocate(mask_et(nrows1, ncols1))
4069 mask_times = .false.
4070 pd_time_series_sm = 0.0_dp
4071 pd_time_series_et = 0.0_dp
4074 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
4077 mat2_sm = unpack(smoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
4078 mask_sm = unpack(
l1_smobs(idomain)%maskObs(:, itime), mask1, .false.)
4079 pd_time_series_sm = pd(mat1_sm, mat2_sm, mask = mask_sm, valid = mask_times(itime))
4082 mat2_et = unpack(etoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
4083 mask_et = unpack(
l1_etobs(idomain)%maskObs(:, itime), mask1, .false.)
4084 pd_time_series_et = pd(mat1_et, mat2_et, mask = mask_et, valid = mask_times(itime))
4088 if (count(mask_times) > 0_i4)
then
4093 0.5 * sum(pd_time_series_sm, mask = mask_times) + &
4094 0.5 * sum(pd_time_series_et, mask = mask_times) &
4095 ) / real(count(mask_times), dp) &
4096 ) / real(
domainmeta%overallNumberOfDomains, dp) &
4098 call message(
' pd_sm = ', &
4099 & num2str(sum(pd_time_series_sm, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
4100 &
' for domain ', num2str(idomain))
4101 call message(
' pd_et = ', &
4102 & num2str(sum(pd_time_series_et, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
4103 &
' for domain ', num2str(idomain))
4105 call message(
'***ERROR: mo_objective_funtion: objective_pd_sm_pd_et: No SM and/or ET observations available!')
4110 deallocate(mask_times)
4111 deallocate(pd_time_series_sm, pd_time_series_et)
4112 deallocate(mat1_sm, mat1_et)
4113 deallocate(mat2_sm, mat2_et)
4114 deallocate(mask_sm, mask_et)
4115 call etoptisim(idomain)%destroy()
4117 deallocate(smoptisim)
4118 deallocate(etoptisim)
4165 use mo_message,
only : message
4166 use mo_errormeasures,
only : kge
4167 use mo_spatialsimilarity,
only : pd
4168 use mo_string_utils,
only : num2str
4174 real(dp),
dimension(:),
intent(in) :: parameterset
4180 real(dp) :: objective_kgestreamflow
4183 integer(i4) :: idomain, jdomain
4186 integer(i4) :: itime
4189 integer(i4) :: nrows1, ncols1
4193 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
4197 real(dp),
dimension(:, :),
allocatable :: mat1_sm, mat2_sm
4200 real(dp),
dimension(:),
allocatable :: pd_time_series_sm
4204 real(dp),
allocatable,
dimension(:, :) :: runoff
4207 type(
optidata_sim),
dimension(:),
allocatable :: smoptisim
4210 logical,
dimension(:, :),
allocatable :: mask1
4213 logical,
dimension(:, :),
allocatable :: mask_sm
4216 logical,
dimension(:),
allocatable :: mask_times
4223 real(dp),
dimension(:),
allocatable :: runoff_obs
4226 real(dp),
dimension(:),
allocatable :: runoff_agg
4229 logical,
dimension(:),
allocatable :: runoff_obs_mask
4233 call eval(parameterset, smoptisim = smoptisim, runoff = runoff)
4243 mask1 =
level1(idomain)%mask
4244 ncols1 =
level1(idomain)%ncols
4245 nrows1 =
level1(idomain)%nrows
4248 allocate(mask_times(
size(smoptisim(idomain)%dataSim, dim = 2)))
4249 allocate(pd_time_series_sm(
size(smoptisim(idomain)%dataSim, dim = 2)))
4250 allocate(mat1_sm(nrows1, ncols1))
4251 allocate(mat2_sm(nrows1, ncols1))
4252 allocate(mask_sm(nrows1, ncols1))
4255 mask_times = .false.
4256 pd_time_series_sm = 0.0_dp
4257 objective_kgestreamflow = 0.0_dp
4258 ngaugesdomain = 0._i4
4261 do itime = 1,
size(smoptisim(idomain)%dataSim, dim = 2)
4264 mat2_sm = unpack(smoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
4265 mask_sm = unpack(
l1_smobs(idomain)%maskObs(:, itime), mask1, .false.)
4266 pd_time_series_sm = pd(mat1_sm, mat2_sm, mask = mask_sm, valid = mask_times(itime))
4273 jdomain =
gauge%domainId(gg)
4275 if (idomain == jdomain)
then
4277 ngaugesdomain = ngaugesdomain + 1_i4
4279 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
4281 objective_kgestreamflow = objective_kgestreamflow + &
4282 kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
4285 objective_kgestreamflow = objective_kgestreamflow / real(ngaugesdomain, dp)
4288 if (count(mask_times) > 0_i4)
then
4293 wt_for_optional_data * sum(pd_time_series_sm, mask = mask_times) / real(count(mask_times), dp) + &
4295 ) / real(
domainmeta%overallNumberOfDomains, dp) &
4297 call message(
' pd_sm = ', &
4298 & num2str(sum(pd_time_series_sm, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
4299 &
' for domain ', num2str(idomain))
4300 call message(
' kge_q = ', num2str(objective_kgestreamflow,
'(F9.5)'),
' for domain ', num2str(idomain))
4302 call message(
'***ERROR: mo_objective_funtion: objective_pd_sm_kge_q: No SM observations available!')
4307 deallocate(mask_times)
4308 deallocate(pd_time_series_sm)
4312 call smoptisim(idomain)%destroy()
4314 deallocate(smoptisim)
4360 use mo_message,
only : message
4361 use mo_errormeasures,
only : kge
4362 use mo_spatialsimilarity,
only : pd
4363 use mo_string_utils,
only : num2str
4369 real(dp),
dimension(:),
intent(in) :: parameterset
4375 real(dp) :: objective_kgestreamflow
4378 integer(i4) :: idomain, jdomain
4381 integer(i4) :: itime
4384 integer(i4) :: nrows1, ncols1
4388 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
4392 real(dp),
dimension(:, :),
allocatable :: mat1_et, mat2_et
4395 real(dp),
dimension(:),
allocatable :: pd_time_series_et
4399 real(dp),
allocatable,
dimension(:, :) :: runoff
4402 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim
4405 logical,
dimension(:, :),
allocatable :: mask1
4408 logical,
dimension(:, :),
allocatable :: mask_et
4411 logical,
dimension(:),
allocatable :: mask_times
4418 real(dp),
dimension(:),
allocatable :: runoff_obs
4421 real(dp),
dimension(:),
allocatable :: runoff_agg
4424 logical,
dimension(:),
allocatable :: runoff_obs_mask
4428 call eval(parameterset, etoptisim = etoptisim, runoff = runoff)
4438 mask1 =
level1(idomain)%mask
4439 ncols1 =
level1(idomain)%ncols
4440 nrows1 =
level1(idomain)%nrows
4443 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
4444 allocate(pd_time_series_et(
size(etoptisim(idomain)%dataSim, dim = 2)))
4445 allocate(mat1_et(nrows1, ncols1))
4446 allocate(mat2_et(nrows1, ncols1))
4447 allocate(mask_et(nrows1, ncols1))
4450 mask_times = .false.
4451 pd_time_series_et = 0.0_dp
4452 objective_kgestreamflow = 0.0_dp
4453 ngaugesdomain = 0._i4
4456 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
4459 mat2_et = unpack(etoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
4460 mask_et = unpack(
l1_etobs(idomain)%maskObs(:, itime), mask1, .false.)
4461 pd_time_series_et = pd(mat1_et, mat2_et, mask = mask_et, valid = mask_times(itime))
4468 jdomain =
gauge%domainId(gg)
4470 if (idomain == jdomain)
then
4472 ngaugesdomain = ngaugesdomain + 1_i4
4474 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
4476 objective_kgestreamflow = objective_kgestreamflow + &
4477 kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
4480 objective_kgestreamflow = objective_kgestreamflow / real(ngaugesdomain, dp)
4483 if (count(mask_times) > 0_i4)
then
4488 wt_for_optional_data * sum(pd_time_series_et, mask = mask_times) / real(count(mask_times), dp) + &
4490 ) / real(
domainmeta%overallNumberOfDomains, dp) &
4492 call message(
' pd_et = ', &
4493 & num2str(sum(pd_time_series_et, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
4494 &
' for domain ', num2str(idomain))
4495 call message(
' kge_q = ', num2str(objective_kgestreamflow,
'(F9.5)'),
' for domain ', num2str(idomain))
4497 call message(
'***ERROR: mo_objective_funtion: objective_pd_et_kge_q: No ET observations available!')
4502 deallocate(mask_times)
4503 deallocate(pd_time_series_et)
4507 call etoptisim(idomain)%destroy()
4509 deallocate(etoptisim)
4557 use mo_message,
only : message
4558 use mo_errormeasures,
only : kge
4559 use mo_spatialsimilarity,
only : pd
4560 use mo_string_utils,
only : num2str
4566 real(dp),
dimension(:),
intent(in) :: parameterset
4572 real(dp) :: objective_kgestreamflow
4575 integer(i4) :: idomain, jdomain
4578 integer(i4) :: itime
4581 integer(i4) :: nrows1, ncols1
4585 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
4589 real(dp),
dimension(:, :),
allocatable :: mat1_sm, mat2_sm, mat1_et, mat2_et
4592 real(dp),
dimension(:),
allocatable :: pd_time_series_sm, pd_time_series_et
4596 real(dp),
allocatable,
dimension(:, :) :: runoff
4599 type(
optidata_sim),
dimension(:),
allocatable :: etoptisim, smoptisim
4602 logical,
dimension(:, :),
allocatable :: mask1
4605 logical,
dimension(:, :),
allocatable :: mask_sm, mask_et
4608 logical,
dimension(:),
allocatable :: mask_times
4615 real(dp),
dimension(:),
allocatable :: runoff_obs
4618 real(dp),
dimension(:),
allocatable :: runoff_agg
4621 logical,
dimension(:),
allocatable :: runoff_obs_mask
4626 call eval(parameterset, smoptisim = smoptisim, etoptisim = etoptisim, runoff = runoff)
4636 if (
size(etoptisim(idomain)%dataSim, dim = 2) /=
size(smoptisim(idomain)%dataSim, dim = 2))
then
4637 call message(
'***ERROR: mo_objective_funtion: objective_spaef_sm_spaef_et: The time dimension of SM (', &
4638 trim(num2str(
size(smoptisim(idomain)%dataSim, dim = 2))),
') and ET (', &
4639 trim(num2str(
size(etoptisim(idomain)%dataSim, dim = 2))),
') are not equal for domain ', &
4640 trim(num2str(idomain)), &
4641 '. Are both of them at same temporal resolution?')
4646 mask1 =
level1(idomain)%mask
4647 ncols1 =
level1(idomain)%ncols
4648 nrows1 =
level1(idomain)%nrows
4651 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
4652 allocate(pd_time_series_sm(
size(smoptisim(idomain)%dataSim, dim = 2)))
4653 allocate(pd_time_series_et(
size(etoptisim(idomain)%dataSim, dim = 2)))
4655 allocate(mat1_et(nrows1, ncols1))
4656 allocate(mat2_et(nrows1, ncols1))
4657 allocate(mask_et(nrows1, ncols1))
4659 allocate(mat1_sm(nrows1, ncols1))
4660 allocate(mat2_sm(nrows1, ncols1))
4661 allocate(mask_sm(nrows1, ncols1))
4664 mask_times = .false.
4665 pd_time_series_sm = 0.0_dp
4666 pd_time_series_et = 0.0_dp
4667 objective_kgestreamflow = 0.0_dp
4668 ngaugesdomain = 0._i4
4671 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
4674 mat2_et = unpack(etoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
4675 mask_et = unpack(
l1_etobs(idomain)%maskObs(:, itime), mask1, .false.)
4676 pd_time_series_et = pd(mat1_et, mat2_et, mask = mask_et, valid = mask_times(itime))
4679 mat2_sm = unpack(smoptisim(idomain)%dataSim(:, itime), mask1,
nodata_dp)
4680 mask_sm = unpack(
l1_smobs(idomain)%maskObs(:, itime), mask1, .false.)
4681 pd_time_series_sm = pd(mat1_sm, mat2_sm, mask = mask_sm, valid = mask_times(itime))
4688 jdomain =
gauge%domainId(gg)
4690 if (idomain == jdomain)
then
4692 ngaugesdomain = ngaugesdomain + 1_i4
4694 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
4696 objective_kgestreamflow = objective_kgestreamflow + &
4697 kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
4700 objective_kgestreamflow = objective_kgestreamflow / real(ngaugesdomain, dp)
4703 if (count(mask_times) > 0_i4)
then
4708 0.5 *
wt_for_optional_data * sum(pd_time_series_sm, mask = mask_times) / real(count(mask_times), dp) + &
4709 0.5 *
wt_for_optional_data * sum(pd_time_series_et, mask = mask_times) / real(count(mask_times), dp) + &
4711 ) / real(
domainmeta%overallNumberOfDomains, dp) &
4713 call message(
' pd_sm = ', &
4714 & num2str(sum(pd_time_series_sm, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
4715 &
' for domain ', num2str(idomain))
4716 call message(
' pd_et = ', &
4717 & num2str(sum(pd_time_series_et, mask = mask_times)/real(count(mask_times), dp),
'(F9.5)'), &
4718 &
' for domain ', num2str(idomain))
4719 call message(
' kge_q = ', num2str(objective_kgestreamflow,
'(F9.5)'),
' for domain ', num2str(idomain))
4721 call message(
'***ERROR: mo_objective_funtion: objective_pd_sm_pd_et_kge_q: No ET observations available!')
4726 deallocate(mask_times)
4727 deallocate(pd_time_series_sm, pd_time_series_et)
4728 deallocate(mat1_sm, mat1_et)
4729 deallocate(mat2_sm, mat2_et)
4730 deallocate(mask_sm, mask_et)
4731 call smoptisim(idomain)%destroy()
4732 call etoptisim(idomain)%destroy()
4734 deallocate(smoptisim)
4735 deallocate(etoptisim)
4780 use mo_errormeasures,
only : ca
4781 use mo_message,
only : message
4782 use mo_string_utils,
only : num2str
4786 real(dp),
dimension(:),
intent(in) :: parameterset
4792 integer(i4) :: idomain
4795 type(
optidata_sim),
dimension(:),
allocatable :: sweoptisim
4798 type(
optidata_sim),
dimension(:),
allocatable :: spfoptisim
4802 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
4808 call eval(parameterset, sweoptisim = sweoptisim)
4818 classification_accuracy = 0.0_dp
4824 classification_accuracy = ca(
l1_spfobs(idomain)%dataObs, spfoptisim(idomain)%dataSim, mask =
l1_spfobs(idomain)%maskObs)
4827 ( ((1.0_dp - classification_accuracy )) / real(
domainmeta%overallNumberOfDomains, dp) )**6
4831 call sweoptisim(idomain)%destroy()
4832 call spfoptisim(idomain)%destroy()
4834 deallocate(sweoptisim)
4835 deallocate(spfoptisim)
4841 call message(
' classification_accuracy_spf = ', num2str(1 -
objective_ca_spf,
'(F9.5)'))
4881 use mo_errormeasures,
only : ca, kge
4882 use mo_message,
only : message
4883 use mo_string_utils,
only : num2str
4889 real(dp),
dimension(:),
intent(in) :: parameterset
4895 integer(i4) :: idomain, jdomain
4898 type(
optidata_sim),
dimension(:),
allocatable :: sweoptisim
4901 type(
optidata_sim),
dimension(:),
allocatable :: spfoptisim
4905 real(dp),
allocatable,
dimension(:, :) :: runoff
4912 real(dp),
dimension(:),
allocatable :: runoff_obs
4915 real(dp),
dimension(:),
allocatable :: runoff_agg
4918 logical,
dimension(:),
allocatable :: runoff_obs_mask
4922 real(dp),
parameter :: onesixth = 1.0_dp / 6.0_dp
4928 call eval(parameterset, sweoptisim = sweoptisim, runoff = runoff)
4939 classification_accuracy = 0.0_dp
4940 kgestreamflow = 0.0_dp
4941 ngaugesdomain = 0_i4
4949 classification_accuracy = ca(
l1_spfobs(idomain)%dataObs, spfoptisim(idomain)%dataSim, mask =
l1_spfobs(idomain)%maskObs)
4956 jdomain =
gauge%domainId(gg)
4958 if (idomain == jdomain)
then
4960 ngaugesdomain = ngaugesdomain + 1_i4
4962 call extract_runoff(gg, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
4964 kgestreamflow = kgestreamflow + &
4965 kge(runoff_obs, runoff_agg, mask = runoff_obs_mask)
4968 kgestreamflow = kgestreamflow / real(ngaugesdomain, dp)
4976 ) / real(
domainmeta%overallNumberOfDomains, dp) &
4978 call message(
' ca_spf = ', num2str(classification_accuracy,
'(F9.5)'),
' for domain ', num2str(idomain))
4979 call message(
' kge_q = ', num2str(kgestreamflow,
'(F9.5)'),
' for domain ', num2str(idomain))
4983 call sweoptisim(idomain)%destroy()
4984 call spfoptisim(idomain)%destroy()
4986 deallocate(sweoptisim)
4987 deallocate(spfoptisim)
5003 tws_opti_catch_avg_domain, mask_times)
5007 use mo_moment,
only : average
5009 integer(i4),
intent(in) :: iDomain
5012 type(
optidata_sim),
dimension(:),
intent(in) :: twsOptiSim
5015 real(dp),
dimension(:),
allocatable,
intent(out) :: tws_catch_avg_domain
5018 real(dp),
dimension(:),
allocatable,
intent(out) :: tws_opti_catch_avg_domain
5021 logical,
dimension(:),
allocatable,
intent(out) :: mask_times
5025 integer(i4) :: iTime
5028 allocate(mask_times(
size(twsoptisim(idomain)%dataSim, dim = 2)))
5029 allocate(tws_catch_avg_domain(
size(twsoptisim(idomain)%dataSim, dim = 2)))
5030 allocate(tws_opti_catch_avg_domain(
size(twsoptisim(idomain)%dataSim, dim = 2)))
5038 do itime = 1,
size(twsoptisim(idomain)%dataSim, dim = 2)
5041 if (all(.NOT.
l1_twsaobs(idomain)%maskObs(:, itime)))
then
5045 mask_times(itime) = .false.
5049 tws_catch_avg_domain(itime) = average(
l1_twsaobs(idomain)%dataObs(:, itime), &
5050 mask =
l1_twsaobs(idomain)%maskObs(:, itime))
5051 tws_opti_catch_avg_domain(itime) = average(twsoptisim(idomain)%dataSim(:, itime), &
5052 mask =
l1_twsaobs(idomain)%maskObs(:, itime))
5058 et_opti_catch_avg_domain, mask_times)
5062 use mo_moment,
only : average
5064 integer(i4),
intent(in) :: iDomain
5067 type(
optidata_sim),
dimension(:),
intent(in) :: etOptiSim
5070 real(dp),
dimension(:),
allocatable,
intent(out) :: et_catch_avg_domain
5073 real(dp),
dimension(:),
allocatable,
intent(out) :: et_opti_catch_avg_domain
5076 logical,
dimension(:),
allocatable,
intent(out) :: mask_times
5080 integer(i4) :: iTime
5083 allocate(mask_times(
size(etoptisim(idomain)%dataSim, dim = 2)))
5084 allocate(et_catch_avg_domain(
size(etoptisim(idomain)%dataSim, dim = 2)))
5085 allocate(et_opti_catch_avg_domain(
size(etoptisim(idomain)%dataSim, dim = 2)))
5093 do itime = 1,
size(etoptisim(idomain)%dataSim, dim = 2)
5096 if (all(.NOT.
l1_etobs(idomain)%maskObs(:, itime)))
then
5100 mask_times(itime) = .false.
5104 et_catch_avg_domain(itime) = average(
l1_etobs(idomain)%dataObs(:, itime), &
5105 mask =
l1_etobs(idomain)%maskObs(:, itime))
5106 et_opti_catch_avg_domain(itime) = average(etoptisim(idomain)%dataSim(:, itime), &
5107 mask =
l1_etobs(idomain)%maskObs(:, itime))
5114 use mo_moment,
only : average
5118 type(
optidata),
intent(in) :: L1_twsaObs
5123 integer(i4) :: iCell
5124 real(dp) :: twsa_av_cell
5126 allocate(twsaoptisim%dataSim(
size(twsoptisim%dataSim(:, :), dim = 1),
size(twsoptisim%dataSim(:, :), dim = 2)))
5128 do icell = 1,
size(twsoptisim%dataSim(:, :), dim = 1)
5129 twsa_av_cell = average(twsoptisim%dataSim(icell, :), mask = l1_twsaobs%maskObs(icell, :))
5130 twsaoptisim%dataSim(icell, :) = twsoptisim%dataSim(icell, :) - twsa_av_cell
5144 integer(i4) :: iCell
5145 real(dp) :: twsa_av_cell
5147 allocate(spfoptisim%dataSim(
size(sweoptisim%dataSim(:, :), dim = 1),
size(sweoptisim%dataSim(:, :), dim = 2)))
5149 spfoptisim%dataSim = 0
5153 spfoptisim%dataSim = 1
5156 spfoptisim%dataSim = 0
Interface for evaluation routine.
Provides constants commonly used by mHM, mRM and MPR.
real(dp), parameter, public eps_dp
epsilon(1.0) in double precision
real(dp), parameter, public nodata_dp
Provides structures needed by mHM, mRM and/or mpr.
integer(i4), public opti_function
type(period), dimension(:), allocatable, public evalper
Provides common types needed by mHM, mRM and/or mpr.
Provides structures needed by mHM, mRM and/or mpr.
type(domain_meta), public domainmeta
type(grid), dimension(:), allocatable, target, public level1
Main global variables for mHM.
integer(i4) wt_for_optional_data
type(optidata), dimension(:), allocatable, public l1_twsaobs
this stores L1_tws, the mask, the directory of the observerd data, and the timestepInput of the simul...
type(optidata), dimension(:), allocatable, public l1_neutronsobs
type(optidata), dimension(:), allocatable, public l1_spfobs
integer(i4) swe_threshold_for_spf
type(optidata), dimension(:), allocatable, public l1_smobs
type(optidata), dimension(:), allocatable, public l1_etobs
real(dp), dimension(:), allocatable, public bfi_obs
given base-flow index per domain
Global variables for mRM only.
type(gaugingstation), public gauge
integer(i4), public ngaugestotal
Objective Functions for Optimization of mHM/mRM against runoff.
subroutine, public extract_runoff(gaugeid, runoff, runoff_agg, runoff_obs, runoff_obs_mask)
extracts runoff data from global variables
real(dp) function objective_kge(parameterset, eval)
Objective function of KGE.
Objective Functions for Optimization of mHM.
real(dp) function objective_sm_corr(parameterset, eval)
Objective function for soil moisture.
subroutine convert_swe_to_spf(sweoptisim, spfoptisim)
real(dp) function, public objective(parameterset, eval, arg1, arg2, arg3)
Wrapper for objective functions.
subroutine create_domain_avg_et(idomain, etoptisim, et_catch_avg_domain, et_opti_catch_avg_domain, mask_times)
real(dp) function objective_spaef_sm_spaef_et(parameterset, eval)
Bivariate Objective function for SM and ET.
real(dp) function objective_spaef_sm(parameterset, eval)
Objective function for soil moisture.
real(dp) function objective_pd_sm_pd_et(parameterset, eval)
Bivariate Objective function for SM and ET.
real(dp) function objective_neutrons_kge_catchment_avg(parameterset, eval)
Objective function for neutrons.
real(dp) function objective_sm_pd(parameterset, eval)
Objective function for soil moisture.
subroutine convert_tws_to_twsa(twsoptisim, l1_twsaobs, twsaoptisim)
real(dp) function objective_ca_spf(parameterset, eval)
Objective function for matching SPF.
real(dp) function objective_kge_q_rmse_et(parameterset, eval)
Objective function of KGE for runoff and RMSE for domain_avg ET (standarized scores)
real(dp) function objective_kge_q_sm_corr(parameterset, eval)
Objective function of KGE for runoff and correlation for SM.
real(dp) function objective_ca_spf_kge_q(parameterset, eval)
Bivaiate objective function for matching SPF and KGE of streamflow.
subroutine create_domain_avg_tws(idomain, twsoptisim, tws_catch_avg_domain, tws_opti_catch_avg_domain, mask_times)
real(dp) function objective_pd_et(parameterset, eval)
Objective function for ET.
real(dp) function objective_spaef_et(parameterset, eval)
Objective function for ET.
real(dp) function objective_pd_sm_kge_q(parameterset, eval)
Bivariate Objective function for SM and Q.
real(dp) function objective_sm_sse_standard_score(parameterset, eval)
Objective function for soil moisture.
real(dp) function objective_kge_q_rmse_tws(parameterset, eval)
Objective function of KGE for runoff and RMSE for domain_avg TWS (standarized scores)
real(dp) function objective_kge_q_bfi(parameterset, eval)
Objective function of KGE for runoff and BFI absulute difference.
real(dp) function objective_spaef_sm_kge_q(parameterset, eval)
Bivariate Objective function for SM and Q.
real(dp) function objective_pd_et_kge_q(parameterset, eval)
Bivariate Objective function for ET and Q.
subroutine init_indexarray_for_opti_data(domainmeta, optidataoption, noptidomains, opti_domain_indices)
creates an index array of the inidices of the domains eval should MPI process.
real(dp) function, dimension(6) objective_q_et_tws_kge_catchment_avg(parameterset, eval)
Objective function for et, tws and q.
real(dp) function objective_spaef_et_kge_q(parameterset, eval)
Bivariate Objective function for ET and Q.
real(dp) function objective_sm_kge_catchment_avg(parameterset, eval)
Wrapper for objective functions.
real(dp) function objective_et_kge_catchment_avg(parameterset, eval)
Objective function for evpotranspirstion (et).
real(dp) function objective_pd_sm_pd_et_kge_q(parameterset, eval)
Trivariate Objective function for SM, ET and Q.
real(dp) function objective_spaef_sm_spaef_et_kge_q(parameterset, eval)
Trivariate Objective function for SM, ET and Q.
real(dp) function objective_kge_q_et(parameterset, eval)
Objective function of KGE for runoff and KGE for ET.
Type definitions for optimization routines.
Utility functions, such as interface definitions, for optimization routines.
DOMAIN general description.
type for simulated optional data
optional data, such as sm, neutrons, et, tws