void main(int argc, char *argv[]){
  int t;
  char fname1[100], fname2[100];
  int m = sprintf(fname1,"phi");
  int n = sprintf(fname2,"velocities");

  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
  MPI_Comm_rank(MPI_COMM_WORLD,&taskid);
  numworkers = numtasks - 1;
  allocate_memory_phasefields(MESHX);
#ifdef FLUID
  allocate_memory_FluidVariables(MESHX,pmesh);
#endif
  if(taskid == MASTER) {
    initialize_phasefields();
#ifdef FLUID
    initialize_velocities(MESHX);
#endif
    mpi_distribute(MESHX);
    for (t = 0; t <= phi_timesteps; t++){
#ifdef FLUID
      gauss_siedel();
#endif
      if (t%save_phi == 0) {
        receivefrmworker(phi_old);
        receivefrmworker(u_old);
        receivefrmworker(v_old);
        write2file( t, MESHX, phi_old, fname1);
        write2file1( t, MESHX, u_old, v_old, fname2);
      }
    }
  }else {
    mpi_distribute(MESHX);

    for (t = 0; t <= phi_timesteps; t++){
      mpiexchange(taskid, phi_old, MESHX);
      mpiexchange(taskid, mu_old, MESHX);
      boundary_mpi(taskid, phi_old, MESHX);
      boundary_mpi(taskid, mu_old, MESHX);
      laplacian(phi_old, lap_phi, MESHX);
      laplacian(mu_old, lap_mu, MESHX);
#ifdef FLUID
      computeH(u_old,v_old,Hx,Hy);
      RHS_fn(Hx,Hy,rhs_fn,MESHX, pmesh);
      LHS_fn(MESHX, pmesh);
      boundary_pressure(taskid);
      gauss_siedel();
      ns_solver(start, end, phi_old);
      update_velocities(MESHX);
#endif
      solverloop();
      phi_update();
      if (t%save_phi == 0) {
        sendtomaster(taskid, phi_old);
      }
    }
  }
}
//*****************************************************************************//
void phi_solver(){
  laplacian(phi_old,     lap_phi);
  laplacian(mu_old,     lap_mu);
  concentration();
  #ifdef ISO
    isotropic_solverloop();
  #endif
  #ifdef ANISO
    anisotropic_solverloop();
  #endif
  phi_boundary(phi_new);
  phi_boundary(mu_new);
  phi_update();
}
void Bitmap::laplacian_filter(){
    //laplacian mask, center is negative
    Mask laplacian(Laplacian);
    const int delta =1;
    BYTE* image = new BYTE[widthBytes*ih.biHeight];
    for (int i = delta; i < ih.biHeight-delta; ++i)
    {
        for (int j = delta; j < ih.biWidth-delta; ++j)
        {
            int rr,gg,bb;
//            cout<<(int)laplacian.involution(imageData,widthBytes,1,i,j)<<' '<<(int)laplacian.involution(imageData,widthBytes,2,i,j)<<' '<<(int)laplacian.involution(imageData,widthBytes,3,i,j)<<endl;
            rr=imageData[i*widthBytes+j*3+0]-(int)laplacian.involution(imageData,widthBytes,1,i,j);
            gg=imageData[i*widthBytes+j*3+1]-(int)laplacian.involution(imageData,widthBytes,2,i,j);
            bb=imageData[i*widthBytes+j*3+2]-(int)laplacian.involution(imageData,widthBytes,3,i,j);
            
            if (rr>255) image[i*widthBytes+j*3+0]=255;
            else if (rr<0) image[i*widthBytes+j*3+0]=0;
            else image[i*widthBytes+j*3+0]=rr;
            
            if (gg>255) image[i*widthBytes+j*3+1]=255;
            else if (gg<0) image[i*widthBytes+j*3+1]=0;
            else image[i*widthBytes+j*3+1]=gg;
            
            if (bb>255) image[i*widthBytes+j*3+2]=255;
            else if (bb<0) image[i*widthBytes+j*3+2]=0;
            else image[i*widthBytes+j*3+2]=bb;
        }
    }
    delete[] imageData;
    imageData = image;
}
Exemple #4
0
template <int dim, typename T> void update(grid<dim,T>& oldGrid, int steps)
{
	int rank=0;
    #ifdef MPI_VERSION
    rank = MPI::COMM_WORLD.Get_rank();
    #endif

	ghostswap(oldGrid);

	grid<dim,T> newGrid(oldGrid);

	T r = 1.0;
	T u = 1.0;
	T K = 1.0;
	T M = 1.0;
	T dt = 0.01;
	T kT = 0.01;
	T dV = 1.0;

	for (int step=0; step<steps; step++) {
		if (rank==0)
			print_progress(step, steps);

		for (int i=0; i<nodes(oldGrid); i++) {
			T phi = oldGrid(i);
			T noise = gaussian(0.0,sqrt(2.0*kT/(dt*dV)));
			newGrid(i) = phi-dt*M*(-r*phi+u*pow(phi,3)-K*laplacian(oldGrid,i)+noise);
		}
		swap(oldGrid,newGrid);
		ghostswap(oldGrid);
	}
}
Exemple #5
0
template <int dim> void update(MMSP::grid<dim,vector<double> >& grid, int steps)
{
	MMSP::grid<dim,vector<double> > update(grid);

	double dt = 0.01;

	for (int step=0; step<steps; step++) {
		for (int i=0; i<nodes(grid); i++) {
			// compute laplacians
			vector<double> lap = laplacian(grid,i);

			// compute sums of squares
			double sum = 0.0;
			for (int j=0; j<fields(grid); j++) {
				double phi = grid(i)[j];
				sum += phi*phi;
			}

			// compute update values
			for (int j=0; j<fields(grid); j++) {
				double phi = grid(i)[j];
				// particles have zero mobility
				if (j==0) update(i)[j] = phi;
				else update(i)[j] = phi-dt*(-phi-pow(phi,3)+2.0*(phi*sum-lap[j]));
			}
		}
		swap(grid,update);
		ghostswap(grid);
	}
}
Exemple #6
0
template <int dim> void update(MMSP::grid<dim,sparse<double> >& grid, int steps)
{
	double dt = 0.01;
	double epsilon = 1.0e-8;

	for (int step=0; step<steps; step++) {
		// update grid must be overwritten each time
		MMSP::grid<dim,sparse<double> > update(grid);

		for (int i=0; i<nodes(grid); i++) {
			vector<int> x = position(grid,i);

			// determine nonzero fields within
			// the neighborhood of this node
			sparse<bool> neighbors;
			for (int j=0; j<dim; j++)
				for (int k=-1; k<=1; k++) {
					x[j] += k;
					for (int h=0; h<length(grid(x)); h++) {
						int index = MMSP::index(grid(x),h);
						set(neighbors,index) = 1;
					}
					x[j] -= k;
				}

			// if there is only one nonzero field,
			// then it remains the same 
			if (length(neighbors)<2)
				update(i) = grid(i);

			else {
				// compute laplacians
				sparse<double> lap = laplacian(grid,i);

				// compute sums of squares
				double sum = 0.0;
				for (int j=0; j<length(grid(i)); j++) {
					double phi = MMSP::value(grid(i),j);
					sum += phi*phi;
				}

				// compute update values
				for (int j=0; j<length(neighbors); j++) {
					int index = MMSP::index(neighbors,j);
					double phi = grid(i)[index];
					// particles have zero mobility
					if (index==0) set(update(i),index) = phi;
					else {
						double value = phi-dt*(-phi-pow(phi,3)+2.0*(phi*sum-lap[index]));
						if (value>epsilon) set(update(i),index) = value;
					}
				}
			}
		}
		swap(grid,update);
		ghostswap(grid);
	}
}
Exemple #7
0
static void perform_one_iteration(float *x, float *dat,
		int *mask, int nmask, int w, int h, float tstep)
{
	for (int p = 0; p < nmask; p++)
	{
		int i = mask[2*p+0];
		int j = mask[2*p+1];
		int idx = j*w + i;
		x[idx] += tstep * (laplacian(x, w, h, i, j) - dat[idx]);
	}
}
void computeH(double *u, double *v,double *hx, double *hy){

  int i,j,z,x;
  double du_dx,du_dy,dv_dx,dv_dy,du_dt,dv_dt;
  double lap_u[MESHX2], lap_v[MESHX2];
  V_str(MESHX);
  laplacian(u_str,lap_u, MESHX);
  laplacian(v_str,lap_v, MESHX);
  for(i=1; i<MESHX-1; i++){
    for(j=1; j<MESHX-1; j++){
      z = i*MESHX +j;
      du_dx = 0.5*inv_deltax*(u_str[z+1] - u_str[z-1]);
      du_dy = 0.5*inv_deltax*(u_str[z+MESHX] - u_str[z-MESHX]);
      dv_dx = 0.5*inv_deltax*(v_str[z+1] - v_str[z-1]);
      dv_dy = 0.5*inv_deltax*(v_str[z+MESHX] - v_str[z-MESHX]);
      hx[z] = inv_Re*lap_u[z] - (u_old[z]*du_dx + v_old[z]*du_dy);
      hy[z] = inv_Re*lap_v[z] - (u_old[z]*dv_dx + v_old[z]*dv_dy);
    }
  }
}
Exemple #9
0
void main() {
  long i, j, index, index_left, index_back, t;
  double div_flux;

  initialize(phi, mu, V);
  boundary(  phi, mu, V);
  write2file(phi, mu, V, 0);


  for (t=0; t < ntimesteps; t++) {
    if (t%5==0) {
      printf("Iteration=%ld\n", t);
    }
    Gauss_siedel(phi, mu, V);

    //Finding the update in phi
    laplacian(phi,     lap_phi);
    for (i=0; i < (MESHX); i++) {
      for (j=0; j < (MESHY); j++) {
	index           = i*MESHY    + j;
        deltaphi[index] = (deltat/(tau*epsilon))
	                *(2.0*(gamma*epsilon)*lap_phi[index]
	                - 18.0*(gamma/epsilon)*(phi[index]*(1.0-phi[index])*(1.0-2.0*phi[index]))
			+ (mu[index]-mu_eq)*6.0*(phi[index]*(1.0-phi[index])));
      }
    }
    //Ending update of phi

    //Finding update in mu
    calculate_Ddcdmu(phi, mu, Ddcdmu);
    calculate_flux(phi, mu, V, grad_flux, Ddcdmu);


    for (i=1; i < (MESHX-1); i++) {
      for (j=1; j < (MESHY-1); j++) {
	index       = i*MESHY    + j;
	index_left     = index - 1;
	index_back     = index - MESHY;

	div_flux       = (grad_flux[index][Y] - grad_flux[index_left][Y])*inv_deltay2;
	div_flux      += (grad_flux[index][X] - grad_flux[index_back][X])*inv_deltax2;

	deltamu[index] = (deltat*div_flux  -
	               dc_dphi(phi[index], mu[index])*(deltaphi[index]))/dc_dmu(phi[index],mu[index]);
      }
    }
    //update in mu
    update(phi, mu);
    if(t%saveT==0) {
     write2file(phi, mu, V, t);
    }
  }
}
Exemple #10
0
/*
 * This routine is in charge of the Temperature equation.  Virtually all
 * of the terms can be enabled or disabled by parameters read in through the
 * configuration file.  This equation has the form:
 * 
 * dT/dt = div(uT) + w hat z + del^2 T 
 */
