// catbody.fe

// Evolver data for catenoid with fixed inner volume between plane ends.

PARAMETER  RMAX = 1.0
PARAMETER  ZMAX = 0.55 

boundary 1 parameters 1     //  upper ring
x1:  RMAX * cos(p1)
x2:  RMAX * sin(p1)
x3:  ZMAX


boundary 2 parameters 1    //   lower ring
x1:  RMAX * cos(p1)
x2:  RMAX * sin(p1)
x3:  -ZMAX


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 13 7 -14 -1
2 14 8 -15 -2
3 15 9 -16 -3
4 16 10 -17 -4
5 17 11 -18 -5
6 18 12 -13 -6

bodies
1  1 2 3 4 5 6 volconst 2*pi*rmax^2*zmax   volume 1.1 

read

// Typical evolution
gogo := { u; r; g 5; r; g 5; r; g 5; hessian; hessian }

// Adjusting volume to find zero pressure, i.e. the unstable
// equilibrium catenoid.  Run after refining to taste.
// Note that no 'g' steps are used in iteration after changing
// the volume. This is because the triangulation is  not optimal,
// and 'g' lets the vertices slither sideways, but 'hessian'
// moves vertices only perpendicular to the surface (in the default
// hessian_normal mode).  The magnitude of volume changes is limited
// since experimentation showed that too large moves can cause
// blowups.
adjust := {
   oldpressure := body[1].pressure;
   oldtarget := body[1].target;
   dvol := .01;  // starting step size
   body[1].target += dvol;
   hessian; hessian; hessian;
   slope := (body[1].pressure - oldpressure)/dvol;
   for ( inx := 1 ; inx <= 20; inx += 1 )
   { dvol := -body[1].pressure/slope; 
     if abs(dvol) > .01 then dvol := (dvol < 0) ? -.01 : .01;
     oldpressure := body[1].pressure;
     body[1].target += dvol;
     hessian; hessian; hessian;
     printf "Pressure %g   dvol %g  slope %f\n",body[1].pressure,dvol,slope;
     if abs(dvol) > .001  then
       slope := (body[1].pressure - oldpressure)/dvol;
   };
}

