/* []----------------------------------------[] | Bionc.inc | []----------------------------------------[] | | | AUTHOR: MFSomers 2005. | | USE: All boinc stuff for main | | code ready to be | | included if needed ... | | | []----------------------------------------[] */ // Copyright (C) 2005 M.F. Somers, Theoretical Chemistry Department, Leiden University // // This is free software; you can redistribute it and/or modify it under the terms of // the GNU General Public License as published by the Free Software Foundation. // // http://www.gnu.org/licenses/gpl.txt // system specific BOINC includes #if defined(__linux__) #elif defined(_WIN32) || defined(WIN32) # include "boinc_win.h" #elif defined(__APPLE__) #elif defined(FREEBSD) #else # error No BOINC support for this platform ... #endif // general BOINC includes #include "diagnostics.h" #include "boinc_api.h" #include "filesys.h" #include "util.h" #include "version.h" // BOINC graphical includes #if defined(USE_BOINC_GRAPH_API) // system specific BOINC graphical includes # if defined(__linux__) # include "glut.h" # elif defined(_WIN32) || defined(WIN32) # elif defined(__APPLE__) && defined(__MACH__) # include # elif defined(__APPLE__) # include "glut.h" # elif defined(FREEBSD) # include "glut.h" # else # error No GRAPHICAL BOINC support for this platform ... # endif # include "graphics_api.h" #endif /* ----------------------------------------------------------------------- */ #define CHECK_POINT_FILE "chckpnt.dat" char CheckPointFileName[ 256 ]; FILE *CheckPointFilePointer = NULL; /* ----------------------------------------------------------------------- */ unsigned int HashTheString( char *String ) { unsigned int Hash, i; Hash = 0; if( String != NULL ) for( i = 0; i < strlen( String ); ++i ) Hash += String[ i ] ^ Hash - i; return( Hash ); } /* ----------------------------------------------------------------------- */ int TryAndReadCheckPointFile( void ) { double StartTime, TheAccumulatedTotalKineticEnergy, TheAccumulatedTotalInteractionPotential, TheAccumulatedTemperature, TheAccumulatedPressure, TheAutoSnapshotTimeStep, TheNextAutoSnapshotTime, MaxStepSizeConformation, AccuracyConformation; unsigned int TotalNrOfStepsDone, TheNrOfAutoSnapshots; unsigned long TheRandomNumberState; int TheDoConformation, TheDoDynamics, MaxStepsConformation; int Line = 0; // try and open the checkpoint file ... boinc_resolve_filename( CHECK_POINT_FILE, CheckPointFileName, sizeof( CheckPointFileName ) ); CheckPointFilePointer = boinc_fopen( CheckPointFileName, "rt" ); if( CheckPointFilePointer == NULL ) return( 1 ); Line += fscanf( CheckPointFilePointer, "StartTime %le\n", &StartTime ); Line += fscanf( CheckPointFilePointer, "TotalNrOfStepsDone %u\n", &TotalNrOfStepsDone ); Line += fscanf( CheckPointFilePointer, "TheAccumulatedTotalKineticEnergy %le\n", &TheAccumulatedTotalKineticEnergy ); Line += fscanf( CheckPointFilePointer, "TheAccumulatedTotalInteractionPotential %le\n", &TheAccumulatedTotalInteractionPotential ); Line += fscanf( CheckPointFilePointer, "TheAccumulatedTemperature %le\n", &TheAccumulatedTemperature ); Line += fscanf( CheckPointFilePointer, "TheAccumulatedPressure %le\n", &TheAccumulatedPressure ); Line += fscanf( CheckPointFilePointer, "TheRandomNumberState %lu\n", &TheRandomNumberState ); Line += fscanf( CheckPointFilePointer, "TheAutoSnapshotTimeStep %le\n", &TheAutoSnapshotTimeStep ); Line += fscanf( CheckPointFilePointer, "TheNextAutoSnapshotTime %le\n", &TheNextAutoSnapshotTime ); Line += fscanf( CheckPointFilePointer, "TheNumberOfAutoSnapshotTimes %u\n", &TheNrOfAutoSnapshots ); Line += fscanf( CheckPointFilePointer, "DoConformation %d\n", &TheDoConformation ); Line += fscanf( CheckPointFilePointer, "DoDynamics %d\n", &TheDoDynamics ); Line += fscanf( CheckPointFilePointer, "MaxStepSizeConformation %le\n", &MaxStepSizeConformation ); Line += fscanf( CheckPointFilePointer, "AccuracyConformation %le\n", &AccuracyConformation ); Line += fscanf( CheckPointFilePointer, "MaxStepsConformation %u\n\n", &MaxStepsConformation ); if( Line != 15 ) { fclose( CheckPointFilePointer ); return( 1 ); } if( !ReadDataFromFile( CheckPointFileName, TheInputData, Line, CheckPointFilePointer ) ) { fclose( CheckPointFilePointer ); return( 1 ); } fclose( CheckPointFilePointer ); Dynamics = SetupDynamics( TheInputData ); if( Dynamics == NULL ) { DeleteTheData( TheInputData ); return( 1 ); } Dynamics -> StartTime = StartTime; Dynamics -> TotalNrOfStepsDone = TotalNrOfStepsDone; Dynamics -> TheAccumulatedTotalKineticEnergy = TheAccumulatedTotalKineticEnergy; Dynamics -> TheAccumulatedTotalInteractionPotential = TheAccumulatedTotalInteractionPotential; Dynamics -> TheAccumulatedTemperature = TheAccumulatedTemperature; Dynamics -> TheAccumulatedPressure = TheAccumulatedPressure; TheInputData.AutoSnapShotTimeStep = TheAutoSnapshotTimeStep; TheInputData.NextAutoSnapShotTime = TheNextAutoSnapshotTime; TheInputData.NrOfAutoSnapshotsToTake = TheNrOfAutoSnapshots; TheInputData.DoConformation = TheDoConformation; TheInputData.DoDynamics = TheDoDynamics; TheInputData.MaxStepSizeConformation = MaxStepSizeConformation; TheInputData.AccuracyConformation = AccuracyConformation; TheInputData.MaxStepsConformation = MaxStepsConformation; SRand( TheRandomNumberState ); return( 0 ); } /* ----------------------------------------------------------------------- */ void CreateCheckPointFile( void ) { boinc_resolve_filename( CHECK_POINT_FILE, CheckPointFileName, sizeof( CheckPointFileName ) ); CheckPointFilePointer = boinc_fopen( CheckPointFileName, "wt" ); if( CheckPointFilePointer == NULL ) return; fprintf( CheckPointFilePointer, "StartTime %.20le\n", Dynamics -> StartTime ); fprintf( CheckPointFilePointer, "TotalNrOfStepsDone %u\n", Dynamics -> TotalNrOfStepsDone ); fprintf( CheckPointFilePointer, "TheAccumulatedTotalKineticEnergy %.20le\n", Dynamics -> TheAccumulatedTotalKineticEnergy ); fprintf( CheckPointFilePointer, "TheAccumulatedTotalInteractionPotential %.20le\n", Dynamics -> TheAccumulatedTotalInteractionPotential ); fprintf( CheckPointFilePointer, "TheAccumulatedTemperature %.20le\n", Dynamics -> TheAccumulatedTemperature ); fprintf( CheckPointFilePointer, "TheAccumulatedPressure %.20le\n", Dynamics -> TheAccumulatedPressure ); fprintf( CheckPointFilePointer, "TheRandomNumberState %lu\n", GRand() ); fprintf( CheckPointFilePointer, "TheAutoSnapshotTimeStep %.20le\n", TheInputData.AutoSnapShotTimeStep ); fprintf( CheckPointFilePointer, "TheNextAutoSnapshotTime %.20le\n", TheInputData.NextAutoSnapShotTime ); fprintf( CheckPointFilePointer, "TheNumberOfAutoSnapshotTimes %u\n", TheInputData.NrOfAutoSnapshotsToTake ); fprintf( CheckPointFilePointer, "DoConformation %d\n", TheInputData.DoConformation ); fprintf( CheckPointFilePointer, "DoDynamics %d\n", TheInputData.DoDynamics ); fprintf( CheckPointFilePointer, "MaxStepSizeConformation %.20le\n", TheInputData.MaxStepSizeConformation ); fprintf( CheckPointFilePointer, "AccuracyConformation %.20le\n", TheInputData.AccuracyConformation ); fprintf( CheckPointFilePointer, "MaxStepsConformation %u\n\n", TheInputData.MaxStepsConformation ); // now copy the final state into the InputDataType for a possible restart dynamics run StoreFinalState( TheInputData, Dynamics -> GetFinalStateParticlesPointer(), 1 ); TheInputData.TimeStep = Dynamics -> MaxTimeStep; TheInputData.Time = Dynamics -> Time; TheInputData.EndTime = Dynamics -> EndTime; TheInputData.TheBox = Dynamics -> TheBox; TheInputData.AccuracyEnergy = Dynamics -> Accuracy; TheInputData.Periodicity = Dynamics -> Periodicity; TheInputData.ConstantTemperature = Dynamics -> ConstantTemperature; TheInputData.BoltzmannConstant = Dynamics -> BoltzmannConstant; TheInputData.TargetTemperature = Dynamics -> TargetTemperature; TheInputData.TemperatureReScaleTime = Dynamics -> TemperatureReScaleTime; WriteDataToFile( CheckPointFileName, TheInputData, CheckPointFilePointer ); fclose( CheckPointFilePointer ); fflush( NULL ); } /* ----------------------------------------------------------------------- */ void BOINC_DoTheWork( void ) { int BOINC_return; APP_INIT_DATA BoincInitData; // get initial data from boinc to get work-unit name boinc_get_init_data( BoincInitData ); // now initialize random number generators with hash value of work-unit name SRand( HashTheString( BoincInitData.wu_name ) ); // first redirect stdout and sterr if needed to files if( StdOutFileName[ 0 ] ) { BOINC_return = boinc_resolve_filename( StdOutFileName, StdOutFileName, sizeof( StdOutFileName ) ); StdOutFilePointer = boinc_fopen( StdOutFileName, "at" ); if( StdOutFilePointer == NULL ) { fprintf( stderr, "Error opening stdout filename !\n" ); exit( boinc_finish( 1 ) ); } } else StdOutFilePointer = stdout; if( StdErrFileName[ 0 ] ) { BOINC_return = boinc_resolve_filename( StdErrFileName, StdErrFileName, sizeof( StdErrFileName ) ); StdErrFilePointer = boinc_fopen( StdErrFileName, "at" ); if( StdErrFilePointer == NULL ) { fprintf( stderr, "Error opening stderr filename !\n" ); exit( boinc_finish( 1 ) ); } } else StdErrFilePointer = stderr; BOINC_return = boinc_resolve_filename( OutputFileName, OutputFileName, sizeof( OutputFileName ) ); OutputFilePointer = boinc_fopen( OutputFileName, "at" ); if( OutputFilePointer == NULL ) { fprintf( stderr, "Error opening output file !\n" ); fclose( InputFilePointer ); exit( boinc_finish( 1 ) ); } if( ( BOINC_return = TryAndReadCheckPointFile() ) ) { // then redirect input and output filenames BOINC_return = boinc_resolve_filename( InputFileName, InputFileName, sizeof( InputFileName ) ); InputFilePointer = boinc_fopen( InputFileName, "rt" ); if( InputFilePointer == NULL ) { fprintf( stderr, "Error opening input file !\n" ); exit( boinc_finish( 1 ) ); } // then read from redirected input and output files BOINC_return = ReadInputDoConformationSearchAndSetupDynamics(); // create first check point data CreateCheckPointFile(); fclose( InputFilePointer ); } fflush( NULL ); if( !BOINC_return & ( TheInputData.DoDynamics > 0 ) ) { // and start running the trajectory, quietly... we are the worker thread ... while( !Dynamics -> StopTrajectory ) { #if defined(USE_BOINC_GRAPH_API) if( OpenGL_DynamicsRunning ) DoSomeOfTheWork( Dynamics ); #else DoSomeOfTheWork( Dynamics ); #endif boinc_fraction_done( ( Dynamics -> Time - Dynamics -> StartTime ) / ( Dynamics -> EndTime - Dynamics -> StartTime ) ); if( boinc_time_to_checkpoint() ) // and do checkpoint if we need to... { CreateCheckPointFile(); boinc_checkpoint_completed(); } } // finally dump the stuff to the redirected output file DumpFinalStateAndCleanup( Dynamics, TheInputData, 1 ); } // close open files fclose( OutputFilePointer ); if( StdOutFileName[ 0 ] ) fclose( StdOutFilePointer ); // only close if they have been redirected ... if( StdErrFileName[ 0 ] ) fclose( StdErrFilePointer ); // and finish boinc exit( boinc_finish( 0 ) ); } /* ----------------------------------------------------------------------- */ #if defined(USE_BOINC_GRAPH_API) // we need to redefine the trigger for boinc, cause it's slower than glut #if defined(OPENGL_MOUSE_TRIGGER) # undef OPENGL_MOUSE_TRIGGER #endif #define OPENGL_MOUSE_TRIGGER 1 int BOINC_CurrentMouseXPos, BOINC_CurrentMouseYPos, BOINC_LeftMouseButtonPressed, BOINC_RightMouseButtonPressed = 0; /* ----------------------------------------------------------------------- */ /* Called by main program to setup boinc rendering if needed */ void SetupBoincRendering( int argc, char *argv[] ) { int BOINC_return; BOINC_return = boinc_init_diagnostics( BOINC_DIAG_REDIRECTSTDERR | BOINC_DIAG_REDIRECTSTDOUT ); if( BOINC_return ) exit( BOINC_return ); BOINC_return = boinc_init_graphics( &BOINC_DoTheWork ); if( BOINC_return ) { fprintf( stderr, "Error calling boinc_init_graphics !\n" ); exit( BOINC_return ); } } /* ----------------------------------------------------------------------- */ /* Called to render the current scene when usiong graphical BOINC */ void BOINC_DoRenderCurrentScene( void ) { if( Conformation != NULL ) if( Conformation -> GetFinalStateParticlesPointer() != NULL ) RenderOpenGLScene( Conformation -> GetFinalStateParticlesPointer(), TheInputData.Colors, TheInputData.TheBox, TheInputData.Periodicity ); if( Dynamics != NULL ) if( Dynamics -> GetFinalStateParticlesPointer() != NULL ) RenderOpenGLScene( Dynamics -> GetFinalStateParticlesPointer(), TheInputData.Colors, TheInputData.TheBox, TheInputData.Periodicity ); } /* ----------------------------------------------------------------------- */ /* Called when the screen is resized */ void app_graphics_resize( int Width, int Height ) { ResizeOpenGLScene( Width, Height, TheInputData.TheBox ); BOINC_DoRenderCurrentScene(); } /* ----------------------------------------------------------------------- */ /* Called when to render the scene */ void app_graphics_render( int X, int Y, double TimeOfDay ) { BOINC_DoRenderCurrentScene(); } /* ----------------------------------------------------------------------- */ /* Called at graphical setup */ void app_graphics_init( void ) { SetupOpenGLScene( 1, 1, TheInputData.TheBox ); BOINC_DoRenderCurrentScene(); } /* ----------------------------------------------------------------------- */ /* Called when preferences change */ void app_graphics_reread_prefs( void ) { } /* ----------------------------------------------------------------------- */ /* Called when mouse is moved */ void boinc_app_mouse_move( int MousePosX, int MousePosY, int LeftButton, int MiddleButton, int RightButton ) { int dX = MousePosX - BOINC_CurrentMouseXPos; int dY = MousePosY - BOINC_CurrentMouseYPos; int HasBeenUpdated = 0; int dPhi, dTheta, dZoom; dPhi = dTheta = dZoom = 0; if( LeftButton ) { // check if moving mouse to the left if( dX < -OPENGL_MOUSE_TRIGGER ) { --dPhi; HasBeenUpdated = 1; } // check if moving mouse to the right if( dX > OPENGL_MOUSE_TRIGGER ) { ++dPhi; HasBeenUpdated = 1; } // check if moving mouse upwards if( dY < -OPENGL_MOUSE_TRIGGER ) { --dTheta; HasBeenUpdated = 1; } // check if moving mouse downwards if( dY > OPENGL_MOUSE_TRIGGER ) { ++dTheta; HasBeenUpdated = 1; } } if( RightButton ) { // check if moving mouse upwards if( dY < -OPENGL_MOUSE_TRIGGER ) { --dZoom; HasBeenUpdated = 1; } // check if moving mouse downwards if( dY > OPENGL_MOUSE_TRIGGER ) { ++dZoom; HasBeenUpdated = 1; } } if( HasBeenUpdated ) { OpenGL_ModelOrientationPhi += ( double )( dPhi ) * OPENGL_DELTA_ANGLE; OpenGL_ModelOrientationTheta += ( double )( dTheta ) * OPENGL_DELTA_ANGLE; OpenGL_ModelOrientationZoomF += ( double )( dZoom ) * OPENGL_DELTA_ZOOM; ChangeViewPointOfOpenGLScene( OpenGL_ModelOrientationPhi, OpenGL_ModelOrientationTheta, OpenGL_ModelOrientationZoomF ); BOINC_DoRenderCurrentScene(); } if( ( !RightButton ) || ( !LeftButton ) ) { BOINC_CurrentMouseXPos = MousePosX; BOINC_CurrentMouseYPos = MousePosY; } } /* ----------------------------------------------------------------------- */ /* Called when button is hit */ void boinc_app_mouse_button( int X, int Y, int Which, int IsDown ) { } /* ----------------------------------------------------------------------- */ /* Called on key press */ void boinc_app_key_press( int Key1, int Key2 ) { // stop rendering for a while and take snap-shot of current situation if( boinc_is_standalone() ) { if( OpenGL_DynamicsRunning && Dynamics != NULL ) DumpFinalStateAndCleanup( Dynamics, TheInputData, 0 ); OpenGL_DynamicsRunning = !OpenGL_DynamicsRunning; } } /* ----------------------------------------------------------------------- */ /* Called when key released */ void boinc_app_key_release( int Key1, int Key2 ) { } #else /* ----------------------------------------------------------------------- */ /* Called by main program to setup non-graphical boinc environment */ void SetupBoinc( int argc, char *argv[] ) { int BOINC_return; BOINC_return = boinc_init_diagnostics( BOINC_DIAG_REDIRECTSTDERR | BOINC_DIAG_REDIRECTSTDOUT ); if( BOINC_return ) exit( BOINC_return ); // init boinc environment BOINC_return = boinc_init(); // Do the work BOINC_DoTheWork(); } #endif