parameters: (
          self,
          this_phase_species: List[Dict[str, Iterable[str]]],
          activity_node: etree.Element,
          species_data: Dict[str, List["Species"]],
      )
return_statement: return activity_data
docstring: Process the activity coefficients for the ``DebyeHuckel`` phase-thermo type.
  
          :param this_phase_species:
              A list of mappings of species data sources to the species names in that
              data source. Passed as an argument instead of using the ``species`` key
              in the instance ``attribs`` because the attribute could be a mapping or
              a list of mappings, whereas this argument is always a list of mappings.
          :param activity_node:
              XML ``activityCoefficients`` node.
          :param species_data:
              Mapping of species data sources (i.e., ``id`` attributes on ``speciesData``
              nodes) to lists of `Species` instances.
docstring_summary: Process the activity coefficients for the ``DebyeHuckel`` phase-thermo type.
docstring_tokens: Process the activity coefficients for the DebyeHuckel phase - thermo type .
function: def debye_huckel(
          self,
          this_phase_species: List[Dict[str, Iterable[str]]],
          activity_node: etree.Element,
          species_data: Dict[str, List["Species"]],
      ) -> Dict[str, Union[str, "QUANTITY", bool]]:
          """Process the activity coefficients for the ``DebyeHuckel`` phase-thermo type.
  
          :param this_phase_species:
              A list of mappings of species data sources to the species names in that
              data source. Passed as an argument instead of using the ``species`` key
              in the instance ``attribs`` because the attribute could be a mapping or
              a list of mappings, whereas this argument is always a list of mappings.
          :param activity_node:
              XML ``activityCoefficients`` node.
          :param species_data:
              Mapping of species data sources (i.e., ``id`` attributes on ``speciesData``
              nodes) to lists of `Species` instances.
          """
          model_map = {
              "dilute_limit": "dilute-limit",
              "bdot_with_variable_a": "B-dot-with-variable-a",
              "bdot_with_common_a": "B-dot-with-common-a",
              "pitzer_with_beta_ij": "Pitzer-with-beta_ij",
              "beta_ij": "beta_ij",
              "": "dilute-limit",
          }
          activity_model = activity_node.get("model")
          if activity_model is None:
              raise MissingXMLAttribute(
                  "The 'activityCoefficients' node must have a 'model' attribute.",
                  activity_node,
              )
          activity_data = BlockMap({"model": model_map[activity_model.lower()]})
          A_Debye = activity_node.findtext("A_Debye")
          if A_Debye is not None:
              # Assume the units are kg^0.5/gmol^0.5. Apparently,
              # this is not handled in the same way as other units?
              activity_data["A_Debye"] = A_Debye.strip() + " kg^0.5/gmol^0.5"
  
          B_Debye = activity_node.findtext("B_Debye")
          if B_Debye is not None:
              # Assume the units are kg^0.5/gmol^0.5/m. Apparently,
              # this is not handled in the same way as other units?
              activity_data["B_Debye"] = B_Debye.strip() + " kg^0.5/gmol^0.5/m"
  
          max_ionic_strength = activity_node.findtext("maxIonicStrength")
          if max_ionic_strength is not None:
              activity_data["max-ionic-strength"] = float(max_ionic_strength)
  
          if activity_node.find("UseHelgesonFixedForm") is not None:
              activity_data["use-Helgeson-fixed-form"] = True
  
          B_dot_node = activity_node.find("B_dot")
          if B_dot_node is not None:
              activity_data["B-dot"] = get_float_or_quantity(B_dot_node)
  
          ionic_radius_node = activity_node.find("ionicRadius")
          species_ionic_radii = {}  # type: Dict[str, QUANTITY]
          if ionic_radius_node is not None:
              default_radius = ionic_radius_node.get("default")
              radius_units = ionic_radius_node.get("units")
              if default_radius is not None:
                  if radius_units is not None:
                      if radius_units == "Angstroms":
                          radius_units = "angstrom"
                      default_radius += " {}".format(radius_units)
                      activity_data["default-ionic-radius"] = default_radius
                  else:
                      activity_data["default-ionic-radius"] = float(default_radius)
              if ionic_radius_node.text is not None:
                  radii = clean_node_text(ionic_radius_node).split()
                  for r in radii:
                      species_name, radius = r.strip().rsplit(":", 1)
                      if radius_units is not None:
                          radius += " {}".format(radius_units)
                          species_ionic_radii[species_name] = radius
                      else:
                          species_ionic_radii[species_name] = float(radius)
  
          beta_matrix_node = activity_node.find("DHBetaMatrix")
          if beta_matrix_node is not None:
              beta_matrix = []
              beta_units = beta_matrix_node.get("units")
              for beta_text in clean_node_text(beta_matrix_node).split():
                  # The C++ code to process this matrix from XML assumes that the species
                  # names in this matrix do not contain colons, so we retain that
                  # behavior here.
                  species_1, species_2, beta_value = beta_text.split(":")
                  beta_dict = {
                      "species": FlowList([species_1, species_2])
                  }  # type: DH_BETA_MATRIX
                  if beta_units is not None:
                      beta_units = re.sub(r"([A-Za-z])-([A-Za-z])", r"\1*\2", beta_units)
                      beta_units = re.sub(r"([A-Za-z])([-\d])", r"\1^\2", beta_units)
                      beta_dict["beta"] = beta_value + " " + beta_units
                  else:
                      beta_dict["beta"] = float(beta_value)
                  beta_matrix.append(beta_dict)
  
              if beta_matrix:
                  activity_data["beta"] = beta_matrix
  
          ionic_strength_mods_node = activity_node.find("stoichIsMods")
          is_mods = {}
          if ionic_strength_mods_node is not None:
              mods = clean_node_text(ionic_strength_mods_node).split()
              for m in mods:
                  species_name, mod = m.strip().rsplit(":", 1)
                  is_mods[species_name] = float(mod)
  
          electrolyte_species_type_node = activity_node.find("electrolyteSpeciesType")
          etype_mods = {}
          if electrolyte_species_type_node is not None:
              mods = clean_node_text(electrolyte_species_type_node).split()
              for m in mods:
                  species_name, mod = m.strip().rsplit(":", 1)
                  etype_mods[species_name] = mod
  
          flat_species = {k: v for d in this_phase_species for k, v in d.items()}
          for datasrc, species_names in flat_species.items():
              if datasrc == "species":
                  datasrc = "species_data"
              species = species_data.get(datasrc)
              if species is None:
                  continue
              for spec in species:
                  name = spec.attribs["name"]
                  if name not in species_names:
                      continue
                  debye_huckel = spec.attribs.get("Debye-Huckel", {})
                  if name in species_ionic_radii:
                      debye_huckel["ionic-radius"] = species_ionic_radii[name]
                  if name in is_mods:
                      if "weak-acid-charge" not in debye_huckel:
                          debye_huckel["weak-acid-charge"] = is_mods[name]
                      else:
                          if is_mods[name] != debye_huckel["weak-acid-charge"]:
                              warnings.warn(
                                  "The stoichIsMods node was specified at the phase and "
                                  "species level for species '{}'. The value specified "
                                  "in the species node will be used".format(name)
                              )
                  if name in etype_mods:
                      etype = spec.electrolyte_species_type_mapping[etype_mods[name]]
                      if "electrolyte-species-type" not in debye_huckel:
                          debye_huckel["electrolyte-species-type"] = etype
                      else:
                          if debye_huckel["electrolyte-species-type"] != etype:
                              warnings.warn(
                                  "The electrolyteSpeciesType node was specified at the "
                                  "phase and species level for species '{}'. The value "
                                  "specified in the species node will be "
                                  "used".format(name)
                              )
                  if debye_huckel:
                      spec.attribs["Debye-Huckel"] = debye_huckel
  
          return activity_data
