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
1c3186a9
Commit
1c3186a9
authored
13 years ago
by
Amaury Johnen
Browse files
Options
Downloads
Patches
Plain Diff
No commit message
No commit message
parent
8d9a85f5
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Plugin/AnalyseCurvedMesh.cpp
+335
-811
335 additions, 811 deletions
Plugin/AnalyseCurvedMesh.cpp
Plugin/AnalyseCurvedMesh.h
+24
-40
24 additions, 40 deletions
Plugin/AnalyseCurvedMesh.h
with
359 additions
and
851 deletions
Plugin/AnalyseCurvedMesh.cpp
+
335
−
811
View file @
1c3186a9
...
@@ -10,28 +10,31 @@
...
@@ -10,28 +10,31 @@
#include
"polynomialBasis.h"
#include
"polynomialBasis.h"
#include
"AnalyseCurvedMesh.h"
#include
"AnalyseCurvedMesh.h"
#include
"Context.h"
#include
"Context.h"
#include
<queue>
#include
<cmath>
#include
<fstream>
#include
"OS.h"
#include
"PView.h"
#if defined(HAVE_OPENGL)
#if defined(HAVE_OPENGL)
#include
"drawContext.h"
#include
"drawContext.h"
#endif
#endif
#include
"OS.h"
#if defined(HAVE_FLTK)
#if defined(HAVE_FLTK)
#include
"FlGui.h"
#include
"FlGui.h"
#endif
#endif
#define UNDEF_JAC_TAG -999
//#define UNDEF_JAC_TAG -999
//#define _ANALYSECURVEDMESH_BLAS_
StringXNumber
JacobianOptions_Number
[]
=
{
StringXNumber
JacobianOptions_Number
[]
=
{
{
GMSH_FULLRC
,
"Dim"
,
NULL
,
-
1
},
{
GMSH_FULLRC
,
"Dim"
,
NULL
,
-
1
},
{
GMSH_FULLRC
,
"Analysis"
,
NULL
,
1
},
{
GMSH_FULLRC
,
"Analysis"
,
NULL
,
2
},
{
GMSH_FULLRC
,
"Effect"
,
NULL
,
6
},
{
GMSH_FULLRC
,
"Effect
(1)
"
,
NULL
,
6
},
{
GMSH_FULLRC
,
"
MaxDepth
"
,
NULL
,
1
0
},
{
GMSH_FULLRC
,
"
JacBreak (1)
"
,
NULL
,
.
0
},
{
GMSH_FULLRC
,
"
Jac
Break"
,
NULL
,
.0
},
{
GMSH_FULLRC
,
"
Bez
Break
(1)
"
,
NULL
,
.0
},
{
GMSH_FULLRC
,
"
BezBreak
"
,
NULL
,
.
0
},
{
GMSH_FULLRC
,
"
MaxDepth (1,2)
"
,
NULL
,
2
0
},
{
GMSH_FULLRC
,
"Tolerance"
,
NULL
,
1e-
5
}
{
GMSH_FULLRC
,
"Tolerance
(2)
"
,
NULL
,
1e-
3
}
};
};
extern
"C"
extern
"C"
...
@@ -74,51 +77,6 @@ std::string GMSH_AnalyseCurvedMeshPlugin::getHelp() const
...
@@ -74,51 +77,6 @@ std::string GMSH_AnalyseCurvedMeshPlugin::getHelp() const
}
}
// Miscellaneous method
// Miscellaneous method
/*int max(const std::vector<int> &vec)
{
int max = vec[0];
for (unsigned int i = 1; i < vec.size(); i++)
if (vec[i] > max) max = vec[i];
return max;
}*/
/*static double computeDeterminant(MElement *el, double jac[3][3])
{
switch (el->getDim()) {
case 0:
return 1.0;
case 1:
return jac[0][0];
case 2:
return jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0];
case 3:
return jac[0][0] * jac[1][1] * jac[2][2] + jac[0][2] * jac[1][0] * jac[2][1] +
jac[0][1] * jac[1][2] * jac[2][0] - jac[0][2] * jac[1][1] * jac[2][0] -
jac[0][0] * jac[1][2] * jac[2][1] - jac[0][1] * jac[1][0] * jac[2][2];
default:
return 1;
}
}
double getJacobian(double gsf[][3], double jac[3][3], MElement *el)
{
jac[0][0] = jac[0][1] = jac[0][2] = 0.;
jac[1][0] = jac[1][1] = jac[1][2] = 0.;
jac[2][0] = jac[2][1] = jac[2][2] = 0.;
for (int i = 0; i < el->getNumVertices(); i++) {
const MVertex *v = el->getVertex(i);
double *gg = gsf[i];
for (int j = 0; j < 3; j++) {
jac[j][0] += v->x() * gg[j];
jac[j][1] += v->y() * gg[j];
jac[j][2] += v->z() * gg[j];
}
}
return computeDeterminant(el, jac);
}*/
static
void
setJacobian
(
MElement
*
el
,
const
JacobianBasis
*
jfs
,
fullVector
<
double
>
&
jacobian
)
static
void
setJacobian
(
MElement
*
el
,
const
JacobianBasis
*
jfs
,
fullVector
<
double
>
&
jacobian
)
{
{
int
numVertices
=
el
->
getNumVertices
();
int
numVertices
=
el
->
getNumVertices
();
...
@@ -322,6 +280,15 @@ static void setJacobian(MElement *const *el, const JacobianBasis *jfs, fullMatri
...
@@ -322,6 +280,15 @@ static void setJacobian(MElement *const *el, const JacobianBasis *jfs, fullMatri
}
}
}
}
static
double
sum
(
fullVector
<
double
>
&
v
)
{
double
sum
=
.0
;
for
(
int
i
=
0
;
i
<
v
.
size
();
++
i
)
{
sum
+=
v
(
i
);
}
return
sum
;
}
// Execution
// Execution
PView
*
GMSH_AnalyseCurvedMeshPlugin
::
execute
(
PView
*
v
)
PView
*
GMSH_AnalyseCurvedMeshPlugin
::
execute
(
PView
*
v
)
{
{
...
@@ -329,167 +296,29 @@ PView *GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
...
@@ -329,167 +296,29 @@ PView *GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
_dim
=
(
int
)
JacobianOptions_Number
[
0
].
def
;
_dim
=
(
int
)
JacobianOptions_Number
[
0
].
def
;
if
(
_dim
<
0
||
_dim
>
3
)
if
(
_dim
<
0
||
_dim
>
3
)
_dim
=
_m
->
getDim
();
_dim
=
_m
->
getDim
();
int
analysis
=
(
int
)
JacobianOptions_Number
[
1
].
def
%
2
;
int
analysis
=
(
int
)
JacobianOptions_Number
[
1
].
def
%
4
;
int
toDo
=
(
int
)
JacobianOptions_Number
[
1
].
def
%
8
;
int
toDo
=
(
int
)
JacobianOptions_Number
[
2
].
def
%
8
;
_maxDepth
=
(
int
)
JacobianOptions_Number
[
2
].
def
;
_maxDepth
=
(
int
)
JacobianOptions_Number
[
5
].
def
;
_jacBreak
=
(
double
)
JacobianOptions_Number
[
3
].
def
;
_jacBreak
=
(
double
)
JacobianOptions_Number
[
3
].
def
;
_bezBreak
=
(
double
)
JacobianOptions_Number
[
4
].
def
;
_bezBreak
=
(
double
)
JacobianOptions_Number
[
4
].
def
;
_tol
=
(
double
)
JacobianOptions_Number
[
5
].
def
;
_tol
=
(
double
)
JacobianOptions_Number
[
6
].
def
;
if
(
analysis
%
2
)
{
if
(
analysis
%
2
)
{
double
t
=
Cpu
();
double
t
=
Cpu
();
Msg
::
Info
(
"St
r
ating validity check..."
);
Msg
::
Info
(
"Sta
r
ting validity check..."
);
checkValidity
(
toDo
);
checkValidity
(
toDo
);
Msg
::
Info
(
"Done validity check (%fs)"
,
Cpu
()
-
t
);
Msg
::
Info
(
"Done validity check (%fs)"
,
Cpu
()
-
t
);
}
}
if
(
analysis
/
2
)
{
if
(
analysis
/
2
)
{
double
t
=
Cpu
();
double
t
=
Cpu
();
Msg
::
Info
(
"Strating computation J_min / J_max..."
);
Msg
::
Info
(
"Starting computation J_min, J_max..."
);
computeMinMax
();
std
::
map
<
int
,
std
::
vector
<
double
>
>
data
;
Msg
::
Info
(
"Done computation J_min / J_max (%fs)"
,
Cpu
()
-
t
);
computeMinMax
(
&
data
);
new
PView
(
"Jmin"
,
"ElementData"
,
_m
,
data
);
Msg
::
Info
(
"Done computation J_min, J_max (%fs)"
,
Cpu
()
-
t
);
}
}
}
}
//{
// Msg::Info("AnalyseCurvedMeshPlugin : Starting analysis.");
// int numBadEl = 0;
// int numUncertain = 0;
// int numAnalysedEl = 0;
// std::vector<int> tag;
// int method = (int)JacobianOptions_Number[0].def % 4;
// int maxDepth = (int)JacobianOptions_Number[1].def;
//
// if (method < 1 || method > 2) {
//#if defined(HAVE_BLAS)
// method = 2;
//#else
// method = 1;
//#endif
// }
//
// GModel *m = GModel::current();
// switch (m->getDim()) {
//
// case 3 :
// Msg::Info("Only 3D elements will be analyse.");
// for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++) {
// GRegion *r = *it;
//
// unsigned int numType[5] = {0, 0, 0, 0, 0};
// r->getNumMeshElements(numType);
//
// for(int type = 0; type < 5; type++) {
// MElement *const *el = r->getStartElementType(type);
//
// int *a;
// a = checkJacobian(el, numType[type], maxDepth, method);
// numUncertain += a[0];
// numBadEl += a[1];
// numAnalysedEl += numType[type];
// delete[] a;
//
// /*for(unsigned int i = 0; i < numType[type]; i++) {
// numAnalysedEl++;
// if (checkJacobian(el[i], maxDepth) <= 0) numBadEl++;
// }*/
// }
// }
// break;
//
// case 2 :
// Msg::Info("Only 2D elements will be analyse.");
// Msg::Warning("2D elements must be in a z=cst plane ! If they aren't, results won't be correct.");
// for (GModel::fiter it = m->firstFace(); it != m->lastFace(); it++) {
// GFace *f = *it;
//
// unsigned int numType[3] = {0, 0, 0};
// f->getNumMeshElements(numType);
//
// for (int type = 0; type < 3; type++) {
// MElement *const *el = f->getStartElementType(type);
//
// int *a;
// a = checkJacobian(el, numType[type], maxDepth, method);
// numUncertain += a[0];
// numBadEl += a[1];
// numAnalysedEl += numType[type];
// delete[] a;
//
// /*for (unsigned int i = 0; i < numType[type]; i++) {
// numAnalysedEl++;
// if (checkJacobian(el[i], maxDepth) <= 0) numBadEl++;
// }*/
// }
// }
// break;
//
// case 1 :
// Msg::Info("Only 1D elements will be analyse.");
// Msg::Warning("1D elements must be on a y=cst & z=cst line ! If they aren't, results won't be correct.");
// for (GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++) {
// GEdge *e = *it;
//
// unsigned int numElement = e->getNumMeshElements();
// MElement *const *el = e->getStartElementType(0);
//
// int *a;
// a = checkJacobian(el, numElement, maxDepth, method);
// numUncertain += a[0];
// numBadEl += a[1];
// numAnalysedEl += numElement;
// delete[] a;
//
// /*for (unsigned int i = 0; i < numElement; i++) {
// numAnalysedEl++;
// if (checkJacobian(el[i], maxDepth) <= 0) numBadEl++;
// }*/
// }
// break;
//
// default :
// Msg::Error("I can't analyse any element.");
// }
//
//
// //Set all visibility of smaller dimension elements to 0
// switch (m->getDim()) {
// case 2 :
// for (GModel::fiter it = m->firstFace(); it != m->lastFace(); it++) {
// GFace *f = *it;
//
// unsigned int numType[3] = {0, 0, 0};
// f->getNumMeshElements(numType);
//
// for (int type = 0; type < 3; type++) {
// MElement *const *el = f->getStartElementType(type);
// for (unsigned int i = 0; i < numType[type]; i++) {
// el[i]->setVisibility(0);
// }
// }
// }
// case 1 :
// for (GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++) {
// GEdge *e = *it;
//
// unsigned int numElement = e->getNumMeshElements();
// MElement *const *el = e->getStartElementType(0);
//
// for (unsigned int i = 0; i < numElement; i++) {
// el[i]->setVisibility(0);
// }
// }
// break;
// }
//
// Msg::Info("%d elements have been analysed.", numAnalysedEl);
// Msg::Info("%d elements were bad.", numBadEl);
// Msg::Info("%d elements were undetermined.", numUncertain);
// Msg::Info("AnalyseCurvedMeshPlugin : Job finished.");
//
// return 0;
//}
void
GMSH_AnalyseCurvedMeshPlugin
::
checkValidity
(
int
toDo
)
void
GMSH_AnalyseCurvedMeshPlugin
::
checkValidity
(
int
toDo
)
{
{
std
::
vector
<
MElement
*>
invalids
;
std
::
vector
<
MElement
*>
invalids
;
...
@@ -590,162 +419,59 @@ void GMSH_AnalyseCurvedMeshPlugin::checkValidity(int toDo)
...
@@ -590,162 +419,59 @@ void GMSH_AnalyseCurvedMeshPlugin::checkValidity(int toDo)
}
}
}
}
void
GMSH_AnalyseCurvedMeshPlugin
::
hideValid_ShowInvalid
(
std
::
vector
<
MElement
*>
&
invalids
)
void
GMSH_AnalyseCurvedMeshPlugin
::
checkValidity
(
MElement
*
const
*
el
,
{
int
numEl
,
int
current
=
0
;
std
::
vector
<
MElement
*>
&
invalids
)
invalids
.
push_back
(
NULL
);
switch
(
_dim
)
{
case
3
:
for
(
GModel
::
riter
it
=
_m
->
firstRegion
();
it
!=
_m
->
lastRegion
();
it
++
)
{
GRegion
*
r
=
*
it
;
unsigned
int
numType
[
5
]
=
{
0
,
0
,
0
,
0
,
0
};
r
->
getNumMeshElements
(
numType
);
for
(
int
type
=
0
;
type
<
5
;
type
++
)
{
MElement
*
const
*
el
=
r
->
getStartElementType
(
type
);
for
(
int
i
=
0
;
i
<
numType
[
type
];
++
i
)
{
if
(
el
[
i
]
==
invalids
[
current
])
{
++
current
;
el
[
i
]
->
setVisibility
(
1
);
}
else
el
[
i
]
->
setVisibility
(
0
);
}
}
}
break
;
case
2
:
for
(
GModel
::
fiter
it
=
_m
->
firstFace
();
it
!=
_m
->
lastFace
();
it
++
)
{
GFace
*
f
=
*
it
;
unsigned
int
numType
[
3
]
=
{
0
,
0
,
0
};
f
->
getNumMeshElements
(
numType
);
for
(
int
type
=
0
;
type
<
3
;
type
++
)
{
MElement
*
const
*
el
=
f
->
getStartElementType
(
type
);
for
(
int
i
=
0
;
i
<
numType
[
type
];
++
i
)
{
if
(
el
[
i
]
==
invalids
[
current
])
{
++
current
;
el
[
i
]
->
setVisibility
(
1
);
}
else
el
[
i
]
->
setVisibility
(
0
);
}
}
}
break
;
case
1
:
for
(
GModel
::
eiter
it
=
_m
->
firstEdge
();
it
!=
_m
->
lastEdge
();
it
++
)
{
GEdge
*
e
=
*
it
;
unsigned
int
numElement
=
e
->
getNumMeshElements
();
MElement
*
const
*
el
=
e
->
getStartElementType
(
0
);
for
(
int
i
=
0
;
i
<
numElement
;
++
i
)
{
if
(
el
[
i
]
==
invalids
[
current
])
{
++
current
;
el
[
i
]
->
setVisibility
(
1
);
}
else
el
[
i
]
->
setVisibility
(
0
);
}
}
break
;
default
:
break
;
}
invalids
.
pop_back
();
}
void
GMSH_AnalyseCurvedMeshPlugin
::
checkValidity
(
MElement
*
const
*
el
,
int
numEl
,
std
::
vector
<
MElement
*>
&
invalids
)
{
{
if
(
numEl
<
1
)
if
(
numEl
<
1
)
return
;
return
;
const
JacobianBasis
*
jfs
=
el
[
0
]
->
getJacobianFuncSpace
(
-
1
);
const
JacobianBasis
*
jfs
=
el
[
0
]
->
getJacobianFuncSpace
(
-
1
);
if
(
!
jfs
)
{
const
JacobianBasis
*
jfs1
=
el
[
0
]
->
getJacobianFuncSpace
(
1
);
if
(
!
jfs
||
!
jfs1
)
{
Msg
::
Error
(
"Jacobian function space not implemented for type of element %d"
,
el
[
0
]
->
getNum
());
Msg
::
Error
(
"Jacobian function space not implemented for type of element %d"
,
el
[
0
]
->
getNum
());
return
;
return
;
}
}
const
bezierBasis
*
bb
=
jfs
->
bezier
;
const
bezierBasis
*
bb
=
jfs
->
bezier
;
int
numSamplingPt
=
bb
->
points
.
size1
();
int
numSamplingPt
=
bb
->
points
.
size1
();
int
dim
=
bb
->
points
.
size2
();
#ifdef _ANALYSECURVEDMESH_BLAS_
fullMatrix
<
double
>
jacobianB
(
numSamplingPt
,
numEl
);
fullMatrix
<
double
>
jacBezB
(
numSamplingPt
,
numEl
);
fullVector
<
double
>
jac1B
(
jfs1
->
bezier
->
points
.
size1
(),
numEl
);
fullVector
<
double
>
jacBez
,
jacobian
,
jac1
;
setJacobian
(
el
,
jfs
,
jacobianB
);
setJacobian
(
el
,
jfs1
,
jac1B
);
bb
->
matrixLag2Bez
.
mult
(
jacobianB
,
jacBezB
);
#else
fullVector
<
double
>
jacobian
(
numSamplingPt
);
fullVector
<
double
>
jacobian
(
numSamplingPt
);
fullVector
<
double
>
jacBez
(
numSamplingPt
);
fullVector
<
double
>
jacBez
(
numSamplingPt
);
fullVector
<
double
>
jac1
(
jfs1
->
bezier
->
points
.
size1
());
#endif
for
(
int
k
=
0
;
k
<
numEl
;
++
k
)
{
for
(
int
k
=
0
;
k
<
numEl
;
++
k
)
{
setJacobian
(
el
[
k
],
jfs
,
jacobian
);
int
i
;
#ifdef _ANALYSECURVEDMESH_BLAS_
for
(
i
=
0
;
i
<
numSamplingPt
&&
jacobian
(
i
)
>
_jacBreak
;
++
i
);
jacBez
.
setAsProxy
(
jacBezB
,
k
);
if
(
i
<
numSamplingPt
)
{
jacobian
.
setAsProxy
(
jacobianB
,
k
);
invalids
.
push_back
(
el
[
k
]);
jac1
.
setAsProxy
(
jac1B
,
k
);
++
_numInvalid
;
#else
continue
;
setJacobian
(
el
[
k
],
jfs
,
jacobian
);
}
setJacobian
(
el
[
k
],
jfs1
,
jac1
);
#endif
if
(
_maxDepth
<
1
)
{
invalids
.
push_back
(
el
[
k
]);
++
_numUncertain
;
continue
;
}
bb
->
matrixLag2Bez
.
mult
(
jacobian
,
jacBez
);
for
(
i
=
0
;
i
<
jacBez
.
size
()
&&
jacBez
(
i
)
>
_bezBreak
;
++
i
);
if
(
i
>=
jacBez
.
size
())
{
++
_numValid
;
continue
;
}
if
(
_maxDepth
<
2
)
{
invalids
.
push_back
(
el
[
k
]);
++
_numUncertain
;
continue
;
}
else
{
int
result
=
subDivision
(
bb
,
jacBez
,
_maxDepth
-
1
);
if
(
result
<
0
)
{
invalids
.
push_back
(
el
[
k
]);
++
_numInvalid
;
continue
;
}
if
(
result
>
0
)
{
++
_numValid
;
continue
;
}
invalids
.
push_back
(
el
[
k
]);
++
_numUncertain
;
continue
;
}
}
}
void
GMSH_AnalyseCurvedMeshPlugin
::
checkValidity_BLAS
(
MElement
*
const
*
el
,
int
numEl
,
std
::
vector
<
MElement
*>
&
invalids
)
{
if
(
numEl
<
1
)
return
;
const
JacobianBasis
*
jfs
=
el
[
0
]
->
getJacobianFuncSpace
(
-
1
);
// AmJ : avgJ is not the average Jac for quad, prism or hex
if
(
!
jfs
)
{
double
avgJ
=
sum
(
jac1
)
/
jac1
.
size
();
Msg
::
Error
(
"Jacobian function space not implemented for type of element %d"
,
el
[
0
]
->
getNum
());
if
(
avgJ
<
0
)
{
return
;
jacBez
.
scale
(
-
1
);
jacobian
.
scale
(
-
1
);
avgJ
*=
-
1
;
}
}
const
bezierBasis
*
bb
=
jfs
->
bezier
;
int
numSamplingPt
=
bb
->
points
.
size1
();
int
dim
=
bb
->
points
.
size2
();
fullMatrix
<
double
>
jacobian
(
numSamplingPt
,
numEl
);
fullVector
<
double
>
jacBez
(
numSamplingPt
),
proxJac
(
numSamplingPt
);
setJacobian
(
el
,
jfs
,
jacobian
);
for
(
int
k
=
0
;
k
<
numEl
;
++
k
)
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
numSamplingPt
&&
jacobian
(
i
,
k
)
>
_jacBreak
;
++
i
);
for
(
i
=
0
;
i
<
numSamplingPt
&&
jacobian
(
i
)
>
_jacBreak
*
avgJ
;
++
i
);
if
(
i
<
numSamplingPt
)
{
if
(
i
<
numSamplingPt
)
{
invalids
.
push_back
(
el
[
k
]);
invalids
.
push_back
(
el
[
k
]);
++
_numInvalid
;
++
_numInvalid
;
...
@@ -758,10 +484,11 @@ void GMSH_AnalyseCurvedMeshPlugin::
...
@@ -758,10 +484,11 @@ void GMSH_AnalyseCurvedMeshPlugin::
continue
;
continue
;
}
}
proxJac
.
setAsProxy
(
jacobian
,
k
);
#ifndef _ANALYSECURVEDMESH_BLAS_
bb
->
matrixLag2Bez
.
mult
(
proxJac
,
jacBez
);
bb
->
matrixLag2Bez
.
mult
(
jacobian
,
jacBez
);
#endif
for
(
i
=
0
;
i
<
jacBez
.
size
()
&&
jacBez
(
i
)
>
_bezBreak
;
++
i
);
for
(
i
=
0
;
i
<
jacBez
.
size
()
&&
jacBez
(
i
)
>
_bezBreak
*
avgJ
;
++
i
);
if
(
i
>=
jacBez
.
size
())
{
if
(
i
>=
jacBez
.
size
())
{
++
_numValid
;
++
_numValid
;
continue
;
continue
;
...
@@ -790,8 +517,9 @@ void GMSH_AnalyseCurvedMeshPlugin::
...
@@ -790,8 +517,9 @@ void GMSH_AnalyseCurvedMeshPlugin::
}
}
}
}
int
GMSH_AnalyseCurvedMeshPlugin
::
int
GMSH_AnalyseCurvedMeshPlugin
::
subDivision
(
const
bezierBasis
*
bb
,
subDivision
(
const
bezierBasis
*
bb
,
const
fullVector
<
double
>
&
jacobian
,
int
depth
)
const
fullVector
<
double
>
&
jacobian
,
int
depth
)
{
{
fullVector
<
double
>
newJacobian
(
bb
->
subDivisor
.
size1
());
fullVector
<
double
>
newJacobian
(
bb
->
subDivisor
.
size1
());
bb
->
subDivisor
.
mult
(
jacobian
,
newJacobian
);
bb
->
subDivisor
.
mult
(
jacobian
,
newJacobian
);
...
@@ -836,13 +564,13 @@ int GMSH_AnalyseCurvedMeshPlugin::
...
@@ -836,13 +564,13 @@ int GMSH_AnalyseCurvedMeshPlugin::
}
}
void
GMSH_AnalyseCurvedMeshPlugin
::
computeMinMax
()
void
GMSH_AnalyseCurvedMeshPlugin
::
computeMinMax
(
std
::
map
<
int
,
std
::
vector
<
double
>
>
*
data
)
{
/*
{
_numAnalysedEl
=
0
;
_numAnalysedEl
=
0
;
_numInvalid
=
0
;
_numInvalid
=
0
;
_numValid
=
0
;
_numValid
=
0
;
_numUncertain
=
0
;
_numUncertain
=
0
;
_min_Javg = .0, _max_Javg = .0;
_min_Javg
=
.0
,
_max_Javg
=
.0
,
_avg_Javg
=
.0
;
_min_pJmin
=
.0
,
_avg_pJmin
=
.0
;
_min_pJmin
=
.0
,
_avg_pJmin
=
.0
;
_min_ratioJ
=
.0
,
_avg_ratioJ
=
.0
;
_min_ratioJ
=
.0
,
_avg_ratioJ
=
.0
;
...
@@ -855,7 +583,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
...
@@ -855,7 +583,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
for
(
int
type
=
0
;
type
<
5
;
type
++
)
{
for
(
int
type
=
0
;
type
<
5
;
type
++
)
{
MElement
*
const
*
el
=
r
->
getStartElementType
(
type
);
MElement
*
const
*
el
=
r
->
getStartElementType
(
type
);
computeMinMax(el, numType[type]);
computeMinMax
(
el
,
numType
[
type
]
,
data
);
_numAnalysedEl
+=
numType
[
type
];
_numAnalysedEl
+=
numType
[
type
];
}
}
}
}
...
@@ -870,7 +598,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
...
@@ -870,7 +598,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
for
(
int
type
=
0
;
type
<
3
;
type
++
)
{
for
(
int
type
=
0
;
type
<
3
;
type
++
)
{
MElement
*
const
*
el
=
f
->
getStartElementType
(
type
);
MElement
*
const
*
el
=
f
->
getStartElementType
(
type
);
computeMinMax(el, numType[type]);
computeMinMax
(
el
,
numType
[
type
]
,
data
);
_numAnalysedEl
+=
numType
[
type
];
_numAnalysedEl
+=
numType
[
type
];
}
}
}
}
...
@@ -882,7 +610,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
...
@@ -882,7 +610,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
GEdge
*
e
=
*
it
;
GEdge
*
e
=
*
it
;
unsigned
int
numElement
=
e
->
getNumMeshElements
();
unsigned
int
numElement
=
e
->
getNumMeshElements
();
MElement
*
const
*
el
=
e
->
getStartElementType
(
0
);
MElement
*
const
*
el
=
e
->
getStartElementType
(
0
);
computeMinMax(el, numElement);
computeMinMax
(
el
,
numElement
,
data
);
_numAnalysedEl
+=
numElement
;
_numAnalysedEl
+=
numElement
;
}
}
break
;
break
;
...
@@ -891,52 +619,89 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
...
@@ -891,52 +619,89 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
Msg
::
Error
(
"I can't analyse any element."
);
Msg
::
Error
(
"I can't analyse any element."
);
return
;
return
;
}
}
Msg::Info("Extrema of J_avg : %g, %g", _min_Javg, _max_Javg);
Msg
::
Info
(
"Extrema of J_avg : %g, %g
(avg: %g)
"
,
_min_Javg
,
_max_Javg
,
_avg_Javg
/
_numAnalysedEl
);
Msg
::
Info
(
"Minimum of min(~distortion) : %g"
,
_min_pJmin
);
Msg
::
Info
(
"Minimum of min(~distortion) : %g"
,
_min_pJmin
);
Msg
::
Info
(
"Average of min(~distortion) : %g"
,
_avg_pJmin
/
_numAnalysedEl
);
Msg
::
Info
(
"Average of min(~distortion) : %g"
,
_avg_pJmin
/
_numAnalysedEl
);
Msg
::
Info
(
"Minimum of min(J) / max(J) : %g"
,
_min_ratioJ
);
Msg
::
Info
(
"Minimum of min(J) / max(J) : %g"
,
_min_ratioJ
);
Msg
::
Info
(
"Average of min(J) / max(J) : %g"
,
_avg_ratioJ
/
_numAnalysedEl
);
Msg
::
Info
(
"Average of min(J) / max(J) : %g"
,
_avg_ratioJ
/
_numAnalysedEl
);
*/
}
}
void
GMSH_AnalyseCurvedMeshPlugin
::
void
GMSH_AnalyseCurvedMeshPlugin
::
computeMinMax
(
MElement
*
const
*
el
,
int
numEl
,
std
::
map
<
int
,
std
::
vector
<
double
>
>
*
data
)
computeMinMax
(
MElement
*
const
*
el
,
int
numEl
)
{
{
/*
if
(
numEl
<
1
)
if
(
numEl
<
1
)
return
;
return
;
const
JacobianBasis
*
jfs
=
el
[
0
]
->
getJacobianFuncSpace
(
-
1
);
const
JacobianBasis
*
jfs
=
el
[
0
]
->
getJacobianFuncSpace
(
-
1
);
if (!jfs) {
const
JacobianBasis
*
jfs1
=
el
[
0
]
->
getJacobianFuncSpace
(
1
);
if
(
!
jfs
||
!
jfs1
)
{
Msg
::
Error
(
"Jacobian function space not implemented for type of element %d"
,
el
[
0
]
->
getNum
());
Msg
::
Error
(
"Jacobian function space not implemented for type of element %d"
,
el
[
0
]
->
getNum
());
return
;
return
;
}
}
const
bezierBasis
*
bb
=
jfs
->
bezier
;
const
bezierBasis
*
bb
=
jfs
->
bezier
;
int
numSamplingPt
=
bb
->
points
.
size1
();
int
numSamplingPt
=
bb
->
points
.
size1
();
int dim = bb->points.size2();
fullMatrix<double> jacobian(numSamplingPt, numEl);
#ifdef _ANALYSECURVEDMESH_BLAS_
fullMatrix<double> jacBez(numSamplingPt, numEl);
fullMatrix
<
double
>
jacobianB
(
numSamplingPt
,
numEl
);
fullVector<double> proxBez(numSamplingPt);
fullMatrix
<
double
>
jacBezB
(
numSamplingPt
,
numEl
);
setJacobian(el, jfs, jacobian);
fullVector
<
double
>
jac1B
(
jfs1
->
bezier
->
points
.
size1
(),
numEl
);
bb->matrixLag2Bez.mult(jacobian, jacBez);
fullVector
<
double
>
jacBez
,
jacobian
,
jac1
;
setJacobian
(
el
,
jfs
,
jacobianB
);
setJacobian
(
el
,
jfs1
,
jac1B
);
bb
->
matrixLag2Bez
.
mult
(
jacobianB
,
jacBezB
);
#else
fullVector
<
double
>
jacobian
(
numSamplingPt
);
fullVector
<
double
>
jacBez
(
numSamplingPt
);
fullVector
<
double
>
jac1
(
jfs1
->
bezier
->
points
.
size1
());
#endif
fullVector
<
double
>
subJacBez
(
bb
->
subDivisor
.
size1
());
_min_Javg
=
1.7e308
;
_max_Javg
=
-
1.7e308
;
_min_pJmin
=
1.7e308
;
_min_ratioJ
=
1.7e308
;
std
::
ofstream
fwrite
(
"minDisto.txt"
);
fwrite
<<
numEl
<<
"
\r
"
;
for
(
int
k
=
0
;
k
<
numEl
;
++
k
)
{
for
(
int
k
=
0
;
k
<
numEl
;
++
k
)
{
proxBez.setAsProxy(jacBez, k);
double minJ, maxJ = minJ = jacobian(0,k);
for (int i = 1; i < jacobian.size1(); ++i) {
#ifdef _ANALYSECURVEDMESH_BLAS_
if (jacobian(i,k) < minJ) minJ = jacobian(i,k);
jacBez
.
setAsProxy
(
jacBezB
,
k
);
if (jacobian(i,k) > maxJ) maxJ = jacobian(i,k);
jacobian
.
setAsProxy
(
jacobianB
,
k
);
jac1
.
setAsProxy
(
jac1B
,
k
);
#else
setJacobian
(
el
[
k
],
jfs
,
jacobian
);
setJacobian
(
el
[
k
],
jfs1
,
jac1
);
bb
->
matrixLag2Bez
.
mult
(
jacobian
,
jacBez
);
#endif
// AmJ : avgJ is not the average Jac for quad, prism or hex
double
avgJ
=
sum
(
jac1
)
/
jac1
.
size
();
if
(
avgJ
<
0
)
{
jacBez
.
scale
(
-
1
);
jacobian
.
scale
(
-
1
);
avgJ
*=
-
1
;
}
double
minJ
,
maxJ
=
minJ
=
jacobian
(
0
);
for
(
int
i
=
1
;
i
<
numSamplingPt
;
++
i
)
{
if
(
jacobian
(
i
)
<
minJ
)
minJ
=
jacobian
(
i
);
if
(
jacobian
(
i
)
>
maxJ
)
maxJ
=
jacobian
(
i
);
}
}
double minB, maxB = minB = jacBez(0
,k)
, avgJ = .0;
double
minB
,
maxB
=
minB
=
jacBez
(
0
);
//
, avgJ = .0;
for (int i = 1; i <
proxBez.size1()
; ++i) {
for
(
int
i
=
1
;
i
<
numSamplingPt
;
++
i
)
{
if (
prox
Bez(i
,k
) < minB) minB =
prox
Bez(i
,k
);
if
(
jac
Bez
(
i
)
<
minB
)
minB
=
jac
Bez
(
i
);
if (
prox
Bez(i
,k
) > maxB) maxB =
prox
Bez(i
,k
);
if
(
jac
Bez
(
i
)
>
maxB
)
maxB
=
jac
Bez
(
i
);
avgJ += jacBez(i
,k
);
//
avgJ += jacBez(i);
}
}
avgJ /= proxBez.size1();
//avgJ /= numSamplingPt;
_avg_Javg
+=
avgJ
;
_min_Javg
=
std
::
min
(
_min_Javg
,
avgJ
);
_min_Javg
=
std
::
min
(
_min_Javg
,
avgJ
);
_max_Javg
=
std
::
max
(
_max_Javg
,
avgJ
);
_max_Javg
=
std
::
max
(
_max_Javg
,
avgJ
);
...
@@ -944,452 +709,211 @@ void GMSH_AnalyseCurvedMeshPlugin::
...
@@ -944,452 +709,211 @@ void GMSH_AnalyseCurvedMeshPlugin::
(
minJ
-
minB
>
_tol
*
(
std
::
abs
(
minJ
)
+
std
::
abs
(
minB
))
/
2
||
(
minJ
-
minB
>
_tol
*
(
std
::
abs
(
minJ
)
+
std
::
abs
(
minB
))
/
2
||
maxB
-
maxJ
>
_tol
*
(
std
::
abs
(
maxJ
)
+
std
::
abs
(
maxB
))
/
2
))
{
maxB
-
maxJ
>
_tol
*
(
std
::
abs
(
maxJ
)
+
std
::
abs
(
maxB
))
/
2
))
{
BezierJacobian
*
bj
=
new
BezierJacobian
(
jacBez
,
jfs
,
0
);
std
::
set
<
BezierJacobian
*>
setBJ
;
std
::
priority_queue
<
BezierJacobian
*
,
std
::
vector
<
BezierJacobian
*>
,
lessMinB
>
pqMin
;
std
::
priority_queue
<
BezierJacobian
*
,
std
::
vector
<
BezierJacobian
*>
,
lessMaxB
>
pqMax
;
setBJ
.
insert
(
bj
);
pqMin
.
push
(
bj
);
int
currentDepth
=
0
;
int
p
=
0
;
while
(
minJ
-
minB
>
_tol
*
(
std
::
abs
(
minJ
)
+
std
::
abs
(
minB
))
/
2
&&
pqMin
.
top
()
->
depth
()
<
_maxDepth
-
1
)
{
bj
=
pqMin
.
top
();
bj
->
subDivisions
(
subJacBez
);
currentDepth
=
bj
->
depth
()
+
1
;
setBJ
.
erase
(
bj
);
pqMin
.
pop
();
delete
bj
;
for
(
int
i
=
0
;
i
<
bb
->
numDivisions
;
i
++
)
{
jacBez
.
setAsProxy
(
subJacBez
,
i
*
numSamplingPt
,
numSamplingPt
);
bj
=
new
BezierJacobian
(
jacBez
,
jfs
,
currentDepth
);
pqMin
.
push
(
bj
);
setBJ
.
insert
(
bj
);
minJ
=
std
::
min
(
minJ
,
bj
->
minJ
());
maxJ
=
std
::
max
(
maxJ
,
bj
->
maxJ
());
}
minB
=
minJ
;
maxB
=
maxJ
;
std
::
set
<
BezierJacobian
*>::
iterator
it
;
for
(
it
=
setBJ
.
begin
();
it
!=
setBJ
.
end
();
++
it
)
{
minB
=
std
::
min
(
minB
,
(
*
it
)
->
minB
());
maxB
=
std
::
max
(
maxB
,
(
*
it
)
->
maxB
());
}
}
while
(
pqMin
.
size
()
>
0
)
{
bj
=
pqMin
.
top
();
pqMin
.
pop
();
pqMax
.
push
(
bj
);
}
while
(
maxB
-
maxJ
>
_tol
*
(
std
::
abs
(
maxJ
)
+
std
::
abs
(
maxB
))
/
2
&&
pqMax
.
top
()
->
depth
()
<
_maxDepth
-
1
)
{
bj
=
pqMax
.
top
();
bj
->
subDivisions
(
subJacBez
);
currentDepth
=
bj
->
depth
()
+
1
;
setBJ
.
erase
(
bj
);
pqMax
.
pop
();
delete
bj
;
for
(
int
i
=
0
;
i
<
bb
->
numDivisions
;
i
++
)
{
jacBez
.
setAsProxy
(
subJacBez
,
i
*
numSamplingPt
,
numSamplingPt
);
bj
=
new
BezierJacobian
(
jacBez
,
jfs
,
currentDepth
);
pqMax
.
push
(
bj
);
setBJ
.
insert
(
bj
);
minJ
=
std
::
min
(
minJ
,
bj
->
minJ
());
maxJ
=
std
::
max
(
maxJ
,
bj
->
maxJ
());
}
// Set and map creation :
minB
=
minJ
;
// The set is sorted in such a way that the first key should be the
maxB
=
maxJ
;
// better to partition.
std
::
set
<
BezierJacobian
*>::
iterator
it
;
// The map keep in memory the Bezier minimum and maximum for all part of the element.
for
(
it
=
setBJ
.
begin
();
it
!=
setBJ
.
end
();
++
it
)
{
BezierJacobian *bj = new BezierJacobian(proxBez, jfs, 0);
minB
=
std
::
min
(
minB
,
(
*
it
)
->
minB
());
std::list<BezierJacobian> myset;
maxB
=
std
::
max
(
maxB
,
(
*
it
)
->
maxB
());
myset.insert(*bj);
}
std::pair<double,double> minmaxB(bj->minB(),bj->maxB());
}
std::map< int, std::pair<double,double> > map_minmaxB;
map_minmaxB.insert(std::pair< int, std::pair<double,double> >(bj->num(),minmaxB));
while
(
pqMax
.
size
()
>
0
)
{
bj
=
pqMax
.
top
();
pqMax
.
pop
();
delete
bj
;
}
}
fwrite
<<
minB
/
avgJ
<<
" "
<<
minB
/
maxB
<<
"
\r
"
;
bj->setMinMaxBounds(minLB, minUB, maxLB, maxUB);
if
(
data
)
if (min < minUB) minUB = min;
if
(
1
-
minB
<=
_tol
*
minJ
&&
maxB
-
1
<=
_tol
*
maxB
)
if (max > maxLB) maxLB = max;
(
*
data
)[
el
[
k
]
->
getNum
()].
push_back
(
1.
);
else
if
(
1
-
minB
/
avgJ
<=
1e-8
)
(
*
data
)[
el
[
k
]
->
getNum
()].
push_back
(
1.
);
else
(
*
data
)[
el
[
k
]
->
getNum
()].
push_back
(
minB
/
avgJ
);
fullVector<double> newJacBez(jfs->divisor.size1());
_min_pJmin
=
std
::
min
(
_min_pJmin
,
minB
/
avgJ
);
fullVector<double> prox(numSamplingPt);
_avg_pJmin
+=
minB
/
avgJ
;
_min_ratioJ
=
std
::
min
(
_min_ratioJ
,
minB
/
maxB
);
_avg_ratioJ
+=
minB
/
maxB
;
}
}
int currentDepth, maxDepth = 0, k = 0;
void
GMSH_AnalyseCurvedMeshPlugin
::
hideValid_ShowInvalid
(
std
::
vector
<
MElement
*>
&
invalids
)
{
unsigned
int
current
=
0
;
invalids
.
push_back
(
NULL
);
while ((minUB-minLB > tol || maxUB-maxLB > tol)) {
switch
(
_dim
)
{
// Note that it is not optimized.
case
3
:
// When one interval reach tolerance, myset is certainly
for
(
GModel
::
riter
it
=
_m
->
firstRegion
();
it
!=
_m
->
lastRegion
();
it
++
)
{
// no more the more efficiently sorted
GRegion
*
r
=
*
it
;
// (the fault of BezierJacobian.operator<(...))
unsigned
int
numType
[
5
]
=
{
0
,
0
,
0
,
0
,
0
};
std::set<BezierJacobian>::iterator it = myset.begin();
r
->
getNumMeshElements
(
numType
);
(*it).partition(newJacBez, jfs);
currentDepth = (*it).depth() + 1;
if (maxDepth < currentDepth) maxDepth = currentDepth;
map_minmaxB.erase((*it).num());
myset.erase(it);
k++;
for (int i = 0; i < jfs->numDivisions; i++) {
for
(
int
type
=
0
;
type
<
5
;
type
++
)
{
prox.setAsProxy(newJacBez, i * jacBez.size(), jacBez.size());
MElement
*
const
*
el
=
r
->
getStartElementType
(
type
);
bj = new BezierJacobian(prox, jfs, currentDepth);
for
(
int
i
=
0
;
i
<
numType
[
type
];
++
i
)
{
if (maxLB < bj->maxJ()) maxLB = bj->maxJ();
if
(
el
[
i
]
==
invalids
[
current
])
{
if (minUB > bj->minJ()) minUB = bj->minJ();
++
current
;
myset.insert(*bj);
el
[
i
]
->
setVisibility
(
1
);
minmaxB = std::make_pair(bj->minB(),bj->maxB());
}
map_minmaxB.insert(std::pair< int, std::pair<double,double> >(bj->num(),minmaxB));
else
el
[
i
]
->
setVisibility
(
0
);
}
}
}
}
break
;
// Deletion of obsolet BezierJacobian
case
2
:
it = myset.begin();
for
(
GModel
::
fiter
it
=
_m
->
firstFace
();
it
!=
_m
->
lastFace
();
it
++
)
{
if ((*it).isObsolet(maxLB, minUB, tol))
GFace
*
f
=
*
it
;
myset.erase(it++);
unsigned
int
numType
[
3
]
=
{
0
,
0
,
0
};
else ++it;
f
->
getNumMeshElements
(
numType
);
while (it != myset.end()) {
if ((*it).isObsolet(maxLB, minUB, tol))
for
(
int
type
=
0
;
type
<
3
;
type
++
)
{
myset.erase(it++);
MElement
*
const
*
el
=
f
->
getStartElementType
(
type
);
for
(
int
i
=
0
;
i
<
numType
[
type
];
++
i
)
{
if
(
el
[
i
]
==
invalids
[
current
])
{
++
current
;
el
[
i
]
->
setVisibility
(
1
);
}
else
else
++it;
el
[
i
]
->
setVisibility
(
0
);
}
}
}
}
break
;
// Update of Bezier bounds
case
1
:
minLB = minUB;
for
(
GModel
::
eiter
it
=
_m
->
firstEdge
();
it
!=
_m
->
lastEdge
();
it
++
)
{
maxUB = maxLB;
GEdge
*
e
=
*
it
;
std::map< int, std::pair<double,double> >::iterator mit;
unsigned
int
numElement
=
e
->
getNumMeshElements
();
for (mit = map_minmaxB.begin(); mit != map_minmaxB.end(); mit++) {
MElement
*
const
*
el
=
e
->
getStartElementType
(
0
);
if (minLB > mit->second.first) minLB = mit->second.first;
for
(
int
i
=
0
;
i
<
numElement
;
++
i
)
{
if (maxUB < mit->second.second) maxUB = mit->second.second;
if
(
el
[
i
]
==
invalids
[
current
])
{
++
current
;
el
[
i
]
->
setVisibility
(
1
);
}
else
el
[
i
]
->
setVisibility
(
0
);
}
}
}
}
break
;
double *a = new double[6];
default
:
a[0] = minLB, a[1] = minUB, a[2] = maxLB, a[3] = maxUB;
break
;
a[4] = (double)k; a[5] = (double)maxDepth;
}
return a;
invalids
.
pop_back
();
switch
(
_dim
)
{
case
3
:
for
(
GModel
::
fiter
it
=
_m
->
firstFace
();
it
!=
_m
->
lastFace
();
it
++
)
(
*
it
)
->
setVisibility
(
0
);
case
2
:
for
(
GModel
::
eiter
it
=
_m
->
firstEdge
();
it
!=
_m
->
lastEdge
();
it
++
)
(
*
it
)
->
setVisibility
(
0
);
case
1
:
for
(
GModel
::
viter
it
=
_m
->
firstVertex
();
it
!=
_m
->
lastVertex
();
it
++
)
(
*
it
)
->
setVisibility
(
0
);
default
:
break
;
}
}
BezierJacobian
::
BezierJacobian
(
fullVector
<
double
>
&
v
,
const
JacobianBasis
*
jfs
,
int
depth
)
{
_jacBez
=
v
;
_depthSub
=
depth
;
_jfs
=
jfs
;
_minJ
=
_maxJ
=
v
(
0
);
int
i
=
1
;
for
(;
i
<
jfs
->
bezier
->
numLagPts
;
i
++
)
{
if
(
_minJ
>
v
(
i
))
_minJ
=
v
(
i
);
if
(
_maxJ
<
v
(
i
))
_maxJ
=
v
(
i
);
}
_minB
=
_minJ
;
_maxB
=
_maxJ
;
for
(;
i
<
v
.
size
();
i
++
)
{
if
(
_minB
>
v
(
i
))
_minB
=
v
(
i
);
if
(
_maxB
<
v
(
i
))
_maxB
=
v
(
i
);
}
}
bool
lessMinB
::
operator
()(
BezierJacobian
*
bj1
,
BezierJacobian
*
bj2
)
const
{
return
bj1
->
minB
()
>
bj2
->
minB
();
}
}
_min_pJmin = std::min(_min_pJmin, (minJ+minB)/2);
bool
lessMaxB
::
operator
()(
BezierJacobian
*
bj1
,
BezierJacobian
*
bj2
)
const
_avg_pJmin += (minJ+minB)/2;
{
_min_ratioJ = std::min(_min_ratioJ, (minJ+minB)/(maxB+maxJ));
return
bj1
->
maxB
()
<
bj2
->
maxB
();
_avg_ratioJ += (minJ+minB)/(maxB+maxJ);
}
}
*/
}
//int *GMSH_AnalyseCurvedMeshPlugin::checkJacobian
//(MElement *const *el, int numEl, int maxDepth, int method)
//{
// int *a = new int[2];
// a[0] = a[1] = 0;
// if (numEl <= 0) return a;
//
// switch (method) {
//
// case 1 :
// for (int i = 0; i < numEl; i++) {
// int tag = method_1_2(el[i], maxDepth);
// if (tag < 0) {
// a[1]++;
// if (tag < -1)
// Msg::Info("Bad element : %d (with tag %d)", el[i]->getNum(), tag);
// else
// Msg::Info("Bad element : %d", el[i]->getNum());
// }
// else if (tag > 0) {
// el[i]->setVisibility(0);
// if (tag > 1)
// Msg::Info("Good element : %d (with tag %d)", el[i]->getNum(), tag);
// }
// else {
// a[0]++;
// Msg::Info("Element %d may be bad", el[i]->getNum());
// }
// }
// return a;
//
// case 2 :
// std::vector<int> tag(numEl, UNDEF_JAC_TAG);
// method_2_2(el, tag, maxDepth);
//
// Msg::Info(" ");
// Msg::Info("Bad elements :");
// for (unsigned int i = 0; i < tag.size(); i++) {
// if (tag[i] < 0) {
// if (tag[i] < -1)
// Msg::Info("%d (with tag %d)", el[i]->getNum(), tag[i]);
// else
// Msg::Info("%d", el[i]->getNum());
// a[1]++;
// }
// }
//
// Msg::Info(" ");
// Msg::Info("Uncertain elements :");
// for (unsigned int i = 0; i < tag.size(); i++) {
// if (tag[i] == 0) {
// Msg::Info("%d", el[i]->getNum());
// a[0]++;
// }
// }
//
// Msg::Info(" ");
// return a;
// }
//}
//
//
//int GMSH_AnalyseCurvedMeshPlugin::method_1_1(MElement *el, int depth)
//{
// const polynomialBasis *fs = el->getFunctionSpace(-1);
// if (!fs) {
// Msg::Error("Function space not implemented for type of element %d", el->getNum());
// return 0;
// }
// const JacobianBasis *jfs = el->getJacobianFuncSpace(-1);
// if (!jfs) {
// Msg::Error("Jacobian function space not implemented for type of element %d", el->getNum());
// return 0;
// }
// const bezierBasis *bb = jfs->bezier;
//
// int numSamplingPt = bb->points.size1();
// int dim = bb->points.size2();
// fullVector<double> jacobian(numSamplingPt);
//
// for (int i = 0; i < numSamplingPt; i++) {
// double gsf[256][3];
// switch (dim) {
// case 1 :
// fs->df(bb->points(i,0),0,0, gsf);
// break;
// case 2 :
// fs->df(bb->points(i,0),bb->points(i,1),0, gsf);
// break;
// case 3 :
// fs->df(bb->points(i,0),bb->points(i,1),bb->points(i,2), gsf);
// break;
// default :
// Msg::Error("Can't get the gradient for %dD elements.", dim);
// return false;
// }
// double jac[3][3];
// jacobian(i) = getJacobian(gsf, jac, el);
// }
//
// for (int i = 0; i < jacobian.size(); i++) {
// if (jacobian(i) <= 0.) return -1;
// }
//
//
// fullVector<double> jacBez(jacobian.size());
// bb->matrixLag2Bez.mult(jacobian, jacBez);
//
// bool allPtPositive = true;
// for (int i = 0; i < jacBez.size(); i++) {
// if (jacBez(i) <= 0.) allPtPositive = false;
// }
// if (allPtPositive) return 1;
//
//
// if (depth <= 1) {
// return 0;
// }
// else{
// int tag = division(bb, jacBez, depth-1);
// if (tag < 0)
// return tag - 1;
// if (tag > 0)
// return tag + 1;
// return tag;
// }
//}
//
//
//int GMSH_AnalyseCurvedMeshPlugin::method_1_2(MElement *el, int depth)
//{
// const polynomialBasis *fs = el->getFunctionSpace(-1);
// if (!fs) {
// Msg::Error("Function space not implemented for type of element %d", el->getNum());
// return 0;
// }
// const JacobianBasis *jfs = el->getJacobianFuncSpace(-1);
// if (!jfs) {
// Msg::Error("Jacobian function space not implemented for type of element %d", el->getNum());
// return 0;
// }
// const bezierBasis *bb = jfs->bezier;
//
// int numSamplingPt = bb->points.size1();
// int dim = bb->points.size2();
// fullVector<double> jacobian(numSamplingPt);
//
//
// setJacobian(el, jfs, jacobian);
//
// {
// Msg::Info("Printing vector jac[%d]", el->getNum());
// Msg::Info(" ");
// for(int I = 0; I < jacobian.size(); I++){
// Msg::Info("%lf ", jacobian(I));
// }
// Msg::Info(" ");
// }
//
// for (int i = 0; i < jacobian.size(); i++) {
// if (jacobian(i) <= 0.) return -1;
// }
//
//
// fullVector<double> jacBez(jacobian.size());
// bb->matrixLag2Bez.mult(jacobian, jacBez);
//
// bool allPtPositive = true;
// for (int i = 0; i < jacBez.size(); i++) {
// if (jacBez(i) <= 0.) allPtPositive = false;
// }
// if (allPtPositive) return 1;
//
//
// if (depth <= 1) {
// return 0;
// }
// else{
// int tag = division(bb, jacBez, depth-1);
// if (tag < 0)
// return tag - 1;
// if (tag > 0)
// return tag + 1;
// return tag;
// }
//}
//
//
//void GMSH_AnalyseCurvedMeshPlugin::method_2_2
// (MElement *const *el, std::vector<int> &tags, int depth)
//{
// const polynomialBasis *fs = el[0]->getFunctionSpace(-1);
// if (!fs) {
// Msg::Error("Function space not implemented for type of element %d", el[0]->getNum());
// return;
// }
// const JacobianBasis *jfs = el[0]->getJacobianFuncSpace(-1);
// if (!jfs) {
// Msg::Error("Jacobian function space not implemented for type of element %d", el[0]->getNum());
// return;
// }
// const bezierBasis *bb = jfs->bezier;
//
// int numSamplingPt = bb->points.size1();
// int dim = bb->points.size2();
// int numEl = tags.size();
//
// fullMatrix<double> jacobian(numSamplingPt, numEl);
// setJacobian(el, jfs, jacobian);
//
//
// int numBad = 0;
//
// for (int i = 0; i < numEl; i++) {
// bool isBad = false;
// for (int j = 0; j < jacobian.size1(); j++) {
// if (jacobian(j,i) <= 0.) isBad = true;
// }
// if (isBad) {
// tags[i] = -1;
// numBad++;
// }
// }
//
//
// fullMatrix<double> jacBez;
// std::vector<int> correspondingEl;
//
// double critere = .2; // dfinir suivant le temps de chaque opration
// if ((double) numBad / (double) numEl < critere) {// il vaut mieux calculer les points de controle de chaque lment
// jacBez.resize(numSamplingPt, numEl);
// bb->matrixLag2Bez.mult(jacobian, jacBez);
// correspondingEl.resize(numEl);
// for (int i = 0; i < numEl; i++) correspondingEl[i] = i;
// }
// else {// il vaut mieux ne calculer que les points de controle des lments encore incertains
// fullMatrix<double> newJac(numSamplingPt, numEl-numBad);
// fullMatrix<double> prox1(numSamplingPt,1);
// fullMatrix<double> prox2(numSamplingPt,1);
// int index = 0;
// correspondingEl.resize(numEl - numBad);
// for (int i = 0; i < numEl; i++) {
// if (tags[i] == UNDEF_JAC_TAG) {
// correspondingEl[index] = i;
// prox1.setAsProxy(newJac,index,1);
// prox2.setAsProxy(jacobian,i,1);
// prox1.copy(prox2);
// }
// }
// jacBez.resize(numSamplingPt, numEl-numBad);
// bb->matrixLag2Bez.mult(jacobian, jacBez);
// }
//
//
// int numGood = 0;
//
// for (int i = 0; i < jacBez.size2(); i++) {
// bool allPtPositive = true;
// for (int j = 0; j < jacBez.size1(); j++) {
// if (jacBez(j,i) <= 0.) allPtPositive = false;
// }
// if (allPtPositive) {
// tags[correspondingEl[i]] = 1;
// numGood++;
// }
// }
//
//
// Msg::Warning("Not yet implemented for maxDepth > 1");
// depth = 1;
// if (depth <= 1) {
// for (int i = 0; i < jacBez.size2(); i++)
// if (tags[correspondingEl[i]] == UNDEF_JAC_TAG)
// tags[correspondingEl[i]] = 0;
// return;
// }
// /*else{
// int tag = division(jfs, jacBez, depth-1);
// if (tag < 0)
// return tag - 1;
// if (tag > 0)
// return tag + 1;
// return tag;
// }*/
//
//}
//
//int GMSH_AnalyseCurvedMeshPlugin::division
// (const bezierBasis *jfs, const fullVector<double> &jacobian, int depth)
//{
// if (jfs->subDivisor.size2() != jacobian.size()) {
// Msg::Error("Wrong sizes in division : [%d,%d] * [%d]",
// jfs->subDivisor.size1(), jfs->subDivisor.size2(), jacobian.size());
// Msg::Info(" ");
// return 0;
// }
//
// fullVector<double> newJacobian(jfs->subDivisor.size1());
// jfs->subDivisor.mult(jacobian, newJacobian);
//
// for (int i = 0; i < jfs->numDivisions; i++) {
// for (int j = 0; j < jfs->numLagPts; j++)
// if (newJacobian(i * jfs->points.size1() + j) <= 0.) return -1;
// }
//
// bool allPtPositive = true;
// for (int i = 0; i < newJacobian.size(); i++) {
// if (newJacobian(i) <= 0.) allPtPositive = false;
// }
// if (allPtPositive) return 1;
//
//
// We don't know if the jacobian is positif everywhere or not
// We subdivide if we still can do it (if depth > 0).
// if (depth <= 0) {
// return 0;
// }
// else{
// fullVector<double> subJacobian;
// std::vector<int> negTag, posTag;
// bool zeroTag = false;
//
// for (int i = 0; i < jfs->numDivisions; i++)
// {
// subJacobian.setAsProxy(newJacobian, i * jacobian.size(), jacobian.size());
// int tag = division(jfs, subJacobian, depth-1);
//
// if (tag < 0)
// negTag.push_back(tag);
// else if (tag > 0)
// posTag.push_back(tag);
// else
// zeroTag = true;
// }
//
// if (negTag.size() > 0) return max(negTag) - 1;
//
// if (zeroTag) return 0;
//
// return max(posTag) - 1;
// }
//}
//
//
//
//
/*{
Msg::Info("Printing matrix %s :", "nodesX");
int ni = nodesX.size1();
int nj = nodesX.size2();
for(int I = 0; I < ni; I++){
Msg::Info(" ");
for(int J = 0; J < nj; J++){
Msg::Info("%lf ", nodesX(I, J));
}
}
Msg::Info(" ");
}*/
This diff is collapsed.
Click to expand it.
Plugin/AnalyseCurvedMesh.h
+
24
−
40
View file @
1c3186a9
...
@@ -25,16 +25,14 @@ class GMSH_AnalyseCurvedMeshPlugin : public GMSH_PostPlugin
...
@@ -25,16 +25,14 @@ class GMSH_AnalyseCurvedMeshPlugin : public GMSH_PostPlugin
int
_numAnalysedEl
;
int
_numAnalysedEl
;
int
_numInvalid
,
_numValid
,
_numUncertain
;
int
_numInvalid
,
_numValid
,
_numUncertain
;
double
_min_Javg
,
_max_Javg
;
double
_min_Javg
,
_max_Javg
,
_avg_Javg
;
double
_min_pJmin
,
_avg_pJmin
;
double
_min_pJmin
,
_avg_pJmin
;
double
_min_ratioJ
,
_avg_ratioJ
;
double
_min_ratioJ
,
_avg_ratioJ
;
//
public
:
public
:
GMSH_AnalyseCurvedMeshPlugin
(){}
GMSH_AnalyseCurvedMeshPlugin
(){}
std
::
string
getName
()
const
{
return
"AnalyseCurvedMesh"
;
}
std
::
string
getName
()
const
{
return
"AnalyseCurvedMesh"
;
}
std
::
string
getShortHelp
()
const
std
::
string
getShortHelp
()
const
{
{
return
"Check validity of elements and/or compute min&max of the jacobian"
;
return
"Check validity of elements and/or compute min&max of the jacobian"
;
}
}
std
::
string
getHelp
()
const
;
std
::
string
getHelp
()
const
;
...
@@ -43,25 +41,24 @@ class GMSH_AnalyseCurvedMeshPlugin : public GMSH_PostPlugin
...
@@ -43,25 +41,24 @@ class GMSH_AnalyseCurvedMeshPlugin : public GMSH_PostPlugin
StringXNumber
*
getOption
(
int
);
StringXNumber
*
getOption
(
int
);
PView
*
execute
(
PView
*
);
PView
*
execute
(
PView
*
);
void
checkValidity
(
MElement
*
const
*
,
int
numEl
,
std
::
vector
<
MElement
*>
&
invalids
);
void
checkValidity
(
MElement
*
const
*
,
int
numEl
,
std
::
vector
<
MElement
*>
&
invalids
);
void
checkValidity_BLAS
(
MElement
*
const
*
,
int
numEl
,
std
::
vector
<
MElement
*>
&
invalids
);
//void storeJMin(MElement *const *, int numEl, std::map<int, std::vector<double> > &data);
private
:
private
:
void
checkValidity
(
int
toDo
);
void
checkValidity
(
int
toDo
);
void
computeMinMax
();
void
computeMinMax
(
std
::
map
<
int
,
std
::
vector
<
double
>
>
*
data
=
0
);
void
computeMinMax
(
MElement
*
const
*
,
int
numEl
);
void
computeMinMax
(
MElement
*
const
*
,
int
numEl
,
std
::
map
<
int
,
std
::
vector
<
double
>
>
*
data
=
0
);
void
hideValid_ShowInvalid
(
std
::
vector
<
MElement
*>
&
invalids
);
int
subDivision
(
const
bezierBasis
*
,
const
fullVector
<
double
>&
,
int
depth
);
int
subDivision
(
const
bezierBasis
*
,
const
fullVector
<
double
>&
,
int
depth
);
/*bool isJacPositive(MElement *);
void
hideValid_ShowInvalid
(
std
::
vector
<
MElement
*>
&
invalids
);
int method_1_1(MElement *, int depth);
};
int method_1_2(MElement *, int depth);
int method_1_3(MElement *, int depth);
class
BezierJacobian
;
void method_2_2(MElement *const *, std::vector<int> &tags, int depth);
struct
lessMinB
{
void method_2_3(MElement *const *, std::vector<int> &tags, int depth);
bool
operator
()(
BezierJacobian
*
,
BezierJacobian
*
)
const
;
//int checkJacobian(MElement *, int depth);
};
//int *checkJacobian2(MElement *const *, int numEl, int depth);
struct
lessMaxB
{
int *checkJacobian(MElement *const *, int numEl, int depth, int method);
bool
operator
()(
BezierJacobian
*
,
BezierJacobian
*
)
const
;
int division(const bezierBasis *, const fullVector<double> &, int depth);
*/
};
};
class
BezierJacobian
class
BezierJacobian
...
@@ -70,31 +67,18 @@ private:
...
@@ -70,31 +67,18 @@ private:
fullVector
<
double
>
_jacBez
;
fullVector
<
double
>
_jacBez
;
double
_minJ
,
_maxJ
,
_minB
,
_maxB
;
//Extremum of Jac at corners and of bezier values
double
_minJ
,
_maxJ
,
_minB
,
_maxB
;
//Extremum of Jac at corners and of bezier values
int
_depthSub
;
int
_depthSub
;
int
_num
;
// Used for map of minmaxB
const
JacobianBasis
*
_jfs
;
static
int
_globalNum
;
public:
public:
BezierJacobian
(
fullVector
<
double
>
&
,
const
JacobianBasis
*
,
int
depth
);
BezierJacobian
(
fullVector
<
double
>
&
,
const
JacobianBasis
*
,
int
depth
);
inline
bool
operator
<
(
const
BezierJacobian
&
other
)
const
void
subDivisions
(
fullVector
<
double
>
&
vect
)
const
{
return
other
.
_maxB
-
_maxB
-
other
.
_minB
+
_minB
<
0
;}
{
_jfs
->
bezier
->
subDivisor
.
mult
(
_jacBez
,
vect
);}
void
partition
(
fullVector
<
double
>
&
,
const
JacobianBasis
*
)
const
;
inline
bool
isObsolet
(
double
maxLB
,
double
minUB
,
double
tol
)
const
{
return
_maxB
-
maxLB
<
tol
&&
minUB
-
_minB
<
tol
;}
int
num
()
const
{
return
_num
;}
int
depth
()
const
{
return
_depthSub
;}
double
minJ
()
const
{
return
_minJ
;}
double
minB
()
const
{
return
_minB
;}
double
maxJ
()
const
{
return
_maxJ
;}
double
maxB
()
const
{
return
_maxB
;}
double
setMinMaxBounds
(
double
&
minLB
,
double
&
minUB
,
double
&
maxLB
,
double
&
maxUB
)
const
{
/*
Msg
::
Info
(
"setminmax : %g = %g - %g"
,
_minJ
-
_minB
,
_minJ
,
_minB
);
Msg
::
Info
(
"setminmax : %g = %g - %g"
,
_maxB
-
_maxJ
,
_maxB
,
_maxJ
);
Msg
::
Info
(
" "
);
int
g
;
inline
int
depth
()
const
{
return
_depthSub
;}
std
::
cin
>>
g
;
*/
inline
double
minJ
()
const
{
return
_minJ
;}
minUB
=
_minJ
;
minLB
=
_minB
;
maxUB
=
_maxB
;
maxLB
=
_maxJ
;}
inline
double
maxJ
()
const
{
return
_maxJ
;}
inline
double
minB
()
const
{
return
_minB
;}
inline
double
maxB
()
const
{
return
_maxB
;}
};
};
#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