void KinsolSolver::initialize(ComputeSystemFunction pComputeSystem, double *pParameters, int pSize, void *pUserData) { if (mSolver) // The solver has already been initialised, so reset things... reset(); // Initialise the ODE solver itself OpenCOR::CoreSolver::CoreNlaSolver::initialize(pComputeSystem, pParameters, pSize); // Create some vectors mParametersVector = N_VMake_Serial(pSize, pParameters); mOnesVector = N_VNew_Serial(pSize); N_VConst(1.0, mOnesVector); // Create the KINSOL solver mSolver = KINCreate(); // Use our own error handler KINSetErrHandlerFn(mSolver, errorHandler, this); // Initialise the KINSOL solver KINInit(mSolver, systemFunction, mParametersVector); // Set some user data mUserData = new KinsolSolverUserData(pUserData, pComputeSystem); KINSetUserData(mSolver, mUserData); // Set the linear solver KINDense(mSolver, pSize); }
int nlsKinsolAllocate(int size, NONLINEAR_SYSTEM_DATA *nlsData, int linearSolverMethod) { int i, flag, printLevel; NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*) malloc(sizeof(NLS_KINSOL_DATA)); /* allocate system data */ nlsData->solverData = (void*)kinsolData; kinsolData->size = size; kinsolData->linearSolverMethod = linearSolverMethod; kinsolData->solved = 0; kinsolData->fnormtol = sqrt(newtonFTol); /* function tolerance */ kinsolData->scsteptol = sqrt(newtonXTol); /* step tolerance */ kinsolData->initialGuess = N_VNew_Serial(size); kinsolData->xScale = N_VNew_Serial(size); kinsolData->fScale = N_VNew_Serial(size); kinsolData->fRes = N_VNew_Serial(size); kinsolData->kinsolMemory = KINCreate(); /* setup user defined functions */ KINSetErrHandlerFn(kinsolData->kinsolMemory, nlsKinsolErrorPrint, kinsolData); KINSetInfoHandlerFn(kinsolData->kinsolMemory, nlsKinsolInfoPrint, kinsolData); KINSetUserData(kinsolData->kinsolMemory, (void*)&(kinsolData->userData)); flag = KINInit(kinsolData->kinsolMemory, nlsKinsolResiduals, kinsolData->initialGuess); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } /* Specify linear solver and/or corresponding jacobian function*/ if (kinsolData->linearSolverMethod == 3) { if(nlsData->isPatternAvailable) { kinsolData->nnz = nlsData->sparsePattern.numberOfNoneZeros; flag = KINKLU(kinsolData->kinsolMemory, size, kinsolData->nnz); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } flag = KINSlsSetSparseJacFn(kinsolData->kinsolMemory, nlsSparseJac); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL Sparse Solver!"); } } else { flag = KINDense(kinsolData->kinsolMemory, size); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } } } else if (kinsolData->linearSolverMethod == 1) { flag = KINDense(kinsolData->kinsolMemory, size); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } } else if (kinsolData->linearSolverMethod == 2) { flag = KINDense(kinsolData->kinsolMemory, size); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } flag = KINDlsSetDenseJacFn(kinsolData->kinsolMemory, nlsDenseJac); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL Sparse Solver!"); } } /* configuration */ nlsKinsolConfigSetup(kinsolData); /* debug print level of kinsol */ if (ACTIVE_STREAM(LOG_NLS)) printLevel = 1; else if (ACTIVE_STREAM(LOG_NLS_V)) printLevel = 3; else printLevel = 0; KINSetPrintLevel(kinsolData->kinsolMemory, printLevel); return 0; }
int main(void) { int globalstrategy; realtype fnormtol, scsteptol; N_Vector cc, sc, constraints; UserData data; int flag, maxl, maxlrst; void *kmem; cc = sc = constraints = NULL; kmem = NULL; data = NULL; /* Allocate memory, and set problem data, initial values, tolerances */ globalstrategy = KIN_NONE; data = AllocUserData(); if (check_flag((void *)data, "AllocUserData", 2)) return(1); InitUserData(data); /* Create serial vectors of length NEQ */ cc = N_VNew_Serial(NEQ); if (check_flag((void *)cc, "N_VNew_Serial", 0)) return(1); sc = N_VNew_Serial(NEQ); if (check_flag((void *)sc, "N_VNew_Serial", 0)) return(1); data->rates = N_VNew_Serial(NEQ); if (check_flag((void *)data->rates, "N_VNew_Serial", 0)) return(1); constraints = N_VNew_Serial(NEQ); if (check_flag((void *)constraints, "N_VNew_Serial", 0)) return(1); N_VConst(TWO, constraints); SetInitialProfiles(cc, sc); fnormtol=FTOL; scsteptol=STOL; /* Call KINCreate/KINInit to initialize KINSOL. A pointer to KINSOL problem memory is returned and stored in kmem. */ kmem = KINCreate(); if (check_flag((void *)kmem, "KINCreate", 0)) return(1); /* Vector cc passed as template vector. */ flag = KINInit(kmem, func, cc); if (check_flag(&flag, "KINInit", 1)) return(1); flag = KINSetUserData(kmem, data); if (check_flag(&flag, "KINSetUserData", 1)) return(1); flag = KINSetConstraints(kmem, constraints); if (check_flag(&flag, "KINSetConstraints", 1)) return(1); flag = KINSetFuncNormTol(kmem, fnormtol); if (check_flag(&flag, "KINSetFuncNormTol", 1)) return(1); flag = KINSetScaledStepTol(kmem, scsteptol); if (check_flag(&flag, "KINSetScaledStepTol", 1)) return(1); /* We no longer need the constraints vector since KINSetConstraints creates a private copy for KINSOL to use. */ N_VDestroy_Serial(constraints); /* Call KINSpgmr to specify the linear solver KINSPGMR with preconditioner routines PrecSetupBD and PrecSolveBD. */ maxl = 15; maxlrst = 2; flag = KINSpgmr(kmem, maxl); if (check_flag(&flag, "KINSpgmr", 1)) return(1); flag = KINSpilsSetMaxRestarts(kmem, maxlrst); if (check_flag(&flag, "KINSpilsSetMaxRestarts", 1)) return(1); flag = KINSpilsSetPreconditioner(kmem, PrecSetupBD, PrecSolveBD); if (check_flag(&flag, "KINSpilsSetPreconditioner", 1)) return(1); /* Print out the problem size, solution parameters, initial guess. */ PrintHeader(globalstrategy, maxl, maxlrst, fnormtol, scsteptol); /* Call KINSol and print output concentration profile */ flag = KINSol(kmem, /* KINSol memory block */ cc, /* initial guess on input; solution vector */ globalstrategy, /* global stragegy choice */ sc, /* scaling vector, for the variable cc */ sc); /* scaling vector for function values fval */ if (check_flag(&flag, "KINSol", 1)) return(1); printf("\n\nComputed equilibrium species concentrations:\n"); PrintOutput(cc); /* Print final statistics and free memory */ PrintFinalStats(kmem); N_VDestroy_Serial(cc); N_VDestroy_Serial(sc); KINFree(&kmem); FreeUserData(data); return(0); }
int main(int argc, char *argv[]) { MPI_Comm comm; void *kmem; UserData data; N_Vector cc, sc, constraints; int globalstrategy; long int Nlocal; realtype fnormtol, scsteptol, dq_rel_uu; int flag, maxl, maxlrst; long int mudq, mldq, mukeep, mlkeep; int my_pe, npes, npelast = NPEX*NPEY-1; data = NULL; kmem = NULL; cc = sc = constraints = NULL; /* Get processor number and total number of pe's */ MPI_Init(&argc, &argv); comm = MPI_COMM_WORLD; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &my_pe); if (npes != NPEX*NPEY) { if (my_pe == 0) printf("\nMPI_ERROR(0): npes=%d is not equal to NPEX*NPEY=%d\n", npes, NPEX*NPEY); return(1); } /* Allocate memory, and set problem data, initial values, tolerances */ /* Set local length */ Nlocal = NUM_SPECIES*MXSUB*MYSUB; /* Allocate and initialize user data block */ data = AllocUserData(); if (check_flag((void *)data, "AllocUserData", 2, my_pe)) MPI_Abort(comm, 1); InitUserData(my_pe, Nlocal, comm, data); /* Choose global strategy */ globalstrategy = KIN_NONE; /* Allocate and initialize vectors */ cc = N_VNew_Parallel(comm, Nlocal, NEQ); if (check_flag((void *)cc, "N_VNew_Parallel", 0, my_pe)) MPI_Abort(comm, 1); sc = N_VNew_Parallel(comm, Nlocal, NEQ); if (check_flag((void *)sc, "N_VNew_Parallel", 0, my_pe)) MPI_Abort(comm, 1); data->rates = N_VNew_Parallel(comm, Nlocal, NEQ); if (check_flag((void *)data->rates, "N_VNew_Parallel", 0, my_pe)) MPI_Abort(comm, 1); constraints = N_VNew_Parallel(comm, Nlocal, NEQ); if (check_flag((void *)constraints, "N_VNew_Parallel", 0, my_pe)) MPI_Abort(comm, 1); N_VConst(ZERO, constraints); SetInitialProfiles(cc, sc); fnormtol = FTOL; scsteptol = STOL; /* Call KINCreate/KINInit to initialize KINSOL: nvSpec points to machine environment data A pointer to KINSOL problem memory is returned and stored in kmem. */ kmem = KINCreate(); if (check_flag((void *)kmem, "KINCreate", 0, my_pe)) MPI_Abort(comm, 1); /* Vector cc passed as template vector. */ flag = KINInit(kmem, func, cc); if (check_flag(&flag, "KINInit", 1, my_pe)) MPI_Abort(comm, 1); flag = KINSetUserData(kmem, data); if (check_flag(&flag, "KINSetUserData", 1, my_pe)) MPI_Abort(comm, 1); flag = KINSetConstraints(kmem, constraints); if (check_flag(&flag, "KINSetConstraints", 1, my_pe)) MPI_Abort(comm, 1); /* We no longer need the constraints vector since KINSetConstraints creates a private copy for KINSOL to use. */ N_VDestroy_Parallel(constraints); flag = KINSetFuncNormTol(kmem, fnormtol); if (check_flag(&flag, "KINSetFuncNormTol", 1, my_pe)) MPI_Abort(comm, 1); flag = KINSetScaledStepTol(kmem, scsteptol); if (check_flag(&flag, "KINSetScaledStepTol", 1, my_pe)) MPI_Abort(comm, 1); /* Call KINBBDPrecInit to initialize and allocate memory for the band-block-diagonal preconditioner, and specify the local and communication functions func_local and gcomm=NULL (all communication needed for the func_local is already done in func). */ dq_rel_uu = ZERO; mudq = mldq = 2*NUM_SPECIES - 1; mukeep = mlkeep = NUM_SPECIES; /* Call KINBBDSpgmr to specify the linear solver KINSPGMR */ maxl = 20; maxlrst = 2; flag = KINSpgmr(kmem, maxl); if (check_flag(&flag, "KINSpgmr", 1, my_pe)) MPI_Abort(comm, 1); /* Initialize BBD preconditioner */ flag = KINBBDPrecInit(kmem, Nlocal, mudq, mldq, mukeep, mlkeep, dq_rel_uu, func_local, NULL); if (check_flag(&flag, "KINBBDPrecInit", 1, my_pe)) MPI_Abort(comm, 1); flag = KINSpilsSetMaxRestarts(kmem, maxlrst); if (check_flag(&flag, "KINSpilsSetMaxRestarts", 1, my_pe)) MPI_Abort(comm, 1); /* Print out the problem size, solution parameters, initial guess. */ if (my_pe == 0) PrintHeader(globalstrategy, maxl, maxlrst, mudq, mldq, mukeep, mlkeep, fnormtol, scsteptol); /* call KINSol and print output concentration profile */ flag = KINSol(kmem, /* KINSol memory block */ cc, /* initial guesss on input; solution vector */ globalstrategy, /* global stragegy choice */ sc, /* scaling vector, for the variable cc */ sc); /* scaling vector for function values fval */ if (check_flag(&flag, "KINSol", 1, my_pe)) MPI_Abort(comm, 1); if (my_pe == 0) printf("\n\nComputed equilibrium species concentrations:\n"); if (my_pe == 0 || my_pe==npelast) PrintOutput(my_pe, comm, cc); /* Print final statistics and free memory */ if (my_pe == 0) PrintFinalStats(kmem); N_VDestroy_Parallel(cc); N_VDestroy_Parallel(sc); KINFree(&kmem); FreeUserData(data); MPI_Finalize(); return(0); }
int main() { UserData data; realtype fnormtol, scsteptol; N_Vector u1, u2, u, s, c; int glstr, mset, flag; void *kmem; u1 = u2 = u = NULL; s = c = NULL; kmem = NULL; data = NULL; /* User data */ data = (UserData)malloc(sizeof *data); data->lb[0] = PT25; data->ub[0] = ONE; data->lb[1] = ONEPT5; data->ub[1] = TWO*PI; /* Create serial vectors of length NEQ */ u1 = N_VNew_Serial(NEQ); if (check_flag((void *)u1, "N_VNew_Serial", 0)) return(1); u2 = N_VNew_Serial(NEQ); if (check_flag((void *)u2, "N_VNew_Serial", 0)) return(1); u = N_VNew_Serial(NEQ); if (check_flag((void *)u, "N_VNew_Serial", 0)) return(1); s = N_VNew_Serial(NEQ); if (check_flag((void *)s, "N_VNew_Serial", 0)) return(1); c = N_VNew_Serial(NEQ); if (check_flag((void *)c, "N_VNew_Serial", 0)) return(1); SetInitialGuess1(u1,data); SetInitialGuess2(u2,data); N_VConst_Serial(ONE,s); /* no scaling */ Ith(c,1) = ZERO; /* no constraint on x1 */ Ith(c,2) = ZERO; /* no constraint on x2 */ Ith(c,3) = ONE; /* l1 = x1 - x1_min >= 0 */ Ith(c,4) = -ONE; /* L1 = x1 - x1_max <= 0 */ Ith(c,5) = ONE; /* l2 = x2 - x2_min >= 0 */ Ith(c,6) = -ONE; /* L2 = x2 - x22_min <= 0 */ fnormtol=FTOL; scsteptol=STOL; kmem = KINCreate(); if (check_flag((void *)kmem, "KINCreate", 0)) return(1); flag = KINSetUserData(kmem, data); if (check_flag(&flag, "KINSetUserData", 1)) return(1); flag = KINSetConstraints(kmem, c); if (check_flag(&flag, "KINSetConstraints", 1)) return(1); flag = KINSetFuncNormTol(kmem, fnormtol); if (check_flag(&flag, "KINSetFuncNormTol", 1)) return(1); flag = KINSetScaledStepTol(kmem, scsteptol); if (check_flag(&flag, "KINSetScaledStepTol", 1)) return(1); flag = KINInit(kmem, func, u); if (check_flag(&flag, "KINInit", 1)) return(1); /* Call KINDense to specify the linear solver */ flag = KINDense(kmem, NEQ); if (check_flag(&flag, "KINDense", 1)) return(1); /* Print out the problem size, solution parameters, initial guess. */ PrintHeader(fnormtol, scsteptol); /* --------------------------- */ printf("\n------------------------------------------\n"); printf("\nInitial guess on lower bounds\n"); printf(" [x1,x2] = "); PrintOutput(u1); N_VScale_Serial(ONE,u1,u); glstr = KIN_NONE; mset = 1; SolveIt(kmem, u, s, glstr, mset); /* --------------------------- */ N_VScale_Serial(ONE,u1,u); glstr = KIN_LINESEARCH; mset = 1; SolveIt(kmem, u, s, glstr, mset); /* --------------------------- */ N_VScale_Serial(ONE,u1,u); glstr = KIN_NONE; mset = 0; SolveIt(kmem, u, s, glstr, mset); /* --------------------------- */ N_VScale_Serial(ONE,u1,u); glstr = KIN_LINESEARCH; mset = 0; SolveIt(kmem, u, s, glstr, mset); /* --------------------------- */ printf("\n------------------------------------------\n"); printf("\nInitial guess in middle of feasible region\n"); printf(" [x1,x2] = "); PrintOutput(u2); N_VScale_Serial(ONE,u2,u); glstr = KIN_NONE; mset = 1; SolveIt(kmem, u, s, glstr, mset); /* --------------------------- */ N_VScale_Serial(ONE,u2,u); glstr = KIN_LINESEARCH; mset = 1; SolveIt(kmem, u, s, glstr, mset); /* --------------------------- */ N_VScale_Serial(ONE,u2,u); glstr = KIN_NONE; mset = 0; SolveIt(kmem, u, s, glstr, mset); /* --------------------------- */ N_VScale_Serial(ONE,u2,u); glstr = KIN_LINESEARCH; mset = 0; SolveIt(kmem, u, s, glstr, mset); /* Free memory */ N_VDestroy_Serial(u); N_VDestroy_Serial(s); N_VDestroy_Serial(c); KINFree(&kmem); free(data); 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; }