void calcTemp()
{
    complex PRECISION * forces = T->force1;
    
    if(tDiff)
    {
        laplacian(T->spectral, forces, 0, 1.0);
    }
    else
    {
        memset(forces, 0, spectralCount * sizeof(complex PRECISION));
    }

    if(tempAdvection)
    {
        //advect the background profile (as long as it is enabled)
        if(tempBackground)
        {
            plusEq(forces, u->vec->z->spectral);
        }

        //advect the perturbations
        p_vector flux = temp1;
        multiply(u->vec->x->spatial, T->spatial, flux->x->spatial);
        multiply(u->vec->y->spatial, T->spatial, flux->y->spatial);
        multiply(u->vec->z->spatial, T->spatial, flux->z->spatial);

        fftForward(flux->x);
        fftForward(flux->y);
        fftForward(flux->z);

        p_field advect = temp2->x;
        divergence(flux, advect);

        minusEq(forces, advect->spectral);

    }
    
    //Apply hyper diffusion to the boundaries
    if(sanitize)
    {
        killBoundaries(T->spatial, forces, 1, 100);
    }
}
Exemple #11
0
  ImagePyramid<T> laplacian_pyramid(const ImagePyramid<T>& gaussians)
  {
    auto LoG = ImagePyramid<T>{};
    LoG.reset(gaussians.num_octaves(),
              gaussians.num_scales_per_octave(),
              gaussians.scale_initial(),
              gaussians.scale_geometric_factor());

    for (auto o = 0; o < LoG.num_octaves(); ++o)
    {
      LoG.octave_scaling_factor(o) = gaussians.octave_scaling_factor(o);
      for (auto s = 0; s < LoG.num_scales_per_octave(); ++s)
      {
        LoG(s,o) = laplacian(gaussians(s,o));
        for (auto it = LoG(s, o).begin(); it != LoG(s,o).end(); ++it)
          *it *= pow(gaussians.scale_relative_to_octave(s), 2);
      }
    }
    return LoG;
  }
Exemple #12
0
template <int dim> void update(MMSP::grid<dim,double>& grid, int steps)
{
	MMSP::grid<dim,double> update(grid);

	double r = 1.0;
	double u = 1.0;
	double K = 1.0;
	double M = 1.0;
	double dt = 0.01;
	double kT = 0.01;
	double dV = 1.0;

	for (int step=0; step<steps; step++) {
		for (int i=0; i<nodes(grid); i++) {
			double phi = grid(i);
			double noise = gaussian(0.0,sqrt(2.0*kT/(dt*dV)));
			update(i) = phi-dt*M*(-r*phi+u*pow(phi,3)-K*laplacian(grid,i)+noise);
		}
		swap(grid,update);
		ghostswap(grid);
	}
}
Exemple #13
0
unsigned long update_old(MMSP::grid<dim, sparse<float> >& grid, int steps, int nthreads)
{
#if (!defined MPI_VERSION) && ((defined CCNI) || (defined BGQ))
    std::cerr<<"Error: MPI is required for CCNI."<<std::endl;
    exit(1);
#endif
    unsigned long timer=0;
    int rank=0;
#ifdef MPI_VERSION
    rank=MPI::COMM_WORLD.Get_rank();
#endif
    const float dt = 0.01;
    const float width = 10.0;
    const float gamma = 1.0;
    const float eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width);
    const float w = 4.0 * gamma / width;
    const float mu = 1.0;
    const float epsilon = 1.0e-8;

#ifndef SILENT
    static int iterations = 1;
#ifdef DEBUG
    if (iterations==1 && rank==0)
        printf("CFL condition Co=%2.2f.\n", mu*eps*eps*dt/(dx(grid, 0)*dx(grid,0)));
#endif
#endif

#ifndef SILENT
    if (rank==0) print_progress(0, steps, iterations);
#endif

    for (int step = 0; step < steps; step++) {
        // update grid must be overwritten each time
        MMSP::grid<dim, sparse<float> > update(grid);
        ghostswap(grid);

        unsigned long comp_time=rdtsc();
        for (int i = 0; i < nodes(grid); i++) {
            vector<int> x = position(grid, i);

            // determine nonzero fields within
            // the neighborhood of this node
            // (2 adjacent voxels along each cardinal direction)
            sparse<int> s;
            for (int j = 0; j < dim; j++)
                for (int k = -1; k <= 1; k++) {
                    x[j] += k;
                    for (int h = 0; h < length(grid(x)); h++) {
                        int index = MMSP::index(grid(x), h);
                        set(s, index) = 1;
                    }
                    x[j] -= k;
                }
            float S = float(length(s));

            // if only one field is nonzero,
            // then copy this node to update
            if (S < 2.0) update(i) = grid(i);
            else {
                // compute laplacian of each field
                sparse<float> lap = laplacian(grid, i);

                // compute variational derivatives
                sparse<float> dFdp;
                for (int h = 0; h < length(s); h++) {
                    int hindex = MMSP::index(s, h);
                    for (int j = h + 1; j < length(s); j++) {
                        int jindex = MMSP::index(s, j);
                        // Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h
                        set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * grid(i)[jindex];
                        set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * grid(i)[hindex];
                    }
                }

                // compute time derivatives
                sparse<float> dpdt;
                for (int h = 0; h < length(s); h++) {
                    int hindex = MMSP::index(s, h);
                    for (int j = h + 1; j < length(s); j++) {
                        int jindex = MMSP::index(s, j);
                        set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]);
                        set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]);
                    }
                }

                // compute update values
                float sum = 0.0;
                for (int h = 0; h < length(s); h++) {
                    int index = MMSP::index(s, h);
                    float value = grid(i)[index] + dt * (2.0 / S) * dpdt[index]; // Extraneous factor of 2?
                    if (value > 1.0) value = 1.0;
                    if (value < 0.0) value = 0.0;
                    if (value > epsilon) set(update(i), index) = value;
                    sum += update(i)[index];
                }

                // project onto Gibbs simplex (enforce Σφ=1)
                float rsum = 0.0;
                if (fabs(sum) > 0.0) rsum = 1.0 / sum;
                for (int h = 0; h < length(update(i)); h++) {
                    int index = MMSP::index(update(i), h);
                    set(update(i), index) *= rsum;
                }
            }
        } // Loop over nodes(grid)
        swap(grid, update);
        comp_time=rdtsc()-comp_time;
        timer+=comp_time;
#ifndef SILENT
        if (rank==0) print_progress(step+1, steps, iterations);
#endif
    } // Loop over steps
    ghostswap(grid);
#ifndef SILENT
    ++iterations;
#endif
    return timer;
}
Exemple #14
0
void* update_threads_helper( void * s )
{
    update_thread_para<dim>* ss = ( update_thread_para<dim>* ) s ;

    const float dt = 0.01;
    const float width = 10.0;
    const float gamma = 1.0;
    const float eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width);
    const float w = 4.0 * gamma / width;
    const float mu = 1.0;
    const float epsilon = 1.0e-8;

    for (unsigned int i = ss->nstart; i < ss->nend; i++) {
        vector<int> x = position((*ss->grid), i);

        // determine nonzero fields within
        // the neighborhood of this node
        // (2 adjacent voxels along each cardinal direction)
        sparse<int> s;
        for (int j = 0; j < dim; j++)
            for (int k = -1; k <= 1; k++) {
                x[j] += k;
                for (int h = 0; h < length((*ss->grid)(x)); h++) {
                    int index = MMSP::index((*ss->grid)(x), h);
                    set(s, index) = 1;
                }
                x[j] -= k;
            }
        float S = float(length(s));

        // if only one field is nonzero,
        // then copy this node to update
        if (S < 2.0) (*ss->update)(i) = (*ss->grid)(i);
        else {
            // compute laplacian of each field
            sparse<float> lap = laplacian((*ss->grid), i);

            // compute variational derivatives
            sparse<float> dFdp;
            for (int h = 0; h < length(s); h++) {
                int hindex = MMSP::index(s, h);
                for (int j = h + 1; j < length(s); j++) {
                    int jindex = MMSP::index(s, j);
                    // Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h
                    set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * (*ss->grid)(i)[jindex];
                    set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * (*ss->grid)(i)[hindex];
                }
            }

            // compute time derivatives
            sparse<float> dpdt;
            for (int h = 0; h < length(s); h++) {
                int hindex = MMSP::index(s, h);
                for (int j = h + 1; j < length(s); j++) {
                    int jindex = MMSP::index(s, j);
                    set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]);
                    set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]);
                }
            }

            // compute update values
            float sum = 0.0;
            for (int h = 0; h < length(s); h++) {
                int index = MMSP::index(s, h);
                float value = (*ss->grid)(i)[index] + dt * (2.0 / S) * dpdt[index]; // Extraneous factor of 2?
                if (value > 1.0) value = 1.0;
                if (value < 0.0) value = 0.0;
                if (value > epsilon) set((*ss->update)(i), index) = value;
                sum += (*ss->update)(i)[index];
            }

            // project onto Gibbs simplex (enforce Σφ=1)
            float rsum = 0.0;
            if (fabs(sum) > 0.0) rsum = 1.0 / sum;
            for (int h = 0; h < length((*ss->update)(i)); h++) {
                int index = MMSP::index((*ss->update)(i), h);
                set((*ss->update)(i), index) *= rsum;
            }
        }
    } // Loop over nodes(grid)


    pthread_exit(0);
    return NULL;
}
Exemple #15
0
int main(void) {

	std::string filePath = "CNN-DocTermCountMatrix.txt";
	Matrix& X_Ori = loadMatrix(filePath);
	int NSample = min(20, X_Ori.getRowDimension());
	Matrix& X = X_Ori.getSubMatrix(0, NSample - 1, 0, X_Ori.getColumnDimension() - 1);
	// disp(X.getSubMatrix(0, 10, 0, 100));
	println(sprintf("%d samples loaded", X.getRowDimension()));
	GraphOptions& options = *new GraphOptions();
	options.graphType = "nn";
	std::string type = options.graphType;
	double NN = options.graphParam;
	fprintf("Graph type: %s with NN: %d\n", type.c_str(), (int)NN);

	// Parameter setting for text data
	options.kernelType = "cosine";
	options.graphDistanceFunction = "cosine";

	// Parameter setting for image data
	/*options.kernelType = "rbf";
			options.graphDistanceFunction = "euclidean";*/

	options.graphNormalize = true;
	options.graphWeightType = "heat";

	bool show = true && !false;

	// Test adjacency function - pass
	tic();
	std::string DISTANCEFUNCTION = options.graphDistanceFunction;
	Matrix& A = adjacency(X, type, NN, DISTANCEFUNCTION);
	fprintf("Elapsed time: %.2f seconds.\n", toc());
	std::string adjacencyFilePath = "adjacency.txt";
	saveMatrix(adjacencyFilePath, A);
	if (show)
		disp(A.getSubMatrix(0, 4, 0, 4));

	// Test laplacian function - pass
	tic();
	Matrix& L = laplacian(X, type, options);
	fprintf("Elapsed time: %.2f seconds.\n", toc());
	std::string LaplacianFilePath = "Laplacian.txt";
	saveMatrix(LaplacianFilePath, L);
	if (show)
		disp(L.getSubMatrix(0, 4, 0, 4));

	// Test local learning regularization - pass
	NN = options.graphParam;
	std::string DISTFUNC = options.graphDistanceFunction;
	std::string KernelType = options.kernelType;
	double KernelParam = options.kernelParam;
	double lambda = 0.001;
	tic();
	Matrix& LLR_text = calcLLR(X, NN, DISTFUNC, KernelType, KernelParam, lambda);
	fprintf("Elapsed time: %.2f seconds.\n", toc());
	std::string LLRFilePath = "localLearningRegularization.txt";
	saveMatrix(LLRFilePath, LLR_text);
	if (show)
		display(LLR_text.getSubMatrix(0, 4, 0, 4));

	return EXIT_SUCCESS;

}
 inline fvMatrixHolder< Type > laplacian( const dimensioned< GType >& ds, 
                                          GeometricFieldHolder< Type, fvPatchField, volMesh >& field,
                                          const word& name )
 {
   return fvMatrixHolder< Type >( laplacian( ds, field(), name ), Deps( &field ) );
 }
