// GetShapeNurbs returns a shape structure based on NURBS // Note: span are the local ids of control points in NURBS defining elements // Note: FaceLocalVerts does not work for internal surfaces; only those @ boundaries func GetShapeNurbs(nurbs *gm.Nurbs, nrbfaces []*gm.Nurbs, span []int) (o *Shape) { // basic data o = new(Shape) o.Type = "nurbs" o.FaceType = "nurbs" o.Gndim = nurbs.Gnd() switch o.Gndim { case 1: o.BasicType = "lin2" case 2: o.BasicType = "qua4" case 3: o.BasicType = "hex8" } o.Nverts = nurbs.GetElemNumBasis() o.VtkCode = VTK_POLY_VERTEX o.Func = o.NurbsFunc o.FaceFunc = o.NurbsFaceFunc o.Nurbs = nurbs o.Span = span o.Ibasis = o.Nurbs.IndBasis(o.Span) o.U = make([]float64, o.Gndim) // faces basic data nfaces := 2 * o.Gndim o.FaceLocalVerts = nurbs.ElemBryLocalInds() if o.Gndim == 3 { o.NurbsFaces = nrbfaces o.SpanFace = [][]int{ span[0:2], span[0:2], span[2:4], span[2:4], span[4:6], span[4:6], } o.FaceFlip = []bool{false, true, false, true, false, true} // => point to the inside } else { o.NurbsFaces = []*gm.Nurbs{nrbfaces[2], nrbfaces[1], nrbfaces[3], nrbfaces[0]} o.SpanFace = [][]int{span[0:2], span[2:4], span[0:2], span[2:4]} o.FaceFlip = []bool{false, false, true, true} // => point to the inside } o.IbasisFace = make([][]int, nfaces) for idxface, face := range o.NurbsFaces { o.IbasisFace[idxface] = face.IndBasis(o.SpanFace[idxface]) if idxface == 0 { o.FaceNvertsMax = len(o.IbasisFace[idxface]) } else { o.FaceNvertsMax = utl.Imax(o.FaceNvertsMax, len(o.IbasisFace[idxface])) } } // allocate stracthpad variables o.init_scratchpad() return }