Esempio n. 1
0
	void ModelOBJ::CreateVertexTangentsBinormals( const MaterialGroupIterator & p_MatGroupIt, BIT_FLOAT32 * p_pTangents,
		BIT_FLOAT32 * p_pBinormals, const BIT_UINT32 p_TriangleCount )
	{
		// Go through all the triangles
		BIT_UINT32 ti = 0;
		for( TriangleIterator it_tr = (*p_MatGroupIt)->Triangles.begin( ); it_tr != (*p_MatGroupIt)->Triangles.end( ); it_tr++ )
		{

			for( BIT_UINT32 vt = 0; vt < 3; vt++ )
			{
				Vector3_ui32 Indices( vt, ( vt + 1 ) % 3, ( vt + 2 ) % 3 );

				const Vector3_f32 Vertex1 = m_VertexPositions[ (*it_tr).PositionIndices[ Indices.x ] ];
				const Vector3_f32 Vertex2 = m_VertexPositions[ (*it_tr).PositionIndices[ Indices.y ] ];
				const Vector3_f32 Vertex3 = m_VertexPositions[ (*it_tr).PositionIndices[ Indices.z ] ];

				const Vector2_f32 Texture1 = m_TexturePositions[ (*it_tr).TextureIndices[ Indices.x ] ];
				const Vector2_f32 Texture2 = m_TexturePositions[ (*it_tr).TextureIndices[ Indices.y ] ];
				const Vector2_f32 Texture3 = m_TexturePositions[ (*it_tr).TextureIndices[ Indices.z ] ];

				float x1 = Vertex2.x - Vertex1.x;
				float x2 = Vertex3.x - Vertex1.x;
				float y1 = Vertex2.y - Vertex1.y;
				float y2 = Vertex3.y - Vertex1.y;
				float z1 = Vertex2.z - Vertex1.z;
				float z2 = Vertex3.z - Vertex1.z;

				float s1 = Texture2.x - Texture1.x;
				float s2 = Texture3.x - Texture1.x;
				float t1 = Texture2.y - Texture1.y;
				float t2 = Texture3.y - Texture1.y;

				float r = 1.0f / ( s1 * t2 - s2 * t1 );

				// Tangent
				if( p_pTangents )
				{
					Vector3_f32 Tangent( (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
						(t2 * z1 - t1 * z2) * r );
					Tangent.Normalize( );

					p_pTangents[ ( ti * 9 ) + ( vt * 3 ) + 0 ] = Tangent.x;
					p_pTangents[ ( ti * 9 ) + ( vt * 3 ) + 1 ] = Tangent.y;
					p_pTangents[ ( ti * 9 ) + ( vt * 3 ) + 2 ] = Tangent.z;
				}

				// Binormal
				if( p_pTangents )
				{
					Vector3_f32 Binormal( (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
						(s1 * z2 - s2 * z1) * r );
					Binormal.Normalize( );

					p_pBinormals[ ( ti * 9 ) + ( vt * 3 ) + 0 ] = Binormal.x;
					p_pBinormals[ ( ti * 9 ) + ( vt * 3 ) + 1 ] = Binormal.y;
					p_pBinormals[ ( ti * 9 ) + ( vt * 3 ) + 2 ] = Binormal.z;
				}
			}

			// Increment the triangle index
			ti++;
		}


	}
Esempio n. 2
0
decltype(auto) a2t(const std::array<T, N>& a)
{
    return a2t_impl(a, Indices());
}
Esempio n. 3
0
int main(int argc, char *argv[])
{
#ifdef HAVE_MPI
  // Initialize MPI and setup an Epetra communicator
  MPI_Init(&argc,&argv);
  Teuchos::RCP<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
#else
  // If we aren't using MPI, then setup a serial communicator.
  Teuchos::RCP<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() );
#endif

  bool success = false;
  bool verbose = false;
  try {
    int i, epetra_ierr;
    bool ierr, gerr = true;

    // number of global elements
    int dim = 100;
    int blockSize = 5;

    bool verbose = false;
    if (argc>1) {
      if (argv[1][0]=='-' && argv[1][1]=='v') {
        verbose = true;
      }
    }

    // Construct a Map that puts approximately the same number of
    // equations on each processor.
    Teuchos::RCP<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) );

    // Get update list and number of local equations from newly created Map.
    int NumMyElements = Map->NumMyElements();
    std::vector<int> MyGlobalElements(NumMyElements);
    Map->MyGlobalElements(&MyGlobalElements[0]);

    // Create an integer vector NumNz that is used to build the Petra Matrix.
    // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation
    // on this processor
    std::vector<int> NumNz(NumMyElements);

    // We are building a tridiagonal matrix where each row has (-1 2 -1)
    // So we need 2 off-diagonal terms (except for the first and last equation)
    for (i=0; i<NumMyElements; i++) {
      if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) {
        NumNz[i] = 2;
      }
      else {
        NumNz[i] = 3;
      }
    }

    // Create an Epetra_Matrix
    Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) );

    // Add  rows one-at-a-time
    // Need some vectors to help
    // Off diagonal Values will always be -1
    std::vector<double> Values(2);
    Values[0] = -1.0; Values[1] = -1.0;
    std::vector<int> Indices(2);
    double two = 2.0;
    int NumEntries;
    for (i=0; i<NumMyElements; i++) {
      if (MyGlobalElements[i]==0) {
        Indices[0] = 1;
        NumEntries = 1;
      }
      else if (MyGlobalElements[i] == dim-1) {
        Indices[0] = dim-2;
        NumEntries = 1;
      }
      else {
        Indices[0] = MyGlobalElements[i]-1;
        Indices[1] = MyGlobalElements[i]+1;
        NumEntries = 2;
      }
      epetra_ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]);
      assert(epetra_ierr==0);
      // Put in the diagonal entry
      epetra_ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]);
      assert(epetra_ierr==0);
    }

    // Finish building the epetra matrix A
    epetra_ierr = A->FillComplete();
    assert(epetra_ierr==0);

    // Create an Anasazi::EpetraSymOp from this Epetra_CrsMatrix
    Teuchos::RCP<Anasazi::EpetraSymOp> op = Teuchos::rcp(new Anasazi::EpetraSymOp(A));

    // Issue several useful typedefs;
    typedef Anasazi::MultiVec<double> EMV;
    typedef Anasazi::Operator<double> EOP;

    // Create an Epetra_MultiVector for an initial vector to start the solver.
    // Note that this needs to have the same number of columns as the blocksize.
    Teuchos::RCP<Anasazi::EpetraMultiVec> ivec = Teuchos::rcp( new Anasazi::EpetraMultiVec(*Map, blockSize) );
    ivec->Random();

    // Create an output manager to handle the I/O from the solver
    Teuchos::RCP<Anasazi::OutputManager<double> > MyOM = Teuchos::rcp( new Anasazi::BasicOutputManager<double>() );
    if (verbose) {
      MyOM->setVerbosity( Anasazi::Warnings );
    }

    // test the Epetra adapter multivector
    ierr = Anasazi::TestMultiVecTraits<double,EMV>(MyOM,ivec);
    gerr &= ierr;
    if (ierr) {
      MyOM->print(Anasazi::Warnings,"*** EpetraAdapter PASSED TestMultiVecTraits()\n");
    }
    else {
      MyOM->print(Anasazi::Warnings,"*** EpetraAdapter FAILED TestMultiVecTraits() ***\n\n");
    }

    // test the Epetra adapter operator
    ierr = Anasazi::TestOperatorTraits<double,EMV,EOP>(MyOM,ivec,op);
    gerr &= ierr;
    if (ierr) {
      MyOM->print(Anasazi::Warnings,"*** EpetraAdapter PASSED TestOperatorTraits()\n");
    }
    else {
      MyOM->print(Anasazi::Warnings,"*** EpetraAdapter FAILED TestOperatorTraits() ***\n\n");
    }

    success = gerr;
    if (success) {
      MyOM->print(Anasazi::Warnings,"End Result: TEST PASSED\n");
    } else {
      MyOM->print(Anasazi::Warnings,"End Result: TEST FAILED\n");
    }
  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
  int ierr = 0, i;

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  bool success = false;
  bool verbose = true;
  try {
    //int myRank = Comm.MyPID();

    //int numGlobalElements = 10000000;
    int numGlobalElements = 100;

    Teuchos::CommandLineProcessor cmdp(false,true);
    cmdp.setOption("numGlobalElements",&numGlobalElements,"Global problem size.");
    if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
      throw -1;
    }

    Epetra_Map Map(numGlobalElements, 0, Comm);

    int NumMyElements = Map.NumMyElements();

    std::vector<int> MyGlobalElements(NumMyElements);
    Map.MyGlobalElements(&MyGlobalElements[0]);

    int NumNz = 3;
    // std::vector<int> NumNz(NumMyElements);
    // for (i=0; i<NumMyElements; i++)
    //     if (MyGlobalElements[i]==0 || MyGlobalElements[i] == numGlobalElements-1)
    //       NumNz[i] = 2;
    //     else
    //       NumNz[i] = 3;
    //  Epetra_CrsMatrix A(Copy, Map, &NumNz[0]);

    MemoryUsageStart("Epetra");
    PrintMemoryUsage("Initial memory usage", "epetra-init.heap");

    Epetra_CrsMatrix A(Copy, Map, NumNz);

    PrintMemoryUsage("Memory after CrsMatrix constructor", "epetra-after-ctor.heap");

    std::vector<double> Values(2);
    Values[0] = -1.0; Values[1] = -1.0;
    std::vector<int> Indices(2);
    double two = 2.0;
    int NumEntries;

    for (i=0; i<NumMyElements; i++) {

      if (MyGlobalElements[i]==0) {
        Indices[0] = 1;
        NumEntries = 1;
      } else if (MyGlobalElements[i] == numGlobalElements-1) {
        Indices[0] = numGlobalElements-2;
        NumEntries = 1;
      } else {
        Indices[0] = MyGlobalElements[i]-1;
        Indices[1] = MyGlobalElements[i]+1;
        NumEntries = 2;
      }

      ierr = A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
      assert(ierr==0);

      // Put in the diagonal entry
      ierr = A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i]);
      assert(ierr==0);
    }

    PrintMemoryUsage("Memory after InsertGlobalValues()", "epetra-after-insert.heap");

    ierr = A.FillComplete();
    assert(ierr == 0);

    PrintMemoryUsage("Memory after FillComplete()", "epetra-after-fillcomplete.heap");

    MemoryUsageStop();

    success = true;
  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}
Esempio n. 5
0
void BaseMesh::Split(float (*PositionFunction) (Vec3f &), BaseMesh &M1, BaseMesh &M2)
{
    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<MeshVertex> NV1,NV2;
    Vector<TriMeshFace> NT1,NT2;

    SplitVMapper *VMap = new SplitVMapper[vc];
    float Value;

    for(i=0;i<vc;i++)
    {
        Value = PositionFunction(V[i].Pos);
        if(Value < 0.0f)
        {
            VMap[i].Side = 0;
            VMap[i].NVMap1 = NV1.Length();
            VMap[i].NVMap2 = -1;
            NV1.PushEnd(V[i]);
        } else {
            VMap[i].Side = 1;
            VMap[i].NVMap1 = -1;
            VMap[i].NVMap2 = NV2.Length();
            NV2.PushEnd(V[i]);
        }
    }

    int TSide[3];
    TriMeshFace Tri;
    int Oddball,State;

    for(i=0;i<ic;i+=3)
    {
        TSide[0] = VMap[I[i]].Side;
        TSide[1] = VMap[I[i+1]].Side;
        TSide[2] = VMap[I[i+2]].Side;

        if(TSide[0] && TSide[1] && TSide[2]) //all O2
        {            
            Tri.I[0] = VMap[I[i]].NVMap2;
            Tri.I[1] = VMap[I[i+1]].NVMap2;
            Tri.I[2] = VMap[I[i+2]].NVMap2;
            NT2.PushEnd(Tri);
        } else if(!(TSide[0] || TSide[1] || TSide[2])) //all O1
        {
            Tri.I[0] = VMap[I[i]].NVMap1;
            Tri.I[1] = VMap[I[i+1]].NVMap1;
            Tri.I[2] = VMap[I[i+2]].NVMap1;
            NT1.PushEnd(Tri);
        } else {
            if(TSide[0] && TSide[1]) {Oddball = 2; State = 1;}
            if(TSide[0] && TSide[2]) {Oddball = 1; State = 1;}
            if(TSide[1] && TSide[2]) {Oddball = 0; State = 1;}
            if(!(TSide[0] || TSide[1])) {Oddball = 2; State = 2;}
            if(!(TSide[0] || TSide[2])) {Oddball = 1; State = 2;}
            if(!(TSide[1] || TSide[2])) {Oddball = 0; State = 2;}

            if(State == 1)    //Add to Obj2
            {
                if(VMap[I[i+Oddball]].NVMap2 == -1)
                {
                    VMap[I[i+Oddball]].NVMap2 = NV2.Length();
                    NV2.PushEnd(V[I[i+Oddball]]);
                }
                Tri.I[0] = VMap[I[i]].NVMap2;
                Tri.I[1] = VMap[I[i+1]].NVMap2;
                Tri.I[2] = VMap[I[i+2]].NVMap2;
                NT2.PushEnd(Tri);
            } else {        //Add to Obj1
                if(VMap[I[i+Oddball]].NVMap1 == -1)
                {
                    VMap[I[i+Oddball]].NVMap1 = NV1.Length();
                    NV1.PushEnd(V[I[i+Oddball]]);
                }
                Tri.I[0] = VMap[I[i]].NVMap1;
                Tri.I[1] = VMap[I[i+1]].NVMap1;
                Tri.I[2] = VMap[I[i+2]].NVMap1;
                NT1.PushEnd(Tri);
            }
        }
    }

    delete[] VMap;

    M1.Allocate(NV1.Length(),NT1.Length());
    M2.Allocate(NV2.Length(),NT2.Length());
    
    memcpy(M1.Vertices(), NV1.CArray(), M1.VertexCount() * sizeof(MeshVertex));
    memcpy(M2.Vertices(), NV2.CArray(), M2.VertexCount() * sizeof(MeshVertex));
    memcpy(M1.Indices(), NT1.CArray(), M1.IndexCount() * sizeof(DWORD));
    memcpy(M2.Indices(), NT2.CArray(), M2.IndexCount() * sizeof(DWORD));
}
Esempio n. 6
0
int main(int argc, char *argv[])
{
  int i;
  bool ierr, gerr;
  gerr = true;

#ifdef HAVE_MPI
  // Initialize MPI and setup an Epetra communicator
  MPI_Init(&argc,&argv);
  Teuchos::RCP<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
#else
  // If we aren't using MPI, then setup a serial communicator.
  Teuchos::RCP<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() );
#endif

   // number of global elements
  const int dim = 100;
  const int blockSize = 5;

  bool verbose = false;
  if (argc>1) {
    if (argv[1][0]=='-' && argv[1][1]=='v') {
      verbose = true;
    }
  }

  // Create an output manager to handle the I/O from the solver
  Teuchos::RCP<Anasazi::OutputManager<double> > MyOM = Teuchos::rcp( new Anasazi::BasicOutputManager<double>() );
  if (verbose) {
    MyOM->setVerbosity( Anasazi::Warnings );
  }

