2
c ====================================================================
3
c impl dassl dasrt : simulation de systeme algebrico-differentiel
4
c ====================================================================
10
write(buf(1:4),'(i4)') fin
11
call basout(io,wte,' matimp '//buf(1:4))
17
10 call sciimpl("impl")
19
100 call dassli("dassl")
21
1000 call dasrti("dasrt")
25
subroutine sciimpl(fname)
26
c ==================================================
32
double precision atol,rtol,t0,t1
35
external bresid,badd,bj2
36
external fres,fadda,fj2
38
logical getexternal,getrvect,vcopyobj
39
logical checkrhs,checklhs,getrmat,cremat,getscalar
40
logical typej,typea,typer,getsmat,vectsize
41
character*(nlgh+1) namres,namadd,namjac
44
external setfres,setfadda,setfj2
47
data atol/1.d-7/,rtol/1.d-9/
51
if (.not.checkrhs(fname,6,10)) return
52
C XXXXXX : pour l'instant
53
if (.not.checklhs(fname,1,3)) return
54
c ---------------------------------
60
c first argument (check for string )
61
c ----------------------------
62
if(gettype(topk-rhs+1).eq.10) then
64
if(.not.getsmat(fname,topk,topk-rhs+1,
65
$ m1,n1,1,1,lr1,nlr1))return
66
call cvstr(1,istk(lr1),strf,1)
67
if ( strf.eq.'a') mf = 10
68
if ( strf.eq.'s') mf = 20
69
if(strf.ne.'a'.and.strf.ne.'s') then
74
c Initial condition : y0 arg 2 - iskip
76
kynew=topk-rhs+2-iskip
77
if(.not.getrvect(fname,topk,kynew,ny,my,ly))return
80
c Initial derivative condition : y0dot arg 3 - iskip
82
kydtop=topk-rhs+3-iskip
83
if(.not.getrvect(fname,topk,kydtop,nyd,myd,lyd))return
84
if(.not.vectsize(fname,topk,kydtop,ny*my)) return
86
c ----------------------------
87
kttop=topk-rhs+4-iskip
88
if(.not.getscalar(fname,topk,kttop,lr4))return
91
c ---------------------------
93
if(.not.getrmat(fname,topk,kt1,m5,n5,lt5))return
95
c checking variable rtol (number 6 - iskip)
96
c -----------------------------------
97
itype = gettype(topk-rhs+6-iskip)
98
if ( itype .ne. 1) then
99
if (.not.cremat(fname,topw,0,1,1,latol,lc)) return
101
if (.not.cremat(fname,topw,0,1,1,lrtol,lc)) return
111
if(.not.getrvect(fname,topk,kr,m6,n6,lrtol))return
113
if(nr.ne.1.and.nr.ne.neq) then
119
c checking variable rtol (number 7 - iskip )
120
c --------------------------------
121
itype = gettype(topk-rhs+7-iskip)
122
if (itype .ne. 1) then
123
if (.not.cremat(fname,topw,0,1,1,lrtol,lc)) return
131
if(.not.getrvect(fname,topk,kr,m7,n7,latol))return
133
if(na.ne.1.and.na.ne.neq) then
138
c ----------------------------------
139
11105 if(nr.eq.1.and.na.eq.1) itol=1
140
if(nr.eq.1.and.na.gt.1) itol=2
141
if(nr.gt.1.and.na.eq.1) itol=3
142
if(nr.gt.1.and.na.gt.1) itol=4
143
c les externaux : res,adda et jac
144
c -----------------------------------
145
c checking variable res (number 8 - iskip )
146
kres=topk-rhs+8-iskip
148
if (.not.getexternal(fname,topk,kres,namres,typer,
151
c checking variable number 9 - iskip
152
c -----------------------------
153
kadd=topk-rhs+9-iskip
154
if (.not.getexternal(fname,topk,kadd,namadd,typea,
156
if ( typea.neqv.typer) then
157
buf = fname // ': res and adda must have same type '
160
c checking variable number 10 - iskip
161
c -----------------------------
162
achaud=gettype(topk).eq.1
163
kjac=topk-rhs+10-iskip
164
if ( kjac.eq.topk.or.(achaud.and.kjac.eq.topk-2)) then
165
if (.not.getexternal(fname,topk,kjac,namjac,typej,
181
c hot restart is detected when last argument is a matrix
182
c ---------------------
184
if(.not.cremat(fname,topw,0,neq,nn,lres,lc)) return
191
if (.not.vcopyobj(fname,topk,topw)) return
193
if(.not.getrmat(fname,topk,topw-1,ml,nl,lci))return
196
do 400 k= liwp -nsizi+1 , liwp
197
write(06,*) k,'avant sauv iw',stk(lci+k-1)
200
if (.not.vcopyobj(fname,topk-1,topw)) return
202
if(.not.getrmat(fname,topk,topw-1,ml,nl,lrwp))return
205
c restauration des commons
206
lsavs=lrwp+ilrw- nsizd
207
lsavi=lci+liwp- nsizi
209
call rscom1(stk(lsavs),stk(lsavi))
210
c restauration du tableau entier
211
c the end was used to restore the common
213
istk(ilc+k-1)=int(stk(lci+k-1))
217
c ----create Work space
219
if(mf.gt.10) ilrw=22+16*neq+neq*neq
220
if(mf.gt.20) ilrw=22+9*neq+neq*neq
226
if(.not.cremat(fname,topw,0,1,liwp,li,lc)) return
232
if(.not.cremat(fname,topw,0,1,ilrw,lrwp,lc)) return
258
lstk(top+1)=sadr(ilw1+17)
274
lstk(top+1)=sadr(ilw1+11)
280
c appel de l'integrateur
283
c test sur le type des fonctions fournies
286
c f fortran j fortran
287
call lsodi(fres,fadda,fj2,neq,stk(ly),stk(lyd),t0,t1,
288
1 itol,stk(lrtol),stk(latol),itask,istate,iopt,
289
2 stk(lrwp),ilrw,istk(ilc),liwp,mf)
292
call lsodi(fres,fadda,bj2,neq,stk(ly),stk(lyd),t0,t1,
293
1 itol,stk(lrtol),stk(latol),itask,istate,iopt,
294
2 stk(lrwp),ilrw,istk(ilc),liwp,mf)
299
call lsodi(bresid,badd,fj2,neq,stk(ly),stk(lyd),t0,t1,
300
1 itol,stk(lrtol),stk(latol),itask,istate,iopt,
301
2 stk(lrwp),ilrw,istk(ilc),liwp,mf)
304
call lsodi(bresid,badd,bj2,neq,stk(ly),stk(lyd),t0,t1,
305
1 itol,stk(lrtol),stk(latol),itask,istate,iopt,
306
2 stk(lrwp),ilrw,istk(ilc),liwp,mf)
314
call unsfdcopy(neq,stk(ly),1,stk(lres+(k-1)*neq),1)
317
call copyobj(fname,kresu,topk-rhs+1)
321
buf = fname // ' lhs can only be 1 or 2 '
325
if (.not.cremat(fname,top,0,1,ilrw,lr,lc)) return
326
call unsfdcopy(ilrw-nsizd,stk(lrwp),1,stk(lr),1)
330
if (.not.cremat(fname,top,0,1,liwp,lr,lc)) return
332
stk(lr+k-1)=dble(istk(ilc+k-1))
335
call svcom1(stk(lsvs),stk(lsvi))
339
subroutine dassli(fname)
341
c ============================================
345
integer topk,topw, info(15),gettype
346
logical hotstart,getexternal,getrvect,type
347
logical checkrhs,checklhs,getrmat,cremat,getscalar
348
double precision tout,tstop,maxstep,stepin
349
double precision atol,rtol,t0
350
character*(nlgh+1) namer,namej,names
351
character*(nlgh+1) namjac
353
external setfresd,setfjacd
354
common /dassln/ namer,namej,names
358
data atol/1.d-7/,rtol/1.d-9/
363
c SCILAB function : dassl
364
c --------------------------
365
c [y0 [,hotdata]]=dassl(y0,t0,t1 [,atol,rtol],res [,jac],info..
374
if (.not.checkrhs(fname,4,9)) return
375
if (.not.checklhs(fname,1,2)) return
376
c checking variable y0 (number 1)
377
c -------------------------------
379
if(.not.getrmat(fname,topk,ky,n1,m1,l1))return
384
if (.not.cremat(fname,topw,0,n1,1,lydot,lc)) return
387
call dset(n1,0.0d0,stk(lydot),1)
393
il1 = iadr(lstk(top-rhs+1))
396
c checking variable t0 (number 2)
397
c -------------------------------
399
if(.not.getscalar(fname,topk,kt0,lr2))return
401
c checking variable t1 (number 3)
402
c -------------------------------
403
if(.not.getrmat(fname,topk,top-rhs+3,m3,n3,l3))return
406
c checking variable atol (number 4)
407
c -------------------------------
409
itype = gettype(top-rhs+4)
410
if ( itype .ne. 1) then
411
if (.not.cremat(fname,topw,0,1,1,latol,lc)) return
413
if (.not.cremat(fname,topw,0,1,1,lrtol,lc)) return
421
if(.not.getrvect(fname,topk,top-rhs+4,m4,n4,latol))return
423
c checking variable rtol (number 5)
424
c --------------------------------
425
itype = gettype(top-rhs+5)
426
if (itype .ne. 1) then
427
if (.not.cremat(fname,topw,0,1,1,lrtol,lc)) return
434
if(.not.getrvect(fname,topk,top-rhs+5,m5,n5,lrtol))return
445
c checking variable res (number 6)
447
105 kres=top-rhs+6-iskip
448
if (.not.getexternal(fname,topk,kres,namer,type,
450
c checking variable jac (number 7)
459
c . info or jac ? get list size to decide
461
if (istk(il6).lt.0) il6=istk(il6+1)
462
if (istk(il6+1).eq.2) then
468
if((isres.ne.10).and.(isres.ne.11).and.(isres.ne.13)) then
473
if (.not.getexternal(fname,topk,kjac,namej,type,
478
c checking variable info (number 8)
479
c ---------------------------------
480
kinfo=top-rhs+8-iskip
481
if (kinfo.gt.top) then
492
il8 = iadr(lstk(top-rhs+8-iskip))
493
if (istk(il8) .ne. 15) then
494
c default info values
508
c -- subvariable tstop(info) --
509
il8e1=iadr(l8+istk(il8+1+1)-1)
511
m8e1 = istk(il8e1+1)*istk(il8e1+2)
520
c -- subvariable imode(info) --
521
il8e2=iadr(l8+istk(il8+1+2)-1)
526
c -- subvariable band(info) --
527
il8e3=iadr(l8+istk(il8+1+3)-1)
528
m8e3 =istk(il8e3+2)*istk(il8e3+2)
532
elseif(m8e3.eq.2) then
542
c -- subvariable maxstep(info) --
543
il8e4=iadr(l8+istk(il8+1+4)-1)
544
m8e4 =istk(il8e4+2)*istk(il8e4+2)
554
c -- subvariable stepin(info) --
555
il8e5=iadr(l8+istk(il8+1+5)-1)
556
m8e5 =istk(il8e5+2)*istk(il8e5+2)
566
c -- subvariable nonneg(info) --
567
il8e6=iadr(l8+istk(il8+1+6)-1)
571
c -- subvariable isest(info) --
572
il8e7=iadr(l8+istk(il8+1+7)-1)
575
if(isest.eq.1) info(11)=1
579
if(rhs.eq.9-iskip) then
582
c checking variable hotdata (number 9)
584
il9 = iadr(lstk(top-rhs+9-iskip))
585
if (istk(il9) .ne. 1) then
590
n9 = istk(il9+1)*istk(il9+2)
592
elseif(rhs.ne.8-iskip) then
597
c --------------------Work Tables
598
if (.not.cremat(fname,topw,0,1,1,lw15,lc)) return
600
if (.not.cremat(fname,topw,0,1,1,lw17,lc)) return
603
if(info(6).eq.0) then
604
C for the full (dense) JACOBIAN case
605
lrw = 40+(maxord+4)*neq+neq**2
606
elseif(info(5).eq.1) then
607
C for the banded user-defined JACOBIAN case
608
lrw=40+(maxord+4)*neq+(2*ml+mu+1)*neq
609
elseif(info(5).eq.0) then
610
C for the banded finite-difference-generated JACOBIAN case
611
lrw = 40+(maxord+4)*neq+(2*ml+mu+1)*neq+2*(neq/(ml+mu+1)+1)
614
if(.not.hotstart) then
615
if (.not.cremat(fname,topw,0,1,lrw,lrwork,lc)) return
617
if (.not.cremat(fname,topw,0,1,sadr(liw)+1,liwork,lc)) return
620
if(lrw+liw.gt.n9) then
627
call entier(liw,stk(liwork),istk(iadr(liwork)))
630
if(info(4).eq.1) then
633
if(info(7).eq.1) then
634
stk(lrwork+1)=maxstep
636
if(info(8).eq.1) then
639
if(info(6).eq.1) then
640
istk(iadr(liwork))=ml
641
istk(iadr(liwork+1))=mu
643
c structure d'info pour les externals
648
istk(ilext+1)=ilext+4
649
istk(ilext+2)=ilext+8
650
istk(ilext+3)=ilext+12
669
if(hotstart) info(1)=1
678
margin=(k-1)*(2*n1+1)+4
680
if(lhs.eq.2) lw1=lw1+4+lrw+liw
681
if(lw1-lstk(bot).gt.0) then
683
call msgstxt('Not enough memory to go further')
687
if (tout .eq. t0) then
689
call unsfdcopy(n1,stk(l1),1,stk(lyri+1),1)
690
call unsfdcopy(n1,stk(lydot),1,stk(lyri+n1+1),1)
697
call unsfdcopy(n1,stk(l1),1,stk(lyri+1),1)
698
call unsfdcopy(n1,stk(lydot),1,stk(lyri+n1+1),1)
701
call ddassl(bresd,n1,t0,stk(l1),stk(lydot),
702
& stk(lyri),info,stk(lrtol),stk(latol),idid,
703
& stk(lrwork),lrw,istk(iadr(liwork)),liw,stk(lw15),
708
C A step was successfully taken in the intermediate-output mode.
709
C The code has not yet reached TOUT.
714
elseif(idid.eq.2) then
715
C The integration to TSTOP was successfully completed (T=TSTOP)
718
elseif(idid.eq.3) then
719
C The integration to TOUT was successfully completed (T=TOUT) by
720
C stepping past TOUT. Y,ydot are obtained by interpolation.
725
elseif(idid.eq.-1) then
726
C A large amount of work has been expended (About 500 steps)
727
call msgstxt('to many steps necessary to reached next '//
728
& 'required time discretization point')
729
call msgstxt('Change discretisation of time vector t '//
730
& 'or decrease accuracy')
733
elseif(idid.eq.-2) then
734
C The error tolerances are too stringent.
738
c buf='The error tolerances are too stringent'
741
elseif(idid.eq.-3) then
742
C The local error test cannot be satisfied because you specified
743
C a zero component in ATOL and the corresponding computed solution
744
C component is zero. Thus, a pure relative error test is impossible
745
C for this component.
746
buf='atol and computed test value are zero'
749
elseif(idid.eq.-6) then
750
C repeated error test failures on the last attempted step.
751
call msgstxt('A singularity in the solution '//
754
elseif(idid.eq.-7) then
755
C The corrector could not converge.
756
call msgstxt('May be inaccurate or ill-conditioned '//
759
elseif(idid.eq.-8) then
760
C The matrix of partial derivatives is singular.
761
buf='Singular partial derivatives matrix'//
762
& ' (may be redundant equations)'
765
elseif(idid.eq.-9) then
766
C The corrector could not converge. there were repeated error
767
c test failures in this step.
768
call msgstxt('Either ill-posed problem or '//
769
& 'discontinuity or singularity encountered')
771
elseif(idid.eq.-10) then
772
call msgstxt('external ''res'' return many times'//
775
elseif(idid.eq.-11) then
776
C IRES equal to -2 was encountered and control is being returned to the
778
buf='error in external ''res'' '
781
elseif(idid.eq.-12) then
782
C DDASSL failed to compute the initial YPRIME.
783
buf='dassl failed to compute the initial Ydot.'
786
elseif(idid.eq.-33) then
787
C The code has encountered trouble from which
788
C it cannot recover. A message is printed
789
C explaining the trouble and control is returned
790
C to the calling program. For example, this occurs
791
C when invalid input is detected.
792
call msgstxt('dassl encountered trouble')
802
c Variable de sortie: y0
805
if(k.eq.0) istk(ilyr+1)=0
809
if(lhs.eq.1) goto 150
812
c Variable de sortie: rwork
816
err=lw+4+lrw+liw-lstk(bot)
826
call unsfdcopy(lrw,stk(lrwork),1,stk(lw),1)
827
call int2db(liw,istk(iadr(liwork)),1,stk(lw+lrw),1)
831
c Remise en place de la pile
832
150 call unsfdcopy(lw-lw0,stk(lw0),1,stk(l0),1)