Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F65459691
grid_hermitian.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
Mon, Jun 3, 23:10
Size
5 KB
Mime Type
text/x-c++
Expires
Wed, Jun 5, 23:10 (2 d)
Engine
blob
Format
Raw Data
Handle
17935925
Attached To
rTAMAAS tamaas
grid_hermitian.hh
View Options
/**
* @file
* @section LICENSE
*
* Copyright (©) 2016-2020 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __GRID_HERMITIAN_HH__
#define __GRID_HERMITIAN_HH__
/* -------------------------------------------------------------------------- */
#include "grid.hh"
#include "tamaas.hh"
#include <complex>
#include <type_traits>
#include <vector>
/* -------------------------------------------------------------------------- */
namespace
tamaas
{
static
complex
<
Real
>
dummy
;
/**
* @brief Multi-dimensional, multi-component herimitian array
*
* This class represents an array of hermitian data, meaning it has dimensions
* of: n1 * n2 * n3 * ... * (nx / 2 + 1)
*
* However, it acts as a fully dimensioned array, returning a dummy reference
* for data outside its real dimension, allowing one to write full (and
* inefficient) loops without really worrying about the reduced dimension.
*
* It would however be better to just use the true dimensions of the surface
* for all intents and purposes, as it saves computation time.
*/
template
<
typename
T
,
UInt
dim
>
class
GridHermitian
:
public
Grid
<
complex
<
T
>
,
dim
>
{
public
:
using
value_type
=
complex
<
T
>
;
/* ------------------------------------------------------------------------ */
/* Constructors */
/* ------------------------------------------------------------------------ */
public
:
GridHermitian
()
=
default
;
GridHermitian
(
const
GridHermitian
&
o
)
=
default
;
GridHermitian
(
GridHermitian
&&
o
)
noexcept
=
default
;
using
Grid
<
value_type
,
dim
>::
Grid
;
using
Grid
<
complex
<
T
>
,
dim
>::
operator
=
;
/* ------------------------------------------------------------------------ */
/* Access operators */
/* ------------------------------------------------------------------------ */
template
<
typename
...
T1
>
inline
complex
<
T
>&
operator
()(
T1
...
args
);
template
<
typename
...
T1
>
inline
const
complex
<
T
>&
operator
()(
T1
...
args
)
const
;
static
std
::
array
<
UInt
,
dim
>
hermitianDimensions
(
std
::
array
<
UInt
,
dim
>
n
)
{
n
[
dim
-
1
]
/=
2
;
n
[
dim
-
1
]
+=
1
;
return
n
;
}
template
<
typename
Int
,
typename
=
std
::
enable_if_t
<
std
::
is_arithmetic
<
Int
>::
value
>>
static
std
::
vector
<
Int
>
hermitianDimensions
(
std
::
vector
<
Int
>
n
)
{
n
.
back
()
/=
2
;
n
.
back
()
+=
1
;
return
n
;
}
private
:
template
<
typename
...
T1
>
inline
void
packTuple
(
UInt
*
t
,
UInt
i
,
T1
...
args
)
const
;
template
<
typename
...
T1
>
inline
void
packTuple
(
UInt
*
t
,
UInt
i
)
const
;
};
/* -------------------------------------------------------------------------- */
/* Inline function definitions */
/* -------------------------------------------------------------------------- */
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
void
GridHermitian
<
T
,
dim
>::
packTuple
(
UInt
*
t
,
UInt
i
,
T1
...
args
)
const
{
*
t
=
i
;
packTuple
(
t
+
1
,
args
...);
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
void
GridHermitian
<
T
,
dim
>::
packTuple
(
UInt
*
t
,
UInt
i
)
const
{
*
t
=
i
;
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
complex
<
T
>&
GridHermitian
<
T
,
dim
>::
operator
()(
T1
...
args
)
{
constexpr
UInt
nargs
=
sizeof
...(
T1
);
static_assert
(
nargs
<=
dim
+
1
,
"Too many arguments"
);
UInt
last_index
=
std
::
get
<
nargs
-
1
>
(
std
::
forward_as_tuple
(
args
...));
if
(
nargs
!=
1
&&
last_index
>=
this
->
n
[
dim
-
1
])
{
std
::
array
<
UInt
,
dim
+
1
>
tuple
=
{{
0
}};
packTuple
(
tuple
.
data
(),
args
...);
for
(
UInt
i
=
0
;
i
<
dim
;
i
++
)
{
if
(
tuple
[
i
]
&&
i
!=
dim
-
1
)
tuple
[
i
]
=
this
->
n
[
i
]
-
tuple
[
i
];
else
if
(
tuple
[
i
]
&&
i
==
dim
-
1
)
tuple
[
i
]
=
2
*
(
this
->
n
[
i
]
-
1
)
-
tuple
[
i
];
}
dummy
=
conj
(
this
->
Grid
<
complex
<
T
>
,
dim
>::
operator
()(
tuple
));
return
dummy
;
}
else
return
Grid
<
complex
<
T
>
,
dim
>::
operator
()(
args
...);
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
const
complex
<
T
>&
GridHermitian
<
T
,
dim
>::
operator
()(
T1
...
args
)
const
{
constexpr
UInt
nargs
=
sizeof
...(
T1
);
static_assert
(
nargs
<=
dim
+
1
,
"Too many arguments"
);
UInt
last_index
=
std
::
get
<
nargs
-
1
>
(
std
::
forward_as_tuple
(
args
...));
if
(
nargs
!=
1
&&
last_index
>=
this
->
n
[
dim
-
1
])
{
std
::
array
<
UInt
,
dim
+
1
>
tuple
=
{{
0
}};
packTuple
(
tuple
.
data
(),
args
...);
for
(
UInt
i
=
0
;
i
<
dim
;
i
++
)
{
if
(
tuple
[
i
]
&&
i
!=
dim
-
1
)
tuple
[
i
]
=
this
->
n
[
i
]
-
tuple
[
i
];
else
if
(
tuple
[
i
]
&&
i
==
dim
-
1
)
tuple
[
i
]
=
2
*
(
this
->
n
[
i
]
-
1
)
-
tuple
[
i
];
}
dummy
=
conj
(
this
->
Grid
<
complex
<
T
>
,
dim
>::
operator
()(
tuple
));
return
dummy
;
}
else
return
Grid
<
complex
<
T
>
,
dim
>::
operator
()(
args
...);
}
}
// namespace tamaas
#endif
// __GRID_HERMITIAN_HH__
Event Timeline
Log In to Comment