Пример #1
0
const std::vector<T> linearDiffusion(const std::vector<T> & signal,
                                     T time,
                                     T step_size = 0.25,
                                     BorderInterpolation interpolation_method = CONTINUED)
{
    /* The general formulation of a nonlinear diffusion is
     *
     *      d/dt f(x, t) = div grad f(x, t) = laplace f(x, t)
     *
     * In the 1-dimensional case, the divergence and the gradient simplify to
     * an ordinary differentiation. Thus we get
     *
     *      d/dt f(x, t) = d^2/dx^2 f(x, t)
     *
     * The diffusion equation can be easily solved by using the following
     * approximation
     *
     *      d/dt f(x, t) = [f(x, t+h) - f(x, t) ] / h
     *
     * where h is the step size. With this, we get
     *
     *      d/dt f(x, t+h) = f(x, t) + h *  d^2/dx^2 f(x, t)
     *
     * Iterating until t + n * h = time, yields the solution.
     */


    // If time == 0 return the unchanged signal.

    if (Tools::isZero(time))
    {
        return signal;
    }

    // Modify step_size such, that after n iterations, time is really reached.

    step_size = time / std::ceil(time / step_size);

    // Compute the diffusion.

    const unsigned N = signal.size();
    std::vector<T> B(N);

    std::vector<T> diffused_signal = signal;

    for (T t = step_size; t <= time; t += step_size)
    {
        const std::vector<T> & derivative = secondDerivative(diffused_signal, interpolation_method);

        for (unsigned i = 0; i < signal.size(); ++i)
        {
            diffused_signal[i] = diffused_signal[i] + step_size * derivative[i];
        }
    }

    return diffused_signal;
}
Пример #2
0
// A function to solver Burgers equation
void Solver_FFTW::burgersSolver_FFTW(){
	/*===============================================
		get V at t=0
	===============================================*/
	for(int i = 0; i < numOfXGrid; i++){
		for(int j = 0; j < numOfYGrid; j++){
			temp_Velocity[i*numOfYGrid+j] = v[i][j];
		}
	}
	fftw_execute(plan_r2c);
	for(int i = 0; i < numOfXGrid; i++){
		for(int j = 0; j < numOfYGrid/2 + 1; j++){
			V[i][j][0] = temp_U[i*(numOfYGrid/2+1) + j][0];
			V[i][j][1] = temp_U[i*(numOfYGrid/2+1) + j][1];
		}
	}
	fftw_execute(plan_c2r);
	for(int i = 0; i < numOfXGrid; i++){
		for(int j = 0; j < numOfYGrid; j++){
			v[i][j] = temp_Velocity[i*numOfYGrid + j]/(numOfXGrid*numOfYGrid);
		}
	}
	/*===============================================
		get W at t=0
	===============================================*/
	for(int i = 0; i < numOfXGrid; i++){
		for(int j = 0; j < numOfYGrid; j++){
			temp_Velocity[i*numOfYGrid+j] = w[i][j];
		}
	}
	fftw_execute(plan_r2c);
	for(int i = 0; i < numOfXGrid; i++){
		for(int j = 0; j < numOfYGrid/2 + 1; j++){
			W[i][j][0] = temp_U[i*(numOfYGrid/2+1)+j][0];
			W[i][j][1] = temp_U[i*(numOfYGrid/2+1)+j][1];
		}
	}
	fftw_execute(plan_c2r);
	for(int i = 0; i < numOfXGrid; i++){
		for(int j = 0; j < numOfYGrid; j++){
			w[i][j] = temp_Velocity[i*numOfYGrid+j]/(numOfXGrid*numOfYGrid);
		}
	}

	Output *out = new Output(numOfXGrid,numOfYGrid,v,w,0,initE,_VELOCITY);
	/*==============================================
	Time step iteration
	==============================================*/

	for(long int t = 0; t < TIME_N;t++){

		//First step, get V and W
		for(int i = 0; i < numOfXGrid; i++){
			for(int j = 0; j < numOfYGrid; j++){
				temp_Velocity[i*numOfYGrid+j] = v[i][j];
			}
		}
		fftw_execute(plan_r2c);
		for(int i = 0; i < numOfXGrid; i++){
			for(int j = 0; j < numOfYGrid/2 + 1; j++){
				V[i][j][0] = temp_U[i*(numOfYGrid/2+1)+j][0];
				V[i][j][1] = temp_U[i*(numOfYGrid/2+1)+j][1];
			}
		}
		for(int i = 0; i < numOfXGrid; i++){
			for(int j = 0; j < numOfYGrid; j++){
				temp_Velocity[i*numOfYGrid+j] = w[i][j];
			}
		}
		fftw_execute(plan_r2c);
		for(int i = 0; i < numOfXGrid; i++){
			for(int j = 0; j < numOfYGrid/2 + 1; j++){
				W[i][j][0] = temp_U[i*(numOfYGrid/2+1)+j][0];
				W[i][j][1] = temp_U[i*(numOfYGrid/2+1)+j][1];
			}
		}

		/*=============================
		Second step: get v_x,v_y,w_x,w_y
		/*=============================*/
		firstDerivative();
		/*
		if(t == 0){
			Output* out_1 = new Output(numOfXGrid,numOfYGrid,v_x,v_y,0,initE,_DERIVATIVEv);
			Output* out_2 = new Output(numOfYGrid,numOfYGrid,w_x,w_y,0,initE,_DERIVATIVEw);
		}
		*/

		/*=============================
		Third step: get v_x_x,v_y_y,w_x_x,w_y_y
		=============================*/
		secondDerivative();
		/*
		if(t == 0){
			Output* out_1 = new Output(numOfXGrid,numOfYGrid,v_x_x,v_y_y,0,initE,_DDERIVATIVEv);
			Output* out_2 = new Output(numOfYGrid,numOfYGrid,w_x_x,w_y_y,0,initE,_DDERIVATIVEw);
		}
		*/
		
		/*=============================
		Forth step: sampling force
		=============================*/
		samplingForce();
		
		/*=============================
		Last step: Adams-Bashforth method
		=============================*/
		adamsMethod(t);
		
		
		//calculate energy in some steps, this energy is not rescaled
		if((t+1)%ENERGY_OUTPUT == 0){
			double E = calculateE();
			energy << log((t+1)*TIME_STEP) + log(sqrt(initE*(numOfYGrid-1)/(numOfXGrid-1))/(numOfXGrid-1)) << "\t";
			energy << log(E) - log(initE*(numOfYGrid-1)/(numOfXGrid-1))<< endl;
		}

		//generate output in some steps, this output is rescaled, see output.cpp
		if((t+1)%GENERATE_OUTPUT == 0){
			Output* out_1 = new Output(numOfXGrid,numOfYGrid,v,w,t+1,initE,_VELOCITY);
			Output* out_2 = new Output(numOfXGrid,numOfYGrid,v_x,v_y,t+1,initE,_DERIVATIVEv);
			Output* out_3 = new Output(numOfYGrid,numOfYGrid,w_x,w_y,t+1,initE,_DERIVATIVEw);
			cout << "t=" << t+1 << "_completed" << endl;	
		}

	}

	//empty the memory
	energy.close();
	fftw_destroy_plan(plan_c2r);
	fftw_destroy_plan(plan_r2c);
	fftw_destroy_plan(plan_firstD);
	fftw_destroy_plan(plan_secondD);
	return;
}