template <int dim> void update(grid<dim, sparse<phi_type> >& oldGrid, int steps)
{
	int rank=0;
	#ifdef MPI_VERSION
	rank=MPI::COMM_WORLD.Get_rank();
	#endif
	const phi_type dt = 0.01;
	const phi_type width = 14.5;
	const phi_type epsilon = 1.0e-8;
	const double mu_hi = 1.00;
	const double mu_lo = 0.01;
	const double mu_x = 0.6422;
	const double mu_s = 0.0175;

	std::ofstream vfile;
	if (rank==0)
		vfile.open("v.log",std::ofstream::out | std::ofstream::app);

	for (int step = 0; step < steps; step++) {
		if (rank==0) print_progress(step, steps);
		// newGrid grid must be overwritten each time
		ghostswap(oldGrid);
		grid<dim, sparse<phi_type> > newGrid(oldGrid);

		for (int d=0; d<dim; d++) {
			if (x0(oldGrid, d) == g0(oldGrid,d)) {
				b0(oldGrid,d) = Dirichlet;
				b0(newGrid,d) = Dirichlet;
			} else if (x1(oldGrid,d) == g1(oldGrid,d)) {
				b1(oldGrid,d) = Dirichlet;
				b1(newGrid,d) = Dirichlet;
			}
		}

		for (int i = 0; i < nodes(oldGrid); i++) {
			vector<int> x = position(oldGrid, i);

			// determine nonzero fields within
			// the neighborhood of this node
			// (2 adjacent voxels along each cardinal direction)
			sparse<int> s;
			for (int j = 0; j < dim; j++)
				for (int k = -1; k <= 1; k++) {
					x[j] += k;
					for (int h = 0; h < length(oldGrid(x)); h++) {
						int pindex = index(oldGrid(x), h);
						set(s, pindex) = 1;
					}
					x[j] -= k;
				}
			phi_type S = phi_type(length(s));

			// if only one field is nonzero,
			// then copy this node to newGrid
			if (S < 2.0) newGrid(i) = oldGrid(i);
			else {
				// compute laplacian of each field
				sparse<phi_type> lap = laplacian(oldGrid, i);

				// compute variational derivatives
				sparse<phi_type> dFdp;
				for (int h = 0; h < length(s); h++) {
					int hindex = index(s, h);
					for (int j = h + 1; j < length(s); j++) {
						int jindex = index(s, j);
						phi_type gamma = energy(hindex, jindex);
						phi_type eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width);
						phi_type w = 4.0 * gamma / width;
						// Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h
						set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * oldGrid(i)[jindex];
						set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * oldGrid(i)[hindex];
					}
				}

				// compute time derivatives
				sparse<phi_type> dpdt;
				phi_type mu = mobility(mu_lo, mu_hi, mu_x, mu_s, oldGrid(x).getMagPhi());

				for (int h = 0; h < length(s); h++) {
					int hindex = index(s, h);
					for (int j = h + 1; j < length(s); j++) {
						int jindex = index(s, j);
						set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]);
						set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]);
					}
				}

				// compute update values
				phi_type sum = 0.0;
				for (int h = 0; h < length(s); h++) {
					int pindex = index(s, h);
					phi_type value = oldGrid(i)[pindex] + dt * (2.0 / S) * dpdt[pindex]; // Extraneous factor of 2?
					if (value > 1.0) value = 1.0;
					if (value < 0.0) value = 0.0;
					if (value > epsilon) set(newGrid(i), pindex) = value;
					sum += newGrid(i)[pindex];
				}

				// project onto Gibbs simplex (enforce Σφ=1)
				phi_type rsum = 0.0;
				if (fabs(sum) > 0.0) rsum = 1.0 / sum;
				for (int h = 0; h < length(newGrid(i)); h++) {
					int pindex = index(newGrid(i), h);
					set(newGrid(i), pindex) *= rsum;
				}
			}

		} // Loop over nodes(oldGrid)

		if ((step+1) % 10 == 0) {
			// Scan along just above the mid-line for the grain boundary.
			// When found, determine its angle.
			vector<int> x(dim, 0);
			const int offset = 2;

			const phi_type vert_mag = 1.0/std::sqrt(3.0);
			const phi_type edge_mag = 1.0/std::sqrt(2.0);
			const phi_type bulk_mag = 1.0;

			const phi_type edge_contour = edge_mag + 0.125*(bulk_mag - edge_mag);
			const phi_type vert_contour = vert_mag + 0.125*(edge_mag - vert_mag);

			x[0] = x0(newGrid,0);
			x[1] = (g1(newGrid,1) - g0(newGrid,1))/2;
			while (x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>vert_contour)
				x[0]++;
			if (x[0] == x1(newGrid))
				x[0] = g0(newGrid,0);
			int v0 = x[0];
			#ifdef MPI_VERSION
			MPI::COMM_WORLD.Allreduce(&x[0], &v0, 1, MPI_INT, MPI_MAX);
			#endif

			x[1] += offset;
			while (x[0]>= x0(newGrid) && x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>edge_contour)
				x[0]++;
			if (x[0] == x1(newGrid))
				x[0] = g0(newGrid,0);
			int v1 = x[0];
			#ifdef MPI_VERSION
			MPI::COMM_WORLD.Allreduce(&x[0], &v1, 1, MPI_INT, MPI_MAX);
			#endif

			x[1] += offset;
			while (x[0]>= x0(newGrid) && x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>edge_contour)
				x[0]++;
			if (x[0] == x1(newGrid))
				x[0] = g0(newGrid,0);
			int v2 = x[0];
			#ifdef MPI_VERSION
			MPI::COMM_WORLD.Allreduce(&x[0], &v2, 1, MPI_INT, MPI_MAX);
			#endif

			// Second-order right-sided difference to approximate slope
			double diffX = 3.0*v0 - 4.0*v1 + 1.0*v2;
			double theta = 180.0/M_PI * std::atan2(2.0*offset*dx(newGrid,1), dx(newGrid,0)*diffX);

			if (rank==0)
				vfile << dx(newGrid,0)*v0 << '\t' << dx(newGrid,0)*v1 << '\t' << dx(newGrid,0)*v2 << '\t' << diffX << '\t' << theta << '\n';
		}

		swap(oldGrid, newGrid);
	} // Loop over steps
	ghostswap(oldGrid);

	if (rank==0)
		vfile.close();
}
Exemple #18
0
/*
 * This routine is in charge of the magnetic induction equation.  Virtually all
 * of the terms can be enabled or disabled by parameters read in through the
 * configuration file.  This equation has the form:
 * 
 * dB/dt = curl(u cross B) + Pm/Pr*del^2 B + F_B 
 * 
 * Again we have an incompressible field, so after evaluating the force in 
 * vector notation, we decompose it into poloidal and toroidal scalar fields for
 * the time integration.
 */