#ifndef HAVE_EPETRA_THYRA
  MyOM->stream(Anasazi::Warnings) 
    << "Please configure Anasazi with:" << std::endl
    << "--enable-epetra-thyra" << std::endl
    << "--enable-anasazi-thyra" << std::endl;
#ifdef HAVE_MPI
  MPI_Finalize();
#endif
  return -1;
#endif

  // Construct a Map that puts approximately the same number of 
  // equations on each processor.
  Teuchos::RCP<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) );
  
  // Get update list and number of local equations from newly created Map.
  int NumMyElements = Map->NumMyElements();
  std::vector<int> MyGlobalElements(NumMyElements);
  Map->MyGlobalElements(&MyGlobalElements[0]);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 
  // on this processor
  std::vector<int> NumNz(NumMyElements);

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)
  for (i=0; i<NumMyElements; i++) {
    if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) {
      NumNz[i] = 2;
    }
    else {
      NumNz[i] = 3;
    }
  }

  // Create an Epetra_Matrix
  Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) );
   
  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1
  std::vector<double> Values(2);
  Values[0] = -1.0; Values[1] = -1.0;
  std::vector<int> Indices(2);
  double two = 2.0;
  int NumEntries;
  for (i=0; i<NumMyElements; i++) {
    if (MyGlobalElements[i]==0) {
      Indices[0] = 1;
      NumEntries = 1;
    }
    else if (MyGlobalElements[i] == dim-1) {
      Indices[0] = dim-2;
      NumEntries = 1;
    }
    else {
      Indices[0] = MyGlobalElements[i]-1;
      Indices[1] = MyGlobalElements[i]+1;
      NumEntries = 2;
    }
    ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]);
    assert(ierr==0);
    // Put in the diagonal entry
    ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]);
    assert(ierr==0);
  }

  // Finish building the epetra matrix A
  ierr = A->FillComplete();
  assert(ierr==0);

#ifdef HAVE_EPETRA_THYRA
  typedef Thyra::MultiVectorBase<double> TMVB;
  typedef Thyra::LinearOpBase<double>    TLOB;

  // first, create a Thyra::VectorSpaceBase from an Epetra_Map using the Epetra-Thyra wrappers
  Teuchos::RCP<const Thyra::VectorSpaceBase<double> > space = Thyra::create_VectorSpace(Map);

  // then, create a Thyra::MultiVectorBase from the Thyra::VectorSpaceBase using Thyra creational functions
  Teuchos::RCP<Thyra::MultiVectorBase<double> > thyra_ivec = Thyra::createMembers(space,blockSize);

  // then, create a Thyra::LinearOpBase from the Epetra_CrsMatrix using the Epetra-Thyra wrappers
  Teuchos::RCP<const Thyra::LinearOpBase<double> > thyra_op = Thyra::epetraLinearOp(A);

  // test the Thyra multivector adapter
  ierr = Anasazi::TestMultiVecTraits<double,TMVB>(MyOM,thyra_ivec);
  gerr |= ierr;
  if (ierr) {
    MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter PASSED TestMultiVecTraits()" << std::endl;
  }
  else {
    MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter FAILED TestMultiVecTraits() ***" << std::endl << std::endl;
  }

  // test the Thyra operator adapter
  ierr = Anasazi::TestOperatorTraits<double,TMVB,TLOB>(MyOM,thyra_ivec,thyra_op);
  gerr |= ierr;
  if (ierr) {
    MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter PASSED TestOperatorTraits()" << std::endl;
  }
  else {
    MyOM->stream(Anasazi::Warnings) << "*** ThyraAdapter FAILED TestOperatorTraits() ***" << std::endl << std::endl;
  }
#endif

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  if (gerr == false) {
    MyOM->print(Anasazi::Warnings,"End Result: TEST FAILED\n");
    return -1;
  }
  //
  // Default return value
  //
  MyOM->print(Anasazi::Warnings,"End Result: TEST PASSED\n");
  return 0;

}
Esempio n. 7
0
//==============================================================================
int main(int argc, char *argv[])
{

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  // only one process
  if (Comm.NumProc() != 1) {
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    if (Comm.MyPID() == 0)
      cout << "Please run this test with one process only" << endl;
    // return success not to break the tests
    exit(EXIT_SUCCESS);
  }

  // ======================================================== //
  // now create the famous "upper arrow" matrix, which        //
  // should be reordered as a "lower arrow". Sparsity pattern //
  // will be printed on screen.                               //
  // ======================================================== //
  
  int NumPoints = 16;
  
#if !defined(EPETRA_NO_32BIT_GLOBAL_INDICES) || !defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
  Epetra_Map Map(-1,NumPoints,0,Comm);
#else
  Epetra_Map Map;
#endif

  std::vector<int> Indices(NumPoints);
  std::vector<double> Values(NumPoints);

  Teuchos::RefCountPtr<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy,Map,0) );
  for (int i = 0 ; i < NumPoints ; ++i) {
    
    int NumEntries;
    if (i == 0) {
      NumEntries = NumPoints;
      for (int j = 0 ; j < NumPoints ; ++j) {
	Indices[j] = j;
	Values[j] = 1.0;
      }
    }
    else {
      NumEntries = 2;
      Indices[0] = 0;
      Indices[1] = i;
      Values[0] = 1.0;
      Values[1] = 1.0;
    }

#if !defined(EPETRA_NO_32BIT_GLOBAL_INDICES) || !defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
    A->InsertGlobalValues(i, NumEntries, &Values[0], &Indices[0]);
#endif
  }

  A->FillComplete();

  // print the sparsity to file, postscript format
  ////Ifpack_PrintSparsity(A,"OrigA.ps");

  // create the reordering...
  Teuchos::RefCountPtr<Ifpack_RCMReordering> Reorder = Teuchos::rcp( new Ifpack_RCMReordering() );
  // and compute is on A
  IFPACK_CHK_ERR(Reorder->Compute(*A));

  // cout information
  cout << *Reorder;

  // create a reordered matrix
  Ifpack_ReorderFilter ReordA(A, Reorder);

  // print the sparsity to file, postscript format
  ////Ifpack_PrintSparsity(ReordA,"ReordA.ps");

#ifdef HAVE_MPI
  MPI_Finalize(); 
#endif
  return(EXIT_SUCCESS);

}
Esempio n. 8
0
 T make() const {
   using Indices = std::make_index_sequence<
     std::tuple_size<tuple_type>::value
   >;
   return make_impl<T>(Indices());
 }
int main(int argc, char *argv[]) {
  int i, j, info;
  const double one = 1.0;
  const double zero = 0.0;
  Teuchos::LAPACK<int,double> lapack;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  int MyPID = Comm.MyPID();

  //  Dimension of the matrix
  int m = 500;
  int n = 100;

  // Construct a Map that puts approximately the same number of
  // equations on each processor.

  Epetra_Map RowMap(m, 0, Comm);
  Epetra_Map ColMap(n, 0, Comm);

  // Get update list and number of local equations from newly created Map.

  int NumMyRowElements = RowMap.NumMyElements();
  
  std::vector<int> MyGlobalRowElements(NumMyRowElements);
  RowMap.MyGlobalElements(&MyGlobalRowElements[0]);

  /* We are building an m by n matrix with entries
    
              A(i,j) = k*(si)*(tj - 1) if i <= j
               = k*(tj)*(si - 1) if i  > j
  
     where si = i/(m+1) and tj = j/(n+1) and k = 1/(n+1).
  */

  // Create an Epetra_Matrix
  Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, RowMap, n) );

  // Compute coefficients for discrete integral operator
  std::vector<double> Values(n);
  std::vector<int> Indices(n);
  double inv_mp1 = one/(m+1);
  double inv_np1 = one/(n+1);
  for (i=0; i<n; i++) { Indices[i] = i; }
  
  for (i=0; i<NumMyRowElements; i++) {
    //
    for (j=0; j<n; j++) {
      //
      if ( MyGlobalRowElements[i] <= j ) {
        Values[j] = inv_np1 * ( (MyGlobalRowElements[i]+one)*inv_mp1 ) * ( (j+one)*inv_np1 - one );  // k*(si)*(tj-1)
      }
      else {
        Values[j] = inv_np1 * ( (j+one)*inv_np1 ) * ( (MyGlobalRowElements[i]+one)*inv_mp1 - one );  // k*(tj)*(si-1)
      }
    }
    info = A->InsertGlobalValues(MyGlobalRowElements[i], n, &Values[0], &Indices[0]);
    assert( info==0 );
  }

  // Finish up
  info = A->FillComplete(ColMap, RowMap);
  assert( info==0 );
  info = A->OptimizeStorage();
  assert( info==0 );
  A->SetTracebackMode(1); // Shutdown Epetra Warning tracebacks

  //************************************
  // Start the block Arnoldi iteration
  //***********************************
  //
  //  Variables used for the Block Arnoldi Method
  //
  int nev = 4;
  int blockSize = 1;
  int numBlocks = 10;
  int maxRestarts = 20;
  int verbosity = Anasazi::Errors + Anasazi::Warnings + Anasazi::FinalSummary;
  double tol = lapack.LAMCH('E');
  std::string which = "LM";
  //
  // Create parameter list to pass into solver
  //
  Teuchos::ParameterList MyPL;
  MyPL.set( "Verbosity", verbosity );
  MyPL.set( "Which", which );
  MyPL.set( "Block Size", blockSize );
  MyPL.set( "Num Blocks", numBlocks );
  MyPL.set( "Maximum Restarts", maxRestarts );
  MyPL.set( "Convergence Tolerance", tol );

  typedef Anasazi::MultiVec<double> MV;
  typedef Anasazi::Operator<double> OP;

  // Create an Anasazi::EpetraMultiVec for an initial vector to start the solver. 
  // Note:  This needs to have the same number of columns as the blocksize.
  Teuchos::RCP<Anasazi::EpetraMultiVec> ivec = Teuchos::rcp( new Anasazi::EpetraMultiVec(ColMap, blockSize) );
  ivec->MvRandom();

  // Call the constructor for the (A^T*A) operator
  Teuchos::RCP<Anasazi::EpetraSymOp>  Amat = Teuchos::rcp( new Anasazi::EpetraSymOp(A) );  
  Teuchos::RCP<Anasazi::BasicEigenproblem<double, MV, OP> > MyProblem =
    Teuchos::rcp( new Anasazi::BasicEigenproblem<double, MV, OP>(Amat, ivec) );

  // Inform the eigenproblem that the matrix A is symmetric
  MyProblem->setHermitian(true);

  // Set the number of eigenvalues requested and the blocksize the solver should use
  MyProblem->setNEV( nev );

  // Inform the eigenproblem that you are finished passing it information
  bool boolret = MyProblem->setProblem();
  if (boolret != true) {
    if (MyPID == 0) {
      cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << endl;
    }
#ifdef HAVE_MPI
    MPI_Finalize() ;
#endif
    return -1;
  }

  // Initialize the Block Arnoldi solver
  Anasazi::BlockKrylovSchurSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL);
  
  // Solve the problem to the specified tolerances or length
  Anasazi::ReturnType returnCode = MySolverMgr.solve();
  if (returnCode != Anasazi::Converged && MyPID==0) {
    cout << "Anasazi::EigensolverMgr::solve() returned unconverged." << endl;
  }

  // Get the eigenvalues and eigenvectors from the eigenproblem
  Anasazi::Eigensolution<double,MV> sol = MyProblem->getSolution();
  std::vector<Anasazi::Value<double> > evals = sol.Evals;
  int numev = sol.numVecs;

  if (numev > 0) {
    
    // Compute singular values/vectors and direct residuals.
    //
    // Compute singular values which are the square root of the eigenvalues
    if (MyPID==0) {
      cout<<"------------------------------------------------------"<<endl;
      cout<<"Computed Singular Values: "<<endl;
      cout<<"------------------------------------------------------"<<endl;
    }
    for (i=0; i<numev; i++) { evals[i].realpart = Teuchos::ScalarTraits<double>::squareroot( evals[i].realpart ); }
    //
    // Compute left singular vectors :  u = Av/sigma
    //
    std::vector<double> tempnrm(numev), directnrm(numev);
    std::vector<int> index(numev);
    for (i=0; i<numev; i++) { index[i] = i; }
    Anasazi::EpetraMultiVec Av(RowMap,numev), u(RowMap,numev);
    Anasazi::EpetraMultiVec* evecs = dynamic_cast<Anasazi::EpetraMultiVec* >(sol.Evecs->CloneViewNonConst( index ));
    Teuchos::SerialDenseMatrix<int,double> S(numev,numev);
    A->Apply( *evecs, Av );
    Av.MvNorm( tempnrm );
    for (i=0; i<numev; i++) { S(i,i) = one/tempnrm[i]; };
    u.MvTimesMatAddMv( one, Av, S, zero );
    //
    // Compute direct residuals : || Av - sigma*u ||
    //
    for (i=0; i<numev; i++) { S(i,i) = evals[i].realpart; }
    Av.MvTimesMatAddMv( -one, u, S, one );
    Av.MvNorm( directnrm );
    if (MyPID==0) {
      cout.setf(std::ios_base::right, std::ios_base::adjustfield);
      cout<<std::setw(16)<<"Singular Value"
        <<std::setw(20)<<"Direct Residual"
        <<endl;
      cout<<"------------------------------------------------------"<<endl;
      for (i=0; i<numev; i++) {
        cout<<std::setw(16)<<evals[i].realpart
          <<std::setw(20)<<directnrm[i] 
          <<endl;
      }  
      cout<<"------------------------------------------------------"<<endl;
    }
  }
  
#ifdef EPETRA_MPI
    MPI_Finalize() ;
