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++; } }
decltype(auto) a2t(const std::array<T, N>& a) { return a2t_impl(a, Indices()); }
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 ); }
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 ); }
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)); }
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; }
//============================================================================== 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); }
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(); }
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]; } }
Vect<float &> a2v(std::array<T, N>& a, int j) { return a2v_impl(a, j, Indices()); }
// ====================================================================== 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); }
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
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; }
UINT64 BaseMesh::Hash64() const { return Utility::Hash64((const BYTE *)Vertices(), VertexCount() * sizeof(MeshVertex)) + Utility::Hash64((const BYTE *)Indices(), IndexCount() * sizeof(DWORD)); }
// 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; }
// ============================================================================ 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; }
//========================================================================== 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); }
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()
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); }
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
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 ; }
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(); }