file-type

KSP8000手机获取Root权限刷机教程

RAR文件

下载需积分: 9 | 4.66MB | 更新于2025-09-06 | 65 浏览量 | 11 下载量 举报 1 收藏
download 立即下载
KSP8000手机Root操作及相关知识详解 一、Root操作的基本概念 Root是指获取Android系统最高权限(超级用户权限)的操作,通过该操作用户可以获得对设备系统的完全控制权。这种权限突破了设备制造商和运营商对系统的限制,使用户能够深度定制手机功能、卸载预装应用、提升系统性能等。Root操作源于Unix/Linux系统中的管理员账户概念,在Android系统中,普通用户权限无法对系统核心文件进行修改,而Root操作正是为了打破这一限制。 二、KSP8000手机特性分析 KSP8000作为特定型号的移动设备,其硬件架构和系统配置决定了Root操作的特殊性。该设备采用ARM架构处理器,搭载基于Android 11的定制化操作系统,其安全机制包含Bootloader锁、Verified Boot(验证启动)等防护措施。设备内置的TrustZone安全环境和Keystore系统为Root操作带来额外挑战,需要特殊的技术手段来绕过这些安全机制。 三、Root刷机包组成结构 从压缩包内文件结构分析,root文件包含以下关键组件: 1. Magisk模块:包含核心的系统修补工具,提供系统less的Root实现方案 2. Boot.img修改工具:用于解包、修改并重新打包启动镜像文件 3. TWRP Recovery镜像:提供第三方恢复环境,支持刷机包的安装和系统备份 4. 驱动程序包:包含USB调试模式所需的设备驱动程序 5. 操作脚本:自动化处理分区挂载、权限配置等复杂操作的Shell脚本 四、Root操作技术原理 Root实现的核心在于对系统验证机制的绕过。具体流程包括: 1. Bootloader解锁:通过fastboot命令序列解除启动加载程序的锁定状态 2. Recovery替换:将官方Recovery替换为TWRP等自定义恢复环境 3. 内核修改:在boot.img中植入root权限管理模块,通常涉及: - 修改init.rc启动脚本 - 添加su二进制文件到系统路径 - 配置Superuser权限数据库 4. 系统验证绕过:使用Magisk的Stitch Image功能修改AVB(Android Verification Boot)校验值 五、Root刷机包工作机制 本刷机包采用Magisk框架实现Root权限管理,其技术特点包括: 1. 系统less设计:不修改/system分区内容,通过修改ramdisk实现权限提升 2. 模块化架构:支持第三方模块扩展,可通过Magisk Manager安装附加功能 3. 验证签名绕过:使用Magisk的zygisk模块注入技术绕过SafetyNet检测 4. SELinux策略修改:调整安全策略配置文件,允许特权进程运行 六、Root操作风险与注意事项 1. 硬件风险:不当操作可能导致设备变砖,需注意: - 正确识别设备型号和硬件版本 - 确认电池电量在70%以上 - 避免断电或强制关机 2. 软件风险: - 系统更新可能导致Root失效 - 某些安全应用可能检测到Root状态 - 可能影响设备稳定性或导致功能异常 3. 安全风险: - Root权限滥用可能导致系统文件损坏 - 恶意软件可能获得更高系统权限 - 隐私数据泄露风险增加 4. 保修风险:Root操作通常会导致厂商保修失效 七、Root后的系统优化方向 1. 系统精简: - 卸载预装的厂商定制应用 - 移除无用的系统组件 - 禁用后台进程服务 2. 性能优化: - 调整CPU频率调节器设置 - 修改I/O调度算法 - 优化内存管理参数 3. 功能增强: - 安装Xposed框架实现模块化功能扩展 - 部署AdAway等广告屏蔽应用 - 实现多账户管理功能 4. 安全防护: - 配置防火墙规则限制应用联网 - 启用应用权限监控 - 安装Root权限审计工具 八、Root权限管理实践 1. 权限授予策略: - 采用最小权限原则 - 定期审查授权应用列表 - 区分临时授权和永久授权 2. Root管理工具选择: - Magisk Manager:提供模块管理、权限控制等功能 - SuperSU:经典Root管理方案,支持详细权限配置 - KSU(KernelSU):新型内核级Root方案 3. 安全检测绕过: - 使用Magisk的Hide功能隐藏Root状态 - 配置SELinux策略规避检测 - 修改系统属性值欺骗检测程序 九、刷机操作流程详解 1. 准备阶段: - 启用开发者选项和USB调试模式 - 安装ADB和fastboot工具 - 备份重要数据 2. 解锁Bootloader: - 进入Fastboot模式 - 执行oem unlock命令 - 注意可能清除设备数据 3. 刷入Recovery: - 使用fastboot flash命令写入TWRP镜像 - 验证Recovery启动 4. Root刷机包安装: - 将刷机包复制到设备存储 - 在Recovery中选择"Install"进行刷写 - 完成后清除Dalvik缓存 5. 系统配置: - 安装Root管理应用 - 更新Superuser二进制文件 - 配置初始权限设置 十、Root技术发展趋势 1. 安全机制演变: - Android 13引入的AP的深度整合 - AVB 4.0带来的新挑战 - Trusty TEE环境对Root的影响 2. 新型Root方案: - 内核模块注入技术 - 用户空间Root实现 - 利用系统漏洞的零日Root方法 3. 厂商反制措施: - 强制Verified Boot 2.0 - 引入Root检测硬件机制 - 安全启动链的强化 本刷机包适用于需要深度定制KSP8000手机系统的高级用户,建议在充分了解相关风险和技术原理的前提下进行操作。Root操作虽然能带来更高的系统控制权,但也需要用户具备相应的技术能力和风险意识。随着Android系统安全机制的不断完善,Root技术也在持续发展,需要关注最新的技术动态和安全解决方案。

