Example #1
0
void tecplotter(HashTable* El_Table, HashTable* NodeTable, 
		MatProps* matprops, TimeProps* timeprops, MapNames* mapnames,
		double v_star)
{
  int i_buck, i_neigh;   //indices
  int xp, xm, yp, ym;    //x plus, x minus, y plus, y minus directions
  int gen, *neigh_gen;   //level of grid refinement
  int numprocs;          //number of processes
  int myid, *neigh_proc; //process id's

  int done = 1; 
  unsigned key[2];
  int TECTAG = 123;
  MPI_Status status;
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);

  Element *EmTemp, *EmArray[4];
  HashEntry *entryp;
  
  int e_buckets=El_Table->get_no_of_buckets();
  
  /*There are 2 ways to draw triangles
    1) as a separate ZONE of triangles 
    2) as quads with duplicate points
    I chose the 2nd option.  Why?  Because I want all the elements
    from a given processor to be in a single zone.  Also duplicate 
    points for every element that uses them have been eliminated.
    That makes the "boundary" option in tecplot work right, but 
    more importantly the nodes the triangles use aren't repeated 
    (you get the triangles for free apart from the element 
    conectivity data) and nodes for quads are reduced by about a
    factor of 4.  This reduces file the size by about a factor of 4 
    when grid adaptation is used, and by about a factor of 3 when 
    it's not.  

    MODIFICATION: 20070115: Now Each And Every BUBBLE Node of Active 
    and Ghost Elements are printed once in the order they appear in 
    the Element HashTable.  This eliminates the need to sort (quick
    or otherwise) the elements speeding up tecplot, at the cost of 
    slightly increasing the file size on multiprocessor runs 
    (adding BUBBLE nodes of GHOST elements along the right and upper
    edges of the collection of elements this processor "owns")
  */
   
  //count the number of BUBBLE nodes, and tecplot quads and tecplot 
  //triangles I need to draw
  int num_tec_node=0, num_tec_tri=0, num_tec_quad=0;
  for(i_buck=0;i_buck<e_buckets;i_buck++) {
    entryp = *(El_Table->getbucketptr()+i_buck);
    while(entryp) {	
      EmArray[0]=EmTemp=(Element*)entryp->value;
      assert(EmTemp);
      entryp=entryp->next;
      if((EmTemp->get_adapted_flag()!=TOBEDELETED)&&
	 (abs(EmTemp->get_adapted_flag())<=BUFFER)
	 ) {
	num_tec_node++;
	EmTemp->put_ithelem(num_tec_node);           

	if(EmTemp->get_adapted_flag()>TOBEDELETED) {
	  switch(get_ll_polygon(El_Table,NodeTable,myid,EmArray)) {
	  case 4: //we should draw a lower left quad
	    num_tec_quad++;
	    break;
	  case 3: //we should draw a lower left triangle
	    num_tec_tri++;
	    break;
	  case 0: //we should NOT draw a lower left polygon
	    break;
	  default: //something wierd happened report this to the "FBI"
	    assert(0);
	  }//switch(get_ll_polygon(El_Table,NodeTable,myid,EmArray))

	  //match the lower left triangle at the lower left corner of 
	  //a different subdomain with an upper right triangle in this 
	  //subdomain
	  if(get_ur_tri(El_Table,NodeTable,myid,EmArray)) num_tec_tri++;  
	  
	  neigh_proc = EmTemp->get_neigh_proc();
	  gen=EmTemp->get_gen();
	  neigh_gen=EmTemp->get_neigh_gen();
	  //one triangle is added to an element for each side whose
	  //neighboring element is more refined than current element 
	  //provided the triangle wouldn't fall on a domain boundary
	  for(i_neigh=0; i_neigh<4; i_neigh++)
	    if((neigh_gen[i_neigh]>gen)&&(neigh_proc[i_neigh]!=INIT)) 
	      num_tec_tri++;
	}//if(EmTemp->get_adapted_flag()>TOBEDELETED)
      }//if((EmTemp->get_adapted_flag()!=TOBEDELETED)&&
    }//while(entryp)
  }//for(i_buck=0;i_buck<e_buckets;i_buck++)

  int num_tec_elem=num_tec_quad+num_tec_tri;
  int num_tec_elem2=0;

  char filename[20];
  sprintf(filename,"tecpl%02d%08d.tec",myid,timeprops->iter);
  FILE *fp=fopen(filename,"w");


  //print the tecplot header
  int hrs, mins; double secs;
  timeprops->chunktime(&hrs,&mins,&secs);

  fprintf ( fp, "TITLE= \" %s: time %d:%02d:%g (hrs:min:sec), V*=%g\"\n",
	    mapnames->gis_map,hrs,mins,secs,v_star);
  fprintf ( fp, "VARIABLES = \"X\", \"Y\", \"Z\", \"PILE_HEIGHT\","
                 "\"PHI\", \"SOLID_X_MOMENTUM\", \"SOLID_Y_MOMENTUM\","
                 "\"FLUID_X_MOMENTUM\", \"FLUID_Y_MOMENTUM\","
                 "\"ELEVATION\", \"SOLID_SPEED\", \"FLUID_SPEED\" \n");
  
  fprintf(fp,"\n");
  fprintf(fp,"ZONE N=%d, E=%d, F=FEPOINT, ET=QUADRILATERAL\n",
	  num_tec_node, num_tec_elem);


  //print the element/BUBBLE-node information

  int num_missing_bubble_node=0; //for legacy debugging, I (Keith) 
  //believe the missing BUBBLE node problem has been solved, it 
  //doesn't seem to be a problem anymore

  for(i_buck=0;i_buck<e_buckets;i_buck++) {
    entryp = *(El_Table->getbucketptr()+i_buck);
    while(entryp) {	
      EmTemp=(Element*)entryp->value;
      assert(EmTemp);
      entryp=entryp->next;
      if((EmTemp->get_adapted_flag()!=TOBEDELETED)&&
	 (abs(EmTemp->get_adapted_flag())<=BUFFER)
	 )
	num_missing_bubble_node+=
	  print_bubble_node(fp, NodeTable, matprops, EmTemp);
    }//while(entryp)
  }//for(i_buck=0;i_buck<e_buckets;i_buck++)
  

  //print the tecplot element connectivity data
  int tec_nodes_in_tec_quad[4];
  for(i_buck=0;i_buck<e_buckets;i_buck++) {
    entryp = *(El_Table->getbucketptr()+i_buck);
    while(entryp) {	
      EmArray[0]=EmTemp=(Element*)entryp->value;
      assert(EmTemp);
      entryp=entryp->next;
      if((EmTemp->get_adapted_flag()>TOBEDELETED)&&
	 (EmTemp->get_adapted_flag()<=BUFFER)
	 ) {

	neigh_proc = EmTemp->get_neigh_proc();
	gen=EmTemp->get_gen();  
	neigh_gen=EmTemp->get_neigh_gen();
		
	switch(get_ll_polygon(El_Table,NodeTable,myid,EmArray)) {
	case 4: //we should draw a lower left quad
	  tec_nodes_in_tec_quad[0]=EmArray[2]->get_ithelem();
	  tec_nodes_in_tec_quad[1]=EmArray[0]->get_ithelem();
	  tec_nodes_in_tec_quad[2]=EmArray[1]->get_ithelem();
	  tec_nodes_in_tec_quad[3]=EmArray[3]->get_ithelem();
	  
	  fprintf(fp,"%d %d %d %d\n",
		  tec_nodes_in_tec_quad[0],
		  tec_nodes_in_tec_quad[1],
		  tec_nodes_in_tec_quad[2],
		  tec_nodes_in_tec_quad[3]);

	  num_tec_elem2++; //counter of number of drawing elements
	  break;
	case 3: //we should draw a lower left triangle
	  tec_nodes_in_tec_quad[  0]=EmArray[2]->get_ithelem();
	  tec_nodes_in_tec_quad[  1]=EmArray[0]->get_ithelem();
	  tec_nodes_in_tec_quad[  2]=
	    tec_nodes_in_tec_quad[3]=EmArray[1]->get_ithelem();

	  fprintf(fp,"%d %d %d %d\n",
		  tec_nodes_in_tec_quad[0],
		  tec_nodes_in_tec_quad[1],
		  tec_nodes_in_tec_quad[2],
		  tec_nodes_in_tec_quad[3]);

	  num_tec_elem2++; //counter of number of drawing elements
	  break;
	case 0: //we should NOT draw a lower left polygon
	  break;
	default: //something weird happened report this to the "FBI"
	  assert(0);
	}//switch(get_ll_polygon(El_Table, myid, EmArray))
	
	/**********************************************************/
	/* match the lower left triangle at the lower left corner */
	/* of a different subdomain with an upper right one       */
	/**********************************************************/

	if(get_ur_tri(El_Table,NodeTable,myid,EmArray)) {
	  tec_nodes_in_tec_quad[  0]=EmArray[1]->get_ithelem();
	  tec_nodes_in_tec_quad[  1]=EmArray[2]->get_ithelem();
	  tec_nodes_in_tec_quad[  2]=
	    tec_nodes_in_tec_quad[3]=EmArray[0]->get_ithelem();

	  fprintf(fp,"%d %d %d %d\n",
		  tec_nodes_in_tec_quad[0],
		  tec_nodes_in_tec_quad[1],
		  tec_nodes_in_tec_quad[2],
		  tec_nodes_in_tec_quad[3]);

	  num_tec_elem2++; //counter of number of drawing elements
	}//if(get_ur_tri(El_Table,myid,EmArray))
	
	/**********************************************************/
	/* add triangles for elements with more refined neighbors */
	/* (aka split neighbors) this fills in the holes          */
	/**********************************************************/
	tec_nodes_in_tec_quad[0]=EmTemp->get_ithelem();
	for(i_neigh=0; i_neigh<4; i_neigh++)  
	  if((neigh_gen[i_neigh]>gen)&&(neigh_proc[i_neigh]!=INIT)){
	    /* draw triangles as quads with the last corner of
	       the triangle repeated.  The three corners are
	       1) this element
	       2) the primary neighbor (one of sides 0->3) 
	       3) the secondary neighbor (the primary +4 side) */
	
	    EmArray[1]=EmArray[2]=EmArray[3]=NULL;

	    //The Primary Neighbor
	    EmArray[1]=(Element*) El_Table->lookup(EmTemp->get_neighbors()+i_neigh*KEYLENGTH);
	    assert(EmArray[1]);
	    tec_nodes_in_tec_quad[  1]=EmArray[1]->get_ithelem();

	    //The Secondary Neighbor
	    EmArray[2]=(Element*) El_Table->lookup(EmTemp->get_neighbors()+(i_neigh+4)*KEYLENGTH);
	    assert(EmArray[2]);
	    tec_nodes_in_tec_quad[  2]=
	      tec_nodes_in_tec_quad[3]=EmArray[2]->get_ithelem();

	    fprintf(fp,"%d %d %d %d\n",
		    tec_nodes_in_tec_quad[0],
		    tec_nodes_in_tec_quad[1],
		    tec_nodes_in_tec_quad[2],
		    tec_nodes_in_tec_quad[3]);
	    	    
	    num_tec_elem2++; //counter of number of drawing elements
	  }//if((neigh_gen[i_neigh]>gen)&&(neigh_proc[i_neigh]!=INIT))
      }//if((EmTemp->get_adapted_flag()>TOBEDELETED)&& ...
    }//while(entryp)
  }//for(i_buck=0;i_buck<e_buckets;i_buck++)
  fflush(fp);
  fclose(fp);
  //printf("num_tec_elem {1/2}={%d/%d}\n",num_tec_elem,num_tec_elem2);
  assert(num_tec_elem2==num_tec_elem);

  MPI_Barrier(MPI_COMM_WORLD);

  return;
}
Example #2
0
void
tecplotter (HashTable * El_Table, HashTable * NodeTable,
            MatProps * matprops, TimeProps * timeprops, MapNames * mapnames,
            double v_star)
{
  int i_buck, i_neigh;          //indices
  int xp, xm, yp, ym;           //x plus, x minus, y plus, y minus directions
  int gen, *neigh_gen;          //level of grid refinement
  int numprocs;                 //number of processes
  int myid, *neigh_proc;        //process id's

  int done = 1;
  unsigned key[2];
  int TECTAG = 123;
  MPI_Status status;
  MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank (MPI_COMM_WORLD, &myid);

  Element *EmTemp, *EmArray[4];
  HashEntry *entryp;

  int e_buckets = El_Table->get_no_of_buckets ();

  //move_data(numprocs, myid, El_Table, NodeTable,timeprops);

  if (myid == TARGETPROCA)
    {
      printf ("at tecplotter 1.0\n");
      fflush (stdout);
    }

  //count the number of BUBBLE nodes, and tecplot quads and tecplot 
  //triangles I need to draw
  int num_tec_node = 0, num_tec_tri = 0, num_tec_quad = 0;
  for (i_buck = 0; i_buck < e_buckets; i_buck++)
    {
      entryp = *(El_Table->getbucketptr () + i_buck);
      while (entryp)
        {
          EmArray[0] = EmTemp = (Element *) entryp->value;
          assert (EmTemp);
          entryp = entryp->next;
          if ((EmTemp->get_adapted_flag () != TOBEDELETED) &&
              (abs (EmTemp->get_adapted_flag ()) <= BUFFER))
            {
              num_tec_node++;
              EmTemp->put_ithelem (num_tec_node);

              if (EmTemp->get_adapted_flag () > TOBEDELETED)
                {
                  switch (get_ll_polygon (El_Table, NodeTable, myid, EmArray))
                    {
                    case 4:    //we should draw a lower left quad
                      num_tec_quad++;
                      break;
                    case 3:    //we should draw a lower left triangle
                      num_tec_tri++;
                      break;
                    case 0:    //we should NOT draw a lower left polygon
                      break;
                    default:   //something wierd happened report this to the "FBI"
                      assert (0);
                    }           //switch(get_ll_polygon(El_Table,NodeTable,myid,EmArray))

                  //match the lower left triangle at the lower left corner of 
                  //a different subdomain with an upper right triangle in this 
                  //subdomain
                  if (get_ur_tri (El_Table, NodeTable, myid, EmArray))
                    num_tec_tri++;

                  neigh_proc = EmTemp->get_neigh_proc ();
                  gen = EmTemp->get_gen ();
                  neigh_gen = EmTemp->get_neigh_gen ();
                  //one triangle is added to an element for each side whose
                  //neighboring element is more refined than current element 
                  //provided the triangle wouldn't fall on a domain boundary
                  for (i_neigh = 0; i_neigh < 4; i_neigh++)
                    if ((neigh_gen[i_neigh] > gen)
                        && (neigh_proc[i_neigh] != INIT))
                      num_tec_tri++;
                }               //if(EmTemp->get_adapted_flag()>TOBEDELETED)
            }                   //if((EmTemp->get_adapted_flag()!=TOBEDELETED)&&
        }                       //while(entryp)
    }                           //for(i_buck=0;i_buck<e_buckets;i_buck++)

  int num_tec_elem = num_tec_quad + num_tec_tri;
  int num_tec_elem2 = 0;

  char filename[20];
  sprintf (filename, "tecpl%02d%08d.tec", myid, timeprops->iter);
  FILE *fp = fopen (filename, "w");


  //print the tecplot header
  int hrs, mins;
  double secs;
  timeprops->chunktime (&hrs, &mins, &secs);

  fprintf (fp, "TITLE= \" %s: time %d:%02d:%g (hrs:min:sec), V*=%g\"\n",
           mapnames->gis_map, hrs, mins, secs, v_star);
  fprintf (fp, "VARIABLES = \"X\", \"Y\", \"Z\", \"PILE_HEIGHT\", \"X_MOMENTUM\", \"Y_MOMENTUM\", \"ELEVATION\", \"CORRECTSPEED\" \n");   //}

  fprintf (fp, "\n");
  fprintf (fp, "ZONE N=%d, E=%d, F=FEPOINT, ET=QUADRILATERAL\n",
           num_tec_node, num_tec_elem);


  //print the element/BUBBLE-node information

  int num_missing_bubble_node = 0;      //for legacy debugging, I (Keith)
  //believe the missing BUBBLE node problem has been solved, it 
  //doesn't seem to be a problem anymore

  for (i_buck = 0; i_buck < e_buckets; i_buck++)
    {
      entryp = *(El_Table->getbucketptr () + i_buck);
      while (entryp)
        {
          EmTemp = (Element *) entryp->value;
          assert (EmTemp);
          entryp = entryp->next;
          if ((EmTemp->get_adapted_flag () != TOBEDELETED) &&
              (abs (EmTemp->get_adapted_flag ()) <= BUFFER))
            num_missing_bubble_node +=
              print_bubble_node (fp, NodeTable, matprops, EmTemp);
        }  //while(entryp)
    }  //for(i_buck=0;i_buck<e_buckets;i_buck++)


  //print the tecplot element connectivity data
  int tec_nodes_in_tec_quad[4];
  for (i_buck = 0; i_buck < e_buckets; i_buck++)
    {
      entryp = *(El_Table->getbucketptr () + i_buck);
      while (entryp)
        {
          EmArray[0] = EmTemp = (Element *) entryp->value;
          assert (EmTemp);
          entryp = entryp->next;
          if ((EmTemp->get_adapted_flag () > TOBEDELETED) &&
              (EmTemp->get_adapted_flag () <= BUFFER))
            {

              neigh_proc = EmTemp->get_neigh_proc ();
              gen = EmTemp->get_gen ();
              neigh_gen = EmTemp->get_neigh_gen ();

              switch (get_ll_polygon (El_Table, NodeTable, myid, EmArray))
                {
                case 4:        //we should draw a lower left quad
                  tec_nodes_in_tec_quad[0] = EmArray[2]->get_ithelem ();
                  tec_nodes_in_tec_quad[1] = EmArray[0]->get_ithelem ();
                  tec_nodes_in_tec_quad[2] = EmArray[1]->get_ithelem ();
                  tec_nodes_in_tec_quad[3] = EmArray[3]->get_ithelem ();

                  fprintf (fp, "%d %d %d %d\n",
                           tec_nodes_in_tec_quad[0],
                           tec_nodes_in_tec_quad[1],
                           tec_nodes_in_tec_quad[2],
                           tec_nodes_in_tec_quad[3]);

                  num_tec_elem2++;      //counter of number of drawing elements
                  break;
                case 3:        //we should draw a lower left triangle
                  tec_nodes_in_tec_quad[0] = EmArray[2]->get_ithelem ();
                  tec_nodes_in_tec_quad[1] = EmArray[0]->get_ithelem ();
                  tec_nodes_in_tec_quad[2] =
                    tec_nodes_in_tec_quad[3] = EmArray[1]->get_ithelem ();

                  fprintf (fp, "%d %d %d %d\n",
                           tec_nodes_in_tec_quad[0],
                           tec_nodes_in_tec_quad[1],
                           tec_nodes_in_tec_quad[2],
                           tec_nodes_in_tec_quad[3]);

                  num_tec_elem2++;      //counter of number of drawing elements
                  break;
                case 0:        //we should NOT draw a lower left polygon
                  break;
                default:       //something weird happened report this to the "FBI"
                  assert (0);
                }               //switch(get_ll_polygon(El_Table, myid, EmArray))

        /**********************************************************/
              /* match the lower left triangle at the lower left corner */
              /* of a different subdomain with an upper right one       */
        /**********************************************************/

              if (get_ur_tri (El_Table, NodeTable, myid, EmArray))
                {
                  tec_nodes_in_tec_quad[0] = EmArray[1]->get_ithelem ();
                  tec_nodes_in_tec_quad[1] = EmArray[2]->get_ithelem ();
                  tec_nodes_in_tec_quad[2] =
                    tec_nodes_in_tec_quad[3] = EmArray[0]->get_ithelem ();

                  fprintf (fp, "%d %d %d %d\n",
                           tec_nodes_in_tec_quad[0],
                           tec_nodes_in_tec_quad[1],
                           tec_nodes_in_tec_quad[2],
                           tec_nodes_in_tec_quad[3]);

                  num_tec_elem2++;      //counter of number of drawing elements
                }               //if(get_ur_tri(El_Table,myid,EmArray))

        /**********************************************************/
              /* add triangles for elements with more refined neighbors */
              /* (aka split neighbors) this fills in the holes          */
        /**********************************************************/
              tec_nodes_in_tec_quad[0] = EmTemp->get_ithelem ();
              for (i_neigh = 0; i_neigh < 4; i_neigh++)
                if ((neigh_gen[i_neigh] > gen)
                    && (neigh_proc[i_neigh] != INIT))
                  {
                    /* draw triangles as quads with the last corner of
                       the triangle repeated.  The three corners are
                       1) this element
                       2) the primary neighbor (one of sides 0->3) 
                       3) the secondary neighbor (the primary +4 side) */

                    EmArray[1] = EmArray[2] = EmArray[3] = NULL;

                    //The Primary Neighbor
                    EmArray[1] =
                      (Element *) El_Table->lookup (EmTemp->get_neighbors () +
                                                    i_neigh * KEYLENGTH);
                    assert (EmArray[1]);
                    tec_nodes_in_tec_quad[1] = EmArray[1]->get_ithelem ();

                    //The Secondary Neighbor
                    EmArray[2] =
                      (Element *) El_Table->lookup (EmTemp->get_neighbors () +
                                                    (i_neigh +
                                                     4) * KEYLENGTH);
                    assert (EmArray[2]);
                    tec_nodes_in_tec_quad[2] =
                      tec_nodes_in_tec_quad[3] = EmArray[2]->get_ithelem ();

                    fprintf (fp, "%d %d %d %d\n",
                             tec_nodes_in_tec_quad[0],
                             tec_nodes_in_tec_quad[1],
                             tec_nodes_in_tec_quad[2],
                             tec_nodes_in_tec_quad[3]);

                    num_tec_elem2++;    //counter of number of drawing elements
                  }  //if((neigh_gen[i_neigh]>gen)&&(neigh_proc[i_neigh]!=INIT))
            }  //if((EmTemp->get_adapted_flag()>TOBEDELETED)&& ...
        }  //while(entryp)
    }  //for(i_buck=0;i_buck<e_buckets;i_buck++)
  fflush (fp);
  fclose (fp);
  assert (num_tec_elem2 == num_tec_elem);

  MPI_Barrier (MPI_COMM_WORLD);

  return;
}