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 #include "HeartFileFinder.hpp"
00041 #include "Warnings.hpp"
00042
00043 #include "SimpleStimulus.hpp"
00044 #include "RegularStimulus.hpp"
00045
00046 #include <string>
00047 #include <istream>
00048 #include <fstream>
00049 #include <cassert>
00050
00051 #include <xercesc/util/PlatformUtils.hpp>
00052 #include <xercesc/util/QName.hpp>
00053 #include <xercesc/util/XMLUniDefs.hpp>
00054 #include <xercesc/framework/Wrapper4InputSource.hpp>
00055 #include <xercesc/validators/common/Grammar.hpp>
00056 #include <xercesc/dom/DOMNamedNodeMap.hpp>
00057 #include <xercesc/dom/DOMXPathEvaluator.hpp>
00058 #include <xercesc/dom/DOMXPathResult.hpp>
00059
00060 #include <xsd/cxx/xml/string.hxx>
00061 #include <xsd/cxx/xml/dom/auto-ptr.hxx>
00062 #include <xsd/cxx/xml/sax/std-input-source.hxx>
00063 #include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
00064 #include <xsd/cxx/tree/exceptions.hxx>
00065 #include <xsd/cxx/tree/error-handler.hxx>
00066
00067
00068 using namespace xsd::cxx::tree;
00069
00070
00071
00072 #if (XSD_INT_VERSION >= 3000000L)
00073 #define XSD_SEQUENCE_TYPE(base) base##_sequence
00074 #define XSD_ITERATOR_TYPE(base) base##_iterator
00075 #define XSD_NESTED_TYPE(t) t##_type
00076 #define XSD_ANON_TYPE(t1, t2) \
00077 t1::t2##_type
00078 #else
00079 #define XSD_SEQUENCE_TYPE(base) base::container
00080 #define XSD_ITERATOR_TYPE(base) base::iterator
00081 #define XSD_NESTED_TYPE(t) t::type
00082 #define XSD_ANON_TYPE(t1, t2) \
00083 t1::t2::_xsd_##t2##_::t2
00084 #endif
00085
00086
00087 #define XSD_ANON_SEQUENCE_TYPE(t1, t2, t3) \
00088 XSD_SEQUENCE_TYPE(XSD_ANON_TYPE(t1, t2)::t3)
00089 #define XSD_ANON_ITERATOR_TYPE(t1, t2, t3) \
00090 XSD_ITERATOR_TYPE(XSD_ANON_TYPE(t1, t2)::t3)
00091
00092
00093 #if (XSD_INT_VERSION >= 3020000L)
00094 #define XSD_CREATE_WITH_FIXED_ATTR(type, name, attr) \
00095 type name
00096 #define XSD_CREATE_WITH_FIXED_ATTR1(type, name, arg1, attr) \
00097 type name(arg1)
00098 #define XSD_CREATE_WITH_FIXED_ATTR2(type, name, arg1, arg2, attr) \
00099 type name(arg1, arg2)
00100 #define XSD_CREATE_WITH_FIXED_ATTR3(type, name, arg1, arg2, arg3, attr) \
00101 type name(arg1, arg2, arg3)
00102 #else
00103 #define XSD_CREATE_WITH_FIXED_ATTR(type, name, attr) \
00104 type name(attr)
00105 #define XSD_CREATE_WITH_FIXED_ATTR1(type, name, arg1, attr) \
00106 type name(arg1, attr)
00107 #define XSD_CREATE_WITH_FIXED_ATTR2(type, name, arg1, arg2, attr) \
00108 type name(arg1, arg2, attr)
00109 #define XSD_CREATE_WITH_FIXED_ATTR3(type, name, arg1, arg2, arg3, attr) \
00110 type name(arg1, arg2, arg3, attr)
00111 #endif
00112
00117 #define X(str) xsd::cxx::xml::string(str).c_str()
00118
00122 #define ENSURE_SECTION_PRESENT(location, type) \
00123 if (!location.present()) \
00124 { \
00125 type empty_item; \
00126 location.set(empty_item); \
00127 }
00128
00129
00133 class XmlTools
00134 {
00135 public:
00149 static xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument> ReadFileToDomDocument(
00150 const std::string& rFileName,
00151 ::xml_schema::error_handler& rErrorHandler,
00152 const ::xml_schema::properties& rProps);
00153
00161 static void PrintNode(const std::string& rMsg, xercesc::DOMNode* pNode, bool showChildren=false);
00162
00173 static xercesc::DOMElement* SetNamespace(xercesc::DOMDocument* pDocument,
00174 xercesc::DOMElement* pElement,
00175 const std::string& rNamespace);
00176
00187 static xercesc::DOMElement* SetNamespace(xercesc::DOMDocument* pDocument,
00188 xercesc::DOMElement* pElement,
00189 const XMLCh* pNamespace);
00190
00202 static void WrapContentInElement(xercesc::DOMDocument* pDocument,
00203 xercesc::DOMElement* pElement,
00204 const XMLCh* pNewElementLocalName);
00205
00212 static std::vector<xercesc::DOMElement*> FindElements(xercesc::DOMElement* pContextElement,
00213 const std::string& rPath);
00214
00224 static void FindElements(xercesc::DOMElement* pContextElement,
00225 const std::vector<std::string>& rNames,
00226 std::vector<xercesc::DOMElement*>& rResults,
00227 unsigned depth=0);
00228 };
00229
00234 class XmlTransforms
00235 {
00236 public:
00244 static void TransformIonicModelDefinitions(xercesc::DOMDocument* pDocument,
00245 xercesc::DOMElement* pRootElement);
00246
00255 static void TransformArchiveDirectory(xercesc::DOMDocument* pDocument,
00256 xercesc::DOMElement* pRootElement);
00257
00265 static void CheckForIluPreconditioner(xercesc::DOMDocument* pDocument,
00266 xercesc::DOMElement* pRootElement);
00267 };
00268
00269
00270
00271
00272 #include "HeartConfigDefaults.hpp"
00273
00274
00275
00276
00277 std::auto_ptr<HeartConfig> HeartConfig::mpInstance;
00278
00279
00280
00281
00282
00283 HeartConfig* HeartConfig::Instance()
00284 {
00285 if (mpInstance.get() == NULL)
00286 {
00287 mpInstance.reset(new HeartConfig);
00288 }
00289 return mpInstance.get();
00290 }
00291
00292 HeartConfig::HeartConfig()
00293 {
00294 assert(mpInstance.get() == NULL);
00295 mUseFixedSchemaLocation = true;
00296 SetDefaultSchemaLocations();
00297
00298 mpDefaultParameters = CreateDefaultParameters();
00299 mpUserParameters = mpDefaultParameters;
00300
00301
00302
00303 mEpiFraction = -1.0;
00304 mEndoFraction = -1.0;
00305 mMidFraction = -1.0;
00306 mUserAskedForCellularTransmuralHeterogeneities=false;
00307 mUserAskedForCuboidsForCellularHeterogeneities=false;
00308
00309
00310
00311 mIndexMid = UINT_MAX-3u;
00312 mIndexEpi = UINT_MAX-3u;
00313 mIndexEndo = UINT_MAX-3u;
00314 }
00315
00316 HeartConfig::~HeartConfig()
00317 {
00318 }
00319
00320 void HeartConfig::SetDefaultsFile(const std::string& rFileName)
00321 {
00322 bool same_target = (mpUserParameters == mpDefaultParameters);
00323
00324 mpDefaultParameters = ReadFile(rFileName);
00325
00326 if (same_target)
00327 {
00328 mpUserParameters = mpDefaultParameters;
00329 }
00330 CheckTimeSteps();
00331 }
00332
00333 void HeartConfig::Write(bool useArchiveLocationInfo, std::string subfolderName)
00334 {
00335
00336 std::string output_dirname;
00337 if (useArchiveLocationInfo)
00338 {
00339 output_dirname = ArchiveLocationInfo::GetArchiveDirectory();
00340 }
00341 else
00342 {
00343 OutputFileHandler handler(GetOutputDirectory() + "/" + subfolderName, false);
00344 output_dirname = handler.GetOutputDirectoryFullPath();
00345 }
00346 if (!PetscTools::AmMaster())
00347 {
00348
00349 return;
00350 }
00351 out_stream p_defaults_file( new std::ofstream( (output_dirname+"ChasteDefaults.xml").c_str() ) );
00352 out_stream p_parameters_file( new std::ofstream( (output_dirname+"ChasteParameters.xml").c_str() ) );
00353
00354 if (!p_defaults_file->is_open() || !p_parameters_file->is_open())
00355 {
00356 EXCEPTION("Could not open XML file in HeartConfig");
00357 }
00358
00359
00360
00361 ::xml_schema::namespace_infomap map;
00362
00363 map[""].schema = "ChasteParameters_1_1.xsd";
00364
00365 map["cp20"].name = "https://chaste.comlab.ox.ac.uk/nss/parameters/2_0";
00366 map["cp20"].schema = "ChasteParameters_2_0.xsd";
00367
00368
00369 map["cp"].name = "https://chaste.comlab.ox.ac.uk/nss/parameters/2_1";
00370 map["cp"].schema = "ChasteParameters_2_1.xsd";
00371
00372 cp::ChasteParameters(*p_parameters_file, *mpUserParameters, map);
00373 cp::ChasteParameters(*p_defaults_file, *mpDefaultParameters, map);
00374
00375
00376 if (useArchiveLocationInfo)
00377 {
00378 CopySchema(output_dirname);
00379 }
00380 }
00381
00382 void HeartConfig::CopySchema(const std::string& rToDirectory)
00383 {
00384 std::string schema_name("ChasteParameters_2_1.xsd");
00385 FileFinder schema_location("heart/src/io/" + schema_name, RelativeTo::ChasteSourceRoot);
00386 if (!schema_location.Exists())
00387 {
00388
00389 schema_location.SetPath(schema_name, RelativeTo::CWD);
00390 if (!schema_location.Exists())
00391 {
00392
00393 std::string message("Unable to locate schema file " + schema_name +
00394 ". You will need to ensure it is available when resuming from the checkpoint.");
00395 WARN_ONCE_ONLY(message);
00396 }
00397 }
00398 if (schema_location.Exists())
00399 {
00400 system(("cp " + schema_location.GetAbsolutePath() + " " + rToDirectory).c_str());
00401 }
00402 }
00403
00404 void HeartConfig::SetDefaultSchemaLocations()
00405 {
00406 mSchemaLocations.clear();
00407
00408 std::string root_dir = std::string(ChasteBuildInfo::GetRootDir()) + "/heart/src/io/";
00409
00410 mSchemaLocations[""] = root_dir + "ChasteParameters_1_1.xsd";
00411
00412 mSchemaLocations["https://chaste.comlab.ox.ac.uk/nss/parameters/2_0"] = root_dir + "ChasteParameters_2_0.xsd";
00413 mSchemaLocations["https://chaste.comlab.ox.ac.uk/nss/parameters/2_1"] = root_dir + "ChasteParameters_2_1.xsd";
00414 }
00415
00416 unsigned HeartConfig::GetVersionFromNamespace(const std::string& rNamespaceUri)
00417 {
00418 unsigned version_major = 0;
00419 unsigned version_minor = 0;
00420 if (rNamespaceUri == "")
00421 {
00422 version_major = 1;
00423 version_minor = 1;
00424 }
00425 else
00426 {
00427 std::string uri_base("https://chaste.comlab.ox.ac.uk/nss/parameters/");
00428 if (rNamespaceUri.substr(0, uri_base.length()) == uri_base)
00429 {
00430 std::istringstream version_string(rNamespaceUri.substr(uri_base.length()));
00431 version_string >> version_major;
00432 version_string.ignore(1);
00433 version_string >> version_minor;
00434 if (version_string.fail())
00435 {
00436 version_major = 0;
00437 version_minor = 0;
00438 }
00439 }
00440 }
00441
00442 unsigned version = version_major * 1000 + version_minor;
00443 if (version == 0)
00444 {
00445 EXCEPTION(rNamespaceUri + " is not a recognised Chaste parameters namespace.");
00446 }
00447 return version;
00448 }
00449
00450 void HeartConfig::SetFixedSchemaLocations(const SchemaLocationsMap& rSchemaLocations)
00451 {
00452 mSchemaLocations = rSchemaLocations;
00453 SetUseFixedSchemaLocation(true);
00454 }
00455
00456 void HeartConfig::SetUseFixedSchemaLocation(bool useFixedSchemaLocation)
00457 {
00458 mUseFixedSchemaLocation = useFixedSchemaLocation;
00459 }
00460
00461 std::string HeartConfig::EscapeSpaces(const std::string& rPath)
00462 {
00463 std::string escaped_path;
00464 for (std::string::const_iterator it = rPath.begin(); it != rPath.end(); ++it)
00465 {
00466 if (*it == ' ')
00467 {
00468 escaped_path += "%20";
00469 }
00470 else
00471 {
00472 escaped_path += *it;
00473 }
00474 }
00475 return escaped_path;
00476 }
00477
00478 boost::shared_ptr<cp::chaste_parameters_type> HeartConfig::ReadFile(const std::string& rFileName)
00479 {
00480
00481 ::xml_schema::properties props;
00482 if (mUseFixedSchemaLocation)
00483 {
00484 for (SchemaLocationsMap::iterator it = mSchemaLocations.begin();
00485 it != mSchemaLocations.end();
00486 ++it)
00487 {
00488 if (it->first == "")
00489 {
00490 props.no_namespace_schema_location(EscapeSpaces(it->second));
00491 }
00492 else
00493 {
00494 props.schema_location(it->first, EscapeSpaces(it->second));
00495 }
00496 }
00497 }
00498
00499
00500
00501 try
00502 {
00503
00504 ::xsd::cxx::xml::auto_initializer init_fini(true, true);
00505
00506 ::xsd::cxx::tree::error_handler<char> error_handler;
00507
00508 xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument> p_doc = XmlTools::ReadFileToDomDocument(rFileName, error_handler, props);
00509
00510 error_handler.throw_if_failed< ::xsd::cxx::tree::parsing< char > >();
00511
00512 xercesc::DOMElement* p_root_elt = p_doc->getDocumentElement();
00513 std::string namespace_uri(xsd::cxx::xml::transcode<char>(p_root_elt->getNamespaceURI()));
00514 switch (GetVersionFromNamespace(namespace_uri))
00515 {
00516 case 1001:
00517 XmlTransforms::TransformIonicModelDefinitions(p_doc.get(), p_root_elt);
00518 case 2000:
00519 XmlTransforms::TransformArchiveDirectory(p_doc.get(), p_root_elt);
00520 XmlTransforms::CheckForIluPreconditioner(p_doc.get(), p_root_elt);
00521 XmlTools::SetNamespace(p_doc.get(), p_root_elt, "https://chaste.comlab.ox.ac.uk/nss/parameters/2_1");
00522 default:
00523 break;
00524 }
00525
00526 std::auto_ptr<cp::chaste_parameters_type> p_params(cp::ChasteParameters(*p_doc, ::xml_schema::flags::dont_initialize, props));
00527
00528 p_doc.reset();
00529
00530 return boost::shared_ptr<cp::chaste_parameters_type>(p_params);
00531 }
00532 catch (const xml_schema::parsing& e)
00533 {
00534
00535 mpUserParameters.reset();
00536 mpDefaultParameters.reset();
00537
00538 #if (XSD_INT_VERSION >= 3000000L)
00539 const xml_schema::diagnostics& diags = e.diagnostics();
00540 const xml_schema::error& first_error = diags[0];
00541 #else
00542 const xml_schema::errors& errors = e.errors();
00543 const xml_schema::error& first_error = errors[0];
00544 #endif
00545 if (first_error.line() == 0u)
00546 {
00547 std::cerr << first_error << std::endl;
00548 EXCEPTION("Missing file parsing configuration file: " + rFileName);
00549 }
00550 else
00551 {
00552 std::cerr << e << std::endl;
00553 EXCEPTION("XML parsing error in configuration file: " + rFileName);
00554 }
00555 }
00556 catch (const xml_schema::exception& e)
00557 {
00558 std::cerr << e << std::endl;
00559
00560 mpUserParameters.reset();
00561 mpDefaultParameters.reset();
00562 EXCEPTION("XML parsing error in configuration file: " + rFileName);
00563 }
00564 }
00565
00566 void HeartConfig::SetParametersFile(const std::string& rFileName)
00567 {
00568 mpUserParameters = ReadFile(rFileName);
00569
00570 CheckTimeSteps();
00571 }
00572
00573
00574 void HeartConfig::UpdateParametersFromResumeSimulation(boost::shared_ptr<cp::chaste_parameters_type> pResumeParameters)
00575 {
00576
00577 if ( (pResumeParameters->ResumeSimulation()->SpaceDimension() != HeartConfig::Instance()->GetSpaceDimension())
00578 ||(pResumeParameters->ResumeSimulation()->Domain() != HeartConfig::Instance()->GetDomain()))
00579 {
00580 EXCEPTION("Problem type and space dimension should match when restarting a simulation.");
00581 }
00582
00583
00584 HeartConfig::Instance()->SetSimulationDuration(pResumeParameters->ResumeSimulation()->SimulationDuration());
00585
00586
00587 if (pResumeParameters->ResumeSimulation()->Stimuli().present())
00588 {
00589 mpUserParameters->Simulation()->Stimuli().set(pResumeParameters->ResumeSimulation()->Stimuli().get());
00590 }
00591
00592
00593
00594 if (pResumeParameters->ResumeSimulation()->CellHeterogeneities().present())
00595 {
00596 if (!mpUserParameters->Simulation()->CellHeterogeneities().present())
00597 {
00598
00599 mpUserParameters->Simulation()->CellHeterogeneities().set(pResumeParameters->ResumeSimulation()->CellHeterogeneities().get());
00600 }
00601 else
00602 {
00603
00604 XSD_SEQUENCE_TYPE(cp::cell_heterogeneities_type::CellHeterogeneity)&
00605 new_seq = pResumeParameters->ResumeSimulation()->CellHeterogeneities()->CellHeterogeneity();
00606 XSD_SEQUENCE_TYPE(cp::cell_heterogeneities_type::CellHeterogeneity)&
00607 orig_seq = mpUserParameters->Simulation()->CellHeterogeneities()->CellHeterogeneity();
00608 for (XSD_ITERATOR_TYPE(cp::cell_heterogeneities_type::CellHeterogeneity) i = new_seq.begin();
00609 i != new_seq.end();
00610 ++i)
00611 {
00612 orig_seq.push_back(*i);
00613 }
00614 }
00615 }
00616
00617
00618 if (pResumeParameters->ResumeSimulation()->CheckpointSimulation().present())
00619 {
00620 HeartConfig::Instance()->SetCheckpointSimulation(true,
00621 pResumeParameters->ResumeSimulation()->CheckpointSimulation()->timestep(),
00622 pResumeParameters->ResumeSimulation()->CheckpointSimulation()->max_checkpoints_on_disk());
00623 }
00624
00625
00626 HeartConfig::Instance()->SetVisualizeWithVtk(pResumeParameters->ResumeSimulation()->OutputVisualizer().vtk() == cp::yesno_type::yes);
00627 HeartConfig::Instance()->SetVisualizeWithCmgui(pResumeParameters->ResumeSimulation()->OutputVisualizer().cmgui() == cp::yesno_type::yes);
00628 HeartConfig::Instance()->SetVisualizeWithMeshalyzer(pResumeParameters->ResumeSimulation()->OutputVisualizer().meshalyzer() == cp::yesno_type::yes);
00629
00630
00631 {
00632 cp::numerical_type& r_resume = pResumeParameters->Numerical();
00633 cp::numerical_type& r_user = mpUserParameters->Numerical();
00634 if (r_resume.TimeSteps().present())
00635 {
00636 r_user.TimeSteps().set(r_resume.TimeSteps().get());
00637 }
00638 if (r_resume.KSPTolerances().present())
00639 {
00640 r_user.KSPTolerances().set(r_resume.KSPTolerances().get());
00641 }
00642 if (r_resume.KSPSolver().present())
00643 {
00644 r_user.KSPSolver().set(r_resume.KSPSolver().get());
00645 }
00646 if (r_resume.KSPPreconditioner().present())
00647 {
00648 r_user.KSPPreconditioner().set(r_resume.KSPPreconditioner().get());
00649 }
00650 if (r_resume.AdaptivityParameters().present())
00651 {
00652 r_user.AdaptivityParameters().set(r_resume.AdaptivityParameters().get());
00653 }
00654 }
00655
00656
00657 if (pResumeParameters->PostProcessing().present())
00658 {
00659 EnsurePostProcessingSectionPresent();
00660 cp::postprocessing_type& r_resume = pResumeParameters->PostProcessing().get();
00661 cp::postprocessing_type& r_user = mpUserParameters->PostProcessing().get();
00662 if (!r_resume.ActionPotentialDurationMap().empty())
00663 {
00664 r_user.ActionPotentialDurationMap() = r_resume.ActionPotentialDurationMap();
00665 }
00666 if (!r_resume.UpstrokeTimeMap().empty())
00667 {
00668 r_user.UpstrokeTimeMap() = r_resume.UpstrokeTimeMap();
00669 }
00670 if (!r_resume.MaxUpstrokeVelocityMap().empty())
00671 {
00672 r_user.MaxUpstrokeVelocityMap() = r_resume.MaxUpstrokeVelocityMap();
00673 }
00674 if (!r_resume.ConductionVelocityMap().empty())
00675 {
00676 r_user.ConductionVelocityMap() = r_resume.ConductionVelocityMap();
00677 }
00678 }
00679 }
00680
00681
00682 void HeartConfig::Reset()
00683 {
00684
00685 mpInstance.reset();
00686
00687 mpInstance.reset(new HeartConfig);
00688 }
00689
00690 bool HeartConfig::IsSimulationDefined() const
00691 {
00692 return mpUserParameters->Simulation().present();
00693 }
00694
00695 bool HeartConfig::IsSimulationResumed() const
00696 {
00697 return mpUserParameters->ResumeSimulation().present();
00698 }
00699
00700
00701 template<class TYPE>
00702 TYPE* HeartConfig::DecideLocation(TYPE* ptr1, TYPE* ptr2, const std::string& nameParameter) const
00703 {
00704 if (ptr1->present())
00705 {
00706 return ptr1;
00707 }
00708 if (ptr2->present())
00709 {
00710 return ptr2;
00711 }
00712 EXCEPTION("No " + nameParameter + " provided (neither default nor user defined)");
00713 }
00714
00715 void HeartConfig::CheckSimulationIsDefined(std::string callingMethod) const
00716 {
00717 if (IsSimulationResumed())
00718 {
00719 EXCEPTION(callingMethod + " information is not available in a resumed simulation.");
00720 }
00721 }
00722
00723 void HeartConfig::CheckResumeSimulationIsDefined(std::string callingMethod) const
00724 {
00725 if (IsSimulationDefined())
00726 {
00727 EXCEPTION(callingMethod + " information is not available in a standard (non-resumed) simulation.");
00728 }
00729 }
00730
00731 unsigned HeartConfig::GetSpaceDimension() const
00732 {
00733 if (IsSimulationDefined())
00734 {
00735 return DecideLocation( & mpUserParameters->Simulation().get().SpaceDimension(),
00736 & mpDefaultParameters->Simulation().get().SpaceDimension(),
00737 "SpaceDimension")->get();
00738 }
00739 else
00740 {
00741 return mpUserParameters->ResumeSimulation().get().SpaceDimension();
00742 }
00743 }
00744
00745 double HeartConfig::GetSimulationDuration() const
00746 {
00747 if (IsSimulationDefined())
00748 {
00749 return DecideLocation( & mpUserParameters->Simulation().get().SimulationDuration(),
00750 & mpDefaultParameters->Simulation().get().SimulationDuration(),
00751 "Simulation/SimulationDuration")->get();
00752 }
00753 else
00754 {
00755 return mpUserParameters->ResumeSimulation().get().SimulationDuration();
00756 }
00757 }
00758
00759 cp::domain_type HeartConfig::GetDomain() const
00760 {
00761 if (IsSimulationDefined())
00762 {
00763 return DecideLocation( & mpUserParameters->Simulation().get().Domain(),
00764 & mpDefaultParameters->Simulation().get().Domain(),
00765 "Domain")->get();
00766 }
00767 else
00768 {
00769 return mpUserParameters->ResumeSimulation().get().Domain();
00770 }
00771 }
00772
00773 cp::ionic_model_selection_type HeartConfig::GetDefaultIonicModel() const
00774 {
00775 CheckSimulationIsDefined("DefaultIonicModel");
00776
00777 return DecideLocation( & mpUserParameters->Simulation().get().IonicModels(),
00778 & mpDefaultParameters->Simulation().get().IonicModels(),
00779 "IonicModel")->get().Default();
00780 }
00781
00782 template<unsigned DIM>
00783 void HeartConfig::GetIonicModelRegions(std::vector<ChasteCuboid<DIM> >& definedRegions,
00784 std::vector<cp::ionic_model_selection_type>& ionicModels) const
00785 {
00786 CheckSimulationIsDefined("IonicModelRegions");
00787 definedRegions.clear();
00788 ionicModels.clear();
00789
00790 XSD_SEQUENCE_TYPE(cp::ionic_models_type::Region)&
00791 regions = DecideLocation( & mpUserParameters->Simulation().get().IonicModels(),
00792 & mpDefaultParameters->Simulation().get().IonicModels(),
00793 "IonicModel")->get().Region();
00794
00795 for (XSD_ITERATOR_TYPE(cp::ionic_models_type::Region) i = regions.begin();
00796 i != regions.end();
00797 ++i)
00798 {
00799 cp::ionic_model_region_type ionic_model_region(*i);
00800 if (ionic_model_region.Location().Cuboid().present())
00801 {
00802 cp::point_type point_a = ionic_model_region.Location().Cuboid()->LowerCoordinates();
00803 cp::point_type point_b = ionic_model_region.Location().Cuboid()->UpperCoordinates();
00804
00805 switch (DIM)
00806 {
00807 case 1:
00808 {
00809 ChastePoint<DIM> chaste_point_a ( point_a.x() );
00810 ChastePoint<DIM> chaste_point_b ( point_b.x() );
00811 definedRegions.push_back(ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ));
00812 break;
00813 }
00814 case 2:
00815 {
00816 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y() );
00817 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y() );
00818 definedRegions.push_back(ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ));
00819 break;
00820 }
00821 case 3:
00822 {
00823 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
00824 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
00825 definedRegions.push_back(ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ));
00826 break;
00827 }
00828 default:
00829 NEVER_REACHED;
00830 break;
00831 }
00832
00833 ionicModels.push_back(ionic_model_region.IonicModel());
00834 }
00835 else
00836 {
00837 if(ionic_model_region.Location().EpiLayer().present() || ionic_model_region.Location().MidLayer().present() || ionic_model_region.Location().EndoLayer().present() )
00838 {
00840 EXCEPTION("Definition of transmural layers is not yet supported for defining different ionic models, please use cuboids instead");
00841 }
00842 }
00843 }
00844 }
00845
00846
00847 bool HeartConfig::IsMeshProvided() const
00848 {
00849 CheckSimulationIsDefined("Mesh");
00850
00851 try
00852 {
00853 DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00854 & mpDefaultParameters->Simulation().get().Mesh(),
00855 "Mesh");
00856 return true;
00857 }
00858 catch (Exception& e)
00859 {
00860 return false;
00861 }
00862 }
00863
00864 bool HeartConfig::GetCreateMesh() const
00865 {
00866 CheckSimulationIsDefined("Mesh");
00867
00868 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00869 & mpDefaultParameters->Simulation().get().Mesh(),
00870 "Mesh")->get();
00871
00872 return (mesh.Slab().present() || mesh.Sheet().present() || mesh.Fibre().present());
00873 }
00874
00875 bool HeartConfig::GetCreateSlab() const
00876 {
00877 CheckSimulationIsDefined("Mesh");
00878
00879 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00880 & mpDefaultParameters->Simulation().get().Mesh(),
00881 "Mesh")->get();
00882
00883 return (mesh.Slab().present());
00884 }
00885
00886 bool HeartConfig::GetCreateSheet() const
00887 {
00888 CheckSimulationIsDefined("Mesh");
00889
00890 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00891 & mpDefaultParameters->Simulation().get().Mesh(),
00892 "Mesh")->get();
00893
00894 return (mesh.Sheet().present());
00895 }
00896
00897 bool HeartConfig::GetCreateFibre() const
00898 {
00899 CheckSimulationIsDefined("Mesh");
00900
00901 cp::mesh_type mesh = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00902 & mpDefaultParameters->Simulation().get().Mesh(),
00903 "Mesh")->get();
00904
00905 return (mesh.Fibre().present());
00906 }
00907
00908
00909 bool HeartConfig::GetLoadMesh() const
00910 {
00911 CheckSimulationIsDefined("Mesh");
00912
00913 return (DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00914 & mpDefaultParameters->Simulation().get().Mesh(),
00915 "Mesh")->get().LoadMesh().present());
00916 }
00917
00918 void HeartConfig::GetSlabDimensions(c_vector<double, 3>& slabDimensions) const
00919 {
00920 CheckSimulationIsDefined("Slab");
00921
00922 if (GetSpaceDimension()!=3 || !GetCreateSlab())
00923 {
00924 EXCEPTION("Tissue slabs can only be defined in 3D");
00925 }
00926
00927 optional<cp::slab_type, false> slab_dimensions = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00928 & mpDefaultParameters->Simulation().get().Mesh(),
00929 "Slab")->get().Slab();
00930
00931 slabDimensions[0] = slab_dimensions->x();
00932 slabDimensions[1] = slab_dimensions->y();
00933 slabDimensions[2] = slab_dimensions->z();
00934 }
00935
00936 void HeartConfig::GetSheetDimensions(c_vector<double, 2>& sheetDimensions) const
00937 {
00938 CheckSimulationIsDefined("Sheet");
00939
00940 if (GetSpaceDimension()!=2 || !GetCreateSheet())
00941 {
00942 EXCEPTION("Tissue sheets can only be defined in 2D");
00943 }
00944
00945 optional<cp::sheet_type, false> sheet_dimensions = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00946 & mpDefaultParameters->Simulation().get().Mesh(),
00947 "Sheet")->get().Sheet();
00948
00949 sheetDimensions[0] = sheet_dimensions->x();
00950 sheetDimensions[1] = sheet_dimensions->y();
00951 }
00952
00953 void HeartConfig::GetFibreLength(c_vector<double, 1>& fibreLength) const
00954 {
00955 CheckSimulationIsDefined("Fibre");
00956
00957 if (GetSpaceDimension()!=1 || !GetCreateFibre())
00958 {
00959 EXCEPTION("Tissue fibres can only be defined in 1D");
00960 }
00961
00962 optional<cp::fibre_type, false> fibre_length = DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00963 & mpDefaultParameters->Simulation().get().Mesh(),
00964 "Fibre")->get().Fibre();
00965
00966 fibreLength[0] = fibre_length->x();
00967 }
00968
00969
00970 double HeartConfig::GetInterNodeSpace() const
00971 {
00972 CheckSimulationIsDefined("InterNodeSpace");
00973 assert(GetCreateMesh());
00974
00975 switch(GetSpaceDimension())
00976 {
00977 case 3:
00978 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00979 & mpDefaultParameters->Simulation().get().Mesh(),
00980 "Slab")->get().Slab()->inter_node_space();
00981 break;
00982 case 2:
00983 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00984 & mpDefaultParameters->Simulation().get().Mesh(),
00985 "Sheet")->get().Sheet()->inter_node_space();
00986 break;
00987 case 1:
00988 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
00989 & mpDefaultParameters->Simulation().get().Mesh(),
00990 "Fibre")->get().Fibre()->inter_node_space();
00991 break;
00992 default:
00993 NEVER_REACHED;
00994 #define COVERAGE_IGNORE
00995 return 0.0;
00996 #undef COVERAGE_IGNORE
00997 }
00998 }
00999
01000 std::string HeartConfig::GetMeshName() const
01001 {
01002 CheckSimulationIsDefined("LoadMesh");
01003 assert(GetLoadMesh());
01004
01005 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
01006 & mpDefaultParameters->Simulation().get().Mesh(),
01007 "LoadMesh")->get().LoadMesh()->name();
01008 }
01009
01010 cp::media_type HeartConfig::GetConductivityMedia() const
01011 {
01012 CheckSimulationIsDefined("LoadMesh");
01013 assert(GetLoadMesh());
01014
01015 return DecideLocation( & mpUserParameters->Simulation().get().Mesh(),
01016 & mpDefaultParameters->Simulation().get().Mesh(),
01017 "LoadMesh")->get().LoadMesh()->conductivity_media();
01018 }
01019
01020 template <unsigned DIM>
01021 void HeartConfig::GetStimuli(std::vector<boost::shared_ptr<AbstractStimulusFunction> >& rStimuliApplied,
01022 std::vector<ChasteCuboid<DIM> >& rStimulatedAreas) const
01023 {
01024 CheckSimulationIsDefined("Stimuli");
01025 XSD_SEQUENCE_TYPE(cp::stimuli_type::Stimulus)&
01026 stimuli = DecideLocation( & mpUserParameters->Simulation().get().Stimuli(),
01027 & mpDefaultParameters->Simulation().get().Stimuli(),
01028 "Stimuli")->get().Stimulus();
01029 for (XSD_ITERATOR_TYPE(cp::stimuli_type::Stimulus) i = stimuli.begin();
01030 i != stimuli.end();
01031 ++i)
01032 {
01033 cp::stimulus_type stimulus(*i);
01034 if (stimulus.Location().Cuboid().present())
01035 {
01036 cp::point_type point_a = stimulus.Location().Cuboid()->LowerCoordinates();
01037 cp::point_type point_b = stimulus.Location().Cuboid()->UpperCoordinates();
01038 switch (DIM)
01039 {
01040 case 1:
01041 {
01042 ChastePoint<DIM> chaste_point_a ( point_a.x() );
01043 ChastePoint<DIM> chaste_point_b ( point_b.x() );
01044 rStimulatedAreas.push_back( ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ) );
01045 break;
01046 }
01047 case 2:
01048 {
01049 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y() );
01050 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y() );
01051 rStimulatedAreas.push_back( ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ) );
01052 break;
01053 }
01054 case 3:
01055 {
01056 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
01057 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
01058 rStimulatedAreas.push_back( ChasteCuboid<DIM>( chaste_point_a, chaste_point_b ) );
01059 break;
01060 }
01061 default:
01062 NEVER_REACHED;
01063 break;
01064 }
01065
01066 boost::shared_ptr<AbstractStimulusFunction> stim;
01067
01068 if (stimulus.Period().present())
01069 {
01070 if (stimulus.StopTime().present())
01071 {
01072 stim.reset(new RegularStimulus(stimulus.Strength(),
01073 stimulus.Duration(),
01074 stimulus.Period().get(),
01075 stimulus.Delay(),
01076 stimulus.StopTime().get()));
01077 }
01078 else
01079 {
01080 stim.reset(new RegularStimulus(stimulus.Strength(),
01081 stimulus.Duration(),
01082 stimulus.Period().get(),
01083 stimulus.Delay()));
01084 }
01085
01086 }
01087 else
01088 {
01089 if (stimulus.StopTime().present())
01090 {
01091 EXCEPTION("Stop time can not be defined for SimpleStimulus. Use Duration instead.");
01092 }
01093
01094 stim.reset(new SimpleStimulus(stimulus.Strength(),
01095 stimulus.Duration(),
01096 stimulus.Delay()));
01097 }
01098 rStimuliApplied.push_back( stim );
01099 }
01100 else
01101 {
01102 if(stimulus.Location().EpiLayer().present() || stimulus.Location().MidLayer().present() || stimulus.Location().EndoLayer().present() )
01103 {
01104 EXCEPTION("Definition of transmural layers is not yet supported for specifying stimulated areas, please use cuboids instead");
01105 }
01106 }
01107 }
01108 }
01109
01110
01111 template<unsigned DIM>
01112 void HeartConfig::GetCellHeterogeneities(std::vector<AbstractChasteRegion<DIM>* >& rCellHeterogeneityRegions,
01113 std::vector<double>& rScaleFactorGks,
01114 std::vector<double>& rScaleFactorIto,
01115 std::vector<double>& rScaleFactorGkr,
01116 std::vector<std::map<std::string, double> >* pParameterSettings)
01117 {
01118 CheckSimulationIsDefined("CellHeterogeneities");
01119 XSD_SEQUENCE_TYPE(cp::cell_heterogeneities_type::CellHeterogeneity)&
01120 cell_heterogeneity = DecideLocation( & mpUserParameters->Simulation().get().CellHeterogeneities(),
01121 & mpDefaultParameters->Simulation().get().CellHeterogeneities(),
01122 "CellHeterogeneities")->get().CellHeterogeneity();
01123
01124 bool user_supplied_negative_value = false;
01125 bool user_asking_for_transmural_layers = false;
01126 unsigned counter_of_heterogeneities = 0;
01127
01128 for (XSD_ITERATOR_TYPE(cp::cell_heterogeneities_type::CellHeterogeneity) i = cell_heterogeneity.begin();
01129 i != cell_heterogeneity.end();
01130 ++i)
01131 {
01132 cp::cell_heterogeneity_type ht(*i);
01133
01134 if (ht.Location().Cuboid().present())
01135 {
01136 mUserAskedForCuboidsForCellularHeterogeneities = true;
01137 cp::point_type point_a = ht.Location().Cuboid()->LowerCoordinates();
01138 cp::point_type point_b = ht.Location().Cuboid()->UpperCoordinates();
01139
01140 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
01141 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
01142 rCellHeterogeneityRegions.push_back(new ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
01143 }
01144 else
01145 {
01146
01147 if (ht.Location().EpiLayer().present())
01148 {
01149 mEpiFraction = ht.Location().EpiLayer().get();
01150
01151 user_asking_for_transmural_layers = true;
01152 if (mEpiFraction <0)
01153 {
01154 user_supplied_negative_value=true;
01155 }
01156 mIndexEpi = counter_of_heterogeneities;
01157 }
01158 if (ht.Location().EndoLayer().present())
01159 {
01160 mEndoFraction = ht.Location().EndoLayer().get();
01161
01162 user_asking_for_transmural_layers = true;
01163 if (mEndoFraction <0)
01164 {
01165 user_supplied_negative_value=true;
01166 }
01167 mIndexEndo = counter_of_heterogeneities;
01168 }
01169 if (ht.Location().MidLayer().present())
01170 {
01171 mMidFraction = ht.Location().MidLayer().get();
01172
01173 user_asking_for_transmural_layers = true;
01174 if (mMidFraction <0)
01175 {
01176 user_supplied_negative_value=true;
01177 }
01178 mIndexMid = counter_of_heterogeneities;
01179 }
01180 }
01181
01182 rScaleFactorGks.push_back(ht.ScaleFactorGks().present() ? (double)ht.ScaleFactorGks().get() : 1.0);
01183 rScaleFactorIto.push_back(ht.ScaleFactorIto().present() ? (double)ht.ScaleFactorIto().get() : 1.0);
01184 rScaleFactorGkr.push_back(ht.ScaleFactorGkr().present() ? (double)ht.ScaleFactorGkr().get() : 1.0);
01185
01186
01187 if (pParameterSettings)
01188 {
01189 std::map<std::string, double> param_settings;
01190 XSD_SEQUENCE_TYPE(cp::cell_heterogeneity_type::SetParameter)& params = ht.SetParameter();
01191 for (XSD_ITERATOR_TYPE(cp::cell_heterogeneity_type::SetParameter) param_it = params.begin();
01192 param_it != params.end();
01193 ++param_it)
01194 {
01195 cp::set_parameter_type param(*param_it);
01196 param_settings[param.name()] = param.value();
01197 }
01198 pParameterSettings->push_back(param_settings);
01199 }
01200
01201 counter_of_heterogeneities++;
01202 }
01203
01204
01205 mUserAskedForCellularTransmuralHeterogeneities = user_asking_for_transmural_layers;
01206
01207
01208 if (mUserAskedForCuboidsForCellularHeterogeneities && mUserAskedForCellularTransmuralHeterogeneities)
01209 {
01210
01211 for (unsigned index=0;index < rCellHeterogeneityRegions.size(); index++)
01212 {
01213 delete rCellHeterogeneityRegions[index];
01214 }
01215 EXCEPTION ("Specification of cellular heterogeneities by cuboids and layers at the same time is not yet supported");
01216 }
01217
01218 if (mUserAskedForCellularTransmuralHeterogeneities)
01219 {
01220
01221
01222
01223 if ((mIndexMid+mIndexEndo+mIndexEpi) > 3)
01224 {
01225 EXCEPTION ("Three specifications of layers must be supplied");
01226 }
01227 if (fabs((mEndoFraction+mMidFraction+mEpiFraction)-1)>1e-2)
01228 {
01229 EXCEPTION ("Summation of epicardial, midmyocardial and endocardial fractions should be 1");
01230 }
01231 if (user_supplied_negative_value)
01232 {
01233 EXCEPTION ("Fractions must be positive");
01234 }
01235 }
01236 }
01237
01238 bool HeartConfig::AreCellularTransmuralHeterogeneitiesRequested()
01239 {
01240 return mUserAskedForCellularTransmuralHeterogeneities;
01241 }
01242
01243 bool HeartConfig::AreCellularHeterogeneitiesSpecifiedByCuboids()
01244 {
01245 return mUserAskedForCuboidsForCellularHeterogeneities;
01246 }
01247
01248 double HeartConfig::GetEpiLayerFraction()
01249 {
01250 return mEpiFraction;
01251 }
01252
01253 double HeartConfig::GetEndoLayerFraction()
01254 {
01255 return mEndoFraction;
01256 }
01257
01258 double HeartConfig::GetMidLayerFraction()
01259 {
01260 return mMidFraction;
01261 }
01262
01263 unsigned HeartConfig::GetEpiLayerIndex()
01264 {
01265 return mIndexEpi;
01266 }
01267
01268 unsigned HeartConfig::GetEndoLayerIndex()
01269 {
01270 return mIndexEndo;
01271 }
01272
01273 unsigned HeartConfig::GetMidLayerIndex()
01274 {
01275 return mIndexMid;
01276 }
01277
01278 bool HeartConfig::GetConductivityHeterogeneitiesProvided() const
01279 {
01280 CheckSimulationIsDefined("ConductivityHeterogeneities");
01281 try
01282 {
01283 DecideLocation( & mpUserParameters->Simulation().get().ConductivityHeterogeneities(),
01284 & mpDefaultParameters->Simulation().get().ConductivityHeterogeneities(),
01285 "ConductivityHeterogeneities");
01286 return true;
01287 }
01288 catch (Exception& e)
01289 {
01290 return false;
01291 }
01292 }
01293
01294 template<unsigned DIM>
01295 void HeartConfig::GetConductivityHeterogeneities(
01296 std::vector<AbstractChasteRegion<DIM>* >& conductivitiesHeterogeneityAreas,
01297 std::vector< c_vector<double,3> >& intraConductivities,
01298 std::vector< c_vector<double,3> >& extraConductivities) const
01299 {
01300 CheckSimulationIsDefined("ConductivityHeterogeneities");
01301 XSD_ANON_SEQUENCE_TYPE(cp::simulation_type, ConductivityHeterogeneities, ConductivityHeterogeneity)&
01302 conductivity_heterogeneity = DecideLocation( & mpUserParameters->Simulation().get().ConductivityHeterogeneities(),
01303 & mpDefaultParameters->Simulation().get().ConductivityHeterogeneities(),
01304 "ConductivityHeterogeneities")->get().ConductivityHeterogeneity();
01305
01306 for (XSD_ANON_ITERATOR_TYPE(cp::simulation_type, ConductivityHeterogeneities, ConductivityHeterogeneity) i = conductivity_heterogeneity.begin();
01307 i != conductivity_heterogeneity.end();
01308 ++i)
01309 {
01310 cp::conductivity_heterogeneity_type ht(*i);
01311 if (ht.Location().Cuboid().present())
01312 {
01313 cp::point_type point_a = ht.Location().Cuboid()->LowerCoordinates();
01314 cp::point_type point_b = ht.Location().Cuboid()->UpperCoordinates();
01315 ChastePoint<DIM> chaste_point_a ( point_a.x(), point_a.y(), point_a.z() );
01316 ChastePoint<DIM> chaste_point_b ( point_b.x(), point_b.y(), point_b.z() );
01317 conductivitiesHeterogeneityAreas.push_back( new ChasteCuboid<DIM> ( chaste_point_a, chaste_point_b ) );
01318 }
01319 else if (ht.Location().Ellipsoid().present())
01320 {
01321 cp::point_type centre = ht.Location().Ellipsoid()->Centre();
01322 cp::point_type radii = ht.Location().Ellipsoid()->Radii();
01323 ChastePoint<DIM> chaste_point_a ( centre.x(), centre.y(), centre.z() );
01324 ChastePoint<DIM> chaste_point_b ( radii.x(), radii.y(), radii.z() );
01325 conductivitiesHeterogeneityAreas.push_back( new ChasteEllipsoid<DIM> ( chaste_point_a, chaste_point_b ) );
01326 }
01327 else
01328 {
01329 if(ht.Location().EpiLayer().present() || ht.Location().MidLayer().present() || ht.Location().EndoLayer().present() )
01330 {
01332 EXCEPTION("Definition of transmural layers is not allowed for conductivities heterogeneities, you may use fibre orientation support instead");
01333 }
01334 }
01335
01336 if (ht.IntracellularConductivities().present())
01337 {
01338 double intra_x = ht.IntracellularConductivities().get().longi();
01339 double intra_y = ht.IntracellularConductivities().get().trans();
01340 double intra_z = ht.IntracellularConductivities().get().normal();
01341
01342 intraConductivities.push_back( Create_c_vector(intra_x, intra_y, intra_z) );
01343 }
01344 else
01345 {
01346 c_vector<double, 3> intra_conductivities;
01347 GetIntracellularConductivities(intra_conductivities);
01348 intraConductivities.push_back(intra_conductivities);
01349 }
01350
01351 if (ht.ExtracellularConductivities().present())
01352 {
01353 double extra_x = ht.ExtracellularConductivities().get().longi();
01354 double extra_y = ht.ExtracellularConductivities().get().trans();
01355 double extra_z = ht.ExtracellularConductivities().get().normal();
01356
01357 extraConductivities.push_back( Create_c_vector(extra_x, extra_y, extra_z) );
01358 }
01359 else
01360 {
01361 c_vector<double, 3> extra_conductivities;
01362 GetExtracellularConductivities(extra_conductivities);
01363 extraConductivities.push_back(extra_conductivities);
01364 }
01365
01366 }
01367 }
01368
01369 std::string HeartConfig::GetOutputDirectory() const
01370 {
01371 CheckSimulationIsDefined("Simulation/OutputDirectory");
01372 return DecideLocation( & mpUserParameters->Simulation().get().OutputDirectory(),
01373 & mpDefaultParameters->Simulation().get().OutputDirectory(),
01374 "Simulation/OutputDirectory")->get();
01375 }
01376
01377 std::string HeartConfig::GetOutputFilenamePrefix() const
01378 {
01379 CheckSimulationIsDefined("Simulation/OutputFilenamePrefix");
01380 return DecideLocation( & mpUserParameters->Simulation().get().OutputFilenamePrefix(),
01381 & mpDefaultParameters->Simulation().get().OutputFilenamePrefix(),
01382 "Simulation/OutputFilenamePrefix")->get();
01383 }
01384
01385 bool HeartConfig::GetOutputVariablesProvided() const
01386 {
01387 CheckSimulationIsDefined("OutputVariables");
01388
01389 try
01390 {
01391 DecideLocation( & mpUserParameters->Simulation().get().OutputVariables(),
01392 & mpDefaultParameters->Simulation().get().OutputVariables(),
01393 "OutputVariables");
01394 return true;
01395 }
01396 catch (Exception& e)
01397 {
01398 return false;
01399 }
01400 }
01401
01402 void HeartConfig::GetOutputVariables(std::vector<std::string>& rOutputVariables) const
01403 {
01404 CheckSimulationIsDefined("OutputVariables");
01405 XSD_SEQUENCE_TYPE(cp::output_variables_type::Var)&
01406 output_variables = DecideLocation( & mpUserParameters->Simulation().get().OutputVariables(),
01407 & mpDefaultParameters->Simulation().get().OutputVariables(),
01408 "OutputVariables")->get().Var();
01409 rOutputVariables.clear();
01410
01411 for (XSD_ITERATOR_TYPE(cp::output_variables_type::Var) i = output_variables.begin();
01412 i != output_variables.end();
01413 ++i)
01414 {
01415 cp::var_type& r_var(*i);
01416
01417
01418 rOutputVariables.push_back(r_var.name());
01419 }
01420 }
01421 bool HeartConfig::GetOutputUsingOriginalNodeOrdering()
01422 {
01423 try
01424 {
01425 return (DecideLocation(& mpUserParameters->Simulation().get().OutputUsingOriginalNodeOrdering(),
01426 & mpDefaultParameters->Simulation().get().OutputUsingOriginalNodeOrdering(),
01427 "OutputUsingOriginalNodeOrdering")->get() == cp::yesno_type::yes);
01428 }
01429 catch (Exception &e)
01430 {
01431
01432 return false;
01433 }
01434 }
01435
01436 bool HeartConfig::GetCheckpointSimulation() const
01437 {
01438 try
01439 {
01440 if (IsSimulationDefined())
01441 {
01442 CheckSimulationIsDefined("GetSaveSimulation");
01443 DecideLocation( & mpUserParameters->Simulation().get().CheckpointSimulation(),
01444 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01445 "Simulation/SaveSimulation");
01446 }
01447 else
01448 {
01449 CheckResumeSimulationIsDefined("GetSaveSimulation");
01450 DecideLocation( & mpUserParameters->ResumeSimulation().get().CheckpointSimulation(),
01451 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01452 "ResumeSimulation/SaveSimulation");
01453 }
01454 return true;
01455 }
01456 catch (Exception& e)
01457 {
01458 return false;
01459 }
01460 }
01461
01462 double HeartConfig::GetCheckpointTimestep() const
01463 {
01464 if (IsSimulationDefined())
01465 {
01466 CheckSimulationIsDefined("GetSaveSimulation");
01467 return DecideLocation( & mpUserParameters->Simulation().get().CheckpointSimulation(),
01468 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01469 "Simulation/SaveSimulation")->get().timestep();
01470 }
01471 else
01472 {
01473 CheckResumeSimulationIsDefined("GetSaveSimulation");
01474 return DecideLocation( & mpUserParameters->ResumeSimulation().get().CheckpointSimulation(),
01475 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01476 "ResumeSimulation/SaveSimulation")->get().timestep();
01477 }
01478 }
01479
01480 unsigned HeartConfig::GetMaxCheckpointsOnDisk() const
01481 {
01482 if (IsSimulationDefined())
01483 {
01484 CheckSimulationIsDefined("GetSaveSimulation");
01485 return DecideLocation( & mpUserParameters->Simulation().get().CheckpointSimulation(),
01486 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01487 "Simulation/SaveSimulation")->get().max_checkpoints_on_disk();
01488 }
01489 else
01490 {
01491 CheckResumeSimulationIsDefined("GetSaveSimulation");
01492 return DecideLocation( & mpUserParameters->ResumeSimulation().get().CheckpointSimulation(),
01493 & mpDefaultParameters->Simulation().get().CheckpointSimulation(),
01494 "ResumeSimulation/SaveSimulation")->get().max_checkpoints_on_disk();
01495 }
01496 }
01497
01498
01499 HeartFileFinder HeartConfig::GetArchivedSimulationDir() const
01500 {
01501 CheckResumeSimulationIsDefined("GetArchivedSimulationDir");
01502
01503 return HeartFileFinder(mpUserParameters->ResumeSimulation().get().ArchiveDirectory());
01504 }
01505
01506
01507 void HeartConfig::GetIntracellularConductivities(c_vector<double, 3>& intraConductivities) const
01508 {
01509 optional<cp::conductivities_type, false>* intra_conductivities
01510 = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
01511 & mpDefaultParameters->Physiological().IntracellularConductivities(),
01512 "IntracellularConductivities");
01513 double intra_x_cond = intra_conductivities->get().longi();
01514 double intra_y_cond = intra_conductivities->get().trans();
01515 double intra_z_cond = intra_conductivities->get().normal();;
01516
01517 assert(intra_y_cond != DBL_MAX);
01518 assert(intra_z_cond != DBL_MAX);
01519
01520 intraConductivities[0] = intra_x_cond;
01521 intraConductivities[1] = intra_y_cond;
01522 intraConductivities[2] = intra_z_cond;
01523 }
01524
01525 void HeartConfig::GetIntracellularConductivities(c_vector<double, 2>& intraConductivities) const
01526 {
01527 optional<cp::conductivities_type, false>* intra_conductivities
01528 = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
01529 & mpDefaultParameters->Physiological().IntracellularConductivities(),
01530 "IntracellularConductivities");
01531 double intra_x_cond = intra_conductivities->get().longi();
01532 double intra_y_cond = intra_conductivities->get().trans();
01533
01534 assert(intra_y_cond != DBL_MAX);
01535
01536 intraConductivities[0] = intra_x_cond;
01537 intraConductivities[1] = intra_y_cond;
01538 }
01539
01540 void HeartConfig::GetIntracellularConductivities(c_vector<double, 1>& intraConductivities) const
01541 {
01542 optional<cp::conductivities_type, false>* intra_conductivities
01543 = DecideLocation( & mpUserParameters->Physiological().IntracellularConductivities(),
01544 & mpDefaultParameters->Physiological().IntracellularConductivities(),
01545 "IntracellularConductivities");
01546 double intra_x_cond = intra_conductivities->get().longi();
01547
01548 intraConductivities[0] = intra_x_cond;
01549 }
01550
01551 void HeartConfig::GetExtracellularConductivities(c_vector<double, 3>& extraConductivities) const
01552 {
01553 optional<cp::conductivities_type, false>* extra_conductivities
01554 = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
01555 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
01556 "ExtracellularConductivities");
01557 double extra_x_cond = extra_conductivities->get().longi();
01558 double extra_y_cond = extra_conductivities->get().trans();
01559 double extra_z_cond = extra_conductivities->get().normal();;
01560
01561 assert(extra_y_cond != DBL_MAX);
01562 assert(extra_z_cond != DBL_MAX);
01563
01564 extraConductivities[0] = extra_x_cond;
01565 extraConductivities[1] = extra_y_cond;
01566 extraConductivities[2] = extra_z_cond;
01567 }
01568
01569 void HeartConfig::GetExtracellularConductivities(c_vector<double, 2>& extraConductivities) const
01570 {
01571 optional<cp::conductivities_type, false>* extra_conductivities
01572 = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
01573 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
01574 "ExtracellularConductivities");
01575 double extra_x_cond = extra_conductivities->get().longi();
01576 double extra_y_cond = extra_conductivities->get().trans();
01577
01578 assert(extra_y_cond != DBL_MAX);
01579
01580 extraConductivities[0] = extra_x_cond;
01581 extraConductivities[1] = extra_y_cond;
01582 }
01583
01584 void HeartConfig::GetExtracellularConductivities(c_vector<double, 1>& extraConductivities) const
01585 {
01586 optional<cp::conductivities_type, false>* extra_conductivities
01587 = DecideLocation( & mpUserParameters->Physiological().ExtracellularConductivities(),
01588 & mpDefaultParameters->Physiological().ExtracellularConductivities(),
01589 "ExtracellularConductivities");
01590 double extra_x_cond = extra_conductivities->get().longi();
01591
01592 extraConductivities[0] = extra_x_cond;
01593 }
01594
01595 double HeartConfig::GetBathConductivity() const
01596 {
01597
01598 return DecideLocation( & mpUserParameters->Physiological().BathConductivity(),
01599 & mpDefaultParameters->Physiological().BathConductivity(),
01600 "BathConductivity")->get();
01601 }
01602
01603 double HeartConfig::GetSurfaceAreaToVolumeRatio() const
01604 {
01605
01606 return DecideLocation( & mpUserParameters->Physiological().SurfaceAreaToVolumeRatio(),
01607 & mpDefaultParameters->Physiological().SurfaceAreaToVolumeRatio(),
01608 "SurfaceAreaToVolumeRatio")->get();
01609 }
01610
01611 double HeartConfig::GetCapacitance() const
01612 {
01613
01614 return DecideLocation( & mpUserParameters->Physiological().Capacitance(),
01615 & mpDefaultParameters->Physiological().Capacitance(),
01616 "Capacitance")->get();
01617 }
01618
01619 double HeartConfig::GetOdeTimeStep() const
01620 {
01621 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
01622 & mpDefaultParameters->Numerical().TimeSteps(),
01623 "ode TimeStep")->get().ode();
01624 }
01625
01626 double HeartConfig::GetPdeTimeStep() const
01627 {
01628 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
01629 & mpDefaultParameters->Numerical().TimeSteps(),
01630 "pde TimeStep")->get().pde();
01631 }
01632
01633 double HeartConfig::GetPrintingTimeStep() const
01634 {
01635 return DecideLocation( & mpUserParameters->Numerical().TimeSteps(),
01636 & mpDefaultParameters->Numerical().TimeSteps(),
01637 "printing TimeStep")->get().printing();
01638 }
01639
01640 bool HeartConfig::GetUseAbsoluteTolerance() const
01641 {
01642 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01643 & mpDefaultParameters->Numerical().KSPTolerances(),
01644 "KSPTolerances")->get().KSPAbsolute().present();
01645 }
01646
01647 double HeartConfig::GetAbsoluteTolerance() const
01648 {
01649 if (!GetUseAbsoluteTolerance())
01650 {
01651 EXCEPTION("Absolute tolerance is not set in Chaste parameters");
01652 }
01653 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01654 & mpDefaultParameters->Numerical().KSPTolerances(),
01655 "KSPTolerances")->get().KSPAbsolute().get();
01656 }
01657
01658 bool HeartConfig::GetUseRelativeTolerance() const
01659 {
01660 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01661 & mpDefaultParameters->Numerical().KSPTolerances(),
01662 "KSPTolerances")->get().KSPRelative().present();
01663 }
01664
01665 double HeartConfig::GetRelativeTolerance() const
01666 {
01667 if (!GetUseRelativeTolerance())
01668 {
01669 EXCEPTION("Relative tolerance is not set in Chaste parameters");
01670 }
01671 return DecideLocation( & mpUserParameters->Numerical().KSPTolerances(),
01672 & mpDefaultParameters->Numerical().KSPTolerances(),
01673 "KSPTolerances")->get().KSPRelative().get();
01674 }
01675
01676 const char* HeartConfig::GetKSPSolver() const
01677 {
01678 switch ( DecideLocation( & mpUserParameters->Numerical().KSPSolver(),
01679 & mpDefaultParameters->Numerical().KSPSolver(),
01680 "KSPSolver")->get() )
01681 {
01682 case cp::ksp_solver_type::gmres :
01683 return "gmres";
01684 case cp::ksp_solver_type::cg :
01685 return "cg";
01686 case cp::ksp_solver_type::symmlq :
01687 return "symmlq";
01688 }
01689 #define COVERAGE_IGNORE
01690 EXCEPTION("Unknown ksp solver");
01691 #undef COVERAGE_IGNORE
01692 }
01693
01694 const char* HeartConfig::GetKSPPreconditioner() const
01695 {
01696 switch ( DecideLocation( & mpUserParameters->Numerical().KSPPreconditioner(),
01697 & mpDefaultParameters->Numerical().KSPPreconditioner(),
01698 "KSPPreconditioner")->get() )
01699 {
01700 case cp::ksp_preconditioner_type::jacobi :
01701 return "jacobi";
01702 case cp::ksp_preconditioner_type::bjacobi :
01703 return "bjacobi";
01704 case cp::ksp_preconditioner_type::hypre :
01705 return "hypre";
01706 case cp::ksp_preconditioner_type::ml :
01707 return "ml";
01708 case cp::ksp_preconditioner_type::spai :
01709 return "spai";
01710 case cp::ksp_preconditioner_type::blockdiagonal :
01711 return "blockdiagonal";
01712 case cp::ksp_preconditioner_type::ldufactorisation :
01713 return "ldufactorisation";
01714 case cp::ksp_preconditioner_type::twolevelsblockdiagonal :
01715 return "twolevelsblockdiagonal";
01716 case cp::ksp_preconditioner_type::none :
01717 return "none";
01718
01719 }
01720 #define COVERAGE_IGNORE
01721 EXCEPTION("Unknown ksp preconditioner");
01722 #undef COVERAGE_IGNORE
01723 }
01724
01725 bool HeartConfig::IsAdaptivityParametersPresent() const
01726 {
01727 try
01728 {
01729 DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01730 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01731 "AdaptivityParameters")->present();
01732
01733 return true;
01734 }
01735 catch (Exception &e)
01736 {
01737
01738 return false;
01739 }
01740 }
01741
01742 double HeartConfig::GetTargetErrorForAdaptivity() const
01743 {
01744 if ( IsAdaptivityParametersPresent() )
01745 {
01746 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01747 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01748 "TargetError")->get().target_error();
01749 }
01750 else
01751 {
01752 EXCEPTION("Adaptivity parameters have not been set");
01753 }
01754 }
01755
01756 double HeartConfig::GetSigmaForAdaptivity() const
01757 {
01758 if ( IsAdaptivityParametersPresent() )
01759 {
01760 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01761 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01762 "TargetError")->get().sigma();
01763 }
01764 else
01765 {
01766 EXCEPTION("Adaptivity parameters have not been set");
01767 }
01768 }
01769
01770 double HeartConfig::GetMaxEdgeLengthForAdaptivity() const
01771 {
01772 if ( IsAdaptivityParametersPresent() )
01773 {
01774 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01775 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01776 "TargetError")->get().max_edge_length();
01777 }
01778 else
01779 {
01780 EXCEPTION("Adaptivity parameters have not been set");
01781 }
01782 }
01783
01784 double HeartConfig::GetMinEdgeLengthForAdaptivity() const
01785 {
01786 if ( IsAdaptivityParametersPresent() )
01787 {
01788 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01789 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01790 "TargetError")->get().min_edge_length();
01791 }
01792 else
01793 {
01794 EXCEPTION("Adaptivity parameters have not been set");
01795 }
01796 }
01797
01798 double HeartConfig::GetGradationForAdaptivity() const
01799 {
01800 if ( IsAdaptivityParametersPresent() )
01801 {
01802 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01803 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01804 "TargetError")->get().gradation();
01805 }
01806 else
01807 {
01808 EXCEPTION("Adaptivity parameters have not been set");
01809 }
01810 }
01811
01812 unsigned HeartConfig::GetMaxNodesForAdaptivity() const
01813 {
01814 if ( IsAdaptivityParametersPresent() )
01815 {
01816 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01817 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01818 "TargetError")->get().max_nodes();
01819 }
01820 else
01821 {
01822 EXCEPTION("Adaptivity parameters have not been set");
01823 }
01824 }
01825
01826 unsigned HeartConfig::GetNumberOfAdaptiveSweeps() const
01827 {
01828 if ( IsAdaptivityParametersPresent() )
01829 {
01830 return DecideLocation( & mpUserParameters->Numerical().AdaptivityParameters(),
01831 & mpDefaultParameters->Numerical().AdaptivityParameters(),
01832 "TargetError")->get().num_sweeps();
01833 }
01834 else
01835 {
01836 EXCEPTION("Adaptivity parameters have not been set");
01837 }
01838 }
01839
01840
01841
01842
01843
01844 bool HeartConfig::IsPostProcessingSectionPresent() const
01845 {
01846 try
01847 {
01848 DecideLocation( & mpUserParameters->PostProcessing(),
01849 & mpDefaultParameters->PostProcessing(),
01850 "PostProcessing")->present();
01851
01852 return true;
01853 }
01854 catch (Exception &e)
01855 {
01856
01857 return false;
01858 }
01859 }
01860
01861 void HeartConfig::EnsurePostProcessingSectionPresent()
01862 {
01863 ENSURE_SECTION_PRESENT(mpUserParameters->PostProcessing(), cp::postprocessing_type);
01864 }
01865
01866 bool HeartConfig::IsPostProcessingRequested() const
01867 {
01868 if (IsPostProcessingSectionPresent() == false)
01869 {
01870 return false;
01871 }
01872 else
01873 {
01874 return(IsApdMapsRequested() ||
01875 IsUpstrokeTimeMapsRequested() ||
01876 IsMaxUpstrokeVelocityMapRequested() ||
01877 IsConductionVelocityMapsRequested());
01878 }
01879 }
01880 bool HeartConfig::IsApdMapsRequested() const
01881 {
01882 assert(IsPostProcessingSectionPresent());
01883
01884 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ActionPotentialDurationMap)&
01885 apd_maps = DecideLocation( & mpUserParameters->PostProcessing(),
01886 & mpDefaultParameters->PostProcessing(),
01887 "ActionPotentialDurationMap")->get().ActionPotentialDurationMap();
01888 return (apd_maps.begin() != apd_maps.end());
01889 }
01890
01891 void HeartConfig::GetApdMaps(std::vector<std::pair<double,double> >& apd_maps) const
01892 {
01893 assert(IsApdMapsRequested());
01894 apd_maps.clear();
01895
01896 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ActionPotentialDurationMap)&
01897 apd_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01898 & mpDefaultParameters->PostProcessing(),
01899 "ActionPotentialDurationMap")->get().ActionPotentialDurationMap();
01900
01901 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::ActionPotentialDurationMap) i = apd_maps_sequence.begin();
01902 i != apd_maps_sequence.end();
01903 ++i)
01904 {
01905 std::pair<double,double> map(i->repolarisation_percentage(),i->threshold());
01906
01907 apd_maps.push_back(map);
01908 }
01909 }
01910
01911 bool HeartConfig::IsUpstrokeTimeMapsRequested() const
01912 {
01913 assert(IsPostProcessingSectionPresent());
01914
01915 XSD_SEQUENCE_TYPE(cp::postprocessing_type::UpstrokeTimeMap)&
01916 upstroke_map = DecideLocation( & mpUserParameters->PostProcessing(),
01917 & mpDefaultParameters->PostProcessing(),
01918 "UpstrokeTimeMap")->get().UpstrokeTimeMap();
01919 return (upstroke_map.begin() != upstroke_map.end());
01920 }
01921 void HeartConfig::GetUpstrokeTimeMaps (std::vector<double>& upstroke_time_maps) const
01922 {
01923 assert(IsUpstrokeTimeMapsRequested());
01924 assert(upstroke_time_maps.size() == 0);
01925
01926 XSD_SEQUENCE_TYPE(cp::postprocessing_type::UpstrokeTimeMap)&
01927 upstroke_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01928 & mpDefaultParameters->PostProcessing(),
01929 "UpstrokeTimeMap")->get().UpstrokeTimeMap();
01930
01931 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::UpstrokeTimeMap) i = upstroke_maps_sequence.begin();
01932 i != upstroke_maps_sequence.end();
01933 ++i)
01934 {
01935 upstroke_time_maps.push_back(i->threshold());
01936 }
01937 }
01938
01939 bool HeartConfig::IsMaxUpstrokeVelocityMapRequested() const
01940 {
01941 assert(IsPostProcessingSectionPresent());
01942
01943 XSD_SEQUENCE_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap)&
01944 max_upstroke_velocity_map = DecideLocation( & mpUserParameters->PostProcessing(),
01945 & mpDefaultParameters->PostProcessing(),
01946 "MaxUpstrokeVelocityMap")->get().MaxUpstrokeVelocityMap();
01947
01948 return (max_upstroke_velocity_map.begin() != max_upstroke_velocity_map.end());
01949 }
01950
01951 void HeartConfig::GetMaxUpstrokeVelocityMaps(std::vector<double>& upstroke_velocity_maps) const
01952 {
01953 assert(IsMaxUpstrokeVelocityMapRequested());
01954 assert(upstroke_velocity_maps.size() == 0);
01955
01956 XSD_SEQUENCE_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap)&
01957 max_upstroke_velocity_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01958 & mpDefaultParameters->PostProcessing(),
01959 "MaxUpstrokeVelocityMap")->get().MaxUpstrokeVelocityMap();
01960
01961 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap) i = max_upstroke_velocity_maps_sequence.begin();
01962 i != max_upstroke_velocity_maps_sequence.end();
01963 ++i)
01964 {
01965 upstroke_velocity_maps.push_back(i->threshold());
01966 }
01967 }
01968
01969 bool HeartConfig::IsConductionVelocityMapsRequested() const
01970 {
01971 assert(IsPostProcessingSectionPresent());
01972
01973 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ConductionVelocityMap)&
01974 cond_vel_maps = DecideLocation( & mpUserParameters->PostProcessing(),
01975 & mpDefaultParameters->PostProcessing(),
01976 "ConductionVelocityMap")->get().ConductionVelocityMap();
01977 return (cond_vel_maps.begin() != cond_vel_maps.end());
01978 }
01979
01980 void HeartConfig::GetConductionVelocityMaps(std::vector<unsigned>& conduction_velocity_maps) const
01981 {
01982 assert(IsConductionVelocityMapsRequested());
01983 assert(conduction_velocity_maps.size() == 0);
01984
01985 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ConductionVelocityMap)&
01986 cond_vel_maps_sequence = DecideLocation( & mpUserParameters->PostProcessing(),
01987 & mpDefaultParameters->PostProcessing(),
01988 "ConductionVelocityMap")->get().ConductionVelocityMap();
01989
01990 for (XSD_ITERATOR_TYPE(cp::postprocessing_type::ConductionVelocityMap) i = cond_vel_maps_sequence.begin();
01991 i != cond_vel_maps_sequence.end();
01992 ++i)
01993 {
01994 conduction_velocity_maps.push_back(i->origin_node());
01995 }
01996 }
01997
01998
01999
02000
02001
02002 bool HeartConfig::IsOutputVisualizerPresent() const
02003 {
02004 CheckSimulationIsDefined("OutputVisualizer");
02005
02006 try
02007 {
02008 DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
02009 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
02010 "OutputVisualizer")->present();
02011
02012 return true;
02013 }
02014 catch (Exception &e)
02015 {
02016
02017 return false;
02018 }
02019 }
02020
02021 bool HeartConfig::GetVisualizeWithMeshalyzer() const
02022 {
02023 if (!IsOutputVisualizerPresent())
02024 {
02025 return true;
02026 }
02027 else
02028 {
02029 return DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
02030 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
02031 "OutputVisualizer")->get().meshalyzer() == cp::yesno_type::yes;
02032 }
02033 }
02034
02035 bool HeartConfig::GetVisualizeWithCmgui() const
02036 {
02037 if (!IsOutputVisualizerPresent())
02038 {
02039 return false;
02040 }
02041 else
02042 {
02043 return DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
02044 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
02045 "OutputVisualizer")->get().cmgui() == cp::yesno_type::yes;
02046 }
02047 }
02048
02049 bool HeartConfig::GetVisualizeWithVtk() const
02050 {
02051 if (!IsOutputVisualizerPresent())
02052 {
02053 return false;
02054 }
02055 else
02056 {
02057 return DecideLocation( & mpUserParameters->Simulation().get().OutputVisualizer(),
02058 & mpDefaultParameters->Simulation().get().OutputVisualizer(),
02059 "OutputVisualizer")->get().vtk() == cp::yesno_type::yes;
02060 }
02061 }
02062
02063
02064 bool HeartConfig::IsElectrodesPresent() const
02065 {
02066 try
02067 {
02068 DecideLocation( & mpUserParameters->Simulation().get().Electrodes(),
02069 & mpDefaultParameters->Simulation().get().Electrodes(),
02070 "Electrodes")->present();
02071
02072 return true;
02073 }
02074 catch (Exception &e)
02075 {
02076
02077 return false;
02078 }
02079 }
02080
02081
02082
02083
02084 void HeartConfig::SetSpaceDimension(unsigned spaceDimension)
02085 {
02086 mpUserParameters->Simulation().get().SpaceDimension().set(spaceDimension);
02087 }
02088
02089 void HeartConfig::SetSimulationDuration(double simulationDuration)
02090 {
02091 XSD_CREATE_WITH_FIXED_ATTR1(cp::time_type, time, simulationDuration, "ms");
02092 mpUserParameters->Simulation().get().SimulationDuration().set(time);
02093 }
02094
02095 void HeartConfig::SetDomain(const cp::domain_type& rDomain)
02096 {
02097 mpUserParameters->Simulation().get().Domain().set(rDomain);
02098 }
02099
02100 void HeartConfig::SetDefaultIonicModel(const cp::ionic_models_available_type& rIonicModel)
02101 {
02102 cp::ionic_model_selection_type ionic_model;
02103 ionic_model.Hardcoded(rIonicModel);
02104 cp::ionic_models_type container(ionic_model);
02105 mpUserParameters->Simulation().get().IonicModels().set(container);
02106 }
02107
02108 void HeartConfig::SetSlabDimensions(double x, double y, double z, double inter_node_space)
02109 {
02110 if ( ! mpUserParameters->Simulation().get().Mesh().present())
02111 {
02112 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
02113 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
02114 }
02115
02116 cp::slab_type slab_definition(x, y, z, inter_node_space);
02117 mpUserParameters->Simulation().get().Mesh().get().Slab().set(slab_definition);
02118 }
02119
02120 void HeartConfig::SetSheetDimensions(double x, double y, double inter_node_space)
02121 {
02122 if ( ! mpUserParameters->Simulation().get().Mesh().present())
02123 {
02124 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
02125 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
02126 }
02127
02128 cp::sheet_type sheet_definition(x, y, inter_node_space);
02129 mpUserParameters->Simulation().get().Mesh().get().Sheet().set(sheet_definition);
02130 }
02131
02132 void HeartConfig::SetFibreLength(double x, double inter_node_space)
02133 {
02134 if ( ! mpUserParameters->Simulation().get().Mesh().present())
02135 {
02136 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
02137 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
02138 }
02139
02140 cp::fibre_type fibre_definition(x, inter_node_space);
02141 mpUserParameters->Simulation().get().Mesh().get().Fibre().set(fibre_definition);
02142 }
02143
02144 void HeartConfig::SetMeshFileName(std::string meshPrefix, cp::media_type fibreDefinition)
02145 {
02146 if ( ! mpUserParameters->Simulation().get().Mesh().present())
02147 {
02148 XSD_CREATE_WITH_FIXED_ATTR(cp::mesh_type, mesh_to_load, "cm");
02149 mpUserParameters->Simulation().get().Mesh().set(mesh_to_load);
02150 }
02151
02152 XSD_NESTED_TYPE(cp::mesh_type::LoadMesh) mesh_prefix(meshPrefix, fibreDefinition);
02153 mpUserParameters->Simulation().get().Mesh().get().LoadMesh().set(mesh_prefix);
02154 }
02155
02156 void HeartConfig::SetIonicModelRegions(std::vector<ChasteCuboid<3> >& rDefinedRegions,
02157 std::vector<cp::ionic_model_selection_type>& rIonicModels) const
02158 {
02159 assert(rDefinedRegions.size() == rIonicModels.size());
02161 XSD_SEQUENCE_TYPE(cp::ionic_models_type::Region)&
02162 regions = mpUserParameters->Simulation().get().IonicModels().get().Region();
02163 regions.clear();
02164 for (unsigned region_index=0; region_index<rDefinedRegions.size(); region_index++)
02165 {
02166 cp::point_type point_a(rDefinedRegions[region_index].rGetLowerCorner()[0],
02167 rDefinedRegions[region_index].rGetLowerCorner()[1],
02168 rDefinedRegions[region_index].rGetLowerCorner()[2]);
02169
02170 cp::point_type point_b(rDefinedRegions[region_index].rGetUpperCorner()[0],
02171 rDefinedRegions[region_index].rGetUpperCorner()[1],
02172 rDefinedRegions[region_index].rGetUpperCorner()[2]);
02173
02174 XSD_CREATE_WITH_FIXED_ATTR(cp::location_type, locn, "cm");
02175 locn.Cuboid().set(cp::box_type(point_a, point_b));
02176
02177 cp::ionic_model_region_type region(rIonicModels[region_index], locn);
02178 regions.push_back(region);
02179 }
02180 }
02181
02182 void HeartConfig::SetConductivityHeterogeneities(std::vector<ChasteCuboid<3> >& conductivityAreas,
02183 std::vector< c_vector<double,3> >& intraConductivities,
02184 std::vector< c_vector<double,3> >& extraConductivities)
02185 {
02186 assert ( conductivityAreas.size() == intraConductivities.size() );
02187 assert ( intraConductivities.size() == extraConductivities.size());
02188
02189 XSD_ANON_SEQUENCE_TYPE(cp::simulation_type, ConductivityHeterogeneities, ConductivityHeterogeneity) heterogeneities_container;
02190
02191 for (unsigned region_index=0; region_index<conductivityAreas.size(); region_index++)
02192 {
02193 cp::point_type point_a(conductivityAreas[region_index].rGetLowerCorner()[0],
02194 conductivityAreas[region_index].rGetLowerCorner()[1],
02195 conductivityAreas[region_index].rGetLowerCorner()[2]);
02196
02197 cp::point_type point_b(conductivityAreas[region_index].rGetUpperCorner()[0],
02198 conductivityAreas[region_index].rGetUpperCorner()[1],
02199 conductivityAreas[region_index].rGetUpperCorner()[2]);
02200
02201 XSD_CREATE_WITH_FIXED_ATTR(cp::location_type, locn, "cm");
02202 locn.Cuboid().set(cp::box_type(point_a, point_b));
02203 cp::conductivity_heterogeneity_type ht(locn);
02204
02205 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
02206 intraConductivities[region_index][0],
02207 intraConductivities[region_index][1],
02208 intraConductivities[region_index][2],
02209 "mS/cm");
02210
02211 ht.IntracellularConductivities(intra);
02212
02213 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
02214 extraConductivities[region_index][0],
02215 extraConductivities[region_index][1],
02216 extraConductivities[region_index][2],
02217 "mS/cm");
02218
02219 ht.ExtracellularConductivities(extra);
02220
02221 heterogeneities_container.push_back(ht);
02222 }
02223
02224 XSD_ANON_TYPE(cp::simulation_type, ConductivityHeterogeneities) heterogeneities_object;
02225 heterogeneities_object.ConductivityHeterogeneity(heterogeneities_container);
02226
02227 mpUserParameters->Simulation().get().ConductivityHeterogeneities().set(heterogeneities_object);
02228 }
02229
02230 void HeartConfig::SetConductivityHeterogeneitiesEllipsoid(std::vector<ChasteEllipsoid<3> >& conductivityAreas,
02231 std::vector< c_vector<double,3> >& intraConductivities,
02232 std::vector< c_vector<double,3> >& extraConductivities)
02233 {
02234 assert ( conductivityAreas.size() == intraConductivities.size() );
02235 assert ( intraConductivities.size() == extraConductivities.size());
02236
02237 XSD_ANON_SEQUENCE_TYPE(cp::simulation_type, ConductivityHeterogeneities, ConductivityHeterogeneity) heterogeneities_container;
02238
02239 for (unsigned region_index=0; region_index<conductivityAreas.size(); region_index++)
02240 {
02241 cp::point_type centre(conductivityAreas[region_index].rGetCentre()[0],
02242 conductivityAreas[region_index].rGetCentre()[1],
02243 conductivityAreas[region_index].rGetCentre()[2]);
02244
02245 cp::point_type radii(conductivityAreas[region_index].rGetRadii()[0],
02246 conductivityAreas[region_index].rGetRadii()[1],
02247 conductivityAreas[region_index].rGetRadii()[2]);
02248
02249 XSD_CREATE_WITH_FIXED_ATTR(cp::location_type, locn, "cm");
02250 locn.Ellipsoid().set(cp::ellipsoid_type(centre, radii));
02251 cp::conductivity_heterogeneity_type ht(locn);
02252
02253 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
02254 intraConductivities[region_index][0],
02255 intraConductivities[region_index][1],
02256 intraConductivities[region_index][2],
02257 "mS/cm");
02258
02259 ht.IntracellularConductivities(intra);
02260
02261 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
02262 extraConductivities[region_index][0],
02263 extraConductivities[region_index][1],
02264 extraConductivities[region_index][2],
02265 "mS/cm");
02266
02267 ht.ExtracellularConductivities(extra);
02268
02269 heterogeneities_container.push_back(ht);
02270 }
02271
02272 XSD_ANON_TYPE(cp::simulation_type, ConductivityHeterogeneities) heterogeneities_object;
02273 heterogeneities_object.ConductivityHeterogeneity(heterogeneities_container);
02274
02275 mpUserParameters->Simulation().get().ConductivityHeterogeneities().set(heterogeneities_object);
02276 }
02277
02278 void HeartConfig::SetOutputDirectory(const std::string& rOutputDirectory)
02279 {
02280 mpUserParameters->Simulation().get().OutputDirectory().set(rOutputDirectory);
02281 }
02282
02283 void HeartConfig::SetOutputFilenamePrefix(const std::string& rOutputFilenamePrefix)
02284 {
02285 mpUserParameters->Simulation().get().OutputFilenamePrefix().set(rOutputFilenamePrefix);
02286 }
02287
02288 void HeartConfig::SetOutputVariables(const std::vector<std::string>& rOutputVariables)
02289 {
02290 if ( ! mpUserParameters->Simulation()->OutputVariables().present())
02291 {
02292 cp::output_variables_type variables_requested;
02293 mpUserParameters->Simulation()->OutputVariables().set(variables_requested);
02294 }
02295
02296 XSD_SEQUENCE_TYPE(cp::output_variables_type::Var)&
02297 var_type_sequence = mpUserParameters->Simulation()->OutputVariables()->Var();
02298
02299 var_type_sequence.clear();
02300
02301 for (unsigned i=0; i<rOutputVariables.size(); i++)
02302 {
02303 cp::var_type temp(rOutputVariables[i]);
02304 var_type_sequence.push_back(temp);
02305 }
02306
02307 if (rOutputVariables.size() > 0)
02308 {
02309
02311 SetVisualizeWithMeshalyzer(false);
02312 SetVisualizeWithCmgui(false);
02313 SetVisualizeWithVtk(false);
02314 }
02315 }
02316
02317 void HeartConfig::SetOutputUsingOriginalNodeOrdering(bool useOriginal)
02318 {
02319
02320 mpUserParameters->Simulation().get().OutputUsingOriginalNodeOrdering().set(useOriginal? cp::yesno_type::yes : cp::yesno_type::no);
02321 }
02322
02323 void HeartConfig::SetCheckpointSimulation(bool saveSimulation, double checkpointTimestep, unsigned maxCheckpointsOnDisk)
02324 {
02325 if (saveSimulation)
02326 {
02327
02328 assert(checkpointTimestep!=-1.0 && maxCheckpointsOnDisk!=UINT_MAX);
02329
02330 XSD_CREATE_WITH_FIXED_ATTR2(cp::simulation_type::XSD_NESTED_TYPE(CheckpointSimulation),
02331 cs,
02332 checkpointTimestep,
02333 maxCheckpointsOnDisk,
02334 "ms");
02335 mpUserParameters->Simulation().get().CheckpointSimulation().set(cs);
02336 }
02337 else
02338 {
02339 mpUserParameters->Simulation().get().CheckpointSimulation().reset();
02340 }
02341
02342 CheckTimeSteps();
02343 }
02344
02345
02346 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 3>& intraConductivities)
02347 {
02348 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
02349 intraConductivities[0],
02350 intraConductivities[1],
02351 intraConductivities[2],
02352 "mS/cm");
02353
02354 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
02355 }
02356
02357 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 2>& intraConductivities)
02358 {
02359 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
02360 intraConductivities[0],
02361 intraConductivities[1],
02362 0.0, "mS/cm");
02363
02364 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
02365 }
02366
02367 void HeartConfig::SetIntracellularConductivities(const c_vector<double, 1>& intraConductivities)
02368 {
02369 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, intra,
02370 intraConductivities[0],
02371 0.0, 0.0, "mS/cm");
02372
02373 mpUserParameters->Physiological().IntracellularConductivities().set(intra);
02374 }
02375
02376 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 3>& extraConductivities)
02377 {
02378 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
02379 extraConductivities[0],
02380 extraConductivities[1],
02381 extraConductivities[2],
02382 "mS/cm");
02383
02384 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
02385 }
02386
02387 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 2>& extraConductivities)
02388 {
02389 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
02390 extraConductivities[0],
02391 extraConductivities[1],
02392 0.0, "mS/cm");
02393
02394 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
02395 }
02396
02397 void HeartConfig::SetExtracellularConductivities(const c_vector<double, 1>& extraConductivities)
02398 {
02399 XSD_CREATE_WITH_FIXED_ATTR3(cp::conductivities_type, extra,
02400 extraConductivities[0],
02401 0.0, 0.0, "mS/cm");
02402
02403 mpUserParameters->Physiological().ExtracellularConductivities().set(extra);
02404 }
02405
02406 void HeartConfig::SetBathConductivity(double bathConductivity)
02407 {
02408 XSD_CREATE_WITH_FIXED_ATTR1(cp::conductivity_type, cond, bathConductivity, "mS/cm");
02409 mpUserParameters->Physiological().BathConductivity().set(cond);
02410 }
02411
02412 void HeartConfig::SetSurfaceAreaToVolumeRatio(double ratio)
02413 {
02414 XSD_CREATE_WITH_FIXED_ATTR1(cp::inverse_length_type, ratio_object, ratio, "1/cm");
02415 mpUserParameters->Physiological().SurfaceAreaToVolumeRatio().set(ratio_object);
02416 }
02417
02418 void HeartConfig::SetCapacitance(double capacitance)
02419 {
02420 XSD_CREATE_WITH_FIXED_ATTR1(cp::capacitance_type, capacitance_object, capacitance, "uF/cm^2");
02421 mpUserParameters->Physiological().Capacitance().set(capacitance_object);
02422 }
02423
02424
02425
02426 void HeartConfig::SetOdePdeAndPrintingTimeSteps(double odeTimeStep, double pdeTimeStep, double printingTimeStep)
02427 {
02428 XSD_CREATE_WITH_FIXED_ATTR3(cp::time_steps_type, time_steps,
02429 odeTimeStep, pdeTimeStep, printingTimeStep, "ms");
02430 mpUserParameters->Numerical().TimeSteps().set(time_steps);
02431 CheckTimeSteps();
02432 }
02433
02434 void HeartConfig::SetOdeTimeStep(double odeTimeStep)
02435 {
02436 SetOdePdeAndPrintingTimeSteps(odeTimeStep, GetPdeTimeStep(), GetPrintingTimeStep());
02437 }
02438
02439 void HeartConfig::SetPdeTimeStep(double pdeTimeStep)
02440 {
02441 SetOdePdeAndPrintingTimeSteps(GetOdeTimeStep(), pdeTimeStep, GetPrintingTimeStep());
02442 }
02443
02444 void HeartConfig::SetPrintingTimeStep(double printingTimeStep)
02445 {
02446 SetOdePdeAndPrintingTimeSteps(GetOdeTimeStep(), GetPdeTimeStep(), printingTimeStep);
02447 }
02448
02449 void HeartConfig::CheckTimeSteps() const
02450 {
02451 if (GetOdeTimeStep() <= 0)
02452 {
02453 EXCEPTION("Ode time-step should be positive");
02454 }
02455 if (GetPdeTimeStep() <= 0)
02456 {
02457 EXCEPTION("Pde time-step should be positive");
02458 }
02459 if (GetPrintingTimeStep() <= 0.0)
02460 {
02461 EXCEPTION("Printing time-step should be positive");
02462 }
02463
02464 if (GetPdeTimeStep()>GetPrintingTimeStep())
02465 {
02466 EXCEPTION("Printing time-step should not be smaller than PDE time-step");
02467 }
02468
02469 if ( !Divides(GetPdeTimeStep(), GetPrintingTimeStep()) )
02470 {
02471 EXCEPTION("Printing time-step should be a multiple of PDE time step");
02472 }
02473
02474 if ( GetOdeTimeStep() > GetPdeTimeStep() )
02475 {
02476 EXCEPTION("Ode time-step should not be greater than PDE time-step");
02477 }
02478
02479 if (GetCheckpointSimulation())
02480 {
02481 if (GetCheckpointTimestep() <= 0.0)
02482 {
02483 EXCEPTION("Checkpoint time-step should be positive");
02484 }
02485
02486 if ( !Divides(GetPrintingTimeStep(), GetCheckpointTimestep()) )
02487 {
02488 EXCEPTION("Checkpoint time-step should be a multiple of printing time-step");
02489 }
02490 }
02491 }
02492
02493
02494 void HeartConfig::SetUseRelativeTolerance(double relativeTolerance)
02495 {
02496 ENSURE_SECTION_PRESENT(mpUserParameters->Numerical().KSPTolerances(), cp::ksp_tolerances_type);
02497
02498 mpUserParameters->Numerical().KSPTolerances()->KSPAbsolute().reset();
02499 mpUserParameters->Numerical().KSPTolerances()->KSPRelative().set(relativeTolerance);
02500 }
02501
02502 void HeartConfig::SetUseAbsoluteTolerance(double absoluteTolerance)
02503 {
02504 ENSURE_SECTION_PRESENT(mpUserParameters->Numerical().KSPTolerances(), cp::ksp_tolerances_type);
02505
02506 mpUserParameters->Numerical().KSPTolerances()->KSPRelative().reset();
02507 mpUserParameters->Numerical().KSPTolerances()->KSPAbsolute().set(absoluteTolerance);
02508 }
02509
02510 void HeartConfig::SetKSPSolver(const char* kspSolver)
02511 {
02512
02513 if ( strcmp(kspSolver, "gmres") == 0)
02514 {
02515 mpUserParameters->Numerical().KSPSolver().set(cp::ksp_solver_type::gmres);
02516 return;
02517 }
02518 if ( strcmp(kspSolver, "cg") == 0)
02519 {
02520 mpUserParameters->Numerical().KSPSolver().set(cp::ksp_solver_type::cg);
02521 return;
02522 }
02523 if ( strcmp(kspSolver, "symmlq") == 0)
02524 {
02525 mpUserParameters->Numerical().KSPSolver().set(cp::ksp_solver_type::symmlq);
02526 return;
02527 }
02528
02529 EXCEPTION("Unknown solver type provided");
02530 }
02531
02532 void HeartConfig::SetKSPPreconditioner(const char* kspPreconditioner)
02533 {
02534
02535 if ( strcmp(kspPreconditioner, "jacobi") == 0)
02536 {
02537 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::jacobi);
02538 return;
02539 }
02540 if ( strcmp(kspPreconditioner, "bjacobi") == 0)
02541 {
02542 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::bjacobi);
02543 return;
02544 }
02545 if ( strcmp(kspPreconditioner, "hypre") == 0)
02546 {
02547 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::hypre);
02548 return;
02549 }
02550 if ( strcmp(kspPreconditioner, "ml") == 0)
02551 {
02552 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::ml);
02553 return;
02554 }
02555 if ( strcmp(kspPreconditioner, "spai") == 0)
02556 {
02557 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::spai);
02558 return;
02559 }
02560 if ( strcmp(kspPreconditioner, "twolevelsblockdiagonal") == 0)
02561 {
02562 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::twolevelsblockdiagonal);
02563 return;
02564 }
02565 if ( strcmp(kspPreconditioner, "blockdiagonal") == 0)
02566 {
02567 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::blockdiagonal);
02568 return;
02569 }
02570 if ( strcmp(kspPreconditioner, "ldufactorisation") == 0)
02571 {
02572 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::ldufactorisation);
02573 return;
02574 }
02575 if ( strcmp(kspPreconditioner, "none") == 0)
02576 {
02577 mpUserParameters->Numerical().KSPPreconditioner().set(cp::ksp_preconditioner_type::none);
02578 return;
02579 }
02580
02581 EXCEPTION("Unknown preconditioner type provided");
02582 }
02583
02584 void HeartConfig::SetAdaptivityParameters(double targetError,
02585 double sigma,
02586 double maxEdgeLength,
02587 double minEdgeLength,
02588 double gradation,
02589 unsigned maxNodes,
02590 unsigned numSweeps )
02591 {
02592 if ( maxEdgeLength < minEdgeLength )
02593 {
02594 EXCEPTION("AdaptivityParameters: maxEdgeLength must be greater than minEdgeLength.");
02595 }
02597 if (!IsAdaptivityParametersPresent())
02598 {
02599 cp::adaptivity_parameters_type element(targetError,
02600 sigma,
02601 maxEdgeLength,
02602 minEdgeLength,
02603 gradation,
02604 maxNodes,
02605 numSweeps );
02606 mpUserParameters->Numerical().AdaptivityParameters().set(element);
02607 }
02608 else
02609 {
02610 mpUserParameters->Numerical().AdaptivityParameters().get().target_error(targetError);
02611 mpUserParameters->Numerical().AdaptivityParameters().get().sigma(sigma);
02612 mpUserParameters->Numerical().AdaptivityParameters().get().max_edge_length(maxEdgeLength);
02613 mpUserParameters->Numerical().AdaptivityParameters().get().min_edge_length(minEdgeLength);
02614 mpUserParameters->Numerical().AdaptivityParameters().get().gradation(gradation);
02615 mpUserParameters->Numerical().AdaptivityParameters().get().max_nodes(maxNodes);
02616 mpUserParameters->Numerical().AdaptivityParameters().get().num_sweeps(numSweeps);
02617 }
02618 }
02619
02620 void HeartConfig::SetTargetErrorForAdaptivity(double targetError)
02621 {
02622 SetAdaptivityParameters( targetError,
02623 GetSigmaForAdaptivity(),
02624 GetMaxEdgeLengthForAdaptivity(),
02625 GetMinEdgeLengthForAdaptivity(),
02626 GetGradationForAdaptivity(),
02627 GetMaxNodesForAdaptivity(),
02628 GetNumberOfAdaptiveSweeps() );
02629 }
02630
02631 void HeartConfig::SetSigmaForAdaptivity(double sigma)
02632 {
02633 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02634 sigma,
02635 GetMaxEdgeLengthForAdaptivity(),
02636 GetMinEdgeLengthForAdaptivity(),
02637 GetGradationForAdaptivity(),
02638 GetMaxNodesForAdaptivity(),
02639 GetNumberOfAdaptiveSweeps() );
02640 }
02641
02642 void HeartConfig::SetMaxEdgeLengthForAdaptivity(double maxEdgeLength)
02643 {
02644 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02645 GetSigmaForAdaptivity(),
02646 maxEdgeLength,
02647 GetMinEdgeLengthForAdaptivity(),
02648 GetGradationForAdaptivity(),
02649 GetMaxNodesForAdaptivity(),
02650 GetNumberOfAdaptiveSweeps() );
02651 }
02652
02653 void HeartConfig::SetMinEdgeLengthForAdaptivity(double minEdgeLength)
02654 {
02655 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02656 GetSigmaForAdaptivity(),
02657 GetMaxEdgeLengthForAdaptivity(),
02658 minEdgeLength,
02659 GetGradationForAdaptivity(),
02660 GetMaxNodesForAdaptivity(),
02661 GetNumberOfAdaptiveSweeps() );
02662 }
02663
02664 void HeartConfig::SetGradationForAdaptivity(double gradation)
02665 {
02666 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02667 GetSigmaForAdaptivity(),
02668 GetMaxEdgeLengthForAdaptivity(),
02669 GetMinEdgeLengthForAdaptivity(),
02670 gradation,
02671 GetMaxNodesForAdaptivity(),
02672 GetNumberOfAdaptiveSweeps() );
02673 }
02674
02675 void HeartConfig::SetMaxNodesForAdaptivity(unsigned maxNodes)
02676 {
02677 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02678 GetSigmaForAdaptivity(),
02679 GetMaxEdgeLengthForAdaptivity(),
02680 GetMinEdgeLengthForAdaptivity(),
02681 GetGradationForAdaptivity(),
02682 maxNodes,
02683 GetNumberOfAdaptiveSweeps() );
02684 }
02685
02686 void HeartConfig::SetNumberOfAdaptiveSweeps(unsigned numSweeps)
02687 {
02688 SetAdaptivityParameters( GetTargetErrorForAdaptivity(),
02689 GetSigmaForAdaptivity(),
02690 GetMaxEdgeLengthForAdaptivity(),
02691 GetMinEdgeLengthForAdaptivity(),
02692 GetGradationForAdaptivity(),
02693 GetMaxNodesForAdaptivity(),
02694 numSweeps );
02695 }
02696
02697 void HeartConfig::SetApdMaps(const std::vector<std::pair<double,double> >& apdMaps)
02698 {
02699 EnsurePostProcessingSectionPresent();
02700 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ActionPotentialDurationMap)& apd_maps_sequence
02701 = mpUserParameters->PostProcessing()->ActionPotentialDurationMap();
02702
02703 apd_maps_sequence.clear();
02704
02705 for (unsigned i=0; i<apdMaps.size(); i++)
02706 {
02707 XSD_CREATE_WITH_FIXED_ATTR2(cp::apd_map_type, temp,
02708 apdMaps[i].first, apdMaps[i].second,
02709 "mV");
02710 apd_maps_sequence.push_back( temp);
02711 }
02712 }
02713
02714
02715 void HeartConfig::SetUpstrokeTimeMaps (std::vector<double>& upstrokeTimeMaps)
02716 {
02717 EnsurePostProcessingSectionPresent();
02718 XSD_SEQUENCE_TYPE(cp::postprocessing_type::UpstrokeTimeMap)& var_type_sequence
02719 = mpUserParameters->PostProcessing()->UpstrokeTimeMap();
02720
02721
02722 var_type_sequence.clear();
02723
02724 for (unsigned i=0; i<upstrokeTimeMaps.size(); i++)
02725 {
02726 XSD_CREATE_WITH_FIXED_ATTR1(cp::upstrokes_map_type, temp,
02727 upstrokeTimeMaps[i],
02728 "mV");
02729 var_type_sequence.push_back(temp);
02730 }
02731 }
02732
02733 void HeartConfig::SetMaxUpstrokeVelocityMaps (std::vector<double>& maxUpstrokeVelocityMaps)
02734 {
02735 EnsurePostProcessingSectionPresent();
02736 XSD_SEQUENCE_TYPE(cp::postprocessing_type::MaxUpstrokeVelocityMap)& max_upstroke_velocity_maps_sequence
02737 = mpUserParameters->PostProcessing()->MaxUpstrokeVelocityMap();
02738
02739
02740 max_upstroke_velocity_maps_sequence.clear();
02741
02742 for (unsigned i=0; i<maxUpstrokeVelocityMaps.size(); i++)
02743 {
02744 XSD_CREATE_WITH_FIXED_ATTR1(cp::max_upstrokes_velocity_map_type, temp,
02745 maxUpstrokeVelocityMaps[i],
02746 "mV");
02747
02748
02749 max_upstroke_velocity_maps_sequence.push_back(temp);
02750 }
02751
02752 }
02753
02754 void HeartConfig::SetConductionVelocityMaps (std::vector<unsigned>& conductionVelocityMaps)
02755 {
02756 EnsurePostProcessingSectionPresent();
02757 XSD_SEQUENCE_TYPE(cp::postprocessing_type::ConductionVelocityMap)& conduction_velocity_maps_sequence
02758 = mpUserParameters->PostProcessing()->ConductionVelocityMap();
02759
02760
02761 conduction_velocity_maps_sequence.clear();
02762
02763 for (unsigned i=0; i<conductionVelocityMaps.size(); i++)
02764 {
02765 cp::conduction_velocity_map_type temp(conductionVelocityMaps[i]);
02766 conduction_velocity_maps_sequence.push_back(temp);
02767 }
02768 }
02769
02770
02771
02772
02773
02774 void HeartConfig::EnsureOutputVisualizerExists()
02775 {
02776 ENSURE_SECTION_PRESENT(mpUserParameters->Simulation()->OutputVisualizer(), cp::output_visualizer_type);
02777 }
02778
02779 void HeartConfig::SetVisualizeWithMeshalyzer(bool useMeshalyzer)
02780 {
02781 EnsureOutputVisualizerExists();
02782
02783 mpUserParameters->Simulation().get().OutputVisualizer().get().meshalyzer(
02784 useMeshalyzer ? cp::yesno_type::yes : cp::yesno_type::no);
02785 }
02786
02787 void HeartConfig::SetVisualizeWithCmgui(bool useCmgui)
02788 {
02789 EnsureOutputVisualizerExists();
02790
02791 mpUserParameters->Simulation().get().OutputVisualizer().get().cmgui(
02792 useCmgui ? cp::yesno_type::yes : cp::yesno_type::no);
02793 }
02794
02795 void HeartConfig::SetVisualizeWithVtk(bool useVtk)
02796 {
02797 EnsureOutputVisualizerExists();
02798
02799 mpUserParameters->Simulation().get().OutputVisualizer().get().vtk(
02800 useVtk ? cp::yesno_type::yes : cp::yesno_type::no);
02801 }
02802
02803 void HeartConfig::SetElectrodeParameters(bool groundSecondElectrode,
02804 unsigned index, double magnitude,
02805 double startTime, double duration )
02806 {
02807 assert(index < 3);
02808
02809 cp::axis_type axis = cp::axis_type::x;
02810 if (index==1)
02811 {
02812 axis = cp::axis_type::y;
02813 }
02814 else if (index==2)
02815 {
02816 axis = cp::axis_type::z;
02817 }
02818
02819 XSD_CREATE_WITH_FIXED_ATTR1(cp::surface_stimulus_strength_type, strength, magnitude, "uA/cm^2");
02820 XSD_CREATE_WITH_FIXED_ATTR1(cp::time_type, start_time, startTime, "ms");
02821 XSD_CREATE_WITH_FIXED_ATTR1(cp::time_type, duration_time, duration, "ms");
02822
02823 if (!IsElectrodesPresent())
02824 {
02825 cp::electrodes_type element( groundSecondElectrode ? cp::yesno_type::yes : cp::yesno_type::no,
02826 axis,
02827 strength,
02828 start_time,
02829 duration_time );
02830 mpUserParameters->Simulation().get().Electrodes().set(element);
02831 }
02832 else
02833 {
02834 mpUserParameters->Simulation().get().Electrodes().get().GroundSecondElectrode(groundSecondElectrode ? cp::yesno_type::yes : cp::yesno_type::no);
02835 mpUserParameters->Simulation().get().Electrodes().get().PerpendicularToAxis(axis);
02836 mpUserParameters->Simulation().get().Electrodes().get().Strength(strength);
02837 mpUserParameters->Simulation().get().Electrodes().get().StartTime(start_time);
02838 mpUserParameters->Simulation().get().Electrodes().get().Duration(duration_time);
02839 }
02840 }
02841
02842 void HeartConfig::GetElectrodeParameters(bool& rGroundSecondElectrode,
02843 unsigned& rIndex, double& rMagnitude,
02844 double& rStartTime, double& rDuration )
02845 {
02846 if (!IsElectrodesPresent())
02847 {
02848 EXCEPTION("Attempted to get electrodes that have not been defined.");
02849 }
02850 else
02851 {
02852 rGroundSecondElectrode = (mpUserParameters->Simulation().get().Electrodes().get().GroundSecondElectrode()==cp::yesno_type::yes);
02853
02854 cp::axis_type axis = mpUserParameters->Simulation().get().Electrodes().get().PerpendicularToAxis();
02855 if (axis==cp::axis_type::x)
02856 {
02857 rIndex = 0;
02858 }
02859 else if (axis==cp::axis_type::y)
02860 {
02861 rIndex = 1;
02862 }
02863 else
02864 {
02865 rIndex = 2;
02866 }
02867
02868 rMagnitude = mpUserParameters->Simulation().get().Electrodes().get().Strength();
02869 rStartTime = mpUserParameters->Simulation().get().Electrodes().get().StartTime();
02870 rDuration = mpUserParameters->Simulation().get().Electrodes().get().Duration();
02871 }
02872
02873 }
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883 xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument> XmlTools::ReadFileToDomDocument(
02884 const std::string& rFileName,
02885 ::xml_schema::error_handler& rErrorHandler,
02886 const ::xml_schema::properties& rProps)
02887 {
02888 using namespace xercesc;
02889 namespace xml = xsd::cxx::xml;
02890 namespace tree = xsd::cxx::tree;
02891
02892
02893 const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
02894 DOMImplementation* p_impl(DOMImplementationRegistry::getDOMImplementation(ls_id));
02895
02896 #if _XERCES_VERSION >= 30000
02897
02898 xml::dom::auto_ptr<DOMLSParser> p_parser(p_impl->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
02899 DOMConfiguration* p_conf(p_parser->getDomConfig());
02900
02901
02902 p_conf->setParameter(XMLUni::fgDOMComments, false);
02903
02904
02905 p_conf->setParameter(XMLUni::fgDOMDatatypeNormalization, true);
02906
02907
02908
02909
02910
02911 p_conf->setParameter(XMLUni::fgDOMEntities, false);
02912
02913
02914 p_conf->setParameter(XMLUni::fgDOMNamespaces, true);
02915
02916
02917 p_conf->setParameter(XMLUni::fgDOMElementContentWhitespace, false);
02918
02919
02920 p_conf->setParameter(XMLUni::fgDOMValidate, true);
02921 p_conf->setParameter(XMLUni::fgXercesSchema, true);
02922 p_conf->setParameter(XMLUni::fgXercesSchemaFullChecking, false);
02923
02924 if (!rProps.schema_location().empty())
02925 {
02926 xml::string locn(rProps.schema_location());
02927 const void* p_locn(locn.c_str());
02928 p_conf->setParameter(XMLUni::fgXercesSchemaExternalSchemaLocation,
02929 const_cast<void*>(p_locn));
02930 }
02931 if (!rProps.no_namespace_schema_location().empty())
02932 {
02933 xml::string locn(rProps.no_namespace_schema_location());
02934 const void* p_locn(locn.c_str());
02935
02936 p_conf->setParameter(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
02937 const_cast<void*>(p_locn));
02938 }
02939
02940
02941 p_conf->setParameter(XMLUni::fgXercesUserAdoptsDOMDocument, true);
02942
02943
02944 xml::dom::bits::error_handler_proxy<char> ehp(rErrorHandler);
02945 p_conf->setParameter(XMLUni::fgDOMErrorHandler, &ehp);
02946
02947 #else // _XERCES_VERSION >= 30000
02948
02949 xml::dom::auto_ptr<DOMBuilder> p_parser(p_impl->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
02950
02951 p_parser->setFeature(XMLUni::fgDOMComments, false);
02952 p_parser->setFeature(XMLUni::fgDOMDatatypeNormalization, true);
02953 p_parser->setFeature(XMLUni::fgDOMEntities, false);
02954 p_parser->setFeature(XMLUni::fgDOMNamespaces, true);
02955 p_parser->setFeature(XMLUni::fgDOMWhitespaceInElementContent, false);
02956 p_parser->setFeature(XMLUni::fgDOMValidation, true);
02957 p_parser->setFeature(XMLUni::fgXercesSchema, true);
02958 p_parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
02959 p_parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument, true);
02960
02961
02962 if (!rProps.schema_location().empty())
02963 {
02964 xml::string locn(rProps.schema_location());
02965 const void* p_locn(locn.c_str());
02966 p_parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,
02967 const_cast<void*>(p_locn));
02968 }
02969
02970 if (!rProps.no_namespace_schema_location().empty())
02971 {
02972 xml::string locn(rProps.no_namespace_schema_location());
02973 const void* p_locn(locn.c_str());
02974
02975 p_parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
02976 const_cast<void*>(p_locn));
02977 }
02978
02979 xml::dom::bits::error_handler_proxy<char> ehp(rErrorHandler);
02980 p_parser->setErrorHandler(&ehp);
02981
02982 #endif // _XERCES_VERSION >= 30000
02983
02984
02985 xml::dom::auto_ptr<DOMDocument> p_doc(p_parser->parseURI(rFileName.c_str()));
02986
02987 if (ehp.failed())
02988 {
02989 p_doc.reset();
02990 }
02991
02992 return p_doc;
02993 }
02994
02995 #define COVERAGE_IGNORE
02996 void XmlTools::PrintNode(const std::string& rMsg, xercesc::DOMNode* pNode, bool showChildren)
02997 {
02998 std::string prefix = xsd::cxx::xml::transcode<char>(pNode->getPrefix());
02999 std::string name = xsd::cxx::xml::transcode<char>(pNode->getLocalName());
03000 std::string nsuri = xsd::cxx::xml::transcode<char>(pNode->getNamespaceURI());
03001 std::cout << rMsg << " " << pNode << " " << prefix << ":" << name << " in " << nsuri << std::endl;
03002 if (showChildren)
03003 {
03004 for (xercesc::DOMNode* p_node = pNode->getFirstChild();
03005 p_node != NULL;
03006 p_node = p_node->getNextSibling())
03007 {
03008 std::cout << " child type " << p_node->getNodeType();
03009 PrintNode("", p_node, false);
03010 }
03011 xercesc::DOMNamedNodeMap* p_attrs = pNode->getAttributes();
03012 if (p_attrs)
03013 {
03014 for (XMLSize_t i=0; i<p_attrs->getLength(); i++)
03015 {
03016 xercesc::DOMNode* p_attr = p_attrs->item(i);
03017 std::string value = xsd::cxx::xml::transcode<char>(p_attr->getNodeValue());
03018 PrintNode(" attr (" + value + ")", p_attr, false);
03019 }
03020 }
03021 }
03022 }
03023 #undef COVERAGE_IGNORE
03024
03025 xercesc::DOMElement* XmlTools::SetNamespace(xercesc::DOMDocument* pDocument,
03026 xercesc::DOMElement* pElement,
03027 const XMLCh* pNamespace)
03028 {
03029 using namespace xercesc;
03030
03031
03032 DOMNamedNodeMap* p_orig_attrs = pElement->getAttributes();
03033 std::vector<std::string> attr_values;
03034 if (p_orig_attrs)
03035 {
03036 for (XMLSize_t i=0; i<p_orig_attrs->getLength(); i++)
03037 {
03038 DOMNode* p_attr = p_orig_attrs->item(i);
03039 attr_values.push_back(xsd::cxx::xml::transcode<char>(p_attr->getNodeValue()));
03040 }
03041 }
03042 DOMElement* p_new_elt = static_cast<DOMElement*>(
03043 pDocument->renameNode(pElement, pNamespace, pElement->getLocalName()));
03044
03045
03046 if (p_orig_attrs)
03047 {
03048 DOMNamedNodeMap* p_new_attrs = p_new_elt->getAttributes();
03049 assert(p_new_attrs);
03050 assert(p_new_attrs == p_orig_attrs);
03051 assert(p_new_attrs->getLength() == attr_values.size());
03052 for (XMLSize_t i=0; i<p_new_attrs->getLength(); i++)
03053 {
03054 DOMNode* p_attr = p_new_attrs->item(i);
03055 p_attr->setNodeValue(X(attr_values[i]));
03056 }
03057 }
03058
03059
03060 for (DOMNode* p_node = p_new_elt->getFirstChild();
03061 p_node != NULL;
03062 p_node = p_node->getNextSibling())
03063 {
03064 if (p_node->getNodeType() == DOMNode::ELEMENT_NODE)
03065 {
03066 p_node = SetNamespace(pDocument, static_cast<DOMElement*>(p_node), pNamespace);
03067 }
03068 }
03069
03070 return p_new_elt;
03071 }
03072
03073 xercesc::DOMElement* XmlTools::SetNamespace(xercesc::DOMDocument* pDocument,
03074 xercesc::DOMElement* pElement,
03075 const std::string& rNamespace)
03076 {
03077 return SetNamespace(pDocument, pElement, X(rNamespace));
03078 }
03079
03080 void XmlTools::FindElements(xercesc::DOMElement* pContextElement,
03081 const std::vector<std::string>& rNames,
03082 std::vector<xercesc::DOMElement*>& rResults,
03083 unsigned depth)
03084 {
03085 xercesc::DOMNodeList* p_child_elts = pContextElement->getElementsByTagName(X(rNames[depth]));
03086 unsigned num_children = p_child_elts->getLength();
03087 for (unsigned i=0; i<num_children; i++)
03088 {
03089 xercesc::DOMElement* p_child_elt = static_cast<xercesc::DOMElement*>(p_child_elts->item(i));
03090 if (depth == rNames.size() - 1)
03091 {
03092 rResults.push_back(p_child_elt);
03093 }
03094 else
03095 {
03096 FindElements(p_child_elt, rNames, rResults, depth+1);
03097 }
03098 }
03099 }
03100
03101 std::vector<xercesc::DOMElement*> XmlTools::FindElements(xercesc::DOMElement* pContextElement,
03102 const std::string& rPath)
03103 {
03104 std::vector<xercesc::DOMElement*> results;
03105 std::vector<std::string> path;
03106 size_t start_pos = 0;
03107 size_t slash_pos = 0;
03108 while (slash_pos != std::string::npos)
03109 {
03110 slash_pos = rPath.find('/', start_pos);
03111 if (slash_pos == std::string::npos)
03112 {
03113 path.push_back(rPath.substr(start_pos));
03114 }
03115 else
03116 {
03117 path.push_back(rPath.substr(start_pos, slash_pos-start_pos));
03118 }
03119 start_pos = slash_pos + 1;
03120 }
03121 FindElements(pContextElement, path, results);
03122 return results;
03123 }
03124
03125 void XmlTools::WrapContentInElement(xercesc::DOMDocument* pDocument,
03126 xercesc::DOMElement* pElement,
03127 const XMLCh* pNewElementLocalName)
03128 {
03129 const XMLCh* p_namespace_uri = pElement->getNamespaceURI();
03130 const XMLCh* p_prefix = pElement->getPrefix();
03131 const XMLCh* p_qualified_name;
03132 if (p_prefix)
03133 {
03134 #define COVERAGE_IGNORE
03135
03136
03137 xercesc::QName qname(p_prefix, pNewElementLocalName, 0);
03138 p_qualified_name = qname.getRawName();
03139 #undef COVERAGE_IGNORE
03140 }
03141 else
03142 {
03143 p_qualified_name = pNewElementLocalName;
03144 }
03145 xercesc::DOMElement* p_wrapper_elt = pDocument->createElementNS(p_namespace_uri, p_qualified_name);
03146
03147 xercesc::DOMNodeList* p_children = pElement->getChildNodes();
03148 for (unsigned i=0; i<p_children->getLength(); i++)
03149 {
03150 xercesc::DOMNode* p_child = pElement->removeChild(p_children->item(i));
03151 p_wrapper_elt->appendChild(p_child);
03152 }
03153
03154 pElement->appendChild(p_wrapper_elt);
03155 }
03156
03157
03158 void XmlTransforms::TransformArchiveDirectory(xercesc::DOMDocument* pDocument,
03159 xercesc::DOMElement* pRootElement)
03160 {
03161 using namespace xercesc;
03162 std::vector<xercesc::DOMElement*> elts = XmlTools::FindElements(
03163 pRootElement,
03164 "ResumeSimulation/ArchiveDirectory");
03165 if (elts.size() > 0)
03166 {
03167
03168 DOMElement* p_dir_elt = elts[0];
03169
03170 p_dir_elt->setAttribute(X("relative_to"), X("chaste_test_output"));
03171
03172 }
03173 }
03174
03175 void XmlTransforms::TransformIonicModelDefinitions(xercesc::DOMDocument* pDocument,
03176 xercesc::DOMElement* pRootElement)
03177 {
03178
03179 std::vector<xercesc::DOMElement*> p_elt_list = XmlTools::FindElements(
03180 pRootElement,
03181 "Simulation/IonicModels/Default");
03182 if (p_elt_list.size() > 0)
03183 {
03184 assert(p_elt_list.size() == 1);
03185 XmlTools::WrapContentInElement(pDocument, p_elt_list[0], X("Hardcoded"));
03186
03187 p_elt_list = XmlTools::FindElements(pRootElement, "Simulation/IonicModels/Region/IonicModel");
03188 for (unsigned i=0; i<p_elt_list.size(); i++)
03189 {
03190 XmlTools::WrapContentInElement(pDocument, p_elt_list[i], X("Hardcoded"));
03191 }
03192 }
03193 }
03194
03195 void XmlTransforms::CheckForIluPreconditioner(xercesc::DOMDocument* pDocument,
03196 xercesc::DOMElement* pRootElement)
03197 {
03198 std::vector<xercesc::DOMElement*> p_elt_list = XmlTools::FindElements(
03199 pRootElement,
03200 "Numerical/KSPPreconditioner");
03201 if (p_elt_list.size() > 0)
03202 {
03203 assert(p_elt_list.size() == 1);
03204 std::string text_value = xsd::cxx::xml::transcode<char>(p_elt_list[0]->getTextContent());
03205 if (text_value == "ilu")
03206 {
03207 EXCEPTION("PETSc does not have a parallel implementation of ilu, so we no longer allow it as an option. Use bjacobi instead.");
03208 }
03209 }
03210 }
03211
03213
03215 #define COVERAGE_IGNORE //These methods are covered above with DIM=1,2,3 but the instantiations may fail spuriously
03216
03220 template void HeartConfig::GetIonicModelRegions<3u>(std::vector<ChasteCuboid<3u> >& , std::vector<cp::ionic_model_selection_type>&) const;
03221 template void HeartConfig::GetStimuli<3u>(std::vector<boost::shared_ptr<AbstractStimulusFunction> >& , std::vector<ChasteCuboid<3u> >& ) const;
03222 template void HeartConfig::GetCellHeterogeneities<3u>(std::vector<AbstractChasteRegion<3u>* >& ,std::vector<double>& ,std::vector<double>& ,std::vector<double>& ,std::vector<std::map<std::string, double> >*) ;
03223 template void HeartConfig::GetConductivityHeterogeneities<3u>(std::vector<AbstractChasteRegion<3u>* >& ,std::vector< c_vector<double,3> >& ,std::vector< c_vector<double,3> >& ) const;
03224
03225 template void HeartConfig::GetIonicModelRegions<2u>(std::vector<ChasteCuboid<2u> >& , std::vector<cp::ionic_model_selection_type>&) const;
03226 template void HeartConfig::GetStimuli<2u>(std::vector<boost::shared_ptr<AbstractStimulusFunction> >& , std::vector<ChasteCuboid<2u> >& ) const;
03227 template void HeartConfig::GetCellHeterogeneities<2u>(std::vector<AbstractChasteRegion<2u>* >& ,std::vector<double>& ,std::vector<double>& ,std::vector<double>& ,std::vector<std::map<std::string, double> >*) ;
03228 template void HeartConfig::GetConductivityHeterogeneities<2u>(std::vector<AbstractChasteRegion<2u>* >& ,std::vector< c_vector<double,3> >& ,std::vector< c_vector<double,3> >& ) const;
03229
03230 template void HeartConfig::GetIonicModelRegions<1u>(std::vector<ChasteCuboid<1u> >& , std::vector<cp::ionic_model_selection_type>&) const;
03231 template void HeartConfig::GetStimuli<1u>(std::vector<boost::shared_ptr<AbstractStimulusFunction> >& , std::vector<ChasteCuboid<1u> >& ) const;
03232 template void HeartConfig::GetCellHeterogeneities<1u>(std::vector<AbstractChasteRegion<1u>* >& ,std::vector<double>& ,std::vector<double>& ,std::vector<double>& ,std::vector<std::map<std::string, double> >*);
03233 template void HeartConfig::GetConductivityHeterogeneities<1u>(std::vector<AbstractChasteRegion<1u>* >& ,std::vector< c_vector<double,3> >& ,std::vector< c_vector<double,3> >& ) const;
03238 #undef COVERAGE_IGNORE //These methods are covered above with DIM=1,2,3 but the instantiations may fail spuriously
03239
03240
03241
03242 #include "SerializationExportWrapperForCpp.hpp"
03243 CHASTE_CLASS_EXPORT(HeartConfig)