示例#1
0
void Domain::assignLIDs() {
    int LIDCounter = 0;
    srand(time(NULL));
    /*first calculated how many LIDs should I calculate*/
    int totalLIDs = number_of_nodes/*the iLIDs*/ + number_of_connections;
    vector<Bitvector> LIDs(totalLIDs);
    for (int i = 0; i < totalLIDs; i++) {
        calculateLID(LIDs, i);
    }
    for (int i = 0; i < totalLIDs; i++) {
        cout << "LID " << i << " : " << LIDs.at(i).to_string() << endl;
    }
    for (int i = 0; i < network_nodes.size(); i++) {
        NetworkNode *nn = network_nodes[i];
        nn->iLid = LIDs[LIDCounter];
        LIDCounter++;
        for (int j = 0; j < nn->connections.size(); j++) {
            NetworkConnection *nc = nn->connections[j];
            nc->LID = LIDs[LIDCounter];
            LIDCounter++;
        }
    }
}
示例#2
0
int main(int argc, char *argv[]) 
{
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Tpetra::MpiComm<OrdinalType, ScalarType> Comm(MPI_COMM_WORLD);
#else
  Tpetra::SerialComm<OrdinalType, ScalarType> Comm;
#endif

  if (Comm.getNumImages() != 2)
  {
    cout << "This example must be ran with two processors" << endl;
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    exit(EXIT_SUCCESS);
  }

  // Get zero and one for the OrdinalType
  
  OrdinalType const OrdinalZero = Teuchos::ScalarTraits<OrdinalType>::zero();
  OrdinalType const OrdinalOne  = Teuchos::ScalarTraits<OrdinalType>::one();

  // Get zero and one for the ScalarType
  
  ScalarType const ScalarOne  = Teuchos::ScalarTraits<ScalarType>::one();
  ScalarType const ScalarZero = Teuchos::ScalarTraits<ScalarType>::zero();

  OrdinalType indexBase = OrdinalZero;

  // Creation of a platform
  
#ifdef HAVE_MPI
  const Tpetra::MpiPlatform <OrdinalType, OrdinalType> platformE(MPI_COMM_WORLD);
  const Tpetra::MpiPlatform <OrdinalType, ScalarType> platformV(MPI_COMM_WORLD);
#else
  const Tpetra::SerialPlatform <OrdinalType, OrdinalType> platformE;
  const Tpetra::SerialPlatform <OrdinalType, ScalarType> platformV;
#endif

  // These are the `elements' assigned to this image
  // NOTE: This element is NOT a finite element, instead it is
  //       a component of the ElementSpace (that is, the distribution of
  //       vertices). FiniteElements values are defined later on.
  // 
  // NOTATION:
  // - Element       -> an entity of the space
  // - Vertex        -> finite element vertex
  // - FiniteElement -> finite element, composed by two Vertices
  
  const OrdinalType NumMyVertices = OrdinalOne * 3;
  vector<OrdinalType> MyGlobalVertices(NumMyVertices);

  if (Comm.getMyImageID() == 0)
  {
    for (OrdinalType i = OrdinalZero ; i < NumMyVertices ; ++i)
      MyGlobalVertices[OrdinalZero + i] = OrdinalZero + i;
  }
  else
  {
    for (OrdinalType i = OrdinalZero ; i < NumMyVertices ; ++i)
      MyGlobalVertices[OrdinalZero + i] = OrdinalZero + i + 3;
  }

  Tpetra::ElementSpace<OrdinalType> VertexSpace(-OrdinalOne, NumMyVertices, MyGlobalVertices, indexBase, platformE);
  Tpetra::VectorSpace<OrdinalType, ScalarType> VectorVertexSpace(VertexSpace, platformV);

  const OrdinalType NumMyPaddedVertices = OrdinalOne * 4;
  vector<OrdinalType> MyGlobalPaddedVertices(NumMyPaddedVertices);
  // Vector BoundaryVertices contains a flag that specifies
  // whether the node is a Dirichlet node or not
  vector<bool> BoundaryVertices(NumMyVertices);

  // Setting the elements of the connectivity
  if (Comm.getMyImageID() == 0)
  {
    MyGlobalPaddedVertices[0] = OrdinalZero;
    MyGlobalPaddedVertices[1] = OrdinalOne;
    MyGlobalPaddedVertices[2] = OrdinalOne * 2;
    MyGlobalPaddedVertices[3] = OrdinalOne * 3; // ghost node

    BoundaryVertices[0] = true;
    BoundaryVertices[1] = false;
    BoundaryVertices[2] = false;
  }
  else
  {
    MyGlobalPaddedVertices[0] = OrdinalOne * 3;
    MyGlobalPaddedVertices[1] = OrdinalOne * 4;
    MyGlobalPaddedVertices[2] = OrdinalOne * 5;
    MyGlobalPaddedVertices[3] = OrdinalOne * 2; // ghost node

    BoundaryVertices[0] = false;
    BoundaryVertices[1] = false;
    BoundaryVertices[2] = true;
  }

  // This space is needed to import the values of coordinates corresponding
  // to ghost elements. 
  Tpetra::ElementSpace<OrdinalType> PaddedVertexSpace(-OrdinalOne, NumMyPaddedVertices, MyGlobalPaddedVertices, indexBase, platformE);
  Tpetra::VectorSpace<OrdinalType, ScalarType> VectorPaddedVertexSpace(PaddedVertexSpace, platformV);

  // This is the connectivity, in local numbering

  const OrdinalType NumVerticesPerFiniteElement = 2;
  const OrdinalType NumDimensions = 2;

  const OrdinalType NumMyElements = OrdinalOne * 3;
  Teuchos::SerialDenseMatrix<OrdinalType, OrdinalType> Connectivity(NumMyElements, NumVerticesPerFiniteElement);

  // this contains the coordinates
  Tpetra::Vector<OrdinalType, ScalarType> Coord(VectorPaddedVertexSpace);

  if (Comm.getMyImageID() == 0)
  {
    Connectivity(0,0) = 0; Connectivity(0,1) = 1;
    Connectivity(1,0) = 1; Connectivity(1,1) = 2;
    Connectivity(2,0) = 2; Connectivity(2,1) = 3;
    Coord[0] = ScalarZero;
    Coord[1] = ScalarOne;
    Coord[2] = ScalarOne * 2;
    Coord[3] = ScalarOne * 3; // ghost node is last
  }
  else
  {
    Connectivity(0,0) = 0; Connectivity(0,1) = 1;
    Connectivity(1,0) = 1; Connectivity(1,1) = 2;
    Connectivity(2,0) = 3; Connectivity(2,1) = 0;
    Coord[0] = ScalarOne * 3;
    Coord[1] = ScalarOne * 4;
    Coord[2] = ScalarOne * 5;
    Coord[3] = ScalarOne * 2; // ghost node is last
  }

  // Setup the matrix
  
  Teuchos::SerialDenseMatrix<OrdinalType, ScalarType> localMatrix(NumVerticesPerFiniteElement, NumVerticesPerFiniteElement);

  Tpetra::CisMatrix<OrdinalType,ScalarType> matrix(VectorVertexSpace);

  // Loop over all the (locally owned) elements
  
  for (OrdinalType FEID = OrdinalZero ; FEID < NumMyElements ; ++FEID)
  {
    vector<OrdinalType> LIDs(NumVerticesPerFiniteElement), GIDs(NumVerticesPerFiniteElement);

    // Get the local and global ID of this element's vertices
    for (OrdinalType i = OrdinalZero ; i < NumVerticesPerFiniteElement ; ++i)
    {
      LIDs[i] = Connectivity(FEID, i);
      GIDs[i] = PaddedVertexSpace.getGID(LIDs[i]);
    }

    // get the coordinates of all nodes in the element
    vector<ScalarType> x(NumVerticesPerFiniteElement);

    for (OrdinalType i = 0 ; i < NumDimensions ; ++i)
    {
      x[i] = Coord[LIDs[i]];
    }
    
    // build the local matrix, in this case A_loc;
    // this is specific to this 1D Laplace, and does not use
    // coordinates. 
    localMatrix(0, 0) = ScalarOne;
    localMatrix(1, 0) = -ScalarOne;
    localMatrix(0, 1) = -ScalarOne;
    localMatrix(1, 1) = ScalarOne;

    // submit entries of localMatrix into the matrix

    for (OrdinalType LRID = OrdinalZero ; LRID < NumVerticesPerFiniteElement ; ++LRID)
    {
      OrdinalType LocalRow = LIDs[LRID];

      // We skip non-locally owned vertices
      if (LocalRow < NumMyVertices)
      {
        // If the node is a boundary node, then put 1 on the diagonal
        if (BoundaryVertices[LocalRow])
        {
          matrix.submitEntry(Tpetra::Insert, GIDs[LRID], ScalarOne, GIDs[LRID]);
        }
        else
        {
          // otherwise add the entire row
          for (OrdinalType LCID = OrdinalZero ; LCID < NumVerticesPerFiniteElement ; ++LCID)
          {
            matrix.submitEntry(Tpetra::Add, GIDs[LRID], localMatrix(LRID,LCID), GIDs[LCID]);
          }
        }
      }
    }
  }

  matrix.fillComplete();

  cout << matrix;
#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

  return(EXIT_SUCCESS);
}