Code Search for Developers
 
 
  

main.cpp from Oscill8 at Krugle


Show main.cpp syntax highlighted


#include "Oscill8External.h" // emery added for oscill8
#include "auto_f2c.h"
#include "auto_c.h"

#ifdef WIN32 /* @@edc: added for windows getopt */
extern char *optarg;
int getopt(int nargc, char * const *nargv, const char *ostr);
#endif

#ifdef FLOATING_POINT_TRAP
#include <fpu_control.h>
/* This is a x86 specific function only used for debugging.
   It turns on various floating point traps.  */
static int trapfpe()
{
  fpu_control_t traps;
  traps = _FPU_DEFAULT & (~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM));
  _FPU_SETCW(traps);
}
#endif

BEGIN_AUTO_NAMESPACE;

FILE *fp2  = NULL;
FILE *fp3  = NULL;
FILE *fp6  = NULL;
FILE *fp7  = NULL;
FILE *fp8  = NULL;
FILE *fp9  = NULL;
FILE *fp12 = NULL;

// initialize these... they may be reset before a call to AUTO_main
int num_model_pars = 10;
int num_total_pars = 2*num_model_pars;
int sysoff = num_model_pars;

void SetAutoNumParameters(int n)
{
  num_model_pars = n;
  num_total_pars = 4*n;
  sysoff = n;
}

// add changable fort names for ease
char fort_name[13][512];
int fort_names_are_valid = 0;
double auto_progress = 0.0;

void SetFortNames(const char *key)
{
	sprintf(fort_name[2], "%s.2", key);
	sprintf(fort_name[3], "%s.3", key);
	sprintf(fort_name[6], "%s.6", key);
	sprintf(fort_name[7], "%s.7", key);
	sprintf(fort_name[8], "%s.8", key);
	sprintf(fort_name[9], "%s.9", key);
	sprintf(fort_name[12], "%s.12", key);
}

int global_conpar_type=CONPAR_DEFAULT;
int global_setubv_type=SETUBV_DEFAULT;
int global_reduce_type=REDUCE_DEFAULT;
int global_num_procs=1;
int global_verbose_flag=0;

static void options(){
  fprintf(fp6, "-v:    Give verbose output.\n");
  fprintf(fp6, "-m:    Use the Message Passing Interface library for parallelization.\n");
  fprintf(fp6, "-t:    Use the Pthreads library for parallelization.\n");
  fprintf(fp6, "       This option takes one of three arguements.\n"); 
  fprintf(fp6, "       'conpar' parallelizes the condensation of parameters routine.\n");
  fprintf(fp6, "       'setubv' parallelizes the jacobian setup routine.\n");
  fprintf(fp6, "       'reduce' parallelizes the nested dissection routine.\n");
  fprintf(fp6, "       'all'    parallelizes all routines.\n");
  fprintf(fp6, "       In general the recommeneded option is 'all'.\n");
  fprintf(fp6, "-#:    The number of processing units to use (currently only used with the -t option)\n");
}

static void scheme_not_supported_error(char *scheme) {
  fprintf(fp6, "'%s' not available in this binary\n",scheme);
  fprintf(fp6, "Support for '%s' needs to be included at compile time\n",scheme);
  EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
}

