+==============================================================================+
This file is a part of the MANIFOLD package.

This package allows LAMMPS to perform MD simulations of particles
constrained on a manifold (i.e., a 2D subspace of the 3D simulation
box). It achieves this using the RATTLE constraint algorithm applied
to single-particle constraint functions g(xi,yi,zi) = 0 and their
derivative (i.e. the normal of the manifold) n = grad(g).

Stefan Paquay, stefanpaquay@gmail.com

until 2017: Applied Physics/Theory of Polymers and Soft Matter,
Eindhoven University of Technology (TU/e), The Netherlands

since 2017: Brandeis University, Waltham, MA, USA.


Thanks to Remy Kusters at TU/e for testing.

This software is distributed under the GNU General Public License.
+==============================================================================+

At the moment we have a few manifolds available, extending them is very easy:
To add a new manifold, do the following in the "MANIFOLD" directory:

0. Create a new pair of source/header files, and name them "manifold_*.cpp/h",
   where you should replace '*' with some (descriptive) name.
1. In the header file, add the following:
   a. Include guards.
   b. Make sure you #include "manifold.h"
   c. In namespace LAMMPS_NS, add a new class that inherits publicly from manifold
     and protectedly from Pointers.
   d. The constructor has to take ( LAMMPS*, int, char ** ) as arguments,
     and should initialize Pointers.
   e. The header file has to contain somewhere the macro ManifoldStyle with as
     first argument the name of the manifold and as second argument the name
     of the class implementing this manifold. The macro expands into some code
     that registers the manifold during static initialization, before main is
     entered.

2. In the source file, make sure you implement the following (of course,
   you can also implement these in the header):
+====================================+=========================================+
|  Function  signature               |   Purpose                               |
+====================================+=========================================+
|  destructor                        | Free space (can be empty)               |
|  constructor                       | Has to take (LAMMPS *lmp, int, char **) |
|                                    | as arguments and has to initialize      |
|                                    | Pointers with lmp.                      |
|  double g( double *x )             | A function that is 0 if the 3-vector    |
|                                    | x is on the manifold.                   |
|  void   n( double *x, double *n )  | Stores the normal of position x in the  |
|                                    | 3-vector n.                             |
|  static const char *type()         | Returns text that identifies the        |
|                                    | manifold in LAMMPS input scripts.       |
|  const char *id()                  | Should return whatever type() returns.  |
|  static int expected_argc()        | Returns the number of arguments needed  |
|                                    | for the construction/initialization of  |
|                                    | your manifold. Example: Sphere only     |
|                                    | needs a radius, so it returns 1. The    |
|                                    | spine needs 5 parameters, so it         |
|                                    | returns 5.                              |
| int nparams()                      | Should return same as expected_argc()   |
+====================================+=========================================+

If the above instructions seem a bit intimidating, you can get by just fine
by copying an existing manifold and modifying it. See e.g. manifold_sphere for
a relatively simple manifold.

With those things in place, the install script should be able to add your
manifold to LAMMPS without any extra work, so just running
make yes-manifold
make <your_architecture>
should (re)compile LAMMPS with the manifolds added.

+==============================================================================+
Obviously, you need some parameters to represent the surface, such as the radius
in the case of a sphere. These should be passed to the nve/manifold/rattle fix,
with the following syntax:
fix ID group-ID nve/manifold/rattle tol maxit manifold_style args

tol             =  tolerance to which RATTLE tries to satisfy the constraints
maxit           =  maximum number of iterations RATTLE uses each time step
manifold_style  =  manifold style, should equal what type() of the desired
                   manifold returns
args            =  parameters for the manifold, order is manifold-dependent.
                   can be equal style variables
+==============================================================================+
