예제 #1
0
void Compute_Forces(gsl_matrix * Positions, gsl_matrix * Velocities, gsl_matrix * Neighbors, 
                    gsl_vector * ListHead, gsl_vector * List, int type1, int type2, 
                    gsl_matrix * Forces, gsl_vector * Energy, gsl_vector * Kinetic )
{

  // RESET MATRICES AND VECTORS
  // TODO: Redundant?
  gsl_matrix_set_zero(Forces);
  gsl_vector_set_zero(Energy);
  gsl_vector_set_zero(Kinetic);

  // Begin of parallel region
  
  int omp_get_max_threads();
  int chunks = NParticles / omp_get_max_threads();

  #pragma omp parallel
  {
    #pragma omp for schedule (dynamic,chunks) 
    for (int i=0;i<NParticles;i++)
    {
      gsl_vector_view vi = gsl_matrix_row(Velocities, i);

      double * fij = malloc(3*sizeof(double));

      // Compute the kinetic energy of particle i (0.5 mi vi^2)
      double ei = KineticEnergy(&vi.vector, (int) gsl_matrix_get(Positions,i,0));
      gsl_vector_set(Kinetic,i,ei);

      // Obtain the list of neighboring cells to iCell (the cell i belongs to)
      int iCell    = FindParticle(Positions,i);
      gsl_vector_view NeighboringCells = gsl_matrix_row(Neighbors, iCell);
           
      // Obtain the list of neighboring particles that interacts with i
      // i interacts with all Verlet[j] particles (j = 0 .. NNeighbors-1)
      int * Verlet = malloc(27 * NParticles * sizeof(int) / (Mx*My*Mz));
      int NNeighbors = Compute_VerletList(Positions, i, &NeighboringCells.vector, iCell, ListHead, List, Verlet);
      
      // Loop over all the j-neighbors of i-particle
      for (int j=0;j<NNeighbors;j++)
      {
        ei = Compute_Force_ij(Positions, i, Verlet[j], type1, type2, fij);
        Forces->data[i*Forces->tda + 0] += fij[0];
        Forces->data[i*Forces->tda + 1] += fij[1];
        Forces->data[i*Forces->tda + 2] += fij[2];
        Energy->data[i*Energy->stride]  += ei;
      }
      free(Verlet);
      free(fij);
    }
  }
  // End of parallel region
}
예제 #2
0
/***=======================================================================***/
void NHThermostat(cellgrid *CG, coord *crd, prmtop *tp, trajcon *tj,
		  Energy *sysUV, double ETAt, double *CHIt, double *CHItp1e,
		  double *CHItp1q, int barostat)
{
  int i, j, g3con;
  double dt, Ttarget, pmass, qmass, invqmass, sigma, vfac;
  double *vtmp;
  cell *C;

  /*** Unpack ***/
  dt = (barostat == 1) ? 0.125*sqrt(418.4)*tj->dt : 0.25*sqrt(418.4)*tj->dt;
  Ttarget = (barostat == 1) ? GASCNST*tj->Ttarget : 0.0;
  pmass = (barostat == 1) ? ETAt*ETAt*tj->npth.pmass : 0.0;
  qmass = tj->npth.qmass;
  sigma = 2.0*tj->npth.sigma;
  invqmass = 1.0/qmass;

  /*** Compute the kinetic energy ***/
  sysUV->kine = KineticEnergy(CG, crd, tp, tj);
  *CHItp1e = *CHIt + dt*(2.0*sysUV->kine + pmass - sigma - Ttarget)*invqmass;
  const int ncell = CG->ng[0]*CG->ng[1]*CG->ng[2];
  vtmp = crd->vel;
  vfac = exp(-2.0*dt*(*CHItp1e));
  for (i = 0; i < ncell; i++) {
    C = &CG->data[i];
    for (j = 0; j < C->nr[0]; j++) {
      g3con = 3*C->data[j].id;
      vtmp[g3con] *= vfac;
      vtmp[g3con+1] *= vfac;
      vtmp[g3con+2] *= vfac;
    }
  }
  sysUV->kine = KineticEnergy(CG, crd, tp, tj);
  *CHItp1q = *CHItp1e +
    dt*(2.0*sysUV->kine + pmass - sigma - Ttarget)*invqmass;
}
예제 #3
0
double
MeanKineticEnergy
(
    const MDConstants K,
    const Molecule **positions,
	const TurbField **turb_velocities
)
{
    double time_mean = 0;

    for (unsigned n = 0; n < K.SnapshotNum; ++n) // calc mean over time
    {
        double part_mean = 0; //for every new timestep

        for (unsigned i = 0; i < K.PartNum; ++i)//calc mean over particles
        {		
            double v_part[kDIM] = {0};
            double v_0[kDIM];  
            InitConstArray (v_0, kDIM, K.v_0);// v_0 * \vec{e_part}

            NormalizeVector (v_0, positions[n][i].direction, v_part);
            double v[kDIM]; //temp array
            SumVector (v_part, turb_velocities[n][i].direction, v);
             
			double kin_energy = KineticEnergy (v);

            part_mean += kin_energy;	assert (part_mean >= 0);
        }

        part_mean /= K.PartNum;		

        time_mean += part_mean; assert (time_mean > 0);
    }	

    time_mean /= (K.iteration_num * K.delta_t);

    return time_mean;
}
예제 #4
0
파일: System.cpp 프로젝트: moncar/FYS3150-8
void System::importanceSampling()
{
    int NOA;            // Number Of Accepted steps
    double I, I2, dx;   // total energy integral
    double T, T2, dt;   // kinetic energy integral
    double V, V2, dv;   // potential energy integral
    int a,b,c,i,j;      // loop variables: a->alpha, b->beta, c->cycles, i->particle, j-> dimension
    int amax = Alpha.n_elem;    // number of total alpha values
    int bmax = Beta.n_elem;     // number of total beta values
    double wf_new, wf_old;
    double greensfunction;
    double D = 0.5;     // diffusion constant


    for (a=0; a<amax; a++)    // LOOP OVER ALPHA VALUES
    {
        Wavefunction->setAlpha(a);
        TypeHamiltonian->getWavefunction()->setAlpha(a);

        for (b=0; b<bmax; b++)    // LOOP OVER BETA VALUES
        {
            Wavefunction->setBeta(b);
            TypeHamiltonian->getWavefunction()->setBeta(b);

            dx = I = I2 = NOA = 0;
            dt = T = T2 = 0;
            dv = V = V2 = 0;

            // IMPORTANCE SAMPLING:
            for (c=0; c<NumberOfCycles; c++)
            {
                dx = 0;
                for (i=0; i<NumberOfParticles; i++)
                {
                    // Taking a new, random step, moving one particle only:
                    NewPosition = OldPosition;
                    NewPosition.row(i) = OldPosition.row(i)+Rnd->nextGauss(0,sqrt(StepLength))+QuantumForceOld.row(i)*StepLength*D;

                    wf_new = Wavefunction->evaluateWavefunction(NewPosition);
                    quantumForce(NewPosition,QuantumForceNew,wf_new);

                    // Metropolis-Hastings algorithm:
                    greensfunction = 0.0;
                    for(j=0;j<NumberOfDimensions;j++)
                    {
                        greensfunction += 0.5*(QuantumForceOld(i,j) + QuantumForceNew(i,j))*(D*StepLength*0.5*(QuantumForceOld(i,j)-QuantumForceNew(i,j)) - NewPosition(i,j) + OldPosition(i,j));
                    }
                    greensfunction = exp(greensfunction);

                    // Metropolis test:
                    if (ran0(&RandomSeed) <= greensfunction*wf_new*wf_new/(wf_old*wf_old))
                    {
                        OldPosition.row(i) = NewPosition.row(i);
                        QuantumForceOld.row(i) = QuantumForceNew.row(i);
                        Wavefunction->setOldWavefunction(wf_new);
                        wf_old = wf_new;
                    }
                }
                // Updating integral:

                // LOCAL ENERGY
                dx = TypeHamiltonian->evaluateLocalEnergy(OldPosition);
                I += dx;
                I2 += dx*dx;

                // LOCAL KINETIC ENERGY
                dt = TypeHamiltonian->getKineticEnergy();
                T += dt;
                T2 += dt*dt;

                // LOCAL POTENTIAL ENERGY
                dv = TypeHamiltonian->getPotentialEnergy();
                V += dv;
                V2 += dv*dv;

                NOA++;
            }
            NumberOfAcceptedSteps(a,b) = NOA;
            Energy(a,b) = I/double(NumberOfCycles);
            EnergySquared(a,b) = I2/double(NumberOfCycles);
            Variance(a,b) = (EnergySquared(a,b) - Energy(a,b)*Energy(a,b));
            KineticEnergy(a,b) = T/double(NumberOfCycles);
            KineticEnergySquared(a,b) = T2/double(NumberOfCycles);
            PotentialEnergy(a,b) = V/double(NumberOfCycles);
            PotentialEnergySquared(a,b) = V2/double(NumberOfCycles);
            //AvgDistance = 0;
        }
    }
}
예제 #5
0
파일: System.cpp 프로젝트: moncar/FYS3150-8
void System::runMonteCarlo()
{
    int i, j, k, NOA;
    int alpha_max = Alpha.n_elem;
    int beta_max = Beta.n_elem;
    double I, I2, dx; // total energy integral
    double T, T2, dt; // kinetic energy integral
    double V, V2, dv; // potential energy integral
    bool Accepted;

    for (i=0; i<alpha_max; i++)    // LOOP OVER ALPHA VALUES
    {
        Wavefunction->setAlpha(i);
        TypeHamiltonian->getWavefunction()->setAlpha(i);

        for (j=0; j<beta_max; j++)    // LOOP OVER BETA VALUES
        {
            Wavefunction->setBeta(j);
            TypeHamiltonian->getWavefunction()->setBeta(j);
            dx = I = I2 = NOA = 0;
            dt = T = T2 = 0;
            dv = V = V2 = 0;

            // BRUTE FORCE METROPOLIS:
            for (k=0; k<NumberOfCycles; k++)
            {
                Accepted = newStepMetropolis(); // NEW STEP: ACCEPTED OR REFUSED
                if (Accepted)
                {
                    // LOCAL ENERGY
                    dx = TypeHamiltonian->evaluateLocalEnergy(OldPosition);
                    I += dx;
                    I2 += dx*dx;

                    // LOCAL KINETIC ENERGY
                    dt = TypeHamiltonian->getKineticEnergy();
                    T += dt;
                    T2 += dt*dt;

                    // LOCAL POTENTIAL ENERGY
                    dv = TypeHamiltonian->getPotentialEnergy();
                    V += dv;
                    V2 += dv*dv;

                    NOA++;
                }
                else
                {
                    I += dx;
                    I2 += dx*dx;

                    T += dt;
                    T2 += dt*dt;

                    V += dv;
                    V2 += dv*dv;
                }

            }

            NumberOfAcceptedSteps(i,j) = NOA;
            Energy(i,j) = I/double(NumberOfCycles);
            EnergySquared(i,j) = I2/double(NumberOfCycles);
            Variance(i,j) = (EnergySquared(i,j) - Energy(i,j)*Energy(i,j));
            KineticEnergy(i,j) = T/double(NumberOfCycles);
            KineticEnergySquared(i,j) = T2/double(NumberOfCycles);
            PotentialEnergy(i,j) = V/double(NumberOfCycles);
            PotentialEnergySquared(i,j) = V2/double(NumberOfCycles);
        }
    }
}