Example #1
0
void GLGPUDataset::SerializeDataInfoToString(std::string& buf) const
{
#if WITH_PROTOBUF
  PBDataInfo pb;

  pb.set_model(PBDataInfo::GLGPU);
  pb.set_name(_data_name);

  if (Lengths()[0]>0) {
    pb.set_ox(Origins()[0]); 
    pb.set_oy(Origins()[1]); 
    pb.set_oz(Origins()[2]); 
    pb.set_lx(Lengths()[0]); 
    pb.set_ly(Lengths()[1]); 
    pb.set_lz(Lengths()[2]); 
  }

  pb.set_bx(B()[0]);
  pb.set_by(B()[1]);
  pb.set_bz(B()[2]);

  pb.set_kex(Kex());

  pb.set_dx(dims()[0]);
  pb.set_dy(dims()[1]);
  pb.set_dz(dims()[2]);

  pb.set_pbc_x(pbc()[0]);
  pb.set_pbc_y(pbc()[0]);
  pb.set_pbc_z(pbc()[0]);

  pb.SerializeToString(&buf);
#endif
}
Example #2
0
File: md2.c Project: kneth/MDreac
void ApplyPerBoundaries(void) {

    size_t i;
    for(i=0; i<(nA+nB); i++) {
        rx[i] += pbc(rx[i]);
        ry[i] += pbc(ry[i]);
    }
}
void force_LJ(mdsys_t *sys) 
{
    double rsq,ffac;
    double rx,ry,rz;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i,j;
    int natoms=sys->natoms;

    /* zero energy and forces */
    sys->epot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    for(i=0; i < natoms-1; ++i) {
        for(j=i+1; j < natoms; ++j) {

            /* particles have no interactions with themselves */
            if (i==j) continue;

            /* get distance between particle i and j */
            rx=pbc(sys->rx[i] - sys->rx[j], b);
            ry=pbc(sys->ry[i] - sys->ry[j], b);
            rz=pbc(sys->rz[i] - sys->rz[j], b);
            rsq = rx*rx + ry*ry + rz*rz;
      
            /* compute force and energy if within cutoff */
            if (rsq < csq) {
		double rsqinv = 1/rsq;
		double r6 = rsqinv*rsqinv*rsqinv;
		double pr = p*r6;
		double p6 = 4.0*sys->epsilon*pr;
                double p12 = p6*pr;

		ffac = rsqinv*(12*p12-6*p6);
                
                sys->epot += 0.5*(p12-p6);

                sys->fx[i] += rx*ffac;
                sys->fy[i] += ry*ffac;
                sys->fz[i] += rz*ffac;
                sys->fx[j] -= rx*ffac;
                sys->fy[j] -= ry*ffac;
                sys->fz[j] -= rz*ffac;

            }
        }
    }
}
void force_morse(mdsys_t *sys) 
{
    double rsq,ffac;
    double rx,ry,rz;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i,j;
    int natoms=sys->natoms;

    /* zero energy and forces */
    sys->epot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    for(i=0; i < natoms-1; ++i) {
        for(j=i+1; j < natoms; ++j) {

            /* particles have no interactions with themselves */
            if (i==j) continue;

            /* get distance between particle i and j */
            rx=pbc(sys->rx[i] - sys->rx[j], b);
            ry=pbc(sys->ry[i] - sys->ry[j], b);
            rz=pbc(sys->rz[i] - sys->rz[j], b);
            rsq = rx*rx + ry*ry + rz*rz;
			rs = sqrt(rsqi);
			rsq = rx*rx + ry*ry + rz*rz;

	       /* compute force and energy if within cutoff */
	       if (rsq < csq) {

			   esp = exp((-1)*sys->a*(rs-sys->rzero));
			   espq = exp((-1)*sys->a*(rs-sys->rzero)*(rs-sys->rzero));			 
			   
			   ffac = 2*sys->De * (1-esp)*sys->a*esp;
			   sys->epot += sys->De*(1-espq)


                sys->fx[i] += rx*ffac;
                sys->fy[i] += ry*ffac;
                sys->fz[i] += rz*ffac;
                sys->fx[j] -= rx*ffac;
                sys->fy[j] -= ry*ffac;
                sys->fz[j] -= rz*ffac;

            }
        }
    }
}
Example #5
0
static int	send_broadcast(t_server *server, t_player *player, t_list tmp,
			       char *params)
{
  t_player	*tmp_player;
  int		tile;
  char		buffer[4096];
  unsigned int	i;

  i = -1;
  while (++i < list_get_size(tmp))
    {
      if ((tmp_player = list_get_elem_at_position(tmp, i)) != NULL
	  && tmp_player->sock != player->sock)
	{
	  tile = determine_best_way(server, player, tmp_player);
	    if (memset(buffer, 0, 1024) == NULL
		|| snprintf(buffer, 1024, BROADCAST,
			    tile, params) == -1)
	    return (-1);
	  if (store_answer_p(tmp_player, strdup(buffer), 0) == -1)
	    return (-1);
	}
    }
  return (pbc(server, player));
}
Example #6
0
int main (int argc, char *argv[]) {
     double frce;
     
     input();
     inithydro();
     equili();
     initpop();

     for (istep = 1; istep <= nsteps; istep++) {
	  pbc();
	  mbc();
	  move();
	  hydrovar();
	  equili();
	  collis();
	  if (iforce)
	       force(istep, &frce);
	  if (iobst)
	       obst();
	  if (istep % ndiag == 0)
	       diag0D();
	  if (istep % nout == 0)
	       profil(istep, frce);
     }

     return 0;
}
std::vector<ElemIdType> GLGPU3DDataset::GetNeighborIds(ElemIdType elem_id) const
{
  std::vector<ElemIdType> neighbors; 

  int idx[3], idx1[3];
  ElemId2Idx(elem_id, idx); 

  for (int face=0; face<6; face++) {
    switch (face) {
    case 0: idx1[0] = idx[0];   idx1[1] = idx[1];   idx1[2] = idx[2]-1; break; 
    case 1: idx1[0] = idx[0]-1; idx1[1] = idx[1];   idx1[2] = idx[2];   break;
    case 2: idx1[0] = idx[0];   idx1[1] = idx[1]-1; idx1[2] = idx[2];   break;
    case 3: idx1[0] = idx[0];   idx1[1] = idx[1];   idx1[2] = idx[2]+1; break; 
    case 4: idx1[0] = idx[0]+1; idx1[1] = idx[1];   idx1[2] = idx[2];   break;
    case 5: idx1[0] = idx[0];   idx1[1] = idx[1]+1; idx1[2] = idx[2];   break;
    default: break;
    }

#if 0 // pbc
    for (int i=0; i<3; i++) 
      if (pbc()[i]) {
        idx1[i] = idx1[i] % dims()[i]; 
        if (idx1[i]<0) idx1[i] += dims()[i];
      }
#endif
    
    neighbors.push_back(Idx2ElemId(idx1)); 
  }

  return neighbors; 
}
Example #8
0
File: md2.c Project: kneth/MDreac
void MakeList(void) {
    size_t i, j, k, n, jcell;
    double        rxi, ryi;
    double        rxij, ryij, r2;

    Np = 0;
    for(k=0; k<(nCells*nCells); k++) {
        i = head[k];
        rxi = rx[i];
        ryi = ry[i];
        while (i != (nA+nB+1)) {
            j = head[k];
            while (j != (nA+nB+1)) {
                rxij = rxi-rx[j];
                ryij = ryi-ry[j];
                rxij += pbc(rxij);
                ryij += pbc(ryij);
                r2 = rxij*rxij+ryij*ryij;
                if (r2 < (Rbuf*Rbuf)) {
                    ipair[Np] = i;
                    jpair[Np] = j;
                    Np++;
                }
                j = list[j];
            }
            /* now neighboring cells */
            for(n=0; n<4; n++) {
                jcell = map[4*k+n];
                j = head[jcell];
                while (j != (nA+nB+1)) {
                    rxij = rxi-rx[j];
                    ryij = ryi-ry[j];
                    rxij += pbc(rxij);
                    ryij += pbc(ryij);
                    r2 = rxij*rxij+ryij*ryij;
                    if (r2 < (Rbuf*Rbuf)) {
                        ipair[Np] = i;
                        jpair[Np] = j;
                        Np++;
                    }
                    j = list[j];
                }
            }
            i = list[i];
        }
    }
}
Example #9
0
void Bubble:: raw_initialize()
{
    
    Tracer *p = root;
    for( size_t i=size;i>0;--i,p=p->next )
    {
        pbc(p->vertex);
        const Tracer *q = p->next; assert(q!=NULL);
        Vertex        pq(p->vertex,q->vertex);
        pbc(pq);
        p->edge = pq;
        p->s2   = p->edge.norm2();
        p->s    = Sqrt( p->s2 );
    }
    compute_area();
    content = pressure * area;
    compute_geometry();
    
}
Example #10
0
int setup_simulation_box(FILE* finput, system_t* system) {
    // read in input.pqr molecules
    system->molecules = read_molecules(finput, system);
    if (!system->molecules && system->ensemble == ENSEMBLE_REPLAY) {
        output(
            "INPUT: end of trajectory file\n");
        return 1;
    } else if (!system->molecules) {
        error(
            "INPUT: error reading in input molecules\n");
        return (-1);
    } else
        output(
            "INPUT: finished reading in molecules\n");

    //read in pqr box and calculate periodic boundary conditions if neccessary
    if (system->read_pqr_box_on)
        read_pqr_box(finput, system);

    pbc(system);
    if (system->ensemble != ENSEMBLE_SURF && system->ensemble != ENSEMBLE_SURF_FIT) {
        if ((system->pbc->volume <= 0.0) || (system->pbc->cutoff <= 0.0)) {
            error(
                "INPUT: invalid simulation box dimensions.\n");
            return -1;
            ;
        }
    }
    if (system->pbc->volume > 0)
        printboxdim(system->pbc);

    // read in the insertion molecules
    if (system->insert_input) {
        system->insertion_molecules = read_insertion_molecules(system);
        if (!system->insertion_molecules) {
            error(
                "INPUT: error read in insertion molecules\n");
            return -1;
        } else
            output(
                "INPUT: finished reading in insertion molecules\n");
    } else  //else only 1 sorbate type
        system->sorbateCount = 1;

    // now that we've read in the sorbates, we can check that user_fugacities is properly set (if used)
    if (system->user_fugacities) {
        if (system->fugacitiesCount != system->sorbateCount) {
            error(
                "INPUT: number of fugacities set via user_fugacities does not match the number of sorbates.\n");
            return -1;
        }
    }

    return 0;
}
Example #11
0
void		gfx_player_broadcast(t_ctrl *c, t_player *p, char *s)
{
  t_jm_list	*l;

  l = c->l;
  while (l)
    {
      if (l->fd != -1 && l->data && ((t_handler *)l->data)->t == GFX)
	pbc(l, p->id, s);
      l = l->next;
    }
}
Example #12
0
/* compute forces */
void force(mdsys_t *sys) 
{
    double r,ffac;
    double rx,ry,rz;
    int i,j;

    /* zero energy and forces */
    sys->epot=0.0;
    azzero(sys->fx,sys->natoms);
    azzero(sys->fy,sys->natoms);
    azzero(sys->fz,sys->natoms);

    for(i=0; i < (sys->natoms); ++i) {
        for(j=0; j < (sys->natoms); ++j) {

            /* particles have no interactions with themselves */
            if (i==j) continue;
            
            /* get distance between particle i and j */
            rx=pbc(sys->rx[i] - sys->rx[j], 0.5*sys->box);
            ry=pbc(sys->ry[i] - sys->ry[j], 0.5*sys->box);
            rz=pbc(sys->rz[i] - sys->rz[j], 0.5*sys->box);
            r = sqrt(rx*rx + ry*ry + rz*rz);
      
            /* compute force and energy if within cutoff */
            if (r < sys->rcut) {
                ffac = -4.0*sys->epsilon*(-12.0*pow(sys->sigma/r,12.0)/r
                                         +6*pow(sys->sigma/r,6.0)/r);
                
                sys->epot += 0.5*4.0*sys->epsilon*(pow(sys->sigma/r,12.0)
                                               -pow(sys->sigma/r,6.0));

                sys->fx[i] += rx/r*ffac;
                sys->fy[i] += ry/r*ffac;
                sys->fz[i] += rz/r*ffac;
            }
        }
    }
}
Example #13
0
File: md2.c Project: kneth/MDreac
void ComputeForces(void) {
    size_t    i, j, k;
    double           pot;
    double           rxij, ryij, r2, r6, Rc;

#pragma omp parallel for
    for(i=0; i<(nA+nB); i++) { /* reset forces */
        fx[i] = 0.0;
        fy[i] = 0.0;
    }
    Epot = 0.0;
    P    = 0.0;
#pragma omp parallel for
    for(k=0; k<Np; k++) { /* loop over all pairs */
        i = ipair[k];
        j = jpair[k];
        rxij = rx[i]-rx[j];
        ryij = ry[j]-ry[j];
        rxij += pbc(rxij);
        ryij += pbc(ryij);
        r2 = rxij*rxij+ryij*ryij;
        Rc = Rcut(i, j);
        if (r2 > Rc*Rc) {
            r2     = 1.0/r2;
            r6     = r2*r2*r2;
            Epot  += r6*(r6-1.0);
            P     += r6*(r6-0.5);
            pot    = r2*r6*(r6-0.5);
            fx[i] += rxij*pot;
            fy[i] += ryij*pot;
            fx[j] -= rxij*pot;
            fy[j] -= ryij*pot;
        }
    }
    Epot *= 4.0;
}
Example #14
0
/* scale the volume : used in NPT ensemble */
void volume_change(system_t *system) {
    molecule_t *m;
    atom_t *a;
    double new_volume, log_new_volume, basis_scale_factor;
    double new_com[3], old_com[3], delta_pos[3];
    int i, j;

    // figure out what the new volume will be
    if (system->ensemble == ENSEMBLE_REPLAY)
        //if ensemble replay, then we're just trying to calculate the pressure via dV change
        new_volume = system->pbc->volume + system->calc_pressure_dv;
    else {
        log_new_volume = log(system->pbc->volume) + (get_rand(system) - 0.5) * system->volume_change_factor;
        new_volume = exp(log_new_volume);
    }

    //scale basis
    basis_scale_factor = pow(new_volume / system->pbc->volume, 1.0 / 3.0);
    for (i = 0; i < 3; i++)
        for (j = 0; j < 3; j++)
            system->pbc->basis[i][j] *= basis_scale_factor;

    //recalculate PBC stuff (volume/reciprocal basis/cutoff)
    pbc(system);
    system->observables->volume = system->pbc->volume;

    //scale molecule positions
    for (m = system->molecules; m; m = m->next) {
        for (i = 0; i < 3; i++) {
            old_com[i] = m->com[i];  //molecule ptr's com will be udated during pairs routine
            new_com[i] = m->com[i] * basis_scale_factor;
            delta_pos[i] = new_com[i] - old_com[i];
        }
        for (a = m->atoms; a; a = a->next) {  //calculate new atomic positions based on new com
            for (i = 0; i < 3; i++) {
                a->pos[i] += delta_pos[i];
                a->wrapped_pos[i] += delta_pos[i];
            }
        }
    }

    return;
}
Example #15
0
void find(int now,int i,int cur)
{
	int temp=i;
	if(now>bound)
		return;
	if(cur==4)
	{
		i++;
	}
	for(;i<=9;i++)
	{
		if(!flag)
		{
			step[now]=i;
			pfc(i);
			flag=Is();
			find(now+1,i,temp==i?(cur+1):2);
			pbc(i);
		}
	}
}
Example #16
0
/* revert changes to volume */
void revert_volume_change(system_t *system) {
    double basis_scale_factor, new_volume;
    double old_com[3], new_com[3], delta_pos[3];
    molecule_t *m;
    atom_t *a;
    int i, j;
    new_volume = system->checkpoint->observables->volume;

    //un-scale basis
    basis_scale_factor = pow(new_volume / system->pbc->volume, 1.0 / 3.0);  //system->pbc->volume still has rejected value until pbc() is called
    for (i = 0; i < 3; i++)
        for (j = 0; j < 3; j++)
            system->pbc->basis[i][j] *= basis_scale_factor;

    //recalc PBC stuff
    pbc(system);
    system->observables->volume = system->pbc->volume;

    //scale molecule positions
    for (m = system->molecules; m; m = m->next) {
        for (i = 0; i < 3; i++) {
            old_com[i] = m->com[i];  //molecule ptr's com will ned to be updated since this is a revert (no energy call following)
            new_com[i] = m->com[i] * basis_scale_factor;
            m->com[i] = new_com[i];
            delta_pos[i] = new_com[i] - old_com[i];
        }
        for (a = m->atoms; a; a = a->next) {  //calculate new atomic positions based on new com
            for (i = 0; i < 3; i++) {
                a->pos[i] += delta_pos[i];
                a->wrapped_pos[i] += delta_pos[i];
            }
        }
    }
    wrapall(system->molecules, system->pbc);
    return;
}
Example #17
0
/* compute forces */
void force(mdsys_t *sys) 
{
    double r_c2 = sys->rcut * sys->rcut;
    double c1, c2, c3, c4, sig6;
	double epot;
    int i;

    /* zero energy and forces */
    epot=0.0;
    azzero(sys->fx,sys->natoms);
    azzero(sys->fy,sys->natoms);
    azzero(sys->fz,sys->natoms);

    /* Precalculate some of the constants used in the potential */
    sig6 = (sys->sigma)*(sys->sigma)*(sys->sigma) * (sys->sigma)*(sys->sigma)*(sys->sigma);
    c1   = -24.0  * sys->epsilon * sig6;
    c2   =  48.0  * sys->epsilon * sig6 * sig6;
    c3   =  -4.0  * sys->epsilon * sig6;        // Leading 4.0 includes factor 2
    c4   =   4.0  * sys->epsilon * sig6 * sig6; // for using Newton's 3rd law (Epot)

	
#ifdef _OPENMP
	#pragma omp parallel for private(i) reduction(+:epot)	
#endif
    for(i=0; i < (sys->natoms); ++i) {
		
		int j;
		double r6;
		double rxi, ryi, rzi;
		double fx, fy, fz;
		fx = fy = fz = 0.0;

		rxi = sys->rx[i];
		ryi = sys->ry[i];
		rzi = sys->rz[i];

        for(j=i+1; j < (sys->natoms); ++j) {

			double rx, ry, rz;
    		double r2, ffac;

            /* get distance between particle i and j */
            rx = pbc(rxi - sys->rx[j], 0.5*sys->box);
            ry = pbc(ryi - sys->ry[j], 0.5*sys->box);
            rz = pbc(rzi - sys->rz[j], 0.5*sys->box);

            r2 = rx*rx + ry*ry + rz*rz;
      
            /* compute force and energy if within cutoff */
            if (r2 < r_c2) {
                r6 = r2*r2*r2;

                ffac = (c2 + c1*r6) / (r6*r6*r2);
                epot += (c4 + c3*r6) / (r6*r6);
/*
#ifdef _OPENMP
#pragma omp atomic
#endif
               	sys->fx[i] += rx*ffac;
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fy[i] += ry*ffac;
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fz[i] += rz*ffac;
*/
				fx += rx*ffac;
				fy += ry*ffac;
				fz += rz*ffac;

#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fx[j] -= rx*ffac; 
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fy[j] -= ry*ffac;
#ifdef _OPENMP
#pragma omp atomic
#endif
				sys->fz[j] -= rz*ffac;

			}

        } /* end loop j */

#ifdef _OPENMP
#pragma omp atomic
#endif
		sys->fx[i] += fx; 
#ifdef _OPENMP
#pragma omp atomic
#endif
		sys->fy[i] += fy;
#ifdef _OPENMP
#pragma omp atomic
#endif
		sys->fz[i] += fz;
		

    } /* end loop i */

	sys->epot = epot;
}
Example #18
0
int main() {

    // Floating point precision
    typedef double FLOAT;

    // Units
    typedef angstrom<FLOAT> x;                  // length
    typedef K<FLOAT> T;                         // temperature
    typedef u<FLOAT> m;                         // mass
    typedef angstrom_div_ps<FLOAT> v;           // velocity
    typedef angstrom_div_ps2<FLOAT> a;          // acceleration
    typedef u_mul_angstrom_div_ps2<FLOAT> f;    // force
    typedef u_mul_angstrom2_div_ps2<FLOAT> e;   // energy
    typedef ps<FLOAT> t;                        // time

    // Declarations
    auto mass = m(39.948);
    auto temp = T(100);
    auto epsilon = T(119.8);
    auto dx = x(5.26);
    auto sigma = x(3.405);
    auto dt = t(0.01);
    auto t_end = t(10);
    auto N = ARRAYLIST(size_t, 4, 4, 4);
    string molecule[4];
    molecule[0] = "Ar";
    molecule[1] = "Ar";
    molecule[2] = "Ar";
    molecule[3] = "Ar";
    ofstream time_file;
    time_file.open("time.dat");
    auto t0 = clock();

    // Boltzmann velocity dirstribution
    Boltzmann<FLOAT> boltz(temp, mass);
    Gaussian<v> gauss(boltz.StandardDeviation());
    auto boltz_vel = delegate(gauss, &Gaussian<v>::Distribution_mu_0);

    // Models
    typedef VMD<x,Vector<v,3>> pos;
    typedef VMD_Vel<x,v> vel;
    typedef Vector<a,3> va;
    typedef Array<va> acc;
    typedef PBC<pos,vel,acc,void,x,3>::CX pref;
    typedef PBC<pos,vel,acc,void,x,3>::CA aref;
    typedef LJ_Potential<3,x,a,m,f,e> Potential;
    typedef Delegate<void,pref&,aref&> LJ_Solver;
    typedef PBC<pos,vel,acc,LJ_Solver,x,3> Boundary;
    typedef Delegate<void,pos&> PeriodicBoundary;
    typedef Delegate<void,pos&,vel&,acc&> List;
    typedef VelocityVerlet<2,pos,vel,va,List> VerletModel;
    typedef Delegate<void,t&> VerletSolver;

    // Molecular dynamic model
    MD_Model<m,t,x,v,VerletSolver,PeriodicBoundary> model(mass, dt, "Argon centered cubic lattice");
    // Lennard-Jones potenial
    Potential potential(sigma, mass, 0);
    auto LJ_acc = delegate(potential, &Potential::Acceleration<pref,aref>);
    // Periodic bounary condition
    Boundary pbc(LJ_acc);
    for(size_t i = 0; i < 3; i++) {
        pbc.origin[i] = -0.25*dx;
        pbc.range[i] = dx*(N[i]-0.25);
    }
    auto periodic_boundary = delegate(pbc, &Boundary::Boundary<pos>);
    model.boundary = &periodic_boundary;
    auto list = delegate(pbc, &Boundary::NeighbourList);
    auto dist_vec = delegate(static_cast<MinImage<x,3>&>(pbc), &MinImage<x,3>::Distance<x,x>);
    auto dist = delegate(&Euclidean::Length<Vector<x,3>>);
    auto unit_vec = delegate(&Euclidean::UnitVector<x,x,3>);
    potential.dist_vec = &dist_vec;
    potential.dist = &dist;
    potential.unit_vec = &unit_vec;
    // Verlet differential solver
    VerletModel verlet(static_cast<pos&>(model), static_cast<vel&>(model), list);
    auto verlet_solver = delegate(verlet, &VerletModel::Solve<t>);
    model.step = &verlet_solver;

    // Lattice configuration
    model.LatticeCenteredCubic(molecule, dx, N);
    model.SetVelocityDistribution(boltz_vel);
    auto data = static_cast<vel>(model);
    TimeStep<t,decltype(model)> time(model);

    // Task a and b
    /*time.Open("b.xyz");
    time.Print();
    time.Close();*/

    // Task c
    auto step = delegate(model, &decltype(model)::Step<t,decltype(model)>);
    auto Time = time;
    /*Time.Open("c.xyz");
    Run(Time, t_end, step);
    Time.Close();*/

    // Task d
    auto boundary = delegate(model, &decltype(model)::Boundary<t,decltype(model)>);
    /**time.data = data;
    Time = time;
    Time.Open("d.xyz");
    Run(Time, t_end, step, boundary);
    Time.Close();*/

    // Task g
    potential = epsilon * Boltzmann<FLOAT>::kB;
    /**time.data = data;
    Time = time;
    Time.Open("g.xyz");
    verlet = 0;         // Initialize verlet solver
    t0 = clock();
    Run(Time, t_end, step, boundary);
    time_file << (double)(clock()-t0)/CLOCKS_PER_SEC << " & ";
    Time.Close();*/

    // Task h
    for(size_t i = 0; i < 3; i++)
        pbc[i] = (pbc.range[i]-pbc.origin[i])/(3*sigma);
    *time.data = data;
    Time = time;
    Time.Open("h.xyz");
    verlet = 0;         // Initialize verlet solver
    t0 = clock();
    Run(Time, t_end, step, boundary);
    time_file << (double)(clock()-t0)/CLOCKS_PER_SEC << " \\\\ ";
    Time.Close();

    time_file.close();

    return 0;
}
Example #19
0
void Bubble:: upgrade_topology()
{
    assert(size>=3);
    assert(root!=NULL);
    
    //--------------------------------------------------------------------------
    // pass 0: pbc on vertices
    //--------------------------------------------------------------------------
    Tracer *p = root;
    
    for( size_t i=size;i>0;--i,p=p->next)
    {
        pbc(p->vertex);
    }
    
   
    
    //--------------------------------------------------------------------------
    // pass : refinement
    //--------------------------------------------------------------------------
    assert(root==p);
    Tracer *q = p->next;
    for( size_t i=0; i < size; ++i )
    {
        
        for(;;)
        {
            //------------------------------------------------------------------
            // compute length to next vertex, with pbc
            //------------------------------------------------------------------
            Vertex pq(p->vertex,q->vertex);
            pbc(pq);
            p->s2 = pq.norm2(); assert(p->s2>0);
            p->s  = Sqrt( p->s2 );
            
            //------------------------------------------------------------------
            // do we refine ?
            //------------------------------------------------------------------
            if( p->s > lambda )
            {
                Tracer *I   = cache.provide();
                I->vertex.x = p->vertex.x + 0.5 * pq.x;
                I->vertex.y = p->vertex.y + 0.5 * pq.y;
                pbc(I->vertex);
                insert_after(p, I);
                assert(p->next==I);
                assert(I->prev==p);
                q = I;
                continue;
            }
            
            //------------------------------------------------------------------
            // ok, keep that in mind...
            //------------------------------------------------------------------
            p->edge= pq;
            assert(p->s2>0);
            assert(p->s>0);
            break;
        }
        
        //----------------------------------------------------------------------
        // next edge
        //----------------------------------------------------------------------
        p = q;
        q = q->next;
    }
    

}
Example #20
0
/* build and update cell list */
static void updcells(mdsys_t *sys)
{
    int i, ngrid, ncell, npair, midx, natoms;
    double delta, boxby2, boxoffs;
    boxby2 = 0.5 * sys->box;
    natoms = sys->natoms;
        
    if (sys->clist == NULL) {
        int nidx;
        
        ngrid  = floor(cellrat * sys->box / sys->rcut);
        ncell  = ngrid*ngrid*ngrid;
        delta  = sys->box / ngrid;
        boxoffs= boxby2 - 0.5*delta;
        
        sys->delta = delta;
        sys->ngrid = ngrid;
        sys->ncell = ncell;

        /* allocate cell list storage */
        sys->clist = (cell_t *) malloc(ncell*sizeof(cell_t));
        sys->plist = (int *) malloc(2*ncell*ncell*sizeof(int));

        /* allocate index lists within cell. cell density < 2x avg. density */
        nidx = 2*natoms / ncell + 2;
        nidx = ((nidx/2) + 1) * 2;
        sys->nidx = nidx;
        for (i=0; i<ncell; ++i) {
            sys->clist[i].idxlist = (int *) malloc(nidx*sizeof(int));
        }

        /* build cell pair list, assuming newtons 3rd law. */
        npair = 0;
        for (i=0; i < ncell-1; ++i) {
            int j,k;
            double x1,y1,z1;
            
            k  = i/ngrid/ngrid;
            x1 = k*delta - boxoffs;
            y1 = ((i-(k*ngrid*ngrid))/ngrid)*delta - boxoffs;
            z1 = (i % ngrid)*delta - boxoffs;

            for (j=i+1; j<ncell; ++j) {
                double x2,y2,z2,rx,ry,rz;
                
                k  = j/ngrid/ngrid;
                x2 = k*delta - boxoffs;
                y2 = ((j-(k*ngrid*ngrid))/ngrid)*delta - boxoffs;
                z2 = (j % ngrid)*delta - boxoffs;

                rx=pbc(x1 - x2, boxby2, sys->box);
                ry=pbc(y1 - y2, boxby2, sys->box);
                rz=pbc(z1 - z2, boxby2, sys->box);

                /* check for cells on a line that are too far apart */
                if (fabs(rx) > sys->rcut+delta) continue;
                if (fabs(ry) > sys->rcut+delta) continue;
                if (fabs(rz) > sys->rcut+delta) continue;

                /* check for cells in a plane that are too far apart */
                if (sqrt(rx*rx+ry*ry) > (sys->rcut+sqrt(2.0)*delta)) continue;
                if (sqrt(rx*rx+rz*rz) > (sys->rcut+sqrt(2.0)*delta)) continue;
                if (sqrt(ry*ry+rz*rz) > (sys->rcut+sqrt(2.0)*delta)) continue;

                /* other cells that are too far apart */
                if (sqrt(rx*rx + ry*ry + rz*rz) > (sqrt(3.0)*delta+sys->rcut)) continue;
                
                /* cells are close enough. add to list */
                sys->plist[2*npair  ] = i;
                sys->plist[2*npair+1] = j;
                ++npair;
            }
        }
        sys->npair = npair;
        printf("Cell list has %dx%dx%d=%d cells with %d/%d pairs and "
               "%d atoms/celllist.\n", ngrid, ngrid, ngrid, sys->ncell, 
               sys->npair, ncell*(ncell-1)/2, nidx);
    }

    /* reset cell list and sort atoms into cells */
    ncell=sys->ncell;
    delta=sys->delta;
    ngrid=sys->ngrid;
    
    for (i=0; i < sys->ncell; ++i) {
        sys->clist[i].natoms=0;
    }

    boxoffs= boxby2 - 0.5*delta;
    midx=0;
    for (i=0; i < natoms; ++i) {
        int idx,j,k,m,n;
        
        k=floor((pbc(sys->pos[i], boxby2, sys->box)+boxby2)/delta);
        m=floor((pbc(sys->pos[natoms + i], boxby2, sys->box)+boxby2)/delta);
        n=floor((pbc(sys->pos[2*natoms + i], boxby2, sys->box)+boxby2)/delta);
        j = ngrid*ngrid*k+ngrid*m+n;

        idx = sys->clist[j].natoms;
        sys->clist[j].idxlist[idx]=i;
        ++idx;
        sys->clist[j].natoms = idx;
        if (idx > midx) midx=idx;
    }
    if (midx > sys->nidx) {
        printf("overflow in cell list: %d/%d atoms/cells.\n", midx, sys->nidx);
        exit(1);
    }
    return;
}
Example #21
0
void Pair_LJ::ComputeForce(Atoms *atom) 
{
    double epot;
    
#if defined(_OPENMP)
#pragma omp parallel reduction(+:epot)
#endif
    {
        double c12,c6,boxby2,rcsq;
        double *fx, *fy, *fz;
        double *rx, *ry, *rz;
        int i, tid, fromidx, toidx, natoms, nthreads;

        /* precompute some constants */
        c12 = 4.0*epsilon*pow(sigma,12.0);
        c6  = 4.0*epsilon*pow(sigma, 6.0);
        rcsq= atom->GetRadCut() * atom->GetRadCut();
        boxby2 = 0.5*atom->GetBoxSize();
        natoms = atom->GetNAtoms();
        epot = 0.0;
        
        /* let each thread operate on a different
           part of the enlarged force array */
#if defined(_OPENMP)
	nthreads=omp_get_num_threads();
        tid=omp_get_thread_num();
#else
	nthreads=1;
        tid=0;
#endif
        fx=atom->GetForce() + (3*tid*natoms);
        azzero(fx,3*natoms);
        fy=atom->GetForce() + ((3*tid+1)*natoms);
        fz=atom->GetForce() + ((3*tid+2)*natoms);
        rx=atom->GetPosition();
        ry=atom->GetPosition() + natoms;
        rz=atom->GetPosition() + 2*natoms;
	int x;
        /* self interaction of atoms in cell */
        for(i=0; i < atom->GetNCells(); i += nthreads) {
            int j;
	    //            cell_t *c1;
            
            j = x = i + tid;
            if (j >= (atom->GetNCells())) break;
//            c1=atom->clist + j;
//            afc=getlist(j) 
            for (j=0; j < atom->GetCellNAtoms(x)-1; ++j) {
//	    for (j=0; j < GetCellData()-1; ++j) {  
                int ii,k;
                double rx1, ry1, rz1;		
 //               ii=c1->idxlist[j];
		ii=atom->GetCellIndex(x,j);
		
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=j+1; k < atom->GetCellNAtoms(x); ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;

		    jj=atom->GetCellIndex(x,k); 
                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, atom->GetBoxSize());
                    ry2=pbc(ry1 - ry[jj], boxby2, atom->GetBoxSize());
                    rz2=pbc(rz1 - rz[jj], boxby2, atom->GetBoxSize());
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;

                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;
                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }    

        /* interaction of atoms in different cells */
        for(i=0; i < atom->GetNPairs(); i += nthreads) {
            int j;
	    //            const cell_t *c1, *c2;

            j = x = i + tid;
            if (x >= (atom->GetNPairs())) break;
	  
        //    c1=atom->clist + atom->plist[2*x];
        //    c2=atom->clist + atom->plist[2*x+1];
        
            for (j=0; j < atom->GetCellNAtoms(atom->GetPairItem(2*x)); ++j) {
                int ii, k;
                double rx1, ry1, rz1;

                ii=atom->GetCellIndex(atom->GetPairItem(2*x),j);
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=0; k < atom->GetCellNAtoms(atom->GetPairItem(2*x+1)); ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;
                
                   // jj=c2->idxlist[k];
		    
		    jj = atom->GetCellIndex(atom->GetPairItem(2*x+1),k);
                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, atom->GetBoxSize());
                    ry2=pbc(ry1 - ry[jj], boxby2, atom->GetBoxSize());
                    rz2=pbc(rz1 - rz[jj], boxby2, atom->GetBoxSize());
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;

                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;

                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }

        /* before reducing the forces, we have to make sure 
           that all threads are done adding to them. */
#if defined (_OPENMP)
#pragma omp barrier
#endif
        /* set equal chunks of index ranges */
        i = 1 + (3*natoms / nthreads);
        fromidx = tid * i;
        toidx = fromidx + i;
        if (toidx > 3*natoms) toidx = 3*natoms;

        /* reduce forces from threads with tid != 0 into
           the storage of the first thread. since we have
           threads already spawned, we do this in parallel. */
        for (i=1; i < nthreads; ++i) {
            int offs, j;

            offs = 3*i*natoms;

            for (j=fromidx; j < toidx; ++j) {
  //              atom->frc[j] += atom->frc[offs+j];
	      atom->SetForce(j,atom->GetForce(j)+atom->GetForce(offs+j));

            }
        }
    }
    atom->SetPotEnergy(epot);
}
/* compute LJ forces */
void force_LJ(mdsys_t *sys) 
{
    double pot;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i;
    int natoms=sys->natoms;

    /* zero energy and forces */
    pot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    #pragma omp parallel for default(shared) private(i) reduction(+:pot)
    for(i = 0; i < (natoms - 1); ++i) {
    /* private versions of sys->rx[i] */
    int j;
    double rxi,ryi,rzi;
    rxi = sys->rx[i];
    ryi = sys->ry[i];
    rzi = sys->rz[i];
        for(j = (1 + i); j < natoms; ++j) {
        double rx,ry,rz,rsq;
            /* particles have no interactions with themselves */
            if (i==j) continue;

            /* get distance between particle i and j */
            rx=pbc(rxi - sys->rx[j], b);
            ry=pbc(ryi - sys->ry[j], b);
            rz=pbc(rzi - sys->rz[j], b);
            rsq = rx*rx + ry*ry + rz*rz;
      
            /* compute force and energy if within cutoff */
            if (rsq < csq) {
		double rsqinv = 1/rsq;
		double r6 = rsqinv*rsqinv*rsqinv;
		double pr = p*r6;
		double p6 = 4.0*sys->epsilon*pr;
                double p12 = p6*pr; 
                double ffac;
		
                ffac = rsqinv*(12*p12-6*p6);
                
                pot += 0.5*(p12-p6);
                
                #pragma omp atomic
                sys->fx[i] += rx*ffac;
                #pragma omp atomic
                sys->fy[i] += ry*ffac;
                #pragma omp atomic
                sys->fz[i] += rz*ffac;
                #pragma omp atomic
                sys->fx[j] -= rx*ffac;
                #pragma omp atomic
                sys->fy[j] -= ry*ffac;
                #pragma omp atomic
                sys->fz[j] -= rz*ffac;
            }
        }
    } 
    sys->epot = pot;
}
/* compute MORSE forces */
void force_morse(mdsys_t *sys) 
{
    double pot;
    double b = 0.5*sys->box;
    double s = sys->sigma*sys->sigma;
    double p = s*s*s;
    double csq = sys->rcut*sys->rcut;            
    int i;
    int natoms=sys->natoms;

    /* zero energy and forces */
    pot=0.0;
    azzero(sys->fx,natoms);
    azzero(sys->fy,natoms);
    azzero(sys->fz,natoms);

    #pragma omp parallel for default(shared) private(i) reduction(+:pot)
    for(i = 0; i < (natoms - 1); ++i) {
    /* private versions of sys->rx[i] */
    int j;
    double rxi,ryi,rzi;
    rxi = sys->rx[i];
    ryi = sys->ry[i];
    rzi = sys->rz[i];
    for(j = (1 + i); j < natoms; ++j) {
    double rx,ry,rz,rsq;
    /* particles have no interactions with themselves */
    if (i==j) continue;

    /* get distance between particle i and j */
    rx=pbc(rxi - sys->rx[j], b);
    ry=pbc(ryi - sys->ry[j], b);
    rz=pbc(rzi - sys->rz[j], b);
    rs = sqrt(rsqi);
    rsq = rx*rx + ry*ry + rz*rz;
            
	/* compute force and energy if within cutoff */
    if (rsq < csq) {
				
				esp = exp((-1)*sys->a*(rs-sys->rzero));
				espq = exp((-1)*sys->a*(rs-sys->rzero)*(rs-sys->rzero));
				
				ffac = 2*sys->De * (1-esp)*sys->a*esp;
				pot += sys->De*(1-espq)
                
				sys->fx[i] += rx*ffac;
                #pragma omp atomic
                sys->fy[i] += ry*ffac;
                #pragma omp atomic
                sys->fz[i] += rz*ffac;
                #pragma omp atomic
                sys->fx[j] -= rx*ffac;
                #pragma omp atomic
                sys->fy[j] -= ry*ffac;
                #pragma omp atomic
                sys->fz[j] -= rz*ffac;
            }
        }
    } 
    sys->epot = pot;
}
Example #24
0
  bool ECPotentialBuilder::put(xmlNodePtr cur) {

    if(localPot.empty()) {
      int ng(IonConfig.getSpeciesSet().getTotalNum());
      localZeff.resize(ng,1);
      localPot.resize(ng,0);
      nonLocalPot.resize(ng,0);
    }

    string ecpFormat("table");
    string pbc("yes");
    string forces("no");
    OhmmsAttributeSet pAttrib;
    pAttrib.add(ecpFormat,"format");
    pAttrib.add(pbc,"pbc");
    pAttrib.add(forces,"forces");
    pAttrib.put(cur);
    bool doForces = (forces == "yes") || (forces == "true");

    //const xmlChar* t=xmlGetProp(cur,(const xmlChar*)"format");
    //if(t != NULL) {
    //  ecpFormat= (const char*)t;
    //} 

    if(ecpFormat == "xml")  
    {
      useXmlFormat(cur);
    } 
    else 
    {
      useSimpleTableFormat();
    } 

    ///create LocalECPotential
    bool usePBC = 
      !(IonConfig.Lattice.SuperCellEnum == SUPERCELL_OPEN || pbc =="no");
    if(hasLocalPot) {
      if(IonConfig.Lattice.SuperCellEnum == SUPERCELL_OPEN || pbc =="no") 
      {
#ifdef QMC_CUDA
        LocalECPotential_CUDA* apot = 
	  new LocalECPotential_CUDA(IonConfig,targetPtcl);
#else
        LocalECPotential* apot = new LocalECPotential(IonConfig,targetPtcl);
#endif
        for(int i=0; i<localPot.size(); i++) {
          if(localPot[i]) apot->add(i,localPot[i],localZeff[i]);
        }
        targetH.addOperator(apot,"LocalECP");
      }
      else
      {
	if (doForces) 
	  app_log() << "  Will compute forces in CoulombPBCABTemp.\n" << endl;
#ifdef QMC_CUDA
        CoulombPBCAB_CUDA* apot=
	  new CoulombPBCAB_CUDA(IonConfig,targetPtcl, doForces);
#else
	CoulombPBCABTemp* apot =
	  new CoulombPBCABTemp(IonConfig,targetPtcl, doForces);
#endif
        for(int i=0; i<localPot.size(); i++) {
          if(localPot[i]) apot->add(i,localPot[i]);
        }
        targetH.addOperator(apot,"LocalECP");
      }
      //if(IonConfig.Lattice.BoxBConds[0]) {
      //  CoulombPBCABTemp* apot=new CoulombPBCABTemp(IonConfig,targetPtcl);
      //  for(int i=0; i<localPot.size(); i++) {
      //    if(localPot[i]) apot->add(i,localPot[i]);
      //  }
      //  targetH.addOperator(apot,"LocalECP");
      //} else {
      //  LocalECPotential* apot = new LocalECPotential(IonConfig,targetPtcl);
      //  for(int i=0; i<localPot.size(); i++) {
      //    if(localPot[i]) apot->add(i,localPot[i],localZeff[i]);
      //  }
      //  targetH.addOperator(apot,"LocalECP");
      //}
    }

    if(hasNonLocalPot) {
      //resize the sphere
      targetPtcl.resizeSphere(IonConfig.getTotalNum());
      RealType rc2=0.0;
#ifdef QMC_CUDA   
      NonLocalECPotential_CUDA* apot = 
	new NonLocalECPotential_CUDA(IonConfig,targetPtcl,targetPsi,usePBC,doForces);
#else
      NonLocalECPotential* apot = 
	new NonLocalECPotential(IonConfig,targetPtcl,targetPsi, doForces);
#endif

      for(int i=0; i<nonLocalPot.size(); i++) 
      {
        if(nonLocalPot[i]) 
        {
          rc2=std::max(rc2,nonLocalPot[i]->Rmax);
          apot->add(i,nonLocalPot[i]);
        }
      }
      targetPtcl.checkBoundBox(2*rc2);
      targetH.addOperator(apot,"NonLocalECP");

      for(int ic=0; ic<IonConfig.getTotalNum(); ic++) 
      {
        int ig=IonConfig.GroupID[ic];
        if(nonLocalPot[ig]) { 
          if(nonLocalPot[ig]->nknot) targetPtcl.Sphere[ic]->resize(nonLocalPot[ig]->nknot);
        }
      }
    }
    return true;
  }
