Nektar++
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
CellMLToNektar.translators.SolverInfo Class Reference
Inheritance diagram for CellMLToNektar.translators.SolverInfo:
[legend]

Public Member Functions

def __init__ (self, model, force=False)
 
def add_all_info (self)
 
def add_dt_reference (self)
 
def add_transmembrane_potential_name (self)
 
def add_linearised_odes (self)
 
def add_jacobian_matrix (self)
 
def use_canonical_variable_names (self)
 
def add_membrane_ionic_current (self)
 
def add_linear_ode_update_equations (self)
 
def add_variable_links (self)
 
def do_binding_time_analysis (self)
 
def has_modifiable_mathematics (self)
 
def get_modifiable_mathematics (self)
 
def get_linearised_odes (self)
 
def create_dt (self, modifier, comp, units)
 
def get_dt (self)
 

Private Member Functions

def _fix_jac_var_name (self, vname)
 
def _check_state_var_units_conversions (self)
 
def _process_mathematics (self, func)
 
def _add_variable_links (self, elt)
 
def _get_variable (self, varname)
 
def _get_special_variable (self, varname, ptype=VarTypes.Unknown)
 
def _get_special_component (self)
 

Private Attributes

 _model
 
 _solver_info
 
 _component
 
 _dt
 

Static Private Attributes

 _jac_temp_re = re.compile(r't[0-9]+')
 

Detailed Description

Add information for specialised translator classes into a model.

Definition at line 1359 of file translators.py.

Constructor & Destructor Documentation

◆ __init__()

def CellMLToNektar.translators.SolverInfo.__init__ (   self,
  model,
  force = False 
)
Add information for the solvers as XML.

The Jacobian and linearity analyses store their results in
Python data structures as attributes of this object.
Transcribe these into XML in a child <solver_info> element.

If any of these elements exist in the model they will be left
unaltered, unless force is set to True.

This constructor just sets up the container element; call one
of the add_* methods to actually add the information to it.

Definition at line 1361 of file translators.py.

1361  def __init__(self, model, force=False):
1362  """Add information for the solvers as XML.
1363 
1364  The Jacobian and linearity analyses store their results in
1365  Python data structures as attributes of this object.
1366  Transcribe these into XML in a child <solver_info> element.
1367 
1368  If any of these elements exist in the model they will be left
1369  unaltered, unless force is set to True.
1370 
1371  This constructor just sets up the container element; call one
1372  of the add_* methods to actually add the information to it.
1373  """
1374  self._model = model
1375  if force and hasattr(model, u'solver_info'):
1376  model.xml_remove_child(model.solver_info)
1377  if hasattr(model, u'solver_info'):
1378  solver_info = model.solver_info
1379  else:
1380  solver_info = model.xml_create_element(u'solver_info', NSS[u'solver'])
1381  model.xml_append(solver_info)
1382  self._solver_info = solver_info
1383  self._component = None
1384  self._dt = None
1385 

Member Function Documentation

◆ _add_variable_links()

def CellMLToNektar.translators.SolverInfo._add_variable_links (   self,
  elt 
)
private
Recursively link ci elements in the given XML tree to cellml_variable objects.

Also sets component links: for ci elements, to the component containing the linked
variable, and for cn elements, to the first component in the model.

Definition at line 1743 of file translators.py.

1743  def _add_variable_links(self, elt):
1744  """Recursively link ci elements in the given XML tree to cellml_variable objects.
1745 
1746  Also sets component links: for ci elements, to the component containing the linked
1747  variable, and for cn elements, to the first component in the model.
1748  """
1749  if isinstance(elt, mathml_ci):
1750  var = self._get_variable(unicode(elt))
1751  elt._cml_variable = var
1752  elt._cml_component = var.component
1753  elif isinstance(elt, mathml_cn):
1754  # Fake a component, since it doesn't really have one
1755  elt._cml_component = elt.model.component
1756  elif hasattr(elt, 'xml_children'):
1757  for child in elt.xml_children:
1758  self._add_variable_links(child)
1759 

References CellMLToNektar.translators.SolverInfo._add_variable_links(), and CellMLToNektar.translators.SolverInfo._get_variable().

Referenced by CellMLToNektar.translators.SolverInfo._add_variable_links(), CellMLToNektar.translators.SolverInfo.add_linear_ode_update_equations(), and CellMLToNektar.translators.SolverInfo.add_variable_links().

