/// <summary> /// Addition/Subtraction of DG fields on different grids /// </summary> /// <param name="A"></param> /// <param name="scaleA"></param> /// <param name="B"></param> /// <param name="scaleB"></param> /// <returns> /// <paramref name="scaleA"/>*<paramref name="A"/> + <paramref name="scaleB"/>*<paramref name="B"/> /// </returns> static public DGField ScaledSummation(this DGField A, double scaleA, DGField B, double scaleB) { if (object.ReferenceEquals(A.GridDat, B.GridDat)) { // ++++++++++++++++++++++++++++ // both fields on the same grid // ++++++++++++++++++++++++++++ DGField sum; if (A.Basis.IsSubBasis(B.Basis)) { sum = (DGField)B.Clone(); sum.Scale(scaleB); sum.AccLaidBack(1.0, A); } else if (B.Basis.IsSubBasis(A.Basis)) { sum = (DGField)A.Clone(); sum.Scale(scaleA); sum.AccLaidBack(1.0, B); } else { throw new ApplicationException("can't add the two fields, because their basis are incompatible"); } sum.Identification = "(" + scaleA + "*" + A.Identification + "+" + scaleB + "*" + B.Identification + ")"; return(sum); } else { // ++++++++++++++++++++++++++ // fields on different grids // ++++++++++++++++++++++++++ DGField fine, coarse; double aF, aC; if (A.GridDat.CellPartitioning.TotalLength > B.GridDat.CellPartitioning.TotalLength) { fine = A; coarse = B; aF = scaleA; aC = scaleB; } else { coarse = A; fine = B; aC = scaleA; aF = scaleB; } DGFieldComparison.ComputeFine2CoarseMap( (Foundation.Grid.Classic.GridData)(fine.GridDat), (Foundation.Grid.Classic.GridData)(coarse.GridDat), out var Fine2CoarseMapS); DGField injected; if (coarse is ConventionalDGField) { ConventionalDGField _injected = new SinglePhaseField( new Basis(fine.GridDat, Math.Max(coarse.Basis.Degree, fine.Basis.Degree)), coarse.Identification); DGFieldComparison.InjectDGField(Fine2CoarseMapS, _injected, coarse as ConventionalDGField); injected = _injected; } else if (coarse is XDGField) { XDGField _injected = new XDGField( new XDGBasis((fine as XDGField).Basis.Tracker, Math.Max(coarse.Basis.Degree, fine.Basis.Degree)), coarse.Identification); DGFieldComparison.InjectXDGField(Fine2CoarseMapS, _injected, coarse as XDGField); injected = _injected; } else { throw new NotSupportedException(); } return(ScaledSummation(injected, aC, fine, aF)); } }