sandbox/msaini/Marangoni/integral-HF.h
#ifndef thrsh
#define thrsh 0.15
#endif
#include "functionsHF.h"
extern scalar * interfaces;
attribute {
scalar sigmaf;
}
event defaults (i = 0) {
if (is_constant(a.x)) {
a = new face vector;
foreach_face() {
a.x[] = 0.;
dimensional (a.x[] == Delta/sq(DT));
}
}
}
event stability (i++)
{
double sigma = 0.;
for (scalar d in interfaces)
if (is_constant (d.sigmaf))
sigma += constant (d.sigmaf);
double sigmamax = sigma;
double amin = HUGE, amax = -HUGE, dmin = HUGE;
foreach_face (reduction(min:amin) reduction(max:amax) reduction(min:dmin)
reduction(max:sigmamax))
if (fm.x[] > 0.) {
if (alpha.x[]/fm.x[] > amax) amax = alpha.x[]/fm.x[];
if (alpha.x[]/fm.x[] < amin) amin = alpha.x[]/fm.x[];
if (Delta < dmin) dmin = Delta;
double sigmai = sigma;
for (scalar d in interfaces)
if (!is_constant (d.sigmaf) && d[] < 0.999999 && d[] > 0.000001) {
scalar sigmaf = d.sigmaf;
sigmai += sigmaf[];
}
if (sigmai > sigmamax)
sigmamax = sigmai;
}
double rhom = (1./amin + 1./amax)/2.;
if (sigmamax) {
double dt = sqrt (rhom*cube(dmin)/(pi*sigmamax));
if (dt < dtmax)
dtmax = dt;
}
}
#if AXI
# include "fractions.h"
#endif
vector nrm[];
foreach_dimension()
double getdiagterm_y(Point point, scalar d,scalar sigma, double kappahf){
double termyy=0.;
for (int i = -1; i <= 1; i += 2)
if (d[]*(d[] + d[i]) < 0.) {
double xi = d[]/(d[] - d[i] + SEPS);
double nx = 2.*xi*(nrm.x[] + nrm.x[i])/2. + (1. - 2.*xi)*(nrm.x[]);
double sigmai = sigma[] + xi*(sigma[i] - sigma[]);
double ki = kappahf;
termyy += sigmai*(fabs(nx)/Delta - sign(d[])*ki*(0.5 - xi));
}
return termyy;
}
foreach_dimension()
double getnondiagterm_y(Point point, scalar d,scalar sigma){
double termxy = 0.;
if ((d[] + d[0,-1])*(d[-1] + d[-1,-1]) > 0.)
return termxy;
else {
double xi = (d[-1] + d[-1,-1])/(d[-1] + d[-1,-1] - d[] - d[0,-1]);
double ny = (xi*(nrm.y[] + nrm.y[0,-1])/2. + (1. - xi)*(nrm.y[-1,0] + nrm.y[-1,-1])/2.);
double sigmai = (sigma[-1] + sigma[-1,-1] +
xi*(sigma[] + sigma[0,-1] - sigma[-1] - sigma[-1,-1]))/2.;
termxy = - sigmai*sign(d[] + d[0,-1])*ny/Delta;
}
return termxy;
}
bool interfacialvertex(Point point, scalar f){
for(int ii = -1; ii <=0; ii++)
for(int jj = -1; jj <=0; jj++)
if(f[ii,jj] > 0 && f[ii,jj] < 1.)
return true;
return false;
}
scalar kappa[];
event acceleration (i++)
{
for (scalar d in interfaces)
if (d.sigmaf.i) {
(const) scalar sigma = d.sigmaf;
vector hf[];
scalar dx[],dy[];
scalar sd[];
foreach(){
d[] = clamp(d[],0.,1.);
sd[] = (4.*d[] +
2.*(d[0,1] + d[0,-1] + d[1,0] + d[-1,0]) +
d[-1,-1] + d[1,-1] + d[1,1] + d[-1,1])/16.;
}
heights(d,hf);
/* curvature(sd,kappa); */
foreach(){
kappa[] = height_curvature_fit(point,f,hf);
//kappa[] = height_curvatureV2(point,sd,hf);
coord nrmf = height_normal(point,f,hf);
foreach_dimension()
nrm.x[] = -nrmf.x; // to match with d[1] - d[-1], I put -ve sign
}
foreach(){
if(hf.x[] < nodata)
dx[] = hf.x[] > HSHIFT/2. ? HSHIFT - hf.x[] : hf.x[];
else
dx[] = nodata;
if(hf.y[] < nodata)
dy[] = hf.y[] > HSHIFT/2. ? HSHIFT - hf.y[] : hf.y[];
else
dy[] = nodata;
}
boundary({dx,dy});
scalar Sxx[], Sxy[], Syy[], Syx[];
tensor S; S.x.x = Sxx, S.x.y = Sxy, S.y.y = Syy, S.y.x = Syx;
foreach(){
coord nrf;
double mag = 0.;
double wx = 0, wy = 0;
foreach_dimension(){
nrf.x = sd[1] - sd[-1];
mag += sq(sd[1] - sd[-1]);
}
if(mag > 0.){
foreach_dimension()
nrf.x /= sqrt(mag);
if(sq(nrf.x) < thrsh){
wx = 0.;
wy = 1.;
}
else if(sq(nrf.x) > (1. - thrsh)){
wx = 1.;
wy = 0.;
}
else{
wx = sq(nrf.x);
wy = sq(nrf.y);
}
}
foreach_dimension() {
S.y.y[] = 0.;
if(interfacial(point,d)){
double syyhx = getdiagterm_y(point,dx,sigma,kappa[]);
double syyhy = getdiagterm_y(point,dy,sigma,kappa[]);
double syy = wx*syyhx + wy*syyhy;
S.y.y[] += syy;
}
}
}
We compute the off-diagonal components of the tensor.
foreach_vertex(){
coord nrf;
double mag = 0.;
double wx = 0, wy = 0;
foreach_dimension(){
nrf.x = sd[1] + sd[0,-1] - sd[-1] - sd[-1,-1];
mag += sq(sd[1] + sd[0,-1] - sd[-1] - sd[-1,-1]);
}
if(mag > 0.){
foreach_dimension()
nrf.x /= sqrt(mag);
if(sq(nrf.x) < thrsh){
wx = 0.;
wy = 1.;
}
else if(sq(nrf.x) > (1. - thrsh)){
wx = 1.;
wy = 0.;
}
else{
wx = sq(nrf.x);
wy = sq(nrf.y);
}
}
foreach_dimension(){
if(interfacialvertex(point,d)){
double sxyhx = getnondiagterm_y(point,dx,sigma);
double sxyhy = getnondiagterm_y(point,dy,sigma);
S.x.y[] = wx*sxyhx + wy*sxyhy;
}
else
S.x.y[] = 0.;
}
}
face vector av = a;
foreach_face() {
av.x[] += alpha.x[]/(fm.x[] + SEPS)*(S.x.x[] - S.x.x[-1] + S.x.y[0,1] - S.x.y[])/Delta;
#if AXI
coord n = {
(nrm.x[] + nrm.x[-1])/2.,
(nrm.y[] + nrm.y[-1])/2.
};
extern scalar f;
av.x[] -= alpha.x[]/sq(fm.x[] + SEPS)*(sigma[] + sigma[-1])/2.*n.y*(f[] - f[-1])/Delta;
#endif // AXI
}
}
}