function_tokens: def debye_huckel ( self , this_phase_species : List [ Dict [ str , Iterable [ str ] ] ] , activity_node : etree . Element , species_data : Dict [ str , List [ "Species" ] ] , ) -> Dict [ str , Union [ str , "QUANTITY" , bool ] ] : model_map = { "dilute_limit" : "dilute-limit" , "bdot_with_variable_a" : "B-dot-with-variable-a" , "bdot_with_common_a" : "B-dot-with-common-a" , "pitzer_with_beta_ij" : "Pitzer-with-beta_ij" , "beta_ij" : "beta_ij" , "" : "dilute-limit" , } activity_model = activity_node . get ( "model" ) if activity_model is None : raise MissingXMLAttribute ( "The 'activityCoefficients' node must have a 'model' attribute." , activity_node , ) activity_data = BlockMap ( { "model" : model_map [ activity_model . lower ( ) ] } ) A_Debye = activity_node . findtext ( "A_Debye" ) if A_Debye is not None : # Assume the units are kg^0.5/gmol^0.5. Apparently, # this is not handled in the same way as other units? activity_data [ "A_Debye" ] = A_Debye . strip ( ) + " kg^0.5/gmol^0.5" B_Debye = activity_node . findtext ( "B_Debye" ) if B_Debye is not None : # Assume the units are kg^0.5/gmol^0.5/m. Apparently, # this is not handled in the same way as other units? activity_data [ "B_Debye" ] = B_Debye . strip ( ) + " kg^0.5/gmol^0.5/m" max_ionic_strength = activity_node . findtext ( "maxIonicStrength" ) if max_ionic_strength is not None : activity_data [ "max-ionic-strength" ] = float ( max_ionic_strength ) if activity_node . find ( "UseHelgesonFixedForm" ) is not None : activity_data [ "use-Helgeson-fixed-form" ] = True B_dot_node = activity_node . find ( "B_dot" ) if B_dot_node is not None : activity_data [ "B-dot" ] = get_float_or_quantity ( B_dot_node ) ionic_radius_node = activity_node . find ( "ionicRadius" ) species_ionic_radii = { } # type: Dict[str, QUANTITY] if ionic_radius_node is not None : default_radius = ionic_radius_node . get ( "default" ) radius_units = ionic_radius_node . get ( "units" ) if default_radius is not None : if radius_units is not None : if radius_units == "Angstroms" : radius_units = "angstrom" default_radius += " {}" . format ( radius_units ) activity_data [ "default-ionic-radius" ] = default_radius else : activity_data [ "default-ionic-radius" ] = float ( default_radius ) if ionic_radius_node . text is not None : radii = clean_node_text ( ionic_radius_node ) . split ( ) for r in radii : species_name , radius = r . strip ( ) . rsplit ( ":" , 1 ) if radius_units is not None : radius += " {}" . format ( radius_units ) species_ionic_radii [ species_name ] = radius else : species_ionic_radii [ species_name ] = float ( radius ) beta_matrix_node = activity_node . find ( "DHBetaMatrix" ) if beta_matrix_node is not None : beta_matrix = [ ] beta_units = beta_matrix_node . get ( "units" ) for beta_text in clean_node_text ( beta_matrix_node ) . split ( ) : # The C++ code to process this matrix from XML assumes that the species # names in this matrix do not contain colons, so we retain that # behavior here. species_1 , species_2 , beta_value = beta_text . split ( ":" ) beta_dict = { "species" : FlowList ( [ species_1 , species_2 ] ) } # type: DH_BETA_MATRIX if beta_units is not None : beta_units = re . sub ( r"([A-Za-z])-([A-Za-z])" , r"\1*\2" , beta_units ) beta_units = re . sub ( r"([A-Za-z])([-\d])" , r"\1^\2" , beta_units ) beta_dict [ "beta" ] = beta_value + " " + beta_units else : beta_dict [ "beta" ] = float ( beta_value ) beta_matrix . append ( beta_dict ) if beta_matrix : activity_data [ "beta" ] = beta_matrix ionic_strength_mods_node = activity_node . find ( "stoichIsMods" ) is_mods = { } if ionic_strength_mods_node is not None : mods = clean_node_text ( ionic_strength_mods_node ) . split ( ) for m in mods : species_name , mod = m . strip ( ) . rsplit ( ":" , 1 ) is_mods [ species_name ] = float ( mod ) electrolyte_species_type_node = activity_node . find ( "electrolyteSpeciesType" ) etype_mods = { } if electrolyte_species_type_node is not None : mods = clean_node_text ( electrolyte_species_type_node ) . split ( ) for m in mods : species_name , mod = m . strip ( ) . rsplit ( ":" , 1 ) etype_mods [ species_name ] = mod flat_species = { k : v for d in this_phase_species for k , v in d . items ( ) } for datasrc , species_names in flat_species . items ( ) : if datasrc == "species" : datasrc = "species_data" species = species_data . get ( datasrc ) if species is None : continue for spec in species : name = spec . attribs [ "name" ] if name not in species_names : continue debye_huckel = spec . attribs . get ( "Debye-Huckel" , { } ) if name in species_ionic_radii : debye_huckel [ "ionic-radius" ] = species_ionic_radii [ name ] if name in is_mods : if "weak-acid-charge" not in debye_huckel : debye_huckel [ "weak-acid-charge" ] = is_mods [ name ] else : if is_mods [ name ] != debye_huckel [ "weak-acid-charge" ] : warnings . warn ( "The stoichIsMods node was specified at the phase and " "species level for species '{}'. The value specified " "in the species node will be used" . format ( name ) ) if name in etype_mods : etype = spec . electrolyte_species_type_mapping [ etype_mods [ name ] ] if "electrolyte-species-type" not in debye_huckel : debye_huckel [ "electrolyte-species-type" ] = etype else : if debye_huckel [ "electrolyte-species-type" ] != etype : warnings . warn ( "The electrolyteSpeciesType node was specified at the " "phase and species level for species '{}'. The value " "specified in the species node will be " "used" . format ( name ) ) if debye_huckel : spec . attribs [ "Debye-Huckel" ] = debye_huckel return activity_data