Chaste Commit::baa90ac2819b962188b7562f2326be23c47859a7
BidomainTissue.cpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, are permitted provided that the following conditions are met:
14 * Redistributions of source code must retain the above copyright notice,
15 this list of conditions and the following disclaimer.
16 * Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 * Neither the name of the University of Oxford nor the names of its
20 contributors may be used to endorse or promote products derived from this
21 software without specific prior written permission.
22
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#include "BidomainTissue.hpp"
37
38#include "DistributedVector.hpp"
39#include "AxisymmetricConductivityTensors.hpp"
40#include "OrthotropicConductivityTensors.hpp"
41#include "ChastePoint.hpp"
42#include "AbstractChasteRegion.hpp"
43
44template <unsigned SPACE_DIM>
47 bool exchangeHalos)
48 : AbstractCardiacTissue<SPACE_DIM>(pCellFactory, exchangeHalos)
49{
51}
52
53template <unsigned SPACE_DIM>
59
60template <unsigned SPACE_DIM>
62{
63 if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
64 {
65 assert(this->mFibreFilePathNoExtension != "");
66
67 switch (this->mpConfig->GetConductivityMedia())
68 {
69 case cp::media_type::Orthotropic:
70 {
71 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
72 FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
73 assert(ortho_file.Exists());
74 mpExtracellularConductivityTensors->SetFibreOrientationFile(ortho_file);
75 break;
76 }
77
78 case cp::media_type::Axisymmetric:
79 {
80 mpExtracellularConductivityTensors = new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
81 FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
82 assert(axi_file.Exists());
83 mpExtracellularConductivityTensors->SetFibreOrientationFile(axi_file);
84 break;
85 }
86
87 case cp::media_type::NoFibreOrientation:
88 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
89 break;
90
91 default:
93 }
94 }
95 else // Slab defined in config file or SetMesh() called; no fibre orientation assumed
96 {
97 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
98 }
99
100 c_vector<double, SPACE_DIM> extra_conductivities;
101 this->mpConfig->GetExtracellularConductivities(extra_conductivities);
102
103 // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
104 // a pointer to it and we don't want it to go out of scope before Init() is called
105 unsigned num_local_elements = this->mpMesh->GetNumLocalElements();
106 std::vector<c_vector<double, SPACE_DIM> > hetero_extra_conductivities;
107
108 if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
110 try
111 {
112 assert(hetero_extra_conductivities.size()==0);
113 //initialise with the values of the default conductivity tensor
114 hetero_extra_conductivities.resize(num_local_elements, extra_conductivities);
115 }
116 // LCOV_EXCL_START
117 catch(std::bad_alloc &r_bad_alloc)
118 {
119 std::cout << "Failed to allocate std::vector of size " << num_local_elements << std::endl;
121 throw r_bad_alloc;
122 }
123 // LCOV_EXCL_STOP
124
126
127 std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
128 std::vector< c_vector<double,3> > intra_h_conductivities;
129 std::vector< c_vector<double,3> > extra_h_conductivities;
130 HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
131 intra_h_conductivities,
132 extra_h_conductivities);
133
134 unsigned local_element_index = 0;
135
136 for (typename AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>::ElementIterator iter = (this->mpMesh)->GetElementIteratorBegin();
137 iter != (this->mpMesh)->GetElementIteratorEnd();
138 ++iter)
139 {
140 // If element centroid is contained in the region
141 ChastePoint<SPACE_DIM> element_centroid(iter->CalculateCentroid());
142 for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
143 {
144 // If element centroid is contained in the region
145 if (conductivities_heterogeneity_areas[region_index]->DoesContain(element_centroid))
146 {
147 //We don't use ublas vector assignment here, because we might be getting a subvector of a 3-vector
148 for (unsigned i=0; i<SPACE_DIM; i++)
149 {
150 hetero_extra_conductivities[local_element_index][i] = extra_h_conductivities[region_index][i];
151 }
152 }
153 }
154 local_element_index++;
155 }
156 mpExtracellularConductivityTensors->SetNonConstantConductivities(&hetero_extra_conductivities);
157 }
158 else
159 {
160 mpExtracellularConductivityTensors->SetConstantConductivities(extra_conductivities);
161 }
162
163 mpExtracellularConductivityTensors->Init(this->mpMesh);
164}
165
166template <unsigned SPACE_DIM>
168{
169 if (mpExtracellularConductivityTensors)
170 {
171 delete mpExtracellularConductivityTensors;
172 }
173}
174
175
176template <unsigned SPACE_DIM>
177const c_matrix<double, SPACE_DIM, SPACE_DIM>& BidomainTissue<SPACE_DIM>::rGetExtracellularConductivityTensor(unsigned elementIndex)
178{
179 assert(mpExtracellularConductivityTensors);
180 if (this->mpConductivityModifier==NULL)
181 {
182 return (*mpExtracellularConductivityTensors)[elementIndex];
183 }
184 else
185 {
186 return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpExtracellularConductivityTensors)[elementIndex], 1u);
187 }
188}
189
190// Explicit instantiation
191template class BidomainTissue<1>;
192template class BidomainTissue<2>;
193template class BidomainTissue<3>;
194
195// Serialization for Boost >= 1.36
#define NEVER_REACHED
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
void CreateExtracellularConductivityTensors()
const c_matrix< double, SPACE_DIM, SPACE_DIM > & rGetExtracellularConductivityTensor(unsigned elementIndex)
BidomainTissue(AbstractCardiacCellFactory< SPACE_DIM > *pCellFactory, bool exchangeHalos=false)
bool Exists() const
void GetConductivityHeterogeneities(std::vector< boost::shared_ptr< AbstractChasteRegion< DIM > > > &conductivitiesHeterogeneityAreas, std::vector< c_vector< double, 3 > > &intraConductivities, std::vector< c_vector< double, 3 > > &extraConductivities) const
static HeartConfig * Instance()
static void ReplicateException(bool flag)