LCOV - code coverage report
Current view: top level - colvar - Plane.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 89 92 96.7 %
Date: 2026-11-05 10:19:04 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2023 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_colvar_Plane_h
      23             : #define __PLUMED_colvar_Plane_h
      24             : #include "Colvar.h"
      25             : #include "ColvarInput.h"
      26             : #include "tools/Pbc.h"
      27             : 
      28             : #include <string>
      29             : #include <cmath>
      30             : 
      31             : namespace PLMD {
      32             : namespace colvar {
      33             : 
      34             : template <typename T>
      35             : class Plane : public Colvar {
      36             : private:
      37             :   bool pbc;
      38             :   std::vector<double> value;
      39             :   std::vector<double> derivs;
      40             : public:
      41             :   using precision=T;
      42             :   static void registerKeywords( Keywords& keys );
      43             :   explicit Plane(const ActionOptions&);
      44             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
      45             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
      46             : // active methods:
      47             :   void calculate() override;
      48             :   static void calculateCV( const ColvarInput<T>& cvin, ColvarOutput<T>& cvout );
      49             : };
      50             : 
      51             : template <typename T>
      52          31 : void Plane<T>::registerKeywords( Keywords& keys ) {
      53          31 :   Colvar::registerKeywords( keys );
      54          62 :   keys.setDisplayName("PLANE");
      55          31 :   keys.add("atoms","ATOMS","the three or four atoms whose plane we are computing");
      56          62 :   keys.addOutputComponent("x","default","scalar/vector","the x-component of the vector that is normal to the plane containing the atoms");
      57          62 :   keys.addOutputComponent("y","default","scalar/vector","the y-component of the vector that is normal to the plane containing the atoms");
      58          62 :   keys.addOutputComponent("z","default","scalar/vector","the z-component of the vector that is normal to the plane containing the atoms");
      59          31 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
      60          62 :   keys.reset_style("NUMERICAL_DERIVATIVES","hidden");
      61          31 : }
      62             : 
      63             : template <typename T>
      64          17 : void Plane<T>::parseAtomList( const int& num, std::vector<AtomNumber>& atoms, ActionAtomistic* aa ) {
      65          34 :   aa->parseAtomList("ATOMS",num,atoms);
      66          17 :   if(atoms.size()==3) {
      67          14 :     aa->log.printf("  containing atoms %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial());
      68          14 :     atoms.resize(4);
      69          14 :     atoms[3]=atoms[2];
      70          14 :     atoms[2]=atoms[1];
      71           3 :   } else if(atoms.size()==4) {
      72           0 :     aa->log.printf("  containing lines %d-%d and %d-%d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
      73           3 :   } else if( num<0 || atoms.size()>0 ) {
      74           0 :     aa->error("Number of specified atoms should be either 3 or 4");
      75             :   }
      76          17 : }
      77             : 
      78             : template <typename T>
      79           5 : unsigned Plane<T>::getModeAndSetupValues( ActionWithValue* av ) {
      80          10 :   av->addComponentWithDerivatives("x");
      81           5 :   av->componentIsNotPeriodic("x");
      82          10 :   av->addComponentWithDerivatives("y");
      83           5 :   av->componentIsNotPeriodic("y");
      84          10 :   av->addComponentWithDerivatives("z");
      85           5 :   av->componentIsNotPeriodic("z");
      86           5 :   return 0;
      87             : }
      88             : 
      89             : template <typename T>
      90           2 : Plane<T>::Plane(const ActionOptions&ao):
      91             :   PLUMED_COLVAR_INIT(ao),
      92           2 :   pbc(true),
      93           2 :   value(3) {
      94           2 :   std::vector<AtomNumber> atoms;
      95           2 :   parseAtomList(-1,atoms,this);
      96           2 :   bool nopbc=!pbc;
      97           2 :   parseFlag("NOPBC",nopbc);
      98           2 :   pbc=!nopbc;
      99             : 
     100           2 :   if(pbc) {
     101           2 :     log.printf("  using periodic boundary conditions\n");
     102             :   } else {
     103           0 :     log.printf("  without periodic boundary conditions\n");
     104             :   }
     105             : 
     106           2 :   /*auto mode =*/ getModeAndSetupValues( this );
     107           2 :   requestAtoms(atoms);
     108           2 :   checkRead();
     109           2 : }
     110             : 
     111             : template <typename T>
     112         115 : void Plane<T>::calculate() {
     113             : 
     114         115 :   if(pbc) {
     115         115 :     makeWhole();
     116             :   }
     117         115 :   auto cvout = ColvarOutput<double>::createColvarOutput(value,derivs,this);
     118         115 :   Plane<double>::calculateCV( ColvarInput<double>::createColvarInput( 0, getPositions(), this ), cvout );
     119         115 :   Value* valuex=getPntrToComponent("x");
     120         115 :   Value* valuey=getPntrToComponent("y");
     121         115 :   Value* valuez=getPntrToComponent("z");
     122             : 
     123         575 :   for(unsigned i=0; i<getPositions().size(); ++i) {
     124         460 :     setAtomsDerivatives( valuex, i, cvout.getAtomDerivatives(0,i) );
     125             :   }
     126         115 :   setBoxDerivatives( valuex, cvout.virial[0] );
     127         115 :   valuex->set( value[0] );
     128             : 
     129         575 :   for(unsigned i=0; i<getPositions().size(); ++i) {
     130         460 :     setAtomsDerivatives( valuey, i, cvout.getAtomDerivatives(1,i) );
     131             :   }
     132         115 :   setBoxDerivatives( valuey, cvout.virial[1] );
     133         115 :   valuey->set( value[1] );
     134             : 
     135         575 :   for(unsigned i=0; i<getPositions().size(); ++i) {
     136         460 :     setAtomsDerivatives( valuez, i, cvout.getAtomDerivatives(2,i) );
     137             :   }
     138         115 :   setBoxDerivatives( valuez, cvout.virial[2] );
     139         115 :   valuez->set( value[2] );
     140         115 : }
     141             : 
     142             : template <typename T>
     143         301 : void Plane<T>::calculateCV( const ColvarInput<T>& cvin, ColvarOutput<T>& cvout ) {
     144         301 :   const auto d1=delta( cvin.pos[1], cvin.pos[0] );
     145         301 :   const auto d2=delta( cvin.pos[2], cvin.pos[3] );
     146         301 :   const auto cp = crossProduct( d1, d2 );
     147             :   using T33 = TensorTyped<T,3,3>;
     148         301 :   cvout.derivs[0][0] = crossProduct( Versors::xm<T>, d2 );
     149         301 :   cvout.derivs[0][1] = crossProduct( Versors::xp<T>, d2 );
     150         301 :   cvout.derivs[0][2] = crossProduct( Versors::xm<T>, d1 );
     151         301 :   cvout.derivs[0][3] = crossProduct( Versors::xp<T>, d1 );
     152         602 :   cvout.virial.set( 0, T33(d1,crossProduct(Versors::xp<T>, d2))
     153         301 :                     + T33(d2, crossProduct(Versors::xm<T>, d1)));
     154         301 :   cvout.values[0] = cp[0];
     155             : 
     156         301 :   cvout.derivs[1][0] = crossProduct( Versors::ym<T>, d2 );
     157         301 :   cvout.derivs[1][1] = crossProduct( Versors::yp<T>, d2 );
     158         301 :   cvout.derivs[1][2] = crossProduct( Versors::ym<T>, d1 );
     159         301 :   cvout.derivs[1][3] = crossProduct( Versors::yp<T>, d1 );
     160         602 :   cvout.virial.set(1, T33(d1,crossProduct(Versors::yp<T>, d2))
     161         301 :                    + T33(d2, crossProduct(Versors::ym<T>, d1)));
     162         301 :   cvout.values[1] = cp[1];
     163             : 
     164         301 :   cvout.derivs[2][0] = crossProduct( Versors::zm<T>, d2 );
     165         301 :   cvout.derivs[2][1] = crossProduct( Versors::zp<T>, d2 );
     166         301 :   cvout.derivs[2][2] = crossProduct( Versors::zm<T>, d1 );
     167         301 :   cvout.derivs[2][3] = crossProduct( Versors::zp<T>, d1 );
     168         602 :   cvout.virial.set(2, T33(d1,crossProduct(Versors::zp<T>, d2))
     169         301 :                    + T33(d2, crossProduct(Versors::zm<T>, d1)));
     170         301 :   cvout.values[2] = cp[2];
     171         301 : }
     172             : 
     173             : }
     174             : }
     175             : 
     176             : #endif // __PLUMED_colvar_Plane_h

Generated by: LCOV version 1.16