Ejemplo n.º 1
0
//------------------------------------------------------------------
int do_phase_field_crystal(doubleArray* valArray_p,
                            doubleArray* dArray_p,
                            doubleArray* cubeArray_p,
                            doubleArray* lapOneArray_p,
                            doubleArray* lapTwoArray_p,
                            doubleArray* sumArray_p,
                            double epsilon,
                            double TMAX,
                            double dt,
                            double dx)
{
    double tTotal = 0;
    while(tTotal < TMAX)
    {
        laplace(valArray_p, lapOneArray_p, dx);
        laplace(lapOneArray_p, lapTwoArray_p, dx);
        cube(valArray_p, cubeArray_p);

        multiply_scalar((1 - epsilon), valArray_p);
        multiply_scalar(2, lapOneArray_p);

        sum_array(valArray_p, sumArray_p);
        sum_array(lapOneArray_p, sumArray_p);
        sum_array(lapTwoArray_p, sumArray_p);
        sum_array(cubeArray_p, sumArray_p);

        laplace(sumArray_p, dArray_p, dx);

        do_time_step(valArray_p, dArray_p, dt);
        tTotal += dt;
    }
    return 1;
}
Ejemplo n.º 2
0
//------------------------------------------------------------------
int do_cahn_hilliard(doubleArray* valArray_p,
                    doubleArray* dArray_p,
                    doubleArray* cubeArray_p,
                    doubleArray* lptermArray_p,
                    doubleArray* sumArray_p,
                    double TMAX,
                    double dt,
                    double dx)
{
    double tTotal = 0;
    while(tTotal < TMAX)
    {
        laplace(valArray_p, lptermArray_p, dx);
        cube(valArray_p, cubeArray_p);
        multiply_scalar(-1, cubeArray_p);

        sum_array(valArray_p, sumArray_p);
        sum_array(lptermArray_p, sumArray_p);
        sum_array(cubeArray_p, sumArray_p);

        laplace(sumArray_p, dArray_p, dx);
        multiply_scalar(-1, dArray_p);

        do_time_step(valArray_p, dArray_p, dt);
        tTotal += dt;
    }
    return 1;
}
Ejemplo n.º 3
0
void psi_do_phi(psi_grid* grid, psi_real* phi_out, psi_real Gn) {

	fftw_plan p, pinv;
	fftw_complex* rhok;
	psi_int ax, i, j, k;
	psi_dvec halfn, dims;
	psi_rvec kvec, L, dx;
	psi_real kvec2;

	for(ax = 0; ax < 3; ++ax) {
		dims.ijk[ax] = grid->n.ijk[ax];
		halfn.ijk[ax] = dims.ijk[ax]/2 + 1;
		L.xyz[ax] = grid->window[1].xyz[ax]-grid->window[0].xyz[ax];
		dx.xyz[ax] = L.xyz[ax]/dims.ijk[ax];
	}
	
	rhok = (fftw_complex*) fftw_malloc(dims.i*dims.j*halfn.k*sizeof(fftw_complex));
	p = fftw_plan_dft_r2c_3d(dims.i, dims.j, dims.k, grid->fields[0], rhok, FFTW_ESTIMATE);
	fftw_execute(p);
	fftw_destroy_plan(p);

	// Phi
	for(i = 0; i < dims.i; ++i) 
	for(j = 0; j < dims.j; ++j) 
	for(k = 0; k < halfn.k; ++k) {

		// zero the DC component
		if(i == 0 && j == 0 && k == 0) {
			rhok[0][0] = 0.0;
			rhok[0][1] = 0.0;
			continue;
		}
	
		// compute wavenumbers (arbitrary units)	
		kvec.x = TWO_PI/L.x * ((i < halfn.i)? i : (i - dims.i));
		kvec.y = TWO_PI/L.y * ((j < halfn.j)? j : (j - dims.j));
		kvec.z = TWO_PI/L.z * k;
		kvec2 = kvec.x*kvec.x + kvec.y*kvec.y + kvec.z*kvec.z;

		// Filter the FFT
		rhok[dims.j*halfn.k*i + halfn.k*j + k][0] *= FOUR_PI*Gn/(dims.i*dims.j*dims.k)*laplace(kvec, dx);
		rhok[dims.j*halfn.k*i + halfn.k*j + k][1] *= FOUR_PI*Gn/(dims.i*dims.j*dims.k)*laplace(kvec, dx);

	}
	pinv = fftw_plan_dft_c2r_3d(dims.i, dims.j, dims.k, rhok, phi_out, FFTW_ESTIMATE);
	fftw_execute(pinv);
	fftw_destroy_plan(pinv);
	fftw_free(rhok);

	return;
}
Ejemplo n.º 4
0
static gint
edge_detect (const guchar *data)
{
  gint ret;

  switch (evals.edgemode)
    {
    case SOBEL:
      ret = sobel (data);
      break;
    case PREWITT:
      ret = prewitt (data);
      break;
    case GRADIENT:
      ret = gradient (data);
      break;
    case ROBERTS:
      ret = roberts (data);
      break;
    case DIFFERENTIAL:
      ret = differential (data);
      break;
    case LAPLACE:
      ret = laplace (data);
      break;
    default:
      ret = -1;
      break;
    }

  return CLAMP0255 (ret);
}
Ejemplo n.º 5
0
PyObject * ppm_laplacian(PyObject *self, PyObject * args)
{
	int width, height;
	char *buffer;
	unsigned char *data;
	unsigned char *srcPR, *destPR;
	Py_ssize_t datasize;
	PyObject *py_data, *result;
	
	dprint("Starting");
	if (!PyArg_ParseTuple(args, "(ii)S", &width, &height, &py_data))
		return NULL;
	dprint("Parsing data");
	PyString_AsStringAndSize(py_data, &buffer, &datasize);
	data = (unsigned char *)(buffer);
	
	dprint("width=%d", width);
	dprint("height=%d", height);
	dprint("datasize=%d", datasize);
	if (width*height*3 != datasize) {
		PyErr_SetString(PyExc_ValueError, "data size does not match 24bit");
		return NULL;
	}
	
	destPR = malloc(datasize);
	srcPR = malloc(datasize);
	memcpy(srcPR, data, datasize);
	
	laplace(width, height, srcPR, destPR);
	
	result = Py_BuildValue("s#", destPR, datasize);
	return result;
}
Ejemplo n.º 6
0
double J(double *a) 
{
  double res = 0.0;
  for (int i = 0; i < POINTS_INNER; i++) 
  {
    res += sqr(laplace(a, test_points[i][0], test_points[i][1]) \
        - f(test_points[i][0], test_points[i][1], 0.0, 0.0, 0.0));
  }
    for (int i = POINTS_INNER; i < POINTS_INNER + POINTS_BORDER; ++i)
    {
        res += DELTA * sqr(calc(a, test_points[i][0], test_points[i][1]) \
            - left_border(test_points[i][1]));
    }
    for (int i = POINTS_INNER + POINTS_BORDER; i < POINTS_INNER + 2 * POINTS_BORDER; ++i)
    {
        res += DELTA * sqr(calc(a, test_points[i][0], test_points[i][1]) \
            - bottom_border(test_points[i][0]));
    }
    for (int i = POINTS_INNER + 2 * POINTS_BORDER; i < POINTS_INNER + 3 * POINTS_BORDER; ++i)
    {
        res += DELTA * sqr(calc(a, test_points[i][0], test_points[i][1]) \
            - top_border(test_points[i][0]));
    }
  return res;
}
Ejemplo n.º 7
0
int main(int argc, char **argv)
{

  int NX,NY,NZ;
  MPI_Init (&argc, &argv);
  int nprocs, procid;
  MPI_Comm_rank(MPI_COMM_WORLD, &procid);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

  /* Parsing Inputs  */
  if(argc==1){
    NX=256;NY=256;NZ=256;
  }
  else{
    NX=atoi(argv[1]); NY=atoi(argv[2]); NZ=atoi(argv[3]);
  }
  int N[3]={NX,NY,NZ};

  int nthreads=1;
  grad(N,nthreads);

  laplace(N,nthreads);

  divergence(N,nthreads);

  biharmonic(N,nthreads);

  MPI_Finalize();
  return 0;
} // end main
Ejemplo n.º 8
0
double J(double *a) 
{
  double res = 0.0;
  for (int i = 0; i < POINTS_INNER; i++) 
  {
    double U = calc(a, test_points[i][0]);
    double tmp = laplace(a, test_points[i][0]) - f(test_points[i][0], U);
    res += sqr(tmp);
  }
  res += DELTA * sqr(calc(a, left_x)) + DELTA * sqr(calc(a, right_x));
  return res;
}
Ejemplo n.º 9
0
//------------------------------------------------------------------
int do_diffusion(doubleArray* valArray_p,
                doubleArray* dArray_p,
                double TMAX,
                double dt,
                double dx)
{
    double tTotal = 0;
    while(tTotal < TMAX)
    {
        laplace(valArray_p, dArray_p, dx);
        do_time_step(valArray_p, dArray_p, dt);
        tTotal += dt;
    }
    return 1;
}
Ejemplo n.º 10
0
//---------------cheminių signalų apskaičiavimas sekančiam laiko momentui
double* chem(int size_x, int size_y, int size_z, 
             double* u, double* v, 
             float dt, float delta, 
             double (*g)(double, double), double k)
{
    int x;
    int y;
    int z;
    
    int pos;
    int dz;
    dz = size_x * size_y;
    double tmp;
    
    char state_x;
    char state_y;
    char state_z;
    
    double* res = (double*)malloc(sizeof(double)*dz*size_z);
    
    #pragma omp parallel for private(x, y, z, state_x, state_y, state_z, pos, tmp) shared(size_x, size_y, size_z, dz, res)
    for (z=0; z<size_z; z++)
    {
        state_z = check(z, size_z);
        
        for (y=0; y<size_y; y++)
        {
            state_y = check(y, size_y);
        
            for (x=0; x<size_x; x++)
            {
                state_x = check(x, size_x);
                pos = x + y*size_x + z*dz;
            
                tmp = laplace(&v[pos], size_x, dz, delta, state_x, state_y, state_z);
                tmp = tmp + g(u[pos], k)*u[pos] - v[pos];
                res[pos] = v[pos] + dt*tmp;
            }
        }
    }
    return res;
}
Ejemplo n.º 11
0
Type objective_function<Type>::operator() ()
{
  DATA_VECTOR(y);
  DATA_MATRIX(X)
  DATA_MATRIX(dd)
  PARAMETER_VECTOR(b);
  PARAMETER(a);
  PARAMETER(log_sigma);
  int n = dd.rows();

  // Construct joint negative log-likelihood
  joint_nll<Type> jnll(y, X, dd, b, a, log_sigma);

  // Random effect initial guess
  vector<Type> u(n);
  u.setZero();

  // Calculate Laplace approx (updates u)
  DATA_INTEGER(niter);
  Type res = laplace(jnll, u, niter);
  ADREPORT(u)

  return res;
}
int main(int argc, char** argv) {
   
    
    /**Abertura do arquivo da imagem*/
    printf("%s\n","Informe o nome do arquivo de imagem a ser aberto:");
    scanf("%s",Nome_arquivo);
    
    /**Função limpa tela*/
    reset();
    
    FILE *arquivo;
    
    /**Ler o arquivo*/
    arquivo = fopen(Nome_arquivo, "r");
    
    /**Faz o teste de erro na abertura do arquivo*/
    if(arquivo == NULL){
        printf("%s\n","Erro ao abrir o arquivo de imagem.");
    }else{
        printf("%s\n","Arquivo de imagem aberto com sucesso."); 
    }
    
        /**Ler os dados do cabeçalho*/
        fscanf(arquivo, "P3 %i %i 255",&largura, &altura);
    
    /**Comparação para ver o maior valor da matriz*/
    if (largura > altura) {
        
        max = largura;
    }else{
        max = altura;
    }
    
    /**Cria uma variável do tipo struct*/
    Pixel imagem[max][max];
    

    /**Ler cada Pixel alocando na variável referente ao struct*/
    for (i = 0; i < altura; i++){
        for(j = 0; j < largura; j++){
            fscanf(arquivo, "%i %i %i", &imagem[i][j].r, &imagem[i][j].g, &imagem[i][j].b);
        }
    }
    /**fecha o arquivo*/
    fclose(arquivo);
    




    do{
        
        /**Menu do programa sendo chamado*/
        menu();

        printf("\nDigite o comando:>");
        /**Comando para leitura do menu*/
        scanf("%s",comando);
        reset();
   
        /**converte as letras para minusculo afim de facilitar a comparação*/
        for(i=0;comando[i];i++)
            comando[i]=tolower(comando[i]);
   
        
       
        if(strcmp(comando,"lap")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama o Filtro de laplace*/
            laplace(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem tratada com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"gau")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama o filtro de gaus*/
            gaussiano(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem tratada com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"blu")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama o filtro Blurring*/
            passa_baixa(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem tratada com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"sha")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama o filtro sharpening*/
            passa_alta(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem tratada com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"amp")==0){
            printf("\nExecutando o comando: %s\n", comando);
           
            printf("\nInforme o zoom desejado:\n");
            /**Ler o zoom para ampliar a imagem*/
            scanf("%i",&zoom);
           
           
            printf("%s\n", "Informe o nome desejado para saída:");
            scanf("%s",arq);
            /**Chama a função para ampliar da imagem*/
            ampliar_img(strcat(arq,".ppm"),zoom,imagem);
            
            printf("%s\n", "Imagem ampliada com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"red")==0){
            printf("\nExecutando o comando: %s\n", comando);
           
            printf("\nInforme o zoom desejado:\n");
            /**Ler o zoom para reduzir a imagem*/
            scanf("%i",&zoom);
           
           
            printf("%s\n", "Informe o nome desejado para saída:");
            scanf("%s",arq);
            /**Chama a função para redução da imagem*/
            reduzir_img(strcat(arq,".ppm"),zoom,imagem);
            
            printf("%s\n", "Imagem reduzida com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"rel")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama o filtro para aplicar o relevo na imagem*/
            relevo(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem tratada com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"thr")==0){
            printf("\nExecutando o comando: %s\n", comando);
            printf("\nInforme o valor do thresholding:\n");
            scanf("%i",&thr);
            /**Chama o filtro da binarização*/
            binarization(imagem, thr);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem binarizada com sucesso.");
            return (EXIT_SUCCESS);

        }else if(strcmp(comando,"gra")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama o filtro para grayscale*/
            grayscale(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem tratada com sucesso.");
            return (EXIT_SUCCESS);
            
        }else if(strcmp(comando,"inv")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama o filtro para inverter as cores*/
            inverter(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem tratada com sucesso.");
            return (EXIT_SUCCESS);

        }else if(strcmp(comando,"esp")==0){
            printf("\nExecutando o comando: %s\n", comando);
            /**Chama a função para espelhar a imagem*/
            espelhar(imagem);
            printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
            gerar_img(imagem, arq);
            printf("%s\n", "Imagem espelhada com sucesso.");
            return (EXIT_SUCCESS);

        }else if(strcmp(comando,"rot")==0){
            printf("%s\n", "Informe o ângulo desejado desejado (90, 180, 270):");
            /**Detalha o ângulo de rotação*/
            scanf("%i",&angulo);
			
		if(angulo == 90){
			printf("\nExecutando o comando: %s\n", comando);
            /**Chama a função para rotacionar a imagem*/
            rotacionar_esq(imagem);
			printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
			gerar_img(imagem, arq);
            printf("%s\n", "Imagem rotacionada com sucesso.");
           	return (EXIT_SUCCESS);
            
		}else if(angulo == 180){
			printf("\nExecutando o comando: %s\n", comando);
            rotacionar_180(imagem);
			printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
			gerar_img(imagem, arq);
            printf("%s\n", "Imagem rotacionada com sucesso.");
           	return (EXIT_SUCCESS);
		
		}else if(angulo == 270){
			printf("\nExecutando o comando: %s\n", comando);
            rotacionar_270(imagem);
			printf("%s\n", "Informe o nome desejado para saída:");
            /**Ler o novo nome para a imagem*/
            scanf("%s",arq);
			gerar_img(imagem, arq);
            printf("%s\n", "Imagem rotacionada com sucesso.");
           	return (EXIT_SUCCESS);
		}
        }else{
            /** chama a funcao limpa tela*/
            reset();
            printf("\nComando desconhecido: %s\n",comando);
            
        }    

    }while(strcmp(comando,"exit")!=0);



        printf("%s\n", "Programa finalizado");
    
    /**Finaliza o programa*/
    return (EXIT_SUCCESS);
}
Ejemplo n.º 13
0
//JS
//static int counter=0;
void gradient_pas_av(float *x, float *fcost, float *grad)
/*< acoustic velocity gradient >*/
{
	int ix, iz, is, ir, it, wit, iturn;
	int rx;

	float temp, dmax;
	float **p0, **p1, **p2, **term, **tmparray, ***wave, **pp;
	float *sendbuf, *recvbuf;

        /*
        //JS
        sf_file Fwfl1, Fwfl2, Fres;
        counter++;
        if (cpuid==0 && counter==3) {
            Fwfl1=sf_output("Fwfl1");
            Fwfl2=sf_output("Fwfl2");
            Fres=sf_output("Fres");
            sf_putint(Fwfl1,"n1",padnz);
            sf_putint(Fwfl1,"n2",padnx);
            sf_putint(Fwfl1,"n3",(nt-1)/50+1);
            sf_putint(Fwfl2,"n1",padnz);
            sf_putint(Fwfl2,"n2",padnx);
            sf_putint(Fwfl2,"n3",(nt-1)/50+1);
            sf_putint(Fres,"n1",nt);
            sf_putint(Fres,"n2",nr);
        }
        */

	/* initialize fcost */
	*fcost=0.;
	/* update velocity */
	pad2d(x, vv, nz, nx, nb);
	/* initialize gradient */
	memset(grad, 0., nzx*sizeof(float));

	/* memory allocation */
	p0=sf_floatalloc2(padnz, padnx);
	p1=sf_floatalloc2(padnz, padnx);
	p2=sf_floatalloc2(padnz, padnx);
	term=sf_floatalloc2(padnz, padnx);
	wave=sf_floatalloc3(nz, nx, wnt);
	pp=sf_floatalloc2(nt, nr);

        iturn=0;
        for(is=cpuid; is<ns; is+=numprocs){
            if(cpuid==0) sf_warning("###### is=%d ######", is+1);

            memset(p0[0], 0., padnzx*sizeof(float));
            memset(p1[0], 0., padnzx*sizeof(float));
            memset(p2[0], 0., padnzx*sizeof(float));
            memset(pp[0], 0., nr*nt*sizeof(float));

            wit=0;
            /* forward propagation */
            for(it=0; it<nt; it++){
                if(verb) sf_warning("Forward propagation it=%d;", it);

                /* output predicted data */
                for(ir=0; ir<nr; ir++){
                    rx=r0_v[0]+ir*dr_v;
                    pp[ir][it]=p1[rx][rz];
                }

                /* save wavefield */
                if(it%interval==0){
#ifdef _OPENMP 
#pragma omp parallel for \
                    private(ix,iz) \
                    shared(wave,p1,wit,nb,nx,nz)
#endif
                    for(ix=0; ix<nx; ix++)
                        for(iz=0; iz<nz; iz++)
                            wave[wit][ix][iz]=p1[ix+nb][iz+nb];
                    wit++;
                }

                /*
                //JS
                if(is==0 && counter==3 && it%50==0) sf_floatwrite(p1[0],padnzx,Fwfl1);
                */

                /* laplacian operator */
                laplace(p1, term, padnx, padnz, dx2, dz2);

                /* load source */
#ifdef _OPENMP 
#pragma omp parallel for \
                private(ix,iz) \
                shared(term,nb,ww3,it)
#endif
                for(ix=0; ix<nx; ix++){
                    for(iz=0; iz<nz; iz++){
                        term[ix+nb][iz+nb] += ww3[iturn][it][ix][iz];
                    }
                }

                /* update */
#ifdef _OPENMP 
#pragma omp parallel for \
                private(ix,iz) \
                shared(p0,p1,p2,vv,term,padnx,padnz,dt2)
#endif
                for(ix=4; ix<padnx-4; ix++){
                    for(iz=4; iz<padnz-4; iz++){
                        p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
                    }
                }

                /* swap wavefield pointer of different time steps */
                tmparray=p0; p0=p1; p1=p2; p2=tmparray;

                /* boundary condition */
                apply_sponge(p0, bc, padnx, padnz, nb);
                apply_sponge(p1, bc, padnx, padnz, nb);
            } // end of time loop

            /* check */
            if(wit != wnt) sf_error("Incorrect number of wavefield snapshots");
            wit--;

            /* calculate data residual and data misfit */
            for(ir=0; ir<nr; ir++){
                for(it=0; it<nt; it++){
                    pp[ir][it]=dd[iturn][ir][it]-pp[ir][it];
                    *fcost += 0.5*pp[ir][it]*pp[ir][it];
                }
            }

            /* window the data residual */
            for(ir=0; ir<nr; ir++){
                /* multiscale */
                if(NULL != blo){
                    sf_butter_apply(blo, nt, pp[ir]);
                    sf_reverse(nt, pp[ir]);
                    sf_butter_apply(blo, nt, pp[ir]);
                    sf_reverse(nt, pp[ir]);
                }
                if(NULL != bhi){
                    sf_butter_apply(bhi, nt, pp[ir]);
                    sf_reverse(nt, pp[ir]);
                    sf_butter_apply(bhi, nt, pp[ir]);
                    sf_reverse(nt, pp[ir]);
                }
                for(it=0; it<nt; it++){
                    pp[ir][it] *= weight[ir][it];
                }
            }

            /*
            // JS
            if(is==0 && counter==3) sf_floatwrite(pp[0], nr*nt, Fres);
            */

            /* initialization */
            memset(p0[0], 0., padnzx*sizeof(float));
            memset(p1[0], 0., padnzx*sizeof(float));
            memset(p2[0], 0., padnzx*sizeof(float));
            memset(term[0], 0., padnzx*sizeof(float));

            /* backward propagation */
            for(it=nt-1; it>=0; it--){
                if(verb) sf_warning("Backward propagation it=%d;", it);

                /* laplacian operator */
                laplace(p1, term, padnx, padnz, dx2, dz2);

                /* load data residual*/
                for(ir=0; ir<nr; ir++){
                    rx=r0_v[0]+ir*dr_v;
                    term[rx][rz] += pp[ir][it];
                }

                /* update */
#ifdef _OPENMP 
#pragma omp parallel for \
                private(ix,iz) \
                shared(p0,p1,p2,vv,term,padnx,padnz,dt2)
#endif
                for(ix=4; ix<padnx-4; ix++){
                    for(iz=4; iz<padnz-4; iz++){
                        p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
                    }
                }

                /*
                // JS
                if(is==0 && counter==3 && it%50==0) sf_floatwrite(p1[0],padnzx,Fwfl2);
                */

                /* calculate gradient  */
                if(it%interval==0){
                    if(wit != wnt-1 && wit != 0){ // avoid the first and last time step
#ifdef _OPENMP 
#pragma omp parallel for \
                        private(ix,iz,temp) \
                        shared(nx,nz,vv,wave,p1,wit,wdt2,grad)
#endif
                        for(ix=0; ix<nx; ix++){
                            for(iz=0; iz<nz; iz++){
                                temp=vv[ix+nb][iz+nb];
                                temp=temp*temp*temp;
                                temp=-2./temp;
                                grad[ix*nz+iz] += gwt[iturn][it][ix][iz]*(wave[wit+1][ix][iz]-2.*wave[wit][ix][iz]+wave[wit-1][ix][iz])/wdt2*p1[ix+nb][iz+nb]*temp;
                            }
                        }
                    }
                    wit--;
                }

                /* swap wavefield pointer of different time steps */
                tmparray=p0; p0=p1; p1=p2; p2=tmparray;

                /* boundary condition */
                apply_sponge(p0, bc, padnx, padnz, nb);
                apply_sponge(p1, bc, padnx, padnz, nb);
            } // end of time loop

            iturn++;

            /*
            // JS
            if(is==0 && counter==3){
            sf_fileclose(Fwfl1);
            sf_fileclose(Fwfl2);
            sf_fileclose(Fres);
            }
            sf_warning("---counter=%d fcost=%3.3e---",counter, *fcost);
            */
        } // end of shot loop
	MPI_Barrier(comm);

	/* misfit reduction */
	if(cpuid==0){
		sendbuf=MPI_IN_PLACE;
		recvbuf=fcost;
	}else{
		sendbuf=fcost;
		recvbuf=NULL;
	}
	MPI_Reduce(sendbuf, recvbuf, 1, MPI_FLOAT, MPI_SUM, 0, comm);
	MPI_Bcast(fcost, 1, MPI_FLOAT, 0, comm);

	/* gradient reduction */
	if(cpuid==0){
		sendbuf=MPI_IN_PLACE;
		recvbuf=grad;
	}else{
		sendbuf=grad;
		recvbuf=NULL;
	}
	MPI_Reduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, 0, comm);
	MPI_Bcast(grad, nzx, MPI_FLOAT, 0, comm);

        /* scaling gradient */
        if(first){
            dmax=0.;
            for(ix=0; ix<nzx; ix++)
                if(fabsf(grad[ix])>dmax)
                    dmax=fabsf(grad[ix]);
            scaling=0.1/dmax;
            first=false;
        }

	/* smooth gradient */
	gradient_smooth2b(grectx, grectz, nx, nz, waterz, waterzb, scaling, grad);

	/* free allocated memory */
	free(*p0); free(p0); free(*p1); free(p1);
	free(*p2); free(p2); free(*pp); free(pp);
	free(**wave); free(*wave); free(wave);
	free(*term); free(term);
}
Ejemplo n.º 14
0
Archivo: Prtm.c Proyecto: yunzhishi/src
void rtm_q(sf_file Fdat, sf_file Fimg, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec_q array, bool verb)
/*< visco-acoustic rtm >*/
{
	int ix, iz, is, ir, it, wit;
	int sx, rx, sz, rz, frectx, frectz;
	int nz, nx, nzx, padnz, padnx, padnzx, nt, nr, nb, wnt;

	float dx2, dz2, dt2, dt;
	float **vv, **tau, **taus, **dd, **mm;
	float **p0, **p1, **p2, **r1, **r2, **term, **tmparray, *rr, ***wave;
	float *sendbuf, *recvbuf;

	MPI_Comm comm=MPI_COMM_WORLD;

	nz=acpar->nz;
	nx=acpar->nx;
	nzx=nz*nx;
	padnz=acpar->padnz;
	padnx=acpar->padnx;
	padnzx=padnz*padnx;
	nr=acpar->nr;
	nb=acpar->nb;
	sz=acpar->sz;
	rz=acpar->rz;
	frectx=soupar->frectx;
	frectz=soupar->frectz;

	nt=acpar->nt;
	wnt=(nt-1)/acpar->interval+1;

	dx2=acpar->dx*acpar->dx;
	dz2=acpar->dz*acpar->dz;
	dt2=acpar->dt*acpar->dt;
	dt=acpar->dt;

	/* memory allocation */
	vv = sf_floatalloc2(padnz, padnx);
	tau= sf_floatalloc2(padnz, padnx);
	taus=sf_floatalloc2(padnz, padnx);
	dd=sf_floatalloc2(nt, nr);
	mm=sf_floatalloc2(nz, nx);

	p0=sf_floatalloc2(padnz, padnx);
	p1=sf_floatalloc2(padnz, padnx);
	p2=sf_floatalloc2(padnz, padnx);
	r1=sf_floatalloc2(padnz, padnx);
	r2=sf_floatalloc2(padnz, padnx);
	term=sf_floatalloc2(padnz, padnx);
	rr=sf_floatalloc(padnzx);
	wave=sf_floatalloc3(nz, nx, wnt);

	/* padding and convert vector to 2-d array */
	pad2d(array->vv, vv, nz, nx, nb);
	pad2d(array->tau, tau, nz, nx, nb);
	pad2d(array->taus, taus, nz, nx, nb);

	memset(mm[0], 0., nzx*sizeof(float));

	for(is=mpipar->cpuid; is<acpar->ns; is+=mpipar->numprocs){
		sf_warning("###### is=%d ######", is+1);

		memset(p0[0], 0., padnzx*sizeof(float));
		memset(p1[0], 0., padnzx*sizeof(float));
		memset(p2[0], 0., padnzx*sizeof(float));
		memset(r1[0], 0., padnzx*sizeof(float));
		memset(r2[0], 0., padnzx*sizeof(float));
		memset(term[0], 0., padnzx*sizeof(float));
		
		sx=acpar->s0_v+is*acpar->ds_v;
		source_map(sx, sz, frectx, frectz, padnx, padnz, padnzx, rr);

		wit=0;
		/* forward propagation */
		for(it=0; it<nt; it++){
			if(verb) sf_warning("Forward propagation is=%d; it=%d;", is+1, it);

			/* save wavefield */
			if(it%acpar->interval==0){
				for(ix=0; ix<nx; ix++)
					for(iz=0; iz<nz; iz++)
						wave[wit][ix][iz]=p1[ix+nb][iz+nb];
				wit++;
			}

			/* load source */
			for(ix=0; ix<padnx; ix++){
				for(iz=0; iz<padnz; iz++){
					p1[ix][iz] += rr[ix*padnz+iz]*array->ww[it];
				}
			}

			/* laplacian operator */
			laplace(p1, term, padnx, padnz, dx2, dz2);
			
			/* update */
			for(ix=4; ix<padnx-4; ix++){
				for(iz=4; iz<padnz-4; iz++){
					r2[ix][iz]=
						(-tau[ix][iz]/taus[ix][iz]*term[ix][iz]
						 + (1./dt-0.5/taus[ix][iz])*r1[ix][iz])
						/(1./dt+0.5/taus[ix][iz]);
					term[ix][iz]=term[ix][iz]*(1.+tau[ix][iz])+(r2[ix][iz]+r1[ix][iz])*0.5;
					p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
				}
			}
			
			/* swap wavefield pointer of different time steps */
			tmparray=p0; p0=p1; p1=p2; p2=tmparray;
			tmparray=r1; r1=r2; r2=tmparray;

			/* boundary condition */
			apply_sponge(p0, acpar->bc, padnx, padnz, nb);
			apply_sponge(p1, acpar->bc, padnx, padnz, nb);
			apply_sponge(r1, acpar->bc, padnx, padnz, nb);
		} // end of time loop

		/* check */
		if(wit != wnt) sf_error("Incorrect number of wavefield snapshots");
		/* read data */
		sf_seek(Fdat, is*nr*nt*sizeof(float), SEEK_SET);
		sf_floatread(dd[0], nr*nt, Fdat);
		/* initialization */
		memset(p0[0], 0., padnzx*sizeof(float));
		memset(p1[0], 0., padnzx*sizeof(float));
		memset(p2[0], 0., padnzx*sizeof(float));
		memset(r1[0], 0., padnzx*sizeof(float));
		memset(r2[0], 0., padnzx*sizeof(float));
		memset(term[0], 0., padnzx*sizeof(float));
		
		/* backward propagation */
		for(it=nt-1; it>=0; it--){
			if(verb) sf_warning("Backward propagation is=%d; it=%d;", is+1, it);

			/* load data */
			for(ir=0; ir<acpar->nr2[is]; ir++){
				rx=acpar->r0_v[is]+ir*acpar->dr_v;
				p1[rx][rz]=dd[acpar->r02[is]+ir][it];
			}

			/* laplacian operator */
			laplace(p1, term, padnx, padnz, dx2, dz2);
			
			/* update */
			for(ix=4; ix<padnx-4; ix++){
				for(iz=4; iz<padnz-4; iz++){
					r2[ix][iz]=
						(-tau[ix][iz]/taus[ix][iz]*term[ix][iz]
						 + (1./dt-0.5/taus[ix][iz])*r1[ix][iz])
						/(1./dt+0.5/taus[ix][iz]);
					term[ix][iz]=term[ix][iz]*(1.+tau[ix][iz])+(r2[ix][iz]+r1[ix][iz])*0.5;
					p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
				}
			}

			/* calculate image */
			if(it%acpar->interval==0){
				for(ix=0; ix<nx; ix++)
					for(iz=0; iz<nz; iz++)
						mm[ix][iz] += wave[wit-1][ix][iz]*p2[ix+nb][iz+nb];
				wit--;
			}
			
			/* swap wavefield pointer of different time steps */
			tmparray=p0; p0=p1; p1=p2; p2=tmparray;
			tmparray=r1; r1=r2; r2=tmparray;

			/* boundary condition */
			apply_sponge(p0, acpar->bc, padnx, padnz, nb);
			apply_sponge(p1, acpar->bc, padnx, padnz, nb);
			apply_sponge(r1, acpar->bc, padnx, padnz, nb);
		} // end of time loop
	}// end of shot loop
	MPI_Barrier(comm);

	if(mpipar->cpuid==0){
		sendbuf=MPI_IN_PLACE;
		recvbuf=mm[0];
	}else{
		sendbuf=mm[0];
		recvbuf=NULL;
	}
	MPI_Reduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, 0, comm);

	if(mpipar->cpuid==0) sf_floatwrite(mm[0], nzx, Fimg);
	MPI_Barrier(comm);
}
Ejemplo n.º 15
0
void gradient_standard(float *x, float *fcost, float *grad)
/*< standard velocity gradient >*/
{
	int ix, iz, is, ir, it, wit, iturn;
	int sx, rx;

	float temp, dmax;
	float **p0, **p1, **p2, **term, **tmparray, *rr, ***wave, **pp;
	float *sendbuf, *recvbuf;

	/* residual file */
	sf_file Fres;
	Fres=sf_output("Fres");
	sf_putint(Fres,"n1",nt);
	sf_putint(Fres,"n2",nr);

	/* initialize fcost */
	*fcost=0.;
	/* update velocity */
	pad2d(x, vv, nz, nx, nb);
	/* initialize gradient */
	memset(grad, 0., nzx*sizeof(float));
	/* initialize data misfit */
	swap=0.;

	/* memory allocation */
	p0=sf_floatalloc2(padnz, padnx);
	p1=sf_floatalloc2(padnz, padnx);
	p2=sf_floatalloc2(padnz, padnx);
	term=sf_floatalloc2(padnz, padnx);
	rr=sf_floatalloc(padnzx);
	wave=sf_floatalloc3(nz, nx, wnt);
	pp=sf_floatalloc2(nt, nr);

	iturn=0;
	for(is=cpuid; is<ns; is+=numprocs){
		if(cpuid==0) sf_warning("###### is=%d ######", is+1);

		memset(p0[0], 0., padnzx*sizeof(float));
		memset(p1[0], 0., padnzx*sizeof(float));
		memset(p2[0], 0., padnzx*sizeof(float));
		memset(pp[0], 0., nr*nt*sizeof(float));
		
		sx=s0_v+is*ds_v;
		source_map(sx, sz, frectx, frectz, padnx, padnz, padnzx, rr);

		wit=0;
		/* forward propagation */
		for(it=0; it<nt; it++){
			if(verb) sf_warning("Forward propagation is=%d; it=%d;", is+1, it);

			/* output predicted data */
			for(ir=0; ir<nr2[is]; ir++){
				rx=r0_v[is]+ir*dr_v;
				pp[r02[is]+ir][it]=p1[rx][rz];
			}

			/* save wavefield */
			if(it%interval==0){
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(wave,p1,wit,nb,nx,nz)
#endif
				for(ix=0; ix<nx; ix++)
					for(iz=0; iz<nz; iz++)
						wave[wit][ix][iz]=p1[ix+nb][iz+nb];
				wit++;
			}

			/* laplacian operator */
			laplace(p1, term, padnx, padnz, dx2, dz2);
			
			/* load source */
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(term,rr,padnx,padnz,ww,it)
#endif
			for(ix=0; ix<padnx; ix++){
				for(iz=0; iz<padnz; iz++){
					term[ix][iz] += rr[ix*padnz+iz]*ww[it];
				}
			}

			/* update */
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(p0,p1,p2,vv,term,padnx,padnz,dt2)
#endif
			for(ix=4; ix<padnx-4; ix++){
				for(iz=4; iz<padnz-4; iz++){
					p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
				}
			}
			
			/* swap wavefield pointer of different time steps */
			tmparray=p0; p0=p1; p1=p2; p2=tmparray;

			/* boundary condition */
			apply_sponge(p0, bc, padnx, padnz, nb);
			apply_sponge(p1, bc, padnx, padnz, nb);
		} // end of time loop

		/* check */
		if(wit != wnt) sf_error("Incorrect number of wavefield snapshots");
		wit--;
		
		/* calculate data residual and data misfit */
		for(ir=0; ir<nr; ir++){
			for(it=0; it<nt; it++){
				pp[ir][it]=dd[iturn][ir][it]-pp[ir][it];
				pp[ir][it] *= weight[ir][it];
				swap += 0.5*pp[ir][it]*pp[ir][it];
			}
		}
		smooth_misfit(pp, fcost, nr, nt, drectx, drectz, nrepeat, ider);

		iturn++;

		/* check the data residual */
		if(is==ns/2) sf_floatwrite(pp[0], nr*nt, Fres);
		sf_fileclose(Fres);

		/* initialization */
		memset(p0[0], 0., padnzx*sizeof(float));
		memset(p1[0], 0., padnzx*sizeof(float));
		memset(p2[0], 0., padnzx*sizeof(float));
		memset(term[0], 0., padnzx*sizeof(float));
		
		/* backward propagation */
		for(it=nt-1; it>=0; it--){
			if(verb) sf_warning("Backward propagation is=%d; it=%d;", is+1, it);
			
			/* laplacian operator */
			laplace(p1, term, padnx, padnz, dx2, dz2);
			
			/* load data residual */
			for(ir=0; ir<nr2[is]; ir++){
				rx=r0_v[is]+ir*dr_v;
				term[rx][rz] += pp[r02[is]+ir][it];
			}

			/* update */
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(p0,p1,p2,vv,term,padnx,padnz,dt2)
#endif
			for(ix=4; ix<padnx-4; ix++){
				for(iz=4; iz<padnz-4; iz++){
					p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
				}
			}
			
			/* calculate gradient  */
			if(it%interval==0){
				if(wit != wnt-1 && wit != 0){ // avoid the first and last time step
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz,temp) \
			shared(nx,nz,vv,wave,p1,wit,wdt2,grad)
#endif
					for(ix=0; ix<nx; ix++){
						for(iz=0; iz<nz; iz++){
							temp=vv[ix+nb][iz+nb];
							temp=temp*temp*temp;
							temp=-2./temp;
							grad[ix*nz+iz] += (wave[wit+1][ix][iz]-2.*wave[wit][ix][iz]+wave[wit-1][ix][iz])/wdt2*p1[ix+nb][iz+nb]*temp;
						}
					}
				}
				wit--;
			}
			
			/* swap wavefield pointer of different time steps */
			tmparray=p0; p0=p1; p1=p2; p2=tmparray;

			/* boundary condition */
			apply_sponge(p0, bc, padnx, padnz, nb);
			apply_sponge(p1, bc, padnx, padnz, nb);
		} // end of time loop
	}// end of shot loop
	MPI_Barrier(comm);
	
	/* misfit reduction */
	//MPI_ALLreduce(sendbuf, recvbuf, 1, MPI_FLOAT, MPI_SUM, comm);
	
	if(cpuid==0){
		sendbuf=MPI_IN_PLACE;
		recvbuf=fcost;
	}else{
		sendbuf=fcost;
		recvbuf=NULL;
	}
	MPI_Reduce(sendbuf, recvbuf, 1, MPI_FLOAT, MPI_SUM, 0, comm);
	MPI_Bcast(fcost, 1, MPI_FLOAT, 0, comm);
	
	if(cpuid==0){
		sendbuf=MPI_IN_PLACE;
		recvbuf=&swap;
	}else{
		sendbuf=&swap;
		recvbuf=NULL;
	}
	MPI_Reduce(sendbuf, recvbuf, 1, MPI_FLOAT, MPI_SUM, 0, comm);
	MPI_Bcast(&swap, 1, MPI_FLOAT, 0, comm);

	/* gradient reduction */
	//MPI_ALLreduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, comm);
	if(cpuid==0){
		sendbuf=MPI_IN_PLACE;
		recvbuf=grad;
	}else{
		sendbuf=grad;
		recvbuf=NULL;
	}
	MPI_Reduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, 0, comm);
	MPI_Bcast(grad, nzx, MPI_FLOAT, 0, comm);

	/* scaling gradient */
	if(first){
		dmax=0.;
		for(ix=0; ix<nzx; ix++)
			if(fabsf(grad[ix])>dmax)
				dmax=fabsf(grad[ix]);
		scaling=0.1/dmax;
		first=false;
	}

	/* smooth gradient */
	gradient_smooth2(grectx, grectz, nx, nz, waterz, scaling, grad);

	/* free allocated memory */
	free(*p0); free(p0); free(*p1); free(p1);
	free(*p2); free(p2); free(*pp); free(pp);
	free(**wave); free(*wave); free(wave);
	free(rr); free(*term); free(term);
}
Ejemplo n.º 16
0
Archivo: Prtm.c Proyecto: yunzhishi/src
void rtm(sf_file Fdat, sf_file Fimg, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec_s array, bool verb)
/*< acoustic rtm >*/
{
	int ix, iz, is, ir, it, wit;
	int sx, rx, sz, rz, frectx, frectz;
	int nz, nx, nzx, padnz, padnx, padnzx, nt, nr, nb, wnt;

	float dx2, dz2, dt2, dt;
	float **vv, **dd, **mm;
	float **p0, **p1, **p2, **term, **tmparray, *rr, ***wave;
	float *sendbuf, *recvbuf;

	//sf_file Fwfl1, Fwfl2;
	//Fwfl1=sf_output("Fwfl1");
	//Fwfl2=sf_output("Fwfl2");

	MPI_Comm comm=MPI_COMM_WORLD;

	nz=acpar->nz;
	nx=acpar->nx;
	nzx=nz*nx;
	padnz=acpar->padnz;
	padnx=acpar->padnx;
	padnzx=padnz*padnx;
	nr=acpar->nr;
	nb=acpar->nb;
	sz=acpar->sz;
	rz=acpar->rz;
	frectx=soupar->frectx;
	frectz=soupar->frectz;

	nt=acpar->nt;
	wnt=(nt-1)/acpar->interval+1;

	dx2=acpar->dx*acpar->dx;
	dz2=acpar->dz*acpar->dz;
	dt2=acpar->dt*acpar->dt;
	dt=acpar->dt;

	//sf_putint(Fwfl1, "n1", padnz);
	//sf_putint(Fwfl1, "n2",padnx);
	//sf_putint(Fwfl1, "n3",(nt-1)/50+1);
	//sf_putint(Fwfl2, "n1", padnz);
	//sf_putint(Fwfl2, "n2",padnx);
	//sf_putint(Fwfl2, "n3",(nt-1)/50+1);

	/* memory allocation */
	vv = sf_floatalloc2(padnz, padnx);
	dd=sf_floatalloc2(nt, nr);
	mm=sf_floatalloc2(nz, nx);

	p0=sf_floatalloc2(padnz, padnx);
	p1=sf_floatalloc2(padnz, padnx);
	p2=sf_floatalloc2(padnz, padnx);
	term=sf_floatalloc2(padnz, padnx);
	rr=sf_floatalloc(padnzx);
	wave=sf_floatalloc3(nz, nx, wnt);

	/* padding and convert vector to 2-d array */
	pad2d(array->vv, vv, nz, nx, nb);

	memset(mm[0], 0., nzx*sizeof(float));

	for(is=mpipar->cpuid; is<acpar->ns; is+=mpipar->numprocs){
		sf_warning("###### is=%d ######", is+1);

		memset(p0[0], 0., padnzx*sizeof(float));
		memset(p1[0], 0., padnzx*sizeof(float));
		memset(p2[0], 0., padnzx*sizeof(float));
		
		sx=acpar->s0_v+is*acpar->ds_v;
		source_map(sx, sz, frectx, frectz, padnx, padnz, padnzx, rr);

		wit=0;
		/* forward propagation */
		for(it=0; it<nt; it++){
			if(verb) sf_warning("Forward propagation is=%d; it=%d;", is+1, it);

			/* save wavefield */
			if(it%acpar->interval==0){
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(wave,p1,wit,nb,nx,nz)
#endif
				for(ix=0; ix<nx; ix++)
					for(iz=0; iz<nz; iz++)
						wave[wit][ix][iz]=p1[ix+nb][iz+nb];
				wit++;
			}

			//if(is==acpar->ns/2 && it%50==0) sf_floatwrite(p1[0],padnzx, Fwfl1);

			/* laplacian operator */
			laplace(p1, term, padnx, padnz, dx2, dz2);
			
			/* load source */
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(term,rr,padnx,padnz,it)
#endif
			for(ix=0; ix<padnx; ix++){
				for(iz=0; iz<padnz; iz++){
					term[ix][iz] += rr[ix*padnz+iz]*array->ww[it];
				}
			}

			/* update */
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(p0,p1,p2,vv,term,padnx,padnz,dt2)
#endif
			for(ix=4; ix<padnx-4; ix++){
				for(iz=4; iz<padnz-4; iz++){
					p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
				}
			}
			
			/* swap wavefield pointer of different time steps */
			tmparray=p0; p0=p1; p1=p2; p2=tmparray;

			/* boundary condition */
			apply_sponge(p0, acpar->bc, padnx, padnz, nb);
			apply_sponge(p1, acpar->bc, padnx, padnz, nb);
		} // end of time loop

		/* check */
		if(wit != wnt) sf_error("Incorrect number of wavefield snapshots");
		wit--;

		/* read data */
		sf_seek(Fdat, is*nr*nt*sizeof(float), SEEK_SET);
		sf_floatread(dd[0], nr*nt, Fdat);

		/* initialization */
		memset(p0[0], 0., padnzx*sizeof(float));
		memset(p1[0], 0., padnzx*sizeof(float));
		memset(p2[0], 0., padnzx*sizeof(float));
		memset(term[0], 0., padnzx*sizeof(float));
		
		/* backward propagation */
		for(it=nt-1; it>=0; it--){
			if(verb) sf_warning("Backward propagation is=%d; it=%d;", is+1, it);

			/* laplacian operator */
			laplace(p1, term, padnx, padnz, dx2, dz2);
			
			/* load data */
			for(ir=0; ir<acpar->nr2[is]; ir++){
				rx=acpar->r0_v[is]+ir*acpar->dr_v;
				term[rx][rz] += dd[acpar->r02[is]+ir][it];
			}

			/* update */
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(p0,p1,p2,vv,term,padnx,padnz,dt2)
#endif
			for(ix=4; ix<padnx-4; ix++){
				for(iz=4; iz<padnz-4; iz++){
					p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
				}
			}

			//if(is==acpar->ns/2 && it%50==0) sf_floatwrite(p1[0],padnzx, Fwfl2);

			/* calculate image */
			if(it%acpar->interval==0){
#ifdef _OPENMP 
#pragma omp parallel for \
			private(ix,iz) \
			shared(p1,wave,nx,nz,wit,mm,nb)
#endif
				for(ix=0; ix<nx; ix++)
					for(iz=0; iz<nz; iz++)
						mm[ix][iz] += wave[wit][ix][iz]*p1[ix+nb][iz+nb];
				wit--;
			}
			
			/* swap wavefield pointer of different time steps */
			tmparray=p0; p0=p1; p1=p2; p2=tmparray;

			/* boundary condition */
			apply_sponge(p0, acpar->bc, padnx, padnz, nb);
			apply_sponge(p1, acpar->bc, padnx, padnz, nb);
		} // end of time loop
	}// end of shot loop
	MPI_Barrier(comm);

	//sf_fileclose(Fwfl1);
	//sf_fileclose(Fwfl2);

	if(mpipar->cpuid==0){
		sendbuf=MPI_IN_PLACE;
		recvbuf=mm[0];
	}else{
		sendbuf=mm[0];
		recvbuf=NULL;
	}
	MPI_Reduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, 0, comm);

	if(mpipar->cpuid==0) sf_floatwrite(mm[0], nzx, Fimg);
	MPI_Barrier(comm);

	/* release allocated memory */
	free(*p0); free(p0); free(*p1); free(p1);
	free(*p2); free(p2); free(*vv); free(vv);
	free(*dd); free(dd); free(*mm); free(mm);
	free(rr); free(*term); free(term);
	free(**wave); free(*wave); free(wave);
}
Ejemplo n.º 17
0
void * grain_highlighter_algorithm(JOB_ARG *job)
{
	GimpRunMode mode = GIMP_RUN_NONINTERACTIVE;
	GimpPixelRgn rgn_in;

    int radius;

    float angle;

    float best_angle;
    int highest;


    int ii;
    int counter = 0;
	double temp;
	int row, col;
    int row_offset;
    int col_offset;

	int max_col, min_col;
	int num_return_vals;

	//PIXEL pixel;
	guchar pixel[4];

	printf("inside %s thread %d\n", grain_plugin.name, job->thread);

	laplace(job);

	//copying the output of the laplace job to my input
			for (row = 0; row < job->height; row++)
			{
				for (col = job->start_colum; col < job->start_colum+job->width; col++)
				{
					job->array_in[col][row].red = job->array_out[col][row].red;
					job->array_in[col][row].green = job->array_out[col][row].green;
					job->array_in[col][row].blue = job->array_out[col][row].blue;
				}
			}


	radius = grain_radius;

			//    //this snipit should let the colums blend in the middle of the image without writing over the edge of the image
				if(job->start_colum+job->width+radius < job->width*NUM_THREADS)
				{
					max_col = job->start_colum+job->width;

				}
				else
				{
					max_col = (job->width*NUM_THREADS) - radius;
				}


	//if im at the left wall i need to start over at least one radius so i dont run off the page
	if(job->start_colum == 0)
	{
		min_col = radius;

	}
	else
	{
		min_col = job->start_colum;
	}

	//set my image to black

	for (row = 0; row < job->height; row++)
	{
		for (col = job->start_colum; col < job->start_colum+job->width; col++)
		{
			job->array_in[col][row].red = job->array_out[col][row].red;
			job->array_out[col][row].red = 0;
	//		job->array_in[col][row].green = job->array_out[col][row].green;
			job->array_out[col][row].green = 0;
	//		job->array_in[col][row].blue = job->array_out[col][row].blue;
			job->array_out[col][row].blue = 0;
		}
	}


	for (row = radius; row < job->height-radius ; row+=radius/4)
	{
		for (col = min_col; col < max_col; col+=radius/4)
		{
			highest = 0;

			for(angle = 0; angle < 3.14*2; angle+= .02)
			{

				temp = 0;
				for(ii = 0; ii < radius; ii++)
				{
					col_offset = (ii*cos(angle));
					row_offset = (ii*sin(angle));
					temp +=  job->array_in[col+col_offset][row+row_offset].red;
				}

				if(temp > highest)
				{
					highest = temp;
					best_angle = angle;
				}
			}
			//this looks down the line to see if it is the brightest in the path
			//write back the best line in only if it is brighter than the other lines it is crossing
			for(ii = 0; ii < radius; ii++)
			{
				col_offset = (ii*cos(best_angle));
				row_offset = (ii*sin(best_angle));
				//		job->array_out[col+col_offset][row+row_offset].red = 230;
				//		job->array_out[col+col_offset][row+row_offset].green = 230;
				//		job->array_out[col+col_offset][row+row_offset].blue = 50;


				if(job->array_out[col+col_offset][row+row_offset].red > highest/radius)
				{
					highest = 0;
				}



			}

			if(best_angle > 3.14)
			{
				best_angle -= 3.14;
			}


			if(highest/radius > 40)
			{
				for(ii = 0; ii < radius; ii++)
				{
					col_offset = (ii*cos(best_angle));
					row_offset = (ii*sin(best_angle));

					//the 1+ is to get rid of the gaps in the histogram when where virticle lines happened
					job->array_out[col+col_offset][row+row_offset].red = highest/radius;
					job->array_out[col+col_offset][row+row_offset].green = 1+(best_angle/(3.14))*254;
					job->array_out[col+col_offset][row+row_offset].blue = 1+(best_angle/(3.14))*254;

				}
			}


		}


		job->progress = (double)row / job->height;

	}

	job->progress = 1;

    return NULL;
}
Ejemplo n.º 18
0
void forward_modeling_a(sf_file Fdat, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec array, bool verb)
/*< acoustic forward modeling >*/
{
	int ix, iz, is, ir, it;
	int sx, rx, sz, rz, rectx, rectz;
	int nz, nx, padnz, padnx, padnzx, nt, nr, nb;

	float dx2, dz2, dt2, dt;
	float **vv, **dd;
	float **p0, **p1, **p2, **term, **tmparray, *rr;

	FILE *swap;

	MPI_Comm comm=MPI_COMM_WORLD;

	swap=fopen("temswap.bin", "wb+");

	padnz=acpar->padnz;
	padnx=acpar->padnx;
	padnzx=padnz*padnx;
	nz=acpar->nz;
	nx=acpar->nx;
	nt=acpar->nt;
	nr=acpar->nr;
	nb=acpar->nb;
	sz=acpar->sz;
	rz=acpar->rz;
	rectx=soupar->rectx;
	rectz=soupar->rectz;

	dx2=acpar->dx*acpar->dx;
	dz2=acpar->dz*acpar->dz;
	dt2=acpar->dt*acpar->dt;
	dt=acpar->dt;

	vv = sf_floatalloc2(padnz, padnx);
	dd=sf_floatalloc2(nt, nr);

	p0=sf_floatalloc2(padnz, padnx);
	p1=sf_floatalloc2(padnz, padnx);
	p2=sf_floatalloc2(padnz, padnx);
	term=sf_floatalloc2(padnz, padnx);
	rr=sf_floatalloc(padnzx);

	/* padding and convert vector to 2-d array */
	pad2d(array->vv, vv, nz, nx, nb);

	for(is=mpipar->cpuid; is<acpar->ns; is+=mpipar->numprocs){
		sf_warning("###### is=%d ######", is+1);

		memset(dd[0], 0., nr*nt*sizeof(float));
		memset(p0[0], 0., padnzx*sizeof(float));
		memset(p1[0], 0., padnzx*sizeof(float));
		memset(p2[0], 0., padnzx*sizeof(float));
		
		sx=acpar->s0_v+is*acpar->ds_v;
		source_map(sx, sz, rectx, rectz, padnx, padnz, padnzx, rr);

		for(it=0; it<nt; it++){
			if(verb) sf_warning("Modeling is=%d; it=%d;", is+1, it);

			/* output data */
			for(ir=0; ir<acpar->nr2[is]; ir++){
				rx=acpar->r0_v[is]+ir*acpar->dr_v;
				dd[acpar->r02[is]+ir][it]=p1[rx][rz];
			}

			/* laplacian operator */
			laplace(p1, term, padnx, padnz, dx2, dz2);
			
			/* load source */
			for(ix=0; ix<padnx; ix++){
				for(iz=0; iz<padnz; iz++){
					term[ix][iz] += rr[ix*padnz+iz]*array->ww[it];
				}
			}

			/* update */
			for(ix=0; ix<padnx; ix++){
				for(iz=0; iz<padnz; iz++){
					p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz];
				}
			}
			
			/* swap wavefield pointer of different time steps */
			tmparray=p0; p0=p1; p1=p2; p2=tmparray;

			/* boundary condition */
			apply_sponge(p0, acpar->bc, padnx, padnz, nb);
			apply_sponge(p1, acpar->bc, padnx, padnz, nb);
		} // end of time loop

		fseeko(swap, is*nr*nt*sizeof(float), SEEK_SET);
		fwrite(dd[0], sizeof(float), nr*nt, swap);
	}// end of shot loop
	fclose(swap);
	MPI_Barrier(comm);

	/* transfer data to Fdat */
	if(mpipar->cpuid==0){
		swap=fopen("temswap.bin", "rb");
		for(is=0; is<acpar->ns; is++){
			fseeko(swap, is*nr*nt*sizeof(float), SEEK_SET);
			fread(dd[0], sizeof(float), nr*nt, swap);
			sf_floatwrite(dd[0], nr*nt, Fdat);
		}
		fclose(swap);
		remove("temswap.bin");
	}
	MPI_Barrier(comm);
	
	/* release allocated memory */
	free(*p0); free(p0); free(*p1); free(p1);
	free(*p2); free(p2); free(*vv); free(vv);
	free(*dd); free(dd);
	free(rr); free(*term); free(term);
}
Ejemplo n.º 19
0
//------------------------------------------------------------------------------
int main( int argc, char * argv[] )
{
    // basic attributes of the computation
    const unsigned    geomDeg   = 1;
    const unsigned    fieldDegU = 2;
    const unsigned    fieldDegP = 1;
    const unsigned    tiOrder   = 2;   // order of time integrator
    const base::Shape shape     = base::QUAD;

    //typedef  base::time::BDF<tiOrder> MSM;
    typedef base::time::AdamsMoulton<tiOrder> MSM;

    // time stepping method determines the history size
    const unsigned nHist = MSM::numSteps;

    
    const std::string inputFile = "terz.inp";
    double E, nu, alpha, c0, k, H, F, tMax;
    unsigned numSteps, numIntervals;
    {
        base::io::PropertiesParser pp;
        pp.registerPropertiesVar( "E",     E     );
        pp.registerPropertiesVar( "nu",    nu    );
        pp.registerPropertiesVar( "alpha", alpha );
        pp.registerPropertiesVar( "c0",    c0    );
        pp.registerPropertiesVar( "k",     k     );
        pp.registerPropertiesVar( "H",     H     );
        pp.registerPropertiesVar( "F",     F     );

        pp.registerPropertiesVar( "tMax",         tMax  );
        pp.registerPropertiesVar( "numSteps",     numSteps );
        pp.registerPropertiesVar( "numIntervals", numIntervals );

        // Read variables from the input file
        std::ifstream inp( inputFile.c_str() );
        VERIFY_MSG( inp.is_open(), "Cannot open input file" );
        pp.readValues( inp );
        inp.close( );

    }

    const double deltaT = tMax / static_cast<double>( numSteps );

    // usage message
    if ( argc != 2 ) {
        std::cout << "Usage:  " << argv[0] << "  mesh.smf \n";
        return 0;
    }

    const std::string meshFile = boost::lexical_cast<std::string>( argv[1] );

    

    // Analytic solution
    Terzaghi terzaghi( E, nu, alpha, c0, k, H, F );
    

    //--------------------------------------------------------------------------
    // define a mesh
    typedef base::Unstructured<shape,geomDeg>    Mesh;
    const unsigned dim = Mesh::Node::dim;

    // create a mesh and read from input
    Mesh mesh;
    {
        std::ifstream smf( meshFile.c_str() );
        base::io::smf::readMesh( smf, mesh );
        smf.close();
    }

    // quadrature objects for volume and surface
    const unsigned kernelDegEstimate = 3;
    typedef base::Quadrature<kernelDegEstimate,shape> Quadrature;
    Quadrature quadrature;
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;

    // Create a displacement field
    const unsigned    doFSizeU = dim;
    typedef base::fe::Basis<shape,fieldDegU>           FEBasisU;
    typedef base::Field<FEBasisU,doFSizeU,nHist>       Displacement;
    typedef Displacement::DegreeOfFreedom              DoFU;
    Displacement displacement;

    // Create a pressure field
    const unsigned    doFSizeP = 1;
    typedef base::fe::Basis<shape,fieldDegP>           FEBasisP;
    typedef base::Field<FEBasisP,doFSizeP,nHist>       Pressure;
    typedef Pressure::DegreeOfFreedom                  DoFP;
    Pressure pressure;

    // generate DoFs from mesh
    base::dof::generate<FEBasisU>( mesh, displacement );
    base::dof::generate<FEBasisP>( mesh, pressure );

    // Creates a list of <Element,faceNo> pairs along the boundary
    base::mesh::MeshBoundary meshBoundary;
    meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

    // Create a boundary mesh from this list
    typedef base::mesh::CreateBoundaryMesh<Mesh::Element> CreateBoundaryMesh;
    typedef CreateBoundaryMesh::BoundaryMesh BoundaryMesh;
    BoundaryMesh boundaryMesh;
    {
        CreateBoundaryMesh::apply( meshBoundary.begin(),
                                   meshBoundary.end(),
                                   mesh, boundaryMesh );
    }



    // material object
    typedef mat::hypel::StVenant Material;
    Material material( mat::Lame::lambda( E, nu), mat::Lame::mu( E, nu ) );

    typedef base::asmb::FieldBinder<Mesh,Displacement,Pressure> Field;
    Field field( mesh, displacement, pressure );

    typedef Field::TupleBinder<1,1>::Type TopLeft;
    typedef Field::TupleBinder<1,2>::Type TopRight;
    typedef Field::TupleBinder<2,1>::Type BotLeft;
    typedef Field::TupleBinder<2,2>::Type BotRight;

    // surface displacement field
    typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Displacement> SurfaceFieldBinder;
    SurfaceFieldBinder surfaceFieldBinder( boundaryMesh, displacement );
    typedef SurfaceFieldBinder::TupleBinder<1>::Type SFTB;
    
    // kernel objects
    typedef solid::HyperElastic<Material,TopLeft::Tuple> HyperElastic;
    HyperElastic hyperElastic( material );

    typedef fluid::PressureGradient<TopRight::Tuple> GradP;
    GradP gradP;

    //typedef fluid::VelocityDivergence<FieldPUUTuple> DivU;
    //DivU divU( true ); // * alpha
    typedef PoroDivU<BotLeft::Tuple> DivU;
    DivU divU( alpha );

    typedef heat::Laplace<BotRight::Tuple> Laplace;
    Laplace laplace( k );

    // constrain the boundary
    base::dof::constrainBoundary<FEBasisU>( meshBoundary.begin(),
                                            meshBoundary.end(),
                                            mesh, displacement, 
                                            boost::bind( &dirichletU<dim,DoFU>, _1, _2, 1.0 ) );
    
    base::dof::constrainBoundary<FEBasisP>( meshBoundary.begin(),
                                            meshBoundary.end(),
                                            mesh, pressure, 
                                            boost::bind( &dirichletP<dim,DoFP>, _1, _2, H ) );


    // Number the degrees of freedom
    const std::size_t numDoFsU =
        base::dof::numberDoFsConsecutively( displacement.doFsBegin(), displacement.doFsEnd() );
    std::cout << "# Number of displacement dofs " << numDoFsU << std::endl;
    const std::size_t numDoFsP =
        base::dof::numberDoFsConsecutively( pressure.doFsBegin(), pressure.doFsEnd(), numDoFsU );
    std::cout << "# Number of pressure     dofs " << numDoFsP << std::endl;


    // write VTK file
    writeVTK( mesh, displacement, pressure, meshFile, 0 );

    
    for ( unsigned n = 0; n < numSteps; n++ ) {

        const double time = (n+1) * deltaT;
        std::cout << time << "  ";

        // initialise current displacement to zero (linear elasticity)
        std::for_each( displacement.doFsBegin(), displacement.doFsEnd(),
                       boost::bind( &DoFU::clearValue, _1 ) );

        // Create a solver object
        typedef base::solver::Eigen3           Solver;
        Solver solver( numDoFsU + numDoFsP );

        //------------------------------------------------------------------
        base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver, 
                                                         field, hyperElastic );

        base::asmb::stiffnessMatrixComputation<TopRight>( quadrature, solver,
                                                          field, gradP );

        base::asmb::stiffnessMatrixComputation<BotRight>( quadrature, solver,
                                                          field, laplace);

        // time integration terms
        base::time::computeReactionTerms<BotLeft,MSM>( divU, quadrature, solver,
                                                       field, deltaT, n );

        base::time::computeInertiaTerms<BotRight,MSM>( quadrature, solver,
                                                       field, deltaT, n, c0 );
        
        base::time::computeResidualForceHistory<BotRight,MSM>( laplace, 
                                                               quadrature, solver,
                                                               field, n );


        // Neumann boundary condition
        base::asmb::neumannForceComputation<SFTB>( surfaceQuadrature, solver, surfaceFieldBinder,
                                                   boost::bind( &neumannBC<dim>, _1, _2,
                                                                H, F ) );


        // Finalise assembly
        solver.finishAssembly();

        // Solve
        solver.superLUSolve();
            
        // distribute results back to dofs
        base::dof::setDoFsFromSolver( solver, displacement );
        base::dof::setDoFsFromSolver( solver, pressure );
        
        // push history
        std::for_each( displacement.doFsBegin(), displacement.doFsEnd(),
                       boost::bind( &DoFU::pushHistory, _1 ) );
        std::for_each( pressure.doFsBegin(), pressure.doFsEnd(),
                       boost::bind( &DoFP::pushHistory, _1 ) );


        // write VTK file
        writeVTK( mesh, displacement, pressure, meshFile, n+1 );
        
        // Finished time steps
        //--------------------------------------------------------------------------

        const std::pair<double,double> approx = probe( mesh, displacement, pressure );

        const double p = terzaghi.pressure( H/2., time );
        const double u = terzaghi.displacement( H/2., time );
        
        std::cout << u  << "  " << approx.first << "  "
                  << p  << "  " << approx.second << '\n';
    }
    
    return 0;
}
Ejemplo n.º 20
0
/** Solve a mixed boundary value problem based on Poisson's equation
 *
 *  New features are
 *  - application of Neumann boundary conditions and body forces
 *  - use classes to describe the reference solution and the boundary
 *    value problem
 *  - convergence analysis (if executed for many meshes)
 *
 *  The picture shows the convergence behaviour of the method
 *  for various mesh sizes, a linear finite element basis
 *  \code{.cpp}
 *  const unsigned fieldDeg = 1;
 *  \endcode
 *  and a quadratic finite element basis
 *  \code{.cpp}
 *  const unsigned fieldDeg = 2;
 *  \endcode
 *  in the \f$ L_2 \f$-norm
 *  \f[
 *         \| u - u^h \|_{L_2(\Omega)}^2
 *         = \int_\Omega (u - u^h)^2 d x
 *  \f]
 *  and the \f$ H^1 \f$-semi-norm
 *  \f[
 *         | u - u^h |_{H^1(\Omega)}^2
 *         = \int_\Omega (\nabla u - \nabla u^h)^2 d x
 *  \f]
 *
 *  \image html convergence.png "Convergence diagram"
 *
 */
