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
Analyze
Contributor 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
gmsh
gmsh
Commits
a2f6433e
Commit
a2f6433e
authored
12 years ago
by
Thomas Toulorge
Browse files
Options
Downloads
Patches
Plain Diff
Changed determination of blobs for high-order mesh optimization (GUI still to be adapted)
parent
d18285c5
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
contrib/HighOrderMeshOptimizer/OptHomRun.cpp
+267
-392
267 additions, 392 deletions
contrib/HighOrderMeshOptimizer/OptHomRun.cpp
with
267 additions
and
392 deletions
contrib/HighOrderMeshOptimizer/OptHomRun.cpp
+
267
−
392
View file @
a2f6433e
...
@@ -22,6 +22,8 @@
...
@@ -22,6 +22,8 @@
#include
"FlGui.h"
#include
"FlGui.h"
#endif
#endif
void
OptHomMessage
(
const
char
*
s
,
...)
{
void
OptHomMessage
(
const
char
*
s
,
...)
{
char
str
[
1024
];
char
str
[
1024
];
va_list
args
;
va_list
args
;
...
@@ -39,16 +41,17 @@ void OptHomMessage (const char *s, ...) {
...
@@ -39,16 +41,17 @@ void OptHomMessage (const char *s, ...) {
}
}
}
}
else
else
fprintf
(
stdout
,
"%s
\n
"
,
str
);
fprintf
(
stdout
,
"%s
\n
"
,
str
);
#else
#else
fprintf
(
stdout
,
"%s
\n
"
,
str
);
fprintf
(
stdout
,
"%s
\n
"
,
str
);
#endif
#endif
}
}
// get all elements that are neighbors
double
distMaxStraight
(
MElement
*
el
){
double
distMaxStraight
(
MElement
*
el
)
{
const
polynomialBasis
*
lagrange
=
el
->
getFunctionSpace
();
const
polynomialBasis
*
lagrange
=
el
->
getFunctionSpace
();
const
polynomialBasis
*
lagrange1
=
el
->
getFunctionSpace
(
1
);
const
polynomialBasis
*
lagrange1
=
el
->
getFunctionSpace
(
1
);
int
nV
=
lagrange
->
points
.
size1
();
int
nV
=
lagrange
->
points
.
size1
();
...
@@ -68,23 +71,76 @@ double distMaxStraight (MElement *el){
...
@@ -68,23 +71,76 @@ double distMaxStraight (MElement *el){
for
(
int
iV
=
nV1
;
iV
<
nV
;
iV
++
)
{
for
(
int
iV
=
nV1
;
iV
<
nV
;
iV
++
)
{
SVector3
d
=
el
->
getVertex
(
iV
)
->
point
()
-
sxyz
[
iV
];
SVector3
d
=
el
->
getVertex
(
iV
)
->
point
()
-
sxyz
[
iV
];
double
dx
=
d
.
norm
();
double
dx
=
d
.
norm
();
if
(
dx
>
maxdx
)
maxdx
=
dx
;
if
(
dx
>
maxdx
)
maxdx
=
dx
;
}
}
return
maxdx
;
return
maxdx
;
}
SVector3
vecMaxStraight
(
MElement
*
el
)
{
const
polynomialBasis
*
lagrange
=
el
->
getFunctionSpace
();
const
polynomialBasis
*
lagrange1
=
el
->
getFunctionSpace
(
1
);
int
nV
=
lagrange
->
points
.
size1
();
int
nV1
=
lagrange1
->
points
.
size1
();
SPoint3
sxyz
[
256
];
for
(
int
i
=
0
;
i
<
nV1
;
++
i
)
{
sxyz
[
i
]
=
el
->
getVertex
(
i
)
->
point
();
}
for
(
int
i
=
nV1
;
i
<
nV
;
++
i
)
{
double
f
[
256
];
lagrange1
->
f
(
lagrange
->
points
(
i
,
0
),
lagrange
->
points
(
i
,
1
),
lagrange
->
points
(
i
,
2
),
f
);
for
(
int
j
=
0
;
j
<
nV1
;
++
j
)
sxyz
[
i
]
+=
sxyz
[
j
]
*
f
[
j
];
}
double
maxdx
=
0.0
;
SVector3
maxVec
;
for
(
int
iV
=
nV1
;
iV
<
nV
;
iV
++
)
{
SVector3
d
=
el
->
getVertex
(
iV
)
->
point
()
-
sxyz
[
iV
];
double
dx
=
d
.
norm
();
if
(
dx
>
maxdx
)
{
maxdx
=
dx
;
maxVec
=
d
;
}
}
return
maxVec
;
}
static
void
PrintBlob
(
std
::
set
<
MElement
*>
&
eles
,
int
iTag
){
char
name
[
256
];
sprintf
(
name
,
"BLOB%d.pos"
,
iTag
);
FILE
*
f
=
fopen
(
name
,
"w"
);
fprintf
(
f
,
"View
\"
%s
\"
{
\n
"
,
name
);
for
(
std
::
set
<
MElement
*>::
iterator
it
=
eles
.
begin
();
it
!=
eles
.
end
();
++
it
){
(
*
it
)
->
writePOS
(
f
,
true
,
false
,
false
,
false
,
false
,
false
,
1.0
,
iTag
);
}
fprintf
(
f
,
"};
\n
"
);
fclose
(
f
);
}
}
void
exportMeshToDassault
(
GModel
*
gm
,
const
std
::
string
&
fn
,
int
dim
){
void
exportMeshToDassault
(
GModel
*
gm
,
const
std
::
string
&
fn
,
int
dim
){
FILE
*
f
=
fopen
(
fn
.
c_str
(),
"w"
);
FILE
*
f
=
fopen
(
fn
.
c_str
(),
"w"
);
int
numVertices
=
gm
->
indexMeshVertices
(
true
);
int
numVertices
=
gm
->
indexMeshVertices
(
true
);
std
::
vector
<
GEntity
*>
entities
;
std
::
vector
<
GEntity
*>
entities
;
gm
->
getEntities
(
entities
);
gm
->
getEntities
(
entities
);
fprintf
(
f
,
"%d %d
\n
"
,
numVertices
,
dim
);
fprintf
(
f
,
"%d %d
\n
"
,
numVertices
,
dim
);
for
(
unsigned
int
i
=
0
;
i
<
entities
.
size
();
i
++
)
for
(
unsigned
int
i
=
0
;
i
<
entities
.
size
();
i
++
)
for
(
unsigned
int
j
=
0
;
j
<
entities
[
i
]
->
mesh_vertices
.
size
();
j
++
){
for
(
unsigned
int
j
=
0
;
j
<
entities
[
i
]
->
mesh_vertices
.
size
();
j
++
){
MVertex
*
v
=
entities
[
i
]
->
mesh_vertices
[
j
];
MVertex
*
v
=
entities
[
i
]
->
mesh_vertices
[
j
];
if
(
dim
==
2
)
fprintf
(
f
,
"%d %22.15E %22.15E
\n
"
,
v
->
getIndex
(),
v
->
x
(),
v
->
y
());
if
(
dim
==
2
)
fprintf
(
f
,
"%d %22.15E %22.15E
\n
"
,
v
->
getIndex
(),
v
->
x
(),
v
->
y
());
else
if
(
dim
==
3
)
fprintf
(
f
,
"%d %22.15E %22.15E %22.5E
\n
"
,
v
->
getIndex
(),
v
->
x
(),
v
->
y
(),
v
->
z
());
else
if
(
dim
==
3
)
fprintf
(
f
,
"%d %22.15E %22.15E %22.5E
\n
"
,
v
->
getIndex
(),
v
->
x
(),
v
->
y
(),
v
->
z
());
}
}
if
(
dim
==
2
){
if
(
dim
==
2
){
...
@@ -95,15 +151,15 @@ void exportMeshToDassault (GModel *gm, const std::string &fn, int dim){
...
@@ -95,15 +151,15 @@ void exportMeshToDassault (GModel *gm, const std::string &fn, int dim){
nt
+=
tris
.
size
();
nt
+=
tris
.
size
();
if
(
tris
.
size
())
order
=
tris
[
0
]
->
getPolynomialOrder
();
if
(
tris
.
size
())
order
=
tris
[
0
]
->
getPolynomialOrder
();
}
}
fprintf
(
f
,
"%d %d
\n
"
,
nt
,(
order
+
1
)
*
(
order
+
2
)
/
2
);
fprintf
(
f
,
"%d %d
\n
"
,
nt
,(
order
+
1
)
*
(
order
+
2
)
/
2
);
int
count
=
1
;
int
count
=
1
;
for
(
GModel
::
fiter
itf
=
gm
->
firstFace
();
itf
!=
gm
->
lastFace
();
++
itf
){
for
(
GModel
::
fiter
itf
=
gm
->
firstFace
();
itf
!=
gm
->
lastFace
();
++
itf
){
std
::
vector
<
MTriangle
*>
&
tris
=
(
*
itf
)
->
triangles
;
std
::
vector
<
MTriangle
*>
&
tris
=
(
*
itf
)
->
triangles
;
for
(
size_t
i
=
0
;
i
<
tris
.
size
();
i
++
){
for
(
size_t
i
=
0
;
i
<
tris
.
size
();
i
++
){
MTriangle
*
t
=
tris
[
i
];
MTriangle
*
t
=
tris
[
i
];
fprintf
(
f
,
"%d "
,
count
++
);
fprintf
(
f
,
"%d "
,
count
++
);
for
(
int
j
=
0
;
j
<
t
->
getNumVertices
();
j
++
){
for
(
int
j
=
0
;
j
<
t
->
getNumVertices
();
j
++
){
fprintf
(
f
,
"%d "
,
t
->
getVertex
(
j
)
->
getIndex
());
fprintf
(
f
,
"%d "
,
t
->
getVertex
(
j
)
->
getIndex
());
}
}
fprintf
(
f
,
"
\n
"
);
fprintf
(
f
,
"
\n
"
);
}
}
...
@@ -113,15 +169,15 @@ void exportMeshToDassault (GModel *gm, const std::string &fn, int dim){
...
@@ -113,15 +169,15 @@ void exportMeshToDassault (GModel *gm, const std::string &fn, int dim){
std
::
vector
<
MLine
*>
&
l
=
(
*
ite
)
->
lines
;
std
::
vector
<
MLine
*>
&
l
=
(
*
ite
)
->
lines
;
ne
+=
l
.
size
();
ne
+=
l
.
size
();
}
}
fprintf
(
f
,
"%d %d
\n
"
,
ne
,(
order
+
1
));
fprintf
(
f
,
"%d %d
\n
"
,
ne
,(
order
+
1
));
count
=
1
;
count
=
1
;
for
(
GModel
::
eiter
ite
=
gm
->
firstEdge
();
ite
!=
gm
->
lastEdge
();
++
ite
){
for
(
GModel
::
eiter
ite
=
gm
->
firstEdge
();
ite
!=
gm
->
lastEdge
();
++
ite
){
std
::
vector
<
MLine
*>
&
l
=
(
*
ite
)
->
lines
;
std
::
vector
<
MLine
*>
&
l
=
(
*
ite
)
->
lines
;
for
(
size_t
i
=
0
;
i
<
l
.
size
();
i
++
){
for
(
size_t
i
=
0
;
i
<
l
.
size
();
i
++
){
MLine
*
t
=
l
[
i
];
MLine
*
t
=
l
[
i
];
fprintf
(
f
,
"%d "
,
count
++
);
fprintf
(
f
,
"%d "
,
count
++
);
for
(
int
j
=
0
;
j
<
t
->
getNumVertices
();
j
++
){
for
(
int
j
=
0
;
j
<
t
->
getNumVertices
();
j
++
){
fprintf
(
f
,
"%d "
,
t
->
getVertex
(
j
)
->
getIndex
());
fprintf
(
f
,
"%d "
,
t
->
getVertex
(
j
)
->
getIndex
());
}
}
fprintf
(
f
,
"%d
\n
"
,(
*
ite
)
->
tag
());
fprintf
(
f
,
"%d
\n
"
,(
*
ite
)
->
tag
());
}
}
...
@@ -132,242 +188,136 @@ void exportMeshToDassault (GModel *gm, const std::string &fn, int dim){
...
@@ -132,242 +188,136 @@ void exportMeshToDassault (GModel *gm, const std::string &fn, int dim){
static
void
getTopologicalNeighbors
(
int
nbLayers
,
static
std
::
set
<
MVertex
*>
getBndVertices
(
std
::
set
<
MElement
*>
&
elements
,
std
::
map
<
MVertex
*
,
std
::
vector
<
MElement
*>
>
&
vertex2elements
)
const
std
::
vector
<
MElement
*>
&
all
,
{
const
std
::
vector
<
MElement
*>
&
elements
,
std
::
set
<
MVertex
*>
bnd
;
std
::
set
<
MElement
*>
&
result
){
for
(
std
::
set
<
MElement
*>::
iterator
itE
=
elements
.
begin
();
itE
!=
elements
.
end
();
++
itE
)
{
for
(
int
i
=
0
;
i
<
(
*
itE
)
->
getNumPrimaryVertices
();
++
i
)
{
const
std
::
vector
<
MElement
*>
&
neighbours
=
vertex2elements
[(
*
itE
)
->
getVertex
(
i
)];
std
::
set
<
MVertex
*>
touched
;
for
(
size_t
k
=
0
;
k
<
neighbours
.
size
();
++
k
)
{
if
(
elements
.
find
(
neighbours
[
k
])
==
elements
.
end
())
{
for
(
int
i
=
0
;
i
<
elements
.
size
();
i
++
)
for
(
int
j
=
0
;
j
<
neighbours
[
k
]
->
getNumVertices
();
++
j
)
{
for
(
int
j
=
0
;
j
<
elements
[
i
]
->
getNumVertices
();
j
++
)
bnd
.
insert
(
neighbours
[
k
]
->
getVertex
(
j
));
touched
.
insert
(
elements
[
i
]
->
getVertex
(
j
));
}
for
(
int
layer
=
0
;
layer
<
nbLayers
;
layer
++
)
{
for
(
int
i
=
0
;
i
<
all
.
size
();
i
++
)
{
MElement
*
t
=
all
[
i
];
bool
add_
=
false
;
for
(
int
j
=
0
;
j
<
t
->
getNumVertices
();
j
++
)
{
if
(
touched
.
find
(
t
->
getVertex
(
j
))
!=
touched
.
end
())
{
add_
=
true
;
}
}
}
}
if
(
add_
)
result
.
insert
(
t
);
}
for
(
std
::
set
<
MElement
*>::
iterator
it
=
result
.
begin
();
it
!=
result
.
end
();
++
it
)
{
for
(
int
j
=
0
;
j
<
(
*
it
)
->
getNumVertices
();
j
++
)
{
touched
.
insert
((
*
it
)
->
getVertex
(
j
));
}
}
}
}
}
// printf("%d %d %d %d\n",all.size(),elements.size(), result.size(),nbLayers);
return
bnd
;
// exit(1);
}
}
static
void
getGeometricalNeighbors
(
MElement
*
e
,
const
std
::
vector
<
MElement
*>
&
all
,
double
F
,
std
::
set
<
MElement
*>
&
result
)
{
double
R
=
distMaxStraight
(
e
);
SPoint3
p
=
e
->
barycenter_infty
();
static
std
::
set
<
MElement
*>
getSurroundingBlob
(
MElement
*
el
,
int
depth
,
std
::
map
<
MVertex
*
,
std
::
vector
<
MElement
*>
>
&
vertex2elements
,
const
double
distFactor
)
for
(
int
i
=
0
;
i
<
all
.
size
();
i
++
)
{
{
MElement
*
e
=
all
[
i
];
double
dist
=
p
.
distance
(
e
->
barycenter_infty
());
if
(
dist
<
R
*
F
)
result
.
insert
(
e
);
}
}
static
void
intersection
(
const
std
::
set
<
MElement
*>
&
a
,
const
std
::
set
<
MElement
*>
&
b
,
std
::
set
<
MElement
*>
&
result
){
const
SPoint3
p
=
el
->
barycenter_infty
();
for
(
std
::
set
<
MElement
*>::
const_iterator
it
=
a
.
begin
()
;
it
!=
a
.
end
()
;
++
it
){
const
double
limDist
=
distMaxStraight
(
el
)
*
distFactor
;
if
(
b
.
find
(
*
it
)
!=
b
.
end
()){
result
.
insert
(
*
it
);
std
::
set
<
MElement
*>
blob
;
}
std
::
list
<
MElement
*>
currentLayer
,
lastLayer
;
}
}
static
void
computeVertices
(
const
std
::
set
<
MElement
*>
&
a
,
std
::
set
<
MVertex
*>
&
result
){
blob
.
insert
(
el
);
for
(
std
::
set
<
MElement
*>::
const_iterator
it
=
a
.
begin
()
;
it
!=
a
.
end
()
;
++
it
){
lastLayer
.
push_back
(
el
);
for
(
int
i
=
0
;
i
<
(
*
it
)
->
getNumVertices
();
++
i
){
for
(
int
d
=
0
;
d
<
depth
;
++
d
)
{
result
.
insert
((
*
it
)
->
getVertex
(
i
));
currentLayer
.
clear
();
for
(
std
::
list
<
MElement
*>::
iterator
it
=
lastLayer
.
begin
();
it
!=
lastLayer
.
end
();
++
it
)
{
for
(
int
i
=
0
;
i
<
(
*
it
)
->
getNumPrimaryVertices
();
++
i
)
{
const
std
::
vector
<
MElement
*>
&
neighbours
=
vertex2elements
[(
*
it
)
->
getVertex
(
i
)];
for
(
std
::
vector
<
MElement
*>::
const_iterator
itN
=
neighbours
.
begin
();
itN
!=
neighbours
.
end
();
++
itN
)
if
(
p
.
distance
((
*
itN
)
->
barycenter_infty
())
<
limDist
)
if
(
blob
.
insert
(
*
itN
).
second
)
currentLayer
.
push_back
(
*
itN
);
// Assume that if an el is too far, its neighbours are too far as well
}
}
}
lastLayer
=
currentLayer
;
}
}
}
static
MElement
*
compare_worst
(
MElement
*
a
,
MElement
*
b
){
return
blob
;
if
(
!
a
)
return
b
;
if
(
!
b
)
return
a
;
if
(
a
->
distoShapeMeasure
()
<
b
->
distoShapeMeasure
())
return
a
;
return
b
;
}
template
<
class
ITERATOR
>
MElement
*
getTheWorstElementDown
(
const
ITERATOR
&
beg
,
const
ITERATOR
&
end
,
double
&
q
)
{
MElement
*
worst
=
0
;
q
=
1.e22
;
ITERATOR
it
=
beg
;
for
(;
it
!=
end
;
++
it
){
MElement
*
t
=
*
it
;
double
jmin
,
jmax
;
t
->
scaledJacRange
(
jmin
,
jmax
);
if
(
jmin
<
q
)
{
worst
=
t
;
q
=
jmin
;
}
}
return
worst
;
}
}
template
<
class
ITERATOR
>
MElement
*
getTheWorstElementUp
(
const
ITERATOR
&
beg
,
const
ITERATOR
&
end
,
double
&
q
)
{
MElement
*
worst
=
0
;
q
=
-
1.e22
;
ITERATOR
it
=
beg
;
for
(;
it
!=
end
;
++
it
){
MElement
*
t
=
*
it
;
double
jmin
,
jmax
;
t
->
scaledJacRange
(
jmin
,
jmax
);
if
(
jmax
>
q
)
{
worst
=
t
;
q
=
jmax
;
}
}
return
worst
;
}
static
std
::
set
<
MVertex
*>
filterSimple
(
GEntity
&
ge
,
std
::
set
<
MElement
*>
&
badElements
,
int
nbLayers
,
std
::
set
<
MElement
*>
&
result
)
// Returns max. dist. between primary vertices of an element
static
double
elementSize
(
MElement
*
el
)
{
{
std
::
vector
<
MElement
*>
allElements
;
for
(
int
i
=
0
;
i
<
ge
.
getNumMeshElements
();
++
i
)
allElements
.
push_back
(
ge
.
getMeshElement
(
i
));
OptHomMessage
(
"%d bad elements"
,
badElements
.
size
());
getTopologicalNeighbors
(
nbLayers
,
allElements
,
std
::
vector
<
MElement
*>
(
badElements
.
begin
(),
badElements
.
end
()),
result
);
std
::
set
<
MVertex
*>
vs
;
for
(
int
i
=
0
;
i
<
allElements
.
size
();
i
++
)
{
if
(
result
.
find
(
allElements
[
i
])
==
result
.
end
())
{
for
(
int
j
=
0
;
j
<
allElements
[
i
]
->
getNumVertices
();
j
++
)
{
vs
.
insert
(
allElements
[
i
]
->
getVertex
(
j
));
}
}
}
return
vs
;
}
std
::
set
<
MVertex
*>
filter2D_boundaryLayer
(
GFace
*
gf
,
std
::
vector
<
SPoint3
>
vert
;
int
nbLayers
,
vert
.
reserve
(
el
->
getNumPrimaryVertices
());
double
_qual_min
,
for
(
int
i
=
0
;
i
<
el
->
getNumPrimaryVertices
();
i
++
)
vert
.
push_back
(
el
->
getVertex
(
i
)
->
point
());
double
_qual_max
,
double
F
,
std
::
set
<
MElement
*>
&
badasses
,
std
::
set
<
MElement
*>
&
result
)
{
double
jmin
,
jmax
;
MElement
*
worstDown
=
getTheWorstElementDown
(
badasses
.
begin
(),
badasses
.
end
(),
jmin
);
MElement
*
worstUp
=
getTheWorstElementUp
(
badasses
.
begin
(),
badasses
.
end
(),
jmax
);
MElement
*
worst
;
if
(
jmin
<
_qual_min
)
worst
=
worstDown
;
else
worst
=
worstUp
;
// MElement *worst = compare_worst (getTheWorstElement(gf->triangles),
// getTheWorstElement(gf->quadrangles));
std
::
vector
<
MElement
*>
vworst
;
vworst
.
push_back
(
worst
);
std
::
vector
<
MElement
*>
all
;
all
.
insert
(
all
.
begin
(),
gf
->
triangles
.
begin
(),
gf
->
triangles
.
end
());
all
.
insert
(
all
.
begin
(),
gf
->
quadrangles
.
begin
(),
gf
->
quadrangles
.
end
());
std
::
set
<
MElement
*>
result1
;
getTopologicalNeighbors
(
nbLayers
,
all
,
vworst
,
result1
);
std
::
set
<
MElement
*>
result2
;
getGeometricalNeighbors
(
worst
,
all
,
F
,
result2
);
intersection
(
result1
,
result2
,
result
);
// printf("intsersection(%d,%d) = %d\n",result1.size(),result2.size(),result.size());
std
::
set
<
MVertex
*>
vs
;
for
(
int
i
=
0
;
i
<
all
.
size
();
i
++
)
{
if
(
result
.
find
(
all
[
i
])
==
result
.
end
())
{
for
(
int
j
=
0
;
j
<
all
[
i
]
->
getNumVertices
();
j
++
)
{
vs
.
insert
(
all
[
i
]
->
getVertex
(
j
));
}
}
}
return
vs
;
}
double
maxDistSq
=
0
;
for
(
int
i
=
0
;
i
<
el
->
getNumPrimaryVertices
()
-
1
;
i
++
)
for
(
int
j
=
i
+
1
;
j
<
el
->
getNumPrimaryVertices
();
j
++
)
maxDistSq
=
std
::
max
(
maxDistSq
,
SVector3
(
vert
[
j
]
-
vert
[
i
]).
normSq
());
std
::
set
<
MVertex
*>
filter3D_boundaryLayer
(
GRegion
*
gr
,
return
sqrt
(
maxDistSq
);
int
nbLayers
,
double
_qual_min
,
double
_qual_max
,
double
F
,
std
::
set
<
MElement
*>
&
result
)
{
double
jmin
,
jmax
;
MElement
*
worst
=
compare_worst
(
getTheWorstElementDown
(
gr
->
tetrahedra
.
begin
(),
gr
->
tetrahedra
.
end
(),
jmin
),
getTheWorstElementDown
(
gr
->
prisms
.
begin
(),
gr
->
prisms
.
end
(),
jmin
));
worst
=
compare_worst
(
worst
,
getTheWorstElementDown
(
gr
->
hexahedra
.
begin
(),
gr
->
hexahedra
.
end
(),
jmin
));
std
::
vector
<
MElement
*>
vworst
;
vworst
.
push_back
(
worst
);
std
::
vector
<
MElement
*>
all
;
all
.
insert
(
all
.
begin
(),
gr
->
tetrahedra
.
begin
(),
gr
->
tetrahedra
.
end
());
all
.
insert
(
all
.
begin
(),
gr
->
prisms
.
begin
(),
gr
->
prisms
.
end
());
all
.
insert
(
all
.
begin
(),
gr
->
hexahedra
.
begin
(),
gr
->
hexahedra
.
end
());
std
::
set
<
MElement
*>
result1
;
getTopologicalNeighbors
(
nbLayers
,
all
,
vworst
,
result1
);
std
::
set
<
MElement
*>
result2
;
getGeometricalNeighbors
(
worst
,
all
,
F
,
result2
);
intersection
(
result1
,
result2
,
result
);
// printf("intsersection(%d,%d) = %d\n",result1.size(),result2.size(),result.size());
std
::
set
<
MVertex
*>
vs
;
for
(
int
i
=
0
;
i
<
all
.
size
();
i
++
)
{
if
(
result
.
find
(
all
[
i
])
==
result
.
end
())
{
for
(
int
j
=
0
;
j
<
all
[
i
]
->
getNumVertices
();
j
++
)
{
vs
.
insert
(
all
[
i
]
->
getVertex
(
j
));
}
}
}
return
vs
;
}
static
std
::
set
<
MVertex
*>
getBndVertices
(
std
::
set
<
MElement
*>
&
elements
,
std
::
map
<
MVertex
*
,
std
::
vector
<
MElement
*>
>
&
vertex2elements
)
{
std
::
set
<
MVertex
*>
bnd
;
for
(
std
::
set
<
MElement
*>::
iterator
itE
=
elements
.
begin
();
itE
!=
elements
.
end
();
++
itE
)
{
for
(
int
i
=
0
;
i
<
(
*
itE
)
->
getNumPrimaryVertices
();
++
i
)
{
const
std
::
vector
<
MElement
*>
&
neighbours
=
vertex2elements
[(
*
itE
)
->
getVertex
(
i
)];
for
(
size_t
k
=
0
;
k
<
neighbours
.
size
();
++
k
)
{
if
(
elements
.
find
(
neighbours
[
k
])
==
elements
.
end
())
{
for
(
int
j
=
0
;
j
<
neighbours
[
k
]
->
getNumVertices
();
++
j
)
{
bnd
.
insert
(
neighbours
[
k
]
->
getVertex
(
j
));
}
}
}
}
}
return
bnd
;
}
}
static
std
::
set
<
MElement
*>
getSurroundingBlob
(
MElement
*
el
,
int
depth
,
std
::
map
<
MVertex
*
,
std
::
vector
<
MElement
*>
>
&
vertex2elements
)
static
std
::
set
<
MElement
*>
getSurroundingBlob_BL
(
MElement
*
el
,
int
depth
,
std
::
map
<
MVertex
*
,
std
::
vector
<
MElement
*>
>
&
vertex2elements
,
const
double
distFactor
)
{
{
std
::
set
<
MElement
*>
blob
;
std
::
set
<
MElement
*>
currentLayer
,
lastLayer
;
const
SPoint3
p
=
el
->
barycenter_infty
();
const
double
halfElSize
=
0.5
*
elementSize
(
el
);
//std::cout << "El. " << el->getNum() << " -> halfElSize = " << halfElSize << "\n";
SVector3
dir
=
vecMaxStraight
(
el
);
dir
.
normalize
();
//std::cout << "El. " << el->getNum() << " -> direction (" << dir(0) << ", " << dir(1) << ", " << dir(2) << ")\n";
std
::
set
<
MElement
*>
blob
;
std
::
list
<
MElement
*>
currentLayer
,
lastLayer
;
blob
.
insert
(
el
);
blob
.
insert
(
el
);
lastLayer
.
insert
(
el
);
lastLayer
.
push_back
(
el
);
for
(
int
d
=
0
;
d
<
depth
;
++
d
)
{
for
(
int
d
=
0
;
d
<
depth
;
++
d
)
{
for
(
std
::
set
<
MElement
*>::
iterator
it
=
lastLayer
.
begin
();
it
!=
lastLayer
.
end
();
++
it
)
{
currentLayer
.
clear
();
for
(
int
i
=
0
;
i
<
(
*
it
)
->
getNumPrimaryVertices
();
++
i
){
for
(
std
::
list
<
MElement
*>::
iterator
it
=
lastLayer
.
begin
();
it
!=
lastLayer
.
end
();
++
it
)
{
for
(
int
i
=
0
;
i
<
(
*
it
)
->
getNumPrimaryVertices
();
++
i
)
{
const
std
::
vector
<
MElement
*>
&
neighbours
=
vertex2elements
[(
*
it
)
->
getVertex
(
i
)];
const
std
::
vector
<
MElement
*>
&
neighbours
=
vertex2elements
[(
*
it
)
->
getVertex
(
i
)];
for
(
size_t
k
=
0
;
k
<
neighbours
.
size
();
++
k
)
{
for
(
std
::
vector
<
MElement
*>::
const_iterator
itN
=
neighbours
.
begin
();
itN
!=
neighbours
.
end
();
++
itN
)
{
if
(
blob
.
find
(
neighbours
[
k
])
!=
blob
.
end
())
const
SVector3
barBar
=
(
*
itN
)
->
barycenter_infty
()
-
p
;
continue
;
const
SVector3
barProj
=
dir
*
dot
(
dir
,
barBar
);
blob
.
insert
(
neighbours
[
k
]);
double
projDist
=
(
barBar
-
barProj
).
norm
();
currentLayer
.
insert
(
neighbours
[
k
]);
//std::cout << "El. " << el->getNum() << ", d = " << d << ", i = " << i << ", projDist = " << projDist << "\n";
double
elSize2
=
elementSize
(
*
itN
);
if
(
projDist
<=
halfElSize
+
elSize2
)
if
(
blob
.
insert
(
*
itN
).
second
)
currentLayer
.
push_back
(
*
itN
);
// Assume that if an el is too far, its neighbours are too far as well
}
}
}
}
}
}
lastLayer
=
currentLayer
;
lastLayer
=
currentLayer
;
}
}
//std::cout << " -> Blob of " << blob.size() << " elements\n";
return
blob
;
return
blob
;
}
static
void
addBlobChaintoGroup
(
std
::
set
<
int
>
&
group
,
const
std
::
vector
<
std
::
set
<
int
>
>
&
groupConnect
,
std
::
vector
<
bool
>
&
todoPB
,
int
iB
)
{
if
(
todoPB
[
iB
])
{
todoPB
[
iB
]
=
false
;
group
.
insert
(
iB
);
const
std
::
set
<
int
>
&
connect
=
groupConnect
[
iB
];
for
(
std
::
set
<
int
>::
iterator
itBC
=
connect
.
begin
();
itBC
!=
connect
.
end
();
++
itBC
)
addBlobChaintoGroup
(
group
,
groupConnect
,
todoPB
,
*
itBC
);
}
}
}
static
std
::
vector
<
std
::
pair
<
std
::
set
<
MElement
*>
,
std
::
set
<
MVertex
*>
>
>
getConnectedBlobs
(
GEntity
&
entity
,
const
std
::
set
<
MElement
*>
&
badElements
,
int
depth
)
static
std
::
vector
<
std
::
pair
<
std
::
set
<
MElement
*>
,
std
::
set
<
MVertex
*>
>
>
getConnectedBlobs
(
GEntity
&
entity
,
const
std
::
set
<
MElement
*>
&
badElements
,
int
depth
,
const
double
distFactor
)
{
{
// Compute vertex -> element connectivity
// std::cout << "Computing vertex -> element connectivity...\n";
std
::
map
<
MVertex
*
,
std
::
vector
<
MElement
*>
>
vertex2elements
;
std
::
map
<
MVertex
*
,
std
::
vector
<
MElement
*>
>
vertex2elements
;
for
(
size_t
i
=
0
;
i
<
entity
.
getNumMeshElements
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
entity
.
getNumMeshElements
();
++
i
)
{
MElement
&
element
=
*
entity
.
getMeshElement
(
i
);
MElement
&
element
=
*
entity
.
getMeshElement
(
i
);
...
@@ -375,45 +325,69 @@ static std::vector<std::pair<std::set<MElement*> , std::set<MVertex*> > > getCon
...
@@ -375,45 +325,69 @@ static std::vector<std::pair<std::set<MElement*> , std::set<MVertex*> > > getCon
vertex2elements
[
element
.
getVertex
(
j
)].
push_back
(
&
element
);
vertex2elements
[
element
.
getVertex
(
j
)].
push_back
(
&
element
);
}
}
}
}
std
::
vector
<
std
::
pair
<
std
::
set
<
MElement
*>
,
std
::
set
<
MVertex
*>
>
>
result
;
std
::
set
<
MElement
*>
badElementsDone
;
// Contruct primary blobs
// std::cout << "Constructing " << badElements.size() << " primary blobs...\n";
std
::
vector
<
std
::
set
<
MElement
*>
>
primBlobs
;
primBlobs
.
reserve
(
badElements
.
size
());
for
(
std
::
set
<
MElement
*>::
const_iterator
it
=
badElements
.
begin
();
it
!=
badElements
.
end
();
++
it
)
{
for
(
std
::
set
<
MElement
*>::
const_iterator
it
=
badElements
.
begin
();
it
!=
badElements
.
end
();
++
it
)
{
if
(
badElementsDone
.
find
(
*
it
)
!=
badElementsDone
.
end
(
))
primBlobs
.
push_back
(
getSurroundingBlob
(
*
it
,
depth
,
vertex2elements
,
distFactor
))
;
continue
;
//
blobs.push_back(getSurroundingBlob_BL(*it, depth, vertex2elements, distFactor))
;
std
::
stack
<
MElement
*>
todo
;
}
todo
.
push
(
*
it
);
result
.
resize
(
result
.
size
()
+
1
);
while
(
!
todo
.
empty
())
{
// Compute blob connectivity
MElement
*
el
=
todo
.
top
()
;
// std::cout << "Computing blob connectivity...\n"
;
todo
.
pop
()
;
std
::
map
<
MElement
*
,
std
::
set
<
int
>
>
tags
;
if
(
badElementsDone
.
find
(
el
)
==
badElementsDone
.
end
())
{
std
::
vector
<
std
::
set
<
int
>
>
blobConnect
(
primBlobs
.
size
())
;
std
::
set
<
MElement
*>
blob
=
getSurroundingBlob
(
el
,
depth
,
vertex2elements
);
for
(
int
iB
=
0
;
iB
<
primBlobs
.
size
();
++
iB
)
{
for
(
std
::
set
<
MElement
*>
::
iterator
itE
=
blob
.
begin
();
itE
!=
blob
.
end
();
++
itE
)
{
std
::
set
<
MElement
*>
&
blob
=
primBlobs
[
iB
];
if
(
badElements
.
find
(
*
itE
)
!=
b
adElements
.
end
())
for
(
std
::
set
<
MElement
*>::
iterator
itEl
=
blob
.
begin
();
itE
l
!=
b
lob
.
end
();
++
itEl
)
{
todo
.
push
(
*
itE
)
;
std
::
set
<
int
>
&
blobInd
=
tags
[
*
itE
l
]
;
}
if
(
!
blobInd
.
empty
())
{
badElementsDone
.
insert
(
el
);
for
(
std
::
set
<
int
>::
iterator
itBS
=
blobInd
.
begin
();
itBS
!=
blobInd
.
end
();
++
itBS
)
blobConnect
[
*
itBS
]
.
insert
(
iB
);
result
.
back
().
first
.
insert
(
blob
.
begin
(),
blob
.
end
());
blobConnect
[
iB
]
.
insert
(
blob
Ind
.
begin
(),
blob
Ind
.
end
());
}
}
blobInd
.
insert
(
iB
);
}
}
result
.
back
().
second
=
getBndVertices
(
result
.
back
().
first
,
vertex2elements
);
}
}
return
result
;
}
// Identify groups of connected blobs
// std::cout << "Identifying groups of primary blobs...\n";
std
::
list
<
std
::
set
<
int
>
>
groups
;
std
::
vector
<
bool
>
todoPB
(
primBlobs
.
size
(),
true
);
for
(
int
iB
=
0
;
iB
<
primBlobs
.
size
();
++
iB
)
if
(
todoPB
[
iB
])
{
std
::
set
<
int
>
group
;
addBlobChaintoGroup
(
group
,
blobConnect
,
todoPB
,
iB
);
groups
.
push_back
(
group
);
}
static
void
PrintBlob
(
std
::
set
<
MElement
*>
&
eles
,
int
iTag
){
// Merge primary blobs according to groups
char
name
[
256
];
// std::cout << "Merging primary blobs into " << groups.size() << " blobs...\n";
sprintf
(
name
,
"BLOB%d.pos"
,
iTag
);
std
::
list
<
std
::
set
<
MElement
*>
>
blobs
;
FILE
*
f
=
fopen
(
name
,
"w"
);
for
(
std
::
list
<
std
::
set
<
int
>
>::
iterator
itG
=
groups
.
begin
();
itG
!=
groups
.
end
();
++
itG
)
{
fprintf
(
f
,
"View
\"
%s
\"
{
\n
"
,
name
);
blobs
.
push_back
(
std
::
set
<
MElement
*>
());
for
(
std
::
set
<
MElement
*>::
iterator
it
=
eles
.
begin
();
it
!=
eles
.
end
();
++
it
){
for
(
std
::
set
<
int
>::
iterator
itB
=
itG
->
begin
();
itB
!=
itG
->
end
();
++
itB
)
{
(
*
it
)
->
writePOS
(
f
,
true
,
false
,
false
,
false
,
false
,
false
,
1.0
,
iTag
);
std
::
set
<
MElement
*>
primBlob
=
primBlobs
[
*
itB
];
blobs
.
back
().
insert
(
primBlob
.
begin
(),
primBlob
.
end
());
}
}
}
fprintf
(
f
,
"};
\n
"
);
fclose
(
f
);
// Store and compute blob boundaries
// std::cout << "Storing and computing boundaries for " << blobs.size() << " blobs...\n";
std
::
vector
<
std
::
pair
<
std
::
set
<
MElement
*>
,
std
::
set
<
MVertex
*>
>
>
result
;
for
(
std
::
list
<
std
::
set
<
MElement
*>
>::
iterator
itB
=
blobs
.
begin
();
itB
!=
blobs
.
end
();
++
itB
)
result
.
push_back
(
std
::
pair
<
std
::
set
<
MElement
*>
,
std
::
set
<
MVertex
*>
>
(
*
itB
,
getBndVertices
(
*
itB
,
vertex2elements
)));
// std::cout << "Done with blobs\n";
return
result
;
}
}
void
HighOrderMeshOptimizer
(
GModel
*
gm
,
OptHomParameters
&
p
)
void
HighOrderMeshOptimizer
(
GModel
*
gm
,
OptHomParameters
&
p
)
{
{
...
@@ -421,9 +395,6 @@ void HighOrderMeshOptimizer (GModel *gm, OptHomParameters &p)
...
@@ -421,9 +395,6 @@ void HighOrderMeshOptimizer (GModel *gm, OptHomParameters &p)
int
samples
=
30
;
int
samples
=
30
;
// int method = Mesh::METHOD_RELAXBND | Mesh::METHOD_PHYSCOORD | Mesh::METHOD_PROJJAC;
// int method = Mesh::METHOD_FIXBND | Mesh::METHOD_PHYSCOORD | Mesh::METHOD_PROJJAC;
// int method = Mesh::METHOD_FIXBND | Mesh::METHOD_SURFCOORD | Mesh::METHOD_PROJJAC;
int
method
=
0
;
int
method
=
0
;
if
(
p
.
method
==
0
)
if
(
p
.
method
==
0
)
method
=
Mesh
::
METHOD_FIXBND
|
Mesh
::
METHOD_PROJJAC
;
method
=
Mesh
::
METHOD_FIXBND
|
Mesh
::
METHOD_PROJJAC
;
...
@@ -434,161 +405,65 @@ void HighOrderMeshOptimizer (GModel *gm, OptHomParameters &p)
...
@@ -434,161 +405,65 @@ void HighOrderMeshOptimizer (GModel *gm, OptHomParameters &p)
else
if
(
p
.
method
<
0
)
else
if
(
p
.
method
<
0
)
method
=
-
p
.
method
;
method
=
-
p
.
method
;
// printf("p.method = %d\n",p.method);
// int method = Mesh::METHOD_SURFCOORD | Mesh::METHOD_PROJJAC;
// int method = Mesh::METHOD_RELAXBND | Mesh::METHOD_SURFCOORD | Mesh::METHOD_PROJJAC;
// int method = Mesh::METHOD_PROJJAC;
SVector3
BND
(
gm
->
bounds
().
max
(),
gm
->
bounds
().
min
());
SVector3
BND
(
gm
->
bounds
().
max
(),
gm
->
bounds
().
min
());
OptHomMessage
(
"High order mesh optimizer starts"
);
OptHomMessage
(
"High order mesh optimizer starts"
);
std
::
vector
<
GEntity
*>
entities
;
gm
->
getEntities
(
entities
);
if
(
p
.
filter
==
0
)
{
for
(
int
i
=
0
;
i
<
entities
.
size
();
++
i
)
{
std
::
vector
<
GEntity
*>
entities
;
gm
->
getEntities
(
entities
);
for
(
int
i
=
0
;
i
<
entities
.
size
();
++
i
)
{
double
tf1
=
Cpu
();;
GEntity
&
entity
=
*
entities
[
i
];
if
(
entity
.
dim
()
!=
p
.
dim
||
(
p
.
onlyVisible
&&
!
entity
.
getVisibility
()))
continue
;
OptHomMessage
(
"Optimizing Model entity %4d..."
,
entity
.
tag
());
std
::
set
<
MElement
*>
badasses
;
for
(
int
i
=
0
;
i
<
entity
.
getNumMeshElements
();
i
++
){
double
jmin
,
jmax
;
//entity.getMeshElement(i)->scaledJacRange(jmin,jmax);
jmin
=
jmax
=
entity
.
getMeshElement
(
i
)
->
distoShapeMeasure
();
if
(
jmin
<
p
.
BARRIER_MIN
||
jmax
>
p
.
BARRIER_MAX
)
badasses
.
insert
(
entity
.
getMeshElement
(
i
));
}
if
(
badasses
.
empty
())
continue
;
std
::
vector
<
std
::
pair
<
std
::
set
<
MElement
*>
,
std
::
set
<
MVertex
*>
>
>
toOptimize
=
getConnectedBlobs
(
entity
,
badasses
,
p
.
nbLayers
);
//#pragma omp parallel for schedule(dynamic, 1)
p
.
SUCCESS
=
1
;
for
(
int
i
=
0
;
i
<
toOptimize
.
size
();
++
i
)
{
PrintBlob
(
toOptimize
[
i
].
first
,
i
+
1
);
OptHomMessage
(
"Optimizing a blob %i/%i composed of %4d elements"
,
i
+
1
,
toOptimize
.
size
(),
toOptimize
[
i
].
first
.
size
());
fflush
(
stdout
);
OptHOM
temp
(
&
entity
,
toOptimize
[
i
].
first
,
toOptimize
[
i
].
second
,
method
);
int
success
=
temp
.
optimize
(
p
.
weightFixed
,
p
.
weightFree
,
p
.
BARRIER_MIN
,
p
.
BARRIER_MAX
,
false
,
samples
,
p
.
itMax
,
p
.
optPassMax
);
if
(
success
>=
0
&&
p
.
BARRIER_MIN_METRIC
>
0
)
{
OptHomMessage
(
"jacobian optimization succeed, starting svd optimization"
);
success
=
temp
.
optimize
(
p
.
weightFixed
,
p
.
weightFree
,
p
.
BARRIER_MIN_METRIC
,
p
.
BARRIER_MAX
,
true
,
samples
,
p
.
itMax
,
p
.
optPassMax
);
}
temp
.
mesh
.
updateGEntityPositions
();
if
(
success
<=
0
)
{
std
::
ostringstream
ossI2
;
ossI2
<<
"final_"
<<
entity
.
tag
()
<<
"ITER_"
<<
i
<<
".msh"
;
temp
.
mesh
.
writeMSH
(
ossI2
.
str
().
c_str
());
}
//#pragma omp critical
p
.
SUCCESS
=
std
::
min
(
p
.
SUCCESS
,
success
);
}
double
DTF
=
Cpu
()
-
tf1
;
if
(
p
.
SUCCESS
==
1
)
OptHomMessage
(
"Optimization succeeded for entity %d (CPU %g sec)"
,
entity
.
tag
(),
DTF
);
else
if
(
p
.
SUCCESS
==
0
)
OptHomMessage
(
"Warning : Model entity %4d has all jacobians positive but not all in the range CPU %g"
,
entity
.
tag
(),
DTF
);
else
if
(
p
.
SUCCESS
==
-
1
)
OptHomMessage
(
"Error : Model entity %4d has still negative jacobians"
,
entity
.
tag
());
}
}
else
{
double
distMaxBND
,
distAvgBND
,
minJac
,
maxJac
;
if
(
p
.
dim
==
2
)
{
double
tf1
=
Cpu
();;
for
(
GModel
::
fiter
itf
=
gm
->
firstFace
();
itf
!=
gm
->
lastFace
();
++
itf
)
{
if
(
p
.
onlyVisible
&&
!
(
*
itf
)
->
getVisibility
())
continue
;
int
ITER
=
0
;
OptHomMessage
(
"Optimizing Model face %4d..."
,(
*
itf
)
->
tag
());
p
.
SUCCESS
=
1
;
std
::
set
<
MElement
*>
badasses
;
for
(
int
i
=
0
;
i
<
(
*
itf
)
->
getNumMeshElements
();
i
++
){
double
jmin
,
jmax
;
(
*
itf
)
->
getMeshElement
(
i
)
->
scaledJacRange
(
jmin
,
jmax
);
if
(
jmin
<
p
.
BARRIER_MIN
||
jmax
>
p
.
BARRIER_MAX
)
badasses
.
insert
((
*
itf
)
->
getMeshElement
(
i
));
}
// printf("START WITH %d bad asses\n",badasses.size());
if
(
badasses
.
size
()
==
0
)
continue
;
while
(
1
){
std
::
set
<
MVertex
*>
toFix
;
std
::
set
<
MElement
*>
toOptimize
;
toFix
=
filter2D_boundaryLayer
(
*
itf
,
p
.
nbLayers
,
p
.
BARRIER_MIN
,
p
.
BARRIER_MAX
,
p
.
DistanceFactor
,
badasses
,
toOptimize
);
OptHOM
temp
(
*
itf
,
toOptimize
,
toFix
,
method
);
temp
.
recalcJacDist
();
temp
.
getJacDist
(
minJac
,
maxJac
,
distMaxBND
,
distAvgBND
);
// if (minJac < 1.e2)OptHomMessage("Optimizing a blob of %4d elements minJ %12.5E -- maxJ %12.5E",(*itf)->getNumMeshElements(), minJac, maxJac);
std
::
ostringstream
ossI
;
ossI
<<
"initial_"
<<
(
*
itf
)
->
tag
()
<<
"ITER_"
<<
ITER
<<
".msh"
;
temp
.
mesh
.
writeMSH
(
ossI
.
str
().
c_str
());
if
(
minJac
>
p
.
BARRIER_MIN
&&
maxJac
<
p
.
BARRIER_MAX
)
break
;
p
.
SUCCESS
=
std
::
min
(
p
.
SUCCESS
,
temp
.
optimize
(
p
.
weightFixed
,
p
.
weightFree
,
p
.
BARRIER_MIN
,
p
.
BARRIER_MAX
,
false
,
samples
,
p
.
itMax
,
p
.
optPassMax
));
// temp.recalcJacDist();
// temp.getJacDist(minJac, maxJac, distMaxBND, distAvgBND);
temp
.
mesh
.
updateGEntityPositions
();
if
(
p
.
SUCCESS
==
-
1
)
break
;
ITER
++
;
if
(
p
.
filter
==
1
&&
ITER
>
badasses
.
size
()
*
2
)
break
;
// std::ostringstream ossF;
// ossF << "final_" << (*itf)->tag() << ".msh";
// temp.mesh.writeMSH(ossF.str().c_str());
PrintBlob
(
toOptimize
,
ITER
);
}
double
DTF
=
Cpu
()
-
tf1
;
if
(
p
.
SUCCESS
==
1
){
OptHomMessage
(
"Optimization succeeded (CPU %g sec)"
,
DTF
);
}
else
if
(
p
.
SUCCESS
==
0
)
OptHomMessage
(
"Warning : Model face %4d has all jacobians positive but not all in the range CPU %g"
,(
*
itf
)
->
tag
(),
DTF
);
else
if
(
p
.
SUCCESS
==
-
1
)
OptHomMessage
(
"Error : Model face %4d has still negative jacobians"
,(
*
itf
)
->
tag
());
Msg
::
Info
(
"---------------------------------------------------------------------------------------------------------------"
);
double
tf1
=
Cpu
();
}
GEntity
&
entity
=
*
entities
[
i
];
exportMeshToDassault
(
gm
,
gm
->
getName
()
+
"_opti.das"
,
2
);
if
(
entity
.
dim
()
!=
p
.
dim
||
(
p
.
onlyVisible
&&
!
entity
.
getVisibility
()))
continue
;
OptHomMessage
(
"Optimizing Model entity %4d..."
,
entity
.
tag
());
std
::
set
<
MElement
*>
badasses
;
for
(
int
i
=
0
;
i
<
entity
.
getNumMeshElements
();
i
++
)
{
double
jmin
,
jmax
;
entity
.
getMeshElement
(
i
)
->
scaledJacRange
(
jmin
,
jmax
);
if
(
p
.
BARRIER_MIN_METRIC
>
0
)
jmax
=
jmin
;
if
(
jmin
<
p
.
BARRIER_MIN
||
jmax
>
p
.
BARRIER_MAX
)
badasses
.
insert
(
entity
.
getMeshElement
(
i
));
}
}
else
if
(
p
.
dim
==
3
)
{
if
(
badasses
.
empty
())
continue
;
for
(
GModel
::
riter
itr
=
gm
->
firstRegion
();
itr
!=
gm
->
lastRegion
();
++
itr
)
{
if
(
p
.
onlyVisible
&&
!
(
*
itr
)
->
getVisibility
())
continue
;
std
::
vector
<
std
::
pair
<
std
::
set
<
MElement
*>
,
std
::
set
<
MVertex
*>
>
>
toOptimize
=
getConnectedBlobs
(
entity
,
badasses
,
p
.
nbLayers
,
p
.
DistanceFactor
);
int
ITER
=
0
;
Msg
::
Info
(
"Model region %4d is considered"
,(
*
itr
)
->
tag
());
//#pragma omp parallel for schedule(dynamic, 1)
p
.
SUCCESS
=
true
;
p
.
SUCCESS
=
1
;
while
(
1
){
for
(
int
i
=
0
;
i
<
toOptimize
.
size
();
++
i
)
{
std
::
set
<
MVertex
*>
toFix
;
//PrintBlob (toOptimize[i].first, i+1);
std
::
set
<
MElement
*>
toOptimize
;
OptHomMessage
(
"Optimizing a blob %i/%i composed of %4d elements"
,
i
+
1
,
toOptimize
.
size
(),
toOptimize
[
i
].
first
.
size
());
fflush
(
stdout
);
toFix
=
filter3D_boundaryLayer
(
*
itr
,
p
.
nbLayers
,
p
.
BARRIER_MIN
,
p
.
BARRIER_MAX
,
p
.
DistanceFactor
,
toOptimize
);
OptHOM
temp
(
&
entity
,
toOptimize
[
i
].
first
,
toOptimize
[
i
].
second
,
method
);
int
success
=
temp
.
optimize
(
p
.
weightFixed
,
p
.
weightFree
,
p
.
BARRIER_MIN
,
p
.
BARRIER_MAX
,
false
,
samples
,
p
.
itMax
,
p
.
optPassMax
);
// if ((*itr)->tetrahedra.size() > 0) {
if
(
success
>=
0
&&
p
.
BARRIER_MIN_METRIC
>
0
)
{
OptHOM
temp
(
*
itr
,
toOptimize
,
toFix
,
method
);
OptHomMessage
(
"Jacobian optimization succeed, starting svd optimization"
);
double
distMaxBND
,
distAvgBND
,
minJac
,
maxJac
;
success
=
temp
.
optimize
(
p
.
weightFixed
,
p
.
weightFree
,
p
.
BARRIER_MIN_METRIC
,
p
.
BARRIER_MAX
,
true
,
samples
,
p
.
itMax
,
p
.
optPassMax
);
temp
.
recalcJacDist
();
temp
.
getJacDist
(
minJac
,
maxJac
,
distMaxBND
,
distAvgBND
);
if
(
minJac
<
1.e2
)
Msg
::
Info
(
"Optimizing a blob of %4d elements minJ %12.5E -- maxJ %12.5E"
,(
*
itr
)
->
getNumMeshElements
(),
minJac
,
maxJac
);
std
::
ostringstream
ossI
;
ossI
<<
"initial_"
<<
(
*
itr
)
->
tag
()
<<
"ITER_"
<<
ITER
<<
".msh"
;
temp
.
mesh
.
writeMSH
(
ossI
.
str
().
c_str
());
if
(
minJac
>
p
.
BARRIER_MIN
&&
maxJac
<
p
.
BARRIER_MAX
)
break
;
p
.
SUCCESS
=
temp
.
optimize
(
p
.
weightFixed
,
p
.
weightFree
,
p
.
BARRIER_MIN
,
p
.
BARRIER_MAX
,
false
,
samples
,
p
.
itMax
,
p
.
optPassMax
);
temp
.
recalcJacDist
();
temp
.
getJacDist
(
minJac
,
maxJac
,
distMaxBND
,
distAvgBND
);
temp
.
mesh
.
updateGEntityPositions
();
if
(
!
p
.
SUCCESS
)
break
;
// }
ITER
++
;
}
Msg
::
Info
(
"Model region %4d is done (%d subdomains were computed) SUCCESS %1d"
,(
*
itr
)
->
tag
(),
ITER
,
p
.
SUCCESS
);
Msg
::
Info
(
"----------------------------------------------------------------"
);
// temp.mesh.writeMSH("final.msh");
}
}
temp
.
mesh
.
updateGEntityPositions
();
if
(
success
<=
0
)
{
std
::
ostringstream
ossI2
;
ossI2
<<
"final_"
<<
entity
.
tag
()
<<
"ITER_"
<<
i
<<
".msh"
;
temp
.
mesh
.
writeMSH
(
ossI2
.
str
().
c_str
());
}
//#pragma omp critical
p
.
SUCCESS
=
std
::
min
(
p
.
SUCCESS
,
success
);
}
}
double
DTF
=
Cpu
()
-
tf1
;
if
(
p
.
SUCCESS
==
1
)
OptHomMessage
(
"Optimization succeeded for entity %d (CPU %g sec)"
,
entity
.
tag
(),
DTF
);
else
if
(
p
.
SUCCESS
==
0
)
OptHomMessage
(
"Warning : Model entity %4d has all jacobians positive but not all in the range (CPU %g sec)"
,
entity
.
tag
(),
DTF
);
else
if
(
p
.
SUCCESS
==
-
1
)
OptHomMessage
(
"Error : Model entity %4d has still negative jacobians (CPU %g sec)"
,
entity
.
tag
(),
DTF
);
}
}
double
t2
=
Cpu
();
double
t2
=
Cpu
();
p
.
CPU
=
t2
-
t1
;
p
.
CPU
=
t2
-
t1
;
}
}
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