#endif
  
  return 0;
}
void GetVerticesIntoModel(Model3D& Model)
{
	// Search for redundant vertices -- if there are any vertices to look for
	if (FullVertexList.empty()) return;
	
	// First, index-sort them
	
	// Set up for index sorting by finding the position range
	// (this code is a bit smarter than BG's 3DMF Mapper code for doing that);
	// this is unnecessary for the other vertex data
	GLfloat PosMin[3], PosMax[3];
	for (int c=0; c<3; c++)
		PosMin[c] = PosMax[c] = FullVertexList[0].Data[FullVertexData::POS_BASE+c];
	
	int OldNumVertices = FullVertexList.size();
	for (int k=0; k<OldNumVertices; k++)
	{
		GLfloat *Pos = FullVertexList[0].Data + FullVertexData::POS_BASE;
		for (int c=0; c<3; c++)
		{
			GLfloat PC = Pos[c];
			PosMin[c] = MIN(PosMin[c],PC);
			PosMax[c] = MAX(PosMax[c],PC);
		}
	}
	const GLfloat ThresholdConstant = 0.001;
	for (int c=0; c<3; c++)
		Thresholds[FullVertexData::POS_BASE+c] = ThresholdConstant*(PosMax[c]-PosMin[c]);
	for (int c=0; c<2; c++)
		Thresholds[FullVertexData::TC_BASE+c] = ThresholdConstant;
	for (int c=0; c<3; c++)
		Thresholds[FullVertexData::NORM_BASE+c] = ThresholdConstant;
	for (int c=0; c<3; c++)
		Thresholds[FullVertexData::COLOR_BASE+c] = ThresholdConstant;

	// Now the actual sorting
	vector<int> Indices(OldNumVertices);
	for (int k=0; k<Indices.size(); k++)
		Indices[k] = k;
	
	// STL sort may be slow
	qsort(&Indices[0],OldNumVertices,sizeof(int),CompareVertices);
	
	// Set up vertex ranks in place; count the distinct vertices.
	// Also, use the first one of a non-distinct set in sorted order
	// as the new vertex
	Model.VertIndices.resize(OldNumVertices);
	vector<int> VertexSelect;
	VertexSelect.resize(OldNumVertices);
	
	int TopRank = 0;
	int PrevIndex = Indices[0];
	VertexSelect[TopRank] = PrevIndex;
	Model.VertIndices[PrevIndex] = TopRank;
	for (int k=1; k<OldNumVertices; k++)
	{
		int CurrIndex = Indices[k];
		if (CompareVertices(&PrevIndex,&CurrIndex) != 0)
		{
			TopRank++;
			VertexSelect[TopRank] = CurrIndex;
		}
		Model.VertIndices[CurrIndex] = TopRank;
		PrevIndex = CurrIndex;
	}
	int NewNumVertices = TopRank + 1;
	
	// Fill up the rest of model arrays
	Model.Positions.resize(3*NewNumVertices);
	GLfloat *PosPtr = &Model.Positions[0];
	
	GLfloat *TCPtr = NULL;
	if (TxtrCoordsPresent)
	{
		Model.TxtrCoords.resize(2*NewNumVertices);
		TCPtr = &Model.TxtrCoords[0];
	}
	
	GLfloat *NormPtr = NULL;
	if (NormalsPresent)
	{
		Model.Normals.resize(3*NewNumVertices);
		NormPtr = &Model.Normals[0];
	}
	
	GLfloat *ColorPtr = NULL;
	if (ColorsPresent)
	{
		Model.Colors.resize(3*NewNumVertices);
		ColorPtr = &Model.Colors[0];
	}
	
	for (int k=0; k<NewNumVertices; k++)
	{
		FullVertexData& FullVertex = FullVertexList[VertexSelect[k]];
		
		GLfloat *Pos = FullVertex.Data + FullVertexData::POS_BASE;
		for (int c=0; c<3; c++)
			*(PosPtr++) = *(Pos++);
		
		if (TxtrCoordsPresent)
		{
			GLfloat *TC = FullVertex.Data + FullVertexData::TC_BASE;
			for (int c=0; c<2; c++)
				*(TCPtr++) = *(TC++);	
		}
		
		if (NormalsPresent)
		{
			GLfloat *Norm = FullVertex.Data + FullVertexData::NORM_BASE;
			for (int c=0; c<3; c++)
				*(NormPtr++) = *(Norm++);	
		}
		
		if (ColorsPresent)
		{
			GLfloat *Color = FullVertex.Data + FullVertexData::COLOR_BASE;
			for (int c=0; c<3; c++)
				*(ColorPtr++) = *(Color++);	
		}
	}
	
	// All done!
	FullVertexList.clear();
}
Esempio n. 11
0
void BaseMesh::TwoPatch()
{
    Vector<MeshVertex> NewVertices;    //list of new vertices in the mesh
    Vector<TriMeshFace> NewFaces;      //list of new faces in the mesh

    UINT vc = VertexCount(), ic = IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<MeshTwoPatchEdge>* HashVertices = new Vector<MeshTwoPatchEdge>[vc];
    //HashVertices is a hash table that stores all edges incident on an edge.
    //a given edge's location in the hash table is HashVertices[Q], where Q is the index
    //of the smallest of the edge's two indices.
    
    DWORD LocalTIndices[6];     //we take each face and add 3 new vertices in the middle of each edge.
                                //LocalTIndices represents these 6 vertices (the 3 new ones and the 3 origional ones.)
                                //these 6 vertices then become 4 triangles that exactly match the origional triangle.

    DWORD VertexIndex;           //the index of the vertex we're looking for
    MeshVertex NewVertex;        //the new vertex we're going to add to the mesh
    TriMeshFace NewTriangle;     //the new triangle we're going to add to the mesh
    MeshTwoPatchEdge NewEdge;    //the edge we're going to add to the hash table

    for(UINT i = 0; i < vc; i++)
    {
        NewVertices.PushEnd(V[i]);    //all old vertices will be in the new mesh
    }

    for(UINT i = 0; i < ic; i+=3)
    {
        LocalTIndices[0] = I[i+0];
        LocalTIndices[1] = I[i+1];
        LocalTIndices[2] = I[i+2];    //the origional 3 triangles are always in LocalTIndices

        //now it remains to get the vertices at the middle of each edge
        //if these aren't already in the mesh we just add a new vertex to the final mesh, otherwise we need to use our hash table to find
        //their position in the mesh and use those indices.

        for(UINT i2=0;i2<3;i2++)
        {
            int EdgeVtx1, EdgeVtx2;    //the indices we're looking for
            if(i2 == 0)
            {
                EdgeVtx1 = I[i+0];
                EdgeVtx2 = I[i+1];
            }
            if(i2 == 1)
            {
                EdgeVtx1 = I[i+1];
                EdgeVtx2 = I[i+2];
            }
            if(i2 == 2)
            {
                EdgeVtx1 = I[i+0];
                EdgeVtx2 = I[i+2];
            }
            if(EdgeVtx2 < EdgeVtx1) Utility::Swap(EdgeVtx1, EdgeVtx2);    //we want EdgeVtx1 to be the smallest
            if(SearchTwoPatchEdge(HashVertices[EdgeVtx1], VertexIndex, EdgeVtx2))    //search for the corresponding edge to see if it's already in the mesh
            {
                LocalTIndices[3+i2] = VertexIndex;    //if it is we just choose the found index as our entry in LocalTIndices.  No need to add another vertex to the mesh; it's already there
            } else 
            {
                Interpolate(V[EdgeVtx1],V[EdgeVtx2],NewVertex,0.5f);    //otherwise make a new vertex at the middle of the edge,
                NewEdge.v2 = EdgeVtx2;
                NewEdge.v1 = NewVertices.Length();
                LocalTIndices[3+i2] = NewVertices.Length();        //this new vertex is our LocalTIndices entry
                HashVertices[EdgeVtx1].PushEnd(NewEdge);           //we need to add it to the hash table...
                NewVertices.PushEnd(NewVertex);                       //and add it to the new mesh
            }
        }

        //Now we have all 6 of our LocalTIndices.  This was one triangle in the origional mesh and is now 4 triangles in the new mesh.
        //we add those 4 new triangles now.

        NewTriangle.I[0] = LocalTIndices[0];
        NewTriangle.I[1] = LocalTIndices[3];
        NewTriangle.I[2] = LocalTIndices[5];
        NewFaces.PushEnd(NewTriangle);

        NewTriangle.I[0] = LocalTIndices[3];
        NewTriangle.I[1] = LocalTIndices[1];
        NewTriangle.I[2] = LocalTIndices[4];
        NewFaces.PushEnd(NewTriangle);

        NewTriangle.I[0] = LocalTIndices[5];
        NewTriangle.I[1] = LocalTIndices[4];
        NewTriangle.I[2] = LocalTIndices[2];
        NewFaces.PushEnd(NewTriangle);

        NewTriangle.I[0] = LocalTIndices[5];
        NewTriangle.I[1] = LocalTIndices[3];
        NewTriangle.I[2] = LocalTIndices[4];
        NewFaces.PushEnd(NewTriangle);
    }

    for(UINT i = 0; i <vc; i++)
    {
        HashVertices[i].FreeMemory();
    }

    delete[] HashVertices;                //free the hash table up

    Allocate(NewVertices.Length(), NewFaces.Length());    //allocate space for the new mesh (deleting the old mesh)

    MeshVertex *VNew = Vertices();
    DWORD *INew = Indices();
    vc = VertexCount();
    ic = IndexCount();

    for(UINT i = 0; i < vc; i++)
    {
        VNew[i] = NewVertices[i];
    }

    for(UINT i = 0; i < ic / 3; i++)
    {
        INew[i * 3 + 0] = NewFaces[i].I[0];
        INew[i * 3 + 1] = NewFaces[i].I[1];
        INew[i * 3 + 2] = NewFaces[i].I[2];
    }
}
Esempio n. 12
0
Vect<float &> a2v(std::array<T, N>& a, int j)
{
    return a2v_impl(a, j, Indices());
}
Esempio n. 13
0
// ======================================================================
int Ifpack_PrintSparsity(const Epetra_RowMatrix& A, const char* InputFileName,
                         const int NumPDEEqns)
{

  int ltit;
  long long m,nc,nr,maxdim;
  double lrmrgn,botmrgn,xtit,ytit,ytitof,fnstit,siz = 0.0;
  double xl,xr, yb,yt, scfct,u2dot,frlw,delt,paperx;
  bool square = false;
  /*change square to .true. if you prefer a square frame around
    a rectangular matrix */
  double conv = 2.54;
  char munt = 'E'; /* put 'E' for centimeters, 'U' for inches */
  int ptitle = 0; /* position of the title, 0 under the drawing,
                     else above */
  FILE* fp = NULL;
  int NumMyRows;
  //int NumMyCols;
  long long NumGlobalRows;
  long long NumGlobalCols;
  int MyPID;
  int NumProc;
  char FileName[1024];
  char title[1024];

  const Epetra_Comm& Comm = A.Comm();

  /* --------------------- execution begins ---------------------- */

  if (strlen(A.Label()) != 0)
    strcpy(title, A.Label());
  else
    sprintf(title, "%s", "matrix");

  if (InputFileName == 0)
    sprintf(FileName, "%s.ps", title);
  else
    strcpy(FileName, InputFileName);

  MyPID = Comm.MyPID();
  NumProc = Comm.NumProc();

  NumMyRows = A.NumMyRows();
  //NumMyCols = A.NumMyCols();

  NumGlobalRows = A.NumGlobalRows64();
  NumGlobalCols = A.NumGlobalCols64();

  if (NumGlobalRows != NumGlobalCols)
    IFPACK_CHK_ERR(-1); // never tested

  /* to be changed for rect matrices */
  maxdim = (NumGlobalRows>NumGlobalCols)?NumGlobalRows:NumGlobalCols;
  maxdim /= NumPDEEqns;

  m = 1 + maxdim;
  nr = NumGlobalRows / NumPDEEqns + 1;
  nc = NumGlobalCols / NumPDEEqns + 1;

  if (munt == 'E') {
    u2dot = 72.0/conv;
    paperx = 21.0;
    siz = 10.0;
  }
  else {
    u2dot = 72.0;
    paperx = 8.5*conv;
    siz = siz*conv;
  }

  /* left and right margins (drawing is centered) */

  lrmrgn = (paperx-siz)/2.0;

  /* bottom margin : 2 cm */

  botmrgn = 2.0;
  /* c scaling factor */
  scfct = siz*u2dot/m;
  /* matrix frame line witdh */
  frlw = 0.25;
  /* font size for title (cm) */
  fnstit = 0.5;
  /* mfh 23 Jan 2013: title is always nonnull, since it's an array of
     fixed nonzero length.  The 'if' test thus results in a compiler
     warning. */
  /*if (title) ltit = strlen(title);*/
  /*else       ltit = 0;*/
  ltit = strlen(title);

  /* position of title : centered horizontally */
  /*                     at 1.0 cm vertically over the drawing */
  ytitof = 1.0;
  xtit = paperx/2.0;
  ytit = botmrgn+siz*nr/m + ytitof;
  /* almost exact bounding box */
  xl = lrmrgn*u2dot - scfct*frlw/2;
  xr = (lrmrgn+siz)*u2dot + scfct*frlw/2;
  yb = botmrgn*u2dot - scfct*frlw/2;
  yt = (botmrgn+siz*nr/m)*u2dot + scfct*frlw/2;
  if (ltit == 0) {
    yt = yt + (ytitof+fnstit*0.70)*u2dot;
  }
  /* add some room to bounding box */
  delt = 10.0;
  xl = xl-delt;
  xr = xr+delt;
  yb = yb-delt;
  yt = yt+delt;

  /* correction for title under the drawing */
  if ((ptitle == 0) && (ltit == 0)) {
    ytit = botmrgn + fnstit*0.3;
    botmrgn = botmrgn + ytitof + fnstit*0.7;
  }

  /* begin of output */

  if (MyPID == 0) {

    fp = fopen(FileName,"w");

    fprintf(fp,"%s","%%!PS-Adobe-2.0\n");
    fprintf(fp,"%s","%%Creator: IFPACK\n");
    fprintf(fp,"%%%%BoundingBox: %f %f %f %f\n",
            xl,yb,xr,yt);
    fprintf(fp,"%s","%%EndComments\n");
    fprintf(fp,"%s","/cm {72 mul 2.54 div} def\n");
    fprintf(fp,"%s","/mc {72 div 2.54 mul} def\n");
    fprintf(fp,"%s","/pnum { 72 div 2.54 mul 20 string ");
    fprintf(fp,"%s","cvs print ( ) print} def\n");
    fprintf(fp,"%s","/Cshow {dup stringwidth pop -2 div 0 rmoveto show} def\n");

    /* we leave margins etc. in cm so it is easy to modify them if
       needed by editing the output file */
    fprintf(fp,"%s","gsave\n");
    if (ltit != 0) {
      fprintf(fp,"/Helvetica findfont %e cm scalefont setfont\n",
              fnstit);
      fprintf(fp,"%f cm %f cm moveto\n",
              xtit,ytit);
      fprintf(fp,"(%s) Cshow\n", title);
      fprintf(fp,"%f cm %f cm translate\n",
              lrmrgn,botmrgn);
    }
    fprintf(fp,"%f cm %d div dup scale \n",
            siz, (int) m);
    /* draw a frame around the matrix */

    fprintf(fp,"%f setlinewidth\n",
            frlw);
    fprintf(fp,"%s","newpath\n");
    fprintf(fp,"%s","0 0 moveto ");
    if (square) {
      printf("------------------- %d\n", (int) m);
      fprintf(fp,"%d %d lineto\n",
              (int) m, 0);
      fprintf(fp,"%d %d lineto\n",
              (int) m, (int) m);
      fprintf(fp,"%d %d lineto\n",
              0, (int) m);
    }
    else {
      fprintf(fp,"%d %d lineto\n",
              (int) nc, 0);
      fprintf(fp,"%d %d lineto\n",
              (int) nc, (int) nr);
      fprintf(fp,"%d %d lineto\n",
              0, (int) nr);
    }
    fprintf(fp,"%s","closepath stroke\n");

    /* plotting loop */

    fprintf(fp,"%s","1 1 translate\n");
    fprintf(fp,"%s","0.8 setlinewidth\n");
    fprintf(fp,"%s","/p {moveto 0 -.40 rmoveto \n");
    fprintf(fp,"%s","           0  .80 rlineto stroke} def\n");

    fclose(fp);
  }

  int MaxEntries = A.MaxNumEntries();
  std::vector<int> Indices(MaxEntries);
  std::vector<double> Values(MaxEntries);

  for (int pid = 0 ; pid < NumProc ; ++pid) {

    if (pid == MyPID) {

      fp = fopen(FileName,"a");
      if( fp == NULL ) {
        fprintf(stderr,"%s","ERROR\n");
        exit(EXIT_FAILURE);
      }

      for (int i = 0 ; i < NumMyRows ; ++i) {

        if (i % NumPDEEqns) continue;

        int Nnz;
        A.ExtractMyRowCopy(i,MaxEntries,Nnz,&Values[0],&Indices[0]);

        long long grow = A.RowMatrixRowMap().GID64(i);

        for (int j = 0 ; j < Nnz ; ++j) {
          int col = Indices[j];
          if (col % NumPDEEqns == 0) {
            long long gcol = A.RowMatrixColMap().GID64(Indices[j]);
            grow /= NumPDEEqns;
            gcol /= NumPDEEqns;
            fprintf(fp,"%lld %lld p\n",
                    gcol, NumGlobalRows - grow - 1);
          }
        }
      }

      fprintf(fp,"%s","%end of data for this process\n");

      if( pid == NumProc - 1 )
        fprintf(fp,"%s","showpage\n");

      fclose(fp);
    }
    Comm.Barrier();
  }

  return(0);
}
Esempio n. 14
0
int main(int argc, char *argv[])
{
  int ierr = 0;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc, &argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if(verbose && MyPID==0)
    cout << Epetra_Version() << std::endl << std::endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
		    << " is alive."<<endl;

  // unused: bool verbose1 = verbose;

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0) 
    verbose = false;

  if (verbose) cout << "Test the memory management system of the class CrsMatrix (memory leak, invalid free)" << std::endl;

  //
  // Test 1: code initially proposed to illustrate bug #5499
  //
  
  if(Comm.NumProc() == 1) { // this is a sequential test

    if (verbose) cout << "* Using Copy, ColMap, Variable number of indices per row and Static profile (cf. bug #5499)." << std::endl;

    // Row Map
    Epetra_Map RowMap(2LL, 0LL, Comm);
    
    // ColMap  
    std::vector<long long> colids(2);
    colids[0]=0;
    colids[1]=1;
    Epetra_Map ColMap(-1LL, 2, &colids[0], 0LL, Comm);

    // NumEntriesPerRow
    std::vector<int> NumEntriesPerRow(2);
    NumEntriesPerRow[0]=2;
    NumEntriesPerRow[1]=2;
    
    // Test
    Epetra_CrsMatrix A(Copy, RowMap, ColMap, &NumEntriesPerRow[0], true);
    // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed)
    A.FillComplete();
    
  }

  //
  // Test 1 Bis: same as Test1, but without ColMap and variable number of indices per row. Does not seems to matter
  //
  
  if(Comm.NumProc() == 1) { // this is a sequential test

    if (verbose) cout << "* Using Copy, Fixed number of indices per row and Static profile" << std::endl;

    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
    // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed)
    A.FillComplete();
    
  }

  //
  // Test 2: same as Test 1 Bis but with one call to InsertGlobalValues.
  //

  if(Comm.NumProc() == 1) {

    if (verbose) cout << "* Using Copy, Fixed number of indices per row and Static profile + InsertGlobalValues()." << std::endl;

    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
    std::vector<long long>    Indices(1);
    std::vector<double> Values(1);
    Values[0] = 2;
    Indices[0] = 0;

    A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]); // Memory leak if CrsMatrix::Values not freed

    A.FillComplete();

  }

  // 
  // Test 3: check if the patch is not introducing some obvious regression
  //

  if(Comm.NumProc() == 1) {
    
    if (verbose) cout << "* Using Copy, Fixed number of indices per row and Dynamic profile" << std::endl;
    
    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, false);
    A.FillComplete();
    
  }

  // 
  // Test 4: idem but with one call to InsertGlobalValues.
  // 

  if(Comm.NumProc() == 1) {
    
    if (verbose) cout << "* Using Copy, Fixed number of indices per row and Dynamic profile + InsertGlobalValues()." << std::endl;
    
    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, false);
    std::vector<long long>    Indices(1);
    std::vector<double> Values(1);
    Values[0] = 2;
    Indices[0] = 0;
    
    A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]);
    A.FillComplete();
    
  }

  if(Comm.NumProc() == 1) {
    
    if (verbose) cout << "* Using Copy, Static Graph()." << std::endl;
    
    Epetra_Map RowMap(1LL, 0LL, Comm);

    // Test
    Epetra_CrsGraph    G(Copy, RowMap, 1);
    std::vector<long long>    Indices(1);
    Indices[0] = 0;
    G.InsertGlobalIndices(0, 1, &Indices[0]);
    G.FillComplete();
    
    Epetra_CrsMatrix    A(Copy, G);
    std::vector<double> Values(1);
    Values[0] = 2;
    A.ReplaceGlobalValues(0, 1, &Values[0], &Indices[0]);
    A.FillComplete();
    double norminf = A.NormInf();
    if (verbose) cout << "** Inf Norm of Matrix = " << norminf << "." << std::endl;
    cout << A << std::endl;

    
  }


  if(Comm.NumProc() == 1) {
    
    if (verbose) cout << "* Using Copy, Fixed number of indices per row and static profile + InsertGlobalValues() for a single row." << std::endl;
    
    Epetra_Map RowMap(1LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
    std::vector<long long>    Indices(1);
    std::vector<double> Values(1);
    Values[0] = 2;
    Indices[0] = 0;
    
    A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]);
    A.FillComplete();
    
  }

  /*
    if (bool) {
    if (verbose) cout << endl << "tests FAILED" << endl << endl;
    }
    else {*/
  if (verbose) cout << endl << "tests PASSED" << endl << endl;
  /*    } */

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return ierr;
}
        std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> >
        Cross3D_Helmholtz_Pair(const Teuchos::RCP<const Map> & map,
                               const GlobalOrdinal nx,      const GlobalOrdinal ny,        const GlobalOrdinal nz,
                               const double h,              const double delta,
                               const int PMLgridptsx_left,  const int PMLgridptsx_right,
                               const int PMLgridptsy_left,  const int PMLgridptsy_right,
                               const int PMLgridptsz_left,  const int PMLgridptsz_right,
                               const double omega,          const Scalar shift,
			       const int model) {

          Teuchos::RCP<Matrix> ktx = MatrixTraits<Map,Matrix>::Build(map, 7);
          Teuchos::RCP<Matrix> mtx = MatrixTraits<Map,Matrix>::Build(map, 1);

          LocalOrdinal                               NumMyElements = map->getNodeNumElements();
          Teuchos::ArrayView<const GlobalOrdinal> MyGlobalElements = map->getNodeElementList();

          GlobalOrdinal left, right, bottom, top, front, back, center;
          std::vector<Scalar> Values(7);
          std::vector<GlobalOrdinal> Indices(7);
	  VelocityModel<Scalar,LocalOrdinal,GlobalOrdinal> velocitymodel(3,model);

          double LBx, RBx, LBy, RBy, LBz, RBz, Dx, Dy, Dz;
          Scalar sx_left, sx_center, sx_right;
          Scalar sy_left, sy_center, sy_right;
          Scalar sz_left, sz_center, sz_right;
	  Scalar c;
          // Calculate some parameters
          Dx = ((double) nx-1)*h;
          Dy = ((double) ny-1)*h;
          Dz = ((double) nz-1)*h;
          LBx = ((double) PMLgridptsx_left)*h;
          RBx = Dx-((double) PMLgridptsx_right)*h;
          LBy = ((double) PMLgridptsy_left)*h;
          RBy = Dy-((double) PMLgridptsy_right)*h;
          LBz = ((double) PMLgridptsz_left)*h;
          RBz = Dz-((double) PMLgridptsz_right)*h;

          for (GlobalOrdinal i = 0; i < NumMyElements; ++i) {

	    // calculate PML functions
            size_t numEntries = 0;
            center = MyGlobalElements[i];
            GetNeighboursCartesian3d(center, nx, ny, nz, left, right, front, back, bottom, top);
            GetPMLvalues(center, nx, ny, nz, h, delta, Dx, Dy, Dz,
                         LBx, RBx, LBy, RBy, LBz, RBz,
                         sx_left, sx_center, sx_right,
                         sy_left, sy_center, sy_right,
                         sz_left, sz_center, sz_right);
	    // get velocity
	    GlobalOrdinal ixy, ix, iy, iz;
	    ixy = i % (nx * ny);
	    iz = (i - ixy) / (nx * ny);
	    ix = ixy % nx;
	    iy = (ixy - ix) / nx;
	    double xcoord, ycoord, zcoord;
	    xcoord=((double) ix)*h;
	    ycoord=((double) iy)*h;
	    zcoord=((double) iz)*h;
	    c = velocitymodel.getVelocity(xcoord,ycoord,zcoord);
	    
            if (left != -1) {
              Indices[numEntries] = left;
              Values [numEntries] = -(sy_center*sz_center/sx_center + sy_center*sz_center/sx_left)/2.0;
              numEntries++;
            }
            if (right != -1) {
              Indices[numEntries] = right;
              Values [numEntries] = -(sy_center*sz_center/sx_center + sy_center*sz_center/sx_right)/2.0;
              numEntries++;
            }
            if (front != -1) {
              Indices[numEntries] = front;
              Values [numEntries] = -(sx_center*sz_center/sy_center + sx_center*sz_center/sy_right)/2.0;
              numEntries++;
            }
            if (back != -1) {
              Indices[numEntries] = back;
              Values [numEntries] = -(sx_center*sz_center/sy_center + sx_center*sz_center/sy_left)/2.0;
              numEntries++;
            }
            if (bottom != -1) {
              Indices[numEntries] = bottom;
              Values [numEntries] = -(sx_center*sy_center/sz_center + sx_center*sy_center/sz_left)/2.0;
              numEntries++;
            }
            if (top != -1) {
              Indices[numEntries] = top;
              Values [numEntries] = -(sx_center*sy_center/sz_center + sx_center*sy_center/sz_right)/2.0;
              numEntries++;
            }

            // diagonal
            Scalar z = (Scalar) 0.0;
            for (size_t j = 0; j < numEntries; j++)
              z -= Values[j];

            Indices[numEntries] = center;
            Values [numEntries] = z;
            numEntries++;

            Teuchos::ArrayView<GlobalOrdinal> iv(&Indices[0], numEntries);
            Teuchos::ArrayView<Scalar>        av(&Values[0],  numEntries);
            ktx->insertGlobalValues(center, iv, av);
            mtx->insertGlobalValues(center,
                                    Teuchos::tuple<GlobalOrdinal>(center),
                                    Teuchos::tuple<Scalar>(h*h*sx_center*sy_center*sz_center/(c*c)) );

          }

          ktx->fillComplete();
          mtx->fillComplete();
          std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> > system;
          system=std::make_pair(ktx,mtx);
          return system;

        } //Cross3D_Helmholtz
