Nektar++
Private Member Functions | List of all members
CellMLToNektar.pycml.mathml_units_mixin Class Reference

MathML elements #. More...

Inheritance diagram for CellMLToNektar.pycml.mathml_units_mixin:
[legend]

Private Member Functions

def _add_units_conversion (self, expr, defn_units, to_units, no_act=False)
 
def _set_element_in_units (self, elt, units, no_act=False)
 

Detailed Description

MathML elements #.

Base class for units mixin classes.

Definition at line 3469 of file pycml.py.

Member Function Documentation

◆ _add_units_conversion()

def CellMLToNektar.pycml.mathml_units_mixin._add_units_conversion (   self,
  expr,
  defn_units,
  to_units,
  no_act = False 
)
private
Add mathematics for an explicit units conversion.

Wraps expr in the expression
m[to_units/defn_units]*(expr-o1[defn_units]) + o2[to_units].

Definition at line 3471 of file pycml.py.

References CellMLToNektar.pycml.extract(), and CellMLToNektar.pycml.simplify().

Referenced by CellMLToNektar.pycml.mathml_units_mixin._set_element_in_units(), and CellMLToNektar.pycml.mathml_units_mixin_tokens._set_in_units().

3471  def _add_units_conversion(self, expr, defn_units, to_units, no_act=False):
3472  """Add mathematics for an explicit units conversion.
3473 
3474  Wraps expr in the expression
3475  m[to_units/defn_units]*(expr-o1[defn_units]) + o2[to_units].
3476  """
3477 # print '_add_units_conv for', element_xpath(expr), 'from', defn_units.description(), 'to', to_units.description()
3478  if hasattr(expr.model, '_cml_special_units_converter') and not defn_units.dimensionally_equivalent(to_units):
3479  # This may be a special conversion case defined by a functional curation protocol
3480  if no_act:
3481  model._cml_conversions_needed = True
3482  return
3483  else:
3484  expr = expr.model._cml_special_units_converter(expr, defn_units, to_units)
3485 # print 'post special, expr units=', expr.get_units().description(), 'm=', expr.get_units().extract().expand().simplify().get_multiplicative_factor()
3486 # print 'orig defn_units=', defn_units.description(), 'm=', defn_units.expand().simplify().get_multiplicative_factor()
3487 # print 'orig to_units=', to_units.description(), 'm=', to_units.expand().simplify().get_multiplicative_factor()
3488  try:
3489  defn_units = expr.get_units().extract(check_equality=True)
3490  except:
3491  print 'ouch', expr.xml()
3492  for u in expr.get_units():
3493  print u.description(), u.get_multiplier(), expr.get_units()._get_sources(u)
3494  raise
3495  defn_units_exp = defn_units.expand().simplify()
3496  to_units_exp = to_units.expand().simplify()
3497  # Conversion factor
3498  m = (defn_units_exp.get_multiplicative_factor() / to_units_exp.get_multiplicative_factor())
3499  # Replace expr by m[to_units/defn_units]*(expr-o1[defn_units]) + o2[to_units]
3500  orig_expr, parent = expr, expr.xml_parent
3501  dummy = expr.xml_create_element(u'dummy', NSS[u'm'])
3502  model = expr.model # So we still have a reference after the next line
3503  parent.replace_child(expr, dummy) # Mark where to put the new elt
3504  if defn_units_exp.get_offset() != 0:
3505  # Create expr-o1 expression
3506  uattr = orig_expr._ensure_units_exist(defn_units, no_act=no_act)
3507  new_expr = mathml_apply.create_new(expr, u'minus',
3508  [expr, (unicode(defn_units_exp.get_offset()), uattr)])
3509  new_expr._cml_units = defn_units
3510  expr = new_expr
3511  if m != 1:
3512  quotient_units = to_units.quotient(defn_units)
3513  # Add units element to model if needed
3514  uattr = orig_expr._ensure_units_exist(quotient_units, no_act=no_act)
3515  # Create m*expr expression
3516  new_expr = mathml_apply.create_new(expr, u'times', [(unicode(m), uattr), expr])
3517  new_expr._cml_units = to_units
3518  expr = new_expr
3519  if to_units_exp.get_offset() != 0:
3520  # Create expr+o2 expression
3521  uattr = orig_expr._ensure_units_exist(to_units, no_act=no_act)
3522  new_expr = mathml_apply.create_new(expr, u'plus',
3523  [expr, (unicode(to_units_exp.get_offset()), uattr)])
3524  new_expr._cml_units = to_units
3525  expr = new_expr
3526  # Note that the model needed conversions
3527  if expr is not orig_expr:
3528  model._cml_conversions_needed = True
3529  if no_act:
3530  expr = orig_expr
3531  parent.replace_child(dummy, expr)
3532  return
3533 
def extract(self, check_equality=False)
Definition: pycml.py:2657
def simplify(self, other_units=None, other_exponent=1)
Definition: pycml.py:2967

◆ _set_element_in_units()

def CellMLToNektar.pycml.mathml_units_mixin._set_element_in_units (   self,
  elt,
  units,
  no_act = False 
)
private
Try to set the units of the given element.

Generates a debug message if this isn't possible.

Definition at line 3534 of file pycml.py.

References CellMLToNektar.pycml.mathml_units_mixin._add_units_conversion(), CellMLToNektar.pycml.cellml_variable.component, CellMLToNektar.pycml.mathml.component, CellMLToNektar.utilities.DEBUG(), and CellMLToNektar.pycml.get_units_by_name().

Referenced by CellMLToNektar.pycml.mathml_units_mixin_set_operands._set_in_units(), CellMLToNektar.pycml.mathml_units_mixin_equalise_operands._set_in_units(), CellMLToNektar.pycml.mathml_units_mixin_choose_nearest._set_in_units(), CellMLToNektar.pycml.mathml_units_mixin_container._set_in_units(), CellMLToNektar.pycml.mathml_apply._set_in_units(), CellMLToNektar.pycml.mathml_piecewise._set_in_units(), CellMLToNektar.pycml.mathml_power._set_in_units(), CellMLToNektar.pycml.mathml_root._set_in_units(), and CellMLToNektar.pycml.mathml_eq._set_in_units().

3534  def _set_element_in_units(self, elt, units, no_act=False):
3535  """Try to set the units of the given element.
3536 
3537  Generates a debug message if this isn't possible.
3538  """
3539  if hasattr(elt, '_set_in_units') and callable(elt._set_in_units):
3540  elt._set_in_units(units, no_act)
3541  elif elt.localName in [u'false', u'true']:
3542  boolean = self.component.get_units_by_name('cellml:boolean')
3543  if boolean is not units:
3544  # TODO: *blink* this should never happen
3545  self._add_units_conversion(elt, boolean, units, no_act)
3546  elif elt.localName in [u'notanumber', u'pi', u'infinity', u'exponentiale']:
3547  dimensionless = self.component.get_units_by_name('dimensionless')
3548  if dimensionless is not units:
3549  # TODO: *blink* this should never happen
3550  self._add_units_conversion(elt, dimensionless, units, no_act)
3551  else:
3552  DEBUG('validator',
3553  'Cannot set units (to', units.description(), ') for element', elt.localName)
3554  return
3555 
def get_units_by_name(self, uname)
Definition: pycml.py:2725
def DEBUG(facility, args)
Definition: utilities.py:95