sandbox/alimare/1_test_cases/crystal.c

    Melt of a solid particle

    We simulate the diffusion of two tracers separated by an embedded boundary. The interface moves using the Stefan relation :

    \displaystyle \mathbf{v}_{pc} = \frac{1}{L_H}(\lambda_1 \nabla T_L - \lambda_1 \nabla T_S) where L_H is the latent heat of water, T_L and T_S are the temperature fields on both sides of the interface.

    The boundaries of the domain are set at T_L = 1. The ice particle is initially at T_S = -1.

    The temperature on the interface is derived from the Gibbs-Thomson relation, withtout any anisotropic effect : \displaystyle T_{\Gamma} = T_{m} - \epsilon_{\kappa} * \kappa - \epsilon_{v} v_{pc}

    Animation of the temperature field

    #define Gibbs_Thomson 1
    #define Pi 3.14159265358979323846
    #define QUADRATIC 1
    #define GHIGO 1
    #define CURVE_LS 1
    
    #include "../../ghigo/src/myembed.h"
    #include "../double_embed-tree.h"
    
    #include "../../ghigo/src/mydiffusion.h"
    #include "../advection_A.h"
    
    #include "fractions.h"
    #include "curvature.h"
    
    #include "view.h"
    
    #define dtLS 1
    #include "../LS_diffusion.h"
    
    
    #define TL_inf       1.
    #define TS_inf       -1.

    Setup of the numerical parameters

    int MAXLEVEL, MINLEVEL;
    double  H0;

    Initial geometry definition. Here the interface equation is :

    \displaystyle r\left(1+ 0.2 *cos(8\theta) \right) - R where r = \sqrt{x^2 + y^2}, \theta = \arctan(x,y) and R = \frac{L_0}{5}

    Notice that the initial dist[] field is not really a distance, it is modified after a few iterations of the LS_reinit() function.

    double geometry(double x, double y, double Radius) {
    
      coord center;
      center.x = 0.5;
      center.y = 0.5;
    
      double theta = atan2 (y-center.y, x-center.x);
      double R2  =  sq(x - center.x) + sq (y - center.y) ;
      double s = -( sqrt(R2)*(1.+0.2*cos(6*theta)) - Radius);
      // double s = -( sqrt(R2)*(1.+0.*cos(6*theta)) - Radius);
    
    
      return s;
    }
    
    double TL_init(double val, double factor){
        return T_eq+(TL_inf-T_eq)*tanh(val*L0/factor);
    }

    k_{loop} is a variable used when the interface arrives in a new cell. Because we are using embedded boundaries, the solver needs to converge a bit more when the interface is moved to a new cell. Therefore, the Poisson solver is used 40*k_{loop} +1 times.

    int k_loop = 0;
    
    int main() {
      CFL = 0.5;
      MAXLEVEL  = 7;
      MINLEVEL = 4;
      int N     = 1 << MAXLEVEL;
      init_grid (N);
      TOLERANCE = 1.e-6;
      NITERMIN = 4;
      TL.third = true;
      TS.third = true;  
      TL[embed] = dirichlet(T_eq + Temp_GT(point, epsK, epsV, vpc, curve, fs, cs, eps4));
      TS[embed] = dirichlet(T_eq + Temp_GT(point, epsK, epsV, vpc, curve, fs, cs, eps4));
    
    
      TL[top]    = dirichlet(TL_inf); 
      TL[bottom] = dirichlet(TL_inf); 
      TL[left]   = dirichlet(TL_inf); 
      TL[right]  = dirichlet(TL_inf); 
    
      TS[top]    = dirichlet(TS_inf); 
      TS[bottom] = dirichlet(TS_inf); 
      TS[left]   = dirichlet(TS_inf); 
      TS[right]  = dirichlet(TS_inf); 
    
      run();
    }
    
    
    event init(t=0){
      DT   = sq(L0/(1 << MAXLEVEL));  // Delta
      epsK = 0.001 ; epsV = 0.001;
      eps4 = 0.;
      DT_LS = 0.45*(L0)/(1 << MAXLEVEL);
      itrecons = 60;
    
    
      nb_cell_NB = 8 ;               // number of cell in the 
                                          // narrow band 
      NB_width   = nb_cell_NB * L0 / (1 << MAXLEVEL);
    
      lambda[0] = 1.;
      lambda[1] = 1.;
      foreach() {
        dist[] = clamp(-geometry(x,y,L0/4.),-1.5*NB_width,1.5*NB_width);
      }
    
      boundary ({dist});
      restriction({dist});
    
      LS2fractions(dist,cs,fs);
      
      curvature(cs,curve);
    
      boundary({curve});
      foreach() {
        TL[] = cs[] > 0. ? TL_init(dist[],0.05) : 0.;
        TS[] = TS_inf;
      }
      boundary({TL,TS});
      restriction({TL,TS});
    
    #if GHIGO
      foreach()
        csm1[]= cs[];
    
      boundary({csm1});
      restriction({csm1});
    #endif // GHIGO
    
      myprop(muv,fs,lambda[0]);
    #if GHIGO // mandatory for GHIGO
      u.n[embed] = dirichlet(0);
      u.t[embed] = dirichlet(0);
    
      // Added to account for moving boundary algorithm
      
      uf.n[embed] = dirichlet (0.);
      uf.t[embed] = dirichlet (0.);
    #endif
    
    }
    
    event snapshot(t+=0.012){
      output_facets (cs, stdout);
    }
    
    event movies ( t+=0.0024,last;t<0.12)
    {
      scalar visu[];
      foreach(){
        visu[] = (cs[])*TL[]+(1.-cs[])*TS[] ;
      }
      boundary({visu});
      restriction({visu});
      view (tx = -0.489668, ty = -0.453663);
      squares("visu", min = -1 , max = 1.);
      draw_vof("cs");
      save("temperature.mp4");
    }
    
    #if 1
    event adapt (i++, last) {
    
      foreach_cell(){
        cs2[] = 1.-cs[];
      }
      foreach_face(){
          fs2.x[]      = 1.-fs.x[];
      }
    
      boundary({cs,cs2});
      fractions_cleanup(cs,fs,smin = 1.e-10);
      fractions_cleanup(cs2,fs2,smin = 1.e-10);
      restriction({cs,cs2,fs,fs2});
      int n=0;
      stats s2 = statsf(curve);
      if(i%10==0.)fprintf(stderr, "%g %g %g\n",t, s2.min, s2.max);
      boundary({TL,TS});
      scalar visu[];
      foreach(){
        visu[] = (cs[])*TL[]+(1.-cs[])*TS[] ;
      }
      boundary({visu});
      restriction({visu});
    
      adapt_wavelet ({cs,visu, vpcf.x, vpcf.y},
        (double[]){1.e-3,1.e-3,5.e-3,5.e-3},MAXLEVEL, MINLEVEL);
      foreach(reduction(+:n)){
        n++;
      }
      curvature(cs,curve);
      boundary({curve});
      if(i%10==0) fprintf(stderr, "##nb cells %d\n", n);
    }
    #endif
    set key left
    set yrange [-30:30]
    set xrange [0:0.095]
    plot 'log' u 1:2 w l t 'curvature min',  \
         'log' u 1:3 w l  t 'curvature max'
    Curvature (script)

    Curvature (script)

    set size ratio -1
    set yrange [*:*]
    set xrange [*:*]
    set key top right
    unset xlabel
    unset xtics
    unset ytics
    unset border
    unset margin
    unset ylabel
    plot 'out' w l lw 2 t 'interface'
    Evolution of the interface (zoom) (script)

    Evolution of the interface (zoom) (script)