From: Peter Munch Date: Sun, 18 Sep 2022 20:20:37 +0000 (+0200) Subject: Add DataOutBase::CompressionLevel::plain_text X-Git-Tag: v9.5.0-rc1~949^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F14284%2Fhead;p=dealii.git Add DataOutBase::CompressionLevel::plain_text --- diff --git a/include/deal.II/base/data_out_base.h b/include/deal.II/base/data_out_base.h index 1eee188989..1b3a1ae174 100644 --- a/include/deal.II/base/data_out_base.h +++ b/include/deal.II/base/data_out_base.h @@ -222,7 +222,10 @@ namespace DataOutBase { /** * An enum for different levels of compression used in several places - * to determine zlib compression levels. + * to determine zlib compression levels for binary output. At some + * places, it is possible to output the data also as plain text as + * an alternative, which is convenient for debugging. We use + * this flag to indicate such an output as well. */ enum class CompressionLevel { @@ -243,7 +246,11 @@ namespace DataOutBase * Use the default compression algorithm. This is a compromise between * speed and file size. */ - default_compression + default_compression, + /** + * Output as plain text (ASCII) if available. + */ + plain_text }; diff --git a/source/base/data_out_base.cc b/source/base/data_out_base.cc index 0ebfb4e285..60e90d8e47 100644 --- a/source/base/data_out_base.cc +++ b/source/base/data_out_base.cc @@ -1921,20 +1921,25 @@ namespace void VtuStream::write_point(const unsigned int, const Point &p) { -#if !defined(DEAL_II_WITH_ZLIB) - // write out coordinates - stream << p; - // fill with zeroes - for (unsigned int i = dim; i < 3; ++i) - stream << " 0"; - stream << '\n'; -#else - // if we want to compress, then first collect all the data in an array - for (unsigned int i = 0; i < dim; ++i) - vertices.push_back(p[i]); - for (unsigned int i = dim; i < 3; ++i) - vertices.push_back(0); +#ifdef DEAL_II_WITH_ZLIB + if (flags.compression_level != DataOutBase::CompressionLevel::plain_text) + { + // if we want to compress, then first collect all the data in an array + for (unsigned int i = 0; i < dim; ++i) + vertices.push_back(p[i]); + for (unsigned int i = dim; i < 3; ++i) + vertices.push_back(0); + } + else #endif + { + // write out coordinates + stream << p; + // fill with zeroes + for (unsigned int i = dim; i < 3; ++i) + stream << " 0"; + stream << '\n'; + } } @@ -1942,10 +1947,13 @@ namespace VtuStream::flush_points() { #ifdef DEAL_II_WITH_ZLIB - // compress the data we have in memory and write them to the stream. then - // release the data - *this << vertices << '\n'; - vertices.clear(); + if (flags.compression_level != DataOutBase::CompressionLevel::plain_text) + { + // compress the data we have in memory and write them to the stream. + // then release the data + *this << vertices << '\n'; + vertices.clear(); + } #endif } @@ -1958,41 +1966,47 @@ namespace unsigned int d2, unsigned int d3) { -#if !defined(DEAL_II_WITH_ZLIB) - stream << start; - if (dim >= 1) +#ifdef DEAL_II_WITH_ZLIB + if (flags.compression_level != DataOutBase::CompressionLevel::plain_text) { - stream << '\t' << start + d1; - if (dim >= 2) + cells.push_back(start); + if (dim >= 1) { - stream << '\t' << start + d2 + d1 << '\t' << start + d2; - if (dim >= 3) + cells.push_back(start + d1); + if (dim >= 2) { - stream << '\t' << start + d3 << '\t' << start + d3 + d1 << '\t' - << start + d3 + d2 + d1 << '\t' << start + d3 + d2; + cells.push_back(start + d2 + d1); + cells.push_back(start + d2); + if (dim >= 3) + { + cells.push_back(start + d3); + cells.push_back(start + d3 + d1); + cells.push_back(start + d3 + d2 + d1); + cells.push_back(start + d3 + d2); + } } } } - stream << '\n'; -#else - cells.push_back(start); - if (dim >= 1) + else +#endif { - cells.push_back(start + d1); - if (dim >= 2) + stream << start; + if (dim >= 1) { - cells.push_back(start + d2 + d1); - cells.push_back(start + d2); - if (dim >= 3) + stream << '\t' << start + d1; + if (dim >= 2) { - cells.push_back(start + d3); - cells.push_back(start + d3 + d1); - cells.push_back(start + d3 + d2 + d1); - cells.push_back(start + d3 + d2); + stream << '\t' << start + d2 + d1 << '\t' << start + d2; + if (dim >= 3) + { + stream << '\t' << start + d3 << '\t' << start + d3 + d1 + << '\t' << start + d3 + d2 + d1 << '\t' + << start + d3 + d2; + } } } + stream << '\n'; } -#endif } void @@ -2005,17 +2019,23 @@ namespace static const std::array table = {{0, 1, 3, 2, 4}}; -#if !defined(DEAL_II_WITH_ZLIB) - for (unsigned int i = 0; i < n_points; ++i) - stream << '\t' - << start + - (reference_cell == ReferenceCells::Pyramid ? table[i] : i); - stream << '\n'; -#else - for (unsigned int i = 0; i < n_points; ++i) - cells.push_back( - start + (reference_cell == ReferenceCells::Pyramid ? table[i] : i)); +#ifdef DEAL_II_WITH_ZLIB + if (flags.compression_level != DataOutBase::CompressionLevel::plain_text) + { + for (unsigned int i = 0; i < n_points; ++i) + cells.push_back( + start + (reference_cell == ReferenceCells::Pyramid ? table[i] : i)); + } + else #endif + { + for (unsigned int i = 0; i < n_points; ++i) + stream << '\t' + << start + (reference_cell == ReferenceCells::Pyramid ? + table[i] : + i); + stream << '\n'; + } } template @@ -2024,24 +2044,32 @@ namespace const unsigned int start, const std::vector &connectivity) { -#if !defined(DEAL_II_WITH_ZLIB) - for (const auto &c : connectivity) - stream << '\t' << start + c; - stream << '\n'; -#else - for (const auto &c : connectivity) - cells.push_back(start + c); +#ifdef DEAL_II_WITH_ZLIB + if (flags.compression_level != DataOutBase::CompressionLevel::plain_text) + { + for (const auto &c : connectivity) + cells.push_back(start + c); + } + else #endif + { + for (const auto &c : connectivity) + stream << '\t' << start + c; + stream << '\n'; + } } void VtuStream::flush_cells() { #ifdef DEAL_II_WITH_ZLIB - // compress the data we have in memory and write them to the stream. then - // release the data - *this << cells << '\n'; - cells.clear(); + if (flags.compression_level != DataOutBase::CompressionLevel::plain_text) + { + // compress the data we have in memory and write them to the stream. + // then release the data + *this << cells << '\n'; + cells.clear(); + } #endif } @@ -2051,13 +2079,18 @@ namespace VtuStream::operator<<(const std::vector &data) { #ifdef DEAL_II_WITH_ZLIB - // compress the data we have in memory and write them to the stream. then - // release the data - write_compressed_block(data, flags, stream); -#else - for (unsigned int i = 0; i < data.size(); ++i) - stream << data[i] << ' '; + if (flags.compression_level != DataOutBase::CompressionLevel::plain_text) + { + // compress the data we have in memory and write them to the stream. + // then release the data + write_compressed_block(data, flags, stream); + } + else #endif + { + for (unsigned int i = 0; i < data.size(); ++i) + stream << data[i] << ' '; + } return stream; } @@ -5804,7 +5837,8 @@ namespace DataOutBase out << "\n-->\n"; out << " cell_types; -#else std::vector cell_types; -#endif cell_types.reserve(n_cells); unsigned int first_vertex_of_patch = 0; @@ -6089,7 +6119,21 @@ namespace DataOutBase << ascii_or_binary << "\">\n"; // this should compress well :-) - vtu_out << cell_types; +#ifdef DEAL_II_WITH_ZLIB + if (flags.compression_level != CompressionLevel::plain_text) + { + std::vector cell_types_uint8_t(cell_types.size()); + for (unsigned int i = 0; i < cell_types.size(); ++i) + cell_types_uint8_t[i] = static_cast(cell_types[i]); + + vtu_out << cell_types_uint8_t; + } + else +#endif + { + vtu_out << cell_types; + } + out << '\n'; out << " \n"; out << " \n"; @@ -7642,6 +7686,9 @@ namespace DataOutBase { boost::iostreams::filtering_ostream f; + AssertThrow(compression != CompressionLevel::plain_text, + ExcNotImplemented()); + if (compression != CompressionLevel::no_compression) # ifdef DEAL_II_WITH_ZLIB f.push(boost::iostreams::zlib_compressor( @@ -9335,6 +9382,11 @@ DataOutReader::read_whole_parallel_file(std::istream &in) std::vector temp_buffer(chunk_sizes[n]); in.read(temp_buffer.data(), chunk_sizes[n]); + AssertThrow(static_cast( + header.compression) != + DataOutBase::CompressionLevel::plain_text, + ExcNotImplemented()); + boost::iostreams::filtering_istreambuf f; if (static_cast(header.compression) != DataOutBase::CompressionLevel::no_compression) diff --git a/tests/data_out/data_out_base_vtu_compression_levels.cc b/tests/data_out/data_out_base_vtu_compression_levels.cc index 94dc6dcaeb..19dc89ae3f 100644 --- a/tests/data_out/data_out_base_vtu_compression_levels.cc +++ b/tests/data_out/data_out_base_vtu_compression_levels.cc @@ -56,7 +56,7 @@ template void check_all(std::ostream &log) { - for (unsigned int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 5; ++i) { DataOutBase::VtkFlags flags; switch (i) @@ -76,6 +76,9 @@ check_all(std::ostream &log) flags.compression_level = DataOutBase::CompressionLevel::default_compression; break; + case (4): + flags.compression_level = DataOutBase::CompressionLevel::plain_text; + break; default: Assert(false, ExcInternalError()); } diff --git a/tests/data_out/data_out_base_vtu_compression_levels.with_zlib=true.output b/tests/data_out/data_out_base_vtu_compression_levels.with_zlib=true.output index 9dcf9755be..40b33aa0f0 100644 --- a/tests/data_out/data_out_base_vtu_compression_levels.with_zlib=true.output +++ b/tests/data_out/data_out_base_vtu_compression_levels.with_zlib=true.output @@ -191,6 +191,76 @@ AQAAADgAAAA4AAAAGAAAAA==eJxjYACBBnsGBO2AynbAwm9wAACFNAV9 ============================== +11-4.vtu +============================== + + + + + + + +0 0 0 +1 0 0 +1 0 0 +1.5 0 0 +2 0 0 +2 0 0 +2.33333 0 0 +2.66667 0 0 +3 0 0 +3 0 0 +3.25 0 0 +3.5 0 0 +3.75 0 0 +4 0 0 + + + + + +0 1 +2 3 +3 4 +5 6 +6 7 +7 8 +9 10 +10 11 +11 12 +12 13 + + +2 4 6 8 10 12 14 16 18 20 + + +3 3 3 3 3 3 3 3 3 3 + + + + +0 1 1 1.5 2 2 2.33333 2.66667 3 3 3.25 3.5 3.75 4 + + +0 0 1 1 1 2 2 2 2 3 3 3 3 3 + + +0 0 1 1 1 2 2 2 2 3 3 3 3 3 + + +0 0 1 1 1 2 2 2 2 3 3 3 3 3 + + +0 1 0 1 2 0 1 2 3 0 1 2 3 4 + + + + + +============================== 22-0.vtu ============================== @@ -383,6 +453,136 @@ AQAAANgAAADYAAAATQAAAA==eJxjYACBBnsg4QBEDgwY/AYgXgDEB4D4AUjekTg1AkCsAMQGQOwAxAFA ============================== +22-4.vtu +============================== + + + + + + + +0 0 0 +1 0 0 +0 1 0 +1 1 0 +1 1 0 +1.5 1 0 +2 1 0 +1 1.5 0 +1.5 1.5 0 +2 1.5 0 +1 2 0 +1.5 2 0 +2 2 0 +2 2 0 +2.33333 2 0 +2.66667 2 0 +3 2 0 +2 2.33333 0 +2.33333 2.33333 0 +2.66667 2.33333 0 +3 2.33333 0 +2 2.66667 0 +2.33333 2.66667 0 +2.66667 2.66667 0 +3 2.66667 0 +2 3 0 +2.33333 3 0 +2.66667 3 0 +3 3 0 +3 3 0 +3.25 3 0 +3.5 3 0 +3.75 3 0 +4 3 0 +3 3.25 0 +3.25 3.25 0 +3.5 3.25 0 +3.75 3.25 0 +4 3.25 0 +3 3.5 0 +3.25 3.5 0 +3.5 3.5 0 +3.75 3.5 0 +4 3.5 0 +3 3.75 0 +3.25 3.75 0 +3.5 3.75 0 +3.75 3.75 0 +4 3.75 0 +3 4 0 +3.25 4 0 +3.5 4 0 +3.75 4 0 +4 4 0 + + + + + +0 1 3 2 +4 5 8 7 +5 6 9 8 +7 8 11 10 +8 9 12 11 +13 14 18 17 +14 15 19 18 +15 16 20 19 +17 18 22 21 +18 19 23 22 +19 20 24 23 +21 22 26 25 +22 23 27 26 +23 24 28 27 +29 30 35 34 +30 31 36 35 +31 32 37 36 +32 33 38 37 +34 35 40 39 +35 36 41 40 +36 37 42 41 +37 38 43 42 +39 40 45 44 +40 41 46 45 +41 42 47 46 +42 43 48 47 +44 45 50 49 +45 46 51 50 +46 47 52 51 +47 48 53 52 + + +4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 + + +9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 + + + + +0 1 0 1 1 1.5 2 1 1.5 2 1 1.5 2 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 + + +0 0 1 1 1 1 1 1.5 1.5 1.5 2 2 2 2 2 2 2 2.33333 2.33333 2.33333 2.33333 2.66667 2.66667 2.66667 2.66667 3 3 3 3 3 3 3 3 3 3.25 3.25 3.25 3.25 3.25 3.5 3.5 3.5 3.5 3.5 3.75 3.75 3.75 3.75 3.75 4 4 4 4 4 + + +0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + + +0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + + +0 1 2 3 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 + + + + + +============================== 33-0.vtu ============================== @@ -574,3 +774,373 @@ AQAAAIADAACAAwAA/wAAAA==eJztz7ErhAEYB+BvMBgMBoPBcIPBYLjBYFC+uwwGww0Gg8FgMBhuMBgM +============================== +33-4.vtu +============================== + + + + + + + +0 0 0 +1 0 0 +0 1 0 +1 1 0 +0 0 1 +1 0 1 +0 1 1 +1 1 1 +1 1 1 +1.5 1 1 +2 1 1 +1 1.5 1 +1.5 1.5 1 +2 1.5 1 +1 2 1 +1.5 2 1 +2 2 1 +1 1 1.5 +1.5 1 1.5 +2 1 1.5 +1 1.5 1.5 +1.5 1.5 1.5 +2 1.5 1.5 +1 2 1.5 +1.5 2 1.5 +2 2 1.5 +1 1 2 +1.5 1 2 +2 1 2 +1 1.5 2 +1.5 1.5 2 +2 1.5 2 +1 2 2 +1.5 2 2 +2 2 2 +2 2 2 +2.33333 2 2 +2.66667 2 2 +3 2 2 +2 2.33333 2 +2.33333 2.33333 2 +2.66667 2.33333 2 +3 2.33333 2 +2 2.66667 2 +2.33333 2.66667 2 +2.66667 2.66667 2 +3 2.66667 2 +2 3 2 +2.33333 3 2 +2.66667 3 2 +3 3 2 +2 2 2.33333 +2.33333 2 2.33333 +2.66667 2 2.33333 +3 2 2.33333 +2 2.33333 2.33333 +2.33333 2.33333 2.33333 +2.66667 2.33333 2.33333 +3 2.33333 2.33333 +2 2.66667 2.33333 +2.33333 2.66667 2.33333 +2.66667 2.66667 2.33333 +3 2.66667 2.33333 +2 3 2.33333 +2.33333 3 2.33333 +2.66667 3 2.33333 +3 3 2.33333 +2 2 2.66667 +2.33333 2 2.66667 +2.66667 2 2.66667 +3 2 2.66667 +2 2.33333 2.66667 +2.33333 2.33333 2.66667 +2.66667 2.33333 2.66667 +3 2.33333 2.66667 +2 2.66667 2.66667 +2.33333 2.66667 2.66667 +2.66667 2.66667 2.66667 +3 2.66667 2.66667 +2 3 2.66667 +2.33333 3 2.66667 +2.66667 3 2.66667 +3 3 2.66667 +2 2 3 +2.33333 2 3 +2.66667 2 3 +3 2 3 +2 2.33333 3 +2.33333 2.33333 3 +2.66667 2.33333 3 +3 2.33333 3 +2 2.66667 3 +2.33333 2.66667 3 +2.66667 2.66667 3 +3 2.66667 3 +2 3 3 +2.33333 3 3 +2.66667 3 3 +3 3 3 +3 3 3 +3.25 3 3 +3.5 3 3 +3.75 3 3 +4 3 3 +3 3.25 3 +3.25 3.25 3 +3.5 3.25 3 +3.75 3.25 3 +4 3.25 3 +3 3.5 3 +3.25 3.5 3 +3.5 3.5 3 +3.75 3.5 3 +4 3.5 3 +3 3.75 3 +3.25 3.75 3 +3.5 3.75 3 +3.75 3.75 3 +4 3.75 3 +3 4 3 +3.25 4 3 +3.5 4 3 +3.75 4 3 +4 4 3 +3 3 3.25 +3.25 3 3.25 +3.5 3 3.25 +3.75 3 3.25 +4 3 3.25 +3 3.25 3.25 +3.25 3.25 3.25 +3.5 3.25 3.25 +3.75 3.25 3.25 +4 3.25 3.25 +3 3.5 3.25 +3.25 3.5 3.25 +3.5 3.5 3.25 +3.75 3.5 3.25 +4 3.5 3.25 +3 3.75 3.25 +3.25 3.75 3.25 +3.5 3.75 3.25 +3.75 3.75 3.25 +4 3.75 3.25 +3 4 3.25 +3.25 4 3.25 +3.5 4 3.25 +3.75 4 3.25 +4 4 3.25 +3 3 3.5 +3.25 3 3.5 +3.5 3 3.5 +3.75 3 3.5 +4 3 3.5 +3 3.25 3.5 +3.25 3.25 3.5 +3.5 3.25 3.5 +3.75 3.25 3.5 +4 3.25 3.5 +3 3.5 3.5 +3.25 3.5 3.5 +3.5 3.5 3.5 +3.75 3.5 3.5 +4 3.5 3.5 +3 3.75 3.5 +3.25 3.75 3.5 +3.5 3.75 3.5 +3.75 3.75 3.5 +4 3.75 3.5 +3 4 3.5 +3.25 4 3.5 +3.5 4 3.5 +3.75 4 3.5 +4 4 3.5 +3 3 3.75 +3.25 3 3.75 +3.5 3 3.75 +3.75 3 3.75 +4 3 3.75 +3 3.25 3.75 +3.25 3.25 3.75 +3.5 3.25 3.75 +3.75 3.25 3.75 +4 3.25 3.75 +3 3.5 3.75 +3.25 3.5 3.75 +3.5 3.5 3.75 +3.75 3.5 3.75 +4 3.5 3.75 +3 3.75 3.75 +3.25 3.75 3.75 +3.5 3.75 3.75 +3.75 3.75 3.75 +4 3.75 3.75 +3 4 3.75 +3.25 4 3.75 +3.5 4 3.75 +3.75 4 3.75 +4 4 3.75 +3 3 4 +3.25 3 4 +3.5 3 4 +3.75 3 4 +4 3 4 +3 3.25 4 +3.25 3.25 4 +3.5 3.25 4 +3.75 3.25 4 +4 3.25 4 +3 3.5 4 +3.25 3.5 4 +3.5 3.5 4 +3.75 3.5 4 +4 3.5 4 +3 3.75 4 +3.25 3.75 4 +3.5 3.75 4 +3.75 3.75 4 +4 3.75 4 +3 4 4 +3.25 4 4 +3.5 4 4 +3.75 4 4 +4 4 4 + + + + + +0 1 3 2 4 5 7 6 +8 9 12 11 17 18 21 20 +9 10 13 12 18 19 22 21 +11 12 15 14 20 21 24 23 +12 13 16 15 21 22 25 24 +17 18 21 20 26 27 30 29 +18 19 22 21 27 28 31 30 +20 21 24 23 29 30 33 32 +21 22 25 24 30 31 34 33 +35 36 40 39 51 52 56 55 +36 37 41 40 52 53 57 56 +37 38 42 41 53 54 58 57 +39 40 44 43 55 56 60 59 +40 41 45 44 56 57 61 60 +41 42 46 45 57 58 62 61 +43 44 48 47 59 60 64 63 +44 45 49 48 60 61 65 64 +45 46 50 49 61 62 66 65 +51 52 56 55 67 68 72 71 +52 53 57 56 68 69 73 72 +53 54 58 57 69 70 74 73 +55 56 60 59 71 72 76 75 +56 57 61 60 72 73 77 76 +57 58 62 61 73 74 78 77 +59 60 64 63 75 76 80 79 +60 61 65 64 76 77 81 80 +61 62 66 65 77 78 82 81 +67 68 72 71 83 84 88 87 +68 69 73 72 84 85 89 88 +69 70 74 73 85 86 90 89 +71 72 76 75 87 88 92 91 +72 73 77 76 88 89 93 92 +73 74 78 77 89 90 94 93 +75 76 80 79 91 92 96 95 +76 77 81 80 92 93 97 96 +77 78 82 81 93 94 98 97 +99 100 105 104 124 125 130 129 +100 101 106 105 125 126 131 130 +101 102 107 106 126 127 132 131 +102 103 108 107 127 128 133 132 +104 105 110 109 129 130 135 134 +105 106 111 110 130 131 136 135 +106 107 112 111 131 132 137 136 +107 108 113 112 132 133 138 137 +109 110 115 114 134 135 140 139 +110 111 116 115 135 136 141 140 +111 112 117 116 136 137 142 141 +112 113 118 117 137 138 143 142 +114 115 120 119 139 140 145 144 +115 116 121 120 140 141 146 145 +116 117 122 121 141 142 147 146 +117 118 123 122 142 143 148 147 +124 125 130 129 149 150 155 154 +125 126 131 130 150 151 156 155 +126 127 132 131 151 152 157 156 +127 128 133 132 152 153 158 157 +129 130 135 134 154 155 160 159 +130 131 136 135 155 156 161 160 +131 132 137 136 156 157 162 161 +132 133 138 137 157 158 163 162 +134 135 140 139 159 160 165 164 +135 136 141 140 160 161 166 165 +136 137 142 141 161 162 167 166 +137 138 143 142 162 163 168 167 +139 140 145 144 164 165 170 169 +140 141 146 145 165 166 171 170 +141 142 147 146 166 167 172 171 +142 143 148 147 167 168 173 172 +149 150 155 154 174 175 180 179 +150 151 156 155 175 176 181 180 +151 152 157 156 176 177 182 181 +152 153 158 157 177 178 183 182 +154 155 160 159 179 180 185 184 +155 156 161 160 180 181 186 185 +156 157 162 161 181 182 187 186 +157 158 163 162 182 183 188 187 +159 160 165 164 184 185 190 189 +160 161 166 165 185 186 191 190 +161 162 167 166 186 187 192 191 +162 163 168 167 187 188 193 192 +164 165 170 169 189 190 195 194 +165 166 171 170 190 191 196 195 +166 167 172 171 191 192 197 196 +167 168 173 172 192 193 198 197 +174 175 180 179 199 200 205 204 +175 176 181 180 200 201 206 205 +176 177 182 181 201 202 207 206 +177 178 183 182 202 203 208 207 +179 180 185 184 204 205 210 209 +180 181 186 185 205 206 211 210 +181 182 187 186 206 207 212 211 +182 183 188 187 207 208 213 212 +184 185 190 189 209 210 215 214 +185 186 191 190 210 211 216 215 +186 187 192 191 211 212 217 216 +187 188 193 192 212 213 218 217 +189 190 195 194 214 215 220 219 +190 191 196 195 215 216 221 220 +191 192 197 196 216 217 222 221 +192 193 198 197 217 218 223 222 + + +8 16 24 32 40 48 56 64 72 80 88 96 104 112 120 128 136 144 152 160 168 176 184 192 200 208 216 224 232 240 248 256 264 272 280 288 296 304 312 320 328 336 344 352 360 368 376 384 392 400 408 416 424 432 440 448 456 464 472 480 488 496 504 512 520 528 536 544 552 560 568 576 584 592 600 608 616 624 632 640 648 656 664 672 680 688 696 704 712 720 728 736 744 752 760 768 776 784 792 800 + + +12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 + + + + +0 1 0 1 0 1 0 1 1 1.5 2 1 1.5 2 1 1.5 2 1 1.5 2 1 1.5 2 1 1.5 2 1 1.5 2 1 1.5 2 1 1.5 2 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 2 2.33333 2.66667 3 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 3 3.25 3.5 3.75 4 + + +0 0 1 1 0 0 1 1 1 1 1 1.5 1.5 1.5 2 2 2 1 1 1 1.5 1.5 1.5 2 2 2 1 1 1 1.5 1.5 1.5 2 2 2 2 2 2 2 2.33333 2.33333 2.33333 2.33333 2.66667 2.66667 2.66667 2.66667 3 3 3 3 2 2 2 2 2.33333 2.33333 2.33333 2.33333 2.66667 2.66667 2.66667 2.66667 3 3 3 3 2 2 2 2 2.33333 2.33333 2.33333 2.33333 2.66667 2.66667 2.66667 2.66667 3 3 3 3 2 2 2 2 2.33333 2.33333 2.33333 2.33333 2.66667 2.66667 2.66667 2.66667 3 3 3 3 3 3 3 3 3 3.25 3.25 3.25 3.25 3.25 3.5 3.5 3.5 3.5 3.5 3.75 3.75 3.75 3.75 3.75 4 4 4 4 4 3 3 3 3 3 3.25 3.25 3.25 3.25 3.25 3.5 3.5 3.5 3.5 3.5 3.75 3.75 3.75 3.75 3.75 4 4 4 4 4 3 3 3 3 3 3.25 3.25 3.25 3.25 3.25 3.5 3.5 3.5 3.5 3.5 3.75 3.75 3.75 3.75 3.75 4 4 4 4 4 3 3 3 3 3 3.25 3.25 3.25 3.25 3.25 3.5 3.5 3.5 3.5 3.5 3.75 3.75 3.75 3.75 3.75 4 4 4 4 4 3 3 3 3 3 3.25 3.25 3.25 3.25 3.25 3.5 3.5 3.5 3.5 3.5 3.75 3.75 3.75 3.75 3.75 4 4 4 4 4 + + +0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.33333 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 2.66667 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.25 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 3.75 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 + + +0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + + +0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 + + + + +