Пример #1
0
void fdprep(const double omega,
            const float eps,
            const int n1, const int n2,
            const float d1, const float d2,
            float **v,
            const int npml,
            const int pad1, const int pad2,
            SuiteSparse_long n, SuiteSparse_long nz,
            SuiteSparse_long *Ti, SuiteSparse_long *Tj,
            double* Tx, double *Tz)
/*< 5-point finite-difference scheme >*/
{
    int i, j, index;
    double eta1, eta2, mvel, c1, c2;
    double *g1, *g2, **pad;
    double complex *s1, *s2, neib, cent;
    SuiteSparse_long count;

    /* prepare PML */
    eta1 = (double) npml*d1;
    eta2 = (double) npml*d2;

    mvel = maxvel(n1*n2,v[0]);
    c1 = -3.*log((double) eps)*mvel/(eta1*omega);
    c2 = -3.*log((double) eps)*mvel/(eta2*omega);

    g1 = (double*) sf_alloc(pad1,sizeof(double));
    for (i=0; i < pad1; i++) {
        if (i < npml) {
            g1[i] = pow(c1*((npml-i)*d1/eta1),2.);
        } else if (i >= pad1-npml) {
            g1[i] = pow(c1*((i-(pad1-npml-1))*d1/eta1),2.);
        } else {
            g1[i] = 0.;
        }
    }

    s1 = (double complex*) sf_alloc(pad1,sizeof(double complex));
    for (i=0; i < pad1; i++) {
        s1[i] = 1./(1.+I*g1[i]);
    }

    g2 = (double*) sf_alloc(pad2,sizeof(double));
    for (j=0; j < pad2; j++) {
        if (j < npml) {
            g2[j] = pow(c2*((npml-j)*d2/eta2),2.);
        } else if (j >= pad2-npml) {
            g2[j] = pow(c2*((j-(pad2-npml-1))*d2/eta2),2.);
        } else {
            g2[j] = 0.;
        }
    }

    s2 = (double complex*) sf_alloc(pad2,sizeof(double complex));
    for (j=0; j < pad2; j++) {
        s2[j] = 1./(1.+I*g2[j]);
    }

    /* extend model */
    pad = (double**) sf_alloc(pad2,sizeof(double*));
    pad[0] = (double*) sf_alloc(pad1*pad2,sizeof(double));
    for (j=1; j < pad2; j++) {
        pad[j] = pad[0]+j*pad1;
    }

    for (j=0; j < npml; j++) {
        for (i=0; i < npml; i++) {
            pad[j][i] = v[0][0];
        }
        for (i=npml; i < pad1-npml; i++) {
            pad[j][i] = v[0][i-npml];
        }
        for (i=pad1-npml; i < pad1; i++) {
            pad[j][i] = v[0][n1-1];
        }
    }
    for (j=npml; j < pad2-npml; j++) {
        for (i=0; i < npml; i++) {
            pad[j][i] = v[j-npml][0];
        }
        for (i=npml; i < pad1-npml; i++) {
            pad[j][i] = v[j-npml][i-npml];
        }
        for (i=pad1-npml; i < pad1; i++) {
            pad[j][i] = v[j-npml][n1-1];
        }
    }
    for (j=pad2-npml; j < pad2; j++) {
        for (i=0; i < npml; i++) {
            pad[j][i] = v[n2-1][0];
        }
        for (i=npml; i < pad1-npml; i++) {
            pad[j][i] = v[n2-1][i-npml];
        }
        for (i=pad1-npml; i < pad1; i++) {
            pad[j][i] = v[n2-1][n1-1];
        }
    }

    /* assemble matrix in triplet form */
    count = 0;
    for (j=1; j < pad2-1; j++) {
        for (i=1; i < pad1-1; i++) {
            index = (j-1)*(pad1-2)+(i-1);

            cent = 0.+I*0.;

            /* left */
            neib = (s1[i]/s2[j]+s1[i-1]/s2[j])/(2.*d1*d1);
            cent += -neib;

            if (i != 1) {
                Ti[count] = index;
                Tj[count] = index-1;
                Tx[count] = creal(neib);
                Tz[count] = cimag(neib);

                count++;
            }

            /* right */
            neib = (s1[i]/s2[j]+s1[i+1]/s2[j])/(2.*d1*d1);
            cent += -neib;

            if (i != pad1-2) {
                Ti[count] = index;
                Tj[count] = index+1;
                Tx[count] = creal(neib);
                Tz[count] = cimag(neib);

                count++;
            }

            /* down */
            neib = (s2[j]/s1[i]+s2[j-1]/s1[i])/(2.*d2*d2);
            cent += -neib;

            if (j != 1) {
                Ti[count] = index;
                Tj[count] = index-(pad1-2);
                Tx[count] = creal(neib);
                Tz[count] = cimag(neib);

                count++;
            }

            /* up */
            neib = (s2[j]/s1[i]+s2[j+1]/s1[i])/(2.*d2*d2);
            cent += -neib;

            if (j != pad2-2) {
                Ti[count] = index;
                Tj[count] = index+(pad1-2);
                Tx[count] = creal(neib);
                Tz[count] = cimag(neib);

                count++;
            }

            /* center */
            cent += pow(omega/pad[j][i],2.)/(s1[i]*s2[j]);

            Ti[count] = index;
            Tj[count] = index;
            Tx[count] = creal(cent);
            Tz[count] = cimag(cent);

            count++;
        }
    }
}
Пример #2
0
double cell_mindt( struct Cell *** theCells, struct Sim * theSim, struct GravMass * theGravMasses ){
    int i_m,j_m,k_m;
    double dt_m = 1.e100;//HUGE_VAL;
    double a_m,r_m,dx_m;
    double mag_vel_m;
    int i,j,k;
    for( k=sim_Nghost_min(theSim,Z_DIR) ; k<sim_N(theSim,Z_DIR)-sim_Nghost_max(theSim,Z_DIR) ; ++k ){
        double zm = sim_FacePos(theSim,k-1,Z_DIR);
        double zp = sim_FacePos(theSim,k,Z_DIR);
        double dz = zp-zm;
        for( i=sim_Nghost_min(theSim,R_DIR) ; i<sim_N(theSim,R_DIR)-sim_Nghost_max(theSim,R_DIR) ; ++i ){
            double rm = sim_FacePos(theSim,i-1,R_DIR);
            double rp = sim_FacePos(theSim,i,R_DIR);
            double dr = rp-rm;
            double r = .5*(rp+rm);
            for( j=0 ; j<sim_N_p(theSim,i) ; ++j ){
                int jm = j-1;
                if( j==0 ) jm = sim_N_p(theSim,i)-1;
                double w = .5*(theCells[k][i][j].wiph+theCells[k][i][jm].wiph);
                double dx = dr;
                double rdphi = .5*(rp+rm)*theCells[k][i][j].dphi;
                if( rdphi<dr ) {
                    dx = rdphi;
                }
                if( dx>dz ) {
                    dx = dz;
                }
                double a  = maxvel( theCells[k][i][j].prim , w , r ,theSim);
                double rho = theCells[k][i][j].prim[RHO]; 
                double Pp  = theCells[k][i][j].prim[PPP]; 


                double dt = sim_CFL(theSim)*dx/a;
                if( sim_EXPLICIT_VISCOSITY(theSim)>0.0 ){
                    double nu;
                    if (sim_VISC_CONST(theSim)==1){
                        nu = sim_EXPLICIT_VISCOSITY(theSim);
                    } else{
                        double tiph = theCells[k][i][j].tiph - 0.5*theCells[k][i][j].dphi;
                        if (sim_InitialDataType(theSim)==SHEAR){
                            double HoR = 0.1;
                            //nu = sim_EXPLICIT_VISCOSITY(theSim)*HoR*HoR*pow(fabs((r*cos(tiph))),1.5);
                            nu = sim_EXPLICIT_VISCOSITY(theSim)*sim_GAMMALAW(theSim)*Pp/rho*pow(fabs(r*cos(tiph)),2.0);
                            if (r*cos(tiph)>20.) nu=0.000000001;
                        } else{
                            double M0 = gravMass_M(theGravMasses,0);
                            double M1 = gravMass_M(theGravMasses,1);
                            double dist_bh0 = gravMass_dist(theGravMasses,0,r,tiph,0.);
                            double dist_bh1 = gravMass_dist(theGravMasses,1,r,tiph,0.);
                            double alpha = sim_EXPLICIT_VISCOSITY(theSim);
                            double eps = sim_G_EPS(theSim);
                            //nu = sim_EXPLICIT_VISCOSITY(theSim)*sim_GAMMALAW(theSim)*Pp/rho*pow(r,1.5);
                            nu = alpha*Pp/rho/sqrt(pow(dist_bh0*dist_bh0+eps*eps,-1.5)*M0+pow(dist_bh1*dist_bh1+eps*eps,-1.5)*M1);
                        }
                    }
                    double dt_visc = .25*dx*dx/nu;
                    dt = dt/( 1. + dt/dt_visc );
                }
                if( dt_m > dt ) {
                    dt_m = dt;
                }
            } 
        }
    }
    double dt2;
    MPI_Allreduce( &dt_m , &dt2 , 1 , MPI_DOUBLE , MPI_MIN , sim_comm );
    return( dt2 );

}