int KINBBDSpbcg(void *kinmem, int maxl, void *p_data) { KINMem kin_mem; int flag; flag = KINSpbcg(kinmem, maxl); if (flag != KINSPILS_SUCCESS) return(flag); kin_mem = (KINMem) kinmem; if (p_data == NULL) { KINProcessError(kin_mem, KINBBDPRE_PDATA_NULL, "KINBBDPRE", "KINBBDSpbcg", MSGBBD_PDATA_NULL); return(KINBBDPRE_PDATA_NULL); } flag = KINSpilsSetPreconditioner(kinmem, KINBBDPrecSetup, KINBBDPrecSolve, p_data); if (flag != KINSPILS_SUCCESS) return(flag); return(KINSPILS_SUCCESS); }
int main(void) { int globalstrategy, linsolver; 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: nvSpec is the nvSpec pointer used in the serial version 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); /* START: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */ for (linsolver = 0; linsolver < 3; ++linsolver) { /* Re-initialize user data */ if (linsolver != 0) SetInitialProfiles(cc, sc); /* Attach a linear solver module */ switch(linsolver) { /* (a) SPGMR */ case(USE_SPGMR): /* Print header */ printf(" -------"); printf(" \n| SPGMR |\n"); printf(" -------\n"); /* Call KINSpgmr to specify the linear solver KINSPGMR with preconditioner routines PrecSetupBD and PrecSolveBD, and the pointer to the user block data. */ 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); break; /* (b) SPBCG */ case(USE_SPBCG): /* Print header */ printf(" -------"); printf(" \n| SPBCG |\n"); printf(" -------\n"); /* Call KINSpbcg to specify the linear solver KINSPBCG with preconditioner routines PrecSetupBD and PrecSolveBD, and the pointer to the user block data. */ maxl = 15; flag = KINSpbcg(kmem, maxl); if (check_flag(&flag, "KINSpbcg", 1)) return(1); break; /* (c) SPTFQMR */ case(USE_SPTFQMR): /* Print header */ printf(" ---------"); printf(" \n| SPTFQMR |\n"); printf(" ---------\n"); /* Call KINSptfqmr to specify the linear solver KINSPTFQMR with preconditioner routines PrecSetupBD and PrecSolveBD, and the pointer to the user block data. */ maxl = 25; flag = KINSptfqmr(kmem, maxl); if (check_flag(&flag, "KINSptfqmr", 1)) return(1); break; } /* Set preconditioner functions */ 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, linsolver); /* 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, linsolver); } /* END: Loop through SPGMR, SPBCG and SPTFQMR linear solver modules */ N_VDestroy_Serial(cc); N_VDestroy_Serial(sc); KINFree(&kmem); FreeUserData(data); return(0); }
void FKIN_SPBCG(int *maxl, int *ier) { *ier = KINSpbcg(KIN_kinmem, *maxl); KIN_ls = KIN_LS_SPBCG; }
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; }