Esempio n. 16
0
status_t
Volume::Mount(const char* deviceName, uint32 flags)
{
	// TODO: validate the FS in write mode as well!
#if (B_HOST_IS_LENDIAN && defined(BFS_BIG_ENDIAN_ONLY)) \
	|| (B_HOST_IS_BENDIAN && defined(BFS_LITTLE_ENDIAN_ONLY))
	// in big endian mode, we only mount read-only for now
	flags |= B_MOUNT_READ_ONLY;
#endif

	DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0
		? O_RDONLY : O_RDWR);
	fDevice = opener.Device();
	if (fDevice < B_OK)
		RETURN_ERROR(fDevice);

	if (opener.IsReadOnly())
		fFlags |= VOLUME_READ_ONLY;

	// read the superblock
	if (Identify(fDevice, &fSuperBlock) != B_OK) {
		FATAL(("invalid superblock!\n"));
		return B_BAD_VALUE;
	}

	// initialize short hands to the superblock (to save byte swapping)
	fBlockSize = fSuperBlock.BlockSize();
	fBlockShift = fSuperBlock.BlockShift();
	fAllocationGroupShift = fSuperBlock.AllocationGroupShift();

	// check if the device size is large enough to hold the file system
	off_t diskSize;
	if (opener.GetSize(&diskSize, &fDeviceBlockSize) != B_OK)
		RETURN_ERROR(B_ERROR);
	if (diskSize < (NumBlocks() << BlockShift()))
		RETURN_ERROR(B_BAD_VALUE);

	// set the current log pointers, so that journaling will work correctly
	fLogStart = fSuperBlock.LogStart();
	fLogEnd = fSuperBlock.LogEnd();

	if ((fBlockCache = opener.InitCache(NumBlocks(), fBlockSize)) == NULL)
		return B_ERROR;

	fJournal = new(std::nothrow) Journal(this);
	if (fJournal == NULL)
		return B_NO_MEMORY;

	status_t status = fJournal->InitCheck();
	if (status < B_OK) {
		FATAL(("could not initialize journal: %s!\n", strerror(status)));
		return status;
	}

	// replaying the log is the first thing we will do on this disk
	status = fJournal->ReplayLog();
	if (status != B_OK) {
		FATAL(("Replaying log failed, data may be corrupted, volume "
			"read-only.\n"));
		fFlags |= VOLUME_READ_ONLY;
			// TODO: if this is the boot volume, Bootscript will assume this
			// is a CD...
			// TODO: it would be nice to have a user visible alert instead
			// of letting him just find this in the syslog.
	}

	status = fBlockAllocator.Initialize();
	if (status != B_OK) {
		FATAL(("could not initialize block bitmap allocator!\n"));
		return status;
	}

	fRootNode = new(std::nothrow) Inode(this, ToVnode(Root()));
	if (fRootNode != NULL && fRootNode->InitCheck() == B_OK) {
		status = publish_vnode(fVolume, ToVnode(Root()), (void*)fRootNode,
			&gBFSVnodeOps, fRootNode->Mode(), 0);
		if (status == B_OK) {
			// try to get indices root dir

			if (!Indices().IsZero()) {
				fIndicesNode = new(std::nothrow) Inode(this,
					ToVnode(Indices()));
			}

			if (fIndicesNode == NULL
				|| fIndicesNode->InitCheck() < B_OK
				|| !fIndicesNode->IsContainer()) {
				INFORM(("bfs: volume doesn't have indices!\n"));

				if (fIndicesNode) {
					// if this is the case, the index root node is gone bad,
					// and BFS switch to read-only mode
					fFlags |= VOLUME_READ_ONLY;
					delete fIndicesNode;
					fIndicesNode = NULL;
				}
			} else {
				// we don't use the vnode layer to access the indices node
			}
		} else {
			FATAL(("could not create root node: publish_vnode() failed!\n"));
			delete fRootNode;
			return status;
		}
	} else {
		status = B_BAD_VALUE;
		FATAL(("could not create root node!\n"));
		return status;
	}

	// all went fine
	opener.Keep();
	return B_OK;
}
Esempio n. 17
0
UINT64 BaseMesh::Hash64() const
{
    return Utility::Hash64((const BYTE *)Vertices(), VertexCount() * sizeof(MeshVertex)) +
           Utility::Hash64((const BYTE *)Indices(), IndexCount() * sizeof(DWORD));
}
Esempio n. 18
0
// source point clouds are assumed to contain their normals
int ICP::registerModelToScene(const Mat& srcPC, const Mat& dstPC, double& residual, Matx44d& pose)
{
  int n = srcPC.rows;

  const bool useRobustReject = m_rejectionScale>0;

  Mat srcTemp = srcPC.clone();
  Mat dstTemp = dstPC.clone();
  Vec3d meanSrc, meanDst;
  computeMeanCols(srcTemp, meanSrc);
  computeMeanCols(dstTemp, meanDst);
  Vec3d meanAvg = 0.5 * (meanSrc + meanDst);
  subtractColumns(srcTemp, meanAvg);
  subtractColumns(dstTemp, meanAvg);

  double distSrc = computeDistToOrigin(srcTemp);
  double distDst = computeDistToOrigin(dstTemp);

  double scale = (double)n / ((distSrc + distDst)*0.5);

  srcTemp(cv::Range(0, srcTemp.rows), cv::Range(0,3)) *= scale;
  dstTemp(cv::Range(0, dstTemp.rows), cv::Range(0,3)) *= scale;

  Mat srcPC0 = srcTemp;
  Mat dstPC0 = dstTemp;

  // initialize pose
  pose = Matx44d::eye();

  Mat M = Mat::eye(4,4,CV_64F);

  double tempResidual = 0;


  // walk the pyramid
  for (int level = m_numLevels-1; level >=0; level--)
  {
    const double impact = 2;
    double div = pow((double)impact, (double)level);
    //double div2 = div*div;
    const int numSamples = cvRound((double)(n/(div)));
    const double TolP = m_tolerance*(double)(level+1)*(level+1);
    const int MaxIterationsPyr = cvRound((double)m_maxIterations/(level+1));

    // Obtain the sampled point clouds for this level: Also rotates the normals
    Mat srcPCT = transformPCPose(srcPC0, pose);

    const int sampleStep = cvRound((double)n/(double)numSamples);

    srcPCT = samplePCUniform(srcPCT, sampleStep);
    /*
    Tolga Birdal thinks that downsampling the scene points might decrease the accuracy.
    Hamdi Sahloul, however, noticed that accuracy increased (pose residual decreased slightly).
    */
    Mat dstPCS = samplePCUniform(dstPC0, sampleStep);
    void* flann = indexPCFlann(dstPCS);

    double fval_old=9999999999;
    double fval_perc=0;
    double fval_min=9999999999;
    Mat Src_Moved = srcPCT.clone();

    int i=0;

    size_t numElSrc = (size_t)Src_Moved.rows;
    int sizesResult[2] = {(int)numElSrc, 1};
    float* distances = new float[numElSrc];
    int* indices = new int[numElSrc];

    Mat Indices(2, sizesResult, CV_32S, indices, 0);
    Mat Distances(2, sizesResult, CV_32F, distances, 0);

    // use robust weighting for outlier treatment
    int* indicesModel = new int[numElSrc];
    int* indicesScene = new int[numElSrc];

    int* newI = new int[numElSrc];
    int* newJ = new int[numElSrc];

    Matx44d PoseX = Matx44d::eye();

    while ( (!(fval_perc<(1+TolP) && fval_perc>(1-TolP))) && i<MaxIterationsPyr)
    {
      uint di=0, selInd = 0;

      queryPCFlann(flann, Src_Moved, Indices, Distances);

      for (di=0; di<numElSrc; di++)
      {
        newI[di] = di;
        newJ[di] = indices[di];
      }

      if (useRobustReject)
      {
        int numInliers = 0;
        float threshold = getRejectionThreshold(distances, Distances.rows, m_rejectionScale);
        Mat acceptInd = Distances<threshold;

        uchar *accPtr = (uchar*)acceptInd.data;
        for (int l=0; l<acceptInd.rows; l++)
        {
          if (accPtr[l])
          {
            newI[numInliers] = l;
            newJ[numInliers] = indices[l];
            numInliers++;
          }
        }
        numElSrc=numInliers;
      }

      // Step 2: Picky ICP
      // Among the resulting corresponding pairs, if more than one scene point p_i
      // is assigned to the same model point m_j, then select p_i that corresponds
      // to the minimum distance

      hashtable_int* duplicateTable = getHashtable(newJ, numElSrc, dstPCS.rows);

      for (di=0; di<duplicateTable->size; di++)
      {
        hashnode_i *node = duplicateTable->nodes[di];

        if (node)
        {
          // select the first node
          size_t idx = reinterpret_cast<size_t>(node->data)-1, dn=0;
          int dup = (int)node->key-1;
          size_t minIdxD = idx;
          float minDist = distances[idx];

          while ( node )
          {
            idx = reinterpret_cast<size_t>(node->data)-1;

            if (distances[idx] < minDist)
            {
              minDist = distances[idx];
              minIdxD = idx;
            }

            node = node->next;
            dn++;
          }

          indicesModel[ selInd ] = newI[ minIdxD ];
          indicesScene[ selInd ] = dup ;
          selInd++;
        }
      }

      hashtableDestroy(duplicateTable);

      if (selInd >= 6)
      {

        Mat Src_Match = Mat(selInd, srcPCT.cols, CV_64F);
        Mat Dst_Match = Mat(selInd, srcPCT.cols, CV_64F);

        for (di=0; di<selInd; di++)
        {
          const int indModel = indicesModel[di];
          const int indScene = indicesScene[di];
          const float *srcPt = srcPCT.ptr<float>(indModel);
          const float *dstPt = dstPCS.ptr<float>(indScene);
          double *srcMatchPt = Src_Match.ptr<double>(di);
          double *dstMatchPt = Dst_Match.ptr<double>(di);
          int ci=0;

          for (ci=0; ci<srcPCT.cols; ci++)
          {
            srcMatchPt[ci] = (double)srcPt[ci];
            dstMatchPt[ci] = (double)dstPt[ci];
          }
        }

        Vec3d rpy, t;
        minimizePointToPlaneMetric(Src_Match, Dst_Match, rpy, t);
        if (cvIsNaN(cv::trace(rpy)) || cvIsNaN(cv::norm(t)))
          break;
        getTransformMat(rpy, t, PoseX);
        Src_Moved = transformPCPose(srcPCT, PoseX);

        double fval = cv::norm(Src_Match, Dst_Match)/(double)(Src_Moved.rows);

        // Calculate change in error between iterations
        fval_perc=fval/fval_old;

        // Store error value
        fval_old=fval;

        if (fval < fval_min)
          fval_min = fval;
      }
      else
        break;

      i++;

    }

    pose = PoseX * pose;
    residual = tempResidual;

    delete[] newI;
    delete[] newJ;
    delete[] indicesModel;
    delete[] indicesScene;
    delete[] distances;
    delete[] indices;

    tempResidual = fval_min;
    destroyFlann(flann);
  }

  Matx33d Rpose;
  Vec3d Cpose;
  poseToRT(pose, Rpose, Cpose);
  Cpose = Cpose / scale + meanAvg - Rpose * meanAvg;
  rtToPose(Rpose, Cpose, pose);

  residual = tempResidual;

  return 0;
}
Esempio n. 19
0
// ============================================================================
void
PrintStencil2D(const Epetra_CrsMatrix* Matrix,
               const int nx, const int ny, int GID)
{
  if (nx <= 0 || ny <= 0)
      throw(Exception(__FILE__, __LINE__, "Input parameter not valid"));

  if (GID == -1)
  {
    if (ny == 1)
      GID = (int)(nx/2);
    else
      GID = (int)(nx*(ny/2) + nx/2);
  }

  int LID = Matrix->RowMatrixRowMap().LID(GID);

  // only processor having this node will go on
  if (LID == -1) return;

  int MaxPerRow = Matrix->MaxNumEntries();
  int NumEntriesRow;   // local entries on each row
  vector<double> Values(MaxPerRow);
  vector<int>    Indices(MaxPerRow);

  int ierr = Matrix->ExtractMyRowCopy(LID, MaxPerRow, NumEntriesRow,
                                      &Values[0], &Indices[0]);

  if (ierr)
    throw(Exception(__FILE__, __LINE__,
                    "Matrix->ExtractMyRowCopy() return an error"));

  // cycle over nonzero elements, look for elements in positions that we
  // can understand

  int size = 5;
  Epetra_IntSerialDenseMatrix SI(size, size);
  Epetra_SerialDenseMatrix    SV(size, size);

  for (int i = 0 ; i < size ; ++i)
    for (int j = 0 ; j < size ; ++j)
      SV(i, j) = 0.0;

  SI(0,0) = Matrix->RowMatrixColMap().LID(GID - 2 - 2 * nx);
  SI(1,0) = Matrix->RowMatrixColMap().LID(GID - 1 - 2 * nx);
  SI(2,0) = Matrix->RowMatrixColMap().LID(GID - 2 * nx);
  SI(3,0) = Matrix->RowMatrixColMap().LID(GID + 1 - 2 * nx);
  SI(4,0) = Matrix->RowMatrixColMap().LID(GID + 2 - 2 * nx);

  SI(0,1) = Matrix->RowMatrixColMap().LID(GID - 2 - nx);
  SI(1,1) = Matrix->RowMatrixColMap().LID(GID - 1 - nx);
  SI(2,1) = Matrix->RowMatrixColMap().LID(GID - nx);
  SI(3,1) = Matrix->RowMatrixColMap().LID(GID + 1 - nx);
  SI(4,1) = Matrix->RowMatrixColMap().LID(GID + 2 - nx);

  SI(0,2) = Matrix->RowMatrixColMap().LID(GID - 2);
  SI(1,2) = Matrix->RowMatrixColMap().LID(GID - 1);
  SI(2,2) = Matrix->RowMatrixColMap().LID(GID);
  SI(3,2) = Matrix->RowMatrixColMap().LID(GID + 1);
  SI(4,2) = Matrix->RowMatrixColMap().LID(GID + 2);

  SI(0,3) = Matrix->RowMatrixColMap().LID(GID - 2 + nx);
  SI(1,3) = Matrix->RowMatrixColMap().LID(GID - 1 + nx);
  SI(2,3) = Matrix->RowMatrixColMap().LID(GID - nx);
  SI(3,3) = Matrix->RowMatrixColMap().LID(GID + 1 + nx);
  SI(4,3) = Matrix->RowMatrixColMap().LID(GID + 2 + nx);

  SI(0,4) = Matrix->RowMatrixColMap().LID(GID - 2 + 2 * nx);
  SI(1,4) = Matrix->RowMatrixColMap().LID(GID - 1 + 2 * nx);
  SI(2,4) = Matrix->RowMatrixColMap().LID(GID - 2 * nx);
  SI(3,4) = Matrix->RowMatrixColMap().LID(GID + 1 + 2 * nx);
  SI(4,4) = Matrix->RowMatrixColMap().LID(GID + 2 + 2 * nx);

  for (int i = 0 ; i < NumEntriesRow ; ++i)
  {
    // convert into block row
    int LocalColID = Indices[i];
    // look for known positions
    for (int ix = 0 ; ix < size ; ++ix)
      for (int iy = 0 ; iy < size ; ++iy)
	if (SI(ix, iy) == LocalColID)
	  SV(ix,iy) = Values[i];
  }

  cout << "2D computational stencil at GID " << GID
       << " (grid is " << nx << " x " << ny << ")" << endl;
  cout << endl;
  for (int iy = 0 ; iy < size ; ++iy)
  {
    for (int ix = 0 ; ix < size ; ++ix)
    {
      cout << " " << std::setw(10) << SV(ix,iy);
    }
    cout << endl;
  }
  cout << endl;
}
Esempio n. 20
0
//==========================================================================
int Ifpack_SPARSKIT::Compute() 
{
  if (!IsInitialized()) 
    IFPACK_CHK_ERR(Initialize());

  IsComputed_ = false;

  // convert the matrix into SPARSKIT format. The matrix is then
  // free'd after method Compute() returns.

  // convert the matrix into CSR format. Note that nnz is an over-estimate,
  // since it contains the nonzeros corresponding to external nodes as well.
  int n   = Matrix().NumMyRows();
  int nnz = Matrix().NumMyNonzeros();

  vector<double> a(nnz);
  vector<int>    ja(nnz);
  vector<int>    ia(n + 1);

  const int MaxNumEntries = Matrix().MaxNumEntries();

  vector<double> Values(MaxNumEntries);
  vector<int>    Indices(MaxNumEntries);

  int count = 0;

  ia[0] = 1;
  for (int i = 0 ; i < n ; ++i)
  {
    int NumEntries;
    int NumMyEntries = 0;
    Matrix().ExtractMyRowCopy(i, MaxNumEntries, NumEntries, &Values[0], 
                              &Indices[0]);

    // NOTE: There might be some issues here with the ILU(0) if the column indices aren't sorted.
    // The other factorizations are probably OK.

    for (int j = 0 ; j < NumEntries ; ++j)
    {
      if (Indices[j] < n) // skip non-local columns
      {
        a[count]  = Values[j];
        ja[count] = Indices[j] + 1; // SPARSKIT is FORTRAN
        ++count;
        ++NumMyEntries;
      }
    }
    ia[i + 1] = ia[i] + NumMyEntries;
  }

  if (mbloc_ == -1) mbloc_ = n;

  int iwk;

  if (Type_ == "ILUT" || Type_ == "ILUTP" || Type_ == "ILUD" ||
      Type_ == "ILUDP")
    iwk = nnz + 2 * lfil_ * n;
  else if (Type_ == "ILUK")
    iwk = (2 * lfil_ + 1) * nnz + 1;
  else if (Type_ == "ILU0")
    iwk = nnz+2;

  int ierr = 0;

  alu_.resize(iwk);
  jlu_.resize(iwk);
  ju_.resize(n + 1);

  vector<int>    jw(n + 1);
  vector<double> w(n + 1);

  if (Type_ == "ILUT")
  {
    jw.resize(2 * n);
    F77_ILUT(&n, &a[0], &ja[0], &ia[0], &lfil_, &droptol_,
             &alu_[0], &jlu_[0], &ju_[0], &iwk, &w[0], &jw[0], &ierr);
  }
  else if (Type_ == "ILUD")
  {
    jw.resize(2 * n);
    F77_ILUD(&n, &a[0], &ja[0], &ia[0], &alph_, &tol_,
             &alu_[0], &jlu_[0], &ju_[0], &iwk, &w[0], &jw[0], &ierr);
  }
  else if (Type_ == "ILUTP")
  {
    jw.resize(2 * n);
    iperm_.resize(2 * n);
    F77_ILUTP(&n, &a[0], &ja[0], &ia[0], &lfil_, &droptol_, &permtol_, 
              &mbloc_, &alu_[0], &jlu_[0], &ju_[0], &iwk, &w[0], &jw[0],
              &iperm_[0], &ierr);
    for (int i = 0 ; i < n ; ++i)
      iperm_[i]--;
  }
  else if (Type_ == "ILUDP")
  {
    jw.resize(2 * n);
    iperm_.resize(2 * n);
    F77_ILUDP(&n, &a[0], &ja[0], &ia[0], &alph_, &droptol_, &permtol_, 
              &mbloc_, &alu_[0], &jlu_[0], &ju_[0], &n, &w[0], &jw[0],
              &iperm_[0], &ierr);
    for (int i = 0 ; i < n ; ++i)
      iperm_[i]--;
  }
  else if (Type_ == "ILUK")
  {
    vector<int> levs(iwk);
    jw.resize(3 * n);
    F77_ILUK(&n, &a[0], &ja[0], &ia[0], &lfil_, 
             &alu_[0], &jlu_[0], &ju_[0], &levs[0], &iwk, &w[0], &jw[0], &ierr);
  }
  else if (Type_ == "ILU0")
  {
    // here w is only of size n
    jw.resize(2 * n);
    F77_ILU0(&n, &a[0], &ja[0], &ia[0], 
             &alu_[0], &jlu_[0], &ju_[0], &jw[0], &ierr);
  }
  IFPACK_CHK_ERR(ierr);

  IsComputed_ = true;
  return(0);
}
Esempio n. 21
0
 inline Result tuple_init( Tuple && t ) {
   return etude::to_tuple( std::forward<Tuple>(t), Indices() );
 }
