GPLIB++
ThreeDMTModel.cpp
Go to the documentation of this file.
1 #include "ThreeDMTModel.h"
2 #include "FatalException.h"
3 #include "netcdfcpp.h"
4 #include <fstream>
5 #include <boost/lambda/lambda.hpp>
6 #include <boost/lambda/bind.hpp>
7 using namespace std;
8 using namespace boost::lambda;
9 
10 namespace gplib
11  {
12  ThreeDMTModel::ThreeDMTModel()
13  {
14  airlayers = 0;
15  }
16 
17  ThreeDMTModel::~ThreeDMTModel()
18  {
19  }
20 
21  double ThreeDMTModel::LookupResistivity(const int index)
22  {
23  return Resistivities[index];
24  }
25 
26  int ThreeDMTModel::LookupIndex(const double resistivity)
27  {
28  const size_t nresistivity = Resistivities.size();
29  for (size_t i = 0; i < nresistivity; ++i)
30  if (Resistivities[i] == resistivity)
31  return i;
32 
33  Resistivities.push_back(resistivity);
34  return (nresistivity);
35  }
36 
37  void ThreeDMTModel::ReadWinGLink(std::string filename)
38  {
39  ifstream infile(filename.c_str());
40  size_t xlength, ylength, zlength = 0;
41  int currentlayer = 0;
42  size_t i, j, k = 0;
43  double currentres = 0;
44  char dummy[255];
45  infile >> xlength >> ylength >> zlength >> airlayers;
46  if (infile.fail())
47  throw FatalException("Cannot read file: " + filename);
48  infile.getline(dummy, 255);
49 
50  Model.resize(boost::extents[xlength][ylength][zlength]);
51  xsize.resize(xlength);
52  ysize.resize(ylength);
53  zsize.resize(zlength);
54 
55  for (i = 0; i < xlength; ++i)
56  infile >> xsize[i];
57  for (i = 0; i < ylength; ++i)
58  infile >> ysize[i];
59  for (i = 0; i < zlength; ++i)
60  infile >> zsize[i];
61 
62  for (i = 0; i < zlength; ++i)
63  {
64  infile >> currentlayer;
65  for (j = 0; j < ylength; ++j)
66  for (k = 0; k < xlength; ++k)
67  {
68  infile >> currentres;
69  Model[k][j][currentlayer - 1] = LookupIndex(currentres);
70  }
71  }
72  //Resistivities.resizeAndPreserve(nresistivity);
73  if (infile.fail())
74  throw FatalException("Problem reading file: " + filename);
75  }
76 
77  void ThreeDMTModel::ReadMackie(std::string filename)
78  {
79  ifstream infile(filename.c_str());
80  size_t xlength, ylength, zlength;
81  int currentlayer;
82  size_t i, j, k;
83 
84  infile >> xlength >> ylength >> zlength;
85  if (infile.fail())
86  throw FatalException("Cannot read file: " + filename);
87  Model.resize(boost::extents[xlength][ylength][zlength]);
88  xsize.resize(xlength);
89  ysize.resize(ylength);
90  zsize.resize(zlength);
91 
92  for (i = 0; i < xlength; ++i)
93  infile >> xsize[i];
94  for (i = 0; i < ylength; ++i)
95  infile >> ysize[i];
96  for (i = 0; i < zlength; ++i)
97  infile >> zsize[i];
98 
99  for (i = 0; i < zlength; ++i)
100  {
101  infile >> currentlayer;
102  for (j = 0; j < ylength; ++j)
103  for (k = 0; k < xlength; ++k)
104  infile >> Model[k][j][currentlayer - 1];
105  }
106 
107  while (infile.good())
108  {
109  double currvalue = 0.0;
110  infile >> currvalue;
111  Resistivities.push_back(currvalue);
112  }
113 
114  if (!infile.eof())
115  throw FatalException("Problem reading file: " + filename);
116 
117  }
118 
119  void ThreeDMTModel::WriteWinGLink(std::string filename)
120  {
121  ofstream outfile(filename.c_str());
122  size_t i, j, k;
123  const size_t xlength = xsize.size();
124  const size_t ylength = ysize.size();
125  const size_t zlength = zsize.size();
126  //write out the number of cells in each direction and the number of airlayers
127  //followed by the keyword values
128  outfile << xlength << " " << ylength << " " << zlength << " "
129  << airlayers << " VALUES" << endl;
130  //write out the cell sizes in x-direction
131  std::copy(xsize.begin(), xsize.end(), std::ostream_iterator<double>(
132  outfile, " "));
133  outfile << endl;
134  //write out the cell sizes in y-direction
135  std::copy(ysize.begin(), ysize.end(), std::ostream_iterator<double>(
136  outfile, " "));
137  outfile << endl;
138  //write out the cell sizes in z-direction
139  std::copy(zsize.begin(), zsize.end(), std::ostream_iterator<double>(
140  outfile, " "));
141  outfile << endl;
142  //write out the resistivity values for each cell
143  //by looking up the resistivity from the index of each cell
144  for (i = 0; i < zlength; ++i)
145  {
146  outfile << i + 1 << endl;
147  for (j = 0; j < ylength; ++j)
148  {
149  for (k = 0; k < xlength; ++k)
150  outfile << LookupResistivity(Model[k][j][i]) << " ";
151  outfile << endl;
152  }
153  }
154  if (outfile.fail())
155  throw FatalException("Problem writing file: " + filename);
156  }
157 
158  void ThreeDMTModel::WriteMackie(std::string filename)
159  {
160  ofstream outfile(filename.c_str());
161  size_t i, j, k;
162  const size_t xlength = xsize.size();
163  const size_t ylength = ysize.size();
164  const size_t zlength = zsize.size();
165  //write out the number of values in each direction
166  outfile << xlength << " " << ylength << " " << zlength << endl;
167  //write out the cell sizes in x-direction
168  std::copy(xsize.begin(), xsize.end(), std::ostream_iterator<double>(
169  outfile, " "));
170  outfile << endl;
171  //write out the cell sizes in y-direction
172  std::copy(ysize.begin(), ysize.end(), std::ostream_iterator<double>(
173  outfile, " "));
174  outfile << endl;
175  //write out the cell sizes in z-direction
176  std::copy(zsize.begin(), zsize.end(), std::ostream_iterator<double>(
177  outfile, " "));
178  outfile << endl;
179  //write out the resistivity index for each cell
180  for (i = 0; i < zlength; ++i)
181  {
182  outfile << i + 1 << endl;
183  for (j = 0; j < ylength; ++j)
184  {
185  for (k = 0; k < xlength; ++k)
186  outfile << Model[k][j][i] << " ";
187  outfile << endl;
188  }
189  }
190  //write out the resistivities that correspond to each index
191  std::copy(Resistivities.begin(), Resistivities.end(),
192  std::ostream_iterator<double>(outfile, " "));
193  if (outfile.fail())
194  throw FatalException("Problem writing file: " + filename);
195  }
196 
197  void ThreeDMTModel::WriteNetCDF(std::string filename)
198  {
199  //prepare the netcdf file object
200  NcFile cdf(filename.c_str(), NcFile::Replace);
201  if (!cdf.is_valid())
202  throw FatalException("Problem writing cdf file");
203  //write dimension information
204  NcDim* xd = cdf.add_dim("x", xsize.size());
205  NcDim* yd = cdf.add_dim("y", ysize.size());
206  NcDim* zd = cdf.add_dim("z", zsize.size());
207  NcVar* x = cdf.add_var("x", ncDouble, xd);
208  //write some attributes to make the file understandable
209  x->add_att("units", "meters");
210  x->add_att("long_name", "x-coordinate in Cartesian system");
211  NcVar* y = cdf.add_var("y", ncDouble, yd);
212  y->add_att("units", "meters");
213  y->add_att("long_name", "y-coordinate in Cartesian system");
214  NcVar* z = cdf.add_var("z", ncDouble, zd);
215  z->add_att("units", "meters");
216  z->add_att("long_name", "z-coordinate in Cartesian system");
217  z->add_att("positive", "down");
218  NcVar* res = cdf.add_var("res", ncDouble, xd, yd, zd);
219  res->add_att("units", "ohm meters");
220  res->add_att("long_name", "Resistivity");
221  res->add_att("coordinates", "x y z");
222  std::vector<double> xvals, yvals, zvals, resvals;
223  //the netcdf file need the coordinates not the sizes
224  std::partial_sum(xsize.begin(), xsize.end(), std::back_inserter(xvals));
225  std::partial_sum(ysize.begin(), ysize.end(), std::back_inserter(yvals));
226  std::partial_sum(zsize.begin(), zsize.end(), std::back_inserter(zvals));
227  const size_t nres = Model.num_elements();
228  //get the resistivity values from the indices
229  std::transform(Model.origin(), Model.origin() + nres, back_inserter(
230  resvals), _1 = var(Resistivities)[_1]);
231  //store everything in the file
232  x->put(&xvals[0], xd->size());
233  y->put(&yvals[0], yd->size());
234  z->put(&zvals[0], zd->size());
235  res->put(&resvals[0], res->edges());
236  }
237 
238  void ThreeDMTModel::WriteVTK(std::string filename)
239  {
240  ofstream outfile(filename.c_str());
241  //write header information for the vtk file
242  //this is the legacy vtk format
243  outfile << "# vtk DataFile Version 2.0" << endl;
244  outfile << "3D Model data" << endl;
245  outfile << "ASCII" << endl;
246  outfile << "DATASET RECTILINEAR_GRID" << endl;
247  //we want to write grid cells, so we need one more value than cells
248  //this is for the left/right boundaries
249  outfile << "DIMENSIONS " << xsize.size() + 1 << " " << ysize.size() + 1
250  << " " << zsize.size() + 1 << endl;
251  //write out the information for each coordinate axis
252  outfile << "X_COORDINATES " << xsize.size() + 1 << " double" << endl;
253  double currcoord = 0.0;
254  outfile << currcoord << " ";
255  std::partial_sum(xsize.begin(),xsize.end(),std::ostream_iterator<double>(outfile," "));
256  outfile << endl;
257  outfile << "Y_COORDINATES " << ysize.size() + 1 << " double" << endl;
258  currcoord = 0;
259  outfile << currcoord << " ";
260  std::partial_sum(ysize.begin(),ysize.end(),std::ostream_iterator<double>(outfile," "));
261  outfile << endl;
262  outfile << "Z_COORDINATES " << zsize.size() + 1 << " double" << endl;
263  currcoord = 0;
264  outfile << currcoord << " ";
265  std::partial_sum(zsize.begin(),zsize.end(),std::ostream_iterator<double>(outfile," "));
266  outfile << endl;
267  outfile << "CELL_DATA " << xsize.size() * ysize.size() * zsize.size()
268  << endl;
269  outfile << "SCALARS Resistivity double" << endl;
270  outfile << "LOOKUP_TABLE default" << endl;
271  //and finally write out the resistivity values, x varies fastest
272  for (size_t i = 0; i < zsize.size(); ++i)
273  {
274  for (size_t j = 0; j < ysize.size(); ++j)
275  {
276  for (size_t k = 0; k < xsize.size(); ++k)
277  {
278  outfile << LookupResistivity(Model[k][j][i]) << " ";
279  }
280  outfile << endl;
281  }
282  }
283  if (outfile.fail())
284  throw FatalException("Problem writing vtk file");
285  }
286  }
void WriteNetCDF(const string name, const boost::numeric::ublas::matrix< double, boost::numeric::ublas::column_major > &Matrix)
Definition: mtuadaptive.cpp:36
The basic exception class for all errors that arise in gplib.