private void CreateLinearShell(int elementDegreeKsi, int elementDegreeHeta, Matrix extractionOperator, int[] connectivity) { Element element = new TSplineKirchhoffLoveShellElement() { ID = elementIDCounter, Patch = _model.PatchesDictionary[0], ElementType = new TSplineKirchhoffLoveShellElement(), DegreeKsi = elementDegreeKsi, DegreeHeta = elementDegreeHeta, ExtractionOperator = extractionOperator }; for (int cp = 0; cp < connectivity.Length; cp++) { element.AddControlPoint(_model.ControlPointsDictionary[connectivity[cp]]); } _model.ElementsDictionary.Add(elementIDCounter++, element); _model.PatchesDictionary[0].Elements.Add(element); }
/// <summary> /// Two-dimensional T-spline shape functions from Bezier extraction for <see cref="TSplineKirchhoffLoveShellElement"/>. /// </summary> /// <param name="element">An <see cref="Element"/> of type <see cref="TSplineKirchhoffLoveShellElement"/>.</param> /// <param name="controlPoints">A <see cref="List{T}"/> containing the control points of the element.</param> public ShapeTSplines2DFromBezierExtraction(TSplineKirchhoffLoveShellElement element, ControlPoint[] controlPoints) { GaussQuadrature gauss = new GaussQuadrature(); IList <GaussLegendrePoint3D> gaussPoints = gauss.CalculateElementGaussPoints(element.DegreeKsi, element.DegreeHeta, new List <Knot> { new Knot() { ID = 0, Ksi = -1, Heta = -1, Zeta = 0 }, new Knot() { ID = 1, Ksi = -1, Heta = 1, Zeta = 0 }, new Knot() { ID = 2, Ksi = 1, Heta = -1, Zeta = 0 }, new Knot() { ID = 3, Ksi = 1, Heta = 1, Zeta = 0 } }); var parametricGaussPointKsi = Vector.CreateZero(element.DegreeKsi + 1); for (int i = 0; i < element.DegreeKsi + 1; i++) { parametricGaussPointKsi[i] = gaussPoints[i * (element.DegreeHeta + 1)].Ksi; } var parametricGaussPointHeta = Vector.CreateZero(element.DegreeHeta + 1); for (int i = 0; i < element.DegreeHeta + 1; i++) { parametricGaussPointHeta[i] = gaussPoints[i].Heta; } Vector knotValueVectorKsi = Vector.CreateZero((element.DegreeKsi + 1) * 2); Vector knotValueVectorHeta = Vector.CreateZero((element.DegreeHeta + 1) * 2); for (int i = 0; i < element.DegreeKsi + 1; i++) { knotValueVectorKsi[i] = -1; knotValueVectorKsi[element.DegreeKsi + 1 + i] = 1; } for (int i = 0; i < element.DegreeHeta + 1; i++) { knotValueVectorHeta[i] = -1; knotValueVectorHeta[element.DegreeHeta + 1 + i] = 1; } BSPLines1D bernsteinKsi = new BSPLines1D(element.DegreeKsi, knotValueVectorKsi, parametricGaussPointKsi); BSPLines1D bernsteinHeta = new BSPLines1D(element.DegreeHeta, knotValueVectorHeta, parametricGaussPointHeta); bernsteinKsi.calculateBSPLinesAndDerivatives(); bernsteinHeta.calculateBSPLinesAndDerivatives(); int supportKsi = element.DegreeKsi + 1; int supportHeta = element.DegreeHeta + 1; var bKsi = MatrixPart(supportKsi, bernsteinKsi.BSPLineValues); var bdKsi = MatrixPart(supportKsi, bernsteinKsi.BSPLineDerivativeValues); var bddKsi = MatrixPart(supportKsi, bernsteinKsi.BSPLineSecondDerivativeValues); var bheta = MatrixPart(supportHeta, bernsteinHeta.BSPLineValues); var bdheta = MatrixPart(supportHeta, bernsteinHeta.BSPLineDerivativeValues); var bddheta = MatrixPart(supportHeta, bernsteinHeta.BSPLineSecondDerivativeValues); var bernsteinShapeFunctions = KroneckerProduct(bKsi, bheta); Matrix bernsteinShapeFunctionDerivativesKsi = KroneckerProduct(bheta, bdKsi); Matrix bernsteinShapeFunctionDerivativesHeta = KroneckerProduct(bdheta, bKsi); Matrix bernsteinShapeFunctionSecondDerivativesKsi = KroneckerProduct(bheta, bddKsi); Matrix bernsteinShapeFunctionSecondDerivativesHeta = KroneckerProduct(bddheta, bKsi); Matrix bernsteinShapeFunctionSecondDerivativesKsiHeta = KroneckerProduct(bdheta, bdKsi); Matrix rationalTSplines = element.ExtractionOperator * bernsteinShapeFunctions; Matrix rationalTSplineDerivativesKsi = element.ExtractionOperator * bernsteinShapeFunctionDerivativesKsi; Matrix rationalTSplineDerivativesHeta = element.ExtractionOperator * bernsteinShapeFunctionDerivativesHeta; Matrix rationalTSplineSecondDerivativesKsi = element.ExtractionOperator * bernsteinShapeFunctionSecondDerivativesKsi; Matrix rationalTSplineSecondDerivativesHeta = element.ExtractionOperator * bernsteinShapeFunctionSecondDerivativesHeta; Matrix rationalTSplineSecondDerivativesKsiHeta = element.ExtractionOperator * bernsteinShapeFunctionSecondDerivativesKsiHeta; TSplineValues = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineDerivativeValuesKsi = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineDerivativeValuesHeta = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineSecondDerivativesValueKsi = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineSecondDerivativesValueHeta = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineSecondDerivativesValueKsiHeta = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); for (int i = 0; i < supportKsi; i++) { for (int j = 0; j < supportHeta; j++) { double sumKsiHeta = 0; double sumdKsiHeta = 0; double sumKsidHeta = 0; double sumdKsidKsi = 0; double sumdHetadHeta = 0; double sumdKsidHeta = 0; var index = i * supportHeta + j; for (int k = 0; k < controlPoints.Length; k++) { sumKsiHeta += rationalTSplines[k, index] * controlPoints[k].WeightFactor; sumdKsiHeta += rationalTSplineDerivativesKsi[k, index] * controlPoints[k].WeightFactor; sumKsidHeta += rationalTSplineDerivativesHeta[k, index] * controlPoints[k].WeightFactor; sumdKsidKsi += rationalTSplineSecondDerivativesKsi[k, index] * controlPoints[k].WeightFactor; sumdHetadHeta += rationalTSplineSecondDerivativesHeta[k, index] * controlPoints[k].WeightFactor; sumdKsidHeta += rationalTSplineSecondDerivativesKsiHeta[k, index] * controlPoints[k].WeightFactor; } for (int k = 0; k < controlPoints.Length; k++) { TSplineValues[k, index] = rationalTSplines[k, index] * controlPoints[k].WeightFactor / sumKsiHeta; TSplineDerivativeValuesKsi[k, index] = (rationalTSplineDerivativesKsi[k, index] * sumKsiHeta - rationalTSplines[k, index] * sumdKsiHeta) / Math.Pow(sumKsiHeta, 2) * controlPoints[k].WeightFactor; TSplineDerivativeValuesHeta[k, index] = (rationalTSplineDerivativesHeta[k, index] * sumKsiHeta - rationalTSplines[k, index] * sumKsidHeta) / Math.Pow(sumKsiHeta, 2) * controlPoints[k].WeightFactor; TSplineSecondDerivativesValueKsi[k, index] = (rationalTSplineSecondDerivativesKsi[k, index] / sumKsiHeta - 2 * rationalTSplineDerivativesKsi[k, index] * sumdKsiHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplines[k, index] * sumdKsidKsi / Math.Pow(sumKsiHeta, 2) + 2 * rationalTSplines[k, index] * Math.Pow(sumdKsiHeta, 2) / Math.Pow(sumKsiHeta, 3)) * controlPoints[k].WeightFactor; TSplineSecondDerivativesValueHeta[k, index] = (rationalTSplineSecondDerivativesHeta[k, index] / sumKsiHeta - 2 * rationalTSplineDerivativesHeta[k, index] * sumKsidHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplines[k, index] * sumdHetadHeta / Math.Pow(sumKsiHeta, 2) + 2 * rationalTSplines[k, index] * Math.Pow(sumKsidHeta, 2) / Math.Pow(sumKsiHeta, 3)) * controlPoints[k].WeightFactor; TSplineSecondDerivativesValueKsiHeta[k, index] = (rationalTSplineSecondDerivativesKsiHeta[k, index] / sumKsiHeta - rationalTSplineDerivativesKsi[k, index] * sumKsidHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplineDerivativesHeta[k, index] * sumdKsiHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplines[k, index] * sumdKsidHeta / Math.Pow(sumKsiHeta, 2) + 2 * rationalTSplines[k, index] * sumdKsiHeta * sumKsidHeta / Math.Pow(sumKsiHeta, 3)) * controlPoints[k].WeightFactor; } } } }
/// <summary> /// Two-dimensional T-spline shape functions from Bezier extraction for <see cref="TSplineKirchhoffLoveShellElement"/>. /// </summary> /// <param name="element">An <see cref="Element"/> of type <see cref="TSplineKirchhoffLoveShellElement"/>.</param> /// <param name="controlPoints">A <see cref="List{T}"/> containing the control points of the element.</param> /// <param name="parametricGaussPointKsi">An <see cref="IVector"/> containing Gauss points of axis Ksi.</param> /// <param name="parametricGaussPointHeta">An <see cref="IVector"/> containing Gauss points of axis Heta.</param> public ShapeTSplines2DFromBezierExtraction(TSplineKirchhoffLoveShellElement element, ControlPoint[] controlPoints, Vector parametricGaussPointKsi, Vector parametricGaussPointHeta) { Vector knotValueVectorKsi = Vector.CreateZero((element.DegreeKsi + 1) * 2); Vector knotValueVectorHeta = Vector.CreateZero((element.DegreeHeta + 1) * 2); for (int i = 0; i < element.DegreeKsi + 1; i++) { knotValueVectorKsi[i] = -1; knotValueVectorKsi[element.DegreeKsi + 1 + i] = 1; } for (int i = 0; i < element.DegreeHeta + 1; i++) { knotValueVectorHeta[i] = -1; knotValueVectorHeta[element.DegreeHeta + 1 + i] = 1; } BSPLines1D bernsteinKsi = new BSPLines1D(element.DegreeKsi, knotValueVectorKsi, parametricGaussPointKsi); BSPLines1D bernsteinHeta = new BSPLines1D(element.DegreeHeta, knotValueVectorHeta, parametricGaussPointHeta); bernsteinKsi.calculateBSPLinesAndDerivatives(); bernsteinHeta.calculateBSPLinesAndDerivatives(); int supportElementKsi = element.DegreeKsi + 1; int supportElementHeta = element.DegreeHeta + 1; int supportKsi = parametricGaussPointKsi.Length; int supportHeta = parametricGaussPointHeta.Length; var bKsi = MatrixPart(supportElementKsi, supportKsi, bernsteinKsi.BSPLineValues); var bdKsi = MatrixPart(supportElementKsi, supportKsi, bernsteinKsi.BSPLineDerivativeValues); var bddKsi = MatrixPart(supportElementKsi, supportKsi, bernsteinKsi.BSPLineSecondDerivativeValues); var bheta = MatrixPart(supportElementHeta, supportHeta, bernsteinHeta.BSPLineValues); var bdheta = MatrixPart(supportElementHeta, supportHeta, bernsteinHeta.BSPLineDerivativeValues); var bddheta = MatrixPart(supportElementHeta, supportHeta, bernsteinHeta.BSPLineSecondDerivativeValues); var bernsteinShapeFunctions = KroneckerProduct(bKsi, bheta); Matrix bernsteinShapeFunctionDerivativesKsi = KroneckerProduct(bheta, bdKsi); Matrix bernsteinShapeFunctionDerivativesHeta = KroneckerProduct(bdheta, bKsi); Matrix bernsteinShapeFunctionSecondDerivativesKsi = KroneckerProduct(bheta, bddKsi); Matrix bernsteinShapeFunctionSecondDerivativesHeta = KroneckerProduct(bddheta, bKsi); Matrix bernsteinShapeFunctionSecondDerivativesKsiHeta = KroneckerProduct(bdheta, bdKsi); Matrix rationalTSplines = element.ExtractionOperator * bernsteinShapeFunctions; Matrix rationalTSplineDerivativesKsi = element.ExtractionOperator * bernsteinShapeFunctionDerivativesKsi; Matrix rationalTSplineDerivativesHeta = element.ExtractionOperator * bernsteinShapeFunctionDerivativesHeta; Matrix rationalTSplineSecondDerivativesKsi = element.ExtractionOperator * bernsteinShapeFunctionSecondDerivativesKsi; Matrix rationalTSplineSecondDerivativesHeta = element.ExtractionOperator * bernsteinShapeFunctionSecondDerivativesHeta; Matrix rationalTSplineSecondDerivativesKsiHeta = element.ExtractionOperator * bernsteinShapeFunctionSecondDerivativesKsiHeta; TSplineValues = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineDerivativeValuesKsi = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineDerivativeValuesHeta = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineSecondDerivativesValueKsi = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineSecondDerivativesValueHeta = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); TSplineSecondDerivativesValueKsiHeta = Matrix.CreateZero(controlPoints.Length, supportKsi * supportHeta); for (int i = 0; i < supportKsi; i++) { for (int j = 0; j < supportHeta; j++) { double sumKsiHeta = 0; double sumdKsiHeta = 0; double sumKsidHeta = 0; double sumdKsidKsi = 0; double sumdHetadHeta = 0; double sumdKsidHeta = 0; var index = i * supportHeta + j; for (int k = 0; k < controlPoints.Length; k++) { sumKsiHeta += rationalTSplines[k, index] * controlPoints[k].WeightFactor; sumdKsiHeta += rationalTSplineDerivativesKsi[k, index] * controlPoints[k].WeightFactor; sumKsidHeta += rationalTSplineDerivativesHeta[k, index] * controlPoints[k].WeightFactor; sumdKsidKsi += rationalTSplineSecondDerivativesKsi[k, index] * controlPoints[k].WeightFactor; sumdHetadHeta += rationalTSplineSecondDerivativesHeta[k, index] * controlPoints[k].WeightFactor; sumdKsidHeta += rationalTSplineSecondDerivativesKsiHeta[k, index] * controlPoints[k].WeightFactor; } for (int k = 0; k < controlPoints.Length; k++) { TSplineValues[k, index] = rationalTSplines[k, index] * controlPoints[k].WeightFactor / sumKsiHeta; TSplineDerivativeValuesKsi[k, index] = (rationalTSplineDerivativesKsi[k, index] * sumKsiHeta - rationalTSplines[k, index] * sumdKsiHeta) / Math.Pow(sumKsiHeta, 2) * controlPoints[k].WeightFactor; TSplineDerivativeValuesHeta[k, index] = (rationalTSplineDerivativesHeta[k, index] * sumKsiHeta - rationalTSplines[k, index] * sumKsidHeta) / Math.Pow(sumKsiHeta, 2) * controlPoints[k].WeightFactor; TSplineSecondDerivativesValueKsi[k, index] = (rationalTSplineSecondDerivativesKsi[k, index] / sumKsiHeta - 2 * rationalTSplineDerivativesKsi[k, index] * sumdKsiHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplines[k, index] * sumdKsidKsi / Math.Pow(sumKsiHeta, 2) + 2 * rationalTSplines[k, index] * Math.Pow(sumdKsiHeta, 2) / Math.Pow(sumKsiHeta, 3)) * controlPoints[k].WeightFactor; TSplineSecondDerivativesValueHeta[k, index] = (rationalTSplineSecondDerivativesHeta[k, index] / sumKsiHeta - 2 * rationalTSplineDerivativesHeta[k, index] * sumKsidHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplines[k, index] * sumdHetadHeta / Math.Pow(sumKsiHeta, 2) + 2 * rationalTSplines[k, index] * Math.Pow(sumKsidHeta, 2) / Math.Pow(sumKsiHeta, 3)) * controlPoints[k].WeightFactor; TSplineSecondDerivativesValueKsiHeta[k, index] = (rationalTSplineSecondDerivativesKsiHeta[k, index] / sumKsiHeta - rationalTSplineDerivativesKsi[k, index] * sumKsidHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplineDerivativesHeta[k, index] * sumdKsiHeta / Math.Pow(sumKsiHeta, 2) - rationalTSplines[k, index] * sumdKsidHeta / Math.Pow(sumKsiHeta, 2) + 2 * rationalTSplines[k, index] * sumdKsiHeta * sumKsidHeta / Math.Pow(sumKsiHeta, 3)) * controlPoints[k].WeightFactor; } } } }