Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-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 : #ifndef __PLUMED_volumes_VolumeInSphere_h 23 : #define __PLUMED_volumes_VolumeInSphere_h 24 : #include "tools/Pbc.h" 25 : #include "tools/SwitchingFunction.h" 26 : #include "ActionVolume.h" 27 : 28 : namespace PLMD { 29 : namespace volumes { 30 : 31 60 : struct VolumeInSphere { 32 : using precision=double; 33 : typedef VolumeIn<precision> VolumeInput; 34 : typedef VolumeOut<precision> VolumeOutput; 35 : #ifdef __PLUMED_HAS_OPENACC 36 : SwitchingFunctionAccelerable switchingFunction; 37 : #else 38 : SwitchingFunction switchingFunction; 39 : #endif //__PLUMED_HAS_OPENACC 40 : static void registerKeywords( Keywords& keys ); 41 : template<typename TPM> 42 : void parseInput( ActionVolume<VolumeInSphere, TPM>* action ); 43 : template<typename TPM> 44 : void setupRegions( ActionVolume<VolumeInSphere, TPM>* action, 45 : const Pbc& pbc, 46 : const std::vector<Vector>& positions ) {} 47 : template<typename TPM> 48 : static void parseAtoms( ActionVolume<VolumeInSphere, TPM>* action, 49 : std::vector<AtomNumber>& atom ); 50 : static void calculateNumberInside( const VolumeInput& input, 51 : const VolumeInSphere& actioninput, 52 : VolumeOutput& output ); 53 : #ifdef __PLUMED_HAS_OPENACC 54 : void toACCDevice() const { 55 : #pragma acc enter data copyin(this[0:1]) 56 : switchingFunction.toACCDevice(); 57 : } 58 : void removeFromACCDevice() const { 59 : switchingFunction.removeFromACCDevice(); 60 : #pragma acc exit data delete(this[0:1]) 61 : } 62 : #endif //__PLUMED_HAS_OPENACC 63 : }; 64 : 65 55 : void VolumeInSphere::registerKeywords( Keywords& keys ) { 66 110 : keys.setDisplayName("INSPHERE"); 67 55 : keys.add("atoms","CENTER","the atom whose vicinity we are interested in examining"); 68 55 : keys.addDeprecatedKeyword("ATOM","CENTER"); 69 55 : keys.add("compulsory","RADIUS","the switching function that tells us the extent of the sphereical region of interest"); 70 110 : keys.linkActionInDocs("RADIUS","LESS_THAN"); 71 55 : } 72 : 73 : template<typename TPM> 74 15 : void VolumeInSphere::parseInput( ActionVolume<VolumeInSphere, TPM>* action ) { 75 : std::string errors; 76 : std::string swinput; 77 30 : action->parse("RADIUS",swinput); 78 15 : if(swinput.length()==0) { 79 0 : action->error("missing RADIUS keyword"); 80 : } 81 : 82 15 : switchingFunction.set(swinput,errors); 83 15 : if( errors.length()!=0 ) { 84 0 : action->error("problem reading RADIUS keyword : " + errors ); 85 : } 86 : 87 30 : action->log.printf(" radius of sphere is given by %s \n", 88 : switchingFunction.description().c_str() ); 89 15 : } 90 : 91 : template<typename TPM> 92 15 : void VolumeInSphere::parseAtoms( ActionVolume<VolumeInSphere, TPM>* action, 93 : std::vector<AtomNumber>& atom ) { 94 30 : action->parseAtomList("CENTER",atom); 95 15 : if( atom.size()==0 ) { 96 0 : action->parseAtomList("ATOM",atom); 97 : } 98 15 : if( atom.size()!=1 ) { 99 0 : action->error("should only be one atom specified"); 100 : } 101 15 : action->log.printf(" center of sphere is at position of atom : %d\n",atom[0].serial() ); 102 15 : } 103 : 104 946046 : void VolumeInSphere::calculateNumberInside( const VolumeInput& input, 105 : const VolumeInSphere& actioninput, 106 : VolumeOutput& output ) { 107 : // Calculate position of atom wrt to origin 108 946046 : Vector fpos=input.pbc.distance( Vector(input.refpos[0][0],input.refpos[0][1],input.refpos[0][2]), Vector(input.cpos[0],input.cpos[1],input.cpos[2]) ); 109 : double dfunc; 110 946046 : output.values[0] = actioninput.switchingFunction.calculateSqr( fpos.modulo2(), dfunc ); 111 946046 : output.derivatives = dfunc*fpos; 112 946046 : output.refders[0][0] = -output.derivatives[0]; 113 946046 : output.refders[0][1] = -output.derivatives[1]; 114 946046 : output.refders[0][2] = -output.derivatives[2]; 115 : // Add a virial contribution 116 1892092 : output.virial.set( 0, -Tensor(fpos,Vector(output.derivatives[0], output.derivatives[1], output.derivatives[2])) ); 117 946046 : } 118 : 119 : } 120 : } 121 : #endif //__PLUMED_volumes_VolumeInSphere_h