~ubuntu-branches/ubuntu/raring/openwalnut/raring

« back to all changes in this revision

Viewing changes to src/core/common/math/WTensorBase.h

  • Committer: Package Import Robot
  • Author(s): Sebastian Eichelbaum
  • Date: 2012-12-12 11:26:32 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20121212112632-xhiuwkxuz5h0idkh
Tags: 1.3.1+hg5849-1
* Minor changes compared to 1.3.0 but included several bug fixes.
* See http://www.openwalnut.org/versions/4

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <vector>
31
31
 
32
32
#include <boost/static_assert.hpp>
 
33
#include <boost/array.hpp>
33
34
 
34
35
#include "../WAssert.h"
35
36
#include "WCompileTimeFunctions.h"
62
63
 * \param pos The position to be iterated.
63
64
 */
64
65
template< std::size_t order, std::size_t dim >
65
 
inline void positionIterateOneStep( std::vector< std::size_t >& pos ) // NOLINT, need a reference here
 
66
inline void positionIterateOneStep( boost::array< std::size_t, order >& pos ) // NOLINT, need a reference here
66
67
{
67
68
    WAssert( pos.size() >= order, "" );
68
69
 
97
98
 * \param pos The sorted(!) position to be iterated.
98
99
 */
99
100
template< std::size_t order, std::size_t dim >
100
 
inline void positionIterateSortedOneStep( std::vector< std::size_t >& pos ) // NOLINT, need a reference here
 
101
inline void positionIterateSortedOneStep( boost::array< std::size_t, order >& pos ) // NOLINT, need a reference here
101
102
{
102
103
    WAssert( pos.size() >= order, "" );
103
104
 
288
289
     */
289
290
    bool operator != ( WTensorBase const& other ) const;
290
291
 
 
292
    /**
 
293
     * Declare a compile-time constant as enum and not as static constant.
 
294
     */
 
295
    enum
 
296
    {
 
297
        /**
 
298
         * The number of elements to store.
 
299
         */
 
300
        dataSize = WPower< dim, order >::value
 
301
    };
 
302
 
291
303
private:
292
304
    /**
293
305
     * Calculate the position of the element in the data vector. The function
300
312
    template< typename Index_T >
301
313
    static inline std::size_t getPos( Index_T pos[] );
302
314
 
303
 
    /**
304
 
     * Stores all elements.
305
 
     */
306
 
    std::vector< Data_T > m_data;
307
 
 
308
 
    /**
309
 
     * Declare a compile-time constant as enum and not as static constant.
310
 
     */
311
 
    enum
312
 
    {
313
 
        /**
314
 
         * The number of elements to store.
315
 
         */
316
 
        dataSize = WPower< dim, order >::value
317
 
    };
 
315
    //! Stores all elements.
 
316
    //std::vector< Data_T > m_data;
 
317
    boost::array< Data_T, dataSize > m_data;
318
318
};
319
319
 
320
320
template< std::size_t order, std::size_t dim, typename Data_T >
321
321
WTensorBase< order, dim, Data_T >::WTensorBase()
322
 
    : m_data( dataSize, Data_T() )
323
322
{
 
323
    m_data.assign( Data_T() );
324
324
}
325
325
 
326
326
template< std::size_t order, std::size_t dim, typename Data_T >
331
331
 
332
332
template< std::size_t order, std::size_t dim, typename Data_T >
333
333
WTensorBase< order, dim, Data_T >::WTensorBase( WTensorBaseSym< order, dim, Data_T > const& t )
334
 
    : m_data( dataSize )
335
334
{
336
335
    *this = t;
337
336
}
346
345
template< std::size_t order, std::size_t dim, typename Data_T >
347
346
WTensorBase< order, dim, Data_T > const& WTensorBase< order, dim, Data_T >::operator = ( WTensorBaseSym< order, dim, Data_T > const& t )
348
347
{
349
 
    std::vector< std::size_t > pos( order, 0 );
 
348
    boost::array< std::size_t, order > pos;
 
349
    pos.assign( 0 );
350
350
 
351
351
    for( std::size_t k = 0; k < dataSize; ++k )
352
352
    {
353
 
        ( *this )[ pos ] = t[ pos ];
 
353
        ( *this )[ &pos[ 0 ] ] = t[ &pos[ 0 ] ];
354
354
        positionIterateOneStep< order, dim >( pos );
355
355
    }
356
356
 
474
474
    explicit WTensorBase( WTensorBaseSym< 0, dim, Data_T > const& t )
475
475
        : m_data()
476
476
    {
477
 
        m_data = t.operator[]< std::size_t >( NULL );
 
477
        m_data = t.template operator[]< std::size_t >( NULL );
478
478
    }
479
479
 
480
480
    /**
499
499
     */
500
500
    WTensorBase const& operator = ( WTensorBaseSym< 0, dim, Data_T > const& t )
501
501
    {
502
 
        m_data = t.operator[]< std::size_t >( NULL );
 
502
        m_data = t.template operator[]< std::size_t >( NULL );
503
503
        return *this;
504
504
    }
505
505
 
653
653
 
654
654
public:
655
655
    /**
 
656
     * Declare a compile-time constant as enum and not as static constant.
 
657
     */
 
658
    enum
 
659
    {
 
660
        /**
 
661
         * The number of elements to store.
 
662
         */
 
663
        dataSize = WBinom< order + dim - 1, order >::value
 
664
    };
 
665
 
 
666
    /**
656
667
     * Standard constructor.
657
668
     *
658
669
     * All elements are set to Data_T().
668
679
    explicit WTensorBaseSym( const WValue< Data_T >& data );
669
680
 
670
681
    /**
 
682
     * Constructs the symmetrical tensor and initialize with the given data.
 
683
     *
 
684
     * \param data The components of the symmetrical tensor: Take care of the
 
685
     * ordering of the components to match the ordering in \see m_data.
 
686
     */
 
687
    explicit WTensorBaseSym( const boost::array< Data_T, dataSize >& data );
 
688
 
 
689
    /**
671
690
     * Copy constructor.
672
691
     *
673
692
     * \param t The tensor to copy from.
698
717
    std::size_t getOrder() const;
699
718
 
700
719
    /**
 
720
     * Set internal data from a WValue.
 
721
     *
 
722
     * \param values The input values.
 
723
     */
 
724
    void setValues( WValue< Data_T > const& values );
 
725
 
 
726
    /**
 
727
     * Set internal data from a boost array.
 
728
     *
 
729
     * \param values The input values.
 
730
     */
 
731
    void setValues( boost::array< Data_T, dataSize > const& values );
 
732
 
 
733
    /**
701
734
     * Get the element at a specific position.
702
735
     *
703
736
     * \param indices A std::vector of indices that has a size of at least order.
759
792
     */
760
793
    bool operator != ( WTensorBaseSym const& other ) const;
761
794
 
762
 
private:
 
795
protected:
763
796
    /**
764
797
     * Stores the elements of this tensor lexicographical ordered on their
765
798
     * indices, where for each set of permutations the lexicographical lowest
766
799
     * index is used.
767
800
     */
768
 
    std::vector< Data_T > m_data;
769
 
 
770
 
    /**
771
 
     * Declare a compile-time constant as enum and not as static constant.
772
 
     */
773
 
    enum
774
 
    {
775
 
        /**
776
 
         * The number of elements to store.
777
 
         */
778
 
        dataSize = WBinom< order + dim - 1, order >::value
779
 
    };
780
 
 
 
801
    // std::vector< Data_T > m_data;
 
802
    boost::array< Data_T, dataSize > m_data;
 
803
 
 
804
private:
781
805
    /**
782
806
     * A class that maps symmetric tensor indices to vector positions.
783
807
     */
833
857
WTensorBaseSym< order, dim, Data_T >::PositionIndexer::PositionIndexer()
834
858
{
835
859
    // the map uses lexical ordering of vectors
836
 
    std::map< std::vector< std::size_t >, std::size_t > m;
 
860
    std::map< boost::array< std::size_t, order >, std::size_t > m;
837
861
 
838
862
    // fill the map with all possible combinations of indices, where
839
863
    // every combination of indices appears in ascending order of indices
840
 
    std::vector< std::size_t > pos( order, 0 );
 
864
    boost::array< std::size_t, order > pos;
 
865
    pos.assign( 0 );
 
866
 
841
867
    for( std::size_t k = 0; k < dataSize; ++k )
842
868
    {
843
869
        // enumerate the position
844
 
        m[ pos ] = k;
 
870
        // m[ pos ] = k;
 
871
        m.insert( std::make_pair( pos, k ) );
845
872
 
846
873
        // get the next sorted combination
847
874
        positionIterateSortedOneStep< order, dim >( pos );
848
875
    }
849
876
 
850
877
    // now iterate all possible sets of indices
851
 
    pos = std::vector< std::size_t >( order, 0 );
852
 
    std::vector< std::size_t > _p( order, 0 );
 
878
    pos.assign( 0 );
 
879
 
 
880
    boost::array< std::size_t, order > _p;
 
881
    _p.assign( 0 );
 
882
 
853
883
    for( std::size_t k = 0; k < WPower< dim, order >::value; ++k )
854
884
    {
855
885
        _p = pos;
858
888
        std::sort( _p.begin(), _p.end() );
859
889
 
860
890
        // now map the arbitrary ordered indices to the position of the ordered set in m (and thus in m_data)
861
 
        m_positions[ pos ] = m[ _p ];
 
891
        m_positions[ &pos[ 0 ] ] = m[ _p ];
862
892
 
863
 
        // the map should already know the sorted position,
 
893
        // the map should already knows the sorted position,
864
894
        // it should never be added by std::map::operator [] at this point
865
895
        WAssert( m.size() == dataSize, "" );
866
896
 
880
910
 
881
911
template< std::size_t order, std::size_t dim, typename Data_T >
882
912
WTensorBaseSym< order, dim, Data_T >::WTensorBaseSym()
883
 
    : m_data( dataSize, Data_T() )
884
913
{
 
914
    m_data.assign( Data_T() );
885
915
}
886
916
 
887
917
template< std::size_t order, std::size_t dim, typename Data_T >
888
918
WTensorBaseSym< order, dim, Data_T >::WTensorBaseSym( const WValue< Data_T >& data )
889
 
    : m_data( &data[0], &data[0] + data.size() )
890
919
{
891
920
    WAssert( dataSize == m_data.size(), "Number of given components does not match the order and dimension of this symmetric tensor" );
 
921
    std::copy( &data[ 0 ], &data[ 0 ] + data.size(), &m_data[ 0 ] );
 
922
}
 
923
 
 
924
template< std::size_t order, std::size_t dim, typename Data_T >
 
925
WTensorBaseSym< order, dim, Data_T >::WTensorBaseSym( const boost::array< Data_T, dataSize >& data )
 
926
{
 
927
    std::copy( &data[ 0 ], &data[ 0 ] + dataSize, &m_data[ 0 ] );
892
928
}
893
929
 
894
930
template< std::size_t order, std::size_t dim, typename Data_T >
917
953
}
918
954
 
919
955
template< std::size_t order, std::size_t dim, typename Data_T >
 
956
void WTensorBaseSym< order, dim, Data_T >::setValues( WValue< Data_T > const& values )
 
957
{
 
958
    WAssert( m_data.size() == values.size(), "Number of given components does not match the order and dimension of this symmetric tensor" );
 
959
    std::copy( &values[ 0 ], &values[ 0 ] + values.size(), &m_data[ 0 ] );
 
960
}
 
961
 
 
962
template< std::size_t order, std::size_t dim, typename Data_T >
 
963
void WTensorBaseSym< order, dim, Data_T >::setValues( boost::array< Data_T, dataSize > const& values )
 
964
{
 
965
    std::copy( &values[ 0 ], &values[ 0 ] + dataSize, &m_data[ 0 ] );
 
966
}
 
967
 
 
968
template< std::size_t order, std::size_t dim, typename Data_T >
920
969
template< typename Index_T >
921
970
Data_T& WTensorBaseSym< order, dim, Data_T >::operator[] ( std::vector< Index_T > const& indices )
922
971
{
1098
1147
        return m_data != other.m_data;
1099
1148
    }
1100
1149
 
1101
 
private:
1102
 
    /**
1103
 
     * Stores the value.
1104
 
     */
1105
 
    Data_T m_data;
1106
 
 
1107
1150
    /**
1108
1151
     * Declare a compile-time constant as enum and not as static constant.
1109
1152
     */
1114
1157
         */
1115
1158
        dataSize = 1
1116
1159
    };
 
1160
 
 
1161
protected:
 
1162
    /**
 
1163
     * Stores the value.
 
1164
     */
 
1165
    Data_T m_data;
 
1166
 
 
1167
private:
1117
1168
};
1118
1169
 
1119
1170
// ################################### class WTensorFunc<> ######################################
1131
1182
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t order, std::size_t dim, typename Data_T > //NOLINT
1132
1183
class WTensorFunc : public TensorBase_T< order, dim, Data_T >
1133
1184
{
 
1185
public:
 
1186
    /**
 
1187
     * Default constructor.
 
1188
     */
 
1189
    WTensorFunc();
 
1190
 
 
1191
    /**
 
1192
     * Initializes the tensor with the given data.
 
1193
     *
 
1194
     * \param data Components in same ordering as the components of the TensorBase class.
 
1195
     */
 
1196
    explicit WTensorFunc( const WValue< Data_T >& data );
 
1197
 
 
1198
    /**
 
1199
     * Initializes the tensor with the given data.
 
1200
     *
 
1201
     * \param data Components in same ordering as the components of the TensorBase class.
 
1202
     */
 
1203
    explicit WTensorFunc( const boost::array< Data_T, TensorBase_T< order, dim, Data_T >::dataSize >& data );
1134
1204
};
1135
1205
 
 
1206
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t order, std::size_t dim, typename Data_T >
 
1207
WTensorFunc< TensorBase_T, order, dim, Data_T >::WTensorFunc()
 
1208
    : TensorBase_T< order, dim, Data_T >()
 
1209
{
 
1210
}
 
1211
 
 
1212
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t order, std::size_t dim, typename Data_T >
 
1213
WTensorFunc< TensorBase_T, order, dim, Data_T >::WTensorFunc( const WValue< Data_T >& data )
 
1214
    : TensorBase_T< order, dim, Data_T >( data )
 
1215
{
 
1216
}
 
1217
 
 
1218
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t order, std::size_t dim, typename Data_T >
 
1219
WTensorFunc< TensorBase_T, order, dim, Data_T >::WTensorFunc( const boost::array< Data_T, TensorBase_T< order, dim, Data_T >::dataSize >& data )
 
1220
    : TensorBase_T< order, dim, Data_T >( data )
 
1221
{
 
1222
}
 
1223
 
 
1224
 
1136
1225
/**
1137
1226
 * Implements the operator () for an order of 6.
1138
1227
 *
1146
1235
{
1147
1236
public:
1148
1237
    /**
 
1238
     * Default constructor.
 
1239
     */
 
1240
    WTensorFunc();
 
1241
 
 
1242
    /**
 
1243
     * Initializes the tensor with the given data.
 
1244
     *
 
1245
     * \param data Components in same ordering as the components of the TensorBase class.
 
1246
     */
 
1247
    explicit WTensorFunc( const WValue< Data_T >& data );
 
1248
 
 
1249
    /**
 
1250
     * Initializes the tensor with the given data.
 
1251
     *
 
1252
     * \param data Components in same ordering as the components of the TensorBase class.
 
1253
     */
 
1254
    explicit WTensorFunc( const boost::array< Data_T, TensorBase_T< 6, dim, Data_T >::dataSize  >& data );
 
1255
 
 
1256
    /**
1149
1257
     * Access operator.
1150
1258
     *
1151
1259
     * \param i0 An index.
1174
1282
    Data_T const& operator() ( std::size_t i0, std::size_t i1, std::size_t i2, std::size_t i3, std::size_t i4, std::size_t i5 ) const;
1175
1283
};
1176
1284
 
 
1285
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T >
 
1286
WTensorFunc< TensorBase_T, 6, dim, Data_T >::WTensorFunc()
 
1287
    : TensorBase_T< 6, dim, Data_T >()
 
1288
{
 
1289
}
 
1290
 
 
1291
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T >
 
1292
WTensorFunc< TensorBase_T, 6, dim, Data_T >::WTensorFunc( const WValue< Data_T >& data )
 
1293
    : TensorBase_T< 6, dim, Data_T >( data )
 
1294
{
 
1295
}
 
1296
 
 
1297
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T >
 
1298
WTensorFunc< TensorBase_T, 6, dim, Data_T >::WTensorFunc( const boost::array< Data_T, TensorBase_T< 6, dim, Data_T >::dataSize >& data )
 
1299
    : TensorBase_T< 6, dim, Data_T >( data )
 
1300
{
 
1301
}
 
1302
 
1177
1303
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T > //NOLINT
1178
1304
Data_T& WTensorFunc< TensorBase_T, 6, dim, Data_T >::operator() ( std::size_t i0, std::size_t i1, std::size_t i2,
1179
1305
                                                                  std::size_t i3, std::size_t i4, std::size_t i5 )
1262
1388
{
1263
1389
public:
1264
1390
    /**
 
1391
     * Default constructor.
 
1392
     */
 
1393
    WTensorFunc();
 
1394
 
 
1395
    /**
 
1396
     * Initializes the tensor with the given data.
 
1397
     *
 
1398
     * \param data Components in same ordering as the components of the TensorBase class.
 
1399
     */
 
1400
    explicit WTensorFunc( const WValue< Data_T >& data );
 
1401
 
 
1402
    /**
 
1403
     * Initializes the tensor with the given data.
 
1404
     *
 
1405
     * \param data Components in same ordering as the components of the TensorBase class.
 
1406
     */
 
1407
    explicit WTensorFunc( const boost::array< Data_T, TensorBase_T< 4, dim, Data_T >::dataSize  >& data );
 
1408
 
 
1409
    /**
1265
1410
     * Access operator.
1266
1411
     *
1267
1412
     * \param i0 An index.
1286
1431
    Data_T const& operator() ( std::size_t i0, std::size_t i1, std::size_t i2, std::size_t i3 ) const;
1287
1432
};
1288
1433
 
 
1434
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T >
 
1435
WTensorFunc< TensorBase_T, 4, dim, Data_T >::WTensorFunc()
 
1436
    : TensorBase_T< 4, dim, Data_T >()
 
1437
{
 
1438
}
 
1439
 
 
1440
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T >
 
1441
WTensorFunc< TensorBase_T, 4, dim, Data_T >::WTensorFunc( const WValue< Data_T >& data )
 
1442
    : TensorBase_T< 4, dim, Data_T >( data )
 
1443
{
 
1444
}
 
1445
 
 
1446
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T >
 
1447
WTensorFunc< TensorBase_T, 4, dim, Data_T >::WTensorFunc( const boost::array< Data_T, TensorBase_T< 4, dim, Data_T >::dataSize >& data )
 
1448
    : TensorBase_T< 4, dim, Data_T >( data )
 
1449
{
 
1450
}
 
1451
 
1289
1452
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T > //NOLINT
1290
1453
Data_T& WTensorFunc< TensorBase_T, 4, dim, Data_T >::operator() ( std::size_t i0, std::size_t i1, std::size_t i2, std::size_t i3 )
1291
1454
{
1374
1537
    explicit WTensorFunc( const WValue< Data_T >& data );
1375
1538
 
1376
1539
    /**
 
1540
     * Initializes the tensor with the given data.
 
1541
     *
 
1542
     * \param data Components in same ordering as the components of the TensorBase class.
 
1543
     */
 
1544
    explicit WTensorFunc( const boost::array< Data_T, TensorBase_T< 2, dim, Data_T >::dataSize  >& data );
 
1545
 
 
1546
    /**
1377
1547
     * Access operator.
1378
1548
     *
1379
1549
     * \param i0 An index.
1411
1581
{
1412
1582
}
1413
1583
 
 
1584
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T >
 
1585
WTensorFunc< TensorBase_T, 2, dim, Data_T >::WTensorFunc( const boost::array< Data_T, TensorBase_T< 2, dim, Data_T >::dataSize >& data )
 
1586
    : TensorBase_T< 2, dim, Data_T >( data )
 
1587
{
 
1588
}
 
1589
 
1414
1590
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T > //NOLINT
1415
1591
Data_T& WTensorFunc< TensorBase_T, 2, dim, Data_T >::operator() ( std::size_t i0, std::size_t i1 )
1416
1592
{
1541
1717
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T > //NOLINT
1542
1718
Data_T const& WTensorFunc< TensorBase_T, 0, dim, Data_T >::operator() () const
1543
1719
{
1544
 
#ifdef _MSC_VER
1545
 
    return TensorBase_T< 0, dim, Data_T >::operator[]< std::size_t >( NULL );
1546
 
#else
1547
1720
    return TensorBase_T< 0, dim, Data_T >::template operator[]< std::size_t >( NULL );
1548
 
#endif
1549
1721
}
1550
1722
 
1551
1723
template< template< std::size_t, std::size_t, typename > class TensorBase_T, std::size_t dim, typename Data_T > //NOLINT
1552
1724
WTensorFunc< TensorBase_T, 0, dim, Data_T >::operator Data_T() const
1553
1725
{
1554
 
#ifdef _MSC_VER
1555
 
    return TensorBase_T< 0, dim, Data_T >::operator[]< std::size_t >( NULL );
1556
 
#else
1557
1726
    return TensorBase_T< 0, dim, Data_T >::template operator[]< std::size_t >( NULL );
1558
 
#endif
1559
1727
}
1560
1728
 
1561
1729
#endif  // WTENSORBASE_H