//============================================================================== 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); }
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); } }