static void implicit_darcy_2D (FttCell * cell, GfsSourceDarcy * s) { GfsSourceVelocity * sv = GFS_SOURCE_VELOCITY (s); gdouble m[2][2]; gdouble f[2]; GfsSimulation * sim = gfs_object_simulation (s); gdouble dt = sim->advection_params.dt; darcy_coefficients (s, cell, sv->v, FTT_X, f); gdouble d = s->darcycoeff ? gfs_function_value (s->darcycoeff, cell):0.; gdouble e = s->forchhicoeff ? gfs_function_value (s->forchhicoeff, cell):0.; f[0] *= d; f[1] *= e; m[0][0] = 1. + (f[0]+f[1])*dt; m[0][1] = 0; darcy_coefficients (s, cell, sv->v, FTT_Y, f); m[1][0] = 0; m[1][1] = 1. + (f[0]+f[1])*dt; gdouble det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; gdouble u = GFS_VALUE (cell, sv->v[0]); gdouble v = GFS_VALUE (cell, sv->v[1]); GFS_VALUE (cell, sv->v[0]) = ( m[1][1]*u - m[0][1]*v)/det; GFS_VALUE (cell, sv->v[1]) = (- m[1][0]*u + m[0][0]*v)/det; }
static void gfs_refine_read (GtsObject ** o, GtsFile * fp) { GfsRefine * refine = GFS_REFINE (*o); GtsObjectClass * klass; gboolean class_changed = FALSE; if (fp->type != GTS_STRING) { gts_file_error (fp, "expecting a string (GfsRefineClass)"); return; } klass = gfs_object_class_from_name (fp->token->str); if (klass == NULL) { gts_file_error (fp, "unknown class `%s'", fp->token->str); return; } if (!gts_object_class_is_from_class (klass, gfs_refine_class ())) { gts_file_error (fp, "`%s' is not a GfsRefine", fp->token->str); return; } if (klass != (*o)->klass) { *o = gts_object_new (klass); gts_object_destroy (GTS_OBJECT (refine)); refine = GFS_REFINE (*o); class_changed = TRUE; } gts_file_next_token (fp); gfs_function_read (refine->maxlevel, gfs_object_simulation (refine), fp); if (fp->type == GTS_ERROR) return; if (class_changed && fp->type != '\n' && klass->read) (* klass->read) (o, fp); }
static void refine_solid_destroy (GtsObject * object) { gfs_domain_remove_derived_variable (GFS_DOMAIN (gfs_object_simulation (object)), "SolidCurvature"); (* GTS_OBJECT_CLASS (gfs_refine_solid_class ())->parent_class->destroy) (object); }
static void init_energy (FttCell * cell, GfsInitWave * event) { GfsWave * wave = GFS_WAVE (gfs_object_simulation (event)); for (wave->ik = 0; wave->ik < wave->nk; wave->ik++) for (wave->ith = 0; wave->ith < wave->ntheta; wave->ith++) GFS_VALUE (cell, wave->F[wave->ik][wave->ith]) = gfs_function_value (event->d, cell); }
static void gfs_source_darcy_read (GtsObject ** o, GtsFile * fp) { (* GTS_OBJECT_CLASS (gfs_source_darcy_class ())->parent_class->read) (o, fp); if (fp->type == GTS_ERROR) return; printf("\ntesting1\n"); /*Check if source darcy has already been added or not*/ FttComponent c; for (c = 0; c < FTT_DIMENSION; c++) { GfsVariable * v = GFS_SOURCE_VELOCITY (*o)->v[c]; if (v->sources) { GSList * i = GTS_SLIST_CONTAINER (v->sources)->items; while (i) { if (i->data != *o && GFS_IS_SOURCE_DARCY (i->data)) { gts_file_error (fp, "variable '%s' cannot have multiple Darcy source terms", v->name); return; } i = i->next; } } } printf("\ntesting2\n"); GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o)); GfsSourceDarcy * s = GFS_SOURCE_DARCY (*o); printf("\ntesting3\n"); s->darcycoeff = gfs_function_new (gfs_function_class (), 0.); gfs_function_read (s->darcycoeff, gfs_object_simulation (s), fp); printf("\ntesting4\n"); if (fp->type != '\n') { s->forchhicoeff = gfs_function_new (gfs_function_class (), 0.); gfs_function_read (s->forchhicoeff, gfs_object_simulation (s), fp); } if (s->beta < 1.) for (c = 0; c < FTT_DIMENSION; c++) s->u[c] = gfs_temporary_variable (domain); else { GFS_SOURCE_GENERIC (s)->centered_value = NULL; GFS_SOURCE_GENERIC (s)->mac_value = NULL; } printf("\ntesting5\n"); }
static void refine_surface_read (GtsObject ** o, GtsFile * fp) { (* GTS_OBJECT_CLASS (gfs_refine_surface_class ())->parent_class->read) (o, fp); if (fp->type == GTS_ERROR) return; gfs_generic_surface_read (GFS_REFINE_SURFACE (*o)->surface, gfs_object_simulation (*o), fp); }
static void refine_distance_destroy (GtsObject * object) { GfsRefineDistance * d = GFS_REFINE_DISTANCE (object); if (d->stree) gts_bb_tree_destroy (d->stree, TRUE); gfs_domain_remove_derived_variable (GFS_DOMAIN (gfs_object_simulation (object)), "Distance"); (* GTS_OBJECT_CLASS (gfs_refine_distance_class ())->parent_class->destroy) (object); }
static void projection_transform (GfsMap * map, const FttVector * src, FttVector * dest) { projLP idata; projXY odata; GfsMapProjection * m = GFS_MAP_PROJECTION (map); gdouble L = gfs_object_simulation (map)->physical_params.L; idata.u = src->x*L*DEG_TO_RAD; idata.v = src->y*L*DEG_TO_RAD; odata = pj_fwd (idata, m->pj); dest->x = (odata.u*m->cosa - odata.v*m->sina)/L; dest->y = (odata.v*m->cosa + odata.u*m->sina)/L; dest->z = src->z; }
static void refine_solid_read (GtsObject ** o, GtsFile * fp) { GfsRefineSolid * refine = GFS_REFINE_SOLID (*o); GfsDerivedVariableInfo v = { "SolidCurvature", "curvature of the solid boundary", solid_curvature }; refine->v = gfs_domain_add_derived_variable (GFS_DOMAIN (gfs_object_simulation (*o)), v); if (!refine->v) { gts_file_error (fp, "derived variable `SolidCurvature' already defined"); return; } (* GTS_OBJECT_CLASS (gfs_refine_solid_class ())->parent_class->read) (o, fp); }
static void scale_energy (FttCell * cell, GfsInitWave * event) { GfsWave * wave = GFS_WAVE (gfs_object_simulation (event)); gdouble E = cell_E (cell, NULL, GFS_DOMAIN (wave)); if (E > 0.) { gdouble Hs = gfs_function_value (event->hs, cell); gdouble scaling = Hs*Hs/(16.*E); guint ik, ith; for (ik = 0; ik < wave->nk; ik++) for (ith = 0; ith < wave->ntheta; ith++) GFS_VALUE (cell, wave->F[ik][ith]) *= scaling; } }
static void projection_inverse (GfsMap * map, const FttVector * src, FttVector * dest) { projLP odata; projXY idata; GfsMapProjection * m = GFS_MAP_PROJECTION (map); gdouble L = gfs_object_simulation (map)->physical_params.L; idata.u = (src->x*m->cosa + src->y*m->sina)*L; idata.v = (src->y*m->cosa - src->x*m->sina)*L; odata = pj_inv (idata, GFS_MAP_PROJECTION (map)->pj); dest->x = odata.u*RAD_TO_DEG/L; dest->y = odata.v*RAD_TO_DEG/L; dest->z = src->z; }
static void gfs_init_wave_read (GtsObject ** o, GtsFile * fp) { (* GTS_OBJECT_CLASS (gfs_init_wave_class ())->parent_class->read) (o, fp); if (fp->type == GTS_ERROR) return; GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o)); if (!GFS_IS_WAVE (domain)) { gts_file_error (fp, "GfsInitWave can only be used within a GfsWave simulation"); return; } gfs_function_read (GFS_INIT_WAVE (*o)->d, domain, fp); if (fp->type == GTS_ERROR) return; gfs_function_read (GFS_INIT_WAVE (*o)->hs, domain, fp); }
static void refine_height_read (GtsObject ** o, GtsFile * fp) { GfsDerivedVariableInfo v = { "Height", "vertical distance to the surface", cell_height }; v.data = *o; if (!gfs_domain_add_derived_variable (GFS_DOMAIN (gfs_object_simulation (*o)), v)) { gts_file_error (fp, "derived variable `Height' already defined"); return; } (* GTS_OBJECT_CLASS (gfs_refine_height_class ())->parent_class->read) (o, fp); if (fp->type == GTS_ERROR) return; if (!GFS_SURFACE (GFS_REFINE_SURFACE (*o)->surface)->s) { gts_file_error (fp, "RefineHeight only works with GTS surfaces"); return; } }
static void projection_inverse_cell (GfsMap * map, const FttVector * src, FttVector * dest) { gint i; FttVector o = { 0., 0., 0. }; for (i = 0; i < 4; i++) { o.x += src[i].x; o.y += src[i].y; o.z += src[i].z; projection_inverse (map, &(src[i]), &(dest[i])); } o.x /= 4.; o.y /= 4.; o.z /= 4.; projection_inverse (map, &o, &o); /* make sure we do not cross periodic longitude boundary */ gdouble L = gfs_object_simulation (map)->physical_params.L; for (i = 0; i < 4; i++) if (dest[i].x > o.x + 180./L) dest[i].x -= 360./L; else if (dest[i].x < o.x - 180./L) dest[i].x += 360./L; }
static void refine_distance_read (GtsObject ** o, GtsFile * fp) { GfsDerivedVariableInfo v = { "Distance", "distance to the surface", cell_distance }; v.data = *o; if (!gfs_domain_add_derived_variable (GFS_DOMAIN (gfs_object_simulation (*o)), v)) { gts_file_error (fp, "derived variable `Distance' already defined"); return; } (* GTS_OBJECT_CLASS (gfs_refine_distance_class ())->parent_class->read) (o, fp); if (fp->type == GTS_ERROR) return; GtsSurface * s = GFS_SURFACE (GFS_REFINE_SURFACE (*o)->surface)->s; if (!s) { gts_file_error (fp, "RefineDistance only works with GTS surfaces"); return; } GFS_REFINE_DISTANCE (*o)->stree = gts_bb_tree_surface (s); }
static void darcy_coefficients (GfsSourceDarcy * sd, FttCell * cell, GfsVariable ** u, FttComponent c1, gdouble f[2]) { GfsPorous * por = GFS_POROUS (gfs_object_simulation (sd)); GfsDomain * domain = GFS_DOMAIN(por); GfsFunction * porosity = por->porosity; GfsFunction * K = por->K; gdouble viscosity = 0.001; GfsVariable ** U = gfs_domain_velocity (domain); GfsSourceVelocity * sv = GFS_SOURCE_VELOCITY (domain); GfsSourceDiffusion * d = source_diffusion_viscosity (U[0]); if (d) viscosity = gfs_diffusion_cell (d->D, cell); f[0] = (viscosity * gfs_function_value (porosity,cell))/gfs_function_value (K,cell); gdouble modu; modu = fabs(sqrt(GFS_VALUE (cell, sv->v[0])*GFS_VALUE (cell, sv->v[0]) + GFS_VALUE (cell, sv->v[1])*GFS_VALUE (cell, sv->v[1]))); f[1] = (gfs_function_value (porosity,cell))/sqrt(gfs_function_value (K,cell))*modu; }
static void refine_surface_write (GtsObject * o, FILE * fp) { (* GTS_OBJECT_CLASS (gfs_refine_surface_class ())->parent_class->write) (o, fp); gfs_generic_surface_write (GFS_REFINE_SURFACE (o)->surface, gfs_object_simulation (o), fp); }
static void output_spectra_read (GtsObject ** o, GtsFile * fp) { (* GTS_OBJECT_CLASS (gfs_output_spectra_class ())->parent_class->read) (o, fp); if (fp->type == GTS_ERROR) return; GfsOutputSpectra * v = GFS_OUTPUT_SPECTRA (*o); if (fp->type != GTS_STRING) { gts_file_error (fp, "expecting a string (v)"); return; } GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o)); if (!(v->v = gfs_variable_from_name (domain->variables, fp->token->str))) { gts_file_error (fp, "unknown variable `%s'", fp->token->str); return; } gts_file_next_token (fp); GtsFileVariable var[] = { {GTS_DOUBLE, "x", TRUE, &v->pos.x}, {GTS_DOUBLE, "y", TRUE, &v->pos.y}, {GTS_DOUBLE, "z", TRUE, &v->pos.z}, {GTS_DOUBLE, "Lx", TRUE, &v->L.x}, {GTS_DOUBLE, "Ly", TRUE, &v->L.y}, {GTS_DOUBLE, "Lz", TRUE, &v->L.z}, {GTS_NONE} }; gts_file_assign_variables (fp, var); if (fp->type == GTS_ERROR) return; if (fp->type == GTS_INT) { v->level = atoi (fp->token->str); gts_file_next_token (fp); } else v->level = gfs_domain_depth (domain); guint i, j, k, size = 1; v->cgd = gfs_cartesian_grid_new (gfs_cartesian_grid_class ()); /* number of dims of the fft */ v->cgd->N = 3; v->Ndim = 0; k = 0; for (i = 0; i < 3; i++) { if ((&(v->L.x))[i] != 0) { v->Ndim++; v->dir[k] = i; k++; } } if (v->Ndim == 0) { gts_file_error (fp, "There must be at least one L component larger than 0"); return; } /* number of points in each direction */ v->cgd->n = g_malloc (3*sizeof (guint)); for (i = 0; i < 3; i++) { if ((&(v->L.x))[i] == 0 ) v->cgd->n[i] = 1; else v->cgd->n[i] = pow(2,v->level); size *= v->cgd->n[i]; } /* mesh coordinates */ v->cgd->x = g_malloc0 (3*sizeof (gdouble *)); for (i = 0; i < 3; i++) { v->cgd->x[i] = g_malloc (v->cgd->n[i]*sizeof (gdouble)); if (v->cgd->n[i] != 1) for (j = 0; j < v->cgd->n[i]; j++) v->cgd->x[i][j] = (&(v->pos.x))[i] + (&(v->L.x))[i]*(gdouble)j/((gdouble)(v->cgd->n[i]-1)) - 0.5; else v->cgd->x[i][0] = (&(v->pos.x))[i]; } /* memory data allocation */ v->cgd->v = g_malloc0( sizeof ( gdouble ) * 2*(size/2+1) ); }