# Surface Evolver Documentation

## Named quantities and methods

This is the systematic scheme of calculating global quantities such as area, volume, and surface integrals that replaces the original ad hoc scheme in the Evolver. Briefly, methods are built-in functions, and named quantities are combinations of instances of methods. See the ringblob datafile for an example. The original ad hoc calculations are still the default where they exist, but all new quantities are being added in the named quantity scheme. Some new features will work only with named quantities. To convert everything to named quantities, start Evolver with the -q option or use the convert_to_quantities command. This has not been made the default since named quantities can be slower than the originals.

The sample datafiles qcube.fe, qmound.fe, and ringblob.fe contains some examples of named quantities and instances. The first two are quantity versions of cube.fe and mound.fe. These illustrate the most general and useful methods, namely facet_vector_integral, facet_scalar_integral, and edge_vector_integral, rather than the faster but more specialized methods such as facet_area. My advice is that the user stick to the old implicit methods for area, volume, and gravitational energy, and use named quantities only for specialized circumstances.

## Named methods

A "method" is a way of calculating a scalar value from some particular type of element (vertex, edge, facet, body). Each method is implemented internally as a set of functions for calculating the value and its gradient as a function of vertex positions. The most common methods also have Hessian functions. Methods are referred to by their names.

See Implemented methods for a list of available methods. Adding a new method involves writing C routines to calculate the value and the gradient (and maybe the Hessian) as functions of vertex coordinates, adding the function declarations to quantity.h, and adding a structure to the method declaration array in quantity.c. All the other syntax for invoking it from the datafile is already in place.

## Method instances

A "method instance" is the sum of a particular method applied to a particular set of geometric elements. Some methods (like facet_area) are completely self-contained. Others (like facet_vector_integral) require the user to specify some further information. For these, each instance has a specification of this further information. Method instances are defined in the datafile, and may either be unnamed parts of named quantity definitions or separate named method instances for inclusion in named quantities. The separate named version is useful if you want to inspect instance values for the whole surface or individual elements. An instance total value can be printed with the A commands, or may be referred to as "instancename.value" in commands. The instance name itself may be used as an element attribute. For example, supposing there is an instance named moment, which applies to facets. Then typical commands would be
  print moment.value
print facet[3].moment
list facet where moment > 0.1

Every method instance has a "modulus", which is multiplied times the basic method value to give the instance value. A modulus of 0 causes the entire instance calculation to be omitted whenever quantities are calculated. The modulus may be set in the datafile or with the A command or by assignment. Example commands:
  print moment.modulus
moment.modulus := 1.3


## Named quantities

A "named quantity" is the sum total of various method instances, although usually just one instance is involved. The instances need not apply to the same type of element; for example, both facet and edge integrals may be needed to define a volume quantity. Each named quantity is one of three types:
• "energy" quantities which are added to the total energy of the surface;
• "fixed" quantities that are constrained to a fixed target value (by Newton steps at each iteration); and
• "info_only" quantities whose values are merely reported to the user.
This type is initially set in a quantity's datafile declaration. A quantity can be toggled between fixed and info_only with the "fix quantityname" and "unfix quantityname" commands.

The value of a quantity may be displayed with the A or v commands, or as an expression "quantityname.value". Furthermore, using the quantity name as an element attribute evaluates to the sum of all the applicable component instance values on that element. For example, supposing there is a quantity named vol, one could do

  print vol.value
print facet[2].vol
histogram(facet,vol)


Each quantity has a "modulus", which is just a scalar multiplier for the sum of all instance values. A modulus of 0 will turn off calculation of all the instances. The modulus can be set in the datafile declaration, with the A command, or by assignment:

 quantityname.modulus := 1.2

Each fixed quantity has a target value, to which the Evolver attempts to constraint the quantity value. Each time an iteration is done ( g command or the various Hessian commands), Newton's Method is used to project the surface to the constrained values. The target value can be displayed with the A or v commands, or as "quantityname.target". It can be changed with the A command or by assignment. Example:

  print qname.target
qname.target := 3.12


A quantity can have a constant value added to it, similar to the body attribute volconst. This quantity attribute is also called volconst. It is useful for adding in known values of say integrals that are omitted from the actual calculation. It can be set in the quantity's datafile definition, or by an assignment command.

Each fixed quantity has a Lagrange multiplier associated to it. The Lagrange multiplier of a constraint is the rate of energy change with respect to the constraint target value. For a volume constraint, the Lagrange multiplier is just the pressure. Lagrange multipliers are calculated whenever an iteration step is done. They may be displayed with the v command in the "pressure" column, or as an expression "quantityname.pressure".

A fixed quantity can have a tolerance attribute, which is used to judge convergence. A surface is deemed converged when the sum of all ratios of quantity discrepancies to tolerances is less than 1. This sum also includes bodies of fixed volume. If the tolerance is not set or is negative, the value of the variable target_tolerance is used, which has a default value of 0.0001.

The sample datafile column.fe contains some examples of named quantities and instances.

It is planned that eventually all energies and global constraints will be converted to named quantity system. However, existing syntax will remain valid wherever possible. Starting Evolver with the -q option will do this conversion now.

## Implemented methods

The currently implemented methods are listed here, grouped somewhat by nature. Within each group, they are more or less in order of importance.

## Method descriptions