◆ _check_state_var_units_conversions()

def CellMLToNektar.translators.SolverInfo._check_state_var_units_conversions (   self)
private
Check if any Jacobian entries need to be altered because the units of state variables have changed.

If any variable considered a state variable by the Jacobian is now of type Computed then it has been
converted.  We figure out the conversion factor, update the Jacobian to reference the new state variable,
and units-convert the derivative.

Definition at line 1604 of file translators.py.

1604  def _check_state_var_units_conversions(self):
1605  """Check if any Jacobian entries need to be altered because the units of state variables have changed.
1606 
1607  If any variable considered a state variable by the Jacobian is now of type Computed then it has been
1608  converted. We figure out the conversion factor, update the Jacobian to reference the new state variable,
1609  and units-convert the derivative.
1610  """
1611  if not hasattr(self._solver_info, u'jacobian'):
1612  return
1613  # Helper methods
1614  def set_var_values(elt, vars=None):
1615  """Fake all variables appearing in the given expression being set to 1.0, and return them."""
1616  if vars is None:
1617  vars = []
1618  if isinstance(elt, mathml_ci):
1619  elt.variable.set_value(1.0)
1620  vars.append(elt.variable)
1621  else:
1622  for child in getattr(elt, 'xml_children', []):
1623  set_var_values(child, vars)
1624  return vars
1625  # Find any converted state variables
1626  converted_state_vars = set()
1627  for entry in getattr(self._solver_info.jacobian, u'entry', []):
1628  var = self._get_variable(entry.var_i)
1629  if var.get_type() == VarTypes.Computed:
1630  converted_state_vars.add(var)
1631  if not converted_state_vars:
1632  return
1633  # Figure out the conversion factor in each case
1634  state_var_map = {}
1635  for var in converted_state_vars:
1636  defn = var.get_dependencies()[0]
1637  defn_vars = set_var_values(defn.eq.rhs)
1638  assert len(defn_vars) == 1, "Unexpected form of units conversion expression found"
1639  factor = defn.eq.rhs.evaluate()
1640  state_var_map[var] = (defn_vars[0], factor)
1641  defn_vars[0].unset_values()
1642  # Apply the conversion to relevant Jacobian entries
1643  for entry in getattr(self._solver_info.jacobian, u'entry', []):
1644  factor = 1
1645  var_i = self._get_variable(entry.var_i)
1646  if var_i in converted_state_vars:
1647  var_i, factor_i = state_var_map[var_i]
1648  var_i = var_i.get_source_variable(recurse=True)
1649  entry.var_i = unicode(var_i.fullname())
1650  factor /= factor_i
1651  var_j = self._get_variable(entry.var_j)
1652  if var_j in converted_state_vars:
1653  var_j, factor_j = state_var_map[var_j]
1654  var_j = var_j.get_source_variable(recurse=True)
1655  entry.var_j = unicode(var_j.fullname())
1656  factor *= factor_j
1657  if factor != 1:
1658  # Replace rhs with rhs * factor
1659  rhs = list(entry.math.xml_element_children())[0]
1660  entry.math.safe_remove_child(rhs)
1661  new_rhs = mathml_apply.create_new(entry, 'times', [(factor, 'dimensionless'), rhs])
1662  entry.math.xml_append(new_rhs)
1663 

References CellMLToNektar.translators.SolverInfo._get_variable(), and CellMLToNektar.translators.SolverInfo._solver_info.

Referenced by CellMLToNektar.translators.SolverInfo.add_variable_links().

◆ _fix_jac_var_name()

def CellMLToNektar.translators.SolverInfo._fix_jac_var_name (   self,
  vname 
)
private
If PE will be performed on a model with a single component, then we'll need full names in
the variable attributes.

Definition at line 1458 of file translators.py.

1458  def _fix_jac_var_name(self, vname):
1459  """
1460  If PE will be performed on a model with a single component, then we'll need full names in
1461  the variable attributes.
1462  """
1463  if vname[:4] == 'var_' and len(self._model.component) == 1 and not self._model.component.ignore_component_name:
1464  name = unicode('var_' + self._model.component.name + '__' + vname[4:])
1465  else:
1466  name = unicode(vname)
1467  return name
1468 

