Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CellMLToNektar.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 """Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 """
34 
35 """
36 This part of PyCml deals with converting CellML models into programming language code.
37 It is a thin executable wrapper around translators.py.
38 """
39 
40 import os #importing functions related to operating system
41 import sys #importing functions related to system (e.g. path directory etc)
42 
43 # Make sure PyCml is on sys.path
44 pycml_path = os.path.dirname(os.path.realpath(__file__))
45 sys.path[0:0] = [pycml_path]
46 
47 import translators #importing the main translator class
48 from translators import CellMLTranslator #again, just to make sure
49 import CellMLToNektarTranslator #importing the nektar sub-class
50 
51 #This part actually runs the code
52 
53 if __name__ == '__main__': #this part of the code is only run when CellMLToNektar.py is run directly, not imported
54  CellMLTranslator.register(CellMLTranslator, 'C++') #this registers the main translator and it's name when called as an option in modified_translators
55  CellMLTranslator.register(CellMLToNektarTranslator.CellMLToNektarTranslator, 'Nektar') #this registers the nektar subclass and it's name when called as an option in modified_translators
56  if '--profile' in sys.argv: #sys.argv is the list of command line items passed to the script, this checks if a specific translator is requested
57  import time, cProfile
58  profile_name = '/tmp/pycml-profile-%f-%d' % (time.time(), os.getpid())
59  cProfile.run('modified_translators.run()', profile_name) #the requested translator is run
60  else:
61  translators.run() #if no specific translator is requested, the default run function in modified_translators is run
62 
63 #Below here seem to be variables that do some form of testing
64 
65  # For use in testing
66  def euler(doc, t, nsteps=1000, dt=0.01):
67  global tvar, state_vars, exprs #assigns tvar, state_vars and exprs to be global variables, meaning they can be used by any function
68  tvar = t.free_vars[0] #takes the t-input and does "free_vars[0]" to it?
69  state_vars = t.state_vars #defines state_vars as the state_vars of the t-input?
70  for var in state_vars: #cycles through all the entries in "state_vars"
71  var.set_value(float(var.initial_value)) #for all the entries in "state_vars" it sets the value to a float of the initial value
72  tvar.set_value(0.0) #this sets the value of tvars to (0.0)?
73  exprs = [e for e in doc.model.get_assignments() #I don't understand this part
74  if isinstance(e, modified_translators.mathml_apply)] #what is the mathml_apply function? Can't find it in modified_translators
75  for _ in range(nsteps): #this is a for-loop through all the values up to the input of nsteps
76  for expr in exprs: #this cycles through all the entries in exprs
77  expr.evaluate()
78  tvar.set_value(tvar.get_value() + dt)
79  for var in state_vars:
80  var.set_value(var.get_value() +
81  dt * var.get_value(ode=tvar))
82  return
83 
84  def writefile(doc, outfn='test.cml'):
85  # Write out CellML file
86  st = modified_translators.open_output_stream(outfn)
87  doc.xml(indent=1, stream=st)
88  st.close()
89  return
90 
91  def show_usage(doc):
92  for comp in doc.model.component:
93  for var in comp.variable:
94  print var.fullname(), var._cml_usage_count
95 
96 
98  """
99  Several models have equations of a form that may give rise to
100  a divide by zero error on simulation, especially when lookup
101  tables are used. The general form is:
102 
103  (a * (V - v0)) / (exp(b * (V - v0)) - 1)
104 
105  When V = v0 this is undefined, however the limit of the
106  function as V approaches v0 from either side is well-defined,
107  and each limit is the same. We approximate the limit by
108  linear interpolation between values of the expression for
109  (V-v0) = +/- 1e-10.
110  """
111  divides = [d.xml_parent
112  for d in doc.xml_xpath(u'//m:apply/m:divide')]
113  for divide in divides:
114  pass
115  return