Пример #1
0
/**
In order to do so, first a reasonable dt for stability is calculated and F,G,RHS are evaluated.
Afterwards, the Poisson pressure equation is solved and the velocitys are updated.
\param[in] printInfo boolean if additional informations on the fields and rediduum of p are printed
\param[in] verbose boolean if debbuging information should be printed (standard: false)
*/
void Compute::TimeStep(bool printInfo, bool verbose=false)
{
	// TODO: test
	
	// compute dt
	if (verbose) std::cout << "Computing the timestep width..." << std::flush; // only for debugging issues
	real_t dt = compute_dt();
	if (verbose) std::cout << "Done.\n" << std::flush; // only for debugging issues
	
	// compute F, G
	MomentumEqu(dt);
	update_boundary_values(); //update boundary values
	
	// compute rhs
	RHS(dt);
	
	// solve Poisson equation
	real_t residual(_epslimit + 1.0);
	index_t iteration(0);
	//while (iteration <= _param->IterMax() && residual > _epslimit){
	while (true){
		// one solver cycle is done here
		residual = _solver->Cycle(_p, _rhs);

		iteration++;
		if (iteration > _param->IterMax()){
			//if (printInfo) {
				std::cout << "Warning: Solver did not converge! Residual: " << residual << "\n";
			//}
			break;
		} else if (residual < _epslimit){
			//if (printInfo) {
				std::cout << "Solver converged after " << iteration << " timesteps. Residual: " << residual << "\n";
			//}
			break;
		}
	}
	
	// compute new velocitys u, v
	NewVelocities(dt);
	update_boundary_values();

	//update total time
	_t += dt;

	// print information
	if (printInfo){
		std::cout << "============================================================\n";
		// total simulated time
		std::cout << "Total simulated time: t = " << _t << "\n";
		// timestep
		std::cout << "Last timestep: dt = " << dt << "\n";
		// magnitudes of the fields
		std::cout << "max(F) = " << _F->AbsMax() << ", max(G) = " << _G->AbsMax() << ", max(rhs) = " << _rhs->AbsMax() << "\n";
		std::cout << "max(u) = " << _u->AbsMax() << ", max(v) = " << _v->AbsMax() << ", max(p) = " << _p->AbsMax() << "\n";
		//std::cout << "Average value of rhs: " << _rhs->average_value() << "\n";
		std::cout << "============================================================\n";
	}
}
Пример #2
0
int
main (int argc, char* argv[])
{
    BoxLib::Initialize(argc,argv);

    // What time is it now?  We'll use this to compute total run time.
    Real strt_time = ParallelDescriptor::second();

    std::cout << std::setprecision(15);

    // ParmParse is way of reading inputs from the inputs file
    ParmParse pp;
    
    int verbose = 0;
    pp.query("verbose", verbose);
    
    // We need to get n_cell from the inputs file - this is the number of cells on each side of 
    //   a square (or cubic) domain.
    int n_cell;
    pp.get("n_cell",n_cell);

    int max_grid_size;
    pp.get("max_grid_size",max_grid_size);

    // Default plot_int to 1, allow us to set it to something else in the inputs file
    //  If plot_int < 0 then no plot files will be written
    int plot_int = 1;
    pp.query("plot_int",plot_int);

    // Default nsteps to 0, allow us to set it to something else in the inputs file
    int nsteps   = 0;
    pp.query("nsteps",nsteps);

    pp.query("do_tiling", do_tiling);

    // Define a single box covering the domain
    IntVect dom_lo(0,0,0);
    IntVect dom_hi(n_cell-1,n_cell-1,n_cell-1);
    Box domain(dom_lo,dom_hi);

    // Initialize the boxarray "bs" from the single box "bx"
    BoxArray bs(domain);

    // Break up boxarray "bs" into chunks no larger than "max_grid_size" along a direction
    bs.maxSize(max_grid_size);

    // This defines the physical size of the box.  Right now the box is [-1,1] in each direction.
    RealBox real_box;
    for (int n = 0; n < BL_SPACEDIM; n++) {
	real_box.setLo(n,-1.0);
	real_box.setHi(n, 1.0);
    }

    // This says we are using Cartesian coordinates
    int coord = 0;
    
    // This sets the boundary conditions to be doubly or triply periodic
    int is_per[BL_SPACEDIM];
    for (int i = 0; i < BL_SPACEDIM; i++) is_per[i] = 1; 
    
    // This defines a Geometry object which is useful for writing the plotfiles  
    Geometry geom(domain,&real_box,coord,is_per);

    // This defines the mesh spacing
    Real dx[BL_SPACEDIM];
    for ( int n=0; n<BL_SPACEDIM; n++ )
	dx[n] = ( geom.ProbHi(n) - geom.ProbLo(n) )/domain.length(n);

    // Nghost = number of ghost cells for each array 
    int Nghost = 1;

    // Ncomp = number of components for each array
    int Ncomp  = 1;
    pp.query("ncomp", Ncomp);

    // Allocate space for the old_phi and new_phi -- we define old_phi and new_phi as
    PArray < MultiFab > phis(2, PArrayManage);
    phis.set(0, new MultiFab(bs, Ncomp, Nghost));
    phis.set(1, new MultiFab(bs, Ncomp, Nghost));
    MultiFab* old_phi = &phis[0];
    MultiFab* new_phi = &phis[1];

    // Initialize both to zero (just because)
    old_phi->setVal(0.0);
    new_phi->setVal(0.0);

    // Initialize phi by calling a Fortran routine.
    // MFIter = MultiFab Iterator
#ifdef _OPENMP
#pragma omp parallel
#endif
    for ( MFIter mfi(*new_phi,true); mfi.isValid(); ++mfi )
    {
	const Box& bx = mfi.tilebox();

	init_phi(bx.loVect(),bx.hiVect(), 
		 BL_TO_FORTRAN((*new_phi)[mfi]),Ncomp,
		 dx,geom.ProbLo(),geom.ProbHi());
    }

    // Call the compute_dt routine to return a time step which we will pass to advance
    Real dt = compute_dt(dx[0]);

    // Write a plotfile of the initial data if plot_int > 0 (plot_int was defined in the inputs file)
    if (plot_int > 0) {
	int n = 0;
	const std::string& pltfile = BoxLib::Concatenate("plt",n,5);
	writePlotFile(pltfile, *new_phi, geom);
    }

    Real adv_start_time = ParallelDescriptor::second();

    for (int n = 1; n <= nsteps; n++)
    {
	// Swap the pointers so we don't have to allocate and de-allocate data
	std::swap(old_phi, new_phi);

	// new_phi = old_phi + dt * (something)
	advance(old_phi, new_phi, dx, dt, geom); 

	// Tell the I/O Processor to write out which step we're doing
	if (verbose && ParallelDescriptor::IOProcessor())
	    std::cout << "Advanced step " << n << std::endl;

	// Write a plotfile of the current data (plot_int was defined in the inputs file)
	if (plot_int > 0 && n%plot_int == 0) {
	    const std::string& pltfile = BoxLib::Concatenate("plt",n,5);
	    writePlotFile(pltfile, *new_phi, geom);
	}
    }

    // Call the timer again and compute the maximum difference between the start time and stop time
    //   over all processors
    Real advance_time = ParallelDescriptor::second() - adv_start_time;
    Real stop_time = ParallelDescriptor::second() - strt_time;
    const int IOProc = ParallelDescriptor::IOProcessorNumber();
    ParallelDescriptor::ReduceRealMax(stop_time,IOProc);
    ParallelDescriptor::ReduceRealMax(advance_time,IOProc);
    ParallelDescriptor::ReduceRealMax(kernel_time,IOProc);
    ParallelDescriptor::ReduceRealMax(FB_time,IOProc);
    
    // Tell the I/O Processor to write out the "run time"
    if (ParallelDescriptor::IOProcessor()) {
	std::cout << "Kernel    time = " << kernel_time << std::endl;
	std::cout << "FB        time = " << FB_time << std::endl;
	std::cout << "Advance   time = " << advance_time << std::endl;
	std::cout << "Total run time = " << stop_time << std::endl;
    }
    
    // Say goodbye to MPI, etc...
    BoxLib::Finalize();
}
Пример #3
0
int
main (int argc, char* argv[])
{
  BoxLib::Initialize(argc,argv);

  // What time is it now?  We'll use this to compute total run time.
  Real strt_time = ParallelDescriptor::second();

  std::cout << std::setprecision(15);

  // ParmParse is way of reading inputs from the inputs file
  ParmParse pp;

  // We need to get n_cell from the inputs file - this is the number of cells on each side of 
  //   a square (or cubic) domain.
  int n_cell;
  pp.get("n_cell",n_cell);

  // Default nsteps to 0, allow us to set it to something else in the inputs file
  int max_grid_size;
  pp.get("max_grid_size",max_grid_size);

  // Default plot_int to 1, allow us to set it to something else in the inputs file
  //  If plot_int < 0 then no plot files will be written
  int plot_int = 1;
  pp.query("plot_int",plot_int);

  // Default nsteps to 0, allow us to set it to something else in the inputs file
  int nsteps   = 0;
  pp.query("nsteps",nsteps);

  // Define a single box covering the domain
#if (BL_SPACEDIM == 2)
  IntVect dom_lo(0,0);
  IntVect dom_hi(n_cell-1,n_cell-1);
#else
  IntVect dom_lo(0,0,0);
  IntVect dom_hi(n_cell-1,n_cell-1,n_cell-1);
#endif
  Box domain(dom_lo,dom_hi);

  // Initialize the boxarray "bs" from the single box "bx"
  BoxArray bs(domain);

  // Break up boxarray "bs" into chunks no larger than "max_grid_size" along a direction
  bs.maxSize(max_grid_size);

  // This defines the physical size of the box.  Right now the box is [-1,1] in each direction.
  RealBox real_box;
  for (int n = 0; n < BL_SPACEDIM; n++)
  {
     real_box.setLo(n,-1.0);
     real_box.setHi(n, 1.0);
  }

  // This says we are using Cartesian coordinates
  int coord = 0;

  // This sets the boundary conditions to be doubly or triply periodic
  int is_per[BL_SPACEDIM];
  for (int i = 0; i < BL_SPACEDIM; i++) is_per[i] = 1; 

  // This defines a Geometry object which is useful for writing the plotfiles  
  Geometry geom(domain,&real_box,coord,is_per);

  // This defines the mesh spacing
  Real dx[BL_SPACEDIM];
  for ( int n=0; n<BL_SPACEDIM; n++ )
      dx[n] = ( geom.ProbHi(n) - geom.ProbLo(n) )/domain.length(n);

  // Nghost = number of ghost cells for each array 
  int Nghost = 1;

  // Ncomp = number of components for each array
  int Ncomp  = 1;

  // Make sure we can fill the ghost cells from the adjacent grid
  if (Nghost > max_grid_size)
    std::cout <<  "NGHOST < MAX_GRID_SIZE --  grids are too small! " << std::endl;

  // Allocate space for the old_phi and new_phi -- we define old_phi and new_phi as
  //   pointers to the MultiFabs
  MultiFab* old_phi = new MultiFab(bs, Ncomp, Nghost);
  MultiFab* new_phi = new MultiFab(bs, Ncomp, Nghost);

  // Initialize both to zero (just because)
  old_phi->setVal(0.0);
  new_phi->setVal(0.0);

  // Initialize the old_phi by calling a Fortran routine.
  // MFIter = MultiFab Iterator
  for ( MFIter mfi(*new_phi); mfi.isValid(); ++mfi )
  {
    const Box& bx = mfi.validbox();

    FORT_INIT_PHI((*new_phi)[mfi].dataPtr(),
                     bx.loVect(),bx.hiVect(), &Nghost,
                     dx,geom.ProbLo(),geom.ProbHi());
  }

  // Call the compute_dt routine to return a time step which we will pass to advance
  Real dt = compute_dt(dx[0]);

  // Write a plotfile of the initial data if plot_int > 0 (plot_int was defined in the inputs file)
  if (plot_int > 0)
  {
     int n = 0;
     const std::string& pltfile = BoxLib::Concatenate("plt",n,5);
     writePlotFile(pltfile, *new_phi, geom);
  }

  // build the flux multifabs
  MultiFab* flux = new MultiFab[BL_SPACEDIM];
  for (int dir = 0; dir < BL_SPACEDIM; dir++)
    {
      BoxArray edge_grids(bs);
      // flux(dir) has one component, zero ghost cells, and is nodal in direction dir
      edge_grids.surroundingNodes(dir);
      flux[dir].define(edge_grids,1,0,Fab_allocate);
    }

  for (int n = 1; n <= nsteps; n++)
  {
     // Swap the pointers so we don't have to allocate and de-allocate data
     std::swap(old_phi, new_phi);

     // new_phi = old_phi + dt * (something)
     advance(old_phi, new_phi, flux, dx, dt, geom); 

     // Tell the I/O Processor to write out which step we're doing
     if (ParallelDescriptor::IOProcessor())
        std::cout << "Advanced step " << n << std::endl;

     // Write a plotfile of the current data (plot_int was defined in the inputs file)
     if (plot_int > 0 && n%plot_int == 0)
     {
        const std::string& pltfile = BoxLib::Concatenate("plt",n,5);
        writePlotFile(pltfile, *new_phi, geom);
     }
  }

  // Call the timer again and compute the maximum difference between the start time and stop time
  //   over all processors
  Real stop_time = ParallelDescriptor::second() - strt_time;
  const int IOProc = ParallelDescriptor::IOProcessorNumber();
  ParallelDescriptor::ReduceRealMax(stop_time,IOProc);

  // Tell the I/O Processor to write out the "run time"
  if (ParallelDescriptor::IOProcessor())
     std::cout << "Run time = " << stop_time << std::endl;
  
  // Say goodbye to MPI, etc...
  BoxLib::Finalize();

}