Beispiel #1
0
//==============================================================================
int Komplex_LinearProblem::MakeKomplexMap(const Epetra_Map & Map, Teuchos::RCP<Epetra_Map> & KMap) {

  if (Map.LinearMap()) {
    KMap = Teuchos::rcp(new Epetra_Map(-1, Map.NumMyElements()*2, Map.IndexBase(), Map.Comm()));
  }
  else {
    Epetra_IntSerialDenseVector KMapGIDs(Map.NumMyElements()*2);
    int * myGlobalElements = Map.MyGlobalElements();
    for (int i=0; i<Map.NumMyElements(); i++) {
      KMapGIDs[2*i] = 2*myGlobalElements[i];
      KMapGIDs[2*i+1] = 2*myGlobalElements[i]+1;
    }
    KMap = Teuchos::rcp(new Epetra_Map(-1, KMapGIDs.Length(), KMapGIDs.Values(), Map.IndexBase(), Map.Comm()));
  }
  return(0);
}
Beispiel #2
0
int checkmap(Epetra_Map & Map, int NumGlobalElements, int NumMyElements, 
	     int *MyGlobalElements, int IndexBase, Epetra_Comm& Comm,
	     bool DistributedGlobal)
{
  int i, ierr=0, forierr = 0;

  EPETRA_TEST_ERR(!Map.ConstantElementSize(),ierr);

  EPETRA_TEST_ERR(DistributedGlobal!=Map.DistributedGlobal(),ierr);


  EPETRA_TEST_ERR(Map.ElementSize()!=1,ierr);
  int *MyElementSizeList = new int[NumMyElements];

  EPETRA_TEST_ERR(Map.ElementSizeList(MyElementSizeList)!=0,ierr);

  forierr = 0;
  for (i=0; i<NumMyElements; i++) forierr += MyElementSizeList[i]!=1;
  EPETRA_TEST_ERR(forierr,ierr);

  delete [] MyElementSizeList;

  const Epetra_Comm & Comm1 = Map.Comm();

  EPETRA_TEST_ERR(Comm1.NumProc()!=Comm.NumProc(),ierr);

  EPETRA_TEST_ERR(Comm1.MyPID()!=Comm.MyPID(),ierr);

  EPETRA_TEST_ERR(Map.IndexBase()!=IndexBase,ierr);

  EPETRA_TEST_ERR(!Map.LinearMap() && MyGlobalElements==0,ierr);

  EPETRA_TEST_ERR(Map.LinearMap() && MyGlobalElements!=0,ierr);

  EPETRA_TEST_ERR(Map.MaxAllGID()!=NumGlobalElements-1+IndexBase,ierr);

  EPETRA_TEST_ERR(Map.MaxElementSize()!=1,ierr);

  int MaxLID = Map.MaxLID();
  EPETRA_TEST_ERR(MaxLID!=NumMyElements-1,ierr);

  int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
  if (Comm.MyPID()>2) MaxMyGID+=3;
  if (!DistributedGlobal) MaxMyGID = NumMyElements-1+IndexBase;
  EPETRA_TEST_ERR(Map.MaxMyGID()!=MaxMyGID,ierr);

  EPETRA_TEST_ERR(Map.MinAllGID()!=IndexBase,ierr);

  EPETRA_TEST_ERR(Map.MinElementSize()!=1,ierr);

  EPETRA_TEST_ERR(Map.MinLID()!=0,ierr);

  int MinMyGID = Comm.MyPID()*NumMyElements+IndexBase;
  if (Comm.MyPID()>2) MinMyGID+=3;
  if (!DistributedGlobal) MinMyGID = 0;
  EPETRA_TEST_ERR(Map.MinMyGID()!=MinMyGID,ierr);
  
  int * MyGlobalElements1 = new int[NumMyElements];
  EPETRA_TEST_ERR(Map.MyGlobalElements(MyGlobalElements1)!=0,ierr);

  forierr = 0;
  if (MyGlobalElements==0)
    {
      for (i=0; i<NumMyElements; i++) 
	forierr += MyGlobalElements1[i]!=MinMyGID+i;
      EPETRA_TEST_ERR(forierr,ierr);
    }
  else {
    for (i=0; i<NumMyElements; i++)
      forierr += MyGlobalElements[i]!=MyGlobalElements1[i];
    EPETRA_TEST_ERR(forierr,ierr);
  }
  EPETRA_TEST_ERR(Map.NumGlobalElements()!=NumGlobalElements,ierr);
  
  EPETRA_TEST_ERR(Map.NumGlobalPoints()!=NumGlobalElements,ierr);
  
  EPETRA_TEST_ERR(Map.NumMyElements()!=NumMyElements,ierr);  

  EPETRA_TEST_ERR(Map.NumMyPoints()!=NumMyElements,ierr);

  int MaxMyGID2 = Map.GID(Map.LID(MaxMyGID));
  EPETRA_TEST_ERR(MaxMyGID2 != MaxMyGID,ierr);
  int MaxLID2 = Map.LID(Map.GID(MaxLID));
  EPETRA_TEST_ERR(MaxLID2 != MaxLID,ierr);

  EPETRA_TEST_ERR(Map.GID(MaxLID+1) != IndexBase-1,ierr);// MaxLID+1 doesn't exist
  EPETRA_TEST_ERR(Map.LID(MaxMyGID+1) != -1,ierr);// MaxMyGID+1 doesn't exist or is on a different processor

  EPETRA_TEST_ERR(!Map.MyGID(MaxMyGID),ierr);
  EPETRA_TEST_ERR(Map.MyGID(MaxMyGID+1),ierr);

  EPETRA_TEST_ERR(!Map.MyLID(MaxLID),ierr);
  EPETRA_TEST_ERR(Map.MyLID(MaxLID+1),ierr);

  EPETRA_TEST_ERR(!Map.MyGID(Map.GID(MaxLID)),ierr);
  EPETRA_TEST_ERR(Map.MyGID(Map.GID(MaxLID+1)),ierr);

  EPETRA_TEST_ERR(!Map.MyLID(Map.LID(MaxMyGID)),ierr);
  EPETRA_TEST_ERR(Map.MyLID(Map.LID(MaxMyGID+1)),ierr);

  // Check RemoteIDList function
  // Get some GIDs off of each processor to test
  int TotalNumEle, NumElePerProc, NumProc = Comm.NumProc();
  int MinNumEleOnProc;
  int NumMyEle=Map.NumMyElements();
  Comm.MinAll(&NumMyEle,&MinNumEleOnProc,1);
  if (MinNumEleOnProc > 5) NumElePerProc = 6;
  else NumElePerProc = MinNumEleOnProc;
  if (NumElePerProc > 0) {
    TotalNumEle = NumElePerProc*NumProc;
    int * MyGIDlist = new int[NumElePerProc];
    int * GIDlist = new int[TotalNumEle];
    int * PIDlist = new int[TotalNumEle];
    int * LIDlist = new int[TotalNumEle];
    for (i=0; i<NumElePerProc; i++)
	  MyGIDlist[i] = MyGlobalElements1[i];
    Comm.GatherAll(MyGIDlist,GIDlist,NumElePerProc);// Get a few values from each proc
    Map.RemoteIDList(TotalNumEle, GIDlist, PIDlist, LIDlist);
    int MyPID= Comm.MyPID();

    forierr = 0;
    for (i=0; i<TotalNumEle; i++) {
      if (Map.MyGID(GIDlist[i])) {
	forierr += PIDlist[i] != MyPID;
	forierr += !Map.MyLID(Map.LID(GIDlist[i])) || Map.LID(GIDlist[i]) != LIDlist[i] || Map.GID(LIDlist[i]) != GIDlist[i];
      }
      else {
	forierr += PIDlist[i] == MyPID; // If MyGID comes back false, the PID listed should be that of another proc
      }
    }
    EPETRA_TEST_ERR(forierr,ierr);

    delete [] MyGIDlist;
    delete [] GIDlist;
    delete [] PIDlist;
    delete [] LIDlist;
  }

  delete [] MyGlobalElements1;

  // Check RemoteIDList function (assumes all maps are linear, even if not stored that way)

  if (Map.LinearMap()) {

    int * GIDList = new int[3];
    int * PIDList = new int[3];
    int * LIDList = new int[3];
    int MyPID = Map.Comm().MyPID();
  
    int NumIDs = 0;
    //GIDList[NumIDs++] = Map.MaxAllGID()+1; // Should return -1 for both PID and LID
    if (Map.MinMyGID()-1>=Map.MinAllGID()) GIDList[NumIDs++] = Map.MinMyGID()-1;
    if (Map.MaxMyGID()+1<=Map.MaxAllGID()) GIDList[NumIDs++] = Map.MaxMyGID()+1;

    Map.RemoteIDList(NumIDs, GIDList, PIDList, LIDList);

    NumIDs = 0;

    //EPETRA_TEST_ERR(!(PIDList[NumIDs]==-1),ierr);
    //EPETRA_TEST_ERR(!(LIDList[NumIDs++]==-1),ierr);

    if (Map.MinMyGID()-1>=Map.MinAllGID()) EPETRA_TEST_ERR(!(PIDList[NumIDs++]==MyPID-1),ierr);
    if (Map.MaxMyGID()+1<=Map.MaxAllGID()) EPETRA_TEST_ERR(!(PIDList[NumIDs]==MyPID+1),ierr);
    if (Map.MaxMyGID()+1<=Map.MaxAllGID()) EPETRA_TEST_ERR(!(LIDList[NumIDs++]==0),ierr);

    delete [] GIDList;
    delete [] PIDList;
    delete [] LIDList;

  }
  
  return (ierr);
}
void
exampleRoutine (const Epetra_Comm& comm,
                std::ostream& out)
{
    using std::endl;

    // Print out the Epetra software version.
    if (comm.MyPID () == 0) {
        out << Epetra_Version () << endl << endl;
    }

    // The type of global indices.  You could just set this to int,
    // but we want the example to work for Epetra64 as well.
#ifdef EPETRA_NO_32BIT_GLOBAL_INDICES
    // Epetra was compiled only with 64-bit global index support, so use
    // 64-bit global indices.
    typedef long long global_ordinal_type;
#else
    // Epetra was compiled with 32-bit global index support.  If
    // EPETRA_NO_64BIT_GLOBAL_INDICES is defined, it does not also
    // support 64-bit indices.
    typedef int global_ordinal_type;
#endif // EPETRA_NO_32BIT_GLOBAL_INDICES

    //////////////////////////////////////////////////////////////////////
    // Create some Epetra_Map objects
    //////////////////////////////////////////////////////////////////////

    //
    // Epetra has local and global Maps.  Local maps describe objects
    // that are replicated over all participating MPI processes.  Global
    // maps describe distributed objects.  You can do imports and
    // exports between local and global maps; this is how you would turn
    // locally replicated objects into distributed objects and vice
    // versa.
    //

    // The total (global, i.e., over all MPI processes) number of
    // entries in the Map.  This has the same type as that of global
    // indices, so it can represent very large values if Epetra was
    // built with 64-bit global index support.
    //
    // For this example, we scale the global number of entries in the
    // Map with the number of MPI processes.  That way, you can run this
    // example with any number of MPI processes and every process will
    // still have a positive number of entries.
    const global_ordinal_type numGlobalEntries = comm.NumProc () * 5;

    // Tpetra can index the entries of a Map starting with 0 (C style),
    // 1 (Fortran style), or any base you want.  1-based indexing is
    // handy when interfacing with Fortran.  We choose 0-based indexing
    // here.  This also has the same type as that of global indices.
    const global_ordinal_type indexBase = 0;

    // Construct a Map that puts the same number of equations on each
    // (MPI) process.  The Epetra_Comm is passed in by value, but that's
    // OK, because Epetra_Comm has shallow copy semantics.  (Its copy
    // constructor and assignment operator do not call MPI_Comm_dup;
    // they just pass along the MPI_Comm.)
    Epetra_Map contigMap (numGlobalEntries, indexBase, comm);

    // contigMap is contiguous by construction.
    if (! contigMap.LinearMap ()) {
        throw std::logic_error ("The supposedly contiguous Map isn't contiguous.");
    }

    // Let's create a second Map.  It will have the same number of
    // global entries per process, but will distribute them differently,
    // in round-robin (1-D cyclic) fashion instead of contiguously.

    // We'll use the version of the Map constructor that takes, on each
    // MPI process, a list of the global indices in the Map belonging to
    // that process.  You can use this constructor to construct an
    // overlapping (also called "not 1-to-1") Map, in which one or more
    // entries are owned by multiple processes.  We don't do that here;
    // we make a nonoverlapping (also called "1-to-1") Map.
    const int numGblIndsPerProc = 5;
    global_ordinal_type* gblIndList = new global_ordinal_type [numGblIndsPerProc];

    const int numProcs = comm.NumProc ();
    const int myRank = comm.MyPID ();
    for (int k = 0; k < numGblIndsPerProc; ++k) {
        gblIndList[k] = myRank + k*numProcs;
    }

    Epetra_Map cyclicMap (numGlobalEntries, numGblIndsPerProc,
                          gblIndList, indexBase, comm);
    // The above constructor makes a deep copy of the input index list,
    // so it's safe to deallocate that list after this constructor
    // completes.
    if (gblIndList != NULL) {
        delete [] gblIndList;
        gblIndList = NULL;
    }

    // If there's more than one MPI process in the communicator,
    // then cyclicMap is definitely NOT contiguous.
    if (comm.NumProc () > 1 && cyclicMap.LinearMap ()) {
        throw std::logic_error ("The cyclic Map claims to be contiguous.");
    }

    // contigMap and cyclicMap should always be compatible.  However, if
    // the communicator contains more than 1 process, then contigMap and
    // cyclicMap are NOT the same.
    // if (! contigMap.isCompatible (*cyclicMap)) {
    //   throw std::logic_error ("contigMap should be compatible with cyclicMap, "
    //                           "but it's not.");
    // }
    if (comm.NumProc () > 1 && contigMap.SameAs (cyclicMap)) {
        throw std::logic_error ("contigMap should not be the same as cyclicMap.");
    }

    //////////////////////////////////////////////////////////////////////
    // We have maps now, so we can create vectors.
    //////////////////////////////////////////////////////////////////////

    // Create an Epetra_Vector with the contiguous Map we created above.
    // This version of the constructor will fill the vector with zeros.
    // The Vector constructor takes a Map by value, but that's OK,
    // because Epetra_Map has shallow copy semantics.  It uses reference
    // counting internally to avoid copying data unnecessarily.
    Epetra_Vector x (contigMap);

    // The copy constructor performs a deep copy.
    // x and y have the same Map.
    Epetra_Vector y (x);

    // Create a Vector with the 1-D cyclic Map.  Calling the constructor
    // with false for the second argument leaves the data uninitialized,
    // so that you can fill it later without paying the cost of
    // initially filling it with zeros.
    Epetra_Vector z (cyclicMap, false);

    // Set the entries of z to (pseudo)random numbers.  Please don't
    // consider this a good parallel pseudorandom number generator.
    (void) z.Random ();

    // Set the entries of x to all ones.
    (void) x.PutScalar (1.0);

    // Define some constants for use below.
    const double alpha = 3.14159;
    const double beta = 2.71828;
    const double gamma = -10.0;

    // x = beta*x + alpha*z
    //
    // This is a legal operation!  Even though the Maps of x and z are
    // not the same, their Maps are compatible.  Whether it makes sense
    // or not depends on your application.
    (void) x.Update (alpha, z, beta);

    (void) y.PutScalar (42.0); // Set all entries of y to 42.0
    // y = gamma*y + alpha*x + beta*z
    y.Update (alpha, x, beta, z, gamma);

    // Compute the 2-norm of y.
    //
    // The norm may have a different type than scalar_type.
    // For example, if scalar_type is complex, then the norm is real.
    // The ScalarTraits "traits class" gives us the type of the norm.
    double theNorm = 0.0;
    (void) y.Norm2 (&theNorm);

    // Print the norm of y on Proc 0.
    out << "Norm of y: " << theNorm << endl;
}
// FIXME long long
Epetra_Map
Epetra_Util::Create_Root_Map(const Epetra_Map& usermap,
         int root)
{
  int numProc = usermap.Comm().NumProc();
  if (numProc==1) {
    Epetra_Map newmap(usermap);
    return(newmap);
  }

  const Epetra_Comm & comm = usermap.Comm();
  bool isRoot = usermap.Comm().MyPID()==root;

  //if usermap is already completely owned by root then we'll just return a copy of it.
  int quickreturn = 0;
  int globalquickreturn = 0;

  if (isRoot) {
    if (usermap.NumMyElements()==usermap.NumGlobalElements64()) quickreturn = 1;
  }
  else {
    if (usermap.NumMyElements()==0) quickreturn = 1;
  }
  usermap.Comm().MinAll(&quickreturn, &globalquickreturn, 1);
  
  if (globalquickreturn==1) {
    Epetra_Map newmap(usermap);
    return(newmap);
  }
  
  // Linear map: Simple case, just put all GIDs linearly on root processor
  if (usermap.LinearMap() && root!=-1) {
    int numMyElements = 0;
    if (isRoot) numMyElements = usermap.MaxAllGID64()+1; // FIXME long long
    Epetra_Map newmap(-1, numMyElements, usermap.IndexBase(), comm);
    return(newmap);
  }

  if (!usermap.UniqueGIDs()) 
    throw usermap.ReportError("usermap must have unique GIDs",-1);

  // General map

  // Build IntVector of the GIDs, then ship them to root processor
  int numMyElements = usermap.NumMyElements();
  Epetra_Map allGidsMap(-1, numMyElements, 0, comm);
  Epetra_IntVector allGids(allGidsMap);
  for (int i=0; i<numMyElements; i++) allGids[i] = usermap.GID64(i);
  
  int numGlobalElements = usermap.NumGlobalElements64();
  if (root!=-1) {
    int n1 = 0; if (isRoot) n1 = numGlobalElements;
    Epetra_Map allGidsOnRootMap(-1, n1, 0, comm);
    Epetra_Import importer(allGidsOnRootMap, allGidsMap);
    Epetra_IntVector allGidsOnRoot(allGidsOnRootMap);
    allGidsOnRoot.Import(allGids, importer, Insert);
    
    Epetra_Map rootMap(-1, allGidsOnRoot.MyLength(), allGidsOnRoot.Values(), usermap.IndexBase(), comm);
    return(rootMap);
  }
  else {
    int n1 = numGlobalElements;
    Epetra_LocalMap allGidsOnRootMap(n1, 0, comm);
    Epetra_Import importer(allGidsOnRootMap, allGidsMap);
    Epetra_IntVector allGidsOnRoot(allGidsOnRootMap);
    allGidsOnRoot.Import(allGids, importer, Insert);
    
    Epetra_Map rootMap(-1, allGidsOnRoot.MyLength(), allGidsOnRoot.Values(), usermap.IndexBase(), comm);

    return(rootMap);
  }
}