References CellMLToNektar.translators.SolverInfo._model.

Referenced by CellMLToNektar.translators.SolverInfo.add_jacobian_matrix().

◆ _get_special_component()

def CellMLToNektar.translators.SolverInfo._get_special_component (   self)
private
Get or create a special component for containing special variables.

Definition at line 1798 of file translators.py.

1798  def _get_special_component(self):
1799  """Get or create a special component for containing special variables."""
1800  if not self._component:
1801  self._component = cellml_component.create_new(self._model, u'')
1802  self._model._add_component(self._component, special=True)
1803  return self._component
1804 
1805 
1806 

References CellMLToNektar.translators.SolverInfo._component, and CellMLToNektar.translators.SolverInfo._model.

Referenced by CellMLToNektar.translators.SolverInfo._get_special_variable(), CellMLToNektar.translators.SolverInfo.add_jacobian_matrix(), and CellMLToNektar.translators.SolverInfo.add_linearised_odes().

◆ _get_special_variable()

def CellMLToNektar.translators.SolverInfo._get_special_variable (   self,
  varname,
  ptype = VarTypes.Unknown 
)
private
Get or create a special variable object that doesn't really exist in the model.

Definition at line 1787 of file translators.py.

1787  def _get_special_variable(self, varname, ptype=VarTypes.Unknown):
1788  """Get or create a special variable object that doesn't really exist in the model."""
1789  comp = self._get_special_component()
1790  try:
1791  var = comp.get_variable_by_name(varname)
1792  except KeyError:
1793  var = cellml_variable.create_new(self._model, varname, u'dimensionless')
1794  comp._add_variable(var)
1795  var._set_type(ptype)
1796  return var
1797 

References CellMLToNektar.translators.SolverInfo._get_special_component(), and CellMLToNektar.translators.SolverInfo._model.

Referenced by CellMLToNektar.translators.SolverInfo._get_variable(), and CellMLToNektar.translators.SolverInfo.get_dt().

◆ _get_variable()

def CellMLToNektar.translators.SolverInfo._get_variable (   self,
  varname 
)
private
Return the variable in the model with name varname.

Definition at line 1761 of file translators.py.

1761  def _get_variable(self, varname):
1762  """Return the variable in the model with name varname."""
1763  try:
1764  if varname == 'delta_t':
1765  # Special case for the timestep in ComputeJacobian and elsewhere
1766  var = self.get_dt()
1767  elif self._jac_temp_re.match(varname):
1768  var = self._get_special_variable(varname, VarTypes.Unknown)
1769  else:
1770  var = cellml_variable.get_variable_object(self._model, varname)
1771  except KeyError:
1772  raise ValueError("Cannot find variable '%s' referenced in SolverInfo" % varname)
1773  return var
1774 

References CellMLToNektar.translators.SolverInfo._get_special_variable(), CellMLToNektar.translators.SolverInfo._jac_temp_re, CellMLToNektar.translators.SolverInfo._model, and CellMLToNektar.translators.SolverInfo.get_dt().

Referenced by CellMLToNektar.translators.SolverInfo._add_variable_links(), CellMLToNektar.translators.SolverInfo._check_state_var_units_conversions(), and CellMLToNektar.translators.SolverInfo.use_canonical_variable_names().

◆ _process_mathematics()

def CellMLToNektar.translators.SolverInfo._process_mathematics (   self,
  func 
)
private
Apply func to each top-level mathematical construct in the solver info blocks.

func must be able to accept mathml_piecewise, mathml_apply, mathml_ci and mathml_cn elements.

Definition at line 1671 of file translators.py.

1671  def _process_mathematics(self, func):
1672  """Apply func to each top-level mathematical construct in the solver info blocks.
1673 
1674  func must be able to accept mathml_piecewise, mathml_apply, mathml_ci and mathml_cn elements.
1675  """
1676  solver_info = self._solver_info
1677  # Jacobian
1678  if hasattr(solver_info, u'jacobian'):
1679  if hasattr(solver_info.jacobian, u'math'):
1680  for elt in solver_info.jacobian.math.apply:
1681  func(elt)
1682  for entry in solver_info.jacobian.entry:
1683  for elt in entry.math.xml_element_children():
1684  func(elt)
1685  # Linearised ODEs
1686  if hasattr(solver_info, u'linear_odes'):
1687  for math in solver_info.linear_odes.math:
1688  for elt in math.xml_element_children():
1689  func(elt)
1690 

