Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
create_dp.cpp
Go to the documentation of this file.
1 /*
2  * create_dp.cpp
3  *
4  * Created on: Dec 12, 2013
5  * just to add a "DP" tag to an already partitioned mesh, based on some formula
6  * it is launched in serial
7  */
8 #include "moab/Core.hpp"
9 #include "moab/Interface.hpp"
10 #include <iostream>
11 #include <cmath>
12 #include <cassert>
13 
15 #include "IntxUtilsCSLAM.hpp"
16 
17 #include <TestUtil.hpp>
18 
19 using namespace moab;
20 
21 double radius = 1.; // in m: 6371220.
22 int field_type = 1;
23 
25 {
26  Tag tagTracer = 0;
27  std::string tag_name( "Tracer" );
28  ErrorCode rval = mb.tag_get_handle( tag_name.c_str(), 1, MB_TYPE_DOUBLE, tagTracer, MB_TAG_DENSE | MB_TAG_CREAT );CHECK_ERR( rval );
29 
30  // tagElem is the average computed at each element, from nodal values
31  Tag tagElem = 0;
32  std::string tag_name2( "TracerAverage" );
33  rval = mb.tag_get_handle( tag_name2.c_str(), 1, MB_TYPE_DOUBLE, tagElem, MB_TAG_DENSE | MB_TAG_CREAT );CHECK_ERR( rval );
34 
35  Tag tagArea = 0;
36  std::string tag_name4( "Area" );
37  rval = mb.tag_get_handle( tag_name4.c_str(), 1, MB_TYPE_DOUBLE, tagArea, MB_TAG_DENSE | MB_TAG_CREAT );CHECK_ERR( rval );
38 
39  /*
40  * get all plys first, then vertices, then move them on the surface of the sphere
41  * radius is 1., most of the time
42  *
43  */
44  Range polygons;
45  rval = mb.get_entities_by_dimension( 0, 2, polygons );
46  if( MB_SUCCESS != rval ) return rval;
47 
48  Range connecVerts;
49  rval = mb.get_connectivity( polygons, connecVerts );
50  if( MB_SUCCESS != rval ) return rval;
51 
52  void* data; // pointer to the LOC in memory, for each vertex
53  int count;
54 
55  rval = mb.tag_iterate( tagTracer, connecVerts.begin(), connecVerts.end(), count, data );CHECK_ERR( rval );
56  // here we are checking contiguity
57  assert( count == (int)connecVerts.size() );
58  double* ptr_DP = (double*)data;
59  // lambda is for longitude, theta for latitude
60  // param will be: (la1, te1), (la2, te2), b, c; hmax=1, r=1/2
61  // nondivergent flow, page 5, case 1, (la1, te1) = (M_PI, M_PI/3)
62  // (la2, te2) = (M_PI, -M_PI/3)
63  // la1, te1 la2 te2 b c hmax r
64  if( field_type == 1 ) // quasi smooth
65  {
66  double params[] = { M_PI, M_PI / 3, M_PI, -M_PI / 3, 0.1, 0.9, 1., 0.5 };
67  for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit )
68  {
69  EntityHandle oldV = *vit;
70  CartVect posi;
71  rval = mb.get_coords( &oldV, 1, &( posi[0] ) );CHECK_ERR( rval );
72 
74 
75  ptr_DP[0] = IntxUtilsCSLAM::quasi_smooth_field( sphCoord.lon, sphCoord.lat, params );
76  ;
77 
78  ptr_DP++; // increment to the next node
79  }
80  }
81  else if( 2 == field_type ) // smooth
82  {
83  CartVect p1, p2;
85  spr.R = 1;
86  spr.lat = M_PI / 3;
87  spr.lon = M_PI;
89  spr.lat = -M_PI / 3;
91  // x1, y1, z1, x2, y2, z2, h_max, b0
92  double params[] = { p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], 1, 5. };
93  for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit )
94  {
95  EntityHandle oldV = *vit;
96  CartVect posi;
97  rval = mb.get_coords( &oldV, 1, &( posi[0] ) );CHECK_ERR( rval );
98 
100 
101  ptr_DP[0] = IntxUtilsCSLAM::smooth_field( sphCoord.lon, sphCoord.lat, params );
102  ;
103 
104  ptr_DP++; // increment to the next node
105  }
106  }
107  else if( 3 == field_type ) // slotted
108  {
109  // la1, te1, la2, te2, b, c, r
110  double params[] = { M_PI, M_PI / 3, M_PI, -M_PI / 3, 0.1, 0.9, 0.5 }; // no h_max
111  for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit )
112  {
113  EntityHandle oldV = *vit;
114  CartVect posi;
115  rval = mb.get_coords( &oldV, 1, &( posi[0] ) );CHECK_ERR( rval );
116 
118 
119  ptr_DP[0] = IntxUtilsCSLAM::slotted_cylinder_field( sphCoord.lon, sphCoord.lat, params );
120  ;
121 
122  ptr_DP++; // increment to the next node
123  }
124  }
125 
126  // add average value for quad/polygon (average corners)
127  // do some averages
128 
129  Range::iterator iter = polygons.begin();
130  // double local_mass = 0.; // this is total mass on one proc
131  while( iter != polygons.end() )
132  {
133  rval = mb.tag_iterate( tagElem, iter, polygons.end(), count, data );CHECK_ERR( rval );
134  double* ptr = (double*)data;
135 
136  rval = mb.tag_iterate( tagArea, iter, polygons.end(), count, data );CHECK_ERR( rval );
137  double* ptrArea = (double*)data;
138  for( int i = 0; i < count; i++, ++iter, ptr++, ptrArea++ )
139  {
140  const moab::EntityHandle* conn = NULL;
141  int num_nodes = 0;
142  rval = mb.get_connectivity( *iter, conn, num_nodes );CHECK_ERR( rval );
143  if( num_nodes == 0 ) return MB_FAILURE;
144  std::vector< double > nodeVals( num_nodes );
145  double average = 0.;
146  rval = mb.tag_get_data( tagTracer, conn, num_nodes, &nodeVals[0] );CHECK_ERR( rval );
147  for( int j = 0; j < num_nodes; j++ )
148  average += nodeVals[j];
149  average /= num_nodes;
150  *ptr = average;
151 
152  // now get area
153  std::vector< double > coords;
154  coords.resize( 3 * num_nodes );
155  rval = mb.get_coords( conn, num_nodes, &coords[0] );CHECK_ERR( rval );
156  IntxAreaUtils sphAreaUtils;
157  *ptrArea = sphAreaUtils.area_spherical_polygon( &coords[0], num_nodes, radius );
158 
159  // we should have used some
160  // total mass:
161  // local_mass += *ptrArea * average;
162  }
163  }
164 
165  // now we can delete the tags? not yet
166  return MB_SUCCESS;
167 }
168 
169 int main( int argc, char** argv )
170 {
171 
172  if( argc < 3 )
173  {
174  std::cout << " usage: create_dp <input> <output> -t <time> -dt <delta_t> [-skipdp] -f "
175  "<field> -h \n";
176  return 1;
177  }
178 
179  bool skip = false;
180  double dt = 0.1;
181  double t = 0.1; // corresponding to diffusion first step
182 
183  int index = 2;
184  char* input_mesh1 = argv[1];
185  char* output = argv[2];
186  while( index < argc )
187  {
188  if( !strcmp( argv[index], "-t" ) ) // this is for radius to project
189  {
190  t = atof( argv[++index] );
191  }
192  if( !strcmp( argv[index], "-dt" ) ) // delete partition sets
193  {
194  dt = atof( argv[++index] );
195  }
196 
197  if( !strcmp( argv[index], "-h" ) )
198  {
199  std::cout << " usage: create_dp <input> <output> -t <time> -dt <delta_t> [-skipdp] "
200  "-f <field> -h \n";
201  return 1;
202  }
203  if( !strcmp( argv[index], "-f" ) ) // delete partition sets
204  {
205  field_type = atoi( argv[++index] );
206  }
207 
208  if( !strcmp( argv[index], "-skipdp" ) )
209  {
210  skip = true;
211  }
212  index++;
213  }
214 
215  Core moab;
216  Interface& mb = moab;
217 
218  ErrorCode rval;
219 
220  rval = mb.load_mesh( input_mesh1 );
221 
222  std::cout << " -t " << t << " -dt " << dt << " input: " << input_mesh1 << " output: " << output << "\n";
223 
224  // skip if we need for DP (already existing)
225  if( skip )
226  {
227  std::cout << " do not add DP tag \n";
228  }
229  else
230  {
231  Range verts;
232  rval = mb.get_entities_by_dimension( 0, 0, verts );
233  if( MB_SUCCESS != rval ) return 1;
234 
235  double *x_ptr, *y_ptr, *z_ptr;
236  int count;
237  rval = mb.coords_iterate( verts.begin(), verts.end(), x_ptr, y_ptr, z_ptr, count );
238  if( MB_SUCCESS != rval ) return 1;
239  assert( count == (int)verts.size() ); // should end up with just one contiguous chunk of vertices
240 
241  Tag tagh = 0;
242  std::string tag_name( "DP" );
243  rval = mb.tag_get_handle( tag_name.c_str(), 3, MB_TYPE_DOUBLE, tagh, MB_TAG_DENSE | MB_TAG_CREAT );CHECK_ERR( rval );
244  void* data; // pointer to the LOC in memory, for each vertex
245  int count_tag;
246 
247  rval = mb.tag_iterate( tagh, verts.begin(), verts.end(), count_tag, data );CHECK_ERR( rval );
248  // here we are checking contiguity
249  assert( count_tag == (int)verts.size() );
250  double* ptr_DP = (double*)data;
251 
252  for( int v = 0; v < count; v++ )
253  {
254  // EntityHandle v = verts[v];
255  CartVect pos( x_ptr[v], y_ptr[v], z_ptr[v] );
256  CartVect newPos;
257  IntxUtilsCSLAM::departure_point_case1( pos, t, dt, newPos );
258  ptr_DP[0] = newPos[0];
259  ptr_DP[1] = newPos[1];
260  ptr_DP[2] = newPos[2];
261  ptr_DP += 3; // increment to the next vertex
262  }
263  }
264 
265  rval = add_field_value( mb );
266 
267  mb.write_file( output );
268 
269  return 0;
270 }