V3FIT
shared_functions.f90
1 
5  USE v3_utilities, ONLY: assert
6  USE shared_data
7  USE utilities
8  USE descriptor_mod, ONLY: inhessian, nprocs, iam, siesta_comm
9  USE island_params, ns=>ns_i, hs=>hs_i, mpol=>mpol_i, ntor=>ntor_i
10  USE hessian, ONLY: apply_precond, l_compute_hessian, apply_colscale
11  USE timer_mod, ONLY: time_init_state, time_funci
12  USE nscalingtools, ONLY: startglobrow, endglobrow, mpi_err, &
13  parsolver
14  USE mpi_inc
15  USE gmres_lib, ONLY: truncate
16 
17  IMPLICIT NONE
18 
19  INTEGER, PRIVATE :: nsmin, nsmax
20 
21  CONTAINS
22 
25  SUBROUTINE funct_island
26 !-----------------------------------------------
27 ! PARALLEL (in N rows, PARSOLVER=T)
28 ! SERIAL (PARSOLVER=F, startglobrow=1, endglobrow=ns)
29 !-----------------------------------------------
30  USE siesta_bfield, ONLY: update_bfield
31  USE siesta_pressure, ONLY: update_pres
32  USE siesta_force, ONLY: update_force
33  USE siesta_displacement, ONLY: update_upperv
34  USE siesta_init, ONLY: init_state
35  USE quantities, ONLY: wb, wp
36  USE siesta_state, ONLY: clear_field_perts
37 !-----------------------------------------------
38 ! L o c a l V a r i a b l e s
39 !-----------------------------------------------
40  REAL(dp) :: ton, toff, skston, skstoff
41  LOGICAL :: ltype
42 !-----------------------------------------------
43  CALL second0(ton)
44  nsmin = max(1, startglobrow)
45  nsmax = min(endglobrow, ns)
46 
47  IF (inhessian) THEN
49  ELSE
51  END IF
52 
53  l_update_state = .false.
54  IF (l_init_state) THEN
55  CALL second0(skston)
56  CALL init_state(.false.)
57  CALL second0(skstoff)
58  time_init_state = time_init_state + (skstoff - skston)
59  l_init_state = .false.
60  END IF
61 
62  IF (any(xc .ne. 0) .or. ALLOCATED(buv_res)) THEN
63  CALL update_upperv
64  CALL update_bfield(.false.)
65  CALL update_pres
66  ELSE
67  CALL clear_field_perts
68  END IF
69  CALL update_force
70 
71  CALL assert(gamma.NE.one,'SIESTA REQUIRES gamma != 1')
72  wtotal = wb + wp/(gamma - 1)
73  IF (wtotal0 .eq. -1) THEN
74  wtotal0 = wtotal
75  END IF
76 
77  gc = gnorm_i*gc
78 
79 ! CALLED FROM GMRES: ADD BACK INITIAL FORCE gc0 or STORE UNPRECONDITIONED FORCES
80  IF (ALLOCATED(gc0) .AND. (l_getfsq .OR. l_conjgrad) .AND. &
81  l_linearize .AND. .NOT.l_compute_hessian) gc = gc+gc0
82 
83  CALL assert(.NOT.(l_getfsq.AND.inhessian), &
84  'l_getfsq must be set to FALSE in Hessian')
85 
86  IF (l_getfsq) THEN
87 ! COMPUTE PRECONDITIONED, VOLUME-AVERAGED FORCE fsq_total
88  CALL getfsq(fsq_total)
89 
90 !COMPUTE UN-PRECONDITIONED, VOLUME-AVERAGED FORCE fsq_total1
91  IF (any(col_scale .NE. one)) THEN
92  col_scale(:,:,:,nsmin:nsmax) = one/col_scale(:,:,:,nsmin:nsmax)
93  CALL apply_colscale(gc, col_scale, nsmin, nsmax)
94 
95  CALL getfsq(fsq_total1)
96 
97  col_scale(:,:,:,nsmin:nsmax) = one/col_scale(:,:,:,nsmin:nsmax)
98  CALL apply_colscale(gc, col_scale, nsmin, nsmax)
99  ELSE
101  END IF
102  END IF
103 
104 !
105 ! GMRES handles preconditioning itself: do NOT apply
106 ! Do not precondition when Hessian is being computed
107  IF (l_applyprecon) CALL apply_precond(gc)
108 
109  CALL second0(toff)
110  time_funci = time_funci+(toff-ton)
111 
112  END SUBROUTINE funct_island
113 
114 
115  SUBROUTINE getfsq(fsqout)
116  USE quantities, ONLY: fsubsmncf, fsubumnsf, fsubvmnsf, &
118  fsubsmnsf, fsubumncf, fsubvmncf, &
120  toupper_forces
121 !-----------------------------------------------
122 ! D u m m y A r g u m e n t s
123 !-----------------------------------------------
124  REAL(dp), INTENT(OUT) :: fsqout
125 !-----------------------------------------------
126 ! L o c a l V a r i a b l e s
127 !-----------------------------------------------
128  REAL(dp) :: temp(3)
129  INTEGER :: js
130 !-----------------------------------------------
131  temp(1) = sum(fsubsmncf(:,:,nsmin:nsmax)**2)
132  temp(2) = sum(fsubumnsf(:,:,nsmin:nsmax)**2)
133  temp(3) = sum(fsubvmnsf(:,:,nsmin:nsmax)**2)
134  IF (lasym) THEN
135  temp(1) = temp(1) + sum(fsubsmnsf(:,:,nsmin:nsmax)**2)
136  temp(2) = temp(2) + sum(fsubumncf(:,:,nsmin:nsmax)**2)
137  temp(3) = temp(3) + sum(fsubvmncf(:,:,nsmin:nsmax)**2)
138  END IF
139 #if defined(MPI_OPT)
140  IF (parsolver) THEN
141  CALL mpi_allreduce(mpi_in_place,temp,3,mpi_real8,mpi_sum, &
142  siesta_comm,mpi_err)
143  END IF
144 #endif
145  fsqvs = hs*temp(1)
146  fsqvu = hs*temp(2)
147  fsqvv = hs*temp(3)
148 
149  CALL toupper_forces
150 
151 !VOLUME-AVERAGE |F|**2
152  temp(1) = 0
153  DO js = nsmin, nsmax
154  temp(1) = temp(1) &
155  + vp_f(js)*sum(fsupsmncf(:,:,js)*fsubsmncf(:,:,js) + &
156  fsupumnsf(:,:,js)*fsubumnsf(:,:,js) + &
157  fsupvmnsf(:,:,js)*fsubvmnsf(:,:,js))
158  IF (lasym) THEN
159  temp(1) = temp(1) &
160  + vp_f(js)*sum(fsupsmnsf(:,:,js)*fsubsmnsf(:,:,js) + &
161  fsupumncf(:,:,js)*fsubumncf(:,:,js) + &
162  fsupvmncf(:,:,js)*fsubvmncf(:,:,js))
163  END IF
164  END DO
165 #if defined(MPI_OPT)
166  IF (parsolver) THEN
167 ! FIXME: All reduce is not deterministic. This causes a divergent run sequence.
168  CALL mpi_allreduce(mpi_in_place,temp,1,mpi_real8,mpi_sum, &
169  siesta_comm,mpi_err)
170  END IF
171 #endif
172 
173  fsqout = temp(1)/sum(vp_f)
174 
175  END SUBROUTINE getfsq
176 
177 
180  FUNCTION getwmhd (p)
181 !-----------------------------------------------
182 ! D u m m y A r g u m e n t s
183 !-----------------------------------------------
184  REAL(dp), INTENT(in) :: p(neqs)
185 !-----------------------------------------------
186 ! L o c a l V a r i a b l e s
187 !-----------------------------------------------
188  REAL(dp) :: getwmhd
189 !-----------------------------------------------
190 
191  xc = p
192  l_init_state = .true.
193  l_linearize = .false.
194  l_getwmhd = .true.
195  l_getfsq = .false.
196 
197  CALL funct_island
198 
199  l_getwmhd = .false.
200 
201  getwmhd = wtotal
202 
203  END FUNCTION getwmhd
204 
205 
208  SUBROUTINE linesearch(xcmin, fsq_min)
210 !-----------------------------------------------
211 ! D u m m y A r g u m e n t s
212 !-----------------------------------------------
213  REAL(dp), INTENT(INOUT) :: xcmin(neqs)
214  REAL(dp), INTENT(INOUT) :: fsq_min
215 !-----------------------------------------------
216  REAL(dp) :: facmin
217  INTEGER :: iter, j
218  LOGICAL :: lwrite
219 !-----------------------------------------------
220  facmin = 3
221  l_init_state = .false.
222  l_getfsq = .true.
223 
224  lwrite = (iam .EQ. 0 .and. lverbose)
225  IF (lwrite) print 90
226  90 FORMAT(/,1x,'LINE SEARCH - SCAN ||X|| FOR MIN FSQ_NL',/,1x,15('-'), &
227  /,1x,'ITER',7x,'FSQ_NL',10x,'||X||',9x,'MAX|X|',10x,'FAC')
228 
229  xc = facmin*xcmin
230  iter = 0
231  fsq_min = huge(fsq_min)
232 
233  DO j = 1, 100
234  CALL funct_island
235  IF (fsq_total1 .lt. fsq_min) THEN
236  xcmin = xc
237 ! FIXME: Remove one.
238  IF (fsq_total1 .GT. 0.98_dp*fsq_min) THEN
239  iter = iter + 1
240  END IF
241  IF (fsq_total1 .LT. 0.85_dp*fsq_min) THEN
242  iter = 0
243  END IF
244  fsq_min = fsq_total1
245  ELSE IF (j .gt. 4) THEN
246  iter = iter + 1
247  END IF
248  IF (iam .eq. 0 .and. lverbose) THEN
249  WRITE (*,1000) j, fsq_total1, sqrt(sum(xc*xc)), maxval(abs(xc)), &
250  facmin
251  facmin = facmin/sqrt2
252  END IF
253  IF (iter .gt. 2 .OR. fsq_total1 .le. ftol) EXIT
254  xc = xc/sqrt2
255  END DO
256 
257 1000 FORMAT(i5,4(3x,1pe12.3))
258 
259  END SUBROUTINE linesearch
260 
262  SUBROUTINE init_ptrs (xtarget, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6)
263 !-----------------------------------------------
264 ! D u m m y A r g u m e n t s
265 !-----------------------------------------------
266  REAL(dp), TARGET, INTENT(IN) :: xtarget(0:mpol,-ntor:ntor,ndims,ns)
267  REAL(dp), POINTER, DIMENSION(:,:,:) :: ptr1, ptr4
268  REAL(dp), POINTER, DIMENSION(:,:,:) :: ptr2, ptr5
269  REAL(dp), POINTER, DIMENSION(:,:,:) :: ptr3, ptr6
270 
271 !-----------------------------------------------
272  ptr1 => xtarget(:,:,1,:)
273  ptr2 => xtarget(:,:,2,:)
274  ptr3 => xtarget(:,:,3,:)
275  IF (ndims .EQ. 6) THEN
276  ptr4 => xtarget(:,:,4,:)
277  ptr5 => xtarget(:,:,5,:)
278  ptr6 => xtarget(:,:,6,:)
279  END IF
280 
281  END SUBROUTINE init_ptrs
282 
283  END MODULE shared_functions
shared_data::out_hess_nfunct
integer out_hess_nfunct
FIXME UNKNOWN.
Definition: shared_data.f90:87
shared_data::lverbose
logical lverbose
Use verbose screen output.
Definition: shared_data.f90:234
shared_data::l_getfsq
logical l_getfsq
Compute |F|^2.
Definition: shared_data.f90:216
shared_functions
Module contained subroutines and functions updating MHD forces and Wmhd.
Definition: shared_functions.f90:4
shared_data::xc
real(dp), dimension(:), allocatable xc
1D array of Fourier mode displacement components.
Definition: shared_data.f90:97
shared_data::in_hess_nfunct
integer in_hess_nfunct
FIXME UNKNOWN.
Definition: shared_data.f90:85
shared_data::fsq_total
real(dp) fsq_total
|F|^2 WITH column scaling.
Definition: shared_data.f90:91
quantities
This file contains subroutines for allocating and initializing curvilinear magnetic covariant and pre...
Definition: quantities.f90:11
shared_data::l_applyprecon
logical l_applyprecon
Apply preconditioner.
Definition: shared_data.f90:218
siesta_state
This file contains subroutines for aupdating from t to t + delta_t the magnetic field and pressure as...
Definition: siesta_state.f90:12
shared_data::l_init_state
logical l_init_state
Store initial field/pressure state.
Definition: shared_data.f90:222
siesta_bfield
This file contains subroutines for updating half-grid magnetic fields.
Definition: siesta_bfield.f90:10
shared_data::fsupumncf
real(dp), dimension(:,:,:), pointer fsupumncf
Contravariant force for stellarator symmetric u component on full grid.
Definition: shared_data.f90:192
shared_data::fsupsmnsf
real(dp), dimension(:,:,:), pointer fsupsmnsf
Contravariant force for stellarator symmetric s component on full grid.
Definition: shared_data.f90:188
siesta_bfield::update_bfield
subroutine update_bfield(l_add_res)
Update contravariant componets of the magnetic field.
Definition: siesta_bfield.f90:37
shared_data::fsqvv
real(dp) fsqvv
|F|^2 for v components.
Definition: shared_data.f90:131
siesta_init::init_state
subroutine, public init_state(lcurrent_only, lpar_in)
Initialize equilibrium state.
Definition: siesta_init.f90:45
v3_utilities::assert
Definition: v3_utilities.f:55
shared_data::buv_res
real(dp), dimension(:,:,:), allocatable buv_res
Resonant magnetic field perturbation.
Definition: shared_data.f90:104
shared_data::col_scale
real(dp), dimension(:,:,:,:), allocatable col_scale
Column scaling factors.
Definition: shared_data.f90:110
shared_data::wtotal
real(dp) wtotal
MHD energy sum of magnetic and thermal.
Definition: shared_data.f90:121
mpi_inc
Umbrella module avoid multiple inlcudes of the mpif.h header.
Definition: mpi_inc.f:11
siesta_force::update_force
subroutine update_force
Update MHD forces on full radial mesh.
Definition: siesta_force.f90:70
shared_data::fsupumnsf
real(dp), dimension(:,:,:), pointer fsupumnsf
Contravariant force for stellarator non-symmetric u component on full grid.
Definition: shared_data.f90:194
island_params
This file contains fix parameters related to the computational grids.
Definition: island_params.f90:10
shared_data::l_linearize
logical l_linearize
Use linearized forces.
Definition: shared_data.f90:210
island_params::gamma
real(dp), parameter gamma
Adiabatic constant.
Definition: island_params.f90:66
siesta_force
Compute the JxB - Grad(p) covariant force components. The plasma is in equilibrium when the force of ...
Definition: siesta_force.f90:37
shared_data::fsupsmncf
real(dp), dimension(:,:,:), pointer fsupsmncf
Contravariant force for stellarator non-symmetric s component on full grid.
Definition: shared_data.f90:190
shared_data::lasym
logical lasym
Use non-stellarator symmetry.
Definition: shared_data.f90:230
island_params::hs_i
real(dp) hs_i
Radial grid spacing. hs = s_i+1 - s_i.
Definition: island_params.f90:47
siesta_namelist::ftol
real(dp) ftol
Force tolarance.
Definition: siesta_namelist.f90:146
shared_data::gc
real(dp), dimension(:), allocatable, target gc
1D Array of Fourier mode MHD force components
Definition: shared_data.f90:99
shared_data::l_update_state
logical l_update_state
Update the ste array.
Definition: shared_data.f90:224
shared_data::fsqvu
real(dp) fsqvu
|F|^2 for u components.
Definition: shared_data.f90:129
shared_data::l_getwmhd
logical l_getwmhd
Compute MHD energy.
Definition: shared_data.f90:214
shared_data::fsq_total1
real(dp) fsq_total1
|F|^2 WITHOUT column scaling.
Definition: shared_data.f90:93
shared_data::fsupvmncf
real(dp), dimension(:,:,:), pointer fsupvmncf
Contravariant force for stellarator symmetric v component on full grid.
Definition: shared_data.f90:196
shared_data::l_conjgrad
logical l_conjgrad
FIXME: UNKNOWN.
Definition: shared_data.f90:212
siesta_namelist
This file contains all the variables and maximum sizes of the inputs for a SIESTA namelist input file...
Definition: siesta_namelist.f90:103
siesta_init
Initializes unperturbed siesta fields and pressure in real space.
Definition: siesta_init.f90:10
shared_data
This file contains variables and parameters used by many modules in SIESTA.
Definition: shared_data.f90:10
siesta_pressure
Updates pressure.
Definition: siesta_pressure.f90:11
shared_data::fsqvs
real(dp) fsqvs
|F|^2 for s components.
Definition: shared_data.f90:127
shared_data::fsupvmnsf
real(dp), dimension(:,:,:), pointer fsupvmnsf
Contravariant force for stellarator non-symmetric v component on full grid.
Definition: shared_data.f90:198
shared_data::wtotal0
real(dp) wtotal0
Saved MHD energy sum of magnetic and thermal.
Definition: shared_data.f90:123
shared_data::neqs
integer neqs
Number of elements in the xc array.
Definition: shared_data.f90:54
shared_data::gc0
real(dp), dimension(:), allocatable gc0
Saved fouier MHD forces.
Definition: shared_data.f90:108
island_params::vp_f
real(dp), dimension(:), allocatable vp_f
Volume of a radial grid surface.
Definition: island_params.f90:74