Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IM_Reader.h
Go to the documentation of this file.
1 /* *******************************************************************
2  * Rocstar Simulation Suite *
3  * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4  * *
5  * Illinois Rocstar LLC *
6  * Champaign, IL *
7  * www.illinoisrocstar.com *
8  * sales@illinoisrocstar.com *
9  * *
10  * License: See LICENSE file in top level of distribution package or *
11  * http://opensource.org/licenses/NCSA *
12  *********************************************************************/
13 /* *******************************************************************
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22  *********************************************************************/
23 // $Id: IM_Reader.h,v 1.10 2008/12/06 08:43:23 mtcampbe Exp $
24 
25 #ifndef IM_READER_H
26 #define IM_READER_H
27 
28 #include "../Rocsurf/include/surfbasic.h"
29 #include <vector>
30 #include <string>
31 #include <fstream>
32 #include <cstdlib>
33 #include <cstdio>
34 
36 
37 // This class provides an interface for reading in a surface mesh
38 // from the ".im" file.
39 class IM_Reader {
40 #ifndef isfinite /* this is a macro under Intel CC 8.0 */
41  bool isfinite( double x) { return x>-HUGE_VAL && x<HUGE_VAL; }
42 #endif
43 public:
44  // Constructor from an MPI communicator and a scale factor.
45  explicit IM_Reader( MPI_Comm comm=MPI_COMM_WORLD, double a=1) : _alpha(a) {
46  int flag; MPI_Initialized(&flag);
47  if ( !flag || comm == MPI_COMM_NULL) {
48  _rank = 0; _size = 1;
49  }
50  else {
51  MPI_Comm_rank( comm, &_rank);
52  MPI_Comm_size( comm, &_size);
53  }
54  }
55 
56  typedef bool (*Func_ptr)(int pane_id, int comm_rank, int comm_size);
57 
58  int read_winmesh( const char *fname, const std::string &wname,
59  bool del=true) {
60 
61  const char *lastdot=std::strrchr( fname, '.');
62  if ( lastdot && (std::strcmp( lastdot, ".hdf")==0 ||
63  std::strcmp( lastdot, ".cgns")==0 ||
64  std::strcmp( lastdot, ".txt")==0)) {
65  // Read in HDF format
67 
68  int IN_read;
69  if ( std::strcmp( lastdot, ".hdf") == 0 ||
70  std::strcmp( lastdot, ".cgns") == 0)
71  IN_read = COM_get_function_handle( "IN.read_window");
72  else
73  IN_read = COM_get_function_handle( "IN.read_by_control_file");
74 
75  COM_call_function( IN_read, fname, wname.c_str());
76 
77  int IN_obtain = COM_get_function_handle( "IN.obtain_attribute");
78  int mesh_hdl = COM_get_attribute_handle((wname+".mesh").c_str());
79  COM_call_function( IN_obtain, &mesh_hdl, &mesh_hdl);
81 
82  // Change the memory layout to contiguous.
83  COM_resize_array( (wname+".mesh").c_str(), 0, NULL, 0);
84 
85  if ( del) {
86  // Delete all attributes and leave alone the mesh.
87  COM_delete_attribute( (wname+".atts").c_str());
88  }
89 
90  int npanes; COM_get_panes( wname.c_str(), &npanes, NULL);
91  return npanes;
92  }
93  else if (!lastdot || std::strcmp( lastdot, ".im")) {
94  std::cerr << "Unknown file format with suffix " << lastdot << std::endl;
95  return -1;
96  }
97  return read_mesh( fname, wname, NULL);
98  }
99 
100  // Assuming the window has been created, read in the local panes from
101  // given file and return the number of local panes.
102  int read_mesh( const char *fname, const std::string &wname,
103  Func_ptr is_local) {
104  std::ifstream is( fname);
105  if ( is == NULL) {
106  std::cerr << "Error: Could not open file " << fname << std::endl;
107  exit(-1);
108  }
109 
110  // Create the window if not yet exist
111  int h=COM_get_window_handle(wname.c_str());
112  if ( h<=0) COM_new_window( wname.c_str());
113 
114  std::cout << "Reading file " << fname << std::endl;
115 
116  get_nextline( is, buf);
117  int num_panes, mesh_type;
118  char t;
119 
120  std::sscanf( buf, "%d%c%d", &num_panes, &t, &mesh_type);
121  if ( num_panes<=0) {
122  std::cerr << "Error: The number of panes must be positive." << std::endl;
123  exit(-1);
124  }
125 
126  int n=0;
127  switch (mesh_type) {
128  case 2: // Structured mesh
129  for ( int i=0; i<num_panes; ++i) {
130  get_nextline( is, buf);
131  int pid;
132  std::sscanf( buf, "%d", &pid);
133  if ( pid<=0) {
134  std::cerr << "Error: Found nonpositive pane id " << pid << std::endl;
135  exit(-1);
136  }
137 
138  bool local=(!is_local) || is_local( pid, _rank, _size);
139  n+=local;
140  read_pane_ij( is, wname, pid, local);
141  }
142  break;
143  case 3: // Unstrured mesh with 3-node triangles
144  case 4: // Unstrured mesh with 4-node quadrilaterals
145  case 6: // Unstrured mesh with 6-node triangles
146  for ( int i=0; i<num_panes; ++i) {
147  get_nextline( is, buf);
148  int pid;
149  std::sscanf( buf, "%d", &pid);
150  if ( pid<=0) {
151  std::cerr << "Error: Found nonpositive pane id " << pid << std::endl;
152  exit(-1);
153  }
154 
155  bool local=(!is_local) || is_local( pid, _rank, _size);
156  n+=local;
157  read_pane_uns( is, wname, pid, mesh_type, local);
158  }
159  break;
160  case 5: // Mixed mesh with 3-node triangles and 4-node quadrilaterals
161  for ( int i=0; i<num_panes; ++i) {
162  get_nextline( is, buf);
163  int pid;
164  std::sscanf( buf, "%d", &pid);
165  if ( pid<=0) {
166  std::cerr << "Error: Found nonpositive pane id " << pid << std::endl;
167  exit(-1);
168  }
169 
170  bool local=(!is_local) || is_local( pid, _rank, _size);
171  n+=local;
172  read_pane_mixed( is, wname, pid, local);
173  }
174  break;
175  default:
176  std::cerr << "Error: File: " << fname
177  << " has unknown mesh type" << mesh_type << std::endl;
178  exit(-1);
179  }
180  std::cout << "Finished reading file " << fname << std::endl;
181  return n;
182  }
183 
184 private:
185  void get_nextline( std::istream &is, char *str) {
186  char accpet[]={'0','1','2','3','4','5','6','7','8','9',
187  '.','+','-','e','E'};
188 
189  do {
190  if ( is.eof()) {
191  std::cerr << "Error: Unexpected EOF" << std::endl;
192  exit(-1);
193  }
194  is.getline( str, MAXLEN);
195  } while ( str[0]=='#' || strpbrk( str,accpet)==NULL);
196  }
197 
198  // Read in coordinates of a pane into a window if local
199  void read_pane_coors( std::istream &is, const std::string &wname,
200  int pid, int n, bool local) {
201  SURF::Point_3<double> *coors=NULL;
202 
203  if ( local) {
204  COM_set_size( (wname+".nc").c_str(), pid, n);
205  COM_allocate_array( (wname+".nc").c_str(), pid, &(void*&)coors);
206  }
207 
208  for ( int i=0; i<n; ++i) {
209  get_nextline( is, buf);
210  if ( local) {
211  std::sscanf( buf, "%lf %lf %lf", &coors[i][0], &coors[i][1], &coors[i][2]);
212  if (!isfinite( coors[i][0]) || !isfinite(coors[i][1]) ||
213  !isfinite( coors[i][2])) {
214  std::cerr << "Error: Got invalid coordinates " << coors[i]
215  << " for node " << i+1 << " on pane " << pid
216  << " of window " << wname << std::endl;
217  exit(-1);
218  }
219  }
220  }
221 
222  if ( local && _alpha!=1.)
223  for ( int i=0; i<n; ++i) {
224  coors[i][0]*=_alpha; coors[i][1]*=_alpha; coors[i][2]*=_alpha;
225  }
226  }
227 
228  // Read in element connectivity of a pane into a window if local
229  void read_pane_elems( std::istream &is, const std::string &wname, int pid,
230  int num_elems, int nodes_per_elem, bool local){
231  int *elems;
232 
233  const char *types[] = {".:t3:", ".:q4:", "", ".:t6:"};
234  if (local) {
235  COM_set_size( (wname+types[nodes_per_elem-3]).c_str(), pid, num_elems);
236  COM_allocate_array( (wname+types[nodes_per_elem-3]).c_str(),
237  pid, &(void*&)elems);
238  }
239 
240  for ( int i=0; i<num_elems; ++i) {
241  get_nextline( is, buf);
242  if (local) {
243  int *p = &elems[i*nodes_per_elem];
244  switch ( nodes_per_elem) {
245  case 3: std::sscanf( buf, "%d %d %d", p, p+1, p+2); break;
246  case 4: std::sscanf( buf, "%d %d %d %d", p, p+1, p+2, p+3); break;
247  case 6: std::sscanf( buf, "%d %d %d %d %d %d", p, p+1, p+2, p+3, p+4, p+5); break;
248  default: assert(false); abort();
249  }
250  }
251  }
252  }
253 
254  // Read in a structured pane into a window if local
255  void read_pane_ij( std::istream &is, const std::string &wname,
256  int pid, bool local) {
257  get_nextline( is, buf);
258  int dims[2];
259  std::sscanf( buf, "%d %d", &dims[0], &dims[1]);
260  if ( dims[0]<0 && dims[1]<0) {
261  std::cerr << "Error: Negative mesh dimension " << std::endl;
262  exit(-1);
263  }
264 
265  COM_set_array( (wname+".:st2:").c_str(), pid, dims);
266  read_pane_coors( is, wname, pid, dims[0]*dims[1], local);
267  }
268 
269  // Read in an unstructured pane into a window if local
270  void read_pane_uns( std::istream &is, const std::string &wname,
271  int pid, int nodes_per_elem, bool local) {
272  int num_nodes, num_elmes;
273 
274  get_nextline( is, buf);
275  std::sscanf( buf, "%d %d", &num_nodes, &num_elmes);
276  if ( num_nodes<0 || num_elmes<0) {
277  std::cerr << "Error: Negative node or element size" << std::endl;
278  exit(-1);
279  }
280 
281  read_pane_coors( is, wname, pid, num_nodes, local);
282  read_pane_elems( is, wname, pid, num_elmes, nodes_per_elem, local);
283  }
284 
285  // Read in a mixed pane into a window if local
286  void read_pane_mixed( std::istream &is, const std::string &wname,
287  int pid, bool local) {
288  int num_nodes, num_tris, num_quads;
289  get_nextline( is, buf);
290  std::sscanf( buf, "%d %d %d", &num_nodes, &num_tris, &num_quads);
291  if ( num_nodes<0 && num_tris<0 || num_quads<0) {
292  std::cerr << "Error: Negative node or element size" << std::endl;
293  exit(-1);
294  }
295 
296  read_pane_coors( is, wname, pid, num_nodes, local);
297  read_pane_elems( is, wname, pid, num_tris, 3, local);
298  read_pane_elems( is, wname, pid, num_quads, 4, local);
299  }
300 
301 private:
302  enum {MAXLEN=255};
303  char buf[MAXLEN+1];
304  double _alpha;
305  int _rank, _size;
306 };
307 
308 #endif
309 
310 
311 
312 
313 
314 
bool isfinite(double x)
Definition: IM_Reader.h:41
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_COMM_WORLD
void get_nextline(std::istream &is, char *str)
Definition: IM_Reader.h:185
void read_pane_coors(std::istream &is, const std::string &wname, int pid, int n, bool local)
Definition: IM_Reader.h:199
void COM_set_size(const char *wa_str, int pane_id, int size, int ng=0)
Set sizes of for a specific attribute.
Definition: roccom_c++.h:136
void read_pane_elems(std::istream &is, const std::string &wname, int pid, int num_elems, int nodes_per_elem, bool local)
Definition: IM_Reader.h:229
int _rank
Definition: IM_Reader.h:305
void read_pane_mixed(std::istream &is, const std::string &wname, int pid, bool local)
Definition: IM_Reader.h:286
int COM_get_attribute_handle(const char *waname)
Definition: roccom_c++.h:412
void COM_delete_attribute(const char *wa_str)
Delete an existing attribute.
Definition: roccom_c++.h:128
bool is_local(int pid, int comm_rank, int comm_size)
const int num_nodes
Definition: ex1.C:96
#define COM_UNLOAD_MODULE_STATIC_DYNAMIC(moduleName, windowString)
Definition: roccom_basic.h:113
char buf[MAXLEN+1]
Definition: IM_Reader.h:303
int read_mesh(const char *fname, const std::string &wname, Func_ptr is_local)
Definition: IM_Reader.h:102
bool(* Func_ptr)(int pane_id, int comm_rank, int comm_size)
Definition: IM_Reader.h:56
Definition: Rocin.h:64
blockLoc i
Definition: read.cpp:79
double _alpha
Definition: IM_Reader.h:304
void int int REAL * x
Definition: read.cpp:74
const NT & n
void COM_new_window(const char *wname, MPI_Comm c=MPI_COMM_NULL)
Definition: roccom_c++.h:86
void COM_call_function(const int wf, int argc,...)
Definition: roccom_c.C:48
void COM_allocate_array(const char *wa_str, int pane_id=0, void **addr=NULL, int strd=0, int cap=0)
Allocate space for an attribute on a specific pane and return the address by setting addr...
Definition: roccom_c++.h:196
void COM_set_array(const char *wa_str, int pane_id, void *addr, int strd=0, int cap=0)
Associates an array with an attribute for a specific pane.
Definition: roccom_c++.h:156
int COM_get_window_handle(const char *wname)
Definition: roccom_c++.h:404
IM_Reader(MPI_Comm comm=MPI_COMM_WORLD, double a=1)
Definition: IM_Reader.h:45
void COM_get_panes(const char *wname, std::vector< int > &pane_ids, int rank=-2)
Definition: roccom_c++.h:350
int read_winmesh(const char *fname, const std::string &wname, bool del=true)
Definition: IM_Reader.h:58
int _size
Definition: IM_Reader.h:305
void read_pane_uns(std::istream &is, const std::string &wname, int pid, int nodes_per_elem, bool local)
Definition: IM_Reader.h:270
#define COM_LOAD_MODULE_STATIC_DYNAMIC(moduleName, windowString)
Definition: roccom_basic.h:111
void read_pane_ij(std::istream &is, const std::string &wname, int pid, bool local)
Definition: IM_Reader.h:255
void COM_resize_array(const char *wa_str, int pane_id=0, void **addr=NULL, int strd=-1, int cap=0)
Resize an attribute on a specific pane and return the address by setting addr.
Definition: roccom_c++.h:200
int COM_get_function_handle(const char *wfname)
Definition: roccom_c++.h:428
#define COM_EXTERN_MODULE(moduleName)
Definition: roccom_basic.h:116