The descriptions below of the individual methods give a mathematical definition of the method, what type of element it applies to, definition parameters, which types of models it applies to, any restrictions on the dimension of ambient space, and whether the method has a Hessian implemented. Unless specifically noted, a method has the gradient implemented, and hence may be used for an energy or a constraint. The definition parameters are usually scalar or vector integrands (see the datafile declaration for full syntax). Some methods also depend on global variables as noted. The sample datafile declarations given are for simple cases; full syntax is given elsewhere. Remember in the samples that for quantities not declared global, the quantity has to be individually applied to the desired elements.

## 0-dimensional

### vertex_scalar_integral

Named method. Description: Function value at a vertex. This actually produces a sum over vertices, but as a mathematician, I think of a sum over vertices as a point-weighted integral. Element: vertex. Parameters: scalar_integrand. Models: linear, quadratic, Lagrange, simplex. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity point_value energy method vertex_scalar_integral
scalar_integrand: x^2 + y^2 - 2x + 3


## 1-dimensional

### edge_tension or edge_length

Named method. Description: Length of edge. Quadratic model uses Gaussian quadrature of order integral_order_1D. Element: edge. Parameters: none. Models: linear, quadratic, Lagrange. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity len energy method edge_length global


### density_edge_length

Named method. Description: Length of edge, multiplied by the edge density. Quadratic model uses Gaussian quadrature of order integral_order_1D. Element: edge. Parameters: none. Models: linear, quadratic, Lagrange. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity len energy method density_edge_length global


### edge_scalar_integral

Named method. Description: Integral of a scalar function over arclength. Uses Gaussian quadrature of order integral_order_1D. Element: Parameters: Models: linear, quadratic, Lagrange. Ambient dimension: any. Hessian: yes. Type: edge. Parameters: scalar_integrand. Example datafile declaration:
quantity edge_sint energy method edge_scalar_integral
scalar_integrand: x^2 - 3*y + 4


### edge_vector_integral

Named method. Description: Integral of a vectorfield over an oriented edge. Uses Gaussian quadrature of order integral_order_1D. Element: edge. Parameters: vector_integrand. Models: linear, quadratic, Lagrange. Ambient dimension: any. Hessian: yes. Orientable: yes. Example datafile declaration:
quantity edge_vint energy method edge_vector_integral
vector_integrand:
q1: 0
q2: 0
q3: z^2/2


### edge_general_integral

Named method. Description: Integral of a scalar function of position and tangent over an edge. The components of the tangent vector are represented by continuing the coordinate indices. That is, in 3D the position coordinates are x1,x2,x3 and the tangent components are x4,x5,x6. For proper behavior, the integrand should be homogeneous of degree 1 in the tangent components. Uses Gaussian quadrature of order integral_order_1D. Element: edge. Parameters: scalar_integrand. Models: linear, quadratic, Lagrange. Ambient dimension: any. Hessian: yes. Example datafile declaration: the edge length in 3D could be calculated with this quantity:
quantity arclength energy method edge_general_integral
scalar_integrand: sqrt(x4^2 + x5^2 + x6^2)


### edge_area

Named method. Description: For calculating the area of a body in the string model. Implemented as the exact integral of -y dx over the edge. Valid for torus model, but not general symmetry groups. You may have to set the quantity volconst attribute in the torus model, since the area calculation is ambiguous up to one torus area. Element: edge. Parameters: none. Models: linear, quadratic, Lagrange. Ambient dimension: 2. Hessian: yes. Example datafile declaration:
quantity cell1_area fixed = 1.3 method edge_area


### edge_torus_area

Named method. Description: For 2D torus string model body area calculations. Contains adjustments for torus wraps. You may have to set the quantity volconst attribute in the torus model, since the area calculation is ambiguous up to one torus area. Element: edge. Parameters: none. Models: torus; string; linear,quadratic,Lagrange. Ambient dimension: 2. Hessian: no. Example datafile declaration:
quantity cell_area fixed = 1.3 method edge_torus_area


### string_gravity

Named method. Description: To calculate the gravitational potential energy of a body in the string model. Uses differences in body densities. Does not use gravitational constant G as modulus (unless invoked as internal quantity by convert_to_quantities). Element: edge. Parameters: none. Models: string linear, quadratic, lagrange. Ambient dimension: 2. Hessian: yes. Orientable: yes. Example datafile declaration:
quantity cell_grav energy modulus 980*8.5 method string_gravity


### hooke_energy

Named method. Description: One would often like to require edges to have fixed length. The total length of some set of edges may be constrained by defining a fixed quantity. This is used to fix the total length of an evolving knot, for example. But to have one constraint for each edge would be impractical, since projecting to n constraints requires inverting an n x n matrix. Instead there is a Hooke's Law energy available to encourage edges to have equal length. Its form per edge is
   E =  | L - L_0| ^p

where L is the edge length, L_0 is the equilibrium length, embodied as an adjustable parameter hooke_length', and the power p is an adjustable parameter hooke_power'. The default power is p = 2, and the default equilibrium length is the average edge length in the initial datafile. You will want to adjust this, especially if you have a total length constaint. A high modulus will decrease the hooke component of the total energy, since the restoring force is linear in displacement and the energy is quadratic (when p=2). As an extra added bonus, a hooke_power' of 0 will give
 E = -\log|L-L_0|.
