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++; } } }
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 ); }