TEST(MathLibCVodeTest, ExponentialWithJacobianNewton) { // initial values const double y0 = 1.0; const double t0 = 0.0; boost::property_tree::ptree tree; tree.put("linear_multistep_method", "BDF"); tree.put("nonlinear_solver_iteration", "Newton"); auto ode_solver = make_ode_solver<1>(tree); ASSERT_EQ(any_ode_solver_libs_available(), !!ode_solver); // Don't run the test if the ODE solver could not be constructed. if (!ode_solver) return; ode_solver->setFunction(f, df); ode_solver->setTolerance(abs_tol, rel_tol); ode_solver->setIC(t0, {y0}); ode_solver->preSolve(); const double dt = 1e-1; for (unsigned i = 1; i <= 10; ++i) { const double time = dt * i; ASSERT_TRUE(ode_solver->solve(time)); auto const y = ode_solver->getSolution(); auto const time_reached = ode_solver->getTime(); auto const y_dot = ode_solver->getYDot(time_reached, y); auto const y_ana = exp(-15.0 * time); auto const y_dot_ana = -15.0 * exp(-15.0 * time); check(time_reached, y[0], y_dot[0], time, y_ana, y_dot_ana); } }
void mainWindow::startSolution(void) { if (!problem->mesh->getIsMeshGenerated()) { appendMessage(tr("ERROR: First generate the mesh. Solution will not start."), Qt::red); return; } setIC(); // IC values are trasferred from the GUI into the variables. setParameters(); // Parameters are trasferred from the GUI into the variables. if (!checkBC()) { // All items of the mesh should have a BC assigned. appendMessage(tr("ERROR: Provide boundary conditions for all geometrical entities. Solution will not start."), Qt::red); return; } if (!checkIC()) { // IC related check boxes need to be filled. appendMessage(tr("ERROR: Provide values for all initial conditions. Solution will not start."), Qt::red); return; } if (!checkParameters()) { // IC related check boxes need to be filled. appendMessage(tr("ERROR: Provide values for all solution parameters. Solution will not start."), Qt::red); return; } if (!saveProblem()) // We need to save the problem before starting the solution. return; rightTab->setCurrentIndex(1); // Show the Convergence page. convergencePlot->initialize(problem->getMaxOuterIter()); controlPointPlot->initialize(problem->getMaxOuterIter()); solverThread.start(); pauseButton->setEnabled(TRUE); terminateButton->setEnabled(TRUE); startButton->setEnabled(FALSE); } // End of function startSolution()
int main(void) { UserData data; void *mem; N_Vector yy, yp, id; realtype rtol, atol; realtype t0, tf, tout, dt, tret; int flag, iout; /* User data */ 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->J2 = 2.0; /* moment of inertia of connecting rod */ data->k = 1.0; /* spring constant */ data->c = 1.0; /* damper constant */ data->l0 = 1.0; /* spring free length */ data->F = 1.0; /* external constant force */ /* Create N_Vectors */ yy = N_VNew_Serial(NEQ); yp = N_VNew_Serial(NEQ); id = N_VNew_Serial(NEQ); /* Consistent IC */ setIC(yy, yp, data); /* ID array */ N_VConst(ONE, id); NV_Ith_S(id,6) = ZERO; NV_Ith_S(id,7) = ZERO; NV_Ith_S(id,8) = ZERO; NV_Ith_S(id,9) = ZERO; /* Tolerances */ rtol = RCONST(1.0e-6); atol = RCONST(1.0e-6); /* Integration limits */ t0 = ZERO; tf = TEND; dt = (tf-t0)/(NOUT-1); /* IDA initialization */ mem = IDACreate(); flag = IDAInit(mem, ressc, t0, yy, yp); flag = IDASStolerances(mem, rtol, atol); flag = IDASetUserData(mem, data); flag = IDASetId(mem, id); flag = IDASetSuppressAlg(mem, TRUE); /* Call IDADense and set up the linear solver. */ flag = IDADense(mem, NEQ); PrintHeader(rtol, atol, yy); /* In loop, call IDASolve, print results, and test for error. */ PrintOutput(mem,t0,yy); tout = dt; for (iout=1; iout<NOUT; iout++) { tout = iout*dt; flag = IDASolve(mem, tout, &tret, yy, yp, IDA_NORMAL); if (flag < 0) break; PrintOutput(mem,tret,yy); } PrintFinalStats(mem); /* Free memory */ free(data); IDAFree(&mem); N_VDestroy_Serial(yy); N_VDestroy_Serial(yp); N_VDestroy_Serial(id); return(0); }
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); }
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); }
TEST(MathLibCVodeTest, ExponentialExtraData) { // initial values const double y0 = 1.0; const double t0 = 0.0; auto tree = boost::property_tree::ptree{}; auto ode_solver = make_ode_solver<1>(tree); ASSERT_EQ(any_ode_solver_libs_available(), !!ode_solver); // Don't run the test if the ODE solver could not be constructed. if (!ode_solver) return; ExtraData data; auto f_lambda = [&](double t, MathLib::ODE::MappedConstVector<1> const& y, MathLib::ODE::MappedVector<1>& ydot) { return f_extra(t, y, ydot, data); }; ode_solver->setFunction(f_lambda, nullptr); ode_solver->setTolerance(abs_tol, rel_tol); ode_solver->setIC(t0, {y0}); ode_solver->preSolve(); const double dt = 1e-1; for (unsigned i = 1; i <= 10; ++i) { const double time = dt * i; ASSERT_TRUE(ode_solver->solve(time)); auto const y = ode_solver->getSolution(); auto const time_reached = ode_solver->getTime(); auto const y_dot = ode_solver->getYDot(time_reached, y); auto const y_ana = exp(-data.value * time); auto const y_dot_ana = -data.value * exp(-data.value * time); check(time_reached, y[0], y_dot[0], time, y_ana, y_dot_ana); } ode_solver->setFunction(f_lambda, nullptr); ode_solver->preSolve(); for (unsigned i = 11; i <= 15; ++i) { const double time = dt * i; ASSERT_TRUE(ode_solver->solve(time)); auto const y = ode_solver->getSolution(); auto const time_reached = ode_solver->getTime(); auto const y_dot = ode_solver->getYDot(time_reached, y); auto const y_ana = exp(-data.value * time); auto const y_dot_ana = -data.value * exp(-data.value * time); check(time_reached, y[0], y_dot[0], time, y_ana, y_dot_ana); } }