From e818ba5bcc461af545665c78157be4e52252aa1c Mon Sep 17 00:00:00 2001
From: Miha <miha.fosnaric@fe.uni-lj.si>
Date: Mon, 11 Jul 2016 11:52:30 +0000
Subject: [PATCH] Merge branch 'master' of https://bitbucket.org/samop/trisurf-ng

---
 python/trisurf/Remote.py       |   73 +++++
 src/main.c                     |    6 
 python/tape                    |   12 
 python/trisurf/trisurf.py      |    8 
 src/io.c                       |   72 ----
 src/tape                       |   18 
 python/pythonvtk.py            |   42 +++
 python/trisurf/__init__.py     |    0 
 python/trisurf/WebTrisurf.py   |   59 ++++
 python/networkedExample.py     |   27 +
 src/timestep.c                 |    5 
 python/trisurf/tsmgr.py        |  316 +++++++++++++++++----
 python/trisurf/VTKRendering.py |  155 +++++++++++
 13 files changed, 638 insertions(+), 155 deletions(-)

diff --git a/python/networkedExample.py b/python/networkedExample.py
new file mode 100755
index 0000000..74c0a04
--- /dev/null
+++ b/python/networkedExample.py
@@ -0,0 +1,27 @@
+from trisurf import trisurf
+from trisurf import tsmgr
+
+
+
+
+#Ok... Configure your keys:
+#ssh-keygen
+#and copy them to all the remote hosts
+#ssh-copy-id -i ./ssh/id_rsa.pub username@remotehost
+
+run2=trisurf.Runner(tape='tape')
+run2.setMaindir(("N","k","V","Np","Nm"),("nshell","xk0","constvolswitch","npoly","nmono"))
+run2.setSubdir("run1")
+
+run3=trisurf.Runner(tape='tape')
+run3.setMaindir(("N","k","V","Np","Nm"),("nshell","xk0","constvolswitch","npoly","nmono"))
+run3.setSubdir("run2")
+
+
+
+Runs=[run2, run3]
+
+hosts=({'name':'natalie','address':'kabinet.penic.eu', 'runs':Runs, 'username':'samo'},
+	{'name':'Hestia','address':'127.0.0.1', 'runs':Runs, 'username':'samo'})
+
+tsmgr.start(hosts)
diff --git a/python/pythonvtk.py b/python/pythonvtk.py
new file mode 100644
index 0000000..b50ff7c
--- /dev/null
+++ b/python/pythonvtk.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# by Panos Mavrogiorgos, email: pmav99 <> gmail
+ 
+from vtk import *
+ 
+# The source file
+#file_name = "uGridEx.vtk"
+file_name="timestep.vtu"
+# Read the source file.
+#reader = vtkUnstructuredGridReader()
+reader=vtkXMLUnstructuredGridReader()
+reader.SetFileName(file_name)
+reader.Update() # Needed because of GetScalarRange
+output = reader.GetOutput()
+scalar_range = output.GetScalarRange()
+ 
+# Create the mapper that corresponds the objects of the vtk file
+# into graphics elements
+mapper = vtkDataSetMapper()
+mapper.SetInput(output)
+mapper.SetScalarRange(scalar_range)
+ 
+# Create the Actor
+actor = vtkActor()
+actor.SetMapper(mapper)
+ 
+# Create the Renderer
+renderer = vtkRenderer()
+renderer.AddActor(actor)
+renderer.SetBackground(0, 0, 0) # Set background to white
+ 
+# Create the RendererWindow
+renderer_window = vtkRenderWindow()
+renderer_window.AddRenderer(renderer)
+ 
+# Create the RendererWindowInteractor and display the vtk_file
+interactor = vtkRenderWindowInteractor()
+interactor.SetRenderWindow(renderer_window)
+interactor.Initialize()
+interactor.Start()
diff --git a/python/tape b/python/tape
index f207db2..35b52e6 100644
--- a/python/tape
+++ b/python/tape
@@ -1,6 +1,6 @@
 ####### Vesicle definitions ###########
 # nshell is a number of divisions of dipyramid
-nshell=5
+nshell=10
 # dmax is the max. bond length (in units l_min)
 dmax=1.7
 # dmin_interspecies in the min. dist. between different vertex species (in units l_min)
@@ -17,15 +17,15 @@
 pressure=0.0
 
 #Constant volume constraint (0 disable constant volume, 1 enable wiht additional vertex move, 2 enable with epsvol)
-constvolswitch=2
+constvolswitch=0
 constvolprecision=1e-14
 
 #Constant area constraint (0 disable constant area, 2 enable constant area with epsarea)
-constareaswitch=2
+constareaswitch=0
 
 ####### Polymer (brush) definitions ###########
 # npoly is a number of polymers attached to npoly distinct vertices on vesicle
-npoly=2
+npoly=60
 # nmono is a number of monomers in each polymer
 nmono=10
 # Spring constant between monomers of the polymer
