VMEC 8.52
3D Equilibrium solver with nested flux surfaces.
Loading...
Searching...
No Matches
mgrid_mod.f
Go to the documentation of this file.
1 MODULE mgrid_mod
2 USE stel_kinds
3 USE vmec_input, ONLY: lfreeb !, nbfld, nflxs, lrecon
4! USE vsvd0, ONLY: nigroup, nparts, npfcoil, nbcoilsp, nfloops,
5! 1 nbctotp
6 IMPLICIT NONE
7
8 LOGICAL :: lnverror=.true.
9 INTEGER, PARAMETER :: nlimset = 2 !number of different limiters
10 CHARACTER(LEN=*), PARAMETER ::
11 1 vn_br0 = 'br', vn_bp0 = 'bp', vn_bz0 = 'bz',
12 3 vn_ir = 'ir', vn_jz = 'jz',
13 4 vn_kp = 'kp', vn_nfp = 'nfp',
14 5 vn_rmin='rmin', vn_rmax='rmax', vn_zmin='zmin',
15 6 vn_zmax='zmax', vn_coilgrp='coil_group'
16 CHARACTER(LEN=*), PARAMETER ::
17 1 vn_nextcur = 'nextcur', vn_mgmode='mgrid_mode',
18 2 vn_coilcur = 'raw_coil_cur',
19 3 vn_flp = 'nobser', vn_nobd = 'nobd', vn_nbset = 'nbsets',
20 4 vn_nbfld = 'nbfld',
21 2 ln_flp = 'flux loops', ln_nobd = 'Connected flux loops',
22 3 ln_nbset = 'B-coil loops', ln_next = 'External currents',
23 4 ln_nbfld = 'B-coil measurements'
24
25C-----------------------------------------------
26C L o c a l V a r i a b l e s
27C-----------------------------------------------
28! nr0b, np0b, nz0b:
29! : grid dimensions of magnetic field in mgrid file
30! nbvac : total number of grid points (nr0b*np0b*nz0b) in mgrid file
31! bvac(:,1): br (radial component of external magnetic field)
32! bvac(:,2): bp (toroidal component)
33! bvac(:,3) = bz (z-component)
34! rminb, rmaxb : min (max) radial dimension of grid in mgrid
35! zminb, zmaxb : min (max) vertical dimension of grid in mgrid
36!
37! nextcur: no. of EXTERNAL current groups (eg., TF, PF, helical)
38! raw_coil_current array of raw currents for each coil group
39! mgrid_mode = 'S', scaled mode; = 'R', raw mode
40! curlabel: array of labels describing each current group
41! included in green''s FUNCTION BFIELD response
42!
43! - - - - - - - - - - - - - - - - - -
44! FOR DIAGNOSTICS AND DATA ANALYSIS
45! (HERE,COILS ARE FOR MEASURING FIELDS, FLUXES)
46! iconnect: two-dimensional array describing electrical
47! needflx: =NEEDIT, loop required for flux match
48! >=ISYMCOIL, loop required but flux computed by
49! invoking symmetry in Z
50! =IDONTNEED, loop not required for flux match
51! needbfld: =NEEDIT, loop required for B-field match
52! =ISAMECOIL, loop at same position as previous loop
53! >=ISYMCOIL, loop required but B-field computed
54! by invoking symmetry in Z
55! =IDONTNEED, loop not required in B-field match
56! dsiext: connected flux loop signals due to EXTERNAL coils
57! plflux: array of measured (inferred) plasma contrib. to flux loops
58! plbfld: array of measured (inferred) plasma contrib. to B-loops
59! connection of up to four flux loops. Specifies
60! the sign and flux loop number of (up to) four
61! connected individual loops (indexing based on
62! xobser,zobser arrays).
63! nobd: number of connected flux loop measurements
64! nobser: number of individual flux loop positions
65! nbsets: number of B-coil sets defined in mgrid file
66! nbcoils(n): number of bfield coils in each set defined in mgrid file
67! nbcoilsn: total number of bfield coils defined in mgrid file
68! nbfldn: total number of EXTERNAL bfield measurements used in matching
69! bloopnames: array of labels describing b-field sets
70! dsilabel: array of labels describing connected flux loops
71! xobser: array of flux loop R-positions
72! zobser: array of flux loop Z-positions
73! rbcoil(m,n): R position of the m-th coil in the n-th set from mgrid file
74! zbcoil(m,n): Z position of the m-th coil in the n-th set from mgrid file
75! abcoil(m,n): orientation (surface normal wrt R axis; in radians)
76!
77 INTEGER :: nr0b, np0b, nfper0, nz0b
80 1 nrgrid, nzgrid
81 INTEGER, DIMENSION(:), ALLOCATABLE :: needflx, nbcoils
82 INTEGER, DIMENSION(:), ALLOCATABLE :: limitr, nsetsn
83 INTEGER, DIMENSION(:,:), ALLOCATABLE :: iconnect, needbfld
85 REAL(rprec) ::rx1, rx2, zy1, zy2, condif
86 REAL(rprec), DIMENSION(:,:), ALLOCATABLE, TARGET :: bvac
87 REAL(rprec), DIMENSION(:,:,:), POINTER :: brvac, bzvac, bpvac
88 REAL(rprec), DIMENSION(:,:), ALLOCATABLE :: unpsiext,
90 REAL(rprec), DIMENSION(:), ALLOCATABLE :: raw_coil_current
91 REAL(rprec), DIMENSION(:), ALLOCATABLE :: xobser, zobser,
93 CHARACTER(LEN=300) :: mgrid_path
94 CHARACTER(LEN=300) :: mgrid_path_old = " "
95 CHARACTER(LEN=30), DIMENSION(:), ALLOCATABLE :: curlabel
96 CHARACTER(LEN=15), DIMENSION(:), ALLOCATABLE ::
98 CHARACTER(LEN=30) :: tokid
99 REAL(rprec), DIMENSION(:,:,:), ALLOCATABLE :: dbcoil, pfcspec
100 REAL(rprec), DIMENSION(:,:), ALLOCATABLE ::
102 CHARACTER(LEN=1) :: mgrid_mode
103
104c !DEC$ IF DEFINED (NETCDF)
105 PRIVATE :: read_mgrid_bin, read_mgrid_nc
106c !DEC$ ELSE
107c PRIVATE :: read_mgrid_bin
108c !DEC$ ENDIF
109
110 CONTAINS
111
112 SUBROUTINE read_mgrid (mgrid_file, extcur, nv, nfp, lscreen,
113 1 ier_flag)
114 !USE system_mod
115 IMPLICIT NONE
116C-----------------------------------------------
117C D u m m y V a r i a b l e s
118C-----------------------------------------------
119!
120! mgrid_file: full path to mgrid file
121! lscreen : logical controlling output to screen
122! ier_flag ; error flag returned to caller
123! extcur(n) : external current multiplier for bfield(n) components
124!
125 INTEGER, INTENT(out) :: ier_flag
126 INTEGER, INTENT(in) :: nv, nfp
127 LOGICAL, INTENT(in) :: lscreen
128 REAL(rprec), INTENT(in) :: extcur(:)
129 CHARACTER(len=*), INTENT(in) :: mgrid_file
130C-----------------------------------------------
131C L o c a l P a r a m e t e r s
132C-----------------------------------------------
133c !DEC$ IF DEFINED (VMS)
134c CHARACTER(LEN=*), PARAMETER :: mgrid_defarea='vmec$:[makegrid]'
135c !DEC$ ELSE
136 CHARACTER(LEN=*), PARAMETER :: mgrid_defarea='$HOME/vmec/MAKEGRID'
137c !DEC$ ENDIF
138C-----------------------------------------------
139C L o c a l V a r i a b l e s
140C-----------------------------------------------
141!
142! lgrid_exist : logical set if mgrid file is found in given path
143!
144 INTEGER :: istat, ii
145 CHARACTER(LEN=200) :: home_dir
146 LOGICAL :: lgrid_exist, lfind
147C-----------------------------------------------
148 mgrid_path(:) = ' '
149 mgrid_path = trim(mgrid_file)
150
151 IF ((mgrid_path .eq. trim(mgrid_path_old)) .and.
152 1 ALLOCATED(curlabel)) THEN
153 print *,' mgrid file previously parsed!'
154 RETURN
155 END IF
156
157 INQUIRE (file=mgrid_path,exist=lgrid_exist,iostat=istat)
158 IF (istat.ne.0 .or. .not.lgrid_exist) THEN
159 IF (lscreen) print *,' MGRID FILE NOT FOUND IN SPECIFIED ',
160 1 'PATH: SEARCHING DEFAULT AREA'
161c ii = INDEX(mgrid_file,'/',back=.true.)
162c istat = INDEX(mgrid_defarea, '$HOME')
163c IF (istat .ne. 0) THEN
164c CALL getenv('HOME', home_dir)
165c IF (istat .gt. 1) THEN
166c home_dir = mgrid_defarea(1:istat-1) // TRIM(home_dir)
167c 1 // mgrid_defarea(istat+5:)
168c ELSE
169c home_dir = TRIM(home_dir) // mgrid_defarea(istat+5:)
170c END IF
171c ELSE
172c home_dir = mgrid_defarea
173c END IF
174c mgrid_path = TRIM(home_dir) // mgrid_file(ii+1:)
175c INQUIRE (file=mgrid_path,exist=lgrid_exist,iostat=istat)
176 END IF
177
179
180 ier_flag = 0
181
182 IF (lgrid_exist) THEN
183 IF (lscreen) print '(2x,2a)',
184 1 'Opening vacuum field file: ', trim(mgrid_file)
185!
186! Parse mgrid file name, look for .nc extension (netcdf format)
187!
188 ii = len_trim(trim(mgrid_path)) - 2
189 lfind = (mgrid_path(ii:ii+2) == '.nc')
190 IF (lfind) THEN
191c !DEC$ IF DEFINED (NETCDF)
192 CALL read_mgrid_nc (mgrid_path, extcur, nv, nfp,
193 1 ier_flag, lscreen)
194c !DEC$ ELSE
195c lgrid_exist = .false.
196c !DEC$ ENDIF
197 ELSE
198 CALL read_mgrid_bin (mgrid_path, extcur, nv, nfp,
199 1 ier_flag, lscreen)
200 END IF
201
202 IF (np0b .ne. nv) THEN
203 IF (lnverror) print *,' NZETA=',nv,
204 1 ' NOT EQUAL TO NP0B=',np0b,' IN MGRID FILE'
205 ier_flag = 9
206 ELSE IF (nfper0.ne.nfp) THEN
207 print *,' NFP(READ in) = ',nfp,' DOES NOT AGREE WITH ',
208 1 'NFPER (in vacuum field file) = ',nfper0
209 ier_flag = 9
210 END IF
211
212 END IF
213
214 IF (ier_flag .ne. 0) RETURN
215
216 IF (.not.lgrid_exist .or. ier_flag.ne.0) THEN
217 lfreeb = .false.
218c lrecon = .false.
219 IF (lscreen) THEN
220 print *, ' Error opening/reading mgrid file in dir: ',
221 1 trim(home_dir)
222 print *, ' User must supply vacuum bfield in mgrid to ',
223 1 'run vmec in free-boundary mode!'
224 print *, ' Proceeding to run vmec in',
225 1 ' fixed boundary mode'
226 END IF
227 END IF
228
229 END SUBROUTINE read_mgrid
230
231
232 SUBROUTINE read_mgrid_bin (filename, extcur, nv, nfp, ier_flag,
233 1 lscreen)
234 USE safe_open_mod
235 IMPLICIT NONE
236C-----------------------------------------------
237C D u m m y A r g u m e n t s
238C-----------------------------------------------
239!
240! lstyle_2000 : logical controlling ordering of magnetic field components read in
241!
242 INTEGER, INTENT(in) :: nv, nfp
243 CHARACTER(LEN=*), INTENT(in) :: filename
244 REAL(rprec), INTENT(in) :: extcur(:)
245C-----------------------------------------------
246C L o c a l V a r i a b l e s
247C-----------------------------------------------
248 REAL(rprec), DIMENSION(:,:,:), ALLOCATABLE ::
249 1 brtemp, bztemp, bptemp
250 INTEGER :: ier_flag, iunit = 50
251 integer :: istat, ig, i, j, n, n1, m, nsets_max, k
252 LOGICAL :: lscreen, lstyle_2000
253C-----------------------------------------------
254
255 CALL safe_open(iunit, istat, filename, 'old', 'unformatted')
256 IF (istat .ne. 0) THEN
257 ier_flag = 9
258 RETURN
259 END IF
260
261 READ (iunit,iostat=istat) nr0b, nz0b, np0b, nfper0, nextcur
262 IF (istat .ne. 0) ier_flag = 9
263
264 IF (nfper0.ne.nfp .or. np0b.ne.nv) RETURN
265
266 lstyle_2000 = (nextcur < 0)
267 nextcur = abs(nextcur)
268 READ(iunit,iostat=istat) rminb, zminb, rmaxb, zmaxb
269 IF (istat .ne. 0) ier_flag = 9
270
271 IF (nextcur .eq. 0) THEN
272 print *,' NEXTCUR = 0 IN READING MGRID FILE'
273 ier_flag = 9
274c ELSE IF (nextcur .gt. nigroup) THEN
275c PRINT *,' NEXTCUR > NIGROUP IN MGRID FILE'
276c ier_flag = 9
277 END IF
278
279 IF (ier_flag .ne. 0) RETURN
280
281 ALLOCATE (curlabel(5*(nextcur/5+1)), stat=istat) !MIN of 5 for printing
282 curlabel = " "
283 READ(iunit,iostat=istat) (curlabel(n),n=1,nextcur)
284 IF (istat .ne. 0) THEN
285 print *,' reading mgrid file failed (curlabel)'
286 ier_flag = 9
287 RETURN
288 END IF
289
290!
291! NOTE: ADD UP CONTRIBUTION TO BVAC DIRECTLY FOR ALL EXTERNAL CURRENT GROUPS
292
294 IF (.NOT. ALLOCATED(bvac)) THEN
295 ALLOCATE (bvac(nbvac,3))
296 ELSE IF (SIZE(bvac,1) .ne. nbvac) THEN
297 DEALLOCATE (bvac); ALLOCATE(bvac(nbvac,3))
298 END IF
299
300 ALLOCATE (brtemp(nr0b,nz0b,np0b), bptemp(nr0b,nz0b,np0b),
301 1 bztemp(nr0b,nz0b,np0b), stat=istat)
302
303 IF (istat .ne. 0) THEN
304 print *,' allocation for b-vector storage failed'
305 ier_flag = 9
306 RETURN
307 END IF
308
309 bvac = 0
310
311 DO ig = 1,nextcur
312 IF (lstyle_2000) THEN
313 READ(iunit, iostat=istat) brtemp, bptemp, bztemp
314 ELSE
315 READ(iunit, iostat=istat) (((brtemp(i,j,k), bztemp(i,j,k),
316 1 bptemp(i,j,k), i= 1,nr0b),
317 2 j=1,nz0b), k=1,np0b)
318 END IF
319!
320! STORE SUMMED BFIELD (OVER COIL GROUPS) IN BVAC
321!
322 CALL sum_bfield(bvac(1,1), brtemp, extcur(ig), nbvac)
323 CALL sum_bfield(bvac(1,2), bptemp, extcur(ig), nbvac)
324 CALL sum_bfield(bvac(1,3), bztemp, extcur(ig), nbvac)
325
326 END DO
327
328 DEALLOCATE (brtemp, bztemp, bptemp)
329
330 IF (istat .ne. 0) THEN
331 ier_flag = 9
332 RETURN
333 END IF
334
335 IF (lstyle_2000) THEN
336 READ (iunit, iostat=istat) mgrid_mode
337 IF (istat .eq. 0) THEN
338 ALLOCATE (raw_coil_current(nextcur))
339 READ (iunit, iostat=istat) raw_coil_current(1:nextcur)
340 IF (istat .ne. 0) mgrid_mode = 'N'
341 END IF
342 ELSE
343 mgrid_mode = 'N' !Old-style, no mode info
344 END IF
345
346!
347! READ IN EXTERNAL POLOIDAL FLUX, FIELD MEASURMENT
348! LOOP COORDINATES AND LABELS
349!
350 READ(iunit,iostat=istat) nobser, nobd, nbsets
351 IF (istat.ne.0) THEN
352 nobser = 0
353 nobd = 0
354 nbsets = 0
355 IF (lscreen) print *,' No observation data in mgrid data'
356 GOTO 900
357 END IF
358
359c nbfldn = SUM(nbfld(:nbsets))
360c ALLOCATE (nbcoils(nbsets), stat=istat)
361c READ(iunit) (nbcoils(n),n=1,nbsets)
362c
363c nbcoil_max = MAXVAL(nbcoils(:nbsets))
364c
365c ALLOCATE (xobser(nobser), zobser(nobser), dsilabel(nobd),
366c 1 iconnect(4,nobser+nobd), unpsiext(nobser,nextcur),
367c 2 xobsqr(nobser), needflx(nobser), plflux(nobser+nobd),
368c 3 dsiext(nobd), psiext(nobser), bloopnames(nbsets),
369c 4 needbfld(nbcoil_max,nbsets), plbfld(nbcoil_max,nbsets),
370c 5 rbcoil(nbcoil_max,nbsets), zbcoil(nbcoil_max,nbsets),
371c 6 abcoil(nbcoil_max,nbsets), bcoil(nbcoil_max,nbsets),
372c 7 rbcoilsqr(nbcoil_max,nbsets), b_chi(nbsets),
373c 8 dbcoil(nbcoil_max,nbsets,nextcur), stat = istat)
374c IF (istat .ne. 0) THEN
375c IF (lscreen)
376c 1 PRINT *,' allocation error for xobser: istat = ',istat
377c ier_flag = 9
378c RETURN
379c END IF
380c
381c IF (nobser .gt. nfloops) THEN
382c PRINT *, 'NOBSER>NFLOOPS'
383c ier_flag = 9
384c END IF
385c IF (nobd .gt. nfloops) THEN
386c PRINT *, 'NOBD>NFLOOPS'
387c ier_flag = 9
388c END IF
389c IF (nflxs .gt. nfloops) THEN
390c PRINT *, 'NFLXS>NFLOOPS'
391c ier_flag = 9
392c END IF
393c IF (nbfldn .gt. nbctotp) THEN
394c PRINT *, 'NBFLDN>NBCTOTP'
395c ier_flag = 9
396c END IF
397c IF (nbcoil_max .gt. nbcoilsp) THEN
398c PRINT *, 'NBCOIL_max>NBCOILSP'
399c ier_flag = 9
400c END IF
401c
402c IF (ier_flag .ne. 0) RETURN
403c
404c IF (nobser+nobd .gt. 0) iconnect(:4,:nobser+nobd) = 0
405c
406c READ(iunit) (xobser(n), zobser(n),n=1,nobser)
407c READ(iunit) (dsilabel(n),n=1,nobd)
408c READ(iunit) ((iconnect(j,n),j=1,4),n=1,nobd)
409c
410c IF (nbcoil_max.gt.0 .and. nbsets.gt.0) THEN
411c rbcoil(:nbcoil_max,:nbsets) = 0
412c zbcoil(:nbcoil_max,:nbsets) = 0
413c abcoil(:nbcoil_max,:nbsets) = 0
414c
415c DO n=1,nbsets
416c IF (nbcoils(n).gt.0) THEN
417c READ(iunit) n1,bloopnames(n1)
418c READ(iunit)(rbcoil(m,n),zbcoil(m,n),abcoil(m,n),
419c 1 m=1,nbcoils(n))
420c ENDIF
421c ENDDO
422c
423c dbcoil(:nbcoil_max,:nbsets,:nextcur) = 0
424c END IF
425c DO ig = 1,nextcur
426c !un-connected coil fluxes
427c READ(iunit) (unpsiext(n,ig),n=1,nobser)
428c DO n = 1,nbsets
429c READ(iunit) (dbcoil(m,n,ig),m=1,nbcoils(n))
430c ENDDO
431c ENDDO
432c
433c !
434c ! READ LIMITER & PROUT PLOTTING SPECS
435c !
436c ALLOCATE (limitr(nlimset), nsetsn(nigroup))
437c
438c READ (iunit,iostat=istat) nlim,(limitr(i),i=1,nlim)
439c IF (istat .ne. 0)then
440c nlim = 0
441c IF (lscreen) PRINT *,' No limiter data in mgrid file'
442c GOTO 900
443c END IF
444c
445c nlim_max = MAXVAL(limitr)
446c
447c IF (nlim .gt. nlimset) THEN
448c PRINT *, 'nlim>nlimset'
449c ier_flag = 9
450c RETURN
451c END IF
452c
453c ALLOCATE( rlim(nlim_max,nlim), zlim(nlim_max,nlim),
454c 1 reslim(nlim_max,nlim) ,seplim(nlim_max,nlim),
455c 2 stat=istat)
456c IF (istat .ne. 0) THEN
457c PRINT *, 'rlim istat!=0'
458c ier_flag = 9
459c RETURN
460c END IF
461c
462c READ(iunit, iostat=istat)
463c 1 ((rlim(i,j),zlim(i,j),i=1,limitr(j)),j=1,nlim)
464c READ(iunit, iostat=istat) nsets,(nsetsn(i), i=1,nsets)
465c
466c IF (nsets .gt. nigroup) THEN
467c PRINT *, 'nsets>nigroup'
468c ier_flag = 9
469c RETURN
470c ELSE IF (istat .ne. 0) THEN
471c ier_flag = 9
472c RETURN
473c END IF
474c
475c nsets_max = MAXVAL(nsetsn)
476c
477c IF (nsets_max .gt. npfcoil) THEN
478c PRINT *, 'nsetsn>npfcoil'
479c ier_flag = 9
480c RETURN
481c END IF
482c
483c ALLOCATE (pfcspec(nparts,nsets_max,nsets), stat=istat)
484c
485c ! NOTE TO RMW: SHOULD READ IN NPARTS HERE (PUT INTO MGRID FILE)
486c
487c READ(iunit, iostat=istat) (((pfcspec(i,j,k),i=1,nparts),
488c 1 j=1,nsetsn(k)), k=1,nsets)
489c
490c DEALLOCATE (limitr, nsetsn)
491c
492c READ(iunit, iostat=istat) rx1,rx2,zy1,zy2,condif,
493c 1 nrgrid,nzgrid,tokid
494c
495c IF (istat .ne. 0) THEN
496c ier_flag = 9
497c RETURN
498c END IF
499c
500c IF (nobser .gt. 0) xobsqr(:nobser) = SQRT(xobser(:nobser))
501c !
502c ! PARTITION MGRID B-LOOPS INTO SETS
503c !
504c nbcoilsn = SUM(nbcoils(:nbsets))
505c
506c DO n = 1,nbsets
507c rbcoilsqr(:nbcoils(n),n) = SQRT(rbcoil(:nbcoils(n),n))
508c ENDDO
509
510 900 CONTINUE
511
512 CLOSE (iunit)
513
514 delrb = (rmaxb-rminb)/(nr0b-1)
515 delzb = (zmaxb-zminb)/(nz0b-1)
516
517!
518! SUM UP CONTRIBUTIONS FROM INDIVIDUAL COIL GROUPS
519!
520 IF (lfreeb) THEN
521 IF (nobser .gt. 0) psiext(:nobser) = 0
522 IF (nbcoil_max.gt.0 .and. nbsets.gt.0)
523 1 bcoil(:nbcoil_max, :nbsets) = 0
524
525 DO ig = 1,nextcur
526 IF (nobser .gt. 0)
527 1 psiext(:nobser) = psiext(:nobser) +
528 2 extcur(ig)*unpsiext(:nobser,ig)
529 DO n=1,nbsets
530 n1 = nbcoils(n)
531 bcoil(:n1,n) = bcoil(:n1,n) +
532 1 extcur(ig)*dbcoil(:n1,n,ig)
533 ENDDO
534 ENDDO
535 ENDIF !!IF LFREEB
536
537 END SUBROUTINE read_mgrid_bin
538
539c !DEC$ IF DEFINED (NETCDF)
540 SUBROUTINE read_mgrid_nc (filename, extcur, nv, nfp,
541 1 ier_flag, lscreen)
542 USE ezcdf
543 IMPLICIT NONE
544C-----------------------------------------------
545C D u m m y A r g u m e n t s
546C-----------------------------------------------
547 CHARACTER(LEN=*), INTENT(in) :: filename
548 INTEGER, INTENT(in) :: nv, nfp
549 REAL(rprec), INTENT(in) :: extcur(:)
550C-----------------------------------------------
551C L o c a l V a r i a b l e s
552C-----------------------------------------------
553 REAL(rprec), DIMENSION(:,:,:), ALLOCATABLE ::
554 1 brtemp, bztemp, bptemp
555 INTEGER :: ier_flag, ngrid
556 INTEGER :: istat, ig
557 LOGICAL :: lscreen
558 INTEGER, DIMENSION(3) :: dimlens
559 CHARACTER(LEN=100) :: temp
560 CHARACTER(LEN=100), ALLOCATABLE, DIMENSION(:) ::
561 1 vn_br, vn_bp, vn_bz
562C-----------------------------------------------
563 call cdf_open(ngrid, filename,'r', istat)
564 IF (istat .ne. 0) THEN
565 ier_flag = 9
566 RETURN
567 END IF
568
569!
570! READ IN DATA
571!
572 CALL cdf_read(ngrid, vn_ir, nr0b)
573 CALL cdf_read(ngrid, vn_jz, nz0b)
574 CALL cdf_read(ngrid, vn_kp, np0b)
575 CALL cdf_read(ngrid, vn_nfp, nfper0)
576
577 IF (nfper0.ne.nfp .or. np0b.ne.nv) RETURN
578
579 CALL cdf_read(ngrid, vn_nextcur, nextcur)
580
581 IF (nextcur .eq. 0) THEN
582 print *,' NEXTCUR = 0 IN READING MGRID FILE'
583 ier_flag = 9
584 RETURN
585c ELSE IF (nextcur .gt. nigroup) THEN
586c PRINT *,' NEXTCUR > NIGROUP IN MGRID FILE'
587c ier_flag = 9
588c RETURN
589 END IF
590
591 CALL cdf_read(ngrid, vn_rmin, rminb)
592 CALL cdf_read(ngrid, vn_zmin, zminb)
593 CALL cdf_read(ngrid, vn_rmax, rmaxb)
594 CALL cdf_read(ngrid, vn_zmax, zmaxb)
595
596 delrb = (rmaxb-rminb)/(nr0b-1)
597 delzb = (zmaxb-zminb)/(nz0b-1)
598
599 CALL cdf_inquire(ngrid, vn_coilgrp, dimlens)
600 IF (.NOT. ALLOCATED(curlabel)) THEN
601 ALLOCATE (curlabel(nextcur), stat=istat)
602 ELSE IF (SIZE(curlabel) .ne. nextcur) THEN
603 DEALLOCATE (curlabel)
604 ALLOCATE (curlabel(nextcur), stat=istat)
605 END IF
606!THIS IS A GLITCH WITH cdf_read: must distinguish 1D char array from multi-D
607 IF (nextcur .eq. 1) THEN
608 IF (istat .eq. 0)
609 1 CALL cdf_read(ngrid, vn_coilgrp, curlabel(1))
610 ELSE IF (istat .eq. 0) THEN
611 CALL cdf_read(ngrid, vn_coilgrp, curlabel(1:nextcur))
612 END IF
613
614 IF (istat .ne. 0) stop 'Error allocating CURLABEL in mgrid_mod'
615!
616! READ 3D Br, Bp, Bz ARRAYS FOR EACH COIL GROUP
617!
618 ALLOCATE (vn_br(nextcur), vn_bz(nextcur), vn_bp(nextcur),
619 1 stat=istat)
620 IF (istat .ne. 0) stop 'Error allocating vn_bX in mgrid_mod'
621
623 IF (.NOT. ALLOCATED(bvac)) THEN
624 ALLOCATE (bvac(nbvac,3), stat=istat)
625 ELSE IF (SIZE(bvac,1) .ne. nbvac) THEN
626 DEALLOCATE (bvac); ALLOCATE(bvac(nbvac,3), stat=istat)
627 END IF
628 IF (istat .ne. 0) stop 'Error allocating bvac in mgrid_mod'
629
630 bvac = 0
631
632 DO ig = 1, nextcur
633 WRITE (temp, '(a,i3.3)') "_",ig
634 vn_br(ig) = vn_br0 // temp
635 vn_bp(ig) = vn_bp0 // temp
636 vn_bz(ig) = vn_bz0 // temp
637 CALL cdf_inquire(ngrid, vn_br(ig), dimlens)
638 IF (.NOT. ALLOCATED(brtemp)) THEN
639 ALLOCATE (brtemp(dimlens(1),dimlens(2),dimlens(3)),
640 1 bptemp(dimlens(1),dimlens(2),dimlens(3)),
641 2 bztemp(dimlens(1),dimlens(2),dimlens(3)),
642 3 stat=istat)
643 IF (istat .ne. 0)stop 'Error allocating bXtemp in mgrid_mod'
644 END IF
645 CALL cdf_read(ngrid, vn_br(ig), brtemp)
646 CALL cdf_read(ngrid, vn_bp(ig), bptemp)
647 CALL cdf_read(ngrid, vn_bz(ig), bztemp)
648
649!
650! STORE SUMMED BFIELD (OVER COIL GROUPS) IN BVAC
651!
652 CALL sum_bfield(bvac(1,1), brtemp, extcur(ig), nbvac)
653 CALL sum_bfield(bvac(1,2), bptemp, extcur(ig), nbvac)
654 CALL sum_bfield(bvac(1,3), bztemp, extcur(ig), nbvac)
655
656 END DO
657
658!
659! MUST ADD EXTERNAL LOOP STUFF LATER
660! MAY DECIDE TO WRITE THAT INFO INTO A SEPARATE FILE
661! FOR NOW, JUST SET DEFAULTS
662!
663 nobser = 0
664 nobd = 0
665 nbsets = 0
666
667 CALL cdf_inquire(ngrid, vn_mgmode, dimlens, ier=istat)
668 IF (istat .eq. 0) THEN
669 CALL cdf_read(ngrid, vn_mgmode, mgrid_mode)
670 ELSE
671 mgrid_mode = 'N'
672 END IF
673
674 CALL cdf_inquire(ngrid, vn_coilcur, dimlens, ier=istat)
675 IF (istat .eq. 0) THEN
676 IF (ALLOCATED(raw_coil_current)) DEALLOCATE(raw_coil_current)
677 ALLOCATE (raw_coil_current(nextcur), stat=istat)
678 IF (istat .ne. 0) stop 'Error allocating RAW_COIL in mgrid_mod'
679 CALL cdf_read(ngrid, vn_coilcur, raw_coil_current)
680 END IF
681
682 CALL cdf_close(ngrid)
683
684 IF (ALLOCATED(brtemp))
685 1 DEALLOCATE (vn_br, vn_bz, vn_bp, brtemp, bptemp, bztemp)
686
687 END SUBROUTINE read_mgrid_nc
688c !DEC$ ENDIF
689
690 SUBROUTINE sum_bfield(bfield, bf_add, cur, n1)
691 INTEGER :: n1
692 REAL(rprec), INTENT(inout) :: bfield(n1)
693 REAL(rprec), INTENT(in) :: bf_add(n1)
694 REAL(rprec) :: cur
695
696 bfield = bfield + cur*bf_add
697
698 END SUBROUTINE sum_bfield
699
700 SUBROUTINE assign_bptrs(bptr)
701 IMPLICIT NONE
702 REAL(rprec), TARGET, INTENT(in) :: bptr(nr0b,nz0b,np0b,3)
703
704 brvac => bptr(:,:,:,1)
705 bpvac => bptr(:,:,:,2)
706 bzvac => bptr(:,:,:,3)
707
708 END SUBROUTINE assign_bptrs
709
710 SUBROUTINE free_mgrid (istat)
711 INTEGER :: istat
712
713 istat = 0
714 mgrid_path_old = ''
715
716 IF (ALLOCATED(bvac)) DEALLOCATE (bvac,stat=istat)
717 IF (ALLOCATED(xobser))
718 1 DEALLOCATE (xobser, xobsqr, zobser, unpsiext, dsiext,
721 4 pfcspec,dsilabel, bloopnames, curlabel, b_chi, stat=istat)
722 IF (ALLOCATED(raw_coil_current)) DEALLOCATE(raw_coil_current)
723
724 IF (ALLOCATED(rlim))
725 1 DEALLOCATE (rlim,zlim, reslim,seplim,stat=istat)
726
727 END SUBROUTINE free_mgrid
728
729 END MODULE mgrid_mod
integer, dimension(:), allocatable nbcoils
Definition mgrid_mod.f:81
real(rprec), dimension(:,:), allocatable seplim
Definition mgrid_mod.f:100
real(rprec), dimension(:), allocatable xobser
Definition mgrid_mod.f:91
integer nzgrid
Definition mgrid_mod.f:79
character(len= *), parameter vn_mgmode
Definition mgrid_mod.f:16
integer nobd
Definition mgrid_mod.f:78
real(rprec), dimension(:,:,:), pointer brvac
Definition mgrid_mod.f:87
integer, dimension(:), allocatable nsetsn
Definition mgrid_mod.f:82
real(rprec), dimension(:,:), allocatable unpsiext
Definition mgrid_mod.f:88
integer nbvac
Definition mgrid_mod.f:79
real(rprec), dimension(:,:), allocatable abcoil
Definition mgrid_mod.f:88
character(len= *), parameter vn_br0
Definition mgrid_mod.f:10
character(len=30), dimension(:), allocatable curlabel
Definition mgrid_mod.f:95
character(len=1) mgrid_mode
Definition mgrid_mod.f:102
subroutine free_mgrid(istat)
Definition mgrid_mod.f:711
real(rprec), dimension(:), allocatable dsiext
Definition mgrid_mod.f:91
real(rprec), dimension(:), allocatable plflux
Definition mgrid_mod.f:91
integer nbfldn
Definition mgrid_mod.f:78
subroutine read_mgrid(mgrid_file, extcur, nv, nfp, lscreen, ier_flag)
Definition mgrid_mod.f:114
real(rprec) delzb
Definition mgrid_mod.f:84
real(rprec), dimension(:,:), allocatable rbcoilsqr
Definition mgrid_mod.f:88
real(rprec) zy1
Definition mgrid_mod.f:85
real(rprec) rx1
Definition mgrid_mod.f:85
real(rprec), dimension(:), allocatable raw_coil_current
Definition mgrid_mod.f:90
character(len= *), parameter vn_zmax
Definition mgrid_mod.f:10
character(len= *), parameter vn_kp
Definition mgrid_mod.f:10
integer nr0b
Definition mgrid_mod.f:77
real(rprec), dimension(:), allocatable b_chi
Definition mgrid_mod.f:91
character(len= *), parameter vn_jz
Definition mgrid_mod.f:10
character(len= *), parameter vn_bz0
Definition mgrid_mod.f:10
integer nlim
Definition mgrid_mod.f:79
character(len= *), parameter vn_nobd
Definition mgrid_mod.f:16
integer, dimension(:), allocatable needflx
Definition mgrid_mod.f:81
character(len= *), parameter vn_nfp
Definition mgrid_mod.f:10
real(rprec), dimension(:), allocatable psiext
Definition mgrid_mod.f:91
real(rprec), dimension(:,:), allocatable bcoil
Definition mgrid_mod.f:88
real(rprec) zminb
Definition mgrid_mod.f:84
integer nrgrid
Definition mgrid_mod.f:79
integer, dimension(:,:), allocatable needbfld
Definition mgrid_mod.f:83
character(len= *), parameter vn_zmin
Definition mgrid_mod.f:10
real(rprec), dimension(:,:), allocatable rbcoil
Definition mgrid_mod.f:88
real(rprec), dimension(:,:), allocatable rlim
Definition mgrid_mod.f:100
character(len=15), dimension(:), allocatable bloopnames
Definition mgrid_mod.f:96
character(len= *), parameter vn_flp
Definition mgrid_mod.f:16
integer nextcur
Definition mgrid_mod.f:78
integer, parameter nlimset
Definition mgrid_mod.f:9
character(len=30) tokid
Definition mgrid_mod.f:98
real(rprec), dimension(:,:,:), pointer bpvac
Definition mgrid_mod.f:87
character(len= *), parameter vn_rmin
Definition mgrid_mod.f:10
integer nfper0
Definition mgrid_mod.f:77
real(rprec), dimension(:,:), allocatable, target bvac
Definition mgrid_mod.f:86
character(len= *), parameter vn_coilcur
Definition mgrid_mod.f:16
real(rprec), dimension(:,:), allocatable reslim
Definition mgrid_mod.f:100
real(rprec), dimension(:,:,:), allocatable dbcoil
Definition mgrid_mod.f:99
real(rprec) zmaxb
Definition mgrid_mod.f:84
character(len= *), parameter vn_ir
Definition mgrid_mod.f:10
character(len= *), parameter ln_flp
Definition mgrid_mod.f:16
integer nbcoil_max
Definition mgrid_mod.f:79
real(rprec) condif
Definition mgrid_mod.f:85
real(rprec) rminb
Definition mgrid_mod.f:84
character(len= *), parameter ln_nobd
Definition mgrid_mod.f:16
real(rprec) rmaxb
Definition mgrid_mod.f:84
real(rprec), dimension(:,:), allocatable zbcoil
Definition mgrid_mod.f:88
character(len= *), parameter ln_nbset
Definition mgrid_mod.f:16
real(rprec), dimension(:,:,:), allocatable pfcspec
Definition mgrid_mod.f:99
integer, dimension(:), allocatable limitr
Definition mgrid_mod.f:82
integer nz0b
Definition mgrid_mod.f:77
subroutine sum_bfield(bfield, bf_add, cur, n1)
Definition mgrid_mod.f:691
character(len= *), parameter vn_coilgrp
Definition mgrid_mod.f:10
integer nbcoilsn
Definition mgrid_mod.f:78
logical lnverror
Definition mgrid_mod.f:8
character(len= *), parameter vn_nbfld
Definition mgrid_mod.f:16
integer, dimension(:,:), allocatable iconnect
Definition mgrid_mod.f:83
real(rprec), dimension(:), allocatable xobsqr
Definition mgrid_mod.f:91
real(rprec) rx2
Definition mgrid_mod.f:85
character(len=300) mgrid_path
Definition mgrid_mod.f:93
real(rprec) zy2
Definition mgrid_mod.f:85
real(rprec) delrb
Definition mgrid_mod.f:84
character(len= *), parameter ln_nbfld
Definition mgrid_mod.f:16
subroutine assign_bptrs(bptr)
Definition mgrid_mod.f:701
character(len= *), parameter ln_next
Definition mgrid_mod.f:16
character(len=15), dimension(:), allocatable dsilabel
Definition mgrid_mod.f:96
real(rprec), dimension(:,:), allocatable plbfld
Definition mgrid_mod.f:88
real(rprec), dimension(:,:,:), pointer bzvac
Definition mgrid_mod.f:87
integer nlim_max
Definition mgrid_mod.f:79
real(rprec), dimension(:,:), allocatable zlim
Definition mgrid_mod.f:100
integer np0b
Definition mgrid_mod.f:77
integer nobser
Definition mgrid_mod.f:78
character(len=300) mgrid_path_old
Definition mgrid_mod.f:94
integer nsets
Definition mgrid_mod.f:79
character(len= *), parameter vn_nextcur
Definition mgrid_mod.f:16
character(len= *), parameter vn_nbset
Definition mgrid_mod.f:16
integer nbsets
Definition mgrid_mod.f:78
character(len= *), parameter vn_bp0
Definition mgrid_mod.f:10
real(rprec), dimension(:), allocatable zobser
Definition mgrid_mod.f:91
character(len= *), parameter vn_rmax
Definition mgrid_mod.f:10
fault-tolerant file opening routines
subroutine safe_open(iunit, istat, filename, filestat, fileform, record_in, access_in, delim_in)
integer, parameter rprec
logical lfreeb