c     Nonlinear Gauss Seidel static solver 
c     DLL file for VisSim User defined static solver
c
c ... Basics:
c     Requires Vissim version 1.3, impsim.lib (11/24/93) and higher
c     The name of the dll is VSOLVER.DLL
c     The name of the function is USERSOLVER
c     Vissim will call usersolver at each dt.  Usersolver can call the 
c     Vissim routine VSMREQUEST(CMD,VECVAL) where:
c     CMD = an integer from 1 to 5 denoting a command;
c           1 = VrGetConstraints = fills vecval with the constraint values
c           2 = VGetUnk = fills vecval with the unknown output values
c           3 = VSetUnk = vecval values go the vissim unknowns
c           4 = VGetSolverInfo = fills vecval with 5 values;
c                       element 1 = # of constraints
c                       element 2 = # of unknowns
c                       element 3 = relaxation value
c                                         redefined for debug (1 = debug output on)
c                       element 4 = max # of iterations
c                       element 5 = convergence delta
c           5 = VrExec = executes the block diagram
c				6 = VGetUnkInputs = fills vecval with unknown input values
c     VECVAL = a vector used to pass info to and from vissim
c     The vsolver dll also needs a .def file with the EXPORT statement 
c     defined as USERSOLVER.   
c        
	interface to subroutine debmsg[c,varying](fmt)
	character*32 fmt[reference]
	end
c
	subroutine usersolver
	implicit real*8 (A-H,O-Z) 
	parameter (nmax=20) 
	common/vs/nc,nu
	real*8 unk(nmax), con(nmax), unk_in(nmax), time  
c  
	call getSimTime(time)
	ipass=0 !first pass flag, 1=first pass
	if (time.eq.0.)  ipass=1
c
c     Get dimension info 1st pass only
	if (ipass.eq.1) then
		call vsmrequest(4,unk)
		nc=unk(1)   !# of constraints
		nu=unk(2)   !# of unknowns
		relax=unk(3)    !relaxation factor
		itermax=unk(4)     !max iterations
		converg=unk(5)     !truncation error for jumpout
	endif
c

c     Iteration loop
	do 20 k=1,itermax
c
		call vsmrequest(2,unk)  !get unknown outputs from vissim
		call vsmrequest(5,unk)  !execute the diagram
		call vsmrequest(6,unk_in)  !get unknown inputs from vissim
		err=0.
	  do 10 i=1,nu !update unknowns and compute error in con vector 
		err=err+abs(unk(i)-unk_in(i))
			unk(i)=(unk_in(i)*relax) + (unk(i)*(1.-relax) )
  10    continue
		if (err.le.converg) goto 30 !jumpout if error satisfied
		call vsmrequest(3,unk)  !send new unknowns back to vissim

  20  continue
  30  continue
c
	return
	end
