Skip to content
Snippets Groups Projects
Commit 81e5f657 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

remove mentions to old solver interface

parent ea2431ac
No related branches found
No related tags found
No related merge requests found
...@@ -201,7 +201,6 @@ Mesh commands ...@@ -201,7 +201,6 @@ Mesh commands
Solver module Solver module
* Solver options:: * Solver options::
* Solver example::
Post-processing module Post-processing module
...@@ -3034,28 +3033,27 @@ as well as the way meshes are displayed in the GUI, is given in ...@@ -3034,28 +3033,27 @@ as well as the way meshes are displayed in the GUI, is given in
@cindex Solver, module @cindex Solver, module
@cindex Module, Solver @cindex Module, Solver
External solvers can be interfaced with Gmsh using a simple External solvers can driven by Gmsh through the ONELAB
client-server model. @url{http://www.onelab.info} interface. To add a new solver in the
solver module, you need to specify its name (@code{Solver.Name0},
To add a new solver in the solver module, you need to specify its name @code{Solver.Name1}, etc.) and the path to the executable
(@code{Solver.Name0}, @code{Solver.Name1}, etc.) and the path to the (@code{Solver.Executable0}, @code{Solver.Executable1}, etc.); see
executable (@code{Solver.Executable0}, @code{Solver.Executable1}, etc.); @ref{Solver options list}).
see @ref{Solver options list}).
The client-server API for the solver interface is defined in the The client-server API for the solver interface is defined in the
@file{onelab.h} header: see @ref{Solver example}, for an example of how @file{onelab.h} header. See the sources of GetDP
to interface a C++ solver. (@url{http://geuz.org/getdp}, for an example on how to use the ONELAB
programming interface.
@menu @menu
* Solver options:: * Solver options::
* Solver example::
@end menu @end menu
@c ------------------------------------------------------------------------- @c -------------------------------------------------------------------------
@c Solver options @c Solver options
@c ------------------------------------------------------------------------- @c -------------------------------------------------------------------------
@node Solver options, Solver example, Solver module, Solver module @node Solver options, , Solver module, Solver module
@section Solver options @section Solver options
@cindex Solver commands @cindex Solver commands
...@@ -3063,35 +3061,6 @@ to interface a C++ solver. ...@@ -3063,35 +3061,6 @@ to interface a C++ solver.
The list of all the solver options is given in @ref{Solver options list}. The list of all the solver options is given in @ref{Solver options list}.
@c -------------------------------------------------------------------------
@c Solver example
@c -------------------------------------------------------------------------
@node Solver example, , Solver options, Solver module
@section Solver example
@cindex Solver example
@cindex Example, solver
Here is a small example of how to interface a C++ solver with Gmsh. The
following listing reproduces the @file{utils/solvers/c++/solver.cpp} file
from the Gmsh source distribution.
@sp 1
@verbatiminclude ../../utils/solvers/c++/solver.cpp
@sp 1
To define the above solver as the second external solver in Gmsh, you then
need to define the following options (either merge them in your Gmsh option
file, or use the @code{-option} command-line option---see @ref{Command-line
options}):
@sp 1
@verbatiminclude ../../utils/solvers/c++/solver.opt
@c ========================================================================= @c =========================================================================
@c Post-processing module @c Post-processing module
@c ========================================================================= @c =========================================================================
...@@ -5357,24 +5326,9 @@ output file just load the mesh file back using `File->Open'. ...@@ -5357,24 +5326,9 @@ output file just load the mesh file back using `File->Open'.
@enumerate @enumerate
@item How do I integrate my own solver with Gmsh? @item How do I integrate my own solver with Gmsh?
If you want to simply launch a program from within Gmsh, just edit the Gmsh uses the ONELAB interface (@url{http://www.onelab.info}) to
options to define your solver commands (e.g. Solver.Name0, interact with external solvers. Have a look at the GetDP finite element
Solver.Executable0, etc.), and set the ClientServer option to zero solver (@url{http://geuz.org/getdp}) to see how this is done.
(e.g. Solver.ClientServer0 = 0).
If you want your solver to interact with Gmsh (for error messages,
option definitions, post-processing, etc.), you will need to link your
solver with the GmshClient routines and add the appropriate function
calls inside your program. You will of course also need to define your
solver commands in an option file, but this time you should set the
ClientServer variable to 1 (e.g. Solver.ClientServer = 1). C, C++,
Perl and Python solver examples are available in the source
distribution in the @file{utils/solvers} directory.
@item On Windows, Gmsh does not seem to find the solver executable. What's wrong?
The solver executable (for example, `getdp.exe') has to be in your
path. If it is not specify its location in the `Command' field.
@item Can I launch Gmsh from my solver (instead of launching my solver from Gmsh) in order to monitor a solution? @item Can I launch Gmsh from my solver (instead of launching my solver from Gmsh) in order to monitor a solution?
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define _GMSH_SOCKET_H_ #define _GMSH_SOCKET_H_
//#include "GmshConfig.h" //#include "GmshConfig.h"
#include <string>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -82,7 +83,7 @@ class GmshSocket{ ...@@ -82,7 +83,7 @@ class GmshSocket{
// the socket descriptor // the socket descriptor
int _sock; int _sock;
// the socket name // the socket name
const char *_sockname; std::string _sockname;
// send some data over the socket // send some data over the socket
void _SendData(const void *buffer, int bytes) void _SendData(const void *buffer, int bytes)
{ {
...@@ -132,7 +133,7 @@ class GmshSocket{ ...@@ -132,7 +133,7 @@ class GmshSocket{
#endif #endif
} }
public: public:
GmshSocket() : _sock(0), _sockname(0) GmshSocket() : _sock(0)
{ {
#if defined(WIN32) && !defined(__CYGWIN__) #if defined(WIN32) && !defined(__CYGWIN__)
WSADATA wsaData; WSADATA wsaData;
...@@ -245,7 +246,6 @@ class GmshClient : public GmshSocket { ...@@ -245,7 +246,6 @@ class GmshClient : public GmshSocket {
// slight delay to make sure that the socket is bound by the // slight delay to make sure that the socket is bound by the
// server before we attempt to connect to it // server before we attempt to connect to it
_Sleep(100); _Sleep(100);
if(strstr(sockname, "/") || strstr(sockname, "\\") || !strstr(sockname, ":")){ if(strstr(sockname, "/") || strstr(sockname, "\\") || !strstr(sockname, ":")){
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
// UNIX socket (testing ":" is not enough with Windows paths) // UNIX socket (testing ":" is not enough with Windows paths)
...@@ -288,8 +288,9 @@ class GmshClient : public GmshSocket { ...@@ -288,8 +288,9 @@ class GmshClient : public GmshSocket {
memcpy((char *)&addr_in.sin_addr.s_addr, (char *)server->h_addr, server->h_length); memcpy((char *)&addr_in.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
addr_in.sin_port = htons(portno); addr_in.sin_port = htons(portno);
for(int tries = 0; tries < 5; tries++) { for(int tries = 0; tries < 5; tries++) {
if(connect(_sock, (struct sockaddr *)&addr_in, sizeof(addr_in)) >= 0) if(connect(_sock, (struct sockaddr *)&addr_in, sizeof(addr_in)) >= 0){
return _sock; return _sock;
}
_Sleep(100); _Sleep(100);
} }
} }
...@@ -323,33 +324,36 @@ class GmshServer : public GmshSocket{ ...@@ -323,33 +324,36 @@ class GmshServer : public GmshSocket{
if(!sockname) throw "Invalid (null) socket name"; if(!sockname) throw "Invalid (null) socket name";
_sockname = sockname; _sockname = sockname;
int tmpsock; int tmpsock;
if(strstr(_sockname, "/") || strstr(_sockname, "\\") || !strstr(_sockname, ":")){ if(strstr(_sockname.c_str(), "/") || strstr(_sockname.c_str(), "\\") ||
!strstr(_sockname.c_str(), ":")){
// UNIX socket (testing ":" is not enough with Windows paths) // UNIX socket (testing ":" is not enough with Windows paths)
_portno = -1; _portno = -1;
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
// delete the file if it already exists // delete the file if it already exists
unlink(_sockname); unlink(_sockname.c_str());
// create a socket // create a socket
tmpsock = socket(PF_UNIX, SOCK_STREAM, 0); tmpsock = socket(PF_UNIX, SOCK_STREAM, 0);
if(tmpsock < 0) throw "Couldn't create socket"; if(tmpsock < 0) throw "Couldn't create socket";
// bind the socket to its name // bind the socket to its name
struct sockaddr_un addr_un; struct sockaddr_un addr_un;
memset((char *) &addr_un, 0, sizeof(addr_un)); memset((char *) &addr_un, 0, sizeof(addr_un));
strcpy(addr_un.sun_path, _sockname); strcpy(addr_un.sun_path, _sockname.c_str());
addr_un.sun_family = AF_UNIX; addr_un.sun_family = AF_UNIX;
if(bind(tmpsock, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0){ if(bind(tmpsock, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0){
CloseSocket(tmpsock); CloseSocket(tmpsock);
throw "Couldn't bind socket to name"; throw "Couldn't bind socket to name";
} }
// change permissions on the socket name in case it has to be rm'd later // change permissions on the socket name in case it has to be rm'd later
chmod(_sockname, 0666); chmod(_sockname.c_str(), 0666);
#else #else
throw "Unix sockets not available on Windows"; throw "Unix sockets not available on Windows";
#endif #endif
} }
else{ else{
// TCP/IP socket // TCP/IP socket: valid names are either explicit ("hostname:12345")
const char *port = strstr(_sockname, ":"); // or implicit ("hostname:", "hostname: ", "hostname:0") in which case
// the system attributes at random an available port
const char *port = strstr(_sockname.c_str(), ":");
_portno = atoi(port + 1); _portno = atoi(port + 1);
// create a socket // create a socket
tmpsock = socket(AF_INET, SOCK_STREAM, 0); tmpsock = socket(AF_INET, SOCK_STREAM, 0);
...@@ -364,15 +368,30 @@ class GmshServer : public GmshSocket{ ...@@ -364,15 +368,30 @@ class GmshServer : public GmshSocket{
memset((char *) &addr_in, 0, sizeof(addr_in)); memset((char *) &addr_in, 0, sizeof(addr_in));
addr_in.sin_family = AF_INET; addr_in.sin_family = AF_INET;
addr_in.sin_addr.s_addr = INADDR_ANY; addr_in.sin_addr.s_addr = INADDR_ANY;
addr_in.sin_port = htons(_portno); addr_in.sin_port = htons(_portno); // random assign if _portno == 0
if(bind(tmpsock, (struct sockaddr *)&addr_in, sizeof(addr_in)) < 0){ if(bind(tmpsock, (struct sockaddr *)&addr_in, sizeof(addr_in)) < 0){
CloseSocket(tmpsock); CloseSocket(tmpsock);
throw "Couldn't bind socket to name"; throw "Couldn't bind socket to name";
} }
if(!_portno){ // retrieve name if randomly assigned port
socklen_t addrlen = sizeof(addr_in);
int rc = getsockname(tmpsock, (struct sockaddr *)&addr_in, &addrlen);
_portno = ntohs(addr_in.sin_port);
int pos = _sockname.find(':'); // remove trailing ' ' or '0'
char tmp[256];
sprintf(tmp, "%s:%d", _sockname.substr(0, pos).c_str(), _portno);
_sockname.assign(tmp);
}
} }
if(command && strlen(command)){ if(command && strlen(command)){
SystemCall(command); // start the solver // we assume that the command line always ends with the socket name
std::string cmd(command);
cmd += " " + _sockname;
#if !defined(WIN32)
cmd += " &";
#endif
SystemCall(cmd.c_str()); // start the solver
} }
else{ else{
timeout = 0.; // no command launched: don't set a timeout timeout = 0.; // no command launched: don't set a timeout
...@@ -420,7 +439,7 @@ class GmshServer : public GmshSocket{ ...@@ -420,7 +439,7 @@ class GmshServer : public GmshSocket{
{ {
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
if(_portno < 0) if(_portno < 0)
unlink(_sockname); unlink(_sockname.c_str());
#endif #endif
ShutdownSocket(_sock); ShutdownSocket(_sock);
CloseSocket(_sock); CloseSocket(_sock);
......
File moved
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment