public Matrix GetLocalStifnessMatrix()
        {
            var helpers = GetHelpers();

            var buf = MatrixPool.Allocate(18, 18);

            for (var i = 0; i < helpers.Length; i++)
            {
                var helper = helpers[i];

                var ki = helper.CalcLocalStiffnessMatrix(this);// ComputeK(helper, transMatrix);

                var dofs = helper.GetDofOrder(this);

                for (var ii = 0; ii < dofs.Length; ii++)
                {
                    var bi = dofs[ii].NodeIndex * 6 + (int)dofs[ii].Dof;

                    for (var jj = 0; jj < dofs.Length; jj++)
                    {
                        var bj = dofs[jj].NodeIndex * 6 + (int)dofs[jj].Dof;

                        buf[bi, bj] += ki[ii, jj];
                    }
                }
            }
            return(buf);
        }
Esempio n. 2
0
        public void LogInfo()
        {
            this.LogInfo("Loading tied-state acoustic model from: " + Location);
            MeansPool.LogInfo();
            VariancePool.LogInfo();
            MatrixPool.LogInfo();
            SenonePool.LogInfo();

            if (MeansTransformationMatrixPool != null)
            {
                MeansTransformationMatrixPool.LogInfo();
            }
            if (MeansTransformationVectorPool != null)
            {
                MeansTransformationVectorPool.LogInfo();
            }
            if (VarianceTransformationMatrixPool != null)
            {
                VarianceTransformationMatrixPool.LogInfo();
            }
            if (VarianceTransformationVectorPool != null)
            {
                VarianceTransformationVectorPool.LogInfo();
            }

            MixtureWeightsPool.LogInfo();
            SenonePool.LogInfo();
            this.LogInfo("Context Independent Unit Entries: "
                         + ContextIndependentUnits.Count);
            HmmManager.LogInfo();
        }
        public Matrix GetLocalMassMatrix()
        {
            var helpers = new List <IElementHelper>();

            if ((this._behavior & PlateElementBehaviour.ThinPlate) != 0)
            {
                helpers.Add(new DktHelper());
            }

            var buf = MatrixPool.Allocate(18, 18);

            for (var i = 0; i < helpers.Count; i++)
            {
                var helper = helpers[i];

                var ki = helper.CalcLocalMassMatrix(this);// ComputeK(helper, transMatrix);

                var dofs = helper.GetDofOrder(this);

                for (var ii = 0; ii < dofs.Length; ii++)
                {
                    var bi = dofs[ii].NodeIndex * 6 + (int)dofs[ii].Dof;

                    for (var jj = 0; jj < dofs.Length; jj++)
                    {
                        var bj = dofs[jj].NodeIndex * 6 + (int)dofs[jj].Dof;

                        buf[bi, bj] += ki[ii, jj];
                    }
                }
            }
            return(buf);
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public Matrix GetDMatrixAt(Element targetElement, params double[] isoCoords)
        {
            var tri = targetElement as TriangleElement;

            if (tri == null)
            {
                throw new Exception();
            }

            var mat = tri._material.GetMaterialPropertiesAt(isoCoords);
            var t   = tri.Section.GetThicknessAt(isoCoords);

            var d = MatrixPool.Allocate(3, 3);

            {
                var cf = t * t * t / 12;

                d[0, 0] = mat.Ex / (1 - mat.NuXy * mat.NuYx);
                d[1, 1] = mat.Ey / (1 - mat.NuXy * mat.NuYx);
                d[0, 1] = d[1, 0] =
                    mat.Ex * mat.NuYx / (1 - mat.NuXy * mat.NuYx);

                d[2, 2] = mat.Ex / (2 * (1 + mat.NuXy));

                //p55 http://www.code-aster.org/doc/v11/en/man_r/r3/r3.07.03.pdf

                d.MultiplyByConstant(cf);
            }

            return(d);
        }
        /// <summary>
        /// Gets the stifness matrix in local coordination system.
        /// </summary>
        /// <returns>stiffness matrix</returns>
        public virtual Matrix GetLocalStifnessMatrix()
        {
            var helpers = GetElementHelpers();

            var buf =
                MatrixPool.Allocate(6 * nodes.Length, 6 * nodes.Length);

            //var transMatrix = GetTransformationMatrix();

            for (var i = 0; i < helpers.Count; i++)
            {
                var helper = helpers[i];

                var ki = helper.CalcLocalStiffnessMatrix(this);// ComputeK(helper, transMatrix);

                var dofs = helper.GetDofOrder(this);


                for (var ii = 0; ii < dofs.Length; ii++)
                {
                    var bi = dofs[ii].NodeIndex * 6 + (int)dofs[ii].Dof;

                    for (var jj = 0; jj < dofs.Length; jj++)
                    {
                        var bj = dofs[jj].NodeIndex * 6 + (int)dofs[jj].Dof;

                        buf[bi, bj] += ki[ii, jj];
                    }
                }

                ki.ReturnToPool();
            }

            return(buf);
        }
Esempio n. 6
0
        public override Matrix GetLambdaMatrix()
        {
            //local coor system is same as global one
            var buf = MatrixPool.Allocate(3, 3);

            buf[0, 0] = buf[1, 1] = buf[2, 2] = 1;

            return(buf);
        }
Esempio n. 7
0
    /// <summary>
    /// 自前モーションで使用(現在は未使用)
    /// </summary>
    /// <param name="postures"></param>
    public void update(MotionPlayer.PostureUnit[] postures)
    {
        if (mr.isVisible)
        {
            var mts = MatrixPool.GetList();

            mts.AddRange(postures.Select(p => Matrix4x4.TRS(p.localPosition, p.localRotation, p.localScale)));

            mr.material.SetMatrixArray(ShaderId.Matrix, mts);
        }
    }
Esempio n. 8
0
    protected void LateUpdate()
    {
        if (mr.isVisible)
        {
            var mts = MatrixPool.GetList();

            mts.AddRange(bones.Select(bone => (bone != null) ? bone.localToWorldMatrix : Matrix4x4.identity));

            mr.material.SetMatrixArray(ShaderId.Matrix, mts);
        }
    }
Esempio n. 9
0
        /// <inheritdoc/>
        public Matrix GetJMatrixAt(Element targetElement, params double[] isoCoords)
        {
            var tmgr = targetElement.GetTransformationManager();

            var tri = targetElement as TriangleElement;

            if (tri == null)
            {
                throw new Exception();
            }

            var xi  = isoCoords[0];
            var eta = isoCoords[1];

            var mgr = tmgr;

            var p1l = mgr.TransformGlobalToLocal(tri.Nodes[0].Location);
            var p2l = mgr.TransformGlobalToLocal(tri.Nodes[1].Location);
            var p3l = mgr.TransformGlobalToLocal(tri.Nodes[2].Location);

            var p23 = p2l - p3l;
            var p31 = p3l - p1l;
            var p12 = p1l - p2l;


            var x23 = p23.X;
            var x31 = p31.X;
            var x12 = p12.X;

            var y23 = p23.Y;
            var y31 = p31.Y;
            var y12 = p12.Y;

            var buf = MatrixPool.Allocate(2, 2);

            buf[0, 0] = x31;
            buf[1, 1] = y12;

            buf[0, 1] = x12;
            buf[1, 0] = y31;

            return(buf);
        }
        public Matrix GetTransformationMatrix()
        {
            var cxx = 0.0;
            var cxy = 0.0;
            var cxz = 0.0;

            var cyx = 0.0;
            var cyy = 0.0;
            var cyz = 0.0;

            var czx = 0.0;
            var czy = 0.0;
            var czz = 0.0;

            var teta = _webRotation;

            var s = Math.Sin(teta * Math.PI / 180.0);
            var c = Math.Cos(teta * Math.PI / 180.0);

            var v = this.EndNode.Location - this.StartNode.Location;

            if (MathUtil.Equals(0, v.X) && MathUtil.Equals(0, v.Y))
            {
                if (v.Z > 0)
                {
                    czx = 1;
                    cyy = 1;
                    cxz = -1;
                }
                else
                {
                    czx = -1;
                    cyy = 1;
                    cxz = 1;
                }
            }
            else
            {
                var l = v.Length;
                cxx = v.X / l;
                cyx = v.Y / l;
                czx = v.Z / l;
                var d = Math.Sqrt(cxx * cxx + cyx * cyx);
                cxy = -cyx / d;
                cyy = cxx / d;
                cxz = -cxx * czx / d;
                cyz = -cyx * czx / d;
                czz = d;
            }

            var pars = new double[9];

            pars[0] = cxx;
            pars[1] = cxy * c + cxz * s;
            pars[2] = -cxy * s + cxz * c;

            pars[3] = cyx;
            pars[4] = cyy * c + cyz * s;
            pars[5] = -cyy * s + cyz * c;

            pars[6] = czx;
            pars[7] = czy * c + czz * s;
            pars[8] = -czy * s + czz * c;


            var buf =
                //new Matrix(3, 3);
                MatrixPool.Allocate(3, 3);

            buf.FillColumn(0, pars[0], pars[1], pars[2]);
            buf.FillColumn(1, pars[3], pars[4], pars[5]);
            buf.FillColumn(2, pars[6], pars[7], pars[8]);

            return(buf);
        }
        /// <summary>
        /// get the polynomial that takes iso coord as input and return local coord as output
        /// </summary>
        /// <returns>X(ξ) (ξ input, X output)</returns>
        public virtual Mathh.Polynomial GetIsoToLocalConverter()
        {
            var cachekey = "{54CEC6B2-F882-4505-9FC0-E7844C99F249}";

            Mathh.Polynomial chd;

            if (this.TryGetCache(cachekey, out chd)) //prevent double calculation
            {
                if (IsValidIsoToLocalConverter(chd)) //Validation of chached polynomial to see if is outdated due to change in node locations
                {
                    return(chd);
                }
            }

            chd = null;

            var targetElement = this;
            var bar           = this;

            Mathh.Polynomial x_xi = null;//x(ξ)

            var n = targetElement.Nodes.Length;

            var xs   = new double[n];
            var xi_s = new double[n];

            {
                //var conds = new List<Tuple<double, double>>();//x[i] , ξ[i]

                for (var i = 0; i < n; i++)
                {
                    var deltaXi = 2.0 / (n - 1);
                    var xi      = (bar.Nodes[i].Location - bar.Nodes[0].Location).Length;
                    var xi_i    = -1 + deltaXi * i;

                    xs[i]   = xi;
                    xi_s[i] = xi_i;

                    //conds.Add(Tuple.Create(xi, xi_i));
                }

                //polinomial degree of shape function is n-1


                var mtx =
                    //new Matrix(n, n);
                    MatrixPool.Allocate(n, n);

                var right =
                    //new Matrix(n, 1);
                    MatrixPool.Allocate(n, 1);

                //var o = n - 1;

                for (var i = 0; i < n; i++)
                {
                    //fill row i'th of mtx

                    //x[i] = { ξ[i]^o, ξ[i]^o-1 ... ξ[i]^1 ξ[i]^0} * {a[o] a[o-1] ... a[1] a[0]}'

                    var kesi_i = xi_s[i];

                    for (var j = 0; j < n; j++)
                    {
                        mtx[i, j]   = Math.Pow(kesi_i, n - j - 1);
                        right[i, 0] = xs[i];
                    }
                }

                //var as_ = mtx.Inverse() * right;
                var as_ = mtx.Solve(right.CoreArray);

                x_xi = new Mathh.Polynomial(as_);


                right.ReturnToPool();
                mtx.ReturnToPool();
            }

            SetCache(cachekey, x_xi);

            return(x_xi);
        }
        /// <summary>
        /// Computes the I.
        /// </summary>
        /// <returns>The I</returns>
        public Matrix Integrate()
        {
            if (MatrixPool == null)
            {
                MatrixPool = new MatrixPool();
            }


            if (XiPointCount < 1 || EtaPointCount < 1 || GammaPointCount < 1)
            {
                throw new NotSupportedException();
            }

            double a1 = A1, a2 = A2;

            var f1 = F1;
            var f2 = F2;

            var g1 = G1;
            var g2 = G2;

            var vk = GaussPoints.GetGaussianValues(GammaPointCount);
            var wk = GaussPoints.GetGaussianWeights(GammaPointCount);

            var vj = GaussPoints.GetGaussianValues(EtaPointCount);
            var wj = GaussPoints.GetGaussianWeights(EtaPointCount);

            var vi = GaussPoints.GetGaussianValues(XiPointCount);
            var wi = GaussPoints.GetGaussianWeights(XiPointCount);

            Matrix I = null;//we do not know dimensions yet!

            for (var k = 0; k < GammaPointCount; k++)
            {
                var    gammaK = (a2 - a1) / 2 * vk[k] + (a2 + a1) / 2;
                Matrix phi    = null;// = new Matrix(H, W);

                for (var j = 0; j < EtaPointCount; j++)
                {
                    var    noj  = (f2(gammaK) - f1(gammaK)) / 2 * vj[j] + (f2(gammaK) + f1(gammaK)) / 2;
                    Matrix beta = null;//= new Matrix(H, W);

                    for (var i = 0; i < XiPointCount; i++)
                    {
                        var xii = (g2(noj, gammaK) - g1(noj, gammaK)) / 2 * vi[i] + (g2(noj, gammaK) + g1(noj, gammaK)) / 2;

                        var val = H.GetMatrix(xii, noj, gammaK);

                        //initiate I, phi and beta
                        if (beta == null)
                        {
                            beta =
                                //new Matrix(val.RowCount, val.ColumnCount);
                                MatrixPool.Allocate(val.RowCount, val.ColumnCount);
                        }

                        if (phi == null)
                        {
                            phi =
                                //new Matrix(val.RowCount, val.ColumnCount);
                                MatrixPool.Allocate(val.RowCount, val.ColumnCount);
                        }

                        if (I == null)
                        {
                            I =
                                //new Matrix(val.RowCount, val.ColumnCount);
                                MatrixPool.Allocate(val.RowCount, val.ColumnCount);
                        }

                        var valSc = (g2(noj, gammaK) - g1(noj, gammaK)) / 2 * wi[i];
                        //beta += val;
                        beta.AddToThis(val, valSc);

                        val.ReturnToPool();
                    }

                    var phiSc = (f2(gammaK) - f1(gammaK)) / 2 * wj[j];
                    phi.AddToThis(beta, phiSc);

                    beta.ReturnToPool();
                }

                var iSc = (a2 - a1) / 2 * wk[k];

                I.AddToThis(phi, iSc);

                phi.ReturnToPool();
                //I += (a2 - a1) / 2 * wk[k] * phi;
            }

            return(I);
        }
Esempio n. 13
0
        public static Matrix CalcLocalKMatrix_Triangle(IElementHelper helper, Element targetElement)
        {
            var qq = targetElement as TriangleElement;

            if (qq == null)
            {
                throw new Exception();
            }

            var trans = qq.GetLambdaMatrix().Transpose();

            var nb = helper.GetBMaxOrder(targetElement);
            var nd = qq.Material.GetMaxFunctionOrder();
            var nt = qq.Section.GetMaxFunctionOrder();
            var nj = helper.GetDetJOrder(targetElement);

            var sum = new int[3];

            foreach (var i in new int[][] { nb, nd, nb, nt, nj })
            {
                for (int j = 0; j < 3; j++)
                {
                    sum[j] += i[j];
                }
            }

            var nXi   = sum[0] / 2 + 1;
            var nEta  = sum[1] / 2 + 1;
            var nGama = sum[2] / 2 + 1;

            var intg = new GaussianIntegrator();

            intg.GammaPointCount = nGama;
            intg.XiPointCount    = nXi;
            intg.EtaPointCount   = nEta;

            intg.A2 = 1;
            intg.A1 = 0;

            intg.F2 = (gama => 1);
            intg.F1 = (gama => 0);

            intg.G2 = ((eta, gama) => 1 - eta);
            intg.G1 = ((eta, gama) => 0);

            intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
            {
                var b = helper.GetBMatrixAt(qq, xi, eta);
                var d = helper.GetDMatrixAt(qq, xi, eta);
                var j = helper.GetJMatrixAt(qq, xi, eta);

                var buf = MatrixPool.Allocate(b.ColumnCount, b.ColumnCount);

                CalcUtil.Bt_D_B(b, d, buf);

                buf.MultiplyByConstant((j.Determinant()));

                return(buf);
            });

            var res = intg.Integrate();

            return(res);
        }
