// Compute thermal vector
        public override void thermalVector()
        {
            // Zeros to thermal vector evec
            for (int i = 0; i < 16; i++)
            {
                evec[i] = 0.0;
            }
            int ld = (FeModel.stressState
                      == FeModel.StrStates.axisym) ? 4 : 3;

            // Material mat
            mat = (Material)fem.materials[matName];
            mat.elasticityMatrix(emat);
            double alpha = mat.getAlpha();
            double nu    = mat.getNu();

            // Gauss integration loop
            for (int ip = 0; ip < gh.nIntPoints; ip++)
            {
                // Set displacement differentiation matrix bmat
                double det = setBmatrix(gh.xii[ip], gh.eti[ip]);
                // Shape functions an
                ShapeQuad2D.shape(gh.xii[ip], gh.eti[ip], ind, an);
                double t = 0.0;
                for (int i = 0; i < 8; i++)
                {
                    t += an[i] * dtn[i];
                }
                double dv = det * gh.wi[ip];
                if (FeModel.stressState == FeModel.StrStates.axisym)
                {
                    dv *= 2.0 * Math.PI * r;
                }
                ept[0] = alpha * t;
                if (FeModel.stressState == FeModel.StrStates.plstrain)
                {
                    ept[0] *= (1 + nu);
                }
                ept[1] = ept[0];
                ept[2] = 0.0;
                ept[3] = ept[0];

                for (int i = 0; i < 16; i++)
                {
                    double s = 0;
                    for (int j = 0; j < ld; j++)
                    {
                        for (int k = 0; k < ld; k++)
                        {
                            s += bmat[k][i] * emat[j][k] * ept[j] * this.t;
                        }
                    }
                    evec[i] += s * dv;
                }
            }
        }
        // Get temperature at integration point (stress)
        public override double getTemperatureAtIntPoint(int ip)
        {
            ShapeQuad2D.shape(gs.xii[ip], gs.eti[ip], ind, an);
            double t = 0;

            for (int i = 0; i < 8; i++)
            {
                t += an[i] * dtn[i];
            }
            return(t);
        }
        // Set displacement differentiation matrix bmat.
        // xi, et - local coordinates,
        // returns  determinant of Jacobian matrix
        private double setBmatrix(double xi, double et)
        {
            // Derivatives of shape functions
            double det = ShapeQuad2D.deriv(xi, et, ind, xy, dnxy);

            if (det <= 0)
            {
                UTIL.errorMsg("Negative/zero 8Nr element area");
            }
            if (FeModel.stressState == FeModel.StrStates.axisym)
            {
                ShapeQuad2D.shape(xi, et, ind, an);
                r = 0.0;
                for (int i = 0; i < 8; i++)
                {
                    r += an[i] * xy[i][0];
                }
            }
            // Eight blocks of the displacement differentiation
            //   matrix
            for (int ib = 0; ib < 8; ib++)
            {
                bmat[0][2 * ib]     = dnxy[ib][0];
                bmat[0][2 * ib + 1] = 0.0;
                bmat[1][2 * ib]     = 0.0;
                bmat[1][2 * ib + 1] = dnxy[ib][1];
                bmat[2][2 * ib]     = dnxy[ib][1];
                bmat[2][2 * ib + 1] = dnxy[ib][0];
                if (FeModel.stressState == FeModel.StrStates.axisym)
                {
                    bmat[3][2 * ib]     = an[ib] / r;
                    bmat[3][2 * ib + 1] = 0.0;
                }
            }
            return(det);
        }