SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
mode_splines.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! ######spl
7 !-------------------------------------------------------------------------------
8 !! MODIFICATIONS
9 !! -------------
10 !!
11 !! J.Escobar 06/2013 for REAL4/8 add EPSILON management
12 !!
13 !-------------------------------------------------------------------------------
14 USE modi_abor1_sfx
15 USE modd_splines
16 USE yomhook ,ONLY : lhook, dr_hook
17 USE parkind1 ,ONLY : jprb
18 USE modd_surf_par , ONLY : xsurf_huge , xsurf_tiny
19 !
20 INTERFACE sscopy
21  MODULE PROCEDURE sscopy_1
22  MODULE PROCEDURE sscopy_2
23 END INTERFACE
24 INTERFACE mxidml
25  MODULE PROCEDURE mxidml
26 END INTERFACE
27 INTERFACE mtxaxm
28  MODULE PROCEDURE mtxaxm
29 END INTERFACE
30 INTERFACE mxmspl
31  MODULE PROCEDURE mxmspl_1
32  MODULE PROCEDURE mxmspl_2
33  MODULE PROCEDURE mxmspl_3
34 END INTERFACE
35 INTERFACE smxinv
36  MODULE PROCEDURE smxinv
37 END INTERFACE
38 !génération de matrices
39 INTERFACE splie
40  MODULE PROCEDURE splie
41 END INTERFACE
42 INTERFACE splk
43  MODULE PROCEDURE splk_1
44  MODULE PROCEDURE splk_2
45 END INTERFACE
46 INTERFACE splbfin
47  MODULE PROCEDURE splbfin
48 END INTERFACE
49 INTERFACE splt
50  MODULE PROCEDURE splt_1
51  MODULE PROCEDURE splt_2
52 END INTERFACE
53 INTERFACE sple
54  MODULE PROCEDURE sple
55 END INTERFACE
56 INTERFACE splb2e1
57  MODULE PROCEDURE splb2e1
58 END INTERFACE
59 INTERFACE splb2e
60  MODULE PROCEDURE splb2e
61 END INTERFACE
62 INTERFACE tred2
63  MODULE PROCEDURE tred2
64 END INTERFACE
65 INTERFACE tql2_2
66  MODULE PROCEDURE tql2_2
67 END INTERFACE
68 INTERFACE eisrs1
69  MODULE PROCEDURE eisrs1
70 END INTERFACE
71 INTERFACE splv
72  MODULE PROCEDURE splv
73 END INTERFACE
74 INTERFACE spls2vi
75  MODULE PROCEDURE spls2vi
76 END INTERFACE
77 INTERFACE splbvm
78  MODULE PROCEDURE splbvm
79 END INTERFACE
80 INTERFACE spls2v
81  MODULE PROCEDURE spls2v
82 END INTERFACE
83 INTERFACE splds2v
84  MODULE PROCEDURE splds2v
85 END INTERFACE
86 INTERFACE splps2v
87  MODULE PROCEDURE splps2v
88 END INTERFACE
89 INTERFACE splri
90  MODULE PROCEDURE splri
91 END INTERFACE
92 INTERFACE splrs
93  MODULE PROCEDURE splrs
94 END INTERFACE
95 INTERFACE spldrs
96  MODULE PROCEDURE spldrs
97 END INTERFACE
98 INTERFACE splpr
99  MODULE PROCEDURE splpr
100 END INTERFACE
101 INTERFACE spldv
102  MODULE PROCEDURE spldv
103 END INTERFACE
104 INTERFACE spld2v
105  MODULE PROCEDURE spld2v
106 END INTERFACE
107 INTERFACE splpv
108  MODULE PROCEDURE splpv
109 END INTERFACE
110 INTERFACE splp
111  MODULE PROCEDURE splp
112 END INTERFACE
113 INTERFACE spltt
114  MODULE PROCEDURE spltt
115 END INTERFACE
116 INTERFACE splr
117  MODULE PROCEDURE splr_1
118  MODULE PROCEDURE splr_2
119 END INTERFACE
120 INTERFACE splu
121  MODULE PROCEDURE splu
122 END INTERFACE
123 INTERFACE splw
124  MODULE PROCEDURE splw
125 END INTERFACE
126 INTERFACE splvpq
127  MODULE PROCEDURE splvpq
128 END INTERFACE
129 INTERFACE splc
130  MODULE PROCEDURE splc
131 END INTERFACE
132 INTERFACE splm
133  MODULE PROCEDURE splm
134 END INTERFACE
135 INTERFACE sp0nop
136  MODULE PROCEDURE sp0nop
137 END INTERFACE
138 INTERFACE sp0cvq
139  MODULE PROCEDURE sp0cvq
140 END INTERFACE
141 INTERFACE splbsd
142  MODULE PROCEDURE splbsd
143 END INTERFACE
144 INTERFACE splbsel
145  MODULE PROCEDURE splbsel
146 END INTERFACE
147 INTERFACE splb2c
148  MODULE PROCEDURE splb2c
149 END INTERFACE
150 
151  CONTAINS
152 
153 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
154 
155 !COPIE D'UNE MATRICE DANS UNE AUTRE
156 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
157 !1. copie de matrices potentiellement de tailles différentes
158 !SPLR
159 SUBROUTINE sscopy_1(A,B,IA,IB)
160 !
161 IMPLICIT NONE
162 
163 REAL, DIMENSION(:), INTENT(IN) :: a
164 INTEGER, INTENT(IN) :: ia
165 INTEGER, INTENT(IN) :: ib
166 REAL, DIMENSION(:), INTENT(OUT) :: b
167 
168 INTEGER :: i, j, k
169 REAL(KIND=JPRB) :: zhook_handle
170 
171 IF (lhook) CALL dr_hook('MODE_SPLINES:SSCOPY_1',0,zhook_handle)
172 j = ib
173 k = ia
174 DO i=1,SIZE(a)
175  b(j) = a(k)
176  j = j + ib
177  k = k + ia
178 ENDDO
179 IF (lhook) CALL dr_hook('MODE_SPLINES:SSCOPY_1',1,zhook_handle)
180 
181 END SUBROUTINE sscopy_1
182 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
183 !1. copie de matrices potentiellement de tailles différentes
184 SUBROUTINE sscopy_2(A,B,IA,IB)
185 !
186 IMPLICIT NONE
187 
188 REAL, DIMENSION(:,:), INTENT(IN) :: a
189 INTEGER, INTENT(IN) :: ia
190 INTEGER, INTENT(IN) :: ib
191 REAL, DIMENSION(:,:), INTENT(OUT) :: b
192 
193 REAL,DIMENSION(SIZE(A,1)*SIZE(A,2)) :: a1
194 REAL,DIMENSION(SIZE(B,1)*SIZE(B,2)) :: b1
195 
196 INTEGER :: n
197 INTEGER :: i, j, k
198 REAL(KIND=JPRB) :: zhook_handle
199 
200 IF (lhook) CALL dr_hook('MODE_SPLINES:SSCOPY_2',0,zhook_handle)
201 n=SIZE(a,1)*SIZE(a,2)
202 
203 DO j=1,SIZE(a,2)
204  a1((j-1)*SIZE(a,1)+1:j*SIZE(a,1))=a(:,j)
205 ENDDO
206 
207 j = ib
208 k = ia
209 DO i=1,n-1
210  b1(j) = a1(k)
211  j = j + ib
212  k = k + ia
213 ENDDO
214 
215 DO j=1,SIZE(b,2)
216  b(:,j)=b1((j-1)*SIZE(b,1)+1:j*SIZE(b,1))
217 ENDDO
218 IF (lhook) CALL dr_hook('MODE_SPLINES:SSCOPY_2',1,zhook_handle)
219 
220 END SUBROUTINE sscopy_2
221 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
222 
223 !OPERATIONS SUR LES MATRICES
224 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
225 !2. A(I) B(I*J) R(I*J) R(:,K)=B(:,K)/A(:)
226 SUBROUTINE mxidml(A,B,R)
227 !SPLTT, SPLR
228 IMPLICIT NONE
229 
230 REAL, DIMENSION(:), INTENT(IN) :: a
231 REAL, DIMENSION(:,:), INTENT(IN) :: b
232 REAL, DIMENSION(:,:), INTENT(OUT):: r
233 
234 INTEGER :: k
235 REAL(KIND=JPRB) :: zhook_handle
236 
237 IF (lhook) CALL dr_hook('MODE_SPLINES:MXIDML',0,zhook_handle)
238 IF (SIZE(b,1).EQ.0 .OR. SIZE(b,2).EQ.0 .AND. lhook) &
239  CALL dr_hook('MODE_SPLINES:MXIDML',1,zhook_handle)
240 IF (SIZE(b,1).EQ.0 .OR. SIZE(b,2).EQ.0) RETURN
241 
242 DO k=1,SIZE(b,2)
243  r(:,k)=b(:,k)/a(:)
244 ENDDO
245 IF (lhook) CALL dr_hook('MODE_SPLINES:MXIDML',1,zhook_handle)
246 
247 END SUBROUTINE mxidml
248 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
249 !3. produit bizarre de matrices
250 SUBROUTINE mtxaxm(A,B,R)
251 !SPLR,SPLU,SPLVPQ
252 IMPLICIT NONE
253 
254 REAL, DIMENSION(:,:),INTENT(IN) :: a
255 REAL, DIMENSION(:,:),INTENT(IN) :: b
256 REAL, DIMENSION(:,:),INTENT(OUT)::r
257 
258 INTEGER :: i,j,k, l
259 REAL :: rij
260 REAL(KIND=JPRB) :: zhook_handle
261 
262 IF (lhook) CALL dr_hook('MODE_SPLINES:MTXAXM',0,zhook_handle)
263 r(:,:)=0.
264 DO i=1,SIZE(a,2)
265  DO j=1,SIZE(a,1)
266  rij=0.
267  DO k=1,SIZE(a,1)
268  rij=rij+b(j,k)*a(k,i)
269  ENDDO
270  DO l=1,i
271  r(l,i)=r(l,i)+rij*a(j,l)
272  r(i,l)=r(l,i)
273  ENDDO
274  ENDDO
275 ENDDO
276 IF (lhook) CALL dr_hook('MODE_SPLINES:MTXAXM',1,zhook_handle)
277 
278 END SUBROUTINE mtxaxm
279 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
280 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
281 !4. produit simple de matrices (mettre les deux dans la même interface)
282 SUBROUTINE mxmspl_1(A,B,R)
283 !SPLE, SPLC, SPLTT, SPLR, SPLW, SPLVPQ
284 IMPLICIT NONE
285 
286 REAL, DIMENSION(:,:),INTENT(IN) :: a
287 REAL, DIMENSION(:,:),INTENT(IN) :: b
288 REAL, DIMENSION(:,:),INTENT(OUT)::r
289 
290 INTEGER :: i,j,k
291 REAL(KIND=JPRB) :: zhook_handle
292 
293 IF (lhook) CALL dr_hook('MODE_SPLINES:MXMSPL_1',0,zhook_handle)
294 r(:,:)=0.
295 
296 DO i=1,SIZE(a,1)
297  DO j=1,SIZE(b,2)
298  DO k=1,SIZE(a,2)
299  r(i,j)=r(i,j)+a(i,k)*b(k,j)
300  ENDDO
301  ENDDO
302 ENDDO
303 IF (lhook) CALL dr_hook('MODE_SPLINES:MXMSPL_1',1,zhook_handle)
304 
305 END SUBROUTINE mxmspl_1
306 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
307 !4. produit simple de matrices 2
308 SUBROUTINE mxmspl_2(A,B,R)
309 !
310 IMPLICIT NONE
311 
312 REAL, DIMENSION(:,:),INTENT(IN) :: a
313 REAL, DIMENSION(:),INTENT(IN) :: b
314 REAL, DIMENSION(:),INTENT(OUT)::r
315 
316 INTEGER :: i,j
317 REAL(KIND=JPRB) :: zhook_handle
318 
319 IF (lhook) CALL dr_hook('MODE_SPLINES:MXMSPL_2',0,zhook_handle)
320 r(:)=0.
321 
322 DO i=1,SIZE(a,1)
323  DO j=1,SIZE(a,2)
324  r(i)=r(i)+a(i,j)*b(j)
325  ENDDO
326 ENDDO
327 IF (lhook) CALL dr_hook('MODE_SPLINES:MXMSPL_2',1,zhook_handle)
328 
329 END SUBROUTINE mxmspl_2
330 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
331 !4. produit simple de matrices 3
332 SUBROUTINE mxmspl_3(A,B,RES)
333 !
334 IMPLICIT NONE
335 
336 REAL, DIMENSION(:),INTENT(IN) :: a
337 REAL, DIMENSION(:),INTENT(IN) :: b
338 REAL,INTENT(OUT)::res
339 
340 INTEGER :: i
341 REAL(KIND=JPRB) :: zhook_handle
342 
343 IF (lhook) CALL dr_hook('MODE_SPLINES:MXMSPL_3',0,zhook_handle)
344 res=0.
345 
346 DO i=1,SIZE(a)
347  res=res+a(i)*b(i)
348 ENDDO
349 IF (lhook) CALL dr_hook('MODE_SPLINES:MXMSPL_3',1,zhook_handle)
350 
351 END SUBROUTINE mxmspl_3
352 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
353 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
354 !5. inversion de la matrice A.
355 SUBROUTINE smxinv(A,IREP)
356 !SPLTT
357 IMPLICIT NONE
358 
359 REAL, DIMENSION(:,:), INTENT(INOUT) :: a
360 INTEGER, INTENT(OUT) :: irep
361 
362 REAL, DIMENSION(SIZE(A,1)*SIZE(A,2)) :: a2
363 INTEGER, DIMENSION(SIZE(A,1)) :: index
364 REAL, DIMENSION(SIZE(A,1)) :: ri
365 INTEGER :: n, np, np1, i, j, jj, k, l, kk, kj, jl
366 INTEGER :: ij0, ji0, ij, ji
367 REAL :: pivot, elm
368 REAL(KIND=JPRB) :: zhook_handle
369 
370 IF (lhook) CALL dr_hook('MODE_SPLINES:SMXINV',0,zhook_handle)
371 irep=0
372 n=SIZE(a,1)
373 np1=n+1
374 
375 index(:)=1
376 
377 DO j=1,n
378  !les colonnes sont à la suite
379  a2((j-1)*n+1:j*n)=a(:,j)
380 ENDDO
381 
382 DO i=1,n
383  !find pivot
384  pivot=0.
385  jj=1
386  !dans la diagonale, on retient le plus grand élément
387  DO j=1,n
388  IF(index(j).NE.0) THEN
389  elm=abs(a2(jj))
390  IF (elm.GT.pivot) THEN
391  pivot=elm
392  k=j !numéro de la ligne / colonne
393  !numéro de l'élément dans A2
394  kk=jj
395  ENDIF
396  ENDIF
397  jj=jj+np1
398  ENDDO
399  index(k)=0
400  IF (pivot.EQ.0.) THEN
401  irep=-1
402  IF (lhook) CALL dr_hook('MODE_SPLINES:SMXINV',1,zhook_handle)
403  RETURN
404  ENDIF
405  pivot=-a2(kk)
406  !elimination
407  kj=k
408  np=n
409  DO j=1,n
410  !KJ=K, KJ=K+N, KJ=K+2N ... : avant l'élément pivot,
411  !on se déplace sur les colonnes
412  !J=K=3: KJ=K+2N+1, KJ=K+2N+2....!une fois qu'on a passé
413  !le pivot, on se déplace sur la ligne, à droite de l'élément pivot
414  !si on est sur le premier élément de la colonne pivot
415  IF (j==k) THEN
416  !KJ réfère à l'élément diagonal du pivot
417  a2(kj)=1./pivot
418  ri(j)=0.
419  np=1
420  ELSE
421  !si on est sur un autre élément de du pivot
422  elm=-a2(kj)
423  ri(j)=elm/pivot
424  IF (elm.NE.0.) THEN
425  jl=j
426  !JL prend pour valeur les élements de la colonne
427  !du premier en haut au diagonal -1
428  DO l=1,j
429  !à chaque fois A2 de cet élément est incrémenté
430  a2(jl)=a2(jl)+elm*ri(l)
431  jl=jl+n
432  ENDDO
433  ENDIF
434  !élement véritablement en cours
435  a2(kj)=ri(j)
436  ENDIF
437  !KJ=K+JN si on n'a pas encore passé l'élément de la colonne pivot
438  !KJ=K+J0N+J si on l'a passé
439  kj=kj+np
440  ENDDO
441 ENDDO
442 
443 !change the sign and provisional fill-up
444 DO j=1,n
445  a(:,j)= a2((j-1)*n+1:j*n)
446 ENDDO
447 
448 DO i=1,n
449  DO j=1,i
450  a(i,j)=-a(i,j)
451  a(j,i)=a(i,j)
452  ENDDO
453 ENDDO
454 IF (lhook) CALL dr_hook('MODE_SPLINES:SMXINV',1,zhook_handle)
455 
456 END SUBROUTINE smxinv
457 
458 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
459 ! CALCULS PLUS SPECIFIQUES
460 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
461 !6. IE(ND,M): calcul de la matrice IE en fonction de NDEG.
462 SUBROUTINE splie(NDEG,IE)
463 !SPLE, SPLR
464 IMPLICIT NONE
465 
466 INTEGER, INTENT(IN) :: ndeg
467 INTEGER, DIMENSION(:,:), INTENT(OUT) :: ie
468 
469 INTEGER, DIMENSION(SIZE(IE,1)) :: nv
470 INTEGER :: i, j, k, t, n, n0, nc
471 REAL(KIND=JPRB) :: zhook_handle
472 
473 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLIE',0,zhook_handle)
474 nv(:)=1
475 ie(:,1)=0
476 n=1
477 n0=1
478 
479 !boucle d'itération
480 DO t=1,ndeg
481 !boucle sur les indices
482  DO i=1,SIZE(ie,1)
483  nc=0
484  !NV(I) varie d'itération T en itération
485  DO k=nv(i),n0
486  n=n+1
487  nc=nc+1
488  !boucle sur les indices
489  DO j=1,SIZE(ie,1)
490  ie(j,n)=ie(j,k)
491  IF (j.EQ.i) ie(j,n)=ie(j,n)+1
492  ENDDO
493  ENDDO
494  nv(i)=n-nc+1
495  ENDDO
496  n0=n
497 ENDDO
498 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLIE',1,zhook_handle)
499 
500 END SUBROUTINE splie
501 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
502 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
503 !7. calcul de RK en fonction des autres RK(N1,N2)
504 SUBROUTINE splk_1(NORD,X1,X2,G,RK)
505 !SPLE,SPLU,
506 IMPLICIT NONE
507 
508 INTEGER, INTENT(IN) :: nord
509 REAL, DIMENSION(:), INTENT(IN) :: x1
510 REAL, DIMENSION(:,:), INTENT(IN) :: x2
511 REAL, DIMENSION(:,:), INTENT(IN) :: g
512 REAL, DIMENSION(:), INTENT(OUT):: rk
513 
514 INTEGER :: i, id, jd, exp, isigne
515 INTEGER :: nd, n, di, dj
516 REAL :: d2
517 REAL(KIND=JPRB) :: zhook_handle
518 
519 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLK_1',0,zhook_handle)
520 nd=SIZE(x1)
521 n=SIZE(x2,2)
522 
523 !Exposant du noyau
524 exp=(2*nord-nd)/2.
525 
526 IF (mod(nd,2).EQ.0) THEN
527  !Calcul de K dans le cas d'un espace de dimension paire
528  isigne=(-1)**(1+nord+nd/2)
529 ELSE
530  !Calcul de K dans le cas d'un espace de dimension impair
531  isigne=(-1)**(nord+nd/2)
532 ENDIF
533 
534 rk(:)=0.
535 
536 DO i=1,n
537  d2=0.
538  DO id=1,nd
539  DO jd=1,nd
540  di=x1(id)-x2(id,i)
541  dj=x1(jd)-x2(jd,i)
542  d2=d2+g(id,jd)*di*dj
543  ENDDO
544  ENDDO
545  IF (d2.NE.0.) THEN
546  rk(i) = isigne*d2**exp
547  IF (mod(nd,2).EQ.0) rk(i)=rk(i)*0.5*log(d2)
548  ENDIF
549 ENDDO
550 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLK_1',1,zhook_handle)
551 
552 END SUBROUTINE splk_1
553 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
554 !7. calcul de RK en fonction des autres RK(N1,N2)
555 SUBROUTINE splk_2(NORD,X1,X2,G,RK)
556 
557 IMPLICIT NONE
558 
559 INTEGER, INTENT(IN) :: nord
560 REAL, DIMENSION(:,:), INTENT(IN) :: x1
561 REAL, DIMENSION(:,:), INTENT(IN) :: x2
562 REAL, DIMENSION(:,:), INTENT(IN) :: g
563 REAL, DIMENSION(:,:), INTENT(OUT):: rk
564 
565 INTEGER :: i1, i2, id, jd, isigne
566 INTEGER :: nd, n1, n2
567 REAL :: exp, d2, di, dj
568 REAL(KIND=JPRB) :: zhook_handle
569 
570 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLK_2',0,zhook_handle)
571 nd=SIZE(x1,1)
572 n1=SIZE(x1,2)
573 n2=SIZE(x2,2)
574 
575 !Exposant du noyau
576 exp=(2*nord-nd)/2.
577 
578 IF (mod(nd,2).EQ.0) THEN
579  !Calcul de K dans le cas d'un espace de dimension paire
580  isigne=(-1)**(1+nord+nd/2)
581 ELSE
582  !Calcul de K dans le cas d'un espace de dimension impair
583  isigne=(-1)**(nord+nd/2)
584 ENDIF
585 
586 rk(:,:)=0.
587 
588 DO i1=1,n1
589  DO i2=1,n2
590  d2=0.
591  DO id=1,nd
592  DO jd=1,nd
593  di=x1(id,i1)-x2(id,i2)
594  dj=x1(jd,i1)-x2(jd,i2)
595  d2=d2+g(id,jd)*di*dj
596  ENDDO
597  ENDDO
598  IF (d2.NE.0.) THEN
599  rk(i1,i2) = isigne*d2**exp
600  IF (mod(nd,2).EQ.0) rk(i1,i2)=rk(i1,i2)*0.5*log(d2)
601  ENDIF
602  ENDDO
603 ENDDO
604 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLK_2',1,zhook_handle)
605 
606 END SUBROUTINE splk_2
607 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
608 !8. on cherche l'indice I de la 3ème dimension de AI tel que XE(ID) soit compris
609 !entre AI(ID,1,I) et AI(ID,2,I+1). Il est compris entre 1 et NSD(ID),
610 !par défaut il est égal à NDSD(ID)
611 SUBROUTINE splbfin(ID,NSD,XE,AI,IDX,IDX1)
612 !SPLB2E
613 IMPLICIT NONE
614 
615 INTEGER, INTENT(IN) :: id
616 INTEGER, DIMENSION(:), INTENT(IN) :: nsd
617 REAL, DIMENSION(:), INTENT(IN) :: xe
618 REAL, DIMENSION(:,:,:), INTENT(IN) :: ai
619 INTEGER, INTENT(OUT) :: idx
620 INTEGER, INTENT(OUT) :: idx1
621 
622 !INTEGER, PARAMETER: NSDMAX=20
623 INTEGER :: i, i1
624 REAL(KIND=JPRB) :: zhook_handle
625 
626 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBFIN',0,zhook_handle)
627 idx1=0
628 DO i=1,nsd(id)-1
629  IF (xe(id).LE.ai(id,2,i)) THEN
630  idx=i
631  i1=i+1
632  IF (xe(id).GT.ai(id,1,i1)) idx1=i1
633  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBFIN',1,zhook_handle)
634  RETURN
635  ENDIF
636 ENDDO
637 idx=nsd(id)
638 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBFIN',1,zhook_handle)
639 
640 END SUBROUTINE splbfin
641 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
642 !9. X(ND,N) IE(ND,M) : T(N,M) T=produit(X**IE) quand IE est non nul
643 SUBROUTINE splt_1(X,IE,T)
644 !SPLE, SPLTT
645 IMPLICIT NONE
646 
647 REAL, DIMENSION(:), INTENT(IN) :: x
648 INTEGER, DIMENSION(:,:), INTENT(IN) :: ie
649 REAL, DIMENSION(:), INTENT(OUT) :: t
650 !
651 INTEGER :: j,k
652 REAL(KIND=JPRB) :: zhook_handle
653 
654 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLT_1',0,zhook_handle)
655 t(:)=1.
656 
657 DO j=1,SIZE(ie,2)
658  DO k=1,SIZE(x,1)
659  IF (ie(k,j).NE.0) t(j)=t(j)*x(k)**ie(k,j)
660  ENDDO
661 ENDDO
662 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLT_1',1,zhook_handle)
663 
664 END SUBROUTINE splt_1
665 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
666 !9. X(ND,N) IE(ND,M) : T(N,M) T=produit(X**IE) quand IE est non nul
667 SUBROUTINE splt_2(X,IE,T)
668 !
669 IMPLICIT NONE
670 
671 REAL, DIMENSION(:,:), INTENT(IN) :: x
672 INTEGER, DIMENSION(:,:), INTENT(IN) :: ie
673 REAL, DIMENSION(:,:), INTENT(OUT) :: t
674 !
675 INTEGER :: i,j,k
676 REAL(KIND=JPRB) :: zhook_handle
677 
678 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLT_2',0,zhook_handle)
679 t(:,:)=1.
680 
681 DO j=1,SIZE(ie,2)
682  DO i=1,SIZE(x,2)
683  DO k=1,SIZE(x,1)
684  IF (ie(k,j).NE.0) t(i,j)=t(i,j)*x(k,i)**ie(k,j)
685  ENDDO
686  ENDDO
687 ENDDO
688 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLT_2',1,zhook_handle)
689 
690 END SUBROUTINE splt_2
691 
692 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
693 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
694 ! PARTIE "E"
695 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
696 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
697 !10.
698 SUBROUTINE sple(NORD,X,G,C,XE,ZE)
699 !SPLB2E1
700 IMPLICIT NONE
701 
702 INTEGER, INTENT(IN) :: nord
703 REAL, DIMENSION(:,:),INTENT(IN) :: x !ND,N
704 REAL, DIMENSION(:,:), INTENT(IN) :: g !ND,ND
705 REAL, DIMENSION(:),INTENT(IN) :: c ! N+M
706 REAL, DIMENSION(:),INTENT(IN) :: xe !ND
707 REAL, INTENT(OUT) :: ze
708 
709 INTEGER, DIMENSION(SIZE(X,1),SIZE(C)-SIZE(X,2)) :: iw !ND,M
710 REAL, DIMENSION(SIZE(X,2)) :: we1
711 REAL, DIMENSION(SIZE(IW,2)) :: we2
712 REAL :: zout1,zout2
713 INTEGER :: m, n, ne, m1, m2, m3
714 REAL(KIND=JPRB) :: zhook_handle
715 
716 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLE',0,zhook_handle)
717 n=SIZE(x,2)
718 m=SIZE(c)-n
719 
720 ! Calcul de la matrice Kxe
721  CALL splk(nord,xe,x,g,we1)
722 ! Calcul de Kxe.c
723  CALL mxmspl(we1,c(1:n),zout1)
724 
725 IF (m.NE.0) THEN
726  ! Generation des exposants des monomes
727  CALL splie(nord-1,iw) !IW(ND,M)
728  ! Calcul de la matrice Txe
729  CALL splt(xe,iw,we2)
730  ! Calcul Txe.d
731  CALL mxmspl(we2,c(n+1:n+m),zout2)
732  ! Calcul de Txe.d + Kxe.c
733  ze = zout1+zout2
734 ENDIF
735 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLE',1,zhook_handle)
736 
737 END SUBROUTINE sple
738 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
739 !11.
740 SUBROUTINE splb2e1(NORD,M,G,C,XE,IDX,IDX1,IDY,IDY1,ZE)
741 !SPLB2E
742 
743 IMPLICIT NONE
744 
745 INTEGER, INTENT(IN) :: nord
746 INTEGER, INTENT(IN) :: m
747 REAL, DIMENSION(:,:),INTENT(IN) :: g
748 REAL, DIMENSION(:,:,:), INTENT(IN) :: c
749 REAL, DIMENSION(:), INTENT(IN) :: xe
750 INTEGER, INTENT(IN) :: idx,idx1,idy,idy1
751 REAL, INTENT(OUT) :: ze
752 
753 INTEGER :: nn,nm
754 REAL :: rx,ry,alphax,alphay,sum_ax,sum_ay,sum_a
755 REAL :: zxy, zx1y, zxy1, zx1y1
756 REAL(KIND=JPRB) :: zhook_handle
757 
758 
759 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLB2E1',0,zhook_handle)
760 
761 rx=0
762 ry=0
763 IF (idx1.NE.0) rx=(xe(1)-ai(1,1,idx1))/(ai(1,2,idx)-ai(1,1,idx1))
764 IF (idy1.NE.0) ry=(xe(2)-ai(2,1,idy1))/(ai(2,2,idy)-ai(2,1,idy1))
765 alphax=(rx-1.)*(rx-1.)*(2*rx+1.)
766 alphay=(ry-1.)*(ry-1.)*(2*ry+1.)
767 sum_ax=0.
768 sum_ay=0.
769 sum_a=0.
770 zxy=0.
771 zx1y=0.
772 zxy1=0.
773 zx1y1=0.
774 
775 nm=0
776 
777 IF (ns(idx,idy).GE.m) THEN
778  nm=1
779  sum_ax=sum_ax+alphax
780  sum_ay=sum_ay+alphay
781  sum_a=sum_a+alphax*alphay
782  nn=ns(idx,idy)
783  !N=NN
784  CALL sple(nord,xs(:,1:nn,idx,idy),g,c(1:nn+m,idx,idy),xe,zxy)
785 ENDIF
786 
787 IF (idx1.NE.0) THEN
788  IF (ns(idx1,idy).GE.m) THEN
789  nm=1
790  sum_ax=sum_ax+1.-alphax
791  sum_a=sum_a+(1-alphax)*alphay
792  nn=ns(idx1,idy)
793  CALL sple(nord,xs(:,1:nn,idx1,idy),g,c(1:nn+m,idx1,idy),xe,zx1y)
794  ENDIF
795 ENDIF
796 
797 IF (idy1.NE.0) THEN
798  IF (ns(idx,idy1).GE.m) THEN
799  nm=1
800  sum_ay=sum_ay+1.-alphay
801  sum_a=sum_a+alphax*(1-alphay)
802  nn=ns(idx,idy1)
803  CALL sple(nord,xs(:,1:nn,idx,idy1),g,c(1:nn+m,idx,idy1),xe,zxy1)
804  ENDIF
805 ENDIF
806 
807 IF (idx1.NE.0 .AND. idy1.NE.0) THEN
808  IF (ns(idx1,idy1).GE.m) THEN
809  nm=1
810  sum_a=sum_a+(1-alphax)*(1-alphay)
811  nn=ns(idx1,idy1)
812  CALL sple(nord,xs(:,1:nn,idx1,idy1),g,c(1:nn+m,idx1,idy1),xe,zx1y1)
813  ENDIF
814 ENDIF
815 
816 IF (nm==1) THEN
817  IF (idx1.NE.0 .AND. idy1.EQ.0) THEN
818  ze=(alphax*zxy+(1-alphax)*zx1y)/sum_ax
819  ELSEIF (idx1.EQ.0 .AND. idy1.NE.0) THEN
820  ze=(alphay*zxy+(1-alphay)*zxy1)/sum_ay
821  ELSEIF (idx1.NE.0 .AND. idy1.NE.0) THEN
822  ze=(alphax*alphay *zxy + (1-alphax)* alphay*zx1y + &
823  alphax*(1-alphay)*zxy1 + (1-alphax)*(1-alphay)*zx1y1) / sum_a
824  ELSE
825  ze=zxy
826  ENDIF
827 ENDIF
828 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLB2E1',1,zhook_handle)
829 
830 END SUBROUTINE splb2e1
831 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
832 ! APPELEE PAR INTERPOL_SPLINES.F90
833 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
834 !12.
835 SUBROUTINE splb2e(NORD,M,NSDI,NSDJ,G,C,XE,ZE)
836 
837 IMPLICIT NONE
838 
839 INTEGER, INTENT(IN) :: nord
840 INTEGER, INTENT(IN) :: m
841 INTEGER, INTENT(IN) :: nsdi,nsdj
842 REAL, DIMENSION(:,:), INTENT(IN) :: g
843 REAL,DIMENSION(:,:,:), INTENT(IN) :: c
844 REAL, DIMENSION(:,:), INTENT(IN) :: xe
845 REAL, DIMENSION(:), INTENT(OUT) :: ze
846 
847 INTEGER, DIMENSION(2) :: nsd
848 INTEGER :: j, id, ne
849 INTEGER :: idx, idx1, idy, idy1
850 REAL(KIND=JPRB) :: zhook_handle
851 
852 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLB2E',0,zhook_handle)
853 ne=SIZE(xe,2)
854 
855 nsd(1)=nsdi
856 nsd(2)=nsdj
857 
858 DO j=1,ne
859  id=1
860  CALL splbfin(id,nsd,xe(:,j),ai,idx,idx1)
861  id=2
862  CALL splbfin(id,nsd,xe(:,j),ai,idy,idy1)
863  CALL splb2e1(nord,m,g,c,xe(:,j),idx,idx1,idy,idy1,ze(j))
864 ENDDO
865 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLB2E',1,zhook_handle)
866 
867 END SUBROUTINE splb2e
868 
869 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
870 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
871 ! PARTIE "C"
872 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
873 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
874 
875 ! Calculs EISRS1
876 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
877 !13.
878 SUBROUTINE tred2(A,D,E,Z)
879 !EISRS1
880 IMPLICIT NONE
881 
882 REAL, DIMENSION(:,:), INTENT(IN) :: a
883 REAL, DIMENSION(:), INTENT(OUT) :: d
884 REAL, DIMENSION(:), INTENT(OUT) :: e
885 REAL, DIMENSION(:,:), INTENT(OUT):: z
886 
887 INTEGER :: n, i, ii, j, k, l, jp1
888 REAL :: f, g, h, scale, hh
889 REAL(KIND=JPRB) :: zhook_handle
890 
891 
892 IF (lhook) CALL dr_hook('MODE_SPLINES:TRED2',0,zhook_handle)
893 n=SIZE(a,1)
894 
895 !Z=A sur la partie gauceh jusqu'à la diagonale
896 DO i=1,n
897  DO j=1,i
898  z(i,j)=a(i,j)
899  ENDDO
900 ENDDO
901 
902 IF (n.NE.1) THEN
903  DO ii=2,n
904  !I varie de N à 2
905  i=n+2-ii
906  !L varie de N-1 à 1
907  l=i-1
908  h=0.0
909  scale=0.0
910  IF (l.GE.2) THEN
911  !scale = somme des éléments de la ligne à l'exclusion du diagonal
912  DO k=1,l
913  scale=scale+abs(z(i,k))
914  ENDDO
915  IF (scale.NE.0.0) THEN
916  !normalisation de Z par la valeur de la ligne
917  DO k=1,l
918  z(i,k)=z(i,k)/scale
919  !H = somme des carrés de Z / (somme des ABS(Z)) au carré
920  h=h+z(i,k)**2
921  ENDDO
922  f=z(i,l)
923  !SQRT(H) signé par lélément diagonal-1 de la ligne
924  g=-sign(sqrt(h),f)
925  !moyenne des éléments au carrés de la ligne, signée
926  e(i)=scale*g
927  h=h-f*g
928  z(i,l)=f-g
929  f=0.0
930  DO j=1,l
931  z(j,i)=z(i,j)/(scale*h)
932  g=0.0
933  DO k=1,j
934  g=g+z(j,k)*z(i,k)
935  ENDDO
936  jp1=j+1
937  IF (l.GE.jp1) THEN
938  DO k=jp1,l
939  g=g+z(k,j)*z(i,k)
940  ENDDO
941  ENDIF
942  e(j)=g/h
943  f=f+e(j)*z(i,j)
944  ENDDO
945  hh=f/(h+h)
946  DO j=1,l
947  f=z(i,j)
948  g=e(j)-hh*f
949  e(j)=g
950  DO k=1,j
951  z(j,k)=z(j,k)-f*e(k)-g*z(i,k)
952  ENDDO
953  ENDDO
954  DO k=1,l
955  z(i,k)=scale*z(i,k)
956  ENDDO
957  ELSE
958  e(i)=z(i,l)
959  ENDIF
960  ELSE
961  e(i)=z(i,l)
962  ENDIF
963  d(i)=h
964  ENDDO
965 ENDIF
966 
967 d(1)=0.0
968 e(1)=0.0
969 DO i=1,n
970  l=i-1
971  IF (d(i).NE.0.0) THEN
972  DO j=1,l
973  g=0.0
974  DO k=1,l
975  g=g+z(i,k)*z(k,j)
976  ENDDO
977  DO k=1,l
978  z(k,j)=z(k,j)-g*z(k,i)
979  ENDDO
980  ENDDO
981  ENDIF
982  d(i)=z(i,i)
983  z(i,i)=1.0
984  IF (l.GE.1) THEN
985  DO j=1,l
986  z(i,j)=0.0
987  z(j,i)=0.0
988  ENDDO
989  ENDIF
990 ENDDO
991 IF (lhook) CALL dr_hook('MODE_SPLINES:TRED2',1,zhook_handle)
992 
993 END SUBROUTINE tred2
994 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
995 !14.
996 SUBROUTINE tql2_2(D,E,Z,IERR)
997 !EISRS1
998 IMPLICIT NONE
999 
1000 REAL, DIMENSION(:), INTENT(INOUT) :: d
1001 REAL, DIMENSION(:), INTENT(INOUT) :: e
1002 REAL, DIMENSION(:,:), INTENT(OUT) :: z
1003 INTEGER, INTENT(OUT) :: ierr
1004 
1005 INTEGER :: i, ii, j, k, l, m, n, mml
1006 REAL :: b, c, f, g, h, p, r, s
1007 REAL :: machep
1008 REAL(KIND=JPRB) :: zhook_handle
1009 
1010 
1011 IF (lhook) CALL dr_hook('MODE_SPLINES:TQL2_2',0,zhook_handle)
1012 machep=2.**(-52)
1013 ierr=0
1014 n=SIZE(d)
1015 
1016 IF (n.NE.1) THEN
1017  DO i=2,n
1018  e(i-1)=e(i)
1019  ENDDO
1020  f=0.0
1021  b=0.0
1022  e(n)=0.0
1023  DO l=1,n
1024  j=0
1025  h=machep*(abs(d(l))+abs(e(l)))
1026  IF (b.LT.h) b=h
1027  DO m=l,n
1028  IF (abs(e(m)).LE.b) EXIT
1029  ENDDO
1030  IF (m.NE.l) THEN
1031  DO WHILE (abs(e(l)).GT.b)
1032  IF (j.EQ.30) THEN
1033  ierr=l
1034  IF (lhook) CALL dr_hook('MODE_SPLINES:TQL2_2',1,zhook_handle)
1035  RETURN
1036  ENDIF
1037  j=j+1
1038  p=(d(l+1)-d(l)) / (2.0 * e(l))
1039  r=sqrt(p*p+1.0)
1040  h=d(l)-e(l) / (p+sign(r,p))
1041  DO i=l,n
1042  d(i)=d(i)-h
1043  ENDDO
1044  f=f+h
1045  p=d(m)
1046  c=1.0
1047  s=0.0
1048  mml=m-l
1049  DO ii=1,mml
1050  i=m-ii
1051  g=c*e(i)
1052  h=c*p
1053  IF (abs(p).GE.abs(e(i))) THEN
1054  c=e(i)/p
1055  r=sqrt(c*c+1.0)
1056  e(i+1)=s*p*r
1057  s=c/r
1058  c=1.0/r
1059  ELSE
1060  c=p/e(i)
1061  r=sqrt(c*c+1.0)
1062  e(i+1)=s*e(i)*r
1063  s=1.0/r
1064  c=c*s
1065  ENDIF
1066  p=c*d(i)-s*g
1067  d(i+1)=h+s*(c*g+s*d(i))
1068  DO k=1,n
1069  h=z(k,i+1)
1070  z(k,i+1)=s*z(k,i)+c*h
1071  z(k,i)=c*z(k,i)-s*h
1072  ENDDO
1073  ENDDO
1074  e(l)=s*p
1075  d(l)=c*p
1076  ENDDO
1077  ENDIF
1078  d(l)=d(l)+f
1079  ENDDO
1080  DO ii=2,n
1081  i=ii-1
1082  k=i
1083  p=d(i)
1084  DO j=ii,n
1085  IF (d(j).LT.p) THEN
1086  k=j
1087  p=d(j)
1088  ENDIF
1089  ENDDO
1090  IF (k.NE.i) THEN
1091  d(k)=d(i)
1092  d(i)=p
1093  DO j=1,n
1094  p=z(j,i)
1095  z(j,i)=z(j,k)
1096  z(j,k)=p
1097  ENDDO
1098  ENDIF
1099  ENDDO
1100 ENDIF
1101 IF (lhook) CALL dr_hook('MODE_SPLINES:TQL2_2',1,zhook_handle)
1102 
1103 END SUBROUTINE tql2_2
1104 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1105 !15. SPLR,SPLU
1106 SUBROUTINE eisrs1(AR,WR,ZR,WORK,IERR)
1107 !
1108 ! all eigenvalues and corresponding eigenvectors of a real
1109 ! symmetric matrix
1110 !
1111 IMPLICIT NONE
1112 !toutes les dimensions sont N: ok
1113 REAL, DIMENSION(:,:), INTENT(IN) :: ar
1114 REAL, DIMENSION(:), INTENT(OUT) :: wr
1115 REAL, DIMENSION(:,:), INTENT(OUT) :: zr
1116 REAL, DIMENSION(:), INTENT(OUT) :: work
1117 INTEGER, INTENT(OUT) :: ierr
1118 REAL(KIND=JPRB) :: zhook_handle
1119 
1120 IF (lhook) CALL dr_hook('MODE_SPLINES:EISRS1',0,zhook_handle)
1121  CALL tred2(ar,wr,work,zr)
1122  CALL tql2_2(wr,work,zr,ierr)
1123 IF (lhook) CALL dr_hook('MODE_SPLINES:EISRS1',1,zhook_handle)
1124 
1125 END SUBROUTINE eisrs1
1126 
1127 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1128 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1129 ! GROUPES DES PROCEDURES V
1130 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1131 !16.
1132 SUBROUTINE splv(B,W,N,P,RES)
1133 !SP0NOP
1134 IMPLICIT NONE
1135 
1136 REAL,DIMENSION(:),INTENT(IN) :: b
1137 REAL,DIMENSION(:), INTENT(IN) :: w
1138 INTEGER, INTENT(IN) :: n
1139 REAL, INTENT(IN) :: p
1140 REAL, INTENT(OUT) :: res
1141 !
1142 INTEGER :: a, d, i
1143 REAL(KIND=JPRB) :: zhook_handle
1144 
1145 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLV',0,zhook_handle)
1146 a=0.
1147 res=0.
1148 DO i=1,SIZE(b)
1149  d=b(i)+n*p
1150  a=a+1./d
1151  res=res+w(i)**2 / d**2
1152 ENDDO
1153 res=n*res/a**2
1154 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLV',1,zhook_handle)
1155 
1156 END SUBROUTINE splv
1157 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1158 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1159 ! GROUPE DES PROCEDURES P
1160 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1161 !PROCEDURES INTERMEDIAIRES POUR SPLPS2V
1162 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1163 !17. S2VI=somme(W(i)**2)/size(W)
1164 SUBROUTINE spls2vi(W,RES)
1165 !
1166 IMPLICIT NONE
1167 
1168 REAL, DIMENSION(:), INTENT(IN) :: w
1169 REAL, INTENT(OUT) :: res
1170 
1171 INTEGER :: i
1172 REAL(KIND=JPRB) :: zhook_handle
1173 
1174 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLS2VI',0,zhook_handle)
1175 res = 0.
1176 DO i=1,SIZE(w)
1177  res = res + w(i)**2
1178 ENDDO
1179 res=res/SIZE(w)
1180 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLS2VI',1,zhook_handle)
1181 
1182 END SUBROUTINE spls2vi
1183 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1184 !18. calcul de BN en fonction de W, B, N et P
1185 SUBROUTINE splbvm(B,W,N,P,RES)
1186 !SPLS2V, SP0VPQ
1187 IMPLICIT NONE
1188 
1189 REAL, DIMENSION(:), INTENT(IN) :: b, w
1190 INTEGER, INTENT(IN) :: n
1191 REAL, INTENT(IN) :: p
1192 REAL, INTENT(OUT) :: res
1193 !
1194 REAL :: a
1195 INTEGER :: i
1196 REAL(KIND=JPRB) :: zhook_handle
1197 
1198 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBVM',0,zhook_handle)
1199 res=0.
1200 a=0.
1201 DO i=1,SIZE(b)
1202  res=res+(w(i)**2)/(b(i)+n*p)**2
1203  a=a+1./(b(i)+n*p)
1204 ENDDO
1205 res=res/a
1206 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBVM',1,zhook_handle)
1207 
1208 END SUBROUTINE splbvm
1209 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1210 !19.
1211 SUBROUTINE spls2v(BI,WI,N,P,RES)
1212 !SPLPS2V, SPLP
1213 IMPLICIT NONE
1214 
1215 REAL, DIMENSION(:), INTENT(IN) :: bi !dimension N-M
1216 REAL, DIMENSION(:), INTENT(IN) :: wi !dimension N-M
1217 INTEGER, INTENT(IN) :: n
1218 REAL, INTENT(IN) :: p
1219 REAL, INTENT(OUT) :: res
1220 REAL(KIND=JPRB) :: zhook_handle
1221 
1222 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLS2V',0,zhook_handle)
1223  CALL splbvm(bi,wi,n,p,res)
1224 res=n*p*res
1225 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLS2V',1,zhook_handle)
1226 
1227 END SUBROUTINE spls2v
1228 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1229 !20.
1230 SUBROUTINE splds2v(B,W,N,P,RES)
1231 !SPLPS2V
1232 IMPLICIT NONE
1233 
1234 REAL, DIMENSION(:), INTENT(IN) :: b
1235 REAL, DIMENSION(:), INTENT(IN) :: w
1236 INTEGER, INTENT(IN) :: n
1237 REAL, INTENT(IN) :: p
1238 REAL, INTENT(OUT) :: res
1239 
1240 REAL :: da, db, a1, a2, a3, b2, c1, c2
1241 INTEGER :: j, i
1242 REAL(KIND=JPRB) :: zhook_handle
1243 
1244 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLDS2V',0,zhook_handle)
1245 da=0.
1246 db=0.
1247 DO i=1,SIZE(b)
1248  a1=1./(b(i)+n*p)
1249  a2=a1**2
1250  a3=a1**3
1251  da=da+a1
1252  b2=w(j)**2
1253  DO j=1,SIZE(b)
1254  c1=1./(b(j)+n*p)
1255  c2=c1**2
1256  db=db+b2*(a2*c1+n*p*(-2*a3*c1+a2*c2))
1257  ENDDO
1258 ENDDO
1259 res=(n/(da**2))*db
1260 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLDS2V',1,zhook_handle)
1261 
1262 END SUBROUTINE splds2v
1263 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1264 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1265 !21. SPLPS2V procedure
1266 SUBROUTINE splps2v(B,W,N,P0,S2,P,IREP)
1267 !SPLP
1268 IMPLICIT NONE
1269 
1270 REAL, DIMENSION(:), INTENT(IN) :: b
1271 REAL, DIMENSION(:), INTENT(IN) :: w
1272 INTEGER, INTENT(IN) :: n
1273 REAL, INTENT(INOUT) :: p0
1274 REAL, INTENT(IN) :: s2
1275 REAL, INTENT(OUT) :: p
1276 INTEGER, INTENT(OUT) :: irep
1277 
1278 INTEGER, PARAMETER :: eps=1.e-2
1279 REAL :: p1, rinf, rs, drs
1280 INTEGER :: niter
1281 REAL(KIND=JPRB) :: zhook_handle
1282 
1283 ! Calcul de la valeur du s2 de Wahba pour p=infini
1284 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPS2V',0,zhook_handle)
1285  CALL spls2vi(w,rinf)
1286 IF (rinf.LE.s2) THEN
1287  irep=-6
1288  p0=0.
1289  WRITE(*,fmt='(A53,G15.5)') &
1290  "SPLPS2V : S2 > VALEUR DE LA FONCTION POUR P INFINI = ",rinf
1291  p=(b(SIZE(b))**2)/b(1)
1292  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPS2V',1,zhook_handle)
1293  RETURN
1294 ENDIF
1295 
1296 p1=0.
1297 ! Iterations de Newton
1298 DO niter=1,nmax
1299  p0=p1
1300  CALL spls2v(b,w,n,p0,rs)
1301  CALL splds2v(b,w,n,p0,drs)
1302 
1303  p1=p0+(s2-rs)/drs
1304 
1305  IF (abs(p1-p0)/p0.LT.eps) THEN
1306  IF (p1.GE.0.) THEN
1307  irep=0
1308  p=p1
1309  p0=p1
1310  ELSE
1311  irep=-3
1312  p=0.
1313  p0=0.
1314  WRITE(*,fmt='(A34,G15.5)') &
1315  "SPLPS2V : SOLUTION NEGATIVE : P = ",p
1316  ENDIF
1317  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPS2V',1,zhook_handle)
1318  RETURN
1319  ENDIF
1320 ENDDO
1321 
1322 irep=-5
1323 p=p1
1324 p0=0.
1325 WRITE(*,fmt='(A48,A23,G15.5)') &
1326  "SPLPS2V : NOMBRE MAXIMAL D ITERATIONS ATTEINT : ",&
1327  "VALEUR DE P ATTEINTE : ",p1
1328 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPS2V',1,zhook_handle)
1329 
1330 END SUBROUTINE splps2v
1331 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1332 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1333 !PROCEDURES INTERMEDIAIRES POUR SPLPR
1334 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1335 !22. Comme SPLS2VI mais on ne divise pas par SIZE(W) mais par N
1336 SUBROUTINE splri(W,N,RES)
1337 !SPLPR
1338 IMPLICIT NONE
1339 
1340 REAL, DIMENSION(:), INTENT(IN) :: w
1341 INTEGER, INTENT(IN) :: n
1342 REAL, INTENT(OUT) :: res
1343 
1344 INTEGER :: i
1345 REAL(KIND=JPRB) :: zhook_handle
1346 
1347 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLRI',0,zhook_handle)
1348 res=0.
1349 DO i=1,SIZE(w)
1350  res = res + w(i)**2
1351 ENDDO
1352 res=res/n
1353 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLRI',1,zhook_handle)
1354 
1355 END SUBROUTINE splri
1356 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1357 !23. RS=SQRT(S2/(SOMME((W(I)/B(I))**2)*N)
1358 SUBROUTINE splpr0(B,W,N,S2,P)
1359 !SPLPR
1360 IMPLICIT NONE
1361 
1362 REAL, DIMENSION(:), INTENT(IN) :: b
1363 REAL, DIMENSION(:), INTENT(IN) :: w
1364 INTEGER, INTENT(IN) :: n
1365 REAL, INTENT(IN) :: s2
1366 REAL, INTENT(OUT) :: p
1367 
1368 REAL :: res
1369 INTEGER :: i
1370 REAL(KIND=JPRB) :: zhook_handle
1371 
1372 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPR0',0,zhook_handle)
1373 res=0.
1374 DO i=1,SIZE(w)
1375  res=res+(w(i)/b(i))**2
1376 ENDDO
1377 p=sqrt(s2/(res*n))
1378 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPR0',1,zhook_handle)
1379 
1380 END SUBROUTINE splpr0
1381 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1382 !24. RS=N*SOMME((W(I)/(B(I)+N*P))**2)*P**2
1383 SUBROUTINE splrs(B,W,N,P,RES)
1384 !SPLP, SPLPR, SP0CVQ
1385 IMPLICIT NONE
1386 
1387 REAL, DIMENSION(:), INTENT(IN) :: b
1388 REAL, DIMENSION(:), INTENT(IN) :: w
1389 INTEGER, INTENT(IN) :: n
1390 REAL, INTENT(IN) :: p
1391 REAL, INTENT(OUT):: res
1392 
1393 INTEGER :: i
1394 REAL(KIND=JPRB) :: zhook_handle
1395 
1396 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLRS',0,zhook_handle)
1397 res=0.
1398 DO i=1,SIZE(b)
1399  res=res+(w(i)/(b(i)+n*p))**2
1400 ENDDO
1401 res=n*res*p**2
1402 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLRS',1,zhook_handle)
1403 
1404 END SUBROUTINE splrs
1405 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1406 !25. DRS=2*N*P*(SOMME(W(I)**2*B(I)/(B(I)+N*P)**3)
1407 SUBROUTINE spldrs(B,W,N,P,RES)
1408 !SPLPR
1409 IMPLICIT NONE
1410 
1411 REAL, DIMENSION(:), INTENT(IN) :: b
1412 REAL, DIMENSION(:), INTENT(IN) :: w
1413 INTEGER, INTENT(IN) :: n
1414 REAL, INTENT(IN) :: p
1415 REAL, INTENT(OUT) :: res
1416 !
1417 INTEGER :: j
1418 REAL :: d
1419 REAL(KIND=JPRB) :: zhook_handle
1420 
1421 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLDRS',0,zhook_handle)
1422 res=0.
1423 DO j=1,SIZE(b)
1424  d=b(j)+n*p
1425  res=res+w(j)**2*b(j)/(d**3)
1426 ENDDO
1427 res=2.*n*p*res
1428 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLDRS',1,zhook_handle)
1429 
1430 END SUBROUTINE spldrs
1431 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1432 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1433 !26. SPLPR procedure: parallèle de splps2v
1434 SUBROUTINE splpr(N,W,B,P0,S2,P,IREP)
1435 !SPLP
1436 IMPLICIT NONE
1437 
1438 INTEGER, INTENT(IN) :: n
1439 REAL, DIMENSION(:), INTENT(IN) :: w !N-M
1440 REAL, DIMENSION(:), INTENT(IN) :: b !N-M
1441 REAL, INTENT(INOUT) :: p0
1442 REAL, INTENT(INOUT) :: s2
1443 REAL, INTENT(INOUT) :: p
1444 INTEGER, INTENT(OUT) :: irep
1445 
1446 INTEGER, PARAMETER :: eps=1.e-2
1447 REAL :: rs, drs, p1, rinf
1448 INTEGER :: niter
1449 REAL(KIND=JPRB) :: zhook_handle
1450 
1451 ! Calcul de la valeur de la fonction de Reinsch pour p=infini
1452 
1453 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPR',0,zhook_handle)
1454  CALL splri(w,n,rinf)
1455 IF (rinf.LE.s2) THEN
1456  irep=-6
1457  p0=0.
1458  WRITE(*,fmt='(A51,G15.5)') &
1459  "SPLPR : S2 > VALEUR DE LA FONCTION POUR P INFINI = ",rinf
1460  p=(b(SIZE(b))**2)/b(1)
1461  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPR',1,zhook_handle)
1462  RETURN
1463 ENDIF
1464 
1465 ! Recherche du point de depart de l'iteration
1466 IF (p0.EQ.0.) CALL splpr0(b,w,n,s2,p0)
1467 p1=p0
1468 
1469 ! Iterations de Newton
1470 DO niter=1,nsdmax
1471  p0=p1
1472  CALL splrs(b,w,n,p0,rs)
1473  CALL spldrs(b,w,n,p0,drs)
1474 
1475  p1=p0+(s2-rs)/drs
1476 
1477  IF (abs(p1-p0)/p0.LT.eps) THEN
1478  IF (p1.GE.0.) THEN
1479  irep=0
1480  p=p1
1481  p0=p1
1482  ELSE
1483  irep=-3
1484  p=0.
1485  p0=0.
1486  WRITE(*,fmt='(A32,G15.5)') &
1487  "SPLPR : SOLUTION NEGATIVE : P = ",p
1488  ENDIF
1489  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPR',1,zhook_handle)
1490  RETURN
1491  ENDIF
1492 ENDDO
1493 
1494 irep=-5
1495 p=0.
1496 p0=0.
1497 WRITE(*,fmt='(A45,A23,G15.5)') &
1498  "SPLPR : NOMBRE MAXIMAL D ITERATIONS ATTEINT: ",&
1499  "VALEUR DE P ATTEINTE : ",p1
1500 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPR',1,zhook_handle)
1501 
1502 END SUBROUTINE splpr
1503 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1504 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1505 !PROCEDURES INTERMEDIAIRES POUR SPLPV
1506 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1507 !27.
1508 SUBROUTINE spldv(B,W,N,P,RES)
1509 !SPLPV
1510 IMPLICIT NONE
1511 
1512 REAL, DIMENSION(:), INTENT(IN) :: b
1513 REAL, DIMENSION(:), INTENT(IN) :: w
1514 INTEGER, INTENT(IN) :: n
1515 REAL, INTENT(IN) :: p
1516 REAL, INTENT(OUT) :: res
1517 !
1518 REAL :: s1, s2, sb2, sb3, a1, a2, b2
1519 INTEGER :: i
1520 REAL(KIND=JPRB) :: zhook_handle
1521 
1522 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLDV',0,zhook_handle)
1523 s1=0.
1524 s2=0.
1525 sb2=0.
1526 sb3=0.
1527 DO i=1,SIZE(b)
1528  a1=1./(b(i)+n*p)
1529  a2=a1**2
1530  b2=a2*w(i)**2
1531  s1=s1+a1
1532  s2=s2+a2
1533  sb2=sb2+b2
1534  sb3=sb3+b2*a1
1535 ENDDO
1536 res=s2*sb2-s1*sb3
1537 res=2.*n**2*res/(s1**3)
1538 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLDV',1,zhook_handle)
1539 
1540 END SUBROUTINE spldv
1541 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1542 !28.
1543 SUBROUTINE spld2v(B,W,N,P,RES)
1544 !SPLPV
1545 IMPLICIT NONE
1546 
1547 REAL, DIMENSION(:), INTENT(IN) :: b
1548 REAL, DIMENSION(:), INTENT(IN) :: w
1549 INTEGER, INTENT(IN) :: n
1550 REAL, INTENT(IN) :: p
1551 REAL, INTENT(OUT) :: res
1552 
1553 REAL :: s1, s2, s3, sb2, sb3, sb4
1554 REAL :: a1, a2, b2
1555 INTEGER :: i
1556 REAL(KIND=JPRB) :: zhook_handle
1557 
1558 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLD2V',0,zhook_handle)
1559 s1=0.
1560 s2=0.
1561 s3=0.
1562 sb2=0.
1563 sb3=0.
1564 sb4=0.
1565 DO i=1,SIZE(b)
1566  a1=1./(b(i)+n*p)
1567  a2=a1**2
1568  b2=a2*w(i)**2
1569  s1=s1+a1
1570  s2=s2+a2
1571  s3=s3+a2*a1
1572  sb2=sb2+b2
1573  sb3=sb3+b2*a1
1574  sb4=sb4+b2*a2
1575 ENDDO
1576 res=3.*s2**2*sb2-4.*s2*s1*sb3+3.*s1**2*sb4-2.*s3*s1*sb2
1577 res=res/(s1**4)
1578 res=res*2.*n**3
1579 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLD2V',1,zhook_handle)
1580 
1581 END SUBROUTINE spld2v
1582 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1583 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1584 !29.
1585 SUBROUTINE splpv(N,B,W,P0,P,IREP)
1586 !SPLP
1587 IMPLICIT NONE
1588 
1589 INTEGER, INTENT(IN) :: n
1590 REAL, DIMENSION(:), INTENT(IN):: b, w !N-M
1591 REAL, INTENT(INOUT) :: p0
1592 REAL, INTENT(OUT) :: p
1593 INTEGER, INTENT(OUT) :: irep
1594 
1595 INTEGER, PARAMETER:: eps=xsurf_tiny, epsr=1.e-2
1596 REAL :: dvm, d2vm, p1
1597 INTEGER :: iflag, niter
1598 REAL(KIND=JPRB) :: zhook_handle
1599 
1600 
1601 ! Calcul de Vm'(0) . Si Vm'(0) > 0 alors popt = 0.
1602 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPV',0,zhook_handle)
1603  CALL spldv(b,w,n,0.,dvm)
1604 
1605 IF (dvm.GT.0.) THEN
1606  irep=0.
1607  p=0.
1608  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPV',1,zhook_handle)
1609  RETURN
1610 ENDIF
1611 
1612 ! Recherche du point de depart p0 de l'iteration de Newton
1613 iflag=0
1614 
1615 DO WHILE(iflag==0)
1616 
1617  IF (p0.EQ.0.) THEN
1618 
1619  iflag=1
1620  p0=b(1)/n
1621 
1622  !on augmente P0 et on calcul D2VM; quand D2VM est supérieur à 0,
1623  !on passe à la suite
1624  DO niter=1,nsdmax
1625  CALL spld2v(b,w,n,p0,d2vm)
1626  IF (d2vm.GT.0.) EXIT
1627  p0=p0*10.
1628  ENDDO
1629 
1630  IF (d2vm.LE.0.) THEN
1631  irep=-1
1632  p0=0.
1633  p=0.
1634  WRITE(*,fmt='(A41)') &
1635  "SPLPV : PAS DE MINIMUM: D2VM < 0 PARTOUT "
1636  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPV',1,zhook_handle)
1637  RETURN
1638  ENDIF
1639 
1640  ENDIF
1641 
1642  p1=p0
1643 
1644  DO niter=1,nsdmax
1645 
1646  p0=p1
1647  CALL spldv(b,w,n,p0,dvm)
1648  CALL spld2v(b,w,n,p0,d2vm)
1649 
1650  !Si D2Vm est très proche de 0, on sort et P=P0
1651  IF (abs(d2vm).LT.eps) THEN
1652  p0=0.
1653  IF (iflag.EQ.0) EXIT
1654  irep=-2
1655  p=p0
1656  WRITE(*,fmt='(A28)') "SPLPV : PASSAGE PAR D2VM = 0"
1657  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPV',1,zhook_handle)
1658  RETURN
1659  ENDIF
1660 
1661  p1=p0-dvm/d2vm
1662 
1663  !si l'écart entre P0 et P1 est suffisamment petit
1664  IF (abs(p1-p0)/p0.LT.epsr) THEN
1665  !Si P1 est négatif, on repart dans la boucle
1666  IF (p1.LT.0.) THEN
1667  p0=0.
1668  IF (iflag.EQ.0) EXIT
1669  irep=-3
1670  p=0.
1671  WRITE(*,fmt='(A33,G15.5)') &
1672  "SPLPV : SOLUTION NEGATIVE : P = ",p1
1673  ELSE
1674  !si P1 et positif et D2VM positif, on garde P1
1675  IF (d2vm.GE.0.) THEN
1676  irep=0
1677  p=p1
1678  p0=p1
1679  ELSE
1680  !si P1 est négatif, on repart dans la boucle
1681  p0=0.
1682  IF (iflag.EQ.0) EXIT
1683  irep=-4
1684  p=0.
1685  WRITE(*,fmt='(A28,G15.5)') &
1686  "SPLPV : MAXIMUM DE VM : P = ",p1
1687  ENDIF
1688  ENDIF
1689  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPV',1,zhook_handle)
1690  RETURN
1691  ENDIF
1692  ENDDO
1693 
1694  p0=0.
1695  IF (iflag.NE.0) THEN
1696  irep=-5
1697  p=p1
1698  WRITE(*,fmt='(A46,A23,G15.5)') &
1699  "SPLPV : NOMBRE MAXIMAL D ITERATIONS ATTEINT : ",&
1700  "VALEUR DE P ATTEINTE : ",p1
1701  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPV',1,zhook_handle)
1702  RETURN
1703  ENDIF
1704 
1705 ENDDO
1706 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLPV',1,zhook_handle)
1707 
1708 END SUBROUTINE splpv
1709 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1710 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1711 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1712 !30.
1713 SUBROUTINE splp(LISSAGE,N,B,W,P,S2,IREP)
1714 !SP0NOP
1715 IMPLICIT NONE
1716 
1717 INTEGER, INTENT(IN) :: lissage
1718 INTEGER, INTENT(IN) :: n
1719 REAL, DIMENSION(:), INTENT(IN) :: b
1720 REAL, DIMENSION(:), INTENT(IN) :: w
1721 REAL, INTENT(INOUT) :: p
1722 REAL, INTENT(INOUT) :: s2
1723 INTEGER, INTENT(OUT) :: irep
1724 
1725 REAL :: p0
1726 REAL(KIND=JPRB) :: zhook_handle
1727 
1728 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLP',0,zhook_handle)
1729 IF (lissage.EQ.1) THEN
1730 ! Recherche de la valeur de P pour S2 connu, par la methode de Wahba
1731  p0=0.
1732  CALL splps2v(b,w,n,p0,s2,p,irep)
1733  IF (irep.NE.0) THEN
1734  irep=-2
1735  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLP',1,zhook_handle)
1736  RETURN
1737  ENDIF
1738 ELSEIF (lissage.EQ.10) THEN
1739 ! Recherche de la valeur de P pour S2 connu, par la methode de Reinsch
1740  p0=0.
1741  CALL splpr(n,w,b,p0,s2,p,irep)
1742  IF (irep.NE.0) THEN
1743  irep=-2
1744  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLP',1,zhook_handle)
1745  RETURN
1746  ENDIF
1747 ELSEIF (lissage.EQ.2) THEN
1748 ! Recherche de la valeur de P par la methode de G.C.V
1749  p0=0.
1750  CALL splpv(n,b,w,p0,p,irep)
1751  IF (irep.NE.0) irep=-3
1752 ! Calcul de la variance d'erreur de mesure correspondante
1753  CALL spls2v(b,w,n,p,s2)
1754 ELSEIF (lissage.EQ.3) THEN
1755 ! Calcul de l'ajustement correspondant a une valeur de P donnee
1756  CALL splrs(b,w,n,p,s2)
1757 ENDIF
1758 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLP',1,zhook_handle)
1759 
1760 END SUBROUTINE splp
1761 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1762 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1763 ! GROUPE DES PROCEDURES T et R
1764 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1765 !31. TT procedure
1766 SUBROUTINE spltt(X,DS,IW,TM,TT,IREP)
1767 !SPLR
1768 IMPLICIT NONE
1769 
1770 REAL,DIMENSION(:,:),INTENT(IN) :: x !ND,N
1771 REAL,DIMENSION(:),INTENT(IN) :: ds !N
1772 INTEGER,DIMENSION(:,:),INTENT(IN) :: iw !ND,M
1773 REAL,DIMENSION(:,:),INTENT(OUT) :: tm !N,M
1774 REAL,DIMENSION(:,:),INTENT(OUT) :: tt !M,M
1775 INTEGER, INTENT(OUT) :: irep
1776 
1777 REAL(KIND=JPRB) :: zhook_handle
1778 
1779 ! Calcul de la matrice T des monomes
1780 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLTT',0,zhook_handle)
1781  CALL splt(x,iw,tm)
1782 ! Calcul de Tm=(Ds-1)*T
1783  CALL mxidml(ds,tm,tm)
1784 ! Calcul de Tm'*Tm
1785  CALL mxmspl(transpose(tm),tm,tt)
1786 ! Calcul de (Tm'*Tm)-1
1787  CALL smxinv(tt,irep)
1788 ! Test du compte-rendu de smxinv
1789 IF (irep.NE.0) WRITE(*,fmt='(A27)') "SPLTT: MATRICE TT NON INVERSIBLE"
1790 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLTT',1,zhook_handle)
1791 
1792 END SUBROUTINE spltt
1793 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1794 !32. r procedure
1795 SUBROUTINE splr_1(NORD,X,DS,IW,TTT,R,IREP)
1796 !SP0NOP, SP0CVQ
1797 IMPLICIT NONE
1798 
1799 INTEGER,INTENT(IN) :: nord
1800 REAL,DIMENSION(:,:), INTENT(IN) :: x !ND,N
1801 REAL,DIMENSION(:),INTENT(IN) :: ds !N
1802 INTEGER,DIMENSION(:),INTENT(OUT) :: iw !ND
1803 REAL,DIMENSION(:),INTENT(OUT) :: ttt !N
1804 REAL,DIMENSION(:,:),INTENT(OUT) :: r !N,N
1805 INTEGER, INTENT(OUT)::irep
1806 
1807 INTEGER :: n, i, j
1808 REAL(KIND=JPRB) :: zhook_handle
1809 
1810 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLR_1',0,zhook_handle)
1811 n=SIZE(x,2)
1812 
1813 ! R = I
1814 DO i=1,n
1815  DO j=1,n
1816  IF (i.EQ.j) THEN
1817  r(i,i)=1.
1818  ELSE
1819  r(i,j)=0.
1820  ENDIF
1821  ENDDO
1822 ENDDO
1823 
1824 irep=0
1825 
1826 ! Calcul de (Ds-1)*R
1827  CALL mxidml(ds,r,r)
1828 
1829 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLR_1',1,zhook_handle)
1830 
1831 END SUBROUTINE splr_1
1832 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1833 !32.
1834 SUBROUTINE splr_2(NORD,X,DS,IW,TTT,R,IREP)
1835 
1836 IMPLICIT NONE
1837 
1838 INTEGER,INTENT(IN) :: nord
1839 REAL,DIMENSION(:,:), INTENT(IN) :: x !ND,N
1840 REAL,DIMENSION(:),INTENT(IN) :: ds !N
1841 INTEGER,DIMENSION(:,:),INTENT(OUT) :: iw !ND,M
1842 REAL,DIMENSION(:,:),INTENT(OUT) :: ttt !M,N
1843 REAL,DIMENSION(:,:),INTENT(OUT) :: r !N,N-M
1844 INTEGER, INTENT(OUT)::irep
1845 
1846 REAL,DIMENSION(SIZE(X,2),SIZE(X,2)) :: c !N,N
1847 REAL,DIMENSION(SIZE(X,2),SIZE(IW,2)) :: tm !N,M
1848 REAL,DIMENSION(SIZE(IW,2),SIZE(IW,2)) :: tt !M,M
1849 REAL, DIMENSION(SIZE(X,2),SIZE(X,2)) :: r1
1850 REAL,DIMENSION(SIZE(X,2)) :: vp !N
1851 REAL,DIMENSION(SIZE(X,2)) :: work !N
1852 INTEGER :: m, n, j
1853 INTEGER, DIMENSION(1) :: imin
1854 REAL(KIND=JPRB) :: zhook_handle
1855 
1856 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLR_2',0,zhook_handle)
1857 n=SIZE(x,2)
1858 m=SIZE(iw,2)
1859 
1860 ! Recherche des monomes de degre inferieur ou egal a nord-1
1861  CALL splie(nord-1,iw)
1862 !----------------------------------------------------------
1863 ! Calcul de la matrice (Tm'*Tm)-1
1864  CALL spltt(x,ds,iw,tm,tt,irep)
1865 ! Calcul de (T'm*Tm)-1 Tm'
1866  CALL mxmspl(tt,transpose(tm),ttt)
1867 !R1(:,1:M)=TRANSPOSE(TTT)
1868 !------------------------------------------------------------
1869 ! Calcul de Tm ((Tm'*Tm)-1) Tm'
1870  CALL mtxaxm(transpose(tm),tt,c)
1871 DO j=1,n
1872  c(j,j)=c(j,j)-1.
1873 ENDDO
1874  c(:,:)=-c(:,:)
1875 !-----------------------------------------------------------
1876 ! Calcul des vecteurs propres de I - Tm c ((Tm'*Tm)-1) c Tm'
1877  CALL eisrs1(c,vp,r1,work,irep)
1878 
1879 ! Test du signe des valeurs propres de C
1880 imin=minloc(vp(m+1:n))
1881 IF(vp(m+imin(1)).LE.0) THEN
1882  irep=-1
1883  WRITE(*,fmt='(A31)') "SPLR: VALEUR PROPRE < 0 DE PROJ"
1884  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLR_2',1,zhook_handle)
1885  RETURN
1886 ENDIF
1887 ! Compte-rendu OK
1888 irep=0
1889 ! Calcul de (Ds-1)*R
1890 r=r1(:,m+1:n)
1891  CALL mxidml(ds,r,r)
1892 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLR_2',1,zhook_handle)
1893 
1894 END SUBROUTINE splr_2
1895 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1896 ! GROUPE DES PROCEDURES U
1897 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1898 !33. U procedure
1899 SUBROUTINE splu(NORD,X,G,R,RK,U,DB)
1900 !SP0NOP, SP0CVQ
1901 IMPLICIT NONE
1902 
1903 INTEGER, INTENT(IN) :: nord
1904 REAL,DIMENSION(:,:), INTENT(IN) :: x !ND,N
1905 REAL,DIMENSION(:,:), INTENT(IN) :: g ! ND,ND
1906 REAL,DIMENSION(:,:), INTENT(IN) :: r !N,N-M
1907 REAL,DIMENSION(:,:), INTENT(OUT) :: rk !N,N
1908 REAL,DIMENSION(:,:), INTENT(OUT) :: u !N-M,N-M
1909 REAL,DIMENSION(:), INTENT(OUT) :: db !N-M
1910 
1911 REAL,DIMENSION(SIZE(R,2),SIZE(R,2)) :: rkr !N-M,N-M
1912 REAL,DIMENSION(SIZE(R,2)) :: work !N-M
1913 
1914 INTEGER :: m, n, irep
1915 INTEGER, DIMENSION(1) :: imin
1916 REAL(KIND=JPRB) :: zhook_handle
1917 
1918 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLU',0,zhook_handle)
1919 n=SIZE(x,2)
1920 m=SIZE(x,2)-SIZE(r,2)
1921 
1922 ! Calcul de la matrice K des noyaux
1923  CALL splk(nord,x,x,g,rk)
1924 ! Calcul de R'*K*R
1925  CALL mtxaxm(r,rk,rkr)
1926 ! Calcul de la matrice U des vecteurs propres de R'*K*R
1927  CALL eisrs1(rkr,db,u,work,irep)
1928 ! Test du signe des valeurs propres de R'KR
1929 imin=minloc(db)
1930 IF (db(imin(1)).LE.0) &
1931  WRITE(*,fmt='(A31)') "SPLU : VALEUR PROPRE < 0 DE RKR"
1932 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLU',1,zhook_handle)
1933 
1934 END SUBROUTINE splu
1935 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1936 ! GROUPE DES PROCEDURES W
1937 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1938 !34. w procedure
1939 SUBROUTINE splw(Z,R,U,W,RZ)
1940 !SP0NOP, SP0CVQ
1941 IMPLICIT NONE
1942 
1943 REAL,DIMENSION(:), INTENT(IN) :: z !N
1944 REAL, DIMENSION(:,:),INTENT(IN) :: r !N,N-M
1945 REAL,DIMENSION(:,:),INTENT(IN) :: u !N-M,N-M
1946 REAL, DIMENSION(:),INTENT(OUT) :: w !N-M
1947 REAL,DIMENSION(:),INTENT(OUT) :: rz !N-M
1948 
1949 INTEGER :: n, m
1950 REAL(KIND=JPRB) :: zhook_handle
1951 
1952 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLW',0,zhook_handle)
1953 n=SIZE(z)
1954 m=SIZE(z)-SIZE(r,2)
1955 
1956 ! Calcul de R'*Z
1957  CALL mxmspl(transpose(r),z,rz)
1958 ! Calcul de U'R'Z
1959  CALL mxmspl(transpose(u),rz,w)
1960 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLW',1,zhook_handle)
1961 
1962 END SUBROUTINE splw
1963 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1964 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1965 ! GROUPE DES PROCEDURES Q
1966 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1967 !35. splvpQ procedure
1968 SUBROUTINE splvpq(P,R,RK,U,DB,Q)
1969 !SP0CVQ
1970 IMPLICIT NONE
1971 
1972 REAL, INTENT(IN) :: p
1973 REAL, DIMENSION(:,:), INTENT(IN) :: r !N,N-M
1974 REAL, DIMENSION(:,:), INTENT(IN) :: rk ! N,N
1975 REAL, DIMENSION(:,:), INTENT(IN) :: u !N-M,N-M
1976 REAL, DIMENSION(:), INTENT(IN) :: db !N-M
1977 REAL, DIMENSION(:,:), INTENT(OUT) :: q ! N,N
1978 
1979 REAL, DIMENSION(SIZE(R,1),SIZE(R,1)):: q1 !N,N
1980 REAL, DIMENSION(SIZE(U,1),SIZE(U,2))::qw1,qw2 !N-M,N-M
1981 INTEGER :: n, j
1982 REAL(KIND=JPRB) :: zhook_handle
1983 
1984 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLVPQ',0,zhook_handle)
1985 n=SIZE(r,1)
1986 
1987 ! Calcul de (DB+n*p*I)-1
1988 qw1(:,:)=0.
1989 DO j=1,SIZE(db)
1990  qw1(j,j)=1./(db(j)+n*p)
1991 ENDDO
1992 
1993 ! Calcul de U((DB+n*p*I)-1)U'
1994  CALL mtxaxm(transpose(u),qw1,qw2)
1995 ! Calcul de RU((DB+n*p*I)-1))UR'
1996  CALL mtxaxm(transpose(r),qw2,q)
1997 ! Calcul de QK
1998  CALL mxmspl(q,rk,q1)
1999 
2000 ! Calcul de I - QK
2001 q1(:,:)=-q1(:,:)
2002 DO j=1,n
2003  q1(j,j)=q1(j,j)+1
2004 ENDDO
2005 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLVPQ',1,zhook_handle)
2006 
2007 END SUBROUTINE splvpq
2008 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2009 ! GROUPE DES PROCEDURES C
2010 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2011 !36.
2012 SUBROUTINE splc(Q,Z,RK,DS,TTT,RKC,C)
2013 !SP0NOP, SP0CVQ
2014 IMPLICIT NONE
2015 
2016 REAL, DIMENSION(:,:), INTENT(IN) :: q !Q(N,N)
2017 REAL, DIMENSION(:), INTENT(IN) :: z !Z(N)
2018 REAL, DIMENSION(:,:), INTENT(IN) :: rk !RK(N,n)
2019 REAL, DIMENSION(:), INTENT(IN) :: ds !DS(N)
2020 REAL, DIMENSION(:,:), INTENT(IN) :: ttt !TTT(M,N)
2021 REAL, DIMENSION(:), INTENT(OUT) :: rkc !RKC(N)
2022 REAL, DIMENSION(:), INTENT(OUT) :: c !C(N+M)
2023 REAL(KIND=JPRB) :: zhook_handle
2024 
2025 INTEGER :: n, m
2026 
2027 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLC',0,zhook_handle)
2028 n=SIZE(z)
2029 m=SIZE(ttt,1)
2030 
2031 ! Calcul de c
2032 ! -----------
2033 ! Calcul de c = Qz = R((R'KR+n*p*I)-1)R'z
2034  CALL mxmspl(q,z,c(1:n))
2035 
2036 ! Calcul de d
2037 ! -----------
2038 IF (m.NE.0) THEN
2039 ! Calcul de K*c
2040  CALL mxmspl(rk,c(1:n),rkc)
2041 ! Calcul de z - K*c
2042  rkc(:)=z(:)-rkc(:)
2043 ! Calcul de (Ds-1) * (z-K*c)
2044  rkc(:)=rkc(:)/ds(:)
2045 ! Calcul de d = (Tm'*Tm)-1 * Tm' * (Ds-1) * (z-K*c)
2046  CALL mxmspl(ttt,rkc,c(n+1:n+m))
2047 ENDIF
2048 
2049 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLC',1,zhook_handle)
2050 
2051 END SUBROUTINE splc
2052 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2053 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2054 ! PROCEDURES GLOBALES
2055 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2056 !37. Calcul de M en fonction de NORD et ND (qu'est-ce que c'est que ce ND?)
2057 SUBROUTINE splm(ND,NORD,M)
2058 !SP0NOP
2059 IMPLICIT NONE
2060 
2061 INTEGER, INTENT(IN) :: nd
2062 INTEGER, INTENT(IN) :: nord
2063 INTEGER, INTENT(OUT):: m
2064 REAL(KIND=JPRB) :: zhook_handle
2065 
2066 
2067 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLM',0,zhook_handle)
2068 IF (nd==1) THEN
2069  m=nord
2070 ELSEIF (nd==2) THEN
2071  m=nord*(nord+1)/2.
2072 ELSEIF (nd==3) THEN
2073  m=nord*(nord+1)*(nord+2)/6.
2074 ELSEIF (nd==4) THEN
2075  m=nord*(nord+1)*(nord+2)*(nord+3)/24.
2076 ENDIF
2077 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLM',1,zhook_handle)
2078 
2079 END SUBROUTINE splm
2080 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2081 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2082 !38.
2083 SUBROUTINE sp0nop(X,G,Z,DS,LISSAGE,LORDRE,IOPT,NORDOPT,M,S2,P,&
2084  iw,ttt,r,rk,u,db,w,rz,irep)
2085 !SP0CVQ
2086 IMPLICIT NONE
2087 
2088 REAL, DIMENSION(:,:), INTENT(IN) :: x !ND,N
2089 REAL, DIMENSION(:,:), INTENT(IN) :: g ! ND,ND
2090 REAL, DIMENSION(:), INTENT(IN) :: z ! N
2091 REAL, DIMENSION(:), INTENT(IN) :: ds ! N
2092 INTEGER, INTENT(IN) :: lissage
2093 INTEGER, INTENT(IN) :: lordre
2094 INTEGER, INTENT(IN) :: iopt
2095 INTEGER, INTENT(INOUT) :: nordopt
2096 INTEGER, INTENT(INOUT) :: m
2097 REAL, INTENT(INOUT) :: s2
2098 REAL, INTENT(INOUT) :: p
2099 INTEGER, DIMENSION(:,:), INTENT(OUT):: iw !ND,M
2100 REAL, DIMENSION(:,:), INTENT(OUT) :: ttt ! M,N
2101 REAL, DIMENSION(:,:), INTENT(OUT) :: r ! N,N-M
2102 REAL,DIMENSION(:,:), INTENT(OUT) :: rk !N,N
2103 REAL,DIMENSION(:,:), INTENT(OUT) :: u !N-M,N-M
2104 REAL,DIMENSION(:), INTENT(OUT) :: db !N-M
2105 REAL, DIMENSION(:),INTENT(OUT) :: w !N-M
2106 REAL,DIMENSION(:),INTENT(OUT) :: rz !N-M
2107 INTEGER, INTENT (OUT) :: irep
2108 
2109 
2110 REAL, DIMENSION(NORDMAX) :: vm, s2save, psave, msave
2111 INTEGER :: n, nd
2112 INTEGER :: nordmi, nordma, nordm, nord
2113 REAL :: vmmin
2114 REAL(KIND=JPRB) :: zhook_handle
2115 
2116 IF (lhook) CALL dr_hook('MODE_SPLINES:SP0NOP',0,zhook_handle)
2117 n=SIZE(x,2)
2118 nd=SIZE(x,1)
2119 
2120 IF (lordre.EQ.0) THEN
2121 !
2122 ! Recherche de p seulement avec nord fixe
2123 ! ---------------------------------------
2124  IF (iopt.EQ.0) THEN
2125 ! Calcul de IW, TTT, R
2126  CALL splr(nordopt,x,ds,iw,ttt,r,irep)
2127 ! Calcul de RK, U, DB
2128  CALL splu(nordopt,x,g,r,rk,u,db)
2129  ENDIF
2130  !calcul de W, RZ
2131  CALL splw(z,r,u,w,rz)
2132  !calcul de P
2133  CALL splp(lissage,n,db,w,p,s2,irep)
2134 
2135 ELSE
2136 
2137 ! Recherche de nordopt et popt
2138 ! ----------------------------
2139 
2140  nordmi=nd/2+1
2141 
2142 ! Calcul de l'ordre maximal pour le nombre de points n
2143  CALL splm(nd,nord,m)
2144  DO WHILE(n.GT.m)
2145  nord=nord+1
2146  CALL splm(nd,nord,m)
2147  ENDDO
2148  nordma=min(nord,nordmax)
2149  nordm=nordma
2150 
2151 ! Calcul de Vm pour les differents ordre
2152  DO nord=nordmi,nordma
2153  !calcul de M
2154  CALL splm(nd,nord,m)
2155  CALL splr(nord,x,ds,iw,ttt,r,irep)
2156  CALL splu(nord,x,g,r,rk,u,db)
2157  CALL splw(z,r,u,w,rz)
2158  CALL splp(lissage,n,db,w,p,s2,irep)
2159  msave(nord)=m
2160  s2save(nord)=s2
2161  psave(nord)=p
2162  IF (irep.EQ.0) THEN
2163  !calcul de VM(NORD)
2164  CALL splv(db,w,n,p,vm(nord))
2165  WRITE(*,fmt='(A15,I5,A5,G15.5,A6,G15.5)')&
2166  "CNORD : NORD = ",nord," P = ",p," VM = ",vm(nord)
2167  ELSE
2168  IF (nord.EQ.nordmi) THEN
2169  nordopt=nord
2170  IF (lhook) CALL dr_hook('MODE_SPLINES:SP0NOP',1,zhook_handle)
2171  RETURN
2172  ELSE
2173  nordm=nord-1
2174  irep=0
2175  EXIT
2176  ENDIF
2177  ENDIF
2178  ENDDO
2179 
2180 ! Recherche de l'ordre optimal
2181  vmmin=xsurf_huge
2182  DO nord=nordmi,nordm
2183  IF(vm(nord).LT.vmmin) THEN
2184  vmmin=vm(nord)
2185  nordopt=nord
2186  m=msave(nord)
2187  s2=s2save(nord)
2188  p=psave(nord)
2189  ENDIF
2190  ENDDO
2191  WRITE(*,fmt='(A24,I5)') "CNORD : ORDRE OPTIMAL = ",nordopt
2192 ENDIF
2193 IF (lhook) CALL dr_hook('MODE_SPLINES:SP0NOP',1,zhook_handle)
2194 
2195 END SUBROUTINE sp0nop
2196 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2197 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2198 !39.
2199 SUBROUTINE sp0cvq(NORD,M,X,G,Z,DS,S2,P,LISSAGE,LORDRE,IOPT,C,IREP)
2200 !SPLB2C
2201 IMPLICIT NONE
2202 
2203 INTEGER, INTENT(INOUT) :: nord
2204 INTEGER, INTENT(INOUT) :: m
2205 REAL,DIMENSION(:,:), INTENT(IN) :: x !ND,N
2206 REAL, DIMENSION(:,:), INTENT(IN) :: g !ND,ND
2207 REAL,DIMENSION(:), INTENT(IN) :: z ! N
2208 REAL, DIMENSION(:), INTENT(IN) :: ds !N
2209 REAL, INTENT(INOUT) :: s2
2210 REAL, INTENT(INOUT) :: p
2211 INTEGER, INTENT(IN) :: lissage
2212 INTEGER, INTENT(IN) :: lordre
2213 INTEGER, INTENT(IN) :: iopt
2214 REAL, DIMENSION(:), INTENT(OUT) :: c !N+M
2215 INTEGER, INTENT(OUT) :: irep
2216 
2217 INTEGER, DIMENSION(SIZE(X,1),SIZE(C)-SIZE(X,2)) :: iw
2218 REAL, DIMENSION(SIZE(C)-SIZE(X,2),SIZE(X,2)) :: ttt ! M,N
2219 REAL, DIMENSION(SIZE(X,2),2*SIZE(X,2)-SIZE(C)) :: r ! N,N-M
2220 REAL,DIMENSION(SIZE(X,2),SIZE(X,2)) :: rk !N,N
2221 REAL,DIMENSION(2*SIZE(X,2)-SIZE(C),2*SIZE(X,2)-SIZE(C)) :: u !N-M,N-M
2222 REAL,DIMENSION(2*SIZE(X,2)-SIZE(C)):: db !N-M
2223 REAL, DIMENSION(2*SIZE(X,2)-SIZE(C)) :: w !N-M
2224 REAL,DIMENSION(SIZE(R,2)) :: rz !N-M
2225 REAL, DIMENSION(SIZE(X,2),SIZE(X,2)) :: q ! N,N
2226 REAL :: rn
2227 REAL, DIMENSION(SIZE(X,2)) :: rkc !RKC(N)
2228 
2229 
2230 INTEGER :: n
2231 REAL(KIND=JPRB) :: zhook_handle
2232 
2233 IF (lhook) CALL dr_hook('MODE_SPLINES:SP0CVQ',0,zhook_handle)
2234 n=SIZE(x,2)
2235 
2236 ! Test des differents parametres
2237 IF (nord.LT.1) THEN
2238  WRITE(*,fmt='(A17)') "SP0CVQ : NORD < 1"
2239 ELSEIF (m.LT.0) THEN
2240  WRITE(*,'(A14)') "SP0CVQ : M < 0"
2241 ELSEIF (n.LT.m) THEN
2242  WRITE(*,'(A14)') "SP0CVQ : N < M"
2243 ELSEIF (s2.LT.0.) THEN
2244  WRITE(*,'(A15)') "SP0CVQ : S2 < 0"
2245 ELSEIF (p.LT.0.) THEN
2246  WRITE(*,'(A14)') "SP0CVQ : P < 0"
2247 ELSEIF ((lissage.LT.0.OR.lissage.GT.3).AND.lissage.NE.10) THEN
2248  WRITE(*,'(A27)') "SP0CVQ : LISSAGE < 0 OU > 3"
2249 ELSEIF (lordre.LT.0.OR.lordre.GT.1) THEN
2250  WRITE(*,'(A26)') "SP0CVQ : LORDRE < 0 OU > 1"
2251 ELSEIF (iopt.LT.0.OR.iopt.GT.1) THEN
2252  WRITE(*,'(A24)') "SP0CVQ : IOPT < 0 OU > 1"
2253 ELSE
2254 
2255 ! Determination de nord opt ou de p pot
2256 ! -----------------------------------------
2257  IF (lordre.EQ.1 .OR. &
2258  lissage.EQ.1 .OR. lissage.EQ.2 .OR. lissage.EQ.10) THEN
2259  !calcul de P en passant par SPLR, SPLU, SPLW, si LORDRE = 0
2260  !calcul de NORD, M, S2, P si LORDRE=1
2261  CALL sp0nop(x,g,z,ds,lissage,lordre,iopt,nord,m,s2,p,&
2262  iw,ttt,r,rk,u,db,w,rz,irep)
2263  ELSEIF (lissage.EQ.0) THEN
2264  p=0.
2265  ENDIF
2266 !---------------------------------------------------------------------
2267 !---------------------------------------------------------------------
2268 
2269  IF (lordre.EQ.1 .OR. lissage.EQ.0 .OR. lissage.EQ.3) THEN
2270  IF (iopt.EQ.0) THEN
2271 ! Calcul de IW, TTT, R
2272  CALL splr(nord,x,ds,iw,ttt,r,irep)
2273  IF (irep.NE.0 .AND. lhook) CALL dr_hook('MODE_SPLINES:SP0CVQ',1,zhook_handle)
2274  IF (irep.NE.0) RETURN
2275 ! Calcul de RK, U, DB
2276  CALL splu(nord,x,g,r,rk,u,db)
2277  ENDIF
2278 !---------------------------------------------------------------------
2279 ! Calcul de W,RZ
2280  CALL splw(z,r,u,w,rz)
2281 ! Calcul de S2 pour lissage=3
2282  IF (lissage.EQ.3) CALL splrs(db,w,n,p,s2)
2283  ENDIF
2284 
2285 !---------------------------------------------------------------------
2286 !---------------------------------------------------------------------
2287 ! Calcul de Q
2288  CALL splvpq(p,r,rk,u,db,q)
2289 ! Calcul de RN
2290  CALL splbvm(db,w,n,p,rn)
2291 ! Calcul des coefficients C et RKC
2292  CALL splc(q,z,rk,ds,ttt,rkc,c)
2293  IF (lhook) CALL dr_hook('MODE_SPLINES:SP0CVQ',1,zhook_handle)
2294  RETURN
2295 
2296 ENDIF
2297 
2298 irep=-1
2299 IF (lhook) CALL dr_hook('MODE_SPLINES:SP0CVQ',1,zhook_handle)
2300 
2301 END SUBROUTINE sp0cvq
2302 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2303 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2304 !40. AI(ND,ND,NSDMAX): calcul de AI en fonction de XD, NSD, INTER;
2305 !remarque: on dirait que la deuxième dimension de AI est plutôt 2 que ND
2306 SUBROUTINE splbsd(NSD,INTER,XD,AI)
2307 !SPLB2C
2308 IMPLICIT NONE
2309 
2310 INTEGER, DIMENSION(:), INTENT(IN) :: nsd
2311 INTEGER, INTENT(IN) :: inter
2312 REAL, DIMENSION(:,:), INTENT(IN) :: xd
2313 REAL, DIMENSION(:,:,:), INTENT(OUT) :: ai
2314 REAL(KIND=JPRB) :: zhook_handle
2315 
2316 REAL, DIMENSION(SIZE(NSD)) :: dxi, dxr
2317 INTEGER :: j, i
2318 
2319 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBSD',0,zhook_handle)
2320 DO j=1,SIZE(nsd)
2321  dxi(j)=(xd(2,j)-xd(1,j))/nsd(j)
2322  dxr(j)=dxi(j)/(2*inter-2)
2323 ENDDO
2324 
2325 DO j=1,SIZE(nsd)
2326  ai(j,1,1)=xd(1,j)
2327  DO i=2,nsd(j)
2328  ai(j,1,i)=xd(1,j)+(i-1)*dxi(j)-dxr(j)
2329  ENDDO
2330  ai(j,2,nsd(j))=xd(2,j)
2331  DO i=1,nsd(j)-1
2332  ai(j,2,i)=xd(2,j)-(nsd(j)-i)*dxi(j)+dxr(j)
2333  ENDDO
2334 ENDDO
2335 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBSD',1,zhook_handle)
2336 
2337 END SUBROUTINE splbsd
2338 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2339 !41. récupère les X et Z tels que les valeurs soient toutes comprises entre
2340 !A et B, dans XS et ZS. NS est la taille finale des tableaux.
2341 SUBROUTINE splbsel(X,Z,AI,BI,NS,XS,ZS,IREP)
2342 !SPLB2C
2343 IMPLICIT NONE
2344 
2345 REAL, DIMENSION(:,:), INTENT(IN) :: x !ND,N
2346 REAL, DIMENSION(:), INTENT(IN) :: z !N
2347 REAL, DIMENSION(:), INTENT(IN) :: ai !ND
2348 REAL, DIMENSION(:), INTENT(IN) :: bi !ND
2349 INTEGER, INTENT(OUT) :: ns
2350 REAL, DIMENSION(:,:), INTENT(OUT) :: xs !ND,NMAX
2351 REAL, DIMENSION(:), INTENT(OUT) :: zs !NMAX
2352 INTEGER, INTENT(OUT) :: irep
2353 
2354 INTEGER :: i, j, i0
2355 REAL(KIND=JPRB) :: zhook_handle
2356 
2357 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBSEL',0,zhook_handle)
2358 irep=0
2359 ns=0
2360 DO j=1,SIZE(x,2)
2361  i0=0
2362  DO i=1,SIZE(x,1)
2363  !il faut que tous les X(I,J) soient compris entre AI et BI
2364  IF (x(i,j).LT.ai(i).OR.x(i,j).GT.bi(i)) THEN
2365  i0=1
2366  EXIT
2367  ENDIF
2368  ENDDO
2369  IF (i0.NE.1) THEN
2370  ns=ns+1
2371  IF (ns.GT.SIZE(zs)) THEN
2372  irep=-1
2373  IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBSEL',1,zhook_handle)
2374  RETURN
2375  ENDIF
2376  DO i=1,SIZE(x,1)
2377  xs(i,ns)=x(i,j)
2378  ENDDO
2379  zs(ns)=z(j)
2380  ENDIF
2381 ENDDO
2382 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLBSEL',1,zhook_handle)
2383 
2384 END SUBROUTINE splbsel
2385 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2386 !42. appelée par INTERPOL_SPLINES
2387 SUBROUTINE splb2c(NORD,M,X,G,Z,S2,P,LISSAGE,IOPT,NSDI,NSDJ,&
2388  inter,xd,c,irep)
2389 !INTERPOL_SPLINES
2390 IMPLICIT NONE
2391 
2392 INTEGER, INTENT(INOUT) :: nord
2393 INTEGER, INTENT(INOUT) :: m
2394 REAL, DIMENSION(:,:), INTENT(IN) :: x !ND,N
2395 REAL, DIMENSION(:,:), INTENT(IN) :: g ! ND,ND
2396 REAL, DIMENSION(:), INTENT(IN) :: z !N
2397 REAL, INTENT(INOUT) :: s2
2398 REAL, INTENT(INOUT) :: p
2399 INTEGER, INTENT(IN) :: lissage
2400 INTEGER, INTENT(IN) :: iopt
2401 INTEGER, INTENT(IN) :: nsdi
2402 INTEGER, INTENT(IN) :: nsdj
2403 INTEGER, INTENT(IN) :: inter
2404 REAL, DIMENSION(:,:), INTENT(IN) :: xd !2,ND
2405 REAL, DIMENSION(:,:,:), INTENT(OUT) :: c !nmax+mmax,nsdi,nsdj
2406 INTEGER, INTENT(OUT) :: irep
2407 !
2408 INTEGER :: nn, nd
2409 INTEGER :: lordre, i, j
2410 INTEGER, DIMENSION(2) :: nsd
2411 REAL, DIMENSION(NMAX) :: ds
2412 REAL, DIMENSION(2,2) :: ci
2413 
2414 REAL(KIND=JPRB) :: zhook_handle
2415 
2416 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLB2C',0,zhook_handle)
2417 nd=SIZE(x,1)
2418 IF (.NOT.ALLOCATED(ai)) ALLOCATE(ai(nd,2,nsdmax))
2419 IF (.NOT.ALLOCATED(ns)) ALLOCATE(ns(nsdmax,nsdmax))
2420 IF (.NOT.ALLOCATED(zs)) ALLOCATE(zs(nmax,nsdmax,nsdmax))
2421 IF (.NOT.ALLOCATED(xs)) ALLOCATE(xs(nd,nmax,nsdmax,nsdmax))
2422 
2423 ! Initialisation de Ds
2424 ds(:)=1.
2425 
2426 ! Generation des sous-domaines: matrice AI de MODD_SPLINES
2427 nsd(1)=nsdi
2428 nsd(2)=nsdj
2429  CALL splbsd(nsd,inter,xd,ai)
2430 
2431 lordre=0
2432 
2433 ! Calcul des splines par sous-domaines
2434 DO i=1,nsdi
2435  DO j=1,nsdj
2436  ci(1,1)=ai(1,1,i)
2437  ci(1,2)=ai(1,2,i)
2438  ci(2,1)=ai(2,1,j)
2439  ci(2,2)=ai(2,2,j)
2440  !selection des points
2441  CALL splbsel(x,z,ci(:,1),ci(:,2),ns(i,j),xs(:,:,i,j),zs(:,i,j),irep)
2442  IF (irep.NE.0) THEN
2443  WRITE(*,fmt='(A35)') "SPLB2C: NOMBRE DE POINTS TROP GRAND"
2444  irep=-4
2445  CALL abor1_sfx('SPLINES: SPLB2C: NOMBRE DE POINTS TROP GRAND')
2446  ELSEIF (ns(i,j).LE.m) THEN
2447  WRITE(*,fmt='(A42)') &
2448  "SPB2C : NB DE PTS <= M : COEF NON CALCULES"
2449  ENDIF
2450  !calcul de la spline
2451  IF (ns(i,j).GT.m) THEN
2452  nn=ns(i,j)
2453  !X(ND,NN) ZS(NN) C(NN+M) IW(ND,M) W(7*NN*NN)
2454  CALL sp0cvq(nord,m,xs(:,1:nn,i,j),g,zs(1:nn,i,j),ds(1:nn),s2,p,&
2455  lissage,lordre,iopt,c(1:nn+m,i,j),irep)
2456  ENDIF
2457  ENDDO
2458 ENDDO
2459 IF (lhook) CALL dr_hook('MODE_SPLINES:SPLB2C',1,zhook_handle)
2460 
2461 END SUBROUTINE splb2c
2462 
2463 
2464 END MODULE mode_splines
subroutine splk_1(NORD, X1, X2, G, RK)
subroutine splk_2(NORD, X1, X2, G, RK)
subroutine splr_1(NORD, X, DS, IW, TTT, R, IREP)
subroutine splr_2(NORD, X, DS, IW, TTT, R, IREP)
subroutine sscopy_2(A, B, IA, IB)
subroutine splt_1(X, IE, T)
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:6
subroutine mxmspl_1(A, B, R)
subroutine sscopy_1(A, B, IA, IB)
subroutine mxmspl_2(A, B, R)
subroutine splt_2(X, IE, T)
subroutine mxmspl_3(A, B, RES)
subroutine splpr0(B, W, N, S2, P)