Esempio n. 14
0
        /**
         * /// Loads the sphinx3 density file, a set of density arrays are created and
         * /// placed in the given pool.
         * ///
         * /// @param useCDUnits
         * ///            if true, loads also the context dependent units
         * /// @param inputStream
         * ///            the open input stream to use
         * /// @param path
         * ///            the path to a density file
         * /// @throws FileNotFoundException
         * ///             if a file cannot be found
         * /// @throws IOException
         * ///             if an error occurs while loading the data
         */
        protected void LoadHMMPool(Boolean useCDUnits, Stream inputStream,
                                   string path)
        {
            var est = new ExtendedStreamTokenizer(inputStream,
                                                  '#', false);

            this.LogInfo("Loading HMM file from: " + path);

            est.ExpectString(ModelVersion);

            var numBase = est.GetInt("numBase");

            est.ExpectString("n_base");

            var numTri = est.GetInt("numTri");

            est.ExpectString("n_tri");

            var numStateMap = est.GetInt("numStateMap");

            est.ExpectString("n_state_map");

            var numTiedState = est.GetInt("numTiedState");

            est.ExpectString("n_tied_state");

            var numContextIndependentTiedState = est
                                                 .GetInt("numContextIndependentTiedState");

            est.ExpectString("n_tied_ci_state");

            var numTiedTransitionMatrices = est.GetInt("numTiedTransitionMatrices");

            est.ExpectString("n_tied_tmat");

            var numStatePerHMM = numStateMap / (numTri + numBase);

            Debug.Assert(numTiedState == MixtureWeightsPool.StatesNum);
            Debug.Assert(numTiedTransitionMatrices == MatrixPool.Size);

            // Load the base phones
            for (var i = 0; i < numBase; i++)
            {
                var name      = est.GetString();
                var left      = est.GetString();
                var right     = est.GetString();
                var position  = est.GetString();
                var attribute = est.GetString();
                var tmat      = est.GetInt("tmat");

                var stid = new int[numStatePerHMM - 1];

                for (var j = 0; j < numStatePerHMM - 1; j++)
                {
                    stid[j] = est.GetInt("j");
                    Debug.Assert(stid[j] >= 0 && stid[j] < numContextIndependentTiedState);
                }
                est.ExpectString("N");

                Debug.Assert(left.Equals("-"));
                Debug.Assert(right.Equals("-"));
                Debug.Assert(position.Equals("-"));
                Debug.Assert(tmat < numTiedTransitionMatrices);

                var unit = _unitManager.GetUnit(name, attribute.Equals(Filler));
                ContextIndependentUnits.Put(unit.Name, unit);


                //this.LogInfo("Loaded " + unit.ToString());

                // The first filler
                if (unit.IsFiller && unit.Name.Equals(SilenceCiphone))
                {
                    unit = UnitManager.Silence;
                }

                var transitionMatrix = MatrixPool.Get(tmat);
                var ss = GetSenoneSequence(stid);

                IHMM hmm = new SenoneHMM(unit, ss, transitionMatrix, GetHMMPosition(position));
                HmmManager.Put(hmm);
            }

            if (HmmManager.Get(HMMPosition.Undefined, UnitManager.Silence) == null)
            {
                throw new IOException("Could not find SIL unit in acoustic model");
            }

            // Load the context dependent phones. If the useCDUnits
            // property is false, the CD phones will not be created, but
            // the values still need to be read in from the file.

            var  lastUnitName = "";
            Unit lastUnit     = null;

            int[]          lastStid           = null;
            SenoneSequence lastSenoneSequence = null;

            for (var i = 0; i < numTri; i++)
            {
                var name      = est.GetString();
                var left      = est.GetString();
                var right     = est.GetString();
                var position  = est.GetString();
                var attribute = est.GetString();
                var tmat      = est.GetInt("tmat");

                var stid = new int[numStatePerHMM - 1];

                for (var j = 0; j < numStatePerHMM - 1; j++)
                {
                    stid[j] = est.GetInt("j");
                    Debug.Assert(stid[j] >= numContextIndependentTiedState &&
                                 stid[j] < numTiedState);
                }
                est.ExpectString("N");

                Debug.Assert(!left.Equals("-"));
                Debug.Assert(!right.Equals("-"));
                Debug.Assert(!position.Equals("-"));
                Debug.Assert(attribute.Equals("n/a"));
                Debug.Assert(tmat < numTiedTransitionMatrices);

                if (useCDUnits)
                {
                    Unit unit;
                    var  unitName = (name + ' ' + left + ' ' + right);

                    if (unitName.Equals(lastUnitName))
                    {
                        unit = lastUnit;
                    }
                    else
                    {
                        var leftContext = new Unit[1];
                        leftContext[0] = ContextIndependentUnits.Get(left);

                        var rightContext = new Unit[1];
                        rightContext[0] = ContextIndependentUnits.Get(right);

                        Context context = LeftRightContext.Get(leftContext,
                                                               rightContext);
                        unit = _unitManager.GetUnit(name, false, context);
                    }
                    lastUnitName = unitName;
                    lastUnit     = unit;


                    //this.LogInfo("Loaded " + unit.ToString());


                    var transitionMatrix = MatrixPool.Get(tmat);

                    var ss = lastSenoneSequence;
                    if (ss == null || !SameSenoneSequence(stid, lastStid))
                    {
                        ss = GetSenoneSequence(stid);
                    }
                    lastSenoneSequence = ss;
                    lastStid           = stid;

                    IHMM hmm = new SenoneHMM(unit, ss, transitionMatrix, GetHMMPosition(position));
                    HmmManager.Put(hmm);
                }
            }

            est.Close();
        }
