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); }
void ParticleSet::randomizeFromSource (ParticleSet &src) { SpeciesSet& srcSpSet(src.getSpeciesSet()); SpeciesSet& spSet(getSpeciesSet()); int srcChargeIndx = srcSpSet.addAttribute("charge"); int srcMemberIndx = srcSpSet.addAttribute("membersize"); int ChargeIndex = spSet.addAttribute("charge"); int MemberIndx = spSet.addAttribute("membersize"); int Nsrc = src.getTotalNum(); int Nptcl = getTotalNum(); int NumSpecies = spSet.TotalNum; int NumSrcSpecies = srcSpSet.TotalNum; //Store information about charges and number of each species vector<int> Zat, Zspec, NofSpecies, NofSrcSpecies, CurElec; Zat.resize(Nsrc); Zspec.resize(NumSrcSpecies); NofSpecies.resize(NumSpecies); CurElec.resize(NumSpecies); NofSrcSpecies.resize(NumSrcSpecies); for(int spec=0; spec<NumSrcSpecies; spec++) { Zspec[spec] = (int)round(srcSpSet(srcChargeIndx,spec)); NofSrcSpecies[spec] = (int)round(srcSpSet(srcMemberIndx,spec)); } for(int spec=0; spec<NumSpecies; spec++) { NofSpecies[spec] = (int)round(spSet(MemberIndx,spec)); CurElec[spec] = first(spec); } int totQ=0; for(int iat=0; iat<Nsrc; iat++) totQ+=Zat[iat] = Zspec[src.GroupID[iat]]; app_log() << " Total ion charge = " << totQ << endl; totQ -= Nptcl; app_log() << " Total system charge = " << totQ << endl; // Now, loop over ions, attaching electrons to them to neutralize // charge int spToken = 0; // This is decremented when we run out of electrons in each species int spLeft = NumSpecies; vector<PosType> gaussRand (Nptcl); makeGaussRandom (gaussRand); for (int iat=0; iat<Nsrc; iat++) { // Loop over electrons to add, selecting round-robin from the // electron species int z = Zat[iat]; while (z > 0 && spLeft) { int sp = spToken++ % NumSpecies; if (NofSpecies[sp]) { NofSpecies[sp]--; z--; int elec = CurElec[sp]++; app_log() << " Assigning " << (sp ? "down" : "up ") << " electron " << elec << " to ion " << iat << " with charge " << z << endl; double radius = 0.5* std::sqrt((double)Zat[iat]); R[elec] = src.R[iat] + radius * gaussRand[elec]; } else spLeft--; } } // Assign remaining electrons int ion=0; for (int sp=0; sp < NumSpecies; sp++) { for (int ie=0; ie<NofSpecies[sp]; ie++) { int iat = ion++ % Nsrc; double radius = std::sqrt((double)Zat[iat]); int elec = CurElec[sp]++; R[elec] = src.R[iat] + radius * gaussRand[elec]; } } }