예제 #1
0
GrayScott::GrayScott(int N, double L, double dt, double Du, double Dv, double F, double k, int nSteps, std::string pngname)
    : N_(N)
    , Ntot_(N*N)
//    , L_(L)
    , dx_((double) L / (double) N)
    , dt_(dt)
    , nSteps_(nSteps)
    , currStep_(0)
    , Du_(Du)
    , Dv_(Dv)
    , F_(F)
    , k_(k)
    , matU1_(N, -Du*dt/(2.*dx_*dx_), 1.+Du*dt/(dx_*dx_), -Du*dt/(2.*dx_*dx_))
    , matU2_(N, -Du*dt/(2.*dx_*dx_), 1.+Du*dt/(dx_*dx_), -Du*dt/(2.*dx_*dx_)) // equal to matU1_, since we have a square grid (dx==dy)
    , matV1_(N, -Dv*dt/(2.*dx_*dx_), 1.+Dv*dt/(dx_*dx_), -Dv*dt/(2.*dx_*dx_))
    , matV2_(N, -Dv*dt/(2.*dx_*dx_), 1.+Dv*dt/(dx_*dx_), -Dv*dt/(2.*dx_*dx_))
    , pngName_(pngname)
{
    // create directory to save output to
    time_t rawtime;
	struct tm * timeinfo;
	char buffer[80];
	time (&rawtime);
	timeinfo = localtime(&rawtime);
	strftime(buffer,80,"%d-%m-%Y_%H-%M-%S",timeinfo);
	std::string timeString(buffer);
	
	dirPath_ = "data/" + timeString + "/";
	
	boost::filesystem::path dir(dirPath_);
	boost::filesystem::create_directory(dir);
    
    initialize_fields();
}
예제 #2
0
/**
 * \brief Sets the type of this entity.
 *
 * When the type changes, all fields are reset to their default value.
 *
 * \param type The new type.
 */
void EntityData::set_type(EntityType type) {

    if (type == this->type) {
        return;
    }

    this->type = type;
    initialize_fields();
}
예제 #3
0
/**
 * \brief Creates data for an entity of the given type.
 * \param type A type of entity.
 */
EntityData::EntityData(EntityType type) :
    type(type),
    name(),
    layer(0),
    xy(),
    fields() {

    initialize_fields();
}
예제 #4
0
/**
 * \brief Creates data for an entity of a default-constructed type.
 */