References CellMLToNektar.translators.SolverInfo._solver_info.

Referenced by CellMLToNektar.translators.SolverInfo.add_variable_links(), and CellMLToNektar.translators.SolverInfo.do_binding_time_analysis().

◆ add_all_info()

def CellMLToNektar.translators.SolverInfo.add_all_info (   self)
Actually add the info.

Definition at line 1386 of file translators.py.

1386  def add_all_info(self):
1387  """Actually add the info."""
1388  self.add_transmembrane_potential_name()
1389  self.add_membrane_ionic_current()
1390  self.add_linearised_odes()
1391  self.add_jacobian_matrix()
1392  self.add_dt_reference()
1393 

References CellMLToNektar.translators.SolverInfo.add_dt_reference(), CellMLToNektar.translators.SolverInfo.add_jacobian_matrix(), CellMLToNektar.translators.SolverInfo.add_linearised_odes(), CellMLToNektar.translators.SolverInfo.add_membrane_ionic_current(), and CellMLToNektar.translators.SolverInfo.add_transmembrane_potential_name().

◆ add_dt_reference()

def CellMLToNektar.translators.SolverInfo.add_dt_reference (   self)
Add a reference to the variable representing dt.

Definition at line 1394 of file translators.py.

1394  def add_dt_reference(self):
1395  """Add a reference to the variable representing dt."""
1396  solver_info = self._solver_info
1397  model = self._model
1398  if not hasattr(solver_info, u'dt'):
1399  dt = self.get_dt()
1400  elt = model.xml_create_element(u'dt', NSS[u'solver'], content=dt.fullname(cellml=True))
1401  solver_info.xml_append(elt)
1402  self._model._add_sorted_assignment(dt)
1403 

References CellMLToNektar.translators.SolverInfo._model, CellMLToNektar.translators.SolverInfo._solver_info, and CellMLToNektar.translators.SolverInfo.get_dt().

Referenced by CellMLToNektar.translators.SolverInfo.add_all_info().

◆ add_jacobian_matrix()

def CellMLToNektar.translators.SolverInfo.add_jacobian_matrix (   self)
Jacobian matrix elements.

Structure looks like:
<jacobian>
    [<math> assignments of common sub-terms </math>]
    <entry var_i='varname' var_j='varname'>
        <math> apply|cn|ci ...</math>
    </entry>
</jacobian>

Definition at line 1469 of file translators.py.

1469  def add_jacobian_matrix(self):
1470  """Jacobian matrix elements.
1471 
1472  Structure looks like:
1473  <jacobian>
1474  [<math> assignments of common sub-terms </math>]
1475  <entry var_i='varname' var_j='varname'>
1476  <math> apply|cn|ci ...</math>
1477  </entry>
1478  </jacobian>
1479  """
1480  solver_info = self._solver_info
1481  model = self._model
1482  if model._cml_jacobian and model._cml_jacobian_full:
1483  jac = model._cml_jacobian[1]
1484  else:
1485  # Old-style partial jacobian, or no jacobian
1486  jac = model._cml_jacobian
1487  if not hasattr(solver_info, u'jacobian') and jac:
1488  jac_elt = model.xml_create_element(u'jacobian', NSS[u'solver'])
1489  solver_info.xml_append(jac_elt)
1490 
1491  if model._cml_jacobian_full:
1492  # There may be temporaries
1493  temporaries = model._cml_jacobian[0]
1494  if temporaries:
1495  jac_elt.xml_append(amara_parse_cellml(temporaries).math)
1496 
1497  jac_vars = jac.keys()
1498  jac_vars.sort() # Will sort by variable name
1499  for v_i, v_j in jac_vars:
1500  # Add (i,j)-th entry
1501  attrs = {u'var_i': self._fix_jac_var_name(v_i),
1502  u'var_j': self._fix_jac_var_name(v_j)}
1503  entry = model.xml_create_element(u'entry', NSS[u'solver'], attributes=attrs)
1504  jac_elt.xml_append(entry)
1505  entry_doc = amara_parse_cellml(jac[(v_i, v_j)].xml())
1506  entry.xml_append(entry_doc.math)
1507  # Ensure that the model has a special component
1508  self._get_special_component()
1509  return
1510 
def amara_parse_cellml(source, uri=None, prefixes=None)
Definition: pycml.py:191

