Chaste Commit::f2ff7ee04e70ac9d06c57344df8d017dbb12b97b
ExtendedBidomainTissue.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 "ExtendedBidomainTissue.hpp"
37
38#include "DistributedVector.hpp"
39#include "OrthotropicConductivityTensors.hpp"
40#include "AxisymmetricConductivityTensors.hpp"
41#include "AbstractStimulusFunction.hpp"
42#include "ChastePoint.hpp"
43#include "AbstractChasteRegion.hpp"
44#include "HeartEventHandler.hpp"
45
46template <unsigned SPACE_DIM>
48 AbstractCardiacCellFactory<SPACE_DIM>* pCellFactorySecondCell,
49 AbstractStimulusFactory<SPACE_DIM>* pExtracellularStimulusFactory)
50 : AbstractCardiacTissue<SPACE_DIM>(pCellFactory),
51 mpIntracellularConductivityTensorsSecondCell(NULL),
52 mUserSuppliedExtracellularStimulus(false)
53{
54 //First, do the same that the abstract constructor does, but applied to the second cell
55
56 assert(pCellFactorySecondCell != NULL);
57 assert(pCellFactorySecondCell->GetMesh() != NULL);
58 assert(pCellFactorySecondCell->GetNumberOfCells() == pCellFactory->GetNumberOfCells() );
59 assert(pExtracellularStimulusFactory != NULL);
60 assert(pExtracellularStimulusFactory->GetMesh() != NULL);
61 assert(pExtracellularStimulusFactory->GetNumberOfCells() == pCellFactorySecondCell->GetNumberOfCells() );
62
63 unsigned num_local_nodes = this->mpDistributedVectorFactory->GetLocalOwnership();
64 unsigned ownership_range_low = this->mpDistributedVectorFactory->GetLow();
65 mCellsDistributedSecondCell.resize(num_local_nodes);
66 mGgapDistributed.resize(num_local_nodes);
67 mExtracellularStimuliDistributed.resize(num_local_nodes);
68
69 try
70 {
71 for (unsigned local_index = 0; local_index < num_local_nodes; local_index++)
72 {
73 unsigned global_index = local_index + ownership_range_low;
74 Node<SPACE_DIM>* p_node = this->mpMesh->GetNode(global_index);
75 mCellsDistributedSecondCell[local_index] = pCellFactorySecondCell->CreateCardiacCellForNode(p_node);
77 mGgapDistributed[local_index] = 0.0;//default. It will be changed by specific method later when user input will be obtained
78 mExtracellularStimuliDistributed[local_index] = pExtracellularStimulusFactory->CreateStimulusForNode(p_node);
79 }
80
83 this->mpDistributedVectorFactory->GetHigh());
84 }
85 // LCOV_EXCL_START //don't really know how to cover this...
86 catch (const Exception& e)
87 {
88 // Errors thrown creating cells will often be process-specific
90 // Should really do this for other processes too, but this is all we need
91 // to get memory testing to pass, and leaking when we're about to die isn't
92 // that bad! Delete second cells
93 for (std::vector<AbstractCardiacCellInterface*>::iterator cell_iterator = mCellsDistributedSecondCell.begin();
94 cell_iterator != mCellsDistributedSecondCell.end();
95 ++cell_iterator)
96 {
97 delete (*cell_iterator);
98 }
99 throw e;
100 }
101 // LCOV_EXCL_STOP
103
104 HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
107 mGgapCacheReplicated.Resize(pCellFactorySecondCell->GetNumberOfCells());//this is a bit of a hack...
108 mExtracellularStimulusCacheReplicated.Resize(pExtracellularStimulusFactory->GetNumberOfCells());
109 HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
110
111 //Create the extracellular conductivity tensor
113}
114
115//archiving constructor
116template <unsigned SPACE_DIM>
117ExtendedBidomainTissue<SPACE_DIM>::ExtendedBidomainTissue(std::vector<AbstractCardiacCellInterface*> & rCellsDistributed,
118 std::vector<AbstractCardiacCellInterface*> & rSecondCellsDistributed,
119 std::vector<boost::shared_ptr<AbstractStimulusFunction> > & rExtraStimuliDistributed,
120 std::vector<double> & rGgapsDistributed,
122 c_vector<double, SPACE_DIM> intracellularConductivitiesSecondCell)
123 : AbstractCardiacTissue<SPACE_DIM>(pMesh),
124 mpIntracellularConductivityTensorsSecondCell(NULL),
125 mIntracellularConductivitiesSecondCell(intracellularConductivitiesSecondCell),
126 mCellsDistributedSecondCell(rSecondCellsDistributed),
127 mExtracellularStimuliDistributed(rExtraStimuliDistributed),
128 mGgapDistributed(rGgapsDistributed),
129 mUserSuppliedExtracellularStimulus(false)
130{
131 //segfault guards in case we failed to load anything from the archive
132 assert(mCellsDistributedSecondCell.size() > 0);
133 assert(mExtracellularStimuliDistributed.size() > 0);
134 assert(mGgapDistributed.size() > 0);
135 //allocate memory for the caches
140
143}
144
145
146template <unsigned SPACE_DIM>
147void ExtendedBidomainTissue<SPACE_DIM>::SetGgapHeterogeneities(std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > >& rGgapHeterogeneityRegions,
148 std::vector<double> rGgapValues)
149{
150 assert( rGgapHeterogeneityRegions.size() == rGgapValues.size() );//problem class (which calls this method should have thrown otherwise)
151 mGgapHeterogeneityRegions = rGgapHeterogeneityRegions;
152 mGgapValues =rGgapValues;
153}
154
155template <unsigned SPACE_DIM>
157{
158 assert(mGgapHeterogeneityRegions.size() == mGgapValues.size());
159 assert(this->mpMesh != NULL);
160
161 unsigned ownership_range_low = this->mpDistributedVectorFactory->GetLow();
162 unsigned num_local_nodes = this->mpDistributedVectorFactory->GetLocalOwnership();
163 assert(mGgapDistributed.size() == num_local_nodes);//the constructor should have allocated memory.
164 try
165 {
166 for (unsigned local_index = 0; local_index < num_local_nodes; local_index++)
167 {
168 unsigned global_index = ownership_range_low + local_index;
169 Node<SPACE_DIM>* p_node = this->mpMesh->GetNode(global_index);
170 mGgapDistributed[local_index] = mGGap;//assign default uniform value everywhere first
171
172 // Then change where and if necessary
173 for (unsigned het_index = 0; het_index < mGgapHeterogeneityRegions.size(); het_index++)
174 {
175 if (mGgapHeterogeneityRegions[het_index]->DoesContain(p_node->GetPoint()))
176 {
177 mGgapDistributed[local_index] = mGgapValues[het_index];
178 }
179 }
180 }
181 }
182 // LCOV_EXCL_START
183 catch (const Exception& e)
184 {
186 throw e;
187 }
188 // LCOV_EXCL_STOP
191}
192
193template <unsigned SPACE_DIM>
195{
196 HeartEventHandler::BeginEvent(HeartEventHandler::READ_MESH);
197 this->mpConfig = HeartConfig::Instance();
198
199 if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
200 {
201 assert(this->mFibreFilePathNoExtension != "");
202
203 switch (this->mpConfig->GetConductivityMedia())
204 {
205 case cp::media_type::Orthotropic:
206 {
207 mpIntracellularConductivityTensorsSecondCell = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
208 FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
209 assert(ortho_file.Exists());
210 mpIntracellularConductivityTensorsSecondCell->SetFibreOrientationFile(ortho_file);
211 break;
212 }
213
214 case cp::media_type::Axisymmetric:
215 {
216 mpIntracellularConductivityTensorsSecondCell = new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
217 FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
218 assert(axi_file.Exists());
219 mpIntracellularConductivityTensorsSecondCell->SetFibreOrientationFile(axi_file);
220 break;
221 }
222
223 case cp::media_type::NoFibreOrientation:
224 mpIntracellularConductivityTensorsSecondCell = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
225 break;
226
227 default:
229 }
230 }
231 else // Slab defined in config file or SetMesh() called; no fibre orientation assumed
232 {
233 mpIntracellularConductivityTensorsSecondCell = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
234 }
235
236 // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
237 // a pointer to it and we don't want it to go out of scope before Init() is called
238 unsigned num_elements = this->mpMesh->GetNumElements();
239 std::vector<c_vector<double, SPACE_DIM> > hetero_intra_conductivities;
240
241 c_vector<double, SPACE_DIM> intra_conductivities;
242 this->mpConfig->GetIntracellularConductivities(intra_conductivities);//this one is used just for resizing
243
244 if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
245 {
246 try
247 {
248 assert(hetero_intra_conductivities.size()==0);
249 hetero_intra_conductivities.resize(num_elements, intra_conductivities);
250 }
251 // LCOV_EXCL_START
252 catch(std::bad_alloc &badAlloc)
253 {
254
255 std::cout << "Failed to allocate std::vector of size " << num_elements << std::endl;
257 throw badAlloc;
258 }
259 // LCOV_EXCL_STOP
260
262
263 std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
264 std::vector< c_vector<double,3> > intra_h_conductivities;
265 std::vector< c_vector<double,3> > extra_h_conductivities;
266 HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
267 intra_h_conductivities,
268 extra_h_conductivities);
269 unsigned local_element_index = 0;
270 for (typename AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>::ElementIterator it = this->mpMesh->GetElementIteratorBegin();
271 it != this->mpMesh->GetElementIteratorEnd();
272 ++it)
273 {
274 //unsigned element_index = it->GetIndex();
275 // if element centroid is contained in the region
276 ChastePoint<SPACE_DIM> element_centroid(it->CalculateCentroid());
277 for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
278 {
279 if (conductivities_heterogeneity_areas[region_index]->DoesContain(element_centroid))
280 {
281 // We don't use ublas vector assignment here, because we might be getting a subvector of a 3-vector
282 for (unsigned i=0; i<SPACE_DIM; i++)
283 {
284 hetero_intra_conductivities[local_element_index][i] = intra_h_conductivities[region_index][i];
285 }
286 }
287 }
288 local_element_index++;
289 }
290
291 mpIntracellularConductivityTensorsSecondCell->SetNonConstantConductivities(&hetero_intra_conductivities);
293 else
294 {
295 mpIntracellularConductivityTensorsSecondCell->SetConstantConductivities(mIntracellularConductivitiesSecondCell);
296 }
298 mpIntracellularConductivityTensorsSecondCell->Init(this->mpMesh);
299 HeartEventHandler::EndEvent(HeartEventHandler::READ_MESH);
300}
301
302template <unsigned SPACE_DIM>
304{
305 return mUserSuppliedExtracellularStimulus;
306}
307
308template <unsigned SPACE_DIM>
310{
311 mUserSuppliedExtracellularStimulus = flag;
313
314template <unsigned SPACE_DIM>
315const std::vector<AbstractCardiacCellInterface*>& ExtendedBidomainTissue<SPACE_DIM>::rGetSecondCellsDistributed() const
316{
317 return mCellsDistributedSecondCell;
319
320template <unsigned SPACE_DIM>
322{
323 return mGgapDistributed;
325
326template <unsigned SPACE_DIM>
327const std::vector<boost::shared_ptr<AbstractStimulusFunction> >& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularStimulusDistributed() const
329 return mExtracellularStimuliDistributed;
330}
332
333template <unsigned SPACE_DIM>
335{
336 if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
338 assert(this->mFibreFilePathNoExtension != "");
339 switch (this->mpConfig->GetConductivityMedia())
340 {
341 case cp::media_type::Orthotropic:
343 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
344 FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
345 assert(ortho_file.Exists());
346 mpExtracellularConductivityTensors->SetFibreOrientationFile(ortho_file);
347 break;
348 }
349
350 case cp::media_type::Axisymmetric:
351 {
352 mpExtracellularConductivityTensors = new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
353 FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
354 assert(axi_file.Exists());
355 mpExtracellularConductivityTensors->SetFibreOrientationFile(axi_file);
356 break;
358
359 case cp::media_type::NoFibreOrientation:
360 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
361 break;
363 default:
365 }
366 }
367 else // no fibre orientation assumed
368 {
369 mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
370 }
371
372 c_vector<double, SPACE_DIM> extra_conductivities;
373 this->mpConfig->GetExtracellularConductivities(extra_conductivities);
374
375 // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
376 // a pointer to it and we don't want it to go out of scope before Init() is called
377 unsigned num_elements = this->mpMesh->GetNumElements();
378 std::vector<c_vector<double, SPACE_DIM> > hetero_extra_conductivities;
379
380 if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
381 {
382 try
383 {
384 assert(hetero_extra_conductivities.size()==0);
385 //initialise with the values of teh default conductivity tensor
386 hetero_extra_conductivities.resize(num_elements, extra_conductivities);
388 // LCOV_EXCL_START
389 catch(std::bad_alloc &badAlloc)
390 {
391 std::cout << "Failed to allocate std::vector of size " << num_elements << std::endl;
393 throw badAlloc;
394 }
395 // LCOV_EXCL_STOP
396
398
399 std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
400 std::vector< c_vector<double,3> > intra_h_conductivities;
401 std::vector< c_vector<double,3> > extra_h_conductivities;
402 HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
403 intra_h_conductivities,
404 extra_h_conductivities);
405 unsigned local_element_index = 0;
406 for (typename AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>::ElementIterator iter = (this->mpMesh)->GetElementIteratorBegin();
407 iter != (this->mpMesh)->GetElementIteratorEnd();
408 ++iter)
409 {
410 //unsigned element_index = iter->GetIndex();
411 // if element centroid is contained in the region
412 ChastePoint<SPACE_DIM> element_centroid(iter->CalculateCentroid());
413 for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
414 {
415 // If element centroid is contained in the region
416 if (conductivities_heterogeneity_areas[region_index]->DoesContain(element_centroid))
417 {
418 // We don't use ublas vector assignment here, because we might be getting a subvector of a 3-vector
419 for (unsigned i=0; i<SPACE_DIM; i++)
420 {
421 hetero_extra_conductivities[local_element_index][i] = extra_h_conductivities[region_index][i];
422 }
423 }
424 }
425 local_element_index++;
426 }
427
428 mpExtracellularConductivityTensors->SetNonConstantConductivities(&hetero_extra_conductivities);
429 }
430 else
431 {
432 mpExtracellularConductivityTensors->SetConstantConductivities(extra_conductivities);
433 }
434 mpExtracellularConductivityTensors->Init(this->mpMesh);
435}
436
437template <unsigned SPACE_DIM>
439{
440 // Delete (second) cells
441 for (std::vector<AbstractCardiacCellInterface*>::iterator cell_iterator = mCellsDistributedSecondCell.begin();
442 cell_iterator != mCellsDistributedSecondCell.end();
443 ++cell_iterator)
444 {
445 delete (*cell_iterator);
446 }
447
448 if (mpExtracellularConductivityTensors)
449 {
450 delete mpExtracellularConductivityTensors;
451 }
452
453 if (mpIntracellularConductivityTensorsSecondCell)
454 {
455 delete mpIntracellularConductivityTensorsSecondCell;
456 }
457}
458
459template <unsigned SPACE_DIM>
461{
462 for (unsigned i = 0; i < SPACE_DIM; i++)
463 {
464 mIntracellularConductivitiesSecondCell[i] = conductivities[i];
465 }
466}
467
468template <unsigned SPACE_DIM>
470{
471 return mIntracellularConductivitiesSecondCell;
472}
473
474template <unsigned SPACE_DIM>
475const c_matrix<double, SPACE_DIM, SPACE_DIM>& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularConductivityTensor(unsigned elementIndex)
476{
477 assert(mpExtracellularConductivityTensors);
478 if (this->mpConductivityModifier==NULL)
479 {
480 return (*mpExtracellularConductivityTensors)[elementIndex];
481 }
482 else
483 {
484 return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpExtracellularConductivityTensors)[elementIndex], 1u);
485 }
486}
487
488template <unsigned SPACE_DIM>
489const c_matrix<double, SPACE_DIM, SPACE_DIM>& ExtendedBidomainTissue<SPACE_DIM>::rGetIntracellularConductivityTensorSecondCell(unsigned elementIndex)
490{
491 assert(mpIntracellularConductivityTensorsSecondCell);
492 if (this->mpConductivityModifier==NULL)
493 {
494 return (*mpIntracellularConductivityTensorsSecondCell)[elementIndex];
495 }
496 else
497 {
498 return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpIntracellularConductivityTensorsSecondCell)[elementIndex], 2u);
499 }
500}
501
502template <unsigned SPACE_DIM>
504{
505 return mCellsDistributedSecondCell[globalIndex - this->mpDistributedVectorFactory->GetLow()];
506}
507
508template <unsigned SPACE_DIM>
509boost::shared_ptr<AbstractStimulusFunction> ExtendedBidomainTissue<SPACE_DIM>::GetExtracellularStimulus( unsigned globalIndex )
510{
511 return mExtracellularStimuliDistributed[globalIndex - this->mpDistributedVectorFactory->GetLow()];
512}
513
514template <unsigned SPACE_DIM>
515void ExtendedBidomainTissue<SPACE_DIM>::SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage)
516{
517 HeartEventHandler::BeginEvent(HeartEventHandler::SOLVE_ODES);
518
519 DistributedVector dist_solution = this->mpDistributedVectorFactory->CreateDistributedVector(existingSolution);
520 DistributedVector::Stripe V_first_cell(dist_solution, 0);
521 DistributedVector::Stripe V_second_cell(dist_solution, 1);
522 DistributedVector::Stripe phi_e(dist_solution, 2);
523
524 for (DistributedVector::Iterator index = dist_solution.Begin();
525 index != dist_solution.End();
526 ++index)
527 {
528 // overwrite the voltage with the input value
529 this->mCellsDistributed[index.Local]->SetVoltage( V_first_cell[index] );
530 mCellsDistributedSecondCell[index.Local]->SetVoltage( V_second_cell[index] );
531 try
532 {
533 // solve
534 // Note: Voltage should not be updated. GetIIonic will be called later
535 // and needs the old voltage. The voltage will be updated from the pde.
536 this->mCellsDistributed[index.Local]->ComputeExceptVoltage(time, nextTime);
537 mCellsDistributedSecondCell[index.Local]->ComputeExceptVoltage(time, nextTime);
538 }
539 // LCOV_EXCL_START
540 catch (Exception &e)
541 {
543 throw e;
544 }
545 // LCOV_EXCL_STOP
546
547 // update the Iionic and stimulus caches
548 this->UpdateCaches(index.Global, index.Local, nextTime);//in parent class
549 UpdateAdditionalCaches(index.Global, index.Local, nextTime);//extended bidomain specific caches
550 }
552 HeartEventHandler::EndEvent(HeartEventHandler::SOLVE_ODES);
553
554 HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
555 if (this->mDoCacheReplication)
556 {
557 this->ReplicateCaches();
558 ReplicateAdditionalCaches();//extended bidomain specific caches
559 }
560 HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
561}
562
563template <unsigned SPACE_DIM>
564void ExtendedBidomainTissue<SPACE_DIM>::UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
565{
566 mIionicCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIIonic();
567 mIntracellularStimulusCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIntracellularStimulus(nextTime);
568 mExtracellularStimulusCacheReplicated[globalIndex] = mExtracellularStimuliDistributed[localIndex]->GetStimulus(nextTime);
569 mGgapCacheReplicated[globalIndex] = mGgapDistributed[localIndex];
570}
571
572template <unsigned SPACE_DIM>
574{
575 mIionicCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
576 mIntracellularStimulusCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
577 mExtracellularStimulusCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
578 mGgapCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
579}
580
581template <unsigned SPACE_DIM>
586
587template <unsigned SPACE_DIM>
589{
590 return mIntracellularStimulusCacheReplicatedSecondCell;
591}
592
593template <unsigned SPACE_DIM>
595{
596 return mExtracellularStimulusCacheReplicated;
597}
598
599template <unsigned SPACE_DIM>
604
605template <unsigned SPACE_DIM>
607{
608 return mAmFirstCell;
609}
610
611template <unsigned SPACE_DIM>
613{
614 return mAmSecondCell;
615}
616
617template <unsigned SPACE_DIM>
619{
620 return mAmGap;
621}
622
623template <unsigned SPACE_DIM>
625{
626 return mCmFirstCell;
627}
628
629template <unsigned SPACE_DIM>
631{
632 return mCmSecondCell;
633}
634
635template <unsigned SPACE_DIM>
637{
638 return mGGap;
639}
640
641template <unsigned SPACE_DIM>
643{
644 mAmFirstCell = value;
645}
646
647template <unsigned SPACE_DIM>
649{
650 mAmSecondCell = value;
651}
652
653template <unsigned SPACE_DIM>
655{
656 mAmGap = value;
657}
658
659template <unsigned SPACE_DIM>
661{
662 mGGap = value;
663}
664
665template <unsigned SPACE_DIM>
667{
668 mCmFirstCell = value;
669}
670
671template <unsigned SPACE_DIM>
673{
674 mCmSecondCell = value;
675}
676
677// Explicit instantiation
678template class ExtendedBidomainTissue<1>;
679template class ExtendedBidomainTissue<2>;
680template class ExtendedBidomainTissue<3>;
681
682// Serialization for Boost >= 1.36
#define NEVER_REACHED
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
virtual AbstractCardiacCellInterface * CreateCardiacCellForNode(Node< SPACE_DIM > *pNode)
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * GetMesh()
virtual void FinaliseCellCreation(std::vector< AbstractCardiacCellInterface * > *pCellsDistributed, unsigned lo, unsigned hi)
DistributedVectorFactory * mpDistributedVectorFactory
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * mpMesh
virtual boost::shared_ptr< AbstractStimulusFunction > CreateStimulusForNode(Node< SPACE_DIM > *pNode)
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * GetMesh()
ReplicatableVector mExtracellularStimulusCacheReplicated
void UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
ReplicatableVector & rGetExtracellularStimulusCacheReplicated()
const std::vector< boost::shared_ptr< AbstractStimulusFunction > > & rGetExtracellularStimulusDistributed() const
virtual void SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage=false)
void SetGgapHeterogeneities(std::vector< boost::shared_ptr< AbstractChasteRegion< SPACE_DIM > > > &rGgapHeterogeneityRegions, std::vector< double > rGgapValues)
ExtendedBidomainTissue(AbstractCardiacCellFactory< SPACE_DIM > *pCellFactory, AbstractCardiacCellFactory< SPACE_DIM > *pCellFactorySecondCell, AbstractStimulusFactory< SPACE_DIM > *pExtracellularStimulusFactory)
ReplicatableVector mIionicCacheReplicatedSecondCell
ReplicatableVector & rGetIionicCacheReplicatedSecondCell()
ReplicatableVector & rGetGgapCacheReplicated()
const std::vector< AbstractCardiacCellInterface * > & rGetSecondCellsDistributed() const
std::vector< AbstractCardiacCellInterface * > mCellsDistributedSecondCell
ReplicatableVector mIntracellularStimulusCacheReplicatedSecondCell
boost::shared_ptr< AbstractStimulusFunction > GetExtracellularStimulus(unsigned globalIndex)
std::vector< boost::shared_ptr< AbstractStimulusFunction > > mExtracellularStimuliDistributed
ReplicatableVector & rGetIntracellularStimulusCacheReplicatedSecondCell()
c_vector< double, SPACE_DIM > GetIntracellularConductivitiesSecondCell() const
const c_matrix< double, SPACE_DIM, SPACE_DIM > & rGetExtracellularConductivityTensor(unsigned elementIndex)
std::vector< double > mGgapDistributed
AbstractCardiacCellInterface * GetCardiacSecondCell(unsigned globalIndex)
const std::vector< double > & rGetGapsDistributed() const
void SetUserSuppliedExtracellularStimulus(bool flag)
void SetIntracellularConductivitiesSecondCell(c_vector< double, SPACE_DIM > conductivities)
const c_matrix< double, SPACE_DIM, SPACE_DIM > & rGetIntracellularConductivityTensorSecondCell(unsigned elementIndex)
ReplicatableVector mGgapCacheReplicated
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()
Definition Node.hpp:59
ChastePoint< SPACE_DIM > GetPoint() const
Definition Node.cpp:133
static void ReplicateException(bool flag)
void Resize(unsigned size)