Exemplo n.º 1
0
        //Algorithm 2
        //page: A1005
        private void SurfaceIntegrand(MultidimensionalArray X, double X_weight, T arg, bool isNew)
        {
            Debug.Assert(arg.n == 1);
            //Calculate the roots of phi in the interval R = ... (line 1)
            S   phi             = arg.PsiAndS[0].Item1;
            int heightDirection = arg.HeightDirection;

            double[] bounds = GetBoundaries(arg, heightDirection);
            ISortedBoundedList <double> roots = new SayeSortedList(3, 1.0e-14);

            roots.SetBounds(bounds[0], bounds[1]);
            double[] newRoots = FindRoots(phi, X, heightDirection, bounds, this.cell);
            roots.Add(newRoots);

            //if there is a root, insert node
            Debug.Assert(roots.Count() <= 3);
            if (roots.Count() > 2)
            {
                X[0, heightDirection] = roots[1];
                SayeQuadRule surfaceQuadNode = BuildSurfaceQuadRule(X, X_weight, heightDirection, this.cell);
                arg.NodesAndWeights.AddRule(surfaceQuadNode, true);
            }
            //else remove node
            else
            {
                arg.NodesAndWeights.RemoveActiveNode();
            }
        }
Exemplo n.º 2
0
        private void ComboIntegrandEvaluation(TreeNode <T> node)
        {
            if (node.level == 1)
            {
                //Calculate Surface and Volume Rule
                T nodeArg = node.Value;
                switch (nodeArg.Status)
                {
                case SayeArgument <S> .Mode.Standard:
                    SetStandartComboNodes(node);
                    break;

                case SayeArgument <S> .Mode.GaussQuadrature:
                    //No need for surface quadNodes
                    SayeQuadRule newRule = SetGaussQuadratureNodes(nodeArg);
                    nodeArg.NodesAndWeights.AddRule(newRule, false);
                    break;

                case SayeArgument <S> .Mode.LowOrderQuadrature:
                    throw new NotImplementedException();

                case SayeArgument <S> .Mode.DomainIsEmpty:
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            else
            {
                IntegrandEvaluation(node);
            }
        }
Exemplo n.º 3
0
        protected override SayeQuadRule BuildQuadRule(MultidimensionalArray X, double X_weight, int heightDirection, double length)
        {
            QuadRule gaussRule_1D = Line.Instance.GetQuadratureRule(order);

            double[,] nodesArr = new double[gaussRule_1D.NoOfNodes, 2];
            for (int i = 0; i < gaussRule_1D.NoOfNodes; ++i)
            {
                for (int j = 0; j < 2; ++j)
                {
                    nodesArr[i, j] = X[0, j];
                    if (j == heightDirection)
                    {
                        nodesArr[i, j] += length / 2 * gaussRule_1D.Nodes[i, 0];
                    }
                }
            }

            MultidimensionalArray weights = gaussRule_1D.Weights.CloneAs();

            weights.Scale(length / 2);
            weights.Scale(X_weight);

            MultidimensionalArray nodes = new MultidimensionalArray(2);

            nodes.InitializeFrom(nodesArr);
            SayeQuadRule transformed_GaussRule_1D = new SayeQuadRule(nodes, weights);

            return(transformed_GaussRule_1D);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        //Algorithm 1
        //page: A1005
        private void VolumeIntegrand(MultidimensionalArray X, double X_weight, T arg, bool isNew)
        {
            //Calculate the set of roots and union with the interval endpoints ( line 1)
            int heightDirection = arg.HeightDirection;

            //Sort R into ascending order such that ... (line 2) : Implemented with a sortedList
            ISortedBoundedList <double> roots = new SayeSortedList(2 + arg.n, 1.0e-14);

            double[] bounds = GetBoundaries(arg, heightDirection);
            roots.SetBounds(bounds[0], bounds[1]);
            RestrictToBound(X, bounds[0], arg.HeightDirection);
            for (int i = 0; i < arg.n; ++i)
            {
                S        psi_i      = arg.PsiAndS[i].Item1;
                double[] rootsInPsi = FindRoots(psi_i, X, heightDirection, bounds, this.cell);
                roots.Add(rootsInPsi);
            }

            //For j = 1 to l - 1 do (line 4)
            bool xIsUnchanged = true;

            for (int j = 0; j < roots.Count() - 1; ++j)
            {
                //Define L and x_c(line 5)
                double  L   = roots[j + 1] - roots[j];
                NodeSet x_c = NodeOnRay(X, heightDirection, roots[j] - roots[0] + L / 2.0);

                //If s_i * psi_i >= 0 for all i (line 6)
                bool updateIntegrand = true;
                foreach (Tuple <S, int> psiAndS in arg.PsiAndS)
                {
                    S   psi_i = psiAndS.Item1;
                    int s_i   = psiAndS.Item2;
                    updateIntegrand &= s_i * EvaluateAt(psi_i, x_c) >= 0;
                }
                //Update I = ...(line 7)
                if (updateIntegrand)
                {
                    SayeQuadRule newRule = BuildQuadRule(x_c, X_weight, heightDirection, L);
                    bool         deriveFromExistingNode = !isNew && xIsUnchanged;
                    arg.NodesAndWeights.AddRule(newRule, deriveFromExistingNode);
                    xIsUnchanged = false;
                }
            }
            if (xIsUnchanged && !isNew)
            {
                arg.NodesAndWeights.RemoveActiveNode();
            }
        }
Exemplo n.º 6
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);
        }