protected GmresSolver(ILogger logger, INativeMemoryProvider memoryProvider, GmresParams parameters) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (memoryProvider == null) { throw new ArgumentNullException(nameof(memoryProvider)); } Logger = logger; Parameters = parameters; _nloc = Parameters.LocalDimensionSize; _m = Parameters.BufferSize; _dotProducts = Parameters.GramSchmidtType == GramSchmidtType.IterativeClassical ? new NativeVector(memoryProvider, _m) : new NativeVector(memoryProvider, 1); var krylovSize = Parameters.ResidualAtRestart == ResidualAtRestart.ComputeTheTrue ? _m : _m + 1; _krylovBasis = new FortranMatrix(memoryProvider, _nloc, krylovSize); _hessenberg = new FortranMatrix(memoryProvider, _m + 1, _m + 1); _w = new NativeVector(memoryProvider, _nloc); _r0 = new NativeVector(memoryProvider, _nloc); _xCurrent = new NativeVector(memoryProvider, _nloc); _yCurrent = new NativeVector(memoryProvider, _m); _givensRotSin = new Complex[_m]; _givensRotCos = new double[_m]; }
protected override void ApplyPreconditionerRight(NativeVector src, NativeVector dst, int jH) { var col = _precondKrylovBasis.GetColumnVector(jH); OnRightPreconditionerRequest(new RightPreconditionerRequestEventArgs(src, col)); UnsafeNativeMethods.Zcopy(Parameters.LocalDimensionSize, col.Ptr, dst.Ptr); }
public static void Sub(NativeVector v1, NativeVector v2, NativeVector result) { for (int i = 0; i < result.Length; i++) { result[i] = v1[i] - v2[i]; } }
private double PrepareRestart(NativeVector rhs, NativeVector x, int jH) { ConstructCurrentSolution(jH, x); double beta; if (Parameters.ResidualAtRestart == ResidualAtRestart.ComputeTheTrue) { UnsafeNativeMethods.Zcopy(_nloc, x.Ptr, _w.Ptr); CalculateMatrixVectorMult(_w, _r0); NativeVector.Sub(rhs, _r0, _r0); if (Parameters.Preconditioning != Preconditioning.None) { throw new NotImplementedException(); } UnsafeNativeMethods.Zcopy(_nloc, _r0.Ptr, _w.Ptr); beta = CalculateVectorNorm(_w); } else { beta = _hessenberg[_m, _m].Magnitude; for (int j = _m - 1; j >= 0; j--) { _hessenberg[j, _m] = Zero; Zrot(_hessenberg.GetPointer(j, _m), _hessenberg.GetPointer(j + 1, _m), _givensRotCos[j], -_givensRotSin[j]); UnsafeNativeMethods.ZgemvNotTrans(_nloc, _m + 1, One, _krylovBasis.Ptr, _hessenberg.GetColumn(_m), Zero, _w.Ptr); } } return(beta); }
private double CalculateVectorNorm(NativeVector vector) { CalculateDotProduct(vector.Ptr, vector.Ptr); var vectorNorm = Sqrt(_dotProducts[0].Real); return(vectorNorm); }
public static void Mult(double alpha, NativeVector v, NativeVector result) { for (int i = 0; i < result.Length; i++) { result[i] = alpha * v[i]; } ; }
private void ApplyPreconditionerLeft(NativeVector x, NativeVector result) { if (Parameters.Preconditioning != Preconditioning.None) { throw new NotImplementedException(); } UnsafeNativeMethods.Zcopy(_nloc, x.Ptr, result.Ptr); }
protected override void ApplyPreconditionerRight(NativeVector src, NativeVector dst, int jH) { if (Parameters.Preconditioning != Preconditioning.None) { throw new NotImplementedException(); } UnsafeNativeMethods.Zcopy(Parameters.LocalDimensionSize, src.Ptr, dst.Ptr); }
private void ConstructCurrentSolution(int jH, NativeVector result) { UnsafeNativeMethods.Zcopy(jH, _hessenberg.GetColumn(_m), _yCurrent.Ptr); UnsafeNativeMethods.SimplifiedZtrsv(jH, _hessenberg.Ptr, _m + 1, _yCurrent.Ptr); CalculateSolutionProjectionToKrylovSubspace(jH); NativeVector.Add(result, _r0, _xCurrent); UnsafeNativeMethods.Zcopy(_nloc, _xCurrent.Ptr, result.Ptr); }
private double FinalActions(int jH, double sPb, NativeVector rhs, NativeVector result) { ConstructCurrentSolution(jH, result); if (Parameters.BackwardErrorChecking != BackwardErrorChecking.CheckArnoldiOnly) { return(CheckBackwardError(sPb, rhs)); } return(-1); }
private double CheckBackwardError(double sPb, NativeVector rhs) { UnsafeNativeMethods.Zcopy(_nloc, _xCurrent.Ptr, _r0.Ptr); CalculateMatrixVectorMult(_r0, _w); for (int i = 0; i < _w.Length; i++) { _w[i] = rhs[i] - _w[i]; } var trueNormRes = CalculateVectorNorm(_w); if (Parameters.Preconditioning != Preconditioning.None) { throw new NotImplementedException(); } var dnormres = trueNormRes; var be = dnormres / sPb; if (be >= Parameters.Tolerance) { var messageString = $"be = {be}, tolerance = {Parameters.Tolerance}"; if (Parameters.BackwardErrorChecking == BackwardErrorChecking.CheckWithException) { throw new BackwardErrorException(messageString); } if (Parameters.BackwardErrorChecking == BackwardErrorChecking.CheckWithWarning) { Logger.WriteWarning(messageString); } } return(be); }
private void CalculateMatrixVectorMult(NativeVector x, NativeVector result) { var args = new MatrixVectorMultRequestEventArgs(x, result); OnMatrixVectorMultRequest(args); }
public MatrixVectorMultRequestEventArgs(NativeVector x, NativeVector result) { X = x; Result = result; }
public RightPreconditionerRequestEventArgs(NativeVector src, NativeVector dst) { Src = src; Dst = dst; }
protected abstract void ApplyPreconditionerRight(NativeVector src, NativeVector dst, int jH);
public ResultInfo Solve(NativeVector rightHandSide, NativeVector initialGuess, NativeVector result) { return(_flexibleGmres.Solve(rightHandSide, initialGuess, result)); }
public ResultInfo Solve(NativeVector rightHandSide, NativeVector initialGuess, NativeVector result) { _iterationCounter = 0; var bn = CalculateVectorNorm(rightHandSide); if (CheckRightHandSideForZero(bn)) { return(ResultInfo.Converged(0, 0, 0)); } var sb = CalculateScaleFactorsForBackwardErrorUnprecond(bn); var sPb = CalculateScaleFactorsForBackwardErrorPrecond(bn); if (Parameters.InitialGuess == InitialGuess.EqualsZero) { initialGuess.SetAllValuesToZero(); for (int i = 0; i < _r0.Length; i++) { _r0[i] = rightHandSide[i]; } } else { CalculateMatrixVectorMult(initialGuess, _r0); for (int i = 0; i < _r0.Length; i++) { _r0[i] = rightHandSide[i] - _r0[i]; } } ApplyPreconditionerLeft(_r0, _w); var beta = CalculateVectorNorm(_w); if (CheckForExactSolution(beta)) { UnsafeNativeMethods.Zcopy(_nloc, initialGuess.Ptr, result.Ptr); return(ResultInfo.Converged(0, 0, 1)); } double bea = -1; double be = -1; int iter = 0; UnsafeNativeMethods.Zcopy(initialGuess.Length, initialGuess.Ptr, result.Ptr); while (true) { NativeVector.Mult(1 / beta, _w, _krylovBasis.GetColumnVector(0)); _hessenberg[0, _m] = beta; for (int i = 1; i <= _m; i++) { _hessenberg[i, _m] = Zero; } int jH = 0; bea = KrylovSubspaceConstruction(bn, ref jH); if (bea < Parameters.Tolerance) { be = FinalActions(jH, sPb, rightHandSide, result); return(ResultInfo.Converged(bea, be, _iterationCounter)); } iter++; if (iter >= Parameters.MaxRepeatNumber) { break; } beta = PrepareRestart(rightHandSide, result, jH); } be = FinalActions(_m, sPb, rightHandSide, result);//ConstructCurrentSolution(_m, result); return(ResultInfo.NonConverged(bea, be, _iterationCounter)); }