static void PrintFinalStats(void *kmem) { long int nni, nfe, nli, npe, nps, ncfl, nfeSG; int flag; flag = KINGetNumNonlinSolvIters(kmem, &nni); check_flag(&flag, "KINGetNumNonlinSolvIters", 1); flag = KINGetNumFuncEvals(kmem, &nfe); check_flag(&flag, "KINGetNumFuncEvals", 1); flag = KINSpilsGetNumLinIters(kmem, &nli); check_flag(&flag, "KINSpilsGetNumLinIters", 1); flag = KINSpilsGetNumPrecEvals(kmem, &npe); check_flag(&flag, "KINSpilsGetNumPrecEvals", 1); flag = KINSpilsGetNumPrecSolves(kmem, &nps); check_flag(&flag, "KINSpilsGetNumPrecSolves", 1); flag = KINSpilsGetNumConvFails(kmem, &ncfl); check_flag(&flag, "KINSpilsGetNumConvFails", 1); flag = KINSpilsGetNumFuncEvals(kmem, &nfeSG); check_flag(&flag, "KINSpilsGetNumFuncEvals", 1); printf("Final Statistics.. \n"); printf("nni = %5ld nli = %5ld\n", nni, nli); printf("nfe = %5ld nfeSG = %5ld\n", nfe, nfeSG); printf("nps = %5ld npe = %5ld ncfl = %5ld\n", nps, npe, ncfl); }
static void PrintFinalStats(void *kmem) { long int nni, nfe, nje, nfeD; long int lenrwB, leniwB; int flag; /* Main solver statistics */ flag = KINGetNumNonlinSolvIters(kmem, &nni); check_flag(&flag, "KINGetNumNonlinSolvIters", 1); flag = KINGetNumFuncEvals(kmem, &nfe); check_flag(&flag, "KINGetNumFuncEvals", 1); /* Band linear solver statistics */ flag = KINDlsGetNumJacEvals(kmem, &nje); check_flag(&flag, "KINDlsGetNumJacEvals", 1); flag = KINDlsGetNumFuncEvals(kmem, &nfeD); check_flag(&flag, "KINDlsGetNumFuncEvals", 1); /* Band linear solver workspace size */ flag = KINDlsGetWorkSpace(kmem, &lenrwB, &leniwB); check_flag(&flag, "KINDlsGetWorkSpace", 1); printf("\nFinal Statistics.. \n\n"); printf("nni = %6ld nfe = %6ld \n", nni, nfe); printf("nje = %6ld nfeB = %6ld \n", nje, nfeD); printf("\n"); printf("lenrwB = %6ld leniwB = %6ld \n", lenrwB, leniwB); }
static void PrintFinalStats(void *kmem) { long int nni, nfe, nje, nfeD; int flag; flag = KINGetNumNonlinSolvIters(kmem, &nni); check_flag(&flag, "KINGetNumNonlinSolvIters", 1); flag = KINGetNumFuncEvals(kmem, &nfe); check_flag(&flag, "KINGetNumFuncEvals", 1); flag = KINDlsGetNumJacEvals(kmem, &nje); check_flag(&flag, "KINDlsGetNumJacEvals", 1); flag = KINDlsGetNumFuncEvals(kmem, &nfeD); check_flag(&flag, "KINDlsGetNumFuncEvals", 1); printf("Final Statistics:\n"); printf(" nni = %5ld nfe = %5ld \n", nni, nfe); printf(" nje = %5ld nfeD = %5ld \n", nje, nfeD); }
int nlsKinsolSolve(DATA *data, threadData_t *threadData, int sysNumber) { NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]); NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*)nlsData->solverData; long eqSystemNumber = nlsData->equationIndex; int indexes[2] = {1,eqSystemNumber}; int flag, i; long nFEval; int success = 0; int retry = 0; double *xStart = NV_DATA_S(kinsolData->initialGuess); double *xScaling = NV_DATA_S(kinsolData->xScale); double *fScaling = NV_DATA_S(kinsolData->fScale); double fNormValue; /* set user data */ kinsolData->userData.data = data; kinsolData->userData.threadData = threadData; kinsolData->userData.sysNumber = sysNumber; /* reset configuration settings */ nlsKinsolConfigSetup(kinsolData); infoStreamPrint(LOG_NLS, 0, "------------------------------------------------------"); infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "Start solving non-linear system >>%ld<< using Kinsol solver at time %g", eqSystemNumber, data->localData[0]->timeValue); nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION); /* set x scaling */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_NOMINALSTART); /* set f scaling */ _omc_fillVector(_omc_createVector(nlsData->size, fScaling), 1.); /* */ do{ /* dump configuration */ nlsKinsolConfigPrint(kinsolData, nlsData); flag = KINSol(kinsolData->kinsolMemory, /* KINSol memory block */ kinsolData->initialGuess, /* initial guess on input; solution vector */ kinsolData->kinsolStrategy, /* global strategy choice */ kinsolData->xScale, /* scaling vector, for the variable cc */ kinsolData->fScale); /* scaling vector for function values fval */ infoStreamPrint(LOG_NLS_V, 0, "KINSol finished with errorCode %d.", flag); /* check for errors */ if(flag < 0) { retry = nlsKinsolErrorHandler(flag, data, nlsData, kinsolData); } /* solution found */ if ((flag == KIN_SUCCESS) || (flag == KIN_INITIAL_GUESS_OK) || (flag == KIN_STEP_LT_STPTOL)) { success = 1; } kinsolData->retries++; /* write statistics */ KINGetNumNonlinSolvIters(kinsolData->kinsolMemory, &nFEval); nlsData->numberOfIterations += nFEval; nlsData->numberOfFEval += kinsolData->countResCalls; infoStreamPrint(LOG_NLS_V, 0, "Next try? success = %d, retry = %d, retries = %d = %s\n", success, retry, kinsolData->retries,!success && !(retry<1) && kinsolData->retries<RETRY_MAX ? "true" : "false" ); }while(!success && !(retry<0) && kinsolData->retries < RETRY_MAX); /* solution found */ if (success) { /* check if solution really solves the residuals */ nlsKinsolResiduals(kinsolData->initialGuess, kinsolData->fRes, &kinsolData->userData); fNormValue = N_VWL2Norm(kinsolData->fRes, kinsolData->fRes); infoStreamPrint(LOG_NLS, 0, "scaled Euclidean norm of F(u) = %e", fNormValue); if (FTOL_WITH_LESS_ACCURANCY<fNormValue) { warningStreamPrint(LOG_NLS, 0, "False positive solution. FNorm is too small."); success = 0; } else /* solved system for reuse linear solver information */ { kinsolData->solved = 1; } /* copy solution */ memcpy(nlsData->nlsx, xStart, nlsData->size*(sizeof(double))); /* dump solution */ if(ACTIVE_STREAM(LOG_NLS)) { infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "solution for NLS %ld at t=%g", eqSystemNumber, kinsolData->userData.data->localData[0]->timeValue); for(i=0; i<nlsData->size; ++i) { infoStreamPrintWithEquationIndexes(LOG_NLS, 0, indexes, "[%d] %s = %g", i+1, modelInfoGetEquation(&kinsolData->userData.data->modelData->modelDataXml,eqSystemNumber).vars[i], nlsData->nlsx[i]); } messageClose(LOG_NLS); } } messageClose(LOG_NLS); return success; }
void FKIN_SOL(realtype *uu, int *globalstrategy, realtype *uscale , realtype *fscale, int *ier) { N_Vector uuvec, uscalevec, fscalevec; *ier = 0; uuvec = uscalevec = fscalevec = NULL; uuvec = F2C_KINSOL_vec; N_VSetArrayPointer(uu, uuvec); uscalevec = NULL; uscalevec = N_VCloneEmpty(F2C_KINSOL_vec); if (uscalevec == NULL) { *ier = -4; /* KIN_MEM_FAIL */ return; } N_VSetArrayPointer(uscale, uscalevec); fscalevec = NULL; fscalevec = N_VCloneEmpty(F2C_KINSOL_vec); if (fscalevec == NULL) { N_VDestroy(uscalevec); *ier = -4; /* KIN_MEM_FAIL */ return; } N_VSetArrayPointer(fscale, fscalevec); /* Call main solver function */ *ier = KINSol(KIN_kinmem, uuvec, *globalstrategy, uscalevec, fscalevec); N_VSetArrayPointer(NULL, uuvec); N_VSetArrayPointer(NULL, uscalevec); N_VDestroy(uscalevec); N_VSetArrayPointer(NULL, fscalevec); N_VDestroy(fscalevec); /* load optional outputs into iout[] and rout[] */ KINGetWorkSpace(KIN_kinmem, &KIN_iout[0], &KIN_iout[1]); /* LENRW & LENIW */ KINGetNumNonlinSolvIters(KIN_kinmem, &KIN_iout[2]); /* NNI */ KINGetNumFuncEvals(KIN_kinmem, &KIN_iout[3]); /* NFE */ KINGetNumBetaCondFails(KIN_kinmem, &KIN_iout[4]); /* NBCF */ KINGetNumBacktrackOps(KIN_kinmem, &KIN_iout[5]); /* NBCKTRK */ KINGetFuncNorm(KIN_kinmem, &KIN_rout[0]); /* FNORM */ KINGetStepLength(KIN_kinmem, &KIN_rout[1]); /* SSTEP */ switch(KIN_ls) { case KIN_LS_DENSE: case KIN_LS_BAND: case KIN_LS_LAPACKDENSE: case KIN_LS_LAPACKBAND: KINDlsGetWorkSpace(KIN_kinmem, &KIN_iout[6], &KIN_iout[7]); /* LRW & LIW */ KINDlsGetLastFlag(KIN_kinmem, (int *) &KIN_iout[8]); /* LSTF */ KINDlsGetNumFuncEvals(KIN_kinmem, &KIN_iout[9]); /* NFE */ KINDlsGetNumJacEvals(KIN_kinmem, &KIN_iout[10]); /* NJE */ case KIN_LS_SPTFQMR: case KIN_LS_SPBCG: case KIN_LS_SPGMR: KINSpilsGetWorkSpace(KIN_kinmem, &KIN_iout[6], &KIN_iout[7]); /* LRW & LIW */ KINSpilsGetLastFlag(KIN_kinmem, (int *) &KIN_iout[8]); /* LSTF */ KINSpilsGetNumFuncEvals(KIN_kinmem, &KIN_iout[9]); /* NFE */ KINSpilsGetNumJtimesEvals(KIN_kinmem, &KIN_iout[10]); /* NJE */ KINSpilsGetNumPrecEvals(KIN_kinmem, &KIN_iout[11]); /* NPE */ KINSpilsGetNumPrecSolves(KIN_kinmem, &KIN_iout[12]); /* NPS */ KINSpilsGetNumLinIters(KIN_kinmem, &KIN_iout[13]); /* NLI */ KINSpilsGetNumConvFails(KIN_kinmem, &KIN_iout[14]); /* NCFL */ break; } return; }
/*! \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_Stats(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const char *fnames_solver[]= { "nfe", "nni", "nbcf", "nbops", "fnorm", "step", "LSInfo", }; const char *fnames_dense[]= { "name", "njeD", "nfeD" }; const char *fnames_spils[]= { "name", "nli", "npe", "nps", "ncfl", }; long int nfe, nni, nbcf, nbops; double fnorm, step; long int njeD, nfeD; long int nli, npe, nps, ncfl; int flag; mxArray *mx_ls; int nfields; if (kim_Kdata == NULL) return; flag = KINGetNumNonlinSolvIters(kin_mem, &nni); flag = KINGetNumFuncEvals(kin_mem, &nfe); flag = KINGetNumBetaCondFails(kin_mem, &nbcf); flag = KINGetNumBacktrackOps(kin_mem, &nbops); flag = KINGetFuncNorm(kin_mem, &fnorm); flag = KINGetStepLength(kin_mem, &step); nfields = sizeof(fnames_solver)/sizeof(*fnames_solver); plhs[0] = mxCreateStructMatrix(1, 1, nfields, fnames_solver); mxSetField(plhs[0], 0, "nfe", mxCreateScalarDouble((double)nfe)); mxSetField(plhs[0], 0, "nni", mxCreateScalarDouble((double)nni)); mxSetField(plhs[0], 0, "nbcf", mxCreateScalarDouble((double)nbcf)); mxSetField(plhs[0], 0, "nbops", mxCreateScalarDouble((double)nbops)); mxSetField(plhs[0], 0, "fnorm", mxCreateScalarDouble(fnorm)); mxSetField(plhs[0], 0, "step", mxCreateScalarDouble(step)); /* Linear Solver Statistics */ switch(ls) { case LS_DENSE: flag = KINDenseGetNumJacEvals(kin_mem, &njeD); flag = KINDenseGetNumFuncEvals(kin_mem, &nfeD); nfields = sizeof(fnames_dense)/sizeof(*fnames_dense); mx_ls = mxCreateStructMatrix(1, 1, nfields, fnames_dense); mxSetField(mx_ls, 0, "name", mxCreateString("Dense")); mxSetField(mx_ls, 0, "njeD", mxCreateScalarDouble((double)njeD)); mxSetField(mx_ls, 0, "nfeD", mxCreateScalarDouble((double)nfeD)); break; case LS_SPGMR: case LS_SPBCG: case LS_SPTFQMR: flag = KINSpilsGetNumLinIters(kin_mem, &nli); flag = KINSpilsGetNumPrecEvals(kin_mem, &npe); flag = KINSpilsGetNumPrecSolves(kin_mem, &nps); flag = KINSpilsGetNumConvFails(kin_mem, &ncfl); nfields = sizeof(fnames_spils)/sizeof(*fnames_spils); mx_ls = mxCreateStructMatrix(1, 1, nfields, fnames_spils); if (ls == LS_SPGMR) mxSetField(mx_ls, 0, "name", mxCreateString("GMRES")); else if (ls == LS_SPBCG) mxSetField(mx_ls, 0, "name", mxCreateString("BiCGStab")); else mxSetField(mx_ls, 0, "name", mxCreateString("TFQMR")); mxSetField(mx_ls, 0, "nli", mxCreateScalarDouble((double)nli)); mxSetField(mx_ls, 0, "npe", mxCreateScalarDouble((double)npe)); mxSetField(mx_ls, 0, "nps", mxCreateScalarDouble((double)nps)); mxSetField(mx_ls, 0, "ncfl", mxCreateScalarDouble((double)ncfl)); break; } mxSetField(plhs[0], 0, "LSInfo", mx_ls); return; }