void calcMag()
{
    int i,j,k;
    int index;
    debug("Calculating Magnetic forces\n");

    if(magDiff)
    {
        laplacian(B->vec->x->spectral, rhs->x->spectral, 0, Pr/Pm);
        laplacian(B->vec->y->spectral, rhs->y->spectral, 0, Pr/Pm);
        laplacian(B->vec->z->spectral, rhs->z->spectral, 0, Pr/Pm);
    }
    else
    {
        //make sure we don't start with garbage
        memset(rhs->x->spectral, 0, spectralCount * sizeof(complex PRECISION));
        memset(rhs->y->spectral, 0, spectralCount * sizeof(complex PRECISION));
        memset(rhs->z->spectral, 0, spectralCount * sizeof(complex PRECISION));
    }
    
    //Apply hyper diffusion to the boundaries.  Again, this does not currently
    //work!
    if(sanitize)
    {
        killBoundaries(B->vec->x->spatial, rhs->x->spectral, 1, 100*Pr/Pm);
        killBoundaries(B->vec->y->spatial, rhs->y->spectral, 1, 100*Pr/Pm);
        killBoundaries(B->vec->z->spatial, rhs->z->spectral, 1, 100*Pr/Pm);
    }

    //static forcing is currently only in the x direction and a function of y and z
    if(magStaticForcing)
    {
        complex PRECISION * xfield = rhs->x->spectral;
        complex PRECISION * ffield = magForceField->spectral;
        index = 0;
        for(i = 0; i < spectralCount; i++)
        {
            xfield[i] += ffield[i];
        }
    }
    
    //If we are doing the kinematic problem then the velocity field is
    //specified ahead of time.  Note, this conflicts with the momentum equation
    //being enabled.  If both momentum equation and kinematic are enabled, then
    //we will still be doing all the work of both, but right here we will erase
    //any work previously done on the momentum equation, at least insofar as
    //the magnetic field is concerned.
    if(kinematic)
    {
        fillTimeField(u->vec, KINEMATIC);
    }

    //This is really the induction term, not advection, though it does contain
    //advection effects within it.
    if(magAdvect)
    {
        p_vector uxb = temp1;
        p_vector cuxb = temp2;

        crossProduct(u->vec, B->vec, uxb);
        fftForward(uxb->x);
        fftForward(uxb->y);
        fftForward(uxb->z);

        curl(uxb, cuxb);

        plusEq(rhs->x->spectral, cuxb->x->spectral);
        plusEq(rhs->y->spectral, cuxb->y->spectral);
        plusEq(rhs->z->spectral, cuxb->z->spectral);
    }

    if(magTimeForcing)
    {
        fillTimeField(temp1, MAGNETIC);

        plusEq(rhs->x->spectral, temp1->x->spectral);
        plusEq(rhs->y->spectral, temp1->y->spectral);
        plusEq(rhs->z->spectral, temp1->z->spectral);
    }

    //The 1 means we store the result in the force vectors.
    decomposeSolenoidal(B->sol, rhs, 1);
    debug("Magnetic forces done\n");
}
template <int dim> void update(MMSP::grid<dim,sparse<double> >& grid, int steps)
{
	double dt = 0.01;
	double width = 8.0;

	for (int step=0; step<steps; step++) {
		print_progress(step, steps);
		// update grid must be overwritten each time
		MMSP::grid<dim,sparse<double> > update(grid);

		#ifndef MPI_VERSION
		#pragma omp parallel for
		#endif
		for (int n=0; n<nodes(grid); n++) {
			vector<int> x = position(grid,n);

			// compute laplacian of each field
			sparse<double> lapPhi = laplacian(grid,n);

			double S = double(length(lapPhi));

			// if only one field is nonzero,
			// then copy this node to update
			if (S<2.0) update(x) = grid(n);

			else {

				// compute variational derivatives
				sparse<double> dFdp;
				for (int h=0; h<length(lapPhi); h++) {
					int hindex = MMSP::index(lapPhi,h);
					double phii = grid(n)[hindex];
					for (int j=h+1; j<length(lapPhi); j++) {
						int jindex = MMSP::index(lapPhi,j);
						double phij = grid(n)[jindex];
						double gamma = energy(hindex,jindex);
						double eps = 4.0/acos(-1.0)*sqrt(0.5*gamma*width);
						double w = 4.0*gamma/width;
						set(dFdp,hindex) += 0.5*eps*eps*lapPhi[jindex]+w*phij;
						set(dFdp,jindex) += 0.5*eps*eps*lapPhi[hindex]+w*phii;
						for (int k=j+1; k<length(lapPhi); k++) {
							int kindex = MMSP::index(lapPhi,k);
							double phik = grid(n)[kindex];
							set(dFdp,hindex) += 3.0*phij*phik;
							set(dFdp,jindex) += 3.0*phii*phik;
							set(dFdp,kindex) += 3.0*phii*phij;
						}
					}
				}

				// compute time derivatives
				sparse<double> dpdt;
				for (int h=0; h<length(lapPhi); h++) {
					int hindex = MMSP::index(lapPhi,h);
					for (int j=h+1; j<length(lapPhi); j++) {
						int jindex = MMSP::index(lapPhi,j);
						double mu = mobility(hindex,jindex);
						set(dpdt,hindex) -= mu*(dFdp[hindex]-dFdp[jindex]);
						set(dpdt,jindex) -= mu*(dFdp[jindex]-dFdp[hindex]);
					}
				}

				// compute update values
				double sum = 0.0;
				for (int h=0; h<length(dpdt); h++) {
					int index = MMSP::index(dpdt,h);
					double value = grid(n)[index]+dt*(2.0/S)*dpdt[index];
					if (value>1.0) value = 1.0;
					if (value<0.0) value = 0.0;
					if (value>machine_epsilon) set(update(x),index) = value;
					sum += update(x)[index];
				}

				// project onto Gibbs simplex
				double rsum = (fabs(sum)>machine_epsilon)?1.0/sum:0.0;
				for (int h=0; h<length(update(x)); h++) {
					int index = MMSP::index(update(x),h);
					set(update(x),index) *= rsum;
				}
			}
		}
		swap(grid,update);
		ghostswap(grid);
	}
	MMSP::sparse<double> mass;
	for (int n=0; n<nodes(grid); n++)
		for (int l=0; l<length(grid(n)); l++) {
			int index = grid(n).index(l);
			set(mass,index) += grid(n)[index];
		}
	for (int l=0; l<length(mass); l++)
		std::cout<<mass.value(l)<<'\t';
	std::cout<<std::endl;
}
Exemple #20
0
int main(int argc, char *argv[])
{
    int ix, iz, it, itau;
    int nx, nz, ntau, nt, pad;
    float dt, dtau, dx, dz, dt2, idz2, idx2;
    float tau0, tau;
    
    float ***dd, ***mm, **vv, **v0;
    float **u0, **u1, **u2, **ud, **tmp;
    
    sf_axis ax, az, atau;
    sf_file tgather, cgather, vel;
    
    sf_init(argc, argv);
    
    tgather=sf_input("in");
    cgather=sf_output("out");
    vel=sf_input("velocity");
    
    az=sf_iaxa(tgather, 1);
    ax=sf_iaxa(tgather, 2);
    atau=sf_iaxa(tgather, 3);
    
    nz=sf_n(az); dz=sf_d(az);
    nx=sf_n(ax); dx=sf_d(ax);
    ntau=sf_n(atau); dtau=sf_d(atau); tau0=sf_o(atau);
    
    if(!sf_getfloat("dt", &dt)) dt=0.001;
    if(!sf_getint("pad", &pad)) pad=30;
    padnx=nx+2*pad;
    padnz=nz+2*pad;
    
    idz2=1.0/(dz*dz);
    idx2=1.0/(dx*dx);
    
    c11=4.0*idz2/3.0;
    c12=-idz2/12.0;
    c21=4.0*idx2/3.0;
    c22=-idx2/12.0;
    c0=-2.0*(c11+c12+c21+c22);
    
    dd=sf_floatalloc3(nz, nx, ntau);
    mm=sf_floatalloc3(nz, nx, ntau);
    vv=sf_floatalloc2(nz, nx);
    
    v0=sf_floatalloc2(padnz, padnx);
    padvv=sf_floatalloc2(padnz, padnx);
    
    u0=sf_floatalloc2(padnz, padnx);
    u1=sf_floatalloc2(padnz, padnx);
    u2=sf_floatalloc2(padnz, padnx);
    ud=sf_floatalloc2(padnz, padnx);
    
    sf_floatread(dd[0][0], ntau*nx*nz, tgather);
    sf_floatread(vv[0], nx*nz, vel);
    
    dt2=dt*dt;
    for(ix=0; ix<nx; ix++)
        for(iz=0; iz<nz; iz++)
            padvv[ix+pad][iz+pad]=vv[ix][iz]*vv[ix][iz]*dt2;
    for(iz=0; iz<pad; iz++)
        for(ix=pad; ix<nx+pad; ix++){
            padvv[ix][iz]=padvv[ix][pad];
            padvv[ix][pad+nz+iz]=padvv[ix][pad+nz-1];
        }
    
    for(ix=0; ix<pad; ix++)
        for(iz=0; iz<padnz; iz++){
            padvv[ix][iz]=padvv[pad][iz];
            padvv[ix+pad+nx][iz]=padvv[pad+nx-1][iz];
        }
    
    for(itau=0; itau<ntau; itau++){
		sf_warning("itau=%d/%d", itau+1, ntau);
        
        zero2(u0, padnz, padnx);
        zero2(u1, padnz, padnx);
        zero2(u2, padnz, padnx);
        zero2(ud, padnz, padnx);
        zero2(v0, padnz, padnx);
        
        tau=tau0+itau*dtau;

		// tau=0
        if(tau==0.){
            for(ix=0; ix<nx; ix++)
                for(iz=0; iz<nz; iz++)
                    mm[itau][ix][iz]=dd[itau][ix][iz];
            continue;
        }
        
        // calculate v0 (derivative with respect to tau)
        if(itau==0){
            for(ix=0; ix<nx; ix++){
                for(iz=0; iz<nz; iz++){
                    v0[ix+pad][iz+pad]=(dd[1][ix][iz]-dd[0][ix][iz])/dtau;
                }
            }
        } else if (itau==ntau-1){
            for(ix=0; ix<nx; ix++){
                for(iz=0; iz<nz; iz++){
                    v0[ix+pad][iz+pad]=(dd[ntau-1][ix][iz]-dd[ntau-2][ix][iz])/dtau;
                }
            }
        } else {
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
            for(ix=0; ix<nx; ix++){
                for(iz=0; iz<nz; iz++){
                    v0[ix+pad][iz+pad]=(dd[itau+1][ix][iz]-dd[itau-1][ix][iz])/dtau/2.0;
                }
            }
        }
        
        // calculate u1
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
        for(ix=0; ix<nx; ix++)
            for(iz=0; iz<nz; iz++)
                u1[ix+pad][iz+pad]=dd[itau][ix][iz];
        
		// tau>0
        if(tau>0.){
            
            laplacian(u1, ud);
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
            for(ix=0; ix<padnx; ix++){
                for(iz=0; iz<padnz; iz++){
                    u0[ix][iz]=u1[ix][iz]+ud[ix][iz]/2.0-v0[ix][iz]*dt;
                }
            }
            
            nt=tau/dt+0.5;
            
            for(it=1; it<nt; it++){
				sf_warning("it=%d/%d;", it+1, nt);
                tmp=u2; u2=u1; u1=u0; u0=tmp;
                
                laplacian(u1, ud);
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
                for(ix=0; ix<padnx; ix++){
                    for(iz=0; iz<padnz; iz++){
                        u0[ix][iz]=2*u1[ix][iz]-u2[ix][iz]+ud[ix][iz];
                    }
                }
            } //end of it
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
            for(ix=0; ix<nx; ix++){
                for(iz=0; iz<nz; iz++){
                    mm[itau][ix][iz]=u0[ix+pad][iz+pad];
                }
            }
        }
        
		// tau<0
        if(tau<0.){
            
            laplacian(u1, ud);
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
            for(ix=0; ix<padnx; ix++){
                for(iz=0; iz<padnz; iz++){
                    u2[ix][iz]=u1[ix][iz]+dt*v0[ix][iz]+ud[ix][iz]/2.0;
                }
            }
            
            nt=-tau/dt+0.5;
            
            for(it=1; it<nt; it++){
				sf_warning("it=%d/%d;", it+1, nt);
                tmp=u0; u0=u1; u1=u2; u2=tmp;
                
                laplacian(u1, ud);
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
                for(ix=0; ix<padnx; ix++){
                    for(iz=0; iz<padnz; iz++){
                        u2[ix][iz]=2*u1[ix][iz]-u0[ix][iz]+ud[ix][iz];
                    }
                }
            }//end of it
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
            for(ix=0; ix<nx; ix++){
                for(iz=0; iz<nz; iz++){
                    mm[itau][ix][iz]=u2[ix+pad][iz+pad];
                }
            }
        }
    } //end of itau
    
    sf_floatwrite(mm[0][0], ntau*nx*nz, cgather);
    
    exit(0);
}
Exemple #21
0
int main(int argc, char* argv[])
{
    int it,i1,i2;        /* index variables */
    int nt,n12,ft,jt;
    float dt,d1,d2,dt2;

    float  *ww,**vv,**rr;       
    float **u0,**u1,**u2,**ud; 

    sf_file Fw,Fv,Fr,Fo;  /* I/O files */

    /* initialize Madagascar */
    sf_init(argc,argv);

    /* initialize OpenMP support */ 
    omp_init();

    /* setup I/O files */
    Fr = sf_input ("in");    /* source position */
    Fo = sf_output("out");   /* output wavefield */

    Fw = sf_input ("wav");   /* source wavelet */
    Fv = sf_input ("v");     /* velocity */

    /* Read/Write axes */
    if (!sf_histint(Fr,"n1",&n1))   sf_error("No n1= in inp");
    if (!sf_histint(Fr,"n2",&n2))   sf_error("No n2= in inp");
    if (!sf_histfloat(Fr,"d1",&d1)) sf_error("No d1= in inp");
    if (!sf_histfloat(Fr,"d2",&d2)) sf_error("No d2= in inp");

    if (!sf_histint(Fw,"n1",&nt))   sf_error("No n1= in wav");
    if (!sf_histfloat(Fw,"d1",&dt)) sf_error("No d1= in wav");

    n12 = n1*n2;

    if (!sf_getint("ft",&ft)) ft=0; 
    /* first recorded time */
    if (!sf_getint("jt",&jt)) jt=1; 
    /* time interval */

    sf_putint(Fo,"n3",(nt-ft)/jt);
    sf_putfloat(Fo,"d3",jt*dt);
    sf_putfloat(Fo,"o3",ft*dt);

    dt2 =    dt*dt;

    /* set Laplacian coefficients */
    d1 = 1.0/(d1*d1);
    d2 = 1.0/(d2*d2);

    c11 = 4.0*d1/3.0;
    c12=  -d1/12.0;
    c21 = 4.0*d2/3.0;
    c22=  -d2/12.0;
    c0  = -2.0 * (c11+c12+c21+c22);

    /* read wavelet, velocity & source position */
    ww=sf_floatalloc(nt);     sf_floatread(ww   ,nt ,Fw);
    vv=sf_floatalloc2(n1,n2); sf_floatread(vv[0],n12,Fv);
    rr=sf_floatalloc2(n1,n2); sf_floatread(rr[0],n12,Fr);

    /* allocate temporary arrays */
    u0=sf_floatalloc2(n1,n2);
    u1=sf_floatalloc2(n1,n2);
    u2=sf_floatalloc2(n1,n2);
    ud=sf_floatalloc2(n1,n2);
    
    for (i2=0; i2<n2; i2++) {
	for (i1=0; i1<n1; i1++) {
	    u0[i2][i1]=0.0;
	    u1[i2][i1]=0.0;
	    u2[i2][i1]=0.0;
	    ud[i2][i1]=0.0;
	    vv[i2][i1] *= vv[i2][i1]*dt2;
	}
    }

    /* Time loop */
    for (it=0; it<nt; it++) {
	laplacian(u1,ud);

#ifdef _OPENMP
#pragma omp parallel for	    \
    private(i2,i1)		    \
    shared(ud,vv,ww,it,rr,u2,u1,u0)
#endif	
	for (i2=0; i2<n2; i2++) {
	    for (i1=0; i1<n1; i1++) {
		/* scale by velocity */
		ud[i2][i1] *= vv[i2][i1];
		/* inject wavelet */
		ud[i2][i1] += ww[it] * rr[i2][i1];
		/* time step */
		u2[i2][i1] = 
		    2*u1[i2][i1] 
		    - u0[i2][i1] 
		    + ud[i2][i1]; 
		u0[i2][i1] = u1[i2][i1];
		u1[i2][i1] = u2[i2][i1];
	    }
	}		
	
	/* write wavefield to output */
	if (it >= ft && 0 == (it-ft)%jt) {
	    sf_warning("%d;",it+1);
	    sf_floatwrite(u1[0],n12,Fo);
	}
    }
    sf_warning(".");
    
    exit (0);
}
int main(int argc, char *argv[])
{
  int step, ie, iside, i, j, k;
  double mflops, tmax, nelt_tot = 0.0;
  char Class;
  logical ifmortar = false, verified;

  double t2, trecs[t_last+1];
  char *t_names[t_last+1];

	//--------------------------------------------------------------------
	// Initialize NUMA control
	//--------------------------------------------------------------------
	numa_initialize_env(NUMA_MIGRATE_EXISTING);

  //---------------------------------------------------------------------
  // Read input file (if it exists), else take
  // defaults from parameters
  //---------------------------------------------------------------------
  FILE *fp;
  if ((fp = fopen("timer.flag", "r")) != NULL) {
    timeron = true;
    t_names[t_total] = "total";
    t_names[t_init] = "init";
    t_names[t_convect] = "convect";
    t_names[t_transfb_c] = "transfb_c";
    t_names[t_diffusion] = "diffusion";
    t_names[t_transf] = "transf";
    t_names[t_transfb] = "transfb";
    t_names[t_adaptation] = "adaptation";
    t_names[t_transf2] = "transf+b";
    t_names[t_add2] = "add2";
    fclose(fp);
  } else {
    timeron = false;
  }

  printf("\n\n NAS Parallel Benchmarks (NPB3.3-OMP-C) - UA Benchmark\n\n");

  if ((fp = fopen("inputua.data", "r")) != NULL) {
    int result;
    printf(" Reading from input file inputua.data\n");
    result = fscanf(fp, "%d", &fre);
    while (fgetc(fp) != '\n');
    result = fscanf(fp, "%d", &niter);
    while (fgetc(fp) != '\n');
    result = fscanf(fp, "%d", &nmxh);
    while (fgetc(fp) != '\n');
    result = fscanf(fp, "%lf", &alpha);
    Class = 'U';
    fclose(fp);
  } else {
    printf(" No input file inputua.data. Using compiled defaults\n");
    fre   = FRE_DEFAULT;
    niter = NITER_DEFAULT;
    nmxh  = NMXH_DEFAULT;
    alpha = ALPHA_DEFAULT;
    Class = CLASS_DEFAULT;
  }

  dlmin = pow(0.5, REFINE_MAX);
  dtime = 0.04*dlmin;

  printf(" Levels of refinement:        %8d\n", REFINE_MAX);
  printf(" Adaptation frequency:        %8d\n", fre);
  printf(" Time steps:                  %8d    dt: %15.6E\n", niter, dtime);
  printf(" CG iterations:               %8d\n", nmxh);
  printf(" Heat source radius:          %8.4f\n", alpha);
  printf(" Number of available threads: %8d\n", omp_get_max_threads());
  printf("\n");

  top_constants();

  for (i = 1; i <= t_last; i++) {
    timer_clear(i);
  }
  if (timeron) timer_start(t_init);

  // set up initial mesh (single element) and solution (all zero)
  create_initial_grid();

  r_init_omp((double *)ta1, ntot, 0.0);
  nr_init_omp((int *)sje, 4*6*nelt, -1);

  init_locks();

  // compute tables of coefficients and weights      
  coef();
  geom1();

  // compute the discrete laplacian operators
  setdef();

  // prepare for the preconditioner
  setpcmo_pre();

  // refine initial mesh and do some preliminary work
  time = 0.0;
  mortar();
  prepwork();
  adaptation(&ifmortar, 0);
  if (timeron) timer_stop(t_init);

  timer_clear(1);

  time = 0.0;
  for (step = 0; step <= niter; step++) {
    if (step == 1) {
      // reset the solution and start the timer, keep track of total no elms
      r_init((double *)ta1, ntot, 0.0);

      time = 0.0;
      nelt_tot = 0.0;
      for (i = 1; i <= t_last; i++) {
        if (i != t_init) timer_clear(i);
      }
      timer_start(1);
    }

    // advance the convection step 
    convect(ifmortar);

    if (timeron) timer_start(t_transf2);
    // prepare the intital guess for cg
    transf(tmort, (double *)ta1);

    // compute residual for diffusion term based on intital guess

    // compute the left hand side of equation, lapacian t
    #pragma omp parallel default(shared) private(ie,k,j,i) 
    {
    #pragma omp for
    for (ie = 0; ie < nelt; ie++) {
      laplacian(ta2[ie], ta1[ie], size_e[ie]);
    }

    // compute the residual 
    #pragma omp for
    for (ie = 0; ie < nelt; ie++) {
      for (k = 0; k < LX1; k++) {
        for (j = 0; j < LX1; j++) {
          for (i = 0; i < LX1; i++) {
            trhs[ie][k][j][i] = trhs[ie][k][j][i] - ta2[ie][k][j][i];
          }
        }
      }
    }
    } //end parallel

    // get the residual on mortar 
    transfb(rmor, (double *)trhs);
    if (timeron) timer_stop(t_transf2);

    // apply boundary condition: zero out the residual on domain boundaries

    // apply boundary conidtion to trhs
    #pragma omp parallel for default(shared) private(ie,iside)
    for (ie = 0; ie < nelt; ie++) {
      for (iside = 0; iside < NSIDES; iside++) {
        if (cbc[ie][iside] == 0) {
          facev(trhs[ie], iside, 0.0);
        }
      }
    }
    // apply boundary condition to rmor
    col2(rmor, tmmor, nmor);

    // call the conjugate gradient iterative solver
    diffusion(ifmortar);

    // add convection and diffusion
    if (timeron) timer_start(t_add2);
    add2((double *)ta1, (double *)t, ntot);
    if (timeron) timer_stop(t_add2);

    // perform mesh adaptation
    time = time + dtime;
    if ((step != 0) && (step/fre*fre == step)) {
      if (step != niter) {
        adaptation(&ifmortar, step);
      }
    } else {
      ifmortar = false;
    }
    nelt_tot = nelt_tot + (double)(nelt);
  }

  timer_stop(1);
  tmax = timer_read(1);

  verify(&Class, &verified);

  // compute millions of collocation points advanced per second.
  // diffusion: nmxh advancements, convection: 1 advancement
  mflops = nelt_tot*(double)(LX1*LX1*LX1*(nmxh+1))/(tmax*1.e6);

  print_results("UA", Class, REFINE_MAX, 0, 0, niter, 
                tmax, mflops, "    coll. point advanced", 
                verified, NPBVERSION, COMPILETIME, CS1, CS2, CS3, CS4, CS5, 
                CS6, "(none)");

  //---------------------------------------------------------------------
  // More timers
  //---------------------------------------------------------------------
  if (timeron) {
    for (i = 1; i <= t_last; i++) {
      trecs[i] = timer_read(i);
    }
    if (tmax == 0.0) tmax = 1.0;

    printf("  SECTION     Time (secs)\n");
    for (i = 1; i <= t_last; i++) {
      printf("  %-10s:%9.3f  (%6.2f%%)\n",
          t_names[i], trecs[i], trecs[i]*100./tmax);
      if (i == t_transfb_c) {
        t2 = trecs[t_convect] - trecs[t_transfb_c];
        printf("    --> %11s:%9.3f  (%6.2f%%)\n", 
            "sub-convect", t2, t2*100./tmax);
      } else if (i == t_transfb) {
        t2 = trecs[t_diffusion] - trecs[t_transf] - trecs[t_transfb];
        printf("    --> %11s:%9.3f  (%6.2f%%)\n", 
            "sub-diffuse", t2, t2*100./tmax);
      }
    }
  }

	//--------------------------------------------------------------------
	// Teardown NUMA control
	//--------------------------------------------------------------------
	numa_shutdown();

  return 0;
}
    inline fvMatrixHolder< Type > laplacian( const GeometricFieldHolder< GType, fvPatchField, volMesh >& field1, 
					     GeometricFieldHolder< Type, fvPatchField, volMesh >& field2 )
    {
      return fvMatrixHolder< Type >( laplacian( field1(), field2() ), Deps( &field1, &field2 )  );
    }