References CellMLToNektar.translators.SolverInfo._fix_jac_var_name(), CellMLToNektar.translators.SolverInfo._get_special_component(), CellMLToNektar.translators.SolverInfo._model, CellMLToNektar.translators.SolverInfo._solver_info, and CellMLToNektar.pycml.amara_parse_cellml().

Referenced by CellMLToNektar.translators.SolverInfo.add_all_info().

◆ add_linear_ode_update_equations()

def CellMLToNektar.translators.SolverInfo.add_linear_ode_update_equations (   self)
Add the update equations for the linear ODEs.

A linear ODE has the form du/dt = g+h.u where g & h are not functions of u.  The
update expression then looks like u = (u + g.dt)/(1 - h.dt).

This replaces the linear_odes block with the structure:
<linear_odes>
    <math>
        <ci>u</ci>
        <ci>t</ci>
        <apply> <!-- (u + g.dt)/(1 - h.dt) --> </apply>
    </math>
    .
    .
    .
</linear_odes>

Definition at line 1547 of file translators.py.

1547  def add_linear_ode_update_equations(self):
1548  """Add the update equations for the linear ODEs.
1549 
1550  A linear ODE has the form du/dt = g+h.u where g & h are not functions of u. The
1551  update expression then looks like u = (u + g.dt)/(1 - h.dt).
1552 
1553  This replaces the linear_odes block with the structure:
1554  <linear_odes>
1555  <math>
1556  <ci>u</ci>
1557  <ci>t</ci>
1558  <apply> <!-- (u + g.dt)/(1 - h.dt) --> </apply>
1559  </math>
1560  .
1561  .
1562  .
1563  </linear_odes>
1564  """
1565  block = getattr(self._solver_info, u'linear_odes', None)
1566  dt = self._model.get_config().dt_variable.fullname() # was dt = u'delta_t'
1567  # Add the new equations
1568  for u, t, gh in self.get_linearised_odes():
1569  g, h = gh
1570  g.safe_remove_child(g, g.xml_parent)
1571  g_dt = mathml_apply.create_new(block, u'times', [g, dt])
1572  numer = mathml_apply.create_new(block, u'plus', [u.fullname(), g_dt])
1573  h.safe_remove_child(h, h.xml_parent)
1574  h_dt = mathml_apply.create_new(block, u'times', [h, dt])
1575  denom = mathml_apply.create_new(block, u'minus', [(u'1', u'dimensionless'), h_dt])
1576  eqn = mathml_apply.create_new(block, u'divide', [numer, denom])
1577  math = block.xml_create_element(u'math', NSS[u'm'])
1578  math.xml_append(mathml_ci.create_new(block, u.fullname()))
1579  math.xml_append(mathml_ci.create_new(block, t.fullname()))
1580  math.xml_append(eqn)
1581  block.xml_append(math)
1582  self._add_variable_links(math)
1583  # Remove the old equations (first math element)
1584  block.xml_remove_child(block.math)
1585 

References CellMLToNektar.translators.SolverInfo._add_variable_links(), CellMLToNektar.translators.SolverInfo._model, CellMLToNektar.translators.SolverInfo._solver_info, and CellMLToNektar.translators.SolverInfo.get_linearised_odes().

◆ add_linearised_odes()

def CellMLToNektar.translators.SolverInfo.add_linearised_odes (   self)
Linearised ODEs - where du/dt = g + hu (and g, h are not functions of u).

Structure looks like:
<linear_odes>
    <math>
        <apply><eq/>
            <apply><diff/>
                <bvar><ci>t</ci></bvar>
                <ci>u</ci>
            </apply>
            <apply><plus/>
                g
                <apply><times/>
                    h
                    <ci>u</ci>
                </apply>
            </apply>
        </apply>
        .
        .
        .
    </math>
</linear_odes>

Definition at line 1414 of file translators.py.

