Nstrophy/src/main.c

806 lines
21 KiB
C
Raw Normal View History

2023-05-10 19:33:29 -04:00
/*
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.
*/
2022-05-18 09:57:06 +02:00
#define VERSION "0.1"
2018-01-11 22:48:14 +00:00
2023-04-12 15:23:35 -04:00
#include <signal.h>
2018-01-11 22:48:14 +00:00
#include <string.h>
#include <stdlib.h>
2022-05-27 16:09:17 -04:00
#include <errno.h>
2023-04-26 11:27:03 -04:00
#include "constants.cpp"
2022-05-18 09:57:06 +02:00
#include "driving.h"
2022-05-26 15:05:30 -04:00
#include "init.h"
#include "int_tools.h"
2023-04-26 11:27:03 -04:00
#include "navier-stokes.h"
2023-04-12 19:05:01 -04:00
2022-05-26 14:25:45 -04:00
// structure to store parameters, to make it easier to pass parameters to CLI functions
typedef struct nstrophy_parameters {
2023-04-05 22:41:19 -04:00
double init_en; // initial value for the energy for ins and enstrophy for rns
2023-04-05 20:33:38 -04:00
bool irreversible;
2022-05-26 14:25:45 -04:00
int K1;
int K2;
int N1;
int N2;
double final_time;
2022-05-26 14:25:45 -04:00
double nu;
double delta;
double L;
2023-05-15 20:29:06 -04:00
double adaptive_tolerance;
double adaptive_factor;
2023-06-13 18:45:19 -04:00
double max_delta;
2023-06-13 23:56:35 -04:00
unsigned int adaptive_norm;
double print_freq;
2022-05-26 15:05:30 -04:00
int seed;
2023-05-15 20:29:06 -04:00
double starting_time;
unsigned int driving;
unsigned int init;
2023-04-26 11:27:03 -04:00
unsigned int algorithm;
FILE* initfile;
2023-04-24 12:22:29 -04:00
FILE* drivingfile;
2022-05-26 14:25:45 -04:00
} nstrophy_parameters;
2018-01-11 22:48:14 +00:00
// usage message
int print_usage();
// print parameters
2023-04-24 12:22:29 -04:00
int print_params(nstrophy_parameters parameters, char* initfile_str, char* drivingfile_str, FILE* file);
2022-05-18 09:57:06 +02:00
2018-01-11 22:48:14 +00:00
// read command line arguments
int read_args(int argc, const char* argv[], char** params, unsigned int* command, unsigned int* nthreads, char** savefile_str);
2023-04-24 12:22:29 -04:00
int read_params(char* param_str, nstrophy_parameters* parameters, char** initfile_str, char** drivingfile_str);
int set_parameter(char* lhs, char* rhs, nstrophy_parameters* parameters, bool* setN1, bool* setN2, char** initfile_str, char** drivingfile_str);
2022-05-18 09:57:06 +02:00
// set driving force
_Complex double* set_driving(nstrophy_parameters parameters);
2022-05-26 15:05:30 -04:00
// set initial condition
2023-05-15 20:29:06 -04:00
_Complex double* set_init(nstrophy_parameters* parameters);
2022-05-26 15:05:30 -04:00
2023-04-12 15:23:35 -04:00
// signal handler
void sig_handler (int signo);
// global variable to handle interrupts
volatile bool g_abort = false;
// signal handler
void sig_handler (int signo){
2023-05-26 17:37:51 -04:00
if (signo == SIGINT || signo == SIGTERM){
2023-04-12 15:23:35 -04:00
g_abort = true;
}
}
2022-05-18 09:57:06 +02:00
int main (
int argc,
const char* argv[]
){
2022-05-26 14:25:45 -04:00
char* param_str=NULL;
nstrophy_parameters parameters;
2018-01-11 22:48:14 +00:00
int ret;
unsigned int command;
2022-05-18 23:52:01 +02:00
unsigned int nthreads=1;
2022-05-26 15:05:30 -04:00
_Complex double* u0;
_Complex double *g;
2022-05-27 16:09:17 -04:00
char* savefile_str=NULL;
char* initfile_str=NULL;
2023-04-24 12:22:29 -04:00
char* drivingfile_str=NULL;
2022-05-27 16:09:17 -04:00
FILE* savefile=NULL;
2018-01-11 22:48:14 +00:00
2022-05-18 09:57:06 +02:00
command=0;
2018-01-11 22:48:14 +00:00
// read command line arguments
ret=read_args(argc, argv, &param_str, &command, &nthreads, &savefile_str);
2022-05-18 09:57:06 +02:00
if(ret<0){
return(-1);
}
2022-05-26 15:05:30 -04:00
2022-05-18 09:57:06 +02:00
// read params
2023-04-24 12:22:29 -04:00
ret=read_params(param_str, &parameters, &initfile_str, &drivingfile_str);
2018-01-11 22:48:14 +00:00
if(ret<0){
return(-1);
}
2022-05-26 15:05:30 -04:00
2022-05-27 16:09:17 -04:00
// open initfile
if(initfile_str!=NULL){
parameters.initfile=fopen(initfile_str,"r");
if(parameters.initfile==NULL){
2022-05-27 16:09:17 -04:00
fprintf(stderr,"Error opening file '%s' for reading: %s\n", initfile_str, strerror(errno));
return(-1);
}
}
2023-04-24 12:22:29 -04:00
// open drivingfile
if(drivingfile_str!=NULL){
parameters.drivingfile=fopen(drivingfile_str,"r");
if(parameters.drivingfile==NULL){
fprintf(stderr,"Error opening file '%s' for reading: %s\n", drivingfile_str, strerror(errno));
return(-1);
}
}
2022-05-27 16:09:17 -04:00
2022-05-18 09:57:06 +02:00
// set driving force
g=set_driving(parameters);
2022-05-26 15:05:30 -04:00
// set initial condition
2023-05-15 20:29:06 -04:00
u0=set_init(&parameters);
2022-05-27 16:09:17 -04:00
// close initfile (do this early, so that it is possible to use the same file for init and save)
if (parameters.initfile!=NULL){
fclose(parameters.initfile);
2022-05-27 16:09:17 -04:00
}
2023-04-24 12:22:29 -04:00
// close drivingfile
if (parameters.drivingfile!=NULL){
fclose(parameters.drivingfile);
}
2022-05-27 16:09:17 -04:00
// open savefile (do this after closing init file)
if(savefile_str!=NULL){
savefile=fopen(savefile_str,"w");
if(savefile==NULL){
fprintf(stderr,"Error opening file '%s' for writing: %s\n", savefile_str, strerror(errno));
return(-1);
}
}
2022-05-26 15:05:30 -04:00
// print parameters
2023-04-24 12:22:29 -04:00
print_params(parameters, initfile_str, drivingfile_str, stderr);
print_params(parameters, initfile_str, drivingfile_str, stdout);
2023-04-12 19:05:01 -04:00
// free initfile_str
if(initfile_str!=NULL){
free(initfile_str);
}
2023-04-24 12:22:29 -04:00
// free drivingfile_str
if(drivingfile_str!=NULL){
free(drivingfile_str);
}
2023-04-12 19:05:01 -04:00
2022-05-18 09:57:06 +02:00
// run command
if (command==COMMAND_UK){
2023-06-13 23:56:35 -04:00
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, parameters.adaptive_norm, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile);
2022-05-18 09:57:06 +02:00
}
else if(command==COMMAND_ENSTROPHY){
2023-04-12 15:23:35 -04:00
// register signal handler to handle aborts
signal(SIGINT, sig_handler);
2023-05-26 17:37:51 -04:00
signal(SIGTERM, sig_handler);
2023-06-13 23:56:35 -04:00
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, parameters.adaptive_norm, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile, (char*)argv[0], param_str, savefile_str);
2022-05-18 09:57:06 +02:00
}
2022-05-18 22:22:42 +02:00
else if(command==COMMAND_QUIET){
2023-06-13 23:56:35 -04:00
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.adaptive_norm, parameters.starting_time, u0, g, parameters.irreversible, parameters.algorithm, nthreads, savefile);
2022-05-18 22:22:42 +02:00
}
2022-05-18 09:57:06 +02:00
else if(command==0){
fprintf(stderr, "error: no command specified\n");
print_usage();
2018-01-11 22:48:14 +00:00
}
free(g);
2022-05-26 15:05:30 -04:00
free(u0);
2022-05-27 16:09:17 -04:00
// close savefile
if (savefile!=NULL){
fclose(savefile);
}
2018-01-11 22:48:14 +00:00
return(0);
}
// usage message
int print_usage(){
fprintf(stderr, "usage:\n nstrophy [-t nthreads] [-p parameters] [-s savefile] <command>\n\n");
2018-01-11 22:48:14 +00:00
return(0);
}
// print parameters
int print_params(
nstrophy_parameters parameters,
2022-05-27 16:09:17 -04:00
char* initfile_str,
2023-04-24 12:22:29 -04:00
char* drivingfile_str,
FILE* file
){
2023-04-05 22:41:19 -04:00
fprintf(file,"# ");
if (parameters.irreversible){
fprintf(file,"equation=irreversible");
} else {
fprintf(file,"equation=reversible");
}
fprintf(file,", K1=%d, K2=%d, N1=%d, N2=%d, nu=%.15e, delta=%.15e, L=%.15e, init_en=%.15e", parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.nu, parameters.delta, parameters.L, parameters.init_en);
switch(parameters.driving){
case DRIVING_TEST:
fprintf(file,", driving=test");
break;
case DRIVING_ZERO:
fprintf(file,", driving=zero");
break;
2023-04-24 12:22:29 -04:00
case DRIVING_FILE:
fprintf(file,", driving=file:%s", drivingfile_str);
break;
case DRIVING_FILE_TXT:
fprintf(file,", driving=file_txt:%s", drivingfile_str);
break;
default:
fprintf(file,", driving=test");
break;
}
switch(parameters.init){
case INIT_RANDOM:
fprintf(file,", init=random");
break;
case INIT_GAUSSIAN:
fprintf(file,", init=gaussian");
break;
2022-05-27 16:09:17 -04:00
case INIT_FILE:
fprintf(file,", init=file:%s", initfile_str);
break;
case INIT_FILE_TXT:
fprintf(file,", init=file_txt:%s", initfile_str);
break;
default:
fprintf(file,", init=gaussian");
break;
}
2023-04-26 11:27:03 -04:00
switch(parameters.algorithm){
case ALGORITHM_RK4:
fprintf(file,", algorithm=RK4");
break;
case ALGORITHM_RK2:
fprintf(file,", algorithm=RK2");
break;
2023-05-15 20:29:06 -04:00
case ALGORITHM_RKF45:
2023-06-13 18:45:19 -04:00
fprintf(file,", algorithm=RKF45, tolerance=%.15e",parameters.adaptive_tolerance);
2023-05-15 20:29:06 -04:00
break;
2023-05-17 17:41:00 -04:00
case ALGORITHM_RKDP54:
2023-06-13 18:45:19 -04:00
fprintf(file,", algorithm=RKDP54, tolerance=%.15e",parameters.adaptive_tolerance);
2023-05-17 17:41:00 -04:00
break;
2023-05-17 16:59:15 -04:00
case ALGORITHM_RKBS32:
2023-06-13 18:45:19 -04:00
fprintf(file,", algorithm=RKBS32, tolerance=%.15e",parameters.adaptive_tolerance);
2023-05-17 16:47:15 -04:00
break;
2023-04-26 11:27:03 -04:00
default:
fprintf(file,", algorithm=RK4");
break;
}
2023-06-13 23:56:35 -04:00
if(parameters.algorithm>ALGORITHM_ADAPTIVE_THRESHOLD){
switch(parameters.adaptive_norm){
case NORM_L1:
fprintf(file,", norm=L1");
break;
case NORM_k3:
fprintf(file,", norm=k3");
break;
case NORM_k32:
fprintf(file,", norm=k32");
break;
case NORM_ENSTROPHY:
fprintf(file,", norm=enstrophy");
break;
}
}
fprintf(file,"\n");
return 0;
}
2023-04-12 19:05:01 -04:00
2018-01-11 22:48:14 +00:00
// read command line arguments
2022-05-18 09:57:06 +02:00
#define CP_FLAG_PARAMS 1
#define CP_FLAG_NTHREADS 2
#define CP_FLAG_SAVEFILE 3
2022-05-18 09:57:06 +02:00
int read_args(
int argc,
const char* argv[],
char** params,
2022-05-18 23:52:01 +02:00
unsigned int* command,
2022-05-27 16:09:17 -04:00
unsigned int* nthreads,
char** savefile_str
2022-05-18 09:57:06 +02:00
){
2018-01-11 22:48:14 +00:00
int i;
2022-05-18 23:52:01 +02:00
int ret;
2018-01-11 22:48:14 +00:00
// pointers
char* ptr;
// flag that indicates what argument is being read
int flag=0;
// loop over arguments
for(i=1;i<argc;i++){
// flag
if(argv[i][0]=='-'){
for(ptr=((char*)argv[i])+1;*ptr!='\0';ptr++){
switch(*ptr){
2022-05-18 09:57:06 +02:00
case 'p':
flag=CP_FLAG_PARAMS;
2018-01-11 22:48:14 +00:00
break;
2022-05-18 23:52:01 +02:00
case 't':
flag=CP_FLAG_NTHREADS;
break;
2022-05-27 16:09:17 -04:00
case 's':
flag=CP_FLAG_SAVEFILE;
break;
2018-01-11 22:48:14 +00:00
default:
fprintf(stderr, "unrecognized option '-%c'\n", *ptr);
print_usage();
return(-1);
break;
}
}
}
2022-05-18 09:57:06 +02:00
// params
else if(flag==CP_FLAG_PARAMS){
*params=(char*)argv[i];
2018-01-11 22:48:14 +00:00
flag=0;
}
2022-05-18 23:52:01 +02:00
// nthreads
else if(flag==CP_FLAG_NTHREADS){
ret=sscanf(argv[i],"%u",nthreads);
if(ret!=1){
fprintf(stderr, "error: '-t' should be followed by an unsigned integer\n got '%s'\n",argv[i]);
return(-1);
}
flag=0;
}
2022-05-27 16:09:17 -04:00
// savefile
else if(flag==CP_FLAG_SAVEFILE){
*savefile_str=(char*)argv[i];
flag=0;
}
2018-01-11 22:48:14 +00:00
// computation to run
else{
2022-05-18 09:57:06 +02:00
if(strcmp(argv[i], "uk")==0){
*command=COMMAND_UK;
}
else if(strcmp(argv[i], "enstrophy")==0){
*command=COMMAND_ENSTROPHY;
2018-01-11 22:48:14 +00:00
}
2022-05-18 22:22:42 +02:00
else if(strcmp(argv[i], "quiet")==0){
*command=COMMAND_QUIET;
}
2018-01-11 22:48:14 +00:00
else{
2022-05-18 09:57:06 +02:00
fprintf(stderr, "error: unrecognized command: '%s'\n",argv[i]);
2018-01-11 22:48:14 +00:00
return(-1);
}
flag=0;
}
}
return(0);
}
2022-05-18 09:57:06 +02:00
// read parameters string
int read_params(
2022-05-26 14:25:45 -04:00
char* param_str,
nstrophy_parameters* parameters,
2023-04-24 12:22:29 -04:00
char** initfile_str,
char** drivingfile_str
2022-05-18 09:57:06 +02:00
){
int ret;
// pointer in params
char* ptr;
// buffer and associated pointer
char *buffer_lhs, *lhs_ptr;
char *buffer_rhs, *rhs_ptr;
// whether N was set explicitly
bool setN1=false;
bool setN2=false;
// whether lhs (false is rhs)
bool lhs=true;
// defaults
2023-04-05 22:41:19 -04:00
parameters->init_en=1.54511597324389e+02;
2023-04-05 20:33:38 -04:00
parameters->irreversible=true;
2022-05-26 14:25:45 -04:00
parameters->K1=16;
parameters->K2=parameters->K1;
2022-05-18 09:57:06 +02:00
//delta=2^-13
2022-05-26 14:25:45 -04:00
parameters->delta=0.0001220703125;
2022-05-18 09:57:06 +02:00
//nu=2^-11
2022-05-26 14:25:45 -04:00
parameters->nu=0.00048828125;
parameters->L=2*M_PI;
2023-05-15 20:29:06 -04:00
parameters->adaptive_tolerance=1e-11;
parameters->adaptive_factor=0.9;
2023-06-13 18:45:19 -04:00
parameters->max_delta=1e-2;
2023-06-13 23:56:35 -04:00
parameters->adaptive_norm=NORM_L1;
parameters->final_time=100000;
parameters->print_freq=1;
2022-05-27 17:06:38 -04:00
parameters->starting_time=0;
2022-05-26 15:05:30 -04:00
parameters->seed=17;
parameters->driving=DRIVING_TEST;
2023-04-24 12:22:29 -04:00
parameters->drivingfile=NULL;
parameters->init=INIT_GAUSSIAN;
parameters->initfile=NULL;
2023-04-26 11:27:03 -04:00
parameters->algorithm=ALGORITHM_RK4;
2022-05-18 09:57:06 +02:00
2022-05-26 14:25:45 -04:00
if (param_str!=NULL){
2022-05-18 09:57:06 +02:00
// init
2022-05-26 14:25:45 -04:00
buffer_lhs=calloc(sizeof(char),strlen(param_str));
2022-05-18 09:57:06 +02:00
lhs_ptr=buffer_lhs;
*lhs_ptr='\0';
2022-05-26 14:25:45 -04:00
buffer_rhs=calloc(sizeof(char),strlen(param_str));
2022-05-18 09:57:06 +02:00
rhs_ptr=buffer_rhs;
*rhs_ptr='\0';
2018-01-11 22:48:14 +00:00
2022-05-26 14:25:45 -04:00
for(ptr=param_str;*ptr!='\0';ptr++){
2022-05-18 09:57:06 +02:00
switch(*ptr){
case '=':
// reset buffer
rhs_ptr=buffer_rhs;
*rhs_ptr='\0';
lhs=false;
break;
case ';':
//set parameter
ret=set_parameter(buffer_lhs, buffer_rhs, parameters, &setN1, &setN2, initfile_str, drivingfile_str);
2022-05-18 09:57:06 +02:00
if(ret<0){
return ret;
}
// reset buffer
lhs_ptr=buffer_lhs;
*lhs_ptr='\0';
lhs=true;
break;
default:
// add to buffer
if (lhs){
*lhs_ptr=*ptr;
lhs_ptr++;
*lhs_ptr='\0';
}
else{
*rhs_ptr=*ptr;
rhs_ptr++;
*rhs_ptr='\0';
}
break;
}
}
2018-01-11 22:48:14 +00:00
2022-05-18 09:57:06 +02:00
// set last param
2022-05-26 14:25:45 -04:00
if (*param_str!='\0'){
ret=set_parameter(buffer_lhs, buffer_rhs, parameters, &setN1, &setN2, initfile_str, drivingfile_str);
2022-05-18 09:57:06 +02:00
if(ret<0){
return ret;
}
}
2018-01-11 22:48:14 +00:00
2022-05-18 09:57:06 +02:00
// free vects
free(buffer_lhs);
free(buffer_rhs);
}
2018-02-19 16:00:07 +00:00
// if N not set explicitly, set it to the smallest power of 2 that is >3*K+1 (the fft is faster on vectors whose length is a power of 2)
2022-05-18 09:57:06 +02:00
if (!setN1){
parameters->N1=smallest_pow2(3*(parameters->K1));
2018-02-19 16:00:07 +00:00
}
2022-05-18 09:57:06 +02:00
if (!setN2){
parameters->N2=smallest_pow2(3*(parameters->K2));
2018-02-19 16:00:07 +00:00
}
2022-05-18 09:57:06 +02:00
return(0);
}
// set a parameter from the parameter string
int set_parameter(
char* lhs,
char* rhs,
2022-05-26 14:25:45 -04:00
nstrophy_parameters* parameters,
2022-05-18 09:57:06 +02:00
bool* setN1,
2023-04-12 14:37:02 -04:00
bool* setN2,
2023-04-24 12:22:29 -04:00
char** initfile_str,
char** drivingfile_str
2022-05-18 09:57:06 +02:00
){
int ret;
2023-04-05 20:33:38 -04:00
if (strcmp(lhs,"equation")==0){
if (strcmp(rhs,"irreversible")==0){
parameters->irreversible=true;
}
else if (strcmp(rhs,"reversible")==0){
parameters->irreversible=false;
}
else {
fprintf(stderr, "error: 'equation' should be 'irreversible' or 'reversible'\n got '%s'\n",rhs);
return(-1);
}
}
2023-04-05 22:41:19 -04:00
else if (strcmp(lhs,"init_en")==0){
ret=sscanf(rhs,"%lf",&(parameters->init_en));
if(ret!=1){
fprintf(stderr, "error: parameter 'init_en' should be a double\n got '%s'\n",rhs);
return(-1);
}
}
2023-04-05 20:33:38 -04:00
else if (strcmp(lhs,"K1")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%d",&(parameters->K1));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'K1' should be an integer\n got '%s'\n",rhs);
return(-1);
}
2018-02-19 16:00:07 +00:00
}
2022-05-18 09:57:06 +02:00
else if (strcmp(lhs,"K2")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%d",&(parameters->K2));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'K2' should be an integer\n got '%s'\n",rhs);
return(-1);
2018-02-19 16:00:07 +00:00
}
}
2022-05-18 09:57:06 +02:00
else if (strcmp(lhs,"K")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%d",&(parameters->K1));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'K' should be an integer\n got '%s'\n",rhs);
return(-1);
2018-02-19 16:00:07 +00:00
}
2022-05-26 14:25:45 -04:00
parameters->K2=parameters->K1;
2018-02-19 16:00:07 +00:00
}
2022-05-18 09:57:06 +02:00
else if (strcmp(lhs,"N1")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%d",&(parameters->N1));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'N1' should be an integer\n got '%s'\n",rhs);
return(-1);
2018-02-19 16:00:07 +00:00
}
2022-05-18 09:57:06 +02:00
*setN1=true;
2018-02-19 16:00:07 +00:00
}
2022-05-18 09:57:06 +02:00
else if (strcmp(lhs,"N2")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%d",&(parameters->N2));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'N2' should be an integer\n got '%s'\n",rhs);
return(-1);
2018-01-11 22:48:14 +00:00
}
2022-05-18 09:57:06 +02:00
*setN2=true;
2018-01-11 22:48:14 +00:00
}
2022-05-18 09:57:06 +02:00
else if (strcmp(lhs,"N")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%d",&(parameters->N1));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'N' should be an integer\n got '%s'\n",rhs);
return(-1);
2022-05-17 14:31:22 +02:00
}
2022-05-26 14:25:45 -04:00
parameters->N2=parameters->N1;
2022-05-18 09:57:06 +02:00
*setN1=true;
*setN2=true;
2022-05-17 14:31:22 +02:00
}
else if (strcmp(lhs,"final_time")==0){
ret=sscanf(rhs,"%lf",&(parameters->final_time));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'final_time' should be a double\n got '%s'\n",rhs);
2022-05-18 09:57:06 +02:00
return(-1);
2018-01-11 22:48:14 +00:00
}
}
2022-05-18 09:57:06 +02:00
else if (strcmp(lhs,"nu")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%lf",&(parameters->nu));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'nu' should be a double\n got '%s'\n",rhs);
return(-1);
2018-01-11 22:48:14 +00:00
}
2022-05-18 09:57:06 +02:00
}
else if (strcmp(lhs,"delta")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%lf",&(parameters->delta));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'delta' should be a double\n got '%s'\n",rhs);
return(-1);
2018-01-11 22:48:14 +00:00
}
2022-05-18 09:57:06 +02:00
}
2022-05-25 11:12:02 -04:00
else if (strcmp(lhs,"L")==0){
2022-05-26 14:25:45 -04:00
ret=sscanf(rhs,"%lf",&(parameters->L));
2022-05-25 11:12:02 -04:00
if(ret!=1){
fprintf(stderr, "error: parameter 'L' should be a double\n got '%s'\n",rhs);
return(-1);
}
}
2023-05-15 20:29:06 -04:00
else if (strcmp(lhs,"adaptive_tolerance")==0){
ret=sscanf(rhs,"%lf",&(parameters->adaptive_tolerance));
if(ret!=1){
fprintf(stderr, "error: parameter 'adaptive_tolerance' should be a double\n got '%s'\n",rhs);
return(-1);
}
}
else if (strcmp(lhs,"adaptive_factor")==0){
ret=sscanf(rhs,"%lf",&(parameters->adaptive_factor));
if(ret!=1){
fprintf(stderr, "error: parameter 'adaptive_factor' should be a double\n got '%s'\n",rhs);
return(-1);
}
}
2023-06-13 18:45:19 -04:00
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);
}
}
2023-06-13 23:56:35 -04:00
else if (strcmp(lhs,"adaptive_norm")==0){
if (strcmp(rhs,"L1")==0){
parameters->adaptive_norm=NORM_L1;
}
else if (strcmp(rhs,"k3")==0){
parameters->adaptive_norm=NORM_k3;
}
else if (strcmp(rhs,"k32")==0){
parameters->adaptive_norm=NORM_k32;
}
else if (strcmp(rhs,"enstrophy")==0){
parameters->adaptive_norm=NORM_ENSTROPHY;
}
else{
fprintf(stderr, "error: unrecognized adaptive_norm '%s'\n",rhs);
return(-1);
}
}
2022-05-18 09:57:06 +02:00
else if (strcmp(lhs,"print_freq")==0){
ret=sscanf(rhs,"%lf",&(parameters->print_freq));
2022-05-18 09:57:06 +02:00
if(ret!=1){
fprintf(stderr, "error: parameter 'print_freq' should be a double\n got '%s'\n",rhs);
2022-05-18 09:57:06 +02:00
return(-1);
2018-01-11 22:48:14 +00:00
}
}
2022-05-26 15:05:30 -04:00
else if (strcmp(lhs,"random_seed")==0){
ret=sscanf(rhs,"%d",&(parameters->seed));
if(ret!=1){
fprintf(stderr, "error: parameter 'random_seed' should be an integer\n got '%s'\n",rhs);
return(-1);
}
}
2022-05-27 17:06:38 -04:00
else if (strcmp(lhs,"starting_time")==0){
2023-05-15 20:29:06 -04:00
ret=sscanf(rhs,"%lf",&(parameters->starting_time));
2022-05-27 17:06:38 -04:00
if(ret!=1){
2023-05-15 20:29:06 -04:00
fprintf(stderr, "error: parameter 'starting_time' should be a double\n got '%s'\n",rhs);
2022-05-27 17:06:38 -04:00
return(-1);
}
}
else if (strcmp(lhs,"driving")==0){
if (strcmp(rhs,"zero")==0){
parameters->driving=DRIVING_ZERO;
}
else if (strcmp(rhs,"test")==0){
parameters->driving=DRIVING_TEST;
}
2023-04-24 12:22:29 -04:00
// matches any argument that starts with 'file:'
else if (strncmp(rhs,"file:",5)==0){
parameters->driving=DRIVING_FILE;
*drivingfile_str=calloc(sizeof(char), strlen(rhs)-5+1);
strcpy(*drivingfile_str, rhs+5);
}
// matches any argument that starts with 'file_txt:'
else if (strncmp(rhs,"file_txt:",9)==0){
parameters->driving=DRIVING_FILE_TXT;
*drivingfile_str=calloc(sizeof(char), strlen(rhs)-9+1);
strcpy(*drivingfile_str, rhs+9);
}
else{
fprintf(stderr, "error: unrecognized driving force '%s'\n",rhs);
return(-1);
}
}
// initial condition
else if (strcmp(lhs,"init")==0){
if (strcmp(rhs,"random")==0){
parameters->init=INIT_RANDOM;
}
else if (strcmp(rhs,"gaussian")==0){
parameters->init=INIT_GAUSSIAN;
}
// matches any argument that starts with 'file:'
else if (strncmp(rhs,"file:",5)==0){
parameters->init=INIT_FILE;
2023-04-14 15:11:55 -04:00
*initfile_str=calloc(sizeof(char), strlen(rhs)-5+1);
2023-04-12 19:05:01 -04:00
strcpy(*initfile_str, rhs+5);
}
// matches any argument that starts with 'file_txt:'
else if (strncmp(rhs,"file_txt:",9)==0){
parameters->init=INIT_FILE_TXT;
*initfile_str=calloc(sizeof(char), strlen(rhs)-9+1);
strcpy(*initfile_str, rhs+9);
}
else{
fprintf(stderr, "error: unrecognized initial condition '%s'\n",rhs);
return(-1);
}
}
2023-04-26 11:27:03 -04:00
// algorithm
else if (strcmp(lhs,"algorithm")==0){
if (strcmp(rhs,"RK4")==0){
parameters->algorithm=ALGORITHM_RK4;
}
else if (strcmp(rhs,"RK2")==0){
parameters->algorithm=ALGORITHM_RK2;
}
2023-05-15 20:29:06 -04:00
else if (strcmp(rhs,"RKF45")==0){
parameters->algorithm=ALGORITHM_RKF45;
}
2023-05-17 17:41:00 -04:00
else if (strcmp(rhs,"RKDP54")==0){
parameters->algorithm=ALGORITHM_RKDP54;
}
2023-05-17 16:59:15 -04:00
else if (strcmp(rhs,"RKBS32")==0){
parameters->algorithm=ALGORITHM_RKBS32;
2023-05-17 16:47:15 -04:00
}
2023-04-26 11:27:03 -04:00
else{
fprintf(stderr, "error: unrecognized algorithm '%s'\n",rhs);
return(-1);
}
}
2022-05-18 09:57:06 +02:00
else{
fprintf(stderr, "error: unrecognized parameter '%s'\n",lhs);
return(-1);
}
2018-01-11 22:48:14 +00:00
return(0);
}
2022-05-26 15:05:30 -04:00
// set driving force
_Complex double* set_driving(
nstrophy_parameters parameters
){
2023-04-25 17:51:14 -04:00
_Complex double* g=calloc(sizeof(_Complex double),parameters.K1*(2*parameters.K2+1)+parameters.K2);
switch(parameters.driving){
case DRIVING_ZERO:
g_zero(g, parameters.K1, parameters.K2);
break;
case DRIVING_TEST:
g_test(g, parameters.K1, parameters.K2);
break;
2023-04-24 12:22:29 -04:00
case DRIVING_FILE:
init_file_bin(g, parameters.K1, parameters.K2, parameters.drivingfile);
break;
case DRIVING_FILE_TXT:
init_file_txt(g, parameters.K1, parameters.K2, parameters.drivingfile);
break;
default:
g_test(g, parameters.K1, parameters.K2);
break;
}
return g;
}
2022-05-26 15:05:30 -04:00
// set initial condition
_Complex double* set_init(
2023-05-15 20:29:06 -04:00
nstrophy_parameters* parameters
2022-05-26 15:05:30 -04:00
){
2023-05-15 20:29:06 -04:00
_Complex double* u0=calloc(sizeof(_Complex double),parameters->K1*(2*parameters->K2+1)+parameters->K2);
2022-05-26 15:05:30 -04:00
2023-05-15 20:29:06 -04:00
switch(parameters->init){
2022-05-26 15:05:30 -04:00
case INIT_RANDOM:
2023-05-15 20:29:06 -04:00
init_random(u0, parameters->init_en, parameters->K1, parameters->K2, parameters->L, parameters->seed, parameters->irreversible);
2022-05-26 15:05:30 -04:00
break;
case INIT_GAUSSIAN:
2023-05-15 20:29:06 -04:00
init_gaussian(u0, parameters->init_en, parameters->K1, parameters->K2, parameters->L, parameters->irreversible);
2022-05-26 15:05:30 -04:00
break;
2022-05-27 16:09:17 -04:00
case INIT_FILE:
2023-05-15 20:29:06 -04:00
init_file_bin(u0, parameters->K1, parameters->K2, parameters->initfile);
// read start time
fread(&(parameters->starting_time), sizeof(double), 1, parameters->initfile);
2023-05-15 20:29:06 -04:00
if(parameters->algorithm>ALGORITHM_ADAPTIVE_THRESHOLD){
// read delta
fread(&(parameters->delta), sizeof(double), 1, parameters->initfile);
}
break;
case INIT_FILE_TXT:
2023-05-15 20:29:06 -04:00
init_file_txt(u0, parameters->K1, parameters->K2, parameters->initfile);
2022-05-27 16:09:17 -04:00
break;
2022-05-26 15:05:30 -04:00
default:
2023-05-15 20:29:06 -04:00
init_gaussian(u0, parameters->init_en, parameters->K1, parameters->K2, parameters->L, parameters->irreversible);
2022-05-26 15:05:30 -04:00
break;
}
return u0;
}