From f21ab0d79594c23ead5b98a31ad6b6fb82d8b88a Mon Sep 17 00:00:00 2001 From: Ian Jauslin Date: Wed, 18 May 2022 09:57:06 +0200 Subject: Rewrite: change cli arguments handling --- src/navier-stokes.c | 408 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 340 insertions(+), 68 deletions(-) (limited to 'src/navier-stokes.c') diff --git a/src/navier-stokes.c b/src/navier-stokes.c index 303392d..ab4803c 100644 --- a/src/navier-stokes.c +++ b/src/navier-stokes.c @@ -1,63 +1,311 @@ #include "navier-stokes.h" #include +#include #define M_PI 3.14159265358979323846 +// compute solution as a function of time +int uk( + int K1, + int K2, + int N1, + int N2, + unsigned int nsteps, + double nu, + double delta, + _Complex double (*g)(int,int), + unsigned int print_freq +){ + _Complex double* u; + _Complex double* tmp1; + _Complex double* tmp2; + _Complex double* tmp3; + unsigned int t; + fft_vect fft1; + fft_vect fft2; + fft_vect ifft; + int kx,ky; + + ns_init_tmps(&u, &tmp1, &tmp2, &tmp3, &fft1, &fft2, &ifft, K1, K2, N1, N2); + ns_init_u(u, K1, K2); + + // iterate + for(t=0;t0){ + avg=avg-(avg-alpha)/t; + } + + if(t>0 && t%print_freq==0){ + fprintf(stderr,"% .15e % .15e % .15e % .15e % .15e\n",t*delta, __real__ avg, __imag__ avg, __real__ alpha, __imag__ alpha); + printf("% .15e % .15e % .15e % .15e % .15e\n",t*delta, __real__ avg, __imag__ avg, __real__ alpha, __imag__ alpha); + } + } + + ns_free_tmps(u, tmp1, tmp2, tmp3, fft1, fft2, ifft); + return(0); +} + + +// initialize vectors for computation +int ns_init_tmps( + _Complex double ** u, + _Complex double ** tmp1, + _Complex double ** tmp2, + _Complex double ** tmp3, + fft_vect* fft1, + fft_vect* fft2, + fft_vect* ifft, + int K1, + int K2, + int N1, + int N2 +){ + // velocity field + *u=calloc(sizeof(_Complex double),(2*K1+1)*(2*K2+1)); + + // allocate tmp vectors for computation + *tmp1=calloc(sizeof(_Complex double),(2*K1+1)*(2*K2+1)); + *tmp2=calloc(sizeof(_Complex double),(2*K1+1)*(2*K2+1)); + *tmp3=calloc(sizeof(_Complex double),(2*K1+1)*(2*K2+1)); + + // prepare vectors for fft + fft1->fft=fftw_malloc(sizeof(fftw_complex)*N1*N2); + fft1->fft_plan=fftw_plan_dft_2d(N1,N2, fft1->fft, fft1->fft, FFTW_FORWARD, FFTW_MEASURE); + fft2->fft=fftw_malloc(sizeof(fftw_complex)*N1*N2); + fft2->fft_plan=fftw_plan_dft_2d(N1,N2, fft2->fft, fft2->fft, FFTW_FORWARD, FFTW_MEASURE); + ifft->fft=fftw_malloc(sizeof(fftw_complex)*N1*N2); + ifft->fft_plan=fftw_plan_dft_2d(N1,N2, ifft->fft, ifft->fft, FFTW_BACKWARD, FFTW_MEASURE); + + return 0; +} + +// release vectors +int ns_free_tmps( + _Complex double* u, + _Complex double* tmp1, + _Complex double* tmp2, + _Complex double* tmp3, + fft_vect fft1, + fft_vect fft2, + fft_vect ifft +){ + // free memory + fftw_destroy_plan(fft1.fft_plan); + fftw_destroy_plan(fft2.fft_plan); + fftw_destroy_plan(ifft.fft_plan); + fftw_free(fft1.fft); + fftw_free(fft2.fft); + fftw_free(ifft.fft); + + fftw_cleanup(); + + free(tmp3); + free(tmp2); + free(tmp1); + + free(u); + + return 0; +} + + + +// initial value +int ns_init_u( + _Complex double* u, + int K1, + int K2 +){ + int kx,ky; + /* + double rescale; + + srand(17); + + // random init (set half, then the other half are the conjugates) + for(ky=0;ky<=K2;ky++){ + u[klookup(0,ky,2*K1+1,2*K2+1)]=(-RAND_MAX*0.5+rand())*1.0/RAND_MAX+(-RAND_MAX*0.5+rand())*1.0/RAND_MAX*I; + } + for(kx=1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + u[klookup(kx,ky,2*K1+1,2*K2+1)]=(-RAND_MAX*0.5+rand())*1.0/RAND_MAX+(-RAND_MAX*0.5+rand())*1.0/RAND_MAX*I; + } + } + // conjugates + for(ky=-K2;ky<=-1;ky++){ + u[klookup(0,ky,2*K1+1,2*K2+1)]=conj(u[klookup(0,-ky,2*K1+1,2*K2+1)]); + } + for(kx=-K1;kx<=-1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + u[klookup(kx,ky,2*K1+1,2*K2+1)]=conj(u[klookup(-kx,-ky,2*K1+1,2*K2+1)]); + } + } + + // rescale: 1/k decay + rescale=0; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + rescale=rescale+((__real__ u[klookup(kx,ky,2*K1+1,2*K2+1)])*(__real__ u[klookup(kx,ky,2*K1+1,2*K2+1)])+(__imag__ u[klookup(kx,ky,2*K1+1,2*K2+1)])*(__imag__ u[klookup(kx,ky,2*K1+1,2*K2+1)]))*(kx*kx+ky*ky); + } + } + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + u[klookup(kx,ky,2*K1+1,2*K2+1)]=u[klookup(kx,ky,2*K1+1,2*K2+1)]*sqrt(155.1/rescale); + } + } + */ + + + /* + // constant init + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + u[klookup(kx,ky,2*K1+1,2*K2+1)]=1.; + } + } + */ + + // exponentially decaying init + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + u[klookup(kx,ky,2*K1+1,2*K2+1)]=exp(-sqrt(kx*kx+ky*ky)); + } + } + + return 0; +} + + // next time step for Irreversible Navier-Stokes equation -int ins_step(_Complex double* u, ns_params params, fft_vects vects, _Complex double* tmp1, _Complex double* tmp2, _Complex double* tmp3){ +int ins_step( + _Complex double* u, + int K1, + int K2, + int N1, + int N2, + double nu, + double delta, + _Complex double (*g)(int,int), + fft_vect fft1, + fft_vect fft2, + fft_vect ifft, + _Complex double* tmp1, + _Complex double* tmp2, + _Complex double* tmp3 +){ int kx,ky; // k1 - ins_rhs(tmp1, u, params, vects); + ins_rhs(tmp1, u, K1, K2, N1, N2, nu, g, fft1, fft2, ifft); // add to output - for(kx=-params.K;kx<=params.K;kx++){ - for(ky=-params.K;ky<=params.K;ky++){ - tmp3[KLOOKUP(kx,ky,params.S)]=u[KLOOKUP(kx,ky,params.S)]+params.h/6*tmp1[KLOOKUP(kx,ky,params.S)]; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + tmp3[klookup(kx,ky,2*K1+1,2*K2+1)]=u[klookup(kx,ky,2*K1+1,2*K2+1)]+delta/6*tmp1[klookup(kx,ky,2*K1+1,2*K2+1)]; } } // u+h*k1/2 - for(kx=-params.K;kx<=params.K;kx++){ - for(ky=-params.K;ky<=params.K;ky++){ - tmp2[KLOOKUP(kx,ky,params.S)]=u[KLOOKUP(kx,ky,params.S)]+params.h/2*tmp1[KLOOKUP(kx,ky,params.S)]; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + tmp2[klookup(kx,ky,2*K1+1,2*K2+1)]=u[klookup(kx,ky,2*K1+1,2*K2+1)]+delta/2*tmp1[klookup(kx,ky,2*K1+1,2*K2+1)]; } } // k2 - ins_rhs(tmp1, tmp2, params, vects); + ins_rhs(tmp1, tmp2, K1, K2, N1, N2, nu, g, fft1, fft2, ifft); // add to output - for(kx=-params.K;kx<=params.K;kx++){ - for(ky=-params.K;ky<=params.K;ky++){ - tmp3[KLOOKUP(kx,ky,params.S)]+=params.h/3*tmp1[KLOOKUP(kx,ky,params.S)]; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + tmp3[klookup(kx,ky,2*K1+1,2*K2+1)]+=delta/3*tmp1[klookup(kx,ky,2*K1+1,2*K2+1)]; } } // u+h*k2/2 - for(kx=-params.K;kx<=params.K;kx++){ - for(ky=-params.K;ky<=params.K;ky++){ - tmp2[KLOOKUP(kx,ky,params.S)]=u[KLOOKUP(kx,ky,params.S)]+params.h/2*tmp1[KLOOKUP(kx,ky,params.S)]; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + tmp2[klookup(kx,ky,2*K1+1,2*K2+1)]=u[klookup(kx,ky,2*K1+1,2*K2+1)]+delta/2*tmp1[klookup(kx,ky,2*K1+1,2*K2+1)]; } } // k3 - ins_rhs(tmp1, tmp2, params, vects); + ins_rhs(tmp1, tmp2, K1, K2, N1, N2, nu, g, fft1, fft2, ifft); // add to output - for(kx=-params.K;kx<=params.K;kx++){ - for(ky=-params.K;ky<=params.K;ky++){ - tmp3[KLOOKUP(kx,ky,params.S)]+=params.h/3*tmp1[KLOOKUP(kx,ky,params.S)]; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + tmp3[klookup(kx,ky,2*K1+1,2*K2+1)]+=delta/3*tmp1[klookup(kx,ky,2*K1+1,2*K2+1)]; } } // u+h*k3 - for(kx=-params.K;kx<=params.K;kx++){ - for(ky=-params.K;ky<=params.K;ky++){ - tmp2[KLOOKUP(kx,ky,params.S)]=u[KLOOKUP(kx,ky,params.S)]+params.h*tmp1[KLOOKUP(kx,ky,params.S)]; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + tmp2[klookup(kx,ky,2*K1+1,2*K2+1)]=u[klookup(kx,ky,2*K1+1,2*K2+1)]+delta*tmp1[klookup(kx,ky,2*K1+1,2*K2+1)]; } } // k4 - ins_rhs(tmp1, tmp2, params, vects); + ins_rhs(tmp1, tmp2, K1, K2, N1, N2, nu, g, fft1, fft2, ifft); // add to output - for(kx=-params.K;kx<=params.K;kx++){ - for(ky=-params.K;ky<=params.K;ky++){ - u[KLOOKUP(kx,ky,params.S)]=tmp3[KLOOKUP(kx,ky,params.S)]+params.h/6*tmp1[KLOOKUP(kx,ky,params.S)]; + for(kx=-K1;kx<=K1;kx++){ + for(ky=-K2;ky<=K2;ky++){ + u[klookup(kx,ky,2*K1+1,2*K2+1)]=tmp3[klookup(kx,ky,2*K1+1,2*K2+1)]+delta/6*tmp1[klookup(kx,ky,2*K1+1,2*K2+1)]; } } @@ -65,74 +313,82 @@ int ins_step(_Complex double* u, ns_params params, fft_vects vects, _Complex dou } // right side of Irreversible Navier-Stokes equation -int ins_rhs(_Complex double* out, _Complex double* u, ns_params params, fft_vects vects){ +int ins_rhs( + _Complex double* out, + _Complex double* u, + int K1, + int K2, + int N1, + int N2, + double nu, + _Complex double (*g)(int,int), + fft_vect fft1, + fft_vect fft2, + fft_vect ifft +){ int kx,ky; + int i; // F(px/|p|*u)*F(qy*|q|*u) // init to 0 - for(kx=0; kx=0 ? kx : S1+kx)*S2 + (ky>=0 ? ky : S2+ky); +} -- cgit v1.2.3-54-g00ecf