#define RCSID "$Id: Main.c,v 1.62 2006/03/11 17:55:01 geuzaine Exp $"
/*
* Copyright (C) 1997-2006 P. Dular, C. Geuzaine
*
* This program 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to <getdp@geuz.org>.
*/
#include <signal.h>
#include <time.h>
#include "GetDP.h"
#include "Init_Problem.h"
#include "Print_ProblemStructure.h"
#include "LinAlg.h"
#include "Magic.h"
#include "Numeric.h"
#include "GmshClient.h"
#include "OS.h"
extern FILE *yyin ;
long int yylinenum = 0 ;
int yycolnum = 0, yyincludenum = 0 ;
char yyname[MAX_FILE_NAME_LENGTH] = "", yyincludename[MAX_FILE_NAME_LENGTH];
int yyparse(void) ;
int yyrestart(FILE*) ;
int GetDP_CurrentStackIndex = 0 ;
char *GetDP_CurrentFunction[GETDP_DEBUG_STACK_SIZE] ;
char *GetDP_CurrentSourceFile[GETDP_DEBUG_STACK_SIZE] ;
int GetDP_CurrentSourceLine[GETDP_DEBUG_STACK_SIZE] ;
FILE *PostStream, *LogStream, *PrintStream ;
List_T *GeoData_L, *PreResolutionIndex_L ;
struct Problem Problem_S ;
struct Expression *Problem_Expression0 ;
struct CurrentData Current ;
struct PostProcessing InteractivePostProcessing_S ;
struct PostSubOperation InteractivePostSubOperation_S ;
int TreatmentStatus;
int ErrorLevel, InteractiveLevel = 0;
int InteractiveCompute, InteractiveInterrupt = 0 ;
int Flag_PRE, Flag_PAR, Flag_CAL, Flag_POS, Flag_IPOS, Flag_XDATA;
int Flag_CHECK, Flag_LRES, Flag_LPOS, Flag_LIPOS, Flag_I;
int Flag_RESTART, Flag_LOG, Flag_VERBOSE, Flag_BIN, Flag_PROGRESS ;
int Flag_FMM, Flag_DTA ;
int Flag_SPLIT, Flag_SOCKET ;
double Flag_ORDER ;
char Name_Generic[MAX_FILE_NAME_LENGTH], Name_Path[MAX_FILE_NAME_LENGTH] ;
char *Name_Resolution ;
char *Name_PostProcessing[NBR_MAX_POS], *Name_PostOperation[NBR_MAX_POS] ;
char *Name_MshFile, *Name_ResFile[NBR_MAX_RES], *Name_AdaptFile ;
int Flag_RemoveSingularity = 0;
/* ------------------------------------------------------------------------ */
/* m a i n */
/* ------------------------------------------------------------------------ */
#if defined(HAVE_BLACKBOX)
#include "MainBlackBox.c"
#else
int main(int argc, char *argv[]) {
char **sargv;
int sargc, i, choose = 1 ;
char Name_ProFile[MAX_FILE_NAME_LENGTH], Name_LogFile[MAX_FILE_NAME_LENGTH] ;
time_t now;
GetDP_Begin("main");
/* handle some signals FIXME: could not make this work on IRIX */
#if !defined(__sgi__)
signal(SIGFPE, Signal); /* Floating-point exception (ANSI). */
signal(SIGSEGV, Signal); /* Segmentation violation (ANSI). */
signal(SIGINT, Signal); /* Interrupt (ANSI). */
#endif
/* init MPI for multi-processor jobs */
LinAlg_Initialize(&argc, &argv, &Current.NbrCpu, &Current.RankCpu);
/* no arguments on command line */
if(argc < 2) Info(0, argv[0]);
/* process getdp options, save unused options in sargv */
sargv = (char**)Malloc(256*sizeof(char**));
Init_GlobalVariables() ;
Get_Options(argc, argv, &sargc, sargv, Name_ProFile, Name_Generic, Name_Path) ;
/* log file */
if(Flag_LOG){
strcpy(Name_LogFile, Name_Generic) ;
strcat(Name_LogFile, ".log") ;
if(!(LogStream = fopen(Name_LogFile, "w+"))){
Flag_LOG = 0;
Msg(WARNING, "Unable to open file '%s'", Name_LogFile) ;
}
else{
time(&now);
fprintf(LogStream, "%s", ctime(&now));
}
}
/* unused options */
if(sargc > 1){
Msg(INFO1, "Passing unused options to solver: '") ;
for(i = 1 ; i < sargc ; i++) {
if(i != 1) Msg(INFO2, " ") ;
Msg(INFO2, "%s", sargv[i]) ;
}
Msg(INFO3, "'") ;
}
/* default .res file */
if(!Name_ResFile[0]){
Name_ResFile[0] = (char*)Malloc((strlen(Name_Generic)+5)*sizeof(char)) ;
strcpy(Name_ResFile[0], Name_Generic) ;
strcat(Name_ResFile[0], ".res") ;
Name_ResFile[1] = NULL ;
}
/* default .msh file */
if(!Name_MshFile){
Name_MshFile = (char*)Malloc((strlen(Name_Generic)+5)*sizeof(char)) ;
strcpy(Name_MshFile, Name_Generic) ;
strcat(Name_MshFile, ".msh") ;
}
/* check GSL version */
check_gsl();
/* Solver init */
LinAlg_InitializeSolver(&sargc, &sargv, &Current.NbrCpu, &Current.RankCpu) ;
/* fill-in problem structure (read pro files) */
Init_ProblemStructure();
Read_ProblemStructure(Name_ProFile) ;
/* check available resources (stack size, etc.) */
CheckResources();
/* process */
Problem_Expression0 = (Problem_S.Expression)?
(struct Expression*)List_Pointer(Problem_S.Expression, 0) : NULL ;
if (!Flag_PRE && !Flag_PAR && !Flag_CAL && !Flag_POS && !Flag_CHECK && !Flag_I){
Flag_LRES = Flag_LPOS = 1 ;
choose = 0 ;
}
if (Flag_I) Pos_Interactive(NULL, NULL) ;
if (Flag_CHECK) Print_ProblemStructure(&Problem_S) ;
if (Flag_LRES) Print_ListResolution(choose, &Problem_S) ;
if (Flag_LPOS) Print_ListPostOperation(choose, &Problem_S) ;
if (Flag_LIPOS) Print_ListPostProcessing(choose, &Problem_S) ;
if (Flag_PRE || Flag_PAR || Flag_CAL || Flag_POS) SolvingAnalyse() ;
/* finalize the solver */
LinAlg_FinalizeSolver() ;
/* end */
Msg(DIRECT, "E n d");
if(Flag_LOG){
time(&now);
fprintf(LogStream, "%s", ctime(&now));
fclose(LogStream);
}
/* finalize MPI job */
LinAlg_Finalize() ;
/* close socket */
if(Flag_SOCKET>0){
Gmsh_SendString(Flag_SOCKET, GMSH_CLIENT_STOP, "Goodbye!");
Gmsh_Disconnect(Flag_SOCKET);
}
GetDP_Return(0) ;
}
#endif
/* ------------------------------------------------------------------------ */
/* I n i t _ G l o b a l V a r i a b l e s */
/* ------------------------------------------------------------------------ */
void Init_GlobalVariables(void){
GetDP_Begin("Init_GlobalVariables");
Flag_PRE = 0 ; Flag_CAL = 0 ; Flag_POS = 0 ; Flag_IPOS = 0 ;
Flag_CHECK = 0 ; Flag_XDATA = 0 ; Flag_RESTART = 0 ; Flag_BIN = 0 ;
Flag_LRES = 0 ; Flag_LPOS = 0 ; Flag_LIPOS = 0 ; Flag_PAR = 0;
Flag_LOG = 0 ; Flag_VERBOSE = 4 ; Flag_PROGRESS = 10 ; Flag_SPLIT = 0 ;
Flag_ORDER = -1. ; Flag_FMM = 0 ; Flag_DTA = 0 ; Flag_SOCKET = -1 ; Flag_I = 0 ;
Name_Resolution = Name_PostProcessing[0] = Name_PostOperation[0] = NULL ;
Name_MshFile = Name_ResFile[0] = Name_AdaptFile = NULL ;
PostStream = PrintStream = stdout ;
GetDP_End ;
}
/* ------------------------------------------------------------------------ */
/* I n i t _ P r o b l e m S t r u c t u r e */
/* ------------------------------------------------------------------------ */
void Init_ProblemStructure(void){
GetDP_Begin("Init_ProblemStructure");
Problem_S.Expression = NULL ;
Problem_S.Group = NULL ;
Problem_S.Constraint = NULL ;
Problem_S.JacobianMethod = NULL ;
Problem_S.IntegrationMethod = NULL ;
Problem_S.FunctionSpace = NULL ;
Problem_S.Formulation = NULL ;
Problem_S.Resolution = NULL ;
Problem_S.PostProcessing = NULL ;
Problem_S.PostOperation = NULL ;
Problem_S.FMMGroup = NULL ;
GetDP_End ;
}
/* ------------------------------------------------------------------------ */
/* G e t _ O p t i o n s */
/* ------------------------------------------------------------------------ */
int Get_Options(int argc, char *argv[], int *sargc, char **sargv,
char *Name_ProFile, char *Name_Generic, char *Name_Path) {
int i, j, Flag_TmpLOG = 0, Flag_NameProblem = 0 ;
char pid[32];
GetDP_Begin("Get_Options");
strcpy(Name_ProFile, "") ;
strcpy(Name_Generic, "") ;
i = *sargc = 1 ;
while (i < argc) {
if (argv[i][0] == '-') {
if (!strcmp(argv[i]+1, "cal")) { Flag_CAL = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "check")) { Flag_CHECK = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "i")) { Flag_I = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "xdata")) { Flag_XDATA = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "quiet")) { Flag_VERBOSE = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "silent")) { Flag_VERBOSE = 0 ; i++ ; }
else if (!strcmp(argv[i]+1, "log")) { Flag_TmpLOG = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "nolog")) { Flag_TmpLOG = 0 ; i++ ; }
else if (!strcmp(argv[i]+1, "debug")) { Flag_VERBOSE = 99 ; i++ ; }
else if (!strcmp(argv[i]+1, "bin")) { Flag_BIN = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "ascii")) { Flag_BIN = 0 ; i++ ; }
else if (!strcmp(argv[i]+1, "split")) { Flag_SPLIT = 1 ; i++ ; }
else if (!strcmp(argv[i]+1, "socket")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
Flag_SOCKET = Gmsh_Connect(argv[i]) ;
if(Flag_SOCKET == -1)
Msg(GERROR, "Couldn't create socket %s", argv[i]);
else if(Flag_SOCKET == -2)
Msg(GERROR, "Couldn't connect to socket %s", argv[i]);
else if(Flag_SOCKET == -3)
Msg(GERROR, "No such host %s", argv[i]);
else if(Flag_SOCKET == -4)
Msg(GERROR, "Couldn't initialize Windows sockets");
else{
sprintf(pid, "%d", GetProcessId());
Gmsh_SendString(Flag_SOCKET, GMSH_CLIENT_START, pid);
}
i++ ;
}
else {
Msg(GERROR, "Missing socket name");
}
}
else if (!strcmp(argv[i]+1, "restart")){
/* Flag_PRE johan */
Flag_PAR = 0 ; Flag_CAL = Flag_RESTART = 1 ; i++ ;
}
else if (!strcmp(argv[i]+1, "verbose") ||
!strcmp(argv[i]+1, "v")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
Flag_VERBOSE = atoi(argv[i]) ; i++ ;
}
else {
Msg(GERROR, "Missing number");
}
}
else if (!strcmp(argv[i]+1, "help") || !strcmp(argv[i]+1, "h") ||
!strcmp(argv[i]+1, "-help") || !strcmp(argv[i]+1, "-h")) {
Info(0, argv[0]);
}
else if (!strcmp(argv[i]+1, "version") ||
!strcmp(argv[i]+1, "-version")) {
Info(1, argv[0]);
}
else if (!strcmp(argv[i]+1, "info") ||
!strcmp(argv[i]+1, "-info")) {
Info(2, argv[0]);
}
else if (!strcmp(argv[i]+1, "progress") ||
!strcmp(argv[i]+1, "p")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
Flag_PROGRESS = atoi(argv[i]) ; i++ ;
}
else {
Msg(GERROR, "Missing number");
}
}
else if (!strcmp(argv[i]+1, "pre")) {
i++ ;
if (i<argc && argv[i][0]=='#') {
Flag_PRE = 1 ; Flag_LRES = -atoi(argv[i]+1) ; i++ ;
}
else if (i<argc && argv[i][0]!='-') {
Flag_PRE = 1 ; Name_Resolution = argv[i] ; i++ ;
}
else {
Flag_PRE = Flag_LRES = 1 ;
}
}
else if (!strcmp(argv[i]+1, "order") ||
!strcmp(argv[i]+1, "ord")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
Flag_ORDER = atof(argv[i]) ; i++ ;
}
else {
Msg(GERROR, "Missing interpolation order") ;
}
}
else if (!strcmp(argv[i]+1, "partition") ||
!strcmp(argv[i]+1, "part") ||
!strcmp(argv[i]+1, "par")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
Flag_PAR = atoi(argv[i]) ; i++ ;
}
else {
Msg(GERROR, "Missing number of partitions") ;
}
}
else if (!strcmp(argv[i]+1, "solve") ||
!strcmp(argv[i]+1, "sol")) {
i++ ;
if (i<argc && argv[i][0]=='#') {
Flag_PRE = Flag_CAL = 1 ; Flag_LRES = -atoi(argv[i]+1) ; i++ ;
}
else if (i<argc && argv[i][0]!='-') {
Flag_PRE = Flag_CAL = 1 ; Name_Resolution = argv[i] ; i++ ;
}
else {
Flag_PRE = Flag_CAL = Flag_LRES = 1 ;
}
}
else if (!strcmp(argv[i]+1, "post") ||
!strcmp(argv[i]+1, "pos")) {
i++ ; j = 0 ;
if (i<argc && argv[i][0]=='#') {
Flag_POS = 1 ; Flag_LPOS = -atoi(argv[i]+1) ; i++ ;
} /* Only one numbered (#) PostOperation allowed */
else {
while (i<argc && argv[i][0]!='-') {
Name_PostOperation[j] = argv[i] ; i++ ; j++ ;
if(j == NBR_MAX_POS)
Msg(GERROR, "Too many PostOperations");
}
if(!j){
Flag_POS = Flag_LPOS = 1 ;
}
else{
Flag_POS = 1 ;
Name_PostOperation[j] = NULL ;
}
}
}
else if (!strcmp(argv[i]+1, "interactive-post") ||
!strcmp(argv[i]+1, "ipost") ||
!strcmp(argv[i]+1, "ipos")) {
i++ ; j = 0 ;
while (i<argc && argv[i][0]!='-') {
Name_PostProcessing[j] = argv[i] ; i++ ; j++ ;
if(j == NBR_MAX_POS)
Msg(GERROR, "Too many PostProcessings");
}
if(!j){
Flag_IPOS = Flag_POS = Flag_LIPOS = 1 ;
}
else{
Flag_IPOS = Flag_POS = 1 ;
Name_PostProcessing[j] = NULL ;
}
}
else if (!strcmp(argv[i]+1, "mesh") ||
!strcmp(argv[i]+1, "msh") ||
!strcmp(argv[i]+1, "m")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
Name_MshFile = argv[i] ; i++ ;
}
else {
Msg(GERROR, "Missing file name");
}
}
else if (!strcmp(argv[i]+1, "adapt") ||
!strcmp(argv[i]+1, "adap") ||
!strcmp(argv[i]+1, "ada")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
Name_AdaptFile = argv[i] ; i++ ;
}
else {
Msg(GERROR, "Missing file name");
}
}
else if (!strcmp(argv[i]+1, "res")) {
i++ ; j = 0 ;
while (i<argc && argv[i][0]!='-') {
Name_ResFile[j] = argv[i] ; i++ ; j++ ;
if(j == NBR_MAX_RES)
Msg(GERROR, "Too many '.res' files");
}
if(!j)
Msg(GERROR, "Missing file name");
else{
Name_ResFile[j] = NULL ;
}
}
else if (!strcmp(argv[i]+1, "name")) {
i++ ;
if (i<argc && argv[i][0]!='-') {
strcpy(Name_Generic, argv[i]) ; i++ ;
}
else {
Msg(GERROR, "Missing string");
}
}
else {
sargv[(*sargc)++] = argv[i++];
}
}
else{
if (!Flag_NameProblem) {
Flag_NameProblem = 1 ;
sargv[0] = argv[i] ;
strcpy(Name_ProFile, argv[i++]) ;
}
else{
sargv[(*sargc)++] = argv[i++];
}
}
}
if(!strlen(Name_ProFile))
Msg(GERROR, "Missing input file name");
else{
if(!strlen(Name_Generic)){
strcpy(Name_Generic, Name_ProFile) ;
if(strcmp(Name_ProFile+(strlen(Name_ProFile)-4), ".pro") &&
strcmp(Name_ProFile+(strlen(Name_ProFile)-4), ".PRO"))
strcat(Name_ProFile,".pro") ;
else
Name_Generic[strlen(Name_ProFile)-4] = '\0' ;
}
else if(strcmp(Name_ProFile+(strlen(Name_ProFile)-4), ".pro") &&
strcmp(Name_ProFile+(strlen(Name_ProFile)-4), ".PRO"))
strcat(Name_ProFile,".pro") ;
strcpy(Name_Path, Name_Generic);
i = strlen(Name_Path)-1 ;
while(i >= 0 && Name_Path[i] != '/' && Name_Path[i] != '\\') i-- ;
Name_Path[i+1] = '\0';
}
Flag_LOG = Flag_TmpLOG ;
GetDP_Return(0) ;
}
/* ------------------------------------------------------------------------ */
/* F i n a l i z e A n d E x i t */
/* ------------------------------------------------------------------------ */
void FinalizeAndExit(void){
time_t now;
GetDP_Begin("FinalizeAndExit");
LinAlg_FinalizeSolver();
if(Flag_LOG){
time(&now);
fprintf(LogStream, "%s", ctime(&now));
fclose(LogStream);
}
LinAlg_Finalize();
if(Flag_SOCKET>0){
Gmsh_SendString(Flag_SOCKET, GMSH_CLIENT_STOP, "Goodbye (prematured...)!");
Gmsh_Disconnect(Flag_SOCKET);
}
UnlinkFile(GETDP_TMP_FILENAME);
GetDP_Exit(1) ;
}
/* ------------------------------------------------------------------------ */
/* R e a d _ P r o b l e m S t r u c t u r e */
/* ------------------------------------------------------------------------ */
void Read_ProblemStructure (char * Name){
char AbsPath[2048], Last_yyname[MAX_FILE_NAME_LENGTH];
int Last_yylinenum, Last_yyincludenum, Last_ErrorLevel, i ;
GetDP_Begin("Read_ProblemStructure");
Last_yylinenum = yylinenum ;
strcpy(Last_yyname, yyname);
Last_ErrorLevel = ErrorLevel ;
Last_yyincludenum = yyincludenum ;
strcpy(AbsPath, yyname);
i = strlen(yyname)-1 ;
while(i >= 0 && yyname[i] != '/' && yyname[i] != '\\') i-- ;
AbsPath[i+1] = '\0';
strcat(AbsPath, Name);
Msg(LOADING, "Problem definition '%s'", AbsPath) ;
/* opening the file in text mode messes up the loops (they use
fsetpos/fgetpos) on Windows without Cygwin; not sure why, but
opening the file in binary mode fixes the problem */
if(!(yyin = fopen(AbsPath, "rb")))
Msg(GERROR, "Unable to open file '%s'", AbsPath);
ErrorLevel = 0 ; yylinenum = 1 ; yyincludenum=0 ; strcpy(yyname, AbsPath) ;
yyrestart(yyin); yyparse(); fclose(yyin);
if(ErrorLevel) FinalizeAndExit();
while(yyincludenum > 0){
Read_ProblemStructure(yyincludename);
yyin = fopen(yyname, "rb"); /* same comment as above */
yyrestart(yyin);
for(i=0;i<yylinenum;i++) fgets(AbsPath, 2048, yyin);
yylinenum++ ;
yyparse(); fclose(yyin);
if(ErrorLevel) FinalizeAndExit();
}
yylinenum = Last_yylinenum ; strcpy(yyname, Last_yyname) ;
ErrorLevel = Last_ErrorLevel ; yyincludenum = Last_yyincludenum ;
GetDP_End ;
}
syntax highlighted by Code2HTML, v. 0.9.1