int main(int argc, char *argv[]) 
{
  int i, j, k;//-- counters
  
  HashTable*   BT_Node_Ptr; 
  HashTable*   BT_Elem_Ptr; 
  
  //-- MPI
  int   myid, numprocs;

  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);

#ifdef DEBUG
  if (myid==0){
    int w;
    printf("type in a number: \n");
    (void) scanf ("%d", &w);
  } 
//  MPI_Barrier(MPI_COMM_WORLD);
#endif 
  
  /* create new MPI datastructures for class objects */
  MPI_New_Datatype();

  /* read original data from serial preprocessing
     code and then initialize element 
     stiffness routines info */
  double epsilon = 1., intfrictang = 1, bedfrictang = 1, gamma = 1; 
  double frict_tiny = 0.1, mu = .0001, rho = 2200, porosity = 1;
  
  MatProps matprops(intfrictang, bedfrictang, porosity, mu, rho, epsilon, 
		    gamma, frict_tiny, (double) 1, (double) 1, (double) 1);

  int max_time_steps = 3000, numoutput = 1, adaptflag;  
  double end_time = 10000.0;  
  /*
   * viz_flag is used to determine which viz output to use
   * viz_flag%2 == 0 means output tecplotxxxx.plt
   * viz_flag%3 == 0 means output mshplotxxxx.plt
   * viz_flag%5 == 0 means output pady's stuff (viz_filenames.out and viz_outputxxx.plt)
   * viz_flag%7 == 0 means output hdf stuff (not implemented yet)
   */
  int viz_flag = 0;
  int order_flag = 0;  //order flag for time stepping scheme -- not used as of 6/19/03
  Read_data(&BT_Node_Ptr, myid, &BT_Elem_Ptr, &matprops, &max_time_steps, 
	    &end_time, &numoutput, &adaptflag, &viz_flag, &order_flag);
  printf("bed friction angle is %e and internal friction angle is %e, epsilon is %e\n",
	 (double) (matprops.bedfrict*180./PI), 
	 (double) (matprops.intfrict*180./PI),
	 (double) (matprops.epsilon));
  printf("METHOD ORDER %d \n",ORDER);

  double dummyt=-100.;
  double maxFluxIntegral=0; //overall maximum of the integral of the 
  //flux on the element boundary   
  int h_c=0;
  //  H_adapt(BT_Elem_Ptr, BT_Node_Ptr, h_c, dummyt, &matprops);
  //H_adapt(BT_Elem_Ptr, BT_Node_Ptr, h_c, dummyt, &matprops);


  if(viz_flag%3==0)
    meshplotter(BT_Elem_Ptr, BT_Node_Ptr, 0,&matprops);
    
  /*
    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

                  Time Stepping Loop

    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    */
  
  int time_step = 0;
  double time = 0;
  while(time_step <= max_time_steps && time < end_time)
    {
      //if(myid ==0) 
	//	printf("doing time_step = %d and time is %e\n",time_step,
	//       time*sqrt(matprops.LENGTH_SCALE/matprops.GRAVITY_SCALE));
      /*  
       *  mesh adaption routines 
       */
      double TARGET = 0.005;
      double UNREFINE_TARGET=GEOFLOW_TINY;
      int h_count = 0;
      if (time_step < 0)
	matprops.frict_tiny=0.1;
      else if (time_step >= 0)
	matprops.frict_tiny=0.000001;

      if(adaptflag != 0) {
	if(time_step%4 == 0 ) {
	  H_adapt(BT_Elem_Ptr, BT_Node_Ptr, h_count, TARGET, &matprops, &maxFluxIntegral);
	}
	else if(time_step%4 == 2 ) { 
	  unrefine(BT_Elem_Ptr, BT_Node_Ptr, UNREFINE_TARGET, myid, numprocs, time_step, &matprops);
	}

	//P_adapt(BT_Elem_Ptr, BT_Node_Ptr, TARGET);
	//CN	if(viz_flag%3==0)
	//CN     meshplotter(BT_Elem_Ptr, BT_Node_Ptr, time_step+1,&matprops);
	
	/*
	 *  mesh repartitioning routines
	 */
	if(time_step % 10 == 1 && numprocs > 1) {
	  delete_ghost_elms(BT_Elem_Ptr, myid);
	  repartition(BT_Elem_Ptr, BT_Node_Ptr, time_step);
	  // move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr);
	}
      }

      step(BT_Elem_Ptr, BT_Node_Ptr, myid, numprocs, end_time, &time,
	   &matprops, time_step,  &maxFluxIntegral,numoutput); 
      //  printf(" maxFluxIntegral %e in hpfem.C \n ",maxFluxIntegral);
      //  exit(0);

      calc_volume(BT_Elem_Ptr, BT_Node_Ptr, myid, numprocs, &matprops);

      /*
       * output results to file 
       */
      if(time_step % numoutput == 0) {
	move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr);
	if(viz_flag%3==0)
	  meshplotter(BT_Elem_Ptr, BT_Node_Ptr, time_step+1,&matprops);
      }
      
      time_step++;
    }
  move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr);
  if(viz_flag%3==0)
    meshplotter(BT_Elem_Ptr, BT_Node_Ptr, time_step+1,&matprops);
  printf("%d Finished -- Final simulation time %e\n",myid,time);
  MPI_Finalize();    
  return(0);  
}
Пример #2
0
int main(int argc, char *argv[]) 
{
  int i;//-- counters

  HashTable*   BT_Node_Ptr; 
  HashTable*   BT_Elem_Ptr; 

  //-- MPI
  int   myid, master, numprocs;
  int   namelen;
  char  processor_name[MPI_MAX_PROCESSOR_NAME]; 
  MPI_Status status;

  MPI_Init(&argc,&argv);

  //PetscInitializeNoArguments();
  PetscInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);

  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  MPI_Get_processor_name(processor_name, &namelen);

  char debugfilename[256];
  sprintf(debugfilename,"hpfem%04d.debug",myid);

  double start, end;

  start = MPI_Wtime();

  /* create new MPI datastructures for class objects */
  MPI_New_Datatype();

  char filename[50];
  sprintf(filename,"debug.main.%04d",myid);


  /* read original data from serial preprocessing
     code and then initialize element 
     stiffness routines info */
  int material_count=0, output_flag;
  double epsilon = 1., intfrictang = 1, *bedfrictang = NULL, gamma = 1; 
  double frict_tiny = 0.1, mu = 1.0e-03, rho = 1600, rhof = 1000, porosity = 1;
  char **matnames=NULL;
  int xdmerr;

  StatProps statprops;
  MatProps matprops(material_count, matnames, 
		    intfrictang, bedfrictang, porosity, mu, 
		    rho, rhof, epsilon, gamma, frict_tiny,  1.0, 1.0, 1.0);
  TimeProps timeprops;
  timeprops.starttime=time(NULL);

  MapNames mapnames;
  PileProps pileprops;
  FluxProps fluxprops;
  OutLine outline;
  DISCHARGE discharge;

  int adaptflag;  
  double end_time = 10000.0;  
  /*
   * viz_flag is used to determine which viz output to use
   * nonzero 1st bit of viz_flag means output tecplotxxxx.plt
   * nonzero 2nd bit of viz_flag means output mshplotxxxx.plt
   * nonzero 4th bit of viz_flag means output xdmfxxxxx.xmf
   * nonzero 5th bit of viz_flag means output grass_sites files

   order_flag == 1 means use first order method
   order_flag == 2 means use second order method
  */
  int viz_flag = 0, order_flag, savefileflag=1; //savefileflag will be flipped so first savefile will end in 0
  int Init_Node_Num, Init_Elem_Num, srctype;
  double v_star; // v/v_slump
  double nz_star; /* temporary... used for negligible velocity as stopping 
		     criteria paper... plan to include in v_star implicitly 
		     later */

  Read_data(myid, &matprops, &pileprops, &statprops, &timeprops, 
	    &fluxprops, &adaptflag, &viz_flag, &order_flag,
	    &mapnames, &discharge, &outline, &srctype );

  if(!loadrun(myid, numprocs, &BT_Node_Ptr, &BT_Elem_Ptr, 
	      &matprops,  &timeprops, &mapnames, 
	      &adaptflag, &order_flag, &statprops, &discharge, &outline)) 
    {
      Read_grid(myid, numprocs, &BT_Node_Ptr, &BT_Elem_Ptr, 
		&matprops, &outline);

      setup_geoflow(BT_Elem_Ptr, BT_Node_Ptr, myid, numprocs, &matprops,&timeprops);

      move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops);

      AssertMeshErrorFree(BT_Elem_Ptr,BT_Node_Ptr,numprocs,myid,-1.0);


      //initialize pile height and if appropriate perform initial adaptation
      init_piles(BT_Elem_Ptr, BT_Node_Ptr, myid, numprocs, adaptflag,
		 &matprops, &timeprops, &mapnames, &pileprops, &fluxprops,
		 &statprops);
    }


  if (myid==0)
    {
      for(int imat=1; imat<=matprops.material_count; imat++)
	printf("bed friction angle for \"%s\" is %g\n",matprops.matnames[imat],
	       matprops.bedfrict[imat]*180.0/PI);

      printf("internal friction angle is %g, epsilon is %g \n method order = %i\n",
	     matprops.intfrict*180.0/PI, matprops.epsilon, order_flag );
      printf("REFINE_LEVEL=%d\n",REFINE_LEVEL);
    }

  //printdate(BT_Elem_Ptr, BT_Node_Ptr,&matprops, &fluxprops,&timeprops);


  MPI_Barrier(MPI_COMM_WORLD);
  calc_stats(BT_Elem_Ptr, BT_Node_Ptr, myid, &matprops, 
	     &timeprops, &statprops, &discharge, 0.0);
  output_discharge(&matprops, &timeprops, &discharge, myid);

  move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops);
  // int jiter;
  // for( jiter=0; jiter <3; jiter++){

  //   LaplacianData  Laplacian (BT_Elem_Ptr, BT_Node_Ptr ,1 ,.001);

  //   implicit_solver(&Laplacian);
  // }

  // HashEntryPtr      *buck = BT_Elem_Ptr->getbucketptr();

  // for(jiter=0; jiter<BT_Elem_Ptr->get_no_of_buckets(); jiter++){
  //   if(*(buck+jiter))
  //     {
  // 	HashEntryPtr currentPtr = *(buck+jiter);
  // 	while(currentPtr)
  // 	  {
  // 	    Element* Curr_El=(Element*)(currentPtr->value);
  // 	    if(Curr_El->get_adapted_flag()>0)//||(timeprops_ptr->iter%5==2)))
  // 	      { //if this is a refined element don't involve!!!
  // 		double phi = *(Curr_El->get_state_vars()+4);
  // 		if(phi>1) phi=1;
  // 		if(phi<0) phi=0;
  // 		Curr_El->update_phase2(phi);
  // 		Curr_El->update_phase1(phi);

  // 	      }
  // 	    currentPtr=currentPtr->next;
  // 	  }
  //     }
  // }
  //=============================================================================================================

  // int num_buck=BT_Elem_Ptr->get_no_of_buckets();
  // HashEntryPtr* buck = BT_Elem_Ptr->getbucketptr();
  // int num_nonzero_elem=0, *all_num_nonzero_elem;
  // for(i=0; i<num_buck; i++)
  //   if(*(buck+i)){

  //     HashEntryPtr currentPtr = *(buck+i);
  //     while(currentPtr){

  // 	Element* Curr_El=(Element*)(currentPtr->value);
  // 	if((Curr_El->get_adapted_flag()>0)&&
  // 	   (myid==Curr_El->get_myprocess()))
  // 	  if(*(Curr_El->pass_key())==3842346279 && *(Curr_El->pass_key()+1)==2368179492)
  // 	    {
  // 	      int xp=Curr_El->get_positive_x_side();
  // 	      int yp=(xp+1)%4, xm=(xp+2)%4, ym=(xp+3)%4;
  // 	      Node* nym = (Node*) BT_Node_Ptr->lookup(Curr_El->getNode()+(ym+4)*2);
  // 	      assert(nym->flux[1]);
  // 	    }

  // 	currentPtr=currentPtr->next;
  //     }
  //   }

  //=====================================================================================================


  if(myid==0) output_summary(&timeprops, &statprops, savefileflag);

  if(viz_flag&1)
    tecplotter(BT_Elem_Ptr, BT_Node_Ptr, &matprops, &timeprops, &mapnames, 
	       statprops.vstar );

  if(viz_flag&2)
    meshplotter(BT_Elem_Ptr, BT_Node_Ptr, &matprops, &timeprops, &mapnames, statprops.vstar);


  //printdate(BT_Elem_Ptr, BT_Node_Ptr,&matprops, &fluxprops,&timeprops);

