OrthotropicConductivityTensors.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 Ventricular Myocytes Influences Electrical
00094              * Behavior of the Heart, DA Hooks et al. 2007):
00095              *
00096              *
00097              *                         [g_f  0   0 ] [a_f']
00098              *  tensor = [a_f a_l a_n] [ 0  g_l  0 ] [a_l']
00099              *                         [ 0   0  g_n] [a_n']
00100              *
00101              *              [x_i]
00102              *  where a_i = [y_i], i={f,l,n} are read from the fibre orientation file and
00103              *              [z_i]
00104              *
00105              *  g_f = fibre/longitudinal conductivity (constant or element specific)
00106              *  g_l = laminar/transverse conductivity (constant or element specific)
00107              *  g_n = normal conductivity (constant or element specific)
00108              *
00109              */
00110             if (this->mUseNonConstantConductivities)
00111             {
00112                 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00113                 {
00114                     conductivity_matrix(dim,dim) = (*this->mpNonConstantConductivities)[local_element_index][dim];
00115                 }
00116             }
00117             else
00118             {
00119                 for (unsigned dim=0; dim<SPACE_DIM; dim++)
00120                 {
00121                     assert(this->mConstantConductivities(dim) != DBL_MAX);
00122                     conductivity_matrix(dim,dim) = this->mConstantConductivities(dim);
00123                 }
00124             }
00125 
00126             if (this->mUseFibreOrientation)
00127             {
00128                 unsigned current_fibre_global_index = it->GetIndex();
00129                 this->mFileReader->GetFibreSheetAndNormalMatrix(current_fibre_global_index, orientation_matrix);
00130             }
00131 
00132             c_matrix<double,SPACE_DIM,SPACE_DIM> temp;
00133             noalias(temp) = prod(orientation_matrix, conductivity_matrix);
00134             this->mTensors.push_back( prod(temp, trans(orientation_matrix) ) );
00135 
00136             local_element_index++;
00137         }
00138         assert(this->mTensors.size() == this->mpMesh->GetNumLocalElements());
00139         assert(this->mTensors.size() == local_element_index);
00140 
00141         if (this->mUseFibreOrientation)
00142         {
00143             // close fibre file
00144             this->mFileReader.reset();
00145         }
00146     }
00147 
00148     this->mInitialised = true;
00149 }
00150 
00151 
00153 // Explicit instantiation
00155 
00156 template class OrthotropicConductivityTensors<1,1>;
00157 template class OrthotropicConductivityTensors<1,2>;
00158 template class OrthotropicConductivityTensors<1,3>;
00159 template class OrthotropicConductivityTensors<2,2>;
00160 template class OrthotropicConductivityTensors<2,3>;
00161 template class OrthotropicConductivityTensors<3,3>;

Generated by  doxygen 1.6.2