LCOV - code coverage report
Current view: top level - volumes - VolumeInSphere.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 30 34 88.2 %
Date: 2026-11-05 10:19:04 Functions: 4 4 100.0 %

          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

Generated by: LCOV version 1.16