See hooke2_energy for individual edge equilibrium lengths. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
parameter hooke_length 0.3   // will apply to all edges
parameter hooke_power  2     // the default
quantity slinky energy method hooke_energy global


### hooke2_energy

Named method. Description: Same as hooke_energy, but each edge has an equilibrium length extra attribute hooke_size' (which the user need not declare). If the user does not set hooke_size by the time the method is first called, the value will default to the current length. Hooke_size is not automatically adjusted by refining. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
parameter hooke_power  2     // the default
quantity slinky energy method hooke2_energy global
...
r;r;set edge hooke_size length


### hooke3_energy

Named method. Description: Same as hooke2_energy, but uses an elastic model instead of a spring. The energy is
energy = 0.5*(length-hooke_size)^2/hooke_size.
The exponent can be altered from 2 by setting the parameter hooke3_power. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
parameter hooke3_power  2     // the default
quantity slinky energy method hooke3_energy global
...
r;r;set edge hooke_size length


### local_hooke_energy

Named method. Description: Energy of edges as springs with equilibrium length being average of lengths of neighbor edges. Actually, the energy is calculated per vertex,
 E = ({L_1 - L_2 \over L_1 + L_2})^2

where L_1 and L_2 are the lengths of the edges adjacent to the vertex. Meant for loops of string. (by John Sullivan) Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity slinky energy method local_hooke_energy global


### dihedral_hooke

Named method. Description: Energy of an edge is edge length times square of angle between normals of adjacent facets. Actually, e = (1 - cos(angle))*length. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity bender energy method dihedral_hooke global


### sqcurve_string

Named method. Description: Integral of squared curvature in string model. Assumes two edges per vertex, so don't use with triple points. Value zero at endpoint of curve. Calue is calculated as if the exterior angle at the vertex is evenly spread over the adjacent half-edges. More precisely, if s1 and s2 are the adjacent edge lengths and t is the exterior angle, value = 4*(1 - cos(t))/(s1+s2). Other powers of the curvature can be specified by using the parameter parameter_1 in the instance definition. Element: vertex. Parameters: parameter_1. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity sq energy method sqcurve_string global
parameter_1 3


### metric_edge_length

Named method. Description: In the string model with a Riemannian metric, this is the length of an edge. Element: edge. Parameters: none. Models: linear,quadratic,simplex. Ambient dimension: any. Hessian: yes. Example datafile declaration:
string
space_dimension 2
metric
1+x^2 y
y   1+y^2
quantity mel energy method metric_edge_length global


### klein_length

Named method. Description: Edge length in Klein hyperbolic plane model. Does not depend on klein_metric being declared. Vertices should be inside unit sphere. Element: edge. Parameters: none. Models: linear. Ambient dimension: 2. Hessian: no. Example datafile declaration:
quantity kleinlen energy method klein_length global


## 2-dimensional

### facet_tension, facet_area

Named method. Description: Area of facet. Does not multiply by facet density; density_facet_area does that. Quadratic model uses Gaussian cubature of order integral_order_2D. Beware that this is an approximation to the area, and if the facets in the quadratic or Lagrange model get too distorted, it can be a bad approximation. Furthermore, facets can distort themselves in seeking the lowest numerical area. By default, changing the model to quadratic or Lagrange will set an appropriate integral_order_2D. Element: facet. Parameters: none. Models: linear, quadratic, Lagrange, simplex. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity farea energy method facet_area global


### density_facet_area

Named method. Description: Area of facet, multiplied by its density. Otherwise same as facet_area. Element: Parameters: Models: linear, quadratic, Lagrange, simplex. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity farea energy method density_facet_area global


### facet_volume

Named method. Description: Integral of z dx dy over an oriented facet. Valid in the torus domain. Not valid for other symmetry groups. You may have to set the quantity volconst attribute in the torus model, since the volume calculation is ambiguous up to one torus volume. Element: facet. Parameters: none. Models: linear, quadratic, Lagrange. Ambient dimension: 3. Hessian: yes. Orientable: yes. Example datafile declaration:
quantity vol fixed = 1.3 method facet_volume


### facet_scalar_integral

Named method. Description: Integral of a scalar function over facet area. Uses Gaussian cubature of order integral_order_2D. Element: facet. Parameters: scalar_integrand. Models: linear, quadratic, Lagrange. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity fint energy method facet_scalar_integral global
scalar_integrand: x^2+y^2


### facet_vector_integral

Named method. Description: Integral of a vectorfield inner product with the surface normal over a facet. The normal is the right-hand rule normal of the facet as defined in the datafile. Uses Gaussian cubature of order integral_order_2D. Element: facet. Parameters: vector_integrand. Models: linear, quadratic, Lagrange, simplex. Ambient dimension: any. Hessian: yes. Orientable: yes. Example datafile declaration, for volume equivalent:
quantity fvint energy method facet_vector_integrand
vector_integrand:
q1: 0
q2: 0
q3: z


### facet_2form_integral

Named method. Description: Integral of a 2-form over a facet. Meant for ambient dimensions higher than 3. Uses Gaussian cubature of order integral_order_2D. Element: facet. Parameters: form_integrand (components in lexicographic order). Models: linear, Lagrange, simplex. Ambient dimension: any. Hessian: yes. Orientable: yes. Example datafile declaration in 4D:
quantity formex energy method facet_2form_integral
form_integrand:
q1: x2     // 12 component
q1: 0      // 13 component
q1: x4     // 14 component
q1: 0      // 23 component
q1: 0      // 24 component
q1: x3*x2  // 34 component


