Core API

State

class State

The state of a minimisation.

Holds the coordinates, potential, and communicator, and provides methods to compute energies and gradients.

A state may be distributed over any subset of the available MPI ranks (all ranks by default). Each rank holds the local data for the degrees of freedom it requires. The block is the set of degrees of freedom allocated primarily to that rank, and the proc data is the block plus the halo of degrees of freedom, owned by neighbouring ranks, that are needed to compute the energy and gradient of the block. The local data therefore has size Communicator::nproc.

The plain energy and gradient functions are intended for end users: they accept either the full set of coordinates or the local proc data, and return the total energy and gradient over the whole system. The remaining parallel functions are intended for writing new minimisation algorithms that make use of the distributed data.

Public Functions

State(const Potential &pot, const vector<double> &coords, const vector<int> &ranks = {})

Construct a state from a potential and initial coordinates.

Parameters:
  • pot – The potential to be minimised.

  • coords – The initial coordinates.

  • ranks – The MPI ranks to distribute the state over (default: all ranks).

Public Members

size_t ndof

The total number of degrees of freedom.

double convergence

Convergence criterion: the minimisation is converged when the energy gradient falls below this value.

std::unique_ptr<Potential> pot

The potential to be minimised.

std::unique_ptr<Communicator> comm

The communicator, handling distribution over MPI processes.

bool usesThisProc = true

Whether the current MPI rank is used by the state.

Failure

Early termination of the minimisation.

bool isFailed = false

Whether the minimisation has failed and should be terminated early.

void failed()

Mark the state as failed, causing the minimiser to terminate early.

Energy and gradient

Compute the total energy and gradient over the whole system.

These are the functions intended for end users; any MPI communication required is handled internally.

double energy() const

Compute the total energy of the current state.

Returns:

The total energy (0 on ranks not used by the state).

double energy(const vector<double> &coords) const

Compute the total energy of the given coordinates.

Parameters:

coords – The coordinates to compute the energy of: either the full set of degrees of freedom, or the local proc data.

Returns:

The total energy, identical on all ranks used by the state (0 on unused ranks).

vector<double> gradient() const

Compute the gradient of the total energy of the current state.

Returns:

The gradient over all degrees of freedom (empty on ranks not used by the state).

vector<double> gradient(const vector<double> &coords) const

Compute the gradient of the total energy of the given coordinates.

Parameters:

coords – The coordinates to compute the gradient of: either the full set of degrees of freedom, or the local proc data.

Returns:

The gradient over all degrees of freedom, identical on all ranks used by the state (empty on unused ranks).

void energyGradient(double *e, vector<double> *g) const

Compute the total energy and gradient of the current state.

Parameters:
  • e – Output: the total energy (may be null).

  • g – Output: the gradient over all degrees of freedom (may be null).

void energyGradient(const vector<double> &coords, double *e, vector<double> *g) const

Compute the total energy and gradient of the given coordinates.

Parameters:
  • coords – The coordinates to compute the energy and gradient of: either the full set of degrees of freedom, or the local proc data.

  • e – Output: the total energy (may be null).

  • g – Output: the gradient over all degrees of freedom (may be null).

double componentEnergy(int component) const

Compute the energy of a single component of the potential, e.g.

for analysing the different contributions to the total energy.

Unlike energy(), the result is not summed over the ranks used by the state: each rank returns the contribution of the elements it holds.

Parameters:

component – The index of the component.

Returns:

The energy of the component.

Coordinates

Read and assign the coordinates of the whole system.

double operator[](int i)

Get a single coordinate by its global index.

Parameters:

i – The global index of the degree of freedom.

Returns:

The value of the coordinate.

vector<double> coords() const

Get the full set of coordinates of the state.

Returns:

All coordinates, identical on all ranks used by the state.

void coords(const vector<double> &in)

Set the coordinates of the state.

Parameters:

in – The new coordinates, given as the full set of degrees of freedom (distributed over the ranks used by the state).

Parallel functions

Compute with the distributed data.

These are intended for writing new minimisation algorithms; see the class description for the block / proc terminology.

const vector<double> &blockCoords() const

Get the local coordinates held by this processor (its block plus halo).

