protected override SayeQuadRule SetGaussQuadratureNodes(SayeSquare arg) { //Aquire needed data //------------------------------------------------------------------------------------------------------------ QuadRule gaussRule_2D = Square.Instance.GetQuadratureRule(order); MultidimensionalArray nodes_GaussRule_2D = ((MultidimensionalArray)gaussRule_2D.Nodes).CloneAs(); MultidimensionalArray weights_GaussRule_2D = gaussRule_2D.Weights.CloneAs(); double[] diameters = arg.Diameters; MultidimensionalArray centerArr = arg.GetCellCenter().ExtractSubArrayShallow(new int[] { 0, -1 }); double jacobian = diameters[0] * diameters[1]; //AffineTransformation of nodes, scale weights //------------------------------------------------------------------------------------------------------------ //Scale Nodes for (int i = 0; i < 2; ++i) { nodes_GaussRule_2D.ColScale(i, diameters[i]); } //Scale Weights weights_GaussRule_2D.Scale(jacobian); //Move Nodes int[] index = new int[] { 0, -1 }; for (int i = 0; i < gaussRule_2D.NoOfNodes; ++i) { index[0] = i; nodes_GaussRule_2D.AccSubArray(1, centerArr, index); } //Set return data //------------------------------------------------------------------------------------------------------------ SayeQuadRule transformed_GaussRule_2D = new SayeQuadRule(nodes_GaussRule_2D, weights_GaussRule_2D); return(transformed_GaussRule_2D); }
public SayeSquare Subdivide() { subdivided = true; double[][] newBoundary = boundaries.Copy(); //Figure out new Boundaries int k; if (diameters[0] > diameters[1]) { k = 0; } else { k = 1; } double[] maxBounds = boundaries[k]; double newBound = (maxBounds[0] + maxBounds[1]) / 2; maxBounds[1] = newBound; SetBoundaries(boundaries); newBoundary[k][0] = newBound; SayeSquare sibling = new SayeSquare(newBoundary); sibling.psiAndS = new List <Tuple <LinearPSI <Square>, int> >(this.psiAndS); sibling.removedDims = this.removedDims.CloneAs(); sibling.subdivided = true; sibling.Surface = this.surface; return(sibling); }
public SayeSquare DeriveNew() { double[][] newBoundary = boundaries.Copy(); SayeSquare arg = new SayeSquare(newBoundary); arg.subdivided = this.subdivided; arg.Surface = this.surface; return(arg); }
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); }
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); }
public QuadRule[] ComboEvaluate(int Cell) { SayeSquare startArg = CreateStartSetup(); return(ComboEvaluate(Cell, startArg)); }
public override double[] GetBoundaries(SayeSquare arg, int heightDirection) { return(arg.Boundaries[heightDirection]); }
protected override SayeQuadRule SetLowOrderQuadratureNodes(SayeSquare arg) { throw new NotImplementedException(); }
protected override SayeSquare DeriveNewArgument(SayeSquare OldSquare) { return(OldSquare.DeriveNew()); }
protected override bool SubdivideSuitable(SayeSquare arg) { return(true); }
protected override SayeSquare Subdivide(SayeSquare Arg) { SayeSquare newArg = Arg.Subdivide(); return(newArg); }
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 }); }