FourthOrderTensor2.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 
00030 #ifndef _FOURTHORDERTENSOR2_HPP_
00031 #define _FOURTHORDERTENSOR2_HPP_
00032 
00033 #include <cassert>
00034 #include <vector>
00035 
00036 #include <boost/numeric/ublas/vector.hpp>
00037 #include <boost/numeric/ublas/matrix.hpp>
00038 using namespace boost::numeric::ublas;
00039 #include "Exception.hpp"
00040 
00041 
00048 template <int DIM>
00049 class FourthOrderTensor2
00050 {
00051 private:
00052     std::vector<double> mData;
00053     unsigned mDimSqd;
00054     unsigned mDimCubed;
00055     unsigned mDimToFour;
00056 
00057 public:
00058     FourthOrderTensor2()
00059     {
00060         // check dim>0 but <4
00061         assert(DIM>0);
00062         assert(DIM<4);
00063 
00064         mDimSqd = DIM*DIM;
00065         mDimCubed = DIM*DIM*DIM;
00066         mDimToFour = DIM*DIM*DIM*DIM;
00067 
00068         // allocate memory and zero entries
00069         mData.resize(mDimToFour, 0.0);
00070     }
00071 
00084     void SetAsProduct(FourthOrderTensor2<DIM>& tensor, const c_matrix<double,DIM,DIM>& matrix, unsigned component)
00085     {
00086         Zero();
00087 
00088         // messy repeated code but not sure how to do this neatly and efficiently..
00089         switch (component)
00090         {
00091             case 0:
00092             {
00093                 for(unsigned M=0; M<DIM; M++)
00094                 {
00095                     for(unsigned N=0; N<DIM; N++)
00096                     {
00097                         for(unsigned P=0; P<DIM; P++)
00098                         {
00099                             for(unsigned Q=0; Q<DIM; Q++)
00100                             {
00101                                 unsigned index = M*mDimCubed + N*mDimSqd + P*DIM + Q;
00102                                 for(unsigned s=0; s<DIM; s++)
00103                                 {
00104                                     mData[index] += matrix(M,s) * tensor(s,N,P,Q);
00105                                 }
00106                             }
00107                         }
00108                     }
00109                 }
00110                 break;
00111             }
00112             case 1:
00113             {
00114                 for(unsigned M=0; M<DIM; M++)
00115                 {
00116                     for(unsigned N=0; N<DIM; N++)
00117                     {
00118                         for(unsigned P=0; P<DIM; P++)
00119                         {
00120                             for(unsigned Q=0; Q<DIM; Q++)
00121                             {
00122                                 unsigned index = M*mDimCubed + N*mDimSqd + P*DIM + Q;
00123                                 for(unsigned s=0; s<DIM; s++)
00124                                 {
00125                                     mData[index] += matrix(N,s) * tensor(M,s,P,Q);
00126                                 }
00127                             }
00128                         }
00129                     }
00130                 }
00131                 break;
00132             }
00133             case 2:
00134             {
00135                 for(unsigned M=0; M<DIM; M++)
00136                 {
00137                     for(unsigned N=0; N<DIM; N++)
00138                     {
00139                         for(unsigned P=0; P<DIM; P++)
00140                         {
00141                             for(unsigned Q=0; Q<DIM; Q++)
00142                             {
00143                                 unsigned index = M*mDimCubed + N*mDimSqd + P*DIM + Q;
00144                                 for(unsigned s=0; s<DIM; s++)
00145                                 {
00146                                     mData[index] += matrix(P,s) * tensor(M,N,s,Q);
00147                                 }
00148                             }
00149                         }
00150                     }
00151                 }
00152                 break;
00153             }
00154             case 3:
00155             {
00156                 for(unsigned M=0; M<DIM; M++)
00157                 {
00158                     for(unsigned N=0; N<DIM; N++)
00159                     {
00160                         for(unsigned P=0; P<DIM; P++)
00161                         {
00162                             for(unsigned Q=0; Q<DIM; Q++)
00163                             {
00164                                 unsigned index = M*mDimCubed + N*mDimSqd + P*DIM + Q;
00165                                 for(unsigned s=0; s<DIM; s++)
00166                                 {
00167                                     mData[index] += matrix(Q,s) * tensor(M,N,P,s);
00168                                 }
00169                             }
00170                         }
00171                     }
00172                 }
00173                 break;
00174             }
00175             default:
00176             {
00177                 EXCEPTION("Component not 0, 1, 2, or 3");
00178             }
00179         }
00180     }
00181 
00182     double& operator()(unsigned M, unsigned N, unsigned P, unsigned Q)
00183     {
00184         assert(M<DIM);
00185         assert(N<DIM);
00186         assert(P<DIM);
00187         assert(Q<DIM);
00188 
00189         unsigned index = M*mDimCubed + N*mDimSqd + P*DIM + Q;
00190         return mData[index];
00191     }
00192 
00193     void Zero()
00194     {
00195         for(unsigned i=0; i<mDimToFour; i++)
00196         {
00197             mData[i] = 0.0;
00198         }
00199     }
00200 };
00201 
00202 #endif //_FOURTHORDERTENSOR2_HPP_

Generated on Wed Mar 18 12:51:52 2009 for Chaste by  doxygen 1.5.5