예제 #1
0
int
rn_inithead(struct radix_node_head **head, int off)
{
	struct radix_node_head *rnh;
	struct radix_node *t, *tt, *ttt;
	if (*head)
		return (1);
	rnh = (struct radix_node_head *)rtmalloc(sizeof(*rnh), "rn_inithead");
	Bzero(rnh, sizeof (*rnh));
	*head = rnh;
	t = rn_newpair(rn_zeros, off, rnh->rnh_nodes);
	ttt = rnh->rnh_nodes + 2;
	t->rn_r = ttt;
	t->rn_p = t;
	tt = t->rn_l;
	tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE;
	tt->rn_b = -1 - off;
	*ttt = *tt;
	ttt->rn_key = rn_ones;
	rnh->rnh_addaddr = rn_addroute;
	rnh->rnh_deladdr = rn_delete;
	rnh->rnh_matchaddr = rn_match;
	rnh->rnh_lookup = rn_lookup;
	rnh->rnh_walktree = rn_walktree;
	rnh->rnh_treetop = t;
	return (1);
}
예제 #2
0
WIN32DLL_DEFINE
    int _mcrypt_set_key(CRYPT_KEY * ckey, char *password, int plen,
			void *u1, int u2)
{
	int ic, i, k, temp;
	unsigned random;
	sword32 seed;


	Bzero(ckey, sizeof(CRYPT_KEY));
	ckey->n1 = ckey->n2 = ckey->nr1 = ckey->nr2 = 0;

	if (plen > 13)
		plen = 13;

	memmove(ckey->cbuf, password, plen);

	seed = 123;
	for (i = 0; i < 13; i++)
		seed = seed * ckey->cbuf[i] + i;
	for (i = 0; i < ROTORSZ; i++) {
		ckey->t1[i] = i;
		ckey->deck[i] = i;
	}
	for (i = 0; i < ROTORSZ; i++) {
		seed = 5 * seed + ckey->cbuf[i % 13];
		random = seed % 65521;
		k = ROTORSZ - 1 - i;
		ic = (random & MASK) % (k + 1);
		random >>= 8;

		temp = ckey->t1[k];
		ckey->t1[k] = ckey->t1[ic];
		ckey->t1[ic] = temp;
		if (ckey->t3[k] != 0)
			continue;

		ic = (random & MASK) % k;
		while (ckey->t3[ic] != 0)
			ic = (ic + 1) % k;
		ckey->t3[k] = ic;
		ckey->t3[ic] = k;
	}

	for (i = 0; i < ROTORSZ; i++)
		ckey->t2[ckey->t1[i] & MASK] = i;

	return 0;
}
예제 #3
0
void
rn_init(void)
{
	char *cp, *cplim;
	if (max_keylen == 0) {
		printf("rn_init: radix functions require max_keylen be set\n");
		return;
	}
	rn_zeros = (char *)rtmalloc(3 * max_keylen, "rn_init");
	Bzero(rn_zeros, 3 * max_keylen);
	rn_ones = cp = rn_zeros + max_keylen;
	addmask_key = cplim = rn_ones + max_keylen;
	while (cp < cplim)
		*cp++ = -1;
	if (rn_inithead(&mask_rnhead, 0) == 0)
		panic("rn_init 2");
}
예제 #4
0
static struct radix_mask *
rn_new_radix_mask(struct radix_node *tt,
		  struct radix_mask *next)
{
	struct radix_mask *m;

	MKGet(m);
	if (m == 0) {
		log(LOG_ERR, "Mask for route not entered\n");
		return (0);
	}
	Bzero(m, sizeof *m);
	m->rm_b = tt->rn_b;
	m->rm_flags = tt->rn_flags;
	if (tt->rn_flags & RNF_NORMAL)
		m->rm_leaf = tt;
	else
		m->rm_mask = tt->rn_mask;
	m->rm_mklist = next;
	tt->rn_mklist = m;
	return m;
}
예제 #5
0
/****************************************************************
 * Build RHS which is the residual of the nonlinear system.
 ***************************************************************/