int main(int argc, char **argv)
{
 PetscInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);
 //PetscInitializeNoArguments();

 //double bubbleDiam = 3.0E-3; // sqrt(Ar) = 535.83  ; Eo = 1.2091 
 //double bubbleDiam = 4.0E-3; // sqrt(Ar) = 824.96  ; Eo = 2.1495 
 double bubbleDiam = 5.2E-3; //   sqrt(Ar) = 12228.0 ; Eo = 3.6327
 double mu_in = 18.21E-6;
 double mu_out = 958.08E-6;
 double rho_in = 1.205;
 double rho_out = 998.0;
 double gravity = 9.8;
 double sigma = 0.0728;
 double betaGrad = 1.0; // 0.9625

 double Re = sqrt( CalcArchimedesBuoyancy(gravity,bubbleDiam,rho_out,mu_out ) );
 double We = CalcEotvos(gravity,bubbleDiam,rho_out,sigma);
 double Fr = 1.0;
 
 
 /*
 // Rabello's thesis: sugar-syrup 1
 double Re = 33.0413; 
 double Sc = 1.0;
 double Fr = 1.0;
 double We = 115.662;
 double mu_in = 1.78E-5;
 double mu_out = 0.5396;
 double rho_in = 1.225;
 double rho_out = 1350.0;
 */

 int iter = 0;
 double alpha = 1.0;
 double cfl = 0.5;

 double c1 = 0.0;  // lagrangian
 double c2 = 0.1;  // smooth vel
 double c3 = 10.0;  // smooth coord (fujiwara)
 double d1 = 1.0;  // surface tangent velocity u_n=u-u_t 
 double d2 = 0.1;  // surface smooth cord (fujiwara)

 //const char* _frame = "fixed";
 const char* _frame = "moving";

 string physGroup = "\"wallInflowZeroU\"";
 
 Solver *solverP = new PetscSolver(KSPGMRES,PCILU);
 Solver *solverV = new PetscSolver(KSPCG,PCICC);
 Solver *solverC = new PetscSolver(KSPCG,PCICC);

 /*
 string meshFile = "rising-moving-x.msh";
 const char *binFolder  = "/home/gcpoliveira/post-processing/vtk/3d/rising-pbc-moving/bin/";
 const char *mshFolder  = "/home/gcpoliveira/post-processing/vtk/3d/rising-pbc-moving/msh/";
 const char *datFolder  = "/home/gcpoliveira/post-processing/vtk/3d/rising-pbc-moving/dat/";
 const char *vtkFolder  = "/home/gcpoliveira/post-processing/vtk/3d/rising-pbc-moving/";
 */

  
 // cell-2D
 string meshFile = "unit-cell-s-2D-3d.msh";
 // 1
 /*
 const char *binFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1/bin/";
 const char *datFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1/dat/";
 const char *mshFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1/msh/";
 const char *vtkFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1/vtk/";
 */
 // 2
 /*
 const char *binFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-2/bin/";
 const char *datFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-2/dat/";
 const char *mshFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-2/msh/";
 const char *vtkFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-2/vtk/";
 */
 // 3
 
 const char *binFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-3/bin/";
 const char *datFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-3/dat/";
 const char *mshFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-3/msh/";
 const char *vtkFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-2D-nb1-3/vtk/";
 

 /* 
 // cell-D
 string meshFile = "unit-cell-s-D-3d.msh";
 const char *binFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-D-nb1/bin/";
 const char *vtkFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-D-nb1/";
 const char *datFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-D-nb1/dat/";
 const char *mshFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-D-nb1/msh/";
 */

 /*
 // cell-0.5D
 string meshFile = "unit-cell-s-0.5D-3d.msh";
 const char *binFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-0.5D-nb1/bin/";
 const char *vtkFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-0.5D-nb1/";
 const char *datFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-0.5D-nb1/dat/";
 const char *mshFolder  = "/home/gcpoliveira/post-processing/vtk/3d/unit-cell-s-0.5D-nb1/msh/";
 */ 

 string meshDir = (string) getenv("MESH3D_DIR");

 if( strcmp( _frame,"moving") == 0 )
  meshDir += "/rising/movingFrame/" + meshFile;
 else
  meshDir += "/rising/" + meshFile;
 
 const char *mesh = meshDir.c_str();

 Model3D m1;

  cout << endl;
  cout << "--------------> STARTING FROM 0" << endl;
  cout << endl;

  const char *mesh1 = mesh;

  m1.readMSH(mesh1);
  m1.setInterfaceBC();
  m1.setTriEdge();
  m1.mesh2Dto3D();
  m1.setMapping();
