Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Rocon.C
Go to the documentation of this file.
1 #include <string>
2 #include <cmath>
3 #include <iostream>
4 #include <sstream>
5 
6 #include "Rocon.H"
7 #include "TRAIL.H"
8 #include "Parameters.H"
9 
11 
13 void Rocon::init_from_file( const char *inp, const int *ndiv )
14 {
15  if(!inp){
16  std::cout << "Rocon::Error: Called without an input file." << std::endl;
17  return;
18  }
19  std::string configfile(inp);
20  ifstream ConfigFile;
21  ConfigFile.open(configfile.c_str());
22  if(!ConfigFile){
23  std::cout << "Rocon::Error: Could not open configuration file, "
24  << configfile << std::endl;
25  return;
26  }
27  IRAD::Util::Parameters configparams;
28  configparams.ReadFromStream(ConfigFile);
29  ConfigFile.close();
30  std::string inpath(configparams.Param("constraint_surface"));
31  int verbosity = configparams.GetValue<int>("verbosity");
32  _transform_x = 1.0;
33  _transform_y = 1.0;
34  _transform_z = 1.0;
35  _transform = false;
36  if(!configparams.Param("transform_x").empty()){
37  _transform_x = configparams.GetValue<double>("transform_x");
38  _transform = true;
39  }
40  if(!configparams.Param("transform_y").empty()){
41  _transform_y = configparams.GetValue<double>("transform_y");
42  _transform = true;
43  }
44  if(!configparams.Param("transform_z").empty()){
45  _transform_z = configparams.GetValue<double>("transform_z");
46  _transform = true;
47  }
48  if(!configparams.Param("transform").empty()){
49  _transform_x = _transform_y = _transform_z = configparams.GetValue<double>("transform");
50  _transform = true;
51  }
52  if(verbosity > 1)
53  std::cout << "Rocon: Reading " << inpath << std::endl;
54  int numdiv = 100;
55  if(ndiv)
56  numdiv = *ndiv;
58  int IN_read;
59  IN_read = COM_get_function_handle( "PROPCONIN.read_window");
60  MPI_Comm comm_null = MPI_COMM_NULL;
61  std::string bufwin("bufwin");
62  COM_call_function( IN_read, inpath.c_str(), bufwin.c_str(), &comm_null);
63  int IN_obtain = COM_get_function_handle( "PROPCONIN.obtain_attribute");
64  int mesh_handle = COM_get_attribute_handle((bufwin+".mesh").c_str());
65  COM_call_function( IN_obtain, &mesh_handle, &mesh_handle);
67  COM_window_init_done(bufwin.c_str());
68  int init_handle = COM_get_function_handle((_wname+".initialize").c_str());
69  COM_get_attribute_handle((bufwin+".mesh").c_str());
70  COM_call_function(init_handle,&mesh_handle,&numdiv);
71  COM_delete_window(bufwin.c_str());
72 }
73 
74 void CheckCoordinates(double *coords,int number_of_points,double tol)
75 {
76  for(int i = 0; i < number_of_points*3;i++)
77  {
78  if(std::fabs(coords[i]) < tol && (coords[i] != 0.0)){
79  // std::cout << "Rocon> WARNING: node " << (i/3)+1 << "/"
80  // << number_of_points << " "
81  // << (((i%3)==0 ? "x " : ((i%3) < 2) ? "y " : "z "))
82  // << "coordinate = " << coords[i] << std::endl;
83  coords[i] = 0.0;
84  }
85  }
86 }
87 void TransformCoordinates(double *coords,int number_of_points,double xfac,double yfac,double zfac)
88 {
89  for(int i = 0; i < number_of_points;i++)
90  {
91  coords[i*3] *= xfac;
92  coords[i*3 + 1] *= yfac;
93  coords[i*3 + 2] *= zfac;
94  }
95 }
96 
98 void Rocon::initialize( const COM::Attribute *pmesh,const int *ndiv)
99 {
100  COM_assertion_msg( validate_object()==0, "Invalid object");
101  COM_assertion_msg( pmesh, "Mesh must be present");
102  _checked = false;
103 
104  COM::Window *win = const_cast<COM::Window*>(pmesh->window());
105  this->_comm = win->get_communicator();
106  if ( COMMPI_Initialized()) this->_rank = COMMPI_Comm_rank(this->_comm);
107  else this->_rank = 0;
108 
109  if(false){
110  double test_coords[21];
111  test_coords[0] = test_coords[1] = test_coords[2] = 0.0;
112  test_coords[3] = test_coords[7] = 1.0;
113  test_coords[4] = test_coords[5] = test_coords[8] = 0.0;
114  test_coords[6] = 0.5;
115  test_coords[9] = test_coords[11] = test_coords[14] = 0.0;
116  test_coords[10] = test_coords[12] = test_coords[13] = 1.0;
117  test_coords[15] = test_coords[18] = test_coords[19] = 0.0;
118  test_coords[16] = 1.0;
119  test_coords[17] = test_coords[20] = -1.0;
120  double test_point[3];
121  test_point[0] = test_point[1] = 0.5;
122  test_point[2] = 0.0;
123  double test_disp[3];
124  test_disp[0] = test_disp[1] = 0.0;
125  test_disp[2] = -1.0;
126  int test_conn[15];
127  test_conn[0] = 1;
128  test_conn[1] = 0;
129  test_conn[2] = 2;
130  test_conn[3] = 3;
131  test_conn[4] = 0;
132  test_conn[5] = 2;
133  test_conn[6] = 2;
134  test_conn[7] = 1;
135  test_conn[8] = 4;
136  test_conn[9] = 5;
137  test_conn[10] = 0;
138  test_conn[11] = 3;
139  test_conn[12] = 5;
140  test_conn[13] = 6;
141  test_conn[14] = 0;
142  double test_position[3];
143  MeshBndSurf testmbs;
144  testmbs.initialize(test_coords,test_conn,7,5,1);
145  if(testmbs.intersection(test_point,test_disp,test_position) && !_rank)
146  std::cout << "Rocon> Passed the test, found <" << test_position[0] << ","
147  << test_position[1] << "," << test_position[2] << " >" << std::endl;
148  else if(!_rank)
149  std::cout << "Rocon> FAILED THE TEST" << std::endl;
150  }
151 
152 
153  COM_new_window("tempwin");
154  // ensures contiguous layout
155  COM_clone_attribute("tempwin.mesh", (win->name()+".mesh").c_str(), 0);
156  COM_window_init_done("tempwin");
157 
158  int *connectivity = NULL;
159  double *nodal_coordinates = NULL;
160  std::vector<int> pane_ids;
161  COM_get_panes("tempwin",pane_ids);
162  COM_assertion_msg((pane_ids.size() == 1),"Too many panes in input mesh.");
163  COM_get_array("tempwin.nc",pane_ids[0],&nodal_coordinates);
164  COM_assertion_msg((nodal_coordinates != NULL),
165  "Failed to extract coordinates from input.");
166  COM_get_array("tempwin.:t3:real",pane_ids[0],&connectivity);
167  COM_assertion_msg((connectivity != NULL),
168  "Failed to extract surface triangles from input.");
169  int number_of_divisions = *ndiv;
170  int number_of_nodes = 0;
171  int number_of_elements = 0;
172  COM_get_size("tempwin.nc", pane_ids[0],&number_of_nodes);
173  COM_get_size("tempwin.:t3:real", pane_ids[0],&number_of_elements);
174  if(_transform){
175  if(!_rank)
176  std::cout << "Rocon> Transforming coordinates" << std::endl;
177  TransformCoordinates(nodal_coordinates,number_of_nodes,
179  }
180  if(!_rank){
181  std::cout << "Rocon> Checking input coordinates. " << std::endl;
182  }
183 
184  CheckCoordinates(nodal_coordinates,number_of_nodes,1.0e-9);
185  // Connectivity from Window is 1-based, change it to 0-based.
186  for(int i = 0;i < number_of_elements*3;i++)
187  connectivity[i] -= 1;
188  this->_mbs = new MeshBndSurf;
189  this->_mbs->initialize(nodal_coordinates,connectivity,number_of_nodes,
190  number_of_elements,number_of_divisions);
191  if(!_rank)
192  std::cout << "Rocon> Initialized constraint surface with "
193  << number_of_nodes << " nodes and "
194  << number_of_elements << " triangles. (ndiv = "
195  << *ndiv << ")" << std::endl;
196  if(false){
197  double test_point[6];
198  test_point[0] = test_point[1] = 0.0;
199  test_point[2] = 0.0599999999999;
200  test_point[3] = test_point[4] = 0.0;
201  test_point[5] = 0.06;
202  double test_disp[6];
203  test_disp[0] = test_disp[1] = 0.0;
204  test_disp[2] = 2e-9;
205  test_disp[3] = 2e-3;
206  test_disp[4] = 0.0;
207  test_disp[5] = 2e-3;
208  double test_position[3];
209  if(this->_mbs->intersection(test_point,test_disp,test_position) && !_rank)
210  std::cout << "Rocon> Passed the test2, found <" << test_position[0] << ","
211  << test_position[1] << "," << test_position[2] << " >" << std::endl;
212  else if(!_rank)
213  std::cout << "Rocon> FAILED THE TEST 2" << std::endl;
214 
215  if(this->_mbs->intersection(&(test_point[3]),&(test_disp[3]),test_position) && !_rank)
216  std::cout << "Rocon> Passed the test3, found <" << test_position[0] << ","
217  << test_position[1] << "," << test_position[2] << " >" << std::endl;
218  else if(!_rank)
219  std::cout << "Rocon> FAILED THE TEST 3" << std::endl;
220 
221  }
222  COM_delete_window("tempwin");
223 }
224 
227 void Rocon::burnout( const COM::Attribute *pmesh,
228  const COM::Attribute *cflag,
229  COM::Attribute *bflag)
230 {
231  COM_assertion_msg( validate_object()==0, "Invalid object");
232  COM_assertion_msg( pmesh, "Mesh must be present");
233  COM_assertion_msg( cflag, "Cflag must be present");
234  COM_assertion_msg( bflag, "Bflag must be present");
235 
236  COM::Window *meshwin = const_cast<COM::Window*>(pmesh->window());
237  COM::Window *cflagwin = const_cast<COM::Window*>(cflag->window());
238  COM::Window *bflagwin = const_cast<COM::Window*>(bflag->window());
239 
240  std::string meshwinname(meshwin->name());
241  std::string cflagwinname(cflagwin->name());
242  std::string bflagwinname(bflagwin->name());
243 
244  std::string cflagname(cflag->name());
245  std::string bflagname(bflag->name());
246 
247  unsigned int number_of_panes = 0;
248  std::vector<int> pane_ids;
249  COM_get_panes(meshwinname.c_str(),pane_ids);
250  number_of_panes = pane_ids.size();
251  int total_burned_out = 0;
252  int local_burned_out = 0;
253 
254  // First, make sure that nodes on nonburning panes are
255  // seen as "burned out" by the burnout processing.
256  // We need to be sure and remove this
257  std::vector<int>::iterator pii = pane_ids.begin();
258  while(pii != pane_ids.end()){
259  int pane_id = *pii++;
260  int *bcflag = NULL;
261  int nreal = 0;
262  int nghost = 0;
263  COM_get_array((cflagwinname+".bcflag").c_str(),pane_id,&bcflag);
264  if(bcflag != NULL){
265  if(*bcflag == 0 || *bcflag == 2){
266  int *constrained = NULL;
267  COM_get_array((cflagwinname+"."+cflagname).c_str(),pane_id,&constrained);
268  if(constrained){
269  COM_get_size((cflagwinname+"."+cflagname).c_str(),pane_id,&nreal,&nghost);
270  if(nreal > 0){
271  for(int i = 0;i < nreal;i++)
272  constrained[i] = 1;
273  }
274  }
275  }
276  }
277  }
278  pii = pane_ids.begin();
279  // std::vector<int>::iterator pii = pane_ids.begin();
280  while(pii != pane_ids.end()){
281  int *connectivity = NULL;
282  int *constrained = NULL;
283  int *burning = NULL;
284  int nreal = 0;
285  int nghost = 0;
286  int pane_id = *pii++;
287  COM_get_array((cflagwinname+"."+cflagname).c_str(),pane_id,&constrained);
288  if(constrained == NULL){
289  if(!_rank && _verbose)
290  std::cout << "Rocon> Skipping pane " << pane_id
291  << " which has no cflag array."
292  << std::endl;
293  continue;
294  }
295  int bflag_size = 0;
296  int bflag_ghosts = 0;
297  int bflag_stride = 0;
298  int bflag_cap = 0;
299  int *bcflag = NULL;
300  COM_get_array((bflagwinname+"."+bflagname).c_str(),pane_id,
301  &burning,&bflag_stride,&bflag_cap);
302  // COM_get_array((bflagwinname+"."+bflagname).c_str(),pane_id,
303  // &bcflag);
304  bool burning_pane = (burning != NULL);
305  // if(bcflag && burning)
306  // if(*bcflag == 1)
307  // burning_pane = true;
308  // if(!burning_pane){
309  // if(!_rank && _verbose)
310  // std::cout << "Rocon> Skipping pane " << pane_id
311  // << " which has no matching bflag array." << std::endl;
312  // continue;
313  // }
314  if(burning_pane)
315  COM_get_size((bflagwinname+"."+bflagname).c_str(),pane_id,
316  &bflag_size,&bflag_ghosts);
317  // has a cflag array, should be processed
318  Mesh::Connectivity pane_conn;
319  COM_get_size((cflagwinname+".nc").c_str(),pane_id,&nreal,&nghost);
320  if(_rank==0 && _verbose){
321  std::cout << "Rocon> Burning out window " << cflagwinname
322  << " with " << nghost << " ghost nodes." << std::endl
323  << "Rocon> Bflag stats: size = " << bflag_size
324  << ", nghosts = " << bflag_ghosts
325  << ", stride = " << bflag_stride << ", cap = "
326  << bflag_cap << std::endl;
327  }
328  int nnodes = nreal;
329  int nreal_nodes = nreal-nghost;
330  int nghost_nodes = nghost;
331  nreal = nghost = 0;
332 
333  COM_get_size((cflagwinname+".conn").c_str(),pane_id,&nreal,&nghost);
334  if(nghost > 0 && !_rank){
335  std::cout << "Rocon> Burning out window " << cflagwinname << " with "
336  << nghost << " ghost elements." << std::endl;
337  }
338  int nelem = nreal;
339  int nreal_elem = nreal - nghost;
340  int nghost_elem = nghost;
341  nreal = nghost = 0;
342  if((nelem == 0 || nnodes == 0) && !_rank && _verbose){
343  std::cout << "Rocon> Empty pane " << pane_id << " on window "
344  << cflagwinname << "." << std::endl;
345  continue;
346  }
347  // Obtain the connectivity tables
348  int nmeshtypes; // Number of connectivity tables
349  std::string connNames; // Names of connectivity tables separated by space
350  COM_get_connectivities(cflagwinname.c_str(), pane_id,
351  &nmeshtypes, connNames);
352  int ndims;
353  const int* dims = NULL;
354  char elemType = '\0';
355  int eTotal = 0;
356  // std::vector<ConnInfo> connInfo(nConn);
357  if (nmeshtypes == 1 && (connNames.find(":st") != std::string::npos))
358  {
359  // Structured mesh
360  if(!_rank && _verbose){
361  std::cout << "Rocon> Processing block structured mesh."
362  << std::endl;
363  }
364  COM_get_size((cflagwinname+"."+connNames).c_str(), pane_id,
365  &nreal, &nghost);
366  COM_get_array_const((cflagwinname+"."+connNames).c_str(),
367  pane_id, &dims);
368  int ndims = nreal;
369  int nghost_layers = nghost;
370  // nghost is wrt element layers, dims are wrt nodes
371  if(!_rank && _verbose){
372  std::cout << "Rocon> Conn size (dimension,ghost) = ("
373  << ndims << "," << nghost_layers << std::endl
374  << "Rocon> dims: ";
375  for(int i = 0;i < ndims;i++){
376  std::cout << dims[i];
377  if(i != (ndims-1))
378  std::cout << ",";
379  }
380  std::cout << std::endl;
381  }
382  std::vector<Mesh::IndexType> flat_extent(6,0);
383  for(int i = 0;i < ndims;i++){
384  flat_extent[i*2] = 1;
385  flat_extent[i*2+1] = dims[i];
386  }
387  for(int i = 0;i < 6;i++)
388  if(flat_extent[i] == 0)
389  flat_extent[i] = 1;
390  Mesh::BSExtent<Mesh::IndexType> bsextent(flat_extent);
391  bsextent.CreateUnstructuredMesh(pane_conn);
392  if(!_rank && _verbose){
393  std::cout << "Rocon> Pane Connectivity has " << pane_conn.Nelem()
394  << " elements of size " << pane_conn.Esize(1) << std::endl
395  << "Rocon> First elem: (" << pane_conn.Node(1,1) << ","
396  << pane_conn.Node(1,2) << "," << pane_conn.Node(1,3) << ","
397  << pane_conn.Node(1,4) << ")" << std::endl;
398  }
399  }
400  else
401  {
402  if(!_rank && _verbose)
403  std::cout << "Rocon> Processing unstructured mesh" << std::endl;
404  Mesh::Connectivity ghost_conn;
405  std::istringstream Istr(connNames);
406  std::string ucname;
407  int nnodes_per_element;
408  while(Istr >> ucname){
409  int *conn = NULL;
410  int stride = 0;
411  int cap = 0;
412  int nelem = 0;
413  nghost = 0;
414  std::string fullname(cflagwinname + "." + ucname);
415  COM_get_size(fullname.c_str(),pane_id,&nelem,&nghost);
416  COM_get_array(fullname.c_str(),pane_id,&conn,&stride,&cap);
417  if(!_rank && _verbose)
418  std::cout << "Rocon> Found connectivity " << ucname
419  << " for pane " << pane_id
420  << ", with size: " << nelem << ", and "
421  << nghost << " ghosts. Stride = "
422  << stride << ", and cap = " << cap << std::endl;
423  int npe = 9;
424  if(ucname.find("t3") != std::string::npos)
425  npe = 3;
426  else if(ucname.find("t6") != std::string::npos)
427  npe = 6;
428  else if(ucname.find("q4") != std::string::npos)
429  npe = 4;
430  else if(ucname.find("q8") != std::string::npos)
431  npe = 8;
432  else if(ucname.find("q9") != std::string::npos)
433  npe = 9;
434  else{
435  std::string msg("Rocon> Unknown connectivity type: "+ucname);
436  COM_assertion_msg(false,msg.c_str());
437  }
438  if(stride == 0)
439  stride = 1;
440  for(int j = 0;j < nelem;j++){
441  std::vector<Mesh::IndexType> new_element(npe,0);
442  if(stride == 1)
443  for(int k = 0;k < npe;k++)
444  new_element.push_back(conn[j*npe+k]);
445  else
446  for(int k = 0;k < npe;k++)
447  new_element.push_back(conn[j+k*stride]);
448  pane_conn.AddElement(new_element);
449  }
450  }
451  }
452  pane_conn.Sync();
453  // Now Burnout on this pane if it is burning
454  if(burning_pane){
455  for(int j = 0;j < pane_conn.Nelem();j++){
456  std::vector<Mesh::IndexType>::iterator ei = pane_conn[j].begin();
457  bool all_burned_out = true;
458  while(ei != pane_conn[j].end() && all_burned_out)
459  if(constrained[*ei++-1] == 0)
460  all_burned_out = false;
461  if(all_burned_out){
462  burning[j] = 0;
463  local_burned_out++;
464  }
465  }
466  }
467  // experimental, set stupid cflag to 1 for nonburning panes
468  else {
469  for(int j = 0;j < pane_conn.Nelem();j++){
470  std::vector<Mesh::IndexType>::iterator ei = pane_conn[j].begin();
471  while(ei != pane_conn[j].end())
472  constrained[*ei++-1] = 1;
473  }
474  }
475  }
476  MPI_Reduce(&local_burned_out,&total_burned_out,
477  1,MPI_INTEGER,MPI_SUM,0,_comm);
478  if(!_rank && _verbose)
479  std::cout << "Rocon> Burned out " << total_burned_out << " elements."
480  << std::endl;
481  // if(nghost > 0)
482  // number_of_nodes -= nghost;
483  // if(!_checked){
484  // std::cout << "Rocon> Checking coords for pane " << pane_id << std::endl;
485  // CheckCoordinates(original_coordinates,number_of_nodes,1e-9);
486  // }
487 }
488 
491 void Rocon::burnout_filter( const COM::Attribute *bflag,
492  COM::Attribute *target)
493 {
494  COM_assertion_msg( validate_object()==0, "Invalid object");
495  COM_assertion_msg( bflag, "Bflag must be present");
496  COM_assertion_msg( target, "Target attribute must be present");
497 
498  COM::Window *targwin = const_cast<COM::Window*>(target->window());
499  COM::Window *bflagwin = const_cast<COM::Window*>(bflag->window());
500 
501  std::string targwinname(targwin->name());
502  std::string bflagwinname(bflagwin->name());
503 
504  std::string targname(target->name());
505  std::string bflagname(bflag->name());
506 
507  unsigned int number_of_panes = 0;
508  std::vector<int> pane_ids;
509  COM_get_panes(targwinname.c_str(),pane_ids);
510  number_of_panes = pane_ids.size();
511  int local_nfiltered = 0;
512  int global_nfiltered = 0;
513  std::vector<int>::iterator pii = pane_ids.begin();
514  while(pii != pane_ids.end()){
515  int *burning = NULL;
516  double *targ = NULL;
517  int targ_size = 0;
518  int bflag_size = 0;
519  int bflag_ghosts = 0;
520  int targ_ghosts = 0;
521  int pane_id = *pii++;
522  COM_get_array((bflagwinname+"."+bflagname).c_str(),pane_id,&burning);
523  COM_get_array((targwinname+"."+targname).c_str(),pane_id,&targ);
524  if(burning && targ){
525  COM_get_size((bflagwinname+"."+bflagname).c_str(),pane_id,
526  &bflag_size,&bflag_ghosts);
527  COM_get_size((targwinname+"."+targname).c_str(),pane_id,
528  &targ_size,&targ_ghosts);
529  assert(targ_size == bflag_size);
530  if(_rank==0 && _verbose){
531  std::cout << "Rocon> Burning out " << targname << " on "
532  << targwinname << std::endl
533  << "Rocon> Target stats: size = " << targ_size
534  << ", nghosts = " << targ_ghosts << std::endl;
535  }
536  for(int i = 0;i < targ_size;i++)
537  if(burning[i] == 0){
538  local_nfiltered++;
539  targ[i] = 0.0;
540  }
541  }
542  }
543  MPI_Reduce(&local_nfiltered,&global_nfiltered,
544  1,MPI_INTEGER,MPI_SUM,0,_comm);
545  if(!_rank && _verbose)
546  std::cout << "Rocon> Burnout filtered " << global_nfiltered << " elements."
547  << std::endl;
548 }
549 
557 void Rocon::find_intersections( const COM::Attribute *pmesh,
558  const COM::Attribute *disp,
559  COM::Attribute *pos,
560  COM::Attribute *constr)
561 {
562  COM_assertion_msg( validate_object()==0, "Invalid object");
563  COM_assertion_msg( pmesh, "Mesh must be present");
564  COM_assertion_msg( disp, "Displacements must be present");
565  COM_assertion_msg( pos, "Positions att must be present");
566 
567  COM::Window *meshwin = const_cast<COM::Window*>(pmesh->window());
568  COM::Window *dispwin = const_cast<COM::Window*>(disp->window());
569  COM::Window *poswin = const_cast<COM::Window*>(pos->window());
570  COM::Window *conwin = const_cast<COM::Window*>(constr->window());
571 
572  std::string meshwinname(meshwin->name());
573  std::string dispwinname(dispwin->name());
574  std::string poswinname(poswin->name());
575  std::string conwinname(conwin->name());
576 
577  std::string dispname(disp->name());
578  std::string posname(pos->name());
579  std::string conname(constr->name());
580 
581  unsigned int number_of_panes = 0;
582  std::vector<int> pane_ids;
583  COM_get_panes(meshwinname.c_str(),pane_ids);
584  number_of_panes = pane_ids.size();
585 
586  std::vector<int> paneids;
587  COM_get_panes(dispwinname.c_str(),paneids);
588  COM_assertion_msg(paneids.size() == number_of_panes,
589  "Number of panes must match.");
590  COM_get_panes(poswinname.c_str(),paneids);
591  COM_assertion_msg(paneids.size() == number_of_panes,
592  "Number of panes must match.");
593  COM_get_panes(conwinname.c_str(),paneids);
594  COM_assertion_msg(paneids.size() == number_of_panes,
595  "Number of panes must match.");
596 
597  std::vector<int>::iterator pii = pane_ids.begin();
598  int local_number_constrained = 0;
599  int local_number_checked = 0;
600  int global_number_constrained = 0;
601  int global_number_checked = 0;
602  while(pii != pane_ids.end()){
603  double *original_coordinates = NULL;
604  double *displacements = NULL;
605  double *positions = NULL;
606  int *constrained = NULL;
607  int number_of_nodes = 0;
608  int nghost = 0;
609  int pane_id = *pii++;
610  COM_get_array((meshwinname+".nc").c_str(),pane_id,&original_coordinates);
611  COM_get_size((meshwinname+".nc"),pane_id,&number_of_nodes,&nghost);
612  if(nghost > 0)
613  number_of_nodes -= nghost;
614  if(!_checked){
615  // std::cout << "Rocon> Checking coords for pane " << pane_id << std::endl;
616  CheckCoordinates(original_coordinates,number_of_nodes,1e-9);
617  }
618  COM_get_array((dispwinname+"."+dispname).c_str(),pane_id,&displacements);
619  COM_get_array((poswinname+"."+posname).c_str(),pane_id,&positions);
620  COM_get_array((conwinname+"."+conname).c_str(),pane_id,&constrained);
621  if(constrained == NULL && !_rank && _verbose) {
622  std::cout << "Rocon> Skipping pane " << pane_id << " for no cflag." << std::endl;
623  }
624  if((constrained != NULL) && (number_of_nodes > 0)){
625  // In an attempt to fix some problems, a check is added here to see if this
626  // is a burning pane. If not, then it'll set all nodes to "constrained" on
627  // that pane. Hopefully this will help sticky elements finally burn out
628  // and keep nonburning panes from getting jerked around anomalously.
629  int *burning_flag = NULL;
630  int *bcflag = NULL;
631  COM_get_array((conwinname+".bflag").c_str(),pane_id,&burning_flag);
632  // COM_get_array((conwinname+".bcflag").c_str(),pane_id,&bcflag);
633  // bool pane_is_burning = true;
634  // if((bcflag != NULL) && (burning_flag != NULL))
635  // if(*bcflag == 1)
636  // pane_is_burning = true;
637  bool pane_is_burning = (burning_flag != NULL);
638  if(pane_is_burning)
639  local_number_checked += number_of_nodes;
640  for(int i = 0;i < number_of_nodes;i++){
641  // could check here if they are already constrained going in,
642  // then just set disp to 0 else perform the check below. disp
643  // to 0 and/or positions to current pos.
644  // if(constrained[i] == 0){
645  if(pane_is_burning){
646  double point[3];
647  double disp[3];
648  point[0] = original_coordinates[i*3] - displacements[i*3];
649  point[1] = original_coordinates[i*3+1] - displacements[i*3+1];
650  point[2] = original_coordinates[i*3+2] - displacements[i*3+2];
651  disp[0] = 2.0*displacements[i*3];
652  disp[1] = 2.0*displacements[i*3+1];
653  disp[2] = 2.0*displacements[i*3+2];
654  //point[0] = original_coordinates[i*3] - displacements[i*3];
655  // point[1] = original_coordinates[i*3+1] - displacements[i*3+1];
656  //point[2] = original_coordinates[i*3+2] - displacements[i*3+2];
657  //disp[0] = 2.0*displacements[i*3];
658  //disp[1] = 2.0*displacements[i*3+1];
659  //disp[2] = 2.0*displacements[i*3+2];
660  // if(this->_mbs->intersection(&original_coordinates[i*3],
661  // &displacements[i*3],&positions[i*3])){
662  if(this->_mbs->intersection(point,disp,&positions[i*3])){
663  local_number_constrained++;
664  constrained[i] = 1;
665  }
666  else{
667  positions[i*3] = original_coordinates[i*3] + displacements[i*3];
668  positions[i*3+1] = original_coordinates[i*3+1] + displacements[i*3+1];
669  positions[i*3+2] = original_coordinates[i*3+2] + displacements[i*3+2];
670  }
671 
672  }
673  else{
674  constrained[i] = 1;
675  // Experimental - 0 out displacements
676  // displacements[i*3] = 0.0;
677  // displacements[i*3+1] = 0.0;
678  // displacements[i*3+2] = 0.0;
679  }
680  // }
681  // else{
682  // displacements[i*3] = 0.0;
683  // displacements[i*3+1] = 0.0;
684  // displacements[i*3+2] = 0.0;
685  // }
686  }
687  }
688  }
689  this->_comm = meshwin->get_communicator();
690  if ( COMMPI_Initialized()) this->_rank = COMMPI_Comm_rank(this->_comm);
691  else this->_rank = 0;
692  MPI_Reduce(&local_number_constrained,&global_number_constrained,
693  1,MPI_INTEGER,MPI_SUM,0,_comm);
694  MPI_Reduce(&local_number_checked,&global_number_checked,
695  1,MPI_INTEGER,MPI_SUM,0,_comm);
696  if(!_rank){
697  std::cout << "Rocon> Checked " << global_number_checked
698  << " nodes." << std::endl;
699  std::cout << "Rocon> Found " << global_number_constrained
700  << " intersections." << std::endl;
701  }
702  // _checked = true;
703 }
704 
706 void Rocon::constrain_displacements( const COM::Attribute *pmesh,
707  COM::Attribute *disp,
708  const COM::Attribute *pos,
709  const COM::Attribute *constr)
710 {
711  COM_assertion_msg( validate_object()==0, "Invalid object");
712  COM_assertion_msg( pmesh, "Mesh must be present");
713  COM_assertion_msg( disp, "Displacements must be present");
714  COM_assertion_msg( pos, "Positions must be present");
715 
716  COM::Window *meshwin = const_cast<COM::Window*>(pmesh->window());
717  COM::Window *dispwin = const_cast<COM::Window*>(disp->window());
718  COM::Window *poswin = const_cast<COM::Window*>(pos->window());
719  COM::Window *conwin = const_cast<COM::Window*>(constr->window());
720 
721  std::string meshwinname(meshwin->name());
722  std::string dispwinname(dispwin->name());
723  std::string poswinname(poswin->name());
724  std::string conwinname(conwin->name());
725 
726  std::string dispname(disp->name());
727  std::string posname(pos->name());
728  std::string conname(constr->name());
729 
730  unsigned int number_of_panes = 0;
731  std::vector<int> pane_ids;
732  COM_get_panes(meshwinname.c_str(),pane_ids);
733  number_of_panes = pane_ids.size();
734 
735  std::vector<int> paneids;
736  COM_get_panes(dispwinname.c_str(),paneids);
737  COM_assertion_msg(paneids.size() == number_of_panes,
738  "Number of panes must match.");
739  COM_get_panes(poswinname.c_str(),paneids);
740  COM_assertion_msg(paneids.size() == number_of_panes,
741  "Number of panes must match.");
742  COM_get_panes(conwinname.c_str(),paneids);
743  COM_assertion_msg(paneids.size() == number_of_panes,
744  "Number of panes must match.");
745 
746  std::vector<int>::iterator pii = pane_ids.begin();
747  int local_number_checked = 0;
748  int global_number_checked = 0;
749  int local_number_constrained = 0;
750  int global_number_constrained = 0;
751  while(pii != pane_ids.end()){
752  double *original_coordinates = NULL;
753  double *displacements = NULL;
754  double *positions = NULL;
755  int *constrained = NULL;
756  int number_of_nodes = 0;
757  int nghost = 0;
758  int pane_id = *pii++;
759  COM_get_array((meshwinname+".nc").c_str(),pane_id,&original_coordinates);
760  COM_get_size((meshwinname+".nc"),pane_id,&number_of_nodes,&nghost);
761  if(nghost > 0)
762  number_of_nodes -= nghost;
763  COM_get_array((dispwinname+"."+dispname).c_str(),pane_id,&displacements);
764  COM_get_array((poswinname +"."+posname).c_str(),pane_id,&positions);
765  COM_get_array((conwinname +"."+conname).c_str(),pane_id,&constrained);
766  if((constrained != NULL) && (number_of_nodes > 0)){
767  int *burning_flag = NULL;
768  int *bcflag = NULL;
769  COM_get_array((conwinname+".bflag").c_str(),pane_id,&burning_flag);
770  // COM_get_array((conwinname+".bcflag").c_str(),pane_id,&bcflag);
771  bool pane_is_burning = (burning_flag != NULL);
772  // if(bcflag && burning_flag)
773  // if(*bcflag == 1)
774  // pane_is_burning = true;
775  if(pane_is_burning){
776  local_number_checked += number_of_nodes;
777  for(int i = 0;i < number_of_nodes;i++){
778  if(constrained[i] == 1){
779  local_number_constrained++;
780  displacements[i*3] = positions[i*3] - original_coordinates[i*3];
781  displacements[i*3+1] = positions[i*3+1] - original_coordinates[i*3+1];
782  displacements[i*3+2] = positions[i*3+2] - original_coordinates[i*3+2];
783  // experimental, just stop them
784  // displacements[i*3] = 0.0;
785  // displacements[i*3+1] = 0.0;
786  // displacements[i*3+2] = 0.0;
787  if(std::fabs(displacements[i*3]) <= this->_TOL)
788  displacements[i*3] = 0;
789  if(std::fabs(displacements[i*3+1]) <= this->_TOL)
790  displacements[i*3+1] = 0;
791  if(std::fabs(displacements[i*3+2]) <= this->_TOL)
792  displacements[i*3+2] = 0;
793  }
794  }
795  }
796  }
797  }
798  this->_comm = meshwin->get_communicator();
799  if ( COMMPI_Initialized()) this->_rank = COMMPI_Comm_rank(this->_comm);
800  else this->_rank = 0;
801  MPI_Reduce(&local_number_constrained,&global_number_constrained,
802  1,MPI_INTEGER,MPI_SUM,0,_comm);
803  if(!_rank){
804  std::cout << "Rocon> Constrained " << global_number_constrained
805  << " nodes." << std::endl;
806  }
807 
808 
809 }
810 
811 
812 
813 void Rocon::load( const std::string &mname) {
814  Rocon *rp = new Rocon();
815  COM_new_window( mname.c_str());
816  rp->WindowName() = mname;
817  rp->SetVerbosity(1);
818  std::string glb=mname+".global";
819  COM_new_attribute( glb.c_str(), 'w', COM_VOID, 1, "");
820  COM_set_object( glb.c_str(), 0, rp);
821 
822  COM_Type types[5];
823 
824  types[0] = COM_RAWDATA;
825  types[2] = COM_INT;
826  types[1] = types[3] = types[4] = COM_METADATA;
827  COM_set_member_function( (mname+".initialize").c_str(),
828  (Member_func_ptr)(&Rocon::initialize),
829  glb.c_str(), "bii", types);
830 
831  types[1] = COM_STRING;
832  COM_set_member_function( (mname+".init_from_file").c_str(),
833  (Member_func_ptr)(&Rocon::init_from_file),
834  glb.c_str(),"bii", types);
835  types[1] = COM_METADATA;
836  types[2] = COM_METADATA;
837  COM_set_member_function( (mname+".find_intersections").c_str(),
838  (Member_func_ptr)(&Rocon::find_intersections),
839  glb.c_str(), "biiob", types);
840  COM_set_member_function( (mname+".constrain_displacements").c_str(),
841  (Member_func_ptr)(&Rocon::constrain_displacements),
842  glb.c_str(), "bibii", types);
843 
844  COM_set_member_function( (mname+".burnout").c_str(),
845  (Member_func_ptr)(&Rocon::burnout),
846  glb.c_str(), "biib", types);
847 
848  COM_set_member_function( (mname+".burnout_filter").c_str(),
849  (Member_func_ptr)(&Rocon::burnout_filter),
850  glb.c_str(), "bib", types);
851 
852 
853  COM_window_init_done( mname.c_str());
854 }
855 
856 void Rocon::unload( const std::string &mname) {
857  Rocon *rp;
858  std::string glb=mname+".global";
859 
860  COM_get_object( glb.c_str(), 0, &rp);
861 
862  COM_assertion_msg( rp->validate_object()==0, "Invalid object");
863 
864  delete rp;
865  COM_delete_window( mname.c_str());
866 }
867 
868 // C/C++ binding
869 extern "C" void Rocon_load_module( const char *name)
870 { Rocon::load( std::string(name)); }
871 extern "C" void Rocon_unload_module( const char *name)
872 { Rocon::unload( std::string(name)); }
873 
874 // Fortran binding
875 extern "C" void rocon_load_module( const char *name, long int length)
876 { Rocon::load( std::string(name, length)); }
877 extern "C" void rocon_unload_module( const char *name, long int length)
878 { Rocon::unload( std::string(name, length)); }
879 
880 extern "C" void ROCON_LOAD_MODULE( const char *name, long int length)
881 { Rocon::load( std::string(name, length)); }
882 extern "C" void ROCON_UNLOAD_MODULE( const char *name, long int length)
883 { Rocon::unload( std::string(name, length)); }
884 
885 extern "C" void rocon_load_module_( const char *name, long int length)
886 { Rocon::load( std::string(name, length)); }
887 extern "C" void rocon_unload_module_( const char *name, long int length)
888 { Rocon::unload( std::string(name, length)); }
889 
890 extern "C" void ROCON_LOAD_MODULE_( const char *name, long int length)
891 { Rocon::load( std::string(name, length)); }
892 extern "C" void ROCON_UNLOAD_MODULE_( const char *name, long int length)
893 { Rocon::unload( std::string(name, length)); }
int COMMPI_Comm_rank(MPI_Comm c)
Definition: commpi.h:162
double _transform_x
Definition: Rocon.H:107
void Sync()
Definition: Mesh.C:246
void find_intersections(const COM::Attribute *pmesh, const COM::Attribute *disp, COM::Attribute *pos, COM::Attribute *constr)
Displace the points in pmesh by disp and calcuate the intersections (if any) with the constraint mesh...
Definition: Rocon.C:557
int COM_Type
Indices for derived data types.
Definition: roccom_basic.h:122
int _verbose
Definition: Rocon.H:98
void AddElement(const std::vector< IndexType > &elem)
Definition: Mesh.C:235
General connectivity object.
Definition: Mesh.H:334
void rocon_load_module_(const char *name, long int length)
Definition: Rocon.C:885
void init_from_file(const char *inp, const int *ndiv)
Initialize Rocon from the given file.
Definition: Rocon.C:13
void COM_delete_window(const char *wname)
Definition: roccom_c++.h:94
j indices k indices k
Definition: Indexing.h:6
void CreateUnstructuredMesh(Connectivity &conn)
Definition: BSMesh.H:199
#define COM_assertion_msg(EX, msg)
static void unload(const std::string &mname)
Definition: Rocon.C:856
void Rocon_unload_module(const char *name)
Definition: Rocon.C:871
void constrain_displacements(const COM::Attribute *pmesh, COM::Attribute *disp, const COM::Attribute *pos, const COM::Attribute *constr)
Constrain the displacements, disp, to the appropriate positions, pos.
Definition: Rocon.C:706
void ROCON_LOAD_MODULE(const char *name, long int length)
Definition: Rocon.C:880
void ROCON_LOAD_MODULE_(const char *name, long int length)
Definition: Rocon.C:890
void COM_get_array(const char *wa_str, int pane_id, void **addr, int *strd, int *cap)
Get the address for an attribute on a specific pane.
void CheckCoordinates(double *coords, int number_of_points, double tol)
Definition: Rocon.C:74
bool _transform
Definition: Rocon.H:110
void COM_set_object(const char *wa_str, int pane_id, Type *addr)
Definition: roccom_c++.h:144
int COM_get_attribute_handle(const char *waname)
Definition: roccom_c++.h:412
void ROCON_UNLOAD_MODULE(const char *name, long int length)
Definition: Rocon.C:882
double _transform_z
Definition: Rocon.H:109
void COM_get_connectivities(const char *wname, int pane_id, int *nc, std::string &names)
Definition: roccom_c++.h:363
double length(Vector3D *const v, int n)
void COM_get_object(const char *wa_str, int pane_id, Type **addr)
Definition: roccom_c++.h:152
int _rank
Definition: Rocon.H:101
std::string & WindowName()
Definition: Rocon.H:92
void burnout_filter(const COM::Attribute *bflag, COM::Attribute *target)
Sets target = 0 for every burning pane element on which bflag = 0.
Definition: Rocon.C:491
#define COM_UNLOAD_MODULE_STATIC_DYNAMIC(moduleName, windowString)
Definition: roccom_basic.h:113
void rocon_unload_module(const char *name, long int length)
Definition: Rocon.C:877
IndexType & Node(IndexType e, IndexType n)
Definition: Mesh.H:354
void initialize(double *nodes, int *triangles, unsigned int nv, unsigned int nt, int divisions=50)
IndexType Esize(IndexType n) const
Definition: Mesh.H:365
Definition: Rocin.h:64
blockLoc i
Definition: read.cpp:79
void Rocon_load_module(const char *name)
Definition: Rocon.C:869
double _TOL
Definition: Rocon.H:103
IndexType Nelem() const
Definition: Mesh.H:364
double _transform_y
Definition: Rocon.H:108
void COM_window_init_done(const char *w_str, int pane_changed=true)
Definition: roccom_c++.h:102
void COM_get_size(const char *wa_str, int pane_id, int *size, int *ng=0)
Get the sizes of an attribute.
Definition: roccom_c++.h:274
Rocon()
Default constructor.
Definition: Rocon.H:64
void COM_clone_attribute(const char *wname, const char *attr, int wg=1, const char *ptnname=0, int val=0)
Clone the subset of panes of another window of which the given pane attribute has value val...
Definition: roccom_c++.h:234
void rocon_unload_module_(const char *name, long int length)
Definition: Rocon.C:887
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 burnout(const COM::Attribute *pmesh, const COM::Attribute *cflag, COM::Attribute *bflag)
Sets bflag = 0 for every element for which every node&#39;s cflag = 1.
Definition: Rocon.C:227
bool intersection(const Vec3D &p, const Vec3D &d, Vec3D &x)
std::string _wname
Definition: Rocon.H:104
MPI_Comm _comm
Definition: Rocon.H:102
void ROCON_UNLOAD_MODULE_(const char *name, long int length)
Definition: Rocon.C:892
j indices j
Definition: Indexing.h:6
bool _checked
Definition: Rocon.H:106
static void load(const std::string &mname)
Definition: Rocon.C:813
Definition: Rocon.H:61
void COM_new_attribute(const char *wa_str, const char loc, const int type, int ncomp, const char *unit)
Registering an attribute type.
Definition: roccom_c++.h:118
void COM_get_panes(const char *wname, std::vector< int > &pane_ids, int rank=-2)
Definition: roccom_c++.h:350
void COM_set_member_function(const char *wf_str, Member_func_ptr func, const char *wa_str, const char *intents, const COM_Type *types)
Definition: roccom_c++.h:330
MeshBndSurf * _mbs
Definition: Rocon.H:105
void initialize(const COM::Attribute *pmesh, const int *ndiv)
Initialize Rocon with given mesh.
Definition: Rocon.C:98
void rocon_load_module(const char *name, long int length)
Definition: Rocon.C:875
void SetVerbosity(int v)
Definition: Rocon.H:98
int COMMPI_Initialized()
Definition: commpi.h:168
void TransformCoordinates(double *coords, int number_of_points, double xfac, double yfac, double zfac)
Definition: Rocon.C:87
Simple Block Structured Mesh object.
Definition: BSMesh.H:16
#define COM_LOAD_MODULE_STATIC_DYNAMIC(moduleName, windowString)
Definition: roccom_basic.h:111
int COM_get_function_handle(const char *wfname)
Definition: roccom_c++.h:428
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_GROUP_EMPTY INTEGER MPI_SUM
#define COM_EXTERN_MODULE(moduleName)
Definition: roccom_basic.h:116