static void gfs_skew_symmetric_momentum (GfsSimulation * sim, FaceData * fd, GfsVariable **gmac) { GfsDomain * domain = GFS_DOMAIN (sim); FttComponent c; FttDirection d; /* it is used for implementation of viscosity (improve?) */ GfsSourceDiffusion * dif = source_diffusion_viscosity (fd->u[0]); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) advance_face_values, fd); /* boundary conditions */ for (d = 0; d < FTT_NEIGHBORS; d++) gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, fd->velfaces[d]); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) advection_term, fd); if (dif) { DataDif dd = { dif , sim->physical_params.alpha, fd }; gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) diffusion_term, &dd); } /* regularize flux at faces */ for (c = 0; c < FTT_DIMENSION; c++) gfs_domain_face_bc (domain, c, fd->u[c]); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) obtain_face_fluxes, NULL); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) update_vel, fd); gfs_velocity_face_sources (domain, fd->u, (*fd->dt), sim->physical_params.alpha, gmac); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) correct_face_velocity, NULL); }
void gfs_post_projection (GfsDomain *domain, GfsPorous *por, guint dimension) { GfsVariable **v; FttComponent c; gpointer data[3]; g_return_if_fail (domain != NULL); data[0] = v = gfs_domain_velocity (domain); data[1] = &dimension; data[2] = por; gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) correct_por_undo, data); for (c = 0; c < dimension; c++) gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, v[c]); printf("\nvelocity correction undo !!!\n"); }
static void gse_alleviation_diffusion (GfsDomain * domain, GfsVariable * F, FttVector * cg, gdouble dt) { gfs_domain_timer_start (domain, "gse_alleviation"); gdouble ncg = sqrt (cg->x*cg->x + cg->y*cg->y); gdouble dcg = (GFS_WAVE_GAMMA - 1./GFS_WAVE_GAMMA)*ncg/2.; gdouble dtheta = 2.*M_PI/GFS_WAVE (domain)->ntheta; #if 0 gdouble Ts = 4.*GFS_WAVE (domain)->alpha_s*GFS_WAVE (domain)->alpha_s*dt; gdouble dtDss = dt*dcg*dcg*Ts/12.; gdouble dtDnn = dt*(ncg*dtheta)*(ncg*dtheta)*Ts/12.; #else gdouble alpha = GFS_WAVE (domain)->alpha_s*dcg*dt; gdouble beta = GFS_WAVE (domain)->alpha_s*ncg*dtheta*dt; gdouble dtDss = alpha*alpha/3.; gdouble dtDnn = beta*beta/3.; #endif GSEData p; gdouble cost = cg->x/ncg, sint = cg->y/ncg; p.D[0][0] = dtDss*cost*cost + dtDnn*sint*sint; p.D[1][1] = dtDss*sint*sint + dtDnn*cost*cost; p.D[0][1] = p.D[1][0] = (dtDss - dtDnn)*cost*sint; p.F = F; p.Fn = gfs_temporary_variable (domain); p.dF = gfs_temporary_variable (domain); gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) copy_F, &p); gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1, (FttCellTraverseFunc) p.Fn->fine_coarse, p.Fn); for (p.dF->component = 0; p.dF->component < 2; p.dF->component++) { gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1, (FttCellTraverseFunc) compute_gradient, &p); gfs_domain_bc (domain, FTT_TRAVERSE_ALL, -1, p.dF); gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) diffusion, &p); } gts_object_destroy (GTS_OBJECT (p.Fn)); gts_object_destroy (GTS_OBJECT (p.dF)); gfs_domain_timer_stop (domain, "gse_alleviation"); }
static void wave_run (GfsSimulation * sim) { GfsDomain * domain = GFS_DOMAIN (sim); GfsWave * wave = GFS_WAVE (sim); SolidFluxParams par; par.div = gfs_variable_from_name (domain->variables, "P"); g_assert (par.div); par.p = &sim->advection_params; par.fv = gfs_temporary_variable (domain); gfs_simulation_refine (sim); gfs_simulation_init (sim); while (sim->time.t < sim->time.end && sim->time.i < sim->time.iend) { gdouble tstart = gfs_clock_elapsed (domain->timer); gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim); /* get global timestep */ gfs_domain_face_traverse (domain, FTT_XYZ, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL); gfs_simulation_set_timestep (sim); gdouble dt = sim->advection_params.dt; gdouble g = sim->physical_params.g/sim->physical_params.L; gdouble tnext = sim->tnext; /* spatial advection */ guint ik, ith; for (ik = 0; ik < wave->nk; ik++) { FttVector cg; group_velocity (ik, 0, &cg, wave->ntheta, g); gfs_domain_face_traverse (domain, FTT_XYZ, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttFaceTraverseFunc) set_group_velocity, &cg); if (wave->alpha_s > 0.) { /* stability criterion for GSE diffusion */ gdouble cfl = sim->advection_params.cfl; sim->advection_params.cfl = MIN (cfl, 2./(4.*wave->alpha_s*M_PI/wave->ntheta)); /* fixme: this should be: sim->advection_params.cfl = MIN (cfl, sqrt(3.)/(wave->alpha_s*2.*M_PI/wave->ntheta)); */ gfs_simulation_set_timestep (sim); sim->advection_params.cfl = cfl; } else gfs_simulation_set_timestep (sim); /* subcycling */ guint n = rint (dt/sim->advection_params.dt); g_assert (fabs (sim->time.t + sim->advection_params.dt*n - tnext) < 1e-12); while (n--) { for (ith = 0; ith < wave->ntheta; ith++) { FttVector cg; group_velocity (ik, ith, &cg, wave->ntheta, g); gfs_domain_face_traverse (domain, FTT_XYZ, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttFaceTraverseFunc) set_group_velocity, &cg); GfsVariable * t = GFS_WAVE (sim)->F[ik][ith]; sim->advection_params.v = t; gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) solid_flux, &par); gfs_tracer_advection_diffusion (domain, &sim->advection_params, NULL); sim->advection_params.fv = par.fv; gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) gfs_advection_update, &sim->advection_params); if (wave->alpha_s > 0.) gse_alleviation_diffusion (domain, t, &cg, sim->advection_params.dt); gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, t); gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1, (FttCellTraverseFunc) t->fine_coarse, t); } gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) redo_some_events, sim); gfs_simulation_adapt (sim); } } sim->advection_params.dt = dt; /* source terms */ if (wave->source) (* wave->source) (wave); sim->time.t = sim->tnext = tnext; sim->time.i++; gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart); gts_range_update (&domain->timestep); gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1)); gts_range_update (&domain->size); } gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim); gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL); gts_object_destroy (GTS_OBJECT (par.fv)); }