int AUTO_main(int argc,char *argv[])
{
	// init progress
	auto_progress = 0.0;

#ifdef WIN32
  clock_t time0, time1;
#else
  struct timeval  *time0,*time1;
#endif
  integer *icp = (integer *)malloc(sizeof(integer)*num_total_pars);
  doublereal *par = (doublereal *)malloc(sizeof(doublereal)*num_total_pars),
		         *thl = (doublereal *)malloc(sizeof(doublereal)*num_total_pars);
  doublereal *thu = 0;
  integer *iuz = 0;
  doublereal *vuz = 0;
  iap_type iap;
  rap_type rap;
  function_list list;

#ifdef USAGE
  struct rusage *init_usage,*total_usage;
  usage_start(&init_usage);
  usage_start(&total_usage);
#endif

#ifdef FLOATING_POINT_TRAP
  trapfpe();
#endif

#ifdef MPI
  MPI_Init(&argc,&argv);
#endif

	// check if we should set fort_names or not
	if(!fort_names_are_valid)
	{
		SetFortNames("fort");
		strcpy(fort_name[6], "stdout");
	}

OPEN_FP3:
  fp3 = fopen(fort_name[3],"r");
  if(fp3 == NULL) {
    EXTERNAL_LIBRARY_FPRINTF_STDERR("warning:  Could not open %s\n", fort_name[3]);

		// don't die, just "touch" the file
		fp3 = fopen(fort_name[3], "w");
		if(fp3 == NULL)
		{
			EXTERNAL_LIBRARY_FPRINTF_STDERR("Error: couldn't not create %s\n", fort_name[3]);
			EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
		}
		fclose(fp3);
		goto OPEN_FP3;
  }
#ifdef LIBRARY_ONLY
	if(strcmp(fort_name[6], "stdout"))
	{
		fp6 = fopen(fort_name[6],"w");
		if(fp6 == NULL) {
			EXTERNAL_LIBRARY_FPRINTF_STDERR("Error:  Could not open %s\n", fort_name[6]);
			EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
		}
	}
	else
		fp6 = stdout;
#endif
  fp7 = fopen(fort_name[7],"w");
  if(fp7 == NULL) {
    EXTERNAL_LIBRARY_FPRINTF_STDERR("Error:  Could not open %s\n", fort_name[7]);
    EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
  }

#ifdef _DEBUG
  fp9 = fopen(fort_name[9],"w");
  if(fp9 == NULL) {
    EXTERNAL_LIBRARY_FPRINTF_STDERR("Error:  Could not open %s\n", fort_name[9]);
    EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
  }
#endif

#ifndef LIBRARY_ONLY
  {
    int c;
    while (1)
    {
			c = getopt(argc, argv, "mt:?#:v");
			if (c == -1)
				break;
			switch (c){
			case 'v':
				global_verbose_flag=1;
				break;
			case 'm':
		#ifdef MPI
				global_conpar_type = CONPAR_MPI;
				global_setubv_type = SETUBV_MPI;
				break;
		#endif
				scheme_not_supported_error("mpi");
				break;
			case 't':
		#ifdef PTHREADS
				if(strcmp(optarg,"setubv")==0) {
					global_setubv_type = SETUBV_PTHREADS;
				}
				else if(strcmp(optarg,"conpar")==0) {
					global_conpar_type = CONPAR_PTHREADS;
				}
				else if(strcmp(optarg,"reduce")==0) {
					global_conpar_type = REDUCE_PTHREADS;
				}
				else if(strcmp(optarg,"all")==0) {
					global_conpar_type = CONPAR_PTHREADS;
					global_setubv_type = SETUBV_PTHREADS;
					global_reduce_type = REDUCE_PTHREADS;
				}
				else {
					EXTERNAL_LIBRARY_FPRINTF_STDERR("Unknown type for threads '%s'.  Using 'all'\n",optarg);
					global_conpar_type = CONPAR_PTHREADS;
					global_setubv_type = SETUBV_PTHREADS;
				}
				break;
		#endif
				scheme_not_supported_error("threads");
				break;
			case '#':
				global_num_procs=atoi(optarg);
				break;
			case '?':
				options();
				EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
				break;
			default:
				EXTERNAL_LIBRARY_PRINTF("?? getopt returned character code 0%o ??\n", c);
				options();
				EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
			}
		} // while
  } // scope
#endif

#ifdef MPI
  {
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int myid,namelen;
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Get_processor_name(processor_name,&namelen);
    if(global_verbose_flag) {
      EXTERNAL_LIBRARY_FPRINTF_STDERR("Process %d on %s with pid %ld\n",
	      myid, processor_name, (long int)getpid());
    }
    if(myid!=0) {
      global_conpar_type = CONPAR_MPI;
      global_setubv_type = SETUBV_MPI;
      mpi_worker();
    }
  }    
#endif    
  /* Initialization : */

  iap.mynode = mynode();
  iap.numnodes = numnodes();
  if (iap.numnodes > 1) {
    iap.parallel_flag = 1;
  } else {
    iap.parallel_flag = 0;
  }


  while(1){
    time_start(&time0);
    time_start(&time1);
    /* NOTE:  thu is allocated inside this function, and the
       pointer is passed back.  I know this is ugly, but
       this function does a bit of work to get thu setup correctly,
       as well as figuring out the size the array should be.
       What really should happen is to have one function which
       reads fort.2 and another fuction which initializes the array.
       That way the allocation could happen between the two calles.
    */
    {
      logical eof;
      init(&iap, &rap, par, icp, thl, &thu, &iuz, &vuz, &eof);
      
      if (eof) {
	break;
      }
    }

    /* Find restart label and determine type of restart point. */
    if (iap.irs > 0) {
      logical found = FALSE_;

      findlb(&iap, &rap, iap.irs, &(iap.nfpr), &found);
      if (! found) {
	if (iap.mynode == 0) {
	  EXTERNAL_LIBRARY_FPRINTF_STDERR("\nRestart label %4ld not found\n",iap.irs);
	}
	EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
      }
    }
#ifdef MPI
    
    if(global_setubv_type==SETUBV_MPI) {
      /* A few words about what is going on here.  ips, irs, isw, itp, and
	 nfpr are used to choose which functions are used for funi, icni, bcni, etc.
	 unfortunately, their values are changed in init1 and chdim.  In the
	 old version of AUTO the functions were already choosen by the point
	 these values were modified, so there was no problem.  Now, in the
	 message passing parallel version, the workers need both versions, since
	 they both need to select the appropriate functions (using the old values)
	 and actually compute (using the new values).  */
      int comm_size,i;
      integer funi_icni_params[5];
      MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
      funi_icni_params[0]=iap.ips;
      funi_icni_params[1]=iap.irs;
      funi_icni_params[2]=iap.isw;
      funi_icni_params[3]=iap.itp;
      funi_icni_params[4]=iap.nfpr;
      for(i=1;i<comm_size;i++){
	/*Send message to get worker into init mode*/
	{
	  int message=AUTO_MPI_INIT_MESSAGE;
	  MPI_Send(&message,1,MPI_INT,i,0,MPI_COMM_WORLD);
	}
      }
      MPI_Bcast(funi_icni_params,5,MPI_LONG,0,MPI_COMM_WORLD);
    }
#endif
    set_function_pointers(iap,&list);
    init1(&iap, &rap, icp, par);
    chdim(&iap);

    /* Create the allocations for the global structures used in 
       autlib3.c and autlib5.c.  These are purely an efficiency thing.
       The allocation and deallocation of these scratch areas takes
       up a nontrivial amount of time if done directly in the
       wrapper functions in autlib3.c*/
    allocate_global_memory(iap);

    /* ---------------------------------------------------------- */
    /* ---------------------------------------------------------- */
    /*  One-parameter continuations */
    /* ---------------------------------------------------------- */
    /* ---------------------------------------------------------- */

#ifdef AUTO_CONSTRUCT_DESTRUCT
    user_construct(argc,argv);
#endif
#ifdef USAGE
    usage_end(init_usage,"main initialization");
#endif
    
    if(list.type==AUTOAE)
      autoae(&iap, &rap, par, icp, list.aelist.funi, list.aelist.stpnt, list.aelist.pvli, thl, thu, iuz, vuz);
    if(list.type==AUTOBV)
      autobv(&iap, &rap, par, icp, list.bvlist.funi, list.bvlist.bcni, 
	     list.bvlist.icni, list.bvlist.stpnt, list.bvlist.pvli, thl, thu, iuz, vuz);

#ifdef USAGE
    usage_end(total_usage,"total");

#endif
    if(fp9 != NULL)
			time_end(time0,"Total Time ",fp9);
    fp9_printf("----------------------------------------------");
    fp9_printf("----------------------------------------------\n");
    time_end(time1,"",fp6);
#ifdef AUTO_CONSTRUCT_DESTRUCT
    user_destruct();
#endif


  }
#ifdef MPI
  {
    int message = AUTO_MPI_KILL_MESSAGE;
    int size,i;
    MPI_Comm_size(MPI_COMM_WORLD,&size);
    for(i=1;i<size;i++)
      MPI_Send(&message,1,MPI_INT,i,0,MPI_COMM_WORLD);
  }

  MPI_Finalize();
#endif

	free(icp);
	free(par);
	free(thl);

	if(thu != 0)
		free(thu);
  if(iuz != 0)
		free(iuz);
  if(vuz != 0)
		free(vuz);

	// close files
	fclose(fp2); fp2 = NULL;
	fclose(fp3); fp3 = NULL;
#ifdef LIBRARY_ONLY
  if(fp6 != stdout)
		fclose(fp6);
	fp6 = NULL;
#else
	fp6 = stdout;
#endif
  if(fp7 != NULL)
	{
		fclose(fp7);
		fp7 = NULL;
	}
  if(fp8 != NULL)
	{
		fclose(fp8);
		fp8 = NULL;
	}
	if(fp9 != NULL)
	{
		fclose(fp9);
		fp9 = NULL;
	}

	auto_progress = 1.0;

  return 0;
} 