void 
phgNSBuildSolverURHS(NSSolver *ns)
{
    GRID *g = ns->g;
    SIMPLEX *e;
    SOLVER *solver_u = ns->solver_u;
    int i, k, l, q, s;
    FLOAT *dt = ns->dt;
    BOOLEAN tstep_minus = (ns->u[-1] != NULL);
    VEC *vec_rhs = phgMapCreateVec(solver_u->rhs->map, 1);
    FLOAT Theta = _nsp->Theta, nu = _nsp->nu, Thet1;
    int viscosity_type = ns->viscosity_type;

    SURF_BAS *surf_bas = ns->surf_bas;
    DOF *surf_dof = surf_bas->dof;
    BOOLEAN *rotated = surf_bas->rotated;
    const FLOAT *Trans = DofData(surf_dof);


#if STEADY_STATE
    assert(fabs(Theta - 1) < 1e-12);
    Thet1 = 0; Unused(Thet1);
    Unused(dt);
#else
    Thet1 = 1 - Theta;
    Unused(dt);
#endif /* STEADY_STATE */

    phgPrintf("   DB_mask: [");
    for (k = 0; k < Dim; k++)
	phgPrintf("%d ", ns->u[1]->DB_masks[k]);
    phgPrintf("]   ");

    nu_max = -1e10;
    nu_min = +1e10;

    phgVecDisassemble(vec_rhs);
    ForAllElements(g, e) {
	int M = ns->u[1]->type->nbas;	/* num of bases of Velocity */
	int N = ns->p[1]->type->nbas;	/* num of bases of Pressure */
	int order = DofTypeOrder(ns->u[1], e) * 3 - 1; /* Note:
							*   quad order is really high here,
							*   highest order term (u \nabla u, phi)  */
	FLOAT bufu[M], bufp[N], rhsu[M][Dim], rhsp[N];
	INT Iu[M][Dim], Ip[N];
	QUAD *quad;
	FLOAT vol, area, det;
	const FLOAT *w, *p, *normal,
	    **vu, *vu_queue[3],
	    *vf[2], *gu[2], *vp[2], *vw, *vT;
	FLOAT *vf_cache[2];

	vu = vu_queue + 1;

	quad = phgQuadGetQuad3D(order);
	vu[0] = phgQuadGetDofValues(e, ns->u[0], quad);	           /* u^{n} */
	vp[0] = phgQuadGetDofValues(e, ns->p[0], quad);	           /* p^{n} */
	gu[0] = phgQuadGetDofValues(e, ns->gradu[0], quad);        /* grad u^{n} */
	vw = phgQuadGetDofValues(e, ns->wind, quad);               /* wind */
	vT = phgQuadGetDofValues(e, ns->T[1], quad);	           /* T^{n} */


	if (tstep_minus) { 
	    vu[-1] = phgQuadGetDofValues(e, ns->u[-1], quad);      /* u^{n-1} */
	} else {
	    vu[-1] = vu[0];
	}

#if STEADY_STATE || TIME_DEP_NON
	vu[1] = phgQuadGetDofValues(e, ns->u[1], quad);          /* u^{n+1} */
	gu[1] = phgQuadGetDofValues(e, ns->gradu[1], quad);      /* grad u^{n} */
	vp[1] = phgQuadGetDofValues(e, ns->p[1], quad);          /* p^{n+1} */
#else
	TIME_DEP_LINEAR_ENTRY; /* Unavailable */
#endif /* STEADY_STATE || TIME_DEP_NON */

	Unused(l);
	Unused(vf); Unused(vf_cache); 

	if (!_nsp->no_extern_source) {
	    /* cache f values */
	    for (l = 0; l < 2; l++) {
		const FLOAT *cache;
		size_t cache_size;
		setFuncTime(ns->time[l]); /* set static time in ins-test.c */

		/* cache f */
		cache_size = Dim * quad->npoints * sizeof(FLOAT);
		cache = phgQuadGetFuncValues(g, e, Dim, func_f, quad);
		vf[l] = vf_cache[l] = phgAlloc(cache_size);
		memcpy(vf_cache[l], cache, cache_size);

		phgQuadGetFuncValues(NULL, NULL, 0, NULL, NULL); /* clear cache */
	    }
	}

	/* Global Matrix */
	Bzero(rhsu); Bzero(rhsp);
    
	p = quad->points;
	w = quad->weights;
	for (q = 0; q < quad->npoints; q++) {
	    phgGeomGetCurvedJacobianAtLambda(g, e, p, &det);
	    vol = fabs(det / 6.);

	    /* rhs u */
	    for (i = 0; i < M; i++) {
		/* interior node or Neumann */
		const FLOAT *gi_u = phgQuadGetBasisValues(e, ns->u[1], i, quad) + q;       /* phi_i */
		const FLOAT *ggi_u = phgQuadGetBasisCurvedGradient(e, ns->u[1], i, quad, q);    /* grad phi_i */

		for (k = 0; k < Dim; k++) {
#if ICE_BENCH_TEST
		    nu = get_effective_viscosity(gu[1], 0, 0, viscosity_type);
		    FLOAT eu[DDim];

		    MAT3_SYM(gu[1], eu);
		    rhsu[i][k] += vol*(*w) * EQU_SCALING * (- nu * INNER_PRODUCT(eu+k*Dim, ggi_u) 
							    + (*vp[1]) * *(ggi_u+k) * LEN_SCALING * PRES_SCALING
							    );     /* left */

		    if (k == Z_DIR) { 
			const FLOAT rho = RHO_ICE;
			const FLOAT grav = GRAVITY;
			const FLOAT a = SEC_PER_YEAR;
			const FLOAT f = rho*grav * EQU_SCALING * LEN_SCALING2; 

			Unused(a);
			rhsu[i][k] += vol*(*w) * (-f * (*gi_u) 
						  ); /* right */
		    }


#elif ESIMINT_TEST ||				\
    HEINO_TEST ||				\
    TEST_CASE == ICE_GREEN_LAND
		    nu = get_effective_viscosity(gu[1], *vT, 0, viscosity_type);
		    FLOAT eu[DDim];

		    MAT3_SYM(gu[1], eu);
		    rhsu[i][k] += vol*(*w) * EQU_SCALING * (- nu * INNER_PRODUCT(eu+k*Dim, ggi_u) 
							    + (*vp[1]) * *(ggi_u+k) * LEN_SCALING * PRES_SCALING
							    );     /* left */

		    if (k == Z_DIR) { 
			const FLOAT rho = RHO_ICE;
			const FLOAT grav = GRAVITY;
			const FLOAT a = SEC_PER_YEAR;
			const FLOAT f = rho*grav * EQU_SCALING * LEN_SCALING2; 

			Unused(a);
			rhsu[i][k] += vol*(*w) * (-f * (*gi_u) 
						  ); /* right */
		    }

#elif STEADY_STATE
		    rhsu[i][k] += vol*(*w) * (- nu * INNER_PRODUCT(gu[1]+k*Dim, ggi_u)
					      + (*vp[1]) * *(ggi_u+k)
					      );     /* left */
		    if (!_nsp->no_extern_source)
			rhsu[i][k] += vol*(*w) * (*(vf[1]+k) * (*gi_u)
						  ); /* right */
#elif TIME_DEP_NON
		    rhsu[i][k] -= vol*(*w) * ((vu[1][k] - vu[0][k]) * (*gi_u) / dt[0]
					      + Theta * (nu * INNER_PRODUCT(gu[1]+k*Dim, ggi_u)
							 )
					      - (*vp[1]) * *(ggi_u+k)
					      + Thet1 * (nu * INNER_PRODUCT(gu[0]+k*Dim, ggi_u)
							 )
					      );     /* left */
		    if (!_nsp->no_extern_source)
			rhsu[i][k] += vol*(*w) * (Theta * *(vf[1]+k) * (*gi_u)
						  + Thet1 * *(vf[0]+k) * (*gi_u)
						  ); /* right */
#else
		    TIME_DEP_LINEAR_ENTRY; /* Unavailable */
#endif /* STEADY_STATE */
		}
	    }

	    /* rhs p */
	    for (i = 0; i < N; i++) {
		const FLOAT *gi_p = phgQuadGetBasisValues(e, ns->p[1], i, quad) + q;       /* psi_i */
		FLOAT divu1 = gu[1][0] + gu[1][4] + gu[1][8];
		//FLOAT divu0 = gu[0][0] + gu[0][4] + gu[0][8];
		rhsp[i] += vol*(*w) * (divu1 * (*gi_p)
				       );
	    }
	    
	    if (tstep_minus) 
		vu[-1] += Dim;

#if STEADY_STATE || TIME_DEP_NON
	    vu[1] += Dim;
	    gu[1] += Dim*Dim;
	    vp[1]++;
#else
	    TIME_DEP_LINEAR; /* Unavailable */
#endif /* STEADY_STATE || TIME_DEP_NON */
	    vu[0] += Dim;
	    gu[0] += Dim * Dim;
	    vp[0]++; 
	    vw += Dim;
	    if (!_nsp->no_extern_source) {
		vf[0] += Dim; vf[1] += Dim;
	    }
	    vT++;
	    w++; p += Dim + 1;
	}

	if (!_nsp->no_extern_source) {
	    phgFree(vf_cache[0]);
	    phgFree(vf_cache[1]);
	}

	normal = NULL; Unused(normal);
	area = 0; Unused(area);

	if (!_nsp->enclosed_flow) {
	    /* slip boundary */
	    for (s = 0; s < NFace; s++) {
		if (e->bound_type[s] & INFLOW) {
		    int v0, v1, v2;
		    int nbas_face = NbasFace(ns->u[1]);
		    SHORT bases[nbas_face];
		    FLOAT lambda[Dim + 1], x,y,z, beta;
		    order = DofTypeOrder(ns->u[1], e) * 3 - 1;

		    phgDofGetBasesOnFace(ns->u[1], e, s, bases);
		    v0 = GetFaceVertex(s, 0);
		    v1 = GetFaceVertex(s, 1);
		    v2 = GetFaceVertex(s, 2);
		    lambda[s] = 0.;
		    
		    area = phgGeomGetFaceArea(g, e, s);
		    normal = phgGeomGetFaceOutNormal(g, e, s);
		    quad = phgQuadGetQuad2D(order);
		
		    p = quad->points;
		    w = quad->weights;
		    for (q = 0; q < quad->npoints; q++) {
			FLOAT vu[Dim];
			lambda[v0] = *(p++);
			lambda[v1] = *(p++);
			lambda[v2] = *(p++);
			
			phgGeomLambda2XYZ(g, e, lambda, &x, &y, &z);
			func_beta(x, y, z, &beta);
			phgDofEval(ns->u[1], e, lambda, vu);

			for (i = 0; i < nbas_face; i++) {
			    int ii = bases[i];
			    FLOAT gi_u = 
				*ns->u[1]->type->BasFuncs(ns->u[1], e, ii, ii + 1, lambda);

			    for (k = 0; k < Dim; k++) {
#if STEADY_STATE
				rhus[ii][k] += 0.;
#elif TIME_DEP_NON
#  if USE_SLIDING_BC
				abort();
				rhsu[ii][k] += SIGN_FRICTION * area*(*w) * beta * vu[k] * (gi_u)
				    * EQU_SCALING * LEN_SCALING;
#  else
				Unused(gi_u);
#  endif
#else
				TIME_DEP_LINEAR_ENTRY; /* Unavailable */
#endif /* STEADY_STATE */
			    }
			}     /* end of bas_i */
			w++;
		    }		/* end of quad point */
		}		/* end of face outflow */
	    }			/* end of all outflow face in element */
	}                       /* end out flow boundary */


#if USE_SLIDING_BC
	/* Rotate bases */
	for (i = 0; i < M; i++) {
	    INT id = phgDofMapE2D(surf_dof, e, i * (Dim*Dim)) / (Dim*Dim);
	    if (!rotated[id])
		continue;	
	    const FLOAT *trans = Trans + id*(Dim*Dim);

	    trans_left(&rhsu[i][0], 1, 1, trans);
	}
#else
	Unused(Trans);
	Unused(rotated);
#endif


	/* Map: Element -> system */
	for (i = 0; i < M; i++)
	    for (k = 0; k < Dim; k++)
		Iu[i][k] = phgMapE2L(solver_u->rhs->map, 0, e, i * Dim + k);
	for (i = 0; i < N; i++)
	    Ip[i] = phgMapE2L(solver_u->rhs->map, 1, e, i);

	/* set velocity dirichlet bdry */
	FLOAT tmp[Dim];
	for (i = 0; i < M; i++)
	    for (k = 0; k < Dim; k++)
		if (phgDofDirichletBC_(ns->u[1], e, i*Dim+k, NULL, bufu, tmp,
				       DOF_PROJ_NONE)) {
		    rhsu[i][k] = 0.;
		}

#if STEADY_STATE || TIME_DEP_NON
	/* set pressure dirichlet bdry for pinned point */
	for (i = 0; i < N; i++)
	    if (phgDofDirichletBC(ns->p[1], e, i, NULL, bufp, &rhsp[i],
				  DOF_PROJ_NONE)) {
		if (!_nsp->enclosed_flow)
		    phgError(1, "No dirichlet bc for Unenclosed flow!\n");
		if (_nsp->pin_node) {
# if PIN_AT_ROOT 
		    if (g->rank != 0)
		    	phgError(1, "Pinned node only on rank 0!\n");
		    if (g, e->verts[i] != ns->pinned_node_id)
			phgError(1, "Build rhs: pinned node e:%d, bas:%d, [%d] and [%d] "
				 "doesn't coincide when build RHS!\n", 
				 e->index, i, e->verts[i], ns->pinned_node_id);
# else
		    if (GlobalVertex(g, e->verts[i]) != ns->pinned_node_id)
			phgError(1, "Build rhs: pinned node e:%d, bas:%d, [%d] and [%d] "
				 "doesn't coincide when build RHS!\n", 
				 e->index, i, e->verts[i], ns->pinned_node_id);
# endif /* PIN_AT_ROOT */
		}
	    } 
#else
	TIME_DEP_LINEAR; /* Unavailable */
#endif /* STEADY_STATE || TIME_DEP_NON */


	/* Global res */
	phgVecAddEntries(vec_rhs, 0, M * Dim, Iu[0], &rhsu[0][0]);
	phgVecAddEntries(vec_rhs, 0, N, Ip, rhsp);
    }				/* end element */
예제 #6
0
void get_smooth_surface_values(NSSolver *ns, DOF *dof_P1, int up_or_lower)
{
    GRID *g = ns->g;
    DOF *sn = dof_P1;
    LAYERED_MESH *gL = ns->gL;

    int avg_style = 1;

    int nx = NX, ny = NY;

    int i, ii, j, k;

    static FLOAT *nsv, *nsv0, *x_coord, *x_coord0, *y_coord, *y_coord0;

    PHG_CALLOC(nsv, gL->nvert);
    PHG_CALLOC(nsv0, gL->nvert);

    for (i = 0; i < gL->nvert; i++)
    {
        nsv[i] = -1e30;
    }
    
    for (ii = 0; ii < gL->nvert_bot; ii++) {
	i = gL->vert_bot_Lidx[ii];
	assert(gL->vert_local_lists[i] != NULL);

    INT iG = gL->vert_bot_Gidx[ii];
    assert(iG < gL->nvert);
	int nv = gL->vert_local_lists[i][0];
	int *iL = &gL->vert_local_lists[i][1];
	assert(nv > 0);
	
    FLOAT val;

    if (up_or_lower == 0)
        val = *DofVertexData(sn, iL[0]);
        // smooth the values at the lower surface
    if (up_or_lower == 1)
        val = *DofVertexData(sn, iL[nv-1]);
        // smooth the values of the upper surface
    

    nsv[iG] = val;

    }

    MPI_Allreduce(nsv, nsv0, gL->nvert,
    		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);
    //MPI_Allreduce(x_coord, x_coord0, gL->nvert,
   // 		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);
    //MPI_Allreduce(y_coord, y_coord0, gL->nvert,
   // 		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);

    if (0 && phgRank == 0){
	FILE *fp = fopen("nsv.dat", "w");
	for (ii = 0; ii < gL->nvert; ii++) {
	    fprintf(fp, "%e\n", 
		   nsv0[ii]);
	}
	fclose(fp);
    }

    if (phgRank == 0)
    {
    //FLOAT **data_x = read_txt_data("data_x.txt");
    //FLOAT **data_y = read_txt_data("data_y.txt");

    FLOAT snv[nx][ny];
    FLOAT sum_sn[nx];
    FLOAT mean_sn[nx];
    FLOAT m_avg[nx][ny];

    FLOAT data4fit[ny];

    Bzero(snv); Bzero(sum_sn); Bzero(mean_sn); Bzero(m_avg);

    Bzero(data4fit);

    for (i = 0; i < gL->nvert; i++)
    {
        for (j = 0; j < ny; j++)
        {
            if (fabs(gL->verts[i][1] - data_y[0][j]) < 1e-1)
            {
                for (k = 0; k < nx; k++)
                {
                    //printf("%f %f\n", gL->verts[i][0], data_x[0][k]);
                    if (fabs(gL->verts[i][0]-data_x[k][0]) < 1e-1)
                    {
                        snv[k][j] = nsv0[i];
                        //printf("nsv: %f %d %d %d\n", nsv0[i], i, j, k);
                        //printf("nsv: %f %d %d %d\n", snv[j][k], i, j, k);
                    }
                }
            }
        }
    }


#if 0
    FILE *fp0 = fopen("data_orig.txt", "w");

    for (k = 0; k < nx; k++)
    {
        for (j = 0; j < ny; j++)
        {
            fprintf(fp0, "%f ", snv[k][j]);
        }
        fprintf(fp0, "\n");
    }

    fclose(fp0);


    system("python get_smooth_data_along_y.py");
#endif


    for (k = 0; k < nx; k++)
    {
        //if (k==0)
        //printf("%f %f %f %f %f %f %f %f %f %f %f %d\n", snv[0][k], snv[1][k], snv[2][k], snv[3][k], snv[4][k], snv[5][k],snv[6][k],snv[7][k],snv[8][k],snv[9][k],snv[10][k],k);
        //FILE *fp = fopen("data_polyfit.txt", "w");

        for (j = 0; j < ny; j++)
        {
            sum_sn[k] += snv[k][j];

            if (j == 0)
                m_avg[k][j] = (snv[k][0] + snv[k][1])/2;
            else if (j == ny-1)
                m_avg[k][j] = (snv[k][ny-2] + snv[k][ny-1])/2;
            else
                m_avg[k][j] = (snv[k][j-1] + snv[k][j] + snv[k][j+1])/3;

            //data4fit[j] = snv[k][j];

            //fprintf(fp, "%d %f\n", j, data4fit[j]);
        }

        //fclose(fp);

        //system("python get_smooth_data_along_y.py");



        mean_sn[k] = sum_sn[k]/ny;
        //printf("mean_dH: %f %f %f\n", snv[j][k], sum_sn[k], mean_sn[k]);
    }


#if 0
    FILE *fp1 = fopen("data_fitted.txt", "r");
    if (fp1==NULL){
        printf("errors when opening fitting file!\n");
    }

	FLOAT **data = (double**) calloc(nx, sizeof *data);
	for (j=0;j<nx;j++)
	{
		data[j] = (double*) calloc(ny, sizeof *data[j]);
		for (i=0;i<ny;i++)
		{
			fscanf(fp1, "%f", &data[j][i]);
		}
	}

    fclose(fp1);

    for (k = 0; k < nx; k++)
        for (j = 0; j < ny; j++)
            m_avg[k][j] = data[k][j];

#endif

    for (i = 0; i < gL->nvert; i++)
    {
        for (j = 0; j < ny; j++)
        {
            if (fabs(gL->verts[i][1] - data_y[0][j]) < 1e-1)
            {

                for (k = 0; k < nx; k++)
                {
                    if (fabs(gL->verts[i][0]-data_x[k][0]) < 1e-1)
                    {
                        if (avg_style == 1)
                            nsv0[i] = mean_sn[k];
#if 0
                        if (avg_style == 2)
                            nsv0[i] = m_avg[k][j];
#endif
                    }
                }
            }
        }
    }
    }


    MPI_Bcast(nsv0, gL->nvert,
	      PHG_MPI_FLOAT, 0, MPI_COMM_WORLD);

     for (ii = 0; ii < gL->nvert_bot; ii++) { 
     	i = gL->vert_bot_Lidx[ii]; 
     	assert(gL->vert_local_lists[i] != NULL); 

     	INT iG = gL->vert_bot_Gidx[ii]; 
     	assert(iG < gL->nvert); 

     	int nv = gL->vert_local_lists[i][0]; 
     	int *iL = &gL->vert_local_lists[i][1]; 
	    
     	assert(nv > 0); 
        FLOAT *vg;

        if (up_or_lower == 0)
            vg = DofVertexData(sn, iL[0]); 
        if (up_or_lower == 1)
            vg = DofVertexData(sn, iL[nv-1]); 

        vg[0] = nsv0[iG]; 
     } 

}
예제 #7
0
void save_free_surface_elev(NSSolver *ns, int up_or_lower)
{
    GRID *g = ns->g;
    LAYERED_MESH *gL = ns->gL;

    int avg_style = 1;

    int nx = NX, ny = NY;

    int i, ii, j, k;

    static FLOAT *nsv, *nsv0, *x_coord, *x_coord0, *y_coord, *y_coord0;

    PHG_CALLOC(nsv, gL->nvert);
    PHG_CALLOC(nsv0, gL->nvert);

    for (i = 0; i < gL->nvert; i++)
    {
        nsv[i] = -1e30;
    }
    
    for (ii = 0; ii < gL->nvert_bot; ii++) {
	i = gL->vert_bot_Lidx[ii];
	assert(gL->vert_local_lists[i] != NULL);

    INT iG = gL->vert_bot_Gidx[ii];
    assert(iG < gL->nvert);
	int nv = gL->vert_local_lists[i][0];
	int *iL = &gL->vert_local_lists[i][1];
	assert(nv > 0);
	
    FLOAT val;

    if (up_or_lower == 0)
        val = g->verts[iL[0]][2];
        //val = *DofVertexData(sn, iL[0]);
        // smooth the values at the lower surface
    if (up_or_lower == 1)
        val = g->verts[iL[nv-1]][2];
        //val = *DofVertexData(sn, iL[nv-1]);
        // smooth the values of the upper surface
    

    nsv[iG] = val;

    }

    MPI_Allreduce(nsv, nsv0, gL->nvert,
    		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);
    //MPI_Allreduce(x_coord, x_coord0, gL->nvert,
   // 		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);
    //MPI_Allreduce(y_coord, y_coord0, gL->nvert,
   // 		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);

    if (1 && phgRank == 0){
	FILE *fp = fopen("nsv.dat", "w");
	for (ii = 0; ii < gL->nvert; ii++) {
	    fprintf(fp, "%e\n", 
		   nsv0[ii]);
	}
	fclose(fp);
    }

    if (phgRank == 0)
    {

    FLOAT snv[nx][ny];

    Bzero(snv);

    for (i = 0; i < gL->nvert; i++)
    {
        for (j = 0; j < ny; j++)
        {
            if (fabs(gL->verts[i][1] - data_y[j][0]) < 1e-1)
            {
                for (k = 0; k < nx; k++)
                {
                    //printf("%f %f\n", gL->verts[i][0], data_x[0][k]);
                    if (fabs(gL->verts[i][0]-data_x[0][k]) < 1e-1)
                    {
                        snv[k][j] = nsv0[i];
                        //printf("nsv: %f %d %d %d\n", nsv0[i], i, j, k);
                        //printf("nsv: %f %d %d %d\n", snv[j][k], i, j, k);
                    }
                }
            }
        }
    }



    FILE *fp0;

    if (up_or_lower == 0)
        fp0 = fopen("s_bot.txt", "w");

    if (up_or_lower == 1)
        fp0 = fopen("s_sur.txt", "w");


    for (k = 0; k < nx; k++)
    {
        for (j = 0; j < ny; j++)
        {
            fprintf(fp0, "%f ", snv[k][j]);
        }
        fprintf(fp0, "\n");
    }

    phgPrintf("save surface elevation!\n");

    fclose(fp0);

    }

}
예제 #8
0
void save_free_surface_velo(NSSolver *ns, int which_dim, int up_or_lower)
{
    GRID *g = ns->g;
    LAYERED_MESH *gL = ns->gL;


    int nx = NX, ny = NY;

    int i, ii, j, k;

    static FLOAT *nsv, *nsv0, *x_coord, *x_coord0, *y_coord, *y_coord0;

    PHG_CALLOC(nsv, gL->nvert);
    PHG_CALLOC(nsv0, gL->nvert);

    for (i = 0; i < gL->nvert; i++)
    {
        nsv[i] = -1e30;
    }
    
    for (ii = 0; ii < gL->nvert_bot; ii++) {
	i = gL->vert_bot_Lidx[ii];
	assert(gL->vert_local_lists[i] != NULL);

    INT iG = gL->vert_bot_Gidx[ii];
    assert(iG < gL->nvert);
	int nv = gL->vert_local_lists[i][0];
	int *iL = &gL->vert_local_lists[i][1];
	assert(nv > 0);
	
    FLOAT val;

    FLOAT *vu = DofVertexData(ns->u[1], iL[j]);

    if (up_or_lower == 0)
    {
        vu = DofVertexData(ns->u[1], iL[0]);
        val = vu[which_dim];
    }

    if (up_or_lower == 1)
    {
        vu = DofVertexData(ns->u[1], iL[nv-1]);
        val = vu[which_dim];
    }
    

    nsv[iG] = val;

    }

    MPI_Allreduce(nsv, nsv0, gL->nvert,
    		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);
    //MPI_Allreduce(x_coord, x_coord0, gL->nvert,
   // 		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);
    //MPI_Allreduce(y_coord, y_coord0, gL->nvert,
   // 		  PHG_MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD);

    if (1 && phgRank == 0){
	FILE *fp = fopen("nsv.dat", "w");
	for (ii = 0; ii < gL->nvert; ii++) {
	    fprintf(fp, "%e\n", 
		   nsv0[ii]);
	}
	fclose(fp);
    }

    if (phgRank == 0)
    {
    //FLOAT **data_x = read_txt_data("data_x.txt");
    //FLOAT **data_y = read_txt_data("data_y.txt");

    FLOAT snv[nx][ny];

    Bzero(snv);

    for (i = 0; i < gL->nvert; i++)
    {
        for (j = 0; j < ny; j++)
        {
            if (fabs(gL->verts[i][1] - data_y[j][0]) < 1e-1)
            {
                for (k = 0; k < nx; k++)
                {
                    //printf("%f %f\n", gL->verts[i][0], data_x[0][k]);
                    if (fabs(gL->verts[i][0]-data_x[0][k]) < 1e-1)
                    {
                        snv[k][j] = nsv0[i];
                        //printf("nsv: %f %d %d %d\n", nsv0[i], i, j, k);
                        //printf("nsv: %f %d %d %d\n", snv[j][k], i, j, k);
                    }
                }
            }
        }
    }



    FILE *fp0;

    if (up_or_lower == 0)
    {
        if (which_dim == 0)
            fp0 = fopen("u_bot.txt", "w");
        else if (which_dim == 1)
            fp0 = fopen("v_bot.txt", "w");
        else if (which_dim == 2)
            fp0 = fopen("w_bot.txt", "w");
        else
            printf("Wrong dimension !");

    }

    if (up_or_lower == 1)
    {
        if (which_dim == 0)
            fp0 = fopen("u_sur.txt", "w");
        else if (which_dim == 1)
            fp0 = fopen("v_sur.txt", "w");
        else if (which_dim == 2)
            fp0 = fopen("w_sur.txt", "w");
        else
            printf("Wrong dimension !");
    }


    for (k = 0; k < nx; k++)
    {
        for (j = 0; j < ny; j++)
        {
            fprintf(fp0, "%f ", snv[k][j]);
        }
        fprintf(fp0, "\n");
    }

    fclose(fp0);

    }

}
예제 #9
0
void load_dH_from_file(NSSolver *ns, DOF *dof_P1, int up_or_lower)
{
    GRID *g = ns->g;
    DOF *sn = dof_P1;
    LAYERED_MESH *gL = ns->gL;


    int nx = NX, ny = NY;

    int i, ii, j, k;

    static FLOAT *nsv, *nsv0, *x_coord, *x_coord0, *y_coord, *y_coord0;

    PHG_CALLOC(nsv, gL->nvert);
    PHG_CALLOC(nsv0, gL->nvert);
    

    if (phgRank == 0)
    {
    //FLOAT **data_x = read_txt_data("data_x.txt");
    //FLOAT **data_y = read_txt_data("data_y.txt");

    FLOAT snv[nx][ny];
    FLOAT sum_sn[nx];
    FLOAT mean_sn[nx];
    FLOAT m_avg[nx][ny];

    Bzero(snv); Bzero(sum_sn); Bzero(mean_sn); Bzero(m_avg);



    FILE *fp1;

    if (up_or_lower == 0)
    {
        fp1 = fopen("bot_dh_implicit_fdm.txt", "r");
        if (fp1==NULL){
            printf("errors when opening bot dh file!\n");
        }
    }
    
    if (up_or_lower == 1)
    {
        fp1 = fopen("sur_dh_implicit_fdm.txt", "r");
        if (fp1==NULL){
            printf("errors when opening sur dh file!\n");
        }
    }

	FLOAT **data = (double**) calloc(nx, sizeof *data);
	for (j=0;j<nx;j++)
	{
		data[j] = (double*) calloc(ny, sizeof *data[j]);
		for (i=0;i<ny;i++)
		{
			fscanf(fp1, "%lf", &data[j][i]);
            //if (data[j][i] > 0.3)
            //printf("%f\n", data[j][i]);
		}
	}

    fclose(fp1);

    for (k = 0; k < nx; k++)
        for (j = 0; j < ny; j++)
            m_avg[k][j] = data[k][j];


    for (i = 0; i < gL->nvert; i++)
    {
        for (j = 0; j < ny; j++)
        {
            if (fabs(gL->verts[i][1] - data_y[j][0]) < 1e-1)
            {
                for (k = 0; k < nx; k++)
                {
                    if (fabs(gL->verts[i][0]-data_x[0][k]) < 1e-1)
                    {
                            nsv0[i] = m_avg[k][j];
                    }
                }
            }
        }
    }
    }


    MPI_Bcast(nsv0, gL->nvert,
	      PHG_MPI_FLOAT, 0, MPI_COMM_WORLD);

     for (ii = 0; ii < gL->nvert_bot; ii++) { 
     	i = gL->vert_bot_Lidx[ii]; 
     	assert(gL->vert_local_lists[i] != NULL); 

     	INT iG = gL->vert_bot_Gidx[ii]; 
     	assert(iG < gL->nvert); 

     	int nv = gL->vert_local_lists[i][0]; 
     	int *iL = &gL->vert_local_lists[i][1]; 
	    
     	assert(nv > 0); 
        FLOAT *vg;

        if (up_or_lower == 0)
            vg = DofVertexData(sn, iL[0]); 
        if (up_or_lower == 1)
            vg = DofVertexData(sn, iL[nv-1]); 

        vg[0] = nsv0[iG]; 
     } 

}
예제 #10
0
int
rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
    u_int tableid)
{
	int			 s = splsoftnet(); int error = 0;
	struct rtentry		*rt, *crt;
	struct radix_node	*rn;
	struct radix_node_head	*rnh;
	struct ifaddr		*ifa;
	struct sockaddr		*ndst;
	struct sockaddr_rtlabel	*sa_rl;
#define senderr(x) { error = x ; goto bad; }

	if ((rnh = rt_gettable(info->rti_info[RTAX_DST]->sa_family, tableid)) ==
	    NULL)
		senderr(EAFNOSUPPORT);
	if (info->rti_flags & RTF_HOST)
		info->rti_info[RTAX_NETMASK] = NULL;
	switch (req) {
	case RTM_DELETE:
		if ((rn = rnh->rnh_lookup(info->rti_info[RTAX_DST],
		    info->rti_info[RTAX_NETMASK], rnh)) == NULL)
			senderr(ESRCH);
		rt = (struct rtentry *)rn;
#ifndef SMALL_KERNEL
		/*
		 * if we got multipath routes, we require users to specify
		 * a matching RTAX_GATEWAY.
		 */
		if (rn_mpath_capable(rnh)) {
			rt = rt_mpath_matchgate(rt,
			    info->rti_info[RTAX_GATEWAY]);
			rn = (struct radix_node *)rt;
			if (!rt)
				senderr(ESRCH);
		}
#endif
		if ((rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST],
		    info->rti_info[RTAX_NETMASK], rnh, rn)) == NULL)
			senderr(ESRCH);
		rt = (struct rtentry *)rn;

		/* clean up any cloned children */
		if ((rt->rt_flags & RTF_CLONING) != 0)
			rtflushclone(rnh, rt);

		if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
			panic ("rtrequest delete");

		if (rt->rt_gwroute) {
			rt = rt->rt_gwroute; RTFREE(rt);
			(rt = (struct rtentry *)rn)->rt_gwroute = NULL;
		}

		if (rt->rt_parent) {
			rt->rt_parent->rt_refcnt--;
			rt->rt_parent = NULL;
		}

