/// <summary> /// copies /// </summary> /// <typeparam name="vectype"></typeparam> /// <param name="vec"></param> public void GetValues <vectype>(vectype vec) where vectype : IList <double> { int Nupdate = m_VectorPartition.LocalLength; int i0 = (int)m_VectorPartition.i0; int nvalues = Math.Min(1024, Nupdate); int[] indices = new int[nvalues]; double[] values = new double[nvalues]; for (int i = 0; i < Nupdate; i += nvalues) { if (i + nvalues > Nupdate) { nvalues = Nupdate - i; } for (int ii = 0; ii < nvalues; ii++) { indices[ii] = i + ii + i0; } HypreException.Check(Wrappers.IJVector.GetValues(m_IJVector, nvalues, indices, values)); for (int ii = 0; ii < nvalues; ii++) { vec[i + ii] = values[ii]; } } }
/// <summary> /// general matrix/vector product; see <see cref="ISparseMatrix.SpMV"/>; /// </summary> /// <typeparam name="VectorType1"></typeparam> /// <typeparam name="VectorType2"></typeparam> /// <param name="alpha"></param> /// <param name="a"></param> /// <param name="beta"></param> /// <param name="acc"></param> public void SpMV <VectorType1, VectorType2>(double alpha, VectorType1 a, double beta, VectorType2 acc) where VectorType1 : System.Collections.Generic.IList <double> where VectorType2 : System.Collections.Generic.IList <double> { if (a.Count < ColPartition.LocalLength) { throw new ArgumentException("length/count of 'a' must be equal to local length of column partition", "a"); } if (acc.Count < RowPartitioning.LocalLength) { throw new ArgumentException("length/count of 'acc' must be greater or equal to local length of row partition", "acc"); } if (object.ReferenceEquals(a, acc)) { throw new ArgumentException("in-place computation is not supported.", "a,acc"); } IJVector _acc = new IJVector(RowPartitioning); if (beta != 0.0) { _acc.SetValues(acc); } IJVector _a = new IJVector(ColPartition); _a.SetValues(a); HypreException.Check(Wrappers.ParCSRMatrix.ParCSRMatrixMatvec(alpha, m_ParCSR_matrix, _a.ParCRS_vector, beta, _acc.ParCRS_vector)); _acc.GetValues(acc); _acc.Dispose(); _a.Dispose(); }
/// <summary> /// calls the PCG solver /// </summary> /// <param name="Converged">true if converged</param> /// <param name="NoOfIter">no of iterations done by solver</param> /// <param name="Unknowns"></param> /// <param name="Rhs"></param> protected override void CallSolver(out int NoOfIter, out bool Converged, IJVector Unknowns, IJVector Rhs) { if (m_Solver.p == IntPtr.Zero) { throw new ApplicationException("solver not initialized"); } HypreException.Check(Wrappers.PCG.Setup(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector)); Wrappers.PCG.Solve(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector); // We don't want to raise an exception for // a 'method did not converge'- or 'numerical breakdown' - Error // that may occur in HYPRE Wrappers.Utilities.HYPRE_ClearAllErrors(); int Con; HypreException.Check(Wrappers.PCG.GetConverged(m_Solver, out Con)); if (Con != 0) { Converged = true; } else { Converged = false; } HypreException.Check(Wrappers.PCG.GetNumIterations(m_Solver, out NoOfIter)); }
/// <summary> /// see <see cref="IMutableMatrix.SetValues"/> /// </summary> public void SetValues(int RowIndex, int[] ColumnIndices, double[] newValues) { if (RowIndex < this.RowPartitioning.i0 || RowIndex >= (this.RowPartitioning.i0 + this.RowPartitioning.LocalLength)) { throw new ArgumentOutOfRangeException("RowIndex", "row index not within local range"); } HypreException.Check(Wrappers.IJMatrix.SetValues(m_IJMatrix, 1, new int[] { ColumnIndices.Length }, new int[] { RowIndex }, ColumnIndices, newValues)); }
/// <summary> /// destroys the HYPRE object, if not allready done; /// </summary> public override void Dispose() { if (m_Solver.p != IntPtr.Zero) { HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGDestroy(m_Solver)); m_Solver.p = IntPtr.Zero; } base.Dispose(); }
/// <summary> /// /// </summary> protected override void CreateSolver() { HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGCreate(out m_Solver)); if (m_Solver.p == IntPtr.Zero) { throw new ApplicationException("Solver initialization failed"); } PrintLevel = 0; }
/// <summary> /// destroy the hypre objects, if not allready done /// </summary> public void Dispose() { if (m_IJVector.p != IntPtr.Zero) { HypreException.Check(Wrappers.IJVector.Destroy(m_IJVector)); m_IJVector.p = IntPtr.Zero; ParCRS_vector.p = IntPtr.Zero; } }
/// <summary> /// destroys the HYPRE object, if not already done; /// </summary> public override void Dispose() { if (m_Solver.p != IntPtr.Zero) { HypreException.Check(Wrappers.ParCSRGMRES.Destroy(m_Solver)); m_Solver.p = IntPtr.Zero; } base.Dispose(); }
/// <summary> /// destroys the native ParaSails object /// </summary> public override void Dispose() { base.Dispose(); if (m_Solver.p != IntPtr.Zero) { HypreException.Check(Wrappers.ParaSails.HYPRE_ParaSailsDestroy(m_Solver)); m_Solver.p = IntPtr.Zero; } }
/// <summary> /// constructs and initializes a new HYPRE_IJVector object /// </summary> /// <param name="partition">distribution of the vector over MPI processes</param> public IJVector(IPartitioning partition) { if (partition.IsMutable) { throw new NotSupportedException(); } if (partition.TotalLength > (int.MaxValue - 2)) { throw new ApplicationException("unable to create HYPRE vector: no. of matrix rows is larger than HYPRE index type (32 bit signed int);"); } m_VectorPartition = partition; int jLower = (int)partition.i0; int jUpper = (int)partition.i0 + partition.LocalLength - 1; MPI_Comm comm = csMPI.Raw._COMM.WORLD; int Nupdate = partition.LocalLength; // create object HypreException.Check(Wrappers.IJVector.Create(comm, jLower, jUpper, out m_IJVector)); HypreException.Check(Wrappers.IJVector.SetObjectType(m_IJVector, Wrappers.Constants.HYPRE_PARCSR)); HypreException.Check(Wrappers.IJVector.Initialize(m_IJVector)); // set values int nvalues = Math.Min(1024, Nupdate); int[] indices = new int[nvalues]; double[] values = new double[nvalues]; int i0 = (int)m_VectorPartition.i0; for (int i = 0; i < Nupdate; i += nvalues) { if (i + nvalues > Nupdate) { nvalues = Nupdate - i; } for (int ii = 0; ii < nvalues; ii++) { indices[ii] = i + ii + i0; //if (vec == null) // values[ii] = mapping[i_ii]; //else // values[ii] = vec[i_ii]; } HypreException.Check(Wrappers.IJVector.SetValues(m_IJVector, nvalues, indices, values)); } // assable HypreException.Check(Wrappers.IJVector.Assemble(m_IJVector)); HypreException.Check(Wrappers.IJVector.GetObject(m_IJVector, out ParCRS_vector)); }
/// <summary> /// set/get this property /// </summary> /// <param name="level"></param> /// <returns></returns> public RelaxType this[CycleLevel level] { get { int k = (int)level; int rt; HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGGetCycleRelaxType(m_Solver, out rt, k)); return((RelaxType)rt); } set { int k = (int)level; int rt = (int)value; HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGSetCycleRelaxType(m_Solver, rt, k)); } }
/// <summary> /// see <see cref="IMutableMatrix.GetValues"/> /// </summary> public double[] GetValues(int RowIndex, int[] ColumnIndices) { if (RowIndex < this.RowPartitioning.i0 || RowIndex >= (this.RowPartitioning.i0 + this.RowPartitioning.LocalLength)) { throw new ArgumentOutOfRangeException("RowIndex", "row index not within local range"); } double[] ret = new double[ColumnIndices.Length]; HypreException.Check(Wrappers.IJMatrix.GetValues(m_IJMatrix, 1, new int[] { ColumnIndices.Length }, new int[] { RowIndex }, ColumnIndices, ret)); return(ret); }
/// <summary> /// destroys the hypre PCG solver object, and the nested preconditioner, /// if not allready done; /// </summary> public override void Dispose() { if (m_Solver.p != IntPtr.Zero) { IDisposable pc = m_NestedPrecond as IDisposable; if (pc != null) { pc.Dispose(); } HypreException.Check(Wrappers.ParCSRPCG.Destroy(m_Solver)); m_Solver.p = IntPtr.Zero; } base.Dispose(); }
/// <summary> /// returns the diagonal element in the <paramref name="row"/>-th row. /// </summary> /// <param name="row">global row/column index</param> /// <returns>value of diagonal element</returns> public double GetDiagonalElement(int row) { if (row < m_RowPartition.i0 || row >= (m_RowPartition.i0 + m_RowPartition.LocalLength)) { throw new IndexOutOfRangeException("row index is not assigned to current processor."); } int[] ncols = new int[] { 1 }; int[] rows = new int[] { row }; int[] cols = new int[] { row }; double[] ret = new double[1]; HypreException.Check(Wrappers.IJMatrix.GetValues(m_IJMatrix, 1, ncols, rows, cols, ret)); return(ret[0]); }
/// <summary> /// set/get this property /// </summary> /// <param name="level"></param> /// <returns></returns> public int this[CycleNumSweepsLevels level] { get { int num_sweeps; HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGGetCycleNumSweeps(m_solver, out num_sweeps, (int)level)); return(num_sweeps); } set { if (value < 0) { throw new ArgumentException("Positive Integers only are allowed"); } int num_sweeps = value; HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGSetCycleNumSweeps(m_solver, num_sweeps, (int)level)); } }
/// <summary> /// see <see cref="Solver.CallSolver"/> /// </summary> /// <remarks> /// ParaSails should be used only as aa implicit preconditioner, this method /// exists only for reasons of compability and completeness. /// </remarks> protected override void CallSolver(out int NoOfIter, out bool Converged, IJVector Unknowns, IJVector Rhs) { if (m_Solver.p == IntPtr.Zero) { throw new ApplicationException("solver not initialized"); } HypreException.Check(Wrappers.ParaSails.__HYPRE_ParaSailsSetup(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector)); Wrappers.ParaSails.__HYPRE_ParaSailsSolve(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector); // We dont want to raise an exception for // a 'method did not converge'- or 'nomerical breakdown' - Error // that may occur in HYPRE Wrappers.Utilities.HYPRE_ClearAllErrors(); NoOfIter = 1; Converged = true; }
/// <summary> /// (Optional) Defines the outer relaxation weight for hybrid /// SOR or SSOR on the user defined level. Note that the finest level is denoted 0, /// the next coarser level 1, etc. For nonpositive omega, an outer relaxation weight is /// determined with at most k CG steps on each level /// (this only makes sense for symmetric positive definite problems and smoothers, e.g. SSOR). /// The default is 1; /// </summary> /// <param name="level"></param> /// <returns></returns> public double this[int level] { get { if (level < 0 || level >= NumLevels) { throw new IndexOutOfRangeException(); } double val; HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGGetLevelOuterWt(m_solver, out val, level)); return(val); } set { if (level < 0 || level >= NumLevels) { throw new IndexOutOfRangeException(); } HypreException.Check(Wrappers.BoomerAMG.HYPRE_BoomerAMGSetLevelOuterWt(m_solver, value, level)); } }
/// <summary> /// sets the diagonal element in the <paramref name="row"/>-th row /// to value <paramref name="val"/> /// </summary> /// <param name="row">global row/column index</param> /// <param name="val">new value of diagonal element</param> public void SetDiagonalElement(int row, double val) { if (row < m_RowPartition.i0 || row >= (m_RowPartition.i0 + m_RowPartition.LocalLength)) { throw new IndexOutOfRangeException("row index is not assigned to current processor."); } int[] ncols = new int[] { 1 }; int[] rows = new int[] { row }; int[] cols = new int[] { row }; double[] _val = new double[] { val }; HypreException.Check(Wrappers.IJMatrix.SetValues(m_IJMatrix, 1, ncols, rows, cols, _val)); //// test code: //double vchk = GetDiagElement(row); //if (vchk != val) // throw new ApplicationException(); }
/// <summary> /// create GMRES solver object /// </summary> protected override void CreateSolver() { HypreException.Check(Wrappers.ParCSRGMRES.CreateGMRES(csMPI.Raw._COMM.WORLD, out m_Solver)); PrintLevel = 0; }
/// <summary> /// creates solver for MPI_COMM_WORLD communicator /// </summary> protected override void CreateSolver() { HypreException.Check(Wrappers.Euclid.Create(csMPI.Raw._COMM.WORLD, out base.m_Solver)); }
/// <summary> /// creates the native HYPRE object /// </summary> protected override void CreateSolver() { HypreException.Check(Wrappers.ParaSails.HYPRE_ParaSailsCreate(MPI.Wrappers.csMPI.Raw._COMM.WORLD, out base.m_Solver)); }
/// <summary> /// creates the PCG solver object /// </summary> protected override void CreateSolver() { HypreException.Check(Wrappers.ParCSRPCG.Create(csMPI.Raw._COMM.WORLD, out m_Solver)); }
/// <summary> /// initializes this matrix to be a copy of <paramref name="mtx"/>; /// </summary> /// <param name="mtx"></param> public IJMatrix(IMutableMatrixEx mtx) { if (mtx.RowPartitioning.MPI_Comm != mtx.ColPartition.MPI_Comm) { throw new ArgumentException(); } if (mtx.RowPartitioning.IsMutable) { throw new ArgumentException(); } if (mtx.ColPartition.IsMutable) { throw new ArgumentException(); } m_RowPartition = mtx.RowPartitioning; m_ColPartition = mtx.ColPartition; if (mtx.NoOfRows != mtx.NoOfCols) { throw new ArgumentException("matrix must be quadratic.", "mtx"); } if (mtx.NoOfRows > (int.MaxValue - 2)) { throw new ApplicationException("unable to create HYPRE matrix: no. of matrix rows is larger than HYPRE index type (32 bit signed int);"); } if (mtx.NoOfCols > (int.MaxValue - 2)) { throw new ApplicationException("unable to create HYPRE matrix: no. of matrix columns is larger than HYPRE index type (32 bit signed int);"); } // matrix: init MPI_Comm comm = csMPI.Raw._COMM.WORLD; int ilower = (int)mtx.RowPartitioning.i0; int iupper = (int)ilower + mtx.RowPartitioning.LocalLength - 1; int jlower = (int)mtx.ColPartition.i0; int jupper = (int)jlower + mtx.ColPartition.LocalLength - 1; HypreException.Check(Wrappers.IJMatrix.Create(comm, ilower, iupper, jlower, jupper, out m_IJMatrix)); HypreException.Check(Wrappers.IJMatrix.SetObjectType(m_IJMatrix, Wrappers.Constants.HYPRE_PARCSR)); HypreException.Check(Wrappers.IJMatrix.Initialize(m_IJMatrix)); // matrix: set values, row by row ... int nrows, lmax = mtx.GetMaxNoOfNonZerosPerRow(); int[] rows = new int[1], cols = new int[lmax], ncols = new int[1]; double[] values = new double[lmax]; int LR; int[] col = null; double[] val = null; for (int i = 0; i < mtx.RowPartitioning.LocalLength; i++) { int iRowGlob = i + mtx.RowPartitioning.i0; LR = mtx.GetRow(iRowGlob, ref col, ref val); nrows = 1; rows[0] = iRowGlob; ncols[0] = LR; int cnt = 0; for (int j = 0; j < LR; j++) { if (val[j] != 0.0) { cols[cnt] = col[j]; values[cnt] = val[j]; cnt++; } } if (cnt <= 0) { throw new ArgumentException(string.Format("Zero matrix row detected (local row index: {0}, global row index: {1}).", i, iRowGlob)); } HypreException.Check(Wrappers.IJMatrix.SetValues(m_IJMatrix, nrows, ncols, rows, cols, values)); } // matrix: assembly HypreException.Check(Wrappers.IJMatrix.Assemble(m_IJMatrix)); HypreException.Check(Wrappers.IJMatrix.GetObject(m_IJMatrix, out m_ParCSR_matrix)); }