Returns:

The local proc data, of size Communicator::nproc.

void blockCoords(const vector<double> &in)

Set the local coordinates held by this processor.

The halo region is set exactly as given; call communicate() afterwards if it needs updating from the neighbouring blocks.

Parameters:

in – The new local coordinates, of size Communicator::nproc.

double blockEnergy() const

Compute the energy contribution of this processor’s block of the current state.

Returns:

The block’s contribution to the total energy: the total is the sum of the block energies over all ranks used by the state.

double blockEnergy(const vector<double> &coords) const

Compute the energy contribution of this processor’s block of the given coordinates.

Parameters:

coords – The local proc data to compute the energy of.

Returns:

The block’s contribution to the total energy: the total is the sum of the block energies over all ranks used by the state.

vector<double> blockGradient() const

Compute the gradient contribution of this processor’s block of the current state.

Returns:

The gradient in the local proc layout, of size Communicator::nproc. The block entries give the total gradient for those degrees of freedom, but the halo entries are not guaranteed to be correct; use procGradient() if the halo entries are also required.

vector<double> blockGradient(const vector<double> &coords) const

Compute the gradient contribution of this processor’s block of the given coordinates.

Parameters:

coords – The local proc data to compute the gradient of.

Returns:

The gradient in the local proc layout, of size Communicator::nproc. The block entries give the total gradient for those degrees of freedom, but the halo entries are not guaranteed to be correct; use procGradient() if the halo entries are also required.

void blockEnergyGradient(double *e, vector<double> *g) const

Compute the energy and gradient contributions of this processor’s block of the current state.

Parameters:
  • e – Output: the block’s contribution to the total energy.

  • g – Output: the gradient in the local proc layout, of size Communicator::nproc, as given by blockGradient().

void blockEnergyGradient(const vector<double> &coords, double *e, vector<double> *g) const

Compute the energy and gradient contributions of this processor’s block of the given coordinates.

Parameters:
  • coords – The local proc data to compute the energy and gradient of.

  • e – Output: the block’s contribution to the total energy.

  • g – Output: the gradient in the local proc layout, of size Communicator::nproc, as given by blockGradient().

double procEnergy() const

Compute the energy contribution of the coordinates assigned to this processor.

This is identical to blockEnergy(); it is provided for symmetry with procGradient().

Returns:

The processor’s contribution to the total energy.

double procEnergy(const vector<double> &coords) const

Compute the energy contribution of the given coordinates assigned to this processor.

This is identical to blockEnergy(); it is provided for symmetry with procGradient().

Parameters:

coords – The local proc data to compute the energy of.

Returns:

The processor’s contribution to the total energy.

vector<double> procGradient() const

Compute the gradient of the current state over this processor’s data.

This is blockGradient() followed by a halo communication, so that the returned gradient is correct over the whole proc region (block plus halo). This allows minimisation steps to be applied locally to the proc data without further communication.

Returns:

The gradient in the local proc layout, of size Communicator::nproc.

vector<double> procGradient(const vector<double> &coords) const

Compute the gradient of the given coordinates over this processor’s data.

This is blockGradient() followed by a halo communication, so that the returned gradient is correct over the whole proc region (block plus halo). This allows minimisation steps to be applied locally to the proc data without further communication.

Parameters:

coords – The local proc data to compute the gradient of.

Returns:

The gradient in the local proc layout, of size Communicator::nproc.

void procEnergyGradient(double *e, vector<double> *g) const

Compute the energy and gradient of the current state over this processor’s data.

This is blockEnergyGradient() followed by the halo communication of procGradient(): the energy is the processor’s contribution to the total, and the gradient is correct over the whole proc region (block plus halo).

Parameters:
  • e – Output: the processor’s contribution to the total energy.

  • g – Output: the gradient in the local proc layout, of size Communicator::nproc.

void procEnergyGradient(const vector<double> &coords, double *e, vector<double> *g) const

Compute the energy and gradient of the given coordinates over this processor’s data.

This is blockEnergyGradient() followed by the halo communication of procGradient(): the energy is the processor’s contribution to the total, and the gradient is correct over the whole proc region (block plus halo).

