Ejemplo n.º 1
0
    void RamFileSystemSerialise::serialise_folder(RamFileSystem::Folder *folder)
    {
        write_binary(folder->id());
        _output << 'f';
        
        auto num_writable = 0u;
        for (auto iter = folder->begin(); iter != folder->end(); ++iter)
        {
            auto type = iter->second->metadata().type();
            if (type == MOUNT_POINT_ENTRY || type == CHARACTER_DEVICE_ENTRY)
            {
                continue;
            }
            num_writable++;
        }
        write_binary(num_writable);

        for (auto iter = folder->begin(); iter != folder->end(); ++iter)
        {
            auto type = iter->second->metadata().type();
            if (type == MOUNT_POINT_ENTRY || type == CHARACTER_DEVICE_ENTRY)
            {
                continue;
            }

            write_string(iter->first);
            write_binary(iter->second->id());
        }
    }
Ejemplo n.º 2
0
static size_t red_record_data_chunks_ptr(FILE *fd, const char *prefix,
                                         RedMemSlotInfo *slots, int group_id,
                                         int memslot_id, QXLDataChunk *qxl)
{
    size_t data_size = qxl->data_size;
    int count_chunks = 0;
    QXLDataChunk *cur = qxl;
    int error;

    while (cur->next_chunk) {
        cur =
            (QXLDataChunk*)get_virt(slots, cur->next_chunk, sizeof(*cur), group_id,
                                    &error);
        data_size += cur->data_size;
        count_chunks++;
    }
    fprintf(fd, "data_chunks %d %ld\n", count_chunks, data_size);
    validate_virt(slots, (intptr_t)qxl->data, memslot_id, qxl->data_size, group_id);
    write_binary(fd, prefix, qxl->data_size, qxl->data);

    while (qxl->next_chunk) {
        memslot_id = get_memslot_id(slots, qxl->next_chunk);
        qxl = (QXLDataChunk*)get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id,
                                      &error);

        validate_virt(slots, (intptr_t)qxl->data, memslot_id, qxl->data_size, group_id);
        write_binary(fd, prefix, qxl->data_size, qxl->data);
    }

    return data_size;
}
Ejemplo n.º 3
0
inline int binary_compare(const T &a, const T &b){
	std::vector<uint8_t> a_bytes(binary_length(a));
	std::vector<uint8_t> b_bytes(binary_length(b));
	write_binary(a_bytes.data(), a);
	write_binary(b_bytes.data(), b);
	if(a_bytes == b_bytes){ return 0; }
	return (a_bytes < b_bytes) ? -1 : 1;
}
Ejemplo n.º 4
0
void binary_reader::stock_data::write_raw( std::ofstream& out )
{	
	write_binary( out, stock_name_ );
	write_binary( out, date_time_ );
	write_binary( out, price_ );
	write_binary( out, vwap_ );
	write_binary( out, volume_ );
	write_binary( out, f1_ );
	write_binary( out, t1_ );
	write_binary( out, f2_ );
	write_binary( out, f3_ );
	write_binary( out, f4_ );	
}
Ejemplo n.º 5
0
static void red_record_surface_cmd(FILE *fd, RedMemSlotInfo *slots, int group_id,
                            QXLPHYSICAL addr)
{
    QXLSurfaceCmd *qxl;
    size_t size;
    int error;

    qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
                                    &error);

    fprintf(fd, "surface_cmd\n");
    fprintf(fd, "surface_id %d\n", qxl->surface_id);
    fprintf(fd, "type %d\n", qxl->type);
    fprintf(fd, "flags %d\n", qxl->flags);

    switch (qxl->type) {
    case QXL_SURFACE_CMD_CREATE:
        fprintf(fd, "u.surface_create.format %d\n", qxl->u.surface_create.format);
        fprintf(fd, "u.surface_create.width %d\n", qxl->u.surface_create.width);
        fprintf(fd, "u.surface_create.height %d\n", qxl->u.surface_create.height);
        fprintf(fd, "u.surface_create.stride %d\n", qxl->u.surface_create.stride);
        size = qxl->u.surface_create.height * abs(qxl->u.surface_create.stride);
        if ((qxl->flags & QXL_SURF_FLAG_KEEP_DATA) != 0) {
            write_binary(fd, "data", size,
                (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id,
                                   &error));
        }
        break;
    }
}
Ejemplo n.º 6
0
bool MCSessionWriteSession(MCSession *p_session)
{
	bool t_success = true;
	
	t_success = write_binary(p_session->filehandle, p_session->data, p_session->data_length);

	return t_success;
}
Ejemplo n.º 7
0
static int erl_json_ei_string(void* ctx, const unsigned char* val, unsigned int len) {
  State* pState = (State*) ctx;

  flog(stderr, "string", 0, (const char*)val, len);
  
  list_header_for_value(pState);
  write_binary(pState, (const char*)val, len);
  return 1;
}
Ejemplo n.º 8
0
 void RamFileSystemSerialise::serialise_file(RamFileSystem::File *file)
 {
     write_binary(file->id());
     _output << 'd';
     uint8_t *temp = new uint8_t[file->size()];
     file->read(0, file->size(), temp);
     write_string(temp, file->size());
     delete [] temp;
 }
