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