#include #include "xpplim.h" #include "getvar.h" #include "volterra.h" #include #include #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) /* #define Set_ivar(a,b) variables[(a)]=(b) */ /* This is an implicit solver for volterra integral and integro-differential equations. It is based on code found in Peter Linz's book ont Volterra equations. One tries to evaluate: int_0^t ( (t-t')^-mu K(t,t',u) dt') where 0 <= mu < 1 and K(t,t',u) is cts and Lipschitz. The product method is used combined with the trapezoidal rule for integration. The method is A-stable since it is an implicit scheme. The kernel structure contains the constant mu and the expression for evaluating K(t,t',u) */ #define CONV 2 extern KERNEL kernel[MAXKER]; extern int NODE,NMarkov,FIX_VAR,PrimeStart; extern int NKernel; extern double *Memory[MAXODE]; extern double T0,DELTA_T; extern int MaxPoints; extern int EqType[MAXODE]; int CurrentPoint; int KnFlag; int AutoEvaluate=0; extern double variables[]; extern int NVAR; extern int MaxEulIter; extern double EulTol,NEWT_ERR; double evaluate(); double ker_val(); double alpha1n(); double alpbetjn(); double betnn(); extern int *my_ode[]; double get_ivar(); double ker_val(in) int in; { if(KnFlag)return(kernel[in].k_n); return(kernel[in].k_n1); } alloc_v_memory() /* allocate stuff for volterra equations */ { int i,len,formula[256],j; /* First parse the kernels since these were deferred */ for(i=0;i0.0){ mu=kernel[i].mu; if(flag==1)free(kernel[i].al); kernel[i].al=(double *)malloc((n+1)*sizeof(double)); for(j=0;j<=n;j++)kernel[i].al[j]=alpbetjn(mu,DELTA_T,j); } } } /* the following is the main driver for evaluating the sums in the kernel the results here are used in the implicit solver. The integral up to t_n-1 is evaluated and placed in sum. Kn-> Kn-1 the weights al and bet are computed in general, but specifically for mu=0,.5 since these involve no transcendental functions */ /*** FIX THIS TO DO MORE GENERAL STUFF K(t,t',u,u') someday... ***/ init_sums(t0,n,dt,i0,iend,ishift) double t0,dt; int n,i0,iend,ishift; { double t=t0+n*dt,tp=t0+i0*dt; double sum[MAXODE],al,bet,alpbet,mu; int nvar=FIX_VAR+NODE+NMarkov; int l,ioff,ker,i; SETVAR(0,t); SETVAR(PrimeStart,tp); for(l=0;lMaxEulIter)return(-2); /* too many iterates */ } /* We have a good point; lets save it */ get_kn(yg,t); /* for(i=NODE;i