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 "CheckpointArchiveTypesIfNeeded.hpp"
00031
00032 #include "UblasCustomFunctions.hpp"
00033
00034 #include "HeartConfig.hpp"
00035 #include "OutputFileHandler.hpp"
00036 #include "Exception.hpp"
00037 #include "ChastePoint.hpp"
00038 #include "Version.hpp"
00039 #include "AbstractChasteRegion.hpp"
00040
00041 #include <cassert>
00042
00043 #include <xercesc/util/PlatformUtils.hpp>
00044 #include <xercesc/util/QName.hpp>
00045 #include <xsd/cxx/tree/error-handler.hxx>
00046
00047
00048 #if (XSD_INT_VERSION >= 3000000L)
00049 #define XSD_SEQUENCE_TYPE(base) base##_sequence
00050 #define XSD_ITERATOR_TYPE(base) base##_iterator
00051 #define XSD_NESTED_TYPE(t) t##_type
00052 #define XSD_ANON_TYPE(t1, t2) \
00053 t1::t2##_type
00054 #else
00055 #define XSD_SEQUENCE_TYPE(base) base::container
00056 #define XSD_ITERATOR_TYPE(base) base::iterator
00057 #define XSD_NESTED_TYPE(t) t::type
00058 #define XSD_ANON_TYPE(t1, t2) \
00059 t1::t2::_xsd_##t2##_::t2
00060 #endif
00061
00062
00063 #define XSD_ANON_SEQUENCE_TYPE(t1, t2, t3) \
00064 XSD_SEQUENCE_TYPE(XSD_ANON_TYPE(t1, t2)::t3)
00065 #define XSD_ANON_ITERATOR_TYPE(t1, t2, t3) \
00066 XSD_ITERATOR_TYPE(XSD_ANON_TYPE(t1, t2)::t3)
00067
00068
00069 #if (XSD_INT_VERSION >= 3020000L)
00070 #define XSD_CREATE_WITH_FIXED_ATTR(type, name, attr) \
00071 type name
00072 #define XSD_CREATE_WITH_FIXED_ATTR1(type, name, arg1, attr) \
00073 type name(arg1)
00074 #define XSD_CREATE_WITH_FIXED_ATTR2(type, name, arg1, arg2, attr) \
00075 type name(arg1, arg2)
00076 #define XSD_CREATE_WITH_FIXED_ATTR3(type, name, arg1, arg2, arg3, attr) \
00077 type name(arg1, arg2, arg3)
00078 #else
00079 #define XSD_CREATE_WITH_FIXED_ATTR(type, name, attr) \
00080 type name(attr)
00081 #define XSD_CREATE_WITH_FIXED_ATTR1(type, name, arg1, attr) \
00082 type name(arg1, attr)
00083 #define XSD_CREATE_WITH_FIXED_ATTR2(type, name, arg1, arg2, attr) \
00084 type name(arg1, arg2, attr)
00085 #define XSD_CREATE_WITH_FIXED_ATTR3(type, name, arg1, arg2, arg3, attr) \
00086 type name(arg1, arg2, arg3, attr)
00087 #endif
00088
00089 using namespace xsd::cxx::tree;
00090
00091
00092
00093
00094 std::auto_ptr<HeartConfig> HeartConfig::mpInstance;
00095
00096
00097
00098
00099
00100 HeartConfig* HeartConfig::Instance()
00101 {
00102 if (mpInstance.get() == NULL)
00103 {
00104 mpInstance.reset(new HeartConfig);
00105 }
00106 return mpInstance.get();
00107 }
00108
00109 HeartConfig::HeartConfig()
00110 {
00111 assert(mpInstance.get() == NULL);
00112 mUseFixedSchemaLocation = true;
00113 SetDefaultSchemaLocations();
00114
00115 SetDefaultsFile("ChasteDefaults.xml");
00116
00117 mpUserParameters = mpDefaultParameters;
00118
00119
00120
00121 mEpiFraction = -1.0;
00122 mEndoFraction = -1.0;
00123 mMidFraction = -1.0;
00124 mUserAskedForCellularTransmuralHeterogeneities=false;
00125 mUserAskedForCuboidsForCellularHeterogeneities=false;
00126
00127
00128
00129 mIndexMid = UINT_MAX-3u;
00130 mIndexEpi = UINT_MAX-3u;
00131 mIndexEndo = UINT_MAX-3u;
00132 }
00133
00134 HeartConfig::~HeartConfig()
00135 {
00136 }
00137
00138 void HeartConfig::SetDefaultsFile(const std::string& rFileName)
00139 {
00140 bool same_target = (mpUserParameters == mpDefaultParameters);
00141
00142 mpDefaultParameters = ReadFile(rFileName);
00143
00144 if (same_target)
00145 {
00146 mpUserParameters = mpDefaultParameters;
00147 }
00148 CheckTimeSteps();
00149 }
00150
00151 void HeartConfig::Write(bool useArchiveLocationInfo, std::string subfolderName)
00152 {
00153
00154 std::string output_dirname;
00155 if (useArchiveLocationInfo)
00156 {
00157 output_dirname = ArchiveLocationInfo::GetArchiveDirectory();
00158 }
00159 else
00160 {
00161 OutputFileHandler handler(GetOutputDirectory(), false);
00162 output_dirname = handler.GetOutputDirectoryFullPath() + subfolderName + "/";
00163 }
00164 if (!PetscTools::AmMaster())
00165 {
00166
00167 return;
00168 }
00169 out_stream p_defaults_file( new std::ofstream( (output_dirname+"ChasteDefaults.xml").c_str() ) );
00170 out_stream p_parameters_file( new std::ofstream( (output_dirname+"ChasteParameters.xml").c_str() ) );
00171
00172 if (!p_defaults_file->is_open() || !p_parameters_file->is_open())
00173 {
00174 EXCEPTION("Could not open XML file in HeartConfig");
00175 }
00176
00177
00178
00179 ::xml_schema::namespace_infomap map;
00180 std::string absolute_path_to_xsd = EscapeSpaces(ChasteBuildInfo::GetRootDir());
00181 absolute_path_to_xsd += "/heart/src/io/";
00182
00183 map[""].schema = absolute_path_to_xsd + "ChasteParameters_1_1.xsd";
00184
00185 map["cp20"].name = "https://chaste.comlab.ox.ac.uk/nss/parameters/2_0";
00186 map["cp20"].schema = absolute_path_to_xsd + "ChasteParameters_2_0.xsd";
00187
00188 cp::ChasteParameters(*p_parameters_file, *mpUserParameters, map);
00189 cp::ChasteParameters(*p_defaults_file, *mpDefaultParameters, map);
00190 }
00191
00192 void HeartConfig::SetDefaultSchemaLocations()
00193 {
00194 mSchemaLocations.clear();
00195
00196 std::string root_dir = std::string(ChasteBuildInfo::GetRootDir()) + "/heart/src/io/";
00197
00198 mSchemaLocations[""] = root_dir + "ChasteParameters_1_1.xsd";
00199
00200 mSchemaLocations["https://chaste.comlab.ox.ac.uk/nss/parameters/2_0"] = root_dir + "ChasteParameters_2_0.xsd";
00201 }
00202
00203 void HeartConfig::SetFixedSchemaLocations(const SchemaLocationsMap& rSchemaLocations)
00204 {
00205 mSchemaLocations = rSchemaLocations;
00206 SetUseFixedSchemaLocation(true);
00207 }
00208
00209 void HeartConfig::SetUseFixedSchemaLocation(bool useFixedSchemaLocation)
00210 {
00211 mUseFixedSchemaLocation = useFixedSchemaLocation;
00212 }
00213
00214 std::string HeartConfig::EscapeSpaces(const std::string& rPath)
00215 {
00216 std::string escaped_path;
00217 for (std::string::const_iterator it = rPath.begin(); it != rPath.end(); ++it)
00218 {
00219 if (*it == ' ')
00220 {
00221 escaped_path += "%20";
00222 }
00223 else
00224 {
00225 escaped_path += *it;
00226 }
00227 }
00228 return escaped_path;
00229 }
00230
00231 boost::shared_ptr<cp::chaste_parameters_type> HeartConfig::ReadFile(const std::string& rFileName)
00232 {
00233
00234 ::xml_schema::properties props;
00235 if (mUseFixedSchemaLocation)
00236 {
00237 for (SchemaLocationsMap::iterator it = mSchemaLocations.begin();
00238 it != mSchemaLocations.end();
00239 ++it)
00240 {
00241 if (it->first == "")
00242 {
00243 props.no_namespace_schema_location(EscapeSpaces(it->second));
00244 }
00245 else
00246 {
00247 props.schema_location(it->first, EscapeSpaces(it->second));
00248 }
00249 }
00250 }
00251
00252
00253
00254 try
00255 {
00256
00257 ::xsd::cxx::xml::auto_initializer init_fini(true, true);
00258
00259 ::xsd::cxx::tree::error_handler<char> error_handler;
00260
00261 xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument> p_doc = ReadFileToDomDocument(rFileName, error_handler, props);
00262
00263 error_handler.throw_if_failed< ::xsd::cxx::tree::parsing< char > >();
00264
00265 xercesc::DOMElement* p_root_elt = p_doc->getDocumentElement();
00266 std::string namespace_uri(xsd::cxx::xml::transcode<char>(p_root_elt->getNamespaceURI()));
00267 if (namespace_uri == "")
00268 {
00269
00270 AddNamespace(p_doc.get(), p_root_elt, "https://chaste.comlab.ox.ac.uk/nss/parameters/2_0");
00271
00272 TransformIonicModelDefinitions(p_doc.get(), p_root_elt);
00273 }
00274
00275 std::auto_ptr<cp::chaste_parameters_type> p_params(cp::ChasteParameters(*p_doc, ::xml_schema::flags::dont_initialize, props));
00276
00277 p_doc.reset();
00278
00279 return boost::shared_ptr<cp::chaste_parameters_type>(p_params);
00280 }
00281 catch (const xml_schema::parsing& e)
00282 {
00283
00284 mpUserParameters.reset();
00285 mpDefaultParameters.reset();
00286
00287 #if (XSD_INT_VERSION >= 3000000L)
00288 const xml_schema::diagnostics& diags = e.diagnostics();
00289 const xml_schema::error& first_error = diags[0];
00290 #else
00291 const xml_schema::errors& errors = e.errors();
00292 const xml_schema::error& first_error = errors[0];
00293 #endif
00294 if (first_error.line() == 0u)
00295 {
00296 std::cerr << first_error << std::endl;
00297 EXCEPTION("Missing file parsing configuration file: " + rFileName);
00298 }
00299 else
00300 {
00301 std::cerr << e << std::endl;
00302 EXCEPTION("XML parsing error in configuration file: " + rFileName);
00303 }
00304 }
00305 catch (const xml_schema::exception& e)
00306 {
00307 std::cerr << e << std::endl;
00308
00309 mpUserParameters.reset();
00310 mpDefaultParameters.reset();
00311 EXCEPTION("XML parsing error in configuration file: " + rFileName);
00312 }
00313 }
00314
00315 void HeartConfig::SetParametersFile(const std::string& rFileName)
00316 {
00317 mpUserParameters = ReadFile(rFileName);
00318
00319 CheckTimeSteps();
00320 }
00321
00322
00323 void HeartConfig::Reset()
00324 {
00325
00326 mpInstance.reset();
00327
00328 mpInstance.reset(new HeartConfig);
00329 }
00330
00331 bool HeartConfig::IsSimulationDefined() const
00332 {
00333 return mpUserParameters->Simulation().present();
00334 }
00335
00336 bool HeartConfig::IsSimulationResumed() const
00337 {
00338 return mpUserParameters->ResumeSimulation().present();
00339 }
00340
00341
00342 template<class TYPE>
00343 TYPE* HeartConfig::DecideLocation(TYPE* ptr1, TYPE* ptr2, const std::string& nameParameter) const
00344 {
00345 if (ptr1->present())
00346 {
00347 return ptr1;
00348 }
00349 if (ptr2->present())
00350 {
00351 return ptr2;
00352 }
00353 EXCEPTION("No " + nameParameter + " provided (neither default nor user defined)");
00354 }
00355
00356 void HeartConfig::CheckSimulationIsDefined(std::string callingMethod) const
00357 {
00358 if (IsSimulationResumed())
00359 {
00360 EXCEPTION(callingMethod + " information is not available in a resumed simulation.");
00361 }
00362 }
00363
00364 void HeartConfig::CheckResumeSimulationIsDefined(std::string callingMethod) const
00365 {
00366 if (IsSimulationDefined())
00367 {
00368 EXCEPTION(callingMethod + " information is not available in a standard (non-resumed) simulation.");
00369 }
00370 }
00371
00372 unsigned HeartConfig::GetSpaceDimension() const
00373 {
00374 if (IsSimulationDefined())
00375 {
00376 return DecideLocation( & mpUserParameters->Simulation().get().SpaceDimension(),
00377 & mpDefaultParameters->Simulation().get().SpaceDimension(),
00378 "SpaceDimension")->get();
00379 }
00380 else
00381 {
00382 return mpUserParameters->ResumeSimulation().get().SpaceDimension();
00383 }
00384 }
00385
00386 double HeartConfig::GetSimulationDuration() const
00387 {
00388 if (IsSimulationDefined())
00389 {
00390 return DecideLocation( & mpUserParameters->Simulation().get().SimulationDuration(),
00391 & mpDefaultParameters->Simulation().get().SimulationDuration(),
00392 "Simulation/SimulationDuration")->get();
00393 }
00394 else
00395 {
00396 return mpUserParameters->ResumeSimulation().get().SimulationDuration();
00397 }
00398 }
00399
00400 cp::domain_type HeartConfig::GetDomain() const
00401 {
00402 if (IsSimulationDefined())
00403 {
00404 return DecideLocation( & mpUserParameters->Simulation().get().Domain(),
00405 & mpDefaultParameters->Simulation().get().Domain(),
00406 "Domain")->get();
00407 }
00408 else
00409 {
00410 return mpUserParameters->ResumeSimulation().get().Domain();
00411 }
00412 }
00413
00414 cp::ionic_model_selection_type HeartConfig::GetDefaultIonicModel() const
00415 {
00416 CheckSimulationIsDefined("DefaultIonicModel");
00417
00418 return DecideLocation( & mpUserParameters->Simulation().get().IonicModels(),
00419 & mpDefaultParameters->Simulation().get().IonicModels(),
00420 "IonicModel")->get().Default();
00421 }
00422
00423 template<unsigned DIM>
00424 void HeartConfig::GetIonicModelRegions(std::vector<ChasteCuboid<DIM> >& definedRegions,
00425 std::vector<cp::ionic_model_selection_type>& ionicModels) const
00426 {
00427 CheckSimulationIsDefined("IonicModelRegions");
00428 definedRegions.clear();
00429 ionicModels.clear();
00430
00431 XSD_SEQUENCE_TYPE(cp::ionic_models_type::Region)&
00432 regions = DecideLocation( & mpUserParameters->Simulation().get().IonicModels(),
00433 & mpDefaultParameters->Simulation().get().IonicModels(),
00434 "IonicModel")->get().Region();
00435
00436 for (XSD_ITERATOR_TYPE(cp::ionic_models_type::Region) i = regions.begin();
00437 i != regions.end();
00438 ++i)
00439 {
00440 cp::ionic_model_region_type ionic_model_region(*i);
00441 if (ionic_model_region.Location().Cuboid().present())
00442 {
00443 cp::point_type point_a = ionic_model_region.Location().Cuboid()->LowerCoordinates();
00444 cp::point_type point_b = ionic_model_region.Location().Cuboid()->UpperCoordinates();
00445
00446 switch (DIM)
00447 {
00448 case 1:
00449 {
00450 ChastePoint<DIM> chaste_point_a ( point_a.x() );
00451 ChastePoint<DIM> chaste_point_b ( point_b.x() );
00452 definedRegions.push_back(ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ));
00453 break;
00454 }
00455 case 2:
00456 {
00457 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y() );
00458 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y() );
00459 definedRegions.push_back(ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ));
00460 break;
00461 }
00462 case 3:
00463 {
00464 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
00465 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
00466 definedRegions.push_back(ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ));
00467 break;
00468 }
00469 default:
00470 NEVER_REACHED;
00471 break;
00472 }
00473
00474 ionicModels.push_back(ionic_model_region.IonicModel());
00475 }
00476 else
00477 {
00478 if(ionic_model_region.Location().EpiLayer().present() || ionic_model_region.Location().MidLayer().present() || ionic_model_region.Location().EndoLayer().present() )
00479 {
00481 EXCEPTION("Definition of transmural layers is not yet supported for defining different ionic models, please use cuboids instead");
00482 }
00483 }
00484 }
00485 }
00486
00487
00488 bool HeartConfig::IsMeshProvided() const
00489 {
00490 CheckSimulationIsDefined("Mesh");
00491
00492 try
00493 {
00494 DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00495 & mpDefaultParameters->Simulation().get().Mesh(),
00496 "Mesh");
00497 return true;
00498 }
00499 catch (Exception& e)
00500 {
00501 return false;
00502 }
00503 }
00504
00505 bool HeartConfig::GetCreateMesh() const
00506 {
00507 CheckSimulationIsDefined("Mesh");
00508
00509 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00510 & mpDefaultParameters->Simulation().get().Mesh(),
00511 "Mesh")->get();
00512
00513 return (mesh.Slab().present() || mesh.Sheet().present() || mesh.Fibre().present());
00514 }
00515
00516 bool HeartConfig::GetCreateSlab() const
00517 {
00518 CheckSimulationIsDefined("Mesh");
00519
00520 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00521 & mpDefaultParameters->Simulation().get().Mesh(),
00522 "Mesh")->get();
00523
00524 return (mesh.Slab().present());
00525 }
00526
00527 bool HeartConfig::GetCreateSheet() const
00528 {
00529 CheckSimulationIsDefined("Mesh");
00530
00531 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00532 & mpDefaultParameters->Simulation().get().Mesh(),
00533 "Mesh")->get();
00534
00535 return (mesh.Sheet().present());
00536 }
00537
00538 bool HeartConfig::GetCreateFibre() const
00539 {
00540 CheckSimulationIsDefined("Mesh");
00541
00542 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00543 & mpDefaultParameters->Simulation().get().Mesh(),
00544 "Mesh")->get();
00545
00546 return (mesh.Fibre().present());
00547 }
00548
00549
00550 bool HeartConfig::GetLoadMesh() const
00551 {
00552 CheckSimulationIsDefined("Mesh");
00553
00554 return (DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00555 & mpDefaultParameters->Simulation().get().Mesh(),
00556 "Mesh")->get().LoadMesh().present());
00557 }
00558
00559 void HeartConfig::GetSlabDimensions(c_vector<double, 3>& slabDimensions) const
00560 {
00561 CheckSimulationIsDefined("Slab");
00562
00563 if (GetSpaceDimension()!=3 || !GetCreateSlab())
00564 {
00565 EXCEPTION("Tissue slabs can only be defined in 3D");
00566 }
00567
00568 optional<cp::slab_type, false> slab_dimensions = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00569 & mpDefaultParameters->Simulation().get().Mesh(),
00570 "Slab")->get().Slab();
00571
00572 slabDimensions[0] = slab_dimensions->x();
00573 slabDimensions[1] = slab_dimensions->y();
00574 slabDimensions[2] = slab_dimensions->z();
00575 }
00576
00577 void HeartConfig::GetSheetDimensions(c_vector<double, 2>& sheetDimensions) const
00578 {
00579 CheckSimulationIsDefined("Sheet");
00580
00581 if (GetSpaceDimension()!=2 || !GetCreateSheet())
00582 {
00583 EXCEPTION("Tissue sheets can only be defined in 2D");
00584 }
00585
00586 optional<cp::sheet_type, false> sheet_dimensions = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00587 & mpDefaultParameters->Simulation().get().Mesh(),
00588 "Sheet")->get().Sheet();
00589
00590 sheetDimensions[0] = sheet_dimensions->x();
00591 sheetDimensions[1] = sheet_dimensions->y();
00592 }
00593
00594 void HeartConfig::GetFibreLength(c_vector<double, 1>& fibreLength) const
00595 {
00596 CheckSimulationIsDefined("Fibre");
00597
00598 if (GetSpaceDimension()!=1 || !GetCreateFibre())
00599 {
00600 EXCEPTION("Tissue fibres can only be defined in 1D");
00601 }
00602
00603 optional<cp::fibre_type, false> fibre_length = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00604 & mpDefaultParameters->Simulation().get().Mesh(),
00605 "Fibre")->get().Fibre();
00606
00607 fibreLength[0] = fibre_length->x();
00608 }
00609
00610
00611 double HeartConfig::GetInterNodeSpace() const
00612 {
00613 CheckSimulationIsDefined("InterNodeSpace");
00614 assert(GetCreateMesh());
00615
00616 switch(GetSpaceDimension())
00617 {
00618 case 3:
00619 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00620 & mpDefaultParameters->Simulation().get().Mesh(),
00621 "Slab")->get().Slab()->inter_node_space();
00622 break;
00623 case 2:
00624 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00625 & mpDefaultParameters->Simulation().get().Mesh(),
00626 "Sheet")->get().Sheet()->inter_node_space();
00627 break;
00628 case 1:
00629 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00630 & mpDefaultParameters->Simulation().get().Mesh(),
00631 "Fibre")->get().Fibre()->inter_node_space();
00632 break;
00633 default:
00634 NEVER_REACHED;
00635 }
00636
00637
00638 }
00639
00640 std::string HeartConfig::GetMeshName() const
00641 {
00642 CheckSimulationIsDefined("LoadMesh");
00643 assert(GetLoadMesh());
00644
00645 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00646 & mpDefaultParameters->Simulation().get().Mesh(),
00647 "LoadMesh")->get().LoadMesh()->name();
00648 }
00649
00650 cp::media_type HeartConfig::GetConductivityMedia() const
00651 {
00652 CheckSimulationIsDefined("LoadMesh");
00653 assert(GetLoadMesh());
00654
00655 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00656 & mpDefaultParameters->Simulation().get().Mesh(),
00657 "LoadMesh")->get().LoadMesh()->conductivity_media();
00658 }
00659
00660 template <unsigned DIM>
00661 void HeartConfig::GetStimuli(std::vector<boost::shared_ptr<SimpleStimulus> >& rStimuliApplied,
00662 std::vector<ChasteCuboid<DIM> >& rStimulatedAreas) const
00663 {
00664 CheckSimulationIsDefined("Stimuli");
00665 XSD_ANON_SEQUENCE_TYPE(cp::simulation_type, Stimuli, Stimulus)&
00666 stimuli = DecideLocation( & mpUserParameters->Simulation().get().Stimuli(),
00667 & mpDefaultParameters->Simulation().get().Stimuli(),
00668 "Stimuli")->get().Stimulus();
00669 for (XSD_ANON_ITERATOR_TYPE(cp::simulation_type, Stimuli, Stimulus) i = stimuli.begin();
00670 i != stimuli.end();
00671 ++i)
00672 {
00673 cp::stimulus_type stimulus(*i);
00674 if (stimulus.Location().Cuboid().present())
00675 {
00676 cp::point_type point_a = stimulus.Location().Cuboid()->LowerCoordinates();
00677 cp::point_type point_b = stimulus.Location().Cuboid()->UpperCoordinates();
00678 switch (DIM)
00679 {
00680 case 1:
00681 {
00682 ChastePoint<DIM> chaste_point_a ( point_a.x() );
00683 ChastePoint<DIM> chaste_point_b ( point_b.x() );
00684 rStimulatedAreas.push_back( ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ) );
00685 break;
00686 }
00687 case 2:
00688 {
00689 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y() );
00690 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y() );
00691 rStimulatedAreas.push_back( ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ) );
00692 break;
00693 }
00694 case 3:
00695 {
00696 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
00697 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
00698 rStimulatedAreas.push_back( ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ) );
00699 break;
00700 }
00701 default:
00702 NEVER_REACHED;
00703 break;
00704 }
00705
00706 boost::shared_ptr<SimpleStimulus> stim(new SimpleStimulus(stimulus.Strength(),
00707 stimulus.Duration(),
00708 stimulus.Delay()));
00709 rStimuliApplied.push_back( stim );
00710 }
00711 else
00712 {
00713 if(stimulus.Location().EpiLayer().present() || stimulus.Location().MidLayer().present() || stimulus.Location().EndoLayer().present() )
00714 {
00715 EXCEPTION("Definition of transmural layers is not yet supported for specifying stimulated areas, please use cuboids instead");
00716 }
00717 }
00718 }
00719 }
00720
00721 template<unsigned DIM>
00722 void HeartConfig::GetCellHeterogeneities(std::vector<AbstractChasteRegion<DIM>* >& rCellHeterogeneityRegions,
00723 std::vector<double>& rScaleFactorGks,
00724 std::vector<double>& rScaleFactorIto,
00725 std::vector<double>& rScaleFactorGkr)
00726 {
00727 CheckSimulationIsDefined("CellHeterogeneities");
00728 XSD_ANON_SEQUENCE_TYPE(cp::simulation_type, CellHeterogeneities, CellHeterogeneity)&
00729 cell_heterogeneity = DecideLocation( & mpUserParameters->Simulation().get().CellHeterogeneities(),
00730 & mpDefaultParameters->Simulation().get().CellHeterogeneities(),
00731 "CellHeterogeneities")->get().CellHeterogeneity();
00732
00733 bool user_supplied_negative_value = false;
00734 bool user_asking_for_transmural_layers = false;
00735 unsigned counter_of_heterogeneities = 0;
00736
00737 for (XSD_ANON_ITERATOR_TYPE(cp::simulation_type, CellHeterogeneities, CellHeterogeneity) i = cell_heterogeneity.begin();
00738 i != cell_heterogeneity.end();
00739 ++i)
00740 {
00741 cp::cell_heterogeneity_type ht(*i);
00742
00743 if (ht.Location().Cuboid().present())
00744 {
00745 mUserAskedForCuboidsForCellularHeterogeneities = true;
00746 cp::point_type point_a = ht.Location().Cuboid()->LowerCoordinates();
00747 cp::point_type point_b = ht.Location().Cuboid()->UpperCoordinates();
00748
00749 switch (DIM)
00750 {
00751 case 1:
00752 {
00753 ChastePoint<DIM> chaste_point_a ( point_a.x() );
00754 ChastePoint<DIM> chaste_point_b ( point_b.x() );
00755 rCellHeterogeneityRegions.push_back(new ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
00756 break;
00757 }
00758 case 2:
00759 {
00760 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y() );
00761 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y() );
00762 rCellHeterogeneityRegions.push_back(new ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
00763 break;
00764 }
00765 case 3:
00766 {
00767 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
00768 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
00769 rCellHeterogeneityRegions.push_back(new ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
00770 break;
00771 }
00772 default:
00773 NEVER_REACHED;
00774 break;
00775 }
00776
00777 }
00778 else
00779 {
00780
00781 if(ht.Location().EpiLayer().present())
00782 {
00783 mEpiFraction = ht.Location().EpiLayer().get();
00784
00785 user_asking_for_transmural_layers = true;
00786 if (mEpiFraction <0)
00787 {
00788 user_supplied_negative_value=true;
00789 }
00790 mIndexEpi = counter_of_heterogeneities;
00791 }
00792 if(ht.Location().EndoLayer().present())
00793 {
00794 mEndoFraction = ht.Location().EndoLayer().get();
00795
00796 user_asking_for_transmural_layers = true;
00797 if (mEndoFraction <0)
00798 {
00799 user_supplied_negative_value=true;
00800 }
00801 mIndexEndo = counter_of_heterogeneities;
00802 }
00803 if(ht.Location().MidLayer().present())
00804 {
00805 mMidFraction = ht.Location().MidLayer().get();
00806
00807 user_asking_for_transmural_layers = true;
00808 if (mMidFraction <0)
00809 {
00810 user_supplied_negative_value=true;
00811 }
00812 mIndexMid = counter_of_heterogeneities;
00813 }
00814 }
00815 rScaleFactorGks.push_back (ht.ScaleFactorGks());
00816 rScaleFactorIto.push_back (ht.ScaleFactorIto());
00817 rScaleFactorGkr.push_back (ht.ScaleFactorGkr());
00818 counter_of_heterogeneities++;
00819 }
00820
00821
00822 mUserAskedForCellularTransmuralHeterogeneities = user_asking_for_transmural_layers;
00823
00824
00825 if (mUserAskedForCuboidsForCellularHeterogeneities && mUserAskedForCellularTransmuralHeterogeneities)
00826 {
00827
00828 for (unsigned index=0;index < rCellHeterogeneityRegions.size(); index++)
00829 {
00830 delete rCellHeterogeneityRegions[index];
00831 }
00832 EXCEPTION ("Specification of cellular heterogeneities by cuboids and layers at the same time is not yet supported");
00833 }
00834
00835 if (mUserAskedForCellularTransmuralHeterogeneities)
00836 {
00837
00838
00839
00840 if ((mIndexMid+mIndexEndo+mIndexEpi) > 3)
00841 {
00842 EXCEPTION ("Three specifications of layers must be supplied");
00843 }
00844 if (fabs((mEndoFraction+mMidFraction+mEpiFraction)-1)>1e-2)
00845 {
00846 EXCEPTION ("Summation of epicardial, midmyocardial and endocardial fractions should be 1");
00847 }
00848 if (user_supplied_negative_value)
00849 {
00850 EXCEPTION ("Fractions must be positive");
00851 }
00852 }
00853 }
00854
00855 bool HeartConfig::AreCellularTransmuralHeterogeneitiesRequested()
00856 {
00857 return mUserAskedForCellularTransmuralHeterogeneities;
00858 }
00859
00860 bool HeartConfig::AreCellularlHeterogeneitiesSpecifiedByCuboids()
00861 {
00862 return mUserAskedForCuboidsForCellularHeterogeneities;
00863 }
00864
00865 double HeartConfig::GetEpiLayerFraction()
00866 {
00867 return mEpiFraction;
00868 }
00869
00870 double HeartConfig::GetEndoLayerFraction()
00871 {
00872 return mEndoFraction;
00873 }
00874
00875 double HeartConfig::GetMidLayerFraction()
00876 {
00877 return mMidFraction;
00878 }
00879
00880 unsigned HeartConfig::GetEpiLayerIndex()
00881 {
00882 return mIndexEpi;
00883 }
00884
00885 unsigned HeartConfig::GetEndoLayerIndex()
00886 {
00887 return mIndexEndo;
00888 }
00889
00890 unsigned HeartConfig::GetMidLayerIndex()
00891 {
00892 return mIndexMid;
00893 }
00894
00895 bool HeartConfig::GetConductivityHeterogeneitiesProvided() const
00896 {
00897 CheckSimulationIsDefined("ConductivityHeterogeneities");
00898 try
00899 {
00900 DecideLocation( & mpUserParameters->Simulation().get().ConductivityHeterogeneities(),
00901 & mpDefaultParameters->Simulation().get().ConductivityHeterogeneities(),
00902 "ConductivityHeterogeneities");
00903 return true;
00904 }
00905 catch (Exception& e)
00906 {
00907 return false;
00908 }
00909 }
00910
00911 template<unsigned DIM>
00912 void HeartConfig::GetConductivityHeterogeneities(
00913 std::vector<ChasteCuboid<DIM> >& conductivitiesHeterogeneityAreas,
00914 std::vector< c_vector<double,3> >& intraConductivities,
00915 std::vector< c_vector<double,3> >& extraConductivities) const
00916 {
00917 CheckSimulationIsDefined("ConductivityHeterogeneities");
00918 XSD_ANON_SEQUENCE_TYPE(cp::simulation_type, ConductivityHeterogeneities, ConductivityHeterogeneity)&
00919 conductivity_heterogeneity = DecideLocation( & mpUserParameters->Simulation().get().ConductivityHeterogeneities(),
00920 & mpDefaultParameters->Simulation().get().ConductivityHeterogeneities(),
00921 "ConductivityHeterogeneities")->get().ConductivityHeterogeneity();
00922
00923 for (XSD_ANON_ITERATOR_TYPE(cp::simulation_type, ConductivityHeterogeneities, ConductivityHeterogeneity) i = conductivity_heterogeneity.begin();
00924 i != conductivity_heterogeneity.end();
00925 ++i)
00926 {
00927 cp::conductivity_heterogeneity_type ht(*i);
00928 if (ht.Location().Cuboid().present())
00929 {
00930 cp::point_type point_a = ht.Location().Cuboid()->LowerCoordinates();
00931 cp::point_type point_b = ht.Location().Cuboid()->UpperCoordinates();
00932
00933 switch (DIM)
00934 {
00935 case 1:
00936 {
00937 ChastePoint<DIM> chaste_point_a ( point_a.x() );
00938 ChastePoint<DIM> chaste_point_b ( point_b.x() );
00939 conductivitiesHeterogeneityAreas.push_back( ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
00940 break;
00941 }
00942 case 2:
00943 {
00944 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y() );
00945 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y() );
00946 conductivitiesHeterogeneityAreas.push_back( ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
00947 break;
00948 }
00949 case 3:
00950 {
00951 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
00952 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
00953 conductivitiesHeterogeneityAreas.push_back( ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
00954 break;
00955 }
00956 default:
00957 NEVER_REACHED;
00958 break;
00959 }
00960
00961
00962 }
00963 else
00964 {
00965 if(ht.Location().EpiLayer().present() || ht.Location().MidLayer().present() || ht.Location().EndoLayer().present() )
00966 {
00968 EXCEPTION("Definition of transmural layers is not allowed for conductivities heterogeneities, you may use fibre orientation support instead");
00969 }
00970 }
00971
00972 if (ht.IntracellularConductivities().present())
00973 {
00974 double intra_x = ht.IntracellularConductivities().get().longi();
00975 double intra_y = ht.IntracellularConductivities().get().trans();
00976 double intra_z = ht.IntracellularConductivities().get().normal();
00977
00978 intraConductivities.push_back( Create_c_vector(intra_x, intra_y, intra_z) );
00979 }
00980 else
00981 {
00982 c_vector<double, 3> intra_conductivities;
00983 GetIntracellularConductivities(intra_conductivities);
00984 intraConductivities.push_back(intra_conductivities);
00985 }
00986
00987 if (ht.ExtracellularConductivities().present())
00988 {
00989 double extra_x = ht.ExtracellularConductivities().get().longi();
00990 double extra_y = ht.ExtracellularConductivities().get().trans();
00991 double extra_z = ht.ExtracellularConductivities().get().normal();
00992
00993 extraConductivities.push_back( Create_c_vector(extra_x, extra_y, extra_z) );
00994 }
00995 else
00996 {
00997 c_vector<double, 3> extra_conductivities;
00998 GetExtracellularConductivities(extra_conductivities);
00999 extraConductivities.push_back(extra_conductivities);
01000 }
01001
01002 }
01003 }
01004
01005 std::string HeartConfig::GetOutputDirectory() const
01006 {
01007 CheckSimulationIsDefined("Simulation/OutputDirectory");
01008 return DecideLocation( & mpUserParameters->Simulation().get().OutputDirectory(),
01009 & mpDefaultParameters->Simulation().get().OutputDirectory(),
01010 "Simulation/OutputDirectory")->get();
01011 }
01012
01013 std::string HeartConfig::GetOutputFilenamePrefix() const
01014 {
01015 CheckSimulationIsDefined("Simulation/OutputFilenamePrefix");
01016 return DecideLocation( & mpUserParameters->Simulation().get().OutputFilenamePrefix(),
01017 & mpDefaultParameters->Simulation().get().OutputFilenamePrefix(),
01018 "Simulation/OutputFilenamePrefix")->get();
01019 }
01020
01021 bool HeartConfig::GetOutputVariablesProvided() const
01022 {
01023 CheckSimulationIsDefined("OutputVariables");
01024
01025 try
01026 {
01027 DecideLocation( & mpUserParameters->Simulation().get().OutputVariables(),
01028 & mpDefaultParameters->Simulation().get().OutputVariables(),
01029 "OutputVariables");
01030 return true;
01031 }
01032 catch (Exception& e)
01033 {
01034 return false;
01035 }
01036 }
01037
01038 void HeartConfig::GetOutputVariables(std::vector<std::string> &outputVariables) const
01039 {
01040 CheckSimulationIsDefined("OutputVariables");
01041 XSD_SEQUENCE_TYPE(cp::output_variables_type::Var)&
01042 output_variables = DecideLocation( & mpUserParameters->Simulation().get().OutputVariables(),
01043 & mpDefaultParameters->Simulation().get().OutputVariables(),
01044 "OutputVariables")->get().Var();
01045
01046 for (XSD_ITERATOR_TYPE(cp::output_variables_type::Var) i = output_variables.begin();
01047 i != output_variables.end();
01048 ++i)
01049 {
01050 cp::var_type var(*i);
01051
01052
01053 outputVariables.push_back(var.name());
01054 }
01055 }
01056
01057 bool HeartConfig::GetCheckpointSimulation() const
01058 {
01059 try
01060 {
01061 if (IsSimulationDefined())
01062 {
01063 CheckSimulationIsDefined("GetSaveSimulation");
01064 DecideLocation( & mpUserParameters->Simulation().get().CheckpointSimulation(),
01065 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01066 "Simulation/SaveSimulation");
01067 }
01068 else
01069 {
01070 CheckResumeSimulationIsDefined("GetSaveSimulation");
01071 DecideLocation( & mpUserParameters->ResumeSimulation().get().CheckpointSimulation(),
01072 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01073 "ResumeSimulation/SaveSimulation");
01074 }
01075 return true;
01076 }
01077 catch (Exception& e)
01078 {
01079 return false;
01080 }
01081 }
01082
01083 double HeartConfig::GetCheckpointTimestep() const
01084 {
01085 if (IsSimulationDefined())
01086 {
01087 CheckSimulationIsDefined("GetSaveSimulation");
01088 return DecideLocation( & mpUserParameters->Simulation().get().CheckpointSimulation(),
01089 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01090 "Simulation/SaveSimulation")->get().timestep();
01091 }
01092 else
01093 {
01094 CheckResumeSimulationIsDefined("GetSaveSimulation");
01095 return DecideLocation( & mpUserParameters->ResumeSimulation().get().CheckpointSimulation(),
01096 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01097 "ResumeSimulation/SaveSimulation")->get().timestep();
01098 }
01099 }
01100
01101 unsigned HeartConfig::GetMaxCheckpointsOnDisk() const
01102 {
01103 if (IsSimulationDefined())
01104 {
01105 CheckSimulationIsDefined("GetSaveSimulation");
01106 return DecideLocation( & mpUserParameters->Simulation().get().CheckpointSimulation(),
01107 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01108 "Simulation/SaveSimulation")->get().max_checkpoints_on_disk();
01109 }
01110 else
01111 {
01112 CheckResumeSimulationIsDefined("GetSaveSimulation");
01113 return DecideLocation( & mpUserParameters->ResumeSimulation().get().CheckpointSimulation(),
01114 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01115 "ResumeSimulation/SaveSimulation")->get().max_checkpoints_on_disk();
01116 }
01117 }
01118
01119
01120 std::string HeartConfig::GetArchivedSimulationDir() const
01121 {
01122 CheckResumeSimulationIsDefined("GetArchivedSimulationDir");
01123
01124 return mpUserParameters->ResumeSimulation().get().ArchiveDirectory();
01125 }
01126
01127
01128 void HeartConfig::GetIntracellularConductivities(c_vector<double, 3>& intraConductivities) const
01129 {
01130 optional<cp::conductivities_type, false>* intra_conductivities
01131 = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
01132 & mpDefaultParameters->Physiological().IntracellularConductivities(),
01133 "IntracellularConductivities");
01134 double intra_x_cond = intra_conductivities->get().longi();
01135 double intra_y_cond = intra_conductivities->get().trans();
01136 double intra_z_cond = intra_conductivities->get().normal();;
01137
01138 assert(intra_y_cond != DBL_MAX);
01139 assert(intra_z_cond != DBL_MAX);
01140
01141 intraConductivities[0] = intra_x_cond;
01142 intraConductivities[1] = intra_y_cond;
01143 intraConductivities[2] = intra_z_cond;
01144 }
01145
01146 void HeartConfig::GetIntracellularConductivities(c_vector<double, 2>& intraConductivities) const
01147 {
01148 optional<cp::conductivities_type, false>* intra_conductivities
01149 = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
01150 & mpDefaultParameters->Physiological().IntracellularConductivities(),
01151 "IntracellularConductivities");
01152 double intra_x_cond = intra_conductivities->get().longi();
01153 double intra_y_cond = intra_conductivities->get().trans();
01154
01155 assert(intra_y_cond != DBL_MAX);
01156
01157 intraConductivities[0] = intra_x_cond;
01158 intraConductivities[1] = intra_y_cond;
01159 }
01160
01161 void HeartConfig::GetIntracellularConductivities(c_vector<double, 1>& intraConductivities) const
01162 {
01163 optional<cp::conductivities_type, false>* intra_conductivities
01164 = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
01165 & mpDefaultParameters->Physiological().IntracellularConductivities(),
01166 "IntracellularConductivities");
01167 double intra_x_cond = intra_conductivities->get().longi();
01168
01169 intraConductivities[0] = intra_x_cond;
01170 }
01171
01172 void HeartConfig::GetExtracellularConductivities(c_vector<double, 3>& extraConductivities) const
01173 {
01174 optional<cp::conductivities_type, false>* extra_conductivities
01175 = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
01176 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
01177 "ExtracellularConductivities");
01178 double extra_x_cond = extra_conductivities->get().longi();
01179 double extra_y_cond = extra_conductivities->get().trans();
01180 double extra_z_cond = extra_conductivities->get().normal();;
01181
01182 assert(extra_y_cond != DBL_MAX);
01183 assert(extra_z_cond != DBL_MAX);
01184
01185 extraConductivities[0] = extra_x_cond;
01186 extraConductivities[1] = extra_y_cond;
01187 extraConductivities[2] = extra_z_cond;
01188 }
01189
01190 void HeartConfig::GetExtracellularConductivities(c_vector<double, 2>& extraConductivities) const
01191 {
01192 optional<cp::conductivities_type, false>* extra_conductivities
01193 = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
01194 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
01195 "ExtracellularConductivities");
01196 double extra_x_cond = extra_conductivities->get().longi();
01197 double extra_y_cond = extra_conductivities->get().trans();
01198
01199 assert(extra_y_cond != DBL_MAX);
01200
01201 extraConductivities[0] = extra_x_cond;
01202 extraConductivities[1] = extra_y_cond;
01203 }
01204
01205 void HeartConfig::GetExtracellularConductivities(c_vector<double, 1>& extraConductivities) const
01206 {
01207 optional<cp::conductivities_type, false>* extra_conductivities
01208 = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
01209 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
01210 "ExtracellularConductivities");
01211 double extra_x_cond = extra_conductivities->get().longi();
01212
01213 extraConductivities[0] = extra_x_cond;
01214 }
01215
01216 double HeartConfig::GetBathConductivity() const
01217 {
01218
01219 return DecideLocation( & mpUserParameters->Physiological().BathConductivity(),
01220 & mpDefaultParameters->Physiological().BathConductivity(),
01221 "BathConductivity")->get();
01222 }
01223
01224 double HeartConfig::GetSurfaceAreaToVolumeRatio() const
01225 {
01226
01227 return DecideLocation( & mpUserParameters->Physiological().SurfaceAreaToVolumeRatio(),
01228 & mpDefaultParameters->Physiological().SurfaceAreaToVolumeRatio(),
01229 "SurfaceAreaToVolumeRatio")->get();
01230 }
01231
01232 double HeartConfig::GetCapacitance() const
01233 {
01234
01235 return DecideLocation( & mpUserParameters->Physiological().Capacitance(),
01236 & mpDefaultParameters->Physiological().Capacitance(),
01237 "Capacitance")->get();
01238 }
01239
01240 double HeartConfig::GetOdeTimeStep() const
01241 {
01242 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
01243 & mpDefaultParameters->Numerical().TimeSteps(),
01244 "ode TimeStep")->get().ode();
01245 }
01246
01247 double HeartConfig::GetPdeTimeStep() const
01248 {
01249 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
01250 & mpDefaultParameters->Numerical().TimeSteps(),
01251 "pde TimeStep")->get().pde();
01252 }
01253
01254 double HeartConfig::GetPrintingTimeStep() const
01255 {
01256 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
01257 & mpDefaultParameters->Numerical().TimeSteps(),
01258 "printing TimeStep")->get().printing();
01259 }
01260
01261 bool HeartConfig::GetUseAbsoluteTolerance() const
01262 {
01263 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01264 & mpDefaultParameters->Numerical().KSPTolerances(),
01265 "KSPTolerances")->get().KSPAbsolute().present();
01266 }
01267
01268 double HeartConfig::GetAbsoluteTolerance() const
01269 {
01270 if (!GetUseAbsoluteTolerance())
01271 {
01272 EXCEPTION("Absolute tolerance is not set in Chaste parameters");
01273 }
01274 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01275 & mpDefaultParameters->Numerical().KSPTolerances(),
01276 "KSPTolerances")->get().KSPAbsolute().get();
01277 }
01278
01279 bool HeartConfig::GetUseRelativeTolerance() const
01280 {
01281 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01282 & mpDefaultParameters->Numerical().KSPTolerances(),
01283 "KSPTolerances")->get().KSPRelative().present();
01284 }
01285
01286 double HeartConfig::GetRelativeTolerance() const
01287 {
01288 if (!GetUseRelativeTolerance())
01289 {
01290 EXCEPTION("Relative tolerance is not set in Chaste parameters");
01291 }
01292 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01293 & mpDefaultParameters->Numerical().KSPTolerances(),
01294 "KSPTolerances")->get().KSPRelative().get();
01295 }
01296
01297 const char* HeartConfig::GetKSPSolver() const
01298 {
01299 switch ( DecideLocation( & mpUserParameters->Numerical().KSPSolver(),
01300 & mpDefaultParameters->Numerical().KSPSolver(),
01301 "KSPSolver")->get() )
01302 {
01303 case cp::ksp_solver_type::gmres :
01304 return "gmres";
01305 case cp::ksp_solver_type::cg :
01306 return "cg";
01307 case cp::ksp_solver_type::symmlq :
01308 return "symmlq";
01309 }
01310 #define COVERAGE_IGNORE
01311 EXCEPTION("Unknown ksp solver");
01312 #undef COVERAGE_IGNORE
01313 }
01314
01315 const char* HeartConfig::GetKSPPreconditioner() const
01316 {
01317 switch ( DecideLocation( & mpUserParameters->Numerical().KSPPreconditioner(),
01318 & mpDefaultParameters->Numerical().KSPPreconditioner(),
01319 "KSPPreconditioner")->get() )
01320 {
01321 case cp::ksp_preconditioner_type::ilu :
01322 return "ilu";
01323 case cp::ksp_preconditioner_type::jacobi :
01324 return "jacobi";
01325 case cp::ksp_preconditioner_type::bjacobi :
01326 return "bjacobi";
01327 case cp::ksp_preconditioner_type::hypre :
01328 return "hypre";
01329 case cp::ksp_preconditioner_type::ml :
01330 return "ml";
01331 case cp::ksp_preconditioner_type::spai :
01332 return "spai";
01333 case cp::ksp_preconditioner_type::blockdiagonal :
01334 return "blockdiagonal";
01335 case cp::ksp_preconditioner_type::ldufactorisation :
01336 return "ldufactorisation";
01337 case cp::ksp_preconditioner_type::none :
01338 return "none";
01339
01340 }
01341 #define COVERAGE_IGNORE
01342 EXCEPTION("Unknown ksp preconditioner");
01343 #undef COVERAGE_IGNORE
01344 }
01345
01346 bool HeartConfig::IsAdaptivityParametersPresent() const
01347 {
01348 try
01349 {
01350 DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01351 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01352 "AdaptivityParameters")->present();
01353
01354 return true;
01355 }
01356 catch (Exception &e)
01357 {
01358
01359 return false;
01360 }
01361 }
01362
01363 double HeartConfig::GetTargetErrorForAdaptivity() const
01364 {
01365 if ( IsAdaptivityParametersPresent() )
01366 {
01367 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01368 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01369 "TargetError")->get().target_error();
01370 }
01371 else
01372 {
01373 EXCEPTION("Adaptivity parameters have not been set");
01374 }
01375 }
01376
01377 double HeartConfig::GetSigmaForAdaptivity() const
01378 {
01379 if ( IsAdaptivityParametersPresent() )
01380 {
01381 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01382 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01383 "TargetError")->get().sigma();
01384 }
01385 else
01386 {
01387 EXCEPTION("Adaptivity parameters have not been set");
01388 }
01389 }
01390
01391 double HeartConfig::GetMaxEdgeLengthForAdaptivity() const
01392 {
01393 if ( IsAdaptivityParametersPresent() )
01394 {
01395 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01396 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01397 "TargetError")->get().max_edge_length();
01398 }
01399 else
01400 {
01401 EXCEPTION("Adaptivity parameters have not been set");
01402 }
01403 }
01404
01405 double HeartConfig::GetMinEdgeLengthForAdaptivity() const
01406 {
01407 if ( IsAdaptivityParametersPresent() )
01408 {
01409 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01410 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01411 "TargetError")->get().min_edge_length();
01412 }
01413 else
01414 {
01415 EXCEPTION("Adaptivity parameters have not been set");
01416 }
01417 }
01418
01419 double HeartConfig::GetGradationForAdaptivity() const
01420 {
01421 if ( IsAdaptivityParametersPresent() )
01422 {
01423 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01424 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01425 "TargetError")->get().gradation();
01426 }
01427 else
01428 {
01429 EXCEPTION("Adaptivity parameters have not been set");
01430 }
01431 }
01432
01433 unsigned HeartConfig::GetMaxNodesForAdaptivity() const
01434 {
01435 if ( IsAdaptivityParametersPresent() )
01436 {
01437 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01438 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01439 "TargetError")->get().max_nodes();
01440 }
01441 else
01442 {
01443 EXCEPTION("Adaptivity parameters have not been set");
01444 }
01445 }
01446
01447 unsigned HeartConfig::GetNumberOfAdaptiveSweeps() const
01448 {
01449 if ( IsAdaptivityParametersPresent() )
01450 {
01451 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01452 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01453 "TargetError")->get().num_sweeps();
01454 }
01455 else
01456 {
01457 EXCEPTION("Adaptivity parameters have not been set");
01458 }
01459 }
01460
01461
01462
01463
01464
01465 bool HeartConfig::IsPostProcessingSectionPresent() const
01466 {
01467 try
01468 {
01469 DecideLocation( & mpUserParameters->PostProcessing(),
01470 & mpDefaultParameters->PostProcessing(),
01471 "PostProcessing")->present();
01472
01473 return true;
01474 }
01475 catch (Exception &e)
01476 {
01477
01478 return false;
01479 }
01480 }
01481
01482 bool HeartConfig::IsPostProcessingRequested() const
01483 {
01484 if (IsPostProcessingSectionPresent() == false)
01485 {
01486 return false;
01487 }
01488 else
01489 {
01490 return(IsApdMapsRequested() ||
01491 IsUpstrokeTimeMapsRequested() ||
01492 IsMaxUpstrokeVelocityMapRequested() ||
01493 IsConductionVelocityMapsRequested());
01494 }
01495 }
01496 bool HeartConfig::IsApdMapsRequested() const
01497 {
01498 assert(IsPostProcessingSectionPresent());
01499
01500 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ActionPotentialDurationMap)&
01501 apd_maps = DecideLocation( & mpUserParameters->PostProcessing(),
01502 & mpDefaultParameters->PostProcessing(),
01503 "ActionPotentialDurationMap")->get().ActionPotentialDurationMap();
01504 return (apd_maps.begin() != apd_maps.end());
01505 }
01506
01507 void HeartConfig::GetApdMaps(std::vector<std::pair<double,double> >& apd_maps) const
01508 {
01509 assert(IsApdMapsRequested());
01510 apd_maps.clear();
01511
01512 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ActionPotentialDurationMap)&
01513 apd_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01514 & mpDefaultParameters->PostProcessing(),
01515 "ActionPotentialDurationMap")->get().ActionPotentialDurationMap();
01516
01517 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::ActionPotentialDurationMap) i = apd_maps_sequence.begin();
01518 i != apd_maps_sequence.end();
01519 ++i)
01520 {
01521 std::pair<double,double> map(i->repolarisation_percentage(),i->threshold());
01522
01523 apd_maps.push_back(map);
01524 }
01525 }
01526
01527 bool HeartConfig::IsUpstrokeTimeMapsRequested() const
01528 {
01529 assert(IsPostProcessingSectionPresent());
01530
01531 XSD_SEQUENCE_TYPE(cp::postprocessing_type::UpstrokeTimeMap)&
01532 upstroke_map = DecideLocation( & mpUserParameters->PostProcessing(),
01533 & mpDefaultParameters->PostProcessing(),
01534 "UpstrokeTimeMap")->get().UpstrokeTimeMap();
01535 return (upstroke_map.begin() != upstroke_map.end());
01536 }
01537 void HeartConfig::GetUpstrokeTimeMaps (std::vector<double>& upstroke_time_maps) const
01538 {
01539 assert(IsUpstrokeTimeMapsRequested());
01540 assert(upstroke_time_maps.size() == 0);
01541
01542 XSD_SEQUENCE_TYPE(cp::postprocessing_type::UpstrokeTimeMap)&
01543 upstroke_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01544 & mpDefaultParameters->PostProcessing(),
01545 "UpstrokeTimeMap")->get().UpstrokeTimeMap();
01546
01547 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::UpstrokeTimeMap) i = upstroke_maps_sequence.begin();
01548 i != upstroke_maps_sequence.end();
01549 ++i)
01550 {
01551 upstroke_time_maps.push_back(i->threshold());
01552 }
01553 }
01554
01555 bool HeartConfig::IsMaxUpstrokeVelocityMapRequested() const
01556 {
01557 assert(IsPostProcessingSectionPresent());
01558
01559 XSD_SEQUENCE_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap)&
01560 max_upstroke_velocity_map = DecideLocation( & mpUserParameters->PostProcessing(),
01561 & mpDefaultParameters->PostProcessing(),
01562 "MaxUpstrokeVelocityMap")->get().MaxUpstrokeVelocityMap();
01563
01564 return (max_upstroke_velocity_map.begin() != max_upstroke_velocity_map.end());
01565 }
01566
01567 void HeartConfig::GetMaxUpstrokeVelocityMaps(std::vector<double>& upstroke_velocity_maps) const
01568 {
01569 assert(IsMaxUpstrokeVelocityMapRequested());
01570 assert(upstroke_velocity_maps.size() == 0);
01571
01572 XSD_SEQUENCE_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap)&
01573 max_upstroke_velocity_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01574 & mpDefaultParameters->PostProcessing(),
01575 "MaxUpstrokeVelocityMap")->get().MaxUpstrokeVelocityMap();
01576
01577 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap) i = max_upstroke_velocity_maps_sequence.begin();
01578 i != max_upstroke_velocity_maps_sequence.end();
01579 ++i)
01580 {
01581 upstroke_velocity_maps.push_back(i->threshold());
01582 }
01583 }
01584
01585 bool HeartConfig::IsConductionVelocityMapsRequested() const
01586 {
01587 assert(IsPostProcessingSectionPresent());
01588
01589 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ConductionVelocityMap)&
01590 cond_vel_maps = DecideLocation( & mpUserParameters->PostProcessing(),
01591 & mpDefaultParameters->PostProcessing(),
01592 "ConductionVelocityMap")->get().ConductionVelocityMap();
01593 return (cond_vel_maps.begin() != cond_vel_maps.end());
01594 }
01595
01596 void HeartConfig::GetConductionVelocityMaps(std::vector<unsigned>& conduction_velocity_maps) const
01597 {
01598 assert(IsConductionVelocityMapsRequested());
01599 assert(conduction_velocity_maps.size() == 0);
01600
01601 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ConductionVelocityMap)&
01602 cond_vel_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01603 & mpDefaultParameters->PostProcessing(),
01604 "ConductionVelocityMap")->get().ConductionVelocityMap();
01605
01606 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::ConductionVelocityMap) i = cond_vel_maps_sequence.begin();
01607 i != cond_vel_maps_sequence.end();
01608 ++i)
01609 {
01610 conduction_velocity_maps.push_back(i->origin_node());
01611 }
01612 }
01613
01614
01615
01616
01617
01618 bool HeartConfig::IsOutputVisualizerPresent() const
01619 {
01620 CheckSimulationIsDefined("OutputVisualizer");
01621
01622 try
01623 {
01624 DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
01625 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
01626 "OutputVisualizer")->present();
01627
01628 return true;
01629 }
01630 catch (Exception &e)
01631 {
01632
01633 return false;
01634 }
01635 }
01636
01637 bool HeartConfig::GetVisualizeWithMeshalyzer() const
01638 {
01639 if (!IsOutputVisualizerPresent())
01640 {
01641 return true;
01642 }
01643 else
01644 {
01645 return DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
01646 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
01647 "OutputVisualizer")->get().meshalyzer() == cp::yesno_type::yes;
01648 }
01649 }
01650
01651 bool HeartConfig::GetVisualizeWithCmgui() const
01652 {
01653 if (!IsOutputVisualizerPresent())
01654 {
01655 return false;
01656 }
01657 else
01658 {
01659 return DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
01660 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
01661 "OutputVisualizer")->get().cmgui() == cp::yesno_type::yes;
01662 }
01663 }
01664
01665 bool HeartConfig::GetVisualizeWithVtk() const
01666 {
01667 if (!IsOutputVisualizerPresent())
01668 {
01669 return false;
01670 }
01671 else
01672 {
01673 return DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
01674 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
01675 "OutputVisualizer")->get().vtk() == cp::yesno_type::yes;
01676 }
01677 }
01678
01679
01680
01681
01682
01683 void HeartConfig::SetSpaceDimension(unsigned spaceDimension)
01684 {
01685 mpUserParameters->Simulation().get().SpaceDimension().set(spaceDimension);
01686 }
01687
01688 void HeartConfig::SetSimulationDuration(double simulationDuration)
01689 {
01690 XSD_CREATE_WITH_FIXED_ATTR1(cp::time_type, time, simulationDuration, "ms");
01691 mpUserParameters->Simulation().get().SimulationDuration().set(time);
01692 }
01693
01694 void HeartConfig::SetDomain(const cp::domain_type& rDomain)
01695 {
01696 mpUserParameters->Simulation().get().Domain().set(rDomain);
01697 }
01698
01699 void HeartConfig::SetDefaultIonicModel(const cp::ionic_models_available_type& rIonicModel)
01700 {
01701 cp::ionic_model_selection_type ionic_model;
01702 ionic_model.Hardcoded(rIonicModel);
01703 cp::ionic_models_type container(ionic_model);
01704 mpUserParameters->Simulation().get().IonicModels().set(container);
01705 }
01706
01707 void HeartConfig::SetSlabDimensions(double x, double y, double z, double inter_node_space)
01708 {
01709 if ( ! mpUserParameters->Simulation().get().Mesh().present())
01710 {
01711 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
01712 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
01713 }
01714
01715 cp::slab_type slab_definition(x, y, z, inter_node_space);
01716 mpUserParameters->Simulation().get().Mesh().get().Slab().set(slab_definition);
01717 }
01718
01719 void HeartConfig::SetSheetDimensions(double x, double y, double inter_node_space)
01720 {
01721 if ( ! mpUserParameters->Simulation().get().Mesh().present())
01722 {
01723 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
01724 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
01725 }
01726
01727 cp::sheet_type sheet_definition(x, y, inter_node_space);
01728 mpUserParameters->Simulation().get().Mesh().get().Sheet().set(sheet_definition);
01729 }
01730
01731 void HeartConfig::SetFibreLength(double x, double inter_node_space)
01732 {
01733 if ( ! mpUserParameters->Simulation().get().Mesh().present())
01734 {
01735 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
01736 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
01737 }
01738
01739 cp::fibre_type fibre_definition(x, inter_node_space);
01740 mpUserParameters->Simulation().get().Mesh().get().Fibre().set(fibre_definition);
01741 }
01742
01743 void HeartConfig::SetMeshFileName(std::string meshPrefix, cp::media_type fibreDefinition)
01744 {
01745 if ( ! mpUserParameters->Simulation().get().Mesh().present())
01746 {
01747 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
01748 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
01749 }
01750
01751 XSD_NESTED_TYPE(cp::mesh_type::LoadMesh) mesh_prefix(meshPrefix, fibreDefinition);
01752 mpUserParameters->Simulation().get().Mesh().get().LoadMesh().set(mesh_prefix);
01753 }
01754
01755 void HeartConfig::SetIonicModelRegions(std::vector<ChasteCuboid<3> >& rDefinedRegions,
01756 std::vector<cp::ionic_model_selection_type>& rIonicModels) const
01757 {
01758 assert(rDefinedRegions.size() == rIonicModels.size());
01760 XSD_SEQUENCE_TYPE(cp::ionic_models_type::Region)&
01761 regions = mpUserParameters->Simulation().get().IonicModels().get().Region();
01762 regions.clear();
01763 for (unsigned region_index=0; region_index<rDefinedRegions.size(); region_index++)
01764 {
01765 cp::point_type point_a(rDefinedRegions[region_index].rGetLowerCorner()[0],
01766 rDefinedRegions[region_index].rGetLowerCorner()[1],
01767 rDefinedRegions[region_index].rGetLowerCorner()[2]);
01768
01769 cp::point_type point_b(rDefinedRegions[region_index].rGetUpperCorner()[0],
01770 rDefinedRegions[region_index].rGetUpperCorner()[1],
01771 rDefinedRegions[region_index].rGetUpperCorner()[2]);
01772
01773 XSD_CREATE_WITH_FIXED_ATTR(cp::location_type, locn, "cm");
01774 locn.Cuboid().set(cp::box_type(point_a, point_b));
01775
01776 cp::ionic_model_region_type region(rIonicModels[region_index], locn);
01777 regions.push_back(region);
01778 }
01779 }
01780
01781 void HeartConfig::SetConductivityHeterogeneities(std::vector<ChasteCuboid<3> >& conductivityAreas,
01782 std::vector< c_vector<double,3> >& intraConductivities,
01783 std::vector< c_vector<double,3> >& extraConductivities)
01784 {
01785 assert ( conductivityAreas.size() == intraConductivities.size() );
01786 assert ( intraConductivities.size() == extraConductivities.size());
01787
01788 XSD_ANON_SEQUENCE_TYPE(cp::simulation_type, ConductivityHeterogeneities, ConductivityHeterogeneity) heterogeneities_container;
01789
01790 for (unsigned region_index=0; region_index<conductivityAreas.size(); region_index++)
01791 {
01792 cp::point_type point_a(conductivityAreas[region_index].rGetLowerCorner()[0],
01793 conductivityAreas[region_index].rGetLowerCorner()[1],
01794 conductivityAreas[region_index].rGetLowerCorner()[2]);
01795
01796 cp::point_type point_b(conductivityAreas[region_index].rGetUpperCorner()[0],
01797 conductivityAreas[region_index].rGetUpperCorner()[1],
01798 conductivityAreas[region_index].rGetUpperCorner()[2]);
01799
01800 XSD_CREATE_WITH_FIXED_ATTR(cp::location_type, locn, "cm");
01801 locn.Cuboid().set(cp::box_type(point_a, point_b));
01802 cp::conductivity_heterogeneity_type ht(locn);
01803
01804 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
01805 intraConductivities[region_index][0],
01806 intraConductivities[region_index][1],
01807 intraConductivities[region_index][2],
01808 "mS/cm");
01809
01810 ht.IntracellularConductivities(intra);
01811
01812 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
01813 extraConductivities[region_index][0],
01814 extraConductivities[region_index][1],
01815 extraConductivities[region_index][2],
01816 "mS/cm");
01817
01818 ht.ExtracellularConductivities(extra);
01819
01820 heterogeneities_container.push_back(ht);
01821 }
01822
01823 XSD_ANON_TYPE(cp::simulation_type, ConductivityHeterogeneities) heterogeneities_object;
01824 heterogeneities_object.ConductivityHeterogeneity(heterogeneities_container);
01825
01826 mpUserParameters->Simulation().get().ConductivityHeterogeneities().set(heterogeneities_object);
01827 }
01828
01829
01830 void HeartConfig::SetOutputDirectory(const std::string& rOutputDirectory)
01831 {
01832 mpUserParameters->Simulation().get().OutputDirectory().set(rOutputDirectory);
01833 }
01834
01835 void HeartConfig::SetOutputFilenamePrefix(const std::string& rOutputFilenamePrefix)
01836 {
01837 mpUserParameters->Simulation().get().OutputFilenamePrefix().set(rOutputFilenamePrefix);
01838 }
01839
01840 void HeartConfig::SetOutputVariables(const std::vector<std::string>& rOutputVariables)
01841 {
01842 if ( ! mpUserParameters->Simulation().get().OutputVariables().present())
01843 {
01844 cp::output_variables_type variables_requested;
01845 mpUserParameters->Simulation().get().OutputVariables().set(variables_requested);
01846 }
01847
01848 XSD_SEQUENCE_TYPE(cp::output_variables_type::Var)&
01849 var_type_sequence = mpUserParameters->Simulation().get().OutputVariables()->Var();
01850
01851 var_type_sequence.clear();
01852
01853 for (unsigned i=0; i<rOutputVariables.size(); i++)
01854 {
01855 cp::var_type temp(rOutputVariables[i]);
01856 var_type_sequence.push_back(temp);
01857 }
01858
01859 if (rOutputVariables.size() > 0)
01860 {
01861
01862 SetVisualizeWithMeshalyzer(false);
01863 SetVisualizeWithCmgui(false);
01864 SetVisualizeWithVtk(false);
01865 }
01866 }
01867
01868 void HeartConfig::SetCheckpointSimulation(bool saveSimulation, double checkpointTimestep, unsigned maxCheckpointsOnDisk)
01869 {
01870 if (saveSimulation)
01871 {
01872
01873 assert(checkpointTimestep!=-1.0 && maxCheckpointsOnDisk!=UINT_MAX);
01874
01875 XSD_CREATE_WITH_FIXED_ATTR2(cp::simulation_type::XSD_NESTED_TYPE(CheckpointSimulation),
01876 cs,
01877 checkpointTimestep,
01878 maxCheckpointsOnDisk,
01879 "ms");
01880 mpUserParameters->Simulation().get().CheckpointSimulation().set(cs);
01881 }
01882 else
01883 {
01884 mpUserParameters->Simulation().get().CheckpointSimulation().reset();
01885 }
01886
01887 CheckTimeSteps();
01888 }
01889
01890
01891 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 3>& intraConductivities)
01892 {
01893 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
01894 intraConductivities[0],
01895 intraConductivities[1],
01896 intraConductivities[2],
01897 "mS/cm");
01898
01899 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
01900 }
01901
01902 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 2>& intraConductivities)
01903 {
01904 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
01905 intraConductivities[0],
01906 intraConductivities[1],
01907 0.0, "mS/cm");
01908
01909 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
01910 }
01911
01912 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 1>& intraConductivities)
01913 {
01914 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
01915 intraConductivities[0],
01916 0.0, 0.0, "mS/cm");
01917
01918 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
01919 }
01920
01921 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 3>& extraConductivities)
01922 {
01923 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
01924 extraConductivities[0],
01925 extraConductivities[1],
01926 extraConductivities[2],
01927 "mS/cm");
01928
01929 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
01930 }
01931
01932 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 2>& extraConductivities)
01933 {
01934 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
01935 extraConductivities[0],
01936 extraConductivities[1],
01937 0.0, "mS/cm");
01938
01939 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
01940 }
01941
01942 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 1>& extraConductivities)
01943 {
01944 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
01945 extraConductivities[0],
01946 0.0, 0.0, "mS/cm");
01947
01948 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
01949 }
01950
01951 void HeartConfig::SetBathConductivity(double bathConductivity)
01952 {
01953 XSD_CREATE_WITH_FIXED_ATTR1(cp::conductivity_type, cond, bathConductivity, "mS/cm");
01954 mpUserParameters->Physiological().BathConductivity().set(cond);
01955 }
01956
01957 void HeartConfig::SetSurfaceAreaToVolumeRatio(double ratio)
01958 {
01959 XSD_CREATE_WITH_FIXED_ATTR1(cp::inverse_length_type, ratio_object, ratio, "1/cm");
01960 mpUserParameters->Physiological().SurfaceAreaToVolumeRatio().set(ratio_object);
01961 }
01962
01963 void HeartConfig::SetCapacitance(double capacitance)
01964 {
01965 XSD_CREATE_WITH_FIXED_ATTR1(cp::capacitance_type, capacitance_object, capacitance, "uF/cm^2");
01966 mpUserParameters->Physiological().Capacitance().set(capacitance_object);
01967 }
01968
01969
01970
01971 void HeartConfig::SetOdePdeAndPrintingTimeSteps(double odeTimeStep, double pdeTimeStep, double printingTimeStep)
01972 {
01973 XSD_CREATE_WITH_FIXED_ATTR3(cp::time_steps_type, time_steps,
01974 odeTimeStep, pdeTimeStep, printingTimeStep, "ms");
01975 mpUserParameters->Numerical().TimeSteps().set(time_steps);
01976 CheckTimeSteps();
01977 }
01978
01979 void HeartConfig::SetOdeTimeStep(double odeTimeStep)
01980 {
01981 SetOdePdeAndPrintingTimeSteps(odeTimeStep, GetPdeTimeStep(), GetPrintingTimeStep());
01982 }
01983
01984 void HeartConfig::SetPdeTimeStep(double pdeTimeStep)
01985 {
01986 SetOdePdeAndPrintingTimeSteps(GetOdeTimeStep(), pdeTimeStep, GetPrintingTimeStep());
01987 }
01988
01989 void HeartConfig::SetPrintingTimeStep(double printingTimeStep)
01990 {
01991 SetOdePdeAndPrintingTimeSteps(GetOdeTimeStep(), GetPdeTimeStep(), printingTimeStep);
01992 }
01993
01994 void HeartConfig::CheckTimeSteps() const
01995 {
01996 if (GetOdeTimeStep() <= 0)
01997 {
01998 EXCEPTION("Ode time-step should be positive");
01999 }
02000 if (GetPdeTimeStep() <= 0)
02001 {
02002 EXCEPTION("Pde time-step should be positive");
02003 }
02004 if (GetPrintingTimeStep() <= 0.0)
02005 {
02006 EXCEPTION("Printing time-step should be positive");
02007 }
02008
02009 if (GetPdeTimeStep()>GetPrintingTimeStep())
02010 {
02011 EXCEPTION("Printing time-step should not be smaller than PDE time-step");
02012 }
02013
02014
02015
02016 double remainder=fmod(GetPrintingTimeStep(), GetPdeTimeStep());
02017
02018 if ( remainder > DBL_EPSILON && remainder < GetPdeTimeStep()-DBL_EPSILON)
02019 {
02020 EXCEPTION("Printing time-step should be a multiple of PDE time step");
02021 }
02022
02023 if ( GetOdeTimeStep() > GetPdeTimeStep() )
02024 {
02025 EXCEPTION("Ode time-step should not be greater than PDE time-step");
02026 }
02027
02028 if (GetCheckpointSimulation())
02029 {
02030 if (GetCheckpointTimestep() <= 0.0)
02031 {
02032 EXCEPTION("Checkpoint time-step should be positive");
02033 }
02034
02035
02036
02037 double remainder_checkpoint_over_printing=fmod(GetCheckpointTimestep(), GetPrintingTimeStep());
02038
02039
02040 if ( remainder_checkpoint_over_printing > DBL_EPSILON && remainder_checkpoint_over_printing < GetPrintingTimeStep()-DBL_EPSILON*(1/GetPrintingTimeStep()))
02041 {
02042 EXCEPTION("Checkpoint time-step should be a multiple of printing time-step");
02043 }
02044 }
02045 }
02046
02047
02048 void HeartConfig::SetUseRelativeTolerance(double relativeTolerance)
02049 {
02050
02051 mpUserParameters->Numerical().KSPTolerances().get().KSPAbsolute().reset();
02052 mpUserParameters->Numerical().KSPTolerances().get().KSPRelative().set(relativeTolerance);
02053 }
02054
02055 void HeartConfig::SetUseAbsoluteTolerance(double absoluteTolerance)
02056 {
02057
02058 mpUserParameters->Numerical().KSPTolerances().get().KSPRelative().reset();
02059 mpUserParameters->Numerical().KSPTolerances().get().KSPAbsolute().set(absoluteTolerance);
02060 }
02061
02062 void HeartConfig::SetKSPSolver(const char* kspSolver)
02063 {
02064
02065 if ( strcmp(kspSolver, "gmres") == 0)
02066 {
02067 mpUserParameters->Numerical().KSPSolver().set(cp::ksp_solver_type::gmres);
02068 return;
02069 }
02070 if ( strcmp(kspSolver, "cg") == 0)
02071 {
02072 mpUserParameters->Numerical().KSPSolver().set(cp::ksp_solver_type::cg);
02073 return;
02074 }
02075 if ( strcmp(kspSolver, "symmlq") == 0)
02076 {
02077 mpUserParameters->Numerical().KSPSolver().set(cp::ksp_solver_type::symmlq);
02078 return;
02079 }
02080
02081 EXCEPTION("Unknown solver type provided");
02082 }
02083
02084 void HeartConfig::SetKSPPreconditioner(const char* kspPreconditioner)
02085 {
02086
02087 if ( strcmp(kspPreconditioner, "ilu") == 0)
02088 {
02089 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::ilu);
02090 return;
02091 }
02092 if ( strcmp(kspPreconditioner, "jacobi") == 0)
02093 {
02094 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::jacobi);
02095 return;
02096 }
02097 if ( strcmp(kspPreconditioner, "bjacobi") == 0)
02098 {
02099 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::bjacobi);
02100 return;
02101 }
02102 if ( strcmp(kspPreconditioner, "hypre") == 0)
02103 {
02104 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::hypre);
02105 return;
02106 }
02107 if ( strcmp(kspPreconditioner, "ml") == 0)
02108 {
02109 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::ml);
02110 return;
02111 }
02112 if ( strcmp(kspPreconditioner, "spai") == 0)
02113 {
02114 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::spai);
02115 return;
02116 }
02117 if ( strcmp(kspPreconditioner, "blockdiagonal") == 0)
02118 {
02119 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::blockdiagonal);
02120 return;
02121 }
02122 if ( strcmp(kspPreconditioner, "ldufactorisation") == 0)
02123 {
02124 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::ldufactorisation);
02125 return;
02126 }
02127 if ( strcmp(kspPreconditioner, "none") == 0)
02128 {
02129 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::none);
02130 return;
02131 }
02132
02133 EXCEPTION("Unknown preconditioner type provided");
02134 }
02135
02136 void HeartConfig::SetAdaptivityParameters(double targetError,
02137 double sigma,
02138 double maxEdgeLength,
02139 double minEdgeLength,
02140 double gradation,
02141 unsigned maxNodes,
02142 unsigned numSweeps )
02143 {
02144 if ( maxEdgeLength < minEdgeLength )
02145 {
02146 EXCEPTION("AdaptivityParameters: maxEdgeLength must be greater than minEdgeLength.");
02147 }
02148 if (!IsAdaptivityParametersPresent())
02149 {
02150 cp::adaptivity_parameters_type element(targetError,
02151 sigma,
02152 maxEdgeLength,
02153 minEdgeLength,
02154 gradation,
02155 maxNodes,
02156 numSweeps );
02157 mpUserParameters->Numerical().AdaptivityParameters().set(element);
02158 }
02159 else
02160 {
02161 mpUserParameters->Numerical().AdaptivityParameters().get().target_error(targetError);
02162 mpUserParameters->Numerical().AdaptivityParameters().get().sigma(sigma);
02163 mpUserParameters->Numerical().AdaptivityParameters().get().max_edge_length(maxEdgeLength);
02164 mpUserParameters->Numerical().AdaptivityParameters().get().min_edge_length(minEdgeLength);
02165 mpUserParameters->Numerical().AdaptivityParameters().get().gradation(gradation);
02166 mpUserParameters->Numerical().AdaptivityParameters().get().max_nodes(maxNodes);
02167 mpUserParameters->Numerical().AdaptivityParameters().get().num_sweeps(numSweeps);
02168 }
02169 }
02170
02171 void HeartConfig::SetTargetErrorForAdaptivity(double targetError)
02172 {
02173 SetAdaptivityParameters( targetError,
02174 GetSigmaForAdaptivity(),
02175 GetMaxEdgeLengthForAdaptivity(),
02176 GetMinEdgeLengthForAdaptivity(),
02177 GetGradationForAdaptivity(),
02178 GetMaxNodesForAdaptivity(),
02179 GetNumberOfAdaptiveSweeps() );
02180 }
02181
02182 void HeartConfig::SetSigmaForAdaptivity(double sigma)
02183 {
02184 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02185 sigma,
02186 GetMaxEdgeLengthForAdaptivity(),
02187 GetMinEdgeLengthForAdaptivity(),
02188 GetGradationForAdaptivity(),
02189 GetMaxNodesForAdaptivity(),
02190 GetNumberOfAdaptiveSweeps() );
02191 }
02192
02193 void HeartConfig::SetMaxEdgeLengthForAdaptivity(double maxEdgeLength)
02194 {
02195 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02196 GetSigmaForAdaptivity(),
02197 maxEdgeLength,
02198 GetMinEdgeLengthForAdaptivity(),
02199 GetGradationForAdaptivity(),
02200 GetMaxNodesForAdaptivity(),
02201 GetNumberOfAdaptiveSweeps() );
02202 }
02203
02204 void HeartConfig::SetMinEdgeLengthForAdaptivity(double minEdgeLength)
02205 {
02206 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02207 GetSigmaForAdaptivity(),
02208 GetMaxEdgeLengthForAdaptivity(),
02209 minEdgeLength,
02210 GetGradationForAdaptivity(),
02211 GetMaxNodesForAdaptivity(),
02212 GetNumberOfAdaptiveSweeps() );
02213 }
02214
02215 void HeartConfig::SetGradationForAdaptivity(double gradation)
02216 {
02217 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02218 GetSigmaForAdaptivity(),
02219 GetMaxEdgeLengthForAdaptivity(),
02220 GetMinEdgeLengthForAdaptivity(),
02221 gradation,
02222 GetMaxNodesForAdaptivity(),
02223 GetNumberOfAdaptiveSweeps() );
02224 }
02225
02226 void HeartConfig::SetMaxNodesForAdaptivity(unsigned maxNodes)
02227 {
02228 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02229 GetSigmaForAdaptivity(),
02230 GetMaxEdgeLengthForAdaptivity(),
02231 GetMinEdgeLengthForAdaptivity(),
02232 GetGradationForAdaptivity(),
02233 maxNodes,
02234 GetNumberOfAdaptiveSweeps() );
02235 }
02236
02237 void HeartConfig::SetNumberOfAdaptiveSweeps(unsigned numSweeps)
02238 {
02239 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02240 GetSigmaForAdaptivity(),
02241 GetMaxEdgeLengthForAdaptivity(),
02242 GetMinEdgeLengthForAdaptivity(),
02243 GetGradationForAdaptivity(),
02244 GetMaxNodesForAdaptivity(),
02245 numSweeps );
02246 }
02247
02248 void HeartConfig::SetApdMaps(const std::vector<std::pair<double,double> >& apdMaps)
02249 {
02250 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ActionPotentialDurationMap)& apd_maps_sequence
02251 = mpUserParameters->PostProcessing()->ActionPotentialDurationMap();
02252
02253 apd_maps_sequence.clear();
02254
02255 for (unsigned i=0; i<apdMaps.size(); i++)
02256 {
02257 XSD_CREATE_WITH_FIXED_ATTR2(cp::apd_map_type, temp,
02258 apdMaps[i].first, apdMaps[i].second,
02259 "mV");
02260 apd_maps_sequence.push_back( temp);
02261 }
02262 }
02263
02264
02265 void HeartConfig::SetUpstrokeTimeMaps (std::vector<double>& upstrokeTimeMaps)
02266 {
02267 XSD_SEQUENCE_TYPE(cp::postprocessing_type::UpstrokeTimeMap)& var_type_sequence
02268 = mpUserParameters->PostProcessing()->UpstrokeTimeMap();
02269
02270
02271 var_type_sequence.clear();
02272
02273 for (unsigned i=0; i<upstrokeTimeMaps.size(); i++)
02274 {
02275 XSD_CREATE_WITH_FIXED_ATTR1(cp::upstrokes_map_type, temp,
02276 upstrokeTimeMaps[i],
02277 "mV");
02278 var_type_sequence.push_back(temp);
02279 }
02280 }
02281
02282 void HeartConfig::SetMaxUpstrokeVelocityMaps (std::vector<double>& maxUpstrokeVelocityMaps)
02283 {
02284 XSD_SEQUENCE_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap)& max_upstroke_velocity_maps_sequence
02285 = mpUserParameters->PostProcessing()->MaxUpstrokeVelocityMap();
02286
02287
02288 max_upstroke_velocity_maps_sequence.clear();
02289
02290 for (unsigned i=0; i<maxUpstrokeVelocityMaps.size(); i++)
02291 {
02292 XSD_CREATE_WITH_FIXED_ATTR1(cp::max_upstrokes_velocity_map_type, temp,
02293 maxUpstrokeVelocityMaps[i],
02294 "mV");
02295
02296
02297 max_upstroke_velocity_maps_sequence.push_back(temp);
02298 }
02299
02300 }
02301
02302 void HeartConfig::SetConductionVelocityMaps (std::vector<unsigned>& conductionVelocityMaps)
02303 {
02304 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ConductionVelocityMap)& conduction_velocity_maps_sequence
02305 = mpUserParameters->PostProcessing()->ConductionVelocityMap();
02306
02307
02308 conduction_velocity_maps_sequence.clear();
02309
02310 for (unsigned i=0; i<conductionVelocityMaps.size(); i++)
02311 {
02312 cp::conduction_velocity_map_type temp(conductionVelocityMaps[i]);
02313 conduction_velocity_maps_sequence.push_back(temp);
02314 }
02315 }
02316
02317
02318
02319
02320
02321 void HeartConfig::EnsureOutputVisualizerExists()
02322 {
02323 if (!IsOutputVisualizerPresent())
02324 {
02325 cp::output_visualizer_type element;
02326 mpUserParameters->Simulation().get().OutputVisualizer().set(element);
02327 }
02328 }
02329
02330 void HeartConfig::SetVisualizeWithMeshalyzer(bool useMeshalyzer)
02331 {
02332 EnsureOutputVisualizerExists();
02333
02334 mpUserParameters->Simulation().get().OutputVisualizer().get().meshalyzer(
02335 useMeshalyzer ? cp::yesno_type::yes : cp::yesno_type::no);
02336 }
02337
02338 void HeartConfig::SetVisualizeWithCmgui(bool useCmgui)
02339 {
02340 EnsureOutputVisualizerExists();
02341
02342 mpUserParameters->Simulation().get().OutputVisualizer().get().cmgui(
02343 useCmgui ? cp::yesno_type::yes : cp::yesno_type::no);
02344 }
02345
02346 void HeartConfig::SetVisualizeWithVtk(bool useVtk)
02347 {
02348 EnsureOutputVisualizerExists();
02349
02350 mpUserParameters->Simulation().get().OutputVisualizer().get().vtk(
02351 useVtk ? cp::yesno_type::yes : cp::yesno_type::no);
02352 }
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362 #include <string>
02363 #include <istream>
02364 #include <fstream>
02365
02366 #include <xercesc/util/XMLUniDefs.hpp>
02367 #include <xercesc/framework/Wrapper4InputSource.hpp>
02368 #include <xercesc/validators/common/Grammar.hpp>
02369
02370 #include <xsd/cxx/xml/string.hxx>
02371 #include <xsd/cxx/xml/dom/auto-ptr.hxx>
02372 #include <xsd/cxx/xml/sax/std-input-source.hxx>
02373 #include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
02374
02375 #include <xsd/cxx/tree/exceptions.hxx>
02376 #include <xsd/cxx/tree/error-handler.hxx>
02377
02378
02379 xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument> HeartConfig::ReadFileToDomDocument(
02380 const std::string& rFileName,
02381 ::xml_schema::error_handler& rErrorHandler,
02382 const ::xml_schema::properties& rProps)
02383 {
02384 using namespace xercesc;
02385 namespace xml = xsd::cxx::xml;
02386 namespace tree = xsd::cxx::tree;
02387
02388
02389 const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
02390 DOMImplementation* p_impl(DOMImplementationRegistry::getDOMImplementation(ls_id));
02391
02392 #if _XERCES_VERSION >= 30000
02393
02394 xml::dom::auto_ptr<DOMLSParser> p_parser(p_impl->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
02395 DOMConfiguration* p_conf(p_parser->getDomConfig());
02396
02397
02398 p_conf->setParameter(XMLUni::fgDOMComments, false);
02399
02400
02401 p_conf->setParameter(XMLUni::fgDOMDatatypeNormalization, true);
02402
02403
02404
02405
02406
02407 p_conf->setParameter(XMLUni::fgDOMEntities, false);
02408
02409
02410 p_conf->setParameter(XMLUni::fgDOMNamespaces, true);
02411
02412
02413 p_conf->setParameter(XMLUni::fgDOMElementContentWhitespace, false);
02414
02415
02416 p_conf->setParameter(XMLUni::fgDOMValidate, true);
02417 p_conf->setParameter(XMLUni::fgXercesSchema, true);
02418 p_conf->setParameter(XMLUni::fgXercesSchemaFullChecking, false);
02419
02420 if (!rProps.schema_location().empty())
02421 {
02422 xml::string locn(rProps.schema_location());
02423 const void* p_locn(locn.c_str());
02424 p_conf->setParameter(XMLUni::fgXercesSchemaExternalSchemaLocation,
02425 const_cast<void*>(p_locn));
02426 }
02427 if (!rProps.no_namespace_schema_location().empty())
02428 {
02429 xml::string locn(rProps.no_namespace_schema_location());
02430 const void* p_locn(locn.c_str());
02431
02432 p_conf->setParameter(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
02433 const_cast<void*>(p_locn));
02434 }
02435
02436
02437 p_conf->setParameter(XMLUni::fgXercesUserAdoptsDOMDocument, true);
02438
02439
02440 xml::dom::bits::error_handler_proxy<char> ehp(rErrorHandler);
02441 p_conf->setParameter(XMLUni::fgDOMErrorHandler, &ehp);
02442
02443 #else // _XERCES_VERSION >= 30000
02444
02445 xml::dom::auto_ptr<DOMBuilder> p_parser(p_impl->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
02446
02447 p_parser->setFeature(XMLUni::fgDOMComments, false);
02448 p_parser->setFeature(XMLUni::fgDOMDatatypeNormalization, true);
02449 p_parser->setFeature(XMLUni::fgDOMEntities, false);
02450 p_parser->setFeature(XMLUni::fgDOMNamespaces, true);
02451 p_parser->setFeature(XMLUni::fgDOMWhitespaceInElementContent, false);
02452 p_parser->setFeature(XMLUni::fgDOMValidation, true);
02453 p_parser->setFeature(XMLUni::fgXercesSchema, true);
02454 p_parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
02455 p_parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument, true);
02456
02457
02458 if (!rProps.schema_location().empty())
02459 {
02460 xml::string locn(rProps.schema_location());
02461 const void* p_locn(locn.c_str());
02462 p_parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,
02463 const_cast<void*>(p_locn));
02464 }
02465
02466 if (!rProps.no_namespace_schema_location().empty())
02467 {
02468 xml::string locn(rProps.no_namespace_schema_location());
02469 const void* p_locn(locn.c_str());
02470
02471 p_parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
02472 const_cast<void*>(p_locn));
02473 }
02474
02475 xml::dom::bits::error_handler_proxy<char> ehp(rErrorHandler);
02476 p_parser->setErrorHandler(&ehp);
02477
02478 #endif // _XERCES_VERSION >= 30000
02479
02480
02481 xml::dom::auto_ptr<DOMDocument> p_doc(p_parser->parseURI(rFileName.c_str()));
02482
02483 if (ehp.failed())
02484 {
02485 p_doc.reset();
02486 }
02487
02488 return p_doc;
02489 }
02490
02491 xercesc::DOMElement* HeartConfig::AddNamespace(xercesc::DOMDocument* pDocument,
02492 xercesc::DOMElement* pElement,
02493 const XMLCh* pNamespace)
02494 {
02495 using namespace xercesc;
02496
02497 DOMElement* p_new_elt = static_cast<DOMElement*>(
02498 pDocument->renameNode(pElement, pNamespace, pElement->getLocalName()));
02499
02500 for (DOMNode* p_node = p_new_elt->getFirstChild();
02501 p_node != NULL;
02502 p_node = p_node->getNextSibling())
02503 {
02504 if (p_node->getNodeType() == DOMNode::ELEMENT_NODE)
02505 {
02506 p_node = AddNamespace(pDocument, static_cast<DOMElement*>(p_node), pNamespace);
02507 }
02508 }
02509
02510 return p_new_elt;
02511 }
02512
02513 xercesc::DOMElement* HeartConfig::AddNamespace(xercesc::DOMDocument* pDocument,
02514 xercesc::DOMElement* pElement,
02515 const std::string& rNamespace)
02516 {
02517 return AddNamespace(pDocument, pElement, xsd::cxx::xml::string(rNamespace).c_str());
02518 }
02519
02526 class XStr
02527 {
02528 public :
02533 XStr(const char* const toTranscode)
02534 {
02535
02536 mUnicodeForm = xercesc::XMLString::transcode(toTranscode);
02537 }
02538
02540 ~XStr()
02541 {
02542 xercesc::XMLString::release(&mUnicodeForm);
02543 }
02544
02545
02547 const XMLCh* UnicodeForm() const
02548 {
02549 return mUnicodeForm;
02550 }
02551
02552 private :
02554 XMLCh* mUnicodeForm;
02555 };
02556
02557
02558 #define X(str) xsd::cxx::xml::string(str).c_str()
02559
02560
02561 void HeartConfig::TransformIonicModelDefinitions(xercesc::DOMDocument* pDocument,
02562 xercesc::DOMElement* pRootElement)
02563 {
02564 xercesc::DOMNodeList* p_sim_elt_list = pRootElement->getElementsByTagName(X("Simulation"));
02565 if (p_sim_elt_list->getLength() > 0)
02566 {
02567 xercesc::DOMElement* p_sim_elt = static_cast<xercesc::DOMElement*>(p_sim_elt_list->item(0));
02568 xercesc::DOMNodeList* p_ionic_models_elt_list = p_sim_elt->getElementsByTagName(X("IonicModels"));
02569 if (p_ionic_models_elt_list->getLength() > 0)
02570 {
02571 xercesc::DOMElement* p_ionic_models_elt = static_cast<xercesc::DOMElement*>(p_ionic_models_elt_list->item(0));
02572
02573 xercesc::DOMNodeList* p_default_list = p_ionic_models_elt->getElementsByTagName(X("Default"));
02574 assert(p_default_list->getLength() > 0);
02575 xercesc::DOMElement* p_default_elt = static_cast<xercesc::DOMElement*>(p_default_list->item(0));
02576 WrapContentInElement(pDocument, p_default_elt, X("Hardcoded"));
02577
02578 xercesc::DOMNodeList* p_region_list = p_ionic_models_elt->getElementsByTagName(X("Region"));
02579 for (unsigned i=0; i<p_region_list->getLength(); i++)
02580 {
02581 xercesc::DOMElement* p_region_elt = static_cast<xercesc::DOMElement*>(p_region_list->item(0));
02582 xercesc::DOMNodeList* p_ionic_model_list = p_region_elt->getElementsByTagName(X("IonicModel"));
02583 assert(p_ionic_model_list->getLength() > 0);
02584 xercesc::DOMElement* p_ionic_model_elt = static_cast<xercesc::DOMElement*>(p_ionic_model_list->item(0));
02585 WrapContentInElement(pDocument, p_ionic_model_elt, X("Hardcoded"));
02586 }
02587 }
02588 }
02589 }
02590
02591 void HeartConfig::WrapContentInElement(xercesc::DOMDocument* pDocument,
02592 xercesc::DOMElement* pElement,
02593 const XMLCh* pNewElementLocalName)
02594 {
02595 const XMLCh* p_namespace_uri = pElement->getNamespaceURI();
02596 const XMLCh* p_prefix = pElement->getPrefix();
02597 const XMLCh* p_qualified_name;
02598 if (p_prefix)
02599 {
02600 #define COVERAGE_IGNORE
02601
02602
02603 xercesc::QName qname(p_prefix, pNewElementLocalName, 0);
02604 p_qualified_name = qname.getRawName();
02605 #undef COVERAGE_IGNORE
02606 }
02607 else
02608 {
02609 p_qualified_name = pNewElementLocalName;
02610 }
02611 xercesc::DOMElement* p_wrapper_elt = pDocument->createElementNS(p_namespace_uri, p_qualified_name);
02612
02613 xercesc::DOMNodeList* p_children = pElement->getChildNodes();
02614 for (unsigned i=0; i<p_children->getLength(); i++)
02615 {
02616 xercesc::DOMNode* p_child = pElement->removeChild(p_children->item(i));
02617 p_wrapper_elt->appendChild(p_child);
02618 }
02619
02620 pElement->appendChild(p_wrapper_elt);
02621 }
02622
02624
02626 #define COVERAGE_IGNORE //These methods are covered above with DIM=1,2,3 but the instantiations may fail spuriously
02627
02631 template void HeartConfig::GetIonicModelRegions<3u>(std::vector<ChasteCuboid<3u> >& , std::vector<cp::ionic_model_selection_type>&) const;
02632 template void HeartConfig::GetStimuli<3u>(std::vector<boost::shared_ptr<SimpleStimulus> >& , std::vector<ChasteCuboid<3u> >& ) const;
02633 template void HeartConfig::GetCellHeterogeneities<3u>(std::vector<AbstractChasteRegion<3u>* >& ,std::vector<double>& ,std::vector<double>& ,std::vector<double>& ) ;
02634 template void HeartConfig::GetConductivityHeterogeneities<3u>(std::vector<ChasteCuboid<3u> >& ,std::vector< c_vector<double,3> >& ,std::vector< c_vector<double,3> >& ) const;
02635
02636 template void HeartConfig::GetIonicModelRegions<2u>(std::vector<ChasteCuboid<2u> >& , std::vector<cp::ionic_model_selection_type>&) const;
02637 template void HeartConfig::GetStimuli<2u>(std::vector<boost::shared_ptr<SimpleStimulus> >& , std::vector<ChasteCuboid<2u> >& ) const;
02638 template void HeartConfig::GetCellHeterogeneities<2u>(std::vector<AbstractChasteRegion<2u>* >& ,std::vector<double>& ,std::vector<double>& ,std::vector<double>& ) ;
02639 template void HeartConfig::GetConductivityHeterogeneities<2u>(std::vector<ChasteCuboid<2u> >& ,std::vector< c_vector<double,3> >& ,std::vector< c_vector<double,3> >& ) const;
02640
02641 template void HeartConfig::GetIonicModelRegions<1u>(std::vector<ChasteCuboid<1u> >& , std::vector<cp::ionic_model_selection_type>&) const;
02642 template void HeartConfig::GetStimuli<1u>(std::vector<boost::shared_ptr<SimpleStimulus> >& , std::vector<ChasteCuboid<1u> >& ) const;
02643 template void HeartConfig::GetCellHeterogeneities<1u>(std::vector<AbstractChasteRegion<1u>* >& ,std::vector<double>& ,std::vector<double>& ,std::vector<double>& );
02644 template void HeartConfig::GetConductivityHeterogeneities<1u>(std::vector<ChasteCuboid<1u> >& ,std::vector< c_vector<double,3> >& ,std::vector< c_vector<double,3> >& ) const;
02649 #undef COVERAGE_IGNORE //These methods are covered above with DIM=1,2,3 but the instantiations may fail spuriously
02650
02651
02652
02653 #include "SerializationExportWrapperForCpp.hpp"
02654 CHASTE_CLASS_EXPORT(HeartConfig);