MoCSI API Reference
Loading...
Searching...
No Matches
OutputCsvTool.h
Go to the documentation of this file.
1#ifndef OUTPUT_CSV_TOOL_H
2#define OUTPUT_CSV_TOOL_H
3
4#define OUTPUT_CSV_TOOL_VERSION "13"
5
6#include <algorithm>
7#include <cstdint>
8#include <ctime>
9#include <exception>
10#include <fstream>
11#include <iomanip>
12#include <iostream>
13#include <memory>
14#include <ostream>
15#include <sstream>
16#include <string>
17#include <valarray>
18#include <vector>
19
20#include "../../src/GenericManagingModule.h"
21#include "../../src/ModuleFactory.h"
22
23#ifdef MPI_PRESENT
24#include <mpi.h>
25
26#endif
27
50template <typename T>
52{
53 private:
54 static bool m_registered;
55 std::string m_ini_filepath{"tools/OutputCsvTool.ini"};
56 std::string m_output_filepath{};
57 std::string m_save_mode{};
58 std::vector<std::string>
59 m_save_fields; // Right now this lives only in the local ini, but we make it live in
60 // the sim class, so that the other modules can write their save request
61 // to it.
62 std::string m_start_time_utc{};
63 int64_t m_start_time_seconds{};
64 std::vector<int64_t> m_interval_start_times_seconds{};
65 std::vector<int64_t> m_interval_end_times_seconds{};
66 std::vector<int> m_save_steps{};
67 int m_currentIndex{0};
68 double m_time_delta;
69 double m_time_max;
70 std::ofstream output_file;
71
72 void _writeData();
73 void _writeDataSurface(int period);
74 void _utcIntervalToSeconds();
75 void _verifyIntervalIntegrity();
76 bool _checkInterval();
77
78#ifdef MPI_PRESENT
83 int count{0};
87 std::string footer{};
88 void _writeDataMpi();
90 MPI_Offset _calcDisplacement(const std::valarray<T>& field);
91 void _writeFooter();
92#endif
93
94 public:
96 bool setup(std::vector<std::shared_ptr<GenericSubmodule<T>>> all_submodules) override;
97 bool exec(std::string_view param) override; // main functionality of the module
98
99 bool init() override;
100 bool preTimeStep() override { return true; };
101 bool postNonLinIter() override { return true; };
102 bool postTimeStep() override;
103 bool output() override;
104 std::vector<std::string> getChainInsertion() const override
105 {
106 return this->ini_file_data.getStringVectorParameters("chain_insertion");
107 };
108
109 static std::shared_ptr<GenericManagingModule<T>> createMethode(SimulationClassBase<T>* sim)
110 {
111 return std::make_shared<OutputCsvTool<T>>(sim);
112 };
113 static std::string getName() { return "OutputCsvTool"; };
114 std::string_view getNameLocal() const override { return "OutputCsvTool"; };
115};
116
117// ================= Implementation =================
118
119template <typename T>
121{
122 try
123 {
124 std::string ini_folder_path{
125 this->sim->m_simulation_config.getStringParameters("ini_folder_path")};
126 this->ini_file_data.loadUserInput(ini_folder_path + m_ini_filepath);
127 m_output_filepath = this->ini_file_data.getStringParameters("file_path");
128 m_save_mode = this->ini_file_data.getStringParameters("save_mode");
129 m_save_fields = this->ini_file_data.getStringVectorParameters("save_fields");
131 }
132 catch (const BadInput& e)
133 {
134 std::cerr << "[OutputCsvTool]: " << e.what() << '\n';
135 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ")
136 + static_cast<std::string>(e.what()));
137 }
138}
139
140template <typename T>
142{
143#ifdef MPI_PRESENT
144 // Get information necessary to calculate byte sizes of output
145 numerical_layers = this->sim->m_simulation_config.getIntParameters("numerical_layers");
146 local_number_of_facets = this->sim->m_simulation_config.getIntParameters("number_of_facets");
148 this->sim->m_simulation_config.getIntParameters("global_number_of_facets");
149 // Set datatype of field to the one used across this simulation
153 if (this->sim->my_rank == 0)
154 {
155 // Flush the file
156 std::ofstream file(m_output_filepath);
157 }
158#else
159 // Flush the file
160 std::ofstream file(m_output_filepath);
161#endif
162 if (m_save_mode == "specific_time_steps" || m_save_mode == "specific_time_steps_surface")
163 {
164 try
165 {
166 std::vector<double> save_steps{
167 this->ini_file_data.getDoubleVectorParameters("save_time_steps")};
168 for (int i{0}; i < save_steps.size(); i++)
169 {
170 m_save_steps.push_back(static_cast<int>(save_steps[i]));
171 }
172 }
173 catch (const BadInput& e)
174 {
175 std::cerr << "[OutputCsvTool]: " << e.what() << '\n';
176 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ")
177 + static_cast<std::string>(e.what()));
178 }
179 }
180 if (m_save_mode == "time_interval" || m_save_mode == "time_interval_surface")
181 {
182 try
183 {
184 m_time_delta = this->sim->m_simulation_config.getDoubleParameters("time_delta");
185 m_time_max = this->sim->m_simulation_config.getDoubleParameters("time_max");
186 m_start_time_utc = this->ini_file_data.getStringParameters("start_time_utc");
187 _utcIntervalToSeconds();
188 }
189 catch (const BadInput& e)
190 {
191 std::cerr << e.what() << '\n';
192 }
193 }
194 return true;
195}
196
197template <typename T>
198bool OutputCsvTool<T>::exec(std::string_view param)
199{
200 if (param == "InitChain")
201 {
202 return init();
203 }
204 if (param == "PreTimeStepChain")
205 {
206 return preTimeStep();
207 }
208 if (param == "PostNonLinIterChain")
209 {
210 return postNonLinIter();
211 }
212 if (param == "PostTimeStepChain")
213 {
214 return postTimeStep();
215 }
216 if (param == "OutputChain")
217 {
218 return output();
219 }
220 return false;
221}
222
223template <typename T>
225{
226#ifdef MPI_PRESENT
227 MPI_File_open(MPI_COMM_WORLD, m_output_filepath.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE,
229#endif
230 return true;
231}
232
233template <typename T>
235{
236 try
237 {
238 if ((m_save_mode == "specific_time_steps") && (m_currentIndex < m_save_steps.size())
239 && (m_save_steps[m_currentIndex] == this->sim->time_step))
240 {
241#ifdef MPI_PRESENT
243#else
244 _writeData();
245#endif
246 m_currentIndex++;
247 }
248 else if ((m_save_mode == "specific_time_steps_surface")
249 && (m_currentIndex < m_save_steps.size())
250 && (m_save_steps[m_currentIndex] == this->sim->time_step))
251 {
252#ifdef MPI_PRESENT
254 this->sim->m_simulation_config.getIntParameters("numerical_layers"));
255#else
256 _writeDataSurface(this->sim->m_simulation_config.getIntParameters("numerical_layers"));
257#endif
258 m_currentIndex++;
259 }
260 else if ((m_save_mode == "interval")
261 && (this->sim->time_step % this->ini_file_data.getIntParameters("interval") == 0))
262 {
263#ifdef MPI_PRESENT
265#else
266 _writeData();
267#endif
268 }
269 else if ((m_save_mode == "interval_surface")
270 && (this->sim->time_step % this->ini_file_data.getIntParameters("interval") == 0))
271 {
272#ifdef MPI_PRESENT
274 this->sim->m_simulation_config.getIntParameters("numerical_layers"));
275#else
276 _writeDataSurface(this->sim->m_simulation_config.getIntParameters("numerical_layers"));
277#endif
278 }
279 else if ((m_save_mode == "time_interval") && _checkInterval())
280 {
281#ifdef MPI_PRESENT
283#else
284 _writeData();
285#endif
286 }
287 else if ((m_save_mode == "time_interval_surface") && _checkInterval())
288 {
289#ifdef MPI_PRESENT
291 this->sim->m_simulation_config.getIntParameters("numerical_layers"));
292#else
293 _writeDataSurface(this->sim->m_simulation_config.getIntParameters("numerical_layers"));
294#endif
295 }
296 }
297 catch (const BadInput& e)
298 {
299 std::cerr << "[OutputCsvTool]: " << e.what() << '\n';
300 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ")
301 + static_cast<std::string>(e.what()));
302 }
303 return true;
304}
305
306template <typename T>
308{
309#ifdef MPI_PRESENT
310 // Check to only write footer, if it hasn't already been written (in preTimeStep)
311 if (!(footer.empty()))
312 {
313 _writeFooter();
314 }
316#else
317 if (m_save_mode == "surface")
318 {
319 try
320 {
321 _writeDataSurface(this->sim->m_simulation_config.getIntParameters("numerical_layers"));
322 }
323 catch (const BadInput& e)
324 {
325 std::cerr << "[OutputCsvTool]: " << e.what() << '\n';
326 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ")
327 + static_cast<std::string>(e.what()));
328 }
329 }
330 else
331 {
332 _writeData();
333 }
334#endif
335 return true;
336}
337
344template <typename T>
346{
347 output_file.open(m_output_filepath, std::ios::app);
348
349 for (const auto& field_name : m_save_fields)
350 {
351 output_file << field_name << "," << this->sim->elapsed_time << ",";
352 try
353 {
354 const std::valarray<T>& field{this->sim->getField(field_name)};
355 for (int i{0}; i < field.size() - 1; i++)
356 {
357 output_file << field[i] << std::setprecision(15) << ",";
358 }
359 output_file << field[field.size() - 1] << std::setprecision(15) << "\n";
360 }
361 catch (const BadInput& e)
362 {
363 std::cerr << "[OutputCsvTool]: " << field_name
364 << " module not "
365 "loaded or accessable!\n "
366 "[OutputCsvTool]:"
367 << e.what() << '\n';
368 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ") + field_name
369 + static_cast<std::string>(" module "
370 "not loaded or "
371 "accessable!\n [OutputCsvTool]: ")
372 + static_cast<std::string>(e.what()));
373 }
374 }
375
376 output_file.close();
377}
378
379#ifdef MPI_PRESENT
388template <typename T>
390{
392 {
393 std::cerr << "[OutputCsvTool]: Trying to access an unopened file. Please also use init and "
394 "output chains "
395 "when using MPI I/O.\n";
396 throw std::runtime_error(
397 "[OutputCsvTool]: Trying to access an unopened file. Please also use init and output "
398 "chains when using "
399 "MPI I/O.");
400 }
401 for (const auto& field_name : m_save_fields)
402 {
403 try
404 {
405 const std::valarray<T>& field{this->sim->getField(field_name)};
408 static_cast<int>(field.size()), m_dtype, MPI_STATUS_IGNORE);
409 // Update the starting position (in bytes) for the next write
410 // Each process from the first k can write at position rank * size of its array.
411 // Each process > k needs to account for the larger k processes to determine its pointer
412 // start.
414 {
416 footer += field_name + "," + std::to_string(this->sim->elapsed_time) + ","
417 + std::to_string(numerical_layers * global_number_of_facets) + ",";
418 }
419 else if (field.size() == local_number_of_facets)
420 {
422 footer += field_name + "," + std::to_string(this->sim->elapsed_time) + ","
423 + std::to_string(global_number_of_facets) + ",";
424 }
425 else
426 {
427 start += type_size * static_cast<MPI_Offset>(field.size()) * this->sim->world_size;
428 footer += field_name + "," + std::to_string(this->sim->elapsed_time) + ","
429 + std::to_string(field.size() * this->sim->world_size) + ",";
430 }
431 }
432 catch (const BadInput& e)
433 {
434 std::cerr << "[OutputCsvTool]: " << field_name
435 << " module not "
436 "loaded or accessable!\n "
437 "[OutputCsvTool]:"
438 << e.what() << '\n';
439 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ") + field_name
440 + static_cast<std::string>(" module "
441 "not loaded or "
442 "accessable!\n [OutputCsvTool]: ")
443 + static_cast<std::string>(e.what()));
444 }
445 }
446}
447#endif
448
457template <typename T>
459{
460 output_file.open(m_output_filepath, std::ios::app);
461
462 for (const auto& field_name : m_save_fields)
463 {
464 output_file << field_name << "," << this->sim->elapsed_time << ",";
465 try
466 {
467 const std::valarray<T>& field{this->sim->getField(field_name)};
468 for (int i{0}; i < static_cast<int>(field.size() / period) - 1; i++)
469 {
470 output_file << field[i * period] << std::setprecision(15) << ",";
471 }
472 output_file << field[field.size() - period] << std::setprecision(15) << "\n";
473 }
474 catch (const BadInput& e)
475 {
476 std::cerr << "[OutputCsvTool]: " << field_name
477 << " module not "
478 "loaded or accessable!\n "
479 "[OutputCsvTool]:"
480 << e.what() << '\n';
481 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ") + field_name
482 + static_cast<std::string>(" module "
483 "not loaded or "
484 "accessable!\n [OutputCsvTool]:")
485 + static_cast<std::string>(e.what()));
486 }
487 }
488
489 output_file.close();
490}
491
492#ifdef MPI_PRESENT
502template <typename T>
504{
506 {
507 std::cerr << "[OutputCsvTool]: Trying to access an unopened file. Please also use init and "
508 "output chains "
509 "when using MPI I/O.\n";
510 throw std::runtime_error(
511 "[OutputCsvTool]: Trying to access an unopened file. Please also use init and output "
512 "chains when using "
513 "MPI I/O.");
514 }
515 for (const auto& field_name : m_save_fields)
516 {
517 // Get only the surface values of the field variable.
518 try
519 {
520 const std::valarray<T>& field{this->sim->getField(field_name)};
521 std::valarray<T> field_surface(field.size() / period);
522 for (int i{0}; i < field_surface.size(); i++)
523 {
525 }
526 // Update the starting position (in bytes) for the next write
527 // Each process from the first k can write at position rank * size of its array.
528 // Each process > k needs to account for the larger k processes to determine its pointer
529 // start.
532 static_cast<int>(field_surface.size()), m_dtype,
534 // Update the starting position (in bytes) for the next write
536 {
538 footer += field_name + "," + std::to_string(this->sim->elapsed_time) + ","
540 + ",";
541 }
542 }
543 catch (const BadInput& e)
544 {
545 std::cerr << "[OutputCsvTool]: " << field_name
546 << " module not "
547 "loaded or accessable!\n "
548 "[OutputCsvTool]:"
549 << e.what() << '\n';
550 throw BadInput(static_cast<std::string>("[OutputCsvTool]: ") + field_name
551 + static_cast<std::string>(" module "
552 "not loaded or "
553 "accessable!\n [OutputCsvTool]: ")
554 + static_cast<std::string>(e.what()));
555 }
556 }
557}
558
568template <typename T>
570{
573 {
574 // For the block of same size processes, displacement is rank * local_field_size *
575 // data_type_byte_size.
576 if (this->sim->my_rank < this->sim->number_of_larger_procs)
577 {
579 this->sim->my_rank * static_cast<MPI_Offset>(field.size()) * type_size;
580 }
581 // For the second block, add the first block displacement and count how many second block
582 // processes are between the targeted position and the first block.
583 // local_field_size_large_proc = local_field_size_small_proc + numerical_layers.
584 else
585 {
587 (this->sim->number_of_larger_procs * (field.size() + numerical_layers)
588 + (this->sim->my_rank - this->sim->number_of_larger_procs)
589 * static_cast<MPI_Offset>(field.size()))
590 * type_size;
591 }
592 }
593 else if (field.size() == local_number_of_facets)
594 {
595 // For the block of same size processes, displacement is rank * local_field_size *
596 // data_type_byte_size.
597 if (this->sim->my_rank < this->sim->number_of_larger_procs)
598 {
600 this->sim->my_rank * static_cast<MPI_Offset>(field.size()) * type_size;
601 }
602 // For the second block, add the first block displacement and count how many second block
603 // processes are between the targeted position and the first block.
604 // local_field_size_large_proc = local_field_size_small_proc + 1.
605 else
606 {
608 (this->sim->number_of_larger_procs * (field.size() + 1)
609 + (this->sim->my_rank - this->sim->number_of_larger_procs) * field.size())
610 * type_size;
611 }
612 }
613 else
614 {
615 proc_displacement = type_size * static_cast<MPI_Offset>(field.size());
616 }
617 return proc_displacement;
618}
619
627template <typename T>
629{
632 static_cast<MPI_Offset>(start + footer_type_size * footer.size())};
633 if (this->sim->my_rank == 0)
634 {
636 static_cast<int>(footer.size()), MPI_UNSIGNED_CHAR, MPI_STATUS_IGNORE);
638 data_sizes[1] = footer.size();
641 }
642}
643#endif
644
658template <typename T>
660{
661 std::vector<std::string> m_interval_start_times_utc{
662 this->ini_file_data.getStringVectorParameters("interval_start_times_utc")};
663 std::vector<std::string> m_interval_end_times_utc{
664 this->ini_file_data.getStringVectorParameters("interval_end_times_utc")};
665 const std::string format = "%Y-%m-%dT%H:%M:%S";
666 std::tm tm_struct{}; // Always zero-initialize this type.
667 tm_struct.tm_isdst = -1;
668 std::istringstream sstream{};
669 std::time_t time_point{};
670
671 sstream.str(m_start_time_utc);
672 sstream >> std::get_time(&tm_struct, format.c_str());
673 time_point = std::mktime(&tm_struct);
674 m_start_time_seconds = static_cast<int64_t>(time_point);
675 if (sstream.fail())
676 {
677 std::cerr << "[OutputCsvTool]: Could not parse the start time stamp: " << m_start_time_utc
678 << "!\nPlease use the format YYYY-MM-DDThh:mm:ss\n";
679 throw std::runtime_error("[OutputCsvTool]: Could not parse the start time stamp: "
680 + m_start_time_utc
681 + "!\nPlease use the format YYYY-MM-DDThh:mm:ss\n");
682 }
683 sstream.clear();
684
685 for (int i{0}; i < m_interval_start_times_utc.size(); i++)
686 {
688 sstream >> std::get_time(&tm_struct, format.c_str());
689 time_point = std::mktime(&tm_struct);
690 m_interval_start_times_seconds.push_back(static_cast<int64_t>(time_point));
691 if (sstream.fail())
692 {
693 std::cerr << "[OutputCsvTool]: Could not parse the starting interval time stamp: "
695 << "!\nPlease use the format YYYY-MM-DDThh:mm:ss\n";
696 throw std::runtime_error(
697 "[OutputCsvTool]: Could not parse the starting interval time stamp: "
698 + m_interval_start_times_utc[i] + "!\nPlease use the format YYYY-MM-DDThh:mm:ss\n");
699 }
700 sstream.clear();
701 }
702
703 for (int i{0}; i < m_interval_end_times_utc.size(); i++)
704 {
706 sstream >> std::get_time(&tm_struct, format.c_str());
707 time_point = std::mktime(&tm_struct);
708 m_interval_end_times_seconds.push_back(static_cast<int64_t>(time_point));
709 if (sstream.fail())
710 {
711 std::cerr << "[OutputCsvTool]: Could not parse the starting interval time stamp: "
713 << "!\nPlease use the format YYYY-MM-DDThh:mm:ss\n";
714 throw std::runtime_error(
715 "[OutputCsvTool]: Could not parse the starting interval time stamp: "
716 + m_interval_end_times_utc[i] + "!\nPlease use the format YYYY-MM-DDThh:mm:ss\n");
717 }
718 sstream.clear();
719 }
720
721 // I do this test here and not in checkIntervalIntegrity to not have them sorted yet so I can
722 // give the utc time stamps back to the user.
723 for (int i{0}; i < m_interval_end_times_utc.size(); i++)
724 {
725 if (m_interval_start_times_seconds[i] > m_interval_end_times_seconds[i])
726 {
727 std::cerr << "[OutputCsvTool]: Starting time of interval "
728 << m_interval_start_times_utc[i] << " is after the end time of the interval "
730 << "! Please ensure that interval start time < interval end time.\n";
731 throw std::runtime_error(
732 "[OutputCsvTool]: Starting time of interval " + m_interval_start_times_utc[i]
733 + " is after the end time of the interval " + m_interval_end_times_utc[i]
734 + "! Please ensure that interval start time < interval end time.\n");
735 }
736
737 // I sort here, because I expect the user to give disjoint intervals. If I didn't and the
738 // user did not sort the intervals in ascending order themself, the code would lock up and
739 // might skip intervals, so sorting here should do what the user wants more often than not
740 // sorting.
741 std::sort(m_interval_start_times_seconds.begin(), m_interval_start_times_seconds.end());
742 std::sort(m_interval_end_times_seconds.begin(), m_interval_end_times_seconds.end());
743
744 _verifyIntervalIntegrity();
745 }
746}
747
759template <typename T>
761{
762 if (m_interval_start_times_seconds.size() != m_interval_end_times_seconds.size())
763 {
764 std::cerr << "[OutputCsvTool]: Start and end intervalls have different amount of time "
765 "stamps!\n";
766 throw std::runtime_error(
767 "[OutputCsvTool]: Start and end intervalls have different amount of time "
768 "stamps!\n");
769 }
770
772 double sim_end_time{m_start_time_seconds + m_time_max};
773 for (int i{0}; i < m_interval_start_times_seconds.size(); i++)
774 {
775 if (m_interval_start_times_seconds[i] > sim_end_time
776 || m_interval_end_times_seconds[i] < m_start_time_seconds)
777 {
779 }
780 }
781 if (intervals_out_of_range == m_interval_start_times_seconds.size())
782 {
783 std::cerr << "[OutputCsvTool]: None of the given intervals are within the simulation "
784 "time span! Please provide at least one valid interval.\n";
785 throw std::runtime_error(
786 "[OutputCsvTool]: None of the given intervals are within the simulation time span! "
787 "Please provide at least one valid interval.\n");
788 }
789 else if (intervals_out_of_range > 0)
790 {
791 std::cerr << "[OutputCsvTool]: " << intervals_out_of_range << " out of "
792 << m_interval_start_times_seconds.size()
793 << " intervals are outside of the simulation time span and will be ignored\n";
794 }
795}
796
804template <typename T>
806{
807 while (m_currentIndex < m_interval_start_times_seconds.size())
808 {
809 // If we are within an time interval, check if we are also within a time step interval and
810 // return true or false.
811 if (m_interval_start_times_seconds[m_currentIndex]
812 <= m_start_time_seconds + this->sim->time_step * m_time_delta
813 && m_interval_end_times_seconds[m_currentIndex]
814 >= m_start_time_seconds + this->sim->time_step * m_time_delta)
815 {
816 if (this->sim->time_step % this->ini_file_data.getIntParameters("interval") == 0)
817 {
818 return true;
819 }
820 else
821 {
822 return false;
823 }
824 }
825 // If we have passed an interval, go to the next one (don't return yet, for there might be
826 // multiple intervals out of the time span).
827 else if (m_interval_end_times_seconds[m_currentIndex]
828 < m_start_time_seconds + this->sim->time_step * m_time_delta)
829 {
830 m_currentIndex++;
831 }
832 // Otherwise, we are currently outside of an interval and return false.
833 else
834 {
835 return false;
836 }
837 }
838 // If the while loop exits, we have passed the final interval and can always return false.
839 return false;
840}
841
842template <typename T>
844
845#endif // OUTPUT_CSV_TOOL_H
This error class inherits from std::exception and marks faulty parameter or CL inputs....
Definition IniParser.h:71
Concrete implementation of a matrix class representing a Compressed Sparse Rows (CSR) matrix....
Definition CsrMatrix.h:37
CsrSparseMatrix()
Constructor for an empty CsrSparseMatrix object. Leaves all storage arrays empty but sets the flag to...
Definition CsrMatrix.h:94
Abstract base class for the managing modules. Managing modules are the highest tier of modules and ar...
Definition GenericManagingModule.h:29
InputManager ini_file_data
Definition GenericManagingModule.h:38
SimulationClassBase< T > * sim
Definition GenericManagingModule.h:31
std::vector< std::string > m_generic_submodules
Definition GenericManagingModule.h:36
std::pair< int, int > size() const
Function that returns the size of the matrix as a pair in (rows, columns) format.
Definition GenericMatrix.h:120
std::vector< std::string > getStringVectorParameters(const std::string &key) const
Definition InputManager.cpp:508
void loadUserInput(const std::string &user_ini_file_path)
Public function to load and merge user supplied ini files with the already stored data.
Definition InputManager.cpp:45
std::string getStringParameters(const std::string &key) const
Getter function to access the m_parameters map and returns a string. Throws a BadInput error,...
Definition InputManager.cpp:498
static constexpr bool registerModule(std::string name, creation_method module) noexcept
Function that adds a module to the module registry map.
Definition ModuleFactory.h:76
Saves specified simulation field data into CSV files.
Definition OutputCsvTool.h:52
bool output() override
Definition OutputCsvTool.h:307
bool preTimeStep() override
Definition OutputCsvTool.h:100
std::string_view getNameLocal() const override
Definition OutputCsvTool.h:114
bool postNonLinIter() override
Definition OutputCsvTool.h:101
bool init() override
Definition OutputCsvTool.h:224
static std::string getName()
Definition OutputCsvTool.h:113
bool exec(std::string_view param) override
Definition OutputCsvTool.h:198
bool setup(std::vector< std::shared_ptr< GenericSubmodule< T > > > all_submodules) override
Definition OutputCsvTool.h:141
OutputCsvTool(SimulationClassBase< T > *sim)
Definition OutputCsvTool.h:120
static std::shared_ptr< GenericManagingModule< T > > createMethode(SimulationClassBase< T > *sim)
Definition OutputCsvTool.h:109
std::vector< std::string > getChainInsertion() const override
Definition OutputCsvTool.h:104
bool postTimeStep() override
Definition OutputCsvTool.h:234