// bga-6.fe

// Simple ball grid array joint.

// Circular, parallel, coaxial wetted pads. With gravity.
// Same as bga-5.fe, but with upper pad load and optimizing pad height.

// Both pads represented with constraints.
// Liquid entirely bounded by facets.

evolver_version "2.11c"  // minimum Evolver version needed

// physical constants, in cgs units
parameter S_TENSION = 480    // liquid solder surface tension, erg/cm^2
parameter SOLDER_DENSITY = 9 // grams/cm^3
gravity_constant 980         // cm/sec^2

// configuration parameters
optimizing_parameter height = 0.12 delta=1e-5  // height of upper pad, cm
parameter radius = 0.1               // radius of pads, cm
parameter pad_weight = 500           // weight of upper pad, dynes

// upper pad energy
quantity pad_energy energy method vertex_scalar_integral
scalar_integrand: pad_weight*z

// lower pad
constraint 1
formula: z = 0

// upper pad
constraint 2
formula: z = height

// rim of pads
constraint 3
formula: x^2 + y^2 = radius^2

// lower barrier (substrate off pad, nonwetting)
constraint 4 nonnegative
formula: z

// upper barrier (upper chip off pad, nonwetting)
constraint 5 nonpositive
formula: z - height

// lower substrate off pad, exact constraint
constraint 6 
formula: z = 0

// upper chip off pad, exact constraint
constraint 7
formula: z = height

vertices
// lower pad
1  radius*cos(0*pi/3) radius*sin(0*pi/3) 0   constraints 1,3 fixed
2  radius*cos(1*pi/3) radius*sin(1*pi/3) 0   constraints 1,3 fixed
3  radius*cos(2*pi/3) radius*sin(2*pi/3) 0   constraints 1,3 fixed
4  radius*cos(3*pi/3) radius*sin(3*pi/3) 0   constraints 1,3 fixed
5  radius*cos(4*pi/3) radius*sin(4*pi/3) 0   constraints 1,3 fixed
6  radius*cos(5*pi/3) radius*sin(5*pi/3) 0   constraints 1,3 fixed
// upper pad
7  radius*cos(0*pi/3) radius*sin(0*pi/3) height   constraints 2,3 fixed
8  radius*cos(1*pi/3) radius*sin(1*pi/3) height   constraints 2,3 fixed
9  radius*cos(2*pi/3) radius*sin(2*pi/3) height   constraints 2,3 fixed
10 radius*cos(3*pi/3) radius*sin(3*pi/3) height   constraints 2,3 fixed
11 radius*cos(4*pi/3) radius*sin(4*pi/3) height   constraints 2,3 fixed
12 radius*cos(5*pi/3) radius*sin(5*pi/3) height   constraints 2,3 fixed
// dummy vertex for upper pad load
13 0 0 height constraint 2 fixed bare pad_energy

edges  // defined by endpoints
// lower pad edges
1    1  2  constraints 1,3   fixed
2    2  3  constraints 1,3   fixed
3    3  4  constraints 1,3   fixed
4    4  5  constraints 1,3   fixed
5    5  6  constraints 1,3   fixed
6    6  1  constraints 1,3   fixed
// upper pad edges
7    7  8  constraints 2,3   fixed
8    8  9  constraints 2,3   fixed
9    9  10 constraints 2,3   fixed
10   10 11 constraints 2,3   fixed
11   11 12 constraints 2,3   fixed
12   12 7  constraints 2,3   fixed
// vertical edges
13   1  7 constraints 4,5
14   2  8 constraints 4,5
15   3  9 constraints 4,5
16   4  10 constraints 4,5 
17   5  11 constraints 4,5
18   6  12 constraints 4,5

faces // defined by oriented edge loops to have outward normal
// lateral faces
1   1 14  -7 -13 tension S_TENSION constraints 4,5
2   2 15  -8 -14 tension S_TENSION constraints 4,5
3   3 16  -9 -15 tension S_TENSION constraints 4,5
4   4 17 -10 -16 tension S_TENSION constraints 4,5
5   5 18 -11 -17 tension S_TENSION constraints 4,5
6   6 13 -12 -18 tension S_TENSION constraints 4,5
// lower pad
7   -6 -5 -4 -3 -2 -1 fixed no_refine color red tension 0
// upper pad
8   7 8 9 10 11 12 fixed no_refine color green tension 0 constraint 2

bodies // defined by oriented face list
1   1 2 3 4 5 6 7 8   volume 1.3*pi*radius^2*height  density SOLDER_DENSITY

read
hessian_normal

// command to transfer vertices that hit one-sided constraints to exact constraints
nail := { nailcount := 0;
	  foreach vertex vv where hit_constraint 4 do
	  { unset vv constraint 4; set vv constraint 6; nailcount := nailcount + 1 };
          foreach vertex vv where hit_constraint 5 do
	  { unset vv constraint 5; set vv constraint 7; nailcount := nailcount + 1 };
	  printf "Nailed vertices: %g\n",nailcount;
        }


// command to loosen up vertices that maybe should not be nailed.
unnail := { unnailcount := 0;
	    foreach vertex vv where on_constraint 6 do
	    { unset vv constraint 6; set vv constraint 4; unnailcount := unnailcount + 1 };
            foreach vertex vv where on_constraint 7 do
	    { unset vv constraint 7; set vv constraint 5; unnailcount := unnailcount + 1 };
	    printf "Unnailed vertices: %g\n",unnailcount;
          }


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