Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
gmsh
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Larry Price
gmsh
Commits
8506977d
Commit
8506977d
authored
13 years ago
by
Christophe Geuzaine
Browse files
Options
Downloads
Patches
Plain Diff
simple onelab demo
parent
614a7f75
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
utils/solvers/c++/onelab.h
+817
-0
817 additions, 0 deletions
utils/solvers/c++/onelab.h
utils/solvers/c++/solver.cpp
+36
-0
36 additions, 0 deletions
utils/solvers/c++/solver.cpp
with
853 additions
and
0 deletions
utils/solvers/c++/onelab.h
0 → 100644
+
817
−
0
View file @
8506977d
// OneLab - Copyright (C) 2011 ULg-UCL
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, and/or sell copies of the
// Software, and to permit persons to whom the Software is furnished
// to do so, provided that the above copyright notice(s) and this
// permission notice appear in all copies of the Software and that
// both the above copyright notice(s) and this permission notice
// appear in supporting documentation.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR
// ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE.
//
// Please report all bugs and problems to <gmsh@geuz.org>.
#ifndef _ONELAB_H_
#define _ONELAB_H_
#include
<string>
#include
<vector>
#include
<set>
#include
<map>
#include
<iostream>
#include
<sstream>
#include
"GmshSocket.h"
namespace
onelab
{
// The base parameter class.
class
parameter
{
private:
// the name of the parameter, including its '/'-separated path in
// the parameter hierarchy. Parameters or subpaths can start with
// numbers to force their relative ordering (such numbers are
// automatically hidden in the interface).
std
::
string
_name
;
// help strings (if provided, the short help serves as a better
// way to display the parameter in the interface). Richer encoding
// (UTF? HTML?) might be used in the future.
std
::
string
_shortHelp
,
_help
;
// clients that use this parameter
std
::
set
<
std
::
string
>
_clients
;
// flag to check if the parameter has been changed since the last
// run()
bool
_changed
;
// should the parameter be visible in the interface?
bool
_visible
;
protected:
// optional additional attributes
std
::
map
<
std
::
string
,
std
::
string
>
_attributes
;
public:
parameter
(
const
std
::
string
&
name
=
""
,
const
std
::
string
&
shortHelp
=
""
,
const
std
::
string
&
help
=
""
)
:
_name
(
name
),
_shortHelp
(
shortHelp
),
_help
(
help
),
_changed
(
true
),
_visible
(
true
)
{}
void
setName
(
const
std
::
string
&
name
){
_name
=
name
;
}
void
setShortHelp
(
const
std
::
string
&
shortHelp
){
_shortHelp
=
shortHelp
;
}
void
setHelp
(
const
std
::
string
&
help
){
_help
=
help
;
}
void
setChanged
(
bool
changed
){
_changed
=
changed
;
}
void
setVisible
(
bool
visible
){
_visible
=
visible
;
}
void
setAttribute
(
const
std
::
string
&
key
,
const
std
::
string
&
value
)
{
_attributes
[
key
]
=
value
;
}
void
setAttributes
(
const
std
::
map
<
std
::
string
,
std
::
string
>
&
attributes
)
{
_attributes
=
attributes
;
}
void
setClients
(
const
std
::
set
<
std
::
string
>
&
clients
){
_clients
=
clients
;
}
void
addClient
(
const
std
::
string
&
client
){
_clients
.
insert
(
client
);
}
void
addClients
(
const
std
::
set
<
std
::
string
>
&
clients
)
{
_clients
.
insert
(
clients
.
begin
(),
clients
.
end
());
}
bool
hasClient
(
const
std
::
string
&
client
)
{
return
(
_clients
.
find
(
client
)
!=
_clients
.
end
());
}
virtual
std
::
string
getType
()
const
=
0
;
const
std
::
string
&
getName
()
const
{
return
_name
;
}
const
std
::
string
&
getShortHelp
()
const
{
return
_shortHelp
;
}
const
std
::
string
&
getHelp
()
const
{
return
_help
;
}
bool
getChanged
()
const
{
return
_changed
;
}
bool
getVisible
()
const
{
return
_visible
;
}
std
::
string
getAttribute
(
const
std
::
string
&
key
)
const
{
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
_attributes
.
find
(
key
);
if
(
it
!=
_attributes
.
end
())
return
it
->
second
;
return
""
;
}
const
std
::
map
<
std
::
string
,
std
::
string
>
&
getAttributes
()
const
{
return
_attributes
;
}
const
std
::
set
<
std
::
string
>
&
getClients
()
const
{
return
_clients
;
}
static
char
charSep
()
{
return
'\0'
;
}
static
double
maxNumber
()
{
return
1e200
;
}
static
std
::
string
version
()
{
return
"1.0"
;
}
static
std
::
string
getNextToken
(
const
std
::
string
&
msg
,
std
::
string
::
size_type
&
first
)
{
std
::
string
::
size_type
last
=
msg
.
find_first_of
(
charSep
(),
first
);
std
::
string
next
=
msg
.
substr
(
first
,
last
-
first
);
first
=
(
last
==
std
::
string
::
npos
)
?
last
:
last
+
1
;
return
next
;
}
std
::
string
sanitize
(
const
std
::
string
&
in
)
const
{
std
::
string
out
(
in
);
for
(
unsigned
int
i
=
0
;
i
<
in
.
size
();
i
++
)
if
(
out
[
i
]
==
charSep
())
out
[
i
]
=
' '
;
return
out
;
}
virtual
std
::
string
toChar
()
const
{
std
::
ostringstream
sstream
;
sstream
<<
version
()
<<
charSep
()
<<
getType
()
<<
charSep
()
<<
sanitize
(
getName
())
<<
charSep
()
<<
sanitize
(
getShortHelp
())
<<
charSep
()
<<
sanitize
(
getHelp
())
<<
charSep
()
<<
(
getVisible
()
?
1
:
0
)
<<
charSep
()
<<
_attributes
.
size
()
<<
charSep
();
for
(
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
_attributes
.
begin
();
it
!=
_attributes
.
end
();
it
++
)
sstream
<<
sanitize
(
it
->
first
)
<<
charSep
()
<<
sanitize
(
it
->
second
)
<<
charSep
();
sstream
<<
getClients
().
size
()
<<
charSep
();
for
(
std
::
set
<
std
::
string
>::
const_iterator
it
=
getClients
().
begin
();
it
!=
getClients
().
end
();
it
++
)
sstream
<<
sanitize
(
*
it
)
<<
charSep
();
return
sstream
.
str
();
}
virtual
std
::
string
::
size_type
fromChar
(
const
std
::
string
&
msg
)
{
std
::
string
::
size_type
pos
=
0
;
if
(
getNextToken
(
msg
,
pos
)
!=
version
())
return
0
;
if
(
getNextToken
(
msg
,
pos
)
!=
getType
())
return
0
;
setName
(
getNextToken
(
msg
,
pos
));
setShortHelp
(
getNextToken
(
msg
,
pos
));
setHelp
(
getNextToken
(
msg
,
pos
));
setVisible
(
atoi
(
getNextToken
(
msg
,
pos
).
c_str
()));
int
numAttributes
=
atoi
(
getNextToken
(
msg
,
pos
).
c_str
());
for
(
int
i
=
0
;
i
<
numAttributes
;
i
++
){
std
::
string
key
(
getNextToken
(
msg
,
pos
));
setAttribute
(
key
,
getNextToken
(
msg
,
pos
));
}
int
numClients
=
atoi
(
getNextToken
(
msg
,
pos
).
c_str
());
for
(
int
i
=
0
;
i
<
numClients
;
i
++
){
std
::
string
client
(
getNextToken
(
msg
,
pos
));
addClient
(
client
);
}
return
pos
;
}
static
void
getInfoFromChar
(
const
std
::
string
&
msg
,
std
::
string
&
version
,
std
::
string
&
type
,
std
::
string
&
name
)
{
std
::
string
::
size_type
first
=
0
;
version
=
getNextToken
(
msg
,
first
);
type
=
getNextToken
(
msg
,
first
);
name
=
getNextToken
(
msg
,
first
);
}
};
class
parameterLessThan
{
public:
bool
operator
()(
const
parameter
*
p1
,
const
parameter
*
p2
)
const
{
return
p1
->
getName
()
<
p2
->
getName
();
}
};
// The number class. Numbers are stored internally as double
// precision real numbers. Currently all more complicated types
// (complex numbers, vectors, etc.) are supposed to be encapsulated
// in functions. We might add more base types in the future to make
// the interface more expressive.
class
number
:
public
parameter
{
private:
double
_value
,
_min
,
_max
,
_step
;
std
::
vector
<
double
>
_choices
;
public:
number
(
const
std
::
string
&
name
=
""
,
double
value
=
0.
,
const
std
::
string
&
shortHelp
=
""
,
const
std
::
string
&
help
=
""
)
:
parameter
(
name
,
shortHelp
,
help
),
_value
(
value
),
_min
(
-
maxNumber
()),
_max
(
maxNumber
()),
_step
(
0.
)
{}
void
setValue
(
double
value
){
_value
=
value
;
}
void
setMin
(
double
min
){
_min
=
min
;
}
void
setMax
(
double
max
){
_max
=
max
;
}
void
setStep
(
double
step
){
_step
=
step
;
}
void
setChoices
(
const
std
::
vector
<
double
>
&
choices
){
_choices
=
choices
;
}
std
::
string
getType
()
const
{
return
"number"
;
}
double
getValue
()
const
{
return
_value
;
}
double
getMin
()
const
{
return
_min
;
}
double
getMax
()
const
{
return
_max
;
}
double
getStep
()
const
{
return
_step
;
}
const
std
::
vector
<
double
>
&
getChoices
()
const
{
return
_choices
;
}
void
update
(
const
number
&
p
)
{
addClients
(
p
.
getClients
());
// complete the list
setShortHelp
(
p
.
getShortHelp
());
setHelp
(
p
.
getHelp
());
setAttributes
(
p
.
getAttributes
());
if
(
p
.
getValue
()
!=
getValue
()){
setValue
(
p
.
getValue
());
setChanged
(
true
);
}
setMin
(
p
.
getMin
());
setMax
(
p
.
getMax
());
setStep
(
p
.
getStep
());
setChoices
(
p
.
getChoices
());
}
std
::
string
toChar
()
const
{
std
::
ostringstream
sstream
;
sstream
<<
parameter
::
toChar
()
<<
_value
<<
charSep
()
<<
_min
<<
charSep
()
<<
_max
<<
charSep
()
<<
_step
<<
charSep
()
<<
_choices
.
size
()
<<
charSep
();
for
(
unsigned
int
i
=
0
;
i
<
_choices
.
size
();
i
++
)
sstream
<<
_choices
[
i
]
<<
charSep
();
return
sstream
.
str
();
}
std
::
string
::
size_type
fromChar
(
const
std
::
string
&
msg
)
{
std
::
string
::
size_type
pos
=
parameter
::
fromChar
(
msg
);
if
(
!
pos
)
return
0
;
setValue
(
atof
(
getNextToken
(
msg
,
pos
).
c_str
()));
setMin
(
atof
(
getNextToken
(
msg
,
pos
).
c_str
()));
setMax
(
atof
(
getNextToken
(
msg
,
pos
).
c_str
()));
setStep
(
atof
(
getNextToken
(
msg
,
pos
).
c_str
()));
_choices
.
resize
(
atoi
(
getNextToken
(
msg
,
pos
).
c_str
()));
for
(
unsigned
int
i
=
0
;
i
<
_choices
.
size
();
i
++
)
_choices
[
i
]
=
atof
(
getNextToken
(
msg
,
pos
).
c_str
());
return
pos
;
}
};
// The string class. A string has a mutable "kind": we do not derive
// specialized classes, because the kind should be changeable at
// runtime (e.g. from a client-dependent mathematical expression to
// a table of values). Possible kinds: generic, filename, hostname,
// client-dependent mathematical expression, comma-separated list of
// values, matlab matrix, onelab mathematical expression (through
// mathex?), ...
class
string
:
public
parameter
{
private:
std
::
string
_value
,
_kind
;
std
::
vector
<
std
::
string
>
_choices
;
public:
string
(
const
std
::
string
&
name
=
""
,
const
std
::
string
&
value
=
""
,
const
std
::
string
&
shortHelp
=
""
,
const
std
::
string
&
help
=
""
)
:
parameter
(
name
,
shortHelp
,
help
),
_value
(
value
),
_kind
(
"generic"
)
{}
void
setValue
(
const
std
::
string
&
value
){
_value
=
value
;
}
void
setKind
(
const
std
::
string
&
kind
){
_kind
=
kind
;
}
void
setChoices
(
const
std
::
vector
<
std
::
string
>
&
choices
){
_choices
=
choices
;
}
std
::
string
getType
()
const
{
return
"string"
;
}
const
std
::
string
&
getValue
()
const
{
return
_value
;
}
const
std
::
string
&
getKind
()
const
{
return
_kind
;
}
const
std
::
vector
<
std
::
string
>
&
getChoices
()
const
{
return
_choices
;
}
void
update
(
const
string
&
p
)
{
addClients
(
p
.
getClients
());
setShortHelp
(
p
.
getShortHelp
());
setHelp
(
p
.
getHelp
());
setAttributes
(
p
.
getAttributes
());
if
(
p
.
getValue
()
!=
getValue
()){
setValue
(
p
.
getValue
());
setChanged
(
true
);
}
if
(
p
.
getKind
()
!=
getKind
()){
setKind
(
p
.
getKind
());
setChanged
(
true
);
}
setChoices
(
p
.
getChoices
());
}
std
::
string
toChar
()
const
{
std
::
ostringstream
sstream
;
sstream
<<
parameter
::
toChar
()
<<
sanitize
(
_value
)
<<
charSep
()
<<
sanitize
(
_kind
)
<<
charSep
()
<<
_choices
.
size
()
<<
charSep
();
for
(
unsigned
int
i
=
0
;
i
<
_choices
.
size
();
i
++
)
sstream
<<
sanitize
(
_choices
[
i
])
<<
charSep
();
return
sstream
.
str
();
}
std
::
string
::
size_type
fromChar
(
const
std
::
string
&
msg
)
{
std
::
string
::
size_type
pos
=
parameter
::
fromChar
(
msg
);
if
(
!
pos
)
return
0
;
setValue
(
getNextToken
(
msg
,
pos
));
setKind
(
getNextToken
(
msg
,
pos
));
_choices
.
resize
(
atoi
(
getNextToken
(
msg
,
pos
).
c_str
()));
for
(
unsigned
int
i
=
0
;
i
<
_choices
.
size
();
i
++
)
_choices
[
i
]
=
getNextToken
(
msg
,
pos
);
return
pos
;
}
};
// The region class. A region can be any kind of geometrical entity,
// represented as identifiers of physical regions. Operations on
// regions will include union, intersection, etc.
class
region
:
public
parameter
{
private:
std
::
string
_value
;
// TODO: change this into std::set<std::string>
std
::
vector
<
std
::
string
>
_choices
;
public:
region
(
const
std
::
string
&
name
=
""
,
const
std
::
string
&
value
=
""
,
const
std
::
string
&
shortHelp
=
""
,
const
std
::
string
&
help
=
""
)
:
parameter
(
name
,
shortHelp
,
help
),
_value
(
value
)
{}
void
setValue
(
const
std
::
string
&
value
){
_value
=
value
;
}
std
::
string
getType
()
const
{
return
"region"
;
}
const
std
::
string
&
getValue
()
const
{
return
_value
;
}
void
update
(
const
region
&
p
)
{
addClients
(
p
.
getClients
());
setShortHelp
(
p
.
getShortHelp
());
setHelp
(
p
.
getHelp
());
setAttributes
(
p
.
getAttributes
());
if
(
p
.
getValue
()
!=
getValue
()){
setValue
(
p
.
getValue
());
setChanged
(
true
);
}
}
std
::
string
toChar
()
const
{
std
::
ostringstream
sstream
;
sstream
<<
parameter
::
toChar
()
<<
_value
<<
charSep
()
<<
_choices
.
size
()
<<
charSep
();
for
(
unsigned
int
i
=
0
;
i
<
_choices
.
size
();
i
++
)
sstream
<<
sanitize
(
_choices
[
i
])
<<
charSep
();
return
sstream
.
str
();
}
};
// The (possibly piece-wise defined on regions) function
// class. Functions are entirely client-dependent: they are just
// represented internally as onelab strings, defined on onelab
// regions.
class
function
:
public
parameter
{
private:
std
::
string
_value
;
std
::
map
<
std
::
string
,
std
::
string
>
_pieceWiseValues
;
std
::
vector
<
std
::
string
>
_choices
;
public:
function
(
const
std
::
string
&
name
=
""
,
const
std
::
string
&
value
=
""
,
const
std
::
string
&
shortHelp
=
""
,
const
std
::
string
&
help
=
""
)
:
parameter
(
name
,
shortHelp
,
help
),
_value
(
value
)
{}
void
setValue
(
const
std
::
string
&
value
,
const
std
::
string
&
region
=
""
)
{
if
(
region
.
empty
())
_value
=
value
;
else
_pieceWiseValues
[
region
]
=
value
;
}
std
::
string
getType
()
const
{
return
"function"
;
}
const
std
::
string
getValue
(
const
std
::
string
&
region
=
""
)
const
{
if
(
region
.
size
()){
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
_pieceWiseValues
.
find
(
region
);
if
(
it
!=
_pieceWiseValues
.
end
())
return
it
->
second
;
return
""
;
}
else
return
_value
;
}
const
std
::
map
<
std
::
string
,
std
::
string
>
&
getPieceWiseValues
()
const
{
return
_pieceWiseValues
;
}
void
update
(
const
function
&
p
)
{
addClients
(
p
.
getClients
());
setShortHelp
(
p
.
getShortHelp
());
setHelp
(
p
.
getHelp
());
setAttributes
(
p
.
getAttributes
());
if
(
p
.
getValue
()
!=
getValue
()){
setValue
(
p
.
getValue
());
setChanged
(
true
);
}
}
std
::
string
toChar
()
const
{
std
::
ostringstream
sstream
;
sstream
<<
parameter
::
toChar
()
<<
sanitize
(
_value
)
<<
charSep
()
<<
_pieceWiseValues
.
size
()
<<
charSep
();
for
(
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
_pieceWiseValues
.
begin
();
it
!=
_pieceWiseValues
.
end
();
it
++
)
sstream
<<
sanitize
(
it
->
first
)
<<
charSep
()
<<
sanitize
(
it
->
second
)
<<
charSep
();
sstream
<<
_choices
.
size
()
<<
charSep
();
for
(
unsigned
int
i
=
0
;
i
<
_choices
.
size
();
i
++
)
sstream
<<
sanitize
(
_choices
[
i
])
<<
charSep
();
return
sstream
.
str
();
}
};
// The parameter space, i.e., the set of parameters stored and
// handled by the onelab server.
class
parameterSpace
{
private:
std
::
set
<
number
*
,
parameterLessThan
>
_numbers
;
std
::
set
<
string
*
,
parameterLessThan
>
_strings
;
std
::
set
<
region
*
,
parameterLessThan
>
_regions
;
std
::
set
<
function
*
,
parameterLessThan
>
_functions
;
// set a parameter in the parameter space; if it already exists,
// update it (adding new clients if necessary). This needs to be
// locked to avoid race conditions when several clients try to set
// a parameter at the same time.
template
<
class
T
>
bool
_set
(
const
T
&
p
,
const
std
::
string
&
client
,
std
::
set
<
T
*
,
parameterLessThan
>
&
ps
)
{
typename
std
::
set
<
T
*
,
parameterLessThan
>::
iterator
it
=
ps
.
find
((
T
*
)
&
p
);
if
(
it
!=
ps
.
end
()){
(
*
it
)
->
update
(
p
);
if
(
client
.
size
())
(
*
it
)
->
addClient
(
client
);
}
else
{
T
*
newp
=
new
T
(
p
);
if
(
client
.
size
())
newp
->
addClient
(
client
);
ps
.
insert
(
newp
);
}
return
true
;
}
// get the parameter matching the given name, or all the
// parameters in the category if no name is given. If we find a
// given parameter by name, we add the client requesting the
// parameter to the list of clients for this parameter. This also
// needs to be locked.
template
<
class
T
>
bool
_get
(
std
::
vector
<
T
>
&
p
,
const
std
::
string
&
name
,
const
std
::
string
&
client
,
std
::
set
<
T
*
,
parameterLessThan
>
&
ps
)
{
p
.
clear
();
if
(
name
.
empty
()){
for
(
typename
std
::
set
<
T
*
,
parameterLessThan
>::
iterator
it
=
ps
.
begin
();
it
!=
ps
.
end
();
it
++
)
p
.
push_back
(
**
it
);
}
else
{
T
tmp
(
name
);
typename
std
::
set
<
T
*
,
parameterLessThan
>::
iterator
it
=
ps
.
find
(
&
tmp
);
if
(
it
!=
ps
.
end
()){
if
(
client
.
size
())
(
*
it
)
->
addClient
(
client
);
p
.
push_back
(
**
it
);
}
}
return
true
;
}
void
_getAllParameters
(
std
::
set
<
parameter
*>
&
ps
)
const
{
ps
.
insert
(
_numbers
.
begin
(),
_numbers
.
end
());
ps
.
insert
(
_strings
.
begin
(),
_strings
.
end
());
ps
.
insert
(
_regions
.
begin
(),
_regions
.
end
());
ps
.
insert
(
_functions
.
begin
(),
_functions
.
end
());
}
public
:
parameterSpace
(){}
~
parameterSpace
(){
clear
();
}
void
clear
()
{
std
::
set
<
parameter
*>
ps
;
_getAllParameters
(
ps
);
for
(
std
::
set
<
parameter
*>::
iterator
it
=
ps
.
begin
();
it
!=
ps
.
end
();
it
++
)
delete
*
it
;
_numbers
.
clear
();
_strings
.
clear
();
_regions
.
clear
();
_functions
.
clear
();
}
bool
set
(
const
number
&
p
,
const
std
::
string
&
client
=
""
){
return
_set
(
p
,
client
,
_numbers
);
}
bool
set
(
const
string
&
p
,
const
std
::
string
&
client
=
""
){
return
_set
(
p
,
client
,
_strings
);
}
bool
set
(
const
region
&
p
,
const
std
::
string
&
client
=
""
){
return
_set
(
p
,
client
,
_regions
);
}
bool
set
(
const
function
&
p
,
const
std
::
string
&
client
=
""
){
return
_set
(
p
,
client
,
_functions
);
}
bool
get
(
std
::
vector
<
number
>
&
ps
,
const
std
::
string
&
name
=
""
,
const
std
::
string
&
client
=
""
){
return
_get
(
ps
,
name
,
client
,
_numbers
);
}
bool
get
(
std
::
vector
<
string
>
&
ps
,
const
std
::
string
&
name
=
""
,
const
std
::
string
&
client
=
""
){
return
_get
(
ps
,
name
,
client
,
_strings
);
}
bool
get
(
std
::
vector
<
region
>
&
ps
,
const
std
::
string
&
name
=
""
,
const
std
::
string
&
client
=
""
){
return
_get
(
ps
,
name
,
client
,
_regions
);
}
bool
get
(
std
::
vector
<
function
>
&
ps
,
const
std
::
string
&
name
=
""
,
const
std
::
string
&
client
=
""
){
return
_get
(
ps
,
name
,
client
,
_functions
);
}
// check if at least one parameter depends on the given client
bool
hasClient
(
const
std
::
string
&
client
)
const
{
std
::
set
<
parameter
*>
ps
;
_getAllParameters
(
ps
);
for
(
std
::
set
<
parameter
*>::
iterator
it
=
ps
.
begin
();
it
!=
ps
.
end
();
it
++
)
if
((
*
it
)
->
hasClient
(
client
))
return
true
;
return
false
;
}
// check if some parameters have changed (optionnally only check
// the parameters that depend on a given client)
bool
getChanged
(
const
std
::
string
&
client
=
""
)
const
{
std
::
set
<
parameter
*>
ps
;
_getAllParameters
(
ps
);
for
(
std
::
set
<
parameter
*>::
iterator
it
=
ps
.
begin
();
it
!=
ps
.
end
();
it
++
){
if
((
client
.
empty
()
||
(
*
it
)
->
hasClient
(
client
))
&&
(
*
it
)
->
getChanged
())
return
true
;
}
return
false
;
}
// set the changed flag for all parameters (optionnally only affect those
// parameters that depend on a given client)
bool
setChanged
(
bool
changed
,
const
std
::
string
&
client
=
""
)
{
std
::
set
<
parameter
*>
ps
;
_getAllParameters
(
ps
);
for
(
std
::
set
<
parameter
*>::
iterator
it
=
ps
.
begin
();
it
!=
ps
.
end
();
it
++
)
if
(
client
.
empty
()
||
(
*
it
)
->
hasClient
(
client
))
(
*
it
)
->
setChanged
(
changed
);
}
// serialize the parameter space (optinally only serialize those
// parameters that depend on the given client)
std
::
string
toChar
(
const
std
::
string
&
client
=
""
)
const
{
std
::
string
s
;
std
::
set
<
parameter
*>
ps
;
_getAllParameters
(
ps
);
for
(
std
::
set
<
parameter
*>::
const_iterator
it
=
ps
.
begin
();
it
!=
ps
.
end
();
it
++
)
if
(
client
.
empty
()
||
(
*
it
)
->
hasClient
(
client
))
s
+=
(
*
it
)
->
toChar
()
+
"
\n
"
;
return
s
;
}
};
// The onelab client: a class that communicates with the onelab
// server. Each client should be derived from this one. A client can
// be understood as "one simulation step in a complex computation".
class
client
{
protected:
// the name of the client
std
::
string
_name
;
// the id of the client, used to create a unique socket for this client
int
_id
;
// the index of the client in an external client list (if any)
int
_index
;
public:
client
(
const
std
::
string
&
name
)
:
_name
(
name
),
_id
(
0
),
_index
(
-
1
){}
virtual
~
client
(){}
std
::
string
getName
(){
return
_name
;
}
void
setId
(
int
id
){
_id
=
id
;
}
int
getId
(){
return
_id
;
}
void
setIndex
(
int
index
){
_index
=
index
;
}
int
getIndex
(){
return
_index
;
}
virtual
bool
run
(
const
std
::
string
&
what
){
return
false
;
}
virtual
bool
isNetworkClient
(){
return
false
;
}
virtual
bool
kill
(){
return
false
;
}
virtual
void
sendInfo
(
const
std
::
string
&
msg
){
std
::
cout
<<
msg
<<
std
::
endl
;
}
virtual
void
sendWarning
(
const
std
::
string
&
msg
){
std
::
cerr
<<
msg
<<
std
::
endl
;
}
virtual
void
sendError
(
const
std
::
string
&
msg
){
std
::
cerr
<<
msg
<<
std
::
endl
;
}
virtual
void
sendProgress
(
const
std
::
string
&
msg
){
std
::
cout
<<
msg
<<
std
::
endl
;
}
virtual
void
sendMergeFileRequest
(
const
std
::
string
&
msg
){}
virtual
void
sendParseStringRequest
(
const
std
::
string
&
msg
){}
virtual
void
sendVertexArray
(
const
std
::
string
&
msg
){}
virtual
bool
set
(
const
number
&
p
)
=
0
;
virtual
bool
set
(
const
string
&
p
)
=
0
;
virtual
bool
set
(
const
region
&
p
)
=
0
;
virtual
bool
set
(
const
function
&
p
)
=
0
;
virtual
bool
get
(
std
::
vector
<
number
>
&
ps
,
const
std
::
string
&
name
=
""
)
=
0
;
virtual
bool
get
(
std
::
vector
<
string
>
&
ps
,
const
std
::
string
&
name
=
""
)
=
0
;
virtual
bool
get
(
std
::
vector
<
region
>
&
ps
,
const
std
::
string
&
name
=
""
)
=
0
;
virtual
bool
get
(
std
::
vector
<
function
>
&
ps
,
const
std
::
string
&
name
=
""
)
=
0
;
};
// The onelab server: a singleton that stores the parameter space
// and interacts with onelab clients.
class
server
{
private:
// the unique server
static
server
*
_server
;
// the address of the server
std
::
string
_address
;
// the connected clients, indexed by name
std
::
map
<
std
::
string
,
client
*>
_clients
;
// the parameter space
parameterSpace
_parameterSpace
;
public:
server
(
const
std
::
string
&
address
=
""
)
:
_address
(
address
)
{}
~
server
(){}
static
server
*
instance
(
const
std
::
string
&
address
=
""
)
{
if
(
!
_server
)
_server
=
new
server
(
address
);
return
_server
;
}
void
clear
(){
_parameterSpace
.
clear
();
}
template
<
class
T
>
bool
set
(
const
T
&
p
,
const
std
::
string
&
client
=
""
)
{
return
_parameterSpace
.
set
(
p
,
client
);
}
template
<
class
T
>
bool
get
(
std
::
vector
<
T
>
&
ps
,
const
std
::
string
&
name
=
""
,
const
std
::
string
&
client
=
""
)
{
return
_parameterSpace
.
get
(
ps
,
name
,
client
);
}
typedef
std
::
map
<
std
::
string
,
client
*>::
iterator
citer
;
citer
firstClient
(){
return
_clients
.
begin
();
}
citer
lastClient
(){
return
_clients
.
end
();
}
citer
findClient
(
const
std
::
string
&
name
){
return
_clients
.
find
(
name
);
}
void
registerClient
(
client
*
c
)
{
_clients
[
c
->
getName
()]
=
c
;
c
->
setId
(
_clients
.
size
());
}
void
unregisterClient
(
client
*
c
){
_clients
.
erase
(
c
->
getName
());
}
void
setChanged
(
bool
changed
,
const
std
::
string
&
client
=
""
)
{
_parameterSpace
.
setChanged
(
changed
,
client
);
}
bool
getChanged
(
const
std
::
string
&
client
=
""
)
{
return
_parameterSpace
.
getChanged
(
client
);
}
std
::
string
toChar
(
const
std
::
string
&
client
=
""
)
{
return
_parameterSpace
.
toChar
(
client
);
}
};
class
localClient
:
public
client
{
private:
template
<
class
T
>
bool
_set
(
const
T
&
p
)
{
server
::
instance
()
->
set
(
p
,
_name
);
return
true
;
}
template
<
class
T
>
bool
_get
(
std
::
vector
<
T
>
&
ps
,
const
std
::
string
&
name
=
""
)
{
server
::
instance
()
->
get
(
ps
,
name
,
_name
);
return
true
;
}
public
:
localClient
(
const
std
::
string
&
name
)
:
client
(
name
)
{
server
::
instance
()
->
registerClient
(
this
);
}
virtual
~
localClient
(){}
virtual
bool
set
(
const
number
&
p
){
return
_set
(
p
);
}
virtual
bool
set
(
const
string
&
p
){
return
_set
(
p
);
}
virtual
bool
set
(
const
function
&
p
){
return
_set
(
p
);
}
virtual
bool
set
(
const
region
&
p
){
return
_set
(
p
);
}
virtual
bool
get
(
std
::
vector
<
number
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
virtual
bool
get
(
std
::
vector
<
string
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
virtual
bool
get
(
std
::
vector
<
function
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
virtual
bool
get
(
std
::
vector
<
region
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
};
class
localNetworkClient
:
public
localClient
{
private:
// command line to launch the remote network client
std
::
string
_commandLine
;
// command line option to specify socket
std
::
string
_socketSwitch
;
// pid of the remote network client
int
_pid
;
// underlying GmshServer
GmshServer
*
_gmshServer
;
public:
localNetworkClient
(
const
std
::
string
&
name
,
const
std
::
string
&
commandLine
)
:
localClient
(
name
),
_commandLine
(
commandLine
),
_socketSwitch
(
"-onelab"
),
_pid
(
-
1
),
_gmshServer
(
0
)
{}
virtual
~
localNetworkClient
(){}
virtual
bool
isNetworkClient
(){
return
true
;
}
const
std
::
string
&
getCommandLine
(){
return
_commandLine
;
}
void
setCommandLine
(
const
std
::
string
&
s
){
_commandLine
=
s
;
}
const
std
::
string
&
getSocketSwitch
(){
return
_socketSwitch
;
}
void
setSocketSwitch
(
const
std
::
string
&
s
){
_socketSwitch
=
s
;
}
int
getPid
(){
return
_pid
;
}
void
setPid
(
int
pid
){
_pid
=
pid
;
}
GmshServer
*
getGmshServer
(){
return
_gmshServer
;
}
void
setGmshServer
(
GmshServer
*
server
){
_gmshServer
=
server
;
}
virtual
bool
run
(
const
std
::
string
&
what
);
virtual
bool
kill
();
};
class
remoteNetworkClient
:
public
client
{
private:
// address (inet:port or unix socket) of the server
std
::
string
_serverAddress
;
// underlying GmshClient
GmshClient
*
_gmshClient
;
template
<
class
T
>
bool
_set
(
const
T
&
p
)
{
if
(
!
_gmshClient
)
return
false
;
std
::
string
msg
=
p
.
toChar
();
_gmshClient
->
SendMessage
(
GmshSocket
::
GMSH_PARAMETER
,
msg
.
size
(),
&
msg
[
0
]);
return
true
;
}
template
<
class
T
>
bool
_get
(
std
::
vector
<
T
>
&
ps
,
const
std
::
string
&
name
=
""
)
{
ps
.
clear
();
if
(
!
_gmshClient
)
return
false
;
T
p
(
name
);
std
::
string
msg
=
p
.
toChar
();
_gmshClient
->
SendMessage
(
GmshSocket
::
GMSH_PARAMETER_QUERY
,
msg
.
size
(),
&
msg
[
0
]);
while
(
1
){
// stop if we have no communications for 10 secs
int
ret
=
_gmshClient
->
Select
(
10
,
0
);
if
(
!
ret
){
_gmshClient
->
Info
(
"Timout: aborting remote get"
);
return
false
;
}
else
if
(
ret
<
0
){
_gmshClient
->
Error
(
"Error on select: aborting remote get"
);
return
false
;
}
int
type
,
length
,
swap
;
if
(
!
_gmshClient
->
ReceiveHeader
(
&
type
,
&
length
,
&
swap
)){
_gmshClient
->
Error
(
"Did not receive message header: aborting remote get"
);
return
false
;
}
std
::
string
msg
(
length
,
' '
);
if
(
!
_gmshClient
->
ReceiveMessage
(
length
,
&
msg
[
0
])){
_gmshClient
->
Error
(
"Did not receive message body: aborting remote get"
);
return
false
;
}
if
(
type
==
GmshSocket
::
GMSH_PARAMETER
){
T
p
;
p
.
fromChar
(
msg
);
ps
.
push_back
(
p
);
return
true
;
}
else
if
(
type
==
GmshSocket
::
GMSH_INFO
){
// parameter not found
return
true
;
}
else
{
_gmshClient
->
Error
(
"Unknown message type: aborting remote get"
);
return
false
;
}
}
return
true
;
}
public
:
remoteNetworkClient
(
const
std
::
string
&
name
,
const
std
::
string
&
serverAddress
)
:
client
(
name
),
_serverAddress
(
serverAddress
)
{
_gmshClient
=
new
GmshClient
();
if
(
_gmshClient
->
Connect
(
_serverAddress
.
c_str
())
<
0
){
delete
_gmshClient
;
_gmshClient
=
0
;
}
else
{
_gmshClient
->
Start
();
}
}
virtual
~
remoteNetworkClient
()
{
if
(
_gmshClient
){
_gmshClient
->
Stop
();
_gmshClient
->
Disconnect
();
delete
_gmshClient
;
_gmshClient
=
0
;
}
}
GmshClient
*
getGmshClient
(){
return
_gmshClient
;
}
virtual
bool
isNetworkClient
(){
return
true
;
}
virtual
bool
set
(
const
number
&
p
){
return
_set
(
p
);
}
virtual
bool
set
(
const
string
&
p
){
return
_set
(
p
);
}
virtual
bool
set
(
const
function
&
p
){
return
_set
(
p
);
}
virtual
bool
set
(
const
region
&
p
){
return
_set
(
p
);
}
virtual
bool
get
(
std
::
vector
<
number
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
virtual
bool
get
(
std
::
vector
<
string
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
virtual
bool
get
(
std
::
vector
<
function
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
virtual
bool
get
(
std
::
vector
<
region
>
&
ps
,
const
std
::
string
&
name
=
""
){
return
_get
(
ps
,
name
);
}
void
sendInfo
(
const
std
::
string
&
msg
)
{
if
(
_gmshClient
)
_gmshClient
->
Info
(
msg
.
c_str
());
}
void
sendWarning
(
const
std
::
string
&
msg
)
{
if
(
_gmshClient
)
_gmshClient
->
Warning
(
msg
.
c_str
());
}
void
sendError
(
const
std
::
string
&
msg
)
{
if
(
_gmshClient
)
_gmshClient
->
Error
(
msg
.
c_str
());
}
void
sendProgress
(
const
std
::
string
&
msg
)
{
if
(
_gmshClient
)
_gmshClient
->
Progress
(
msg
.
c_str
());
}
void
sendMergeFileRequest
(
const
std
::
string
&
msg
)
{
if
(
_gmshClient
)
_gmshClient
->
MergeFile
(
msg
.
c_str
());
}
void
sendParseStringRequest
(
const
std
::
string
&
msg
)
{
if
(
_gmshClient
)
_gmshClient
->
ParseString
(
msg
.
c_str
());
}
};
}
#endif
This diff is collapsed.
Click to expand it.
utils/solvers/c++/solver.cpp
0 → 100644
+
36
−
0
View file @
8506977d
#include
<iostream>
#include
<vector>
#include
<string>
#include
"onelab.h"
int
main
(
int
argc
,
char
**
argv
)
{
onelab
::
remoteNetworkClient
*
client
=
0
;
for
(
int
i
=
0
;
i
<
argc
;
i
++
){
if
(
std
::
string
(
argv
[
i
])
==
"-onelab"
&&
i
<
argc
-
1
)
client
=
new
onelab
::
remoteNetworkClient
(
"My solver"
,
argv
[
i
+
1
]);
}
if
(
!
client
){
printf
(
"usage: %s -onelab socket
\n
"
,
argv
[
0
]);
exit
(
1
);
}
std
::
vector
<
onelab
::
string
>
strings
;
// try to get the string variable "My solver/My string" from the server
client
->
get
(
strings
,
"My solver/My string"
);
if
(
strings
.
size
()){
std
::
cout
<<
"Got string from server: '"
<<
strings
[
0
].
getValue
()
<<
"'
\n
"
;
}
else
{
// send a value to the server
onelab
::
string
s
(
"My solver/My string"
,
"Hello!"
);
client
->
set
(
s
);
}
delete
client
;
return
0
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment