Chaste Release::3.1
OrthotropicConductivityTensors.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "OrthotropicConductivityTensors.hpp"
00037 #include "Exception.hpp"
00038 
00039 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00040 void OrthotropicConductivityTensors<ELEMENT_DIM, SPACE_DIM>::Init(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> *pMesh) throw (Exception)
00041 {
00042     this->mpMesh = pMesh;
00043 
00044     if (!this->mUseNonConstantConductivities && !this->mUseFibreOrientation)
00045     {
00046         // Constant tensor for every element
00047         c_matrix<double, SPACE_DIM, SPACE_DIM> conductivity_matrix(zero_matrix<double>(SPACE_DIM,SPACE_DIM));
00048 
00049         for (unsigned dim=0; dim<SPACE_DIM; dim++)
00050         {
00051             assert(this->mConstantConductivities(dim) != DBL_MAX);
00052             conductivity_matrix(dim,dim) = this->mConstantConductivities(dim);
00053         }
00054 
00055         this->mTensors.push_back(conductivity_matrix);
00056     }
00057     else
00058     {
00059         c_matrix<double,SPACE_DIM,SPACE_DIM> orientation_matrix((identity_matrix<double>(SPACE_DIM)));
00060 
00061         if (this->mUseFibreOrientation)
00062         {
00063             // open file
00064             this->mFileReader.reset(new FibreReader<SPACE_DIM>(this->mFibreOrientationFile, ORTHO));
00065             if(this->mFileReader->GetNumLinesOfData() != this->mpMesh->GetNumElements())
00066             {
00067                 EXCEPTION("The size of the fibre file does not match the number of elements in the mesh");
00068             }
00069         }
00070 
00071         if (this->mUseNonConstantConductivities)
00072         {
00073             if(this->mpNonConstantConductivities->size() != this->mpMesh->GetNumLocalElements())
00074             {
00075                 EXCEPTION("The size of the conductivities vector does not match the number of elements in the mesh");
00076             }
00077         }
00078 
00079         // reserve() allocates all the memory at once, more efficient than relying
00080         // on the automatic reallocation scheme.
00081         this->mTensors.reserve(this->mpMesh->GetNumLocalElements());
00082 
00083         c_matrix<double, SPACE_DIM, SPACE_DIM> conductivity_matrix(zero_matrix<double>(SPACE_DIM,SPACE_DIM));
00084 
00085         unsigned local_element_index = 0;
00086 
00087         for (typename AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>::ElementIterator it = this->mpMesh->GetElementIteratorBegin();
00088              it != this->mpMesh->GetElementIteratorEnd();
00089              ++it)
00090         {
00091             /*
00092              *  For every element of the mesh we compute its tensor like (from
00093              * "Laminar Arrangement of VentricularMyocites Influences Electrical
00094              * Behavior of the Heart", Darren et al. 2007):
00095              *
00096              *                         [g_f  0   0 ] [a_f']
00097              *  tensor = [a_f a_l a_n] [ 0  g_l  0 ] [a_l']
00098              *                         [ 0   0  g_n] [a_n']
00099              *
00100              *              [x_i]
00101              *  where a_i = [y_i], i={f,l,n} are read from the fibre orientation file and
00102              *              [z_i]
00103              *
00104              *  g_f = fibre/longitudinal conductivity (constant or element specific)
00105              *  g_l = laminar/transverse conductivity (constant or element specific)
00106              *  g_n = normal conductivity (constant or element specific)
00107              *
00108              */
00109             if (this->mUseNonConstantConductivities)
00110             {
00111                 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00112                 {
00113                     conductivity_matrix(dim,dim) = (*this->mpNonConstantConductivities)[local_element_index][dim];
00114                 }
00115             }
00116             else
00117             {
00118                 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00119                 {
00120                     assert(this->mConstantConductivities(dim) != DBL_MAX);
00121                     conductivity_matrix(dim,dim) = this->mConstantConductivities(dim);
00122                 }
00123             }
00124 
00125             if (this->mUseFibreOrientation)
00126             {
00127                 unsigned current_fibre_global_index = it->GetIndex();
00128                 this->mFileReader->GetFibreSheetAndNormalMatrix(current_fibre_global_index, orientation_matrix);
00129             }
00130 
00131             c_matrix<double,SPACE_DIM,SPACE_DIM> temp;
00132             noalias(temp) = prod(orientation_matrix, conductivity_matrix);
00133             this->mTensors.push_back( prod(temp, trans(orientation_matrix) ) );
00134 
00135             local_element_index++;
00136         }
00137         assert(this->mTensors.size() == this->mpMesh->GetNumLocalElements());
00138         assert(this->mTensors.size() == local_element_index);
00139 
00140         if (this->mUseFibreOrientation)
00141         {
00142             // close fibre file
00143             this->mFileReader.reset();
00144         }
00145     }
00146 
00147     this->mInitialised = true;
00148 }
00149 
00150 
00152 // Explicit instantiation
00154 
00155 template class OrthotropicConductivityTensors<1,1>;
00156 template class OrthotropicConductivityTensors<1,2>;
00157 template class OrthotropicConductivityTensors<1,3>;
00158 template class OrthotropicConductivityTensors<2,2>;
00159 template class OrthotropicConductivityTensors<2,3>;
00160 template class OrthotropicConductivityTensors<3,3>;