#ifdef HAVE_HDF5
  if(viz_flag&8) 
    xdmerr=write_xdmf(BT_Elem_Ptr,BT_Node_Ptr,&timeprops,&matprops,&mapnames,XDMF_NEW);
#endif

  if(viz_flag&16){
    if(myid==0) grass_sites_header_output(&timeprops);
    grass_sites_proc_output(BT_Elem_Ptr, BT_Node_Ptr, myid, &matprops, 
			    &timeprops);}

  /*
    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

    Time Stepping Loop

    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
  */
  long element_counter=0; // for performance count elements/timestep/proc 
  int ifstop=0;
  double max_momentum=100;  //nondimensional

  /* ifend(0.5*statprops.vmean) is a hack, the original intent (when we were 
     intending to use vstar as a stopping criteria) whas to have the 
     calculation when vstar dropped back down below 1, instead we're 
     using the ifend() function to stop the simulation when the volume 
     averaged velocity falls back down below 2 meters... this hack is only
     for the colima hazard map runs, otherwise pass ifend() a constant 
     valued */

  while(!(timeprops.ifend(0)) && !ifstop)//(timeprops.ifend(0.5*statprops.vmean)) && !ifstop)
    {

      /*  
       *  mesh adaption routines 
       */
      double TARGET = .05;
      //double UNREFINE_TARGET = .005;
      double UNREFINE_TARGET = .01;
      int h_count = 0;
      if (timeprops.iter < 50)
	matprops.frict_tiny=0.1;
      else 
	matprops.frict_tiny=0.000000001;


      //check for changes in topography and update if necessary
      //may want to put an "if(timeprops.iter %20==0)" (20 is arbitrary) here
      if(timeprops.iter==200){
	update_topo(BT_Elem_Ptr, BT_Node_Ptr, myid, numprocs, &matprops, 
		    &timeprops,&mapnames);
      }

      if((adaptflag!=0)&&(timeprops.iter%5==4))
	{
	  AssertMeshErrorFree(BT_Elem_Ptr,BT_Node_Ptr,numprocs,myid,-2.0);

	  H_adapt(BT_Elem_Ptr, BT_Node_Ptr, h_count, TARGET, &matprops, 
		  &fluxprops, &timeprops, 5);

	  move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops);

	  unrefine(BT_Elem_Ptr, BT_Node_Ptr, UNREFINE_TARGET, myid, numprocs, &timeprops, &matprops);

	  MPI_Barrier(MPI_COMM_WORLD);//for debug

	  move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops); //this move_data() here for debug... to make AssertMeshErrorFree() Work

	  if((numprocs>1)&&(timeprops.iter%10==9)) 
	    {

	      repartition2(BT_Elem_Ptr, BT_Node_Ptr, &timeprops);

	      move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops); //this move_data() here for debug... to make AssertMeshErrorFree() Work
	    }
	  move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops);
	}

      step(BT_Elem_Ptr, BT_Node_Ptr, myid, numprocs, &matprops, &timeprops, 
	   &pileprops, &fluxprops, &statprops, &order_flag, &outline, 
	   &discharge,adaptflag);

      /*
       * output results to file 
       */
             if(timeprops.ifoutput()) {
//      if (timeprops.iter%30==1){//(timeprops.iter<1000 && timeprops.iter%60==58)
	//output_flag=1;
	//else if ( timeprops.iter%200==198)
	//output_flag=1;
	//    if(output_flag) 
	//	{
	move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops);

	output_discharge(&matprops, &timeprops, &discharge, myid);
	//output_flag=0;

	if(myid==0){ 
	  output_summary(&timeprops, &statprops, savefileflag);
	}

	if(viz_flag&1)
	  tecplotter(BT_Elem_Ptr, BT_Node_Ptr, &matprops, &timeprops, &mapnames,statprops.vstar);

	if(viz_flag&2)
	  meshplotter(BT_Elem_Ptr, BT_Node_Ptr, &matprops, &timeprops, &mapnames,statprops.vstar);

