class_docstr: Subclass of RectPartitioner2D, which uses MPI via mpi4py for communication
code: def update_internal_boundary(self, solution_array):
      nsd_ = self.nsd
      if (
          nsd_
          != len(self.in_lower_buffers) | nsd_
          != len(self.out_lower_buffers)
      ):
          print(
              "Buffers for communicating with lower neighbors not ready"
          )
          return
      if (
          nsd_
          != len(self.in_upper_buffers) | nsd_
          != len(self.out_upper_buffers)
      ):
          print(
              "Buffers for communicating with upper neighbors not ready"
          )
          return
  
      loc_nx = self.subd_hi_ix[0] - self.subd_lo_ix[0]
      loc_ny = self.subd_hi_ix[1] - self.subd_lo_ix[1]
  
      lower_x_neigh = self.lower_neighbors[0]
      upper_x_neigh = self.upper_neighbors[0]
      lower_y_neigh = self.lower_neighbors[1]
      upper_y_neigh = self.upper_neighbors[1]
  
      # communicate in the x-direction first
      if lower_x_neigh > -1:
          if self.slice_copy:
              self.out_lower_buffers[0] = ascontiguousarray(
                  solution_array[1, :]
              )
          else:
              for i in range(0, loc_ny + 1):
                  self.out_lower_buffers[0][i] = solution_array[1, i]
          mpi.Isend(self.out_lower_buffers[0], lower_x_neigh)
  
      if upper_x_neigh > -1:
          mpi.Recv(self.in_upper_buffers[0], upper_x_neigh)
          if self.slice_copy:
              solution_array[loc_nx, :] = self.in_upper_buffers[0]
              self.out_upper_buffers[0] = ascontiguousarray(
                  solution_array[loc_nx - 1, :]
              )
          else:
              for i in range(0, loc_ny + 1):
                  solution_array[loc_nx, i] = self.in_upper_buffers[0][
                      i
                  ]
                  self.out_upper_buffers[0][i] = solution_array[
                      loc_nx - 1, i
                  ]
          mpi.Isend(self.out_upper_buffers[0], upper_x_neigh)
  
      if lower_x_neigh > -1:
          mpi.Recv(self.in_lower_buffers[0], lower_x_neigh)
          if self.slice_copy:
              solution_array[0, :] = self.in_lower_buffers[0]
          else:
              for i in range(0, loc_ny + 1):
                  solution_array[0, i] = self.in_lower_buffers[0][i]
  
      # communicate in the y-direction afterwards
      if lower_y_neigh > -1:
          if self.slice_copy:
              self.out_lower_buffers[1] = ascontiguousarray(
                  solution_array[:, 1]
              )
          else:
              for i in range(0, loc_nx + 1):
                  self.out_lower_buffers[1][i] = solution_array[i, 1]
          mpi.Isend(self.out_lower_buffers[1], lower_y_neigh)
  
      if upper_y_neigh > -1:
          mpi.Recv(self.in_upper_buffers[1], upper_y_neigh)
          if self.slice_copy:
              solution_array[:, loc_ny] = self.in_upper_buffers[1]
              self.out_upper_buffers[1] = ascontiguousarray(
                  solution_array[:, loc_ny - 1]
              )
          else:
              for i in range(0, loc_nx + 1):
                  solution_array[i, loc_ny] = self.in_upper_buffers[1][
                      i
                  ]
                  self.out_upper_buffers[1][i] = solution_array[
                      i, loc_ny - 1
                  ]
          mpi.Isend(self.out_upper_buffers[1], upper_y_neigh)
  
      if lower_y_neigh > -1:
          mpi.Recv(self.in_lower_buffers[1], lower_y_neigh)
          if self.slice_copy:
              solution_array[:, 0] = self.in_lower_buffers[1]
          else:
              for i in range(0, loc_nx + 1):
                  solution_array[i, 0] = self.in_lower_buffers[1][i]
  
imports: from numpy import ascontiguousarray, frombuffer, zeros
label_desc: Use image node_id 2 for calling the MPIRectPartitioner2D obj's underlying member method code with example usage: obj.update_internal_boundary(solution_array) without return types