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
Package registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Romin Tomasetti
gmsh
Commits
5f4c855e
Commit
5f4c855e
authored
Mar 25, 2020
by
Christophe Geuzaine
Browse files
Options
Downloads
Plain Diff
Merge branch 'master' of
https://gitlab.onelab.info/gmsh/gmsh
parents
1fb6573b
0a62cc77
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Plugin/SpanningTree.cpp
+112
-50
112 additions, 50 deletions
Plugin/SpanningTree.cpp
Plugin/SpanningTree.h
+11
-6
11 additions, 6 deletions
Plugin/SpanningTree.h
with
123 additions
and
56 deletions
Plugin/SpanningTree.cpp
+
112
−
50
View file @
5f4c855e
...
@@ -4,17 +4,26 @@
...
@@ -4,17 +4,26 @@
// issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
// issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
// Contributed by Nicolas Marsic.
// Contributed by Nicolas Marsic.
#include
<sstream>
#include
<algorithm>
#include
"SpanningTree.h"
#include
"SpanningTree.h"
#include
"GModel.h"
#include
"GModel.h"
#include
"MLine.h"
#include
"MLine.h"
#include
"OS.h"
#include
"OS.h"
using
namespace
std
;
StringXNumber
SpanningTreeOptions_Number
[]
=
{
StringXNumber
SpanningTreeOptions_Number
[]
=
{
{
GMSH_FULLRC
,
"PhysicalGroup"
,
NULL
,
-
1
},
{
GMSH_FULLRC
,
"StartingOn"
,
NULL
,
-
1
},
{
GMSH_FULLRC
,
"OutputPhysical"
,
NULL
,
-
1
},
{
GMSH_FULLRC
,
"OutputPhysical"
,
NULL
,
-
1
},
};
};
StringXString
SpanningTreeOptions_String
[]
=
{
{
GMSH_FULLRC
,
"PhysicalVolumes"
,
NULL
,
""
},
{
GMSH_FULLRC
,
"PhysicalSurfaces"
,
NULL
,
""
},
{
GMSH_FULLRC
,
"PhysicalCurves"
,
NULL
,
""
},
};
extern
"C"
{
extern
"C"
{
GMSH_Plugin
*
GMSH_RegisterSpanningTreePlugin
(
void
)
GMSH_Plugin
*
GMSH_RegisterSpanningTreePlugin
(
void
)
{
{
...
@@ -24,37 +33,42 @@ GMSH_Plugin *GMSH_RegisterSpanningTreePlugin(void)
...
@@ -24,37 +33,42 @@ GMSH_Plugin *GMSH_RegisterSpanningTreePlugin(void)
GMSH_SpanningTreePlugin
::
GMSH_SpanningTreePlugin
(
void
)
{}
GMSH_SpanningTreePlugin
::
GMSH_SpanningTreePlugin
(
void
)
{}
std
::
string
GMSH_SpanningTreePlugin
::
getName
(
void
)
const
string
GMSH_SpanningTreePlugin
::
getName
(
void
)
const
{
{
return
"SpanningTree"
;
return
"SpanningTree"
;
}
}
std
::
string
GMSH_SpanningTreePlugin
::
getShortHelp
(
void
)
const
string
GMSH_SpanningTreePlugin
::
getShortHelp
(
void
)
const
{
{
return
"Builds a tree spanning every vertex of a mesh"
;
return
"Builds a tree spanning every vertex of a mesh"
;
}
}
std
::
string
GMSH_SpanningTreePlugin
::
getHelp
(
void
)
const
string
GMSH_SpanningTreePlugin
::
getHelp
(
void
)
const
{
{
return
"Plugin(SpanningTree) builds a tree spanning every vertex of a mesh.
\n
"
return
"Plugin(SpanningTree) builds a tree spanning every vertex of a mesh "
"Optionally, this tree can be built by starting on a specific part.
\n
"
"and stores it directly in the model.
\n
"
"The generated tree is stored directly in the model.
\n
"
"The tree is constructed by starting first on the curves, "
"then on the surfaces and finally on the volumes.
\n
"
"
\n
"
"
\n
"
"Parameters
\n
"
"Parameters
\n
"
"- PhysicalGroup: physical group upon which the tree must be built "
"- PhysicalVolumes: list of the physical volumes "
"(-1 means the whole mesh).
\n
"
"upon which the tree must be built.
\n
"
"- StartingOn: physical group used to start the tree construction "
"- PhysicalSurfaces: list of the physical surfaces "
"(-1 deactivates this feature).
\n
"
"upon which the tree must be built.
\n
"
"- PhysicalCurves: list of the physical curves "
"upon which the tree must be built.
\n
"
"- OutputPhysical: physical tag of the generated tree "
"- OutputPhysical: physical tag of the generated tree "
"(-1 will select a new tag automatically).
\n
"
"(-1 will select a new tag automatically).
\n
"
"
\n
"
"
\n
"
"Note - Lists must be comma separated integers "
"and spaces are ignored.
\n
"
"Remark - This plugin does not overwrite a physical group."
"Remark - This plugin does not overwrite a physical group."
"Therefore, if an existing physical tag is used in OutputPhysical, "
"Therefore, if an existing physical tag is used in OutputPhysical, "
"the edges of the tree will be /added/ to the specified group.
\n
"
"the edges of the tree will be /added/ to the specified group.
\n
"
"Limitation - Unknown behaviour with curved meshes."
;
"Limitation - Unknown behaviour with curved meshes."
;
}
}
std
::
string
GMSH_SpanningTreePlugin
::
getAuthor
(
void
)
const
string
GMSH_SpanningTreePlugin
::
getAuthor
(
void
)
const
{
{
return
"N. Marsic"
;
return
"N. Marsic"
;
}
}
...
@@ -69,45 +83,66 @@ StringXNumber *GMSH_SpanningTreePlugin::getOption(int iopt)
...
@@ -69,45 +83,66 @@ StringXNumber *GMSH_SpanningTreePlugin::getOption(int iopt)
return
&
SpanningTreeOptions_Number
[
iopt
];
return
&
SpanningTreeOptions_Number
[
iopt
];
}
}
int
GMSH_SpanningTreePlugin
::
getNbOptionsStr
()
const
{
return
sizeof
(
SpanningTreeOptions_String
)
/
sizeof
(
StringXString
);
}
StringXString
*
GMSH_SpanningTreePlugin
::
getOptionStr
(
int
iopt
)
{
return
&
SpanningTreeOptions_String
[
iopt
];
}
void
GMSH_SpanningTreePlugin
::
run
(
void
)
void
GMSH_SpanningTreePlugin
::
run
(
void
)
{
{
// Get data
// Get data
double
time
=
Cpu
();
double
time
=
Cpu
();
int
physical
=
(
int
)
SpanningTreeOptions_Number
[
0
].
def
;
int
output
=
(
int
)
SpanningTreeOptions_Number
[
0
].
def
;
int
startOn
=
(
int
)
SpanningTreeOptions_Number
[
1
].
def
;
string
volume
=
SpanningTreeOptions_String
[
0
].
def
;
int
output
=
(
int
)
SpanningTreeOptions_Number
[
2
].
def
;
string
surface
=
SpanningTreeOptions_String
[
1
].
def
;
string
curve
=
SpanningTreeOptions_String
[
2
].
def
;
// Parse physical tags
vector
<
list
<
int
>
>
physical
(
3
);
curve
=
parse
(
curve
,
physical
[
0
]);
surface
=
parse
(
surface
,
physical
[
1
]);
volume
=
parse
(
volume
,
physical
[
2
]);
// Dimensions
int
dim
[
3
]
=
{
1
,
2
,
3
};
// Get model
// Get model
GModel
*
model
=
GModel
::
current
();
GModel
*
model
=
GModel
::
current
();
// Get all elements in physical
// Get all elements in physicals for each dimension
ElementSet
element
;
vector
<
ElementSet
>
element
(
3
);
getAllMElement
(
*
model
,
physical
,
element
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
for
(
list
<
int
>::
iterator
j
=
physical
[
i
].
begin
();
j
!=
physical
[
i
].
end
();
j
++
)
// Get all elements in startOn (if defined)
getAllMElement
(
*
model
,
*
j
,
dim
[
i
],
element
[
i
]);
ElementSet
elementStartOn
;
if
(
startOn
>=
0
)
getAllMElement
(
*
model
,
startOn
,
elementStartOn
);
// Check if we have something
// Check if we have something
if
(
element
.
empty
()
&&
element
StartOn
.
empty
())
{
if
(
element
[
0
]
.
empty
()
&&
element
[
1
].
empty
()
&&
element
[
2
]
.
empty
())
{
Msg
::
Warning
(
"No elements found in physcial
%d
: abording!"
,
physical
);
Msg
::
Warning
(
"No elements found in
the given
physcial
s
: abording!"
);
return
;
return
;
}
}
// Get all edges from elements
// Display physicals (as [poorly] parsed) //
EdgeSet
edge
;
Msg
::
Info
(
"--> PhysicalVolumes: %s"
,
volume
.
c_str
());
getAllMEdge
(
element
,
edge
);
Msg
::
Info
(
"--> PhysicalSurfaces: %s"
,
surface
.
c_str
());
Msg
::
Info
(
"--> PhysicalCurves: %s"
,
curve
.
c_str
());
Msg
::
Info
(
"--> OutputPhysical: %d"
,
output
);
// Get all edges from startOn (if defined)
// Get all edges from elements for each dimension
EdgeSet
edgeStartOn
;
vector
<
EdgeSet
>
edge
(
3
);
if
(
startOn
>=
0
)
getAllMEdge
(
elementStartOn
,
edgeStartOn
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
getAllMEdge
(
element
[
i
],
edge
[
i
]);
// Build spanning tree
and save into the model (begin with startOn if defined)
// Build spanning tree
(in ascending dimension order) and save into the model
DSU
vertex
(
model
->
getNumMeshVertices
());
DSU
vertex
(
model
->
getNumMeshVertices
());
Tree
tree
;
Tree
tree
;
if
(
startOn
>=
0
)
spanningTree
(
edgeStartOn
,
vertex
,
tree
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
spanningTree
(
edge
[
i
],
vertex
,
tree
);
spanningTree
(
edge
,
vertex
,
tree
);
addToModel
(
*
model
,
tree
,
output
);
addToModel
(
*
model
,
tree
,
output
);
// Done
// Done
...
@@ -132,21 +167,48 @@ void GMSH_SpanningTreePlugin::spanningTree(EdgeSet &edge, DSU &vertex,
...
@@ -132,21 +167,48 @@ void GMSH_SpanningTreePlugin::spanningTree(EdgeSet &edge, DSU &vertex,
}
}
}
}
void
GMSH_SpanningTreePlugin
::
getAllMElement
(
GModel
&
model
,
int
physical
,
string
GMSH_SpanningTreePlugin
::
parse
(
string
str
,
list
<
int
>&
physical
)
ElementSet
&
element
)
{
{
std
::
vector
<
GEntity
*>
entities
;
// Remove spaces //
str
.
erase
(
remove
(
str
.
begin
(),
str
.
end
(),
' '
),
str
.
end
());
// Replace commas by spaces //
replace
(
str
.
begin
(),
str
.
end
(),
','
,
' '
);
// Init string stream //
stringstream
stream
;
stream
<<
str
;
// Parse stream for integers //
int
tag
;
string
tmp
;
while
(
!
stream
.
eof
()){
stream
>>
tmp
;
// Take next 'word'
if
(
sscanf
(
tmp
.
c_str
(),
"%d"
,
&
tag
)
>
0
)
physical
.
push_back
(
tag
);
}
if
(
physical
==
-
1
)
{
model
.
getEntities
(
entities
,
-
1
);
}
// Return modified string //
else
{
return
str
;
std
::
map
<
int
,
std
::
vector
<
GEntity
*>
>
groups
;
model
.
getPhysicalGroups
(
-
1
,
groups
);
entities
=
groups
[
physical
];
}
}
for
(
size_t
i
=
0
;
i
<
entities
.
size
();
i
++
)
void
GMSH_SpanningTreePlugin
::
getAllMElement
(
GModel
&
model
,
int
physical
,
for
(
size_t
j
=
0
;
j
<
entities
[
i
]
->
getNumMeshElements
();
j
++
)
int
dim
,
ElementSet
&
element
)
element
.
insert
(
entities
[
i
]
->
getMeshElement
(
j
));
{
std
::
map
<
int
,
std
::
vector
<
GEntity
*>
>
group
;
std
::
map
<
int
,
std
::
vector
<
GEntity
*>
>::
iterator
entity
;
// Get groups //
model
.
getPhysicalGroups
(
dim
,
group
);
// Get entities, if any //
entity
=
group
.
find
(
physical
);
if
(
entity
==
group
.
end
())
return
;
for
(
size_t
i
=
0
;
i
<
entity
->
second
.
size
();
i
++
)
for
(
size_t
j
=
0
;
j
<
entity
->
second
[
i
]
->
getNumMeshElements
();
j
++
)
element
.
insert
(
entity
->
second
[
i
]
->
getMeshElement
(
j
));
}
}
void
GMSH_SpanningTreePlugin
::
getAllMEdge
(
ElementSet
&
element
,
EdgeSet
&
edge
)
void
GMSH_SpanningTreePlugin
::
getAllMEdge
(
ElementSet
&
element
,
EdgeSet
&
edge
)
...
...
This diff is collapsed.
Click to expand it.
Plugin/SpanningTree.h
+
11
−
6
View file @
5f4c855e
...
@@ -52,12 +52,17 @@ public:
...
@@ -52,12 +52,17 @@ public:
int
getNbOptions
(
void
)
const
;
int
getNbOptions
(
void
)
const
;
StringXNumber
*
getOption
(
int
iopt
);
StringXNumber
*
getOption
(
int
iopt
);
int
getNbOptionsStr
()
const
;
StringXString
*
getOptionStr
(
int
iopt
);
void
run
(
void
);
void
run
(
void
);
private
:
private
:
static
void
spanningTree
(
EdgeSet
&
edge
,
DSU
&
vertex
,
Tree
&
tree
);
static
void
spanningTree
(
EdgeSet
&
edge
,
DSU
&
vertex
,
Tree
&
tree
);
static
void
getAllMElement
(
GModel
&
model
,
int
physical
,
ElementSet
&
element
);
static
std
::
string
parse
(
std
::
string
str
,
std
::
list
<
int
>&
physical
);
static
void
getAllMElement
(
GModel
&
model
,
int
physical
,
int
dim
,
ElementSet
&
element
);
static
void
getAllMEdge
(
ElementSet
&
element
,
EdgeSet
&
edge
);
static
void
getAllMEdge
(
ElementSet
&
element
,
EdgeSet
&
edge
);
static
void
addToModel
(
GModel
&
model
,
Tree
&
tree
,
int
tag
);
static
void
addToModel
(
GModel
&
model
,
Tree
&
tree
,
int
tag
);
...
...
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