//==============================================================================
int Ifpack_PointRelaxation::
ApplyInverseGS_RowMatrix(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
{
  int NumVectors = X.NumVectors();

  int Length = Matrix().MaxNumEntries();
  vector<int> Indices(Length);
  vector<double> Values(Length);

  Teuchos::RefCountPtr< Epetra_MultiVector > Y2;
  if (IsParallel_)
    Y2 = Teuchos::rcp( new Epetra_MultiVector(Importer_->TargetMap(), NumVectors) );
  else
    Y2 = Teuchos::rcp( &Y, false );

  // extract views (for nicer and faster code)
  double** y_ptr, ** y2_ptr, ** x_ptr, *d_ptr;
  X.ExtractView(&x_ptr);
  Y.ExtractView(&y_ptr);
  Y2->ExtractView(&y2_ptr);
  Diagonal_->ExtractView(&d_ptr);

  for (int j = 0; j < NumSweeps_ ; j++) {

    // data exchange is here, once per sweep
    if (IsParallel_)
      IFPACK_CHK_ERR(Y2->Import(Y,*Importer_,Insert));

    // FIXME: do I really need this code below?
    if (NumVectors == 1) {

      double* y0_ptr = y_ptr[0];
      double* y20_ptr = y2_ptr[0];
      double* x0_ptr = x_ptr[0];

      if(!DoBackwardGS_){      
        /* Forward Mode */
        for (int i = 0 ; i < NumMyRows_ ; ++i) {

          int NumEntries;
          int col;
          IFPACK_CHK_ERR(Matrix_->ExtractMyRowCopy(i, Length,NumEntries,
                                                   &Values[0], &Indices[0]));
          
          double dtemp = 0.0;
          for (int k = 0 ; k < NumEntries ; ++k) {
            
            col = Indices[k];
            dtemp += Values[k] * y20_ptr[col];
          }
          
          y20_ptr[i] += DampingFactor_ * d_ptr[i] * (x0_ptr[i] - dtemp);
        }
      }
      else {
        /* Backward Mode */
        for (int i = NumMyRows_  - 1 ; i > -1 ; --i) {

          int NumEntries;
          int col;
          IFPACK_CHK_ERR(Matrix_->ExtractMyRowCopy(i, Length,NumEntries,
                                                   &Values[0], &Indices[0]));
          double dtemp = 0.0;
          for (int k = 0 ; k < NumEntries ; ++k) {

            col = Indices[k];
            dtemp += Values[k] * y20_ptr[i];
          }
          
          y20_ptr[i] += DampingFactor_ * d_ptr[i] * (x0_ptr[i] - dtemp);
        }
      }
      
      // using Export() sounded quite expensive
      if (IsParallel_)
        for (int i = 0 ; i < NumMyRows_ ; ++i)
          y0_ptr[i] = y20_ptr[i];

    }
    else {
      if(!DoBackwardGS_){      
        /* Forward Mode */
        for (int i = 0 ; i < NumMyRows_ ; ++i) {
          
          int NumEntries;
          int col;
          IFPACK_CHK_ERR(Matrix_->ExtractMyRowCopy(i, Length,NumEntries,
                                                   &Values[0], &Indices[0]));
          
          for (int m = 0 ; m < NumVectors ; ++m) {
            
            double dtemp = 0.0;
            for (int k = 0 ; k < NumEntries ; ++k) {
              
              col = Indices[k];
              dtemp += Values[k] * y2_ptr[m][col];
            }
            
            y2_ptr[m][i] += DampingFactor_ * d_ptr[i] * (x_ptr[m][i] - dtemp);
          }
        }
      }
      else {
        /* Backward Mode */
        for (int i = NumMyRows_  - 1 ; i > -1 ; --i) {
          int NumEntries;
          int col;
          IFPACK_CHK_ERR(Matrix_->ExtractMyRowCopy(i, Length,NumEntries,
                                                   &Values[0], &Indices[0]));

          for (int m = 0 ; m < NumVectors ; ++m) {
            
            double dtemp = 0.0;
            for (int k = 0 ; k < NumEntries ; ++k) {

              col = Indices[k];
              dtemp += Values[k] * y2_ptr[m][col];
            }

            y2_ptr[m][i] += DampingFactor_ * d_ptr[i] * (x_ptr[m][i] - dtemp);

          }
        }
      }

      // using Export() sounded quite expensive   
      if (IsParallel_)
        for (int m = 0 ; m < NumVectors ; ++m) 
          for (int i = 0 ; i < NumMyRows_ ; ++i)
            y_ptr[m][i] = y2_ptr[m][i];
      
    }
  }

  ApplyInverseFlops_ += NumVectors * (4 * NumGlobalRows_ + 2 * NumGlobalNonzeros_);

  return(0);
} //ApplyInverseGS_RowMatrix()
Esempio n. 23
0
void BaseMesh::ClosedPlaneSplit(const Plane &P, BaseMesh &M1, BaseMesh &M2)
{
    UINT VC = VertexCount(), IC = IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<Vec3f> NewVertices[2];
    Vector<TriMeshFace> NewFaces[2];
    Vector<Vec2f> BoundaryVertices;
    Vector<UINT> BoundaryIndices[2];

    Vec3f OrthogonalBasis1, OrthogonalBasis2;
    Vec3f::CompleteOrthonormalBasis(P.Normal(), OrthogonalBasis1, OrthogonalBasis2);

    PerfectSplitVMapper *VMap = new PerfectSplitVMapper[VC];
    
    for(UINT VertexIndex = 0; VertexIndex < VC; VertexIndex++)
    {
        Vec3f Pos = V[VertexIndex].Pos;
        float Value = Plane::DotCoord(P, Pos);
        if(Value < 0.0f)
        {
            VMap[VertexIndex].Side = 0;
            VMap[VertexIndex].NVMap = NewVertices[0].Length();
            NewVertices[0].PushEnd(Pos);
        }
        else
        {
            VMap[VertexIndex].Side = 1;
            VMap[VertexIndex].NVMap = NewVertices[1].Length();
            NewVertices[1].PushEnd(Pos);
        }
    }

    for(UINT IndexIndex = 0; IndexIndex < IC; IndexIndex += 3)
    {
        int TSide[3];
        TSide[0] = VMap[I[IndexIndex + 0]].Side;
        TSide[1] = VMap[I[IndexIndex + 1]].Side;
        TSide[2] = VMap[I[IndexIndex + 2]].Side;

        DWORD LocalTriangleM1[6], LocalTriangleM2[6];
        LocalTriangleM2[0] = LocalTriangleM1[0] = VMap[I[IndexIndex + 0]].NVMap;
        LocalTriangleM2[1] = LocalTriangleM1[1] = VMap[I[IndexIndex + 1]].NVMap;
        LocalTriangleM2[2] = LocalTriangleM1[2] = VMap[I[IndexIndex + 2]].NVMap;

        UINT TriangleType = TSide[0] * 4 + TSide[1] * 2 + TSide[2] * 1;

        for(UINT EdgeIndex = 0; EdgeIndex < 3; EdgeIndex++)
        {
            if(PerfectEdges[TriangleType][EdgeIndex])
            {
                Vec3f Vtx1 = V[I[IndexIndex + PerfectEdgeList[EdgeIndex][0]]].Pos;
                Vec3f Vtx2 = V[I[IndexIndex + PerfectEdgeList[EdgeIndex][1]]].Pos;
                Vec3f VtxIntersect = P.IntersectLine(Vtx1, Vtx2);
                
                if(!Vec3f::WithinRect(VtxIntersect, Rectangle3f::ConstructFromTwoPoints(Vtx1, Vtx2)))
                {
                    VtxIntersect = (Vtx1 + Vtx2) * 0.5f;
                }
                
                BoundaryVertices.PushEnd(Vec2f(Vec3f::Dot(VtxIntersect, OrthogonalBasis1), Vec3f::Dot(VtxIntersect, OrthogonalBasis2)));

                LocalTriangleM1[3 + EdgeIndex] = NewVertices[0].Length();
                BoundaryIndices[0].PushEnd(NewVertices[0].Length());
                NewVertices[0].PushEnd(VtxIntersect);

                LocalTriangleM2[3 + EdgeIndex] = NewVertices[1].Length();
                BoundaryIndices[1].PushEnd(NewVertices[1].Length());
                NewVertices[1].PushEnd(VtxIntersect);
            }
        }

        for(UINT LocalTriangleIndex = 0; LocalTriangleIndex < 6; LocalTriangleIndex += 3)
        {
            if(M1Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                TriMeshFace Tri;
                Tri.I[0] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 0]];
                Tri.I[1] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 1]];
                Tri.I[2] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 2]];
                NewFaces[0].PushEnd(Tri);
            }
            if(M2Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                TriMeshFace Tri;
                Tri.I[0] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 0]];
                Tri.I[1] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 1]];
                Tri.I[2] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 2]];
                NewFaces[1].PushEnd(Tri);
            }
        }
    }