### facet_general_integral

Named method. Description: Integral of a scalar function of position and normal vector over a facet. Uses Gaussian cubature of order integral_order_2D. The components of the normal vector are represented by continuing the coordinate indices. That is, in 3D the position coordinates are x1,x2,x3 and the normal components are x4,x5,x6. For proper behavior, the integrand should be homogeneous of degree 1 in the normal components. Element: facet. Parameters: scalar_integrand. Models: linear, quadratic, Lagrange. Ambient dimension: any. Hessian: yes. Example: The facet area could be calculated with this quantity:
quantity arclength energy method edge_general_integral
scalar_integrand: sqrt(x4^2 + x5^2 + x6^2)


### facet_torus_volume

Named method. Description: For 3D soapfilm model, calculates body volume integral for a facet, with corrections for edge wraps. You may have to set the quantity volconst attribute in the torus model, since the volume calculation is ambiguous up to one torus volume. Element: facet. Parameters: none. Models: linear,quadratic,lagrange. Ambient dimension: 3. Hessian: yes. Orientable: yes. Example datafile declaration:
quantity body_vol energy method facet_torus_volume


### gravity_method, full_gravity_method

Named method. Description: Gravitational energy, integral of p z^2/2 dxdy over a facet, where p is difference in adjacent body densities. Note: this method uses the gravitational constant as the modulus if invoked as full_gravity_method. Just gravity_method does not automatically use the gravitational constant. Element: facet. Parameters: none. Models: linear, quadratic, Lagrange. Ambient dimension: 3. Hessian: yes. Orientable: yes. Example datafile declaration:
quantity grav energy modulus 980*8.5 method gravity_method


### facet_area_u, density_facet_area_u

Named method. Description: Area of facet. In quadratic model, it is an upper bound of area, by the Schwarz Inequality. For the paranoid. Same as facet_area in linear model. Sets integral_order_2D to 6, since it doesn't work well with less. Using the density_facet_area_u name automatically incorporates the facet tension, but facet_area_u doesn't. Element: facet. Parameters: none. Models: linear, quadratic. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity area_u energy method facet_area_u global


### gap_energy

Named method. Description: Implementation of gap energy, which is designed to keep edges from short-cutting curved constraint surfaces. This method serves the same purpose as declaring a constraint convex. Automatically incorporates the gap_constant set in the datafile or by the k command. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity gappy energy method gap_energy global


### metric_facet_area

Named method. Description: For a Riemannian metric, this is the area of a facet. Element: edge. Parameters: none. Models: linear,quadratic,simplex. Ambient dimension: any. Hessian: yes. Example datafile declaration:
metric
1+x^2 0 z
0 1+y^2 0
z 0 1+z^2
quantity mfa energy method metric_facet_area global


### klein_area

Named method. Description: Facet area in Klein hyperbolic 3D space model. Does not depend on klein_metric being declared in the datafile. Vertices should be inside the unit sphere. Element: facet. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity kleinarea energy method klein_area global


### dirichlet_area

Named method. Description: Same as the facet_tension method, but the Hessian is modified to be guaranteed positive definite, after the scheme of Polthier and Pinkall [PP]. The energy is taken to be the Dirichlet integral of the perturbation from the current surface, which is exactly quadratic and positive definite. Hence the hessian command always works, but final convergence may be slow (no faster than regular iteration) since it is only an approximate Hessian. Also see the dirichlet command. Element: facet. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity dirarea energy method dirichlet_area global


### sobolev_area

Named method. Description: Same as the facet_tension method, but the Hessian is modified to be guaranteed positive definite, after the scheme of Renka and Neuberger. [RN]. Hence the hessian command always works, but final convergence may be slow (no faster than regular iteration) since it is only an approximate Hessian. Also see the sobolev command. Element: facet. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity sobarea energy method sobolev_area global


### pos_area_hess

Named method. Description: Same as the facet_area method, but the Hessian can be adjusted various ways by setting the variables fgagfa_coeff, gfa_2_coeff, gfagfa_coeff, and gfaafg_coeff. This will make sense if you look at the Dirichlet section of the Technical Reference chapter of the printed manual. The default values of the coefficients are -1, 1, -1, and 0 respectively. Element: facet. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity parea energy method pos_area_hess global


### spherical_area

Named method. Description: Area of the facet projected to unit sphere. The vertices of the facet are assumed to be on the unit sphere. Element: facet. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity spharea energy method spherical_area global


## Surface curvature functions

### mean_curvature_integral

Named method. Description: Integral of signed scalar mean curvature of a 2D surface. The computation is exact, in the sense that for a polyhedral surface the mean curvature is concentrated on edges and singular there, but the total mean curvature for an edge is the edge length times its dihedral angle. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity mci energy method mean_curvature_integral


### sq_mean_curvature

Named method. Description: Integral of squared mean curvature of a surface. The integral of squared mean curvature in the soapfilm model is calculated as follows: Each vertex v has a star of facets around it of area A_v. The force due to surface tension on the vertex is
   F_v = -{\partial A_v \over \partial v}.