#ifdef HAVE_HDF5
	if(viz_flag&8)
	  xdmerr=write_xdmf(BT_Elem_Ptr,BT_Node_Ptr,&timeprops,&matprops,&mapnames,XDMF_OLD);
#endif

	if(viz_flag&16){
	  if(myid==0) grass_sites_header_output(&timeprops);
	  grass_sites_proc_output(BT_Elem_Ptr, BT_Node_Ptr, myid, &matprops, 
				  &timeprops);
	}
      }

#ifdef PERFTEST
      int countedvalue=timeprops.iter%2+1;
      int e_buckets=BT_Elem_Ptr->get_no_of_buckets();
      HashEntry* entryp;
      for(i=0; i<e_buckets; i++)
	{
	  entryp = *(BT_Elem_Ptr->getbucketptr() + i);
	  while(entryp)
	    {	
	      Element *  EmTemp = (Element*)entryp->value;
	      assert(EmTemp);
	      assert(EmTemp->get_counted()!=countedvalue);

	      if((EmTemp->get_adapted_flag()>=NOTRECADAPTED)&&
		 (EmTemp->get_adapted_flag()<=BUFFER)
		 ) {
		//if this element doesn't belong on this processor don't involve
		element_counter++;
		EmTemp->put_counted(countedvalue);
	      }
	      entryp = entryp->next;
	    }
	}

      MPI_Barrier(MPI_COMM_WORLD);      
