protected virtual void DelComputeOperatorMatrix(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping Mapping, DGField[] CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double phystime) { OpAffine.ClearEntries(); bool Eval = false; if (OpMatrix == null) { Eval = true; OpMatrix = new BlockMsrMatrix(uResidual.Mapping, u.Mapping); } else { OpMatrix.Clear(); } //Op.ComputeMatrixEx(base.LsTrk, // u.Mapping, null, uResidual.Mapping, // OpMatrix, OpAffine, false, // phystime, // false, // base.LsTrk.SpeciesIdS.ToArray()); XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, u.Mapping, null, uResidual.Mapping); mtxBuilder.CellLengthScales.AddRange(AgglomeratedCellLengthScales); mtxBuilder.time = phystime; mtxBuilder.ComputeMatrix(OpMatrix, OpAffine); if (Eval) { OpMatrix.SpMV(1.0, new CoordinateVector(CurrentState), 1.0, OpAffine); } }
public static void CellwiseSubSelection( [Values(SelectionType.all_combined, SelectionType.degrees, SelectionType.species, SelectionType.variables)] SelectionType SType ) { Utils.TestInit((int)SType); Console.WriteLine("SubSelection({0})", SType); //Arrange --- extracts entries of matrix according to hardcoded selection int DGdegree = 2; int GridResolution = 4; var mgo = Utils.CreateTestMGOperator(XDGusage.all, DGdegree, MatrixShape.full_var_spec, GridResolution); int sampleCellA = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, false); //1 species int sampleCellB = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, true); //2 species BlockMsrMatrix compA = Utils.GetCellCompMatrix(SType, mgo, sampleCellA); BlockMsrMatrix compB = Utils.GetCellCompMatrix(SType, mgo, sampleCellB); int iBlock = sampleCellB + mgo.Mapping.AggGrid.CellPartitioning.i0; int i0 = mgo.Mapping.GetBlockI0(iBlock); var block = MultidimensionalArray.Create(mgo.Mapping.GetBlockLen(iBlock), mgo.Mapping.GetBlockLen(iBlock)); mgo.OperatorMatrix.ReadBlock(i0, i0, block); //Arrange --- setup masking, which correspond to hardcoded SubBlockSelector sbsA = new SubBlockSelector(mgo.Mapping); sbsA.GetDefaultSelection(SType, sampleCellA); // single spec BlockMask maskA = new BlockMask(sbsA, null); SubBlockSelector sbsB = new SubBlockSelector(mgo.Mapping); sbsB.GetDefaultSelection(SType, sampleCellB); // double spec BlockMask maskB = new BlockMask(sbsB, null); //Arrange --- some time measurement Stopwatch stw = new Stopwatch(); stw.Reset(); //Act --- subblock extraction stw.Start(); var blocksA = maskA.GetDiagonalBlocks(mgo.OperatorMatrix, false, false); var blocksB = maskB.GetDiagonalBlocks(mgo.OperatorMatrix, false, false); stw.Stop(); //Assert --- Assert.IsTrue(blocksA.Length == 1); Assert.IsTrue(blocksB.Length == 1); Assert.IsTrue(compA.RowPartitioning.LocalLength == blocksA[0].GetLength(0)); Assert.IsTrue(compB.RowPartitioning.LocalLength == blocksB[0].GetLength(0)); //Assert --- compare masking of single spec cell Debug.Assert(compA.InfNorm() != 0.0); compA.AccBlock(0, 0, -1.0, blocksA[0]); Assert.IsTrue(compA.InfNorm() == 0.0); //Assert --- compare masking of double spec cell Debug.Assert(compB.InfNorm() != 0.0); compB.AccBlock(0, 0, -1.0, blocksB[0]); Assert.IsTrue(compB.InfNorm() == 0.0, String.Format("proc{0}: not fulfilled at block {1}", mgo.Mapping.MpiRank, sampleCellB)); }
public int Bandwidth(double[] currentX) { int beta; int dim = currentX.Length; int full_bandwidth_row; BlockMsrMatrix OpMatrix = CurrentLin.OperatorMatrix; double[] b = new double[dim]; for (int j = 0; j < dim; j++) { for (int i = dim - 1; i >= 0; i--) { if (OpMatrix[j, i] != 0) { b[j] = i - j; break; } } } beta = (int)b.Max(); full_bandwidth_row = b.FirstIndexWhere(c => c == beta); return(beta); }
/// <summary> /// Constructor for XDG solvers /// </summary> public OpAnalysisBase(LevelSetTracker LsTrk, BlockMsrMatrix Mtx, double[] RHS, UnsetteledCoordinateMapping Mapping, MultiphaseCellAgglomerator CurrentAgglomeration, BlockMsrMatrix _mass, IEnumerable <MultigridOperator.ChangeOfBasisConfig[]> OpConfig, ISpatialOperator abstractOperator) { int RHSlen = Mapping.TotalLength; m_map = Mapping; // mapping VarGroup = Mapping.BasisS.Count.ForLoop(i => i); //default: all dependent variables are included in operator matrix m_LsTrk = LsTrk; m_OpMtx = Mtx.CloneAs(); localRHS = RHS.CloneAs(); // create the Dummy XDG aggregation basis var baseGrid = Mapping.GridDat; var mgSeq = Foundation.Grid.Aggregation.CoarseningAlgorithms.CreateSequence(baseGrid, 1); AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(mgSeq, Mapping.BasisS); // XAggB.UpdateXdgAggregationBasis(CurrentAgglomeration); // create multigrid operator m_MultigridOp = new MultigridOperator(XAggB, Mapping, m_OpMtx, _mass, OpConfig, abstractOperator.DomainVar.Select(varName => abstractOperator.FreeMeanValue[varName]).ToArray()); }
public static void SetAll(this BlockMsrMatrix A, double val) { var rowmap = A._RowPartitioning; var colmap = A._ColPartitioning; int RowBlocks = rowmap.LocalNoOfBlocks; int ColBlocks = colmap.LocalNoOfBlocks; Partitioning rowpart = new Partitioning(RowBlocks); for (int iBlock = rowpart.i0; iBlock < rowpart.iE; iBlock++) { for (int jBlock = rowpart.i0; jBlock < rowpart.iE; jBlock++) { int i0 = rowmap.GetBlockI0(iBlock); int j0 = colmap.GetBlockI0(jBlock); int iL = rowmap.GetBlockLen(iBlock); int jL = colmap.GetBlockLen(jBlock); var subM = MultidimensionalArray.Create(iL, jL); subM.SetAll(val); A.AccBlock(i0, j0, 1.0, subM); } } double min, max; int minc, minr, maxc, maxr; A.GetMinimumAndMaximum_MPILocal(out min, out minr, out minc, out max, out maxr, out maxc); Debug.Assert(min == max); Debug.Assert(min == val); }
public static BlockMsrMatrix CreateShapeOfOnes(BlockMsrMatrix A) { var rowmap = A._RowPartitioning; var colmap = A._ColPartitioning; int RowBlocks = rowmap.LocalNoOfBlocks; int ColBlocks = colmap.LocalNoOfBlocks; BlockMsrMatrix B = new BlockMsrMatrix(rowmap, colmap); Partitioning rowpart = new Partitioning(RowBlocks); for (int iBlock = rowpart.i0; iBlock < rowpart.iE; iBlock++) { for (int jBlock = rowpart.i0; jBlock < rowpart.iE; jBlock++) { int i0 = rowmap.GetBlockI0(iBlock); int j0 = colmap.GetBlockI0(jBlock); int iL = rowmap.GetBlockLen(iBlock); int jL = colmap.GetBlockLen(jBlock); var subM = MultidimensionalArray.Create(iL, jL); A.ReadBlock(i0, j0, subM); subM.ApplyAll(i => i != 0.0 ? 1 : 0); B.AccBlock(i0, j0, 1.0, subM); } } double min, max; int minc, minr, maxc, maxr; B.GetMinimumAndMaximum_MPILocal(out min, out minr, out minc, out max, out maxr, out maxc); Debug.Assert(min == 0); Debug.Assert(max == 1); return(B); }
/// <summary> /// Reload of some operator after before grid-redistribution. /// </summary> /// <param name="Mtx_new"> /// Output, matrix which should be restored. /// </param> /// <param name="Reference"> /// Unique string reference under which data has been stored before grid-redistribution. /// </param> /// <param name="RowMapping"> /// Coordinate mapping to correlate the matrix rows with cells of the computational grid. /// </param> /// <param name="ColMapping"> /// Coordinate mapping to correlate the matrix columns with cells of the computational grid. /// </param> public void RestoreMatrix(BlockMsrMatrix Mtx_new, string Reference, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping) { int J = m_NewGrid.iLogicalCells.NoOfLocalUpdatedCells; CheckMatrix(Mtx_new, RowMapping, ColMapping, J); BlockMsrMatrix Mtx_old = m_Matrices[Reference].Item3; int[] RowHash = GetDGBasisHash(RowMapping.BasisS); int[] ColHash = GetDGBasisHash(ColMapping.BasisS); if (!ArrayTools.AreEqual(RowHash, m_Matrices[Reference].Item1)) { throw new ApplicationException(); } if (!ArrayTools.AreEqual(ColHash, m_Matrices[Reference].Item2)) { throw new ApplicationException(); } BlockMsrMatrix P_Row = GetRowPermutationMatrix(Mtx_new, Mtx_old, RowHash); BlockMsrMatrix P_Col = GetColPermutationMatrix(Mtx_new, Mtx_old, ColHash); Debug.Assert(Mtx_new._RowPartitioning.LocalNoOfBlocks == m_newJ); Debug.Assert(Mtx_new._ColPartitioning.LocalNoOfBlocks == m_newJ); Debug.Assert(Mtx_old._RowPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(Mtx_old._ColPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(P_Row._RowPartitioning.LocalNoOfBlocks == m_newJ); Debug.Assert(P_Row._ColPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(P_Col._RowPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(P_Col._ColPartitioning.LocalNoOfBlocks == m_newJ); BlockMsrMatrix.Multiply(Mtx_new, BlockMsrMatrix.Multiply(P_Row, Mtx_old), P_Col); }
/* * /// <summary> * /// base matrix assembly * /// </summary> * /// <typeparam name="T"></typeparam> * /// <param name="OpMatrix"></param> * /// <param name="OpAffine"></param> * /// <param name="RowMapping"></param> * /// <param name="ColMapping"></param> * /// <param name="CurrentState"></param> * /// <param name="ParamsMap"></param> * /// <param name="AgglomeratedCellLengthScales"></param> * /// <param name="time"></param> * public void AssembleMatrix<T>(BlockMsrMatrix OpMatrix, double[] OpAffine, * UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, * IEnumerable<T> CurrentState, IList<DGField> ParamsMap, Dictionary<SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, * double time) where T : DGField { * * // checks * if(ColMapping.BasisS.Count != m_XOp.DomainVar.Count) * throw new ArgumentException(); * if(RowMapping.BasisS.Count != m_XOp.CodomainVar.Count) * throw new ArgumentException(); * if(OpMatrix == null && CurrentState == null) * throw new ArgumentException(); * * SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); * if(!m_XOp.Species.SetEquals(SpcToCompute.Select(spcId => LsTrk.GetSpeciesName(spcId)))) { * throw new ArgumentException("mismatch between species of operator and length scales."); * } * * if(OpMatrix != null) { * * XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = m_XOp.GetMatrixBuilder(LsTrk, ColMapping, ParamsMap, RowMapping); * * foreach(var kv in AgglomeratedCellLengthScales) { * mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; * } * * mtxBuilder.time = time; * * mtxBuilder.ComputeMatrix(OpMatrix, OpAffine); * * } else { * XSpatialOperatorMk2.XEvaluatorNonlin eval = m_XOp.GetEvaluatorEx(this.LsTrk, * CurrentState.ToArray(), ParamsMap, RowMapping); * * foreach(var kv in AgglomeratedCellLengthScales) { * eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; * } * * eval.time = time; * * eval.Evaluate(1.0, 1.0, OpAffine); * * } * } */ public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time) where T : DGField { AssembleMatrix(OpMatrix, OpAffine, RowMapping, ColMapping, CurrentState, AgglomeratedCellLengthScales, time); }
public BlockMsrMatrix freebandeddiffjac(CoordinateVector SolutionVec, double[] currentX, double[] f0) { int n = currentX.Length; BlockMsrMatrix jac = new BlockMsrMatrix(SolutionVec.Mapping); int beta = Bandwidth(currentX); int number_Cells = n / beta; var temp = new double[n]; for (int k = 0; k < beta; k++) { var zz = new double[n]; for (int i = 0; i < number_Cells; i++) { zz[i * beta + k] = 1; } temp = dirder(SolutionVec, currentX, zz, f0); for (int i = 0; i < number_Cells; i++) { for (int j = i * beta + k; j < (i + 1) * beta; j++) { jac[j, i *beta + k] = temp[j]; } } } return(jac); }
private static void CheckMatrix(BlockMsrMatrix M, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, int J) { if (M._RowPartitioning.LocalNoOfBlocks != J) { throw new ArgumentException("Number of column blocks must be equal to number of cells."); } if (M._ColPartitioning.LocalNoOfBlocks != J) { throw new ArgumentException("Number of column blocks must be equal to number of cells."); } if (!M._RowPartitioning.EqualsPartition(RowMapping)) { throw new ArgumentException("Mapping must match partitioning."); } if (!M._ColPartitioning.EqualsPartition(ColMapping)) { throw new ArgumentException("Mapping must match partitioning."); } if (!M._RowPartitioning.AllBlockSizesEqual) { throw new NotSupportedException("Only mappings with constant frame blocks are supported."); } if (!M._ColPartitioning.AllBlockSizesEqual) { throw new NotSupportedException("Only mappings with constant frame blocks are supported."); } }
/// <summary> /// Discards all saved mass matrices /// </summary> /// <param name="value"></param> public void OnNext(LevelSetTracker.LevelSetRegions value) { //this.baseFactory = null; this.nonAgglomeratedMassMatrix = null; this.massMatrix = null; this.inverseMassMatrix = null; }
/// <summary> /// returns all external rows of <paramref name="M"/> /// corresponding to ghost cells of <paramref name="map"/>, /// which are located on other Mpi-ranks. /// </summary> /// <param name="map">Multigrid mapping</param> /// <param name="M">matrix distributed according to <paramref name="map"/></param> /// <returns></returns> public static BlockMsrMatrix GetAllExternalRows(MultigridMapping map, BlockMsrMatrix M) { var extcells = map.AggGrid.iLogicalCells.NoOfExternalCells.ForLoop(i => i + map.LocalNoOfBlocks); var SBS = new SubBlockSelector(map); SBS.CellSelector(extcells, false); var AllExtMask = new BlockMaskExt(SBS, 0); var ExternalRows_BlockI0 = AllExtMask.GetAllSubMatrixCellOffsets(); var ExternalRows_BlockN = AllExtMask.GetAllSubMatrixCellLength(); var ExternalRowsIndices = AllExtMask.m_GlobalMask; BlockPartitioning PermRow = new BlockPartitioning(ExternalRowsIndices.Count, ExternalRows_BlockI0, ExternalRows_BlockN, M.MPI_Comm, i0isLocal: true); BlockMsrMatrix Perm = new BlockMsrMatrix(PermRow, M._RowPartitioning); for (int iRow = 0; iRow < ExternalRowsIndices.Count; iRow++) { Debug.Assert(M._RowPartitioning.IsInLocalRange(ExternalRowsIndices[iRow]) == false); Perm[iRow + PermRow.i0, ExternalRowsIndices[iRow]] = 1; } #if TEST Perm.SaveToTextFileSparseDebug("Perm"); #endif return(BlockMsrMatrix.Multiply(Perm, M)); }
/// <summary> /// Get SubMatrix corresponding to this <see cref="BlockMask"/>. /// With the ignore flags, coupling blocks can be left out (e.g. blocks containing level-set). /// If <paramref name="ignoreCellCoupling"/> is set true, only diagonal blocks are concidered. /// Probably slower than <see cref="GetSubBlockMatrix(BlockMsrMatrix)"/>. /// </summary> /// <param name="source">matrix to apply masking to</param> /// <param name="ignoreCellCoupling">flag to ignore cell coupling</param> /// <param name="ignoreVarCoupling">flag to ignore variable coupling</param> /// <param name="ignoreSpecCoupling">flag to ignore species coupling</param> /// <returns>sub block matrix</returns> public BlockMsrMatrix GetSubBlockMatrix(BlockMsrMatrix source, bool ignoreCellCoupling, bool ignoreVarCoupling, bool ignoreSpecCoupling) { if (ignoreCellCoupling && m_includeExternalCells) { throw new NotImplementedException("Coupling of internal and external block is not concidered"); } BlockMsrMatrix submatrix = null; if (m_includeExternalCells) { BlockPartitioning extBlocking = new BlockPartitioning(BMLoc.LocalDOF + BMExt.LocalDOF, SubMatrixOffsets, SubMatrixLen, csMPI.Raw._COMM.SELF); submatrix = new BlockMsrMatrix(extBlocking); var ExtRowsTmp = m_ExtRows; AuxGetSubBlockMatrix(submatrix, source, BMLoc, ignoreCellCoupling, ignoreVarCoupling, ignoreSpecCoupling); AuxGetSubBlockMatrix(submatrix, ExtRowsTmp, BMExt, ignoreCellCoupling, ignoreVarCoupling, ignoreSpecCoupling); } else { int Loclength = BMLoc.LocalDOF; var tmpN = BMLoc.GetAllSubMatrixCellLength(); var tmpi0 = BMLoc.GetAllSubMatrixCellOffsets(); BlockPartitioning localBlocking = new BlockPartitioning(Loclength, tmpi0.ToArray(), tmpN.ToArray(), csMPI.Raw._COMM.SELF, i0isLocal: true); submatrix = new BlockMsrMatrix(localBlocking); AuxGetSubBlockMatrix(submatrix, source, BMLoc, ignoreCellCoupling, ignoreVarCoupling, ignoreSpecCoupling); } Debug.Assert(submatrix != null); return(submatrix); }
public static void GetExternalRowsTest( [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg, [Values(2)] int DGOrder, [Values(4)] int Res) { //Matlabaufruf --> gesamte Matrix nach Matlab schreiben //Teilmatritzen gemäß Globalid extrahieren //Mit ExternalRows vergleichen //Die große Frage: funktioniert der batchmode connector parallel? Beim rausschreiben beachten Utils.TestInit((int)UseXdg, DGOrder); Console.WriteLine("GetExternalRowsTest({0},{1})", UseXdg, DGOrder); //Arrange --- setup mgo and mask MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MatrixShape.laplace, Res); MultigridMapping map = mgo.Mapping; BlockMsrMatrix M = mgo.OperatorMatrix; //Delete this plz ... //M.SaveToTextFileSparse("M"); //int[] A = Utils.GimmeAllBlocksWithSpec(map, 9); //int[] B = Utils.GimmeAllBlocksWithSpec(map, 18); //if (map.MpiRank == 0) { // A.SaveToTextFileDebug("ACells"); // B.SaveToTextFileDebug("BCells"); //} var selector = new SubBlockSelector(map); var dummy = new BlockMsrMatrix(map); // we are only interested in getting indices, so a dummy is sufficient var mask = new BlockMask(selector, dummy); //Arrange --- get stuff to put into matlab int[] GlobalIdx_ext = Utils.GetAllExtCellIdc(map); double[] GlobIdx = GlobalIdx_ext.Length.ForLoop(i => (double)GlobalIdx_ext[i] + 1.0); //Arrange --- get external rows by mask BlockMsrMatrix extrows = BlockMask.GetAllExternalRows(mgo.Mapping, mgo.OperatorMatrix); //Assert --- idc and rows of extrows have to be the same Assert.IsTrue(GlobIdx.Length == extrows._RowPartitioning.LocalLength); //Arrange --- get external rows by matlab var infNorm = MultidimensionalArray.Create(1, 1); using (BatchmodeConnector matlab = new BatchmodeConnector()) { //note: BatchmodeCon maybe working on proc0 but savetotxt file, etc. (I/O) is full mpi parallel //so concider this as full mpi-parallel matlab.PutSparseMatrix(M, "M"); matlab.PutSparseMatrix(extrows, "M_test"); matlab.PutVector(GlobIdx, "Idx"); matlab.Cmd(String.Format("M_ext = M(Idx, :);")); matlab.Cmd("n=norm(M_test-M_ext,inf)"); matlab.GetMatrix(infNorm, "n"); matlab.Execute(); } //Assert --- test if we actually got the right Matrix corresponding to Index Assert.IsTrue(infNorm[0, 0] == 0.0); }
/// <summary> /// computes <see cref="LaplaceMtx"/> and <see cref="LaplaceAffine"/> /// </summary> private void UpdateMatrices() { using (var tr = new FuncTrace()) { // time measurement for matrix assembly Stopwatch stw = new Stopwatch(); stw.Start(); // console Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); // quadrature domain var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData, MaskType.Geometrical)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical)); #if DEBUG // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard) var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif using (new BlockTrace("SipMatrixAssembly", tr)) { LaplaceMtx = new BlockMsrMatrix(T.Mapping); LaplaceAffine = new double[T.Mapping.LocalLength]; LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, LaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); } #if DEBUG LaplaceAffine.ClearEntries(); LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, RefLaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs(); ErrMtx.Acc(-1.0, LaplaceMtx); double err = ErrMtx.InfNorm(); double infNrm = LaplaceMtx.InfNorm(); Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm); Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed."); #endif stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); //var JB = LapaceIp.GetFDJacobianBuilder(T.Mapping.Fields, null, T.Mapping, edgQrSch, volQrSch); //var JacobiMtx = new BlockMsrMatrix(T.Mapping); //var JacobiAffine = new double[T.Mapping.LocalLength]; //JB.ComputeMatrix(JacobiMtx, JacobiAffine); //double L2ErrAffine = GenericBlas.L2Dist(JacobiAffine, LaplaceAffine); //var ErrMtx2 = LaplaceMtx.CloneAs(); //ErrMtx2.Acc(-1.0, JacobiMtx); //double LinfErrMtx2 = ErrMtx2.InfNorm(); //JacobiMtx.SaveToTextFileSparse("D:\\tmp\\Jac.txt"); //LaplaceMtx.SaveToTextFileSparse("D:\\tmp\\Lap.txt"); //Console.WriteLine("FD Jacobi Mtx: {0:e14}, Affine: {1:e14}", LinfErrMtx2, L2ErrAffine); } }
/// <summary> /// If you just want to get the <see cref="BlockMsrMatrix"/>, which corresponds to this <see cref="BlockMask"/>. /// This is the method to choose! In addition, MPI communicator can be defined via <paramref name="comm"/>. /// </summary> /// <returns>submatrix on <paramref name="comm"/></returns> public BlockMsrMatrix GetSubBlockMatrix(BlockMsrMatrix source, MPI_Comm comm) { if (source == null) { throw new ArgumentNullException(); } if (source.NoOfRows < BMLoc.LocalDOF) { throw new ArgumentException(); } BlockMsrMatrix target; if (m_includeExternalCells) { BlockPartitioning targetBlocking = new BlockPartitioning(BMLoc.LocalDOF + BMExt.LocalDOF, SubMatrixOffsets, SubMatrixLen, comm); //make an extended block dummy to fit local and external blocks target = new BlockMsrMatrix(targetBlocking, targetBlocking); //get the external rows via MPI exchange var ExtRowsTmp = m_ExtRows; int offset = BMLoc.m_GlobalMask.Count; var extBlockRows = BMExt.m_GlobalMask.Count.ForLoop(i => i + offset); var extBlockCols = BMExt.m_GlobalMask.Count.ForLoop(i => i + offset); //ExtRowsTmp lives at the MPI-Communicator of the target, thus the global index is related to a new partitioning and has nothing to do with the partitioning of the multigrid operator ... var GlobalIdxExtRows = BMExt.m_GlobalMask.Count.ForLoop(i => BMExt.m_LocalMask[i] - m_map.LocalLength); for (int iGlob = 0; iGlob < GlobalIdxExtRows.Count(); iGlob++) { Debug.Assert(GlobalIdxExtRows[iGlob] < ExtRowsTmp._RowPartitioning.LocalLength); GlobalIdxExtRows[iGlob] += ExtRowsTmp._RowPartitioning.i0; Debug.Assert(ExtRowsTmp._RowPartitioning.IsInLocalRange(GlobalIdxExtRows[iGlob])); } //add local Block ... source.WriteSubMatrixTo(target, BMLoc.m_GlobalMask, default(int[]), BMLoc.m_GlobalMask, default(int[])); //add columns related to external rows ... source.AccSubMatrixTo(1.0, target, BMLoc.m_GlobalMask, default(int[]), new int[0], default(int[]), BMExt.m_GlobalMask, extBlockCols); //add external rows ... ExtRowsTmp.AccSubMatrixTo(1.0, target, GlobalIdxExtRows, extBlockRows, BMLoc.m_GlobalMask, default(int[]), BMExt.m_GlobalMask, extBlockCols); } else { BlockPartitioning localBlocking = new BlockPartitioning(BMLoc.LocalDOF, SubMatrixOffsets, SubMatrixLen, csMPI.Raw._COMM.SELF, i0isLocal: true); target = new BlockMsrMatrix(localBlocking); source.AccSubMatrixTo(1.0, target, BMLoc.m_GlobalMask, default(int[]), BMLoc.m_GlobalMask, default(int[])); } Debug.Assert(target != null); return(target); }
public static void SubSelection( [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg, [Values(2)] int DGOrder, [Values(MatrixShape.full_var_spec, MatrixShape.full_spec, MatrixShape.full_var, MatrixShape.full)] MatrixShape MShape, [Values(4)] int Res) { Utils.TestInit((int)UseXdg, DGOrder, (int)MShape, Res); Console.WriteLine("SubSelection({0},{1},{2},{3})", UseXdg, DGOrder, MShape, Res); //Arrange --- create test matrix, MG mapping MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape, Res); MultigridMapping map = mgo.Mapping; BlockMsrMatrix M = mgo.OperatorMatrix; //Arrange --- get mask int[] cells = Utils.GetCellsOfOverlappingTestBlock(map); Array.Sort(cells); var sbs = new SubBlockSelector(map); sbs.CellSelector(cells, false); BlockMsrMatrix M_ext = BlockMask.GetAllExternalRows(map, M); var mask = new BlockMask(sbs, M_ext); //Arrange --- get GlobalIdxList int[] idc = Utils.GetIdcOfSubBlock(map, cells); bool[] coup = Utils.SetCoupling(MShape); var M_sub = mask.GetSubBlockMatrix(M, false, coup[0], coup[1]); var infNorm = MultidimensionalArray.Create(4, 1); int rank = map.MpiRank; using (BatchmodeConnector matlab = new BatchmodeConnector()) { double[] GlobIdx = idc.Count().ForLoop(i => (double)idc[i] + 1.0); Assert.IsTrue(GlobIdx.Length == M_sub.NoOfRows); matlab.PutSparseMatrix(M, "M"); // note: M_sub lives on Comm_Self, therefore we have to distinguish between procs ... matlab.PutSparseMatrixRankExclusive(M_sub, "M_sub"); matlab.PutVectorRankExclusive(GlobIdx, "Idx"); matlab.Cmd("M_0 = full(M(Idx_0, Idx_0));"); matlab.Cmd("M_1 = full(M(Idx_1, Idx_1));"); matlab.Cmd("M_2 = full(M(Idx_2, Idx_2));"); matlab.Cmd("M_3 = full(M(Idx_3, Idx_3));"); matlab.Cmd("n=[0; 0; 0; 0];"); matlab.Cmd("n(1,1)=norm(M_0-M_sub_0,inf);"); matlab.Cmd("n(2,1)=norm(M_1-M_sub_1,inf);"); matlab.Cmd("n(3,1)=norm(M_2-M_sub_2,inf);"); matlab.Cmd("n(4,1)=norm(M_3-M_sub_3,inf);"); matlab.GetMatrix(infNorm, "n"); matlab.Execute(); } Assert.IsTrue(infNorm[rank, 0] == 0.0); }