Since each facet has 3 vertices, the area associated with v is A_v/3. Hence the average mean curvature at v is
   h_v = {1\over 2}{F_v\over A_v/3},
and this vertex's contribution to the total integral is
E_v = h_v^2 A_v/3 = {1\over 4}{F_v^2 \over A_v/3}.
Philosophical note: The squared mean curvature on a triangulated surface is technically infinite, so some kind of approximation scheme is needed. The alternative to locating curvature at vertices is to locate it on the edges, where it really is, and average it over the neighboring facets. But this has the problem that a least area triangulated surface would have nonzero squared curvature, whereas in the vertex formulation it would have zero squared curvature.
Practical note: The above definition of squared mean curvature seems in practice to be subject to instablities. One is that sharp corners grow sharper rather than smoothing out. Another is that some facets want to get very large at the expense of their neighbors. Hence a couple of alternate definitions have been added.
Curvature at boundary: If the edge of the surface is a free boundary on a constraint, then the above calculation gives the proper curvature under the assumption the surface is continued by reflection across the constraint. This permits symmetric surfaces to be represented by one fundamental region. If the edge of the surface is a fixed edge or on a 1-dimensional boundary, then there is no way to calculate the curvature on a boundary vertex from knowledge of neighboring facets. For example, the rings of facets around the bases of a catenoid and a spherical cap may be identical. Therefore curvature is calculated only at interior vertices, and when the surface integral is done, area along the boundary is assigned to the nearest interior vertex. However, including IGNORE_FIXED or IGNORE_CONSTRAINTS in the method declaration will force the calculation of energy even at fixed points or ignoring constraints respectively.
If the parameter h_zero is defined, then the value per vertex is the same as for the following method, eff_area_sq_mean_curvature.
Element: vertex. Parameters: IGNORE_CONSTRAINTS, IGNORE_FIXED. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity sqc energy method sq_mean_curvature global


### eff_area_sq_mean_curvature

Named method. Description: Integral of squared mean curvature of a surface, with a slightly different definition from sq_mean_curvature or normal_sq_mean_curvature. The area around a vertex is taken to be the magnitude of the gradient of the volume. This is less than the true area, so makes a larger curvature. This also eliminates the spike instability, since a spike has more area gradient but the same volume gradient. Letting N_v be the volume gradient at vertex v,
   h_v = {1\over 2}{F_v \over ||N_v||/3},
and
  E_v = h_v^2 A_v/3 =  {3\over 4}{F_v^2 \over ||N_v||^2}A_v.
The facets of the surface must be consistently oriented for this to work, since the evolver needs an inside' and outside' of the surface to calculate the volume gradient. There are still possible instabilities where some facets grow at the expense of others.
If the parameter {\tt h\_zero} is defined, then the value per vertex is
  E_v = (h_v-h_0)^2 A_v/3 =
3\left({F_v\cdot N_v \over 2 ||N_v||^2}-h_0\right)^2A_v. 
This does not reduce to the non-h_zero formula when h_zero has the value zero, but users should feel lucky to have any h\_zero version at all.
If the vertex is on one or several constraints, the F_v and N_v are projected to the constraints, essentially making the constraints act as mirror symmetry planes.
WARNING: For some extreme shapes, Evolver may have problems detecting consistent local surface orientation. The assume_oriented toggle lets Evolver assume that the facets have been defined with consistent local orientation.
Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity effsq energy method eff_area_sq_mean_curvature global


### normal_sq_mean_curvature

Named method. Description: Integral of squared mean curvature of a surface, with a slightly different definition from sq_mean_curvature or eff_area_sq_mean_curvature. To alleviate the instability of eff_area_sq_mean_curvature, normal_sq_mean_curvature considers the area around the vertex to be the component of the volume gradient parallel to the mean curvature vector, rather than the magnitude of the volume gradient. Thus
  h_v = {1\over 2}{F_v ||F_v|| \over N_v\cdot F_v /3}

E_v = {3\over 4}[F_v \cdot F_v \over N_v \cdot F_v]^2 A_v. 
This is still not perfect, but is a lot better. WARNING: For some extreme shapes, Evolver may have problems detecting consistent local surface orientation. The assume_oriented toggle lets Evolver assume that the facets have been defined with consistent local orientation.
If the parameter h_zero is defined, then the value per vertex is
  E_v = (h_v-h_0)^2 A_v/3 =
\left[{3\over 2}{F_v^2  \over N_v\cdot F_v } - h_0\right]^2{A_v \over 3} 
If the vertex is on one or several constraints, the F_v and N_v are projected to the constraints, essentially making the constraints act as mirror symmetry planes.
Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity nsq energy method normal_sq_mean_curvature global


### star_sq_mean_curvature

Named method. Description: Integral of squared mean curvature over a surface. This is a different implementation of sq_mean_curvature which is more suitable for parallel calculation and has a Hessian. But assumes a closed surface i.e. each vertex it is applied to should have a complete star of facets around it. This method does not use the h_zero parameter.
Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity starsq energy method star_sq_mean_curvature global


### star_eff_area_sq_mean_curvature

