Compare commits

...

8 Commits

Author SHA1 Message Date
Ian Jauslin 6c12e47105 Do not override command when using 'resume' 2023-11-03 18:02:12 -04:00
Ian Jauslin 209ba06cbf memory fix 2023-11-03 17:41:30 -04:00
Ian Jauslin 16c80d2305 strlen in dstrings.c 2023-11-03 16:48:18 -04:00
Ian Jauslin f9aac70796 dstring in read_args_from_file 2023-11-03 16:45:51 -04:00
Ian Jauslin 9d232a8fca dstrings in read_params 2023-11-03 16:42:27 -04:00
Ian Jauslin 04a15dd2c7 Replace argv strings with dstrings 2023-11-03 16:04:53 -04:00
Ian Jauslin dd9bd74c83 dynamic strings 2023-11-03 12:25:02 -04:00
Ian Jauslin 3d94694017 Resume command
Not functional yet: need to deal with memory of argv
2023-11-03 12:08:25 -04:00
4 changed files with 599 additions and 121 deletions

View File

@ -18,6 +18,7 @@ limitations under the License.
#define COMMAND_UK 1
#define COMMAND_ENSTROPHY 2
#define COMMAND_QUIET 3
#define COMMAND_RESUME 4
#define DRIVING_ZERO 1
#define DRIVING_TEST 2

244
src/dstring.c Normal file
View File

