int main(int argc,char **argv) { #ifdef CH_MPI MPI_Init(&argc, &argv); #endif // registerDebugger(); // begin forever present scoping trick { pout()<<std::endl; Vector<std::string> names0(1, "phi"); Vector<int> refRatio(3,2); Vector<Real> coveredVal(1,3.0); const char* in_file = "sphere.inputs"; // read in an input file or use default file // if (argc > 1) // { // in_file = argv[1]; // } //parse input file ParmParse pp(0,NULL,NULL,in_file); RealVect center; Real radius; RealVect origin; RealVect dx; Box domain; ProblemDomain pDomain(domain); int eekflag = 0; LevelData<EBCellFAB> fine, med, coarse; LevelData<EBCellFAB> fineRHS, medRHS, coarseRHS; LevelData<EBCellFAB> fineResidual, mediumResidual, coarseResidual; Vector<LevelData<EBCellFAB>* > ebvector(3,NULL); Vector<LevelData<EBCellFAB>* > vresidual(3,NULL); Vector<LevelData<EBCellFAB>* > rhsvector(3,NULL); ebvector[0]=&coarse; ebvector[1]=&med; ebvector[2]=&fine; vresidual[0]=&coarseResidual; vresidual[1]=&mediumResidual; vresidual[2]=&fineResidual; rhsvector[0] = &coarseRHS; rhsvector[1] = &medRHS; rhsvector[2] = &fineRHS; readGeometryInfo(domain, dx, origin, center, radius); Box domainFine(domain), domainMedi, domainCoar; ProblemDomain pFine(domain); RealVect dxFine(dx), dxMedi, dxCoar; CH_assert(eekflag == 0); domainMedi = coarsen(domainFine, 2); domainCoar = coarsen(domainMedi, 2); dxMedi = 2.0*dxFine; dxCoar = 2.0*dxMedi; Vector<RealVect> xVec(3, IntVect::Unit); xVec[0]*= dxCoar; xVec[1]*= dxMedi; xVec[2]*= dxFine; Vector<DisjointBoxLayout> grids(3); ProblemDomain baseDomain(domainCoar); ProblemDomain pMed(domainMedi); Vector<ProblemDomain> pd(3); pd[0] = baseDomain; pd[1] = pMed; pd[2] = ProblemDomain(domainFine); RefCountedPtr<BaseBCValue>value(new DirichletBC()); DirichletPoissonDomainBC* domainBC = new DirichletPoissonDomainBC(); domainBC->setFunction(value); RefCountedPtr<BaseDomainBC> bc(domainBC); //make data holders Vector<int> comps(2,1); int steps= 5; int step = 0; while (step < steps) { eekflag = makeGeometry( domain, dx, origin, center, radius); //make grids //IntVectSet tags = mfIndexSpace->interfaceRegion(2); IntVectSet tags(domainCoar); tags.grow(1); makeHierarchy(grids, baseDomain, tags); const CH_XD::EBIndexSpace* ebisPtr = Chombo_EBIS::instance(); Vector<EBISLayout> layouts(3); EBISLayout& fineLayout = layouts[2]; ebisPtr->fillEBISLayout(fineLayout, grids[2], domainFine, 2); EBCellFactory fineFactory(fineLayout); ebvector[2]->define(grids[2], 1, IntVect::Unit, fineFactory); rhsvector[2]->define(grids[2], 1, IntVect::Zero, fineFactory); EBISLayout& medLayout = layouts[1]; ebisPtr->fillEBISLayout(medLayout, grids[1], domainMedi, 2); EBCellFactory medFactory(medLayout); ebvector[1]->define(grids[1], 1, IntVect::Unit, medFactory); rhsvector[1]->define(grids[1], 1, IntVect::Zero, medFactory); EBISLayout& coarseLayout = layouts[0]; ebisPtr->fillEBISLayout(coarseLayout, grids[0], domainCoar, 2); EBCellFactory coarseFactory(coarseLayout); ebvector[0]->define(grids[0], 1, IntVect::Unit, coarseFactory); rhsvector[0]->define(grids[0], 1, IntVect::Zero, coarseFactory); for (int lev=0; lev<3; lev++) { setValue(*rhsvector[lev], RHS(), pd[lev].domainBox(), xVec[lev], origin, true); } Vector<int> refRatio(3,2); int max_iter = 40; pp.get("max_iter", max_iter); Real eps = 1.e-6; pp.get("eps", eps); int relaxType; pp.get("relaxType",relaxType); DirichletPoissonDomainBCFactory* domDirBC = new DirichletPoissonDomainBCFactory(); domDirBC->setFunction(value); RefCountedPtr<BaseDomainBCFactory> domBC( domDirBC ); DirichletPoissonEBBCFactory* ebDirBC = new DirichletPoissonEBBCFactory(); ebDirBC->setFunction(value); RefCountedPtr<BaseEBBCFactory> ebBC( ebDirBC ); Vector<EBLevelGrid> eblgs(3); Vector<RefCountedPtr<EBQuadCFInterp> > quadCFI(3, RefCountedPtr<EBQuadCFInterp>()); for (int i=0; i<3; i++) { eblgs[i] = EBLevelGrid(grids[i], layouts[i], pd[i]); if (i > 0) { quadCFI[i] = RefCountedPtr<EBQuadCFInterp>( new EBQuadCFInterp(grids[i], grids[i-1], layouts[i], layouts[i-1], pd[i-1], refRatio[i-1], 1, *eblgs[i].getCFIVS())); } } EBAMRPoissonOpFactory opFact(eblgs, refRatio, quadCFI, xVec[0], RealVect::Zero, 4, relaxType, domBC, ebBC, 0.0, 1.0, 0.0, IntVect::Unit, IntVect::Zero); for (int i=0; i<3; i++) { LevelData<EBCellFAB> &phi=*ebvector[i], &rhs=*rhsvector[i], &residual=*vresidual[i]; LevelData<EBCellFAB> correction; DisjointBoxLayout dblMGCoar; EBISLayout ebislMGCoar; EBAMRPoissonOp* opPtr = opFact.AMRnewOp(pd[i]); EBAMRPoissonOp& op = *opPtr; RelaxSolver<LevelData<EBCellFAB> > solver; solver.define(&op, false); solver.m_imax = max_iter; solver.m_eps = eps; op.create(residual, rhs); op.create(correction, phi); op.setToZero(residual); op.setToZero(phi); op.residual(residual, phi, rhs); Real r2norm = op.norm(residual, 2); Real r0norm = op.norm(residual, 0); pout()<<indent<<"Residual L2 norm "<<r2norm<<"Residual max norm = " <<r0norm<<std::endl; solver.solve(phi, rhs); op.residual(residual, phi, rhs); r2norm = op.norm(residual, 2); r0norm = op.norm(residual, 0); pout()<<indent2<<"Residual L2 norm "<<r2norm<<" Residual max norm = " <<r0norm<<std::endl; delete opPtr; } #ifdef CH_USE_HDF5 sprintf(iter_str, "residual.%03d.%dd.hdf5",step, SpaceDim); Vector<std::string> names(1); names[0]="residual"; writeEBHDF5(iter_str, grids, vresidual, names, domainCoar, dxCoar[0], 1, step, refRatio, 3, true, coveredVal); sprintf(iter_str, "phi.%03d.%dd.hdf5",step, SpaceDim); names[0]="phi"; writeEBHDF5(iter_str, grids, ebvector ,names, domainCoar, dxCoar[0], 1, step, refRatio, 3, true, coveredVal); #endif step++; center[0]-= dx[0]/3.0; center[1]-= dx[1]/2.0; radius += dx[0]/6.0; Chombo_EBIS::instance()->clear(); pout()<<step<<std::endl; } pout() <<"\n "<<indent2<<pgmname<<" test passed " << endl; } // end scoping trick #ifdef CH_MPI MPI_Finalize(); #endif 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 Teuchos::ParameterList GaleriList; // The problem is defined on a 2D grid, global size is nx * nx. int nx = 30; GaleriList.set("n", nx * nx); GaleriList.set("nx", nx); GaleriList.set("ny", nx); Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap("Linear", Comm, GaleriList) ); Teuchos::RefCountPtr<Epetra_RowMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) ); // =============================================================== // // B E G I N N I N G O F I F P A C K C O N S T R U C T I O N // // =============================================================== // Teuchos::ParameterList List; // allocates an IFPACK factory. No data is associated // to this object (only method Create()). Ifpack Factory; // create the preconditioner. For valid PrecType values, // please check the documentation string PrecType = "ILU"; // incomplete LU int OverlapLevel = 1; // must be >= 0. If Comm.NumProc() == 1, // it is ignored. Teuchos::RefCountPtr<Ifpack_Preconditioner> Prec = Teuchos::rcp( Factory.Create(PrecType, &*A, OverlapLevel) ); assert(Prec != Teuchos::null); // specify parameters for ILU List.set("fact: drop tolerance", 1e-9); List.set("fact: level-of-fill", 1); // the combine mode is on the following: // "Add", "Zero", "Insert", "InsertAdd", "Average", "AbsMax" // Their meaning is as defined in file Epetra_CombineMode.h List.set("schwarz: combine mode", "Add"); // sets the parameters IFPACK_CHK_ERR(Prec->SetParameters(List)); // initialize the preconditioner. At this point the matrix must // have been FillComplete()'d, but actual values are ignored. IFPACK_CHK_ERR(Prec->Initialize()); // Builds the preconditioners, by looking for the values of // the matrix. IFPACK_CHK_ERR(Prec->Compute()); // =================================================== // // E N D O F I F P A C K C O N S T R U C T I O N // // =================================================== // // At this point, we need some additional objects // to define and solve the linear system. // defines LHS and RHS Epetra_Vector LHS(A->OperatorDomainMap()); Epetra_Vector RHS(A->OperatorDomainMap()); // solution is constant LHS.PutScalar(1.0); // now build corresponding RHS A->Apply(LHS,RHS); // now randomize the solution RHS.Random(); // need an Epetra_LinearProblem to define AztecOO solver Epetra_LinearProblem Problem(&*A,&LHS,&RHS); // now we can allocate the AztecOO solver AztecOO Solver(Problem); // specify solver Solver.SetAztecOption(AZ_solver,AZ_gmres); Solver.SetAztecOption(AZ_output,32); // HERE WE SET THE IFPACK PRECONDITIONER Solver.SetPrecOperator(&*Prec); // .. and here we solve Solver.Iterate(1550,1e-8); cout << *Prec; #ifdef HAVE_MPI MPI_Finalize() ; #endif return(EXIT_SUCCESS); }
// ====================================================================== bool KrylovTest(std::string PrecType, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A, bool backward, bool reorder=false) { Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); // Set up the list Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: type", PrecType); if(backward) List.set("relaxation: backward mode",backward); // Reordering if needed int NumRows=A->NumMyRows(); std::vector<int> RowList(NumRows); if(reorder) { for(int i=0; i<NumRows; i++) RowList[i]=i; List.set("relaxation: number of local smoothing indices",NumRows); List.set("relaxation: local smoothing indices",RowList.size()>0? &RowList[0] : (int*)0); } int Iters1, Iters10; if (verbose) { cout << "Krylov test: Using " << PrecType << " with AztecOO" << endl; } // ============================================== // // get the number of iterations with 1 sweep only // // ============================================== // { List.set("relaxation: sweeps",1); Ifpack_PointRelaxation Point(&*A); Point.SetParameters(List); Point.Compute(); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Point); AztecOOSolver.Iterate(2550,1e-5); double TrueResidual = AztecOOSolver.TrueResidual(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Norm of the true residual = " << TrueResidual << endl; } Iters1 = AztecOOSolver.NumIters(); } // ======================================================== // // now re-run with 10 sweeps, solver should converge faster // ======================================================== // { List.set("relaxation: sweeps",10); Ifpack_PointRelaxation Point(&*A); Point.SetParameters(List); Point.Compute(); LHS.PutScalar(0.0); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Point); AztecOOSolver.Iterate(2550,1e-5); double TrueResidual = AztecOOSolver.TrueResidual(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Norm of the true residual = " << TrueResidual << endl; } Iters10 = AztecOOSolver.NumIters(); } if (verbose) { cout << "Iters_1 = " << Iters1 << ", Iters_10 = " << Iters10 << endl; cout << "(second number should be smaller than first one)" << endl; } if (Iters10 > Iters1) { if (verbose) cout << "KrylovTest TEST FAILED!" << endl; return(false); } else { if (verbose) cout << "KrylovTest TEST PASSED" << endl; return(true); } }
inline RHS& operator()(const LHS &name) { return insert(name, RHS()); }
double *rk4vec (double t0, int m, double u0[], double dt, double *RHS ( double t, int m, double[] )) /*************************************************************************************************** Description: This function uses rk4 to calculate the ODE for the three body problem. Input: t0 : The initial time value. m : The dimension of the array of values being solved. u0[] : The array of initial values. dt : The desired time step. RHS(double t, int m, double[] ) : Function that calculates the right hand side of the ODE function. Output: u : Pointer to array of current values for the ODE. ***************************************************************************************************/ { double *f0; double *f1; double *f2; double *f3; int i; double t1; double t2; double t3; double *u; double *u1; double *u2; double *u3; /******************************************************** Get sample derivatives. *********************************************************/ f0 = RHS(t0, m, u0); t1 = t0 + dt / 2.0; u1 = (double *) malloc( m * sizeof(double)); for ( i = 0; i < m; i++) { u1[i] = u0[i] + dt * f0[i] / 2.0; } f1 = RHS(t1, m, u1); t2 = t0 + dt / 2.0; u2 = (double *) malloc( m * sizeof(double)); for (i = 0; i < m; i++) { u2[i] = u0[i] + dt*f1[i] / 2.0; } f2 = RHS(t2, m, u2); t3 = t0 + dt; u3 = (double *) malloc(m * sizeof(double)); for ( i = 0; i < m; i++) { u3[i] = u0[i] + dt * f2[i]; } f3 = RHS( t3, m, u3); /********************************************************* Combine them to get estimate solution. **********************************************************/ u = (double*) malloc(m *sizeof(double)); for (i =0; i < m; i++) { u[i] = u0[i] + dt * (f0[i] + 2.0 * f1[i] + 2.0 * f2[i] + f3[i] )/6.0; } /******************************************************** Free memmory. **********************************************************/ free ( f0 ); free ( f1 ); free ( f2 ); free ( f3 ); free ( u1 ); free ( u2 ); free ( u3 ); return u; }
int main(int argc, char *argv[]) { // initialize MPI and Epetra communicator #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif Teuchos::ParameterList GaleriList; // The problem is defined on a 2D grid, global size is nx * nx. int nx = 30; GaleriList.set("nx", nx); GaleriList.set("ny", nx * Comm.NumProc()); GaleriList.set("mx", 1); GaleriList.set("my", Comm.NumProc()); Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap64("Cartesian2D", Comm, GaleriList) ); Teuchos::RefCountPtr<Epetra_RowMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) ); // =============================================================== // // B E G I N N I N G O F I F P A C K C O N S T R U C T I O N // // =============================================================== // Teuchos::ParameterList List; // builds an Ifpack_AdditiveSchwarz. This is templated with // the local solvers, in this case Ifpack_ICT. Note that any // other Ifpack_Preconditioner-derived class can be used // instead of Ifpack_ICT. // In this example the overlap is zero. Use // Prec(A,OverlapLevel) for the general case. Ifpack_AdditiveSchwarz<Ifpack_ICT> Prec(&*A); // `1.0' means that the factorization should approximatively // keep the same number of nonzeros per row of the original matrix. List.set("fact: ict level-of-fill", 1.0); // no modifications on the diagonal List.set("fact: absolute threshold", 0.0); List.set("fact: relative threshold", 1.0); List.set("fact: relaxation value", 0.0); // matrix `laplace_2d_bc' is not symmetric because of the way // boundary conditions are imposed. We can filter the singletons, // (that is, Dirichlet nodes) and end up with a symmetric // matrix (as ICT requires). List.set("schwarz: filter singletons", true); // sets the parameters IFPACK_CHK_ERR(Prec.SetParameters(List)); // initialize the preconditioner. At this point the matrix must // have been FillComplete()'d, but actual values are ignored. IFPACK_CHK_ERR(Prec.Initialize()); // Builds the preconditioners, by looking for the values of // the matrix. IFPACK_CHK_ERR(Prec.Compute()); // =================================================== // // E N D O F I F P A C K C O N S T R U C T I O N // // =================================================== // // At this point, we need some additional objects // to define and solve the linear system. // defines LHS and RHS Epetra_Vector LHS(A->OperatorDomainMap()); Epetra_Vector RHS(A->OperatorDomainMap()); LHS.PutScalar(0.0); RHS.Random(); // need an Epetra_LinearProblem to define AztecOO solver Epetra_LinearProblem Problem(&*A,&LHS,&RHS); // now we can allocate the AztecOO solver AztecOO Solver(Problem); // specify solver Solver.SetAztecOption(AZ_solver,AZ_cg_condnum); Solver.SetAztecOption(AZ_output,32); // HERE WE SET THE IFPACK PRECONDITIONER Solver.SetPrecOperator(&Prec); // .. and here we solve // NOTE: with one process, the solver must converge in // one iteration. Solver.Iterate(1550,1e-5); // Prints out some information about the preconditioner cout << Prec; #ifdef HAVE_MPI MPI_Finalize(); #endif return (EXIT_SUCCESS); }
int main(int argc, char *argv[]) { // initialize MPI and Epetra communicator #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif Teuchos::ParameterList GaleriList; // The problem is defined on a 2D grid, global size is nx * nx. int nx = 30; GaleriList.set("nx", nx); GaleriList.set("ny", nx * Comm.NumProc()); GaleriList.set("mx", 1); GaleriList.set("my", Comm.NumProc()); Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap64("Cartesian2D", Comm, GaleriList) ); Teuchos::RefCountPtr<Epetra_RowMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) ); // =============================================================== // // B E G I N N I N G O F I F P A C K C O N S T R U C T I O N // // =============================================================== // Teuchos::ParameterList List; // builds an Ifpack_AdditiveSchwarz. This is templated with // the local solvers, in this case Ifpack_BlockRelaxation. // Ifpack_BlockRelaxation requires as a templated a container // class. A container defines // how to store the diagonal blocks. Two choices are available: // Ifpack_DenseContainer (to store them as dense block, // than use LAPACK' factorization to apply the inverse of // each block), of Ifpack_SparseContainer (to store // the diagonal block as Epetra_CrsMatrix's). // // Here, we use Ifpack_SparseContainer, which in turn is // templated with the class to use to apply the inverse // of each block. For example, we can use Ifpack_Amesos. // We still have to decide the overlap among the processes, // and the overlap among the blocks. The two values // can be different. The overlap among the blocks is // considered only if block Jacobi is used. int OverlapProcs = 2; int OverlapBlocks = 0; // define the block below to use dense containers #if 0 Ifpack_AdditiveSchwarz<Ifpack_BlockRelaxation<Ifpack_DenseContainer> > Prec(A, OverlapProcs); #else Ifpack_AdditiveSchwarz<Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > > Prec(&*A, OverlapProcs); #endif List.set("relaxation: type", "symmetric Gauss-Seidel"); List.set("partitioner: overlap", OverlapBlocks); #ifdef HAVE_IFPACK_METIS // use METIS to create the blocks. This requires --enable-ifpack-metis. // If METIS is not installed, the user may select "linear". List.set("partitioner: type", "metis"); #else // or a simple greedy algorithm is METIS is not enabled List.set("partitioner: type", "greedy"); #endif // defines here the number of local blocks. If 1, // and only one process is used in the computation, then // the preconditioner must converge in one iteration. List.set("partitioner: local parts", 4); // sets the parameters IFPACK_CHK_ERR(Prec.SetParameters(List)); // initialize the preconditioner. IFPACK_CHK_ERR(Prec.Initialize()); // Builds the preconditioners. IFPACK_CHK_ERR(Prec.Compute()); // =================================================== // // E N D O F I F P A C K C O N S T R U C T I O N // // =================================================== // // At this point, we need some additional objects // to define and solve the linear system. // defines LHS and RHS Epetra_Vector LHS(A->OperatorDomainMap()); Epetra_Vector RHS(A->OperatorDomainMap()); LHS.PutScalar(0.0); RHS.Random(); // need an Epetra_LinearProblem to define AztecOO solver Epetra_LinearProblem Problem(&*A,&LHS,&RHS); // now we can allocate the AztecOO solver AztecOO Solver(Problem); // specify solver Solver.SetAztecOption(AZ_solver,AZ_cg); Solver.SetAztecOption(AZ_output,32); // HERE WE SET THE IFPACK PRECONDITIONER Solver.SetPrecOperator(&Prec); // .. and here we solve // NOTE: with one process, the solver must converge in // one iteration. Solver.Iterate(1550,1e-5); #ifdef HAVE_MPI MPI_Finalize() ; #endif return(EXIT_SUCCESS); }
double Ifpack_Condest(const Ifpack_Preconditioner& IFP, const Ifpack_CondestType CT, const int MaxIters, const double Tol, Epetra_RowMatrix* Matrix) { double ConditionNumberEstimate = -1.0; if (CT == Ifpack_Cheap) { // Create a vector with all values equal to one Epetra_Vector Ones(IFP.OperatorDomainMap()); Ones.PutScalar(1.0); // Create the vector of results Epetra_Vector OnesResult(IFP.OperatorRangeMap()); // Compute the effect of the solve on the vector of ones IFPACK_CHK_ERR(IFP.ApplyInverse(Ones, OnesResult)); // Make all values non-negative IFPACK_CHK_ERR(OnesResult.Abs(OnesResult)); // Get the maximum value across all processors IFPACK_CHK_ERR(OnesResult.MaxValue(&ConditionNumberEstimate)); } else if (CT == Ifpack_CG) { #ifdef HAVE_IFPACK_AZTECOO if (Matrix == 0) Matrix = (Epetra_RowMatrix*)&(IFP.Matrix()); Epetra_Vector LHS(IFP.OperatorDomainMap()); LHS.PutScalar(0.0); Epetra_Vector RHS(IFP.OperatorRangeMap()); RHS.Random(); Epetra_LinearProblem Problem; Problem.SetOperator(Matrix); Problem.SetLHS(&LHS); Problem.SetRHS(&RHS); AztecOO Solver(Problem); Solver.SetAztecOption(AZ_output,AZ_none); Solver.SetAztecOption(AZ_solver,AZ_cg_condnum); Solver.Iterate(MaxIters,Tol); const double* status = Solver.GetAztecStatus(); ConditionNumberEstimate = status[AZ_condnum]; #endif } else if (CT == Ifpack_GMRES) { #ifdef HAVE_IFPACK_AZTECOO if (Matrix == 0) Matrix = (Epetra_RowMatrix*)&(IFP.Matrix()); Epetra_Vector LHS(IFP.OperatorDomainMap()); LHS.PutScalar(0.0); Epetra_Vector RHS(IFP.OperatorRangeMap()); RHS.Random(); Epetra_LinearProblem Problem; Problem.SetOperator(Matrix); Problem.SetLHS(&LHS); Problem.SetRHS(&RHS); AztecOO Solver(Problem); Solver.SetAztecOption(AZ_solver,AZ_gmres_condnum); Solver.SetAztecOption(AZ_output,AZ_none); // the following can be problematic for large problems, // but any restart would destroy useful information about // the condition number. Solver.SetAztecOption(AZ_kspace,MaxIters); Solver.Iterate(MaxIters,Tol); const double* status = Solver.GetAztecStatus(); ConditionNumberEstimate = status[AZ_condnum]; #endif } return(ConditionNumberEstimate); }
// Like AffineFromAffine, try another pass of scaffold refinement. // void MAffine::AffineFromAffine2( vector<double> &X, int nTr ) { double sc = 2 * max( gW, gH ); int nvars = nTr * NX; printf( "Aff: %d unknowns; %d constraints.\n", nvars, vAllC.size() ); vector<double> RHS( nvars, 0.0 ); vector<LHSCol> LHS( nvars ); X.resize( nvars ); // Get the Affines A vector<double> A; AffineFromAffine( A, nTr ); // SetPointPairs: A(pi) = A(pj) double fz = 1.0; int nc = vAllC.size(); for( int i = 0; i < nc; ++i ) { const Constraint &C = vAllC[i]; if( !C.used || !C.inlier ) continue; // A(p1) = A(p2) { int j = vRgn[C.r1].itr * NX; double x1 = C.p1.x * fz / sc, y1 = C.p1.y * fz / sc, x2, y2; Point g2 = C.p2; L2GPoint( g2, A, vRgn[C.r2].itr ); x2 = g2.x * fz / sc; y2 = g2.y * fz / sc; double v[3] = { x1, y1, fz }; int i1[3] = { j, j+1, j+2 }, i2[3] = { j+3, j+4, j+5 }; AddConstraint( LHS, RHS, 3, i1, v, x2 ); AddConstraint( LHS, RHS, 3, i2, v, y2 ); } // A(p2) = T(p1) { int j = vRgn[C.r2].itr * NX; double x1 = C.p2.x * fz / sc, y1 = C.p2.y * fz / sc, x2, y2; Point g2 = C.p1; L2GPoint( g2, A, vRgn[C.r1].itr ); x2 = g2.x * fz / sc; y2 = g2.y * fz / sc; double v[3] = { x1, y1, fz }; int i1[3] = { j, j+1, j+2 }, i2[3] = { j+3, j+4, j+5 }; AddConstraint( LHS, RHS, 3, i1, v, x2 ); AddConstraint( LHS, RHS, 3, i2, v, y2 ); } } // Solve //SolveWithSquareness( X, LHS, RHS, nTr ); //SolveWithUnitMag( X, LHS, RHS, nTr ); WriteSolveRead( X, LHS, RHS, "A-FrmA2", nproc, false ); PrintMagnitude( X ); RescaleAll( X, sc ); }
// Experiment to use approximations H(pi) = T(pj). In practice // translations lack the accuracy of affines and are always an // inferior starting point for homographies. // void MHmgphy::HmgphyFromTrans( vector<double> &X, int nTr ) { double sc = 2 * max( gW, gH ); int nvars = nTr * NX; printf( "Hmg: %d unknowns; %d constraints.\n", nvars, vAllC.size() ); vector<double> RHS( nvars, 0.0 ); vector<LHSCol> LHS( nvars ); X.resize( nvars ); // Get the pure translations T MTrans M; vector<double> T; M.SetModelParams( gW, gH, -1, -1, -1, -1, nproc, -1, NULL, NULL, zs ); M.SolveSystem( T, nTr ); // SetPointPairs: H(pi) = T(pj) double fz = 1.0; int nc = vAllC.size(); for( int i = 0; i < nc; ++i ) { const Constraint &C = vAllC[i]; if( !C.used || !C.inlier ) continue; // H(p1) = T(p2) { int j = vRgn[C.r1].itr * NX, k = vRgn[C.r2].itr * 2; double x1 = C.p1.x * fz / sc, y1 = C.p1.y * fz / sc, x2 = (C.p2.x + T[k ]) / sc, y2 = (C.p2.y + T[k+1]) / sc; double v[5] = { x1, y1, fz, -x1*x2, -y1*x2 }; int i1[5] = { j, j+1, j+2, j+6, j+7 }, i2[5] = { j+3, j+4, j+5, j+6, j+7 }; AddConstraint( LHS, RHS, 5, i1, v, x2 * fz ); v[3] = -x1*y2; v[4] = -y1*y2; AddConstraint( LHS, RHS, 5, i2, v, y2 * fz ); } // H(p2) = T(p1) { int j = vRgn[C.r2].itr * NX, k = vRgn[C.r1].itr * 2; double x1 = C.p2.x * fz / sc, y1 = C.p2.y * fz / sc, x2 = (C.p1.x + T[k ]) / sc, y2 = (C.p1.y + T[k+1]) / sc; double v[5] = { x1, y1, fz, -x1*x2, -y1*x2 }; int i1[5] = { j, j+1, j+2, j+6, j+7 }, i2[5] = { j+3, j+4, j+5, j+6, j+7 }; AddConstraint( LHS, RHS, 5, i1, v, x2 * fz ); v[3] = -x1*y2; v[4] = -y1*y2; AddConstraint( LHS, RHS, 5, i2, v, y2 * fz ); } } // Solve WriteSolveRead( X, LHS, RHS, "H-FrmT", nproc, false ); PrintMagnitude( X ); RescaleAll( X, sc ); }
// This method for solving montages omits calling SetPointPairs // to assert A1(p1) - A2(p2). Rather, we only set approximations // A(pi) = T(pj). This isn't nearly as accurate as the current // favorite AffineFromTransWt, which combines SetPointPairs with // downweighted scaffold constraints A(pi) = T(pj). // // Rather than give up on this method, I also tried to improve // results by a series of scaffold refinements. That is, first // get T's, use those to get A's, use those to get better A's // do that again. The result of that slowly converges toward // AffineFromTransWt but a great computaion cost. These iterative // experiment snippets follow. // void MAffine::AffineFromTrans( vector<double> &X, int nTr ) { double sc = 2 * max( gW, gH ); int nvars = nTr * NX; printf( "Aff: %d unknowns; %d constraints.\n", nvars, vAllC.size() ); vector<double> RHS( nvars, 0.0 ); vector<LHSCol> LHS( nvars ); X.resize( nvars ); // Get the pure translations T MTrans M; vector<double> T; M.SetModelParams( gW, gH, -1, -1, -1, -1, nproc, -1, NULL, NULL, zs ); M.SolveSystem( T, nTr ); // SetPointPairs: A(pi) = T(pj) int nc = vAllC.size(); for( int i = 0; i < nc; ++i ) { const Constraint &C = vAllC[i]; if( !C.used || !C.inlier ) continue; // A(p1) = T(p2) { int j = vRgn[C.r1].itr * NX, k = vRgn[C.r2].itr * 2; double x1 = C.p1.x * scaf_strength / sc, y1 = C.p1.y * scaf_strength / sc, x2 = (C.p2.x + T[k ]) * scaf_strength / sc, y2 = (C.p2.y + T[k+1]) * scaf_strength / sc; double v[3] = { x1, y1, scaf_strength }; int i1[3] = { j, j+1, j+2 }, i2[3] = { j+3, j+4, j+5 }; AddConstraint( LHS, RHS, 3, i1, v, x2 ); AddConstraint( LHS, RHS, 3, i2, v, y2 ); } // A(p2) = T(p1) { int j = vRgn[C.r2].itr * NX, k = vRgn[C.r1].itr * 2; double x1 = C.p2.x * scaf_strength / sc, y1 = C.p2.y * scaf_strength / sc, x2 = (C.p1.x + T[k ]) * scaf_strength / sc, y2 = (C.p1.y + T[k+1]) * scaf_strength / sc; double v[3] = { x1, y1, scaf_strength }; int i1[3] = { j, j+1, j+2 }, i2[3] = { j+3, j+4, j+5 }; AddConstraint( LHS, RHS, 3, i1, v, x2 ); AddConstraint( LHS, RHS, 3, i2, v, y2 ); } } // Solve //SolveWithSquareness( X, LHS, RHS, nTr ); //SolveWithUnitMag( X, LHS, RHS, nTr ); WriteSolveRead( X, LHS, RHS, "A-FrmT", nproc, false ); PrintMagnitude( X ); RescaleAll( X, sc ); }
QRect CEdge::drawTree( Q3Canvas* canvas, int left, int depth, StringToString* filter ) { int X_PADDING = 10; int Y_SPACING = 30; // int X_MARGIN = 10; unused variable 'X_Margin' int Y_MARGIN = 10; //================================================ Q3CanvasItem* edge = new Q3CanvasText( LHS(), canvas ), * leaf = NULL; Q3CanvasLine* line; m_CanvasItems.clear(); m_CanvasItems.append( edge ); int myLeft = left, myTop = ( depth * Y_SPACING ) + Y_MARGIN, myCenterX, myBottom, childCenterX, childLeft, childTop, shiftAmount; Q3ValueList<QRect> daughterBoundingRectangles; Q3ValueList<QRect>::iterator it; QRect myBoundingRect, rectangle; myBoundingRect.setTop( myTop ); myBoundingRect.setLeft( myLeft ); myBoundingRect.setBottom( myTop + edge->boundingRect().height() - 1 ); myBoundingRect.setRight( myLeft + edge->boundingRect().width() - 1 ); int count = 0; // bool first = TRUE; unused variable 'first' CEdge* daughter; for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() ) { daughterBoundingRectangles.append( rectangle ); daughterBoundingRectangles[count] = daughter->drawTree( canvas, left, depth + 1, filter ); // Adjust left position based on bounding rectangle of last daughter left = daughterBoundingRectangles[count].right() + X_PADDING; count++; } if( m_Daughters.isEmpty() ) { // Create leaf node childLeft = myLeft; childTop = ( ( depth + 1 ) * Y_SPACING ) + Y_MARGIN; leaf = new Q3CanvasText( Filter( filter, RHS() ), canvas ); m_CanvasItems.append( leaf ); leaf->move( childLeft, childTop ); leaf->show(); // Adjust my bounding rect if( leaf->boundingRect().right() > myBoundingRect.right() ) myBoundingRect.setRight( leaf->boundingRect().right() ); myBoundingRect.setBottom( leaf->boundingRect().bottom() ); } else { for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it ) { // Adjust my bounding rect if( (*it).right() > myBoundingRect.right() ) myBoundingRect.setRight( (*it).right() ); if( (*it).bottom() > myBoundingRect.bottom() ) myBoundingRect.setBottom( (*it).bottom() ); } } if( myBoundingRect.width() == edge->boundingRect().width() ) { // Shift all children to the right if( m_Daughters.isEmpty() ) { shiftAmount = int (( myBoundingRect.width() - leaf->boundingRect().width() ) / 2.0); leaf->move( leaf->boundingRect().left() + shiftAmount, leaf->boundingRect().top() ); leaf->show(); } else { shiftAmount = int (( myBoundingRect.width() - ( daughterBoundingRectangles.last().right() - daughterBoundingRectangles.first().left() ) ) / 2.0); for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() ) { daughter->shiftTree( canvas, shiftAmount, 0 ); } for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it ) { // Adjust the bounding rect position (*it).setLeft( (*it).left() + shiftAmount ); (*it).setRight( (*it).right() + shiftAmount ); } } } else myLeft = ( myBoundingRect.right() - ( myBoundingRect.width() / 2 ) ) - ( edge->boundingRect().width() / 2 ); if( myLeft < myBoundingRect.left() ) myLeft = myBoundingRect.left(); edge->move( myLeft, myTop ); // Draw lines to daughter nodes if( m_Daughters.isEmpty() ) { myCenterX = edge->boundingRect().center().x(); myBottom = edge->boundingRect().bottom(); childCenterX = leaf->boundingRect().center().x(); childTop = leaf->boundingRect().top(); if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX; line = new Q3CanvasLine( canvas ); line->setPoints( myCenterX, myBottom, childCenterX, childTop ); line->show(); m_CanvasItems.append( line ); } else { Q3ValueList<QRect>::iterator it; for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it ) { myCenterX = edge->boundingRect().center().x(); myBottom = edge->boundingRect().bottom(); childCenterX = (*it).center().x(); childTop = (*it).top(); if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX; line = new Q3CanvasLine( canvas ); line->setPoints( myCenterX, myBottom, childCenterX, childTop ); line->show(); m_CanvasItems.append( line ); } } edge->show(); canvas->update(); return myBoundingRect; }
void operator()(const Vec1 &rhs, Vec2 &x) const { Eigen::Map< Eigen::Matrix<value_type, Eigen::Dynamic, 1> > RHS(const_cast<value_type*>(&rhs[0]), n), X(&x[0], n); X = S.solve(RHS); }
int user_find_cuts(void *user, int varnum, int iter_num, int level, int index, double objval, int *indices, double *values, double ub, double etol, int *num_cuts, int *alloc_cuts, cut_data ***cuts) { vrp_cg_problem *vrp = (vrp_cg_problem *)user; int vertnum = vrp->vertnum; network *n; vertex *verts = NULL; int *compdemands = NULL, *compnodes = NULL, *compnodes_copy = NULL; int *compmembers = NULL, comp_num = 0; /*__BEGIN_EXPERIMENTAL_SECTION__*/ int *compdemands_copy = NULL; double *compcuts_copy = NULL, *compdensity = NULL, density; /*___END_EXPERIMENTAL_SECTION___*/ double node_cut, max_node_cut, *compcuts = NULL; int rcnt, cur_bins = 0, k; char **coef_list; int i, max_node; double cur_slack = 0.0; int capacity = vrp->capacity; int cut_size = (vertnum >> DELETE_POWER) + 1; cut_data *new_cut = NULL; elist *cur_edge = NULL; int which_connected_routine = vrp->par.which_connected_routine; int *ref = vrp->ref; double *cut_val = vrp->cut_val; char *in_set = vrp->in_set; char *cut_list = vrp->cut_list; elist *cur_edge1 = NULL, *cur_edge2 = NULL; /*__BEGIN_EXPERIMENTAL_SECTION__*/ #ifdef COMPILE_OUR_DECOMP edge *edge_pt; #endif /*___END_EXPERIMENTAL_SECTION___*/ int node1 = 0, node2 = 0; int *demand = vrp->demand; int *new_demand = vrp->new_demand; int total_demand = demand[0]; int num_routes = vrp->numroutes, num_trials; int triangle_cuts = 0; char *coef; if (iter_num == 1) SRANDOM(1); /*__BEGIN_EXPERIMENTAL_SECTION__*/ #if 0 CCutil_sprand(1, &rand_state); #endif /*___END_EXPERIMENTAL_SECTION___*/ /*__BEGIN_EXPERIMENTAL_SECTION__*/ #if 0 if (vrp->dg_id && vrp->par.verbosity > 3){ sprintf(name, "support graph"); display_support_graph(vrp->dg_id, (p->cur_sol.xindex == 0 && p->cur_sol.xiter_num == 1) ? TRUE: FALSE, name, varnum, xind, xval, etol, CTOI_WAIT_FOR_CLICK_AND_REPORT); } #endif /*___END_EXPERIMENTAL_SECTION___*/ /* This creates a fractional graph representing the LP solution */ n = createnet(indices, values, varnum, etol, vrp->edges, demand, vertnum); if (n->is_integral){ /* if the network is integral, check for connectivity */ check_connectivity(n, etol, capacity, num_routes, cuts, num_cuts, alloc_cuts); free_net(n); return(USER_SUCCESS); } #ifdef DO_TSP_CUTS if (vrp->par.which_tsp_cuts && vrp->par.tsp_prob){ tsp_cuts(n, vrp->par.verbosity, vrp->par.tsp_prob, vrp->par.which_tsp_cuts, cuts, num_cuts, alloc_cuts); free_net(n); return(USER_SUCCESS); } #endif /*__BEGIN_EXPERIMENTAL_SECTION__*/ if (!vrp->par.always_do_mincut){/*user_par.always_do_mincut indicates whether we should just always do the min_cut routine or whether we should also try this routine*/ /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 { #endif verts = n->verts; if (which_connected_routine == BOTH) which_connected_routine = CONNECTED; new_cut = (cut_data *) calloc(1, sizeof(cut_data)); new_cut->size = cut_size; compnodes_copy = (int *) malloc((vertnum + 1) * sizeof(int)); compmembers = (int *) malloc((vertnum + 1) * sizeof(int)); /*__BEGIN_EXPERIMENTAL_SECTION__*/ compdemands_copy = (int *) calloc(vertnum + 1, sizeof(int)); compcuts_copy = (double *) calloc(vertnum + 1, sizeof(double)); #ifdef COMPILE_OUR_DECOMP compdensity = vrp->par.do_our_decomp ? (double *) calloc(vertnum+1, sizeof(double)) : NULL; #endif /*___END_EXPERIMENTAL_SECTION___*/ do{ compnodes = (int *) calloc(vertnum + 1, sizeof(int)); compdemands = (int *) calloc(vertnum + 1, sizeof(int)); compcuts = (double *) calloc(vertnum + 1, sizeof(double)); /*------------------------------------------------------------------*\ * Get the connected components of the solution graph without the * depot and see if the number of components is more than one \*------------------------------------------------------------------*/ rcnt = (which_connected_routine == BICONNECTED ? biconnected(n, compnodes, compdemands, compcuts) : connected(n, compnodes, compdemands, compmembers, /*__BEGIN_EXPERIMENTAL_SECTION__*/ compcuts, compdensity)); /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 compcuts, NULL)); #endif /* copy the arrays as they will be needed later */ if (!which_connected_routine && /*__BEGIN_EXPERIMENTAL_SECTION__*/ (vrp->par.do_greedy || vrp->par.do_our_decomp)){ /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 vrp->par.do_greedy){ #endif compnodes_copy = (int *) memcpy((char *)compnodes_copy, (char*)compnodes, (vertnum+1)*sizeof(int)); /*__BEGIN_EXPERIMENTAL_SECTION__*/ compdemands_copy = (int *) memcpy((char *)compdemands_copy, (char *)compdemands, (vertnum+1)*ISIZE); compcuts_copy = (double *) memcpy((char *)compcuts_copy, (char *)compcuts, (vertnum+1)*DSIZE); /*___END_EXPERIMENTAL_SECTION___*/ n->compnodes = compnodes_copy; comp_num = rcnt; } if (rcnt > 1){ /*---------------------------------------------------------------*\ * If the number of components is more then one, then check each * component to see if it violates a capacity constraint \*---------------------------------------------------------------*/ coef_list = (char **) calloc(rcnt, sizeof(char *)); coef_list[0] = (char *) calloc(rcnt*cut_size, sizeof(char)); for(i = 1; i<rcnt; i++) coef_list[i] = coef_list[0]+i*cut_size; for(i = 1; i < vertnum; i++) (coef_list[(verts[i].comp)-1][i >> DELETE_POWER]) |= (1 << (i & DELETE_AND)); for (i = 0; i < rcnt; i++){ if (compnodes[i+1] < 2) continue; /*check ith component to see if it violates a constraint*/ if (vrp->par.which_connected_routine == BOTH && which_connected_routine == BICONNECTED && compcuts[i+1]==0) continue; if (compcuts[i+1] < 2*BINS(compdemands[i+1], capacity)-etol){ /*the constraint is violated so impose it*/ new_cut->coef = (char *) (coef_list[i]); new_cut->type = (compnodes[i+1] < vertnum/2 ? SUBTOUR_ELIM_SIDE:SUBTOUR_ELIM_ACROSS); new_cut->rhs = (new_cut->type == SUBTOUR_ELIM_SIDE ? RHS(compnodes[i+1],compdemands[i+1], capacity): 2*BINS(compdemands[i+1], capacity)); cg_send_cut(new_cut, num_cuts, alloc_cuts, cuts); } else{/*if the constraint is not violated, then try generating a violated constraint by deleting customers that don't change the number of trucks required by the customers in the component but decrease the value of the cut*/ cur_bins = BINS(compdemands[i+1], capacity);/*the current number of trucks required*/ /*current slack in the constraint*/ cur_slack = (compcuts[i+1] - 2*cur_bins); while (compnodes[i+1]){/*while there are still nodes in the component*/ for (max_node = 0, max_node_cut = 0, k = 1; k < vertnum; k++){ if (verts[k].comp == i+1){ if (BINS(compdemands[i+1]-verts[k].demand, capacity) == cur_bins){ /*if the number of trucks doesn't decrease upon deleting this customer*/ for (node_cut = 0, cur_edge = verts[k].first; cur_edge; cur_edge = cur_edge->next_edge){ node_cut += (cur_edge->other_end ? -cur_edge->data->weight : cur_edge->data->weight); } if (node_cut > max_node_cut){/*check whether the value of the cut decrease is the best seen so far*/ max_node = k; max_node_cut = node_cut; } } } } if (!max_node){ break; } /*delete the customer that exhibited the greatest decrease in cut value*/ compnodes[i+1]--; compdemands[i+1] -= verts[max_node].demand; compcuts[i+1] -= max_node_cut; cur_slack -= max_node_cut; verts[max_node].comp = 0; coef_list[i][max_node >> DELETE_POWER] ^= (1 << (max_node & DELETE_AND)); if (cur_slack < 0){/*if the cut is now violated, impose it*/ new_cut->coef = (char *) (coef_list[i]); new_cut->type = (compnodes[i+1] < vertnum/2 ? SUBTOUR_ELIM_SIDE:SUBTOUR_ELIM_ACROSS); new_cut->size = cut_size; new_cut->rhs = (new_cut->type == SUBTOUR_ELIM_SIDE ? RHS(compnodes[i+1], compdemands[i+1], capacity): 2*cur_bins); cg_send_cut(new_cut, num_cuts, alloc_cuts, cuts); break; } } } } FREE(coef_list[0]); FREE(coef_list); } which_connected_routine++; FREE(compnodes); FREE(compdemands); FREE(compcuts); }while((!(*num_cuts) && vrp->par.which_connected_routine == BOTH)
// A second pass deriving better H from previous H is worthwhile. // More such passes gain nothing for the extra compute time. // void MHmgphy::HmgphyFromHmgphy( vector<double> &X, int nTr ) { double sc = 2 * max( gW, gH ); int nvars = nTr * NX; printf( "Hmg: %d unknowns; %d constraints.\n", nvars, vAllC.size() ); vector<double> RHS( nvars, 0.0 ); vector<LHSCol> LHS( nvars ); X.resize( nvars ); // Apply previous final results at highest level, once only SetUniteLayer( LHS, RHS, sc ); // Get the Homographies A vector<double> A; HmgphyFromAffine( A, nTr ); // SetPointPairs: H(pi) = A(pj) double fz = 1.0; int nc = vAllC.size(); for( int i = 0; i < nc; ++i ) { const Constraint &C = vAllC[i]; if( !C.used || !C.inlier ) continue; // H(p1) = A(p2) { int j = vRgn[C.r1].itr * NX; double x1 = C.p1.x * fz / sc, y1 = C.p1.y * fz / sc, x2, y2; Point g2 = C.p2; L2GPoint( g2, A, vRgn[C.r2].itr ); x2 = g2.x / sc; y2 = g2.y / sc; double v[5] = { x1, y1, fz, -x1*x2, -y1*x2 }; int i1[5] = { j, j+1, j+2, j+6, j+7 }, i2[5] = { j+3, j+4, j+5, j+6, j+7 }; AddConstraint( LHS, RHS, 5, i1, v, x2 * fz ); v[3] = -x1*y2; v[4] = -y1*y2; AddConstraint( LHS, RHS, 5, i2, v, y2 * fz ); } // H(p2) = A(p1) { int j = vRgn[C.r2].itr * NX; double x1 = C.p2.x * fz / sc, y1 = C.p2.y * fz / sc, x2, y2; Point g2 = C.p1; L2GPoint( g2, A, vRgn[C.r1].itr ); x2 = g2.x / sc; y2 = g2.y / sc; double v[5] = { x1, y1, fz, -x1*x2, -y1*x2 }; int i1[5] = { j, j+1, j+2, j+6, j+7 }, i2[5] = { j+3, j+4, j+5, j+6, j+7 }; AddConstraint( LHS, RHS, 5, i1, v, x2 * fz ); v[3] = -x1*y2; v[4] = -y1*y2; AddConstraint( LHS, RHS, 5, i2, v, y2 * fz ); } } // Solve WriteSolveRead( X, LHS, RHS, "H-FrmH", nproc, false ); PrintMagnitude( X ); RescaleAll( X, sc ); }
void getstencil(MatGenFD g, HYPRE_Int ix, HYPRE_Int iy, HYPRE_Int iz) { HYPRE_Int k; double h = g->hh; double hhalf = h*0.5; double x = h*ix; double y = h*iy; double z = h*iz; double cntr = 0.0; double *stencil = g->stencil; double coeff; bool threeD = g->threeD; for (k=0; k<8; ++k) stencil[k] = 0.0; /* differentiation wrt x */ coeff = g->A(g->a, x+hhalf,y,z); EAST(stencil) += coeff; cntr += coeff; coeff = g->A(g->a, x-hhalf,y,z); WEST(stencil) += coeff; cntr += coeff; coeff = g->D(g->d, x,y,z)*hhalf; EAST(stencil) += coeff; WEST(stencil) -= coeff; /* differentiation wrt y */ coeff = g->B(g->b,x,y+hhalf,z); NORTH(stencil) += coeff; cntr += coeff; coeff = g->B(g->b,x,y-hhalf,z); SOUTH(stencil) += coeff; cntr += coeff; coeff = g->E(g->e,x,y,z)*hhalf; NORTH(stencil) += coeff; SOUTH(stencil) -= coeff; /* differentiation wrt z */ if (threeD) { coeff = g->C(g->c,x,y,z+hhalf); BACK(stencil) += coeff; cntr += coeff; coeff = g->C(g->c,x,y,z-hhalf); FRONT(stencil) += coeff; cntr += coeff; coeff = g->F(g->f,x,y,z)*hhalf; BACK(stencil) += coeff; FRONT(stencil) -= coeff; } /* contribution from function G: */ coeff = g->G(g->g,x,y,z); CENTER(stencil) = h*h*coeff - cntr; RHS(stencil) = h*h*g->H(g->h,x,y,z); }
NOX::StatusTest::StatusType NOX::Solver::AndersonAcceleration::step() { prePostOperator.runPreIterate(*this); Teuchos::ParameterList lsParams = paramsPtr->sublist("Direction").sublist("Newton").sublist("Linear Solver"); // On the first step, do some initializations if (nIter == 0) { // Compute F of initital guess NOX::Abstract::Group::ReturnType rtype = solnPtr->computeF(); if (rtype != NOX::Abstract::Group::Ok) { utilsPtr->out() << "NOX::Solver::AndersonAcceleration::init - " << "Unable to compute F" << std::endl; throw "NOX Error"; } // Test the initial guess status = testPtr->checkStatus(*this, checkType); if ((status == NOX::StatusTest::Converged) && (utilsPtr->isPrintType(NOX::Utils::Warning))) { utilsPtr->out() << "Warning: NOX::Solver::AndersonAcceleration::init() - " << "The solution passed into the solver (either " << "through constructor or reset method) " << "is already converged! The solver wil not " << "attempt to solve this system since status is " << "flagged as converged." << std::endl; } printUpdate(); // First check status if (status != NOX::StatusTest::Unconverged) { prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Apply preconditioner if enabled if (precond) { if (recomputeJacobian) solnPtr->computeJacobian(); solnPtr->applyRightPreconditioning(false, lsParams, solnPtr->getF(), *oldPrecF); } else *oldPrecF = solnPtr->getF(); // Copy initial guess to old soln *oldSolnPtr = *solnPtr; // Compute step then first iterate with a line search. workVec->update(mixParam,*oldPrecF); bool ok = lineSearchPtr->compute(*solnPtr, stepSize, *workVec, *this); if (!ok) { if (stepSize == 0.0) { utilsPtr->out() << "NOX::Solver::AndersonAcceleratino::iterate - line search failed" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } else if (utilsPtr->isPrintType(NOX::Utils::Warning)) utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - using recovery step for line search" << std::endl; } // Compute F for the first iterate in case it isn't in the line search rtype = solnPtr->computeF(); if (rtype != NOX::Abstract::Group::Ok) { utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - unable to compute F" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Evaluate the current status. status = testPtr->checkStatus(*this, checkType); //Update iteration count nIter++; prePostOperator.runPostIterate(*this); printUpdate(); return status; } // First check status if (status != NOX::StatusTest::Unconverged) { prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Apply preconditioner if enabled if (precond) { if (recomputeJacobian) solnPtr->computeJacobian(); solnPtr->applyRightPreconditioning(false, lsParams, solnPtr->getF(), *precF); } else *precF = solnPtr->getF(); // Manage the matrices of past iterates and QR factors if (storeParam > 0) { if (nIter == accelerationStartIteration) { // Initialize nStore = 0; rMat.shape(0,0); oldPrecF->update(1.0, *precF, -1.0); qrAdd(*oldPrecF); xMat[0]->update(1.0, solnPtr->getX(), -1.0, oldSolnPtr->getX(), 0.0); } else if (nIter > accelerationStartIteration) { if (nStore == storeParam) { Teuchos::RCP<NOX::Abstract::Vector> tempPtr = xMat[0]; for (int ii = 0; ii<nStore-1; ii++) xMat[ii] = xMat[ii+1]; xMat[nStore-1] = tempPtr; qrDelete(); } oldPrecF->update(1.0, *precF, -1.0); qrAdd(*oldPrecF); xMat[nStore-1]->update(1.0, solnPtr->getX(), -1.0, oldSolnPtr->getX(), 0.0); } } // Reorthogonalize if ( (nStore > 1) && (orthoFrequency > 0) ) if (nIter % orthoFrequency == 0) reorthogonalize(); // Copy current soln to the old soln. *oldSolnPtr = *solnPtr; *oldPrecF = *precF; // Adjust for condition number if (nStore > 0) { Teuchos::LAPACK<int,double> lapack; char normType = '1'; double invCondNum = 0.0; int info = 0; if ( WORK.size() < static_cast<std::size_t>(4*nStore) ) WORK.resize(4*nStore); if (IWORK.size() < static_cast<std::size_t>(nStore)) IWORK.resize(nStore); lapack.GECON(normType,nStore,rMat.values(),nStore,rMat.normOne(),&invCondNum,&WORK[0],&IWORK[0],&info); if (utilsPtr->isPrintType(Utils::Details)) utilsPtr->out() << " R condition number estimate ("<< nStore << ") = " << 1.0/invCondNum << std::endl; if (adjustForConditionNumber) { while ( (1.0/invCondNum > dropTolerance) && (nStore > 1) ) { Teuchos::RCP<NOX::Abstract::Vector> tempPtr = xMat[0]; for (int ii = 0; ii<nStore-1; ii++) xMat[ii] = xMat[ii+1]; xMat[nStore-1] = tempPtr; qrDelete(); lapack.GECON(normType,nStore,rMat.values(),nStore,rMat.normOne(),&invCondNum,&WORK[0],&IWORK[0],&info); if (utilsPtr->isPrintType(Utils::Details)) utilsPtr->out() << " Adjusted R condition number estimate ("<< nStore << ") = " << 1.0/invCondNum << std::endl; } } } // Solve the least-squares problem. Teuchos::SerialDenseMatrix<int,double> gamma(nStore,1), RHS(nStore,1), Rgamma(nStore,1); for (int ii = 0; ii<nStore; ii++) RHS(ii,0) = precF->innerProduct( *(qMat[ii]) ); //Back-solve for gamma for (int ii = nStore-1; ii>=0; ii--) { gamma(ii,0) = RHS(ii,0); for (int jj = ii+1; jj<nStore; jj++) { gamma(ii,0) -= rMat(ii,jj)*gamma(jj,0); } gamma(ii,0) /= rMat(ii,ii); } if (nStore > 0) Rgamma.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,mixParam,rMat,gamma,0.0); // Compute the step and new solution using the line search. workVec->update(mixParam,*precF); for (int ii=0; ii<nStore; ii++) workVec->update(-gamma(ii,0), *(xMat[ii]), -Rgamma(ii,0),*(qMat[ii]),1.0); bool ok = lineSearchPtr->compute(*solnPtr, stepSize, *workVec, *this); if (!ok) { if (stepSize == 0.0) { utilsPtr->out() << "NOX::Solver::AndersonAcceleratino::iterate - line search failed" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } else if (utilsPtr->isPrintType(NOX::Utils::Warning)) utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - using recovery step for line search" << std::endl; } // Compute F for new current solution in case the line search didn't . NOX::Abstract::Group::ReturnType rtype = solnPtr->computeF(); if (rtype != NOX::Abstract::Group::Ok) { utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - unable to compute F" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Update iteration count nIter++; // Evaluate the current status. status = testPtr->checkStatus(*this, checkType); prePostOperator.runPostIterate(*this); printUpdate(); return status; }
void EventLoop(CCam & Camera1) { bool quitit=false; SDL_Event event; SDL_MouseMotionEvent event2; SDL_keysym *whatkey; bool mousedown=false; // Go to while(!quitit) to see what happens once data set up // Go to Render Scene for graphics bit bool exitnow=false; double xunit,yunit,zunit; xunit=1.0;yunit=1.0;zunit=1.0; // if_stream opens for input // of_stream opens for output // f_stream opens for both // string filename ="Sphere4.dat"; ifstream file_in; file_in.open(filename.c_str()); file_in >> n_nodes >> ntri; cout << n_nodes << " number of nodes" << endl; cout << ntri<< " number of triangles" << endl; cout << "read next line\n"; cout << "start read loop\n"; Triangles=(Triangle*)calloc(ntri, sizeof(Triangle)); NodeV=(D3Dvec*)calloc(n_nodes, sizeof(D3Dvec)); //initiales char quad, otherquad; int id,l,m,n; double x,y,z; for(int i=0; i<ntri;i++){ file_in >>l; file_in >>m; file_in >>n; file_in >>quad; // same resuly of file_in >> l >>m >>n; Triangles[i]=Triangle(); //initialise Triangles[i].SetTri(l,m,n); Triangles[i].SetQuad(quad); } for(int i=0; i<ntri;i++){ file_in >> l >> m >> n; Triangles[i].SetNeighb(l,m,n); } for(int i=0; i < n_nodes; i++){ NodeV[i]=D3Dvec(); file_in >> x >> y >> z; NodeV[i].SetVec(x,y,z); } istart=0; istop=ntri; /********************************************************************************** Calculate Metric Tensor **********************************************************************************/ double **Gmetric; Gmetric =(double**)calloc( ntri, sizeof( double[3] ) ); if(!Gmetric){ cout << "Memory Failed for Gmetric " << endl; exit(0);} // 2D vectors in each triangle double **avec, **bvec; avec=(double**)calloc( ntri, sizeof(double[2]) ); if(!avec){ cout << "Memory Failed for avec" << endl; exit(0);} bvec=(double**)calloc( ntri, sizeof(double[2]) ); if(!bvec){ cout << "Memory Failed for bvec" << endl; exit(0);} double avecdash[2], bvecdash[2]; double avecdash_new[2], bvecdash_new[2]; D3Dvec Ve1,Ve2,VOrig; //origin and edge vectors Ve1=D3Dvec(); Ve2=D3Dvec(); VOrig=D3Dvec(); //Initialise D3Dvec Unit_i, Unit_j, Unit_k; Unit_i=D3Dvec(); Unit_j=D3Dvec(); Unit_k=D3Dvec(); int i1,i2,i3; double rad=-1; for(int i=0; i<ntri; i++){ Gmetric[i]=new double[3]; //initialise i1=Triangles[i].Get1(); i2=Triangles[i].Get2(); i3=Triangles[i].Get3(); x=NodeV[i1].GetX(); y=NodeV[i1].GetY(); z=NodeV[i1].GetZ(); VOrig.SetVec(x,y,z); x=NodeV[i2].GetX()-VOrig.GetX(); y=NodeV[i2].GetY()-VOrig.GetY(); z=NodeV[i2].GetZ()-VOrig.GetZ(); Ve1.SetVec(x,y,z); x=NodeV[i3].GetX()-VOrig.GetX(); y=NodeV[i3].GetY()-VOrig.GetY(); z=NodeV[i3].GetZ()-VOrig.GetZ(); Ve2.SetVec(x,y,z); Gmetric[i][0]=Ve1.Dot(Ve1); Gmetric[i][1]=Ve1.Dot(Ve2); Gmetric[i][2]=Ve2.Dot(Ve2); rad=Gmetric[i][0]; rad=sqrt(rad)*6370.; // local cartesians Unit_i=Ve1; Normalise(Unit_i); Unit_k=Ve1*Ve2; Normalise(Unit_k); Unit_j=Unit_k*Unit_i; avec[i]=new double[2]; bvec[i]=new double[2]; avec[i][0]=Unit_i.Dot(Ve1); avec[i][1]=0.0; bvec[i][0]=Unit_i.Dot(Ve2); bvec[i][1]=Unit_j.Dot(Ve2); } /********************************************************************************** GEODESIC- start point **********************************************************************************/ // Now for a geodesic ! // int Tstart0=56; int Tstart, TNext; double xO,yO,zO; double x1,y1,z1; double x2,y2,z2; double x3,y3,z3; char qStart,qNext; double d1, d2, lambda; double d1dash,d2dash; double ds_total, ds_squared; double alpha_start, beta_start; double alphaTstart, betaTstart; //values of lambda to hit the line alpha=0, beta=0, alpha+beta=1 double Tol1=0.000001; // if fabs(d) less than this it lands on edge miles // away or never at all double Tol2=1e-8; //possibility that we land on a corner double alpha_e1, beta_e1; double alpha_e2, beta_e2; double alpha_e3, beta_e3; bool land_e1, land_e2, land_e3; double lambda_edge1, lambda_edge2, lambda_edge3; int Node1, Node2, Node3; double alphaNext,betaNext; double alpha_p, beta_p, alpha_q, beta_q; double alpha_p_dash, beta_p_dash, alpha_q_dash, beta_q_dash; double CosTheta,SinTheta,Theta,Phi; double adot_adash, adot_bdash, bdot_adash, bdot_bdash; double W1,W2,X1,X2,Y1,Y2,Z1,Z2,Det; double ex1,why1,ex2,why3; unsigned int ndim; int kount=0; Tstart=Tstart0; alpha_start=0.25, beta_start=0.25; d1=.25; d2=0.19; bool start_e1, start_e2, start_e3; start_e1=false; //assume that for first triangle start_e2=false; //we don't start off on an edge start_e3=false; //change for instance, if we have alpha_start=0 /********************************************************************************** GEODESIC- Propagate **********************************************************************************/ while(ds_total < 6.3 && kount < GeoPos){ if(kount==GeoPos-1){ cout <<"Last One! " << endl; } Node1=Triangles[Tstart].Get1(); Node2=Triangles[Tstart].Get2(); Node3=Triangles[Tstart].Get3(); D3Dvec Rnode1,Rnode2; Rnode1=D3Dvec(); Rnode2=D3Dvec(); xO=NodeV[Node1].GetX(); yO=NodeV[Node1].GetY(); zO=NodeV[Node1].GetZ(); VOrig.SetVec(xO,yO,zO); x1=NodeV[Node2].GetX(); y1=NodeV[Node2].GetY(); z1=NodeV[Node2].GetZ(); Rnode1.SetVec(x1,y1,z1); x2=NodeV[Node3].GetX(); y2=NodeV[Node3].GetY(); z2=NodeV[Node3].GetZ(); Rnode2.SetVec(x2,y2,z2); Ve1=Rnode1-VOrig; Ve2=Rnode2-VOrig; x3=VOrig.GetX()+alpha_start*Ve1.GetX()+beta_start*Ve2.GetX(); y3=VOrig.GetY()+alpha_start*Ve1.GetY()+beta_start*Ve2.GetY(); z3=VOrig.GetZ()+alpha_start*Ve1.GetZ()+beta_start*Ve2.GetZ(); Geodesy[kount]=new D3Dvec(); Geodesy[kount].SetX(x3); Geodesy[kount].SetY(y3); Geodesy[kount].SetZ(z3); cout << Geodesy[kount].GetX() << " " << Geodesy[kount].GetY() << " " << Geodesy[kount].GetZ() << " kount=" << kount << " Tstart=" << Tstart << endl; kount++; land_e1=false; land_e2=false; land_e3=false; //alpha_start + d1 lambda=0 lands on edge2; //beta_start+ d2 lambda=0 lands on edge1; if( fabs(d1) > Tol1){lambda_edge1=-beta_start/d2; land_e1=true;} if( fabs(d2) > Tol1){lambda_edge2=-alpha_start/d1; land_e2=true;} if( fabs(d2+d2) > Tol1) {lambda_edge3=(1.0-alpha_start-beta_start)/(d1+d2); land_e3=true;} cout << "d1=" << d1 << endl; cout << "d2=" << d2 << endl; cout << "alpha_s=" << alpha_start << endl; cout << "beta_s=" << beta_start << endl; alpha_e1=alpha_start+lambda_edge1*d1; beta_e1=beta_start+lambda_edge1*d2; alpha_e2=alpha_start+lambda_edge2*d1; beta_e2=beta_start+lambda_edge2*d2; alpha_e3=alpha_start+lambda_edge3*d1; beta_e3=beta_start+lambda_edge3*d2; ndim=2; Dmatrix Mat(ndim,ndim); //creates 4 by 3 on the heap. Dvector RHS(ndim); Dvector LHS(ndim); if( (fabs(alpha_e1) < Tol2) && (fabs(beta_e1) <Tol2) ){ // set it safely on edge 1 alpha_e1=2.*Tol2; beta_e1=0.0; } if( (fabs(1.0-alpha_e1) < Tol2) && (fabs(beta_e1) <Tol2) ){ // set it safely on edge 1 alpha_e1=1.0-2.0*Tol2; beta_e1=0.0; } if( (fabs(alpha_e2) < Tol2) && (fabs(beta_e2) <Tol2) ){ // set it safely on edge 2 alpha_e2=0.0; beta_e2=2.0*Tol2; } if( (fabs(1.0-beta_e2) < Tol2) && (fabs(alpha_e2) <Tol2) ){ // set it safely on edge 2 alpha_e2=0.0; beta_e2=1.0-2.0*Tol2; } if( (fabs(1.0-alpha_e3-beta_e3) < Tol2) ){ if(fabs(alpha_e3) < Tol2){ // set it safely on edge 3 alpha_e3=2.0*Tol2; beta_e3=1.0-alpha_e3; } if(fabs(beta_e3) < Tol2){ // set it safely on edge 3 beta_e3=2.0*Tol2; alpha_e3=1.0-beta_e3; } } /* cout << "e1 " << alpha_e1 << " L e1=" << lambda_edge1 << endl; cout << "e2 " << beta_e2 << " L_e2=" << lambda_edge2 << endl; cout << "a e3 " << alpha_e3 << " L_e3=" << lambda_edge3 << endl; cout << "b e3 " << beta_e3 << endl; */ if(lambda_edge1 <0.0 || alpha_e1 < 0.0 || alpha_e1 > 1.0)land_e1=false; if(lambda_edge2 <0.0 || beta_e2 < 0.0 || beta_e2 > 1.0)land_e2=false; if(lambda_edge3 <0.0 || alpha_e3 < 0.0 || alpha_e3 > 1.0)land_e3=false; if(lambda_edge3 <0.0 || beta_e3 < 0.0 || beta_e3 > 1.0)land_e3=false; cout << land_e1 << land_e2 << land_e3 << " edges 1 2 and 3" << endl; // Normally we land on two edges! // We start it some point in the start triangle // proceed to the edge, but now we start at an edge // if(start_e1)land_e1=false; if(start_e2)land_e2=false; if(start_e3)land_e3=false; start_e1=false; start_e2=false; start_e3=false; if(land_e1){ //beta_e1=0 ds_squared= Gmetric[Tstart][0]*(alpha_e1-alpha_start)*(alpha_e1-alpha_start) -2.0*Gmetric[Tstart][1]*(alpha_e1-alpha_start)*beta_start +Gmetric[Tstart][2]*beta_start*beta_start; ds_total=ds_total+sqrt(ds_squared); } if(land_e2){ //alpha_e1=0 ds_squared= Gmetric[Tstart][0]*alpha_start*alpha_start -2.0*Gmetric[Tstart][1]*alpha_start*(beta_e2-beta_start) +Gmetric[Tstart][2]*(beta_e2-beta_start)*(beta_e2-beta_start); ds_total=ds_total+sqrt(ds_squared); } if(land_e3){ ds_squared= Gmetric[Tstart][0]*(alpha_e3-alpha_start)*(alpha_e3-alpha_start) +2.0*Gmetric[Tstart][1]*(alpha_e3-alpha_start)*(beta_e3-beta_start) +Gmetric[Tstart][2]*(beta_e3-beta_start)*(beta_e3-beta_start); ds_total=ds_total+sqrt(ds_squared); } if( land_e1 )TNext=Triangles[Tstart].GetN1(); if( land_e2 )TNext=Triangles[Tstart].GetN2(); if( land_e3 )TNext=Triangles[Tstart].GetN3(); avecdash[0]=avec[TNext][0]; avecdash[1]=avec[TNext][1]; bvecdash[0]=bvec[TNext][0]; bvecdash[1]=bvec[TNext][1]; qStart=Triangles[Tstart].GetQuad(); qNext=Triangles[TNext].GetQuad(); // edge 1 always crosses into an edge 1 in the opposite sense if(land_e1){ alphaNext=1.0-alpha_e1; betaNext=0.0; start_e1=true; alpha_p=0.0; //edge 1 beta_p=0.0; alpha_q=1.0; beta_q=0.0; alpha_p_dash=alpha_q; // same edge, opposite sense beta_p_dash=beta_q; alpha_q_dash=alpha_p; beta_q_dash=beta_p; } // If the neighbour on edge 2 is in a different quad // it lands on edge 3, otherwise minus edge 2 if(land_e2){ alpha_p=0.0; beta_p=0.0; alpha_q=0.0; beta_q=1.0; if(qNext==qStart){ //crosses to edge 2 of neighbour- opposite sense betaNext=1.0-beta_e2; alphaNext=0.0; start_e2=true; alpha_p_dash=alpha_q; beta_p_dash=beta_q; alpha_q_dash=alpha_p; beta_q_dash=beta_p; } else { //crosses to edge 3 of neighbour- same sense. alphaNext=1.0-beta_e2; betaNext=beta_e2; start_e3=true; alpha_p_dash=1.0; beta_p_dash=0.0; alpha_q_dash=0.0; beta_q_dash=1.0; } } if(land_e3){ alpha_p=1.0; beta_p=0.0; alpha_q=0.0; beta_q=1.0; if(qNext==qStart){ //crosses to edge 3 of neighbour- opposite sense. alphaNext=1.0-alpha_e3; betaNext=alpha_e3; alpha_p_dash=alpha_q; beta_p_dash=beta_q; alpha_q_dash=alpha_p; beta_q_dash=beta_p; start_e3=true; } else { //crosses to edge 2 of neighbour -- has same sense alphaNext=0; betaNext=beta_e3; alpha_p_dash=0.0; beta_p_dash=0.0; alpha_q_dash=0.0; beta_q_dash=1.0; start_e2=true; } } cout << "ds_total=" << ds_total << endl; X1=alpha_p_dash*avecdash[0]+beta_p_dash*bvecdash[0]; X2=alpha_p_dash*avecdash[1]+beta_p_dash*bvecdash[1]; Y1=alpha_p*avec[Tstart][0]+beta_p*bvec[Tstart][0]; Y2=alpha_p*avec[Tstart][1]+beta_p*bvec[Tstart][1]; W1=alpha_q_dash*avecdash[0]+beta_q_dash*bvecdash[0]; W2=alpha_q_dash*avecdash[1]+beta_q_dash*bvecdash[1]; Z1=alpha_q*avec[Tstart][0]+beta_q*bvec[Tstart][0]; Z2=alpha_q*avec[Tstart][1]+beta_q*bvec[Tstart][1]; Det=(W2-X2)*(W2-X2)+(W1-X1)*(W1-X1); unsigned int ir,ic,ir1,ir2; ir=0; ic=0; Mat(ir,ic)=W1-X1; ir=0; ic=1; Mat(ir,ic)=W2-X2; ir=1; ic=0; Mat(ir,ic)=-(W2-X2); ir=1; ic=1; Mat(ir,ic)=W1-X1; Mat=Mat/Det; ir=0; RHS(ir)=Z1-Y1; ir=1; RHS(ir)=Z2-Y2; LHS=Mat*RHS; ir=0; CosTheta=LHS(ir); ir=1; SinTheta=LHS(ir); // cout << "cos and sin "<< CosTheta << " " << SinTheta << endl; // cout << "cossq+sinsq=" << CosTheta*CosTheta+SinTheta*SinTheta << endl; avecdash_new[0]= avecdash[0]*CosTheta-avecdash[1]*SinTheta; avecdash_new[1]= avecdash[0]*SinTheta+avecdash[1]*CosTheta; bvecdash_new[0]= bvecdash[0]*CosTheta-bvecdash[1]*SinTheta; bvecdash_new[1]= bvecdash[0]*SinTheta+bvecdash[1]*CosTheta; adot_adash=avec[Tstart][0]*avecdash_new[0] +avec[Tstart][1]*avecdash_new[1]; adot_bdash=avec[Tstart][0]*bvecdash_new[0] +avec[Tstart][1]*bvecdash_new[1]; bdot_adash=bvec[Tstart][0]*avecdash_new[0] +bvec[Tstart][1]*avecdash_new[1]; bdot_bdash=bvec[Tstart][0]*bvecdash_new[0] +bvec[Tstart][1]*bvecdash_new[1]; /* cout << adot_adash << " a dot adash " << avec[Tstart][0]*avecdash_new[0]+ avec[Tstart][1]*avecdash_new[1] << endl; cout << adot_bdash << " a dot bdash " << avec[Tstart][0]*bvecdash_new[0]+ avec[Tstart][1]*bvecdash_new[1] << endl; cout << bdot_adash << " b dot adash " << bvec[Tstart][0]*avecdash_new[0]+ bvec[Tstart][1]*avecdash_new[1] << endl; cout << bdot_bdash << " b dot bdash " << bvec[Tstart][0]*bvecdash_new[0]+ bvec[Tstart][1]*bvecdash_new[1] << endl; */ // The next couts all check out /* cout << " a dot a " << avec[Tstart][0]*avec[Tstart][0]+ avec[Tstart][1]*avec[Tstart][1] << endl; cout << " b dot b " << bvec[Tstart][0]*bvec[Tstart][0]+ bvec[Tstart][1]*bvec[Tstart][1] << endl; cout << " a dot a in Next " << avec[TNext][0]*avec[TNext][0]+ avec[TNext][1]*avec[TNext][1] << endl; cout << bdot_bdash << " b dot b in Next " << bvec[TNext][0]*bvec[TNext][0]+ bvec[TNext][1]*bvec[TNext][1] << endl; cout << "a " << avec[Tstart][0] << " " << avec[Tstart][1] << endl; cout << "b " << bvec[Tstart][0] << " " << bvec[Tstart][1] << endl; */ /* cout << "a dash " << avecdash[0] << " " << avecdash[1] << endl; cout << "b dash " << bvecdash[0] << " " << bvecdash[1] << endl; */ /* cout << "a dash rotate " << avecdash_new[0] << " " << avecdash_new[1] << endl; cout << "b dash rotate " << bvecdash_new[0] << " " << bvecdash_new[1] << endl; */ ir=0;ic=0; Mat(ir,ic)=Gmetric[Tstart][2]; ir=0;ic=1; Mat(ir,ic)=-Gmetric[Tstart][1]; ir=1;ic=0; Mat(ir,ic)=-Gmetric[Tstart][1]; ir=1;ic=1; Mat(ir,ic)=Gmetric[Tstart][0]; Det=Gmetric[Tstart][0]*Gmetric[Tstart][2] -Gmetric[Tstart][1]*Gmetric[Tstart][1]; Mat=Mat/Det; ir=0; RHS(ir)=adot_adash; ir=1; RHS(ir)=bdot_adash; LHS=Mat*RHS; ir=0; x1=LHS(ir); ir=1; y1=LHS(ir); ir=0; RHS(ir)=adot_bdash; ir=1; RHS(ir)=bdot_bdash; LHS=Mat*RHS; ir=0; x2=LHS(ir); ir=1; y2=LHS(ir); //check adash=x1 a + y1 b, bdash=x2 a+ y2 b cout << x1*avec[Tstart][0]+y1*bvec[Tstart][0] << " " << avecdash_new[0] << endl; cout << x1*avec[Tstart][1]+y1*bvec[Tstart][1] << " " << avecdash_new[1] << endl; cout << x2*avec[Tstart][0]+y2*bvec[Tstart][0] << " " << bvecdash_new[0] << endl; cout << x2*avec[Tstart][1]+y2*bvec[Tstart][1] << " " << bvecdash_new[1] << endl; ir=0;ic=0; Mat(ir,ic)=y2; ir=0;ic=1; Mat(ir,ic)=-x2; ir=1;ic=0; Mat(ir,ic)=-y1; ir=1;ic=1; Mat(ir,ic)=x1; Det=x1*y2-x2*y1; Mat=Mat/Det; cout << "M11=" << y2/Det << " M12=" << -x2/Det << endl; cout << "M21=" << -y1/Det << " M12=" << x1/Det << endl; ir=0; RHS(ir)=d1; ir=1; RHS(ir)=d2; LHS=Mat*RHS; ir=0; d1dash=LHS(ir); ir=1; d2dash=LHS(ir); // We have finally arrived in TNext, which will be the new Tstart; Tstart=TNext; alpha_start=alphaNext; beta_start=betaNext; d1=d1dash; d2=d2dash; } //end while ds_total Geokount=kount; cout << "Geokount=" << Geokount << endl; while(!quitit){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: quitit=true; break; case SDL_MOUSEBUTTONDOWN: mousedown=true; break; case SDL_MOUSEBUTTONUP: mousedown=false; break; case SDL_MOUSEMOTION: if(mousedown){ if(MouseOn)Camera1.MouseView();} else{ if(MouseOn)Camera1.MouseLookAt(); } break; case SDL_KEYDOWN: whatkey=&event.key.keysym; HandleKeyPress(whatkey); break; case SDL_KEYUP: whatkey=&event.key.keysym; HandleKeyRelease(whatkey); default: break; } // end of case } //end of inner loop CheckMove(Camera1); RenderScene(Camera1); } //end of outer loop }
void MeshEnergy::GetKappa( const std::vector<int>& C, const std::vector<double>& phi, std::valarray<double>& kappa) { // kappa: divergence of normal // dy^2 * dxx - 2dxdydxy + dx^2dyy / ( dx^2 + dy^2 )^(3/2) vtkPoints* verts = meshdata->polydata->GetPoints(); for( ::size_t k_ = 0; k_ < C.size(); k_++ )\ { int k = C[k_]; std::vector<double> nhat(3); nhat[0] = meshdata->nx[k]; // these are normal to surface; the nx_ are the contour normals nhat[1] = meshdata->ny[k]; nhat[2] = meshdata->nz[k]; // step 1. create the rotation matrix that orients the current normal as [0,0,1]'. double phiang = atan2( nhat[0], nhat[1] ); std::vector<double> rotate1(9); rotate1[0] = cos(phiang); rotate1[1] = -sin(phiang); rotate1[2] = 0; rotate1[3] = sin(phiang); rotate1[4] = cos(phiang); rotate1[5] = 0; rotate1[6] = 0; rotate1[7] = 0; rotate1[8] = 1.0; std::vector<double> nhat_a(3); pkmult( nhat, rotate1, nhat_a ); double ytilde = nhat_a[1]; double theta = M_PI_2 - atan2(nhat[2],ytilde); std::vector<double> rotate2(9); rotate2[0] = 1.0; rotate2[1] = 0; rotate2[2] = 0; rotate2[3] = 0; rotate2[4] = cos(theta); rotate2[5] = -sin(theta); rotate2[6] = 0; rotate2[7] = sin(theta); rotate2[8] = cos(theta); std::vector<double> nhat_b(3); pkmult( nhat_a, rotate2, nhat_b ); // nhat_b should now be [0 0 1]' double thispt[3]; verts->GetPoint( k, thispt ); // apply rotate2 * rotate1 to each *translated* neighbor of this k-th point ::size_t num_neigh = meshdata->adj[k].myNeighbs.size(); double vec[3]; std::vector<double> vv(3); std::vector<double> vv_(3); std::valarray<double> xdata(num_neigh); std::valarray<double> ydata(num_neigh); std::valarray<double> zdata(num_neigh); // step 2. create temporary set of std::vectors as copies of neighboring points // translated to origin // step 3. apply the rotation to all these points for (::size_t i = 0; i < num_neigh; i++ ) { int idx = meshdata->adj[k].myNeighbs[i]; verts->GetPoint( idx, vec ); vv[0] = vec[0] - thispt[0]; vv[1] = vec[1] - thispt[1]; vv[2] = vec[2] - thispt[2]; pkmult( vv, rotate1, vv_ ); pkmult( vv_, rotate2, vv ); xdata[i] = vv[0]; ydata[i] = vv[1]; zdata[i] = phi[idx] - phi[k]; //vv[2]; // zero reference phi at the vertex where we are forming tangent plane } /*if( abs(zdata).min() < 1e-6 ) continue;*/ // step 4. find first derivatives double phi_x = 0.0; double phi_y = 0.0; { std::valarray<double> RHS(2); std::valarray<double> ATA(4); ATA[0] = (xdata * xdata).sum(); ATA[1] = (xdata * ydata).sum(); ATA[2] = ATA[1]; ATA[3] = (ydata * ydata).sum(); RHS[0] = (xdata * zdata).sum(); RHS[1] = (ydata * zdata).sum(); int maxits = 1000; std::valarray<double> ab = RHS; // initial guess std::valarray<double> LHS(2); pkmult2( ab, ATA, LHS ); double res = sqrt( ( (LHS - RHS)*(LHS - RHS) ).sum() ); double tol = 1e-8; int iter = 0; while( iter < maxits && res > tol ) { iter++; ab[0] = (RHS[0] - ( ab[1]*ATA[1] ) )/ ATA[0]; ab[1] = (RHS[1] - ( ab[0]*ATA[2] ) )/ ATA[3]; pkmult2( ab, ATA, LHS ); res = sqrt( ( (LHS - RHS)*(LHS - RHS) ).sum() ); } phi_x = ab[0]; phi_y = ab[1]; } // step 4. find least-squares fit for phi(x,y) = ax^2 + bxy + cy^2 // to get second derivatives std::valarray<double> RHS(3); // A'z RHS[0] = ( xdata * xdata * zdata ).sum(); RHS[1] = ( xdata * ydata * zdata ).sum(); RHS[2] = ( ydata * ydata * zdata ).sum(); double tik_delta = 1e-1 * abs(RHS).min(); std::vector<double> ATA(9); // A'A ATA[0] = tik_delta + (xdata * xdata * xdata * xdata).sum(); ATA[1] = (xdata * xdata * xdata * ydata).sum(); ATA[2] = (xdata * xdata * ydata * ydata).sum(); ATA[3] = (xdata * ydata * xdata * xdata).sum(); ATA[4] = tik_delta + (xdata * ydata * xdata * ydata).sum(); ATA[5] = (xdata * ydata * ydata * ydata).sum(); ATA[6] = (ydata * ydata * xdata * xdata).sum(); ATA[7] = (ydata * ydata * xdata * ydata).sum(); ATA[8] = tik_delta + (ydata * ydata * ydata * ydata).sum(); int maxits = 1000; std::valarray<double> abc = RHS; // initial guess std::valarray<double> LHS(3); pkmult( abc, ATA, LHS ); double res = sqrt( ( (LHS - RHS)*(LHS - RHS) ).sum() ); double tol = 1e-8; int iter = 0; while( iter < maxits && res > tol ) { iter++; abc[0] = (RHS[0] - ( abc[1]*ATA[1] + abc[2]*ATA[2] ) )/ ATA[0]; abc[1] = (RHS[1] - ( abc[0]*ATA[3] + abc[2]*ATA[5] ) )/ ATA[4]; abc[2] = (RHS[2] - ( abc[0]*ATA[6] + abc[1]*ATA[7] ) )/ ATA[8]; pkmult( abc, ATA, LHS ); res = sqrt( ( (LHS - RHS)*(LHS - RHS) ).sum() ); } // step 5. get the derivatives from quadratic form double phi_xx = 2*abc[0]; double phi_xy = abc[1]; double phi_yy = 2*abc[2]; kappa[k_] = phi_y * phi_y * phi_xx - 2 * phi_x * phi_y * phi_xy + phi_x * phi_x * phi_yy; if( abs(phi_x) + abs(phi_y) > 1e-9 ) { kappa[k_] /= pow( (phi_x*phi_x + phi_y*phi_y), 1.5 ); } } }
// ====================================================================== bool TestContainer(string Type, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A) { int NumVectors = 3; int NumMyRows = A->NumMyRows(); Epetra_MultiVector LHS_exact(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); LHS_exact.Random(); LHS.PutScalar(0.0); A->Multiply(false, LHS_exact, RHS); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); if (verbose) { cout << "Container type = " << Type << endl; cout << "NumMyRows = " << NumMyRows << ", NumVectors = " << NumVectors << endl; } LHS.PutScalar(0.0); Teuchos::RefCountPtr<Ifpack_Container> Container; if (Type == "dense") Container = Teuchos::rcp( new Ifpack_DenseContainer(A->NumMyRows(), NumVectors) ); else Container = Teuchos::rcp( new Ifpack_SparseContainer<Ifpack_Amesos>(A->NumMyRows(), NumVectors) ); assert (Container != Teuchos::null); IFPACK_CHK_ERR(Container->Initialize()); // set as ID all the local rows of A for (int i = 0 ; i < A->NumMyRows() ; ++i) Container->ID(i) = i; // extract submatrix (in this case, the entire matrix) // and complete setup IFPACK_CHK_ERR(Container->Compute(*A)); // set the RHS and LHS for (int i = 0 ; i < A->NumMyRows() ; ++i) for (int j = 0 ; j < NumVectors ; ++j) { Container->RHS(i,j) = RHS[j][i]; Container->LHS(i,j) = LHS[j][i]; } // set parameters (empty for dense containers) Teuchos::ParameterList List; List.set("amesos: solver type", Type); IFPACK_CHK_ERR(Container->SetParameters(List)); // solve the linear system IFPACK_CHK_ERR(Container->ApplyInverse()); // get the computed solution, store it in LHS for (int i = 0 ; i < A->NumMyRows() ; ++i) for (int j = 0 ; j < NumVectors ; ++j) { LHS[j][i] = Container->LHS(i,j); } double residual = Galeri::ComputeNorm(&LHS, &LHS_exact); if (A->Comm().MyPID() == 0 && verbose) { cout << "||x_exact - x||_2 = " << residual << endl; cout << *Container; } bool passed = false; if (residual < 1e-5) passed = true; return(passed); }
void MeshEnergy::GetNormalsTangentPlane( const std::vector<int>& C, const std::vector<double>& phi, std::valarray<double>& ne1, std::valarray<double>& ne2, MeshData* vtkNotUsed(meshdata)) { vtkPoints* verts = meshdata->polydata->GetPoints(); for( ::size_t k_ = 0; k_ < C.size(); k_++ ) { int k = C[k_]; std::vector<double> nhat(3); nhat[0] = meshdata->nx[k]; // these are normal to surface; the nx_ are the contour normals nhat[1] = meshdata->ny[k]; nhat[2] = meshdata->nz[k]; // step 1. create the rotation matrix that orients the current normal as [0,0,1]'. double phiang = atan2( nhat[0], nhat[1] ); std::vector<double> rotate1(9); rotate1[0] = cos(phiang); rotate1[1] = -sin(phiang); rotate1[2] = 0; rotate1[3] = sin(phiang); rotate1[4] = cos(phiang); rotate1[5] = 0; rotate1[6] = 0; rotate1[7] = 0; rotate1[8] = 1.0; std::vector<double> nhat_a(3); pkmult( nhat, rotate1, nhat_a ); double ytilde = nhat_a[1]; double theta = M_PI_2 - atan2(nhat[2],ytilde); std::vector<double> rotate2(9); rotate2[0] = 1.0; rotate2[1] = 0; rotate2[2] = 0; rotate2[3] = 0; rotate2[4] = cos(theta); rotate2[5] = -sin(theta); rotate2[6] = 0; rotate2[7] = sin(theta); rotate2[8] = cos(theta); std::vector<double> nhat_b(3); pkmult( nhat_a, rotate2, nhat_b ); // nhat_b should now be [0 0 1]' double thispt[3]; verts->GetPoint( k, thispt ); // apply rotate2 * rotate1 to each *translated* neighbor of this k-th point ::size_t num_neigh = meshdata->adj[k].myNeighbs.size(); double vec[3]; std::vector<double> vv(3); std::vector<double> vv_(3); std::valarray<double> xdata(num_neigh); std::valarray<double> ydata(num_neigh); std::valarray<double> zdata(num_neigh); // step 2. create temporary set of std::vectors as copies of neighboring points // translated to origin // step 3. apply the rotation to all these points for ( ::size_t i = 0; i < num_neigh; i++ ) { int idx = meshdata->adj[k].myNeighbs[i]; verts->GetPoint( idx, vec ); vv[0] = vec[0] - thispt[0]; vv[1] = vec[1] - thispt[1]; vv[2] = vec[2] - thispt[2]; pkmult( vv, rotate1, vv_ ); pkmult( vv_, rotate2, vv ); xdata[i] = vv[0]; ydata[i] = vv[1]; zdata[i] = phi[idx] - phi[k]; //vv[2]; // zero reference phi at the vertex where we are forming tangent plane } /*if( abs(zdata).min() < 1e-6 ) continue;*/ // step 4. find least-squares fit for H(x,y) = ax + by std::valarray<double> RHS(2); std::valarray<double> ATA(4); ATA[0] = (xdata * xdata).sum(); ATA[1] = (xdata * ydata).sum(); ATA[2] = ATA[1]; ATA[3] = (ydata * ydata).sum(); RHS[0] = (xdata * zdata).sum(); RHS[1] = (ydata * zdata).sum(); int maxits = 1000; std::valarray<double> ab = RHS; // initial guess std::valarray<double> LHS(2); pkmult2( ab, ATA, LHS ); double res = sqrt( ( (LHS - RHS)*(LHS - RHS) ).sum() ); double tol = 1e-8; int iter = 0; while( iter < maxits && res > tol ) { iter++; ab[0] = (RHS[0] - ( ab[1]*ATA[1] ) )/ ATA[0]; ab[1] = (RHS[1] - ( ab[0]*ATA[2] ) )/ ATA[3]; pkmult2( ab, ATA, LHS ); res = sqrt( ( (LHS - RHS)*(LHS - RHS) ).sum() ); } ne1[k_] = ab[0] / sqrt( (ab*ab).sum() ); ne2[k_] = ab[1] / sqrt( (ab*ab).sum() ); // step 5. differentiate the plane along principal directions } }
// ====================================================================== bool ComparePointAndBlock(std::string PrecType, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A, int sweeps) { Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); // Set up the list Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: type", PrecType); List.set("relaxation: sweeps",sweeps); List.set("partitioner: type", "linear"); List.set("partitioner: local parts", A->NumMyRows()); int ItersPoint, ItersBlock; // ================================================== // // get the number of iterations with point relaxation // // ================================================== // { RHS.PutScalar(1.0); LHS.PutScalar(0.0); Ifpack_PointRelaxation Point(&*A); Point.SetParameters(List); Point.Compute(); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); if (verbose) AztecOOSolver.SetAztecOption(AZ_output,32); else AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Point); AztecOOSolver.Iterate(2550,1e-2); double TrueResidual = AztecOOSolver.TrueResidual(); ItersPoint = AztecOOSolver.NumIters(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Iterations = " << ItersPoint << endl; cout << "Norm of the true residual = " << TrueResidual << endl; } } // ================================================== // // get the number of iterations with block relaxation // // ================================================== // { RHS.PutScalar(1.0); LHS.PutScalar(0.0); Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > Block(&*A); Block.SetParameters(List); Block.Compute(); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); if (verbose) AztecOOSolver.SetAztecOption(AZ_output,32); else AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Block); AztecOOSolver.Iterate(2550,1e-2); double TrueResidual = AztecOOSolver.TrueResidual(); ItersBlock = AztecOOSolver.NumIters(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Iterations " << ItersBlock << endl; cout << "Norm of the true residual = " << TrueResidual << endl; } } int diff = ItersPoint - ItersBlock; if (diff < 0) diff = -diff; if (diff > 10) { if (verbose) cout << "ComparePointandBlock TEST FAILED!" << endl; return(false); } else { if (verbose) cout << "ComparePointandBlock TEST PASSED" << endl; return(true); } }
int Rossler::Events (realtype t, N_Vector x, realtype * event, void * data) { RHS(t,x,xderiv,data); for(int i=0; i<GetNumberOfEvents(); i++) event[i] = Ith(xderiv,i); return CV_SUCCESS; }
int main(int argc, char *argv[]) { // initialize MPI and Epetra communicator #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif Teuchos::ParameterList GaleriList; // The problem is defined on a 2D grid, global size is nx * nx. int nx = 30; GaleriList.set("nx", nx); GaleriList.set("ny", nx * Comm.NumProc()); GaleriList.set("mx", 1); GaleriList.set("my", Comm.NumProc()); Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap("Cartesian2D", Comm, GaleriList) ); Teuchos::RefCountPtr<Epetra_RowMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) ); // =============================================================== // // B E G I N N I N G O F I F P A C K C O N S T R U C T I O N // // =============================================================== // Teuchos::ParameterList List; // allocates an IFPACK factory. No data is associated // to this object (only method Create()). Ifpack Factory; // create the preconditioner. For valid PrecType values, // please check the documentation std::string PrecType = "Amesos"; int OverlapLevel = 2; // must be >= 0. If Comm.NumProc() == 1, // it is ignored. Teuchos::RefCountPtr<Ifpack_Preconditioner> Prec = Teuchos::rcp( Factory.Create(PrecType, &*A, OverlapLevel) ); assert(Prec != Teuchos::null); // specify the Amesos solver to be used. // If the selected solver is not available, // IFPACK will try to use Amesos' KLU (which is usually always // compiled). Amesos' serial solvers are: // "Amesos_Klu", "Amesos_Umfpack", "Amesos_Superlu" List.set("amesos: solver type", "Amesos_Klu"); // sets the parameters IFPACK_CHK_ERR(Prec->SetParameters(List)); // initialize the preconditioner. At this point the matrix must // have been FillComplete()'d, but actual values are ignored. // At this call, Amesos will perform the symbolic factorization. IFPACK_CHK_ERR(Prec->Initialize()); // Builds the preconditioners, by looking for the values of // the matrix. At this call, Amesos will perform the // numeric factorization. IFPACK_CHK_ERR(Prec->Compute()); // =================================================== // // E N D O F I F P A C K C O N S T R U C T I O N // // =================================================== // // At this point, we need some additional objects // to define and solve the linear system. // defines LHS and RHS Epetra_Vector LHS(A->OperatorDomainMap()); Epetra_Vector RHS(A->OperatorDomainMap()); // solution is constant LHS.PutScalar(1.0); // now build corresponding RHS A->Apply(LHS,RHS); // now randomize the solution RHS.Random(); // need an Epetra_LinearProblem to define AztecOO solver Epetra_LinearProblem Problem(&*A,&LHS,&RHS); // now we can allocate the AztecOO solver AztecOO Solver(Problem); // specify solver Solver.SetAztecOption(AZ_solver,AZ_gmres); Solver.SetAztecOption(AZ_output,32); // HERE WE SET THE IFPACK PRECONDITIONER Solver.SetPrecOperator(&*Prec); // .. and here we solve // NOTE: with one process, the solver must converge in // one iteration. Solver.Iterate(1550,1e-8); #ifdef HAVE_MPI MPI_Finalize() ; #endif return(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int Nnodes=32*32; /* Total number of nodes in the problem.*/ /* 'Nnodes' must be a perfect square. */ struct user_partition Edge_Partition = {NULL, NULL,0,0,NULL,0,0,0}, Node_Partition = {NULL, NULL,0,0,NULL,0,0,0}; int proc_config[AZ_PROC_SIZE]; #ifdef ML_MPI MPI_Init(&argc,&argv); #endif AZ_set_proc_config(proc_config, COMMUNICATOR); ML_Comm* comm; ML_Comm_Create(&comm); Node_Partition.Nglobal = Nnodes; Edge_Partition.Nglobal = Node_Partition.Nglobal*2; user_partition_nodes(&Node_Partition); user_partition_edges(&Edge_Partition, &Node_Partition); AZ_MATRIX * AZ_Ke = user_Ke_build(&Edge_Partition); AZ_MATRIX * AZ_Kn = user_Kn_build(&Node_Partition); // convert (put wrappers) from Aztec matrices to ML_Operator's ML_Operator * ML_Ke, * ML_Kn, * ML_Tmat; ML_Ke = ML_Operator_Create( comm ); ML_Kn = ML_Operator_Create( comm ); AZ_convert_aztec_matrix_2ml_matrix(AZ_Ke,ML_Ke,proc_config); AZ_convert_aztec_matrix_2ml_matrix(AZ_Kn,ML_Kn,proc_config); ML_Tmat = user_T_build(&Edge_Partition, &Node_Partition, ML_Kn, comm); Epetra_CrsMatrix * Epetra_Kn, * Epetra_Ke, * Epetra_T; int MaxNumNonzeros; double CPUTime; ML_Operator2EpetraCrsMatrix(ML_Ke,Epetra_Ke, MaxNumNonzeros, true,CPUTime); ML_Operator2EpetraCrsMatrix(ML_Kn, Epetra_Kn,MaxNumNonzeros, true,CPUTime); ML_Operator2EpetraCrsMatrix(ML_Tmat,Epetra_T,MaxNumNonzeros, true,CPUTime); Teuchos::ParameterList MLList; ML_Epetra::SetDefaults("maxwell", MLList); MLList.set("ML output", 0); MLList.set("aggregation: type", "Uncoupled"); MLList.set("coarse: max size", 30); MLList.set("aggregation: threshold", 0.0); MLList.set("coarse: type", "Amesos-KLU"); ML_Epetra::MultiLevelPreconditioner * MLPrec = new ML_Epetra::MultiLevelPreconditioner(*Epetra_Ke, *Epetra_T, *Epetra_Kn, MLList); Epetra_Vector LHS(Epetra_Ke->DomainMap()); LHS.Random(); Epetra_Vector RHS(Epetra_Ke->DomainMap()); RHS.PutScalar(1.0); Epetra_LinearProblem Problem(Epetra_Ke,&LHS,&RHS); AztecOO solver(Problem); solver.SetPrecOperator(MLPrec); solver.SetAztecOption(AZ_solver, AZ_cg_condnum); solver.SetAztecOption(AZ_output, 32); solver.Iterate(500, 1e-8); // ========================= // // compute the real residual // // ========================= // Epetra_Vector RHScomp(Epetra_Ke->DomainMap()); int ierr; ierr = Epetra_Ke->Multiply(false, LHS, RHScomp); assert(ierr==0); Epetra_Vector resid(Epetra_Ke->DomainMap()); ierr = resid.Update(1.0, RHS, -1.0, RHScomp, 0.0); assert(ierr==0); double residual; ierr = resid.Norm2(&residual); assert(ierr==0); if (proc_config[AZ_node] == 0) { std::cout << std::endl; std::cout << "==> Residual = " << residual << std::endl; std::cout << std::endl; } // =============== // // C L E A N U P // // =============== // delete MLPrec; // destroy phase prints out some information delete Epetra_Kn; delete Epetra_Ke; delete Epetra_T; ML_Operator_Destroy( &ML_Ke ); ML_Operator_Destroy( &ML_Kn ); ML_Comm_Destroy( &comm ); if (Edge_Partition.my_local_ids != NULL) free(Edge_Partition.my_local_ids); if (Node_Partition.my_local_ids != NULL) free(Node_Partition.my_local_ids); if (Node_Partition.my_global_ids != NULL) free(Node_Partition.my_global_ids); if (Edge_Partition.my_global_ids != NULL) free(Edge_Partition.my_global_ids); if (Node_Partition.needed_external_ids != NULL) free(Node_Partition.needed_external_ids); if (Edge_Partition.needed_external_ids != NULL) free(Edge_Partition.needed_external_ids); if (AZ_Ke!= NULL) { AZ_free(AZ_Ke->bindx); AZ_free(AZ_Ke->val); AZ_free(AZ_Ke->data_org); AZ_matrix_destroy(&AZ_Ke); } if (AZ_Kn!= NULL) { AZ_free(AZ_Kn->bindx); AZ_free(AZ_Kn->val); AZ_free(AZ_Kn->data_org); AZ_matrix_destroy(&AZ_Kn); } ML_Operator_Destroy(&ML_Tmat); if (residual > 1e-5) { std::cout << "`MultiLevelPreconditioner_Maxwell.exe' failed!" << std::endl; exit(EXIT_FAILURE); } #ifdef ML_MPI MPI_Finalize(); #endif if (proc_config[AZ_node] == 0) std::cout << "`MultiLevelPreconditioner_Maxwell.exe' passed!" << std::endl; exit(EXIT_SUCCESS); }