Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Aland, Sebastian
amdis
Commits
5de011fb
Commit
5de011fb
authored
Dec 21, 2010
by
Praetorius, Simon
Browse files
RecoveryEstimator modified to have a structure similar to ResidualEstimator
parent
04249ebf
Changes
4
Hide whitespace changes
Inline
Side-by-side
AMDiS/src/ProblemVec.cc
View file @
5de011fb
...
@@ -772,12 +772,12 @@ namespace AMDiS {
...
@@ -772,12 +772,12 @@ namespace AMDiS {
assembleFlag
);
assembleFlag
);
}
}
if
(
asmMatrix
)
{
//
if (asmMatrix) {
solverMatrix
.
setMatrix
(
*
systemMatrix
);
solverMatrix
.
setMatrix
(
*
systemMatrix
);
createPrecon
();
createPrecon
();
INFO
(
info
,
8
)(
"fillin of assembled matrix: %d
\n
"
,
nnz
);
INFO
(
info
,
8
)(
"fillin of assembled matrix: %d
\n
"
,
nnz
);
}
//
}
#ifdef _OPENMP
#ifdef _OPENMP
INFO
(
info
,
8
)(
"buildAfterCoarsen needed %.5f seconds system time / %.5f seconds wallclock time
\n
"
,
INFO
(
info
,
8
)(
"buildAfterCoarsen needed %.5f seconds system time / %.5f seconds wallclock time
\n
"
,
...
...
AMDiS/src/RecoveryEstimator.cc
View file @
5de011fb
...
@@ -15,12 +15,13 @@
...
@@ -15,12 +15,13 @@
namespace
AMDiS
{
namespace
AMDiS
{
RecoveryEstimator
::
RecoveryEstimator
(
std
::
string
name
,
DOFVector
<
double
>
*
uh
,
int
r
)
RecoveryEstimator
::
RecoveryEstimator
(
std
::
string
name
,
DOFVector
<
double
>
*
uh
_
,
int
r
)
:
Estimator
(
name
,
r
),
:
Estimator
(
name
,
r
),
uh
_
(
uh
),
uh
(
uh
_
),
relative
_
(
0
),
relative
(
0
),
C
(
1.0
),
C
(
1.0
),
method
(
0
),
method
(
0
),
addEstimationToOld
(
false
),
feSpace
(
NULL
),
feSpace
(
NULL
),
f_vec
(
NULL
),
f_vec
(
NULL
),
f_scal
(
NULL
),
f_scal
(
NULL
),
...
@@ -29,14 +30,14 @@ namespace AMDiS {
...
@@ -29,14 +30,14 @@ namespace AMDiS {
{
{
FUNCNAME
(
"RecoveryEstimator::constructor()"
);
FUNCNAME
(
"RecoveryEstimator::constructor()"
);
GET_PARAMETER
(
0
,
name
+
"->rec method"
,
"%d"
,
&
method
);
GET_PARAMETER
(
0
,
name
+
"->rec method"
,
"%d"
,
&
method
);
// 0, 1, or 2 (see Recovery.h)
GET_PARAMETER
(
0
,
name
+
"->rel error"
,
"%d"
,
&
relative
_
);
GET_PARAMETER
(
0
,
name
+
"->rel error"
,
"%d"
,
&
relative
);
// 0 or 1
GET_PARAMETER
(
0
,
name
+
"->C"
,
"%f"
,
&
C
);
GET_PARAMETER
(
0
,
name
+
"->C"
,
"%f"
,
&
C
);
C
=
C
>
1e-25
?
sqr
(
C
)
:
1.0
;
C
=
C
>
1e-25
?
sqr
(
C
)
:
1.0
;
if
(
norm
==
H1_NORM
)
{
if
(
norm
==
H1_NORM
)
{
feSpace
=
uh
->
getFeSpace
();
feSpace
=
uh
_
->
getFeSpace
();
degree
=
feSpace
->
getBasisFcts
()
->
getDegree
();
degree
=
feSpace
->
getBasisFcts
()
->
getDegree
();
if
(
degree
<=
2
&&
C
!=
1.0
)
{
if
(
degree
<=
2
&&
C
!=
1.0
)
{
...
@@ -44,10 +45,10 @@ namespace AMDiS {
...
@@ -44,10 +45,10 @@ namespace AMDiS {
WAIT
;
WAIT
;
}
}
}
else
{
}
else
{
degree
=
uh
->
getFeSpace
()
->
getBasisFcts
()
->
getDegree
()
+
1
;
degree
=
uh
_
->
getFeSpace
()
->
getBasisFcts
()
->
getDegree
()
+
1
;
feSpace
=
FiniteElemSpace
::
provideFeSpace
(
NULL
,
feSpace
=
FiniteElemSpace
::
provideFeSpace
(
NULL
,
Lagrange
::
getLagrange
(
uh
->
getFeSpace
()
->
getMesh
()
->
getDim
(),
degree
),
Lagrange
::
getLagrange
(
uh
_
->
getFeSpace
()
->
getMesh
()
->
getDim
(),
degree
),
uh
->
getFeSpace
()
->
getMesh
(),
uh
_
->
getFeSpace
()
->
getMesh
(),
name
+
"->feSpace"
);
name
+
"->feSpace"
);
if
(
method
==
2
)
{
if
(
method
==
2
)
{
...
@@ -66,72 +67,114 @@ namespace AMDiS {
...
@@ -66,72 +67,114 @@ namespace AMDiS {
rec_struct
=
new
Recovery
(
norm
,
method
);
rec_struct
=
new
Recovery
(
norm
,
method
);
}
}
void
RecoveryEstimator
::
init
(
double
ts
)
double
RecoveryEstimator
::
estimate
(
double
timestep
)
{
{
FUNCNAME
(
"RecoveryEstimator::estimate()"
);
FUNCNAME
(
"RecoveryEstimator::init()"
);
const
BasisFunction
*
basFcts
=
uh_
->
getFeSpace
()
->
getBasisFcts
();
basFcts
=
uh
->
getFeSpace
()
->
getBasisFcts
();
Mesh
*
mesh
=
uh_
->
getFeSpace
()
->
getMesh
();
int
dim
=
mesh
->
getDim
();
int
dim
=
mesh
->
getDim
();
int
dow
=
Global
::
getGeo
(
WORLD
);
h1Norm2
=
0.0
;
double
h1Norm2
=
0.0
;
if
(
norm
==
H1_NORM
)
{
// sets recovery gradient.
if
(
norm
==
H1_NORM
)
{
// sets recovery gradient.
if
(
method
==
2
)
if
(
method
==
2
)
rec_grd
=
rec_struct
->
recovery
(
uh
_
,
f_vec
,
f_scal
,
aux_vec
);
rec_grd
=
rec_struct
->
recovery
(
uh
,
f_vec
,
f_scal
,
aux_vec
);
else
else
rec_grd
=
rec_struct
->
recovery
(
uh
_
,
feSpace
,
f_vec
,
f_scal
,
aux_vec
);
rec_grd
=
rec_struct
->
recovery
(
uh
,
feSpace
,
f_vec
,
f_scal
,
aux_vec
);
rec_basFcts
=
rec_grd
->
getFeSpace
()
->
getBasisFcts
();
rec_basFcts
=
rec_grd
->
getFeSpace
()
->
getBasisFcts
();
}
else
{
// sets higher-order recovery solution.
}
else
{
// sets higher-order recovery solution.
rec_uh
=
rec_struct
->
recoveryUh
(
uh
_
,
feSpace
);
rec_uh
=
rec_struct
->
recoveryUh
(
uh
,
feSpace
);
rec_basFcts
=
rec_uh
->
getFeSpace
()
->
getBasisFcts
();
rec_basFcts
=
rec_uh
->
getFeSpace
()
->
getBasisFcts
();
}
}
int
deg
=
2
*
std
::
max
(
basFcts
->
getDegree
(),
rec_basFcts
->
getDegree
());
int
deg
=
2
*
std
::
max
(
basFcts
->
getDegree
(),
rec_basFcts
->
getDegree
());
Quadrature
*
quad
=
Quadrature
::
provideQuadrature
(
dim
,
deg
);
quad
=
Quadrature
::
provideQuadrature
(
dim
,
deg
);
int
nPoints
=
quad
->
getNumPoints
();
nPoints
=
quad
->
getNumPoints
();
WorldVector
<
double
>
quad_pt
;
//
WorldVector<double> quad_pt;
WorldVector
<
double
>
*
grdAtQP
=
new
WorldVector
<
double
>
[
nPoints
];
grdAtQP
=
new
WorldVector
<
double
>
[
nPoints
];
mtl
::
dense_vector
<
WorldVector
<
double
>
>
recoveryGrdAtQP
(
nPoints
);
recoveryGrdAtQP
=
mtl
::
dense_vector
<
WorldVector
<
double
>
>
(
nPoints
);
mtl
::
dense_vector
<
double
>
uhAtQP
(
nPoints
),
recoveryUhAtQP
(
nPoints
);
uhAtQP
=
mtl
::
dense_vector
<
double
>
(
nPoints
);
recoveryUhAtQP
=
mtl
::
dense_vector
<
double
>
(
nPoints
);
FastQuadrature
*
quadFast
=
FastQuadrature
::
provideFastQuadrature
(
basFcts
,
*
quad
,
INIT_PHI
|
INIT_GRD_PHI
);
FastQuadrature
*
rec_quadFast
=
FastQuadrature
::
provideFastQuadrature
(
rec_basFcts
,
*
quad
,
INIT_PHI
|
INIT_GRD_PHI
);
quadFast
=
FastQuadrature
::
provideFastQuadrature
(
basFcts
,
*
quad
,
INIT_PHI
|
INIT_GRD_PHI
);
rec_quadFast
=
FastQuadrature
::
provideFastQuadrature
(
rec_basFcts
,
*
quad
,
INIT_PHI
|
INIT_GRD_PHI
);
// clear error indicators
// clear error indicators
if
(
!
addEstimationToOld
)
{
TraverseStack
stack
;
TraverseStack
stack
;
ElInfo
*
elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
ElInfo
*
elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
while
(
elInfo
)
{
while
(
elInfo
)
{
elInfo
->
getElement
()
->
setEstimation
(
0.0
,
row
);
elInfo
->
getElement
()
->
setEstimation
(
0.0
,
row
);
elInfo
=
stack
.
traverseNext
(
elInfo
);
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
}
}
est_sum
=
0.0
;
est_max
=
0.0
;
est_t_sum
=
0.0
;
est_t_max
=
0.0
;
traverseFlag
=
Mesh
::
CALL_LEAF_EL
|
Mesh
::
FILL_COORDS
|
Mesh
::
FILL_DET
|
Mesh
::
FILL_GRD_LAMBDA
;
}
void
RecoveryEstimator
::
exit
(
bool
output
)
{
FUNCNAME
(
"RecoveryEstimator::exit()"
);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double
send_est_sum
=
est_sum
;
double
send_est_max
=
est_max
;
// traverse mesh
MPI
::
COMM_WORLD
.
Allreduce
(
&
send_est_sum
,
&
est_sum
,
1
,
MPI_DOUBLE
,
MPI_SUM
);
est_sum
=
est_max
=
est_t_sum
=
0.0
;
MPI
::
COMM_WORLD
.
Allreduce
(
&
send_est_max
,
&
est_max
,
1
,
MPI_DOUBLE
,
MPI_MAX
);
#endif
// Computing relative errors
if
(
relative
)
{
TraverseStack
stack
;
ElInfo
*
elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
while
(
elInfo
)
{
double
estEl
=
elInfo
->
getElement
()
->
getEstimation
(
row
);
estEl
/=
h1Norm2
;
elInfo
->
getElement
()
->
setEstimation
(
estEl
,
row
);
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
est_max
/=
h1Norm2
;
est_sum
/=
h1Norm2
;
}
est_sum
=
sqrt
(
est_sum
);
delete
[]
grdAtQP
;
elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
if
(
output
)
{
Mesh
::
CALL_LEAF_EL
|
Mesh
::
FILL_COORDS
|
MSG
(
"estimate for component %d = %.8e
\n
"
,
row
,
est_sum
);
Mesh
::
FILL_DET
|
Mesh
::
FILL_GRD_LAMBDA
);
}
while
(
elInfo
)
{
}
void
RecoveryEstimator
::
estimateElement
(
ElInfo
*
elInfo
,
DualElInfo
*
dualElInfo
)
{
FUNCNAME
(
"RecoveryEstimator::estimateElement()"
);
Element
*
el
=
elInfo
->
getElement
();
Element
*
el
=
elInfo
->
getElement
();
double
det
=
elInfo
->
getDet
();
double
det
=
elInfo
->
getDet
();
double
errEl
=
0.0
;
double
errEl
=
0.0
;
double
estEl
=
el
->
getEstimation
(
row
);
int
dow
=
Global
::
getGeo
(
WORLD
);
if
(
norm
==
H1_NORM
)
{
if
(
norm
==
H1_NORM
)
{
// get gradient and recovery gradient at quadrature points
// get gradient and recovery gradient at quadrature points
uh
_
->
getGrdAtQPs
(
elInfo
,
NULL
,
quadFast
,
grdAtQP
);
uh
->
getGrdAtQPs
(
elInfo
,
NULL
,
quadFast
,
grdAtQP
);
rec_grd
->
getVecAtQPs
(
elInfo
,
NULL
,
rec_quadFast
,
recoveryGrdAtQP
);
rec_grd
->
getVecAtQPs
(
elInfo
,
NULL
,
rec_quadFast
,
recoveryGrdAtQP
);
if
(
f_scal
)
{
if
(
f_scal
)
{
if
(
aux_vec
)
if
(
aux_vec
)
aux_vec
->
getVecAtQPs
(
elInfo
,
NULL
,
quadFast
,
uhAtQP
);
aux_vec
->
getVecAtQPs
(
elInfo
,
NULL
,
quadFast
,
uhAtQP
);
else
else
uh
_
->
getVecAtQPs
(
elInfo
,
NULL
,
quadFast
,
uhAtQP
);
uh
->
getVecAtQPs
(
elInfo
,
NULL
,
quadFast
,
uhAtQP
);
}
}
// calc h1 error
// calc h1 error
...
@@ -151,7 +194,7 @@ namespace AMDiS {
...
@@ -151,7 +194,7 @@ namespace AMDiS {
}
}
}
else
{
}
else
{
// get vector and recovery vector at quadrature points
// get vector and recovery vector at quadrature points
uh
_
->
getVecAtQPs
(
elInfo
,
NULL
,
quadFast
,
uhAtQP
);
uh
->
getVecAtQPs
(
elInfo
,
NULL
,
quadFast
,
uhAtQP
);
rec_uh
->
getVecAtQPs
(
elInfo
,
NULL
,
rec_quadFast
,
recoveryUhAtQP
);
rec_uh
->
getVecAtQPs
(
elInfo
,
NULL
,
rec_quadFast
,
recoveryUhAtQP
);
// calc l2 error
// calc l2 error
...
@@ -159,12 +202,12 @@ namespace AMDiS {
...
@@ -159,12 +202,12 @@ namespace AMDiS {
errEl
+=
quad
->
getWeight
(
i
)
*
sqr
(
recoveryUhAtQP
[
i
]
-
uhAtQP
[
i
]);
errEl
+=
quad
->
getWeight
(
i
)
*
sqr
(
recoveryUhAtQP
[
i
]
-
uhAtQP
[
i
]);
}
}
double
estEl
=
C
*
det
*
errEl
;
estEl
+
=
C
*
det
*
errEl
;
el
->
setEstimation
(
estEl
,
row
);
el
->
setEstimation
(
estEl
,
row
);
est_sum
+=
estEl
;
est_sum
+=
estEl
;
est_max
=
std
::
max
(
est_max
,
estEl
);
est_max
=
std
::
max
(
est_max
,
estEl
);
if
(
relative
_
)
{
if
(
relative
)
{
double
normEl
=
0.0
;
double
normEl
=
0.0
;
if
(
norm
==
H1_NORM
)
{
if
(
norm
==
H1_NORM
)
{
...
@@ -181,31 +224,6 @@ namespace AMDiS {
...
@@ -181,31 +224,6 @@ namespace AMDiS {
h1Norm2
+=
det
*
normEl
;
h1Norm2
+=
det
*
normEl
;
}
}
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
// Computing relative errors
if
(
relative_
)
{
elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
while
(
elInfo
)
{
double
estEl
=
elInfo
->
getElement
()
->
getEstimation
(
row
);
estEl
/=
h1Norm2
;
elInfo
->
getElement
()
->
setEstimation
(
estEl
,
row
);
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
est_max
/=
h1Norm2
;
est_sum
/=
h1Norm2
;
}
est_sum
=
sqrt
(
est_sum
);
delete
[]
grdAtQP
;
MSG
(
"estimate = %.8e
\n
"
,
est_sum
);
return
est_sum
;
}
}
}
}
AMDiS/src/RecoveryEstimator.h
View file @
5de011fb
...
@@ -59,19 +59,24 @@ namespace AMDiS {
...
@@ -59,19 +59,24 @@ namespace AMDiS {
};
};
/// constructor
/// constructor
RecoveryEstimator
(
std
::
string
name
,
DOFVector
<
double
>
*
uh
,
int
r
=
-
1
);
RecoveryEstimator
(
std
::
string
name
,
DOFVector
<
double
>
*
uh
_
,
int
r
=
-
1
);
/// destructor.
/// destructor.
virtual
~
RecoveryEstimator
()
{}
virtual
~
RecoveryEstimator
()
{}
/// implements \ref Estimator::
estimate(
).
/// implements \ref Estimator::
init(double
).
v
irtual
double
estimate
(
double
timestep
=
0.0
);
v
oid
init
(
double
ts
);
/// implements \ref Estimator::estimateElement(ElInfo*, DualElInfo*).
void
estimateElement
(
ElInfo
*
elInfo
,
DualElInfo
*
dualElInfo
);
/// implements \ref Estimator::exit(bool).
void
exit
(
bool
output
);
/// Sets uh.
/// Sets uh.
inline
void
setUh
(
DOFVector
<
double
>
*
uh
)
inline
void
setUh
(
DOFVector
<
double
>
*
uh
_
)
{
{
uh
_
=
uh
;
uh
=
uh
_
;
}
}
/// Sets f.
/// Sets f.
...
@@ -92,6 +97,10 @@ namespace AMDiS {
...
@@ -92,6 +97,10 @@ namespace AMDiS {
aux_vec
=
uh
;
aux_vec
=
uh
;
}
}
inline
void
setAddEstimationToOld
(
bool
value
)
{
addEstimationToOld
=
value
;
}
/// Gets recovery gradient.
/// Gets recovery gradient.
inline
DOFVector
<
WorldVector
<
double
>
>*
getRecGrd
()
inline
DOFVector
<
WorldVector
<
double
>
>*
getRecGrd
()
...
@@ -108,10 +117,10 @@ namespace AMDiS {
...
@@ -108,10 +117,10 @@ namespace AMDiS {
protected:
protected:
/// finite element solution
/// finite element solution
DOFVector
<
double
>
*
uh
_
;
DOFVector
<
double
>
*
uh
;
/// absolute or relative error?
/// absolute or relative error?
int
relative
_
;
int
relative
;
/// constant for scaling the estimator
/// constant for scaling the estimator
double
C
;
double
C
;
...
@@ -119,6 +128,8 @@ namespace AMDiS {
...
@@ -119,6 +128,8 @@ namespace AMDiS {
/// recovery method
/// recovery method
int
method
;
int
method
;
bool
addEstimationToOld
;
/// Working finite element space
/// Working finite element space
const
FiniteElemSpace
*
feSpace
;
const
FiniteElemSpace
*
feSpace
;
...
@@ -143,6 +154,23 @@ namespace AMDiS {
...
@@ -143,6 +154,23 @@ namespace AMDiS {
/// Recovery structure.
/// Recovery structure.
Recovery
*
rec_struct
;
Recovery
*
rec_struct
;
/// Number of quadrature points.
int
nPoints
;
Quadrature
*
quad
;
FastQuadrature
*
quadFast
,
*
rec_quadFast
;
/// Basis functions
const
BasisFunction
*
basFcts
;
double
h1Norm2
;
WorldVector
<
double
>
quad_pt
;
WorldVector
<
double
>
*
grdAtQP
;
mtl
::
dense_vector
<
WorldVector
<
double
>
>
recoveryGrdAtQP
;
mtl
::
dense_vector
<
double
>
uhAtQP
;
mtl
::
dense_vector
<
double
>
recoveryUhAtQP
;
};
};
}
}
...
...
AMDiS/src/UmfPackSolver.h
View file @
5de011fb
...
@@ -87,19 +87,24 @@ namespace AMDiS {
...
@@ -87,19 +87,24 @@ namespace AMDiS {
else
else
solver
=
new
mtl
::
matrix
::
umfpack
::
solver
<
matrix_type
>
(
A
,
UMFPACK_STRATEGY_SYMMETRIC
);
solver
=
new
mtl
::
matrix
::
umfpack
::
solver
<
matrix_type
>
(
A
,
UMFPACK_STRATEGY_SYMMETRIC
);
}
else
{
}
else
{
if
(
!
multipleRhs
)
if
(
!
multipleRhs
)
{
if
(
store_symbolic
)
if
(
store_symbolic
)
solver
->
update_numeric
();
solver
->
update_numeric
();
else
else
solver
->
update
();
solver
->
update
();
}
}
}
int
code
=
(
*
solver
)(
x
,
b
);
int
code
=
(
*
solver
)(
x
,
b
);
mtl
::
dense_vector
<
value_type
>
r
(
b
);
if
(
info
>
0
)
{
r
-=
A
*
x
;
mtl
::
dense_vector
<
value_type
>
r
(
b
);
residual
=
two_norm
(
r
);
r
-=
A
*
x
;
std
::
cout
<<
"UmfPackSolver: ||b-Ax|| = "
<<
residual
<<
"
\n
"
;
residual
=
two_norm
(
r
);
std
::
cout
<<
"UmfPackSolver: ||b-Ax|| = "
<<
residual
<<
"
\n
"
;
if
(
residual
>
tolerance
)
{
WARNING
(
"Tolerance tol=%e could not be reached!
\n
"
,
tolerance
);
}
}
return
code
;
return
code
;
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment