void TestConductionVelocityConvergesFasterWithSvi1d() { double h[3] = {0.001,0.01,0.02}; unsigned probe_node_index[3] = {300, 30, 15}; unsigned number_of_nodes[3] = {1001, 101, 51}; std::vector<double> conduction_vel_ici(3); std::vector<double> conduction_vel_svi(3); ReplicatableVector final_voltage_ici; ReplicatableVector final_voltage_svi; //HeartConfig::Instance()->SetUseRelativeTolerance(1e-8); HeartConfig::Instance()->SetSimulationDuration(4.0); //ms HeartConfig::Instance()->SetOdePdeAndPrintingTimeSteps(0.01, 0.01, 0.01); for (unsigned i=0; i<3; i++) { // ICI - ionic current interpolation - the default { DistributedTetrahedralMesh<1,1> mesh; mesh.ConstructRegularSlabMesh(h[i], 1.0); TS_ASSERT_EQUALS(mesh.GetNumNodes(), number_of_nodes[i]); //Double check (for later) that the indexing is as expected if (mesh.GetDistributedVectorFactory()->IsGlobalIndexLocal( probe_node_index[i] )) { TS_ASSERT_DELTA(mesh.GetNode( probe_node_index[i] )->rGetLocation()[0], 0.3, 1e-8); } std::stringstream output_dir; output_dir << "MonodomainIci_" << h[i]; HeartConfig::Instance()->SetOutputDirectory(output_dir.str()); HeartConfig::Instance()->SetOutputFilenamePrefix("results"); // need to have this for i=1,2 cases!! HeartConfig::Instance()->SetUseStateVariableInterpolation(false); BlockCellFactory<1> cell_factory; MonodomainProblem<1> monodomain_problem( &cell_factory ); monodomain_problem.SetMesh(&mesh); monodomain_problem.Initialise(); monodomain_problem.Solve(); final_voltage_ici.ReplicatePetscVector(monodomain_problem.GetSolution()); //// see #1633 //// end time needs to be increased for these (say, to 7ms) // Hdf5DataReader simulation_data(OutputFileHandler::GetChasteTestOutputDirectory() + output_dir.str(), // "results", false); // PropagationPropertiesCalculator ppc(&simulation_data); // unsigned node_at_0_04 = (unsigned)round(0.04/h[i]); // unsigned node_at_0_40 = (unsigned)round(0.40/h[i]); // assert(fabs(mesh.GetNode(node_at_0_04)->rGetLocation()[0]-0.04)<1e-6); // assert(fabs(mesh.GetNode(node_at_0_40)->rGetLocation()[0]-0.40)<1e-6); // conduction_vel_ici[i] = ppc.CalculateConductionVelocity(node_at_0_04,node_at_0_40,0.36); // std::cout << "conduction_vel_ici = " << conduction_vel_ici[i] << "\n"; } // SVI - state variable interpolation { DistributedTetrahedralMesh<1,1> mesh; mesh.ConstructRegularSlabMesh(h[i], 1.0); //Double check (for later) that the indexing is as expected if (mesh.GetDistributedVectorFactory()->IsGlobalIndexLocal( probe_node_index[i] )) { TS_ASSERT_DELTA(mesh.GetNode( probe_node_index[i] )->rGetLocation()[0], 0.3, 1e-8); } std::stringstream output_dir; output_dir << "MonodomainSvi_" << h[i]; HeartConfig::Instance()->SetOutputDirectory(output_dir.str()); HeartConfig::Instance()->SetOutputFilenamePrefix("results"); HeartConfig::Instance()->SetUseStateVariableInterpolation(); BlockCellFactory<1> cell_factory; MonodomainProblem<1> monodomain_problem( &cell_factory ); monodomain_problem.SetMesh(&mesh); monodomain_problem.Initialise(); monodomain_problem.Solve(); final_voltage_svi.ReplicatePetscVector(monodomain_problem.GetSolution()); // Hdf5DataReader simulation_data(OutputFileHandler::GetChasteTestOutputDirectory() + output_dir.str(), // "results", false); // PropagationPropertiesCalculator ppc(&simulation_data); // unsigned node_at_0_04 = (unsigned)round(0.04/h[i]); // unsigned node_at_0_40 = (unsigned)round(0.40/h[i]); // assert(fabs(mesh.GetNode(node_at_0_04)->rGetLocation()[0]-0.04)<1e-6); // assert(fabs(mesh.GetNode(node_at_0_40)->rGetLocation()[0]-0.40)<1e-6); // conduction_vel_svi[i] = ppc.CalculateConductionVelocity(node_at_0_04,node_at_0_40,0.36); // std::cout << "conduction_vel_svi = " << conduction_vel_svi[i] << "\n"; } if (i==0) // finest mesh { for (unsigned j=0; j<final_voltage_ici.GetSize(); j++) { // visually checked they agree at this mesh resolution, and chosen tolerance from results TS_ASSERT_DELTA(final_voltage_ici[j], final_voltage_svi[j], 0.3); if (final_voltage_ici[j]>-80) { // shouldn't be exactly equal, as long as away from resting potential TS_ASSERT_DIFFERS(final_voltage_ici[j], final_voltage_svi[j]); } } double ici_voltage_at_0_03_finest_mesh = final_voltage_ici[ probe_node_index[i] ]; double svi_voltage_at_0_03_finest_mesh = final_voltage_svi[ probe_node_index[i] ]; TS_ASSERT_DELTA(svi_voltage_at_0_03_finest_mesh, 11.0067, 2e-4); //hardcoded value from fine svi TS_ASSERT_DELTA(ici_voltage_at_0_03_finest_mesh, 11.0067, 1.2e-1); //hardcoded value from fine svi } else if (i==1) { double ici_voltage_at_0_03_middle_mesh = final_voltage_ici[ probe_node_index[i] ]; double svi_voltage_at_0_03_middle_mesh = final_voltage_svi[ probe_node_index[i] ]; // ICI conduction velocity > SVI conduction velocity // and both should be greater than CV on finesh mesh TS_ASSERT_DELTA(ici_voltage_at_0_03_middle_mesh, 19.8924, 1e-3); TS_ASSERT_DELTA(svi_voltage_at_0_03_middle_mesh, 14.9579, 1e-3); } else { double ici_voltage_at_0_03_coarse_mesh = final_voltage_ici[ probe_node_index[i] ]; double svi_voltage_at_0_03_coarse_mesh = final_voltage_svi[ probe_node_index[i] ]; // ICI conduction velocity even greater than SVI conduction // velocity TS_ASSERT_DELTA(ici_voltage_at_0_03_coarse_mesh, 24.4938, 1e-3); TS_ASSERT_DELTA(svi_voltage_at_0_03_coarse_mesh, 17.3131, 1e-3); } } }
void TestConductionVelocityConvergesFasterWithSvi1d() throw(Exception) { double h[3] = {0.001,0.01,0.02}; std::vector<double> conduction_vel_nci(3); std::vector<double> conduction_vel_svi(3); ReplicatableVector final_solution_ici; ReplicatableVector final_solution_svi; ReplicatableVector final_solution_svit; HeartConfig::Instance()->SetSimulationDuration(4.0); //ms HeartConfig::Instance()->SetOdePdeAndPrintingTimeSteps(0.01, 0.01, 0.01); for(unsigned i=0; i<3; i++) { // ICI - ionic current interpolation - the default { TetrahedralMesh<1,1> mesh; mesh.ConstructRegularSlabMesh(h[i], 1.0); std::stringstream output_dir; output_dir << "BidomainIci_" << h[i]; HeartConfig::Instance()->SetOutputDirectory(output_dir.str()); HeartConfig::Instance()->SetOutputFilenamePrefix("results"); // need to have this for i=1,2 cases!! HeartConfig::Instance()->SetUseStateVariableInterpolation(false); BlockCellFactory<1> cell_factory; BidomainProblem<1> bidomain_problem( &cell_factory ); bidomain_problem.SetMesh(&mesh); bidomain_problem.Initialise(); bidomain_problem.Solve(); final_solution_ici.ReplicatePetscVector(bidomain_problem.GetSolution()); } // SVI - state variable interpolation { DistributedTetrahedralMesh<1,1> mesh; mesh.ConstructRegularSlabMesh(h[i], 1.0); std::stringstream output_dir; output_dir << "BidomainSvi_" << h[i]; HeartConfig::Instance()->SetOutputDirectory(output_dir.str()); HeartConfig::Instance()->SetOutputFilenamePrefix("results"); HeartConfig::Instance()->SetUseStateVariableInterpolation(); BlockCellFactory<1> cell_factory; BidomainProblem<1> bidomain_problem( &cell_factory ); bidomain_problem.SetMesh(&mesh); bidomain_problem.Initialise(); bidomain_problem.Solve(); final_solution_svi.ReplicatePetscVector(bidomain_problem.GetSolution()); } // SVIT - state variable interpolation on straight (not distributed) tetrahedral mesh { TetrahedralMesh<1,1> mesh; mesh.ConstructRegularSlabMesh(h[i], 1.0); std::stringstream output_dir; output_dir << "BidomainSviTet_" << h[i]; HeartConfig::Instance()->SetOutputDirectory(output_dir.str()); HeartConfig::Instance()->SetOutputFilenamePrefix("results"); HeartConfig::Instance()->SetUseStateVariableInterpolation(); BlockCellFactory<1> cell_factory; BidomainProblem<1> bidomain_problem( &cell_factory ); bidomain_problem.SetMesh(&mesh); bidomain_problem.Initialise(); bidomain_problem.Solve(); final_solution_svit.ReplicatePetscVector(bidomain_problem.GetSolution()); } double voltage_at_0_03_finest_mesh; if(i==0) // finest mesh { for(unsigned j=0; j<final_solution_ici.GetSize(); j++) { // visually checked they agree at this mesh resolution, and chosen tolerance from results TS_ASSERT_DELTA(final_solution_ici[j], final_solution_svi[j], 0.35); TS_ASSERT_DELTA(final_solution_svit[j], final_solution_svi[j], 1e-8); if(j%2==0 /* just look at voltage */ && final_solution_ici[j]>-80) { // shouldn't be exactly equal, as long as away from resting potential TS_ASSERT_DIFFERS(final_solution_ici[j], final_solution_svi[j]); } } voltage_at_0_03_finest_mesh = final_solution_ici[600]; TS_ASSERT_DELTA(voltage_at_0_03_finest_mesh, -65.2218, 1e-2); //hardcoded value } else if(i==1) { double nci_voltage_at_0_03_middle_mesh = final_solution_ici[60]; double svi_voltage_at_0_03_middle_mesh = final_solution_svi[60]; double svit_voltage_at_0_03_middle_mesh = final_solution_svit[60]; // ICI conduction velocity > SVI conduction velocity // and both should be greater than CV on finesh mesh TS_ASSERT_DELTA(nci_voltage_at_0_03_middle_mesh, -44.3111, 1e-3); TS_ASSERT_DELTA(svi_voltage_at_0_03_middle_mesh, -60.7765, 1e-3); TS_ASSERT_DELTA(svit_voltage_at_0_03_middle_mesh, -60.7765, 1e-3); } else { double nci_voltage_at_0_03_coarse_mesh = final_solution_ici[30]; double svi_voltage_at_0_03_coarse_mesh = final_solution_svi[30]; double svit_voltage_at_0_03_coarse_mesh = final_solution_svit[30]; // ICI conduction velocity even greater than SVI conduction // velocity TS_ASSERT_DELTA(nci_voltage_at_0_03_coarse_mesh, -6.5622, 1e-3); TS_ASSERT_DELTA(svi_voltage_at_0_03_coarse_mesh, -51.8848, 1e-3); TS_ASSERT_DELTA(svit_voltage_at_0_03_coarse_mesh, -51.8848, 1e-3); } } }