1
0
Fork 0
mirror of https://github.com/cosmo-sims/monofonIC.git synced 2024-09-19 17:03:45 +02:00
monofonIC/include/math/vec3.hh

136 lines
4.8 KiB
C++
Raw Normal View History

// 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
/// @brief implements a simple class of 3-vectors of arbitrary scalar type
/// @tparam T scalar type
2019-05-07 01:05:16 +02:00
template< typename T >
class vec3_t{
2019-05-07 01:05:16 +02:00
private:
//! holds the data
2019-05-07 01:05:16 +02:00
std::array<T,3> data_;
public:
//! expose access to elements via references
2019-05-10 04:48:35 +02:00
T &x,&y,&z;
/// @brief empty constructor
vec3_t()
: data_{{T(0),T(0),T(0)}},x(data_[0]),y(data_[1]),z(data_[2]){}
2019-05-10 04:48:35 +02:00
/// @brief copy constructor
/// @param v vector to copy from
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
/// @brief copy constructor for non-const reference, needed to avoid variadic template being called for non-const reference
/// @param v vector to copy from
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]){}
/// @brief move constructor
/// @param v vector to move from
vec3_t( vec3_t<T> &&v)
: data_(std::move(v.data_)), x(data_[0]), y(data_[1]), z(data_[2]){}
2019-05-10 04:48:35 +02:00
//! construct vec3_t from initializer list
// template<typename ...E>
// vec3_t(E&&...e)
// : data_{{std::forward<E>(e)...}}, x{data_[0]}, y{data_[1]}, z{data_[2]}
// {}
vec3_t( T a, T b, T c )
: data_{{a,b,c}}, x(data_[0]), y(data_[1]), z(data_[2]){}
explicit vec3_t( T a)
: data_{{a,a,a}}, x(data_[0]), y(data_[1]), z(data_[2]){}
//! 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
//! 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]; }
// assignment operator
vec3_t<T>& operator=( const vec3_t<T>& v ) noexcept { data_=v.data_; return *this; }
//! 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}); }
//! 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}); }
//! implementation of unary negative
vec3_t<T> operator-() const noexcept{ return vec3_t<T>({-x,-y,-z}); }
2019-11-01 13:16:05 +01:00
//! implementation of scalar multiplication
vec3_t<T> operator*( T s ) const noexcept{ return vec3_t<T>({x*s,y*s,z*s}); }
//! implementation of scalar division
vec3_t<T> operator/( T s ) const noexcept{ return vec3_t<T>({x/s,y/s,z/s}); }
2019-11-01 13:16:05 +01:00
//! implementation of += operator
vec3_t<T>& operator+=( const vec3_t<T>& v ) noexcept{ x+=v.x; y+=v.y; z+=v.z; return *this; }
2019-11-01 13:16:05 +01:00
//! implementation of -= operator
vec3_t<T>& operator-=( const vec3_t<T>& v ) noexcept{ x-=v.x; y-=v.y; z-=v.z; return *this; }
2019-11-01 13:16:05 +01:00
//! multiply with scalar
vec3_t<T>& operator*=( T s ) noexcept{ x*=s; y*=s; z*=s; return *this; }
2019-05-07 01:05:16 +02:00
//! divide by scalar
vec3_t<T>& operator/=( T s ) noexcept{ x/=s; y/=s; z/=s; return *this; }
2019-11-01 13:16:05 +01:00
//! compute dot product with another vector
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
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
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;
}
//! ordering, allows 3d sorting of vec3_ts
bool operator<( const vec3_t<T>& o ) const noexcept{
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>
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
}