END_AUTO_NAMESPACE;

#ifndef LIBRARY_ONLY /* @@edc: compiling in main will be an option now */
int main(int argc,char *argv[])
{
#ifdef __cplusplus
using LibAuto::AUTO_main;
#endif
	return AUTO_main(argc, argv);
}
#endif




See more files for this project here

Oscill8

Oscill8 is a suite of tools for analyzing dynamical systems which concentrates on understanding how the dynamical behavior depends on the parameters using bifurcation theory and reaction network theory.

Project homepage: http://sourceforge.net/projects/oscill8
Programming language(s): C,C#,C++
License: other

  libf2c/
    cabs.cpp
    d_imag.cpp
    d_lg10.cpp
    d_sign.cpp
    i_dnnt.cpp
    i_nint.cpp
    pow_dd.cpp
    pow_di.cpp
    pow_ii.cpp
    r_lg10.cpp
    z_abs.cpp
    z_exp.cpp
    z_log.cpp
  Doxyfile
  ReadMe.txt
  autlib1.cpp
  autlib2.cpp
  autlib3.cpp
  autlib4.cpp
  autlib5.cpp
  auto.h
  auto.vcproj
  auto_api.cpp
  auto_api.h
  auto_c.h
  auto_f2c.h
  auto_mpi.h
  auto_types.h
  conpar.cpp
  dmatrix.cpp
  eispack.cpp
  main.cpp
  reduce.cpp
  setubv.cpp