Named method. Description: Integral of squared mean curvature over a surface. This is a different implementation of eff_area_sq_mean_curvature which is more suitable for parallel calculation and has a Hessian. But assumes a closed surface i.e. each vertex it is applied to should have a complete star of facets around it. This method does not use the h_zero parameter.
Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity seffsq energy method star_eff_area_sq_mean_curvature global


### star_normal_sq_mean_curvature

Named method. Description: Integral of squared mean curvature over a surface. This is a different implementation of normal_sq_mean_curvature which is more suitable for parallel calculation and has a Hessian. But assumes a closed surface, i.e. each vertex it is applied to should have a complete star of facets around it. This method can use the h_zero parameter.
Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
quantity stnsq energy method star_normal_sq_mean_curvature global


### gauss_curvature_integral

Named method. Description: This computes the total Gaussian curvature of a surface with boundary. The Gaussian curvature of a polyhedral surface may be defined at an interior vertex as the angle deficit of the adjacent angles. But as is well-known, total Gaussian curvature can be computed simply in terms of the boundary vertices, which is what is done here. The total Gaussian curvature is implemented as the total geodesic curvature around the boundary of the surface. The contribution of a boundary vertex is
E =  (\sum_i \theta_i) - \pi.
The total over all boundary vertices is exactly equal to the total angle deficit of all interior vertices plus 2\pi\chi, where \chi is the Euler characteristic of the surface. Element: facet. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity gint energy method gauss_curvature_integral global


### sq_gauss_curvature

Named method. Description: Computes the integral of the squared Gaussian curvature. At each vertex, the Gaussian curvature is calculated as the angle defect divided by one third of the total area of the adjacent facets. This is then squared and weighted with one third of the area of the adjacent facets. This method works only on closed surfaces with no singularities due to the way it calculates the angle defect. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity sqg energy method sq_gauss_curvature global


## Simplex model methods

### simplex_vector_integral

Named method. Description: Integral of a vectorfield over a (n-1)-dimensional simplicial facet in n-space. Vectorfield is dotted with normal of facet; actually the side vectors of the simplex and the integrand vector are formed into a determinant. Element: facet. Parameters: vector_integrand. Models: simplex. Ambient dimension: any. Hessian: no. Orientable: yes. Example datafile declaration, for 4-volume under a 3D surface in 4D:
quantity xvint energy method simplex_vector_integral
vector_integrand:
q1: 0
q2: 0
q3: 0
q4: x4


### simplex_k_vector_integral

Named method. Description: Integral of a simple (n-k)-vector over an oriented k-dimensional simplicial facet in n-space. The vector integrand lists the components of each of the k vectors sequentially. Evaluation is done by forming a determinant whose first k rows are k vectors spanning the facet, and last (n-k) rows are vectors of the integrand. Element: facet. Parameters: k_vector_order, vector_integrand. Models: simplex. Ambient dimension: any. Hessian: yes. Orientable: yes. Example datafile declaration, for 3D surface in 5D:
quantity kvec energy method simplex_k_vector_integral
k_vector_order 3
vector_integrand:
q1: 0   // first vector
q2: 0
q3: 0
q4: 0
q5: x4
q6: 0   // second vector
q7: 0
q8: 0
q9: x3
q10: 0


### edge_k_vector_integral

Named method. Description: Integral of a simple (n-k)-vector over an oriented k-dimensional simplicial edge in n-space. The vector integrand lists the components of each of the k vectors sequentially. Evaluation is done by forming a determinant whose first k rows are k vectors spanning the edge, and last (n-k) rows are vectors of the integrand. Element: edge. Parameters: k_vector_order, vector_integrand. Models: linear, quadratic, simplex. Ambient dimension: any. Hessian: yes. Orientable: yes. Example datafile declaration, for 3D edges of a 4D surface in 5D:
quantity kvec energy method edge_k_vector_integral
k_vector_order 3
vector_integrand:
q1: 0   // first vector
q2: 0
q3: 0
q4: 0
q5: x4
q6: 0   // second vector
q7: 0
q8: 0
q9: x3
q10: 0


### knot_energy

Named method. Description: An electrostatic'' energy in which vertices are endowed with equal charges. Inverse power law of potential is adjustable via the global parameter knot_power', default value 2 (which is not electrostatic, but the knot theorists like it). If the extra attribute node_charge' is defined for vertices, then that value is used for the vertex charge. Use of this energy is not restricted to knots; it has been used to embed complicated network graphs in space. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: yes. Example datafile declaration:
parameter knot_power  2     // the default
quantity knotten energy method knot_energy global


### uniform_knot_energy or edge_knot_energy

Named method. Description: A knot energy where vertex charge is proportional to neighboring edge length. This simulates an electrostatic charge uniformly distributed along a wire. Inverse power law of potential is adjustable via the global parameter knot_power' (default 2). Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knotten energy method uniform_knot_energy global


### uniform_knot_energy_normalizer

Named method. Description: Supposed to approximate the part of uniform_knot_energy that is singular in the continuous limit. Element: vertex. Parameters: Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knottenorm energy method uniform_knot_energy global
method uniform_knot_energy_normalizer global


### uniform_knot_normalizer1

Named method. Description: Calculates internal knot energy to normalize singular divergence of integral of uniform_knot_energy. Actually a synonym for uniform_knot_energy_normalizer. No gradient. Element: vertex. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knottenorm energy method uniform_knot_energy global
method uniform_knot_energy_normalizer1 global


