Exemple #1
0
        // triangle-winding-number second-order approximation
        // t is triangle, p is 'center' of cluster of dipoles, q is evaluation point
        // (This is really just for testing)
        public static double Order2Approx(ref Triangle3d t, ref Vector3d p, ref Vector3d xn, ref double xA, ref Vector3d q)
        {
            Vector3d dpq = (p - q);

            double len  = dpq.Length;
            double len3 = len * len * len;

            // first-order approximation - integrated_normal_area * \grad(G)
            double order1 = (xA / MathUtil.FourPI) * xn.Dot(dpq / len3);

            // second-order hessian \grad^2(G)
            Matrix3d xqxq = new Matrix3d(ref dpq, ref dpq);

            xqxq *= 3.0 / (MathUtil.FourPI * len3 * len * len);
            double   diag    = 1 / (MathUtil.FourPI * len3);
            Matrix3d hessian = new Matrix3d(diag, diag, diag) - xqxq;

            // second-order LHS - integrated second-order area matrix (formula 26)
            Vector3d centroid = new Vector3d(
                (t.V0.x + t.V1.x + t.V2.x) / 3.0, (t.V0.y + t.V1.y + t.V2.y) / 3.0, (t.V0.z + t.V1.z + t.V2.z) / 3.0);
            Vector3d dcp    = centroid - p;
            Matrix3d o2_lhs = new Matrix3d(ref dcp, ref xn);
            double   order2 = xA * o2_lhs.InnerProduct(ref hessian);

            return(order1 + order2);
        }
Exemple #2
0
        /// <summary>
        /// Evaluate second-order FWN approximation at point q, relative to center c
        /// </summary>
        public static double EvaluateOrder2Approx(ref Vector3d center, ref Vector3d order1Coeff, ref Matrix3d order2Coeff, ref Vector3d q)
        {
            Vector3d dpq         = (center - q);
            double   len         = dpq.Length;
            double   len3        = len * len * len;
            double   fourPi_len3 = 1.0 / (MathUtil.FourPI * len3);

            double order1 = fourPi_len3 * order1Coeff.Dot(ref dpq);

            // second-order hessian \grad^2(G)
            double c = -3.0 / (MathUtil.FourPI * len3 * len * len);

            // expanded-out version below avoids extra constructors
            //Matrix3d xqxq = new Matrix3d(ref dpq, ref dpq);
            //Matrix3d hessian = new Matrix3d(fourPi_len3, fourPi_len3, fourPi_len3) - c * xqxq;
            Matrix3d hessian = new Matrix3d(
                fourPi_len3 + c * dpq.x * dpq.x, c * dpq.x * dpq.y, c * dpq.x * dpq.z,
                c * dpq.y * dpq.x, fourPi_len3 + c * dpq.y * dpq.y, c * dpq.y * dpq.z,
                c * dpq.z * dpq.x, c * dpq.z * dpq.y, fourPi_len3 + c * dpq.z * dpq.z);

            double order2 = order2Coeff.InnerProduct(ref hessian);

            return(order1 + order2);
        }
Exemple #3
0
        // point-winding-number second-order approximation
        // x is dipole point, p is 'center' of cluster of dipoles, q is evaluation point
        public static double Order2Approx(ref Vector3d x, ref Vector3d p, ref Vector3d xn, double xA, ref Vector3d q)
        {
            Vector3d dpq = (p - q);
            Vector3d dxp = (x - p);

            double len  = dpq.Length;
            double len3 = len * len * len;

            // first-order approximation - area*normal*\grad(G)
            double order1 = (xA / MathUtil.FourPI) * xn.Dot(dpq / len3);

            // second-order hessian \grad^2(G)
            Matrix3d xqxq = new Matrix3d(ref dpq, ref dpq);

            xqxq *= 3.0 / (MathUtil.FourPI * len3 * len * len);
            double   diag    = 1 / (MathUtil.FourPI * len3);
            Matrix3d hessian = new Matrix3d(diag, diag, diag) - xqxq;

            // second-order LHS area * \outer(x-p, normal)
            Matrix3d o2_lhs = new Matrix3d(ref dxp, ref xn);
            double   order2 = xA * o2_lhs.InnerProduct(ref hessian);

            return(order1 + order2);
        }