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> /// Reconstructs a level set <see cref="SinglePhaseField"/> from a given set of points /// </summary> /// <param name="field">The DG field to work with</param> /// <param name="clustering"> as <see cref="MultidimensionalArray"/> /// Lenghts --> [0]: numOfPoints, [1]: 5 /// [1] --> [0]: x, [1]: y, [2]: data, [3]: cellToCluster (e.g. cell 0 is in cluster 1), [4]: local cell index /// </param> /// <param name="patchRecovery">Use <see cref="ShockFindingExtensions.PatchRecovery(SinglePhaseField)"/></param> /// <param name="continuous">Use <see cref="ShockFindingExtensions.ContinuousLevelSet(SinglePhaseField, MultidimensionalArray)"/></param> /// <returns>Returns the reconstructed level set as <see cref="SinglePhaseField"/></returns> public SinglePhaseField ReconstructLevelSet(SinglePhaseField field = null, MultidimensionalArray clustering = null, bool patchRecovery = true, bool continuous = true) { Console.WriteLine("ReconstructLevelSet: START"); if (field == null) { field = this.densityField; } Console.WriteLine(string.Format("ReconstructLevelSet based on field {0}", field.Identification)); if (clustering == null) { clustering = _clusterings.Last(); Console.WriteLine(string.Format("ReconstructLevelSet based on clustering {0}", _clusterings.Count() - 1)); } else { Console.WriteLine("ReconstructLevelSet based on user-defined clustering"); } // Extract points (x-coordinates, y-coordinates) for reconstruction from clustering MultidimensionalArray points = clustering.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { clustering.Lengths[0] - 1, 1 }); _levelSetFields.Add(geometryLevelSetField); SinglePhaseField levelSetField = ShockFindingExtensions.ReconstructLevelSetField(field, points); _levelSetFields.Add(levelSetField); if (patchRecovery) { levelSetField = ShockFindingExtensions.PatchRecovery(levelSetField); _levelSetFields.Add(levelSetField); } if (continuous) { levelSetField = ShockFindingExtensions.ContinuousLevelSet(levelSetField, clustering.ExtractSubArrayShallow(-1, 4).To1DArray()); _levelSetFields.Add(levelSetField); } Console.WriteLine("ReconstructLevelSet: END"); return(levelSetField); }
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); }