### uniform_knot_normalizer2

Named method. Description: Calculates internal knot energy to normalize singular divergence of integral of uniform_knot_energy a different way from uniform_knot_energy_normalizer. Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knottenorm energy method uniform_knot_energy global
method uniform_knot_energy_normalizer2 global


### edge_edge_knot_energy

Named method. Description: Between pairs of edges, energy is inverse square power of distance between midpoints of edges. Can also be called just edge_knot_energy. See also edge_knot_energy_normalizer. (by John Sullivan) Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity knotten energy method edge_edge_knot_energy global


### edge_knot_energy_normalizer

Named method. Description: Calculates internal knot energy to normalize singular divergence of integral of edge_edge_knot_energy. Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity knotten energy method edge_edge_knot_energy global
method edge_knot_energy_normalizer global


### simon_knot_energy_normalizer

Named method. Description: Another normalization of edge_knot_energy, which I don't feel like deciphering right now. Element: edge. Parameters: none. Models: string linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity kenergy energy method edge_knotenergy global
method simon_knot_energy_normalizer global


### facet_knot_energy

Named method. Description: Charge on vertex is proportional to area of neighboring facets. Meant for knotted surfaces in 4D. Power law of potential is adjustable via the global parameter knot_power'. See also facet_knot_energy_fix. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knotten energy method facet_knot_energy global


### facet_knot_energy_fix

Named method. Description: Provides adjacent vertex correction to facet_knot_energy. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knotten energy method facet_knot_energy global
method facet_knot_energy_fix global


### buck_knot_energy

Named method. Description: Energy between pair of edges given by formula suggested by Greg Buck. Power law of potential is adjustable via the global parameter knot_power'. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knotten energy method buck_knot_energy global


### proj_knot_energy

Named method. Description: This energy is due to Gregory Buck. It tries to eliminate the need for a normalization term by projecting the energy to the normal to the curve. Its form is
   E_{e_1e_2} = {L_1L_2 \cos^p\theta\over |x_1 - x_2|^p}

where x_1,x_2 are the midpoints of the edges and \theta is the angle between the normal plane of edge e_1 and the vector x_1 - x_2. The default power is 2. Power law of potential is adjustable via the global parameter knot_power'. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knotten energy method proj_knot_energy global


### circle_knot_energy

Named method. Description: This energy is due to Peter Doyle, who says it is equivalent in the continuous case to the insulating wire with power 2. Its form is
  E_{e_1e_2} = {L_1L_2 (1 - \cos\alpha)^2 \over |x_1 - x_2|^2},

where x_1,x_2 are the midpoints of the edges and \alpha is the angle between edge 1 and the circle through x_1 tangent to edge 2 at x_2. Only power 2 is implemented. Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity knotten energy method circle_knot_energy global


### sphere_knot_energy

Named method. Description: This is the 2D surface version of the circle energy. Its most general form is
  E_{f_1f_2} = { A_1A_2(1 - \cos\alpha)^p \over |x_1 - x_2|^q},

where A_1,A_2 are the facet areas, x_1,x_2 are the barycenters of the facets, and \alpha is the angle between f_1 and the sphere through x_1 tangent to f2 at x_2. The energy is conformally invariant for p = 1 and q = 4. For p=0 and q=1, one gets electrostatic energy for a uniform charge density. Note that facet self-energies are not included. For electrostatic energy, this is approximately 2.8A^{3/2} per facet. The powers p and q are Evolver variables surface_knot_power and surface_cos_power respectively. The defaults are p=1 and q=4. Element: facet. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter surface_knot_power  1     // the default
parameter surface_cos_power  4     // the default
quantity knotten energy method sphere_knot_energy global


### sin_knot_energy

Named method. Description: Another weird way to calculate a nonsingular energy between midpoints of pairs of edges. (by John Sullivan) Element: edge. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity knotten energy method sin_knot_energy global


### curvature_binormal

Named method. Description: For string model. The energy evaluates to zero, but the force calculated is the mean curvature vector rotated to the binormal direction. Element: vertex. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity curbi energy method curvature_binormal global


### ddd_gamma_sq

Named method. Description: Third derivative of curve position as function of arclength, squared. Element: vertex. Parameters: none. Models: string, linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity ddd energy method ddd_gamma_sq global


### edge_min_knot_energy

Named method. Description: Between pairs of edges, energy is inverse square power of distance between closest points of edges.
    Energy = 1/d^2 * |e1||e2|

This should be roughly the same as edge_edge_knot_energy, but distances are calculated from edge midpoints there. This is not a smooth function, so we don't try to compute a gradient. DO NOT use as an energy; use just for info_only quantities. Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity eminknot info_only method edge_min_knot_energy global


### true_average_crossings

Named method. Description: Calculates the average crossing number of an edge with respect to all other edges, averaged over all projections. Knot stuff. No gradient, so use just in info_only quantities. Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity true_cross info_only method true_average_crossings global


### true_writhe

Named method. Description: For calculating the writhe of a link or knot. No gradient, so use just in info_only quantities. Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity twrithe info_only method true_average_crossings global


### twist

Named method. Description: Another average crossing number calculation. No gradient, so use just in info_only quantities. Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity twister info_only method twist global


### writhe

