Skip to content

Commit

Permalink
Added new documentation for actions in core and refdist
Browse files Browse the repository at this point in the history
  • Loading branch information
Gareth Aneurin Tribello authored and Gareth Aneurin Tribello committed Dec 3, 2024
1 parent 13f6608 commit ebe7bb7
Show file tree
Hide file tree
Showing 12 changed files with 795 additions and 82 deletions.
1 change: 1 addition & 0 deletions new-manual/specifying_atoms.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ predefined as a [GROUP](GROUP.md) that can be reused multiple times. Lists of at
- numerical ranges. So `g2: GROUP ATOMS=10-20` is equivalent to `g2: GROUP ATOMS=10,11,12,13,14,15,16,17,18,19,20`
- numerical ranges with a stride. So `g3: GROUP ATOMS=10-100:10` is equivalent to `g3: GROUP ATOMS=10,20,30,40,50,60,70,80,90,100`
- atom ranges with a negative stride. So `g4: GROUP ATOMS=100-10:-10` is equivalent to `g4: GROUP ATOMS=100,90,80,70,60,50,40,30,20,10`
- by using an auxiliary [ndx file](https://manual.gromacs.org/archive/5.0.4/online/ndx.html). So `g5: GROUP ATOMS={@ndx:{index.ndx Protein}}`

If you want to use the atoms in a group as the input for a action you use the label of the group as shown in the following input:

Expand Down
41 changes: 40 additions & 1 deletion src/core/ActionToGetData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,46 @@
/*
Get data from PLUMED for another code
\par Examples
The GET command takes in the label of a Value and transfers the contents of the Value to
to a void pointer that is accessible in the code that called PLUMED. As the calling code does not know the shape of the Value in advance,
we provide the functionality to get the data rank and shape. The following Python snippet illustrates how this works in practice:
```python
import plumed
# Create a PLUMED object
p = plumed.Plumed()
# Setup PLUMED
num_atoms = 10
p.cmd("setNatoms",num_atoms)
p.cmd("setLogFile","test.log")
p.cmd("init")
# Tell PLUMED to calculate the distance between two atoms
p.cmd("readInputLine", "d1: DISTANCE ATOMS=1,2")
# Get the rank of the PLMD::Value that holds the distance
# This command sets up the GET object
rank = np.zeros( 1, dtype=np.int_ )
p.cmd("getDataRank d1", rank )
# Now get the shape of the PLMD::Value d1 that we are asking for in the GET object
shape = np.zeros( rank, dtype=np.int_ )
p.cmd("getDataShape d1", shape )
# And now set the void pointer that the data in PLMD::Value d1 should be
# transferred to so it can be accessed in our python script when asking PLMD to do a calculation
d1 = np.zeros( shape )
p.cmd("setMemoryForData d1", data )
# if we now transfer some atomic positions to plumed and call calc the variable d1 is set equal to the distance between atom 1 and atom 2.
```
Notice that you can have as many GET actions as you need. The data is transferred from the PLMD::Value to the void pointer when the `calculate` method of GET is called.
Transferring variables is thus seamlessly integrated into the PLUMED calculation cycle.
You would only use the GET command if you were calling PLUMED from python or an MD code. The equivalent commands that you would use for this action in a conventional PLUMED input file as follows.
```plumed
d: DISTANCE ATOMS=1,2
GET ARG=d
```
*/
//+ENDPLUMEDOC
Expand Down
43 changes: 42 additions & 1 deletion src/core/ActionToPutData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,48 @@
/*
Pass data into PLUMED
\par Examples
The PUT command transfers the data from a void pointer passed to PLUMED from the calling code to a PLMD::Value. The calling
object knows the shapes of the variables it is passing, so if you want to pass a 3x3 matrix from the MD code to PLUMED, you create the space to do so as follows:
```c++
plumed.cmd("readInputLine n: PUT SHAPE=3,3 UNIT=length PERIODIC=NO");
```
This command then creates a PLMD::Value called `n` that you can refer to later in your PLUMED input file. To transfer data from the void pointer called val into the PLMD::Value
called `n`, you would then use the following command:
```c++
plumed.cmd("setValue n", val);
```
Notice also that if you expect PLUMED to try to apply forces on `n`, you can pass a void pointer called `force` to get the forces that PLUMED has applied on the elements of n as follows:
```c++
plumed.cmd("setValueForces n", force);
```
Within the PLMD::Value `n`, the forces that PLUMED wishes to apply on the components of the input object are stored in the std::vector called `inputForce`. Furthermore, whenever a PLMD::Value
is created from a PUT action `storedata` is set to true. PUT also has a CONSTANT flag that allows you to transfer variables such as the value of the timestep that is set only once during the
simulation (i.e. during startup).
Data is transferred from the input void pointers to the PLMD value when the `share` and `wait` methods are called. Vectors, e.g. positions, that are split between the domains
are transferred when the share and wait methods of the [DOMAIN_DECOMPOSITION](DOMAIN_DECOMPOSITION.md) action are called.
You would only use the PUT command if you were calling PLUMED from python or an MD code. The equivalent commands in a convetional PLUMED input file would look like this.
```plumed
# This is how you create a value to hold the energy the MD code passes energy in plumed
eng: PUT UNIT=energy PERIODIC=NO
# This is how you create an vector of the 100 x positions to plumed
xpos: PUT SHAPE=100 UNIT=length PERIODIC=NO
# This is how you create a scalar to hold the timestep
# The constant flag indicates that the value of the timestep doesn't change during the simulation
tstep: PUT CONSTANT UNIT=time PERIODIC=NO
# This is how you create a value to hold a 10 x 10 matrix in plumed whose elements are unitless
matrix: PUT SHAPE=10,10 UNIT=number PERIODIC=NO
# Lastly, if you want to pass a value that has a periodic domain you can do so as follows
tor: PUT PERIODIC=-pi,pi
```
*/
//+ENDPLUMEDOC
Expand Down
68 changes: 67 additions & 1 deletion src/core/DomainDecomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,73 @@
/*
Pass domain decomposed properties of atoms to PLUMED
\par Examples
Data is passed from the MD code to PLUMED by creating [PUT](PUT.md) actions.
These PUT actions take the data from a void pointer that is passed to PLUMED from the MD code and transfer it into a
PLMD::Value object. Passing a void pointer and using a PUT action to convert the data within it
to a PLMD::Value is also used when the atomic positions, masses and charges are sent to PLUMED. However,
there are some other subtleties for these quantities because MD codes use a domain decomposition and scatter the properties of atoms across
multiple domains. We thus need to use the action DOMAIN_DECOMPOSITION when passing these quantities to make sense of the
information in the void pointers that the MD code passes.
## Creating a DOMAIN_DECOMPOSITION action
A DOMAIN_DECOMPOSITION can be created by using a call to plumed.cmd as follows:
```c++
plumed.cmd("readInputLine dd: DOMAIN_DECOMPOSITION NATOMS=20 VALUE1=vv UNIT1=length PERIODIC1=NO CONSTANT1=False");
```
The DOMAIN_DECOMPOSTION command above creates a PUT action with the label vv. The pointer to the data that needs to be transferred to the PLMD::Value
object that is created by the PUT action is then set by using the command below:
```c++
plumed.cmd("setInputValue vv, &val);
```
Meanwhile, the pointer to the forces that should be modified is passed as follows:
```c++
plumed.cmd("setValueForces vv", force);
```
In other words, pointers to values and forces in the MD code are passed to PUT actions that are created by the DOMAIN_DECOMPOSION in
[the way you pass data to other PUT actions](PUT.md).
The PLMD::Value objects created by a DOMAIN_DECOMPOSITION action are always vectors with the same number of components as atoms in the system. Furthermore, you can create multiple PUT
actions from a single DOMAIN_DECOMPOSITION action. To see why this is useful, consider the following DOMAIN_DECOMPOSITION command:
```plumed
gromacs: DOMAIN_DECOMPOSITION ...
NATOMS=2000
VALUE1=myposx UNIT1=length PERIODIC1=NO CONSTANT1=False ROLE1=x
VALUE2=myposy UNIT2=length PERIODIC2=NO CONSTANT2=False ROLE2=y
VALUE3=myposz UNIT3=length PERIODIC3=NO CONSTANT3=False ROLE3=z
VALUE4=myMasses UNIT4=mass PERIODIC4=NO CONSTANT4=True ROLE4=m
VALUE5=myCharges UNIT5=charge PERIODIC5=NO CONSTANT5=True ROLE5=q
PBCLABEL=mybox
...
```
This action is created when you call `plumed.cmd("setNatoms",&natoms)` from gromacs. It makes 5 PLMD::Value called posx, posy, posz, Masses and Charges.
These PLMD::Value objects then hold the x, y and z positions of the atoms and the masses and charges of the atoms. It is important to note that this command will
also, create a PBC_ACTION to hold the cell.
The ROLE keywords above are only needed because the five quantities passed by the command above play a unique role within PLUMED. If you pass
some other quantities, this instruction is not required. PLMD::ActionAtomistic searches for atomic positions, masses and charges by looking for PUT Actions
that have these five particular roles and for ActionWithVirtualAtom objects.
## Differences from regular PUT actions
PUT actions created from a DOMAIN_DECOMPOSITION action behave differently from other PUT actions. In particular:
* If a DOMAIN_DECOMPOSITION action creates a PUT action, then the PUT action depends on the DOMAIN_DECOMPOSITION action. ActionToPutData::apply thus does nothing for these PUT actions.
* Similarly, when DOMAIN_DECOMPOSITION actions create PUT actions, data is transferred from the input pointer to the PLMD::Value object by the DOMAIN_DECOMPOSITION action. When ActionToPutData::wait is called for these PUT Actions `wasset=true`, ActionToPutData::wait does nothing.
* Lastly, if a constant PUT action is created by DOMAIN_DECOMPOSITION, the values in the vector are set during the first step of MD rather than during initialisation.
These differences are necessary because PUT actions cannot understand the information in the pointers that are passed from the MD code. These pointers are only understandable if you know
which atoms are on each processor. This information is only passed to the DOMAIN_DECOMPOSITION action. DOMAIN_DECOMPOSITION must translate the information passed from the MD code before it is
passed back on through PLMD::Value objects created by the PUT actions. DOMAIN_DECOMPOSITION thus keeps pointers to all the PUT actions that it creates. It sets the data in these action's PLMD::Value objects
within `DomainDecomposition::share(const std::vector<AtomNumber>& unique)` and `DomainDecomposition::wait().` The forces on the PUT actions created by the DOMAIN_DECOMPOSITION action are added in `DomainDecomposition::apply()`.
*/
//+ENDPLUMEDOC
Expand Down
113 changes: 45 additions & 68 deletions src/core/Group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,36 +37,10 @@ namespace PLMD {
/*
Define a group of atoms so that a particular list of atoms can be referenced with a single label in definitions of CVs or virtual atoms.
Atoms can be listed as comma separated numbers (i.e. `1,2,3,10,45,7,9`) , simple positive ranges
(i.e. `20-40`), ranges with a stride either positive or negative (i.e. `20-40:2` or `80-50:-2`) or as
comma separated combinations of all the former methods (`1,2,4,5,10-20,21-40:2,80-50:-2`).
Moreover, lists can be imported from ndx files (GROMACS format). Use `NDX_FILE` to set the name of
the index file and `NDX_GROUP` to set the name of the group to be imported (default is first one).
Notice that starting from version 2.10 it is possible to directly use an `@ndx:` selector
(see \ref Group).
It is also possible to remove atoms from a list and or sort them using keywords `REMOVE`, `SORT`, and `UNIQUE`.
The flow is the following:
- If `ATOMS` is present, then take the ordered list of atoms from the `ATOMS` keyword as a starting list.
- Alternatively, if `NDX_FILE` is present, use the list obtained from the gromacs group.
- If `REMOVE` is present, then remove the first occurrence of each of these atoms from the list.
If one tries to remove an atom that was not listed plumed adds a notice in the output.
An atom that is present twice in the original list might be removed twice.
- If `SORT` is present, then the resulting list is sorted by increasing serial number.
- If `UNIQUE` is present, then the resulting list is sorted by increasing serial number _and_ duplicate elements are removed.
The GROUP command can be used to define a list of atoms so that the group can be referenced in the definitions of other
CVs or virtual atoms as shown below:
Notice that this command just creates a shortcut, and does not imply any real calculation.
So, having a huge group defined does not slow down your calculation in any way.
It is just convenient to better organize input files. Might be used in combination with
the \ref INCLUDE command so as to store long group definitions in a separate file.
\par Examples
This command create a group of atoms containing atoms 1, 4, 7, 11 and 14 (labeled 'o'), and another containing
atoms 2, 3, 5, 6, 8, 9, 12, and 13 (labeled 'h'):
\plumedfile
```plumed
o: GROUP ATOMS=1,4,7,11,14
h: GROUP ATOMS=2,3,5,6,8,9,12,13
# compute the coordination among the two groups
Expand All @@ -76,64 +50,67 @@ c: COORDINATION GROUPA=o GROUPB=h R_0=0.3
# print the coordination on file 'colvar'
PRINT ARG=c FILE=colvar
\endplumedfile
```
Groups can be conveniently stored in a separate file.
E.g. one could create a file named `groups.dat` which reads
\plumedfile
#SETTINGS FILENAME=groups.dat
# this is groups.dat
o: GROUP ATOMS=1,4,7,11,14
h: GROUP ATOMS=2,3,5,6,8,9,12,13
\endplumedfile
and then include it in the main 'plumed.dat' file
\plumedfile
The first group command here creates a group of atoms called `o` containing atoms 1, 4, 7, 11 and 14.
The second group command here creates a group of toms called `h` containing atoms 2, 3, 5, 6, 8, 9, 12, and 13.
As discussed on [this page](specifying_atoms.md) atoms in groups can be listed as comma separated numbers (i.e. `1,2,3,10,45,7,9`),
simple positive ranges (i.e. `20-40`), ranges with a stride either positive or negative (i.e. `20-40:2` or `80-50:-2`) or as
comma separated combinations of all the former methods (`1,2,4,5,10-20,21-40:2,80-50:-2`).
Oftentime people will store the definitions in a separate file as has been done in the following example input.
```plumed
INCLUDE FILE=groups.dat
# compute the coordination among the two groups
c: COORDINATION GROUPA=o GROUPB=h R_0=0.3
c: COORDINATION GROUPA=groupa GROUPB=groupb R_0=0.3
# print the coordination on file 'colvar'
PRINT ARG=c FILE=colvar
\endplumedfile
The `groups.dat` file could be very long and include lists of thousand atoms without cluttering the main plumed.dat file.
A GROMACS index file such as the one shown below:
\auxfile{index.ndx}
[ Protein ]
1 3 5 7 9
2 4 6 8 10
[ Group2 ]
30 31 32 33 34 35 36 37 38 39 40
5
\endauxfile
can also be imported by using the GROUP keyword as shown below
\plumedfile
```
Storing the groups in the extra file is particularly useful if the groups include list of thousand atoms. Putting these definitions
in a separate file ensures that the main plumed.dat file is not cluttered. You can even use a [GROMACS index file](https://manual.gromacs.org/archive/5.0.4/online/ndx.html)
to hold the groups as illustrated in the input below:
```plumed
# import group named 'Protein' from file index.ndx
pro: GROUP NDX_FILE=index.ndx NDX_GROUP=Protein
# dump all the atoms of the protein on a trajectory file
DUMPATOMS ATOMS=pro FILE=traj.gro
\endplumedfile
```
Notice that it is now possible to directly use the `@ndx:` selector
in the definition of collective variables. Thus, the same result can be obtained
with the following input:
\plumedfile
Notice that you use the keyword `NDX_FILE` to set the name of the index file and `NDX_GROUP` to set the name of the group to be imported (default is first one).
Further notice that starting from version 2.10 it is possible to directly use an `@ndx:` selector in the input to an action as shwn below:
```plumed
DUMPATOMS ATOMS={@ndx:{index.ndx Protein}} FILE=traj.gro
\endplumedfile
```
Lastly notice that it is also possible to remove atoms from the list of atoms specified in a GROUP by using the keywords `REMOVE`, `SORT`, and `UNIQUE` as shown below:
A list can be edited with `REMOVE`. For instance, if you
are using a water model with three atoms per molecule, you can
easily construct the list of hydrogen atoms in this manner
\plumedfile
```plumed
# take one atom every three, that is oxygens
ox: GROUP ATOMS=1-90:3
# take the remaining atoms, that is hydrogens
hy: GROUP ATOMS=1-90 REMOVE=ox
DUMPATOMS ATOMS=ox FILE=ox.gro
DUMPATOMS ATOMS=hy FILE=hy.gro
\endplumedfile
```
When you used the GROUP command the flow as follows:
- If `ATOMS` is present, then take the ordered list of atoms from the `ATOMS` keyword as a starting list.
- Alternatively, if `NDX_FILE` is present, use the list obtained from the gromacs group.
- If `REMOVE` is present, then remove the first occurrence of each of these atoms from the list.
If one tries to remove an atom that was not listed plumed adds a notice in the output.
An atom that is present twice in the original list might be removed twice.
- If `SORT` is present, then the resulting list is sorted by increasing serial number.
- If `UNIQUE` is present, then the resulting list is sorted by increasing serial number _and_ duplicate elements are removed.
Notice that this command just creates a shortcut, and does not imply any real calculation.
So, having a huge group defined does not slow down your calculation in any way.
It is just convenient to better organize input files.
*/
//+ENDPLUMEDOC
Expand Down
24 changes: 23 additions & 1 deletion src/core/PbcAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,29 @@
/*
Pass the cell vectors into PLUMED.
\par Examples
This command is used to pass the cell vectors from an MD code to PLUMED. The command is a specialised
version of the [PUT](PUT.md) command that accepts a $3\times 3$ matrix. The additional specialisation is
required because the cell vectors play a special role when you do calculations with PLUMED.
Notice that when you create a [DOMAIN_DECOMPOSITION](DOMAIN_DECOMPOSITION.md) action a PBC action is created
automatically.
You would only use the PBC command if you were calling PLUMED from python or an MD code. There is no reason for using this command in a conventional PLUMED
input file like this:
```plumed
pbc: PBC
```
Instead this command would be called from python like this:
```plumed
import plumed
# Create a PLUMED object
p = plumed.Plumed()
p.cmd("readInputLine", "pbc: PBC")
```
*/
//+ENDPLUMEDOC
Expand Down
Loading

1 comment on commit ebe7bb7

@PlumedBot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found broken examples in automatic/ANN.tmp
Found broken examples in automatic/CLASSICAL_MDS.tmp
Found broken examples in automatic/CONVERT_TO_FES.tmp
Found broken examples in automatic/COORDINATIONNUMBER.tmp
Found broken examples in automatic/DISTANCE_FROM_CONTOUR.tmp
Found broken examples in automatic/DUMPCUBE.tmp
Found broken examples in automatic/DUMPGRID.tmp
Found broken examples in automatic/EDS.tmp
Found broken examples in automatic/EMMI.tmp
Found broken examples in automatic/FIND_CONTOUR.tmp
Found broken examples in automatic/FIND_CONTOUR_SURFACE.tmp
Found broken examples in automatic/FIND_SPHERICAL_CONTOUR.tmp
Found broken examples in automatic/FOURIER_TRANSFORM.tmp
Found broken examples in automatic/FUNNEL.tmp
Found broken examples in automatic/FUNNEL_PS.tmp
Found broken examples in automatic/GPROPERTYMAP.tmp
Found broken examples in automatic/HISTOGRAM.tmp
Found broken examples in automatic/INTERPOLATE_GRID.tmp
Found broken examples in automatic/LOCAL_AVERAGE.tmp
Found broken examples in automatic/MAZE_OPTIMIZER_BIAS.tmp
Found broken examples in automatic/MAZE_RANDOM_ACCELERATION_MD.tmp
Found broken examples in automatic/MAZE_SIMULATED_ANNEALING.tmp
Found broken examples in automatic/MAZE_STEERED_MD.tmp
Found broken examples in automatic/METATENSOR.tmp
Found broken examples in automatic/MULTICOLVARDENS.tmp
Found broken examples in automatic/PCA.tmp
Found broken examples in automatic/PCAVARS.tmp
Found broken examples in automatic/PIV.tmp
Found broken examples in automatic/PYCVINTERFACE.tmp
Found broken examples in automatic/PYTHONFUNCTION.tmp
Found broken examples in automatic/Q3.tmp
Found broken examples in automatic/Q4.tmp
Found broken examples in automatic/Q6.tmp
Found broken examples in automatic/QUATERNION.tmp
Found broken examples in automatic/REWEIGHT_BIAS.tmp
Found broken examples in automatic/REWEIGHT_METAD.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_LINEAR_PROJ.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_MAHA_DIST.tmp
Found broken examples in AnalysisPP.md
Found broken examples in CollectiveVariablesPP.md
Found broken examples in MiscelaneousPP.md

Please sign in to comment.