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