Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F90454715
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
Fri, Nov 1, 20:33
Size
5 KB
Mime Type
text/x-c++
Expires
Sun, Nov 3, 20:33 (2 d)
Engine
blob
Format
Raw Data
Handle
22079094
Attached To
rTAMAAS tamaas
grid_hermitian.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_HERMITIAN_HH__
#define __GRID_HERMITIAN_HH__
/* -------------------------------------------------------------------------- */
#include "tamaas.hh"
#include "grid.hh"
#include <vector>
#include <complex>
/* -------------------------------------------------------------------------- */
__BEGIN_TAMAAS__
static
std
::
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
<
std
::
complex
<
T
>
,
dim
>
{
public
:
typedef
std
::
complex
<
T
>
value_type
;
/* -------------------------------------------------------------------------- */
/* Constructors */
/* -------------------------------------------------------------------------- */
public
:
GridHermitian
()
=
default
;
GridHermitian
(
const
GridHermitian
&
o
)
=
default
;
GridHermitian
(
GridHermitian
&&
o
)
=
default
;
using
Grid
<
value_type
,
dim
>::
Grid
;
using
Grid
<
std
::
complex
<
T
>
,
dim
>::
operator
=
;
/* -------------------------------------------------------------------------- */
/* Access operators */
/* -------------------------------------------------------------------------- */
template
<
typename
...
T1
>
inline
std
::
complex
<
T
>
&
operator
()(
T1
...
args
);
template
<
typename
...
T1
>
inline
const
std
::
complex
<
T
>
&
operator
()(
T1
...
args
)
const
;
static
std
::
array
<
UInt
,
dim
>
hermitianDimensions
(
const
std
::
array
<
UInt
,
dim
>
&
n
)
{
std
::
array
<
UInt
,
dim
>
hn
(
n
);
hn
[
dim
-
1
]
/=
2
;
hn
[
dim
-
1
]
+=
1
;
return
hn
;
}
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
std
::
complex
<
T
>
&
GridHermitian
<
T
,
dim
>::
operator
()(
T1
...
args
)
{
TAMAAS_ASSERT
(
sizeof
...(
T1
)
==
dim
+
1
||
sizeof
...(
T1
)
==
1
,
"operator() does not match dimension"
);
if
(
sizeof
...(
T1
)
==
1
&&
dim
!=
1
)
{
UInt
tuple
[
1
]
=
{
0
};
packTuple
(
tuple
,
args
...);
if
(
tuple
[
0
]
>=
this
->
data
.
size
())
{
TAMAAS_DEBUG_EXCEPTION
(
"out of bonds access on hermitian surface"
);
dummy
=
std
::
complex
<
T
>
(
0
,
0
);
return
dummy
;
}
else
return
this
->
Grid
<
std
::
complex
<
T
>
,
dim
>::
operator
()(
args
...);
}
std
::
array
<
UInt
,
dim
+
1
>
tuple
=
{{
0
}};
packTuple
(
tuple
.
data
(),
args
...);
// reverse tuple if necessary
if
(
tuple
[
dim
-
1
]
>=
this
->
n
[
dim
-
1
])
{
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
=
std
::
conj
(
this
->
Grid
<
std
::
complex
<
T
>
,
dim
>::
operator
()(
tuple
));
return
dummy
;
}
else
{
return
this
->
Grid
<
std
::
complex
<
T
>
,
dim
>::
operator
()(
tuple
);
}
}
template
<
typename
T
,
UInt
dim
>
template
<
typename
...
T1
>
inline
const
std
::
complex
<
T
>
&
GridHermitian
<
T
,
dim
>::
operator
()(
T1
...
args
)
const
{
TAMAAS_ASSERT
(
sizeof
...(
T1
)
==
dim
+
1
||
sizeof
...(
T1
)
==
1
,
"operator() does not match dimension"
);
if
(
sizeof
...(
T1
)
==
1
&&
dim
!=
1
)
{
UInt
tuple
[
1
]
=
{
0
};
packTuple
(
tuple
,
args
...);
if
(
tuple
[
0
]
>=
this
->
data
.
size
())
{
TAMAAS_DEBUG_EXCEPTION
(
"out of bonds access on hermitian surface"
);
dummy
=
std
::
complex
<
T
>
(
0
,
0
);
return
dummy
;
}
else
return
this
->
Grid
<
std
::
complex
<
T
>
,
dim
>::
operator
()(
args
...);
}
std
::
array
<
UInt
,
dim
+
1
>
tuple
=
{
0
};
packTuple
(
tuple
.
data
(),
args
...);
// reverse tuple if necessary
if
(
tuple
[
dim
-
1
]
>=
this
->
n
[
dim
-
1
])
{
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
=
std
::
conj
(
this
->
Grid
<
std
::
complex
<
T
>
,
dim
>::
operator
()(
tuple
));
return
dummy
;
}
else
{
return
this
->
Grid
<
std
::
complex
<
T
>
,
dim
>::
operator
()(
tuple
);
}
}
__END_TAMAAS__
#endif
// __GRID_HERMITIAN_HH__
Event Timeline
Log In to Comment