Esempio n. 15
0
        /// <inheritdoc/>
        public Matrix GetBMatrixAt(Element targetElement, params double[] isoCoords)
        {
            var tri = targetElement as TriangleElement;

            if (tri == null)
            {
                throw new Exception();
            }

            var xi  = isoCoords[0];
            var eta = isoCoords[1];

            #region inits

            var mgr = targetElement.GetTransformationManager();//TransformManagerL2G.MakeFromTransformationMatrix(transformMatrix);

            var p1l = mgr.TransformGlobalToLocal(tri.Nodes[0].Location);
            var p2l = mgr.TransformGlobalToLocal(tri.Nodes[1].Location);
            var p3l = mgr.TransformGlobalToLocal(tri.Nodes[2].Location);

            var p23 = p2l - p3l;
            var p31 = p3l - p1l;
            var p12 = p1l - p2l;

            var x23 = p23.X;
            var x31 = p31.X;
            var x12 = p12.X;

            var y23 = p23.Y;
            var y31 = p31.Y;
            var y12 = p12.Y;

            var a = 0.5 * Math.Abs(x31 * y12 - x12 * y31);

            var l23_2 = y23 * y23 + x23 * x23;
            var l31_2 = y31 * y31 + x31 * x31;
            var l12_2 = y12 * y12 + x12 * x12;

            var P4 = -6 * x23 / l23_2;
            var P5 = -6 * x31 / l31_2;
            var P6 = -6 * x12 / l12_2;

            var q4 = 3 * x23 * y23 / l23_2;
            var q5 = 3 * x31 * y31 / l31_2;
            var q6 = 3 * x12 * y12 / l12_2;

            var r4 = 3 * y23 * y23 / l23_2;
            var r5 = 3 * y31 * y31 / l31_2;
            var r6 = 3 * y12 * y12 / l12_2;

            var t4 = -6 * y23 / l23_2;
            var t5 = -6 * y31 / l31_2;
            var t6 = -6 * y12 / l12_2;

            #endregion

            #region h{x,y}{kesi,no}

            var hx_xi = new double[]//eq. 4.27 ref [1], also noted in several other references
            {
                P6 *(1 - 2 * xi) + (P5 - P6) * eta,
                q6 *(1 - 2 * xi) - (q5 + q6) * eta,
                -4 + 6 * (xi + eta) + r6 * (1 - 2 * xi) - eta * (r5 + r6),
                -P6 * (1 - 2 * xi) + eta * (P4 + P6),
                q6 *(1 - 2 * xi) - eta * (q6 - q4),
                -2 + 6 * xi + r6 * (1 - 2 * xi) + eta * (r4 - r6),
                -eta * (P5 + P4),
                eta *(q4 - q5),
                -eta * (r5 - r4)
            };

            var hy_xi = new double[] //eq. 4.28 ref [1], also noted in several other references
            {
                t6 *(1 - 2 * xi) + eta * (t5 - t6),
                1 + r6 * (1 - 2 * xi) - eta * (r5 + r6),
                -q6 * (1 - 2 * xi) + eta * (q5 + q6),
                -t6 * (1 - 2 * xi) + eta * (t4 + t6),
                -1 + r6 * (1 - 2 * xi) + eta * (r4 - r6),
                -q6 * (1 - 2 * xi) - eta * (q4 - q6),
                -eta * (t4 + t5),
                eta *(r4 - r5),
                -eta * (q4 - q5)
            };


            var hx_eta = new double[] //eq. 4.29 ref [1], also noted in several other references
            {
                -P5 * (1 - 2 * eta) - xi * (P6 - P5),
                q5 *(1 - 2 * eta) - xi * (q5 + q6),
                -4 + 6 * (xi + eta) + r5 * (1 - 2 * eta) - xi * (r5 + r6),
                xi *(P4 + P6),
                xi *(q4 - q6),
                -xi * (r6 - r4),
                P5 *(1 - 2 * eta) - xi * (P4 + P5),
                q5 *(1 - 2 * eta) + xi * (q4 - q5),
                -2 + 6 * eta + r5 * (1 - 2 * eta) + xi * (r4 - r5)
            };

            var hy_eta = new double[] //eq. 4.30 ref [1], also noted in several other references
            {
                -t5 * (1 - 2 * eta) - xi * (t6 - t5),
                1 + r5 * (1 - 2 * eta) - xi * (r5 + r6),
                -q5 * (1 - 2 * eta) + xi * (q5 + q6),
                xi *(t4 + t6),
                xi *(r4 - r6),
                -xi * (q4 - q6),
                t5 *(1 - 2 * eta) - xi * (t4 + t5),
                -1 + r5 * (1 - 2 * eta) + xi * (r4 - r5),
                -q5 * (1 - 2 * eta) - xi * (q4 - q5)
            };

            #endregion

            var buf = MatrixPool.Allocate(3, 9);

            for (var i = 0; i < 9; i++)
            {
                buf[0, i] = y31 * hx_xi[i] + y12 * hx_eta[i];
                buf[1, i] = -x31 * hy_xi[i] - x12 * hy_eta[i];
                buf[2, i] = -x31 * hx_xi[i] - x12 * hx_eta[i] + y31 * hy_xi[i] + y12 * hy_eta[i];
            }//eq. 4.26 page 46 ref [1]

            buf.MultiplyByConstant(1 / (2 * a));

            return(buf);
        }