EXPORT void rotate_and_zoom_rect_grid( RECT_GRID *gr, double *L, double *U, double **Q) { double **Qi = NULL; int i, j, dim = gr->dim; static double **pc = NULL; if (pc == NULL) bi_array(&pc,MAXNCORNERS,MAXD,FLOAT); if (Q != NULL) { static double** M = NULL; if (M == NULL) bi_array(&M,MAXD,MAXD,FLOAT); Qi = M; for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) Qi[i][j] = Q[j][i]; } calculate_box(L,U,pc,Q,Qi,dim); for (i = 0; i < dim; i++) { gr->gmax[i] = irint(_scaled_separation(pc[1<<i],pc[0],gr->h,dim)); if (gr->gmax[i] < 1) gr->gmax[i] = 1; } if (Qi != NULL) { rotate_point(L,U,Qi,gr->U,dim); rotate_point(L,gr->GU,Qi,gr->GU,dim); rotate_point(L,gr->GL,Qi,gr->GL,dim); } set_rect_grid(L,gr->U,gr->GL,gr->GU,gr->lbuf,gr->ubuf,gr->gmax, dim,&gr->Remap,gr); } /*end rotate_and_zoom_rect_grid*/
EXPORT bool FrontIntrpStateAtPoint( Front *front, COMPONENT comp, float *coords, float *grid_array, float (*get_state)(Locstate), float *ans) { int icoords[MAXD]; INTERFACE *grid_intfc = front->grid_intfc; static INTRP_CELL *blk_cell; RECT_GRID *gr = &topological_grid(grid_intfc); int i,dim = gr->dim; if (blk_cell == NULL) { scalar(&blk_cell,sizeof(INTRP_CELL)); uni_array(&blk_cell->var,MAX_NUM_VERTEX_IN_CELL,sizeof(float)); bi_array(&blk_cell->coords,MAX_NUM_VERTEX_IN_CELL,MAXD,sizeof(float)); bi_array(&blk_cell->p_lin,MAXD+1,MAXD,sizeof(float)); uni_array(&blk_cell->var_lin,MAXD+1,sizeof(float)); lin_cell_tol = 1.0; for (i = 0; i < dim; ++i) lin_cell_tol *= 0.00001*gr->h[i]; } if (!rect_in_which(coords,icoords,gr)) { return NO; } collect_cell_ptst(blk_cell,icoords,comp,front,grid_array,get_state); if (build_linear_element(blk_cell,coords)) { *ans = FrontLinIntrp(coords,blk_cell,NO); return YES; } else return NO; } /* end FrontIntrpStateAtPoint */
EXPORT bool output_spectral_in_time( char *basename, Wave *wave, Front *front) { COMPONENT comp; Locstate state; float *coords; float *L = wave->rect_grid->L; float *U = wave->rect_grid->U; float *h = wave->rect_grid->h; float kk,kx,ky,dk,Ek,Vk; int icoords[MAXD]; int dim = wave->rect_grid->dim; int status; char eng_name[100],vor_name[100]; static FILE *eng_file,*vor_file; static int first = YES; int i, ix, iy; int xmax, ymax, kmax, mx, my, dummy; COMPLEX **mesh_eng,**mesh_vor; Locstate lstate,rstate,bstate,tstate; debug_print("fft","Entered output_spectral_in_time()\n"); if (first) { first = NO; (void) sprintf(eng_name,"%s.energy-time.dat",basename); (void) sprintf(vor_name,"%s.vorticity-time.dat",basename); eng_file = fopen(eng_name,"w"); vor_file = fopen(vor_name,"w"); fprintf(eng_file,"VARIABLES=k,E(k)\n",xmax,ymax); fprintf(vor_file,"VARIABLES=k,V(k)\n",xmax,ymax); } xmax = wave->rect_grid->gmax[0]; ymax = wave->rect_grid->gmax[1]; if (!Powerof2(xmax,&mx,&dummy) || !Powerof2(ymax,&my,&dummy)) { screen("output_spectral_in_time() cannot analyze " "mesh not power of 2\n"); screen("xmax = %d ymax = %d\n",xmax,ymax); return FUNCTION_FAILED; } bi_array(&mesh_eng,xmax,ymax,sizeof(COMPLEX)); bi_array(&mesh_vor,xmax,ymax,sizeof(COMPLEX)); for (iy = 0; iy < ymax; ++iy) { for (ix = 0; ix < xmax; ++ix) { icoords[0] = ix; icoords[1] = iy; coords = Rect_coords(icoords,wave); comp = Rect_comp(icoords,wave); state = Rect_state(icoords,wave); if (ix != 0) icoords[0] = ix - 1; else icoords[0] = ix; lstate = Rect_state(icoords,wave); if (ix != xmax-1) icoords[0] = ix + 1; else icoords[0] = ix; rstate = Rect_state(icoords,wave); icoords[0] = ix; if (iy != 0) icoords[1] = iy - 1; else icoords[1] = iy; bstate = Rect_state(icoords,wave); if (iy != ymax-1) icoords[1] = iy + 1; else icoords[1] = iy; tstate = Rect_state(icoords,wave); mesh_eng[ix][iy].real = kinetic_energy(state); mesh_eng[ix][iy].imag = 0.0; mesh_vor[ix][iy].real = (Mom(rstate)[1]/Dens(rstate) - Mom(lstate)[1]/Dens(lstate))/h[0] - (Mom(tstate)[0]/Dens(tstate) - Mom(bstate)[0]/Dens(bstate))/h[1]; mesh_vor[ix][iy].imag = 0.0; } } fft2d(mesh_eng,xmax,ymax,1); fft2d(mesh_vor,xmax,ymax,1); kmax = xmax/2; dk = 2.0*PI/(U[0] - L[0]); fprintf(eng_file,"ZONE\n",kk,Ek); fprintf(vor_file,"ZONE\n",kk,Vk); for (i = 0; i < kmax; ++i) { Ek = 0.0; Vk = 0.0; kk = 2.0*i*PI/(U[0] - L[0]); for (iy = 0; iy < ymax/2; ++iy) { for (ix = 0; ix < xmax/2; ++ix) { kx = 2.0*ix*PI/(U[0] - L[0]); ky = 2.0*iy*PI/(U[1] - L[1]); if (sqrt(sqr(kx)+sqr(ky)) >= kk-0.5*dk && sqrt(sqr(kx)+sqr(ky)) < kk+0.5*dk) { Ek += 2.0*sqrt(sqr(mesh_eng[ix][iy].real) + sqr(mesh_eng[ix][iy].imag)); Vk += 2.0*sqrt(sqr(mesh_vor[ix][iy].real) + sqr(mesh_vor[ix][iy].imag)); } } } fprintf(eng_file,"%lf\t%lf\n",kk,Ek); fprintf(vor_file,"%lf\t%lf\n",kk,Vk); } fflush(eng_file); fflush(vor_file); free_these(2,mesh_eng,mesh_vor); debug_print("fft","Left output_spectral_in_time()\n"); return FUNCTION_SUCCEEDED; } /*end output_spectral_in_time*/
EXPORT bool output_spectral_analysis( char *basename, Wave *wave, Front *front) { COMPONENT comp; Locstate state; float *coords; float *L = wave->rect_grid->L; float *U = wave->rect_grid->U; float *h = wave->rect_grid->h; int icoords[MAXD]; int dim = wave->rect_grid->dim; int status; int step = front->step; char energy_name[100],vorticity_name[100], enstrophy_name[100],dens_name[100],pres_name[100]; FILE *energy_file,*vorticity_file, *enstrophy_file,*dens_file,*pres_file; debug_print("fft","Entered fft_energy_spectral()\n"); (void) sprintf(energy_name,"%s.energy%s.dat",basename, right_flush(step,TSTEP_FIELD_WIDTH)); (void) sprintf(vorticity_name,"%s.vorticity%s.dat",basename, right_flush(step,TSTEP_FIELD_WIDTH)); (void) sprintf(enstrophy_name,"%s.enstrophy%s.dat",basename, right_flush(step,TSTEP_FIELD_WIDTH)); (void) sprintf(dens_name,"%s.density%s.dat",basename, right_flush(step,TSTEP_FIELD_WIDTH)); (void) sprintf(pres_name,"%s.pressure%s.dat",basename, right_flush(step,TSTEP_FIELD_WIDTH)); energy_file = fopen(energy_name,"w"); vorticity_file = fopen(vorticity_name,"w"); enstrophy_file = fopen(enstrophy_name,"w"); dens_file = fopen(dens_name,"w"); pres_file = fopen(pres_name,"w"); if (wave->sizest == 0) { debug_print("fft","Left fft_energy_spectral()\n"); return FUNCTION_FAILED; } switch (dim) { #if defined(ONED) case 1: { int ix; int xmax; COMPLEX *mesh_energy; xmax = wave->rect_grid->gmax[0]; uni_array(&mesh_energy,xmax,sizeof(COMPLEX)); for (ix = 0; ix < xmax; ++ix) { icoords[0] = ix; coords = Rect_coords(icoords,wave); comp = Rect_comp(icoords,wave); state = Rect_state(icoords,wave); mesh_energy[ix].real = Energy(state); mesh_energy[ix].imag = 0.0; } break; } #endif /* defined(ONED) */ #if defined(TWOD) case 2: { int ix, iy; int xmax, ymax, mx, my, dummy; COMPLEX **mesh_energy,**mesh_vorticity,**mesh_enstrophy; Locstate lstate,rstate,bstate,tstate; float kk,kx,ky,dk; xmax = wave->rect_grid->gmax[0]; ymax = wave->rect_grid->gmax[1]; if (!Powerof2(xmax,&mx,&dummy) || !Powerof2(ymax,&my,&dummy)) { screen("fft_energy_spectral() cannot analyze " "mesh not power of 2\n"); screen("xmax = %d ymax = %d\n",xmax,ymax); return FUNCTION_FAILED; } bi_array(&mesh_energy,xmax,ymax,sizeof(COMPLEX)); bi_array(&mesh_vorticity,xmax,ymax,sizeof(COMPLEX)); fprintf(energy_file,"zone i=%d, j=%d\n",xmax,ymax); fprintf(vorticity_file,"zone i=%d, j=%d\n",xmax,ymax); fprintf(dens_file,"zone i=%d, j=%d\n",xmax,ymax); fprintf(pres_file,"zone i=%d, j=%d\n",xmax,ymax); fprintf(enstrophy_file,"zone i=%d, j=%d\n",xmax,ymax); for (iy = 0; iy < ymax; ++iy) { for (ix = 0; ix < xmax; ++ix) { icoords[0] = ix; icoords[1] = iy; coords = Rect_coords(icoords,wave); comp = Rect_comp(icoords,wave); state = Rect_state(icoords,wave); mesh_energy[ix][iy].real = kinetic_energy(state); mesh_energy[ix][iy].imag = 0.0; if (ix != 0) icoords[0] = ix - 1; else icoords[0] = ix; lstate = Rect_state(icoords,wave); if (ix != xmax-1) icoords[0] = ix + 1; else icoords[0] = ix; rstate = Rect_state(icoords,wave); icoords[0] = ix; if (iy != 0) icoords[1] = iy - 1; else icoords[1] = iy; bstate = Rect_state(icoords,wave); if (iy != ymax-1) icoords[1] = iy + 1; else icoords[1] = iy; tstate = Rect_state(icoords,wave); mesh_vorticity[ix][iy].real = (Mom(rstate)[1]/Dens(rstate) - Mom(lstate)[1]/Dens(lstate))/h[0] - (Mom(tstate)[0]/Dens(tstate) - Mom(bstate)[0]/Dens(bstate))/h[1]; mesh_vorticity[ix][iy].imag = 0.0; fprintf(energy_file,"%lf\n",kinetic_energy(state)); fprintf(vorticity_file,"%lf\n",mesh_vorticity[ix][iy].real); fprintf(enstrophy_file,"%lf\n", sqr(mesh_vorticity[ix][iy].real)); fprintf(dens_file,"%lf\n",Dens(state)); fprintf(pres_file,"%lf\n",pressure(state)); } } fft_output2d(basename,"energy",step,wave->rect_grid, mesh_energy); fft_output2d(basename,"vorticity",step,wave->rect_grid, mesh_vorticity); free_these(2,mesh_energy,mesh_vorticity); break; } #endif /* defined(TWOD) */ #if defined(THREED) case 3: { int ix, iy, iz; int xmax, ymax, zmax; COMPLEX ***mesh_energy; xmax = wave->rect_grid->gmax[0]; ymax = wave->rect_grid->gmax[1]; zmax = wave->rect_grid->gmax[2]; tri_array(&mesh_energy,xmax,ymax,zmax,sizeof(COMPLEX)); for (iz = 0; iz < zmax; ++iz) { icoords[2] = iz; for (iy = 0; iy < ymax; ++iy) { icoords[1] = iy; for (ix = 0; ix < xmax; ++ix) { icoords[0] = ix; coords = Rect_coords(icoords,wave); comp = Rect_comp(icoords,wave); state = Rect_state(icoords,wave); mesh_energy[ix][iy][iz].real = Energy(state); mesh_energy[ix][iy][iz].imag = 0.0; } } } break; } #endif /* defined(THREED) */ } fclose(energy_file); fclose(vorticity_file); fclose(enstrophy_file); fclose(dens_file); fclose(pres_file); debug_print("fft","Left fft_energy_spectral()\n"); return FUNCTION_SUCCEEDED; } /*end fft_energy_spectral*/
EXPORT void prompt_for_gravity( INIT_DATA *init, INIT_PHYSICS *ip) { RECT_GRID *gr = &Comp_grid(init); float *L, *U; char s[Gets_BUF_SIZE]; float **m; int c, len; static char dname[3][2] = {"x", "y", "z"}; float *g; GRAVITY *grav_data; int i, dim; gravity_data(init) = NULL; screen("The following choices are available for a gravitational " "acceleration\n" "\tNo gravity (N or default)\n" "\tConstant gravity (C or Y)\n" "\tTime dependent gravity (T)\n" "\tAstrophysical (central force) gravity (A)\n" "\tGeneralized Astrophysical gravity (G)\n" "\tRadial gravity with constant magnitude (R)\n"); screen("Enter choice: "); (void) Gets(s); scalar(&grav_data,sizeof(GRAVITY)); gravity_data(init) = grav_data; dim = gr->dim; grav_data->dim = dim; switch (s[0]) { case 'N': case 'n': case '\0': grav_data->type = NO_GRAVITY; return; case 'C': case 'c': case 'Y': /*For historical compatibility of input files*/ case 'y': /*For historical compatibility of input files*/ grav_data->type = CONSTANT_GRAVITY; g = grav_data->g; g[0] = g[1] = g[2] = 0.0; for (i = 0; i < dim; ++i) { screen("\tEnter %s component of gravity (dflt = 0): ",dname[i]); (void) Gets(s); if (s[0] != '\0') (void) sscan_float(s,g+i); } return; case 'T': case 't': screen("Gravity data consists of an array of uni_arrays (time, g)\n"); screen("This data can be entered directly or input from a file\n"); screen("Enter either a filename or the number of data points\n"); screen("Enter filename or integer: "); (void) Gets(s); if (s[0] == '\0') { grav_data->type = NO_GRAVITY; return; } grav_data->type = TIME_DEPENDENT_GRAVITY; /*Was an integer input?*/ len = (int) strlen(s); for (i = 0; i < len; ++i) { c = s[i]; if (!isdigit(c)) break; } if (i == len) { (void) sscanf(s,"%d",&grav_data->num_time_points); bi_array(&m,grav_data->num_time_points,dim+1,FLOAT); grav_data->g_of_t = m; screen("Enter %d data points consisting of a monotonically " "increasing time value\n",grav_data->num_time_points); screen("\tfollowed by a %d vector of gravity " "values for that time\n",dim); read_gravity_data(stdin,dim,m,grav_data->num_time_points); } else { FILE *file = fopen(s,"r"); int nf; float x; if (file == NULL) { screen("ERROR in prompt_for_gravity(), can't open %s",s); clean_up(ERROR); } /*count entries in file*/ for (nf = 0; ((c = getc(file)) != EOF); ++nf) { (void)ungetc(c,file); if (fscan_float(file,&x) != 1) break; } if ((nf%(dim+1)) != 0) { screen("ERROR in prompt_for_gravity(), invalid file\n"); clean_up(ERROR); } grav_data->num_time_points = nf/(dim+1); rewind(file); bi_array(&m,grav_data->num_time_points,dim+1,FLOAT); grav_data->g_of_t = m; read_gravity_data(file,dim,m,grav_data->num_time_points); } /*Check for monotonicity of time values*/ for (i = 1; i < grav_data->num_time_points; ++i) { if (m[i][0] <= m[i-1][0]) { screen("ERROR in prompt_for_gravity(), " "invalid time values\n"); clean_up(ERROR); } } return; case 'A': case 'a': grav_data->type = ASTROPHYSICAL_GRAVITY; grav_data->G = 0.0; grav_data->M = 0.0; L = gr->GL; U = gr->GU; for (i = 0; i < dim; ++i) grav_data->center[i] = 0.5*(L[i]+U[i]); screen("Enter the coordinates of the gravity center (dflt ="); for (i = 0; i < dim; ++i) screen(" %g",grav_data->center[i]); screen("): "); (void) Gets(s); if (s[0] != '\0') { float *cen = grav_data->center; #if defined(float) static const char *fmt = "%lf %lf %lf"; #else /* defined(float) */ static const char *fmt = "%f %f %f"; #endif /* defined(float) */ if (sscanf(s,fmt,cen,cen+1,cen+2) != dim) { screen("ERROR in prompt_for_gravity(), " "invalid coordinate for gravity center\n"); clean_up(ERROR); } } screen("Enter the gravitational constant (dflt = %g): ", grav_data->G); (void) Gets(s); if (s[0] != '\0') sscan_float(s,&grav_data->G); screen("Enter the mass of the gravity center (dflt = %g): ", grav_data->M); (void) Gets(s); if (s[0] != '\0') sscan_float(s,&grav_data->M); return; case 'R': case 'r': grav_data->type = RADIAL_GRAVITY; grav_data->G = 0.0; grav_data->M = 0.0; L = gr->GL; U = gr->GU; for (i = 0; i < dim; ++i) grav_data->center[i] = 0.5*(L[i]+U[i]); screen("Enter the coordinates of the gravity center (dflt ="); for (i = 0; i < dim; ++i) screen(" %g",grav_data->center[i]); screen("): "); (void) Gets(s); if (s[0] != '\0') { float *cen = grav_data->center; #if defined(float) static const char *fmt = "%lf %lf %lf"; #else /* defined(float) */ static const char *fmt = "%f %f %f"; #endif /* defined(float) */ if (sscanf(s,fmt,cen,cen+1,cen+2) != dim) { screen("ERROR in prompt_for_gravity(), " "invalid coordinate for gravity center\n"); clean_up(ERROR); } } screen("Enter the magnitude of the gravitational acceleration " "(dflt = %g): ",grav_data->G); (void) Gets(s); if (s[0] != '\0') sscan_float(s,&grav_data->G); return; case 'G': case 'g': grav_data->type = GENERALIZED_ASTROPHYSICAL_GRAVITY; grav_data->roots = &ip->root; grav_data->nroots = 1; grav_data->G = 0.0; grav_data->M = 0.0; grav_data->N = 100; for (i = 0; i < dim; ++i) grav_data->center[i] = 0.0; screen("Enter the coordinates of the gravity center (dflt ="); for (i = 0; i < dim; ++i) screen(" %g",grav_data->center[i]); screen("): "); (void) Gets(s); if (s[0] != '\0') { float *cen = grav_data->center; #if defined(float) static const char *fmt = "%lf %lf %lf"; #else /* defined(float) */ static const char *fmt = "%f %f %f"; #endif /* defined(float) */ if (sscanf(s,fmt,cen,cen+1,cen+2) != dim) { screen("ERROR in prompt_for_gravity(), " "invalid coordinate for gravity center\n"); clean_up(ERROR); } } screen("Enter the gravitational constant (dflt = %g): ", grav_data->G); (void) Gets(s); if (s[0] != '\0') sscan_float(s,&grav_data->G); for(i = 0; i < dim; ++i) { grav_data->GL[i] = gr->GL[i]; grav_data->GU[i] = gr->GU[i]; grav_data->gmax[i] = gr->gmax[i]; } screen("Enter the number of rings the whole domain" "should be divided into (dflt = %d): ", grav_data->N); (void) Gets(s); if (s[0] != '\0') (void) sscanf(s,"%d",&grav_data->N); //grav_data->Mp = (float*)malloc(grav_data->N*sizeof(float)); return; default: screen("ERROR in prompt_for_gravity(), " "invalid choice %s\n",s); clean_up(ERROR); } } /*end prompt_for_gravity*/
/*ARGSUSED*/ EXPORT INTERFACE *i_zoom_interface( INTERFACE *given_intfc, RECT_GRID *gr, double *L, double *U, double **Q) { INTERFACE *cur_intfc; INTERFACE *zoom_intfc; RECT_GRID *t_gr; int dim = given_intfc->dim; int i, j; double **Qi = NULL; static double **pc = NULL; debug_print("zoom","Entered zoom_interface()\n"); cur_intfc = current_interface(); if ((zoom_intfc = copy_interface(given_intfc)) == NULL) { Error(ERROR,"Unable to copy interface."); clean_up(ERROR); } if (debugging("zoom")) { (void) output(); (void) printf("INTERFACE before zoom:\n\n"); print_interface(zoom_intfc); } if (Q != NULL) { static double** M = NULL; if (M == NULL) bi_array(&M,MAXD,MAXD,FLOAT); Qi = M; for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) Qi[i][j] = Q[j][i]; } if (pc == NULL) bi_array(&pc,MAXNCORNERS,MAXD,FLOAT); calculate_box(L,U,pc,Q,Qi,dim); /* Shrink topological grid to cutting boundary */ t_gr = &topological_grid(zoom_intfc); rotate_and_zoom_rect_grid(t_gr,L,U,Q); switch(dim) { case 1: /* TODO */ return NULL; case 2: insert_cuts_and_bdry2d(zoom_intfc,pc); clip_interface2d(zoom_intfc); break; case 3: /* TODO */ return NULL; } rotate_interface(zoom_intfc,pc[0],Qi); if (set_boundary(zoom_intfc,t_gr,component(pc[0],given_intfc), grid_tolerance(gr) != FUNCTION_SUCCEEDED)) { screen("ERROR in i_zoom_interface(), set_boundary failed\n"); clean_up(ERROR); } set_current_interface(cur_intfc); if (debugging("zoom")) { (void) printf("INTERFACE after zoom:\n\n"); print_interface(zoom_intfc); } debug_print("zoom","Leaving zoom_interface()\n"); return zoom_intfc; } /*end i_zoom_interface*/