Exemple #24
0
int main(int argc, char* argv[])
{
	int i, j, k, it;
    //FILE *fp;
	//int fd;
	real mean;
	struct timeval tim;
	double start, end;

	if (argc != 5)
	{
		printf("Usage: %s <nx> <ny> <ns> <nt>\n", argv[0]);
		exit(1);
	}

	srand(17);
	parse_arg(nx, argv[1]);
	parse_arg(ny, argv[2]);
	parse_arg(ns, argv[3]);
	parse_arg(nt, argv[4]);

	real alpha = real_rand();
	real beta = real_rand();

	printf("alpha = %f, beta = %f\n", alpha, beta);

	unsigned int szarray = (unsigned int)nx * ny * ns;
	unsigned int szarrayb = szarray * sizeof(real);

	real* w0 = (real*)malloc(szarrayb);
	real* w1 = (real*)malloc(szarrayb);

	if (!w0 || !w1)
	{
		printf("Error allocating memory for arrays: %p, %p\n", w0, w1);
		exit(1);
	}

	for (i = 0; i < szarray; i++)
	{
		w0[i] = real_rand();
		w1[i] = real_rand();
	}

	// 1) Perform an empty offload, that should strip
	// the initialization time from further offloads.
	acc_init(acc_device_default);
	
	gettimeofday(&tim, NULL);
	start = tim.tv_sec + (tim.tv_usec/1000000.0);

	// 2) Allocate data on device, but do not copy anything.
	#pragma acc data create (w0[0:szarray], w1[0:szarray])
	{
		// 3) Transfer data from host to device and leave it there,
		// i.e. do not allocate deivce memory buffers.
		#pragma acc update device(w0[0:szarray], w1[0:szarray])
		// 4) Perform data processing iterations, keeping all data
		// on device.
		{
			for (it = 0; it < nt; it++)
			{
				laplacian(nx, ny, ns, alpha, beta, w0, w1);
				real* w = w0; w0 = w1; w1 = w;
			}
		}

		// 5) Transfer output data back from device to host.
		#pragma acc update host (w0[0:szarray])
	}
	
	gettimeofday(&tim, NULL);
    end = tim.tv_sec + (tim.tv_usec/1000000.0);
#if 0	
	fd = creat(argv[5], 00666);
	fd = open(argv[5], O_WRONLY);
	write(fd, w0, szarrayb);
	close(fd);
    fp = fopen(argv[5], "w");
    fprintf(fp, "%d %d %d\n", ns, ny, nx);
	for(k = 0; k < ns; k++){
    	for (j = 0; j < ny; j++) {
        	for (i = 0; i < nx; i++) {
            	fprintf(fp, "%d %d %d %f\n", k, j, i, w0[k*nx*ny + j*nx + i]);
        	}
    	}
	}
    fclose(fp);
#endif
	
	mean = 0.0f;
	for (i = 0; i < szarray; i++)
		mean += w0[i];

	printf("Final mean = %f\n", mean/szarray);
	printf("Time for computing: %.2f s\n",end-start);

	free(w0);
	free(w1);

	return 0;
}
Exemple #25
0
/*
 * This routine is in charge of the momentum equation.  Virtually all
 * of the terms can be enabled or disabled by parameters read in through the
 * configuration file.  This equation has the form:
 * 
 * du/dt = div(alpha BB - uu - P) + (Ra T + B^2 / beta) hat z + Pr del^2 u + F_u 
 * 
 * Since the velocity field is incompressible, the pressure term doesn't matter
 * and is eliminated by taking the curl of the right-hand side.  This is then
 * decomposed into poloidal and toroidal components, which are then used in the
 * time integration.
 */
