MODULE EXAMPLE2 ! DEMONSTRATION PROGRAM FOR THE DVODE_F90 PACKAGE. ! The following is a modification of the previous example ! program to illustrate root finding. The problem is from ! chemical kinetics, and consists of the following three ! rate equations: ! dy1/dt = -.04d0*y1 + 1.d4*y2*y3 ! dy2/dt = .04d0*y1 - 1.d4*y2*y3 - 3.d7*y2**2 ! dy3/dt = 3.d7*y2**2 ! on the interval from t = 0.0d0 to t = 4.d10, with initial ! conditions y1 = 1.0d0, y2 = y3 = 0.0d0. The problem is stiff. ! In addition, we want to find the values of t, y1, y2, ! and y3 at which: ! (1) y1 reaches the value 1.d-4, and ! (2) y3 reaches the value 1.d-2. ! The following coding solves this problem with DVODE_F90 ! using an internally generated dense Jacobian and ! printing results at t = .4, 4., ..., 4.d10, and at the ! computed roots. It uses ITOL = 2 and ATOL much smaller ! for y2 than y1 or y3 because y2 has much smaller values. ! At the end of the run, statistical quantities of interest ! are printed (see optional outputs in the full description ! below). Output is written to the file example2.dat. CONTAINS SUBROUTINE FEX(NEQ,T,Y,YDOT) IMPLICIT NONE INTEGER NEQ DOUBLE PRECISION T, Y, YDOT DIMENSION Y(3), YDOT(3) YDOT(1) = -0.04D0*Y(1) + 1.0D4*Y(2)*Y(3) YDOT(3) = 3.0D7*Y(2)*Y(2) YDOT(2) = -YDOT(1) - YDOT(3) RETURN END SUBROUTINE FEX SUBROUTINE GEX(NEQ,T,Y,NG,GOUT) IMPLICIT NONE INTEGER NEQ, NG DOUBLE PRECISION T, Y, GOUT DIMENSION Y(3), GOUT(2) GOUT(1) = Y(1) - 1.0D-4 GOUT(2) = Y(3) - 1.0D-2 RETURN END SUBROUTINE GEX END MODULE EXAMPLE2 !****************************************************************** PROGRAM RUNEXAMPLE2 USE DVODE_F90_M USE EXAMPLE2 IMPLICIT NONE INTEGER ITASK, ISTATE, NG, NEQ, IOUT, JROOT, ISTATS, IERROR, I DOUBLE PRECISION ATOL, RTOL, RSTATS, T, TOUT, Y DIMENSION Y(3), ATOL(3), RSTATS(22), ISTATS(31), JROOT(2) TYPE (VODE_OPTS) :: OPTIONS OPEN (UNIT=6,FILE='example2.dat') IERROR = 0 NEQ = 3 Y(1) = 1.0D0 Y(2) = 0.0D0 Y(3) = 0.0D0 T = 0.0D0 TOUT = 0.4D0 RTOL = 1.0D-4 ATOL(1) = 1.0D-8 ATOL(2) = 1.0D-10 ATOL(3) = 1.0D-8 ITASK = 1 ISTATE = 1 NG = 2 ! OPTIONS = SET_OPTS(DENSE_J=.TRUE.,RELERR=RTOL,ABSERR_VECTOR=ATOL, & ! NEVENTS=NG) OPTIONS = SET_NORMAL_OPTS(DENSE_J=.TRUE.,RELERR=RTOL, & ABSERR_VECTOR=ATOL,NEVENTS=NG) DO 20 IOUT = 1, 12 10 CONTINUE CALL DVODE_F90(FEX,NEQ,Y,T,TOUT,ITASK,ISTATE,OPTIONS,G_FCN=GEX) CALL GET_STATS(RSTATS,ISTATS,NG,JROOT) WRITE (6,90000) T, Y(1), Y(2), Y(3) DO I = 1, NEQ IF (Y(I)<0.0D0) IERROR = 1 END DO 90000 FORMAT (' At t =',D12.4,' Y =',3D14.6) IF (ISTATE<0) GO TO 30 IF (ISTATE==2) GO TO 20 WRITE (6,90001) JROOT(1), JROOT(2) 90001 FORMAT (5X,' The above line is a root, JROOT =',2I5) ISTATE = 2 GO TO 10 20 TOUT = TOUT*10.0D0 WRITE (6,90002) ISTATS(11), ISTATS(12), ISTATS(13), ISTATS(10) IF (IERROR==1) THEN WRITE (6,90003) ELSE WRITE (6,90004) END IF 90002 FORMAT (/' No. steps =',I4,' No. f-s =',I4,' No. J-s =',I4, & ' No. g-s =',I4/) STOP 30 WRITE (6,90005) ISTATE 90003 FORMAT (/' An error occurred.') 90004 FORMAT (/' No errors occurred.') 90005 FORMAT (///' Error halt.. ISTATE =',I3) STOP END PROGRAM RUNEXAMPLE2