The TELEMAC-MASCARET system  trunk
cvtrvf_eria.f
Go to the documentation of this file.
1 ! **********************
2  SUBROUTINE cvtrvf_eria
3 ! **********************
4 !
5  &(f,fn,fscexp,h,hn,hprop,udel,vdel,dm1,zconv,solsys,
6  & sm,smh,yasmh,smi,yasmi,fbor,masktr,mesh,
7  & t1,t2,t3,t4,t5,t6,t7,ht,dt,entet,
8  & msk,maskel,optsou,limtra,kdir,kddl,nptfr,flbor,
9  & yaflbor,unsv2d,iopt,flbortra,nbor,
10  & rain,pluie,train,nitmax,nco_dist,optadv)
11 !
12 !***********************************************************************
13 ! BIEF V7P3
14 !***********************************************************************
15 !
16 !brief Distributive advection scheme ERIA
17 !
18 !warning SEE BELOW FOR DEFINITION OF IOPT1 AND IOPT2, RETRIEVED FROM IOPT
19 !+ IOPT2=1 NOT TREATED HERE, MASS-CONSERVATION WILL BE DOWNGRADED
20 !+ IN THIS CASE (A CORRECT TREATMENT MAY RESULT IN INFINITE F)
21 !+ THE PROGRAM WILL NOT STOP IF IOPT2=1
22 !
23 !history J-M HERVOUET (EDF LAB, LNHE)
24 !+ 09/09/2016
25 !+ V7P2
26 !+ First version. Comes from the former cvtrvf_pos with option 1.
27 !
28 !history J-M HERVOUET (EDF LAB, LNHE)
29 !+ 23/11/2016
30 !+ V7P3
31 !+ Adding an option for predictor for sharing volumes of points
32 !+ between elements (see variable OPTPRE, OPTPRE=1 old strategy,
33 !+ OPTPRE=2, new and simpler strategy). Tests do not show much
34 !+ difference, kept here to be tested in other cases.
35 !
36 !history J-M HERVOUET (EDF LAB, LNHE)
37 !+ 02/01/2017
38 !+ V7P3
39 !+ Second order in time added.
40 !
41 !history J-M HERVOUET (EDF LAB, LNHE)
42 !+ 09/09/2017
43 !+ V7P3
44 !+ Treating cases where NELMAX is not equal to NELEM.
45 !
46 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47 !| DM1 |-->| THE PIECE-WISE CONSTANT PART OF ADVECTION FIELD
48 !| | | IS DM1*GRAD(ZCONV), SEE SOLSYS.
49 !| DT |-->| TIME STEP
50 !| ENTET |-->| LOGICAL, IF YES INFORMATION IS GIVEN ON MASS
51 !| | | CONSERVATION.
52 !| F |<--| F AT TIME T(N+1)
53 !| FBOR |-->| DIRICHLET CONDITIONS ON F.
54 !| FLBOR |-->| FLUXES AT BOUNDARIES
55 !| FLBORTRA |<->| TRACER FLUXES AT BOUNDARIES
56 !| FN |-->| F AT TIME T(N)
57 !| FSCEXP |-->| EXPLICIT PART OF THE SOURCE TERM
58 !| | | EQUAL TO ZERO EVERYWHERE BUT ON SOURCES
59 !| | | WHERE THERE IS FSCE - (1-TETAT) FN
60 !| | | SEE DIFSOU
61 !| HT |<--| WORK ARRAY (DEPTH GOING FROM HN TO H)
62 !| HPROP |-->| PROPAGATION DEPTH (DONE IN CVDFTR).
63 !| IOPT |-->| OPTIONS FOR COMPUTATION (NUMBER BETWEEN 0 AND 13)
64 !| | | THE TENS (IOPT2, I.E. 0 OR 1):
65 !| | | 0: UCONV OBEYS THE CONTINUITY EQUATION
66 !| | | 1: UCONV DOES NOT OBEY THE CONTINUITY EQUATION
67 !| | | THE UNITS (IOPT1, I.E. 0 TO 3): VARIANT FOR FLUXES
68 !| | | 0: CONSTANT PER ELEMENT = 0
69 !| | | 1: CHI-TUAN PHAM'S CONSTANT
70 !| | | 2: N SCHEME
71 !| | | 3: PSI SCHEME
72 !| KDDL |-->| CONVENTION FOR DEGREE OF FREEDOM
73 !| KDIR |-->| CONVENTION FOR DIRICHLET POINT
74 !| LIMTRA |-->| BOUNDARY CONDITIONS ON BOOUNDARY POINTS
75 !| MASKEL |-->| MASKING OF ELEMENTS
76 !| | | =1. : NORMAL =0. : MASKED ELEMENT
77 !| MESH |-->| MESH STRUCTURE
78 !| MSK |-->| IF YES, THERE IS MASKED ELEMENTS.
79 !| NBOR |-->| GLOBAL NUMBERS OF BOUNDARY POINTS
80 !| NCO_DIST |-->| NUMBER OF CORRECTIONS IN DISTRIBUTIVE SCHEMES
81 !| NITMAX |-->| MAXIMUM NUMBER OF ITERATIONS
82 !| NPTFR |-->| NUMBER OF BOUNDARY POINTS
83 !| OPTADV |-->| FOR ERIA SCHEME 1: FIRST ORDER
84 !| | | 2: SECOND ORDER
85 !| OPTSOU |-->| TYPE OF SOURCES
86 !| | | 1: NORMAL
87 !| | | 2: DIRAC
88 !| PLUIE |-->| RAIN OR EVAPORATION, IN M/S
89 !| RAIN |-->| IF YES: RAIN OR EVAPORATION
90 !| SM |-->| SOURCE TERMS.
91 !| SMH |-->| SOURCE TERM IN CONTINUITY EQUATION
92 !| SMI |-->| IMPLICIT SOURCE TERM
93 !| SOLSYS |-->| 1 OR 2. IF 2 ADVECTION FIELD IS UCONV + DM1*GRAD(ZCONV)
94 !| T1 |<->| WORK BIEF_OBJ STRUCTURE
95 !| T2 |<->| WORK BIEF_OBJ STRUCTURE
96 !| T3 |<->| WORK BIEF_OBJ STRUCTURE
97 !| T4 |<->| WORK BIEF_OBJ STRUCTURE
98 !| T5 |<->| WORK BIEF_OBJ STRUCTURE
99 !| T6 |<->| WORK BIEF_OBJ STRUCTURE
100 !| T7 |<->| WORK BIEF_OBJ STRUCTURE
101 !| TRAIN |-->| VALUE OF TRACER IN THE RAIN
102 !| UDEL |-->| X-COMPONENT OF ADVECTION VELOCITY
103 !| UNSV2D |-->| INVERSE OF V2DPAR
104 !| VDEL |-->| X-COMPONENT OF ADVECTION VELOCITY
105 !| YAFLBOR |-->| IF YES FLBOR IS GIVEN
106 !| YASMH |-->| IF YES, SMH MUST BE TAKEN INTO ACCOUNT
107 !| YASMI |-->| IF YES, SMI MUST BE TAKEN INTO ACCOUNT
108 !| ZCONV |-->| THE PIECE-WISE CONSTANT PART OF ADVECTION FIELD
109 !| | | IS DM1*GRAD(ZCONV), SEE SOLSYS.
110 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
111 !
112  USE bief, ex_cvtrvf_eria => cvtrvf_eria
114 !
117 !
118  IMPLICIT NONE
119 !
120 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
121 !
122  INTEGER, INTENT(IN) :: OPTSOU,KDIR,NPTFR,SOLSYS
123  INTEGER, INTENT(IN) :: KDDL,IOPT,NITMAX,OPTADV
124  INTEGER, INTENT(IN) :: NCO_DIST
125  INTEGER, INTENT(IN) :: NBOR(nptfr)
126  INTEGER, INTENT(INOUT) :: LIMTRA(nptfr)
127  DOUBLE PRECISION, INTENT(IN) :: DT,TRAIN
128  LOGICAL, INTENT(IN) :: YASMH,YAFLBOR,RAIN
129  LOGICAL, INTENT(IN) :: MSK,ENTET,YASMI
130  TYPE(bief_obj), INTENT(IN) :: MASKEL,H,HN,DM1,ZCONV
131  TYPE(bief_obj), INTENT(IN) :: UNSV2D,HPROP
132  TYPE(bief_obj), INTENT(IN) :: UDEL,VDEL,FN,SMI,SMH
133  TYPE(bief_obj), INTENT(INOUT) :: FLBORTRA,FBOR,F,SM,HT
134  TYPE(bief_obj), INTENT(INOUT) :: T1,T2,T3,T4,T5,T6,T7,FLBOR
135  TYPE(bief_obj), INTENT(IN) :: FSCEXP,MASKTR,PLUIE
136  TYPE(bief_mesh) :: MESH
137 !
138 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
139 !
140  INTEGER I,IOPT2,NPOIN,IPTFR,I1,I2,I3,NITER,NEWREMAIN,NELMAX
141  INTEGER IR,N,NELEM,IELEM,REMAIN,NSEG
142  INTEGER OPTPRE
143 !
144 !-----------------------------------------------------------------------
145 !
146  DOUBLE PRECISION C,CPREV,CINIT,HFL1,TET,LOCALMIN,LOCALMAX
147  DOUBLE PRECISION F1,F2,F3,COEF,FI1,FI2,FI3,VOL1,VOL2,VOL3
148  DOUBLE PRECISION DT1,DT2,DT3,FMIN,FMAX,VOLD1,VOLD2,VOLD3
149  DOUBLE PRECISION SURDT,FITOT,BETA1,BETA2,BETA3,A1,A2,A3
150  DOUBLE PRECISION FP1,FP2,FP3,FIP1,FIP2,FIP3,FS1,FS2,FS3
151  CHARACTER(LEN=16) FORMUL
152  DOUBLE PRECISION, POINTER, DIMENSION(:) :: FXMAT
153  DOUBLE PRECISION, PARAMETER :: TIERS=1.d0/3.d0
154  LOGICAL, PARAMETER :: TESTING = .false.
155  DOUBLE PRECISION, PARAMETER :: EPS_FLUX = 1.d-15
156  DOUBLE PRECISION, POINTER :: FLOP1(:),FLOP2(:),FLOP3(:)
157  DOUBLE PRECISION, POINTER :: DTLIM1(:),DTLIM2(:),DTLIM3(:)
158  DOUBLE PRECISION, POINTER :: SVOL1(:),SVOL2(:),SVOL3(:)
159 !
160 !-----------------------------------------------------------------------
161 !
162 ! INDIC_CPOS WILL BE A LIST OF SEGMENTS WITH NON ZERO FLUXES
163 !
164  nelem=mesh%NELEM
165  nelmax=mesh%NELMAX
166  nseg=mesh%NSEG
167  npoin=h%DIM1
168  surdt=1.d0/dt
169 !
170  IF(.NOT.deja_cpos) THEN
171  ALLOCATE(indic_cpos(nelem))
172  deja_cpos=.true.
173  ENDIF
174 !
175 !-----------------------------------------------------------------------
176 !
177 ! THERE IS PLENTY OF MEMORY AVAILABLE IN A BIEF_MESH STRUCTURE...
178 !
179 ! 3*NELEM+NPTFR=2*NSEG IN 2D, SO 2*NSEG IS ENOUGH TO STORE 3*NELEM
180  flop1=>mesh%MSEG%X%R( 1: nelem)
181  flop2=>mesh%MSEG%X%R( nelem+1:2*nelem)
182  flop3=>mesh%MSEG%X%R(2*nelem+1:3*nelem)
183  svol1=> mesh%W%R( 1: nelem)
184  svol2=> mesh%W%R( nelem+1:2*nelem)
185  svol3=> mesh%W%R(2*nelem+1:3*nelem)
186  dtlim1=> mesh%M%X%R( 1: nelem)
187  dtlim2=> mesh%M%X%R( nelem+1:2*nelem)
188  dtlim3=> mesh%M%X%R(2*nelem+1:3*nelem)
189 ! ASSUMING THAT NSEG<3*NELEM
190 ! WILL BE DESTROYED WHEN DTLIM1 IS BUILT (BEWARE !!!!)
191  fxmat=>mesh%M%X%R(1:nseg)
192 !
193 !-----------------------------------------------------------------------
194 !
195 ! VARIANTS (1 OR 2, DIFFERENT IMPLEMENTATION FOR SHARING VOLUMES
196 ! AT PREDICTOR LEVEL).
197 !
198 ! OPTPRE MUST BE EQUAL TO ITS VALUE IN POSITIVE_DEPTHS_ERIA !!!!!!!!
199  optpre=1
200 !
201 !-----------------------------------------------------------------------
202 !
203 ! EXTRACTING OPTIONS, AND CONTROL
204 !
205  iopt2=iopt/10
206  IF(iopt2.NE.0.AND.iopt2.NE.1) THEN
207  WRITE(lu,*) 'CVTRVF_ERIA: OPTION IOPT2 UNKNOWN: ',iopt2
208  CALL plante(1)
209  stop
210  ENDIF
211 !
212 !-----------------------------------------------------------------------
213 !
214 ! STARTING AGAIN FROM NON CORRECTED DEPTH
215 !
216  IF(testing) THEN
217  c=1.d99
218  cinit=1.d99
219  DO i=1,npoin
220  c =min(c ,h%R(i))
221  cinit=min(cinit,hn%R(i))
222  ENDDO
223  IF(ncsize.GT.1) THEN
224  c=p_min(c)
225  cinit=p_min(cinit)
226  ENDIF
227  WRITE(lu,*) 'AVANT TRAITEMENT HAUTEURS NEGATIVES, H MIN=',c
228  WRITE(lu,*) 'AVANT TRAITEMENT HAUTEURS NEGATIVES, HN MIN=',cinit
229  ENDIF
230 !
231  CALL cpstvc(h,t1)
232  CALL cpstvc(h,t2)
233  CALL cpstvc(h,t3)
234  CALL cpstvc(h,t4)
235  CALL cpstvc(h,t5)
236  CALL cpstvc(h,t6)
237  CALL cpstvc(h,t7)
238 !
239 ! T2 WILL BE THE ASSEMBLED FLBOR, INITIALISATION HERE
240 ! IS USELESS EXCEPT THAT PARCOM MAY ADD UNDEFINED
241 ! NUMBERS (THAT WILL NOT BE USED BUT THAT WILL STOP
242 ! A COMPILER... TOO BAD!)
243  IF(ncsize.GT.1) CALL os('X=0 ',x=t2)
244 ! OPTIONAL COMPUTATION OF BOUNDARY FLUXES
245  IF(.NOT.yaflbor) THEN
246 ! MASK=8 FOR LIQUID BOUNDARIES
247  CALL vector(flbor,'=','FLUBDF ',1,1.d0,
248  & hprop,hprop,hprop,
249  & udel , vdel, vdel,mesh,.true.,masktr%ADR(8)%P)
250  ENDIF
251 ! BOUNDARY FLUXES : ADDING THE ENTERING (NEGATIVE) FLUXES
252 ! FIRST PUTTING FLBOR (BOUNDARY) IN T2 (DOMAIN)
253  CALL osdb( 'X=Y ' ,t2,flbor,flbor,0.d0,mesh)
254 ! ASSEMBLING T2 (FLBOR IS NOT ASSEMBLED)
255  IF(ncsize.GT.1) CALL parcom(t2,2,mesh)
256 ! POSSIBLE CORRECTION OF LIMTRA AND FBOR (LIMTRA HAS BEEN DONE BY
257 ! DIFFIN WITH U.N)
258  DO i=1,mesh%NPTFR
259  n=mesh%NBOR%I(i)
260  IF(limtra(i).EQ.kdir.AND.t2%R(n).GT.0.d0) THEN
261  limtra(i)=kddl
262  ELSEIF(limtra(i).EQ.kddl.AND.t2%R(n).LT.0.d0) THEN
263  limtra(i)=kdir
264 ! HERE FBOR MAY NOT HAVE BEEN GIVEN, FN TAKEN
265  fbor%R(i)=fn%R(n)
266  ELSE
267 ! INITIALISING FLBORTRA FOR POINTS NOT KDIR AND KDDL
268  flbortra%R(i)=0.d0
269  ENDIF
270  ENDDO
271 !
272 ! INITIALIZING F AND INITIAL H
273 !
274  CALL os('X=Y ',x=f,y=fn)
275  CALL os('X=Y ',x=ht,y=hn)
276 !
277 ! FLUXES
278 !
279  formul='HUGRADP '
280  IF(solsys.EQ.2) formul(8:8)='2'
281 ! COMPUTING THE FLUXES LEAVING NODES
282  CALL vector(t1,'=',formul,h%ELM,-1.d0,
283  & hprop,dm1,zconv,udel,vdel,vdel,mesh,msk,maskel)
284 ! T1 AS HUGRADP IS NOT USED AS AN ASSEMBLED VECTOR
285 ! BUT TO GET THE NON ASSEMBLED FORM MESH%W
286 ! COPYING EBE FLUXES INTO FLOPOINT
287  DO i=1,nelem
288  flop1(i)=mesh%W%R(i)
289  flop2(i)=mesh%W%R(i+nelmax)
290  flop3(i)=mesh%W%R(i+2*nelmax)
291  ENDDO
292 ! ASSEMBLING EBE FLUXES BY SEGMENT (TE1 SUIVI DE FALSE NON UTILISE)
293 ! HARDCODED OPTION 2 (MUST BE THE SAME AS IN POSITIVE_DEPTHS)
294 ! FXMAT IS NOT ASSEMBLED IN //
295  CALL flux_ef_vf(fxmat,mesh%W%R,mesh%NSEG,nelem,nelmax,
296  & mesh%ELTSEG%I,mesh%ORISEG%I,
297  & mesh%IKLE%I,.true.,2)
298 ! ASSEMBLING FXMAT IN PARALLEL
299  IF(ncsize.GT.1) THEN
300  CALL parcom2_seg(fxmat,fxmat,fxmat,mesh%NSEG,1,2,1,mesh,1,11)
301  ENDIF
302 ! CHANGING FLUXES FROM POINTS INTO N FLUXES BETWEEN POINTS
303  DO ielem = 1,nelem
304  a1 = abs(flop1(ielem))
305  a2 = abs(flop2(ielem))
306  a3 = abs(flop3(ielem))
307  IF(a1.GE.a2.AND.a1.GE.a3) THEN
308 ! ALL FLOW TO AND FROM NODE 1
309  flop1(ielem)=-flop2(ielem)
310  flop2(ielem)=0.d0
311 ! FLOP3(IELEM)= UNCHANGED!
312  ELSEIF(a2.GE.a1.AND.a2.GE.a3) THEN
313 ! ALL FLOW TO AND FROM NODE 2
314 ! FLOP1(IELEM)= UNCHANGED!
315  flop2(ielem)=-flop3(ielem)
316  flop3(ielem)=0.d0
317  ELSE
318 ! ALL FLOW TO AND FROM NODE 3
319  flop3(ielem)=-flop1(ielem)
320  flop1(ielem)=0.d0
321 ! FLOP2(IELEM)= UNCHANGED!
322  ENDIF
323  ENDDO
324 !
325 ! ADDING THE POSITIVE SOURCES (SMH IS NATURALLY ASSEMBLED IN //)
326 !
327  IF(yasmh) THEN
328  IF(optsou.EQ.1) THEN
329  DO i=1,npoin
330  IF(smh%R(i).GT.0.d0) THEN
331  ht%R(i)=ht%R(i)+dt*smh%R(i)
332  f%R(i)=f%R(i)+dt/max(ht%R(i),1.d-4)*smh%R(i)*fscexp%R(i)
333  ENDIF
334  ENDDO
335  ELSEIF(optsou.EQ.2) THEN
336  DO i=1,npoin
337  IF(smh%R(i).GT.0.d0) THEN
338  ht%R(i)=ht%R(i)+dt*smh%R(i)*unsv2d%R(i)
339  f%R(i)=f%R(i)+dt/max(ht%R(i),1.d-4)*
340  & unsv2d%R(i)*smh%R(i)*fscexp%R(i)
341  ENDIF
342  ENDDO
343  ENDIF
344  ENDIF
345 !
346 ! RAIN-EVAPORATION: RAIN FIRST, EVAPORATION IN THE END
347 !
348  IF(rain) THEN
349  DO i=1,npoin
350  c=max(pluie%R(i),0.d0)
351 ! HT WILL BE AT LEAST C*DT
352  ht%R(i)=ht%R(i)+c*dt
353  IF(c.NE.0.d0) THEN
354 ! VALUE IN RAIN
355  f%R(i)=f%R(i)+((c*dt)/ht%R(i))*(train-f%R(i))
356  ENDIF
357  ENDDO
358  ENDIF
359 !
360  DO iptfr=1,nptfr
361  i=nbor(iptfr)
362  ht%R(i)=ht%R(i)-dt*unsv2d%R(i)*min(t2%R(i),0.d0)
363 ! ENTERING FLUXES OF TRACERS
364 ! THE FINAL DEPTH IS TAKEN
365  IF(limtra(iptfr).EQ.kdir) THEN
366  f%R(i)=f%R(i)-dt/max(ht%R(i),1.d-4)*
367  & unsv2d%R(i)*t2%R(i)*(fbor%R(iptfr)-f%R(i))
368 ! ELSEIF(LIMTRA(IPTFR).EQ.KDDL) THEN
369 ! NOTHING TO DO
370  ENDIF
371  ENDDO
372 !
373 ! FOR OPTIMIZING THE LOOP ON SEGMENTS, ONLY SEGMENTS
374 ! WITH NON ZERO FLUXES WILL BE CONSIDERED, THIS LIST
375 ! WILL BE UPDATED. TO START WITH, ALL FLUXES ASSUMED NON ZERO
376 !
377  remain=mesh%NELEM
378 !
379  DO i=1,remain
380  indic_cpos(i)=i
381  ENDDO
382 !
383 ! MAXIMUM INITIAL FLUX
384 !
385  cprev=0.d0
386  DO ir=1,nelem
387  cprev=cprev+abs(flop1(ir))+abs(flop2(ir))+abs(flop3(ir))
388  ENDDO
389  IF(ncsize.GT.1) cprev=p_sum(cprev)
390  IF(testing) WRITE(lu,*) 'INITIAL SUM OF FLUXES=',cprev
391  cinit=cprev
392 !
393  niter = 0
394 777 CONTINUE
395  niter = niter + 1
396 !
397 ! COMPUTING DEMAND (T7) AND OFFER (T1)
398 !
399  CALL os('X=0 ',x=t7)
400  CALL os('X=0 ',x=t1)
401  IF(optpre.EQ.1) THEN
402  DO ir=1,remain
403  i=indic_cpos(ir)
404  i1=mesh%IKLE%I(i )
405  i2=mesh%IKLE%I(i +nelmax)
406  i3=mesh%IKLE%I(i+2*nelmax)
407 ! A PRIORI AVAILABLE VOLUMES
408  vol1=mesh%SURFAC%R(i)*ht%R(i1)*tiers
409  vol2=mesh%SURFAC%R(i)*ht%R(i2)*tiers
410  vol3=mesh%SURFAC%R(i)*ht%R(i3)*tiers
411 ! FLUXES LEAVING POINTS AGAIN
412  f1= flop1(i)-flop3(i)
413  f2=-flop1(i)+flop2(i)
414  f3=-flop2(i)+flop3(i)
415 ! DEMAND OR OFFER
416  IF(f1*dt.GT.vol1) THEN
417 ! POINT IN NEED OF EXTRA WATER
418  t7%R(i1)=t7%R(i1)+f1*dt-vol1
419  ELSE
420 ! POINT THAT CAN OFFER EXTRA WATER
421 ! BUT NOT MORE THAN ITS OWN VOLUME (AS WOULD BE THE CASE IF F1<0...)
422  t1%R(i1)=t1%R(i1)+min(vol1,vol1-f1*dt)
423  ENDIF
424  IF(f2*dt.GT.vol2) THEN
425  t7%R(i2)=t7%R(i2)+f2*dt-vol2
426  ELSE
427  t1%R(i2)=t1%R(i2)+min(vol2,vol2-f2*dt)
428  ENDIF
429  IF(f3*dt.GT.vol3) THEN
430  t7%R(i3)=t7%R(i3)+f3*dt-vol3
431  ELSE
432  t1%R(i3)=t1%R(i3)+min(vol3,vol3-f3*dt)
433  ENDIF
434  ENDDO
435  ELSEIF(optpre.EQ.2) THEN
436  DO ir=1,remain
437  i=indic_cpos(ir)
438  i1=mesh%IKLE%I(i )
439  i2=mesh%IKLE%I(i +nelmax)
440  i3=mesh%IKLE%I(i+2*nelmax)
441 ! A PRIORI AVAILABLE VOLUMES
442  vol1=mesh%SURFAC%R(i)*ht%R(i1)*tiers
443  vol2=mesh%SURFAC%R(i)*ht%R(i2)*tiers
444  vol3=mesh%SURFAC%R(i)*ht%R(i3)*tiers
445 ! FLUXES LEAVING POINTS AGAIN
446  f1= flop1(i)-flop3(i)
447  f2=-flop1(i)+flop2(i)
448  f3=-flop2(i)+flop3(i)
449 ! DEMAND AND OFFER
450  IF(f1.GT.0.d0) t7%R(i1)=t7%R(i1)+f1
451  IF(f2.GT.0.d0) t7%R(i2)=t7%R(i2)+f2
452  IF(f3.GT.0.d0) t7%R(i3)=t7%R(i3)+f3
453  t1%R(i1)=t1%R(i1)+vol1
454  t1%R(i2)=t1%R(i2)+vol2
455  t1%R(i3)=t1%R(i3)+vol3
456  ENDDO
457  ENDIF
458  IF(ncsize.GT.1) THEN
459  CALL parcom(t7,2,mesh)
460  CALL parcom(t1,2,mesh)
461  ENDIF
462 !
463 ! PREPARING VOLUMES AND LIMITATION FOR PREDICTOR
464 !
465  DO ir=1,remain
466 !
467  i=indic_cpos(ir)
468 !
469  i1=mesh%IKLE%I(i )
470  i2=mesh%IKLE%I(i +nelmax)
471  i3=mesh%IKLE%I(i+2*nelmax)
472 !
473 ! A PRIORI AVAILABLE VOLUMES FOR THIS ELEMENT
474 !
475  f1= flop1(i)-flop3(i)
476  f2=-flop1(i)+flop2(i)
477  f3=-flop2(i)+flop3(i)
478 !
479 ! PRELIMINARY DISTRIBUTION OF VOLUMES BETWEEN ELEMENTS,
480 ! ACCORDING TO DEMAND AND OFFER
481 !
482  IF(optpre.EQ.1) THEN
483  vol1=mesh%SURFAC%R(i)*ht%R(i1)*tiers
484  vol2=mesh%SURFAC%R(i)*ht%R(i2)*tiers
485  vol3=mesh%SURFAC%R(i)*ht%R(i3)*tiers
486  IF(f1*dt.GT.vol1) THEN
487 ! VOLUME TOO SMALL, TRYING TO INCREASE IT WITH GIFTS FROM OTHER
488 ! ELEMENTS
489  IF(t7%R(i1).GT.t1%R(i1)) THEN
490 ! MORE DEMAND THAN OFFER, NEED TO SHARE
491 ! Commas very important to have T1/T7 <1
492 ! before multiplication
493 ! ( )
494  vol1=vol1+(f1*dt-vol1)*(t1%R(i1)/t7%R(i1))
495  ELSE
496 ! MORE OFFER THAN DEMAND, THE POINT CAN HAVE THE REQUESTED VOLUME
497  vol1=f1*dt
498  ENDIF
499  ELSE
500 ! VOLUME LARGE ENOUGH, GIVING WATER TO OTHER ELEMENTS ?
501  IF(t1%R(i1).GT.t7%R(i1)) THEN
502 ! MORE OFFER THAN DEMAND, GIVING ENOUGH, BUT NOT ALL
503  vol1=vol1-min(vol1,vol1-f1*dt)*(t7%R(i1)/t1%R(i1))
504  ELSE
505 ! MORE DEMAND THAN OFFER, KEEPING ONLY WHAT IS NECESSARY
506  vol1=max(f1,0.d0)*dt
507  ENDIF
508  ENDIF
509  IF(f2*dt.GT.vol2) THEN
510  IF(t7%R(i2).GT.t1%R(i2)) THEN
511  vol2=vol2+(f2*dt-vol2)*(t1%R(i2)/t7%R(i2))
512  ELSE
513  vol2=f2*dt
514  ENDIF
515  ELSE
516  IF(t1%R(i2).GT.t7%R(i2)) THEN
517  vol2=vol2-min(vol2,vol2-f2*dt)*(t7%R(i2)/t1%R(i2))
518  ELSE
519  vol2=max(f2,0.d0)*dt
520  ENDIF
521  ENDIF
522  IF(f3*dt.GT.vol3) THEN
523  IF(t7%R(i3).GT.t1%R(i3)) THEN
524  vol3=vol3+(f3*dt-vol3)*(t1%R(i3)/t7%R(i3))
525  ELSE
526  vol3=f3*dt
527  ENDIF
528  ELSE
529  IF(t1%R(i3).GT.t7%R(i3)) THEN
530  vol3=vol3-min(vol3,vol3-f3*dt)*(t7%R(i3)/t1%R(i3))
531  ELSE
532  vol3=max(f3,0.d0)*dt
533  ENDIF
534  ENDIF
535  ELSEIF(optpre.EQ.2) THEN
536  IF(t7%R(i1).GT.1.d-30) THEN
537 ! ( THIS IS IMPORTANT
538  vol1=t1%R(i1)*(max(f1,0.d0)/t7%R(i1))
539  ELSE
540  vol1=mesh%SURFAC%R(i)*h%R(i1)*tiers
541  ENDIF
542  IF(t7%R(i2).GT.1.d-30) THEN
543  vol2=t1%R(i2)*(max(f2,0.d0)/t7%R(i2))
544  ELSE
545  vol2=mesh%SURFAC%R(i)*h%R(i2)*tiers
546  ENDIF
547  IF(t7%R(i3).GT.1.d-30) THEN
548  vol3=t1%R(i3)*(max(f3,0.d0)/t7%R(i3))
549  ELSE
550  vol3=mesh%SURFAC%R(i)*h%R(i3)*tiers
551  ENDIF
552  ENDIF
553 !
554 ! SAVING VOLUMES FOR CORRECTOR (ACTUALLY NOT USED BY PREDICTOR, THOUGH
555 ! DONE FOR IT, BUT IT GIVES THE LIMITATIONS...)
556 !
557  svol1(i)=vol1
558  svol2(i)=vol2
559  svol3(i)=vol3
560 !
561 ! LIMITATION OF FLUXES, FIRST IN TERMS OF LIMITED TIME-STEP
562 !
563  IF(f1*dt.GT.vol1) THEN
564  dt1=dt*(vol1/(f1*dt))
565  ELSE
566  dt1=dt
567  ENDIF
568  IF(f2*dt.GT.vol2) THEN
569  dt2=dt*(vol2/(f2*dt))
570  ELSE
571  dt2=dt
572  ENDIF
573  IF(f3*dt.GT.vol3) THEN
574  dt3=dt*(vol3/(f3*dt))
575  ELSE
576  dt3=dt
577  ENDIF
578 !
579 ! NOW LIMITED VOLUMES TRANSITING BETWEEN POINTS (1/DT MISSING)
580 ! A SEGMENT GETS THE STRONGEST LIMITATION OF ITS TWO POINTS
581 ! THIS WILL CREATE NO NEGATIVE VOLUME, AS IT COULD BE FEARED,
582 ! BECAUSE WE HAVE ONLY THE 1-TARGET CASE AND THE 2-TARGET CASE
583 ! THUS ALL FLUXES LEAVING OR ARRIVING TO A POINT HAVE THE SAME
584 ! SIGN OR ARE ZERO !
585 !
586  dtlim1(i)=min(dt1,dt2)
587  dtlim2(i)=min(dt2,dt3)
588  dtlim3(i)=min(dt3,dt1)
589 !
590  ENDDO
591 !
592 !
593 ! NOW SEQUENCE PREDICTOR-CORRECTOR
594 !
595 !
596 ! INITIALISING T3, FUTURE VALUE OF F BECAUSE POINTS THAT DO NOT RECEIVE
597 ! WATER WILL NOT BE TREATED
598 ! T4 IS THE EVOLUTION OF VOLUME OF WATER, HERE INITIALISED TO 0
599 ! T5 IS THE EVOLUTION OF MASSES OF TRACER, HERE INITIALISED TO 0
600 ! T6 IS THE INITIAL TRACER*DEPTH
601  CALL os('X=0 ',x=t4)
602  CALL os('X=0 ',x=t5)
603  DO i=1,f%DIM1
604  t6%R(i)=f%R(i)*ht%R(i)
605  ENDDO
606  DO i=1,f%DIM1
607  t3%R(i)=f%R(i)
608  ENDDO
609 !
610 ! COMPUTING MIN AND MAX FOR FINAL CLIPPING, THIS WILL ENSURE A GLOBAL
611 ! MONOTONICITY, THAT COULD OTHERWISE BE VIOLATED BY TRUNCATION ERRORS
612 ! THIS COULD BE DONE LOCALLY, BUT IT WOULD BE MORE EXPENSIVE
613 ! FOR LOCAL MIN AND MAX SEE CVTRVF.F
614 !
615  fmin=f%R(1)
616  fmax=f%R(1)
617  DO i=2,f%DIM1
618  fmin=min(fmin,f%R(i))
619  fmax=max(fmax,f%R(i))
620  ENDDO
621  IF(ncsize.GT.1) THEN
622  fmin=p_min(fmin)
623  fmax=p_max(fmax)
624  ENDIF
625 !
626 ! PREDICTOR
627 !
628  DO ir=1,remain
629 !
630  i=indic_cpos(ir)
631 !
632  i1=mesh%IKLE%I(i )
633  i2=mesh%IKLE%I(i +nelmax)
634  i3=mesh%IKLE%I(i+2*nelmax)
635 !
636  fp1=flop1(i)*dtlim1(i)
637  fp2=flop2(i)*dtlim2(i)
638  fp3=flop3(i)*dtlim3(i)
639 !
640 ! CORRESPONDING VARIATIONS OF VOLUMES OF POINTS (DT MISSING SO OK)
641 !
642  t4%R(i1)=t4%R(i1)-( fp1-fp3)
643  t4%R(i2)=t4%R(i2)-(-fp1+fp2)
644  t4%R(i3)=t4%R(i3)-(-fp2+fp3)
645 !
646 ! VARIATIONS OF MASSES ADDED AND REMOVED IN REDUCED FORM
647 !
648  t5%R(i1)=t5%R(i1)-( fp1-fp3)*f%R(i1)
649  t5%R(i2)=t5%R(i2)-(-fp1+fp2)*f%R(i2)
650  t5%R(i3)=t5%R(i3)-(-fp2+fp3)*f%R(i3)
651 !
652  fi1=-min(fp1,0.d0)*(f%R(i2)-f%R(i1))
653  & +max(fp3,0.d0)*(f%R(i3)-f%R(i1))
654  fi2=+max(fp1,0.d0)*(f%R(i1)-f%R(i2))
655  & -min(fp2,0.d0)*(f%R(i3)-f%R(i2))
656  fi3=+max(fp2,0.d0)*(f%R(i2)-f%R(i3))
657  & -min(fp3,0.d0)*(f%R(i1)-f%R(i3))
658 !
659 ! PSI LIMITATION
660 !
661  fitot=fi1+fi2+fi3
662 !
663  IF(fitot.GT.eps_flux) THEN
664 ! PSI REDUCTION
665  beta1=max(fi1,0.d0)
666  beta2=max(fi2,0.d0)
667  beta3=max(fi3,0.d0)
668  coef=fitot/(beta1+beta2+beta3)
669  fi1=beta1*coef
670  fi2=beta2*coef
671  fi3=beta3*coef
672  ELSEIF(fitot.LT.-eps_flux) THEN
673 ! PSI REDUCTION
674  beta1=min(fi1,0.d0)
675  beta2=min(fi2,0.d0)
676  beta3=min(fi3,0.d0)
677  coef=fitot/(beta1+beta2+beta3)
678  fi1=beta1*coef
679  fi2=beta2*coef
680  fi3=beta3*coef
681  ELSE
682 ! NO REDUCTION
683  ENDIF
684 !
685  t5%R(i1)=t5%R(i1)+fi1
686  t5%R(i2)=t5%R(i2)+fi2
687  t5%R(i3)=t5%R(i3)+fi3
688 !
689  ENDDO
690 !
691 ! ADDING THE EVOLUTIONS TO THE DEPTHS AND TRACERS
692 ! AFTER ASSEMBLY AT INTERFACES AND AFTER
693 ! CHANGING VOLUMES INTO DEPTHS.
694 !
695  IF(ncsize.GT.1) THEN
696  CALL parcom(t4,2,mesh)
697  CALL parcom(t5,2,mesh)
698  ENDIF
699  CALL os('X=XY ',x=t4,y=unsv2d)
700  CALL os('X=XY ',x=t5,y=unsv2d)
701 ! UPDATING DEPOTH AND TRACER
702  DO i=1,f%DIM1
703 ! ADDING INITIAL QUANTITY T6 AND VARIATION T5
704  t6%R(i)=t6%R(i)+t5%R(i)
705 ! NOW T5 USED TO STORE OLD DEPTH
706  t5%R(i)=ht%R(i)
707 ! NEW DEPTH
708  ht%R(i)=ht%R(i)+t4%R(i)
709  IF(ht%R(i).GT.1.d-15) THEN
710 ! NEW VALUE OF TRACER
711  t3%R(i)=t6%R(i)/ht%R(i)
712  ENDIF
713 ! TO COPE WITH TRUNCATION ERRORS AND AVOID NEGATIVE VALUES
714 ! IF HT NEGATIVE FOR OTHER REASONS IT WILL MAKE MASS ERRORS
715  ht%R(i)=max(0.d0,ht%R(i))
716 ! ENSURING A GLOBAL MONOTONICITY OF T3
717  t3%R(i)=min(fmax,max(fmin,t3%R(i)))
718  ENDDO
719 !
720 ! CORRECTOR
721 !
722  IF(nco_dist.GT.0) THEN
723 !
724  DO i=1,f%DIM1
725  t7%R(i)=0.d0
726  t1%R(i)=0.d0
727  ENDDO
728 !
729 ! EVALUATING OFFER (T1) AND DEMAND (T7)
730 !
731  DO ir=1,remain
732  i=indic_cpos(ir)
733 !
734  i1=mesh%IKLE%I(i )
735  i2=mesh%IKLE%I(i +nelmax)
736  i3=mesh%IKLE%I(i+2*nelmax)
737 ! LIMITED VOLUMES TRAVELLING BETWEEN POINTS
738  fp1=flop1(i)*dtlim1(i)
739  fp2=flop2(i)*dtlim2(i)
740  fp3=flop3(i)*dtlim3(i)
741 ! VOLUMES OF BASIC SOLUTION AT T(N+1)
742  vol1=svol1(i)-( fp1-fp3)
743  vol2=svol2(i)-(-fp1+fp2)
744  vol3=svol3(i)-(-fp2+fp3)
745  IF(vol1.LT.mesh%SURFAC%R(i)*ht%R(i1)*tiers) THEN
746  t7%R(i1)=t7%R(i1)+mesh%SURFAC%R(i)*ht%R(i1)*tiers-vol1
747  ELSE
748  t1%R(i1)=t1%R(i1)+vol1+min( fp1,0.d0)+min(-fp3,0.d0)
749  ENDIF
750  IF(vol2.LT.mesh%SURFAC%R(i)*ht%R(i2)*tiers) THEN
751  t7%R(i2)=t7%R(i2)+mesh%SURFAC%R(i)*ht%R(i2)*tiers-vol2
752  ELSE
753  t1%R(i2)=t1%R(i2)+vol2+min(-fp1,0.d0)+min( fp2,0.d0)
754  ENDIF
755  IF(vol3.LT.mesh%SURFAC%R(i)*ht%R(i3)*tiers) THEN
756  t7%R(i3)=t7%R(i3)+mesh%SURFAC%R(i)*ht%R(i3)*tiers-vol3
757  ELSE
758  t1%R(i3)=t1%R(i3)+vol3+min(-fp2,0.d0)+min( fp3,0.d0)
759  ENDIF
760  ENDDO
761 !
762  IF(ncsize.GT.1) THEN
763 ! GLOBAL OFFER (T1) AND DEMAND (T7)
764  CALL parcom(t1,2,mesh)
765  CALL parcom(t7,2,mesh)
766  ENDIF
767 !
768 ! VOLUMES THAT WILL BE USED FOR THE DERIVATIVE IN TIME
769 !
770  DO ir=1,remain
771 !
772  i=indic_cpos(ir)
773 !
774  i1=mesh%IKLE%I(i )
775  i2=mesh%IKLE%I(i +nelmax)
776  i3=mesh%IKLE%I(i+2*nelmax)
777 !
778 ! LIMITED VOLUMES BETWEEN POINTS
779 !
780  fp1=flop1(i)*dtlim1(i)
781  fp2=flop2(i)*dtlim2(i)
782  fp3=flop3(i)*dtlim3(i)
783 ! LOCAL VOLUMES AFTER PREDICTOR
784  vol1=svol1(i)-( fp1-fp3)
785  vol2=svol2(i)-(-fp1+fp2)
786  vol3=svol3(i)-(-fp2+fp3)
787 ! VOLUME1
788  IF(vol1.LT.mesh%SURFAC%R(i)*ht%R(i1)*tiers) THEN
789  IF(t7%R(i1).GT.t1%R(i1)) THEN
790 ! MORE DEMAND THAN OFFER, VOL1 GETS ONLY A SHARE
791  vol1=vol1+(mesh%SURFAC%R(i)*ht%R(i1)*tiers-vol1)
792  & *(t1%R(i1)/t7%R(i1))
793  ELSE
794 ! VOL1 GETS ALL
795  vol1=mesh%SURFAC%R(i)*ht%R(i1)*tiers
796  ENDIF
797  ELSE
798  IF(t1%R(i1).GT.t7%R(i1)) THEN
799 ! MORE OFFER THAN DEMAND, VOL1 GIVES A SHARE ONLY
800  vol1=vol1-(vol1+(min( fp1,0.d0)+min(-fp3,0.d0)))
801  & *(t7%R(i1)/t1%R(i1))
802  ELSE
803 ! MORE DEMAND THAN OFFER, VOL1 GIVES ALL IT CAN
804  vol1=-(min( fp1,0.d0)+min(-fp3,0.d0))
805  ENDIF
806  ENDIF
807 ! VOLUME 2
808  IF(vol2.LT.mesh%SURFAC%R(i)*ht%R(i2)*tiers) THEN
809  IF(t7%R(i2).GT.t1%R(i2)) THEN
810 ! MORE DEMAND THAN OFFER, VOL2 GETS ONLY A SHARE
811  vol2=vol2+(mesh%SURFAC%R(i)*ht%R(i2)*tiers-vol2)
812  & *(t1%R(i2)/t7%R(i2))
813  ELSE
814 ! VOL2 GETS ALL
815  vol2=mesh%SURFAC%R(i)*ht%R(i2)*tiers
816  ENDIF
817  ELSE
818  IF(t1%R(i2).GT.t7%R(i2)) THEN
819 ! MORE OFFER THAN DEMAND, VOL2 GIVES A SHARE ONLY
820  vol2=vol2-(vol2+(min(-fp1,0.d0)+min( fp2,0.d0)))
821  & *(t7%R(i2)/t1%R(i2))
822  ELSE
823 ! MORE DEMAND THAN OFFER, VOL1 GIVES ALL IT CAN
824  vol2=-(min(-fp1,0.d0)+min( fp2,0.d0))
825  ENDIF
826  ENDIF
827 ! VOLUME 3
828  IF(vol3.LT.mesh%SURFAC%R(i)*ht%R(i3)*tiers) THEN
829  IF(t7%R(i3).GT.t1%R(i3)) THEN
830 ! MORE DEMAND THAN OFFER, VOL1 GETS ONLY A SHARE
831  vol3=vol3+(mesh%SURFAC%R(i)*ht%R(i3)*tiers-vol3)
832  & *(t1%R(i3)/t7%R(i3))
833  ELSE
834 ! VOL3 GETS ALL
835  vol3=mesh%SURFAC%R(i)*ht%R(i3)*tiers
836  ENDIF
837  ELSE
838  IF(t1%R(i3).GT.t7%R(i3)) THEN
839 ! MORE OFFER THAN DEMAND, VOL3 GIVES A SHARE ONLY
840  vol3=vol3-(vol3+(min(-fp2,0.d0)+min( fp3,0.d0)))
841  & *(t7%R(i3)/t1%R(i3))
842  ELSE
843 ! MORE DEMAND THAN OFFER, VOL3 GIVES ALL IT CAN
844  vol3=-(min(-fp2,0.d0)+min( fp3,0.d0))
845  ENDIF
846  ENDIF
847  svol1(i)=vol1
848  svol2(i)=vol2
849  svol3(i)=vol3
850  ENDDO
851 !
852  DO n=1,nco_dist
853 !
854  DO i=1,f%DIM1
855 ! INITIAL QUANTITY
856  t6%R(i)=f%R(i)*ht%R(i)
857  ENDDO
858 !
859  IF(optadv.EQ.2) THEN
860 ! FOR SECOND ORDER, COMPUTING POSSIBLE MIN AND MAX
861 ! MIN IN T1 AND MAX IN T7
862  DO i=1,f%DIM1
863  t1%R(i)=f%R(i)
864  t7%R(i)=f%R(i)
865  ENDDO
866  DO ir=1,remain
867  i=indic_cpos(ir)
868  i1=mesh%IKLE%I(i )
869  i2=mesh%IKLE%I(i +nelmax)
870  i3=mesh%IKLE%I(i+2*nelmax)
871  localmin=min( f%R(i1), f%R(i2), f%R(i3),
872  & t3%R(i1),t3%R(i2),t3%R(i3))
873  localmax=max( f%R(i1), f%R(i2), f%R(i3),
874  & t3%R(i1),t3%R(i2),t3%R(i3))
875  t1%R(i1)=min(t1%R(i1),localmin)
876  t1%R(i2)=min(t1%R(i2),localmin)
877  t1%R(i3)=min(t1%R(i3),localmin)
878  t7%R(i1)=max(t7%R(i1),localmax)
879  t7%R(i2)=max(t7%R(i2),localmax)
880  t7%R(i3)=max(t7%R(i3),localmax)
881  ENDDO
882  IF(ncsize.GT.1) THEN
883 ! 4:MIN
884  CALL parcom(t1,4,mesh)
885 ! 3:MAX
886  CALL parcom(t7,3,mesh)
887  ENDIF
888  ENDIF
889 !
890  CALL os('X=0 ',x=t5)
891 !
892 ! NOW THE REAL CORRECTOR
893 !
894  IF(optadv.EQ.1) THEN
895 !
896 ! FIRST ORDER IN TIME
897 !
898  DO ir=1,remain
899 !
900  i=indic_cpos(ir)
901  i1=mesh%IKLE%I(i )
902  i2=mesh%IKLE%I(i +nelmax)
903  i3=mesh%IKLE%I(i+2*nelmax)
904 !
905 ! LIMITED VOLUMES BETWEEN POINTS
906 !
907  fp1=flop1(i)*dtlim1(i)
908  fp2=flop2(i)*dtlim2(i)
909  fp3=flop3(i)*dtlim3(i)
910 !
911  fi1=(t3%R(i1)-f%R(i1))*svol1(i)
912  fi2=(t3%R(i2)-f%R(i2))*svol2(i)
913  fi3=(t3%R(i3)-f%R(i3))*svol3(i)
914 !
915 ! ADDING THE DERIVATIVE THAT WILL BE REMOVED IN UPWIND FORM
916 ! THIS IS DONE ONLY FOR REMAINING ELEMENTS.
917 !
918  t5%R(i1)=t5%R(i1)+fi1
919  t5%R(i2)=t5%R(i2)+fi2
920  t5%R(i3)=t5%R(i3)+fi3
921 !
922 ! THEN FLUXES
923 !
924  fip1=-min(fp1,0.d0)*(f%R(i2)-f%R(i1))
925  & +max(fp3,0.d0)*(f%R(i3)-f%R(i1))
926  fip2=+max(fp1,0.d0)*(f%R(i1)-f%R(i2))
927  & -min(fp2,0.d0)*(f%R(i3)-f%R(i2))
928  fip3=+max(fp2,0.d0)*(f%R(i2)-f%R(i3))
929  & -min(fp3,0.d0)*(f%R(i1)-f%R(i3))
930 !
931 ! THIS EXTRA PSI REDUCTION IS NOT NECESSARY
932 ! BUT GIVES SLIGHTLY BETTER RESULTS
933  fitot=fip1+fip2+fip3
934  IF(fitot.GT.eps_flux) THEN
935 ! PSI REDUCTION
936  beta1=max(fip1,0.d0)
937  beta2=max(fip2,0.d0)
938  beta3=max(fip3,0.d0)
939  coef=fitot/(beta1+beta2+beta3)
940  fip1=beta1*coef
941  fip2=beta2*coef
942  fip3=beta3*coef
943  ELSEIF(fitot.LT.-eps_flux) THEN
944 ! PSI REDUCTION
945  beta1=min(fip1,0.d0)
946  beta2=min(fip2,0.d0)
947  beta3=min(fip3,0.d0)
948  coef=fitot/(beta1+beta2+beta3)
949  fip1=beta1*coef
950  fip2=beta2*coef
951  fip3=beta3*coef
952  ELSE
953 ! NO REDUCTION
954  ENDIF
955 !
956 ! ADDING TO FINAL CONTRIBUTIONS THAT WILL BE REDUCED AGAIN
957 !
958  fi1=-fi1+fip1
959  fi2=-fi2+fip2
960  fi3=-fi3+fip3
961 !
962 ! PSI LIMITATION
963 !
964  fitot=fi1+fi2+fi3
965 !
966  IF(fitot.GT.eps_flux) THEN
967 ! PSI REDUCTION
968  beta1=max(fi1,0.d0)
969  beta2=max(fi2,0.d0)
970  beta3=max(fi3,0.d0)
971  coef=fitot/(beta1+beta2+beta3)
972  fi1=beta1*coef
973  fi2=beta2*coef
974  fi3=beta3*coef
975  ELSEIF(fitot.LT.-eps_flux) THEN
976 ! PSI REDUCTION
977  beta1=min(fi1,0.d0)
978  beta2=min(fi2,0.d0)
979  beta3=min(fi3,0.d0)
980  coef=fitot/(beta1+beta2+beta3)
981  fi1=beta1*coef
982  fi2=beta2*coef
983  fi3=beta3*coef
984  ELSE
985 ! NO REDUCTION
986  ENDIF
987 !
988  t5%R(i1)=t5%R(i1)+fi1
989  t5%R(i2)=t5%R(i2)+fi2
990  t5%R(i3)=t5%R(i3)+fi3
991 !
992  ENDDO
993 !
994  ELSEIF(optadv.EQ.2) THEN
995 !
996 ! SECOND ORDER IN TIME
997 !
998  DO ir=1,remain
999 !
1000  i=indic_cpos(ir)
1001  i1=mesh%IKLE%I(i )
1002  i2=mesh%IKLE%I(i +nelmax)
1003  i3=mesh%IKLE%I(i+2*nelmax)
1004 !
1005 ! LIMITED VOLUMES BETWEEN POINTS
1006 !
1007  fp1=flop1(i)*dtlim1(i)
1008  fp2=flop2(i)*dtlim2(i)
1009  fp3=flop3(i)*dtlim3(i)
1010 !
1011  fi1=(f%R(i1)-t3%R(i1))*svol1(i)
1012  fi2=(f%R(i2)-t3%R(i2))*svol2(i)
1013  fi3=(f%R(i3)-t3%R(i3))*svol3(i)
1014 !
1015 ! ADDING THE DERIVATIVE THAT WILL BE REMOVED IN UPWIND FORM
1016 !
1017  t5%R(i1)=t5%R(i1)-fi1
1018  t5%R(i2)=t5%R(i2)-fi2
1019  t5%R(i3)=t5%R(i3)-fi3
1020 !
1021 ! THEN FLUXES
1022 !
1023  vold1=max(0.d0,svol1(i)+min(fp1,0.d0)-max(fp3,0.d0))
1024  vold2=max(0.d0,svol2(i)-max(fp1,0.d0)+min(fp2,0.d0))
1025  vold3=max(0.d0,svol3(i)-max(fp2,0.d0)+min(fp3,0.d0))
1026  a1=2.d0*vold1/max(1.d-30, max(fp1,0.d0)-min(fp3,0.d0))
1027  a2=2.d0*vold2/max(1.d-30,-min(fp1,0.d0)+max(fp2,0.d0))
1028  a3=2.d0*vold3/max(1.d-30,-min(fp2,0.d0)+max(fp3,0.d0))
1029  fs1=min(t3%R(i1),f%R(i1)+a1*(f%R(i1)-t1%R(i1)))
1030  fs1=max(fs1 ,f%R(i1)+a1*(f%R(i1)-t7%R(i1)))
1031  fs2=min(t3%R(i2),f%R(i2)+a2*(f%R(i2)-t1%R(i2)))
1032  fs2=max(fs2 ,f%R(i2)+a2*(f%R(i2)-t7%R(i2)))
1033  fs3=min(t3%R(i3),f%R(i3)+a3*(f%R(i3)-t1%R(i3)))
1034  fs3=max(fs3 ,f%R(i3)+a3*(f%R(i3)-t7%R(i3)))
1035 !
1036  fip1=0.5d0*(-min(fp1,0.d0)*(fs2-f%R(i1)+f%R(i2)-f%R(i1))
1037  & +max(fp3,0.d0)*(fs3-f%R(i1)+f%R(i3)-f%R(i1))
1038  & -max(fp1,0.d0)*(fs1-f%R(i1))
1039  & +min(fp3,0.d0)*(fs1-f%R(i1)))
1040  fip2=0.5d0*(+max(fp1,0.d0)*(fs1-f%R(i2)+f%R(i1)-f%R(i2))
1041  & -min(fp2,0.d0)*(fs3-f%R(i2)+f%R(i3)-f%R(i2))
1042  & +min(fp1,0.d0)*(fs2-f%R(i2))
1043  & -max(fp2,0.d0)*(fs2-f%R(i2)))
1044  fip3=0.5d0*(+max(fp2,0.d0)*(fs2-f%R(i3)+f%R(i2)-f%R(i3))
1045  & -min(fp3,0.d0)*(fs1-f%R(i3)+f%R(i1)-f%R(i3))
1046  & +min(fp2,0.d0)*(fs3-f%R(i3))
1047  & -max(fp3,0.d0)*(fs3-f%R(i3)))
1048 !
1049 ! GO TO 2000
1050 ! THIS EXTRA PSI REDUCTION IS NOT NECESSARY
1051 ! BUT GIVES SLIGHTLY BETTER RESULTS
1052  fitot=fip1+fip2+fip3
1053  IF(fitot.GT.eps_flux) THEN
1054 ! PSI REDUCTION
1055  beta1=max(fip1,0.d0)
1056  beta2=max(fip2,0.d0)
1057  beta3=max(fip3,0.d0)
1058  coef=fitot/(beta1+beta2+beta3)
1059  fip1=beta1*coef
1060  fip2=beta2*coef
1061  fip3=beta3*coef
1062  ELSEIF(fitot.LT.-eps_flux) THEN
1063 ! PSI REDUCTION
1064  beta1=min(fip1,0.d0)
1065  beta2=min(fip2,0.d0)
1066  beta3=min(fip3,0.d0)
1067  coef=fitot/(beta1+beta2+beta3)
1068  fip1=beta1*coef
1069  fip2=beta2*coef
1070  fip3=beta3*coef
1071  ELSE
1072 ! NO REDUCTION
1073  ENDIF
1074 !2000 CONTINUE
1075 !
1076 ! ADDING TO FINAL CONTRIBUTIONS THAT WILL BE REDUCED AGAIN
1077 !
1078  fi1=fi1+fip1
1079  fi2=fi2+fip2
1080  fi3=fi3+fip3
1081 !
1082 ! PSI LIMITATION
1083 !
1084  fitot=fi1+fi2+fi3
1085 !
1086  IF(fitot.GT.eps_flux) THEN
1087 ! PSI REDUCTION
1088  beta1=max(fi1,0.d0)
1089  beta2=max(fi2,0.d0)
1090  beta3=max(fi3,0.d0)
1091  coef=fitot/(beta1+beta2+beta3)
1092  fi1=beta1*coef
1093  fi2=beta2*coef
1094  fi3=beta3*coef
1095  ELSEIF(fitot.LT.-eps_flux) THEN
1096 ! PSI REDUCTION
1097  beta1=min(fi1,0.d0)
1098  beta2=min(fi2,0.d0)
1099  beta3=min(fi3,0.d0)
1100  coef=fitot/(beta1+beta2+beta3)
1101  fi1=beta1*coef
1102  fi2=beta2*coef
1103  fi3=beta3*coef
1104  ELSE
1105 ! NO REDUCTION
1106  ENDIF
1107 !
1108  t5%R(i1)=t5%R(i1)+fi1
1109  t5%R(i2)=t5%R(i2)+fi2
1110  t5%R(i3)=t5%R(i3)+fi3
1111 !
1112  ENDDO
1113 !
1114  ELSE
1115  WRITE(lu,*) 'UNKNOWN OPTION IN CVTRVF_ERIA: ',optadv
1116  CALL plante(1)
1117  stop
1118  ENDIF
1119 !
1120 ! ADDING THE EVOLUTIONS TO THE TRACERS
1121 ! AFTER ASSEMBLY AT INTERFACES AND AFTER
1122 ! CHANGING VOLUMES INTO DEPTHS.
1123 !
1124  IF(ncsize.GT.1) CALL parcom(t5,2,mesh)
1125  CALL os('X=XY ',x=t5,y=unsv2d)
1126 ! NEW AVERAGE VALUE OF TRACER
1127  DO i=1,f%DIM1
1128  IF(ht%R(i).GT.1.d-15) THEN
1129  t3%R(i)=(t6%R(i)+t5%R(i))/ht%R(i)
1130 ! ENSURING A GLOBAL MONOTONICITY
1131  t3%R(i)=min(fmax,max(fmin,t3%R(i)))
1132  ENDIF
1133  ENDDO
1134 !
1135 ! END OF THE LOOP OF CORRECTIONS
1136 !
1137  ENDDO
1138  ENDIF
1139 !
1140 ! SETTING THE FINAL VALUE OF THE TRACER FOR THIS SUB-ITERATION
1141  DO i=1,f%DIM1
1142  f%R(i)=t3%R(i)
1143  ENDDO
1144 !
1145 ! IF REMAINING FLUXES, THE ELEMENT IS KEPT IN THE LIST
1146  newremain=0
1147  c=0.d0
1148 !
1149  DO ir=1,remain
1150  i=indic_cpos(ir)
1151  IF(dtlim1(i).EQ.dt.AND.dtlim2(i).EQ.dt.AND.
1152  & dtlim3(i).EQ.dt) THEN
1153  flop1(i)=0.d0
1154  flop2(i)=0.d0
1155  flop3(i)=0.d0
1156  ELSE
1157  newremain=newremain+1
1158 ! BEFORE NEWREMAIN: FOR NEXT ITERATION
1159 ! AFTER NEWREMAIN: STILL VALID FOR NEXT ITERATION
1160  indic_cpos(newremain)=i
1161  flop1(i)=flop1(i)*(1.d0-dtlim1(i)*surdt)
1162  flop2(i)=flop2(i)*(1.d0-dtlim2(i)*surdt)
1163  flop3(i)=flop3(i)*(1.d0-dtlim3(i)*surdt)
1164  c=c+abs(flop1(i))+abs(flop2(i))+abs(flop3(i))
1165  ENDIF
1166  ENDDO
1167 !
1168  IF(ncsize.GT.1) c=p_sum(c)
1169  IF(testing) WRITE(lu,*) 'FLUX NON PRIS EN COMPTE=',c
1170 !
1171  remain=newremain
1172 !
1173  IF(c.NE.cprev.AND.abs(c-cprev).GT.cinit*1.d-9
1174  & .AND.c.NE.0.d0) THEN
1175  cprev=c
1176  IF(niter.LT.nitmax) GO TO 777
1177  ENDIF
1178 !
1179 ! ADDING THE NEGATIVE SOURCES
1180 !
1181  IF(yasmh) THEN
1182  IF(optsou.EQ.1) THEN
1183  DO i=1,npoin
1184  IF(smh%R(i).LT.0.d0) THEN
1185  ht%R(i)=ht%R(i)+dt*smh%R(i)
1186  f%R(i)=f%R(i)+dt/max(ht%R(i),1.d-4)*smh%R(i)*fscexp%R(i)
1187  ENDIF
1188  ENDDO
1189  ELSEIF(optsou.EQ.2) THEN
1190  DO i=1,npoin
1191  IF(smh%R(i).LT.0.d0) THEN
1192  ht%R(i)=ht%R(i)+dt*smh%R(i)*unsv2d%R(i)
1193  f%R(i)=f%R(i)+dt/max(ht%R(i),1.d-4)*
1194  & unsv2d%R(i)*smh%R(i)*fscexp%R(i)
1195  ENDIF
1196  ENDDO
1197  ENDIF
1198  ENDIF
1199 !
1200 ! RAIN-EVAPORATION: RAIN DONE ABOVE, NOW EVAPORATION
1201 !
1202  IF(rain) THEN
1203  DO i=1,npoin
1204  c=min(pluie%R(i),0.d0)
1205 ! POSITIVITY NOT TESTED HERE, WOULD REQUIRE C=MAX(C,-HT%R(I)/DT)
1206 ! BUT THEN MASS-BALANCE WOULD NOT BE CORRECT,
1207  ht%R(i)=ht%R(i)+c*dt
1208 ! MONOTONICITY NON OBEYED HERE OF COURSE
1209 ! VALUE IN VAPOR
1210 ! F%R(I)=F%R(I)+(0.D0-F%R(I))*((C*DT)/MAX(HT%R(I),1.D-4))
1211  f%R(i)=f%R(i)*(1.d0-((c*dt)/max(ht%R(i),1.d-4)))
1212  ENDDO
1213  ENDIF
1214 !
1215 ! BOUNDARY FLUXES : ADDING THE EXITING (POSITIVE) FLUXES
1216 ! WITH A POSSIBLE LIMITATION
1217 !
1218  DO iptfr=1,nptfr
1219  i=nbor(iptfr)
1220 ! T2 = // ASSEMBLED FLBOR
1221  hfl1=dt*unsv2d%R(i)*max(t2%R(i),0.d0)
1222  tet=1.d0
1223  IF(hfl1.GT.ht%R(i)) tet=ht%R(i)/hfl1
1224 ! MAX IS ONLY TO PREVENT TRUNCATION ERROR
1225  ht%R(i)=max(ht%R(i)-hfl1*tet,0.d0)
1226 ! LIMITATION OF FLBOR (MUST HAVE BEEN DONE ALREADY
1227 ! IN POSITIVE_DEPTHS)
1228 ! FLBOR%R(IPTFR)=FLBOR%R(IPTFR)*TET
1229  IF(limtra(iptfr).EQ.kdir) THEN
1230  f%R(i)=f%R(i)-hfl1*tet/max(ht%R(i),1.d-4)*
1231  & (fbor%R(iptfr)-f%R(i))
1232  flbortra%R(iptfr)=flbor%R(iptfr)*fbor%R(iptfr)
1233  ELSEIF(limtra(iptfr).EQ.kddl) THEN
1234  flbortra%R(iptfr)=flbor%R(iptfr)*f%R(i)
1235  ENDIF
1236  ENDDO
1237 !
1238  IF(testing) THEN
1239  c=0.d0
1240  DO i=1,npoin
1241  c=c+(ht%R(i)-h%R(i))**2
1242  ENDDO
1243 ! FAUX MAIS PAS GRAVE SI 0.
1244  IF(ncsize.GT.1) c=p_sum(c)
1245  WRITE(lu,*) 'DIFFERENCE ENTRE H ET HT =',c
1246 !
1247  c=1.d99
1248  DO i=1,npoin
1249  c=min(c,f%R(i))
1250  ENDDO
1251  IF(ncsize.GT.1) c=p_min(c)
1252  WRITE(lu,*) 'APRES TRAITEMENT TRACEUR MIN=',c
1253  c=-1.d99
1254  DO i=1,npoin
1255  c=max(c,f%R(i))
1256  ENDDO
1257  IF(ncsize.GT.1) c=p_max(c)
1258  WRITE(lu,*) 'APRES TRAITEMENT TRACEUR MAX=',c
1259  ENDIF
1260 !
1261 !-----------------------------------------------------------------------
1262 !
1263 ! SOURCE TERMS
1264 !
1265  IF(yasmi) THEN
1266 !
1267 ! IMPLICIT AND EXPLICIT SOURCE TERM
1268 !
1269  IF(iopt2.EQ.0) THEN
1270  DO i = 1,mesh%NPOIN
1271  f%R(i)=(f%R(i)+dt*sm%R(i))/
1272  & (1.d0-dt*smi%R(i)/max(h%R(i),1.d-15))
1273 ! COULD BE DONE LIKE THIS...
1274 ! F%R(I)=H%R(I)*(F%R(I)+DT*SM%R(I))/(H%R(I)-DT*SMI%R(I))
1275  ENDDO
1276  ELSEIF(iopt2.EQ.1) THEN
1277 ! HERE WE ASSUME THAT SMI WILL PREVENT A DIVISION BY ZERO
1278 ! THIS IS THE CASE WITH SETTLING VELOCITY IN SISYPHE
1279  DO i = 1,mesh%NPOIN
1280  f%R(i)=(f%R(i)*ht%R(i)+dt*sm%R(i)*h%R(i))/
1281  & (h%R(i)-dt*smi%R(i))
1282  ENDDO
1283  ENDIF
1284 !
1285  ELSE
1286 !
1287 ! EXPLICIT SOURCE TERM ONLY (AND IOPT2=1 NOT TREATED !!!)
1288 !
1289  DO i = 1,mesh%NPOIN
1290  f%R(i) = f%R(i)+dt*sm%R(i)
1291  ENDDO
1292 !
1293  ENDIF
1294 !
1295 !-----------------------------------------------------------------------
1296 !
1297  IF(entet) THEN
1298  WRITE(lu,102) niter
1299  ENDIF
1300 !
1301  IF(niter.EQ.nitmax) THEN
1302  WRITE(lu,103) niter
1303  ENDIF
1304 !
1305 102 FORMAT(' CVTRVF_ERIA (SCHEME ERIA, 15): ',1i3,' ITERATIONS')
1306 103 FORMAT(' CVTRVF_ERIA (SCHEME ERIA, 15): ',1i3,' ITERATIONS',
1307  & ' = MAXIMUM',
1308  & /,'INCREASE MAXIMUM NUMBER OF ITERATIONS FOR ADVECTION SCHEMES')
1309 !
1310 !-----------------------------------------------------------------------
1311 !
1312  RETURN
1313  END
subroutine parcom2_seg(X1, X2, X3, NSEG, NPLAN, ICOM, IAN, MESH, OPT, IELM)
Definition: parcom2_seg.f:7
subroutine cvtrvf_eria(F, FN, FSCEXP, H, HN, HPROP, UDEL, VDEL, DM1, ZCONV, SOLSYS, SM, SMH, YASMH, SMI, YASMI, FBOR, MASKTR, MESH, T1, T2, T3, T4, T5, T6, T7, HT, DT, ENTET, MSK, MASKEL, OPTSOU, LIMTRA, KDIR, KDDL, NPTFR, FLBOR, YAFLBOR, UNSV2D, IOPT, FLBORTRA, NBOR, RAIN, PLUIE, TRAIN, NITMAX, NCO_DIST, OPTADV)
Definition: cvtrvf_eria.f:12
subroutine cpstvc(X, Y)
Definition: cpstvc.f:7
subroutine vector(VEC, OP, FORMUL, IELM1, XMUL, F, G, H, U, V, W, MESH, MSK, MASKEL, LEGO, ASSPAR)
Definition: vector.f:7
subroutine osdb(OP, X, Y, Z, C, MESH)
Definition: osdb.f:7
subroutine flux_ef_vf(FLOW, PHIEL, NSEG, NELEM, NELMAX, ELTSEG, ORISEG, IKLE, INIFLO, IOPT, FN, YAFLULIM, FLULIM, YAFLULIMEBE, FLULIMEBE)
Definition: flux_ef_vf.f:8
subroutine os(OP, X, Y, Z, C, IOPT, INFINI, ZERO)
Definition: os.f:7
subroutine parcom(X, ICOM, MESH)
Definition: parcom.f:7
integer, dimension(:), allocatable indic_cpos
Definition: bief.f:3