Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F65467740
grid.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
Tue, Jun 4, 00:31
Size
10 KB
Mime Type
text/x-c++
Expires
Thu, Jun 6, 00:31 (2 d)
Engine
blob
Format
Raw Data
Handle
18044579
Attached To
rTAMAAS tamaas
grid.hh
View Options
/**
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @section LICENSE
*
* Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Tamaas 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.
*
* Tamaas 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 Tamaas. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __GRID_HH__
#define __GRID_HH__
/* -------------------------------------------------------------------------- */
#include "tamaas.hh"
#include "grid_base.hh"
#include <array>
#include <vector>
/* -------------------------------------------------------------------------- */
__BEGIN_TAMAAS__
/**
* @brief Multi-dimensional & multi-component array class
*
* This class is a container for multi-component data stored on a multi-
* dimensional grid.
*
* The access function is the parenthesis operator. For a grid of dimension d,
* the operator takes d+1 arguments: the first d arguments are the position on
* the grid and the last one is the component of the stored data.
*
* It is also possible to use the access operator with only one argument, it is
* then considering the grid as a flat array, accessing the given cell of the
* array.
*/
template
<
typename
T
,
UInt
dim
>
class
Grid
:
public
GridBase
<
T
>
{
public
:
typedef
T
storage_type
;
static
constexpr
UInt
dimension
=
dim
;
/* -------------------------------------------------------------------------- */
/* Constructors */
/* -------------------------------------------------------------------------- */
public
:
/// Constructor by default (empty array)
Grid
();
/// Constructor
Grid
(
const
std
::
array
<
UInt
,
dim
>
&
n
,
UInt
nb_components
);
/// Constructor with vectors
Grid
(
const
std
::
vector
<
UInt
>
&
n
,
UInt
nb_components
);
/// Destructor
virtual
~
Grid
();
private
:
/// Init function
template
<
typename
T1
>
void
init
(
const
T1
&
n
,
UInt
nb_components
);
public
:
/* -------------------------------------------------------------------------- */
/* Common operations */
/* -------------------------------------------------------------------------- */
/// Resize array
void
resize
(
const
std
::
array
<
UInt
,
dim
>
&
n
);
/// Compute size
inline
UInt
computeSize
()
const
;
/// Print
void
printself
(
std
::
ostream
&
str
)
const
;
/// Get sizes
const
std
::
array
<
UInt
,
dim
>
&
sizes
()
const
{
return
n
;}
/// Get total size
UInt
dataSize
()
const
{
return
this
->
data
.
size
();
}
/// Get number of points
UInt
getNbPoints
()
const
{
return
dataSize
()
/
this
->
getNbComponents
();
}
/// Set components
void
uniformSetComponents
(
const
Grid
<
T
,
1
>
&
vec
);
/* -------------------------------------------------------------------------- */
/* Access operators */
/* -------------------------------------------------------------------------- */
/// Variadic access operator (non-const)
template
<
typename
...
T1
>
inline
T
&
operator
()(
T1
...
args
);
/// Variadic access operator
template
<
typename
...
T1
>
inline
const
T
&
operator
()(
T1
...
args
)
const
;
/// Tuple index access operator
inline
T
&
operator
()(
UInt
tuple
[
dim
+
1
]);
inline
const
T
&
operator
()(
UInt
tuple
[
dim
+
1
])
const
;
private
:
/// Unpacking the arguments of variadic () operator when nargs == dim+1
template
<
typename
...
T1
>
inline
UInt
unpackOffset
(
UInt
offset
,
UInt
index
,
T1
...
rest
)
const
;
/// End case for recursion
template
<
typename
...
T1
>
inline
UInt
unpackOffset
(
UInt
offset
,
UInt
index
)
const
;
template
<
typename
...
T1
>
/// Unpacking the arguments of variadic () operator when nargs == dim (for nb_components == 1)
inline
UInt
unpackOffsetReduced
(
UInt
offset
,
UInt
index
,
T1
...
rest
)
const
;
template
<
typename
...
T1
>
/// End case for recursion
inline
UInt
unpackOffsetReduced
(
UInt
offset
,
UInt
index
)
const
;
/// Computing offset for a tuple index
inline
UInt
computeOffset
(
UInt
tuple
[
dim
+
1
])
const
;
/* -------------------------------------------------------------------------- */
/* Arithmetic operators */
/* -------------------------------------------------------------------------- */
public
:
#define GRID_VEC_OPERATOR(op) \
template <typename T1> \
void operator op(const Grid<T1, dim> & other) \
GRID_VEC_OPERATOR
(
+=
);
GRID_VEC_OPERATOR
(
*=
);
GRID_VEC_OPERATOR
(
-=
);
GRID_VEC_OPERATOR
(
/=
);
#undef GRID_VEC_OPERATOR
#define GRID_SCALAR_OPERATOR(op) \
void operator op(const T & e) \
GRID_SCALAR_OPERATOR
(
+=
);
GRID_SCALAR_OPERATOR
(
*=
);
GRID_SCALAR_OPERATOR
(
-=
);
GRID_SCALAR_OPERATOR
(
/=
);
GRID_SCALAR_OPERATOR
(
=
);
#undef GRID_SCALAR_OPERATOR
// = operator
void
operator
=
(
const
Grid
<
T
,
dim
>
&
other
);
// = operator (not const input, otherwise gcc is confused)
void
operator
=
(
Grid
<
T
,
dim
>
&
other
);
// Copy data from another grid
template
<
typename
T1
>
void
copy
(
const
Grid
<
T1
,
dim
>
&
other
);
/* -------------------------------------------------------------------------- */
/* Member variables */
/* -------------------------------------------------------------------------- */
protected
:
std
::
array
<
UInt
,
dim
>
n
;
};
/* -------------------------------------------------------------------------- */
/* Inline/template function definitions */
/* -------------------------------------------------------------------------- */
template
<
typename
T
,
UInt
dim
>
template
<
typename
T1
>
void
Grid
<
T
,
dim
>::
init
(
const
T1
&
n
,
UInt
nb_components
)
{
std
::
copy
(
n
.
begin
(),
n
.
end
(),
this
->
n
.
begin
());
this
->
nb_components
=
nb_components
;
this
->
resize
(
this
->
n
);
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
,
UInt
dim
>
inline
UInt
Grid
<
T
,
dim
>::
computeSize
()
const
{
UInt
size
=
1
;
for
(
UInt
i
=
0
;
i
<
dim
;
i
++
)
size
*=
n
[
i
];
size
*=
this
->
nb_components
;
return
size
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
UInt
Grid
<
T
,
dim
>::
unpackOffset
(
UInt
offset
,
UInt
index
,
T1
...
rest
)
const
{
UInt
size
=
sizeof
...(
T1
);
offset
+=
index
;
offset
*=
(
size
==
1
)
?
this
->
nb_components
:
this
->
n
[
dim
-
size
+
1
];
return
unpackOffset
(
offset
,
rest
...);
// tail-rec bb
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
UInt
Grid
<
T
,
dim
>::
unpackOffset
(
UInt
offset
,
UInt
index
)
const
{
return
offset
+
index
;
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
UInt
Grid
<
T
,
dim
>::
unpackOffsetReduced
(
UInt
offset
,
UInt
index
,
T1
...
rest
)
const
{
UInt
size
=
sizeof
...(
T1
);
offset
+=
index
;
offset
*=
this
->
n
[
dim
-
size
-
1
];
return
unpackOffsetReduced
(
offset
,
rest
...);
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
UInt
Grid
<
T
,
dim
>::
unpackOffsetReduced
(
UInt
offset
,
UInt
index
)
const
{
return
unpackOffset
(
offset
,
index
);
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
T
&
Grid
<
T
,
dim
>::
operator
()(
T1
...
args
)
{
TAMAAS_ASSERT
(
sizeof
...(
T1
)
==
dim
+
1
||
sizeof
...(
T1
)
==
1
||
(
sizeof
...(
T1
)
==
dim
&&
this
->
nb_components
==
1
),
"operator() does not match dimension"
);
UInt
offset
=
(
sizeof
...(
T1
)
==
dim
)
?
unpackOffsetReduced
(
0
,
args
...)
:
unpackOffset
(
0
,
args
...);
return
this
->
data
[
offset
];
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
const
T
&
Grid
<
T
,
dim
>::
operator
()(
T1
...
args
)
const
{
TAMAAS_ASSERT
(
sizeof
...(
T1
)
==
dim
+
1
||
sizeof
...(
T1
)
==
1
||
(
sizeof
...(
T1
)
==
dim
&&
this
->
nb_components
==
1
),
"operator() does not match dimension"
);
UInt
offset
=
(
sizeof
...(
T1
)
==
dim
)
?
unpackOffsetReduced
(
0
,
args
...)
:
unpackOffset
(
0
,
args
...);
return
this
->
data
[
offset
];
}
template
<
typename
T
,
UInt
dim
>
inline
UInt
Grid
<
T
,
dim
>::
computeOffset
(
UInt
tuple
[
dim
+
1
])
const
{
UInt
offset
=
0
;
for
(
UInt
i
=
0
;
i
<
dim
-
1
;
i
++
)
{
offset
+=
tuple
[
i
];
offset
*=
n
[
i
+
1
];
}
offset
+=
tuple
[
dim
-
1
];
offset
*=
this
->
nb_components
;
return
offset
+
tuple
[
dim
];
}
template
<
typename
T
,
UInt
dim
>
inline
T
&
Grid
<
T
,
dim
>::
operator
()(
UInt
tuple
[
dim
+
1
])
{
UInt
offset
=
computeOffset
(
tuple
);
return
this
->
data
[
offset
];
}
template
<
typename
T
,
UInt
dim
>
inline
const
T
&
Grid
<
T
,
dim
>::
operator
()(
UInt
tuple
[
dim
+
1
])
const
{
UInt
offset
=
computeOffset
(
tuple
);
return
this
->
data
[
offset
];
}
/* -------------------------------------------------------------------------- */
#define GRID_VEC_OPERATOR_IMPL(op) \
template <typename T, UInt dim> \
template <typename T1> \
inline void Grid<T, dim>::operator op(const Grid<T1, dim> & other) { \
TAMAAS_ASSERT(other.computeSize() == this->data.size(), "surface size does not match");\
_Pragma("omp parallel for") \
for (UInt i = 0 ; i < this->data.size() ; i++) { \
this->data[i] op other(i); \
} \
} \
GRID_VEC_OPERATOR_IMPL
(
+=
);
GRID_VEC_OPERATOR_IMPL
(
-=
);
GRID_VEC_OPERATOR_IMPL
(
*=
);
GRID_VEC_OPERATOR_IMPL
(
/=
);
#undef GRID_VEC_OPERATOR
/* -------------------------------------------------------------------------- */
template
<
typename
T
,
UInt
dim
>
void
Grid
<
T
,
dim
>::
operator
=
(
const
Grid
<
T
,
dim
>
&
other
)
{
this
->
copy
(
other
);
}
template
<
typename
T
,
UInt
dim
>
void
Grid
<
T
,
dim
>::
operator
=
(
Grid
<
T
,
dim
>
&
other
)
{
this
->
copy
(
other
);
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
,
UInt
dim
>
template
<
typename
T1
>
void
Grid
<
T
,
dim
>::
copy
(
const
Grid
<
T1
,
dim
>
&
other
)
{
resize
(
other
.
sizes
());
#pragma omp parallel for
for
(
UInt
i
=
0
;
i
<
this
->
data
.
size
()
;
i
++
)
this
->
data
[
i
]
=
other
(
i
);
}
/* -------------------------------------------------------------------------- */
/* Stream operator */
/* -------------------------------------------------------------------------- */
template
<
typename
T
,
UInt
dim
>
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
stream
,
const
Grid
<
T
,
dim
>
&
_this
)
{
_this
.
printself
(
stream
);
return
stream
;
}
/* -------------------------------------------------------------------------- */
__END_TAMAAS__
#endif
// __GRID_HH__
Event Timeline
Log In to Comment