#endif
    }

  MPI_Barrier(MPI_COMM_WORLD);


  move_data(numprocs, myid, BT_Elem_Ptr, BT_Node_Ptr,&timeprops);
  MPI_Barrier(MPI_COMM_WORLD);

  output_discharge(&matprops, &timeprops, &discharge, myid);
  MPI_Barrier(MPI_COMM_WORLD);

  if(myid==0) output_summary(&timeprops, &statprops, savefileflag);

  //printf("hpfem.C 1: xcen=%g\n",statprops.xcen);

  if(viz_flag&1)
    tecplotter(BT_Elem_Ptr, BT_Node_Ptr, &matprops, &timeprops, &mapnames, 
	       statprops.vstar);
  //printf("hpfem.C 2: xcen=%g\n",statprops.xcen);
  MPI_Barrier(MPI_COMM_WORLD);

  if(viz_flag&2)
    meshplotter(BT_Elem_Ptr, BT_Node_Ptr, &matprops, &timeprops, &mapnames,
		statprops.vstar);
  MPI_Barrier(MPI_COMM_WORLD);

#ifdef HAVE_HDF5
  if(viz_flag&8)
    xdmerr=write_xdmf(BT_Elem_Ptr,BT_Node_Ptr,&timeprops,&matprops,&mapnames,XDMF_CLOSE);
  MPI_Barrier(MPI_COMM_WORLD);