1414  def add_linearised_odes(self):
1415  """Linearised ODEs - where du/dt = g + hu (and g, h are not functions of u).
1416 
1417  Structure looks like:
1418  <linear_odes>
1419  <math>
1420  <apply><eq/>
1421  <apply><diff/>
1422  <bvar><ci>t</ci></bvar>
1423  <ci>u</ci>
1424  </apply>
1425  <apply><plus/>
1426  g
1427  <apply><times/>
1428  h
1429  <ci>u</ci>
1430  </apply>
1431  </apply>
1432  </apply>
1433  .
1434  .
1435  .
1436  </math>
1437  </linear_odes>
1438  """
1439  solver_info = self._solver_info
1440  model = self._model
1441  if not hasattr(solver_info, u'linear_odes') and model._cml_linear_update_exprs:
1442  odes_elt = model.xml_create_element(u'linear_odes', NSS[u'solver'])
1443  solver_info.xml_append(odes_elt)
1444  odes_math = model.xml_create_element(u'math', NSS[u'm'])
1445  odes_elt.xml_append(odes_math)
1446  linear_vars = model._cml_linear_update_exprs.keys()
1447  linear_vars.sort(key=lambda v: v.fullname())
1448  free_var = model._cml_free_var
1449  for var in linear_vars:
1450  g, h = model._cml_linear_update_exprs[var]
1451  hu = mathml_apply.create_new(model, u'times', [h, var.fullname()])
1452  rhs = mathml_apply.create_new(model, u'plus', [g, hu])
1453  odes_math.xml_append(mathml_diff.create_new(
1454  model, free_var.fullname(), var.fullname(), rhs))
1455  # Ensure that the model has a special component
1456  self._get_special_component()
1457 

References CellMLToNektar.translators.SolverInfo._get_special_component(), CellMLToNektar.translators.SolverInfo._model, and CellMLToNektar.translators.SolverInfo._solver_info.

Referenced by CellMLToNektar.translators.SolverInfo.add_all_info().

◆ add_membrane_ionic_current()

def CellMLToNektar.translators.SolverInfo.add_membrane_ionic_current (   self)
Add ionic current information as XML for solvers to use.

Definition at line 1530 of file translators.py.

1530  def add_membrane_ionic_current(self):
1531  """Add ionic current information as XML for solvers to use."""
1532  solver_info = self._solver_info
1533  model = self._model
1534  # The total ionic current. This relies on having a configuration store.
1535  if hasattr(model.xml_parent, '_cml_config') and not hasattr(solver_info, u'ionic_current'):
1536  conf = model.xml_parent._cml_config
1537  if conf.i_ionic_vars:
1538  ionic_elt = model.xml_create_element(u'ionic_current', NSS[u'solver'])
1539  # Adds each ionic var to the xml doc from the config store
1540  for var in conf.i_ionic_vars:
1541  varelt = model.xml_create_element(u'var', NSS[u'solver'],
1542  content=var.fullname())
1543  ionic_elt.xml_append(varelt)
1544  solver_info.xml_append(ionic_elt)
1545  return
1546 

References CellMLToNektar.translators.SolverInfo._model, and CellMLToNektar.translators.SolverInfo._solver_info.

Referenced by CellMLToNektar.translators.SolverInfo.add_all_info().

◆ add_transmembrane_potential_name()

def CellMLToNektar.translators.SolverInfo.add_transmembrane_potential_name (   self)
The name of the transmembrane potential.

Definition at line 1404 of file translators.py.

1404  def add_transmembrane_potential_name(self):
1405  """The name of the transmembrane potential."""
1406  solver_info = self._solver_info
1407  model = self._model
1408  if not hasattr(solver_info, u'transmembrane_potential'):
1409  v_elt = model.xml_create_element(
1410  u'transmembrane_potential', NSS[u'solver'],
1411  content=model._cml_transmembrane_potential.fullname())
1412  solver_info.xml_append(v_elt)
1413 

References CellMLToNektar.translators.SolverInfo._model, and CellMLToNektar.translators.SolverInfo._solver_info.

Referenced by CellMLToNektar.translators.SolverInfo.add_all_info().

◆ add_variable_links()

def CellMLToNektar.translators.SolverInfo.add_variable_links (   self)
Link ci elements in the added XML to cellml_variable objects.

This analyses the names in the ci elements to determine which variable in
the model they refer to.

Definition at line 1586 of file translators.py.