EntityData::EntityData() :
    type(),
    name(),
    layer(LAYER_LOW),
    xy(),
    fields() {

  initialize_fields();
}
예제 #5
0
int main (int argc, char ** argv)
{
  int i;
    
  /*
   *  this is set to either euler or runge_kutta_4
   */
  enum solver_t solver;

  /*
   *  bc (boundary condition) can be either periodic or no_slip
   */
  enum bc_t bc;

  /*
   * these specify the geometry of the area to be simulated 
   * tdim ist the total number of points, i.e. tdim = xdim *ydim 
   */
  int xdim, ydim, tdim;
  double dx, dy;

  /*
   * this holds the neighbors 
   */
  int **neighbors;

  /*
   * this holds latitude and longitude values of each point
   */
  unsigned int *lat, *lon;

  /*
   * this holds order of the data to be printed out
   */
  unsigned int *print_out_order;

  /*
   * these control temporal aspects of the simulation 
   */
  long int ncycle;
  double dt = 5.1;
  long int n_iter = 25800;
  int write_out_interval = 5000;

  /*
   * these hold the physical parameters 
   *
   * f0:              coriolis parameter (1/1sec)
   * beta:            linear beta for coriolis force (1/(meter sec))
   * forcingTerm:     Wind stress amplitude "tau_0"(N/meter^2)
   * dissipationTerm: "A" viscosity coefficient (meters^2/sec)
   * RayleighFriction: Rayleigh friction parameter (1/sec)
   */
  double f0 = 5.0e-5;
  double beta =2e-11;
  double forcingTerm = 0.0005;
  double dissipationTerm = 0.00005;
  double RayleighFriction = 5e-8;

  /*
   * upper layer equilibrium depth (meters)
   */
  double EquilibriumDepth = 50000.0;
  double A;

  /*
   * this holds the physical parameters and the forcing
   */
  double *parameters;
  double *x_forcing, *y_forcing, *z_forcing;

  /*
   * "fields" holds the values of the u, v and P fields
   */
  double *fields;
  double *u, *v, *P;     

  /*
   * "fields_prev" holds the u, v and P values of the previous time step
   */
  //double *fields_prev;
  //double *u_prev, *v_prev, *P_prev;     

  /*
   * these are temporary storage locations 
   * for the Runge-Kutta scheme
   */
  double *temp_dots_rk;
  double *temp_fields_rk;

  /*
   * read parameters from command line
   */
  if(argc == 2){

    get_parameters(argv[1], &xdim, &ydim, &dx, &dy, &n_iter, &dt, &write_out_interval, &bc, &solver, &f0, &beta, &forcingTerm, &dissipationTerm, &RayleighFriction, &EquilibriumDepth, &A);

  }
  else{

    fprintf(stderr, "ERROR: You need to give a file containing the parameters as an argument!\n");
    exit(1);

  }

  print_parameters(xdim, ydim, dx, dy, n_iter, dt, write_out_interval, bc, solver, f0, beta, forcingTerm, dissipationTerm, RayleighFriction, EquilibriumDepth, A);

  tdim = xdim*ydim;

  /*
   *  allocate arrays containing geometrical information and fill these
   */
  lat = calloc(tdim, sizeof(unsigned int)); 
  lon = calloc(tdim, sizeof(unsigned int)); 
  print_out_order = calloc(tdim, sizeof(unsigned int)); 
  neighbors = calloc(tdim, sizeof(int*)); 
  for(i=0; i< tdim; i++){
    neighbors[i] = calloc(4, sizeof(int));
  }

  initialize_geometry(xdim, ydim, neighbors, lat, lon, print_out_order);

  /*
   * allocate memory for physical parameters and forcing
   */
  parameters = calloc(5+3*tdim, sizeof(double));

  parameters[0] = f0;
  parameters[1] = beta;
  parameters[2] = forcingTerm;
  parameters[3] = dissipationTerm;
  parameters[4] = RayleighFriction;

  x_forcing = parameters + 5;
  y_forcing = parameters + 5 + tdim;
  z_forcing = parameters + 5 + 2*tdim;

  /*
   * allocate "fields" and set addresses for u, v, and P
   */
  fields = calloc(3*tdim, sizeof(double));
  u = fields;
  v = fields + tdim;
  P = fields + 2 * tdim;

  /*
   * allocate "fields_prev" and set addresses for u_prev, v_prev, and P_prev
   */
  //fields_prev = calloc(3*tdim, sizeof(double));
  //u_prev = fields_prev;
  //v_prev = fields_prev + tdim;
  //P_prev = fields_prev + 2 * tdim;

  double *fields_dot;
  fields_dot = calloc(3*tdim, sizeof(double));

  /*
   * allocate memory for temporary Runge-Kutta storage locations 
   */
  temp_dots_rk = calloc(3*tdim, sizeof(double));
  temp_fields_rk = calloc(3*tdim, sizeof(double));

  /*
   * initialize fields
   */
  initialize_fields (u, v, P, x_forcing, y_forcing, z_forcing, xdim, ydim, dx, dy, EquilibriumDepth, A, neighbors, lat, lon, bc);

  /*
   *  loop through time steps to do the actual simulation
   */
  for (ncycle=0; ncycle<n_iter; ncycle++) {
    //printf("step #%li\n", ncycle);

    /*
     * print result
     */
    if(ncycle % write_out_interval == 0){
      print_field(u, "u", ncycle, xdim, ydim, print_out_order);
      print_field(v, "v", ncycle, xdim, ydim, print_out_order);
      print_field(P, "P", ncycle, xdim, ydim, print_out_order);
      printf("%li ", ncycle);
      fflush(stdout);
    }
    Fcalc(fields_dot, fields, parameters, xdim, ydim, dx, dy, neighbors, lat, bc, print_out_order, ncycle);
 

    //for (i=0;i<3*tdim;i++) {
    //  fields_prev[i] = fields[i];
    //}

    if(solver == runge_kutta_4){

      /*
       *  Runge-Kutta 4th order
       *
       *                 dt
       *    y_1 = y_0 + ---- (y'_0 + 2 * y'_A + 2 * y'_B +y'_C)
       *                  6
       */

      /*                          dt
       * first step: y_A = y_0 + ---- y'_0
       *                          2
       */
      for (i=0; i < 3*tdim;  i++) {
        temp_fields_rk[i] = fields[i]+0.5*dt*fields_dot[i];
      }
      Fcalc(temp_dots_rk, temp_fields_rk, parameters, xdim, ydim, dx, dy, neighbors, lat, bc, print_out_order, ncycle);
      for (i=0; i < 3*tdim;  i++) {
        fields_dot[i] += 2*temp_dots_rk[i];
      }

      /*                           dt
       * second step: y_B = y_0 + ---- y'_A
       *                            2
       */
      for (i=0; i < 3*tdim;  i++) {
        temp_fields_rk[i] = fields[i]+0.5*dt*temp_dots_rk[i];
      }
      Fcalc(temp_dots_rk, temp_fields_rk, parameters, xdim, ydim, dx, dy, neighbors, lat, bc, print_out_order, ncycle);
      for (i=0; i < 3*tdim;  i++) {
        fields_dot[i] += 2*temp_dots_rk[i];
      }

      /*
       * third step: y_C = y_0 + dt * y'_B
       */
      for (i=0; i < 3*tdim;  i++){
        temp_fields_rk[i] = fields[i]+dt*temp_dots_rk[i];
      }
      Fcalc(temp_dots_rk, temp_fields_rk, parameters, xdim, ydim, dx, dy, neighbors, lat, bc, print_out_order, ncycle);
      for (i=0; i < 3*tdim;  i++) {
        fields_dot[i] += temp_dots_rk[i];
      }

      /*                          dt
       * final step: y_1 = y_0 + ---- (y'_0 + 2 * y'_A + 2 * y'_B +y'_C)
       *                           6
       */
      for (i=0; i < 3*tdim;  i++) {
        fields_dot[i] /= 6.0;
        fields[i] += dt*fields_dot[i];
      }
    }
    else{

      if(solver == euler){

        /*
         *  the Euler scheme
         */
        for (i=0; i < 3*tdim;  i++) {
          fields[i] += dt*fields_dot[i];
        }
      }
      else{
        fprintf(stderr, "ERROR: No valid solver was found\n");
        exit(2);
      }
    }
  }
  printf("\n");

  return(0);
}
예제 #6
0
GrayScott::GrayScott(int N, double rmin, double rmax, double dt, double Du, double Dv, double F, double k, int nSteps, std::string pngname, world_info w, bool localtranspose, unsigned int nthreads)
    : N_(N)
    , Ntot_(N*N)
