From 70ee93d449e989d45d5fa22a96a4c762bcd7cc08 Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 15 Mar 2022 00:05:37 +0100 Subject: [PATCH 1/2] Add HYPRE interop. --- CSparse.Interop/CSparse.Interop.csproj | 4 + CSparse.Interop/Interop/Hypre/BiCGSTAB.cs | 68 + CSparse.Interop/Interop/Hypre/BoomerAMG.cs | 93 + CSparse.Interop/Interop/Hypre/CGNR.cs | 68 + CSparse.Interop/Interop/Hypre/COGMRES.cs | 79 + CSparse.Interop/Interop/Hypre/Constants.cs | 10 + CSparse.Interop/Interop/Hypre/FlexGMRES.cs | 89 + CSparse.Interop/Interop/Hypre/GMRES.cs | 80 + CSparse.Interop/Interop/Hypre/HypreMatrix.cs | 108 + CSparse.Interop/Interop/Hypre/HypreResult.cs | 10 + CSparse.Interop/Interop/Hypre/HypreSolver.cs | 52 + CSparse.Interop/Interop/Hypre/HypreVector.cs | 84 + .../Interop/Hypre/IHyprePreconditioner.cs | 11 + CSparse.Interop/Interop/Hypre/ILU.cs | 39 + CSparse.Interop/Interop/Hypre/LGMRES.cs | 78 + .../Interop/Hypre/NativeMethods.cs | 1854 +++++++++++++++++ CSparse.Interop/Interop/Hypre/PCG.cs | 83 + CSparse.Interop/Interop/Hypre/ParaSails.cs | 41 + CSparse.Interop/Interop/Hypre/Types.cs | 30 + 19 files changed, 2881 insertions(+) create mode 100644 CSparse.Interop/Interop/Hypre/BiCGSTAB.cs create mode 100644 CSparse.Interop/Interop/Hypre/BoomerAMG.cs create mode 100644 CSparse.Interop/Interop/Hypre/CGNR.cs create mode 100644 CSparse.Interop/Interop/Hypre/COGMRES.cs create mode 100644 CSparse.Interop/Interop/Hypre/Constants.cs create mode 100644 CSparse.Interop/Interop/Hypre/FlexGMRES.cs create mode 100644 CSparse.Interop/Interop/Hypre/GMRES.cs create mode 100644 CSparse.Interop/Interop/Hypre/HypreMatrix.cs create mode 100644 CSparse.Interop/Interop/Hypre/HypreResult.cs create mode 100644 CSparse.Interop/Interop/Hypre/HypreSolver.cs create mode 100644 CSparse.Interop/Interop/Hypre/HypreVector.cs create mode 100644 CSparse.Interop/Interop/Hypre/IHyprePreconditioner.cs create mode 100644 CSparse.Interop/Interop/Hypre/ILU.cs create mode 100644 CSparse.Interop/Interop/Hypre/LGMRES.cs create mode 100644 CSparse.Interop/Interop/Hypre/NativeMethods.cs create mode 100644 CSparse.Interop/Interop/Hypre/PCG.cs create mode 100644 CSparse.Interop/Interop/Hypre/ParaSails.cs create mode 100644 CSparse.Interop/Interop/Hypre/Types.cs diff --git a/CSparse.Interop/CSparse.Interop.csproj b/CSparse.Interop/CSparse.Interop.csproj index fbe8686..380f25c 100644 --- a/CSparse.Interop/CSparse.Interop.csproj +++ b/CSparse.Interop/CSparse.Interop.csproj @@ -30,5 +30,9 @@ + + + + diff --git a/CSparse.Interop/Interop/Hypre/BiCGSTAB.cs b/CSparse.Interop/Interop/Hypre/BiCGSTAB.cs new file mode 100644 index 0000000..7d45067 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/BiCGSTAB.cs @@ -0,0 +1,68 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class BiCGSTAB : HypreSolver + where T : struct, IEquatable, IFormattable + { + public BiCGSTAB() + { + NativeMethods.HYPRE_ParCSRBiCGSTABCreate(Constants.MPI_COMM_WORLD, out solver); + } + + public BiCGSTAB(IHyprePreconditioner precond) + : this() + { + precond.Bind(this); + } + + internal override void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + NativeMethods.HYPRE_ParCSRBiCGSTABSetPrecond(solver, precond, precond_setup, precond_solver); + } + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_BiCGSTABSetPrintLevel(solver, PrintLevel); + NativeMethods.HYPRE_BiCGSTABSetLogging(solver, Logging); + + NativeMethods.HYPRE_BiCGSTABSetTol(solver, 1e-7); + //-HYPRE_BiCGSTABSetAbsoluteTol + //-HYPRE_BiCGSTABSetConvergenceFactorTol + //-HYPRE_BiCGSTABSetStopCrit + //-HYPRE_BiCGSTABSetMinIter + NativeMethods.HYPRE_BiCGSTABSetMaxIter(solver, 1000); + + var parcsr_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_ParCSRBiCGSTABSetup(solver, parcsr_A, par_b, par_x); + NativeMethods.HYPRE_ParCSRBiCGSTABSolve(solver, parcsr_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_BiCGSTABGetNumIterations(solver, out result.NumIterations); + //NativeMethods.HYPRE_BiCGSTABGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_BiCGSTABGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + result.Converged = 1; // result.NumIterations < max_iter; + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParCSRBiCGSTABDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/BoomerAMG.cs b/CSparse.Interop/Interop/Hypre/BoomerAMG.cs new file mode 100644 index 0000000..3409c82 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/BoomerAMG.cs @@ -0,0 +1,93 @@ + +namespace CSparse.Interop.Hypre +{ + using System; + + public class BoomerAMG : HypreSolver, IHyprePreconditioner + where T : struct, IEquatable, IFormattable + { + public BoomerAMG() + { + NativeMethods.HYPRE_BoomerAMGCreate(out solver); + } + + public void Bind(HypreSolver solver) + { + solver.SetPreconditioner(NativeMethods.HYPRE_BoomerAMGSolve, NativeMethods.HYPRE_BoomerAMGSetup, this.solver); + } + + public void SetTol(double tol) + { + NativeMethods.HYPRE_BoomerAMGSetTol(solver, tol); + } + + public void SetMaxLevels(int max_levels) + { + NativeMethods.HYPRE_BoomerAMGSetMaxLevels(solver, max_levels); + } + + public void SetNumSweeps(int num_sweeps) + { + NativeMethods.HYPRE_BoomerAMGSetNumSweeps(solver, num_sweeps); + } + + public void SetRelaxOrder(int relax_order) + { + NativeMethods.HYPRE_BoomerAMGSetRelaxOrder(solver, relax_order); + } + + public void SetRelaxType(int relax_type) + { + NativeMethods.HYPRE_BoomerAMGSetRelaxType(solver, relax_type); + } + + public void SetCoarsenType(int coarsen) + { + NativeMethods.HYPRE_BoomerAMGSetCoarsenType(solver, coarsen); + } + + public void SetOldDefault() + { + NativeMethods.HYPRE_BoomerAMGSetOldDefault(solver); + } + + public void SetMaxIter(int max_iter) + { + NativeMethods.HYPRE_BoomerAMGSetMaxIter(solver, max_iter); + } + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_BoomerAMGSetPrintLevel(solver, PrintLevel); + NativeMethods.HYPRE_BoomerAMGSetLogging(solver, Logging); + + var par_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_BoomerAMGSetup(solver, par_A, par_b, par_x); + NativeMethods.HYPRE_BoomerAMGSolve(solver, par_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_BoomerAMGGetNumIterations(solver, out result.NumIterations); + //NativeMethods.HYPRE_BoomerAMGGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_BoomerAMGGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + result.Converged = 1; + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_BoomerAMGDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/CGNR.cs b/CSparse.Interop/Interop/Hypre/CGNR.cs new file mode 100644 index 0000000..df08c20 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/CGNR.cs @@ -0,0 +1,68 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class CGNR : HypreSolver + where T : struct, IEquatable, IFormattable + { + public CGNR() + { + NativeMethods.HYPRE_ParCSRCGNRCreate(Constants.MPI_COMM_WORLD, out solver); + } + + /* + public CGNR(IHyprePreconditioner precond) + : this() + { + precond.Bind(this); + } + + internal override void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precondT, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + NativeMethods.HYPRE_ParCSRCGNRSetPrecond(solver, precond, precondT, precond_setup, precond_solver); + } + //*/ + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_CGNRSetLogging(solver, Logging); + + NativeMethods.HYPRE_CGNRSetTol(solver, 1e-7); + //-HYPRE_CGNRSetStopCrit + //-HYPRE_CGNRSetMinIter + NativeMethods.HYPRE_CGNRSetMaxIter(solver, 1000); + + var par_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_ParCSRCGNRSetup(solver, par_A, par_b, par_x); + NativeMethods.HYPRE_ParCSRCGNRSolve(solver, par_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_CGNRGetNumIterations(solver, out result.NumIterations); + //NativeMethods.HYPRE_CGNRGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_CGNRGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + result.Converged = 1; + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParCSRCGNRDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/COGMRES.cs b/CSparse.Interop/Interop/Hypre/COGMRES.cs new file mode 100644 index 0000000..1fc6c55 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/COGMRES.cs @@ -0,0 +1,79 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class COGMRES : HypreSolver + where T : struct, IEquatable, IFormattable + { + public COGMRES() + { + NativeMethods.HYPRE_ParCSRCOGMRESCreate(Constants.MPI_COMM_WORLD, out solver); + } + public COGMRES(IHyprePreconditioner precond) + : this() + { + precond.Bind(this); + } + + internal override void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + NativeMethods.HYPRE_ParCSRCOGMRESSetPrecond(solver, precond, precond_setup, precond_solver); + } + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_COGMRESSetPrintLevel(solver, PrintLevel); + NativeMethods.HYPRE_COGMRESSetLogging(solver, Logging); + + int restart = 30; + bool modify = true; + + NativeMethods.HYPRE_COGMRESSetTol(solver, 1e-7); + //HYPRE_COGMRESSetAbsoluteTol + //-HYPRE_COGMRESSetConvergenceFactorTol + //-HYPRE_COGMRESSetMinIter + NativeMethods.HYPRE_COGMRESSetMaxIter(solver, 1000); + NativeMethods.HYPRE_COGMRESSetKDim(solver, restart); + //HYPRE_COGMRESSetUnroll + //HYPRE_COGMRESSetCGS + + if (modify) + { + /* this is an optional call - if you don't call it, hypre_COGMRESModifyPCDefault + is used - which does nothing. Otherwise, you can define your own, similar to + the one used here */ + //HYPRE_COGMRESSetModifyPC( + // solver, (HYPRE_PtrToModifyPCFcn)hypre_COGMRESModifyPCAMGExample); + } + + var par_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_ParCSRCOGMRESSetup(solver, par_A, par_b, par_x); + NativeMethods.HYPRE_ParCSRCOGMRESSolve(solver, par_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_COGMRESGetNumIterations(solver, out result.NumIterations); + NativeMethods.HYPRE_COGMRESGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_COGMRESGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParCSRCOGMRESDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/Constants.cs b/CSparse.Interop/Interop/Hypre/Constants.cs new file mode 100644 index 0000000..40cc8ff --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/Constants.cs @@ -0,0 +1,10 @@ + +namespace CSparse.Interop.Hypre +{ + public class Constants + { + public const int MPI_COMM_WORLD = 1; + public const int HYPRE_PARCSR = 5555; + public const int HYPRE_OK = 0; + } +} diff --git a/CSparse.Interop/Interop/Hypre/FlexGMRES.cs b/CSparse.Interop/Interop/Hypre/FlexGMRES.cs new file mode 100644 index 0000000..b6df52f --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/FlexGMRES.cs @@ -0,0 +1,89 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class FlexGMRES : HypreSolver + where T : struct, IEquatable, IFormattable + { + public FlexGMRES() + { + NativeMethods.HYPRE_ParCSRFlexGMRESCreate(Constants.MPI_COMM_WORLD, out solver); + } + public FlexGMRES(IHyprePreconditioner precond) + : this() + { + precond.Bind(this); + } + + internal override void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + NativeMethods.HYPRE_ParCSRFlexGMRESSetPrecond(solver, precond, precond_setup, precond_solver); + } + + //HYPRE_FlexGMRESSetAbsoluteTol + //-HYPRE_FlexGMRESSetConvergenceFactorTol + //-HYPRE_FlexGMRESSetMinIter + + public void SetTol(double tol) + { + NativeMethods.HYPRE_FlexGMRESSetTol(solver, tol); + } + + public void SetKDim(int restart) + { + NativeMethods.HYPRE_FlexGMRESSetKDim(solver, restart); + } + + public void SetMaxIter(int max_iter) + { + NativeMethods.HYPRE_FlexGMRESSetMaxIter(solver, max_iter); + } + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_FlexGMRESSetLogging(solver, Logging); + NativeMethods.HYPRE_FlexGMRESSetPrintLevel(solver, PrintLevel); + + int restart = 30; + bool modify = true; + + if (modify) + { + /* this is an optional call - if you don't call it, hypre_FlexGMRESModifyPCDefault + is used - which does nothing. Otherwise, you can define your own, similar to + the one used here */ + //HYPRE_FlexGMRESSetModifyPC( + // solver, (HYPRE_PtrToModifyPCFcn)hypre_FlexGMRESModifyPCAMGExample); + } + + var par_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_ParCSRFlexGMRESSetup(solver, par_A, par_b, par_x); + NativeMethods.HYPRE_ParCSRFlexGMRESSolve(solver, par_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_FlexGMRESGetNumIterations(solver, out result.NumIterations); + NativeMethods.HYPRE_FlexGMRESGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_FlexGMRESGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParCSRFlexGMRESDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/GMRES.cs b/CSparse.Interop/Interop/Hypre/GMRES.cs new file mode 100644 index 0000000..a8c453d --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/GMRES.cs @@ -0,0 +1,80 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class GMRES : HypreSolver + where T : struct, IEquatable, IFormattable + { + public GMRES() + { + NativeMethods.HYPRE_ParCSRGMRESCreate(Constants.MPI_COMM_WORLD, out solver); + } + public GMRES(IHyprePreconditioner precond) + : this() + { + precond.Bind(this); + } + + internal override void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + NativeMethods.HYPRE_ParCSRGMRESSetPrecond(solver, precond, precond_setup, precond_solver); + } + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_GMRESSetPrintLevel(solver, PrintLevel); + NativeMethods.HYPRE_GMRESSetLogging(solver, Logging); + + int restart = 30; + bool modify = true; + + NativeMethods.HYPRE_GMRESSetTol(solver, 1e-7); + //HYPRE_GMRESSetAbsoluteTol + //-HYPRE_GMRESSetConvergenceFactorTol + //-HYPRE_GMRESSetStopCrit + //-HYPRE_GMRESSetMinIter + NativeMethods.HYPRE_GMRESSetMaxIter(solver, 1000); + NativeMethods.HYPRE_GMRESSetKDim(solver, restart); + //HYPRE_GMRESSetRelChange + //HYPRE_GMRESSetSkipRealResidualCheck + + if (modify) + { + /* this is an optional call - if you don't call it, hypre_GMRESModifyPCDefault + is used - which does nothing. Otherwise, you can define your own, similar to + the one used here */ + //HYPRE_GMRESSetModifyPC( + // solver, (HYPRE_PtrToModifyPCFcn)hypre_GMRESModifyPCAMGExample); + } + + var par_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_ParCSRGMRESSetup(solver, par_A, par_b, par_x); + NativeMethods.HYPRE_ParCSRGMRESSolve(solver, par_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_GMRESGetNumIterations(solver, out result.NumIterations); + NativeMethods.HYPRE_GMRESGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_GMRESGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParCSRGMRESDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/HypreMatrix.cs b/CSparse.Interop/Interop/Hypre/HypreMatrix.cs new file mode 100644 index 0000000..c32729c --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/HypreMatrix.cs @@ -0,0 +1,108 @@ + +namespace CSparse.Interop.Hypre +{ + using CSparse.Storage; + using System; + using System.Runtime.InteropServices; + + public class HypreMatrix : IDisposable + where T : struct, IEquatable, IFormattable + { + HYPRE_IJMatrix mat; + + CompressedColumnStorage A; + + public int RowCount { get; private set; } + public int ColumnCount { get; private set; } + + public HypreMatrix(CompressedColumnStorage matrix, bool symmetric) + { + // HYPRE uses CSR storage. + A = symmetric ? matrix : matrix.Transpose(); + + RowCount = matrix.RowCount; + ColumnCount = matrix.ColumnCount; + + NativeMethods.HYPRE_IJMatrixCreate(Constants.MPI_COMM_WORLD, + 0, A.RowCount - 1, + 0, A.ColumnCount - 1, + out mat); + + NativeMethods.HYPRE_IJMatrixSetObjectType(mat, Constants.HYPRE_PARCSR); + NativeMethods.HYPRE_IJMatrixInitialize(mat); + + SetValues(); + + NativeMethods.HYPRE_IJMatrixAssemble(mat); + } + + protected virtual int SetValues() + { + var ap = A.ColumnPointers; + var aj = A.RowIndices; + var ax = A.Values; + + int cols = A.ColumnCount; + + int size = (int)(A.NonZerosCount / (double)A.ColumnCount) + 1; + + var columns = new int[size]; + var values = new T[size]; + + var hValues = GCHandle.Alloc(values, GCHandleType.Pinned); + var pValues = hValues.AddrOfPinnedObject(); + + for (int i = 0; i < cols; i++) + { + int j = ap[i]; + int end = ap[i + 1]; + int nnz = end - j; + + if (nnz == 0) continue; + + if (size < nnz) + { + size = nnz; + columns = new int[size]; + values = new T[size]; + + hValues.Free(); + + hValues = GCHandle.Alloc(values, GCHandleType.Pinned); + pValues = hValues.AddrOfPinnedObject(); + } + + for (int k = 0; j < end; j++, k++) + { + columns[k] = aj[j]; + values[k] = ax[j]; + } + + int status = NativeMethods.HYPRE_IJMatrixSetValues(mat, 1, ref nnz, ref i, columns, pValues); + + if (status != Constants.HYPRE_OK) + { + return status; + } + } + + return Constants.HYPRE_OK; + } + + internal HYPRE_ParCSRMatrix GetObject() + { + NativeMethods.HYPRE_IJMatrixGetObject(mat, out var par_mat); + + return par_mat; + } + + public void Dispose() + { + if (mat.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_IJMatrixDestroy(mat); + mat.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/HypreResult.cs b/CSparse.Interop/Interop/Hypre/HypreResult.cs new file mode 100644 index 0000000..f5d6088 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/HypreResult.cs @@ -0,0 +1,10 @@ + +namespace CSparse.Interop.Hypre +{ + public struct HypreResult + { + public int NumIterations; + public int Converged; + public double RelResidualNorm; + } +} diff --git a/CSparse.Interop/Interop/Hypre/HypreSolver.cs b/CSparse.Interop/Interop/Hypre/HypreSolver.cs new file mode 100644 index 0000000..8b310af --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/HypreSolver.cs @@ -0,0 +1,52 @@ + +namespace CSparse.Interop.Hypre +{ + using System; + + public abstract class HypreSolver : IDisposable + where T : struct, IEquatable, IFormattable + { + protected HYPRE_Solver solver; + + public HypreSolver() + { + if (typeof(T) != typeof(double)) + { + throw new NotSupportedException("This version of HYPRE only supports type 'double'"); + } + } + + ~HypreSolver() + { + Dispose(false); + } + + public int Logging { get; set; } = 0; + + public int PrintLevel { get; set; } = 0; + + public abstract HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b); + + internal virtual void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + throw new NotImplementedException(); + } + + #region IDisposable + + // See https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected abstract void Dispose(bool disposing); + + #endregion + } +} diff --git a/CSparse.Interop/Interop/Hypre/HypreVector.cs b/CSparse.Interop/Interop/Hypre/HypreVector.cs new file mode 100644 index 0000000..1fe69cb --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/HypreVector.cs @@ -0,0 +1,84 @@ + +namespace CSparse.Interop.Hypre +{ + using CSparse.Interop.Common; + using System; + using System.Collections.Generic; + using System.Runtime.InteropServices; + + public class HypreVector : IDisposable + where T : struct + { + HYPRE_IJVector vec; + + GCHandle pi, pv; + + int length; + + public HypreVector(T[] values) + : this(values, values.Length) + { + } + + public HypreVector(T[] values, int length) + { + this.length = length; + + NativeMethods.HYPRE_IJVectorCreate(Constants.MPI_COMM_WORLD, 0, length, out vec); + NativeMethods.HYPRE_IJVectorSetObjectType(vec, Constants.HYPRE_PARCSR); + NativeMethods.HYPRE_IJVectorInitialize(vec); + + var indices = GetIndices(0, length); + + pi = GCHandle.Alloc(indices, GCHandleType.Pinned); + pv = GCHandle.Alloc(values, GCHandleType.Pinned); + + NativeMethods.HYPRE_IJVectorSetValues(vec, length, + pi.AddrOfPinnedObject(), + pv.AddrOfPinnedObject()); + + NativeMethods.HYPRE_IJVectorAssemble(vec); + } + + internal int Synchronize() + { + return NativeMethods.HYPRE_IJVectorGetValues(vec, length, + pi.AddrOfPinnedObject(), + pv.AddrOfPinnedObject()); + } + + internal HYPRE_ParVector GetObject() + { + NativeMethods.HYPRE_IJVectorGetObject(vec, out var par_vec); + + return par_vec; + } + + // TODO: use cache so we don't have to create the same indices all time. + private static int[] GetIndices(int start, int end) + { + int length = end - start; + + var indices = new int[length]; + + for (int i = 0; i < length; i++) + { + indices[i] = start + i; + } + + return indices; + } + + public void Dispose() + { + pi.Free(); + pv.Free(); + + if (vec.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_IJVectorDestroy(vec); + vec.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/IHyprePreconditioner.cs b/CSparse.Interop/Interop/Hypre/IHyprePreconditioner.cs new file mode 100644 index 0000000..cdc4415 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/IHyprePreconditioner.cs @@ -0,0 +1,11 @@ + +namespace CSparse.Interop.Hypre +{ + using System; + + public interface IHyprePreconditioner : IDisposable + where T : struct, IEquatable, IFormattable + { + void Bind(HypreSolver solver); + } +} diff --git a/CSparse.Interop/Interop/Hypre/ILU.cs b/CSparse.Interop/Interop/Hypre/ILU.cs new file mode 100644 index 0000000..77d1e18 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/ILU.cs @@ -0,0 +1,39 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class ILU : IHyprePreconditioner + where T : struct, IEquatable, IFormattable + { + protected HYPRE_Solver precond; + + public ILU() + { + NativeMethods.HYPRE_ILUCreate(out precond); + + double threshold = 0.1; + + /* Set some parameters (See Reference Manual for more parameters) */ + NativeMethods.HYPRE_ILUSetLevelOfFill(precond, 2); + NativeMethods.HYPRE_ILUSetMaxNnzPerRow(precond, 3); + NativeMethods.HYPRE_ILUSetDropThreshold(precond, threshold); + //NativeMethods.HYPRE_ILUSetType(precond, ); + //NativeMethods.HYPRE_ILUSetLocalReordering(precond, ); + //NativeMethods.HYPRE_ILUSetLogging(precond, 3); + } + + public void Bind(HypreSolver solver) + { + solver.SetPreconditioner(NativeMethods.HYPRE_ILUSolve, NativeMethods.HYPRE_ILUSetup, precond); + } + + public void Dispose() + { + if (precond.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ILUDestroy(precond); + precond.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/LGMRES.cs b/CSparse.Interop/Interop/Hypre/LGMRES.cs new file mode 100644 index 0000000..a31ca1e --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/LGMRES.cs @@ -0,0 +1,78 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class LGMRES : HypreSolver + where T : struct, IEquatable, IFormattable + { + public LGMRES() + { + NativeMethods.HYPRE_ParCSRLGMRESCreate(Constants.MPI_COMM_WORLD, out solver); + } + public LGMRES(IHyprePreconditioner precond) + : this() + { + precond.Bind(this); + } + + internal override void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + NativeMethods.HYPRE_ParCSRLGMRESSetPrecond(solver, precond, precond_setup, precond_solver); + } + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_LGMRESSetPrintLevel(solver, PrintLevel); + NativeMethods.HYPRE_LGMRESSetLogging(solver, Logging); + + int restart = 30; + bool modify = true; + + NativeMethods.HYPRE_LGMRESSetTol(solver, 1e-7); + //HYPRE_LGMRESSetAbsoluteTol + //-HYPRE_LGMRESSetConvergenceFactorTol + //-HYPRE_LGMRESSetMinIter + NativeMethods.HYPRE_LGMRESSetMaxIter(solver, 1000); + NativeMethods.HYPRE_LGMRESSetKDim(solver, restart); + //HYPRE_LGMRESSetAugDim + + if (modify) + { + /* this is an optional call - if you don't call it, hypre_LGMRESModifyPCDefault + is used - which does nothing. Otherwise, you can define your own, similar to + the one used here */ + //HYPRE_LGMRESSetModifyPC( + // solver, (HYPRE_PtrToModifyPCFcn)hypre_LGMRESModifyPCAMGExample); + } + + var par_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_ParCSRLGMRESSetup(solver, par_A, par_b, par_x); + NativeMethods.HYPRE_ParCSRLGMRESSolve(solver, par_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_LGMRESGetNumIterations(solver, out result.NumIterations); + NativeMethods.HYPRE_LGMRESGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_LGMRESGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParCSRLGMRESDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/NativeMethods.cs b/CSparse.Interop/Interop/Hypre/NativeMethods.cs new file mode 100644 index 0000000..5d4c560 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/NativeMethods.cs @@ -0,0 +1,1854 @@ + +namespace CSparse.Interop.Hypre +{ + using System; + using System.Runtime.InteropServices; + + using HYPRE_Int = System.Int32; + using HYPRE_BigInt = System.Int32; + using HYPRE_Real = System.Double; + using HYPRE_Complex = System.Double; + using HYPRE_Matrix = HYPRE_IJMatrix; + using HYPRE_Vector = HYPRE_IJVector; + + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate HYPRE_Int HYPRE_PtrToParSolverFcn(HYPRE_Solver solver, + HYPRE_ParCSRMatrix matrix, + HYPRE_ParVector x, + HYPRE_ParVector b); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate HYPRE_Int HYPRE_PtrToModifyPCFcn(HYPRE_Solver solver, HYPRE_Int iterations, HYPRE_Real rel_residual_norm); + + public static class NativeMethods + { + const string HYPRE_DLL = "libhypre"; + + #region HYPRE_utilities.h + + /// + /// HYPRE init. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_Init(); + + /// + /// HYPRE finalize. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_Finalize(); + + // HYPRE error user functions + + /// + /// Return the current hypre error flag. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GetError(); + + /// + /// Check if the given error flag contains the given error code. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CheckError(HYPRE_Int hypre_ierr, HYPRE_Int hypre_error_code); + + /// + /// Return the index of the argument (counting from 1) where argument error (HYPRE_ERROR_ARG) has occured. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GetErrorArg(); + + /// + /// Clears the hypre error flag. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ClearAllErrors(); + + /// + /// Clears the given error code from the hypre error flag. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ClearError(HYPRE_Int hypre_error_code); + + /// + /// Print GPU information. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PrintDeviceInfo(); + + // HYPRE Version routines + + /// + /// Allocates and returns a string with version number information in it. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_Version(ref IntPtr version_ptr); + + /// + /// Returns version number information in integer form. + /// + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_VersionNumber(out HYPRE_Int major_ptr, + out HYPRE_Int minor_ptr, + out HYPRE_Int patch_ptr, + out HYPRE_Int single_ptr); + + #endregion + + #region HYPRE_IJ_mv.h + + #region IJMatrix + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixCreate(int comm, + HYPRE_BigInt ilower, HYPRE_BigInt iupper, + HYPRE_BigInt jlower, HYPRE_BigInt jupper, + out HYPRE_IJMatrix matrix); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixDestroy(HYPRE_IJMatrix matrix); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern void HYPRE_IJMatrixInitialize(HYPRE_IJMatrix matrix); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixSetValues(HYPRE_IJMatrix matrix, + HYPRE_Int nrows, + ref HYPRE_Int ncols, + ref HYPRE_BigInt rows, + HYPRE_BigInt[] cols, + IntPtr values); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixSetValues(HYPRE_IJMatrix matrix, + HYPRE_Int nrows, + HYPRE_Int[] ncols, + HYPRE_BigInt[] rows, + HYPRE_BigInt[] cols, + IntPtr values); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixAssemble(HYPRE_IJMatrix matrix); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixSetObjectType(HYPRE_IJMatrix matrix, HYPRE_Int type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixGetObjectType(HYPRE_IJMatrix matrix, out HYPRE_Int type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJMatrixGetObject(HYPRE_IJMatrix matrix, out HYPRE_ParCSRMatrix obj); + + #endregion + + #region IJVector + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorCreate(int comm, + HYPRE_BigInt ilower, + HYPRE_BigInt iupper, + out HYPRE_IJVector vector); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorDestroy(HYPRE_IJVector vector); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorInitialize(HYPRE_IJVector vector); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorSetValues(HYPRE_IJVector vector, + HYPRE_Int nvalues, + HYPRE_BigInt[] indices, + HYPRE_Complex[] values); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorSetValues(HYPRE_IJVector vector, + HYPRE_Int nvalues, IntPtr indices, IntPtr values); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorGetValues(HYPRE_IJVector vector, + HYPRE_Int nvalues, IntPtr indices, IntPtr values); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorAssemble(HYPRE_IJVector vector); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorSetObjectType(HYPRE_IJVector vector, HYPRE_Int type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorGetObjectType(HYPRE_IJVector vector, + out HYPRE_Int type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_IJVectorGetObject(HYPRE_IJVector vector, out HYPRE_ParVector obj); + + #endregion + + #endregion + + #region HYPRE_parcsr_ls.h + + #region BoomerAMG + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGCreate(out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetPrintLevel(HYPRE_Solver solver, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetTol(HYPRE_Solver solver, double v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetMaxLevels(HYPRE_Solver solver, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetNumSweeps(HYPRE_Solver solver, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetRelaxOrder(HYPRE_Solver solver, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetRelaxType(HYPRE_Solver solver, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetOldDefault(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix parcsr_A, HYPRE_ParVector par_b, HYPRE_ParVector par_x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix parcsr_A, HYPRE_ParVector par_b, HYPRE_ParVector par_x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGGetNumIterations(HYPRE_Solver solver, out int num_iterations); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGGetFinalRelativeResidualNorm(HYPRE_Solver solver, out double final_res_norm); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetCoarsenType(HYPRE_Solver precond, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetMaxIter(HYPRE_Solver precond, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetILUType(HYPRE_Solver solver, + HYPRE_Int ilu_type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetILULevel(HYPRE_Solver solver, + HYPRE_Int ilu_lfil); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetILUMaxRowNnz(HYPRE_Solver solver, + HYPRE_Int ilu_max_row_nnz); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetILUMaxIter(HYPRE_Solver solver, + HYPRE_Int ilu_max_iter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetILUDroptol(HYPRE_Solver solver, + HYPRE_Real ilu_droptol); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetRestriction(HYPRE_Solver solver, + HYPRE_Int restr_par); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetIsTriangular(HYPRE_Solver solver, + HYPRE_Int is_triangular); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetGMRESSwitchR(HYPRE_Solver solver, + HYPRE_Int gmres_switch); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetADropTol(HYPRE_Solver solver, + HYPRE_Real A_drop_tol); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetADropType(HYPRE_Solver solver, + HYPRE_Int A_drop_type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BoomerAMGSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + #endregion + + #region ILU + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUCreate(out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetMaxIter(HYPRE_Solver solver, HYPRE_Int max_iter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetTol(HYPRE_Solver solver, HYPRE_Real tol); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetLevelOfFill(HYPRE_Solver solver, HYPRE_Int lfil); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetMaxNnzPerRow(HYPRE_Solver solver, HYPRE_Int nzmax); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetDropThreshold(HYPRE_Solver solver, HYPRE_Real threshold); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetDropThresholdArray(HYPRE_Solver solver, HYPRE_Real[] threshold); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetNSHDropThreshold(HYPRE_Solver solver, HYPRE_Real threshold); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetNSHDropThresholdArray(HYPRE_Solver solver, HYPRE_Real[] threshold); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetSchurMaxIter(HYPRE_Solver solver, HYPRE_Int ss_max_iter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetType(HYPRE_Solver solver, HYPRE_Int ilu_type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetLocalReordering(HYPRE_Solver solver, HYPRE_Int reordering_type); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetPrintLevel(HYPRE_Solver solver, HYPRE_Int print_level); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUSetLogging(HYPRE_Solver solver, HYPRE_Int logging); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ILUGetNumIterations(HYPRE_Solver solver, out HYPRE_Int num_iterations); + + #endregion + + #region ParaSails + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsCreate(int comm, out HYPRE_Solver precond); + + /** + * Set up the ParaSails preconditioner. This function should be passed + * to the iterative solver \e SetPrecond function. + * + * @param solver [IN] Preconditioner object to set up. + * @param A [IN] ParCSR matrix used to construct the preconditioner. + * @param b Ignored by this function. + * @param x Ignored by this function. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + /** + * Apply the ParaSails preconditioner. This function should be passed + * to the iterative solver \e SetPrecond function. + * + * @param solver [IN] Preconditioner object to apply. + * @param A Ignored by this function. + * @param b [IN] Vector to precondition. + * @param x [OUT] Preconditioned vector. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsSetParams(HYPRE_Solver precond, double sai_threshold, int sai_max_levels); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsSetFilter(HYPRE_Solver precond, double sai_filter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsSetSym(HYPRE_Solver precond, int sai_sym); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsSetLogging(HYPRE_Solver precond, int v); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParaSailsDestroy(HYPRE_Solver precond); + + #endregion + + #region PCG + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRPCGCreate(int comm, out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRPCGDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRPCGSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix parcsr_A, + HYPRE_ParVector par_b, + HYPRE_ParVector par_x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRPCGSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix parcsr_A, + HYPRE_ParVector par_b, + HYPRE_ParVector par_x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRPCGSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #region GMRES + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRGMRESCreate(int comm, + out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRGMRESDestroy(HYPRE_Solver solver); + + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRGMRESSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRGMRESSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRGMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #region COGMRES + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCOGMRESCreate(int comm, + out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCOGMRESDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCOGMRESSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCOGMRESSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCOGMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #region FlexGMRES + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRFlexGMRESCreate(int comm, out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRFlexGMRESDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRFlexGMRESSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix parcsr_A, + HYPRE_ParVector par_b, + HYPRE_ParVector par_x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRFlexGMRESSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix parcsr_A, + HYPRE_ParVector par_b, + HYPRE_ParVector par_x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRFlexGMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #region LGMRES + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRLGMRESCreate(int comm, + out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRLGMRESDestroy(HYPRE_Solver solver); + + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRLGMRESSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRLGMRESSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRLGMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #region BiCGSTAB + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRBiCGSTABCreate(int comm, out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRBiCGSTABDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRBiCGSTABSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRBiCGSTABSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRBiCGSTABSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #region Hybrid + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRHybridCreate(out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRHybridDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRHybridSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRHybridSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRHybridSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #region CGNR + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCGNRCreate(int comm, out HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCGNRDestroy(HYPRE_Solver solver); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCGNRSetup(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCGNRSolve(HYPRE_Solver solver, + HYPRE_ParCSRMatrix A, + HYPRE_ParVector b, + HYPRE_ParVector x); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_ParCSRCGNRSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precondT, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + #endregion + + #endregion + + #region HYPRE_krylov.h + + #region PCG Solver + + /** + * Prepare to solve the system. The coefficient data in \e b and \e x is + * ignored here, but information about the layout of the data may be used. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetup(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * Solve the system. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSolve(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * (Optional) Set the relative convergence tolerance. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetTol(HYPRE_Solver solver, + HYPRE_Real tol); + + /** + * (Optional) Set the absolute convergence tolerance (default is + * 0). If one desires the convergence test to check the absolute + * convergence tolerance \e only, then set the relative convergence + * tolerance to 0.0. (The default convergence test is \f$ \leq\f$ + * max(relative\f$\_\f$tolerance\f$^{2} \ast \f$, absolute\f$\_\f$tolerance\f$^2\f$).) + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetAbsoluteTol(HYPRE_Solver solver, + HYPRE_Real a_tol); + + /** + * (Optional) Set a residual-based convergence tolerance which checks if + * \f$\|r_{old}-r_{new}\| < rtol \|b\|\f$. This is useful when trying to converge to + * very low relative and/or absolute tolerances, in order to bail-out before + * roundoff errors affect the approximation. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetResidualTol(HYPRE_Solver solver, + HYPRE_Real rtol); + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetAbsoluteTolFactor(HYPRE_Solver solver, + HYPRE_Real abstolf); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetConvergenceFactorTol(HYPRE_Solver solver, + HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetStopCrit(HYPRE_Solver solver, + HYPRE_Int stop_crit); + + /** + * (Optional) Set maximum number of iterations. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetMaxIter(HYPRE_Solver solver, + HYPRE_Int max_iter); + + /** + * (Optional) Use the two-norm in stopping criteria. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetTwoNorm(HYPRE_Solver solver, + HYPRE_Int two_norm); + + /** + * (Optional) Additionally require that the relative difference in + * successive iterates be small. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetRelChange(HYPRE_Solver solver, + HYPRE_Int rel_change); + + /** + * (Optional) Recompute the residual at the end to double-check convergence. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetRecomputeResidual(HYPRE_Solver solver, + HYPRE_Int recompute_residual); + + /** + * (Optional) Periodically recompute the residual while iterating. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetRecomputeResidualP(HYPRE_Solver solver, + HYPRE_Int recompute_residual_p); + + /** + * (Optional) Set the preconditioner to use. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + /** + * (Optional) Set the amount of logging to do. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + /** + * (Optional) Set the amount of printing to do to the screen. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGSetPrintLevel(HYPRE_Solver solver, + HYPRE_Int level); + + /** + * Return the number of iterations taken. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetNumIterations(HYPRE_Solver solver, + out HYPRE_Int num_iterations); + + /** + * Return the norm of the final relative residual. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetFinalRelativeResidualNorm(HYPRE_Solver solver, + out HYPRE_Real norm); + + /** + * Return the residual. + **/ + //public static extern HYPRE_Int HYPRE_PCGGetResidual(HYPRE_Solver solver, + // void* residual); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetTol(HYPRE_Solver solver, + out HYPRE_Real tol); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetResidualTol(HYPRE_Solver solver, + out HYPRE_Real rtol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetAbsoluteTolFactor(HYPRE_Solver solver, + out HYPRE_Real abstolf); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetConvergenceFactorTol(HYPRE_Solver solver, + out HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetStopCrit(HYPRE_Solver solver, + out HYPRE_Int stop_crit); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetMaxIter(HYPRE_Solver solver, + out HYPRE_Int max_iter); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetTwoNorm(HYPRE_Solver solver, + out HYPRE_Int two_norm); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetRelChange(HYPRE_Solver solver, + out HYPRE_Int rel_change); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetSkipRealResidualCheck(HYPRE_Solver solver, + out HYPRE_Int skip_real_r_check); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetPrecond(HYPRE_Solver solver, + out HYPRE_Solver precond_data_ptr); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetLogging(HYPRE_Solver solver, + out HYPRE_Int level); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetPrintLevel(HYPRE_Solver solver, + out HYPRE_Int level); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_PCGGetConverged(HYPRE_Solver solver, + out HYPRE_Int converged); + + #endregion + + #region GMRES Solver + + /** + * Prepare to solve the system. The coefficient data in \e b and \e x is + * ignored here, but information about the layout of the data may be used. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetup(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * Solve the system. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSolve(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * (Optional) Set the relative convergence tolerance. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetTol(HYPRE_Solver solver, + HYPRE_Real tol); + + /** + * (Optional) Set the absolute convergence tolerance (default is 0). + * If one desires + * the convergence test to check the absolute convergence tolerance \e only, then + * set the relative convergence tolerance to 0.0. (The convergence test is + * \f$\|r\| \leq\f$ max(relative\f$\_\f$tolerance\f$\ast \|b\|\f$, absolute\f$\_\f$tolerance).) + * + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetAbsoluteTol(HYPRE_Solver solver, + HYPRE_Real a_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetConvergenceFactorTol(HYPRE_Solver solver, + HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetStopCrit(HYPRE_Solver solver, + HYPRE_Int stop_crit); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetMinIter(HYPRE_Solver solver, + HYPRE_Int min_iter); + + /** + * (Optional) Set maximum number of iterations. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetMaxIter(HYPRE_Solver solver, + HYPRE_Int max_iter); + + /** + * (Optional) Set the maximum size of the Krylov space. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetKDim(HYPRE_Solver solver, + HYPRE_Int k_dim); + + /** + * (Optional) Additionally require that the relative difference in + * successive iterates be small. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetRelChange(HYPRE_Solver solver, + HYPRE_Int rel_change); + + /** + * (Optional) By default, hypre checks for convergence by evaluating the actual + * residual before returnig from GMRES (with restart if the true residual does + * not indicate convergence). This option allows users to skip the evaluation + * and the check of the actual residual for badly conditioned problems where + * restart is not expected to be beneficial. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetSkipRealResidualCheck(HYPRE_Solver solver, + HYPRE_Int skip_real_r_check); + + /** + * (Optional) Set the preconditioner to use. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + /** + * (Optional) Set the amount of logging to do. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + /** + * (Optional) Set the amount of printing to do to the screen. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESSetPrintLevel(HYPRE_Solver solver, + HYPRE_Int level); + + /** + * Return the number of iterations taken. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetNumIterations(HYPRE_Solver solver, + out HYPRE_Int num_iterations); + + /** + * Return the norm of the final relative residual. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetFinalRelativeResidualNorm(HYPRE_Solver solver, + out HYPRE_Real norm); + + /** + * Return the residual. + **/ + //public static extern HYPRE_Int HYPRE_GMRESGetResidual(HYPRE_Solver solver, + // void* residual); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetTol(HYPRE_Solver solver, + out HYPRE_Real tol); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetAbsoluteTol(HYPRE_Solver solver, + out HYPRE_Real tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetConvergenceFactorTol(HYPRE_Solver solver, + out HYPRE_Real cf_tol); + + /* + * OBSOLETE + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetStopCrit(HYPRE_Solver solver, + out HYPRE_Int stop_crit); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetMinIter(HYPRE_Solver solver, + out HYPRE_Int min_iter); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetMaxIter(HYPRE_Solver solver, + out HYPRE_Int max_iter); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetKDim(HYPRE_Solver solver, + out HYPRE_Int k_dim); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetRelChange(HYPRE_Solver solver, + out HYPRE_Int rel_change); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetPrecond(HYPRE_Solver solver, + out HYPRE_Solver precond_data_ptr); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetLogging(HYPRE_Solver solver, + out HYPRE_Int level); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetPrintLevel(HYPRE_Solver solver, + out HYPRE_Int level); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_GMRESGetConverged(HYPRE_Solver solver, + out HYPRE_Int converged); + + #endregion + + #region FlexGMRES Solver + + /** + * Prepare to solve the system. The coefficient data in \e b and \e x is + * ignored here, but information about the layout of the data may be used. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetup(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * Solve the system. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSolve(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * (Optional) Set the convergence tolerance. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetTol(HYPRE_Solver solver, + HYPRE_Real tol); + + /** + * (Optional) Set the absolute convergence tolerance (default is 0). + * If one desires + * the convergence test to check the absolute convergence tolerance \e only, then + * set the relative convergence tolerance to 0.0. (The convergence test is + * \f$\|r\| \leq\f$ max(relative\f$\_\f$tolerance\f$\ast \|b\|\f$, absolute\f$\_\f$tolerance).) + * + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetAbsoluteTol(HYPRE_Solver solver, + HYPRE_Real a_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetConvergenceFactorTol(HYPRE_Solver solver, HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetMinIter(HYPRE_Solver solver, HYPRE_Int min_iter); + + /** + * (Optional) Set maximum number of iterations. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetMaxIter(HYPRE_Solver solver, + HYPRE_Int max_iter); + + /** + * (Optional) Set the maximum size of the Krylov space. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetKDim(HYPRE_Solver solver, + HYPRE_Int k_dim); + + /** + * (Optional) Set the preconditioner to use. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + /** + * (Optional) Set the amount of logging to do. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + /** + * (Optional) Set the amount of printing to do to the screen. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetPrintLevel(HYPRE_Solver solver, + HYPRE_Int level); + + /** + * Return the number of iterations taken. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetNumIterations(HYPRE_Solver solver, + out HYPRE_Int num_iterations); + + /** + * Return the norm of the final relative residual. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetFinalRelativeResidualNorm(HYPRE_Solver solver, + out HYPRE_Real norm); + + /** + * Return the residual. + **/ + //public static extern HYPRE_Int HYPRE_FlexGMRESGetResidual(HYPRE_Solver solver, + // void* residual); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetTol(HYPRE_Solver solver, + out HYPRE_Real tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetConvergenceFactorTol(HYPRE_Solver solver, + out HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetStopCrit(HYPRE_Solver solver, + out HYPRE_Int stop_crit); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetMinIter(HYPRE_Solver solver, + out HYPRE_Int min_iter); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetMaxIter(HYPRE_Solver solver, + out HYPRE_Int max_iter); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetKDim(HYPRE_Solver solver, + out HYPRE_Int k_dim); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetPrecond(HYPRE_Solver solver, + out HYPRE_Solver precond_data_ptr); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetLogging(HYPRE_Solver solver, + out HYPRE_Int level); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetPrintLevel(HYPRE_Solver solver, + out HYPRE_Int level); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESGetConverged(HYPRE_Solver solver, + out HYPRE_Int converged); + + /** + * (Optional) Set a user-defined function to modify solve-time preconditioner + * attributes. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_FlexGMRESSetModifyPC(HYPRE_Solver solver, + HYPRE_PtrToModifyPCFcn modify_pc); + + #endregion + + #region LGMRES Solver + + /** + * Prepare to solve the system. The coefficient data in \e b and \e x is + * ignored here, but information about the layout of the data may be used. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetup(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * Solve the system. Details on LGMRES may be found in A. H. Baker, + * E.R. Jessup, and T.A. Manteuffel, "A technique for accelerating the + * convergence of restarted GMRES." SIAM Journal on Matrix Analysis and + * Applications, 26 (2005), pp. 962-984. LGMRES(m,k) in the paper + * corresponds to LGMRES(Kdim+AugDim, AugDim). + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSolve(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * (Optional) Set the convergence tolerance. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetTol(HYPRE_Solver solver, + HYPRE_Real tol); + /** + * (Optional) Set the absolute convergence tolerance (default is 0). + * If one desires + * the convergence test to check the absolute convergence tolerance \e only, then + * set the relative convergence tolerance to 0.0. (The convergence test is + * \f$\|r\| \leq\f$ max(relative\f$\_\f$tolerance\f$\ast \|b\|\f$, absolute\f$\_\f$tolerance).) + * + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetAbsoluteTol(HYPRE_Solver solver, + HYPRE_Real a_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetConvergenceFactorTol(HYPRE_Solver solver, + HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetMinIter(HYPRE_Solver solver, + HYPRE_Int min_iter); + + /** + * (Optional) Set maximum number of iterations. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetMaxIter(HYPRE_Solver solver, + HYPRE_Int max_iter); + + /** + * (Optional) Set the maximum size of the approximation space + * (includes the augmentation vectors). + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetKDim(HYPRE_Solver solver, + HYPRE_Int k_dim); + + /** + * (Optional) Set the number of augmentation vectors (default: 2). + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetAugDim(HYPRE_Solver solver, + HYPRE_Int aug_dim); + + /** + * (Optional) Set the preconditioner to use. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + /** + * (Optional) Set the amount of logging to do. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + /** + * (Optional) Set the amount of printing to do to the screen. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESSetPrintLevel(HYPRE_Solver solver, + HYPRE_Int level); + + /** + * Return the number of iterations taken. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetNumIterations(HYPRE_Solver solver, + out HYPRE_Int num_iterations); + + /** + * Return the norm of the final relative residual. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetFinalRelativeResidualNorm(HYPRE_Solver solver, + out HYPRE_Real norm); + + /** + * Return the residual. + **/ + //public static extern HYPRE_Int HYPRE_LGMRESGetResidual(HYPRE_Solver solver, + // void* residual); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetTol(HYPRE_Solver solver, + out HYPRE_Real tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetConvergenceFactorTol(HYPRE_Solver solver, + out HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetStopCrit(HYPRE_Solver solver, + out HYPRE_Int stop_crit); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetMinIter(HYPRE_Solver solver, + out HYPRE_Int min_iter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetMaxIter(HYPRE_Solver solver, + out HYPRE_Int max_iter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetKDim(HYPRE_Solver solver, + out HYPRE_Int k_dim); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetAugDim(HYPRE_Solver solver, + out HYPRE_Int k_dim); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetPrecond(HYPRE_Solver solver, + out HYPRE_Solver precond_data_ptr); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetLogging(HYPRE_Solver solver, + out HYPRE_Int level); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetPrintLevel(HYPRE_Solver solver, + out HYPRE_Int level); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_LGMRESGetConverged(HYPRE_Solver solver, + out HYPRE_Int converged); + + #endregion + + #region COGMRES Solver + + /** + * Prepare to solve the system. The coefficient data in \e b and \e x is + * ignored here, but information about the layout of the data may be used. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetup(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * Solve the system. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSolve(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * (Optional) Set the convergence tolerance. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetTol(HYPRE_Solver solver, + HYPRE_Real tol); + + /** + * (Optional) Set the absolute convergence tolerance (default is 0). + * If one desires + * the convergence test to check the absolute convergence tolerance \e only, then + * set the relative convergence tolerance to 0.0. (The convergence test is + * \f$\|r\| \leq\f$ max(relative\f$\_\f$tolerance\f$\ast \|b\|\f$, absolute\f$\_\f$tolerance).) + * + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetAbsoluteTol(HYPRE_Solver solver, + HYPRE_Real a_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetConvergenceFactorTol(HYPRE_Solver solver, + HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetMinIter(HYPRE_Solver solver, + HYPRE_Int min_iter); + + /** + * (Optional) Set maximum number of iterations. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetMaxIter(HYPRE_Solver solver, + HYPRE_Int max_iter); + + /** + * (Optional) Set the maximum size of the Krylov space. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetKDim(HYPRE_Solver solver, + HYPRE_Int k_dim); + + /** + * (Optional) Set number of unrolling in mass funcyions in COGMRES + * Can be 4 or 8. Default: no unrolling. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetUnroll(HYPRE_Solver solver, + HYPRE_Int unroll); + + /** + * (Optional) Set the number of orthogonalizations in COGMRES (at most 2). + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetCGS(HYPRE_Solver solver, + HYPRE_Int cgs); + + /** + * (Optional) Set the preconditioner to use. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + /** + * (Optional) Set the amount of logging to do. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + /** + * (Optional) Set the amount of printing to do to the screen. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetPrintLevel(HYPRE_Solver solver, + HYPRE_Int level); + + /** + * Return the number of iterations taken. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetNumIterations(HYPRE_Solver solver, + out HYPRE_Int num_iterations); + + /** + * Return the norm of the final relative residual. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetFinalRelativeResidualNorm(HYPRE_Solver solver, + out HYPRE_Real norm); + + /** + * Return the residual. + **/ + //public static extern HYPRE_Int HYPRE_COGMRESGetResidual(HYPRE_Solver solver, + // void* residual); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetTol(HYPRE_Solver solver, + out HYPRE_Real tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetConvergenceFactorTol(HYPRE_Solver solver, + out HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetMinIter(HYPRE_Solver solver, + out HYPRE_Int min_iter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetMaxIter(HYPRE_Solver solver, + out HYPRE_Int max_iter); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetKDim(HYPRE_Solver solver, + out HYPRE_Int k_dim); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetUnroll(HYPRE_Solver solver, + out HYPRE_Int unroll); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetCGS(HYPRE_Solver solver, + out HYPRE_Int cgs); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetPrecond(HYPRE_Solver solver, + out HYPRE_Solver precond_data_ptr); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetLogging(HYPRE_Solver solver, + out HYPRE_Int level); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetPrintLevel(HYPRE_Solver solver, + out HYPRE_Int level); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESGetConverged(HYPRE_Solver solver, + out HYPRE_Int converged); + + /** + * (Optional) Set a user-defined function to modify solve-time preconditioner + * attributes. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_COGMRESSetModifyPC(HYPRE_Solver solver, + HYPRE_PtrToModifyPCFcn modify_pc); + + #endregion + + #region BiCGSTAB Solver + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABDestroy(HYPRE_Solver solver); + + /** + * Prepare to solve the system. The coefficient data in \e b and \e x is + * ignored here, but information about the layout of the data may be used. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetup(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * Solve the system. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSolve(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * (Optional) Set the convergence tolerance. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetTol(HYPRE_Solver solver, + HYPRE_Real tol); + + /** + * (Optional) Set the absolute convergence tolerance (default is 0). + * If one desires + * the convergence test to check the absolute convergence tolerance \e only, then + * set the relative convergence tolerance to 0.0. (The convergence test is + * \f$\|r\| \leq\f$ max(relative\f$\_\f$tolerance \f$\ast \|b\|\f$, absolute\f$\_\f$tolerance).) + * + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetAbsoluteTol(HYPRE_Solver solver, + HYPRE_Real a_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetConvergenceFactorTol(HYPRE_Solver solver, + HYPRE_Real cf_tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetStopCrit(HYPRE_Solver solver, + HYPRE_Int stop_crit); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetMinIter(HYPRE_Solver solver, + HYPRE_Int min_iter); + + /** + * (Optional) Set maximum number of iterations. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetMaxIter(HYPRE_Solver solver, + HYPRE_Int max_iter); + + /** + * (Optional) Set the preconditioner to use. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + /** + * (Optional) Set the amount of logging to do. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + /** + * (Optional) Set the amount of printing to do to the screen. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABSetPrintLevel(HYPRE_Solver solver, + HYPRE_Int level); + + /** + * Return the number of iterations taken. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABGetNumIterations(HYPRE_Solver solver, + out HYPRE_Int num_iterations); + + /** + * Return the norm of the final relative residual. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABGetFinalRelativeResidualNorm(HYPRE_Solver solver, + out HYPRE_Real norm); + + /** + * Return the residual. + **/ + //public static extern HYPRE_Int HYPRE_BiCGSTABGetResidual(HYPRE_Solver solver, + // void* residual); + + /** + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_BiCGSTABGetPrecond(HYPRE_Solver solver, + out HYPRE_Solver precond_data_ptr); + + #endregion + + #region CGNR Solver + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRDestroy(HYPRE_Solver solver); + + /** + * Prepare to solve the system. The coefficient data in \e b and \e x is + * ignored here, but information about the layout of the data may be used. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSetup(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * Solve the system. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSolve(HYPRE_Solver solver, + HYPRE_Matrix A, + HYPRE_Vector b, + HYPRE_Vector x); + + /** + * (Optional) Set the convergence tolerance. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSetTol(HYPRE_Solver solver, + HYPRE_Real tol); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSetStopCrit(HYPRE_Solver solver, + HYPRE_Int stop_crit); + + /* + * RE-VISIT + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSetMinIter(HYPRE_Solver solver, + HYPRE_Int min_iter); + + /** + * (Optional) Set maximum number of iterations. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSetMaxIter(HYPRE_Solver solver, + HYPRE_Int max_iter); + + /** + * (Optional) Set the preconditioner to use. + * Note that the only preconditioner available in hypre for use with + * CGNR is currently BoomerAMG. It requires to use Jacobi as + * a smoother without CF smoothing, i.e. relax_type needs to be set to 0 + * or 7 and relax_order needs to be set to 0 by the user, since these + * are not default values. It can be used with a relaxation weight for + * Jacobi, which can significantly improve convergence. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSetPrecond(HYPRE_Solver solver, + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precondT, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver); + + /** + * (Optional) Set the amount of logging to do. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRSetLogging(HYPRE_Solver solver, + HYPRE_Int logging); + + + /** + * Return the number of iterations taken. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRGetNumIterations(HYPRE_Solver solver, + out HYPRE_Int num_iterations); + + /** + * Return the norm of the final relative residual. + **/ + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRGetFinalRelativeResidualNorm(HYPRE_Solver solver, + out HYPRE_Real norm); + + [DllImport(HYPRE_DLL, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern HYPRE_Int HYPRE_CGNRGetPrecond(HYPRE_Solver solver, + out HYPRE_Solver precond_data_ptr); + + #endregion + + #endregion + } +} diff --git a/CSparse.Interop/Interop/Hypre/PCG.cs b/CSparse.Interop/Interop/Hypre/PCG.cs new file mode 100644 index 0000000..bf0a70b --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/PCG.cs @@ -0,0 +1,83 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class PCG : HypreSolver + where T : struct, IEquatable, IFormattable + { + public PCG() + { + NativeMethods.HYPRE_ParCSRPCGCreate(Constants.MPI_COMM_WORLD, out solver); + } + + public PCG(IHyprePreconditioner precond) + : this() + { + precond.Bind(this); + } + + internal override void SetPreconditioner( + HYPRE_PtrToParSolverFcn precond, + HYPRE_PtrToParSolverFcn precond_setup, + HYPRE_Solver precond_solver) + { + NativeMethods.HYPRE_ParCSRPCGSetPrecond(solver, precond, precond_setup, precond_solver); + } + + //HYPRE_PCGSetAbsoluteTol + //HYPRE_PCGSetResidualTol + //-HYPRE_PCGSetAbsoluteTolFactor + //-HYPRE_PCGSetConvergenceFactorTol + //-HYPRE_PCGSetStopCrit + //HYPRE_PCGSetRelChange + //HYPRE_PCGSetRecomputeResidual + //HYPRE_PCGSetRecomputeResidualP + + public void SetTol(double tol) + { + NativeMethods.HYPRE_PCGSetTol(solver, tol); + } + + public void SetTwoNorm(int two_norm) + { + NativeMethods.HYPRE_PCGSetTwoNorm(solver, two_norm); + } + + public void SetMaxIter(int max_iter) + { + NativeMethods.HYPRE_PCGSetMaxIter(solver, max_iter); + } + + public override HypreResult Solve(HypreMatrix A, HypreVector x, HypreVector b) + { + NativeMethods.HYPRE_PCGSetLogging(solver, Logging); + NativeMethods.HYPRE_PCGSetPrintLevel(solver, PrintLevel); + + var par_A = A.GetObject(); + var par_b = b.GetObject(); + var par_x = x.GetObject(); + + NativeMethods.HYPRE_ParCSRPCGSetup(solver, par_A, par_b, par_x); + NativeMethods.HYPRE_ParCSRPCGSolve(solver, par_A, par_b, par_x); + + x.Synchronize(); + + HypreResult result; + + NativeMethods.HYPRE_PCGGetNumIterations(solver, out result.NumIterations); + NativeMethods.HYPRE_PCGGetConverged(solver, out result.Converged); + NativeMethods.HYPRE_PCGGetFinalRelativeResidualNorm(solver, out result.RelResidualNorm); + + return result; + } + + protected override void Dispose(bool disposing) + { + if (solver.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParCSRPCGDestroy(solver); + solver.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/ParaSails.cs b/CSparse.Interop/Interop/Hypre/ParaSails.cs new file mode 100644 index 0000000..c333396 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/ParaSails.cs @@ -0,0 +1,41 @@ +using System; + +namespace CSparse.Interop.Hypre +{ + public class ParaSails : IHyprePreconditioner + where T : struct, IEquatable, IFormattable + { + protected HYPRE_Solver precond; + + public ParaSails(bool symmetric) + { + NativeMethods.HYPRE_ParaSailsCreate(Constants.MPI_COMM_WORLD, out precond); + + NativeMethods.HYPRE_ParaSailsSetSym(precond, symmetric ? 1 : 0); + } + + public void SetParams(double threshold, int max_levels) + { + NativeMethods.HYPRE_ParaSailsSetParams(precond, threshold, max_levels); + } + + public void SetFilter(double filter) + { + NativeMethods.HYPRE_ParaSailsSetFilter(precond, filter); + } + + public void Bind(HypreSolver solver) + { + solver.SetPreconditioner(NativeMethods.HYPRE_ParaSailsSolve, NativeMethods.HYPRE_ParaSailsSetup, precond); + } + + public void Dispose() + { + if (precond.Ptr != IntPtr.Zero) + { + NativeMethods.HYPRE_ParaSailsDestroy(precond); + precond.Ptr = IntPtr.Zero; + } + } + } +} diff --git a/CSparse.Interop/Interop/Hypre/Types.cs b/CSparse.Interop/Interop/Hypre/Types.cs new file mode 100644 index 0000000..4d9b862 --- /dev/null +++ b/CSparse.Interop/Interop/Hypre/Types.cs @@ -0,0 +1,30 @@ + +namespace CSparse.Interop.Hypre +{ + using System; + + public struct HYPRE_ParCSRMatrix + { + public IntPtr Ptr; + } + + public struct HYPRE_ParVector + { + public IntPtr Ptr; + } + + public struct HYPRE_IJMatrix + { + public IntPtr Ptr; + } + + public struct HYPRE_IJVector + { + public IntPtr Ptr; + } + + public struct HYPRE_Solver + { + public IntPtr Ptr; + } +} From 618638b004fac1ac86e15d62fc5bfcad4a8f39d2 Mon Sep 17 00:00:00 2001 From: wo80 Date: Wed, 19 Mar 2025 21:51:30 +0100 Subject: [PATCH 2/2] Add HYPRE example. --- .../Examples/Double/TestHypre.cs | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 CSparse.Benchmark/Examples/Double/TestHypre.cs diff --git a/CSparse.Benchmark/Examples/Double/TestHypre.cs b/CSparse.Benchmark/Examples/Double/TestHypre.cs new file mode 100644 index 0000000..7f4e76a --- /dev/null +++ b/CSparse.Benchmark/Examples/Double/TestHypre.cs @@ -0,0 +1,157 @@ + +namespace CSparse.Double.Examples +{ + using System; + using CSparse.Interop.Hypre; + + static class TestHypre + { + public static void Run() + { + NativeMethods.HYPRE_Init(); + + int n = 33; + var h = 1.0 / (n + 1); + + var A = CSparse.Double.Generate.Laplacian(n, n); + var b = Vector.Create(A.RowCount, h * h); + + using (var hypreA = new HypreMatrix(A, true)) + { + Check(TestAMG(hypreA, b), "AMG"); + Check(TestPCG(hypreA, b), "PCG"); + Check(TestPCG_AMG(hypreA, b), "PCG + AMG"); + Check(TestPCG_ParaSails(hypreA, b), "PCG + ParaSails"); + Check(TestFlexGMRES_AMG(hypreA, b), "FlexGMRES + AMG"); + } + + NativeMethods.HYPRE_Finalize(); + } + + private static void Check(HypreResult result, string name) + { + Console.WriteLine(name); + Console.WriteLine(" Iterations = {0}", result.NumIterations); + Console.WriteLine(" Final Relative Residual Norm = {0}", result.RelResidualNorm); + Console.WriteLine(); + } + + private static HypreResult TestAMG(HypreMatrix A, double[] _b) + { + var _x = Vector.Create(A.RowCount, 0.0); + + using var x = new HypreVector(_x); + using var b = new HypreVector(_b); + + using var solver = new BoomerAMG(); + + solver.SetOldDefault(); // Falgout coarsening with modified classical interpolation + solver.SetRelaxType(3); // G-S/Jacobi hybrid relaxation + solver.SetRelaxOrder(1); // uses C/F relaxation + solver.SetNumSweeps(1); // Sweeps on each level + solver.SetMaxLevels(20); + solver.SetTol(1e-7); + //solver.PrintLevel = 3; + + return solver.Solve(A, x, b); + } + + private static HypreResult TestPCG(HypreMatrix A, double[] _b) + { + var _x = Vector.Create(A.RowCount, 0.0); + + using var x = new HypreVector(_x); + using var b = new HypreVector(_b); + + using var solver = new PCG(); + + solver.SetMaxIter(1000); + solver.SetTol(1e-7); + solver.SetTwoNorm(1); // use the two norm as the stopping criteria + //solver.PrintLevel = 2; + //solver.Logging = 1; + + return solver.Solve(A, x, b); + } + + private static HypreResult TestPCG_AMG(HypreMatrix A, double[] _b) + { + var _x = Vector.Create(A.RowCount, 0.0); + + using var x = new HypreVector(_x); + using var b = new HypreVector(_b); + + using var precond = new BoomerAMG(); + + //precond.PrintLevel = 1; + precond.SetCoarsenType(6); + precond.SetOldDefault(); + precond.SetRelaxType(6); // Sym G.S./Jacobi hybrid + precond.SetNumSweeps(1); + precond.SetTol(0.0); + precond.SetMaxIter(1); // do only one iteration! + + using var solver = new PCG(precond); + + solver.SetMaxIter(1000); + solver.SetTol(1e-7); + solver.SetTwoNorm(1); // use the two norm as the stopping criteria + //solver.PrintLevel = 2; + //solver.Logging = 1; + + return solver.Solve(A, x, b); + } + + private static HypreResult TestPCG_ParaSails(HypreMatrix A, double[] _b) + { + var _x = Vector.Create(A.RowCount, 0.0); + + using var x = new HypreVector(_x); + using var b = new HypreVector(_b); + + using var precond = new ParaSails(true); + + precond.SetParams(0.1, 1); + precond.SetFilter(0.05); + //precond.Logging = 3; + + using var solver = new PCG(precond); + + solver.SetMaxIter(1000); + solver.SetTol(1e-7); + solver.SetTwoNorm(1); // use the two norm as the stopping criteria + //solver.PrintLevel = 2; + //solver.Logging = 1; + + return solver.Solve(A, x, b); + } + + private static HypreResult TestFlexGMRES_AMG(HypreMatrix A, double[] _b) + { + var _x = Vector.Create(A.RowCount, 0.0); + + using var x = new HypreVector(_x); + using var b = new HypreVector(_b); + + using var precond = new BoomerAMG(); + + //precond.PrintLevel = 1; + precond.SetCoarsenType(6); + precond.SetOldDefault(); + precond.SetRelaxType(6); // Sym G.S./Jacobi hybrid + precond.SetNumSweeps(1); + precond.SetTol(0.0); // conv. tolerance zero + precond.SetMaxIter(1); // do only one iteration! + + using var solver = new FlexGMRES(precond); + + solver.SetKDim(30); + solver.SetMaxIter(1000); + solver.SetTol(1e-7); + //solver.PrintLevel = 2; + //solver.Logging = 1; + + return solver.Solve(A, x, b); + } + } +} \ No newline at end of file