/// <summary> /// % /// </summary> /// <param name="output"></param> /// <param name="input">input DG field; unchanged on </param> public void Perform(SinglePhaseField output, SinglePhaseField input) { if (!output.Basis.Equals(this.m_bOutput)) { throw new ArgumentException("output basis mismatch"); } if (!input.Basis.Equals(this.m_bInput)) { throw new ArgumentException("output basis mismatch"); } var GridDat = this.m_bOutput.GridDat; int N = m_bOutput.Length; int Nin = m_bInput.Length; int J = GridDat.iLogicalCells.NoOfLocalUpdatedCells; diagnosis = new double[N * J]; double[] RHS = new double[N]; double[] f2 = new double[N]; double[] g1 = new double[N]; MultidimensionalArray Trf = MultidimensionalArray.Create(N, N); input.MPIExchange(); for (int jCell = 0; jCell < J; jCell++) { Debug.Assert((this.AggregateBasisTrafo[jCell] != null) == (this.Stencils[jCell] != null)); //FullMatrix invMassM = this.InvMassMatrix[jCell]; MultidimensionalArray ExPolMtx = this.AggregateBasisTrafo[jCell]; if (ExPolMtx != null) { int[] Stencil_jCells = this.Stencils[jCell]; int K = Stencil_jCells.Length; Debug.Assert(Stencil_jCells[0] == jCell); var coordIn = input.Coordinates; //for(int n = Math.Min(Nin, N) - 1; n >= 0; n--) { // RHS[n] = coordIn[jCell, n]; //} RHS.ClearEntries(); g1.ClearEntries(); var oldCoords = input.Coordinates.GetRow(jCell); for (int k = 0; k < K; k++) { int jNeigh = Stencil_jCells[k]; for (int n = Math.Min(input.Basis.Length, N) - 1; n >= 0; n--) { f2[n] = input.Coordinates[jNeigh, n]; } if (Nlim != null && Nlim[jNeigh] > 0) { for (int n = Nlim[jNeigh]; n < RHS.Length; n++) { f2[n] = 0; } } for (int l = 0; l < N; l++) { double acc = 0; for (int i = 0; i < N; i++) { acc += ExPolMtx[k, i, l] * f2[i]; } RHS[l] += acc; } } if (Nlim != null && Nlim[jCell] > 0) { for (int n = Nlim[jCell]; n < RHS.Length; n++) { RHS[n] = 0; } } for (int l = 0; l < N; l++) { diagnosis[jCell * N + l] = RHS[l]; } //invMassM.gemv(1.0, RHS, 0.0, g1); Trf.Clear(); Trf.Acc(1.0, ExPolMtx.ExtractSubArrayShallow(0, -1, -1)); //Trf.Solve(FulCoords, AggCoords); Trf.gemv(1.0, RHS, 0.0, g1); if (Nlim != null && Nlim[jCell] > 0) { for (int n = Nlim[jCell]; n < RHS.Length; n++) { g1[n] = 0; } } if (Nlim == null) { output.Coordinates.SetRow(jCell, g1); } else { if ((Nlim[jCell] <= 0 && this.notchangeunlim)) { output.Coordinates.SetRow(jCell, oldCoords); } else { output.Coordinates.SetRow(jCell, g1); } } } } output.MPIExchange(); }