int IDASetQuadErrConB(void *ida_mem, int which, int errconQB) { IDAMem IDA_mem; IDAadjMem IDAADJ_mem; IDABMem IDAB_mem; void *ida_memB; /* Is ida_mem valid? */ if (ida_mem == NULL) { IDAProcessError(NULL, IDA_MEM_NULL, "IDAA", "IDASetQuadErrConB", MSGAM_NULL_IDAMEM); return IDA_MEM_NULL; } IDA_mem = (IDAMem) ida_mem; /* Is ASA initialized? */ if (IDA_mem->ida_adjMallocDone == FALSE) { IDAProcessError(IDA_mem, IDA_NO_ADJ, "IDAA", "IDASetQuadErrConB", MSGAM_NO_ADJ); return(IDA_NO_ADJ); } IDAADJ_mem = IDA_mem->ida_adj_mem; /* Check the value of which */ if ( which >= nbckpbs ) { IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDAA", "IDASetQuadErrConB", MSGAM_BAD_WHICH); return(IDA_ILL_INPUT); } /* Find the IDABMem entry in the linked list corresponding to 'which'. */ IDAB_mem = IDAADJ_mem->IDAB_mem; while (IDAB_mem != NULL) { if( which == IDAB_mem->ida_index ) break; /* advance */ IDAB_mem = IDAB_mem->ida_next; } ida_memB = (void *) IDAB_mem->IDA_mem; return IDASetQuadErrCon(ida_memB, errconQB); }
int main(void) { UserData data; void *mem; N_Vector yy, yp, id, q; realtype tret, tout; int flag; id = N_VNew_Serial(NEQ); yy = N_VNew_Serial(NEQ); yp = N_VNew_Serial(NEQ); q = N_VNew_Serial(1); data = (UserData) malloc(sizeof *data); data->a = 0.5; /* half-length of crank */ data->J1 = 1.0; /* crank moment of inertia */ data->m2 = 1.0; /* mass of connecting rod */ data->m1 = 1.0; data->J2 = 2.0; /* moment of inertia of connecting rod */ data->params[0] = 1.0; /* spring constant */ data->params[1] = 1.0; /* damper constant */ data->l0 = 1.0; /* spring free length */ data->F = 1.0; /* external constant force */ N_VConst(ONE, id); NV_Ith_S(id, 9) = ZERO; NV_Ith_S(id, 8) = ZERO; NV_Ith_S(id, 7) = ZERO; NV_Ith_S(id, 6) = ZERO; /* Consistent IC*/ setIC(yy, yp, data); /* IDAS initialization */ mem = IDACreate(); flag = IDAInit(mem, ressc, TBEGIN, yy, yp); flag = IDASStolerances(mem, RTOLF, ATOLF); flag = IDASetUserData(mem, data); flag = IDASetId(mem, id); flag = IDASetSuppressAlg(mem, TRUE); flag = IDASetMaxNumSteps(mem, 20000); /* Call IDADense and set up the linear solver. */ flag = IDADense(mem, NEQ); N_VConst(ZERO, q); flag = IDAQuadInit(mem, rhsQ, q); flag = IDAQuadSStolerances(mem, RTOLQ, ATOLQ); flag = IDASetQuadErrCon(mem, TRUE); PrintHeader(RTOLF, ATOLF, yy); /* Print initial states */ PrintOutput(mem,0.0,yy); /* Perform forward run */ tout = TEND/NOUT; while (1) { flag = IDASolve(mem, tout, &tret, yy, yp, IDA_NORMAL); if (check_flag(&flag, "IDASolve", 1)) return(1); PrintOutput(mem,tret,yy); tout += TEND/NOUT; if (tret > TEND) break; } PrintFinalStats(mem); IDAGetQuad(mem, &tret, q); printf("--------------------------------------------\n"); printf(" G = %24.16f\n", Ith(q,1)); printf("--------------------------------------------\n\n"); IDAFree(&mem); /* Free memory */ free(data); N_VDestroy(id); N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); N_VDestroy_Serial(q); return(0); }
/* Main program */ int main() { UserData data; void *mem; N_Vector yy, yp, rr, q; int flag; realtype time, tout, incr; int nout; mem = NULL; yy = yp = NULL; /* Allocate user data. */ data = (UserData) malloc(sizeof(*data)); /* Fill user's data with the appropriate values for coefficients. */ data->k1 = RCONST(18.7); data->k2 = RCONST(0.58); data->k3 = RCONST(0.09); data->k4 = RCONST(0.42); data->K = RCONST(34.4); data->klA = RCONST(3.3); data->Ks = RCONST(115.83); data->pCO2 = RCONST(0.9); data->H = RCONST(737.0); /* Allocate N-vectors. */ yy = N_VNew_Serial(NEQ); if (check_flag((void *)yy, "N_VNew_Serial", 0)) return(1); yp = N_VNew_Serial(NEQ); if (check_flag((void *)yp, "N_VNew_Serial", 0)) return(1); /* Consistent IC for y, y'. */ #define y01 0.444 #define y02 0.00123 #define y03 0.00 #define y04 0.007 #define y05 0.0 Ith(yy,1) = RCONST(y01); Ith(yy,2) = RCONST(y02); Ith(yy,3) = RCONST(y03); Ith(yy,4) = RCONST(y04); Ith(yy,5) = RCONST(y05); Ith(yy,6) = data->Ks * RCONST(y01) * RCONST(y04); /* Get y' = - res(t0, y, 0) */ N_VConst(ZERO, yp); rr = N_VNew_Serial(NEQ); res(T0, yy, yp, rr, data); N_VScale(-ONE, rr, yp); N_VDestroy_Serial(rr); /* Create and initialize q0 for quadratures. */ q = N_VNew_Serial(1); if (check_flag((void *)q, "N_VNew_Serial", 0)) return(1); Ith(q,1) = ZERO; /* Call IDACreate and IDAInit to initialize IDA memory */ mem = IDACreate(); if(check_flag((void *)mem, "IDACreate", 0)) return(1); flag = IDAInit(mem, res, T0, yy, yp); if(check_flag(&flag, "IDAInit", 1)) return(1); /* Set tolerances. */ flag = IDASStolerances(mem, RTOL, ATOL); if(check_flag(&flag, "IDASStolerances", 1)) return(1); /* Attach user data. */ flag = IDASetUserData(mem, data); if(check_flag(&flag, "IDASetUserData", 1)) return(1); /* Attach linear solver. */ flag = IDADense(mem, NEQ); /* Initialize QUADRATURE(S). */ flag = IDAQuadInit(mem, rhsQ, q); if (check_flag(&flag, "IDAQuadInit", 1)) return(1); /* Set tolerances and error control for quadratures. */ flag = IDAQuadSStolerances(mem, RTOLQ, ATOLQ); if (check_flag(&flag, "IDAQuadSStolerances", 1)) return(1); flag = IDASetQuadErrCon(mem, TRUE); if (check_flag(&flag, "IDASetQuadErrCon", 1)) return(1); PrintHeader(RTOL, ATOL, yy); /* Print initial states */ PrintOutput(mem,0.0,yy); tout = T1; nout = 0; incr = RPowerR(TF/T1,ONE/NF); /* FORWARD run. */ while (1) { flag = IDASolve(mem, tout, &time, yy, yp, IDA_NORMAL); if (check_flag(&flag, "IDASolve", 1)) return(1); PrintOutput(mem, time, yy); nout++; tout *= incr; if (nout>NF) break; } flag = IDAGetQuad(mem, &time, q); if (check_flag(&flag, "IDAGetQuad", 1)) return(1); printf("\n--------------------------------------------------------\n"); printf("G: %24.16f \n",Ith(q,1)); printf("--------------------------------------------------------\n\n"); PrintFinalStats(mem); IDAFree(&mem); N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); N_VDestroy_Serial(q); return(0); }
int main(void) { UserData data; void *mem; N_Vector yy, yp, id, q, *yyS, *ypS, *qS; realtype tret; realtype pbar[2]; realtype dp, G, Gm[2], Gp[2]; int flag, is; realtype atolS[NP]; id = N_VNew_Serial(NEQ); yy = N_VNew_Serial(NEQ); yp = N_VNew_Serial(NEQ); q = N_VNew_Serial(1); yyS= N_VCloneVectorArray(NP,yy); ypS= N_VCloneVectorArray(NP,yp); qS = N_VCloneVectorArray_Serial(NP, q); data = (UserData) malloc(sizeof *data); data->a = 0.5; /* half-length of crank */ data->J1 = 1.0; /* crank moment of inertia */ data->m2 = 1.0; /* mass of connecting rod */ data->m1 = 1.0; data->J2 = 2.0; /* moment of inertia of connecting rod */ data->params[0] = 1.0; /* spring constant */ data->params[1] = 1.0; /* damper constant */ data->l0 = 1.0; /* spring free length */ data->F = 1.0; /* external constant force */ N_VConst(ONE, id); NV_Ith_S(id, 9) = ZERO; NV_Ith_S(id, 8) = ZERO; NV_Ith_S(id, 7) = ZERO; NV_Ith_S(id, 6) = ZERO; printf("\nSlider-Crank example for IDAS:\n"); /* Consistent IC*/ setIC(yy, yp, data); for (is=0;is<NP;is++) { N_VConst(ZERO, yyS[is]); N_VConst(ZERO, ypS[is]); } /* IDA initialization */ mem = IDACreate(); flag = IDAInit(mem, ressc, TBEGIN, yy, yp); flag = IDASStolerances(mem, RTOLF, ATOLF); flag = IDASetUserData(mem, data); flag = IDASetId(mem, id); flag = IDASetSuppressAlg(mem, TRUE); flag = IDASetMaxNumSteps(mem, 20000); /* Call IDADense and set up the linear solver. */ flag = IDADense(mem, NEQ); flag = IDASensInit(mem, NP, IDA_SIMULTANEOUS, NULL, yyS, ypS); pbar[0] = data->params[0];pbar[1] = data->params[1]; flag = IDASetSensParams(mem, data->params, pbar, NULL); flag = IDASensEEtolerances(mem); IDASetSensErrCon(mem, TRUE); N_VConst(ZERO, q); flag = IDAQuadInit(mem, rhsQ, q); flag = IDAQuadSStolerances(mem, RTOLQ, ATOLQ); flag = IDASetQuadErrCon(mem, TRUE); N_VConst(ZERO, qS[0]); flag = IDAQuadSensInit(mem, rhsQS, qS); atolS[0] = atolS[1] = ATOLQ; flag = IDAQuadSensSStolerances(mem, RTOLQ, atolS); flag = IDASetQuadSensErrCon(mem, TRUE); /* Perform forward run */ printf("\nForward integration ... "); flag = IDASolve(mem, TEND, &tret, yy, yp, IDA_NORMAL); if (check_flag(&flag, "IDASolve", 1)) return(1); printf("done!\n"); PrintFinalStats(mem); IDAGetQuad(mem, &tret, q); printf("--------------------------------------------\n"); printf(" G = %24.16f\n", Ith(q,1)); printf("--------------------------------------------\n\n"); IDAGetQuadSens(mem, &tret, qS); printf("-------------F O R W A R D------------------\n"); printf(" dG/dp: %12.4le %12.4le\n", Ith(qS[0],1), Ith(qS[1],1)); printf("--------------------------------------------\n\n"); IDAFree(&mem); /* Finite differences for dG/dp */ dp = 0.00001; data->params[0] = ONE; data->params[1] = ONE; mem = IDACreate(); setIC(yy, yp, data); flag = IDAInit(mem, ressc, TBEGIN, yy, yp); flag = IDASStolerances(mem, RTOLFD, ATOLFD); flag = IDASetUserData(mem, data); flag = IDASetId(mem, id); flag = IDASetSuppressAlg(mem, TRUE); /* Call IDADense and set up the linear solver. */ flag = IDADense(mem, NEQ); N_VConst(ZERO, q); IDAQuadInit(mem, rhsQ, q); IDAQuadSStolerances(mem, RTOLQ, ATOLQ); IDASetQuadErrCon(mem, TRUE); IDASolve(mem, TEND, &tret, yy, yp, IDA_NORMAL); IDAGetQuad(mem,&tret,q); G = Ith(q,1); /*printf(" G =%12.6e\n", Ith(q,1));*/ /****************************** * BACKWARD for k ******************************/ data->params[0] -= dp; setIC(yy, yp, data); IDAReInit(mem, TBEGIN, yy, yp); N_VConst(ZERO, q); IDAQuadReInit(mem, q); IDASolve(mem, TEND, &tret, yy, yp, IDA_NORMAL); IDAGetQuad(mem, &tret, q); Gm[0] = Ith(q,1); /*printf("Gm[0]=%12.6e\n", Ith(q,1));*/ /**************************** * FORWARD for k * ****************************/ data->params[0] += (TWO*dp); setIC(yy, yp, data); IDAReInit(mem, TBEGIN, yy, yp); N_VConst(ZERO, q); IDAQuadReInit(mem, q); IDASolve(mem, TEND, &tret, yy, yp, IDA_NORMAL); IDAGetQuad(mem, &tret, q); Gp[0] = Ith(q,1); /*printf("Gp[0]=%12.6e\n", Ith(q,1));*/ /* Backward for c */ data->params[0] = ONE; data->params[1] -= dp; setIC(yy, yp, data); IDAReInit(mem, TBEGIN, yy, yp); N_VConst(ZERO, q); IDAQuadReInit(mem, q); IDASolve(mem, TEND, &tret, yy, yp, IDA_NORMAL); IDAGetQuad(mem, &tret, q); Gm[1] = Ith(q,1); /* Forward for c */ data->params[1] += (TWO*dp); setIC(yy, yp, data); IDAReInit(mem, TBEGIN, yy, yp); N_VConst(ZERO, q); IDAQuadReInit(mem, q); IDASolve(mem, TEND, &tret, yy, yp, IDA_NORMAL); IDAGetQuad(mem, &tret, q); Gp[1] = Ith(q,1); IDAFree(&mem); printf("\n\n Checking using Finite Differences \n\n"); printf("---------------BACKWARD------------------\n"); printf(" dG/dp: %12.4le %12.4le\n", (G-Gm[0])/dp, (G-Gm[1])/dp); printf("-----------------------------------------\n\n"); printf("---------------FORWARD-------------------\n"); printf(" dG/dp: %12.4le %12.4le\n", (Gp[0]-G)/dp, (Gp[1]-G)/dp); printf("-----------------------------------------\n\n"); printf("--------------CENTERED-------------------\n"); printf(" dG/dp: %12.4le %12.4le\n", (Gp[0]-Gm[0])/(TWO*dp) ,(Gp[1]-Gm[1])/(TWO*dp)); printf("-----------------------------------------\n\n"); /* Free memory */ free(data); N_VDestroy(id); N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); N_VDestroy_Serial(q); return(0); }