source: trunk/UTIL/SPECTRA/spectra_analysis.f90 @ 1410

Last change on this file since 1410 was 1404, checked in by milmd, 10 years ago

Add the opportunity to create some harmonical wind fields for testing. Spherepack library can also be compiled with ifort.

File size: 18.0 KB
Line 
1!M. Indurain & E. Millour
2!March 2015
3
4PROGRAM spectra_analysis
5
6!Compute energy spectrum of a 2d wind field with spherepack routines.
7!v = sum(n=1..nlat-1) 0.5*b(0,n)*B(0,n)+0.5*c(0,n)*C(0,n) + sum(m=1..mmax-1)sum(n=m..nlat-1) b(m,n)*B(m,n)+c(m,n)*C(m,n)
8!where B(m,n) and C(m,n) are vector spherical harmonics
9!Then energy spectra is defined as:
10!E(n) = 0.5*|b(0,n)|^2 + 0.5*|c(0,n)|^2 + sum(m=1..n) |b(m,n)|^2 + |c(m,n)|^2
11
12!Wind field read from netcdf file follows lmdz convention:
13!  u(nlong+1,nlat) zonal eastward wind, v(nlong+1,nlat) latitudinal wind
14!Wind field needed for spherepack routines must be like:
15!  u(nlat,nlong) zonal eastward wind, v(nlong,nlat) colatitudinal wind (from North pole)
16
17use netcdf
18
19implicit none
20
21!Physical grid
22integer :: nlat,nlong,nlongp1,nalt,ntime
23double precision, dimension(:,:), allocatable :: merid_wind,zonal_wind !spherepack convention
24double precision, dimension(:,:), allocatable :: merid_wind_lmdz,zonal_wind_lmdz !lmdz convention
25!Spectral grid
26integer :: mmax !spectra truncation mmax=min(nalt,nlong/2) or min(nalt,(nlong+1)/2)
27double precision, dimension (:,:), allocatable :: br,bi,cr,ci !spectra coefficients
28double precision, dimension (:,:), allocatable :: norm,norm_b,norm_c !norm of spectra coefficients
29double precision, dimension (:), allocatable :: spectra,spectra_b,spectra_c
30double precision, dimension (:,:), allocatable :: spectra_config,spectra_b_config,spectra_c_config
31double precision, dimension (:,:), allocatable :: spectra_global,spectra_b_global,spectra_c_global
32!Spherepack declarations
33integer :: ierror,lvhaec,ldwork,lwork,l1,l2,nt=1,ityp=0,idvw,jdvw,mdab,ndab
34double precision, dimension (:), allocatable :: wvhaec,work
35double precision, dimension (:), allocatable :: dwork
36!Netcdf stuff
37integer :: idfile,idmerid_wind,idzonal_wind
38integer :: idlat,idlong,idalt,idtime
39!Input arguments
40character (len=100), dimension(:), allocatable :: arg
41character (len=100) :: file_netcdf,file_spectra
42integer :: n_indt,n_indz,meant,meanz
43integer, dimension(:), allocatable :: tab_indt,tab_indz
44character (len=100) :: name_u,name_v,name_lat,name_long,name_alt,name_time
45character (len=100) :: tab_name_u(4)=(/'u','U','vitu','zonal_wind'/)
46character (len=100) :: tab_name_v(4)=(/'v','V','vitv','merid_wind'/)
47character (len=100) :: tab_name_lat(2)=(/'latitude','lat'/)
48character (len=100) :: tab_name_long(2)=(/'longitude','lon'/)
49character (len=100) :: tab_name_alt(3)=(/'altitude','alt','presnivs'/)
50character (len=100) :: tab_name_time(3)=(/'time','Time','time_counter'/)
51logical :: is_div_rot
52integer :: narg
53!Other
54integer :: i,j,t,z,mt,mz
55integer :: number_config        !number of (t,z) configurations wanted by user (from 1 to n_indt*n_indz))
56integer :: number_local         !number of (t,z) sub-configurations to mean (from 1 to (meant+1)*(meanz+1))
57integer :: number_global        !number of total (t,z) configurations to compute (from 1 to n_indt*n_indz*(meant+1)*(meanz+1))
58logical :: is_file,first_reading=.true.
59integer, dimension(:), allocatable :: tmp_tab_int
60character (len=100) :: tmp_char
61
62!**********
63!Initialisation
64file_netcdf = '??@@??'
65file_spectra = 'spectra'
66n_indt = 0
67n_indz = 0
68allocate(tab_indt(20))
69allocate(tab_indz(20))
70allocate(tmp_tab_int(20))
71tab_indt(:) = 1
72tab_indz(:) = 1
73meant = 0
74meanz = 0
75name_u = '??@@??'
76name_v = '??@@??'
77name_lat = '??@@??'
78name_long = '??@@??'
79name_alt = '??@@??'
80name_time = '??@@??'
81is_div_rot=.false.
82
83!**********
84!Input reading
85narg = command_argument_count()
86allocate(arg(narg))
87do i = 1, narg
88  call get_command_argument(i,arg(i))
89end do
90i = 1
91do while (i .le. narg)
92  if (arg(i) == '-o' .or. arg(i) == '-t' .or. arg(i) == '-z' .or. arg(i) == '-mt' .or. arg(i) == '-mz'&
93                .or. arg(i) == '-u' .or. arg(i) == '-v' .or. arg(i) == '-lat' .or. arg(i) == '-lon' &
94                .or. arg(i) == '-alt' .or. arg(i) == '-time') then
95    select case(arg(i))
96    case('-t')
97      n_indt = n_indt + 1
98      read(arg(i+1),'(i10)' ) tab_indt(n_indt) !temporal indice                 
99    case('-z')
100      n_indz = n_indz + 1
101      read(arg(i+1),'(i10)' ) tab_indz(n_indz) !vertical indice
102    case('-mt')
103      read(arg(i+1),'(i10)' ) meant !extent of temporal mean
104    case('-mz')
105      read(arg(i+1),'(i10)' ) meanz !extent of vertical mean
106    case('-o')
107      file_spectra=arg(i+1) !spectra file
108    case('-u')
109      read(arg(i+1),'(a100)' ) name_u !name of zonal wind
110    case('-v')
111      read(arg(i+1),'(a100)' ) name_v !name of meridional wind
112    case('-lat')
113      read(arg(i+1),'(a100)' ) name_lat !name of latitude axis
114    case('-lon')
115      read(arg(i+1),'(a100)' ) name_long !name of longitude axis
116    case('-alt')
117      read(arg(i+1),'(a100)' ) name_alt !name of altitude axis
118    case('-time')
119      read(arg(i+1),'(a100)' ) name_time !name of time axis
120    end select
121    i = i + 2
122    elseif (arg(i) == '-divrot') then
123      is_div_rot = .true.
124      i = i + 1
125    elseif (arg(i) == '-h' .or. arg(i) == '--help') then
126      print*,'Usage\n spectra netcdfFile [option]\n [-h or --help]\t: brief help'
127      print*,'[-t int]\t: temporal indice (default: 1)\n [-z int]\t: vertical indice (default: 1)'
128      print*,'[-mt int]\t: extent of temporal mean (default: 0)\n [-mz int]\t: extent of vertical mean (default: 0)'
129      print*,'[-o str]\t: output spectra file name (default: spectra)'
130      print*,'[-u str]\t: name of zonal wind in netcdf file'
131      print*,'[-v str]\t: name of meridional wind in netcdf file'
132      print*,'[-lat str]\t: name of latitude field in netcdf file'
133      print*,'[-lon str]\t: name of longitude field in netcdf file'
134      print*,'[-alt str]\t: name of altitude field in netcdf file. ''none'' if no altitude axis.'
135      print*,'[-time str]\t: name of time field in netcdf file. ''none'' if no time axis.'
136      print*,'[-divrot]\t: total, divergence and vorticity spectra coefficient in output file'
137      stop 'End help'
138    else
139      file_netcdf = arg(i)
140      i = i + 1
141  end if
142end do
143
144!**********
145!Check input/output files
146inquire(file=trim(file_netcdf),exist=is_file)
147if (.not. is_file) then
148  print*,"no netcdf file: ",trim(file_netcdf)
149  stop "Stopped"
150end if
151call system('rm -f '//trim(file_spectra))
152
153!**********
154!Netcdf file dimensions
155ierror=nf90_open(trim(file_netcdf),NF90_NOWRITE,idfile)
156
157ierror=-99999
158i=0
159ierror=nf90_inq_dimid(idfile,trim(name_lat),idlat) !try user named latitude
160do while (ierror /= 0 .and. i <= size(tab_name_lat)-1)!try automatic named latitude
161  i=i+1
162  ierror=nf90_inq_dimid(idfile,trim(tab_name_lat(i)),idlat)
163end do
164if (ierror == 0) then
165  ierror=nf90_inquire_dimension(idfile,idlat,tmp_char,nlat)
166else
167  print*,'latitude dimension not found!'
168  stop ' must have this... use ''-lat latitudefieldname'' option.'
169end if
170
171ierror=-99999
172i=0
173ierror=nf90_inq_dimid(idfile,trim(name_long),idlong) !try user named longitude
174do while (ierror /= 0 .and. i <= size(tab_name_long)-1)  !try automatic named longitude
175  i=i+1
176  ierror=nf90_inq_dimid(idfile,trim(tab_name_long(i)),idlong)
177end do
178if (ierror == 0) then
179  ierror=nf90_inquire_dimension(idfile,idlong,tmp_char,nlongp1)
180else
181  print*,'longitude dimension not found!'
182  stop ' must have this... use ''-lon longitudefieldname'' option.'
183end if
184
185ierror=-99999
186i=0
187ierror=nf90_inq_dimid(idfile,trim(name_alt),idalt) !try user named altitude
188do while (ierror /= 0 .and. i <= size(tab_name_alt)-1)!try automatic named altitude
189  i=i+1
190  ierror=nf90_inq_dimid(idfile,trim(tab_name_alt(i)),idalt)
191end do
192if (ierror == 0) then
193  ierror=nf90_inquire_dimension(idfile,idalt,tmp_char,nalt)
194else
195  if (name_alt == 'none') then
196    print*,'netcdf file without altitude axis: all the same.'
197  else
198    print*,'altitude dimension not found!'
199    stop ' if no altitude axis, use ''-alt none'' option...'
200  end if
201end if
202
203ierror=-99999
204i=0
205ierror=nf90_inq_dimid(idfile,trim(name_time),idtime) !try user named time
206do while (ierror /= 0 .and. i <= size(tab_name_time)-1)  !try automatic named time
207  i=i+1
208  ierror=nf90_inq_dimid(idfile,trim(tab_name_time(i)),idtime)
209end do
210if (ierror == 0) then
211  ierror=nf90_inquire_dimension(idfile,idtime,tmp_char,ntime)
212else
213  if (name_time == 'none') then
214    print*,'netcdf file without time axis: all the same.'
215  else
216    print*,'time dimension not found!'
217    stop ' if no time axis, use ''-time none'' option...'
218  end if
219end if
220
221!**********
222!Check input indices and add average indices
223if (n_indt == 0) n_indt = 1
224tmp_tab_int(:) = tab_indt(:)
225deallocate(tab_indt)
226allocate(tab_indt(n_indt*(meant+1)))
227do t = 1,n_indt
228do mt = 0,meant
229  tab_indt((t-1)*(meant+1)+1+mt) = tmp_tab_int(t)+mt
230end do
231end do 
232do t = 1,n_indt*(meant+1)
233  if (tab_indt(t) > ntime .or. tab_indt(t) < 1) tab_indt(t) = 1
234end do
235
236if (n_indz == 0) n_indz = 1
237tmp_tab_int(:) = tab_indz(:)
238deallocate(tab_indz)
239allocate(tab_indz(n_indz*(meanz+1)))
240do z = 1,n_indz
241do mz = 0,meanz
242  tab_indz((z-1)*(meanz+1)+1+mz) = tmp_tab_int(z)+mz
243end do
244end do 
245do z = 1,n_indz*(meanz+1)
246  if (tab_indz(z) > nalt .or. tab_indz(z) < 1) tab_indz(z) = 1
247end do
248
249!**********
250!Loop over time and altitude indices
251allocate(spectra_config(nlat,n_indt*n_indz))
252allocate(spectra_b_config(nlat,n_indt*n_indz))
253allocate(spectra_c_config(nlat,n_indt*n_indz))
254allocate(spectra_global(nlat,n_indt*(meant+1)*n_indz*(meanz+1)))
255allocate(spectra_b_global(nlat,n_indt*(meant+1)*n_indz*(meanz+1)))
256allocate(spectra_c_global(nlat,n_indt*(meant+1)*n_indz*(meanz+1)))
257do t = 1,n_indt
258do z = 1,n_indz
259number_config = (t-1)*n_indz+z
260do mt = 0,meant
261do mz = 0,meanz
262number_local = mt*(meanz+1)+mz+1
263number_global = (number_config-1)*(meant+1)*(meanz+1) + number_local
264if (first_reading) then
265  print*,'First netcdf file reading...'
266  first_reading = .false.
267end if
268
269!**********
270!Netcdf file reading
271ierror=-99999
272i=0
273ierror=nf90_inq_varid(idfile,trim(name_u),idzonal_wind) !try user named zonal wind
274do while (ierror /= 0 .and. i <= size(tab_name_u)-1)        !try automatic named zonal wind
275  i=i+1
276  ierror=nf90_inq_varid(idfile,trim(tab_name_u(i)),idzonal_wind)
277end do
278if (ierror == 0) then
279  allocate(zonal_wind_lmdz(nlongp1,nlat))
280  if (name_alt == 'none') then
281    if(name_time == 'none') then
282      ierror=nf90_get_var(idfile,idzonal_wind,zonal_wind_lmdz,(/1,1/),(/nlongp1,nlat/))
283    else
284      ierror=nf90_get_var(idfile,idzonal_wind,zonal_wind_lmdz,(/1,1,tab_indt((t-1)*(meant+1)+mt+1)/),(/nlongp1,nlat,1/))
285    end if
286  end if
287  if (name_alt /= 'none') then
288    if(name_time == 'none') then
289      ierror=nf90_get_var(idfile,idzonal_wind,zonal_wind_lmdz,(/1,1,tab_indz((z-1)*(meanz+1)+1)/),(/nlongp1,nlat,1/))
290    else
291      ierror=nf90_get_var(idfile,idzonal_wind,zonal_wind_lmdz,&
292                                (/1,1,tab_indz((z-1)*(meanz+1)+1),tab_indt((t-1)*(meant+1)+mt+1)/),(/nlongp1,nlat,1,1/))
293    end if
294  end if
295else
296  print*,'zonal wind variable not found!'
297  stop ' must have this... use ''-u zonalwindfieldname'' option.'
298end if
299
300ierror=-99999
301i=0
302ierror=nf90_inq_varid(idfile,trim(name_v),idmerid_wind) !try user named meridional wind
303do while (ierror /= 0 .and. i <= size(tab_name_v)-1)        !try automatic named meridional wind
304  i=i+1
305  ierror=nf90_inq_varid(idfile,trim(tab_name_v(i)),idmerid_wind)
306end do
307if (ierror == 0) then
308  allocate(merid_wind_lmdz(nlongp1,nlat))
309  if (name_alt == 'none') then
310    if(name_time == 'none') then
311      ierror=nf90_get_var(idfile,idmerid_wind,merid_wind_lmdz,(/1,1/),(/nlongp1,nlat/))
312    else
313      ierror=nf90_get_var(idfile,idmerid_wind,merid_wind_lmdz,(/1,1,tab_indt((t-1)*(meant+1)+mt+1)/),(/nlongp1,nlat,1/))
314    end if
315  end if
316  if (name_alt /= 'none') then
317    if(name_time == 'none') then
318      ierror=nf90_get_var(idfile,idmerid_wind,merid_wind_lmdz,(/1,1,tab_indz((z-1)*(meanz+1)+1)/),(/nlongp1,nlat,1/))
319    else
320      ierror=nf90_get_var(idfile,idmerid_wind,merid_wind_lmdz,&
321                                (/1,1,tab_indz((z-1)*(meanz+1)+1),tab_indt((t-1)*(meant+1)+mt+1)/),(/nlongp1,nlat,1,1/))
322    end if
323  end if
324else
325  print*,'meridional wind variable not found!'
326  stop ' must have this... use ''-v meridionalwindfieldname'' option.'
327end if
328
329!**********From lmdz to spherepack convention
330nlong=nlongp1-1
331allocate(zonal_wind(nlat,nlong))
332allocate(merid_wind(nlat,nlong))
333zonal_wind(:,:)=transpose(zonal_wind_lmdz(1:nlong,:))
334merid_wind(:,:)=transpose(merid_wind_lmdz(1:nlong,:))
335!if (mod(nlat,2) == 0) then
336!  merid_wind(1:nlat/2,:)=-merid_wind(1:nlat/2,:)
337!else
338!  merid_wind(1:(nlat+1)/2,:)=-merid_wind(1:(nlat+1)/2,:)
339!end if
340
341!#####
342!Spectra computation
343!#####
344!**********Maximum value for m
345if (mod(nlong,2) == 0) then
346  mmax = min(nlat,nlong/2)
347else
348  mmax = min(nlat,(nlong+1)/2)
349end if
350
351!**********Vhaeci function (initialisations for Vhaec function)
352if (mod(nlong,2) == 0) then
353  l1 = min(nlat,nlong/2)
354else
355  l1 = min(nlat,(nlong+1)/2)
356end if
357if (mod(nlat,2) == 0) then
358  l2 = nlat/2
359else
360  l2 = (nlat+1)/2
361end if
362lvhaec=4*nlat*l2+3*max(l1-2,0)*(nlat+nlat-l1-1)+nlong+15
363allocate(wvhaec(lvhaec))
364wvhaec(:) = 0.
365ldwork=2*(nlat+2)
366allocate(dwork(ldwork))
367dwork(:) = 0.
368ierror=3
369call vhaeci(nlat,nlong,wvhaec,lvhaec,dwork,ldwork,ierror)
370 
371!**********Vhaeci function result
372select case (ierror)
373  case(1)
374    print*,'Vhaeci: ERROR on nlat'
375  case(2)
376    print*,'Vhaeci: ERROR on nlong'
377  case(3)
378    print*,'Vhaeci: ERROR on lvhaec'
379  case(4)
380    print*,'Vhaeci: ERROR on ldwork'
381end select
382
383!**********Vhaec function (computes spectra coefficients)
384idvw=nlat
385jdvw=nlong
386mdab=mmax
387ndab=nlat
388allocate(br(mdab,ndab))
389allocate(bi(mdab,ndab))
390allocate(cr(mdab,ndab))
391allocate(ci(mdab,ndab))
392br(:,:) = 0.
393bi(:,:) = 0.
394cr(:,:) = 0.
395ci(:,:) = 0.
396if (mod(nlong,2) == 0) then
397  l1 = min(nlat,nlong/2)
398else
399  l1 = min(nlat,(nlong+1)/2)
400end if
401if (mod(nlat,2) == 0) then
402  l2 = nlat/2
403else
404  l2 = (nlat+1)/2
405end if
406lvhaec=4*nlat*l2+3*max(l1-2,0)*(nlat+nlat-l1-1)+nlong+15
407if (ityp .le. 2) then
408  lwork=nlat*(2*nt*nlong+max(6*l2,nlong))
409else
410  lwork=l2*(2*nt*nlong+max(6*nlat,nlong))
411end if
412allocate(work(lwork))
413work(:) = 0.
414ierror=3
415call vhaec(nlat,nlong,ityp,nt,merid_wind,zonal_wind,idvw,jdvw,br,bi,cr,ci,mdab,ndab,wvhaec,lvhaec,work,lwork,ierror)
416
417!**********Vhaec function result
418select case (ierror)
419  case(1)
420    print*,'Vhaec: ERROR on nlat'
421  case(2)
422    print*,'Vhaec: ERROR on nlong'
423  case(3)
424    print*,'Vhaec: ERROR on ityp'
425  case(4)
426    print*,'Vhaec: ERROR on nt'
427  case(5)
428    print*,'Vhaec: ERROR on idvw'
429  case(6)
430    print*,'Vhaec: ERROR on jdvw'
431  case(7)
432    print*,'Vhaec: ERROR on mdab'
433  case(8)
434    print*,'Vhaec: ERROR on ndab'
435  case(9)
436    print*,'Vhaec: ERROR on lvhaec'
437  case(10)
438    print*,'Vhaec: ERROR on lwork'
439end select
440
441!**********Energy spectra
442allocate(norm(mMax,nLat))
443allocate(norm_b(mMax,nLat))
444allocate(norm_c(mMax,nLat))
445do i = 1,mMax
446do j = 1,nLat
447  norm(i,j)=(br(i,j)*br(i,j)+bi(i,j)*bi(i,j)+cr(i,j)*cr(i,j)+ci(i,j)*ci(i,j))
448  norm_b(i,j)=(br(i,j)*br(i,j)+bi(i,j)*bi(i,j))
449  norm_c(i,j)=(cr(i,j)*cr(i,j)+ci(i,j)*ci(i,j))
450end do
451end do
452allocate(spectra(nLat))
453allocate(spectra_b(nLat))
454allocate(spectra_c(nLat))
455do j = 1,nLat
456  spectra(j) = 0.5*norm(1,j)
457  spectra_b(j) = 0.5*norm_b(1,j)
458  spectra_c(j) = 0.5*norm_c(1,j)
459  do i = 2,mMax
460    spectra(j) = spectra(j) + norm(i,j)
461    spectra_b(j) = spectra_b(j) + norm_b(i,j)
462    spectra_c(j) = spectra_c(j) + norm_c(i,j)
463  end do
464end do
465!do j = 2,nLat
466!  spectra(j) = spectra(j)/((j-1)*j)
467!  spectra_b(j) = spectra_b(j)/((j-1)*j)
468!  spectra_c(j) = spectra_c(j)/((j-1)*j)
469!end do
470write(*,'(a16,i5,a3,i5,a1)') 'done spectra (t=',tab_indt((t-1)*(meant+1)+mt+1),',z=',tab_indz((z-1)*(meanz+1)+mz+1),')'
471
472!**********Storage of all spectra
473spectra_global(:,number_global) = spectra(:)
474spectra_b_global(:,number_global) = spectra_b(:)
475spectra_c_global(:,number_global) = spectra_c(:)
476
477!**********
478!End of loop over time and altitude indices
479end do
480end do
481write(*,'(a24,i5,a3,i5,a8)') 'spectra computed for (t=',tab_indt((t-1)*(meant+1)+1),',z=',tab_indz((z-1)*(meanz+1)+1),') config'
482write(*,*) '**********'
483end do
484end do
485
486!**********
487!Spectra mean
488do t = 1,n_indt
489do z = 1,n_indz
490number_config = (t-1)*n_indz+z
491spectra_config(:,number_config) = 0.
492do mt = 0,meant
493do mz = 0,meanz
494number_local = mt*(meanz+1)+mz+1
495number_global = (number_config-1)*(meant+1)*(meanz+1) + number_local
496spectra_config(:,number_config) = spectra_config(:,number_config) + &
497                spectra_global(:,number_global)
498spectra_b_config(:,number_config) = spectra_b_config(:,number_config) + &
499                spectra_b_global(:,number_global)
500spectra_c_config(:,number_config) = spectra_c_config(:,number_config) + &
501                spectra_c_global(:,number_global)
502end do
503end do
504spectra_config(:,number_config) = spectra_config(:,number_config)/(meanz+1)/(meant+1)
505spectra_b_config(:,number_config) = spectra_b_config(:,number_config)/(meanz+1)/(meant+1)
506spectra_c_config(:,number_config) = spectra_c_config(:,number_config)/(meanz+1)/(meant+1)
507end do
508end do
509
510!**********Writing header of file_spectra
511open(unit=10,file=file_spectra,action="write",position="rewind")
512write(10,'(a10,a2)',advance='no') '#Spherical',' '
513do t = 1,n_indt
514do z = 1,n_indz
515  write(10,'(a50)',advance='no') file_netcdf
516end do
517end do
518write(10,*) ''
519write(10,'(a11,a1)',advance='no') '#wavenumber',' '
520do t = 1,n_indt
521do z = 1,n_indz
522  write(10,'(a2,i5,a3,i5,a35)',advance='no') 't=',tab_indt((t-1)*(meant+1)+1),' z=',tab_indz((z-1)*(meanz+1)+1),' '
523end do
524end do
525write(10,*) ''
526write(10,'(a1,a11)',advance='no') '#',' '
527do t = 1,n_indt
528do z = 1,n_indz
529if (is_div_rot) then
530  write(10,'(a8,a8,a8,a8,a8,a10)',advance='no') 'spec_tot',' ','spec_div',' ','spec_rot',' '
531else
532  write(10,'(a8,a42)',advance='no') 'spec_tot',' '
533end if
534end do
535end do
536write(10,*)''
537!**********Writing file_spectra
538do j=1,nLat
539  write(10,'(i5,a7)',advance='no') j-1,' '
540  do t = 1,n_indt
541  do z = 1,n_indz
542  number_config = (t-1)*n_indz+z
543  if (is_div_rot) then
544    write(10,'(e13.6E2,a4,e13.6E2,a4,e13.6E2,a6)',advance='no') spectra_config(j,number_config),' ',&
545                        spectra_b_config(j,number_config),' ',spectra_c_config(j,number_config),' '
546  else
547    write(10,'(e13.6E2,a38)',advance='no') spectra_config(j,number_config),' '
548  end if
549  end do
550  end do
551  if (j /= nlat) write(10,*)''
552end do
553close(10)
554
555print *, "***SUCCESS writing ",trim(file_spectra)
556deallocate(br)
557deallocate(bi)
558deallocate(cr)
559deallocate(ci)
560deallocate(wvhaec)
561deallocate(dwork)
562deallocate(work)
563
564contains
565  subroutine check(status)
566    integer, intent (in) :: status
567   
568    if(status /= nf90_noerr) then
569      print *, trim(nf90_strerror(status))
570      stop "Stopped"
571    end if
572  end subroutine check 
573
574END PROGRAM spectra_analysis
Note: See TracBrowser for help on using the repository browser.