summaryrefslogtreecommitdiff
path: root/modules/cacsd/src/fortran/domout.f
blob: 6dabb9a2d64b866107517ea0d714ecfc6ba3165e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
      subroutine domout(neq,q,qi,nbout,ti,touti,itol,rtol,atol,itask

c Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
c Copyright (C) INRIA
c 
c This file must be used under the terms of the CeCILL.
c This source file is licensed as described in the file COPYING, which
c you should have received as part of this distribution.  The terms
c are also available at    
c http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt

     $     ,istate,iopt,w,lrw,iw,liw,jacl2,mf,job)
C!but
C     Etant sortie du domaine d'integration au cours
C     de l'execution de la routine Optm2, il s'agit ici de
C     gerer ou d'effectuer l'ensemble des taches necessaires
C     a l'obtention du point de la face par lequel la
C     'recherche' est passee.
C!liste d'appel
C     subroutine domout(neq,q,qi,nbout,ti,touti,itol,rtol,atol,itask,
C    *     istate,iopt,w,lrw,iw,liw,jacl2,mf,job)
C
C     double precision  atol(neq(1)+1),rtol(neq(1)+1),q(neq(1)+1),
C    *                  qi(neq(1)+1)
C     double precision w(*),iw(*)
C
C     Entree :
c     - neq. tableau entier de taille 3+(nq+1)*(nq+2)
c         neq(1)=nq est le degre effectif du polynome q
c         neq(2)=ng est le nombre de coefficient de fourier
c         neq(3)=dgmax degre maximum pour q (l'adresse des coeff de 
c               fourier dans tq est neq(3)+2
c         neq(4:(nq+1)*(nq+2)) tableau de travail entier
c     - tq. tableau reel de taille au moins
c               7+dgmax+5*nq+6*ng+nq*ng+nq**2*(ng+1)
c         tq(1:nq+1) est le tableau des coefficients du polynome q.
c         tq(dgmax+2:dgmax+ng+2) est le tableau des coefficients
c                      de fourier
c         tq(dgmax+ng+3:) est un tableau de travail de taille au moins
c                         5+5*nq+5*ng+nq*ng+nq**2*(ng+1)
c
C     - toutes les variables et tableaux de variables necessaires a 
C               l'execution de la routine Lsode
C     - qi. est le dernier point obtenu de la trajectoire
C        qui soit a l'interieur du domaine.
C     - q(1:nq+1). est celui precedemment calcule, qui se situe a
C       l'exterieur.
C
C     Sortie :
C     - q(1:nq+1). est cense etre le point correspondant a l'inter-
C        section entre la face et la trajectoire.
C     - job. est un parametre indiquant si le franchissement
C            est verifie.
C            si job=-1 pb de detection arret requis
C
C     Tableaux de travail
C     - w : 24+22*nq+ng+nq**2
C     - iw : 20+nq
C!
      implicit double precision (a-h,o-z)
      dimension atol(*), rtol(*), w(*), iw(*), q(*),
     &          qi(*), xx(1)

      integer neq(*)
      external feq, jacl2
      common /sortie/ io,info,ll
C
      nq=neq(1)
      ng=neq(2)
      nqmax=neq(3)
c
      lq=1
      ltg=lq+nqmax+1
c
      lrw=nq**2 + 9*nq + 22
      liw=20+nq
c

      lrwork = 1
      lw     = lrwork + nq**2 + 9*nq + 22
      lqex   = lw+12*nq+ng+1
      free   = lqex + nq + 1

C
      tout = touti
      nboute = 0
C
C     --- Etape d'approche de la frontiere ----------------------------
C
      kmax = int(log((tout-ti)/0.006250d+0)/log(2.0d+0))
      k0 = 1
      if (info .gt. 1) call outl2(40,nq,kmax,xx,xx,x,x)
 314  do 380 k = k0,kmax
        tpas = (tout-ti) / 2.0d+0
        if (nbout .gt. 0) then
          istate = 1
          call dcopy(nq+1,qi,1,q,1)
          t = ti
          tout = ti + tpas
        else
          call dcopy(nq+1,q,1,qi,1)
          ti = t
          tout = ti + tpas
        endif
 340    if (info .gt. 1) call outl2(41,nq,nq,q,xx,t,tout)
        tsave=t
        call lsode(feq,neq,q,t,tout,itol,rtol,atol,itask,istate,iopt,
     &             w(lrwork),lrw,iw,liw,jacl2,mf)
        if (info .gt. 1) call outl2(42,nq,nq,q,xx,t,tout)
        if (istate.eq.-1 .and. t.ne.tout) then
          if (info .gt. 1) call outl2(43,nq,nq,xx,xx,x,x)
           if (t.le.tsave) then
              job=-1
              return
           endif
          istate = 2
          goto 340
        endif
        call front(nq,q,nbout,w(lw))
        if (info .gt. 1) call outl2(44,nq,nbout,xx,xx,x,x)
        if (nbout .gt. 0) then
          nboute = nbout
          call dcopy(nq+1,q,1,w(lqex),1)
        endif
        if (istate .lt. 0) then
          if (info .gt. 1) call outl2(45,nq,istate,xx,xx,x,x)
          job = -1
          return
        endif
        if (k.eq.kmax .and. nboute.eq.0 .and. tout.ne.touti) then
          tout = touti
          goto 340
        endif
 380  continue
c
      if (nboute .eq. 0) then
        job = 0
        return
      elseif (nboute .gt. 2) then
        newrap = 1
        nqsav = nq
        goto 390
      endif
C
      call watfac(nq,w(lqex),nface,newrap,w(lw))
      if (newrap .eq. 1) goto 390
C
      nqsav = nq
      call onface(nq,q,q(ltg),ng,nface,ierr,w(lw))
      if (ierr .ne. 0) then
        job = -1
        return
      endif
      yi = phi(qi,nqsav,q(ltg),ng,w(lw))
      yf = phi(q,nq,q(ltg),ng,w(lw))
C
      eps390 = 1.0d-08
      if (yi .lt. (yf-eps390)) then
        newrap = 1
        goto 390
      endif
C
      if (info .gt. 1) call outl2(46,nq,nface,q,xx,yi,yf)
C
      newrap = 0
C
 390  if (newrap .eq. 1) then
        nq = nqsav
        k0 = kmax
        kmax = kmax + 1
        nbout = 1
        if(ti + 2*tpas.le.ti) then
           job=-1
           return
        endif
        tout = ti + 2*tpas
        if (info .gt. 1) call outl2(47,nq,nq,xx,qi,x,x)
        goto 314
      endif
C
      neq(1)=nq
      job = 1
      return
C
      end