00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "BidomainTissue.hpp"
00030
00031 #include "DistributedVector.hpp"
00032 #include "AxisymmetricConductivityTensors.hpp"
00033 #include "OrthotropicConductivityTensors.hpp"
00034 #include "ChastePoint.hpp"
00035 #include "AbstractChasteRegion.hpp"
00036
00037 template <unsigned SPACE_DIM>
00038 BidomainTissue<SPACE_DIM>::BidomainTissue(
00039 AbstractCardiacCellFactory<SPACE_DIM>* pCellFactory,
00040 bool exchangeHalos)
00041 : AbstractCardiacTissue<SPACE_DIM>(pCellFactory, exchangeHalos)
00042 {
00043 CreateExtracellularConductivityTensors();
00044 }
00045
00046 template <unsigned SPACE_DIM>
00047 BidomainTissue<SPACE_DIM>::BidomainTissue(AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh)
00048 : AbstractCardiacTissue<SPACE_DIM>(pMesh)
00049 {
00050 CreateExtracellularConductivityTensors();
00051 }
00052
00053 template <unsigned SPACE_DIM>
00054 void BidomainTissue<SPACE_DIM>::CreateExtracellularConductivityTensors()
00055 {
00056 if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
00057 {
00058 assert(this->mFibreFilePathNoExtension != "");
00059
00060 switch (this->mpConfig->GetConductivityMedia())
00061 {
00062 case cp::media_type::Orthotropic:
00063 {
00064 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00065 FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
00066 assert(ortho_file.Exists());
00067 mpExtracellularConductivityTensors->SetFibreOrientationFile(ortho_file);
00068 break;
00069 }
00070
00071 case cp::media_type::Axisymmetric:
00072 {
00073 mpExtracellularConductivityTensors = new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
00074 FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
00075 assert(axi_file.Exists());
00076 mpExtracellularConductivityTensors->SetFibreOrientationFile(axi_file);
00077 break;
00078 }
00079
00080 case cp::media_type::NoFibreOrientation:
00081 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00082 break;
00083
00084 default :
00085 NEVER_REACHED;
00086 }
00087 }
00088 else
00089 {
00090 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00091 }
00092
00093 c_vector<double, SPACE_DIM> extra_conductivities;
00094 this->mpConfig->GetExtracellularConductivities(extra_conductivities);
00095
00096
00097
00098 unsigned num_local_elements = this->mpMesh->GetNumLocalElements();
00099 std::vector<c_vector<double, SPACE_DIM> > hetero_extra_conductivities;
00100
00101 if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
00102 {
00103 try
00104 {
00105 assert(hetero_extra_conductivities.size()==0);
00106
00107 hetero_extra_conductivities.resize(num_local_elements, extra_conductivities);
00108 }
00109 catch(std::bad_alloc &r_bad_alloc)
00110 {
00111 #define COVERAGE_IGNORE
00112 std::cout << "Failed to allocate std::vector of size " << num_local_elements << std::endl;
00113 PetscTools::ReplicateException(true);
00114 throw r_bad_alloc;
00115 #undef COVERAGE_IGNORE
00116 }
00117 PetscTools::ReplicateException(false);
00118
00119 std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
00120 std::vector< c_vector<double,3> > intra_h_conductivities;
00121 std::vector< c_vector<double,3> > extra_h_conductivities;
00122 HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
00123 intra_h_conductivities,
00124 extra_h_conductivities);
00125
00126 unsigned local_element_index = 0;
00127
00128 for (typename AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>::ElementIterator iter = (this->mpMesh)->GetElementIteratorBegin();
00129 iter != (this->mpMesh)->GetElementIteratorEnd();
00130 ++iter)
00131 {
00132
00133 ChastePoint<SPACE_DIM> element_centroid(iter->CalculateCentroid());
00134 for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
00135 {
00136
00137 if ( conductivities_heterogeneity_areas[region_index]->DoesContain( element_centroid ) )
00138 {
00139
00140 for (unsigned i=0; i<SPACE_DIM; i++)
00141 {
00142 hetero_extra_conductivities[local_element_index][i] = extra_h_conductivities[region_index][i];
00143 }
00144 }
00145 }
00146 local_element_index++;
00147 }
00148 mpExtracellularConductivityTensors->SetNonConstantConductivities(&hetero_extra_conductivities);
00149 }
00150 else
00151 {
00152 mpExtracellularConductivityTensors->SetConstantConductivities(extra_conductivities);
00153 }
00154
00155 mpExtracellularConductivityTensors->Init(this->mpMesh);
00156 }
00157
00158 template <unsigned SPACE_DIM>
00159 BidomainTissue<SPACE_DIM>::~BidomainTissue()
00160 {
00161 if (mpExtracellularConductivityTensors)
00162 {
00163 delete mpExtracellularConductivityTensors;
00164 }
00165 }
00166
00167
00168 template <unsigned SPACE_DIM>
00169 const c_matrix<double, SPACE_DIM, SPACE_DIM>& BidomainTissue<SPACE_DIM>::rGetExtracellularConductivityTensor(unsigned elementIndex)
00170 {
00171 assert(mpExtracellularConductivityTensors);
00172 if(this->mpConductivityModifier==NULL)
00173 {
00174 return (*mpExtracellularConductivityTensors)[elementIndex];
00175 }
00176 else
00177 {
00178 return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpExtracellularConductivityTensors)[elementIndex]);
00179 }
00180 }
00181
00182
00184
00186
00187 template class BidomainTissue<1>;
00188 template class BidomainTissue<2>;
00189 template class BidomainTissue<3>;
00190
00191
00192
00193 #include "SerializationExportWrapperForCpp.hpp"
00194 EXPORT_TEMPLATE_CLASS_SAME_DIMS(BidomainTissue)