nodes: 0, module; 1, function_definition; 2, function_name:set_residual; 3, parameters; 4, block; 5, identifier:self; 6, default_parameter; 7, default_parameter; 8, expression_statement; 9, expression_statement; 10, if_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, expression_statement; 18, for_statement; 19, expression_statement; 20, comment:# we have added new clusters that are currently isolated and we; 21, comment:# need to stop them invading until they merge into an invading; 22, comment:# cluster; 23, for_statement; 24, identifier:pores; 25, list; 26, identifier:overwrite; 27, False; 28, comment:r"""
          Method to start invasion in a network w. residual saturation.
          Called after inlets are set.
  
          Parameters
          ----------
          pores : array_like
              The pores locations that are to be filled with invader at the
              beginning of the simulation.
  
          overwrite : boolean
              If ``True`` then all existing inlet locations will be removed and
              then the supplied locations will be added.  If ``False``, then
              supplied locations are added to any already existing locations.
  
          Notes
          -----
          Currently works for pores only and treats inner throats, i.e.
          those that connect two pores in the cluster as invaded and outer ones
          as uninvaded. Uninvaded throats are added to a new residual cluster
          queue but do not start invading independently if not connected to an
          inlet.
  
          Step 1. Identify clusters in the phase occupancy.
          Step 2. Look for clusters that are connected or contain an inlet
          Step 3. For those that are merge into inlet cluster. May be connected
          to more than one - run should sort this out
          Step 4. For those that are isolated set the queue to not invading.
          Step 5. (in run) When isolated cluster is met my invading cluster it
          merges in and starts invading
  
  
          """; 29, assignment; 30, identifier:overwrite; 31, block; 32, assignment; 33, assignment; 34, assignment; 35, assignment; 36, assignment; 37, assignment; 38, assignment; 39, identifier:rcluster_id; 40, identifier:rcluster_ids; 41, block; 42, assignment; 43, identifier:c_num; 44, call; 45, block; 46, identifier:Ps; 47, call; 48, expression_statement; 49, subscript; 50, True; 51, identifier:residual; 52, subscript; 53, identifier:net; 54, attribute; 55, identifier:conns; 56, subscript; 57, identifier:rclusters; 58, attribute; 59, identifier:rcluster_ids; 60, call; 61, identifier:initial_num; 62, binary_operator:len(self.queue)-1; 63, expression_statement; 64, expression_statement; 65, expression_statement; 66, if_statement; 67, expression_statement; 68, comment:# Set the residual pores and inner throats as part of cluster; 69, expression_statement; 70, expression_statement; 71, expression_statement; 72, expression_statement; 73, expression_statement; 74, expression_statement; 75, expression_statement; 76, comment:# Add all the outer throats to the queue; 77, expression_statement; 78, for_statement; 79, attribute; 80, binary_operator:[True]*len(self.queue); 81, identifier:range; 82, argument_list; 83, if_statement; 84, attribute; 85, argument_list; 86, assignment; 87, subscript; 88, identifier:Ps; 89, identifier:self; 90, string; 91, attribute; 92, identifier:network; 93, identifier:net; 94, string; 95, call; 96, identifier:sites; 97, attribute; 98, argument_list; 99, call; 100, integer:1; 101, assignment; 102, assignment; 103, assignment; 104, comparison_operator:len(existing) > 0; 105, comment:# There was at least one inlet cluster connected to this; 106, comment:# residual cluster, pick the first one.; 107, block; 108, else_clause; 109, assignment; 110, assignment; 111, assignment; 112, assignment; 113, assignment; 114, assignment; 115, assignment; 116, assignment; 117, assignment; 118, identifier:T; 119, identifier:Ts; 120, block; 121, identifier:self; 122, identifier:invasion_running; 123, list; 124, call; 125, call; 126, comparison_operator:c_num > initial_num; 127, block; 128, identifier:self; 129, identifier:_parse_indices; 130, identifier:pores; 131, subscript; 132, False; 133, identifier:self; 134, string; 135, string_content:pore.residual; 136, identifier:self; 137, identifier:project; 138, string_content:throat.conns; 139, identifier:site_percolation; 140, argument_list; 141, identifier:np; 142, identifier:unique; 143, subscript; 144, identifier:len; 145, argument_list; 146, identifier:rPs; 147, comparison_operator:rclusters == rcluster_id; 148, identifier:existing; 149, call; 150, identifier:existing; 151, subscript; 152, call; 153, integer:0; 154, expression_statement; 155, comment:# Make a new cluster queue; 156, block; 157, identifier:queue; 158, subscript; 159, subscript; 160, identifier:cluster_num; 161, identifier:Ts; 162, call; 163, subscript; 164, identifier:cluster_num; 165, subscript; 166, integer:0; 167, subscript; 168, integer:0; 169, subscript; 170, unary_operator; 171, subscript; 172, unary_operator; 173, identifier:Ts; 174, call; 175, expression_statement; 176, comment:# Pc; 177, expression_statement; 178, comment:# Element Index; 179, expression_statement; 180, comment:# Element Type (Pore of Throat); 181, expression_statement; 182, expression_statement; 183, True; 184, identifier:len; 185, argument_list; 186, identifier:len; 187, argument_list; 188, identifier:c_num; 189, identifier:initial_num; 190, expression_statement; 191, identifier:self; 192, string; 193, string_content:pore.residual; 194, identifier:conns; 195, identifier:residual; 196, identifier:rclusters; 197, comparison_operator:rclusters > -1; 198, attribute; 199, identifier:rclusters; 200, identifier:rcluster_id; 201, attribute; 202, argument_list; 203, identifier:existing; 204, comparison_operator:existing > -1; 205, identifier:len; 206, argument_list; 207, assignment; 208, expression_statement; 209, expression_statement; 210, attribute; 211, identifier:cluster_num; 212, subscript; 213, identifier:rPs; 214, attribute; 215, argument_list; 216, subscript; 217, identifier:Ts; 218, subscript; 219, identifier:rPs; 220, subscript; 221, identifier:Ts; 222, subscript; 223, identifier:rPs; 224, attribute; 225, subscript; 226, identifier:Ts; 227, attribute; 228, attribute; 229, argument_list; 230, assignment; 231, call; 232, call; 233, call; 234, call; 235, attribute; 236, attribute; 237, assignment; 238, string_content:pore.residual; 239, identifier:rclusters; 240, unary_operator; 241, identifier:self; 242, identifier:queue; 243, identifier:np; 244, identifier:unique; 245, subscript; 246, identifier:existing; 247, unary_operator; 248, identifier:existing; 249, identifier:cluster_num; 250, subscript; 251, assignment; 252, call; 253, identifier:self; 254, identifier:queue; 255, identifier:self; 256, string; 257, identifier:net; 258, identifier:find_neighbor_throats; 259, keyword_argument; 260, keyword_argument; 261, keyword_argument; 262, identifier:self; 263, string; 264, identifier:self; 265, string; 266, identifier:self; 267, string; 268, identifier:self; 269, string; 270, identifier:np; 271, identifier:inf; 272, identifier:self; 273, string; 274, identifier:np; 275, identifier:inf; 276, identifier:net; 277, identifier:find_neighbor_throats; 278, keyword_argument; 279, keyword_argument; 280, keyword_argument; 281, identifier:data; 282, list; 283, attribute; 284, argument_list; 285, attribute; 286, argument_list; 287, attribute; 288, argument_list; 289, attribute; 290, argument_list; 291, identifier:self; 292, identifier:queue; 293, identifier:self; 294, identifier:queue; 295, subscript; 296, False; 297, integer:1; 298, subscript; 299, identifier:rPs; 300, integer:1; 301, identifier:existing; 302, integer:0; 303, identifier:cluster_num; 304, call; 305, attribute; 306, argument_list; 307, string_content:pore.cluster; 308, identifier:pores; 309, identifier:rPs; 310, identifier:flatten; 311, True; 312, identifier:mode; 313, string; 314, string_content:throat.cluster; 315, string_content:pore.invasion_sequence; 316, string_content:throat.invasion_sequence; 317, string_content:pore.invasion_pressure; 318, string_content:throat.invasion_pressure; 319, identifier:pores; 320, identifier:rPs; 321, identifier:flatten; 322, True; 323, identifier:mode; 324, string; 325, identifier:data; 326, identifier:append; 327, subscript; 328, identifier:data; 329, identifier:append; 330, identifier:T; 331, identifier:data; 332, identifier:append; 333, string; 334, identifier:hq; 335, identifier:heappush; 336, identifier:queue; 337, identifier:data; 338, attribute; 339, identifier:c_num; 340, identifier:self; 341, string; 342, identifier:len; 343, argument_list; 344, attribute; 345, identifier:append; 346, list; 347, string_content:xnor; 348, string_content:exclusive_or; 349, subscript; 350, identifier:T; 351, string_content:throat; 352, identifier:self; 353, identifier:invasion_running; 354, string_content:pore.cluster; 355, attribute; 356, identifier:self; 357, identifier:queue; 358, identifier:self; 359, string; 360, identifier:self; 361, identifier:queue; 362, string_content:throat.entry_pressure
code: def set_residual(self, pores=[], overwrite=False):
          r"""
          Method to start invasion in a network w. residual saturation.
          Called after inlets are set.
  
          Parameters
          ----------
          pores : array_like
              The pores locations that are to be filled with invader at the
              beginning of the simulation.
  
          overwrite : boolean
              If ``True`` then all existing inlet locations will be removed and
              then the supplied locations will be added.  If ``False``, then
              supplied locations are added to any already existing locations.
  
          Notes
          -----
          Currently works for pores only and treats inner throats, i.e.
          those that connect two pores in the cluster as invaded and outer ones
          as uninvaded. Uninvaded throats are added to a new residual cluster
          queue but do not start invading independently if not connected to an
          inlet.
  
          Step 1. Identify clusters in the phase occupancy.
          Step 2. Look for clusters that are connected or contain an inlet
          Step 3. For those that are merge into inlet cluster. May be connected
          to more than one - run should sort this out
          Step 4. For those that are isolated set the queue to not invading.
          Step 5. (in run) When isolated cluster is met my invading cluster it
          merges in and starts invading
  
  
          """
          Ps = self._parse_indices(pores)
          if overwrite:
              self['pore.residual'] = False
          self['pore.residual'][Ps] = True
          residual = self['pore.residual']
          net = self.project.network
          conns = net['throat.conns']
          rclusters = site_percolation(conns, residual).sites
          rcluster_ids = np.unique(rclusters[rclusters > -1])
          initial_num = len(self.queue)-1
          for rcluster_id in rcluster_ids:
              rPs = rclusters == rcluster_id
              existing = np.unique(self['pore.cluster'][rPs])
              existing = existing[existing > -1]
              if len(existing) > 0:
                  # There was at least one inlet cluster connected to this
                  # residual cluster, pick the first one.
                  cluster_num = existing[0]
              else:
                  # Make a new cluster queue
                  cluster_num = len(self.queue)
                  self.queue.append([])
              queue = self.queue[cluster_num]
              # Set the residual pores and inner throats as part of cluster
              self['pore.cluster'][rPs] = cluster_num
              Ts = net.find_neighbor_throats(pores=rPs,
                                             flatten=True,
                                             mode='xnor')
              self['throat.cluster'][Ts] = cluster_num
              self['pore.invasion_sequence'][rPs] = 0
              self['throat.invasion_sequence'][Ts] = 0
              self['pore.invasion_pressure'][rPs] = -np.inf
              self['throat.invasion_pressure'][Ts] = -np.inf
              # Add all the outer throats to the queue
              Ts = net.find_neighbor_throats(pores=rPs,
                                             flatten=True,
                                             mode='exclusive_or')
              for T in Ts:
                  data = []
                  # Pc
                  data.append(self['throat.entry_pressure'][T])
                  # Element Index
                  data.append(T)
                  # Element Type (Pore of Throat)
                  data.append('throat')
                  hq.heappush(queue, data)
          self.invasion_running = [True]*len(self.queue)
          # we have added new clusters that are currently isolated and we
          # need to stop them invading until they merge into an invading
          # cluster
          for c_num in range(len(self.queue)):
              if c_num > initial_num:
                  self.invasion_running[c_num] = False