#ifdef DELAUNAY_TRIANGULATOR
    if(BoundaryVertices.Length() > 0)
    {
        Vector<DWORD> BoundaryTriangulation;
        DelaunayTriangulator::Triangulate(BoundaryVertices, BoundaryTriangulation);
        for(UINT TriangleIndex = 0; TriangleIndex < BoundaryTriangulation.Length() / 3; TriangleIndex++)
        {
            for(UINT MeshIndex = 0; MeshIndex < 2; MeshIndex++)
            {
                TriMeshFace Tri;
                Vec3f V[3];
                for(UINT LocalVertexIndex = 0; LocalVertexIndex < 3; LocalVertexIndex++)
                {
                    Tri.I[LocalVertexIndex] = BoundaryIndices[MeshIndex][UINT(BoundaryTriangulation[TriangleIndex * 3 + LocalVertexIndex])];
                    V[LocalVertexIndex] = NewVertices[MeshIndex][UINT(Tri.I[LocalVertexIndex])];
                }
                //Utility::Swap(Tri.I[0], Tri.I[1]);
                //if(Math::TriangleArea(V[0], V[1], V[2]) > 1e-5f)
                {
                    NewFaces[MeshIndex].PushEnd(Tri);
                }
            }
        }
    }
#endif

    delete[] VMap;

    M1.SetGD(GetGD());
    M2.SetGD(GetGD());
    M1.Allocate(NewVertices[0].Length(), NewFaces[0].Length());
    M2.Allocate(NewVertices[1].Length(), NewFaces[1].Length());
    
    for(UINT VertexIndex = 0; VertexIndex < NewVertices[0].Length(); VertexIndex++)
    {
        M1.Vertices()[VertexIndex].Pos = NewVertices[0][VertexIndex];
    }
    for(UINT VertexIndex = 0; VertexIndex < NewVertices[1].Length(); VertexIndex++)
    {
        M2.Vertices()[VertexIndex].Pos = NewVertices[1][VertexIndex];
    }
    
    if(NewFaces[0].Length() > 0)
    {
        memcpy(M1.Indices(), NewFaces[0].CArray(), M1.IndexCount() * sizeof(DWORD));
    }
    if(NewFaces[1].Length() > 0)
    {
        memcpy(M2.Indices(), NewFaces[1].CArray(), M2.IndexCount() * sizeof(DWORD));
    }
}
//==============================================================================
int Ifpack_PointRelaxation::
ApplyInverseSGS_RowMatrix(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
{
  int NumVectors = X.NumVectors();
  int Length = Matrix().MaxNumEntries();
  vector<int> Indices(Length);
  vector<double> Values(Length);

  Teuchos::RefCountPtr< Epetra_MultiVector > Y2;
  if (IsParallel_) {
    Y2 = Teuchos::rcp( new Epetra_MultiVector(Importer_->TargetMap(), NumVectors) );
  }
  else
    Y2 = Teuchos::rcp( &Y, false );

  double** y_ptr, ** y2_ptr, ** x_ptr, *d_ptr;
  X.ExtractView(&x_ptr);
  Y.ExtractView(&y_ptr);
  Y2->ExtractView(&y2_ptr);
  Diagonal_->ExtractView(&d_ptr);
  
  for (int iter = 0 ; iter < NumSweeps_ ; ++iter) {
    
    // only one data exchange per sweep
    if (IsParallel_)
      IFPACK_CHK_ERR(Y2->Import(Y,*Importer_,Insert));

    for (int i = 0 ; i < NumMyRows_ ; ++i) {

      int NumEntries;
      int col;
      double diag = d_ptr[i];

      IFPACK_CHK_ERR(Matrix_->ExtractMyRowCopy(i, Length,NumEntries,
                                               &Values[0], &Indices[0]));

      for (int m = 0 ; m < NumVectors ; ++m) {

        double dtemp = 0.0;

        for (int k = 0 ; k < NumEntries ; ++k) {

          col = Indices[k];
          dtemp += Values[k] * y2_ptr[m][col];
        }

        y2_ptr[m][i] += DampingFactor_ * (x_ptr[m][i] - dtemp) * diag;
      }
    }

    for (int i = NumMyRows_  - 1 ; i > -1 ; --i) {

      int NumEntries;
      int col;
      double diag = d_ptr[i];

      IFPACK_CHK_ERR(Matrix_->ExtractMyRowCopy(i, Length,NumEntries,
                                               &Values[0], &Indices[0]));

      for (int m = 0 ; m < NumVectors ; ++m) {

        double dtemp = 0.0;
        for (int k = 0 ; k < NumEntries ; ++k) {

          col = Indices[k];
          dtemp += Values[k] * y2_ptr[m][col];
        }

        y2_ptr[m][i] += DampingFactor_ * (x_ptr[m][i] - dtemp) * diag;

      }
    }

    if (IsParallel_)
      for (int m = 0 ; m < NumVectors ; ++m) 
        for (int i = 0 ; i < NumMyRows_ ; ++i)
          y_ptr[m][i] = y2_ptr[m][i];
  }

  ApplyInverseFlops_ += NumVectors * (8 * NumGlobalRows_ + 4 * NumGlobalNonzeros_);
  return(0);
}
Esempio n. 25
0
int main(int argc, char *argv[]) {

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  bool testFailed;
  bool boolret;
  int MyPID = Comm.MyPID();

  bool verbose = true;
  bool debug = false;
  std::string which("SM");

  Teuchos::CommandLineProcessor cmdp(false,true);
  cmdp.setOption("verbose","quiet",&verbose,"Print messages and results.");
  cmdp.setOption("debug","nodebug",&debug,"Print debugging information.");
  cmdp.setOption("sort",&which,"Targetted eigenvalues (SM,LM,SR,LR,SI,or LI).");
  if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    return -1;
  }

  typedef double ScalarType;
  typedef Teuchos::ScalarTraits<ScalarType>          ScalarTypeTraits;
  typedef ScalarTypeTraits::magnitudeType            MagnitudeType;
  typedef Epetra_MultiVector                         MV;
  typedef Epetra_Operator                            OP;
  typedef Anasazi::MultiVecTraits<ScalarType,MV>     MVTraits;
  typedef Anasazi::OperatorTraits<ScalarType,MV,OP>  OpTraits;

  //  Dimension of the matrix
  int nx = 10;        // Discretization points in any one direction.
  int NumGlobalElements = nx*nx;  // Size of matrix nx*nx

  // Construct a Map that puts approximately the same number of
  // equations on each processor.

  Epetra_Map Map(NumGlobalElements, 0, Comm);

  // Get update list and number of local equations from newly created Map.

  int NumMyElements = Map.NumMyElements();

  std::vector<int> MyGlobalElements(NumMyElements);
  Map.MyGlobalElements(&MyGlobalElements[0]);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation
  // on this processor
  std::vector<int> NumNz(NumMyElements);

  /* We are building a matrix of block structure:

      | T -I          |
      |-I  T -I       |
      |   -I  T       |
      |        ...  -I|
      |           -I T|

   where each block is dimension nx by nx and the matrix is on the order of
   nx*nx.  The block T is a tridiagonal matrix.
  */

  for (int i=0; i<NumMyElements; i++) {
    if (MyGlobalElements[i] == 0 || MyGlobalElements[i] == NumGlobalElements-1 ||
        MyGlobalElements[i] == nx-1 || MyGlobalElements[i] == nx*(nx-1) ) {
      NumNz[i] = 3;
    }
    else if (MyGlobalElements[i] < nx || MyGlobalElements[i] > nx*(nx-1) ||
             MyGlobalElements[i]%nx == 0 || (MyGlobalElements[i]+1)%nx == 0) {
      NumNz[i] = 4;
    }
    else {
      NumNz[i] = 5;
    }
  }

  // Create an Epetra_Matrix

  Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, Map, &NumNz[0]) );

  // Diffusion coefficient, can be set by user.
  // When rho*h/2 <= 1, the discrete convection-diffusion operator has real eigenvalues.
  // When rho*h/2 > 1, the operator has complex eigenvalues.
  double rho = 2*(nx+1);

  // Compute coefficients for discrete convection-diffution operator
  const double one = 1.0;
  std::vector<double> Values(4);
  std::vector<int> Indices(4);
  double h = one /(nx+1);
  double h2 = h*h;
  double c = 5.0e-01*rho/ h;
  Values[0] = -one/h2 - c; Values[1] = -one/h2 + c; Values[2] = -one/h2; Values[3]= -one/h2;
  double diag = 4.0 / h2;
  int NumEntries, info;

  for (int i=0; i<NumMyElements; i++)
  {
    if (MyGlobalElements[i]==0)
    {
      Indices[0] = 1;
      Indices[1] = nx;
      NumEntries = 2;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]);
      assert( info==0 );
    }
    else if (MyGlobalElements[i] == nx*(nx-1))
    {
      Indices[0] = nx*(nx-1)+1;
      Indices[1] = nx*(nx-2);
      NumEntries = 2;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]);
      assert( info==0 );
    }
    else if (MyGlobalElements[i] == nx-1)
    {
      Indices[0] = nx-2;
      NumEntries = 1;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
      assert( info==0 );
      Indices[0] = 2*nx-1;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]);
      assert( info==0 );
    }
    else if (MyGlobalElements[i] == NumGlobalElements-1)
    {
      Indices[0] = NumGlobalElements-2;
      NumEntries = 1;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
      assert( info==0 );
      Indices[0] = nx*(nx-1)-1;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]);
      assert( info==0 );
    }
    else if (MyGlobalElements[i] < nx)
    {
      Indices[0] = MyGlobalElements[i]-1;
      Indices[1] = MyGlobalElements[i]+1;
      Indices[2] = MyGlobalElements[i]+nx;
      NumEntries = 3;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
      assert( info==0 );
    }
    else if (MyGlobalElements[i] > nx*(nx-1))
    {
      Indices[0] = MyGlobalElements[i]-1;
      Indices[1] = MyGlobalElements[i]+1;
      Indices[2] = MyGlobalElements[i]-nx;
      NumEntries = 3;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
      assert( info==0 );
    }
    else if (MyGlobalElements[i]%nx == 0)
    {
      Indices[0] = MyGlobalElements[i]+1;
      Indices[1] = MyGlobalElements[i]-nx;
      Indices[2] = MyGlobalElements[i]+nx;
      NumEntries = 3;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]);
      assert( info==0 );
    }
    else if ((MyGlobalElements[i]+1)%nx == 0)
    {
      Indices[0] = MyGlobalElements[i]-nx;
      Indices[1] = MyGlobalElements[i]+nx;
      NumEntries = 2;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]);
      assert( info==0 );
      Indices[0] = MyGlobalElements[i]-1;
      NumEntries = 1;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
      assert( info==0 );
    }
    else
    {
      Indices[0] = MyGlobalElements[i]-1;
      Indices[1] = MyGlobalElements[i]+1;
      Indices[2] = MyGlobalElements[i]-nx;
      Indices[3] = MyGlobalElements[i]+nx;
      NumEntries = 4;
      info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
      assert( info==0 );
    }
    // Put in the diagonal entry
    info = A->InsertGlobalValues(MyGlobalElements[i], 1, &diag, &MyGlobalElements[i]);
    assert( info==0 );
  }

  // Finish up
  info = A->FillComplete();
  assert( info==0 );
  A->SetTracebackMode(1); // Shutdown Epetra Warning tracebacks

  //************************************
  // Start the block Davidson iteration
  //***********************************
  //
  //  Variables used for the Generalized Davidson Method
  //
  int nev = 4;
  int blockSize = 1;
  int maxDim = 50;
  int restartDim = 10;
  int maxRestarts = 500;
  double tol = 1e-10;

  // Set verbosity level
  int verbosity = Anasazi::Errors + Anasazi::Warnings;
  if (verbose) {
    verbosity += Anasazi::FinalSummary + Anasazi::TimingDetails;
  }
  if (debug) {
    verbosity += Anasazi::Debug;
  }
  //
  // Create parameter list to pass into solver manager
  //
  Teuchos::ParameterList MyPL;
  MyPL.set( "Verbosity", verbosity );
  MyPL.set( "Which", which );
  MyPL.set( "Block Size", blockSize );
  MyPL.set( "Maximum Subspace Dimension", maxDim);
  MyPL.set( "Restart Dimension", restartDim);
  MyPL.set( "Maximum Restarts", maxRestarts );
  MyPL.set( "Convergence Tolerance", tol );
  MyPL.set( "Relative Convergence Tolerance", true );
  MyPL.set( "Initial Guess", "User" );

  // Create an Epetra_MultiVector for an initial vector to start the solver.
  // Note:  This needs to have the same number of columns as the blocksize.
  Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(Map, blockSize) );
  ivec->Random();

  // Create the eigenproblem.
  Teuchos::RCP<Anasazi::BasicEigenproblem<double, MV, OP> > MyProblem = Teuchos::rcp(
    new Anasazi::BasicEigenproblem<double,MV,OP>() );
  MyProblem->setA(A);
  MyProblem->setInitVec(ivec);

  // Inform the eigenproblem that the operator A is non-Hermitian
  MyProblem->setHermitian(false);

  // Set the number of eigenvalues requested
  MyProblem->setNEV( nev );

  // Inform the eigenproblem that you are finishing passing it information
  boolret = MyProblem->setProblem();
  if (boolret != true) {
    if (verbose && MyPID == 0) {
      std::cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << std::endl;
    }
#ifdef HAVE_MPI
    MPI_Finalize() ;
#endif
    return -1;
  }

  // Initialize the Block Arnoldi solver
  Anasazi::GeneralizedDavidsonSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL);

  // Solve the problem to the specified tolerances or length
  Anasazi::ReturnType returnCode = MySolverMgr.solve();
  testFailed = false;
  if (returnCode != Anasazi::Converged && MyPID==0 && verbose) {
    testFailed = true;
  }

  // Get the eigenvalues and eigenvectors from the eigenproblem
  Anasazi::Eigensolution<ScalarType,MV> sol = MyProblem->getSolution();
  std::vector<Anasazi::Value<ScalarType> > evals = sol.Evals;
  Teuchos::RCP<MV> evecs = sol.Evecs;
  std::vector<int> index = sol.index;
  int numev = sol.numVecs;

  // Output computed eigenvalues and their direct residuals
  if (verbose && MyPID==0) {
    int numritz = (int)evals.size();
    std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
    std::cout<<std::endl<< "Computed Ritz Values"<< std::endl;
    std::cout<< std::setw(16) << "Real Part"
        << std::setw(16) << "Imag Part"
        << std::endl;
    std::cout<<"-----------------------------------------------------------"<<std::endl;
    for (int i=0; i<numritz; i++) {
      std::cout<< std::setw(16) << evals[i].realpart
          << std::setw(16) << evals[i].imagpart
          << std::endl;
    }
    std::cout<<"-----------------------------------------------------------"<<std::endl;
  }

  if (numev > 0) {
    // Compute residuals.
    Teuchos::LAPACK<int,double> lapack;
    std::vector<double> normA(numev);

    // The problem is non-Hermitian.
    int i=0;
    std::vector<int> curind(1);
    std::vector<double> resnorm(1), tempnrm(1);
    Teuchos::RCP<MV> tempAevec;
    Teuchos::RCP<const MV> evecr, eveci;
    Epetra_MultiVector Aevec(Map,numev);

    // Compute A*evecs
    OpTraits::Apply( *A, *evecs, Aevec );

    Teuchos::SerialDenseMatrix<int,double> Breal(1,1), Bimag(1,1);
    while (i<numev) {
      if (index[i]==0) {
        // Get a view of the current eigenvector (evecr)
        curind[0] = i;
        evecr = MVTraits::CloneView( *evecs, curind );

        // Get a copy of A*evecr
        tempAevec = MVTraits::CloneCopy( Aevec, curind );

        // Compute A*evecr - lambda*evecr
        Breal(0,0) = evals[i].realpart;
        MVTraits::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec );

        // Compute the norm of the residual and increment counter
        MVTraits::MvNorm( *tempAevec, resnorm );
        normA[i] = resnorm[0] / Teuchos::ScalarTraits<MagnitudeType>::magnitude( evals[i].realpart );
        i++;
      } else {
        // Get a view of the real part of the eigenvector (evecr)
        curind[0] = i;
        evecr = MVTraits::CloneView( *evecs, curind );

        // Get a copy of A*evecr
        tempAevec = MVTraits::CloneCopy( Aevec, curind );

        // Get a view of the imaginary part of the eigenvector (eveci)
        curind[0] = i+1;
        eveci = MVTraits::CloneView( *evecs, curind );

        // Set the eigenvalue into Breal and Bimag
        Breal(0,0) = evals[i].realpart;
        Bimag(0,0) = evals[i].imagpart;

        // Compute A*evecr - evecr*lambdar + eveci*lambdai
        MVTraits::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec );
        MVTraits::MvTimesMatAddMv( 1.0, *eveci, Bimag, 1.0, *tempAevec );
        MVTraits::MvNorm( *tempAevec, tempnrm );

        // Get a copy of A*eveci
        tempAevec = MVTraits::CloneCopy( Aevec, curind );

        // Compute A*eveci - eveci*lambdar - evecr*lambdai
        MVTraits::MvTimesMatAddMv( -1.0, *evecr, Bimag, 1.0, *tempAevec );
        MVTraits::MvTimesMatAddMv( -1.0, *eveci, Breal, 1.0, *tempAevec );
        MVTraits::MvNorm( *tempAevec, resnorm );

        // Compute the norms and scale by magnitude of eigenvalue
        normA[i] = lapack.LAPY2( tempnrm[0], resnorm[0] ) /
          lapack.LAPY2( evals[i].realpart, evals[i].imagpart );
        normA[i+1] = normA[i];

        i=i+2;
      }
    }

    // Output computed eigenvalues and their direct residuals
    if (verbose && MyPID==0) {
      std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
      std::cout<<std::endl<< "Actual Residuals"<<std::endl;
      std::cout<< std::setw(16) << "Real Part"
          << std::setw(16) << "Imag Part"
          << std::setw(20) << "Direct Residual"<< std::endl;
      std::cout<<"-----------------------------------------------------------"<<std::endl;
      for (int j=0; j<numev; j++) {
        std::cout<< std::setw(16) << evals[j].realpart
            << std::setw(16) << evals[j].imagpart
            << std::setw(20) << normA[j] << std::endl;
        if ( normA[j] > tol ) {
          testFailed = true;
        }
      }
      std::cout<<"-----------------------------------------------------------"<<std::endl;
    }
  }

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  if (testFailed) {
    if (verbose && MyPID==0) {
      std::cout << "End Result: TEST FAILED" << std::endl;
    }
    return -1;
  }
  //
  // Default return value
  //
  if (verbose && MyPID==0) {
    std::cout << "End Result: TEST PASSED" << std::endl;
  }

  return 0;
}
    std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> >
    TriDiag_Helmholtz_Pair(const Teuchos::RCP<const Map> & map, const GlobalOrdinal nx,
                           const double h, const double omega, const Scalar shift) {

      Teuchos::RCP<Matrix> ktx = MatrixTraits<Map,Matrix>::Build(map, 3);
      Teuchos::RCP<Matrix> mtx = MatrixTraits<Map,Matrix>::Build(map, 1);
      LocalOrdinal NumMyElements = map->getNodeNumElements();
      Teuchos::ArrayView<const GlobalOrdinal> MyGlobalElements = map->getNodeElementList();
      Teuchos::RCP<const Teuchos::Comm<int> > comm = map->getComm();
      GlobalOrdinal NumGlobalElements = map->getGlobalNumElements();
      GlobalOrdinal NumEntries;
      LocalOrdinal nnz=2;
      std::vector<Scalar> Values(nnz);
      std::vector<GlobalOrdinal> Indices(nnz);
      Scalar one = (Scalar) 1.0;
      comm->barrier();
      if (comm->getRank() == 0) {
        std::cout << "starting global insert" << std::endl;
      }
      Teuchos::RCP<Teuchos::Time> timer = rcp(new Teuchos::Time("TriDiag global insert"));
      timer->start(true);
      for (LocalOrdinal i = 0; i < NumMyElements; ++i) {
        if (MyGlobalElements[i] == 0) {
          // off-diagonal for first row
          Indices[0] = 1;
          NumEntries = 1;
          Values[0] = -one;
        }
        else if (MyGlobalElements[i] == NumGlobalElements - 1) {
          // off-diagonal for last row
          Indices[0] = NumGlobalElements - 2;
          NumEntries = 1;
          Values[0] = -one;
        }
        else {
          // off-diagonal for internal row
          Indices[0] = MyGlobalElements[i] - 1;
          Indices[1] = MyGlobalElements[i] + 1;
          Values[0] = -one;
          Values[1] = -one;
          NumEntries = 2;
        }
        // put the off-diagonal entries
        // Xpetra wants ArrayViews (sigh)
        Teuchos::ArrayView<Scalar> av(&Values[0],NumEntries);
        Teuchos::ArrayView<GlobalOrdinal> iv(&Indices[0],NumEntries);
        ktx->insertGlobalValues(MyGlobalElements[i], iv, av);
        // Put in the diagonal entry
        mtx->insertGlobalValues(MyGlobalElements[i],
                                Teuchos::tuple<GlobalOrdinal>(MyGlobalElements[i]),
                                Teuchos::tuple<Scalar>(h*h) );
      }
      timer->stop();
      timer = rcp(new Teuchos::Time("TriDiag fillComplete"));
      timer->start(true);
      ktx->fillComplete();
      mtx->fillComplete();
      timer->stop();
      std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> > system;
      system=std::make_pair(ktx,mtx);
      return system;

    } //TriDiag_Helmholtz
