예제 #1
0
파일: FFT.c 프로젝트: JohnXinhua/UVa
complex multiply_complex(complex *a, complex *b) {
	return init_complex(a->x * b->x - a->y * b->y, a->x * b->y+ a->y * b->x);
}
예제 #2
0
파일: FFT.c 프로젝트: JohnXinhua/UVa
complex substract_complex(complex *a, complex *b) {
	return init_complex(a->x - b->x, a->y - b->y);
}
예제 #3
0
void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
                    float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
                    short do_jacobian, int seed)
{
	int i, j, ii;

	BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);

	o->_M = M;
	o->_N = N;
	o->_V = V;
	o->_l = l;
	o->_A = A;
	o->_w = w;
	o->_damp_reflections = 1.0f - damp;
	o->_wind_alignment = alignment;
	o->_depth = depth;
	o->_Lx = Lx;
	o->_Lz = Lz;
	o->_wx = cos(w);
	o->_wz = -sin(w); /* wave direction */
	o->_L = V * V / GRAVITY;  /* largest wave for a given velocity V */
	o->time = time;

	o->_do_disp_y = do_height_field;
	o->_do_normals = do_normals;
	o->_do_chop = do_chop;
	o->_do_jacobian = do_jacobian;

	o->_k = (float *) MEM_mallocN(M * (1 + N / 2) * sizeof(float), "ocean_k");
	o->_h0 = (fftw_complex *) MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0");
	o->_h0_minus = (fftw_complex *) MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0_minus");
	o->_kx = (float *) MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
	o->_kz = (float *) MEM_mallocN(o->_N * sizeof(float), "ocean_kz");

	/* make this robust in the face of erroneous usage */
	if (o->_Lx == 0.0f)
		o->_Lx = 0.001f;

	if (o->_Lz == 0.0f)
		o->_Lz = 0.001f;

	/* the +ve components and DC */
	for (i = 0; i <= o->_M / 2; ++i)
		o->_kx[i] = 2.0f * (float)M_PI * i / o->_Lx;

	/* the -ve components */
	for (i = o->_M - 1, ii = 0; i > o->_M / 2; --i, ++ii)
		o->_kx[i] = -2.0f * (float)M_PI * ii / o->_Lx;

	/* the +ve components and DC */
	for (i = 0; i <= o->_N / 2; ++i)
		o->_kz[i] = 2.0f * (float)M_PI * i / o->_Lz;

	/* the -ve components */
	for (i = o->_N - 1, ii = 0; i > o->_N / 2; --i, ++ii)
		o->_kz[i] = -2.0f * (float)M_PI * ii / o->_Lz;

	/* pre-calculate the k matrix */
	for (i = 0; i < o->_M; ++i)
		for (j = 0; j <= o->_N / 2; ++j)
			o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);

	/*srand(seed);*/
	BLI_srand(seed);

	for (i = 0; i < o->_M; ++i) {
		for (j = 0; j < o->_N; ++j) {
			float r1 = gaussRand();
			float r2 = gaussRand();

			fftw_complex r1r2;
			init_complex(r1r2, r1, r2);
			mul_complex_f(o->_h0[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, o->_kx[i], o->_kz[j]) / 2.0f)));
			mul_complex_f(o->_h0_minus[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, -o->_kx[i], -o->_kz[j]) / 2.0f)));
		}
	}

	o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
	o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");

	if (o->_do_disp_y) {
		o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
		o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
	}

	if (o->_do_normals) {
		o->_fft_in_nx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nx");
		o->_fft_in_nz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nz");

		o->_N_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
		/* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */
		o->_N_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");

		o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE);
		o->_N_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nz, o->_N_z, FFTW_ESTIMATE);
	}

	if (o->_do_chop) {
		o->_fft_in_x = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
		o->_fft_in_z = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");

		o->_disp_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
		o->_disp_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");

		o->_disp_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_x, o->_disp_x, FFTW_ESTIMATE);
		o->_disp_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_z, o->_disp_z, FFTW_ESTIMATE);
	}
	if (o->_do_jacobian) {
		o->_fft_in_jxx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
		                                             "ocean_fft_in_jxx");
		o->_fft_in_jzz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
		                                             "ocean_fft_in_jzz");
		o->_fft_in_jxz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
		                                             "ocean_fft_in_jxz");

		o->_Jxx = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
		o->_Jzz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
		o->_Jxz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");

		o->_Jxx_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxx, o->_Jxx, FFTW_ESTIMATE);
		o->_Jzz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jzz, o->_Jzz, FFTW_ESTIMATE);
		o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
	}

	BLI_rw_mutex_unlock(&o->oceanmutex);

	set_height_normalize_factor(o);

}
예제 #4
0
파일: FFT.c 프로젝트: JohnXinhua/UVa
complex add_complex(complex *a, complex *b) {
	return init_complex(a->x + b->x, a->y + b->y);
}
예제 #5
0
void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount)
{
	int i, j;

	scale *= o->normalize_factor;

	BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);

	/* compute a new htilda */
