sandbox/jtault/README
My Sandbox
Welcome to the README of my sandbox. Here I provide an overview of the projects under /sandbox/jtault. I mainly work in the areas of vortex breakdown and electrokinetics, but I also perform some multi-phase simulations using Basilisk.
Jesse T. Ault (Web)
Fluids and Thermal Sciences Group
Brown University
Email: (jesse_ault@brown.edu)
Repositories
Bubble bursting at a compound interface
We investigate the bursting of rising bubbles at an air-water interface when the bubbles are initially coated in a thin oil layer. This work is currently under review for publication in Nature Physics:
Title: Singular jets from oil-coated bubble bursting
Authors: Z. Yang, B. Ji, J. T. Ault, and J. Feng*
Sample results: Here, we initialize the interface shapes using the model developed in the above paper, and we simulate the coupled transport. Note that these results use the three-phase contact line implementation by Dr. Vatsal Sanjay (Basilisk sandbox). A typical result of the simulations is shown below over time for a case that experiences singular jet formation.
Simulation of an oil-coated bubble bursting
As mentioned, this simulation uses the three-phase solver developed by Dr. Vatsal Sanjay (Basilisk sandbox) to simulate the bursting of an oil-coated bubble at an air-water interface. The different needed codes are published below along with some documentation, and over 1 TB of data from simulation runs can be made available upon request.
The needed codes are found below:
batch.sh
This is one of the submission scripts submitted for the Brown CCV supercomputer. Here, this runs the conversion operation to output VTK files.
#!/bin/bash
#SBATCH --time=24:00:00
#SBATCH -N 1
#SBATCH -n 1
#SBATCH --mem=80G
# Specify a job name:
#SBATCH -J basilisk
export BASILISK=~/basilisk/src
export PATH=$PATH:~/basilisk/src
# This section will compile to run in parallel and then run the solver. Make sure that the correct number of processors are allocated above.
#CC99='mpicc -std=c99' qcc -Wall -O2 -D_MPI=1 newTest.c -o run -lm
#srun --mpi=pmix -n 32 ./run
# This section of code will run the convert program to convert the output checkpoint files into VTK files.
rm run
qcc -Wall -O2 convert.c -o run -lm
./run
convert.c
This code will run the conversion to reload all of the output checkpoint files and re-output them as VTK files. The reason for this ‘hack’ approach is that the VTK output writer I found will only work in serial and not in parallel. There are probably better options out there.
#define R_VOFLIMIT 1e-3
#include "axi.h"
#include "navier-stokes/centered.h"
#include "three-phase.h"
#include "tension.h"
#include "VTKoutput.h"
#include "distance.h"
#define MINLEVEL 7
#define MAXLEVEL 10
#define fErr 1e-3
#define KErr 1e-3
#define VelErr 1e-3
// Define the geometry
#define L 10.0e-3
// Boundary Conditions
u.n[right] = neumann(0.);
p[right] = dirichlet(0.);
scalar alphas[];
scalar testDistance[];
scalar testDistance2[];
scalar testDistance3[];
int main()
{
size(L);
origin(6e-3, 0);
init_grid (1 << MAXLEVEL);
rho1 = 1.204; // air
rho2 = 913.0; // oil
rho3 = 998.0; // water
mu1 = 18.13e-6; // air
mu2 = 4.6e-3; // oil
mu3 = 0.89e-3; // water
double sigma13 = 71.6e-3;// air-water
double sigma23 = 38.1e-3;// oil-water
double sigma12 = 18.7e-3;
//f3.sigma = (sigma13 + sigma23 - sigma12) / 2.0;
//f2.sigma = sigma23 - f3.sigma;
//f1.sigma = sigma13 - f3.sigma;
TOLERANCE = 1e-6;
run();
}
event init(t = 0)
{
for (double t = 1e-4; t < 10.0e-3; t += 1e-4) {
char name[500];
sprintf(name, "out-%.2f-CC.out", t*1e5);
char name2[500];
sprintf(name2, "out-%.2f-CC.vtk", t*1e5);
fprintf(stdout, name);
fprintf(stdout, "\n");
fprintf(stdout, name2);
fprintf(stdout, "\n\n");
restore (file = name);
output_paraview_CC(name2, t, 0., {alphas});
}
}
newTest.c
This is the actual solver. Note that the really ugly, large equations are basically high-order polynomials to set the initial conditions. We found these by solving numerically a model (in the paper) to approximate the initial (static) interface shapes before rupture. We fit these to high-order polynomials and use them to initialize the initial conditions here.
#define R_VOFLIMIT 1e-3
#include "axi.h"
#include "navier-stokes/centered.h"
#include "fractions.h"
#define FILTERED
#include "three-phase.h"
#include "tension.h"
#include "VTKoutput.h"
#include "distance.h"
#define MINLEVEL 5
#define MAXLEVEL 13 // 12
#define fErr 1e-3
#define KErr 1e-3
#define VelErr 1e-3
// Define the geometry
#define L 15.0e-3
#define R1 1.95e-3
#define R2 2.0e-3
// Boundary Conditions
u.n[right] = neumann(0.);
p[right] = dirichlet(0.);
scalar alphas[];
int main()
{
int Oil_visc = 2;
size(L);
origin(-4.0e-3, 0);
init_grid (1 << MAXLEVEL);
rho2 = 998.0; // water
rho3 = 1.204; // air
mu2 = 0.89e-3; // water
mu3 = 18.13e-6; // air
if (Oil_visc == 2) {
rho1 = 875.0; // oil
mu1 = 2.086e-3; // oil
f1.sigma = 0.0181; // air/oil
f2.sigma = 0.041; // water/oil
}
else if (Oil_visc == 5) {
rho1 = 913.0; // oil
mu1 = 4.6e-3; // oil
f1.sigma = 18.7e-3; // air/oil
f2.sigma = 38.1e-3; // water/oil
}
else if (Oil_visc == 10) {
rho1 = 930; // oil
mu1 = 10e-3; // oil
f1.sigma = 0.01914; // air/oil
f2.sigma = 0.0409; // water/oil
}
else if (Oil_visc == 20) {
rho1 = 950; // oil
mu1 = 20e-3; // oil
f1.sigma = 0.0194; // air/oil
f2.sigma = 0.0409; // water/oil
}
TOLERANCE = 1e-6;
run();
}
event init(t = 0)
{
int Case = 8;
double r_lim_1, z_lim_1, r_lim_2, z_lim_2;
if (Case == 1) {
r_lim_1 = 1.35170501037191*1e-3;
z_lim_1 = 0.375533185058833*1e-3;
r_lim_2 = 1.59385013047239*1e-3;
z_lim_2 = 0.00328458654733756; //3.31611768024265*1e-3;
}
else if (Case == 2) {
r_lim_1 = 1.55159657698644*1e-3;
z_lim_1 = 0.522700173908474*1e-3;
r_lim_2 = 1.54782189406541*1e-3;
z_lim_2 = 0.00326478169318366; //3.28846997949751*1e-3;
}
else if (Case == 3) {
r_lim_1 = 1.67375791111958*1e-3;
z_lim_1 = 0.617796545460821*1e-3;
r_lim_2 = 1.55679065522414*1e-3;
z_lim_2 = 0.00328; //3.30420391019313*1e-3;
}
else if (Case == 4) {
r_lim_1 = 1.71466210548685*1e-3;
z_lim_1 = 0.663274484062195*1e-3;
r_lim_2 = 1.53544600078326*1e-3;
z_lim_2 = 0.003255; //3.28482605413889*1e-3;
}
else if (Case == 5) {
r_lim_1 = 1.85098498594908*1e-3;
z_lim_1 = 0.796007833576201*1e-3;
r_lim_2 = 1.53819508214288*1e-3;
z_lim_2 = 0.003272; //3.29542201024412*1e-3;
}
else if (Case == 6) {
r_lim_1 = 1.9009883223642*1e-3;
z_lim_1 = 0.910164782832564*1e-3;
r_lim_2 = 1.45497436018858*1e-3;
z_lim_2 = 0.003194;//3.2166405390881*1e-3;
}
else if (Case == 7) {
r_lim_1 = 1.94457064731323*1e-3;
z_lim_1 = 1.13285973958969*1e-3;
r_lim_2 = 1.30286284651996*1e-3;
z_lim_2 = 0.003033; //3.05772205364344*1e-3;
}
else if (Case == 8) {
r_lim_1 = 1.99902888895628*1e-3;
z_lim_1 = 1.3294242176447*1e-3;
r_lim_2 = 1.26504714282477*1e-3;
z_lim_2 = 0.002969; //2.99788379545318*1e-3;
}
if (!restore (file = "restart")) {
fprintf(stdout, "There is no restart file.\n");
}
double z1, z2, r3, z4;
foreach () {
if (Case == 1) {
z1 = (+1.357750734735647E-02*pow(y*1e3,9)-7.828809454891772E-02*pow(y*1e3,8)+1.846452373664142E-01*pow(y*1e3,7)-2.206772221231513E-01*pow(y*1e3,6)+1.355022474315898E-01*pow(y*1e3,5)-2.049765146117644E-02*pow(y*1e3,4)-5.715990749624263E-03*pow(y*1e3,3)+1.852664336432668E-01*pow(y*1e3,2)-1.873714767149672E-04*y*1e3+0.000000000000000E+00)*1e-3;
z2 = (+4.666870450890280E-04*pow(y*1e3,8)-1.606997846860378E-03*pow(y*1e3,7)+3.450338223489183E-03*pow(y*1e3,6)-2.696369974962074E-03*pow(y*1e3,5)+9.421133458189922E-03*pow(y*1e3,4)-4.782870031683002E-04*pow(y*1e3,3)+1.977020911974303E-01*pow(y*1e3,2)-6.399865698026097E-06*y*1e3-1.678024588435728E-02)*1e-3;
r3 = (-1.637302807743277E-06*pow(x*1e3,26)+5.191074284599997E-05*pow(x*1e3,25)-7.312210369651989E-04*pow(x*1e3,24)+5.927951163048202E-03*pow(x*1e3,23)-2.954896509387863E-02*pow(x*1e3,22)+8.615066103507581E-02*pow(x*1e3,21)-1.011405276428509E-01*pow(x*1e3,20)-1.201502749740012E-01*pow(x*1e3,19)-2.560619684268452E-01*pow(x*1e3,18)+6.525162055755866E+00*pow(x*1e3,17)-2.673802114556107E+01*pow(x*1e3,16)+4.079281232870543E+01*pow(x*1e3,15)+6.550814282833809E+01*pow(x*1e3,14)-5.051887512037449E+02*pow(x*1e3,13)+1.373521197219294E+03*pow(x*1e3,12)-2.301362628679914E+03*pow(x*1e3,11)+2.491043762487982E+03*pow(x*1e3,10)-1.435685947069049E+03*pow(x*1e3,9)-3.747303472331048E+02*pow(x*1e3,8)+1.779155819135926E+03*pow(x*1e3,7)-2.055012932754647E+03*pow(x*1e3,6)+1.463849575586401E+03*pow(x*1e3,5)-7.176711930654154E+02*pow(x*1e3,4)+2.465055251470648E+02*pow(x*1e3,3)-5.903213962992336E+01*pow(x*1e3,2)+1.092715882937194E+01*x*1e3+9.662396473630194E-03)*1e-3;
z4 = (+1.796980939385519E+00+exp(-y*1e3/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+4.814616379274008E-07*pow(y*1e3,8)-1.691820605303149E-05*pow(y*1e3,7)+3.291226573009550E-04*pow(y*1e3,6)-3.155283225199848E-03*pow(y*1e3,5)+2.295398020365885E-02*pow(y*1e3,4)-6.153623141702021E-02*pow(y*1e3,3)+2.927138607997448E-01*pow(y*1e3,2)+5.391471616005816E-01*y*1e3+1.978581809251079E+00))*1e-3;
}
else if (Case == 2) {
z1 = (+1.734566043095817E-03*pow(y*1e3,9)-5.725322370807498E-03*pow(y*1e3,8)-8.079160444084561E-04*pow(y*1e3,7)+3.523212192087177E-02*pow(y*1e3,6)-7.046570033197115E-02*pow(y*1e3,5)+7.690026907906994E-02*pow(y*1e3,4)-3.150821996806371E-02*pow(y*1e3,3)+1.897203803469847E-01*pow(y*1e3,2)-3.591810435034399E-04*(y*1e3)+0.000000000000000E+00)*1e-3;
z2 = (+1.126718848073794E-03*pow(y*1e3,8)-5.004690322252760E-03*pow(y*1e3,7)+1.105055888438056E-02*pow(y*1e3,6)-1.152732869858489E-02*pow(y*1e3,5)+1.607345418280904E-02*pow(y*1e3,4)-2.726175712598447E-03*pow(y*1e3,3)+2.042069582057293E-01*pow(y*1e3,2)-4.699085705630971E-05*(y*1e3)-3.184678299225876E-02)*1e-3;
r3 = (-3.461778056802014E-06*pow(x*1e3,26)+1.097959845742229E-04*pow(x*1e3,25)-1.539709697777255E-03*pow(x*1e3,24)+1.228974470838716E-02*pow(x*1e3,23)-5.849253553706244E-02*pow(x*1e3,22)+1.433967828431854E-01*pow(x*1e3,21)+4.004571462029775E-02*pow(x*1e3,20)-1.451725726473805E+00*pow(x*1e3,19)+3.745855575665001E+00*pow(x*1e3,18)+1.501424673773274E+00*pow(x*1e3,17)-2.738927671664976E+01*pow(x*1e3,16)+3.669032071816854E+01*pow(x*1e3,15)+1.275852954960601E+02*pow(x*1e3,14)-5.186229656211442E+02*pow(x*1e3,13)+2.478330591063275E+02*pow(x*1e3,12)+3.246611100482060E+03*pow(x*1e3,11)-1.284095100531124E+04*pow(x*1e3,10)+2.787249109921619E+04*pow(x*1e3,9)-4.186458822369487E+04*pow(x*1e3,8)+4.647937837886125E+04*pow(x*1e3,7)-3.900481912425752E+04*pow(x*1e3,6)+2.478710338421063E+04*pow(x*1e3,5)-1.177184889285986E+04*pow(x*1e3,4)+4.055310381722206E+03*pow(x*1e3,3)-9.593896129191204E+02*pow(x*1e3,2)+1.413647015693208E+02*(x*1e3)-8.707391011059862E+00)*1e-3;
z4 = (+1.834083755952505E+00+exp(-(y*1e3)/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+4.302850993249406E-07*pow(y*1e3,8)-1.475284320604043E-05*pow(y*1e3,7)+2.830616689583812E-04*pow(y*1e3,6)-2.631618306605154E-03*pow(y*1e3,5)+1.896106465817967E-02*pow(y*1e3,4)-4.525807347752398E-02*pow(y*1e3,3)+2.372066908255421E-01*pow(y*1e3,2)+5.751900065355661E-01*(y*1e3)+1.823081377828373E+00))*1e-3;
}
else if (Case == 3) {
z1 = (+2.553020545006675E-03*pow(y*1e3,9)-1.230698052171267E-02*pow(y*1e3,8)+2.031715622664721E-02*pow(y*1e3,7)-7.590482288837250E-04*pow(y*1e3,6)-3.537756380403528E-02*pow(y*1e3,5)+5.668429841231605E-02*pow(y*1e3,4)-2.540552934865686E-02*pow(y*1e3,3)+1.860259688621521E-01*pow(y*1e3,2)-3.091863342791807E-04*(y*1e3)+0.000000000000000E+00)*1e-3;
z2 = (+1.683231832037126E-03*pow(y*1e3,8)-8.456682406301794E-03*pow(y*1e3,7)+1.980606444280598E-02*pow(y*1e3,6)-2.321241035078907E-02*pow(y*1e3,5)+2.487670588366412E-02*pow(y*1e3,4)-6.447808547813161E-03*pow(y*1e3,3)+2.050996113728243E-01*pow(y*1e3,2)-1.283538787817568E-04*(y*1e3)-4.459084492335252E-02)*1e-3;
r3 = (-3.798584396124963E-06*pow(x*1e3,25)+1.034430437944233E-04*pow(x*1e3,24)-1.122146658943431E-03*pow(x*1e3,23)+4.991039736847306E-03*pow(x*1e3,22)+1.020424557593881E-02*pow(x*1e3,21)-2.524720371707730E-01*pow(x*1e3,20)+1.404753146891352E+00*pow(x*1e3,19)-3.334521744028362E+00*pow(x*1e3,18)-2.563313917867945E+00*pow(x*1e3,17)+4.197345989968779E+01*pow(x*1e3,16)-1.124799363577139E+02*pow(x*1e3,15)+5.026597842203771E+00*pow(x*1e3,14)+8.382276360645093E+02*pow(x*1e3,13)-2.743344853098155E+03*pow(x*1e3,12)+4.129918311172393E+03*pow(x*1e3,11)-5.735185164205906E+02*pow(x*1e3,10)-1.210014979611065E+04*pow(x*1e3,9)+3.160652274193595E+04*pow(x*1e3,8)-4.762506886889882E+04*pow(x*1e3,7)+4.988944081584470E+04*pow(x*1e3,6)-3.804173736159656E+04*pow(x*1e3,5)+2.120128568615137E+04*pow(x*1e3,4)-8.448553818925895E+03*pow(x*1e3,3)+2.283992971201232E+03*pow(x*1e3,2)-3.739511044717337E+02*(x*1e3)+2.914247661470471E+01)*1e-3;
z4 = (+1.897348845830787E+00+exp(-(y*1e3)/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+4.096789569804559E-07*pow(y*1e3,8)-1.434139930108769E-05*pow(y*1e3,7)+2.781355619683686E-04*pow(y*1e3,6)-2.644662747903875E-03*pow(y*1e3,5)+1.911440072882209E-02*pow(y*1e3,4)-4.923194493435865E-02*pow(y*1e3,3)+2.385173995779500E-01*pow(y*1e3,2)+5.182389909609149E-01*(y*1e3)+1.826613266783410E+00))*1e-3;
}
else if (Case == 4) {
z1 = (+3.762946270343899E-03*pow(y*1e3,9)-2.097010735058038E-02*pow(y*1e3,8)+4.646145430317290E-02*pow(y*1e3,7)-4.366898569757142E-02*pow(y*1e3,6)+6.183506681200351E-03*pow(y*1e3,5)+3.279669973386517E-02*pow(y*1e3,4)-1.743009903175263E-02*pow(y*1e3,3)+1.858182254004300E-01*pow(y*1e3,2)-2.193720061143926E-04*(y*1e3)+0.000000000000000E+00)*1e-3;
z2 = (+2.286529413827035E-03*pow(y*1e3,8)-1.202350979314283E-02*pow(y*1e3,7)+2.876631656579727E-02*pow(y*1e3,6)-3.507392739282125E-02*pow(y*1e3,5)+3.417863198068876E-02*pow(y*1e3,4)-1.027883942884728E-02*pow(y*1e3,3)+2.085530895515245E-01*pow(y*1e3,2)-2.140534251745023E-04*(y*1e3)-5.126221283079233E-02)*1e-3;
r3 = (-1.153031452438236E-05*pow(x*1e3,25)+3.760784393407455E-04*pow(x*1e3,24)-5.519279339004914E-03*pow(x*1e3,23)+4.766734194266867E-02*pow(x*1e3,22)-2.646367453626475E-01*pow(x*1e3,21)+9.586596199740014E-01*pow(x*1e3,20)-2.145894691744502E+00*pow(x*1e3,19)+2.473173759218941E+00*pow(x*1e3,18)-1.736621399471612E+00*pow(x*1e3,17)+1.363682080216863E+01*pow(x*1e3,16)-6.525634755579998E+01*pow(x*1e3,15)+1.137415629487406E+02*pow(x*1e3,14)+3.261933894664333E+01*pow(x*1e3,13)-2.218690329303315E+02*pow(x*1e3,12)-1.529320089806187E+03*pow(x*1e3,11)+9.842122185647026E+03*pow(x*1e3,10)-2.862133953580387E+04*pow(x*1e3,9)+5.420571763630197E+04*pow(x*1e3,8)-7.360217235570999E+04*pow(x*1e3,7)+7.417598168214969E+04*pow(x*1e3,6)-5.593715328338479E+04*pow(x*1e3,5)+3.126165651084794E+04*pow(x*1e3,4)-1.259104140963987E+04*pow(x*1e3,3)+3.457943891807339E+03*pow(x*1e3,2)-5.781654528980691E+02*(x*1e3)+4.555588663814002E+01)*1e-3;
z4 = (+1.890688756549617E+00+exp(-(y*1e3)/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+3.961847483962144E-07*pow(y*1e3,8)-1.365263938073278E-05*pow(y*1e3,7)+2.624897094740637E-04*pow(y*1e3,6)-2.449078669846295E-03*pow(y*1e3,5)+1.760903167063099E-02*pow(y*1e3,4)-4.225039211707429E-02*pow(y*1e3,3)+2.178355813518475E-01*pow(y*1e3,2)+5.450932524617216E-01*(y*1e3)+1.766232489218609E+00))*1e-3;
}
else if (Case == 5) {
z1 = (+8.915472792548803E-03*pow(y*1e3,11)-8.534912362770053E-02*pow(y*1e3,10)+3.564490518743868E-01*pow(y*1e3,9)-8.452026545636626E-01*pow(y*1e3,8)+1.244378900021080E+00*pow(y*1e3,7)-1.164755742064439E+00*pow(y*1e3,6)+6.818263133845935E-01*pow(y*1e3,5)-2.221300261736691E-01*pow(y*1e3,4)+3.844482739892839E-02*pow(y*1e3,3)+1.768629697895080E-01*pow(y*1e3,2)+3.325121655837649E-05*(y*1e3)+0.000000000000000E+00)*1e-3;
z2 = (+2.676253446203033E-03*pow(y*1e3,9)-1.849408051053678E-02*pow(y*1e3,8)+5.573643654259904E-02*pow(y*1e3,7)-9.154394236715026E-02*pow(y*1e3,6)+9.128069431344996E-02*pow(y*1e3,5)-4.548271212674311E-02*pow(y*1e3,4)+1.914303865794668E-02*pow(y*1e3,3)+2.034816757139944E-01*pow(y*1e3,2)+3.201563973190555E-04*(y*1e3)-7.428143045156226E-02)*1e-3;
r3 = (-3.123709314648088E-05*pow(x*1e3,24)+1.038309906506804E-03*pow(x*1e3,23)-1.562433609606056E-02*pow(x*1e3,22)+1.395800124505716E-01*pow(x*1e3,21)-8.121861889581281E-01*pow(x*1e3,20)+3.148191043523620E+00*pow(x*1e3,19)-7.789201187464736E+00*pow(x*1e3,18)+1.003573629902521E+01*pow(x*1e3,17)+5.288841891037384E-01*pow(x*1e3,16)-9.084504447478238E+00*pow(x*1e3,15)-6.095118451661253E+01*pow(x*1e3,14)+1.703419891883260E+02*pow(x*1e3,13)+4.216129504824901E+02*pow(x*1e3,12)-3.433620206611360E+03*pow(x*1e3,11)+9.908355497929469E+03*pow(x*1e3,10)-1.706466677192035E+04*pow(x*1e3,9)+1.835565500355895E+04*pow(x*1e3,8)-9.828957426255411E+03*pow(x*1e3,7)-3.802537314714993E+03*pow(x*1e3,6)+1.288815671741646E+04*pow(x*1e3,5)-1.288754918198505E+04*pow(x*1e3,4)+7.587488775978768E+03*pow(x*1e3,3)-2.789462018118803E+03*pow(x*1e3,2)+5.981984419971424E+02*(x*1e3)-5.621802974995823E+01)*1e-3;
z4 = (+1.959289184179813E+00+exp(-(y*1e3)/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+3.667579558689089E-07*pow(y*1e3,8)-1.286193316460832E-05*pow(y*1e3,7)+2.495343530139651E-04*pow(y*1e3,6)-2.371127941845747E-03*pow(y*1e3,5)+1.707978889801498E-02*pow(y*1e3,4)-4.345029398942986E-02*pow(y*1e3,3)+2.100226102193354E-01*pow(y*1e3,2)+4.946628833559660E-01*(y*1e3)+1.744966012667424E+00))*1e-3;
}
else if (Case == 6) {
z1 = (+1.124927072157150E-02*pow(y*1e3,12)-1.117778361352201E-01*pow(y*1e3,11)+4.846257157437565E-01*pow(y*1e3,10)-1.199264798805468E+00*pow(y*1e3,9)+1.865808323041380E+00*pow(y*1e3,8)-1.900268032688820E+00*pow(y*1e3,7)+1.290944003534704E+00*pow(y*1e3,6)-5.935640551767414E-01*pow(y*1e3,5)+2.028929081193303E-01*pow(y*1e3,4)-4.531612120089164E-02*pow(y*1e3,3)+1.914986271371421E-01*pow(y*1e3,2)-2.870071934395852E-04*(y*1e3)+0.000000000000000E+00)*1e-3;
z2 = (+4.494758327991492E-03*pow(y*1e3,11)-4.181232839166163E-02*pow(y*1e3,10)+1.706466393557839E-01*pow(y*1e3,9)-3.982076957822844E-01*pow(y*1e3,8)+5.847233400726854E-01*pow(y*1e3,7)-5.587556702272352E-01*pow(y*1e3,6)+3.510819613343818E-01*pow(y*1e3,5)-1.310386954712479E-01*pow(y*1e3,4)+3.485892981413170E-02*pow(y*1e3,3)+2.116597509159015E-01*pow(y*1e3,2)+3.182005111867819E-04*(y*1e3)-9.639383327565591E-02)*1e-3;
r3 = (-3.087596912819145E-06*pow(x*1e3,26)+7.268001421841417E-05*pow(x*1e3,25)-5.988269950060388E-04*pow(x*1e3,24)+5.139265588345693E-04*pow(x*1e3,23)+2.738147989119212E-02*pow(x*1e3,22)-2.278623450074246E-01*pow(x*1e3,21)+8.220603165975566E-01*pow(x*1e3,20)-8.929744823027228E-01*pow(x*1e3,19)-3.509442322148726E+00*pow(x*1e3,18)+9.743066303997477E+00*pow(x*1e3,17)+2.798573634636314E+01*pow(x*1e3,16)-1.872156527277869E+02*pow(x*1e3,15)+3.007226046048532E+02*pow(x*1e3,14)+4.688483070628662E+02*pow(x*1e3,13)-3.139802868214468E+03*pow(x*1e3,12)+7.194720371383052E+03*pow(x*1e3,11)-1.141077501325201E+04*pow(x*1e3,10)+2.067816004528886E+04*pow(x*1e3,9)-4.918182488475753E+04*pow(x*1e3,8)+1.041313770571485E+05*pow(x*1e3,7)-1.627590069520270E+05*pow(x*1e3,6)+1.826584247578050E+05*pow(x*1e3,5)-1.464597687151276E+05*pow(x*1e3,4)+8.235946129725396E+04*pow(x*1e3,3)-3.098528762292010E+04*pow(x*1e3,2)+7.026327131426672E+03*(x*1e3)-7.263497791520297E+02)*1e-3;
z4 = (+1.938317828072450E+00+exp(-(y*1e3)/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+3.112501365588245E-07*pow(y*1e3,8)-1.011740368851976E-05*pow(y*1e3,7)+1.886127885301112E-04*pow(y*1e3,6)-1.627961839418399E-03*pow(y*1e3,5)+1.147331802673129E-02*pow(y*1e3,4)-1.818325611869879E-02*pow(y*1e3,3)+1.359777765151707E-01*pow(y*1e3,2)+5.797386576988547E-01*(y*1e3)+1.519681364696940E+00))*1e-3;
}
else if (Case == 7) {
z1 = (+6.032840027367756E-01*pow(y*1e3,18)-1.034747503124785E+01*pow(y*1e3,17)+8.158435521347644E+01*pow(y*1e3,16)-3.919250810583663E+02*pow(y*1e3,15)+1.281893400982021E+03*pow(y*1e3,14)-3.021556036772349E+03*pow(y*1e3,13)+5.298872271634809E+03*pow(y*1e3,12)-7.036949060778345E+03*pow(y*1e3,11)+7.134330653727826E+03*pow(y*1e3,10)-5.525017851069726E+03*pow(y*1e3,9)+3.247443045909889E+03*pow(y*1e3,8)-1.428669674292363E+03*pow(y*1e3,7)+4.596743366929156E+02*pow(y*1e3,6)-1.043669331192064E+02*pow(y*1e3,5)+1.585031180292594E+01*pow(y*1e3,4)-1.478448748233937E+00*pow(y*1e3,3)+2.721476892252029E-01*pow(y*1e3,2)-1.395829828619478E-03*(y*1e3)+0.000000000000000E+00)*1e-3;
z2 = (+8.316198455060027E-02*pow(y*1e3,15)-1.150026761894942E+00*pow(y*1e3,14)+7.182127710845053E+00*pow(y*1e3,13)-2.676644689352613E+01*pow(y*1e3,12)+6.627815940569374E+01*pow(y*1e3,11)-1.149075440361159E+02*pow(y*1e3,10)+1.432156217494786E+02*pow(y*1e3,9)-1.297079883778235E+02*pow(y*1e3,8)+8.529722196174643E+01*pow(y*1e3,7)-4.027439977632196E+01*pow(y*1e3,6)+1.335395639403316E+01*pow(y*1e3,5)-2.984996605088992E+00*pow(y*1e3,4)+4.308065018416945E-01*pow(y*1e3,3)+1.987460442127914E-01*pow(y*1e3,2)+1.529177913416072E-03*(y*1e3)-1.502092737769593E-01)*1e-3;
r3 = (-6.462952002815783E-06*pow(x*1e3,28)+1.660572393826929E-04*pow(x*1e3,27)-1.791480054946803E-03*pow(x*1e3,26)+1.006557416350918E-02*pow(x*1e3,25)-2.757775637258781E-02*pow(x*1e3,24)+9.851614608987203E-03*pow(x*1e3,23)+1.069979178420239E-01*pow(x*1e3,22)+1.084083545255772E-01*pow(x*1e3,21)-1.710115966899643E+00*pow(x*1e3,20)+2.424452162457393E+00*pow(x*1e3,19)+4.235165463043534E+00*pow(x*1e3,18)-4.857450985439783E+00*pow(x*1e3,17)-3.287199004739289E+00*pow(x*1e3,16)-2.209991829051377E+02*pow(x*1e3,15)+9.010158776224191E+02*pow(x*1e3,14)-3.599559063767255E+02*pow(x*1e3,13)-3.781650778137994E+03*pow(x*1e3,12)+1.311099275549052E+03*pow(x*1e3,11)+3.435505715780759E+04*pow(x*1e3,10)-7.920780957168083E+04*pow(x*1e3,9)-4.388970620909670E+04*pow(x*1e3,8)+5.726237413715654E+05*pow(x*1e3,7)-1.439427439389998E+06*pow(x*1e3,6)+2.106670277992343E+06*pow(x*1e3,5)-2.047456340135086E+06*pow(x*1e3,4)+1.350693348438106E+06*pow(x*1e3,3)-5.862787112878283E+05*pow(x*1e3,2)+1.519683961374361E+05*(x*1e3)-1.789545662106964E+04)*1e-3;
z4 = (+1.950144199995576E+00+exp(-(y*1e3)/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+1.771439652204018E-07*pow(y*1e3,8)-4.387948680150140E-06*pow(y*1e3,7)+7.133123638140792E-05*pow(y*1e3,6)-3.415198419388539E-04*pow(y*1e3,5)+2.296630865429201E-03*pow(y*1e3,4)+1.725142373421358E-02*pow(y*1e3,3)+2.592783827471624E-02*pow(y*1e3,2)+6.177461602659763E-01*(y*1e3)+1.151784142410524E+00))*1e-3;
}
else if (Case == 8) {
z1 = (+1.023110466698491E-02*pow(y*1e3,35)-1.619717946205029E-01*pow(y*1e3,34)+1.054768256041203E+00*pow(y*1e3,33)-3.397655809084593E+00*pow(y*1e3,32)+4.130602435724366E+00*pow(y*1e3,31)+6.844258544426098E+00*pow(y*1e3,30)-3.043232130813468E+01*pow(y*1e3,29)+3.628708796419274E+01*pow(y*1e3,28)-8.034927560229239E+00*pow(y*1e3,27)-1.393137429114003E+01*pow(y*1e3,26)+8.997812162994708E+01*pow(y*1e3,25)-3.626193291261448E+02*pow(y*1e3,24)+5.198200571293503E+02*pow(y*1e3,23)-3.014118687574323E+02*pow(y*1e3,22)+9.722693565103714E+02*pow(y*1e3,21)-2.708194896701445E+03*pow(y*1e3,20)+1.140087739996066E+03*pow(y*1e3,19)+3.403493705715294E+03*pow(y*1e3,18)+1.201975808671888E+03*pow(y*1e3,17)-8.752400339944144E+03*pow(y*1e3,16)-3.520938317631042E+04*pow(y*1e3,15)+1.782522695693886E+05*pow(y*1e3,14)-3.679921964945815E+05*pow(y*1e3,13)+4.754163339939423E+05*pow(y*1e3,12)-4.299172942104379E+05*pow(y*1e3,11)+2.845048363784255E+05*pow(y*1e3,10)-1.402289303188671E+05*pow(y*1e3,9)+5.162197713099514E+04*pow(y*1e3,8)-1.408282982901494E+04*pow(y*1e3,7)+2.798258244636952E+03*pow(y*1e3,6)-3.938191826992070E+02*pow(y*1e3,5)+3.762837702061519E+01*pow(y*1e3,4)-2.281061508024931E+00*pow(y*1e3,3)+2.788575722635748E-01*pow(y*1e3,2)-1.169492420663609E-03*(y*1e3)+0.000000000000000E+00)*1e-3;
z2 = (+1.398951343285082E+00*pow(y*1e3,24)-2.332727067125230E+01*pow(y*1e3,23)+1.467485975924787E+02*pow(y*1e3,22)-2.101960577109287E+02*pow(y*1e3,21)-3.038008318108298E+03*pow(y*1e3,20)+2.612562828542780E+04*pow(y*1e3,19)-1.164108643858779E+05*pow(y*1e3,18)+3.552784996501544E+05*pow(y*1e3,17)-8.075971392512823E+05*pow(y*1e3,16)+1.420943265564656E+06*pow(y*1e3,15)-1.975300824311701E+06*pow(y*1e3,14)+2.193884137511772E+06*pow(y*1e3,13)-1.957000894143032E+06*pow(y*1e3,12)+1.403252793544079E+06*pow(y*1e3,11)-8.065196161068449E+05*pow(y*1e3,10)+3.692107597105068E+05*pow(y*1e3,9)-1.332803635190936E+05*pow(y*1e3,8)+3.740415875538073E+04*pow(y*1e3,7)-8.004218401711085E+03*pow(y*1e3,6)+1.272265802473709E+03*pow(y*1e3,5)-1.448911307274275E+02*pow(y*1e3,4)+1.123686868723157E+01*pow(y*1e3,3)-3.085538372504257E-01*pow(y*1e3,2)+1.475773147641798E-02*(y*1e3)-2.173289186711275E-01)*1e-3;
r3 = (-5.008912673139158E-05*pow(x*1e3,27)+1.228438300524165E-03*pow(x*1e3,26)-1.249008518986552E-02*pow(x*1e3,25)+6.481650769797284E-02*pow(x*1e3,24)-1.590000089126579E-01*pow(x*1e3,23)+6.637322992321443E-02*pow(x*1e3,22)+8.537149399975134E-02*pow(x*1e3,21)+2.278107100599540E+00*pow(x*1e3,20)-3.008835908776580E+00*pow(x*1e3,19)-3.908660577222337E+01*pow(x*1e3,18)+1.240440783246039E+02*pow(x*1e3,17)+4.872970902143749E+01*pow(x*1e3,16)-3.279289815879526E+02*pow(x*1e3,15)-2.239674074348071E+03*pow(x*1e3,14)+7.765603548886496E+03*pow(x*1e3,13)+7.652315862961751E+03*pow(x*1e3,12)-7.060966580344526E+04*pow(x*1e3,11)+7.388063517595197E+04*pow(x*1e3,10)+2.279705043392706E+05*pow(x*1e3,9)-6.081825299112491E+05*pow(x*1e3,8)-2.955914293816218E+05*pow(x*1e3,7)+3.853088505916576E+06*pow(x*1e3,6)-8.822968010480234E+06*pow(x*1e3,5)+1.139059127557150E+07*pow(x*1e3,4)-9.376240492026070E+06*pow(x*1e3,3)+4.918114277035544E+06*pow(x*1e3,2)-1.511507307491638E+06*(x*1e3)+2.084742402876324E+05)*1e-3;
z4 = (+1.980525937191926E+00+exp(-(y*1e3)/(+2.710523708715753E+00))*pow(1./(y*1e3),0.5)*(+1.293247227135023E-07*pow(y*1e3,8)-2.767100772388310E-06*pow(y*1e3,7)+4.122061701047429E-05*pow(y*1e3,6)-6.972221744923378E-05*pow(y*1e3,5)+3.983187289256702E-04*pow(y*1e3,4)+2.162517219002935E-02*pow(y*1e3,3)+2.247220673179393E-03*pow(y*1e3,2)+5.707703718817071E-01*(y*1e3)+1.054440595337796E+00))*1e-3;
}
bool air1, air2, air3, air4;
air1 = (y >= r_lim_2) && (x >= z4);
air2 = (x >= z_lim_2);
air3 = (x <= z_lim_2) && (x >= z_lim_1) && (y <= r3);
air4 = (x <= z_lim_1) && (x >= z1);
if (air1 || air2 || air3 || air4) { // Air
f1[] = 0.0;
f2[] = 0.0;
}
else if ((x >= z2) && (x <= z1) && y < r_lim_1) { // Oil
f1[] = 1.0;
f2[] = 0.0;
}
else { // Water
f1[] = 1.0;
f2[] = 1.0;
}
if (abs(f1[]*(1.0-f2[])-1.0)<1e-6) { // oil
alphas[] = 2.0;
}
else if (abs(f1[]*f2[]-1.0)<1e-6) { // water
alphas[] = 1.0;
}
else { // air
alphas[] = 3.0;
}
}
}
event acceleration (i++) {
face vector av = a;
foreach_face(x)
av.x[] -= 9.81;
}
event adapt(i++)
{
scalar KAPPA1[], KAPPA2[];
curvature(f1, KAPPA1);
curvature(f2, KAPPA2);
adapt_wavelet((scalar *){f1, f2, u.x, u.y, KAPPA1, KAPPA2},
(double[]){fErr, fErr, VelErr, VelErr, KErr, KErr},
maxlevel = MAXLEVEL, minlevel = MINLEVEL);
}
event printout(i++){
fprintf(stdout,"i= %d t= %.4e mg[ %d %d %d] max(u,v)= %.3e %.3e \n",i, t, mgp.i, mgpf.i, mgu.i, statsf(u.x).max, statsf(u.y).max);
}
event vtkoutput (t = 0; t < 10.0e-3; t += 1e-4)
{
fprintf(stdout, "Output checkpoint file.\n");
char name[500];
sprintf(name, "out-%.2f-CC.out", t*1e5);
dump (file = name);
}
event setFields(i++){
foreach () {
if (abs(f1[]*(1.0-f2[])-1.0)<1e-6) { // oil
alphas[] = 2.0;
}
else if (abs(f1[]*f2[]-1.0)<1e-6) { // water
alphas[] = 1.0;
}
else { // air
alphas[] = 3.0;
}
}
}
three-phase.h
This is a version of the code that I believe is unchanged from the referenced sandbox by Vatsal Sanjay. I’m reproducing it here as I used it just in case he updates his version and the new one isn’t compatible in some way.
#include "vof.h"
scalar f1[], f2[], *interfaces = {f1, f2};
double rho1 = 1., mu1 = 0., rho2 = 1., mu2 = 0., rho3 = 1., mu3 = 0.;
face vector alphav[];
scalar rhov[];
event defaults (i = 0) {
alpha = alphav;
rho = rhov;
if (mu1 || mu2)
mu = new face vector;
}
#ifndef rho
#define rho(f1, f2) (clamp(f1*(1-f2), 0., 1.) * rho1 + clamp(f1*f2, 0., 1.) * rho2 + clamp((1-f1), 0., 1.) * rho3)
#endif
#ifndef mu
#define mu(f1, f2) (clamp(f1*(1-f2), 0., 1.) * mu1 + clamp(f1*f2, 0., 1.) * mu2 + clamp((1-f1), 0., 1.) * mu3)
#endif
#ifdef FILTERED
scalar sf1[], sf2[], *smearInterfaces = {sf1, sf2};
#else
#define sf1 f1
#define sf2 f2
scalar *smearInterfaces = {sf1, sf2};
#endif
event properties (i++) {
if (i > 1){
foreach(){
if (f2[]>f1[]){
f1[] = f2[];
}
}
}
#ifdef FILTERED
int counter1 = 0;
for (scalar sf in smearInterfaces){
counter1++;
int counter2 = 0;
for (scalar f in interfaces){
counter2++;
if (counter1 == counter2){
// fprintf(ferr, "%s %s\n", sf.name, f.name);
#if dimension <= 2
foreach(){
sf[] = (4.*f[] +
2.*(f[0,1] + f[0,-1] + f[1,0] + f[-1,0]) +
f[-1,-1] + f[1,-1] + f[1,1] + f[-1,1])/16.;
}
#else // dimension == 3
foreach(){
sf[] = (8.*f[] +
4.*(f[-1] + f[1] + f[0,1] + f[0,-1] + f[0,0,1] + f[0,0,-1]) +
2.*(f[-1,1] + f[-1,0,1] + f[-1,0,-1] + f[-1,-1] +
f[0,1,1] + f[0,1,-1] + f[0,-1,1] + f[0,-1,-1] +
f[1,1] + f[1,0,1] + f[1,-1] + f[1,0,-1]) +
f[1,-1,1] + f[-1,1,1] + f[-1,1,-1] + f[1,1,1] +
f[1,1,-1] + f[-1,-1,-1] + f[1,-1,-1] + f[-1,-1,1])/64.;
}
#endif
}
}
}
#endif
#if TREE
for (scalar sf in smearInterfaces){
sf.prolongation = refine_bilinear;
boundary ({sf});
}
#endif
foreach_face() {
double ff1 = (sf1[] + sf1[-1])/2.;
double ff2 = (sf2[] + sf2[-1])/2.;
// double rhoTemp = max(rho(ff1, ff2), rho3);
// alphav.x[] = fm.x[]/rhoTemp;
alphav.x[] = fm.x[]/rho(ff1, ff2);
face vector muv = mu;
// double muTemp = max(mu(ff1, ff2), mu3);
// muv.x[] = fm.x[]*muTemp;
muv.x[] = fm.x[]*mu(ff1, ff2);
}
foreach(){
// double rhoTemp = max(rho(sf1[], sf2[]), rho3);
// rhov[] = cm[]*rhoTemp;
rhov[] = cm[]*rho(sf1[], sf2[]);
}
#if TREE
for (scalar sf in smearInterfaces){
sf.prolongation = fraction_refine;
boundary ({sf});
}
#endif
}
vof-3p.h
This is a version of the code that I believe is unchanged from the referenced sandbox by Vatsal Sanjay. I’m reproducing it here as I used it just in case he updates his version and the new one isn’t compatible in some way.
attribute {
scalar * tracers;
bool inverse;
}
#include "fractions-3p.h"
extern scalar * interfaces;
extern face vector uf;
extern double dt;
event defaults (i = 0)
{
#if TREE
for (scalar c in interfaces)
c.refine = c.prolongation = fraction_refine;
#endif
}
event stability (i++) {
if (CFL > 0.5)
CFL = 0.5;
}
foreach_dimension()
static void sweep_x (scalar c, scalar cc)
{
vector n[];
scalar alpha[], flux[];
double cfl = 0.;
scalar * tracers = c.tracers, * gfl = NULL, * tfluxl = NULL;
if (tracers) {
for (scalar t in tracers) {
scalar gf = new scalar, flux = new scalar;
gfl = list_append (gfl, gf);
tfluxl = list_append (tfluxl, flux);
}
foreach() {
scalar t, gf;
for (t,gf in tracers,gfl) {
double cl = c[-1], cc = c[], cr = c[1];
if (t.inverse)
cl = 1. - cl, cc = 1. - cc, cr = 1. - cr;
gf[] = 0.;
static const double cmin = 0.5;
if (cc >= cmin) {
if (cr >= cmin) {
if (cl >= cmin) {
if (t.gradient)
gf[] = t.gradient (t[-1]/cl, t[]/cc, t[1]/cr)/Delta;
else
gf[] = (t[1]/cr - t[-1]/cl)/(2.*Delta);
}
else
gf[] = (t[1]/cr - t[]/cc)/Delta;
}
else if (cl >= cmin)
gf[] = (t[]/cc - t[-1]/cl)/Delta;
}
}
}
boundary (gfl);
}
reconstruction (c, n, alpha);
foreach_face(x, reduction (max:cfl)) {
double un = uf.x[]*dt/(Delta*fm.x[]), s = sign(un);
int i = -(s + 1.)/2.;
if (un*fm.x[]*s/cm[] > cfl)
cfl = un*fm.x[]*s/cm[];
double cf = (c[i] <= 0. || c[i] >= 1.) ? c[i] :
rectangle_fraction ((coord){-s*n.x[i], n.y[i], n.z[i]}, alpha[i],
(coord){-0.5, -0.5, -0.5},
(coord){s*un - 0.5, 0.5, 0.5});
flux[] = cf*uf.x[];
scalar t, gf, tflux;
for (t,gf,tflux in tracers,gfl,tfluxl) {
double cf1 = cf, ci = c[i];
if (t.inverse)
cf1 = 1. - cf1, ci = 1. - ci;
if (ci > 1e-10) {
double ff = t[i]/ci + s*min(1., 1. - s*un)*gf[i]*Delta/2.;
tflux[] = ff*cf1*uf.x[];
}
else
tflux[] = 0.;
}
}
delete (gfl); free (gfl);
#if TREE
scalar * fluxl = list_concat (NULL, tfluxl);
fluxl = list_append (fluxl, flux);
for (int l = depth() - 1; l >= 0; l--)
foreach_halo (prolongation, l) {
#if dimension == 1
if (is_refined (neighbor(-1)))
for (scalar fl in fluxl)
fl[] = fine(fl);
if (is_refined (neighbor(1)))
for (scalar fl in fluxl)
fl[1] = fine(fl,2);
#elif dimension == 2
if (is_refined (neighbor(-1)))
for (scalar fl in fluxl)
fl[] = (fine(fl,0,0) + fine(fl,0,1))/2.;
if (is_refined (neighbor(1)))
for (scalar fl in fluxl)
fl[1] = (fine(fl,2,0) + fine(fl,2,1))/2.;
#else // dimension == 3
if (is_refined (neighbor(-1)))
for (scalar fl in fluxl)
fl[] = (fine(fl,0,0,0) + fine(fl,0,1,0) +
fine(fl,0,0,1) + fine(fl,0,1,1))/4.;
if (is_refined (neighbor(1)))
for (scalar fl in fluxl)
fl[1] = (fine(fl,2,0,0) + fine(fl,2,1,0) +
fine(fl,2,0,1) + fine(fl,2,1,1))/4.;
#endif
}
free (fluxl);
#endif
if (cfl > 0.5 + 1e-6)
fprintf (ferr,
"WARNING: CFL must be <= 0.5 for VOF (cfl - 0.5 = %g)\n",
cfl - 0.5), fflush (ferr);
foreach() {
c[] += dt*(flux[] - flux[1] + cc[]*(uf.x[1] - uf.x[]))/(cm[]*Delta);
scalar t, tflux;
for (t, tflux in tracers, tfluxl)
t[] += dt*(tflux[] - tflux[1])/(cm[]*Delta);
}
boundary ({c});
boundary (tracers);
delete (tfluxl); free (tfluxl);
}
void vof_advection (scalar * interfaces, int i)
{
for (scalar c in interfaces) {
scalar cc[];
foreach()
cc[] = (c[] > 0.5);
void (* sweep[dimension]) (scalar, scalar);
int d = 0;
foreach_dimension()
sweep[d++] = sweep_x;
boundary ({c});
for (d = 0; d < dimension; d++)
sweep[(i + d) % dimension] (c, cc);
}
}
event vof (i++)
vof_advection (interfaces, i);
VTKoutput.h
This is a reproduced version of VTKoutput.h by Chizari. I am reproducing it in the current version to avoid incompatibilities that could occur from future versions.
/* The purpose is to export a vtk ascii file for using in Paraview. There are two main functions, one for the contour plot “output_paraview_CC” and the other for the interface “output_paraview_IF”.
/* These functions may be used as follow, */
/* char name[500]; */
/* sprintf(name, "%s-%.4f-CC.vtk", "out", t); */
/* output_paraview_CC(name, t, 90.0, {f, u.x, u.y}); */
/* sprintf(name, "%s-%.4f-F1.vtk", "out", t); */
/* output_paraview_IF(name, t, 90.0, f); */
/* Creating the VTK format for the contour plot will be done by the following function, note that the “rotationangle” variable is for rotating the whole area CCW. */
#define R_PI 3.1415926535897932384626433832795
void output_paraview_CC(char *name, double time, double rotationangle, scalar *outlist)
{
scalar *list = dump_list(outlist);
;
int i, cellnumber;
// int varNO = list_len(list);
double xxx[4], yyy[4];
const double angle = rotationangle * R_PI / 180.0;
FILE *fp;
scalar vartmp[];
;
cellnumber = 0;
foreach ()
cellnumber++;
;
fp = fopen(name, "w");
fprintf(fp, "# vtk DataFile Version 2.0\r\n");
fprintf(fp, "Unstructured Grid\r\n");
fprintf(fp, "ASCII\r\n");
fprintf(fp, "DATASET UNSTRUCTURED_GRID\r\n");
fprintf(fp, "POINTS %d float\r\n", cellnumber * 4);
foreach_leaf()
{
xxx[0] = x - 0.50 * Delta;
xxx[1] = x + 0.50 * Delta;
xxx[2] = x + 0.50 * Delta;
xxx[3] = x - 0.50 * Delta;
yyy[0] = y - 0.50 * Delta;
yyy[1] = y - 0.50 * Delta;
yyy[2] = y + 0.50 * Delta;
yyy[3] = y + 0.50 * Delta;
fprintf(fp, "%.9f %.9f 0.0\r\n", xxx[0] * cos(angle) - yyy[0] * sin(angle), yyy[0] * cos(angle) + xxx[0] * sin(angle));
fprintf(fp, "%.9f %.9f 0.0\r\n", xxx[1] * cos(angle) - yyy[1] * sin(angle), yyy[1] * cos(angle) + xxx[1] * sin(angle));
fprintf(fp, "%.9f %.9f 0.0\r\n", xxx[2] * cos(angle) - yyy[2] * sin(angle), yyy[2] * cos(angle) + xxx[2] * sin(angle));
fprintf(fp, "%.9f %.9f 0.0\r\n", xxx[3] * cos(angle) - yyy[3] * sin(angle), yyy[3] * cos(angle) + xxx[3] * sin(angle));
}
fprintf(fp, "CELLS %d %d\r\n", cellnumber, cellnumber + cellnumber * 4);
for (i = 0; i < cellnumber; i++)
fprintf(fp, "%d %d %d %d %d\r\n", 4, i * 4 + 0, i * 4 + 1, i * 4 + 2, i * 4 + 3);
fprintf(fp, "CELL_TYPES %d\r\n", cellnumber);
for (i = 0; i < cellnumber; i++)
fprintf(fp, "7\r\n");
fprintf(fp, "CELL_DATA %d\r\n", cellnumber);
for (scalar s in list)
{
if (strcmp(s.name, "cm"))
{
fprintf(fp, "SCALARS %s float\r\n", s.name);
fprintf(fp, "LOOKUP_TABLE default\r\n");
foreach_leaf()
fprintf(fp, "%f\r\n", s[]);
}
};
fclose(fp);
return;
}
//The following function will find the intersection points for 2D.
int findintersectionpoints(double nx, double ny, double alpha, double xc, double yc, double delta, double xi[2], double yi[2], char typei[2])
{
int ppp = 0;
double xtmp[2], ytmp[2], underflow = 1.0e-6;
if (fabs(nx) < underflow)
{
ytmp[0] = (alpha - nx * (-0.50)) / ny;
ytmp[1] = (alpha - nx * (+0.50)) / ny;
xi[ppp] = xc + (-0.50) * delta;
yi[ppp] = yc + (ytmp[0]) * delta;
typei[ppp] = 'l';
(ppp)++;
xi[ppp] = xc + (+0.50) * delta;
yi[ppp] = yc + (ytmp[1]) * delta;
typei[ppp] = 'r';
(ppp)++;
}
else if (fabs(ny) < underflow)
{
xtmp[0] = (alpha - ny * (-0.50)) / nx;
xtmp[1] = (alpha - ny * (+0.50)) / nx;
xi[ppp] = xc + (xtmp[0]) * delta;
yi[ppp] = yc + (-0.50) * delta;
typei[ppp] = 'b';
(ppp)++;
xi[ppp] = xc + (xtmp[1]) * delta;
yi[ppp] = yc + (+0.50) * delta;
typei[ppp] = 't';
(ppp)++;
}
else
{
xtmp[0] = (alpha - ny * (-0.50)) / nx;
xtmp[1] = (alpha - ny * (+0.50)) / nx;
ytmp[0] = (alpha - nx * (-0.50)) / ny;
ytmp[1] = (alpha - nx * (+0.50)) / ny;
if (-0.50 <= ytmp[0] && ytmp[0] <= +0.50)
{
xi[ppp] = xc + (-0.50) * delta;
yi[ppp] = yc + (ytmp[0]) * delta;
typei[ppp] = 'l';
(ppp)++;
}
if (-0.50 <= xtmp[0] && xtmp[0] <= +0.50)
{
xi[ppp] = xc + (xtmp[0]) * delta;
yi[ppp] = yc + (-0.50) * delta;
typei[ppp] = 'b';
(ppp)++;
}
if (-0.50 <= ytmp[1] && ytmp[1] <= +0.50)
{
xi[ppp] = xc + (+0.50) * delta;
yi[ppp] = yc + (ytmp[1]) * delta;
typei[ppp] = 'r';
(ppp)++;
}
if (-0.50 <= xtmp[1] && xtmp[1] <= +0.50)
{
xi[ppp] = xc + (xtmp[1]) * delta;
yi[ppp] = yc + (+0.50) * delta;
typei[ppp] = 't';
(ppp)++;
}
}
return true;
}
//And the VTK format of the interface will be,
void output_paraview_IF(char *name, double time, double rotationangle, scalar intrfc)
{
int interfacepoints, cellnumber, i;
char typei[2], *typeintersect;
double xi[2], yi[2], *xintersect, *yintersect;
FILE *fp;
const double angle = rotationangle * R_PI / 180.0;
scalar alpha[];
vector n[];
;
cellnumber = 0;
foreach ()
cellnumber++;
xintersect = (double *)calloc(sizeof(double), cellnumber);
yintersect = (double *)calloc(sizeof(double), cellnumber);
typeintersect = (char *)calloc(sizeof(char), cellnumber);
;
reconstruction(intrfc, n, alpha);
interfacepoints = 0;
foreach_leaf()
{
if (intrfc[] > R_VOFLIMIT && intrfc[] < 1.0 - R_VOFLIMIT)
{
findintersectionpoints(n.x[], n.y[], alpha[], x, y, Delta, xi, yi, typei);
xintersect[interfacepoints] = xi[0] * cos(angle) - yi[0] * sin(angle);
yintersect[interfacepoints] = yi[0] * cos(angle) + xi[0] * sin(angle);
typeintersect[interfacepoints] = typei[0];
interfacepoints++;
xintersect[interfacepoints] = xi[1] * cos(angle) - yi[1] * sin(angle);
yintersect[interfacepoints] = yi[1] * cos(angle) + xi[1] * sin(angle);
typeintersect[interfacepoints] = typei[1];
interfacepoints++;
}
};
fp = fopen(name, "w");
fprintf(fp, "# vtk DataFile Version 2.0\r\n");
fprintf(fp, "Unstructured Grid\r\n");
fprintf(fp, "ASCII\r\n");
fprintf(fp, "DATASET UNSTRUCTURED_GRID\r\n");
switch (interfacepoints)
{
case 0:
{
fprintf(fp, "POINTS %d float\r\n", 2);
foreach_leaf()
{
fprintf(fp, "%.9f %.9f 0.0\r\n", x, y);
fprintf(fp, "%.9f %.9f 0.0\r\n", x, y);
break;
}
fprintf(fp, "CELLS %d %d\r\n", 1, 3);
fprintf(fp, "%d %d %d\r\n", 2, 0, 1);
fprintf(fp, "CELL_TYPES %d\r\n", 1);
fprintf(fp, "3\r\n");
break;
}
default:
{
fprintf(fp, "POINTS %d float\r\n", interfacepoints);
for (i = 0; i < interfacepoints; i++)
fprintf(fp, "%.9f %.9f 0.0\r\n", xintersect[i], yintersect[i]);
fprintf(fp, "CELLS %d %d\r\n", interfacepoints / 2, interfacepoints + interfacepoints / 2);
for (i = 0; i < interfacepoints / 2; i++)
fprintf(fp, "%d %d %d\r\n", 2, i * 2 + 0, i * 2 + 1);
fprintf(fp, "CELL_TYPES %d\r\n", interfacepoints / 2);
for (i = 0; i < interfacepoints / 2; i++)
fprintf(fp, "3\r\n");
break;
}
};
free(xintersect);
free(yintersect);
fclose(fp);
return;
}