Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F93902954
test_dof_manager.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Dec 2, 09:34
Size
9 KB
Mime Type
text/x-c++
Expires
Wed, Dec 4, 09:34 (1 d, 21 h)
Engine
blob
Format
Raw Data
Handle
22719240
Attached To
rAKA akantu
test_dof_manager.cc
View Options
/**
* Copyright (©) 2019-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* This file is part of Akantu
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*/
/* -------------------------------------------------------------------------- */
#include "test_gtest_utils.hh"
/* -------------------------------------------------------------------------- */
#include <dof_manager.hh>
#include <mesh_partition_scotch.hh>
#include <mesh_utils.hh>
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#include <numeric>
#include <string>
#include <type_traits>
/* -------------------------------------------------------------------------- */
namespace
akantu
{
enum
DOFManagerType
{
_dmt_default
,
_dmt_petsc
};
}
AKANTU_ENUM_HASH
(
DOFManagerType
)
using
namespace
akantu
;
// defined as struct to get there names in gtest outputs
struct
dof_manager_default_
:
public
std
::
integral_constant
<
DOFManagerType
,
_dmt_default
>
{};
struct
dof_manager_petsc_
:
public
std
::
integral_constant
<
DOFManagerType
,
_dmt_petsc
>
{};
using
dof_manager_types
=
::
testing
::
Types
<
#ifdef AKANTU_USE_PETSC
dof_manager_petsc_
,
#endif
dof_manager_default_
>
;
namespace
std
{
std
::
string
to_string
(
const
DOFManagerType
&
type
)
{
std
::
unordered_map
<
DOFManagerType
,
std
::
string
>
map
{
#ifdef AKANTU_USE_PETSC
{
_dmt_petsc
,
"petsc"
},
#endif
{
_dmt_default
,
"default"
},
};
return
map
.
at
(
type
);
}
}
// namespace std
/* -------------------------------------------------------------------------- */
using
namespace
akantu
;
/* -------------------------------------------------------------------------- */
namespace
akantu
{
class
DOFManagerTester
{
public
:
DOFManagerTester
(
std
::
unique_ptr
<
DOFManager
>
dof_manager
)
:
dof_manager
(
std
::
move
(
dof_manager
))
{}
DOFManager
&
operator
*
()
{
return
*
dof_manager
;
}
DOFManager
*
operator
->
()
{
return
dof_manager
.
get
();
}
void
getArrayPerDOFs
(
const
ID
&
id
,
SolverVector
&
vector
,
Array
<
Real
>
&
array
)
{
dof_manager
->
getArrayPerDOFs
(
id
,
vector
,
array
);
}
SolverVector
&
residual
()
{
return
*
dof_manager
->
residual
;
}
private
:
std
::
unique_ptr
<
DOFManager
>
dof_manager
;
};
}
// namespace akantu
template
<
class
T
>
class
DOFManagerFixture
:
public
::
testing
::
Test
{
public
:
constexpr
static
DOFManagerType
type
=
T
::
value
;
constexpr
static
Int
dim
=
3
;
void
SetUp
()
override
{
mesh
=
std
::
make_unique
<
Mesh
>
(
this
->
dim
);
auto
&
communicator
=
Communicator
::
getStaticCommunicator
();
if
(
communicator
.
whoAmI
()
==
0
)
{
mesh
->
read
(
"mesh.msh"
);
}
mesh
->
distribute
();
nb_nodes
=
this
->
mesh
->
getNbNodes
();
nb_total_nodes
=
this
->
mesh
->
getNbGlobalNodes
();
auto
&&
range_nodes
=
arange
(
nb_nodes
);
nb_pure_local
=
std
::
accumulate
(
range_nodes
.
begin
(),
range_nodes
.
end
(),
0
,
[
&
](
auto
&&
init
,
auto
&&
val
)
{
return
init
+
mesh
->
isLocalOrMasterNode
(
val
);
});
}
void
TearDown
()
override
{
mesh
.
reset
();
dof1
.
reset
();
dof2
.
reset
();
}
decltype
(
auto
)
alloc
()
{
std
::
unordered_map
<
DOFManagerType
,
std
::
string
>
types
{
{
_dmt_default
,
"default"
},
{
_dmt_petsc
,
"petsc"
}};
return
DOFManagerTester
(
DOFManagerFactory
::
getInstance
().
allocate
(
types
[
T
::
value
],
*
mesh
,
"dof_manager"
));
}
decltype
(
auto
)
registerDOFs
(
DOFSupportType
dst1
,
DOFSupportType
dst2
)
{
auto
dof_manager
=
DOFManagerTester
(
this
->
alloc
());
auto
n1
=
dst1
==
_dst_nodal
?
nb_nodes
:
nb_pure_local
;
this
->
dof1
=
std
::
make_unique
<
Array
<
Real
>>
(
n1
,
3
);
dof_manager
->
registerDOFs
(
"dofs1"
,
*
this
->
dof1
,
dst1
);
EXPECT_EQ
(
dof_manager
.
residual
().
size
(),
nb_total_nodes
*
3
);
auto
n2
=
dst2
==
_dst_nodal
?
nb_nodes
:
nb_pure_local
;
this
->
dof2
=
std
::
make_unique
<
Array
<
Real
>>
(
n2
,
5
);
dof_manager
->
registerDOFs
(
"dofs2"
,
*
this
->
dof2
,
dst2
);
EXPECT_EQ
(
dof_manager
.
residual
().
size
(),
nb_total_nodes
*
8
);
return
dof_manager
;
}
protected
:
Int
nb_nodes
{
0
},
nb_total_nodes
{
0
},
nb_pure_local
{
0
};
std
::
unique_ptr
<
Mesh
>
mesh
;
std
::
unique_ptr
<
Array
<
Real
>>
dof1
;
std
::
unique_ptr
<
Array
<
Real
>>
dof2
;
};
template
<
class
T
>
constexpr
DOFManagerType
DOFManagerFixture
<
T
>::
type
;
template
<
class
T
>
constexpr
Int
DOFManagerFixture
<
T
>::
dim
;
TYPED_TEST_SUITE
(
DOFManagerFixture
,
dof_manager_types
,
);
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
Construction
)
{
auto
dof_manager
=
this
->
alloc
();
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
DoubleConstruction
)
{
auto
dof_manager
=
this
->
alloc
();
dof_manager
=
this
->
alloc
();
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
RegisterGenericDOF1
)
{
auto
dof_manager
=
this
->
alloc
();
Array
<
Real
>
dofs
(
this
->
nb_pure_local
,
3
);
dof_manager
->
registerDOFs
(
"dofs1"
,
dofs
,
_dst_generic
);
EXPECT_GE
(
dof_manager
.
residual
().
size
(),
this
->
nb_total_nodes
*
3
);
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
RegisterNodalDOF1
)
{
auto
dof_manager
=
this
->
alloc
();
Array
<
Real
>
dofs
(
this
->
nb_nodes
,
3
);
dof_manager
->
registerDOFs
(
"dofs1"
,
dofs
,
_dst_nodal
);
EXPECT_GE
(
dof_manager
.
residual
().
size
(),
this
->
nb_total_nodes
*
3
);
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
RegisterGenericDOF2
)
{
this
->
registerDOFs
(
_dst_generic
,
_dst_generic
);
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
RegisterNodalDOF2
)
{
this
->
registerDOFs
(
_dst_nodal
,
_dst_nodal
);
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
RegisterMixedDOF
)
{
auto
dof_manager
=
this
->
registerDOFs
(
_dst_nodal
,
_dst_generic
);
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
AssembleVector
)
{
auto
dof_manager
=
this
->
registerDOFs
(
_dst_nodal
,
_dst_generic
);
dof_manager
.
residual
().
zero
();
for
(
auto
&&
data
:
enumerate
(
make_view
(
*
this
->
dof1
,
this
->
dof1
->
getNbComponent
())))
{
auto
n
=
std
::
get
<
0
>
(
data
);
auto
&
l
=
std
::
get
<
1
>
(
data
);
l
.
set
(
1.
*
this
->
mesh
->
isLocalOrMasterNode
(
n
));
}
this
->
dof2
->
set
(
2.
);
dof_manager
->
assembleToResidual
(
"dofs1"
,
*
this
->
dof1
);
dof_manager
->
assembleToResidual
(
"dofs2"
,
*
this
->
dof2
);
this
->
dof1
->
set
(
0.
);
this
->
dof2
->
set
(
0.
);
dof_manager
.
getArrayPerDOFs
(
"dofs1"
,
dof_manager
.
residual
(),
*
this
->
dof1
);
for
(
auto
&&
data
:
enumerate
(
make_view
(
*
this
->
dof1
,
this
->
dof1
->
getNbComponent
())))
{
if
(
this
->
mesh
->
isLocalOrMasterNode
(
std
::
get
<
0
>
(
data
)))
{
const
auto
&
l
=
std
::
get
<
1
>
(
data
);
auto
e
=
(
l
-
Vector
<
Real
>
{
1.
,
1.
,
1.
}).
norm
();
ASSERT_EQ
(
e
,
0.
);
}
}
dof_manager
.
getArrayPerDOFs
(
"dofs2"
,
dof_manager
.
residual
(),
*
this
->
dof2
);
for
(
auto
&&
l
:
make_view
(
*
this
->
dof2
,
this
->
dof2
->
getNbComponent
()))
{
auto
e
=
(
l
-
Vector
<
Real
>
{
2.
,
2.
,
2.
,
2.
,
2.
}).
norm
();
ASSERT_EQ
(
e
,
0.
);
}
}
/* -------------------------------------------------------------------------- */
TYPED_TEST
(
DOFManagerFixture
,
AssembleMatrixNodal
)
{
auto
dof_manager
=
this
->
registerDOFs
(
_dst_nodal
,
_dst_nodal
);
auto
&&
K
=
dof_manager
->
getNewMatrix
(
"K"
,
_symmetric
);
K
.
zero
();
auto
&&
elemental_matrix
=
std
::
make_unique
<
Array
<
Real
>>
(
this
->
mesh
->
getNbElement
(
this
->
dim
),
8
*
3
*
8
*
3
);
for
(
auto
&&
m
:
make_view
(
*
elemental_matrix
,
8
*
3
,
8
*
3
))
{
m
.
set
(
1.
);
}
dof_manager
->
assembleElementalMatricesToMatrix
(
"K"
,
"dofs1"
,
*
elemental_matrix
,
_hexahedron_8
);
elemental_matrix
=
std
::
make_unique
<
Array
<
Real
>>
(
this
->
mesh
->
getNbElement
(
this
->
dim
),
8
*
5
*
8
*
5
);
for
(
auto
&&
m
:
make_view
(
*
elemental_matrix
,
8
*
5
,
8
*
5
))
{
m
.
set
(
1.
);
}
dof_manager
->
assembleElementalMatricesToMatrix
(
"K"
,
"dofs2"
,
*
elemental_matrix
,
_hexahedron_8
);
CSR
<
Element
>
node_to_elem
;
MeshUtils
::
buildNode2Elements
(
*
this
->
mesh
,
node_to_elem
,
this
->
dim
);
dof_manager
.
residual
().
zero
();
for
(
auto
&&
data
:
enumerate
(
zip
(
make_view
(
*
this
->
dof1
,
this
->
dof1
->
getNbComponent
()),
make_view
(
*
this
->
dof2
,
this
->
dof2
->
getNbComponent
()))))
{
auto
n
=
std
::
get
<
0
>
(
data
);
auto
&
l1
=
std
::
get
<
0
>
(
std
::
get
<
1
>
(
data
));
auto
&
l2
=
std
::
get
<
1
>
(
std
::
get
<
1
>
(
data
));
auto
v
=
1.
*
this
->
mesh
->
isLocalOrMasterNode
(
n
);
l1
.
set
(
v
);
l2
.
set
(
v
);
}
dof_manager
->
assembleToResidual
(
"dofs1"
,
*
this
->
dof1
);
dof_manager
->
assembleToResidual
(
"dofs2"
,
*
this
->
dof2
);
for
(
auto
&&
n
:
arange
(
this
->
nb_nodes
))
{
if
(
not
this
->
mesh
->
isLocalOrMasterNode
(
n
))
{
}
}
}
Event Timeline
Log In to Comment