1586  def add_variable_links(self):
1587  """Link ci elements in the added XML to cellml_variable objects.
1588 
1589  This analyses the names in the ci elements to determine which variable in
1590  the model they refer to.
1591  """
1592  self._process_mathematics(self._add_variable_links)
1593  #1795 - classify temporary variables for the Jacobian matrix, and append
1594  # to the main list of assignments in the model
1595  solver_info = self._solver_info
1596  if hasattr(solver_info, u'jacobian') and hasattr(solver_info.jacobian, u'math'):
1597  for elt in solver_info.jacobian.math.apply:
1598  elt.classify_variables(root=True)
1599  for elt in solver_info.jacobian.math.apply:
1600  self._model.topological_sort(elt)
1601  #2418 - check if any state variables have been units-converted
1602  self._check_state_var_units_conversions()
1603 

References CellMLToNektar.translators.SolverInfo._add_variable_links(), CellMLToNektar.translators.SolverInfo._check_state_var_units_conversions(), CellMLToNektar.translators.SolverInfo._model, CellMLToNektar.translators.SolverInfo._process_mathematics(), and CellMLToNektar.translators.SolverInfo._solver_info.

◆ create_dt()

def CellMLToNektar.translators.SolverInfo.create_dt (   self,
  modifier,
  comp,
  units 
)
Create the special 'dt' variable in the given component.

Definition at line 1775 of file translators.py.

1775  def create_dt(self, modifier, comp, units):
1776  """Create the special 'dt' variable in the given component."""
1777  self._dt = modifier.add_variable(comp, modifier._uniquify_var_name(u'dt', comp), units)
1778  self._dt._set_type(VarTypes.Free)
1779  return self._dt
1780 

References CellMLToNektar.translators.SolverInfo._dt.

◆ do_binding_time_analysis()

def CellMLToNektar.translators.SolverInfo.do_binding_time_analysis (   self)
Do a binding time analysis on the additional mathematics.

This requires self.add_variable_links to have been called already.

Definition at line 1664 of file translators.py.

1664  def do_binding_time_analysis(self):
1665  """Do a binding time analysis on the additional mathematics.
1666 
1667  This requires self.add_variable_links to have been called already.
1668  """
1669  self._process_mathematics(lambda elt: elt._get_binding_time())
1670 

References CellMLToNektar.translators.SolverInfo._process_mathematics().

◆ get_dt()

def CellMLToNektar.translators.SolverInfo.get_dt (   self)
Get or create a special 'dt' variable.

Definition at line 1781 of file translators.py.

1781  def get_dt(self):
1782  """Get or create a special 'dt' variable."""
1783  if not self._dt:
1784  self._dt = self._get_special_variable(u'dt', VarTypes.Free)
1785  return self._dt
1786 

References CellMLToNektar.translators.SolverInfo._dt, and CellMLToNektar.translators.SolverInfo._get_special_variable().

Referenced by CellMLToNektar.translators.SolverInfo._get_variable(), and CellMLToNektar.translators.SolverInfo.add_dt_reference().

◆ get_linearised_odes()

def CellMLToNektar.translators.SolverInfo.get_linearised_odes (   self)
Return an iterable over the linearised ODEs, i.e. ODEs of the form
du/dt = g + hu (with g, h not functions of u).

Yields tuples (u, t, eqns) where the form of eqns depends on whether
add_linear_ode_update_equations has been called.  If so, it is a 1-tuple
containing the update equation; if not, it is (g,h).

Definition at line 1719 of file translators.py.

1719  def get_linearised_odes(self):
1720  """Return an iterable over the linearised ODEs, i.e. ODEs of the form
1721  du/dt = g + hu (with g, h not functions of u).
1722 
1723  Yields tuples (u, t, eqns) where the form of eqns depends on whether
1724  add_linear_ode_update_equations has been called. If so, it is a 1-tuple
1725  containing the update equation; if not, it is (g,h).
1726  """
1727  if hasattr(self._solver_info, u'linear_odes'):
1728  if hasattr(self._solver_info.linear_odes.math, u'ci'):
1729  for math in self._solver_info.linear_odes.math:
1730  u, t, eqn = list(math.xml_element_children())
1731  u = u.variable
1732  t = t.variable
1733  yield (u, t, (eqn,))
1734  else:
1735  for ode in self._solver_info.linear_odes.math.apply:
1736  u = ode.apply.ci.variable
1737  t = ode.apply.bvar.ci.variable
1738  opers = ode.apply[1].operands()
1739  g = opers.next()
1740  h = opers.next().operands().next()
1741  yield (u, t, (g,h))
1742 

