Page MenuHomec4science

surface_complex.hh
No OneTemporary

File Metadata

Created
Sun, Jun 2, 01:54

surface_complex.hh

/**
* @file
* @section LICENSE
*
* Copyright (©) 2016-19 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 SURFACE_COMPLEX_H
#define SURFACE_COMPLEX_H
/* -------------------------------------------------------------------------- */
#include "grid_hermitian.hh"
#include "surface.hh"
#include <thrust/complex.h>
namespace tamaas {
/**
* @deprecated should use GridHermitian instead
* @brief Square 2D complex surface
*/
template <typename T>
class SurfaceComplex : public GridHermitian<T, 2> {
public:
SurfaceComplex(UInt a, Real L);
using GridHermitian<T, 2>::GridHermitian;
using GridHermitian<T, 2>::operator=;
using GridHermitian<T, 2>::operator();
//! make a surface real by taking norm as real part and imaginary 0
void makeItRealBySquare();
//! make it real by summing the imaginary and real parts
void makeItRealBySum();
//! make a surface real by taking norm as real part and imaginary 0
void makeItRealByAbs();
//! get real part
Surface<T> real() const;
//! get imaginary part
Surface<T> imag() const;
UInt size() const { return this->n[0]; }
UInt getL() const { return 1.; }
void setGridSize(UInt s);
virtual const SurfaceComplex<T>& getWrappedNumpy() { return *this; };
#define SURF_OPERATOR(op) \
inline void operator op(const Surface<T>& other); \
inline void operator op(const SurfaceComplex<T>& other)
SURF_OPERATOR(+=);
SURF_OPERATOR(*=);
SURF_OPERATOR(-=);
SURF_OPERATOR(/=);
#undef SURF_OPERATOR
};
/* -------------------------------------------------------------------------- */
template <typename T>
void SurfaceComplex<T>::setGridSize(UInt s) {
this->n[0] = s;
this->n[1] = s / 2 + 1;
this->resize(this->n);
}
/* -------------------------------------------------------------------------- */
template <typename T>
Surface<T> SurfaceComplex<T>::real() const {
Surface<T> res(this->size(), this->getL());
UInt n = this->size();
for (UInt i = 0; i < n; ++i)
for (UInt j = 0; j < n; ++j) {
res(i, j) = (*this)(i, j).real();
}
return res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
Surface<T> SurfaceComplex<T>::imag() const {
Surface<T> res(this->size(), this->getL());
UInt n = this->size();
for (UInt i = 0; i < n; ++i)
for (UInt j = 0; j < n; ++j) {
res(i, j) = (*this)(i, j).imag();
}
return res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
void SurfaceComplex<T>::makeItRealBySquare() {
Loop::loop([] CUDA_LAMBDA(complex<T> & x) { x *= thrust::conj(x); }, *this);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void SurfaceComplex<T>::makeItRealByAbs() {
Loop::loop([] CUDA_LAMBDA(complex<T> & x) { x = thrust::abs(x); }, *this);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void SurfaceComplex<T>::makeItRealBySum() {
Loop::loop([] CUDA_LAMBDA(complex<T> & x) { x = x.real() + x.imag(); },
*this);
}
/* -------------------------------------------------------------------------- */
template <typename T>
SurfaceComplex<T>::SurfaceComplex(UInt a, Real /*L*/) : GridHermitian<T, 2>() {
this->n = GridHermitian<T, 2>::hermitianDimensions(std::array<UInt, 2>{a, a});
this->resize(this->n);
}
/* -------------------------------------------------------------------------- */
#define SURF_OP_IMPL(op) \
template <typename T> \
inline void SurfaceComplex<T>::operator op(const Surface<T>& other) { \
TAMAAS_ASSERT(this->n[0] == other.sizes()[0] && \
this->n[1] == other.sizes()[1] / 2 + 1, \
"surface size does not match"); \
_Pragma("omp parallel for") for (UInt i = 0; i < this->n[0]; \
i++) for (UInt j = 0; j < this->n[1]; \
j++) (*this)(i, j)op other(i, \
j); \
} \
template <typename T> \
inline void SurfaceComplex<T>::operator op(const SurfaceComplex<T>& other) { \
Grid<complex<T>, 2>::operator op(other); \
}
SURF_OP_IMPL(+=);
SURF_OP_IMPL(*=);
SURF_OP_IMPL(-=);
SURF_OP_IMPL(/=);
#undef SURF_OP_IMPL
} // namespace tamaas
#endif /* SURFACE_COMPLEX_H */

Event Timeline