delta_max and fix cabs2
This commit is contained in:
22
src/complex_tools.c
Normal file
22
src/complex_tools.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2017-2023 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "complex_tools.h"
|
||||
|
||||
// magnitude squared
|
||||
double cabs2(_Complex double x){
|
||||
return (__real__ x)*(__real__ x)+(__imag__ x)*(__imag__ x);
|
||||
}
|
23
src/complex_tools.h
Normal file
23
src/complex_tools.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2017-2023 Ian Jauslin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef COMPLEXTOOLS_H
|
||||
#define COMPLEXTOOLS_H
|
||||
|
||||
// magnitude squared
|
||||
double cabs2(_Complex double x);
|
||||
|
||||
#endif
|
21
src/main.c
21
src/main.c
@ -47,6 +47,7 @@ typedef struct nstrophy_parameters {
|
||||
double L;
|
||||
double adaptive_tolerance;
|
||||
double adaptive_factor;
|
||||
double max_delta;
|
||||
double print_freq;
|
||||
int seed;
|
||||
double starting_time;
|
||||
@ -170,16 +171,16 @@ int main (
|
||||
|
||||
// run command
|
||||
if (command==COMMAND_UK){
|
||||
uk(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.final_time, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile);
|
||||
uk(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.final_time, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, parameters.max_delta, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile);
|
||||
}
|
||||
else if(command==COMMAND_ENSTROPHY){
|
||||
// register signal handler to handle aborts
|
||||
signal(SIGINT, sig_handler);
|
||||
signal(SIGTERM, sig_handler);
|
||||
enstrophy(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.final_time, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile, (char*)argv[0], param_str, savefile_str);
|
||||
enstrophy(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.final_time, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, parameters.max_delta, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile, (char*)argv[0], param_str, savefile_str);
|
||||
}
|
||||
else if(command==COMMAND_QUIET){
|
||||
quiet(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.final_time, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, parameters.starting_time, u0, g, parameters.irreversible, parameters.algorithm, nthreads, savefile);
|
||||
quiet(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.final_time, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, parameters.max_delta, parameters.starting_time, u0, g, parameters.irreversible, parameters.algorithm, nthreads, savefile);
|
||||
}
|
||||
else if(command==0){
|
||||
fprintf(stderr, "error: no command specified\n");
|
||||
@ -264,13 +265,13 @@ int print_params(
|
||||
fprintf(file,", algorithm=RK2");
|
||||
break;
|
||||
case ALGORITHM_RKF45:
|
||||
fprintf(file,", algorithm=RKF45, tolerance=%.15e, factor=%.15e",parameters.adaptive_tolerance, parameters.adaptive_factor);
|
||||
fprintf(file,", algorithm=RKF45, tolerance=%.15e",parameters.adaptive_tolerance);
|
||||
break;
|
||||
case ALGORITHM_RKDP54:
|
||||
fprintf(file,", algorithm=RKDP54, tolerance=%.15e, factor=%.15e",parameters.adaptive_tolerance, parameters.adaptive_factor);
|
||||
fprintf(file,", algorithm=RKDP54, tolerance=%.15e",parameters.adaptive_tolerance);
|
||||
break;
|
||||
case ALGORITHM_RKBS32:
|
||||
fprintf(file,", algorithm=RKBS32, tolerance=%.15e, factor=%.15e",parameters.adaptive_tolerance, parameters.adaptive_factor);
|
||||
fprintf(file,", algorithm=RKBS32, tolerance=%.15e",parameters.adaptive_tolerance);
|
||||
break;
|
||||
default:
|
||||
fprintf(file,", algorithm=RK4");
|
||||
@ -397,6 +398,7 @@ int read_params(
|
||||
parameters->L=2*M_PI;
|
||||
parameters->adaptive_tolerance=1e-11;
|
||||
parameters->adaptive_factor=0.9;
|
||||
parameters->max_delta=1e-2;
|
||||
parameters->final_time=100000;
|
||||
parameters->print_freq=1;
|
||||
parameters->starting_time=0;
|
||||
@ -597,6 +599,13 @@ int set_parameter(
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else if (strcmp(lhs,"max_delta")==0){
|
||||
ret=sscanf(rhs,"%lf",&(parameters->max_delta));
|
||||
if(ret!=1){
|
||||
fprintf(stderr, "error: parameter 'max_delta' should be a double\n got '%s'\n",rhs);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else if (strcmp(lhs,"print_freq")==0){
|
||||
ret=sscanf(rhs,"%lf",&(parameters->print_freq));
|
||||
if(ret!=1){
|
||||
|
@ -17,13 +17,12 @@ limitations under the License.
|
||||
#include "constants.cpp"
|
||||
#include "io.h"
|
||||
#include "navier-stokes.h"
|
||||
#include "complex_tools.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CABS2(x) ((__real__ x) * (__real__ x) + (__imag__ x) * (__imag__ x))
|
||||
|
||||
// compute solution as a function of time
|
||||
int uk(
|
||||
int K1,
|
||||
@ -36,6 +35,7 @@ int uk(
|
||||
double L,
|
||||
double adaptive_tolerance,
|
||||
double adaptive_factor,
|
||||
double max_delta,
|
||||
_Complex double* u0,
|
||||
_Complex double* g,
|
||||
bool irreversible,
|
||||
@ -94,7 +94,7 @@ int uk(
|
||||
ns_step_rkf45(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, true);
|
||||
} else if (algorithm==ALGORITHM_RKDP54) {
|
||||
// only compute k1 on the first step
|
||||
ns_step_rkdp54(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, &tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, time==starting_time);
|
||||
ns_step_rkdp54(u, adaptive_tolerance, adaptive_factor, max_delta, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, &tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, time==starting_time);
|
||||
} else if (algorithm==ALGORITHM_RKBS32) {
|
||||
// only compute k1 on the first step
|
||||
ns_step_rkbs32(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, tmp2, tmp3, &tmp4, tmp5, irreversible, time==starting_time);
|
||||
@ -144,6 +144,7 @@ int enstrophy(
|
||||
double L,
|
||||
double adaptive_tolerance,
|
||||
double adaptive_factor,
|
||||
double max_delta,
|
||||
_Complex double* u0,
|
||||
_Complex double* g,
|
||||
bool irreversible,
|
||||
@ -203,7 +204,7 @@ int enstrophy(
|
||||
ns_step_rkf45(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, true);
|
||||
} else if (algorithm==ALGORITHM_RKDP54) {
|
||||
// only compute k1 on the first step
|
||||
ns_step_rkdp54(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, &tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, time==starting_time);
|
||||
ns_step_rkdp54(u, adaptive_tolerance, adaptive_factor, max_delta, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, &tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, time==starting_time);
|
||||
} else if (algorithm==ALGORITHM_RKBS32) {
|
||||
// only compute k1 on the first step
|
||||
ns_step_rkbs32(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, tmp2, tmp3, &tmp4, tmp5, irreversible, time==starting_time);
|
||||
@ -317,6 +318,7 @@ int quiet(
|
||||
double final_time,
|
||||
double nu,
|
||||
double delta,
|
||||
double max_delta,
|
||||
double L,
|
||||
double adaptive_tolerance,
|
||||
double adaptive_factor,
|
||||
@ -361,7 +363,7 @@ int quiet(
|
||||
ns_step_rkf45(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, true);
|
||||
} else if (algorithm==ALGORITHM_RKDP54) {
|
||||
// only compute k1 on the first step
|
||||
ns_step_rkdp54(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, &tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, time==starting_time);
|
||||
ns_step_rkdp54(u, adaptive_tolerance, adaptive_factor, max_delta, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, &tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, irreversible, time==starting_time);
|
||||
} else if (algorithm==ALGORITHM_RKBS32) {
|
||||
// only compute k1 on the first step
|
||||
ns_step_rkbs32(u, adaptive_tolerance, adaptive_factor, K1, K2, N1, N2, nu, &step, &next_step, L, g, fft1, fft2, ifft, &tmp1, tmp2, tmp3, &tmp4, tmp5, irreversible, time==starting_time);
|
||||
@ -856,6 +858,7 @@ int ns_step_rkdp54(
|
||||
_Complex double* u,
|
||||
double tolerance,
|
||||
double factor,
|
||||
double max_delta,
|
||||
int K1,
|
||||
int K2,
|
||||
int N1,
|
||||
@ -946,10 +949,13 @@ int ns_step_rkdp54(
|
||||
for(ky=(kx>0 ? -K2 : 1);ky<=K2;ky++){
|
||||
// difference between 5th order and 4th order
|
||||
// use the norm |u_k|^2k^2 (to get a bound on the error of the enstrophy)
|
||||
err+=(kx*kx+ky*ky)*CABS2((*delta)*(-71./57600*(*k1)[klookup_sym(kx,ky,K2)]+71./16695*k3[klookup_sym(kx,ky,K2)]-71./1920*k4[klookup_sym(kx,ky,K2)]+17253./339200*k5[klookup_sym(kx,ky,K2)]-22./525*k6[klookup_sym(kx,ky,K2)]+1./40*(*k2)[klookup_sym(kx,ky,K2)]));
|
||||
relative+=(kx*kx+ky*ky)*(CABS2(tmp[klookup_sym(kx,ky,K2)]-u[klookup_sym(kx,ky,K2)]));
|
||||
err+=(kx*kx+ky*ky)*cabs2((*delta)*(-71./57600*(*k1)[klookup_sym(kx,ky,K2)]+71./16695*k3[klookup_sym(kx,ky,K2)]-71./1920*k4[klookup_sym(kx,ky,K2)]+17253./339200*k5[klookup_sym(kx,ky,K2)]-22./525*k6[klookup_sym(kx,ky,K2)]+1./40*(*k2)[klookup_sym(kx,ky,K2)]));
|
||||
//relative+=(kx*kx+ky*ky)*(CABS2(tmp[klookup_sym(kx,ky,K2)]-u[klookup_sym(kx,ky,K2)]));
|
||||
relative+=(kx*kx+ky*ky)*(cabs2(u[klookup_sym(kx,ky,K2)]));
|
||||
}
|
||||
}
|
||||
err=sqrt(err);
|
||||
relative=sqrt(relative);
|
||||
|
||||
// compare relative error with tolerance
|
||||
if(err<relative*tolerance){
|
||||
@ -959,8 +965,8 @@ int ns_step_rkdp54(
|
||||
u[klookup_sym(kx,ky,K2)]=tmp[klookup_sym(kx,ky,K2)];
|
||||
}
|
||||
}
|
||||
// next delta to use in future steps
|
||||
*next_delta=(*delta)*pow(relative*tolerance/err,1./5);
|
||||
// next delta to use in future steps (do not exceed max_delta)
|
||||
*next_delta=fmin(max_delta, (*delta)*pow(relative*tolerance/err,1./5));
|
||||
|
||||
// k1 in the next step will be this k4 (first same as last)
|
||||
tmp=*k1;
|
||||
@ -971,7 +977,7 @@ int ns_step_rkdp54(
|
||||
else{
|
||||
*delta=factor*(*delta)*pow(relative*tolerance/err,1./5);
|
||||
// this will reuse the same k1 without re-computing it
|
||||
ns_step_rkdp54(u,tolerance,factor,K1,K2,N1,N2,nu,delta,next_delta,L,g,fft1,fft2,ifft,k1,k2,k3,k4,k5,k6,tmp,irreversible,false);
|
||||
ns_step_rkdp54(u,tolerance,factor,max_delta,K1,K2,N1,N2,nu,delta,next_delta,L,g,fft1,fft2,ifft,k1,k2,k3,k4,k5,k6,tmp,irreversible,false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -33,13 +33,13 @@ typedef struct fft_vects {
|
||||
} fft_vect;
|
||||
|
||||
// compute u_k
|
||||
int uk( int K1, int K2, int N1, int N2, double final_time, double nu, double delta, double L, double adaptive_tolerance, double adaptive_factor, _Complex double* u0, _Complex double* g, bool irreversible, unsigned int algorithm, double print_freq, double starting_time, unsigned int nthreadsl, FILE* savefile);
|
||||
int uk( int K1, int K2, int N1, int N2, double final_time, double nu, double delta, double L, double adaptive_tolerance, double adaptive_factor, double max_delta, _Complex double* u0, _Complex double* g, bool irreversible, unsigned int algorithm, double print_freq, double starting_time, unsigned int nthreadsl, FILE* savefile);
|
||||
|
||||
// compute enstrophy and alpha
|
||||
int enstrophy( int K1, int K2, int N1, int N2, double final_time, double nu, double delta, double L, double adaptive_tolerance, double adaptive_factor, _Complex double* u0, _Complex double* g, bool irreversible, unsigned int algorithm, double print_freq, double starting_time, unsigned int nthreads, FILE* savefile, char* cmd_string, char* params_string, char* savefile_string);
|
||||
int enstrophy( int K1, int K2, int N1, int N2, double final_time, double nu, double delta, double L, double adaptive_tolerance, double adaptive_factor, double max_delta, _Complex double* u0, _Complex double* g, bool irreversible, unsigned int algorithm, double print_freq, double starting_time, unsigned int nthreads, FILE* savefile, char* cmd_string, char* params_string, char* savefile_string);
|
||||
|
||||
// compute solution as a function of time, but do not print anything (useful for debugging)
|
||||
int quiet( int K1, int K2, int N1, int N2, double final_time, double nu, double delta, double L, double adaptive_tolerance, double adaptive_factor, double starting_time, _Complex double* u0, _Complex double* g, bool irreversible, unsigned int algorithm, unsigned int nthreads, FILE* savefile);
|
||||
int quiet( int K1, int K2, int N1, int N2, double final_time, double nu, double delta, double L, double adaptive_tolerance, double adaptive_factor, double max_delta, double starting_time, _Complex double* u0, _Complex double* g, bool irreversible, unsigned int algorithm, unsigned int nthreads, FILE* savefile);
|
||||
|
||||
|
||||
// initialize vectors for computation
|
||||
@ -58,7 +58,7 @@ int ns_step_rk2( _Complex double* u, int K1, int K2, int N1, int N2, double nu,
|
||||
// Runge-Kutta-Fehlberg
|
||||
int ns_step_rkf45( _Complex double* u, double tolerance, double factor, int K1, int K2, int N1, int N2, double nu, double* delta, double* next_delta, double L, _Complex double* g, fft_vect fft1, fft_vect fft2, fft_vect ifft, _Complex double* k1, _Complex double* k2, _Complex double* k3, _Complex double* k4, _Complex double* k5, _Complex double* k6, _Complex double* tmp, bool irreversible, bool compute_k1);
|
||||
// Runge-Kutta-Dromand-Prince
|
||||
int ns_step_rkdp54( _Complex double* u, double tolerance, double factor, int K1, int K2, int N1, int N2, double nu, double* delta, double* next_delta, double L, _Complex double* g, fft_vect fft1, fft_vect fft2, fft_vect ifft, _Complex double** k1, _Complex double** k2, _Complex double* k3, _Complex double* k4, _Complex double* k5, _Complex double* k6, _Complex double* tmp, bool irreversible, bool compute_k1);
|
||||
int ns_step_rkdp54( _Complex double* u, double tolerance, double factor, double max_delta, int K1, int K2, int N1, int N2, double nu, double* delta, double* next_delta, double L, _Complex double* g, fft_vect fft1, fft_vect fft2, fft_vect ifft, _Complex double** k1, _Complex double** k2, _Complex double* k3, _Complex double* k4, _Complex double* k5, _Complex double* k6, _Complex double* tmp, bool irreversible, bool compute_k1);
|
||||
// Runge-Kutta-Bogacki-Shampine
|
||||
int ns_step_rkbs32( _Complex double* u, double tolerance, double factor, int K1, int K2, int N1, int N2, double nu, double* delta, double* next_delta, double L, _Complex double* g, fft_vect fft1, fft_vect fft2, fft_vect ifft, _Complex double** k1, _Complex double* k2, _Complex double* k3, _Complex double** k4, _Complex double* tmp, bool irreversible, bool compute_k1);
|
||||
|
||||
|
Reference in New Issue
Block a user