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)||...
Beispiel #2
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];
}
Beispiel #3
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
            {
Beispiel #4
0
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;
}