40 USE v3_utilities,
ONLY:
assert
41 USE descriptor_mod,
ONLY: siesta_comm, iam, nprocs
46 USE nscalingtools,
ONLY: startglobrow, endglobrow, mpi_err
47 USE utilities,
ONLY: gradientfull, to_full_mesh
72 USE hessian,
ONLY: apply_colscale
78 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: bsupsijh
79 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: bsupuijh
80 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: bsupvijh
81 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: pijh
82 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: pijf1
83 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: KxBsij
84 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: KxBuij
85 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: KxBvij
86 REAL (dp),
DIMENSION(:,:),
ALLOCATABLE :: pardamp
99 nsmin = max(1, startglobrow)
100 nsmax = min(ns, endglobrow + 1)
102 ALLOCATE(bsupsijh(ntheta,nzeta,nsmin:nsmax),
103 bsupuijh(ntheta,nzeta,nsmin:nsmax),
104 bsupvijh(ntheta,nzeta,nsmin:nsmax),
105 pijh(ntheta,nzeta,nsmin:nsmax), stat=istat)
106 CALL assert_eq(0, istat,
'Allocation1 failed in UPDATE_FORCE')
112 CALL incfields(jbsupsmnsh, jbsupumnch, jbsupvmnch, jpmnch,
113 djbsupsmnsh, djbsupumnch, djbsupvmnch, djpmnch,
114 bsupsijh, bsupuijh, bsupvijh, pijh,
f_sin)
116 CALL incfields(jbsupsmnch, jbsupumnsh, jbsupvmnsh, jpmnsh,
117 djbsupsmnch, djbsupumnsh, djbsupvmnsh, djpmnsh,
118 bsupsijh, bsupuijh, bsupvijh, pijh,
f_cos)
123 wpres:
IF (l_getwmhd)
THEN
124 CALL assert(.not.inhessian,
125 'l_getwmhd must be set to FALSE in Hessian')
126 n2 = min(ns, endglobrow)
128 wp = signjac*(twopi*twopi*
hs_i)*sum(pijh(:,:,n1:n2)*wint(:,:,n1
134 CALL mpi_allreduce(mpi_in_place, wp, 1, mpi_real8, mpi_sum,
135 siesta_comm, mpi_err)
140 ALLOCATE(pijf1(ntheta,nzeta,nsmin:nsmax), stat=istat)
141 CALL assert_eq(0, istat,
'Allocation2 failed in UPDATE_FORCE')
145 CALL bhalftobfull(bsupsijh, bsupuijh, bsupvijh,
146 bsupsijf, bsupuijf, bsupvijf, pijh, pijf1)
151 ksupsijf, ksupuijf, ksupvijf,
152 .not.l_linearize .OR. l_getwmhd, .false.)
154 DEALLOCATE(bsupsijh, bsupuijh, bsupvijh, stat=istat)
156 nsmax = min(ns, endglobrow)
158 ALLOCATE(kxbsij(ntheta,nzeta,nsmin:nsmax),
159 kxbuij(ntheta,nzeta,nsmin:nsmax),
160 kxbvij(ntheta,nzeta,nsmin:nsmax), stat=istat)
161 CALL assert_eq(0, istat,
'Allocation3 failed in UPDATE_FORCE')
167 IF (l_linearize)
THEN
169 CALL lorentz(bsupsijf0, bsupuijf0, bsupvijf0,
170 ksupsijf, ksupuijf, ksupvijf,
171 kxbsij, kxbuij, kxbvij,
f_none)
173 CALL lorentz(bsupsijf, bsupuijf, bsupvijf,
174 ksupsijf0, ksupuijf0, ksupvijf0,
175 kxbsij, kxbuij, kxbvij,
f_sum)
178 CALL lorentz(bsupsijf, bsupuijf, bsupvijf,
179 ksupsijf, ksupuijf, ksupvijf,
180 kxbsij, kxbuij, kxbvij,
f_none)
183 IF (nsmax .eq. ns .and. .not.l_vessel)
THEN
184 CALL assert(all(bsupsijf(:,:,ns) .eq. zero),
185 'bsupsijf(ns) != 0 in UPDATE_FORCE')
189 pijh, kxbsij, kxbuij, kxbvij, pardamp,
f_cos)
192 pijh, kxbsij, kxbuij, kxbvij, pardamp,
f_sin)
197 DEALLOCATE(pijf1, kxbsij, kxbuij, kxbvij, pijh, stat=istat)
198 IF (
ALLOCATED(pardamp))
THEN
202 CALL second0(skstoff)
203 time_update_force = time_update_force + (skstoff - skston)
230 SUBROUTINE incfields(jbsupsmnh, jbsupumnh, jbsupvmnh, jpmnh, &
231 djbsupsmnh, djbsupumnh, djbsupvmnh, djpmnh, &
232 jbsupsijh, jbsupuijh, jbsupvijh, jpijh, &
239 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: jbsupsmnh
240 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: jbsupumnh
241 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: jbsupvmnh
242 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: jpmnh
243 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: djbsupsmnh
244 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: djbsupumnh
245 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: djbsupvmnh
246 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: djpmnh
247 REAL (dp),
DIMENSION(:,:,:),
INTENT(out) :: jbsupsijh
248 REAL (dp),
DIMENSION(:,:,:),
INTENT(out) :: jbsupuijh
249 REAL (dp),
DIMENSION(:,:,:),
INTENT(out) :: jbsupvijh
250 REAL (dp),
DIMENSION(:,:,:),
INTENT(out) :: jpijh
251 INTEGER,
INTENT(in) :: parity
260 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: jbsupsmnh_i
261 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: jbsupumnh_i
262 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: jbsupvmnh_i
263 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: jpmnh_i
266 nsmin = max(1, startglobrow)
267 nsmax = min(ns, endglobrow + 1)
269 IF (parity .EQ.
f_sin)
THEN
280 ALLOCATE(jbsupsmnh_i(0:mpol,-ntor:ntor,nsmin:nsmax),
281 jbsupumnh_i(0:mpol,-ntor:ntor,nsmin:nsmax),
282 jbsupvmnh_i(0:mpol,-ntor:ntor,nsmin:nsmax),
283 jpmnh_i(0:mpol,-ntor:ntor,nsmin:nsmax), stat=istat)
284 CALL assert_eq(0, istat,
'Allocation failed in IncFields')
288 jbsupsmnh_i = djbsupsmnh
289 jbsupumnh_i = djbsupumnh
290 jbsupvmnh_i = djbsupvmnh
293 jbsupsmnh_i = jbsupsmnh_i + jbsupsmnh(:,:,nsmin:nsmax)
294 jbsupumnh_i = jbsupumnh_i + jbsupumnh(:,:,nsmin:nsmax)
295 jbsupvmnh_i = jbsupvmnh_i + jbsupvmnh(:,:,nsmin:nsmax)
296 jpmnh_i = jpmnh_i + jpmnh(:,:,nsmin:nsmax)
301 IF (nsmin .EQ. 1)
THEN
302 jbsupsmnh_i(:,:,1) = 0
303 jbsupsmnh_i(
m1,:,1) = jbsupsmnh_i(
m1,:,2)
304 jbsupumnh_i(:,:,1) = 0
305 jbsupumnh_i(
m0:
m1,:,1) = jbsupumnh_i(
m0:
m1,:,2)
306 jbsupvmnh_i(:,:,1) = 0
307 jbsupvmnh_i(
m0,:,1) = jbsupvmnh_i(
m0,:,2)
309 jpmnh_i(
m0,:,1) = jpmnh_i(
m0,:,2)
318 DEALLOCATE(jbsupsmnh_i, jbsupumnh_i, jbsupvmnh_i, jpmnh_i)
347 SUBROUTINE lorentz(bsupsijf, bsupuijf, bsupvijf, &
348 ksupsijf, ksupuijf, ksupvijf, &
349 KxBsij, KxBuij, KxBvij, fcomb)
354 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: bsupsijf
355 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: bsupuijf
356 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: bsupvijf
357 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: ksupsijf
358 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: ksupuijf
359 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: ksupvijf
360 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(inout) :: KxBsij
361 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(inout) :: KxBuij
362 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(inout) :: KxBvij
363 INTEGER,
INTENT(in) :: fcomb
370 nsmin = max(1, startglobrow)
371 nsmax = min(ns, endglobrow)
374 IF (fcomb .eq.
f_none)
THEN
382 + ksupuijf(:,:,nsmin:nsmax)*bsupvijf(:,:,nsmin:nsmax)
383 - ksupvijf(:,:,nsmin:nsmax)*bsupuijf(:,:,nsmin:nsmax)
385 + ksupvijf(:,:,nsmin:nsmax)*bsupsijf(:,:,nsmin:nsmax)
386 - ksupsijf(:,:,nsmin:nsmax)*bsupvijf(:,:,nsmin:nsmax)
388 + ksupsijf(:,:,nsmin:nsmax)*bsupuijf(:,:,nsmin:nsmax)
389 - ksupuijf(:,:,nsmin:nsmax)*bsupsijf(:,:,nsmin:nsmax)
428 SUBROUTINE getmhdforce(fsubsmnf, fsubumnf, fsubvmnf, pijh, &
429 KxBsij, KxBuij, KxBvij, pardamp, parity)
431 USE utilities,
ONLY: set_bndy_half_to_full, set_bndy_half_to_full_ds, &
437 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: fsubsmnf
438 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: fsubumnf
439 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: fsubvmnf
440 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: pijh
441 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: KxBsij
442 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: KxBuij
443 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(in) :: KxBvij
444 REAL (dp),
DIMENSION(:,:),
ALLOCATABLE,
INTENT(inout) :: pardamp
445 INTEGER,
INTENT(in) :: parity
455 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: pmnh
456 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: pmnf
457 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE :: pmnf_ds
463 nsmax = min(ns, endglobrow + 1)
464 nsmin = max(1, startglobrow)
466 ALLOCATE(pmnf_ds(0:mpol,-ntor:ntor,nsmin:nsmax),
467 pmnf(0:mpol,-ntor:ntor,nsmin:nsmax),
468 pmnh(0:mpol,-ntor:ntor,nsmin:nsmax), stat=istat)
469 CALL assert_eq(0, istat,
'Allocation failed before GetMHDForce')
471 nsmax = min(ns, endglobrow)
473 IF (parity .EQ.
f_cos)
THEN
488 IF (nsmin .eq. 1)
THEN
489 CALL set_bndy_full_origin(fsubsmnf, fsubumnf, fsubvmnf)
494 CALL to_full_mesh(pmnh, pmnf)
495 CALL set_bndy_half_to_full(pmnh, pmnf, nsmin, fours)
498 CALL gradientfull(pmnf_ds, pmnh)
499 CALL set_bndy_half_to_full_ds(pmnh, pmnf_ds, nsmin, fours)
501 IF (nsmax.EQ.ns .AND.
l_pedge)
THEN
503 pmnf(
m0,0,ns) = pmnh(
m0,0,ns)
507 fsubsmnf(:,:,nsmin:nsmax) = fsubsmnf(:,:,nsmin:nsmax) - pmnf_ds
509 moff = m + lbound(fsubumnf, 1)
510 fsubumnf(moff,:,nsmin:nsmax) = fsubumnf(moff,:,nsmin:nsmax)
511 - m*sparity*pmnf(m,:,nsmin:nsmax)
514 noff = n + ntor + lbound(fsubvmnf, 2)
515 fsubvmnf(:,noff,nsmin:nsmax) = fsubvmnf(:,noff,nsmin:nsmax)
516 - n*nfp*sparity*pmnf(:,n,nsmin:nsmax
519 DEALLOCATE(pmnf, pmnf_ds, pmnh)
521 IF (nsmin .eq. 1)
THEN
522 CALL set_bndy_full_origin(fsubsmnf, fsubumnf, fsubvmnf)
536 USE hessian,
ONLY: l_compute_hessian, mupar, mupar_norm
539 REAL (dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(inout) :: parscale
540 REAL (dp),
DIMENSION(:,:),
ALLOCATABLE,
INTENT(inout) :: pardamp
547 IF (mupar .eq. zero .or. .not.l_compute_hessian)
THEN
550 nsmin = max(1, startglobrow)
551 nsmax = min(ns, endglobrow)
553 CALL assert_eq(nsmin, lbound(parscale, 3),
'PARSCALE LBOUND WRONG!'
554 CALL assert_eq(nsmax, ubound(parscale, 3),
'PARSCALE UBOUND WRONG!'
555 ALLOCATE(pardamp(nsmin:nsmax,3))
561 parscale = bsubsijf(:,:,nsmin:nsmax)*bsubsijf(:,:,nsmin:nsmax)
562 / jacobf(:,:,nsmin:nsmax)
563 CALL surfaverage(pardamp(nsmin:nsmax,1), parscale, nsmin, nsmax
564 pardamp(:,1) = pardamp(:,1)*mupar*mupar_norm(nsmin:nsmax)
566 parscale = bsubuijf(:,:,nsmin:nsmax)*bsubuijf(:,:,nsmin:nsmax)
567 / jacobf(:,:,nsmin:nsmax)
568 CALL surfaverage(pardamp(nsmin:nsmax,2), parscale, nsmin, nsmax
569 pardamp(:,2) = pardamp(:,2)*mupar*mupar_norm(nsmin:nsmax)
571 parscale = bsubvijf(:,:,nsmin:nsmax)*bsubvijf(:,:,nsmin:nsmax)
572 / jacobf(:,:,nsmin:nsmax)
573 CALL surfaverage(pardamp(nsmin:nsmax,3), parscale, nsmin, nsmax
574 pardamp(:,3) = pardamp(:,3)*mupar*mupar_norm(nsmin:nsmax)
595 USE hessian,
ONLY: mupar, l_compute_hessian
599 USE nscalingtools,
ONLY: firstpartition_ge_2, lastpartition_ge_2
601 USE quantities,
ONLY: gvsupsmncf => fsupsmncf, gvsupumnsf => fsupumnsf, &
602 gvsupvmnsf => fsupvmnsf, gvsupsmnsf => fsupsmnsf, &
603 gvsupumncf => fsupumncf, gvsupvmncf => fsupvmncf
604 USE utilities,
ONLY: set_bndy_full_origin, set_bndy_fouier_m0
609 REAL (dp),
DIMENSION(:,:),
ALLOCATABLE,
INTENT(inout) :: pardamp
610 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: f_smnf
611 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: f_umnf
612 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: f_vmnf
613 INTEGER,
INTENT(in) :: parity
618 REAL (dp),
DIMENSION(10) :: tmps
625 REAL (dp),
PARAMETER :: p5 = 0.5_dp
630 nsmin = max(1, startglobrow)
631 nsmax = min(ns,endglobrow)
636 CALL assert(all(f_smnf(
m0+moff,-ntor+noff:noff-1,nsmin:nsmax) .eq.
637 'f_smnf != 0, m=0, n<0')
638 CALL assert(all(f_umnf(
m0+moff,-ntor+noff:noff-1,nsmin:nsmax) .eq.
639 'f_umnf != 0, m=0, n<0')
640 CALL assert(all(f_vmnf(
m0+moff,-ntor+noff:noff-1,nsmin:nsmax) .eq.
641 'f_vmnf != 0, m=0, n<0')
642 IF (
ALLOCATED(pardamp))
THEN
643 IF (parity .eq.
f_cos)
THEN
645 f_smnf(:,:,nsmin:nsmax),
646 f_umnf(:,:,nsmin:nsmax),
647 f_vmnf(:,:,nsmin:nsmax),
648 gvsupsmncf(:,:,nsmin:nsmax),
649 gvsupumnsf(:,:,nsmin:nsmax),
650 gvsupvmnsf(:,:,nsmin:nsmax))
651 CALL assert(all(f_umnf(
m0+moff,noff,:) .eq. zero),
653 CALL assert(all(f_vmnf(
m0+moff,noff,:) .eq. zero),
657 f_smnf(:,:,nsmin:nsmax),
658 f_umnf(:,:,nsmin:nsmax),
659 f_vmnf(:,:,nsmin:nsmax),
660 gvsupsmnsf(:,:,nsmin:nsmax),
661 gvsupumncf(:,:,nsmin:nsmax),
662 gvsupvmncf(:,:,nsmin:nsmax))
663 CALL assert(all(f_smnf(
m0+moff,noff,:) .eq. zero),
672 IF (nsmin .le. 2 .and. nsmax .ge. 2)
THEN
673 tmps(1) = sqrt(sum(f_smnf(
m1+moff,:,2)**2))
674 tmps(2) = sqrt(sum(f_smnf(
m0+moff,:,2)**2) +
675 sum(f_smnf(
m2+moff:,:,2)**2))
676 tmps(3) = sqrt(sum(f_umnf(
m1+moff,:,2)**2))
677 tmps(4) = sqrt(sum(f_umnf(
m0+moff,:,2)**2) +
678 sum(f_umnf(
m2+moff:,:,2)**2))
679 tmps(5) = sqrt(sum(f_vmnf(
m0+moff,:,2)**2))
680 tmps(6) = sqrt(sum(f_vmnf(
m1+moff:,:,2)**2))
683 IF (nsmin .le. ns - 1 .and. nsmax .ge. ns - 1)
THEN
684 tmps(7) = sqrt(sum(f_umnf(:,:,ns-1)**2))
685 tmps(8) = sqrt(sum(f_vmnf(:,:,ns-1)**2))
688 IF (nsmax .eq. ns)
THEN
689 tmps(9) = sqrt(sum(f_umnf(:,:,ns)**2))
690 tmps(10) = sqrt(sum(f_vmnf(:,:,ns)**2))
694 CALL mpi_allreduce(mpi_in_place, tmps, 10, mpi_real8, mpi_sum,
695 siesta_comm, mpi_err)
698 IF (iam .eq. 0 .and. lverbose)
THEN
699 IF (parity .eq.
f_cos)
THEN
704 WRITE (*,1002) sqrt(sum(f_smnf(
m1+moff,:,1)**2)), tmps(1), tmps
705 WRITE (*,1003) sqrt(sum(f_umnf(
m1+moff,:,1)**2)), tmps(3), tmps
706 WRITE (*,1004) sqrt(sum(f_vmnf(
m0+moff,:,1)**2)), tmps(5), tmps
707 WRITE (*,1005) tmps(9), tmps(7)
708 WRITE (*,1006) tmps(10), tmps(8)
714 IF (nsmin .eq. 1)
THEN
717 f_smnf(
m1 + moff,:,1) = 0
719 f_smnf(
m1 + moff,:,1) = p5*f_smnf(
m1 + moff,:,1)
729 f_vmnf(:
m1 + moff,:,1) = 0
731 f_vmnf(:
m1 + moff,:,1) = p5*f_vmnf(:
m1 + moff,:,1)
736 edge:
IF (nsmax .EQ. ns)
THEN
745 f_umnf(:,:,ns) = p5*f_umnf(:,:,ns)
746 f_vmnf(:,:,ns) = p5*f_vmnf(:,:,ns)
750 CALL second0(skstoff)
751 get_force_harmonics_time = get_force_harmonics_time + (skstoff - skston
753 1000
FORMAT(/,1x,
'SYMMETRIC FORCES: ')
754 1001
FORMAT(/,1x,
'ASYMMETRIC FORCES: ')
755 1002
FORMAT(
' fs(1,m=1): ',1p,e12.3,
756 ' fs(2,m=1): ',1pe12.3,
' fs(2,m!=1):',1pe12.3)
757 1003
FORMAT(
' fu(1,m=1): ',1p,e12.3,
758 ' fu(2,m=1): ',1pe12.3,
' fu(2,m!=1):',1pe12.3)
759 1004
FORMAT(
' fv(1,m=0): ',1p,e12.3,
760 ' fv(2,m=0): ',1pe12.3,
' fv(2,m>0): ',1pe12.3)
761 1005
FORMAT(
' fu(ns-1) : ',1p,e12.3,
' fu(ns) : ',1pe12.3)
762 1006
FORMAT(
' fv(ns-1) : ',1p,e12.3,
' fv(ns) : ',1pe12.3,/)
784 jvsupsmnf, jvsupumnf, jvsupvmnf)
790 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: pardamp
791 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: f_smnf
792 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: f_umnf
793 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: f_vmnf
794 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: jvsupsmnf
795 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: jvsupumnf
796 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: jvsupvmnf
804 DO js = 1,
SIZE(pardamp,1)
805 f_smnf(:,:,js) = f_smnf(:,:,js) + jvsupsmnf(:,:,js)*pardamp(js,
806 f_umnf(:,:,js) = f_umnf(:,:,js) + jvsupumnf(:,:,js)*pardamp(js,
807 f_vmnf(:,:,js) = f_vmnf(:,:,js) + jvsupvmnf(:,:,js)*pardamp(js,