246 const std::string mesh_dir =
"ConvergenceMesh";
254 out_stream p_conv_info_file;
257 std::cout <<
"=========================== Beginning Test...==================================\n";
258 p_conv_info_file = conv_info_handler.
OpenOutputFile(nameOfTest+
"_info.csv");
259 (*p_conv_info_file) <<
"#Abcisa\t"
262 <<
"Max absolute err\t"
263 <<
"APD90_1st_quad\t"
264 <<
"APD90_3rd_quad\t"
265 <<
"Conduction velocity (relative diffs)" << std::endl;
269 double prev_apd90_first_qn=0.0;
270 double prev_apd90_third_qn=0.0;
271 double prev_cond_velocity=0.0;
272 std::vector<double> prev_voltage;
273 std::vector<double> prev_times;
283 while (printing_step < 1.0e-4)
285 printing_step *= 2.0;
286 std::cout<<
"Warning: PrintingTimeStep increased\n";
306 unsigned num_ele_across = SmallPow(2u, this->
MeshNum+2);
333 CARDIAC_PROBLEM cardiac_problem(p_cell_factory);
334 cardiac_problem.SetMesh(&
mesh);
337 unsigned third_quadrant_node;
338 unsigned first_quadrant_node;
349 unsigned n= SmallPow (2u, this->
MeshNum+2);
350 first_quadrant_node = (n+1)*(n/2)+ n/4 ;
351 third_quadrant_node = (n+1)*(n/2)+3*n/4 ;
356 const unsigned first_quadrant_nodes_3d[5]={61, 362, 2452, 17960, 137296};
357 const unsigned third_quadrant_nodes_3d[5]={63, 366, 2460, 17976, 137328};
359 first_quadrant_node = first_quadrant_nodes_3d[this->
MeshNum];
360 third_quadrant_node = third_quadrant_nodes_3d[this->
MeshNum];
368 double mesh_width=constructor.
GetWidth();
371 std::vector<unsigned> nodes_to_be_output;
372 nodes_to_be_output.push_back(first_quadrant_node);
373 nodes_to_be_output.push_back(third_quadrant_node);
374 cardiac_problem.SetOutputNodes(nodes_to_be_output);
379 SetConductivities(cardiac_problem);
381 cardiac_problem.Initialise();
397 double x = ((*iter)->CalculateCentroid())[0];
401 p_bcc->AddNeumannBoundaryCondition(*iter, p_bc_stim);
406 cardiac_problem.SetBoundaryConditionsContainer(p_bcc);
416 cardiac_problem.Solve();
420 WARNING(
"This run threw an exception. Check convergence results\n");
421 std::cout << e.GetMessage() << std::endl;
433 std::vector<double> transmembrane_potential = results_reader.
GetVariableOverTime(
"V", third_quadrant_node);
441 std::stringstream plot_file_name_stream;
442 plot_file_name_stream<< nameOfTest <<
"_Third_quadrant_node_run_"<< file_num <<
".csv";
443 out_stream p_plot_file = plot_file_handler.
OpenOutputFile(plot_file_name_stream.str());
444 for (
unsigned data_point = 0; data_point<time_series.size(); data_point++)
446 (*p_plot_file) << time_series[data_point] <<
"\t" << transmembrane_potential[data_point] <<
"\n";
448 p_plot_file->close();
452 std::vector<double> transmembrane_potential_1qd=results_reader.
GetVariableOverTime(
"V", first_quadrant_node);
454 std::stringstream plot_file_name_stream;
455 plot_file_name_stream<< nameOfTest <<
"_First_quadrant_node_run_"<< file_num <<
".csv";
456 out_stream p_plot_file = plot_file_handler.
OpenOutputFile(plot_file_name_stream.str());
457 for (
unsigned data_point = 0; data_point<time_series.size(); data_point++)
459 (*p_plot_file) << time_series_1qd[data_point] <<
"\t" << transmembrane_potential_1qd[data_point] <<
"\n";
461 p_plot_file->close();
481 std::cout <<
"Warning - this run threw an exception in calculating propagation. Check convergence results\n";
482 std::cout << e.GetMessage() << std::endl;
485 double cond_velocity_error = 1e10;
486 double apd90_first_qn_error = 1e10;
487 double apd90_third_qn_error = 1e10;
491 if (prev_cond_velocity != 0.0)
493 cond_velocity_error = fabs(
ConductionVelocity - prev_cond_velocity) / prev_cond_velocity;
496 if (prev_apd90_first_qn != 0.0)
498 apd90_first_qn_error = fabs(
Apd90FirstQn - prev_apd90_first_qn) / prev_apd90_first_qn;
500 if (prev_apd90_third_qn != 0.0)
502 apd90_third_qn_error = fabs(
Apd90ThirdQn - prev_apd90_third_qn) / prev_apd90_third_qn;
504 if (apd90_first_qn_error == 0.0)
506 apd90_first_qn_error = DBL_EPSILON;
508 if (apd90_third_qn_error == 0.0)
510 apd90_third_qn_error = DBL_EPSILON;
513 if (cond_velocity_error == 0.0)
515 cond_velocity_error = DBL_EPSILON;
524 double max_abs_error = 0;
525 double sum_sq_abs_error =0;
526 double sum_sq_prev_voltage = 0;
527 double sum_sq_abs_error_full =0;
528 double sum_sq_prev_voltage_full = 0;
533 unsigned time_factor=(time_series.size()-1) / (prev_times.size()-1);
534 assert (time_factor == 1 || time_factor == 2 || time_factor == 8);
536 for (
unsigned data_point = 0; data_point<prev_times.size(); data_point++)
538 unsigned this_data_point=time_factor*data_point;
540 assert(time_series[this_data_point] == prev_times[data_point]);
541 double abs_error = fabs(transmembrane_potential[this_data_point]-prev_voltage[data_point]);
542 max_abs_error = (abs_error > max_abs_error) ? abs_error : max_abs_error;
544 sum_sq_abs_error_full += abs_error*abs_error;
545 sum_sq_prev_voltage_full += prev_voltage[data_point] * prev_voltage[data_point];
546 if (time_series[this_data_point] <= 8.0)
549 sum_sq_abs_error += abs_error*abs_error;
550 sum_sq_prev_voltage += prev_voltage[data_point] * prev_voltage[data_point];
557 prev_voltage = transmembrane_potential;
558 prev_times = time_series;
563 double l2_norm_upstroke = sqrt(sum_sq_abs_error/sum_sq_prev_voltage);
564 double l2_norm_full = sqrt(sum_sq_abs_error_full/sum_sq_prev_voltage_full);
568 (*p_conv_info_file) << std::setprecision(8)
570 << l2_norm_full <<
"\t"
571 << l2_norm_upstroke <<
"\t"
572 << max_abs_error <<
"\t"
573 <<
Apd90FirstQn <<
" "<< apd90_first_qn_error <<
""<<
"\t"
574 <<
Apd90ThirdQn <<
" "<< apd90_third_qn_error <<
""<<
"\t"
581 assert (time_series.size() != 1u);
582 if (time_series.back() == 0.0)
584 std::cout <<
"Failed after successful convergence - give up this convergence test\n";
591 if (time_series.back() != 0.0)
605 delete p_cell_factory;
612 p_conv_info_file->close();
614 std::cout <<
"Results: " << std::endl;
619 std::cout << info_file.rdbuf();