# Example: Column of liquid solder

Here we have a tiny drop of liquid solder that bridges between two parallel, horizontal planes at z = 0 and z = `ZH`. On each plane there is a circular pad that the solder perfectly wets, and the solder is perfectly nonwetting off the pads. This would be just a catenoid problem with fixed volume, except that the pads are offset, and it is desired to find out what aligning force the solder exerts. The surface is defined the same way as in the catenoid example, except the lower boundary ring has a shift variable `SHIFT` in it to provide an offset in the y direction. This makes the shift adjustable at run time. Since the top and bottom facets of the body are not included, the constant volume they account for is provided by content integrals around the upper boundary, and the gravitational energy is provided by an energy integral. One could use the volconst attribute of the body instead for the volume, but then one would have to reset that every time `ZH` changed.

The interesting part of this example is the calculation of the forces. One could incrementally shift the pad, minimize the energy at each shift, and numerically differentiate the energy to get the force. Or one could set up integrals to calculate the force directly. But the simplest method is to use the Principle of Virtual Work by shifting the pad, recalculating the energy without re-evolving, and correcting for the volume change. Re-evolution is not necessary because when a surface is at an equilibrium, then by definition any perturbation that respects constraints does not change the energy to first order. To adjust for changes in constraints such as volume, the Lagrange multipliers (pressure for the volume constraint) tell how much the energy changes for given change in the constraints:

```          DE = L*DC
```
where `DE` is the energy change, `L` is the row vector of Lagrange multipliers and `DC` is the column vector of constraint value changes. Therefore, the adjusted energy after a change in a parameter is
```          E_adj = E_raw - L*DC
```
where `E_raw` is the actual energy and `DC` is the vector of differences of constraint values from target values. The commands `do_yforce` and `do_zforce` in the datafile do central difference calculations of the forces on the top pad, and put the surface back to where it was originally. Note that the perturbations are made smoothly, i.e. the shear varies linearly from bottom to top. This is not absolutely necessary, but it gives a smoother perturbation and hence a bit more accuracy.
 The initial column skeleton, with vertices and edges numbered.
```// column.fe
// Example of calculating forces exerted by a
// column of liquid solder in shape of skewed catenoid.

// All units cgs
parameter ZH = 0.08      // total height
parameter SHIFT = 0.025    // shift
#define SG 8      // specific gravity of solder
#define TENS 460  // surface tension of solder
#define GR  980   // acceleration of gravity

gravity_constant GR

BOUNDARY 1  PARAMETERS 1
X3: ZH
CONTENT  // used to compensate for missing top facets
c1: 0
c2: -ZH*x
c3: 0
ENERGY  // used to compensate for gravitational energy under top facets
e1: 0
e2: GR*ZH^2/2*x
e3: 0

BOUNDARY 2  PARAMETERS 1
X3: 0

vertices   // given in terms of boundary parameter
1    0.00  boundary 1   fixed
2    pi/3  boundary 1   fixed
3  2*pi/3  boundary 1   fixed
4    pi    boundary 1   fixed
5  4*pi/3  boundary 1   fixed
6  5*pi/3  boundary 1   fixed
7    0.00  boundary 2   fixed
8    pi/3  boundary 2   fixed
9  2*pi/3  boundary 2   fixed
10   pi    boundary 2   fixed
11 4*pi/3  boundary 2   fixed
12 5*pi/3  boundary 2   fixed

edges
1    1  2  boundary 1   fixed
2    2  3  boundary 1   fixed
3    3  4  boundary 1   fixed
4    4  5  boundary 1   fixed
5    5  6  boundary 1   fixed
6    6  1  boundary 1   fixed
7    7  8  boundary 2   fixed
8    8  9  boundary 2   fixed
9    9  10 boundary 2   fixed
10   10 11 boundary 2   fixed
11   11 12 boundary 2   fixed
12   12 7  boundary 2   fixed
13   1  7
14   2  8
15   3  9
16   4  10
17   5  11
18   6  12

faces
1   1 14  -7 -13   density TENS
2   2 15  -8 -14   density TENS
3   3 16  -9 -15   density TENS
4   4 17 -10 -16   density TENS
5   5 18 -11 -17   density TENS
6   6 13 -12 -18   density TENS

bodies
1    -1 -2 -3 -4 -5 -6 volume 0.00045 density SG

// horizontal force on upper pad by central differences
dy := .0001
do_yforce := { oldshift := shift; shift := shift + dy;
set vertex y  y+dy*z/zh; // uniform shear
recalc;
energy1 := total_energy -
body[1].pressure*(body[1].volume - body[1].target);
oldshift := shift; shift := shift - 2*dy;
set vertex y  y-2*dy*z/zh; // uniform shear
recalc;
energy2 := total_energy -
body[1].pressure*(body[1].volume - body[1].target);
yforce := -(energy1-energy2)/2/dy;
printf "restoring force: %20.15f\n",yforce;
// restore everything
oldshift := shift; shift := shift + dy;
set vertex y  y+dy*z/zh; // uniform shear
recalc;
}

// vertical force on upper pad by central differences.
dz := .0001
do_zforce := { oldzh := zh; zh := zh + dz;
set vertex z  z+dz*z/oldzh; recalc; // uniform stretch
energy1 := total_energy -
body[1].pressure*(body[1].volume - body[1].target);
oldzh := zh; zh := zh - 2*dz;
set vertex z  z-2*dz*z/oldzh; recalc; // uniform stretch
energy2 := total_energy -
body[1].pressure*(body[1].volume - body[1].target);
zforce := -(energy1-energy2)/2/dz;
printf "vertical force:  %20.15f\n",zforce;
// restore everything
oldzh := zh; zh := zh + dz;
set vertex z  z+dz*z/oldzh; recalc; // uniform stretch
}

```