Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
iwr
amdis
Commits
18086950
Commit
18086950
authored
Sep 03, 2008
by
Thomas Witkowski
Browse files
* compositeFEM source adapted to AMDiS source layout
* deleted all gcc warnings from compiling compositeFEM
parent
d3b88dd1
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
AMDiS/compositeFEM/src/CFE_Integration.cc
View file @
18086950
#include
"CFE_Integration.h"
#include
"Mesh.h"
#include
"SurfaceQuadrature.h"
#include
"Traverse.h"
#include
"ScalableQuadrature.h"
#include
"SubElInfo.h"
#include
"SubPolytope.h"
double
CFE_Integration
::
integrate_onNegLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
,
Quadrature
*
q
)
{
FUNCNAME
(
"CFE_Integration::integrate_onNegLs()"
);
int
dim
=
elLS
->
getDim
();
double
int_val
=
0.0
;
double
el_int_val
;
double
subEl_int_val
;
VectorOfFixVecs
<
DimVec
<
double
>
>
*
intersecPts
;
SubPolytope
*
subPolytope
;
int
numIntersecPts
;
int
iq
;
double
val
;
int
numQuadPts
;
int
vertex_interior
;
ScalableQuadrature
*
loc_scalQuad
;
int
numScalQuadPts
;
bool
subPolIsExterior
=
false
;
int
elStatus
;
Mesh
*
mesh
=
elLS
->
getMesh
();
// ===== Get quadratures. =====
if
(
!
q
)
{
q
=
Quadrature
::
provideQuadrature
(
dim
,
deg
);
}
numQuadPts
=
q
->
getNumPoints
();
loc_scalQuad
=
NEW
ScalableQuadrature
(
q
);
numScalQuadPts
=
loc_scalQuad
->
getNumPoints
();
namespace
AMDiS
{
double
CFE_Integration
::
integrate_onNegLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
,
Quadrature
*
q
)
{
FUNCNAME
(
"CFE_Integration::integrate_onNegLs()"
);
int
dim
=
elLS
->
getDim
();
double
int_val
=
0.0
;
double
el_int_val
;
double
subEl_int_val
;
VectorOfFixVecs
<
DimVec
<
double
>
>
*
intersecPts
;
SubPolytope
*
subPolytope
;
int
numIntersecPts
;
int
iq
;
double
val
;
int
numQuadPts
;
int
vertex_interior
;
ScalableQuadrature
*
loc_scalQuad
;
int
numScalQuadPts
;
bool
subPolIsExterior
=
false
;
int
elStatus
;
Mesh
*
mesh
=
elLS
->
getMesh
();
// ===== Get quadratures. =====
if
(
!
q
)
{
q
=
Quadrature
::
provideQuadrature
(
dim
,
deg
);
}
numQuadPts
=
q
->
getNumPoints
();
loc_scalQuad
=
NEW
ScalableQuadrature
(
q
);
numScalQuadPts
=
loc_scalQuad
->
getNumPoints
();
// ===== Traverse mesh and calculate integral on each element. =====
TraverseStack
stack
;
// ===== Traverse mesh and calculate integral on each element. =====
TraverseStack
stack
;
ElInfo
*
loc_elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
|
Mesh
::
FILL_COORDS
|
Mesh
::
FILL_DET
);
while
(
loc_elInfo
)
{
el_int_val
=
0.0
;
subEl_int_val
=
0.0
;
subPolIsExterior
=
false
;
ElInfo
*
loc_elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
|
Mesh
::
FILL_COORDS
|
Mesh
::
FILL_DET
);
while
(
loc_elInfo
)
{
el_int_val
=
0.0
;
subEl_int_val
=
0.0
;
subPolIsExterior
=
false
;
// Check whether current element is cut by the zero level set.
elStatus
=
elLS
->
createElementLevelSet
(
loc_elInfo
);
// Check whether current element is cut by the zero level set.
elStatus
=
elLS
->
createElementLevelSet
(
loc_elInfo
);
if
(
elStatus
==
ElementLevelSet
::
LEVEL_SET_BOUNDARY
)
{
if
(
elStatus
==
ElementLevelSet
::
LEVEL_SET_BOUNDARY
)
{
// -------------------------------------------------------------------
// Element is cut by the zero level set.
// -------------------------------------------------------------------
// -------------------------------------------------------------------
// Element is cut by the zero level set.
// -------------------------------------------------------------------
// Create subelements.
intersecPts
=
elLS
->
getElIntersecPoints
();
numIntersecPts
=
elLS
->
getNumElIntersecPoints
();
// Create subelements.
intersecPts
=
elLS
->
getElIntersecPoints
();
numIntersecPts
=
elLS
->
getNumElIntersecPoints
();
if
(
dim
==
1
||
(
dim
==
3
&&
numIntersecPts
==
4
))
{
if
(
dim
==
1
||
(
dim
==
3
&&
numIntersecPts
==
4
))
{
// -----------------------------------------------------------------
// Subelement(s) are inside the domain with negative level set
// function value.
// -----------------------------------------------------------------
// Subelement(s) are inside the domain with negative level set
// function value.
// Get vertex with negative level set function value.
for
(
int
i
=
0
;
i
<=
dim
;
++
i
)
{
if
(
elLS
->
getElVertLevelSetVec
(
i
)
<
0
)
{
vertex_interior
=
i
;
break
;
// Get vertex with negative level set function value.
for
(
int
i
=
0
;
i
<=
dim
;
++
i
)
{
if
(
elLS
->
getElVertLevelSetVec
(
i
)
<
0
)
{
vertex_interior
=
i
;
break
;
}
}
}
subPolytope
=
NEW
SubPolytope
(
loc_elInfo
,
intersecPts
,
numIntersecPts
,
vertex_interior
);
}
else
{
// -----------------------------------------------------------------
// Subelement may be inside the domain with negative level set
// function value as well as inside the domain with positive
// function value.
//
// Whether a subelement is in the domain with negative or positive
// level set function values is checked by the level set function
// value of the first vertex of the subelement. (The subelements
// are created in such a way that this vertex always is a vertex
// of the element and not an intersection point. Thus the level set
// function value of this vertex really is unequal to zero.)
subPolytope
=
NEW
SubPolytope
(
loc_elInfo
,
intersecPts
,
numIntersecPts
,
0
);
if
(
elLS
->
getVertexPos
(
subPolytope
->
getSubElement
(
0
)
->
getLambda
(
0
))
==
ElementLevelSet
::
LEVEL_SET_EXTERIOR
)
{
subPolIsExterior
=
true
;
subPolytope
=
NEW
SubPolytope
(
loc_elInfo
,
intersecPts
,
numIntersecPts
,
vertex_interior
);
}
else
{
// -----------------------------------------------------------------
// Subelement may be inside the domain with negative level set
// function value as well as inside the domain with positive
// function value.
//
// Whether a subelement is in the domain with negative or positive
// level set function values is checked by the level set function
// value of the first vertex of the subelement. (The subelements
// are created in such a way that this vertex always is a vertex
// of the element and not an intersection point. Thus the level set
// function value of this vertex really is unequal to zero.)
subPolytope
=
NEW
SubPolytope
(
loc_elInfo
,
intersecPts
,
numIntersecPts
,
0
);
if
(
elLS
->
getVertexPos
(
subPolytope
->
getSubElement
(
0
)
->
getLambda
(
0
))
==
ElementLevelSet
::
LEVEL_SET_EXTERIOR
)
{
subPolIsExterior
=
true
;
}
}
}
elLS
->
setLevelSetDomain
(
ElementLevelSet
::
LEVEL_SET_INTERIOR
);
elLS
->
setLevelSetDomain
(
ElementLevelSet
::
LEVEL_SET_INTERIOR
);
// Calculate integral on subelement(s).
f
->
setElInfo
(
loc_elInfo
);
for
(
std
::
vector
<
SubElInfo
*>::
iterator
it
=
subPolytope
->
getSubElementsBegin
();
it
!=
subPolytope
->
getSubElementsEnd
();
it
++
)
{
// Calculate integral on subelement(s).
f
->
setElInfo
(
loc_elInfo
);
for
(
std
::
vector
<
SubElInfo
*>::
iterator
it
=
subPolytope
->
getSubElementsBegin
();
it
!=
subPolytope
->
getSubElementsEnd
();
it
++
)
{
loc_scalQuad
->
scaleQuadrature
(
**
it
);
loc_scalQuad
->
scaleQuadrature
(
**
it
);
for
(
val
=
iq
=
0
;
iq
<
numScalQuadPts
;
++
iq
)
{
val
+=
loc_scalQuad
->
getWeight
(
iq
)
*
(
*
f
)(
loc_scalQuad
->
getLambda
(
iq
));
}
el_int_val
+=
fabs
((
*
it
)
->
getDet
())
*
val
;
}
for
(
val
=
iq
=
0
;
iq
<
numScalQuadPts
;
++
iq
)
{
val
+=
loc_scalQuad
->
getWeight
(
iq
)
*
(
*
f
)(
loc_scalQuad
->
getLambda
(
iq
));
// -------------------------------------------------------------------
// In case the subelement is in the domain with positive level set
// function values:
// Calculate the integral on the element part with negative
// level set function values by substracting the integral on the
// subelement from the integral on the complete element.
if
(
subPolIsExterior
)
{
subEl_int_val
=
el_int_val
;
el_int_val
=
0.0
;
f
->
setElInfo
(
loc_elInfo
);
for
(
val
=
iq
=
0
;
iq
<
numQuadPts
;
++
iq
)
{
val
+=
q
->
getWeight
(
iq
)
*
(
*
f
)(
q
->
getLambda
(
iq
));
}
el_int_val
=
loc_elInfo
->
calcDet
()
*
val
-
subEl_int_val
;
}
el_int_val
+=
fabs
((
*
it
)
->
getDet
())
*
val
;
// Free data.
DELETE
subPolytope
;
}
else
if
(
elStatus
==
ElementLevelSet
::
LEVEL_SET_INTERIOR
)
{
// -------------------------------------------------------------------
// In case the subelement is in the domain with positive level set
// function values:
// Calculate the integral on the element part with negative
// level set function values by substracting the integral on the
// subelement from the integral on the complete element.
if
(
subPolIsExterior
)
{
subEl_int_val
=
el_int_val
;
el_int_val
=
0.0
;
// -------------------------------------------------------------------
// Element is in the domain with negative level set function values.
// -------------------------------------------------------------------
elLS
->
setLevelSetDomain
(
ElementLevelSet
::
LEVEL_SET_INTERIOR
);
f
->
setElInfo
(
loc_elInfo
);
for
(
val
=
iq
=
0
;
iq
<
numQuadPts
;
++
iq
)
{
val
+=
q
->
getWeight
(
iq
)
*
(
*
f
)(
q
->
getLambda
(
iq
));
}
el_int_val
=
loc_elInfo
->
calcDet
()
*
val
-
subEl_int_val
;
}
// Free data.
DELETE
subPolytope
;
}
else
if
(
elStatus
==
ElementLevelSet
::
LEVEL_SET_INTERIOR
)
{
// -------------------------------------------------------------------
// Element is in the domain with negative level set function values.
// -------------------------------------------------------------------
elLS
->
setLevelSetDomain
(
ElementLevelSet
::
LEVEL_SET_INTERIOR
);
f
->
setElInfo
(
loc_elInfo
);
for
(
val
=
iq
=
0
;
iq
<
numQuadPts
;
++
iq
)
{
val
+=
q
->
getWeight
(
iq
)
*
(
*
f
)(
q
->
getLambda
(
iq
));
el_int_val
=
loc_elInfo
->
calcDet
()
*
val
;
}
el_int_val
=
loc_elInfo
->
calcDet
()
*
val
;
}
int_val
+=
el_int_val
;
loc_elInfo
=
stack
.
traverseNext
(
loc_elInfo
);
}
// end of: mesh traverse
int_val
+=
el_int_val
;
loc_elInfo
=
stack
.
traverseNext
(
loc_elInfo
);
DELETE
loc_scalQuad
;
}
// end of: mesh traverse
return
int_val
;
}
double
CFE_Integration
::
integrate_onZeroLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
,
Quadrature
*
q
)
{
FUNCNAME
(
"CFE_Integration::integrate_onZeroLs()"
);
int
dim
=
elLS
->
getDim
();
double
int_val
=
0.0
;
VectorOfFixVecs
<
DimVec
<
double
>
>
*
intersecPts
;
int
numIntersecPts
;
int
iq
;
double
val
;
SurfaceQuadrature
*
surfQuad
;
int
numQuadPts
;
VectorOfFixVecs
<
DimVec
<
double
>
>
tmpPts
(
dim
,
dim
,
NO_INIT
);
DimVec
<
double
>
tmpPt
(
dim
,
DEFAULT_VALUE
,
0.0
);
int
elStatus
;
Mesh
*
mesh
=
elLS
->
getMesh
();
// ===== Define default points for surface quadrature. =====
for
(
int
i
=
0
;
i
<
dim
;
++
i
)
{
tmpPt
[
i
]
=
1.0
;
tmpPts
[
i
]
=
tmpPt
;
tmpPt
[
i
]
=
0.0
;
}
DELETE
loc_scalQuad
;
// ===== Get quadratures. =====
if
(
!
q
)
{
q
=
Quadrature
::
provideQuadrature
(
dim
-
1
,
deg
);
return
int_val
;
}
surfQuad
=
NEW
SurfaceQuadrature
(
q
,
tmpPts
);
numQuadPts
=
surfQuad
->
getNumPoints
();
double
CFE_Integration
::
integrate_onZeroLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
,
Quadrature
*
q
)
{
FUNCNAME
(
"CFE_Integration::integrate_onZeroLs()"
);
int
dim
=
elLS
->
getDim
();
double
int_val
=
0.0
;
VectorOfFixVecs
<
DimVec
<
double
>
>
*
intersecPts
;
int
numIntersecPts
;
int
iq
;
double
val
;
SurfaceQuadrature
*
surfQuad
;
int
numQuadPts
;
VectorOfFixVecs
<
DimVec
<
double
>
>
tmpPts
(
dim
,
dim
,
NO_INIT
);
DimVec
<
double
>
tmpPt
(
dim
,
DEFAULT_VALUE
,
0.0
);
int
elStatus
;
Mesh
*
mesh
=
elLS
->
getMesh
();
// ===== Define default points for surface quadrature. =====
for
(
int
i
=
0
;
i
<
dim
;
++
i
)
{
tmpPt
[
i
]
=
1.0
;
tmpPts
[
i
]
=
tmpPt
;
tmpPt
[
i
]
=
0.0
;
}
// ===== Traverse mesh and calculate integral on each element cut by
// the zero level set. =====
TraverseStack
stack
;
ElInfo
*
loc_elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
|
Mesh
::
FILL_COORDS
|
Mesh
::
FILL_DET
);
while
(
loc_elInfo
)
{
// Check whether current element is cut by the zero level set.
elStatus
=
elLS
->
createElementLevelSet
(
loc_elInfo
);
// ===== Get quadratures. =====
if
(
!
q
)
{
q
=
Quadrature
::
provideQuadrature
(
dim
-
1
,
deg
);
}
surfQuad
=
NEW
SurfaceQuadrature
(
q
,
tmpPts
);
numQuadPts
=
surfQuad
->
getNumPoints
();
if
(
elStatus
==
ElementLevelSet
::
LEVEL_SET_BOUNDARY
)
{
// Get intersection points.
intersecPts
=
elLS
->
getElIntersecPoints
();
numIntersecPts
=
elLS
->
getNumElIntersecPoints
();
// Calculate surface integral on intersection plane.
f
->
setElInfo
(
loc_elInfo
);
// ===== Traverse mesh and calculate integral on each element cut by
// the zero level set. =====
TraverseStack
stack
;
// Note: The vector *intersecPts has always MAX_INTERSECTION_POINTS
// entries.
for
(
int
i
=
0
;
i
<
dim
;
++
i
)
tmpPts
[
i
]
=
(
*
intersecPts
)[
i
];
ElInfo
*
loc_elInfo
=
stack
.
traverseFirst
(
mesh
,
-
1
,
Mesh
::
CALL_LEAF_EL
|
Mesh
::
FILL_COORDS
|
Mesh
::
FILL_DET
);
while
(
loc_elInfo
)
{
surfQuad
->
scaleSurfaceQuadrature
(
tmpPts
);
// Check whether current element is cut by the zero level set.
elStatus
=
elLS
->
createElementLevelSet
(
loc_elInfo
);
for
(
val
=
iq
=
0
;
iq
<
numQuadPts
;
++
iq
)
{
val
+=
surfQuad
->
getWeight
(
iq
)
*
(
*
f
)(
surfQuad
->
getLambda
(
iq
));
}
int_val
+=
calcSurfaceDet
(
loc_elInfo
,
tmpPts
)
*
val
;
if
(
elStatus
==
ElementLevelSet
::
LEVEL_SET_BOUNDARY
)
{
// Get intersection points.
intersecPts
=
elLS
->
getElIntersecPoints
();
numIntersecPts
=
elLS
->
getNumElIntersecPoints
();
if
(
dim
==
3
&&
numIntersecPts
==
4
)
{
// Calculate surface integral on intersection plane.
f
->
setElInfo
(
loc_elInfo
);
// -----------------------------------------------------------------
// Intersection plane must be divided into two simplices. Calculate
// the surface integral for the second simplex.
//
// Note: The intersection points S0, S1, S2, S3 are supposed to be
// alligned in such a manner that a line through S1 and S2
// divides the intersection plane.
tmpPts
[
0
]
=
(
*
intersecPts
)[
3
];
// Note: The vector *intersecPts has always MAX_INTERSECTION_POINTS
// entries.
for
(
int
i
=
0
;
i
<
dim
;
++
i
)
tmpPts
[
i
]
=
(
*
intersecPts
)[
i
];
surfQuad
->
scaleSurfaceQuadrature
(
tmpPts
);
...
...
@@ -262,33 +244,53 @@ CFE_Integration::integrate_onZeroLs(ElementFunction<double> *f,
val
+=
surfQuad
->
getWeight
(
iq
)
*
(
*
f
)(
surfQuad
->
getLambda
(
iq
));
}
int_val
+=
calcSurfaceDet
(
loc_elInfo
,
tmpPts
)
*
val
;
if
(
dim
==
3
&&
numIntersecPts
==
4
)
{
// -----------------------------------------------------------------
// Intersection plane must be divided into two simplices. Calculate
// the surface integral for the second simplex.
//
// Note: The intersection points S0, S1, S2, S3 are supposed to be
// alligned in such a manner that a line through S1 and S2
// divides the intersection plane.
tmpPts
[
0
]
=
(
*
intersecPts
)[
3
];
surfQuad
->
scaleSurfaceQuadrature
(
tmpPts
);
for
(
val
=
iq
=
0
;
iq
<
numQuadPts
;
++
iq
)
{
val
+=
surfQuad
->
getWeight
(
iq
)
*
(
*
f
)(
surfQuad
->
getLambda
(
iq
));
}
int_val
+=
calcSurfaceDet
(
loc_elInfo
,
tmpPts
)
*
val
;
}
}
}
loc_elInfo
=
stack
.
traverseNext
(
loc_elInfo
);
loc_elInfo
=
stack
.
traverseNext
(
loc_elInfo
);
}
// end of: mesh traverse
}
// end of: mesh traverse
DELETE
surfQuad
;
DELETE
surfQuad
;
return
int_val
;
}
return
int_val
;
}
double
CFE_Integration
::
calcSurfaceDet
(
ElInfo
*
loc_elInfo
,
VectorOfFixVecs
<
DimVec
<
double
>
>
&
surfVert
)
{
double
surfDet
;
int
dim
=
surfVert
[
0
].
getSize
()
-
1
;
FixVec
<
WorldVector
<
double
>
,
VERTEX
>
worldCoords
(
dim
-
1
,
NO_INIT
);
double
CFE_Integration
::
calcSurfaceDet
(
ElInfo
*
loc_elInfo
,
VectorOfFixVecs
<
DimVec
<
double
>
>
&
surfVert
)
{
double
surfDet
;
int
dim
=
surfVert
[
0
].
getSize
()
-
1
;
FixVec
<
WorldVector
<
double
>
,
VERTEX
>
worldCoords
(
dim
-
1
,
NO_INIT
);
// transform barycentric coords to world coords
for
(
int
i
=
0
;
i
<
dim
;
i
++
)
{
loc_elInfo
->
coordToWorld
(
surfVert
[
i
],
&
worldCoords
[
i
]);
}
// transform barycentric coords to world coords
for
(
int
i
=
0
;
i
<
dim
;
i
++
)
{
loc_elInfo
->
coordToWorld
(
surfVert
[
i
],
&
worldCoords
[
i
]);
}
// calculate determinant for surface
surfDet
=
ElInfo
::
calcDet
(
worldCoords
);
// calculate determinant for surface
surfDet
=
ElInfo
::
calcDet
(
worldCoords
);
return
surfDet
;
}
return
surfDet
;
}
AMDiS/compositeFEM/src/CFE_Integration.h
View file @
18086950
...
...
@@ -4,40 +4,41 @@
#include
"ElementFunction.h"
#include
"MemoryManager.h"
#include
"Quadrature.h"
#include
"ElementLevelSet.h"
using
namespace
AMDiS
;
namespace
AMDiS
{
class
CFE_Integration
{
public:
MEMORY_MANAGED
(
CFE_Integration
);
class
CFE_Integration
{
public:
MEMORY_MANAGED
(
CFE_Integration
);
/**
* Calculates integral of function f on domain where level set function
* is negative.
*/
static
double
integrate_onNegLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
=
1
,
Quadrature
*
q
=
NULL
);
/**
* Calculates integral of function f on domain where level set function
* is negative.
*/
static
double
integrate_onNegLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
=
1
,
Quadrature
*
q
=
NULL
);
/**
* Calculates surface integral of function f on the zero level set.
*
* Note: Quadrature q is a quadrature formula for dimension dim-1.
*/
static
double
integrate_onZeroLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
=
1
,
Quadrature
*
q
=
NULL
);
protected:
/**
* Calculates determinant for surface given through surfVert.
*/
static
double
calcSurfaceDet
(
ElInfo
*
loc_elInfo
,
VectorOfFixVecs
<
DimVec
<
double
>
>
&
surfVert
);
};
/**
* Calculates surface integral of function f on the zero level set.
*
* Note: Quadrature q is a quadrature formula for dimension dim-1.
*/
static
double
integrate_onZeroLs
(
ElementFunction
<
double
>
*
f
,
ElementLevelSet
*
elLS
,
int
deg
=
1
,
Quadrature
*
q
=
NULL
);
protected:
/**
* Calculates determinant for surface given through surfVert.
*/
static
double
calcSurfaceDet
(
ElInfo
*
loc_elInfo
,
VectorOfFixVecs
<
DimVec
<
double
>
>
&
surfVert
);
};
}
#endif // AMDIS_CFE_INTEGRATION_H
AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.cc
View file @
18086950
This diff is collapsed.
Click to expand it.
AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.h
View file @
18086950
This diff is collapsed.
Click to expand it.
AMDiS/compositeFEM/src/ScalableQuadrature.cc