static int IDAnlsIC (IDAMem IDA_mem) { int retval, nj; N_Vector tv1, tv2, tv3; tv1 = ee; tv2 = tempv2; tv3 = phi[2]; retval = res(t0, yy0, yp0, delta, user_data); nre++; if(retval < 0) return(IDA_RES_FAIL); if(retval > 0) return(IDA_FIRST_RES_FAIL); N_VScale(ONE, delta, savres); /* Loop over nj = number of linear solve Jacobian setups. */ for(nj = 1; nj <= maxnj; nj++) { /* If there is a setup routine, call it. */ if(setupNonNull) { nsetups++; retval = lsetup(IDA_mem, yy0, yp0, delta, tv1, tv2, tv3); if(retval < 0) return(IDA_LSETUP_FAIL); if(retval > 0) return(IC_FAIL_RECOV); } /* Call the Newton iteration routine, and return if successful. */ retval = IDANewtonIC(IDA_mem); if(retval == IDA_SUCCESS) return(IDA_SUCCESS); /* If converging slowly and lsetup is nontrivial, retry. */ if(retval == IC_SLOW_CONVRG && setupNonNull) { N_VScale(ONE, savres, delta); continue; } else { return(retval); } } /* End of nj loop */ /* No convergence after maxnj tries; return with retval=IC_SLOW_CONVRG */ return(retval); }
/* * ----------------------------------------------------------------- * IDASensNlsIC * ----------------------------------------------------------------- * IDASensNlsIC solves nonlinear systems forsensitivities consistent * initial conditions. It mainly relies on IDASensNewtonIC. * * The return value is IDA_SUCCESS = 0 if no error occurred. * The error return values (positive) considered recoverable are: * IC_FAIL_RECOV if res, lsetup, or lsolve failed recoverably * IC_CONSTR_FAILED if the constraints could not be met * IC_LINESRCH_FAILED if the linesearch failed (on steptol test) * IC_CONV_FAIL if the Newton iterations failed to converge * IC_SLOW_CONVRG if the iterations are converging slowly * (failed the convergence test, but showed * norm reduction or convergence rate < 1) * The error return values (negative) considered non-recoverable are: * IDA_RES_FAIL if res had a non-recoverable error * IDA_FIRST_RES_FAIL if res failed recoverably on the first call * IDA_LSETUP_FAIL if lsetup had a non-recoverable error * IDA_LSOLVE_FAIL if lsolve had a non-recoverable error * ----------------------------------------------------------------- */ static int IDASensNlsIC(IDAMem IDA_mem) { int retval; int is, nj; retval = resS(Ns, t0, yy0, yp0, delta, yyS0, ypS0, deltaS, user_dataS, tmpS1, tmpS2, tmpS3); nrSe++; if(retval < 0) return(IDA_RES_FAIL); if(retval > 0) return(IDA_FIRST_RES_FAIL); /* Save deltaS */ for(is=0; is<Ns; is++) N_VScale(ONE, deltaS[is], savresS[is]); /* Loop over nj = number of linear solve Jacobian setups. */ for(nj = 1; nj <= 2; nj++) { /* Call the Newton iteration routine */ retval = IDASensNewtonIC(IDA_mem); if(retval == IDA_SUCCESS) return(IDA_SUCCESS); /* If converging slowly and lsetup is nontrivial and this is the first pass, update Jacobian and retry. */ if(retval == IC_SLOW_CONVRG && setupNonNull && nj==1) { /* Restore deltaS. */ for(is=0; is<Ns; is++) N_VScale(ONE, savresS[is], deltaS[is]); nsetupsS++; retval = lsetup(IDA_mem, yy0, yp0, delta, tmpS1, tmpS2, tmpS3); if(retval < 0) return(IDA_LSETUP_FAIL); if(retval > 0) return(IC_FAIL_RECOV); continue; } else { return(retval); } } return(IDA_SUCCESS); }
static int KINLinSolDrv(KINMem kin_mem, N_Vector bb, N_Vector xx) { int ret; if (nni - nnilpre >= msbpre) pthrsh = TWO; loop { precondcurrent = FALSE; if ((pthrsh > ONEPT5) && setupNonNull) { /* Call precondset routine */ ret = lsetup(kin_mem); precondcurrent = TRUE; nnilpre = nni; if (ret != 0) return(KINSOL_PRECONDSET_FAILURE); } /* load bb with the current value of fval */ N_VScale(-ONE, fval, bb); /* call the generic 'lsolve' routine to solve the system J x = b */ ret = lsolve(kin_mem, xx, bb, &res_norm); if (ret != 1) return(ret); if (!precondflag) return(KINSOL_KRYLOV_FAILURE); if (precondcurrent) return(KINSOL_KRYLOV_FAILURE); /* loop back only if the preconditioner is in use and is not current */ pthrsh = TWO; } /* end of loop */ }
/*ARGSUSED*/ static int lo_mount(struct vfs *vfsp, struct vnode *vp, struct mounta *uap, struct cred *cr) { int error; struct vnode *srootvp = NULL; /* the server's root */ struct vnode *realrootvp; struct loinfo *li; int nodev; nodev = vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL); if ((error = secpolicy_fs_mount(cr, vp, vfsp)) != 0) return (EPERM); /* * Loopback devices which get "nodevices" added can be done without * "nodevices" set because we cannot import devices into a zone * with loopback. Note that we have all zone privileges when * this happens; if not, we'd have gotten "nosuid". */ if (!nodev && vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL)) vfs_setmntopt(vfsp, MNTOPT_DEVICES, NULL, VFS_NODISPLAY); mutex_enter(&vp->v_lock); if (!(uap->flags & MS_OVERLAY) && (vp->v_count != 1 || (vp->v_flag & VROOT))) { mutex_exit(&vp->v_lock); return (EBUSY); } mutex_exit(&vp->v_lock); /* * Find real root, and make vfs point to real vfs */ if (error = lookupname(uap->spec, (uap->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE, FOLLOW, NULLVPP, &realrootvp)) return (error); /* * Enforce MAC policy if needed. * * Loopback mounts must not allow writing up. The dominance test * is intended to prevent a global zone caller from accidentally * creating write-up conditions between two labeled zones. * Local zones can't violate MAC on their own without help from * the global zone because they can't name a pathname that * they don't already have. * * The special case check for the NET_MAC_AWARE process flag is * to support the case of the automounter in the global zone. We * permit automounting of local zone directories such as home * directories, into the global zone as required by setlabel, * zonecopy, and saving of desktop sessions. Such mounts are * trusted not to expose the contents of one zone's directories * to another by leaking them through the global zone. */ if (is_system_labeled() && crgetzoneid(cr) == GLOBAL_ZONEID) { char specname[MAXPATHLEN]; zone_t *from_zptr; zone_t *to_zptr; if (vnodetopath(NULL, realrootvp, specname, sizeof (specname), CRED()) != 0) { VN_RELE(realrootvp); return (EACCES); } from_zptr = zone_find_by_path(specname); to_zptr = zone_find_by_path(refstr_value(vfsp->vfs_mntpt)); /* * Special case for zone devfs: the zone for /dev will * incorrectly appear as the global zone since it's not * under the zone rootpath. So for zone devfs check allow * read-write mounts. * * Second special case for scratch zones used for Live Upgrade: * this is used to mount the zone's root from /root to /a in * the scratch zone. As with the other special case, this * appears to be outside of the zone because it's not under * the zone rootpath, which is $ZONEPATH/lu in the scratch * zone case. */ if (from_zptr != to_zptr && !(to_zptr->zone_flags & ZF_IS_SCRATCH)) { /* * We know at this point that the labels aren't equal * because the zone pointers aren't equal, and zones * can't share a label. * * If the source is the global zone then making * it available to a local zone must be done in * read-only mode as the label will become admin_low. * * If it is a mount between local zones then if * the current process is in the global zone and has * the NET_MAC_AWARE flag, then regular read-write * access is allowed. If it's in some other zone, but * the label on the mount point dominates the original * source, then allow the mount as read-only * ("read-down"). */ if (from_zptr->zone_id == GLOBAL_ZONEID) { /* make the mount read-only */ vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0); } else { /* cross-zone mount */ if (to_zptr->zone_id == GLOBAL_ZONEID && /* LINTED: no consequent */ getpflags(NET_MAC_AWARE, cr) != 0) { /* Allow the mount as read-write */ } else if (bldominates( label2bslabel(to_zptr->zone_slabel), label2bslabel(from_zptr->zone_slabel))) { /* make the mount read-only */ vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0); } else { VN_RELE(realrootvp); zone_rele(to_zptr); zone_rele(from_zptr); return (EACCES); } } } zone_rele(to_zptr); zone_rele(from_zptr); } /* * realrootvp may be an AUTOFS node, in which case we * perform a VOP_ACCESS() to trigger the mount of the * intended filesystem, so we loopback mount the intended * filesystem instead of the AUTOFS filesystem. */ (void) VOP_ACCESS(realrootvp, 0, 0, cr, NULL); /* * We're interested in the top most filesystem. * This is specially important when uap->spec is a trigger * AUTOFS node, since we're really interested in mounting the * filesystem AUTOFS mounted as result of the VOP_ACCESS() * call not the AUTOFS node itself. */ if (vn_mountedvfs(realrootvp) != NULL) { if (error = traverse(&realrootvp)) { VN_RELE(realrootvp); return (error); } } /* * Allocate a vfs info struct and attach it */ li = kmem_zalloc(sizeof (struct loinfo), KM_SLEEP); li->li_realvfs = realrootvp->v_vfsp; li->li_mountvfs = vfsp; /* * Set mount flags to be inherited by loopback vfs's */ if (vfs_optionisset(vfsp, MNTOPT_RO, NULL)) { li->li_mflag |= VFS_RDONLY; } if (vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL)) { li->li_mflag |= (VFS_NOSETUID|VFS_NODEVICES); } if (vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL)) { li->li_mflag |= VFS_NODEVICES; } if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL)) { li->li_mflag |= VFS_NOSETUID; } /* * Permissive flags are added to the "deny" bitmap. */ if (vfs_optionisset(vfsp, MNTOPT_NOXATTR, NULL)) { li->li_dflag |= VFS_XATTR; } if (vfs_optionisset(vfsp, MNTOPT_NONBMAND, NULL)) { li->li_dflag |= VFS_NBMAND; } /* * Propagate inheritable mount flags from the real vfs. */ if ((li->li_realvfs->vfs_flag & VFS_RDONLY) && !vfs_optionisset(vfsp, MNTOPT_RO, NULL)) vfs_setmntopt(vfsp, MNTOPT_RO, NULL, VFS_NODISPLAY); if ((li->li_realvfs->vfs_flag & VFS_NOSETUID) && !vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL)) vfs_setmntopt(vfsp, MNTOPT_NOSETUID, NULL, VFS_NODISPLAY); if ((li->li_realvfs->vfs_flag & VFS_NODEVICES) && !vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL)) vfs_setmntopt(vfsp, MNTOPT_NODEVICES, NULL, VFS_NODISPLAY); /* * Permissive flags such as VFS_XATTR, as opposed to restrictive flags * such as VFS_RDONLY, are handled differently. An explicit * MNTOPT_NOXATTR should override the underlying filesystem's VFS_XATTR. */ if ((li->li_realvfs->vfs_flag & VFS_XATTR) && !vfs_optionisset(vfsp, MNTOPT_NOXATTR, NULL) && !vfs_optionisset(vfsp, MNTOPT_XATTR, NULL)) vfs_setmntopt(vfsp, MNTOPT_XATTR, NULL, VFS_NODISPLAY); if ((li->li_realvfs->vfs_flag & VFS_NBMAND) && !vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL) && !vfs_optionisset(vfsp, MNTOPT_NONBMAND, NULL)) vfs_setmntopt(vfsp, MNTOPT_NBMAND, NULL, VFS_NODISPLAY); li->li_refct = 0; vfsp->vfs_data = (caddr_t)li; vfsp->vfs_bcount = 0; vfsp->vfs_fstype = lofsfstype; vfsp->vfs_bsize = li->li_realvfs->vfs_bsize; vfsp->vfs_dev = li->li_realvfs->vfs_dev; vfsp->vfs_fsid.val[0] = li->li_realvfs->vfs_fsid.val[0]; vfsp->vfs_fsid.val[1] = li->li_realvfs->vfs_fsid.val[1]; if (vfs_optionisset(vfsp, MNTOPT_LOFS_NOSUB, NULL)) { li->li_flag |= LO_NOSUB; } /* * Propagate any VFS features */ vfs_propagate_features(li->li_realvfs, vfsp); /* * Setup the hashtable. If the root of this mount isn't a directory, * there's no point in allocating a large hashtable. A table with one * bucket is sufficient. */ if (realrootvp->v_type != VDIR) lsetup(li, 1); else lsetup(li, 0); /* * Make the root vnode */ srootvp = makelonode(realrootvp, li, 0); srootvp->v_flag |= VROOT; li->li_rootvp = srootvp; #ifdef LODEBUG lo_dprint(4, "lo_mount: vfs %p realvfs %p root %p realroot %p li %p\n", vfsp, li->li_realvfs, srootvp, realrootvp, li); #endif return (0); }
static int cpNlsNewtonImpl(CPodeMem cp_mem, int nflag) { N_Vector vtemp1, vtemp2, vtemp3; int convfail, retval; booleantype callSetup; #ifdef CPODES_DEBUG printf(" Newton, implicit ODE\n"); #endif /* In this situation we do not pass convfail information to the linear sovler setup function */ convfail = 0; /* Vectors used as temporary space in lsetup */ vtemp1 = acor; vtemp2 = y; vtemp3 = tempv; /* If the linear solver provides a setup function, call it if: * - we are at the first step (nst == 0), or * - gamma changed significantly, or * - enough steps passed from last evaluation */ if (lsetup_exists) { callSetup = (nst == 0) || (ABS(gamrat-ONE) > DGMAX) || (nst >= nstlset + NLS_MSBLS); } else { callSetup = FALSE; crate = ONE; } /* Begin the main loop. This loop is traversed at most twice. * The second pass only occurs when the first pass had a recoverable * failure with old Jacobian data. */ loop { /* Evaluate predicted y' from Nordsieck array */ N_VScale(ONE/h, zn[1], yp); /* Evaluate residual at predicted y and y' */ retval = fi(tn, zn[0], yp, ftemp, f_data); nfe++; if (retval < 0) return(CP_ODEFUNC_FAIL); if (retval > 0) return(ODEFUNC_RECVR); /* If needed, call setup function */ if (callSetup) { retval = lsetup(cp_mem, 0, zn[0], yp, ftemp, &jcur, vtemp1, vtemp2, vtemp3); nsetups++; nstlset = nst; crate = ONE; gammap = gamma; gamrat = ONE; if (retval < 0) return(CP_LSETUP_FAIL); if (retval > 0) return(CONV_FAIL); } /* Set acor to zero and load prediction into y vector */ N_VConst(ZERO, acor); N_VScale(ONE, zn[0], y); /* Do the Newton iteration */ retval = cpNewtonIterationImpl(cp_mem); /* On a recoverable failure, if setup was not called, reattempt loop */ if ( (retval > 0) && lsetup_exists && !callSetup ) { callSetup = TRUE; continue; } /* Return (success or unrecoverable failure) */ return(retval); } }
static int cpNlsNewtonExpl(CPodeMem cp_mem, int nflag) { N_Vector vtemp1, vtemp2, vtemp3; int convfail, retval, ier; booleantype callSetup; #ifdef CPODES_DEBUG printf(" Newton, explicit ODE\n"); #endif vtemp1 = acor; /* rename acor as vtemp1 for readability */ vtemp2 = y; /* rename y as vtemp2 for readability */ vtemp3 = tempv; /* rename tempv as vtemp3 for readability */ /* Set flag convfail, input to lsetup for its evaluation decision */ convfail = ((nflag == FIRST_CALL) || (nflag == PREV_ERR_FAIL)) ? CP_NO_FAILURES : CP_FAIL_OTHER; /* Decide whether or not to call setup routine (if one exists) */ if (lsetup_exists) { callSetup = (nflag == PREV_CONV_FAIL) || (nflag == PREV_ERR_FAIL) || (nst == 0) || (nst >= nstlset + NLS_MSBLS) || (ABS(gamrat-ONE) > DGMAX); } else { crate = ONE; callSetup = FALSE; } /* Begin the main loop. This loop is traversed at most twice. * The second pass only occurs when the first pass had a recoverable * failure with old Jacobian data. */ loop { /* Evaluate function at predicted y */ retval = fe(tn, zn[0], ftemp, f_data); nfe++; if (retval < 0) return(CP_ODEFUNC_FAIL); if (retval > 0) return(ODEFUNC_RECVR); /* If needed, call setup function (ypP = NULL in this case) */ if (callSetup) { ier = lsetup(cp_mem, convfail, zn[0], NULL, ftemp, &jcur, vtemp1, vtemp2, vtemp3); #ifdef CPODES_DEBUG printf(" Linear solver setup return value = %d\n",ier); #endif nsetups++; callSetup = FALSE; gamrat = crate = ONE; gammap = gamma; nstlset = nst; if (ier < 0) return(CP_LSETUP_FAIL); if (ier > 0) return(CONV_FAIL); } /* Set acor to zero and load prediction into y vector */ N_VConst(ZERO, acor); N_VScale(ONE, zn[0], y); /* Do the Newton iteration */ #ifdef CPODES_DEBUG printf(" NonlinearIteration\n"); #endif ier = cpNewtonIterationExpl(cp_mem); #ifdef CPODES_DEBUG printf(" NonlinearIteration return value = %d\n",ier); #endif /* If there is a convergence failure and the Jacobian-related data appears not to be current, loop again with a call to lsetup in which convfail=CP_FAIL_BAD_J. Otherwise return. */ if ( (ier > 0) && (lsetup_exists) && (!jcur) ) { callSetup = TRUE; convfail = CP_FAIL_BAD_J; continue; } return(ier); } }
static int IDANlsIC(IDAMem IDA_mem) { int retval, nj, is; N_Vector tv1, tv2, tv3; booleantype sensi_sim; /* Are we computing sensitivities with the IDA_SIMULTANEOUS approach? */ sensi_sim = (sensi && (ism==IDA_SIMULTANEOUS)); tv1 = ee; tv2 = tempv2; tv3 = phi[2]; /* Evaluate RHS. */ retval = res(t0, yy0, yp0, delta, user_data); nre++; if(retval < 0) return(IDA_RES_FAIL); if(retval > 0) return(IDA_FIRST_RES_FAIL); /* Save the residual. */ N_VScale(ONE, delta, savres); if(sensi_sim) { /*Evaluate sensitivity RHS and save it in savresS. */ retval = resS(Ns, t0, yy0, yp0, delta, yyS0, ypS0, deltaS, user_dataS, tmpS1, tmpS2, tmpS3); nrSe++; if(retval < 0) return(IDA_RES_FAIL); if(retval > 0) return(IDA_FIRST_RES_FAIL); for(is=0; is<Ns; is++) N_VScale(ONE, deltaS[is], savresS[is]); } /* Loop over nj = number of linear solve Jacobian setups. */ for(nj = 1; nj <= maxnj; nj++) { /* If there is a setup routine, call it. */ if(setupNonNull) { nsetups++; retval = lsetup(IDA_mem, yy0, yp0, delta, tv1, tv2, tv3); if(retval < 0) return(IDA_LSETUP_FAIL); if(retval > 0) return(IC_FAIL_RECOV); } /* Call the Newton iteration routine, and return if successful. */ retval = IDANewtonIC(IDA_mem); if(retval == IDA_SUCCESS) return(IDA_SUCCESS); /* If converging slowly and lsetup is nontrivial, retry. */ if(retval == IC_SLOW_CONVRG && setupNonNull) { N_VScale(ONE, savres, delta); if(sensi_sim) for(is=0; is<Ns; is++) N_VScale(ONE, savresS[is], deltaS[is]); continue; } else { return(retval); } } /* End of nj loop */ /* No convergence after maxnj tries; return with retval=IC_SLOW_CONVRG */ return(retval); }