예제 #1
0
파일: zoom.c 프로젝트: antdvid/FronTier
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*/
예제 #2
0
파일: fmap.c 프로젝트: irisvogon/fulldomain
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 */
예제 #3
0
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*/
예제 #4
0
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*/
예제 #5
0
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*/
예제 #6
0
파일: zoom.c 프로젝트: antdvid/FronTier
/*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*/