//    , L_(L)
    , dx_((double) (rmax-rmin) / (double) (N-1))
    , dt_(dt)//(dx_*dx_ / (2.*std::max(Du,Dv)))
    , nSteps_(nSteps)
    , currStep_(0)
    , Du_(Du)
    , Dv_(Dv)
    , uCoeff(Du_*dt_/(2.*dx_*dx_))
    , vCoeff(Dv_*dt_/(2.*dx_*dx_))
    , F_(F)
    , k_(k)
    , matU1_(N, -Du*dt/(2.*dx_*dx_), 1.+Du*dt/(dx_*dx_), -Du*dt/(2.*dx_*dx_))
//    , matU2_(N, -Du*dt/(2.*dx_*dx_), 1.+Du*dt/(dx_*dx_), -Du*dt/(2.*dx_*dx_)) // equal to matU1_, since we have a square grid (dx==dy)
    , matV1_(N, -Dv*dt/(2.*dx_*dx_), 1.+Dv*dt/(dx_*dx_), -Dv*dt/(2.*dx_*dx_))
//    , matV2_(N, -Dv*dt/(2.*dx_*dx_), 1.+Dv*dt/(dx_*dx_), -Dv*dt/(2.*dx_*dx_))
    , pngName_(pngname)
    , world(w)
    , rmin_(rmin)
    , rmax_(rmax)
    , localtranspose_(localtranspose)
    , nthreads_(nthreads)
{
    if (world.rank == 0) {
        // create directory to save output to
        time_t rawtime;
        struct tm * timeinfo;
        char buffer[80];
        time (&rawtime);
        timeinfo = localtime(&rawtime);
        strftime(buffer,80,"%d-%m-%Y_%H-%M-%S",timeinfo);
        std::string timeString(buffer);
	
        dirPath_ = "data/" + timeString + "/";
	
        boost::filesystem::path dir(dirPath_);
//        boost::filesystem::create_directory(dir);
    }
    
    
    
    
    // global grid
    Nx_glo = N;
    Ny_glo = N;
    NN_glo = Nx_glo * Ny_glo;
    
    // local grid
    Nx_loc = Nx_glo / world.dims_x;
    Ny_loc = Ny_glo / world.dims_y;
    NN_loc = Nx_loc * Ny_loc;
    
    Nb_loc = Ny_loc/Nx_loc;
    
    
    
    // build process geometry with cartesian communicator
    int periods[2] = {false, false};
    int dims[2] = {world.dims_x, world.dims_y};
    
    MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, true, &cart_comm);
    
    MPI_Comm_rank(cart_comm, &world.cart_rank);
    
    MPI_Cart_shift(cart_comm, 0, 1, &world.top_proc, &world.bottom_proc);
    
    int coords[2];
    MPI_Cart_coords(cart_comm, world.cart_rank, 2, coords);
    
    world.coord_x = coords[0];
    world.coord_y = coords[1];
    
    
    
    // datatypes
    
    // build contiguous (rows) vectors for boundaries.
    // each process has multiple rows in the grid
    MPI_Type_contiguous(Ny_loc, MPI_DOUBLE, &bottom_boundary);
    MPI_Type_commit(&bottom_boundary);
    
    MPI_Type_contiguous(Ny_loc, MPI_DOUBLE, &top_boundary);
    MPI_Type_commit(&top_boundary);
    
    
    // build datatypes for transpose
    MPI_Datatype block_send, block_col, block_recv;
    
    // send datatype
    int sizes[2]    = {Nx_loc, Ny_loc}; // size of global array
    int subsizes[2] = {Nx_loc, Nx_loc}; // size of sub-region (square)
    int starts[2]   = {0,0};            // where does the first subarray begin (which index)
    
    MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_DOUBLE, &block_send);
    MPI_Type_commit(&block_send);

    // resize -> make contiguous
    MPI_Type_create_resized(block_send, 0, Nx_loc*sizeof(double), &block_resized_send);
    MPI_Type_free(&block_send);
    MPI_Type_commit(&block_resized_send);
    
    
    // receive datatype
    MPI_Type_vector(Nx_loc, 1, Ny_loc, MPI_DOUBLE, &block_col);
    MPI_Type_commit(&block_col);
    MPI_Type_hvector(Nx_loc, 1, sizeof(double), block_col, &block_recv);
    MPI_Type_free(&block_col);
    MPI_Type_commit(&block_recv);

    // resize data structure, so that it is contigious (for alltoall)
    MPI_Type_create_resized(block_recv, 0, 1*sizeof(double), &block_resized_recv);
    MPI_Type_free(&block_recv);
    MPI_Type_commit(&block_resized_recv);
    
    
    
    // sub-domain boundaries
    xmin_loc = rmin + world.coord_x * Nx_loc * dx_;
    xmax_loc = xmin_loc + (Nx_loc - 1) * dx_;
    ymin_loc = rmin + world.coord_y * Ny_loc * dx_;
    ymax_loc = ymin_loc + (Ny_loc - 1) * dx_;
    
    
    
    initialize_fields();
    
    MPI_Barrier(MPI_COMM_WORLD);
}