示例#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();
            }
        }
示例#2
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();
            }
        }