private MultidimensionalArray GetBlock(BlockMsrMatrix target, bool ignoreVarCoupling, bool ignoreSpecCoupling, int iLoc, int jLoc) { var _Sblocks = MultidimensionalArray.Create(BMLoc.GetLengthOfCell(iLoc), BMLoc.GetLengthOfCell(jLoc)); for (int iVar = 0; iVar < StructuredNi0[iLoc].Length; iVar++) // loop over (row/codomain/test) variables { for (int jVar = 0; jVar < StructuredNi0[jLoc].Length; jVar++) // loop over (column/domain/trial) variables { if (ignoreVarCoupling && jVar != iVar) { continue; } for (int iSpc = 0; iSpc < StructuredNi0[iLoc][iVar].Length; iSpc++) // loop over species { for (int jSpc = 0; jSpc < StructuredNi0[jLoc][jVar].Length; jSpc++) { if (ignoreSpecCoupling && jSpc != iSpc) { continue; } for (int iMode = 0; iMode < StructuredNi0[iLoc][iVar][iSpc].Length; iMode++) { for (int jMode = 0; jMode < StructuredNi0[jLoc][jVar][jSpc].Length; jMode++) { extNi0 RowNi0 = StructuredNi0[iLoc][iVar][iSpc][iMode]; extNi0 ColNi0 = StructuredNi0[jLoc][jVar][jSpc][jMode]; int Targeti0 = RowNi0.Gi0; int Targetj0 = ColNi0.Gi0; int Subi0 = BMLoc.GetRelativeSubBlockOffset(iLoc, iVar, iSpc, iMode); int Subj0 = BMLoc.GetRelativeSubBlockOffset(jLoc, jVar, jSpc, jMode); int Subie = Subi0 + RowNi0.N - 1; int Subje = Subj0 + ColNi0.N - 1; target.ReadBlock(Targeti0, Targetj0, _Sblocks.ExtractSubArrayShallow(new int[] { Subi0, Subj0 }, new int[] { Subie, Subje })); } } } } } } return(_Sblocks); }
/// <summary> /// Get the length of a cell within this mask /// </summary> /// <param name="iCell"></param> /// <returns></returns> public int GetLengthOfCell(int iCell) { int len = 0; Debug.Assert(iCell < m_StructuredNi0.Length); for (int i = 0; i < m_StructuredNi0[iCell].Length; i++) { for (int j = 0; j < m_StructuredNi0[iCell][i].Length; j++) { for (int k = 0; k < m_StructuredNi0[iCell][i][j].Length; k++) { extNi0 block = m_StructuredNi0[iCell][i][j][k]; len += block.N; } } } return(len); }
/// <summary> /// Get the local index list of a cell within this mask /// </summary> /// <param name="iCell"></param> /// <returns></returns> public int[] GetLocalidcOfCell(int iCell) { List <int> cellidx = new List <int>(); for (int i = 0; i < m_StructuredNi0[iCell].Length; i++) { for (int j = 0; j < m_StructuredNi0[iCell][i].Length; j++) { for (int k = 0; k < m_StructuredNi0[iCell][i][j].Length; k++) { extNi0 block = m_StructuredNi0[iCell][i][j][k]; for (int m = 0; m < block.N; m++) { cellidx.Add(block.Li0 + m); } } } } int[] array = cellidx.ToArray(); Debug.Assert(array.GroupBy(x => x).Any(g => g.Count() == 1)); return(array); }
private void AuxGetSubBlockMatrix(BlockMsrMatrix target, BlockMsrMatrix source, BlockMaskBase mask, bool ignoreCellCoupling, bool ignoreVarCoupling, bool ignoreSpecCoupling) { bool IsLocalMask = mask.GetType() == typeof(BlockMaskLoc); extNi0[][][][] RowNi0s = mask.m_StructuredNi0; extNi0[][][][] ColNi0s = this.StructuredNi0; int auxIdx = 0; for (int iLoc = 0; iLoc < RowNi0s.Length; iLoc++) { for (int jLoc = 0; jLoc < ColNi0s.Length; jLoc++) { if (ignoreCellCoupling && jLoc != iLoc) { continue; } for (int iVar = 0; iVar < RowNi0s[iLoc].Length; iVar++) { for (int jVar = 0; jVar < ColNi0s[jLoc].Length; jVar++) { if (ignoreVarCoupling && jVar != iVar) { continue; } for (int iSpc = 0; iSpc < RowNi0s[iLoc][iVar].Length; iSpc++) { for (int jSpc = 0; jSpc < ColNi0s[jLoc][jVar].Length; jSpc++) { if (ignoreSpecCoupling && jSpc != iSpc) { continue; } for (int iMode = 0; iMode < RowNi0s[iLoc][iVar][iSpc].Length; iMode++) { int Trgi0 = RowNi0s[iLoc][iVar][iSpc][iMode].Si0; for (int jMode = 0; jMode < ColNi0s[jLoc][jVar][jSpc].Length; jMode++) { extNi0 RowNi0 = RowNi0s[iLoc][iVar][iSpc][iMode]; extNi0 ColNi0 = ColNi0s[jLoc][jVar][jSpc][jMode]; int Srci0 = IsLocalMask? RowNi0.Gi0: RowNi0.Li0 + source._RowPartitioning.i0 - m_map.LocalLength; int Srcj0 = ColNi0.Gi0; var tmpBlock = MultidimensionalArray.Create(RowNi0.N, ColNi0.N); int Trgj0 = ColNi0s[jLoc][jVar][jSpc][jMode].Si0; #if Debug SubMSR.ReadBlock(SubRowIdx, SubColIdx, tmpBlock); Debug.Assert(tmpBlock.Sum() == 0); Debug.Assert(tmpBlock.InfNorm() == 0); #endif try { source.ReadBlock(Srci0, Srcj0, tmpBlock); } catch (Exception e) { Console.WriteLine("row: " + Srci0); Console.WriteLine("col: " + Srcj0); throw new Exception(e.Message); } Debug.Assert(Trgi0 < target.RowPartitioning.LocalLength); Debug.Assert(Trgj0 < target.ColPartition.LocalLength); target.AccBlock(Trgi0, Trgj0, 1.0, tmpBlock); } } } } } } auxIdx++; } auxIdx++; } }
private MultidimensionalArray[] AuxGetSubBlocks(BlockMsrMatrix source, BlockMaskBase mask, bool ignoreCellCoupling, bool ignoreVarCoupling, bool ignoreSpecCoupling) { bool IsLocMask = mask.GetType() == typeof(BlockMaskLoc); // if external cells are masked, we have to consider other offsets ... int NoOfCells = mask.m_StructuredNi0.Length; int size = ignoreCellCoupling ? NoOfCells : NoOfCells * NoOfCells; MultidimensionalArray[] Sblocks = new MultidimensionalArray[size]; int auxIdx = 0; for (int iLoc = 0; iLoc < mask.m_StructuredNi0.Length; iLoc++) { for (int jLoc = 0; jLoc < mask.m_StructuredNi0.Length; jLoc++) { if (ignoreCellCoupling && jLoc != iLoc) { continue; } int CellBlockLen = mask.GetLengthOfCell(jLoc); Sblocks[auxIdx] = MultidimensionalArray.Create(CellBlockLen, CellBlockLen); for (int iVar = 0; iVar < mask.m_StructuredNi0[iLoc].Length; iVar++) { for (int jVar = 0; jVar < mask.m_StructuredNi0[jLoc].Length; jVar++) { if (ignoreVarCoupling && jVar != iVar) { continue; } for (int iSpc = 0; iSpc < mask.m_StructuredNi0[iLoc][iVar].Length; iSpc++) { for (int jSpc = 0; jSpc < mask.m_StructuredNi0[jLoc][jVar].Length; jSpc++) { if (ignoreSpecCoupling && jSpc != iSpc) { continue; } for (int iMode = 0; iMode < mask.m_StructuredNi0[iLoc][iVar][iSpc].Length; iMode++) { for (int jMode = 0; jMode < mask.m_StructuredNi0[jLoc][jVar][jSpc].Length; jMode++) { extNi0 RowNi0 = mask.m_StructuredNi0[iLoc][iVar][iSpc][iMode]; extNi0 ColNi0 = mask.m_StructuredNi0[jLoc][jVar][jSpc][jMode]; int Targeti0 = IsLocMask ? RowNi0.Gi0 : RowNi0.Li0 + source._RowPartitioning.i0 - m_map.LocalLength; int Targetj0 = ColNi0.Gi0; int Subi0 = mask.GetRelativeSubBlockOffset(iLoc, iVar, iSpc, iMode); int Subj0 = mask.GetRelativeSubBlockOffset(jLoc, jVar, jSpc, jMode); int Subie = Subi0 + RowNi0.N - 1; int Subje = Subj0 + ColNi0.N - 1; var tmp = Sblocks[auxIdx].ExtractSubArrayShallow(new int[] { Subi0, Subj0 }, new int[] { Subie, Subje }); Debug.Assert((m_map.IsInLocalRange(Targeti0) && m_map.IsInLocalRange(Targetj0) && mask.GetType() == typeof(BlockMaskLoc)) || mask.GetType() == typeof(BlockMaskExt)); try { source.ReadBlock(Targeti0, Targetj0, tmp ); } catch (Exception e) { Console.WriteLine("row: " + Targeti0); Console.WriteLine("col: " + Targetj0); throw new Exception(e.Message); } } } } } } } auxIdx++; } } return(Sblocks); }
/// <summary> /// The core of the masking /// Generates index lists and the Ni0-struct-list corresponding to mask /// and is called by the child classes: local and external mask /// Note: the smallest unit are DG sub blocks! /// </summary> protected void GenerateAllMasks() { int NoOfCells = m_NoOfCells; int NoOfVariables = m_NoOfVariables; int[][] NoOfSpecies = m_NoOfSpecies; int[] DGdegreeP1 = m_DGdegree.CloneAs(); for (int iDG = 0; iDG < DGdegreeP1.Length; iDG++) { DGdegreeP1[iDG] += 1; } List <extNi0> ListNi0 = new List <extNi0>(); List <int> Globalint = new List <int>(); List <int> Localint = new List <int>(); List <int> SubBlockIdx = new List <int>(); int SubOffset = m_SubBlockOffset; // 0 for local mask and BMLoc.LocalDof for external mask int Ni0Length = 0; int MaskLen = 0; int prevLocie = m_map.LocalNoOfBlocks; var tmpCell = new List <extNi0[][][]>(); // local caching of filter functions // ensures that functions are not re-allocated during the loops var CellInstruction = m_sbs.CellFilter; var VarInstruction = m_sbs.VariableFilter; var SpecInstruction = m_sbs.SpeciesFilter; var ModeInstruction = m_sbs.ModeFilter; bool emptysel = true; // loop over cells... for (int iLoc = 0; iLoc < NoOfCells; iLoc++) { int jLoc = m_CellOffset + iLoc; //to address correctly, external cells offset has to be concidered, you know ... emptysel &= !CellInstruction(jLoc); //for testing if the entire selection is empty, which hopefully only can happen at the level of cells if (!CellInstruction(jLoc)) { continue; } var tmpVar = new List <extNi0[][]>(); // loop over variables... for (int iVar = 0; iVar < NoOfVariables; iVar++) { if (!VarInstruction(jLoc, iVar)) { continue; } var tmpSpc = new List <extNi0[]>(); // loop over species... for (int iSpc = 0; iSpc < NoOfSpecies[iLoc][iVar]; iSpc++) { if (!SpecInstruction(jLoc, iVar, iSpc)) { continue; } int GlobalOffset = m_map.GlobalUniqueIndex(iVar, jLoc, iSpc, 0); int LocalOffset = m_map.LocalUniqueIndex(iVar, jLoc, iSpc, 0); var tmpMod = new List <extNi0>(); // loop over polynomial degrees... for (int degree = 0; degree < DGdegreeP1[iVar]; degree++) { if (ModeInstruction(jLoc, iVar, iSpc, degree)) { int GlobalModeOffset = m_Ni0[degree].i0 + GlobalOffset; int LocalModeOffset = m_Ni0[degree].i0 + LocalOffset; int ModeLength = m_Ni0[degree].N; var newNi0 = new extNi0(LocalModeOffset, GlobalModeOffset, SubOffset, ModeLength); SubOffset += ModeLength; // Fill int lists for (int i = 0; i < newNi0.N; i++) { Globalint.Add(newNi0.Gi0 + i); Localint.Add(newNi0.Li0 + i); SubBlockIdx.Add(newNi0.Si0 + i); MaskLen++; } // Fill Ni0 Lists tmpMod.Add(newNi0); Ni0Length++; ListNi0.Add(newNi0); Debug.Assert(m_map.LocalUniqueIndex(iVar, jLoc, iSpc, GetNp(degree) - 1) == LocalModeOffset + ModeLength - 1); } } if (tmpMod.Count > 0) { tmpSpc.Add(tmpMod.ToArray()); } } if (tmpSpc.Count > 0) { tmpVar.Add(tmpSpc.ToArray()); } } if (tmpVar.Count > 0) { tmpCell.Add(tmpVar.ToArray()); } } var tmpStructNi0 = tmpCell.ToArray(); int NumOfNi0 = 0; #if DEBUG for (int iCell = 0; iCell < tmpStructNi0.Length; iCell++) { for (int iVar = 0; iVar < tmpStructNi0[iCell].Length; iVar++) { for (int iSpc = 0; iSpc < tmpStructNi0[iCell][iVar].Length; iSpc++) { NumOfNi0 += tmpStructNi0[iCell][iVar][iSpc].Length; } } } #endif // an empty selection is allowed, // e.g. consider a combination of empty external and non empty local mask if (!emptysel) { Debug.Assert(ListNi0.GroupBy(x => x.Li0).Any(g => g.Count() == 1)); Debug.Assert(ListNi0.GroupBy(x => x.Gi0).Any(g => g.Count() == 1)); Debug.Assert(ListNi0.Count() == NumOfNi0); Debug.Assert(MaskLen <= m_LocalLength); Debug.Assert(Localint.GroupBy(x => x).Any(g => g.Count() == 1)); Debug.Assert(Globalint.GroupBy(x => x).Any(g => g.Count() == 1)); Debug.Assert(Localint.Count() == MaskLen); Debug.Assert(SubBlockIdx.Count() == MaskLen); Debug.Assert(SubBlockIdx.GroupBy(x => x).Any(g => g.Count() == 1)); } m_GlobalMask = Globalint; m_LocalMask = Localint; m_StructuredNi0 = tmpStructNi0; m_MaskLen = MaskLen; m_Ni0Len = Ni0Length; m_SubBlockMask = SubBlockIdx; }