BidomainPde.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 #include "BidomainPde.hpp"
00030 
00031 #include "DistributedVector.hpp"
00032 #include "AxisymmetricConductivityTensors.hpp"
00033 #include "OrthotropicConductivityTensors.hpp"
00034 #include "ChastePoint.hpp"
00035 #include "ChasteCuboid.hpp"
00036 
00037 
00038 template <unsigned SPACE_DIM>
00039 BidomainPde<SPACE_DIM>::BidomainPde(
00040             AbstractCardiacCellFactory<SPACE_DIM>* pCellFactory)
00041     : AbstractCardiacPde<SPACE_DIM>(pCellFactory, 2 /*mStride*/)
00042 {
00043     mExtracellularStimulusCacheReplicated.Resize( pCellFactory->GetNumberOfCells() );
00044     CreateExtracellularConductivityTensors();
00045 }
00046 
00047 template <unsigned SPACE_DIM>
00048 BidomainPde<SPACE_DIM>::BidomainPde(std::vector<AbstractCardiacCell*> &rCellsDistributed,AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh)
00049         :  AbstractCardiacPde<SPACE_DIM>(rCellsDistributed, pMesh, 2u) // The 2 tells it this is a bidomain
00050 {
00051     mExtracellularStimulusCacheReplicated.Resize(this->mpDistributedVectorFactory->GetProblemSize());
00052     CreateExtracellularConductivityTensors();
00053 }
00054 
00055 template <unsigned SPACE_DIM>
00056 void BidomainPde<SPACE_DIM>::CreateExtracellularConductivityTensors()
00057 {
00058     if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
00059     {
00060         switch (this->mpConfig->GetConductivityMedia())
00061         {
00062             case cp::media_type::Orthotropic:
00063                 mpExtracellularConductivityTensors =  new OrthotropicConductivityTensors<SPACE_DIM>;
00064                 mpExtracellularConductivityTensors->SetFibreOrientationFile(this->mpConfig->GetMeshName() + ".ortho");
00065                 break;
00066 
00067             case cp::media_type::Axisymmetric:
00068                 mpExtracellularConductivityTensors =  new AxisymmetricConductivityTensors<SPACE_DIM>;
00069                 mpExtracellularConductivityTensors->SetFibreOrientationFile(this->mpConfig->GetMeshName() + ".axi");
00070                 break;
00071 
00072             case cp::media_type::NoFibreOrientation:
00073                 mpExtracellularConductivityTensors =  new OrthotropicConductivityTensors<SPACE_DIM>;
00074                 break;
00075 
00076             default :
00077                 NEVER_REACHED;
00078         }
00079     }
00080     else // Slab defined in config file or SetMesh() called; no fibre orientation assumed
00081     {
00082         mpExtracellularConductivityTensors =  new OrthotropicConductivityTensors<SPACE_DIM>;
00083     }
00084 
00085     c_vector<double, SPACE_DIM> extra_conductivities;
00086     this->mpConfig->GetExtracellularConductivities(extra_conductivities);
00087 
00088     // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
00089     // a pointer to it and we don't want it to go out of scope before Init() is called
00090     unsigned num_elements = this->mpMesh->GetNumElements();
00091     std::vector<c_vector<double, SPACE_DIM> > hetero_extra_conductivities;
00092 
00093     if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
00094     {
00095         try
00096         {
00097             hetero_extra_conductivities.resize(num_elements);
00098         }
00099         catch(std::bad_alloc &badAlloc)
00100         {
00101 #define COVERAGE_IGNORE
00102             std::cout << "Failed to allocate std::vector of size " << num_elements << std::endl;
00103             PetscTools::ReplicateException(true);
00104             throw badAlloc;
00105 #undef COVERAGE_IGNORE
00106         }
00107         PetscTools::ReplicateException(false);
00108 
00109         std::vector<ChasteCuboid<SPACE_DIM> > conductivities_heterogeneity_areas;
00110         std::vector< c_vector<double,3> > intra_h_conductivities;
00111         std::vector< c_vector<double,3> > extra_h_conductivities;
00112         HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
00113                                                                 intra_h_conductivities,
00114                                                                 extra_h_conductivities);
00115 
00116         for (unsigned element_index=0; element_index<num_elements; element_index++)
00117         {
00118             for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
00119             {
00120                 // if element centroid is contained in the region
00121                 ChastePoint<SPACE_DIM> element_centroid(this->mpMesh->GetElement(element_index)->CalculateCentroid());
00122                 if ( conductivities_heterogeneity_areas[region_index].DoesContain( element_centroid ) )
00123                 {
00124                     hetero_extra_conductivities[element_index] = extra_h_conductivities[region_index];
00125                 }
00126                 else
00127                 {
00128                     hetero_extra_conductivities[element_index] = extra_conductivities;
00129                 }
00130             }
00131         }
00132 
00133         mpExtracellularConductivityTensors->SetNonConstantConductivities(&hetero_extra_conductivities);
00134     }
00135     else
00136     {
00137         mpExtracellularConductivityTensors->SetConstantConductivities(extra_conductivities);
00138     }
00139 
00140     mpExtracellularConductivityTensors->Init();
00141 }
00142 
00143 template <unsigned SPACE_DIM>
00144 BidomainPde<SPACE_DIM>::~BidomainPde()
00145 {
00146     if (mpExtracellularConductivityTensors)
00147     {
00148         delete mpExtracellularConductivityTensors;
00149     }
00150 }
00151 
00152 
00153 template <unsigned SPACE_DIM>
00154 const c_matrix<double, SPACE_DIM, SPACE_DIM>& BidomainPde<SPACE_DIM>::rGetExtracellularConductivityTensor(unsigned elementIndex)
00155 {
00156     assert(mpExtracellularConductivityTensors);
00157     return (*mpExtracellularConductivityTensors)[elementIndex];
00158 }
00159 
00160 
00162 // Explicit instantiation
00164 
00165 template class BidomainPde<1>;
00166 template class BidomainPde<2>;
00167 template class BidomainPde<3>;
00168 
00169 
00170 // Serialization for Boost >= 1.36
00171 #include "SerializationExportWrapperForCpp.hpp"
00172 EXPORT_TEMPLATE_CLASS_SAME_DIMS(BidomainPde)

Generated by  doxygen 1.6.2