Chaste  Release::3.4
ExtendedBidomainTissue.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, 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 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF 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 
46 template <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);
76  mCellsDistributedSecondCell[local_index]->SetUsedInTissueSimulation();
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 
81  pCellFactorySecondCell->FinaliseCellCreation(&mCellsDistributedSecondCell,
84  }
85  catch (const Exception& e)
86  {
87 #define COVERAGE_IGNORE //don't really know how to cover this...
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 #undef COVERAGE_IGNORE
101  }
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
116 template <unsigned SPACE_DIM>
117 ExtendedBidomainTissue<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 
146 template <unsigned SPACE_DIM>
147 void 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 
155 template <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  catch (const Exception& e)
183  {
184 #define COVERAGE_IGNORE
186  throw e;
187 #undef COVERAGE_IGNORE
188  }
190 }
191 
192 template <unsigned SPACE_DIM>
194 {
195  HeartEventHandler::BeginEvent(HeartEventHandler::READ_MESH);
196  this->mpConfig = HeartConfig::Instance();
197 
198  if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
199  {
200  assert(this->mFibreFilePathNoExtension != "");
201 
202  switch (this->mpConfig->GetConductivityMedia())
203  {
204  case cp::media_type::Orthotropic:
205  {
206  mpIntracellularConductivityTensorsSecondCell = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
207  FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
208  assert(ortho_file.Exists());
209  mpIntracellularConductivityTensorsSecondCell->SetFibreOrientationFile(ortho_file);
210  break;
211  }
212 
213  case cp::media_type::Axisymmetric:
214  {
215  mpIntracellularConductivityTensorsSecondCell = new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
216  FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
217  assert(axi_file.Exists());
218  mpIntracellularConductivityTensorsSecondCell->SetFibreOrientationFile(axi_file);
219  break;
220  }
221 
222  case cp::media_type::NoFibreOrientation:
223  mpIntracellularConductivityTensorsSecondCell = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
224  break;
225 
226  default :
228  }
229  }
230  else // Slab defined in config file or SetMesh() called; no fibre orientation assumed
231  {
232  mpIntracellularConductivityTensorsSecondCell = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
233  }
234 
235  // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
236  // a pointer to it and we don't want it to go out of scope before Init() is called
237  unsigned num_elements = this->mpMesh->GetNumElements();
238  std::vector<c_vector<double, SPACE_DIM> > hetero_intra_conductivities;
239 
240  c_vector<double, SPACE_DIM> intra_conductivities;
241  this->mpConfig->GetIntracellularConductivities(intra_conductivities);//this one is used just for resizing
242 
243  if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
244  {
245  try
246  {
247  assert(hetero_intra_conductivities.size()==0);
248  hetero_intra_conductivities.resize(num_elements, intra_conductivities);
249  }
250  catch(std::bad_alloc &badAlloc)
251  {
252 #define COVERAGE_IGNORE
253  std::cout << "Failed to allocate std::vector of size " << num_elements << std::endl;
255  throw badAlloc;
256 #undef COVERAGE_IGNORE
257  }
259 
260  std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
261  std::vector< c_vector<double,3> > intra_h_conductivities;
262  std::vector< c_vector<double,3> > extra_h_conductivities;
263  HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
264  intra_h_conductivities,
265  extra_h_conductivities);
266  unsigned local_element_index = 0;
268  it != this->mpMesh->GetElementIteratorEnd();
269  ++it)
270  {
271  //unsigned element_index = it->GetIndex();
272  // if element centroid is contained in the region
273  ChastePoint<SPACE_DIM> element_centroid(it->CalculateCentroid());
274  for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
275  {
276  if ( conductivities_heterogeneity_areas[region_index]->DoesContain(element_centroid) )
277  {
278  //We don't use ublas vector assignment here, because we might be getting a subvector of a 3-vector
279  for (unsigned i=0; i<SPACE_DIM; i++)
280  {
281  hetero_intra_conductivities[local_element_index][i] = intra_h_conductivities[region_index][i];
282  }
283  }
284  }
285  local_element_index++;
286  }
287 
288  mpIntracellularConductivityTensorsSecondCell->SetNonConstantConductivities(&hetero_intra_conductivities);
289  }
290  else
291  {
292  mpIntracellularConductivityTensorsSecondCell->SetConstantConductivities(mIntracellularConductivitiesSecondCell);
293  }
294 
295  mpIntracellularConductivityTensorsSecondCell->Init(this->mpMesh);
296  HeartEventHandler::EndEvent(HeartEventHandler::READ_MESH);
297 }
298 
299 template <unsigned SPACE_DIM>
301 {
302  return mUserSuppliedExtracellularStimulus;
303 }
304 
305 template <unsigned SPACE_DIM>
307 {
308  mUserSuppliedExtracellularStimulus = flag;
309 }
310 
311 template <unsigned SPACE_DIM>
312 const std::vector<AbstractCardiacCellInterface*>& ExtendedBidomainTissue<SPACE_DIM>::rGetSecondCellsDistributed() const
313 {
314  return mCellsDistributedSecondCell;
315 }
316 
317 template <unsigned SPACE_DIM>
319 {
320  return mGgapDistributed;
321 }
322 
323 template <unsigned SPACE_DIM>
324 const std::vector<boost::shared_ptr<AbstractStimulusFunction> >& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularStimulusDistributed() const
325 {
326  return mExtracellularStimuliDistributed;
327 }
328 
329 
330 template <unsigned SPACE_DIM>
332 {
333  if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
334  {
335  assert(this->mFibreFilePathNoExtension != "");
336  switch (this->mpConfig->GetConductivityMedia())
337  {
338  case cp::media_type::Orthotropic:
339  {
340  mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
341  FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
342  assert(ortho_file.Exists());
343  mpExtracellularConductivityTensors->SetFibreOrientationFile(ortho_file);
344  break;
345  }
346 
347  case cp::media_type::Axisymmetric:
348  {
349  mpExtracellularConductivityTensors = new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
350  FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
351  assert(axi_file.Exists());
352  mpExtracellularConductivityTensors->SetFibreOrientationFile(axi_file);
353  break;
354  }
355 
356  case cp::media_type::NoFibreOrientation:
357  mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
358  break;
359 
360  default :
362  }
363  }
364  else // no fibre orientation assumed
365  {
366  mpExtracellularConductivityTensors = new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
367  }
368 
369  c_vector<double, SPACE_DIM> extra_conductivities;
370  this->mpConfig->GetExtracellularConductivities(extra_conductivities);
371 
372  // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
373  // a pointer to it and we don't want it to go out of scope before Init() is called
374  unsigned num_elements = this->mpMesh->GetNumElements();
375  std::vector<c_vector<double, SPACE_DIM> > hetero_extra_conductivities;
376 
377  if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
378  {
379  try
380  {
381  assert(hetero_extra_conductivities.size()==0);
382  //initialise with the values of teh default conductivity tensor
383  hetero_extra_conductivities.resize(num_elements, extra_conductivities);
384  }
385  catch(std::bad_alloc &badAlloc)
386  {
387 #define COVERAGE_IGNORE
388  std::cout << "Failed to allocate std::vector of size " << num_elements << std::endl;
390  throw badAlloc;
391 #undef COVERAGE_IGNORE
392  }
394 
395  std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
396  std::vector< c_vector<double,3> > intra_h_conductivities;
397  std::vector< c_vector<double,3> > extra_h_conductivities;
398  HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
399  intra_h_conductivities,
400  extra_h_conductivities);
401  unsigned local_element_index = 0;
402  for (typename AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>::ElementIterator iter = (this->mpMesh)->GetElementIteratorBegin();
403  iter != (this->mpMesh)->GetElementIteratorEnd();
404  ++iter)
405  {
406  //unsigned element_index = iter->GetIndex();
407  // if element centroid is contained in the region
408  ChastePoint<SPACE_DIM> element_centroid(iter->CalculateCentroid());
409  for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
410  {
411  // if element centroid is contained in the region
412  if ( conductivities_heterogeneity_areas[region_index]->DoesContain( element_centroid ) )
413  {
414  //We don't use ublas vector assignment here, because we might be getting a subvector of a 3-vector
415  for (unsigned i=0; i<SPACE_DIM; i++)
416  {
417  hetero_extra_conductivities[local_element_index][i] = extra_h_conductivities[region_index][i];
418  }
419  }
420  }
421  local_element_index++;
422  }
423 
424  mpExtracellularConductivityTensors->SetNonConstantConductivities(&hetero_extra_conductivities);
425  }
426  else
427  {
428  mpExtracellularConductivityTensors->SetConstantConductivities(extra_conductivities);
429  }
430  mpExtracellularConductivityTensors->Init(this->mpMesh);
431 }
432 
433 template <unsigned SPACE_DIM>
435 {
436  // Delete (second) cells
437  for (std::vector<AbstractCardiacCellInterface*>::iterator cell_iterator = mCellsDistributedSecondCell.begin();
438  cell_iterator != mCellsDistributedSecondCell.end();
439  ++cell_iterator)
440  {
441  delete (*cell_iterator);
442  }
443 
444  if (mpExtracellularConductivityTensors)
445  {
446  delete mpExtracellularConductivityTensors;
447  }
448 
449  if (mpIntracellularConductivityTensorsSecondCell)
450  {
451  delete mpIntracellularConductivityTensorsSecondCell;
452  }
453 }
454 
455 template <unsigned SPACE_DIM>
457 {
458  for (unsigned i = 0; i < SPACE_DIM; i++)
459  {
460  mIntracellularConductivitiesSecondCell[i] = conductivities[i];
461  }
462 }
463 
464 template <unsigned SPACE_DIM>
466 {
467  return mIntracellularConductivitiesSecondCell;
468 }
469 
470 template <unsigned SPACE_DIM>
471 const c_matrix<double, SPACE_DIM, SPACE_DIM>& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularConductivityTensor(unsigned elementIndex)
472 {
473  assert(mpExtracellularConductivityTensors);
474  if (this->mpConductivityModifier==NULL)
475  {
476  return (*mpExtracellularConductivityTensors)[elementIndex];
477  }
478  else
479  {
480  return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpExtracellularConductivityTensors)[elementIndex], 1u);
481  }
482 }
483 
484 template <unsigned SPACE_DIM>
485 const c_matrix<double, SPACE_DIM, SPACE_DIM>& ExtendedBidomainTissue<SPACE_DIM>::rGetIntracellularConductivityTensorSecondCell(unsigned elementIndex)
486 {
487  assert(mpIntracellularConductivityTensorsSecondCell);
488  if (this->mpConductivityModifier==NULL)
489  {
490  return (*mpIntracellularConductivityTensorsSecondCell)[elementIndex];
491  }
492  else
493  {
494  return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpIntracellularConductivityTensorsSecondCell)[elementIndex], 2u);
495  }
496 }
497 
498 template <unsigned SPACE_DIM>
500 {
501  return mCellsDistributedSecondCell[globalIndex - this->mpDistributedVectorFactory->GetLow()];
502 }
503 
504 template <unsigned SPACE_DIM>
505 boost::shared_ptr<AbstractStimulusFunction> ExtendedBidomainTissue<SPACE_DIM>::GetExtracellularStimulus( unsigned globalIndex )
506 {
507  return mExtracellularStimuliDistributed[globalIndex - this->mpDistributedVectorFactory->GetLow()];
508 }
509 
510 template <unsigned SPACE_DIM>
511 void ExtendedBidomainTissue<SPACE_DIM>::SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage)
512 {
513  HeartEventHandler::BeginEvent(HeartEventHandler::SOLVE_ODES);
514 
515  DistributedVector dist_solution = this->mpDistributedVectorFactory->CreateDistributedVector(existingSolution);
516  DistributedVector::Stripe V_first_cell(dist_solution, 0);
517  DistributedVector::Stripe V_second_cell(dist_solution, 1);
518  DistributedVector::Stripe phi_e(dist_solution, 2);
519 
520  for (DistributedVector::Iterator index = dist_solution.Begin();
521  index != dist_solution.End();
522  ++index)
523  {
524  // overwrite the voltage with the input value
525  this->mCellsDistributed[index.Local]->SetVoltage( V_first_cell[index] );
526  mCellsDistributedSecondCell[index.Local]->SetVoltage( V_second_cell[index] );
527  try
528  {
529  // solve
530  // Note: Voltage should not be updated. GetIIonic will be called later
531  // and needs the old voltage. The voltage will be updated from the pde.
532  this->mCellsDistributed[index.Local]->ComputeExceptVoltage(time, nextTime);
533  mCellsDistributedSecondCell[index.Local]->ComputeExceptVoltage(time, nextTime);
534  }
535  catch (Exception &e)
536  {
537 #define COVERAGE_IGNORE
539  throw e;
540 #undef COVERAGE_IGNORE
541  }
542 
543  // update the Iionic and stimulus caches
544  this->UpdateCaches(index.Global, index.Local, nextTime);//in parent class
545  UpdateAdditionalCaches(index.Global, index.Local, nextTime);//extended bidomain specific caches
546  }
548  HeartEventHandler::EndEvent(HeartEventHandler::SOLVE_ODES);
549 
550  HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
551  if ( this->mDoCacheReplication )
552  {
553  this->ReplicateCaches();
554  ReplicateAdditionalCaches();//extended bidomain specific caches
555  }
556  HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
557 }
558 
559 template <unsigned SPACE_DIM>
560 void ExtendedBidomainTissue<SPACE_DIM>::UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
561 {
562  mIionicCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIIonic();
563  mIntracellularStimulusCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIntracellularStimulus(nextTime);
564  mExtracellularStimulusCacheReplicated[globalIndex] = mExtracellularStimuliDistributed[localIndex]->GetStimulus(nextTime);
565  mGgapCacheReplicated[globalIndex] = mGgapDistributed[localIndex];
566 }
567 
568 template <unsigned SPACE_DIM>
570 {
571  mIionicCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
572  mIntracellularStimulusCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
573  mExtracellularStimulusCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
574  mGgapCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
575 }
576 
577 template <unsigned SPACE_DIM>
579 {
580  return mIionicCacheReplicatedSecondCell;
581 }
582 
583 template <unsigned SPACE_DIM>
585 {
586  return mIntracellularStimulusCacheReplicatedSecondCell;
587 }
588 
589 template <unsigned SPACE_DIM>
591 {
592  return mExtracellularStimulusCacheReplicated;
593 }
594 
595 template <unsigned SPACE_DIM>
597 {
598  return mGgapCacheReplicated;
599 }
600 
601 template <unsigned SPACE_DIM>
603 {
604  return mAmFirstCell;
605 }
606 
607 template <unsigned SPACE_DIM>
609 {
610  return mAmSecondCell;
611 }
612 
613 template <unsigned SPACE_DIM>
615 {
616  return mAmGap;
617 }
618 
619 template <unsigned SPACE_DIM>
621 {
622  return mCmFirstCell;
623 }
624 
625 template <unsigned SPACE_DIM>
627 {
628  return mCmSecondCell;
629 }
630 
631 template <unsigned SPACE_DIM>
633 {
634  return mGGap;
635 }
636 
637 template <unsigned SPACE_DIM>
639 {
640  mAmFirstCell = value;
641 }
642 
643 template <unsigned SPACE_DIM>
645 {
646  mAmSecondCell = value;
647 }
648 
649 template <unsigned SPACE_DIM>
651 {
652  mAmGap = value;
653 }
654 
655 template <unsigned SPACE_DIM>
657 {
658  mGGap = value;
659 }
660 
661 template <unsigned SPACE_DIM>
663 {
664  mCmFirstCell = value;
665 }
666 
667 template <unsigned SPACE_DIM>
669 {
670  mCmSecondCell = value;
671 }
672 
674 // Explicit instantiation
676 
677 template class ExtendedBidomainTissue<1>;
678 template class ExtendedBidomainTissue<2>;
679 template class ExtendedBidomainTissue<3>;
680 
681 // Serialization for Boost >= 1.36
virtual void FinaliseCellCreation(std::vector< AbstractCardiacCellInterface * > *pCellsDistributed, unsigned lo, unsigned hi)
ReplicatableVector mIionicCacheReplicatedSecondCell
ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
virtual AbstractCardiacCellInterface * CreateCardiacCellForNode(Node< SPACE_DIM > *pNode)
ReplicatableVector & rGetExtracellularStimulusCacheReplicated()
DistributedVectorFactory * mpDistributedVectorFactory
ReplicatableVector & rGetIionicCacheReplicatedSecondCell()
Definition: Node.hpp:58
virtual void SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage=false)
c_vector< double, SPACE_DIM > GetIntracellularConductivitiesSecondCell() const
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * GetMesh()
std::vector< AbstractCardiacCellInterface * > mCellsDistributedSecondCell
ReplicatableVector & rGetGgapCacheReplicated()
void SetGgapHeterogeneities(std::vector< boost::shared_ptr< AbstractChasteRegion< SPACE_DIM > > > &rGgapHeterogeneityRegions, std::vector< double > rGgapValues)
AbstractCardiacCellInterface * GetCardiacSecondCell(unsigned globalIndex)
Node< SPACE_DIM > * GetNode(unsigned index) const
const c_matrix< double, SPACE_DIM, SPACE_DIM > & rGetExtracellularConductivityTensor(unsigned elementIndex)
void SetAmSecondCell(double value)
std::vector< double > mGgapDistributed
void UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
std::vector< boost::shared_ptr< AbstractStimulusFunction > > mExtracellularStimuliDistributed
#define NEVER_REACHED
Definition: Exception.hpp:206
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
boost::shared_ptr< AbstractStimulusFunction > GetExtracellularStimulus(unsigned globalIndex)
void SetCmSecondCell(double value)
const std::vector< AbstractCardiacCellInterface * > & rGetSecondCellsDistributed() const
ReplicatableVector mExtracellularStimulusCacheReplicated
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
ReplicatableVector mGgapCacheReplicated
const std::vector< boost::shared_ptr< AbstractStimulusFunction > > & rGetExtracellularStimulusDistributed() const
ReplicatableVector & rGetIntracellularStimulusCacheReplicatedSecondCell()
static void ReplicateException(bool flag)
Definition: PetscTools.cpp:198
AbstractTetrahedralMesh< ELEMENT_DIM, ELEMENT_DIM > * mpMesh
const std::vector< double > & rGetGapsDistributed() const
virtual boost::shared_ptr< AbstractStimulusFunction > CreateStimulusForNode(Node< SPACE_DIM > *pNode)
ReplicatableVector mIntracellularStimulusCacheReplicatedSecondCell
bool Exists() const
Definition: FileFinder.cpp:180
void Resize(unsigned size)
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * GetMesh()
ChastePoint< SPACE_DIM > GetPoint() const
Definition: Node.cpp:134
void SetIntracellularConductivitiesSecondCell(c_vector< double, SPACE_DIM > conductivities)
void SetUserSuppliedExtracellularStimulus(bool flag)
const c_matrix< double, SPACE_DIM, SPACE_DIM > & rGetIntracellularConductivityTensorSecondCell(unsigned elementIndex)
static HeartConfig * Instance()
ExtendedBidomainTissue(AbstractCardiacCellFactory< SPACE_DIM > *pCellFactory, AbstractCardiacCellFactory< SPACE_DIM > *pCellFactorySecondCell, AbstractStimulusFactory< SPACE_DIM > *pExtracellularStimulusFactory)