protected override LinearPSI <Cube>[] ExtractSubPsis(LinearPSI <Cube> psi, LinearSayeSpace <Cube> arg, int heightDirection) { double[] bounds = arg.GetBoundaries(heightDirection); double x_U = bounds[1]; double x_L = bounds[0]; LinearPSI <Cube> Psi_U = psi.ReduceDim(heightDirection, x_U); LinearPSI <Cube> Psi_L = psi.ReduceDim(heightDirection, x_L); return(new LinearPSI <Cube>[] { Psi_L, Psi_U }); }
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); }
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); }
public QuadRule[] ComboEvaluate(int Cell) { LinearSayeSpace <Cube> startArg = CreateStartSetup(); return(ComboEvaluate(Cell, startArg)); }
public override double[] GetBoundaries(LinearSayeSpace <Cube> arg, int heightDirection) { return(arg.Boundaries[heightDirection]); }
protected override SayeQuadRule SetGaussQuadratureNodes(LinearSayeSpace <Cube> arg) { //Aquire needed data //------------------------------------------------------------------------------------------------------------ MultidimensionalArray nodes_GaussRule_3D; MultidimensionalArray weights_GaussRule_3D; MultidimensionalArray centerArr = arg.GetCellCenter().ExtractSubArrayShallow(0, -1); double[] diameters = arg.Diameters; double jacobianDet; //Gaussrule 2d or Gaussrule 3d? //2d Gaussrule embedded in 3d space on [-1,1]^3 //------------------------------------------------------------------------------------------------------------ if (arg.Dimension == 2) { QuadRule gaussRule_2D = Square.Instance.GetQuadratureRule(order); MultidimensionalArray nodes_GaussRule_2D = gaussRule_2D.Nodes; nodes_GaussRule_3D = MultidimensionalArray.Create(gaussRule_2D.NoOfNodes, 3); weights_GaussRule_3D = gaussRule_2D.Weights.CloneAs(); //Embed 2D nodes in 3d space for (int i = 0; i < gaussRule_2D.NoOfNodes; ++i) { int nodePositionCounter = 0; for (int j = 0; j < 3; ++j) { if (arg.DimActive(j)) { nodes_GaussRule_3D[i, j] = nodes_GaussRule_2D[i, nodePositionCounter]; ++nodePositionCounter; } else { nodes_GaussRule_3D[i, j] = centerArr[j]; } } } //Set rest jacobianDet = 1; for (int j = 0; j < 3; ++j) { if (arg.DimActive(j)) { jacobianDet *= diameters[j]; } } } //3d Gauss quadrature rule on [-1,1]^3 //------------------------------------------------------------------------------------------------------------ else { Debug.Assert(arg.Dimension == 3); //Extract Rule QuadRule gaussRule_3D = Cube.Instance.GetQuadratureRule(order); nodes_GaussRule_3D = ((MultidimensionalArray)gaussRule_3D.Nodes).CloneAs(); weights_GaussRule_3D = gaussRule_3D.Weights.CloneAs(); //Set rest jacobianDet = diameters[0] * diameters[1] * diameters[2]; } //AffineTransformation of nodes, scale weights //------------------------------------------------------------------------------------------------------------ //Scale Nodes for (int i = 0; i < 3; ++i) { nodes_GaussRule_3D.ColScale(i, diameters[i]); } //Scale Weights weights_GaussRule_3D.Scale(jacobianDet); //Move Nodes int[] index = new int[] { 0, -1 }; for (int i = 0; i < nodes_GaussRule_3D.Lengths[0]; ++i) { index[0] = i; nodes_GaussRule_3D.AccSubArray(1, centerArr, index); } //Set return data //------------------------------------------------------------------------------------------------------------ SayeQuadRule transformed_GaussRule_2D = new SayeQuadRule(nodes_GaussRule_3D, weights_GaussRule_3D); return(transformed_GaussRule_2D); }
protected override SayeQuadRule SetLowOrderQuadratureNodes(LinearSayeSpace <Cube> arg) { throw new NotImplementedException(); }
protected override LinearSayeSpace <Cube> DeriveNewArgument(LinearSayeSpace <Cube> OldSquare) { return(OldSquare.DeriveNew()); }
protected override bool SubdivideSuitable(LinearSayeSpace <Cube> arg) { return(true); }
protected override LinearSayeSpace <Cube> Subdivide(LinearSayeSpace <Cube> Arg) { LinearSayeSpace <Cube> newArg = Arg.Subdivide(); return(newArg); }
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); }