//==============================================================================
int Ifpack_GreedyPartitioner::ComputePartitions()
{
  std::vector<int> ElementsPerPart(NumLocalParts());
  std::vector<int> Count(NumLocalParts());
  for (int i = 0 ; i < NumLocalParts() ; ++i)
    Count[i] = 0;

  // define how many nodes have to be put on each part
  int div = NumMyRows() / NumLocalParts();
  int mod = NumMyRows() % NumLocalParts();

  for (int i = 0 ; i < NumLocalParts() ; ++i) {
    Count[i] = 0;
    ElementsPerPart[i] = div;
    if (i < mod) ElementsPerPart[i]++;
  }

  for( int i=0 ; i<NumMyRows() ; ++i ) {
    Partition_[i] = -1;
  }

  int NumEntries;
  std::vector<int> Indices(MaxNumEntries());
  
  // load root node for partition 0
  int CurrentPartition = 0;
  int TotalCount = 0;

  // filter singletons and empty rows, put all of them in partition 0
  for (int i = 0 ; i < NumMyRows() ; ++i) {
    NumEntries = 0;
    int ierr = Graph_->ExtractMyRowCopy(i, MaxNumEntries(),
                                        NumEntries, &Indices[0]);
    IFPACK_CHK_ERR(ierr);
    if (NumEntries <= 1) {
      Partition_[i] = 0;
      TotalCount++;
    }
  }

  if (TotalCount)
    CurrentPartition = 1;

  std::vector<int> ThisLevel(1);
  ThisLevel[0] = RootNode_;

  // be sure that RootNode is not a singleton or empty row
  if (Partition_[RootNode_] != -1) {
    // look for another RN
    for (int i = 0 ; i < NumMyRows() ; ++i)
      if (Partition_[i] == -1) {
        ThisLevel[0] = i;
        break;
      }
  }
  else {
    Partition_[RootNode_] = CurrentPartition;
  }

  // now aggregate the non-empty and non-singleton rows
  while (ThisLevel.size()) {

    std::vector<int> NextLevel;

    for (unsigned int i = 0 ; i < ThisLevel.size() ; ++i) {

      int CurrentNode = ThisLevel[i];
      int ierr = Graph_->ExtractMyRowCopy(CurrentNode, MaxNumEntries(),
                                          NumEntries, &Indices[0]);
      IFPACK_CHK_ERR(ierr);

      if (NumEntries <= 1)
        continue;

      for (int j = 0 ; j < NumEntries ; ++j) {

        int NextNode = Indices[j];
        if (NextNode >= NumMyRows()) continue;

        if (Partition_[NextNode] == -1) {
          // this is a free node
          NumLocalParts_ = CurrentPartition + 1;
          Partition_[NextNode] = CurrentPartition;
          ++Count[CurrentPartition];
          ++TotalCount;
          NextLevel.push_back(NextNode);
        }
      }
    } // for (i)

    // check whether change partition or not
    if (Count[CurrentPartition] >= ElementsPerPart[CurrentPartition])
      ++CurrentPartition;

    // swap next and this
    ThisLevel.resize(0);
    for (unsigned int i = 0 ; i < NextLevel.size() ; ++i)
      ThisLevel.push_back(NextLevel[i]);

    if (ThisLevel.size() == 0 && (TotalCount != NumMyRows())) {
      // need to look for new RootNode, do this in a simple way
      for (int i = 0 ; i < NumMyRows() ; i++) {
        if (Partition_[i] == -1)
          ThisLevel.push_back(i);
        break;
      }
    }

  } // while (ok)

  return(0);
}
    std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> >
    Cross2D_Helmholtz_Pair(const Teuchos::RCP<const Map> & map,
                           const GlobalOrdinal nx,      const GlobalOrdinal ny,
                           const double h,              const double delta,
                           const int PMLgridptsx_left,  const int PMLgridptsx_right,
                           const int PMLgridptsy_left,  const int PMLgridptsy_right,
                           const double omega,          const Scalar shift,
			   const int model) {

      Teuchos::RCP<Matrix> ktx = MatrixTraits<Map,Matrix>::Build(map, 5);
      Teuchos::RCP<Matrix> mtx = MatrixTraits<Map,Matrix>::Build(map, 1);
      LocalOrdinal NumMyElements = map->getNodeNumElements();
      Teuchos::ArrayView<const GlobalOrdinal> MyGlobalElements = map->getNodeElementList();
      GlobalOrdinal left, right, lower, upper, center;
      LocalOrdinal nnz=5;
      std::vector<Scalar> Values(nnz);
      std::vector<GlobalOrdinal> Indices(nnz);
      VelocityModel<Scalar,LocalOrdinal,GlobalOrdinal> velocitymodel(2,model);

      double LBx, RBx, LBy, RBy, Dx, Dy;
      Scalar sx_left, sx_center, sx_right;
      Scalar sy_left, sy_center, sy_right;
      Scalar c;
      // Calculate some parameters
      Dx = ((double) nx-1)*h;
      Dy = ((double) ny-1)*h;
      LBx = ((double) PMLgridptsx_left)*h;
      RBx = Dx-((double) PMLgridptsx_right)*h;
      LBy = ((double) PMLgridptsy_left)*h;
      RBy = Dy-((double) PMLgridptsy_right)*h;

      for (LocalOrdinal i = 0; i < NumMyElements; ++i)  {

	// calculate PML functions
        size_t numEntries = 0;
        center = MyGlobalElements[i];
        GetNeighboursCartesian2d(center, nx, ny, left, right, lower, upper);
        GetPMLvalues(center, nx, ny, h, delta,
                     Dx, Dy, LBx, RBx, LBy, RBy,
                     sx_left, sx_center, sx_right,
                     sy_left, sy_center, sy_right);
	// get velocity
	GlobalOrdinal ix, iy;
	ix = i % nx;
	iy = (i - ix) / nx;
	double xcoord, ycoord;
	xcoord=((double) ix)*h;
	ycoord=((double) iy)*h;
	c = velocitymodel.getVelocity(xcoord,ycoord,0.0);

        if (left != -1) {
          Indices[numEntries] = left;
          Values [numEntries] = -(sy_center/sx_center + sy_center/sx_left)/2.0;
          numEntries++;
        }
        if (right != -1) {
          Indices[numEntries] = right;
          Values [numEntries] = -(sy_center/sx_center + sy_center/sx_right)/2.0;
          numEntries++;
        }
        if (lower != -1) {
          Indices[numEntries] = lower;
          Values [numEntries] = -(sx_center/sy_center + sx_center/sy_left)/2.0;
          numEntries++;
        }
        if (upper != -1) {
          Indices[numEntries] = upper;
          Values [numEntries] = -(sx_center/sy_center + sx_center/sy_right)/2.0;
          numEntries++;
        }

        // diagonal
        Scalar z = (Scalar) 0.0;
        for (size_t j = 0; j < numEntries; j++)
          z -= Values[j];

        Indices[numEntries] = center;
        Values [numEntries] = z;
        numEntries++;

        Teuchos::ArrayView<GlobalOrdinal> iv(&Indices[0], numEntries);
        Teuchos::ArrayView<Scalar>        av(&Values[0],  numEntries);
        ktx->insertGlobalValues(center, iv, av);
        mtx->insertGlobalValues(center,
                                Teuchos::tuple<GlobalOrdinal>(center),
                                Teuchos::tuple<Scalar>(h*h*sx_center*sy_center/(c*c)) );

      }

      ktx->fillComplete();
      mtx->fillComplete();
      std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> > system;
      system=std::make_pair(ktx,mtx);
      return system;

    } //Cross2D_Helmholtz