#if NUMGLEU == 5
 m1.setMiniElement();
#else
 m1.setQuadElement();
#endif
  m1.setSurfaceConfig();
  m1.setInitSurfaceVolume();
  m1.setInitSurfaceArea();
  m1.setGenericBCPBCNew(physGroup);
  m1.setGenericBC();

  Periodic3D pbc(m1);
  pbc.MountPeriodicVectorsNew("print");

  Simulator3D s1(pbc,m1);

  s1.setRe(Re);
  s1.setWe(We);
  s1.setFr(Fr);
  s1.setC1(c1);
  s1.setC2(c2);
  s1.setC3(c3);
  s1.setD1(d1);
  s1.setD2(d2);
  s1.setAlpha(alpha);
  s1.setMu(mu_in,mu_out);
  s1.setRho(rho_in,rho_out);
  s1.setCfl(cfl);
  s1.init();
  s1.setBetaPressureLiquid(betaGrad);
  s1.setDtALETwoPhase();
  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);

  // Point's distribution
 Helmholtz3D h1(m1);
 h1.setBC();
 h1.initRisingBubble();
 //h1.initThreeBubbles();
 h1.assemble();
 h1.setk(0.2);
 h1.matMountC();
 h1.setUnCoupledCBC(); 
 h1.setCRHS();
 h1.unCoupledC();
 h1.setModel3DEdgeSize();

 InOut save(m1,s1); // cria objeto de gravacao
 save.saveVTK(vtkFolder,"geometry");
 save.saveVTKSurface(vtkFolder,"geometry");
 save.saveMeshInfo(datFolder);
 save.saveInfo(datFolder,"info",mesh);

 double vinst=0;
 double vref=0;
 double xref=0;
 double xinit=0;
 double dx=0;
 if( strcmp( _frame,"moving") == 0 )
 {
  // moving
  vref = s1.getURef();
  xref = s1.getXRef();
  s1.setCentroidVelPos();
  xinit = s1.getCentroidPosXAverage();
 }

 int nIter = 30000;
 int nReMesh = 1;
 for( int i=1;i<=nIter;i++ )
 {
  for( int j=0;j<nReMesh;j++ )
  {
   cout << color(none,magenta,black);
   cout << "____________________________________ Iteration: " 
	    << iter << endl << endl;
   cout << resetColor();

   // moving
   if( strcmp( _frame,"moving") == 0 )
   {
	// moving frame
	dx = s1.getCentroidPosXAverage() - xinit;
	vinst = s1.getCentroidVelXAverage() + dx/s1.getDt();
    vref += vinst;
	xref += vref*s1.getDt();
	cout << "vref: " << vref << " xref: " << xref << endl;
	cout << "dx: " << dx << endl;
	s1.setUSol(vinst);
    m1.setGenericBCPBCNew(physGroup);
	m1.setGenericBC(vref);
    pbc.MountPeriodicVectorsNew("print");
	s1.setURef(vref);
	s1.setXRef(xref);
   }

   s1.setDtALETwoPhase();

   InOut save(m1,s1); // cria objeto de gravacao
   save.printSimulationReport();

   s1.stepALEPBC();
   s1.movePoints();
   s1.assemble();
   s1.matMount();
   s1.setUnCoupledBC();
   s1.setGravity("-X");
   s1.setBetaFlowLiq("+X");
   s1.setRHS();
   s1.setCopyDirectionPBC("RL");
   s1.setInterfaceGeo();
   //s1.setInterfaceLevelSet();
   s1.unCoupledPBCNew();

   save.saveMSH(mshFolder,"newMesh",iter);
   save.saveVTK(vtkFolder,"sim",iter);
   save.saveVTKSurface(vtkFolder,"sim",iter);
   save.saveSol(binFolder,"sim",iter);
   save.saveBubbleInfo(datFolder);
   //save.crossSectionalVoidFraction(datFolder,"voidFraction",iter);
   save.saveBubbleShapeFactors(datFolder,"shapeFactors",iter);

   s1.saveOldData();

   cout << color(none,magenta,black);
   cout << "________________________________________ END of " 
	    << iter << endl << endl;;
   cout << resetColor();

   s1.timeStep();

   iter++;
  }
  Helmholtz3D h2(m1,h1);
  h2.setBC();
  h2.initRisingBubble();
  //h2.initThreeBubbles();
  h2.assemble();
  h2.matMountC();
  h2.setUnCoupledCBC(); 
  h2.setCRHS();
  h2.unCoupledC();
  h2.setModel3DEdgeSize();

  Model3D mOld = m1; 

  /* *********** MESH TREATMENT ************* */
  // set normal and kappa values
  m1.setNormalAndKappa();
  m1.initMeshParameters();

  // 3D operations
  m1.insert3dMeshPointsByDiffusion(6.0);
  m1.remove3dMeshPointsByDiffusion(1.0);
  //m1.removePointByVolume();
  //m1.removePointsByInterfaceDistance();
  //m1.remove3dMeshPointsByDistance();
  m1.remove3dMeshPointsByHeight();
  m1.delete3DPoints();

  // surface operations
  m1.smoothPointsByCurvature();

  m1.insertPointsByLength("curvature");
  //m1.insertPointsByCurvature("flat");
  //m1.removePointsByCurvature();
  //m1.insertPointsByInterfaceDistance("flat");
  m1.contractEdgesByLength("curvature");
  //m1.removePointsByLength();
  m1.flipTriangleEdges();

  m1.removePointsByNeighbourCheck();
  //m1.checkAngleBetweenPlanes();

  /* **************************************** */

  //m1.mesh2Dto3DOriginal();
  m1.mesh3DPoints();
  m1.setMapping();
#if NUMGLEU == 5
 m1.setMiniElement();
#else
 m1.setQuadElement();
#endif
  m1.setSurfaceConfig();

  if( strcmp( _frame,"moving") == 0 )
  {
    m1.setGenericBCPBCNew(physGroup);
    m1.setGenericBC(vref);
    pbc.MountPeriodicVectorsNew("print");
  }
  else
  {
    m1.setGenericBCPBCNew(physGroup);
    m1.setGenericBC();
    pbc.MountPeriodicVectorsNew("noPrint");
  }

  Simulator3D s2(m1,s1);
  s2.applyLinearInterpolation(mOld);
  s1 = s2;
  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);

  InOut saveEnd(m1,s1); // cria objeto de gravacao
  saveEnd.printMeshReport();
  saveEnd.saveMeshInfo(datFolder);
 }

 PetscFinalize();
 return 0;
}
int main(){
	
	bool deposit = true;

	printf("Enter value for diffusion rate D: ");
	scanf(" %f", &D);

	printf("Enter value for deposition rate F: ");
	scanf(" %f", &F);

	printf("Enter total number of steps: ");
	scanf(" %d", &steps);

	FILE *file = fopen("Output.txt", "w");
	fclose(file);
	
	int deposition_ct=0;
	
	create_lattice();
	//sets inverse pointer array to -1 
	for(i=0;i<L;i++){
	  for(j=0;j<L;j++){
	    ipointa[i][j]=-1;
	  }}

	//initialize ip and im arrays to take care to pbc's easilyn
	for(i=0;i<L;i++){
	  ip[i]=i+1;
	  im[i]=i-1;
	}
	ip[L-1]=0;
	im[0]=L-1;
	//initialize nbxa[L][4] and nbya[L][4] for the 4 directions
	for(i=0;i<L;i++){
	  nbxa[i][0]=ip[i];
	  nbya[i][0]=i;
	  nbxa[i][1]=i;
	  nbya[i][1]=im[i];
	  nbxa[i][2]=im[i];
	  nbya[i][2]=i;
	  nbxa[i][3]=i;
	  nbya[i][3]=ip[i];
	}	  

	

	for(int i = 0; i <steps; i++){
		

		float Rdep = F*(L^2);
		float Rdiff = monomer_ct * D;

		P_d = Rdep / (Rdep + Rdiff);
		P_f = 1 - P_d;

		float random = (rand() % 10000)/10000.0;
		fprintf(debug, "P_d %f, random %f\n", P_d, random);

		fprintf(debug, "monomer_ct %d\n", monomer_ct);
		
		
		if((random < P_d) /*&& (deposit)*/){
			
			deposition();
			fprintf(debug, "Deposition \n");
			deposition_ct++;
		}
		else{
			fprintf(debug, "Carrying out diffusion\n");
			diffusion();
			//printf("Diffusion \n");
		}
		
		pbc();
		print_walkers();
		output();		
		//draw();
	}

}
int main(int argc, char **argv)
{
 PetscInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);
 //PetscInitializeNoArguments();

 int iter = 0;

 double velVCrossflow = 0.0; // i.e. V_crossflow = velVCrossflow x V_jet
 double velWCrossflow = velVCrossflow; 
 
 //const char* _frame = "fixed";
 const char* _frame = "moving";

 string _physGroup = "\"wallInflowVTransverse\"";
 double betaGrad = 0.0;
 
 Solver *solverP = new PetscSolver(KSPCG,PCILU);
 Solver *solverV = new PCGSolver();
 Solver *solverC = new PCGSolver();

 string meshFile = "crossflow-3d-Lp1.5-b0.09.msh";

 const char* name = "ms";
 
 const char *binFolder = "null";
 const char *datFolder = "null";
 const char *mshFolder = "null";
 const char *vtkFolder = "null";

 if( strcmp( name,"wl") == 0 )
 {
 binFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-1.0-longmire-Lp5/bin/";
 datFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-1.0-longmire-Lp5/dat/";
 mshFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-1.0-longmire-Lp5/msh/";
 vtkFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-1.0-longmire-Lp5/vtk/";
 }
 else
 { 
 binFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-0.0-meister-Lp1.5-b0.09/bin/";
 datFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-0.0-meister-Lp1.5-b0.09/dat/";
 mshFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-0.0-meister-Lp1.5-b0.09/msh/";
 vtkFolder  = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-0.0-meister-Lp1.5-b0.09/vtk/";
 } 

 string meshDir = (string) getenv("MESH3D_DIR");

 if( strcmp( _frame,"moving") == 0 )
  meshDir += "/rising/movingFrame/" + meshFile;
 else
  meshDir += "/rising/" + meshFile;

 const char *mesh = meshDir.c_str();

 Model3D m1;


  cout << endl;
  cout << "--------------> RE-STARTING..." << endl;
  cout << endl;

  string mshBase = "null"; 
 if( strcmp( name,"wl") == 0 )
  mshBase = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-1.0-longmire-Lp5/msh/newMesh-";
 else
  mshBase = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-0.0-meister-Lp1.5-b0.09/msh/newMesh-";

  // load surface mesh
  string aux = *(argv+1);
  string file = mshBase + *(argv+1) + (string) ".msh";
  const char *mesh2 = file.c_str();
  m1.readMSH(mesh2);
  m1.setInterfaceBC();
  m1.setTriEdge();
  m1.mesh2Dto3D();

  string vtkBase = "null";
 if( strcmp( name,"wl") == 0 )
  vtkBase = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-1.0-longmire-Lp5/vtk/sim-";
 else
  vtkBase = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-0.0-meister-Lp1.5-b0.09/vtk/sim-";
  
  // load 3D mesh
  file = vtkBase + *(argv+1) + (string) ".vtk";
  const char *vtkFile = file.c_str();

  m1.readVTK(vtkFile);
  m1.setMapping();