int ref05::mixedPoisson( int argc, char * argv[] )
{
    if ( argc != 2 ) {
        std::cout << "Usage:  " << argv[0] << " file.smf \n\n";
        return -1;
    }

    const std::string smfFile  = boost::lexical_cast<std::string>( argv[1] );
    const std::string baseName = base::io::baseName( smfFile, ".smf" );

    //--------------------------------------------------------------------------
    const unsigned    geomDeg  = 1;
    const unsigned    fieldDeg = 2;
    const base::Shape shape    = base::QUAD;
    const unsigned    doFSize  = 1;

    //--------------------------------------------------------------------------
    typedef base::Unstructured<shape,geomDeg>     Mesh;
    const unsigned dim = Mesh::Node::dim;
    
    Mesh mesh;
    {
        std::ifstream smf( smfFile.c_str() );
        base::io::smf::readMesh( smf, mesh );
        smf.close();
    }

    // Quadrature and surface quadrature
    const unsigned kernelDegEstimate = 3;
    typedef base::Quadrature<kernelDegEstimate,shape> Quadrature;
    Quadrature quadrature;
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;
 
    // DOF handling
    typedef base::fe::Basis<shape,fieldDeg>        FEBasis;
    typedef base::Field<FEBasis,doFSize>           Field;
    typedef Field::DegreeOfFreedom                 DoF;
    Field field;

    // generate DoFs from mesh
    base::dof::generate<FEBasis>( mesh, field );

    // Object of reference solution and the Poisson problem
    typedef ReferenceSolution<dim>       RefSol;
    typedef GivenData<RefSol>            GivenData;
    RefSol    refSol(    3., 5., 4. );
    GivenData givenData( refSol );

    // Creates a list of <Element,faceNo> pairs
    base::mesh::MeshBoundary meshBoundary;
    meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

    // Object to constrain the boundary 
    base::dof::constrainBoundary<FEBasis>( meshBoundary.begin(),
                                           meshBoundary.end(),
                                           mesh, field,
                                           boost::bind( &GivenData::dirichletBC<DoF>,
                                                        &givenData, _1, _2 ) );

    // Number of DoFs after constraint application!
    const std::size_t numDofs =
        base::dof::numberDoFsConsecutively( field.doFsBegin(), field.doFsEnd() );
    std::cout << "Number of dofs " << numDofs << std::endl;

    // Create a solver object
    typedef base::solver::Eigen3           Solver;
    Solver solver( numDofs );

    // Bind the fields together
    typedef base::asmb::FieldBinder<Mesh,Field> FieldBinder;
    FieldBinder fieldBinder( mesh, field );
    typedef FieldBinder::TupleBinder<1,1>::Type FTB;


    // Body force
    base::asmb::bodyForceComputation<FTB>( quadrature, solver, fieldBinder,
                                           boost::bind( &GivenData::forceFun,
                                                        &givenData, _1 ) );
#if 0
    base::asmb::bodyForceComputation2<FTB>( quadrature, solver, fieldBinder,
                                            boost::bind( &GivenData::forceFun2<Mesh::Element>,
                                                         &givenData, _1, _2 ) );
#endif 

    // Create a connectivity out of this list
    typedef base::mesh::BoundaryMeshBinder<Mesh::Element>::Type BoundaryMesh;
    BoundaryMesh boundaryMesh;
    {
        // Create a real mesh object from this list
        base::mesh::generateBoundaryMesh( meshBoundary.begin(),
                                          meshBoundary.end(),
                                          mesh, boundaryMesh );
    }


    typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Field> SurfaceFieldBinder;
    SurfaceFieldBinder surfaceFieldBinder( boundaryMesh, field );
    typedef SurfaceFieldBinder::TupleBinder<1>::Type SFTB;

    // Neumann boundary condition
    base::asmb::neumannForceComputation<SFTB>( surfaceQuadrature, solver, surfaceFieldBinder,
                                               boost::bind( &GivenData::neumannBC,
                                                            &givenData,
                                                            _1, _2 ) );

    // compute stiffness matrix
    typedef heat::Laplace<FTB::Tuple> Laplace;
    Laplace laplace( 1. );
    base::asmb::stiffnessMatrixComputation<FTB>( quadrature, solver,
                                                 fieldBinder, laplace );
    
    // Finalise assembly
    solver.finishAssembly();

    // Solve
    solver.choleskySolve();

    // distribute results back to dofs
    base::dof::setDoFsFromSolver( solver, field );

    //--------------------------------------------------------------------------
    // output to a VTK file
    {
        // VTK Legacy
        const std::string vtkFile = baseName + ".vtk";
        std::ofstream vtk( vtkFile.c_str() );
        base::io::vtk::LegacyWriter vtkWriter( vtk );
        vtkWriter.writeUnstructuredGrid( mesh );
        base::io::vtk::writePointData( vtkWriter, mesh, field, "temperature" );

        const base::Vector<dim>::Type xi =
            base::ShapeCentroid<Mesh::Element::shape>::apply();
        base::io::vtk::writeCellData( vtkWriter, mesh, field,
                                      boost::bind(
                                          base::post::evaluateFieldGradient<
                                          Mesh::Element,
                                          Field::Element>, _1, _2, xi ),
                                      "flux" );
        vtk.close();
    }

    //--------------------------------------------------------------------------
    // compute L2-error
    std::cout << "L2-error = "
              << base::post::errorComputation<0>(
                  quadrature, mesh, field,
                  boost::bind( &ReferenceSolution<dim>::evaluate,
                               &refSol, _1 ) )
              << '\n';

    //--------------------------------------------------------------------------
    // compute H1-error
    std::cout << "H1-error = "
              << base::post::errorComputation<1>(
                  quadrature, mesh, field,
                  boost::bind( &ReferenceSolution<dim>::evaluateGradient,
                               &refSol, _1 ) )
              << '\n';

    //--------------------------------------------------------------------------
    // Compute mesh volume
    double volume = 0.;

    base::asmb::simplyIntegrate<FTB>( quadrature, volume, fieldBinder,
                                      base::kernel::Measure<FTB::Tuple>() );
    std::cout << "Volume of mesh: " << volume << '\n';

    
    return 0;
}