int MultiVectorTests(const Epetra_BlockMap & Map, int NumVectors, bool verbose)
{
  (void)NumVectors;
  const Epetra_Comm & Comm = Map.Comm();
  int ierr = 0;
  
  /* get number of processors and the name of this processor */
  
  // int NumProc = Comm.getNumProc();
  int MyPID   = Comm.MyPID();
  
  // Construct FEVector
  
  if (verbose&&MyPID==0) cout << "constructing Epetra_FEVector" << endl;

  Epetra_FEVector A(Map, 1);
 
  //For an extreme test, we'll have each processor sum-in a 1.0 for All
  //global ids.

  int minGID = Map.MinAllGID();
  int numGlobalIDs = Map.NumGlobalElements();

  //For now we're going to have just one point associated with
  //each GID (element).

  int* ptIndices = new int[numGlobalIDs];
  double* ptCoefs = new double[numGlobalIDs];

  Epetra_IntSerialDenseVector epetra_indices(View, ptIndices, numGlobalIDs);
  Epetra_SerialDenseVector epetra_coefs(View, ptCoefs, numGlobalIDs);

  {for(int i=0; i<numGlobalIDs; ++i) {
    ptIndices[i] = minGID+i;
    ptCoefs[i] = 1.0;
  }}

  if (verbose&&MyPID==0) {
    cout << "calling A.SumIntoGlobalValues with " << numGlobalIDs << " values"<<endl;
  }
  EPETRA_TEST_ERR( A.SumIntoGlobalValues(numGlobalIDs, ptIndices, ptCoefs), ierr);

  if (verbose&&MyPID==0) {
    cout << "calling A.SumIntoGlobalValues with " << numGlobalIDs << " values"<<endl;
  }
  EPETRA_TEST_ERR( A.SumIntoGlobalValues(epetra_indices, epetra_coefs), ierr);

  if (verbose&&MyPID==0) {
    cout << "calling A.GlobalAssemble()" << endl;
  }

  EPETRA_TEST_ERR( A.GlobalAssemble(), ierr );

  if (verbose&&MyPID==0) {
  cout << "after globalAssemble"<<endl;
  }
  if (verbose) {
  A.Print(cout);
  }

  //now do a quick test of the copy constructor
  Epetra_FEVector B(A);

  double nrm2a, nrm2b;
  A.Norm2(&nrm2a);
  B.Norm2(&nrm2b);

  if (nrm2a != nrm2b) {
    cerr << "copy-constructor test failed, norm of copy doesn't equal"
         << " norm of original."<<endl;
    return(-1);
  }

  delete [] ptIndices;
  delete [] ptCoefs;

  return(ierr);
}
int submatrix_formats(const Epetra_Comm& Comm, bool verbose)
{
  (void)verbose;
  //
  //This function simply verifies that the ROW_MAJOR/COLUMN_MAJOR switch works.
  //
  int numProcs = Comm.NumProc();
  int myPID = Comm.MyPID();

  int numLocalElements = 3;
  int numGlobalElements = numLocalElements*numProcs;
  int indexBase = 0;

  Epetra_Map map(numGlobalElements, numLocalElements, indexBase, Comm);

  Epetra_FECrsMatrix A(Copy, map, numLocalElements);

  Epetra_IntSerialDenseVector epetra_indices(numLocalElements);

  int firstGlobalElement = numLocalElements*myPID;

  int i, j;
  for(i=0; i<numLocalElements; ++i) {
    epetra_indices[i] = firstGlobalElement+i;
  }

  Epetra_SerialDenseMatrix submatrix(numLocalElements, numLocalElements);

  for(i=0; i<numLocalElements; ++i) {
    for(j=0; j<numLocalElements; ++j) {
      submatrix(i,j) = 1.0*(firstGlobalElement+i);
    }
  }

  EPETRA_CHK_ERR( A.InsertGlobalValues(epetra_indices, submatrix,
                               Epetra_FECrsMatrix::COLUMN_MAJOR) );

  EPETRA_CHK_ERR( A.GlobalAssemble() );

  int len = 20;
  int numIndices;
  int* indices = new int[len];
  double* coefs = new double[len];

  for(i=0; i<numLocalElements; ++i) {
    int row = firstGlobalElement+i;

    EPETRA_CHK_ERR( A.ExtractGlobalRowCopy(row, len, numIndices,
					   coefs, indices) );

    for(j=0; j<numIndices; ++j) {
      if (coefs[j] != 1.0*row) {
	return(-2);
      }
    }
  }

  //now reset submatrix (transposing the i,j indices)

  for(i=0; i<numLocalElements; ++i) {
    for(j=0; j<numLocalElements; ++j) {
      submatrix(j,i) = 1.0*(firstGlobalElement+i);
    }
  }

  //sum these values into the matrix using the ROW_MAJOR switch, which should
  //result in doubling what's already there from the above Insert operation.

  EPETRA_CHK_ERR( A.SumIntoGlobalValues(epetra_indices, submatrix,
					Epetra_FECrsMatrix::ROW_MAJOR) );

  EPETRA_CHK_ERR( A.GlobalAssemble() );

  for(i=0; i<numLocalElements; ++i) {
    int row = firstGlobalElement+i;

    EPETRA_CHK_ERR( A.ExtractGlobalRowCopy(row, len, numIndices,
					   coefs, indices) );

    for(j=0; j<numIndices; ++j) {
      if (coefs[j] != 2.0*row) {
	return(-3);
      }
    }
  }

  delete [] indices;
  delete [] coefs;

  return(0);
}