36 #include "AbstractCardiacTissue.hpp" 38 #include <boost/scoped_array.hpp> 40 #include "DistributedVector.hpp" 41 #include "AxisymmetricConductivityTensors.hpp" 42 #include "OrthotropicConductivityTensors.hpp" 44 #include "ChastePoint.hpp" 45 #include "AbstractChasteRegion.hpp" 46 #include "HeartEventHandler.hpp" 48 #include "PetscVecTools.hpp" 49 #include "AbstractCvodeCell.hpp" 50 #include "Warnings.hpp" 52 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
56 : mpMesh(pCellFactory->GetMesh()),
57 mpDistributedVectorFactory(mpMesh->GetDistributedVectorFactory()),
58 mpConductivityModifier(NULL),
60 mDoCacheReplication(true),
61 mMeshUnarchived(false),
62 mExchangeHalos(exchangeHalos)
65 assert(pCellFactory != NULL);
66 assert(pCellFactory->
GetMesh() != NULL);
75 bool process_has_no_nodes = (num_local_nodes == 0u);
85 EXCEPTION(
"No cells were assigned some process in AbstractCardiacTissue constructor. Advice: Make total number of processors no greater than number of nodes in the mesh");
94 if (p_purkinje_cell_factory)
105 for (
unsigned local_index = 0; local_index < num_local_nodes; local_index++)
107 unsigned global_index = ownership_range_low + local_index;
142 for (std::vector<AbstractCardiacCellInterface*>::iterator cell_iterator =
mCellsDistributed.begin();
146 delete (*cell_iterator);
180 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
196 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
200 for (std::vector<AbstractCardiacCellInterface*>::iterator iter =
mCellsDistributed.begin();
233 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
239 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
251 case cp::media_type::Orthotropic:
255 assert(ortho_file.
Exists());
260 case cp::media_type::Axisymmetric:
264 assert(axi_file.
Exists());
269 case cp::media_type::NoFibreOrientation:
284 c_vector<double, SPACE_DIM> intra_conductivities;
289 unsigned num_local_elements =
mpMesh->GetNumLocalElements();
290 std::vector<c_vector<double, SPACE_DIM> > hetero_intra_conductivities;
296 assert(hetero_intra_conductivities.size()==0);
297 hetero_intra_conductivities.resize(num_local_elements, intra_conductivities);
300 catch(std::bad_alloc &r_bad_alloc)
302 std::cout <<
"Failed to allocate std::vector of size " << num_local_elements << std::endl;
310 std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
311 std::vector< c_vector<double,3> > intra_h_conductivities;
312 std::vector< c_vector<double,3> > extra_h_conductivities;
314 intra_h_conductivities,
315 extra_h_conductivities);
317 unsigned local_element_index = 0;
320 it !=
mpMesh->GetElementIteratorEnd();
326 for (
unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
328 if (conductivities_heterogeneity_areas[region_index]->DoesContain(element_centroid))
331 for (
unsigned i=0; i<SPACE_DIM; i++)
333 hetero_intra_conductivities[local_element_index][i] = intra_h_conductivities[region_index][i];
337 local_element_index++;
352 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
358 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
364 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
378 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
381 EXCEPTION(
"Monodomain tissues do not have extracellular conductivity tensors.");
384 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
392 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
401 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
404 std::map<unsigned, unsigned>::const_iterator node_position;
422 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
425 std::set<unsigned> halos_as_set;
430 mHaloNodes = std::vector<unsigned>(halos_as_set.begin(), halos_as_set.end());
435 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
447 for (
unsigned local_index = 0; local_index < num_halo_nodes; local_index++)
449 unsigned global_index =
mHaloNodes[local_index];
463 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
469 assert(!updateVoltage);
486 double voltage_before_update;
488 index != dist_solution.
End();
491 voltage_before_update = voltage[index];
520 WARNING(
"Global node " << index.Global <<
" had an ODE solving problem in t = [" << time <<
521 ", " << nextTime <<
"] ms. This was fixed by a reset of CVODE, but may suggest PDE time" 522 " step should be reduced, or CVODE tolerances relaxed.");
529 #endif // CHASTE_CVODE 540 std::cout << std::setprecision(16);
541 std::cout <<
"Global node " << index.Global <<
" had problems with ODE solve between " 542 "t = " << time <<
" and " << nextTime <<
"ms.\n";
544 std::cout <<
"Voltage at this node before solve was " << voltage_before_update <<
"mV\n" 545 "(this SHOULD NOT necessarily be the same as the one in the state variables,\n" 546 "which can be ignored and stay at the initial condition - the voltage is dictated by PDE instead of state variable.)\n";
548 std::cout <<
"Stimulus current (NB converted to micro-Amps per cm^3) applied here is equal to:\n\t" 549 <<
mCellsDistributed[index.Local]->GetIntracellularStimulus(time) <<
" at t = " << time <<
"ms,\n\t" 550 <<
mCellsDistributed[index.Local]->GetIntracellularStimulus(nextTime) <<
" at t = " << nextTime <<
"ms.\n";
554 std::cout <<
"All state variables are now:\n";
555 std::vector<double> state_vars =
mCellsDistributed[index.Local]->GetStdVecStateVariables();
556 std::vector<std::string> state_var_names =
mCellsDistributed[index.Local]->rGetStateVariableNames();
557 for (
unsigned i=0; i<state_vars.size(); i++)
559 std::cout <<
"\t" << state_var_names[i] <<
"\t:\t" << state_vars[i] <<
"\n";
561 std::cout << std::flush;
589 index != dist_solution.
End();
634 unsigned send_size = 0;
635 for (
unsigned i=0; i<number_of_cells_to_send; i++)
641 boost::scoped_array<double> send_data(
new double[send_size]);
643 unsigned send_index = 0;
644 for (
unsigned cell = 0; cell < number_of_cells_to_send; cell++)
650 for (
unsigned state_variable = 0; state_variable < num_state_vars; state_variable++)
652 send_data[send_index++] = cell_data[state_variable];
656 unsigned receive_size = 0;
657 for (
unsigned i=0; i<number_of_cells_to_receive; i++)
663 boost::scoped_array<double> receive_data(
new double[receive_size]);
668 ret = MPI_Sendrecv(send_data.get(), send_size,
671 receive_data.get(), receive_size,
674 PETSC_COMM_WORLD, &status);
676 assert ( ret == MPI_SUCCESS);
679 unsigned receive_index = 0;
680 for (
unsigned cell = 0; cell < number_of_cells_to_receive; cell++ )
685 std::vector<double> cell_data(number_of_state_variables);
686 for (
unsigned state_variable = 0; state_variable < number_of_state_variables; state_variable++)
688 cell_data[state_variable] = receive_data[receive_index++];
703 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
709 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
715 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
722 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
729 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
736 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
744 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
761 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
767 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
774 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
780 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
783 assert(pModifier!=NULL);
virtual void FinaliseCellCreation(std::vector< AbstractCardiacCellInterface * > *pCellsDistributed, unsigned lo, unsigned hi)
ReplicatableVector mIntracellularStimulusCacheReplicated
virtual AbstractCardiacCellInterface * CreateCardiacCellForNode(Node< SPACE_DIM > *pNode)
AbstractConductivityTensors< ELEMENT_DIM, SPACE_DIM > * mpIntracellularConductivityTensors
void SetConductivityModifier(AbstractConductivityModifier< ELEMENT_DIM, SPACE_DIM > *pModifier)
cp::media_type GetConductivityMedia() const
void CreateIntracellularConductivityTensor()
DistributedVectorFactory * mpDistributedVectorFactory
AbstractCardiacCellInterface * CreatePurkinjeCellForNode(Node< SPACE_DIM > *pNode, AbstractCardiacCellInterface *pCardiacCell)
virtual unsigned GetNumberOfCells()
ReplicatableVector & rGetPurkinjeIionicCacheReplicated()
AbstractCardiacTissue(AbstractCardiacCellFactory< ELEMENT_DIM, SPACE_DIM > *pCellFactory, bool exchangeHalos=false)
std::vector< std::vector< unsigned > > mNodesToSendPerProcess
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * GetMesh()
virtual void SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage=false)
static std::string GetMeshFilename()
void Replicate(unsigned lo, unsigned hi)
void GetIntracellularConductivities(c_vector< double, 3 > &rIntraConductivities) const
DistributedVector CreateDistributedVector(Vec vec, bool readOnly=false)
#define EXCEPTION(message)
static void BeginEvent(unsigned event)
virtual ~AbstractCardiacTissue()
void UpdateCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
ReplicatableVector mPurkinjeIionicCacheReplicated
std::vector< AbstractCardiacCellInterface * > mPurkinjeCellsDistributed
virtual std::vector< double > GetStdVecStateVariables()=0
ReplicatableVector mPurkinjeIntracellularStimulusCacheReplicated
std::string GetMeshName() 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
virtual void SetStateVariables(const std::vector< double > &rVariables)=0
virtual unsigned GetNumberOfStateVariables() const =0
std::vector< AbstractCardiacCellInterface * > mHaloCellsDistributed
std::vector< AbstractCardiacCellInterface * > mCellsDistributed
bool IsGlobalIndexLocal(unsigned globalIndex)
bool GetDoCacheReplication()
AbstractCardiacCellInterface * GetCardiacCellOrHaloCell(unsigned globalIndex)
std::string mFibreFilePathNoExtension
ReplicatableVector & rGetIntracellularStimulusCacheReplicated()
std::vector< std::vector< unsigned > > mNodesToReceivePerProcess
AbstractCardiacCellInterface * GetPurkinjeCell(unsigned globalIndex)
void SetUpHaloCells(AbstractCardiacCellFactory< ELEMENT_DIM, SPACE_DIM > *pCellFactory)
unsigned GetProblemSize() const
virtual void FinalisePurkinjeCellCreation(std::vector< AbstractCardiacCellInterface * > *pPurkinjeCellsDistributed, unsigned lo, unsigned hi)
ReplicatableVector mIionicCacheReplicated
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * mpMesh
#define EXCEPT_IF_NOT(test)
const std::vector< AbstractCardiacCellInterface * > & rGetCellsDistributed() const
bool IsMeshProvided() const
virtual const c_matrix< double, SPACE_DIM, SPACE_DIM > & rGetExtracellularConductivityTensor(unsigned elementIndex)
AbstractConductivityModifier< ELEMENT_DIM, SPACE_DIM > * mpConductivityModifier
unsigned GetLocalOwnership() const
std::map< unsigned, unsigned > mHaloGlobalToLocalIndexMap
void Resize(unsigned size)
const std::vector< AbstractCardiacCellInterface * > & rGetPurkinjeCellsDistributed() const
void CalculateHaloNodesFromNodeExchange()
void SetCacheReplication(bool doCacheReplication)
ReplicatableVector & rGetPurkinjeIntracellularStimulusCacheReplicated()
static void EndEvent(unsigned event)
const c_matrix< double, SPACE_DIM, SPACE_DIM > & rGetIntracellularConductivityTensor(unsigned elementIndex)
static std::string GetArchiveDirectory()
std::vector< unsigned > mHaloNodes
AbstractCardiacCellInterface * GetCardiacCell(unsigned globalIndex)
void UpdatePurkinjeCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
static HeartConfig * Instance()
const AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * pGetMesh() const
bool GetConductivityHeterogeneitiesProvided() const
ReplicatableVector & rGetIionicCacheReplicated()