From 2238c56ea1f0591168f962e69ad224be2866dafd Mon Sep 17 00:00:00 2001 From: wolf Date: Thu, 1 Apr 1999 09:00:50 +0000 Subject: [PATCH] Add some initial functionality to dump a grid to disk and re-read it later. git-svn-id: https://svn.dealii.org/trunk@1069 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/include/grid/tria.h | 22 ++ deal.II/deal.II/include/grid/tria_levels.h | 178 +++++++++++++++ .../source/grid/tria.all_dimensions.cc | 206 ++++++++++++++++++ 3 files changed, 406 insertions(+) diff --git a/deal.II/deal.II/include/grid/tria.h b/deal.II/deal.II/include/grid/tria.h index 6116968413..fecd2dcaae 100644 --- a/deal.II/deal.II/include/grid/tria.h +++ b/deal.II/deal.II/include/grid/tria.h @@ -1552,6 +1552,28 @@ class Triangulation : public TriaDimensionInfo, public Subscriptor { * beforehand. */ void copy_triangulation (const Triangulation &old_tria); + + /** + * Write out a triangulation en bloc, i.e. + * in a binary or near binary format. Since + * some of the data vectors describing a + * triangulation are written en bloc + * from memory to the stream, the file + * resulting from this operation will not + * be readable on other platforms; this + * function along with the following is + * only thought to support fast creation + * of and restoration from temporary + * files. + */ + void block_write (ostream &out) const; + + /** + * Restore a triangulation written by the + * above function. The present content of + * the triangulation is obviously lost. + */ + void block_read (istream &in); /** * Create a triangulation from a list diff --git a/deal.II/deal.II/include/grid/tria_levels.h b/deal.II/deal.II/include/grid/tria_levels.h index 0d228d8698..f3ac64850b 100644 --- a/deal.II/deal.II/include/grid/tria_levels.h +++ b/deal.II/deal.II/include/grid/tria_levels.h @@ -146,6 +146,21 @@ class TriangulationLevel<0> { */ void monitor_memory (const unsigned int true_dimension) const; + /** + * Write out the data of this object + * in a raw format, i.e. binary or almost + * binary. + */ + void block_write (ostream &out) const; + + /** + * Read back the data written by the above + * function. By doing so, all content + * which may have been in this object will + * be lost. + */ + void block_read (istream &in); + /** * Exception */ @@ -161,6 +176,106 @@ class TriangulationLevel<0> { int, int, << "The containers have sizes " << arg1 << " and " << arg2 << ", which is not as expected."); + /** + * Exception + */ + DeclException0 (ExcIO); + + protected: + + /** + * Write out a vector of anything + * in a binary format. To be exact, + * what we write is the memory content + * between #v.begin()# and #v.end()#; + * this function is therefore only + * useful if the whole information of + * the objects stored in this vector + * are contained within the objects, + * i.e. they do not have pointers, + * references, other vectors, etc. + * + * For all other vectors, specialized + * functions need to be written; the + * following one is an example for + * this. + */ + template + static void write_raw_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + ostream &out); + + /** + * Write a bool vector to the given stream, + * writing a pre- and a postfix magica + * number. The vector is written in an + * almost binary format, i.e. the bool + * flags are packed but the data is written + * as ASCII text. + * + * The flags are stored in a binary + * format: for each #true#, a #1# + * bit is stored, a #0# bit otherwise. + * The bits are stored as #unsigned char#, + * thus avoiding endianess. They are + * written to #out# in plain text, thus + * amounting to 3.6 bits per flag + * on the overage. Other information + * (magic numbers ans number of elements) + * is stored as plain text + * as well. The format should therefore be + * interplatform compatible. + */ + static void write_raw_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + ostream &out); + + /** + * Write out a vector almost raw: we + * use a run-length encoding (rle) scheme + * to reduce the size of a vector. This + * function yields better results than the + * above ones if frequently larger chunks + * of data have the same value. + */ + template + static void write_rle_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + ostream &out); + + /** + * Read back a vector written by + * #write_raw_vector#. + */ + template + static void read_raw_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + istream &in); + + /** + * Read back a vector written by + * the version of #write_raw_vector# + * for #bool# vectors. + */ + static void read_raw_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + istream &in); + + /** + * Read back a run-length encoded + * vector, as written by + * #write_rle_vector#. + */ + template + static void read_rle_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + istream &in); }; @@ -307,6 +422,27 @@ class TriangulationLevel<1> : public TriangulationLevel<0> { * #TriangulationLevel# classes. */ void monitor_memory (const unsigned int true_dimension) const; + + /** + * Write out the data of this object + * in a raw format, i.e. binary or almost + * binary. + * + * Calls the respective function of + * #TriangulationLevel<0>#. + */ + void block_write (ostream &out) const; + + /** + * Read back the data written by the above + * function. By doing so, all content + * which may have been in this object will + * be lost. + * + * Calls the respective function of + * #TriangulationLevel<0>#. + */ + void block_read (istream &in); }; @@ -415,6 +551,27 @@ class TriangulationLevel<2> : public TriangulationLevel<1> * #TriangulationLevel# classes. */ void monitor_memory (const unsigned int true_dimension) const; + + /** + * Write out the data of this object + * in a raw format, i.e. binary or almost + * binary. + * + * Calls the respective function of + * #TriangulationLevel<1>#. + */ + void block_write (ostream &out) const; + + /** + * Read back the data written by the above + * function. By doing so, all content + * which may have been in this object will + * be lost. + * + * Calls the respective function of + * #TriangulationLevel<1>#. + */ + void block_read (istream &in); }; @@ -523,6 +680,27 @@ class TriangulationLevel<3> : public TriangulationLevel<2> * #TriangulationLevel# classes. */ void monitor_memory (const unsigned int true_dimension) const; + + /** + * Write out the data of this object + * in a raw format, i.e. binary or almost + * binary. + * + * Calls the respective function of + * #TriangulationLevel<2>#. + */ + void block_write (ostream &out) const; + + /** + * Read back the data written by the above + * function. By doing so, all content + * which may have been in this object will + * be lost. + * + * Calls the respective function of + * #TriangulationLevel<2>#. + */ + void block_read (istream &in); }; diff --git a/deal.II/deal.II/source/grid/tria.all_dimensions.cc b/deal.II/deal.II/source/grid/tria.all_dimensions.cc index 02a11eaf24..dbc43d83f6 100644 --- a/deal.II/deal.II/source/grid/tria.all_dimensions.cc +++ b/deal.II/deal.II/source/grid/tria.all_dimensions.cc @@ -90,6 +90,171 @@ void TriangulationLevel<0>::monitor_memory (const unsigned int true_dimension) c +template +void TriangulationLevel<0>::write_raw_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + ostream &out) +{ + AssertThrow (out, ExcIO()); + + out << magic_number1 << ' ' << v.size() << '['; + out.write (reinterpret_cast(v.begin()), + reinterpret_cast(v.end()) + - reinterpret_cast(v.begin())); + out << ']' << magic_number2 << endl; + + AssertThrow (out, ExcIO()); +}; + + + +void TriangulationLevel<0>::write_raw_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + ostream &out) { + const unsigned int N = v.size(); + unsigned char *flags = new unsigned char[N/8+1]; + for (unsigned int i=0; i(flags[i]) << " "; + + out << ']' << magic_number2 << endl; + + delete[] flags; + + AssertThrow (out, ExcIO()); +}; + + + +template +void TriangulationLevel<0>::write_rle_vector (const unsigned int magic_number1, + const vector &v, + const unsigned int magic_number2, + ostream &out) +{ + AssertThrow (out, ExcIO()); + + // store the position of the last + // break in the data stream from + // which on nothing was yet written + // to #out# + typename vector::const_iterator last_major_break = v.begin(); + // pointer to an element against + // which we want to compare following + // elements + typename vector::const_iterator comparator; + // name says all + typename vector::const_iterator present_element; + // same here + typename vector::const_iterator end_of_vector = v.end(); + + out << magic_number1 << ' ' << v.size() << '['; + + while (last_major_break < end_of_vector) + { + // from the present position onward: + // find how many elements are equal + comparator = last_major_break; + + while (true) + { + present_element = comparator+1; + while ((present_element != end_of_vector) && + (*present_element == *comparator) && + (present_element-comparator < 255)) + ++present_element; + + // now present_element points to the + // first element which is not equal + // to #comparator# or alternatively + // to #end_of_vector# or to + // #comparator+255# + // + // if #present_element# is + // #comparator+1#, i.e. the + // sequence of equal + // elements consisted of + // only one elements then + // discard this sequence + // and find the next one + // + // otherwise leave the loop + if ((present_element != end_of_vector) && + (present_element < comparator+1)) + comparator = present_element; + else + break; + }; + + // if the loop broke because we have + // reached the end of the vector: + // maybe set comparator to + // present_element + if ((present_element == end_of_vector) && + (present_element < comparator+1)) + comparator = present_element; + + // now comparator points to the start + // of the sequence of equal elements + // and present_element points past its + // end; they may be the same if the + // length of the sequence of unequal + // elements was 255 + // + // now do the following: write out + // the elements of + // last_major_break...comparator, + // then write + // comparator...present_element + // if necessary; note that we need + // only write *one* element (that is why + // we do all this here) + out << '<' << comparator-last_major_break << '>'; + if (comparator != last_major_break) + out.write (reinterpret_cast(last_major_break), + reinterpret_cast(comparator) + - reinterpret_cast(last_major_break)); + out << '<' << present_element-comparator << '>'; + if (present_element != comparator) + out.write (reinterpret_cast(comparator), + reinterpret_cast(comparator+1) + - reinterpret_cast(comparator)); + + last_major_break = present_element; + }; + + out << ']' << magic_number2 << endl; + + AssertThrow (out, ExcIO()); +}; + + + +void TriangulationLevel<0>::block_write (ostream &out) const +{ + write_raw_vector (0, refine_flags, 0, out); + write_raw_vector (0, coarsen_flags, 0, out); + write_raw_vector (0, neighbors, 0, out); +}; + + + + + void TriangulationLevel<1>::reserve_space (const unsigned int new_lines) { const unsigned int new_size = new_lines + count_if (lines.used.begin(), @@ -169,6 +334,20 @@ void TriangulationLevel<1>::monitor_memory (const unsigned int true_dimension) c +void TriangulationLevel<1>::block_write (ostream &out) const +{ + TriangulationLevel<0>::block_write (out); + + write_raw_vector (0, lines.lines, 0, out); + write_rle_vector (0, lines.children, 0, out); + write_raw_vector (0, lines.used, 0, out); + write_raw_vector (0, lines.user_flags, 0, out); + write_rle_vector (0, lines.material_id, 0, out); + // note: user_pointers are not written +}; + + + void TriangulationLevel<2>::reserve_space (const unsigned int new_quads) { const unsigned int new_size = new_quads + @@ -239,6 +418,21 @@ void TriangulationLevel<2>::monitor_memory (const unsigned int true_dimension) c +void TriangulationLevel<2>::block_write (ostream &out) const +{ + TriangulationLevel<1>::block_write (out); + + write_raw_vector (0, quads.quads, 0, out); + write_rle_vector (0, quads.children, 0, out); + write_raw_vector (0, quads.used, 0, out); + write_raw_vector (0, quads.user_flags, 0, out); + write_rle_vector (0, quads.material_id, 0, out); + // note: user_pointers are not written +}; + + + + void TriangulationLevel<3>::reserve_space (const unsigned int new_hexes) { @@ -310,4 +504,16 @@ void TriangulationLevel<3>::monitor_memory (const unsigned int true_dimension) c +void TriangulationLevel<3>::block_write (ostream &out) const +{ + TriangulationLevel<2>::block_write (out); + + write_raw_vector (0, hexes.hexes, 0, out); + write_rle_vector (0, hexes.children, 0, out); + write_raw_vector (0, hexes.used, 0, out); + write_raw_vector (0, hexes.user_flags, 0, out); + write_rle_vector (0, hexes.material_id, 0, out); + // note: user_pointers are not written +}; + -- 2.39.5