void multigrid(int m, /* Malla en la que estamos */ double ***d, /* Defecto */ double ***v, int iteraciones_s1, int iteraciones_s2, const char * tipo) /* tipo de suavizador */ { int d_malla; /* dimension de la malla */ int d_malla_inf; /* dimension de la malla inferior */ double **fu; double **vg; if(m==0) { exacta(d[m],v[m]); printf("Exacta"); } else { d_malla=pow(2,m+1)+1; d_malla_inf=pow(2,m)+1; inicializa_cero(v[m],d_malla); fu=allocate2D(d_malla,d_malla); vg=allocate2D(d_malla,d_malla); copia_matriz(d[m],fu,d_malla); suaviza(v[m],fu,iteraciones_s1,tipo,d_malla); copia_matriz(v[m],vg,d_malla); calcula_defecto(d[m],fu,v[m],d_malla); ///muestra_matriz("d",d[m],d_malla,d_malla); restringe(d[m],d[m-1],d_malla_inf); multigrid(m-1,d,v,iteraciones_s1,iteraciones_s2,tipo); interpola(v[m-1],v[m],d_malla_inf,d_malla); suma_matrices(v[m],vg,d_malla); suaviza(v[m],fu,iteraciones_s2,tipo,d_malla); deallocate2D(fu,d_malla); deallocate2D(vg,d_malla); } }
int main(int argc,char *argv[]) { int i,j; int n_mallas=4; int iteraciones_s1=1; /* Iteraciones del primer suavizador */ int iteraciones_s2=1; /* Iteraciones del segundo suavizador */ int dimension; int dim_inf; /* Dimension de la malla inferior */ double norma_defecto=1.0; double norma_defecto_anterior; double **u; /* Solución */ double **f; double ***v; double ***d; const char *tipo="gsrb"; const char *uso="\n"; /////////////////////////////////////////// // escaneo de argumentos // if((argc>1) && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) { printf (uso, argv[0]); exit(1); } for(i=1;i<argc;i++) { if(!strcmp(argv[i],"-mallas")) { n_mallas=atoi(argv[++i]); } else { fprintf(stderr,"Opción inválida '%s'\n `%s --help` para mas información\n", argv[i], argv[0]); exit(1); } } // Fin escaneo de argumentos // /////////////////////////////////////////// /////////////////////////////////////////// // Generamos los datos necesarios // // // // x . x . x // // . . . . . // // x . x . x // // . . . . . // // x . x . x n_mallas=2, dimension=5 // dimension = pow(2,n_mallas)+1; u=allocate2D(dimension,dimension); f=allocate2D(dimension,dimension); inicializa_cero(f,dimension); //muestra_matriz("f",f,dimension,dimension); inicializa(u,dimension); //muestra_matriz("u",u,dimension,dimension); v=(double***)malloc(n_mallas*sizeof(double**)); // v y d son matrices p d=(double***)malloc(n_mallas*sizeof(double**)); // en cada malla for(i=0;i<n_mallas;i++) { j=pow(2,i+1)+1; v[i]=allocate2D(j,j); d[i]=allocate2D(j,j); inicializa_cero(v[i],j); inicializa_cero(d[i],j); //muestra_matriz("v",v[i],j,j); } // Fin inicialización // //////////////////////////////////////////// //////////////////////////////////////////// // Bucle principal // for(i=0;i<20;i++) { dim_inf=(dimension+1)/2; /* Suavizado */ suaviza(u,f,iteraciones_s1,tipo,dimension); //muestra_matriz("u",u,dimension,dimension); /* Cálculo del defecto */ calcula_defecto(d[n_mallas-1],f,u,dimension); //muestra_matriz("d",d[n_mallas-1],dimension,dimension); /* Restringimos el defecto */ restringe(d[n_mallas-1],d[n_mallas-2],(dimension+1)/2); //muestra_matriz("d_",d[n_mallas-2],(dimension+1)/2,(dimension+1)/2); /* Llamamos a multigrid */ multigrid(n_mallas-2,d,v,iteraciones_s1,iteraciones_s2,tipo); //muestra_matriz("v_",v[n_mallas-2],(dimension+1)/2,(dimension+1)/2); /* Interpolamos */ interpola(v[n_mallas-2],v[n_mallas-1],(dimension+1)/2,dimension); //muestra_matriz("v",v[n_mallas-1],dimension,dimension); /* Sumamos */ suma_matrices(u,v[n_mallas-1],dimension); //muestra_matriz("u",u,dimension,dimension); /* Volvemos a suavizar */ suaviza(u,f,iteraciones_s2,tipo,dimension); //muestra_matriz("u",u,dimension,dimension); /* Comienza el test de convergencia */ calcula_defecto(d[n_mallas-1],f,u,dimension); //muestra_matriz("d",d[n_mallas-1],dimension,dimension); norma_defecto_anterior=norma_defecto; norma_defecto=calcula_max(d[n_mallas-1],dimension); printf("Iter: %d max(defecto)=%e\tratio=%0.10f\n",i,norma_defecto,norma_defecto/norma_defecto_anterior); } // Fin bucle principal // //////////////////////////////////////////// //////////////////////////////////////////// // Liberamos memoria // deallocate2D(u,dimension); deallocate2D(f,dimension); for(i=0;i<n_mallas;i++) { j=pow(2,i+1)+1; deallocate2D(v[i],j); deallocate2D(d[i],j); } free(v); free(d); return 0; }
void busca() { static float f[22][22]; float pi = 3.141592653; short in1, mu5, i, mu3, ind, ind1, indice, iflag, j, ix=0, iy=0, k; float h, th, costh, sinth, fi, anc, xk0, yk0, hpi, x, y, z, xx, yy; float b, g, d1, e1, ext; int count = 0; suaviza(); in = XMIPP_MIN(in, 10); mu1 = mu - 1; m = 2 * mu; mu4 = mu * ncic; mt = 2 * m; ntot = mt * ncic; ntot4 = ntot + mu4 + ncic; zzz0 = ntot; ncic2 = 2 * ncic; in1 = in + 1; h = 2. * pi / ntot; idz = 2 - ntot; th = ncic * h; costh = cos(th); sinth = sin(th); b = 2. / (th * th) * (1. + costh * costh - sin(2. * th) / th); g = 4. / (th * th) * (sinth / th - costh); d1 = 2. * th / 45.; e1 = d1 * sinth * 2.; d1 *= sin(2. * th); mu5 = mu4 - 1; for (i = 1; i <= mu5; i++) { fi = i * h; coseno[i] = sin(fi); } coseno[mu4] = 1.; mu3 = 2 * mu4; for (i = 1; i <= mu5; i++) { coseno[mu3-i] = coseno[i]; coseno[mu3+i] = -coseno[i]; coseno[ntot-i] = -coseno[i]; coseno[ntot+i] = coseno[i]; } coseno[mu3] = 0.; coseno[mu3+mu4] = -1.; coseno[ntot] = 0.; coseno[ntot+mu4] = 1.; ind = 2 * in + 1; ind1 = ind - 1; indice = 0; iflag = 0; e9: if (indice >= ni) goto e10; if (iflag == 2) goto e22; anc = (int)(3. + in * del); xk0 = xc0; yk0 = yc0; rh = XMIPP_MIN(rh, r2); rh = XMIPP_MIN(rh, xk0 - anc - 1.); rh = XMIPP_MIN(rh, yk0 - anc - 1.); rh = XMIPP_MIN(rh, largo - xk0 - anc); rh = XMIPP_MIN(rh, lancho - yk0 - anc); ir = (int)((rh - r1) / r3 + 1); hpi = h / 2. / pi / ir; cxp1 = 2. * b * e1 * hpi; cxp2 = -2. * g * d1 * hpi; cxp3 = 2. * (g * e1 - b * d1) * hpi; cxm1 = (b * b + e1 * e1) * hpi; cxm2 = (g * g + d1 * d1) * hpi; cxm3 = 2. * (b * g - d1 * e1) * hpi; /* if(iflag == 1) goto 21 */ if (iflag == 2) goto e22; x = xc0 - in * del; for (i = 1; i <= ind; i++) /* do 5 */ { y = yc0 - in * del; for (j = 1; j <= ind; j++) /*do 4 */ { ergrot(x, y, &z); /* printf ("%10.3f%10.3f%10.5f%10.3f%10.3f AA\n", x,y,z,del,rh);*/ printf("."); fflush(stdout); z = 100. + indmul * z; f[i][j] = z; y += del; } x += del; } // Introduced by Sjors dd 28.9.2004 to avoid infinite loops count++; if (count > 1000) goto s1; e23: ext = -1000000.; for (i = 1; i <= ind; i++) /* do 7 */ for (j = 1; j <= ind; j++) /* do 7 */ { if (f[i][j] > ext) { ix = i; iy = j; ext = f[i][j]; } } xc0 = xc0 + (ix - in - 1) * del; yc0 = yc0 + (iy - in - 1) * del; if (ix == 1 || ix == ind || iy == 1 || iy == ind) goto e8; del /= in; iflag = 2; indice++; goto e9; e8: iflag = 1; goto e9; e22: f[1][1] = f[ix-1][iy-1]; f[ind][1] = f[ix+1][iy-1]; f[1][ind] = f[ix-1][iy+1]; f[ind][ind] = f[ix+1][iy+1]; f[1][in1] = f[ix-1][iy]; f[in1][1] = f[ix][iy-1]; f[ind][in1] = f[ix+1][iy]; f[in1][ind] = f[ix][iy+1]; f[in1][in1] = f[ix][iy]; x = xc0 - (in - 1) * del; for (i = 2; i < ind1; i++) /* do 11 */ { y = yc0 - (in - 1) * del; for (j = 2;j <= ind1; j++) /* do 12 */ { if (i == in1 && j == in1) goto e13; ergrot(x, y, &z); /* printf ("%10.3f%10.3f%10.5f%10.3f BB \n", x,y,z,del);*/ printf("."); fflush(stdout); z = 100. + indmul * z; f[i][j] = z; e13: y += del; } x += del; } x = xc0 - (in - 1) * del; y = yc0 - (in - 1) * del; for (k = 2; k <= ind1; k++) /* do 16 */ { if (k == in1) goto e17; xx = xc0 - in * del; ergrot(xx, y, &z); /* printf ("%10.3f%10.3f%10.5f%10.3f CC \n", xx,y,z,del);*/ printf("."); fflush(stdout); z = 100. + indmul * z; f[1][k] = z; yy = yc0 - in * del; ergrot(x, yy, &z); /* printf ("%10.3f%10.3f%10.5f%10.3f DD \n", xx,y,z,del);*/ printf("."); fflush(stdout); z = 100. + indmul * z; f[k][1] = z; xx = xc0 + in * del; ergrot(xx, y, &z); /* printf ("%10.3f%10.3f%10.5f%10.3f EE \n", xx,y,z,del);*/ printf("."); fflush(stdout); z = 100. + indmul * z; f[ind][k] = z; yy = yc0 + in * del; ergrot(x, yy, &z); /* printf ("%10.3f%10.3f%10.5f%10.3f FF\n", x,yy,z,del);*/ printf("."); fflush(stdout); z = 100. + indmul * z; f[k][ind] = z; e17: x += del; y += del; } goto e23; e10: std::cout << "\nOptimal center coordinates: x= " << yc0-1 << " ,y= " << xc0-1 << " " << std::endl; return; s1: yc0=xc0=-1; printf("\nNot-converged\n"); return; }