00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "AbstractCardiacProblem.hpp"
00030
00031 #include "TrianglesMeshReader.hpp"
00032 #include "Exception.hpp"
00033 #include "HeartConfig.hpp"
00034 #include "HeartEventHandler.hpp"
00035 #include "TimeStepper.hpp"
00036 #include "PetscTools.hpp"
00037 #include "DistributedVector.hpp"
00038 #include "ProgressReporter.hpp"
00039 #include "LinearSystem.hpp"
00040 #include "PostProcessingWriter.hpp"
00041 #include "Hdf5ToMeshalyzerConverter.hpp"
00042 #include "Hdf5ToCmguiConverter.hpp"
00043 #include "Hdf5ToVtkConverter.hpp"
00044
00045 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00046 AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::AbstractCardiacProblem(
00047 AbstractCardiacCellFactory<ELEMENT_DIM,SPACE_DIM>* pCellFactory)
00048 : mMeshFilename(""),
00049 mUseMatrixBasedRhsAssembly(true),
00050 mAllocatedMemoryForMesh(false),
00051 mWriteInfo(false),
00052 mPrintOutput(true),
00053 mpCardiacPde(NULL),
00054 mpAssembler(NULL),
00055 mpCellFactory(pCellFactory),
00056 mpMesh(NULL),
00057 mSolution(NULL),
00058 mCurrentTime(0.0),
00059 mpWriter(NULL)
00060 {
00061 assert(mNodesToOutput.empty());
00062
00063 HeartEventHandler::BeginEvent(HeartEventHandler::EVERYTHING);
00064 }
00065
00066
00067 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00068 AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::AbstractCardiacProblem()
00069
00070
00071 : mMeshFilename(""),
00072 mUseMatrixBasedRhsAssembly(true),
00073 mAllocatedMemoryForMesh(false),
00074 mWriteInfo(false),
00075 mPrintOutput(true),
00076 mVoltageColumnId(UINT_MAX),
00077 mTimeColumnId(UINT_MAX),
00078 mNodeColumnId(UINT_MAX),
00079 mpCardiacPde(NULL),
00080 mpAssembler(NULL),
00081 mpCellFactory(NULL),
00082 mpMesh(NULL),
00083 mSolution(NULL),
00084 mCurrentTime(0.0),
00085 mpWriter(NULL)
00086 {
00087 }
00088
00089
00090 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00091 AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::~AbstractCardiacProblem()
00092 {
00093 delete mpCardiacPde;
00094 if (mSolution)
00095 {
00096 VecDestroy(mSolution);
00097 }
00098
00099 if (mAllocatedMemoryForMesh)
00100 {
00101 delete mpMesh;
00102 }
00103 };
00104
00105 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00106 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::Initialise()
00107 {
00108 HeartEventHandler::BeginEvent(HeartEventHandler::READ_MESH);
00109 if (mpMesh==NULL)
00110 {
00111
00112 try
00113 {
00114 if(HeartConfig::Instance()->GetLoadMesh())
00115 {
00116 mpMesh = new DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>();
00117 TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM> mesh_reader(HeartConfig::Instance()->GetMeshName());
00118 mpMesh->ConstructFromMeshReader(mesh_reader);
00119 }
00120 else if(HeartConfig::Instance()->GetCreateMesh())
00121 {
00122 mpMesh = new DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>();
00123 assert(HeartConfig::Instance()->GetSpaceDimension()==SPACE_DIM);
00124 double inter_node_space = HeartConfig::Instance()->GetInterNodeSpace();
00125
00126 switch(HeartConfig::Instance()->GetSpaceDimension())
00127 {
00128 case 1:
00129 {
00130 c_vector<double, 1> fibre_length;
00131 HeartConfig::Instance()->GetFibreLength(fibre_length);
00132 unsigned slab_nodes_x = (unsigned)round(fibre_length[0]/inter_node_space);
00133 mpMesh->ConstructLinearMesh(slab_nodes_x);
00134 break;
00135 }
00136 case 2:
00137 {
00138 c_vector<double, 2> sheet_dimensions;
00139 HeartConfig::Instance()->GetSheetDimensions(sheet_dimensions);
00140 unsigned slab_nodes_x = (unsigned)round(sheet_dimensions[0]/inter_node_space);
00141 unsigned slab_nodes_y = (unsigned)round(sheet_dimensions[1]/inter_node_space);
00142 mpMesh->ConstructRectangularMesh(slab_nodes_x, slab_nodes_y);
00143 break;
00144 }
00145 case 3:
00146 {
00147 c_vector<double, 3> slab_dimensions;
00148 HeartConfig::Instance()->GetSlabDimensions(slab_dimensions);
00149 unsigned slab_nodes_x = (unsigned)round(slab_dimensions[0]/inter_node_space);
00150 unsigned slab_nodes_y = (unsigned)round(slab_dimensions[1]/inter_node_space);
00151 unsigned slab_nodes_z = (unsigned)round(slab_dimensions[2]/inter_node_space);
00152 mpMesh->ConstructCuboid(slab_nodes_x, slab_nodes_y, slab_nodes_z);
00153 break;
00154 }
00155 default:
00156 NEVER_REACHED;
00157 }
00158
00159 mpMesh->Scale(inter_node_space, inter_node_space, inter_node_space);
00160
00161 }
00162 else
00163 {
00164 NEVER_REACHED;
00165 }
00166
00167 mAllocatedMemoryForMesh = true;
00168 }
00169 catch (Exception& e)
00170 {
00171 EXCEPTION(std::string("No mesh given: define it in XML parameters file or call SetMesh()\n") + e.GetShortMessage());
00172 }
00173 }
00174 mpCellFactory->SetMesh( mpMesh );
00175 HeartEventHandler::EndEvent(HeartEventHandler::READ_MESH);
00176
00177 HeartEventHandler::BeginEvent(HeartEventHandler::INITIALISE);
00178
00179 if (HeartConfig::Instance()->AreCellularTransmuralHeterogeneitiesRequested())
00180 {
00181 mpCellFactory->FillInCellularTransmuralAreas();
00182 }
00183
00184 delete mpCardiacPde;
00185 mpCardiacPde = CreateCardiacPde();
00186
00187 HeartEventHandler::EndEvent(HeartEventHandler::INITIALISE);
00188
00189
00190 if (mSolution)
00191 {
00192 HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
00193 VecDestroy(mSolution);
00194 mSolution = NULL;
00195 HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
00196 }
00197
00198
00199 mCurrentTime = 0.0;
00200 }
00201
00202
00203 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00204 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::SetBoundaryConditionsContainer(boost::shared_ptr<BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM> > pBcc)
00205 {
00206 this->mpBoundaryConditionsContainer = pBcc;
00207 }
00208
00209 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00210 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::PreSolveChecks()
00211 {
00212 if ( mpCardiacPde == NULL )
00213 {
00214 EXCEPTION("Pde is null, Initialise() probably hasn't been called");
00215 }
00216 if ( HeartConfig::Instance()->GetSimulationDuration() <= mCurrentTime)
00217 {
00218 EXCEPTION("End time should be in the future");
00219 }
00220 if (mPrintOutput==true)
00221 {
00222 if( (HeartConfig::Instance()->GetOutputDirectory()=="") || (HeartConfig::Instance()->GetOutputFilenamePrefix()==""))
00223 {
00224 EXCEPTION("Either explicitly specify not to print output (call PrintOutput(false)) or specify the output directory and filename prefix");
00225 }
00226 }
00227
00228 double end_time = HeartConfig::Instance()->GetSimulationDuration();
00229 double pde_time = HeartConfig::Instance()->GetPdeTimeStep();
00230
00231
00232
00233
00234
00235 if( fabs( end_time - pde_time*round(end_time/pde_time)) > 1e-10 )
00236 {
00237 EXCEPTION("Pde timestep does not seem to divide end time - check parameters");
00238 }
00239 }
00240
00241 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00242 Vec AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::CreateInitialCondition()
00243 {
00244 DistributedVectorFactory* p_factory = mpMesh->GetDistributedVectorFactory();
00245 Vec initial_condition = p_factory->CreateVec(PROBLEM_DIM);
00246 DistributedVector ic = p_factory->CreateDistributedVector(initial_condition);
00247 std::vector<DistributedVector::Stripe> stripe;
00248 stripe.reserve(PROBLEM_DIM);
00249
00250 for (unsigned i=0; i<PROBLEM_DIM; i++)
00251 {
00252 stripe.push_back(DistributedVector::Stripe(ic, i));
00253 }
00254
00255 for (DistributedVector::Iterator index = ic.Begin();
00256 index != ic.End();
00257 ++index)
00258 {
00259 stripe[0][index] = mpCardiacPde->GetCardiacCell(index.Global)->GetVoltage();
00260 if (PROBLEM_DIM==2)
00261 {
00262 stripe[1][index] = 0;
00263 }
00264 }
00265
00266 ic.Restore();
00267
00268 return initial_condition;
00269 }
00270
00271 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00272 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::SetMesh(AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh)
00273 {
00274
00275
00276 assert(mpMesh==NULL);
00277 assert(pMesh!=NULL);
00278 mAllocatedMemoryForMesh = false;
00279 mpMesh = pMesh;
00280 }
00281
00282 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00283 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::PrintOutput(bool printOutput)
00284 {
00285 mPrintOutput = printOutput;
00286 }
00287
00288 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00289 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::SetWriteInfo(bool writeInfo)
00290 {
00291 mWriteInfo = writeInfo;
00292 }
00293
00294 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00295 Vec AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::GetSolution()
00296 {
00297 return mSolution;
00298 }
00299
00300 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00301 DistributedVector AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::GetSolutionDistributedVector()
00302 {
00303 return mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(mSolution);
00304 }
00305
00306 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00307 double AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::GetCurrentTime()
00308 {
00309 return mCurrentTime;
00310 }
00311
00312 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00313 AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM> & AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::rGetMesh()
00314 {
00315 assert (mpMesh);
00316 return *mpMesh;
00317 }
00318
00319 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00320 AbstractCardiacPde<ELEMENT_DIM,SPACE_DIM>* AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::GetPde()
00321 {
00322 return mpCardiacPde;
00323 }
00324
00325 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00326 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::Solve()
00327 {
00328 PreSolveChecks();
00329
00330 if (!mpBoundaryConditionsContainer)
00331 {
00332
00333 mpDefaultBoundaryConditionsContainer.reset(new BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>);
00334 for (unsigned problem_index=0; problem_index<PROBLEM_DIM; problem_index++)
00335 {
00336 mpDefaultBoundaryConditionsContainer->DefineZeroNeumannOnMeshBoundary(mpMesh, problem_index);
00337 }
00338 mpBoundaryConditionsContainer = mpDefaultBoundaryConditionsContainer;
00339 }
00340
00341 assert(mpAssembler==NULL);
00342 mpAssembler = CreateAssembler();
00343
00344
00345 Vec initial_condition;
00346 if (mSolution)
00347 {
00348 initial_condition = mSolution;
00349 }
00350 else
00351 {
00352 initial_condition = CreateInitialCondition();
00353 }
00354
00355 std::vector<double> additional_stopping_times;
00356 SetUpAdditionalStoppingTimes(additional_stopping_times);
00357
00358 TimeStepper stepper(mCurrentTime,
00359 HeartConfig::Instance()->GetSimulationDuration(),
00360 HeartConfig::Instance()->GetPrintingTimeStep(),
00361 false,
00362 additional_stopping_times);
00363
00364 std::string progress_reporter_dir;
00365
00366 if (mPrintOutput)
00367 {
00368 HeartEventHandler::BeginEvent(HeartEventHandler::WRITE_OUTPUT);
00369 try
00370 {
00371 InitialiseWriter();
00372 }
00373 catch (Exception& e)
00374 {
00375 delete mpWriter;
00376 mpWriter = NULL;
00377 delete mpAssembler;
00378 if (mSolution != initial_condition)
00379 {
00380 VecDestroy(initial_condition);
00381 }
00382 throw e;
00383 }
00384
00385
00386
00387
00388 if (!mSolution)
00389 {
00390 WriteOneStep(stepper.GetTime(), initial_condition);
00391 mpWriter->AdvanceAlongUnlimitedDimension();
00392 }
00393 HeartEventHandler::EndEvent(HeartEventHandler::WRITE_OUTPUT);
00394
00395 progress_reporter_dir = HeartConfig::Instance()->GetOutputDirectory();
00396 }
00397 else
00398 {
00399 progress_reporter_dir = "";
00400 }
00401
00402
00403
00404
00405 ProgressReporter progress_reporter(progress_reporter_dir, mCurrentTime,
00406 HeartConfig::Instance()->GetSimulationDuration());
00407 progress_reporter.Update(mCurrentTime);
00408
00409
00410 while ( !stepper.IsTimeAtEnd() )
00411 {
00412
00413 mpAssembler->SetTimes(stepper.GetTime(), stepper.GetNextTime(), HeartConfig::Instance()->GetPdeTimeStep());
00414 mpAssembler->SetInitialCondition( initial_condition );
00415
00416 AtBeginningOfTimestep(stepper.GetTime());
00417
00418 try
00419 {
00420 mSolution = mpAssembler->Solve();
00421 }
00422 catch (Exception &e)
00423 {
00424
00425 delete mpAssembler;
00426 mpAssembler=NULL;
00427
00428 #ifndef NDEBUG
00429 PetscTools::ReplicateException(true);
00430 #endif
00431
00432 HeartEventHandler::Reset();
00434 CloseFilesAndPostProcess();
00435 throw e;
00436 }
00437 #ifndef NDEBUG
00438 PetscTools::ReplicateException(false);
00439 #endif
00440
00441
00442 HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
00443 VecDestroy(initial_condition);
00444 HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
00445
00446
00447 initial_condition = mSolution;
00448
00449
00450 stepper.AdvanceOneTimeStep();
00451 mCurrentTime = stepper.GetTime();
00452
00453 if (mPrintOutput)
00454 {
00455
00456 if (mWriteInfo)
00457 {
00458 HeartEventHandler::BeginEvent(HeartEventHandler::WRITE_OUTPUT);
00459 WriteInfo(stepper.GetTime());
00460 HeartEventHandler::EndEvent(HeartEventHandler::WRITE_OUTPUT);
00461 }
00462
00463
00464 HeartEventHandler::BeginEvent(HeartEventHandler::WRITE_OUTPUT);
00465 WriteOneStep(stepper.GetTime(), mSolution);
00466
00467 mpWriter->AdvanceAlongUnlimitedDimension();
00468
00469 HeartEventHandler::EndEvent(HeartEventHandler::WRITE_OUTPUT);
00470 }
00471
00472 progress_reporter.Update(stepper.GetTime());
00473
00474 OnEndOfTimestep(stepper.GetTime());
00475 }
00476
00477
00478 delete mpAssembler;
00479 mpAssembler=NULL;
00480
00481
00482 progress_reporter.PrintFinalising();
00483 CloseFilesAndPostProcess();
00484 HeartEventHandler::EndEvent(HeartEventHandler::EVERYTHING);
00485 }
00486
00487 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00488 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::CloseFilesAndPostProcess()
00489 {
00490
00491 if (!mPrintOutput)
00492 {
00493
00494 return;
00495 }
00496 delete mpWriter;
00497 mpWriter = NULL;
00498
00499 HeartEventHandler::BeginEvent(HeartEventHandler::POST_PROC);
00500
00501 if (mNodesToOutput.empty())
00502 {
00503 if (HeartConfig::Instance()->GetVisualizeWithMeshalyzer())
00504 {
00505
00506 Hdf5ToMeshalyzerConverter<ELEMENT_DIM,SPACE_DIM> converter(HeartConfig::Instance()->GetOutputDirectory(), HeartConfig::Instance()->GetOutputFilenamePrefix(), mpMesh);
00507 }
00508
00509 if (HeartConfig::Instance()->GetVisualizeWithCmgui())
00510 {
00511
00512 Hdf5ToCmguiConverter<ELEMENT_DIM,SPACE_DIM> converter(HeartConfig::Instance()->GetOutputDirectory(), HeartConfig::Instance()->GetOutputFilenamePrefix(), mpMesh);
00513 }
00514
00515 if (HeartConfig::Instance()->GetVisualizeWithVtk())
00516 {
00517
00518 Hdf5ToVtkConverter<ELEMENT_DIM,SPACE_DIM> converter(HeartConfig::Instance()->GetOutputDirectory(), HeartConfig::Instance()->GetOutputFilenamePrefix(), mpMesh);
00519 }
00520 }
00521
00522 if(HeartConfig::Instance()->IsPostProcessingRequested())
00523 {
00524 PostProcessingWriter<ELEMENT_DIM, SPACE_DIM> post_writer(*mpMesh, HeartConfig::Instance()->GetOutputDirectory(),
00525 HeartConfig::Instance()->GetOutputFilenamePrefix(), true);
00526 post_writer.WritePostProcessingFiles();
00527 }
00528
00529 HeartEventHandler::EndEvent(HeartEventHandler::POST_PROC);
00530 }
00531
00532 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00533 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::DefineWriterColumns(bool extending)
00534 {
00535 if (!extending)
00536 {
00537 if ( mNodesToOutput.empty() )
00538 {
00539
00540 mpWriter->DefineFixedDimension( mpMesh->GetNumNodes() );
00541 }
00542 else
00543 {
00544
00545 mpWriter->DefineFixedDimension( mNodesToOutput, mpMesh->GetNumNodes() );
00546 }
00547
00548 mVoltageColumnId = mpWriter->DefineVariable("V","mV");
00549
00550 mpWriter->DefineUnlimitedDimension("Time","msecs");
00551 }
00552 else
00553 {
00554 mVoltageColumnId = mpWriter->GetVariableByName("V");
00555 }
00556 }
00557
00558 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00559 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::DefineExtraVariablesWriterColumns(bool extending)
00560 {
00561
00562 if (HeartConfig::Instance()->GetOutputVariablesProvided())
00563 {
00564
00565 std::vector<std::string> output_variables;
00566 HeartConfig::Instance()->GetOutputVariables(output_variables);
00567
00568
00569 for (unsigned var_index=0; var_index<output_variables.size(); var_index++)
00570 {
00571
00572 std::string var_name = output_variables[var_index];
00573
00574
00575 unsigned column_id;
00576 if (extending)
00577 {
00578 column_id = this->mpWriter->GetVariableByName(var_name);
00579 }
00580 else
00581 {
00582 column_id = this->mpWriter->DefineVariable(var_name, "");
00583 }
00584
00585
00586 mExtraVariablesId.push_back(column_id);
00587 }
00588 }
00589 }
00590
00591 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00592 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::WriteExtraVariablesOneStep()
00593 {
00594
00595 for (unsigned var_index=0; var_index<mExtraVariablesId.size(); var_index++)
00596 {
00597
00598 Vec variable_data = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00599 DistributedVector distributed_var_data = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(variable_data);
00600
00601
00602 for (DistributedVector::Iterator index = distributed_var_data.Begin();
00603 index!= distributed_var_data.End();
00604 ++index)
00605 {
00606
00607 distributed_var_data[index] = this->mpCardiacPde->GetCardiacCell(index.Global)->GetStateVariableValueByNumber(mExtraVariablesId[var_index]);
00608 }
00609 distributed_var_data.Restore();
00610
00611
00612 this->mpWriter->PutVector(mExtraVariablesId[var_index], variable_data);
00613
00614 VecDestroy(variable_data);
00615 }
00616 }
00617
00618 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00619 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::InitialiseWriter()
00620 {
00621 bool extend_file = (mSolution != NULL);
00622
00623
00624 assert(!mpWriter);
00625
00626 try
00627 {
00628 mpWriter = new Hdf5DataWriter(*mpMesh->GetDistributedVectorFactory(),
00629 HeartConfig::Instance()->GetOutputDirectory(),
00630 HeartConfig::Instance()->GetOutputFilenamePrefix(),
00631 !extend_file,
00632 extend_file);
00633 }
00634 catch (Exception& e)
00635 {
00636
00637 assert(extend_file);
00638
00639 extend_file = false;
00640 mpWriter = new Hdf5DataWriter(*mpMesh->GetDistributedVectorFactory(),
00641 HeartConfig::Instance()->GetOutputDirectory(),
00642 HeartConfig::Instance()->GetOutputFilenamePrefix(),
00643 !extend_file,
00644 extend_file);
00645 }
00646
00647
00648 DefineWriterColumns(extend_file);
00649 if (!extend_file)
00650 {
00651 mpWriter->EndDefineMode();
00652 }
00653 }
00654
00655 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00656 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::SetOutputNodes(std::vector<unsigned> &nodesToOutput)
00657 {
00658 mNodesToOutput = nodesToOutput;
00659 }
00660
00661 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00662 Hdf5DataReader AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::GetDataReader()
00663 {
00664 if( (HeartConfig::Instance()->GetOutputDirectory()=="") || (HeartConfig::Instance()->GetOutputFilenamePrefix()==""))
00665 {
00666 EXCEPTION("Data reader invalid as data writer cannot be initialised");
00667 }
00668 return Hdf5DataReader(HeartConfig::Instance()->GetOutputDirectory(), HeartConfig::Instance()->GetOutputFilenamePrefix());
00669 }
00670
00671 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00672 void AbstractCardiacProblem<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::UseMatrixBasedRhsAssembly(bool usematrix)
00673 {
00674 mUseMatrixBasedRhsAssembly = usematrix;
00675 }
00676
00678
00680
00681
00682 template class AbstractCardiacProblem<1,1,1>;
00683 template class AbstractCardiacProblem<1,2,1>;
00684 template class AbstractCardiacProblem<1,3,1>;
00685 template class AbstractCardiacProblem<2,2,1>;
00686 template class AbstractCardiacProblem<3,3,1>;
00687
00688
00689 template class AbstractCardiacProblem<1,1,2>;
00690 template class AbstractCardiacProblem<2,2,2>;
00691 template class AbstractCardiacProblem<3,3,2>;