2020-09-10 19:09:21 +02:00
|
|
|
// This file is part of monofonIC (MUSIC2)
|
|
|
|
// A software package to generate ICs for cosmological simulations
|
|
|
|
// Copyright (C) 2020 by Oliver Hahn
|
|
|
|
//
|
|
|
|
// monofonIC is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// monofonIC 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 General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2019-05-07 01:05:16 +02:00
|
|
|
#pragma once
|
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implements a simple class of 3-vectors of arbitrary scalar type
|
2019-05-07 01:05:16 +02:00
|
|
|
template< typename T >
|
2020-03-29 14:45:43 +02:00
|
|
|
class vec3_t{
|
2019-05-07 01:05:16 +02:00
|
|
|
private:
|
2019-11-01 04:45:34 +01:00
|
|
|
//! holds the data
|
2019-05-07 01:05:16 +02:00
|
|
|
std::array<T,3> data_;
|
2019-11-01 04:45:34 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
//! expose access to elements via references
|
2019-05-10 04:48:35 +02:00
|
|
|
T &x,&y,&z;
|
2019-11-01 04:45:34 +01:00
|
|
|
|
|
|
|
//! empty constructor
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t()
|
2019-05-10 04:48:35 +02:00
|
|
|
: x(data_[0]),y(data_[1]),z(data_[2]){}
|
|
|
|
|
2019-11-01 04:45:34 +01:00
|
|
|
//! copy constructor
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t( const vec3_t<T> &v)
|
2019-05-10 04:48:35 +02:00
|
|
|
: data_(v.data_), x(data_[0]),y(data_[1]),z(data_[2]){}
|
2019-12-01 14:34:28 +01:00
|
|
|
|
|
|
|
//! copy constructor for non-const reference, needed to avoid variadic template being called for non-const reference
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t( vec3_t<T>& v)
|
2019-12-01 14:34:28 +01:00
|
|
|
: data_(v.data_), x(data_[0]),y(data_[1]),z(data_[2]){}
|
2019-12-01 18:52:53 +01:00
|
|
|
|
2019-11-01 04:45:34 +01:00
|
|
|
//! move constructor
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t( vec3_t<T> &&v)
|
2019-11-01 04:45:34 +01:00
|
|
|
: data_(std::move(v.data_)), x(data_[0]), y(data_[1]), z(data_[2]){}
|
2019-05-10 04:48:35 +02:00
|
|
|
|
2020-03-29 14:45:43 +02:00
|
|
|
//! construct vec3_t from initializer list
|
2019-11-01 04:45:34 +01:00
|
|
|
template<typename ...E>
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t(E&&...e)
|
2019-12-01 14:34:28 +01:00
|
|
|
: data_{{std::forward<E>(e)...}}, x{data_[0]}, y{data_[1]}, z{data_[2]}
|
|
|
|
{}
|
2020-03-29 14:45:43 +02:00
|
|
|
// vec3_t( T a, T b, T c )
|
2019-12-01 14:34:28 +01:00
|
|
|
// : data_{{a,b,c}}, x(data_[0]), y(data_[1]), z(data_[2]){}
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-03 15:54:17 +01:00
|
|
|
//! bracket index access to vector components
|
2019-12-01 14:34:28 +01:00
|
|
|
T &operator[](size_t i) noexcept{ return data_[i];}
|
2019-05-07 01:05:16 +02:00
|
|
|
|
2019-11-03 15:54:17 +01:00
|
|
|
//! const bracket index access to vector components
|
2019-12-01 14:34:28 +01:00
|
|
|
const T &operator[](size_t i) const noexcept { return data_[i]; }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-05 00:29:33 +01:00
|
|
|
// assignment operator
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T>& operator=( const vec3_t<T>& v ) noexcept { data_=v.data_; return *this; }
|
2019-11-05 00:29:33 +01:00
|
|
|
|
2020-03-29 14:45:43 +02:00
|
|
|
//! implementation of summation of vec3_t
|
|
|
|
vec3_t<T> operator+( const vec3_t<T>& v ) const noexcept{ return vec3_t<T>({x+v.x,y+v.y,z+v.z}); }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2020-03-29 14:45:43 +02:00
|
|
|
//! implementation of difference of vec3_t
|
|
|
|
vec3_t<T> operator-( const vec3_t<T>& v ) const noexcept{ return vec3_t<T>({x-v.x,y-v.y,z-v.z}); }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-12-01 18:52:53 +01:00
|
|
|
//! implementation of unary negative
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T> operator-() const noexcept{ return vec3_t<T>({-x,-y,-z}); }
|
2019-12-01 18:52:53 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of scalar multiplication
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T> operator*( T s ) const noexcept{ return vec3_t<T>({x*s,y*s,z*s}); }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-05 00:29:33 +01:00
|
|
|
//! implementation of scalar division
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T> operator/( T s ) const noexcept{ return vec3_t<T>({x/s,y/s,z/s}); }
|
2019-11-05 00:29:33 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of += operator
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T>& operator+=( const vec3_t<T>& v ) noexcept{ x+=v.x; y+=v.y; z+=v.z; return *this; }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of -= operator
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T>& operator-=( const vec3_t<T>& v ) noexcept{ x-=v.x; y-=v.y; z-=v.z; return *this; }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! multiply with scalar
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T>& operator*=( T s ) noexcept{ x*=s; y*=s; z*=s; return *this; }
|
2019-05-07 01:05:16 +02:00
|
|
|
|
2019-12-04 14:26:42 +01:00
|
|
|
//! divide by scalar
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T>& operator/=( T s ) noexcept{ x/=s; y/=s; z/=s; return *this; }
|
2019-12-04 14:26:42 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! compute dot product with another vector
|
2020-03-29 14:45:43 +02:00
|
|
|
T dot(const vec3_t<T> &a) const noexcept
|
2019-05-07 01:05:16 +02:00
|
|
|
{
|
|
|
|
return data_[0] * a.data_[0] + data_[1] * a.data_[1] + data_[2] * a.data_[2];
|
|
|
|
}
|
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! returns 2-norm squared of vector
|
2019-12-01 14:34:28 +01:00
|
|
|
T norm_squared(void) const noexcept { return this->dot(*this); }
|
2019-05-07 01:05:16 +02:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! returns 2-norm of vector
|
2019-12-01 14:34:28 +01:00
|
|
|
T norm(void) const noexcept { return std::sqrt( this->norm_squared() ); }
|
|
|
|
|
|
|
|
//! wrap absolute vector to box of size p
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T>& wrap_abs( T p = 1.0 ) noexcept{
|
2019-12-01 14:34:28 +01:00
|
|
|
for( auto& x : data_ ) x = std::fmod( 2*p + x, p );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! wrap relative vector to box of size p
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T>& wrap_rel( T p = 1.0 ) noexcept{
|
2019-12-01 14:34:28 +01:00
|
|
|
for( auto& x : data_ ) x = (x<-p/2)? x+p : (x>=p/2)? x-p : x;
|
|
|
|
return *this;
|
|
|
|
}
|
2019-12-05 05:43:49 +01:00
|
|
|
|
2020-03-29 14:45:43 +02:00
|
|
|
//! ordering, allows 3d sorting of vec3_ts
|
|
|
|
bool operator<( const vec3_t<T>& o ) const noexcept{
|
2019-12-05 05:43:49 +01:00
|
|
|
if( x!=o.x ) return x<o.x?true:false;
|
|
|
|
if( y!=o.y ) return y<o.y?true:false;
|
|
|
|
if( z!=o.z ) return z<o.z?true:false;
|
|
|
|
return false;
|
|
|
|
}
|
2019-05-07 01:05:16 +02:00
|
|
|
};
|
2019-11-01 13:16:05 +01:00
|
|
|
|
|
|
|
//! multiplication with scalar
|
|
|
|
template<typename T>
|
2020-03-29 14:45:43 +02:00
|
|
|
vec3_t<T> operator*( T s, const vec3_t<T>& v ){
|
|
|
|
return vec3_t<T>({v.x*s,v.y*s,v.z*s});
|
2019-11-01 13:16:05 +01:00
|
|
|
}
|