Parameters:
  • coords – The local proc data to compute the energy and gradient of.

  • e – Output: the processor’s contribution to the total energy.

  • g – Output: the gradient in the local proc layout, of size Communicator::nproc.

double allEnergy() const

Compute the total energy of the current state, returning the result on all MPI ranks.

Unlike energy(), which returns the result only on the ranks used by the state, this broadcasts it to every rank. This is needed when the state is distributed over a subset of the ranks.

Returns:

The total energy.

vector<double> allGradient() const

Compute the gradient of the total energy of the current state, returning the result on all MPI ranks.

Unlike gradient(), which returns the result only on the ranks used by the state, this broadcasts it to every rank. This is needed when the state is distributed over a subset of the ranks.

Returns:

The gradient over all degrees of freedom.

void allEnergyGradient(double *e, vector<double> *g) const

Compute the total energy and gradient of the current state, returning the results on all MPI ranks.

Unlike energyGradient(), which returns the results only on the ranks used by the state, this broadcasts them to every rank. This is needed when the state is distributed over a subset of the ranks.

Parameters:
  • e – Output: the total energy.

  • g – Output: the gradient over all degrees of freedom.

vector<double> allCoords() const

Get the full set of coordinates, returning them on all MPI ranks.

Unlike coords(), which returns the coordinates only on the ranks used by the state, this broadcasts them to every rank. This is needed when the state is distributed over a subset of the ranks.

Returns:

All coordinates.

void communicate()

Communicate the local coordinates between processors.

Updates the halo region of the local proc data using the block data of the neighbouring ranks.

Constraints

void applyConstraints(vector<double> &data) const

Apply any constraints from the potential to the given data.

Parameters:

data – The data to apply the constraints to.

Minimiser

class Minimiser

Abstract base class for minimisation procedures.

Holds the settings common to different minimisation algorithms and provides the minimise entry point.

Subclassed by minim::NewMinimiser< Anneal >, minim::NewMinimiser< Fire >, minim::NewMinimiser< GradDescent >, minim::NewMinimiser< Lbfgs >, minim::NewMinimiser< Derived >

Public Functions

virtual std::unique_ptr<Minimiser> clone() const = 0

Create a deep copy of the minimiser.

virtual Minimiser &setMaxIter(int maxIter)

Set the maximum number of iterations.

Minimiser &setLinesearch(std::string method)

Set the line search method.

std::vector<double> minimise(State &state, std::function<void(int, State&)> adjustState = nullptr)

Minimise a state with an optional function to be run each iteration.

Parameters:
  • state – The state to be minimised.

  • adjustState – Optional function run each iteration.

Returns:

The final coordinates.

std::vector<double> minimise(State &state, std::string logType)

Minimise with a predefined log function.

Format: [fields]-[iter], e.g. “e-100” logs the energy every 100 iterations.

Parameters:
  • state – The state to be minimised.

  • logType – The log format.

Returns:

The final coordinates.

inline virtual void init(State &state)

Initialise the minimiser before the first iteration.

virtual void iteration(State &state) = 0

Perform a single minimisation iteration.

inline virtual bool checkConvergence(const State &state)

Check whether the minimisation is converged.

Public Members

int maxIter = 100000

Maximum number of iterations before terminating.

std::string linesearch = "backtracking"

The line search method to use.

Potential

class Potential

Abstract base class for system potentials.

The potential computes the energy and gradient of a set of coordinates. It can be constructed from user-supplied functions, or derived from to create more complex potentials.

Subclassed by minim::NewPotential< BarAndHinge >, minim::NewPotential< LjNd >, minim::NewPotential< PhaseField >, minim::NewPotential< PhaseFieldUnstructured >, minim::NewPotential< Derived >

Public Types

enum ParallelType

The type of parallelisation used by the potential.

Values:

enumerator SERIAL
enumerator UNSTRUCTURED
enumerator GRID

Public Functions

Potential(EFunc energy, GFunc gradient)

Construct a potential from separate energy and gradient functions.

Potential(EGFunc energyGradient)

Construct a potential from a combined energy and gradient function.

virtual double energy(const vector<double> &coords) const

