Beispiel #1
0
static void SolverError(SolverStruct *S, char *errmsg)
{
    sprintf(S->buf,"Error at t=%20.16e: %s\n",S->w[0],errmsg);
    if(S->err==-1) kv->error(S->buf);
    S->err=1;
}
Beispiel #2
0
EXP ALGEB M_DECL ParamDriver( MKernelVector kv_in, ALGEB *args )
{
    double t0,tf,dt,*ic,*p,*out;
    M_INT nargs,bounds[4],npts,naout,i;
    RTableSettings s;
    ALGEB outd;
    char buf[1000];

    kv=kv_in;
    nargs=kv->numArgs((ALGEB)args);
    if( nargs<5 || nargs>6 )
        kv->error("incorrect number of arguments");

    /* Process time vals */
    if( !kv->isNumeric(args[1]) )
        kv->error("argument #1, the initial time, must be numeric");
    t0=kv->mapleToFloat64(args[1]);
    if( !kv->isNumeric(args[2]) )
        kv->error("argument #2, the final time, must be numeric");
    tf=kv->mapleToFloat64(args[2]);
    if( t0>=tf )
        kv->error("the final time must be larger than the initial time");
    if( !kv->isNumeric(args[3]) )
        kv->error("argument #3, the time step, must be a positive numeric value");
    dt=kv->mapleToFloat64(args[3]);
    if(dt<=0)
        kv->error("argument #3, the time step, must be a positive numeric value");
    npts=(M_INT)ceil((tf+1e-10-t0)/dt)+1;

    /* Processing ic in */
    if( NDIFF==0 )
        ic=NULL;
    else if( kv->isInteger(args[4]) && kv->mapleToInteger32(args[4])==0 )
        ic=NULL;
    else if( !kv->isRTable(args[4]) ) {
        ic=NULL;
        kv->error("argument #4, the initial data, must be a 1..ndiff rtable");
    }
    else {
        kv->rtableGetSettings(&s,args[4]);
        if( s.storage != RTABLE_RECT || s.data_type != RTABLE_FLOAT64 ||
                s.num_dimensions != 1 || kv->rtableLowerBound(args[4],1)!=1 ||
                kv->rtableUpperBound(args[4],1) != NDIFF )
            kv->error("argument #4, the initial data, must be a 1..ndiff rtable");
        ic=(double *)kv->rtableData(args[4]);
    }

    /* Processing parameters in */
    if( NPAR==0 )
        p=NULL;
    else if( kv->isInteger(args[5]) && kv->mapleToInteger32(args[5])==0 )
        p=NULL;
    else if( !kv->isRTable(args[5]) ) {
        p=NULL;
        kv->error("argument #5, the parameter data, must be a 1..npar rtable");
    }
    else {
        kv->rtableGetSettings(&s,args[5]);
        if( s.storage != RTABLE_RECT || s.data_type != RTABLE_FLOAT64 ||
                s.num_dimensions != 1 || kv->rtableLowerBound(args[5],1)!=1 ||
                kv->rtableUpperBound(args[5],1) != NPAR )
            kv->error("argument #5, the parameter data, must be a 1..npar rtable");
        p=(double *)kv->rtableData(args[5]);
    }

    /* Output data table */
    if( nargs==6 ) {
        outd=NULL;
        if( !kv->isRTable(args[6]) ) {
            out=NULL;
            naout=0;
            kv->error("argument #6, the output data, must be a 1..npts,1..nout+1 C_order rtable");
        }
        else {
            kv->rtableGetSettings(&s,args[6]);
            if( s.storage != RTABLE_RECT || s.data_type != RTABLE_FLOAT64 ||
                    s.order != RTABLE_C || s.num_dimensions != 2 ||
                    kv->rtableLowerBound(args[6],1)!=1 ||
                    kv->rtableLowerBound(args[6],2)!=1 ||
                    kv->rtableUpperBound(args[6],2) != NOUT+1 )
                kv->error("argument #6, the output data, must be a 1..npts,1..nout+1 C_order rtable");
            naout=kv->rtableUpperBound(args[6],1);
            if( naout<1 )
                kv->error("argument #6, the output data, must have at least 1 output slot");
            out=(double *)kv->rtableData(args[6]);
            if(naout<npts) npts=naout;
        }
    }
    else {
        kv->rtableGetDefaults(&s);
        bounds[0]=1;
        bounds[1]=npts;
        bounds[2]=1;
        bounds[3]=NOUT+1;
        s.storage=RTABLE_RECT;
        s.data_type=RTABLE_FLOAT64;
        s.order=RTABLE_C;
        s.num_dimensions=2;
        s.subtype=RTABLE_ARRAY;
        outd=kv->rtableCreate(&s,NULL,bounds);
        out=(double *)kv->rtableData(outd);
        naout=npts;
    }
    for(i=0; i<naout*(NOUT+1); i++) out[i]=*dsn_undef;

    i=ParamDriverC(t0,dt,npts,ic,p,out,buf,1);

    /* All done */
    if(outd==NULL)
        return(kv->toMapleInteger(i));
    else
        return(outd);
}