The TELEMAC-MASCARET system  trunk
find_variable.f
Go to the documentation of this file.
1 ! ************************
2  SUBROUTINE find_variable
3 ! ************************
4 !
5  &(fformat,fid,var_name,res,n,ierr,time,eps_time,record,
6  & time_record, offset)
7 !
8 !***********************************************************************
9 ! HERMES V7P2
10 !***********************************************************************
11 !
12 !brief Returns the value for each point of a given variable,
13 !+ for a given time or a given record.
14 !+ This subroutine can interpolate from two time steps
15 !+ if the time does not exist in the file with an accuracy of EPS.
16 !+
17 !+ If no optional parameter is given, the last record is chosen.
18 !+
19 !+ Accepted formats so far: 'SERAFIN ', 'SERAFIND', 'MED '
20 !
21 !history Y. AUDOUIN (EDF LAB, LNHE)
22 !+ 28/07/2015
23 !+ V7P1
24 !+ First version.
25 !
26 !history J-M HERVOUET (EDF LAB, LNHE)
27 !+ 10/06/2016
28 !+ V7P2
29 !+ Just a message corrected.
30 !
31 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 !| EPS_TIME |-->| EPSILON TO DETERMINE IF TWO TIMES ARE EQUAL
33 !| | | IF NOT PRESENT, CONSIDERED TO BE 0.D0
34 !| IERR |<--| 0 IF NO ERROR DURING THE EXECUTION
35 !| FFORMAT |-->| FORMAT OF THE FILE
36 !| FID |-->| FILE LOGICAL UNIT
37 !| RECORD |-->| RECORD OF RESULTS IN THE FILE THAT SHOULD BE
38 !| | | TAKEN. RECORD = -1 TAKES THE LAST RECORD.
39 !| RES |<->| VALUE FOR EACH POINT AT TIME STEP RECORD
40 !| | | FOR THE VARIABLE VAR_NAME
41 !| TIME |-->| TIME TO INTERPOLATE FROM THE FILE
42 !| TIME_RECORD |<--| TIME OF THE RECORD THAT HAS BEEN CHOSEN
43 !| VAR_NAME |-->| VARIABLE FOR WHICH WE NEED THE VALUE
44 !| N |-->| SIZE OF EXPECTED RES_VALUE
45 !| OFFSET |-->| OFFSET FOR TIME
46 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47 !
48  USE bief, ONLY : date_mjd2sec
51 !
53  IMPLICIT NONE
54 !
55 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 !
57  CHARACTER(LEN=8), INTENT(IN) :: FFORMAT
58  INTEGER, INTENT(IN) :: FID
59  CHARACTER(LEN=16), INTENT(IN) :: VAR_NAME
60  INTEGER, INTENT(IN) :: N
61  DOUBLE PRECISION, INTENT(INOUT) :: RES(n)
62  INTEGER, INTENT(INOUT) :: IERR
63  DOUBLE PRECISION, INTENT(IN) , OPTIONAL :: EPS_TIME,TIME
64  INTEGER, INTENT(IN) , OPTIONAL :: RECORD
65  DOUBLE PRECISION, INTENT(INOUT), OPTIONAL :: TIME_RECORD
66  DOUBLE PRECISION, INTENT(IN), OPTIONAL :: OFFSET
67 !
68 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 !
70  INTEGER RECORD1,RECORD2
71  DOUBLE PRECISION :: TIME1,TIME2,COEF,EPS
72  DOUBLE PRECISION,ALLOCATABLE :: RES2(:)
73  INTEGER NTIMESTEP,I
74  INTEGER :: RRECORD
75  CHARACTER(LEN=16), ALLOCATABLE :: VAR_LIST(:)
76  CHARACTER(LEN=16), ALLOCATABLE :: UNIT_LIST(:)
77  INTEGER :: NVAR
78  DOUBLE PRECISION :: TEL_OFFSET1
79  INTEGER, DIMENSION(6) :: DATE
80  DOUBLE PRECISION :: OFFSET_FILE
81  DOUBLE PRECISION :: TIME_FULL
82 !
83 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84 !
85  IF(PRESENT(offset)) THEN
86  tel_offset1 = offset
87  ELSE
88  tel_offset1 = 0.d0
89  ENDIF
90 
91  IF(PRESENT(time)) THEN
92 !
93 ! TIME ASKED
94 !
95 ! EPSILON TO BE CONSIDERED
96  IF(PRESENT(eps_time))THEN
97  eps=eps_time
98  ELSE
99  eps=0.d0
100  ENDIF
101 !
102 ! GET THE NUMBER OF TIME STEPS
103 !
104  CALL get_data_ntimestep(fformat,fid,ntimestep,ierr)
105  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_TIME:REC1')
106 !
107 ! IDENTIFY THE TWO RECORDS IN BETWEEN OUR TIME
108 !
109  record1 = 0
110  record2 = ntimestep-1
111  CALL get_data_time(fformat,fid,record1,time1,ierr)
112  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_TIME:REC1')
113  CALL get_data_time(fformat,fid,record2,time2,ierr)
114  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_TIME:REC2')
115 
116  IF (tel_offset1.GE.1.d-16) THEN
117  CALL get_mesh_date(fformat, fid, date, ierr)
118  IF (any(date.NE.0)) THEN
119  offset_file = date_mjd2sec(date(1:3),date(4:6))
120  time_full = time + tel_offset1
121  ELSE
122  time_full = time
123  offset_file = 0.d0
124  ENDIF
125  ELSE
126  time_full = time
127  offset_file = 0.d0
128  ENDIF
129 
130  time1 = time1+offset_file
131  time2 = time2+offset_file
132 
133 !
134 ! Quick check to see if the time is indeed within the first
135 ! and last time step of the file
136 !
137  IF((time1.GT.time_full.AND.abs(time1-time_full).GT.eps)
138  & .OR.(time2.LT.time_full.AND.abs(time2-time_full).GT.eps)) THEN
139  WRITE(lu,*) 'TIME: ',time_full,
140  & 'IS NOT WITHIN THE RANGE',
141  & ' OF THE FILE I.E.[',
142  & time1,'-',time2,']'
143  CALL plante(1)
144  stop
145  ENDIF
146 !
147  DO WHILE ((time1.LT.time_full).AND.
148  & (abs(time1-time_full).GT.eps) )
149  record1 = record1 + 1
150  CALL get_data_time(fformat,fid,record1,time1,ierr)
151  time1 = time1+offset_file
152  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_TIME:REC1')
153  ENDDO
154 ! If the time is on the file return the value for that record
155 ! otherwise we interpolate between the two time step
156  IF(abs(time1-time_full).LE.eps) THEN
157  CALL get_data_value(fformat,fid,record1,var_name,res,n,ierr)
158  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_VALUE:REC1')
159  ELSE
160 ! Get the time and values for the record before and after time
161  record2 = record1
162  record1 = record1 -1
163  CALL get_data_time(fformat,fid,record1,time1,ierr)
164  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_TIME:REC1')
165  CALL get_data_time(fformat,fid,record2,time2,ierr)
166  time1 = time1+offset_file
167  time2 = time2+offset_file
168  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_TIME:REC2')
169 ! Get the value for each time step
170  CALL get_data_value(fformat,fid,record1,var_name,res,n,ierr)
171  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_VALUE:REC1')
172  ALLOCATE(res2(n),stat=ierr)
173  CALL check_allocate(ierr,'FIND_VARIABLE:RES2')
174  CALL get_data_value(fformat,fid,record2,var_name,res2,n,ierr)
175  CALL check_call(ierr,'FIND_VARIABLE:GET_DATA_VALUE:REC1')
176 !
177 ! Interpolates in time
178  coef=(time_full-time1)/(time2-time1)
179 !
180  DO i=1,n
181  res(i)=(res2(i)-res(i))*coef+res(i)
182  ENDDO
183  DEALLOCATE(res2)
184  ENDIF
185 !
186  ELSE
187  CALL get_data_ntimestep(fformat,fid,ntimestep,ierr)
188  CALL check_call(ierr, 'READ_DATA:GET_DATA_NTIMESTEP')
189  ! Check if record was given if not 0 is taken
190  IF (PRESENT(record)) THEN
191  ! Taking last time step
192  IF(record.EQ.-1) THEN
193  rrecord = ntimestep - 1
194  ELSE
195  rrecord = record
196  ENDIF
197  ELSE
198  rrecord = 0
199  ENDIF
200  ! WE CHECK IF THE RECORD IS IN THE FILE BY GETTING THE NUMBER OF
201  ! TIMESTEPS AND CHECKING THAT THE RECORD IS INDEED
202  ! BETWEEN 0 AND NTIMESTEP - 1
203  IF((rrecord.LT.0).AND.(rrecord.GE.ntimestep)) THEN
205  RETURN
206  ENDIF
207  ! CHECKING THAT THE VARIABLE IS INDEED IN THE FILE
208  ! BY LOOPING ON THE LIST OF VARIABLE
209  CALL get_data_nvar(fformat,fid,nvar,ierr)
210  CALL check_call(ierr, 'FIND_VARIABLE:GET_DATA_NVAR')
211  ALLOCATE(var_list(nvar),stat=ierr)
212  ALLOCATE(unit_list(nvar),stat=ierr)
213  CALL check_allocate(ierr, 'VAR_LIST')
214  CALL get_data_var_list(fformat,fid,nvar,var_list,
215  & unit_list,ierr)
216  CALL check_call(ierr, 'FIND_VARIABLE:GET_DATA_VAR_LIST')
217  i=1
218  DO WHILE(i.LE.nvar)
219  IF (var_list(i).EQ.var_name) EXIT
220  i = i +1
221  ENDDO
222  IF(i.EQ.nvar+1) THEN
224  RETURN
225  ENDIF
226  DEALLOCATE(var_list)
227  DEALLOCATE(unit_list)
228 
229  ! Getting the data value by record number
230 !
231  ! If asked for giving the time value associated with the record
232  IF(PRESENT(time_record)) THEN
233  CALL get_data_time(fformat,fid,rrecord,time_record,ierr)
234  IF(ierr.NE.0) THEN
235  WRITE(lu,*) 'ERROR WHILE READING TIME VALUE ',
236  & 'FOR RECORD:',rrecord
237  CALL plante(1)
238  stop
239  ENDIF
240  ENDIF
241  CALL get_data_value(fformat,fid,rrecord,var_name,res,
242  & n,ierr)
243  IF(ierr.NE.0) THEN
244  WRITE(lu,*) 'ERROR WHILE READING VALUE ',
245  & 'FOR VARIABLE:',var_name,
246  & 'FOR RECORD:',rrecord
247  CALL plante(1)
248  stop
249  ENDIF
250 !
251  ENDIF
252 !
253 !-----------------------------------------------------------------------
254 !
255  RETURN
256  END
257 
subroutine get_data_nvar(FFORMAT, FID, NVAR, IERR)
Definition: get_data_nvar.f:7
subroutine get_data_var_list(FFORMAT, FID, NVAR, VARLIST, UNITLIST, IERR)
subroutine get_data_value(FFORMAT, FID, RECORD, VAR_NAME, RES_VALUE, N, IERR)
Definition: get_data_value.f:7
integer, parameter hermes_record_unknown_err
subroutine get_mesh_date(FFORMAT, FID, DATE, IERR)
Definition: get_mesh_date.f:7
subroutine find_variable(FFORMAT, FID, VAR_NAME, RES, N, IERR, TIME, EPS_TIME, RECORD, TIME_RECORD, OFFSET)
Definition: find_variable.f:8
double precision function date_mjd2sec(DATE, TIME)
Definition: date_mjd2sec.f:7
integer, parameter hermes_var_unknown_err
subroutine get_data_time(FFORMAT, FID, RECORD, TIME, IERR)
Definition: get_data_time.f:7
subroutine get_data_ntimestep(FFORMAT, FID, NTIMESTEP, IERR)
Definition: bief.f:3