void cow_fft_reverse(cow_dfield *f, cow_dfield *fkre, cow_dfield *fkim) { int nx = cow_domain_getnumlocalzonesinterior(f->domain, 0); int ny = cow_domain_getnumlocalzonesinterior(f->domain, 1); int nz = cow_domain_getnumlocalzonesinterior(f->domain, 2); int ng = cow_domain_getguard(f->domain); int ntot = nx * ny * nz; int I0[3] = { ng, ng, ng }; int I1[3] = { nx + ng, ny + ng, nz + ng }; double *out = (double*) malloc(ntot * sizeof(double) * f->n_members); double *inr = (double*) malloc(ntot * sizeof(double) * f->n_members); double *ini = (double*) malloc(ntot * sizeof(double) * f->n_members); cow_dfield_extract(fkre, I0, I1, inr); cow_dfield_extract(fkim, I0, I1, ini); for (int m=0; m<f->n_members; ++m) { FFT_DATA *fk = (FFT_DATA*) malloc(ntot * sizeof(FFT_DATA)); for (int n=0; n<ntot; ++n) { fk[n][0] = inr[f->n_members*n + m]; fk[n][1] = ini[f->n_members*n + m]; } double *fx = _rev(f->domain, fk); for (int n=0; n<ntot; ++n) { out[f->n_members*n + m] = fx[n]; } free(fx); free(fk); } cow_dfield_replace(f, I0, I1, out); free(out); free(inr); free(ini); }
Node* _rev(Node *head) { if(head->next == NULL) { newHead = head; return newHead; } else { _rev(head->next)->next = head; head->next = NULL; return head; } }
void _rev(const char * str, int len, int p, char * rv) { if (p == len - 1) { rv[0] = str[p]; return; } rv[len - 1 - p] = str[p]; _rev(str, len, p + 1, rv); }
void cow_fft_helmholtzdecomp(cow_dfield *f, int mode) { #if (COW_FFTW) if (!f->committed) return; if (f->n_members != 3) { printf("[%s] error: need a 3-component field for pspecvectorfield", MODULE); return; } clock_t start = clock(); int nx = cow_domain_getnumlocalzonesinterior(f->domain, 0); int ny = cow_domain_getnumlocalzonesinterior(f->domain, 1); int nz = cow_domain_getnumlocalzonesinterior(f->domain, 2); int ng = cow_domain_getguard(f->domain); int ntot = nx * ny * nz; int I0[3] = { ng, ng, ng }; int I1[3] = { nx + ng, ny + ng, nz + ng }; double *input = (double*) malloc(3 * ntot * sizeof(double)); cow_dfield_extract(f, I0, I1, input); FFT_DATA *gx = _fwd(f->domain, input, 0, 3); // start, stride FFT_DATA *gy = _fwd(f->domain, input, 1, 3); FFT_DATA *gz = _fwd(f->domain, input, 2, 3); free(input); FFT_DATA *gx_p = (FFT_DATA*) malloc(ntot * sizeof(FFT_DATA)); FFT_DATA *gy_p = (FFT_DATA*) malloc(ntot * sizeof(FFT_DATA)); FFT_DATA *gz_p = (FFT_DATA*) malloc(ntot * sizeof(FFT_DATA)); for (int i=0; i<nx; ++i) { for (int j=0; j<ny; ++j) { for (int k=0; k<nz; ++k) { int m = i*ny*nz + j*nz + k; FFT_DATA gdotk; double khat[3]; khat_at(f->domain, i, j, k, khat); gdotk[0] = gx[m][0] * khat[0] + gy[m][0] * khat[1] + gz[m][0] * khat[2]; gdotk[1] = gx[m][1] * khat[0] + gy[m][1] * khat[1] + gz[m][1] * khat[2]; switch (mode) { case COW_PROJECT_OUT_DIV: gx_p[m][0] = gx[m][0] - gdotk[0] * khat[0]; gx_p[m][1] = gx[m][1] - gdotk[1] * khat[0]; gy_p[m][0] = gy[m][0] - gdotk[0] * khat[1]; gy_p[m][1] = gy[m][1] - gdotk[1] * khat[1]; gz_p[m][0] = gz[m][0] - gdotk[0] * khat[2]; gz_p[m][1] = gz[m][1] - gdotk[1] * khat[2]; break; case COW_PROJECT_OUT_CURL: gx_p[m][0] = gdotk[0] * khat[0]; gx_p[m][1] = gdotk[1] * khat[0]; gy_p[m][0] = gdotk[0] * khat[1]; gy_p[m][1] = gdotk[1] * khat[1]; gz_p[m][0] = gdotk[0] * khat[2]; gz_p[m][1] = gdotk[1] * khat[2]; break; default: break; } } } } free(gx); free(gy); free(gz); double *fx_p = _rev(f->domain, gx_p); double *fy_p = _rev(f->domain, gy_p); double *fz_p = _rev(f->domain, gz_p); free(gx_p); free(gy_p); free(gz_p); double *res = (double*) malloc(3 * ntot * sizeof(double)); for (int i=0; i<ntot; ++i) { res[3*i + 0] = fx_p[i]; res[3*i + 1] = fy_p[i]; res[3*i + 2] = fz_p[i]; } free(fx_p); free(fy_p); free(fz_p); cow_dfield_replace(f, I0, I1, res); cow_dfield_syncguard(f); free(res); printf("[%s] %s took %3.2f seconds\n", MODULE, __FUNCTION__, (double) (clock() - start) / CLOCKS_PER_SEC); #endif // COW_FFTW }
Node* Reverse(Node *head) { _rev(head); return newHead; }