Ignore:
Timestamp:
Dec 19, 2012, 3:25:53 PM (13 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, Candidate_v1.7.0, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
990a62
Parents:
e7579e
git-author:
Frederik Heber <heber@…> (10/04/12 22:01:47)
git-committer:
Frederik Heber <heber@…> (12/19/12 15:25:53)
Message:

ManyBodyPotential_Tersoff is now correctly implemented.

  • changed implementation to match with [Tersoff, '89] with incorporates configurations consisting of different elements and which is also the one implemented in tremolo (for whose ptential parameters we aim for).
  • we have unit test of operator() that checks against a set of values obtained from a brief run with tremolo of a configuration consisting of 5 carbon atoms: the results are the same by each function.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp

    re7579e rffc368  
    4343
    4444#include "CodePatterns/Assert.hpp"
     45//#include "CodePatterns/Info.hpp"
    4546
    4647#include "Potentials/helpers.hpp"
     
    5455
    5556ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
    56     const double &_cutoff_offset,
    57     const double &_cutoff_halfwidth,
     57    const double &_R,
     58    const double &_S,
    5859    const double &_A,
    5960    const double &_B,
    60     const double &_lambda1,
    61     const double &_lambda2,
     61    const double &_lambda,
     62    const double &_mu,
    6263    const double &_lambda3,
    6364    const double &_alpha,
    6465    const double &_beta,
     66    const double &_chi,
     67    const double &_omega,
    6568    const double &_n,
    6669    const double &_c,
     
    7174  triplefunction(_triplefunction)
    7275{
    73   params[cutoff_offset] = _cutoff_offset;
    74   params[cutoff_halfwidth] = _cutoff_halfwidth;
     76//  Info info(__func__);
     77  params[R] = _R;
     78  params[S] = _S;
    7579  params[A] = _A;
    7680  params[B] = _B;
    77   params[lambda1] = _lambda1;
    78   params[lambda2] = _lambda2;
     81  params[lambda] = _lambda;
     82  params[mu] = _mu;
    7983  params[lambda3] = _lambda3;
    8084  params[alpha] = _alpha;
    8185  params[beta] = _beta;
     86  params[chi] = _chi;
     87  params[omega] = _omega;
    8288  params[n] = _n;
    8389  params[c] = _c;
     
    9197    ) const
    9298{
    93   const double &distance = arguments[0].distance;
    94   const double cutoff = function_cutoff(distance);
    95   const double result = (cutoff == 0.) ? 0. : cutoff * (
    96       function_prefactor(
    97           alpha,
    98           boost::bind(&ManyBodyPotential_Tersoff::function_eta,
    99               boost::cref(*this),
    100               boost::cref(arguments[0])))
    101       * function_smoother(
    102           distance,
    103           A,
    104           lambda1)
    105       +
    106       function_prefactor(
    107           beta,
    108           boost::bind(&ManyBodyPotential_Tersoff::function_zeta,
    109               boost::cref(*this),
    110               boost::cref(arguments[0])))
    111       * function_smoother(
    112           distance,
    113           -B,
    114           lambda2)
    115   );
     99//  Info info(__func__);
     100  const argument_t &r_ij = arguments[0];
     101  const double cutoff = function_cutoff(r_ij.distance);
     102  const double result = (cutoff == 0.) ?
     103      0. :
     104      cutoff * (
     105          function_prefactor(
     106              params[alpha],
     107              function_eta(r_ij))
     108          * function_smoother(
     109              params[A],
     110              params[lambda],
     111              r_ij.distance)
     112          +
     113          function_prefactor(
     114              params[beta],
     115              function_zeta(r_ij))
     116          * function_smoother(
     117              -params[B],
     118              params[mu],
     119              r_ij.distance)
     120      );
     121//  LOG(2, "DEBUG: operator()(" << r_ij.distance << ") = " << result);
    116122  return std::vector<result_t>(1, result);
     123}
     124
     125ManyBodyPotential_Tersoff::derivative_components_t
     126ManyBodyPotential_Tersoff::derivative(
     127    const arguments_t &arguments
     128    ) const
     129{
     130//  Info info(__func__);
     131  return ManyBodyPotential_Tersoff::derivative_components_t();
     132}
     133
     134ManyBodyPotential_Tersoff::results_t
     135ManyBodyPotential_Tersoff::parameter_derivative(
     136    const arguments_t &arguments,
     137    const size_t index
     138    ) const
     139{
     140//  Info info(__func__);
     141//  ASSERT( arguments.size() == 1,
     142//      "PairPotential_Harmonic::parameter_derivative() - requires exactly one argument.");
     143  const argument_t &r_ij = arguments[0];
     144  switch (index) {
     145    case R:
     146    {
     147      const double result = 0.;
     148      return results_t(1, result);
     149      break;
     150    }
     151    case S:
     152    {
     153      const double result = 0.;
     154      return results_t(1, result);
     155      break;
     156    }
     157    case A:
     158    {
     159      const double result = 0.;
     160      return results_t(1, result);
     161      break;
     162    }
     163    case B:
     164    {
     165      const double result = 0.;
     166      return results_t(1, result);
     167      break;
     168    }
     169    case lambda:
     170    {
     171      const double cutoff = function_cutoff(r_ij.distance);
     172      const double result = (cutoff == 0.) ?
     173          0. :
     174          -r_ij.distance * cutoff * params[lambda] * (
     175          function_prefactor(
     176              params[alpha],
     177              function_eta(r_ij))
     178          * function_smoother(
     179              params[A],
     180              params[lambda],
     181              r_ij.distance)
     182          );
     183      return results_t(1, result);
     184      break;
     185    }
     186    case mu:
     187    {
     188      const double cutoff = function_cutoff(r_ij.distance);
     189      const double result = (cutoff == 0.) ?
     190          0. :
     191          -r_ij.distance * cutoff * params[mu] *(
     192          function_prefactor(
     193              params[beta],
     194              function_zeta(r_ij))
     195          * function_smoother(
     196              -params[B],
     197              params[mu],
     198              r_ij.distance)
     199      );
     200      return results_t(1, result);
     201      break;
     202    }
     203    case lambda3:
     204    {
     205      const double result = 0.;
     206      return results_t(1, result);
     207      break;
     208    }
     209    case alpha:
     210    {
     211      const double temp =
     212          pow(params[alpha]*function_eta(r_ij), params[n]);
     213      const double cutoff = function_cutoff(r_ij.distance);
     214      const double result = (cutoff == 0.) || (params[alpha] == 0. )?
     215          0. :
     216          function_smoother(
     217              -params[A],
     218              params[lambda],
     219              r_ij.distance)
     220          * (-.5) * params[alpha] * (temp/params[alpha])
     221          / (1. + temp)
     222          ;
     223      return results_t(1, result);
     224      break;
     225    }
     226    case beta:
     227    {
     228      const double temp =
     229          pow(params[beta]*function_zeta(r_ij), params[n]);
     230      const double cutoff = function_cutoff(r_ij.distance);
     231      const double result = (cutoff == 0.) || (params[beta] == 0. )?
     232          0. : cutoff *
     233          function_smoother(
     234              -params[B],
     235              params[mu],
     236              r_ij.distance)
     237          * (-.5) * params[beta] * (temp/params[beta])
     238          / (1. + temp)
     239          ;
     240      return results_t(1, result);
     241      break;
     242    }
     243    case n:
     244    {
     245      const double temp =
     246          pow(params[beta]*function_zeta(r_ij), params[n]);
     247      const double cutoff = function_cutoff(r_ij.distance);
     248      const double result = (cutoff == 0.) ?
     249          0. : cutoff *
     250          function_smoother(
     251              -params[B],
     252              params[mu],
     253              r_ij.distance)
     254          * params[B]
     255          * ( log(1.+temp)/(params[n]*params[n]) - temp
     256              * (log(function_zeta(r_ij)) + log(params[beta]))
     257              /(params[n]*(1.+temp)))
     258          ;
     259      return results_t(1, result);
     260      break;
     261    }
     262    case c:
     263    {
     264      const double result = 0.;
     265      return results_t(1, result);
     266      break;
     267    }
     268    case d:
     269    {
     270      const double result = 0.;
     271      return results_t(1, result);
     272      break;
     273    }
     274    case h:
     275    {
     276      const double result = 0.;
     277      return results_t(1, result);
     278      break;
     279    }
     280    default:
     281      break;
     282  }
     283  return results_t(1, 0.);
    117284}
    118285
     
    122289  ) const
    123290{
    124   const double offset = (distance - cutoff_offset);
    125   if (offset < - cutoff_halfwidth)
    126     return 1.;
    127   else if (offset > cutoff_halfwidth)
    128     return 0.;
     291//  Info info(__func__);
     292  double result = 0.;
     293  if (distance < params[R])
     294    result = 1.;
     295  else if (distance > params[S])
     296    result = 0.;
    129297  else {
    130     return (0.5 - 0.5 * sin( .5 * M_PI * offset/cutoff_halfwidth));
     298    result = (0.5 + 0.5 * cos( M_PI * (distance - params[R])/(params[S]-params[R])));
    131299  }
     300//  LOG(2, "DEBUG: function_cutoff(" << distance << ") = " << result);
     301  return result;
    132302}
    133303
     
    135305ManyBodyPotential_Tersoff::function_prefactor(
    136306    const double &alpha,
    137     boost::function<result_t()> etafunction
     307    const double &eta
    138308  ) const
    139309{
    140   return pow(
    141       (1. + Helpers::pow(alpha * etafunction(), n)),
    142       -1./(2.*n));
     310//  Info info(__func__);
     311  const double result = params[chi] * pow(
     312      (1. + pow(alpha * eta, params[n])),
     313      -1./(2.*params[n]));
     314//  LOG(2, "DEBUG: function_prefactor(" << alpha << "," << eta << ") = " << result);
     315  return result;
     316}
     317
     318ManyBodyPotential_Tersoff::result_t
     319ManyBodyPotential_Tersoff::function_smoother(
     320    const double &prefactor,
     321    const double &lambda,
     322    const double &distance
     323    ) const
     324{
     325//  Info info(__func__);
     326  const double result = prefactor * exp(-lambda * distance);
     327//  LOG(2, "DEBUG: function_smoother(" << prefactor << "," << lambda << "," << distance << ") = " << result);
     328  return result;
    143329}
    144330
     
    148334  ) const
    149335{
     336//  Info info(__func__);
    150337  result_t result = 0.;
    151338
    152339  // get all triples within the cutoff
    153   std::vector<arguments_t> triples = triplefunction(r_ij, cutoff_offset+cutoff_halfwidth);
     340  std::vector<arguments_t> triples = triplefunction(r_ij, params[S]);
    154341  for (std::vector<arguments_t>::const_iterator iter = triples.begin();
    155342      iter != triples.end(); ++iter) {
     
    158345    const argument_t &r_ik = (*iter)[0];
    159346    result += function_cutoff(r_ik.distance)
    160         * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
     347        * exp( Helpers::pow(params[lambda3] * (r_ij.distance - r_ik.distance) ,3));
    161348  }
    162349
     350//  LOG(2, "DEBUG: function_eta(" << r_ij.distance << ") = " << result);
    163351  return result;
    164352}
     
    169357  ) const
    170358{
     359//  Info info(__func__);
    171360  result_t result = 0.;
    172361
    173362  // get all triples within the cutoff
    174   std::vector<arguments_t> triples = triplefunction(r_ij, cutoff_offset+cutoff_halfwidth);
     363  std::vector<arguments_t> triples = triplefunction(r_ij, params[S]);
    175364  for (std::vector<arguments_t>::const_iterator iter = triples.begin();
    176365      iter != triples.end(); ++iter) {
     
    181370    result +=
    182371        function_cutoff(r_ik.distance)
     372        * params[omega]
    183373        * function_angle(r_ij.distance, r_ik.distance, r_jk.distance)
    184         * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
     374        * exp( Helpers::pow(params[lambda3] * (r_ij.distance - r_ik.distance) ,3));
    185375  }
    186376
     377//  LOG(2, "DEBUG: function_zeta(" << r_ij.distance << ") = " << result);
    187378  return result;
    188379}
     
    195386  ) const
    196387{
     388//  Info info(__func__);
    197389  const double angle = Helpers::pow(r_ij,2) + Helpers::pow(r_ik,2) - Helpers::pow(r_jk,2);
    198   const double divisor = r_ij * r_ik;
    199   const double result =
    200       1.
    201       + (Helpers::pow(c, 2)/Helpers::pow(d, 2))
    202       - Helpers::pow(c, 2)/(Helpers::pow(d, 2) +
    203           Helpers::pow(h - cos(angle/divisor),2));
    204   return result;
    205 }
     390  const double divisor = 2.* r_ij * r_ik;
     391//  LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
     392  if (divisor != 0.) {
     393    const double result =
     394        1.
     395        + (Helpers::pow(params[c]/params[d], 2))
     396        - Helpers::pow(params[c], 2)/(Helpers::pow(params[d], 2) +
     397            Helpers::pow(params[h] - angle/divisor,2));
     398
     399//    LOG(2, "DEBUG: function_angle(" << r_ij << "," << r_ik << "," << r_jk << ") = " << result);
     400    return result;
     401  } else
     402    return 0.;
     403}
     404
Note: See TracChangeset for help on using the changeset viewer.