References CellMLToNektar.translators.SolverInfo._solver_info.

Referenced by CellMLToNektar.translators.SolverInfo.add_linear_ode_update_equations(), and CellMLToNektar.translators.SolverInfo.get_modifiable_mathematics().

◆ get_modifiable_mathematics()

def CellMLToNektar.translators.SolverInfo.get_modifiable_mathematics (   self)
Get an iterable over mathematical constructs in the solver info blocks that can be changed.

Returned elements will be mathml_piecewise, mathml_apply, mathml_ci or mathml_cn instances.

Definition at line 1699 of file translators.py.

1699  def get_modifiable_mathematics(self):
1700  """Get an iterable over mathematical constructs in the solver info blocks that can be changed.
1701 
1702  Returned elements will be mathml_piecewise, mathml_apply, mathml_ci or mathml_cn instances.
1703  """
1704  solver_info = self._solver_info
1705  # Jacobian - entry definitions and temporaries can be changed
1706  if hasattr(solver_info, u'jacobian'):
1707  if hasattr(solver_info.jacobian, u'math'):
1708  for elt in solver_info.jacobian.math.apply:
1709  yield elt
1710  for entry in solver_info.jacobian.entry:
1711  for elt in entry.math.xml_element_children():
1712  yield elt
1713  # Linearised ODEs - only g & h can be changed
1714  if hasattr(solver_info, u'linear_odes'):
1715  for _, _, eqns in self.get_linearised_odes():
1716  for eqn in eqns:
1717  yield eqn
1718 

References CellMLToNektar.translators.SolverInfo._solver_info, and CellMLToNektar.translators.SolverInfo.get_linearised_odes().

Referenced by CellMLToNektar.translators.SolverInfo.has_modifiable_mathematics().

◆ has_modifiable_mathematics()

def CellMLToNektar.translators.SolverInfo.has_modifiable_mathematics (   self)
Check if the solver info blocks contain any modifiable mathematics.

Definition at line 1691 of file translators.py.

1691  def has_modifiable_mathematics(self):
1692  """Check if the solver info blocks contain any modifiable mathematics."""
1693  try:
1694  self.get_modifiable_mathematics().next()
1695  return True
1696  except StopIteration:
1697  return False
1698 

References CellMLToNektar.translators.SolverInfo.get_modifiable_mathematics().

◆ use_canonical_variable_names()

def CellMLToNektar.translators.SolverInfo.use_canonical_variable_names (   self)
PE has just been performed, so we need to update variable names occurring outside
the modifiable mathematics sections.

Definition at line 1511 of file translators.py.

1511  def use_canonical_variable_names(self):
1512  """
1513  PE has just been performed, so we need to update variable names occurring outside
1514  the modifiable mathematics sections.
1515  """
1516  jac_elt = getattr(self._solver_info, u'jacobian', None)
1517  for entry in getattr(jac_elt, u'entry', []):
1518  for vlabel in ['var_i', 'var_j']:
1519  vname = getattr(entry, vlabel)
1520  var = self._get_variable(vname)
1521  new_name = var.get_source_variable(recurse=True).fullname()
1522  setattr(entry, vlabel, new_name)
1523  dt_elt = getattr(self._solver_info, u'dt', None)
1524  if dt_elt:
1525  var = self._get_variable(unicode(dt_elt))
1526  new_name = var.get_source_variable(recurse=True).fullname()
1527  dt_elt.xml_remove_child(unicode(dt_elt))
1528  dt_elt.xml_append(unicode(new_name))
1529 

References CellMLToNektar.translators.SolverInfo._get_variable(), and CellMLToNektar.translators.SolverInfo._solver_info.

Member Data Documentation

◆ _component

CellMLToNektar.translators.SolverInfo._component
private

◆ _dt

CellMLToNektar.translators.SolverInfo._dt
private

◆ _jac_temp_re

CellMLToNektar.translators.SolverInfo._jac_temp_re = re.compile(r't[0-9]+')
staticprivate

◆ _model

CellMLToNektar.translators.SolverInfo._model
private

◆ _solver_info

CellMLToNektar.translators.SolverInfo._solver_info
private