double get_coef_and_eigen(HashTable* El_Table, HashTable* NodeTable, MatProps* matprops_ptr, FluxProps* fluxprops_ptr, TimeProps* timeprops_ptr, int ghost_flag) { int myid; MPI_Comm_rank(MPI_COMM_WORLD, &myid); double min_distance = 1000000, max_evalue = GEOFLOW_TINY, doubleswap; int ibuck, ierr; double tiny = GEOFLOW_TINY, min_dx_dy_evalue = 10000000, hmax = 0; double evalue = 1.0; //might need to change this //-------------------go through all the elements of the subdomain and get //-------------------the coefficients and eigenvalues and calculate the time step double global_dt[3], dt[3] = { 0.0, 0.0, HUGE_VAL }; HashEntryPtr* elem_bucket_zero = El_Table->getbucketptr(); HashEntryPtr entryp; int num_elem_buckets = El_Table->get_no_of_buckets(); Element *EmTemp; //beginning of section that SHOULD ____NOT___ be openmp'd double maxinflux = 0.0; if ((maxinflux = fluxprops_ptr->MaxInfluxNow(matprops_ptr, timeprops_ptr) * (matprops_ptr->epsilon)) > 0.0) { double mindx = -1.0; ; for (ibuck = 0; ibuck < num_elem_buckets; ibuck++) { entryp = *(elem_bucket_zero + ibuck); while (entryp) { EmTemp = (Element*) (entryp->value); entryp = entryp->next; if ((EmTemp->get_adapted_flag() > 0) || (EmTemp->get_adapted_flag() < 0)) { mindx = ((*(EmTemp->get_dx() + 0) < *(EmTemp->get_dx() + 1)) ? *(EmTemp->get_dx() + 0) : *(EmTemp->get_dx() + 1)) * pow(0.5, REFINE_LEVEL - EmTemp->get_gen()); break; } } if (mindx > 0.0) break; } double dttemp = mindx / maxinflux; //equivalent to dx/eigen_speed //equivalent to 0.9*sqrt(hmax/g) where hmax=maxinflux*dt when xVel and yVel =0 double dttemp2 = 0.81 * maxinflux * (matprops_ptr->GRAVITY_SCALE) / 9.8; dt[2] = c_dmin1(dttemp, dttemp2); } //end of section that SHOULD ____NOT___ be openmp'd double kactxy[DIMENSION]; double* d_uvec, *dx_ptr; int intswap; double *curve, maxcurve; int ifanynonzeroheight = 0; double Vsolid[2], Vfluid[2]; for (ibuck = 0; ibuck < num_elem_buckets; ibuck++) { entryp = *(elem_bucket_zero + ibuck); while (entryp) { EmTemp = (Element*) (entryp->value); entryp = entryp->next; if ((EmTemp->get_adapted_flag() > 0) || ((EmTemp->get_adapted_flag() < 0) && (ghost_flag == 1))) { //if this element does not belong on this processor don't involve!!! if (*(EmTemp->get_state_vars() + 1) > GEOFLOW_TINY) { ifanynonzeroheight = 1; /* calculate hmax */ if (hmax < *(EmTemp->get_state_vars() + 1)) hmax = *(EmTemp->get_state_vars() + 1); //printf("Please attention the phi is .......................... %f\n", *(EmTemp->get_state_vars())); d_uvec = EmTemp->get_d_state_vars(); dx_ptr = EmTemp->get_dx(); #ifdef SUNOS gmfggetcoef_(EmTemp->get_state_vars(), d_uvec, (d_uvec + NUM_STATE_VARS), dx_ptr, &(matprops_ptr->bedfrict[EmTemp->get_material()]), &(matprops_ptr->intfrict), &kactxy[0], &kactxy[1], &tiny, &(matprops_ptr->epsilon)); //printf("probably this is the problem ........first Kx=%f...........second Ky=%f.............\n",kactxy[0],kactxy[1]); EmTemp->put_kactxy(kactxy); EmTemp->calc_stop_crit(matprops_ptr); intswap = EmTemp->get_stoppedflags(); if ((intswap < 0) || (intswap > 2)) printf("get_coef_and_eigen stopped flag=%d\n", intswap); //must use hVx/h and hVy/h rather than eval_velocity (L'Hopital's //rule speed if it is smaller) because underestimating speed (which //results in over estimating the timestep) is fatal to stability... //if (*(EmTemp->get_state_vars()+1)>.0001){ Vsolid[0] = (*(EmTemp->get_state_vars() + 2)) / (*(EmTemp->get_state_vars() + 1)); Vsolid[1] = (*(EmTemp->get_state_vars() + 3)) / (*(EmTemp->get_state_vars() + 1)); Vfluid[0] = 0;//(*(EmTemp->get_state_vars()+4))/(*(EmTemp->get_state_vars()+1)); Vfluid[1] = 0;//(*(EmTemp->get_state_vars()+4))/(*(EmTemp->get_state_vars()+1)); //}else // Vsolid[0]=Vsolid[1]=Vfluid[0]=Vfluid[1]=0; //printf("the value of height=%f .................phi=%f\n", *(EmTemp->get_state_vars()+1),*(EmTemp->get_state_vars())); //printf("there should be some other problem ....vsolid_x=%f....vsolid_y=%f.........vfluid_x=%f.....vfluid_y=%f \n",Vsolid[0],Vsolid[1],Vfluid[0],Vfluid[1]); eigen_(EmTemp->get_state_vars(), (EmTemp->get_eigenvxymax()), (EmTemp->get_eigenvxymax() + 1), &evalue, &tiny, EmTemp->get_kactxy(), EmTemp->get_gravity(), Vsolid, Vfluid, &(matprops_ptr->epsilon), &(matprops_ptr->flow_type)); if (isnan(evalue)) printf( "the evalue is NaN: pile height= %f phi=%f \n", *(EmTemp->get_state_vars() + 1), *(EmTemp->get_state_vars())); #endif // *********************************************************** // !!!!!!!!!!!!!!!!!!!!!check dx & dy!!!!!!!!!!!!!!!!!!!!!!!! // *********************************************************** doubleswap = c_dmin1(dx_ptr[0], dx_ptr[1]); if (doubleswap / evalue < min_dx_dy_evalue) { min_distance = doubleswap; max_evalue = evalue; } if (evalue > 1000000000.) { curve = EmTemp->get_curvature(); maxcurve = (dabs(curve[0]) > dabs(curve[1])) ? curve[0] : curve[1]; fprintf(stderr, "eigenvalue is %e for procd %d momentums are:\n \ solid :(%e, %e) \n \ fluid :(%e, %e) \n \ for pile height %e phi %e curvature=%e (x,y)=(%e,%e)\n \ with gravity=%f k_xy=%f \n", evalue, myid, *(EmTemp->get_state_vars() + 2), *(EmTemp->get_state_vars() + 3), *(EmTemp->get_state_vars() + 4), *(EmTemp->get_state_vars() + 5), *(EmTemp->get_state_vars() + 1), *(EmTemp->get_state_vars()), maxcurve, *(EmTemp->get_coord()), *(EmTemp->get_coord() + 1)), *(EmTemp->get_gravity() + 3), *(EmTemp->get_kactxy()); exit(1); } min_dx_dy_evalue = c_dmin1( c_dmin1(dx_ptr[0], dx_ptr[1]) / evalue, min_dx_dy_evalue); } else { EmTemp->calc_stop_crit(matprops_ptr); // ensure decent friction-values kactxy[0] = kactxy[1] = matprops_ptr->epsilon; EmTemp->put_kactxy(kactxy); } } //(EmTemp->get_adapted_flag()>0)||...
double Integrator_SinglePhase_Pouliquen_Forterre::get_coef_and_eigen(int ghost_flag) { int myid; MPI_Comm_rank(MPI_COMM_WORLD, &myid); int ierr; double min_dx_dy_evalue = 10000000.0, hmax = 0.0; //double evalue = 1.0; //might need to change this //-------------------go through all the elements of the subdomain and get //-------------------the coefficients and eigenvalues and calculate the time step double global_dt[3], dt[3] = { 0.0, 0.0, HUGE_VAL }; //beginning of section that SHOULD ____NOT___ be openmp'd //why the first element is good enough? double maxinflux = 0.0; if((maxinflux = fluxprops_ptr->MaxInfluxNow(matprops_ptr, timeprops_ptr) * scale_.epsilon) > 0.0) { double mindx = -1.0; for(ti_ndx_t ndx = 0; ndx < elements_.size(); ndx++) { if(adapted_[ndx]!=0) { mindx = (dx_[0][ndx] < dx_[1][ndx]) ? dx_[0][ndx] : dx_[1][ndx] * pow(0.5, REFINE_LEVEL - generation_[ndx]); break; } } double dttemp = mindx / maxinflux; //equivalent to dx/eigen_speed //equivalent to 0.9*sqrt(hmax/g) where hmax=maxinflux*dt when xVel and yVel =0 double dttemp2 = 0.81 * maxinflux * (scale_.gravity) / 9.8; dt[2] = c_dmin1(dttemp, dttemp2); } //end of section that SHOULD ____NOT___ be openmp'd #pragma omp parallel for schedule(dynamic,TITAN2D_DINAMIC_CHUNK) reduction(min:min_dx_dy_evalue) reduction(max:hmax) for(ti_ndx_t ndx = 0; ndx < elements_.size(); ndx++) { if((adapted_[ndx] > 0) || ((adapted_[ndx] < 0) && (ghost_flag == 1))) { //if this element does not belong on this processor don't involve!!! if(h[ndx] > GEOFLOW_TINY) { double VxVy[2]; double evalue; /* calculate hmax */ if(hmax < h[ndx]) hmax = h[ndx]; gmfggetcoef_PF(kactxy_[0][ndx], kactxy_[1][ndx], scale_.epsilon); elements_[ndx].calc_stop_crit(matprops_ptr, this); if((stoppedflags_[ndx] < 0) || (stoppedflags_[ndx] > 2)) printf("get_coef_and_eigen stopped flag=%d\n", stoppedflags_[ndx]); //must use hVx/h and hVy/h rather than eval_velocity (L'Hopital's //rule speed if it is smaller) because underestimating speed (which //results in over estimating the timestep) is fatal to stability... VxVy[0] = hVx[ndx] / h[ndx]; VxVy[1] = hVy[ndx] / h[ndx]; //eigen_(EmTemp->eval_state_vars(u_vec_alt), eigen_PF(h[ndx], eigenvxymax_[0][ndx],eigenvxymax_[1][ndx], evalue, tiny, kactxy_[0][ndx], gravity_[2][ndx], VxVy); // *********************************************************** // !!!!!!!!!!!!!!!!!!!!!check dx & dy!!!!!!!!!!!!!!!!!!!!!!!! // *********************************************************** if(evalue > 1000000000.) { double maxcurve = (dabs(curvature_[0][ndx]) > dabs(curvature_[1][ndx]) ? curvature_[0][ndx] : curvature_[1][ndx]); printf(" eigenvalue is %e for procd %d momentums are %e %e for pile height %e curvature=%e (x,y)=(%e,%e)\n", evalue, myid, hVx[ndx], hVy[ndx], h[ndx], maxcurve, coord_[0][ndx], coord_[1][ndx]); assert(0); } min_dx_dy_evalue = min( min(dx_[0][ndx], dx_[1][ndx]) / evalue, min_dx_dy_evalue); } else { stoppedflags_[ndx]=2; } } } dt[0] = 0.5 * min_dx_dy_evalue; dt[1] = -0.9 * sqrt(hmax * scale_.epsilon * scale_.gravity / 9.8); //find the negative of the max not the positive min #ifdef USE_MPI ierr = MPI_Allreduce(dt, global_dt, 3, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); #else //USE_MPI global_dt[0]=dt[0]; global_dt[1]=dt[1]; global_dt[2]=dt[2]; #endif //USE_MPI dt[0] = 0.5 * c_dmin1(global_dt[0], -global_dt[1]); if(dt[0] == 0.0) dt[0] = 0.5 * global_dt[2]; return dt[0]; }
double Integrator_TwoPhases::get_coef_and_eigen(int ghost_flag) { MatPropsTwoPhases* matprops2_ptr=static_cast<MatPropsTwoPhases*>(matprops_ptr); int myid; MPI_Comm_rank(MPI_COMM_WORLD, &myid); int ierr; double min_dx_dy_evalue = 10000000, hmax = 0; //might need to change this //-------------------go through all the elements of the subdomain and get //-------------------the coefficients and eigenvalues and calculate the time step double global_dt[3], dt[3] = { 0.0, 0.0, HUGE_VAL }; //beginning of section that SHOULD ____NOT___ be openmp'd //why the first element is good enough? double maxinflux = 0.0; if((maxinflux = fluxprops_ptr->MaxInfluxNow(matprops_ptr, timeprops_ptr) * (matprops_ptr->scale.epsilon)) > 0.0) { double mindx = -1.0; for(ti_ndx_t ndx = 0; ndx < elements_.size(); ndx++) { if(adapted_[ndx]!=0) { mindx = (dx_[0][ndx] < dx_[1][ndx]) ? dx_[0][ndx] : dx_[1][ndx] * pow(0.5, REFINE_LEVEL - generation_[ndx]); break; } } double dttemp = mindx / maxinflux; //equivalent to dx/eigen_speed //equivalent to 0.9*sqrt(hmax/g) where hmax=maxinflux*dt when xVel and yVel =0 double dttemp2 = 0.81 * maxinflux * (scale_.gravity) / 9.8; dt[2] = c_dmin1(dttemp, dttemp2); } //end of section that SHOULD ____NOT___ be openmp'd #pragma omp parallel for schedule(dynamic,TITAN2D_DINAMIC_CHUNK) reduction(min:min_dx_dy_evalue) reduction(max:hmax) for(ti_ndx_t ndx = 0; ndx < elements_.size(); ndx++) { if((adapted_[ndx] > 0) || ((adapted_[ndx] < 0) && (ghost_flag == 1))) { //if this element does not belong on this processor don't involve!!! if(h[ndx] > GEOFLOW_TINY) { double Vsolid[2], Vfluid[2]; double evalue; /* calculate hmax */ if(hmax < h[ndx]) hmax = h[ndx]; gmfggetcoef2ph(h_liq[ndx],hVx_sol[ndx],hVy_sol[ndx], dh_liq_dx[ndx],dhVx_sol_dx[ndx], dh_liq_dy[ndx],dhVy_sol_dy[ndx], matprops_ptr->bedfrict[material_[ndx]], int_frict, kactxy_[0][ndx], kactxy_[1][ndx], tiny, scale_.epsilon); elements_[ndx].calc_stop_crit(matprops_ptr, this); if((stoppedflags_[ndx] < 0) || (stoppedflags_[ndx] > 2)) printf("get_coef_and_eigen stopped flag=%d\n", stoppedflags_[ndx]); //must use hVx/h and hVy/h rather than eval_velocity (L'Hopital's //rule speed if it is smaller) because underestimating speed (which //results in over estimating the timestep) is fatal to stability... Vsolid[0] = hVx_sol[ndx] / h_liq[ndx]; Vsolid[1] = hVy_sol[ndx] / h_liq[ndx]; Vfluid[0] = hVx_liq[ndx] / h[ndx]; Vfluid[1] = hVy_liq[ndx] / h[ndx]; //eigen_(EmTemp->eval_state_vars(u_vec_alt), eigen2ph(h[ndx], h_liq[ndx], eigenvxymax_[0][ndx], eigenvxymax_[1][ndx], evalue, tiny, kactxy_[0][ndx], gravity_[2][ndx], Vsolid, Vfluid, matprops2_ptr->flow_type); // *********************************************************** // !!!!!!!!!!!!!!!!!!!!!check dx & dy!!!!!!!!!!!!!!!!!!!!!!!! // *********************************************************** if(evalue > 1000000000.) { double maxcurve = (dabs(curvature_[0][ndx]) > dabs(curvature_[1][ndx]) ? curvature_[0][ndx] : curvature_[1][ndx]); fprintf(stderr, "eigenvalue is %e for procd %d momentums are:\n \ solid :(%e, %e) \n \ fluid :(%e, %e) \n \ for pile height %e curvature=%e (x,y)=(%e,%e)\n", evalue, myid, hVx_sol[ndx],hVy_sol[ndx], hVx_liq[ndx],hVy_liq[ndx], h[ndx], maxcurve, coord_[0][ndx], coord_[1][ndx]); assert(0); } min_dx_dy_evalue = min( min(dx_[0][ndx], dx_[1][ndx]) / evalue, min_dx_dy_evalue); } else {
void ElementsProperties::get_slopes(ti_ndx_t ndx, double gamma) { int j = 0, bc = 0; /* check to see if this is a boundary */ while (j < 4 && bc == 0) { if(neigh_proc_[j][ndx] == INIT) bc = 1; j++; } if(bc == 1) { for(j = 0; j < NUM_STATE_VARS * DIMENSION; j++) d_state_vars_[j][ndx]=0.0; return; } int xp, xm, yp, ym; //x plus, x minus, y plus, y minus xp = positive_x_side_[ndx]; xm = (2 + xp) % 4; yp = (1 + xp) % 4; ym = (3 + xp) % 4; /* x direction */ ti_ndx_t ep = neighbor_ndx_[xp][ndx]; //(Element*) (ElemTable->lookup(&neighbor(xp)[0])); ti_ndx_t em = neighbor_ndx_[xm][ndx]; //(Element*) (ElemTable->lookup(&neighbor(xm)[0])); ti_ndx_t ep2 = ti_ndx_doesnt_exist; ti_ndx_t em2 = ti_ndx_doesnt_exist; //check if element has 2 neighbors on either side ti_ndx_t ndtemp = node_key_ndx_[xp + 4][ndx]; //(Node*) NodeTable->lookup(&node_key[xp + 4][0]); if(node_info_[ndtemp] == S_C_CON) { ep2 = neighbor_ndx_[xp + 4][ndx]; //(Element*) (ElemTable->lookup(&neighbor[xp + 4][0])); ASSERT3(neigh_proc_[xp + 4][ndx] >= 0 && ti_ndx_not_negative(ep2)); } ndtemp = node_key_ndx_[xm + 4][ndx]; //(Node*) NodeTable->lookup(&node_key[xm + 4][0]); if(node_info_[ndtemp] == S_C_CON) { em2 = neighbor_ndx_[xm + 4][ndx]; //(Element*) (ElemTable->lookup(&neighbor[xm + 4][0])); ASSERT3(neigh_proc_[xm + 4][ndx] >= 0 && ti_ndx_not_negative(em2)); } double dp, dm, dc, dxp, dxm; dxp = coord_[0][ep] - coord_[0][ndx]; dxm = coord_[0][ndx] - coord_[0][em]; for(j = 0; j < NUM_STATE_VARS; j++) { dp = (state_vars_[j][ep] - state_vars_[j][ndx]) / dxp; if(ti_ndx_not_negative(ep2)) dp = .5 * (dp + (state_vars_[j][ep2] - state_vars_[j][ndx]) / dxp); dm = (state_vars_[j][ndx] - state_vars_[j][em]) / dxm; if(ti_ndx_not_negative(em2)) dm = .5 * (dm + (state_vars_[j][ndx] - state_vars_[j][em2]) / dxm); dc = (dp * dxm + dm * dxp) / (dxm + dxp); // weighted average //do slope limiting d_state_vars_[j][ndx]=0.5 * (c_sgn(dp) + c_sgn(dm)) * c_dmin1(gamma * dabs(dp), gamma * dabs(dm), dabs(dc)); } /* y direction */ ep = neighbor_ndx_[yp][ndx]; //(Element*) (ElemTable->lookup(&neighbor(yp)[0])); em = neighbor_ndx_[ym][ndx]; //(Element*) (ElemTable->lookup(&neighbor(ym)[0])); ep2 = ti_ndx_doesnt_exist; em2 = ti_ndx_doesnt_exist; //check if element has 2 neighbors on either side ndtemp = node_key_ndx_[yp + 4][ndx]; //(Node*) NodeTable->lookup(&node_key[yp + 4][0]); if(node_info_[ndtemp] == S_C_CON) { ep2 = neighbor_ndx_[yp + 4][ndx]; //(Element*) (ElemTable->lookup(&neighbor[yp + 4][0])); ASSERT3(neigh_proc_[yp + 4][ndx] >= 0 && ti_ndx_not_negative(ep2)); } ndtemp = node_key_ndx_[ym + 4][ndx]; //(Node*) NodeTable->lookup(&node_key[ym + 4][0]); if(node_info_[ndtemp] == S_C_CON) { em2 = neighbor_ndx_[ym + 4][ndx]; //(Element*) (ElemTable->lookup(&neighbor[ym + 4][0])); ASSERT3(neigh_proc_[ym + 4][ndx] >= 0 && ti_ndx_not_negative(em2)); } dxp = coord_[1][ep] - coord_[1][ndx]; dxm = coord_[1][ndx] - coord_[1][em]; for(j = 0; j < NUM_STATE_VARS; j++) { dp = (state_vars_[j][ep] - state_vars_[j][ndx]) / dxp; if(ti_ndx_not_negative(ep2)) dp = .5 * (dp + (state_vars_[j][ep2] - state_vars_[j][ndx]) / dxp); dm = (state_vars_[j][ndx] - state_vars_[j][em]) / dxm; if(ti_ndx_not_negative(em2)) dm = .5 * (dm + (state_vars_[j][ndx] - state_vars_[j][em2]) / dxm); dc = (dp * dxm + dm * dxp) / (dxm + dxp); // weighted average //do slope limiting d_state_vars_[j + NUM_STATE_VARS][ndx]=0.5 * (c_sgn(dp) + c_sgn(dm)) * c_dmin1(gamma * dabs(dp), gamma * dabs(dm), dabs(dc)); } return; }