source: trunk/LMDZ.MARS/util/lslin.F90 @ 2432

Last change on this file since 2432 was 2432, checked in by emillour, 4 years ago

Mars GCM:

  • Make a single README file (get rid of REAME.exec) and update "compile" script to (hopefully) better illustrate how to compile utilities
  • Update utilities zrecast and lslin: zrecast.F90: Force the vertical interpolation of any variable starting by "rho" to be in log space (as it should for density, molecular concentration in mol.cm-3 etc..). Set missing value to 1.E20 lslin.F90: fix various problems in the output.

FF + EM

  • Property svn:executable set to *
File size: 43.7 KB
Line 
1
2
3program lslin
4
5! Program to interpolate data in Solar Longitude linear time coordinate
6! (usable with grads) from Netcdf diagfi or concatnc  files
7! author Y. Wanherdrick, K. Dassas 2004
8! Modified by F.Forget 04/2005
9! More modifications by Ehouarn Millour 12/2005
10! Modified by Ehouarn Millour 10/2007 (changed evaluation of 'start_var'
11! from hard-coded values to a computed value)
12! Read controle field, if available TN, October 2013
13! Allow to chose a starting Ls and to average within Ls timestep a
14! (great to compare with TES and MCS data. F. Forget december 2013)
15
16
17implicit none
18
19include "netcdf.inc" ! NetCDF definitions
20
21character (len=50) :: infile
22! infile(): input file name
23character (len=50), dimension(:), allocatable :: var
24! var(): names of the variables
25character (len=50) :: title,units
26! title(),units(): [netcdf] "title" and "units" attributes
27character (len=50) :: units_alt
28! var(): units of altitude which can be 'km' or 'Pa' (after zrecast)
29character (len=50) :: altlong_name,altunits,altpositive
30! altlong_name(): [netcdf] altitude "long_name" attribute
31! altunits(): [netcdf] altitude "units" attribute
32! altpositive(): [netcdf] altitude "positive" attribute
33
34character (len=100) :: outfile
35! outfile(): output file name
36character (len=100) :: vartmp
37! vartmp(): used for temporary storage of various strings
38character (len=1) :: answer
39! answer: the character 'y' (or 'Y'), if input file is of 'concatnc' type
40character (len=1) :: average
41! average: the character 'y' to average within the Ls timestep
42integer :: nid,varid,ierr,miss,validr
43! nid: [netcdf] ID # of input file
44! varid: [netcdf] ID # of a variable
45! ierr: [netcdf] error code (returned by subroutines)
46integer :: nout,varidout
47! nout: [netcdf] ID # of output file
48! varidout: [netcdf] ID # of a variable (to write in the output file)
49integer :: i,j,k,l,x,y,n
50! counters for various loops
51integer :: start_var
52! starting index/ID # from which physical variables are to be found
53integer :: reptime ! Ehouarn: integer or real ?
54! rep_time: starting date/time of the run (given by user)
55integer :: day_ini ! Ehouarn: integer or real ?
56! day_ini: starting date/time of the run stored in input file
57integer, parameter :: length=100
58! length: (default) lenght of tab_cntrl()
59real, dimension(length) :: tab_cntrl
60! tab_cntrl(length): array, stored in the input file,
61!                which contains various control parameters.
62real, dimension(:), allocatable:: lat,lon,alt,time,lsgcm,timels,ctl
63! lat(): latitude coordinates (read from input file)
64! lon(): longitude coordinates (read from input file)
65! alt(): altitude coordinates (read from input file)
66! time(): time coordinates (in "sol", read from input file)
67! lsgcm(): time coordinate (in unevenly spaced "Ls")
68! timels(): new time coordinates (evenly spaced "Ls"; written to output file)
69! ctl(): array, stores controle array
70integer :: latlen,lonlen,altlen,timelen,Nls,Sls,ctllen
71! latlen: # of elements of lat() array
72! lonlen: # of elements of lon() array
73! altvar: # of elements of alt() array
74! timelen: # of elements of time() and lsgcm() arrays
75! Nls: # of elements of timels() array
76integer :: nbvarfile,nbvar,ndim !,nbfile
77! nbvar: # of time-dependent variables
78! nbvarfile: total # of variables (in netcdf file)
79! ndim: [netcdf] # of dimensions (3 or 4) of a variable
80integer :: latdim,londim,altdim,timedim,ctldim
81! latdim: [netcdf] "latitude" dim ID
82! londim: [netcdf] "longitude" dim ID
83! altdim: [netcdf] "altdim" dim ID
84! timedim: [netcdf] "timedim" dim ID
85! ctldim: [netcdf] "controle" dim ID
86integer :: latvar,lonvar,altvar,timevar,ctlvar
87! latvar: [netcdf] ID of "latitude" variable
88! lonvar: [netcdf] ID of "longitude" variable
89! altvar: [netcdf] ID of "altitude" variable
90! timevar: [netcdf] ID of "Time" variable
91integer :: latdimout,londimout,altdimout,timedimout,timevarout
92! latdimout: [netcdf] output latitude (dimension) ID
93! londimout: [netcdf] output longitude (dimension) ID
94! altdimout: [netcdf] output altitude (dimension) ID
95! timedimout: [netcdf] output time (dimension) ID
96! timevarout: [netcdf] ID of output "Time" variable
97integer, dimension(4) :: corner,edges,dim
98! corner(4): [netcdf] start indexes (where block of data will be written)
99! edges(4): [netcdf] lenght (along dimensions) of block of data to write
100! dim(4): [netcdf] lat, long, alt and time dimensions
101real, dimension(:,:,:,:), allocatable :: var3d,var3dls
102! var3d(,,,): 4D array to store a variable (on initial lat/lon/alt/sol grid)
103! var3dls(,,,): 4D array to store a variable (on new lat/lon/alt/Ls grid)
104real, dimension(:), allocatable :: var3dxy
105! var3dxy(): to store the temporal evolution of a variable (at fixed lat/lon/alt)
106real :: deltatsol,deltals,resultat,ls0
107! deltatsol: time step (in sols) of input file data
108! deltals: time step (in Ls) for the data sent to output
109! ls0: first Ls value for the data sent to output
110! resultat: to temporarily store the result of the interpolation
111character (len=3) :: mon
112! mon(3): to store (and write to file) the 3 first letters of a month
113real :: date
114! date: used to compute/build a fake date (for grads output)
115real :: missing
116! to handle missing value when reading /writing files
117real, dimension(2) :: valid_range
118! valid range
119
120!==============================================================================
121! 1. Initialisation step
122!==============================================================================
123
124!==============================================================================
125! 1.1. Get input file name and 'type' (to initialize start_var and reptime)
126!==============================================================================
127
128write(*,*) "which file do you want to use?"
129read(*,'(a50)') infile
130
131!write(*,*) "Is it a concatnc file? (y/n)?"
132write(*,*) "Do you want to specify the beginning day of the file"
133write(*,*) "in case the controle field is not present ? (y/n)?"
134read(*,*) answer
135if ((answer=="y").or.(answer=="Y")) then
136   write(*,*) "Beginning day of the file?"
137   read(*,*) reptime
138!   start_var=8 ! 'concatnc' type of file
139!else
140!   start_var=16 ! 'diagfi' type of file
141! N.B.: start_var is now computed; see below
142endif
143
144
145!==============================================================================
146! 1.2. Open input file and read/list the variables it contains
147!==============================================================================
148
149write(*,*) "opening "//trim(infile)//"..."
150ierr = NF_OPEN(infile,NF_NOWRITE,nid)
151if (ierr.NE.NF_NOERR) then
152   write(*,*) 'Failed to open file '//infile
153   write(*,*) NF_STRERROR(ierr)
154   stop ""
155endif
156
157! Compute 'start_var', the index from which variables are lon-lat-time
158! and/or lon-lat-alt-time
159! WARNING: We assume here that the ordering of variables in the NetCDF
160! file is such that 0D, 1D and 2D variables are placed BEFORE 3D and 4D
161! variables
162
163i=1 ! dummy initialization to enter loop below
164start_var=0 ! initialization
165do while (i.lt.3)
166  start_var=start_var+1
167  ! request number of dims of variable number 'start_var'
168  ierr=NF_INQ_VARNDIMS(nid,start_var,i)
169  if (ierr.ne.NF_NOERR) then
170    write(*,*) "Failed to get number of dims for variable number:",start_var
171    write(*,*) NF_STRERROR(ierr)
172    stop ""
173  endif
174enddo
175write(*,*) "start_var=",start_var
176
177
178ierr=NF_INQ_NVARS(nid,nbvarfile)
179! nbvarfile is now equal to the (total) number of variables in input file
180
181allocate(var(nbvarfile-(start_var-1)))
182
183! Yield the list of variables (to the screen)
184write(*,*)
185do i=start_var,nbvarfile
186   ierr=NF_INQ_VARNAME(nid,i,vartmp)
187   write(*,*) trim(vartmp)
188enddo
189!nbvar=0
190
191! Ehouarn: Redundant (and obsolete) lines ?
192!  nbvar=nbvarfile-(start_var-1)
193!  do j=start_var,nbvarfile
194!  ierr=nf_inq_varname(nid,j,var(j-(start_var-1)))
195!  enddo
196                                       
197! Get the variables' names from the input file (and store them in var())
198nbvar=nbvarfile-(start_var-1)
199do i=1,nbvar
200   ierr=NF_INQ_VARNAME(nid,i+(start_var-1),var(i))
201   write(*,'(a9,1x,i2,1x,a1,1x,a50)') "variable ",i,":",var(i)
202enddo
203
204!==============================================================================
205! 1.3. Output file name
206!==============================================================================
207! outfile="lslin.nc"
208outfile=infile(1:len_trim(infile)-3)//"_Ls.nc"
209 write(*,*) outfile
210
211
212!==============================================================================
213! 2. Work: read input, build new time coordinate and write it to output
214!==============================================================================
215
216!==============================================================================
217! 2.1. Read (and check) latitude, longitude and altitude from input file
218!==============================================================================
219
220   ierr=NF_INQ_DIMID(nid,"latitude",latdim)
221   ierr=NF_INQ_VARID(nid,"latitude",latvar)
222   if (ierr.NE.NF_NOERR) then
223      write(*,*) 'ERROR: Field <latitude> is missing'
224      write(*,*) NF_STRERROR(ierr)
225      stop "" 
226   endif
227   ierr=NF_INQ_DIMLEN(nid,latdim,latlen)
228!  write(*,*) "latlen: ",latlen
229
230   ierr=NF_INQ_DIMID(nid,"longitude",londim)
231   ierr=NF_INQ_VARID(nid,"longitude",lonvar)
232   if (ierr.NE.NF_NOERR) then
233      write(*,*) 'ERROR: Field <longitude> is missing'
234      write(*,*) NF_STRERROR(ierr)
235      stop ""
236   endif
237   ierr=NF_INQ_DIMLEN(nid,londim,lonlen)
238!  write(*,*) "lonlen: ",lonlen
239
240   ierr=NF_INQ_DIMID(nid,"altitude",altdim)
241   ierr=NF_INQ_VARID(nid,"altitude",altvar)
242   if (ierr.NE.NF_NOERR) then
243      write(*,*) 'ERROR: Field <altitude> is missing'
244      write(*,*) NF_STRERROR(ierr)
245!     stop ""
246       altlen = 1
247   else
248      ierr=NF_INQ_DIMLEN(nid,altdim,altlen)
249      units_alt=""
250      ierr=NF_GET_ATT_TEXT(nid,varid,"units",units_alt)
251   endif
252   write(*,*) "altlen: ",altlen
253! Get altitude attributes to handle files with any altitude type
254   ierr=nf_get_att_text(nid,altvar,'long_name',altlong_name)
255   ierr=nf_get_att_text(nid,altvar,'units',altunits)
256   ierr=nf_get_att_text(nid,altvar,'positive',altpositive)
257
258
259! Allocate lat(), lon() and alt()
260      allocate(lat(latlen))
261      allocate(lon(lonlen))
262      allocate(alt(altlen))
263
264! Read lat(),lon() and alt() from input file
265      ierr = NF_GET_VAR_REAL(nid,latvar,lat)
266      ierr = NF_GET_VAR_REAL(nid,lonvar,lon)
267      ierr = NF_GET_VAR_REAL(nid,altvar,alt)
268      if (ierr.NE.NF_NOERR) then
269          if (altlen.eq.1) alt(1)=0.
270      end if
271
272
273   ierr=NF_INQ_DIMID(nid,"index",ctldim)
274   if (ierr.NE.NF_NOERR) then
275      write(*,*) ' Dimension <index> is missing in file '//trim(infile)
276      ctllen=0
277      !stop "" 
278   endif
279   ierr=NF_INQ_VARID(nid,"controle",ctlvar)
280   if (ierr.NE.NF_NOERR) then
281      write(*,*) 'Field <controle> is missing in file '//trim(infile)
282      ctllen=0
283      !stop ""
284   else
285      ierr=NF_INQ_DIMLEN(nid,ctldim,ctllen)
286   endif
287
288   allocate(ctl(ctllen),stat=ierr)
289   if (ierr.ne.0) then
290     write(*,*) "Error: failed to allocate ctl(ctllen)"
291     stop
292   endif
293
294   if (ctllen .ne. 0) then
295     ierr = NF_GET_VAR_REAL(nid,ctlvar,ctl)
296     if (ierr.ne.0) then
297       write(*,*) "Error: failed to load controle"
298       write(*,*) NF_STRERROR(ierr)
299       stop
300     endif
301   endif ! of if (ctllen .ne. 0)
302
303
304
305!==============================================================================
306! 2.2. Create (and initialize latitude, longitude and altitude in) output file
307!==============================================================================
308
309  ! Initialize output file's lat,lon,alt and time dimensions
310   call initiate(outfile,lat,lon,alt,ctl,latlen,lonlen,altlen,ctllen,&
311         altlong_name,altunits,altpositive,&
312         nout,latdimout,londimout,altdimout,timedimout,timevarout)
313
314  ! Initialize output file's aps,bps and phisinit variables
315   call init2(nid,lonlen,latlen,altlen,altdim,&
316              nout,londimout,latdimout,altdimout)
317
318!==============================================================================
319! 2.3. Read time from input file
320!==============================================================================
321
322ierr=NF_INQ_DIMID(nid,"Time",timedim)
323if (ierr.NE.NF_NOERR) then
324   write(*,*) 'ERROR: Dimension <Time> is missing'
325   write(*,*) NF_STRERROR(ierr)
326   stop ""
327endif
328ierr=NF_INQ_VARID(nid,"Time",timevar)
329if (ierr.NE.NF_NOERR) then
330   write(*,*) 'ERROR: Field <Time> is missing'
331   write(*,*) NF_STRERROR(ierr)
332   stop ""
333endif
334
335ierr=NF_INQ_DIMLEN(nid,timedim,timelen)
336write(*,*) "timelen: ",timelen
337
338allocate(time(timelen))
339allocate(lsgcm(timelen))
340
341
342
343
344ierr = NF_GET_VAR_REAL(nid,timevar,time)
345
346
347!==============================================================================
348! 2.4. Initialize day_ini (starting day of the run)
349!==============================================================================
350
351
352write(*,*) 'answer',answer
353if ((answer/="y").and.(answer/="Y")) then
354   ! input file is of 'concatnc' type; the starting date of the run
355   ! is stored in the "controle" array
356   ierr = NF_INQ_VARID (nid, "controle", varid)
357   if (ierr .NE. NF_NOERR) then
358      write(*,*) 'ERROR: <controle> variable is missing'
359      write(*,*) NF_STRERROR(ierr)
360      stop ""
361   endif
362
363
364
365
366   ierr = NF_GET_VAR_REAL(nid, varid, tab_cntrl)
367
368
369   if (ierr .NE. NF_NOERR) then
370      write(*,*) 'ERROR: Failed to read <controle>'
371      write(*,*) NF_STRERROR(ierr)
372     stop ""
373   endif
374
375   day_ini = nint(tab_cntrl(4))                                               
376   day_ini = modulo(day_ini,669)                                                   
377   write(*,*) 'day_ini', day_ini
378else
379   day_ini= reptime
380   write(*,*) 'day_ini', day_ini
381endif
382
383!==============================================================================
384! 2.5. Build timels() (i.e.: time, but in evenly spaced "Ls" time steps)
385!==============================================================================
386
387! compute time step, in sols, of input dataset
388deltatsol=time(2)-time(1)
389write(*,*) 'deltatsol',deltatsol
390
391! compute time/dates in "Ls"; result stored in lsgcm()
392do i=1,timelen
393   call sol2ls(day_ini+time(i),lsgcm(i))
394  if (lsgcm(i).lt.lsgcm(1)) lsgcm(i)=lsgcm(i) + 360.
395enddo
396
397write(*,*) 'Input data LS range :', lsgcm(1),lsgcm(timelen)
398
399!******************************************
400write(*,*) "Automatic Ls timetsep (y/n)?"
401read(*,*) answer
402if ((answer=="y").or.(answer=="Y")) then
403!   *********************************************
404!   Trick of the trade:
405!   Use the value of deltatsol to determine
406!   a suitable value for deltals
407!   *********************************************
408    deltals=1./12.
409    if (0.6*deltatsol.ge.1/6.) deltals=1./6.
410    if (0.6*deltatsol.ge.0.25) deltals=0.25
411    if (0.6*deltatsol.ge.0.5) deltals=0.5
412    if (0.6*deltatsol.ge.0.75) deltals=0.75
413    if (0.6*deltatsol.ge.1) deltals=1.
414    if (0.6*deltatsol.ge.2) deltals=2.
415    if (0.6*deltatsol.ge.3) deltals=3.
416    if (0.6*deltatsol.ge.5) deltals=5.
417    ls0=lsgcm(1) ! First Ls date
418else
419    write(*,*) "New timestep in Ls (deg)"
420    read(*,*) deltals
421    write(*,*) "First Ls (deg)"
422    read(*,*) ls0
423    if (ls0.lt.lsgcm(1)) then
424       write(*,*) 'with this file, the earliest Ls is ',lsgcm(1),'let s use it'
425       ls0=lsgcm(1)
426    end if
427    write(*,*) "First Ls date (deg) = ", ls0  ! FF2013
428
429    do while((average.ne.'y').and.(average.ne.'n'))
430       write(*,*) "Average data within the Ls timestep (y/n) or interpolate ? "
431       read(*,*) average
432    end do
433endif
434  NLs=int(Int((lsgcm(timelen)-ls0)/deltals) +1)   ! FF2013
435!********************************************
436allocate(timels(Nls))
437
438! Build timels()
439timels(1) = 0.01*nint(100.*ls0)
440do k=2,Nls
441   timels(k) = timels(k-1) + deltals
442end do
443
444write(*,*) 'timestep in Ls (deg) ', deltals
445write(*,*) 'output data LS range : ', timels(1),timels(Nls)
446
447!==============================================================================
448! 2.6. Write timels() to output file
449!==============================================================================
450
451do k=1,Nls
452
453
454
455ierr= NF_PUT_VARA_REAL(nout,timevarout,k,1,timels(k))
456
457enddo
458
459
460!==============================================================================
461! 3. Read variables, interpolate them along the new time coordinate
462!    and send the result to output
463!==============================================================================
464
465do j=1,nbvar ! loop on the variables to read/interpolate/write
466
467!==============================================================================
468! 3.1 Check that variable exists, and get some of its attributes
469!==============================================================================
470   write(*,*) "variable ",var(j)
471   ! Get the variable's ID
472   ierr=NF_INQ_VARID(nid,var(j),varid)
473   if (ierr.NE.NF_NOERR) then
474      write(*,*) 'ERROR: Field <',var(j),'> not found'
475      write(*,*) NF_STRERROR(ierr)
476      stop ""
477   endif
478   ! Get the value of 'ndim' for this varriable
479   ierr=NF_INQ_VARNDIMS(nid,varid,ndim)
480   write(*,*) 'ndim', ndim
481
482!==============================================================================
483! 3.2 Prepare a few things in order to interpolate/write
484!==============================================================================
485
486   if (ndim==3) then
487      allocate(var3d(lonlen,latlen,timelen,1))
488      allocate(var3dls(lonlen,latlen,Nls,1))
489      allocate(var3dxy(timelen))
490
491      dim(1)=londimout
492      dim(2)=latdimout
493      dim(3)=timedimout
494
495      corner(1)=1
496      corner(2)=1
497      corner(3)=1
498      corner(4)=1
499
500      edges(1)=lonlen
501      edges(2)=latlen
502      edges(3)=Nls
503      edges(4)=1
504
505   else if (ndim==4) then
506      allocate(var3d(lonlen,latlen,altlen,timelen))
507      allocate(var3dls(lonlen,latlen,altlen,Nls))
508      allocate(var3dxy(timelen))
509
510      dim(1)=londimout
511      dim(2)=latdimout
512      dim(3)=altdimout
513      dim(4)=timedimout
514
515      corner(1)=1
516      corner(2)=1
517      corner(3)=1
518      corner(4)=1
519
520      edges(1)=lonlen
521      edges(2)=latlen
522      edges(3)=altlen
523      edges(4)=Nls
524   endif
525
526!==============================================================================
527! 3.3 Write this variable's definition and attributes to the output file
528!==============================================================================
529   if (ndim.ge.3) then
530    units=""
531    title=""
532    ierr=NF_GET_ATT_TEXT(nid,varid,"title",title)
533    ierr=NF_GET_ATT_TEXT(nid,varid,"units",units)
534
535    call def_var(nout,var(j),title,units,ndim,dim,varidout,ierr)
536   end if
537
538!==============================================================================
539! 3.4 Read variable
540!==== ==========================================================================
541
542   if (ndim.ge.3) then
543      ierr = NF_GET_VAR_REAL(nid,varid,var3d)
544      miss=NF_GET_ATT_REAL(nid,varid,"missing_value",missing)
545      validr=NF_GET_ATT_REAL(nid,varid,"valid_range",valid_range)
546   end if
547
548
549!==============================================================================
550! 3.6 interpolate or average
551!==============================================================================
552
553! 2D variable  (lon, lat, time)   
554! interpolation of var at timels
555   if (ndim==3) then
556      do x=1,lonlen
557       do y=1,latlen
558!        write(*,*) 'd: x, y', x, y
559        do l=1,timelen
560          var3dxy(l)=var3d(x,y,l,1)
561        enddo
562        do n=1,Nls
563          if(average.eq.'y') then
564            resultat=0.
565            Sls=0 ! (gcm data counter within each Ls timestep)
566            do l=1,timelen
567               if((lsgcm(l).ge.(timels(n)-deltals/2.)).and.   &
568               (lsgcm(l).lt.(timels(n)+deltals/2.))) then
569                  if(var3dxy(l) .ne. missing) then
570                    Sls= Sls +1
571                    resultat = resultat + var3dxy(l)
572                  end if
573               end if
574               if (Sls.ne.0) then
575                  var3dls(x,y,n,1)=resultat/float(Sls)
576               else
577                  var3dls(x,y,n,1)=missing
578               endif
579            enddo
580          else   ! average = n
581            call interpolf(timels(n),resultat,lsgcm,var3dxy,timelen)
582            var3dls(x,y,n,1)=resultat
583          endif
584        enddo
585       enddo
586      enddo
587! 3D variable (lon, lat, alt, time)     
588! interpolation of var at timels
589   else if (ndim==4) then
590      do x=1,lonlen
591       do y=1,latlen
592        do k=1,altlen
593        do l=1,timelen
594        var3dxy(l)=var3d(x,y,k,l)
595        enddo
596        do n=1,Nls
597          if(average.eq.'y') then
598            resultat=0.
599            Sls=0 ! (gcm data counter within each Ls timestep)
600            do l=1,timelen
601               if((lsgcm(l).ge.(timels(n)-deltals/2.)).and.   &
602               (lsgcm(l).lt.(timels(n)+deltals/2.))) then
603                  if(var3dxy(l) .ne. missing) then
604                    Sls= Sls +1
605                    resultat = resultat + var3dxy(l)
606                  end if
607               end if
608               if (Sls.ne.0) then
609                  var3dls(x,y,k,n)=resultat/float(Sls)
610               else
611                  var3dls(x,y,k,n)=missing
612               endif
613            enddo
614          else   ! average = n
615             call interpolf(timels(n),resultat,lsgcm,var3dxy,timelen)
616             var3dls(x,y,k,n)=resultat
617          end if
618         enddo
619        enddo
620       enddo
621      enddo
622   endif
623
624!==============================================================================
625! 3.7 Write variable to output file
626!==============================================================================
627
628
629
630   if (ndim.ge.3) then
631
632     ierr= NF_PUT_VARA_REAL(nout,varidout,corner,edges,var3dls)
633
634
635     if (ierr.ne.NF_NOERR) then
636      write(*,*) 'PUT_VAR ERROR: ',NF_STRERROR(ierr)
637      stop ""
638     endif
639
640! In case there is a "missing value" attribute and "valid range"
641     if (miss.eq.NF_NOERR) then
642      call missing_value(nout,varidout,missing) 
643     end if
644
645     deallocate(var3d)
646     deallocate(var3dls)
647     deallocate(var3dxy)
648   endif !  if (ndim.ge.3)
649
650enddo ! of do j=1,nbvar loop
651
652deallocate(time)
653deallocate(lsgcm)
654
655! close input and output files
656ierr=nf_close(nid)
657ierr=NF_CLOSE(nout)
658
659
660!==============================================================================
661! 4. Build a companion file 'lslin.ctl', so that output file can be
662!    processed by Grads
663!==============================================================================
664
665!  ----------------------------------------------------
666!  Writing ctl file to directly read Ls coordinate in grads
667!  (because of bug in grads that refuse to read date like 0089 in .nc files)
668!open(33,file='lslin.ctl')
669 open(33,file=infile(1:len_trim(infile)-3)//"_Ls.ctl")
670 date= (timels(1)-int(timels(1)))*365.
671 mon='jan'
672 if(date.ge.32) mon='feb'
673 if(date.ge.60) mon='mar'
674 if(date.ge.91) mon='apr'
675 if(date.ge.121) mon='may'
676 if(date.ge.152) mon='jun'
677 if(date.ge.182) mon='jul'
678 if(date.ge.213) mon='aug'
679 if(date.ge.244) mon='sep'
680 if(date.ge.274) mon='oct'
681 if(date.ge.305) mon='nov'
682 if(date.ge.335) mon='dec'
683write(33,98) "^"//outfile
68498 format("DSET ",a)
685  write(33,99) Nls, 15,mon, int(timels(1)),nint(deltals*12),'mo'
68699 format("TDEF Time ",i5," LINEAR ", i2,a3,i4.4,1x,i2,a2)
687   
688   deallocate(timels)
689contains
690
691!******************************************************************************
692
693subroutine initiate(filename,lat,lon,alt,ctl,latlen,lonlen,altlen,ctllen,&
694                     altlong_name,altunits,altpositive,&
695                     nout,latdimout,londimout,altdimout,timedimout,timevarout)
696!==============================================================================
697! Purpose:
698! Create and initialize a data file (NetCDF format)
699!==============================================================================
700! Remarks:
701! The NetCDF file (created in this subroutine) remains open
702!==============================================================================
703
704implicit none
705
706include "netcdf.inc" ! NetCDF definitions
707
708!==============================================================================
709! Arguments:
710!==============================================================================
711character (len=*), intent(in):: filename
712! filename(): the file's name
713integer,intent(in) ::latlen,lonlen,altlen,ctllen
714real, intent(in):: lat(latlen)
715! lat(): latitude
716real, intent(in):: lon(lonlen)
717! lon(): longitude
718real, intent(in):: alt(altlen)
719! alt(): altitude
720real, intent(in):: ctl(ctllen)
721! ctl(): controle
722character (len=*), intent(in) :: altlong_name
723! altlong_name(): [netcdf] altitude "long_name" attribute
724character (len=*), intent(in) :: altunits
725! altunits(): [netcdf] altitude "units" attribute
726character (len=*), intent(in) :: altpositive
727! altpositive(): [netcdf] altitude "positive" attribute
728integer, intent(out):: nout
729! nout: [netcdf] file ID
730integer, intent(out):: latdimout
731! latdimout: [netcdf] lat() (i.e.: latitude)  ID
732integer, intent(out):: londimout
733! londimout: [netcdf] lon()  ID
734integer, intent(out):: altdimout
735! altdimout: [netcdf] alt()  ID
736integer, intent(out):: timedimout
737! timedimout: [netcdf] "Time"  ID
738integer, intent(out):: timevarout
739! timevarout: [netcdf] "Time" (considered as a variable) ID
740
741!==============================================================================
742! Local variables:
743!==============================================================================
744!integer :: latdim,londim,altdim,timedim
745integer :: nvarid,ierr
746integer :: ctldimout
747! nvarid: [netcdf] ID of a variable
748! ierr: [netcdf]  return error code (from called subroutines)
749
750!==============================================================================
751! 1. Create (and open) output file
752!==============================================================================
753write(*,*) "creating "//trim(adjustl(filename))//'...'
754ierr = NF_CREATE(filename,IOR(NF_CLOBBER,NF_64BIT_OFFSET),nout)
755! NB: setting NF_CLOBBER mode means that it's OK to overwrite an existing file
756if (ierr.NE.NF_NOERR) then
757   WRITE(*,*)'ERROR: Impossible to create the file ',trim(filename)
758   write(*,*) NF_STRERROR(ierr)
759   stop ""
760endif
761
762!==============================================================================
763! 2. Define/write "dimensions" and get their IDs
764!==============================================================================
765
766ierr = NF_DEF_DIM(nout, "latitude", latlen, latdimout)
767if (ierr.NE.NF_NOERR) then
768   WRITE(*,*)'initiate: error failed to define dimension <latitude>'
769   write(*,*) NF_STRERROR(ierr)
770   stop ""
771endif
772ierr = NF_DEF_DIM(nout, "longitude", lonlen, londimout)
773if (ierr.NE.NF_NOERR) then
774   WRITE(*,*)'initiate: error failed to define dimension <longitude>'
775   write(*,*) NF_STRERROR(ierr)
776   stop ""
777endif
778ierr = NF_DEF_DIM(nout, "altitude", altlen, altdimout)
779if (ierr.NE.NF_NOERR) then
780   WRITE(*,*)'initiate: error failed to define dimension <altitude>'
781   write(*,*) NF_STRERROR(ierr)
782   stop ""
783endif
784if (size(ctl).ne.0) then
785  ierr = NF_DEF_DIM(nout, "index", ctllen, ctldimout)
786  if (ierr.NE.NF_NOERR) then
787    WRITE(*,*)'initiate: error failed to define dimension <index>'
788    write(*,*) NF_STRERROR(ierr)
789    stop ""
790  endif
791endif
792ierr = NF_DEF_DIM(nout, "Time", NF_UNLIMITED, timedimout)
793if (ierr.NE.NF_NOERR) then
794   WRITE(*,*)'initiate: error failed to define dimension <Time>'
795   write(*,*) NF_STRERROR(ierr)
796   stop ""
797endif
798
799! End netcdf define mode
800ierr = NF_ENDDEF(nout)
801if (ierr.NE.NF_NOERR) then
802   WRITE(*,*)'initiate: error failed to switch out of define mode'
803   write(*,*) NF_STRERROR(ierr)
804   stop ""
805endif
806
807!==============================================================================
808! 3. Write "Time" and its attributes
809!==============================================================================
810
811call def_var(nout,"Time","Ls (Solar Longitude)","degrees",1,&
812             (/timedimout/),timevarout,ierr)
813! Switch to netcdf define mode
814ierr = NF_REDEF (nout)
815ierr = NF_ENDDEF(nout)
816
817!==============================================================================
818! 4. Write "latitude" (data and attributes)
819!==============================================================================
820
821call def_var(nout,"latitude","latitude","degrees_north",1,&
822             (/latdimout/),nvarid,ierr)
823
824ierr = NF_PUT_VAR_REAL (nout,nvarid,lat)
825if (ierr.NE.NF_NOERR) then
826   WRITE(*,*)'initiate: error failed writing variable <latitude>'
827   write(*,*) NF_STRERROR(ierr)
828   stop ""
829endif
830
831!==============================================================================
832! 4. Write "longitude" (data and attributes)
833!==============================================================================
834
835call def_var(nout,"longitude","East longitude","degrees_east",1,&
836             (/londimout/),nvarid,ierr)
837
838ierr = NF_PUT_VAR_REAL (nout,nvarid,lon)
839if (ierr.NE.NF_NOERR) then
840   WRITE(*,*)'initiate: error failed writing variable <longitude>'
841   write(*,*) NF_STRERROR(ierr)
842   stop ""
843endif
844
845!==============================================================================
846! 5. Write "altitude" (data and attributes)
847!==============================================================================
848
849! Switch to netcdf define mode
850ierr = NF_REDEF (nout)
851
852ierr = NF_DEF_VAR (nout,"altitude",NF_FLOAT,1,altdimout,nvarid)
853
854ierr = NF_PUT_ATT_TEXT (nout,nvarid,'long_name',len_trim(adjustl(altlong_name)),adjustl(altlong_name))
855ierr = NF_PUT_ATT_TEXT (nout,nvarid,'units',len_trim(adjustl(altunits)),adjustl(altunits))
856ierr = NF_PUT_ATT_TEXT (nout,nvarid,'positive',len_trim(adjustl(altpositive)),adjustl(altpositive))
857
858! End netcdf define mode
859ierr = NF_ENDDEF(nout)
860
861ierr = NF_PUT_VAR_REAL (nout,nvarid,alt)
862if (ierr.NE.NF_NOERR) then
863   WRITE(*,*)'initiate: error failed writing variable <altitude>'
864   write(*,*) NF_STRERROR(ierr)
865   stop ""
866endif
867
868!==============================================================================
869! 6. Write "controle" (data and attributes)
870!==============================================================================
871
872if (size(ctl).ne.0) then
873   ! Switch to netcdf define mode
874   ierr = NF_REDEF (nout)
875
876   ierr = NF_DEF_VAR (nout,"controle",NF_FLOAT,1,ctldimout,nvarid)
877
878   ierr = NF_PUT_ATT_TEXT (nout,nvarid,"title",18,"Control parameters")
879
880   ! End netcdf define mode
881   ierr = NF_ENDDEF(nout)
882
883   ierr = NF_PUT_VAR_REAL (nout,nvarid,ctl)
884   if (ierr.NE.NF_NOERR) then
885      WRITE(*,*)'initiate: error failed writing variable <controle>'
886      write(*,*) NF_STRERROR(ierr)
887      stop ""
888   endif
889endif
890
891end Subroutine initiate
892
893!******************************************************************************
894subroutine init2(infid,lonlen,latlen,altlen,altdimid, &
895                 outfid,londimout,latdimout,altdimout)
896!==============================================================================
897! Purpose:
898! Copy aps(), bps() and phisinit() from input file to output file
899!==============================================================================
900! Remarks:
901! The NetCDF files must be open
902!==============================================================================
903
904implicit none
905
906include "netcdf.inc" ! NetCDF definitions
907
908!==============================================================================
909! Arguments:
910!==============================================================================
911integer, intent(in) :: infid  ! NetCDF output file ID
912integer, intent(in) :: lonlen ! # of grid points along longitude
913integer, intent(in) :: latlen ! # of grid points along latitude
914integer, intent(in) :: altlen ! # of grid points along altitude
915integer, intent(in) :: altdimid ! ID of altitude dimension
916integer, intent(in) :: outfid ! NetCDF output file ID
917integer, intent(in) :: londimout ! longitude dimension ID
918integer, intent(in) :: latdimout ! latitude dimension ID
919integer, intent(in) :: altdimout ! altitude dimension ID
920!==============================================================================
921! Local variables:
922!==============================================================================
923real,dimension(:),allocatable :: aps,bps ! hybrid vertical coordinates
924real,dimension(:,:),allocatable :: phisinit ! Ground geopotential
925integer :: apsid,bpsid,phisinitid
926integer :: ierr
927integer :: tmpdimid ! temporary dimension ID
928integer :: tmpvarid ! temporary variable ID
929integer :: tmplen ! temporary variable length
930logical :: phis, aps_ok, bps_ok ! are "phisinit" "aps" "bps" available ?
931
932
933!==============================================================================
934! 1. Read data from input file
935!==============================================================================
936
937! hybrid coordinate aps
938  allocate(aps(altlen),stat=ierr)
939  if (ierr.ne.0) then
940    write(*,*) "init2: failed to allocate aps(altlen)"
941    stop
942  endif
943
944ierr=NF_INQ_VARID(infid,"aps",tmpvarid)
945if (ierr.ne.NF_NOERR) then
946  write(*,*) "oops Failed to get aps ID. OK"
947  aps_ok=.false.
948else
949  ! Check that aps() is the right size (it most likely won't be if
950  ! zrecast has be used to generate the input file)
951  ierr=NF_INQ_VARDIMID(infid,tmpvarid,tmpdimid)
952  ierr=NF_INQ_DIMLEN(infid,tmpdimid,tmplen)
953  if (tmplen.ne.altlen) then
954    write(*,*) "tmplen,altlen", tmpdimid, altdimid
955    write(*,*) "init2: wrong dimension size for aps(), skipping it ..."
956    aps_ok=.false.
957  else
958    ierr=NF_GET_VAR_REAL(infid,tmpvarid,aps)
959    if (ierr.ne.NF_NOERR) then
960     stop "init2 error: Failed reading aps"
961     aps_ok=.false.
962    endif
963    aps_ok=.true.
964  endif
965endif
966
967! hybrid coordinate bps
968  allocate(bps(altlen),stat=ierr)
969  if (ierr.ne.0) then
970    write(*,*) "init2: failed to allocate bps(altlen)"
971    stop
972  endif
973
974ierr=NF_INQ_VARID(infid,"bps",tmpvarid)
975if (ierr.ne.NF_NOERR) then
976  write(*,*) "oops: Failed to get bps ID. OK"
977  bps_ok=.false.
978else
979  ! Check that bps() is the right size
980  ierr=NF_INQ_VARDIMID(infid,tmpvarid,tmpdimid)
981  ierr=NF_INQ_DIMLEN(infid,tmpdimid,tmplen)
982  if (tmplen.ne.altlen) then
983    write(*,*) "init2: wrong dimension size for bps(), skipping it ..."
984    bps_ok=.false.
985  else
986    ierr=NF_GET_VAR_REAL(infid,tmpvarid,bps)
987    if (ierr.ne.NF_NOERR) then
988      stop "init2 Error: Failed reading bps"
989      bps_ok=.false.
990    endif
991    bps_ok=.true.
992  endif
993endif
994
995! ground geopotential phisinit
996allocate(phisinit(lonlen,latlen),stat=ierr)
997if (ierr.ne.0) then
998  write(*,*) "init2: failed to allocate phisinit(lonlen,latlen)"
999  stop
1000endif
1001ierr=NF_INQ_VARID(infid,"phisinit",tmpvarid)
1002if (ierr.ne.NF_NOERR) then
1003  write(*,*) "Failed to get phisinit ID. OK"
1004  phisinit = 0.
1005  phis = .false.
1006else
1007  ierr=NF_GET_VAR_REAL(infid,tmpvarid,phisinit)
1008  if (ierr.ne.NF_NOERR) then
1009    stop "init2 Error: Failed reading phisinit"
1010  endif
1011  phis = .true.
1012endif
1013
1014
1015!==============================================================================
1016! 2. Write
1017!==============================================================================
1018
1019!==============================================================================
1020! 2.2. Hybrid coordinates aps() and bps()
1021!==============================================================================
1022
1023IF (aps_ok) then
1024  ! define aps
1025  call def_var(outfid,"aps","hybrid pressure at midlayers"," ",1,&
1026               (/altdimout/),apsid,ierr)
1027  if (ierr.ne.NF_NOERR) then
1028    stop "Error: Failed to def_var aps"
1029  endif
1030
1031  ! write aps
1032  ierr=NF_PUT_VAR_REAL(outfid,apsid,aps)
1033  if (ierr.ne.NF_NOERR) then
1034    stop "Error: Failed to write aps"
1035  endif
1036ENDIF ! of IF (aps_ok)
1037
1038IF (bps_ok) then
1039  ! define bps
1040  call def_var(outfid,"bps","hybrid sigma at midlayers"," ",1,&
1041               (/altdimout/),bpsid,ierr)
1042  if (ierr.ne.NF_NOERR) then
1043    stop "Error: Failed to def_var bps"
1044  endif
1045
1046  ! write bps
1047  ierr=NF_PUT_VAR_REAL(outfid,bpsid,bps)
1048  if (ierr.ne.NF_NOERR) then
1049    stop "Error: Failed to write bps"
1050  endif
1051ENDIF ! of IF (bps_ok)
1052
1053!==============================================================================
1054! 2.2. phisinit()
1055!==============================================================================
1056
1057IF (phis) THEN
1058
1059  !define phisinit
1060  call def_var(outfid,"phisinit","Ground level geopotential"," ",2,&
1061              (/londimout,latdimout/),phisinitid,ierr)
1062  if (ierr.ne.NF_NOERR) then
1063     stop "Error: Failed to def_var phisinit"
1064  endif
1065
1066  ! write phisinit
1067  ierr=NF_PUT_VAR_REAL(outfid,phisinitid,phisinit)
1068  if (ierr.ne.NF_NOERR) then
1069    stop "Error: Failed to write phisinit"
1070  endif
1071
1072ENDIF ! of IF (phis)
1073
1074
1075! Cleanup
1076deallocate(aps)
1077deallocate(bps)
1078deallocate(phisinit)
1079
1080end subroutine init2
1081
1082!******************************************************************************
1083subroutine def_var(nid,name,title,units,nbdim,dim,nvarid,ierr)
1084!==============================================================================
1085! Purpose: Write a variable (i.e: add a variable to a dataset)
1086! called "name"; along with its attributes "title", "units"...
1087! to a file (following the NetCDF format)
1088!==============================================================================
1089! Remarks:
1090! The NetCDF file must be open
1091!==============================================================================
1092
1093implicit none
1094
1095include "netcdf.inc" ! NetCDF definitions
1096
1097!==============================================================================
1098! Arguments:
1099!==============================================================================
1100integer, intent(in) :: nid
1101! nid: [netcdf] file ID #
1102character (len=*), intent(in) :: name
1103! name(): [netcdf] variable's name
1104character (len=*), intent(in) :: title
1105! title(): [netcdf] variable's "title" attribute
1106character (len=*), intent(in) :: units
1107! unit(): [netcdf] variable's "units" attribute
1108integer, intent(in) :: nbdim
1109! nbdim: number of dimensions of the variable
1110integer, dimension(nbdim), intent(in) :: dim
1111! dim(nbdim): [netcdf] dimension(s) ID(s)
1112integer, intent(out) :: nvarid
1113! nvarid: [netcdf] ID # of the variable
1114integer, intent(out) :: ierr
1115! ierr: [netcdf] subroutines returned error code
1116
1117! Switch to netcdf define mode
1118ierr=NF_REDEF(nid)
1119
1120! Insert the definition of the variable
1121ierr=NF_DEF_VAR(nid,adjustl(name),NF_FLOAT,nbdim,dim,nvarid)
1122
1123! Write the attributes
1124ierr=NF_PUT_ATT_TEXT(nid,nvarid,"title",len_trim(adjustl(title)),adjustl(title))
1125ierr=NF_PUT_ATT_TEXT(nid,nvarid,"units",len_trim(adjustl(units)),adjustl(units))
1126
1127! End netcdf define mode
1128ierr=NF_ENDDEF(nid)
1129
1130end subroutine def_var
1131
1132!******************************************************************************
1133subroutine  missing_value(nout,nvarid,missing)
1134!==============================================================================
1135! Purpose:
1136! Write "valid_range" and "missing_value" attributes (of a given
1137! variable) to a netcdf file
1138!==============================================================================
1139! Remarks:
1140! NetCDF file must be open
1141! Variable (nvarid) ID must be set
1142!==============================================================================
1143
1144implicit none
1145
1146include "netcdf.inc"  ! NetCDF definitions
1147
1148!==============================================================================
1149! Arguments:
1150!==============================================================================
1151integer, intent(in) :: nout
1152! nout: [netcdf] file ID #
1153integer, intent(in) :: nvarid
1154! varid: [netcdf] variable ID #
1155!real, dimension(2), intent(in) :: valid_range
1156! valid_range(2): [netcdf] "valid_range" attribute (min and max)
1157real, intent(in) :: missing
1158! missing: [netcdf] "missing_value" attribute
1159
1160!==============================================================================
1161! Local variables:
1162!==============================================================================
1163integer :: ierr
1164! ierr: [netcdf] subroutine returned error code
1165!      INTEGER nout,nvarid,ierr
1166!      REAL missing
1167!      REAL valid_range(2)
1168
1169! Switch to netcdf dataset define mode
1170ierr = NF_REDEF (nout)
1171if (ierr.ne.NF_NOERR) then
1172   print*,'missing_value: '
1173   print*, NF_STRERROR(ierr)
1174endif
1175
1176
1177!********* valid range not used in Lslin ****************
1178! Write valid_range() attribute
1179!ierr=NF_PUT_ATT_REAL(nout,nvarid,'valid_range',NF_FLOAT,2,valid_range)
1180!
1181!if (ierr.ne.NF_NOERR) then
1182!   print*,'missing_value: valid_range attribution failed'
1183!   print*, NF_STRERROR(ierr)
1184!   !write(*,*) 'NF_NOERR', NF_NOERR
1185!   !CALL abort
1186!   stop ""
1187!endif
1188!*********************************************************
1189
1190! Write "missing_value" attribute
1191ierr= NF_PUT_ATT_REAL(nout,nvarid,'missing_value',NF_FLOAT,1,missing)
1192if (ierr.NE.NF_NOERR) then
1193   print*, 'missing_value: missing value attribution failed'
1194   print*, NF_STRERROR(ierr)
1195!    WRITE(*,*) 'NF_NOERR', NF_NOERR
1196!    CALL abort
1197   stop ""
1198endif
1199
1200! End netcdf dataset define mode
1201ierr = NF_ENDDEF(nout)
1202
1203end subroutine  missing_value
1204
1205!******************************************************************************
1206subroutine sol2ls(sol,Ls)
1207!==============================================================================
1208! Purpose:
1209! Convert a date/time, given in sol (martian day),
1210! into solar longitude date/time, in Ls (in degrees),
1211! where sol=0 is (by definition) the northern hemisphere
1212!  spring equinox (where Ls=0).
1213!==============================================================================
1214! Notes:
1215! Even though "Ls" is cyclic, if "sol" is greater than N (martian) year,
1216! "Ls" will be increased by N*360
1217! Won't work as expected if sol is negative (then again,
1218! why would that ever happen?)
1219!==============================================================================
1220
1221implicit none
1222
1223!==============================================================================
1224! Arguments:
1225!==============================================================================
1226real,intent(in) :: sol
1227real,intent(out) :: Ls
1228
1229!==============================================================================
1230! Local variables:
1231!==============================================================================
1232real year_day,peri_day,timeperi,e_elips,twopi,degrad
1233data year_day /669./            ! # of sols in a martian year
1234data peri_day /485.0/           
1235data timeperi /1.9082314/! True anomaly at vernal equinox = 2*PI-Lsperi
1236data e_elips  /0.093358/
1237data twopi       /6.2831853/    ! 2.*pi
1238data degrad   /57.2957795/      ! pi/180
1239
1240real zanom,xref,zx0,zdx,zteta,zz
1241
1242integer count_years
1243integer iter
1244
1245!==============================================================================
1246! 1. Compute Ls
1247!==============================================================================
1248
1249zz=(sol-peri_day)/year_day
1250zanom=twopi*(zz-nint(zz))
1251xref=abs(zanom)
1252
1253!  The equation zx0 - e * sin (zx0) = xref, solved by Newton
1254zx0=xref+e_elips*sin(xref)
1255do iter=1,20 ! typically, 2 or 3 iterations are enough
1256   zdx=-(zx0-e_elips*sin(zx0)-xref)/(1.-e_elips*cos(zx0))
1257   zx0=zx0+zdx
1258   if(abs(zdx).le.(1.e-7)) then
1259!      write(*,*)'iter:',iter,'     |zdx|:',abs(zdx)
1260      exit
1261   endif
1262enddo
1263
1264if(zanom.lt.0.) zx0=-zx0
1265
1266zteta=2.*atan(sqrt((1.+e_elips)/(1.-e_elips))*tan(zx0/2.))
1267Ls=zteta-timeperi
1268
1269if(Ls.lt.0.) then
1270   Ls=Ls+twopi
1271else
1272   if(Ls.gt.twopi) then
1273      Ls=Ls-twopi
1274   endif
1275endif
1276
1277Ls=degrad*Ls
1278! Ls is now in degrees
1279
1280!==============================================================================
1281! 1. Account for (eventual) years included in input date/time sol
1282!==============================================================================
1283
1284count_years=0 ! initialize
1285zz=sol  ! use "zz" to store (and work on) the value of sol
1286do while (zz.ge.year_day)
1287   count_years=count_years+1
1288   zz=zz-year_day
1289enddo
1290
1291! Add 360 degrees to Ls for every year
1292if (count_years.ne.0) then
1293   Ls=Ls+360.*count_years
1294endif
1295
1296
1297end subroutine sol2ls
1298!************************************
1299
1300Subroutine interpolf(x,y,xd,yd,nd)
1301!interpolation, give y = f(x) with array xd,yd known, size nd
1302! Version with CONSTANT values oustide limits
1303! Variable declaration
1304! --------------------
1305!  Arguments :
1306real x,y
1307real xd(*),yd(*)
1308integer nd
1309!  internal
1310integer i
1311real y_undefined
1312                                                                               
1313! run
1314! ---
1315      y_undefined=1.e20
1316                                                                               
1317      y=0.
1318   if ((x.le.xd(1)).and.(x.le.xd(nd))) then
1319    if (xd(1).lt.xd(nd)) y = yd(1) !y_undefined
1320    if (xd(1).ge.xd(nd)) y = y_undefined ! yd(nd)
1321   else if ((x.ge.xd(1)).and.(x.ge.xd(nd))) then
1322    if (xd(1).lt.xd(nd)) y =  y_undefined ! yd(nd)
1323    if (xd(1).ge.xd(nd)) y = y_undefined ! yd(1)
1324    y = yd(nd)
1325   else
1326    do i=1,nd-1
1327     if ( ( (x.ge.xd(i)).and.(x.lt.xd(i+1)) ).or.((x.le.xd(i)).and.(x.gt.xd(i+1))) ) then
1328     y=yd(i)+(x-xd(i))*(yd(i+1)-yd(i))/(xd(i+1)-xd(i))
1329     goto 99
1330     end if
1331    end do
1332   end if
1333
1334!     write (*,*)' x , y' , x,y
1335!     do i=1,nd
1336!       write (*,*)' i, xd , yd' ,i, xd(i),yd(i)
1337!     end do
1338!     stop
1339                                                                               
134099   continue
1341                                                                               
1342end subroutine interpolf
1343     
1344end program lslin
Note: See TracBrowser for help on using the repository browser.