1 /*
2   The main function of netgen.
3   This file is a modification of tkAppInit.c from the Tcl/Tk package
4 */
5 
6 #include <mystdlib.h>
7 #include <inctcl.hpp>
8 #include <meshing.hpp>
9 
10 #ifdef PARALLEL
11 #include <mpi.h>
12 
13 extern void ParallelRun();
14 #endif
15 
16 #include "../libsrc/interface/writeuser.hpp"
17 
18 namespace netgen
19 {
20   DLL_HEADER extern Flags parameters;
21   DLL_HEADER extern bool netgen_executable_started;
22 }
23 
24 DLL_HEADER extern bool nodisplay;
25 
26 
27 using netgen::parameters;
28 using netgen::ngdir;
29 using netgen::verbose;
30 using netgen::NgArray;
31 using netgen::RegisterUserFormats;
32 
33 
34 
35 
36 /*
37  * The following variable is a special hack that is needed in order for
38  * Sun shared libraries to be used for Tcl.
39  */
40 
41 // extern "C" int matherr();
42 // int *tclDummyMathPtr = (int *) matherr;
43 
44 extern "C" int Ng_ServerSocketManagerInit (int port);
45 extern "C" int Ng_ServerSocketManagerRun (void);
46 
47 bool shellmode = false;
48 
49 
50 /*
51  *
52  *     The Netgen main function
53  *
54  */
55 
main(int argc,char ** argv)56 int main(int argc, char ** argv)
57 {
58   netgen::netgen_executable_started = true;
59 
60 #ifdef PARALLEL
61   int mpi_required = MPI_THREAD_MULTIPLE;
62 #ifdef VTRACE
63   mpi_required = MPI_THREAD_SINGLE;
64 #endif
65   int mpi_provided;
66   MPI_Init_thread(&argc, &argv, mpi_required, &mpi_provided);
67 
68   MPI_Comm_size(MPI_COMM_WORLD, &netgen::ntasks);
69   MPI_Comm_rank(MPI_COMM_WORLD, &netgen::id);
70 
71   if(netgen::ntasks!=1)
72       throw ngcore::Exception("Netgen GUI cannot run MPI-parallel");
73 
74   // MPI_COMM_WORLD is just a local communicator
75   // netgen::ng_comm = ngcore::NgMPI_Comm{MPI_COMM_WORLD, false};
76 
77 #endif
78 
79   if ( netgen::id == 0 )
80     {
81       cout << "NETGEN-" << netgen::netgen_version << endl;
82 
83       cout << "Developed by Joachim Schoeberl at" << endl
84 	   << "2010-xxxx Vienna University of Technology" << endl
85 	   << "2006-2010 RWTH Aachen University" << endl
86            << "1996-2006 Johannes Kepler University Linz" << endl;
87 
88 #ifdef OCCGEOMETRY
89       cout << "Including OpenCascade geometry kernel" << endl;
90 #endif
91 
92 #ifdef ACIS
93       cout << "Including ACIS geometry kernel" << endl;
94 #endif
95 
96 #ifdef LINUX
97       //feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
98       //feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW);
99       //cout << "Handle Floating Point Exceptions: " << fegetexcept() << endl;
100 #endif
101 
102 #ifdef DEBUG
103       cout << "You are running the debug version !" << endl;
104 #endif
105 
106 
107 #ifdef PARALLEL
108       cout << "Including MPI version " << MPI_VERSION << '.' << MPI_SUBVERSION << endl;
109 #endif
110     }
111 
112 
113   netgen::h_argc = argc;
114   netgen::h_argv = argv;
115 
116   // command line arguments:
117   for (int i = 1; i < argc; i++)
118     {
119       if (argv[i][0] == '-')
120 	parameters.SetCommandLineFlag (argv[i]);
121       else
122         {
123           if (strstr(argv[i], ".py"))
124             parameters.SetFlag ("py", argv[i]);
125           else
126             parameters.SetFlag ("geofile", argv[i]);
127         }
128     }
129 
130 
131   if (getenv ("NETGENDIR") && strlen (getenv ("NETGENDIR")))
132     ngdir = getenv ("NETGENDIR");
133   else
134     ngdir = ".";
135 
136   verbose = parameters.GetDefineFlag ("V");
137 
138   if (verbose)
139     cout << "NETGENDIR = " << ngdir << endl;
140 
141 
142   if ( netgen::id == 0 )
143     {
144       if (parameters.StringFlagDefined ("testout"))
145         {
146           delete ngcore::testout;
147           ngcore::testout = new ofstream (parameters.GetStringFlag ("testout", "test.out"));
148         }
149 
150 
151 #ifdef SOCKETS
152       Ng_ServerSocketManagerInit(static_cast<int>(parameters.GetNumFlag("serversocket",-1)));
153       if(parameters.GetNumFlag("serversocket",-1) > 0 && !parameters.GetDefineFlag("display"))
154         nodisplay = true;
155 #endif
156 
157       if(parameters.GetDefineFlag("batchmode"))
158         nodisplay = true;
159 
160 
161       if(parameters.GetDefineFlag("shellmode"))
162         {
163           nodisplay = true;
164           shellmode = true;
165         }
166 
167       Tcl_FindExecutable(NULL);
168 
169       // initialize application
170       Tcl_Interp * myinterp = Tcl_CreateInterp ();
171       if (Tcl_AppInit (myinterp) == TCL_ERROR)
172         {
173           cerr << "Exit Netgen due to initialization problem" << endl;
174           exit (1);
175         }
176 
177 
178 
179       // parse tcl-script
180       int errcode;
181 
182       bool internaltcl = INTERNAL_TCL_DEFAULT;
183       if (shellmode)
184         internaltcl = false;
185 
186       if (verbose)
187         {
188           cout << "Tcl header version = " << TCL_PATCH_LEVEL << endl;
189           Tcl_Eval (myinterp, "puts \"Tcl runtime version = [info patchlevel] \";");
190         }
191 
192       if (parameters.GetDefineFlag ("internaltcl"))
193         internaltcl=true;
194       if (parameters.GetDefineFlag ("externaltcl"))
195         internaltcl=false;
196 
197 
198 
199       if (internaltcl)
200         {
201           if (verbose)
202             cout << "using internal Tcl-script" << endl;
203 
204           // connect to one string
205           DLL_HEADER extern const char * ngscript[];
206           const char ** hcp = ngscript;
207           int len = 0;
208           while (*hcp)
209             len += strlen (*hcp++);
210 
211           char * tr1 = new char[len+1];
212           *tr1 = 0;
213           hcp = ngscript;
214 
215           char * tt1 = tr1;
216           while (*hcp)
217             {
218               strcat (tt1, *hcp);
219               tt1 += strlen (*hcp++);
220             }
221 
222           errcode = Tcl_Eval (myinterp, tr1);
223           delete [] tr1;
224         }
225 
226       else
227 
228         {
229           string startfile = ngdir + "/ng.tcl";
230 
231           if (verbose)
232             cout << "Load Tcl-script from " << startfile << endl;
233 
234           errcode = Tcl_EvalFile (myinterp, (char*)startfile.c_str());
235         }
236 
237       if (errcode)
238         {
239           cout << "Error in Tcl-Script:" << endl;
240           // cout << "result = " << myinterp->result << endl;
241           cout << "result = " << Tcl_GetStringResult (myinterp) << endl;
242           // cout << "in line " << myinterp->errorLine << endl;
243 
244           cout << "\nMake sure to set environment variable NETGENDIR to directory containing ng.tcl" << endl;
245           exit (1);
246         }
247 
248       /*
249       // lookup user file formats and insert into format list:
250       NgArray<const char*> userformats;
251       NgArray<const char*> extensions;
252       RegisterUserFormats (userformats, extensions);
253 
254       ostringstream fstr;
255 
256       tcl_const char * exportft = Tcl_GetVar (myinterp, "exportfiletype", 0);
257       for (int i = 1; i <= userformats.Size(); i++)
258 	{
259 	  fstr << ".ngmenu.file.filetype add radio -label \""
260 	       << userformats.Get(i) << "\" -variable exportfiletype -command { .ngmenu.file invoke \"Export Mesh...\" } \n";
261 	  fstr << "lappend meshexportformats { {" << userformats.Get(i) << "} {" << extensions.Get(i) << "} }\n";
262 	}
263 
264         Tcl_Eval (myinterp, (char*)fstr.str().c_str());
265       Tcl_SetVar (myinterp, "exportfiletype", exportft, 0);
266       */
267 
268 #ifdef SOCKETS
269       Ng_ServerSocketManagerRun();
270 #endif
271 
272       // start event-loop
273       Tk_MainLoop();
274       Tcl_DeleteInterp (myinterp);
275       Tcl_Exit(0);
276     }
277 
278 #ifdef PARALLEL
279   else
280     {
281       ParallelRun();
282       MPI_Finalize();
283     }
284 
285 #endif
286 
287   return 0;
288 }
289 
290 
291 
292 /*
293 extern "C" int Tix_Init (Tcl_Interp * interp);
294 extern "C" int Itcl_Init (Tcl_Interp * interp);
295 extern "C" int Itk_Init (Tcl_Interp * interp);
296 */
297 extern "C" int Ng_Init (Tcl_Interp * interp);
298 extern "C" int Ng_Vis_Init (Tcl_Interp * interp);
299 
300 
301 
302 // extern Tcl_PackageInitProc * Tk_SafeInit;
303 
304 /*
305  *
306  * Initialize packages
307  *
308  */
309 
310 // extern "C" int NGSolve_Init (Tcl_Interp * interp);
311 
312 
Tcl_AppInit(Tcl_Interp * interp)313 int Tcl_AppInit(Tcl_Interp * interp)
314 {
315 
316   if (Tcl_Init(interp) == TCL_ERROR) {
317     cerr << "Problem in Tcl_Init: " << endl;
318     cout << "result = " << Tcl_GetStringResult (interp) << endl;
319     // cerr << interp->result << endl;
320     // return TCL_ERROR;
321   }
322 
323   if (!nodisplay && Tk_Init(interp) == TCL_ERROR) {
324     cerr << "Problem in Tk_Init: " << endl;
325     cout << "result = " << Tcl_GetStringResult (interp) << endl;
326     // cerr << interp->result << endl;
327     // return TCL_ERROR;
328   }
329 
330 #ifdef TRAFO
331   //   extern int Trafo_Init (Tcl_Interp * interp);
332   //   if (Trafo_Init(interp) == TCL_ERROR)
333   //     {
334   //       cerr << "Problem in Trafo_Init: " << endl;
335   //       cerr << interp->result << endl;
336   //       return TCL_ERROR;
337   //     }
338 #endif
339 
340 #ifdef EBGELAST
341   extern int EBGElast_Init (Tcl_Interp * interp);
342   if(EBGElast_Init(interp) == TCL_ERROR)
343     {
344       cerr << "Problem in EBGElast_Init: " << endl;
345       cerr << interp->result << endl;
346       return TCL_ERROR;
347     }
348 
349 #endif
350 
351 #ifdef SMALLTRAFO
352   extern int SmallModels_Init (Tcl_Interp * interp);
353   if(SmallModels_Init(interp) == TCL_ERROR)
354     {
355       cerr << "Problem in SmallModel_Init: " << endl;
356       cerr << interp->result << endl;
357       return TCL_ERROR;
358     }
359 
360 #endif
361 
362 #ifdef SOCKETS
363   extern int Ng_Socket_Init (Tcl_Interp * interp);
364   if ( Ng_Socket_Init(interp) == TCL_ERROR)
365     {
366       cerr << "Problem in Ng_Socket_Init: " << endl;
367       cerr << interp->result << endl;
368       return TCL_ERROR;
369     }
370 
371 #endif
372 
373 
374 #ifdef ZUGSTANGE
375   extern int Zugstange_Init (Tcl_Interp * interp);
376   if (Zugstange_Init(interp) == TCL_ERROR)
377     {
378       cerr << "Problem in Zugstange_Init: " << endl;
379       cerr << interp->result << endl;
380       return TCL_ERROR;
381     }
382 #endif
383 
384 
385   Tcl_StaticPackage(interp, "Tk", Tk_Init, 0);
386   return TCL_OK;
387 }
388 
389