HeartConfig.cpp

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

Generated on Tue Aug 4 16:10:22 2009 for Chaste by  doxygen 1.5.5