Bridge++  Ver. 1.1.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fieldIO_Fortran.cpp
Go to the documentation of this file.
1 
10 // This class is to read binary file generated by Fortran code.
11 // If the endian of the system differs from file format,
12 // byte_swap must be called.
13 
14 #include "fieldIO_Fortran.h"
15 
16 #include <iostream>
17 #include <fstream>
18 
19 #include "commonParameters.h"
20 #include "communicator.h"
21 #include "bridgeIO.h"
22 using Bridge::vout;
23 
24 #include "field.h"
25 
26 //====================================================================
27 void FieldIO_Fortran::read_file(Field *v, std::string filename)
28 {
29  int nin_field = v->nin();
30  int nex_field = v->nex();
31 
32  int nin_file = m_format->nin();
33  int nex_file = m_format->nex();
34 
35  if ((nin_file == 0) || (nex_file == 0)) {
36  nin_file = nin_field;
37  nex_file = nex_field;
38  }
39 
40  int Lvol = CommonParameters::Lvol();
41 
42  int size = nin_file * Lvol * nex_file;
43 
44  Field vtmp;
45 
47  vout.detailed(m_vl, "reading field data from %s", filename.c_str());
48 
49  vtmp.reset(nin_field, Lvol, nex_field);
50 
51  std::fstream infile;
52  infile.open(filename.c_str(), std::ios::in | std::ios::binary);
53 
54  bool do_byteswap = false;
55 
56  // Skipping 4B data size area (for size less than 2 GB)
57  // infile.seekg(4);
58 
59  // read header: record length (bytes)
60  // assume header is 4bytes.
61  uint32_t flen;
62  infile.read((char *)&flen, sizeof(uint32_t) * 1);
63  if (!infile) {
64  vout.general(m_vl, "file = %s open failed\n", filename.c_str());
65  return;
66  }
67 
68  // find byteorder
69  if (flen == sizeof(double) * size) {
70  // file byteorder is equal to machine byteorder
71  vout.detailed(m_vl, "endian matched.\n");
72  } else {
73  uint32_t flen_s = flen;
74  byte_swap(&flen_s, sizeof(uint32_t), 1);
75 
76  if (flen_s == sizeof(double) * size) {
77  // file byteorder is different from machine byteorder: need swap.
78  vout.detailed(m_vl, "different endian. do swap.\n");
79  do_byteswap = true;
80  } else {
81  vout.crucial(m_vl, "size mismatch or format unidentified.\n");
82  abort();
83  }
84  }
85 
86  // read content
87  const int block_size = nin_file;
88  char buf[sizeof(double) * block_size];
89 
90  for (int j = 0; j < nex_file; ++j) {
91  for (int isite = 0; isite < Lvol; ++isite) {
92  // read 1 block
93  infile.read(buf, sizeof(double) * block_size);
94 
95  if (do_byteswap) {
96  byte_swap(buf, sizeof(double), block_size);
97  }
98 
99  double *ptr = (double *)buf;
100 
101  for (int i = 0; i < nin_file; ++i) {
102  int s, t;
103  m_format->file_to_field(s, t, i, j);
104 
105  vtmp.set(s, isite, t, ptr[i]);
106  }
107  }
108  }
109 
110  // read trailer
111  uint32_t ftail;
112  infile.read((char *)&ftail, sizeof(uint32_t) * 1);
113 
114  if (flen != ftail) {
115  vout.crucial(m_vl, "record info mismatch.\n");
116  abort();
117  }
118  if (!infile) {
119  vout.crucial(m_vl, "file read failed.\n");
120  abort();
121  }
122 
123  infile.close();
124  }
125 
126  FieldIO::deliver(v, &vtmp);
127 
128  vout.detailed(m_vl, "read successful\n");
129 }
130 
131 
132 //====================================================================
133 void FieldIO_Fortran::write_file(Field *v, std::string filename)
134 {
135  int nin_field = v->nin();
136  int nex_field = v->nex();
137 
138  int nin_file = m_format->nin();
139  int nex_file = m_format->nex();
140 
141  if ((nin_file == 0) || (nex_file == 0)) {
142  nin_file = nin_field;
143  nex_file = nex_field;
144  }
145 
146  int Lvol = CommonParameters::Lvol();
147 
148  Field vtmp;
149  if (Communicator::is_primary()) {
150  vtmp.reset(nin_field, Lvol, nex_field);
151  }
152 
153  size_t count = nin_file * Lvol * nex_file;
154 
155  FieldIO::gather(&vtmp, v);
156 
157  if (Communicator::is_primary()) {
158  vout.detailed(m_vl, "writing field data to %s\n", filename.c_str());
159 
160  std::ofstream outfile(filename.c_str(), std::ios::out | std::ios::binary);
161  if (!outfile) {
162  vout.general(m_vl, "file = %s open failed\n", filename.c_str());
163  return;
164  }
165 
166  uint32_t flen = sizeof(double) * count;
167 
168  // record header: record length (bytes)
169  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
170 
171  // record content
172  const int block_size = nin_file;
173  char buf[sizeof(double) * block_size];
174 
175 
176  for (int j = 0; j < nex_file; ++j) {
177  for (int isite = 0; isite < Lvol; ++isite) {
178  double *ptr = (double *)buf;
179 
180  for (int i = 0; i < nin_file; ++i) {
181  int s, t;
182  m_format->file_to_field(s, t, i, j);
183 
184  ptr[i] = vtmp.cmp(s, isite, t);
185  }
186 
187  outfile.write(buf, sizeof(double) * block_size);
188  }
189  }
190 
191  // record footer: record length (bytes)
192  outfile.write((char *)&flen, sizeof(uint32_t) * 1);
193 
194  outfile.close();
195  }
196 
197  vout.detailed(m_vl, "write succeeded.\n");
198 }
199 
200 
201 //====================================================================
202 //============================================================END=====