@@ -55,7 +55,7 @@
 mcsweeps=200
 #how many initial mcsweeps*inititer MC sweeps before recording to disk?
 #2
-inititer=0
+inititer=10
 #how many records do you want on the disk iteration are there in a run?
 #10000
 iterations=100
@@ -63,7 +63,7 @@
 
 ###### Spherical harmonics ###########
 # If 0 then spherical harmonics are not calculated at all.
-spherical_harmonics_coefficients=21
+spherical_harmonics_coefficients=0
 
 #shut up if we are using cluster!!!
 quiet=false
diff --git a/python/trisurf/Remote.py b/python/trisurf/Remote.py
new file mode 100644
index 0000000..8da08be
--- /dev/null
+++ b/python/trisurf/Remote.py
@@ -0,0 +1,73 @@
+import paramiko
+
+
+
+class Connection:
+	def __init__(self, hostname, port=22, username=None, password=None):
+		self.hostname=hostname
+		self.port=port
+		if(username!=None):
+			self.username=username
+		else:
+			self.username=''
+		if(password!=None):
+			self.password=password
+		else:
+			self.password=''
+		self.ssh=paramiko.SSHClient()
+		self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+		self.connected=False
+		return
+	
+	def connect(self, Timeout=5):
+		if(not self.connected):
+			try:
+				print("Trying to connect to: "+self.username+"@"+self.hostname+":"+str(self.port)+".")
+				self.ssh.connect(self.hostname, username=self.username, password=self.password, port=self.port, timeout=Timeout)
+				self.connected=True
+			except:
+				print("Error establishing connection with "+self.username+"@"+self.hostname+":"+str(self.port)+".")
+				exit(1)
+		else:
+			print("Already connected!")
+		return
+
+	def disconnect(self):
+		if(self.connected):
+			try:
+				self.ssh.close()
+			except:
+				print("Cannot disconect. Unknown error.")
+		else:
+			print("Cannot disconect. Already disconnected.")
+		self.connected=False
+
+	def execute(self,command):
+		if(self.connected):
+			try:
+				stdin,stdout,stderr=self.ssh.exec_command(command)
+				output=stdout.readlines()
+				errors=stderr.readlines()
+			#	print(errors)
+				return(output)
+			except:
+				print("Cannot execute remote commands")
+		else:
+			print("Cannot execute remote commands. Connect first.")
+
+	def send_file(self, local, remote):
+		sftp=self.ssh.open_sftp()
+		sftp.put(local,remote)
+		sftp.close()
+
+	def receive_file(self,remote,local):
+		sftp=self.ssh.open_sftp()
+		sftp.get(remote,local)
+		sftp.close()
+
+	def mkdir_remote(self,directory):
+		sftp=self.ssh.open_sftp()
+		sftp.mkdir(directory)
+		sftp.close()
+
+	
diff --git a/python/trisurf/VTKRendering.py b/python/trisurf/VTKRendering.py
new file mode 100644
index 0000000..5e72b98
--- /dev/null
+++ b/python/trisurf/VTKRendering.py
@@ -0,0 +1,155 @@
+import os,sys
+from . import trisurf
+if sys.version_info<(3,0):
+	from vtk import *
+
+
+
+class MultiRender:
+	def __init__(self,args,host):
+		target_runs=getRargetRunIdxList(args)
+		if target_runs==None:
+			target_runs=list(range(1,len(host['runs'])+1))
+		nruns=len(target_runs)
+		#prepare rendering window
+		self.renderer_window = vtkRenderWindow()
+		self.renderer_window.AddRenderer(self.renderer)
+		self.renderer_window.SetSize(1200,600)
+		interactor = vtkRenderWindowInteractor()
+		interactor.SetRenderWindow(self.renderer_window)
+		interactor.Initialize()
+ 		interactor.AddObserver("TimerEvent", self.RenderUpdate)
+		timerIDR = interactor.CreateRepeatingTimer(1000)
+		self.filename=[]
+		self.renderer=[]
+		i=0
+		for run in target_runs:	
+			#for each target run calculate renderer location
+			r.vtkRenderer()
+			r.SetBackground(0,0,0)
+			p=1.0/float(nruns)
+			x1=i*p
+			x2=(i+1)*p
+			r.SetViewport(x1,0.0,x2,1.0)
+			self.renderer.Append(r)
+			self.renderer_window.AddRenderer(r)
+			i=i+1
+		#call Renderer object with Run, renderer
+		#start endless loop of interactor
+		interactor.Start()
+
+	def lastVTU(self,run):
+		Dir=trisurf.Directory(maindir=run.maindir,simdir=run.subdir)
+		filename=os.path.join("./",Dir.fullpath(),run.getLastVTU())
+		return filename
+
+	def lastActorForRun(self,run):
+		filename=self.lastVTU(run)
+		reader=vtkXMLUnstructuredGridReader()
+		reader.SetFileName(self.filename)
+		reader.Update() # Needed because of GetScalarRange
+		output = reader.GetOutput()
+		scalar_range = output.GetScalarRange()
+		mapper = vtkDataSetMapper()
+		mapper.SetInput(output)
+		mapper.SetScalarRange(scalar_range)
+
+		# Create the Actor
+		actor = vtkActor()
+		actor.SetMapper(mapper)
+		return actor
+
+
+
+	def RenderUpdate(self, obj, event):
+		i=0
+		for run in runs:
+			if(self.lastVTU(run)!=self.filename[i]):
+				#print("updejt")
+				self.renderer.RemoveActor(self.actor)
+				self.renderer.RemoveActor(self.textactor)
+				self.actor=self.lastActor()
+				self.textactor=self.textActor()
+				self.renderer.AddActor(self.actor)
+				self.renderer.AddActor(self.textactor)
+				self.renderer_window.Render()
+			#self.render.RemoveActor(self.actor)
+			i=i+1	
+		return
+
+
+class Renderer:
+	def __init__(self,args,host):
+		self.host=host
+		self.args=args
+		self.renderer = vtkRenderer()
+		self.actor=self.lastActor()
+		self.textactor=self.textActor()
+		self.renderer.AddActor(self.actor)
+		self.renderer.AddActor(self.textactor)
+		self.renderer.SetBackground(0, 0, 0) # Set background to white
+		# Create the RendererWindow
+		self.renderer_window = vtkRenderWindow()
+		self.renderer_window.AddRenderer(self.renderer)
+		self.renderer_window.SetSize(1200,600)
+	
+		self.renderer.SetViewport(0.0,0.0,0.5,1.0)
+		rend=vtk.vtkRenderer()
+		rend.AddActor(self.actor)
+		rend.SetViewport(0.5,0.0,1.0,1.0)
+		self.renderer_window.AddRenderer(rend)	
+# Set up a check for aborting rendering.
+		# Create the RendererWindowInteractor and display the vtk_file
+		interactor = vtkRenderWindowInteractor()
+		interactor.SetRenderWindow(self.renderer_window)
+		interactor.Initialize()
+ 		interactor.AddObserver("TimerEvent", self.RenderUpdate)
+		timerIDR = interactor.CreateRepeatingTimer(1000)
+		interactor.Start()
+
+		return
+
+	def lastVTU(self):
+		Dir=trisurf.Directory(maindir=self.host['runs'][0].maindir,simdir=self.host['runs'][0].subdir)
+		filename=os.path.join("./",Dir.fullpath(),self.host['runs'][0].getLastVTU())
+		return filename
+
+	def textActor(self):
+		textactor=vtkTextActor()
+		textactor.SetInput(self.filename)
+		tp=textactor.GetTextProperty()
+		tp.SetColor(1,1,1)
+		tp.SetFontSize(11)
+		textactor.SetDisplayPosition(20,30)
+		return textactor
+
+	def lastActor(self):
+		self.filename=self.lastVTU()
+		reader=vtkXMLUnstructuredGridReader()
+		reader.SetFileName(self.filename)
+		reader.Update() # Needed because of GetScalarRange
+		output = reader.GetOutput()
+		scalar_range = output.GetScalarRange()
+		mapper = vtkDataSetMapper()
+		mapper.SetInput(output)
+		mapper.SetScalarRange(scalar_range)
+
+		# Create the Actor
+		actor = vtkActor()
+		actor.SetMapper(mapper)
+		return actor
+
+
+	def RenderUpdate(self, obj, event):
+		if(self.lastVTU()!=self.filename):
+			#print("updejt")
+			self.renderer.RemoveActor(self.actor)
+			self.renderer.RemoveActor(self.textactor)
+			self.actor=self.lastActor()
+			self.textactor=self.textActor()
+			self.renderer.AddActor(self.actor)
+			self.renderer.AddActor(self.textactor)
+			self.renderer_window.Render()
+		#self.render.RemoveActor(self.actor)
+		
+		return
diff --git a/python/trisurf/WebTrisurf.py b/python/trisurf/WebTrisurf.py
new file mode 100644
index 0000000..4b36ec9
--- /dev/null
+++ b/python/trisurf/WebTrisurf.py
@@ -0,0 +1,59 @@
+import subprocess
+import sys, os
+if sys.version_info>=(3,0):
+	from urllib.parse import urlparse
+else:
+	from urlparse import urlparse
+import http.server
+import socketserver
+
+#Web server
+class TsWEB(http.server.BaseHTTPRequestHandler):
+	def do_GET(self):
+		parsed_path=urlparse(self.path)
+		"""	message_parts = [
+                'CLIENT VALUES:',
+                'client_address=%s (%s)' % (self.client_address, self.address_string()),
+                'command=%s' % self.command,
+                'path=%s' % self.path,
+                'real path=%s' % parsed_path.path,
+                'query=%s' % parsed_path.query,
+                'request_version=%s' % self.request_version,
+                '',
+                'SERVER VALUES:',
+                'server_version=%s' % self.server_version,
+                'sys_version=%s' % self.sys_version,
+                'protocol_version=%s' % self.protocol_version,
+                '',
+                'HEADERS RECEIVED:',
+                ]
+		for name, value in sorted(self.headers.items()):
+			message_parts.append('%s=%s' % (name, value.rstrip()))
+		message_parts.append('')
+		message = '<br>'.join(message_parts) """
+		self.send_response(200)
+		self.end_headers()
+		self.wfile.write(b"<h1>Trisurf-ng manager web interface</h1><hr>")
+		oldstdout=sys.stdout
+		process=subprocess.Popen (['/usr/bin/python3', sys.argv[0], '-s', '--html'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+		stdout, stderr= process.communicate()
+		output=stdout.decode('ascii')
+		output=output.replace('\n','<BR>')
+		output=bytearray(output,'ascii')
+		self.wfile.write(output)
+
+
+
+
+class WebServer():
+	def __init__(self, port=8000):
+		http_server = socketserver.TCPServer(('', port), TsWEB)
+		try:
+			http_server.serve_forever()
+		except KeyboardInterrupt:
+			print('^C received, shutting down the web server')
+			http_server.socket.close()
+
+
+
+
diff --git a/python/trisurf/__init__.py b/python/trisurf/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/trisurf/__init__.py
diff --git a/python/trisurf/trisurf.py b/python/trisurf/trisurf.py
index ddcb7f9..3fe4adb 100644
--- a/python/trisurf/trisurf.py
+++ b/python/trisurf/trisurf.py
@@ -2,7 +2,7 @@
 import xml.etree.ElementTree as ET
 import base64
 import zlib
-import io
+import sys,io
 import os
 from itertools import islice
 import mmap
@@ -350,7 +350,7 @@
 		return int(status)
 
 	def isCompleted(self):
-		if (int(self.tape.getValue("iterations"))==self.getLastIteration()+1):
+		if int(self.tape.getValue("iterations"))+int(self.tape.getValue("inititer"))==self.getLastIteration()+1:
 			return True
 		else:
 			return False
@@ -443,6 +443,8 @@
 		for p,v in zip(prefix,variables):
 			if(v=="xk0"):
 				tv=str(round(float(self.tape.config[v])))
+				if sys.version_info<(3,0):
+					tv=str(int(float(self.tape.config[v])))
 			else:
 				tv=self.tape.config[v]
 			maindir=maindir+p+tv
@@ -493,7 +495,7 @@
 
 
 	def getLastVTU(self):
-		vtuidx=self.getLastIteration()
+		vtuidx=self.getLastIteration() -int(self.tape.getValue("inititer"))
 		if vtuidx<0:
 			return None
 		else:
diff --git a/python/trisurf/tsmgr.py b/python/trisurf/tsmgr.py
index fa7d20f..d973360 100644
--- a/python/trisurf/tsmgr.py
+++ b/python/trisurf/tsmgr.py
@@ -1,21 +1,61 @@
-import sys, getopt
+import argparse
+import paramiko
+from . import Remote
+from . import trisurf
+import socket
+import os,sys
 import tabulate
 import subprocess,re
 import psutil
-
-def printHelp():
-	print('Python module tsmgr accept following switches:\n')
-	print('tsmgr [-n process number] [-R] [-h] [-r] [-s] [-c comment text] [-a comment text]\n')
-	print('[-n process number]: number of process for which -s -r -c or -a switch apply. Should be placed before any other switch');
-	print('[-R]               : raw output for -s switch');
-	print('[-r]               : run process');
-	print('[-s]               : process status');
-	print('[-k]               : kill process');
-	print('[-c comment text]  : write new comment for process');
-	print('[-a comment text]  : append additional comment for process');
-	print('[-h]               : print help');
+#import http.server
+#import socketserver
+if sys.version_info>=(3,0):
+	from urllib.parse import urlparse
+	from . import WebTrisurf
+else:
+	from urlparse import urlparse
+	from vtk import *
+	from . import VTKRendering
+#import io
 
 
+
+#Color definitions for terminal
+class bcolors:
+    HEADER = '\033[95m'
+    OKBLUE = '\033[94m'
+    OKGREEN = '\033[92m'
+    WARNING = '\033[93m'
+    FAIL = '\033[91m'
+    ENDC = '\033[0m'
+    BOLD = '\033[1m'
+    UNDERLINE = '\033[4m'
+
+#parses Command Line Arguments and returns the list of parsed values
+def ParseCLIArguments(arguments):
+	parser = argparse.ArgumentParser(description='Manages (start, stop, status) multiple simulation processes of trisurf according to the configuration file.')
+	parser.add_argument('proc_no', metavar='PROC_NO', nargs='*',
+			    help='process number at host. If hostname is not specified, localhost is assumed. If no processes are specified all processes on all hosts are assumed.')
+	action_group=parser.add_mutually_exclusive_group(required=True)
+	action_group.add_argument('-c','--comment',nargs=1, help='append comment to current comment')
+	action_group.add_argument('--delete-comment', help='delete comment',action='store_true')
+	action_group.add_argument('-k','--kill','--stop','--suspend', help='stop/kill the process', action='store_true')
+	action_group.add_argument('-r','--run','--start','--continue', help='start/continue process', action='store_true')
+	action_group.add_argument('-s','--status',help='print status of the processes',action='store_true')
+	action_group.add_argument('-v','--version', help='print version information and exit', action='store_true')
+	action_group.add_argument('--web-server', type=int,metavar="PORT", nargs=1, help='EXPERIMENTAL: starts web server and never exist.')
+	action_group.add_argument('-p','--preview',help='preview last VTU shape',action='store_true')
+	parser.add_argument('--force', help='if dangerous operation (killing all the processes) is requested, this flag is required to execute the operation. Otherwise, the request will be ignored.', action="store_true")
+	parser.add_argument('-H', '--host', nargs=1, help='specifies which host is itended for the operation. Defauts to localhost for all operations except --status and --version, where all configured hosts are assumed.')
+	parser.add_argument('--html', help='Generate HTML output', action="store_true")
+	parser.add_argument('-n', nargs='+', metavar='PROC_NO', type=int, help='OBSOLETE. Specifies process numbers.')
+	parser.add_argument('-R','--raw',help='print status and the rest of the information in raw format', action="store_true")
+	parser.add_argument('-x','--local-only',help='do not attempt to contact remote hosts. Run all operations only on local machine',action='store_true')
+	args = parser.parse_args(arguments)
+	return args
+
+
+#gets version of trisurf currently running
 def getTrisurfVersion():
 	p = subprocess.Popen('trisurf --version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
 	lines=p.stdout.readlines()
@@ -26,67 +66,205 @@
 	else:
 		return "unknown version"
 
-def start(Runs):
-	argv=sys.argv[1:]
-	processno=0
-	raw=False
-	try:
-		opts, args = getopt.getopt(argv,"Ra:n:hrskc:")
-	except getopt.GetoptError:
-		printHelp()
-		sys.exit(2)
-	for opt, arg in opts:
-		if opt == '-R':
-			raw=True
-		elif opt == '-h':
-			printHelp()
-			sys.exit()
-		elif opt == '-r':
-			if processno:
-				localRuns=[Runs[processno-1]]
-			else:
-				localRuns=Runs
-			for run in localRuns:
-				run.start()
-		elif opt == '-s':
-			report=[]
-			i=1
-			if processno:
-				localRuns=[Runs[processno-1]]
-			else:
-				localRuns=Runs
-			for run in localRuns:
-				line=run.getStatistics()
-				line.insert(0,i)
-				report.append(line)
-				i=i+1
-			if(raw):
-				print(report)
-			else:
-				print ("\n\nTrisurf running processes report\n")
-				print (tabulate.tabulate(report,headers=["Run no.", "Run start time", "ETA", "Status", "PID", "Path", "Comment"], tablefmt='fancy_grid'))
-		elif opt == '-n':
-			processno=int(arg)
-			if processno<1 or processno>len(Runs) :
-				processno=0
-		elif opt == '-c':
-			comment = arg
-			if processno:
-				Runs[processno-1].writeComment(arg)
-		elif opt == '-a':
-			comment = arg
-			if processno:
-				Runs[processno-1].writeComment("\n"+arg, 'a')
 
-		elif opt == '-k':
-			if processno:
-				Runs[processno-1].stop()
+
+def copyConfigAndConnect(hosts):
+	print("Connecting to remote hosts and copying config files, tapes and snapshots")
+	for host in hosts:
+		if(host['name'] !=socket.gethostname()): #if I am not the computer named in host name
+			try:
+				username=host['username']
+			except:
+				username=os.getusername() #default username is current user user's name
+			try:
+				port=host['port']
+			except:
+				port=22 #default ssh port
+			rm=Remote.Connection(hostname=host['address'],username=username, port=port)
+			rm.connect()
+			rm.send_file(__file__,'remote_control.py')
+			for run in host['runs']:
+				try:
+					rm.send_file(run.tapeFile,run.tapeFile)
+				except:
+					pass
+				try:
+					rm.send_file(run.snapshotFile,run.snapshotFile)
+				except:
+					pass
+			host['_conn']= rm
+	# we are connected to all hosts...
+	return hosts
+
+
+
+def getTargetRunIdxList(args):
+	target_runs=list(map(int,args['proc_no']))
+	if len(target_runs)==0:
+		#check if obsolete -n flags have numbers
+		target_runs=args['n']
+		if target_runs==None:
+			return None
+	target_runs=list(set(target_runs))
+	return target_runs
+
+
+
+def status_processes(args,host):
+	target_runs=getTargetRunIdxList(args)
+	if target_runs==None:
+		target_runs=list(range(1,len(host['runs'])+1))
+	report=[]
+	for i in target_runs:
+		line=host['runs'][i-1].getStatistics()
+		line.insert(0,i)
+		report.append(line)
+	if(args['raw']):
+		print(report)
+	else:
+		if(args['html']):
+			tablefmt='html'
 		else:
-			printHelp()
-			sys.exit(2)
+			tablefmt='fancy_grid'
+		print(tabulate.tabulate(report,headers=["Run no.", "Run start time", "ETA", "Status", "PID", "Path", "Comment"], tablefmt=tablefmt))
+	return
+
+def run_processes(args,host):
+	target_runs=getTargetRunIdxList(args)
+	if target_runs==None:
+		target_runs=list(range(1,len(host['runs'])+1))
+	for i in target_runs:
+		host['runs'][i-1].start()
+	return
+
+def kill_processes(args,host):
+	target_runs=getTargetRunIdxList(args)
+	if target_runs==None:
+		if args['force']==True:
+			target_runs=list(range(1,len(host['runs'])+1))
+		else:
+			print("Not stopping all processes on the host. Run with --force flag if you are really sure to stop all simulations")
+			return
+	for i in target_runs:
+		host['runs'][i-1].stop()
+	return
+
+def comment_processes(args,host):
+	target_runs=getTargetRunIdxList(args)
+	if target_runs==None:
+		target_runs=list(range(1,len(host['runs'])+1))
+	for i in target_runs:
+		host['runs'][i-1].writeComment(args['comment'][0],'a')
+	print("Comment added")
+	return
+
+def delete_comments(args,host):
+	target_runs=getTargetRunIdxList(args)
+	if target_runs==None:
+		if args['force']==True:
+			target_runs=list(range(1,len(host['runs'])+1))
+		else:
+			print("Not deleting comments on all posts on the host. Run with --force flag if you are really sure to delete all comments")
+			return
+	for i in target_runs:
+		host['runs'][i-1].writeComment("")
+	print("Comment deleted")
+	return
+
+
+def start_web_server(args,host):
+	print('Server listening on port {}'.format(args['web_server'][0]))
+	if sys.version_info>=(3,0):
+		WebTrisurf.WebServer(port=args['web_server'][0])
+	else:
+		print("Cannot start WebServer in python 2.7")
+	exit(0)
+
+def perform_action(args,host):
+	#find which flags have been used and act upon them. -r -s -k -v -c --delete-comment are mutually exclusive, so only one of them is active
+	if args['run']:
+		run_processes(args,host)
+	elif args['kill']:
+		kill_processes(args,host)
+	elif args['status']:
+		status_processes(args,host)
+	elif args['comment']!= None:
+		comment_processes(args,host)
+	elif args['delete_comment']:
+		delete_comments(args,host)
+	elif args['web_server']!=None:
+		start_web_server(args,host)
+	elif args['preview']:
+		preview_vtu(args,host)
+	else: #version requested
+		print(getTrisurfVersion())
+	return
 
 
 
+def preview_vtu(args,host):
+	#only for localhost at the moment
+	if sys.version_info>=(3,0):
+		print("Preview works only with python 2.7")
+		exit(1)
+	if host['name'] == socket.gethostname():
+		VTKRendering.Renderer(args,host)
+
+def getListOfHostConfigurationByHostname(hosts,host):
+	rhost=[]
+	for chost in hosts:
+		if chost['name'] in host:
+			rhost.append(chost)
+	return rhost
+
+
+
+def start(hosts,argv=sys.argv[1:]):
+	args=vars(ParseCLIArguments(argv))
+	#print(vars(args))
+
+	#Backward compatibility... If running just on localmode, the host specification is unnecessary. Check if only Runs are specified
+	try:
+		test_host=hosts[0]['name']
+	except:
+		print("Network mode disabled. Old syntax detected.")
+		host={'name':socket.gethostname(),'address':'127.0.0.1', 'runs':hosts}
+		perform_action(args,host)
+		exit(0)
+
+
+	#find the host at which the action is attended
+	if args['host']==None:
+		if(args['status']==False and args['version']==False):
+			hosts=getListOfHostConfigurationByHostname(hosts,socket.gethostname())
+	else:
+		hosts=getListOfHostConfigurationByHostname(hosts,args['host'])
+	if len(hosts)==0:
+		print ('Hostname "{}" does not exist in configuration file. Please check the spelling'.format(args['host'][0]))
+		exit(1)
+
+	if not args['local_only']:
+			hosts=copyConfigAndConnect(hosts)
+
+	#do local stuff:
+	for host in hosts:
+		if host['name'] == socket.gethostname():
+			if(args['html']):
+				print("Host <font color='orange'>"+host['name']+"</font> reports the following:")
+			else:
+				print("Host "+bcolors.WARNING+host['name']+bcolors.ENDC+" reports the following:")
+			perform_action(args,host)
+		elif not args['local_only']:
+			output=host['_conn'].execute('python3 ./remote_control.py -x '+" ".join(argv))
+			for line in output:
+				print(line.replace('\n',''))
+
+
+	if not args['local_only']:
+		print("Closing connections to remote hosts")
+		for host in hosts:
+			if(host['name'] !=socket.gethostname()):
+				host['_conn'].disconnect()
 
 
 
diff --git a/src/io.c b/src/io.c
index f0207ac..6d6cbbb 100644
--- a/src/io.c
+++ b/src/io.c
@@ -861,8 +861,8 @@
 	fprintf(fh, "<?xml version=\"1.0\"?>\n<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n");
 	xml_trisurf_data(fh,vesicle);
 	fprintf(fh, " <UnstructuredGrid>\n");
-    fprintf(fh, "<Piece NumberOfPoints=\"%u\" NumberOfCells=\"%u\">\n",vlist->n+monono*polyno+fonono*filno, blist->n+monono*polyno+filno*(fonono-1));
-    fprintf(fh,"<PointData Scalars=\"vertices_idx\">\n<DataArray type=\"Int64\" Name=\"vertices_idx\" format=\"ascii\">");
+    fprintf(fh, "<Piece NumberOfPoints=\"%u\" NumberOfCells=\"%u\">\n",vlist->n+monono*polyno+fonono*filno, blist->n+monono*polyno+filno*(fonono-1)+vesicle->tlist->n);
+    fprintf(fh,"<PointData Scalars=\"scalars\">\n<DataArray type=\"Int64\" Name=\"scalars\" format=\"ascii\">");
    	for(i=0;i<vlist->n;i++){
 		fprintf(fh,"%u ",vtx[i]->idx);
     }
@@ -887,61 +887,6 @@
 	}
 
     	fprintf(fh,"</DataArray>\n");
-	
-	//here comes additional data as needed. Currently only spontaneous curvature
-	fprintf(fh,"<DataArray type=\"Float64\" Name=\"spontaneous_curvature\" format=\"ascii\">");
-	for(i=0;i<vlist->n;i++){
-		fprintf(fh,"%.17e ",vtx[i]->c);
-	}
-		//polymeres
-		if(poly){
-			poly_idx=vlist->n;
-			for(i=0;i<vesicle->poly_list->n;i++){
-				for(j=0;j<vesicle->poly_list->poly[i]->vlist->n;j++,poly_idx++){
-					fprintf(fh,"%.17e ", vesicle->poly_list->poly[i]->vlist->vtx[j]->c);
-				}
-			}
-		}
-		//filaments
-		if(fil){
-			poly_idx=vlist->n+monono*polyno;
-			for(i=0;i<vesicle->filament_list->n;i++){
-				for(j=0;j<vesicle->filament_list->poly[i]->vlist->n;j++,poly_idx++){
-		//	fprintf(stderr,"was here\n");
-					fprintf(fh,"%.17e ",  vesicle->filament_list->poly[i]->vlist->vtx[j]->c);
-				}
-			}
-		}
-    fprintf(fh,"</DataArray>\n");
-
-	//here comes additional data. Energy!
-	fprintf(fh,"<DataArray type=\"Float64\" Name=\"bending_energy\" format=\"ascii\">");
-	for(i=0;i<vlist->n;i++){
-		fprintf(fh,"%.17e ",vtx[i]->energy*vtx[i]->xk);
-	}
-		//polymeres
-		if(poly){
-			poly_idx=vlist->n;
-			for(i=0;i<vesicle->poly_list->n;i++){
-				for(j=0;j<vesicle->poly_list->poly[i]->vlist->n;j++,poly_idx++){
-					fprintf(fh,"%.17e ", vesicle->poly_list->poly[i]->vlist->vtx[j]->energy* vesicle->poly_list->poly[i]->k);
-				}
-			}
-		}
-		//filaments
-		if(fil){
-			poly_idx=vlist->n+monono*polyno;
-			for(i=0;i<vesicle->filament_list->n;i++){
-				for(j=0;j<vesicle->filament_list->poly[i]->vlist->n;j++,poly_idx++){
-		//	fprintf(stderr,"was here\n");
-					fprintf(fh,"%.17e ",  vesicle->filament_list->poly[i]->vlist->vtx[j]->energy*  vesicle->filament_list->poly[i]->k);
-				}
-			}
-		}
-    fprintf(fh,"</DataArray>\n");
-
-
-
 	
 	fprintf(fh,"</PointData>\n<CellData>\n</CellData>\n<Points>\n<DataArray type=\"Float64\" Name=\"Koordinate tock\" NumberOfComponents=\"3\" format=\"ascii\">\n");
 	for(i=0;i<vlist->n;i++){
@@ -994,17 +939,24 @@
 		}
 
 	}
-
+	for(i=0;i<vesicle->tlist->n;i++){
+		fprintf(fh,"%u %u %u\n", vesicle->tlist->tria[i]->vertex[0]->idx, vesicle->tlist->tria[i]->vertex[1]->idx, vesicle->tlist->tria[i]->vertex[2]->idx);
+	}
     fprintf(fh,"</DataArray>\n<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">");
     for (i=2;i<(blist->n+monono*polyno+(fonono-1)*filno)*2+1;i+=2){
     fprintf(fh,"%u ",i);
     }
+	for(j=i+1;j<i+3*(vesicle->tlist->n);j+=3){ //let's continue counting from where we left of
+		fprintf(fh,"%u ", j);
+	}
     fprintf(fh,"\n");
     fprintf(fh,"</DataArray>\n<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n");
-     for (i=0;i<blist->n+monono*polyno+fonono*filno;i++){
+     for (i=0;i<blist->n+monono*polyno+(fonono-1)*filno;i++){
         fprintf(fh,"3 ");
     }
-
+	for(i=0;i<vesicle->tlist->n;i++){
+		fprintf(fh,"5 ");
+	}
     fprintf(fh,"</DataArray>\n</Cells>\n</Piece>\n</UnstructuredGrid>\n</VTKFile>\n");
     fclose(fh);
     return TS_SUCCESS;
diff --git a/src/main.c b/src/main.c
index 7c1ff29..c2e51af 100644
--- a/src/main.c
+++ b/src/main.c
@@ -54,13 +54,13 @@
 		if(fd!=NULL){
 			arguments_no=fscanf(fd,"%u", &start_iteration);
 			if(arguments_no==0){
-				ts_fprintf(stdout,"No information of start iteration in .status file");
+				ts_fprintf(stdout,"No information of start iteration in .status file\n");
 				}
 			fclose(fd);
-			start_iteration++;
+			start_iteration++; 
 		}
 		else
-			ts_fprintf(stdout,"No .status file. The iteration count will start from 0");
+			ts_fprintf(stdout,"No .status file. The iteration count will start from 0\n");
 /* Here you should read new tape file, reassign some values in vertex from the tape and assign read tape to vesicle->tape */
 //        tape=parsetape(command_line_args.tape_fullfilename);
   //      vesicle=vtk2vesicle(command_line_args.dump_from_vtk,tape);
diff --git a/src/tape b/src/tape
index 0784fac..2e8b8c7 100644
--- a/src/tape
+++ b/src/tape
@@ -1,6 +1,6 @@
 ####### Vesicle definitions ###########
 # nshell is a number of divisions of dipyramid
-nshell=17
+nshell=5
 # dmax is the max. bond length (in units l_min)
 dmax=1.7
 # dmin_interspecies in the min. dist. between different vertex species (in units l_min)
@@ -25,26 +25,26 @@
 
 ####### Polymer (brush) definitions ###########
 # npoly is a number of polymers attached to npoly distinct vertices on vesicle
-npoly=3
+npoly=0
 # nmono is a number of monomers in each polymer
-nmono=10
+nmono=2
 # Spring constant between monomers of the polymer
 k_spring=800
 
 ####### Filament (inside the vesicle) definitions ###########
 # nfil is a number of filaments inside the vesicle
-nfil=2
+nfil=0
 # nfono is a number of monomers in each filament
-nfono=300
+nfono=3
 # Persistence lenght of the filaments (in units l_min)
 xi=100
 
 ####### Nucleus (inside the vesicle) ###########
 # Radius of an impenetrable hard sphere inside the vesicle
 R_nucleus=0
-R_nucleusX=6.0
-R_nucleusY=12.0
-R_nucleusZ=6.0
+R_nucleusX=0
+R_nucleusY=0
+R_nucleusZ=0
 #######  Cell definitions ############
 nxmax=60
 nymax=60
@@ -57,7 +57,7 @@
 mcsweeps=200
 #how many initial mcsweeps*inititer MC sweeps before recording to disk?
 #2
-inititer=0
+inititer=10
 #how many records do you want on the disk iteration are there in a run?
 #10000
 iterations=100
diff --git a/src/timestep.c b/src/timestep.c
index 6328b0f..be14619 100644
--- a/src/timestep.c
+++ b/src/timestep.c
@@ -60,11 +60,6 @@
 /* RANDOM SEED SET BY CURRENT TIME */
 	epochtime=get_epoch();			
 	srand48(epochtime);
-/*Nir Gov: randomly add spontaneous curvature for some vertices */
-	for(i=0;i<20;i++){
-		int b=rand() % vesicle->vlist->n;
-		vesicle->vlist->vtx[b]->c=-0.5;
-	}
 	centermass(vesicle);
 	cell_occupation(vesicle);
 	vesicle_volume(vesicle); //needed for constant volume at this moment

--
Gitblit v1.9.3