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
00030 #include "HeartConfig.hpp"
00031 using namespace xsd::cxx::tree;
00032
00033 std::auto_ptr<HeartConfig> HeartConfig::mpInstance;
00034
00035 HeartConfig* HeartConfig::Instance()
00036 {
00037 if (mpInstance.get() == NULL)
00038 {
00039 mpInstance.reset(new HeartConfig);
00040 }
00041 return mpInstance.get();
00042 }
00043
00044 HeartConfig::HeartConfig()
00045 {
00046 assert(mpInstance.get() == NULL);
00047 mpDefaultParameters = NULL;
00048 mpUserParameters = NULL;
00049 mpDefaultParameters = ReadFile("ChasteDefaults.xml");
00050 mpUserParameters = mpDefaultParameters;
00051
00052 }
00053
00054 HeartConfig::~HeartConfig()
00055 {
00056 if (mpUserParameters != mpDefaultParameters)
00057 {
00058 delete mpUserParameters;
00059 }
00060
00061 delete mpDefaultParameters;
00062 }
00063
00064 void HeartConfig::SetDefaultsFile(std::string fileName)
00065 {
00066 bool same_target = (mpUserParameters == mpDefaultParameters);
00067
00068 delete mpDefaultParameters;
00069 mpDefaultParameters = ReadFile(fileName);
00070
00071 if (same_target)
00072 {
00073 mpUserParameters = mpDefaultParameters;
00074 }
00075 CheckTimeSteps();
00076 }
00077
00078 void HeartConfig::Write(std::string dirName, std::string fileName)
00079 {
00080
00081 OutputFileHandler output_file_handler(dirName, false);
00082 out_stream p_file = output_file_handler.OpenOutputFile(fileName);
00083
00084
00085
00086 xml_schema::namespace_infomap map;
00087 char buf[10000];
00088 std::string absolute_path_to_xsd=getcwd(buf, 10000);
00089 absolute_path_to_xsd += "/heart/src/io/ChasteParameters.xsd";
00090 map[""].schema = absolute_path_to_xsd;
00091
00092 ChasteParameters(*p_file, *mpUserParameters, map);
00093 }
00094 chaste_parameters_type* HeartConfig::ReadFile(std::string fileName)
00095 {
00096
00097
00098
00099
00100 try
00101 {
00102 std::auto_ptr<chaste_parameters_type> p_default(ChasteParameters(fileName));
00103 return new chaste_parameters_type(*p_default);
00104 }
00105 catch (const xml_schema::exception& e)
00106 {
00107 std::cerr << e << std::endl;
00108
00109 mpUserParameters = NULL;
00110 mpDefaultParameters = NULL;
00111 EXCEPTION("XML parsing error in configuration file: " + fileName);
00112 }
00113 }
00114
00115 void HeartConfig::SetParametersFile(std::string fileName)
00116 {
00117
00118 if (mpUserParameters != mpDefaultParameters)
00119 {
00120 delete mpUserParameters;
00121 }
00122 mpUserParameters = ReadFile(fileName);
00123 }
00124
00125 chaste_parameters_type* HeartConfig::UserParameters()
00126 {
00127 return mpUserParameters;
00128 }
00129
00130 chaste_parameters_type* HeartConfig::DefaultParameters()
00131 {
00132 return mpDefaultParameters;
00133 }
00134
00135 void HeartConfig::Reset()
00136 {
00137
00138 mpInstance.reset(0);
00139
00140 mpInstance.reset(new HeartConfig);
00141 }
00142
00143 template<class TYPE>
00144 TYPE* HeartConfig::DecideLocation(TYPE* ptr1, TYPE* ptr2, const std::string& nameParameter) const
00145 {
00146 if (ptr1->present())
00147 {
00148 return ptr1;
00149 }
00150 if (ptr2->present())
00151 {
00152 return ptr2;
00153 }
00154 EXCEPTION("No " + nameParameter + " provided (neither default nor user defined)");
00155 }
00156
00157 unsigned HeartConfig::GetSpaceDimension() const
00158 {
00159 return DecideLocation( & mpUserParameters->Simulation().SpaceDimension(),
00160 & mpDefaultParameters->Simulation().SpaceDimension(),
00161 "SpaceDimension")->get();
00162 }
00163
00164 double HeartConfig::GetSimulationDuration() const
00165 {
00166 return DecideLocation( & mpUserParameters->Simulation().SimulationDuration(),
00167 & mpDefaultParameters->Simulation().SimulationDuration(),
00168 "SimulationDuration")->get();
00169 }
00170
00171 domain_type HeartConfig::GetDomain() const
00172 {
00173 return DecideLocation( & mpUserParameters->Simulation().Domain(),
00174 & mpDefaultParameters->Simulation().Domain(),
00175 "Domain")->get();
00176 }
00177
00178 ionic_models_available_type HeartConfig::GetDefaultIonicModel() const
00179 {
00180 return DecideLocation( & mpUserParameters->Simulation().IonicModels(),
00181 & mpDefaultParameters->Simulation().IonicModels(),
00182 "IonicModel")->get().Default();
00183 }
00184
00185 void HeartConfig::GetIonicModelRegions(std::vector<ChasteCuboid>& definedRegions,
00186 std::vector<ionic_models_available_type>& ionicModels) const
00187 {
00188 ionic_models_type::Region::container&
00189 regions = DecideLocation( & mpUserParameters->Simulation().IonicModels(),
00190 & mpDefaultParameters->Simulation().IonicModels(),
00191 "IonicModel")->get().Region();
00192
00193 for (ionic_models_type::Region::iterator i = regions.begin();
00194 i != regions.end();
00195 ++i)
00196 {
00197 ionic_model_region_type ionic_model_region(*i);
00198 point_type point_a = ionic_model_region.Location().Cuboid().LowerCoordinates();
00199 point_type point_b = ionic_model_region.Location().Cuboid().UpperCoordinates();
00200
00201 ChastePoint<3> chaste_point_a ( point_a.x(),
00202 point_a.y(),
00203 point_a.z());
00204
00205 ChastePoint<3> chaste_point_b ( point_b.x(),
00206 point_b.y(),
00207 point_b.z());
00208
00209 definedRegions.push_back(ChasteCuboid( chaste_point_a, chaste_point_b ));
00210 ionicModels.push_back(ionic_model_region.IonicModel());
00211 }
00212 }
00213
00214
00215 bool HeartConfig::GetIsMeshProvided() const
00216 {
00217 try
00218 {
00219 DecideLocation( & mpUserParameters->Simulation().Mesh(),
00220 & mpDefaultParameters->Simulation().Mesh(),
00221 "Mesh");
00222 return true;
00223 }
00224 catch (Exception& e)
00225 {
00226 return false;
00227 }
00228 }
00229
00230 bool HeartConfig::GetCreateMesh() const
00231 {
00232 mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().Mesh(),
00233 & mpDefaultParameters->Simulation().Mesh(),
00234 "Mesh")->get();
00235
00236 return (mesh.Slab().present() || mesh.Sheet().present() || mesh.Fibre().present());
00237 }
00238
00239 bool HeartConfig::GetCreateSlab() const
00240 {
00241 mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().Mesh(),
00242 & mpDefaultParameters->Simulation().Mesh(),
00243 "Mesh")->get();
00244
00245 return (mesh.Slab().present());
00246 }
00247
00248 bool HeartConfig::GetCreateSheet() const
00249 {
00250 mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().Mesh(),
00251 & mpDefaultParameters->Simulation().Mesh(),
00252 "Mesh")->get();
00253
00254 return (mesh.Sheet().present());
00255 }
00256
00257 bool HeartConfig::GetCreateFibre() const
00258 {
00259 mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().Mesh(),
00260 & mpDefaultParameters->Simulation().Mesh(),
00261 "Mesh")->get();
00262
00263 return (mesh.Fibre().present());
00264 }
00265
00266
00267 bool HeartConfig::GetLoadMesh() const
00268 {
00269 return (DecideLocation( & mpUserParameters->Simulation().Mesh(),
00270 & mpDefaultParameters->Simulation().Mesh(),
00271 "Mesh")->get().LoadMesh().present());
00272 }
00273
00274 void HeartConfig::GetSlabDimensions(c_vector<double, 3>& slabDimensions) const
00275 {
00276 if (GetSpaceDimension()!=3 || !GetCreateSlab())
00277 {
00278 EXCEPTION("Tissue slabs can only be defined in 3D");
00279 }
00280
00281 optional<slab_type, false> slab_dimensions = DecideLocation( & mpUserParameters->Simulation().Mesh(),
00282 & mpDefaultParameters->Simulation().Mesh(),
00283 "Slab")->get().Slab();
00284
00285 slabDimensions[0] = slab_dimensions->x();
00286 slabDimensions[1] = slab_dimensions->y();
00287 slabDimensions[2] = slab_dimensions->z();
00288 }
00289
00290 void HeartConfig::GetSheetDimensions(c_vector<double, 2>& sheetDimensions) const
00291 {
00292 if (GetSpaceDimension()!=2 || !GetCreateSheet())
00293 {
00294 EXCEPTION("Tissue sheets can only be defined in 2D");
00295 }
00296
00297 optional<sheet_type, false> sheet_dimensions = DecideLocation( & mpUserParameters->Simulation().Mesh(),
00298 & mpDefaultParameters->Simulation().Mesh(),
00299 "Sheet")->get().Sheet();
00300
00301 sheetDimensions[0] = sheet_dimensions->x();
00302 sheetDimensions[1] = sheet_dimensions->y();
00303 }
00304
00305 void HeartConfig::GetFibreLength(c_vector<double, 1>& fibreLength) const
00306 {
00307 if (GetSpaceDimension()!=1 || !GetCreateFibre())
00308 {
00309 EXCEPTION("Tissue fibres can only be defined in 1D");
00310 }
00311
00312 optional<fibre_type, false> fibre_length = DecideLocation( & mpUserParameters->Simulation().Mesh(),
00313 & mpDefaultParameters->Simulation().Mesh(),
00314 "Fibre")->get().Fibre();
00315
00316 fibreLength[0] = fibre_length->x();
00317 }
00318
00319
00320 double HeartConfig::GetInterNodeSpace() const
00321 {
00322 assert(GetCreateMesh());
00323
00324 switch(GetSpaceDimension())
00325 {
00326 case 3:
00327 return DecideLocation( & mpUserParameters->Simulation().Mesh(),
00328 & mpDefaultParameters->Simulation().Mesh(),
00329 "Slab")->get().Slab()->inter_node_space();
00330 break;
00331 case 2:
00332 return DecideLocation( & mpUserParameters->Simulation().Mesh(),
00333 & mpDefaultParameters->Simulation().Mesh(),
00334 "Sheet")->get().Sheet()->inter_node_space();
00335 break;
00336 case 1:
00337 return DecideLocation( & mpUserParameters->Simulation().Mesh(),
00338 & mpDefaultParameters->Simulation().Mesh(),
00339 "Fibre")->get().Fibre()->inter_node_space();
00340 break;
00341 default:
00342 NEVER_REACHED;
00343 }
00344
00345
00346 }
00347
00348 std::string HeartConfig::GetMeshName() const
00349 {
00350 assert(GetLoadMesh());
00351
00352 return DecideLocation( & mpUserParameters->Simulation().Mesh(),
00353 & mpDefaultParameters->Simulation().Mesh(),
00354 "LoadMesh")->get().LoadMesh()->name();
00355 }
00356
00357 media_type HeartConfig::GetConductivityMedia() const
00358 {
00359 assert(GetLoadMesh());
00360
00361 return DecideLocation( & mpUserParameters->Simulation().Mesh(),
00362 & mpDefaultParameters->Simulation().Mesh(),
00363 "LoadMesh")->get().LoadMesh()->conductivity_media();
00364 }
00365
00366 void HeartConfig::GetStimuli(std::vector<SimpleStimulus>& stimuliApplied, std::vector<ChasteCuboid>& stimulatedAreas) const
00367 {
00368
00369 simulation_type::Stimuli::_xsd_Stimuli_::Stimuli::Stimulus::container&
00370 stimuli = DecideLocation( & mpUserParameters->Simulation().Stimuli(),
00371 & mpDefaultParameters->Simulation().Stimuli(),
00372 "Stimuli")->get().Stimulus();
00373 for (simulation_type::Stimuli::_xsd_Stimuli_::Stimuli::Stimulus::iterator i = stimuli.begin();
00374 i != stimuli.end();
00375 ++i)
00376 {
00377 stimulus_type stimulus(*i);
00378 point_type point_a = stimulus.Location().Cuboid().LowerCoordinates();
00379 point_type point_b = stimulus.Location().Cuboid().UpperCoordinates();
00380
00381 ChastePoint<3> chaste_point_a ( point_a.x(),
00382 point_a.y(),
00383 point_a.z());
00384
00385 ChastePoint<3> chaste_point_b ( point_b.x(),
00386 point_b.y(),
00387 point_b.z());
00388
00389 stimuliApplied.push_back( SimpleStimulus(stimulus.Strength(), stimulus.Duration(), stimulus.Delay() ) );
00390 stimulatedAreas.push_back( ChasteCuboid( chaste_point_a, chaste_point_b ) );
00391 }
00392 }
00393
00394 void HeartConfig::GetCellHeterogeneities(std::vector<ChasteCuboid>& cellHeterogeneityAreas,
00395 std::vector<double>& scaleFactorGks,
00396 std::vector<double>& scaleFactorIto,
00397 std::vector<double>& scaleFactorGkr) const
00398 {
00399 simulation_type::CellHeterogeneities::_xsd_CellHeterogeneities_::CellHeterogeneities::CellHeterogeneity::container&
00400 cell_heterogeneity = DecideLocation( & mpUserParameters->Simulation().CellHeterogeneities(),
00401 & mpDefaultParameters->Simulation().CellHeterogeneities(),
00402 "CellHeterogeneities")->get().CellHeterogeneity();
00403
00404 for (simulation_type::CellHeterogeneities::_xsd_CellHeterogeneities_::CellHeterogeneities::CellHeterogeneity::iterator i = cell_heterogeneity.begin();
00405 i != cell_heterogeneity.end();
00406 ++i)
00407 {
00408 cell_heterogeneity_type ht(*i);
00409 point_type point_a = ht.Location().Cuboid().LowerCoordinates();
00410 point_type point_b = ht.Location().Cuboid().UpperCoordinates();
00411
00412 ChastePoint<3> chaste_point_a (point_a.x(),
00413 point_a.y(),
00414 point_a.z());
00415
00416 ChastePoint<3> chaste_point_b (point_b.x(),
00417 point_b.y(),
00418 point_b.z());
00419
00420 scaleFactorGks.push_back (ht.ScaleFactorGks());
00421 scaleFactorIto.push_back (ht.ScaleFactorIto());
00422 scaleFactorGkr.push_back (ht.ScaleFactorGkr());
00423 cellHeterogeneityAreas.push_back( ChasteCuboid( chaste_point_a, chaste_point_b ) );
00424 }
00425 }
00426
00427 bool HeartConfig::GetConductivityHeterogeneitiesProvided() const
00428 {
00429 try
00430 {
00431 DecideLocation( & mpUserParameters->Simulation().ConductivityHeterogeneities(),
00432 & mpDefaultParameters->Simulation().ConductivityHeterogeneities(),
00433 "CellHeterogeneities");
00434 return true;
00435 }
00436 catch (Exception& e)
00437 {
00438 return false;
00439 }
00440 }
00441
00442 void HeartConfig::GetConductivityHeterogeneities(std::vector<ChasteCuboid>& conductivitiesHeterogeneityAreas,
00443 std::vector< c_vector<double,3> >& intraConductivities,
00444 std::vector< c_vector<double,3> >& extraConductivities) const
00445 {
00446 simulation_type::ConductivityHeterogeneities::_xsd_ConductivityHeterogeneities_::ConductivityHeterogeneities::ConductivityHeterogeneity::container&
00447 conductivity_heterogeneity = DecideLocation( & mpUserParameters->Simulation().ConductivityHeterogeneities(),
00448 & mpDefaultParameters->Simulation().ConductivityHeterogeneities(),
00449 "CellHeterogeneities")->get().ConductivityHeterogeneity();
00450
00451 for (simulation_type::ConductivityHeterogeneities::_xsd_ConductivityHeterogeneities_::ConductivityHeterogeneities::ConductivityHeterogeneity::iterator i = conductivity_heterogeneity.begin();
00452 i != conductivity_heterogeneity.end();
00453 ++i)
00454 {
00455 conductivity_heterogeneity_type ht(*i);
00456 point_type point_a = ht.Location().Cuboid().LowerCoordinates();
00457 point_type point_b = ht.Location().Cuboid().UpperCoordinates();
00458
00459 ChastePoint<3> chaste_point_a (point_a.x(),
00460 point_a.y(),
00461 point_a.z());
00462
00463 ChastePoint<3> chaste_point_b (point_b.x(),
00464 point_b.y(),
00465 point_b.z());
00466
00467 conductivitiesHeterogeneityAreas.push_back( ChasteCuboid( chaste_point_a, chaste_point_b ) );
00468
00469 if (ht.IntracellularConductivities().present())
00470 {
00471 double intra_x = ht.IntracellularConductivities().get().longi();
00472 double intra_y = ht.IntracellularConductivities().get().trans();
00473 double intra_z = ht.IntracellularConductivities().get().normal();
00474
00475 intraConductivities.push_back( Create_c_vector(intra_x, intra_y, intra_z) );
00476 }
00477 else
00478 {
00479 c_vector<double, 3> intra_conductivities;
00480 GetIntracellularConductivities(intra_conductivities);
00481 intraConductivities.push_back(intra_conductivities);
00482 }
00483
00484 if (ht.ExtracellularConductivities().present())
00485 {
00486 double extra_x = ht.ExtracellularConductivities().get().longi();
00487 double extra_y = ht.ExtracellularConductivities().get().trans();
00488 double extra_z = ht.ExtracellularConductivities().get().normal();
00489
00490 extraConductivities.push_back( Create_c_vector(extra_x, extra_y, extra_z) );
00491 }
00492 else
00493 {
00494 c_vector<double, 3> extra_conductivities;
00495 GetExtracellularConductivities(extra_conductivities);
00496 extraConductivities.push_back(extra_conductivities);
00497 }
00498
00499 }
00500 }
00501
00502 std::string HeartConfig::GetOutputDirectory() const
00503 {
00504 return DecideLocation( & mpUserParameters->Simulation().OutputDirectory(),
00505 & mpDefaultParameters->Simulation().OutputDirectory(),
00506 "OutputDirectory")->get();
00507 }
00508
00509 std::string HeartConfig::GetOutputFilenamePrefix() const
00510 {
00511 return DecideLocation( & mpUserParameters->Simulation().OutputFilenamePrefix(),
00512 & mpDefaultParameters->Simulation().OutputFilenamePrefix(),
00513 "OutputFilenamePrefix")->get();
00514 }
00515
00516 void HeartConfig::GetIntracellularConductivities(c_vector<double, 3>& intraConductivities) const
00517 {
00518 optional<conductivities_type, false>* intra_conductivities = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
00519 & mpDefaultParameters->Physiological().IntracellularConductivities(),
00520 "IntracellularConductivities");
00521 double intra_x_cond = intra_conductivities->get().longi();
00522 double intra_y_cond = intra_conductivities->get().trans();
00523 double intra_z_cond = intra_conductivities->get().normal();;
00524
00525 assert(intra_y_cond != DBL_MAX);
00526 assert(intra_z_cond != DBL_MAX);
00527
00528 intraConductivities[0] = intra_x_cond;
00529 intraConductivities[1] = intra_y_cond;
00530 intraConductivities[2] = intra_z_cond;
00531 }
00532
00533 void HeartConfig::GetIntracellularConductivities(c_vector<double, 2>& intraConductivities) const
00534 {
00535 optional<conductivities_type, false>* intra_conductivities = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
00536 & mpDefaultParameters->Physiological().IntracellularConductivities(),
00537 "IntracellularConductivities");
00538 double intra_x_cond = intra_conductivities->get().longi();
00539 double intra_y_cond = intra_conductivities->get().trans();
00540
00541 assert(intra_y_cond != DBL_MAX);
00542
00543 intraConductivities[0] = intra_x_cond;
00544 intraConductivities[1] = intra_y_cond;
00545 }
00546
00547 void HeartConfig::GetIntracellularConductivities(c_vector<double, 1>& intraConductivities) const
00548 {
00549 optional<conductivities_type, false>* intra_conductivities = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
00550 & mpDefaultParameters->Physiological().IntracellularConductivities(),
00551 "IntracellularConductivities");
00552 double intra_x_cond = intra_conductivities->get().longi();
00553
00554 intraConductivities[0] = intra_x_cond;
00555 }
00556
00557 void HeartConfig::GetExtracellularConductivities(c_vector<double, 3>& extraConductivities) const
00558 {
00559 optional<conductivities_type, false>* extra_conductivities = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
00560 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
00561 "ExtracellularConductivities");
00562 double extra_x_cond = extra_conductivities->get().longi();
00563 double extra_y_cond = extra_conductivities->get().trans();
00564 double extra_z_cond = extra_conductivities->get().normal();;
00565
00566 assert(extra_y_cond != DBL_MAX);
00567 assert(extra_z_cond != DBL_MAX);
00568
00569 extraConductivities[0] = extra_x_cond;
00570 extraConductivities[1] = extra_y_cond;
00571 extraConductivities[2] = extra_z_cond;
00572 }
00573
00574 void HeartConfig::GetExtracellularConductivities(c_vector<double, 2>& extraConductivities) const
00575 {
00576 optional<conductivities_type, false>* extra_conductivities = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
00577 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
00578 "ExtracellularConductivities");
00579 double extra_x_cond = extra_conductivities->get().longi();
00580 double extra_y_cond = extra_conductivities->get().trans();
00581
00582 assert(extra_y_cond != DBL_MAX);
00583
00584 extraConductivities[0] = extra_x_cond;
00585 extraConductivities[1] = extra_y_cond;
00586 }
00587
00588 void HeartConfig::GetExtracellularConductivities(c_vector<double, 1>& extraConductivities) const
00589 {
00590 optional<conductivities_type, false>* extra_conductivities = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
00591 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
00592 "ExtracellularConductivities");
00593 double extra_x_cond = extra_conductivities->get().longi();
00594
00595 extraConductivities[0] = extra_x_cond;
00596 }
00597
00598 double HeartConfig::GetBathConductivity() const
00599 {
00600
00601 return DecideLocation( & mpUserParameters->Physiological().BathConductivity(),
00602 & mpDefaultParameters->Physiological().BathConductivity(),
00603 "BathConductivity")->get();
00604 }
00605
00606 double HeartConfig::GetSurfaceAreaToVolumeRatio() const
00607 {
00608
00609 return DecideLocation( & mpUserParameters->Physiological().SurfaceAreaToVolumeRatio(),
00610 & mpDefaultParameters->Physiological().SurfaceAreaToVolumeRatio(),
00611 "SurfaceAreaToVolumeRatio")->get();
00612 }
00613
00614 double HeartConfig::GetCapacitance() const
00615 {
00616
00617 return DecideLocation( & mpUserParameters->Physiological().Capacitance(),
00618 & mpDefaultParameters->Physiological().Capacitance(),
00619 "Capacitance")->get();
00620 }
00621
00622 double HeartConfig::GetOdeTimeStep() const
00623 {
00624 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
00625 & mpDefaultParameters->Numerical().TimeSteps(),
00626 "ode TimeStep")->get().ode();
00627 }
00628
00629 double HeartConfig::GetPdeTimeStep() const
00630 {
00631 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
00632 & mpDefaultParameters->Numerical().TimeSteps(),
00633 "pde TimeStep")->get().pde();
00634 }
00635
00636 double HeartConfig::GetPrintingTimeStep() const
00637 {
00638 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
00639 & mpDefaultParameters->Numerical().TimeSteps(),
00640 "printing TimeStep")->get().printing();
00641 }
00642
00643 bool HeartConfig::GetUseAbsoluteTolerance() const
00644 {
00645
00646
00647
00648
00649 if (mpUserParameters->Numerical().KSPTolerances().get().KSPRelative().present() )
00650 {
00651 return false;
00652 }
00653
00654 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
00655 & mpDefaultParameters->Numerical().KSPTolerances(),
00656 "KSPTolerances")->get().KSPAbsolute().present();
00657 }
00658
00659 double HeartConfig::GetAbsoluteTolerance() const
00660 {
00661 if (!GetUseAbsoluteTolerance())
00662 {
00663 EXCEPTION("Absolute tolerance is not set in Chaste parameters");
00664 }
00665 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
00666 & mpDefaultParameters->Numerical().KSPTolerances(),
00667 "KSPTolerances")->get().KSPAbsolute().get();
00668 }
00669
00670 bool HeartConfig::GetUseRelativeTolerance() const
00671 {
00672
00673
00674
00675
00676
00677
00678 if (mpUserParameters->Numerical().KSPTolerances().get().KSPAbsolute().present() )
00679 {
00680 return false;
00681 }
00682 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
00683 & mpDefaultParameters->Numerical().KSPTolerances(),
00684 "KSPTolerances")->get().KSPRelative().present();
00685 }
00686
00687 double HeartConfig::GetRelativeTolerance() const
00688 {
00689 if (!GetUseRelativeTolerance())
00690 {
00691 EXCEPTION("Relative tolerance is not set in Chaste parameters");
00692 }
00693
00694 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
00695 & mpDefaultParameters->Numerical().KSPTolerances(),
00696 "KSPTolerances")->get().KSPRelative().get();
00697 }
00698
00699 const char* HeartConfig::GetKSPSolver() const
00700 {
00701 switch ( DecideLocation( & mpUserParameters->Numerical().KSPSolver(),
00702 & mpDefaultParameters->Numerical().KSPSolver(),
00703 "KSPSolver")->get() )
00704 {
00705 case ksp_solver_type::gmres :
00706 return "gmres";
00707 case ksp_solver_type::cg :
00708 return "cg";
00709 case ksp_solver_type::symmlq :
00710 return "symmlq";
00711 }
00712 #define COVERAGE_IGNORE
00713 EXCEPTION("Unknown ksp solver");
00714 #undef COVERAGE_IGNORE
00715 }
00716
00717 const char* HeartConfig::GetKSPPreconditioner() const
00718 {
00719 switch ( DecideLocation( & mpUserParameters->Numerical().KSPPreconditioner(),
00720 & mpDefaultParameters->Numerical().KSPPreconditioner(),
00721 "KSPPreconditioner")->get() )
00722 {
00723 case ksp_preconditioner_type::ilu :
00724 return "ilu";
00725 case ksp_preconditioner_type::jacobi :
00726 return "jacobi";
00727 case ksp_preconditioner_type::bjacobi :
00728 return "bjacobi";
00729 case ksp_preconditioner_type::hypre :
00730 return "hypre";
00731 case ksp_preconditioner_type::none :
00732 return "none";
00733
00734 }
00735 #define COVERAGE_IGNORE
00736 EXCEPTION("Unknown ksp preconditioner");
00737 #undef COVERAGE_IGNORE
00738 }
00739
00740
00741
00742
00743
00744 void HeartConfig::SetSpaceDimension(unsigned spaceDimension)
00745 {
00746 mpUserParameters->Simulation().SpaceDimension().set(spaceDimension);
00747 }
00748
00749 void HeartConfig::SetSimulationDuration(double simulationDuration)
00750 {
00751 time_type time(simulationDuration, "ms");
00752 mpUserParameters->Simulation().SimulationDuration().set(time);
00753 }
00754
00755 void HeartConfig::SetDomain(domain_type domain)
00756 {
00757 mpUserParameters->Simulation().Domain().set(domain);
00758 }
00759
00760 void HeartConfig::SetDefaultIonicModel(ionic_models_available_type ionicModel)
00761 {
00762 mpUserParameters->Simulation().IonicModels().set(ionicModel);
00763 }
00764
00765 void HeartConfig::SetSlabDimensions(double x, double y, double z, double inter_node_space)
00766 {
00767 if ( ! mpUserParameters->Simulation().Mesh().present())
00768 {
00769 mesh_type mesh_to_load("cm");
00770 mpUserParameters->Simulation().Mesh().set(mesh_to_load);
00771 }
00772
00773 slab_type slab_definition(x, y, z, inter_node_space);
00774 mpUserParameters->Simulation().Mesh().get().Slab().set(slab_definition);
00775 }
00776
00777 void HeartConfig::SetSheetDimensions(double x, double y, double inter_node_space)
00778 {
00779 if ( ! mpUserParameters->Simulation().Mesh().present())
00780 {
00781 mesh_type mesh_to_load("cm");
00782 mpUserParameters->Simulation().Mesh().set(mesh_to_load);
00783 }
00784
00785 sheet_type sheet_definition(x, y, inter_node_space);
00786 mpUserParameters->Simulation().Mesh().get().Sheet().set(sheet_definition);
00787 }
00788
00789 void HeartConfig::SetFibreLength(double x, double inter_node_space)
00790 {
00791 if ( ! mpUserParameters->Simulation().Mesh().present())
00792 {
00793 mesh_type mesh_to_load("cm");
00794 mpUserParameters->Simulation().Mesh().set(mesh_to_load);
00795 }
00796
00797 fibre_type fibre_definition(x, inter_node_space);
00798 mpUserParameters->Simulation().Mesh().get().Fibre().set(fibre_definition);
00799 }
00800
00801 void HeartConfig::SetMeshFileName(std::string meshPrefix, media_type fibreDefinition)
00802 {
00803 if ( ! mpUserParameters->Simulation().Mesh().present())
00804 {
00805 mesh_type mesh_to_load("cm");
00806 mpUserParameters->Simulation().Mesh().set(mesh_to_load);
00807 }
00808
00809 mesh_type::LoadMesh::type mesh_prefix(meshPrefix, fibreDefinition);
00810 mpUserParameters->Simulation().Mesh().get().LoadMesh().set(mesh_prefix);
00811 }
00812
00813 void HeartConfig::SetConductivityHeterogeneities(std::vector< c_vector<double,3> >& cornerA,
00814 std::vector< c_vector<double,3> >& cornerB,
00815 std::vector< c_vector<double,3> >& intraConductivities,
00816 std::vector< c_vector<double,3> >& extraConductivities)
00817 {
00818 assert ( cornerA.size() == cornerB.size() );
00819 assert ( cornerB.size() == intraConductivities.size() );
00820 assert ( intraConductivities.size() == extraConductivities.size());
00821
00822 simulation_type::ConductivityHeterogeneities::_xsd_ConductivityHeterogeneities_::ConductivityHeterogeneities::ConductivityHeterogeneity::container heterogeneities_container;
00823
00824 for (unsigned region_index=0; region_index<cornerA.size(); region_index++)
00825 {
00826 point_type point_a(cornerA[region_index][0],
00827 cornerA[region_index][1],
00828 cornerA[region_index][2]);
00829
00830 point_type point_b(cornerB[region_index][0],
00831 cornerB[region_index][1],
00832 cornerB[region_index][2]);
00833
00834 conductivity_heterogeneity_type ht(location_type(box_type(point_a, point_b), "cm"));
00835
00836 conductivities_type intra(intraConductivities[region_index][0],
00837 intraConductivities[region_index][1],
00838 intraConductivities[region_index][2],
00839 "mS/cm");
00840
00841 ht.IntracellularConductivities(intra);
00842
00843 conductivities_type extra(extraConductivities[region_index][0],
00844 extraConductivities[region_index][1],
00845 extraConductivities[region_index][2],
00846 "mS/cm");
00847
00848 ht.ExtracellularConductivities(extra);
00849
00850 heterogeneities_container.push_back(ht);
00851 }
00852
00853 simulation_type::ConductivityHeterogeneities::_xsd_ConductivityHeterogeneities_::ConductivityHeterogeneities heterogeneities_object;
00854 heterogeneities_object.ConductivityHeterogeneity(heterogeneities_container);
00855
00856 mpUserParameters->Simulation().ConductivityHeterogeneities().set(heterogeneities_object);
00857 }
00858
00859
00860 void HeartConfig::SetOutputDirectory(std::string outputDirectory)
00861 {
00862 mpUserParameters->Simulation().OutputDirectory().set(outputDirectory);
00863 }
00864
00865 void HeartConfig::SetOutputFilenamePrefix(std::string outputFilenamePrefix)
00866 {
00867 mpUserParameters->Simulation().OutputFilenamePrefix().set(outputFilenamePrefix);
00868 }
00869
00870
00871
00872 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 3>& intraConductivities)
00873 {
00874 conductivities_type intra(intraConductivities[0],
00875 intraConductivities[1],
00876 intraConductivities[2],
00877 "mS/cm");
00878
00879 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
00880 }
00881
00882 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 2>& intraConductivities)
00883 {
00884 conductivities_type intra(intraConductivities[0],
00885 intraConductivities[1],
00886 DBL_MAX,
00887 "mS/cm");
00888
00889 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
00890 }
00891
00892 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 1>& intraConductivities)
00893 {
00894 conductivities_type intra(intraConductivities[0],
00895 DBL_MAX,
00896 DBL_MAX,
00897 "mS/cm");
00898
00899 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
00900 }
00901
00902 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 3>& extraConductivities)
00903 {
00904 conductivities_type extra(extraConductivities[0],
00905 extraConductivities[1],
00906 extraConductivities[2],
00907 "mS/cm");
00908
00909 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
00910 }
00911
00912 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 2>& extraConductivities)
00913 {
00914 conductivities_type extra(extraConductivities[0],
00915 extraConductivities[1],
00916 DBL_MAX,
00917 "mS/cm");
00918
00919 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
00920 }
00921
00922 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 1>& extraConductivities)
00923 {
00924 conductivities_type extra(extraConductivities[0],
00925 DBL_MAX,
00926 DBL_MAX,
00927 "mS/cm");
00928
00929 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
00930 }
00931
00932 void HeartConfig::SetBathConductivity(double bathConductivity)
00933 {
00934 conductivity_type cond(bathConductivity, "mS/cm");
00935 mpUserParameters->Physiological().BathConductivity().set(cond);
00936 }
00937
00938 void HeartConfig::SetSurfaceAreaToVolumeRatio(double ratio)
00939 {
00940 inverse_length_type ratio_object(ratio, "1/cm");
00941 mpUserParameters->Physiological().SurfaceAreaToVolumeRatio().set(ratio_object);
00942 }
00943
00944 void HeartConfig::SetCapacitance(double capacitance)
00945 {
00946 capacitance_type capacitance_object(capacitance, "uF/cm^2");
00947 mpUserParameters->Physiological().Capacitance().set(capacitance_object);
00948 }
00949
00950
00951
00952 void HeartConfig::SetOdePdeAndPrintingTimeSteps(double odeTimeStep, double pdeTimeStep, double printingTimeStep)
00953 {
00954 time_steps_type TimeSteps(odeTimeStep, pdeTimeStep, printingTimeStep, "ms");
00955 mpUserParameters->Numerical().TimeSteps().set(TimeSteps);
00956 CheckTimeSteps();
00957 }
00958
00959 void HeartConfig::SetOdeTimeStep(double odeTimeStep)
00960 {
00961 SetOdePdeAndPrintingTimeSteps(odeTimeStep, GetPdeTimeStep(), GetPrintingTimeStep());
00962 }
00963
00964 void HeartConfig::SetPdeTimeStep(double pdeTimeStep)
00965 {
00966 SetOdePdeAndPrintingTimeSteps(GetOdeTimeStep(), pdeTimeStep, GetPrintingTimeStep());
00967 }
00968
00969 void HeartConfig::SetPrintingTimeStep(double printingTimeStep)
00970 {
00971 SetOdePdeAndPrintingTimeSteps(GetOdeTimeStep(), GetPdeTimeStep(), printingTimeStep);
00972 }
00973
00974 void HeartConfig::CheckTimeSteps() const
00975 {
00976 if (GetOdeTimeStep() <= 0)
00977 {
00978 EXCEPTION("Ode time-step should be positive");
00979 }
00980 if (GetPdeTimeStep() <= 0)
00981 {
00982 EXCEPTION("Pde time-step should be positive");
00983 }
00984 if (GetPrintingTimeStep() <= 0.0)
00985 {
00986 EXCEPTION("Printing time-step should be positive");
00987 }
00988 if (GetPdeTimeStep()>GetPrintingTimeStep())
00989 {
00990 EXCEPTION("Printing time-step should not be smaller than PDE time step");
00991 }
00992
00993
00994
00995 double remainder=fmod(GetPrintingTimeStep(), GetPdeTimeStep());
00996
00997 if ( remainder > DBL_EPSILON && remainder < GetPdeTimeStep()-DBL_EPSILON)
00998 {
00999 EXCEPTION("Printing time-step should a multiple of PDE time step");
01000 }
01001
01002 if ( GetOdeTimeStep() > GetPdeTimeStep() )
01003 {
01004 EXCEPTION("Ode time-step should not be greater than pde time-step");
01005 }
01006 }
01007
01008
01009 void HeartConfig::SetUseRelativeTolerance(double relativeTolerance)
01010 {
01011
01012 mpUserParameters->Numerical().KSPTolerances().get().KSPAbsolute().reset();
01013 mpUserParameters->Numerical().KSPTolerances().get().KSPRelative().set(relativeTolerance);
01014 }
01015
01016 void HeartConfig::SetUseAbsoluteTolerance(double absoluteTolerance)
01017 {
01018
01019 mpUserParameters->Numerical().KSPTolerances().get().KSPRelative().reset();
01020 mpUserParameters->Numerical().KSPTolerances().get().KSPAbsolute().set(absoluteTolerance);
01021 }
01022
01023 void HeartConfig::SetKSPSolver(const char* kspSolver)
01024 {
01025 if ( strcmp(kspSolver, "gmres") == 0)
01026 {
01027 mpUserParameters->Numerical().KSPSolver().set(ksp_solver_type::gmres);
01028 return;
01029 }
01030 if ( strcmp(kspSolver, "cg") == 0)
01031 {
01032 mpUserParameters->Numerical().KSPSolver().set(ksp_solver_type::cg);
01033 return;
01034 }
01035 if ( strcmp(kspSolver, "symmlq") == 0)
01036 {
01037 mpUserParameters->Numerical().KSPSolver().set(ksp_solver_type::symmlq);
01038 return;
01039 }
01040
01041 EXCEPTION("Unknown solver type provided");
01042 }
01043
01044 void HeartConfig::SetKSPPreconditioner(const char* kspPreconditioner)
01045 {
01046 if ( strcmp(kspPreconditioner, "ilu") == 0)
01047 {
01048 mpUserParameters->Numerical().KSPPreconditioner().set(ksp_preconditioner_type::ilu);
01049 return;
01050 }
01051 if ( strcmp(kspPreconditioner, "jacobi") == 0)
01052 {
01053 mpUserParameters->Numerical().KSPPreconditioner().set(ksp_preconditioner_type::jacobi);
01054 return;
01055 }
01056 if ( strcmp(kspPreconditioner, "bjacobi") == 0)
01057 {
01058 mpUserParameters->Numerical().KSPPreconditioner().set(ksp_preconditioner_type::bjacobi);
01059 return;
01060 }
01061 if ( strcmp(kspPreconditioner, "hypre") == 0)
01062 {
01063 mpUserParameters->Numerical().KSPPreconditioner().set(ksp_preconditioner_type::hypre);
01064 return;
01065 }
01066 if ( strcmp(kspPreconditioner, "none") == 0)
01067 {
01068 mpUserParameters->Numerical().KSPPreconditioner().set(ksp_preconditioner_type::none);
01069 return;
01070 }
01071
01072 EXCEPTION("Unknown preconditioner type provided");
01073 }