void CalculateDerivativeByFlux() { DuDx.Clear(); DuDy.Clear(); DvDx.Clear(); DvDy.Clear(); DuDx.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[0], 0); DuDy.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[0], 1); DvDx.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[1], 0); DvDy.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[1], 1); if (m_app.GridData.SpatialDimension == 3) { DuDz.Clear(); DvDz.Clear(); DwDx.Clear(); DwDy.Clear(); DwDz.Clear(); DuDz.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[0], 2); DvDz.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[1], 2); DwDx.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[2], 0); DwDy.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[2], 1); DwDz.DerivativeByFlux(1.0, m_app.WorkingSet.Velocity.Current[2], 2); } }
private double[] NormalizedGradientByFlux(SinglePhaseField field, int jCell, NodeSet nodeSet) { if (this.gradientX == null) { // Evaluate gradient gradientX = new SinglePhaseField(field.Basis, "gradientX"); gradientY = new SinglePhaseField(field.Basis, "gradientY"); gradientX.DerivativeByFlux(1.0, field, d: 0); gradientY.DerivativeByFlux(1.0, field, d: 1); if (this.patchRecoveryGradient) { gradientX = ShockFindingExtensions.PatchRecovery(gradientX); gradientY = ShockFindingExtensions.PatchRecovery(gradientY); } } if (this.resultGradX == null) { resultGradX = MultidimensionalArray.Create(1, 1); resultGradY = MultidimensionalArray.Create(1, 1); } gradientX.Evaluate(jCell, 1, nodeSet, resultGradX); gradientY.Evaluate(jCell, 1, nodeSet, resultGradY); double[] gradient = new double[] { resultGradX[0, 0], resultGradY[0, 0] }; gradient.Normalize(); return(gradient); }
/// <summary> /// Calculate current Nusselt number. /// </summary> public void CalculateNusseltNumber() { dTdx.Clear(); //dTdx.Derivative(1.0, Temperature, 0, GridDat.BoundaryCells.VolumeMask); dTdx.DerivativeByFlux(1.0, Temperature, 0); dTdy.Clear(); //dTdy.Derivative(1.0, Temperature, 1, GridDat.BoundaryCells.VolumeMask); dTdy.DerivativeByFlux(1.0, Temperature, 1); for (int bc = 0; bc < Nusselt.Length; bc++) { double LocalNusselt = NusseltIntegrals[bc].Evaluate(); double GlobalNusselt = 0.0; unsafe { MPI.Wrappers.csMPI.Raw.Allreduce((IntPtr)(&LocalNusselt), (IntPtr)(&GlobalNusselt), 1, MPI.Wrappers.csMPI.Raw._DATATYPE.DOUBLE, MPI.Wrappers.csMPI.Raw._OP.SUM, MPI.Wrappers.csMPI.Raw._COMM.WORLD); } Nusselt[bc] = GlobalNusselt; } }
private double SecondDerivativeByFlux(SinglePhaseField field, int jCell, NodeSet nodeSet) { if (this.gradientX == null) { // Evaluate gradient gradientX = new SinglePhaseField(field.Basis, "gradientX"); gradientY = new SinglePhaseField(field.Basis, "gradientY"); gradientX.DerivativeByFlux(1.0, field, d: 0); gradientY.DerivativeByFlux(1.0, field, d: 1); if (this.patchRecoveryGradient) { gradientX = ShockFindingExtensions.PatchRecovery(gradientX); gradientY = ShockFindingExtensions.PatchRecovery(gradientY); } } if (this.hessianXX == null) { // Evaluate Hessian matrix hessianXX = new SinglePhaseField(field.Basis, "hessianXX"); hessianXY = new SinglePhaseField(field.Basis, "hessianXY"); hessianYX = new SinglePhaseField(field.Basis, "hessianYX"); hessianYY = new SinglePhaseField(field.Basis, "hessianYY"); hessianXX.DerivativeByFlux(1.0, gradientX, d: 0); hessianXY.DerivativeByFlux(1.0, gradientX, d: 1); hessianYX.DerivativeByFlux(1.0, gradientY, d: 0); hessianYY.DerivativeByFlux(1.0, gradientY, d: 1); if (this.patchRecoveryHessian) { hessianXX = ShockFindingExtensions.PatchRecovery(hessianXX); hessianXY = ShockFindingExtensions.PatchRecovery(hessianXY); hessianYX = ShockFindingExtensions.PatchRecovery(hessianYX); hessianYY = ShockFindingExtensions.PatchRecovery(hessianYY); } } if (this.resultGradX == null) { resultGradX = MultidimensionalArray.Create(1, 1); resultGradY = MultidimensionalArray.Create(1, 1); } if (this.resultHessXX == null) { resultHessXX = MultidimensionalArray.Create(1, 1); resultHessXY = MultidimensionalArray.Create(1, 1); resultHessYX = MultidimensionalArray.Create(1, 1); resultHessYY = MultidimensionalArray.Create(1, 1); } gradientX.Evaluate(jCell, 1, nodeSet, resultGradX); gradientY.Evaluate(jCell, 1, nodeSet, resultGradY); hessianXX.Evaluate(jCell, 1, nodeSet, resultHessXX); hessianXY.Evaluate(jCell, 1, nodeSet, resultHessXY); hessianYX.Evaluate(jCell, 1, nodeSet, resultHessYX); hessianYY.Evaluate(jCell, 1, nodeSet, resultHessYY); // Compute second derivative along curve double g_alpha_alpha = 2 * ((resultHessXX[0, 0] * resultGradX[0, 0] + resultHessXY[0, 0] * resultGradY[0, 0]) * resultGradX[0, 0] + (resultHessYX[0, 0] * resultGradX[0, 0] + resultHessYY[0, 0] * resultGradY[0, 0]) * resultGradY[0, 0]); if (g_alpha_alpha == 0.0 || g_alpha_alpha.IsNaN()) { throw new NotSupportedException("Second derivative is zero"); } return(g_alpha_alpha); }
/// <summary> /// Reconstructs a <see cref="BoSSS.Foundation.XDG.LevelSet"/> from a given set of points on a given DG field /// </summary> /// <param name="field">The DG field to work with</param> /// <param name="points"> <see cref="MultidimensionalArray"/> /// Lengths --> [0]: numOfPoints, [1]: 2 /// [1] --> [0]: x, [1]: y /// </param> public static SinglePhaseField ReconstructLevelSetField(SinglePhaseField field, MultidimensionalArray points) { // Init IGridData gridData = field.GridDat; // Evaluate gradient SinglePhaseField gradientX = new SinglePhaseField(field.Basis, "gradientX"); SinglePhaseField gradientY = new SinglePhaseField(field.Basis, "gradientY"); gradientX.DerivativeByFlux(1.0, field, d: 0); gradientY.DerivativeByFlux(1.0, field, d: 1); //gradientX = PatchRecovery(gradientX); //gradientY = PatchRecovery(gradientY); FieldEvaluation ev = new FieldEvaluation((GridData)gridData); MultidimensionalArray GradVals = MultidimensionalArray.Create(points.GetLength(0), 2); ev.Evaluate(1.0, new DGField[] { gradientX, gradientY }, points, 0.0, GradVals); // Level set reconstruction Console.WriteLine("Reconstruction of field levelSet started..."); int count = 0; Func <double[], double> func = delegate(double[] X) { double minDistSigned = double.MaxValue; int iMin = int.MaxValue; double closestPointOnInterfaceX = double.MaxValue; double closestPointOnInterfaceY = double.MaxValue; double x = X[0]; double y = X[1]; for (int i = 0; i < points.Lengths[0]; i++) { double currentPointX = points[i, 0]; double currentPointY = points[i, 1]; double deltaX = x - currentPointX; double deltaY = y - currentPointY; double dist = Math.Sqrt(deltaX * deltaX + deltaY * deltaY); if (dist <= minDistSigned) { iMin = i; minDistSigned = dist; closestPointOnInterfaceX = currentPointX; closestPointOnInterfaceY = currentPointY; } } //// Compute global cell index of quadrature node //gridData.LocatePoint(X, out long GlobalId, out long GlobalIndex, out bool IsInside, out bool OnThisProcess); //// Compute local node set //NodeSet nodeSet = GetLocalNodeSet(gridData, X, (int)GlobalIndex); //// Evaluate gradient //// Get local cell index of quadrature node //int j0Grd = gridData.CellPartitioning.i0; //int j0 = (int)(GlobalIndex - j0Grd); //int Len = 1; //MultidimensionalArray resultGradX = MultidimensionalArray.Create(1, 1); //MultidimensionalArray resultGradY = MultidimensionalArray.Create(1, 1); //gradientX.Evaluate(j0, Len, nodeSet, resultGradX); //gradientY.Evaluate(j0, Len, nodeSet, resultGradY); int sign = Math.Sign((x - closestPointOnInterfaceX) * GradVals[iMin, 0] + (y - closestPointOnInterfaceY) * GradVals[iMin, 1]); minDistSigned *= sign; //Console.WriteLine(String.Format("Quadrature point #{0}: ({1}, {2}), interface point: ({3}, {4})", count, X[0], X[1], closestPointOnInterfaceX, closestPointOnInterfaceY)); count++; return(minDistSigned); }; // DG level set field SinglePhaseField DGLevelSet = new SinglePhaseField(field.Basis, "levelSet_recon"); DGLevelSet.ProjectField(func.Vectorize()); Console.WriteLine("finished"); return(DGLevelSet); }