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