2013-07-17 19:24:07 +02:00
/*******************************************************************************
*
* TRIQS : a Toolbox for Research in Interacting Quantum Systems
*
* Copyright ( C ) 2012 - 2013 by M . Ferrero , O . Parcollet
*
* TRIQS 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 .
*
* TRIQS 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
* TRIQS . If not , see < http : //www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef TRIQS_GF_GFBASECLASS_H
# define TRIQS_GF_GFBASECLASS_H
# include <triqs/utility/first_include.hpp>
# include <triqs/utility/std_vector_expr_template.hpp>
# include <triqs/utility/factory.hpp>
# include <triqs/utility/tuple_tools.hpp>
# include <triqs/arrays/h5.hpp>
# include <vector>
# include "./tools.hpp"
# include "./data_proxies.hpp"
2013-07-28 13:28:19 +02:00
namespace triqs { namespace gfs {
2013-07-17 19:24:07 +02:00
using utility : : factory ;
2013-07-28 13:28:19 +02:00
using arrays : : make_shape ;
2013-07-17 19:24:07 +02:00
2013-10-18 13:39:00 +02:00
// the gf mesh
template < typename Variable , typename Opt = void > struct gf_mesh ;
// The regular type
2013-10-22 21:28:25 +02:00
template < typename Variable , typename Target = matrix_valued , typename Opt = void > class gf ;
2013-10-18 13:39:00 +02:00
// The view type
template < typename Variable , typename Target = matrix_valued , typename Opt = void , bool IsConst = false > class gf_view ;
// The const view type
template < typename Variable , typename Target = matrix_valued , typename Opt = void >
using gf_const_view = gf_view < Variable , Target , Opt , true > ;
// the implementation class
template < typename Variable , typename Target , typename Opt , bool IsView , bool IsConst > class gf_impl ;
2013-07-17 19:24:07 +02:00
// various implementation traits
2013-10-16 23:55:26 +02:00
namespace gfs_implementation { // never use using of this...
2013-07-17 19:24:07 +02:00
2013-10-16 23:55:26 +02:00
// evaluator regroup functions to evaluate the function.
2013-07-17 19:24:07 +02:00
template < typename Variable , typename Target , typename Opt > struct evaluator { static constexpr int arity = 0 ; } ;
// closest_point mechanism
template < typename Variable , typename Target , typename Opt > struct get_closest_point ;
2013-10-16 23:55:26 +02:00
// singularity
2013-07-17 19:24:07 +02:00
template < typename Variable , typename Target , typename Opt > struct singularity { typedef nothing type ; } ;
2013-10-16 23:55:26 +02:00
// symmetry
2013-07-17 19:24:07 +02:00
template < typename Variable , typename Target , typename Opt > struct symmetry { typedef nothing type ; } ;
// data_proxy contains function to manipulate the data array, but no data itself.
// this is used to specialize this part of the code to array of dim 3 (matrix gf), dim 1 (scalar gf) and vector (e.g. block gf, ...)
template < typename Variable , typename Target , typename Opt , typename Enable = void > struct data_proxy ;
2013-10-22 21:28:25 +02:00
// Traits to read/write in hdf5 files. Can be specialized for some case (Cf block). Defined below
template < typename Variable , typename Target , typename Opt > struct h5_name ; // value is a const char
template < typename Variable , typename Target , typename Opt > struct h5_rw ;
// factories regroup all factories (constructors..) for all types of gf. Defaults implemented below.
2013-10-16 23:55:26 +02:00
template < typename Variable , typename Target , typename Opt > struct factories ;
2013-07-28 13:28:19 +02:00
} // gfs_implementation
2013-07-17 19:24:07 +02:00
2013-10-22 21:28:25 +02:00
// OBSOLETE : kept for backward compatibility only. Do not document.
2013-07-17 19:24:07 +02:00
// make_gf and make_gf_view forward any args to them
2013-08-30 12:37:12 +02:00
template < typename Variable , typename Target = matrix_valued , typename Opt = void , typename . . . U >
gf < Variable , Target , Opt > make_gf ( gf_mesh < Variable , Opt > m , U & & . . . x )
{ return gfs_implementation : : factories < Variable , Target , Opt > : : make_gf ( std : : move ( m ) , std : : forward < U > ( x ) . . . ) ; }
2013-07-17 19:24:07 +02:00
template < typename Variable , typename Target = matrix_valued , typename Opt = void , typename . . . U >
2013-07-28 13:28:19 +02:00
gf < Variable , Target , Opt > make_gf ( U & & . . . x ) { return gfs_implementation : : factories < Variable , Target , Opt > : : make_gf ( std : : forward < U > ( x ) . . . ) ; }
2013-07-17 19:24:07 +02:00
template < typename Variable , typename Target = matrix_valued , typename Opt = void , typename . . . U >
2013-07-28 13:28:19 +02:00
gf_view < Variable , Target , Opt > make_gf_view ( U & & . . . x ) { return gfs_implementation : : factories < Variable , Target , Opt > : : make_gf_view ( std : : forward < U > ( x ) . . . ) ; }
2013-07-17 19:24:07 +02:00
// The trait that "marks" the Green function
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT ( ImmutableGreenFunction ) ;
2013-10-22 21:28:25 +02:00
template < typename G > auto get_gf_data_shape ( G const & g ) DECL_AND_RETURN ( g . get_data_shape ( ) ) ;
2013-10-16 23:55:26 +02:00
2013-10-23 15:51:51 +02:00
template < typename Variable , typename Target , typename Opt , bool IsView , bool IsConst >
auto get_target_shape ( gf_impl < Variable , Target , Opt , IsView , IsConst > const & g ) DECL_AND_RETURN ( g . data ( ) . shape ( ) . front_pop ( ) ) ;
2013-07-17 19:24:07 +02:00
// ---------------------- implementation --------------------------------
2013-10-22 21:28:25 +02:00
// overload get_shape for a vector to simplify code below in gf block case.
template < typename T > long get_shape ( std : : vector < T > const & x ) { return x . size ( ) ; }
2013-07-17 19:24:07 +02:00
/// A common implementation class for gf and gf_view. They will only redefine contructor and = ...
2013-10-22 21:28:25 +02:00
template < typename Variable , typename Target , typename Opt , bool IsView , bool IsConst >
class gf_impl : TRIQS_CONCEPT_TAG_NAME ( ImmutableGreenFunction ) {
static_assert ( ! ( ! IsView & & IsConst ) , " Internal error " ) ;
2013-07-17 19:24:07 +02:00
public :
2013-10-18 13:39:00 +02:00
typedef gf_view < Variable , Target , Opt > mutable_view_type ;
typedef gf_const_view < Variable , Target , Opt > const_view_type ;
typedef typename std : : conditional < IsConst , const_view_type , mutable_view_type > : : type view_type ;
2013-08-20 16:15:43 +02:00
typedef gf < Variable , Target , Opt > regular_type ;
2013-07-17 19:24:07 +02:00
2013-07-27 22:59:51 +02:00
typedef Variable variable_t ;
2013-10-16 23:55:26 +02:00
typedef Target target_t ;
2013-07-27 22:59:51 +02:00
typedef Opt option_t ;
2013-08-27 14:20:50 +02:00
typedef gf_mesh < Variable , Opt > mesh_t ;
2013-07-17 19:24:07 +02:00
typedef typename mesh_t : : domain_t domain_t ;
typedef typename mesh_t : : mesh_point_t mesh_point_t ;
typedef typename mesh_t : : index_t mesh_index_t ;
2013-10-16 23:55:26 +02:00
typedef typename gfs_implementation : : symmetry < Variable , Target , Opt > : : type symmetry_t ;
typedef gfs_implementation : : evaluator < Variable , Target , Opt > evaluator_t ;
2013-07-17 19:24:07 +02:00
2013-10-16 23:55:26 +02:00
typedef gfs_implementation : : data_proxy < Variable , Target , Opt > data_proxy_t ;
2013-08-20 16:15:43 +02:00
typedef typename data_proxy_t : : storage_t data_regular_t ;
2013-07-17 19:24:07 +02:00
typedef typename data_proxy_t : : storage_view_t data_view_t ;
2013-10-18 13:39:00 +02:00
typedef typename data_proxy_t : : storage_const_view_t data_const_view_t ;
typedef typename std : : conditional < IsView , typename std : : conditional < IsConst , data_const_view_t , data_view_t > : : type ,
data_regular_t > : : type data_t ;
2013-07-17 19:24:07 +02:00
2013-10-16 23:55:26 +02:00
typedef typename gfs_implementation : : singularity < Variable , Target , Opt > : : type singularity_non_view_t ;
2013-07-17 19:24:07 +02:00
typedef typename view_type_if_exists_else_type < singularity_non_view_t > : : type singularity_view_t ;
typedef typename std : : conditional < IsView , singularity_view_t , singularity_non_view_t > : : type singularity_t ;
mesh_t const & mesh ( ) const { return _mesh ; }
domain_t const & domain ( ) const { return _mesh . domain ( ) ; }
data_t & data ( ) { return _data ; }
data_t const & data ( ) const { return _data ; }
singularity_t & singularity ( ) { return _singularity ; }
singularity_t const & singularity ( ) const { return _singularity ; }
symmetry_t const & symmetry ( ) const { return _symmetry ; }
evaluator_t const & get_evaluator ( ) const { return _evaluator ; }
2013-10-16 23:55:26 +02:00
auto get_data_shape ( ) const DECL_AND_RETURN ( get_shape ( this - > data ( ) ) ) ;
2013-07-17 19:24:07 +02:00
protected :
mesh_t _mesh ;
data_t _data ;
singularity_t _singularity ;
symmetry_t _symmetry ;
evaluator_t _evaluator ;
data_proxy_t _data_proxy ;
// --------------------------------Constructors -----------------------------------------------
// all protected but one, this is an implementation class, see gf/gf_view later for public one
gf_impl ( ) { } // all arrays of zero size (empty)
2013-10-22 21:28:25 +02:00
public : //everyone can make a copy and a move (for clef lib in particular, this one needs to be public)
gf_impl ( gf_impl const & x )
: _mesh ( x . mesh ( ) ) ,
_data ( factory < data_t > ( x . data ( ) ) ) ,
_singularity ( factory < singularity_t > ( x . singularity ( ) ) ) ,
_symmetry ( x . symmetry ( ) ) ,
_evaluator ( x . _evaluator ) { }
2013-07-17 19:24:07 +02:00
gf_impl ( gf_impl & & ) = default ;
protected :
2013-10-22 21:28:25 +02:00
template < typename G >
gf_impl ( G & & x , bool ) // bool to disambiguate
: _mesh ( x . mesh ( ) ) ,
_data ( factory < data_t > ( x . data ( ) ) ) ,
_singularity ( factory < singularity_t > ( x . singularity ( ) ) ) ,
_symmetry ( x . symmetry ( ) ) ,
_evaluator ( x . get_evaluator ( ) ) { }
template < typename M , typename D , typename S , typename SY , typename EV >
gf_impl ( M & & m , D & & dat , S & & sing , SY & & sy , EV & & ev )
: _mesh ( std : : forward < M > ( m ) ) ,
_data ( std : : forward < D > ( dat ) ) ,
_singularity ( std : : forward < S > ( sing ) ) ,
_symmetry ( std : : forward < SY > ( sy ) ) ,
_evaluator ( std : : forward < EV > ( ev ) ) { }
2013-07-17 19:24:07 +02:00
void operator = ( gf_impl const & rhs ) = delete ; // done in derived class.
void swap_impl ( gf_impl & b ) noexcept {
using std : : swap ;
2013-10-22 21:28:25 +02:00
swap ( this - > _mesh , b . _mesh ) ;
swap ( this - > _data , b . _data ) ;
swap ( this - > _singularity , b . _singularity ) ;
swap ( this - > _symmetry , b . _symmetry ) ;
swap ( this - > _evaluator , b . _evaluator ) ;
2013-07-17 19:24:07 +02:00
}
2013-10-22 21:28:25 +02:00
public :
2013-07-17 19:24:07 +02:00
// ------------- All the call operators -----------------------------
// First, a simple () returns a view, like for an array...
2013-10-22 21:28:25 +02:00
const_view_type operator ( ) ( ) const { return * this ; }
2013-10-18 13:39:00 +02:00
view_type operator ( ) ( ) { return * this ; }
2013-07-17 19:24:07 +02:00
/// Calls are (perfectly) forwarded to the evaluator::operator(), except mesh_point_t and when
/// there is at least one lazy argument ...
2013-10-22 21:28:25 +02:00
template < typename . . . Args > // match any argument list, picking out the first type : () is not permitted
typename std : : add_const < typename boost : : lazy_disable_if_c < // disable the template if one the following conditions it true
( sizeof . . . ( Args ) = = 0 ) | | clef : : is_any_lazy < Args . . . > : : value | |
( ( sizeof . . . ( Args ) ! = evaluator_t : : arity ) & & ( evaluator_t : : arity ! = - 1 ) ) // if -1 : no check
,
std : : result_of < evaluator_t ( gf_impl * , Args . . . ) > // what is the result type of call
> : : type // end of lazy_disable_if
> : : type // end of add_Const
operator ( ) ( Args & & . . . args ) const {
return _evaluator ( this , std : : forward < Args > ( args ) . . . ) ;
}
2013-10-16 23:55:26 +02:00
2013-10-22 21:28:25 +02:00
template < typename . . . Args >
typename clef : : _result_of : : make_expr_call < gf_impl & , Args . . . > : : type operator ( ) ( Args & & . . . args ) & {
return clef : : make_expr_call ( * this , std : : forward < Args > ( args ) . . . ) ;
}
2013-10-16 23:48:14 +02:00
2013-10-22 21:28:25 +02:00
template < typename . . . Args >
typename clef : : _result_of : : make_expr_call < gf_impl const & , Args . . . > : : type operator ( ) ( Args & & . . . args ) const & {
return clef : : make_expr_call ( * this , std : : forward < Args > ( args ) . . . ) ;
}
2013-09-07 15:27:10 +02:00
2013-10-22 21:28:25 +02:00
template < typename . . . Args > typename clef : : _result_of : : make_expr_call < gf_impl , Args . . . > : : type operator ( ) ( Args & & . . . args ) & & {
return clef : : make_expr_call ( std : : move ( * this ) , std : : forward < Args > ( args ) . . . ) ;
}
// ------------- All the [] operators -----------------------------
// [] and access to the grid point
typedef typename std : : result_of < data_proxy_t ( data_t & , size_t ) > : : type r_type ;
typedef typename std : : result_of < data_proxy_t ( data_t const & , size_t ) > : : type cr_type ;
2013-07-28 13:47:42 +02:00
r_type operator [ ] ( mesh_index_t const & arg ) { return _data_proxy ( _data , _mesh . index_to_linear ( arg ) ) ; }
cr_type operator [ ] ( mesh_index_t const & arg ) const { return _data_proxy ( _data , _mesh . index_to_linear ( arg ) ) ; }
r_type operator [ ] ( mesh_point_t const & x ) { return _data_proxy ( _data , x . linear_index ( ) ) ; }
cr_type operator [ ] ( mesh_point_t const & x ) const { return _data_proxy ( _data , x . linear_index ( ) ) ; }
template < typename . . . U >
r_type operator [ ] ( closest_pt_wrap < U . . . > const & p ) { return _data_proxy ( _data , _mesh . index_to_linear ( gfs_implementation : : get_closest_point < Variable , Target , Opt > : : invoke ( this , p ) ) ) ; }
template < typename . . . U >
cr_type operator [ ] ( closest_pt_wrap < U . . . > const & p ) const { return _data_proxy ( _data , _mesh . index_to_linear ( gfs_implementation : : get_closest_point < Variable , Target , Opt > : : invoke ( this , p ) ) ) ; }
2013-10-16 23:55:26 +02:00
template < typename Arg >
typename clef : : _result_of : : make_expr_subscript < gf_impl const & , Arg > : : type
operator [ ] ( Arg & & arg ) const & { return clef : : make_expr_subscript ( * this , std : : forward < Arg > ( arg ) ) ; }
2013-10-16 23:48:14 +02:00
template < typename Arg >
2013-10-16 23:55:26 +02:00
typename clef : : _result_of : : make_expr_subscript < gf_impl & , Arg > : : type
operator [ ] ( Arg & & arg ) & { return clef : : make_expr_subscript ( * this , std : : forward < Arg > ( arg ) ) ; }
2013-10-16 23:48:14 +02:00
2013-07-28 13:47:42 +02:00
template < typename Arg >
2013-10-16 23:55:26 +02:00
typename clef : : _result_of : : make_expr_subscript < gf_impl , Arg > : : type
operator [ ] ( Arg & & arg ) & & { return clef : : make_expr_subscript ( std : : move ( * this ) , std : : forward < Arg > ( arg ) ) ; }
2013-07-17 19:24:07 +02:00
2013-10-22 21:28:25 +02:00
/// --------------------- A direct access to the grid point --------------------------
2013-07-17 19:24:07 +02:00
template < typename . . . Args >
r_type on_mesh ( Args & & . . . args ) { return _data_proxy ( _data , _mesh . index_to_linear ( mesh_index_t ( std : : forward < Args > ( args ) . . . ) ) ) ; }
template < typename . . . Args >
cr_type on_mesh ( Args & & . . . args ) const { return _data_proxy ( _data , _mesh . index_to_linear ( mesh_index_t ( std : : forward < Args > ( args ) . . . ) ) ) ; }
2013-10-22 21:28:25 +02:00
// The on_mesh little adaptor ....
private :
2013-07-17 19:24:07 +02:00
struct _on_mesh_wrapper_const {
2013-10-22 21:28:25 +02:00
gf_impl const & f ;
template < typename . . . Args > cr_type operator ( ) ( Args & & . . . args ) const { return f . on_mesh ( std : : forward < Args > ( args ) . . . ) ; }
2013-07-17 19:24:07 +02:00
} ;
struct _on_mesh_wrapper {
2013-10-22 21:28:25 +02:00
gf_impl & f ;
template < typename . . . Args > r_type operator ( ) ( Args & & . . . args ) const { return f . on_mesh ( std : : forward < Args > ( args ) . . . ) ; }
2013-07-17 19:24:07 +02:00
} ;
2013-10-22 21:28:25 +02:00
public :
_on_mesh_wrapper_const friend on_mesh ( gf_impl const & f ) {
return { f } ;
}
_on_mesh_wrapper friend on_mesh ( gf_impl & f ) {
return { f } ;
}
2013-07-17 19:24:07 +02:00
//----------------------------- HDF5 -----------------------------
2013-07-29 17:56:31 +02:00
friend std : : string get_triqs_hdf5_data_scheme ( gf_impl const & g ) { return " Gf " + gfs_implementation : : h5_name < Variable , Target , Opt > : : invoke ( ) ; }
2013-07-17 19:24:07 +02:00
2013-10-18 13:39:00 +02:00
friend class gfs_implementation : : h5_rw < Variable , Target , Opt > ;
2013-10-16 23:55:26 +02:00
2013-07-17 19:24:07 +02:00
/// Write into HDF5
friend void h5_write ( h5 : : group fg , std : : string subgroup_name , gf_impl const & g ) {
auto gr = fg . create_group ( subgroup_name ) ;
gr . write_triqs_hdf5_data_scheme ( g ) ;
2013-10-18 13:39:00 +02:00
gfs_implementation : : h5_rw < Variable , Target , Opt > : : write ( gr , g ) ;
2013-07-17 19:24:07 +02:00
}
/// Read from HDF5
friend void h5_read ( h5 : : group fg , std : : string subgroup_name , gf_impl & g ) {
auto gr = fg . open_group ( subgroup_name ) ;
// Check the attribute or throw
auto tag_file = gr . read_triqs_hdf5_data_scheme ( ) ;
auto tag_expected = get_triqs_hdf5_data_scheme ( g ) ;
if ( tag_file ! = tag_expected )
TRIQS_RUNTIME_ERROR < < " h5_read : mismatch of the tag TRIQS_HDF5_data_scheme tag in the h5 group : found " < < tag_file < < " while I expected " < < tag_expected ;
2013-10-18 13:39:00 +02:00
gfs_implementation : : h5_rw < Variable , Target , Opt > : : read ( gr , g ) ;
2013-07-17 19:24:07 +02:00
}
//----------------------------- BOOST Serialization -----------------------------
friend class boost : : serialization : : access ;
template < class Archive >
void serialize ( Archive & ar , const unsigned int version ) {
ar & boost : : serialization : : make_nvp ( " data " , _data ) ;
ar & boost : : serialization : : make_nvp ( " singularity " , _singularity ) ;
ar & boost : : serialization : : make_nvp ( " mesh " , _mesh ) ;
ar & boost : : serialization : : make_nvp ( " symmetry " , _symmetry ) ;
}
/// print
friend std : : ostream & operator < < ( std : : ostream & out , gf_impl const & x ) { return out < < ( IsView ? " gf_view " : " gf " ) ; }
friend std : : ostream & triqs_nvl_formal_print ( std : : ostream & out , gf_impl const & x ) { return out < < ( IsView ? " gf_view " : " gf " ) ; }
2013-10-16 23:55:26 +02:00
2013-10-26 13:49:24 +02:00
} ;
// -------------------------Interaction with the CLEF library : auto assignement implemnetation--------------------------------------
// auto assignment of the gf (gf(om_) << expression fills the functions by evaluation of expression)
template < typename RHS , typename Variable , typename Target , typename Opt , bool IsView >
void triqs_clef_auto_assign ( gf_impl < Variable , Target , Opt , IsView , false > & g , RHS const & rhs ) {
triqs_clef_auto_assign_impl ( g , rhs , typename std : : is_base_of < tag : : composite , gf_mesh < Variable , Opt > > : : type ( ) ) ;
assign_from_expression ( g . singularity ( ) , rhs ) ;
// access to the data . Beware, we view it as a *matrix* NOT an array... (crucial for assignment to scalars !)
// if f is an expression, replace the placeholder with a simple tail. If f is a function callable on freq_infty,
// it uses the fact that tail_non_view_t can be casted into freq_infty
}
2013-10-16 23:55:26 +02:00
2013-10-26 13:49:24 +02:00
// enable the writing g[om_] << .... also
template < typename RHS , typename Variable , typename Target , typename Opt , bool IsView >
void triqs_clef_auto_assign_subscript ( gf_impl < Variable , Target , Opt , IsView , false > & g , RHS const & rhs ) {
triqs_clef_auto_assign ( g , rhs ) ;
}
2013-10-16 23:55:26 +02:00
2013-10-26 13:49:24 +02:00
template < bool B , typename G , typename RHS >
void triqs_gf_clef_auto_assign_impl_aux_assign ( G & & g , RHS & & rhs , std : : integral_constant < bool , B > ) {
std : : forward < G > ( g ) = std : : forward < RHS > ( rhs ) ;
}
template < typename G , bool B , typename Expr , int . . . Is >
void triqs_gf_clef_auto_assign_impl_aux_assign ( G & & g , clef : : make_fun_impl < Expr , Is . . . > & & rhs , std : : integral_constant < bool , B > ) {
triqs_clef_auto_assign_impl ( std : : forward < G > ( g ) , std : : forward < clef : : make_fun_impl < Expr , Is . . . > > ( rhs ) , std : : integral_constant < bool , B > ( ) ) ;
}
template < typename RHS , typename Variable , typename Target , typename Opt , bool IsView >
void triqs_clef_auto_assign_impl ( gf_impl < Variable , Target , Opt , IsView , false > & g , RHS const & rhs ,
std : : integral_constant < bool , false > ) {
for ( auto const & w : g . mesh ( ) ) {
triqs_gf_clef_auto_assign_impl_aux_assign ( g [ w ] , rhs ( w ) , std : : integral_constant < bool , false > ( ) ) ;
//(*this)[w] = rhs(w);
}
}
template < typename RHS , typename Variable , typename Target , typename Opt , bool IsView >
void triqs_clef_auto_assign_impl ( gf_impl < Variable , Target , Opt , IsView , false > & g , RHS const & rhs ,
std : : integral_constant < bool , true > ) {
for ( auto const & w : g . mesh ( ) ) {
triqs_gf_clef_auto_assign_impl_aux_assign ( g [ w ] , triqs : : tuple : : apply ( rhs , w . components_tuple ( ) ) , std : : integral_constant < bool , true > ( ) ) ;
//(*this)[w] = triqs::tuple::apply(rhs, w.components_tuple());
}
}
2013-07-17 19:24:07 +02:00
2013-10-22 21:28:25 +02:00
// -------------------------The regular class of GF --------------------------------------------------------
2013-10-18 13:39:00 +02:00
template < typename Variable , typename Target , typename Opt > class gf : public gf_impl < Variable , Target , Opt , false , false > {
typedef gf_impl < Variable , Target , Opt , false , false > B ;
2013-10-16 23:55:26 +02:00
typedef gfs_implementation : : factories < Variable , Target , Opt > factory ;
2013-07-17 19:24:07 +02:00
public :
2013-10-22 21:28:25 +02:00
gf ( ) : B ( ) { }
gf ( gf const & g ) : B ( g ) { }
gf ( gf & & g ) noexcept : B ( std : : move ( g ) ) { }
gf ( gf_view < Variable , Target , Opt > const & g ) : B ( g , bool { } ) { }
gf ( gf_const_view < Variable , Target , Opt > const & g ) : B ( g , bool { } ) { }
template < typename GfType >
gf ( GfType const & x , typename std : : enable_if < ImmutableGreenFunction < GfType > : : value > : : type * dummy = 0 )
: B ( ) {
* this = x ;
}
2013-07-17 19:24:07 +02:00
2013-10-22 21:28:25 +02:00
gf ( typename B : : mesh_t m , typename B : : data_t dat , typename B : : singularity_view_t const & si , typename B : : symmetry_t const & s )
: B ( std : : move ( m ) , std : : move ( dat ) , si , s , typename B : : evaluator_t { } ) { }
2013-10-16 23:55:26 +02:00
typedef typename factory : : target_shape_t target_shape_t ;
gf ( typename B : : mesh_t m , target_shape_t shape = target_shape_t { } ) :
B ( std : : move ( m ) , factory : : make_data ( m , shape ) , factory : : make_singularity ( m , shape ) , typename B : : symmetry_t { } , typename B : : evaluator_t { } ) { }
2013-07-17 19:24:07 +02:00
friend void swap ( gf & a , gf & b ) noexcept { a . swap_impl ( b ) ; }
2013-10-16 23:55:26 +02:00
gf & operator = ( gf const & rhs ) { * this = gf ( rhs ) ; return * this ; } // use move =
gf & operator = ( gf & rhs ) { * this = gf ( rhs ) ; return * this ; } // use move =
gf & operator = ( gf & & rhs ) noexcept { swap ( * this , rhs ) ; return * this ; }
2013-07-17 19:24:07 +02:00
template < typename RHS > void operator = ( RHS & & rhs ) {
2013-10-16 23:48:14 +02:00
this - > _mesh = rhs . mesh ( ) ;
2013-10-16 23:55:26 +02:00
this - > _data . resize ( get_gf_data_shape ( rhs ) ) ;
for ( auto const & w : this - > mesh ( ) ) { ( * this ) [ w ] = rhs [ w ] ; }
2013-07-17 19:24:07 +02:00
this - > _singularity = rhs . singularity ( ) ;
// to be implemented : there is none in the gf_expr in particular....
//this->_symmetry = rhs.symmetry();
}
2013-10-16 23:55:26 +02:00
2013-07-17 19:24:07 +02:00
} ;
2013-10-22 21:28:25 +02:00
// --------------------------The const View class of GF -------------------------------------------------------
2013-10-18 13:39:00 +02:00
template < typename Variable , typename Target , typename Opt > class gf_view < Variable , Target , Opt , true > : public gf_impl < Variable , Target , Opt , true , true > {
typedef gf_impl < Variable , Target , Opt , true , true > B ;
public :
gf_view ( ) = delete ;
2013-10-22 21:28:25 +02:00
gf_view ( gf_view const & g ) : B ( g ) { }
gf_view ( gf_view & & g ) noexcept : B ( std : : move ( g ) ) { }
gf_view ( gf_impl < Variable , Target , Opt , true , true > const & g ) : B ( g , bool { } ) { } // from a const_view
gf_view ( gf_impl < Variable , Target , Opt , true , false > const & g ) : B ( g , bool { } ) { } // from a view
gf_view ( gf_impl < Variable , Target , Opt , false , false > const & g ) : B ( g , bool { } ) { } // from a const gf
gf_view ( gf_impl < Variable , Target , Opt , false , false > & g ) : B ( g , bool { } ) { } // from a gf &
gf_view ( gf_impl < Variable , Target , Opt , false , false > & & g ) noexcept : B ( std : : move ( g ) , bool { } ) { } // from a gf &&
template < typename D >
gf_view ( typename B : : mesh_t const & m , D const & dat , typename B : : singularity_view_t const & t , typename B : : symmetry_t const & s )
: B ( m , factory < typename B : : data_t > ( dat ) , t , s , typename B : : evaluator_t { } ) { }
void rebind ( gf_view const & X ) noexcept {
2013-10-18 13:39:00 +02:00
this - > _mesh = X . _mesh ; this - > _symmetry = X . _symmetry ;
this - > _data_proxy . rebind ( this - > _data , X ) ;
this - > _singularity . rebind ( X . _singularity ) ;
}
2013-10-22 14:10:44 +02:00
2013-10-22 21:28:25 +02:00
void rebind ( gf_view < Variable , Target , Opt , false > const & X ) noexcept {
rebind ( gf_view { X } ) ;
}
2013-10-22 14:10:44 +02:00
2013-10-18 13:39:00 +02:00
gf_view & operator = ( gf_view const & ) = delete ;
} ; // class gf_const_view
2013-10-22 21:28:25 +02:00
// ------------------------- The View class of GF -------------------------------------------------------
2013-10-18 13:39:00 +02:00
template < typename Variable , typename Target , typename Opt > class gf_view < Variable , Target , Opt , false > : public gf_impl < Variable , Target , Opt , true , false > {
typedef gf_impl < Variable , Target , Opt , true , false > B ;
2013-07-17 19:24:07 +02:00
public :
2013-10-18 13:39:00 +02:00
gf_view ( ) = delete ;
2013-10-22 21:28:25 +02:00
gf_view ( gf_view const & g ) : B ( g ) { }
gf_view ( gf_view & & g ) noexcept : B ( std : : move ( g ) ) { }
gf_view ( gf_impl < Variable , Target , Opt , true , true > const & g ) = delete ; // from a const view : impossible
gf_view ( gf_impl < Variable , Target , Opt , true , false > const & g ) : B ( g , bool { } ) { } // from a view
gf_view ( gf_impl < Variable , Target , Opt , false , false > const & g ) = delete ; // from a const gf : impossible
gf_view ( gf_impl < Variable , Target , Opt , false , false > & g ) : B ( g , bool { } ) { } // from a gf &
gf_view ( gf_impl < Variable , Target , Opt , false , false > & & g ) noexcept : B ( std : : move ( g ) , bool { } ) { } // from a gf &&
template < typename D >
gf_view ( typename B : : mesh_t const & m , D const & dat , typename B : : singularity_view_t const & t , typename B : : symmetry_t const & s )
: B ( m , factory < typename B : : data_t > ( dat ) , t , s , typename B : : evaluator_t { } ) { }
2013-07-17 19:24:07 +02:00
friend void swap ( gf_view & a , gf_view & b ) noexcept { a . swap_impl ( b ) ; }
2013-10-22 21:28:25 +02:00
void rebind ( gf_view const & X ) noexcept {
2013-07-17 19:24:07 +02:00
this - > _mesh = X . _mesh ; this - > _symmetry = X . _symmetry ;
this - > _data_proxy . rebind ( this - > _data , X ) ;
this - > _singularity . rebind ( X . _singularity ) ;
}
2013-10-22 21:28:25 +02:00
gf_view & operator = ( gf_view const & rhs ) {
triqs_gf_view_assign_delegation ( * this , rhs ) ;
return * this ;
}
2013-07-17 19:24:07 +02:00
2013-10-22 21:28:25 +02:00
template < typename RHS > gf_view & operator = ( RHS const & rhs ) {
triqs_gf_view_assign_delegation ( * this , rhs ) ;
return * this ;
}
2013-07-17 19:24:07 +02:00
} ; // class gf_view
// delegate = so that I can overload it for specific RHS...
template < typename Variable , typename Target , typename Opt , typename RHS >
2013-09-06 15:53:28 +02:00
DISABLE_IF ( arrays : : is_scalar < RHS > ) triqs_gf_view_assign_delegation ( gf_view < Variable , Target , Opt > g , RHS const & rhs ) {
2013-10-16 23:55:26 +02:00
if ( ! ( g . mesh ( ) = = rhs . mesh ( ) ) ) TRIQS_RUNTIME_ERROR < < " Gf Assignment in View : incompatible mesh " ;
for ( auto const & w : g . mesh ( ) ) g [ w ] = rhs [ w ] ;
2013-07-17 19:24:07 +02:00
g . singularity ( ) = rhs . singularity ( ) ;
}
template < typename Variable , typename Target , typename Opt , typename T >
2013-09-06 15:53:28 +02:00
ENABLE_IF ( arrays : : is_scalar < T > ) triqs_gf_view_assign_delegation ( gf_view < Variable , Target , Opt > g , T const & x ) {
2013-07-17 19:24:07 +02:00
gf_view < Variable , Target , Opt > : : data_proxy_t : : assign_to_scalar ( g . data ( ) , x ) ;
g . singularity ( ) = x ;
}
// tool for lazy transformation
2013-10-18 13:39:00 +02:00
template < typename Tag , typename D , typename Target = matrix_valued > struct gf_keeper {
gf_const_view < D , Target > g ;
} ;
2013-07-17 19:24:07 +02:00
// ---------------------------------- slicing ------------------------------------
2013-07-28 13:47:42 +02:00
2013-10-22 21:28:25 +02:00
// slice
template < typename Variable , typename Target , typename Opt , bool IsConst , typename . . . Args >
gf_view < Variable , matrix_valued , Opt , IsConst > slice_target ( gf_view < Variable , Target , Opt , IsConst > g , Args & & . . . args ) {
static_assert ( std : : is_same < Target , matrix_valued > : : value , " slice_target only for matrix_valued GF's " ) ;
using arrays : : range ;
return { g . mesh ( ) , g . data ( ) ( range ( ) , std : : forward < Args > ( args ) . . . ) ,
slice_target ( g . singularity ( ) , std : : forward < Args > ( args ) . . . ) , g . symmetry ( ) } ;
}
template < typename Variable , typename Target , typename Opt , typename . . . Args >
gf_view < Variable , matrix_valued , Opt > slice_target ( gf < Variable , Target , Opt > & g , Args & & . . . args ) {
return slice_target ( g ( ) , std : : forward < Args > ( args ) . . . ) ;
}
template < typename Variable , typename Target , typename Opt , typename . . . Args >
gf_const_view < Variable , matrix_valued , Opt > slice_target ( gf < Variable , Target , Opt > const & g , Args & & . . . args ) {
return slice_target ( g ( ) , std : : forward < Args > ( args ) . . . ) ;
}
// slice to scalar
template < typename Variable , typename Target , typename Opt , bool IsConst , typename . . . Args >
gf_view < Variable , scalar_valued , Opt , IsConst > slice_target_to_scalar ( gf_view < Variable , Target , Opt , IsConst > g ,
Args & & . . . args ) {
static_assert ( std : : is_same < Target , matrix_valued > : : value , " slice_target only for matrix_valued GF's " ) ;
using arrays : : range ;
return { g . mesh ( ) , g . data ( ) ( range ( ) , std : : forward < Args > ( args ) . . . ) ,
slice_target ( g . singularity ( ) , range ( args , args + 1 ) . . . ) , g . symmetry ( ) } ;
}
template < typename Variable , typename Target , typename Opt , typename . . . Args >
gf_view < Variable , scalar_valued , Opt > slice_target_to_scalar ( gf < Variable , Target , Opt > & g , Args & & . . . args ) {
return slice_target_to_scalar ( g ( ) , std : : forward < Args > ( args ) . . . ) ;
}
template < typename Variable , typename Target , typename Opt , typename . . . Args >
gf_const_view < Variable , scalar_valued , Opt > slice_target_to_scalar ( gf < Variable , Target , Opt > const & g , Args & & . . . args ) {
return slice_target_to_scalar ( g ( ) , std : : forward < Args > ( args ) . . . ) ;
}
// a scalar_valued gf can be viewed as a 1x1 matrix
2013-10-31 13:24:38 +01:00
template < typename Variable , typename Opt , bool IsConst >
2013-10-22 21:28:25 +02:00
gf_view < Variable , matrix_valued , Opt , IsConst >
reinterpret_scalar_valued_gf_as_matrix_valued ( gf_view < Variable , scalar_valued , Opt , IsConst > g ) {
typedef typename gf_view < Variable , matrix_valued , Opt , IsConst > : : data_view_t a_t ;
auto a = a_t { typename a_t : : indexmap_type ( join ( g . data ( ) . shape ( ) , make_shape ( 1 , 1 ) ) ) , g . data ( ) . storage ( ) } ;
2013-10-18 13:39:00 +02:00
return { g . mesh ( ) , a , g . singularity ( ) , g . symmetry ( ) } ;
2013-07-17 19:24:07 +02:00
}
2013-10-31 13:24:38 +01:00
template < typename Variable , typename Opt >
2013-10-22 21:28:25 +02:00
gf_view < Variable , matrix_valued , Opt > reinterpret_scalar_valued_gf_as_matrix_valued ( gf < Variable , scalar_valued , Opt > & g ) {
2013-10-18 13:39:00 +02:00
return reinterpret_scalar_valued_gf_as_matrix_valued ( g ( ) ) ;
2013-07-29 17:56:31 +02:00
}
2013-10-31 13:24:38 +01:00
template < typename Variable , typename Opt >
2013-10-22 21:28:25 +02:00
gf_const_view < Variable , matrix_valued , Opt >
reinterpret_scalar_valued_gf_as_matrix_valued ( gf < Variable , scalar_valued , Opt > const & g ) {
2013-10-18 13:39:00 +02:00
return reinterpret_scalar_valued_gf_as_matrix_valued ( g ( ) ) ;
2013-07-17 19:24:07 +02:00
}
2013-07-28 13:47:42 +02:00
/*
template < typename Variable1 , typename Variable2 , typename Target , typename Opt , bool V , typename . . . Args >
gf_view < Variable2 , Target , Opt > slice_mesh ( gf_impl < Variable1 , Target , Opt , V > const & g , Args . . . args ) {
return gf_view < Variable2 , Target , Opt > ( g . mesh ( ) . slice ( args . . . ) , g . data ( ) ( g . mesh ( ) . slice_get_range ( args . . . ) , arrays : : ellipsis ( ) ) , g . singularity ( ) , g . symmetry ( ) ) ;
} */
2013-07-19 13:28:30 +02:00
2013-10-22 21:28:25 +02:00
namespace gfs_implementation { // implement some default traits
// ------------------------- default factories ---------------------
2013-10-31 13:24:38 +01:00
// ----- tensor_valued
2013-10-22 21:28:25 +02:00
template < int R , typename Var , typename Opt > struct factories < Var , tensor_valued < R > , Opt > {
typedef gf < Var , tensor_valued < R > , Opt > gf_t ;
typedef tqa : : mini_vector < size_t , R > target_shape_t ;
typedef typename gf_t : : mesh_t mesh_t ;
static typename gf_t : : data_t make_data ( mesh_t const & m , target_shape_t shape ) {
typename gf_t : : data_t A ( shape . front_append ( m . size ( ) ) ) ;
A ( ) = 0 ;
return A ;
}
static typename gf_t : : singularity_t make_singularity ( mesh_t const & m , target_shape_t shape ) {
return typename gf_t : : singularity_t ( shape ) ;
}
} ;
2013-10-31 13:24:38 +01:00
// ----- matrix_valued
2013-10-22 21:28:25 +02:00
template < typename Var , typename Opt > struct factories < Var , matrix_valued , Opt > {
typedef gf < Var , matrix_valued , Opt > gf_t ;
typedef tqa : : mini_vector < size_t , 2 > target_shape_t ;
typedef typename gf_t : : mesh_t mesh_t ;
static typename gf_t : : data_t make_data ( mesh_t const & m , target_shape_t shape ) {
typename gf_t : : data_t A ( shape . front_append ( m . size ( ) ) ) ;
A ( ) = 0 ;
return A ;
}
static typename gf_t : : singularity_t make_singularity ( mesh_t const & m , target_shape_t shape ) {
return typename gf_t : : singularity_t ( shape ) ;
}
} ;
2013-10-31 13:24:38 +01:00
// ----- scalar_valued
2013-10-22 21:28:25 +02:00
template < typename Var , typename Opt > struct factories < Var , scalar_valued , Opt > {
typedef gf < Var , scalar_valued , Opt > gf_t ;
2013-10-23 15:51:51 +02:00
struct target_shape_t {
target_shape_t front_pop ( ) const { // this make the get_target_shape function works in this case...
return { } ;
}
2013-10-30 13:19:33 +01:00
target_shape_t ( ) = default ;
template < typename T > target_shape_t ( utility : : mini_vector < T , 0 > ) { }
2013-10-23 15:51:51 +02:00
} ;
2013-10-30 13:19:33 +01:00
2013-10-22 21:28:25 +02:00
typedef typename gf_t : : mesh_t mesh_t ;
static typename gf_t : : data_t make_data ( mesh_t const & m , target_shape_t shape ) {
typename gf_t : : data_t A ( m . size ( ) ) ;
A ( ) = 0 ;
return A ;
}
static typename gf_t : : singularity_t make_singularity ( mesh_t const & m , target_shape_t shape ) {
return typename gf_t : : singularity_t { 1 , 1 } ;
}
} ;
// --------------------- hdf5 ---------------------------------------
// scalar function : just add a _s
template < typename Variable , typename Opt > struct h5_name < Variable , scalar_valued , Opt > {
static std : : string invoke ( ) { return h5_name < Variable , matrix_valued , Opt > : : invoke ( ) + " _s " ; }
} ;
// the h5 write and read of gf members, so that we can specialize it e.g. for block gf
template < typename Variable , typename Target , typename Opt > struct h5_rw {
static void write ( h5 : : group gr , gf_const_view < Variable , Target , Opt > g ) {
h5_write ( gr , " data " , g . _data ) ;
h5_write ( gr , " singularity " , g . _singularity ) ;
h5_write ( gr , " mesh " , g . _mesh ) ;
h5_write ( gr , " symmetry " , g . _symmetry ) ;
}
template < bool B > static void read ( h5 : : group gr , gf_impl < Variable , Target , Opt , B , false > & g ) {
h5_read ( gr , " data " , g . _data ) ;
h5_read ( gr , " singularity " , g . _singularity ) ;
h5_read ( gr , " mesh " , g . _mesh ) ;
h5_read ( gr , " symmetry " , g . _symmetry ) ;
}
} ;
} // gfs_implementation
2013-10-23 15:51:51 +02:00
2013-07-17 19:24:07 +02:00
} }
2013-10-22 14:10:44 +02:00
// same as for arrays : views can not be swapped by the std::swap. Delete it
namespace std {
2013-10-22 21:28:25 +02:00
template < typename Variable , typename Target , typename Opt , bool C1 , bool C2 >
void swap ( triqs : : gfs : : gf_view < Variable , Target , Opt , C1 > & a , triqs : : gfs : : gf_view < Variable , Target , Opt , C2 > & b ) = delete ;
2013-10-22 14:10:44 +02:00
}
2013-07-17 19:24:07 +02:00
# include "./gf_expr.hpp"
# endif