#ifndef SMALL_KERNEL
		if (rn_mpath_capable(rnh)) {
			if ((rn = rnh->rnh_lookup(info->rti_info[RTAX_DST],
			    info->rti_info[RTAX_NETMASK], rnh)) != NULL &&
			    rn_mpath_next(rn) == NULL)
				((struct rtentry *)rn)->rt_flags &= ~RTF_MPATH;
		}
#endif

		rt->rt_flags &= ~RTF_UP;
		if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
			ifa->ifa_rtrequest(RTM_DELETE, rt, info);
		rttrash++;

		if (ret_nrt)
			*ret_nrt = rt;
		else if (rt->rt_refcnt <= 0) {
			rt->rt_refcnt++;
			rtfree(rt);
		}
		break;

	case RTM_RESOLVE:
		if (ret_nrt == NULL || (rt = *ret_nrt) == NULL)
			senderr(EINVAL);
		if ((rt->rt_flags & RTF_CLONING) == 0)
			senderr(EINVAL);
		ifa = rt->rt_ifa;
		info->rti_flags = rt->rt_flags & ~(RTF_CLONING | RTF_STATIC);
		info->rti_flags |= RTF_CLONED;
		info->rti_info[RTAX_GATEWAY] = rt->rt_gateway;
		if ((info->rti_info[RTAX_NETMASK] = rt->rt_genmask) == NULL)
			info->rti_flags |= RTF_HOST;
		goto makeroute;

	case RTM_ADD:
		if (info->rti_ifa == 0 && (error = rt_getifa(info)))
			senderr(error);
		ifa = info->rti_ifa;
