private IReadOnlyList <Matrix> EvaluateNaturalGradientsAtGaussPoints(IQuadrature1D quadrature)
        {
            bool isCached = cachedNaturalGradientsAtGPs.TryGetValue(quadrature,
                                                                    out IReadOnlyList <Matrix> naturalGradientsAtGPs);

            if (isCached)
            {
                return(naturalGradientsAtGPs);
            }
            else
            {
                int numGPs = quadrature.IntegrationPoints.Count;
                var naturalGradientsAtGPsArray = new Matrix[numGPs];
                for (int gp = 0; gp < numGPs; ++gp)
                {
                    GaussPoint gaussPoint = quadrature.IntegrationPoints[gp];
                    naturalGradientsAtGPsArray[gp] = EvaluateGradientsAt();
                }
                cachedNaturalGradientsAtGPs.Add(quadrature, naturalGradientsAtGPsArray);
                return(naturalGradientsAtGPsArray);
            }
        }
        public IReadOnlyList <Vector> EvaluateFunctionsAtGaussPoints(IQuadrature1D quadrature)
        {
            bool isCached = cachedFunctionsAtGPs.TryGetValue(quadrature,
                                                             out IReadOnlyList <Vector> shapeFunctionsAtGPs);

            if (isCached)
            {
                return(shapeFunctionsAtGPs);
            }
            else
            {
                int numGPs = quadrature.IntegrationPoints.Count;
                var shapeFunctionsAtGPsArray = new Vector[numGPs];
                for (int gp = 0; gp < numGPs; ++gp)
                {
                    GaussPoint gaussPoint = quadrature.IntegrationPoints[gp];
                    shapeFunctionsAtGPsArray[gp] = Vector.CreateFromArray(EvaluateAt(gaussPoint.Xi));
                }
                cachedFunctionsAtGPs.Add(quadrature, shapeFunctionsAtGPsArray);
                return(shapeFunctionsAtGPsArray);
            }
        }
        public IReadOnlyList <EvalInterpolation1D> EvaluateAllAtGaussPoints(IReadOnlyList <Node> nodes, IQuadrature1D quadrature)
        {
            // The shape functions and natural derivatives at each Gauss point are probably cached from previous calls
            IReadOnlyList <Vector> shapeFunctionsAtGPs          = EvaluateFunctionsAtGaussPoints(quadrature);
            IReadOnlyList <Matrix> naturalShapeDerivativesAtGPs = EvaluateNaturalGradientsAtGaussPoints(quadrature);

            // Calculate the Jacobians and shape derivatives w.r.t. global cartesian coordinates at each Gauss point
            int numGPs = quadrature.IntegrationPoints.Count;
            var interpolationsAtGPs = new EvalInterpolation1D[numGPs];

            //for (int gp = 0; gp < numGPs; ++gp)
            //{
            //    interpolationsAtGPs[gp] = new EvalInterpolation2D(shapeFunctionsAtGPs[gp],
            //        naturalShapeDerivativesAtGPs[gp], new IsoparametricJacobian2D(nodes, naturalShapeDerivativesAtGPs[gp]));
            //}
            return(interpolationsAtGPs);
        }