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.

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

◆ 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(), and CellMLToNektar.translators.SolverInfo.add_variable_links().

◆ 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