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
Solver module
* Solver options::
* Solver example::
Post-processing module
......@@ -3034,28 +3033,27 @@ as well as the way meshes are displayed in the GUI, is given in
@cindex Solver, module
@cindex Module, Solver
External solvers can be interfaced with Gmsh using a simple
client-server model.
To add a new solver in the solver module, you need to specify its name
(@code{Solver.Name0}, @code{Solver.Name1}, etc.) and the path to the
executable (@code{Solver.Executable0}, @code{Solver.Executable1}, etc.);
see @ref{Solver options list}).
External solvers can driven by Gmsh through the ONELAB
@url{http://www.onelab.info} interface. To add a new solver in the
solver module, you need to specify its name (@code{Solver.Name0},
@code{Solver.Name1}, etc.) and the path to the executable
(@code{Solver.Executable0}, @code{Solver.Executable1}, etc.); see
@ref{Solver options list}).
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
to interface a C++ solver.
@file{onelab.h} header. See the sources of GetDP
(@url{http://geuz.org/getdp}, for an example on how to use the ONELAB
programming interface.
@menu
* Solver options::
* Solver example::
@end menu
@c -------------------------------------------------------------------------
@c Solver options
@c -------------------------------------------------------------------------
@node Solver options, Solver example, Solver module, Solver module
@node Solver options, , Solver module, Solver module
@section Solver options
@cindex Solver commands
......@@ -3063,35 +3061,6 @@ to interface a C++ solver.
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 Post-processing module
@c =========================================================================
......@@ -5357,24 +5326,9 @@ output file just load the mesh file back using `File->Open'.
@enumerate
@item How do I integrate my own solver with Gmsh?
If you want to simply launch a program from within Gmsh, just edit the
options to define your solver commands (e.g. Solver.Name0,
Solver.Executable0, etc.), and set the ClientServer option to zero
(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.
Gmsh uses the ONELAB interface (@url{http://www.onelab.info}) to
interact with external solvers. Have a look at the GetDP finite element
solver (@url{http://geuz.org/getdp}) to see how this is done.
@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 @@
#define _GMSH_SOCKET_H_
//#include "GmshConfig.h"
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -82,7 +83,7 @@ class GmshSocket{
// the socket descriptor
int _sock;
// the socket name
const char *_sockname;
std::string _sockname;
// send some data over the socket
void _SendData(const void *buffer, int bytes)
{
......@@ -132,7 +133,7 @@ class GmshSocket{
#endif
}
public:
GmshSocket() : _sock(0), _sockname(0)
GmshSocket() : _sock(0)
{
#if defined(WIN32) && !defined(__CYGWIN__)
WSADATA wsaData;
......@@ -245,7 +246,6 @@ class GmshClient : public GmshSocket {
// slight delay to make sure that the socket is bound by the
// server before we attempt to connect to it
_Sleep(100);
if(strstr(sockname, "/") || strstr(sockname, "\\") || !strstr(sockname, ":")){
#if !defined(WIN32) || defined(__CYGWIN__)
// UNIX socket (testing ":" is not enough with Windows paths)
......@@ -288,8 +288,9 @@ class GmshClient : public GmshSocket {
memcpy((char *)&addr_in.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
addr_in.sin_port = htons(portno);
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;
}
_Sleep(100);
}
}
......@@ -323,33 +324,36 @@ class GmshServer : public GmshSocket{
if(!sockname) throw "Invalid (null) socket name";
_sockname = sockname;
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)
_portno = -1;
#if !defined(WIN32) || defined(__CYGWIN__)
// delete the file if it already exists
unlink(_sockname);
unlink(_sockname.c_str());
// create a socket
tmpsock = socket(PF_UNIX, SOCK_STREAM, 0);
if(tmpsock < 0) throw "Couldn't create socket";
// bind the socket to its name
struct sockaddr_un 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;
if(bind(tmpsock, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0){
CloseSocket(tmpsock);
throw "Couldn't bind socket to name";
}
// change permissions on the socket name in case it has to be rm'd later
chmod(_sockname, 0666);
chmod(_sockname.c_str(), 0666);
#else
throw "Unix sockets not available on Windows";
#endif
}
else{
// TCP/IP socket
const char *port = strstr(_sockname, ":");
// TCP/IP socket: valid names are either explicit ("hostname:12345")
// 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);
// create a socket
tmpsock = socket(AF_INET, SOCK_STREAM, 0);
......@@ -364,15 +368,30 @@ class GmshServer : public GmshSocket{
memset((char *) &addr_in, 0, sizeof(addr_in));
addr_in.sin_family = AF_INET;
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){
CloseSocket(tmpsock);
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)){
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{
timeout = 0.; // no command launched: don't set a timeout
......@@ -420,7 +439,7 @@ class GmshServer : public GmshSocket{
{
#if !defined(WIN32) || defined(__CYGWIN__)
if(_portno < 0)
unlink(_sockname);
unlink(_sockname.c_str());
#endif
ShutdownSocket(_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