static int SolveIt(void *kmem, N_Vector u, N_Vector s, int glstr, int mset) { int flag; printf("\n"); if (mset==1) printf("Exact Newton"); else printf("Modified Newton"); if (glstr == KIN_NONE) printf("\n"); else printf(" with line search\n"); flag = KINSetMaxSetupCalls(kmem, mset); if (check_flag(&flag, "KINSetMaxSetupCalls", 1)) return(1); flag = KINSol(kmem, u, glstr, s, s); if (check_flag(&flag, "KINSol", 1)) return(1); printf("Solution:\n [x1,x2] = "); PrintOutput(u); PrintFinalStats(kmem); return(0); }
void FKIN_SETIIN(char key_name[], long int *ival, int *ier, int key_len) { if (!strncmp(key_name,"PRNT_LEVEL", (size_t)key_len)) *ier = KINSetPrintLevel(KIN_kinmem, (int) *ival); else if (!strncmp(key_name,"MAX_NITERS", (size_t)key_len)) *ier = KINSetNumMaxIters(KIN_kinmem, (int) *ival); else if (!strncmp(key_name,"ETA_FORM", (size_t)key_len)) *ier = KINSetEtaForm(KIN_kinmem, (int) *ival); else if (!strncmp(key_name,"MAX_SETUPS", (size_t)key_len)) *ier = KINSetMaxSetupCalls(KIN_kinmem, (int) *ival); else if (!strncmp(key_name,"MAX_SP_SETUPS", (size_t)key_len)) *ier = KINSetMaxSubSetupCalls(KIN_kinmem, (int) *ival); else if (!strncmp(key_name,"NO_INIT_SETUP", (size_t)key_len)) *ier = KINSetNoInitSetup(KIN_kinmem, (int) *ival); else if (!strncmp(key_name,"NO_MIN_EPS", (size_t)key_len)) *ier = KINSetNoMinEps(KIN_kinmem, (int) *ival); else if (!strncmp(key_name,"NO_RES_MON", (size_t)key_len)) *ier = KINSetNoResMon(KIN_kinmem, (int) *ival); else { *ier = -99; printf("FKINSETIIN: Unrecognized key.\n\n"); } }
static int nlsKinsolErrorHandler(int errorCode, DATA *data, NONLINEAR_SYSTEM_DATA *nlsData, NLS_KINSOL_DATA *kinsolData) { int retValue, i, retValue2=0; double fNorm; double *xStart = NV_DATA_S(kinsolData->initialGuess); double *xScaling = NV_DATA_S(kinsolData->xScale); /* check what kind of error * retValue < 0 -> a non recoverable issue * retValue == 1 -> try with other settings */ KINSetNoInitSetup(kinsolData->kinsolMemory, FALSE); switch(errorCode) { case KIN_MEM_NULL: case KIN_ILL_INPUT: case KIN_NO_MALLOC: errorStreamPrint(LOG_NLS, 0, "kinsol has a serious memory issue ERROR %d\n", errorCode); return errorCode; break; /* just retry with new initial guess */ case KIN_MXNEWT_5X_EXCEEDED: warningStreamPrint(LOG_NLS, 0, "initial guess was too far away from the solution. Try again.\n"); return 1; break; /* just retry without line search */ case KIN_LINESEARCH_NONCONV: warningStreamPrint(LOG_NLS, 0, "kinsols line search did not convergence. Try without.\n"); kinsolData->kinsolStrategy = KIN_NONE; return 1; /* maybe happened because of an out-dated factorization, so just retry */ case KIN_LSETUP_FAIL: case KIN_LSOLVE_FAIL: warningStreamPrint(LOG_NLS, 0, "kinsols matrix need new factorization. Try again.\n"); KINKLUReInit(kinsolData->kinsolMemory, kinsolData->size, kinsolData->nnz, 2); return 1; case KIN_MAXITER_REACHED: case KIN_REPTD_SYSFUNC_ERR: warningStreamPrint(LOG_NLS, 0, "kinsols runs into issues retry with differnt configuration.\n"); retValue = 1; break; default: errorStreamPrint(LOG_STDOUT, 0, "kinsol has a serious solving issue ERROR %d\n", errorCode); return errorCode; break; } /* check if the current solution is sufficient anyway */ KINGetFuncNorm(kinsolData->kinsolMemory, &fNorm); if (fNorm<FTOL_WITH_LESS_ACCURANCY) { warningStreamPrint(LOG_NLS, 0, "Move forward with a less accurate solution."); KINSetFuncNormTol(kinsolData->kinsolMemory, FTOL_WITH_LESS_ACCURANCY); KINSetScaledStepTol(kinsolData->kinsolMemory, FTOL_WITH_LESS_ACCURANCY); retValue2 = 1; } else { warningStreamPrint(LOG_NLS, 0, "Current status of fx = %f", fNorm); } /* reconfigure kinsol for an other try */ if (retValue == 1 && !retValue2) { switch(kinsolData->retries) { case 0: /* try without x scaling */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_ONES); break; case 1: /* try without line-search and oldValues */ nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_OLDVALUES); kinsolData->kinsolStrategy = KIN_LINESEARCH; break; case 2: /* try without line-search and oldValues */ nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION); kinsolData->kinsolStrategy = KIN_NONE; break; case 3: /* try with exact newton */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_NOMINALSTART); nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION); KINSetMaxSetupCalls(kinsolData->kinsolMemory, 1); kinsolData->kinsolStrategy = KIN_LINESEARCH; break; case 4: /* try with exact newton to with out x scaling values */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_ONES); nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_OLDVALUES); KINSetMaxSetupCalls(kinsolData->kinsolMemory, 1); kinsolData->kinsolStrategy = KIN_LINESEARCH; break; default: retValue = 0; break; } } return retValue+retValue2; }
int main() { realtype fnormtol, scsteptol; N_Vector y, scale, constraints; int mset, flag, i; void *kmem; SUNMatrix J; SUNLinearSolver LS; y = scale = constraints = NULL; kmem = NULL; J = NULL; LS = NULL; printf("\nRobot Kinematics Example\n"); printf("8 variables; -1 <= x_i <= 1\n"); printf("KINSOL problem size: 8 + 2*8 = 24 \n\n"); /* Create vectors for solution, scales, and constraints */ y = N_VNew_Serial(NEQ); if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1); scale = N_VNew_Serial(NEQ); if (check_flag((void *)scale, "N_VNew_Serial", 0)) return(1); constraints = N_VNew_Serial(NEQ); if (check_flag((void *)constraints, "N_VNew_Serial", 0)) return(1); /* Initialize and allocate memory for KINSOL */ kmem = KINCreate(); if (check_flag((void *)kmem, "KINCreate", 0)) return(1); flag = KINInit(kmem, func, y); /* y passed as a template */ if (check_flag(&flag, "KINInit", 1)) return(1); /* Set optional inputs */ N_VConst_Serial(ZERO,constraints); for (i = NVAR+1; i <= NEQ; i++) Ith(constraints, i) = ONE; flag = KINSetConstraints(kmem, constraints); if (check_flag(&flag, "KINSetConstraints", 1)) return(1); fnormtol = FTOL; flag = KINSetFuncNormTol(kmem, fnormtol); if (check_flag(&flag, "KINSetFuncNormTol", 1)) return(1); scsteptol = STOL; flag = KINSetScaledStepTol(kmem, scsteptol); if (check_flag(&flag, "KINSetScaledStepTol", 1)) return(1); /* Create dense SUNMatrix */ J = SUNDenseMatrix(NEQ, NEQ); if(check_flag((void *)J, "SUNDenseMatrix", 0)) return(1); /* Create dense SUNLinearSolver object */ LS = SUNLinSol_Dense(y, J); if(check_flag((void *)LS, "SUNLinSol_Dense", 0)) return(1); /* Attach the matrix and linear solver to KINSOL */ flag = KINSetLinearSolver(kmem, LS, J); if(check_flag(&flag, "KINSetLinearSolver", 1)) return(1); /* Set the Jacobian function */ flag = KINSetJacFn(kmem, jac); if (check_flag(&flag, "KINSetJacFn", 1)) return(1); /* Indicate exact Newton */ mset = 1; flag = KINSetMaxSetupCalls(kmem, mset); if (check_flag(&flag, "KINSetMaxSetupCalls", 1)) return(1); /* Initial guess */ N_VConst_Serial(ONE, y); for(i = 1; i <= NVAR; i++) Ith(y,i) = SUNRsqrt(TWO)/TWO; printf("Initial guess:\n"); PrintOutput(y); /* Call KINSol to solve problem */ N_VConst_Serial(ONE,scale); flag = KINSol(kmem, /* KINSol memory block */ y, /* initial guess on input; solution vector */ KIN_LINESEARCH, /* global strategy choice */ scale, /* scaling vector, for the variable cc */ scale); /* scaling vector for function values fval */ if (check_flag(&flag, "KINSol", 1)) return(1); printf("\nComputed solution:\n"); PrintOutput(y); /* Print final statistics and free memory */ PrintFinalStats(kmem); N_VDestroy_Serial(y); N_VDestroy_Serial(scale); N_VDestroy_Serial(constraints); KINFree(&kmem); SUNLinSolFree(LS); SUNMatDestroy(J); return(0); }
/*! \fn kinsol_initialization * * \param [ref] [data] * \param [in] [initData] * \param [ref] [initialResiduals] * * \author lochel */ int kinsol_initialization(DATA* data, INIT_DATA* initData, int useScaling) { long i, indz; KINSOL_DATA* kdata = NULL; double fnormtol = 1.e-9; /* function tolerance */ double scsteptol = 1.e-9; /* step tolerance */ long int nni, nfe, nje, nfeD; N_Vector z = NULL; N_Vector sVars = NULL; N_Vector sEqns = NULL; N_Vector c = NULL; int glstr = KIN_NONE; /* globalization strategy applied to the Newton method. It must be one of KIN_NONE or KIN_LINESEARCH */ long int mset = 1; /* maximum number of nonlinear iterations without a call to the preconditioner setup function. Pass 0 to indicate the default [10]. */ void *kmem = NULL; int error_code = -1; ASSERT(data->modelData.nInitResiduals == initData->nz, "The number of initial equations are not consistent with the number of unfixed variables. Select a different initialization."); do /* Try it first with KIN_NONE. If that fails, try it with KIN_LINESEARCH. */ { if(mset == 1 && glstr == KIN_NONE) DEBUG_INFO(LOG_INIT, "using exact Newton"); else if(mset == 1) DEBUG_INFO(LOG_INIT, "using exact Newton with line search"); else if(glstr == KIN_NONE) DEBUG_INFO(LOG_INIT, "using modified Newton"); else DEBUG_INFO(LOG_INIT, "using modified Newton with line search"); DEBUG_INFO_AL1(LOG_INIT, "| mset = %10ld", mset); DEBUG_INFO_AL1(LOG_INIT, "| function tolerance = %10.6g", fnormtol); DEBUG_INFO_AL1(LOG_INIT, "| step tolerance = %10.6g", scsteptol); kdata = (KINSOL_DATA*)malloc(sizeof(KINSOL_DATA)); ASSERT(kdata, "out of memory"); kdata->initData = initData; kdata->data = data; z = N_VNew_Serial(3*initData->nz); ASSERT(z, "out of memory"); sVars = N_VNew_Serial(3*initData->nz); ASSERT(sVars, "out of memory"); sEqns = N_VNew_Serial(3*initData->nz); ASSERT(sEqns, "out of memory"); c = N_VNew_Serial(3*initData->nz); ASSERT(c, "out of memory"); /* initial guess */ for(i=0; i<initData->nz; ++i) { NV_Ith_S(z, i) = initData->start[i]; NV_Ith_S(z, initData->nInitResiduals+2*i+0) = NV_Ith_S(z, i) - initData->min[i]; NV_Ith_S(z, initData->nInitResiduals+2*i+1) = NV_Ith_S(z, i) - initData->max[i]; } kdata->useScaling=useScaling; if(useScaling) { computeInitialResidualScalingCoefficients(data, initData); for(i=0; i<initData->nz; ++i) { NV_Ith_S(sVars, i) = 1.0 / (initData->nominal[i] == 0.0 ? 1.0 : initData->nominal[i]); NV_Ith_S(sVars, initData->nInitResiduals+2*i+0) = NV_Ith_S(sVars, i); NV_Ith_S(sVars, initData->nInitResiduals+2*i+1) = NV_Ith_S(sVars, i); NV_Ith_S(sEqns, i) = 1.0 / (initData->residualScalingCoefficients[i] == 0.0 ? 1.0 : initData->residualScalingCoefficients[i]); NV_Ith_S(sEqns, initData->nInitResiduals+2*i+0) = NV_Ith_S(sEqns, i); NV_Ith_S(sEqns, initData->nInitResiduals+2*i+1) = NV_Ith_S(sEqns, i); } } else { N_VConst_Serial(1.0, sVars); /* no scaling */ N_VConst_Serial(1.0, sEqns); /* no scaling */ } for(i=0; i<initData->nz; ++i) { NV_Ith_S(c, i) = 0.0; /* no constraint on z[i] */ NV_Ith_S(c, initData->nInitResiduals+2*i+0) = 1.0; NV_Ith_S(c, initData->nInitResiduals+2*i+1) = -1.0; } kmem = KINCreate(); ASSERT(kmem, "out of memory"); KINSetErrHandlerFn(kmem, kinsol_errorHandler, NULL); KINSetUserData(kmem, kdata); KINSetConstraints(kmem, c); KINSetFuncNormTol(kmem, fnormtol); KINSetScaledStepTol(kmem, scsteptol); KINInit(kmem, kinsol_residuals, z); /* Call KINDense to specify the linear solver */ KINDense(kmem, 3*initData->nz); KINSetMaxSetupCalls(kmem, mset); /*KINSetNumMaxIters(kmem, 2000);*/ globalInitialResiduals = initData->initialResiduals; error_code = KINSol(kmem, /* KINSol memory block */ z, /* initial guess on input; solution vector */ glstr, /* global stragegy choice */ sVars, /* scaling vector, for the variable cc */ sEqns); /* scaling vector for function values fval */ globalInitialResiduals = NULL; KINGetNumNonlinSolvIters(kmem, &nni); KINGetNumFuncEvals(kmem, &nfe); KINDlsGetNumJacEvals(kmem, &nje); KINDlsGetNumFuncEvals(kmem, &nfeD); DEBUG_INFO(LOG_INIT, "final kinsol statistics"); DEBUG_INFO_AL1(LOG_INIT, "| KINGetNumNonlinSolvIters = %5ld", nni); DEBUG_INFO_AL1(LOG_INIT, "| KINGetNumFuncEvals = %5ld", nfe); DEBUG_INFO_AL1(LOG_INIT, "| KINDlsGetNumJacEvals = %5ld", nje); DEBUG_INFO_AL1(LOG_INIT, "| KINDlsGetNumFuncEvals = %5ld", nfeD); /* Free memory */ N_VDestroy_Serial(z); N_VDestroy_Serial(sVars); N_VDestroy_Serial(sEqns); N_VDestroy_Serial(c); KINFree(&kmem); free(kdata); if(error_code < 0) glstr++; /* try next globalization strategy */ }while(error_code < 0 && glstr <= KIN_LINESEARCH); /* debug output */ indz = 0; DEBUG_INFO(LOG_INIT, "solution"); for(i=0; i<data->modelData.nStates; ++i) if(data->modelData.realVarsData[i].attribute.fixed==0) DEBUG_INFO_AL2(LOG_INIT, "| %s = %g", initData->name[indz++], data->localData[0]->realVars[i]); for(i=0; i<data->modelData.nParametersReal; ++i) if(data->modelData.realParameterData[i].attribute.fixed == 0) DEBUG_INFO_AL2(LOG_INIT, "| %s = %g", initData->name[indz++], data->simulationInfo.realParameter[i]); if(error_code < 0) THROW("kinsol failed. see last warning. use [-lv LOG_INIT] for more output."); return 0; }
static void KIM_Malloc(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int status; mxArray *mx_in[3], *mx_out[2]; int mxiter, msbset, msbsetsub, etachoice, mxnbcf; double eta, egamma, ealpha, mxnewtstep, relfunc, fnormtol, scsteptol; booleantype verbose, noInitSetup, noMinEps; double *constraints; N_Vector NVconstraints; int ptype; int mudq, mldq, mupper, mlower; int maxl, maxrs; double dqrely; /* * ----------------------------- * Find out the vector type and * then pass it to the vector * library. * ----------------------------- */ /* Send vec_type and mx_comm */ InitVectors(); /* * ----------------------------- * Extract stuff from arguments: * - SYS function * - problem dimension * - solver options * - user data * ----------------------------- */ /* Matlab user-provided function */ mxDestroyArray(mx_SYSfct); mx_SYSfct = mxDuplicateArray(prhs[0]); /* problem dimension */ N = (int) mxGetScalar(prhs[1]); /* Solver Options -- optional argument */ status = get_SolverOptions(prhs[2], &verbose, &mxiter, &msbset, &msbsetsub, &etachoice, &mxnbcf, &eta, &egamma, &ealpha, &mxnewtstep, &relfunc, &fnormtol, &scsteptol, &constraints, &noInitSetup, &noMinEps); /* User data -- optional argument */ mxDestroyArray(mx_data); mx_data = mxDuplicateArray(prhs[3]); /* * ----------------------------------------------------- * Set solution vector (used as a template to KINMAlloc) * ----------------------------------------------------- */ y = NewVector(N); /* * ---------------------------------------- * Create kinsol object and allocate memory * ---------------------------------------- */ kin_mem = KINCreate(); /* attach error handler function */ status = KINSetErrHandlerFn(kin_mem, mtlb_KINErrHandler, NULL); if (verbose) { status = KINSetPrintLevel(kin_mem,3); /* attach info handler function */ status = KINSetInfoHandlerFn(kin_mem, mtlb_KINInfoHandler, NULL); /* initialize the output window */ mx_in[0] = mxCreateScalarDouble(0); mx_in[1] = mxCreateScalarDouble(0); /* ignored */ mx_in[2] = mxCreateScalarDouble(0); /* ignored */ mexCallMATLAB(1,mx_out,3,mx_in,"kim_info"); fig_handle = (int)*mxGetPr(mx_out[0]); } /* Call KINMalloc */ status = KINMalloc(kin_mem, mtlb_KINSys, y); /* Redirect output */ status = KINSetErrFile(kin_mem, stdout); /* Optional inputs */ status = KINSetNumMaxIters(kin_mem,mxiter); status = KINSetNoInitSetup(kin_mem,noInitSetup); status = KINSetNoMinEps(kin_mem,noMinEps); status = KINSetMaxSetupCalls(kin_mem,msbset); status = KINSetMaxSubSetupCalls(kin_mem,msbsetsub); status = KINSetMaxBetaFails(kin_mem,mxnbcf); status = KINSetEtaForm(kin_mem,etachoice); status = KINSetEtaConstValue(kin_mem,eta); status = KINSetEtaParams(kin_mem,egamma,ealpha); status = KINSetMaxNewtonStep(kin_mem,mxnewtstep); status = KINSetRelErrFunc(kin_mem,relfunc); status = KINSetFuncNormTol(kin_mem,fnormtol); status = KINSetScaledStepTol(kin_mem,scsteptol); if (constraints != NULL) { NVconstraints = N_VCloneEmpty(y); N_VSetArrayPointer(constraints, NVconstraints); status = KINSetConstraints(kin_mem,NVconstraints); N_VDestroy(NVconstraints); } status = get_LinSolvOptions(prhs[2], &mupper, &mlower, &mudq, &mldq, &dqrely, &ptype, &maxrs, &maxl); switch (ls) { case LS_NONE: mexErrMsgTxt("KINMalloc:: no linear solver specified."); break; case LS_DENSE: status = KINDense(kin_mem, N); if (!mxIsEmpty(mx_JACfct)) status = KINDenseSetJacFn(kin_mem, mtlb_KINDenseJac, NULL); break; case LS_BAND: status = KINBand(kin_mem, N, mupper, mlower); if (!mxIsEmpty(mx_JACfct)) status = KINBandSetJacFn(kin_mem, mtlb_KINBandJac, NULL); break; case LS_SPGMR: switch(pm) { case PM_NONE: status = KINSpgmr(kin_mem, maxl); if (!mxIsEmpty(mx_PSOLfct)) { if (!mxIsEmpty(mx_PSETfct)) status = KINSpilsSetPreconditioner(kin_mem, mtlb_KINSpilsPset, mtlb_KINSpilsPsol, NULL); else status = KINSpilsSetPreconditioner(kin_mem, NULL, mtlb_KINSpilsPsol, NULL); } break; case PM_BBDPRE: if (!mxIsEmpty(mx_GCOMfct)) bbd_data = KINBBDPrecAlloc(kin_mem, N, mudq, mldq, mupper, mlower, dqrely, mtlb_KINGloc, mtlb_KINGcom); else bbd_data = KINBBDPrecAlloc(kin_mem, N, mudq, mldq, mupper, mlower, dqrely, mtlb_KINGloc, NULL); status = KINBBDSpgmr(kin_mem, maxl, bbd_data); break; } status = KINSpilsSetMaxRestarts(kin_mem, maxrs); if (!mxIsEmpty(mx_JACfct)) status = KINSpilsSetJacTimesVecFn(kin_mem, mtlb_KINSpilsJac, NULL); break; case LS_SPBCG: switch(pm) { case PM_NONE: status = KINSpbcg(kin_mem, maxl); if (!mxIsEmpty(mx_PSOLfct)) { if (!mxIsEmpty(mx_PSETfct)) status = KINSpilsSetPreconditioner(kin_mem, mtlb_KINSpilsPset, mtlb_KINSpilsPsol, NULL); else status = KINSpilsSetPreconditioner(kin_mem, NULL, mtlb_KINSpilsPsol, NULL); } break; case PM_BBDPRE: if (!mxIsEmpty(mx_GCOMfct)) bbd_data = KINBBDPrecAlloc(kin_mem, N, mudq, mldq, mupper, mlower, dqrely, mtlb_KINGloc, mtlb_KINGcom); else bbd_data = KINBBDPrecAlloc(kin_mem, N, mudq, mldq, mupper, mlower, dqrely, mtlb_KINGloc, NULL); status = KINBBDSpbcg(kin_mem, maxl, bbd_data); break; } if (!mxIsEmpty(mx_JACfct)) status = KINSpilsSetJacTimesVecFn(kin_mem, mtlb_KINSpilsJac, NULL); break; case LS_SPTFQMR: switch(pm) { case PM_NONE: status = KINSptfqmr(kin_mem, maxl); if (!mxIsEmpty(mx_PSOLfct)) { if (!mxIsEmpty(mx_PSETfct)) status = KINSpilsSetPreconditioner(kin_mem, mtlb_KINSpilsPset, mtlb_KINSpilsPsol, NULL); else status = KINSpilsSetPreconditioner(kin_mem, NULL, mtlb_KINSpilsPsol, NULL); } break; case PM_BBDPRE: if (!mxIsEmpty(mx_GCOMfct)) bbd_data = KINBBDPrecAlloc(kin_mem, N, mudq, mldq, mupper, mlower, dqrely, mtlb_KINGloc, mtlb_KINGcom); else bbd_data = KINBBDPrecAlloc(kin_mem, N, mudq, mldq, mupper, mlower, dqrely, mtlb_KINGloc, NULL); status = KINBBDSptfqmr(kin_mem, maxl, bbd_data); break; } if (!mxIsEmpty(mx_JACfct)) status = KINSpilsSetJacTimesVecFn(kin_mem, mtlb_KINSpilsJac, NULL); break; } return; }
bool kinsol_solve(void) { double fnormtol; N_Vector y, scale, constraints; int mset, flag; void *kmem; y = scale = constraints = NULL; kmem = NULL; /* Create vectors for solution, scales, and constraints */ y = N_VMake_Serial(nvariables, variables); if (y == NULL) goto cleanup; scale = N_VNew_Serial(nvariables); if (scale == NULL) goto cleanup; constraints = N_VNew_Serial(nvariables); if (constraints == NULL) goto cleanup; /* Initialize and allocate memory for KINSOL */ kmem = KINCreate(); if (kmem == NULL) goto cleanup; flag = KINInit(kmem, _f, y); if (flag < 0) goto cleanup; // This constrains metabolites >= 0 N_VConst_Serial(1.0, constraints); flag = KINSetConstraints(kmem, constraints); if (flag < 0) goto cleanup; fnormtol = ARGS.ABSTOL; flag = KINSetFuncNormTol(kmem, fnormtol); if (flag < 0) goto cleanup; //scsteptol = ARGS.RELTOL; //flag = KINSetScaledStepTol(kmem, scsteptol); //if (flag < 0) goto cleanup; /* Attach dense linear solver */ flag = KINDense(kmem, nvariables); if (flag < 0) goto cleanup; flag = KINDlsSetDenseJacFn(kmem, _dfdy); if (flag < 0) goto cleanup; /* Indicate exact Newton */ //This makes sure that the user-supplied Jacobian gets evaluated onevery step. mset = 1; flag = KINSetMaxSetupCalls(kmem, mset); if (flag < 0) goto cleanup; /* Initial guess is the intial variable concentrations */ /* Call KINSol to solve problem */ N_VConst_Serial(1.0,scale); flag = KINSol(kmem, /* KINSol memory block */ y, /* initial guess on input; solution vector */ KIN_NONE, /* basic Newton iteration */ scale, /* scaling vector, for the variable cc */ scale); /* scaling vector for function values fval */ if((ARGS.MODE != ABC) and (ARGS.MODE != ABCSIM) and (ARGS.MODE != Prior)) OUT_nums(); if (flag < 0) goto cleanup; N_VDestroy_Serial(y); N_VDestroy_Serial(scale); N_VDestroy_Serial(constraints); KINFree(&kmem); return true; cleanup: error("Could not integrate!\n"); if (y!=NULL) N_VDestroy_Serial(y); if (scale!=NULL) N_VDestroy_Serial(scale); if (constraints!=NULL) N_VDestroy_Serial(constraints); if (kmem!=NULL) KINFree(&kmem); return false; }