int get_elem_elev(HashTable *NodeTable, MatProps *matprops, Element *EmTemp, double *elevation){ int j; double resolution, xcoord, ycoord; Node *NdTemp; NdTemp = (Node*) NodeTable->lookup(EmTemp->pass_key()); if(NdTemp == NULL){ //printf("\"start\" of get_elem_elev return(1)\n"); fflush(stdout); j = Get_max_resolution(&resolution); if(j != 0) { printf("error in Get_max_resolution\n"); exit(1); } xcoord = *(EmTemp->get_coord())*(matprops->LENGTH_SCALE); ycoord = *(EmTemp->get_coord()+1)*(matprops->LENGTH_SCALE); //printf("elev_ptr=%d, ",(int) elevation); j = Get_elevation(resolution, xcoord, ycoord, elevation); //printf("elev_ptr=%d\n",(int) elevation); if(j != 0) { printf("error in Get_elevation\n"); exit(1); } //printf("End of get_elem_elev return(1)\n"); fflush(stdout); return(1); } else{ *elevation = NdTemp->get_elevation()*(matprops->LENGTH_SCALE); return(0); } }
Node:: Node(unsigned* keyi, double* coordi, MatProps* matprops_ptr) { int i; nextptr =0; preptr = 0; info = INIT; for(i=0; i<DIMENSION; i++) coord[i] = *(coordi+i); for(i=0; i<KEYLENGTH; i++) key[i] = *(keyi+i); dof[0] = INIT; dof[1] = INIT; // find the max resolution of the GIS info and then get the elevation at this node double resolution = 0; double xcoord = coord[0]*(matprops_ptr->LENGTH_SCALE); double ycoord = coord[1]*(matprops_ptr->LENGTH_SCALE); i = Get_max_resolution(&resolution); if(i != 0) { printf("error in Get_max_resolution\n"); exit(1); } i = Get_elevation(resolution, xcoord, ycoord, &elevation); if(i != 0) { printf("error in Get_elevation\n"); exit(1); } elevation = elevation/matprops_ptr->LENGTH_SCALE; }
Node:: Node(unsigned* keyi, double* coordi, MatProps* matprops_ptr) { int i; id =0; /* keith added this so save_node wouldn't write an uninitialized variable and valgrind wouldn't flag an error. id is used in ../repartition/BSFC_update_and_send_elements.C */ order =0; /* keith added this for no good reason, so if you don't know that this is right find out, keith isn't responsible for any errors it may cause because right now the node order is unused, it shouldn't be used, but I wanted to see if assigning it zero gets rid of what looks like a "self contained" memory error */ nextptr =0; preptr = 0; sol = 0; sol_deleted = 0; connection_id = -1; info = INIT; for(i=0; i<DIMENSION; i++) coord[i] = *(coordi+i); for(i=0; i<KEYLENGTH; i++) key[i] = *(keyi+i); dof[0] = INIT; dof[1] = INIT; zero_flux(); // find the max resolution of the GIS info and then get the elevation at this node double resolution = 0; double xcoord = coord[0]*(matprops_ptr->LENGTH_SCALE); double ycoord = coord[1]*(matprops_ptr->LENGTH_SCALE); i = Get_max_resolution(&resolution); if(i != 0) { printf("error in Get_max_resolution\n"); exit(1); } i = Get_elevation(resolution, xcoord, ycoord, &elevation); if(i != 0) { printf("error in Get_elevation(%d) r=%g (x,y)=(%g,%g) e=%g\n",i,resolution,xcoord,ycoord,elevation); exit(1); } elevation = elevation/matprops_ptr->LENGTH_SCALE; /* if((unsigned) 1548032885 == key[0]) printf("created the missing node...\n"); */ /* if((coord[0]==0)||(coord[1]==0)){ printf("node={%u,%u} coord=(%20g,%20g)\n",key[0],key[1],coord[0],coord[1]); assert(coord[0]*coord[1]); } */ }
Node::Node(unsigned* keyi, double* coordi, int inf, int ord, MatProps* matprops_ptr) //for refined { int i; id =0; /* keith added this so save_node wouldn't write an uninitialized variable and valgrind wouldn't flag an error. id is used in ../repartition/BSFC_update_and_send_elements.C */ nextptr =0; preptr = 0; sol = 0; sol_deleted = 0; connection_id = -1; info = INIT; for(i=0; i<DIMENSION; i++) coord[i] = *(coordi+i); for(i=0; i<KEYLENGTH; i++) key[i] = *(keyi+i); dof[0] = INIT; dof[1] = INIT; info=inf; order=ord; //geoflow stuff zero_flux(); // find the max resolution of the GIS info and then get the elevation at this node double resolution = 0; i = Get_max_resolution(&resolution); if(i != 0) { printf("error in Get_max_resolution\n"); exit(1); } double xcoord = coord[0]*(matprops_ptr->LENGTH_SCALE); double ycoord = coord[1]*(matprops_ptr->LENGTH_SCALE); i = Get_elevation(resolution, xcoord, ycoord, &elevation); if(i != 0) { printf("error in Get_elevation\n"); exit(1); } elevation = elevation/matprops_ptr->LENGTH_SCALE; /* if((unsigned) 1548032885 == key[0]) printf("created the missing node111111...\n");*/ /* if((coord[0]==0)||(coord[1]==0)){ printf("node={%u,%u} coord=(%20g,%20g)\n",key[0],key[1],coord[0],coord[1]); assert(coord[0]*coord[1]); } */ return; }
Node::Node(FILE* fp, MatProps* matprops_ptr) { FourBytes temp4; EightBytes temp8; //unsigned readspace[13]; unsigned readspace[8]; int Itemp = 0, itemp; //fread(readspace,sizeof(unsigned),13,fp); fread(readspace, sizeof(unsigned), 8, fp); //KEYLENGTH should be 2 but put it in a loop to make it generic. for (itemp = 0; itemp < KEYLENGTH; itemp++) { key[itemp] = readspace[Itemp++]; } assert(Itemp == 2); //DIMENSION should be 2 but put it in a loop to make it generic. for (itemp = 0; itemp < DIMENSION; itemp++) { temp8.u[0] = readspace[Itemp++]; temp8.u[1] = readspace[Itemp++]; coord[itemp] = temp8.d; } assert(Itemp == 6); temp4.u = readspace[Itemp++]; id = temp4.i; assert(Itemp == 7); temp4.u = readspace[Itemp++]; info = temp4.i; assert(Itemp == 8); // find the max resolution of the GIS info and then get the elevation at this node double resolution = 0; double xcoord = coord[0] * (matprops_ptr->LENGTH_SCALE); double ycoord = coord[1] * (matprops_ptr->LENGTH_SCALE); int i = Get_max_resolution(&resolution); if (i != 0) { printf("error in Get_max_resolution\n"); exit(1); } i = Get_elevation(resolution, xcoord, ycoord, &elevation); if (i != 0) { printf("error in Get_elevation\n"); exit(1); } elevation = elevation / matprops_ptr->LENGTH_SCALE; return; }
void Node::set_elevation(MatProps* matprops_ptr) { double resolution = 0; double xcoord = coord[0] * (matprops_ptr->LENGTH_SCALE); double ycoord = coord[1] * (matprops_ptr->LENGTH_SCALE); int i = Get_max_resolution(&resolution); if (i != 0) { printf("error in Get_max_resolution\n"); exit(1); } i = Get_elevation(resolution, xcoord, ycoord, &elevation); if (i != 0) { printf("error in Get_elevation\n"); exit(1); } elevation = elevation / matprops_ptr->LENGTH_SCALE; }
Node::Node(unsigned* keyi, double* coordi, MatProps* matprops_ptr) { int i; id = 0; /* keith added this so save_node wouldn't write an uninitialized variable and valgrind wouldn't flag an error. id is used in ../repartition/BSFC_update_and_send_elements.C */ info = INIT; for (i = 0; i < DIMENSION; i++) coord[i] = *(coordi + i); for (i = 0; i < KEYLENGTH; i++) key[i] = *(keyi + i); zero_flux(); // find the max resolution of the GIS info and then get the elevation at this node double resolution = 0; double xcoord = coord[0] * (matprops_ptr->LENGTH_SCALE); double ycoord = coord[1] * (matprops_ptr->LENGTH_SCALE); i = Get_max_resolution(&resolution); if (i != 0) { printf("error in Get_max_resolution\n"); exit(1); } i = Get_elevation(resolution, xcoord, ycoord, &elevation); if (i != 0) { printf("error in Get_elevation(%d) r=%g (x,y)=(%g,%g) e=%g\n", i, resolution, xcoord, ycoord, elevation); exit(1); } elevation = elevation / matprops_ptr->LENGTH_SCALE; /* if((unsigned) 1548032885 == key[0]) printf("created the missing node...\n"); */ /* if((coord[0]==0)||(coord[1]==0)){ printf("node={%u,%u} coord=(%20g,%20g)\n",key[0],key[1],coord[0],coord[1]); assert(coord[0]*coord[1]); } */ }
int get_elem_elev (HashTable * NodeTable, MatProps * matprops, Element * EmTemp, double *elevation) { int j; double resolution, xcoord, ycoord; Node *NdTemp; NdTemp = (Node *) NodeTable->lookup (EmTemp->pass_key ()); if (NdTemp == NULL) { j = Get_max_resolution (&resolution); if (j != 0) { printf ("error in Get_max_resolution\n"); exit (1); } xcoord = *(EmTemp->get_coord ()) * (matprops->LENGTH_SCALE); ycoord = *(EmTemp->get_coord () + 1) * (matprops->LENGTH_SCALE); j = Get_elevation (resolution, xcoord, ycoord, elevation); if (j != 0) { printf ("error in Get_elevation\n"); exit (1); } return (1); } else { *elevation = NdTemp->get_elevation () * (matprops->LENGTH_SCALE); return (0); } }
void cxxTitanSimulation::init_piles() { MatProps* matprops_ptr = get_matprops(); FluxProps* fluxprops_ptr = get_fluxprops(); TimeProps* timeprops_ptr = get_timeprops(); StatProps* statprops_ptr = get_statprops(); ElementsHashTable* HT_Elem_Ptr=get_HT_Elem(); NodeHashTable* HT_Node_Ptr=get_HT_Node(); PileProps* pileprops_ptr=get_pileprops(); unsigned nodes[9][KEYLENGTH], *node_key; int no_of_buckets = HT_Elem_Ptr->get_no_of_buckets(); vector<HashEntryLine> &bucket=HT_Elem_Ptr->bucket; tivector<Element> &elenode_=HT_Elem_Ptr->elenode_; PileProps::PileType pile_type= pileprops_ptr->get_default_piletype(); int i; bool allPilesAreElliptical=true; for(i=0;i<pileprops_ptr->numpiles;i++) { if(!(pileprops_ptr->pile_type[i] == PileProps::PARABALOID || pileprops_ptr->pile_type[i] == PileProps::CYLINDER)) allPilesAreElliptical=false; } if(pileprops_ptr->numpiles>0)pile_type= pileprops_ptr->pile_type[0]; if(!adapt) H_adapt_to_level(HT_Elem_Ptr, HT_Node_Ptr, matprops_ptr, pileprops_ptr, fluxprops_ptr, timeprops_ptr, REFINE_LEVEL); if(allPilesAreElliptical) { if(adapt) initial_H_adapt(HT_Elem_Ptr, HT_Node_Ptr, 0, matprops_ptr, pileprops_ptr, fluxprops_ptr, timeprops_ptr, 4); } else { printf("It seems this type of piles have hardcoded coordinates\n"); assert(0); //@ElementsBucketDoubleLoop for(int ibuck = 0; ibuck < no_of_buckets; ibuck++) { for(int ielm = 0; ielm < bucket[ibuck].ndx.size(); ielm++) { Element *EmTemp = &(elenode_[bucket[ibuck].ndx[ielm]]); if(EmTemp->adapted_flag() > 0) { //put in the pile height right here... double pile_height = 0.0; double radius_sq; switch (pile_type) { case PileProps::PLANE: radius_sq = pow(EmTemp->coord(0) - 76., 2) + pow(EmTemp->coord(1) - 80., 2); if(radius_sq < 35.) pile_height = 10 * (1. - radius_sq / 35.); break; case PileProps::CASITA: radius_sq = pow(EmTemp->coord(0) - 504600., 2) + pow(EmTemp->coord(1) - 1402320., 2); if(radius_sq < 30000.) pile_height = 15 * (1. - radius_sq / 30000.); break; case PileProps::POPO: //popo topo radius_sq = pow(EmTemp->coord(0) - 537758. / matprops_ptr->scale.length, 2) + pow(EmTemp->coord(1) - 2100910. / matprops_ptr->scale.length, 2); if(radius_sq < (10000. / matprops_ptr->scale.length)) pile_height = 1. - radius_sq / (10000. / matprops_ptr->scale.length); break; case PileProps::ID1: // iverson and denlinger experiments I -- as pictured if(EmTemp->coord(0) < 53.345 && EmTemp->coord(0) > 45.265 && EmTemp->coord(1) > -10. && EmTemp->coord(1) < 300.) { if(EmTemp->coord(0) < 51.148) pile_height = 3.5912 * (1.0 - (51.148 - EmTemp->coord(0)) / 5.8832); else pile_height = 3.59 * (53.345 - EmTemp->coord(0)) / 2.1967; if(pile_height < 0) pile_height = 0; } break; case PileProps::ID2: //iverson and denlinger experiments II -- 90 angle with plane if(EmTemp->coord(0) < 53.345 / matprops_ptr->scale.length && EmTemp->coord(0) > 46.45 / matprops_ptr->scale.length) pile_height = 4.207255 * (1.0 - (53.345 / matprops_ptr->scale.length - EmTemp->coord(0)) / 6.895 * matprops_ptr->scale.length); break; default: printf("Danger no recognized pile type defined in init_piles.C\n"); assert(0); } EmTemp->put_height(pile_height); } } } } //end "#if defined PARABALOID || defined CYLINDER" move_data(numprocs, myid, HT_Elem_Ptr, HT_Node_Ptr, timeprops_ptr); //update temporary arrays of elements/nodes pointers HT_Node_Ptr->flushNodeTable(); HT_Elem_Ptr->flushElemTable(); HT_Elem_Ptr->updateLocalElements(); HT_Elem_Ptr->updateNeighboursIndexes(); slopes(HT_Elem_Ptr, HT_Node_Ptr, matprops_ptr); /* initial calculation of actual volume on the map */ double realvolume = 0.0, depositedvol = 0.0, forcebed = 0.0, meanslope = 0.0; double epsilon[DIMENSION]; for(i=0;i<DIMENSION;i++) epsilon[i]=matprops_ptr->scale.epsilon; //@ElementsBucketDoubleLoop for(int ibuck = 0; ibuck < no_of_buckets; ibuck++) { for(int ielm = 0; ielm < bucket[ibuck].ndx.size(); ielm++) { Element* Curr_El = &(elenode_[bucket[ibuck].ndx[ielm]]); if(Curr_El->adapted_flag() > 0) { //if this is a refined element don't involve!!! double dvol = Curr_El->dx(0) * Curr_El->dx(1) * Curr_El->state_vars(0); realvolume += dvol; Curr_El->set_kactxy(epsilon); Curr_El->calc_stop_crit(matprops_ptr,integrator); if(Curr_El->stoppedflags() == 2) depositedvol += dvol; double resolution = 0, xslope = 0, yslope = 0; Get_max_resolution(&resolution); Get_slope(resolution, Curr_El->coord(0) * matprops_ptr->scale.length, Curr_El->coord(1) * matprops_ptr->scale.length, xslope, yslope); double slope = sqrt(xslope * xslope + yslope * yslope); forcebed += dvol * 9.8 / sqrt(1.0 + slope * slope) * tan(matprops_ptr->bedfrict[Curr_El->material()]); } } } double tempin[3], tempout[3]; tempin[0] = realvolume; tempin[1] = forcebed; tempin[2] = depositedvol; #ifdef USE_MPI MPI_Reduce(tempin, tempout, 3, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); #else //USE_MPI for(int i9=0;i9<3;++i9)tempout[i9]=tempin[i9]; #endif //USE_MPI statprops_ptr->realvolume = tempout[0] * (matprops_ptr->scale.height) * (matprops_ptr->scale.length) * (matprops_ptr->scale.length); statprops_ptr->outflowvol = 0.0; statprops_ptr->erodedvol = 0.0; statprops_ptr->depositedvol = tempout[2] * (matprops_ptr->scale.height) * (matprops_ptr->scale.length) * (matprops_ptr->scale.length); statprops_ptr->forceint = 0.0; statprops_ptr->forcebed = tempout[1] / tempout[0]; return; }
Node::Node(FILE* fp, MatProps* matprops_ptr) { sol=0; //never USED anywhere in TITAN except when initialized sol_deleted=0; //never USED anywhere in TITAN except when initialized nextptr=preptr=0;//never USED anywhere in TITAN except when initialized FourBytes temp4; EightBytes temp8; //unsigned readspace[13]; unsigned readspace[8]; int Itemp=0, itemp; //fread(readspace,sizeof(unsigned),13,fp); fread(readspace,sizeof(unsigned),8,fp); //KEYLENGTH should be 2 but put it in a loop to make it generic. for(itemp=0;itemp<KEYLENGTH;itemp++) { key[itemp]=readspace[Itemp++]; } assert(Itemp==2); //DIMENSION should be 2 but put it in a loop to make it generic. for(itemp=0;itemp<DIMENSION;itemp++) { temp8.u[0]=readspace[Itemp++]; temp8.u[1]=readspace[Itemp++]; coord[itemp]=temp8.d; } assert(Itemp==6); temp4.u=readspace[Itemp++]; id=temp4.i; assert(Itemp==7); temp4.u=readspace[Itemp++]; info=temp4.i; assert(Itemp==8); /* these are legacy and are not used temp4.u=readspace[Itemp++]; order=temp4.i; assert(Itemp==9); temp4.u=readspace[Itemp++]; dof[0]=temp4.i; temp4.u=readspace[Itemp++]; dof[1]=temp4.i; assert(Itemp==11); temp4.u=readspace[Itemp++]; glnum=temp4.i; assert(Itemp==12); temp4.u=readspace[Itemp++]; reconstructed=temp4.i; assert(Itemp==13); */ // find the max resolution of the GIS info and then get the elevation at this node double resolution = 0; double xcoord = coord[0]*(matprops_ptr->LENGTH_SCALE); double ycoord = coord[1]*(matprops_ptr->LENGTH_SCALE); int i = Get_max_resolution(&resolution); if(i != 0) { printf("error in Get_max_resolution\n"); exit(1); } i = Get_elevation(resolution, xcoord, ycoord, &elevation); if(i != 0) { printf("error in Get_elevation\n"); exit(1); } elevation = elevation/matprops_ptr->LENGTH_SCALE; return; }
void calc_stats(ElementType elementType, HashTable* El_Table, HashTable* NodeTable, int myid, MatProps* matprops, TimeProps* timeprops, StatProps* statprops, DischargePlanes* discharge, double d_time) { int i, iproc; double area = 0.0, max_height = 0.0; double cutoffvolume; /* the desired volume of material to take statistics from, this is portion is the one with the largest heights, for example sampling the 95% (by volume) of the pile with the largest heights, the fraction is set by STAT_VOL_FRAC define statement */ double cutoffheight = 0.0; /* a pile height criteria equivalent to the cutoffvolume, this criteria is found at each iteration */ double statvolume; /* volume where pile thickness >= cutoffheight statvolume >= cutoffvolume */ double realvolume = 0.0; /* the total volume on this processor or across processors */ double slopevolume = 0.0; /* volume used to determine the average slope in the direction of velocity, slopevolume<=statvolume because can't count cells with zero velocity */ double testpointheight = statprops->heightifreach; double testpointx = statprops->xyifreach[0]; double testpointy = statprops->xyifreach[1]; double testpointdist2; double testpointmindist2; testpointmindist2 = pow(2.0, 30.0); //HUGE_VAL; int testpointreach = 0; double testvolume = 0.0; double slope_ave = 0.0; double v_max = 0.0, v_ave = 0.0, vx_ave = 0.0, vy_ave = 0.0, g_ave; double xC = 0.0, yC = 0.0, rC = 0.0, piler2 = 0.0; double xVar = 0.0, yVar = 0.0; //assume that mean starting location is at (x,y) = (1,1) double xCen = 1.2; //0; //1.0/(matprops->LENGTH_SCALE); double yCen = 0.3; //0; //1.0/(matprops->LENGTH_SCALE); double dVol, dA; double min_height = matprops->MAX_NEGLIGIBLE_HEIGHT; double temp; int numproc; double xyminmax[4]; for(i = 0; i < 4; i++) xyminmax[i] = HUGE_VAL; MPI_Comm_size(MPI_COMM_WORLD, &numproc); /* need to allocate space to store nonzero pile heights and volumes, to do that we first have to count the number of nonzero elements */ int num_buck = El_Table->get_no_of_buckets(); HashEntryPtr* buck = El_Table->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->get_state_vars()) > GEOFLOW_TINY) num_nonzero_elem++; currentPtr = currentPtr->next; } } /******************************************************************/ /*** the rewrite involves a sort which increases the cost/time ***/ /*** significantly and does not appear to provide a significant ***/ /*** increase in accuracy of the statistics (it probably makes ***/ /*** them LESS precise/repeatable actually) so the section of ***/ /*** code has been disabled by the following preprocessor ***/ /*** directive. ***/ /******************************************************************/ #ifdef NONONONO printf("NONONONO\n"); /* now we need to tell processor 0 how many there are, so it can allocate space for when it combine their contributions to come up with a cut off height */ MPI_Request request, *proc0request; MPI_Status status, *proc0status; //fprintf(fp,"calc_stats() 2\n"); fflush(fp); if(numproc>1) { if(myid==0) { proc0request=(MPI_Request *) calloc(numproc,sizeof(MPI_Request)); proc0status=(MPI_Status *) calloc(numproc,sizeof(MPI_Status)); all_num_nonzero_elem=CAllocI1(numproc); all_num_nonzero_elem[0]=num_nonzero_elem; for(iproc=1;iproc<numproc;iproc++) MPI_Irecv(&all_num_nonzero_elem[iproc],1,MPI_INT,iproc,1,MPI_COMM_WORLD,&proc0request[iproc]); } else MPI_Isend(&num_nonzero_elem,1,MPI_INT,0,1,MPI_COMM_WORLD,&request); } //fprintf(fp,"calc_stats() 3\n"); fflush(fp); /* now each processor generates a list of pile heights and volumes for each nonzero element sorted in descending order */ double **myprochvol=CAllocD2(num_nonzero_elem,2); double height; int iplace; num_nonzero_elem=0; realvolume=0.0; 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())) { height=*(Curr_El->get_state_vars()); if(height>GEOFLOW_TINY) { /* place this height in right (sorted in descending order) spot in height/volume arrray */ for(iplace=num_nonzero_elem;iplace>0;iplace--) if(height>myprochvol[iplace-1][0]) { myprochvol[iplace][0]=myprochvol[iplace-1][0]; myprochvol[iplace][1]=myprochvol[iplace-1][1];} else break; myprochvol[iplace][0]=height; myprochvol[iplace][1]=height* *(Curr_El->get_dx())**(Curr_El->get_dx()+1); realvolume+=myprochvol[iplace][1]; num_nonzero_elem++; } } currentPtr=currentPtr->next; } } /* now processor zero will use those list(s) to determine the cut off height */ if(numproc==1) { //it's for a single processor so it's very simple cutoffvolume=STAT_VOL_FRAC*realvolume; statvolume =0.0; i=0; while((statvolume<cutoffvolume)&&(i<num_nonzero_elem)) { cutoffheight=myprochvol[i][0]; statvolume +=myprochvol[i++][1]; } CDeAllocD2(myprochvol); } else { // to get a clear idea of what I want to do take a look // at the single processor version (the else to this if) // and ask your self what you would need to do if instead // of one array of sorted heights-volume pairs, you had // numproc of them... that is at every step you look at // the largest not yet counted height from each array and // add the largest ones volume to the total //fprintf(fp,"calc_stats() 4\n"); fflush(fp); //add up the real volume across all processors temp=realvolume; MPI_Reduce(&temp,&realvolume,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); if(myid>0) { //send my processor's list of height and volume to processor 0 //fprintf(fp,"calc_stats() 5\n"); fflush(fp); MPI_Isend(myprochvol[0],num_nonzero_elem*2,MPI_DOUBLE,0,2,MPI_COMM_WORLD,&request); } else { //this is processor zero, myid==0 //fprintf(fp,"calc_stats() 6\n"); fflush(fp); //allocate one big 3D array to hold all the lists from across //all processors MPI_Waitall(numproc-1,proc0request+1,proc0status+1); int max_num_nonzero_elem=num_nonzero_elem; for(iproc=1;iproc<numproc;iproc++) if(max_num_nonzero_elem<all_num_nonzero_elem[iproc]) max_num_nonzero_elem=all_num_nonzero_elem[iproc]; double ***hvol=CAllocD3(numproc,max_num_nonzero_elem,2); //fprintf(fp,"calc_stats() 7\n"); fflush(fp); //bring the individual processors' sorted lists of height and //volume (hvol) over to processor 0 for(iproc=1;iproc<numproc;iproc++) MPI_Irecv(hvol[iproc][0],all_num_nonzero_elem[iproc]*2,MPI_DOUBLE,iproc,2,MPI_COMM_WORLD,&proc0request[iproc]); for(i=0;i<all_num_nonzero_elem[0];i++) { hvol[0][i][0]=myprochvol[i][0]; hvol[0][i][1]=myprochvol[i][1];} //fprintf(fp,"calc_stats() 8\n"); fflush(fp); MPI_Waitall(numproc-1,proc0request+1,proc0status+1); free(proc0request); free(proc0status); //fprintf(fp,"calc_stats() 9\n"); fflush(fp); /* find the cut off height that results in statvolume= STAT_VOL_FRAC*realvolume statvolume= volume represented in stats realvolume= total volume */ cutoffvolume=STAT_VOL_FRAC*realvolume; statvolume =0.0; int *icurrent=CAllocI1(numproc); //fprintf(fp,"calc_stats() 10\n"); fflush(fp); //set the current "element" on each "processor" to the one with //the maximum height on that processor (the first one) for(iproc=0;iproc<numproc;iproc++) icurrent[iproc]=0; int imaxh=0; //check to see if the cut off height is small enough that we have //equaled or exceeded the cut off volume while((statvolume<cutoffvolume)&& (icurrent[imaxh]<max_num_nonzero_elem)) { //find the largest height among the "current" elements and make //it the cut off height for(iproc=0;iproc<numproc;iproc++) if((icurrent[iproc]<all_num_nonzero_elem[iproc])&& (hvol[iproc][icurrent[iproc]][0]> hvol[imaxh][icurrent[imaxh]][0])) imaxh=iproc; cutoffheight=hvol[imaxh][icurrent[imaxh]][0]; //add that element's volume to the total statvolume +=hvol[imaxh][icurrent[imaxh]++][1]; } //fprintf(fp,"calc_stats() 11\n"); fflush(fp); CDeAllocD3(hvol); CDeAllocI1(all_num_nonzero_elem); CDeAllocI1(icurrent); } //fprintf(fp,"calc_stats() 12\n"); fflush(fp); CDeAllocD2(myprochvol); //fprintf(fp,"calc_stats() 13\n"); fflush(fp); MPI_Bcast(&cutoffheight,1,MPI_DOUBLE,0,MPI_COMM_WORLD); //fprintf(fp,"calc_stats() 14\n"); fflush(fp); } #endif /**************************************************/ /****** TADA!!!!!!!!! we have finally found ******/ /****** this iteration's cut off height (and ******/ /****** the global volumes too) now we can ******/ /****** calculate the rest of the stats in a ******/ /****** straight forward manner ******/ /**************************************************/ //for TWO PHASES double Vsolid[2]; double Vfluid[2]; //for SINGLE PHASE double VxVy[2]; for(i = 0; i < num_buck; i++) if(*(buck + i)) { HashEntryPtr currentPtr = *(buck + i); while (currentPtr) { Element* Curr_El = (Element*) (currentPtr->value); assert(Curr_El!=NULL); if((Curr_El->get_adapted_flag() > 0) && (myid == Curr_El->get_myprocess())) { double* state_vars = Curr_El->get_state_vars(); //calculate volume passing through "discharge planes" unsigned *nodes = Curr_El->getNode(); Node** nodesPtr = Curr_El->getNodesPtrs(); double nodescoord[9][2], *coord; Node* node; for(int inode = 0; inode < 8; inode++) { node = nodesPtr[inode]; //(Node*) NodeTable->lookup(nodes + 2 * inode); coord = node->get_coord(); /*if ((timeprops->iter == 291) && (inode == 8)) { printf("coord=(%g,%g) node=%u ", coord[0], coord[1], node); fflush(stdout); }*/ nodescoord[inode][0] = coord[0]; nodescoord[inode][1] = coord[1]; /*if ((timeprops->iter == 291) && (inode >= 8)) { printf("inode=%d node=%u", inode, node); fflush(stdout); }*/ } nodescoord[8][0] = *(Curr_El->get_coord()); nodescoord[8][1] = *(Curr_El->get_coord() + 1); discharge->update(nodescoord, state_vars, d_time); // rule out non physical fast moving thin layers //if(state_vars[0] >= cutoffheight){ if(state_vars[0] > min_height) { if(state_vars[0] > max_height) max_height = state_vars[0]; double* xy = Curr_El->get_coord(); if(state_vars[0] >= statprops->hxyminmax) { if(xy[0] < xyminmax[0]) //xmin xyminmax[0] = xy[0]; if(-xy[0] < xyminmax[1]) //negative xmax xyminmax[1] = -xy[0]; if(xy[1] < xyminmax[2]) //ymin xyminmax[2] = xy[1]; if(-xy[1] < xyminmax[3]) //negative ymax xyminmax[3] = -xy[1]; } //to test if pileheight of depth testpointheight //has reached the testpoint testpointdist2 = (xy[0] - testpointx) * (xy[0] - testpointx) + (xy[1] - testpointy) * (xy[1] - testpointy); double junktest = 0; if(testpointdist2 > 0) junktest = testpointdist2; if(testpointmindist2 > 0) junktest = testpointmindist2; if(testpointdist2 < testpointmindist2) { testpointmindist2 = testpointdist2; testpointreach = ((state_vars[0] >= testpointheight) ? 1 : 0); } dA = *(Curr_El->get_dx()) * *(Curr_El->get_dx() + 1); area += dA; dVol = state_vars[0] * dA; testvolume += dVol; xC += xy[0] * dVol; yC += xy[1] * dVol; xVar += xy[0] * xy[0] * dVol; yVar += xy[1] * xy[1] * dVol; piler2 += (xy[0] * xy[0] + xy[1] * xy[1]) * dVol; rC += sqrt((xy[0] - xCen) * (xy[0] - xCen) + (xy[1] - yCen) * (xy[1] - yCen)) * dVol; if(elementType == ElementType::TwoPhases) { v_ave += sqrt(state_vars[2] * state_vars[2] + state_vars[3] * state_vars[3]) * dA; Curr_El->eval_velocity(0.0, 0.0, Vsolid); if((!((v_ave <= 0.0) || (0.0 <= v_ave))) || (!((state_vars[0] <= 0.0) || (0.0 <= state_vars[0]))) || (!((state_vars[1] <= 0.0) || (0.0 <= state_vars[1]))) || (!((state_vars[2] <= 0.0) || (0.0 <= state_vars[2]))) || (!((state_vars[3] <= 0.0) || (0.0 <= state_vars[3]))) || (!((state_vars[4] <= 0.0) || (0.0 <= state_vars[4]))) || (!((state_vars[5] <= 0.0) || (0.0 <= state_vars[5])))) { //v_ave is NaN printf("calc_stats(): NaN detected in element={%10u,%10u} at iter=%d\n", *(Curr_El->pass_key() + 0), *(Curr_El->pass_key() + 1), timeprops->iter); printf("prevu={%12.6g,%12.6g,%12.6g,%12.6g,%12.6g,%12.6g}\n", *(Curr_El->get_prev_state_vars() + 0), *(Curr_El->get_prev_state_vars() + 1), *(Curr_El->get_prev_state_vars() + 2), *(Curr_El->get_prev_state_vars() + 3), *(Curr_El->get_prev_state_vars() + 4), *(Curr_El->get_prev_state_vars() + 5)); printf(" u={%12.6g,%12.6g,%12.6g,%12.6g,%12.6g,%12.6g}\n", state_vars[0], state_vars[1], state_vars[2], state_vars[3], state_vars[4], state_vars[5]); printf("prev {Vx_s, Vy_s, Vx_f, Vy_f}={%12.6g,%12.6g,%12.6g,%12.6g}\n", *(Curr_El->get_prev_state_vars() + 2) / (*(Curr_El->get_prev_state_vars() + 1)), *(Curr_El->get_prev_state_vars() + 3) / (*(Curr_El->get_prev_state_vars() + 1)), *(Curr_El->get_prev_state_vars() + 4) / (*(Curr_El->get_prev_state_vars())), *(Curr_El->get_prev_state_vars() + 5) / (*(Curr_El->get_prev_state_vars()))); printf("this {Vx_s, Vy_s, Vx_f, Vy_f}={%12.6g,%12.6g,%12.6g,%12.6g}\n", state_vars[2] / state_vars[1], state_vars[3] / state_vars[1], state_vars[4] / state_vars[0], state_vars[5] / state_vars[0]); ElemBackgroundCheck2(El_Table, NodeTable, Curr_El, stdout); exit(1); } temp = sqrt(Vsolid[0] * Vsolid[0] + Vsolid[1] * Vsolid[1]); if(temp > v_max) v_max = temp; vx_ave += state_vars[2] * dA; vy_ave += state_vars[3] * dA; } if(elementType == ElementType::SinglePhase) { v_ave += sqrt(state_vars[1] * state_vars[1] + state_vars[2] * state_vars[2]) * dA; Curr_El->eval_velocity(0.0, 0.0, VxVy); if((!((v_ave <= 0.0) || (0.0 <= v_ave))) || (!((state_vars[0] <= 0.0) || (0.0 <= state_vars[0]))) || (!((state_vars[1] <= 0.0) || (0.0 <= state_vars[1]))) || (!((state_vars[2] <= 0.0) || (0.0 <= state_vars[2])))) { //v_ave is NaN printf("calc_stats(): NaN detected in element={%10u,%10u} at iter=%d\n", *(Curr_El->pass_key() + 0), *(Curr_El->pass_key() + 1), timeprops->iter); printf("prevu={%12.6g,%12.6g,%12.6g}\n", *(Curr_El->get_prev_state_vars() + 0), *(Curr_El->get_prev_state_vars() + 1), *(Curr_El->get_prev_state_vars() + 2)); printf(" u={%12.6g,%12.6g,%12.6g}\n", state_vars[0], state_vars[1], state_vars[2]); printf("prev {hVx/h,hVy/h}={%12.6g,%12.6g}\n", *(Curr_El->get_prev_state_vars() + 1) / *(Curr_El->get_prev_state_vars() + 0), *(Curr_El->get_prev_state_vars() + 2) / *(Curr_El->get_prev_state_vars() + 0)); printf("this {hVx/h,hVy/h}={%12.6g,%12.6g}\n", state_vars[1] / state_vars[0], state_vars[2] / state_vars[0]); printf(" { Vx , Vy }={%12.6g,%12.6g}\n", VxVy[0], VxVy[1]); ElemBackgroundCheck2(El_Table, NodeTable, Curr_El, stdout); assert(0); } temp = sqrt(VxVy[0] * VxVy[0] + VxVy[1] * VxVy[1]); if(temp > v_max) v_max = temp; vx_ave += state_vars[1] * dA; vy_ave += state_vars[2] * dA; } //these are garbage, Bin Yu wanted them when he was trying to come up //with a global stopping criteria (to stop the calculation, not the pile) //volume averaged slope in the direction of velocity //a negative number means the flow is headed uphill double resolution = 0, xslope = 0, yslope = 0; Get_max_resolution(&resolution); Get_slope(resolution, *((Curr_El->get_coord())) * matprops->LENGTH_SCALE, *((Curr_El->get_coord()) + 1) * matprops->LENGTH_SCALE, &xslope, &yslope); if(temp > GEOFLOW_TINY) { if(elementType == ElementType::TwoPhases) { slope_ave += -(state_vars[2] * xslope + state_vars[3] * yslope) * dA / temp; } if(elementType == ElementType::SinglePhase) { slope_ave += -(state_vars[1] * xslope + state_vars[2] * yslope) * dA / temp; } slopevolume += dVol; } } } currentPtr = currentPtr->next; } } MPI_Reduce(xyminmax, statprops->xyminmax, 4, MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD); if(myid == 0) { statprops->xyminmax[0] *= (matprops->LENGTH_SCALE); statprops->xyminmax[1] *= -(matprops->LENGTH_SCALE); statprops->xyminmax[2] *= (matprops->LENGTH_SCALE); statprops->xyminmax[3] *= -(matprops->LENGTH_SCALE); } int inttempout; double tempin[14], tempout[14], temp2in[2], temp2out[2]; //find the minimum distance (squared) to the test point MPI_Allreduce(&testpointmindist2, tempout, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); //if this processor isn't the closest to the test point it doesn't count as it's flow reaching the point if(tempout[0] < testpointmindist2) testpointreach = 0; //did the closest point to the test point get reached by the flow? MPI_Reduce(&testpointreach, &inttempout, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); testpointreach = inttempout; tempin[0] = xC; tempin[1] = yC; tempin[2] = rC; tempin[3] = area; tempin[4] = v_ave; tempin[5] = vx_ave; tempin[6] = vy_ave; tempin[7] = slope_ave; tempin[8] = piler2; tempin[9] = slopevolume; tempin[10] = testvolume; tempin[11] = xVar; tempin[12] = yVar; tempin[13] = El_Table->get_no_of_entries(); i = MPI_Reduce(tempin, tempout, 14, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); temp2in[0] = max_height; temp2in[1] = v_max; i = MPI_Reduce(temp2in, temp2out, 2, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); if(myid == 0) { if(testpointreach && (statprops->timereached < 0.0)) statprops->timereached = timeprops->timesec(); double VELOCITY_SCALE = sqrt(matprops->LENGTH_SCALE * matprops->GRAVITY_SCALE); //dimensionalize statprops->xcen = tempout[0] * (matprops->LENGTH_SCALE) / tempout[10]; statprops->ycen = tempout[1] * (matprops->LENGTH_SCALE) / tempout[10]; statprops->xvar = tempout[11] * (matprops->LENGTH_SCALE) * (matprops->LENGTH_SCALE) / tempout[10] - (statprops->xcen) * (statprops->xcen); statprops->yvar = tempout[12] * (matprops->LENGTH_SCALE) * (matprops->LENGTH_SCALE) / tempout[10] - (statprops->ycen) * (statprops->ycen); statprops->rmean = tempout[2] * (matprops->LENGTH_SCALE) / tempout[10]; statprops->area = tempout[3] * (matprops->LENGTH_SCALE) * (matprops->LENGTH_SCALE); statprops->vmean = tempout[4] * VELOCITY_SCALE / tempout[10]; statprops->vxmean = tempout[5] * VELOCITY_SCALE / tempout[10]; statprops->vymean = tempout[6] * VELOCITY_SCALE / tempout[10]; statprops->slopemean = (tempout[9] > 0) ? tempout[7] / tempout[9] : 0.0; statprops->realvolume = realvolume * (matprops->LENGTH_SCALE) * (matprops->LENGTH_SCALE) * (matprops->HEIGHT_SCALE); //statvolume is really testvolume which is statvolume if it's not disabled statprops->statvolume = tempout[10] * (matprops->LENGTH_SCALE) * (matprops->LENGTH_SCALE) * (matprops->HEIGHT_SCALE); statprops->cutoffheight = cutoffheight * (matprops->HEIGHT_SCALE); testvolume = tempout[10] / statvolume; /* the factor of 3^0.5 is a safety factor, this value was chosen because * it makes the "radius" of a uniformly distributed line equal to half * the line length */ //3 standard deviations out ~ 99.5% of the material statprops->piler = 3.0 * sqrt(statprops->xvar + statprops->yvar); statprops->hmax = temp2out[0] * (matprops->HEIGHT_SCALE); statprops->vmax = temp2out[1] * VELOCITY_SCALE; /* v_star is the nondimensional global average velocity by v_slump once v_slump HAS BEEN CALIBRATED (not yet done see ../main/datread.C) the calculation will terminate when v_star reaches 1 */ statprops->vstar = statprops->vmean / matprops->Vslump; /******************/ /* output section */ /******************/ /* output Center Of Mass and x and y components of mean velocity to assist the dynamic gis update daemon */ if(elementType == ElementType::SinglePhase) { FILE* fp2 = fopen("com.up", "w"); fprintf(fp2, "%d %g %g %g %g %g %g\n", timeprops->iter, timeprops->timesec(), statprops->xcen, statprops->ycen, statprops->vxmean, statprops->vymean, statprops->piler); fclose(fp2); } /* standard to screen output */ d_time *= timeprops->TIME_SCALE; //chunk time int hours, minutes; double seconds; timeprops->chunktime(&hours, &minutes, &seconds); printf("At the end of time step %d the time is %d:%02d:%g (hrs:min:sec),\n", timeprops->iter, hours, minutes, seconds); printf("\ttime step length is %g [sec], volume is %g [m^3],\n", d_time, statprops->statvolume); printf("\tmax height is %g [m], max velocity is %g [m/s],\n", statprops->hmax, statprops->vmax); printf("\tave velocity is %g [m/s], v* = %g,\n", statprops->vmean, statprops->vstar); printf("\ttotal number of elements %.0f\n\n", tempout[13]); } return; }
void init_piles(HashTable* HT_Elem_Ptr, HashTable* HT_Node_Ptr, int myid, int numprocs, int adaptflag, MatProps* matprops, TimeProps* timeprops_ptr, MapNames* mapnames, PileProps* pileprops, FluxProps *fluxprops, StatProps* statprops) { unsigned nodes[9][KEYLENGTH], *node_key; int num_buckets=HT_Elem_Ptr->get_no_of_buckets(); if(!adaptflag) H_adapt_to_level(HT_Elem_Ptr,HT_Node_Ptr,matprops,pileprops, fluxprops,timeprops_ptr,REFINE_LEVEL); #if defined PARABALOID || defined CYLINDER if(adaptflag) initial_H_adapt(HT_Elem_Ptr, HT_Node_Ptr, 0, matprops, pileprops,fluxprops,timeprops_ptr,4); #else for(int ibucket=0; ibucket<num_buckets; ibucket++) { HashEntry *entryp = *(HT_Elem_Ptr->getbucketptr() + ibucket); //check every element in bucket while(entryp){ Element *EmTemp = (Element*)entryp->value; assert(EmTemp); if(EmTemp->get_adapted_flag()>0) { //put in the pile height right here... double* ndcoord = EmTemp->get_coord(); double pile_height=0.0; double radius_sq; EmTemp->put_height(pileheight); } entryp = entryp->next; } } #endif //end "#if defined PARABALOID || defined CYLINDER" move_data(numprocs, myid, HT_Elem_Ptr, HT_Node_Ptr,timeprops_ptr); slopes(HT_Elem_Ptr, HT_Node_Ptr, matprops); /* initial calculation of actual volume on the map */ double realvolume=0.0, depositedvol=0.0, forcebed=0.0, meanslope=0.0; double epsilon[2]={matprops->epsilon, matprops->epsilon}; HashEntryPtr* buck = HT_Elem_Ptr->getbucketptr(); for(int ibucket=0; ibucket<HT_Elem_Ptr->get_no_of_buckets(); ibucket++) if(*(buck+ibucket)) { HashEntryPtr currentPtr = *(buck+ibucket); while(currentPtr) { Element* Curr_El=(Element*)(currentPtr->value); assert(Curr_El); if(Curr_El->get_adapted_flag()>0) { //if this is a refined element don't involve!!! double *dxy=Curr_El->get_dx(); double dvol=dxy[0]*dxy[1]**(Curr_El->get_state_vars()+1); realvolume+=dvol; Curr_El->put_kactxy(epsilon); Curr_El->calc_stop_crit(matprops); if (Curr_El->get_stoppedflags()==2) depositedvol += dvol; double resolution=0, xslope=0, yslope=0; Get_max_resolution(&resolution); Get_slope(resolution, *((Curr_El->get_coord()))*matprops->LENGTH_SCALE, *((Curr_El->get_coord())+1)*matprops->LENGTH_SCALE, &xslope,&yslope); double slope=sqrt(xslope*xslope+yslope*yslope); forcebed+=dvol*9.8/sqrt(1.0+slope*slope)* tan(matprops->bedfrict[Curr_El->get_material()]); Curr_El->level_set(HT_Elem_Ptr); } currentPtr=currentPtr->next; } } //========================================================================================================================= for(int ibucket=0; ibucket<HT_Elem_Ptr->get_no_of_buckets(); ibucket++) if(*(buck+ibucket)) { HashEntryPtr currentPtr = *(buck+ibucket); while(currentPtr) { Element* Curr_El=(Element*)(currentPtr->value); assert(Curr_El); if(Curr_El->get_adapted_flag()>0) { if(*( Curr_El->get_state_vars()+5)==3) *(Curr_El->get_state_vars())=0.0;//to make zero phi on the boundary } currentPtr=currentPtr->next; } } double tempin[3], tempout[3]; tempin[0]=realvolume; tempin[1]=forcebed; tempin[2]=depositedvol; MPI_Reduce(tempin,tempout,3,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); statprops->realvolume=tempout[0]*(matprops->HEIGHT_SCALE) *(matprops->LENGTH_SCALE)*(matprops->LENGTH_SCALE); statprops->outflowvol=0.0; statprops->erodedvol=0.0; statprops->depositedvol=tempout[2]*(matprops->HEIGHT_SCALE) *(matprops->LENGTH_SCALE)*(matprops->LENGTH_SCALE); statprops->forceint=0.0; statprops->forcebed=tempout[1]/tempout[0]; return; }