void calcMomentum()
{
    debug("Calculating momentum forces\n");

    int i,j,k;
    int index;

    if(viscosity)
    {
        //First argument is the field we take the laplacian of.
        //Second argument is where the result is stored.
        //The 0 in the third argument means we overwrite the destination array
        //Pr is the coefficient for this diffusion term.
        laplacian(u->vec->x->spectral, rhs->x->spectral, 0, Pr);
        laplacian(u->vec->y->spectral, rhs->y->spectral, 0, Pr);
        laplacian(u->vec->z->spectral, rhs->z->spectral, 0, Pr);
    }
    else
    {
        //make sure we don't start with garbage
        memset(rhs->x->spectral, 0, spectralCount * sizeof(complex PRECISION));
        memset(rhs->y->spectral, 0, spectralCount * sizeof(complex PRECISION));
        memset(rhs->z->spectral, 0, spectralCount * sizeof(complex PRECISION));
    }
    
    //Apply hyper diffusion to the boundaries
    //This does not currently work and is disabled by default!
    if(sanitize)
    {
        killBoundaries(u->vec->x->spatial, rhs->x->spectral, 1, 100*Pr);
        killBoundaries(u->vec->y->spatial, rhs->y->spectral, 1, 100*Pr);
        killBoundaries(u->vec->z->spatial, rhs->z->spectral, 1, 100*Pr);
    }

    //static forcing is read in from a file and currently only in the u 
    //direction as a function of y and z (to remove nonlinear advection)
    if(momStaticForcing)
    {
        complex PRECISION * xfield = rhs->x->spectral;
        complex PRECISION * ffield = forceField->spectral;
        index = 0;
        for(i = 0; i < spectralCount; i++)
        {
            xfield[i] += ffield[i];
        }
    }

    //
    if(momTimeForcing)
    {
        //Evaluate the force function at the current time.
        fillTimeField(temp1, MOMENTUM);

        plusEq(rhs->x->spectral, temp1->x->spectral);
        plusEq(rhs->y->spectral, temp1->y->spectral);
        plusEq(rhs->z->spectral, temp1->z->spectral);
    }

    
    if(momAdvection)
    {
        p_field tense = temp1->x;

	    //Note here, because I already forgot once.  a 2 as the third
	    //parameter makes things behave as a -= operation!
        multiply(u->vec->x->spatial, u->vec->x->spatial, tense->spatial);
        fftForward(tense);
        partialX(tense->spectral, rhs->x->spectral, 2);

        multiply(u->vec->y->spatial, u->vec->y->spatial, tense->spatial);
        fftForward(tense);
        partialY(tense->spectral, rhs->y->spectral, 2);

        multiply(u->vec->z->spatial, u->vec->z->spatial, tense->spatial);
        fftForward(tense);
        partialZ(tense->spectral, rhs->z->spectral, 2);

        multiply(u->vec->x->spatial, u->vec->y->spatial, tense->spatial);
        fftForward(tense);
        partialY(tense->spectral, rhs->x->spectral, 2);
        partialX(tense->spectral, rhs->y->spectral, 2);

        multiply(u->vec->x->spatial, u->vec->z->spatial, tense->spatial);
        fftForward(tense);
        partialZ(tense->spectral, rhs->x->spectral, 2);
        partialX(tense->spectral, rhs->z->spectral, 2);

        multiply(u->vec->y->spatial, u->vec->z->spatial, tense->spatial);
        fftForward(tense);
        partialZ(tense->spectral, rhs->y->spectral, 2);
        partialY(tense->spectral, rhs->z->spectral, 2);      
    }


    if(lorentz)
    {
        p_field tense = temp1->x;
        p_vector lor = temp2;

        //The third parameter as a 0 means we overwrite the destination array.
        //The third parameter as a 1 means it behaves as a += operation.
        
        multiply(B->vec->x->spatial, B->vec->x->spatial, tense->spatial);
        fftForward(tense);
        partialX(tense->spectral, lor->x->spectral, 0);

        multiply(B->vec->y->spatial, B->vec->y->spatial, tense->spatial);
        fftForward(tense);
        partialY(tense->spectral, lor->y->spectral, 0);

        multiply(B->vec->z->spatial, B->vec->z->spatial, tense->spatial);
        fftForward(tense);
        partialZ(tense->spectral, lor->z->spectral, 0);

        multiply(B->vec->x->spatial, B->vec->y->spatial, tense->spatial);
        fftForward(tense);
        partialY(tense->spectral, lor->x->spectral, 1);
        partialX(tense->spectral, lor->y->spectral, 1);

        multiply(B->vec->x->spatial, B->vec->z->spatial, tense->spatial);
        fftForward(tense);
        partialZ(tense->spectral, lor->x->spectral, 1);
        partialX(tense->spectral, lor->z->spectral, 1);

        multiply(B->vec->y->spatial, B->vec->z->spatial, tense->spatial);
        fftForward(tense);
        partialZ(tense->spectral, lor->y->spectral, 1);
        partialY(tense->spectral, lor->z->spectral, 1);

        //TODO: Find a routine to change to include this factor
        complex PRECISION * px = lor->x->spectral;
        complex PRECISION * py = lor->y->spectral;
        complex PRECISION * pz = lor->z->spectral;
        int i;
        for(i = 0; i < spectralCount; i++)
        {
            px[i] *= alpha;
            py[i] *= alpha;
            pz[i] *= alpha;
        }

        plusEq(rhs->x->spectral, px);
        plusEq(rhs->y->spectral, py);
        plusEq(rhs->z->spectral, pz);
    }
    
    if(magBuoy)
    {
        p_field B2 = temp1->x;
        dotProduct(B->vec,B->vec,B2);
        fftForward(B2);
        for(i = 0; i < spectralCount; i++)
        {
            B2->spectral[i] *= magBuoyScale;
        }
        plusEq(rhs->z->spectral, B2->spectral);
    }

    if(buoyancy)
    {
        complex PRECISION * zfield = rhs->z->spectral;
        complex PRECISION * tfield = T->spectral;

        PRECISION factor =  Ra * Pr;
        index = 0;
        for(i = 0; i < spectralCount; i++)
        {
            zfield[i] += factor * tfield[i];
        }
    }
    
    //curl it so we can avoid dealing with the pressure term
    curl(rhs, temp1);

    //The third parameter as a 1 means we store the result in the force
    //arrays for u->sol.
    decomposeCurlSolenoidal(u->sol, temp1, 1);
    debug("Momentum forces done\n");
}
template <int dim> void update(grid<dim, sparse<phi_type> >& oldGrid, int steps)
{
	#if (!defined MPI_VERSION) && (defined BGQ)
	std::cerr<<"Error: Blue Gene requires MPI."<<std::endl;
	exit(-1);
	#endif
	int rank=0;
	#ifdef MPI_VERSION
	rank = MPI::COMM_WORLD.Get_rank();
	#endif
	const phi_type dt = 0.01;
	const phi_type width = 14.5;
	const phi_type epsilon = 1.0e-8;

	for (int step = 0; step < steps; step++) {
		if (rank==0) print_progress(step, steps);
		// newGrid must be overwritten each time
		ghostswap(oldGrid);
		grid<dim, sparse<phi_type> > newGrid(oldGrid);

		for (int i = 0; i < nodes(oldGrid); i++) {
			vector<int> x = position(oldGrid, i);

			// determine nonzero fields within
			// the neighborhood of this node
			// (2 adjacent voxels along each cardinal direction)
			sparse<int> s;
			for (int j = 0; j < dim; j++)
				for (int k = -1; k <= 1; k++) {
					x[j] += k;
					for (int h = 0; h < length(oldGrid(x)); h++) {
						int sindex = index(oldGrid(x), h);
						set(s, sindex) = 1;
					}
					x[j] -= k;
				}
			phi_type S = phi_type(length(s));

			// if only one field is nonzero,
			// then copy this node to newGrid
			if (S < 2.0) newGrid(i) = oldGrid(i);
			else {
				// compute laplacian of each field
				sparse<phi_type> lap = laplacian(oldGrid, i);

				// compute variational derivatives
				sparse<phi_type> dFdp;
				for (int h = 0; h < length(s); h++) {
					int hindex = index(s, h);
					for (int j = h + 1; j < length(s); j++) {
						int jindex = index(s, j);
						phi_type gamma = energy(hindex, jindex);
						phi_type eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width);
						phi_type w = 4.0 * gamma / width;
						// Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h
						set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * oldGrid(i)[jindex];
						set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * oldGrid(i)[hindex];
					}
				}

				// compute time derivatives
				sparse<phi_type> dpdt;
				for (int h = 0; h < length(s); h++) {
					int hindex = index(s, h);
					for (int j = h + 1; j < length(s); j++) {
						int jindex = index(s, j);
						phi_type mu = mobility(hindex, jindex);
						set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]);
						set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]);
					}
				}

				// compute new values
				phi_type sum = 0.0;
				for (int h = 0; h < length(s); h++) {
					int sindex = index(s, h);
					phi_type value = oldGrid(i)[sindex] + dt * (2.0 / S) * dpdt[sindex]; // Extraneous factor of 2?
					if (value > 1.0) value = 1.0;
					if (value < 0.0) value = 0.0;
					if (value > epsilon) set(newGrid(i), sindex) = value;
					sum += newGrid(i)[sindex];
				}

				// project onto Gibbs simplex (enforce Σφ=1)
				phi_type rsum = 0.0;
				if (fabs(sum) > 0.0) rsum = 1.0 / sum;
				for (int h = 0; h < length(newGrid(i)); h++) {
					int sindex = index(newGrid(i), h);
					set(newGrid(i), sindex) *= rsum;
				}
			}
		} // Loop over nodes(oldGrid)
		swap(oldGrid, newGrid);
	} // Loop over steps
	ghostswap(oldGrid);
}
Exemple #27
0
int main(int argc, char* argv[])
{
    bool adj, snap; /* adjoint flag */
    int ix, iz, it; /* index variables */
    int nt, nx, nz, n0, jt, n12, padx, padz, n2;
    float dt, dx, dz, dt2, idz2, idx2;
    
    float **dd, **mm, **vv;
    float **u0, **u1, **u2, **tmp; /* temporary arrays */

    sf_file in, out, vel, wave; /* I/O files */

    /* initialize Madagascar */
    sf_init(argc,argv);
    
    /* initialize OpenMP support */
#ifdef _OPENMP
    omp_init();
#endif

    if(!sf_getbool("adj", &adj)) adj=true;
    /* adjoint flag, 0: modeling, 1: migration */
    if(!sf_getbool("snap", &snap)) snap=false;
    /* wavefield snapshot flag */
    if(!sf_getint("n0", &n0)) n0=0;
    /* surface */
    if(!sf_getint("jt", &jt)) jt=50;
    /* time interval of wavefield snapshot */
	
    /* setup I/O files */
    in=sf_input("in");
    out=sf_output("out");
    vel=sf_input("velocity");
    /* velocity model */
    
    /* Dimensions */
    if(!sf_histint(vel, "n1", &nz)) sf_error("No n1= in velocity");
    if(!sf_histint(vel, "n2", &nx)) sf_error("No n2= in velocity");
    if(!sf_histfloat(vel, "d1", &dz)) sf_error("No d1= in velocity");
    if(!sf_histfloat(vel, "d2", &dx)) sf_error("No d2= in velocity");

    if(adj){ /* migration */
        if(!sf_histint(in, "n1", &nt)) sf_error("No n1= in data");
        if(!sf_histfloat(in, "d1", &dt)) sf_error("No d1= in data");
        if(!sf_histint(in, "n2", &n2) || n2!=nx) sf_error("Need n2=%d in data", nx);
        
        sf_putint(out, "n1", nz);
        sf_putfloat(out, "d1", dz);
        sf_putfloat(out, "o1", 0.0);
        sf_putstring(out, "label1", "Depth");
        sf_putstring(out, "unit1", "km");
        sf_putstring(out, "label2", "Lateral");
        sf_putstring(out, "unit2", "km");
    }else{ /* modeling */
        if(!sf_getint("nt", &nt)) sf_error("Need nt=");
        if(!sf_getfloat("dt", &dt)) sf_error("Need dt=");
        
        sf_putint(out, "n1", nt);
        sf_putfloat(out, "d1", dt);
        sf_putfloat(out, "o1", 0.0);
        sf_putstring(out, "label1", "Time");
        sf_putstring(out, "unit1", "s");
        sf_putstring(out, "label2", "Lateral");
        sf_putstring(out, "unit2", "km");
    }
    
    /* lengths of padding boundary */
    if(!sf_getint("padx", &padx)) padx=nz/2;
    if(!sf_getint("padz", &padz)) padz=nz/2;
    padnx=nx+2*padx;
    padnz=nz+2*padz;
    n0=n0+padz;
    n12=padnz*padnx;

    /* set Laplacian coefficients */
    idz2=1.0/(dz*dz);
    idx2=1.0/(dx*dx);
    
    c11=4.0*idz2/3.0;
    c12=-idz2/12.0;
    c21=4.0*idx2/3.0;
    c22=-idx2/12.0;
    c0=-2.0*(c11+c12+c21+c22);
    
    /* wavefield snapshot */
    if(snap){
        wave=sf_output("wave");
        
        sf_putint(wave, "n1", padnz);
        sf_putint(wave, "d1", 1);
        sf_putint(wave, "o1", -padz);
            
        sf_putint(wave, "n2", padnx);
        sf_putint(wave, "d2", 1);
        sf_putint(wave, "o2", -padx);
        
        sf_putint(wave, "n3", 1+(nt-1)/jt);
        if(adj){
            sf_putfloat(wave, "d3", -jt*dt);
            sf_putfloat(wave, "o3", (nt-1)*dt);
        }else{
            sf_putfloat(wave, "d3", jt*dt);
            sf_putfloat(wave, "o3", 0.0);
        }
    }
        
    /* allocate arrays */
    vv=sf_floatalloc2(nz, nx);
    dd=sf_floatalloc2(nt, nx);
    mm=sf_floatalloc2(nz, nx);
    padvv=sf_floatalloc2(padnz, padnx);
    u0=sf_floatalloc2(padnz, padnx);
    u1=sf_floatalloc2(padnz, padnx);
    u2=sf_floatalloc2(padnz, padnx);
    
    /* read velocity */
    sf_floatread(vv[0], nz*nx, vel);
    
    /* pad boundary */
    dt2=dt*dt;
    for(ix=0; ix<nx; ix++)
        for(iz=0; iz<nz; iz++)
            padvv[ix+padx][iz+padz]=vv[ix][iz]*vv[ix][iz]*dt2;
    for(iz=0; iz<padz; iz++){
        for(ix=padx; ix<nx+padx; ix++){
            padvv[ix][iz]=padvv[ix][padz];
            padvv[ix][iz+nz+padz]=padvv[ix][nz+padz-1];
        }
    }
    for(ix=0; ix<padx; ix++){
        for(iz=0; iz<padnz; iz++){
            padvv[ix][iz]=padvv[padx][iz];
            padvv[ix+nx+padx][iz]=padvv[nx+padx-1][iz];
        }
    }
    
    memset(u0[0], 0.0, n12*sizeof(float));
    memset(u1[0], 0.0, n12*sizeof(float));
    memset(u2[0], 0.0, n12*sizeof(float));

    if(adj){ /* migration */
        
        /* read data */
        sf_floatread(dd[0], nt*nx, in);
        
        for(it=nt-1; it>=0; it--){
            sf_warning("Migration: %d;", it);
            
            laplacian(adj, u0, u1, u2);
            tmp=u0; u0=u1; u1=u2; u2=tmp;

#ifdef _OPENMP
#pragma omp parallel for default(none) private(ix) shared(padx, nx, dd, u1, it, n0)
#endif
            for(ix=padx; ix<padx+nx; ix++)
            /* inject data */
            u1[ix][n0]+=dd[ix-padx][it];
            
            if(snap && it%jt==0) sf_floatwrite(u1[0], n12, wave);
        }
        sf_warning(".");
        
        /* output image */
        for(ix=0; ix<nx; ix++)
            for(iz=0; iz<nz; iz++)
                mm[ix][iz]=u1[ix+padx][iz+padz];
        sf_floatwrite(mm[0], nz*nx, out);
    
    }else{/* modeling */
    	
        /* read reflector */
    	sf_floatread(mm[0], nz*nx, in);
        for(ix=0; ix<nx; ix++)
            for(iz=0; iz<nz; iz++)
                u1[ix+padx][iz+padz]=mm[ix][iz];
    	    
    	for(it=0; it<nt; it++){
            sf_warning("Modeling: %d;", it);
            
            if(snap && it%jt==0) sf_floatwrite(u1[0], n12, wave);

#ifdef _OPENMP
#pragma omp parallel for default(none) private(ix) shared(padx, nx, dd, u1, it, n0)
#endif
            for(ix=padx; ix<padx+nx; ix++)
            /* record data */
	        dd[ix-padx][it]=u1[ix][n0];
            
            laplacian(adj, u0, u1, u2);
            tmp=u0; u0=u1; u1=u2; u2=tmp;
        }
    	sf_warning(".");
        
    	/* output data */
    	sf_floatwrite(dd[0], nt*nx, out);
    }
    
    free(*padvv); free(padvv); free(*vv); free(vv);
    free(*dd); free(dd); free(*mm); free(mm);
    free(*u0); free(u0); free(*u1); free(u1); free(*u2); free(u2);
    exit (0);
}
Exemple #28
0
int main(int argc, char *argv[]){

  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
  numworkers = numtasks - 1;
  MPI_Comm_rank(MPI_COMM_WORLD,&taskid);

  if(taskid == MASTER){ // This code fragment runs in the master porcesses
    // clock_t start_t, end_t, total_t;
    allocate_memory();
    phi_initialize();
    fluid_initialize();
    gs_allocate();
    // start_t = clock();
    // printf("Starting of the program, start_t = %ld\n", start_t);
    for ( t = 0; t < phi_timesteps; t++ ) {
    #ifdef growth
      neuman_boundary(phi_old, MESHX);
      neuman_boundary(mu_old, MESHX);
      concentration(phi_old, mu_old, conc, MESHX);
      neuman_boundary(conc, MESHX);
      laplacian(phi_old, lap_phi, MESHX);
      laplacian(mu_old,  lap_mu,  MESHX);
      anisotropic_solverloop();
      update(phi_old, phi_new, MESHX);
      update(mu_old, mu_new, MESHX);
      if((t%save_phi) == 0) {
       write2file_phi(t, MESHX,phi_old);
      }
    #endif
    #ifdef FLUID
      if (t>SMOOTH) {
        fluid_solver();
        if((t%save_fluid) ==0) {
             write2file_fluid (t,u_old,v_old,MESHX);
        }
      }
    #endif
      printf("t=%d\n",t);
    }
    free_memory();

    // end_t = clock();
    // printf("End of the big loop, end_t = %ld\n", end_t);
    // total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
    // printf("Total time taken by CPU: %f\n", total_t  );
    printf("Exiting of the program...\n");

  } else { // This code fragment runs in the worker processes
    gs_allocate();
    for ( t = 0; t < phi_timesteps; t++ ) {
      if ( t > SMOOTH ) {
        gs_mpi();
      }
    }
    free(P);
    free(rhs_fn);
    free(a_x);
    free(a_y);
  }
  MPI_Finalize();
  return(0);
}
Exemple #29
0
template <int dim> void update(MMSP::grid<dim,vector<double> >& grid, int steps)
{
	MMSP::grid<dim,vector<double> > update(grid);

	double dt = 0.01;
	double width = 8.0;

	for (int step=0; step<steps; step++) {
		for (int i=0; i<nodes(grid); i++) {
			vector<int> x = position(grid,i);

			// determine nonzero fields within 
			// the neighborhood of this node
			double S = 0.0;
			vector<int> s(fields(grid),0);
			for (int h=0; h<fields(grid); h++) {
				for (int j=0; j<dim; j++)
					for (int k=-1; k<=1; k++) {
						x[j] += k;
						if (grid(x)[h]>0.0) {
							s[h] = 1;
							x[j] -= k;
							goto next;
						}
						x[j] -= k;
					}
				next: S += s[h];
			}

			// if only one field is nonzero,
			// then copy this node to update
			if (S<2.0) update(i) = grid(i);

			else {
				// compute laplacian of each field
				vector<double> lap = laplacian(grid,i);

				// compute variational derivatives
				vector<double> dFdp(fields(grid),0.0);
				for (int h=0; h<fields(grid); h++)
					if (s[h]>0.0)
						for (int j=h+1; j<fields(grid); j++)
							if (s[j]>0.0) {
								double gamma = energy(h,j);
								double eps = 4.0/acos(-1.0)*sqrt(0.5*gamma*width);
								double w = 4.0*gamma/width;
								dFdp[h] += 0.5*eps*eps*lap[j]+w*grid(i)[j];
								dFdp[j] += 0.5*eps*eps*lap[h]+w*grid(i)[h];
								for (int k=j+1; k<fields(grid); k++)
									if (s[k]>0.0) {
										dFdp[h] += 3.0*grid(i)[j]*grid(i)[k];
										dFdp[j] += 3.0*grid(i)[k]*grid(i)[h];
										dFdp[k] += 3.0*grid(i)[h]*grid(i)[j];
									}
							}

				// compute time derivatives
				vector<double> dpdt(fields(grid),0.0);
				for (int h=0; h<fields(grid); h++)
					if (s[h]>0.0)
						for (int j=h+1; j<fields(grid); j++)
							if (s[j]>0.0) {
								double mu = mobility(h,j);
								dpdt[h] -= mu*(dFdp[h]-dFdp[j]);
								dpdt[j] -= mu*(dFdp[j]-dFdp[h]);
							}

				// compute update values
				double sum = 0.0;
				for (int h=0; h<fields(grid); h++) {
					double value = grid(i)[h]+dt*(2.0/S)*dpdt[h];
					if (value>1.0) value = 1.0;
					if (value<0.0) value = 0.0;
					update(i)[h] = value;
					sum += value;
				}

				// project onto Gibbs simplex
				double rsum = 0.0;
				if (fabs(sum)>0.0) rsum = 1.0/sum;
				for (int h=0; h<fields(grid); h++)
					update(i)[h] *= rsum;
			}
		}
		swap(grid,update);
		ghostswap(grid);
	}
}
      return fvMatrixHolder< Type >( laplacian( ds, field(), name ), Deps( &field ) );
    }
    
    template< class Type, class GType >
    inline fvMatrixHolder< Type > laplacian( const GeometricFieldHolder< GType, fvPatchField, volMesh >& field1, 
					     GeometricFieldHolder< Type, fvPatchField, volMesh >& field2 )
    {
      return fvMatrixHolder< Type >( laplacian( field1(), field2() ), Deps( &field1, &field2 )  );
    }
   
    template< class Type, class GType >
    inline fvMatrixHolder< Type > laplacian( const GeometricFieldHolder< GType, fvPatchField, volMesh >& field1, 
					     GeometricFieldHolder< Type, fvPatchField, volMesh >& field2
					     const word& name )
    {
      return fvMatrixHolder< Type >( laplacian( field1(), field2(), name ), Deps( &field1, &field2 )  );
    }

    template< class Type, class GType >
    inline fvMatrixHolder< Type > laplacian( const GeometricFieldHolder< GType, vsPatchField, surfaceMesh >& field1, 
					     GeometricFieldHolder< Type, fvPatchField, volMesh >& field2 )
    {
      return fvMatrixHolder< Type >( laplacian( field1(), field2() ), Deps( &field1, &field2 )  );
    }
   
    template< class Type, class GType >
    inline fvMatrixHolder< Type > laplacian( const GeometricFieldHolder< GType, vsPatchField, surfaceMesh >& field1, 
					     GeometricFieldHolder< Type, fvPatchField, volMesh >& field2
					     const word& name )
    {
      return fvMatrixHolder< Type >( laplacian( field1(), field2(), name ), Deps( &field1, &field2 )  );