runSolver.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import ivp
  2. import os
  3. import cModel
  4. import sys
  5. import json
  6. import numpy
  7. import time
  8. import scipy.interpolate
  9. defaultValues={\
  10. 'method':'LSODA',\
  11. 'atol':1e-4,\
  12. 'rtol':1e-4,\
  13. 'tmax':1,\
  14. 'mode':'IVPSimultaneous',\
  15. 'nt':201,
  16. 'tUnit':'day'}
  17. def get(setup,par):
  18. try:
  19. return setup[par]
  20. except KeyError:
  21. pass
  22. return defaultValues[par]
  23. def parseSetup(setupFile):
  24. with open(setupFile,'r') as f:
  25. setup=json.load(f)
  26. out={}
  27. for p in defaultValues:
  28. out[p]=get(setup,p)
  29. return out
  30. def getScale(setup):
  31. tUnit=setup['tUnit']
  32. if tUnit=='min':
  33. return 1
  34. if tUnit=='hour':
  35. return 60
  36. if tUnit=='day':
  37. return 24*60
  38. if tUnit=='month':
  39. return 24*60*30
  40. if tUnit=='year':
  41. return 24*60*30*365
  42. return 1
  43. def main(parFiles,jobDir):
  44. model=cModel.model()
  45. setupFile=parFiles[0]
  46. modelFile=parFiles[1]
  47. parameterFile=parFiles[2]
  48. model.parse(modelFile,parameterFile)
  49. setup=parseSetup(setupFile)
  50. scale=getScale(setup)
  51. tmax=setup['tmax']*scale
  52. start_time=time.time()
  53. if setup['mode']=='SequentialOdeint':
  54. t,sol,se,s1=ivp.solveSequentialOdeint(model,tmax,setup['nt'])
  55. if setup['mode']=='SimultaneousOdeint':
  56. t,sol,se,s1=ivp.solveSimultaneousOdeint(model,tmax,setup['nt'])
  57. if setup['mode']=='IVP':
  58. t,sol,se,s1=ivp.solveSequential(model,tmax,atol=setup['atol'],
  59. rtol=setup['rtol'],method=setup['method'])
  60. if setup['mode']=='IVPSimultaneous':
  61. t,sol,se,s1=ivp.solveSimultaneous(model,tmax,atol=setup['atol'],
  62. rtol=setup['rtol'],method=setup['method'])
  63. end_time=time.time()
  64. print('Time: {:.3f} s'.format(end_time-start_time))
  65. #store
  66. #interpolate on s1
  67. #s1 has shape ft x n x m
  68. #where ft is LSODE driven number of points
  69. qt,sOut=interpolate(setup,model,t,s1,tmax)
  70. numpy.savetxt(os.path.join(jobDir,'t.txt'),t)
  71. numpy.savetxt(os.path.join(jobDir,'sol.txt'),sol)
  72. numpy.savetxt(os.path.join(jobDir,'se.txt'),se)
  73. numpy.savetxt(os.path.join(jobDir,'qt.txt'),qt)
  74. #this is 3D, so new routines
  75. write3D(os.path.join(jobDir,'sOut.txt'),sOut)
  76. def interpolate(setup,model,t,s1,tmax):
  77. #interpolate on s1
  78. #s1 has shape ft x n x m
  79. #where ft is LSODE driven number of points
  80. sOut=numpy.zeros((setup['nt'],model.n,model.m))
  81. qt=numpy.linspace(0,tmax,setup['nt'])
  82. for i in range(model.n):
  83. for j in range(model.m):
  84. y=s1[:,i,j]
  85. f = scipy.interpolate.interp1d(t, y, kind='cubic')
  86. sOut[:,i,j]=f(qt)
  87. return qt,sOut
  88. def write3D(fName,a):
  89. with open(fName,'w') as f:
  90. f.write('#Shape {}\n'.format(a.shape))
  91. i=0
  92. for data_slice in a:
  93. f.write('#\t Slice {}\n'.format(i))
  94. numpy.savetxt(f,data_slice)
  95. i+=1
  96. def read3D(fName):
  97. new_data=numpy.loadtxt(fName)
  98. #read and parse first row to get shape
  99. with open(fName,'r') as f:
  100. firstLine=f.readline()
  101. shape=firstLine.replace('#Shape ','').\
  102. replace('\n','').\
  103. replace('(','').\
  104. replace(')','').\
  105. split(',')
  106. shape=[int(x) for x in shape]
  107. return new_data.reshape(shape)
  108. if __name__=="__main__":
  109. parFiles=sys.argv[1].split(';')
  110. jobDir=sys.argv[2]
  111. main(parFiles,jobDir)