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

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2013-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_VolumeAround_h
      23             : #define __PLUMED_volumes_VolumeAround_h
      24             : #include "tools/Pbc.h"
      25             : #include "tools/HistogramBead.h"
      26             : #include "ActionVolume.h"
      27             : 
      28             : 
      29             : namespace PLMD {
      30             : namespace volumes {
      31             : 
      32          98 : class VolumeAround {
      33             : public:
      34             :   using precision=double;
      35             :   typedef VolumeIn<precision> VolumeInput;
      36             :   typedef VolumeOut<precision> VolumeOutput;
      37             :   bool dox{true}, doy{true}, doz{true};
      38             :   double sigma;
      39             :   double xlow{0.0}, xhigh{0.0};
      40             :   double ylow{0.0}, yhigh{0.0};
      41             :   double zlow{0.0}, zhigh{0.0};
      42             :   HistogramBead::KernelType kerneltype;
      43             :   static void registerKeywords( Keywords& keys );
      44             :   template<typename TPM>
      45             :   void parseInput( ActionVolume<VolumeAround, TPM>* action );
      46             :   template<typename TPM>
      47             :   void setupRegions( ActionVolume<VolumeAround, TPM>* action,
      48             :                      const Pbc& pbc,
      49             :                      const std::vector<Vector>& positions ) {}
      50             :   template<typename TPM>
      51             :   static void parseAtoms( ActionVolume<VolumeAround, TPM>* action,
      52             :                           std::vector<AtomNumber>& atom );
      53             :   static void calculateNumberInside( const VolumeInput& input,
      54             :                                      const VolumeAround& actioninput,
      55             :                                      VolumeOutput& output );
      56             : #ifdef __PLUMED_HAS_OPENACC
      57             :   void toACCDevice() const {
      58             : #pragma acc enter data copyin(this[0:1],dox,doy,doz,sigma,\
      59             :   xlow,xhigh,ylow,yhigh,zlow,zhigh,kerneltype)
      60             :   }
      61             :   void removeFromACCDevice() const {
      62             : #pragma acc exit data delete(kerneltype,zhigh,zlow,yhigh,ylow,xhigh,xlow,\
      63             :   sigma,doz,doy,dox,this[0:1])
      64             :   }
      65             : #endif //__PLUMED_HAS_OPENACC
      66             : };
      67             : 
      68         169 : void VolumeAround::registerKeywords( Keywords& keys ) {
      69         338 :   keys.setDisplayName("AROUND");
      70         169 :   keys.add("atoms","ORIGIN","the atom whose vicinity we are interested in examining");
      71         169 :   keys.addDeprecatedKeyword("ATOM","ORIGIN");
      72         169 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
      73         169 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
      74         169 :   keys.add("compulsory","XLOWER","0.0","the lower boundary in x relative to the x coordinate of the atom (0 indicates use full extent of box).");
      75         169 :   keys.add("compulsory","XUPPER","0.0","the upper boundary in x relative to the x coordinate of the atom (0 indicates use full extent of box).");
      76         169 :   keys.add("compulsory","YLOWER","0.0","the lower boundary in y relative to the y coordinate of the atom (0 indicates use full extent of box).");
      77         169 :   keys.add("compulsory","YUPPER","0.0","the upper boundary in y relative to the y coordinate of the atom (0 indicates use full extent of box).");
      78         169 :   keys.add("compulsory","ZLOWER","0.0","the lower boundary in z relative to the z coordinate of the atom (0 indicates use full extent of box).");
      79         169 :   keys.add("compulsory","ZUPPER","0.0","the upper boundary in z relative to the z coordinate of the atom (0 indicates use full extent of box).");
      80         169 : }
      81             : 
      82             : template<typename TPM>
      83          49 : void VolumeAround::parseAtoms( ActionVolume<VolumeAround, TPM>* action, std::vector<AtomNumber>& atom ) {
      84          98 :   action->parseAtomList("ORIGIN",atom);
      85          49 :   if( atom.size()==0 ) {
      86           0 :     action->parseAtomList("ATOM",atom);
      87             :   }
      88          49 :   if( atom.size()!=1 ) {
      89           0 :     action->error("should only be one atom specified");
      90             :   }
      91          49 :   action->log.printf("  boundaries for region are calculated based on positions of atom : %d\n",atom[0].serial() );
      92          49 : }
      93             : 
      94             : template<typename TPM>
      95          49 : void VolumeAround::parseInput( ActionVolume<VolumeAround, TPM>* action ) {
      96          98 :   action->parse("SIGMA",sigma);
      97             :   std::string mykerneltype;
      98          49 :   action->parse("KERNEL",mykerneltype);
      99          49 :   kerneltype=HistogramBead::getKernelType(mykerneltype);
     100          49 :   dox=true;
     101          49 :   action->parse("XLOWER",xlow);
     102          49 :   action->parse("XUPPER",xhigh);
     103          49 :   doy=true;
     104          49 :   action->parse("YLOWER",ylow);
     105          49 :   action->parse("YUPPER",yhigh);
     106          49 :   doz=true;
     107          49 :   action->parse("ZLOWER",zlow);
     108          49 :   action->parse("ZUPPER",zhigh);
     109          49 :   if( xlow==0.0 && xhigh==0.0 ) {
     110           8 :     dox=false;
     111             :   }
     112          49 :   if( ylow==0.0 && yhigh==0.0 ) {
     113          16 :     doy=false;
     114             :   }
     115          49 :   if( zlow==0.0 && zhigh==0.0 ) {
     116          16 :     doz=false;
     117             :   }
     118          49 :   if( !dox && !doy && !doz ) {
     119           0 :     action->error("no subregion defined use XLOWER, XUPPER, YLOWER, YUPPER, ZLOWER, ZUPPER");
     120             :   }
     121          49 :   action->log.printf("  boundaries for region (region of interest about atom) : x %f %f, y %f %f, z %f %f \n",xlow,xhigh,ylow,yhigh,zlow,zhigh);
     122          49 : }
     123             : 
     124      140716 : void VolumeAround::calculateNumberInside( const VolumeInput& input,
     125             :     const VolumeAround& actioninput,
     126             :     VolumeOutput& output ) {
     127             :   // Setup the histogram bead
     128      140716 :   HistogramBead bead(actioninput.kerneltype, actioninput.xlow, actioninput.xhigh, actioninput.sigma );
     129             : 
     130             :   // Calculate position of atom wrt to origin
     131      140716 :   Vector fpos=input.pbc.distance( Vector(input.refpos[0][0],input.refpos[0][1],input.refpos[0][2]),
     132      140716 :                                   Vector(input.cpos[0],input.cpos[1],input.cpos[2]) );
     133             :   double xcontr=1.0;
     134      140716 :   double xder=0.0;
     135      140716 :   if( actioninput.dox ) {
     136             :     //bead parameters set in the constructor
     137       96716 :     xcontr=bead.calculate( fpos[0], xder );
     138             :   }
     139             :   double ycontr=1.0;
     140      140716 :   double yder=0.0;
     141      140716 :   if( actioninput.doy ) {
     142       92288 :     bead.set( actioninput.ylow, actioninput.yhigh, actioninput.sigma );
     143       92288 :     ycontr=bead.calculate( fpos[1], yder );
     144             :   }
     145             :   double zcontr=1.0;
     146      140716 :   double zder=0.0;
     147      140716 :   if( actioninput.doz ) {
     148       92288 :     bead.set( actioninput.zlow, actioninput.zhigh, actioninput.sigma );
     149       92288 :     zcontr=bead.calculate( fpos[2], zder );
     150             :   }
     151             : 
     152      140716 :   output.derivatives[0]=xder*ycontr*zcontr;
     153      140716 :   output.derivatives[1]=xcontr*yder*zcontr;
     154      140716 :   output.derivatives[2]=xcontr*ycontr*zder;
     155             :   // Add derivatives wrt to position of origin atom
     156      140716 :   output.refders[0][0] = -output.derivatives[0];
     157      140716 :   output.refders[0][1] = -output.derivatives[1];
     158      140716 :   output.refders[0][2] = -output.derivatives[2];
     159             :   // Add virial contribution
     160      140716 :   output.virial.set( 0, -Tensor(fpos,
     161      140716 :                                 Vector(output.derivatives[0], output.derivatives[1], output.derivatives[2])) );
     162      140716 :   output.values[0] = xcontr*ycontr*zcontr;
     163      140716 : }
     164             : 
     165             : }
     166             : }
     167             : #endif //__PLUMED_volumes_VolumeAround_h 

Generated by: LCOV version 1.16