Thanks, Dale and Menno. Good info and tips. I’ve started messing directly with the knot vector, which may be a little above my understanding of the math going on here (I may need to dig in a little further). Below is my toy problem in Python (done using mostly the RhinoCommon API and running in Rhino 6). Any recommendations on the approach to modifying the knot vector?
nurbsurface.Knots.InsertKnot
inserts additional control points which I don’t want. I’m interested in setting the topology rather than maintaining the existing shape.
The script creates a base surface, adds it to the Rhino document, rebuilds it with more points, then turns a control row into a kink in the manner I am thinking about and adds the modified surface to the document. The result is what I want. Just want to make sure I don’t step on any land mines I don’t see. The ones I do see, that’s another issue 
import Rhino
import Rhino.DocObjects
import Rhino.Geometry as RG
import Rhino.Input as RI
import rhinoscriptsyntax as rs
doc = Rhino.RhinoDoc.ActiveDoc
# Create a base surface to mess with
srf1 = RG.NurbsSurface.CreateFromPoints([
RG.Point3d(0,0,0),
RG.Point3d(0,1,0),
RG.Point3d(0,1,1),
RG.Point3d(0.5,0,0),
RG.Point3d(0.5,1,0),
RG.Point3d(0.5,1,1.5),
RG.Point3d(1,0,0),
RG.Point3d(1,1,0),
RG.Point3d(1,1,2)
], 3, 3, 2, 2)
guid = doc.Objects.AddBrep(srf1.ToBrep(), None, None, False, False )
doc.Views.Redraw()
# Rebuild it
success = rs.RebuildSurface(guid, (3,3), (11,11))
if not success:
print('Rats')
rhobj = Rhino.RhinoDoc.ActiveDoc.Objects.FindId(guid)
brep = rhobj.Geometry
srf1 = brep.Faces[0].ToNurbsSurface()
srf = brep.Faces[0].ToNurbsSurface()
print('yay')
# ---------------------------------------
# Modify the knot vector
vv = 5 # index of parameter to turn into a kink
srf.KnotsV[vv - 1] = vv - 3
srf.KnotsV[vv] = vv - 3
srf.KnotsV[vv + 1] = vv - 3
# Decrement knot values to the right of the one we are looking at
for i in range(vv + 2, srf.KnotsV.Count):
srf.KnotsV[i] -= 2
# ---------------------------------------
print("U Knot Vector: ", " ".join(srf.KnotsU[i].ToString() for i in range(srf.KnotsU.Count)))
print("Old V Knot Vector: ", " ".join(srf1.KnotsV[i].ToString() for i in range(srf1.KnotsV.Count)))
print("New V Knot Vector: ", " ".join(srf.KnotsV[i].ToString() for i in range(srf.KnotsV.Count)))
doc.Objects.AddBrep(srf.ToBrep(), None, None, False, False )
doc.Views.Redraw()