示例#1
0
        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 });
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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);
        }
示例#5
0
        public QuadRule[] ComboEvaluate(int Cell)
        {
            LinearSayeSpace <Cube> startArg = CreateStartSetup();

            return(ComboEvaluate(Cell, startArg));
        }
示例#6
0
 public override double[] GetBoundaries(LinearSayeSpace <Cube> arg, int heightDirection)
 {
     return(arg.Boundaries[heightDirection]);
 }
示例#7
0
        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);
        }
示例#8
0
 protected override SayeQuadRule SetLowOrderQuadratureNodes(LinearSayeSpace <Cube> arg)
 {
     throw new NotImplementedException();
 }
示例#9
0
 protected override LinearSayeSpace <Cube> DeriveNewArgument(LinearSayeSpace <Cube> OldSquare)
 {
     return(OldSquare.DeriveNew());
 }
示例#10
0
 protected override bool SubdivideSuitable(LinearSayeSpace <Cube> arg)
 {
     return(true);
 }
示例#11
0
        protected override LinearSayeSpace <Cube> Subdivide(LinearSayeSpace <Cube> Arg)
        {
            LinearSayeSpace <Cube> newArg = Arg.Subdivide();

            return(newArg);
        }
示例#12
0
        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);
        }