Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/IO/PDFWriter.cpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief Univariate PDF writer
9 : : \brief PDF writer class definition
10 : : \details This file defines a PDF writer class that facilitates outputing
11 : : probability density functions (PDFs) into files in various formats using
12 : : various configurations.
13 : : */
14 : : // *****************************************************************************
15 : :
16 : : #include <iomanip>
17 : :
18 : : #include "NoWarning/exodusII.hpp"
19 : :
20 : : #include "PDFWriter.hpp"
21 : : #include "Exception.hpp"
22 : :
23 : : using tk::PDFWriter;
24 : :
25 : 567 : PDFWriter::PDFWriter( const std::string& filename,
26 : : ctr::TxtFloatFormatType format,
27 : 567 : std::streamsize precision ) :
28 : 567 : Writer( filename )
29 : : // *****************************************************************************
30 : : // Constructor
31 : : //! \param[in] filename Output filename to which output the PDF
32 : : //! \param[in] format Configure floating-point output format for ASCII output
33 : : //! \param[in] precision Configure precision for floating-point ASCII output
34 : : // *****************************************************************************
35 : : {
36 : : // Set floating-point format for output file stream
37 [ - + ]: 567 : if (format == ctr::TxtFloatFormatType::DEFAULT)
38 : : {} //m_outFile << std::defaultfloat; GCC does not yet support this
39 [ - - ]: 0 : else if (format == ctr::TxtFloatFormatType::FIXED)
40 [ - - ]: 0 : m_outFile << std::fixed;
41 [ - - ]: 0 : else if (format == ctr::TxtFloatFormatType::SCIENTIFIC)
42 [ - - ]: 0 : m_outFile << std::scientific;
43 [ - - ][ - - ]: 0 : else Throw( "Text floating-point format not recognized." );
[ - - ]
44 : :
45 : : // Set numeric precision for output file stream if the input makes sense
46 [ + - ][ + - ]: 567 : if (precision > 0 && precision < std::numeric_limits< tk::real >::digits10+2)
47 [ + - ]: 567 : m_outFile << std::setprecision( static_cast<int>(precision) );
48 : 567 : }
49 : :
50 : : void
51 : 567 : PDFWriter::writeTxt( const UniPDF& pdf, const tk::ctr::PDFInfo& info ) const
52 : : // *****************************************************************************
53 : : // Write out standardized univariate PDF to file
54 : : //! \param[in] pdf Univariate PDF
55 : : //! \param[in] info PDF metadata
56 : : // *****************************************************************************
57 : : {
58 : 567 : const auto& name = info.name;
59 : 567 : const auto& uext = info.exts;
60 : 567 : const auto& vars = info.vars;
61 : 567 : const auto& it = info.it;
62 : 567 : const auto& time = info.time;
63 : :
64 [ + - ]: 567 : assertSampleSpaceDimensions< 1 >( vars );
65 [ + - ]: 567 : assertSampleSpaceExtents< 1 >( uext );
66 : :
67 : : // Query and optionally override number of bins and minimum of sample space if
68 : : // user-specified extents were given and copy probabilities from pdf to an
69 : : // array for output
70 : : std::size_t nbi;
71 : : tk::real min, max;
72 : 1134 : std::vector< tk::real > outpdf;
73 : : tk::real binsize;
74 : : std::array< long, 2*UniPDF::dim > ext;
75 [ + - ]: 567 : extents( pdf, uext, nbi, min, max, binsize, ext, outpdf );
76 : :
77 : : // Output header
78 : : m_outFile << "# vim: filetype=sh:\n#\n"
79 : 567 : << "# Univariate PDF: " << name << '(' << vars[0] << ')' << '\n'
80 : : << "# -----------------------------------------------\n"
81 [ + - ][ + - ]: 567 : << "# Numeric precision: " << m_outFile.precision() << '\n'
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
82 [ + - ][ + - ]: 567 : << "# Bin size: " << binsize << '\n'
83 [ + - ][ + - ]: 567 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1
[ + - ][ + - ]
84 : : << '\n'
85 [ + - ][ + - ]: 567 : << "# Number of bins output: " << nbi << '\n'
86 [ + - ][ + - ]: 567 : << "# Sample space extent: [" << min << " : " << max << "]\n"
[ + - ][ + - ]
[ + - ]
87 [ + - ][ + - ]: 567 : << "# Integral: " << pdf.integral() << "\n"
[ + - ][ + - ]
[ + - ]
88 [ + - ][ + - ]: 567 : << "# Iteration: " << it << "\n"
[ + - ]
89 [ + - ][ + - ]: 567 : << "# Physical time: " << time << "\n#\n"
[ + - ]
90 : : << "# Example step-by-step visualization with gnuplot\n"
91 : : << "# -----------------------------------------------\n"
92 : : << "# gnuplot> set grid\n"
93 : : << "# gnuplot> unset key\n"
94 : 567 : << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
95 : 567 : << "# gnuplot> set ylabel \"" << name << "(" << vars[0] << ")\"\n"
96 [ + - ][ + - ]: 567 : << "# gnuplot> plot ";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
97 [ - + ][ - - ]: 567 : if (!uext.empty()) m_outFile << "[" << uext[0] << ':' << uext[1] << "] ";
[ - - ][ - - ]
[ - - ][ - - ]
98 : 567 : m_outFile << "\"" << m_filename << "\" with points\n#\n"
99 : : << "# Gnuplot one-liner for quick copy-paste\n"
100 : : << "# -----------------------------------------------\n"
101 : 567 : << "# set grid; unset key; set xlabel \"" << vars[0]
102 : 567 : << "\"; set ylabel \"" << name << "(" << vars[0]
103 [ + - ][ + - ]: 567 : << ")\"; plot";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
104 [ - + ][ - - ]: 567 : if (!uext.empty()) m_outFile << " [" << uext[0] << ':' << uext[1] << "]";
[ - - ][ - - ]
[ - - ][ - - ]
105 : 567 : m_outFile << " \"" << m_filename << "\" w p\n#\n"
106 : 1134 : << "# Data columns: " << vars[0] << ", " << name << "(" << vars[0]
107 [ + - ][ + - ]: 567 : << ")\n# -----------------------------------------------\n";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
108 : :
109 : : // If no user-specified sample space extents, output pdf map directly
110 [ + - ]: 567 : if (uext.empty()) {
111 [ + + ]: 127013 : for (const auto& p : pdf.map())
112 [ + - ][ + - ]: 126446 : m_outFile << binsize * static_cast<tk::real>(p.first) << '\t'
113 : 126446 : << static_cast<tk::real>(p.second) / binsize /
114 [ + - ]: 126446 : static_cast<tk::real>(pdf.nsample())
115 [ + - ]: 126446 : << std::endl;
116 : : } else { // If user-specified sample space extents, output outpdf array
117 : 0 : std::size_t bin = 0;
118 [ - - ]: 0 : for (const auto& p : outpdf)
119 [ - - ][ - - ]: 0 : m_outFile << binsize * static_cast<tk::real>(bin++) + uext[0] << '\t'
120 [ - - ][ - - ]: 0 : << p << std::endl;
121 : : }
122 : 567 : }
123 : :
124 : : void
125 : 0 : PDFWriter::writeTxt( const BiPDF& pdf, const tk::ctr::PDFInfo& info ) const
126 : : // *****************************************************************************
127 : : // Write out standardized bivariate PDF to text file
128 : : //! \param[in] pdf Bivariate PDF
129 : : //! \param[in] info PDF metadata
130 : : // *****************************************************************************
131 : : {
132 : 0 : const auto& name = info.name;
133 : 0 : const auto& uext = info.exts;
134 : 0 : const auto& vars = info.vars;
135 : 0 : const auto& it = info.it;
136 : 0 : const auto& time = info.time;
137 : :
138 [ - - ]: 0 : assertSampleSpaceDimensions< 2 >( vars );
139 [ - - ]: 0 : assertSampleSpaceExtents< 2 >( uext );
140 : :
141 : : // Query and optionally override number of bins and minima of sample space if
142 : : // user-specified extents were given and copy probabilities from pdf to a
143 : : // logically 2D array for output
144 : : std::size_t nbix, nbiy;
145 : : tk::real xmin, xmax, ymin, ymax;
146 : 0 : std::vector< tk::real > outpdf;
147 : : std::array< tk::real, 2 > binsize;
148 : : std::array< long, 2*BiPDF::dim > ext;
149 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
150 : : ctr::PDFCenteringType::ELEM );
151 : :
152 : : // Output metadata
153 : : m_outFile << "# vim: filetype=sh:\n#\n"
154 : 0 : << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
155 : 0 : << vars[1] << ")\n"
156 : : << "# -----------------------------------------------\n"
157 [ - - ][ - - ]: 0 : << "# Numeric precision: " << m_outFile.precision() << '\n'
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
158 [ - - ][ - - ]: 0 : << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
[ - - ][ - - ]
[ - - ]
159 [ - - ][ - - ]: 0 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
[ - - ][ - - ]
160 [ - - ]: 0 : << ext[3] - ext[2] + 1 << '\n'
161 [ - - ][ - - ]: 0 : << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
[ - - ][ - - ]
162 [ - - ][ - - ]: 0 : << "# Sample space extents: [" << xmin << " : " << xmax
[ - - ][ - - ]
[ - - ]
163 [ - - ][ - - ]: 0 : << "], [" << ymin << " : " << ymax << "]\n"
[ - - ][ - - ]
164 [ - - ][ - - ]: 0 : << "# Iteration: " << it << "\n"
[ - - ][ - - ]
165 [ - - ][ - - ]: 0 : << "# Physical time: " << time << "\n#\n"
[ - - ]
166 : : << "# Example step-by-step visualization with gnuplot\n"
167 : : << "# -----------------------------------------------\n"
168 : : << "# gnuplot> set grid\n"
169 : : << "# gnuplot> unset key\n"
170 : 0 : << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
171 : 0 : << "# gnuplot> set ylabel \"" << vars[1] << "\"\n"
172 : 0 : << "# gnuplot> set zlabel \"" << name << "(" << vars[0] << ","
173 : 0 : << vars[1] << ")\"\n"
174 : : << "# gnuplot> set dgrid3d 50,50,1\n"
175 : : << "# gnuplot> set cntrparam levels 20\n"
176 [ - - ][ - - ]: 0 : << "# gnuplot> set contour\n";
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
177 [ - - ]: 0 : if (!uext.empty())
178 [ - - ][ - - ]: 0 : m_outFile << "# gnuplot> set xrange [" << uext[0] << ':' << uext[1] << "]\n"
[ - - ][ - - ]
179 [ - - ][ - - ]: 0 : << "# gnuplot> set yrange [" << uext[2] << ':' << uext[3] << "]\n";
[ - - ][ - - ]
[ - - ][ - - ]
180 : :
181 : 0 : m_outFile << "# gnuplot> splot \"" << m_filename << "\" with lines\n#\n"
182 : : << "# Gnuplot one-liner for quick copy-paste\n"
183 : : << "# --------------------------------------\n"
184 : 0 : << "# set grid; unset key; set xlabel \"" << vars[0]
185 : 0 : << "\"; set ylabel \"" << vars[1] << "\"; set zlabel \"" << name
186 : 0 : << "(" << vars[0] << ',' << vars[1] << ")\"; set dgrid3d 50,50,1; "
187 [ - - ][ - - ]: 0 : "set cntrparam levels 20; set contour; ";
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
188 [ - - ]: 0 : if (!uext.empty())
189 [ - - ][ - - ]: 0 : m_outFile << "set xrange [" << uext[0] << ':' << uext[1] << "]; set yrange "
[ - - ][ - - ]
190 [ - - ][ - - ]: 0 : "[" << uext[2] << ':' << uext[3] << "]; ";
[ - - ][ - - ]
[ - - ]
191 : 0 : m_outFile << "splot \"" << m_filename << "\" w l\n#\n"
192 : 0 : << "# Data columns: " << vars[0] << ", " << vars[1] << ", "
193 : 0 : << name << '(' << vars[0] << ',' << vars[1] << ")\n"
194 [ - - ][ - - ]: 0 : << "# -----------------------------------------------\n";
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
195 : :
196 : : // If no user-specified sample space extents, output pdf map directly
197 [ - - ]: 0 : if (uext.empty()) {
198 [ - - ]: 0 : for (const auto& p : pdf.map())
199 [ - - ][ - - ]: 0 : m_outFile << binsize[0] * static_cast<tk::real>(p.first[0]) << '\t'
200 [ - - ][ - - ]: 0 : << binsize[1] * static_cast<tk::real>(p.first[1]) << '\t'
201 : 0 : << p.second / binsize[0] / binsize[1] /
202 [ - - ]: 0 : static_cast<tk::real>(pdf.nsample())
203 [ - - ]: 0 : << std::endl;
204 : : } else { // If user-specified sample space extents, output outpdf array
205 : 0 : std::size_t bin = 0;
206 [ - - ]: 0 : for (const auto& p : outpdf) {
207 [ - - ]: 0 : m_outFile << binsize[0] * static_cast<tk::real>(bin % nbix) + uext[0]
208 [ - - ]: 0 : << '\t'
209 [ - - ]: 0 : << binsize[1] * static_cast<tk::real>(bin / nbix) + uext[2]
210 [ - - ]: 0 : << '\t'
211 [ - - ]: 0 : << p
212 [ - - ]: 0 : << std::endl;
213 : 0 : ++bin;
214 : : }
215 : : }
216 : :
217 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
218 : 0 : }
219 : :
220 : : void
221 : 0 : PDFWriter::writeTxt( const TriPDF& pdf, const tk::ctr::PDFInfo& info ) const
222 : : // *****************************************************************************
223 : : // Write out standardized trivariate PDF to text file
224 : : //! \param[in] pdf Trivariate PDF
225 : : //! \param[in] info PDF metadata
226 : : // *****************************************************************************
227 : : {
228 : 0 : const auto& name = info.name;
229 : 0 : const auto& uext = info.exts;
230 : 0 : const auto& vars = info.vars;
231 : 0 : const auto& it = info.it;
232 : 0 : const auto& time = info.time;
233 : :
234 [ - - ]: 0 : assertSampleSpaceDimensions< 3 >( vars );
235 [ - - ]: 0 : assertSampleSpaceExtents< 3 >( uext );
236 : :
237 : : // Query and optionally override number of bins and minima of sample space if
238 : : // user-specified extents were given and copy probabilities from pdf to a
239 : : // logically 3D array for output
240 : : std::size_t nbix, nbiy, nbiz;
241 : : tk::real xmin, xmax, ymin, ymax, zmin, zmax;
242 : 0 : std::vector< tk::real > outpdf;
243 : : std::array< tk::real, 3 > binsize;
244 : : std::array< long, 2*TriPDF::dim > ext;
245 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
246 : : binsize, ext, outpdf, ctr::PDFCenteringType::ELEM );
247 : :
248 : : // Output header
249 : : m_outFile << "# vim: filetype=sh:\n#\n"
250 : 0 : << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
251 : 0 : << vars[1] << ',' << vars[2] << ")\n"
252 : : << "# -----------------------------------------------\n"
253 [ - - ][ - - ]: 0 : << "# Numeric precision: " << m_outFile.precision() << '\n'
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
254 [ - - ][ - - ]: 0 : << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
[ - - ][ - - ]
[ - - ][ - - ]
255 [ - - ]: 0 : << binsize[2] << '\n'
256 [ - - ][ - - ]: 0 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
[ - - ][ - - ]
257 [ - - ][ - - ]: 0 : << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
[ - - ]
258 [ - - ][ - - ]: 0 : << "# Number of bins output: " << nbix << " x " << nbiy << " x "
[ - - ][ - - ]
[ - - ][ - - ]
259 : 0 : << nbiz << '\n'
260 [ - - ][ - - ]: 0 : << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
261 [ - - ][ - - ]: 0 : << ymin << " : " << ymax << "], [" << zmin << " : " << zmax
[ - - ][ - - ]
[ - - ][ - - ]
262 : : << "]\n"
263 [ - - ][ - - ]: 0 : << "# Iteration: " << it << "\n"
[ - - ][ - - ]
264 [ - - ][ - - ]: 0 : << "# Physical time: " << time << "\n#\n"
[ - - ]
265 : : << "# Example step-by-step visualization with gnuplot\n"
266 : : << "# -----------------------------------------------\n"
267 : : << "# gnuplot> set grid\n"
268 : 0 : << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
269 : 0 : << "# gnuplot> set ylabel \"" << vars[1] << "\"\n"
270 [ - - ][ - - ]: 0 : << "# gnuplot> set zlabel \"" << vars[2] << "\"\n";
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
271 [ - - ]: 0 : if (!uext.empty())
272 [ - - ][ - - ]: 0 : m_outFile << "# gnuplot> set xrange [" << uext[0] << ':' << uext[1] << "]\n"
[ - - ][ - - ]
273 [ - - ][ - - ]: 0 : << "# gnuplot> set yrange [" << uext[2] << ':' << uext[3] << "]\n"
[ - - ][ - - ]
[ - - ]
274 [ - - ][ - - ]: 0 : << "# gnuplot> set zrange [" << uext[4] << ':' << uext[5] << "]\n";
[ - - ][ - - ]
[ - - ][ - - ]
275 : 0 : m_outFile << "# gnuplot> splot \"" << m_filename << "\" pointtype 7 "
276 : 0 : "linecolor palette title \"" << name << '(' << vars[0] << ','
277 : 0 : << vars[1] << ',' << vars[2] << ")\"\n#\n"
278 : : << "# Gnuplot one-liner for quick copy-paste\n"
279 : : << "# --------------------------------------\n"
280 : 0 : << "# set grid; set xlabel \"" << vars[0] << "\"; set ylabel \""
281 [ - - ][ - - ]: 0 : << vars[1] << "\"; set zlabel \"" << vars[2] << "\"; ";
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
282 [ - - ]: 0 : if (!uext.empty())
283 [ - - ][ - - ]: 0 : m_outFile << "set xrange [" << uext[0] << ':' << uext[1] << "]; set yrange "
[ - - ][ - - ]
284 [ - - ][ - - ]: 0 : "[" << uext[2] << ':' << uext[3] << "]; set zrange ["
[ - - ][ - - ]
[ - - ]
285 [ - - ][ - - ]: 0 : << uext[4] << ':' << uext[5] << "]; ";
[ - - ][ - - ]
286 : 0 : m_outFile << "splot \"" << m_filename << "\" pt 7 linecolor palette title \""
287 : 0 : << name << '(' << vars[0] << ',' << vars[1] << ',' << vars[2] << ')'
288 : : << "\"\n#\n"
289 : 0 : << "# Data columns: " << vars[0] << ", " << vars[1] << ", "
290 : 0 : << vars[2] << ", " << name << '(' << vars[0] << ',' << vars[1]
291 : 0 : << ',' << vars[2] << ")\n"
292 [ - - ][ - - ]: 0 : << "# -----------------------------------------------\n";
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
293 : :
294 : : // If no user-specified sample space extents, output pdf map directly
295 [ - - ]: 0 : if (uext.empty()) {
296 [ - - ]: 0 : for (const auto& p : pdf.map())
297 [ - - ][ - - ]: 0 : m_outFile << binsize[0] * static_cast<tk::real>(p.first[0]) << '\t'
298 [ - - ][ - - ]: 0 : << binsize[1] * static_cast<tk::real>(p.first[1]) << '\t'
299 [ - - ][ - - ]: 0 : << binsize[2] * static_cast<tk::real>(p.first[2]) << '\t'
300 : 0 : << p.second / binsize[0] / binsize[1] / binsize[2]
301 [ - - ]: 0 : / static_cast<tk::real>(pdf.nsample())
302 [ - - ]: 0 : << std::endl;
303 : : } else { // If user-specified sample space extents, output outpdf array
304 : 0 : std::size_t bin = 0;
305 : 0 : const auto n = nbix*nbiy;
306 [ - - ]: 0 : for (const auto& p : outpdf) {
307 [ - - ]: 0 : m_outFile << binsize[0] * static_cast<tk::real>(bin % n % nbix) + uext[0]
308 [ - - ]: 0 : << '\t'
309 [ - - ]: 0 : << binsize[1] * static_cast<tk::real>(bin % n / nbix) + uext[2]
310 [ - - ]: 0 : << '\t'
311 [ - - ][ - - ]: 0 : << binsize[2] * static_cast<tk::real>(bin / n) + uext[4] << '\t'
312 [ - - ]: 0 : << p
313 [ - - ]: 0 : << std::endl;
314 : 0 : ++bin;
315 : : }
316 : : }
317 : :
318 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
319 : 0 : }
320 : :
321 : : void
322 : 0 : PDFWriter::writeGmshTxt( const BiPDF& pdf,
323 : : const tk::ctr::PDFInfo& info,
324 : : ctr::PDFCenteringType centering ) const
325 : : // *****************************************************************************
326 : : // Write out standardized bivariate PDF to Gmsh (text) format
327 : : //! \param[in] pdf Bivariate PDF
328 : : //! \param[in] info PDF metadata
329 : : //! \param[in] centering Bin centering on sample space mesh
330 : : // *****************************************************************************
331 : : {
332 : 0 : const auto& name = info.name;
333 : 0 : const auto& uext = info.exts;
334 : 0 : const auto& vars = info.vars;
335 : 0 : const auto& it = info.it;
336 : 0 : const auto& time = info.time;
337 : :
338 [ - - ]: 0 : assertSampleSpaceDimensions< 2 >( vars );
339 [ - - ]: 0 : assertSampleSpaceExtents< 2 >( uext );
340 : :
341 : : // Query and optionally override number of bins and minima of sample space if
342 : : // user-specified extents were given and copy probabilities from pdf to a
343 : : // logically 2D array for output
344 : : std::size_t nbix, nbiy;
345 : : tk::real xmin, xmax, ymin, ymax;
346 : 0 : std::vector< tk::real > outpdf;
347 : : std::array< tk::real, 2 > binsize;
348 : : std::array< long, 2*BiPDF::dim > ext;
349 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
350 : : centering );
351 : :
352 : : // Output metadata. The #s are unnecessary, but vi will color it differently.
353 : : m_outFile << "$Comments\n"
354 : : << "# vim: filetype=sh:\n"
355 : 0 : << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
356 : 0 : << vars[1] << ")\n"
357 : : << "# -----------------------------------------------\n"
358 [ - - ][ - - ]: 0 : << "# Numeric precision: " << m_outFile.precision() << '\n'
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
359 [ - - ][ - - ]: 0 : << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
[ - - ][ - - ]
[ - - ]
360 [ - - ][ - - ]: 0 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
[ - - ][ - - ]
361 [ - - ]: 0 : << ext[3] - ext[2] + 1 << '\n'
362 [ - - ][ - - ]: 0 : << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
[ - - ][ - - ]
363 [ - - ][ - - ]: 0 : << "# Sample space extents: [" << xmin << " : " << xmax
[ - - ][ - - ]
[ - - ]
364 [ - - ][ - - ]: 0 : << "], [" << ymin << " : " << ymax << "]\n"
[ - - ][ - - ]
365 [ - - ][ - - ]: 0 : << "# Iteration: " << it << "\n"
[ - - ][ - - ]
366 [ - - ][ - - ]: 0 : << "# Physical time: " << time << "\n"
[ - - ]
367 [ - - ][ - - ]: 0 : << "$EndComments\n";
368 : :
369 : : // Output mesh header: mesh version, file type, data size
370 [ - - ]: 0 : m_outFile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
371 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
372 : :
373 : : // Output grid points of discretized sample space (2D Cartesian grid)
374 [ - - ][ - - ]: 0 : m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1) << std::endl;
[ - - ]
375 : 0 : int k=0;
376 [ - - ]: 0 : for (std::size_t i=0; i<=nbiy; i++) {
377 : 0 : tk::real I = static_cast< tk::real >( i );
378 : 0 : tk::real y = ymin + I*binsize[1];
379 [ - - ]: 0 : for (std::size_t j=0; j<=nbix; j++) {
380 : 0 : tk::real J = static_cast< tk::real >( j );
381 : 0 : tk::real x = xmin + J*binsize[0];
382 [ - - ][ - - ]: 0 : m_outFile << ++k << ' ' << x << ' ' << y << " 0\n";
[ - - ][ - - ]
[ - - ][ - - ]
383 : : }
384 : : }
385 [ - - ]: 0 : m_outFile << "$EndNodes\n";
386 : :
387 : : // Output elements of discretized sample space (2D Cartesian grid)
388 [ - - ][ - - ]: 0 : m_outFile << "$Elements\n" << nbix*nbiy << "\n";
[ - - ]
389 [ - - ]: 0 : for (std::size_t i=0; i<nbix*nbiy; ++i) {
390 : 0 : const auto y = i/nbix;
391 [ - - ][ - - ]: 0 : m_outFile << i+1 << " 3 2 1 1 " << i+y+1 << ' ' << i+y+2 << ' '
[ - - ][ - - ]
[ - - ][ - - ]
392 [ - - ][ - - ]: 0 : << i+y+nbix+3 << ' ' << i+y+nbix+2 << std::endl;
[ - - ][ - - ]
393 : : }
394 [ - - ]: 0 : m_outFile << "$EndElements\n";
395 : :
396 : : // Output PDF function values in element or node centers
397 [ - - ]: 0 : std::string c( "Element" );
398 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) {
399 : 0 : ++nbix; ++nbiy;
400 [ - - ]: 0 : c = "Node";
401 : : }
402 [ - - ][ - - ]: 0 : m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
[ - - ][ - - ]
[ - - ]
403 [ - - ][ - - ]: 0 : << nbix*nbiy << "\n";
404 : :
405 : : // If no user-specified sample space extents, output pdf map directly
406 [ - - ]: 0 : if (uext.empty()) {
407 : :
408 [ - - ]: 0 : std::vector< int > out( nbix*nbiy, 0 ); // indicate bins filled (1)
409 [ - - ]: 0 : for (const auto& p : pdf.map()) {
410 : 0 : const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
411 : 0 : (p.first[0] - ext[0]) % static_cast<long>(nbix);
412 [ - - ][ - - ]: 0 : Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshTxt()." );
[ - - ][ - - ]
413 [ - - ][ - - ]: 0 : Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
[ - - ][ - - ]
414 : : "Bin overflow in PDFWriter::writeGmshTxt()." );
415 : 0 : out[ static_cast<std::size_t>(bin) ] = 1;
416 [ - - ][ - - ]: 0 : m_outFile << bin+1 << '\t'
417 : 0 : << p.second / binsize[0] / binsize[1]
418 [ - - ]: 0 : / static_cast<tk::real>(pdf.nsample())
419 [ - - ]: 0 : << std::endl;
420 : : }
421 : : // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
422 : : // bins if holes exist in the data, it also looks better as zero than holes)
423 [ - - ]: 0 : for (std::size_t i=0; i<out.size(); ++i)
424 [ - - ][ - - ]: 0 : if (out[i] == 0) m_outFile << i+1 << "\t0" << std::endl;
[ - - ][ - - ]
425 : :
426 : : } else { // If user-specified sample space extents, output outpdf array
427 : :
428 : 0 : std::size_t bin = 0;
429 [ - - ][ - - ]: 0 : for (const auto& p : outpdf) m_outFile << ++bin << ' ' << p << std::endl;
[ - - ][ - - ]
[ - - ]
430 : :
431 : : }
432 : :
433 [ - - ][ - - ]: 0 : m_outFile << "$End" << c << "Data\n";
[ - - ]
434 : :
435 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
436 : 0 : }
437 : :
438 : : void
439 : 0 : PDFWriter::writeGmshTxt( const TriPDF& pdf,
440 : : const tk::ctr::PDFInfo& info,
441 : : ctr::PDFCenteringType centering ) const
442 : : // *****************************************************************************
443 : : // Write out standardized trivariate PDF to Gmsh (text) format
444 : : //! \param[in] pdf Trivariate PDF
445 : : //! \param[in] info PDF metadata
446 : : //! \param[in] centering Bin centering on sample space mesh
447 : : // *****************************************************************************
448 : : {
449 : 0 : const auto& name = info.name;
450 : 0 : const auto& uext = info.exts;
451 : 0 : const auto& vars = info.vars;
452 : 0 : const auto& it = info.it;
453 : 0 : const auto& time = info.time;
454 : :
455 [ - - ]: 0 : assertSampleSpaceDimensions< 3 >( vars );
456 [ - - ]: 0 : assertSampleSpaceExtents< 3 >( uext );
457 : :
458 : : // Query and optionally override number of bins and minima of sample space if
459 : : // user-specified extents were given and copy probabilities from pdf to a
460 : : // logically 3D array for output
461 : : std::size_t nbix, nbiy, nbiz;
462 : : tk::real xmin, xmax, ymin, ymax, zmin, zmax;
463 : 0 : std::vector< tk::real > outpdf;
464 : : std::array< tk::real, 3 > binsize;
465 : : std::array< long, 2*TriPDF::dim > ext;
466 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
467 : : binsize, ext, outpdf, centering );
468 : :
469 : : // Output metadata. The #s are unnecessary, but vi will color it differently.
470 : : m_outFile << "$Comments\n"
471 : : << "# vim: filetype=sh:\n#\n"
472 : 0 : << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
473 : 0 : << vars[1] << ',' << vars[2] << ")\n"
474 : : << "# -----------------------------------------------\n"
475 [ - - ][ - - ]: 0 : << "# Numeric precision: " << m_outFile.precision() << '\n'
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
476 [ - - ][ - - ]: 0 : << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
[ - - ][ - - ]
[ - - ][ - - ]
477 [ - - ]: 0 : << binsize[2] << '\n'
478 [ - - ][ - - ]: 0 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
[ - - ][ - - ]
479 [ - - ][ - - ]: 0 : << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
[ - - ]
480 [ - - ][ - - ]: 0 : << "# Number of bins output: " << nbix << " x " << nbiy << " x "
[ - - ][ - - ]
[ - - ][ - - ]
481 : 0 : << nbiz << '\n'
482 [ - - ][ - - ]: 0 : << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
483 [ - - ][ - - ]: 0 : << ymin << " : " << ymax << "], [" << zmin << " : " << zmax << "]\n"
[ - - ][ - - ]
[ - - ][ - - ]
484 [ - - ][ - - ]: 0 : << "# Iteration: " << it << "\n"
[ - - ][ - - ]
485 [ - - ][ - - ]: 0 : << "# Physical time: " << time << "\n#\n"
[ - - ]
486 [ - - ][ - - ]: 0 : << "$EndComments\n";
487 : :
488 : : // Output mesh header: mesh version, file type, data size
489 [ - - ]: 0 : m_outFile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
490 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
491 : :
492 : : // Output grid points of discretized sample space (3D Cartesian grid)
493 [ - - ][ - - ]: 0 : m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1)*(nbiz+1) << std::endl;
[ - - ]
494 : 0 : int l=0;
495 [ - - ]: 0 : for (std::size_t k=0; k<=nbiz; k++) {
496 : 0 : tk::real K = static_cast< tk::real >( k );
497 : 0 : tk::real z = zmin + K*binsize[2];
498 [ - - ]: 0 : for (std::size_t j=0; j<=nbiy; j++) {
499 : 0 : tk::real J = static_cast< tk::real >( j );
500 : 0 : tk::real y = ymin + J*binsize[1];
501 [ - - ]: 0 : for (std::size_t i=0; i<=nbix; i++) {
502 : 0 : tk::real I = static_cast< tk::real >( i );
503 : 0 : tk::real x = xmin + I*binsize[0];
504 [ - - ][ - - ]: 0 : m_outFile << ++l << ' ' << x << ' ' << y << ' ' << z << '\n';
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
505 : : }
506 : : }
507 : : }
508 [ - - ]: 0 : m_outFile << "$EndNodes\n";
509 : :
510 : : // Output elements of discretized sample space (3D Cartesian grid)
511 [ - - ][ - - ]: 0 : m_outFile << "$Elements\n" << nbix*nbiy*nbiz << "\n";
[ - - ]
512 : 0 : const auto n = nbix*nbiy;
513 : 0 : const auto p = (nbix+1)*(nbiy+1);
514 [ - - ]: 0 : for (std::size_t i=0; i<nbix*nbiy*nbiz; ++i) {
515 : 0 : const auto y = i/nbix + i/n*(nbix+1);
516 [ - - ][ - - ]: 0 : m_outFile << i+1 << " 5 2 1 1 " << i+y+1 << ' ' << i+y+2 << ' '
[ - - ][ - - ]
[ - - ][ - - ]
517 [ - - ][ - - ]: 0 : << i+y+nbix+3 << ' ' << i+y+nbix+2 << ' '
[ - - ][ - - ]
518 [ - - ][ - - ]: 0 : << i+y+p+1 << ' ' << i+y+p+2 << ' '
[ - - ][ - - ]
519 [ - - ][ - - ]: 0 : << i+y+p+nbix+3 << ' ' << i+y+p+nbix+2 << ' '
[ - - ][ - - ]
520 [ - - ]: 0 : << std::endl;
521 : : }
522 [ - - ]: 0 : m_outFile << "$EndElements\n";
523 : :
524 : : // Output PDF function values in element or node centers
525 [ - - ]: 0 : std::string c( "Element" );
526 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) {
527 : 0 : ++nbix; ++nbiy; ++nbiz;
528 [ - - ]: 0 : c = "Node";
529 : : }
530 [ - - ][ - - ]: 0 : m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
[ - - ][ - - ]
[ - - ]
531 [ - - ][ - - ]: 0 : << nbix*nbiy*nbiz << "\n";
532 : :
533 : : // If no user-specified sample space extents, output pdf map directly
534 [ - - ]: 0 : if (uext.empty()) {
535 : :
536 [ - - ]: 0 : std::vector< int > out( nbix*nbiy*nbiz, 0 ); // indicate bins filled
537 [ - - ]: 0 : for (const auto& q : pdf.map()) {
538 : 0 : const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
539 : 0 : (q.first[1] - ext[2]) * static_cast<long>(nbix) +
540 : 0 : (q.first[0] - ext[0]) % static_cast<long>(nbix);
541 [ - - ][ - - ]: 0 : Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshTxt()." );
[ - - ][ - - ]
542 [ - - ][ - - ]: 0 : Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
[ - - ][ - - ]
543 : : "Bin overflow in PDFWriter::writeGmshTxt()." );
544 : 0 : out[ static_cast<std::size_t>(bin) ] = 1 ;
545 [ - - ][ - - ]: 0 : m_outFile << bin+1 << '\t'
546 : 0 : << q.second / binsize[0] / binsize[1] / binsize[2]
547 [ - - ]: 0 : / static_cast<tk::real>(pdf.nsample())
548 [ - - ]: 0 : << std::endl;
549 : : }
550 : : // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
551 : : // bins if holes exist in the data, it also looks better as zero than holes)
552 [ - - ]: 0 : for (std::size_t i=0; i<out.size(); ++i)
553 [ - - ][ - - ]: 0 : if (out[i] == 0) m_outFile << i+1 << "\t0" << std::endl;
[ - - ][ - - ]
554 : :
555 : : } else { // If user-specified sample space extents, output outpdf array
556 : :
557 : 0 : std::size_t bin = 0;
558 [ - - ][ - - ]: 0 : for (const auto& q : outpdf) m_outFile << ++bin << ' ' << q << std::endl;
[ - - ][ - - ]
[ - - ]
559 : :
560 : : }
561 : :
562 [ - - ][ - - ]: 0 : m_outFile << "$End" << c << "Data\n";
[ - - ]
563 : :
564 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
565 : 0 : }
566 : :
567 : : void
568 : 0 : PDFWriter::writeGmshBin( const BiPDF& pdf,
569 : : const tk::ctr::PDFInfo& info,
570 : : ctr::PDFCenteringType centering ) const
571 : : // *****************************************************************************
572 : : // Write out standardized bivariate PDF to Gmsh (binary) format
573 : : //! \param[in] pdf Bivariate PDF
574 : : //! \param[in] info PDF metadata
575 : : //! \param[in] centering Bin centering on sample space mesh
576 : : // *****************************************************************************
577 : : {
578 : 0 : const auto& name = info.name;
579 : 0 : const auto& uext = info.exts;
580 : 0 : const auto& vars = info.vars;
581 : 0 : const auto& it = info.it;
582 : 0 : const auto& time = info.time;
583 : :
584 [ - - ]: 0 : assertSampleSpaceDimensions< 2 >( vars );
585 [ - - ]: 0 : assertSampleSpaceExtents< 2 >( uext );
586 : :
587 : : // Query and optionally override number of bins and minima of sample space if
588 : : // user-specified extents were given and copy probabilities from pdf to a
589 : : // logically 2D array for output
590 : : std::size_t nbix, nbiy;
591 : : tk::real xmin, xmax, ymin, ymax;
592 : 0 : std::vector< tk::real > outpdf;
593 : : std::array< tk::real, 2 > binsize;
594 : : std::array< long, 2*BiPDF::dim > ext;
595 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
596 : : centering );
597 : :
598 : : // Output metadata. The #s are unnecessary, but vi will color it differently.
599 : : m_outFile << "$Comments\n"
600 : : << "# vim: filetype=sh:\n"
601 : 0 : << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
602 : 0 : << vars[1] << ")\n"
603 : : << "# -----------------------------------------------\n"
604 : : << "# Numeric precision: 64-bit binary\n"
605 [ - - ][ - - ]: 0 : << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
606 [ - - ][ - - ]: 0 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
[ - - ][ - - ]
607 [ - - ]: 0 : << ext[3] - ext[2] + 1 << '\n'
608 [ - - ][ - - ]: 0 : << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
[ - - ][ - - ]
609 [ - - ][ - - ]: 0 : << "# Sample space extents: [" << xmin << " : " << xmax
[ - - ][ - - ]
[ - - ]
610 [ - - ][ - - ]: 0 : << "], [" << ymin << " : " << ymax << "]\n"
[ - - ][ - - ]
611 [ - - ][ - - ]: 0 : << "# Iteration: " << it << "\n"
[ - - ][ - - ]
612 [ - - ][ - - ]: 0 : << "# Physical time: " << time << "\n#\n"
[ - - ]
613 [ - - ][ - - ]: 0 : << "$EndComments\n";
614 : :
615 : : // Output mesh header: mesh version, file type, data size
616 [ - - ]: 0 : m_outFile << "$MeshFormat\n2.2 1 8\n";
617 : 0 : int one = 1;
618 [ - - ]: 0 : m_outFile.write( reinterpret_cast<char*>(&one), sizeof(int) );
619 [ - - ]: 0 : m_outFile << "\n$EndMeshFormat\n";
620 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
621 : :
622 : : // Output grid points of discretized sample space (2D Cartesian grid)
623 [ - - ][ - - ]: 0 : m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1) << std::endl;
[ - - ]
624 : 0 : int k = 0;
625 : 0 : tk::real z = 0.0;
626 [ - - ]: 0 : for (std::size_t i=0; i<=nbiy; i++) {
627 : 0 : tk::real I = static_cast< tk::real >( i );
628 : 0 : tk::real y = ymin + I*binsize[1];
629 [ - - ]: 0 : for (std::size_t j=0; j<=nbix; j++) {
630 : 0 : tk::real J = static_cast< tk::real >( j );
631 : 0 : tk::real x = xmin + J*binsize[0];
632 : 0 : ++k;
633 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &k ), sizeof(int) );
634 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &x ), sizeof(tk::real) );
635 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &y ), sizeof(tk::real) );
636 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &z ), sizeof(tk::real) );
637 : : }
638 : : }
639 [ - - ]: 0 : m_outFile << "\n$EndNodes\n";
640 : :
641 : : // Output elements of discretized sample space (2D Cartesian grid)
642 [ - - ][ - - ]: 0 : m_outFile << "$Elements\n" << nbix*nbiy << "\n";
[ - - ]
643 : 0 : int type = 3; // gmsh elem type: 4-node quadrangle
644 : 0 : std::size_t n = nbix*nbiy; // number of elements in (this single) block
645 : 0 : int ntags = 2; // number of element tags
646 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &type ), sizeof(int) );
647 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &n ), sizeof(int) );
648 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &ntags ), sizeof(int) );
649 [ - - ]: 0 : for (std::size_t i=0; i<n; ++i) {
650 : 0 : const auto y = i/nbix;
651 : 0 : auto id = i+1;
652 : 0 : int tag[2] = { 1, 1 };
653 : 0 : int con[4] = { static_cast< int >( i+y+1 ),
654 : 0 : static_cast< int >( i+y+2 ),
655 : 0 : static_cast< int >( i+y+nbix+3 ),
656 : 0 : static_cast< int >( i+y+nbix+2 ) };
657 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
658 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( tag ), 2*sizeof(int) );
659 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( con ), 4*sizeof(int) );
660 : : }
661 [ - - ]: 0 : m_outFile << "\n$EndElements\n";
662 : :
663 : : // Output PDF function values in element or node centers
664 [ - - ]: 0 : std::string c( "Element" );
665 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) {
666 : 0 : ++nbix; ++nbiy;
667 [ - - ]: 0 : c = "Node";
668 : : }
669 [ - - ][ - - ]: 0 : m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
[ - - ][ - - ]
[ - - ]
670 [ - - ][ - - ]: 0 : << nbix*nbiy << "\n";
671 : :
672 : : // If no user-specified sample space extents, output pdf map directly
673 [ - - ]: 0 : if (uext.empty()) {
674 : :
675 [ - - ]: 0 : std::vector< int > out( nbix*nbiy, 0 ); // indicate bins filled
676 [ - - ]: 0 : for (const auto& p : pdf.map()) {
677 : 0 : const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
678 : 0 : (p.first[0] - ext[0]) % static_cast<long>(nbix);
679 [ - - ][ - - ]: 0 : Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshBin()." );
[ - - ][ - - ]
680 [ - - ][ - - ]: 0 : Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
[ - - ][ - - ]
681 : : "Bin overflow in PDFWriter::writeGmshBin()." );
682 : 0 : out[ static_cast<std::size_t>(bin) ] = 1;
683 : 0 : auto id = static_cast<int>(bin+1);
684 : 0 : tk::real prob = p.second / binsize[0] / binsize[1]
685 : 0 : / static_cast<tk::real>(pdf.nsample());
686 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
687 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
688 : : }
689 : : // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
690 : : // bins if holes exist in the data, it also looks better as zero than holes)
691 : 0 : tk::real prob = 0.0;
692 [ - - ]: 0 : for (std::size_t i=0; i<out.size(); ++i)
693 [ - - ]: 0 : if (out[i] == 0) {
694 : 0 : auto id = static_cast<int>(i+1);
695 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
696 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
697 : : }
698 : :
699 : : } else { // If user-specified sample space extents, output outpdf array
700 : :
701 : 0 : int bin = 0;
702 [ - - ]: 0 : for (auto& p : outpdf) {
703 : 0 : ++bin;
704 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &bin ), sizeof(int) );
705 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &p ), sizeof(tk::real) );
706 : : }
707 : :
708 : : }
709 : :
710 [ - - ][ - - ]: 0 : m_outFile << "$End" << c << "Data\n";
[ - - ]
711 : :
712 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
713 : 0 : }
714 : :
715 : : void
716 : 0 : PDFWriter::writeGmshBin( const TriPDF& pdf,
717 : : const tk::ctr::PDFInfo& info,
718 : : ctr::PDFCenteringType centering ) const
719 : : // *****************************************************************************
720 : : // Write out standardized trivariate PDF to Gmsh (binary) format
721 : : //! \param[in] pdf Trivariate PDF
722 : : //! \param[in] info PDF metadata
723 : : //! \param[in] centering Bin centering on sample space mesh
724 : : // *****************************************************************************
725 : : {
726 : 0 : const auto& name = info.name;
727 : 0 : const auto& uext = info.exts;
728 : 0 : const auto& vars = info.vars;
729 : 0 : const auto& it = info.it;
730 : 0 : const auto& time = info.time;
731 : :
732 [ - - ]: 0 : assertSampleSpaceDimensions< 3 >( vars );
733 [ - - ]: 0 : assertSampleSpaceExtents< 3 >( uext );
734 : :
735 : : // Query and optionally override number of bins and minima of sample space if
736 : : // user-specified extents were given and copy probabilities from pdf to a
737 : : // logically 3D array for output
738 : : std::size_t nbix, nbiy, nbiz;
739 : : tk::real xmin, xmax, ymin, ymax, zmin, zmax;
740 : 0 : std::vector< tk::real > outpdf;
741 : : std::array< tk::real, 3 > binsize;
742 : : std::array< long, 2*TriPDF::dim > ext;
743 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
744 : : binsize, ext, outpdf, centering );
745 : :
746 : : // Output metadata. The #s are unnecessary, but vi will color it differently.
747 : : m_outFile << "$Comments\n"
748 : : << "# vim: filetype=sh:\n#\n"
749 : 0 : << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
750 : 0 : << vars[1] << ',' << vars[2] << ")\n"
751 : : << "# -----------------------------------------------\n"
752 : : << "# Numeric precision: 64-bit binary\n"
753 [ - - ][ - - ]: 0 : << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
754 [ - - ]: 0 : << binsize[2] << '\n'
755 [ - - ][ - - ]: 0 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
[ - - ][ - - ]
756 [ - - ][ - - ]: 0 : << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
[ - - ]
757 [ - - ][ - - ]: 0 : << "# Number of bins output: " << nbix << " x " << nbiy << " x "
[ - - ][ - - ]
[ - - ][ - - ]
758 : 0 : << nbiz << '\n'
759 [ - - ][ - - ]: 0 : << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
760 [ - - ][ - - ]: 0 : << ymin << " : " << ymax << "], [" << zmin << " : " << zmax << "]\n"
[ - - ][ - - ]
[ - - ][ - - ]
761 [ - - ][ - - ]: 0 : << "# Iteration: " << it << "\n"
[ - - ][ - - ]
762 [ - - ][ - - ]: 0 : << "# Physical time: " << time << "\n#\n"
[ - - ]
763 [ - - ][ - - ]: 0 : << "$EndComments\n";
764 : :
765 : : // Output mesh header: mesh version, file type, data size
766 [ - - ]: 0 : m_outFile << "$MeshFormat\n2.2 1 8\n";
767 : 0 : int one = 1;
768 [ - - ]: 0 : m_outFile.write( reinterpret_cast<char*>(&one), sizeof(int) );
769 [ - - ]: 0 : m_outFile << "\n$EndMeshFormat\n";
770 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
771 : :
772 : : // Output grid points of discretized sample space (3D Cartesian grid)
773 [ - - ][ - - ]: 0 : m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1)*(nbiz+1) << std::endl;
[ - - ]
774 : 0 : int l=0;
775 [ - - ]: 0 : for (std::size_t k=0; k<=nbiz; k++) {
776 : 0 : tk::real K = static_cast< tk::real >( k );
777 : 0 : tk::real z = zmin + K*binsize[2];
778 [ - - ]: 0 : for (std::size_t j=0; j<=nbiy; j++) {
779 : 0 : tk::real J = static_cast< tk::real >( j );
780 : 0 : tk::real y = ymin + J*binsize[1];
781 [ - - ]: 0 : for (std::size_t i=0; i<=nbix; i++) {
782 : 0 : tk::real I = static_cast< tk::real >( i );
783 : 0 : tk::real x = xmin + I*binsize[0];
784 : 0 : ++l;
785 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &l ), sizeof(int) );
786 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &x ), sizeof(tk::real) );
787 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &y ), sizeof(tk::real) );
788 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &z ), sizeof(tk::real) );
789 : : }
790 : : }
791 : : }
792 [ - - ]: 0 : m_outFile << "\n$EndNodes\n";
793 : :
794 : : // Output elements of discretized sample space (3D Cartesian grid)
795 [ - - ][ - - ]: 0 : m_outFile << "$Elements\n" << nbix*nbiy*nbiz << "\n";
[ - - ]
796 : 0 : int type = 5; // gmsh elem type: 8-node hexahedron
797 : 0 : std::size_t nelem = nbix*nbiy*nbiz; // num of elements in (this single) block
798 : 0 : int ntags = 2; // number of element tags
799 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &type ), sizeof(int) );
800 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &nelem ), sizeof(int) );
801 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &ntags ), sizeof(int) );
802 : 0 : const auto n = nbix*nbiy;
803 : 0 : const auto p = (nbix+1)*(nbiy+1);
804 [ - - ]: 0 : for (std::size_t i=0; i<nelem; ++i) {
805 : 0 : const auto y = i/nbix + i/n*(nbix+1);
806 : 0 : auto id = i+1;
807 : 0 : int tag[2] = { 1, 1 };
808 : 0 : int con[8] = { static_cast< int >( i+y+1 ),
809 : 0 : static_cast< int >( i+y+2 ),
810 : 0 : static_cast< int >( i+y+nbix+3 ),
811 : 0 : static_cast< int >( i+y+nbix+2 ),
812 : 0 : static_cast< int >( i+y+p+1 ),
813 : 0 : static_cast< int >( i+y+p+2 ),
814 : 0 : static_cast< int >( i+y+p+nbix+3 ),
815 : 0 : static_cast< int >( i+y+p+nbix+2 ) };
816 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
817 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( tag ), 2*sizeof(int) );
818 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( con ), 8*sizeof(int) );
819 : : }
820 [ - - ]: 0 : m_outFile << "\n$EndElements\n";
821 : :
822 : : // Output PDF function values in element or node centers
823 [ - - ]: 0 : std::string c( "Element" );
824 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) {
825 : 0 : ++nbix; ++nbiy; ++nbiz;
826 [ - - ]: 0 : c = "Node";
827 : : }
828 [ - - ][ - - ]: 0 : m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
[ - - ][ - - ]
[ - - ]
829 [ - - ][ - - ]: 0 : << nbix*nbiy*nbiz << "\n";
830 : :
831 : : // If no user-specified sample space extents, output pdf map directly
832 [ - - ]: 0 : if (uext.empty()) {
833 : :
834 [ - - ]: 0 : std::vector< int > out( nbix*nbiy*nbiz, 0 ); // indicate bins filled
835 [ - - ]: 0 : for (const auto& q : pdf.map()) {
836 : 0 : const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
837 : 0 : (q.first[1] - ext[2]) * static_cast<long>(nbix) +
838 : 0 : (q.first[0] - ext[0]) % static_cast<long>(nbix);
839 [ - - ][ - - ]: 0 : Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshBin()." );
[ - - ][ - - ]
840 [ - - ][ - - ]: 0 : Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
[ - - ][ - - ]
841 : : "Bin overflow in PDFWriter::writeGmshBin()." );
842 : 0 : out[ static_cast<std::size_t>(bin) ] = 1;
843 : 0 : auto id = static_cast<int>(bin+1);
844 : 0 : tk::real prob = q.second / binsize[0] / binsize[1] / binsize[2]
845 : 0 : / static_cast<tk::real>(pdf.nsample());
846 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
847 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
848 : : }
849 : : // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
850 : : // bins if holes exist in the data, it also looks better as zero than holes)
851 : 0 : tk::real prob = 0.0;
852 [ - - ]: 0 : for (std::size_t i=0; i<out.size(); ++i)
853 [ - - ]: 0 : if (out[i] == 0) {
854 : 0 : auto id = static_cast<int>(i+1);
855 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
856 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
857 : : }
858 : :
859 : : } else { // If user-specified sample space extents, output outpdf array
860 : :
861 : 0 : int bin = 0;
862 [ - - ]: 0 : for (auto& q : outpdf) {
863 : 0 : ++bin;
864 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &bin ), sizeof(int) );
865 [ - - ]: 0 : m_outFile.write( reinterpret_cast< char* >( &q ), sizeof(tk::real) );
866 : : }
867 : :
868 : : }
869 : :
870 [ - - ][ - - ]: 0 : m_outFile << "$End" << c << "Data\n";
[ - - ]
871 : :
872 [ - - ][ - - ]: 0 : ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
[ - - ][ - - ]
[ - - ]
873 : 0 : }
874 : :
875 : : void
876 : 0 : PDFWriter::writeExodusII( const BiPDF& pdf,
877 : : const tk::ctr::PDFInfo& info,
878 : : ctr::PDFCenteringType centering ) const
879 : : // *****************************************************************************
880 : : // Write out standardized bivariate PDF to Exodus II format
881 : : //! \param[in] pdf Bivariate PDF
882 : : //! \param[in] info PDF metadata
883 : : //! \param[in] centering Bin centering on sample space mesh
884 : : // *****************************************************************************
885 : : {
886 : 0 : const auto& name = info.name;
887 : 0 : const auto& uext = info.exts;
888 : 0 : const auto& vars = info.vars;
889 : :
890 [ - - ]: 0 : assertSampleSpaceDimensions< 2 >( vars );
891 [ - - ]: 0 : assertSampleSpaceExtents< 2 >( uext );
892 : :
893 : : // Query and optionally override number of bins and minima of sample space if
894 : : // user-specified extents were given and copy probabilities from pdf to a
895 : : // logically 2D array for output
896 : : std::size_t nbix, nbiy;
897 : : tk::real xmin, xmax, ymin, ymax;
898 : 0 : std::vector< tk::real > outpdf;
899 : : std::array< tk::real, 2 > binsize;
900 : : std::array< long, 2*BiPDF::dim > ext;
901 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
902 : : centering );
903 : :
904 : : // Create ExodusII file
905 [ - - ]: 0 : int outFile = createExFile();
906 : :
907 : : // Compute number of nodes and number of elements in sample space mesh
908 : 0 : std::size_t nelem = nbix*nbiy;
909 : 0 : std::size_t nnode = (nbix+1)*(nbiy+1);
910 : :
911 : : // Write ExodusII header
912 [ - - ]: 0 : writeExHdr( outFile, static_cast<int>(nnode), static_cast<int>(nelem) );
913 : :
914 : : // Write sample space variables as coordinate names
915 : 0 : char* coordnames[] = { const_cast< char* >( vars[0].c_str() ),
916 : 0 : const_cast< char* >( vars[1].c_str() ),
917 : 0 : const_cast< char* >( "probability" ) };
918 [ - - ][ - - ]: 0 : ErrChk( ex_put_coord_names( outFile, coordnames ) == 0,
[ - - ][ - - ]
[ - - ]
919 : : "Failed to write coordinate names to file: " + m_filename );
920 : :
921 : : // Output grid points of discretized sample space (2D Cartesian grid)
922 [ - - ]: 0 : std::vector< tk::real > x( nnode, 0.0 );
923 [ - - ]: 0 : std::vector< tk::real > y( nnode, 0.0 );
924 [ - - ]: 0 : std::vector< tk::real > z( nnode, 0.0 );
925 : 0 : std::size_t k = 0;
926 [ - - ]: 0 : for (std::size_t i=0; i<=nbiy; i++)
927 [ - - ]: 0 : for (std::size_t j=0; j<=nbix; j++) {
928 : 0 : x[k] = xmin + static_cast< tk::real >( j )*binsize[0];
929 : 0 : y[k] = ymin + static_cast< tk::real >( i )*binsize[1];
930 : 0 : ++k;
931 : : }
932 [ - - ][ - - ]: 0 : ErrChk( ex_put_coord( outFile, x.data(), y.data(), z.data() ) == 0,
[ - - ][ - - ]
[ - - ]
933 : : "Failed to write coordinates to file: " + m_filename );
934 : :
935 : : // Output elements of discretized sample space (2D Cartesian grid)
936 : : // Write element block information
937 [ - - ][ - - ]: 0 : ErrChk( ex_put_block( outFile,
[ - - ][ - - ]
[ - - ]
938 : : EX_ELEM_BLOCK,
939 : : 1,
940 : : "QUADRANGLES",
941 : : static_cast<int64_t>(nelem),
942 : : 4,
943 : : 0,
944 : : 0,
945 : : 0 ) == 0,
946 : : "Failed to write QUDARANGLE element block to file: " + m_filename );
947 : : // Write element connectivity
948 [ - - ]: 0 : for (std::size_t i=0; i<nelem; ++i) {
949 : 0 : auto ye = i/nbix;
950 : 0 : int con[4] = { static_cast< int >( i+ye+1 ),
951 : 0 : static_cast< int >( i+ye+2 ),
952 : 0 : static_cast< int >( i+ye+nbix+3 ),
953 : 0 : static_cast< int >( i+ye+nbix+2 ) };
954 [ - - ][ - - ]: 0 : ErrChk( ex_put_partial_conn( outFile, EX_ELEM_BLOCK, 1,
[ - - ][ - - ]
[ - - ]
955 : : static_cast<int64_t>(i+1), 1, con, nullptr, nullptr ) == 0,
956 : : "Failed to write element connectivity to file: " + m_filename );
957 : : }
958 : :
959 : : // Output PDF function values in element or node centers
960 : 0 : ex_entity_type c = EX_ELEM_BLOCK;
961 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) {
962 : 0 : ++nbix; ++nbiy;
963 : 0 : c = EX_NODE_BLOCK;
964 : : }
965 : :
966 : : // Write PDF function values metadata
967 [ - - ][ - - ]: 0 : ErrChk( ex_put_variable_param( outFile, c, 1 ) == 0,
[ - - ][ - - ]
[ - - ]
968 : : "Failed to write results metadata to file: " + m_filename );
969 : : char* probname[1];
970 [ - - ][ - - ]: 0 : std::string pdfname( name + '(' + vars[0] + ',' + vars[1] + ')' );
[ - - ][ - - ]
[ - - ]
971 : 0 : probname[0] = const_cast< char* >( pdfname.c_str() );
972 [ - - ][ - - ]: 0 : ErrChk( ex_put_variable_names( outFile, c, 1, probname ) == 0,
[ - - ][ - - ]
[ - - ]
973 : : "Failed to write results metadata to file: " + m_filename );
974 : :
975 : : // If no user-specified sample space extents, output pdf map directly
976 [ - - ]: 0 : if (uext.empty()) {
977 : :
978 : : // Output PDF function values in element centers
979 [ - - ]: 0 : std::vector< tk::real > prob( nbix*nbiy, 0.0 );
980 [ - - ]: 0 : for (const auto& p : pdf.map()) {
981 : 0 : const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
982 : 0 : (p.first[0] - ext[0]) % static_cast<long>(nbix);
983 [ - - ][ - - ]: 0 : Assert( bin >= 0, "Bin underflow in PDFWriter::writeExodusII()." );
[ - - ][ - - ]
984 [ - - ][ - - ]: 0 : Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
[ - - ][ - - ]
985 : : "Bin overflow in PDFWriter::writeExodusII()." );
986 : 0 : prob[ static_cast<std::size_t>(bin) ] =
987 : 0 : p.second / binsize[0] / binsize[1]
988 : 0 : / static_cast<tk::real>(pdf.nsample());
989 : : }
990 [ - - ]: 0 : writeExVar( outFile, centering, prob );
991 : :
992 : : } else { // If user-specified sample space extents, output outpdf array
993 : :
994 [ - - ]: 0 : writeExVar( outFile, centering, outpdf );
995 : :
996 : : }
997 : :
998 [ - - ][ - - ]: 0 : ErrChk( ex_close(outFile) == 0, "Failed to close file: " + m_filename );
[ - - ][ - - ]
[ - - ]
999 : 0 : }
1000 : :
1001 : : void
1002 : 0 : PDFWriter::writeExodusII( const TriPDF& pdf,
1003 : : const tk::ctr::PDFInfo& info,
1004 : : ctr::PDFCenteringType centering ) const
1005 : : // *****************************************************************************
1006 : : // Write out standardized trivariate PDF to Exodus II format
1007 : : //! \param[in] pdf Trivariate PDF
1008 : : //! \param[in] info PDF metadata
1009 : : //! \param[in] centering Bin centering on sample space mesh
1010 : : // *****************************************************************************
1011 : : {
1012 : 0 : const auto& name = info.name;
1013 : 0 : const auto& uext = info.exts;
1014 : 0 : const auto& vars = info.vars;
1015 : :
1016 [ - - ]: 0 : assertSampleSpaceDimensions< 3 >( vars );
1017 [ - - ]: 0 : assertSampleSpaceExtents< 3 >( uext );
1018 : :
1019 : : // Query and optionally override number of bins and minima of sample space if
1020 : : // user-specified extents were given and copy probabilities from pdf to a
1021 : : // logically 3D array for output
1022 : : std::size_t nbix, nbiy, nbiz;
1023 : : tk::real xmin, xmax, ymin, ymax, zmin, zmax;
1024 : 0 : std::vector< tk::real > outpdf;
1025 : : std::array< tk::real, 3 > binsize;
1026 : : std::array< long, 2*TriPDF::dim > ext;
1027 [ - - ]: 0 : extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
1028 : : binsize, ext, outpdf, centering );
1029 : :
1030 : : // Create ExodusII file
1031 [ - - ]: 0 : int outFile = createExFile();
1032 : :
1033 : : // Compute number of nodes and number of elements in sample space mesh
1034 : 0 : std::size_t nelem = nbix*nbiy*nbiz;
1035 : 0 : std::size_t nnode = (nbix+1)*(nbiy+1)*(nbiz+1);
1036 : :
1037 : : // Write ExodusII header
1038 [ - - ]: 0 : writeExHdr( outFile, static_cast<int>(nnode), static_cast<int>(nelem) );
1039 : :
1040 : : // Write sample space variables as coordinate names
1041 : 0 : char* coordnames[] = { const_cast< char* >( vars[0].c_str() ),
1042 : 0 : const_cast< char* >( vars[1].c_str() ),
1043 : 0 : const_cast< char* >( vars[2].c_str() ) };
1044 [ - - ][ - - ]: 0 : ErrChk( ex_put_coord_names( outFile, coordnames ) == 0,
[ - - ][ - - ]
[ - - ]
1045 : : "Failed to write coordinate names to file: " + m_filename );
1046 : :
1047 : : // Output grid points of discretized sample space (2D Cartesian grid)
1048 [ - - ]: 0 : std::vector< tk::real > x( nnode, 0.0 );
1049 [ - - ]: 0 : std::vector< tk::real > y( nnode, 0.0 );
1050 [ - - ]: 0 : std::vector< tk::real > z( nnode, 0.0 );
1051 : 0 : std::size_t l=0;
1052 [ - - ]: 0 : for (std::size_t k=0; k<=nbiz; k++)
1053 [ - - ]: 0 : for (std::size_t i=0; i<=nbiy; i++)
1054 [ - - ]: 0 : for (std::size_t j=0; j<=nbix; j++) {
1055 : 0 : x[l] = xmin + static_cast<tk::real>(j) * binsize[0];
1056 : 0 : y[l] = ymin + static_cast<tk::real>(i) * binsize[1];
1057 : 0 : z[l] = zmin + static_cast<tk::real>(k) * binsize[2];
1058 : 0 : ++l;
1059 : : }
1060 [ - - ][ - - ]: 0 : ErrChk( ex_put_coord( outFile, x.data(), y.data(), z.data() ) == 0,
[ - - ][ - - ]
[ - - ]
1061 : : "Failed to write coordinates to file: " + m_filename );
1062 : :
1063 : : // Output elements of discretized sample space (2D Cartesian grid)
1064 : : // Write element block information
1065 [ - - ][ - - ]: 0 : ErrChk( ex_put_block( outFile,
[ - - ][ - - ]
[ - - ]
1066 : : EX_ELEM_BLOCK,
1067 : : 1,
1068 : : "HEXAHEDRA",
1069 : : static_cast<int64_t>(nelem),
1070 : : 8,
1071 : : 0,
1072 : : 0,
1073 : : 0 ) == 0,
1074 : : "Failed to write HEXAHEDRA element block to file: " + m_filename );
1075 : : // Write element connectivity
1076 : 0 : const auto n = nbix*nbiy;
1077 : 0 : const auto p = (nbix+1)*(nbiy+1);
1078 [ - - ]: 0 : for (std::size_t i=0; i<nelem; ++i) {
1079 : 0 : const auto ye = i/nbix + i/n*(nbix+1);
1080 : 0 : int con[8] = { static_cast< int >( i+ye+1 ),
1081 : 0 : static_cast< int >( i+ye+2 ),
1082 : 0 : static_cast< int >( i+ye+nbix+3 ),
1083 : 0 : static_cast< int >( i+ye+nbix+2 ),
1084 : 0 : static_cast< int >( i+ye+p+1 ),
1085 : 0 : static_cast< int >( i+ye+p+2 ),
1086 : 0 : static_cast< int >( i+ye+p+nbix+3 ),
1087 : 0 : static_cast< int >( i+ye+p+nbix+2 ) };
1088 [ - - ][ - - ]: 0 : ErrChk(
[ - - ][ - - ]
[ - - ]
1089 : : ex_put_partial_conn( outFile, EX_ELEM_BLOCK, 1,
1090 : : static_cast<int64_t>(i+1), 1, con, nullptr, nullptr ) == 0,
1091 : : "Failed to write element connectivity to file: " + m_filename );
1092 : : }
1093 : :
1094 : : // Output PDF function values in element or node centers
1095 : 0 : ex_entity_type c = EX_ELEM_BLOCK;
1096 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) {
1097 : 0 : ++nbix; ++nbiy; ++nbiz;
1098 : 0 : c = EX_NODE_BLOCK;
1099 : : }
1100 : :
1101 : : // Write PDF function values metadata
1102 [ - - ][ - - ]: 0 : ErrChk( ex_put_variable_param( outFile, c, 1 ) == 0,
[ - - ][ - - ]
[ - - ]
1103 : : "Failed to write results metadata to file: " + m_filename );
1104 : : char* probname[1];
1105 [ - - ][ - - ]: 0 : std::string pdfname( name + '(' + vars[0] + ',' +
[ - - ][ - - ]
1106 [ - - ][ - - ]: 0 : vars[1] + ',' + vars[2] + ')' );
[ - - ]
1107 : 0 : probname[0] = const_cast< char* >( pdfname.c_str() );
1108 [ - - ][ - - ]: 0 : ErrChk( ex_put_variable_names( outFile, c, 1, probname ) == 0,
[ - - ][ - - ]
[ - - ]
1109 : : "Failed to write results metadata to file: " + m_filename );
1110 : :
1111 : : // If no user-specified sample space extents, output pdf map directly
1112 [ - - ]: 0 : if (uext.empty()) {
1113 : :
1114 : : // Output PDF function values in element centers
1115 [ - - ]: 0 : std::vector< tk::real > prob( nbix*nbiy*nbiz, 0.0 );
1116 [ - - ]: 0 : for (const auto& q : pdf.map()) {
1117 : 0 : const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
1118 : 0 : (q.first[1] - ext[2]) * static_cast<long>(nbix) +
1119 : 0 : (q.first[0] - ext[0]) % static_cast<long>(nbix);
1120 [ - - ][ - - ]: 0 : Assert( bin >= 0, "Bin underflow in PDFWriter::writeExodusII()." );
[ - - ][ - - ]
1121 [ - - ][ - - ]: 0 : Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
[ - - ][ - - ]
1122 : : "Bin overflow in PDFWriter::writeExodusII()." );
1123 : 0 : prob[ static_cast<std::size_t>(bin) ] =
1124 : 0 : q.second / binsize[0] / binsize[1] / binsize[2]
1125 : 0 : / static_cast<tk::real>(pdf.nsample());
1126 : : }
1127 [ - - ]: 0 : writeExVar( outFile, centering, prob );
1128 : :
1129 : : } else { // If user-specified sample space extents, output outpdf array
1130 : :
1131 [ - - ]: 0 : writeExVar( outFile, centering, outpdf );
1132 : :
1133 : : }
1134 : :
1135 [ - - ][ - - ]: 0 : ErrChk( ex_close(outFile) == 0, "Failed to close file: " + m_filename );
[ - - ][ - - ]
[ - - ]
1136 : 0 : }
1137 : :
1138 : : int
1139 : 0 : PDFWriter::createExFile() const
1140 : : // *****************************************************************************
1141 : : // Create Exodus II file
1142 : : //! \return ExodusII file handle
1143 : : // *****************************************************************************
1144 : : {
1145 : 0 : int cpuwordsize = sizeof( double );
1146 : 0 : int iowordsize = sizeof( double );
1147 [ - - ]: 0 : int outFileId = ex_create( m_filename.c_str(),
1148 : : EX_CLOBBER | EX_NORMAL_MODEL,
1149 : : &cpuwordsize,
1150 : : &iowordsize );
1151 [ - - ][ - - ]: 0 : ErrChk( outFileId > 0, "Failed to create file: " + m_filename );
[ - - ][ - - ]
1152 : 0 : return outFileId;
1153 : : }
1154 : :
1155 : : void
1156 : 0 : PDFWriter::writeExHdr( int outFileId, int nnode, int nelem ) const
1157 : : // *****************************************************************************
1158 : : // Write Exodus II file header
1159 : : //! \param[in] outFileId Output file ExodusII Id
1160 : : //! \param[in] nnode Number of nodes in mesh to write
1161 : : //! \param[in] nelem Number of elements in mesh to write
1162 : : // *****************************************************************************
1163 : : {
1164 [ - - ][ - - ]: 0 : ErrChk( ex_put_init( outFileId,
[ - - ][ - - ]
1165 : : "Written by Quinoa",
1166 : : 3, // number of dimensions
1167 : : nnode, // number of nodes
1168 : : nelem, // number of elements
1169 : : 1, // number of element blocks
1170 : : 0, // number of node sets
1171 : : 0 ) == 0, // number of side sets
1172 : : "Failed to write header to file: " + m_filename );
1173 : 0 : }
1174 : :
1175 : : void
1176 : 0 : PDFWriter::writeExVar( int exoFile,
1177 : : ctr::PDFCenteringType centering,
1178 : : const std::vector< tk::real >& probability ) const
1179 : : // *****************************************************************************
1180 : : // Output probability density function as Exodus II results field
1181 : : //! \param[in] exoFile ExodusII file handle to write to
1182 : : //! \param[in] centering Node-, or element-centering to use on sample space mesh
1183 : : //! \param[in] probability Probabilities at each sample space location
1184 : : // *****************************************************************************
1185 : : {
1186 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE)
1187 [ - - ][ - - ]: 0 : ErrChk( ex_put_var( exoFile,
[ - - ][ - - ]
1188 : : 1,
1189 : : EX_NODE_BLOCK,
1190 : : 1,
1191 : : 1,
1192 : : static_cast<int64_t>(probability.size()),
1193 : : probability.data() ) == 0,
1194 : : "Failed to write node-centered bivariate PDF to file: " +
1195 : : m_filename );
1196 : : else
1197 [ - - ][ - - ]: 0 : ErrChk( ex_put_var( exoFile,
[ - - ][ - - ]
1198 : : 1,
1199 : : EX_ELEM_BLOCK,
1200 : : 1,
1201 : : 1,
1202 : : static_cast<int64_t>(probability.size()),
1203 : : probability.data() ) == 0,
1204 : : "Failed to write elem-centered bivariate PDF to file: " +
1205 : : m_filename );
1206 : 0 : }
1207 : :
1208 : : void
1209 : 567 : PDFWriter::extents( const UniPDF& pdf,
1210 : : const std::vector< tk::real >& uext,
1211 : : std::size_t& nbi,
1212 : : tk::real& min,
1213 : : tk::real& max,
1214 : : tk::real& binsize,
1215 : : std::array< long, 2*UniPDF::dim >& ext,
1216 : : std::vector< tk::real >& outpdf ) const
1217 : : // *****************************************************************************
1218 : : // Query extents and other metadata of univariate PDF sample space
1219 : : //! \details Query and optionally override number of bins and minimum of sample
1220 : : //! space if user-specified extents were given and copy probabilities from
1221 : : //! pdf to an array for output for plotting univariate PDF.
1222 : : //! \param[in] pdf Univariate PDF object
1223 : : //! \param[in] uext User-specified extents of sample space
1224 : : //! \param[inout] nbi Number of bins
1225 : : //! \param[inout] min Minimum value of sample space
1226 : : //! \param[inout] max Maximum value of sample space
1227 : : //! \param[inout] binsize Bin size
1228 : : //! \param[inout] ext Extents of sample space
1229 : : //! \param[inout] outpdf PDF ready to be written out to file
1230 : : // *****************************************************************************
1231 : : {
1232 : 567 : assertSampleSpaceExtents< 1 >( uext );
1233 : :
1234 : : // Query bin size and extents of sample space from PDF
1235 : 567 : binsize = pdf.binsize();
1236 : 567 : ext = pdf.extents();
1237 : :
1238 : : // Compute number of bins of sample space (min bins: 1)
1239 [ - + ][ - - ]: 567 : Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
[ - - ][ - - ]
1240 : 567 : nbi = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
1241 : :
1242 : : // Compute minimum and maximum of sample space
1243 : 567 : min = binsize * static_cast< tk::real >( ext[0] );
1244 : 567 : max = binsize * static_cast< tk::real >( ext[1] );
1245 : :
1246 : : // Override number of bins and minimum if user-specified extents were given,
1247 : : // and copy probabilities from pdf to an array for output
1248 [ - + ]: 567 : if (!uext.empty()) {
1249 : : // Override number of bins by that based on user-specified extents
1250 [ - - ][ - - ]: 0 : Assert( uext[1] >= uext[0],
[ - - ][ - - ]
1251 : : "Wrong user-defined extents in PDFWriter::extents" );
1252 : 0 : nbi = static_cast< std::size_t >(
1253 : 0 : std::lround( (uext[1] - uext[0]) / binsize ) );
1254 : : // Override extents
1255 : 0 : min = uext[0];
1256 : 0 : max = uext[1];
1257 : :
1258 : : // Size output pdf to user-requested dimensions to overridden nbi and
1259 : : // initialize output probabilities to zero
1260 [ - - ]: 0 : outpdf = std::vector< tk::real >( nbi, 0.0 );
1261 : :
1262 : : // Fill requested region of pdf to be output from computed pdf
1263 [ - - ]: 0 : for (const auto& p : pdf.map()) {
1264 : : // Compute (i.e., shift) bin indices relative to user-requested extents
1265 : 0 : const auto bin = p.first - std::lround( uext[0] / binsize );
1266 : : // Only copy probability value if shifted bin indices fall within
1267 : : // user-requested extents (lower inclusive, upper exclusive)
1268 [ - - ][ - - ]: 0 : if (bin >= 0 && bin < std::lround( (uext[1] - uext[0]) / binsize )) {
[ - - ]
1269 [ - - ][ - - ]: 0 : Assert( static_cast<std::size_t>(bin) < nbi,
[ - - ][ - - ]
1270 : : "Bin overflow in user-specified-extent-based bin "
1271 : : "calculation of univariate PDF extents." );
1272 : : // Copy normalized probability to output pdf
1273 : 0 : outpdf[ static_cast<std::size_t>(bin) ] =
1274 : 0 : p.second / binsize / static_cast<tk::real>(pdf.nsample());
1275 : : }
1276 : : }
1277 : : }
1278 : 567 : }
1279 : :
1280 : : void
1281 : 0 : PDFWriter::extents( const BiPDF& pdf,
1282 : : const std::vector< tk::real >& uext,
1283 : : std::size_t& nbix,
1284 : : std::size_t& nbiy,
1285 : : tk::real& xmin,
1286 : : tk::real& xmax,
1287 : : tk::real& ymin,
1288 : : tk::real& ymax,
1289 : : std::array< tk::real, BiPDF::dim >& binsize,
1290 : : std::array< long, 2*BiPDF::dim >& ext,
1291 : : std::vector< tk::real >& outpdf,
1292 : : ctr::PDFCenteringType centering ) const
1293 : : // *****************************************************************************
1294 : : // Query extents and other metadata of bivariate PDF sample space
1295 : : //! \details Query and optionally override number of bins and minima of sample
1296 : : //! space if user-specified extents were given and copy probabilities from
1297 : : //! pdf to a logically 2D array for output for plotting bivariate joint PDF.
1298 : : //! \param[in] pdf Bivariate PDF object
1299 : : //! \param[in] uext User-specified extents of sample space
1300 : : //! \param[inout] nbix Number of bins in x dimension
1301 : : //! \param[inout] nbiy Number of bins in y dimension
1302 : : //! \param[inout] xmin Minimum x value of sample space
1303 : : //! \param[inout] xmax Maximum x value of sample space
1304 : : //! \param[inout] ymin Minimum y value of sample space
1305 : : //! \param[inout] ymax Maximum y value of sample space
1306 : : //! \param[inout] binsize Bin size
1307 : : //! \param[inout] ext Extents of sample space
1308 : : //! \param[inout] outpdf PDF ready to be written out to file
1309 : : //! \param[in] centering Bin centering on sample space mesh
1310 : : // *****************************************************************************
1311 : : {
1312 : 0 : assertSampleSpaceExtents< 2 >( uext );
1313 : :
1314 : : // Query bin sizes and extents of sample space from PDF
1315 : 0 : binsize = pdf.binsize();
1316 : 0 : ext = pdf.extents();
1317 : :
1318 : : // Compute number of bins in sample space directions (min bins: 1)
1319 [ - - ][ - - ]: 0 : Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
[ - - ][ - - ]
1320 [ - - ][ - - ]: 0 : Assert( ext[3] >= ext[2], "Wrong extents in PDFWriter::extents" );
[ - - ][ - - ]
1321 : 0 : nbix = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
1322 : 0 : nbiy = static_cast< std::size_t >( ext[3] - ext[2] + 1 );
1323 : :
1324 : : // Compute minima and maxima of sample space
1325 : 0 : xmin = binsize[0] * static_cast< tk::real >( ext[0] );
1326 : 0 : xmax = binsize[0] * static_cast< tk::real >( ext[1] );
1327 : 0 : ymin = binsize[1] * static_cast< tk::real >( ext[2] );
1328 : 0 : ymax = binsize[1] * static_cast< tk::real >( ext[3] );
1329 : :
1330 : : // Override number of bins and minima if user-specified extents were given,
1331 : : // and copy probabilities from pdf to a logically 2D array for output
1332 [ - - ]: 0 : if (!uext.empty()) {
1333 : : // Override number of bins by that based on user-specified extents
1334 [ - - ][ - - ]: 0 : Assert( uext[1] >= uext[0],
[ - - ][ - - ]
1335 : : "Wrong user-defined extents in PDFWriter::extents" );
1336 [ - - ][ - - ]: 0 : Assert( uext[3] >= uext[2],
[ - - ][ - - ]
1337 : : "Wrong user-defined extents in PDFWriter::extents" );
1338 : 0 : nbix = static_cast< std::size_t >(
1339 : 0 : std::lround( (uext[1] - uext[0]) / binsize[0] ) );
1340 : 0 : nbiy = static_cast< std::size_t >(
1341 : 0 : std::lround( (uext[3] - uext[2]) / binsize[1] ) );
1342 : : // Override extents
1343 : 0 : xmin = uext[0];
1344 : 0 : xmax = uext[1];
1345 : 0 : ymin = uext[2];
1346 : 0 : ymax = uext[3];
1347 : :
1348 : : // Temporarily increase number of bins if node-centered output required
1349 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) { ++nbix; ++nbiy; }
1350 : :
1351 : : // Size output pdf to user-requested dimensions to overridden nbiy * nbix
1352 : : // and initialize output probabilities to zero
1353 [ - - ]: 0 : outpdf = std::vector< tk::real >( nbix*nbiy, 0.0 );
1354 : :
1355 : : // Fill requested region of pdf to be output from computed pdf
1356 [ - - ]: 0 : for (const auto& p : pdf.map()) {
1357 : : // Compute (i.e., shift) bin indices relative to user-requested extents
1358 : 0 : const auto x = p.first[0] - std::lround( uext[0] / binsize[0] );
1359 : 0 : const auto y = p.first[1] - std::lround( uext[2] / binsize[1] );
1360 : : // Only copy probability value if shifted bin indices fall within
1361 : : // user-requested extents (lower inclusive, upper exclusive)
1362 [ - - ][ - - ]: 0 : if (x >= 0 && x < std::lround( (uext[1] - uext[0]) / binsize[0] ) &&
1363 [ - - ][ - - ]: 0 : y >= 0 && y < std::lround( (uext[3] - uext[2]) / binsize[1] ))
[ - - ]
1364 : : {
1365 : 0 : const auto bin =
1366 : 0 : static_cast<std::size_t>(y)*nbix + static_cast<std::size_t>(x);
1367 [ - - ][ - - ]: 0 : Assert( bin < nbix*nbiy, "Bin overflow in user-specified-extent-based "
[ - - ][ - - ]
1368 : : "bin calculation of bivariate PDF." );
1369 : : // Copy normalized probability to output pdf
1370 : 0 : outpdf[ bin ] = p.second / binsize[0] / binsize[1]
1371 : 0 : / static_cast<tk::real>(pdf.nsample());
1372 : : }
1373 : : }
1374 : :
1375 : : // Revert number of bins if node-centered output required
1376 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) { --nbix; --nbiy; }
1377 : : }
1378 : 0 : }
1379 : :
1380 : : void
1381 : 0 : PDFWriter::extents( const TriPDF& pdf,
1382 : : const std::vector< tk::real >& uext,
1383 : : std::size_t& nbix,
1384 : : std::size_t& nbiy,
1385 : : std::size_t& nbiz,
1386 : : tk::real& xmin,
1387 : : tk::real& xmax,
1388 : : tk::real& ymin,
1389 : : tk::real& ymax,
1390 : : tk::real& zmin,
1391 : : tk::real& zmax,
1392 : : std::array< tk::real, TriPDF::dim >& binsize,
1393 : : std::array< long, 2*TriPDF::dim >& ext,
1394 : : std::vector< tk::real >& outpdf,
1395 : : ctr::PDFCenteringType centering ) const
1396 : : // *****************************************************************************
1397 : : // Query extents and other metadata of trivariate PDF sample space
1398 : : //! \details Query and optionally override number of bins and minima of sample
1399 : : //! space if user-specified extents were given and copy probabilities from
1400 : : //! pdf to a logically 3D array for output for plotting trivariate joint PDF.
1401 : : //! \param[in] pdf Trivariate PDF object
1402 : : //! \param[in] uext User-specified extents of sample space
1403 : : //! \param[inout] nbix Number of bins in x dimension
1404 : : //! \param[inout] nbiy Number of bins in y dimension
1405 : : //! \param[inout] nbiz Number of bins in z dimension
1406 : : //! \param[inout] xmin Minimum x value of sample space
1407 : : //! \param[inout] xmax Maximum x value of sample space
1408 : : //! \param[inout] ymin Minimum y value of sample space
1409 : : //! \param[inout] ymax Maximum y value of sample space
1410 : : //! \param[inout] zmin Minimum z value of sample space
1411 : : //! \param[inout] zmax Maximum z value of sample space
1412 : : //! \param[inout] binsize Bin size
1413 : : //! \param[inout] ext Extents of sample space
1414 : : //! \param[inout] outpdf PDF ready to be written out to file
1415 : : //! \param[in] centering Bin centering on sample space mesh
1416 : : // *****************************************************************************
1417 : : {
1418 : 0 : assertSampleSpaceExtents< 3 >( uext );
1419 : :
1420 : : // Query bin sizes and extents of sample space from PDF
1421 : 0 : binsize = pdf.binsize();
1422 : 0 : ext = pdf.extents();
1423 : :
1424 : : // Compute number of bins in sample space directions (min bins: 1)
1425 [ - - ][ - - ]: 0 : Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
[ - - ][ - - ]
1426 [ - - ][ - - ]: 0 : Assert( ext[3] >= ext[2], "Wrong extents in PDFWriter::extents" );
[ - - ][ - - ]
1427 [ - - ][ - - ]: 0 : Assert( ext[5] >= ext[4], "Wrong extents in PDFWriter::extents" );
[ - - ][ - - ]
1428 : 0 : nbix = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
1429 : 0 : nbiy = static_cast< std::size_t >( ext[3] - ext[2] + 1 );
1430 : 0 : nbiz = static_cast< std::size_t >( ext[5] - ext[4] + 1 );
1431 : :
1432 : : // Compute minima and maxima of sample space
1433 : 0 : xmin = binsize[0] * static_cast< tk::real >( ext[0] );
1434 : 0 : xmax = binsize[0] * static_cast< tk::real >( ext[1] );
1435 : 0 : ymin = binsize[1] * static_cast< tk::real >( ext[2] );
1436 : 0 : ymax = binsize[1] * static_cast< tk::real >( ext[3] );
1437 : 0 : zmin = binsize[2] * static_cast< tk::real >( ext[4] );
1438 : 0 : zmax = binsize[2] * static_cast< tk::real >( ext[5] );
1439 : :
1440 : : // Override number of bins and minima if user-specified extents were given,
1441 : : // and copy probabilities from pdf to a logically 3D array for output
1442 [ - - ]: 0 : if (!uext.empty()) {
1443 : : // Override number of bins by that based on user-specified extents
1444 [ - - ][ - - ]: 0 : Assert( uext[1] >= uext[0],
[ - - ][ - - ]
1445 : : "Wrong user-defined extents in PDFWriter::extents" );
1446 [ - - ][ - - ]: 0 : Assert( uext[3] >= uext[2],
[ - - ][ - - ]
1447 : : "Wrong user-defined extents in PDFWriter::extents" );
1448 [ - - ][ - - ]: 0 : Assert( uext[5] >= uext[4],
[ - - ][ - - ]
1449 : : "Wrong user-defined extents in PDFWriter::extents" );
1450 : 0 : nbix = static_cast< std::size_t >(
1451 : 0 : std::lround( (uext[1] - uext[0]) / binsize[0] ) );
1452 : 0 : nbiy = static_cast< std::size_t >(
1453 : 0 : std::lround( (uext[3] - uext[2]) / binsize[1] ) );
1454 : 0 : nbiz = static_cast< std::size_t >(
1455 : 0 : std::lround( (uext[5] - uext[4]) / binsize[2] ) );
1456 : : // Override extents
1457 : 0 : xmin = uext[0];
1458 : 0 : xmax = uext[1];
1459 : 0 : ymin = uext[2];
1460 : 0 : ymax = uext[3];
1461 : 0 : zmin = uext[4];
1462 : 0 : zmax = uext[5];
1463 : :
1464 : : // Temporarily increase number of bins if node-centered output required
1465 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) { ++nbix; ++nbiy; ++nbiz; }
1466 : :
1467 : : // Size output pdf to user-requested dimensions to overridden nbiz * nbiy *
1468 : : // nbix and initialize output probabilities to zero
1469 [ - - ]: 0 : outpdf = std::vector< tk::real >( nbiz * nbiy * nbix, 0.0 );
1470 : :
1471 : : // Fill requested region of pdf to be output from computed pdf
1472 [ - - ]: 0 : for (const auto& p : pdf.map()) {
1473 : : // Compute (i.e., shift) bin indices relative to user-requested extents
1474 : 0 : const auto x = p.first[0] - std::lround( uext[0] / binsize[0] );
1475 : 0 : const auto y = p.first[1] - std::lround( uext[2] / binsize[1] );
1476 : 0 : const auto z = p.first[2] - std::lround( uext[4] / binsize[2] );
1477 : : // Only copy probability value if shifted bin indices fall within
1478 : : // user-requested extents (lower inclusive, upper exclusive)
1479 [ - - ][ - - ]: 0 : if (x >= 0 && x < std::lround( (uext[1] - uext[0]) / binsize[0] ) &&
1480 [ - - ][ - - ]: 0 : y >= 0 && y < std::lround( (uext[3] - uext[2]) / binsize[1] ) &&
1481 [ - - ][ - - ]: 0 : z >= 0 && z < std::lround( (uext[5] - uext[4]) / binsize[2] ))
[ - - ]
1482 : : {
1483 : 0 : const auto X = static_cast< std::size_t >( x );
1484 : 0 : const auto Y = static_cast< std::size_t >( y );
1485 : 0 : const auto Z = static_cast< std::size_t >( z );
1486 : 0 : const auto bin = nbix*(Z*nbiy + Y) + X;
1487 [ - - ][ - - ]: 0 : Assert( bin < nbix*nbiy*nbiz, "Bin overflow in "
[ - - ][ - - ]
1488 : : "user-specified-extent-based bin calculation of bivariate PDF." );
1489 : : // Copy normalized probability to output pdf
1490 : 0 : outpdf[ bin ] =
1491 : 0 : p.second / binsize[0] / binsize[1] / binsize[2]
1492 : 0 : / static_cast<tk::real>(pdf.nsample());
1493 : : }
1494 : : }
1495 : :
1496 : : // Revert number of bins if node-centered output required
1497 [ - - ]: 0 : if (centering == ctr::PDFCenteringType::NODE) { --nbix; --nbiy; --nbiz; }
1498 : : }
1499 : 0 : }
|