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-16 23:55:26 +02:00
template < typename T > long get_shape ( std : : vector < T > const & x ) { return x . size ( ) ; }
2013-08-27 14:20:50 +02:00
template < typename Variable , typename Opt = void > struct gf_mesh ;
2013-08-24 17:24:02 +02:00
template < typename Variable , typename Target = matrix_valued , typename Opt = void > class gf ; // the regular type
template < typename Variable , typename Target = matrix_valued , typename Opt = void > class gf_view ; // the view type
2013-10-16 23:55:26 +02:00
template < typename Variable , typename Target , typename Opt , bool IsView > 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-16 23:55:26 +02:00
// This trait contains functions to read/write in hdf5 files. Can be specialized for some case (Cf block)
2013-07-17 19:24:07 +02:00
template < typename Variable , typename Target , typename Opt > struct h5_name ; // value is a const char *
2013-07-29 17:56:31 +02:00
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 " ; } } ;
2013-10-16 23:55:26 +02:00
// 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 , bool IsView > struct h5_rw {
static void write ( h5 : : group gr , gf_impl < Variable , Target , Opt , IsView > const & 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 ) ;
}
static void read ( h5 : : group gr , gf_impl < Variable , Target , Opt , IsView > & 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 ) ;
}
} ;
// factories regroup all factories (constructors..) for all types of gf.
template < typename Variable , typename Target , typename Opt > struct factories ;
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 ) ; }
} ;
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-07-29 17:56:31 +02:00
2013-10-16 23:55:26 +02:00
template < typename Var , typename Opt > struct factories < Var , scalar_valued , Opt > {
typedef gf < Var , scalar_valued , Opt > gf_t ;
struct 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 ( 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 } ; }
2013-07-17 19:24:07 +02:00
} ;
2013-07-28 13:28:19 +02:00
} // gfs_implementation
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-16 23:55:26 +02:00
template < typename G >
auto get_gf_data_shape ( G const & g ) DECL_AND_RETURN ( g . get_data_shape ( ) ) ;
2013-07-17 19:24:07 +02:00
// ---------------------- implementation --------------------------------
/// A common implementation class for gf and gf_view. They will only redefine contructor and = ...
template < typename Variable , typename Target , typename Opt , bool IsView > class gf_impl :
2013-10-16 23:55:26 +02:00
TRIQS_CONCEPT_TAG_NAME ( ImmutableGreenFunction ) {
2013-07-17 19:24:07 +02:00
public :
typedef gf_view < Variable , Target , Opt > 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-16 23:55:26 +02:00
typedef typename std : : conditional < IsView , data_view_t , 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)
public : //everyone can make a copy (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 ) { }
gf_impl ( gf_impl & & ) = default ;
protected :
gf_impl ( gf_impl < Variable , Target , Opt , ! IsView > const & x ) : _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 ) ) { }
void operator = ( gf_impl const & rhs ) = delete ; // done in derived class.
void swap_impl ( gf_impl & b ) noexcept {
using std : : swap ;
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 ) ;
}
public :
// ------------- All the call operators -----------------------------
// First, a simple () returns a view, like for an array...
view_type operator ( ) ( ) const { return * this ; }
/// Calls are (perfectly) forwarded to the evaluator::operator(), except mesh_point_t and when
/// there is at least one lazy argument ...
template < typename Arg0 , typename . . . Args > // match any argument list, picking out the first type : () is not permitted
typename std : : add_const <
typename boost : : lazy_disable_if < // disable the template if one the following conditions it true
boost : : mpl : : or_ < // starting condition [OR]
clef : : is_any_lazy < Arg0 , Args . . . > // One of Args is a lazy expression
2013-10-16 23:55:26 +02:00
, boost : : mpl : : bool_ < ( sizeof . . . ( Args ) ! = evaluator_t : : arity - 1 ) & & ( evaluator_t : : arity ! = - 1 ) > // if -1 : no check
> , // end of OR
2013-07-17 19:24:07 +02:00
std : : result_of < evaluator_t ( gf_impl * , Arg0 , Args . . . ) > // what is the result type of call
> : : type // end of lazy_disable_if
> : : type // end of add_Const
operator ( ) ( Arg0 & & arg0 , Args & & . . . args ) const { return _evaluator ( this , std : : forward < Arg0 > ( arg0 ) , std : : forward < Args > ( args ) . . . ) ; }
2013-10-16 23:55:26 +02:00
// WHY SEPARATE ARg0 ?
template < typename Arg0 , typename . . . Args >
typename clef : : _result_of : : make_expr_call < gf_impl & , Arg0 , Args . . . > : : type
operator ( ) ( Arg0 & & arg0 , Args & & . . . args ) & {
return clef : : make_expr_call ( * this , std : : forward < Arg0 > ( arg0 ) , std : : forward < Args > ( args ) . . . ) ;
}
template < typename Arg0 , typename . . . Args >
typename clef : : _result_of : : make_expr_call < gf_impl const & , Arg0 , Args . . . > : : type
operator ( ) ( Arg0 & & arg0 , Args & & . . . args ) const & {
return clef : : make_expr_call ( * this , std : : forward < Arg0 > ( arg0 ) , std : : forward < Args > ( args ) . . . ) ;
}
2013-10-16 23:48:14 +02:00
2013-07-17 19:24:07 +02:00
template < typename Arg0 , typename . . . Args >
2013-10-16 23:55:26 +02:00
typename clef : : _result_of : : make_expr_call < gf_impl , Arg0 , Args . . . > : : type
operator ( ) ( Arg0 & & arg0 , Args & & . . . args ) & & {
return clef : : make_expr_call ( std : : move ( * this ) , std : : forward < Arg0 > ( arg0 ) , std : : forward < Args > ( args ) . . . ) ;
2013-07-17 19:24:07 +02:00
}
2013-09-07 15:27:10 +02:00
2013-07-28 13:47:42 +02:00
/*
2013-07-17 19:24:07 +02:00
// on mesh component for composite meshes
// enable iif the first arg is a mesh_point_t for the first component of the mesh_t
template < typename Arg0 , typename . . . Args , bool MeshIsComposite = std : : is_base_of < tag : : composite , mesh_t > : : value >
2013-09-07 15:27:10 +02:00
typename std : : enable_if < MeshIsComposite & & std : : is_base_of < tag : : mesh_point , Arg0 > : : value , r_type > : : type
operator ( ) ( Arg0 const & arg0 , Args const & . . . args )
{ return _data_proxy ( _data , _mesh . mesh_pt_components_to_linear ( arg0 , args . . . ) ) ; }
2013-07-17 19:24:07 +02:00
template < typename Arg0 , typename . . . Args , bool MeshIsComposite = std : : is_base_of < tag : : composite , mesh_t > : : value >
2013-09-07 15:27:10 +02:00
typename std : : enable_if < MeshIsComposite & & std : : is_base_of < tag : : mesh_point , Arg0 > : : value , cr_type > : : type
operator ( ) ( Arg0 const & arg0 , Args const & . . . args ) const
{ return _data_proxy ( _data , _mesh . mesh_pt_components_to_linear ( arg0 , args . . . ) ) ; }
*/
2013-07-28 13:47:42 +02:00
//// [] 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 ;
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
/// A direct access to the grid point
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 ) . . . ) ) ) ; }
private :
struct _on_mesh_wrapper_const {
gf_impl const & f ; _on_mesh_wrapper_const ( gf_impl const & _f ) : f ( _f ) { }
template < typename . . . Args > cr_type operator ( ) ( Args & & . . . args ) const { return f . on_mesh ( std : : forward < Args > ( args ) . . . ) ; }
} ;
struct _on_mesh_wrapper {
gf_impl & f ; _on_mesh_wrapper ( gf_impl & _f ) : f ( _f ) { }
template < typename . . . Args > r_type operator ( ) ( Args & & . . . args ) const { return f . on_mesh ( std : : forward < Args > ( args ) . . . ) ; }
} ;
_on_mesh_wrapper_const friend on_mesh ( gf_impl const & f ) { return f ; }
_on_mesh_wrapper friend on_mesh ( gf_impl & f ) { return f ; }
public :
//----------------------------- 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-16 23:55:26 +02:00
friend class gfs_implementation : : h5_rw < Variable , Target , Opt , IsView > ;
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-16 23:55:26 +02:00
gfs_implementation : : h5_rw < Variable , Target , Opt , IsView > : : 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-16 23:55:26 +02:00
gfs_implementation : : h5_rw < Variable , Target , Opt , IsView > : : 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
// Interaction with the CLEF library : auto assignment of the gf (gf(om_) << expression fills the functions by evaluation of expression)
template < typename RHS > friend void triqs_clef_auto_assign ( gf_impl & g , RHS const & rhs ) {
// access to the data . Beware, we view it as a *matrix* NOT an array... (crucial for assignment to scalars !)
g . triqs_clef_auto_assign_impl ( rhs , typename std : : is_base_of < tag : : composite , mesh_t > : : type ( ) ) ;
assign_from_expression ( g . singularity ( ) , rhs ) ;
// 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
}
// enable the writing g[om_] << .... also
template < typename RHS > friend void triqs_clef_auto_assign_subscript ( gf_impl & g , RHS rhs ) { triqs_clef_auto_assign ( g , rhs ) ; }
private :
template < typename RHS > void triqs_clef_auto_assign_impl ( RHS const & rhs , std : : integral_constant < bool , false > ) {
for ( auto const & w : this - > mesh ( ) ) ( * this ) [ w ] = rhs ( w ) ;
//for (auto const & w: this->mesh()) (*this)[w] = rhs(typename B::mesh_t::mesh_point_t::cast_t(w));
}
template < typename RHS > void triqs_clef_auto_assign_impl ( RHS const & rhs , std : : integral_constant < bool , true > ) {
for ( auto const & w : this - > mesh ( ) ) {
//std::cout << "abot "<<w.components_tuple()<<std::endl ;
//std::cout << "eefef "<< triqs::tuple::apply(rhs,w.components_tuple()) << std::endl ;
( * this ) [ w ] = triqs : : tuple : : apply ( rhs , w . components_tuple ( ) ) ;
//std::cout << "done "<<std::endl ;
}
//for (auto w: this->mesh()) triqs::tuple::apply(*this,w.components_tuple()) = triqs::tuple::apply(rhs,w.components_tuple());
}
2013-07-17 19:24:07 +02:00
} ;
// ---------------------------------------------------------------------------------
///The regular class of GF
template < typename Variable , typename Target , typename Opt > class gf : public gf_impl < Variable , Target , Opt , false > {
typedef gf_impl < Variable , Target , Opt , 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 :
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 ) { }
2013-10-16 23:55:26 +02:00
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-16 23:55:26 +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 ,
typename B : : evaluator_t const & eval = typename B : : evaluator_t ( )
) :
B ( std : : move ( m ) , std : : move ( dat ) , si , s , eval ) { }
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
} ;
// ---------------------------------------------------------------------------------
///The View class of GF
template < typename Variable , typename Target , typename Opt > class gf_view : public gf_impl < Variable , Target , Opt , true > {
typedef gf_impl < Variable , Target , Opt , true > B ;
public :
gf_view ( gf_view const & g ) : B ( g ) { }
gf_view ( gf_view & & g ) noexcept : B ( std : : move ( g ) ) { }
template < bool V > gf_view ( gf_impl < Variable , Target , Opt , V > const & g ) : B ( g ) { }
2013-09-06 15:53:28 +02:00
template < typename D >
2013-07-17 19:24:07 +02:00
gf_view ( typename B : : mesh_t const & m ,
2013-09-06 15:53:28 +02:00
D const & dat , typename B : : singularity_view_t const & t , typename B : : symmetry_t const & s ,
2013-07-17 19:24:07 +02:00
typename B : : evaluator_t const & e = typename B : : evaluator_t ( ) ) :
B ( m , factory < typename B : : data_t > ( dat ) , t , s , e ) { }
friend void swap ( gf_view & a , gf_view & b ) noexcept { a . swap_impl ( b ) ; }
void rebind ( gf_view const & X ) noexcept {
this - > _mesh = X . _mesh ; this - > _symmetry = X . _symmetry ;
this - > _data_proxy . rebind ( this - > _data , X ) ;
this - > _singularity . rebind ( X . _singularity ) ;
}
gf_view & operator = ( gf_view const & rhs ) { triqs_gf_view_assign_delegation ( * this , rhs ) ; return * this ; }
template < typename RHS > gf_view & operator = ( RHS const & rhs ) { triqs_gf_view_assign_delegation ( * this , rhs ) ; return * this ; }
} ; // 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-07-19 13:28:30 +02:00
template < typename Tag , typename D , typename Target = matrix_valued > struct gf_keeper { gf_view < D , Target > g ; gf_keeper ( gf_view < D , Target > const & g_ ) : g ( g_ ) { } } ;
2013-07-17 19:24:07 +02:00
// ---------------------------------- slicing ------------------------------------
2013-07-28 13:47:42 +02:00
2013-07-19 13:28:30 +02:00
//slice
2013-07-17 19:24:07 +02:00
template < typename Variable , typename Target , typename Opt , bool V , typename . . . Args >
2013-10-16 23:55:26 +02:00
gf_view < Variable , matrix_valued , Opt > slice_target ( gf_impl < Variable , Target , Opt , V > const & g , Args & & . . . args ) {
2013-07-19 13:28:30 +02:00
static_assert ( std : : is_same < Target , matrix_valued > : : value , " slice_target only for matrix_valued GF's " ) ;
using arrays : : range ;
//auto sg=slice_target (g.singularity(),range(args,args+1)...);
2013-10-16 23:55:26 +02:00
return gf_view < Variable , matrix_valued , Opt > ( g . mesh ( ) , g . data ( ) ( range ( ) , std : : forward < Args > ( args ) . . . ) , slice_target ( g . singularity ( ) , std : : forward < Args > ( args ) . . . ) , g . symmetry ( ) ) ;
2013-07-17 19:24:07 +02:00
}
template < typename Variable , typename Target , typename Opt , bool V , typename . . . Args >
2013-10-16 23:55:26 +02:00
gf_view < Variable , scalar_valued , Opt > slice_target_to_scalar ( gf_impl < Variable , Target , Opt , V > const & g , Args & & . . . args ) {
2013-07-19 13:28:30 +02:00
static_assert ( std : : is_same < Target , matrix_valued > : : value , " slice_target only for matrix_valued GF's " ) ;
using arrays : : range ;
auto sg = slice_target ( g . singularity ( ) , range ( args , args + 1 ) . . . ) ;
2013-10-16 23:55:26 +02:00
return gf_view < Variable , scalar_valued , Opt > ( g . mesh ( ) , g . data ( ) ( range ( ) , std : : forward < Args > ( args ) . . . ) , sg , g . symmetry ( ) ) ;
2013-07-29 17:56:31 +02:00
}
2013-09-07 15:27:10 +02:00
// a scalar_valued gf can be viewed as a 1x1 matrix
template < typename Variable , typename Opt , bool V , typename . . . Args >
2013-07-29 17:56:31 +02:00
gf_view < Variable , matrix_valued , Opt > reinterpret_scalar_valued_gf_as_matrix_valued ( gf_impl < Variable , scalar_valued , Opt , V > const & g ) {
2013-10-16 23:55:26 +02:00
typedef typename gf_view < Variable , matrix_valued , Opt > : : 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-07-29 17:56:31 +02:00
return gf_view < Variable , matrix_valued , Opt > ( g . mesh ( ) , a , g . singularity ( ) , g . symmetry ( ) ) ;
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-07-17 19:24:07 +02:00
} }
# include "./gf_expr.hpp"
# endif