Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Backofen, Rainer
amdis
Commits
e8e207b4
Commit
e8e207b4
authored
Oct 22, 2012
by
Thomas Witkowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Code refactoring, add comments, dirichlet rows in FETI-DP defined per component.
parent
a276473c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
280 additions
and
264 deletions
+280
-264
AMDiS/src/parallel/MeshDistributor.cc
AMDiS/src/parallel/MeshDistributor.cc
+1
-0
AMDiS/src/parallel/ParallelDofMapping.cc
AMDiS/src/parallel/ParallelDofMapping.cc
+64
-81
AMDiS/src/parallel/ParallelDofMapping.h
AMDiS/src/parallel/ParallelDofMapping.h
+195
-151
AMDiS/src/parallel/PetscSolverFeti.cc
AMDiS/src/parallel/PetscSolverFeti.cc
+17
-31
AMDiS/src/parallel/PetscSolverFeti.h
AMDiS/src/parallel/PetscSolverFeti.h
+3
-1
No files found.
AMDiS/src/parallel/MeshDistributor.cc
View file @
e8e207b4
...
...
@@ -1687,6 +1687,7 @@ namespace AMDiS {
MSG
(
"| number of levels: %d
\n
"
,
nLevels
);
MSG
(
"| number of FE spaces: %d
\n
"
,
uniqueFeSpaces
.
size
());
for
(
unsigned
int
i
=
0
;
i
<
uniqueFeSpaces
.
size
();
i
++
)
{
MSG
(
"| FE space = %d (pointer adr %p):
\n
"
,
i
,
uniqueFeSpaces
[
i
]);
MSG
(
"| nRankDofs = %d
\n
"
,
dofMap
[
uniqueFeSpaces
[
i
]].
nRankDofs
);
...
...
AMDiS/src/parallel/ParallelDofMapping.cc
View file @
e8e207b4
...
...
@@ -42,8 +42,7 @@ namespace AMDiS {
:
levelData
(
ld
),
dofComm
(
NULL
),
feSpace
(
NULL
),
needGlobalMapping
(
false
),
isNonLocal
(
false
)
globalMapping
(
false
)
{
clear
();
}
...
...
@@ -80,11 +79,9 @@ namespace AMDiS {
// === If required, compute also the global indices. ===
if
(
needGlobalMapping
)
{
computeGlobalMapping
();
if
(
isNonLocal
)
computeNonLocalIndices
();
if
(
globalMapping
)
{
computeGlobalMapping
();
computeNonLocalIndices
();
}
}
...
...
@@ -170,67 +167,50 @@ namespace AMDiS {
}
void
ComponentDataEq
FeSpace
::
init
(
vector
<
const
FiniteElemSpace
*>
&
f0
,
vector
<
const
FiniteElemSpace
*>
&
f1
,
bool
isNonLocal
,
MeshLevelData
&
levelData
)
void
FeSpace
Data
::
init
(
vector
<
const
FiniteElemSpace
*>
&
f0
,
vector
<
const
FiniteElemSpace
*>
&
f1
,
bool
globalMapping
,
MeshLevelData
&
levelData
)
{
feSpaces
=
f0
;
feSpacesUnique
=
f1
;
for
(
vector
<
const
FiniteElemSpace
*>::
iterator
it
=
feSpacesUnique
.
begin
();
it
!=
feSpacesUnique
.
end
();
++
it
)
{
addFeSpace
(
*
it
,
levelData
);
componentData
[
*
it
].
setNeedGlobalMapping
(
isNonLocal
);
componentData
[
*
it
].
setNonLocal
(
isNonLocal
);
componentSpaces
=
f0
;
feSpaces
=
f1
;
for
(
vector
<
const
FiniteElemSpace
*>::
iterator
it
=
feSpaces
.
begin
();
it
!=
feSpaces
.
end
();
++
it
)
{
if
(
componentData
.
count
(
*
it
))
componentData
.
find
(
*
it
)
->
second
.
clear
();
else
componentData
.
insert
(
make_pair
(
*
it
,
ComponentDofMap
(
&
levelData
)));
componentData
[
*
it
].
setFeSpace
(
*
it
);
componentData
[
*
it
].
setGlobalMapping
(
globalMapping
);
}
}
void
ComponentDataEqFeSpace
::
addFeSpace
(
const
FiniteElemSpace
*
feSpace
,
MeshLevelData
&
levelData
)
void
ComponentData
::
init
(
vector
<
const
FiniteElemSpace
*>
&
f0
,
vector
<
const
FiniteElemSpace
*>
&
f1
,
bool
globalMapping
,
MeshLevelData
&
levelData
)
{
if
(
componentData
.
count
(
feSpace
))
componentData
.
find
(
feSpace
)
->
second
.
clear
();
else
componentData
.
insert
(
make_pair
(
feSpace
,
ComponentDofMap
(
&
levelData
)));
componentData
.
find
(
feSpace
)
->
second
.
setFeSpace
(
feSpace
);
}
void
ComponentDataDiffFeSpace
::
init
(
vector
<
const
FiniteElemSpace
*>
&
f0
,
vector
<
const
FiniteElemSpace
*>
&
f1
,
bool
isNonLocal
,
MeshLevelData
&
levelData
)
{
feSpaces
=
f0
;
feSpacesUnique
=
f1
;
for
(
unsigned
int
component
=
0
;
component
<
feSpaces
.
size
();
component
++
)
{
addComponent
(
component
,
feSpaces
[
component
],
levelData
);
componentData
[
component
].
setNeedGlobalMapping
(
isNonLocal
);
componentData
[
component
].
setNonLocal
(
isNonLocal
);
componentSpaces
=
f0
;
feSpaces
=
f1
;
for
(
unsigned
int
component
=
0
;
component
<
componentSpaces
.
size
();
component
++
)
{
if
(
componentData
.
count
(
component
))
componentData
.
find
(
component
)
->
second
.
clear
();
else
componentData
.
insert
(
make_pair
(
component
,
ComponentDofMap
(
&
levelData
)));
componentData
[
component
].
setFeSpace
(
componentSpaces
[
component
]);
componentData
[
component
].
setGlobalMapping
(
globalMapping
);
}
}
void
ComponentDataDiffFeSpace
::
addComponent
(
unsigned
int
component
,
const
FiniteElemSpace
*
feSpace
,
MeshLevelData
&
levelData
)
{
if
(
componentData
.
count
(
component
))
componentData
.
find
(
component
)
->
second
.
clear
();
else
componentData
.
insert
(
make_pair
(
component
,
ComponentDofMap
(
&
levelData
)));
componentData
.
find
(
component
)
->
second
.
setFeSpace
(
feSpace
);
}
ParallelDofMapping
::
ParallelDofMapping
(
DofMappingMode
mode
)
:
levelData
(
NULL
),
dofComm
(
NULL
),
isNonLocal
(
true
),
globalMapping
(
true
),
needMatIndexFromGlobal
(
false
),
nRankDofs
(
1
),
nLocalDofs
(
1
),
...
...
@@ -239,10 +219,10 @@ namespace AMDiS {
{
switch
(
mode
)
{
case
COMPONENT_WISE
:
data
=
new
ComponentData
DiffFeSpace
();
data
=
new
ComponentData
();
break
;
case
FESPACE_WISE
:
data
=
new
ComponentDataEq
FeSpace
();
data
=
new
FeSpace
Data
();
break
;
}
...
...
@@ -261,9 +241,10 @@ namespace AMDiS {
FUNCNAME
(
"ParallelDofMapping::init()"
);
levelData
=
&
ldata
;
isNonLocal
=
b
;
globalMapping
=
b
;
componentSpaces
=
fe
;
data
->
init
(
fe
,
uniqueFe
,
isNonLocal
,
ldata
);
data
->
init
(
fe
,
uniqueFe
,
globalMapping
,
ldata
);
}
...
...
@@ -386,29 +367,28 @@ namespace AMDiS {
// === Create the matrix indices for all component FE spaces. ===
vector
<
const
FiniteElemSpace
*>
&
feSpaces
=
data
->
getFeSpaces
();
for
(
unsigned
int
i
=
0
;
i
<
feSpaces
.
size
();
i
++
)
{
for
(
unsigned
int
component
=
0
;
component
<
componentSpaces
.
size
();
component
++
)
{
// Traverse all DOFs of the FE space and create for all rank owned DOFs
// a matrix index.
DofMap
&
dofMap
=
(
*
data
)[
i
].
getMap
();
DofMap
&
dofMap
=
(
*
data
)[
component
].
getMap
();
for
(
DofMap
::
iterator
it
=
dofMap
.
begin
();
it
!=
dofMap
.
end
();
++
it
)
{
if
((
*
data
)[
i
].
isRankDof
(
it
->
first
))
{
if
((
*
data
)[
component
].
isRankDof
(
it
->
first
))
{
int
globalMatIndex
=
it
->
second
.
local
+
offset
;
if
(
globalIndex
)
dofToMatIndex
.
add
(
i
,
it
->
second
.
global
,
globalMatIndex
);
dofToMatIndex
.
add
(
component
,
it
->
second
.
global
,
globalMatIndex
);
else
dofToMatIndex
.
add
(
i
,
it
->
first
,
globalMatIndex
);
dofToMatIndex
.
add
(
component
,
it
->
first
,
globalMatIndex
);
}
}
// Increase the offset for the next FE space by the number of DOFs owned
// by the rank in the current FE space.
offset
+=
(
*
data
)[
i
].
nRankDofs
;
offset
+=
(
*
data
)[
component
].
nRankDofs
;
// If there are no non local DOFs, continue with the next FE space.
if
(
!
isNonLocal
)
if
(
!
globalMapping
)
continue
;
TEST_EXIT_DBG
(
dofComm
!=
NULL
)(
"No communicator given!
\n
"
);
...
...
@@ -417,16 +397,17 @@ namespace AMDiS {
// === interior boundaries. ===
StdMpi
<
vector
<
DegreeOfFreedom
>
>
stdMpi
(
mpiComm
);
for
(
DofComm
::
Iterator
it
(
dofComm
->
getSendDofs
(),
0
,
feSpaces
[
i
]);
for
(
DofComm
::
Iterator
it
(
dofComm
->
getSendDofs
(),
0
,
componentSpaces
[
component
]);
!
it
.
end
();
it
.
nextRank
())
{
vector
<
DegreeOfFreedom
>
sendGlobalDofs
;
for
(;
!
it
.
endDofIter
();
it
.
nextDof
())
if
(
dofMap
.
count
(
it
.
getDofIndex
()))
if
(
globalIndex
)
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
i
,
dofMap
[
it
.
getDofIndex
()].
global
));
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
component
,
dofMap
[
it
.
getDofIndex
()].
global
));
else
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
i
,
it
.
getDofIndex
()));
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
component
,
it
.
getDofIndex
()));
int
rank
=
it
.
getRank
();
if
(
meshLevel
>
0
)
...
...
@@ -435,7 +416,7 @@ namespace AMDiS {
stdMpi
.
send
(
rank
,
sendGlobalDofs
);
}
for
(
DofComm
::
Iterator
it
(
dofComm
->
getRecvDofs
(),
0
,
feSpaces
[
i
]);
for
(
DofComm
::
Iterator
it
(
dofComm
->
getRecvDofs
(),
0
,
componentSpaces
[
component
]);
!
it
.
end
();
it
.
nextRank
())
{
int
rank
=
it
.
getRank
();
if
(
meshLevel
>
0
)
...
...
@@ -446,7 +427,7 @@ namespace AMDiS {
stdMpi
.
startCommunication
();
for
(
DofComm
::
Iterator
it
(
dofComm
->
getRecvDofs
(),
0
,
feSpaces
[
i
]);
for
(
DofComm
::
Iterator
it
(
dofComm
->
getRecvDofs
(),
0
,
componentSpaces
[
component
]);
!
it
.
end
();
it
.
nextRank
())
{
int
rank
=
it
.
getRank
();
if
(
meshLevel
>
0
)
...
...
@@ -457,9 +438,9 @@ namespace AMDiS {
if
(
dofMap
.
count
(
it
.
getDofIndex
()))
{
DegreeOfFreedom
d
=
stdMpi
.
getRecvData
(
rank
)[
counter
++
];
if
(
globalIndex
)
dofToMatIndex
.
add
(
i
,
dofMap
[
it
.
getDofIndex
()].
global
,
d
);
dofToMatIndex
.
add
(
component
,
dofMap
[
it
.
getDofIndex
()].
global
,
d
);
else
dofToMatIndex
.
add
(
i
,
it
.
getDofIndex
(),
d
);
dofToMatIndex
.
add
(
component
,
it
.
getDofIndex
(),
d
);
}
}
}
...
...
@@ -469,7 +450,7 @@ namespace AMDiS {
stdMpi
.
clear
();
for
(
DofComm
::
Iterator
it
(
dofComm
->
getPeriodicDofs
(),
0
,
feSpaces
[
i
]);
for
(
DofComm
::
Iterator
it
(
dofComm
->
getPeriodicDofs
(),
0
,
componentSpaces
[
component
]);
!
it
.
end
();
it
.
nextRank
())
{
vector
<
DegreeOfFreedom
>
sendGlobalDofs
;
...
...
@@ -477,9 +458,10 @@ namespace AMDiS {
if
(
dofMap
.
count
(
it
.
getDofIndex
()))
{
if
(
globalIndex
)
{
sendGlobalDofs
.
push_back
(
dofMap
[
it
.
getDofIndex
()].
global
);
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
i
,
dofMap
[
it
.
getDofIndex
()].
global
));
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
component
,
dofMap
[
it
.
getDofIndex
()].
global
));
}
else
{
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
i
,
it
.
getDofIndex
()));
sendGlobalDofs
.
push_back
(
dofToMatIndex
.
get
(
component
,
it
.
getDofIndex
()));
}
}
...
...
@@ -493,7 +475,7 @@ namespace AMDiS {
stdMpi
.
startCommunication
();
for
(
DofComm
::
Iterator
it
(
dofComm
->
getPeriodicDofs
(),
0
,
feSpaces
[
i
]);
for
(
DofComm
::
Iterator
it
(
dofComm
->
getPeriodicDofs
(),
0
,
componentSpaces
[
component
]);
!
it
.
end
();
it
.
nextRank
())
{
int
rank
=
it
.
getRank
();
...
...
@@ -508,12 +490,13 @@ namespace AMDiS {
TEST_EXIT_DBG
(
counter
+
2
<=
stdMpi
.
getRecvData
(
it
.
getRank
()).
size
())
(
"Should not happen!
\n
"
);
dofToMatIndex
.
add
(
i
,
dofToMatIndex
.
add
(
component
,
stdMpi
.
getRecvData
(
it
.
getRank
())[
counter
],
stdMpi
.
getRecvData
(
it
.
getRank
())[
counter
+
1
]);
counter
+=
2
;
}
else
{
dofToMatIndex
.
add
(
i
,
it
.
getDofIndex
(),
dofToMatIndex
.
add
(
component
,
it
.
getDofIndex
(),
stdMpi
.
getRecvData
(
it
.
getRank
())[
counter
++
]);
}
}
...
...
AMDiS/src/parallel/ParallelDofMapping.h
View file @
e8e207b4
...
...
@@ -222,17 +222,10 @@ namespace AMDiS {
feSpace
=
fe
;
}
/// Informs the mapping whether the mapping will include DOFs that are not
/// owned by the rank.
void
setNonLocal
(
bool
b
)
{
isNonLocal
=
b
;
}
/// Informs the mapping whether a global index must be computed.
void
set
Need
GlobalMapping
(
bool
b
)
void
setGlobalMapping
(
bool
b
)
{
needG
lobalMapping
=
b
;
g
lobalMapping
=
b
;
}
/// Sets the DOF communicator.
...
...
@@ -276,12 +269,7 @@ namespace AMDiS {
boost
::
container
::
flat_set
<
DegreeOfFreedom
>
nonRankDofs
;
/// If true, a global index mapping will be computed for all DOFs.
bool
needGlobalMapping
;
/// Is true if there are DOFs in at least one subdomain that are not owned
/// by the rank. If the value is false, each rank contains only DOFs that
/// are also owned by this rank.
bool
isNonLocal
;
bool
globalMapping
;
public:
///
...
...
@@ -289,6 +277,8 @@ namespace AMDiS {
};
/// Abstract iterator interface to access containrs containing values of
/// type \ref ComponentDofMap.
class
ComponentIterator
{
public:
virtual
ComponentDofMap
&
operator
*
()
=
0
;
...
...
@@ -303,240 +293,249 @@ namespace AMDiS {
};
/// Abstract interface to acces DOF mapping data for each component. Allows
/// to hide specific implementations, which allow, e.g., to efficiently map
/// all components having the same FE space to the same DOF mapping.
class
ComponentDataInterface
{
public:
/// Access via component number
virtual
ComponentDofMap
&
operator
[](
int
compNumber
)
=
0
;
/// Acess via FE space pointer
virtual
ComponentDofMap
&
operator
[](
const
FiniteElemSpace
*
feSpace
)
=
0
;
/// Checks whether the DOF mapping is defined for a specific
/// component number.
virtual
bool
isDefinedFor
(
int
compNumber
)
const
=
0
;
/// Returns iterator which iterates over all DOF mappings.
virtual
ComponentIterator
&
getIteratorData
()
=
0
;
/// Returns iterator which iterates over the DOF mappings of all
/// components. If the data is defined for each FE space and more than
/// one commponent is defined on the same FE space, the iterative will
/// also iterative multple times over the same DOF mapping object.
virtual
ComponentIterator
&
getIteratorComponent
()
=
0
;
virtual
void
init
(
vector
<
const
FiniteElemSpace
*>
&
f0
,
vector
<
const
FiniteElemSpace
*>
&
f1
,
bool
isNonLocal
,
/** \brief
* Initialization of the object.
*
* \param[in] componentSpaces Set of the FE spaces for each component.
* \param[in] feSpaces Set of all different FE spaces.
* \param[in] globalMapping Mapping is parallel (true) or only
* local (false).
* \param[in] levelData Data for multi level method.
*/
virtual
void
init
(
vector
<
const
FiniteElemSpace
*>
&
componentSpaces
,
vector
<
const
FiniteElemSpace
*>
&
feSpaces
,
bool
globalMapping
,
MeshLevelData
&
levelData
)
=
0
;
vector
<
const
FiniteElemSpace
*>&
getFeSpaces
()
{
return
feSpaces
;
}
protected:
/// The FE spaces for all components.
vector
<
const
FiniteElemSpace
*>
fe
Spaces
;
vector
<
const
FiniteElemSpace
*>
component
Spaces
;
/// The set of all FE spaces. It uniquly contains all different FE spaces
/// from \ref feSpaces.
vector
<
const
FiniteElemSpace
*>
feSpaces
Unique
;
vector
<
const
FiniteElemSpace
*>
feSpaces
;
};
class
ComponentDataEqFeSpace
:
public
ComponentDataInterface
/// This class concretizes the interface class \ref ComponentDataInterface. A
/// DOF mapping is implemented for each component.
class
ComponentData
:
public
ComponentDataInterface
{
public:
ComponentDataEqFeSpace
()
:
iterData
(
this
),
iterComponent
(
this
)
ComponentData
()
:
iter
(
this
)
{}
/// Returns DOF mapping for a given component number.
ComponentDofMap
&
operator
[](
int
compNumber
)
{
const
FiniteElemSpace
*
feSpace
=
feSpaces
[
compNumber
];
return
componentData
.
find
(
feSpace
)
->
second
;
}
TEST_EXIT_DBG
(
componentData
.
count
(
compNumber
))
(
"No data for component %d!
\n
"
,
compNumber
);
ComponentDofMap
&
operator
[](
const
FiniteElemSpace
*
feSpace
)
{
TEST_EXIT_DBG
(
componentData
.
count
(
feSpace
))(
"No data for FE space!
\n
"
);;
return
componentData
.
find
(
feSpace
)
->
second
;
return
componentData
.
find
(
compNumber
)
->
second
;
}
bool
isDefinedFor
(
int
compNumber
)
const
/// Just to implement the corresponding virtual function in \ref
/// ComponentDataInterface. Of course it does not work as we have data for
/// each component. Thus there may be different mappings for the same
/// FE space.
ComponentDofMap
&
operator
[](
const
FiniteElemSpace
*
feSpace
)
{
const
FiniteElemSpace
*
feSpace
=
feSpaces
[
compNumber
];
return
static_cast
<
bool
>
(
componentData
.
count
(
feSpace
));
ERROR_EXIT
(
"FE Space acces is not possible for component wise defined DOF mappings
\n
"
);
}
/// Return data iterator.
ComponentIterator
&
getIteratorData
()
{
iter
Data
.
reset
();
return
iter
Data
;
iter
.
reset
();
return
iter
;
}
/// Return component iterator.
ComponentIterator
&
getIteratorComponent
()
{
iter
Component
.
reset
();
return
iter
Component
;
iter
.
reset
();
return
iter
;
}
/// Checks whether the DOF mapping is defined for a specific
/// component number.
bool
isDefinedFor
(
int
compNumber
)
const
{
return
(
static_cast
<
unsigned
int
>
(
compNumber
)
<
componentData
.
size
());
}
/// Initialization
void
init
(
vector
<
const
FiniteElemSpace
*>
&
f0
,
vector
<
const
FiniteElemSpace
*>
&
f1
,
bool
isNonLocal
,
bool
globalMapping
,
MeshLevelData
&
levelData
);
protected:
void
addFeSpace
(
const
FiniteElemSpace
*
feSpace
,
MeshLevelData
&
levelData
);
class
IteratorData
:
public
ComponentIterator
{
/// Iterator class to iterate over all parallel DOF mappings.
class
Iterator
:
public
ComponentIterator
{
public:
IteratorData
(
ComponentDataEqFeSpace
*
d
)
:
data
(
d
)
Iterator
(
ComponentData
*
d
)
:
data
(
d
),
componentCounter
(
-
1
)
{}
ComponentDofMap
&
operator
*
()
{
(
*
data
)[
*
it
];
(
*
data
)[
componentCounter
];
}
ComponentDofMap
*
operator
->
()
{
&
((
*
data
)[
*
it
]);
&
((
*
data
)[
componentCounter
]);
}
bool
end
()
{
return
(
it
==
data
->
feSpacesUnique
.
end
());
return
(
it
==
data
->
componentSpaces
.
end
());
}
void
next
()
{
++
it
;
++
componentCounter
;
if
(
it
==
data
->
componentSpaces
.
end
())
componentCounter
=
-
1
;
}
void
reset
()
{
it
=
data
->
feSpacesUnique
.
begin
();
it
=
data
->
componentSpaces
.
begin
();
componentCounter
=
0
;
}
protected:
ComponentDataEqFeSpace
*
data
;
/// Pointer to data class over which the iterator must iterate.
ComponentData
*
data
;
/// Internal iterator of the internal data from \ref ComponentData.
vector
<
const
FiniteElemSpace
*>::
iterator
it
;
};
class
IteratorComponent
:
public
ComponentIterator
{
public:
IteratorComponent
(
ComponentDataEqFeSpace
*
d
)
:
data
(
d
)
{}
ComponentDofMap
&
operator
*
()
{
(
*
data
)[
*
it
];
}
ComponentDofMap
*
operator
->
()
{
&
((
*
data
)[
*
it
]);
}
bool
end
()
{
return
(
it
==
data
->
feSpaces
.
end
());
}
void
next
()
{
++
it
;
}
void
reset
()
{
it
=
data
->
feSpaces
.
begin
();
}
/// Component number of current iteration.
int
componentCounter
;
};
protected:
ComponentDataEqFeSpace
*
data
;
vector
<
const
FiniteElemSpace
*>::
iterator
it
;
};
/// Data mapping from component numbers to DOF mapping objects.
map
<
unsigned
int
,
ComponentDofMap
>
componentData
;
map
<
const
FiniteElemSpace
*
,
ComponentDofMap
>
componentData
;
/// Iterator object.
Iterator
iter
;
IteratorData
iterData
;
IteratorComponent
iterComponent
;
friend
class
IteratorData
;
friend
class
IteratorComponent
;
friend
class
Iterator
;
};
class
ComponentDataDiffFeSpace
:
public
ComponentDataInterface
/// This class concretizes the interface class \ref ComponentDataInterface. A
/// DOF mapping is implemented for each finite element space. Thus, different
/// components sharing the same FE space are handled by the same DOF mapping.
class
FeSpaceData
:
public
ComponentDataInterface
{
public:
ComponentDataDiffFeSpace
()
:
iter
(
this
)
FeSpaceData
()
:
iterData
(
this
),
iterComponent
(
this
)
{}
/// Returns DOF mapping for a given component number.
ComponentDofMap
&
operator
[](
int
compNumber
)
{
TEST_EXIT_DBG
(
componentData
.
count
(
compNumber
))(
"No data for component %d!
\n
"
,
compNumber
);
return
componentData
.
find
(
compNumber
)
->
second
;
const
FiniteElemSpace
*
feSpace
=
componentSpaces
[
compNumber
];
return
componentData
.
find
(
feSpace
)
->
second
;