Named method. Description: An average crossing number calculation. This one does have a gradient. Suggested by Hermann Gluck. Programmed by John Sullivan. Between pairs of edges, energy is inverse cube power of distance between midpoints of edges, times triple product of edge vectors and distance vector.
     E = 1/d^3 * (e1,e2,d)

Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity writhy energy method writhe global


### curvature_function

Named method. Description: Calculates forces as function of mean and Gaussian curvatures at vertices. Function may be changed by user by altering teix.c. No energy, just forces. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity curfun energy method curvature_function global


### average_crossings

Named method. Description: To calculate the average crossing number in all projections of a knot. (by John Sullivan) Element: edge. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity across energy method average_crossings global


## Weird and miscellaneous

### wulff_energy

Named method. Description: Method version of wulff energy. If Wulff filename is not given in top section of datafile, then the user will be prompted for it. Element: facet. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
wulff "crystal.wlf"
quantity wolf energy method wulff_energy global


### linear_elastic

Named method. Description: To calculate the linear elastic strain energy energy for facets based on the Cauchy-Green strain matrix. Let S be Gram matrix of unstrained facet (dots of sides). Let Q be the inverse of S. Let F be Gram matrix of strained facet. Let C = (FQ-I)/2, the Cauchy-Green strain tensor. Let v be Poisson ratio. Then energy density is
(1/2/(1+v))(Tr(C^2) + v*(Tr C)^2/(1-(dim-1)*v))
Each facet has extra attribute poisson_ratio and extra attribute array form_factors[3] = {s11,s12,s22}, which are the entries in S. That is, s11 = dot(v2-v1,v2-v1), s12 = dot(v2-v1,v3-v1), and s22 = dot(v3-v1,v3-v1). If form_factor is not defined by the user, it will be created by Evolver, and the initial facet shape will be assumed to be unstrained. Element: facet. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: yes. Example datafile declaration:
quantity lastic energy method linear_elastic global


### linear_elastic_B

Named method. Description: A variation of the linear_elastic method. To calculate the linear elastic strain energy energy for facets based on the Cauchy-Green strain matrix. Let S be Gram matrix of unstrained facet (dots of sides). Let Q be the inverse of S. Let F be Gram matrix of strained facet. Let C = (FQ-I)/2, the Cauchy-Green strain tensor. Let v be Poisson ratio. Then energy density is
(1/2/(1+v))(Tr(C^2) + v*(Tr C)^2/(1-(dim-1)*v))
Each facet has extra attribute poisson_ratio and each vertex has two extra coordinates, the coordinates of the unstrained surface in a plane. Hence the surface must be set up as five dimensional. Element: facet. Parameters: none. Models: linear. Ambient dimension: 5. Hessian: yes. Example datafile declaration:
space_dimension 5
quantity lastic energy method linear_elastic_B global


### area_square

Named method. Description: Energy of a facet is the square of the facet area. Element: facet. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity asquare energy method area_square global


### carter_energy

Named method. Description: Craig Carter's energy. pre> Given bodies $B_1$ and $B_2$ in $R^3$, define the energy E = \int_{B_1}\int_{B_2} {1 \over |z_1 - z_2|^{p} } d^3 z_2 d^3 z_1 This reduces to E = {1\over (3-p)(2-p)}\sum_{F_2\in\partial B_2}\sum_{F_1\in\partial B_1} N_1 \cdot N_2 \int_{F_2}\int_{F_1}{1\over |z_1 - z_2|^{p-2}} d^2 z_1 d^2 z_2. And if we crudely approximate with centroids $\bar z_1$ and $\bar z_2$, E = {1\over (3-p)(2-p)}\sum_{F_2\in\partial B_2}\sum_{F_1\in\partial B_1} {A_1 \cdot A_2 \over |\bar z_1 - \bar z_2|^{p-2}}, where $A_1$ and $A_2$ are unnormalized area vectors for the facets. The power p is set by the variable carter_power (default 6). Element: facet. Parameters: none. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
parameter carter_power  6     // the default
quantity craig energy method carter_energy global


Named method. Description: This energy is the gradient^2 of the knot_energy method, assuming the points are constrained to the unit sphere. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
parameter knot_power  2     // the default
quantity knotten energy method knot_energy global


### johndust

Named method. Description: For all point pairs (meant to be on a sphere),
       E = (pi - asin(d/2))/d,

where d is chord distance. For point packing problems on the sphere. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
constraint 1 formula: x^2+y^2+z^2 = 1
quantity jms energy method johndust global


### stress_integral

Named method. Description: Hmm. Looks like this one calculates integrals of components of a stress tensor. The scalar_integrand value is set as an integer standing for which component to do (a kludge). See the function stress_integral in method3.c for details. Does not have a gradient, so should be used for just info_only quantities. Element: facet. Parameters: scalar_integrand. Models: linear. Ambient dimension: 3. Hessian: no. Example datafile declaration:
quantity stressy info_only method stress_integral global
scalar_integrand: 3


### ackerman

Named method. Description: Not actually an energy, but a kludge to put inertia on vertices. Uses extra velocity coordinates to represent vertex in phase space. Invocation actually transfers computed forces from space coordinates to velocity coordinates, so forces become acceleration instead of velocity. Element: vertex. Parameters: none. Models: linear. Ambient dimension: any. Hessian: no. Example datafile declaration:
quantity jeremy energy method ackerman global