相关推荐

filetype

/* This file implements FGMRES (a Generalized Minimal Residual) method. Reference: Saad, 1993. Preconditioning: If the preconditioner is constant then this fgmres code is equivalent to RIGHT-PRECONDITIONED GMRES. FGMRES is a modification of gmres that allows the preconditioner to change at each iteration. Restarts: Restarts are basically solves with x0 not equal to zero. */ #include <../src/ksp/ksp/impls/gmres/fgmres/fgmresimpl.h> /*I "petscksp.h" I*/ #define FGMRES_DELTA_DIRECTIONS 10 #define FGMRES_DEFAULT_MAXK 30 static PetscErrorCode KSPFGMRESGetNewVectors(KSP, PetscInt); static PetscErrorCode KSPFGMRESUpdateHessenberg(KSP, PetscInt, PetscBool, PetscReal *); static PetscErrorCode KSPFGMRESBuildSoln(PetscScalar *, Vec, Vec, KSP, PetscInt); static PetscErrorCode KSPSetUp_FGMRES(KSP ksp) { PetscInt max_k, k; KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscFunctionBegin; max_k = fgmres->max_k; PetscCall(KSPSetUp_GMRES(ksp)); PetscCall(PetscMalloc1(max_k + 2, &fgmres->prevecs)); PetscCall(PetscMalloc1(max_k + 2, &fgmres->prevecs_user_work)); /* fgmres->vv_allocated includes extra work vectors, which are not used in the additional block of vectors used to store the preconditioned directions, hence the -VEC_OFFSET term for this first allocation of vectors holding preconditioned directions */ PetscCall(KSPCreateVecs(ksp, fgmres->vv_allocated - VEC_OFFSET, &fgmres->prevecs_user_work[0], 0, NULL)); for (k = 0; k < fgmres->vv_allocated - VEC_OFFSET; k++) fgmres->prevecs[k] = fgmres->prevecs_user_work[0][k]; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPFGMRESResidual(KSP ksp) { KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; Mat Amat, Pmat; PetscFunctionBegin; PetscCall(PCGetOperators(ksp->pc, &Amat, &Pmat)); /* put A*x into VEC_TEMP */ PetscCall(KSP_MatMult(ksp, Amat, ksp->vec_sol, VEC_TEMP)); /* now put residual (-A*x + f) into vec_vv(0) */ PetscCall(VecWAXPY(VEC_VV(0), -1.0, VEC_TEMP, ksp->vec_rhs)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPFGMRESCycle(PetscInt *itcount, KSP ksp) { KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscReal res_norm; PetscReal hapbnd, tt; PetscBool hapend = PETSC_FALSE; /* indicates happy breakdown ending */ PetscInt loc_it; /* local count of # of dir. in Krylov space */ PetscInt max_k = fgmres->max_k; /* max # of directions Krylov space */ Mat Amat, Pmat; PetscFunctionBegin; /* Number of pseudo iterations since last restart is the number of prestart directions */ loc_it = 0; /* note: (fgmres->it) is always set one less than (loc_it) It is used in KSPBUILDSolution_FGMRES, where it is passed to KSPFGMRESBuildSoln. Note that when KSPFGMRESBuildSoln is called from this function, (loc_it -1) is passed, so the two are equivalent */ fgmres->it = (loc_it - 1); /* initial residual is in VEC_VV(0) - compute its norm*/ PetscCall(VecNorm(VEC_VV(0), NORM_2, &res_norm)); KSPCheckNorm(ksp, res_norm); /* The first entry in the right-hand side of the Hessenberg system is just the initial residual norm */ *RS(0) = res_norm; ksp->rnorm = res_norm; PetscCall(KSPLogResidualHistory(ksp, res_norm)); PetscCall(KSPMonitor(ksp, ksp->its, res_norm)); /* check for the convergence - maybe the current guess is good enough */ PetscCall((*ksp->converged)(ksp, ksp->its, res_norm, &ksp->reason, ksp->cnvP)); if (ksp->reason) { if (itcount) *itcount = 0; PetscFunctionReturn(PETSC_SUCCESS); } /* scale VEC_VV (the initial residual) */ PetscCall(VecScale(VEC_VV(0), 1.0 / res_norm)); /* MAIN ITERATION LOOP BEGINNING*/ /* keep iterating until we have converged OR generated the max number of directions OR reached the max number of iterations for the method */ while (!ksp->reason && loc_it < max_k && ksp->its < ksp->max_it) { if (loc_it) { PetscCall(KSPLogResidualHistory(ksp, res_norm)); PetscCall(KSPMonitor(ksp, ksp->its, res_norm)); } fgmres->it = (loc_it - 1); /* see if more space is needed for work vectors */ if (fgmres->vv_allocated <= loc_it + VEC_OFFSET + 1) { PetscCall(KSPFGMRESGetNewVectors(ksp, loc_it + 1)); /* (loc_it+1) is passed in as number of the first vector that should be allocated */ } /* CHANGE THE PRECONDITIONER? */ /* ModifyPC is the callback function that can be used to change the PC or its attributes before its applied */ PetscCall((*fgmres->modifypc)(ksp, ksp->its, loc_it, res_norm, fgmres->modifyctx)); /* apply PRECONDITIONER to direction vector and store with preconditioned vectors in prevec */ PetscCall(KSP_PCApply(ksp, VEC_VV(loc_it), PREVEC(loc_it))); PetscCall(PCGetOperators(ksp->pc, &Amat, &Pmat)); /* Multiply preconditioned vector by operator - put in VEC_VV(loc_it+1) */ PetscCall(KSP_MatMult(ksp, Amat, PREVEC(loc_it), VEC_VV(1 + loc_it))); /* update Hessenberg matrix and do Gram-Schmidt - new direction is in VEC_VV(1+loc_it)*/ PetscCall((*fgmres->orthog)(ksp, loc_it)); /* new entry in hessenburg is the 2-norm of our new direction */ PetscCall(VecNorm(VEC_VV(loc_it + 1), NORM_2, &tt)); KSPCheckNorm(ksp, tt); *HH(loc_it + 1, loc_it) = tt; *HES(loc_it + 1, loc_it) = tt; /* Happy Breakdown Check */ hapbnd = PetscAbsScalar((tt) / *RS(loc_it)); /* RS(loc_it) contains the res_norm from the last iteration */ hapbnd = PetscMin(fgmres->haptol, hapbnd); if (tt > hapbnd) { /* scale new direction by its norm */ PetscCall(VecScale(VEC_VV(loc_it + 1), 1.0 / tt)); } else { /* This happens when the solution is exactly reached. */ /* So there is no new direction... */ PetscCall(VecSet(VEC_TEMP, 0.0)); /* set VEC_TEMP to 0 */ hapend = PETSC_TRUE; } /* note that for FGMRES we could get HES(loc_it+1, loc_it) = 0 and the current solution would not be exact if HES was singular. Note that HH non-singular implies that HES is no singular, and HES is guaranteed to be nonsingular when PREVECS are linearly independent and A is nonsingular (in GMRES, the nonsingularity of A implies the nonsingularity of HES). So we should really add a check to verify that HES is nonsingular.*/ /* Now apply rotations to the new column of Hessenberg (and the right-hand side of the system), calculate new rotation, and get new residual norm at the same time*/ PetscCall(KSPFGMRESUpdateHessenberg(ksp, loc_it, hapend, &res_norm)); if (ksp->reason) break; loc_it++; fgmres->it = (loc_it - 1); /* Add this here in case it has converged */ PetscCall(PetscObjectSAWsTakeAccess((PetscObject)ksp)); ksp->its++; ksp->rnorm = res_norm; PetscCall(PetscObjectSAWsGrantAccess((PetscObject)ksp)); PetscCall((*ksp->converged)(ksp, ksp->its, res_norm, &ksp->reason, ksp->cnvP)); /* Catch error in happy breakdown and signal convergence and break from loop */ if (hapend) { if (!ksp->reason) { PetscCheck(!ksp->errorifnotconverged, PetscObjectComm((PetscObject)ksp), PETSC_ERR_NOT_CONVERGED, "Reached happy break down, but convergence was not indicated. Residual norm = %g", (double)res_norm); ksp->reason = KSP_DIVERGED_BREAKDOWN; break; } } } /* END OF ITERATION LOOP */ if (itcount) *itcount = loc_it; /* Down here we have to solve for the "best" coefficients of the Krylov columns, add the solution values together, and possibly unwind the preconditioning from the solution */ /* Form the solution (or the solution so far) */ /* Note: must pass in (loc_it-1) for iteration count so that KSPFGMRESBuildSoln properly navigates */ PetscCall(KSPFGMRESBuildSoln(RS(0), ksp->vec_sol, ksp->vec_sol, ksp, loc_it - 1)); /* Monitor if we know that we will not return for a restart */ if (ksp->reason == KSP_CONVERGED_ITERATING && ksp->its >= ksp->max_it) ksp->reason = KSP_DIVERGED_ITS; if (loc_it && ksp->reason) { PetscCall(KSPMonitor(ksp, ksp->its, res_norm)); PetscCall(KSPLogResidualHistory(ksp, res_norm)); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPSolve_FGMRES(KSP ksp) { PetscInt cycle_its = 0; /* iterations done in a call to KSPFGMRESCycle */ KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscBool diagonalscale; PetscFunctionBegin; PetscCall(PCGetDiagonalScale(ksp->pc, &diagonalscale)); PetscCheck(!diagonalscale, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Krylov method %s does not support diagonal scaling", ((PetscObject)ksp)->type_name); PetscCall(PetscObjectSAWsTakeAccess((PetscObject)ksp)); ksp->its = 0; PetscCall(PetscObjectSAWsGrantAccess((PetscObject)ksp)); /* Compute the initial (NOT preconditioned) residual */ if (!ksp->guess_zero) { PetscCall(KSPFGMRESResidual(ksp)); } else { /* guess is 0 so residual is F (which is in ksp->vec_rhs) */ PetscCall(VecCopy(ksp->vec_rhs, VEC_VV(0))); } /* This may be true only on a subset of MPI ranks; setting it here so it will be detected by the first norm computation in the Krylov method */ PetscCall(VecFlag(VEC_VV(0), ksp->reason == KSP_DIVERGED_PC_FAILED)); /* now the residual is in VEC_VV(0) - which is what KSPFGMRESCycle expects... */ PetscCall(KSPFGMRESCycle(&cycle_its, ksp)); while (!ksp->reason) { PetscCall(KSPFGMRESResidual(ksp)); if (ksp->its >= ksp->max_it) break; PetscCall(KSPFGMRESCycle(&cycle_its, ksp)); } /* mark lack of convergence */ if (ksp->its >= ksp->max_it && !ksp->reason) ksp->reason = KSP_DIVERGED_ITS; PetscFunctionReturn(PETSC_SUCCESS); } extern PetscErrorCode KSPReset_FGMRES(KSP); static PetscErrorCode KSPDestroy_FGMRES(KSP ksp) { PetscFunctionBegin; PetscCall(KSPReset_FGMRES(ksp)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPFGMRESSetModifyPC_C", NULL)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPFlexibleSetModifyPC_C", NULL)); PetscCall(KSPDestroy_GMRES(ksp)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPFGMRESBuildSoln(PetscScalar *nrs, Vec vguess, Vec vdest, KSP ksp, PetscInt it) { PetscScalar tt; PetscInt ii, k, j; KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscFunctionBegin; /* Solve for solution vector that minimizes the residual */ /* If it is < 0, no fgmres steps have been performed */ if (it < 0) { PetscCall(VecCopy(vguess, vdest)); /* VecCopy() is smart, exists immediately if vguess == vdest */ PetscFunctionReturn(PETSC_SUCCESS); } /* so fgmres steps HAVE been performed */ /* solve the upper triangular system - RS is the right side and HH is the upper triangular matrix - put soln in nrs */ if (*HH(it, it) != 0.0) { nrs[it] = *RS(it) / *HH(it, it); } else { nrs[it] = 0.0; } for (ii = 1; ii <= it; ii++) { k = it - ii; tt = *RS(k); for (j = k + 1; j <= it; j++) tt = tt - *HH(k, j) * nrs[j]; nrs[k] = tt / *HH(k, k); } /* Accumulate the correction to the soln of the preconditioned prob. in VEC_TEMP - note that we use the preconditioned vectors */ PetscCall(VecMAXPBY(VEC_TEMP, it + 1, nrs, 0, &PREVEC(0))); /* put updated solution into vdest.*/ if (vdest != vguess) { PetscCall(VecCopy(VEC_TEMP, vdest)); PetscCall(VecAXPY(vdest, 1.0, vguess)); } else { /* replace guess with solution */ PetscCall(VecAXPY(vdest, 1.0, VEC_TEMP)); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPFGMRESUpdateHessenberg(KSP ksp, PetscInt it, PetscBool hapend, PetscReal *res) { PetscScalar *hh, *cc, *ss, tt; PetscInt j; KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscFunctionBegin; hh = HH(0, it); /* pointer to beginning of column to update - so incrementing hh "steps down" the (it+1)th col of HH*/ cc = CC(0); /* beginning of cosine rotations */ ss = SS(0); /* beginning of sine rotations */ /* Apply all the previously computed plane rotations to the new column of the Hessenberg matrix */ /* Note: this uses the rotation [conj(c) s ; -s c], c= cos(theta), s= sin(theta), and some refs have [c s ; -conj(s) c] (don't be confused!) */ for (j = 1; j <= it; j++) { tt = *hh; *hh = PetscConj(*cc) * tt + *ss * *(hh + 1); hh++; *hh = *cc++ * *hh - (*ss++ * tt); /* hh, cc, and ss have all been incremented one by end of loop */ } /* compute the new plane rotation, and apply it to: 1) the right-hand side of the Hessenberg system (RS) note: it affects RS(it) and RS(it+1) 2) the new column of the Hessenberg matrix note: it affects HH(it,it) which is currently pointed to by hh and HH(it+1, it) (*(hh+1)) thus obtaining the updated value of the residual... */ /* compute new plane rotation */ if (!hapend) { tt = PetscSqrtScalar(PetscConj(*hh) * *hh + PetscConj(*(hh + 1)) * *(hh + 1)); if (tt == 0.0) { ksp->reason = KSP_DIVERGED_NULL; PetscFunctionReturn(PETSC_SUCCESS); } *cc = *hh / tt; /* new cosine value */ *ss = *(hh + 1) / tt; /* new sine value */ /* apply to 1) and 2) */ *RS(it + 1) = -(*ss * *RS(it)); *RS(it) = PetscConj(*cc) * *RS(it); *hh = PetscConj(*cc) * *hh + *ss * *(hh + 1); /* residual is the last element (it+1) of right-hand side! */ *res = PetscAbsScalar(*RS(it + 1)); } else { /* happy breakdown: HH(it+1, it) = 0, therefore we don't need to apply another rotation matrix (so RH doesn't change). The new residual is always the new sine term times the residual from last time (RS(it)), but now the new sine rotation would be zero...so the residual should be zero...so we will multiply "zero" by the last residual. This might not be exactly what we want to do here -could just return "zero". */ *res = 0.0; } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPFGMRESGetNewVectors(KSP ksp, PetscInt it) { KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscInt nwork = fgmres->nwork_alloc; /* number of work vector chunks allocated */ PetscInt nalloc; /* number to allocate */ PetscInt k; PetscFunctionBegin; nalloc = fgmres->delta_allocate; /* number of vectors to allocate in a single chunk */ /* Adjust the number to allocate to make sure that we don't exceed the number of available slots (fgmres->vecs_allocated)*/ if (it + VEC_OFFSET + nalloc >= fgmres->vecs_allocated) nalloc = fgmres->vecs_allocated - it - VEC_OFFSET; if (!nalloc) PetscFunctionReturn(PETSC_SUCCESS); fgmres->vv_allocated += nalloc; /* vv_allocated is the number of vectors allocated */ /* work vectors */ PetscCall(KSPCreateVecs(ksp, nalloc, &fgmres->user_work[nwork], 0, NULL)); for (k = 0; k < nalloc; k++) fgmres->vecs[it + VEC_OFFSET + k] = fgmres->user_work[nwork][k]; /* specify size of chunk allocated */ fgmres->mwork_alloc[nwork] = nalloc; /* preconditioned vectors */ PetscCall(KSPCreateVecs(ksp, nalloc, &fgmres->prevecs_user_work[nwork], 0, NULL)); for (k = 0; k < nalloc; k++) fgmres->prevecs[it + k] = fgmres->prevecs_user_work[nwork][k]; /* increment the number of work vector chunks */ fgmres->nwork_alloc++; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPBuildSolution_FGMRES(KSP ksp, Vec ptr, Vec *result) { KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscFunctionBegin; if (!ptr) { if (!fgmres->sol_temp) PetscCall(VecDuplicate(ksp->vec_sol, &fgmres->sol_temp)); ptr = fgmres->sol_temp; } if (!fgmres->nrs) { /* allocate the work area */ PetscCall(PetscMalloc1(fgmres->max_k, &fgmres->nrs)); } PetscCall(KSPFGMRESBuildSoln(fgmres->nrs, ksp->vec_sol, ptr, ksp, fgmres->it)); if (result) *result = ptr; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPSetFromOptions_FGMRES(KSP ksp, PetscOptionItems PetscOptionsObject) { PetscBool flg; PetscFunctionBegin; PetscCall(KSPSetFromOptions_GMRES(ksp, PetscOptionsObject)); PetscOptionsHeadBegin(PetscOptionsObject, "KSP flexible GMRES Options"); PetscCall(PetscOptionsBoolGroupBegin("-ksp_fgmres_modifypcnochange", "do not vary the preconditioner", "KSPFGMRESSetModifyPC", &flg)); if (flg) PetscCall(KSPFGMRESSetModifyPC(ksp, KSPFGMRESModifyPCNoChange, NULL, NULL)); PetscCall(PetscOptionsBoolGroupEnd("-ksp_fgmres_modifypcksp", "vary the KSP based preconditioner", "KSPFGMRESSetModifyPC", &flg)); if (flg) PetscCall(KSPFGMRESSetModifyPC(ksp, KSPFGMRESModifyPCKSP, NULL, NULL)); PetscOptionsHeadEnd(); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPFGMRESSetModifyPC_FGMRES(KSP ksp, KSPFlexibleModifyPCFn *fcn, void *ctx, PetscCtxDestroyFn *d) { PetscFunctionBegin; PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); ((KSP_FGMRES *)ksp->data)->modifypc = fcn; ((KSP_FGMRES *)ksp->data)->modifydestroy = d; ((KSP_FGMRES *)ksp->data)->modifyctx = ctx; PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode KSPReset_FGMRES(KSP ksp) { KSP_FGMRES *fgmres = (KSP_FGMRES *)ksp->data; PetscInt i; PetscFunctionBegin; PetscCall(PetscFree(fgmres->prevecs)); if (fgmres->nwork_alloc > 0) { i = 0; /* In the first allocation we allocated VEC_OFFSET fewer vectors in prevecs */ PetscCall(VecDestroyVecs(fgmres->mwork_alloc[i] - VEC_OFFSET, &fgmres->prevecs_user_work[i])); for (i = 1; i < fgmres->nwork_alloc; i++) PetscCall(VecDestroyVecs(fgmres->mwork_alloc[i], &fgmres->prevecs_user_work[i])); } PetscCall(PetscFree(fgmres->prevecs_user_work)); if (fgmres->modifydestroy) PetscCall((*fgmres->modifydestroy)(&fgmres->modifyctx)); PetscCall(KSPReset_GMRES(ksp)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPGMRESSetRestart_FGMRES(KSP ksp, PetscInt max_k) { KSP_FGMRES *gmres = (KSP_FGMRES *)ksp->data; PetscFunctionBegin; PetscCheck(max_k >= 1, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_OUTOFRANGE, "Restart must be positive"); if (!ksp->setupstage) { gmres->max_k = max_k; } else if (gmres->max_k != max_k) { gmres->max_k = max_k; ksp->setupstage = KSP_SETUP_NEW; /* free the data structures, then create them again */ PetscCall(KSPReset_FGMRES(ksp)); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPGMRESGetRestart_FGMRES(KSP ksp, PetscInt *max_k) { KSP_FGMRES *gmres = (KSP_FGMRES *)ksp->data; PetscFunctionBegin; *max_k = gmres->max_k; PetscFunctionReturn(PETSC_SUCCESS); } /*MC KSPFGMRES - Implements the Flexible Generalized Minimal Residual method, flexible GMRES. [](sec_flexibleksp) Options Database Keys: + -ksp_gmres_restart <restart> - the number of Krylov directions to orthogonalize against . -ksp_gmres_haptol <tol> - sets the tolerance for "happy ending" (exact convergence) . -ksp_gmres_preallocate - preallocate all the Krylov search directions initially (otherwise groups of vectors are allocated as needed) . -ksp_gmres_classicalgramschmidt - use classical (unmodified) Gram-Schmidt to orthogonalize against the Krylov space (fast) (the default) . -ksp_gmres_modifiedgramschmidt - use modified Gram-Schmidt in the orthogonalization (more stable, but slower) . -ksp_gmres_cgs_refinement_type <refine_never,refine_ifneeded,refine_always> - determine if iterative refinement is used to increase the stability of the classical Gram-Schmidt orthogonalization. . -ksp_gmres_krylov_monitor - plot the Krylov space generated . -ksp_fgmres_modifypcnochange - do not change the preconditioner between iterations - -ksp_fgmres_modifypcksp - modify the preconditioner using `KSPFGMRESModifyPCKSP()` Level: beginner Notes: See `KSPFlexibleSetModifyPC()` or `KSPFGMRESSetModifyPC()` for how to vary the preconditioner between iterations GMRES requires that the preconditioner used is a linear operator. Flexible GMRES allows the preconditioner to be a nonlinear operator. This allows, for example, Flexible GMRES to use GMRES solvers or other Krylov solvers (which are nonlinear operators in general) inside the preconditioner used by `KSPFGMRES`. For example, the options `-ksp_type fgmres -pc_type ksp -ksp_ksp_type bcgs -ksp_view -ksp_pc_type jacobi` make the preconditioner (or inner solver) be bi-CG-stab with a preconditioner of `PCJACOBI`. `KSPFCG` provides a flexible version of the preconditioned conjugate gradient method. Only right preconditioning is supported. The following options `-ksp_type fgmres -pc_type ksp -ksp_ksp_type bcgs -ksp_view -ksp_pc_type jacobi` make the preconditioner (or inner solver) be bi-CG-stab with a preconditioner of `PCJACOBI` Developer Note: This object is subclassed off of `KSPGMRES`, see the source code in src/ksp/ksp/impls/gmres for comments on the structure of the code Contributed by: Allison Baker .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPCreate()`, `KSPSetType()`, `KSPType`, `KSP`, `KSPGMRES`, `KSPLGMRES`, `KSPFCG`, `KSPGMRESSetRestart()`, `KSPGMRESSetHapTol()`, `KSPGMRESSetPreAllocateVectors()`, `KSPGMRESSetOrthogonalization()`, `KSPGMRESGetOrthogonalization()`, `KSPGMRESClassicalGramSchmidtOrthogonalization()`, `KSPGMRESModifiedGramSchmidtOrthogonalization()`, `KSPGMRESCGSRefinementType`, `KSPGMRESSetCGSRefinementType()`, `KSPGMRESGetCGSRefinementType()`, `KSPGMRESMonitorKrylov()`, `KSPFGMRESSetModifyPC()`, `KSPFGMRESModifyPCKSP()` M*/ PETSC_EXTERN PetscErrorCode KSPCreate_FGMRES(KSP ksp) { KSP_FGMRES *fgmres; PetscFunctionBegin; PetscCall(PetscNew(&fgmres)); ksp->data = (void *)fgmres; ksp->ops->buildsolution = KSPBuildSolution_FGMRES; ksp->ops->setup = KSPSetUp_FGMRES; ksp->ops->solve = KSPSolve_FGMRES; ksp->ops->reset = KSPReset_FGMRES; ksp->ops->destroy = KSPDestroy_FGMRES; ksp->ops->view = KSPView_GMRES; ksp->ops->setfromoptions = KSPSetFromOptions_FGMRES; ksp->ops->computeextremesingularvalues = KSPComputeExtremeSingularValues_GMRES; ksp->ops->computeeigenvalues = KSPComputeEigenvalues_GMRES; PetscCall(KSPSetSupportedNorm(ksp, KSP_NORM_UNPRECONDITIONED, PC_RIGHT, 3)); PetscCall(KSPSetSupportedNorm(ksp, KSP_NORM_NONE, PC_RIGHT, 1)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPGMRESSetPreAllocateVectors_C", KSPGMRESSetPreAllocateVectors_GMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPGMRESSetOrthogonalization_C", KSPGMRESSetOrthogonalization_GMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPGMRESGetOrthogonalization_C", KSPGMRESGetOrthogonalization_GMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPGMRESSetRestart_C", KSPGMRESSetRestart_FGMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPGMRESGetRestart_C", KSPGMRESGetRestart_FGMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPFGMRESSetModifyPC_C", KSPFGMRESSetModifyPC_FGMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPFlexibleSetModifyPC_C", KSPFGMRESSetModifyPC_FGMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPGMRESSetCGSRefinementType_C", KSPGMRESSetCGSRefinementType_GMRES)); PetscCall(PetscObjectComposeFunction((PetscObject)ksp, "KSPGMRESGetCGSRefinementType_C", KSPGMRESGetCGSRefinementType_GMRES)); fgmres->haptol = 1.0e-30; fgmres->q_preallocate = 0; fgmres->delta_allocate = FGMRES_DELTA_DIRECTIONS; fgmres->orthog = KSPGMRESClassicalGramSchmidtOrthogonalization; fgmres->nrs = NULL; fgmres->sol_temp = NULL; fgmres->max_k = FGMRES_DEFAULT_MAXK; fgmres->Rsvd = NULL; fgmres->orthogwork = NULL; fgmres->modifypc = KSPFGMRESModifyPCNoChange; fgmres->modifyctx = NULL; fgmres->modifydestroy = NULL; fgmres->cgstype = KSP_GMRES_CGS_REFINE_NEVER; PetscFunctionReturn(PETSC_SUCCESS); }中文注释,转成Fortran

www_kitty
  • 粉丝: 0
上传资源 快速赚钱