LCOV - code coverage report
Current view: top level - symfunc - Fccubic.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 30 30 100.0 %
Date: 2024-10-18 14:00:25 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2014-2020 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "function/FunctionTemplateBase.h"
      23             : #include "function/FunctionShortcut.h"
      24             : #include "function/FunctionOfMatrix.h"
      25             : #include "core/ActionRegister.h"
      26             : 
      27             : #include <string>
      28             : #include <cmath>
      29             : 
      30             : namespace PLMD {
      31             : namespace symfunc {
      32             : 
      33             : //+PLUMEDOC MCOLVAR FCCUBIC_FUNC
      34             : /*
      35             : Measure how similar the environment around atoms is to that found in a FCC structure.
      36             : 
      37             : \par Examples
      38             : 
      39             : */
      40             : //+ENDPLUMEDOC
      41             : 
      42             : //+PLUMEDOC MCOLVAR FCCUBIC_FUNC_MATRIX
      43             : /*
      44             : Measure how similar the environment around atoms is to that found in a FCC structure.
      45             : 
      46             : \par Examples
      47             : 
      48             : */
      49             : //+ENDPLUMEDOC
      50             : 
      51             : //+PLUMEDOC MCOLVAR FCCUBIC
      52             : /*
      53             : Measure how similar the environment around atoms is to that found in a FCC structure.
      54             : 
      55             : This CV was introduced in this article \cite fcc-michele-1 and again in this article \cite fcc-michele-2
      56             : This CV essentially determines whether the environment around any given atom is similar to that found in
      57             : the FCC structure or not.  The function that is used to make this determination is as follows:
      58             : 
      59             : \f[
      60             : s_i = \frac{ \sum_{i \ne j} \sigma(r_{ij}) \left\{ a\left[ \frac{(x_{ij}y_{ij})^4 + (x_{ij}z_{ij})^4 + (y_{ij}z_{ij})^4}{r_{ij}^8} - \frac{\alpha (x_{ij}y_{ij}z_{ij})^4}{r_{ij}^{12}} \right] + b \right\} }{ \sum_{i \ne j} \sigma(r_{ij}) }
      61             : \f]
      62             : 
      63             : In this expression \f$x_{ij}\f$, \f$y_{ij}\f$ and \f$z_{ij}\f$ are the \f$x\f$, \f$y\f$ and \f$z\f$ components of the vector connecting atom \f$i\f$ to
      64             : atom \f$j\f$ and \f$r_{ij}\f$ is the magnitude of this vector.  \f$\sigma(r_{ij})\f$ is a \ref switchingfunction that acts on the distance between
      65             : atom \f$i\f$ and atom \f$j\f$ and its inclusion in the numerator and the denominator of the above expression as well as the fact that we are summing
      66             : over all of the other atoms in the system ensures that we are calculating an average
      67             : of the function of \f$x_{ij}\f$, \f$y_{ij}\f$ and \f$z_{ij}\f$ for the atoms in the first coordination sphere around atom \f$i\f$.  Lastly, \f$\alpha\f$
      68             : is a parameter that can be set by the user, which by default is equal to three.  The values of \f$a\f$ and \f$b\f$ are calculated from \f$\alpha\f$ using:
      69             : 
      70             : \f[
      71             : a = \frac{ 80080}{ 2717 + 16 \alpha} \qquad \textrm{and} \qquad b = \frac{ 16(\alpha - 143) }{2717 + 16\alpha}
      72             : \f]
      73             : 
      74             : This quantity is once again a multicolvar so you can compute it for multiple atoms using a single PLUMED action and then compute
      75             : the average value for the atoms in your system, the number of atoms that have an \f$s_i\f$ value that is more that some target and
      76             : so on.  Notice also that you can rotate the reference frame if you are using a non-standard unit cell.
      77             : 
      78             : \par Examples
      79             : 
      80             : The following input calculates the FCCUBIC parameter for the 64 atoms in the system
      81             : and then calculates and prints the average value for this quantity.
      82             : 
      83             : \plumedfile
      84             : FCCUBIC SPECIES=1-64 SWITCH={RATIONAL D_0=3.0 R_0=1.5} MEAN LABEL=d
      85             : PRINT ARG=d.* FILE=colv
      86             : \endplumedfile
      87             : 
      88             : */
      89             : //+ENDPLUMEDOC
      90             : 
      91             : 
      92          40 : class Fccubic : public function::FunctionTemplateBase {
      93             : private:
      94             :   double alpha, a1, b1;
      95             : public:
      96             :   void registerKeywords( Keywords& keys ) override;
      97             :   void read( ActionWithArguments* action ) override;
      98             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
      99             : };
     100             : 
     101             : typedef function::FunctionShortcut<Fccubic> FccubicShortcut;
     102             : PLUMED_REGISTER_ACTION(FccubicShortcut,"FCCUBIC_FUNC")
     103             : typedef function::FunctionOfMatrix<Fccubic> MatrixFccubic;
     104             : PLUMED_REGISTER_ACTION(MatrixFccubic,"FCCUBIC_FUNC_MATRIX")
     105             : 
     106          28 : void Fccubic::registerKeywords( Keywords& keys ) {
     107          56 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function");
     108          28 :   keys.setValueDescription("a function that measures the similarity with an fcc environment");
     109          28 : }
     110             : 
     111           6 : void Fccubic::read( ActionWithArguments* action ) {
     112             :   // Scaling factors such that '1' corresponds to fcc lattice
     113             :   // and '0' corresponds to isotropic (liquid)
     114           6 :   parse(action,"ALPHA",alpha);
     115           6 :   a1 = 80080. / (2717. + 16*alpha); b1 = 16.*(alpha-143)/(2717+16*alpha);
     116           6 :   action->log.printf("  setting alpha paramter equal to %f \n",alpha);
     117           6 : }
     118             : 
     119     2486314 : void Fccubic::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
     120     2486314 :   double x2 = args[0]*args[0];
     121     2486314 :   double x4 = x2*x2;
     122             : 
     123     2486314 :   double y2 = args[1]*args[1];
     124     2486314 :   double y4 = y2*y2;
     125             : 
     126     2486314 :   double z2 = args[2]*args[2];
     127     2486314 :   double z4 = z2*z2;
     128             : 
     129     2486314 :   double d2 = x2 + y2 + z2;
     130     2486314 :   double r8 = pow( d2, 4 );
     131     2486314 :   double r12 = pow( d2, 6 );
     132             : 
     133     2486314 :   double tmp = ((x4*y4)+(x4*z4)+(y4*z4))/r8-alpha*x4*y4*z4/r12;
     134             : 
     135     2486314 :   double t0 = (x2*y4+x2*z4)/r8-alpha*x2*y4*z4/r12;
     136     2486314 :   double t1 = (y2*x4+y2*z4)/r8-alpha*y2*x4*z4/r12;
     137     2486314 :   double t2 = (z2*x4+z2*y4)/r8-alpha*z2*x4*y4/r12;
     138     2486314 :   double t3 = (2*tmp-alpha*x4*y4*z4/r12)/d2;
     139             : 
     140     2486314 :   derivatives(0,0)=4*a1*args[0]*(t0-t3);
     141     2486314 :   derivatives(0,1)=4*a1*args[1]*(t1-t3);
     142     2486314 :   derivatives(0,2)=4*a1*args[2]*(t2-t3);
     143             : 
     144             :   // Set the value and the derivatives
     145     2486314 :   vals[0] = (a1*tmp+b1);
     146     2486314 : }
     147             : 
     148             : }
     149             : }
     150             : 

Generated by: LCOV version 1.16