public ShapeNURBS2D(NURBSElement2D element, IGAModel model, IVector <double> parametricCoordinateKsi, IVector <double> parametricCoordinateHeta, IList <ControlPoint> controlPoints)
        {
            int numberOfCPHeta = model.KnotValueVectorHeta.Length - model.DegreeHeta - 1;

            BSPLines1D bsplinesKsi  = new BSPLines1D(model.DegreeKsi, model.KnotValueVectorKsi, parametricCoordinateKsi);
            BSPLines1D bsplinesHeta = new BSPLines1D(model.DegreeHeta, model.KnotValueVectorHeta, parametricCoordinateHeta);

            nurbsValues = new Matrix2D <double>((model.DegreeKsi + 1) * (model.DegreeHeta + 1), element.gaussPoints.Count);
            nurbsDerivativeValuesKsi  = new Matrix2D <double>((model.DegreeKsi + 1) * (model.DegreeHeta + 1), element.gaussPoints.Count);
            nurbsDerivativeValuesHeta = new Matrix2D <double>((model.DegreeKsi + 1) * (model.DegreeHeta + 1), element.gaussPoints.Count);

            int supportKsi  = model.DegreeKsi + 1;
            int supportHeta = model.DegreeHeta + 1;
            int numberOfElementGaussPoints = (model.DegreeKsi + 1) * (model.DegreeHeta + 1);

            for (int i = 0; i < supportKsi; i++)
            {
                for (int j = 0; j < supportHeta; j++)
                {
                    double sumKsiHeta  = 0;
                    double sumdKsiHeta = 0;
                    double sumKsidHeta = 0;

                    for (int k = 0; k < numberOfElementGaussPoints; k++)
                    {
                        sumKsiHeta += bsplinesKsi.BSPLValues[element.connectivity[k] / numberOfCPHeta, i] *
                                      bsplinesHeta.BSPLValues[element.connectivity[k] % numberOfCPHeta, j] *
                                      controlPoints[k].Weight;

                        sumdKsiHeta = +bsplinesKsi.BSPLDerivativeValues[element.connectivity[k] / numberOfCPHeta, i] *
                                      bsplinesHeta.BSPLDerivativeValues[element.connectivity[k] % numberOfCPHeta, j] *
                                      controlPoints[k].Weight;

                        sumKsidHeta = +bsplinesKsi.BSPLValues[element.connectivity[k] / numberOfCPHeta, i] *
                                      bsplinesHeta.BSPLDerivativeValues[element.connectivity[k] % numberOfCPHeta, j] *
                                      controlPoints[k].Weight;
                    }
                    for (int k = 0; k < numberOfElementGaussPoints; k++)
                    {
                        nurbsValues[k, i *supportHeta + j] = bsplinesKsi.BSPLValues[element.connectivity[k] / numberOfCPHeta, i] *
                                                             bsplinesHeta.BSPLValues[element.connectivity[k] % numberOfCPHeta, j] *
                                                             controlPoints[k].Weight / sumKsiHeta;

                        nurbsDerivativeValuesKsi[k, i *supportHeta + j] = bsplinesHeta.BSPLValues[element.connectivity[k] % numberOfCPHeta, j] * controlPoints[k].Weight *
                                                                          (bsplinesKsi.BSPLDerivativeValues[element.connectivity[k] / numberOfCPHeta, i] * sumKsiHeta -
                                                                           bsplinesKsi.BSPLValues[element.connectivity[k] / numberOfCPHeta, i] * sumdKsiHeta) / Math.Pow(sumKsiHeta, 2);

                        nurbsDerivativeValuesHeta[k, i *supportHeta + j] = bsplinesKsi.BSPLValues[element.connectivity[k] / numberOfCPHeta, i] *
                                                                           controlPoints[k].Weight *
                                                                           (bsplinesHeta.BSPLDerivativeValues[element.connectivity[k] % numberOfCPHeta, j] * sumKsiHeta -
                                                                            bsplinesHeta.BSPLValues[element.connectivity[k] % numberOfCPHeta, j] * sumKsidHeta) / Math.Pow(sumKsiHeta, 2);
                    }
                }
            }
        }
        public ShapeNURBS3D(NURBSElement3D element, IGAModel model, IVector <double> parametricCoordinateKsi, IVector <double> parametricCoordinateHeta, IVector <double> parametricCoordinateZeta, IList <ControlPoint> controlPoints)
        {
            int numberOfCPHeta = model.KnotValueVectorHeta.Length - model.DegreeHeta - 1;
            int numberOfCPZeta = model.KnotValueVectorZeta.Length - model.DegreeZeta - 1;

            BSPLines1D bsplinesKsi  = new BSPLines1D(model.DegreeKsi, model.KnotValueVectorKsi, parametricCoordinateKsi);
            BSPLines1D bsplinesHeta = new BSPLines1D(model.DegreeHeta, model.KnotValueVectorHeta, parametricCoordinateHeta);
            BSPLines1D bsplinesZeta = new BSPLines1D(model.DegreeZeta, model.KnotValueVectorZeta, parametricCoordinateZeta);

            nurbsValues = new Matrix2D <double>((model.DegreeKsi + 1) * (model.DegreeHeta + 1) * (model.DegreeZeta + 1), element.gaussPoints.Count);
            nurbsDerivativeValuesKsi  = new Matrix2D <double>((model.DegreeKsi + 1) * (model.DegreeHeta + 1) * (model.DegreeZeta + 1), element.gaussPoints.Count);
            nurbsDerivativeValuesHeta = new Matrix2D <double>((model.DegreeKsi + 1) * (model.DegreeHeta + 1) * (model.DegreeZeta + 1), element.gaussPoints.Count);
            nurbsDerivativeValuesZeta = new Matrix2D <double>((model.DegreeKsi + 1) * (model.DegreeHeta + 1) * (model.DegreeZeta + 1), element.gaussPoints.Count);

            int supportKsi  = model.DegreeKsi + 1;
            int supportHeta = model.DegreeHeta + 1;
            int supportZeta = model.DegreeZeta + 1;
            int numberOfElementGaussPoints = (model.DegreeKsi + 1) * (model.DegreeHeta + 1) * (model.DegreeZeta + 1);


            for (int i = 0; i < supportKsi; i++)
            {
                for (int j = 0; j < supportHeta; j++)
                {
                    for (int k = 0; k < supportZeta; k++)
                    {
                        double sumKsiHetaZeta  = 0;
                        double sumdKsiHetaZeta = 0;
                        double sumKsidHetaZeta = 0;
                        double sumKsiHetadZeta = 0;

                        for (int m = 0; m < numberOfElementGaussPoints; m++)
                        {
                            int indexKsi  = element.connectivity[m] / (numberOfCPHeta * numberOfCPZeta);
                            int indexHeta = element.connectivity[m] % (numberOfCPHeta * numberOfCPZeta) / numberOfCPZeta;
                            int indexZeta = element.connectivity[m] % (numberOfCPHeta * numberOfCPZeta) % numberOfCPZeta;

                            sumKsiHetaZeta += bsplinesKsi.BSPLValues[indexKsi, i] *
                                              bsplinesHeta.BSPLValues[indexHeta, j] *
                                              bsplinesZeta.BSPLValues[indexZeta, k] *
                                              controlPoints[m].Weight;

                            sumdKsiHetaZeta += bsplinesKsi.BSPLDerivativeValues[indexKsi, i] *
                                               bsplinesHeta.BSPLValues[indexHeta, j] *
                                               bsplinesZeta.BSPLValues[indexZeta, k] *
                                               controlPoints[m].Weight;

                            sumKsidHetaZeta += bsplinesKsi.BSPLValues[indexKsi, i] *
                                               bsplinesHeta.BSPLDerivativeValues[indexHeta, j] *
                                               bsplinesZeta.BSPLValues[indexZeta, k] *
                                               controlPoints[m].Weight;

                            sumKsiHetadZeta += bsplinesKsi.BSPLValues[indexKsi, i] *
                                               bsplinesHeta.BSPLValues[indexHeta, j] *
                                               bsplinesZeta.BSPLDerivativeValues[indexZeta, k] *
                                               controlPoints[m].Weight;
                        }
                        for (int m = 0; m < numberOfElementGaussPoints; m++)
                        {
                            int indexKsi  = element.connectivity[m] / (numberOfCPHeta * numberOfCPZeta);
                            int indexHeta = element.connectivity[m] % (numberOfCPHeta * numberOfCPZeta) / numberOfCPZeta;
                            int indexZeta = element.connectivity[m] % (numberOfCPHeta * numberOfCPZeta) % numberOfCPZeta;

                            nurbsValues[m, i *supportHeta *supportZeta + j * supportZeta + k] =
                                bsplinesKsi.BSPLValues[indexKsi, i] *
                                bsplinesHeta.BSPLValues[indexHeta, j] *
                                bsplinesZeta.BSPLValues[indexZeta, k] *
                                controlPoints[m].Weight / sumKsiHetaZeta;

                            nurbsDerivativeValuesKsi[m, i *supportHeta *supportZeta + j * supportZeta + k] =
                                (bsplinesKsi.BSPLDerivativeValues[indexKsi, i] * sumKsiHetaZeta -
                                 bsplinesKsi.BSPLValues[indexKsi, i] * sumdKsiHetaZeta) *
                                bsplinesHeta.BSPLValues[indexHeta, j] *
                                bsplinesZeta.BSPLValues[indexZeta, k] *
                                controlPoints[m].Weight / Math.Pow(sumKsiHetaZeta, 2);

                            nurbsDerivativeValuesHeta[m, i *supportHeta *supportZeta + j * supportZeta + k] =
                                bsplinesKsi.BSPLValues[indexKsi, i] *
                                (bsplinesHeta.BSPLDerivativeValues[indexHeta, j] * sumKsiHetaZeta -
                                 bsplinesHeta.BSPLValues[indexHeta, j] * sumKsidHetaZeta) *
                                bsplinesZeta.BSPLValues[indexZeta, k] *
                                controlPoints[m].Weight / Math.Pow(sumKsiHetaZeta, 2);

                            nurbsDerivativeValuesZeta[m, i *supportHeta *supportZeta + j * supportZeta + k] =
                                bsplinesKsi.BSPLValues[indexKsi, i] *
                                bsplinesHeta.BSPLValues[indexHeta, j] *
                                (bsplinesZeta.BSPLDerivativeValues[indexZeta, k] * sumKsiHetaZeta -
                                 bsplinesZeta.BSPLValues[indexZeta, k] * sumKsiHetadZeta) *
                                controlPoints[m].Weight / Math.Pow(sumKsiHetaZeta, 2);
                        }
                    }
                }
            }
        }