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; }
void FKIN_KLUREINIT(int *neq, int *nnz, int *reinit_type, int *ier) { *ier = KINKLUReInit(KIN_kinmem, *neq, *nnz, *reinit_type); }