RKF45 algorithm
This commit is contained in:
		
							
								
								
									
										86
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								src/main.c
									
									
									
									
									
								
							@@ -46,9 +46,12 @@ typedef struct nstrophy_parameters {
 | 
			
		||||
  double nu;
 | 
			
		||||
  double delta;
 | 
			
		||||
  double L;
 | 
			
		||||
  double adaptive_tolerance;
 | 
			
		||||
  double adaptive_factor;
 | 
			
		||||
  uint64_t print_freq;
 | 
			
		||||
  int seed;
 | 
			
		||||
  uint64_t starting_time;
 | 
			
		||||
  uint64_t starting_step;
 | 
			
		||||
  double starting_time;
 | 
			
		||||
  unsigned int driving;
 | 
			
		||||
  unsigned int init;
 | 
			
		||||
  unsigned int algorithm;
 | 
			
		||||
@@ -64,12 +67,12 @@ int print_params(nstrophy_parameters parameters, char* initfile_str, char* drivi
 | 
			
		||||
// read command line arguments
 | 
			
		||||
int read_args(int argc, const char* argv[], char** params, unsigned int* command, unsigned int* nthreads, char** savefile_str);
 | 
			
		||||
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);
 | 
			
		||||
int set_parameter(char* lhs, char* rhs, nstrophy_parameters* parameters, bool* setN1, bool* setN2, bool* set_starting_time, char** initfile_str, char** drivingfile_str);
 | 
			
		||||
 | 
			
		||||
// set driving force
 | 
			
		||||
_Complex double* set_driving(nstrophy_parameters parameters);
 | 
			
		||||
// set initial condition
 | 
			
		||||
_Complex double* set_init(nstrophy_parameters parameters);
 | 
			
		||||
_Complex double* set_init(nstrophy_parameters* parameters);
 | 
			
		||||
 | 
			
		||||
// signal handler
 | 
			
		||||
void sig_handler (int signo);
 | 
			
		||||
@@ -134,7 +137,7 @@ int main (
 | 
			
		||||
  // set driving force
 | 
			
		||||
  g=set_driving(parameters);
 | 
			
		||||
  // set initial condition
 | 
			
		||||
  u0=set_init(parameters);
 | 
			
		||||
  u0=set_init(¶meters);
 | 
			
		||||
 | 
			
		||||
  // close initfile (do this early, so that it is possible to use the same file for init and save)
 | 
			
		||||
  if (parameters.initfile!=NULL){
 | 
			
		||||
@@ -169,15 +172,15 @@ int main (
 | 
			
		||||
 | 
			
		||||
  // run command
 | 
			
		||||
  if (command==COMMAND_UK){
 | 
			
		||||
    uk(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.nsteps, parameters.nu, parameters.delta, parameters.L, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile);
 | 
			
		||||
    uk(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.nsteps, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_step, parameters.starting_time, nthreads, savefile);
 | 
			
		||||
  }
 | 
			
		||||
  else if(command==COMMAND_ENSTROPHY){
 | 
			
		||||
    // register signal handler to handle aborts
 | 
			
		||||
    signal(SIGINT, sig_handler);
 | 
			
		||||
    enstrophy(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.nsteps, parameters.nu, parameters.delta, parameters.L, 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.nsteps, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, u0, g, parameters.irreversible, parameters.algorithm, parameters.print_freq, parameters.starting_step, 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.nsteps, parameters.nu, parameters.delta, parameters.L, parameters.starting_time, u0, g, parameters.irreversible, parameters.algorithm, nthreads, savefile);
 | 
			
		||||
    quiet(parameters.K1, parameters.K2, parameters.N1, parameters.N2, parameters.nsteps, parameters.nu, parameters.delta, parameters.L, parameters.adaptive_tolerance, parameters.adaptive_factor, parameters.starting_step, u0, g, parameters.irreversible, parameters.algorithm, nthreads, savefile);
 | 
			
		||||
  }
 | 
			
		||||
  else if(command==0){
 | 
			
		||||
    fprintf(stderr, "error: no command specified\n");
 | 
			
		||||
@@ -261,6 +264,9 @@ int print_params(
 | 
			
		||||
  case ALGORITHM_RK2:
 | 
			
		||||
    fprintf(file,", algorithm=RK2");
 | 
			
		||||
    break;
 | 
			
		||||
  case ALGORITHM_RKF45:
 | 
			
		||||
    fprintf(file,", algorithm=RKF45, tolerance=%.15e, factor=%.15e",parameters.adaptive_tolerance, parameters.adaptive_factor);
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    fprintf(file,", algorithm=RK4");
 | 
			
		||||
    break;
 | 
			
		||||
@@ -371,6 +377,7 @@ int read_params(
 | 
			
		||||
  // whether N was set explicitly
 | 
			
		||||
  bool setN1=false;
 | 
			
		||||
  bool setN2=false;
 | 
			
		||||
  bool set_starting_time=false;
 | 
			
		||||
  // whether lhs (false is rhs)
 | 
			
		||||
  bool lhs=true;
 | 
			
		||||
 | 
			
		||||
@@ -384,9 +391,12 @@ int read_params(
 | 
			
		||||
  //nu=2^-11
 | 
			
		||||
  parameters->nu=0.00048828125;
 | 
			
		||||
  parameters->L=2*M_PI;
 | 
			
		||||
  parameters->adaptive_tolerance=1e-11;
 | 
			
		||||
  parameters->adaptive_factor=0.9;
 | 
			
		||||
  parameters->nsteps=10000000;
 | 
			
		||||
  parameters->print_freq=1000;
 | 
			
		||||
  parameters->starting_time=0;
 | 
			
		||||
  parameters->starting_step=0;
 | 
			
		||||
  parameters->seed=17;
 | 
			
		||||
  parameters->driving=DRIVING_TEST;
 | 
			
		||||
  parameters->drivingfile=NULL;
 | 
			
		||||
@@ -413,7 +423,7 @@ int read_params(
 | 
			
		||||
	break;
 | 
			
		||||
      case ';':
 | 
			
		||||
	//set parameter
 | 
			
		||||
	ret=set_parameter(buffer_lhs, buffer_rhs, parameters, &setN1, &setN2, initfile_str, drivingfile_str);
 | 
			
		||||
	ret=set_parameter(buffer_lhs, buffer_rhs, parameters, &setN1, &setN2, &set_starting_time, initfile_str, drivingfile_str);
 | 
			
		||||
	if(ret<0){
 | 
			
		||||
	  return ret;
 | 
			
		||||
	}
 | 
			
		||||
@@ -440,7 +450,7 @@ int read_params(
 | 
			
		||||
 | 
			
		||||
    // set last param
 | 
			
		||||
    if (*param_str!='\0'){
 | 
			
		||||
      ret=set_parameter(buffer_lhs, buffer_rhs, parameters, &setN1, &setN2, initfile_str, drivingfile_str);
 | 
			
		||||
      ret=set_parameter(buffer_lhs, buffer_rhs, parameters, &setN1, &setN2, &set_starting_time, initfile_str, drivingfile_str);
 | 
			
		||||
      if(ret<0){
 | 
			
		||||
	return ret;
 | 
			
		||||
      }
 | 
			
		||||
@@ -459,6 +469,10 @@ int read_params(
 | 
			
		||||
    parameters->N2=smallest_pow2(3*(parameters->K2));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // if starting_time not set explicitly and algorithm is not adaptive, set it to delta*starting_step
 | 
			
		||||
  if (!set_starting_time && parameters->algorithm<ALGORITHM_ADAPTIVE_THRESHOLD){
 | 
			
		||||
    parameters->starting_time=parameters->delta*parameters->starting_step;
 | 
			
		||||
  }
 | 
			
		||||
  return(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -470,6 +484,7 @@ int set_parameter(
 | 
			
		||||
  nstrophy_parameters* parameters,
 | 
			
		||||
  bool* setN1,
 | 
			
		||||
  bool* setN2,
 | 
			
		||||
  bool* set_starting_time,
 | 
			
		||||
  char** initfile_str,
 | 
			
		||||
  char** drivingfile_str
 | 
			
		||||
){
 | 
			
		||||
@@ -570,6 +585,20 @@ int set_parameter(
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(lhs,"print_freq")==0){
 | 
			
		||||
    ret=sscanf(rhs,"%lu",&(parameters->print_freq));
 | 
			
		||||
    if(ret!=1){
 | 
			
		||||
@@ -584,13 +613,21 @@ int set_parameter(
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(lhs,"starting_time")==0){
 | 
			
		||||
    ret=sscanf(rhs,"%lu",&(parameters->starting_time));
 | 
			
		||||
  else if (strcmp(lhs,"starting_step")==0){
 | 
			
		||||
    ret=sscanf(rhs,"%lu",&(parameters->starting_step));
 | 
			
		||||
    if(ret!=1){
 | 
			
		||||
      fprintf(stderr, "error: parameter 'starting_time' should be an unsigned integer\n       got '%s'\n",rhs);
 | 
			
		||||
      fprintf(stderr, "error: parameter 'starting_step' should be a long unsigned integer\n       got '%s'\n",rhs);
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(lhs,"starting_time")==0){
 | 
			
		||||
    ret=sscanf(rhs,"%lf",&(parameters->starting_time));
 | 
			
		||||
    if(ret!=1){
 | 
			
		||||
      fprintf(stderr, "error: parameter 'starting_time' should be a double\n       got '%s'\n",rhs);
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
    *set_starting_time=true;
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(lhs,"driving")==0){
 | 
			
		||||
    if (strcmp(rhs,"zero")==0){
 | 
			
		||||
      parameters->driving=DRIVING_ZERO;
 | 
			
		||||
@@ -648,6 +685,9 @@ int set_parameter(
 | 
			
		||||
    else if (strcmp(rhs,"RK2")==0){
 | 
			
		||||
      parameters->algorithm=ALGORITHM_RK2;
 | 
			
		||||
    }
 | 
			
		||||
    else if (strcmp(rhs,"RKF45")==0){
 | 
			
		||||
      parameters->algorithm=ALGORITHM_RKF45;
 | 
			
		||||
    }
 | 
			
		||||
    else{
 | 
			
		||||
      fprintf(stderr, "error: unrecognized algorithm '%s'\n",rhs);
 | 
			
		||||
      return(-1);
 | 
			
		||||
@@ -692,29 +732,35 @@ _Complex double* set_driving(
 | 
			
		||||
 | 
			
		||||
// set initial condition
 | 
			
		||||
_Complex double* set_init(
 | 
			
		||||
  nstrophy_parameters parameters
 | 
			
		||||
  nstrophy_parameters* parameters
 | 
			
		||||
){
 | 
			
		||||
  _Complex double* u0=calloc(sizeof(_Complex double),parameters.K1*(2*parameters.K2+1)+parameters.K2);
 | 
			
		||||
  _Complex double* u0=calloc(sizeof(_Complex double),parameters->K1*(2*parameters->K2+1)+parameters->K2);
 | 
			
		||||
 | 
			
		||||
  switch(parameters.init){
 | 
			
		||||
  switch(parameters->init){
 | 
			
		||||
  case INIT_RANDOM:
 | 
			
		||||
    init_random(u0, parameters.init_en, parameters.K1, parameters.K2, parameters.L, parameters.seed, parameters.irreversible);
 | 
			
		||||
    init_random(u0, parameters->init_en, parameters->K1, parameters->K2, parameters->L, parameters->seed, parameters->irreversible);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case INIT_GAUSSIAN:
 | 
			
		||||
    init_gaussian(u0, parameters.init_en, parameters.K1, parameters.K2, parameters.L, parameters.irreversible);
 | 
			
		||||
    init_gaussian(u0, parameters->init_en, parameters->K1, parameters->K2, parameters->L, parameters->irreversible);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case INIT_FILE:
 | 
			
		||||
    init_file_bin(u0, parameters.K1, parameters.K2, parameters.initfile);
 | 
			
		||||
    init_file_bin(u0, parameters->K1, parameters->K2, parameters->initfile);
 | 
			
		||||
    if(parameters->algorithm>ALGORITHM_ADAPTIVE_THRESHOLD){
 | 
			
		||||
      // read delta
 | 
			
		||||
      fread(&(parameters->delta), sizeof(double), 1, parameters->initfile);
 | 
			
		||||
      // read start time
 | 
			
		||||
      fread(&(parameters->starting_time), sizeof(double), 1, parameters->initfile);
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case INIT_FILE_TXT:
 | 
			
		||||
    init_file_txt(u0, parameters.K1, parameters.K2, parameters.initfile);
 | 
			
		||||
    init_file_txt(u0, parameters->K1, parameters->K2, parameters->initfile);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    init_gaussian(u0, parameters.init_en, parameters.K1, parameters.K2, parameters.L, parameters.irreversible);
 | 
			
		||||
    init_gaussian(u0, parameters->init_en, parameters->K1, parameters->K2, parameters->L, parameters->irreversible);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user