Esempio n. 29
0
int main(int argc, char *argv[])
{
    int ierr = 0, i, forierr = 0;
#ifdef EPETRA_MPI

    // Initialize MPI

    MPI_Init(&argc,&argv);
    int rank; // My process ID

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

    int rank = 0;
    Epetra_SerialComm Comm;

#endif

    bool verbose = false;

    // Check if we should print results to standard out
    if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

    int verbose_int = verbose ? 1 : 0;
    Comm.Broadcast(&verbose_int, 1, 0);
    verbose = verbose_int==1 ? true : false;


    //  char tmp;
    //  if (rank==0) cout << "Press any key to continue..."<< endl;
    //  if (rank==0) cin >> tmp;
    //  Comm.Barrier();

    Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
    int MyPID = Comm.MyPID();
    int NumProc = Comm.NumProc();

    if(verbose && MyPID==0)
        cout << Epetra_Version() << endl << endl;

    if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
                          << " is alive."<<endl;

    // Redefine verbose to only print on PE 0
    if(verbose && rank!=0)
        verbose = false;

    int NumMyEquations = 10000;
    int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3);
    if(MyPID < 3)
        NumMyEquations++;

    // Construct a Map that puts approximately the same Number of equations on each processor

    Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm);

    // Get update list and number of local equations from newly created Map
    vector<int> MyGlobalElements(Map.NumMyElements());
    Map.MyGlobalElements(&MyGlobalElements[0]);

    // Create an integer vector NumNz that is used to build the Petra Matrix.
    // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

    vector<int> NumNz(NumMyEquations);

    // We are building a tridiagonal matrix where each row has (-1 2 -1)
    // So we need 2 off-diagonal terms (except for the first and last equation)

    for(i = 0; i < NumMyEquations; i++)
        if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1))
            NumNz[i] = 1;
        else
            NumNz[i] = 2;

    // Create a Epetra_Matrix

    Epetra_CrsMatrix A(Copy, Map, &NumNz[0]);
    EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr);
    EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr);

    // Add  rows one-at-a-time
    // Need some vectors to help
    // Off diagonal Values will always be -1


    vector<double> Values(2);
    Values[0] = -1.0;
    Values[1] = -1.0;
    vector<int> Indices(2);
    double two = 2.0;
    int NumEntries;

    forierr = 0;
    for(i = 0; i < NumMyEquations; i++) {
        if(MyGlobalElements[i] == 0) {
            Indices[0] = 1;
            NumEntries = 1;
        }
        else if (MyGlobalElements[i] == NumGlobalEquations-1) {
            Indices[0] = NumGlobalEquations-2;
            NumEntries = 1;
        }
        else {
            Indices[0] = MyGlobalElements[i]-1;
            Indices[1] = MyGlobalElements[i]+1;
            NumEntries = 2;
        }
        forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0);
        forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry
    }
    EPETRA_TEST_ERR(forierr,ierr);

    // Finish up
    A.FillComplete();
    A.OptimizeStorage();

    Epetra_JadMatrix JadA(A);
    Epetra_JadMatrix JadA1(A);
    Epetra_JadMatrix JadA2(A);

    // Create vectors for Power method

    Epetra_Vector q(Map);
    Epetra_Vector z(Map);
    z.Random();
    Epetra_Vector resid(Map);

    Epetra_Flops flopcounter;
    A.SetFlopCounter(flopcounter);
    q.SetFlopCounter(A);
    z.SetFlopCounter(A);
    resid.SetFlopCounter(A);
    JadA.SetFlopCounter(A);
    JadA1.SetFlopCounter(A);
    JadA2.SetFlopCounter(A);


    if (verbose) cout << "=======================================" << endl
                          << "Testing Jad using CrsMatrix as input..." << endl
                          << "=======================================" << endl;

    A.ResetFlops();
    powerMethodTests(A, JadA, Map, q, z, resid, verbose);

    // Increase diagonal dominance

    if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n"
                          << endl;


    if (A.MyGlobalRow(0)) {
        int numvals = A.NumGlobalEntries(0);
        vector<double> Rowvals(numvals);
        vector<int> Rowinds(numvals);
        A.ExtractGlobalRowCopy(0, numvals, numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0]

        for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0;

        A.ReplaceGlobalValues(0, numvals, &Rowvals[0], &Rowinds[0]);
    }
    JadA.UpdateValues(A);
    A.ResetFlops();
    powerMethodTests(A, JadA, Map, q, z, resid, verbose);

    if (verbose) cout << "================================================================" << endl
                          << "Testing Jad using Jad matrix as input matrix for construction..." << endl
                          << "================================================================" << endl;
    JadA1.ResetFlops();
    powerMethodTests(JadA1, JadA2, Map, q, z, resid, verbose);

#ifdef EPETRA_MPI
    MPI_Finalize() ;
#endif

    return ierr ;
}
Esempio n. 30
0
void BaseMesh::CreateSphere(float radius, int slices, int stacks)
{
    Allocate(slices * (stacks - 1) + 2,slices * 2 * (stacks - 1));    //allocate space for the angular splits

    float PI_Stacks = Math::PIf / float(stacks);
    float PI2_Slices = 2.0f * Math::PIf / float(slices);

    float Theta, Phi,CosP,SinP;
    int i,i2,vc=0,ic=0;
    MeshVertex *V = Vertices();
    DWORD *I = Indices();
    MeshVertex MVtx(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    for(i=1;i < stacks;i++)
    {
        Phi = float(i) * PI_Stacks;
        CosP = cosf(Phi);
        SinP = sinf(Phi);

        for(i2=0;i2 < slices;i2++)
        {
            Theta = float(i2) * PI2_Slices;
            MVtx.Pos = Vec3f(radius * cosf(Theta) * SinP, radius * sinf(Theta) * SinP, radius * CosP);    //create the new vertex
            V[vc++] = MVtx;    //add the vertex to the mesh
        }
    }

    //add the top and bottom vertices to the mesh
    int TopVertex = vc,BottomVertex = vc+1;
    MVtx.Pos = Vec3f(0.0f,0.0f,radius);
    V[vc++] = MVtx;
    MVtx.Pos = Vec3f(0.0f,0.0f,-radius);
    V[vc++] = MVtx;

    //add the top and bottom triangles (all triangles involving the TopVertex and BottomVertex)
    int ip1,i2p1;
    for(i=0;i < slices;i++)
    {
        ip1 = i + 1;
        if(ip1 == slices) ip1 = 0;

        I[ic++] = i;
        I[ic++] = TopVertex;                    //top triangle
        I[ic++] = ip1;
        
        I[ic++] = ip1 + (stacks - 2) * slices;
        I[ic++] = BottomVertex;                    //bottom triangle
        I[ic++] = i + (stacks - 2) * slices;
    }

    //add all the remaining triangles
    for(i=0;i < stacks - 2;i++)
    {
        for(i2=0;i2 < slices;i2++)
        {
            i2p1 = i2 + 1;
            if(i2p1 == slices) i2p1 = 0;
            
            I[ic++] = (i+1) * slices + i2;
            I[ic++] = i * slices + i2;
            I[ic++] = i * slices + i2p1;

            
            I[ic++] = (i+1) * slices + i2;
            I[ic++] = i * slices + i2p1;
            I[ic++] = (i+1) * slices + i2p1;
        }
    }

    GenerateNormals();
}