#if NUMGLEU == 5
  m1.setMiniElement();
#else
  m1.setQuadElement();
#endif
  m1.readVTKHeaviside(vtkFile);
  m1.setSurfaceConfig();
  m1.setInitSurfaceVolume();
  m1.setInitSurfaceArea();
  m1.setCrossflowVVelocity(velVCrossflow); 
  m1.setCrossflowWVelocity(velWCrossflow); 
  m1.setGenericBCPBCNew(_physGroup);
  m1.setGenericBC();

  Periodic3D pbc(m1);
  //pbc.MountPeriodicVectorsNew("noPrint");
  pbc.MountPeriodicVectors("noPrint");

  Simulator3D s1(pbc,m1);

  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);

 const char *dirBase = "null";
 if( strcmp( name,"wl") == 0 )
  dirBase = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-1.0-longmire-Lp5/";
 else
  dirBase = "/work/gcpoliveira/post-processing/3d/crossflow-lambda-0.0-meister-Lp1.5-b0.09/";
  
  iter = s1.loadSolution(dirBase,"sim",atoi(*(argv+1)));
  
 // Point's distribution
 Helmholtz3D h1(m1);
 h1.setBC();
 h1.initRisingBubble();
 h1.assemble();
 h1.setk(0.2);
 h1.matMountC();
 h1.setUnCoupledCBC(); 
 h1.setCRHS();
 h1.unCoupledC();
 h1.setModel3DEdgeSize();

 InOut save(m1,s1); // cria objeto de gravacao
 save.saveVTKSurface(vtkFolder,"geometry");
 save.saveVTKPBC(vtkFolder,"initial",0,betaGrad);
 save.saveMeshInfo(datFolder);
 save.saveInfo(datFolder,"info",mesh);

 double uinst=0;
 double vinst=0;
 double winst=0;
 double uref=0;
 double vref=0;
 double wref=0;
 double xref=0;
 double yref=0;
 double zref=0;
 double xinit=0;
 double yinit=0;
 double zinit=0;
 double dx=0;
 double dy=0;
 double dz=0;

 if( strcmp( _frame,"moving") == 0 )
 {
  // moving
  uref = s1.getURef();
  xref = s1.getXRef();
  vref = s1.getVRef();
  yref = s1.getYRef();
  wref = s1.getWRef();
  zref = s1.getZRef();

  s1.setCentroidVelPos();
  xinit = s1.getCentroidPosXAverage(); // initial x centroid
  yinit = s1.getCentroidPosYAverage(); // initial y centroid
  zinit = s1.getCentroidPosZAverage(); // initial z centroid
 }

 int nIter = 50000;
 int nReMesh = 1;
 for( int i=1;i<=nIter;i++ )
 {
  for( int j=0;j<nReMesh;j++ )
  {
   cout << color(none,magenta,black);
   cout << "____________________________________ Iteration: " 
	    << iter << endl;
   cout << resetColor();

   if( strcmp( _frame,"moving") == 0 )
   {
	// moving frame
	dx = s1.getCentroidPosXAverage() - xinit; // mov. frame x displacement 
	dy = s1.getCentroidPosYAverage() - yinit; // mov. frame y displacement
	dz = s1.getCentroidPosZAverage() - zinit; // mov. frame z displacement
	uinst = s1.getCentroidVelXAverage() + dx/s1.getDt(); // uc + correction
	vinst = s1.getCentroidVelYAverage() + dy/s1.getDt(); // vc + correction
	winst = s1.getCentroidVelZAverage() + dz/s1.getDt(); // wc + correction
	uref += uinst; // sums to recover inertial vel
	vref += vinst;
	wref += winst;
	xref += uref*s1.getDt();
	yref += vref*s1.getDt();
	zref += wref*s1.getDt();
	cout << "uref: " << uref << " xref: " << xref << endl;
	cout << "vref: " << vref << " yref: " << yref << endl;
	cout << "wref: " << wref << " zref: " << zref << endl;
	cout << "uinst: " << uinst << " vinst: " << vinst << " winst: " << winst << endl;
	cout << "dx: " << dx << endl;
	cout << "dy: " << dy << endl;
	cout << "dz: " << dz << endl;
	s1.setUSol(uinst); // subtraction for inertial frame: u - u_MFR
	s1.setVSol(vinst); // subtraction for inertial frame: v - v_MFR
	s1.setWSol(winst); // subtraction for inertial frame: w - w_MFR
	m1.setCrossflowVVelocity(velVCrossflow); // set of crossflow velocity for BC
	m1.setCrossflowWVelocity(velWCrossflow); // set of crossflow velocity for BC
    m1.setGenericBCPBCNew(_physGroup);
	m1.setGenericBC(uref,vref,wref); // crossflow condition
    //pbc.MountPeriodicVectorsNew("print");
    pbc.MountPeriodicVectors("print");
	s1.setURef(uref); // sets to recover the inertial physics; ease prints in InOut
	s1.setVRef(vref);
	s1.setWRef(wref);
	s1.setXRef(xref);
	s1.setYRef(yref);
	s1.setZRef(zref);
   }

   s1.setDtALETwoPhase();

   InOut save(m1,s1); // cria objeto de gravacao
   save.printSimulationReport();

   s1.stepALEPBC();
   s1.movePoints();
   s1.assemble();
   s1.matMount();
   s1.setUnCoupledBC();
   //s1.setGravity("-Z");
   //s1.setBetaFlowLiq("+X");
   s1.setRHS();
   s1.setCopyDirectionPBC("RL");
   s1.setInterfaceGeo();
   //s1.unCoupledPBCNew();
   s1.unCoupledPBC();

   if ( i%15 == 0 )
   {
   save.saveVTKPBC(vtkFolder,"sim",iter,betaGrad);
   save.saveVTKSurfacePBC(vtkFolder,"sim",iter,betaGrad);
   save.saveMSH(mshFolder,"newMesh",iter);
   save.saveSol(binFolder,"sim",iter);
   save.saveBubbleInfo(datFolder);
   save.bubbleWallDistance(datFolder,"dist",iter);
   save.saveBubbleShapeFactors(datFolder,"shapeFactors",iter);
   }
   
   s1.saveOldData();

   cout << color(none,magenta,black);
   cout << "________________________________________ END of " 
	    << iter << endl;
   cout << resetColor();

   s1.timeStep();

   iter++;
  }
  
  Helmholtz3D h2(m1,h1);
  h2.setBC();
  h2.initRisingBubble();
  h2.assemble();
  h2.setk(0.2);
  h2.matMountC();
  h2.setUnCoupledCBC(); 
  h2.setCRHS();
  h2.unCoupledC();
  h2.saveVTK(vtkFolder,"edge",iter-1);
  //h2.saveChordalEdge(datFolder,"edge",iter-1);
  h2.setModel3DEdgeSize();
  
  Model3D mOld = m1; 

  /* *********** MESH TREATMENT ************* */
  
  m1.setNormalAndKappa();
  m1.initMeshParameters();
  // 3D mesh operations
  m1.insert3dMeshPointsByDiffusion(6.5);
  m1.remove3dMeshPointsByDiffusion(1.5);
  //m1.removePointByVolume();
  //m1.removePointsByInterfaceDistance();
  //m1.remove3dMeshPointsByDistance();
  m1.remove3dMeshPointsByHeight();
  m1.delete3DPoints();

  // surface mesh operations
  m1.smoothPointsByCurvature();

  m1.insertPointsByLength("curvature");
  //m1.insertPointsByCurvature("flat");
  //m1.removePointsByCurvature();
  //m1.insertPointsByInterfaceDistance("flat");
  m1.contractEdgesByLength("curvature");
  //m1.removePointsByLength();
  m1.flipTriangleEdges();
  
  m1.removePointsByNeighbourCheck();
  //m1.checkAngleBetweenPlanes();
  
  /* **************************************** */

  m1.mesh3DPoints();
  m1.setMapping();
#if NUMGLEU == 5
  m1.setMiniElement();
#else
  m1.setQuadElement();
#endif
  m1.setSurfaceConfig();
  

  if( strcmp( _frame,"moving") == 0 )
  {
	m1.setCrossflowVVelocity(velVCrossflow); 
	m1.setCrossflowWVelocity(velWCrossflow); 
    m1.setGenericBCPBCNew(_physGroup);
	m1.setGenericBC(uref,vref,wref);
    //pbc.MountPeriodicVectorsNew("noPrint");
    pbc.MountPeriodicVectors("noPrint");
  }
  else
  { 
	m1.setCrossflowVVelocity(velVCrossflow); 
	m1.setCrossflowWVelocity(velWCrossflow); 
    m1.setGenericBCPBCNew(_physGroup);
    m1.setGenericBC();
    //pbc.MountPeriodicVectorsNew("noPrint");
    pbc.MountPeriodicVectors("noPrint");
  }

  Simulator3D s2(m1,s1);
  s2.applyLinearInterpolation(mOld);
  s1 = s2;
  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);

  if ( i%15 == 0 )
  {
  InOut saveEnd(m1,s1); // cria objeto de gravacao
  saveEnd.printMeshReport();
  saveEnd.saveMeshInfo(datFolder);
  }
 }
 
 PetscFinalize();
 return 0;
}
int main(int argc, char **argv)
{
 PetscInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);
 //PetscInitializeNoArguments();

 // bogdan's thesis 2010 (Bhaga and Weber, JFM 1980)
 int iter = 1;

 double Re = 100; 
 double Sc = 1;
 double We = 115.662;
 double Fr = 1.0;
 double alpha = 1.0;


 double rho_in = 1.225;
 double rho_out =1350; 

 double mu_out = 1;
 double mu_in = 0.0000178;

 const char* _case = "3";

 // case 1
 if( strcmp( _case,"1") == 0 )
 {
  Re = sqrt(42.895); 
  mu_out = 2.73;
 }

 else if( strcmp( _case,"2") == 0 )
 {
  Re = 13.8487; // case 2
  mu_out = 1.28; 
 }

 else if( strcmp( _case,"3") == 0 )
 {
  Re = 33.0413; // case 3
  mu_out = 0.5396; // case 3
 }

 else if( strcmp( _case,"6") == 0 )
 {
  Re = sqrt(3892.856); // case 6
  mu_out = 0.2857; // case 6
 }

 else if( strcmp( _case,"7") == 0 )
 {
  Re = sqrt(18124.092); // case 7
  mu_out = 0.1324; // case 7
 }

 else if( strcmp( _case,"8") == 0 )
 {
  Re = sqrt(41505.729); // case 8 (extream)
  mu_out = 0.0875134907735; // extream
 }
 else
 {
  cerr << "test case " << _case << " not available!" << endl;
  exit(1);
 }

 double cfl = 0.1;
 
 //string meshFile = "rising-x.msh";
 string meshFile = "airWaterSugarPBC-wallLeftRight.msh";
 
 string physGroup = "\"wallNoSlip\"";
 double betaGrad = 1.0;

 const char* _frame = "fixed";
 //const char* _frame = "moving";

 // fixed
 double c1 = 0.0;      // lagrangian
 double c2 = 1.0;      // smooth vel 
 double c3 = 10.0;     // smooth coord (fujiwara)
 double d1 = 1.0;      // surface tangent vel = (u-ut)
 double d2 = 0.2;      // surface smooth coord (fujiwara)

 // moving
 if( strcmp( _frame,"moving") == 0 )
 {
  c1 = 0.0;      // lagrangian
  c2 = 1.0;      // smooth vel: OBS - different result with c1=0.0
  c3 = 10.0;      // smooth coord (fujiwara)
  d1 = 0.0;      // surface tangent velocity u_n=u-u_t 
  d2 = 0.1;      // surface smooth cord (fujiwara)
 }

 Solver *solverP = new PetscSolver(KSPCG,PCICC);
 //Solver *solverP = new PetscSolver(KSPGMRES,PCILU);
 //Solver *solverP = new PetscSolver(KSPGMRES,PCJACOBI);
 Solver *solverV = new PetscSolver(KSPCG,PCICC);
 //Solver *solverV = new PetscSolver(KSPCG,PCJACOBI);
 Solver *solverC = new PetscSolver(KSPCG,PCICC);

 const char *binFolder  = "/work/gcpoliveira/post-processing/3d/risingPBC/bin/";
 const char *vtkFolder  = "/work/gcpoliveira/post-processing/3d/risingPBC/vtk/";
 const char *datFolder  = "/work/gcpoliveira/post-processing/3d/risingPBC/dat/";
 const char *mshFolder  = "/work/gcpoliveira/post-processing/3d/risingPBC/msh/";
 
 string meshDir = (string) getenv("MESH3D_DIR");
 if( strcmp( _frame,"moving") == 0 )
  meshDir += "/twoPhase/pbc/" + meshFile;
 else
  meshDir += "/twoPhase/pbc/" + meshFile;
 
 const char *mesh = meshDir.c_str();

 Model3D m1;

  cout << endl;
  cout << "--------------> STARTING FROM 0" << endl;
  cout << endl;

  const char *mesh1 = mesh;

  m1.readMSH(mesh1);
  m1.setInterfaceBC();
  m1.setTriEdge();
  m1.mesh2Dto3D();
  m1.setMapping();
