LCOV - code coverage report
Current view: top level - wrapper - Plumed.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 6 6 100.0 %
Date: 2020-11-18 11:20:57 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2019 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_wrapper_Plumed_h
      23             : #define __PLUMED_wrapper_Plumed_h
      24             : 
      25             : /**
      26             : \page ReferencePlumedH Reference for interfacing MD codes with PLUMED
      27             : 
      28             :   Plumed.h and Plumed.c contain the external plumed interface, which is used to
      29             :   integrate it with MD engines. This interface is very general, and is expected
      30             :   not to change across plumed versions. Plumed.c also implements a dummy version
      31             :   of the interface, so as to allow a code to be fully linked even if the plumed
      32             :   library is not available yet. These files could be directly included in the official
      33             :   host MD distribution. In this manner, it will be sufficient to link the plumed
      34             :   library at link time (on all systems) or directly at runtime (on system where
      35             :   dynamic loading is enabled) to include plumed features.
      36             : 
      37             :   Why is Plumed.c written in C and not C++? The reason is that the resulting Plumed.o
      38             :   needs to be linked with the host MD code immediately (whereas the rest of plumed
      39             :   could be linked a posteriori). Imagine the MD code is written in FORTRAN: when we
      40             :   link the Plumed.o file we would like not to need any C++ library linked. In this
      41             :   manner, we do not need to know which C++ compiler will be used to compile plumed.
      42             :   The C++ library is only linked to the "rest" of plumed, which actually use it.
      43             :   Anyway, Plumed.c is written in such a manner to allow its compilation also in C++
      44             :   (C++ is a bit stricter than C; compatibility is checked when PlumedStatic.cpp,
      45             :   which basically includes Plumed.c, is compiled with the C++ compiler). This will
      46             :   allow e.g. MD codes written in C++ to just incorporate Plumed.c (maybe renamed into
      47             :   Plumed.cpp), without the need of configuring a plain C compiler.
      48             : 
      49             :   Plumed interface can be used from C, C++ and FORTRAN. Everything concerning plumed
      50             :   is hidden inside a single object type, which is described in C by a structure
      51             :   (struct \ref plumed), in C++ by a class (PLMD::Plumed) and in FORTRAN by a
      52             :   fixed-length string (CHARACTER(LEN=32)). Obviously C++ can use both struct
      53             :   and class interfaces, but the first should be preferred. The reference interface
      54             :   is the C one, whereas FORTRAN and C++ interfaces are implemented as wrappers
      55             :   around it.
      56             : 
      57             :   In the C++ interface, all the routines are implemented as methods of PLMD::Plumed.
      58             :   In the C and FORTRAN interfaces, all the routines are named plumed_*, to
      59             :   avoid potential name clashes. Notice that the entire plumed library
      60             :   is implemented in C++, and it is hidden inside the PLMD namespace.
      61             :   If the used C++ compiler supports C++11, PLMD::Plumed object defines move semantics
      62             :   so as to be usable in STL containers. That is, you can declare a std::vector<PLMD::Plumed>.
      63             : 
      64             :   Handlers to the plumed object can be converted among different representations,
      65             :   to allow inter-operability among languages. In C, there are tools to convert
      66             :   to/from FORTRAN, whereas in C++ there are tools to convert to/from FORTRAN and C.
      67             : 
      68             :   These handlers only contain a pointer to the real structure, so that
      69             :   when a plumed object is brought from one language to another,
      70             :   it brings a reference to the same environment.
      71             : 
      72             :   Moreover, to simplify life in all cases where a single Plumed object is
      73             :   required for the entire simulation (which covers most of the practical
      74             :   applications with conventional MD codes) it is possible to take advantage
      75             :   of a global interface, which is implicitly referring to a unique global instance.
      76             :   The global object should still be initialized and finalized properly.
      77             : 
      78             :   The basic method to send a message to plumed is
      79             : \verbatim
      80             :   (C) plumed_cmd
      81             :   (C++) PLMD::Plumed::cmd
      82             :   (FORTRAN)  PLUMED_F_CMD
      83             : \endverbatim
      84             : 
      85             :   To initialize a plumed object, use:
      86             : \verbatim
      87             :   (C)        plumed_create
      88             :   (C++)      (constructor of PLMD::Plumed)
      89             :   (FORTRAN)  PLUMED_F_CREATE
      90             : \endverbatim
      91             : 
      92             :   To finalize it, use
      93             : \verbatim
      94             :   (C)        plumed_finalize
      95             :   (C++)      (destructor of PLMD::Plumed)
      96             :   (FORTRAN)  PLUMED_F_FINALIZE
      97             : \endverbatim
      98             : 
      99             :   To access to the global-object, use
     100             : \verbatim
     101             :   (C)        plumed_gcreate, plumed_gfinalize, plumed_gcmd
     102             :   (C++)      PLMD::Plumed::gcreate, PLMD::Plumed::gfinalize, PLMD::Plumed::gcmd
     103             :   (FORTRAN)  PLUMED_F_GCREATE, PLUMED_F_GFINALIZE, PLUMED_F_GCMD
     104             : \endverbatim
     105             : 
     106             :   To check if the global object has been initialized, use
     107             : \verbatim
     108             :   (C)        plumed_ginitialized
     109             :   (C++)      PLMD::Plumed::ginitialized
     110             :   (FORTRAN)  PLUMED_F_GINITIALIZED
     111             : \endverbatim
     112             : 
     113             :   To check if plumed library is available (this is useful for runtime linking), use
     114             : \verbatim
     115             :   (C)        plumed_installed
     116             :   (C++)      PLMD::Plumed::installed
     117             :   (FORTRAN)  PLUMED_F_INSTALLED
     118             : \endverbatim
     119             : 
     120             :   To convert handlers use
     121             : \verbatim
     122             :   (C)        plumed_c2f                 (C to FORTRAN)
     123             :   (C)        plumed_f2c                 (FORTRAN to C)
     124             :   (C++)      Plumed(plumed) constructor (C to C++)
     125             :   (C++)      operator plumed() cast     (C++ to C)
     126             :   (C++)      Plumed(char*)  constructor (FORTRAN to C++)
     127             :   (C++)      toFortran(char*)           (C++ to FORTRAN)
     128             : \endverbatim
     129             : 
     130             : \verbatim
     131             :   FORTRAN interface
     132             :     SUBROUTINE PLUMED_F_INSTALLED(i)
     133             :       INTEGER,           INTENT(OUT)   :: i
     134             :     SUBROUTINE PLUMED_F_GINITIALIZED(i)
     135             :       INTEGER,           INTENT(OUT)   :: i
     136             :     SUBROUTINE PLUMED_F_GCREATE()
     137             :     SUBROUTINE PLUMED_F_GCMD(key,val)
     138             :       CHARACTER(LEN=*), INTENT(IN)     :: key
     139             :       UNSPECIFIED_TYPE, INTENT(INOUT)  :: val(*)
     140             :     SUBROUTINE PLUMED_F_GFINALIZE()
     141             :     SUBROUTINE PLUMED_F_GLOBAL(p)
     142             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
     143             :     SUBROUTINE PLUMED_F_CREATE(p)
     144             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
     145             :     SUBROUTINE PLUMED_F_CMD(p,key,val)
     146             :       CHARACTER(LEN=32), INTENT(IN)    :: p
     147             :       CHARACTER(LEN=*),  INTENT(IN)    :: key
     148             :       UNSPECIFIED_TYPE,  INTENT(INOUT) :: val(*)
     149             :     SUBROUTINE PLUMED_F_FINALIZE(p)
     150             :       CHARACTER(LEN=32), INTENT(IN)    :: p
     151             : \endverbatim
     152             : 
     153             :   The main routine is "cmd", which accepts two arguments:
     154             :   key is a string containing the name of the command
     155             :   val is the argument. it is declared const so as to use allow passing const objects, but in practice plumed
     156             :       is going to modify val in several cases (using a const_cast).
     157             :   In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted).
     158             :   The set of possible keys is the real API of the plumed library, and will be expanded with time.
     159             :   New commands will be added, but backward compatibility will be retained as long as possible.
     160             : 
     161             :   To pass plumed a callback function use the following syntax (not available in FORTRAN yet)
     162             : \verbatim
     163             :     plumed_function_holder ff;
     164             :     ff.p=your_function;
     165             :     plumed_cmd(plumed,"xxxx",&ff);
     166             : \endverbatim
     167             :   (this is passing the your_function() function to the "xxxx" command)
     168             : */
     169             : 
     170             : #ifdef __cplusplus
     171             : extern "C" {
     172             : #endif
     173             : 
     174             : /* Generic function pointer */
     175             : typedef void (*plumed_function_pointer)(void);
     176             : 
     177             : /**
     178             :   \brief Holder for function pointer.
     179             : 
     180             :   To pass plumed a callback function use the following syntax:
     181             : \verbatim
     182             :     plumed_function_holder ff;
     183             :     ff.p=your_function;
     184             :     plumed_cmd(plumed,"xxxx",&ff);
     185             : \endverbatim
     186             :   (this is going to pass the your_function() function to the "xxxx" command)
     187             : */
     188             : 
     189             : typedef struct {
     190             :   plumed_function_pointer p;
     191             : } plumed_function_holder;
     192             : 
     193             : /**
     194             :   \brief Main plumed object
     195             : 
     196             :   This is an object containing a Plumed instance, which should be used in
     197             :   the MD engine. It should first be initialized with plumed_create(),
     198             :   then it communicates with the MD engine using plumed_cmd(). Finally,
     199             :   before the termination, it should be deallocated with plumed_finalize().
     200             :   Its interface is very simple and general, and is expected
     201             :   not to change across plumed versions. See \ref ReferencePlumedH.
     202             : */
     203             : typedef struct {
     204             :   /**
     205             :     \private
     206             :     \brief Void pointer holding the real PlumedMain structure
     207             :   */
     208             :   void*p;
     209             : } plumed;
     210             : 
     211             : /** \relates plumed
     212             :     \brief Constructor
     213             : 
     214             :     \return The constructed plumed object
     215             : */
     216             : plumed plumed_create(void);
     217             : 
     218             : /** \relates plumed
     219             :     \brief Tells p to execute a command
     220             : 
     221             :     \param p The plumed object on which command is acting
     222             :     \param key The name of the command to be executed
     223             :     \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
     224             :                but for some choice of key it can change the content
     225             : */
     226             : void plumed_cmd(plumed p,const char*key,const void*val);
     227             : 
     228             : /** \relates plumed
     229             :     \brief Destructor
     230             : 
     231             :     \param p The plumed object to be deallocated
     232             : */
     233             : void plumed_finalize(plumed p);
     234             : 
     235             : /** \relates plumed
     236             :     \brief Check if plumed is installed (for runtime binding)
     237             : 
     238             :     \return 1 if plumed is installed, 0 otherwise
     239             : */
     240             : int plumed_installed(void);
     241             : 
     242             : /** \relates plumed
     243             :     \brief Retrieves an handler to the global structure.
     244             : */
     245             : plumed plumed_global(void);
     246             : 
     247             : /** \relates plumed
     248             :     \brief Check if the global interface has been initialized
     249             : 
     250             :     \return 1 if plumed has been initialized, 0 otherwise
     251             : */
     252             : int plumed_ginitialized(void);
     253             : 
     254             : /* global C interface, working on a global object */
     255             : 
     256             : /** \relates plumed
     257             :     \brief Constructor for the global interface.
     258             : 
     259             :     \note Equivalent to plumed_create(), but initialize the static global plumed object
     260             : */
     261             : void plumed_gcreate(void);
     262             : 
     263             : /** \relates plumed
     264             :     \brief Tells to the global interface to execute a command.
     265             : 
     266             :     \param key The name of the command to be executed
     267             :     \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
     268             :                but for some choice of key it can change the content
     269             : 
     270             :     \note Equivalent to plumed_cmd(), but acting on the global plumed object.
     271             :           It thus does not require the plumed object to be specified.
     272             : */
     273             : void plumed_gcmd(const char* key,const void* val);
     274             : 
     275             : /** \relates plumed
     276             :     \brief Destructor for the global interface.
     277             : 
     278             :     \note Equivalent to plumed_finalize(), but acting on the global plumed object.
     279             :           It thus does not require the plumed object to be specified.
     280             : */
     281             : void plumed_gfinalize(void);
     282             : 
     283             : /* routines to convert char handler from/to plumed objects */
     284             : 
     285             : /** \related plumed
     286             :     \brief Converts a C handler to a FORTRAN handler
     287             : 
     288             :     \param p The C handler
     289             :     \param c The FORTRAN handler (a char[32])
     290             : 
     291             :     This function can be used to convert a plumed object created in C to
     292             :     a plumed handler that can be used in FORTRAN.
     293             : \verbatim
     294             : #include <plumed/wrapper/Plumed.h>
     295             : int main(int argc,char*argv[]){
     296             :   plumed p;
     297             :   p=plumed_create();
     298             :   char fortran_handler[32];
     299             :   plumed_c2f(p,fortran_handler);
     300             :   printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
     301             :   fortran_routine(fortran_handler);
     302             :   plumed_finalize(p);
     303             :   return 0;
     304             : }
     305             : \endverbatim
     306             :   Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
     307             :   fortran_handler.
     308             : */
     309             : void   plumed_c2f(plumed p,char* c);
     310             : 
     311             : /** \related plumed
     312             :     \brief Converts a FORTRAN handler to a C handler
     313             :     \param c The FORTRAN handler (a char[32])
     314             :     \return The C handler
     315             : 
     316             :     This function can be used to convert a plumed object created in FORTRAN
     317             :     to a plumed handler that can be used in C.
     318             : \verbatim
     319             : void c_routine(char handler[32]){
     320             :   plumed p;
     321             :   p=plumed_f2c(handler);
     322             :   plumed_cmd(p,"init",NULL);
     323             : }
     324             : \endverbatim
     325             :   Here `c_routine` is a C function that can be called from FORTRAN
     326             :   and interact with the provided plumed handler.
     327             : */
     328             : plumed plumed_f2c(const char* c);
     329             : 
     330             : #ifdef __cplusplus
     331             : }
     332             : #endif
     333             : 
     334             : #ifdef __cplusplus
     335             : 
     336             : /* this is to include the NULL pointer */
     337             : #include <cstdlib>
     338             : 
     339             : /* C++ interface is hidden in PLMD namespace (same as plumed library) */
     340             : namespace PLMD {
     341             : 
     342             : /**
     343             :   C++ wrapper for \ref plumed.
     344             : 
     345             :   This class provides a C++ interface to PLUMED.
     346             : */
     347             : 
     348             : class Plumed {
     349             :   /**
     350             :     C structure.
     351             :   */
     352             :   plumed main;
     353             :   /**
     354             :      keeps track if the object was created from scratch using
     355             :      the defaults destructor (reference=false) or if it was imported
     356             :      from C or FORTRAN (reference=true). In the latter case, the
     357             :      plumed_finalize() method is not called when destructing the object,
     358             :      since it is expected to be finalized in the C/FORTRAN code
     359             :   */
     360             :   bool reference;
     361             : public:
     362             :   /**
     363             :      Check if plumed is installed (for runtime binding)
     364             :      \return true if plumed is installed, false otherwise
     365             :      \note Equivalent to plumed_installed() but returns a bool
     366             :   */
     367             :   static bool installed();
     368             :   /**
     369             :      Check if global-plumed has been initialized
     370             :      \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
     371             :              called), false otherwise.
     372             :      \note Equivalent to plumed_ginitialized() but returns a bool
     373             :   */
     374             :   static bool ginitialized();
     375             :   /**
     376             :      Initialize global-plumed.
     377             :      \note Equivalent to plumed_gcreate()
     378             :   */
     379             :   static void gcreate();
     380             :   /**
     381             :      Send a command to global-plumed
     382             :       \param key The name of the command to be executed
     383             :       \param val The argument. It is declared as const to allow calls like gcmd("A","B"),
     384             :                  but for some choice of key it can change the content
     385             :      \note Equivalent to plumed_gcmd()
     386             :   */
     387             :   static void gcmd(const char* key,const void* val=NULL);
     388             :   /**
     389             :      Finalize global-plumed
     390             :   */
     391             :   static void gfinalize();
     392             :   /**
     393             :      Returns the Plumed global object
     394             :      \return The Plumed global object
     395             :   */
     396             :   static Plumed global();
     397             :   /**
     398             :      Constructor.
     399             :     \note Performs the same task a plumed_create()
     400             :   */
     401             :   Plumed();
     402             :   /**
     403             :      Clone a Plumed object from a FORTRAN char* handler
     404             :      \param c The FORTRAN handler (a char[32]).
     405             : 
     406             :    \attention The Plumed object created in this manner
     407             :               will not finalize the corresponding plumed structure.
     408             :               It is expected that the FORTRAN code calls plumed_c_finalize for it
     409             :   */
     410             : // to have maximum portability of this file I do not use the explicit keyword here
     411             : // I thus add a suppress command for cppcheck
     412             : // cppcheck-suppress noExplicitConstructor
     413             :   Plumed(const char*c);
     414             :   /**
     415             :      Clone a Plumed object from a C plumed structure
     416             :      \param p The C plumed structure.
     417             : 
     418             :    \attention The Plumed object created in this manner
     419             :               will not finalize the corresponding plumed structure.
     420             :               It is expected that the C code calls plumed_finalize for it
     421             :   */
     422             : // to have maximum portability of this file I do not use the explicit keyword here
     423             : // I thus add a suppress command for cppcheck
     424             : // cppcheck-suppress noExplicitConstructor
     425             :   Plumed(plumed p);
     426             : private:
     427             :   /** Copy constructor is disabled (private and unimplemented)
     428             :     The problem here is that after copying it will not be clear who is
     429             :     going to finalize the corresponding plumed structure.
     430             :   */
     431             :   Plumed(const Plumed&);
     432             :   /** Assignment operator is disabled (private and unimplemented)
     433             :     The problem here is that after copying it will not be clear who is
     434             :     going to finalize the corresponding plumed structure.
     435             :   */
     436             :   Plumed&operator=(const Plumed&);
     437             : public:
     438             :   /*
     439             :     PLUMED 2.4 requires a C++11 compiler.
     440             :     Anyway, since Plumed.h file might be redistributed with other codes
     441             :     and it should be possible to combine it with earlier PLUMED versions,
     442             :     we here explicitly check if C+11 is available before enabling move semantics.
     443             :     This could still create problems if a compiler 'cheats', setting  __cplusplus > 199711L
     444             :     but not supporting move semantics. Hopefully will not happen!
     445             :   */
     446             : #if __cplusplus > 199711L
     447             :   /** Move constructor.
     448             :     Only if move semantics is enabled.
     449             :     It allows storing PLMD::Plumed objects in STL containers.
     450             :   */
     451             :   Plumed(Plumed&&);
     452             :   /** Move assignment.
     453             :     Only if move semantics is enabled.
     454             :   */
     455             :   Plumed& operator=(Plumed&&);
     456             : #endif
     457             :   /**
     458             :      Retrieve the C plumed structure for this object
     459             :   */
     460             :   operator plumed()const;
     461             :   /**
     462             :      Retrieve a FORTRAN handler for this object
     463             :       \param c The FORTRAN handler (a char[32]).
     464             :   */
     465             :   void toFortran(char*c)const;
     466             :   /**
     467             :      Send a command to this plumed object
     468             :       \param key The name of the command to be executed
     469             :       \param val The argument. It is declared as const to allow calls like p.cmd("A","B"),
     470             :                  but for some choice of key it can change the content
     471             :       \note Equivalent to plumed_cmd()
     472             :   */
     473             :   void cmd(const char*key,const void*val=NULL);
     474             :   /**
     475             :      Destructor
     476             : 
     477             :      Destructor is virtual so as to allow correct inheritance from Plumed object.
     478             :      To avoid linking problems with g++, I specify "inline" also here (in principle
     479             :      it should be enough to specify it down in the definition of the function, but
     480             :      for some reason that I do not understand g++ does not inline it properly in that
     481             :      case and complains when Plumed.h is included but Plumed.o is not linked. Anyway, the
     482             :      way it is done here seems to work properly).
     483             :   */
     484             :   inline virtual ~Plumed();
     485             : };
     486             : 
     487             : /* All methods are inlined so as to avoid the compilation of an extra c++ file */
     488             : 
     489             : inline
     490             : bool Plumed::installed() {
     491             :   return plumed_installed();
     492             : }
     493             : 
     494             : inline
     495        2115 : Plumed::Plumed():
     496             :   main(plumed_create()),
     497        2115 :   reference(false)
     498             : {}
     499             : 
     500             : inline
     501             : Plumed::Plumed(const char*c):
     502             :   main(plumed_f2c(c)),
     503             :   reference(true)
     504             : {}
     505             : 
     506             : inline
     507             : Plumed::Plumed(plumed p):
     508             :   main(p),
     509             :   reference(true)
     510             : {}
     511             : 
     512             : #if __cplusplus > 199711L
     513             : inline
     514             : Plumed::Plumed(Plumed&& p):
     515             :   main(p.main),
     516             :   reference(p.reference)
     517             : {
     518             :   p.main.p=nullptr;
     519             :   p.reference=true; // make sure the moved plumed is not finalized
     520             : }
     521             : 
     522             : inline
     523             : Plumed& Plumed::operator=(Plumed&& p) {
     524             :   if(this != &p) {
     525             :     if(!reference) plumed_finalize(main);
     526             :     main=p.main;
     527             :     reference=p.reference;
     528             :     p.main.p=nullptr;
     529             :     p.reference=true; // make sure the moved plumed is not finalized
     530             :   }
     531             :   return *this;
     532             : }
     533             : 
     534             : #endif
     535             : 
     536             : inline
     537             : Plumed::operator plumed()const {
     538             :   return main;
     539             : }
     540             : 
     541             : inline
     542             : void Plumed::toFortran(char*c)const {
     543             :   plumed_c2f(main,c);
     544             : }
     545             : 
     546             : inline
     547             : void Plumed::cmd(const char*key,const void*val) {
     548      189456 :   plumed_cmd(main,key,val);
     549             : }
     550             : 
     551             : inline
     552        4230 : Plumed::~Plumed() {
     553        2115 :   if(!reference)plumed_finalize(main);
     554        1603 : }
     555             : 
     556             : inline
     557             : bool Plumed::ginitialized() {
     558             :   return plumed_ginitialized();
     559             : }
     560             : 
     561             : inline
     562             : void Plumed::gcreate() {
     563             :   plumed_gcreate();
     564             : }
     565             : 
     566             : inline
     567             : void Plumed::gcmd(const char* key,const void* val) {
     568             :   plumed_gcmd(key,val);
     569             : }
     570             : 
     571             : inline
     572             : void Plumed::gfinalize() {
     573             :   plumed_gfinalize();
     574             : }
     575             : 
     576             : inline
     577             : Plumed Plumed::global() {
     578             :   return plumed_global();
     579             : }
     580             : 
     581             : }
     582             : 
     583             : #endif
     584             : 
     585             : 
     586             : #endif

Generated by: LCOV version 1.13