/// <summary> /// Calculates the cartesian coordinate of a parametric point. /// </summary> /// <param name="numberOfCPKsi">Number of <see cref="ControlPoint"/> in the parametric axis Ksi.</param> /// <param name="degreeKsi">Degree of splines for the parametric axis Ksi.</param> /// <param name="knotValueVectorKsi"> Knot Value Vector for the parametric axis Ksi.</param> /// <param name="numberOfCPHeta">Number of <see cref="ControlPoint"/> in the parametric axis Heta.</param> /// <param name="degreeHeta">Degree of splines for the parametric axis Heta.</param> /// <param name="knotValueVectorHeta"> Knot Value Vector for the parametric axis Heta.</param> /// <param name="numberOfCPZeta">Number of <see cref="ControlPoint"/> in the parametric axis Zeta.</param> /// <param name="degreeZeta">Degree of splines for the parametric axis Zeta.</param> /// <param name="knotValueVectorZeta"> Knot Value Vector for the parametric axis Zeta.</param> /// <param name="projectiveControlPointCoordinates">A <see cref="double"/> two dimensional array containing the projective coordinates of the control points.</param> /// <param name="ksiCoordinate">Parametric coordinate Ksi of the physical point to be evaluated.</param> /// <param name="hetaCoordinate">Parametric coordinate Heta of the physical point to be evaluated.</param> /// <param name="zetaCoordinate">Parametric coordinate Zeta of the physical point to be evaluated.</param> /// <returns>A <see cref="Vector"/> containing the physical coordinates of the solid point calculated.</returns> public static Vector SolidPoint3D(int numberOfCPKsi, int degreeKsi, Vector knotValueVectorKsi, int numberOfCPHeta, int degreeHeta, Vector knotValueVectorHeta, int numberOfCPZeta, int degreeZeta, Vector knotValueVectorZeta, double[,] projectiveControlPointCoordinates, double ksiCoordinate, double hetaCoordinate, double zetaCoordinate) { var spanKsi = ParaviewNurbs2D.FindSpan(numberOfCPKsi, degreeKsi, ksiCoordinate, knotValueVectorKsi); var spanHeta = ParaviewNurbs2D.FindSpan(numberOfCPHeta, degreeHeta, hetaCoordinate, knotValueVectorHeta); var spanZeta = ParaviewNurbs2D.FindSpan(numberOfCPZeta, degreeZeta, zetaCoordinate, knotValueVectorZeta); var pointFunctionsKsi = ParaviewNurbs2D.BasisFunctions(spanKsi, ksiCoordinate, degreeKsi, knotValueVectorKsi); var pointFunctionsHeta = ParaviewNurbs2D.BasisFunctions(spanHeta, hetaCoordinate, degreeHeta, knotValueVectorHeta); var pointFunctionsZeta = ParaviewNurbs2D.BasisFunctions(spanZeta, zetaCoordinate, degreeZeta, knotValueVectorZeta); var cartesianPoint = Vector.CreateZero(4); var indexKsi = spanKsi - degreeKsi; for (int k = 0; k <= degreeZeta; k++) { var indexZeta = spanZeta - degreeZeta + k; for (int j = 0; j <= degreeHeta; j++) { var indexHeta = spanHeta - degreeHeta + j; for (int i = 0; i <= degreeKsi; i++) { var cpIndex = (indexKsi + i) * (numberOfCPHeta + 1) * (numberOfCPZeta + 1) + indexHeta * (numberOfCPZeta + 1) + indexZeta; var cpCoordinates = Vector.CreateFromArray(new double[] { projectiveControlPointCoordinates[cpIndex, 0], projectiveControlPointCoordinates[cpIndex, 1], projectiveControlPointCoordinates[cpIndex, 2], projectiveControlPointCoordinates[cpIndex, 3] }); cpCoordinates.Scale(pointFunctionsKsi[i]); cpCoordinates.Scale(pointFunctionsHeta[j]); cpCoordinates.Scale(pointFunctionsZeta[k]); cartesianPoint = cartesianPoint + cpCoordinates; } } } return(cartesianPoint); }
/// <summary> /// Creates Paraview File of the NURBS Shells geometry. /// </summary> public void CreateParaview2DFile() { var uniqueKnotsKsi = _model.PatchesDictionary[0].KnotValueVectorKsi.RemoveDuplicatesFindMultiplicity(); var uniqueKnotsHeta = _model.PatchesDictionary[0].KnotValueVectorHeta.RemoveDuplicatesFindMultiplicity(); var numberOfKnotsKsi = uniqueKnotsKsi[0].Length; var numberOfKnotsHeta = uniqueKnotsHeta[0].Length; var knots = new double[numberOfKnotsKsi * numberOfKnotsHeta, 3]; var count = 0; var patch = _model.PatchesDictionary[0]; var projectiveControlPoints = CalculateProjectiveControlPoints(); for (var knotKsiIndex = 0; knotKsiIndex < numberOfKnotsKsi; knotKsiIndex++) { for (var knotHetaIndex = 0; knotHetaIndex < numberOfKnotsHeta; knotHetaIndex++) { var hetaCoordinate = uniqueKnotsHeta[0][knotHetaIndex]; var ksiCoordinate = uniqueKnotsKsi[0][knotKsiIndex]; var point3D = ParaviewNurbs2D.SurfacePoint2D(patch.NumberOfControlPointsKsi - 1, patch.DegreeKsi, patch.KnotValueVectorKsi, patch.NumberOfControlPointsHeta - 1, patch.DegreeHeta, patch.KnotValueVectorHeta, projectiveControlPoints, ksiCoordinate, hetaCoordinate); knots[count, 0] = point3D[0] / point3D[3]; knots[count, 1] = point3D[1] / point3D[3]; knots[count++, 2] = point3D[2] / point3D[3]; } } var incrementKsi = numberOfKnotsHeta; var incrementHeta = 1; var nodePattern = new int[] { 0, incrementKsi, incrementKsi + 1, 1 }; var elementConnectivity = CreateElement2DConnectivity(nodePattern, uniqueKnotsKsi[0].Length - 1, uniqueKnotsHeta[0].Length - 1, incrementKsi, incrementHeta); var knotDisplacements = new double[knots.GetLength(0), 3]; foreach (var element in _model.Elements) { var localDisplacements = Matrix.CreateZero(element.ControlPointsDictionary.Count, 3); var counterCP = 0; foreach (var controlPoint in element.ControlPoints) { localDisplacements[counterCP, 0] = (!_model.GlobalDofOrdering.GlobalFreeDofs.Contains(controlPoint, StructuralDof.TranslationX)) ? 0.0 : _solution[_model.GlobalDofOrdering.GlobalFreeDofs[controlPoint, StructuralDof.TranslationX]]; localDisplacements[counterCP, 1] = (!_model.GlobalDofOrdering.GlobalFreeDofs.Contains(controlPoint, StructuralDof.TranslationY)) ? 0.0 : _solution[_model.GlobalDofOrdering.GlobalFreeDofs[controlPoint, StructuralDof.TranslationY]]; localDisplacements[counterCP++, 2] = (!_model.GlobalDofOrdering.GlobalFreeDofs.Contains(controlPoint, StructuralDof.TranslationZ)) ? 0.0 : _solution[_model.GlobalDofOrdering.GlobalFreeDofs[controlPoint, StructuralDof.TranslationZ]]; } var elementKnotDisplacements = element.ElementType.CalculateDisplacementsForPostProcessing(element, localDisplacements); for (int i = 0; i < elementConnectivity.GetLength(1); i++) { var knotConnectivity = elementConnectivity[element.ID, i]; knotDisplacements[knotConnectivity, 0] = elementKnotDisplacements[i, 0]; knotDisplacements[knotConnectivity, 1] = elementKnotDisplacements[i, 1]; knotDisplacements[knotConnectivity, 2] = elementKnotDisplacements[i, 2]; } } Write2DNurbsFile(knots, elementConnectivity, "Quad4", knotDisplacements); }