#if NUMGLEU == 5
 m1.setMiniElement();
#else
 m1.setQuadElement();
#endif
  m1.setSurfaceConfig();
  m1.setInitSurfaceVolume();
  m1.setInitSurfaceArea();
  m1.setGenericBCPBCNew(physGroup);
  m1.setGenericBC();

  Periodic3D pbc(m1);
  pbc.MountPeriodicVectorsNew("print");

  Simulator3D s1(pbc,m1);

  s1.setRe(Re);
  s1.setSc(Sc);
  s1.setWe(We);
  s1.setFr(Fr);
  s1.setC1(c1);
  s1.setC2(c2);
  s1.setC3(c3);
  s1.setD1(d1);
  s1.setD2(d2);
  s1.setAlpha(alpha);
  s1.setMu(mu_in,mu_out);
  s1.setRho(rho_in,rho_out);
  s1.setCfl(cfl);
  s1.init();
  s1.setBetaPressureLiquid(betaGrad);
  s1.setDtALETwoPhase();
  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);
 

 // Point's distribution
 Helmholtz3D h1(m1);
 h1.setBC();
 h1.initRisingBubble();
 h1.assemble();
 h1.setk(0.2);
 h1.matMountC();
 h1.setUnCoupledCBC(); 
 h1.setCRHS();
 h1.unCoupledC();
 h1.setModel3DEdgeSize();

 InOut save(m1,s1); // cria objeto de gravacao
 save.saveVTK(vtkFolder,"geometry");
 save.saveVTKSurface(vtkFolder,"geometry");
 save.saveMeshInfo(datFolder);
 save.saveInfo(datFolder,"info",mesh);

 double vinst=0;
 double vref=0;
 double xref=0;
 double xinit=0;
 double dx=0;
 if( strcmp( _frame,"moving") == 0 )
 {
  // moving
  xref = s1.getURef();
  xref = s1.getXRef();
  s1.setCentroidVelPos();
  xinit = s1.getCentroidPosXAverage();
 }

 int nIter = 300;
 int nReMesh = 1;
 for( int i=1;i<=nIter;i++ )
 {
  for( int j=0;j<nReMesh;j++ )
  {

   cout << color(none,magenta,black);
   cout << "____________________________________ Iteration: " 
	    << iter << endl << endl;
   cout << resetColor();

   // moving
   if( strcmp( _frame,"moving") == 0 )
   {
	// moving frame

	dx = s1.getCentroidPosXAverage() - xinit;
	vinst = s1.getCentroidVelXAverage() + dx/s1.getDt();
    vref += vinst;
	xref += vref*s1.getDt();
	cout << "vref: " << vref << " xref: " << xref << endl;
	cout << "dx: " << dx << endl;
    s1.setUSol(vinst);
    m1.setGenericBC(vref);
    s1.setURef(vref);
	s1.setXRef(xref);
   }

   //s1.stepLagrangian();
   s1.stepALEPBC();
   s1.setDtALETwoPhase();

   InOut save(m1,s1); // cria objeto de gravacao
   save.printSimulationReport();

   s1.movePoints();
   s1.assemble();
   s1.matMount();
   s1.setUnCoupledBC();
   s1.setGravity("-X");
   s1.setBetaFlowLiq("+X");
   s1.setRHS();
   s1.setCopyDirectionPBC("RL");
   s1.setInterfaceGeo();
   s1.unCoupledPBCNew();

   if ( i%5 == 0 )
   {
   save.saveMSH(mshFolder,"newMesh",iter);
   save.saveVTK(vtkFolder,"sim",iter);
   save.saveVTKSurface(vtkFolder,"sim",iter);
   save.saveSol(binFolder,"sim",iter);
   save.saveBubbleInfo(datFolder);
   }

   s1.saveOldData();

   cout << color(none,magenta,black);
   cout << "________________________________________ END of " 
	    << iter << endl << endl;;
   cout << resetColor();

   s1.timeStep();

   iter++;
  }
  Helmholtz3D h2(m1,h1);
  h2.setBC();
  h2.initRisingBubble();
  h2.assemble();
  h2.setk(0.2);
  h2.matMountC();
  h2.setUnCoupledCBC(); 
  h2.setCRHS();
  h2.unCoupledC();
  if ( i%5 == 0 )
  {
  h2.saveVTK(vtkFolder,"edge",iter-1);
  h2.saveChordalEdge(datFolder,"edge",iter-1);
  h2.setModel3DEdgeSize();
  }

  Model3D mOld = m1; 

  /* *********** MESH TREATMENT ************* */
  // set normal and kappa values
  m1.setNormalAndKappa();
  m1.initMeshParameters();

  // 3D operations
  m1.insert3dMeshPointsByDiffusion(6.0);
  m1.remove3dMeshPointsByDiffusion(0.5);
  //m1.removePointByVolume();
  //m1.removePointsByInterfaceDistance();
  //m1.remove3dMeshPointsByDistance();
  m1.remove3dMeshPointsByHeight();
  m1.delete3DPoints();

  // surface operations
  m1.smoothPointsByCurvature();

  m1.insertPointsByLength("flat");
  //m1.insertPointsByCurvature("flat");
  //m1.removePointsByCurvature();
  //m1.insertPointsByInterfaceDistance("flat");
  m1.contractEdgesByLength("flat");
  //m1.removePointsByLength();
  m1.flipTriangleEdges();

  m1.removePointsByNeighbourCheck();
  //m1.checkAngleBetweenPlanes();
  /* **************************************** */

  //m1.mesh2Dto3DOriginal();
  m1.mesh3DPoints();
  m1.setMapping();

#if NUMGLEU == 5
  m1.setMiniElement();
#else
  m1.setQuadElement();
#endif

  m1.setSurfaceConfig();
  if( strcmp( _frame,"moving") == 0 )
  {
    m1.setGenericBCPBCNew(physGroup);
    m1.setGenericBC(vref);
	pbc.MountPeriodicVectorsNew("noPrint");
  }
  else
  {
    m1.setGenericBCPBCNew(physGroup);
    m1.setGenericBC();
	pbc.MountPeriodicVectorsNew("noPrint");
  }

  Simulator3D s2(m1,s1);
  s2.applyLinearInterpolation(mOld);
  s1 = s2;
  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);

  InOut saveEnd(m1,s1); // cria objeto de gravacao
  saveEnd.printMeshReport();
  saveEnd.saveMeshInfo(datFolder);
 }

 PetscFinalize();
 return 0;
}
int main(int argc, char **argv)
{
 PetscInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);
 //PetscInitializeNoArguments();

 int iter = 0;

 //const char* _frame = "fixed";
 const char* _frame = "moving";

 string physGroup = "\"wallInflowZeroU\"";
 //string physGroup = "\"wallNoSlip\"";
 double betaGrad = 1.0;
 
 Solver *solverP = new PetscSolver(KSPCG,PCICC);
 Solver *solverV = new PetscSolver(KSPCG,PCICC);
 Solver *solverC = new PetscSolver(KSPCG,PCICC);

 // rising-pbc
 //string meshFile = "airWaterSugarPBC-wallLeftRight.msh";
 /*
 const char *binFolder  = "/work/gcpoliveira/post-processing/3d/rising-pbc/bin/";
 const char *mshFolder  = "/work/gcpoliveira/post-processing/3d/rising-pbc/msh/";
 const char *datFolder  = "/work/gcpoliveira/post-processing/3d/rising-pbc/dat/";
 const char *vtkFolder  = "/work/gcpoliveira/post-processing/3d/rising-pbc/vtk/";
 */

 // rising-beta
 /*
 const char *binFolder  = "/work/gcpoliveira/post-processing/3d/rising-beta/bin/";
 const char *mshFolder  = "/work/gcpoliveira/post-processing/3d/rising-beta/msh/";
 const char *datFolder  = "/work/gcpoliveira/post-processing/3d/rising-beta/dat/";
 const char *vtkFolder  = "/work/gcpoliveira/post-processing/3d/rising-beta/vtk/";
 */

 // cell-2D
 string meshFile = "unit-cell-s-2D-3d.msh";
 // 1
 /* 
 const char *binFolder  = "/work/gcpoliveira/post-processing/3d/cell-1/bin/";
 const char *datFolder  = "/work/gcpoliveira/post-processing/3d/cell-1/dat/";
 const char *mshFolder  = "/work/gcpoliveira/post-processing/3d/cell-1/msh/";
 const char *vtkFolder  = "/work/gcpoliveira/post-processing/3d/cell-1/vtk/";
 */ 
 // 2
 /*
 const char *binFolder  = "/work/gcpoliveira/post-processing/3d/cell-2/bin/";
 const char *datFolder  = "/work/gcpoliveira/post-processing/3d/cell-2/dat/";
 const char *mshFolder  = "/work/gcpoliveira/post-processing/3d/cell-2/msh/";
 const char *vtkFolder  = "/work/gcpoliveira/post-processing/3d/cell-2/vtk/";
 */
 // 3
 
 const char *binFolder  = "/work/gcpoliveira/post-processing/3d/cell-3/bin/";
 const char *datFolder  = "/work/gcpoliveira/post-processing/3d/cell-3/dat/";
 const char *mshFolder  = "/work/gcpoliveira/post-processing/3d/cell-3/msh/";
 const char *vtkFolder  = "/work/gcpoliveira/post-processing/3d/cell-3/vtk/";
 

 string meshDir = (string) getenv("MESH3D_DIR");

 if( strcmp( _frame,"moving") == 0 )
  meshDir += "/rising/movingFrame/" + meshFile;
 else
  meshDir += "/rising/" + meshFile;
 
 const char *mesh = meshDir.c_str();

 Model3D m1;

  cout << endl;
  cout << "--------------> RE-STARTING..." << endl;
  cout << endl;

  //string mshBase = "/work/gcpoliveira/post-processing/3d/cell-1/msh/newMesh-";
  //string mshBase = "/work/gcpoliveira/post-processing/3d/cell-2/msh/newMesh-";
  string mshBase = "/work/gcpoliveira/post-processing/3d/cell-3/msh/newMesh-";

  //string mshBase = "/work/gcpoliveira/post-processing/3d/rising-pbc/msh/newMesh-";
  //string mshBase = "/work/gcpoliveira/post-processing/3d/rising-beta/msh/newMesh-";

  // load surface mesh
  string aux = *(argv+1);
  string file = mshBase + *(argv+1) + (string) ".msh";
  const char *mesh2 = file.c_str();
  m1.readMSH(mesh2);
  m1.setInterfaceBC();
  m1.setTriEdge();
  m1.mesh2Dto3D();

  //string vtkBase = "/work/gcpoliveira/post-processing/3d/cell-1/vtk/sim-";
  //string vtkBase = "/work/gcpoliveira/post-processing/3d/cell-2/vtk/sim-";
  string vtkBase = "/work/gcpoliveira/post-processing/3d/cell-3/vtk/sim-";
 
  //string vtkBase = "/work/gcpoliveira/post-processing/3d/rising-pbc/vtk/sim-";
  //string vtkBase = "/work/gcpoliveira/post-processing/3d/rising-beta/vtk/sim-";
  
  // load 3D mesh
  file = vtkBase + *(argv+1) + (string) ".vtk";
  const char *vtkFile = file.c_str();

  m1.readVTK(vtkFile);
  m1.setMapping();