Ejemplo n.º 9
0
static void red_record_virt_data_flat(FILE *fd, const char *prefix,
                                      RedMemSlotInfo *slots, int group_id,
                                      QXLPHYSICAL addr, size_t size)
{
    int error;

    write_binary(fd, prefix,
                 size, (uint8_t*)get_virt(slots, addr, size, group_id,
                                          &error));
}
Ejemplo n.º 10
0
void red_record_dev_input_primary_surface_create(FILE *fd,
    QXLDevSurfaceCreate* surface, uint8_t *line_0)
{
    fprintf(fd, "%d %d %d %d\n", surface->width, surface->height,
        surface->stride, surface->format);
    fprintf(fd, "%d %d %d %d\n", surface->position, surface->mouse_mode,
        surface->flags, surface->type);
    write_binary(fd, "data", line_0 ? abs(surface->stride)*surface->height : 0,
        line_0);
}
Ejemplo n.º 11
0
static void red_record_message(FILE *fd, RedMemSlotInfo *slots, int group_id,
                               QXLPHYSICAL addr)
{
    QXLMessage *qxl;
    int error;

    /*
     * security alert:
     *   qxl->data[0] size isn't specified anywhere -> can't verify
     *   luckily this is for debug logging only,
     *   so we can just ignore it by default.
     */
    qxl = (QXLMessage *)get_virt(slots, addr, sizeof(*qxl), group_id,
                                 &error);
    write_binary(fd, "message", strlen((char*)qxl->data), (uint8_t*)qxl->data);
}
Ejemplo n.º 12
0
void jag_store::convert_conduit_to_binary(const std::vector<std::string> &conduit_filenames) {
  m_num_converted_samples = 0;

  if (m_comm->get_procs_in_world() != 1) {
      throw lbann_exception(std::string{} + __FILE__ + " " + std::to_string(__LINE__) + " :: you must run convert_conduit with a single processor");
  }

  options *opts = options::get();
  std::string output_dir = opts->get_string("convert_conduit");
  if (m_master) {
    char b[128];
    sprintf(b, "mkdir --mode=770 -p %s", output_dir.c_str());
    system(b);
    write_binary_metadata(output_dir);
  }
  write_binary(conduit_filenames, output_dir);
}
Ejemplo n.º 13
0
int main(int argc, char **argv)
{
  if (argc != 6) {
    std::cout << "\nUsage:\n" << argv[0] << " file.bin ncols width jump h\n"
              << "file.bin contains media properties with curvy interface\n"
              << "ncols is number of columns in binary file\n"
              << "width is size of part of interface for jump (in cells) - not used with second version\n"
              << "jump is heigth of jump of interface (in cells)\n"
              << "h is cell size (m)\n\n";
    return 1;
  }

  try {
  const std::string filename = std::string(argv[1]);
  const int n_cols = atoi(argv[2]);
  const int width  = atoi(argv[3]);
  const int jump   = atoi(argv[4]);
  const float h    = atof(argv[5]);

  float *values = NULL;
  int n_rows;
  read_binary(filename, n_cols, &n_rows, &values);

  float *curvy_line = new float[n_cols]; // y-coordinates of the line
  get_curvy_line(values, n_cols, n_rows, h, curvy_line);

//  make_super_curvy(values, n_cols, n_rows, width, jump);
  make_super_curvy2(values, n_cols, n_rows, jump, h, curvy_line);

  write_binary(file_stem(filename) + "_curvy.bin", values, n_cols, n_rows);

  delete[] values;
  }
  catch (const std::exception& e) {
    std::cout << "\n" << e.what() << "\n" << std::endl;
    return 2;
  }
  catch (...) {
    std::cout << "\n\n\nUnknown exception!\n\n" << std::endl;
    return 3;
  }

  return 0;
}
Ejemplo n.º 14
0
static int erl_json_ei_map_key(void* ctx, const unsigned char* buf, unsigned int len) {
  State* pState = (State*) ctx;

  flog(stderr, "map key", 0, buf, len);

  list_header_for_value(pState);
  
  write_tuple_header(pState, 2);

  switch(keys_as(pState)) {
    case EEP0018_PARSE_KEYS_AS_ATOM:
      write_atom(pState, (const char*)buf, len);
      break;
    case EEP0018_PARSE_KEYS_AS_BINARY:
      write_binary(pState, (const char*)buf, len);
      break;
  }

  pState->skip_list_header_for_value = -1;
  
  return 1;
}
Ejemplo n.º 15
0
static void red_record_stroke_ptr(FILE *fd, RedMemSlotInfo *slots, int group_id,
                                  QXLStroke *qxl, uint32_t flags)
{
    int error;

    red_record_path(fd, slots, group_id, qxl->path);
    fprintf(fd, "attr.flags %d\n", qxl->attr.flags);
    if (qxl->attr.flags & SPICE_LINE_FLAGS_STYLED) {
        int style_nseg = qxl->attr.style_nseg;
        uint8_t *buf;

        fprintf(fd, "attr.style_nseg %d\n", qxl->attr.style_nseg);
        spice_assert(qxl->attr.style);
        buf = (uint8_t *)get_virt(slots, qxl->attr.style,
                                  style_nseg * sizeof(QXLFIXED), group_id,
                                  &error);
        write_binary(fd, "style", style_nseg * sizeof(QXLFIXED), buf);
    }
    red_record_brush_ptr(fd, slots, group_id, &qxl->brush, flags);
    fprintf(fd, "fore_mode %d\n", qxl->fore_mode);
    fprintf(fd, "back_mode %d\n", qxl->back_mode);
}
Ejemplo n.º 16
0
void binary_reader::stock_data::write( std::ofstream& out )
{
	boost::uint32_t date = 0;
	int month;
	int day;
	int year;
	std::sscanf( date_time_, "%4d%2d%2d", &year, &month, &day );
    date = ( year - 1 ) * 372 +  ( month  - 1 )* 31 + day;

	static char stock_name[ 9 ];
	memcpy( stock_name, stock_name_, sizeof( stock_name_ ) );
	write_binary( out, stock_name );
	write_binary( out, date );
	write_binary( out, vwap_ );
	write_binary( out, volume_ );
	write_binary( out, f1_ );
	write_binary( out, f4_ );
	write_binary( out, f3_ );
	//std::cout << " name:" << stock_name << " date:" << date << " volume:" << volume_ << " f3_:" << f3_ << std::endl;
}
Ejemplo n.º 17
0
int main(int argc, char *argv[])
{  
  int i, j, k, l, index, indexaux, Np, idPart;
  int ii, jj, kk;
  double xc, yc, zc; // Positions of the cells
  double xp, yp, zp, vxp, vyp, vzp; // Positions and velocities of the particles
  double Window_fn; //Window function
  double norm_factor; //Normalization factor for the momentum computation
  char *inFile=NULL;
  FILE *outfile=NULL, *outfile1=NULL, *outfile2=NULL;
  /*----- For verifications -----*/
  double totalMass=0.0;
  double totMassCIC=0.0;
  int sumaPart = 0;

  
  if(argc < 2)
    {
      printf("Error: Incomplete number of parameters. Execute as follows:\n");
      printf("%s Parameters_file\n", argv[0]);
      exit(0);
    }//if 

  inFile = argv[1];


  /*************************************************
             READING DATA FILE
  *************************************************/

  /*+++++  Reading parameters +++++*/
  printf("Reading parameters file\n");
  printf("--------------------------------------------------\n\n");
  read_parameters( inFile );

  printf("Parameters file read!\n");
  printf("--------------------------------------------------\n\n");

  printf("Reading data file\n");
  printf("--------------------------------------------------\n\n");

  
#ifdef BINARYDATA  
  /*+++++ Reading binary data file +++++*/
  read_binary();

  GV.NGRID3 = GV.NGRID * GV.NGRID * GV.NGRID;
  GV.dx = GV.L / (1.0*GV.NGRID);
  GV.volCell = GV.dx*GV.dx*GV.dx;
#endif

  
#ifdef ASCIIDATA 
  /*+++++ Allocating memory +++++*/
  part = (struct particle *) calloc((size_t) GV.NpTot,sizeof(struct particle));
  
  /*+++++ Reading data file +++++*/
  read_ascii( GV.FILENAME );

  /*+++++ Simulation parameters +++++*/  
  GV.NGRID3 = GV.NGRID * GV.NGRID * GV.NGRID;
  GV.dx = GV.L / ((double) GV.NGRID);
  GV.volCell = GV.dx*GV.dx*GV.dx;
#endif

  printf("Data file read!\n");
  printf("--------------------------------------------------\n\n");


  /*+++++ Computing mean density +++++*/
  printf("Computing mean density\n");
  printf("--------------------------------------------------\n\n");
  for(i=0; i<GV.NpTot; i++)
    {
      totalMass += part[i].mass;
    }//for i
  GV.rhoMean = totalMass / pow(GV.L, 3.0); // Mean density in 1e10M_sun/Mpc^3


  printf("-----------------------------------------------\n");
  printf("Cosmological parameters:\n");
  printf("OmegaM0=%lf OmegaL0=%lf redshift=%lf HubbleParam=%lf\n",
	 GV.OmegaM0,
	 GV.OmegaL0,
	 GV.zRS,
	 GV.HubbleParam);
  printf("-----------------------------------------------\n");
  printf("Simulation parameters:\n");
  printf("NGRID=%d NGRID3=%d Particle_Mass=%lf NpTotal=%ld \nrhoMean=%lf L=%lf volCell=%lf dx=%lf \nFilename=%s\n",
	 GV.NGRID,
	 GV.NGRID3,
	 GV.mass,
	 GV.NpTot,
	 GV.rhoMean,
	 GV.L,
	 GV.volCell,
	 GV.dx,
	 GV.FILENAME);
  printf("-----------------------------------------------\n");


  /*************************************************
                FROM PARTICLES TO GRID
  *************************************************/
  
  /*+++++ Array of structure Cell, size NGRID^3 +++++*/
  printf("Allocating memory\n");
  printf("-----------------------------------------------\n");
  cells = (struct Cell *) calloc( GV.NGRID3, sizeof( struct Cell) );
  printf("Memory allocated\n");
  printf("-----------------------------------------------\n");

  /*----- Setting values to zero at the beggining -----*/
  for(i=0; i<GV.NGRID3; i++){
    cells[i].Np_cell = 0;
    cells[i].denCon = 0.0;
    cells[i].rho = 0.0;
  }//for i
  
  printf("Locating cells\n");
  printf("-----------------------------------------------\n");

  /*++++ Locating cells +++++*/
  for(i=0; i<GV.NpTot; i++)    
    {
      locateCell(part[i].pos[X], part[i].pos[Y], part[i].pos[Z], i, cells);
    }//for i
  
  printf("Particles located in the grid\n");
  printf("-----------------------------------------------\n");


  printf("Performing the mass assignment\n");
  printf("-----------------------------------------------\n");
  
  
  /*+++++ Distribution scheme +++++*/
  for(i=0; i<GV.NGRID; i++)
    {
      for(j=0; j<GV.NGRID; j++)
	{
	  for(k=0; k<GV.NGRID; k++)
	    {
	      
	      /*----- Index of the cell  -----*/
	      index = INDEX(i,j,k); // C-order
	      
	      /*----- Coordinates in the center of the cell -----*/
	      xc = GV.dx*(0.5 + i);
	      yc = GV.dx*(0.5 + j);
	      zc = GV.dx*(0.5 + k);
	
	      /*----- Number of particles in the cell -----*/
	      Np = cells[index].Np_cell;
	      
	      for(l=0; l<Np; l++)
		{
		  /*::::: Particle ID :::::*/
		  idPart = cells[index].id_part[l];
		  
		  /*::::: Coordinates of the particle  :::::*/
		  xp = part[idPart].pos[X];
		  yp = part[idPart].pos[Y];
		  zp = part[idPart].pos[Z];
		  
	  
		  /*::::: Mass and momentum assignment to neighbour cells (CIC) :::::*/
		  for(ii=-1; ii<=1; ii++)
		    {
		      for(jj=-1; jj<=1; jj++)
			{
			  for(kk=-1; kk<=1; kk++)
			    {
		
			      indexaux = INDEX(mod(i+ii,GV.NGRID),mod(j+jj,GV.NGRID),mod(k+kk,GV.NGRID));
			      xc = GV.dx*(0.5 + i+ii);
			      yc = GV.dx*(0.5 + j+jj);
			      zc = GV.dx*(0.5 + k+kk);
			      
			      /*----- Mass with CIC assignment scheme ------*/
			      Window_fn = W(xc-xp, yc-yp, zc-zp, GV.dx);
			      cells[indexaux].rho += part[idPart].mass * Window_fn;
			    }//for kk
			}//for jj
		    }//for ii
	   	  
		}//for l	      	      
	      
	    }//for k
	}//for j
    }//for i
  
  free(part);
  
  /*+++++ Saving output file in ASCII format +++++*/
#ifdef ASCIIDATA
  outfile = fopen(strcat(GV.FILENAME,"_DenCon_CIC.dat"),"w");
  fprintf(outfile, "%s%9s %12s %12s %12s %12s %12s\n", 
	  "#", "Index", "NumberOfPars",
	  "x", "y", "z", "DenCon");
  
  for(i=0; i<GV.NGRID; i++)
    {
      for(j=0; j<GV.NGRID; j++)
	{
	  for(k=0; k<GV.NGRID; k++)
	    {
	
	      index = INDEX(i,j,k); // C-order
	      
	      /*----- coordinates of the centre of the cell -----*/
	      xc = GV.dx * (0.5 + i);
	      yc = GV.dx * (0.5 + j);
	      zc = GV.dx * (0.5 + k);
	
	      /*----- Calculating the final density in the cell -----*/
	      totMassCIC += cells[index].rho; /* We have not divided by the volume yet. 
						This is still the mass */
	      cells[index].rho = cells[index].rho / GV.volCell; //This is the actual density
	      
	      /*----- Verification of number of particles -----*/
	      sumaPart += cells[index].Np_cell;
	      
	      
	      /*----- Calculating the final density contrast in the cell -----*/
	      cells[index].denCon = (cells[index].rho/GV.rhoMean) - 1.0;
		
	      fprintf(outfile,
		      "%10d %10d %12.6lf %12.6lf %12.6lf %12.6lf\n", 
		      index, cells[index].Np_cell,
		      xc, yc, zc, cells[index].denCon);


	    }//for k
	}// for j
    }// for i

  fclose(outfile);
#endif


  /*+++++ Writing binary file +++++*/
#ifdef BINARYDATA
  for(i=0; i<GV.NGRID; i++)
    {
      for(j=0; j<GV.NGRID; j++)
	{
	  for(k=0; k<GV.NGRID; k++)
	    {
	      
	      index = INDEX(i,j,k); // C-order
	      
	      /*----- coordinates of the centre of the cell -----*/
	      cells[index].pos[X] = GV.dx * (0.5 + i);
	      cells[index].pos[Y] = GV.dx * (0.5 + j);
	      cells[index].pos[Z] = GV.dx * (0.5 + k);
	      
	      /*----- Calculating the final density in the cell -----*/
	      totMassCIC += cells[index].rho; /* We have not divided by the volume yet. 
						 This is still the mass */

	      cells[index].rho = cells[index].rho / GV.volCell; //This is the actual density
	      

	      /*----- Verification of number of particles -----*/
	      sumaPart += cells[index].Np_cell;
	      
	      
	      /*----- Calculating the final density contrast in the cell -----*/
	      cells[index].denCon = (cells[index].rho/GV.rhoMean) - 1.0;	      	      
	    }//for k
	}// for j
    }// for i

  write_binary();
#endif
  
    
  printf("Total number of particles:%10d\n", sumaPart);
  printf("Mass CIC = %lf\n",totMassCIC);
  printf("Mass Simulation = %lf\n", totalMass);
  
  /*+++++ Freeing up memory allocation +++++*/ 
  free(cells);
  
  printf("Code has finished successfully\n");

  return 0;
}//main
Ejemplo n.º 18
0
inline uint64_t compute_hash(const T &x, m3bp::size_type modulo){
	const auto len = binary_length(x);
	std::vector<uint8_t> buf(len);
	write_binary(buf.data(), x);
	return m3bp::hash_byte_sequence(buf.data(), len, modulo);
}
Ejemplo n.º 19
0
 void RamFileSystemSerialise::write_string(const uint8_t *str, uint32_t size)
 {
     write_binary(size);
     _output.write(reinterpret_cast<const char *>(str), size);
 }
Ejemplo n.º 20
0
 void RamFileSystemSerialise::write_string(const char *str, uint32_t size)
 {
     write_binary(size);
     _output.write(str, size);
 }
