V3FIT
bsc_cdf.f
1 !*******************************************************************************
2 ! File bsc_cdf.f
3 ! Contains the module bsc_cdf.f
4 ! Module for defining variables and writing netCDF files with the
5 ! derived types bsc_coil and bsc_coilcoll, from the bsc (Biot-Savart Coil) module
6 !
7 !-------------------------------------------------------------------------------
8 ! DEPENDENCIES
9 !-------------------------------------------------------------------------------
10 !
11 ! This module uses the following modules:
12 ! stel_kinds
13 ! bsc
14 ! ezcdf
15 !
16 !-------------------------------------------------------------------------------
17 ! CHANGE HISTORY
18 !-------------------------------------------------------------------------------
19 !
20 ! 12.13.2002 - Initial Coding - Ed Lazarus,
21 ! 12.16.2002 - JDH Initial Comments, limit to bsc_cdf subroutines
22 ! 12.17.2002 - JDH - return to using stel_kinds. Eliminate some unused variables.
23 ! 12.18.2002 - JDH - Eliminated identifier. Added prefix. Made _coilcoll routines
24 ! call the _coil routines.
25 ! 09.11.2003 - JDH - Added 'fil_rogo'wski information
26 ! 09-27-2004 - JDH - Added bsc_cdf_read_coil subroutine. Modified coding to be more
27 ! consistent with structure of diagnostic_cdf and signal_cdf.
28 !
29 !-------------------------------------------------------------------------------
30 ! USAGE
31 !-------------------------------------------------------------------------------
32 !-------------------------------------------------------------------------------
33 ! COMMENTS
34 !-------------------------------------------------------------------------------
35 !
36 !*******************************************************************************
37 
38 !*******************************************************************************
39 ! MODULE bsc_cdf
40 !
41 ! SECTION I. VARIABLE DECLARATIONS
42 ! SECTION II. INTERFACE BLOCKS
43 ! SECTION III. DEFINITION SUBROUTINES
44 ! SECTION IV. WRITING SUBROUTINES
45 ! SECTION V. READING SUBROUTINES
46 ! SECTION VI. AUXILLIARY FUNCTIONS
47 !*******************************************************************************
48 
49  MODULE bsc_cdf
50 
51 !*******************************************************************************
52 ! SECTION I. VARIABLE DECLARATIONS
53 !*******************************************************************************
54 
55 !-------------------------------------------------------------------------------
56 ! Type declarations - lengths of reals, integers, and complexes.
57 !-------------------------------------------------------------------------------
58 
59  USE stel_kinds
60  USE stel_constants
61  USE bsc_t
62  USE ezcdf
63  USE v3_utilities
64 
65 !-------------------------------------------------------------------------------
66 ! Implicit None comes after USE statements, before other declarations
67 !-------------------------------------------------------------------------------
68  IMPLICIT NONE
69 
70 !-------------------------------------------------------------------------------
71 ! Variable Names for netCDF
72 !-------------------------------------------------------------------------------
73 
74  CHARACTER (LEN=*), PARAMETER ::
75  & vn_c_type = 'c_type', &
76  & vn_s_name = 's_name', &
77  & vn_l_name = 'l_name', &
78  & vn_current = 'current', &
79  & vn_raux = 'raux', &
80  & vn_xnod = 'xnod', &
81  & vn_ehnod = 'ehnod', &
82  & vn_rcirc = 'rcirc', &
83  & vn_xcent = 'xcent', &
84  & vn_enhat = 'enhat', &
85  & vn_ave_n_area = 'ave_n_area'
86 
87  CHARACTER (LEN=64), PRIVATE ::
88  & vn_c_type_use, &
89  & vn_s_name_use, &
90  & vn_l_name_use, &
91  & vn_current_use, &
92  & vn_raux_use, &
93  & vn_xnod_use, &
94  & vn_ehnod_use, &
95  & vn_rcirc_use, &
96  & vn_xcent_use, &
97  & vn_enhat_use, &
98  & vn_ave_n_area_use
99 
100 !*******************************************************************************
101 ! SECTION II. INTERFACE BLOCKS
102 !*******************************************************************************
103 !-------------------------------------------------------------------------------
104 !
105 !-------------------------------------------------------------------------------
106 
107  CONTAINS
108 !*******************************************************************************
109 ! SECTION III. DEFINITION SUBROUTINES
110 !*******************************************************************************
111 !-------------------------------------------------------------------------------
112 !
113 !-------------------------------------------------------------------------------
114  SUBROUTINE bsc_cdf_define_coil(this,lunit,prefix)
115 ! Subroutine to do the appropriate netCDF definition calls for a bsc_coil
116 
117 !-----------------------------------------------
118 ! D u m m y A r g u m e n t s
119 !-----------------------------------------------
120  TYPE (bsc_coil), INTENT (in) :: this
121  INTEGER :: lunit
122  CHARACTER (len=*) :: prefix
123 
124 ! this bsc_coil - this is the coils that gets defined.
125 ! lunit i/o unit number
126 ! prefix character - prefixed to variable names, so that netCDF
127 ! doesn't have problems with repeated, identical names
128 !-----------------------------------------------
129 ! L o c a l V a r i a b l e s
130 !-----------------------------------------------
131  CHARACTER(len=32) :: prefix_use
132 !-----------------------------------------------
133 ! Start of Executable Code
134 !-----------------------------------------------
135 
136 ! Define the prefix to actually use
137  prefix_use = trim(adjustl(prefix))
138 
139 ! Define all vn_--_use variable names
140  CALL bsc_cdf_defvn_coil(prefix_use)
141 
142 ! Define Components common to all c_types
143  CALL cdf_define(lunit, trim(vn_c_type_use), this%c_type)
144  CALL cdf_define(lunit, trim(vn_s_name_use), this%s_name)
145  CALL cdf_define(lunit, trim(vn_l_name_use), this%l_name)
146  CALL cdf_define(lunit, trim(vn_current_use), this%current)
147  CALL cdf_define(lunit, trim(vn_raux_use), this%raux)
148 
149 ! Particular coding, depending on c_type
150 
151  SELECT CASE (this%c_type)
152 
153  CASE ('fil_loop','floop') ! Filamentary Loop Variables
154  IF (ASSOCIATED(this%xnod)) THEN
155  CALL cdf_define(lunit, trim(vn_xnod_use), this%xnod)
156  END IF ! this%xnod ASSOCIATED
157 
158  CASE ('fil_circ', 'fcirc') ! Filamentary Circle Variables
159  CALL cdf_define(lunit, trim(vn_rcirc_use), this%rcirc)
160  CALL cdf_define(lunit, trim(vn_xcent_use), this%xcent(1:3))
161  CALL cdf_define(lunit, trim(vn_enhat_use), this%enhat(1:3))
162 
163  CASE ('fil_rogo') ! Rogowskis
164  IF (ASSOCIATED(this%xnod)) THEN
165  CALL cdf_define(lunit, trim(vn_xnod_use), this%xnod)
166  END IF ! this%xnod ASSOCIATED
167  CALL cdf_define(lunit, trim(vn_ave_n_area_use), &
168  & this%ave_n_area)
169 
170  END SELECT
171 
172  END SUBROUTINE bsc_cdf_define_coil
173 
174 !-------------------------------------------------------------------------------
175 !
176 !-------------------------------------------------------------------------------
177  SUBROUTINE bsc_cdf_define_coilcoll(this,lunit)
178 ! Subroutine to do the appropriate netCDF definition calls for a bsc_coilcoll
179 ! To avoid duplicate names in the netCDF files, the variable names will
180 ! have a prefix added on.
181 
182 !-----------------------------------------------
183 ! D u m m y A r g u m e n t s
184 !-----------------------------------------------
185  TYPE (bsc_coilcoll), INTENT (in) :: this
186  INTEGER :: lunit
187 
188 ! this bsc_coilcoll - this is the coilcoll that gets defined.
189 ! lunit i/o unit number
190 !
191 !-----------------------------------------------
192 ! L o c a l V a r i a b l e s
193 !-----------------------------------------------
194  INTEGER :: i, n, ncoild
195  INTEGER dimlens(2)
196  CHARACTER(len=40) nowname
197  CHARACTER(len=40) :: prefix
198 
199 !-----------------------------------------------
200 ! Start of Executable Code
201 !-----------------------------------------------
202 ! Not sure of the reason for the next IF test. JDH
203 !
204  IF (this%s_name .eq. ' ') THEN
205  WRITE(*,*) 'this%s_name = one blank. bsc_cdf_define_coilcoll'
206  WRITE(*,*) ' is returning'
207  RETURN
208  END IF
209 
210  ncoild = this%ncoil
211 
212 ! Next loop could be augmented to make sure that the prefixes are unique.
213 
214  DO i = 1,ncoild ! Loop over coils in the coilcoll
215  prefix = this%coils(i)%s_name
216  CALL bsc_cdf_define_coil(this%coils(i),lunit,prefix)
217  END DO
218 
219  END SUBROUTINE bsc_cdf_define_coilcoll
220 
221 !*******************************************************************************
222 ! SECTION IV. WRITING SUBROUTINES
223 !*******************************************************************************
224 !-------------------------------------------------------------------------------
225 !
226 !-------------------------------------------------------------------------------
227  SUBROUTINE bsc_cdf_write_coil(this,lunit,prefix)
228 ! Subroutine to do the appropriate netCDF definition calls for a bsc_coil
229 
230 !-----------------------------------------------
231 ! D u m m y A r g u m e n t s
232 !-----------------------------------------------
233  TYPE (bsc_coil), INTENT (in) :: this
234  INTEGER :: lunit
235  CHARACTER (len=*) :: prefix
236 
237 ! this bsc_coil - this is the coil that gets written.
238 ! lunit i/o unit number
239 ! prefix character - prefixed to variable names, so that netCDF
240 ! doesn't have problems with repeated, identical names
241 !-----------------------------------------------
242 ! L o c a l V a r i a b l e s
243 !-----------------------------------------------
244  CHARACTER(len=32) :: prefix_use
245 !-----------------------------------------------
246 ! Start of Executable Code
247 !-----------------------------------------------
248 
249 ! Define the prefix to actually use
250  prefix_use = trim(adjustl(prefix))
251 
252 ! Define all vn_--_use variable names
253  CALL bsc_cdf_defvn_coil(prefix_use)
254 
255 ! Write Components common to all c_types
256  CALL cdf_write(lunit, trim(vn_c_type_use), this%c_type)
257  CALL cdf_write(lunit, trim(vn_s_name_use), this%s_name)
258  CALL cdf_write(lunit, trim(vn_l_name_use), this%l_name)
259  CALL cdf_write(lunit, trim(vn_current_use), this%current)
260  CALL cdf_write(lunit, trim(vn_raux_use), this%raux)
261 
262 ! Particular coding, depending on c_type
263 
264  SELECT CASE (this%c_type)
265 
266  CASE ('fil_loop','floop') ! Filamentary Loop Variables
267  IF (ASSOCIATED(this%xnod)) THEN
268  CALL cdf_write(lunit, trim(vn_xnod_use), this%xnod)
269  END IF ! this%xnod ASSOCIATED
270 
271  CASE ('fil_circ', 'fcirc') ! Filamentary Circle Variables
272  CALL cdf_write(lunit, trim(vn_rcirc_use), this%rcirc)
273  CALL cdf_write(lunit, trim(vn_xcent_use), this%xcent(1:3))
274  CALL cdf_write(lunit, trim(vn_enhat_use), this%enhat(1:3))
275 
276  CASE ('fil_rogo') ! Rogowskis
277  IF (ASSOCIATED(this%xnod)) THEN
278  CALL cdf_write(lunit, trim(vn_xnod_use), this%xnod)
279  END IF ! this%xnod ASSOCIATED
280  CALL cdf_write(lunit, trim(vn_ave_n_area_use), &
281  & this%ave_n_area)
282 
283  END SELECT
284 
285  END SUBROUTINE bsc_cdf_write_coil
286 
287 !-------------------------------------------------------------------------------
288 !
289 !-------------------------------------------------------------------------------
290  SUBROUTINE bsc_cdf_write_coilcoll(this,lunit)
291 ! Subroutine to do the appropriate netCDF definition calls for a bsc_coilcoll
292 ! To avoid duplicate names in the netCDF files, the variable names will
293 ! have a prefix added on.
294 
295 !-----------------------------------------------
296 ! D u m m y A r g u m e n t s
297 !-----------------------------------------------
298  TYPE (bsc_coilcoll), INTENT (in) :: this
299  INTEGER :: lunit
300 
301 ! this bsc_coilcoll - this is the coilcoll that gets written.
302 ! lunit i/o unit number
303 !
304 !-----------------------------------------------
305 ! L o c a l V a r i a b l e s
306 !-----------------------------------------------
307  INTEGER :: i, n, ncoild
308  INTEGER dimlens(2)
309  CHARACTER(LEN=40) nowname
310  CHARACTER (len=40) :: prefix
311 
312 !-----------------------------------------------
313 ! Start of Executable Code
314 !-----------------------------------------------
315 ! Not sure of the reason for the next IF test. JDH
316 !
317  IF (this%s_name .eq. ' ') THEN
318  WRITE(*,*) 'this%s_name = one blank. bsc_cdf_write_coilcoll'
319  WRITE(*,*) ' is returning'
320  RETURN
321  END IF
322 
323  ncoild = this%ncoil
324 
325 ! Next loop could be augmented to make sure that the prefixes are unique.
326 
327  DO i = 1,ncoild ! Loop over coils in the coilcoll
328  prefix = this%coils(i)%s_name
329  CALL bsc_cdf_write_coil(this%coils(i),lunit,prefix)
330  END DO
331 
332  END SUBROUTINE bsc_cdf_write_coilcoll
333 
334 !*******************************************************************************
335 ! SECTION V. READING SUBROUTINES
336 !*******************************************************************************
337 !-------------------------------------------------------------------------------
338 !
339 !-------------------------------------------------------------------------------
340  SUBROUTINE bsc_cdf_read_coil(this,iou,prefix)
341 ! Subroutine to do the appropriate netCDF read calls for a bsc_coil
342 !
343 
344 !-----------------------------------------------
345 ! D u m m y A r g u m e n t s
346 !-----------------------------------------------
347  TYPE (bsc_coil), INTENT (inout) :: this
348  INTEGER, INTENT (in) :: iou
349  CHARACTER (len=*), INTENT (in), OPTIONAL :: prefix
350 
351 ! this bsc_coil - this is what gets defined and written.
352 ! iou i/o unit number of the netCDF file.
353 ! prefix character - prefixed to variable names, so that netCDF
354 ! doesn't have problems with repeated, identical names
355 !-----------------------------------------------
356 ! L o c a l V a r i a b l e s
357 !-----------------------------------------------
358  CHARACTER(len=*), PARAMETER :: sub_name = &
359  & 'bsc_cdf_read_coil: '
360  CHARACTER(len=32) :: prefix_use
361  INTEGER, DIMENSION(3) :: dimlens
362  INTEGER :: ier1, n2
363 
364  CHARACTER (len=8) :: c_type
365  CHARACTER (len=30) :: s_name
366  CHARACTER (len=80) :: l_name
367  REAL(rprec) :: eps_sq
368  REAL(rprec) :: current
369  REAL(rprec) :: raux
370  REAL(rprec) :: rcirc
371  REAL(rprec) :: ave_n_area
372  REAL(rprec), DIMENSION(3) :: xcent, enhat
373  REAL(rprec), DIMENSION(:,:), ALLOCATABLE :: xnod
374 
375 !-----------------------------------------------
376 ! Start of Executable Code
377 !-----------------------------------------------
378 
379 ! Define the prefix to actually use
380  IF (PRESENT(prefix)) THEN
381  prefix_use = trim(adjustl(prefix))
382  ELSE
383  prefix_use = ' '
384  ENDIF
385 
386 ! Define all vn_--_use variable names
387  CALL bsc_cdf_defvn_coil(prefix_use)
388 
389 ! Read Components
390 ! Note: Read in to variables local to this subroutine.
391 ! Arrays require inquiry regarding size, and allocation before actual reading.
392 
393  CALL cdf_read(iou, trim(vn_c_type_use), c_type)
394  CALL cdf_read(iou, trim(vn_s_name_use),s_name)
395  CALL cdf_read(iou, trim(vn_l_name_use),l_name)
396  CALL cdf_read(iou, trim(vn_current_use),current)
397  CALL cdf_read(iou, trim(vn_raux_use),raux)
398 
399  SELECT CASE (trim(c_type))
400 
401  CASE ('fil_loop','floop') ! Filamentary Loop Variables
402  CALL cdf_inquire(iou, trim(vn_xnod_use),dimlens)
403  ALLOCATE(xnod(dimlens(1),dimlens(2)),stat=ier1)
404  CALL assert_eq(0,ier1,sub_name // 'alloc xnod')
405  CALL assert_eq(3,dimlens(1),sub_name // 'bad xnod dim')
406  CALL cdf_read(iou, trim(vn_xnod_use), xnod)
407 ! Take into account logic in bsc_construct for loop closure
408  IF (dimlens(2) .ge. 4) THEN
409  n2 = dimlens(2) - 1
410  ELSE
411  n2 = dimlens(2)
412  ENDIF
413  CALL bsc_construct(this,c_type,s_name,l_name,current, &
414  & xnod(1:3,1:n2),raux=raux)
415 
416  CASE ('fil_circ', 'fcirc') ! Filamentary Circle Variables
417  CALL cdf_read(iou, trim(vn_rcirc_use),rcirc)
418  CALL cdf_read(iou, trim(vn_xcent_use),xcent)
419  CALL cdf_read(iou, trim(vn_enhat_use),enhat)
420  CALL bsc_construct(this,c_type,s_name,l_name,current, &
421  & rcirc = rcirc,xcent = xcent,enhat = enhat,raux = raux)
422 
423  CASE ('fil_rogo') ! Rogowskis
424  CALL cdf_inquire(iou, trim(vn_xnod_use),dimlens)
425  ALLOCATE(xnod(dimlens(1),dimlens(2)),stat=ier1)
426  CALL assert_eq(0,ier1,sub_name // 'alloc xnod')
427  CALL cdf_read(iou, trim(vn_xnod_use), xnod)
428  CALL cdf_read(iou, trim(vn_ave_n_area_use),ave_n_area)
429  CALL bsc_construct(this,c_type,s_name,l_name,current, &
430  & xnod,raux = raux,anturns = one,xsarea = ave_n_area)
431 
432  END SELECT
433 
434 ! Deallocate the local allocatable space
435  IF (ALLOCATED(xnod)) THEN
436  DEALLOCATE(xnod,stat=ier1)
437  CALL assert_eq(0,ier1,sub_name // 'dealloc xnod')
438  END IF
439 
440  RETURN
441 
442  END SUBROUTINE bsc_cdf_read_coil
443 
444 !*******************************************************************************
445 ! SECTION VI. AUXILLIARY FUNCTIONS
446 !*******************************************************************************
447 !-------------------------------------------------------------------------------
448 !
449 !-------------------------------------------------------------------------------
450  SUBROUTINE bsc_cdf_defvn_coil(prefix_use)
451 ! Subroutine to do define the character variable names for a bsc_coil,
452 ! using the prefix. All the vn_ variables are module variables, and so do not
453 ! need to be declared here
454 
455 !-----------------------------------------------
456 ! D u m m y A r g u m e n t s
457 !-----------------------------------------------
458  CHARACTER (len=*), INTENT (in) :: prefix_use
459 
460 ! prefix_use character - prefixed to variable names, so that netCDF
461 ! doesn't have problems with repeated, identical names
462 
463 !-----------------------------------------------
464 ! L o c a l V a r i a b l e s
465 !-----------------------------------------------
466  CHARACTER(len=*), PARAMETER :: sub_name = &
467  & 'bsc_cdf_defvn_coil: '
468 
469 !-----------------------------------------------
470 ! Start of Executable Code
471 !-----------------------------------------------
472 
473 ! Define all variable names
474  vn_c_type_use = bsc_cdf_mknam(prefix_use,vn_c_type)
475  vn_s_name_use = bsc_cdf_mknam(prefix_use,vn_s_name)
476  vn_l_name_use = bsc_cdf_mknam(prefix_use,vn_l_name)
477  vn_current_use = bsc_cdf_mknam(prefix_use,vn_current)
478  vn_raux_use = bsc_cdf_mknam(prefix_use,vn_raux)
479  vn_xnod_use = bsc_cdf_mknam(prefix_use,vn_xnod)
480  vn_rcirc_use = bsc_cdf_mknam(prefix_use,vn_rcirc)
481  vn_xcent_use = bsc_cdf_mknam(prefix_use,vn_xcent)
482  vn_enhat_use = bsc_cdf_mknam(prefix_use,vn_enhat)
483  vn_ave_n_area_use = bsc_cdf_mknam(prefix_use,vn_ave_n_area)
484 
485  RETURN
486 
487  END SUBROUTINE bsc_cdf_defvn_coil
488 !-------------------------------------------------------------------------------
489 !
490 !-------------------------------------------------------------------------------
491 
492  FUNCTION bsc_cdf_mknam(c1,c2)
493 ! A simple function to help in the generation of names
494 
495 !-----------------------------------------------
496 ! F u n c t i o n N a m e
497 !-----------------------------------------------
498  CHARACTER(LEN=40) bsc_cdf_mknam
499 
500 !-----------------------------------------------
501 ! D u m m y A r g u m e n t s
502 !-----------------------------------------------
503  CHARACTER(LEN=*), INTENT (in) :: c1,c2
504 
505 !-----------------------------------------------
506 ! Start of Executable Code
507 !-----------------------------------------------
508  IF (len_trim(c1) .eq. 0) THEN
509  bsc_cdf_mknam = trim(c2)
510  ELSE
511  bsc_cdf_mknam = adjustl(trim(c1) // '_' // trim(c2))
512  ENDIF
513 
514  RETURN
515 
516  END FUNCTION bsc_cdf_mknam
517 
518 !-----------------------------------------------
519 !-----------------------------------------------
520 
521  END MODULE bsc_cdf
v3_utilities::assert_eq
Definition: v3_utilities.f:62
bsc_t::bsc_construct
Definition: bsc_T.f:181