sandbox/Antoonvh/tree/add_branches.c
A rapidly growing tree
This page tests the combination of the centered solver with an increasing number of embedded tree branches. Using this, the new tree is automatically initilaized with a nearly consistent complex flow field.
It seems to work well in 2D
#include "embed.h"
#include "navier-stokes/centered.h"
#include "navier-stokes/double-projection.h"
#include "view.h"
#include "treegen.h"
#define BVIEW 1
#include "../particles.h"
Branch * trees;
double Re = 500;
int maxlevel = 10, minlevel = 4;
int nt;
void prolongate_ratio (Point point, scalar s) {
foreach_child() {
if (s[] != nodata)
[] += s[]*Delta;
s}
}
.t[embed] = dirichlet (0.);
u.n[embed] = dirichlet (0.);
u#if dimension == 3
.r[embed] = dirichlet (0.);
u#endif
scalar J[], res[];
face vector muc[];
int main () {
periodic (left);
= muc;
mu = tree_skeleton();
trees #if _MPI
(trees, sizeof(Branch)*nb, MPI_BYTE, 0, MPI_COMM_WORLD);
MPI_Bcast #endif
= nb;
nt = 55;
L0 = Z0 = -L0/2;
X0 = 1;
nb (0); //Reproducible tree
srand.prolongation = prolongate_ratio;
res= (1 << 9);
N run();
}
event init0 (t = 0) {
foreach()
.x[] = cs[];
uboundary (all);
}
event init (t = 0) {
if (n_part < 1)
init_particles_2D_square_grid (10, -19., 15., 15.);
for (scalar s in all) //Naive refinement to circumvent assertions
if (s.refine == refine_embed_linear || s.prolongation == refine_embed_linear)
.refine = s.prolongation = refine_bilinear;
sdo {
tree_interface (trees, cs, fs, J);
foreach() {
[] = nodata;
resif (cs[] > 0 && cs[] < 1) {
[] = 1/sqrt(trees[(int)(J[] + 0.5)].R/Re);
res}
}
boundary ({res, u});
} while (adapt_wavelet ({res, u}, (double[]){2, 0.1, 0.1, 0.1},
, minlevel).nf > 10);
maxlevel// Correct for the naive refinement
foreach() {
foreach_dimension()
.x[] *= cs[];
u}
foreach_face() // uf[embed] = 0, this fixes assertions in timestep.h
.x[] *= fs.x[];
uf= 0.1;
DT }
A branch is added every-so-often by increasing nb
and
calling all init
events.
event add_branch (t = 15; t += 15) {
= min(nb++, nt);
nb event ("init");
}
event properties (i++) {
foreach_face()
.x[] = fs.x[]/Re;
mucboundary ((scalar*){muc});
}
event mov (t += 0.25) {
scalar omg[];
vorticity (u, omg);
scatter (loc, pc = {sin(pid()), cos(pid()), sin(2.3*pid())});
draw_vof ("cs", "fs", filled = -1, fc= {98./128., 78./128, 44./128.});
squares ("omg", min = -5, max = 5, map = cool_warm);
mirror ({0,-1})
cells();
save ("mov.mp4");
}
event adapt (i++) {
foreach() {
[] = nodata;
resif (cs[] > 0 && cs[] < 1) {
[] = 1/sqrt(trees[(int)(J[] + 0.5)].R/Re);
res}
}
boundary ({res});
({res, u}, (double[]){2, 0.1, 0.1, 0.1}, maxlevel, minlevel);
adapt_wavelet }
event stop (t = 200) {
free (trees);
return 1;
}