Compute the energy of the given coordinates.

virtual vector<double> gradient(const vector<double> &coords) const

Compute the energy gradient of the given coordinates.

virtual void energyGradient(const vector<double> &coords, const Communicator &comm, double *e, vector<double> *g) const

Compute the energy and gradient of the given coordinates.

Parameters:
  • coords – The coordinates to compute the energy and gradient of.

  • comm – The communicator, used for distributed calculations.

  • e – Output: the total energy.

  • g – Output: the gradient of the total energy.

State newState(int ndof, const vector<int> &ranks = {})

Create a new state of the given number of degrees of freedom.

Parameters:
  • ndof – The number of degrees of freedom.

  • ranks – The MPI ranks to distribute the state over (default: all ranks).

State newState(const vector<double> &coords, const vector<int> &ranks = {})

Create a new state from initial coordinates.

Parameters:
  • coords – The initial coordinates.

  • ranks – The MPI ranks to distribute the state over (default: all ranks).

inline virtual void init(const vector<double> &coords)

Initialise the potential with the coordinates of a new state.

inline virtual void initLocal(const vector<double> &coords, const Communicator &comm)

Initialise the potential with local (distributed) data.

Take care using this, if the potential is cloned any distributed parameters will be copied as they are.

inline virtual std::unique_ptr<Potential> clone() const

Create a deep copy of the potential.

Public Members

double convergence = 1e-6

Convergence criterion used when creating a new state.

struct Constraint

A constraint on a set of degrees of freedom.

Constrains the given degrees of freedom to move only along a normal direction, optionally with a correction function.

Public Members

vector<int> idof

The degrees of freedom the constraint applies to.

NormalFn normalFn

Function returning the constrained components of the normal vector.

CorrectionFn correction = nullptr

Optional function to correct the coordinates to satisfy the constraint.

struct Element

A single energy element, used for parallelisation of unstructured potentials.

Public Members

int type

The element type, used to select the energy calculation.

vector<int> idof

The degrees of freedom in the element.

vector<double> parameters

Any parameters of the element.

Constraints

vector<Constraint> constraints

The constraints applied to the state.

Potential &setConstraints(vector<int> iFix)

Constrain the given degrees of freedom to be fixed.

Potential &setConstraints(vector2d<int> idofs, vector<double> normal)

Constrain the given degrees of freedom to a linear constraint.

Potential &setConstraints(vector2d<int> idofs, Constraint::NormalFn normal, Constraint::CorrectionFn correction = nullptr)

Constrain the given degrees of freedom with a custom normal and correction function.

void applyConstraints(const vector<double> &coords, const Communicator &comm, vector<double> &step) const

Apply the constraints to a proposed step.

void correctConstraints(vector<double> &coords) const

Correct the coordinates to satisfy the constraints.

bool isFixed(int index) const

Whether the given degree of freedom is fixed.

vector<char> isFixed(const vector<int> &indicies) const

Whether each of the given degrees of freedom is fixed.

Energy elements

bool distributed = false

Whether the potential’s elements are distributed over processors.

vector<Element> elements

The energy elements used for parallelisation.

Potential &setElements(vector<Element> elements)

Set the elements for an unstructured potential.

Potential &setElements(vector2d<int> idofs)

Set the elements for an unstructured potential from degrees of freedom.

Potential &setElements(vector2d<int> idofs, vector<int> types, vector2d<double> parameters)

Set the elements for an unstructured potential from degrees of freedom, types, and parameters.

inline virtual void elementEnergyGradient(const vector<double> &coords, const Element &el, double *e, vector<double> *g) const

Compute the energy and gradient of a single element.

inline virtual void blockEnergyGradient(const vector<double> &coords, const Communicator &comm, double *e, vector<double> *g) const

Compute the energy and gradient of the local block.

Grid parameters

int dofPerNode = 1

Number of degrees of freedom per grid node.

int haloWidth = 1

Width of the halo region for grid potentials.

vector<int> gridSize

Size of the grid along each dimension.

vector<int> commArray

The number of processors along each grid dimension.

Potential &setCommArray(vector<int> commArray)

Set the number of processors along each grid dimension.