121 SUBROUTINE simpsonrule_init(sr_env, xnodes, nnodes, a, b, shape_id, conv, weights, tnodes_restart)
123 INTEGER,
INTENT(inout) :: nnodes
124 COMPLEX(kind=dp),
DIMENSION(nnodes),
INTENT(out) :: xnodes
125 COMPLEX(kind=dp),
INTENT(in) :: a, b
126 INTEGER,
INTENT(in) :: shape_id
127 REAL(kind=
dp),
INTENT(in) :: conv
129 REAL(kind=
dp),
DIMENSION(nnodes),
INTENT(in), &
130 OPTIONAL :: tnodes_restart
132 CHARACTER(len=*),
PARAMETER :: routinen =
'simpsonrule_init'
134 INTEGER :: handle, icol, irow, ncols, nrows
135 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
136 POINTER :: w_data, w_data_my
139 CALL timeset(routinen, handle)
144 nnodes = 4*((nnodes - 1)/4) + 1
146 sr_env%shape_id = shape_id
150 sr_env%error = huge(0.0_dp)
151 sr_env%error_conv = 0.0_dp
153 NULLIFY (sr_env%error_fm, sr_env%weights)
154 CALL cp_fm_get_info(weights, local_data=w_data, nrow_local=nrows, ncol_local=ncols, matrix_struct=fm_struct)
155 ALLOCATE (sr_env%error_fm, sr_env%weights)
163 w_data_my(irow, icol) = abs(w_data(irow, icol))/15.0_dp
167 NULLIFY (sr_env%integral, sr_env%integral_conv)
168 NULLIFY (sr_env%integral_abc, sr_env%integral_cde, sr_env%integral_ace)
170 ALLOCATE (sr_env%tnodes(nnodes))
172 IF (
PRESENT(tnodes_restart))
THEN
173 sr_env%tnodes(1:nnodes) = tnodes_restart(1:nnodes)
179 CALL timestop(handle)
343 TYPE(
cp_cfm_type),
DIMENSION(:),
INTENT(inout) :: zdata_next
345 CHARACTER(len=*),
PARAMETER :: routinen =
'simpsonrule_refine_integral'
348 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: zscale
349 COMPLEX(kind=dp),
CONTIGUOUS,
DIMENSION(:, :), &
350 POINTER :: error_zdata
351 INTEGER :: handle, interval, ipoint, jpoint, &
352 nintervals, nintervals_exist, npoints
353 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inds
354 LOGICAL :: interval_converged, interval_exists
355 REAL(kind=
dp) :: my_bound, rscale
356 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: errors
357 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
358 POINTER :: error_rdata
360 TYPE(simpsonrule_subinterval_type),
ALLOCATABLE, &
361 DIMENSION(:) :: subintervals
363 CALL timeset(routinen, handle)
365 npoints =
SIZE(zdata_next)
366 IF (
ASSOCIATED(sr_env%integral))
THEN
370 cpassert(npoints > 0 .AND. mod(npoints, 4) == 0)
376 cpassert(npoints > 1 .AND. mod(npoints, 4) == 1)
380 nintervals_exist =
SIZE(sr_env%tnodes)
381 cpassert(nintervals_exist >= npoints)
382 ALLOCATE (zscale(npoints))
385 sr_env%a, sr_env%b, sr_env%shape_id, weights=zscale)
388 DO ipoint = 1, npoints
395 nintervals = npoints/4
396 IF (
ASSOCIATED(sr_env%integral))
THEN
398 nintervals_exist =
SIZE(sr_env%subintervals)
399 cpassert(nintervals <= nintervals_exist)
401 ALLOCATE (subintervals(nintervals_exist + nintervals))
403 DO interval = 1, nintervals
404 subintervals(2*interval - 1)%lb = sr_env%subintervals(interval)%lb
405 subintervals(2*interval - 1)%ub = 0.5_dp*(sr_env%subintervals(interval)%lb + sr_env%subintervals(interval)%ub)
406 subintervals(2*interval - 1)%conv = 0.5_dp*sr_env%subintervals(interval)%conv
407 subintervals(2*interval - 1)%fa = sr_env%subintervals(interval)%fa
408 subintervals(2*interval - 1)%fb = zdata_next(4*interval - 3)
409 subintervals(2*interval - 1)%fc = sr_env%subintervals(interval)%fb
410 subintervals(2*interval - 1)%fd = zdata_next(4*interval - 2)
411 subintervals(2*interval - 1)%fe = sr_env%subintervals(interval)%fc
413 subintervals(2*interval)%lb = subintervals(2*interval - 1)%ub
414 subintervals(2*interval)%ub = sr_env%subintervals(interval)%ub
415 subintervals(2*interval)%conv = subintervals(2*interval - 1)%conv
416 subintervals(2*interval)%fa = sr_env%subintervals(interval)%fc
417 subintervals(2*interval)%fb = zdata_next(4*interval - 1)
418 subintervals(2*interval)%fc = sr_env%subintervals(interval)%fd
419 subintervals(2*interval)%fd = zdata_next(4*interval)
420 subintervals(2*interval)%fe = sr_env%subintervals(interval)%fe
422 zdata_next(4*interval - 3:4*interval) = cfm_null
425 DO interval = nintervals + 1, nintervals_exist
426 subintervals(interval + nintervals) = sr_env%subintervals(interval)
428 DEALLOCATE (sr_env%subintervals)
432 ALLOCATE (sr_env%integral, sr_env%integral_conv, &
433 sr_env%integral_abc, sr_env%integral_cde, sr_env%integral_ace)
442 ALLOCATE (subintervals(nintervals))
444 rscale = 1.0_dp/real(nintervals, kind=
dp)
446 DO interval = 1, nintervals
448 subintervals(interval)%lb = sr_env%tnodes(4*interval - 3)
449 subintervals(interval)%ub = sr_env%tnodes(4*interval + 1)
450 subintervals(interval)%conv = rscale*sr_env%conv
452 subintervals(interval)%fa = zdata_next(4*interval - 3)
453 subintervals(interval)%fb = zdata_next(4*interval - 2)
454 subintervals(interval)%fc = zdata_next(4*interval - 1)
455 subintervals(interval)%fd = zdata_next(4*interval)
456 subintervals(interval)%fe = zdata_next(4*interval + 1)
462 zdata_next(1:npoints) = cfm_null
469 sr_env%error = sr_env%error_conv
470 nintervals_exist =
SIZE(subintervals)
472 DO interval = 1, nintervals_exist
473 rscale = subintervals(interval)%ub - subintervals(interval)%lb
474 CALL do_simpson_rule(sr_env%integral_ace, &
475 subintervals(interval)%fa, &
476 subintervals(interval)%fc, &
477 subintervals(interval)%fe, &
479 CALL do_simpson_rule(sr_env%integral_abc, &
480 subintervals(interval)%fa, &
481 subintervals(interval)%fb, &
482 subintervals(interval)%fc, &
484 CALL do_simpson_rule(sr_env%integral_cde, &
485 subintervals(interval)%fc, &
486 subintervals(interval)%fd, &
487 subintervals(interval)%fe, &
494 CALL do_boole_rule(sr_env%integral_abc, &
495 subintervals(interval)%fa, &
496 subintervals(interval)%fb, &
497 subintervals(interval)%fc, &
498 subintervals(interval)%fd, &
499 subintervals(interval)%fe, &
500 0.5_dp*rscale, sr_env%integral_cde)
506 error_rdata(:, :) = abs(error_zdata(:, :))
507 CALL cp_fm_trace(sr_env%error_fm, sr_env%weights, subintervals(interval)%error)
509 sr_env%error = sr_env%error + subintervals(interval)%error
512 IF (subintervals(interval)%error <= subintervals(interval)%conv)
THEN
514 sr_env%error_conv = sr_env%error_conv + subintervals(interval)%error
518 IF (sr_env%error <= sr_env%conv)
THEN
529 DO interval = nintervals_exist, 1, -1
530 interval_exists = .false.
531 my_bound = subintervals(interval)%lb
532 DO jpoint = 1, nintervals_exist
533 IF (subintervals(jpoint)%ub == my_bound)
THEN
534 interval_exists = .true.
538 IF (.NOT. interval_exists)
THEN
541 ELSE IF (interval_converged)
THEN
551 ALLOCATE (errors(nintervals_exist), inds(nintervals_exist))
554 DO interval = 1, nintervals_exist
555 errors(interval) = subintervals(interval)%error
557 IF (subintervals(interval)%error > subintervals(interval)%conv)
THEN
558 nintervals = nintervals + 1
562 CALL sort(errors, nintervals_exist, inds)
564 IF (nintervals > 0)
THEN
565 ALLOCATE (sr_env%subintervals(nintervals))
569 DO ipoint = nintervals_exist, 1, -1
570 interval = inds(ipoint)
572 IF (subintervals(interval)%error > subintervals(interval)%conv)
THEN
573 nintervals = nintervals + 1
575 sr_env%subintervals(nintervals) = subintervals(interval)
579 interval_exists = .false.
580 my_bound = subintervals(interval)%lb
581 DO jpoint = 1, nintervals_exist
582 IF (subintervals(jpoint)%ub == my_bound)
THEN
583 interval_exists = .true.
587 IF (.NOT. interval_exists)
THEN
590 ELSE IF (interval_converged)
THEN
599 interval_exists = .false.
600 interval_converged = .false.
601 my_bound = subintervals(interval)%ub
602 DO jpoint = 1, nintervals_exist
603 IF (subintervals(jpoint)%lb == my_bound)
THEN
604 interval_exists = .true.
605 IF (subintervals(jpoint)%error <= subintervals(jpoint)%conv) interval_converged = .true.
609 IF (.NOT. interval_exists .OR. interval_converged)
THEN
615 DEALLOCATE (errors, inds)
618 DEALLOCATE (subintervals)
620 CALL timestop(handle)