36 #include "AbstractCardiacProblem.hpp"
38 #include "GenericMeshReader.hpp"
40 #include "HeartConfig.hpp"
41 #include "HeartEventHandler.hpp"
42 #include "TimeStepper.hpp"
44 #include "DistributedVector.hpp"
45 #include "ProgressReporter.hpp"
46 #include "LinearSystem.hpp"
47 #include "PostProcessingWriter.hpp"
48 #include "Hdf5ToMeshalyzerConverter.hpp"
49 #include "Hdf5ToCmguiConverter.hpp"
50 #include "Hdf5ToVtkConverter.hpp"
53 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
57 mAllocatedMemoryForMesh(false),
60 mpCardiacTissue(NULL),
62 mpCellFactory(pCellFactory),
66 mpTimeAdaptivityController(NULL),
72 EXCEPTION(
"AbstractCardiacProblem: Please supply a cell factory pointer to your cardiac problem constructor.");
77 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
82 mAllocatedMemoryForMesh(false),
85 mVoltageColumnId(UINT_MAX),
86 mTimeColumnId(UINT_MAX),
87 mNodeColumnId(UINT_MAX),
88 mpCardiacTissue(NULL),
94 mpTimeAdaptivityController(NULL),
99 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
102 delete mpCardiacTissue;
108 if (mAllocatedMemoryForMesh)
114 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
122 WARNING(
"Using a non-distributed mesh in a parallel simulation is not a good idea.");
132 CreateMeshFromHeartConfig();
133 std::auto_ptr<AbstractMeshReader<ELEMENT_DIM, SPACE_DIM> > p_mesh_reader
135 mpMesh->ConstructFromMeshReader(*p_mesh_reader);
139 CreateMeshFromHeartConfig();
147 c_vector<double, 1> fibre_length;
149 mpMesh->ConstructRegularSlabMesh(inter_node_space, fibre_length[0]);
154 c_vector<double, 2> sheet_dimensions;
156 mpMesh->ConstructRegularSlabMesh(inter_node_space, sheet_dimensions[0], sheet_dimensions[1]);
161 c_vector<double, 3> slab_dimensions;
163 mpMesh->ConstructRegularSlabMesh(inter_node_space, slab_dimensions[0], slab_dimensions[1], slab_dimensions[2]);
175 mAllocatedMemoryForMesh =
true;
179 EXCEPTION(std::string(
"No mesh given: define it in XML parameters file or call SetMesh()\n") + e.
GetShortMessage());
182 mpCellFactory->SetMesh( mpMesh );
190 mpCellFactory->FillInCellularTransmuralAreas();
193 delete mpCardiacTissue;
194 mpCardiacTissue = CreateCardiacTissue();
214 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
220 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
223 this->mpBoundaryConditionsContainer = pBcc;
226 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
229 if ( mpCardiacTissue == NULL )
231 EXCEPTION(
"Cardiac tissue is null, Initialise() probably hasn't been called");
235 EXCEPTION(
"End time should be in the future");
241 EXCEPTION(
"Either explicitly specify not to print output (call PrintOutput(false)) or specify the output directory and filename prefix");
256 if( fabs(end_time - pde_time*round(end_time/pde_time)) > 1e-10 )
258 EXCEPTION(
"PDE timestep does not seem to divide end time - check parameters");
262 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
266 Vec initial_condition = p_factory->
CreateVec(PROBLEM_DIM);
268 std::vector<DistributedVector::Stripe> stripe;
269 stripe.reserve(PROBLEM_DIM);
271 for (
unsigned i=0; i<PROBLEM_DIM; i++)
280 stripe[0][index] = mpCardiacTissue->GetCardiacCell(index.Global)->GetVoltage();
283 stripe[1][index] = 0;
289 return initial_condition;
292 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
299 assert(mpMesh == NULL);
300 assert(pMesh != NULL);
301 mAllocatedMemoryForMesh =
false;
305 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
308 mPrintOutput = printOutput;
311 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
314 mWriteInfo = writeInfo;
317 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
323 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
326 return mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(mSolution);
329 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
335 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
342 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
345 if (mpCardiacTissue == NULL)
347 EXCEPTION(
"Tissue not yet set up, you may need to call Initialise() before GetTissue().");
349 return mpCardiacTissue;
352 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
360 mpTimeAdaptivityController = pController;
364 mpTimeAdaptivityController = NULL;
369 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
374 std::vector<double> additional_stopping_times;
375 SetUpAdditionalStoppingTimes(additional_stopping_times);
381 additional_stopping_times);
386 if (!mpBoundaryConditionsContainer)
390 for (
unsigned problem_index=0; problem_index<PROBLEM_DIM; problem_index++)
392 mpDefaultBoundaryConditionsContainer->DefineZeroNeumannOnMeshBoundary(mpMesh, problem_index);
394 mpBoundaryConditionsContainer = mpDefaultBoundaryConditionsContainer;
397 assert(mpSolver==NULL);
398 mpSolver = CreateSolver();
401 Vec initial_condition;
404 initial_condition = mSolution;
408 initial_condition = CreateInitialCondition();
411 std::string progress_reporter_dir;
416 bool extending_file =
false;
419 extending_file = InitialiseWriter();
426 if (mSolution != initial_condition)
446 if (!(mSolution && extending_file))
448 WriteOneStep(stepper.
GetTime(), initial_condition);
449 mpWriter->AdvanceAlongUnlimitedDimension();
457 progress_reporter_dir =
"";
459 BOOST_FOREACH(boost::shared_ptr<AbstractOutputModifier> p_output_modifier, mOutputModifiers)
461 p_output_modifier->InitialiseAtStart(this->mpMesh->GetDistributedVectorFactory());
462 p_output_modifier->ProcessSolutionAtTimeStep(stepper.
GetTime(), initial_condition, PROBLEM_DIM);
474 progress_reporter.
Update(mCurrentTime);
477 if (mpTimeAdaptivityController)
479 mpSolver->SetTimeAdaptivityController(mpTimeAdaptivityController);
486 mpSolver->SetInitialCondition( initial_condition );
488 AtBeginningOfTimestep(stepper.
GetTime());
494 mSolution = mpSolver->Solve();
512 if (initial_condition != mSolution)
527 CloseFilesAndPostProcess();
538 initial_condition = mSolution;
542 mCurrentTime = stepper.
GetTime();
552 BOOST_FOREACH(boost::shared_ptr<AbstractOutputModifier> p_output_modifier, mOutputModifiers)
554 p_output_modifier->ProcessSolutionAtTimeStep(stepper.
GetTime(), mSolution, PROBLEM_DIM);
560 WriteOneStep(stepper.
GetTime(), mSolution);
562 mpWriter->AdvanceAlongUnlimitedDimension();
569 OnEndOfTimestep(stepper.
GetTime());
578 BOOST_FOREACH(boost::shared_ptr<AbstractOutputModifier> p_output_modifier, mOutputModifiers)
580 p_output_modifier->FinaliseAtEnd();
582 CloseFilesAndPostProcess();
586 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
625 if (mNodesToOutput.empty())
678 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
683 if ( mNodesToOutput.empty() )
686 mpWriter->DefineFixedDimension( mpMesh->GetNumNodes() );
691 mpWriter->DefineFixedDimension( mNodesToOutput, mpMesh->GetNumNodes() );
694 mVoltageColumnId = mpWriter->DefineVariable(
"V",
"mV");
701 mpWriter->DefineUnlimitedDimension(
"Time",
"msecs", stepper.
EstimateTimeSteps()+1);
705 mVoltageColumnId = mpWriter->GetVariableByName(
"V");
709 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
712 mExtraVariablesId.clear();
717 std::vector<std::string> output_variables;
719 const unsigned num_vars = output_variables.size();
720 mExtraVariablesId.reserve(num_vars);
723 for (
unsigned var_index=0; var_index<num_vars; var_index++)
726 std::string var_name = output_variables[var_index];
732 column_id = this->mpWriter->GetVariableByName(var_name);
738 column_id = this->mpWriter->DefineVariable(var_name,
"unknown_units");
742 mExtraVariablesId.push_back(column_id);
747 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
751 std::vector<std::string> output_variables;
752 unsigned num_vars = mExtraVariablesId.size();
757 assert(output_variables.size() == num_vars);
760 for (
unsigned var_index=0; var_index<num_vars; var_index++)
763 Vec variable_data = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
764 DistributedVector distributed_var_data = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(variable_data);
768 index!= distributed_var_data.
End();
776 distributed_var_data[index] = 0.0;
781 distributed_var_data[index] = this->mpCardiacTissue->GetCardiacCell(index.Global)->
782 GetAnyVariable(output_variables[var_index], mCurrentTime);
785 distributed_var_data.
Restore();
788 this->mpWriter->PutVector(mExtraVariablesId[var_index], variable_data);
794 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
797 bool extend_file = (mSolution != NULL);
822 if (times.back() > mCurrentTime)
825 " with results from time = " << mCurrentTime <<
826 ", but it already contains results up to time = " << times.back() <<
"."
827 " Calling HeartConfig::Instance()->SetOutputDirectory() before Solve() will direct results elsewhere.");
832 mpWriter =
new Hdf5DataWriter(*mpMesh->GetDistributedVectorFactory(),
840 DefineWriterColumns(extend_file);
845 bool success = mpWriter->ApplyPermutation(mpMesh->rGetNodePermutation(),
true);
846 if (success ==
false)
855 mpWriter->EndDefineMode();
861 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
864 mNodesToOutput = nodesToOutput;
867 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
872 EXCEPTION(
"Data reader invalid as data writer cannot be initialised");
877 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
883 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
void WritePostProcessingFiles()
std::string GetOutputFilenamePrefix() const
double GetSimulationDuration() const
static bool IsRegionBath(HeartRegionType regionId)
void PrintOutput(bool rPrintOutput)
void Update(double currentTime)
std::string GetAbsolutePath() const
DistributedVector CreateDistributedVector(Vec vec, bool readOnly=false)
void Write(bool useArchiveLocationInfo=false, std::string subfolderName="output")
void GetSlabDimensions(c_vector< double, 3 > &slabDimensions) const
#define EXCEPTION(message)
static void BeginEvent(unsigned event)
virtual Vec CreateInitialCondition()
virtual void CreateMeshFromHeartConfig()
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > & rGetMesh()
void SetOutputUsingOriginalNodeOrdering(bool useOriginal)
void GetOutputVariables(std::vector< std::string > &rOutputVariables) const
DistributedTetrahedralMeshPartitionType::type GetMeshPartitioning() const
virtual void PreSolveChecks()
double GetPdeTimeStep() const
std::string GetMeshName() const
void GetFibreLength(c_vector< double, 1 > &fibreLength) const
void AdvanceOneTimeStep()
void CloseFilesAndPostProcess()
void GetSheetDimensions(c_vector< double, 2 > &sheetDimensions) const
Hdf5DataReader GetDataReader()
void SetUseTimeAdaptivityController(bool useAdaptivity, AbstractTimeAdaptivityController *pController=NULL)
AbstractCardiacTissue< ELEMENT_DIM, SPACE_DIM > * GetTissue()
std::vector< double > GetUnlimitedDimensionValues()
std::vector< unsigned > mNodesToOutput
std::string GetSubdirectory()
unsigned EstimateTimeSteps() const
void SetMesh(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh)
double GetInterNodeSpace() const
AbstractCardiacCellFactory< ELEMENT_DIM, SPACE_DIM > * mpCellFactory
virtual bool GetHasBath()
void SetOutputNodes(std::vector< unsigned > &rNodesToOutput)
virtual void DefineWriterColumns(bool extending)
virtual ~AbstractCardiacProblem()
void SetBoundaryConditionsContainer(BccType pBcc)
virtual void SetElectrodes()
bool GetVisualizeWithMeshalyzer() const
std::string GetOutputDirectory() const
static void EndEvent(unsigned event)
static std::string GetChasteTestOutputDirectory()
double GetNextTime() const
void SetWriteInfo(bool writeInfo=true)
void WriteExtraVariablesOneStep()
DistributedVector GetSolutionDistributedVector()
std::string GetShortMessage() const
static HeartConfig * Instance()
void DefineExtraVariablesWriterColumns(bool extending)