begintemplate TwoElectrodeIdealVClamp


public xmeasure, xinject, set_vc, vc, ic, valid


// usage:
// e = TwoElectrodeIdealVClamp()
// section e.xmeasure(x) // measurement electrode location
// section e.xinject(x) // current injection electrode location
// e.set_vc(control_potential) // sets the value of b.x[2]
// e.vc() // returns the value of b.x[2]
// e.ic() // returns the value of y.x[2]
// e.valid() returns true if the clamp is part of the simulation


public b, y // if you want to use the addresses instead of the
        // functions for plotting. They are necessary for
        // recording the current into a Vector, or playing a Vector into
        // the control potential.


objref c, g, y, b, model, nil
objref sec[2], x, sl


proc init() {
print "init"
        c = new Matrix(5,5,2) //sparse
        g = new Matrix(5,5)
        y = new Vector(5)
        b = new Vector(5)
	
	
        g.x[1][3] = 1
	
        g.x[2][4] = 1
	
	g.x[3][0] = -1e+06
	g.x[3][1] = 1
	g.x[3][2] = 1e+06
	
	g.x[4][2] = 1
	g.printf
        x = new Vector(2)
print "init return"
}


proc install() {
        if (sec[0] != nil && sec[1] != nil) {
                sl = new SectionList()
                sec[0].sec sl.append()
                sec[1].sec sl.append()
                model = new LinearMechanism(c, g, y, b, sl, x)
		print "attached TEVC to cell"
        }
}


proc xmeasure() { 
        x.x[0] = $1
        sec[0] = new SectionRef()
        install()
}


proc xinject() { local a
        x.x[1] = $1
        sec[1] = new SectionRef()
	a = area(x.x[1])
	print "area at current injection electorde ", a
	g.x[1][3]=-100/a
	print "g"
	g.printf
        install()
}


proc set_vc() { b.x[4] = $1 }
func vc() { return b.x[4] }
func ic() { return y.x[3] }


func valid() {
        if (model != nil) {
                return model.valid
        }
        return 0
}


endtemplate TwoElectrodeIdealVClamp