#pragma omp parallel for private(i, j)
	for (i = 0; i < o->_M; ++i) {
		/* note the <= _N/2 here, see the fftw doco about the mechanics of the complex->real fft storage */
		for (j = 0; j <= o->_N / 2; ++j) {
			fftw_complex exp_param1;
			fftw_complex exp_param2;
			fftw_complex conj_param;


			init_complex(exp_param1, 0.0, omega(o->_k[i * (1 + o->_N / 2) + j], o->_depth) * t);
			init_complex(exp_param2, 0.0, -omega(o->_k[i * (1 + o->_N / 2) + j], o->_depth) * t);
			exp_complex(exp_param1, exp_param1);
			exp_complex(exp_param2, exp_param2);
			conj_complex(conj_param, o->_h0_minus[i * o->_N + j]);

			mul_complex_c(exp_param1, o->_h0[i * o->_N + j], exp_param1);
			mul_complex_c(exp_param2, conj_param, exp_param2);

			add_comlex_c(o->_htilda[i * (1 + o->_N / 2) + j], exp_param1, exp_param2);
			mul_complex_f(o->_fft_in[i * (1 + o->_N / 2) + j], o->_htilda[i * (1 + o->_N / 2) + j], scale);
		}
	}

#pragma omp parallel sections private(i, j)
	{

#pragma omp section
		{
			if (o->_do_disp_y) {
				/* y displacement */
				fftw_execute(o->_disp_y_plan);
			}
		} /* section 1 */

#pragma omp section
		{
			if (o->_do_chop) {
				/* x displacement */
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j <= o->_N / 2; ++j) {
						fftw_complex mul_param;
						fftw_complex minus_i;

						init_complex(minus_i, 0.0, -1.0);
						init_complex(mul_param, -scale, 0);
						mul_complex_f(mul_param, mul_param, chop_amount);
						mul_complex_c(mul_param, mul_param, minus_i);
						mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
						mul_complex_f(mul_param, mul_param,
						              ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
						               0.0f :
						               o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
						init_complex(o->_fft_in_x[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
					}
				}
				fftw_execute(o->_disp_x_plan);
			}
		} /* section 2 */

#pragma omp section
		{
			if (o->_do_chop) {
				/* z displacement */
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j <= o->_N / 2; ++j) {
						fftw_complex mul_param;
						fftw_complex minus_i;

						init_complex(minus_i, 0.0, -1.0);
						init_complex(mul_param, -scale, 0);
						mul_complex_f(mul_param, mul_param, chop_amount);
						mul_complex_c(mul_param, mul_param, minus_i);
						mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
						mul_complex_f(mul_param, mul_param,
						              ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
						               0.0f :
						               o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
						init_complex(o->_fft_in_z[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
					}
				}
				fftw_execute(o->_disp_z_plan);
			}
		} /* section 3 */

#pragma omp section
		{
			if (o->_do_jacobian) {
				/* Jxx */
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j <= o->_N / 2; ++j) {
						fftw_complex mul_param;

						/* init_complex(mul_param, -scale, 0); */
						init_complex(mul_param, -1, 0);

						mul_complex_f(mul_param, mul_param, chop_amount);
						mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
						mul_complex_f(mul_param, mul_param,
						              ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
						               0.0f :
						               o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
						init_complex(o->_fft_in_jxx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
					}
				}
				fftw_execute(o->_Jxx_plan);

				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j < o->_N; ++j) {
						o->_Jxx[i * o->_N + j] += 1.0;
					}
				}
			}
		} /* section 4 */

#pragma omp section
		{
			if (o->_do_jacobian) {
				/* Jzz */
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j <= o->_N / 2; ++j) {
						fftw_complex mul_param;

						/* init_complex(mul_param, -scale, 0); */
						init_complex(mul_param, -1, 0);

						mul_complex_f(mul_param, mul_param, chop_amount);
						mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
						mul_complex_f(mul_param, mul_param,
						              ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
						               0.0f :
						               o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
						init_complex(o->_fft_in_jzz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
					}
				}
				fftw_execute(o->_Jzz_plan);
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j < o->_N; ++j) {
						o->_Jzz[i * o->_N + j] += 1.0;
					}
				}
			}
		} /* section 5 */

#pragma omp section
		{
			if (o->_do_jacobian) {
				/* Jxz */
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j <= o->_N / 2; ++j) {
						fftw_complex mul_param;

						/* init_complex(mul_param, -scale, 0); */
						init_complex(mul_param, -1, 0);

						mul_complex_f(mul_param, mul_param, chop_amount);
						mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
						mul_complex_f(mul_param, mul_param,
						              ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
						               0.0f :
						               o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
						init_complex(o->_fft_in_jxz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
					}
				}
				fftw_execute(o->_Jxz_plan);
			}
		} /* section 6 */

#pragma omp section
		{
			/* fft normals */
			if (o->_do_normals) {
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j <= o->_N / 2; ++j) {
						fftw_complex mul_param;

						init_complex(mul_param, 0.0, -1.0);
						mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
						mul_complex_f(mul_param, mul_param, o->_kx[i]);
						init_complex(o->_fft_in_nx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
					}
				}
				fftw_execute(o->_N_x_plan);

			}
		} /* section 7 */

#pragma omp section
		{
			if (o->_do_normals) {
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j <= o->_N / 2; ++j) {
						fftw_complex mul_param;

						init_complex(mul_param, 0.0, -1.0);
						mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
						mul_complex_f(mul_param, mul_param, o->_kz[i]);
						init_complex(o->_fft_in_nz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
					}
				}
				fftw_execute(o->_N_z_plan);

#if 0
				for (i = 0; i < o->_M; ++i) {
					for (j = 0; j < o->_N; ++j) {
						o->_N_y[i * o->_N + j] = 1.0f / scale;
					}
				}
				(MEM01)
#endif
				o->_N_y = 1.0f / scale;
			}
		} /* section 8 */

	} /* omp sections */

	BLI_rw_mutex_unlock(&o->oceanmutex);
}