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
feb3fce9
Commit
feb3fce9
authored
9 years ago
by
Jonathan Lambrechts
Browse files
Options
Downloads
Patches
Plain Diff
add FieldExternalProcess
parent
a156173c
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
Common/GmshMessage.cpp
+2
-0
2 additions, 0 deletions
Common/GmshMessage.cpp
Mesh/Field.cpp
+241
-7
241 additions, 7 deletions
Mesh/Field.cpp
with
243 additions
and
7 deletions
Common/GmshMessage.cpp
+
2
−
0
View file @
feb3fce9
...
...
@@ -155,6 +155,8 @@ void Msg::Init(int argc, char **argv)
void
Msg
::
Exit
(
int
level
)
{
if
(
GModel
::
current
())
delete
GModel
::
current
();
// delete the temp file
if
(
!
_commRank
)
UnlinkFile
(
CTX
::
instance
()
->
homeDir
+
CTX
::
instance
()
->
tmpFileName
);
...
...
This diff is collapsed.
Click to expand it.
Mesh/Field.cpp
+
241
−
7
View file @
feb3fce9
...
...
@@ -7,7 +7,8 @@
// Jonathan Lambrechts
//
#include
<stdlib.h>
#include
<cstdlib>
#include
<limits>
#include
<list>
#include
<math.h>
#include
<fstream>
...
...
@@ -34,6 +35,13 @@
#include
"MVertex.h"
#endif
#if defined(WIN32) && !defined(__CYGWIN__)
#include
<windows.h>
#include
<io.h>
#else
#include
<unistd.h>
#endif
#if defined(HAVE_ANN)
#include
"ANN/ANN.h"
#endif
...
...
@@ -1074,17 +1082,11 @@ class MathEvalField : public Field
std
::
string
f
;
public:
void
myAction
()
{
printf
(
"doing sthg
\n
"
);
}
MathEvalField
()
{
options
[
"F"
]
=
new
FieldOptionString
(
f
,
"Mathematical function to evaluate."
,
&
update_needed
);
f
=
"F2 + Sin(z)"
;
callbacks
[
"test"
]
=
new
FieldCallbackGeneric
<
MathEvalField
>
(
this
,
&
MathEvalField
::
myAction
,
"description blabla"
);
}
double
operator
()
(
double
x
,
double
y
,
double
z
,
GEntity
*
ge
=
0
)
{
...
...
@@ -1173,6 +1175,235 @@ class MathEvalFieldAniso : public Field
}
};
#if defined(WIN32) && !defined(__CYGWIN__)
//windows implementation from https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
class
Popen2
{
HANDLE
_hIn
,
_hOut
;
public:
Popen2
(){
_hIn
=
NULL
;
_hOut
=
NULL
;
}
void
stop
(){
if
(
_hIn
)
{
CloseHandle
(
_hIn
);
CloseHandle
(
_hOut
);
_hIn
=
_hOut
=
NULL
;
}
}
bool
started
()
const
{
return
_hIn
;
}
bool
start
(
const
char
*
command
)
{
stop
();
HANDLE
hChildStd_OUT_Wr
,
hChildStd_IN_Rd
;
PROCESS_INFORMATION
piProcInfo
;
SECURITY_ATTRIBUTES
saAttr
;
saAttr
.
nLength
=
sizeof
(
SECURITY_ATTRIBUTES
);
saAttr
.
bInheritHandle
=
TRUE
;
saAttr
.
lpSecurityDescriptor
=
NULL
;
if
(
!
CreatePipe
(
&
_hIn
,
&
hChildStd_OUT_Wr
,
&
saAttr
,
0
))
Msg
::
Error
(
"StdoutRd CreatePipe"
);
if
(
!
CreatePipe
(
&
hChildStd_IN_Rd
,
&
_hOut
,
&
saAttr
,
0
))
Msg
::
Error
(
"Stdin CreatePipe"
);
if
(
!
CreatePipe
(
&
_hIn
,
&
hChildStd_OUT_Wr
,
&
saAttr
,
0
))
Msg
::
Error
(
"StdoutRd CreatePipe"
);
if
(
!
SetHandleInformation
(
_hIn
,
HANDLE_FLAG_INHERIT
,
0
))
Msg
::
Error
(
"Stdout SetHandleInformation"
);
STARTUPINFO
siStartInfo
;
BOOL
bSuccess
=
FALSE
;
ZeroMemory
(
&
piProcInfo
,
sizeof
(
PROCESS_INFORMATION
)
);
ZeroMemory
(
&
siStartInfo
,
sizeof
(
STARTUPINFO
)
);
siStartInfo
.
cb
=
sizeof
(
STARTUPINFO
);
siStartInfo
.
hStdError
=
GetStdHandle
(
STD_ERROR_HANDLE
);
siStartInfo
.
hStdOutput
=
hChildStd_OUT_Wr
;
siStartInfo
.
hStdInput
=
hChildStd_IN_Rd
;
siStartInfo
.
dwFlags
|=
STARTF_USESTDHANDLES
;
bSuccess
=
CreateProcess
(
NULL
,
(
char
*
)
command
,
NULL
,
NULL
,
TRUE
,
0
,
NULL
,
NULL
,
&
siStartInfo
,
&
piProcInfo
);
if
(
!
bSuccess
){
Msg
::
Error
(
"Child process creation failed %i"
,
GetLastError
());
_hIn
=
_hOut
=
NULL
;
return
false
;
}
CloseHandle
(
piProcInfo
.
hProcess
);
CloseHandle
(
piProcInfo
.
hThread
);
return
true
;
}
bool
read
(
void
*
data
,
size_t
size
)
{
if
(
!
_hIn
)
return
false
;
DWORD
nSuccess
=
0
;
ReadFile
(
_hIn
,
data
,
size
,
&
nSuccess
,
NULL
);
return
nSuccess
==
size
;
}
bool
write
(
void
*
data
,
size_t
size
)
{
if
(
!
_hOut
)
return
false
;
DWORD
nSuccess
=
0
;
WriteFile
(
_hOut
,
data
,
size
,
&
nSuccess
,
NULL
);
return
nSuccess
==
size
;
}
~
Popen2
()
{
stop
();
}
};
#else //unix
class
Popen2
{
int
_fdIn
,
_fdOut
;
public:
Popen2
(){
_fdIn
=
_fdOut
=
-
1
;
}
void
stop
(){
if
(
_fdIn
!=
-
1
)
{
::
close
(
_fdIn
);
::
close
(
_fdOut
);
_fdIn
=
_fdOut
=
-
1
;
}
}
bool
started
()
const
{
return
_fdIn
;}
bool
start
(
const
char
*
command
)
{
stop
();
int
p_stdin
[
2
],
p_stdout
[
2
];
if
(
pipe
(
p_stdin
)
!=
0
||
pipe
(
p_stdout
)
!=
0
)
return
false
;
int
pid
=
fork
();
if
(
pid
<
0
)
return
false
;
else
if
(
pid
==
0
)
{
close
(
p_stdin
[
1
]);
dup2
(
p_stdin
[
0
],
0
);
close
(
p_stdout
[
0
]);
dup2
(
p_stdout
[
1
],
1
);
execl
(
"/bin/sh"
,
"sh"
,
"-c"
,
command
,
NULL
);
perror
(
"execl"
);
exit
(
0
);
}
_fdOut
=
p_stdin
[
1
];
_fdIn
=
p_stdout
[
0
];
return
true
;
}
bool
read
(
void
*
data
,
size_t
size
)
{
return
::
read
(
_fdIn
,
data
,
size
)
==
(
ssize_t
)
size
;
}
bool
write
(
void
*
data
,
size_t
size
)
{
return
::
write
(
_fdOut
,
data
,
size
)
==
(
ssize_t
)
size
;
}
~
Popen2
()
{
stop
();
}
};
#endif
class
ExternalProcessField
:
public
Field
{
std
::
string
_cmdLine
;
Popen2
_pipes
;
void
closePipes
()
{
if
(
_pipes
.
started
())
{
double
xyz
[
3
]
=
{
std
::
numeric_limits
<
double
>::
quiet_NaN
(),
std
::
numeric_limits
<
double
>::
quiet_NaN
(),
std
::
numeric_limits
<
double
>::
quiet_NaN
()
};
_pipes
.
write
((
void
*
)
xyz
,
3
*
sizeof
(
double
));
_pipes
.
stop
();
}
}
public
:
ExternalProcessField
()
{
options
[
"CommandLine"
]
=
new
FieldOptionString
(
_cmdLine
,
"Command line to launch."
,
&
update_needed
);
_cmdLine
=
""
;
}
~
ExternalProcessField
()
{
closePipes
();
}
double
operator
()
(
double
x
,
double
y
,
double
z
,
GEntity
*
ge
=
0
)
{
double
xyz
[
3
]
=
{
x
,
y
,
z
};
double
f
;
if
(
update_needed
)
{
closePipes
();
_pipes
.
start
(
_cmdLine
.
c_str
());
update_needed
=
false
;
}
if
(
!
_pipes
.
write
((
void
*
)
xyz
,
3
*
sizeof
(
double
))
||
!
_pipes
.
read
((
void
*
)
&
f
,
sizeof
(
double
))){
f
=
1e22
;
// std::numeric_limits<double>::max();
}
return
f
;
}
const
char
*
getName
()
{
return
"ExternalProcess"
;
}
std
::
string
getDescription
()
{
return
"**This Field is experimental**
\n
"
"Call an external process that received coordinates triple (x,y,z) "
"as binary double precision numbers on stdin and is supposed to write the "
"field value on stdout as a binary double precision number.
\n
"
"NaN,NaN,NaN is sent as coordinate to indicate the end of the process.
\n
"
"
\n
"
"Example of client (python2):
\n
"
"import os
\n
"
"import struct
\n
"
"import math
\n
"
"import sys
\n
"
"if sys.platform ==
\"
win32
\"
:
\n
"
"import msvcrt
\n
"
"msvcrt.setmode(0, os.O_BINARY)
\n
"
"msvcrt.setmode(1, os.O_BINARY)
\n
"
"while(True):
\n
"
"____xyz = struct.unpack(
\"
ddd
\"
, os.read(0,24))
\n
"
"____if math.isnan(xyz[0]):
\n
"
"_________break
\n
"
"____f = 0.001 + xyz[1]*0.009
\n
"
"____os.write(1,struct.pack(
\"
d
\"
,f))
\n
"
"
\n
"
"Example of client (python3):
\n
"
"import struct
\n
"
"import sys
\n
"
"import math
\n
"
"while(True):
\n
"
"____xyz = struct.unpack(
\"
ddd
\"
, sys.stdin.buffer.read(24))
\n
"
"____if math.isnan(xyz[0]):
\n
"
"________break
\n
"
"____f = 0.001 + xyz[1]*0.009
\n
"
"____sys.stdout.buffer.write(struct.pack(
\"
d
\"
,f))
\n
"
"____sys.stdout.flush()
\n
"
"
\n
"
"Example of client (c, unix):
\n
"
"#include <unistd.h>
\n
"
"int main(int argc, char **argv) {
\n
"
"__double xyz[3];
\n
"
"__while(read(STDIN_FILENO, &xyz, 3*sizeof(double)) == 3*sizeof(double)) {
\n
"
"____if (xyz[0] != xyz[0]) break; //nan
\n
"
"____double f = 0.001 + 0.009 * xyz[1];
\n
"
"____write(STDOUT_FILENO, &f, sizeof(double));
\n
"
"__}
\n
"
"__return 0;
\n
"
"}
\n
"
"
\n
"
"Example of client (c, windows):
\n
"
"#include <stdio.h>
\n
"
"#include <io.h>
\n
"
"#include <fcntl.h>
\n
"
"int main(int argc, char **argv) {
\n
"
"__double xyz[3];
\n
"
"__setmode(fileno(stdin),O_BINARY);
\n
"
"__setmode(fileno(stdout),O_BINARY);
\n
"
"__while(read(fileno(stdin), &xyz, 3*sizeof(double)) == 3*sizeof(double)) {
\n
"
"____if (xyz[0] != xyz[0])
\n
"
"______break;
\n
"
"____double f = f = 0.01 + 0.09 * xyz[1];
\n
"
"____write(fileno(stdout), &f, sizeof(double));
\n
"
"__}
\n
"
"}
\n
"
;
}
};
class
ParametricField
:
public
Field
{
MathEvalExpression
expr
[
3
];
...
...
@@ -2333,6 +2564,7 @@ FieldManager::FieldManager()
map_type_name
[
"Mean"
]
=
new
FieldFactoryT
<
MeanField
>
();
map_type_name
[
"Curvature"
]
=
new
FieldFactoryT
<
CurvatureField
>
();
map_type_name
[
"Param"
]
=
new
FieldFactoryT
<
ParametricField
>
();
map_type_name
[
"ExternalProcess"
]
=
new
FieldFactoryT
<
ExternalProcessField
>
();
map_type_name
[
"MathEval"
]
=
new
FieldFactoryT
<
MathEvalField
>
();
map_type_name
[
"MathEvalAniso"
]
=
new
FieldFactoryT
<
MathEvalFieldAniso
>
();
#if defined(HAVE_ANN)
...
...
@@ -2349,6 +2581,8 @@ FieldManager::~FieldManager()
for
(
std
::
map
<
std
::
string
,
FieldFactory
*>::
iterator
it
=
map_type_name
.
begin
();
it
!=
map_type_name
.
end
();
it
++
)
delete
it
->
second
;
for
(
FieldManager
::
iterator
it
=
begin
();
it
!=
end
();
it
++
)
delete
it
->
second
;
}
void
FieldManager
::
setBackgroundField
(
Field
*
BGF
)
...
...
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