makeroute:
		rt = pool_get(&rtentry_pool, PR_NOWAIT);
		if (rt == NULL)
			senderr(ENOBUFS);
		Bzero(rt, sizeof(*rt));
		rt->rt_flags = RTF_UP | info->rti_flags;
		LIST_INIT(&rt->rt_timer);
		if (rt_setgate(rt, info->rti_info[RTAX_DST],
		    info->rti_info[RTAX_GATEWAY], tableid)) {
			pool_put(&rtentry_pool, rt);
			senderr(ENOBUFS);
		}
		ndst = rt_key(rt);
		if (info->rti_info[RTAX_NETMASK] != NULL) {
			rt_maskedcopy(info->rti_info[RTAX_DST], ndst,
			    info->rti_info[RTAX_NETMASK]);
		} else
			Bcopy(info->rti_info[RTAX_DST], ndst,
			    info->rti_info[RTAX_DST]->sa_len);
#ifndef SMALL_KERNEL
		/* do not permit exactly the same dst/mask/gw pair */
		if (rn_mpath_capable(rnh) &&
		    rt_mpath_conflict(rnh, rt, info->rti_info[RTAX_NETMASK],
		    info->rti_flags & RTF_MPATH)) {
			if (rt->rt_gwroute)
				rtfree(rt->rt_gwroute);
			Free(rt_key(rt));
			pool_put(&rtentry_pool, rt);
			senderr(EEXIST);
		}
#endif

		if (info->rti_info[RTAX_LABEL] != NULL) {
			sa_rl = (struct sockaddr_rtlabel *)
			    info->rti_info[RTAX_LABEL];
			rt->rt_labelid = rtlabel_name2id(sa_rl->sr_label);
		}

		ifa->ifa_refcnt++;
		rt->rt_ifa = ifa;
		rt->rt_ifp = ifa->ifa_ifp;
		if (req == RTM_RESOLVE) {
			/*
			 * Copy both metrics and a back pointer to the cloned
			 * route's parent.
			 */
			rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
			rt->rt_parent = *ret_nrt;	 /* Back ptr. to parent. */
			rt->rt_parent->rt_refcnt++;
		}
		rn = rnh->rnh_addaddr((caddr_t)ndst,
		    (caddr_t)info->rti_info[RTAX_NETMASK], rnh, rt->rt_nodes);
		if (rn == NULL && (crt = rtalloc1(ndst, 0, tableid)) != NULL) {
			/* overwrite cloned route */
			if ((crt->rt_flags & RTF_CLONED) != 0) {
				rtdeletemsg(crt, tableid);
				rn = rnh->rnh_addaddr((caddr_t)ndst,
				    (caddr_t)info->rti_info[RTAX_NETMASK],
				    rnh, rt->rt_nodes);
			}
			RTFREE(crt);
		}
		if (rn == 0) {
			IFAFREE(ifa);
			if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent)
				rtfree(rt->rt_parent);
			if (rt->rt_gwroute)
				rtfree(rt->rt_gwroute);
			Free(rt_key(rt));
			pool_put(&rtentry_pool, rt);
			senderr(EEXIST);
		}

#ifndef SMALL_KERNEL
		if (rn_mpath_capable(rnh) &&
		    (rn = rnh->rnh_lookup(info->rti_info[RTAX_DST],
		    info->rti_info[RTAX_NETMASK], rnh)) != NULL) {
			if (rn_mpath_next(rn) == NULL)
				((struct rtentry *)rn)->rt_flags &= ~RTF_MPATH;
			else
				((struct rtentry *)rn)->rt_flags |= RTF_MPATH;
		}
#endif

		if (ifa->ifa_rtrequest)
			ifa->ifa_rtrequest(req, rt, info);
		if (ret_nrt) {
			*ret_nrt = rt;
			rt->rt_refcnt++;
		}
		if ((rt->rt_flags & RTF_CLONING) != 0) {
			/* clean up any cloned children */
			rtflushclone(rnh, rt);
		}

		if_group_routechange(info->rti_info[RTAX_DST],
			info->rti_info[RTAX_NETMASK]);
		break;
	}
