Beispiel #1
0
func get_nurbs_xmat(nurbs *gm.Nurbs, ibasis []int) (xmat [][]float64) {
	nd := nurbs.Gnd()
	xmat = utl.DblsAlloc(nd, len(ibasis))
	for k, l := range ibasis {
		q := nurbs.GetQl(l)
		for j := 0; j < nd; j++ {
			xmat[j][k] = q[j]
		}
	}
	return
}
Beispiel #2
0
func get_nurbs_B() *gm.Nurbs {
	verts := [][]float64{
		{5.0, 10, 0, 1}, // global 0
		{8.0, 10, 0, 1}, // global 1
		{8.0, 13, 0, 1}, // global 2
		{5.0, 13, 0, 1}, // global 3
		{6.0, 11, 0, 1}, // global 4
		{6.0, 12, 0, 1}, // global 5
		{7.0, 11, 0, 1}, // global 6
		{7.0, 12, 0, 1}, // global 7
	}
	knots := [][]float64{
		{0, 0, 0, 0.5, 1, 1, 1},
		{0, 0, 1, 1},
	}
	ctrls := []int{
		0, 4, 6, 1, // first level along x
		3, 5, 7, 2, // second level along x
	}
	var nurbs gm.Nurbs
	nurbs.Init(2, []int{2, 1}, knots)
	nurbs.SetControl(verts, ctrls)
	return &nurbs
}
Beispiel #3
0
// 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
}
Beispiel #4
0
// nurbs_func implements shape/deriv functions for NURBS
func nurbs_func(u, S []float64, dSdR [][]float64, r []float64, derivs bool, nurbs *gm.Nurbs, ibasis, span []int) {

	// compute mapping to knots space
	nd := nurbs.Gnd()
	var umin, umax float64
	for i := 0; i < nd; i++ {
		umin = nurbs.U(i, span[i*2])
		umax = nurbs.U(i, span[i*2+1])
		u[i] = ((umax-umin)*r[i] + (umax + umin)) / 2.0
		if u[i] < umin || u[i] > umax {
			chk.Panic("cannot compute NURBS shape function outide cell range:\nr[%d]=%v, u[%d]=%v, urange=[%v,%v]", i, r[i], i, u[i], umin, umax)
		}
	}

	// shape and/or derivatives in knots space
	if derivs {
		nurbs.CalcBasisAndDerivs(u)
	} else {
		nurbs.CalcBasis(u)
	}
	for k, l := range ibasis {
		S[k] = nurbs.GetBasisL(l)
	}

	// derivatives in natural space
	if derivs {
		for k, l := range ibasis {
			nurbs.GetDerivL(dSdR[k], l) // dSdR := dSdU
			for i := 0; i < nd; i++ {
				umin = nurbs.U(i, span[i*2])
				umax = nurbs.U(i, span[i*2+1])
				dSdR[k][i] *= (umax - umin) / 2.0 // dSdR[i] := dSdU[i] * du[i]/dr[i] (no sum on i)
			}
		}
	}
	return
}