/// <summary> /// projects some DG field onto this /// </summary> /// <param name="alpha"></param> /// <param name="DGField"></param> public void ProjectDGFieldMaximum(double alpha, ConventionalDGField DGField) { DGField.MPIExchange(); //var multiplicity = new int[this.m_Basis.NoOfLocalNodes]; int J = m_Basis.GridDat.Cells.NoOfLocalUpdatedCells; var Trafo = m_Basis.GridDat.ChefBasis.Scaling; var C2N = m_Basis.CellNode_To_Node; var MtxN2M = m_Basis.m_Nodal2Modal; var CellData = this.Basis.GridDat.Cells; int[] _K = m_Basis.NodesPerCell; int L = m_Basis.ContainingDGBasis.Length; double[][] _NodalCoordinates = _K.Select(K => new double[K]).ToArray(); double[] ModalCoordinates = new double[L]; for (int j = 0; j < J; j++) // loop over cells... { int iKref = CellData.GetRefElementIndex(j); double[] NodalCoordinates = _NodalCoordinates[iKref]; int K = _K[iKref]; // Get DG coordinates Array.Clear(ModalCoordinates, 0, L); int Lmin = Math.Min(L, DGField.Basis.GetLength(j)); for (int l = 0; l < Lmin; l++) { ModalCoordinates[l] = DGField.Coordinates[j, l]; } // transform DGField.Coordinates.GetRow(j, ModalCoordinates); MtxN2M[iKref].gemv(alpha * Trafo[j], ModalCoordinates, 0.0, NodalCoordinates); // collect coordinates for cell 'j': for (int k = 0; k < K; k++) { int _c2n = C2N[j, k]; m_Coordinates[_c2n] = Math.Max(m_Coordinates[_c2n], NodalCoordinates[k]); } } using (var trx = new Transceiver(this.Basis)) { trx.MaxGather(m_Coordinates); trx.Scatter(m_Coordinates); } }
/// <summary> /// projects some DG field onto this /// </summary> /// <param name="alpha"></param> /// <param name="DGField"></param> public void ProjectDGFieldCheaply(double alpha, ConventionalDGField DGField) { DGField.MPIExchange(); //var multiplicity = new int[this.m_Basis.NoOfLocalNodes]; var gdat = m_Basis.GridDat; int J = gdat.Cells.NoOfLocalUpdatedCells; var Trafo = gdat.ChefBasis.Scaling; var C2N = m_Basis.CellNode_To_Node; var MtxN2M = m_Basis.m_Nodal2Modal; var CellData = gdat.Cells; int[] _K = m_Basis.NodesPerCell; int L = m_Basis.ContainingDGBasis.Length; int pDeg = m_Basis.ContainingDGBasis.Degree; double[][] _NodalCoordinates = _K.Select(K => new double[K]).ToArray(); double[] ModalCoordinates = new double[L]; double[] IntermCoordinates = new double[L]; for (int j = 0; j < J; j++) // loop over cells... { int iKref = CellData.GetRefElementIndex(j); double[] NodalCoordinates = _NodalCoordinates[iKref]; int K = _K[iKref]; // Get DG coordinates Array.Clear(ModalCoordinates, 0, L); int Lmin = Math.Min(L, DGField.Basis.GetLength(j)); for (int l = 0; l < Lmin; l++) { ModalCoordinates[l] = DGField.Coordinates[j, l]; } // transform DGField.Coordinates.GetRow(j, ModalCoordinates); if (CellData.IsCellAffineLinear(j)) { MtxN2M[iKref].GEMV(alpha * Trafo[j], ModalCoordinates, 0.0, NodalCoordinates); } else { var OnbTrafo = gdat.ChefBasis.OrthonormalizationTrafo.GetValue_Cell(j, 1, pDeg).ExtractSubArrayShallow(0, -1, -1); OnbTrafo.GEMV(alpha, ModalCoordinates, 0.0, IntermCoordinates); MtxN2M[iKref].GEMV(1.0, IntermCoordinates, 0.0, NodalCoordinates); } // collect coordinates for cell 'j': for (int k = 0; k < K; k++) { int _c2n = C2N[j, k]; m_Coordinates[_c2n] += NodalCoordinates[k]; //multiplicity[_c2n]++; } } using (var trx = new Transceiver(this.Basis)) { trx.AccumulateGather(m_Coordinates); var multiplicity = this.Basis.NodeMultiplicity; int I = this.Basis.NoOfLocalOwnedNodes; for (int i = 0; i < I; i++) { Debug.Assert(multiplicity[i] > 0); m_Coordinates[i] *= 1.0 / multiplicity[i]; } trx.Scatter(m_Coordinates); } }