bad:
	splx(s);
	return (error);
}
예제 #11
0
static struct radix_node *
rn_addmask(void *n_arg, int search, int skip)
{
	caddr_t netmask = (caddr_t)n_arg;
	struct radix_node *x;
	caddr_t cp, cplim;
	int b = 0, mlen, j;
	int maskduplicated, m0, isnormal;
	struct radix_node *saved_x;
	static int last_zeroed = 0;

	if ((mlen = *(u_char *)netmask) > max_keylen)
		mlen = max_keylen;
	if (skip == 0)
		skip = 1;
	if (mlen <= skip)
		return (mask_rnhead->rnh_nodes);
	if (skip > 1)
		Bcopy(rn_ones + 1, addmask_key + 1, skip - 1);
	if ((m0 = mlen) > skip)
		Bcopy(netmask + skip, addmask_key + skip, mlen - skip);
	/*
	 * Trim trailing zeroes.
	 */
	for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;)
		cp--;
	mlen = cp - addmask_key;
	if (mlen <= skip) {
		if (m0 >= last_zeroed)
			last_zeroed = mlen;
		return (mask_rnhead->rnh_nodes);
	}
	if (m0 < last_zeroed)
		Bzero(addmask_key + m0, last_zeroed - m0);
	*addmask_key = last_zeroed = mlen;
	x = rn_search(addmask_key, rn_masktop);
	if (Bcmp(addmask_key, x->rn_key, mlen) != 0)
		x = 0;
	if (x || search)
		return (x);
	x = (struct radix_node *)rtmalloc(max_keylen + 2*sizeof(*x),
					  "rn_addmask");
	saved_x = x;
	Bzero(x, max_keylen + 2 * sizeof (*x));
	netmask = cp = (caddr_t)(x + 2);
	Bcopy(addmask_key, cp, mlen);
	x = rn_insert(cp, mask_rnhead, &maskduplicated, x);
	if (maskduplicated) {
		log(LOG_ERR, "rn_addmask: mask impossibly already in tree");
		Free(saved_x);
		return (x);
	}
	/*
	 * Calculate index of mask, and check for normalcy.
	 */
	cplim = netmask + mlen; isnormal = 1;
	for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;)
		cp++;
	if (cp != cplim) {
		for (j = 0x80; (j & *cp) != 0; j >>= 1)
			b++;
		if (*cp != normal_chars[b] || cp != (cplim - 1))
			isnormal = 0;
	}
	b += (cp - netmask) << 3;
	x->rn_b = -1 - b;
	if (isnormal)
		x->rn_flags |= RNF_NORMAL;
	return (x);
}
예제 #12
0
///
///
///     Function to calculate the value of the breakage distribution
///     function given T10 and a table ot T10 versus Tn
///     Refer:
///         Napier-Munn et al.
///         "Mineral Comminution Circuits - Their Operation and Optimisation",
///         JKMRC monograph 1996,
///         p143
///
///     Uses spline interpolation
///
void WhitenCrusherBreakageFunction(int nSizes, 
								   double* Size,
                                    double requiredT10,
                                     const Matrix& T10_V_Tn,
									  LowerTriangularMatrix& B)
{
    int nT10 = 5 ;
    int nTn = 7 ;
    
    int iT10 ;
    int iTn ;
    
    int i ;
    int j ;
    int k ;

    double S0 ;
    
    double interpTn[7] ;			 /// extra columns at T1000, T10=0 & T1, T10=100 to help extrapolation

									/// Pin down the end of the curve at T100000, T10=0 to help extrapolation
									/// Calculate 1/Tn fractions
									/// Pin down the end of the curve at T1, T10=100 to help extrapolation
	double fractionTn[7] =  {1.0 / 100000.0, 
							 1.0 / 75.0,     
							 1.0 / 50.0,
                             1.0 / 25.0,
							 1.0 / 4.0,
                             1.0 / 2.0,
							 1.0 } ;

	double X[5] = { 0.0, 10.0, 20.0, 30.0, 40.0 } ;               /// T10 data to interpolate on

	double Y[5] ;
    
    double cumulativeB[100] ;

    double fractionSize ;
    
    CSpline Spline ;
    
                            /// Interpolate to get a range of Tn data at the given T10

	for ( iTn = 0 ; iTn < nTn - 2 ; iTn++ )    /// Do all normal Tn values
	{
        for ( iT10 = 0 ; iT10 < nT10 ; iT10++ )             /// This particular Tn data slice
		{
            Y[iT10] = T10_V_Tn(iT10+1, iTn+1) ;
		}
        
        Spline.Make( X, Y, nT10 ) ;                             /// Calculate the spline
        
        interpTn[iTn+1] = Spline.Evaluate(requiredT10) ;     /// Evaluate the spline
	}
    
    interpTn[0] = 0.0000001 ;
    interpTn[6] = 100.0 ;

                            /// Then interpolate to get the CUMULATIVE breakage distibution function by size
    Spline.Make( fractionTn, interpTn, nTn ) ;                /// Calculate the spline
    S0 = Size[0] ;
    cumulativeB[0] = 1.0 ;                                     /// 100% passing top size
    for ( i = 1 ; i < nSizes ; i++)
	{
        fractionSize = Size[i] / S0 ;
        cumulativeB[i] = Spline.Evaluate(fractionSize) / 100.0 ;  /// Evaluate the spline for all size ratios
	}
        
	ColumnVector Bzero(nSizes) ;
	Bzero = 0.0 ;

	for ( i = 2 ; i <= nSizes ; i++ )	/// first entry in breakage distribution function always 0 (nothing breaks into the top size), so start one down
	{
		double bdv = cumulativeB[i - 2] - cumulativeB[i - 1] ;
		if ( bdv < 0.0 ) bdv = 0.0 ;				//Modification by Kurt Petersen 04/06/2002
		Bzero(i) = bdv ;			    /// convert cumulative to actual breakage distribution function
	}

	for ( i = 1 ; i <= nSizes ; i++ )
	{
		k = 1 ;
		for ( j = i ; j <= nSizes ; j++ )
		{
			B(j,i) = Bzero(k++) ;         /// fill columns of lower triangular
		}
	}

}
예제 #13
0
/*
 * Add an interface to a cluster, possibly creating a new entry in
 * the cluster table. This requires reallocation of the table and
 * updating pointers in ifp2sc.
 */
