Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F72937634
container_array.hh
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
Wed, Jul 17, 17:06
Size
15 KB
Mime Type
text/x-c++
Expires
Fri, Jul 19, 17:06 (2 d)
Engine
blob
Format
Raw Data
Handle
19120816
Attached To
rLIBMULTISCALE LibMultiScale
container_array.hh
View Options
/**
* @file container_array.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Thu Jul 24 14:21:58 2014
*
* @brief This is the contiguous array-like container for LM
*
* @section LICENSE
*
* Copyright INRIA and CEA
*
* The LibMultiScale is a C++ parallel framework for the multiscale
* coupling methods dedicated to material simulations. This framework
* provides an API which makes it possible to program coupled simulations
* and integration of already existing codes.
*
* This Project was initiated in a collaboration between INRIA Futurs Bordeaux
* within ScAlApplix team and CEA/DPTA Ile de France.
* The project is now continued at the Ecole Polytechnique Fédérale de Lausanne
* within the LSMS/ENAC laboratory.
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*
*/
#ifndef __LIBMULTISCALE_CONTAINER_ARRAY_HH__
#define __LIBMULTISCALE_CONTAINER_ARRAY_HH__
/* -------------------------------------------------------------------------- */
#include "container.hh"
#include <algorithm>
#include <vector>
template
<
typename
Ref
>
class
ReferenceManager
;
/* -------------------------------------------------------------------------- */
#ifdef TRACE_ATOM
#include "lammps/ref_atom_lammps.hh"
#include "trace_atom.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/**
* Class ContainerArray<T>
* array implementation of a generic container
*/
/* -------------------------------------------------------------------------- */
template
<
class
T
>
struct
GetDim
{
static
constexpr
UInt
Dim
=
T
::
Dim
;
inline
UInt
getDim
()
{
return
T
::
Dim
;
}
};
template
<>
struct
GetDim
<
Real
>
{};
template
<>
struct
GetDim
<
UInt
>
{};
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
class
ContainerArrayIterator
;
template
<
typename
T
>
class
ContainerArray
;
template
<
typename
T
>
std
::
enable_if_t
<!
std
::
is_arithmetic
<
T
>::
value
,
UInt
>
getContainerArrayDim
([[
gnu
::
unused
]]
ContainerArray
<
T
>
&
cont
)
{
return
T
::
Dim
;
}
template
<
typename
T
>
std
::
enable_if_t
<
std
::
is_arithmetic
<
T
>::
value
,
UInt
>
getContainerArrayDim
(
ContainerArray
<
T
>
&
cont
)
{
return
cont
.
cols
();
}
/* -------------------------------------------------------------------------- */
template
<
class
T
>
class
ContainerArray
:
public
Container_base
<
T
>
,
public
GetDim
<
T
>
{
public
:
using
ContainerSubSet
=
ContainerArray
<
T
>
;
using
iterator
=
ContainerArrayIterator
<
T
>
;
using
EigenArray
=
Eigen
::
Array
<
T
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
,
Eigen
::
RowMajor
>
;
using
value_type
=
T
;
template
<
typename
OtherDerived
>
ContainerArray
(
const
Eigen
::
EigenBase
<
OtherDerived
>
&
other_array
);
ContainerArray
(
EigenArray
&&
other_array
);
ContainerArray
(
const
LMID
&
id
,
UInt
nrows
=
0
,
UInt
ncols
=
1
);
ContainerArray
(
UInt
nrows
=
0
,
UInt
ncols
=
1
);
ContainerArray
(
ContainerArray
&&
);
ContainerArray
(
ContainerArray
&
);
template
<
typename
OtherDerived
>
ContainerArray
&
operator
=
(
const
Eigen
::
EigenBase
<
OtherDerived
>
&
other
);
ContainerArray
&
operator
=
(
const
ContainerArray
&
);
template
<
typename
Other
>
decltype
(
auto
)
operator
*
(
const
Other
&
other
)
{
return
(
*
_array
)
*
other
;
}
~
ContainerArray
();
auto
array
()
{
return
*
_array
;
};
auto
matrix
()
{
return
_array
->
matrix
();
};
auto
matrix
()
const
{
return
_array
->
matrix
();
};
UInt
getDim
()
{
return
getContainerArrayDim
(
*
this
);
}
void
setZero
()
{
this
->
array_storage
.
setZero
();
}
//! return an associated iterator
virtual
iterator
begin
();
virtual
iterator
end
();
//! sort items
virtual
void
sort
()
override
;
//! search for a given item
virtual
UInt
search
(
T
&
el
)
override
;
//! add a particular item
virtual
void
push_back
(
const
T
&
el
)
override
;
//! add a particular item
template
<
UInt
Dim
>
void
push_back
(
const
Array1D
<
Dim
>
&
el
);
template
<
UInt
Dim
>
void
push_back
(
const
Vector
<
Dim
,
T
>
&
el
);
template
<
UInt
Dim
>
void
push_back
(
const
VectorView
<
Dim
,
T
>
el
);
void
push_back
(
const
Eigen
::
Ref
<
const
Eigen
::
ArrayXd
>
&
el
);
//! resize the container (by clearing the additional values)
virtual
void
resize
(
UInt
nrows
,
UInt
ncols
=
-
1
);
//! assign all values up to size to a single value
virtual
void
assign
(
UInt
size
,
T
val
);
//! get an item from its index
inline
T
&
get
(
UInt
index
)
override
;
//! get an item from its index
inline
T
&
operator
[](
UInt
index
)
override
;
//! return the number of contained items
virtual
UInt
size
()
override
;
//! return the number of columns in the array
UInt
cols
()
const
{
return
_array
->
cols
();
};
//! return the number of columns in the array
UInt
rows
()
const
{
return
_array
->
rows
();
};
//! return a row by its index
auto
row
(
UInt
row
)
{
return
_array
->
row
(
row
);
};
//! function that clear the container
virtual
void
clear
();
//! return the element from its index
decltype
(
auto
)
operator
()(
UInt
i
)
{
return
_array
->
row
(
i
);
};
T
&
operator
()(
UInt
i
,
UInt
j
)
{
return
_array
->
operator
()(
i
,
j
);
};
template
<
typename
V
>
auto
&
operator
+=
(
V
&&
v
)
{
*
this
->
_array
+=
v
;
return
*
this
;
}
//! access to raw pointer
T
*
data
()
{
return
array_storage
.
data
();
}
//! shift access to raw pointer
auto
shift
(
UInt
index
,
UInt
size
)
{
return
Eigen
::
Map
<
EigenArray
>
(
&
array_storage
(
index
,
0
),
size
,
_array
->
cols
());
}
decltype
(
auto
)
rowwise
()
{
return
_array
->
rowwise
();
}
private
:
EigenArray
array_storage
;
std
::
unique_ptr
<
Eigen
::
Map
<
EigenArray
>>
_array
;
};
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#include "iterator_array.hh"
#include "reference_manager.hh"
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
ContainerArray
<
T
>::
ContainerArray
(
const
LMID
&
id
,
UInt
nrows
,
UInt
ncols
)
:
LMObject
(
id
),
Container_base
<
T
>
()
{
DUMP
(
"creating array: "
<<
id
<<
" : "
<<
this
<<
" : "
<<
&
(
this
->
array_storage
)
<<
" : "
<<
this
->
array_storage
.
data
(),
DBG_INFO
);
this
->
resize
(
nrows
,
ncols
);
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
ContainerArray
<
T
>::
ContainerArray
(
UInt
nrows
,
UInt
ncols
)
:
LMObject
(
"anonymous"
),
Container_base
<
T
>
()
{
DUMP
(
"creating array: "
<<
this
->
getID
()
<<
" : "
<<
this
<<
" : "
<<
&
(
this
->
array_storage
)
<<
" : "
<<
this
->
array_storage
.
data
(),
DBG_INFO
);
this
->
resize
(
nrows
,
ncols
);
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
template
<
typename
OtherDerived
>
ContainerArray
<
T
>::
ContainerArray
(
const
Eigen
::
EigenBase
<
OtherDerived
>
&
other
)
:
LMObject
(
"anonymous"
),
Container_base
<
T
>
()
{
DUMP
(
"copying array: "
<<
this
->
getID
()
<<
" : "
<<
this
,
DBG_MESSAGE
);
this
->
resize
(
other
.
rows
(),
other
.
cols
());
this
->
array_storage
=
other
;
_array
=
std
::
make_unique
<
Eigen
::
Map
<
EigenArray
>>
(
array_storage
.
data
(),
other
.
rows
(),
other
.
cols
());
}
template
<
typename
T
>
ContainerArray
<
T
>::
ContainerArray
(
ContainerArray
&&
other
)
:
LMObject
(
other
.
getID
())
{
this
->
array_storage
=
std
::
move
(
other
.
array_storage
);
DUMP
(
"move array: "
<<
this
->
getID
()
<<
" : "
<<
this
<<
" : "
<<
&
(
this
->
array_storage
)
<<
" : "
<<
this
->
array_storage
.
data
(),
DBG_INFO
);
_array
=
std
::
make_unique
<
Eigen
::
Map
<
EigenArray
>>
(
array_storage
.
data
(),
other
.
rows
(),
other
.
cols
());
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
ContainerArray
<
T
>::
ContainerArray
(
ContainerArray
&
other
)
:
LMObject
(
other
.
getID
())
{
DUMP
(
"copying array: "
<<
this
->
getID
()
<<
" : "
<<
this
,
DBG_MESSAGE
);
this
->
array_storage
=
other
.
array_storage
;
_array
=
std
::
make_unique
<
Eigen
::
Map
<
EigenArray
>>
(
array_storage
.
data
(),
other
.
rows
(),
other
.
cols
());
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
ContainerArray
<
T
>
&
ContainerArray
<
T
>::
operator
=
(
const
ContainerArray
&
other
)
{
this
->
array_storage
=
other
.
array_storage
;
_array
=
std
::
make_unique
<
Eigen
::
Map
<
EigenArray
>>
(
array_storage
.
data
(),
other
.
rows
(),
other
.
cols
());
return
*
this
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
template
<
typename
OtherDerived
>
ContainerArray
<
T
>
&
ContainerArray
<
T
>::
operator
=
(
const
Eigen
::
EigenBase
<
OtherDerived
>
&
other
)
{
this
->
array_storage
=
other
;
_array
=
std
::
make_unique
<
Eigen
::
Map
<
EigenArray
>>
(
array_storage
.
data
(),
other
.
rows
(),
other
.
cols
());
return
*
this
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
ContainerArray
<
T
>::~
ContainerArray
()
{
DUMP
(
"destroy array: "
<<
this
->
getID
()
<<
" : "
<<
this
<<
" : "
<<
&
(
this
->
array_storage
),
DBG_INFO
);
clear
();
if
(
this
->
hasRefManager
())
{
this
->
getRefManager
()
->
removeSubSet
(
this
->
getID
());
}
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
void
ContainerArray
<
T
>::
sort
()
{
// std::sort(array.begin(),array.end());
LM_TOIMPLEMENT
;
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
UInt
ContainerArray
<
T
>::
size
()
{
return
_array
->
size
();
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
void
ContainerArray
<
T
>::
clear
()
{
array_storage
.
resize
(
0
,
this
->
cols
());
_array
=
std
::
make_unique
<
Eigen
::
Map
<
EigenArray
>>
(
array_storage
.
data
(),
0
,
this
->
cols
());
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
void
ContainerArray
<
T
>::
resize
(
UInt
nrows
,
UInt
ncols
)
{
if
(
ncols
==
UInt
(
-
1
))
ncols
=
_array
->
cols
();
if
(
_array
&&
(
_array
->
rows
()
>
0
)
&&
(
_array
->
cols
()
!=
ncols
))
LM_FATAL
(
this
->
getID
()
<<
": cannot change the number of columns if the vector is full ("
<<
nrows
<<
" , "
<<
ncols
<<
" != "
<<
_array
->
cols
()
<<
")"
);
while
(
nrows
>
array_storage
.
rows
())
{
array_storage
.
conservativeResize
(
1
+
array_storage
.
rows
()
*
2
,
ncols
);
}
_array
=
std
::
make_unique
<
Eigen
::
Map
<
EigenArray
>>
(
array_storage
.
data
(),
nrows
,
ncols
);
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
void
ContainerArray
<
T
>::
assign
(
UInt
size
,
T
val
)
{
this
->
resize
(
size
);
*
_array
=
val
;
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
void
ContainerArray
<
T
>::
push_back
(
const
Eigen
::
Ref
<
const
Eigen
::
ArrayXd
>
&
el
)
{
auto
row
=
_array
->
rows
();
this
->
resize
(
row
+
1
);
_array
->
row
(
row
)
=
el
;
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
void
ContainerArray
<
T
>::
push_back
(
const
T
&
el
)
{
if
(
_array
->
cols
()
>
1
)
LM_FATAL
(
"cannot add a single scalar with push_back in an array having "
"more than one column"
);
auto
row
=
_array
->
rows
();
this
->
resize
(
row
+
1
);
_array
->
row
(
row
)
=
el
;
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
template
<
UInt
Dim
>
inline
void
ContainerArray
<
T
>::
push_back
(
const
Array1D
<
Dim
>
&
arr
)
{
auto
row
=
_array
->
rows
();
this
->
resize
(
row
+
1
);
_array
->
row
(
row
)
=
arr
.
transpose
();
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
template
<
UInt
Dim
>
inline
void
ContainerArray
<
T
>::
push_back
(
const
Vector
<
Dim
,
T
>
&
arr
)
{
auto
row
=
_array
->
rows
();
this
->
resize
(
row
+
1
);
_array
->
row
(
row
)
=
arr
.
transpose
();
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
template
<
UInt
Dim
>
inline
void
ContainerArray
<
T
>::
push_back
(
const
VectorView
<
Dim
,
T
>
arr
)
{
auto
row
=
_array
->
rows
();
this
->
resize
(
row
+
1
);
_array
->
row
(
row
)
=
arr
.
transpose
();
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
T
&
ContainerArray
<
T
>::
get
(
UInt
index
)
{
LM_ASSERT
(
index
<
size
(),
"out of range access : "
<<
index
<<
" over "
<<
size
()
<<
" for "
<<
this
->
getID
());
using
EigenArray1
=
Eigen
::
Array
<
T
,
Eigen
::
Dynamic
,
1u
>
;
Eigen
::
Map
<
EigenArray1
>
view
(
_array
->
data
(),
this
->
size
());
return
view
(
index
);
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
inline
T
&
ContainerArray
<
T
>::
operator
[](
UInt
index
)
{
LM_ASSERT
(
index
<
size
(),
"out of range access : "
<<
index
<<
" over "
<<
size
());
return
this
->
get
(
index
);
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
UInt
ContainerArray
<
T
>::
search
(
T
&
el
)
{
for
(
UInt
i
=
0
;
i
<
size
();
++
i
)
{
T
&
e
=
this
->
get
(
i
);
if
(
el
==
e
)
return
i
;
}
return
UINT_MAX
;
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
auto
ContainerArray
<
T
>::
begin
()
->
iterator
{
return
iterator
(
_array
->
data
());
}
/* ------------------------------------------------------------------------ */
template
<
class
T
>
auto
ContainerArray
<
T
>::
end
()
->
iterator
{
return
iterator
(
_array
->
data
()
+
this
->
size
());
}
/* ------------------------------------------------------------------------ */
template
<
typename
T
>
decltype
(
auto
)
operator
/
(
Real
val
,
ContainerArray
<
T
>
&
c
)
{
return
val
/
c
.
array
();
}
/* ------------------------------------------------------------------------ */
template
<
typename
T
>
decltype
(
auto
)
operator
*
(
Real
val
,
ContainerArray
<
T
>
&
c
)
{
return
val
*
c
.
array
();
}
inline
decltype
(
auto
)
operator
-
(
ContainerArray
<
Real
>
&
v
)
{
return
-
v
.
array
();
}
__END_LIBMULTISCALE__
#endif
/* __LIBMULTISCALE_CONTAINER_ARRAY_HH__ */
Event Timeline
Log In to Comment