#include "grid/octree.h" // For 3D
#include "view.h" // For bview
#include "navier-stokes/centered.h" // Navier stokes
// #include "tracer.h" // Tracers
// #include "diffusion.h" // Diffusion
#include "embed.h"
#include "PointTriangle.h"
/** Global variables */
int minlevel, maxlevel; // Grid depths
double meps, eps; // Maximum error and error in u fields
double TEND = 15;
double H = 5, W = 80, D = 2; //Height (y), width (z) and `depth`(x)
double xp = 200, zp = 200;
#define CP 1005. // C_p for air
#define gCONST 9.81 // Gravitational constant
#define TREF 273. // Kelvin
#define INVERSION .3 // Kelvin per meter
#define karman 0.4 // von Karman constant
#define roughY0u 0.1 // roughness wind length
#define roughY0h 0.1 // roughness heat length
#define WIND(s) (max(0.1*log(s/roughY0u),0.)) // log Wind profile
// #define QFLX 0. // 0 (0.001 = 20wm2)
// #define BSURF (1.5*b[] - 0.5*b[0, 1])
// #define GFLX (-Lambda*(BSURF - bd))
// double Lambda = 0.005, bd = 0.; // Grass coupling
// #define STRAT(s) gCONST/TREF*s*INVERSION
// scalar b[];
// scalar * tracers = {b};
double crho = 1.;
// face vector av[];
// #include "physics.h" // Physics of the simulation
// #include "fan.h" // Include a fan
#include "lambda2.h"
face vector muc[];
double nu;
int main() {
nu = 1./300.;
minlevel = 4;
maxlevel = 9;
L0 = 400.;
X0 = Y0 = Z0 = 0.;
mu = muc;
init_grid(1<<8);
// a = av;
// meps = 10.; // Maximum adaptivity criterion
// DT = 0.5; // For poisson solver
// TOLERANCE=10E-4; // For poisson solver
// CFL = 0.8; // CFL condition
run(); // Start simulation
}
event init(t=0) {
eps = .05;
// u.n[bottom] = dirichlet(0.);
// u.t[bottom] = dirichlet(0.);
// u.n[top] = dirichlet(0.);
// u.t[top] = dirichlet(WIND(y));
// u.n[embed] = dirichlet(0.);
// u.t[embed] = dirichlet(0.);
// periodic (left);
// #if dimension == 3
// u.r[embed] = dirichlet(0.);
// periodic(front);
// #endif
u.n[left] = dirichlet(WIND(y));
p[left] = neumann(0.);
pf[left] = neumann(0.);
u.n[right] = neumann(0.);
p[right] = dirichlet(0.);
pf[right] = dirichlet(0.);
u.n[embed] = dirichlet(0.);
u.t[embed] = dirichlet(0.);
#if dimension == 3
u.r[embed] = dirichlet(0.);
// periodic(back);
#endif
vertex scalar phw[];
D /= 2.;
H -= D/2;
W -= W/2;
foreach_vertex() {
coord cc = {x, y, z};
if ((z - zp) > W/2) { // distance to a side edge
coord p1 = {xp, Y0, zp + W/2.}, p2 = {xp, Y0 + H, zp + W/2.};
coord tmp1[1]; double tmp2[1];
phw[] = sqrt (PointSegmentDistance (&cc, &p1, &p2, tmp1, tmp2));
}
else if ((z - zp) < -W/2) {
coord p1 = {xp, Y0, zp - W/2.}, p2 = {xp, Y0 + H, zp - W/2.};
coord tmp1[1]; double tmp2[1];
phw[] = sqrt (PointSegmentDistance (&cc, &p1, &p2, tmp1, tmp2));
}
else if (y - Y0 > H) {
coord p1 = {xp, Y0 + H, zp - W/2.}, p2 = {xp, Y0 + H, zp + W/2.};
coord tmp1[1]; double tmp2[1];
phw[] = sqrt (PointSegmentDistance (&cc, &p1, &p2, tmp1, tmp2));
}
else
phw[] = fabs(cc.x - xp);
}
fractions (phw, cs, fs, D);
boundary ({cs, fs});
foreach()
u.x[] = cs[] ? WIND(y) : 0.;
// while(adapt_wavelet((scalar *){cs, u},(double []){0.01,eps,eps,eps},maxlevel,minlevel).nf) {
// foreach() {
// u.x[] = cs[]? WIND(y): 0.;
// }
// }
}
event properties (i++) {
foreach_face()
muc.x[] = fm.x[]*nu;
boundary ((scalar*){muc});
}
// event inflow(i++){
// double sides = 50;
// double relaxtime = dt/50;
// foreach(){
// if((x < sides || x > L0-sides) ||
// (z < sides || z > L0-sides) ||
// (y > L0-2*sides )) {
// double a = (x < sides) ? x : fabs(x-L0);
// a = 1.;
// u.x[] = u.x[] + a*(WIND(y)-u.x[])*relaxtime;
// // b[] = b[] + a*(STRAT(y) - b[])*relaxtime;
// u.y[] = u.y[] - a*u.y[]*relaxtime;
// u.z[] = u.z[] - a*u.z[]*relaxtime;
// }
// }
// }
// event tracer_diffusion(i++){
// scalar r[];
// foreach() {
// r[] = 0;
// if (y < Delta)
// r[] = (QFLX + GFLX)/sq(Delta); // div needed as normalization
// }
// double flx = 0, bt = 0;
// double fctr = CP*TREF/gCONST;
// foreach_boundary(bottom reduction(+:flx) reduction(+:bt)) {
// flx = flx + (QFLX + GFLX) * sq(Delta);
// bt = bt + BSURF * sq(Delta);
// }
// bt = bt/sq(L0);
// flx = flx/sq(L0);
// fprintf(stderr, "soil=%g %g %g %d\n", t, fctr*flx, fctr*bt/CP, i);
// mgb = diffusion(b, dt, mu, r = r);
// }
event adapt(i++) {
adapt_wavelet((scalar *){cs,u},(double []){0.01,eps,eps,eps},maxlevel,minlevel);
}
event progress(i++) {
fprintf (stderr, "%d %g %d %d\n", i, t, mgp.i, mgu.i);
}
event mov (t += 0.5) {
#if (dimension == 2)
scalar omega[];
vorticity (u, omega);
boundary ({omega});
// draw_vof ("cs", "fs", filled = -1, fc = {0,0,0});
// draw_vof ("cs", "fs");
squares ("omega", linear = true, map = cool_warm);
mirror ({0,-1})
cells();
#elif (dimension == 3)
scalar l2[], vyz[];
foreach()
vyz[] = ((u.y[0,0,1] - u.y[0,0,-1]) - (u.z[0,1] - u.z[0,-1]))/(2.*Delta);
boundary ({vyz});
lambda2 (u, l2);
view (fov = 30, theta = 0.5, phi = 0.4,
tx = -0.1, ty = 0.1, bg = {65./256,157./256,217./256},
width = 1080, height = 1080);
box();
draw_vof ("cs", "fs", fc = {0.5,0.1,0.2});
draw_vof ("cs", "fs");
isosurface ("l2", -0.01);
translate (y = -5){
squares ("u.x", n = {0,1,0}, alpha = 5.,
min = -1.2, max = 2, map = cool_warm);}
// translate (z = -L0/2.){
// squares ("b", n = {0,0,1}, alpha = L0/2.,
// min = -0.1, max = 0.6, map = cool_warm);}
// translate (x = -L0/2.){
// squares ("b", n = {1,0,0}, alpha = L0/2.,
// min = -0.1, max = 0.6, map = cool_warm);}
#endif
save ("lam_3D.mp4");
}
event end(t=TEND) {
}