static struct cluster_softc *
add_cluster(u_int16_t cluster_id, struct arpcom *ac)
{
    struct cluster_softc *c = NULL;
    int i;

    for (i = 0; i < n_clusters ; i++)
	if (clusters[i].cluster_id == cluster_id)
	    goto found;

    /* Not found, need to reallocate */
    c = malloc((1+n_clusters) * sizeof (*c), M_IFADDR, M_DONTWAIT | M_ZERO);
    if (c == NULL) {/* malloc failure */
	printf("-- bridge: cannot add new cluster\n");
	return NULL;
    }
    Bzero(c, (1+n_clusters) * sizeof (*c));
    c[n_clusters].ht = (struct hash_table *)
	    malloc(HASH_SIZE * sizeof(struct hash_table),
		M_IFADDR, M_WAITOK | M_ZERO);
    if (c[n_clusters].ht == NULL) {
	printf("-- bridge: cannot allocate hash table for new cluster\n");
	free(c, M_IFADDR);
	return NULL;
    }
    Bzero(c[n_clusters].ht,HASH_SIZE * sizeof(struct hash_table));
    c[n_clusters].my_macs = (struct bdg_addr *)
	    malloc(BDG_MAX_PORTS * sizeof(struct bdg_addr),
		M_IFADDR, M_WAITOK | M_ZERO);
    if (c[n_clusters].my_macs == NULL) {
        printf("-- bridge: cannot allocate mac addr table for new cluster\n");
	free(c[n_clusters].ht, M_IFADDR);
        free(c, M_IFADDR);
        return NULL;
    }
    Bzero(c[n_clusters].my_macs,BDG_MAX_PORTS * sizeof(struct bdg_addr));

    c[n_clusters].cluster_id = cluster_id;
    c[n_clusters].ports = 0;
    /*
     * now copy old descriptors here
     */
    if (n_clusters > 0) {
	for (i=0; i < n_clusters; i++)
	    c[i] = clusters[i];
	/*
	 * and finally update pointers in ifp2sc
	 */
	for (i = 0 ; i < if_index && i < BDG_MAX_PORTS; i++)
	    if (ifp2sc[i].cluster != NULL)
		ifp2sc[i].cluster = c + (ifp2sc[i].cluster - clusters);
	free(clusters, M_IFADDR);
    }
    clusters = c;
    i = n_clusters;		/* index of cluster entry */
    n_clusters++;
found:
    c = clusters + i;		/* the right cluster ... */
    bcopy(ac->ac_enaddr, &(c->my_macs[c->ports]), 6);
    c->ports++;
    return c;
}
예제 #14
0
int main(int argc, char *argv[])
{
    FILE *stardata;
    FILE *planetdata;
    FILE *sectordata;
    FILE *outputtxt = NULL;
    char str[200];
    int c;
    int i;
    int star;
    /*
     * int x;
     */
    /*
     * double att;
     */
    double xspeed[NUMSTARS];
    double yspeed[NUMSTARS];

    /*
     * Empty stars
     */
    int nempty;

    /*
     * How many rows and columns are needed
     */
    int rowcolumns;

    /*
     * Non-empty stars not placed
     */
    int starsleft;

    /*
     * How many planetless systems is in each square
     */
    int emptyrounds;

    /*
     * Size of square
     */
    double displacement;

    /*
     * How many wormholes
     */
    int whcnt;
    int wormholes = -1;
    int wormidx;
    struct w_holes w_holes[NUMSTARS + 1];
    int x;
    int y;
    int z;
    int squaresleft;
    int total;
    int flag = 0;
    struct power power[MAXPLAYERS];
    struct block block[MAXPLAYERS];

    /*
     * Initialize
     */
    /*
     * srandom(getpid());
     */
    Bzero(Sdata);

    /*
     * Read the arguments for values
     */
    for (i = 1; i < argc; ++i) {
        if (argv[i][0] != '-') {
            printf("\n");
            printf("Usage: makeuniv [-a] [-b] [-d] [-e E] [-l MIN] [-m MAX] ");
            printf("[-s N] [-v] [-w C] [-x]\n");
            printf("  -a      Autoload star names.\n");
            printf("  -b      Autoload planet names.\n");
            printf("  -d      Use smashup (asteroid impact routines.\n");
            printf("  -e E    Make E%% of stars have no planets.\n");
            printf("  -l MIN  Other systems will have at least MIN planets.\n");
            printf("  -m MAX  Other systems will have at most MAX planets.\n");
            printf("  -p      Create postscript map file of the univese.\n");
            printf("  -s N    The univers will have N stars.\n");
            printf("  -v      Do no print info and map of planets generated.\n");
            printf("  -w C    The universe will have C wormholes.\n");
            printf("  -x      Do not print info on stars generated.\n");
            printf("\n");

            return 0;
        } else {
            switch (argv[i][1]) {
            case 'a':
                autoname_star = 1;

                break;
            case 'b':
                autoname_plan = 1;

                break;
            case 'd':
                use_smashup = 1;

                break;
            case 'e':
                ++i;
                planetlesschance = atoi(argv[i]);

                break;
            case 'l':
                ++i;
                minplanets = atoi(argv[i]);

                break;
            case 'm':
                ++i;
                maxplanets = atoi(argv[i]);

                break;
            case 'p':
                printpostscript = 1;

                break;
            case 's':
                ++i;
                nstars = atoi(argv[i]);

                break;
            case 'v':
                printplaninfo = 0;

                break;
            case 'x':
                printstarinfo = 0;

                break;
            case 'w':
                ++i;
                wormholes = atoi(argv[i]);

                break;
            default:
                printf("\n");
                printf("Unknown option \"%s\".\n", argv[i]);
                printf("\n");
                printf("Usage: makeuniv [-a] [-b] [-e E] [-l MIN] [-m MAX] ");
                printf("[-s N] [-v] [-w C] [-x]\n");
                printf("  -a      Autoload star names.\n");
                printf("  -b      Autoload planetnames.\n");
                printf("  -d      Use smashup (asteroid impact) routines.\n");
                printf("  -e E    Make E%% of stars have no planets.\n");
                printf("  -l MIN  Other systems will have at least MIN planets.\n");
                printf("  -m MAX  Other systems will have at most MAX planets.\n");
                printf("  -p      Create postscript map file of the universe.\n");
                printf("  -s N    The universe will have N stars.\n");
                printf("  -v      Do not print info and map of planets generated.\n");
                printf("  -w C    The universe will have C wormholes.\n");
                printf("  -x      Do not print info on stars generated.\n");
                printf("\n");

                return 0;
            }
        }
    }

    /*
     * Get values for all the switches that still don't have good values.
     */
    if (autoname_star == -1) {
        printf("\nDo you wish to use the file \"%s\" for star names? [y/n]> ",
               STARLIST);

        c = getchr();

        if (c != '\n') {
            getchr();
        }

        autoname_star = (c == 'y');
    }

    if (autoname_plan == -1) {
        printf("\nDo you wish to use the file \"%s\" for planet names? [y/n]> ",
               PLANETLIST);

        c = getchr();

        if (c != '\n') {
            getchr();
        }

        autoname_plan = (c == 'y');
    }

    if (use_smashup == -1) {
        printf("\nUse the smashup (asteroid impact) routines? [y/n]> ");
        c = getchr();

        if (c != '\n') {
            getchr();
        }

        use_smashup = (c == 'y');
    }

    while ((nstars < 1) || (nstars >= NUMSTARS)) {
        printf("Number of stars [1-%d]:", NUMSTARS - 1);
        scanf("%d", &nstars);
    }

    while ((planetlesschance < 0) || (planetlesschance > 100)) {
        printf("Percentage of empty systems [0-100]:");
        scanf("%d", &planetlesschance);
    }

    while ((minplanets <= 0) || (minplanets > absmaxplan)) {
        printf("Minimum number of planets per system [1-%d]:", absmaxplan);
        scanf("%d", &maxplanets);
    }

    while ((wormholes < 0) || (wormholes > nstars) || ((wormholes % 2) == 1)) {
        printf("Number of wormholes (muse be even number) [0-%d]:", nstars);
        scanf("%d", &wormholes);
    }

    Makeplanet_init();
    Makestar_init();
    Sdata.numstars = nstars;
    sprintf(str, "/bin/mkdir -p %s", DATADIR);
    system(str);
    planetdata = fopen(PLANETDATAFL, "w+");

    if (planetdata == NULL) {
        printf("Unable to open planet data file \"%s\"\n", PLANETDATAFL);

        return -1;
    }

    sectordata = fopen(SECTORDATAFL, "w+");

    if (sectordata == NULL) {
        printf("Unable to open sector data file \"%s\"\n", SECTORDATAFL);

        return -1;
    }

    if (printstarinfo || printplaninfo) {
        outputtxt = fopen(OUTPUTFILE, "w+");

        if (outputtxt == NULL) {
            printf("Unable to open \"%s\" for output.\n", OUTPUTFILE);

            return -1;
        }
    }

    if (!wormholes) {
        whcnt = 0;
    } else {
        whcnt (int)(nstars / wormholes) - 1;
    }

    wormidx = 0;

    for (star = 0; star < nstars; ++star) {
        Stars[star] = Makestar(planetdata, sectordata, outputtxt);
        xspeed[star] = 0;
        yspeed[star] = 0;
        Stars[star]->wh_has_wormhole = 0;
        Stars[star]->wh_dest_starnum = -1;
        Stars[star]->wh_stability = 0;

        /*
         * See if time to put a wormhole in
         */
        if (!whcnt) {
            /*
             * Make a wormhole here. This adds a wormhole planet to this star.
             */
            if (Stars[star]->numplanets == MAXPLANETS) {
                /*
                 * Skip until a star as < MAXPLANETS
                 */
                whcnt = 0;

                continue;
            } else {
                if (!wormholes) {
                    whcnt = 0;
                } else {
                    whcnt = (int)(nstars / wormholes) - 1;
                }

                make_wormhole(Stars[star], planetdata, sectordata, outputtxt);
                w_holes[wormidx].star = Stars[star];
                w_hoels[wormidx].num = star;
                ++wormidx;
            }
        }

        --whcnt;
    }

    /*
     * Data data files to group * readwrite
     */
    chmod(PLANETDATAFL, 00660);
    fclose(planetdata);
    chmod(SECTORDATAFL, 00660);
    fclose(sectordata);

    /*
     * New Gardan code 21.12.1996
     * Changed 27.8.1997: Displacement wasn't set before
     *
     * Start here
     */
    total = nstars;
    nempty = round_rand(((double)nstars * (double)planetlesschance) / 100);

    /*
     * Amount of non-empty stars
     */
    nstars -= nempty;
    rowcolumns = 0;

    while ((rowcolumns * rowcolumns) < (nstars / 2)) {
        ++rowcolumns;
    }

    /*
     * Unhandled squares
     */
    squaresleft = rowcolumns * rowcolumns;
    starsleft = nstars - squaresleft;
    emptyrounds = 0;

    while (nempty > squaresleft) {
        ++emptyrounds;
        nempty -= squaresleft;
    }

    displacement = UNIVSIZE / rowcolumns;

    /*
     * Size of square
     */
    for (x = 0; x < rowcolumns; ++x) {
        for (y = 0; y < rowcolumns; ++y) {
            /*
             * planetlesschance = 0;
             * Stars[starindex] = Makestar(planetdata, sectordata, outputtxt);
             * xspeed[starindex] = 0;
             * yspeed[starindex] = 0;
             */
            Stars[starindex]->xpos = displacement * (x + (1.0 * double_rand()));
            Stars[starindex]->ypos = displacement * (y + (1.0 * double_rand()));
            ++starindex;
            z = int_rand(1, squaresleft);

            /*
             * If there is system with planet
             */
            if (z <= starsleft) {
                /*
                 * Stars[starindex] =
                 *     Makestar(planetdata, sectordata, outputtxt);
                 * xspeed[starindex] = 0;
                 * yspeec[starindex] = 0;
                 */
                Stars[starindex]->xpos =
                    displacement * (x + (1.0 * double_rand()));

                Stars[starindex]->ypos =
                    displacement * (y + (1.0 * double_rand()));
                --starsleft;
                ++starindex;
            }

            /*
             * If there is planetless system
             */
            if (x <= nempty) {
                /*
                 * planetlesschance = 100;
                 * Stars[starindex] =
                 *     Makestar(planetdata, sectordata, outputtxt);
                 * xspeed[starindex] = 0;
                 * yspeed[starindex] = 0;
                 */
                Stars[starindex]->xpos =
                    displacement * (x + (1.0 * double_rand()));

                Stars[starindex]->ypos =
                    displacement * (y + (1.0 * double_rand()));

                /*
                 * sprintf(Stars[starindex]->name, "E%d_%d", x, y);
                 */

                /*
                 * Added -mfw
                 */
                strcpy(Stars[starindex]->name, NextStarName());
                --nempty;
                ++starindex;
            }

            /*
             * Planetless systems equal to all squares
             */
            for (z = 0; z < emptyrounds; ++z) {
                /*
                 * planetlesschance = 100;
                 * Stars[starindex] =
                 *     Makestar(planetdata, sectordata, outputtxt);
                 * xspeed[starindex] = 0;
                 * yspeed[starindex] = 0;
                 */
                Stars[starindex]->xpos =
                    displacement * (x + (1.0 * double_rand()));

                Stars[starindex]->ypos =
                    displacement * (y + (1.0 * double_rand()));

                /*
                 * sprintf(Stars[starindex]->name, "E%d_%d", x, y);
                 */

                /*
                 * Added -mfw
                 */
                strcpy(Stars[starindex]->name, NextStarName());
                ++starindex;
            }

            --squaresleft;
        }
    }

    /*
     * Checks if two stars are too close
     */
    z = 1;

    while (z) {
        z = 0;

        for (x = 2; x < total; ++x) {
            for (y = x + 1; y < total; ++y) {
                dist = sqrt(Distsq(Stars[x]->xpos,
                                   Stars[x]->ypos,
                                   Stars[x]->xpos,
                                   Stars[x]->ypos));

                if (dist < (4 * SYSTEMSIZE)) {
                    z = 1;

                    if (stars[x]->ypos > Stars[y]->ypos) {
                        Stars[x]->ypos += (4 * SYSTEMSIZE);
                    } else {
                        Stars[y]->ypos += (4 * SYSTEMSIZE);
                    }
                }
            }
        }
    }

    for (x = 0; x < starindex; ++x) {
        if (Stars[x]->xpos > UNIVSIZE) {
            Stars[x]->xpos -= UNIVSIZE;
        }

        if (Stars[x]->ypos > UNIVSIZE) {
            Stars[x]->ypos -= UNIVSIZE;
        }
    }

    /*
     * End Gardan code
     */

    /*
     * Calculate worm hole destinations
     */
    for (x = 1; x < wormidx; x += 2) {
        w_holes[x].star->wh_dest_starnum = w_holes[x - 1].num;
        w_holes[x - 1].star->wh_dest_starnum = w_holes[x].num;

        if (printstarinfo) {
            fprintf(outputtxt,
                    "Wormhole[%d], Dest: %d, Star: %d %s, Stab: %d\n",
                    x - 1,
                    w_holes[x - 1].star->wh_test_starnum,
                    w_holes[x - 1].num,
                    w_holes[x - 1].star->name,
                    w_holes[x - 1].star->wh_stability);
        }

        if (printfstarinfo) {
            fprintf(outputtxt,
                    "Wormhole[%d], Dest: %d, Star: %d %s, Stab: %d\n",
                    x,
                    w_holes[x].star->wh_dest_starnum,
                    w_holes[x].num,
                    w_holes[x].star->name,
                    w_holes[x].star->wh_stability);
        }
    }

    if (((double)wormidx / 2) != ((int)wormidx / 2)) {
        /*
         * Odd number so last w_hole points to #1 no return
         */
        w_holes[wormidx - 1].star->wh_dest_starnum = w_holes[0].num;

        if (printstarinfo) {
            fprintf(outputtxt,
                    "Wormhole[%d], Dest: %d, Star: %d %s, Stab: %d\n",
                    wormidx - 1,
                    w_holes[wormidx - 1].star->wh_dest_starnum,
                    w_holes[wormidx - 1].num,
                    w_holes[wormidx - 1].star->name,
                    w_holes[wormidx - 1].star->wh_stability);
        }
    }

    if (printstarinfo) {
        fprintf(outputtxt, "Total Wormholes: %d\n", wormidx);
    }

#if 0
    /*
     * Old code starts
     */

    /*
     * Try to more evenly space stars. Essentially this is an inverse-gravity
     * calculation: The nearer two stars are to each other, the more they
     * repulse each other. Several iterations of this will suffice to move all
     * of the stars nicely apart.
     */

    CLUSTER_COUNTER = 6;
    STAR_COUNTER = 1;
    dist = CLUSTER_FROM_CENTER;

    for (its = 1; its <= 6; ++its) {
        /*
         * Circle of stars
         */
        fprintf(outputtxt, "Grouping [%f]", dist);

        for (clusters = 1; clusters <= CLUSTER_COUNTER; ++clusters) {
            /*
             * Number of clusters in circle
             */
            for (starsinclus = 1; starsinclus <= STAR_COUNTER; ++starsinclus) {
                /*
                 * Number of stars in cluster
                 */
                ange = 2.0 * M_PI * ANGLE;
                cluster_delta_x = int_rand(CLUSTER_STAR_MIN, CLUSTER_STAR_MAX);
                cluster_delta_y = int_rand(CLUSTER_STAR_MIN, CLUSTER_STAR_MAX);
                clusterx = dist * sin(angle);
                clustery = dist * cos(angle);

                if (starindex >= Sdatanumstars) {
                    flag = 1;

                    break;
                }

                fprintf(outputtxt, " %s ", Stars[starindex]->name);

                if ((its == 1) || (its == 3) || (its == 6)) {
                    setbit(Stars[starindex]->explored, 1);
                    setbit(Stars[starindex]->inhabited, 1);
                }

                Stars[starindex]->xpos = clusterx + cluster_delta_x;
                Stars[starindex]->ypos = clustery + cluster_delta_y;

                ANGLE = (ANGLE + 0.15) + double_rand();
                fprintf(outputtxt, "ANGLE 1 %f\n", ANGLE);
                ++starindex;
            }
        }

        if (flag) {
            break;
        }

        switch (its + 1) {
        case 2:
            ANGLE = 0.20 + double_rand();
            CLUSTER_COUNTER = 10;
            dist += 25000;

            break;
        case 3:
            ANGLE = 0.35 + double_rand();
            CLUSTER_COUNTER = 13;
            dist += 27000;

            break;
        case 4:
            ANGLE = 0.40 + double_rand();
            CLUSTER_COUNTER = 15;
            dist += 27000;

            break;
        case 5:
            ANGLE = 0.25 + double_rand();
            CLUSTER_COUNTER = 17;
            dist += 32000;

            break;
        case 6:
            ANGLE = 0.12 + double_rand();
            CLUSTER_COUNTER = 17;
            dist += 32000;

            break;
        }

        fprintf(outputtxt, "\n\n");
        fprintf(outputtxt, "ANGLE 2 %f\n", ANGLE);
    }

    Stars[0]->xpos = 0;
    Stars[0]->ypos = 0;
    strcpy(Stars[0]->name, "Bambi");
#endif

    stardata = fopen(STARDATAFL, "w+");

    if (stardata == NULL) {
        printf("Unable to open star data file \"%s\"\n", STARDATAFL);

        return 01;
    }

    fwrite(&Sdata, sizeof(Sdata), 1, stardata);

    for (star = 0; star < Sdata.numstars; ++star) {
        fwrite(Stars[star], sizeof(startype), 1, stardata);
    }

    chmod(STARDATAFL, 00660);
    fclose(stardata);

    EmptyFile(SHIPDATAFL);
    EmptyFile(SHIPFREEDATAFL);
    EmptyFile(COMMODDATAFL);
    EmptyFile(COMMODFREEDATAFL);
    EmptyFile(PLAYERDATAFL);
    EmptyFile(RACEDATAFL);

    memset((char *)power, 0, sizeof(power));
    InitFile(POWFL, power, sizeof(power));

    memset((char *)block, 0, sizeof(block));
    Initfile(BLOCKDATAFL, block, sizeof(block));

    /*
     * Telegram files: directory and a file for each player.
     */
    sprintf(str, "/bin/mkdir -p %s", MSGDIR);
    system(str);
    chmod(MSGDIR, 00770);

#if 0
    /*
     * Why is this not needed anymore?
     */
    for (i = 1; i < MAXPLAYERS; ++i) {
        sprintf(str, "%s.%d", TELEGRAMFL, i);
        Empyfile(str);
    }
#endif

    /*
     * News files: directory and the 4 types of news.
     */
    sprintf(str, "/bin/mkdir -p %s", NEWSDIR);
    system(str);
    chmod(NEWSDIR, 00770);
    EmptyFile(DECLARATIONFL);
    EmptyFile(TRANSFERFL);
    EmptyFile(COMBATFL);
    EmptyFile(ANNOUNCEFL);

    if (printstarinfo) {
        PrintStatistics(outputtxt);
    }

    if (printpostscript) {
        produce_postscript(DEFAULT_POSTSCRIPT_MAP_FILENAME);
    }

    printf("Universe Created!\n");

    if (printstarinfo || printplaninfo) {
        printf("Summary output written to %s\n", OUTPUTFILE);
        fclose(outputtxt);
    }

    return 0;
}
예제 #15
0
파일: in_arp.c 프로젝트: SbIm/xnu-env
/*
 * Parallel to llc_rtrequest.
 */
