LCOV - code coverage report
Current view: top level - symfunc - Fccubic.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 31 31 100.0 %
Date: 2025-04-08 18:07:56 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 shortcut is an example of a [COORDINATION_SHELL_AVERAGE](COORDINATION_SHELL_AVERAGE.md),
      56             : which we can use to measure how similar the environment around atom $i$ is to an fcc structure.
      57             : The function that is used to make this determination is as follows:
      58             : 
      59             : $$
      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             : $$
      62             : 
      63             : 
      64             : In this expression $x_{ij}$, $y_{ij}$ and $z_{ij}$ are the $x$, $y$ and $z$ components of the vector connecting atom $i$ to
      65             : atom $j$ and $r_{ij}$ is the magnitude of this vector.  $\sigma(r_{ij})$ is a switching function that acts on the distance between
      66             : atom $i$ and atom $j$ and its inclusion in the numerator and the denominator of the above expression as well as the fact that we are summing
      67             : over all of the other atoms in the system ensures that we are calculating an average
      68             : of the function of $x_{ij}$, $y_{ij}$ and $z_{ij}$ for the atoms in the first coordination sphere around atom $i$.  Lastly, $\alpha$
      69             : is a parameter that can be set by the user, which by default is equal to three.  The values of $a$ and $b$ are calculated from $\alpha$ using:
      70             : 
      71             : $$
      72             : a = \frac{ 80080}{ 2717 + 16 \alpha} \qquad \textrm{and} \qquad b = \frac{ 16(\alpha - 143) }{2717 + 16\alpha}
      73             : $$
      74             : 
      75             : This action was been used in all the articles in the bibliography. We thus wrote an explict
      76             : action to calculate it in PLUMED instead of using a shortcut as we did for [SIMPLECUBIC](SIMPLECUBIC.md) so that we could get
      77             : good computational performance.
      78             : 
      79             : The following input calculates the FCCUBIC parameter for the 64 atoms in the system
      80             : and then calculates and prints the average value for this quantity.
      81             : 
      82             : ```plumed
      83             : d: FCCUBIC SPECIES=1-64 SWITCH={RATIONAL D_0=3.0 R_0=1.5} MEAN
      84             : PRINT ARG=d.* FILE=colv
      85             : ```
      86             : 
      87             : Notice that you can you can rotate the bond vectors before computing the
      88             : function in the above expression as is discussed in the documentation for [COORDINATION_SHELL_FUNCTION](COORDINATION_SHELL_FUNCTION.md)
      89             : 
      90             : */
      91             : //+ENDPLUMEDOC
      92             : 
      93             : 
      94          40 : class Fccubic : public function::FunctionTemplateBase {
      95             : private:
      96             :   double alpha, a1, b1;
      97             : public:
      98             :   void registerKeywords( Keywords& keys ) override;
      99             :   void read( ActionWithArguments* action ) override;
     100             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
     101             : };
     102             : 
     103             : typedef function::FunctionShortcut<Fccubic> FccubicShortcut;
     104             : PLUMED_REGISTER_ACTION(FccubicShortcut,"FCCUBIC_FUNC")
     105             : typedef function::FunctionOfMatrix<Fccubic> MatrixFccubic;
     106             : PLUMED_REGISTER_ACTION(MatrixFccubic,"FCCUBIC_FUNC_MATRIX")
     107             : 
     108          28 : void Fccubic::registerKeywords( Keywords& keys ) {
     109          28 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function");
     110          56 :   keys.setValueDescription("matrix","a function that measures the similarity with an fcc environment");
     111          28 : }
     112             : 
     113           6 : void Fccubic::read( ActionWithArguments* action ) {
     114             :   // Scaling factors such that '1' corresponds to fcc lattice
     115             :   // and '0' corresponds to isotropic (liquid)
     116           6 :   parse(action,"ALPHA",alpha);
     117           6 :   a1 = 80080. / (2717. + 16*alpha);
     118           6 :   b1 = 16.*(alpha-143)/(2717+16*alpha);
     119           6 :   action->log.printf("  setting alpha paramter equal to %f \n",alpha);
     120           6 : }
     121             : 
     122     2486314 : void Fccubic::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
     123     2486314 :   double x2 = args[0]*args[0];
     124     2486314 :   double x4 = x2*x2;
     125             : 
     126     2486314 :   double y2 = args[1]*args[1];
     127     2486314 :   double y4 = y2*y2;
     128             : 
     129     2486314 :   double z2 = args[2]*args[2];
     130     2486314 :   double z4 = z2*z2;
     131             : 
     132     2486314 :   double d2 = x2 + y2 + z2;
     133     2486314 :   double r8 = pow( d2, 4 );
     134     2486314 :   double r12 = pow( d2, 6 );
     135             : 
     136     2486314 :   double tmp = ((x4*y4)+(x4*z4)+(y4*z4))/r8-alpha*x4*y4*z4/r12;
     137             : 
     138     2486314 :   double t0 = (x2*y4+x2*z4)/r8-alpha*x2*y4*z4/r12;
     139     2486314 :   double t1 = (y2*x4+y2*z4)/r8-alpha*y2*x4*z4/r12;
     140     2486314 :   double t2 = (z2*x4+z2*y4)/r8-alpha*z2*x4*y4/r12;
     141     2486314 :   double t3 = (2*tmp-alpha*x4*y4*z4/r12)/d2;
     142             : 
     143     2486314 :   derivatives(0,0)=4*a1*args[0]*(t0-t3);
     144     2486314 :   derivatives(0,1)=4*a1*args[1]*(t1-t3);
     145     2486314 :   derivatives(0,2)=4*a1*args[2]*(t2-t3);
     146             : 
     147             :   // Set the value and the derivatives
     148     2486314 :   vals[0] = (a1*tmp+b1);
     149     2486314 : }
     150             : 
     151             : }
     152             : }
     153             : 

Generated by: LCOV version 1.16