static void gfs_skew_symmetric_run (GfsSimulation * sim) { GfsVariable * p, * res = NULL, * gmac[FTT_DIMENSION]; GfsDomain * domain; GSList * i; domain = GFS_DOMAIN (sim); p = gfs_variable_from_name (domain->variables, "P"); g_assert (p); FttComponent c; for (c = 0; c < FTT_DIMENSION; c++) gmac[c] = gfs_temporary_variable (domain); gfs_variable_set_vector (gmac, FTT_DIMENSION); gfs_simulation_refine (sim); gfs_simulation_init (sim); i = domain->variables; while (i) { if (GFS_IS_VARIABLE_RESIDUAL (i->data)) res = i->data; i = i->next; } gfs_simulation_set_timestep (sim); GfsVariable ** u = gfs_domain_velocity (domain); GfsVariable ** velfaces = GFS_SKEW_SYMMETRIC(sim)->velfaces; GfsVariable ** velold = GFS_SKEW_SYMMETRIC(sim)->velold; FaceData fd = { velfaces, velold, u, p, &sim->advection_params.dt, GFS_SKEW_SYMMETRIC(sim)->beta}; if (sim->time.i == 0) { gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) reset_unold, &fd); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) get_face_values, &fd); gfs_mac_projection (domain, &sim->projection_params, sim->advection_params.dt/2., p, sim->physical_params.alpha, gmac, NULL); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) get_velfaces, &fd); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) initialize_unold, &fd); } 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); gfs_skew_symmetric_momentum (sim, &fd, gmac); gfs_mac_projection (domain, &sim->projection_params, sim->advection_params.dt/2., p, sim->physical_params.alpha, gmac, NULL); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) correct_face_velocity, NULL); gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) get_velfaces, &fd); gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttCellTraverseFunc) get_cell_values, &fd); gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1, (FttCellTraverseFunc) gfs_cell_coarse_init, domain); gfs_simulation_adapt (sim); sim->time.t = sim->tnext; sim->time.i++; gfs_simulation_set_timestep (sim); gfs_advance_tracers (sim, sim->advection_params.dt); 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); for (c = 0; c < FTT_DIMENSION; c++) gts_object_destroy (GTS_OBJECT (gmac[c])); }
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)); }
static void gfs_porous_run (GfsSimulation * sim) { GfsVariable * p, * pmac, * res = NULL, * g[FTT_DIMENSION], * gmac[FTT_DIMENSION]; GfsVariable ** gc = sim->advection_params.gc ? g : NULL; GfsDomain * domain; GfsPorous *por; GSList * i; domain = GFS_DOMAIN (sim); por = GFS_POROUS (sim); p = gfs_variable_from_name (domain->variables, "P"); g_assert (p); pmac = gfs_variable_from_name (domain->variables, "Pmac"); g_assert (pmac); FttComponent c; for (c = 0; c < FTT_DIMENSION; c++) { gmac[c] = gfs_temporary_variable (domain); if (sim->advection_params.gc) g[c] = gfs_temporary_variable (domain); else g[c] = gmac[c]; } gfs_variable_set_vector (gmac, FTT_DIMENSION); gfs_variable_set_vector (g, FTT_DIMENSION); gfs_simulation_refine (sim); gfs_simulation_init (sim); i = domain->variables; while (i) { if (GFS_IS_VARIABLE_RESIDUAL (i->data)) res = i->data; i = i->next; } gfs_simulation_set_timestep (sim); if (sim->time.i == 0) { /*inserted changes inside this function*/ gfs_approximate_projection_por (domain, por, &sim->approx_projection_params, sim->advection_params.dt, p, sim->physical_params.alpha, res, g, NULL); gfs_simulation_set_timestep (sim); gfs_advance_tracers (sim, sim->advection_params.dt/2.); } else if (sim->advection_params.gc) gfs_update_gradients_por (domain, por, p, sim->physical_params.alpha, g); 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); /*inserted changes */ gfs_pre_projection (domain, por, FTT_DIMENSION); if (sim->advection_params.linear) { /* linearised advection */ gfs_domain_face_traverse (domain, FTT_XYZ, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL); gfs_domain_face_traverse (domain, FTT_XYZ, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, (FttFaceTraverseFunc) gfs_face_interpolated_normal_velocity, sim->u0); } else gfs_predicted_face_velocities (domain, FTT_DIMENSION, &sim->advection_params); gfs_variables_swap (p, pmac); gfs_mac_projection_por (domain, por, &sim->projection_params, sim->advection_params.dt/2., p, sim->physical_params.alpha, gmac, NULL); gfs_variables_swap (p, pmac); gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim); gfs_centered_velocity_advection_diffusion (domain, FTT_DIMENSION, &sim->advection_params, gmac, sim->time.i > 0 || !gc ? gc : gmac, sim->physical_params.alpha); if (gc) { gfs_source_darcy_implicit (domain, sim->advection_params.dt); gfs_correct_centered_velocities (domain, FTT_DIMENSION, sim->time.i > 0 ? gc : gmac, -sim->advection_params.dt); /*inserted changes*/ gfs_post_projection (domain, por, FTT_DIMENSION); } else if (gfs_has_source_coriolis (domain)) { gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, sim->advection_params.dt); gfs_source_darcy_implicit (domain, sim->advection_params.dt); gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, -sim->advection_params.dt); /*inserted changes*/ gfs_post_projection (domain, por, FTT_DIMENSION); } gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1, (FttCellTraverseFunc) gfs_cell_coarse_init, domain); gfs_simulation_adapt (sim); /*inserted changes */ gfs_approximate_projection_por (domain, por, &sim->approx_projection_params, sim->advection_params.dt, p, sim->physical_params.alpha, res, g, NULL); /*inserted changes */ sim->time.t = sim->tnext; sim->time.i++; gfs_simulation_set_timestep (sim); gfs_advance_tracers (sim, sim->advection_params.dt); 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); for (c = 0; c < FTT_DIMENSION; c++) { gts_object_destroy (GTS_OBJECT (gmac[c])); if (sim->advection_params.gc) gts_object_destroy (GTS_OBJECT (g[c])); } }