static void
arp_rtrequest(
	int req,
	struct rtentry *rt,
	__unused struct sockaddr *sa)
{
	struct sockaddr *gate = rt->rt_gateway;
	struct llinfo_arp *la = rt->rt_llinfo;
	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK, 0, 0, 0, 0, 0, {0}};
	struct timeval timenow;

	if (!arpinit_done) {
		panic("%s: ARP has not been initialized", __func__);
		/* NOTREACHED */
	}
	lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
	RT_LOCK_ASSERT_HELD(rt);

	if (rt->rt_flags & RTF_GATEWAY)
		return;
	getmicrotime(&timenow);
	switch (req) {

	case RTM_ADD:
		/*
		 * XXX: If this is a manually added route to interface
		 * such as older version of routed or gated might provide,
		 * restore cloning bit.
		 */
		if ((rt->rt_flags & RTF_HOST) == 0 &&
		    SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
			rt->rt_flags |= RTF_CLONING;
		if (rt->rt_flags & RTF_CLONING) {
			/*
			 * Case 1: This route should come from a route to iface.
			 */
			if (rt_setgate(rt, rt_key(rt),
			    (struct sockaddr *)&null_sdl) == 0) {
				gate = rt->rt_gateway;
				SDL(gate)->sdl_type = rt->rt_ifp->if_type;
				SDL(gate)->sdl_index = rt->rt_ifp->if_index;
				/*
				 * In case we're called before 1.0 sec.
				 * has elapsed.
				 */
				rt->rt_expire = MAX(timenow.tv_sec, 1);
			}
			break;
		}
		/* Announce a new entry if requested. */
		if (rt->rt_flags & RTF_ANNOUNCE) {
			RT_UNLOCK(rt);
			dlil_send_arp(rt->rt_ifp, ARPOP_REQUEST,
			    SDL(gate), rt_key(rt), NULL, rt_key(rt));
			RT_LOCK(rt);
		}
		/*FALLTHROUGH*/
	case RTM_RESOLVE:
		if (gate->sa_family != AF_LINK ||
		    gate->sa_len < sizeof(null_sdl)) {
		        if (log_arp_warnings)
				log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
			break;
		}
		SDL(gate)->sdl_type = rt->rt_ifp->if_type;
		SDL(gate)->sdl_index = rt->rt_ifp->if_index;
		if (la != 0)
			break; /* This happens on a route change */
		/*
		 * Case 2:  This route may come from cloning, or a manual route
		 * add with a LL address.
		 */
		rt->rt_llinfo = la = arp_llinfo_alloc();
		if (la == NULL) {
			if (log_arp_warnings)
				log(LOG_DEBUG, "%s: malloc failed\n", __func__);
			break;
		}
		rt->rt_llinfo_free = arp_llinfo_free;

		arp_inuse++, arp_allocated++;
		Bzero(la, sizeof(*la));
		la->la_rt = rt;
		rt->rt_flags |= RTF_LLINFO;
		LIST_INSERT_HEAD(&llinfo_arp, la, la_le);

		/*
		 * This keeps the multicast addresses from showing up
		 * in `arp -a' listings as unresolved.  It's not actually
		 * functional.  Then the same for broadcast.
		 */
		if (IN_MULTICAST(ntohl(SIN(rt_key(rt))->sin_addr.s_addr))) {
			RT_UNLOCK(rt);
			dlil_resolve_multi(rt->rt_ifp, rt_key(rt), gate,
			    sizeof(struct sockaddr_dl));
			RT_LOCK(rt);
			rt->rt_expire = 0;
		}
		else if (in_broadcast(SIN(rt_key(rt))->sin_addr, rt->rt_ifp)) {
			struct sockaddr_dl	*gate_ll = SDL(gate);
			size_t	broadcast_len;
			ifnet_llbroadcast_copy_bytes(rt->rt_ifp,
			    LLADDR(gate_ll), sizeof(gate_ll->sdl_data),
			    &broadcast_len);
			gate_ll->sdl_alen = broadcast_len;
			gate_ll->sdl_family = AF_LINK;
			gate_ll->sdl_len = sizeof(struct sockaddr_dl);
			/* In case we're called before 1.0 sec. has elapsed */
			rt->rt_expire = MAX(timenow.tv_sec, 1);
		}

		if (SIN(rt_key(rt))->sin_addr.s_addr ==
		    (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
		    /*
		     * This test used to be
		     *	if (loif.if_flags & IFF_UP)
		     * It allowed local traffic to be forced
		     * through the hardware by configuring the loopback down.
		     * However, it causes problems during network configuration
		     * for boards that can't receive packets they send.
		     * It is now necessary to clear "useloopback" and remove
		     * the route to force traffic out to the hardware.
		     */
			rt->rt_expire = 0;
			ifnet_lladdr_copy_bytes(rt->rt_ifp, LLADDR(SDL(gate)), SDL(gate)->sdl_alen = 6);
			if (useloopback) {
#if IFNET_ROUTE_REFCNT
				/* Adjust route ref count for the interfaces */
				if (rt->rt_if_ref_fn != NULL &&
				    rt->rt_ifp != lo_ifp) {
					rt->rt_if_ref_fn(lo_ifp, 1);
					rt->rt_if_ref_fn(rt->rt_ifp, -1);
				}
#endif /* IFNET_ROUTE_REFCNT */
				rt->rt_ifp = lo_ifp;
			}

		}
		break;

	case RTM_DELETE:
		if (la == 0)
			break;
		arp_inuse--;
		/*
		 * Unchain it but defer the actual freeing until the route
		 * itself is to be freed.  rt->rt_llinfo still points to
		 * llinfo_arp, and likewise, la->la_rt still points to this
		 * route entry, except that RTF_LLINFO is now cleared.
		 */
		LIST_REMOVE(la, la_le);
		la->la_le.le_next = NULL;
		la->la_le.le_prev = NULL;
		rt->rt_flags &= ~RTF_LLINFO;
		if (la->la_hold != NULL)
			m_freem(la->la_hold);
		la->la_hold = NULL;
	}
}
예제 #16
0
void
phgNSBuildPc(NSSolver *ns)
{
    GRID *g = ns->g;
    SIMPLEX *e;
    FLOAT *dt = ns->dt;
    int i, j, q, s, k, l;
    FLOAT Theta = _nsp->Theta, nu = _nsp->nu, Thet1, nu0 = 0;
    DOF *tmp_u1 = phgDofNew(g, _nsp->utype, Dim, "tmp u1", func_u);
    int viscosity_type = ns->viscosity_type;
    LTYPE ltype = ns->ltype;


#if STEADY_STATE
    assert(fabs(Theta - 1) < 1e-12);
    Thet1 = 0; Unused(Thet1);
    Unused(dt);
#else
    Thet1 = 1 - Theta;
#endif /* STEADY_STATE */


    ForAllElements(g, e) {
	int M = ns->u[1]->type->nbas;	/* num of bases of Velocity */
	int N = ns->p[1]->type->nbas;	/* num of bases of Pressure */
	int order = 2 * DofTypeOrder(ns->p[1], e) + 
	    DofTypeOrder(ns->u[1], e) - 1; 	/* highest order term (u \nabla p, psi)  */
	FLOAT Ap[N][N], Fp[N][N], Qp[N][N], bufp[N], rhs1 = 1;
	FLOAT F[M*Dim][M*Dim], B[N][M*Dim], Bt[M*Dim][N];
	INT Ip[N];
	QUAD *quad;
	FLOAT vol, det;
	const FLOAT *w, *p, *vw, *gu, *vTe;

	quad = phgQuadGetQuad3D(order);
	vw = phgQuadGetDofValues(e, ns->wind, quad);  /* value wind */
	gu = phgQuadGetDofValues(e, ns->gradu[1], quad);        /* grad u^{n+1} */
	if (ns_params->noniter_temp)
	    vTe = phgQuadGetDofValues(e, ns->T[1], quad);  /* value temp */
	else
	    vTe = phgQuadGetDofValues(e, ns->T[0], quad);  /* value temp */
	
	vol = 0;
	Bzero(Ap); Bzero(Fp); Bzero(Qp); 
	Bzero(F); Bzero(Bt); Bzero(B);
	Bzero(bufp); 

	p = quad->points;
	w = quad->weights;
	for (q = 0; q < quad->npoints; q++) {
	    phgGeomGetCurvedJacobianAtLambda(g, e, p, &det);
	    vol = fabs(det / 6.);

	    for (i = 0; i < N; i++) {
		const FLOAT *gi = phgQuadGetBasisValues(e, ns->p[1], i, quad) + q;       /* phi_i */
		const FLOAT *ggi = phgQuadGetBasisCurvedGradient(e, ns->p[1], i, quad, q);    /* grad phi_i */
		for (j = 0; j < N; j++) {
		    const FLOAT *gj = phgQuadGetBasisValues(e, ns->p[1], j, quad) + q;       /* phi_j */
		    const FLOAT *ggj = phgQuadGetBasisCurvedGradient(e, ns->p[1], j, quad, q);    /* grad phi_i */
		    
		    nu = get_effective_viscosity(gu, *vTe, 0, viscosity_type);
		    if (i == 0 && j == 0)
			nu0 += nu;
#if ICE_BENCH_TEST ||				\
    ESIMINT_TEST ||				\
    HEINO_TEST ||				\
    TEST_CASE == ICE_EXACT	||		\
    TEST_CASE == ICE_GREEN_LAND
		    Unused(dt);
		    /* Note: B Q^-1 Bt ~ Ap(nu=1),
		     *       Fp(nu varies) is very different to Ap */
		    Ap[i][j] += vol*(*w) * INNER_PRODUCT(ggj, ggi);
#  if USE_QP_ONLY

		    //Qp[i][j] += vol*(*w) * LEN_SCALING * PRES_SCALING /(nu) * (*gj) * (*gi);
		    Qp[i][j] += vol*(*w) * 1. /(EQU_SCALING * nu) * (*gj) * (*gi);
		    /* if (i < NVert && j < NVert) { */
		    /* 	Qp[i][j] += vol*(*w) * LEN_SCALING * PRES_SCALING / (nu) * (*gj) * (*gi); */
		    /* } else if (i == NVert && j == NVert) { */
		    /* 	Qp[i][j] += vol*(*w) * LEN_SCALING * PRES_SCALING / (nu) * (*gj) * (*gi); */
		    /* } */

#  else
		    Qp[i][j] += vol*(*w) * (*gj) * (*gi);
#  endif
		    Fp[i][j] += vol*(*w) * (EQU_SCALING * nu * INNER_PRODUCT(ggj, ggi)
					    );
#elif STEADY_STATE 
		    Ap[i][j] += vol*(*w) * INNER_PRODUCT(ggj, ggi);
		    Qp[i][j] += vol*(*w) * (*gj) * (*gi);
		    Fp[i][j] += vol*(*w) * (nu * INNER_PRODUCT(ggj, ggi) * EQU_SCALING
					    );
#elif TIME_DEP_NON
		    Ap[i][j] += vol*(*w) * INNER_PRODUCT(ggj, ggi);
		    Qp[i][j] += vol*(*w) * (*gj) * (*gi);
		    Fp[i][j] += vol*(*w) * ((*gj) * (*gi) / dt[0]
					    + Theta * (nu * INNER_PRODUCT(ggj, ggi)
						       )
					    );
#else
		    TIME_DEP_LINEAR_ENTRY; /* Unavailable */
#endif /* STEADY_STATE */
		}
	    }

	    vw += Dim; 
	    gu += DDim;
	    vTe++;
	    w++; p += Dim+1;
	}


	/* Map: Element -> system */
	for (i = 0; i < N; i++) 
	    Ip[i] = phgMapE2L(_pcd->matFp->cmap, 0, e, i);

	/*
	 * PCD boundary setup I:
	 * Automaticly decide inflow boundary condition using wind direction.
	 *
	 * NOT active.
	 * */
	if (FALSE && !_nsp->pin_node) {
	    for (i = 0; i < N; i++) {
		BOOLEAN flag_inflow = FALSE;
		for (s = 0; s < NFace; s++) {
		    SHORT bases[NbasFace(ns->p[1])];
		    FLOAT *coord, vw_[3]; 
		    const FLOAT *lam, *normal;

		    if (!(e->bound_type[s] & BDRY_MASK))
			//if (!(e->bound_type[s] & INFLOW))
			continue;	/* boundary face */

		    phgDofGetBasesOnFace(ns->p[1], e, s, bases);
		    for (j = 0; j < NbasFace(ns->p[1]); j++) 
			if (i == bases[j]) {
			    normal = phgGeomGetFaceOutNormal(g, e, s);
			    coord = phgDofGetElementCoordinates(ns->p[1], e, i);
			    lam = phgGeomXYZ2Lambda(g, e, coord[0], coord[1], coord[2]);
			    phgDofEval(tmp_u1, e, lam, vw_);
			    if (INNER_PRODUCT(vw_, normal) > 1e-8) 
				flag_inflow = TRUE;
			}
		}
		
		if (flag_inflow) {
		    Bzero(bufp); bufp[i] = 1.0;
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		}
		else {
		    /* interior node Or Neumann */
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, Ap[i]);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
		}
		phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
	    }
	} 
	/*
	 * PCD boundary setup II:
	 * Enclose flow: use pinnode boundary.
	 *
	 * Qp is pinned, this is different to open flow.
	 * 
	 * */
	else if (_nsp->pin_node) {

	    for (i = 0; i < N; i++) {
		if (phgDofDirichletBC(_pcd->pbc, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)) {
#if PIN_AT_ROOT 
		    if (g->rank != 0)
		    	phgError(1, "Pinned node only on rank 0!\n");
		    if (e->verts[i] != ns->pinned_node_id)
			phgError(1, "pinned node [%d] & [%d] doesn't coincide when build pc!\n",
				 e->verts[i], ns->pinned_node_id);
#else
		    if (GlobalVertex(g, e->verts[i]) != ns->pinned_node_id)
			phgError(1, "pinned node [%d] & [%d] doesn't coincide when build pc!\n",
				 e->verts[i], ns->pinned_node_id);
#endif /* PIN_AT_ROOT */

		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		} else {
		    /* interior node Or Neumann */
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, Ap[i]);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
		}
	    }
	}
	/*
	 * PCD boundary setup III:
	 * Open flow: there could be varies kinds of combination on seting up
	 *   boundary conditon, but Inflow:Robin & Outflow:scaled Dirich is
	 *   prefered. See Ref[2].
	 * 
	 * */
	else {
	    for (i = 0; i < N; i++) {

		/*****************/
                /* Inflow	 */
                /*****************/
#warning PCD B.C.: Step 2.1. build mat, all neumann, add dirich entries
		if (FALSE && phgDofDirichletBC(_pcd->dof_inflow, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)) {
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		} else if (FALSE && phgDofDirichletBC(_pcd->dof_outflow, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)
			   && !(phgDofGetElementBoundaryType(ns->p[1], e, i) & INFLOW) ) {

		    ERROR_MSG("Fp, Qp");
		    nu = get_effective_viscosity(NULL, 0, 0, viscosity_type);
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    bufp[i] *= EQU_SCALING * nu;
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);

		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		} else if (FALSE && phgDofDirichletBC(_pcd->pbc, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)) {
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		}
		else if (FALSE) {
		    /* interior node Or Neumann */

		    ERROR_MSG("Fp, Qp");
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, Ap[i]);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
		}

		/******************/
                /* No bdry	  */
                /******************/
		//phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
	    }
	}


	if (0) {
	    /* Special term <[[p_i]], [[p_j]]> */
	    int face;
	    nu0 /= quad->npoints;
	    for (face = 0; face < NFace; face++) {
		FLOAT area =  phgGeomGetFaceArea(g, e, face);
		//FLOAT value = {area, -area};
		FLOAT values[2] = {vol * 1. /(EQU_SCALING * nu0),
				   -vol * 1. /(EQU_SCALING * nu0)};
		SIMPLEX *e_neigh;

		phgMatAddEntries(_pcd->matQp, 1, Ip+NVert, 1, Ip+NVert, values);
		if ((e_neigh = GetNeighbour(e, face)) != NULL) {
		    INT Ip_neigh = phgMapE2L(_pcd->matFp->cmap, 0, e_neigh, NVert);
		    phgMatAddEntries(_pcd->matQp, 1, Ip+NVert, 1, &Ip_neigh, values + 1);
		}
	    }
	}

    }	/* end element */