52 REAL (rprec) :: step_max
54 LOGICAL :: use_central = .false.
56 INTEGER :: current_step = 0
58 INTEGER :: last_para_signal = 0
62 REAL (rprec),
DIMENSION(:,:),
POINTER :: e => null()
65 REAL (rprec),
DIMENSION(:,:),
POINTER :: f => null()
67 REAL (rprec),
DIMENSION(:,:),
POINTER :: jacobian => null()
69 REAL (rprec),
DIMENSION(:,:),
POINTER ::
72 REAL (rprec),
DIMENSION(:,:),
POINTER :: hessian => null()
74 REAL (rprec),
DIMENSION(:),
POINTER :: gradient => null()
76 REAL (rprec),
DIMENSION(:,:),
POINTER :: delta_a => null()
78 REAL (rprec),
DIMENSION(:),
POINTER :: j_svd_w => null()
80 REAL (rprec),
DIMENSION(:,:),
POINTER :: j_svd_u => null()
82 REAL (rprec),
DIMENSION(:,:),
POINTER :: j_svd_vt => null()
84 REAL (rprec),
DIMENSION(:),
POINTER :: delta_a_len => null()
86 REAL (rprec),
DIMENSION(:),
POINTER :: svd_w => null()
89 REAL (rprec),
DIMENSION(:),
POINTER :: exp_g2 => null()
91 REAL (rprec),
DIMENSION(:),
POINTER :: step_size => null()
93 INTEGER,
DIMENSION(:),
POINTER :: num_sv => null()
98 REAL (rprec) :: cut_svd
101 REAL (rprec) :: cut_eff
104 REAL (rprec) :: cut_marg_eff
107 REAL (rprec) :: cut_delta_a
110 REAL (rprec) :: cut_dg2
113 REAL (rprec) :: cut_inv_svd
116 REAL (rprec),
DIMENSION(:,:),
POINTER :: lm_ratio => null()
119 REAL (rprec),
DIMENSION(:,:),
POINTER :: last_values => null()
168 & num_derived_parameters, &
169 & num_parameters, step_type, &
170 & step_max, cut_svd, cut_eff, &
171 & cut_marg_eff, cut_delta_a, &
172 & cut_dg2, last_para_signal, &
173 & cut_inv_svd, use_central)
179 INTEGER,
INTENT(in) :: num_steps
180 INTEGER,
INTENT(in) :: num_signals
181 INTEGER,
INTENT(in) :: num_derived_parameters
182 INTEGER,
INTENT(in) :: num_parameters
183 CHARACTER (len=*),
INTENT(in) :: step_type
184 REAL (rprec),
INTENT(in) :: step_max
185 REAL (rprec),
INTENT(in) :: cut_svd
186 REAL (rprec),
INTENT(in) :: cut_eff
187 REAL (rprec),
INTENT(in) :: cut_marg_eff
188 REAL (rprec),
INTENT(in) :: cut_delta_a
189 REAL (rprec),
INTENT(in) :: cut_dg2
190 INTEGER,
INTENT(in) :: last_para_signal
191 REAL (rprec),
INTENT(in) :: cut_inv_svd
192 LOGICAL,
INTENT(in) :: use_central
196 REAL (rprec) :: start_time
203 num_svd = min(num_signals, num_parameters)
205 SELECT CASE (trim(step_type))
242 & num_derived_parameters,num_parameters))
284 TYPE (reconstruction_class),
POINTER :: this
291 this%cut_marg_eff = 0.0
292 this%cut_delta_a = 0.0
295 this%current_step = 0
297 IF (
ASSOCIATED(this%e))
THEN
302 IF (
ASSOCIATED(this%f))
THEN
307 IF (
ASSOCIATED(this%jacobian))
THEN
308 DEALLOCATE(this%jacobian)
309 this%jacobian => null()
312 IF (
ASSOCIATED(this%derived_jacobian))
THEN
313 DEALLOCATE(this%derived_jacobian)
314 this%derived_jacobian => null()
317 IF (
ASSOCIATED(this%hessian))
THEN
318 DEALLOCATE(this%hessian)
319 this%hessian => null()
322 IF (
ASSOCIATED(this%gradient))
THEN
323 DEALLOCATE(this%gradient)
324 this%gradient => null()
327 IF (
ASSOCIATED(this%delta_a))
THEN
328 DEALLOCATE(this%delta_a)
329 this%delta_a => null()
332 IF (
ASSOCIATED(this%j_svd_w))
THEN
333 DEALLOCATE(this%j_svd_w)
334 this%j_svd_w => null()
337 IF (
ASSOCIATED(this%j_svd_u))
THEN
338 DEALLOCATE(this%j_svd_u)
339 this%j_svd_u => null()
342 IF (
ASSOCIATED(this%j_svd_vt))
THEN
343 DEALLOCATE(this%j_svd_vt)
344 this%j_svd_vt => null()
347 IF (
ASSOCIATED(this%delta_a_len))
THEN
348 DEALLOCATE(this%delta_a_len)
349 this%delta_a_len => null()
352 IF (
ASSOCIATED(this%svd_w))
THEN
353 DEALLOCATE(this%svd_w)
357 IF (
ASSOCIATED(this%exp_g2))
THEN
358 DEALLOCATE(this%exp_g2)
359 this%exp_g2 => null()
362 IF (
ASSOCIATED(this%step_size))
THEN
363 DEALLOCATE(this%step_size)
364 this%step_size => null()
367 IF (
ASSOCIATED(this%num_sv))
THEN
368 DEALLOCATE(this%num_sv)
369 this%num_sv => null()
372 IF (
ASSOCIATED(this%lm_ratio))
THEN
373 DEALLOCATE(this%lm_ratio)
374 this%lm_ratio => null()
377 IF (
ASSOCIATED(this%last_values))
THEN
378 DEALLOCATE(this%last_values)
379 this%last_values => null()
405 INTEGER,
INTENT(in) :: num_sv
408 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: dg2exp
409 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: exp_eff
410 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: marg_exp_eff
412 REAL (rprec) :: denom
413 REAL (rprec) :: largest_w
414 REAL (rprec) :: start_time
419 ALLOCATE(dg2exp(0:num_sv))
420 ALLOCATE(exp_eff(0:num_sv))
421 ALLOCATE(marg_exp_eff(0:num_sv))
429 this%delta_a_len(k) = sqrt(dot_product(this%delta_a(:,k),
430 & this%delta_a(:,k)))
433 exp_eff(k) = abs(dg2exp(k))/this%delta_a_len(k)
439 marg_exp_eff(0:1) = exp_eff(0:1)
442 denom = this%delta_a_len(k) - this%delta_a_len(k - 1)
443 IF (denom .eq. 0.0)
THEN
444 IF (this%delta_a_len(k) .eq. 0.0)
THEN
445 denom = 1.0e-10_rprec
447 denom = 1.0e-10_rprec*this%delta_a_len(k)
450 marg_exp_eff(k) = abs(dg2exp(k)) - abs(dg2exp(k - 1))/denom
454 IF (this%j_svd_w(1) .le. 0.0)
THEN
457 largest_w = this%j_svd_w(1)
464 IF ((this%j_svd_w(k)/largest_w .ge. this%cut_svd) .and.
465 & (exp_eff(k) .ge. this%cut_eff) .and.
466 & (marg_exp_eff(k) .ge. this%cut_marg_eff) .and.
467 & (this%delta_a_len(k) .ge. this%cut_delta_a) .and.
468 & (abs(dg2exp(k)) .ge. this%cut_dg2))
THEN
476 DEALLOCATE(marg_exp_eff)
502 REAL (rprec),
DIMENSION(:),
INTENT(in) :: delta_a
505 REAL (rprec) :: dg2exp_lin
506 REAL (rprec) :: dg2exp_quad
507 REAL (rprec) :: start_time
514 & 2.0*dot_product(this%e(:,this%current_step),
515 & matmul(this%jacobian, delta_a))
519 dg2exp_quad = dot_product(delta_a, matmul(this%hessian, delta_a))
544 REAL (rprec),
DIMENSION(:),
INTENT(in) :: delta_a
547 REAL (rprec) :: start_time
578 REAL (rprec) :: start_time
584 & dot_product(this%e(:,this%current_step),
585 & this%e(:,this%current_step))
608 REAL (rprec) :: start_time
614 & dot_product(this%e(:,this%current_step - 1),
615 & this%e(:,this%current_step - 1))
639 REAL (rprec) :: start_time
669 & eq_steps, iou, eq_comm)
676 TYPE (signal_pointer),
DIMENSION(:),
INTENT(inout) :: signals
677 TYPE (model_class),
POINTER :: a_model
680 INTEGER,
INTENT(inout) :: eq_steps
681 INTEGER,
INTENT(in) :: iou
682 INTEGER,
INTENT(in) :: eq_comm
686 REAL (rprec) :: start_time
692 IF (model_converge(a_model, eq_steps, iou, eq_comm,
'All'))
THEN
693 DO i = 1,
SIZE(gaussp)
701 DO i = 1, this%last_para_signal
702 this%e(i,this%current_step) =
703 & signals(i)%p%get_e(a_model, .false.,
704 & this%last_values(:,i))
708 DO i = this%last_para_signal + 1,
SIZE(signals)
709 this%e(i,this%current_step) =
710 & signals(i)%p%get_e(a_model, .false.,
711 & this%last_values(:,i))
715 a_model%state_flags = model_state_all_off
742 TYPE (reconstruction_class),
INTENT(inout) :: this
743 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) :: derived_params
744 TYPE (model_class),
INTENT(inout) :: a_model
748 REAL (rprec) :: start_time
753 DO i = 1,
SIZE(derived_params)
754 this%f(i,this%current_step) =
755 & param_get_value(derived_params(i)%p, a_model)
781 & derived_params, locks, &
782 & a_model, gaussp, params, &
784 & recon_comm, eq_comm)
790 TYPE (reconstruction_class),
INTENT(inout) :: this
791 TYPE (signal_pointer),
DIMENSION(:),
INTENT(inout) :: signals
792 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) ::
794 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) :: locks
795 TYPE (model_class),
POINTER :: a_model
796 TYPE (gaussp_class_pointer),
DIMENSION(:),
INTENT(inout) ::
798 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) :: params
799 INTEGER,
INTENT(inout) :: eq_steps
800 INTEGER,
INTENT(in) :: iou
801 INTEGER,
INTENT(in) :: recon_comm
802 INTEGER,
INTENT(in) :: eq_comm
806 REAL (rprec) :: param_value
807 REAL (rprec) :: start_time
813 INTEGER,
DIMENSION(:),
ALLOCATABLE :: stride
814 INTEGER,
DIMENSION(:),
ALLOCATABLE :: offset
825 DO i = 1,
SIZE(params)
826 CALL param_sync_value(params(i)%p, a_model, recon_comm,
827 & eq_comm, this%use_central)
829 CALL model_sync_state(a_model, recon_comm)
833 DO i = 1,
SIZE(locks)
834 CALL param_set_lock_value(locks(i)%p, a_model, eq_comm)
837 CALL mpi_comm_rank(recon_comm, mpi_rank, error)
838 CALL mpi_comm_size(recon_comm, mpi_size, error)
845 ALLOCATE(stride(mpi_size))
846 ALLOCATE(offset(mpi_size))
852 minsize =
SIZE(params)/mpi_size
853 extra = mod(
SIZE(params), mpi_size)
856 stride(1:extra) = stride(1:extra) + 1
859 offset(i) = offset(i - 1) + stride(i - 1)
862 CALL model_save_state(a_model)
868 DO j = offset(mpi_rank + 1) + 1, offset(mpi_rank + 1) +
869 & stride(mpi_rank + 1)
872 param_value = param_get_value(params(j)%p, a_model)
876 CALL param_increment(params(j)%p, a_model, eq_comm,
879 DO i = 1,
SIZE(locks)
880 CALL param_set_lock_value(locks(i)%p, a_model, eq_comm)
886 IF (model_converge(a_model, eq_steps, iou, eq_comm,
887 & param_get_name(params(j)%p, a_model)))
THEN
888 DO i = 1,
SIZE(gaussp)
921 IF (this%use_central)
THEN
930 DO i = 1, this%last_para_signal
932 & signals(i)%p%get_e(a_model, .false.,
933 & this%last_values(:,i))
936 DO i = this%last_para_signal + 1,
SIZE(signals)
938 & signals(i)%p%get_e(a_model, .false.,
939 & this%last_values(:,i))
943 DO i = 1,
SIZE(derived_params)
944 this%derived_jacobian(i,j) =
945 & param_get_value(derived_params(i)%p, a_model)
949 CALL param_set_value(params(j)%p, a_model, param_value,
950 & eq_comm, this%use_central)
951 CALL model_reset_state(a_model)
953 DO i = 1,
SIZE(locks)
954 CALL param_set_lock_value(locks(i)%p, a_model,
959 CALL param_decrement(params(j)%p, a_model, eq_comm)
961 IF (model_converge(a_model, eq_steps, iou, eq_comm,
962 & param_get_name(params(j)%p,
964 DO i = 1,
SIZE(gaussp)
974 DO i = 1, this%last_para_signal
976 & -this%jacobian(i,j) +
977 & signals(i)%p%get_e(a_model, .false.,
978 & this%last_values(:,i))
981 DO i = this%last_para_signal + 1,
SIZE(signals)
983 & -this%jacobian(i,j) +
984 & signals(i)%p%get_e(a_model, .false.,
985 & this%last_values(:,i))
989 DO i = 1,
SIZE(derived_params)
990 this%derived_jacobian(i,j) =
991 & -this%derived_jacobian(i,j) +
992 & param_get_value(derived_params(i)%p, a_model)
999 this%jacobian(:,j) = 0.0
1000 this%derived_jacobian(:,j) = 0.0
1012 DO i = 1, this%last_para_signal
1013 this%jacobian(i,j) =
1014 & -(signals(i)%p%get_e(a_model, .false.,
1015 & this%last_values(:,i)) -
1016 & this%e(i,this%current_step))
1019 DO i = this%last_para_signal + 1,
SIZE(signals)
1020 this%jacobian(i,j) =
1021 & -(signals(i)%p%get_e(a_model, .false.,
1022 & this%last_values(:,i)) -
1023 & this%e(i,this%current_step))
1025 this%jacobian(:,j) = this%jacobian(:,j)
1027 & params(j)%p%recon%delta)
1030 DO i = 1,
SIZE(derived_params)
1031 this%derived_jacobian(i,j) =
1032 & -(param_get_value(derived_params(i)%p, a_model)
1033 & - this%f(i,this%current_step))
1035 this%derived_jacobian(:,j) =
1036 & this%derived_jacobian(:,j) *
1037 & sign(1.0_rprec, params(j)%p%recon%delta)
1043 this%jacobian(:,j) = 0.0
1044 this%derived_jacobian(:,j) = 0.0
1049 CALL param_set_value(params(j)%p, a_model, param_value,
1050 & eq_comm, this%use_central)
1051 CALL model_reset_state(a_model)
1053 DO i = 1,
SIZE(locks)
1054 CALL param_set_lock_value(locks(i)%p, a_model, eq_comm)
1059 #if defined(MPI_OPT)
1061 &
SIZE(derived_params), stride,
1062 & offset, recon_comm)
1071 1000
FORMAT(
'Warning: Model failed to converge in Jacobian for ',
1095 & locks, a_model, gaussp, params, &
1096 & eq_steps, iou, recon_comm, &
1104 TYPE (signal_pointer),
DIMENSION(:),
INTENT(inout) :: signals
1105 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) ::
1107 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) :: locks
1108 TYPE (model_class),
POINTER :: a_model
1111 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) :: params
1112 INTEGER,
INTENT(inout) :: eq_steps
1113 INTEGER,
INTENT(in) :: iou
1114 INTEGER,
INTENT(in) :: recon_comm
1115 INTEGER,
INTENT(in) :: eq_comm
1119 REAL (rprec),
DIMENSION(:,:),
ALLOCATABLE :: temp_jacobian
1120 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: temp_work
1121 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: temp_work2
1122 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: temp_work3
1123 INTEGER :: svd_status
1124 REAL (rprec) :: start_time
1125 #if defined(MPI_OPT)
1133 #if defined(MPI_OPT)
1134 CALL mpi_bcast(mpi_jacobian_task, 1, mpi_integer, 0, recon_comm,
1136 CALL mpi_bcast(eq_steps, 1, mpi_integer, 0, recon_comm, error)
1140 & locks, a_model, gaussp, params,
1141 & eq_steps, iou, recon_comm,
1151 this%hessian = matmul(transpose(this%jacobian), this%jacobian)
1157 this%gradient = matmul(transpose(this%jacobian),
1158 & this%e(:,this%current_step))
1163 this%delta_a(:,0) = this%gradient*dot_product(this%gradient,
1165 & / dot_product(this%gradient,
1166 & matmul(this%hessian,
1172 ALLOCATE(temp_jacobian(
SIZE(signals),
SIZE(params)))
1173 temp_jacobian = this%jacobian
1175 ALLOCATE(temp_work(5*max(
SIZE(signals),
SIZE(params))))
1178 CALL dgesvd(
'All',
'All',
SIZE(signals),
SIZE(params),
1179 & temp_jacobian,
SIZE(signals), this%j_svd_w,
1180 & this%j_svd_u,
SIZE(signals), this%j_svd_vt,
1181 &
SIZE(params), temp_work,
SIZE(temp_work), svd_status)
1182 CALL assert_eq(0, svd_status,
'reconstruction_eval_step: ' //
1185 DEALLOCATE(temp_work)
1186 DEALLOCATE(temp_jacobian)
1189 ALLOCATE(temp_work(
SIZE(this%j_svd_w)))
1190 ALLOCATE(temp_work2(
SIZE(signals)))
1191 ALLOCATE(temp_work3(
SIZE(params)))
1194 WHERE (this%j_svd_w .gt. 0.0)
1195 temp_work = 1.0/this%j_svd_w
1201 temp_work2 = matmul(transpose(this%j_svd_u),
1202 & this%e(:,this%current_step))
1206 DO i = 1,
SIZE(this%j_svd_w)
1207 temp_work3(i) = temp_work(i)*temp_work2(i)
1208 this%delta_a(:,i) = matmul(transpose(this%j_svd_vt),
1212 DEALLOCATE(temp_work)
1213 DEALLOCATE(temp_work2)
1214 DEALLOCATE(temp_work3)
1242 INTEGER,
INTENT(in) :: k_use
1243 REAL (rprec),
INTENT(in) :: step_size
1244 REAL (rprec),
DIMENSION(:),
INTENT(out) :: delta_a
1247 REAL (rprec) :: start_time
1252 IF ((step_size .ge. 0.0) .and.
1253 & (this%delta_a_len(k_use) .gt. step_size))
THEN
1254 delta_a = this%step_max/this%delta_a_len(k_use)
1255 & * this%delta_a(:,k_use)
1258 delta_a = this%delta_a(:,k_use)
1284 INTEGER,
INTENT(in) :: k_use
1285 REAL (rprec),
INTENT(in) :: step_size
1286 REAL (rprec),
DIMENSION(:),
INTENT(out) :: delta_a
1290 REAL (rprec) :: ysq, zsq, ydz
1291 REAL (rprec) :: aa, bb, cc, xx
1292 REAL (rprec) :: discriminant
1293 REAL (rprec) :: start_time
1298 IF ((step_size .ge. 0.0) .and.
1299 & (this%delta_a_len(k_use) .gt. step_size))
THEN
1303 DO k = k_use - 1, 1, -1
1304 IF (this%delta_a_len(k) .le. step_size)
THEN
1311 ysq = dot_product(this%delta_a(:,k_min), this%delta_a(:,k_min))
1312 zsq = dot_product(this%delta_a(:,k_min + 1),
1313 & this%delta_a(:,k_min + 1))
1314 ydz = dot_product(this%delta_a(:,k_min),
1315 & this%delta_a(:,k_min + 1))
1319 IF (k_min .eq. 0)
THEN
1324 aa = ysq + zsq - 2.0*ydz
1325 bb = -2.0*ysq + 2.0*ydz
1326 cc = ysq - step_size**2.0
1328 discriminant = bb**2.0 - 4.0*aa*cc
1330 IF (discriminant .le. 0.0)
THEN
1333 xx = (-bb + sqrt(discriminant))/(2.0*aa)
1336 IF ((xx .lt. 0.0) .or. (xx .gt. 1.0))
THEN
1340 delta_a = xx*this%delta_a(:,k_min + 1)
1341 IF (k_min .ne. 0)
THEN
1342 delta_a = this%delta_a(:,k_min)*(1.0 - xx) + delta_a
1347 delta_a = this%delta_a(:,k_use)
1374 INTEGER,
INTENT(in) :: k_use
1375 REAL (rprec),
INTENT(in) :: step_size
1376 REAL (rprec),
DIMENSION(:),
INTENT(out) :: delta_a
1379 REAL (rprec) :: lambda
1380 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: utdote
1381 REAL (rprec) :: start_time
1388 IF ((step_size .ge. 0.0) .and.
1389 & (this%delta_a_len(k_use) .gt. step_size))
THEN
1393 & (this%j_svd_w(1)*this%delta_a_len(k_use)/step_size)**2.0
1395 ALLOCATE(utdote(
SIZE(this%e, 1)))
1396 utdote = matmul(this%e(:,this%current_step), this%j_svd_u)
1400 & step_size, utdote)
1403 utdote(1:k_use) = utdote(1:k_use)*this%j_svd_w(1:k_use)
1404 & / (this%j_svd_w(1:k_use)**2.0 + lambda)
1406 delta_a = matmul(utdote(1:k_use), this%j_svd_vt(1:k_use,:))
1409 this%lm_ratio(1:k_use,1) = lambda
1410 this%lm_ratio(1:k_use,2) = this%j_svd_w(1:k_use)**2.0
1411 this%lm_ratio(1:k_use,3) = this%lm_ratio(1:k_use,1)
1412 & / this%lm_ratio(1:k_use,2)
1416 delta_a = this%delta_a(:,k_use)
1438 & step_size, utdote)
1445 INTEGER,
INTENT(in) :: k_use
1446 REAL (rprec),
INTENT(in) :: lambda_default
1447 REAL (rprec),
INTENT(in) :: step_size
1448 REAL (rprec),
DIMENSION(:),
INTENT(in) :: utdote
1452 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: f_sqrd
1453 REAL (rprec) :: step_size_sqrd
1456 REAL (rprec) :: lambda_0
1457 REAL (rprec) :: lambda_2
1458 REAL (rprec) :: lambda_try
1459 REAL (rprec) :: lambda_new
1460 REAL (rprec) :: f_try, f_new
1462 REAL (rprec) :: start_time
1465 REAL (rprec),
PARAMETER :: d_lambda_min = 1.0e-6_rprec
1471 ALLOCATE(f_sqrd(k_use))
1474 f_sqrd = utdote(1:k_use)**2.0
1475 step_size_sqrd = step_size**2.0
1485 IF (f_0 .lt. 0.0)
THEN
1486 CALL err_warn(
'reconstruction_lm_rootfind: f_0 < 0.0')
1494 lambda_2 = this%j_svd_w(1)**2.0
1498 IF (f_2 .le. 0.0)
THEN
1501 lambda_2 = 4.0*lambda_2
1507 IF (f_2 .gt. 0.0)
THEN
1508 CALL err_warn(
'reconstruction_lm_rootfind: f_2 > 0.0')
1516 IF (f_0*f_2 .gt. 0.0)
THEN
1517 CALL err_warn(
'reconstruction_lm_rootfind: fail to bracket')
1528 lambda_try = 0.5*(lambda_0 + lambda_2)
1532 s = sqrt(f_try**2.0 - f_0*f_2)
1533 IF (s .eq. 0.0)
THEN
1537 lambda_new = lambda_try + (lambda_try - lambda_0)*
1538 & (sign(1.0_rprec, f_0 - f_2)*f_try/s)
1541 & d_lambda_min)
THEN
1549 IF (f_new .eq. 0.0)
THEN
1551 ELSE IF (sign(f_try, f_new) .ne. f_try)
THEN
1552 lambda_0 = lambda_try
1554 lambda_2 = lambda_new
1556 ELSE IF (sign(f_0, f_new) .ne. f_0)
THEN
1557 lambda_2 = lambda_new
1559 ELSE IF (sign(f_2, f_new) .ne. f_2)
THEN
1560 lambda_0 = lambda_new
1563 stop
'reconstruction_lm_rootfind: should never get here'
1566 IF (abs(lambda_0 - lambda_2) .le. d_lambda_min)
THEN
1598 REAL (rprec),
DIMENSION(:),
INTENT(in) :: f_sqrd
1599 REAL (rprec),
INTENT(in) :: step_size_sqrd
1600 REAL (rprec),
INTENT(in) :: lambda
1604 REAL (rprec) :: start_time
1610 DO i = 1,
SIZE(f_sqrd)
1612 & + f_sqrd(i)*(this%j_svd_w(i)/(this%j_svd_w(i)**2.0 +
1645 & locks, a_model, gaussp, params, &
1646 & eq_steps, iou, recon_comm, eq_comm)
1653 TYPE (signal_pointer),
DIMENSION(:),
INTENT(inout) :: signals
1654 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) ::
1656 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) :: locks
1657 TYPE (model_class),
POINTER :: a_model
1660 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) :: params
1661 INTEGER,
INTENT(inout) :: eq_steps
1662 INTEGER,
INTENT(in) :: iou
1663 INTEGER,
INTENT(in) :: recon_comm
1664 INTEGER,
INTENT(in) :: eq_comm
1670 REAL (rprec) :: step_use
1671 REAL (rprec) :: start_time
1673 REAL (rprec),
DIMENSION(4) :: temp_array
1682 & locks, a_model, gaussp, params,
1683 & eq_steps, iou, recon_comm,
1685 this%num_sv(this%current_step + 1) = k_use
1689 #if defined(MPI_OPT)
1690 CALL mpi_bcast(mpi_sync_task, 1, mpi_integer, 0, recon_comm,
1693 DO i = 1,
SIZE(params)
1694 CALL param_sync_delta(params(i)%p, recon_comm)
1699 step_use = this%step_max
1704 & locks, a_model, gaussp, params,
1705 & eq_steps, step_use, iou,
1706 & recon_comm, eq_comm))
THEN
1714 DO j = 1,
SIZE(signals)
1715 this%last_values(:,j) = signals(j)%p%modeled
1720 WRITE (*,*)
' *** Step succeeded'
1721 WRITE (*,*)
' Result of step'
1728 WRITE (iou,*)
' *** Step succeeded'
1729 WRITE (iou,*)
' Result of step'
1737 WRITE (*,*)
'Equilibrium converged but g2 increased'
1743 WRITE (iou,*)
'Equilibrium converged but g2 increased'
1753 WRITE (*,*)
'Equilibrium did not converge'
1754 WRITE (iou,*)
'Equilibrium did not converge'
1759 this%current_step = this%current_step - 1
1765 & gaussp, eq_steps, iou, eq_comm)
1767 WRITE (*,*)
'Reconstruction step failed.'
1768 WRITE (iou,*)
'Reconstruction step failed.'
1773 step_use = step_use/2.0
1774 WRITE (*,*)
'Changing max step size to ', step_use
1775 WRITE (iou,*)
'Changing max step size to ', step_use
1780 1000
FORMAT(
'g^2 old',7x,
'g^2 new',7x,
'g^2 diff')
1781 1001
FORMAT(es12.5,2x,es12.5,2x,es12.5)
1782 1002
FORMAT(
'Change vrnc value for rp number ',i4)
1807 & locks, a_model, gaussp, params, &
1808 & eq_steps, max_step, iou, &
1809 & recon_comm, eq_comm)
1816 TYPE (signal_pointer),
DIMENSION(:),
INTENT(inout) :: signals
1817 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) ::
1819 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) :: locks
1820 TYPE (model_class),
POINTER :: a_model
1823 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) :: params
1824 INTEGER,
INTENT(inout) :: eq_steps
1825 REAL (rprec),
INTENT(inout) :: max_step
1826 INTEGER,
INTENT(in) :: iou
1827 INTEGER,
INTENT(in) :: recon_comm
1828 INTEGER,
INTENT(in) :: eq_comm
1835 LOGICAL :: converged
1837 REAL (rprec) :: step_use
1838 REAL (rprec) :: delta_norm
1839 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: delta_a
1840 REAL (rprec) :: best_g2
1841 REAL (rprec) :: temp_g2
1842 INTEGER :: best_index
1843 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: param_value
1844 REAL (rprec) :: start_time
1849 IF (this%use_central)
THEN
1855 #if defined(MPI_OPT)
1856 CALL mpi_comm_rank(recon_comm, mpi_rank, error)
1857 CALL mpi_comm_size(recon_comm, mpi_size, error)
1863 k_use = this%num_sv(this%current_step + 1)
1886 step_use = max_step - mpi_rank*max_step/(2*mpi_size)
1888 ALLOCATE(param_value(
SIZE(params)))
1889 ALLOCATE(delta_a(
SIZE(params)))
1892 DO i = 1,
SIZE(params)
1893 param_value(i) = param_get_value(params(i)%p, a_model)
1897 SELECT CASE (this%step_type)
1902 this%exp_g2(this%current_step + 1) =
1904 this%step_size(this%current_step + 1) = step_use
1910 this%exp_g2(this%current_step + 1) =
1912 this%step_size(this%current_step + 1) = step_use
1918 this%exp_g2(this%current_step + 1) =
1920 this%step_size(this%current_step + 1) = step_use
1928 IF (mpi_rank .eq. 0)
THEN
1929 #if defined(MPI_OPT)
1930 CALL mpi_bcast(mpi_step_task, 1, mpi_integer, 0, recon_comm,
1932 CALL mpi_bcast(step_use, 1, mpi_real8, 0, recon_comm, error)
1933 CALL mpi_bcast(eq_steps, 1, mpi_integer, 0, recon_comm, error)
1942 DO i = 1,
SIZE(params)
1943 CALL param_set_value(params(i)%p, a_model, param_value(i) +
1944 & delta_a(i)*delta_norm*abs(params(i)%p%recon%delta),
1945 & eq_comm, this%use_central)
1946 WRITE (iou,1001) delta_a(i), param_get_name(params(i)%p,
1949 DO i = 1,
SIZE(locks)
1950 CALL param_set_lock_value(locks(i)%p, a_model, eq_comm)
1955 this%current_step = this%current_step + 1
1957 & gaussp, eq_steps, iou, eq_comm)
1961 #if defined(MPI_OPT)
1962 IF (mpi_rank .gt. 0)
THEN
1963 CALL mpi_ssend(converged, 1, mpi_logical, 0, mpi_rank,
1964 & recon_comm, error)
1969 WRITE (*,1002) mpi_rank, best_g2, step_use
1970 CALL mpi_ssend(best_g2, 1, mpi_real8, 0, mpi_rank,
1971 & recon_comm, error)
1979 WRITE (*,1002) mpi_rank, best_g2, step_use
1982 #if defined(MPI_OPT)
1983 DO i = 1, mpi_size - 1
1984 CALL mpi_recv(converged, 1, mpi_logical, i, i, recon_comm,
1985 & mpi_status_ignore, error)
1990 CALL mpi_recv(temp_g2, 1, mpi_real8, i, i, recon_comm,
1991 & mpi_status_ignore, error)
1992 IF (temp_g2 .lt. best_g2)
THEN
2002 CALL mpi_bcast(best_index, 1, mpi_integer, 0, recon_comm, error)
2004 IF (mpi_rank .eq. 0)
THEN
2005 WRITE (*,1003) best_index
2006 IF (best_index .gt. 0)
THEN
2010 DO i = 1,
SIZE(params)
2011 CALL param_sync_child(params(i)%p, a_model, best_index,
2012 & recon_comm, eq_comm,
2015 CALL mpi_recv(this%e(:,this%current_step),
SIZE(this%e, 1),
2016 & mpi_real8, best_index, best_index, recon_comm,
2017 & mpi_status_ignore, error)
2018 CALL mpi_recv(this%exp_g2(this%current_step), 1, mpi_real8,
2019 & best_index, best_index, recon_comm,
2020 & mpi_status_ignore, error)
2024 DO i = 1,
SIZE(signals)
2025 CALL signals(i)%p%sync_child(best_index, recon_comm)
2030 DO i = 1,
SIZE(locks)
2031 CALL param_set_lock_value(locks(i)%p, a_model, eq_comm)
2035 CALL model_sync_child(a_model, best_index, recon_comm)
2036 a_model%state_flags = model_state_all_off
2041 CALL mpi_barrier(recon_comm, error)
2044 IF ((best_index .lt. 0) .or.
2048 DO i = 1,
SIZE(params)
2049 CALL param_set_value(params(i)%p, a_model,
2050 & param_value(i), eq_comm,
2053 DO i = 1,
SIZE(locks)
2054 CALL param_set_lock_value(locks(i)%p, a_model, eq_comm)
2062 CALL model_reset_state(a_model)
2066 IF (mpi_rank .eq. best_index)
THEN
2068 DO i = 1,
SIZE(params)
2069 CALL param_sync_child(params(i)%p, a_model, best_index,
2070 & recon_comm, eq_comm,
2073 CALL mpi_ssend(this%e(:,this%current_step),
SIZE(this%e, 1),
2074 & mpi_real8, 0, mpi_rank, recon_comm, error)
2075 CALL mpi_ssend(this%exp_g2(this%current_step), 1, mpi_real8,
2076 & 0, mpi_rank, recon_comm, error)
2080 DO i = 1,
SIZE(signals)
2081 CALL signals(i)%p%sync_child(best_index, recon_comm)
2086 CALL model_sync_child(a_model, mpi_rank, recon_comm)
2091 DO i = 1,
SIZE(params)
2092 CALL param_set_value(params(i)%p, a_model, param_value(i),
2093 & eq_comm, this%use_central)
2095 DO i = 1,
SIZE(locks)
2096 CALL param_set_lock_value(locks(i)%p, a_model, eq_comm)
2101 CALL mpi_barrier(recon_comm, error)
2102 CALL model_reset_state(a_model)
2103 this%current_step = this%current_step - 1
2110 DEALLOCATE(param_value)
2115 1000
FORMAT(
'Normalized Step',2x,
'param_name')
2116 1001
FORMAT(es12.5,5x,a)
2117 1002
FORMAT(
' Trying rank: ',i3,
' g^2: ',es12.5,
' step size: ',es12.5)
2118 1003
FORMAT(
' Best index ',i3)
2141 TYPE (reconstruction_class),
INTENT(inout) :: this
2142 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) :: params
2143 TYPE (signal_pointer),
DIMENSION(:),
INTENT(inout) :: signals
2144 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) ::
2150 REAL (rprec),
DIMENSION(:,:),
POINTER :: cp, cd
2151 REAL (rprec),
DIMENSION(:,:),
ALLOCATABLE :: j_dot_cp
2152 REAL (rprec) :: delta_norm
2153 REAL (rprec) :: start_time
2156 CHARACTER (len=*),
PARAMETER ::
2157 'reconstruction_eval_sem'
2162 IF (this%use_central)
THEN
2177 ALLOCATE(cp(
SIZE(params),
SIZE(params)))
2187 IF (
SIZE(derived_params) .gt. 0)
THEN
2188 ALLOCATE(cd(
SIZE(derived_params),
SIZE(derived_params)))
2189 cd = matmul(this%derived_jacobian,
2190 & matmul(cp, transpose(this%derived_jacobian)))
2192 DO j = 1,
SIZE(derived_params)
2193 derived_params(j)%p%sigma = sqrt(cd(j,j))
2194 derived_params(j)%p%correlation = cd(j,:)
2205 DO j = 1,
SIZE(params)
2207 & sqrt(cp(j,j)*(delta_norm*params(j)%p%recon%delta)**2.0)
2208 DO i = 1,
SIZE(params)
2209 params(j)%p%correlation(i) =
2210 & cp(j,i)*delta_norm*params(j)%p%recon%delta *
2211 & delta_norm*params(i)%p%recon%delta
2219 ALLOCATE(j_dot_cp(
SIZE(signals),
SIZE(params)))
2220 j_dot_cp = matmul(this%jacobian, cp)
2232 DO j = 1,
SIZE(params)
2233 params(j)%p%recon%sem = (j_dot_cp(:,j)**2.0) *
2234 & (delta_norm*params(j)%p%recon%delta)**2.0 /
2235 & params(j)%p%sigma**2.0
2238 DEALLOCATE(j_dot_cp, cp)
2260 TYPE (reconstruction_class),
INTENT(inout) :: this
2261 REAL (rprec),
DIMENSION(:,:),
POINTER :: matrix
2262 CHARACTER (len=*),
INTENT(in) :: sub
2263 CHARACTER (len=*),
INTENT(in) :: name
2266 REAL (rprec),
DIMENSION(:,:),
ALLOCATABLE :: svd_vt
2267 REAL (rprec),
DIMENSION(:,:),
ALLOCATABLE :: svd_u
2268 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: svd_work
2270 INTEGER :: work_size
2271 INTEGER :: i, status
2273 REAL (rprec) :: start_time
2281 ALLOCATE(svd_vt(n,n))
2282 ALLOCATE(svd_u(m,m))
2283 ALLOCATE(svd_work(1))
2291 CALL dgesvd(
'All',
'All', m, n, matrix, m, this%svd_w, svd_u, m,
2292 & svd_vt, n, svd_work, -1, status)
2293 work_size = int(svd_work(1))
2294 DEALLOCATE(svd_work)
2295 ALLOCATE(svd_work(work_size))
2298 CALL dgesvd(
'All',
'All', m, n, matrix, m, this%svd_w, svd_u, m,
2299 & svd_vt, n, svd_work, work_size, status)
2300 CALL assert_eq(0, status, sub //
': dgesvd problem when ' //
2301 &
'inverting ' // name)
2305 ALLOCATE(matrix(n,m))
2309 DO i = 1,
SIZE(this%svd_w)
2310 IF (this%svd_w(i) .gt. 0.0 .and.
2311 & this%svd_w(i)/this%svd_w(1) .ge. this%cut_inv_svd)
THEN
2312 matrix(i,i) = 1.0/this%svd_w(i)
2317 matrix = matmul(transpose(svd_vt), matmul(matrix,
2318 & transpose(svd_u)))
2319 DEALLOCATE(svd_vt, svd_u, svd_work)
2339 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) :: params
2343 REAL (rprec) :: start_time
2348 DO j = 1,
SIZE(params)
2349 params(j)%p%correlation = params(j)%p%correlation
2350 & / params(j)%p%sigma
2351 DO i = 1,
SIZE(params)
2352 params(j)%p%correlation(i)
2353 & = params(j)%p%correlation(i)/params(i)%p%sigma
2358 &
'reconstruction_normalize_correlations', start_time)
2377 TYPE (reconstruction_class),
POINTER :: this
2378 INTEGER,
INTENT(in) :: iou
2382 REAL (rprec) :: temp_g2
2383 REAL (rprec) :: start_time
2390 WRITE (*,*)
' *** Reconstruction Steps'
2391 WRITE (iou,*)
' *** Reconstruction Steps'
2395 temp_g2 = dot_product(this%e(:,0), this%e(:,0))
2396 WRITE (*,1001) 0, temp_g2
2397 WRITE (iou,1001) 0, temp_g2
2399 DO i = 1, this%current_step
2400 temp_g2 = dot_product(this%e(:,i), this%e(:,i))
2401 WRITE (*,1001) i, temp_g2, this%exp_g2(i), this%num_sv(i),
2403 WRITE (iou,1001) i, temp_g2, this%exp_g2(i), this%num_sv(i),
2409 1000
FORMAT(
'irstep',2x,
'g^2',11x,
'Expected g^2',4x,
'sv ',2x,
2410 &
'normalized step size')
2411 1001
FORMAT(i6,2(2x,es12.5),2x,i3,2x,es12.5)
2431 TYPE (reconstruction_class),
INTENT(in) :: this
2432 CHARACTER (len=*),
INTENT(in) :: step_type
2433 INTEGER,
INTENT(in) :: iou
2436 REAL (rprec) :: start_time
2442 WRITE (*,1000) this%num_sv(this%current_step + 1)
2443 WRITE (*,1001) step_type, this%step_size(this%current_step + 1)
2444 WRITE (*,1002) this%exp_g2(this%current_step + 1)
2447 WRITE (iou,1000) this%num_sv(this%current_step + 1)
2448 WRITE (iou,1001) step_type, this%step_size(this%current_step + 1)
2449 WRITE (iou,1002) this%exp_g2(this%current_step + 1)
2454 1000
FORMAT(
'Number of singular values used: ',i3)
2455 1001
FORMAT(a4,
': Step size limited to ',es12.5)
2456 1002
FORMAT(
' Expected g^2 = ',es12.5)
2475 TYPE (reconstruction_class),
INTENT(in) :: this
2476 INTEGER,
INTENT(in) :: iou
2479 CHARACTER (len=21) :: jac_format
2481 REAL (rprec) :: start_time
2487 WRITE (iou,*)
' *** Jacobian'
2488 WRITE (jac_format,1000)
SIZE(this%jacobian, 2)
2489 DO i = 1,
SIZE(this%jacobian, 1)
2490 WRITE (iou,jac_format) i, this%jacobian(i,:)
2495 WRITE (iou,*)
' *** Levenberg-Marquardt Parameters'
2496 DO i = 1, this%num_sv(this%current_step)
2497 WRITE (iou,1003) i, this%lm_ratio(i,:)
2502 WRITE (iou,*)
' *** Jacobian Singular Values'
2504 DO i = 1,
SIZE(this%j_svd_w)
2505 WRITE (iou,1002) this%j_svd_w(i), i .le.
2506 & this%num_sv(this%current_step)
2511 WRITE (iou,*)
' *** Derived Jacobian'
2512 WRITE (jac_format,1000)
SIZE(this%derived_jacobian, 2)
2513 DO i = 1,
SIZE(this%derived_jacobian, 1)
2514 WRITE (iou,jac_format) i, this%derived_jacobian(i,:)
2518 WRITE (iou,*)
' *** Parameter Covarance Singular Values'
2520 DO i = 1,
SIZE(this%svd_w)
2521 WRITE (iou,1002) this%svd_w(i),
2522 & this%svd_w(i)/this%svd_w(1) .ge. this%cut_inv_svd
2529 1000
FORMAT(
'(i4,',i3,
'(2x,es12.5))')
2530 1001
FORMAT(
'svd value',5x,
'used')
2531 1002
FORMAT(es12.5,2x,l)
2532 1003
FORMAT(i3,
' lambda = ',es12.5,
' W_i^2 = ',es12.5,
' ratio = ',
2553 & signals, derived_params, &
2560 TYPE (reconstruction_class),
INTENT(inout) :: this
2561 INTEGER,
INTENT(in) :: result_ncid
2562 INTEGER,
INTENT(in) :: current_step
2563 TYPE (signal_pointer),
DIMENSION(:),
INTENT(inout) :: signals
2564 TYPE (param_pointer),
DIMENSION(:),
INTENT(in) :: derived_params
2565 TYPE (model_class),
POINTER :: a_model
2568 REAL (rprec),
DIMENSION(:),
ALLOCATABLE :: temp_model
2570 INTEGER :: temp_var_id
2572 REAL (rprec) :: start_time
2577 status = nf_inq_varid(result_ncid,
'signal_model_value',
2579 CALL assert_eq(status, nf_noerr, nf_strerror(status))
2580 status = nf_get_vara_double(result_ncid, temp_var_id,
2581 & (/ 1, 1, current_step /),
2582 & (/ 4,
SIZE(signals), 1 /),
2584 CALL assert_eq(status, nf_noerr, nf_strerror(status))
2590 DO i = 1, this%last_para_signal
2591 this%e(i,this%current_step) =
2592 & signals(i)%p%get_e(a_model, .false., this%last_values(:,i))
2595 DO i = this%last_para_signal + 1,
SIZE(signals)
2596 this%e(i,this%current_step) =
2597 & signals(i)%p%get_e(a_model, .false., this%last_values(:,i))
2623 TYPE (reconstruction_class),
INTENT(inout) :: this
2624 INTEGER,
INTENT(in) :: recon_comm
2626 #if defined(MPI_OPT)
2628 REAL (rprec) :: start_time
2634 CALL mpi_bcast(this%current_step, 1, mpi_integer, 0, recon_comm,
2636 CALL mpi_bcast(this%e(:,this%current_step),
SIZE(this%e, 1),
2637 & mpi_real8, 0, recon_comm, error)
2638 CALL mpi_bcast(this%f(:,this%current_step),
SIZE(this%f, 1),
2639 & mpi_real8, 0, recon_comm, error)
2640 CALL mpi_bcast(this%last_values, 4*
SIZE(this%e, 1), mpi_real8, 0,
2641 & recon_comm, error)
2664 TYPE (reconstruction_class),
INTENT(inout) :: this
2665 INTEGER,
INTENT(in) :: recon_comm
2667 #if defined(MPI_OPT)
2669 REAL (rprec) :: start_time
2675 CALL mpi_bcast(this%j_svd_w,
SIZE(this%j_svd_w), mpi_real8, 0,
2676 & recon_comm, error)
2677 CALL mpi_bcast(this%j_svd_u,
SIZE(this%j_svd_u), mpi_real8, 0,
2678 & recon_comm, error)
2679 CALL mpi_bcast(this%j_svd_vt,
SIZE(this%j_svd_vt), mpi_real8, 0,
2680 & recon_comm, error)
2682 CALL mpi_bcast(this%delta_a_len,
SIZE(this%delta_a_len),
2683 & mpi_real8, 0, recon_comm, error)
2684 CALL mpi_bcast(this%delta_a,
SIZE(this%delta_a), mpi_real8, 0,
2685 & recon_comm, error)
2687 CALL mpi_bcast(this%jacobian,
SIZE(this%jacobian), mpi_real8, 0,
2688 & recon_comm, error)
2689 CALL mpi_bcast(this%hessian,
SIZE(this%hessian), mpi_real8, 0,
2690 & recon_comm, error)
2694 CALL mpi_bcast(this%num_sv(this%current_step + 1), 1, mpi_integer,
2695 & 0, recon_comm, error)
2718 & num_derived_params, stride, &
2719 & offset, recon_comm)
2724 TYPE (reconstruction_class),
INTENT(inout) :: this
2725 TYPE (param_pointer),
DIMENSION(:),
INTENT(inout) :: params
2726 INTEGER,
INTENT(in) :: num_signal
2727 INTEGER,
INTENT(in) :: num_derived_params
2728 INTEGER,
DIMENSION(:),
INTENT(in) :: stride
2729 INTEGER,
DIMENSION(:),
INTENT(in) :: offset
2730 INTEGER,
INTENT(in) :: recon_comm
2732 #if defined(MPI_OPT)
2734 REAL (rprec) :: start_time
2738 INTEGER :: iLow, iHigh
2743 CALL mpi_comm_rank(recon_comm, mpi_rank, error)
2750 ilow = offset(mpi_rank + 1) + 1
2751 ihigh = offset(mpi_rank + 1) + stride(mpi_rank + 1)
2757 IF (mpi_rank .eq. 0)
THEN
2758 CALL mpi_gatherv(mpi_in_place,
2759 & num_signal*stride(mpi_rank + 1), mpi_real8,
2760 & this%jacobian, num_signal*stride,
2761 & num_signal*offset, mpi_real8, 0, recon_comm,
2764 CALL mpi_gatherv(mpi_in_place,
2765 & num_derived_params*stride(mpi_rank + 1),
2766 & mpi_real8, this%derived_jacobian,
2767 & num_derived_params*stride,
2768 & num_derived_params*offset, mpi_real8, 0,
2769 & recon_comm, error)
2771 CALL mpi_gatherv(this%jacobian(:,ilow:ihigh),
2772 & num_signal*stride(mpi_rank + 1), mpi_real8,
2773 & this%jacobian, num_signal*stride,
2774 & num_signal*offset, mpi_real8, 0, recon_comm,
2777 CALL mpi_gatherv(this%derived_jacobian(:,ilow:ihigh),
2778 & num_derived_params*stride(mpi_rank + 1),
2779 & mpi_real8, this%derived_jacobian,
2780 & num_derived_params*stride,
2781 & num_derived_params*offset, mpi_real8, 0,
2782 & recon_comm, error)
2786 IF (mpi_rank .ne. 0)
THEN
2787 DO i = offset(mpi_rank + 1) + 1, offset(mpi_rank + 1) +
2788 & stride(mpi_rank + 1)
2789 CALL param_send_delta(params(i)%p, i, recon_comm)
2793 IF (mpi_rank .eq. 0)
THEN
2794 DO i = offset(1) + stride(1) + 1,
SIZE(params)
2795 CALL param_recv_delta(params(i)%p, i, recon_comm)