#if NUMGLEU == 5
  m1.setMiniElement();
#else
  m1.setQuadElement();
#endif
  m1.readVTKHeaviside(vtkFile);
  m1.setSurfaceConfig();
  m1.setInitSurfaceVolume();
  m1.setInitSurfaceArea();
  m1.setGenericBCPBCNew(physGroup);
  m1.setGenericBC();

  Periodic3D pbc(m1);
  pbc.MountPeriodicVectorsNew("print");

  Simulator3D s1(pbc,m1);
  s1.setBetaPressureLiquid(betaGrad);

  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);

  //const char *dirBase = "/work/gcpoliveira/post-processing/3d/cell-1/";
  //const char *dirBase = "/work/gcpoliveira/post-processing/3d/cell-2/";
  const char *dirBase = "/work/gcpoliveira/post-processing/3d/cell-3/";
  
  //const char *dirBase = "/work/gcpoliveira/post-processing/3d/rising-pbc/";
  //const char *dirBase = "/work/gcpoliveira/post-processing/3d/rising-beta/";

  iter = s1.loadSolution(dirBase,"sim",atoi(*(argv+1)));
  
 // Point's distribution
 Helmholtz3D h1(m1);
 h1.setBC();
 h1.initRisingBubble();
 //h1.initThreeBubbles();
 h1.assemble();
 h1.setk(0.2);
 h1.matMountC();
 h1.setUnCoupledCBC(); 
 h1.setCRHS();
 h1.unCoupledC();
 h1.setModel3DEdgeSize();

 InOut save(m1,s1); // cria objeto de gravacao
 save.saveVTK(vtkFolder,"geometry");
 save.saveVTKSurface(vtkFolder,"geometry");
 save.saveMeshInfo(datFolder);
 save.saveInfo(datFolder,"info",mesh);

 double vinst=0;
 double vref=0;
 double xref=0;
 double xinit=0;
 double dx=0;
 if( strcmp( _frame,"moving") == 0 )
 {
  // moving
  vref = s1.getURef();
  xref = s1.getXRef();
  s1.setCentroidVelPos();
  xinit = s1.getCentroidPosXAverage();
 }

 int nIter = 30000;
 int nReMesh = 1;
 for( int i=1;i<=nIter;i++ )
 {
  for( int j=0;j<nReMesh;j++ )
  {
   cout << color(none,magenta,black);
   cout << "____________________________________ Iteration: " 
	    << iter << endl << endl;
   cout << resetColor();

   // moving
   if( strcmp( _frame,"moving") == 0 )
   {
	// moving frame
	dx = s1.getCentroidPosXAverage() - xinit;
	vinst = s1.getCentroidVelXAverage() + dx/s1.getDt();
    vref += vinst;
	xref += vref*s1.getDt();
	cout << "vref: " << vref << " xref: " << xref << endl;
	cout << "dx: " << dx << endl;
	s1.setUSol(vinst);
    m1.setGenericBCPBCNew(physGroup);
	m1.setGenericBC(vref);
    pbc.MountPeriodicVectorsNew("print");
	s1.setURef(vref);
	s1.setXRef(xref);
   }

   s1.setDtALETwoPhase();

   InOut save(m1,s1); // cria objeto de gravacao
   save.printSimulationReport();

   s1.stepALEPBC();
   //s1.stepALE();
   s1.movePoints();
   s1.assemble();
   s1.matMount();
   s1.setUnCoupledBC();
   s1.setGravity("-X");
   s1.setBetaFlowLiq("+X");
   s1.setRHS();
   s1.setCopyDirectionPBC("RL");
   s1.setInterfaceGeo();
   //s1.setInterfaceLevelSet();
   s1.unCoupledPBCNew();
   //s1.unCoupledBetaPBC(); // rising-beta

   if ( i%5 == 0 )
   {
   save.saveMSH(mshFolder,"newMesh",iter);
   save.saveVTK(vtkFolder,"sim",iter);
   save.saveVTKSurface(vtkFolder,"sim",iter);
   save.saveSol(binFolder,"sim",iter);
   save.saveBubbleInfo(datFolder);
   //save.crossSectionalVoidFraction(datFolder,"voidFraction",iter);
   save.saveBubbleShapeFactors(datFolder,"shapeFactors",iter);
   }
   s1.saveOldData();

   cout << color(none,magenta,black);
   cout << "________________________________________ END of " 
	    << iter << endl << endl;;
   cout << resetColor();

   s1.timeStep();

   iter++;
  }
  Helmholtz3D h2(m1,h1);
  h2.setBC();
  //h2.initRisingBubble();
  h2.initThreeBubbles();
  h2.assemble();
  h2.matMountC();
  h2.setUnCoupledCBC(); 
  h2.setCRHS();
  h2.unCoupledC();
  h2.setModel3DEdgeSize();

  Model3D mOld = m1; 

  /* *********** MESH TREATMENT ************* */
  // set normal and kappa values
  m1.setNormalAndKappa();
  m1.initMeshParameters();

  // 3D operations
  m1.insert3dMeshPointsByDiffusion(6.0);
  m1.remove3dMeshPointsByDiffusion(0.5);
  //m1.removePointByVolume();
  //m1.removePointsByInterfaceDistance();
  //m1.remove3dMeshPointsByDistance();
  m1.remove3dMeshPointsByHeight();
  m1.delete3DPoints();

  // surface operations
  m1.smoothPointsByCurvature();

  m1.insertPointsByLength("curvature");
  //m1.insertPointsByCurvature("flat");
  //m1.removePointsByCurvature();
  //m1.insertPointsByInterfaceDistance("flat");
  m1.contractEdgesByLength("curvature");
  //m1.removePointsByLength();
  m1.flipTriangleEdges();

  m1.removePointsByNeighbourCheck();
  //m1.checkAngleBetweenPlanes();

  /* **************************************** */

  //m1.mesh2Dto3DOriginal();
  m1.mesh3DPoints();
  m1.setMapping();
#if NUMGLEU == 5
 m1.setMiniElement();
#else
 m1.setQuadElement();
#endif
  m1.setSurfaceConfig();

  if( strcmp( _frame,"moving") == 0 )
  {
    m1.setGenericBCPBCNew(physGroup);
    m1.setGenericBC(vref);
    pbc.MountPeriodicVectorsNew("print");
  }
  else
  {
    m1.setGenericBCPBCNew(physGroup);
    m1.setGenericBC();
    pbc.MountPeriodicVectorsNew("noPrint");
  }

  Simulator3D s2(m1,s1);
  s2.applyLinearInterpolation(mOld);
  s1 = s2;
  s1.setSolverPressure(solverP);
  s1.setSolverVelocity(solverV);
  s1.setSolverConcentration(solverC);

  InOut saveEnd(m1,s1); // cria objeto de gravacao
  saveEnd.printMeshReport();
  saveEnd.saveMeshInfo(datFolder);
 }

 PetscFinalize();
 return 0;
}
Example #30
0
/* compute forces */
static void force(mdsys_t *sys) 
{
    double epot;

    epot = 0.0;
    
#if defined(_OPENMP)
#pragma omp parallel reduction(+:epot)
#endif
    {
        double c12,c6,boxby2,rcsq;
        double *fx, *fy, *fz;
        const double *rx, *ry, *rz;
        int i, tid, fromidx, toidx, natoms;

        /* precompute some constants */
        c12 = 4.0*sys->epsilon*pow(sys->sigma,12.0);
        c6  = 4.0*sys->epsilon*pow(sys->sigma, 6.0);
        rcsq= sys->rcut * sys->rcut;
        boxby2 = 0.5*sys->box;
        natoms = sys->natoms;
        epot = 0.0;
        
        /* let each thread operate on a different
           part of the enlarged force array */
#if defined(_OPENMP)
        tid=omp_get_thread_num();
#else
        tid=0;
#endif
        fx=sys->frc + (3*tid*natoms);
        azzero(fx,3*natoms);
        fy=sys->frc + ((3*tid+1)*natoms);
        fz=sys->frc + ((3*tid+2)*natoms);
        rx=sys->pos;
        ry=sys->pos + natoms;
        rz=sys->pos + 2*natoms;

        /* self interaction of atoms in cell */
        for(i=0; i < sys->ncell; i += sys->nthreads) {
            int j;
            const cell_t *c1;

            j = i + tid;
            if (j >= (sys->ncell)) break;
            c1=sys->clist + j;

            for (j=0; j < c1->natoms-1; ++j) {
                int ii,k;
                double rx1, ry1, rz1;

                ii=c1->idxlist[j];
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=j+1; k < c1->natoms; ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;

                    jj=c1->idxlist[k];

                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, sys->box);
                    ry2=pbc(ry1 - ry[jj], boxby2, sys->box);
                    rz2=pbc(rz1 - rz[jj], boxby2, sys->box);
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;

                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;
                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }    

        /* interaction of atoms in different cells */
        for(i=0; i < sys->npair; i += sys->nthreads) {
            int j;
            const cell_t *c1, *c2;

            j = i + tid;
            if (j >= (sys->npair)) break;
            c1=sys->clist + sys->plist[2*j];
            c2=sys->clist + sys->plist[2*j+1];
        
            for (j=0; j < c1->natoms; ++j) {
                int ii, k;
                double rx1, ry1, rz1;

                ii=c1->idxlist[j];
                rx1=rx[ii];
                ry1=ry[ii];
                rz1=rz[ii];
        
                for(k=0; k < c2->natoms; ++k) {
                    int jj;
                    double rx2,ry2,rz2,rsq;
                
                    jj=c2->idxlist[k];
                
                    /* get distance between particle i and j */
                    rx2=pbc(rx1 - rx[jj], boxby2, sys->box);
                    ry2=pbc(ry1 - ry[jj], boxby2, sys->box);
                    rz2=pbc(rz1 - rz[jj], boxby2, sys->box);
                    rsq = rx2*rx2 + ry2*ry2 + rz2*rz2;
                
                    /* compute force and energy if within cutoff */
                    if (rsq < rcsq) {
                        double r6,rinv,ffac;

                        rinv=1.0/rsq;
                        r6=rinv*rinv*rinv;
                    
                        ffac = (12.0*c12*r6 - 6.0*c6)*r6*rinv;
                        epot += r6*(c12*r6 - c6);

                        fx[ii] += rx2*ffac;
                        fy[ii] += ry2*ffac;
                        fz[ii] += rz2*ffac;
                        fx[jj] -= rx2*ffac;
                        fy[jj] -= ry2*ffac;
                        fz[jj] -= rz2*ffac;
                    }
                }
            }
        }

        /* before reducing the forces, we have to make sure 
           that all threads are done adding to them. */
#if defined (_OPENMP)
#pragma omp barrier
#endif
        /* set equal chunks of index ranges */
        i = 1 + (3*natoms / sys->nthreads);
        fromidx = tid * i;
        toidx = fromidx + i;
        if (toidx > 3*natoms) toidx = 3*natoms;

        /* reduce forces from threads with tid != 0 into
           the storage of the first thread. since we have
           threads already spawned, we do this in parallel. */
        for (i=1; i < sys->nthreads; ++i) {
            int offs, j;

            offs = 3*i*natoms;

            for (j=fromidx; j < toidx; ++j) {
                sys->frc[j] += sys->frc[offs+j];
            }
        }
    }
    sys->epot = epot;
}