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
5a363a6f
Commit
5a363a6f
authored
9 years ago
by
PA Beaufort
Browse files
Options
Downloads
Patches
Plain Diff
Second order for parametrization (over a unit-disk).
Meshing does not work.
parent
62caf342
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
Geo/discreteDiskFace.cpp
+524
-206
524 additions, 206 deletions
Geo/discreteDiskFace.cpp
Geo/discreteDiskFace.h
+29
-8
29 additions, 8 deletions
Geo/discreteDiskFace.h
Geo/discreteFace.cpp
+10
-37
10 additions, 37 deletions
Geo/discreteFace.cpp
with
563 additions
and
251 deletions
Geo/discreteDiskFace.cpp
+
524
−
206
View file @
5a363a6f
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
// See the LICENSE.txt file for license information. Please report all
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to the public mailing list <gmsh@geuz.org>.
// bugs and problems to the public mailing list <gmsh@geuz.org>.
#include
<queue>
// #mark
#include
<stdlib.h>
#include
<stdlib.h>
#include
"GmshConfig.h"
#include
"GmshConfig.h"
...
@@ -23,18 +24,33 @@
...
@@ -23,18 +24,33 @@
#include
"laplaceTerm.h"
#include
"laplaceTerm.h"
#include
"convexLaplaceTerm.h"
#include
"convexLaplaceTerm.h"
#include
"convexCombinationTerm.h"
// #
#include
"convexCombinationTerm.h"
// #
#include
"BasisFactory.h"
// The three things that are mandatory to manipulate octrees (octree in (u;v)).
// The three things that are mandatory to manipulate octrees (octree in (u;v)).
static
void
discreteDiskFaceBB
(
void
*
a
,
double
*
mmin
,
double
*
mmax
)
static
void
discreteDiskFaceBB
(
void
*
a
,
double
*
mmin
,
double
*
mmax
)
{
// called once by buildOct()
{
// called once by buildOct()
discreteDiskFaceTriangle
*
t
=
(
discreteDiskFaceTriangle
*
)
a
;
discreteDiskFaceTriangle
*
t
=
(
discreteDiskFaceTriangle
*
)
a
;
mmin
[
0
]
=
std
::
min
(
std
::
min
(
t
->
p1
.
x
(),
t
->
p2
.
x
()),
t
->
p3
.
x
());
mmin
[
1
]
=
std
::
min
(
std
::
min
(
t
->
p1
.
y
(),
t
->
p2
.
y
()),
t
->
p3
.
y
());
mmax
[
0
]
=
std
::
max
(
std
::
max
(
t
->
p1
.
x
(),
t
->
p2
.
x
()),
t
->
p3
.
x
());
mmin
[
0
]
=
std
::
min
(
std
::
min
(
t
->
p
[
0
].
x
(),
t
->
p
[
1
].
x
()),
t
->
p
[
2
].
x
());
mmax
[
1
]
=
std
::
max
(
std
::
max
(
t
->
p1
.
y
(),
t
->
p2
.
y
()),
t
->
p3
.
y
());
mmin
[
1
]
=
std
::
min
(
std
::
min
(
t
->
p
[
0
].
y
(),
t
->
p
[
1
].
y
()),
t
->
p
[
2
].
y
());
mmax
[
0
]
=
std
::
max
(
std
::
max
(
t
->
p
[
0
].
x
(),
t
->
p
[
1
].
x
()),
t
->
p
[
2
].
x
());
mmax
[
1
]
=
std
::
max
(
std
::
max
(
t
->
p
[
0
].
y
(),
t
->
p
[
1
].
y
()),
t
->
p
[
2
].
y
());
if
(
t
->
tri
->
getPolynomialOrder
()
==
2
){
for
(
int
i
=
3
;
i
<
6
;
i
++
){
int
j
=
i
==
5
?
0
:
i
-
2
;
double
du
=
t
->
p
[
i
].
x
()
-
(
t
->
p
[
i
-
3
].
x
()
+
t
->
p
[
j
].
x
())
/
2.
;
double
dv
=
t
->
p
[
i
].
y
()
-
(
t
->
p
[
i
-
3
].
y
()
+
t
->
p
[
j
].
y
())
/
2.
;
mmin
[
0
]
=
std
::
min
(
mmin
[
0
],
t
->
p
[
i
].
x
()
+
du
);
mmin
[
1
]
=
std
::
min
(
mmin
[
1
],
t
->
p
[
i
].
y
()
+
dv
);
mmax
[
0
]
=
std
::
max
(
mmax
[
0
],
t
->
p
[
i
].
x
()
+
du
);
mmax
[
1
]
=
std
::
max
(
mmax
[
1
],
t
->
p
[
i
].
y
()
+
dv
);
}
}
mmin
[
2
]
=
-
1
;
mmin
[
2
]
=
-
1
;
mmax
[
2
]
=
1
;
mmax
[
2
]
=
1
;
const
double
dx
=
mmax
[
0
]
-
mmin
[
0
];
const
double
dx
=
mmax
[
0
]
-
mmin
[
0
];
const
double
dy
=
mmax
[
1
]
-
mmin
[
1
];
const
double
dy
=
mmax
[
1
]
-
mmin
[
1
];
const
double
eps
=
0.0
;
//1.e-12;
const
double
eps
=
0.0
;
//1.e-12;
...
@@ -47,26 +63,44 @@ static void discreteDiskFaceBB(void *a, double*mmin, double*mmax)
...
@@ -47,26 +63,44 @@ static void discreteDiskFaceBB(void *a, double*mmin, double*mmax)
static
void
discreteDiskFaceCentroid
(
void
*
a
,
double
*
c
)
static
void
discreteDiskFaceCentroid
(
void
*
a
,
double
*
c
)
{
// called once by buildOct()
{
// called once by buildOct()
discreteDiskFaceTriangle
*
t
=
(
discreteDiskFaceTriangle
*
)
a
;
discreteDiskFaceTriangle
*
t
=
(
discreteDiskFaceTriangle
*
)
a
;
c
[
0
]
=
(
t
->
p
1
.
x
()
+
t
->
p
2
.
x
()
+
t
->
p
3
.
x
())
/
3.0
;
c
[
0
]
=
(
t
->
p
[
0
]
.
x
()
+
t
->
p
[
1
]
.
x
()
+
t
->
p
[
2
]
.
x
())
/
3.0
;
c
[
1
]
=
(
t
->
p
1
.
y
()
+
t
->
p
2
.
y
()
+
t
->
p
3
.
y
())
/
3.0
;
c
[
1
]
=
(
t
->
p
[
0
]
.
y
()
+
t
->
p
[
1
]
.
y
()
+
t
->
p
[
2
]
.
y
())
/
3.0
;
c
[
2
]
=
0.0
;
c
[
2
]
=
0.0
;
}
}
static
int
discreteDiskFaceInEle
(
void
*
a
,
double
*
c
)
static
int
discreteDiskFaceInEle
(
void
*
a
,
double
*
c
)
// # mark
{
// called once by buildOct()
{
// called once by buildOct()
discreteDiskFaceTriangle
*
t
=
(
discreteDiskFaceTriangle
*
)
a
;
discreteDiskFaceTriangle
*
t
=
(
discreteDiskFaceTriangle
*
)
a
;
double
M
[
2
][
2
],
R
[
2
],
X
[
2
];
double
X
[
2
];
const
double
eps
=
1.e-8
;
const
double
eps
=
1.e-8
;
const
SPoint3
p0
=
t
->
p1
;
const
SPoint3
p1
=
t
->
p2
;
const
SPoint3
p2
=
t
->
p3
;
M
[
0
][
0
]
=
p1
.
x
()
-
p0
.
x
();
if
(
t
->
tri
->
getPolynomialOrder
()
==
1
){
M
[
0
][
1
]
=
p2
.
x
()
-
p0
.
x
();
M
[
1
][
0
]
=
p1
.
y
()
-
p0
.
y
();
double
M
[
2
][
2
],
R
[
2
];
M
[
1
][
1
]
=
p2
.
y
()
-
p0
.
y
();
const
SPoint3
p0
=
t
->
p
[
0
];
R
[
0
]
=
(
c
[
0
]
-
p0
.
x
());
const
SPoint3
p1
=
t
->
p
[
1
];
R
[
1
]
=
(
c
[
1
]
-
p0
.
y
());
const
SPoint3
p2
=
t
->
p
[
2
];
sys2x2
(
M
,
R
,
X
);
M
[
0
][
0
]
=
p1
.
x
()
-
p0
.
x
();
M
[
0
][
1
]
=
p2
.
x
()
-
p0
.
x
();
M
[
1
][
0
]
=
p1
.
y
()
-
p0
.
y
();
M
[
1
][
1
]
=
p2
.
y
()
-
p0
.
y
();
R
[
0
]
=
(
c
[
0
]
-
p0
.
x
());
R
[
1
]
=
(
c
[
1
]
-
p0
.
y
());
sys2x2
(
M
,
R
,
X
);
}
else
{
double
uv
[
3
]
=
{
c
[
0
],
c
[
1
],
0.
};
double
Xi
[
3
];
t
->
tri
->
xyz2uvw
(
uv
,
Xi
);
X
[
0
]
=
Xi
[
0
];
X
[
1
]
=
Xi
[
1
];
}
if
(
X
[
0
]
>
-
eps
&&
X
[
1
]
>
-
eps
&&
1.
-
X
[
0
]
-
X
[
1
]
>
-
eps
)
if
(
X
[
0
]
>
-
eps
&&
X
[
1
]
>
-
eps
&&
1.
-
X
[
0
]
-
X
[
1
]
>
-
eps
)
return
1
;
return
1
;
...
@@ -99,97 +133,301 @@ static bool orderVertices(const double &tot_length, const std::vector<MVertex*>
...
@@ -99,97 +133,301 @@ static bool orderVertices(const double &tot_length, const std::vector<MVertex*>
}
}
/*BUILDER*/
/*BUILDER*/
discreteDiskFace
::
discreteDiskFace
(
GFace
*
gf
,
std
::
vector
<
MTriangle
*>
&
mesh
)
:
discreteDiskFace
::
discreteDiskFace
(
GFace
*
gf
,
std
::
vector
<
MTriangle
*>
&
mesh
,
int
p
)
:
GFace
(
gf
->
model
(),
123
),
_parent
(
gf
)
GFace
(
gf
->
model
(),
123
),
_parent
(
gf
)
{
{
if
(
mesh
.
empty
())
return
;
std
::
map
<
MVertex
*
,
MVertex
*>
v2v
;
_order
=
p
;
for
(
unsigned
int
i
=
0
;
i
<
mesh
.
size
();
i
++
){
_N
=
(
p
+
1
)
*
(
p
+
2
)
/
2
;
MVertex
*
vs
[
3
]
=
{
NULL
,
NULL
,
NULL
};
for
(
int
j
=
0
;
j
<
3
;
j
++
){
int
tagElementOrder
;
MVertex
*
v
=
mesh
[
i
]
->
getVertex
(
j
);
switch
(
_order
){
case
1
:
tagElementOrder
=
MSH_TRI_3
;
break
;
case
2
:
tagElementOrder
=
MSH_TRI_6
;
break
;
case
3
:
tagElementOrder
=
MSH_TRI_10
;
break
;
default:
Msg
::
Error
(
"discreteDiskFace:: builder, tag is not (yet) covered for this order :-) "
);
}
mynodalbasis
=
BasisFactory
::
getNodalBasis
(
tagElementOrder
);
fullMatrix
<
double
>
myNodes
;
mynodalbasis
->
getReferenceNodes
(
myNodes
);
mybezierbasis
=
BasisFactory
::
getBezierBasis
(
TYPE_TRI
,
_order
);
std
::
map
<
MVertex
*
,
MVertex
*>
v2v
;
// mesh vertex |-> face vertex
std
::
map
<
MEdge
,
std
::
vector
<
MVertex
*>
,
Less_Edge
>
ed2nodes
;
// edge to interior node(s)
for
(
unsigned
int
i
=
0
;
i
<
mesh
.
size
();
i
++
){
// triangle by triangle
std
::
vector
<
MVertex
*>
vs
;
// MTriangle vertices
for
(
unsigned
int
j
=
0
;
j
<
3
;
j
++
){
// loop over vertices AND edges of the current triangle
MVertex
*
v
=
mesh
[
i
]
->
getVertex
(
j
);
// firstly, edge vertices
if
(
v
->
onWhat
()
==
gf
)
{
if
(
v
->
onWhat
()
==
gf
)
{
std
::
map
<
MVertex
*
,
MVertex
*>
::
iterator
it
=
v2v
.
find
(
v
);
std
::
map
<
MVertex
*
,
MVertex
*>
::
iterator
it
=
v2v
.
find
(
v
);
if
(
it
==
v2v
.
end
()){
if
(
it
==
v2v
.
end
()){
MFaceVertex
*
vv
=
new
MFaceVertex
(
v
->
x
(),
v
->
y
(),
v
->
z
(),
this
,
0
,
0
);
MFaceVertex
*
vv
=
new
MFaceVertex
(
v
->
x
(),
v
->
y
(),
v
->
z
(),
this
,
0
,
0
);
v2v
[
v
]
=
vv
;
v2v
[
v
]
=
vv
;
discrete_vertices
.
push_back
(
vv
);
discrete_vertices
.
push_back
(
vv
);
vs
[
j
]
=
vv
;
vs
.
push_back
(
vv
)
;
}
}
else
vs
[
j
]
=
it
->
second
;
else
vs
.
push_back
(
it
->
second
)
;
}
}
else
if
(
v
->
onWhat
()
->
dim
()
==
1
){
else
if
(
v
->
onWhat
()
->
dim
()
==
1
){
if
(
v
->
onWhat
()
->
geomType
()
==
DiscreteCurve
){
if
(
v
->
onWhat
()
->
geomType
()
==
DiscreteCurve
){
discreteEdge
*
de
=
dynamic_cast
<
discreteEdge
*>
(
v
->
onWhat
());
discreteEdge
*
de
=
dynamic_cast
<
discreteEdge
*>
(
v
->
onWhat
());
vs
[
j
]
=
de
->
getGeometricalVertex
(
v
);
vs
.
push_back
(
de
->
getGeometricalVertex
(
v
)
)
;
}
}
else
Msg
::
Fatal
(
"fatality"
);
else
Msg
::
Fatal
(
"fatality"
);
}
}
else
vs
[
j
]
=
v
;
else
vs
.
push_back
(
v
);
}
discrete_triangles
.
push_back
(
new
MTriangle
(
vs
[
0
],
vs
[
1
],
vs
[
2
]));
}
}
// end loop over vertices and edges
if
(
_order
>=
2
)
{
// then, interior nodes :-)
double
Xi
,
Eta
,
X
,
Y
,
Z
;
for
(
unsigned
int
ie
=
0
;
ie
<
3
;
ie
++
){
// firstly, edge interior nodes :-)
MEdge
me
=
mesh
[
i
]
->
getEdge
(
ie
);
// check if edge already visited
if
(
ed2nodes
.
find
(
me
)
==
ed2nodes
.
end
()){
for
(
unsigned
int
iev
=
3
+
ie
*
(
p
-
1
);
iev
<
3
+
(
ie
+
1
)
*
(
p
-
1
);
iev
++
){
Xi
=
myNodes
(
iev
,
0
);
Eta
=
myNodes
(
iev
,
1
);
X
=
vs
[
0
]
->
x
()
*
(
1.
-
Xi
-
Eta
)
+
vs
[
1
]
->
x
()
*
Xi
+
vs
[
2
]
->
x
()
*
Eta
;
Y
=
vs
[
0
]
->
y
()
*
(
1.
-
Xi
-
Eta
)
+
vs
[
1
]
->
y
()
*
Xi
+
vs
[
2
]
->
y
()
*
Eta
;
Z
=
vs
[
0
]
->
z
()
*
(
1.
-
Xi
-
Eta
)
+
vs
[
1
]
->
z
()
*
Xi
+
vs
[
2
]
->
z
()
*
Eta
;
MVertex
*
mv
=
new
MVertex
(
X
,
Y
,
Z
,
gf
);
vs
.
push_back
(
mv
);
ed2nodes
[
me
].
push_back
(
mv
);
}
}
else
{
std
::
vector
<
MVertex
*>
vecmv
=
ed2nodes
[
me
];
for
(
unsigned
int
iev
=
0
;
iev
<
(
p
-
1
);
iev
++
)
vs
.
push_back
(
vecmv
[
iev
]);
}
}
for
(
unsigned
int
iv
=
3
*
_order
;
iv
<
_N
;
iv
++
){
// then, volume nodes
Xi
=
myNodes
(
iv
,
0
);
Eta
=
myNodes
(
iv
,
1
);
X
=
vs
[
0
]
->
x
()
*
(
1.
-
Xi
-
Eta
)
+
vs
[
1
]
->
x
()
*
Xi
+
vs
[
2
]
->
x
()
*
Eta
;
Y
=
vs
[
0
]
->
y
()
*
(
1.
-
Xi
-
Eta
)
+
vs
[
1
]
->
y
()
*
Xi
+
vs
[
2
]
->
y
()
*
Eta
;
Z
=
vs
[
0
]
->
z
()
*
(
1.
-
Xi
-
Eta
)
+
vs
[
1
]
->
z
()
*
Xi
+
vs
[
2
]
->
z
()
*
Eta
;
vs
.
push_back
(
new
MVertex
(
X
,
Y
,
Z
,
gf
));
}
}
// end order > 2
if
(
_order
==
1
)
discrete_triangles
.
push_back
(
new
MTriangle
(
vs
));
if
(
_order
==
2
)
discrete_triangles
.
push_back
(
new
MTriangle6
(
vs
));
if
(
_order
>
2
)
discrete_triangles
.
push_back
(
new
MTriangleN
(
vs
,(
char
)
_order
));
for
(
unsigned
int
check
=
0
;
check
<
_N
;
check
++
)
std
::
cout
<<
"("
<<
vs
[
check
]
->
x
()
<<
";"
<<
vs
[
check
]
->
y
()
<<
")
\t
"
;
std
::
cout
<<
"
\n
"
;
for
(
unsigned
int
check
=
0
;
check
<
_N
;
check
++
)
std
::
cout
<<
"("
<<
myNodes
(
check
,
0
)
<<
";"
<<
myNodes
(
check
,
1
)
<<
")
\t
"
;
std
::
cout
<<
"
\n
"
;
}
// end loop over triangles
// delete MTriangle* and MVertex ? Y E S # mark
// triangles = mesh;
uv_kdtree
=
NULL
;
uv_kdtree
=
NULL
;
kdtree
=
NULL
;
kdtree
=
NULL
;
// checkOrientation(); // mark, need to check after parametrization ? --> no ! (3D, cf. Seb)
std
::
cout
<<
"buildAllNodes"
<<
std
::
endl
;
buildAllNodes
();
buildAllNodes
();
std
::
cout
<<
"getBoundingEdges"
<<
std
::
endl
;
getBoundingEdges
();
getBoundingEdges
();
std
::
cout
<<
"orderVertices"
<<
std
::
endl
;
orderVertices
(
_totLength
,
_U0
,
_coords
);
orderVertices
(
_totLength
,
_U0
,
_coords
);
std
::
cout
<<
"parametrize"
<<
std
::
endl
;
parametrize
();
parametrize
();
std
::
cout
<<
"buildOct"
<<
std
::
endl
;
buildOct
();
buildOct
();
// putOnView();
std
::
cout
<<
"checkOrientation"
<<
std
::
endl
;
checkOrientationUV
();
std
::
cout
<<
"putOnView"
<<
std
::
endl
;
putOnView
();
std
::
cout
<<
"discreteDiskFace: The parametrization of triangulation "
<<
gf
->
tag
()
<<
" is ending."
<<
std
::
endl
;
}
}
void
discreteDiskFace
::
getBoundingEdges
()
void
discreteDiskFace
::
getBoundingEdges
()
{
{
// first of all, all the triangles have to be oriented in the same way
std
::
map
<
MEdge
,
std
::
vector
<
MElement
*>
,
Less_Edge
>
ed2tri
;
// edge to 1 or 2 triangle(s)
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
MElement
*
e
=
discrete_triangles
[
i
];
for
(
int
j
=
0
;
j
<
e
->
getNumEdges
()
;
j
++
){
MEdge
ed
=
e
->
getEdge
(
j
);
ed2tri
[
ed
].
push_back
(
e
);
}
}
// element to its neighbors
std
::
map
<
MElement
*
,
std
::
vector
<
MElement
*>
>
neighbors
;
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
MElement
*
e
=
discrete_triangles
[
i
];
for
(
unsigned
int
j
=
0
;
j
<
e
->
getNumEdges
();
j
++
){
// #fixme: efficiency could be improved by setting neighbors mutually
std
::
vector
<
MElement
*>
my_mt
=
ed2tri
[
e
->
getEdge
(
j
)];
if
(
my_mt
.
size
()
>
1
){
// my_mt.size() = {1;2}
MElement
*
neighTri
=
my_mt
[
0
]
==
e
?
my_mt
[
1
]
:
my_mt
[
0
];
neighbors
[
e
].
push_back
(
neighTri
);
}
}
}
// queue: first in, first out
std
::
queue
<
MElement
*>
checkList
;
// element for reference orientation
std
::
queue
<
std
::
vector
<
MElement
*>
>
checkLists
;
// corresponding neighbor element to be checked for its orientation
std
::
queue
<
MElement
*>
my_todo
;
// todo list
std
::
map
<
MElement
*
,
bool
>
check_todo
;
// help to complete todo list
my_todo
.
push
(
discrete_triangles
[
0
]);
check_todo
[
discrete_triangles
[
0
]]
=
true
;
while
(
!
my_todo
.
empty
()){
MElement
*
myMT
=
my_todo
.
front
();
my_todo
.
pop
();
std
::
vector
<
MElement
*>
myV
=
neighbors
[
myMT
];
std
::
vector
<
MElement
*>
myInsertion
;
checkList
.
push
(
myMT
);
for
(
unsigned
int
i
=
0
;
i
<
myV
.
size
();
++
i
){
if
(
check_todo
.
find
(
myV
[
i
])
==
check_todo
.
end
()){
myInsertion
.
push_back
(
myV
[
i
]);
check_todo
[
myV
[
i
]]
=
true
;
my_todo
.
push
(
myV
[
i
]);
}
}
checkLists
.
push
(
myInsertion
);
}
// end while
while
(
!
checkList
.
empty
()
&&
!
checkLists
.
empty
()){
MElement
*
current
=
checkList
.
front
();
checkList
.
pop
();
std
::
vector
<
MElement
*>
neigs
=
checkLists
.
front
();
checkLists
.
pop
();
for
(
unsigned
int
i
=
0
;
i
<
neigs
.
size
();
i
++
){
bool
myCond
=
false
;
for
(
unsigned
int
k
=
0
;
k
<
3
;
k
++
){
for
(
unsigned
int
j
=
0
;
j
<
3
;
j
++
){
if
(
current
->
getVertex
(
k
)
==
neigs
[
i
]
->
getVertex
(
j
)){
myCond
=
true
;
if
(
!
(
current
->
getVertex
(
k
!=
2
?
k
+
1
:
0
)
==
neigs
[
i
]
->
getVertex
(
j
!=
0
?
j
-
1
:
2
)
||
current
->
getVertex
(
k
!=
0
?
k
-
1
:
2
)
==
neigs
[
i
]
->
getVertex
(
j
!=
2
?
j
+
1
:
0
))){
neigs
[
i
]
->
reverse
();
std
::
cout
<<
"discreteDiskFace: triangle "
<<
neigs
[
i
]
->
getNum
()
<<
" has been reoriented."
<<
std
::
endl
;
}
break
;
}
}
if
(
myCond
)
break
;
}
}
// end for unsigned int i
}
// end while
// now, it is possible to identify the border(s) of the triangulation
// allEdges contains all edges of the boundary
// allEdges contains all edges of the boundary
std
::
set
<
MEdge
,
Less_Edge
>
allEdges
;
std
::
set
<
MEdge
,
Less_Edge
>
allEdges
;
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
MElement
*
e
=
discrete_triangles
[
i
];
MElement
*
e
=
discrete_triangles
[
i
];
for
(
int
j
=
0
;
j
<
e
->
getNumEdges
()
;
j
++
){
for
(
int
j
=
0
;
j
<
e
->
getNumEdges
()
;
j
++
){
MEdge
ed
=
e
->
getEdge
(
j
);
MEdge
ed
=
e
->
getEdge
(
j
);
std
::
set
<
MEdge
,
Less_Edge
>::
iterator
it
=
allEdges
.
find
(
ed
);
std
::
set
<
MEdge
,
Less_Edge
>::
iterator
it
=
allEdges
.
find
(
ed
);
if
(
it
==
allEdges
.
end
())
allEdges
.
insert
(
ed
);
if
(
it
==
allEdges
.
end
())
allEdges
.
insert
(
ed
);
else
allEdges
.
erase
(
it
);
else
allEdges
.
erase
(
it
);
}
}
}
}
std
::
map
<
MVertex
*
,
MVertex
*>
edges
;
// useless ?
std
::
map
<
MVertex
*
,
std
::
vector
<
MVertex
*>
>
firstNode2Edge
;
std
::
map
<
MVertex
*
,
MVertex
*>
firstNode2Edge
;
for
(
std
::
set
<
MEdge
>::
iterator
ie
=
allEdges
.
begin
();
ie
!=
allEdges
.
end
()
;
++
ie
)
{
for
(
std
::
set
<
MEdge
>::
iterator
ie
=
allEdges
.
begin
();
ie
!=
allEdges
.
end
()
;
++
ie
)
{
MEdge
ed
=
*
ie
;
MEdge
ed
=
*
ie
;
MVertex
*
first
=
ed
.
getVertex
(
0
);
MVertex
*
last
=
ed
.
getVertex
(
1
);
std
::
map
<
MVertex
*
,
MVertex
*>::
iterator
im
=
firstNode2Edge
.
find
(
first
);
std
::
vector
<
MElement
*>
vectri
=
ed2tri
[
ed
];
if
(
im
!=
firstNode2Edge
.
end
())
Msg
::
Fatal
(
"Incorrect topology in discreteDiskFace %d"
,
tag
());
MElement
*
tri
=
vectri
[
0
];
// boundary edge: only one triangle :-)
std
::
vector
<
MVertex
*>
vecver
;
tri
->
getEdgeVertices
(
edgeLocalNum
(
tri
,
ed
),
vecver
);
MVertex
*
first
=
vecver
[
0
];
MVertex
*
last
=
vecver
[
1
];
vecver
.
erase
(
vecver
.
begin
());
vecver
.
erase
(
vecver
.
begin
());
firstNode2Edge
[
first
]
=
last
;
std
::
map
<
MVertex
*
,
std
::
vector
<
MVertex
*>
>::
iterator
im
=
firstNode2Edge
.
find
(
first
);
if
(
im
!=
firstNode2Edge
.
end
())
Msg
::
Fatal
(
"Incorrect topology in discreteDiskFace %d"
,
tag
());
firstNode2Edge
[
first
]
=
vecver
;
firstNode2Edge
[
first
].
push_back
(
last
);
}
}
while
(
!
firstNode2Edge
.
empty
())
{
// quid not empty but in within the map ?
while
(
!
firstNode2Edge
.
empty
())
{
// quid
'firstNode2Edge' is
not empty but
'
in
'
within the map ?
std
::
vector
<
MVertex
*>
loop
;
std
::
vector
<
MVertex
*>
loop
;
double
length
=
0.
;
double
length
=
0.
;
std
::
map
<
MVertex
*
,
MVertex
*>::
iterator
in
=
firstNode2Edge
.
begin
();
std
::
map
<
MVertex
*
,
std
::
vector
<
MVertex
*>
>::
iterator
in
=
firstNode2Edge
.
begin
();
while
(
in
!=
firstNode2Edge
.
end
())
{
while
(
in
!=
firstNode2Edge
.
end
())
{
MVertex
*
first
=
in
->
first
;
MVertex
*
first
=
in
->
first
;
MVertex
*
last
=
in
->
second
;
std
::
vector
<
MVertex
*>
myV
=
in
->
second
;
length
+=
sqrt
(
(
last
->
x
()
-
first
->
x
())
*
(
last
->
x
()
-
first
->
x
())
+
(
last
->
y
()
-
first
->
y
())
*
(
last
->
y
()
-
first
->
y
())
+
(
last
->
z
()
-
first
->
z
())
*
(
last
->
z
()
-
first
->
z
())
);
loop
.
push_back
(
first
);
loop
.
push_back
(
first
);
firstNode2Edge
.
erase
(
in
);
in
=
firstNode2Edge
.
find
(
last
);
}
_loops
.
insert
(
std
::
make_pair
(
length
,
loop
));
// it shouldn't be possible to have twice the same length ? mark
}
MVertex
*
previous
=
first
;
for
(
int
i
=
0
;
i
<=
myV
.
size
()
-
1
;
i
++
){
// dirichlet BC
MVertex
*
current
=
myV
[
i
];
std
::
cout
<<
"("
<<
current
->
x
()
<<
";"
<<
current
->
y
()
<<
")"
<<
std
::
endl
;
loop
.
push_back
(
current
);
length
+=
sqrt
(
(
current
->
x
()
-
previous
->
x
())
*
(
current
->
x
()
-
previous
->
x
())
+
(
current
->
y
()
-
previous
->
y
())
*
(
current
->
y
()
-
previous
->
y
())
+
(
current
->
z
()
-
previous
->
z
())
*
(
current
->
z
()
-
previous
->
z
())
);
_loops
.
insert
(
std
::
make_pair
(
length
,
loop
));
// it shouldn't be possible to have twice the same length ? actually, it is possible, but quite seldom #fixme ----> multimap ?
previous
=
current
;
}
firstNode2Edge
.
erase
(
in
);
in
=
firstNode2Edge
.
find
(
previous
);
}
// end while in
}
// end while firstNode2Edge
// dirichlet BC
_U0
=
_loops
.
rbegin
()
->
second
;
_U0
=
_loops
.
rbegin
()
->
second
;
_totLength
=
_loops
.
rbegin
()
->
first
;
_totLength
=
_loops
.
rbegin
()
->
first
;
}
}
...
@@ -198,21 +436,26 @@ void discreteDiskFace::buildOct() const
...
@@ -198,21 +436,26 @@ void discreteDiskFace::buildOct() const
{
{
SBoundingBox3d
bb
;
SBoundingBox3d
bb
;
int
count
=
0
;
int
count
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
MTriangle
*
t
=
discrete_triangles
[
i
];
MTriangle
*
t
=
discrete_triangles
[
i
];
//create bounding box
//create bounding box
for
(
int
j
=
0
;
j
<
3
;
j
++
){
for
(
int
j
=
0
;
j
<
t
->
getNumVertices
()
;
j
++
){
std
::
map
<
MVertex
*
,
SPoint3
>::
const_iterator
itj
=
coordinates
.
find
(
t
->
getVertex
(
j
));
std
::
map
<
MVertex
*
,
SPoint3
>::
const_iterator
itj
=
coordinates
.
find
(
t
->
getVertex
(
j
));
_coordPoints
.
insert
(
std
::
make_pair
(
t
->
getVertex
(
j
)
->
point
(),
itj
->
second
));
// <tr(x;y;z);tr(u;v)>
_coordPoints
.
insert
(
std
::
make_pair
(
t
->
getVertex
(
j
)
->
point
(),
itj
->
second
));
// <tr(x;y;z);tr(u;v)>
bb
+=
SPoint3
(
itj
->
second
.
x
(),
itj
->
second
.
y
(),
0.0
);
if
(
_order
==
2
&&
j
>
2
){
int
ij
=
j
==
5
?
0
:
j
-
2
;
double
du
=
itj
->
second
.
x
()
-
(
t
->
getVertex
(
j
-
3
)
->
x
()
+
t
->
getVertex
(
ij
)
->
x
())
/
2.
;
double
dv
=
itj
->
second
.
y
()
-
(
t
->
getVertex
(
j
-
3
)
->
y
()
+
t
->
getVertex
(
ij
)
->
y
())
/
2.
;
bb
+=
SPoint3
(
itj
->
second
.
x
()
+
du
,
itj
->
second
.
y
()
+
dv
,
0.
);
}
else
bb
+=
SPoint3
(
itj
->
second
.
x
(),
itj
->
second
.
y
(),
0.
);
}
}
count
++
;
count
++
;
}
}
//ANN octree
// ANN octree
std
::
set
<
MVertex
*>
allVS
;
// ? useless ?
ANNpointArray
nodes
=
annAllocPts
(
count
,
_N
);
ANNpointArray
nodes
=
annAllocPts
(
count
,
3
);
// make bounding box
// make bounding box
SPoint3
bbmin
=
bb
.
min
(),
bbmax
=
bb
.
max
();
SPoint3
bbmin
=
bb
.
min
(),
bbmax
=
bb
.
max
();
...
@@ -227,81 +470,90 @@ void discreteDiskFace::buildOct() const
...
@@ -227,81 +470,90 @@ void discreteDiskFace::buildOct() const
discreteDiskFaceCentroid
,
discreteDiskFaceInEle
);
discreteDiskFaceCentroid
,
discreteDiskFaceInEle
);
count
=
0
;
count
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
MTriangle
*
t
=
discrete_triangles
[
i
];
MTriangle
*
t
=
discrete_triangles
[
i
];
std
::
map
<
MVertex
*
,
SPoint3
>::
const_iterator
it0
=
discreteDiskFaceTriangle
*
my_ddft
=
&
_ddft
[
count
];
coordinates
.
find
(
t
->
getVertex
(
0
));
init_ddft
(
my_ddft
);
// #fixme destructor
std
::
map
<
MVertex
*
,
SPoint3
>::
const_iterator
it1
=
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
){
coordinates
.
find
(
t
->
getVertex
(
1
));
std
::
map
<
MVertex
*
,
SPoint3
>::
const_iterator
it
=
std
::
map
<
MVertex
*
,
SPoint3
>::
const_iterator
it2
=
coordinates
.
find
(
t
->
getVertex
(
io
));
coordinates
.
find
(
t
->
getVertex
(
2
));
my_ddft
->
p
[
io
]
=
it
->
second
;
_ddft
[
count
].
p1
=
it0
->
second
;
}
_ddft
[
count
].
p2
=
it1
->
second
;
_ddft
[
count
].
p3
=
it2
->
second
;
if
(
geomType
()
!=
GEntity
::
DiscreteDiskSurface
){
// CAD
if
(
geomType
()
!=
GEntity
::
DiscreteDiskSurface
){
// CAD
if
(
t
->
getVertex
(
0
)
->
onWhat
()
->
dim
()
==
2
){
if
(
t
->
getVertex
(
0
)
->
onWhat
()
->
dim
()
==
2
){
reparamMeshEdgeOnFace
(
t
->
getVertex
(
0
),
t
->
getVertex
(
1
),
_parent
,
for
(
unsigned
int
io
=
1
;
io
<
_N
;
io
++
)
_ddft
[
count
].
gfp1
,
_ddft
[
count
].
gfp2
);
reparamMeshEdgeOnFace
(
t
->
getVertex
(
0
),
t
->
getVertex
(
io
),
_parent
,
reparamMeshEdgeOnFace
(
t
->
getVertex
(
0
),
t
->
getVertex
(
2
),
_parent
,
my_ddft
->
gfp
[
0
],
my_ddft
->
gfp
[
io
]);
_ddft
[
count
].
gfp1
,
_ddft
[
count
].
gfp3
);
}
}
else
if
(
t
->
getVertex
(
1
)
->
onWhat
()
->
dim
()
==
2
){
else
if
(
t
->
getVertex
(
1
)
->
onWhat
()
->
dim
()
==
2
){
reparamMeshEdgeOnFace
(
t
->
getVertex
(
1
),
t
->
getVertex
(
0
),
_parent
,
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
)
_ddft
[
count
].
gfp2
,
_ddft
[
count
].
gfp
1
)
;
if
(
io
!=
1
)
reparamMeshEdgeOnFace
(
t
->
getVertex
(
1
),
t
->
getVertex
(
2
),
_parent
,
reparamMeshEdgeOnFace
(
t
->
getVertex
(
1
),
t
->
getVertex
(
io
),
_parent
,
_ddft
[
count
].
gfp2
,
_ddft
[
count
].
gfp3
);
my_ddft
->
gfp
[
1
],
my_ddft
->
gfp
[
io
]
);
}
}
else
if
(
t
->
getVertex
(
2
)
->
onWhat
()
->
dim
()
==
2
){
else
if
(
t
->
getVertex
(
2
)
->
onWhat
()
->
dim
()
==
2
){
reparamMeshEdgeOnFace
(
t
->
getVertex
(
2
),
t
->
getVertex
(
0
),
_parent
,
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
)
_ddft
[
count
].
gfp3
,
_ddft
[
count
].
gfp1
);
if
(
io
!=
2
)
reparamMeshEdgeOnFace
(
t
->
getVertex
(
2
),
t
->
getVertex
(
1
),
_parent
,
reparamMeshEdgeOnFace
(
t
->
getVertex
(
2
),
t
->
getVertex
(
io
),
_parent
,
_ddft
[
count
].
gfp3
,
_ddft
[
count
].
gfp2
);
my_ddft
->
gfp
[
2
],
my_ddft
->
gfp
[
io
]);
}
else
{
// quid interior vertices ?
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
)
reparamMeshVertexOnFace
(
t
->
getVertex
(
io
),
_parent
,
my_ddft
->
gfp
[
io
]);
}
}
else
{
}
reparamMeshVertexOnFace
(
t
->
getVertex
(
0
),
_parent
,
_ddft
[
count
].
gfp1
);
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
)
reparamMeshVertexOnFace
(
t
->
getVertex
(
1
),
_parent
,
_ddft
[
count
].
gfp2
);
my_ddft
->
v
[
io
]
=
SPoint3
(
t
->
getVertex
(
io
)
->
x
(),
t
->
getVertex
(
io
)
->
y
(),
reparamMeshVertexOnFace
(
t
->
getVertex
(
2
),
_parent
,
_ddft
[
count
].
gfp3
);
t
->
getVertex
(
io
)
->
z
());
my_ddft
->
gf
=
_parent
;
my_ddft
->
tri
=
t
;
SVector3
dXdxi
(
my_ddft
->
v
[
1
]
-
my_ddft
->
v
[
0
]);
// constant
SVector3
dXdeta
(
my_ddft
->
v
[
2
]
-
my_ddft
->
v
[
0
]);
// constant
double
grads
[
_N
][
3
];
// u,v,w=0,grads
for
(
unsigned
int
myI
=
0
;
myI
<
t
->
getNumVertices
();
myI
++
){
double
U
,
V
,
W
;
t
->
getNode
(
myI
,
U
,
V
,
W
);
// Xi Eta
mynodalbasis
->
df
(
U
,
V
,
0
,
grads
);
//compute first derivatives for every triangle
// (dXi/dU)^-1 = dU/dXi
double
mat
[
2
][
2
]
=
{{
0.
,
0.
},{
0.
,
0.
}};
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
){
for
(
unsigned
int
ic
=
0
;
ic
<
2
;
ic
++
){
mat
[
0
][
ic
]
+=
my_ddft
->
p
[
io
].
x
()
*
grads
[
io
][
ic
];
mat
[
1
][
ic
]
+=
my_ddft
->
p
[
io
].
y
()
*
grads
[
io
][
ic
];
}
}
}
double
inv
[
2
][
2
];
inv2x2
(
mat
,
inv
);
SVector3
dXdu
(
dXdxi
*
inv
[
0
][
0
]
+
dXdeta
*
inv
[
1
][
0
]);
SVector3
dXdv
(
dXdxi
*
inv
[
0
][
1
]
+
dXdeta
*
inv
[
1
][
1
]);
firstElemDerivatives
[(
MElement
*
)
t
].
push_back
(
Pair
<
SVector3
,
SVector3
>
(
dXdu
,
dXdv
));
}
}
_ddft
[
count
].
v1
=
SPoint3
(
t
->
getVertex
(
0
)
->
x
(),
t
->
getVertex
(
0
)
->
y
(),
nodes
[
count
][
0
]
=
0.
;
t
->
getVertex
(
0
)
->
z
());
nodes
[
count
][
1
]
=
0.
;
_ddft
[
count
].
v2
=
SPoint3
(
t
->
getVertex
(
1
)
->
x
(),
t
->
getVertex
(
1
)
->
y
(),
nodes
[
count
][
2
]
=
0.
;
t
->
getVertex
(
1
)
->
z
());
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
){
_ddft
[
count
].
v3
=
SPoint3
(
t
->
getVertex
(
2
)
->
x
(),
t
->
getVertex
(
2
)
->
y
(),
nodes
[
count
][
0
]
+=
my_ddft
->
p
[
io
].
x
();
t
->
getVertex
(
2
)
->
z
());
nodes
[
count
][
1
]
+=
my_ddft
->
p
[
io
].
y
();
_ddft
[
count
].
gf
=
_parent
;
}
_ddft
[
count
].
tri
=
t
;
nodes
[
count
][
0
]
/=
(
double
)
_N
;
// #notsure
nodes
[
count
][
1
]
/=
(
double
)
_N
;
//compute first derivatives for every triangle , to disappear (erase)
Octree_Insert
(
my_ddft
,
oct
);
double
mat
[
2
][
2
]
=
{{
_ddft
[
count
].
p2
.
x
()
-
_ddft
[
count
].
p1
.
x
(),
_ddft
[
count
].
p3
.
x
()
-
_ddft
[
count
].
p1
.
x
()},
{
_ddft
[
count
].
p2
.
y
()
-
_ddft
[
count
].
p1
.
y
(),
_ddft
[
count
].
p3
.
y
()
-
_ddft
[
count
].
p1
.
y
()}};
// modified higher
double
inv
[
2
][
2
];
inv2x2
(
mat
,
inv
);
SVector3
dXdxi
(
_ddft
[
count
].
v2
-
_ddft
[
count
].
v1
);
// constant
SVector3
dXdeta
(
_ddft
[
count
].
v3
-
_ddft
[
count
].
v1
);
// constant
SVector3
dXdu
(
dXdxi
*
inv
[
0
][
0
]
+
dXdeta
*
inv
[
1
][
0
]);
// to be modified for higher order
SVector3
dXdv
(
dXdxi
*
inv
[
0
][
1
]
+
dXdeta
*
inv
[
1
][
1
]);
// to be modified for higher order
firstElemDerivatives
[(
MElement
*
)
t
]
=
Pair
<
SVector3
,
SVector3
>
(
dXdu
,
dXdv
);
nodes
[
count
][
0
]
=
(
it0
->
second
.
x
()
+
it1
->
second
.
x
()
+
it2
->
second
.
x
())
/
3.0
;
nodes
[
count
][
1
]
=
(
it0
->
second
.
y
()
+
it1
->
second
.
y
()
+
it2
->
second
.
y
())
/
3.0
;
nodes
[
count
][
2
]
=
0.0
;
Octree_Insert
(
&
_ddft
[
count
],
oct
);
count
++
;
count
++
;
}
}
// end big for over mesh[i]
Octree_Arrange
(
oct
);
Octree_Arrange
(
oct
);
// USELESS, laplacian
//smooth first derivatives at vertices
//smooth first derivatives at vertices
if
(
adjv
.
size
()
==
0
){
if
(
adjv
.
size
()
==
0
){
std
::
vector
<
MTriangle
*>
allTri
;
std
::
vector
<
MTriangle
*>
allTri
;
//
allTri
.
insert
(
allTri
.
end
(),
discrete_triangles
.
begin
(),
discrete_triangles
.
end
()
);
allTri
.
insert
(
allTri
.
end
(),
discrete_triangles
.
begin
(),
discrete_triangles
.
end
()
);
buildVertexToTriangle
(
allTri
,
adjv
);
buildVertexToTriangle
(
allTri
,
adjv
);
}
}
...
@@ -311,15 +563,16 @@ void discreteDiskFace::buildOct() const
...
@@ -311,15 +563,16 @@ void discreteDiskFace::buildOct() const
SVector3
dXdu
(
0.0
),
dXdv
(
0.0
);
SVector3
dXdu
(
0.0
),
dXdv
(
0.0
);
int
nbTri
=
vTri
.
size
();
int
nbTri
=
vTri
.
size
();
for
(
int
j
=
0
;
j
<
nbTri
;
j
++
){
// elements's contribution for a vertex
for
(
int
j
=
0
;
j
<
nbTri
;
j
++
){
// elements's contribution for a vertex
dXdu
+=
firstElemDerivatives
[
vTri
[
j
]].
first
();
std
::
vector
<
Pair
<
SVector3
,
SVector3
>
>
myVec
=
firstElemDerivatives
[
vTri
[
j
]];
dXdv
+=
firstElemDerivatives
[
vTri
[
j
]].
second
();
dXdu
+=
myVec
[
nodeLocalNum
(
vTri
[
j
],
v
)].
first
();
dXdv
+=
myVec
[
nodeLocalNum
(
vTri
[
j
],
v
)].
second
();
}
}
dXdu
*=
1.
/
nbTri
;
dXdu
*=
1.
/
nbTri
;
dXdv
*=
1.
/
nbTri
;
dXdv
*=
1.
/
nbTri
;
firstDerivatives
[
v
]
=
Pair
<
SVector3
,
SVector3
>
(
dXdu
,
dXdv
);
firstDerivatives
[
v
]
=
Pair
<
SVector3
,
SVector3
>
(
dXdu
,
dXdv
);
}
}
kdtree
=
new
ANNkd_tree
(
nodes
,
count
,
3
);
kdtree
=
new
ANNkd_tree
(
nodes
,
count
,
_N
);
// #notsure
}
}
...
@@ -347,14 +600,10 @@ bool discreteDiskFace::parametrize() const
...
@@ -347,14 +600,10 @@ bool discreteDiskFace::parametrize() const
for
(
size_t
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
for
(
size_t
i
=
0
;
i
<
discrete_triangles
.
size
();
++
i
){
MTriangle
*
t
=
discrete_triangles
[
i
];
MTriangle
*
t
=
discrete_triangles
[
i
];
for
(
unsigned
int
j
=
0
;
j
<
t
->
getNumVertices
();
j
++
){
myAssemblerU
.
numberVertex
(
t
->
getVertex
(
0
),
0
,
1
);
myAssemblerU
.
numberVertex
(
t
->
getVertex
(
j
),
0
,
1
);
myAssemblerU
.
numberVertex
(
t
->
getVertex
(
1
),
0
,
1
);
myAssemblerV
.
numberVertex
(
t
->
getVertex
(
j
),
0
,
1
);
myAssemblerU
.
numberVertex
(
t
->
getVertex
(
2
),
0
,
1
);
}
myAssemblerV
.
numberVertex
(
t
->
getVertex
(
0
),
0
,
1
);
myAssemblerV
.
numberVertex
(
t
->
getVertex
(
1
),
0
,
1
);
myAssemblerV
.
numberVertex
(
t
->
getVertex
(
2
),
0
,
1
);
}
}
...
@@ -372,10 +621,7 @@ bool discreteDiskFace::parametrize() const
...
@@ -372,10 +621,7 @@ bool discreteDiskFace::parametrize() const
SElement
se
(
discrete_triangles
[
i
]);
SElement
se
(
discrete_triangles
[
i
]);
mappingU
.
addToMatrix
(
myAssemblerU
,
&
se
);
mappingU
.
addToMatrix
(
myAssemblerU
,
&
se
);
mappingV
.
addToMatrix
(
myAssemblerV
,
&
se
);
mappingV
.
addToMatrix
(
myAssemblerV
,
&
se
);
}
}
// lsys_v->printMatlab("testv.m");
double
t2
=
Cpu
();
double
t2
=
Cpu
();
...
@@ -396,7 +642,7 @@ bool discreteDiskFace::parametrize() const
...
@@ -396,7 +642,7 @@ bool discreteDiskFace::parametrize() const
p
[
1
]
=
value_V
;
p
[
1
]
=
value_V
;
coordinates
[
v
]
=
p
;
coordinates
[
v
]
=
p
;
}
}
else
{
else
{
// #useful ?
itf
->
second
[
0
]
=
value_U
;
itf
->
second
[
0
]
=
value_U
;
itf
->
second
[
1
]
=
value_V
;
itf
->
second
[
1
]
=
value_V
;
}
}
...
@@ -414,39 +660,76 @@ void discreteDiskFace::getTriangleUV(const double u,const double v,
...
@@ -414,39 +660,76 @@ void discreteDiskFace::getTriangleUV(const double u,const double v,
double
&
_u
,
double
&
_v
)
const
{
double
&
_u
,
double
&
_v
)
const
{
double
uv
[
3
]
=
{
u
,
v
,
0.
};
double
uv
[
3
]
=
{
u
,
v
,
0.
};
*
mt
=
(
discreteDiskFaceTriangle
*
)
Octree_Search
(
uv
,
oct
);
*
mt
=
(
discreteDiskFaceTriangle
*
)
Octree_Search
(
uv
,
oct
);
if
(
!
(
*
mt
))
return
;
if
(
!
(
*
mt
))
return
;
double
M
[
2
][
2
],
X
[
2
],
R
[
2
];
if
(
_order
==
1
){
const
SPoint3
p0
=
(
*
mt
)
->
p1
;
double
M
[
2
][
2
],
X
[
2
],
R
[
2
];
const
SPoint3
p1
=
(
*
mt
)
->
p2
;
const
SPoint3
p0
=
(
*
mt
)
->
p
[
0
];
const
SPoint3
p2
=
(
*
mt
)
->
p3
;
const
SPoint3
p1
=
(
*
mt
)
->
p
[
1
];
M
[
0
][
0
]
=
p1
.
x
()
-
p0
.
x
();
const
SPoint3
p2
=
(
*
mt
)
->
p
[
2
];
M
[
0
][
1
]
=
p2
.
x
()
-
p0
.
x
();
M
[
0
][
0
]
=
p1
.
x
()
-
p0
.
x
();
M
[
1
][
0
]
=
p1
.
y
()
-
p0
.
y
();
M
[
0
][
1
]
=
p2
.
x
()
-
p0
.
x
();
M
[
1
][
1
]
=
p2
.
y
()
-
p0
.
y
();
M
[
1
][
0
]
=
p1
.
y
()
-
p0
.
y
();
R
[
0
]
=
(
u
-
p0
.
x
());
M
[
1
][
1
]
=
p2
.
y
()
-
p0
.
y
();
R
[
1
]
=
(
v
-
p0
.
y
());
R
[
0
]
=
(
u
-
p0
.
x
());
sys2x2
(
M
,
R
,
X
);
R
[
1
]
=
(
v
-
p0
.
y
());
_u
=
X
[
0
];
sys2x2
(
M
,
R
,
X
);
_v
=
X
[
1
];
_u
=
X
[
0
];
// xi
_v
=
X
[
1
];
// eta
}
else
{
// newton raphson
discreteDiskFaceTriangle
*
my_ddft
=
*
mt
;
double
Xi
[
3
];
my_ddft
->
tri
->
xyz2uvw
(
uv
,
Xi
);
_u
=
Xi
[
0
];
_v
=
Xi
[
1
];
}
}
void
discreteDiskFace
::
checkOrientationUV
(){
double
initial
,
current
;
// initial and current orientation
discreteDiskFaceTriangle
*
ct
;
ct
=
&
_ddft
[
0
];
double
p1
[
2
]
=
{
ct
->
p
[
0
].
x
(),
ct
->
p
[
0
].
y
()};
double
p2
[
2
]
=
{
ct
->
p
[
1
].
x
(),
ct
->
p
[
1
].
y
()};
double
p3
[
2
]
=
{
ct
->
p
[
2
].
x
(),
ct
->
p
[
2
].
y
()};
initial
=
robustPredicates
::
orient2d
(
p1
,
p2
,
p3
);
unsigned
int
i
=
1
;
for
(;
i
<
discrete_triangles
.
size
();
i
++
){
ct
=
&
_ddft
[
i
];
p1
[
0
]
=
ct
->
p
[
0
].
x
();
p1
[
1
]
=
ct
->
p
[
0
].
y
();
p2
[
0
]
=
ct
->
p
[
1
].
x
();
p2
[
1
]
=
ct
->
p
[
1
].
y
();
p3
[
0
]
=
ct
->
p
[
2
].
x
();
p3
[
1
]
=
ct
->
p
[
2
].
y
();
current
=
robustPredicates
::
orient2d
(
p1
,
p2
,
p3
);
if
(
initial
*
current
<
0.
)
break
;
}
if
(
i
<
discrete_triangles
.
size
())
Msg
::
Error
(
"discreteDiskFace: The parametrization is not one-to-one :-("
);
else
std
::
cout
<<
"discreteDiskFace: The parametrization is one-to-one :-)"
<<
std
::
endl
;
}
}
// (u;v) |-> < (x;y;z); GFace; (u;v) >
// (u;v) |-> < (x;y;z); GFace; (u;v) >
GPoint
discreteDiskFace
::
point
(
const
double
par1
,
const
double
par2
)
const
GPoint
discreteDiskFace
::
point
(
const
double
par1
,
const
double
par2
)
const
{
{
double
U
,
V
;
double
U
,
V
;
double
par
[
2
]
=
{
par1
,
par2
};
double
par
[
2
]
=
{
par1
,
par2
};
discreteDiskFaceTriangle
*
dt
;
discreteDiskFaceTriangle
*
dt
;
getTriangleUV
(
par1
,
par2
,
&
dt
,
U
,
V
);
getTriangleUV
(
par1
,
par2
,
&
dt
,
U
,
V
);
// return Xi,Eta
if
(
!
dt
)
{
if
(
!
dt
)
{
GPoint
gp
=
GPoint
(
1.e22
,
1.e22
,
1.e22
,
_parent
,
par
);
GPoint
gp
=
GPoint
(
1.e22
,
1.e22
,
1.e22
,
_parent
,
par
);
gp
.
setNoSuccess
();
gp
.
setNoSuccess
();
return
gp
;
return
gp
;
}
}
SPoint3
p
=
dt
->
v1
*
(
1.
-
U
-
V
)
+
dt
->
v2
*
U
+
dt
->
v3
*
V
;
//polynomialBasis myPolynomial = polynomialBasis(dt->tri->getTypeForMSH());
double
eval
[
_N
];
mynodalbasis
->
f
(
U
,
V
,
0.
,
eval
);
//#mark
SPoint3
p
;
for
(
int
io
=
0
;
io
<
_N
;
io
++
)
p
+=
dt
->
v
[
io
]
*
eval
[
io
];
return
GPoint
(
p
.
x
(),
p
.
y
(),
p
.
z
(),
_parent
,
par
);
return
GPoint
(
p
.
x
(),
p
.
y
(),
p
.
z
(),
_parent
,
par
);
}
}
...
@@ -469,13 +752,13 @@ SPoint2 discreteDiskFace::parFromVertex(MVertex *v) const
...
@@ -469,13 +752,13 @@ SPoint2 discreteDiskFace::parFromVertex(MVertex *v) const
if
(
de
){
if
(
de
){
MVertex
*
v1
,
*
v2
;
MVertex
*
v1
,
*
v2
;
double
xi
;
double
xi
;
de
->
interpolateInGeometry
(
v
,
&
v1
,
&
v2
,
xi
);
de
->
interpolateInGeometry
(
v
,
&
v1
,
&
v2
,
xi
);
// modify
std
::
map
<
MVertex
*
,
SPoint3
>::
iterator
it1
=
coordinates
.
find
(
v1
);
std
::
map
<
MVertex
*
,
SPoint3
>::
iterator
it1
=
coordinates
.
find
(
v1
);
std
::
map
<
MVertex
*
,
SPoint3
>::
iterator
it2
=
coordinates
.
find
(
v2
);
std
::
map
<
MVertex
*
,
SPoint3
>::
iterator
it2
=
coordinates
.
find
(
v2
);
if
(
it1
==
coordinates
.
end
())
Msg
::
Fatal
(
"FIXME TO DO %d %s"
,
__LINE__
,
__FILE__
);
if
(
it1
==
coordinates
.
end
())
Msg
::
Fatal
(
"FIXME TO DO %d %s"
,
__LINE__
,
__FILE__
);
if
(
it2
==
coordinates
.
end
())
Msg
::
Fatal
(
"FIXME TO DO %d %s"
,
__LINE__
,
__FILE__
);
if
(
it2
==
coordinates
.
end
())
Msg
::
Fatal
(
"FIXME TO DO %d %s"
,
__LINE__
,
__FILE__
);
return
SPoint2
(
it1
->
second
.
x
(),
it1
->
second
.
y
())
*
(
1.
-
xi
)
+
return
SPoint2
(
it1
->
second
.
x
(),
it1
->
second
.
y
())
*
(
1.
-
xi
)
+
SPoint2
(
it2
->
second
.
x
(),
it2
->
second
.
y
())
*
xi
;
SPoint2
(
it2
->
second
.
x
(),
it2
->
second
.
y
())
*
xi
;
// modify
}
}
}
}
Msg
::
Fatal
(
"FIXME TO DO %d %s"
,
__LINE__
,
__FILE__
);
Msg
::
Fatal
(
"FIXME TO DO %d %s"
,
__LINE__
,
__FILE__
);
...
@@ -506,7 +789,6 @@ double discreteDiskFace::curvatures(const SPoint2 ¶m, SVector3 *dirMax, SVec
...
@@ -506,7 +789,6 @@ double discreteDiskFace::curvatures(const SPoint2 ¶m, SVector3 *dirMax, SVec
Pair
<
SVector3
,
SVector3
>
discreteDiskFace
::
firstDer
(
const
SPoint2
&
param
)
const
Pair
<
SVector3
,
SVector3
>
discreteDiskFace
::
firstDer
(
const
SPoint2
&
param
)
const
{
{
double
U
,
V
;
double
U
,
V
;
discreteDiskFaceTriangle
*
ddft
;
discreteDiskFaceTriangle
*
ddft
;
getTriangleUV
(
param
.
x
(),
param
.
y
(),
&
ddft
,
U
,
V
);
getTriangleUV
(
param
.
x
(),
param
.
y
(),
&
ddft
,
U
,
V
);
...
@@ -517,34 +799,26 @@ Pair<SVector3, SVector3> discreteDiskFace::firstDer(const SPoint2 ¶m) const
...
@@ -517,34 +799,26 @@ Pair<SVector3, SVector3> discreteDiskFace::firstDer(const SPoint2 ¶m) const
Msg
::
Warning
(
"discreteDiskFace::firstDer << triangle not found %g %g"
,
param
[
0
],
param
[
1
]);
Msg
::
Warning
(
"discreteDiskFace::firstDer << triangle not found %g %g"
,
param
[
0
],
param
[
1
]);
return
Pair
<
SVector3
,
SVector3
>
(
SVector3
(
1
,
0
,
0
),
SVector3
(
0
,
1
,
0
));
return
Pair
<
SVector3
,
SVector3
>
(
SVector3
(
1
,
0
,
0
),
SVector3
(
0
,
1
,
0
));
}
}
SVector3
dXdU
=
0.
;
//dXdu1*(1.-U-V) + dXdu2*U + dXdu3*V;
SVector3
dXdV
=
0.
;
//dXdv1*(1.-U-V) + dXdv2*U + dXdv3*V;
double
eval
[
_N
];
mynodalbasis
->
f
(
U
,
V
,
0.
,
eval
);
//#mark
for
(
unsigned
int
io
=
0
;
io
<
_N
;
io
++
){
std
::
map
<
MVertex
*
,
Pair
<
SVector3
,
SVector3
>
>::
iterator
it
=
firstDerivatives
.
find
(
tri
->
getVertex
(
io
));
if
(
it
==
firstDerivatives
.
end
())
Msg
::
Fatal
(
"Vertex %d (%d) has no firstDerivatives"
,
tri
->
getVertex
(
io
)
->
getNum
(),
io
);
SVector3
dXdu
=
it
->
second
.
first
();
SVector3
dXdv
=
it
->
second
.
second
();
dXdU
+=
dXdu
*
eval
[
io
];
dXdV
+=
dXdv
*
eval
[
io
];
}
std
::
map
<
MVertex
*
,
Pair
<
SVector3
,
SVector3
>
>::
iterator
it0
=
return
Pair
<
SVector3
,
SVector3
>
(
dXdU
,
dXdV
);
firstDerivatives
.
find
(
tri
->
getVertex
(
0
));
if
(
it0
==
firstDerivatives
.
end
())
Msg
::
Fatal
(
"Vertex %d (0) has no firstDerivatives"
,
tri
->
getVertex
(
0
)
->
getNum
());
std
::
map
<
MVertex
*
,
Pair
<
SVector3
,
SVector3
>
>::
iterator
it1
=
firstDerivatives
.
find
(
tri
->
getVertex
(
1
));
if
(
it1
==
firstDerivatives
.
end
())
Msg
::
Fatal
(
"Vertex %d (1) has no firstDerivatives"
,
tri
->
getVertex
(
1
)
->
getNum
());
std
::
map
<
MVertex
*
,
Pair
<
SVector3
,
SVector3
>
>::
iterator
it2
=
firstDerivatives
.
find
(
tri
->
getVertex
(
2
));
if
(
it2
==
firstDerivatives
.
end
())
Msg
::
Fatal
(
"Vertex %d (2) has no firstDerivatives"
,
tri
->
getVertex
(
2
)
->
getNum
());
SVector3
dXdu1
=
it0
->
second
.
first
();
SVector3
dXdu2
=
it1
->
second
.
first
();
SVector3
dXdu3
=
it2
->
second
.
first
();
SVector3
dXdv1
=
it0
->
second
.
second
();
SVector3
dXdv2
=
it1
->
second
.
second
();
SVector3
dXdv3
=
it2
->
second
.
second
();
SVector3
dXdu
=
dXdu1
*
(
1.
-
U
-
V
)
+
dXdu2
*
U
+
dXdu3
*
V
;
SVector3
dXdv
=
dXdv1
*
(
1.
-
U
-
V
)
+
dXdv2
*
U
+
dXdv3
*
V
;
return
Pair
<
SVector3
,
SVector3
>
(
dXdu
,
dXdv
);
}
}
...
@@ -572,17 +846,64 @@ void discreteDiskFace::buildAllNodes()
...
@@ -572,17 +846,64 @@ void discreteDiskFace::buildAllNodes()
void
discreteDiskFace
::
putOnView
()
void
discreteDiskFace
::
putOnView
()
{
{
FILE
*
view_u
=
Fopen
(
"param_u.pos"
,
"w"
);
FILE
*
view_v
=
Fopen
(
"param_v.pos"
,
"w"
);
FILE
*
UVxyz
=
Fopen
(
"UVxyz.pos"
,
"w"
);
if
(
view_u
&&
view_v
){
fprintf
(
view_u
,
"View
\"
paramU
\"
{
\n
"
);
fprintf
(
view_v
,
"View
\"
paramV
\"
{
\n
"
);
fprintf
(
UVxyz
,
"View
\"
Uxyz
\"
{
\n
"
);
for
(
unsigned
int
i
=
0
;
i
<
discrete_triangles
.
size
();
i
++
){
discreteDiskFaceTriangle
*
my_ddft
=
&
_ddft
[
i
];
if
(
_order
==
1
){
fprintf
(
view_u
,
"ST("
);
fprintf
(
view_v
,
"ST("
);
fprintf
(
UVxyz
,
"ST("
);
}
else
{
fprintf
(
view_u
,
"ST%d("
,
_order
);
fprintf
(
view_v
,
"ST%d("
,
_order
);
fprintf
(
UVxyz
,
"ST%d("
,
_order
);
}
for
(
unsigned
int
j
=
0
;
j
<
_N
-
1
;
j
++
){
fprintf
(
view_u
,
"%g,%g,%g,"
,
my_ddft
->
v
[
j
].
x
(),
my_ddft
->
v
[
j
].
y
(),
my_ddft
->
v
[
j
].
z
());
fprintf
(
view_v
,
"%g,%g,%g,"
,
my_ddft
->
v
[
j
].
x
(),
my_ddft
->
v
[
j
].
y
(),
my_ddft
->
v
[
j
].
z
());
fprintf
(
UVxyz
,
"%g,%g,%g,"
,
my_ddft
->
p
[
j
].
x
(),
my_ddft
->
p
[
j
].
y
(),
0.
);
}
fprintf
(
view_u
,
"%g,%g,%g){"
,
my_ddft
->
v
[
_N
-
1
].
x
(),
my_ddft
->
v
[
_N
-
1
].
y
(),
my_ddft
->
v
[
_N
-
1
].
z
());
fprintf
(
view_v
,
"%g,%g,%g){"
,
my_ddft
->
v
[
_N
-
1
].
x
(),
my_ddft
->
v
[
_N
-
1
].
y
(),
my_ddft
->
v
[
_N
-
1
].
z
());
fprintf
(
UVxyz
,
"%g,%g,%g){"
,
my_ddft
->
p
[
_N
-
1
].
x
(),
my_ddft
->
p
[
_N
-
1
].
y
(),
0.
);
for
(
unsigned
int
j
=
0
;
j
<
_N
-
1
;
j
++
){
fprintf
(
view_u
,
"%g,"
,
my_ddft
->
p
[
j
].
x
());
fprintf
(
view_v
,
"%g,"
,
my_ddft
->
p
[
j
].
y
());
fprintf
(
UVxyz
,
"%g,"
,
sqrt
(
my_ddft
->
v
[
j
].
x
()
*
my_ddft
->
v
[
j
].
x
()
+
my_ddft
->
v
[
j
].
z
()
*
my_ddft
->
v
[
j
].
z
()
+
my_ddft
->
v
[
j
].
y
()
*
my_ddft
->
v
[
j
].
y
()));
}
fprintf
(
view_u
,
"%g};
\n
"
,
my_ddft
->
p
[
_N
-
1
].
x
());
fprintf
(
view_v
,
"%g};
\n
"
,
my_ddft
->
p
[
_N
-
1
].
y
());
fprintf
(
UVxyz
,
"%g};
\n
"
,
sqrt
(
my_ddft
->
v
[
_N
-
1
].
x
()
*
my_ddft
->
v
[
_N
-
1
].
x
()
+
my_ddft
->
v
[
_N
-
1
].
z
()
*
my_ddft
->
v
[
_N
-
1
].
z
()
+
my_ddft
->
v
[
_N
-
1
].
y
()
*
my_ddft
->
v
[
_N
-
1
].
y
()));
}
fprintf
(
view_u
,
"};
\n
"
);
fprintf
(
view_v
,
"};
\n
"
);
fprintf
(
UVxyz
,
"};
\n
"
);
fclose
(
view_u
);
fclose
(
view_v
);
fclose
(
UVxyz
);
}
/*
#ifdef HAVE_POST
#ifdef HAVE_POST
std::map<int, std::vector<double> > u;
std::map<int, std::vector<double> > u;
std::map<int, std::vector<double> > v;
std::map<int, std::vector<double> > v;
for(std::set<MVertex*>::iterator iv = allNodes.begin(); iv!=allNodes.end(); ++iv){
for(std::set<MVertex*>::iterator iv = allNodes.begin(); iv!=allNodes.end(); ++iv){
MVertex *p = *iv;
MVertex *p = *iv;
u[p->getNum()].push_back(coordinates[p].x());
u[p->getNum()].push_back(coordinates[p].x());
v[p->getNum()].push_back(coordinates[p].y());
v[p->getNum()].push_back(coordinates[p].y());
}
}
PView* view_u = new PView("u", "NodeData", GModel::current(), u);
PView* view_u = new PView("u", "NodeData", GModel::current(), u);
PView
*
view_v
=
new
PView
(
"
u
"
,
"NodeData"
,
GModel
::
current
(),
v
);
PView* view_v = new PView("
v
", "NodeData", GModel::current(), v);
view_u->setChanged(true);
view_u->setChanged(true);
view_v->setChanged(true);
view_v->setChanged(true);
view_u->write("param_u.msh", 5);
view_u->write("param_u.msh", 5);
...
@@ -592,6 +913,7 @@ void discreteDiskFace::putOnView()
...
@@ -592,6 +913,7 @@ void discreteDiskFace::putOnView()
#else
#else
Msg::Error("discreteDiskFace: cannot export without post module")
Msg::Error("discreteDiskFace: cannot export without post module")
#endif
#endif
*/
}
}
// useful for mesh generators ----------------------------------------
// useful for mesh generators ----------------------------------------
...
@@ -614,10 +936,8 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
...
@@ -614,10 +936,8 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
// the point is situated in the half plane defined
// the point is situated in the half plane defined
// by direction n1 and point p (exclude the one on the
// by direction n1 and point p (exclude the one on the
// other side)
// other side)
SVector3
t1
=
ct
->
v
[
1
]
-
ct
->
v
[
0
];
SVector3
t1
=
ct
->
v2
-
ct
->
v1
;
SVector3
t2
=
ct
->
v
[
2
]
-
ct
->
v
[
0
];
SVector3
t2
=
ct
->
v3
-
ct
->
v1
;
// let us first compute point q to be the intersection
// let us first compute point q to be the intersection
// of the plane of the triangle with the line L = p + t n1
// of the plane of the triangle with the line L = p + t n1
// Compute w = t1 x t2 = (a,b,c) and write a point of the plabe as
// Compute w = t1 x t2 = (a,b,c) and write a point of the plabe as
...
@@ -626,15 +946,13 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
...
@@ -626,15 +946,13 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
// a (p_x + t n1_x) + a (p_y + t n1_y) + c (p_z + t n1_z) -
// a (p_x + t n1_x) + a (p_y + t n1_y) + c (p_z + t n1_z) -
// (v1_x a + v1_y b + v1_z * c) = 0
// (v1_x a + v1_y b + v1_z * c) = 0
// gives t
// gives t
SVector3
w
=
crossprod
(
t1
,
t2
);
SVector3
w
=
crossprod
(
t1
,
t2
);
double
t
=
d
;
double
t
=
d
;
// if everything is not coplanar ...
// if everything is not coplanar ...
if
(
fabs
(
dot
(
n1
,
w
))
>
1.e-12
){
if
(
fabs
(
dot
(
n1
,
w
))
>
1.e-12
){
t
=
dot
(
ct
->
v
1
-
p
,
w
)
/
dot
(
n1
,
w
);
t
=
dot
(
ct
->
v
[
0
]
-
p
,
w
)
/
dot
(
n1
,
w
);
}
}
SVector3
q
=
p
+
n1
*
t
;
SVector3
q
=
p
+
n1
*
t
;
// consider the line that intersects both planes in its
// consider the line that intersects both planes in its
// parametric form
// parametric form
// X(x,y,z) = q + t m
// X(x,y,z) = q + t m
...
@@ -650,12 +968,10 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
...
@@ -650,12 +968,10 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
// we choose the one that corresponds to (s_i - p) . n1 > 0
// we choose the one that corresponds to (s_i - p) . n1 > 0
SVector3
m
=
crossprod
(
w
,
n
);
SVector3
m
=
crossprod
(
w
,
n
);
const
double
a
=
dot
(
m
,
m
);
const
double
a
=
dot
(
m
,
m
);
const
double
b
=
2
*
dot
(
m
,
q
-
p
);
const
double
b
=
2
*
dot
(
m
,
q
-
p
);
const
double
c
=
dot
(
q
-
p
,
q
-
p
)
-
d
*
d
;
const
double
c
=
dot
(
q
-
p
,
q
-
p
)
-
d
*
d
;
const
double
delta
=
b
*
b
-
4
*
a
*
c
;
const
double
delta
=
b
*
b
-
4
*
a
*
c
;
if
(
delta
>=
0
){
if
(
delta
>=
0
){
const
double
ta
=
(
-
b
+
sqrt
(
delta
))
/
(
2.
*
a
);
const
double
ta
=
(
-
b
+
sqrt
(
delta
))
/
(
2.
*
a
);
const
double
tb
=
(
-
b
-
sqrt
(
delta
))
/
(
2.
*
a
);
const
double
tb
=
(
-
b
-
sqrt
(
delta
))
/
(
2.
*
a
);
...
@@ -681,20 +997,20 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
...
@@ -681,20 +997,20 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
mat
[
0
][
0
]
=
dot
(
t1
,
t1
);
mat
[
0
][
0
]
=
dot
(
t1
,
t1
);
mat
[
1
][
1
]
=
dot
(
t2
,
t2
);
mat
[
1
][
1
]
=
dot
(
t2
,
t2
);
mat
[
0
][
1
]
=
mat
[
1
][
0
]
=
dot
(
t1
,
t2
);
mat
[
0
][
1
]
=
mat
[
1
][
0
]
=
dot
(
t1
,
t2
);
b
[
0
]
=
dot
(
s
-
ct
->
v
1
,
t1
)
;
b
[
0
]
=
dot
(
s
-
ct
->
v
[
0
]
,
t1
)
;
b
[
1
]
=
dot
(
s
-
ct
->
v
1
,
t2
)
;
b
[
1
]
=
dot
(
s
-
ct
->
v
[
0
]
,
t2
)
;
sys2x2
(
mat
,
b
,
uv
);
sys2x2
(
mat
,
b
,
uv
);
// check now if the point is inside the triangle
// check now if the point is inside the triangle
if
(
uv
[
0
]
>=
-
1.e-6
&&
uv
[
1
]
>=
-
1.e-6
&&
if
(
uv
[
0
]
>=
-
1.e-6
&&
uv
[
1
]
>=
-
1.e-6
&&
1.
-
uv
[
0
]
-
uv
[
1
]
>=
-
1.e-6
)
{
1.
-
uv
[
0
]
-
uv
[
1
]
>=
-
1.e-6
)
{
SVector3
pp
=
SVector3
pp
=
ct
->
p
1
*
(
1.
-
uv
[
0
]
-
uv
[
1
]
)
+
ct
->
p
[
0
]
*
(
1.
-
uv
[
0
]
-
uv
[
1
]
)
+
ct
->
p
2
*
uv
[
0
]
+
ct
->
p
[
1
]
*
uv
[
0
]
+
ct
->
p
3
*
uv
[
1
]
;
ct
->
p
[
2
]
*
uv
[
1
]
;
return
GPoint
(
s
.
x
(),
s
.
y
(),
s
.
z
(),
this
,
pp
);
return
GPoint
(
s
.
x
(),
s
.
y
(),
s
.
z
(),
this
,
pp
);
}
}
}
}
}
}
GPoint
pp
(
0
);
GPoint
pp
(
0
);
pp
.
setNoSuccess
();
pp
.
setNoSuccess
();
Msg
::
Debug
(
"ARGG no success intersection circle"
);
Msg
::
Debug
(
"ARGG no success intersection circle"
);
...
@@ -702,4 +1018,6 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
...
@@ -702,4 +1018,6 @@ GPoint discreteDiskFace::intersectionWithCircle(const SVector3 &n1, const SVecto
}
}
#endif
#endif
This diff is collapsed.
Click to expand it.
Geo/discreteDiskFace.h
+
29
−
8
View file @
5a363a6f
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include
"MElementOctree.h"
#include
"MElementOctree.h"
#include
"meshGFaceOptimize.h"
#include
"meshGFaceOptimize.h"
#include
"PView.h"
#include
"PView.h"
#include
"robustPredicates.h"
class
ANNkd_tree
;
class
ANNkd_tree
;
class
Octree
;
class
Octree
;
...
@@ -29,9 +30,9 @@ class GRbf;
...
@@ -29,9 +30,9 @@ class GRbf;
class
discreteDiskFaceTriangle
{
class
discreteDiskFaceTriangle
{
public:
public:
SPoint3
p1
,
p2
,
p
3
;
// vertices in (u;v)
SPoint3
*
p
;
// vertices in (u;v)
SPoint2
gfp1
,
gfp2
,
gfp
3
;
// CAD model
SPoint2
*
gfp
;
// CAD model
SPoint3
v1
,
v2
,
v3
;
// vertices in (x;y;z)
SPoint3
*
v
;
// vertices in (x;y;z)
GFace
*
gf
;
// GFace tag
GFace
*
gf
;
// GFace tag
MTriangle
*
tri
;
// mesh triangle in (x;y;z)
MTriangle
*
tri
;
// mesh triangle in (x;y;z)
discreteDiskFaceTriangle
()
:
gf
(
0
),
tri
(
0
)
{}
discreteDiskFaceTriangle
()
:
gf
(
0
),
tri
(
0
)
{}
...
@@ -41,14 +42,14 @@ class discreteDiskFaceTriangle {
...
@@ -41,14 +42,14 @@ class discreteDiskFaceTriangle {
class
discreteDiskFace
:
public
GFace
{
class
discreteDiskFace
:
public
GFace
{
GFace
*
_parent
;
GFace
*
_parent
;
// bool checkOrientation(int iter, bool moveBoundaries=false) const; // mark todo
void
buildOct
()
const
;
void
buildOct
()
const
;
bool
parametrize
()
const
;
bool
parametrize
()
const
;
void
buildAllNodes
()
;
void
buildAllNodes
()
;
void
getBoundingEdges
();
void
getBoundingEdges
();
void
putOnView
();
void
putOnView
();
public:
public:
discreteDiskFace
(
GFace
*
parent
,
std
::
vector
<
MTriangle
*>
&
mesh
);
discreteDiskFace
(
GFace
*
parent
,
std
::
vector
<
MTriangle
*>
&
mesh
,
int
p
);
// MTriangle -> MTriangle 6
virtual
~
discreteDiskFace
()
{
triangles
.
clear
();}
virtual
~
discreteDiskFace
()
{
triangles
.
clear
();}
void
getTriangleUV
(
const
double
u
,
const
double
v
,
discreteDiskFaceTriangle
**
mt
,
double
&
_u
,
double
&
_v
)
const
;
void
getTriangleUV
(
const
double
u
,
const
double
v
,
discreteDiskFaceTriangle
**
mt
,
double
&
_u
,
double
&
_v
)
const
;
GPoint
point
(
double
par1
,
double
par2
)
const
;
GPoint
point
(
double
par1
,
double
par2
)
const
;
...
@@ -63,12 +64,31 @@ class discreteDiskFace : public GFace {
...
@@ -63,12 +64,31 @@ class discreteDiskFace : public GFace {
GPoint
intersectionWithCircle
(
const
SVector3
&
n1
,
const
SVector3
&
n2
,
GPoint
intersectionWithCircle
(
const
SVector3
&
n1
,
const
SVector3
&
n2
,
const
SVector3
&
p
,
const
double
&
d
,
const
SVector3
&
p
,
const
double
&
d
,
double
uv
[
2
])
const
;
double
uv
[
2
])
const
;
void
checkOrientationUV
();
protected
:
protected
:
//------------------------------------------------
//------------------------------------------------
// a copy of the mesh that should not be destroyed
// a copy of the mesh that should not be destroyed
std
::
vector
<
MTriangle
*>
discrete_triangles
;
std
::
vector
<
MTriangle
*>
discrete_triangles
;
// MTriangleN AND MTriangle6 are children of MTriangle
std
::
vector
<
MVertex
*>
discrete_vertices
;
std
::
vector
<
MVertex
*>
discrete_vertices
;
//------------------------------------------------
//------------------------------------------------
int
nodeLocalNum
(
MElement
*
e
,
MVertex
*
v
)
const
{
for
(
unsigned
int
i
=
0
;
i
<
e
->
getNumVertices
();
i
++
)
if
(
v
==
e
->
getVertex
(
i
))
return
i
;
};
int
edgeLocalNum
(
MElement
*
e
,
MEdge
ed
)
const
{
for
(
unsigned
int
i
=
0
;
i
<
e
->
getNumEdges
();
i
++
)
if
(
ed
==
e
->
getEdge
(
i
))
return
i
;
};
void
init_ddft
(
discreteDiskFaceTriangle
*
ddft
)
const
{
ddft
->
p
=
new
SPoint3
[
_N
];
ddft
->
gfp
=
new
SPoint2
[
_N
];
ddft
->
v
=
new
SPoint3
[
_N
];
};
//------------------------------------------------
int
_order
;
int
_N
;
double
_totLength
;
double
_totLength
;
std
::
map
<
double
,
std
::
vector
<
MVertex
*>
>
_loops
;
std
::
map
<
double
,
std
::
vector
<
MVertex
*>
>
_loops
;
std
::
vector
<
MVertex
*>
_U0
;
// dirichlet's bc's
std
::
vector
<
MVertex
*>
_U0
;
// dirichlet's bc's
...
@@ -77,13 +97,14 @@ class discreteDiskFace : public GFace {
...
@@ -77,13 +97,14 @@ class discreteDiskFace : public GFace {
mutable
std
::
map
<
SPoint3
,
SPoint3
>
_coordPoints
;
// ?
mutable
std
::
map
<
SPoint3
,
SPoint3
>
_coordPoints
;
// ?
mutable
v2t_cont
adjv
;
// ? v2t_cont ? ?????
mutable
v2t_cont
adjv
;
// ? v2t_cont ? ?????
mutable
std
::
map
<
MVertex
*
,
Pair
<
SVector3
,
SVector3
>
>
firstDerivatives
;
mutable
std
::
map
<
MVertex
*
,
Pair
<
SVector3
,
SVector3
>
>
firstDerivatives
;
mutable
std
::
map
<
MElement
*
,
Pair
<
SVector3
,
SVector3
>
>
firstElemDerivatives
;
mutable
std
::
map
<
MElement
*
,
std
::
vector
<
Pair
<
SVector3
,
SVector3
>
>
>
firstElemDerivatives
;
//dXdU
mutable
discreteDiskFaceTriangle
*
_ddft
;
mutable
discreteDiskFaceTriangle
*
_ddft
;
mutable
ANNkd_tree
*
uv_kdtree
;
mutable
ANNkd_tree
*
uv_kdtree
;
mutable
ANNkd_tree
*
kdtree
;
mutable
ANNkd_tree
*
kdtree
;
mutable
Octree
*
oct
;
mutable
Octree
*
oct
;
mutable
std
::
vector
<
double
>
_coords
;
mutable
std
::
vector
<
double
>
_coords
;
const
nodalBasis
*
mynodalbasis
;
const
bezierBasis
*
mybezierbasis
;
};
};
#endif
#endif
...
...
This diff is collapsed.
Click to expand it.
Geo/discreteFace.cpp
+
10
−
37
View file @
5a363a6f
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
#include
"OS.h"
#include
"OS.h"
discreteFace
::
discreteFace
(
GModel
*
model
,
int
num
)
:
GFace
(
model
,
num
)
discreteFace
::
discreteFace
(
GModel
*
model
,
int
num
)
:
GFace
(
model
,
num
)
{
{
Surface
*
s
=
Create_Surface
(
num
,
MSH_SURF_DISCRETE
);
Surface
*
s
=
Create_Surface
(
num
,
MSH_SURF_DISCRETE
);
Tree_Add
(
model
->
getGEOInternals
()
->
Surfaces
,
&
s
);
Tree_Add
(
model
->
getGEOInternals
()
->
Surfaces
,
&
s
);
meshStatistics
.
status
=
GFace
::
DONE
;
meshStatistics
.
status
=
GFace
::
DONE
;
...
@@ -72,79 +72,52 @@ GPoint discreteFace::point(double par1, double par2) const
...
@@ -72,79 +72,52 @@ GPoint discreteFace::point(double par1, double par2) const
SPoint2
discreteFace
::
parFromPoint
(
const
SPoint3
&
p
,
bool
onSurface
)
const
SPoint2
discreteFace
::
parFromPoint
(
const
SPoint3
&
p
,
bool
onSurface
)
const
{
{
if
(
getCompound
()){
return
SPoint2
();
return
getCompound
()
->
parFromPoint
(
p
);
}
else
{
Msg
::
Error
(
"Cannot compute parametric coordinates on discrete face"
);
return
SPoint2
();
}
}
}
SVector3
discreteFace
::
normal
(
const
SPoint2
&
param
)
const
SVector3
discreteFace
::
normal
(
const
SPoint2
&
param
)
const
{
{
if
(
getCompound
()){
return
getCompound
()
->
normal
(
param
);
}
else
{
Msg
::
Error
(
"Cannot evaluate normal on discrete face"
);
return
SVector3
();
return
SVector3
();
}
}
}
double
discreteFace
::
curvatureMax
(
const
SPoint2
&
param
)
const
double
discreteFace
::
curvatureMax
(
const
SPoint2
&
param
)
const
{
{
if
(
getCompound
()){
return
getCompound
()
->
curvatureMax
(
param
);
}
else
{
Msg
::
Error
(
"Cannot evaluate curvature on discrete face"
);
return
false
;
return
false
;
}
}
}
double
discreteFace
::
curvatures
(
const
SPoint2
&
param
,
SVector3
*
dirMax
,
SVector3
*
dirMin
,
double
discreteFace
::
curvatures
(
const
SPoint2
&
param
,
SVector3
*
dirMax
,
SVector3
*
dirMin
,
double
*
curvMax
,
double
*
curvMin
)
const
double
*
curvMax
,
double
*
curvMin
)
const
{
{
if
(
getCompound
()){
return
false
;
return
getCompound
()
->
curvatures
(
param
,
dirMax
,
dirMin
,
curvMax
,
curvMin
);
}
else
{
Msg
::
Error
(
"Cannot evaluate curvatures and curvature directions on discrete face"
);
return
false
;
}
}
}
Pair
<
SVector3
,
SVector3
>
discreteFace
::
firstDer
(
const
SPoint2
&
param
)
const
Pair
<
SVector3
,
SVector3
>
discreteFace
::
firstDer
(
const
SPoint2
&
param
)
const
{
{
if
(
getCompound
()){
return
Pair
<
SVector3
,
SVector3
>
();
return
getCompound
()
->
firstDer
(
param
);
}
else
{
Msg
::
Error
(
"Cannot evaluate derivative on discrete face"
);
return
Pair
<
SVector3
,
SVector3
>
();
}
}
}
void
discreteFace
::
secondDer
(
const
SPoint2
&
param
,
void
discreteFace
::
secondDer
(
const
SPoint2
&
param
,
SVector3
*
dudu
,
SVector3
*
dvdv
,
SVector3
*
dudv
)
const
SVector3
*
dudu
,
SVector3
*
dvdv
,
SVector3
*
dudv
)
const
{
{
/*<<<<<<< .mine
=======
if (getCompound()){
if (getCompound()){
return getCompound()->secondDer(param, dudu, dvdv, dudv);
return getCompound()->secondDer(param, dudu, dvdv, dudv);
}
}
else{
else{
Msg::Error("Cannot evaluate second derivative on discrete face");
Msg::Error("Cannot evaluate second derivative on discrete face");
>>>>>>> .r22873*/
return
;
return
;
}
}
}
// FIXME PAB ----> really create an atlas !!!!!!!!!!!!!!!
// FIXME PAB ----> really create an atlas !!!!!!!!!!!!!!!
void
discreteFace
::
createGeometry
()
void
discreteFace
::
createGeometry
()
{
{
#if defined(HAVE_ANN) && defined(HAVE_SOLVER)
#if defined(HAVE_ANN) && defined(HAVE_SOLVER)
if
(
!
_atlas
.
empty
())
return
;
if
(
!
_atlas
.
empty
())
return
;
// parametrization is done here !!!
// parametrization is done here !!!
discreteDiskFace
*
df
=
new
discreteDiskFace
(
this
,
triangles
);
discreteDiskFace
*
df
=
new
discreteDiskFace
(
this
,
triangles
,
2
);
df
->
replaceEdges
(
l_edges
);
df
->
replaceEdges
(
l_edges
);
_atlas
.
push_back
(
df
);
_atlas
.
push_back
(
df
);
#endif
#endif
...
...
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