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)
342 TYPE(
cp_cfm_type),
DIMENSION(:),
INTENT(inout) :: zdata_next
344 CHARACTER(len=*),
PARAMETER :: routinen =
'simpsonrule_refine_integral'
347 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: zscale
348 COMPLEX(kind=dp),
CONTIGUOUS,
DIMENSION(:, :), &
349 POINTER :: error_zdata
350 INTEGER :: handle, interval, ipoint, jpoint, &
351 nintervals, nintervals_exist, npoints
352 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inds
353 LOGICAL :: interval_converged, interval_exists
354 REAL(kind=
dp) :: my_bound, rscale
355 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: errors
356 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
357 POINTER :: error_rdata
359 TYPE(simpsonrule_subinterval_type),
ALLOCATABLE, &
360 DIMENSION(:) :: subintervals
362 CALL timeset(routinen, handle)
364 npoints =
SIZE(zdata_next)
365 IF (
ASSOCIATED(sr_env%integral))
THEN
369 cpassert(npoints > 0 .AND. mod(npoints, 4) == 0)
375 cpassert(npoints > 1 .AND. mod(npoints, 4) == 1)
379 nintervals_exist =
SIZE(sr_env%tnodes)
380 cpassert(nintervals_exist >= npoints)
381 ALLOCATE (zscale(npoints))
384 sr_env%a, sr_env%b, sr_env%shape_id, weights=zscale)
387 DO ipoint = 1, npoints
394 nintervals = npoints/4
395 IF (
ASSOCIATED(sr_env%integral))
THEN
397 nintervals_exist =
SIZE(sr_env%subintervals)
398 cpassert(nintervals <= nintervals_exist)
400 ALLOCATE (subintervals(nintervals_exist + nintervals))
402 DO interval = 1, nintervals
403 subintervals(2*interval - 1)%lb = sr_env%subintervals(interval)%lb
404 subintervals(2*interval - 1)%ub = 0.5_dp*(sr_env%subintervals(interval)%lb + sr_env%subintervals(interval)%ub)
405 subintervals(2*interval - 1)%conv = 0.5_dp*sr_env%subintervals(interval)%conv
406 subintervals(2*interval - 1)%fa = sr_env%subintervals(interval)%fa
407 subintervals(2*interval - 1)%fb = zdata_next(4*interval - 3)
408 subintervals(2*interval - 1)%fc = sr_env%subintervals(interval)%fb
409 subintervals(2*interval - 1)%fd = zdata_next(4*interval - 2)
410 subintervals(2*interval - 1)%fe = sr_env%subintervals(interval)%fc
412 subintervals(2*interval)%lb = subintervals(2*interval - 1)%ub
413 subintervals(2*interval)%ub = sr_env%subintervals(interval)%ub
414 subintervals(2*interval)%conv = subintervals(2*interval - 1)%conv
415 subintervals(2*interval)%fa = sr_env%subintervals(interval)%fc
416 subintervals(2*interval)%fb = zdata_next(4*interval - 1)
417 subintervals(2*interval)%fc = sr_env%subintervals(interval)%fd
418 subintervals(2*interval)%fd = zdata_next(4*interval)
419 subintervals(2*interval)%fe = sr_env%subintervals(interval)%fe
421 zdata_next(4*interval - 3:4*interval) = cfm_null
424 DO interval = nintervals + 1, nintervals_exist
425 subintervals(interval + nintervals) = sr_env%subintervals(interval)
427 DEALLOCATE (sr_env%subintervals)
431 ALLOCATE (sr_env%integral, sr_env%integral_conv, &
432 sr_env%integral_abc, sr_env%integral_cde, sr_env%integral_ace)
441 ALLOCATE (subintervals(nintervals))
443 rscale = 1.0_dp/real(nintervals, kind=
dp)
445 DO interval = 1, nintervals
447 subintervals(interval)%lb = sr_env%tnodes(4*interval - 3)
448 subintervals(interval)%ub = sr_env%tnodes(4*interval + 1)
449 subintervals(interval)%conv = rscale*sr_env%conv
451 subintervals(interval)%fa = zdata_next(4*interval - 3)
452 subintervals(interval)%fb = zdata_next(4*interval - 2)
453 subintervals(interval)%fc = zdata_next(4*interval - 1)
454 subintervals(interval)%fd = zdata_next(4*interval)
455 subintervals(interval)%fe = zdata_next(4*interval + 1)
461 zdata_next(1:npoints) = cfm_null
468 sr_env%error = sr_env%error_conv
469 nintervals_exist =
SIZE(subintervals)
471 DO interval = 1, nintervals_exist
472 rscale = subintervals(interval)%ub - subintervals(interval)%lb
473 CALL do_simpson_rule(sr_env%integral_ace, &
474 subintervals(interval)%fa, &
475 subintervals(interval)%fc, &
476 subintervals(interval)%fe, &
478 CALL do_simpson_rule(sr_env%integral_abc, &
479 subintervals(interval)%fa, &
480 subintervals(interval)%fb, &
481 subintervals(interval)%fc, &
483 CALL do_simpson_rule(sr_env%integral_cde, &
484 subintervals(interval)%fc, &
485 subintervals(interval)%fd, &
486 subintervals(interval)%fe, &
493 CALL do_boole_rule(sr_env%integral_abc, &
494 subintervals(interval)%fa, &
495 subintervals(interval)%fb, &
496 subintervals(interval)%fc, &
497 subintervals(interval)%fd, &
498 subintervals(interval)%fe, &
499 0.5_dp*rscale, sr_env%integral_cde)
505 error_rdata(:, :) = abs(error_zdata(:, :))
506 CALL cp_fm_trace(sr_env%error_fm, sr_env%weights, subintervals(interval)%error)
508 sr_env%error = sr_env%error + subintervals(interval)%error
511 IF (subintervals(interval)%error <= subintervals(interval)%conv)
THEN
513 sr_env%error_conv = sr_env%error_conv + subintervals(interval)%error
517 IF (sr_env%error <= sr_env%conv)
THEN
528 DO interval = nintervals_exist, 1, -1
529 interval_exists = .false.
530 my_bound = subintervals(interval)%lb
531 DO jpoint = 1, nintervals_exist
532 IF (subintervals(jpoint)%ub == my_bound)
THEN
533 interval_exists = .true.
537 IF (.NOT. interval_exists)
THEN
540 ELSE IF (interval_converged)
THEN
550 ALLOCATE (errors(nintervals_exist), inds(nintervals_exist))
553 DO interval = 1, nintervals_exist
554 errors(interval) = subintervals(interval)%error
556 IF (subintervals(interval)%error > subintervals(interval)%conv) &
557 nintervals = nintervals + 1
560 CALL sort(errors, nintervals_exist, inds)
562 IF (nintervals > 0) &
563 ALLOCATE (sr_env%subintervals(nintervals))
566 DO ipoint = nintervals_exist, 1, -1
567 interval = inds(ipoint)
569 IF (subintervals(interval)%error > subintervals(interval)%conv)
THEN
570 nintervals = nintervals + 1
572 sr_env%subintervals(nintervals) = subintervals(interval)
576 interval_exists = .false.
577 my_bound = subintervals(interval)%lb
578 DO jpoint = 1, nintervals_exist
579 IF (subintervals(jpoint)%ub == my_bound)
THEN
580 interval_exists = .true.
584 IF (.NOT. interval_exists)
THEN
587 ELSE IF (interval_converged)
THEN
596 interval_exists = .false.
597 interval_converged = .false.
598 my_bound = subintervals(interval)%ub
599 DO jpoint = 1, nintervals_exist
600 IF (subintervals(jpoint)%lb == my_bound)
THEN
601 interval_exists = .true.
602 IF (subintervals(jpoint)%error <= subintervals(jpoint)%conv) interval_converged = .true.
606 IF (.NOT. interval_exists .OR. interval_converged)
THEN
612 DEALLOCATE (errors, inds)
615 DEALLOCATE (subintervals)
617 CALL timestop(handle)