Selects the boundary conditions
    E-W is for inside each panel
    N-S is for the block diagonal matrix ("with fringes")
    Then calls the function to build the diagonal matrix

    The current method of coefficient matrix construction utilizes longer-range
    symmetry in the coefficient matrix to build it block-wise, as opposed to
    the much less computationally efficient row-by-row ("serial") method 
    that was previously employed.
    
    The method is spread across the subroutines here.
    
    Important to this is the use of np.roll() to properly offset the 
    diagonals that end up in the main matrix: spdiags() will put each vector
    on the proper diagonal, but will align them such that their first cell is 
    along the first column, instead of using a 45 degrees to matrix corner 
    baseline that would stagger them appropriately for this solution method.
    Therefore, np.roll() effectively does this staggering by having the 
    appropriate cell in the vector start at the first column.

def BC_selector_and_coeff_matrix_creator(self):
    """
    Selects the boundary conditions
    E-W is for inside each panel
    N-S is for the block diagonal matrix ("with fringes")
    Then calls the function to build the diagonal matrix

    The current method of coefficient matrix construction utilizes longer-range
    symmetry in the coefficient matrix to build it block-wise, as opposed to
    the much less computationally efficient row-by-row ("serial") method 
    that was previously employed.
    
    The method is spread across the subroutines here.
    
    Important to this is the use of np.roll() to properly offset the 
    diagonals that end up in the main matrix: spdiags() will put each vector
    on the proper diagonal, but will align them such that their first cell is 
    along the first column, instead of using a 45 degrees to matrix corner 
    baseline that would stagger them appropriately for this solution method.
    Therefore, np.roll() effectively does this staggering by having the 
    appropriate cell in the vector start at the first column.
    """
    
    # Zeroth, start the timer and print the boundary conditions to the screen
    self.coeff_start_time = time.time()
    if self.Verbose:
      print("Boundary condition, West:", self.BC_W, type(self.BC_W))
      print("Boundary condition, East:", self.BC_E, type(self.BC_E))
      print("Boundary condition, North:", self.BC_N, type(self.BC_N))
      print("Boundary condition, South:", self.BC_S, type(self.BC_S))
    
    # First, set flexural rigidity boundary conditions to flesh out this padded
    # array
    self.BC_Rigidity()
    
    # Second, build the coefficient arrays -- with the rigidity b.c.'s
    self.get_coeff_values()
    
    # Third, apply boundary conditions to the coeff_arrays to create the 
    # flexural solution
    self.BC_Flexure()
    
    # Fourth, construct the sparse diagonal array
    self.build_diagonals()

    # Finally, compute the total time this process took    
    self.coeff_creation_time = time.time() - self.coeff_start_time
    if self.Quiet == False:
      print("Time to construct coefficient (operator) array [s]:", self.coeff_creation_time)