Example #1
0
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);
}
Example #3
0
// ====================================================================== 
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);
  }
}
Example #4
0
 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);
}
Example #8
0
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 );
}
Example #12
0
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;
}
Example #13
0
        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);
        }
Example #14
0
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 );
}
Example #16
0
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;
}
Example #18
0
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

}
Example #19
0
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 );
      }
    }
}
Example #20
0
// ======================================================================
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);
}
Example #21
0
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

    }

}
Example #22
0
// ====================================================================== 
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);
  }
}
Example #23
0
 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);
		
}