protected override MultidimensionalArray Gradient(LinearPSI <Square> psi, NodeSet Node, int Cell) { //Move Node onto psi MultidimensionalArray gradient = ScaledReferenceGradient(Node, Cell); return(gradient); }
protected override double EvaluateAt(LinearPSI <Square> Psi, NodeSet Node, int cell) { Debug.Assert(Node.NoOfNodes == 1); NodeSet nodeOnPsi = Psi.ProjectOnto(Node); double value = lsData.GetLevSetValues(nodeOnPsi, cell, 1)[0, 0]; return(value); }
protected override int FindPromisingHeightDirection(LinearPSI <Square> Psi, NodeSet Node, int Cell) { MultidimensionalArray gradient = ScaledReferenceGradient(Node, Cell); if (Math.Abs(gradient[0]) > Math.Abs(gradient[1])) { return(0); } return(1); }
protected override LinearPSI <Square>[] ExtractSubPsis(LinearPSI <Square> psi, SayeSquare arg, int heightDirection) { double[] bounds = arg.GetBoundaries(heightDirection); double x_U = bounds[1]; double x_L = bounds[0]; LinearPSI <Square> Psi_U = psi.ReduceDim(heightDirection, x_U); LinearPSI <Square> Psi_L = psi.ReduceDim(heightDirection, x_L); return(new LinearPSI <Square>[] { Psi_L, Psi_U }); }
public SayeSquare CreateStartSetup() { bool IsSurfaceIntegral = (quadratureMode == QuadratureMode.Surface); int domainSign = (quadratureMode == QuadratureMode.NegativeVolume) ? -1 : 1; LinearPSI <Square> psi = new LinearPSI <Square>(Square.Instance); Tuple <LinearPSI <Square>, int> psi_i_s_i = new Tuple <LinearPSI <Square>, int>(psi, domainSign); SayeSquare arg = new SayeSquare(psi_i_s_i, IsSurfaceIntegral); arg.Reset(); return(arg); }
private LinearSayeSpace <Cube> CreateStartSetup() { bool IsSurfaceIntegral = (mode == QuadratureMode.Surface); LinearPSI <Cube> psi = new LinearPSI <Cube>(Cube.Instance); Tuple <LinearPSI <Cube>, int> psi_i_s_i = new Tuple <LinearPSI <Cube>, int>(psi, 1); LinearSayeSpace <Cube> arg = new LinearSayeSpace <Cube>(Cube.Instance, psi_i_s_i, IsSurfaceIntegral); arg.Reset(); return(arg); }
/// <summary> /// First order approximation of delta >= sup_x|psi(x) - psi(x_center)| /// </summary> /// <param name="Arg"></param> /// <param name="psi"></param> /// <param name="x_center"></param> /// <param name="cell"></param> /// <returns></returns> protected override double EvaluateBounds(LinearSayeSpace <Cube> Arg, LinearPSI <Cube> psi, NodeSet x_center, int cell) { double[] arr = new double[RefElement.SpatialDimension]; Arg.Diameters.CopyTo(arr, 0); psi.SetInactiveDimsToZero(arr); MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, 3); NodeSet nodeOnPsi = psi.ProjectOnto(x_center); MultidimensionalArray grad = ReferenceGradient(nodeOnPsi, cell); grad.ApplyAll(x => Math.Abs(x)); double delta = grad.InnerProduct(diameters); return(delta); }
protected override bool HeightDirectionIsSuitable(SayeSquare arg, LinearPSI <Square> psi, NodeSet x_center, int heightDirection, MultidimensionalArray gradient, int cell) { //Determine bounds //----------------------------------------------------------------------------------------------------------------- double[] arr = arg.Diameters; psi.SetInactiveDimsToZero(arr); MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, new int[] { 2, 1 }); NodeSet nodeOnPsi = psi.ProjectOnto(x_center); MultidimensionalArray hessian = lsData.GetLevelSetReferenceHessian(nodeOnPsi, cell, 1); hessian = hessian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 }); MultidimensionalArray jacobian = grid.InverseJacobian.GetValue_Cell(nodeOnPsi, cell, 1); jacobian = jacobian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 }); hessian = jacobian * hessian; hessian.ApplyAll(x => Math.Abs(x)); //abs(Hessian) * diameters = delta MultidimensionalArray delta = hessian * diameters; delta = delta.ExtractSubArrayShallow(new int[] { -1, 0 }); //Check if suitable //----------------------------------------------------------------------------------------------------------------- //|gk| > δk if (Math.Abs(gradient[heightDirection]) > delta[heightDirection]) { bool suitable = true; // Sum_j( g_j + delta_j)^2 / (g_k - delta_k)^2 < 20 double sum = 0; for (int j = 0; j < delta.Length; ++j) { sum += Math.Pow(gradient[j] + delta[j], 2); } sum /= Math.Pow(gradient[heightDirection] - delta[heightDirection], 2); suitable &= sum < 20; return(suitable); } return(false); }
/// <summary> /// First order approximation of delta >= sup_x|psi(x) - psi(x_center)| /// </summary> /// <param name="Arg"></param> /// <param name="psi"></param> /// <param name="x_center"></param> /// <param name="cell"></param> /// <returns></returns> protected override double EvaluateBounds(SayeSquare Arg, LinearPSI <Square> psi, NodeSet x_center, int cell) { double[] arr = new double[Arg.Dimension]; Arg.Diameters.CopyTo(arr, 0); psi.SetInactiveDimsToZero(arr); MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, new int[] { 2 }); NodeSet nodeOnPsi = psi.ProjectOnto(x_center); MultidimensionalArray grad = ScaledReferenceGradient(nodeOnPsi, cell); grad.ApplyAll(x => Math.Abs(x)); double delta = grad.InnerProduct(diameters) * sqrt_2; return(delta); }
private LinearSayeSpace <Cube> CreateStartSetup() { bool IsSurfaceIntegral = (mode == QuadratureMode.Surface); LinearPSI <Cube> psi = new LinearPSI <Cube>(Cube.Instance); int domainSign = 1; if (mode == QuadratureMode.NegativeVolume) { domainSign = -1; } Tuple <LinearPSI <Cube>, int> psi_i_s_i = new Tuple <LinearPSI <Cube>, int>(psi, domainSign); LinearSayeSpace <Cube> arg = new LinearSayeSpace <Cube>(Cube.Instance, psi_i_s_i, IsSurfaceIntegral); arg.Reset(); return(arg); }
protected override int FindPromisingHeightDirection(LinearPSI <Cube> Psi, NodeSet Node, int Cell) { NodeSet nodeOnPsi = Psi.ProjectOnto(Node); MultidimensionalArray gradient = ReferenceGradient(nodeOnPsi, Cell); int heightDirection = 0; double max = double.MinValue; for (int i = 0; i < RefElement.SpatialDimension; ++i) { if ((Math.Abs(gradient[i]) > max) && (!Psi.DirectionIsFixed(i))) { max = Math.Abs(gradient[i]); heightDirection = i; } } return(heightDirection); }
protected override double[] FindRoots(LinearPSI <Cube> psi, MultidimensionalArray X, int heightDirection, double[] bounds, int cell) { MultidimensionalArray XonPsi = psi.ProjectOnto(X); XonPsi = XonPsi.ExtractSubArrayShallow(0, -1); double[] start = XonPsi.To1DArray(); double[] end = XonPsi.To1DArray(); start[heightDirection] = -1; end[heightDirection] = 1; HMF.LineSegment line = new HMF.LineSegment(3, RefElement, start, end); LevelSet levelSet = lsData.LevelSet as LevelSet; line.ProjectBasisPolynomials(levelSet.Basis); double[] roots = rootFinder.GetRoots(line, levelSet, cell, this.iKref); return(roots); }
protected override bool HeightDirectionIsSuitable( LinearSayeSpace <Cube> arg, LinearPSI <Cube> psi, NodeSet x_center, int heightDirection, MultidimensionalArray agradient, int cell) { //throw new NotImplementedException(); //Determine bounds //----------------------------------------------------------------------------------------------------------------- NodeSet nodeOnPsi = psi.ProjectOnto(x_center); MultidimensionalArray jacobian = grid.Jacobian.GetValue_Cell(nodeOnPsi, cell, 1); jacobian = jacobian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 }); LevelSet levelSet = lsData.LevelSet as LevelSet; MultidimensionalArray hessian = MultidimensionalArray.Create(1, 1, 3, 3); levelSet.EvaluateHessian(cell, 1, nodeOnPsi, hessian); hessian = hessian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 }).CloneAs(); //hessian = jacobian * hessian; hessian.ApplyAll(x => Math.Abs(x)); MultidimensionalArray gradient = lsData.GetLevelSetGradients(nodeOnPsi, cell, 1); gradient = gradient.ExtractSubArrayShallow(0, 0, -1).CloneAs(); //abs(Hessian) * 0,5 * diameters.^2 = delta ,( square each entry of diameters) , //this bounds the second error term from taylor series //+ + + + double[] arr = arg.Diameters.CloneAs(); psi.SetInactiveDimsToZero(arr); MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, 3, 1); diameters = jacobian * diameters; diameters.ApplyAll(x => 0.5 * x * x); MultidimensionalArray delta = hessian * diameters; delta = delta.ExtractSubArrayShallow(-1, 0); //Check if suitable //----------------------------------------------------------------------------------------------------------------- //|gk| > δk //Gradient should be able to turn arround psi.SetInactiveDimsToZero(gradient.Storage); if (Math.Abs(gradient[heightDirection]) > delta[heightDirection]) { bool suitable = true; // ||Grad + maxChange|| should be smaller than 20 * // Sum_j( g_j + delta_j)^2 / (g_k - delta_k)^2 < 20 double sum = 0; for (int j = 0; j < delta.Length; ++j) { sum += Math.Pow(Math.Abs(gradient[j]) + delta[j], 2); } sum /= Math.Pow(Math.Abs(gradient[heightDirection]) - delta[heightDirection], 2); suitable &= sum < 20; return(suitable); } return(false); }
protected override MultidimensionalArray Gradient(LinearPSI <Cube> psi, NodeSet Node, int Cell) { MultidimensionalArray gradient = ReferenceGradient(Node, Cell); return(gradient); }