@ -0,0 +1,244 @@
/*
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 "dstring.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
// init
int dstring_init (dstring* str, unsigned int memory){
str->string=calloc(memory,sizeof(char));
str->memory=memory;
str->length=0;
return(0);
}
int dstring_free (dstring str){
free(str.string);
return(0);
}
// resize memory
int dstring_resize (dstring* str, unsigned int newsize){
unsigned int i;
dstring new_str;
dstring_init (&new_str, newsize);
for(i=0;i<str->length;i++){
new_str.string[i]=str->string[i];
}
new_str.length=str->length;
free(str->string);
*str=new_str;
return(0);
}
// add a character
int dstring_append (char val, dstring* output){
if(output->length >= output->memory){
dstring_resize (output,2*output->memory+1);
}
output->string[output->length]=val;
output->length++;
return(0);
}
// copy
int dstring_cpy (dstring input, dstring* output){
dstring_init (output, input.length);
dstring_cpy_noinit (input, output);
return(0);
}
// do not init output str
int dstring_cpy_noinit (dstring input, dstring* output){
unsigned int i;
if(output->memory<input.length){
fprintf(stderr,"error: cannot copy a dstring of length %u to a dstring with memory %u\n",input.length,output->memory);
return(-1);
}
for(i=0;i<input.length;i++){
output->string[i]=input.string[i];
}
output->length=input.length;
return(0);
}
// concatenate
int dstring_concat (dstring input, dstring* output){
unsigned int i;
for(i=0;i<input.length;i++){
dstring_append (input.string[i], output);
}
return(0);
}
// sub-str
int dstring_substr (dstring str, unsigned int begin, unsigned int end, dstring* substr){
unsigned int i;
if(begin>end || end>=str.length){
fprintf(stderr,"error: cannot take substring [%u,%u] of dstring of lengdth %u\n",begin,end,str.length);
return(-1);
}
dstring_init (substr,end-begin);
for(i=begin;i<=end;i++){
dstring_append (str.string[i], substr);
}
return(0);
}
// find
int dstring_find (char val, dstring str){
unsigned int i;
for(i=0;i<str.length;i++){
if(str.string[i]==val){
return(i);
}
}
return(-1);
}
// compare strings
int dstring_cmp (dstring str1, dstring str2){
unsigned int i;
// compare lengths
if(str1.length<str2.length){
return(-1);
}
if(str1.length>str2.length){
return(1);
}
// compare terms
for(i=0;i<str1.length;i++){
if(str1.string[i]<str2.string[i]){
return(-1);
}
if(str1.string[i]<str2.string[i]){
return(1);
}
}
// if equal
return(0);
}
// print str
int dstring_print (dstring str, FILE* file){
unsigned int i;
for(i=0;i<str.length;i++){
fprintf(file, "%s",str.string);
}
return(0);
}
// append a char*
int dstring_append_str(char* str, dstring* output){
char* ptr;
for (ptr=str;*ptr!='\0';ptr++){
dstring_append(*ptr, output);
}
return(0);
}
// convert to char*
int dstring_to_str(dstring input, char** output){
unsigned int i;
(*output)=calloc(input.length+1,sizeof(char));
for(i=0;i<input.length;i++){
(*output)[i]=input.string[i];
}
if((*output)[input.length-1]!='\0'){
(*output)[input.length]='\0';
}
return(0);
}
// noinit (changes the size of input if needed)
char* dstring_to_str_noinit(dstring* input){
// check if string ends in a trailing '\0' (or if string is empty)
if(input->length==0 || input->string[input->length-1]!='\0'){
if(input->length==input->memory){
dstring_resize(input,input->length+1);
}
// add final '\0'
input->string[input->length]='\0';
}
return(input->string);
}
// convert from char*
int str_to_dstring(char* str, dstring* output){
dstring_init(output, strlen(str));
str_to_dstring_noinit(str, output);
return(0);
}
int str_to_dstring_noinit(char* str, dstring* output){
// reset length
output->length=0;
dstring_append_str(str, output);
return(0);
}
// compare a dstring and a char*
int dstring_cmp_str(dstring dstring, char* str){
unsigned int j;
for(j=0;j<dstring.length && str[j]!='\0';j++){
if(dstring.string[j]!=str[j]){
return(1);
}
}
if(j==dstring.length && str[j]=='\0'){
return(0);
}
return(1);
}
// format strings
int dstring_snprintf(dstring* output, char* fmt, ...){
size_t size=100;
unsigned int extra_size;
char* out_str=calloc(size,sizeof(char));
char* ptr;
va_list vaptr;
// initialize argument list starting after fmt
va_start(vaptr, fmt);
// print format
extra_size=vsnprintf(out_str, size, fmt, vaptr);
va_end(vaptr);
// if too large
if(extra_size>size){
// resize
free(out_str);
// +1 for '\0'
size=extra_size+1;
out_str=calloc(size,sizeof(char));
// read format again
va_start(vaptr, fmt);
vsnprintf(out_str,size,fmt,vaptr);
va_end(vaptr);
}
// write to char array
for(ptr=out_str;*ptr!='\0';ptr++){
dstring_append(*ptr, output);
}
free(out_str);
return(0);
}

77
src/dstring.h Normal file
View File

@ -0,0 +1,77 @@
/*
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 DSTRING_H
#define DSTRING_H
#include <stdio.h>
typedef struct dstring {
char* string;
unsigned int length;
unsigned int memory;
} dstring;
// init
int dstring_init (dstring* str, unsigned int memory);
int dstring_free (dstring str);
// resize memory
int dstring_resize (dstring* str, unsigned int newsize);
// add a character
int dstring_append (char val, dstring* output);
// copy
int dstring_cpy (dstring input, dstring* output);
// do not init output str
int dstring_cpy_noinit (dstring input, dstring* output);
// concatenate
int dstring_concat (dstring input, dstring* output);
// sub-str
int dstring_substr (dstring str, unsigned int begin, unsigned int end, dstring* substr);
// find
int dstring_find (char val, dstring str);
// compare strings
int dstring_cmp (dstring str1, dstring str2);
// print str
int dstring_print (dstring str, FILE* file);
// append a char*
int dstring_append_str(char* str, dstring* output);
// convert to char*
int dstring_to_str(dstring input, char** output);
// noinit (changes the size of input if needed)
char* dstring_to_str_noinit(dstring* input);
// convert from char*
int str_to_dstring(char* str, dstring* output);
int str_to_dstring_noinit(char* str, dstring* output);
// compare a dstring and a char*
int dstring_cmp_str(dstring dstring, char* str);
// format strings
int dstring_snprintf(dstring* output, char* fmt, ...);
#endif

View File

@ -20,9 +20,11 @@ limitations under the License.
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <wordexp.h>
#include "constants.cpp"
#include "driving.h"
#include "dstring.h"
#include "init.h"
#include "int_tools.h"
#include "navier-stokes.h"
@ -61,9 +63,12 @@ int print_usage();
int print_params(nstrophy_parameters parameters, char* initfile_str, char* drivingfile_str, FILE* file);
// read command line arguments
int read_args(int argc, const char* argv[], char** params, unsigned int* command, unsigned int* nthreads, char** savefile_str, char** utfile_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 read_args(int argc, const char* argv[], dstring* params, unsigned int* command, unsigned int* nthreads, dstring* savefile_str, dstring* utfile_str, dstring* resumefile_str);
int set_default_params(nstrophy_parameters* parameters);
int read_params(dstring param_str, nstrophy_parameters* parameters, dstring* initfile_str, dstring* drivingfile_str);
int set_parameter(char* lhs, char* rhs, nstrophy_parameters* parameters, bool* setN1, bool* setN2, dstring* initfile_str, dstring* drivingfile_str);
// read args from file
int args_from_file(dstring* params, unsigned int* command, unsigned int* nthreads, dstring* savefile_str, dstring* utfile_str, char* file_str);
// set driving force
_Complex double* set_driving(nstrophy_parameters parameters);
@ -77,9 +82,17 @@ void sig_handler (int signo);
volatile bool g_abort = false;
// signal handler
void sig_handler (int signo){
if (signo == SIGINT || signo == SIGTERM){
if (signo == SIGINT){
fprintf(stderr,"received signal SIGINT, interrupting computation\n");
g_abort = true;
}
else if (signo == SIGTERM){
fprintf(stderr,"received signal SIGTERM, interrupting computation\n");
g_abort = true;
}
else{
fprintf(stderr,"received signal %d\n",signo);
}
}
@ -87,47 +100,114 @@ int main (
int argc,
const char* argv[]
){
char* param_str=NULL;
dstring param_str;
nstrophy_parameters parameters;
int ret;
unsigned int command;
unsigned int nthreads=1;
_Complex double* u0;
_Complex double *g;
char* savefile_str=NULL;
char* utfile_str=NULL;
char* initfile_str=NULL;
char* drivingfile_str=NULL;
dstring savefile_str;
dstring utfile_str;
dstring initfile_str;
dstring drivingfile_str;
dstring resumefile_str;
FILE* savefile=NULL;
FILE* utfile=NULL;
command=0;
// init strings
dstring_init(&param_str, 64);
dstring_init(&savefile_str, 64);
dstring_init(&utfile_str, 64);
dstring_init(&initfile_str, 64);
dstring_init(&drivingfile_str, 64);
dstring_init(&resumefile_str, 64);
// read command line arguments
ret=read_args(argc, argv, &param_str, &command, &nthreads, &savefile_str, &utfile_str);
ret=read_args(argc, argv, &param_str, &command, &nthreads, &savefile_str, &utfile_str, &resumefile_str);
if(ret<0){
return(-1);
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
dstring_free(resumefile_str);
return(ret);
}
// set default params
set_default_params(&parameters);
// read params
ret=read_params(param_str, &parameters, &initfile_str, &drivingfile_str);
if(ret<0){
return(-1);
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
dstring_free(resumefile_str);
return(ret);
}
// if command is 'resume', then read args from file
if(command==COMMAND_RESUME){
ret=args_from_file(&param_str, &command, &nthreads, &savefile_str, &utfile_str, dstring_to_str_noinit(&resumefile_str));
if(ret<0){
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
dstring_free(resumefile_str);
return(ret);
}
// read params
ret=read_params(param_str, &parameters, &initfile_str, &drivingfile_str);
if(ret<0){
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
dstring_free(resumefile_str);
return(ret);
}
// reread arguments (to allow overrides from the command line, but do not override the command)
unsigned int dummy_command;
read_args(argc, argv, &param_str, &dummy_command, &nthreads, &savefile_str, &utfile_str, &resumefile_str);
// reread params
read_params(param_str, &parameters, &initfile_str, &drivingfile_str);
}
// free strings
dstring_free(resumefile_str);
// open initfile
if(initfile_str!=NULL){
parameters.initfile=fopen(initfile_str,"r");
if(initfile_str.length!=0){
parameters.initfile=fopen(dstring_to_str_noinit(&initfile_str),"r");
if(parameters.initfile==NULL){
fprintf(stderr,"Error opening file '%s' for reading: %s\n", initfile_str, strerror(errno));
fprintf(stderr,"Error opening file '%s' for reading: %s\n", dstring_to_str_noinit(&initfile_str), strerror(errno));
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
return(-1);
}
}
// open drivingfile
if(drivingfile_str!=NULL){
parameters.drivingfile=fopen(drivingfile_str,"r");
if(drivingfile_str.length!=0){
parameters.drivingfile=fopen(dstring_to_str_noinit(&drivingfile_str),"r");
if(parameters.drivingfile==NULL){
fprintf(stderr,"Error opening file '%s' for reading: %s\n", drivingfile_str, strerror(errno));
fprintf(stderr,"Error opening file '%s' for reading: %s\n", dstring_to_str_noinit(&drivingfile_str), strerror(errno));
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
return(-1);
}
}
@ -147,35 +227,44 @@ int main (
}
// open savefile (do this after closing init file)
if(savefile_str!=NULL){
savefile=fopen(savefile_str,"w");
if(savefile_str.length!=0){
savefile=fopen(dstring_to_str_noinit(&savefile_str),"w");
if(savefile==NULL){
fprintf(stderr,"Error opening file '%s' for writing: %s\n", savefile_str, strerror(errno));
fprintf(stderr,"Error opening file '%s' for writing: %s\n", dstring_to_str_noinit(&savefile_str), strerror(errno));
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
free(g);
free(u0);
return(-1);
}
}
// open utfile (do this after closing init file)
if(utfile_str!=NULL){
utfile=fopen(utfile_str,"w");
if(utfile_str.length!=0){
utfile=fopen(dstring_to_str_noinit(&utfile_str),"w");
if(utfile==NULL){
fprintf(stderr,"Error opening file '%s' for writing: %s\n", utfile_str, strerror(errno));
fprintf(stderr,"Error opening file '%s' for writing: %s\n", dstring_to_str_noinit(&utfile_str), strerror(errno));
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
dstring_free(initfile_str);
dstring_free(drivingfile_str);
free(g);
free(u0);
return(-1);
}
}
// print parameters
print_params(parameters, initfile_str, drivingfile_str, stderr);
print_params(parameters, initfile_str, drivingfile_str, stdout);
print_params(parameters, dstring_to_str_noinit(&initfile_str), dstring_to_str_noinit(&drivingfile_str), stderr);
print_params(parameters, dstring_to_str_noinit(&initfile_str), dstring_to_str_noinit(&drivingfile_str), stdout);
// free initfile_str
if(initfile_str!=NULL){
free(initfile_str);
}
// free drivingfile_str
if(drivingfile_str!=NULL){
free(drivingfile_str);
}
// free strings
dstring_free(initfile_str);
dstring_free(drivingfile_str);
// run command
if (command==COMMAND_UK){
@ -185,7 +274,7 @@ int main (
// 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, parameters.max_delta, parameters.adaptive_norm, u0, g, parameters.irreversible, parameters.keep_en_cst, parameters.init_en, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile, utfile, (char*)argv[0], param_str, savefile_str, utfile_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, parameters.adaptive_norm, u0, g, parameters.irreversible, parameters.keep_en_cst, parameters.init_en, parameters.algorithm, parameters.print_freq, parameters.starting_time, nthreads, savefile, utfile, (char*)argv[0], dstring_to_str_noinit(&param_str), dstring_to_str_noinit(&savefile_str), dstring_to_str_noinit(&utfile_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.max_delta, parameters.adaptive_norm, parameters.starting_time, u0, g, parameters.irreversible, parameters.keep_en_cst, parameters.init_en, parameters.algorithm, nthreads, savefile);
@ -198,6 +287,11 @@ int main (
free(g);
free(u0);
// free strings
dstring_free(param_str);
dstring_free(savefile_str);
dstring_free(utfile_str);
// close savefile
if (savefile!=NULL){
fclose(savefile);
@ -213,7 +307,7 @@ int main (
// usage message
int print_usage(){
fprintf(stderr, "usage:\n nstrophy [-t nthreads] [-p parameters] [-s savefile] [-u u_outfile] <command>\n\n");
fprintf(stderr, "usage:\n nstrophy [-t nthreads] [-p parameters] [-s savefile] [-u u_outfile] <command>\n where <command> is one of\n enstrophy\n uk\n quiet\n resume <resume_file>\n\n");
return(0);
}
@ -319,14 +413,16 @@ int print_params(
#define CP_FLAG_NTHREADS 2
#define CP_FLAG_SAVEFILE 3
#define CP_FLAG_UTFILE 4
#define CP_FLAG_RESUME 5
int read_args(
int argc,
const char* argv[],
char** params,
dstring* params,
unsigned int* command,
unsigned int* nthreads,
char** savefile_str,
char** utfile_str
dstring* savefile_str,
dstring* utfile_str,
dstring* resumefile_str
){
int i;
int ret;
@ -363,7 +459,7 @@ int read_args(
}
// params
else if(flag==CP_FLAG_PARAMS){
*params=(char*)argv[i];
str_to_dstring_noinit((char*)argv[i], params);
flag=0;
}
// nthreads
@ -377,12 +473,17 @@ int read_args(
}
// savefile
else if(flag==CP_FLAG_SAVEFILE){
*savefile_str=(char*)argv[i];
str_to_dstring_noinit((char*)argv[i], savefile_str);
flag=0;
}
// savefile
else if(flag==CP_FLAG_UTFILE){
*utfile_str=(char*)argv[i];
str_to_dstring_noinit((char*)argv[i], utfile_str);
flag=0;
}
// resume file
else if(flag==CP_FLAG_RESUME){
str_to_dstring_noinit((char*)argv[i], resumefile_str);
flag=0;
}
// computation to run
@ -396,37 +497,31 @@ int read_args(
else if(strcmp(argv[i], "quiet")==0){
*command=COMMAND_QUIET;
}
else if(strcmp(argv[i], "resume")==0){
*command=COMMAND_RESUME;
flag=CP_FLAG_RESUME;
}
else{
fprintf(stderr, "error: unrecognized command: '%s'\n",argv[i]);
return(-1);
}
flag=0;
}
}
// check that if the command is 'resume', then resumefile has been set
if(*command==COMMAND_RESUME && resumefile_str->length==0){
fprintf(stderr, "error: 'resume' command used, but no resume file\n");
print_usage();
return(-1);
}
return(0);
}
// read parameters string
int read_params(
char* param_str,
nstrophy_parameters* parameters,
char** initfile_str,
char** drivingfile_str
// set default parameters
int set_default_params(
nstrophy_parameters* parameters
){
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
parameters->init_en=1.54511597324389e+02;
parameters->irreversible=true;
parameters->K1=16;
@ -450,64 +545,68 @@ int read_params(
parameters->initfile=NULL;
parameters->algorithm=ALGORITHM_RK4;
parameters->keep_en_cst=false;
return(0);
}
if (param_str!=NULL){
// init
buffer_lhs=calloc(sizeof(char),strlen(param_str));
lhs_ptr=buffer_lhs;
*lhs_ptr='\0';
buffer_rhs=calloc(sizeof(char),strlen(param_str));
rhs_ptr=buffer_rhs;
*rhs_ptr='\0';
// read parameters string
int read_params(
dstring param_str,
nstrophy_parameters* parameters,
dstring* initfile_str,
dstring* drivingfile_str
){
int ret;
unsigned int i;
// buffer and associated pointer
dstring buffer_lhs;
dstring buffer_rhs;
// whether N was set explicitly
bool setN1=false;
bool setN2=false;
// which buffer to add to
dstring* buffer=&buffer_lhs;
for(ptr=param_str;*ptr!='\0';ptr++){
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);
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;
}
}
// init
dstring_init(&buffer_lhs, param_str.length);
dstring_init(&buffer_rhs, param_str.length);
// set last param
if (*param_str!='\0'){
ret=set_parameter(buffer_lhs, buffer_rhs, parameters, &setN1, &setN2, initfile_str, drivingfile_str);
for(i=0;i<param_str.length;i++){
switch(param_str.string[i]){
case '=':
// reset buffer
buffer_rhs.length=0;
buffer=&buffer_rhs;
break;
case ';':
//set parameter
ret=set_parameter(dstring_to_str_noinit(&buffer_lhs), dstring_to_str_noinit(&buffer_rhs), parameters, &setN1, &setN2, initfile_str, drivingfile_str);
if(ret<0){
return ret;
}
// reset buffer
buffer_lhs.length=0;
buffer=&buffer_lhs;
break;
default:
// add to buffer
dstring_append(param_str.string[i],buffer);
break;
}
// free vects
free(buffer_lhs);
free(buffer_rhs);
}
// set last param
if (param_str.length!=0){
ret=set_parameter(dstring_to_str_noinit(&buffer_lhs), dstring_to_str_noinit(&buffer_rhs), parameters, &setN1, &setN2, initfile_str, drivingfile_str);
if(ret<0){
return ret;
}
}
// free vects
dstring_free(buffer_lhs);
dstring_free(buffer_rhs);
// 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)
if (!setN1){
parameters->N1=smallest_pow2(3*(parameters->K1));
@ -527,8 +626,8 @@ int set_parameter(
nstrophy_parameters* parameters,
bool* setN1,
bool* setN2,
char** initfile_str,
char** drivingfile_str
dstring* initfile_str,
dstring* drivingfile_str
){
int ret;
@ -697,14 +796,12 @@ int set_parameter(
// 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);
str_to_dstring_noinit(rhs+5,drivingfile_str);
}
// 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);
str_to_dstring_noinit(rhs+9,drivingfile_str);
}
else{
fprintf(stderr, "error: unrecognized driving force '%s'\n",rhs);
@ -722,14 +819,12 @@ int set_parameter(
// matches any argument that starts with 'file:'
else if (strncmp(rhs,"file:",5)==0){
parameters->init=INIT_FILE;
*initfile_str=calloc(sizeof(char), strlen(rhs)-5+1);
strcpy(*initfile_str, rhs+5);
str_to_dstring_noinit(rhs+5,initfile_str);
}
// 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);
str_to_dstring_noinit(rhs+9,initfile_str);
}
else{
fprintf(stderr, "error: unrecognized initial condition '%s'\n",rhs);
@ -775,6 +870,67 @@ int set_parameter(
return(0);
}
// read args from file
int args_from_file(
dstring* params,
unsigned int* command,
unsigned int* nthreads,
dstring* savefile_str,
dstring* utfile_str,
char* file_str
){
dstring line;
char c;
// open file
FILE* file=fopen(file_str,"r");
if(file==NULL){
fprintf(stderr,"Error opening file '%s' for reading: %s\n", file_str, strerror(errno));
return(-1);
}
// allocate line buffer
dstring_init(&line,64);
while(1){
c=fgetc(file);
// end of file
if (feof(file)){
break;
}
// newline: read line and reset buffer
if(c=='\n' || c=='\r'){
// read entry
// ignore lines with fewer than three characters
if(line.length>=3){
// find line starting with "#!"
if(line.string[0]=='#' && line.string[1]=='!'){
wordexp_t pwordexp;
wordexp(line.string+2,&pwordexp,0);
// read arguments
read_args(pwordexp.we_wordc, (const char **)pwordexp.we_wordv, params, command, nthreads, savefile_str, utfile_str, NULL);
wordfree(&pwordexp);
// exit
break;
}
}
// reset buffer
line.length=0;
}
// add to buffer
else {
dstring_append(c,&line);
}
}
dstring_free(line);
// close file
fclose(file);
return(0);
}
// set driving force
_Complex double* set_driving(
nstrophy_parameters parameters