Пример #1
0
/** calculate buck_capradius from force_cap */
void calc_buck_cap_radii()
{
    /* do not compute cap radii if force capping is individual */
    if( force_cap != -1.0 ) {
        int i,j,cnt=0;
        IA_parameters *params = NULL;
        double force=0.0, frac2, frac6, frac8;
        double r0,r1 = 0.0,diff,exp_term,C_R,D_R;
        for(i=0; i<n_particle_types; i++) {
            for(j=0; j<n_particle_types; j++) {
                params = get_ia_param(i,j);
                if(force_cap>0.0 ) {
                    force = -params->BUCK_F2;
                    if (force_cap<force)
                    {
                        /* Solving numerically using Newton Raphson Technique */
                        force = 0.0;
                        cnt = 0;
                        r1 = (params->BUCK_cut+params->BUCK_discont)/2.0; //First guess value
                        r0 = 0.0 ;
                        while(fabs(r1 - r0)>1.0e-10) {
                            r0 = r1;
                            exp_term = params->BUCK_A*params->BUCK_B*exp(-params->BUCK_B*r0);
                            frac2 = SQR(r0);
                            frac6 = frac2*frac2*frac2;
                            frac8 = frac6*frac2;
                            C_R = 6.0*params->BUCK_C/frac8;
                            D_R = 4.0*params->BUCK_D/frac6;
                            diff = (exp_term - C_R*r0 - D_R*r0 - force_cap)/(-params->BUCK_B*exp_term + 7.0*C_R + 5.0*D_R);
                            r1 = r0 - diff;
                            if(r1>params->BUCK_discont)
                                r1=0.5*(params->BUCK_discont+r0);
                            cnt++;
                            if(cnt>500)
                            {
                                fprintf(stderr,"%d: [email protected]: Failed to converge while determining Buckingham cap radius!!",this_node);
                                fprintf(stderr,"%d: tolerance = %f",this_node, diff);
                                errexit();
                            }
                        }
                        frac2 = SQR(r1);
                        frac6 = frac2*frac2*frac2;
                        force = params->BUCK_A*params->BUCK_B*exp(-params->BUCK_B*r1) - 6.0*params->BUCK_C/(r1*frac6) - 4.0*params->BUCK_D*r1/(frac6);
                        params->BUCK_capradius = r1;
                    }
                    else
                        params->BUCK_capradius = params->BUCK_discont;

                }
                else
                    params->BUCK_capradius = 0.0;

                FORCE_TRACE(fprintf(stderr,"%d: Ptypes %d-%d have cap_radius %f and cap_force %f (iterations: %d)\n",
                                    this_node,i,j,r1,force,cnt));
            }
        }
        BUCK_TRACE(fprintf(stderr,"%d: BUCK: Buckingham force cap imposed %f, Calculated force %f and Cap radius %f after %d iterations\n",this_node,force_cap,force,params->BUCK_capradius,cnt);
                  );
Пример #2
0
/** calculate ljcos2_capradius from force_cap */
void calc_ljcos2_cap_radii()
{
  /* do not compute cap radii if force capping is "individual" */
  if( force_cap != -1.0){
    int i,j,cnt=0;
    IA_parameters *params;
    double force=0.0, rad=0.0, step, frac2, frac6;

    for(i=0; i<n_particle_types; i++) {
      for(j=0; j<n_particle_types; j++) {
        params = get_ia_param(i,j);
        if(force_cap > 0.0 && params->LJCOS2_eps > 0.0) {
    /* I think we have to solve this numerically... and very crude as well */
    cnt=0;
    rad = params->LJCOS2_sig;
    step = -0.1 * params->LJCOS2_sig;
    force=0.0;
    
    while(step != 0) {
      frac2 = SQR(params->LJCOS2_sig/rad);
      frac6 = frac2*frac2*frac2;
            if (rad < params->LJCOS2_rchange) {
              force = 48.0 * params->LJCOS2_eps * frac6*(frac6 - 0.5)/rad;
            }
            else {
        force = 0;
      }
      if((step < 0 && force_cap < force) || (step > 0 && force_cap > force)) {
        step = - (step/2.0); 
      }
      if(fabs(force-force_cap) < 1.0e-6) step=0;
      rad += step; cnt++;
    } 
          params->LJCOS2_capradius = rad;
        }
        else {
    params->LJCOS2_capradius = 0.0; 
        }
        FORCE_TRACE(fprintf(stderr,"%d: Ptypes %d-%d have cap_radius %f and cap_force %f (iterations: %d)\n",
          this_node,i,j,rad,force,cnt));
      }
    }
  }
}
Пример #3
0
/** calculate lj_capradius from force_cap */
void calc_ljgen_cap_radii()
{
  /* do not compute cap radii if force capping is "individual" */
  if( force_cap != -1.0){
    int i,j,cnt=0;
    IA_parameters *params;
    double force=0.0, rad=0.0, step, frac;

    for(i=0; i<n_particle_types; i++) {
      for(j=0; j<n_particle_types; j++) {
        params = get_ia_param(i,j);
        if(force_cap > 0.0 && params->LJGEN_eps > 0.0) {
    /* I think we have to solve this numerically... and very crude as well */
    cnt=0;
    rad = params->LJGEN_sig;
    step = -0.1 * params->LJGEN_sig;
    force=0.0;
    
    while(step != 0) {
      frac = params->LJGEN_sig/rad;
      force =  params->LJGEN_eps 
#ifdef LJGEN_SOFTCORE
        * params->LJGEN_lambda
#endif
        * (params->LJGEN_b1 * params->LJGEN_a1 * pow(frac, params->LJGEN_a1) 
           - params->LJGEN_b2 * params->LJGEN_a2 * pow(frac, params->LJGEN_a2))/rad;
      if((step < 0 && force_cap < force) || (step > 0 && force_cap > force)) {
        step = - (step/2.0); 
      }
      if(fabs(force-force_cap) < 1.0e-6) step=0;
      rad += step; cnt++;
    } 
          params->LJGEN_capradius = rad;
        }
        else {
    params->LJGEN_capradius = 0.0; 
        }
        FORCE_TRACE(fprintf(stderr,"%d: Ptypes %d-%d have cap_radius %f and cap_force %f (iterations: %d)\n",
          this_node,i,j,rad,force,cnt));
      }
    }
  }
}
Пример #4
0
void calc_morse_cap_radii()
{
  /* do not compute cap radii if force capping is "individual" */
  if( force_cap != -1.0){
    int i,j,cnt=0;
    IA_parameters *params;
    double force=0.0, rad=0.0, step, add1, add2;

    for(i=0; i<n_particle_types; i++) {
      for(j=0; j<n_particle_types; j++) {
        params = get_ia_param(i,j);
        if(force_cap > 0.0 && params->MORSE_eps > 0.0) {

    /* I think we have to solve this numerically... and very crude as well */

    cnt=0;
    rad = params->MORSE_rmin - 0.69314719 / params->MORSE_alpha;
    step = -0.1 * rad;
    force=0.0;
    
    while(step != 0) {
      add1 = exp(-2.0 * params->MORSE_alpha * (rad - params->MORSE_rmin));
      add2 = exp( -params->MORSE_alpha * (rad - params->MORSE_rmin));
      force   = -params->MORSE_eps * 2.0 * params->MORSE_alpha * (add2 - add1) / rad;

      if((step < 0 && force_cap < force) || (step > 0 && force_cap > force)) {
        step = - (step/2.0); 
      }
      if(fabs(force-force_cap) < 1.0e-6) step=0;
      rad += step; cnt++;
    } 
          params->MORSE_capradius = rad;
        }
        else {
    params->MORSE_capradius = 0.0; 
        }
        FORCE_TRACE(fprintf(stderr,"%d: Ptypes %d-%d have cap_radius %f and cap_force %f (iterations: %d)\n",
          this_node,i,j,rad,force,cnt));
      }
    }
  }
}
Пример #5
0
/* This routine does not take the optional 2nd environment into account. */
void calc_ljangle_cap_radii()
{
  if( force_cap != -1.0){
    int i,j,cnt=0;
    IA_parameters *params;
    double force=0.0, rad=0.0, step, frac2, frac10;

    for(i=0; i<n_particle_types; i++) {
      for(j=0; j<n_particle_types; j++) {
        params = get_ia_param(i,j);
        if(force_cap > 0.0 && params->LJANGLE_eps > 0.0) {
    /* I think we have to solve this numerically... and very crude as well */
    cnt=0;
    rad = params->LJANGLE_sig;
    step = -0.1 * params->LJANGLE_sig;
    force=0.0;
    
    while(step != 0) {
      frac2  = SQR(params->LJANGLE_sig/rad);
      frac10 = frac2*frac2*frac2*frac2*frac2;
      force = 60.0 * params->LJANGLE_eps * frac10*(frac2 - 1.0) / rad;
      if((step < 0 && force_cap < force) || (step > 0 && force_cap > force)) {
        step = - (step/2.0); 
      }
      if(fabs(force-force_cap) < 1.0e-6) step=0;
      rad += step; cnt++;
    } 
    params->LJANGLE_capradius = rad;
        }
        else {
    params->LJANGLE_capradius = 0.0; 
        }
        FORCE_TRACE(fprintf(stderr,"%d: LJANGLE Ptypes %d-%d have cap_radius %f and cap_force %f (iterations: %d)\n",
          this_node,i,j,rad,force,cnt));
      }
    }
  }
}
Пример #6
0
/** Calculate non bonded forces between a pair of particles.
    @param p1        pointer to particle 1.
    @param p2        pointer to particle 2.
    @param d         vector between p1 and p2. 
    @param dist      distance between p1 and p2.
    @param dist2     distance squared between p1 and p2. */
inline void add_non_bonded_pair_force(Particle *p1, Particle *p2, 
					double d[3], double dist, double dist2)
{
  IA_parameters *ia_params = get_ia_param(p1->p.type,p2->p.type);
  double force[3] = { 0., 0., 0. };
  double torque1[3] = { 0., 0., 0. };
  double torque2[3] = { 0., 0., 0. };
  int j;

  /***********************************************/
  /* bond creation and breaking                  */
  /***********************************************/

#ifdef COLLISION_DETECTION
  if (collision_params.mode > 0)
    detect_collision(p1,p2);
#endif

  /*affinity potential*/
#ifdef AFFINITY
  add_affinity_pair_force(p1,p2,ia_params,d,dist,force);
#endif
  
  FORCE_TRACE(fprintf(stderr, "%d: interaction %d<->%d dist %f\n", this_node, p1->p.identity, p2->p.identity, dist));

  /***********************************************/
  /* thermostat                                  */
  /***********************************************/

#ifdef DPD
  /* DPD thermostat forces */
  if ( thermo_switch & THERMO_DPD ) add_dpd_thermo_pair_force(p1,p2,d,dist,dist2);
#endif

  /** The inter dpd force should not be part of the virial
      
#ifdef INTER_DPD
  add_inter_dpd_pair_force(p1,p2,ia_params,d,dist,dist2);
#endif
  
  /***********************************************/
  /* non bonded pair potentials                  */
  /***********************************************/

   calc_non_bonded_pair_force(p1,p2,ia_params,d,dist,dist2,force,torque1,torque2);
   
  /***********************************************/
  /* short range electrostatics                  */
  /***********************************************/

#ifdef ELECTROSTATICS
  if (coulomb.method == COULOMB_DH)
    add_dh_coulomb_pair_force(p1,p2,d,dist,force);
  
  if (coulomb.method == COULOMB_RF)
    add_rf_coulomb_pair_force(p1,p2,d,dist,force);
#endif

  /*********************************************************************/
  /* everything before this contributes to the virial pressure in NpT, */
  /* but nothing afterwards                                            */
  /*********************************************************************/
#ifdef NPT
  for (j = 0; j < 3; j++)
    if(integ_switch == INTEG_METHOD_NPT_ISO)
      nptiso.p_vir[j] += force[j] * d[j];
#endif

  /***********************************************/
  /* semi-bonded multi-body potentials            */
  /***********************************************/
  
   /* Directional LJ */
#ifdef LJ_ANGLE
   /* This is a multi-body forces that changes the forces of 6 particles */
   add_ljangle_force(p1, p2, ia_params, d, dist);
#endif
  
  /***********************************************/
  /* long range electrostatics                   */
  /***********************************************/

#ifdef ELECTROSTATICS

  /* real space coulomb */
  double q1q2 = p1->p.q*p2->p.q;
  switch (coulomb.method) {
#ifdef P3M
  case COULOMB_ELC_P3M: {
	  if (q1q2) {
		  p3m_add_pair_force(q1q2,d,dist2,dist,force);

		  // forces from the virtual charges
		  // they go directly onto the particles, since they are not pairwise forces
		  if (elc_params.dielectric_contrast_on)
			  ELC_P3M_dielectric_layers_force_contribution(p1, p2, p1->f.f, p2->f.f);
	  }
	  break;
  }
  case COULOMB_P3M_GPU:
  case COULOMB_P3M: {
#ifdef NPT
	  if (q1q2) {
		  double eng = p3m_add_pair_force(q1q2,d,dist2,dist,force);
		  if(integ_switch == INTEG_METHOD_NPT_ISO)
			  nptiso.p_vir[0] += eng;
	  }
#else
	  if (q1q2) p3m_add_pair_force(q1q2,d,dist2,dist,force);
#endif
	  break;
  }
#endif
  case COULOMB_MMM1D:
	  if (q1q2) add_mmm1d_coulomb_pair_force(q1q2,d,dist2,dist,force);
	  break;
  case COULOMB_MMM2D:
	  if (q1q2) add_mmm2d_coulomb_pair_force(q1q2,d,dist2,dist,force);
	  break;
#ifdef EWALD_GPU
  case COULOMB_EWALD_GPU:
	  if (q1q2) add_ewald_gpu_coulomb_pair_force(p1,p2,d,dist,force);
	  break;
#endif
  default:
	  break;
  }

#endif /*ifdef ELECTROSTATICS */


  /***********************************************/
  /* long range magnetostatics                   */
  /***********************************************/


#ifdef DIPOLES
  /* real space magnetic dipole-dipole */
  switch (coulomb.Dmethod) {
#ifdef DP3M
  case  DIPOLAR_MDLC_P3M: 
   //fall trough 
  case DIPOLAR_P3M: {
#ifdef NPT
    double eng = dp3m_add_pair_force(p1,p2,d,dist2,dist,force);
    if(integ_switch == INTEG_METHOD_NPT_ISO)
      nptiso.p_vir[0] += eng;
#else
    dp3m_add_pair_force(p1,p2,d,dist2,dist,force);
#endif
    break;
  }
#endif /*ifdef DP3M */
  default:
      break;
  }  
#endif /* ifdef DIPOLES */
  
  /***********************************************/
  /* add total nonbonded forces to particle      */
  /***********************************************/

  for (j = 0; j < 3; j++) {
    p1->f.f[j] += force[j];
    p2->f.f[j] -= force[j];
#ifdef ROTATION
    p1->f.torque[j] += torque1[j];
    p2->f.torque[j] += torque2[j];
#endif
  }
}
Пример #7
0
void calc_long_range_forces()
{
#ifdef ELECTROSTATICS  
	/* calculate k-space part of electrostatic interaction. */
  switch (coulomb.method) {
#ifdef P3M
  case COULOMB_ELC_P3M:
    if (elc_params.dielectric_contrast_on) {
      ELC_P3M_modify_p3m_sums_both();
      ELC_p3m_charge_assign_both();
      ELC_P3M_self_forces();
    }
    else
      p3m_charge_assign();
    
    p3m_calc_kspace_forces(1,0);
    
    if (elc_params.dielectric_contrast_on)
      ELC_P3M_restore_p3m_sums();
    
    ELC_add_force();
    
    break;
#endif
#ifdef CUDA
  case COULOMB_P3M_GPU:
    if (this_node == 0) {
      FORCE_TRACE(printf("Computing GPU P3M forces.\n"));
      p3m_gpu_add_farfield_force();
    }
    /* there is no NPT handling here as long as we cannot compute energies.
       This is checked in integrator_npt_sanity_checks() when integration starts. */
    break;
#endif
#ifdef P3M
  case COULOMB_P3M:
    FORCE_TRACE(printf("%d: Computing P3M forces.\n", this_node));
    p3m_charge_assign();
#ifdef NPT
    if (integ_switch == INTEG_METHOD_NPT_ISO)
      nptiso.p_vir[0] += p3m_calc_kspace_forces(1,1);
    else
#endif
      p3m_calc_kspace_forces(1, 0);
    break;
#endif
  case COULOMB_MAGGS:
    maggs_calc_forces();
    break;
  case COULOMB_MMM2D:
    MMM2D_add_far_force();
    MMM2D_dielectric_layers_force_contribution();
    break;
#ifdef SCAFACOS
  case COULOMB_SCAFACOS:
    Electrostatics::Scafacos::add_long_range_force();
    break;
#endif
  default:
    break;
  }

/* If enabled, calculate electrostatics contribution from electrokinetics species. */ 
#ifdef EK_ELECTROSTATIC_COUPLING
  ek_calculate_electrostatic_coupling();
#endif

#endif  /*ifdef ELECTROSTATICS */
 
#ifdef DIPOLES  
  /* calculate k-space part of the magnetostatic interaction. */
  switch (coulomb.Dmethod) {
#ifdef DP3M
  case DIPOLAR_MDLC_P3M:
    add_mdlc_force_corrections();
    //fall through 
  case DIPOLAR_P3M:
    dp3m_dipole_assign();
#ifdef NPT
    if(integ_switch == INTEG_METHOD_NPT_ISO) {
      nptiso.p_vir[0] += dp3m_calc_kspace_forces(1,1);
      fprintf(stderr,"dipolar_P3M at this moment is added to p_vir[0]\n");    
    } else
#endif
      dp3m_calc_kspace_forces(1,0);
    
    break;
#endif
  case DIPOLAR_ALL_WITH_ALL_AND_NO_REPLICA: 
    dawaanr_calculations(1,0);
    break;
  case DIPOLAR_MDLC_DS:
    add_mdlc_force_corrections();
    //fall through 
  case DIPOLAR_DS: 
    magnetic_dipolar_direct_sum_calculations(1,0);
    break;
  case DIPOLAR_DS_GPU: 
    // Do nothing. It's an actor
    break;
  case DIPOLAR_NONE:
      break;
  default:
      runtimeErrorMsg() <<"unknown dipolar method";
      break;
  }
#endif  /*ifdef DIPOLES */
}