13#include <spdlog/fmt/bundled/ostream.h>
17#include <unordered_set>
28 return filenamePrefix.empty() || filenamePrefix.ends_with(
'/') ||
29 filenamePrefix.ends_with(
'\\')
35static void outputGlobalMatrix(
GlobalMatrix const& mat, std::ostream& os)
42static void outputGlobalVector(
GlobalVector const& vec, std::ostream& os)
44 os <<
"(" << vec.
size() <<
")\n";
48std::ofstream openGlobalMatrixOutputFile(std::string
const& filenamePrefix,
49 std::size_t
const counter,
50 double const t,
int const process_id,
51 std::string
const& which_matrix,
52 std::string
const& extension)
54 auto const filename = fmt::format(
55 "{}{}ogs_global_matrix_cnt_{:03}_t_{:g}_pcs_{}_{}.{}", filenamePrefix,
57 which_matrix, extension);
59 std::ofstream fh{filename};
63 OGS_FATAL(
"Could not open file `{}' for global matrix debug output",
67 fh << std::setprecision(std::numeric_limits<double>::max_digits10);
73 std::string
const& env_var)
75 char const*
const prefix = std::getenv(env_var.c_str());
76 return prefix ? std::make_optional(prefix) : std::nullopt;
81 return fmt::format(
"{}{}ogs_local_matrix.log", filenamePrefix,
85Eigen::Map<
const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic,
90 static_cast<Eigen::Index
>(std::round(std::sqrt(entries.size())));
92 return {entries.data(), num_r_c, num_r_c};
101 std::string
const& warn_msg)
103 std::istringstream sstr{str};
104 std::unordered_set<std::size_t> result;
105 std::ptrdiff_t value;
107 while (sstr >> value)
109 [[likely]]
if (value >= 0)
111 result.insert(value);
115 if (!warn_msg.empty())
117 WARN(
"{}", warn_msg);
124 if (!sstr.eof() && !warn_msg.empty())
127 WARN(
"{}", warn_msg);
134 std::string
const& element_ids_str)
136 if (element_ids_str.empty())
141 if (element_ids_str ==
"*")
143 return [](std::size_t) {
return true; };
148 "Error parsing list of element ids for local matrix debug "
149 "output. We'll try to proceed anyway, as best as we can.");
151 if (element_ids.empty())
156 return [element_ids = std::move(element_ids)](std::size_t element_id)
157 {
return element_ids.contains(element_id); };
163 auto opt_prefix = getEnvironmentVariable(
"OGS_GLOBAL_MAT_OUT_PREFIX");
165 if (opt_prefix.has_value())
173 "You requested global matrix output (OGS_GLOBAL_MAT_OUT_PREFIX is "
174 "set), which is not yet implemented for PETSc matrices.");
194 process_id,
"M",
"mat");
197 outputGlobalMatrix(M, fh);
202 process_id,
"K",
"mat");
205 outputGlobalMatrix(K, fh);
210 process_id,
"b",
"vec");
213 outputGlobalVector(b, fh);
239 process_id,
"b",
"vec");
242 outputGlobalVector(b, fh);
247 process_id,
"Jac",
"mat");
250 outputGlobalMatrix(Jac, fh);
263 auto const opt_prefix = getEnvironmentVariable(
"OGS_LOCAL_MAT_OUT_PREFIX");
264 auto const opt_elements =
265 getEnvironmentVariable(
"OGS_LOCAL_MAT_OUT_ELEMENTS");
272 "Environment variable OGS_LOCAL_MAT_OUT_ELEMENTS is set, but "
273 "OGS_LOCAL_MAT_OUT_PREFIX is not. Local matrix debug output "
274 "will be disabled.");
282 "Environment variable OGS_LOCAL_MAT_OUT_PREFIX is set, but "
283 "OGS_LOCAL_MAT_OUT_ELEMENTS is not. Local matrix debug output "
284 "will be disabled.");
294 "Environment variable OGS_LOCAL_MAT_OUT_ELEMENTS not set "
295 "properly. Local matrix debug output will be disabled.");
299 auto const outputFilename = localMatrixOutputFilename(*opt_prefix);
305 "File `{}' for local matrix debug output could not be "
310 DBUG(
"Successfully opened local matrix debug output file {}.",
315 std::size_t
const element_id,
316 std::vector<double>
const& local_M_data,
317 std::vector<double>
const& local_K_data,
318 std::vector<double>
const& local_b_data)
325 std::lock_guard lock_guard{
mutex_};
329 DBUG(
"Writing to local matrix debug output file...");
331 fmt::print(fh,
"## t = {:.{}g}, process id = {}, element id = {}\n\n", t,
332 std::numeric_limits<double>::max_digits10, process_id,
335 if (!local_M_data.empty())
338 fmt::print(fh,
"# M\n{}\n\n", toSquareMatrixRowMajor(local_M_data));
341 if (!local_K_data.empty())
344 fmt::print(fh,
"# K\n{}\n\n", toSquareMatrixRowMajor(local_K_data));
347 if (!local_b_data.empty())
355 std::size_t
const element_id,
356 std::vector<double>
const& local_b_data,
357 std::vector<double>
const& local_Jac_data)
364 std::lock_guard lock_guard{
mutex_};
368 DBUG(
"Writing to local matrix debug output file...");
370 fmt::print(fh,
"## t = {:.{}g}, process id = {}, element id = {}\n\n", t,
371 std::numeric_limits<double>::max_digits10, process_id,
374 if (!local_b_data.empty())
380 if (!local_Jac_data.empty())
383 fmt::print(fh,
"# Jac\n{}\n\n\n",
384 toSquareMatrixRowMajor(local_Jac_data));
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
IndexType getNumberOfColumns() const
return the number of columns
void write(const std::string &filename) const
printout this matrix for debugging
IndexType getNumberOfRows() const
return the number of rows
Global vector based on Eigen vector.
IndexType size() const
return a vector length
RawVectorType & getRawVector()
return a raw Eigen vector object
Eigen::Map< const Vector > toVector(std::vector< double > const &data, Eigen::VectorXd::Index size)
Creates an Eigen mapped vector from the given data vector.
std::unordered_set< std::size_t > parseSetOfSizeT(std::string const &str, std::string const &warn_msg)
std::function< bool(std::size_t)> createLocalMatrixOutputElementPredicate(std::string const &element_ids_str)
std::string localMatrixOutputFilename(std::string const &filenamePrefix)
Eigen::Map< const Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > > toSquareMatrixRowMajor(std::vector< double > entries)
static std::optional< std::string > getEnvironmentVariable(std::string const &env_var)
std::string getSeparatorAfterFilenamePrefix(std::string const &filenamePrefix)
std::string filenamePrefix_
void operator()(double const t, int const process_id, GlobalMatrix const &M, GlobalMatrix const &K, GlobalVector const &b)
bool isOutputRequested(std::size_t const element_id) const
std::function< bool(std::size_t)> output_element_predicate_
void operator()(double const t, int const process_id, std::size_t const element_id, std::vector< double > const &local_M_data, std::vector< double > const &local_K_data, std::vector< double > const &local_b_data)
std::ofstream outputFile_