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);
        }
Exemple #2
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);
        }
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #7
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);
        }