Ejemplo n.º 21
0
static void
time_integration_loop_hubble(Forceinfo *fi, Nbodyinfo *nb)
{
    double zval; /* red shift at T=0 */
    double tmpzz;
    double t, t0, dt1, tpresent;
    double W, K, E0, E, Q;
    double cm[3], cmv[3];
    int step = 0;
    double tsnapout, timageout;

    t = 0.0;
    tpresent = 16.0; /* present time must be 16.0 */
    zval = 24.0;
    tmpzz = pow(1.0/(zval+1), 3.0/2.0);
    t0 = tmpzz/(1.0-tmpzz)*tpresent;
    fi->eps = (zval+1)*pow(t0/(tpresent+t0), 2.0/3.0)*eps0;
    dt1 = dt0;

    tsnapout = dtsnapout;
    timageout = dtimageout;

    PR(t0, f); PR(dt0, f); PRL(dt1, f);

    PR(tstart,f); PR(tpresent,f); PR(dt,f); PRL(dtsnapout,f); PRL(dtimageout,f);

    if (cputime_flag) {
	vtc_turnon_cputime();
    }
    vtc_init_cputime();
    vtc_print_cputime("initial vtc_get_force start at");

#if DIRECT /* direct sum */
    if (grape_flag) {
	vtc_set_scale(512.0, nb->m[0]);
	fi->calculator = GRAPE_FORCEONLY;
	vtc_get_force_direct(fi, nb);
#if CALCPOTENTIAL
        fi->calculator = GRAPE_POTENTIALONLY;
	vtc_get_force_direct(fi, nb);
	fi->calculator = GRAPE_FORCEONLY;
#endif
    }
    else {
	vtc_get_force_direct(fi, nb);
    }
#else /* tree */
    if (grape_flag) {
	fi->calculator = GRAPE_FORCEONLY;
	vtc_get_force_tree(fi, nb);
#if CALCPOTENTIAL
        fi->calculator = GRAPE_POTENTIALONLY;
        vtc_get_force_tree(fi, nb);
	fi->calculator = GRAPE_FORCEONLY;
#endif
    }
    else {
	vtc_get_force_tree(fi, nb);
    }
#endif /* direct/tree */
    vtc_print_cputime("initial vtc_get_force end at");
    fprintf(stderr, "ninteraction: %e list_len_avg: %6.5f nwalk: %d\n",
	    fi->ninteraction, (double)fi->ninteraction/nb->n, fi->nwalk);
    K = get_kinetic_energy(nb);
#if CALCPOTENTIAL
    W = get_potential_energy(nb);
    E = E0 = W+K;
    PR(E0, f); PR(W, f);
#endif
    PRL(K, f);
    plot_nbody(t, nb);

    /* calculate force at T=0 and quit */
    if (snapout_flag && dtsnapout == 0.0) {
	static int nout = 0;
	char fn[255];
	snapout_acc_flag = 1;
	sprintf(fn, snapoutfile, nout);
	PRL(fn, s);
	if (ionemo_flag) {
	    write_binary(fn, t, nb);
	}
	else if (usepob_flag) {
	    write_pob(fn, t, nb);
	}
	else {
	    write_ascii(fn, t, nb);
	}
	vtc_print_cputime("exit at");
	return;
    }

    while (t < tend) {
	if (fi->eps < eps) {
	    double eps1;
	    eps1 = (zval+1)*pow((t+t0)/(tpresent+t0), 2.0/3.0)*eps0;
	    fi->eps = (eps1 < eps ? eps1 : eps);
	}
	else {
	    fi->eps = eps;
	}
	if (dt1 < dt) {
	    dt1 = dt0*(t+t0)/t0;
	}
	else {
	    dt1 = dt;
	}
 	if (step%outlogstep == outlogstep - 1 && cputime_flag) {
	    vtc_turnon_cputime();
	}
	else {
	    vtc_turnoff_cputime();
	}
        push_velocity(0.5*dt1, nb);
        push_position(dt1, nb);
	vtc_init_cputime();
#if DIRECT /* direct sum */
	vtc_get_force_direct(fi, nb);
#else /* tree */
	vtc_get_force_tree(fi, nb);
#endif /* direct/tree */
	vtc_print_cputime("vtc_get_force end at");
        push_velocity(0.5*dt1, nb);
	vtc_print_cputime("integration end at");

	plot_nbody(t, nb);
 	if (step%outlogstep == outlogstep - 1) {
	    fprintf(stderr, "ninteraction: %e list_len_avg: %6.5f nwalk: %d\n",
		    fi->ninteraction, fi->ninteraction/nb->n, fi->nwalk);
	    K = get_kinetic_energy(nb);
#if CALCPOTENTIAL
	    if (grape_flag) {
		fi->calculator = GRAPE_POTENTIALONLY;
#if DIRECT /* direct sum */
		vtc_get_force_direct(fi, nb);
#else /* tree */
		vtc_get_force_tree(fi, nb);
#endif /* direct/tree */
		fi->calculator = GRAPE_FORCEONLY;
	    }
	    W = get_potential_energy(nb);
	    E = W+K;
	    Q = K/(K-E);
	    fprintf(stderr, "\nT= %f K= %f Q= %f E= %f Eerr= %f Eabserr= %f\n",
		    t, K, Q, E, (E0-E)/E0, E0-E);
#else
	    fprintf(stderr, "\nT= %f K= %f\n", t, K);
#endif
	    fprintf(stderr, "step: %d\n", step);
	    fprintf(stderr, "T: %f current eps: %f dt: %f\n",
		    t, fi->eps, dt1);
	    get_cmterms(nb, cm, cmv);
	    fprintf(stderr, "CM  %15.13e %15.13e %15.13e\n",
		    cm[0], cm[1], cm[2]);
	    fprintf(stderr, "CMV %15.13e %15.13e %15.13e\n",
		    cmv[0], cmv[1], cmv[2]);
 	}
	if (tsnapout < t && snapout_flag) {
	    static int nout = 0;
	    char fn[255];
	    char cmd[255];

	    sprintf(fn, snapoutfile, nout);
	    PRL(fn, s);
	    if (ionemo_flag) {
		write_binary(fn, t, nb);
	    }
	    else if (usepob_flag) {
		write_pob(fn, t, nb);
	    }
	    else {
		write_ascii(fn, t, nb);
	    }

	    if (command_exec_flag) {
		sprintf(cmd, "%s %s %03d", command_name, fn, nout);
		fprintf(stderr, "execute %s\n", cmd);
		system(cmd);
	    }
	    nout++;
	    PR(t, f); PRL(fn, s);
	    tsnapout += dtsnapout;
	}
	if (timageout < t && imageout_flag) {
	    static int nout = 0;
	    char fn[255];
	    char cmd[255];

	    sprintf(fn, snapoutfile, nout);
	    strcat(fn, ".gif");
	    PRL(fn, s);
	    vtc_plotstar(nb->x, nb->n, t, image_scale, fn);
	    nout++;
	    PR(t, f); PRL(fn, s);
	    timageout += dtimageout;
	}
	t += dt1;
	step++;
	vtc_print_cputime("exit at");
    } /* main loop */
}
int main()
{
  
  int i, j, k, l, index, indexaux, Np, idPart;
  int ii, jj, kk;
  int icor, jcor, kcor;
  int suma = 0;
  double xc, yc, zc, vxc, vyc, vzc; // Positions and velocities of the cells
  double xp, yp, zp, vxp, vyp, vzp; // Positions and velocities of the particles
  FILE *outfile;
  double foo = 0.0;
  double mass;
  /*GSL*/
  const gsl_rng_type * T; /*Define el tipo de generador de números aleatorios. No hay que liberarlo*/
  gsl_rng * r; /*Análogo al w. Puntero que contiene la info sobre cual generador se va a usar,cantidad de memoria a usar, etc.*/  
  long seed;  
  
  /*Plummer*/
  double aux_x, aux_y, aux_z, aux_rad;
  double ux, uy, uz;
  int count_n = 0;
  double Plummer_max, TMass, aSL;
  FILE *outFile=NULL;
  
  //////////////////////////////////
  //* READING GADGET BINARY FILE *//
  //////////////////////////////////
  printf("Reading parameters file\n");
  read_parameters("./Parameters_files/parameters_file.dat");
  GV.NpTot = 300000.0;
  //GV.NpTot = 1000.0;
  
  printf("Parameters file read. Let's work with N=%lf particles\n", GV.NpTot);

  /* Simulation parameters */
  GV.L = 400.0;
  GV.NGRID3 = GV.NGRID * GV.NGRID * GV.NGRID;
  GV.mass = 1.0;
  GV.rhoMean = (GV.mass * GV.NpTot) / pow(GV.L,3); // Mean density in 1e10M_sun/Mpc^3
  GV.dx = GV.L / (1.0* GV.NGRID);
  GV.volCell = GV.dx*GV.dx*GV.dx;
  
  part = (struct particle *) calloc((size_t) GV.NpTot,sizeof(struct particle));
  printf("Memory Allocated\n");
  

  /*+++++ Initializing random generation of numbers +++++*/
  gsl_rng_env_setup();//Inicializa las rutinas de generación
  T = gsl_rng_default;/*Inicialización de T con esta variable de GSL que es la default*/
  r = gsl_rng_alloc(T);/*Alocación de memoria*/
  
  seed = time(NULL)*getpid(); 
  
  gsl_rng_set(r, seed);/*Recibe puntero de inicialización de generación y  un entero largo como semilla*/

  

  /*+++++ Rejection method +++++*/
  printf("Performing Rejection\n");
  /*----- Maximum value of the Plummer function -----*/
  TMass = 100.0;
  aSL = 10.0;
  Plummer_max = aSL * aSL * aSL;
  Plummer_max = 4 * M_PI * Plummer_max;
  Plummer_max = (3.0 * TMass) / Plummer_max;

  outFile = fopen("./../../Processed_data/Plummer_parts.bin", "w");

  while(count_n < GV.NpTot + 1)
    {
      aux_x = GV.L * gsl_rng_uniform (r);
      aux_y = GV.L * gsl_rng_uniform (r);
      aux_z = GV.L * gsl_rng_uniform (r);
      //aux_rad = aux_x*aux_x + aux_y*aux_y + aux_z*aux_z;
      //aux_rad = sqrt(aux_rad);

      ux = Plummer_max * gsl_rng_uniform (r);           
      uy = Plummer_max * gsl_rng_uniform (r);            
      uz = Plummer_max * gsl_rng_uniform (r);

      if( ux < Plummer( aux_x, aSL, TMass) )
	//if( ux < Plummer( aux_rad, aSL, TMass) )
	{
	  if( uy < Plummer( aux_y, aSL, TMass) )
	    //if( uy < Plummer( aux_rad, aSL, TMass) )
	    {
	      if( uz < Plummer( aux_z, aSL, TMass) )
		//if( uz < Plummer( aux_rad, aSL, TMass) )
		{
		  /*
		  part[i].posx = Plummer_inv(ux, aSL, TMass);
		  part[i].posy = Plummer_inv(uy, aSL, TMass);
		  part[i].posz = Plummer_inv(uz, aSL, TMass);
		  */
		  
		  part[i].posx = aux_x;
		  part[i].posy = aux_y;
		  part[i].posz = aux_z;
		  
		  part[i].id = count_n;
		  part[i].mass = 1.0;
		  
		  part[i].velx = 0.0;
		  part[i].vely = 0.0;
		  part[i].velz = 0.0;		  
		  
		  if((count_n%500000)==0)
		    {
		      printf("particle %d finished\n", count_n);
		    }

		  fprintf(outFile, "%16.8lf %16.8lf %16.8lf\n", part[i].posx, part[i].posy, part[i].posz);
		  
		  count_n++; 	  
		}//if z	      
	    }//if y
	}//if x
 
    }//while
  
  fclose(outFile);

  printf("Rejection finished!\n");
  printf("Total number of parts GV.NpTot = %lf, count_n=%d\n", 
	 count_n, GV.NpTot);
  
  
  gsl_rng_free (r);  
  
  /* Cosmological parameters */  
  //GV.OmegaM0 = Header.Omega0;
  //GV.OmegaL0 = Header.OmegaLambda;
  //GV.zRS = Header.redshift;
  //GV.HubbleParam = Header.HubbleParam;

  

  /*
    printf("-----------------------------------------------\n");
    printf("Cosmological parameters:\n");
    printf("OmegaM0=%lf OmegaL0=%lf redshift=%lf HubbleParam=%lf\n",
    GV.OmegaM0,
    GV.OmegaL0,
    GV.zRS,
    GV.HubbleParam);
    printf("-----------------------------------------------\n");
  */
  printf("Simulation parameters:\n");
  printf("NGRID=%d NGRID3=%d Particle_Mass=%lf NpTotal=%lf rhoMean=%lf L=%lf volCell=%lf dx=%lf Filename=%s\n",
	 GV.NGRID,
	 GV.NGRID3,
	 GV.mass,
	 GV.NpTot,
	 GV.rhoMean,
	 GV.L,
	 GV.volCell,
	 GV.dx,
	 GV.FILENAME);
  printf("-----------------------------------------------\n");


  //////////////////////////////
  //* FROM PARTICLES TO GRID *//
  //////////////////////////////

  /* Array of structure Cell, size NGRID^3 */
  cells = (struct Cell *)calloc( GV.NGRID3, sizeof( struct Cell) );

  // Setting values to zero at the beggining
  for(i=0; i<GV.NGRID3; i++){
    cells[i].Np_cell = 0;
    cells[i].denCon = 0.0;
    cells[i].rho = 0.0;
    cells[i].velx = 0.0;
    cells[i].vely = 0.0;
    cells[i].velz = 0.0;
  }
  
  /* Locating cells */
  for(i=0; i<GV.NpTot; i++){
    locateCell(part[i].posx, part[i].posy, part[i].posz, i, cells);
  }

  printf("Particles located in the grid\n");
  printf("-----------------------------------------------\n");

  /* Distribution scheme  */
  for(i=0; i<GV.NGRID; i++){
    for(j=0; j<GV.NGRID; j++){
      for(k=0; k<GV.NGRID; k++){
	
	/* Index of the cell  */
	index = INDEX(i,j,k); // C-order
	
	/* coordinates in the center of the cell */
	xc = GV.dx*(0.5 + i);
	yc = GV.dx*(0.5 + j);
	zc = GV.dx*(0.5 + k);
	
	/* Number of particles in the cell */
	Np = cells[index].Np_cell;
	if(Np == 0){
	  cells[index].velx = 0.0;
	  cells[index].vely = 0.0;
	  cells[index].velz = 0.0;
	  continue;  
	}

	for(l=0; l<Np; l++){
	  /* Particle ID */
	  idPart = cells[index].id_part[l];
	  
	  /* Coordinates of the particle  */
	  xp = part[idPart].posx;
	  yp = part[idPart].posy;
	  zp = part[idPart].posz;
	  
	  /* Velocities of the particle  */
	  vxp = part[idPart].velx;
	  vyp = part[idPart].vely;
	  vzp = part[idPart].velz;
	  
	  /* 
	     Cell velocity assignment:
	     At the end of the for at l-index we are going 
	     to toke the ratio with respect to Np, in order 
	     to get the mean of the volocities in each cell.
	   */
	  cells[index].velx += vxp;
	  cells[index].vely += vyp;
	  cells[index].velz += vzp;

	  
	  for(ii=-1; ii<=1; ii++){
	    for(jj=-1; jj<=1; jj++){
	      for(kk=-1; kk<=1; kk++){
		indexaux = INDEX(mod(i+ii,GV.NGRID),mod(j+jj,GV.NGRID),mod(k+kk,GV.NGRID));
		xc = GV.dx*(0.5 + i+ii);
		yc = GV.dx*(0.5 + j+jj);
		zc = GV.dx*(0.5 + k+kk);
		cells[indexaux].rho += GV.mass * W(xc-xp, yc-yp, zc-zp, GV.dx);
	      }
	    }
	  }
	   	  
	}//for l
	
	/* 
	   Cell velocity assignment:
	   At the end of the for at l-index we are going 
	   to toke the ratio with respect to Np, in order 
	   to get the mean of the volocities in each cell.
	*/
	cells[index].velx = cells[index].velx / ((double) Np);
	cells[index].vely = cells[index].vely / ((double) Np);
	cells[index].velz = cells[index].velz / ((double) Np);
	
      }//for k
    }//for j
  }//for i
  
  /*
  outfile = fopen("dens_uniform.dat","w");

  fprintf(outfile,
	  "%s%9s %12s %12s %12s %12s %12s %12s %12s %12s %12s\n", 
	  "#", "Index", "x", "y", "z",
	  "vx", "vy", "vz",
	  "rho", "DenCon", "Np_cell");
  */
  for(i=0; i<GV.NGRID; i++){
    for(j=0; j<GV.NGRID; j++){
      for(k=0; k<GV.NGRID; k++){
	index = INDEX(i,j,k); // C-order
	/* coordinates of the cell (in the center of) */
	xc = GV.dx * (0.5 + i);
	yc = GV.dx * (0.5 + j);
	zc = GV.dx * (0.5 + k);

	cells[index].pos[X] = xc;
	cells[index].pos[Y] = yc;
	cells[index].pos[Z] = zc;
	/* Calculating the final density in the cell */
	cells[index].rho = cells[index].rho / GV.volCell;
	/* Calculating the final density contrast in the cell */
	cells[index].denCon = (cells[index].rho/GV.rhoMean) - 1.0;
	/* Writting in the file  */
	/*fprintf(outfile,
		"%10d %12.6lf %12.6lf %12.6lf %12.6lf %12.6lf %12.6lf %12.6lf %12.6lf %10d\n", 
		index, xc, yc, zc, 
		cells[index].velx, cells[index].vely, cells[index].velz, 
		cells[index].rho, cells[index].denCon, cells[index].Np_cell);
	*/
      }//for k
    }// for j
  }// for i
  //fclose(outfile);

  /* Writting in the file  */
  write_binary();
  
  
  /* Freeing up memory allocation */
  free(part);
  free(cells);
  
  return 0;
}
Ejemplo n.º 23
0
int main(int argc, char *argv[])
{
    //============= set up MPI =================
    
    MPI_Status status;
    const int root_process = 0;
    int ierr, my_id, an_id, num_procs;

    // tag for MPI message: energy minimization convergence 
    const int tag_99 = 99;

    // initialize MPI, get my_id for this process and total number of processes
    ierr = MPI_Init(&argc, &argv);
    ierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
    ierr = MPI_Comm_size(MPI_COMM_WORLD, &num_procs);


    //============ get input files =============

    // default filenames
    char input_gro[MAX_STR_LEN], input_param[MAX_STR_LEN], input_mdset[MAX_STR_LEN];
    strcpy(input_gro,   "init.gro");
    strcpy(input_param, "param.txt");
    strcpy(input_mdset, "mdset.txt");

    // parse arguments (input files)
    // -gro for gro file
    // -par for parameter file
    // -mds for MD settings
    int iarg = 1;
    while (1)
    {
        if (iarg >= argc) { break; }

        if (0 == strcmp(argv[iarg], "-gro") && iarg < argc)
        {
            strcpy(input_gro, argv[iarg + 1]);
            iarg += 2;
        }
        else if (0 == strcmp(argv[iarg], "-par") && iarg < argc)
        {
            strcpy(input_param, argv[iarg + 1]);
            iarg += 2;
        }
        else if (0 == strcmp(argv[iarg], "-mds") && iarg < argc)
        {
            strcpy(input_mdset, argv[iarg + 1]);
            iarg += 2;
        }
        else
        {
            ++ iarg;
        }
    }


    //========= define variables and read MD settings ===========

    // varialbles to read from input_mdset
    RunSet *p_runset = my_malloc(sizeof(RunSet));
    Metal  *p_metal  = my_malloc(sizeof(Metal));


    // read md settings from input_mdset
    read_settings(input_mdset, p_runset, p_metal);


    // initialize timer
    time_t start_t = time(NULL);
    struct timeval tv;
    gettimeofday(&tv, NULL);
    double start_time = (tv.tv_sec) + (tv.tv_usec) * 1.0e-6;

    // time_used[0] = total
    // time_used[1] = QSC density
    // time_used[2] = QSC force
    // time_used[3] = Bonded
    // time_used[4] = Nonbonded
    // time_used[5] = CPIM matrix
    // time_used[6] = CPIM vector
    // time_used[7] = CPIM solve
    // time_used[8] = CPIM force
    // time_used[10] = QSC density communication
    
    double **time_used = my_malloc(sizeof(double *) * num_procs);
    for(an_id = 0; an_id < num_procs; ++ an_id)
    {
        time_used[an_id] = my_malloc(sizeof(double) * 15);

        int it;
        for(it = 0; it < 15; ++ it)
        {
            time_used[an_id][it] = 0.0;
        }
    }


    // Coulomb type: cut_off, wolf_sum
    if (0 == strcmp(p_runset->coulomb_type, "cut_off" )) 
    { 
        p_runset->use_coulomb = 0; 
    }
    else if (0 == strcmp(p_runset->coulomb_type, "wolf_sum")) 
    { 
        p_runset->use_coulomb = 1; 
    }
    else 
    { 
        printf("Error: unknown coulomb_type %s!\n", p_runset->coulomb_type); 
        exit(1); 
    }


    // Damped shifted force (DSF) approach for electrostatics 
    // Ref.:      Fennell and Gezelter, J. Chem. Phys. 2006, 124, 234104
    //            dx.doi.org/10.1063/1.2206581
    // Based on:  Wolf et al., J. Chem. Phys. 1999, 110, 8254
    //            dx.doi.org/10.1063/1.478738
    //            Zahn et al., J. Phys. Chem. B 2002, 106, 10725-10732
    //            dx.doi.org/10.1021/jp025949h
    // Benchmark: McCann and Acevedo, J. Chem. Theory Comput. 2013, 9, 944-950
    //            dx.doi.org/10.1021/ct300961e

    // note: p_runset->rCut and p_runset->w_alpha were read from mdset.txt
    p_runset->rCut2 = p_runset->rCut * p_runset->rCut;
    double rCut     = p_runset->rCut;
    double rCut2    = p_runset->rCut2;

    double w_alpha         = p_runset->w_alpha;
    p_runset->w_a2_sqrtPI  = w_alpha * 2.0 * INV_SQRT_PI;
    p_runset->w_Const      = erfc(w_alpha * rCut) / rCut2 + 
                             p_runset->w_a2_sqrtPI * exp(-w_alpha * w_alpha * rCut2) / rCut;
    p_runset->w_erfc_arCut = erfc(w_alpha * rCut)/ rCut;



    // van der Waals type: cut_off or shifted
    if (0 == strcmp(p_runset->vdw_type, "cut_off")) 
    { 
        p_runset->use_vdw = 0; 
    }
    else if (0 == strcmp(p_runset->vdw_type, "shifted")) 
    { 
        p_runset->use_vdw = 1; 
    }
    else 
    { 
        printf("Error: unknown vdw_type %s!\n", p_runset->vdw_type); 
        exit(1); 
    }


    // Shifted force method for Lennard-Jones potential
    // Ref:   Toxvaerd and Dyre, J. Chem. Phys. 2011, 134, 081102
    //        dx.doi.org/10.1063/1.3558787

    p_runset->inv_rc12 = 1.0 / pow(rCut, 12.0);
    p_runset->inv_rc6  = 1.0 / pow(rCut, 6.0);


    //============== read force field parameters from param.txt =================
    
    Topol *p_topol = my_malloc(sizeof(Topol));

    int mol, atom;
    int number_VSites, number_Cstrs;

    // variables for bonded and nonbonded interaction


    // CPIM: capacitance-polarizability interaction model
    // Ref.: a) Jensen and Jensen, J. Phys. Chem. C, 2008, 112, 15697-15703
    //          dx.doi.org/10.1021/jp804116z
    //       b) Morton and Jensen, J. Chem. Phys., 2010, 133, 074103
    //          dx.doi.org/10.1063/1.3457365
    //
    // p_metal->cpff_polar: polarizability
    // p_metal->cpff_capac: capacitance
    // p_metal->n_NPs:      number of nanoparticles
    // p_metal->cpff_chg:   total charge of a nanoparticle
    // p_metal->start_NP:   first atom of a nanoparticle
    // p_metal->end_NP:     last atom of a nanoparticle
    

    // read parameters from input_param, step 1
    read_param_1(input_param, p_topol, p_metal);


    // allocate memory for arrays

    // CPIM charge and indices
    p_metal->cpff_chg = my_malloc(p_metal->n_NPs * sizeof(double));
    p_metal->start_NP = my_malloc(p_metal->n_NPs * sizeof(int));
    p_metal->end_NP   = my_malloc(p_metal->n_NPs * sizeof(int));


    // molecules and atom parameters
    // For a given molecule type (mol from 0 to p_topol->mol_types-1):
    // p_topol->atom_num[mol]:  its number of atoms
    // p_topol->mol_num[mol]:   the number of this type of molecule in the system
    p_topol->atom_num   = my_malloc(p_topol->mol_types * sizeof(int));
    p_topol->mol_num    = my_malloc(p_topol->mol_types * sizeof(int));
    p_topol->atom_param = my_malloc(p_topol->mol_types * sizeof(AtomParam *));


    // van der Waals interaction parameters
    NonbondedParam *data_nonbonded = 
        my_malloc_2(p_topol->n_types * p_topol->n_types * sizeof(NonbondedParam), "data_nonbonded");

    p_topol->nonbonded_param =
        my_malloc(p_topol->n_types * sizeof(NonbondedParam *));

    int i_type;
    for(i_type = 0; i_type < p_topol->n_types; ++ i_type)
    {
        p_topol->nonbonded_param[i_type] =
            &(data_nonbonded[p_topol->n_types * i_type]);
    }


    // bonded potentials: bond, pair, angle, dihedral
    int *data_bonded = my_malloc(sizeof(int) * p_topol->mol_types * 6);
    p_topol->n_bonds       = &(data_bonded[0]);
    p_topol->n_pairs       = &(data_bonded[p_topol->mol_types]);
    p_topol->n_angles      = &(data_bonded[p_topol->mol_types * 2]);
    p_topol->n_dihedrals   = &(data_bonded[p_topol->mol_types * 3]);
    p_topol->n_vsites      = &(data_bonded[p_topol->mol_types * 4]);
    p_topol->n_constraints = &(data_bonded[p_topol->mol_types * 5]);

    p_topol->vsite_funct = my_malloc(p_topol->mol_types * sizeof(int *)) ;

    p_topol->bond_param     = my_malloc(p_topol->mol_types * sizeof(BondParam *));
    p_topol->pair_param     = my_malloc(p_topol->mol_types * sizeof(PairParam *)) ;
    p_topol->angle_param    = my_malloc(p_topol->mol_types * sizeof(AngleParam *));
    p_topol->dihedral_param = my_malloc(p_topol->mol_types * sizeof(DihedralParam *)) ;
    p_topol->vsite_4        = my_malloc(p_topol->mol_types * sizeof(VSite_4 *)) ;
    p_topol->constraint     = my_malloc(p_topol->mol_types * sizeof(Constraint *)) ;

    p_topol->exclude = my_malloc(p_topol->mol_types * sizeof(int **)) ;


    // Quantum Sutton-Chen densities for metal
    if (p_metal->min >=0 && p_metal->max >= p_metal->min)
    {
        p_metal->inv_sqrt_dens = my_malloc(sizeof(double) * p_metal->num);
    }


    // read parameters from input_param, step 2
    read_param_2(input_param, p_topol, p_metal);

    int nAtoms = p_topol->n_atoms;
    int nMols  = p_topol->n_mols;


    // count number of virtual sites and constraints
    number_VSites = 0;
    number_Cstrs  = 0;
    for(mol = 0; mol < p_topol->mol_types; ++ mol)
    {
        number_VSites += p_topol->n_vsites[mol] * p_topol->mol_num[mol];
        number_Cstrs  += p_topol->n_constraints[mol] * p_topol->mol_num[mol];
    }


    // Gaussian distribution width for capacitance-polarizability model
    // see Mayer, Phys. Rev. B 2007, 75, 045407
    // and Jensen, J. Phys. Chem. C 2008, 112, 15697

    p_metal->inv_polar = 1.0 / p_metal->cpff_polar;
    p_metal->inv_capac = 1.0 / p_metal->cpff_capac;
    
    double R_q = sqrt(2.0 / M_PI) * p_metal->cpff_capac;
    double R_p = pow(sqrt(2.0 / M_PI) * p_metal->cpff_polar / 3.0, 1.0 / 3.0);

    p_metal->inv_R_qq = 1.0 / sqrt(R_q * R_q + R_q * R_q);
    p_metal->inv_R_pq = 1.0 / sqrt(R_p * R_p + R_q * R_q);
    p_metal->inv_R_pp = 1.0 / sqrt(R_p * R_p + R_p * R_p);


    // print info
    if (root_process == my_id) 
    {
        printf("\n");
        printf("              +-----------------------------------------------------+\n");
        printf("              |             CapacMD program version 1.0             |\n");
        printf("              |         Xin Li, TheoChemBio, KTH, Stockholm         |\n");
        printf("              +-----------------------------------------------------+\n");
        printf("\n");

        printf("              .------------------ reference paper ------------------.\n");
        printf("\n");
        printf("    Molecular Dynamics Simulations using a Capacitance-Polarizability Force Field,\n");
        printf("    Xin Li and Hans Agren, J. Phys. Chem. C, 2015, DOI: 10.1021/acs.jpcc.5b04347\n");
        printf("\n");
        printf("\n");

        printf("    Calculation started at %s", ctime(&start_t));
        printf("    Parallelized via MPI, number of processors = %d\n", num_procs);
        printf("\n");
        printf("\n");

        printf("              .------------------ run parameters -------------------.\n");
        printf("\n");
        printf("    run_type = %s, ensemble = %s\n", p_runset->run_type, p_runset->ensemble);
        printf("    vdw_type = %s, coulomb_type = %s\n", p_runset->vdw_type, p_runset->coulomb_type);

        printf("    rCut = %.3f nm, ", rCut);
        if (1 == p_runset->use_coulomb)
        {
            printf("alpha = %.3f nm^-1", p_runset->w_alpha);
        }
        printf("\n");

        printf("    ref_T = %.1f K\n", p_runset->ref_temp);
        printf("\n");
        printf("\n");

        printf("              .------------------- molecule info -------------------.\n");
        printf("\n");
        printf("    There are %d types of molecules.\n", p_topol->mol_types);
        printf("\n");

        for(mol = 0; mol < p_topol->mol_types; ++ mol)
        {
            printf("    Molecule[%5d], num= %5d\n", mol, p_topol->mol_num[mol]);
            for(atom = 0; atom < p_topol->atom_num[mol]; ++ atom)
            {
                printf("    Atom[%5d], charge= %8.3f, mass= %8.3f, atomtype= %5d\n",
                       atom, p_topol->atom_param[mol][atom].charge,
                       p_topol->atom_param[mol][atom].mass, 
                       p_topol->atom_param[mol][atom].atomtype);
            }
            printf("\n");
        }
        printf("\n");
    }


    //=========== distribute molecules/atoms/metals among the procs ==============

    Task *p_task = my_malloc(sizeof(Task));

    int *data_start_end = my_malloc(sizeof(int) * num_procs * 6);
    p_task->start_mol   = &(data_start_end[0]);
    p_task->end_mol     = &(data_start_end[num_procs]);
    p_task->start_atom  = &(data_start_end[num_procs * 2]);
    p_task->end_atom    = &(data_start_end[num_procs * 3]);
    p_task->start_metal = &(data_start_end[num_procs * 4]);
    p_task->end_metal   = &(data_start_end[num_procs * 5]);

    find_start_end(p_task->start_mol,   p_task->end_mol,   nMols,        num_procs);
    find_start_end(p_task->start_atom,  p_task->end_atom,  nAtoms,       num_procs);
    find_start_end(p_task->start_metal, p_task->end_metal, p_metal->num, num_procs);

    long int *data_long_start_end = my_malloc(sizeof(long int) * num_procs * 2);
    p_task->start_pair = &(data_long_start_end[0]);
    p_task->end_pair   = &(data_long_start_end[num_procs]);

    long int n_pairs = nAtoms * (nAtoms - 1) / 2;
    find_start_end_long(p_task->start_pair,  p_task->end_pair,  n_pairs, num_procs);


    //============= assign indices, masses and charges =======================

    // For each atom in the system (i from 0 to p_topol->n_atoms-1)
    // atom_info[i].iAtom:  the index of this atom in its molecule type
    // atom_info[i].iMol:   the index of its molecule type
    // atom_info[i].molID:  the index of its molecule in the system

    // For each molecule in the system (im from 0 to p_topol->n_mols-1)
    // mol_info[im].mini:  the index of its first atom in the system
    // mol_info[im].maxi:  the index of its last atom in the system
    
    Atom_Info *atom_info = my_malloc(nAtoms * sizeof(Atom_Info));
    Mol_Info  *mol_info  = my_malloc(nMols  * sizeof(Mol_Info));

    assign_indices(p_topol, p_metal, atom_info, mol_info);


    //======= allocate memory for coordinates, velocities and forces ==========

    System *p_system = my_malloc(sizeof(System));

    // potential energy
    // p_system->potential[0] = total energy
    // p_system->potential[1] = metal quantum Sutton-Chen energy
    // p_system->potential[2] = non-metal bond stretching energy
    // p_system->potential[3] = non-metal angle bending energy
    // p_system->potential[4] = non-metal torsional energy
    // p_system->potential[5] = 
    // p_system->potential[6] = Long range Coulomb
    // p_system->potential[7] = Coulomb energy (including 1-4)
    // p_system->potential[8] = vdW energy (including 1-4)
    // p_system->potential[9] = 
    // p_system->potential[10] = CPIM metal charge - non-metal charge
    // p_system->potential[11] = CPIM metal dipole - non-metal charge
    // p_system->potential[12] = CPIM metal charge - metal charge
    // p_system->potential[13] = CPIM metal charge - metal dipole
    // p_system->potential[14] = CPIM metal dipole - metal dipole
    
    double *data_potential = my_malloc(sizeof(double) * 15 * 2);
    p_system->potential   = &(data_potential[0]);
    p_system->partial_pot = &(data_potential[15]);
    p_system->old_potential = 0.0;


    // virial tensor
    p_system->virial      = my_malloc(DIM * sizeof(double*));
    p_system->partial_vir = my_malloc(DIM * sizeof(double*));

    double *data_vir = my_malloc(DIM*2 * DIM * sizeof(double));
    int i;
    for (i = 0; i < DIM; ++ i)
    {
        p_system->virial[i]      = &(data_vir[DIM * i]);
        p_system->partial_vir[i] = &(data_vir[DIM * (DIM + i)]);
    }


    // box size
    // Note: for now we treat rectangular box only.
    // "p_system->box" has six elements
    // the first three are length in x, y, z
    // the second three are half of the length in x, y, z
    p_system->box = my_malloc(sizeof(double) * DIM*2);


    // coordinates, velocities and forces
    double *data_rvf = my_malloc_2(nAtoms*7 * DIM * sizeof(double), "data_rvf");
            
    p_system->rx = &(data_rvf[0]);
    p_system->ry = &(data_rvf[nAtoms]);
    p_system->rz = &(data_rvf[nAtoms*2]);
            
    p_system->vx = &(data_rvf[nAtoms*3]);
    p_system->vy = &(data_rvf[nAtoms*4]);
    p_system->vz = &(data_rvf[nAtoms*5]);
    
    p_system->fx = &(data_rvf[nAtoms*6]);
    p_system->fy = &(data_rvf[nAtoms*7]);
    p_system->fz = &(data_rvf[nAtoms*8]);
            
    // forces from slave processors
    p_system->partial_fx = &(data_rvf[nAtoms*9]);
    p_system->partial_fy = &(data_rvf[nAtoms*10]);
    p_system->partial_fz = &(data_rvf[nAtoms*11]);
            
    // old position for RATTLE constraints
    p_system->old_rx = &(data_rvf[nAtoms*12]);
    p_system->old_ry = &(data_rvf[nAtoms*13]);
    p_system->old_rz = &(data_rvf[nAtoms*14]);
            
    // old force for CG optimization
    p_system->old_fx = &(data_rvf[nAtoms*15]);
    p_system->old_fy = &(data_rvf[nAtoms*16]);
    p_system->old_fz = &(data_rvf[nAtoms*17]);

    // direction for CG optimization
    p_system->sx = &(data_rvf[nAtoms*18]);
    p_system->sy = &(data_rvf[nAtoms*19]);
    p_system->sz = &(data_rvf[nAtoms*20]);


    //================ read input gro file ==================
    
    // vQ and vP are "velocities" of the thermostat/barostat particles
    p_system->vQ = 0.0;
    p_system->vP = 0.0;

    int groNAtoms;
    read_gro(input_gro, p_system, &groNAtoms, atom_info);

    if (groNAtoms != nAtoms)
    {
       printf("Error: groNAtoms(%d) not equal to nAtoms(%d)!\n", 
              groNAtoms, nAtoms);
       exit(1);
    }

    // half of box length for PBC
    p_system->box[3] = p_system->box[0] * 0.5;
    p_system->box[4] = p_system->box[1] * 0.5;
    p_system->box[5] = p_system->box[2] * 0.5;

    p_system->volume = p_system->box[0] * p_system->box[1] * p_system->box[2];
    p_system->inv_volume = 1.0 / p_system->volume;



    //================== set MD variables ==========================

    // degree of freedom
    p_system->ndf = 3 * (nAtoms - number_VSites) - 3 - number_Cstrs;

    // temperature coupling; kT = kB*T, in kJ mol^-1
    p_runset->kT    = K_BOLTZ * p_runset->ref_temp;
    p_system->qMass = (double)p_system->ndf * p_runset->kT * p_runset->tau_temp * p_runset->tau_temp;
    //p_system->pMass = (double)p_system->ndf * p_runset->kT * p_runset->tau_pres * p_runset->tau_pres;


    // temperature control
    p_system->first_temp = 0.0;
    p_system->ext_temp = 0.0;


    // time step
    p_runset->dt_2 = 0.5 * p_runset->dt;


    //=================== CPIM matrix and arrays =========================
    // Relay matrix
    // external electric field and potential
    // induced dipoles and charges
    
    double *data_relay = NULL;

    // dimension of matrix: 4M + n_NPs
    int n_mat = p_metal->num * 4 + p_metal->n_NPs;

    // initialize mat_relay, vec_ext and vec_pq
    if (p_metal->min >=0 && p_metal->max >= p_metal->min)
    {
        data_relay = my_malloc_2(sizeof(double) * n_mat * 3, "data_relay");

        p_metal->vec_pq  = &(data_relay[0]);
        p_metal->vec_ext = &(data_relay[n_mat]);
        p_metal->diag_relay = &(data_relay[n_mat * 2]);

        int i_mat;
        for(i_mat = 0; i_mat < n_mat; ++ i_mat)
        {
            p_metal->vec_pq[i_mat]  = 0.0;
            p_metal->vec_ext[i_mat] = 0.0;
            p_metal->diag_relay[i_mat] = 1.0;
        }
    }


    //================== compute forces ==========================

    mpi_force(p_task, p_topol, atom_info, mol_info,
              p_runset, p_metal, p_system,
              my_id, num_procs, time_used);


    //========== file handles: gro, vec_pq, binary dat, parameters ========
    
    FILE *file_gro, *file_pq, *file_dat;
    file_gro = NULL;
    file_pq  = NULL;
    file_dat = NULL;


    //========== adjust velocities and write trajectories =================

    if (root_process == my_id) 
    {
        // sum potential energies
        sum_potential(p_system->potential);

        // update temperature
        remove_comm(nAtoms, atom_info, p_system);
        kinetic_energy(p_system, nAtoms, atom_info);

        // save the starting temperature
        p_system->first_temp = p_system->inst_temp;
        p_system->ext_temp   = p_runset->ref_temp;

        // creat traj.gro for writing
        file_gro = fopen("traj.gro","w") ;
        if (NULL == file_gro) 
        {
            printf( "Cannot write to traj.gro!\n" ) ;
            exit(1);
        }

        // creat vec_pq.txt for writing
        file_pq = fopen("vec_pq.txt","w") ;
        if (NULL == file_pq) 
        {
            printf( "Cannot write to vec_pq.txt!\n" ) ;
            exit(1);
        }

        // creat traj.dat for writing
        file_dat = fopen("traj.dat","w") ;
        if (NULL == file_dat) 
        {
            printf( "Cannot write to traj.dat!\n" ) ;
            exit(1);
        }

        // get maximal force
        get_fmax_rms(nAtoms, p_system);

        // write the starting geometry to gro and dat file
        write_gro(file_gro, p_system, nAtoms, atom_info, 0);
        write_binary(file_dat, p_system, nAtoms, 0);

        if (p_metal->min >=0 && p_metal->max >= p_metal->min)
        {
            write_vec_pq(file_pq, p_metal, 0);
        }


        printf("              .---------------- start MD calculation ---------------.\n");
        printf("\n");

        // check p_runset->run_type
        if (0 == strcmp(p_runset->run_type, "em") || 
            0 == strcmp(p_runset->run_type, "cg"))
        {
            printf("    Step %-5d Fmax=%10.3e  E=%15.8e\n", 
                    0, p_system->f_max, p_system->potential[0]);
        }
        else if (0 == strcmp(p_runset->run_type, "md"))
        {
            printf("  %10.3f  Fmax=%.2e  E=%.6e  T=%.3e\n", 
                   0.0, p_system->f_max, p_system->potential[0], 
                   p_system->inst_temp);
        }
    }


    //========= Now start MD steps ============================

    int step = 0;

    //===================================================
    // Energy minimization using steepest descent or CG
    //===================================================

    if (0 == strcmp(p_runset->run_type, "em") || 
        0 == strcmp(p_runset->run_type, "cg"))
    {
        p_system->vQ = 0.0;
        p_system->vP = 0.0;

        int converged = 0;
        double gamma = 0.0;
        double delta_pot;

        // initialize direction sx,sy,sz
        for(i = 0; i < nAtoms; ++ i)
        {
            p_system->old_fx[i] = p_system->fx[i];
            p_system->old_fy[i] = p_system->fy[i];
            p_system->old_fz[i] = p_system->fz[i];

            p_system->sx[i] = p_system->fx[i];
            p_system->sy[i] = p_system->fy[i];
            p_system->sz[i] = p_system->fz[i];
        }

        for(step = 1; step <= p_runset->em_steps && 0 == converged; ++ step) 
        {
            // update coordinates on root processor
            if (root_process == my_id) 
            {
                p_system->old_potential = p_system->potential[0];

                for(i = 0; i < nAtoms; ++ i)
                {
                    p_system->old_rx[i] = p_system->rx[i];
                    p_system->old_ry[i] = p_system->ry[i];
                    p_system->old_rz[i] = p_system->rz[i];

                    // fix metal coordinates?
                    if (1 == p_metal->fix_pos && 1 == atom_info[i].is_metal)
                    {
                        continue;
                    }

                    p_system->rx[i] += p_system->sx[i] / p_system->f_max * p_runset->em_length;
                    p_system->ry[i] += p_system->sy[i] / p_system->f_max * p_runset->em_length;
                    p_system->rz[i] += p_system->sz[i] / p_system->f_max * p_runset->em_length;
                }

                // apply constraints
                rattle_1st(p_runset->dt, mol_info, atom_info, p_topol, p_system);

                // zero velocities
                for(i = 0; i < nAtoms; ++ i)
                {
                    p_system->vx[i] = 0.0;
                    p_system->vy[i] = 0.0;
                    p_system->vz[i] = 0.0;
                }
            }

            // update forces
            mpi_force(p_task, p_topol, atom_info, mol_info,
                       p_runset, p_metal, p_system,
                      my_id, num_procs, time_used);

            if (root_process == my_id) 
            {
                // check potential and fmax on root processor
                sum_potential(p_system->potential);
                get_fmax_rms(nAtoms, p_system);
                delta_pot = p_system->potential[0] - p_system->old_potential;

                if (delta_pot <= 0.0) 
                { 
                    p_runset->em_length *= 1.2; 
                }
                else 
                { 
                    p_runset->em_length *= 0.2; 
                }
                
                // print info and write to the gro file
                printf("    Step %-5d Fmax=%10.3e  E=%15.8e\n", 
                        step, p_system->f_max, p_system->potential[0]);

                // write trajectories
                write_gro(file_gro, p_system, nAtoms, atom_info, step);
                write_binary(file_dat, p_system, nAtoms, step);

                if (p_metal->min >=0 && p_metal->max >= p_metal->min)
                {
                    write_vec_pq(file_pq, p_metal, step);
                }

                // check convergence
                if (p_system->f_max < p_runset->em_tol && 
                    p_system->f_rms < p_runset->em_tol * 0.5 && 
                    fabs(delta_pot) < p_runset->em_tol * 0.1)
                {
                    printf("\n");
                    printf("    F_max   (%13.6e) smaller than %e\n", 
                            p_system->f_max, p_runset->em_tol);
                    printf("    F_rms   (%13.6e) smaller than %e\n", 
                            p_system->f_rms, p_runset->em_tol * 0.5);
                    printf("    delta_E (%13.6e) smaller than %e\n", 
                            delta_pot, p_runset->em_tol * 0.1);
                    printf("\n");
                    printf("    ===========  Optimization converged ============\n");
                    converged = 1;
                }
                else
                {
                    // update gamma for CG optimization
                    // for steep descent, gamma = 0.0
                    if (0 == strcmp(p_runset->run_type, "cg"))
                    {
                        double g22 = 0.0;
                        double g12 = 0.0;
                        double g11 = 0.0;
                        for(i = 0; i < nAtoms; ++ i)
                        {
                            g22 += p_system->fx[i] * p_system->fx[i] + 
                                   p_system->fy[i] * p_system->fy[i] + 
                                   p_system->fz[i] * p_system->fz[i];
                            g12 += p_system->old_fx[i] * p_system->fx[i] + 
                                   p_system->old_fy[i] * p_system->fy[i] + 
                                   p_system->old_fz[i] * p_system->fz[i];
                            g11 += p_system->old_fx[i] * p_system->old_fx[i] + 
                                   p_system->old_fy[i] * p_system->old_fy[i] + 
                                   p_system->old_fz[i] * p_system->old_fz[i];
                        }
                        gamma = (g22 - g12) / g11;
                    }

                    for(i = 0; i < nAtoms; ++ i)
                    {
                        p_system->sx[i] = p_system->fx[i] + gamma * p_system->sx[i];
                        p_system->sy[i] = p_system->fy[i] + gamma * p_system->sy[i];
                        p_system->sz[i] = p_system->fz[i] + gamma * p_system->sz[i];

                        p_system->old_fx[i] = p_system->fx[i];
                        p_system->old_fy[i] = p_system->fy[i];
                        p_system->old_fz[i] = p_system->fz[i];
                    }
                }

                // communicate convergence
                for(an_id = 1; an_id < num_procs; ++ an_id) 
                {
                    ierr = MPI_Send(&converged, 1, MPI_INT, an_id, tag_99, MPI_COMM_WORLD);
                }
            }
            else
            {
                ierr = MPI_Recv(&converged, 1, MPI_INT, root_process, tag_99, 
                                MPI_COMM_WORLD, &status);
            }

            // exit loop if converged
            if (1 == converged) { break; }
        }
    }


    //===============================
    // MD with nvt ensemble
    //===============================

    else if (0 == strcmp(p_runset->run_type, "md"))
    {
        for (step = 1; step <= p_runset->nSteps; ++ step) 
        {
            if (root_process == my_id) 
            {
                // gradually increase the reference temperature
                if (step < p_runset->nHeating)
                {
                    p_runset->ref_temp = 
                        p_system->first_temp + 
                        (p_system->ext_temp - p_system->first_temp) * step / p_runset->nHeating;
                }
                else
                {
                    p_runset->ref_temp = p_system->ext_temp;
                }

                // update kT accordingly
                p_runset->kT = K_BOLTZ * p_runset->ref_temp;
            
                // thermostat for 1st half step
                if (0 == strcmp(p_runset->ensemble, "nvt"))
                {
                    nose_hoover(p_runset, p_system, nAtoms);
                }

                // update velocity for 1st half step
                for(i = 0; i < nAtoms; ++ i)
                {
                    // fix metal coordinates?
                    if (1 == p_metal->fix_pos && 1 == atom_info[i].is_metal)
                    {
                        continue;
                    }

                    // for virtual sites, inv_mass == 0.0;
                    double inv_mass = atom_info[i].inv_mass;
                    p_system->vx[i] += p_runset->dt_2 * p_system->fx[i] * inv_mass;
                    p_system->vy[i] += p_runset->dt_2 * p_system->fy[i] * inv_mass;
                    p_system->vz[i] += p_runset->dt_2 * p_system->fz[i] * inv_mass;
                }

                // update position for the whole time step
                // using velocity at half time step
                for(i = 0; i < nAtoms; ++ i)
                {
                    // fix metal coordinates?
                    if (1 == p_metal->fix_pos && 1 == atom_info[i].is_metal)
                    {
                        continue;
                    }

                    p_system->old_rx[i] = p_system->rx[i];
                    p_system->old_ry[i] = p_system->ry[i];
                    p_system->old_rz[i] = p_system->rz[i];

                    p_system->rx[i] += p_runset->dt * p_system->vx[i];
                    p_system->ry[i] += p_runset->dt * p_system->vy[i];
                    p_system->rz[i] += p_runset->dt * p_system->vz[i];
                }

                // apply constraints for the 1st half
                rattle_1st(p_runset->dt, mol_info, atom_info, p_topol, p_system);
            }


            // compute forces
            mpi_force(p_task, p_topol, atom_info, mol_info,
                       p_runset, p_metal, p_system,
                      my_id, num_procs, time_used);
            

            // update velocities
            if (root_process == my_id) 
            {
                // sum potential energies
                sum_potential(p_system->potential);

                // update velocity for 2nd half step
                for(i = 0; i < nAtoms; ++ i)
                {
                    // fix metal coordinates?
                    if (1 == p_metal->fix_pos && 1 == atom_info[i].is_metal)
                    {
                        continue;
                    }

                    // for virtual sites, inv_mass == 0.0;
                    double inv_mass = atom_info[i].inv_mass;
                    p_system->vx[i] += p_runset->dt_2 * p_system->fx[i] * inv_mass;
                    p_system->vy[i] += p_runset->dt_2 * p_system->fy[i] * inv_mass;
                    p_system->vz[i] += p_runset->dt_2 * p_system->fz[i] * inv_mass;
                }

                // apply constraints for the 2nd half
                rattle_2nd(p_runset->dt, mol_info, atom_info, p_topol, p_system);

                // update temperature
                kinetic_energy(p_system, nAtoms, atom_info);


                // thermostat for 2nd half step
                if (0 == strcmp(p_runset->ensemble, "nvt"))
                {
                    nose_hoover(p_runset, p_system, nAtoms);
                }


                // remove center of mass motion and update temperature
                remove_comm(nAtoms, atom_info, p_system);
                kinetic_energy(p_system, nAtoms, atom_info);


                // print information for this step
                if (0 == step % p_runset->nSave)
                {
                    // apply PBC
                    apply_pbc(nMols, mol_info, p_system->rx, p_system->ry, p_system->rz, p_system->box);
             
                    get_fmax_rms(nAtoms, p_system);
                    printf("  %10.3f  Fmax=%.2e  E=%.6e  T=%.3e (%.1f)\n", 
                           p_runset->dt * step, p_system->f_max, p_system->potential[0], 
                           p_system->inst_temp, p_runset->ref_temp);

                    // write to dat file
                    write_binary(file_dat, p_system, nAtoms, step);
                }
             
                // regularly write to gro file
                if (0 == step % (p_runset->nSave*10))
                {
                    write_gro(file_gro, p_system, nAtoms, atom_info, step);

                    if (p_metal->min >=0 && p_metal->max >= p_metal->min)
                    {
                        write_vec_pq(file_pq, p_metal, step);
                    }
                }
            }

        }
    }


    //=========== Finalize MD ====================
    
    sum_time_used(time_used, my_id, num_procs);

    if (root_process == my_id) 
    {
        fclose(file_dat);
        fclose(file_pq);
        fclose(file_gro);

#ifdef DEBUG
        int i;
        for(i = 0; i < nAtoms; ++ i)
        {
            printf("    f[%5d]= %12.5e, %12.5e, %12.5e\n", 
                    i, p_system->fx[i], p_system->fy[i], p_system->fz[i]);
        }
#endif

        printf("\n");
        printf("\n");
        printf("              .------------- final potential energies --------------.\n");
        printf("\n");

        print_potential(p_system->potential);

        time_t end_t = time(NULL);
        gettimeofday(&tv, NULL);
        double end_time = (tv.tv_sec) + (tv.tv_usec) * 1.0e-6;

        printf("    Calculation ended normally at %s", ctime(&end_t));
        printf("    %.3f seconds were used\n", end_time - start_time );
        printf("\n");
        printf("\n");

        printf("              .------------------- time usage ----------------------.\n");
        printf("\n");

        analyze_time_used(time_used, num_procs);
        printf("\n");
    }

    // free arrays
    for(an_id = 0; an_id < num_procs; ++ an_id)
    {
        free(time_used[an_id]);
    }
    free(time_used);

    free(p_metal->cpff_chg);
    free(p_metal->start_NP);
    free(p_metal->end_NP);

    free(data_bonded);
    data_bonded = NULL;

    for(mol = 0; mol < p_topol->mol_types; ++ mol) 
    {
        int atom_i;
        for(atom_i = 0; atom_i < p_topol->atom_num[mol]; ++ atom_i) 
        {
            free(p_topol->exclude[mol][atom_i]);
        }

        free(p_topol->exclude[mol]);

        free(p_topol->bond_param[mol]);
        free(p_topol->pair_param[mol]);
        free(p_topol->angle_param[mol]);
        free(p_topol->dihedral_param[mol]);

        free(p_topol->vsite_4[mol]);
        free(p_topol->vsite_funct[mol]);

        free(p_topol->constraint[mol]);
    }

    free(p_topol->exclude);

    free(p_topol->bond_param);
    free(p_topol->pair_param);
    free(p_topol->angle_param);
    free(p_topol->dihedral_param);
    p_topol->bond_param = NULL;
    p_topol->pair_param = NULL;
    p_topol->angle_param = NULL;
    p_topol->dihedral_param = NULL;

    free(p_topol->vsite_4);
    free(p_topol->vsite_funct);
    p_topol->vsite_4 = NULL;
    p_topol->vsite_funct = NULL;

    free(p_topol->constraint);
    p_topol->constraint = NULL;

    free(p_topol->mol_num);
    free(p_topol->atom_num);
    for(mol = 0; mol < p_topol->mol_types; ++ mol) 
    {
        free(p_topol->atom_param[mol]);
    }
    free(p_topol->atom_param);

    if (p_metal->min >=0 && p_metal->max >= p_metal->min)
    {
        free(p_metal->inv_sqrt_dens);
        p_metal->inv_sqrt_dens = NULL;

        free(data_relay);
        //free(p_metal->mat_relay);
        data_relay = NULL;
        //p_metal->mat_relay = NULL;
        p_metal->vec_pq    = NULL;
        p_metal->vec_ext   = NULL;
        p_metal->diag_relay = NULL;
    }



    free(data_start_end);
    free(data_long_start_end);
    data_start_end      = NULL;
    data_long_start_end = NULL;

    p_task->start_mol   = NULL;
    p_task->end_mol     = NULL;
    p_task->start_atom  = NULL;
    p_task->end_atom    = NULL;
    p_task->start_metal = NULL;
    p_task->end_metal   = NULL;
    p_task->start_pair  = NULL;
    p_task->end_pair    = NULL;

    free(atom_info);
    free(mol_info);
    atom_info = NULL;
    mol_info  = NULL;

    free(data_potential);
    data_potential = NULL;
    p_system->potential   = NULL;
    p_system->partial_pot = NULL;


    free(p_system->virial);
    free(p_system->partial_vir);
    free(data_vir);


    free(p_system->box);
    p_system->box = NULL;

    free(data_rvf);
    data_rvf = NULL;
    p_system->rx = NULL;
    p_system->ry = NULL;
    p_system->rz = NULL;
    p_system->vx = NULL;
    p_system->vy = NULL;
    p_system->vz = NULL;
    p_system->fx = NULL;
    p_system->fy = NULL;
    p_system->fz = NULL;
    p_system->partial_fx = NULL;
    p_system->partial_fy = NULL;
    p_system->partial_fz = NULL;
    p_system->old_rx = NULL;
    p_system->old_ry = NULL;
    p_system->old_rz = NULL;
    p_system->old_fx = NULL;
    p_system->old_fy = NULL;
    p_system->old_fz = NULL;
    p_system->sx = NULL;
    p_system->sy = NULL;
    p_system->sz = NULL;

    free(p_topol->nonbonded_param);
    free(data_nonbonded);
    p_topol->nonbonded_param = NULL;
    data_nonbonded = NULL;

    free(p_task);
    free(p_system);
    free(p_topol);
    free(p_metal);
    free(p_runset);
    p_task   = NULL;
    p_system = NULL;
    p_topol  = NULL;
    p_metal  = NULL;
    p_runset = NULL;

    ierr = MPI_Finalize();

    if (ierr) {}

    return 0;
}
Ejemplo n.º 24
0
static void
time_integration_loop(Forceinfo *fi, Nbodyinfo *nb)
{
    int i, nstep;
    int outsnapstep, outimagestep;
    double W, K, E0, E, Q;
    double cm[3], cmv[3];
    double t = tstart;

    nstep = (int)((tend-tstart)/dt+0.1);
    dt = (tend-tstart)/nstep;
    outsnapstep = (int) (dtsnapout/dt+0.1);
    outimagestep = (int) (dtimageout/dt+0.1);
    PR(tstart,f); PR(tend,f); PR(dt,f); PRL(dtsnapout,f); PRL(dtimageout,f);

    if (cputime_flag) {
	vtc_turnon_cputime();
    }
    vtc_init_cputime();
    vtc_print_cputime("initial vtc_get_force start at");

#if DIRECT /* direct sum */
    if (grape_flag) {
	vtc_set_scale(512.0, nb->m[0]);
#if MDGRAPE2
	fi->calculator = GRAPE_FORCEONLY;
#else
	fi->calculator = GRAPE;
#endif /* MDGRAPE2 */
	vtc_get_force_direct(fi, nb);
#if CALCPOTENTIAL && MDGRAPE2
        fi->calculator = GRAPE_POTENTIALONLY;
        vtc_get_force_direct(fi, nb);
	fi->calculator = GRAPE_FORCEONLY;
#endif /* CALCPOTENTIAL && MDGRAPE2 */
    }
    else {
#if CALCPOTENTIAL
        fi->calculator = HOST;
#endif /* CALCPOTENTIAL */
	vtc_get_force_direct(fi, nb);
    }
#else /* tree */
    if (grape_flag) {
#if NOFORCE
	fi->calculator = NOCALCULATOR;
#elif MDGRAPE2
	fi->calculator = GRAPE_FORCEONLY;
#else
	fi->calculator = GRAPE;
#endif /* NOFORCE */
	vtc_get_force_tree(fi, nb);
#if CALCPOTENTIAL && MDGRAPE2
        fi->calculator = GRAPE_POTENTIALONLY;
        vtc_get_force_tree(fi, nb);
	fi->calculator = GRAPE_FORCEONLY;
#endif /* CALCPOTENTIAL && MDGRAPE2 */
    }
    else {
#if CALCPOTENTIAL
        fi->calculator = HOST;
#endif /* CALCPOTENTIAL */
	vtc_get_force_tree(fi, nb);
    }
#endif
    vtc_print_cputime("initial vtc_get_force end at");
    fprintf(stderr, "ninteraction: %e list_len_avg: %6.5f nwalk: %d\n",
	    fi->ninteraction, (double)fi->ninteraction/nb->n, fi->nwalk);
    K = get_kinetic_energy(nb);
#if CALCPOTENTIAL
    W = get_potential_energy(nb);
    E = E0 = W+K;
    PR(E0, 20.17f); PR(W, 20.17f);
#endif
    PRL(K, f);
    plot_nbody(t, nb);

    /* calculate force at T=0 and quit */
    if (snapout_flag && dtsnapout == 0.0) {
	static int nout = 0;
	char fn[255];
	snapout_acc_flag = 1;
	sprintf(fn, snapoutfile, nout);
	PRL(fn, s);
	if (ionemo_flag) {
	    write_binary(fn, t, nb);
	}
	else if (usepob_flag) {
	    write_pob(fn, t, nb);
	}
	else {
	    write_ascii(fn, t, nb);
	}
	vtc_print_cputime("exit at");
#if USE_GM_API
	fprintf(stderr, "will m2_gm_finalize...\n");
	m2_gm_finalize();
	fprintf(stderr, "done m2_gm_finalize.\n");
#endif /* USE_GM_API */
    }
    for (i = 0; i < nstep; i++) {
 	if (i%outlogstep == outlogstep - 1 && cputime_flag) {
	    vtc_turnon_cputime();
	}
	else {
	    vtc_turnoff_cputime();
	}

	fprintf(stderr, "step %d\n", i);
        push_velocity(0.5*dt, nb);
        push_position(dt, nb);
	t = tstart+(i+1)*dt;
	vtc_init_cputime();
#if DIRECT /* direct sum */
	vtc_get_force_direct(fi, nb);
#else /* tree */
	vtc_get_force_tree(fi, nb);
#endif
	vtc_print_cputime("vtc_get_force end at");
        push_velocity(0.5*dt, nb);
	vtc_print_cputime("integration end at");

	plot_nbody(t, nb);
 	if (i%outlogstep == outlogstep - 1) {
	    fprintf(stderr, "ninteraction: %e list_len_avg: %6.5f nwalk: %d\n",
		    fi->ninteraction, fi->ninteraction/nb->n, fi->nwalk);
	    K = get_kinetic_energy(nb);
#if CALCPOTENTIAL
#if MDGRAPE2
	    if (grape_flag) {
		fi->calculator = GRAPE_POTENTIALONLY;
#if DIRECT /* direct sum */
		vtc_get_force_direct(fi, nb);
#else /* tree */
		vtc_get_force_tree(fi, nb);
#endif /* direct/tree */
		fi->calculator = GRAPE_FORCEONLY;
	    }
#endif /* MDGRAPE2 */
	    W = get_potential_energy(nb);
	    E = W+K;
	    Q = K/(K-E);
	    fprintf(stderr, "\nT= %f K= %20.17f Q= %20.17f E= %20.17f Eerr= %20.17f Eabserr= %20.17f\n",
		    t, K, Q, E, (E0-E)/E0, E0-E);
#else /* CALCPOTENTIAL */
	    fprintf(stderr, "\nT= %f K= %20.17f\n", t, K);
#endif /* CALCPOTENTIAL */
	    fprintf(stderr, "step: %d\n", i);
	    get_cmterms(nb, cm, cmv);
	    fprintf(stderr, "CM  %15.13e %15.13e %15.13e\n",
		    cm[0], cm[1], cm[2]);
	    fprintf(stderr, "CMV %15.13e %15.13e %15.13e\n",
		    cmv[0], cmv[1], cmv[2]);
 	}
	if (i%outsnapstep == outsnapstep - 1 && snapout_flag) {
	    static int nout = 0;
	    char fn[255];
	    char cmd[255];

	    sprintf(fn, snapoutfile, nout);
	    PRL(fn, s);
	    if (ionemo_flag) {
		write_binary(fn, t, nb);
	    }
	    else if (usepob_flag) {
		write_pob(fn, t, nb);
	    }
	    else {
		write_ascii(fn, t, nb);
	    }

	    if (command_exec_flag) {
		sprintf(cmd, "%s %s %03d", command_name, fn, nout);
		fprintf(stderr, "execute %s\n", cmd);
		system(cmd);
	    }
	    nout++;
	    PR(t, f); PRL(fn, s);
	}
	if (i%outimagestep == outimagestep - 1 && imageout_flag) {
	    static int nout = 0;
	    char fn[255];
	    char cmd[255];
	    char msg[255];
	    double center[2];

	    sprintf(fn, snapoutfile, nout);
	    strcat(fn, ".gif");
	    PRL(fn, s);

	    sprintf(msg, "t: %5.3f", t);
	    center[0] = 0.0;
	    center[1] = 0.0;
	    // vtc_plotstar(fn, nb, msg, image_scale, center, 1e10, NULL, NULL);
	    // vtc_plotstar(nb->x, nb->m, nb->n, t, image_scale, fn);
	    nout++;
	    PR(t, f); PRL(fn, s);
	}
	vtc_print_cputime("exit at");
    } /* i loop */
}
Ejemplo n.º 25
0
Archivo: main.cpp Proyecto: bsod/sprot
// program entry point
int main(int argc, char* argv[])
{
  int option_index = 0, c, i;
  char* progname = argv[0];
  static const char* getopt_string = "gvhlt:p:f:bs:";
  static struct option long_options[] =
    {
      {"version",       0,0,'v'},
      {"help",          0,0,'h'},
      {"list",          0,0,'l'},
      {"template-file", 1,0,'t'},
      {"project",       1,0,'p'},
      {"flavor",        1,0,'f'},
      {"write-binary",  0,0,'b'},
      {"snippet",       1,0,'s'},
      {"git",           0,0,'g'},
      {0,0,0,0}
    };

  // select default template file in homedir
  std::string homedir = sysdep_get_homedir();
  option_template_file = homedir + "/" + DEFAULT_TEMPLATE_FILE;
  
  while ((c = getopt_long(argc, argv, getopt_string, long_options, &option_index)) != EOF)
    {
      switch (c)
	{
	case 'v':		/* version */
	  std::cout 
	    << progname
	    << " (GNU "
	    << PACKAGE_NAME 
	    << ") "
	    << PACKAGE_VERSION
	    << "\n\n"
	    << _(
		 "Copyright (C) 2009 Bert van der Weerd.\n"
		 "This is free software; see the source for copying conditions.  There is NO\n"
		 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
		 "\nThis program is dedicated to the loving memory of KaleGek, my friend.\n"
		 )
	    ;
	  return 0;
	                  
	case 'h':		/* help */
	help:
	  std::cout 
	    << 
	    "Generate text source files and projects from a standard template.\n"
	    "\n"
	    "Usage: sprot [-f FLAVOR] FILE...\n"
	    "       sprot -l\n"
	    "       sprot -p PROJECT NAME...\n"
	    "       sprot -b FILE...\n"
	    "       sprot -s SNIPPET\n"
	    "\n"
	    "  -g, --git                     Create git repository, set $(name) and $(email), check in files.\n"
	    "\n"
	    "  -b,--write-binary             Write input files to standard output as a hexadecimal dump\n"
	    "  -f FLAVOR, --flavor=FLAVOR    Specify template flavor for a specific template extension\n"
	    "  -h, --help                    Display this help and exit\n"
	    "  -l, --list                    Display contents of the template file\n"
	    "  -p PROJECT, --project=PROJECT Select PROJECT from template file and generate it under name of FILE\n"
            "  -s SNIPPET, --snippet=SNIPPET Print SNIPPET on stdout.\n"
	    "  -t FILE, --template-file=FILE Use FILE as template file (works with any sprot invocation)\n"
	    "  -v, --version                 Display version information and exit\n"
	    "\n"
	    "Please report bugs and ideas to <"
	    << PACKAGE_BUGREPORT 
	    << ">.\n"
	    ;
	  return 0;

	case 'g':
	  option_do_git = true;
	  break;
	                  
	case 'l':		// list
	  option_list = true;
	  break;

	case 'b':
	  option_write_binary = true;
	  break;

	case 't':
	  option_template_file = std::string(optarg);
	  break;
	  
	case 'p':
	  option_project_mode = true;
	  option_project_name = std::string(optarg);
	  break;

	case 's':
	  option_snippet_mode = true;
	  option_snippet_name = std::string(optarg);

	case 'f':
	  option_flavor = std::string(optarg);
	  break;

	default:		/* getopt() returned invalid value */
	  return 1;
	}
    }


  if (option_list && option_write_binary)
    {
      std::cerr << progname << _(": Cannot specify option -b and -l at the same time.") << std::endl;
      return 1;
    }

  if (option_write_binary)
    {
      if (optind == argc)
	{
	  std::cerr << progname << _(": Please specify one or more files to write out as binary.") << std::endl;
	  return 1;
	}
      else
	for (int i = optind; i < argc; i++)
	  if (write_binary(argv[i]) != 0) return 1;

      return 0;
    }


  if (option_list) {
    if (optind != argc) 
      std::cerr 
	<< progname 
	<< _(": Cannot have arguments when specifying -l option (list template file)")
	<< std::endl;
    else 
      {

	sprot_datafile datafile;

	try 
	  {
	    datafile.parse(option_template_file);
	  }
	catch (std::exception& ex)
	  {
	    std::cerr << option_template_file << ": " << ex.what() << std::endl;
	    return 1;
	  }

	list_sprotfile_contents(datafile);

      }
    return 0;
  }


  if (optind == argc && !option_snippet_mode) goto help;


  // read the sprot datafile
  sprot_datafile datafile;

  try 
    {
      datafile.parse(option_template_file);
    }
  catch (std::exception& ex)
    {
      std::cerr << option_template_file << ": " << ex.what() << std::endl;
      return 1;
    }

  // the actual work
  if (option_project_mode)
    {
      for(i = optind; i < argc; i++)
	{
	  int retval = generate_project_initial(datafile,option_project_name,argv[i]);
	  if (retval) return retval;
	}
    }

  else if (option_snippet_mode)
    {
      if (option_snippet_name == "") 
	{
	  std::cerr << progname << ": The snippet name cannot be empty." << std::endl;
	  return 1;
	}
      int retval = generate_snippet_to_stdout(datafile,option_snippet_name);
      return retval;
    }
  else
    {
      for (i = optind; i < argc; i++)
	{
	  int retval = generate_file_initial(datafile,option_flavor,argv[i]);
	  if (retval) return retval;
	}
    }

  return 0;
}