Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2018 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 "core/ActionRegister.h" 23 : #include "core/ActionShortcut.h" 24 : #include "CoordinationNumbers.h" 25 : #include "multicolvar/MultiColvarShortcuts.h" 26 : 27 : //+PLUMEDOC MCOLVAR TETRA_ANGULAR 28 : /* 29 : Calculate the angular tetra CV 30 : 31 : This shortcut calculates a [symmetry function](https://www.plumed-tutorials.org/lessons/23/001/data/SymmetryFunction.html). The particular function that is being 32 : evaluated for the coordination sphere here is as follows: 33 : 34 : $$ 35 : s_i = 1 - \frac{3}{8}\sum_{j=2}^4 \sum_{k=1}^{j-1} \left( \cos(\theta_{jik} + \frac{1}{2} \right)^2 36 : $$ 37 : 38 : In this expression the 4 atoms in the sums over $j$ and $k$ are the four atoms that are nearest to atom $i$. $\theta_{jik}$ is the angle between the vectors connecting 39 : atoms $i$ and $j$ and the vector connecting atoms $i$ and $k$. The CV is large if the four atoms nearest atom $i$ are arranged on the vertices of a regular tetrahedron 40 : and small otherwise. The following example shows how you can use this action to measure the degree of tetrahedral order in a system. 41 : 42 : ```plumed 43 : # Calculate a vector that contains 64 values for the symmetry function. 44 : # Sum the elements of the vector and calculate the mean value on the atoms from this sum. 45 : acv: TETRA_ANGULAR SPECIES=1-64 SUM MEAN 46 : # Print out the positions of the 64 atoms for which the symmetry function was calculated 47 : # to an xyz file along with the values of the symmetry function 48 : DUMPATOMS ATOMS=1-64 ARG=acv FILE=mcolv.xyz 49 : # Print out the average value of the symmetry function and the sum of all the symmetry functions 50 : PRINT ARG=acv_sum,acv_mean FILE=colvar 51 : ``` 52 : 53 : */ 54 : //+ENDPLUMEDOC 55 : 56 : namespace PLMD { 57 : namespace symfunc { 58 : 59 : class AngularTetra : public ActionShortcut { 60 : public: 61 : static void registerKeywords( Keywords& keys ); 62 : explicit AngularTetra(const ActionOptions&ao); 63 : }; 64 : 65 : PLUMED_REGISTER_ACTION(AngularTetra,"TETRA_ANGULAR") 66 : 67 3 : void AngularTetra::registerKeywords( Keywords& keys ) { 68 3 : CoordinationNumbers::shortcutKeywords( keys ); 69 3 : keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances"); 70 3 : keys.add("compulsory","CUTOFF","-1","ignore distances that have a value larger than this cutoff"); 71 6 : keys.setValueDescription("vector","the value of the angular tetehedrality parameter for each of the input atoms"); 72 3 : keys.remove("NN"); 73 3 : keys.remove("MM"); 74 3 : keys.remove("D_0"); 75 3 : keys.remove("R_0"); 76 3 : keys.remove("SWITCH"); 77 3 : keys.needsAction("DISTANCE_MATRIX"); 78 3 : keys.needsAction("NEIGHBORS"); 79 3 : keys.needsAction("GSYMFUNC_THREEBODY"); 80 3 : keys.needsAction("CUSTOM"); 81 3 : } 82 : 83 1 : AngularTetra::AngularTetra( const ActionOptions& ao): 84 : Action(ao), 85 1 : ActionShortcut(ao) { 86 : bool nopbc; 87 1 : parseFlag("NOPBC",nopbc); 88 1 : std::string pbcstr=""; 89 1 : if( nopbc ) { 90 : pbcstr = " NOPBC"; 91 : } 92 : // Read species input and create the matrix 93 : std::string sp_str, rcut; 94 1 : parse("SPECIES",sp_str); 95 2 : parse("CUTOFF",rcut); 96 1 : if( sp_str.length()>0 ) { 97 2 : readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX COMPONENTS GROUP=" + sp_str + " CUTOFF=" + rcut + pbcstr ); 98 : } else { 99 : std::string specA, specB; 100 0 : parse("SPECIESA",specA); 101 0 : parse("SPECIESB",specB); 102 0 : if( specA.length()==0 ) { 103 0 : error("missing input atoms"); 104 : } 105 0 : if( specB.length()==0 ) { 106 0 : error("missing SPECIESB keyword"); 107 : } 108 0 : readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX COMPONENTS GROUPA=" + specA + " GROUPB=" + specB + " CUTOFF=" + rcut + pbcstr ); 109 : } 110 : // Get the neighbors matrix 111 2 : readInputLine( getShortcutLabel() + "_neigh: NEIGHBORS ARG=" + getShortcutLabel() + "_mat.w NLOWEST=4"); 112 : // Now construct the symmetry function (sum of cos(a) + 1/3) 113 3 : readInputLine( getShortcutLabel() + "_g8: GSYMFUNC_THREEBODY WEIGHT=" + getShortcutLabel() + "_neigh " + 114 3 : "ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.z FUNCTION1={FUNC=(cos(ajik)+1/3)^2 LABEL=g8}"); 115 : // Now evaluate the actual per atom CV 116 2 : readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_g8.g8 FUNC=(1-(3*x/8)) PERIODIC=NO"); 117 : // And get the things to do with the quantities we have computed 118 : std::map<std::string,std::string> keymap; 119 1 : multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this ); 120 2 : multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", keymap, this ); 121 1 : } 122 : 123 : } 124 : }