#endif

  if(viz_flag&16){
    if(myid==0) grass_sites_header_output(&timeprops);
    grass_sites_proc_output(BT_Elem_Ptr, BT_Node_Ptr, myid, &matprops, 
			    &timeprops);}
  MPI_Barrier(MPI_COMM_WORLD);

  // write out ending warning, maybe flow hasn't finished moving
  sim_end_warning(BT_Elem_Ptr, &matprops, &timeprops, statprops.vstar);
  MPI_Barrier(MPI_COMM_WORLD);

  //write out the final pile statistics (and run time)
  if(myid==0) out_final_stats(&timeprops, &statprops);

  MPI_Barrier(MPI_COMM_WORLD);

  //write out stochastic simulation statistics
  //if(statprops.lhs.runid>=0)
  if(myid==0) output_stoch_stats(&matprops, &statprops);
  MPI_Barrier(MPI_COMM_WORLD);

  //saverun(&BT_Node_Ptr, myid, numprocs, &BT_Elem_Ptr, &matprops, &timeprops, &mapnames, 
  //      adaptflag, order_flag, &statprops, &discharge, &outline, &savefileflag); Was not possible because the saverun function doesn't write the information for laplacian, moreover element constructor requires some modifications
  
  MPI_Barrier(MPI_COMM_WORLD);
 

  //output maximum flow depth a.k.a. flow outline
  OutLine outline2;
  double dxy[2];
  dxy[0]=outline.dx;
  dxy[1]=outline.dy;
  outline2.init2(dxy,outline.xminmax,outline.yminmax);
  int NxNyout=outline.Nx*outline.Ny;
  MPI_Reduce(*(outline.pileheight),*(outline2.pileheight),NxNyout, 
	     MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
  if(myid==0) outline2.output(&matprops,&statprops);

#ifdef PERFTEST  
  long  m = element_counter, ii;

  MPI_Allreduce ( &element_counter, &ii, 1, 
		  MPI_LONG, MPI_SUM, MPI_COMM_WORLD );

  end=MPI_Wtime();
  char perffilename[256];
  sprintf(perffilename,"perform%04d.%04d",numprocs,myid);
  FILE *fpperf=fopen(perffilename,"w");
  fprintf(fpperf,"%d Finished -- used %ld elements of %ld total in %e seconds, %e\n",myid,m,ii,end-start, ii/(end-start));
  fclose(fpperf);
#endif
  PetscFinalize();
  MPI_Finalize();  
  return(0);  

}