void out_ktab(MeshS *pM, OutputS *pOut) { GridS *pGrid=pM->Domain[0][0].Grid; int i,nx1; FILE *pFile; char fmt[80],*fname,*plev=NULL,*pdom=NULL; char levstr[8],domstr[8]; Real *data=NULL; Real dmin, dmax, xworld; /* Add a white space to the format, setup format for integer zone columns */ if(pOut->dat_fmt == NULL){ sprintf(fmt," %%12.8e"); /* Use a default format */ } else{ sprintf(fmt," %s",pOut->dat_fmt); } /* compute 1D array of data */ data = OutData1(pGrid,pOut,&nx1); if (data == NULL) return; /* slice not in range of Grid */ minmax1(data,nx1,&dmin,&dmax); if((fname = ath_fname(plev,pM->outfilename,0,0,0,0, pOut->id,"tab")) == NULL){ ath_error("[output_tab]: Error constructing filename\n"); } pFile = fopen(fname,"a"); /* open filename */ if (pFile == NULL) { ath_error("[output_tab]: Unable to open tab file %s\n",fname); } /* write data */ if (pOut->num == 0) { for (i=0; i<nx1; i++) { fprintf(pFile,"%12d\t",pGrid->Disp[0]+i); } fprintf(pFile,"\n"); } for (i=0; i<nx1; i++) { fprintf(pFile,fmt,data[i]); fprintf(pFile,"\t"); } fprintf(pFile,"\n"); /* Compute and store global min/max, for output at end of run */ pOut->gmin = MIN(dmin,pOut->gmin); pOut->gmax = MAX(dmax,pOut->gmax); fclose(pFile); free_1d_array(data); /* Free the memory we malloc'd */ }
/*! \fn static void flux_output_func(MeshS *pM, OutputS *pOut) * \brief New output format which outputs y-integrated angular momentum fluxes * Currently can only be used with 1 proc and 1 domain. */ static void flux_output_func(MeshS *pM, OutputS *pOut) { GridS *pG=pM->Domain[0][0].Grid; int nx1,nx2,nx3, ind, i,j,k, ind_i,ind_k; Real lx1, lx2, lx3; PrimS W[7],Ws[7],We[7]; Real x1[7],x2[7],x3[7],xs1[7],xs2[7],xs3[7],xe1[7],xe2[7],xe3[7]; Real dmin, dmax; Real **Fluxx=NULL; Real **FluxH=NULL; Real **FluxNu=NULL; Real **Th=NULL; Real **outCoordsx1=NULL; Real **outCoordsx3=NULL; Real **vx=NULL; Real **vy=NULL; Real **sigvx=NULL; Real **osigx=NULL; Real **davg=NULL; FILE *pfile; char *fname; nx1 = pG->Nx[0]; nx3 = pG->Nx[2]; nx2 = pG->Nx[1]; lx1 = pG->MaxX[0] - pG->MinX[0]; lx2 = pG->MaxX[1] - pG->MinX[1]; lx3 = pG->MaxX[2] - pG->MinX[2]; printf("%d, %d, %d, %g, %g, %g\n",nx1,nx2,nx3,lx1,lx2,lx3); #ifdef MPI_PARALLEL printf("%d, %d, %d, %g, %g, %g \n", myID_Comm_world,nx1,nx3,lx1,lx2,lx3); printf("IND %d: (%d,%d), (%d,%d)\n",myID_Comm_world,pG->is,pG->js,pG->ie,pG->je); #endif Fluxx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (Fluxx == NULL) return; FluxH=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (FluxH == NULL) return; FluxNu=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (FluxNu == NULL) return; Th=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (Th == NULL) return; outCoordsx1=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (outCoordsx1 == NULL) return; outCoordsx3=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (outCoordsx3 == NULL) return; vx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (vx == NULL) return; vy=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (vy == NULL) return; sigvx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (sigvx == NULL) return; osigx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (osigx == NULL) return; davg=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (davg == NULL) return; /* Open file and write header */ if((fname = ath_fname(NULL,pM->outfilename,NULL,NULL,num_digit, pOut->num,pOut->id,"tab")) == NULL){ ath_error("[dump_tab]: Error constructing filename\n"); } if((pfile = fopen(fname,"w")) == NULL){ ath_error("[dump_tab]: Unable to open ppm file %s\n",fname); } free(fname); #ifdef MPI_PARALLEL if(myID_Comm_world == 0) #endif fprintf(pfile,"#t=%12.8e x,FH,Fx,Fnu,Th,vx,vy,davg,sigvx,omsigx \n", pOut->t); /* Compute y-integrated fluxes explicitly. * For the derivatives use a central difference method. * For the integration use a composite trapezoid method. * Both of these make use of the ghost cells for the boundary values. * 1 FluxH = < d * vx1 *vx2 > * 2 Fluxx = < 0.5 * omega * d * x1 * vx1 > * 3 FluxNu = - < nu_iso * d/dx vx2 > * 4 Th = - < d * d/dy phi > * 5 vx = < vx1 > * 6 vy = < vx2 > * 7 davg = < d > * 8 sigvx = < d * vx1 > * 9 osigx = < 0.5 * sig * omega * x1 > * * * x 4 x * 1 0 2 * x 3 x * * The variables are stored up as arrays of primitives W[7]. * W = ( W[k][j][i], W[k][j][i-1], W[k][j][i+1], W[k][j-1][i], * W[k][j+1][i], W[k-1][j][i], W[k+1][j][i] ) * This is needed for the integration and differentiation. * * The background shear is taken out of vy when doing computations. */ for(k=pG->ks; k <=pG->ke; k++) { for(i=pG->is; i<= pG->ie; i++) { ind_i=i-pG->is; ind_k=k-pG->ks; for(ind=0; ind < 7; ind++) { if (ind==0) { cc_pos(pG,i,pG->js,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js][i])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je][i])); } if (ind > 0 && ind < 3) { cc_pos(pG,i+2*ind-3,pG->js,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i+2*ind-3,pG->je,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js][i+2*ind-3])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je][i+2*ind-3])); } if (ind > 2 && ind < 5) { cc_pos(pG,i,pG->js+2*ind-7,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je+2*ind-7,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js+2*ind-7][i])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je+2*ind-7][i])); } if (ind > 4 && ind < 7) { if (pG->MinX[2] == pG->MaxX[2]) { cc_pos(pG,i,pG->js,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js][i])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je][i])); } else { cc_pos(pG,i,pG->js,k+2*ind-11,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je,k+2*ind-11,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k+2*ind-11][pG->js][i])); We[ind] = Cons_to_Prim(&(pG->U[k+2*ind-11][pG->je][i])); } } Ws[ind].V2 = Ws[ind].V2 + qshear*Omega_0*xs1[ind]; We[ind].V2 = We[ind].V2 + qshear*Omega_0*xe1[ind]; /* If using d' instead of d then put in * W[ind] = W[ind]->d - d0; */ } /* Set initial values for the integration */ FluxH[ind_k][ind_i] = 0.5*( Ws[0].d * Ws[0].V1 * Ws[0].V2 + We[0].d * We[0].V1 * We[0].V2 ); Fluxx[ind_k][ind_i] = 0.5*( Ws[0].d * Ws[0].V1 * xs1[0] + We[0].d * We[0].V1 * xe1[0] ); #ifdef VISCOSITY FluxNu[ind_k][ind_i] = 0.5*( Ws[2].V2 - Ws[1].V2 + We[2].V2 - We[1].V2 ); #else FluxNu[ind_k][ind_i] = 0; #endif Th[ind_k][ind_i] = 0.5*( Ws[0].d * dx2PlanetPot(xs1[0],xs2[0],xs3[0]) + We[0].d * dx2PlanetPot(xe1[0],xe2[0],xe3[0]) ); vx[ind_k][ind_i] = 0.5*( Ws[0].V1 + We[0].V1 ); vy[ind_k][ind_i] = 0.5*( Ws[0].V2 + We[0].V2 ); sigvx[ind_k][ind_i] = 0.5*( Ws[0].d * Ws[0].V1 + We[0].d * We[0].V1 ); osigx[ind_k][ind_i] = 0.5*( Ws[0].d * xs1[0] + We[0].d * xe1[0] ); davg[ind_k][ind_i] = 0.5*(Ws[0].d + We[0].d); for(j=(pG->js)+1; j < pG->je; j++) { for(ind=0; ind < 7; ind++) { if (ind==0) { cc_pos(pG,i,j,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j][i])); } if (ind > 0 && ind < 3) { cc_pos(pG,i+2*ind-3,j,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j][i+2*ind-3])); } if (ind > 2 && ind < 5) { cc_pos(pG,i,j+2*ind-7,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j+2*ind-7][i])); } if (ind > 4 && ind < 7) { if (pG->MinX[2] == pG->MaxX[2]) { cc_pos(pG,i,j,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j][i])); } else { cc_pos(pG,i,j,k+2*ind-11,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k+2*ind-11][j][i])); } } W[ind].V2 = W[ind].V2 + qshear*Omega_0*x1[ind]; } FluxH[ind_k][ind_i] += W[0].d * W[0].V1 * W[0].V2; Fluxx[ind_k][ind_i] += W[0].d * W[0].V1 * x1[0]; #ifdef VISCOSITY FluxNu[ind_k][ind_i] += W[0].d * (W[2].V2 - W[1].V1); #endif Th[ind_k][ind_i] += W[0].d * dx2PlanetPot(x1[0],x2[0],x3[0]); vx[ind_k][ind_i] += W[0].V1; vy[ind_k][ind_i] += W[0].V2; sigvx[ind_k][ind_i] += W[0].d * W[0].V1; osigx[ind_k][ind_i] += W[0].d * x1[0]; davg[ind_k][ind_i] += W[0].d; } FluxH[ind_k][ind_i] *= (pG->dx2)/lx2; Fluxx[ind_k][ind_i] *= .5*Omega_0*(pG->dx2)/lx2; #ifdef VISCOSITY FluxNu[ind_k][ind_i] *= -nu_iso*(pG->dx2)/(2*lx2*(pG->dx1)); #endif Th[ind_k][ind_i] *= -1.0*(pG->dx2)/lx2; vx[ind_k][ind_i] *= (pG->dx2)/lx2; vy[ind_k][ind_i] *= (pG->dx2)/lx2; sigvx[ind_k][ind_i] *= (pG->dx2)/lx2; osigx[ind_k][ind_i] *= (0.5*Omega_0*(pG->dx2))/lx2; davg[ind_k][ind_i] *= (pG->dx2)/lx2; outCoordsx1[ind_k][ind_i]=x1[0]; outCoordsx3[ind_k][ind_i]=x3[0]; } } /* Quantities are ready to be written to output file * Format (Not outputting x3 at the moment: * x1 (x3) FluxH Fluxx Fluxnu Th vx vy davg sigvx osigx */ for(k=pG->ks; k<=pG->ke; k++) { for(i=pG->is; i<=pG->ie; i++) { ind_k=k-pG->ks; ind_i=i-pG->is; if (lx3==0) { fprintf(pfile,"%12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e\n", outCoordsx1[ind_k][ind_i],FluxH[ind_k][ind_i], Fluxx[ind_k][ind_i],FluxNu[ind_k][ind_i],Th[ind_k][ind_i], vx[ind_k][ind_i],vy[ind_k][ind_i],davg[ind_k][ind_i],sigvx[ind_k][ind_i], osigx[ind_k][ind_i]); } else { fprintf(pfile,"%12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e\n", outCoordsx1[ind_k][ind_i],outCoordsx3[ind_k][ind_i],FluxH[ind_k][ind_i], Fluxx[ind_k][ind_i],FluxNu[ind_k][ind_i],Th[ind_k][ind_i], vx[ind_k][ind_i],vy[ind_k][ind_i],davg[ind_k][ind_i],sigvx[ind_k][ind_i], osigx[ind_k][ind_i]); } } } fclose(pfile); free_2d_array(Fluxx); free_2d_array(FluxH); free_2d_array(FluxNu); free_2d_array(Th); free_2d_array(outCoordsx1); free_2d_array(outCoordsx3); free_2d_array(vx); free_2d_array(vy); free_2d_array(sigvx); free_2d_array(osigx); free_2d_array(davg); return; }
/*! \fn void compute_l1_error(const char *problem, const MeshS *pM, * const ConsS ***RootSoln, const int errortype) * \brief COMPUTE THE L1-ERRORS IN ALL VARIABLES AT THE CURRENT * (USUALLY THE FINAL) * TIMESTEP USING THE INITIAL SOLUTION. * * THIS MEANS THAT THE SOLUTION MUST * EITHER BE STATIC (STEADY-STATE) OR MUST HAVE COMPLETED A FULL PERIOD OF * ROTATION, ETC. FOR THE ERRORTYPE FLAG, 0 MEANS ABSOLUTE ERROR, AND * 1 MEANS AVERAGE ERROR PER GRID CELL. */ void compute_l1_error(const char *problem, const MeshS *pM, const ConsS ***RootSoln, const int errortype) { DomainS *pD=&(pM->Domain[0][0]); GridS *pG=pM->Domain[0][0].Grid; int i=0,j=0,k=0; #if (NSCALARS > 0) int n; #endif int is,ie,js,je,ks,ke; Real rms_error=0.0; Real dVol,totVol; ConsS error,total_error; FILE *fp; char *fname, fnamestr[256]; int Nx1,Nx2,Nx3; #if defined MPI_PARALLEL double err[8+NSCALARS], tot_err[8+NSCALARS]; int mpi_err; #endif #ifdef CYLINDRICAL Real x1,x2,x3; #endif /* Clear out the total_error struct */ memset(&total_error,0.0,sizeof(ConsS)); if (pG == NULL) return; /* compute L1 error in each variable, and rms total error */ is = pG->is; ie = pG->ie; js = pG->js; je = pG->je; ks = pG->ks; ke = pG->ke; for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { memset(&error,0.0,sizeof(ConsS)); for (i=is; i<=ie; i++) { dVol = 1.0; if (pG->dx1 > 0.0) dVol *= pG->dx1; if (pG->dx2 > 0.0) dVol *= pG->dx2; if (pG->dx3 > 0.0) dVol *= pG->dx3; #ifdef CYLINDRICAL cc_pos(pG,i,j,k,&x1,&x2,&x3); dVol *= x1; #endif /* Sum local L1 error for each grid cell I own */ error.d += dVol*fabs(pG->U[k][j][i].d - RootSoln[k][j][i].d ); error.M1 += dVol*fabs(pG->U[k][j][i].M1 - RootSoln[k][j][i].M1); error.M2 += dVol*fabs(pG->U[k][j][i].M2 - RootSoln[k][j][i].M2); error.M3 += dVol*fabs(pG->U[k][j][i].M3 - RootSoln[k][j][i].M3); #ifdef MHD error.B1c += dVol*fabs(pG->U[k][j][i].B1c - RootSoln[k][j][i].B1c); error.B2c += dVol*fabs(pG->U[k][j][i].B2c - RootSoln[k][j][i].B2c); error.B3c += dVol*fabs(pG->U[k][j][i].B3c - RootSoln[k][j][i].B3c); #endif /* MHD */ #ifndef ISOTHERMAL error.E += dVol*fabs(pG->U[k][j][i].E - RootSoln[k][j][i].E ); #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) error.s[n] += dVol*fabs(pG->U[k][j][i].s[n] - RootSoln[k][j][i].s[n]);; #endif } /* total_error is sum of local L1 error */ total_error.d += error.d; total_error.M1 += error.M1; total_error.M2 += error.M2; total_error.M3 += error.M3; #ifdef MHD total_error.B1c += error.B1c; total_error.B2c += error.B2c; total_error.B3c += error.B3c; #endif /* MHD */ #ifndef ISOTHERMAL total_error.E += error.E; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) total_error.s[n] += error.s[n]; #endif } } #ifdef MPI_PARALLEL /* Now we have to use an All_Reduce to get the total error over all the MPI * grids. Begin by copying the error into the err[] array */ err[0] = total_error.d; err[1] = total_error.M1; err[2] = total_error.M2; err[3] = total_error.M3; #ifdef MHD err[4] = total_error.B1c; err[5] = total_error.B2c; err[6] = total_error.B3c; #endif /* MHD */ #ifndef ISOTHERMAL err[7] = total_error.E; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) err[8+n] = total_error.s[n]; #endif /* Sum up the Computed Error */ mpi_err = MPI_Reduce(err, tot_err, (8+NSCALARS), MPI_DOUBLE, MPI_SUM, 0, pD->Comm_Domain); if(mpi_err) ath_error("[compute_l1_error]: MPI_Reduce call returned error = %d\n", mpi_err); /* If I'm the parent, copy the sum back to the total_error variable */ if(pD->DomNumber == 0){ /* I'm the parent */ total_error.d = tot_err[0]; total_error.M1 = tot_err[1]; total_error.M2 = tot_err[2]; total_error.M3 = tot_err[3]; #ifdef MHD total_error.B1c = tot_err[4]; total_error.B2c = tot_err[5]; total_error.B3c = tot_err[6]; #endif /* MHD */ #ifndef ISOTHERMAL total_error.E = tot_err[7]; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) total_error.s[n] = err[8+n]; #endif } else return; /* The child grids do not do any of the following code */ #endif /* MPI_PARALLEL */ /* Compute total number of grid cells */ Nx1 = pD->Nx[0]; Nx2 = pD->Nx[1]; Nx3 = pD->Nx[2]; totVol = 1.0; if (errortype == 1) { if (pD->MaxX[0] > pD->MinX[0]) totVol *= pD->MaxX[0] - pD->MinX[0]; if (pD->MaxX[1] > pD->MinX[1]) totVol *= pD->MaxX[1] - pD->MinX[1]; if (pD->MaxX[2] > pD->MinX[2]) totVol *= pD->MaxX[2] - pD->MinX[2]; #ifdef CYLINDRICAL totVol *= 0.5*(pD->MinX[0] + pD->MaxX[0]); #endif } /* Compute RMS error over all variables, and print out */ rms_error = SQR(total_error.d) + SQR(total_error.M1) + SQR(total_error.M2) + SQR(total_error.M3); #ifdef MHD rms_error += SQR(total_error.B1c) + SQR(total_error.B2c) + SQR(total_error.B3c); #endif /* MHD */ #ifndef ISOTHERMAL rms_error += SQR(total_error.E); #endif /* ISOTHERMAL */ rms_error = sqrt(rms_error)/totVol; /* Print error to file "BLAH-errors.#.dat" */ sprintf(fnamestr,"%s-errors",problem); fname = ath_fname(NULL,fnamestr,NULL,NULL,1,0,NULL,"dat"); /* The file exists -- reopen the file in append mode */ if((fp=fopen(fname,"r")) != NULL){ if((fp = freopen(fname,"a",fp)) == NULL){ ath_error("[compute_l1_error]: Unable to reopen file.\n"); free(fname); return; } } /* The file does not exist -- open the file in write mode */ else{ if((fp = fopen(fname,"w")) == NULL){ ath_error("[compute_l1_error]: Unable to open file.\n"); free(fname); return; } /* Now write out some header information */ fprintf(fp,"# Nx1 Nx2 Nx3 RMS-Error d M1 M2 M3"); #ifndef ISOTHERMAL fprintf(fp," E"); #endif /* ISOTHERMAL */ #ifdef MHD fprintf(fp," B1c B2c B3c"); #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { fprintf(fp," S[ %d ]",n); } #endif fprintf(fp,"\n#\n"); } fprintf(fp,"%d %d %d %e",Nx1,Nx2,Nx3,rms_error); fprintf(fp," %e %e %e %e", (total_error.d /totVol), (total_error.M1/totVol), (total_error.M2/totVol), (total_error.M3/totVol)); #ifndef ISOTHERMAL fprintf(fp," %e",total_error.E/totVol); #endif /* ISOTHERMAL */ #ifdef MHD fprintf(fp," %e %e %e", (total_error.B1c/totVol), (total_error.B2c/totVol), (total_error.B3c/totVol)); #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { fprintf(fp," %e",total_error.s[n]/totVol); } #endif fprintf(fp,"\n"); fclose(fp); free(fname); return; }
void dump_history(MeshS *pM, OutputS *pOut) { GridS *pG; DomainS *pD; int i,j,k,is,ie,js,je,ks,ke,nl,nd; double dVol, scal[NSCAL + NSCALARS + MAX_USR_H_COUNT], d1; FILE *pfile; char *fname,*plev=NULL,*pdom=NULL,*pdir=NULL,fmt[80]; char levstr[8],domstr[8],dirstr[20]; int n, total_hst_cnt, mhst, myID_Comm_Domain=1; #ifdef MPI_PARALLEL double my_scal[NSCAL + NSCALARS + MAX_USR_H_COUNT]; /* My Volume averages */ int ierr; #endif #ifdef CYLINDRICAL Real x1,x2,x3; #endif #ifdef SPECIAL_RELATIVITY PrimS W; Real g, g2, g_2; Real bx, by, bz, vB, b2, Bmag2; #endif total_hst_cnt = 9 + NSCALARS + usr_hst_cnt; #ifdef ADIABATIC total_hst_cnt++; #endif #ifdef MHD total_hst_cnt += 3; #endif #ifdef SELF_GRAVITY total_hst_cnt += 1; #endif #ifdef CYLINDRICAL total_hst_cnt++; /* for angular momentum */ #endif #ifdef SPECIAL_RELATIVITY total_hst_cnt = 12 + usr_hst_cnt; #ifdef MHD total_hst_cnt += 6; #endif #endif /* Add a white space to the format */ if(pOut->dat_fmt == NULL){ sprintf(fmt," %%14.6e"); /* Use a default format */ } else{ sprintf(fmt," %s",pOut->dat_fmt); } /* store time and dt in first two elements of output vector */ scal[0] = pM->time; scal[1] = pM->dt; /* Loop over all Domains in Mesh, and output Grid data */ for (nl=0; nl<(pM->NLevels); nl++){ for (nd=0; nd<(pM->DomainsPerLevel[nl]); nd++){ if (pM->Domain[nl][nd].Grid != NULL){ //printf("calculating local sum ... %d\n",myID_Comm_world); pG = pM->Domain[nl][nd].Grid; pD = (DomainS*)&(pM->Domain[nl][nd]); is = pG->is, ie = pG->ie; js = pG->js, je = pG->je; ks = pG->ks, ke = pG->ke; for (i=2; i<total_hst_cnt; i++) { scal[i] = 0.0; } /* Compute history variables */ for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { dVol = 1.0; if (pG->dx1 > 0.0) dVol *= pG->dx1; if (pG->dx2 > 0.0) dVol *= pG->dx2; if (pG->dx3 > 0.0) dVol *= pG->dx3; #ifndef SPECIAL_RELATIVITY #ifdef CYLINDRICAL cc_pos(pG,i,j,k,&x1,&x2,&x3); dVol *= x1; #endif mhst = 2; scal[mhst] += dVol*pG->U[k][j][i].d; d1 = 1.0/pG->U[k][j][i].d; #ifndef BAROTROPIC mhst++; scal[mhst] += dVol*pG->U[k][j][i].E; #endif mhst++; scal[mhst] += dVol*pG->U[k][j][i].M1; mhst++; scal[mhst] += dVol*pG->U[k][j][i].M2; mhst++; scal[mhst] += dVol*pG->U[k][j][i].M3; mhst++; scal[mhst] += dVol*0.5*SQR(pG->U[k][j][i].M1)*d1; mhst++; scal[mhst] += dVol*0.5*SQR(pG->U[k][j][i].M2)*d1; mhst++; scal[mhst] += dVol*0.5*SQR(pG->U[k][j][i].M3)*d1; #ifdef MHD mhst++; scal[mhst] += dVol*0.5*SQR(pG->U[k][j][i].B1c); mhst++; scal[mhst] += dVol*0.5*SQR(pG->U[k][j][i].B2c); mhst++; scal[mhst] += dVol*0.5*SQR(pG->U[k][j][i].B3c); #endif #ifdef SELF_GRAVITY mhst++; scal[mhst] += dVol*pG->U[k][j][i].d*pG->Phi[k][j][i]; #endif #if (NSCALARS > 0) for(n=0; n<NSCALARS; n++){ mhst++; scal[mhst] += dVol*pG->U[k][j][i].s[n]; } #endif #ifdef CYLINDRICAL mhst++; scal[mhst] += dVol*(x1*pG->U[k][j][i].M2); #endif #else /* SPECIAL_RELATIVITY */ W = Cons_to_Prim (&(pG->U[k][j][i])); /* calculate gamma */ g = pG->U[k][j][i].d/W.d; g2 = SQR(g); g_2 = 1.0/g2; mhst = 2; scal[mhst] += dVol*pG->U[k][j][i].d; mhst++; scal[mhst] += dVol*pG->U[k][j][i].E; mhst++; scal[mhst] += dVol*pG->U[k][j][i].M1; mhst++; scal[mhst] += dVol*pG->U[k][j][i].M2; mhst++; scal[mhst] += dVol*pG->U[k][j][i].M3; mhst++; scal[mhst] += dVol*SQR(g); mhst++; scal[mhst] += dVol*SQR(g*W.V1); mhst++; scal[mhst] += dVol*SQR(g*W.V2); mhst++; scal[mhst] += dVol*SQR(g*W.V3); mhst++; scal[mhst] += dVol*W.P; #ifdef MHD vB = W.V1*pG->U[k][j][i].B1c + W.V2*W.B2c + W.V3*W.B3c; Bmag2 = SQR(pG->U[k][j][i].B1c) + SQR(W.B2c) + SQR(W.B3c); bx = g*(pG->U[k][j][i].B1c*g_2 + vB*W.V1); by = g*(W.B2c*g_2 + vB*W.V2); bz = g*(W.B3c*g_2 + vB*W.V3); b2 = Bmag2*g_2 + vB*vB; mhst++; scal[mhst] += dVol*(g*vB*g*vB); mhst++; scal[mhst] += dVol*bx*bx; mhst++; scal[mhst] += dVol*by*by; mhst++; scal[mhst] += dVol*bz*bz; mhst++; scal[mhst] += dVol*b2; mhst++; scal[mhst] += dVol*(Bmag2*(1.0 - 0.5*g_2) - SQR(vB) / 2.0); #endif /* MHD */ #endif /* SPECIAL_RELATIVITY */ /* Calculate the user defined history variables */ for(n=0; n<usr_hst_cnt; n++){ mhst++; scal[mhst] += dVol*(*phst_fun[n])(pG, i, j, k); } } } } /* Compute the sum over all Grids in Domain */ //printf("calculating global sum ... %d\n",myID_Comm_world); #ifdef MPI_PARALLEL for(i=2; i<total_hst_cnt; i++){ my_scal[i] = scal[i]; } ierr = MPI_Reduce(&(my_scal[2]), &(scal[2]), (total_hst_cnt - 2), MPI_DOUBLE, MPI_SUM, 0, pD->Comm_Domain); #endif /* Only the parent (rank=0) process computes the average and writes output. * For single-processor jobs, myID_Comm_world is always zero. */ #ifdef MPI_PARALLEL ierr = MPI_Comm_rank(pD->Comm_Domain, &myID_Comm_Domain); #endif if((myID_Comm_Domain==0) || (myID_Comm_world==0)){ /* I'm the parent */ /* Compute volume averages */ // printf("dump history ... %d\n",myID_Comm_world); dVol = pD->MaxX[0] - pD->MinX[0]; #ifdef CYLINDRICAL dVol = 0.5*(SQR(pD->MaxX[0]) - SQR(pD->MinX[0])); #endif if (pD->Nx[1] > 1) dVol *= (pD->MaxX[1] - pD->MinX[1]); if (pD->Nx[2] > 1) dVol *= (pD->MaxX[2] - pD->MinX[2]); for(i=2; i<total_hst_cnt; i++){ scal[i] /= dVol; } /* Create filename and open file. History files are always written in lev# * directories of root process (rank=0 in MPI_COMM_WORLD) */ #ifdef MPI_PARALLEL if (nl>0) { plev = &levstr[0]; sprintf(plev,"lev%d",nl); pdir = &dirstr[0]; sprintf(pdir,"../id0/lev%d",nl); } #else if (nl>0) { plev = &levstr[0]; sprintf(plev,"lev%d",nl); pdir = &dirstr[0]; sprintf(pdir,"lev%d",nl); } #endif if (nd>0) { pdom = &domstr[0]; sprintf(pdom,"dom%d",nd); } fname = ath_fname(pdir,pM->outfilename,plev,pdom,0,0,NULL,"hst"); if(fname == NULL){ ath_perr(-1,"[dump_history]: Unable to create history filename\n"); } if(pOut->num == 0) pfile = fopen(fname,"w"); else pfile = fopen(fname,"a"); if(pfile == NULL){ ath_perr(-1,"[dump_history]: Unable to open the history file\n"); } free(fname); /* Write out column headers, but only for first dump */ mhst = 0; if(pOut->num == 0){ fprintf(pfile, "# Athena history dump for level=%i domain=%i volume=%e\n",nl,nd,dVol); mhst++; fprintf(pfile,"# [%i]=time ",mhst); mhst++; fprintf(pfile," [%i]=dt ",mhst); #ifndef SPECIAL_RELATIVITY mhst++; fprintf(pfile," [%i]=mass ",mhst); #ifdef ADIABATIC mhst++; fprintf(pfile," [%i]=total E ",mhst); #endif mhst++; fprintf(pfile," [%i]=x1 Mom. ",mhst); mhst++; fprintf(pfile," [%i]=x2 Mom. ",mhst); mhst++; fprintf(pfile," [%i]=x3 Mom. ",mhst); mhst++; fprintf(pfile," [%i]=x1-KE ",mhst); mhst++; fprintf(pfile," [%i]=x2-KE ",mhst); mhst++; fprintf(pfile," [%i]=x3-KE ",mhst); #ifdef MHD mhst++; fprintf(pfile," [%i]=x1-ME ",mhst); mhst++; fprintf(pfile," [%i]=x2-ME ",mhst); mhst++; fprintf(pfile," [%i]=x3-ME ",mhst); #endif #ifdef SELF_GRAVITY mhst++; fprintf(pfile," [%i]=grav PE ",mhst); #endif #if (NSCALARS > 0) for(n=0; n<NSCALARS; n++){ mhst++; fprintf(pfile," [%i]=scalar %i",mhst,n); } #endif #ifdef CYLINDRICAL mhst++; fprintf(pfile," [%i]=Ang.Mom.",mhst); #endif #else /* SPECIAL_RELATIVITY */ mhst++; fprintf(pfile," [%i]=mass ",mhst); mhst++; fprintf(pfile," [%i]=total E ",mhst); mhst++; fprintf(pfile," [%i]=x1 Mom. ",mhst); mhst++; fprintf(pfile," [%i]=x2 Mom. ",mhst); mhst++; fprintf(pfile," [%i]=x3 Mom." ,mhst); mhst++; fprintf(pfile," [%i]=Gamma ",mhst); mhst++; fprintf(pfile," [%i]=x1-KE ",mhst); mhst++; fprintf(pfile," [%i]=x2-KE ",mhst); mhst++; fprintf(pfile," [%i]=x3-KE " ,mhst); mhst++; fprintf(pfile," [%i]=Press " ,mhst); #ifdef MHD mhst++; fprintf(pfile," [%i]=x0-ME " ,mhst); mhst++; fprintf(pfile," [%i]=x1-ME " ,mhst); mhst++; fprintf(pfile," [%i]=x2-ME " ,mhst); mhst++; fprintf(pfile," [%i]=x3-ME " ,mhst); mhst++; fprintf(pfile," [%i]=bsq " ,mhst); mhst++; fprintf(pfile," [%i]=T^00_EM" ,mhst); #endif #endif /* SPECIAL_RELATIVITY */ for(n=0; n<usr_hst_cnt; n++){ mhst++; fprintf(pfile," [%i]=%s",mhst,usr_label[n]); } fprintf(pfile,"\n#\n"); } /* Write out data, and close file */ for (i=0; i<total_hst_cnt; i++) { //printf("dump history data %d ... %d\n",i,myID_Comm_world); fprintf(pfile,fmt,scal[i]); } fprintf(pfile,"\n"); fclose(pfile); } } } } return; }
static void dump_vtksub(MeshS *pM, OutputS *pOut) { GridS *pGrid; FILE *pfile; char *fname, *plev = NULL, *pdom = NULL; char levstr[8], domstr[8]; /* Upper and Lower bounds on i,j,k for data dump */ int i, j, k, il, iu, jl, ju, kl, ku; int big_end = ath_big_endian(); int ndata0; float *data; /* points to 3*ndata0 allocated floats */ double x1m, x2m, x3m, x1M, x1, x2, x3, dR; /* Loop over all Domains in Mesh, and output Grid data */ pGrid = pM->Domain[0][0].Grid; il = pGrid->is, iu = pGrid->ie; jl = pGrid->js, ju = pGrid->je; kl = pGrid->ks, ku = pGrid->ke; x1m = pGrid->MinX[0]; x2m = pGrid->MinX[1]; x3m = pGrid->MinX[2]; x1M = pGrid->MaxX[0]; dR = pGrid->dx1; // Exclude tiles not in the subvolume if ((x1M <= 1.6) || (x1m >= 2.4)) { return; } il = -1; for (i = pGrid->is; i <= pGrid->ie; i++) { cc_pos(pGrid, i, jl, kl, &x1, &x2, &x3); // Get first index in range if ((x1 + 0.5 * dR >= 1.6) && (il < 0)) { il = i; x1m = x1 - 0.5 * dR; } if (x1 - 0.5 * dR <= 2.4) { iu = i; } } ndata0 = iu - il + 1; /* construct filename, open file */ if ((fname = ath_fname(plev, pM->outfilename, plev, pdom, num_digit, pOut->num, "sub", "vtk")) == NULL) { ath_error("[dump_vtk]: Error constructing filename\n"); } if ((pfile = fopen(fname, "w")) == NULL) { ath_error("[dump_vtk]: Unable to open vtk dump file\n"); return; } /* Allocate memory for temporary array of floats */ if ((data = (float *) malloc(3 * ndata0 * sizeof(float))) == NULL) { ath_error("[dump_vtk]: malloc failed for temporary array\n"); return; } /* There are five basic parts to the VTK "legacy" file format. */ /* 1. Write file version and identifier */ fprintf(pfile, "# vtk DataFile Version 2.0\n"); /* 2. Header */ fprintf(pfile, "Subvolume variables at time= %e, level= %i, domain= %i\n", pGrid->time, 0, 0); /* 3. File format */ fprintf(pfile, "BINARY\n"); /* 4. Dataset structure */ /* Set the Grid origin */ fprintf(pfile, "DATASET STRUCTURED_POINTS\n"); if (pGrid->Nx[1] == 1) { fprintf(pfile, "DIMENSIONS %d %d %d\n", iu - il + 2, 1, 1); } else { if (pGrid->Nx[2] == 1) { fprintf(pfile, "DIMENSIONS %d %d %d\n", iu - il + 2, ju - jl + 2, 1); } else { fprintf(pfile, "DIMENSIONS %d %d %d\n", iu - il + 2, ju - jl + 2, ku - kl + 2); } } fprintf(pfile, "ORIGIN %e %e %e \n", x1m, x2m, x3m); fprintf(pfile, "SPACING %e %e %e \n", pGrid->dx1, pGrid->dx2, pGrid->dx3); /* 5. Data */ fprintf(pfile, "CELL_DATA %d \n", (iu - il + 1) * (ju - jl + 1) * (ku - kl + 1)); /* Write density */ fprintf(pfile, "SCALARS density float\n"); fprintf(pfile, "LOOKUP_TABLE default\n"); for (k = kl; k <= ku; k++) { for (j = jl; j <= ju; j++) { for (i = il; i <= iu; i++) { data[i - il] = (float) pGrid->U[k][j][i].d; } if (!big_end) ath_bswap(data, sizeof(float), iu - il + 1); fwrite(data, sizeof(float), (size_t) ndata0, pfile); } } /* Write momentum or velocity */ fprintf(pfile, "\nVECTORS momentum float\n"); for (k = kl; k <= ku; k++) { for (j = jl; j <= ju; j++) { for (i = il; i <= iu; i++) { data[3 * (i - il)] = (float) pGrid->U[k][j][i].M1; data[3 * (i - il) + 1] = (float) pGrid->U[k][j][i].M2; data[3 * (i - il) + 2] = (float) pGrid->U[k][j][i].M3; } if (!big_end) ath_bswap(data, sizeof(float), 3 * (iu - il + 1)); fwrite(data, sizeof(float), (size_t) (3 * ndata0), pfile); } } /* Write cell centered B */ #ifdef MHD fprintf(pfile, "\nVECTORS cell_centered_B float\n"); for (k = kl; k <= ku; k++) { for (j = jl; j <= ju; j++) { for (i = il; i <= iu; i++) { data[3 * (i - il)] = (float) pGrid->U[k][j][i].B1c; data[3 * (i - il) + 1] = (float) pGrid->U[k][j][i].B2c; data[3 * (i - il) + 2] = (float) pGrid->U[k][j][i].B3c; } if (!big_end) ath_bswap(data, sizeof(float), 3 * (iu - il + 1)); fwrite(data, sizeof(float), (size_t) (3 * ndata0), pfile); } } #endif /* close file and free memory */ fclose(pfile); free(data); return; }
void dump_binary(MeshS *pM, OutputS *pOut) { GridS *pGrid; PrimS ***W; FILE *p_binfile; char *fname,*plev=NULL,*pdom=NULL; char levstr[8],domstr[8]; int n,ndata[7]; /* Upper and Lower bounds on i,j,k for data dump */ int i,j,k,il,iu,jl,ju,kl,ku,nl,nd; Real dat[2],*datax,*datay,*dataz; Real *pData,x1,x2,x3; int coordsys = -1; /* Loop over all Domains in Mesh, and output Grid data */ for (nl=0; nl<(pM->NLevels); nl++){ for (nd=0; nd<(pM->DomainsPerLevel[nl]); nd++){ if (pM->Domain[nl][nd].Grid != NULL){ /* write files if domain and level match input, or are not specified (-1) */ if ((pOut->nlevel == -1 || pOut->nlevel == nl) && (pOut->ndomain == -1 || pOut->ndomain == nd)){ pGrid = pM->Domain[nl][nd].Grid; il = pGrid->is, iu = pGrid->ie; jl = pGrid->js, ju = pGrid->je; kl = pGrid->ks, ku = pGrid->ke; #ifdef WRITE_GHOST_CELLS il = pGrid->is - nghost; iu = pGrid->ie + nghost; if(pGrid->Nx[1] > 1){ jl = pGrid->js - nghost; ju = pGrid->je + nghost; } if(pGrid->Nx[2] > 1){ kl = pGrid->ks - nghost; ku = pGrid->ke + nghost; } #endif /* WRITE_GHOST_CELLS */ ndata[0] = iu-il+1; ndata[1] = ju-jl+1; ndata[2] = ku-kl+1; /* calculate primitive variables, if needed */ if(strcmp(pOut->out,"prim") == 0) { if((W = (PrimS***) calloc_3d_array(ndata[2],ndata[1],ndata[0],sizeof(PrimS))) == NULL) ath_error("[dump_bin]: failed to allocate Prim array\n"); for (k=kl; k<=ku; k++) { for (j=jl; j<=ju; j++) { for (i=il; i<=iu; i++) { W[k-kl][j-jl][i-il] = Cons_to_Prim(&(pGrid->U[k][j][i])); }}} } /* construct filename, open file */ if (nl>0) { plev = &levstr[0]; sprintf(plev,"lev%d",nl); } if (nd>0) { pdom = &domstr[0]; sprintf(pdom,"dom%d",nd); } if((fname = ath_fname(plev,pM->outfilename,plev,pdom,num_digit, pOut->num,NULL,"bin")) == NULL){ ath_error("[dump_binary]: Error constructing filename\n"); } if((p_binfile = fopen(fname,"wb")) == NULL){ ath_error("[dump_binary]: Unable to open binary dump file\n"); return; } free(fname); /* Write the coordinate system information */ #if defined CARTESIAN coordsys = -1; #elif defined CYLINDRICAL coordsys = -2; #elif defined SPHERICAL coordsys = -3; #endif fwrite(&coordsys,sizeof(int),1,p_binfile); /* Write number of zones and variables */ ndata[3] = NVAR; ndata[4] = NSCALARS; #ifdef SELF_GRAVITY ndata[5] = 1; #else ndata[5] = 0; #endif #ifdef PARTICLES ndata[6] = 1; #else ndata[6] = 0; #endif fwrite(ndata,sizeof(int),7,p_binfile); /* Write (gamma-1) and isothermal sound speed */ #ifdef ISOTHERMAL dat[0] = (Real)0.0; dat[1] = (Real)Iso_csound; #elif defined ADIABATIC dat[0] = (Real)Gamma_1 ; dat[1] = (Real)0.0; #else dat[0] = dat[1] = 0.0; /* Anything better to put here? */ #endif fwrite(dat,sizeof(Real),2,p_binfile); /* Write time, dt */ dat[0] = (Real)pGrid->time; dat[1] = (Real)pGrid->dt; fwrite(dat,sizeof(Real),2,p_binfile); /* Allocate Memory */ if((datax = (Real *)malloc(ndata[0]*sizeof(Real))) == NULL){ ath_error("[dump_binary]: malloc failed for temporary array\n"); return; } if((datay = (Real *)malloc(ndata[1]*sizeof(Real))) == NULL){ ath_error("[dump_binary]: malloc failed for temporary array\n"); return; } if((dataz = (Real *)malloc(ndata[2]*sizeof(Real))) == NULL){ ath_error("[dump_binary]: malloc failed for temporary array\n"); return; } /* compute x,y,z coordinates of cell centers, and write out */ for (i=il; i<=iu; i++) { cc_pos(pGrid,i,jl,kl,&x1,&x2,&x3); pData = ((Real *) &(x1)); datax[i-il] = (Real)(*pData); } fwrite(datax,sizeof(Real),(size_t)ndata[0],p_binfile); for (j=jl; j<=ju; j++) { cc_pos(pGrid,il,j,kl,&x1,&x2,&x3); pData = ((Real *) &(x2)); datay[j-jl] = (Real)(*pData); } fwrite(datay,sizeof(Real),(size_t)ndata[1],p_binfile); for (k=kl; k<=ku; k++) { cc_pos(pGrid,il,jl,k,&x1,&x2,&x3); pData = ((Real *) &(x3)); dataz[k-kl] = (Real)(*pData); } fwrite(dataz,sizeof(Real),(size_t)ndata[2],p_binfile); /* Write cell-centered data (either conserved or primitives) */ for (n=0;n<NVAR; n++) { for (k=0; k<ndata[2]; k++) { for (j=0; j<ndata[1]; j++) { for (i=0; i<ndata[0]; i++) { if (strcmp(pOut->out,"cons") == 0){ pData = ((Real*)&(pGrid->U[k+kl][j+jl][i+il])) + n; } else if(strcmp(pOut->out,"prim") == 0) { pData = ((Real*)&(W[k][j][i])) + n; } datax[i] = (Real)(*pData); } fwrite(datax,sizeof(Real),(size_t)ndata[0],p_binfile); }} } #ifdef SELF_GRAVITY for (k=0; k<ndata[2]; k++) { for (j=0; j<ndata[1]; j++) { for (i=0; i<ndata[0]; i++) { pData = &(pGrid->Phi[k+kl][j+jl][i+il]); datax[i] = (Real)(*pData); } fwrite(datax,sizeof(Real),(size_t)ndata[0],p_binfile); }} #endif #ifdef PARTICLES if (pOut->out_pargrid) { for (k=0; k<ndata[2]; k++) { for (j=0; j<ndata[1]; j++) { for (i=0; i<ndata[0]; i++) { datax[i] = pGrid->Coup[k+kl][j+jl][i+il].grid_d; } fwrite(datax,sizeof(Real),(size_t)ndata[0],p_binfile); }} for (k=0; k<ndata[2]; k++) { for (j=0; j<ndata[1]; j++) { for (i=0; i<ndata[0]; i++) { datax[i] = pGrid->Coup[k+kl][j+jl][i+il].grid_v1; } fwrite(datax,sizeof(Real),(size_t)ndata[0],p_binfile); }} for (k=0; k<ndata[2]; k++) { for (j=0; j<ndata[1]; j++) { for (i=0; i<ndata[0]; i++) { datax[i] = pGrid->Coup[k+kl][j+jl][i+il].grid_v2; } fwrite(datax,sizeof(Real),(size_t)ndata[0],p_binfile); }} for (k=0; k<ndata[2]; k++) { for (j=0; j<ndata[1]; j++) { for (i=0; i<ndata[0]; i++) { datax[i] = pGrid->Coup[k+kl][j+jl][i+il].grid_v3; } fwrite(datax,sizeof(Real),(size_t)ndata[0],p_binfile); }} } #endif /* close file and free memory */ fclose(p_binfile); free(datax); free(datay); free(dataz); if(strcmp(pOut->out,"prim") == 0) free_3d_array(W); }} } } }
void Userwork_after_loop(Grid *pGrid, Domain *pDomain) { int i=0,j=0,k=0; int is,ie,js,je,ks,ke,n,wavedir,nwave,samp; Real x1,x2,x3,x1max,x1min,x2max,x2min,amp,vflow,kw; Real time,omega,SolGasd,SolLagd; char *fname; is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; /* Read initial conditions */ amp = par_getd("problem","amp"); wavedir = par_geti("problem","wavedir"); vflow = par_getd("problem","vflow"); nwave = par_geti("problem","nwave"); samp = par_geti("problem","sample"); x1min = par_getd("grid","x1min"); x1max = par_getd("grid","x1max"); x2min = par_getd("grid","x2min"); x2max = par_getd("grid","x2max"); /* calculate dispersion relation */ if (wavedir == 1) kw = 2.0*(PI)*nwave/(x1max-x1min); else if (wavedir == 2) kw = 2.0*(PI)*nwave/(x2max-x2min); time = pGrid->time; omega = kw*Iso_csound; /* Bin particles to grid */ particle_to_grid(pGrid, pDomain, property_all); /* Print error to file "Par_LinWave-errors.#.dat", where #=wavedir */ fname = ath_fname(NULL,"Par_LinWave1d-errors",1,wavedir,NULL,"dat"); /* Open output file in write mode */ FILE *fid = fopen(fname,"w"); /* Calculate the error and output */ switch(wavedir){ case 1: fprintf(fid, "%f %d\n", time, ie-is+1); for (i=is; i<=ie; i++) { /* calculate analytic solution */ cc_pos(pGrid,i,js,ks,&x1,&x2,&x3); SolGasd = 1.0+amp*sin(kw*(x1-vflow*time)-omega*time); if (samp == 1) SolLagd = SolGasd; else SolLagd = SolGasd-amp*sin(kw*(x1-vflow*time)); /* output */ fprintf(fid,"%f ",x1); fprintf(fid,"%e %e %e ",pGrid->U[ks][js][i].d-1.0, SolGasd-1.0,pGrid->U[ks][js][i].d-SolGasd); fprintf(fid,"%e %e %e ",pG->Coup[ks][js][i].grid_d-1.0, SolLagd-1.0,pG->Coup[ks][js][i].grid_d-SolLagd); #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) fprintf(fid,"%e %e ",pGrid->U[ks][js][i].s[n]-1.0, pGrid->U[ks][js][i].s[n]-SolLagd); #endif fprintf(fid,"\n"); } break; case 2: fprintf(fid, "%f %d\n", time, je-js+1); for (j=js; j<=je; j++) { /* calculate analytic solution */ cc_pos(pGrid,is,j,ks,&x1,&x2,&x3); SolGasd = 1.0+amp*sin(kw*(x2-vflow*time)-omega*time); if (samp == 1) SolLagd = SolGasd; else SolLagd = SolGasd-amp*sin(kw*(x2-vflow*time)); /* output */ fprintf(fid,"%f ",x2); fprintf(fid,"%e %e %e ",pGrid->U[ks][j][is].d-1.0, SolGasd-1.0,pGrid->U[ks][j][is].d-SolGasd); fprintf(fid,"%e %e %e ",pG->Coup[ks][j][is].grid_d-1.0, SolLagd-1.0,pG->Coup[ks][j][is].grid_d-SolLagd); #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) fprintf(fid,"%e %e ",pGrid->U[ks][j][is].s[n]-1.0, pGrid->U[ks][j][is].s[n]-SolLagd); #endif fprintf(fid,"\n"); } break; } fclose(fid); return; }
void dump_tab_cons(MeshS *pM, OutputS *pOut) { GridS *pG; int nl,nd,i,j,k,il,iu,jl,ju,kl,ku; FILE *pfile; char *fname,*plev=NULL,*pdom=NULL; char levstr[8],domstr[8]; Real x1,x2,x3; char zone_fmt[20], fmt[80]; int col_cnt, nmax; #if (NSCALARS > 0) int n; #endif /* Add a white space to the format, setup format for integer zone columns */ if(pOut->dat_fmt == NULL){ sprintf(fmt," %%12.8e"); /* Use a default format */ } else{ sprintf(fmt," %s",pOut->dat_fmt); } /* Loop over all Domains in Mesh, and output Grid data */ for (nl=0; nl<(pM->NLevels); nl++){ for (nd=0; nd<(pM->DomainsPerLevel[nl]); nd++){ if (pM->Domain[nl][nd].Grid != NULL){ /* write files if domain and level match input, or are not specified (-1) */ if ((pOut->nlevel == -1 || pOut->nlevel == nl) && (pOut->ndomain == -1 || pOut->ndomain == nd)){ pG = pM->Domain[nl][nd].Grid; col_cnt = 1; /* construct output filename. */ if (nl>0) { plev = &levstr[0]; sprintf(plev,"lev%d",nl); } if (nd>0) { pdom = &domstr[0]; sprintf(pdom,"dom%d",nd); } if((fname = ath_fname(plev,pM->outfilename,plev,pdom,num_digit, pOut->num,NULL,"tab")) == NULL){ ath_error("[dump_tab]: Error constructing filename\n"); } /* open output file */ if((pfile = fopen(fname,"w")) == NULL){ ath_error("[dump_tab]: Unable to open ppm file %s\n",fname); } free(fname); /* Upper and Lower bounds on i,j,k for data dump */ il = pG->is; iu = pG->ie; jl = pG->js; ju = pG->je; kl = pG->ks; ku = pG->ke; nmax = pG->Nx[0] > pG->Nx[1] ? pG->Nx[0] : pG->Nx[1]; nmax = (pG->Nx[2] > nmax ? pG->Nx[2] : nmax); #ifdef WRITE_GHOST_CELLS iu = pG->ie + nghost; il = pG->is - nghost; if(pG->Nx[1] > 1) { ju = pG->je + nghost; jl = pG->js - nghost; } if(pG->Nx[2] > 1) { ku = pG->ke + nghost; kl = pG->ks - nghost; } nmax += 2*nghost; #endif sprintf(zone_fmt,"%%%dd", (int)(2+log10((double)(nmax)))); /* Write out some header information */ if (pG->Nx[0] > 1) { fprintf(pfile,"# Nx1 = %d\n",iu-il+1); fprintf(pfile,"# x1-size = %g\n",(iu-il+1)*pG->dx1); } if (pG->Nx[1] > 1) { fprintf(pfile,"# Nx2 = %d\n",ju-jl+1); fprintf(pfile,"# x2-size = %g\n",(ju-jl+1)*pG->dx2); } if (pG->Nx[2] > 1) { fprintf(pfile,"# Nx3 = %d\n",ku-kl+1); fprintf(pfile,"# x3-size = %g\n",(ku-kl+1)*pG->dx3); } fprintf(pfile,"# CONSERVED vars at Time= %g, level= %i, domain= %i\n", pM->time,nl,nd); /* write out i,j,k column headers. Note column number is embedded in header */ fprintf(pfile,"# [%d]=i-zone",col_cnt); col_cnt++; if (pG->Nx[1] > 2) { fprintf(pfile," [%d]=j-zone",col_cnt); col_cnt++; } if (pG->Nx[2] > 3) { fprintf(pfile," [%d]=k-zone",col_cnt); col_cnt++; } /* write out x1,x2,x3 column headers. */ if (pG->Nx[0] > 1) { fprintf(pfile," [%d]=x1",col_cnt); col_cnt++; } if (pG->Nx[1] > 2) { fprintf(pfile," [%d]=x2",col_cnt); col_cnt++; } if (pG->Nx[2] > 3) { fprintf(pfile," [%d]=x3",col_cnt); col_cnt++; } /* write out d,M1,M2,M3 column headers */ fprintf(pfile," [%d]=d",col_cnt); col_cnt++; fprintf(pfile," [%d]=M1",col_cnt); col_cnt++; fprintf(pfile," [%d]=M2",col_cnt); col_cnt++; fprintf(pfile," [%d]=M3",col_cnt); col_cnt++; /* write out E column header, if not barotropic */ #ifndef BAROTROPIC fprintf(pfile," [%d]=E",col_cnt); col_cnt++; #endif /* BAROTROPIC */ /* write out magnetic field component column headers, if mhd */ #ifdef MHD fprintf(pfile," [%d]=B1c",col_cnt); col_cnt++; fprintf(pfile," [%d]=B2c",col_cnt); col_cnt++; fprintf(pfile," [%d]=B3c",col_cnt); col_cnt++; #endif /* MHD */ /* write out column header for gravitational potential (self-gravity) */ #ifdef SELF_GRAVITY fprintf(pfile," [%d]=Phi",col_cnt); col_cnt++; #endif /* write out column headers for particles */ #ifdef PARTICLES if (pOut->out_pargrid) { fprintf(pfile," [%d]=dpar",col_cnt); col_cnt++; fprintf(pfile," [%d]=M1par",col_cnt); col_cnt++; fprintf(pfile," [%d]=M2par",col_cnt); col_cnt++; fprintf(pfile," [%d]=M3par",col_cnt); col_cnt++; } #endif /* write out column headers for passive scalars */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { fprintf(pfile," [%d]=s%d",col_cnt,n); col_cnt++; } #endif fprintf(pfile,"\n"); /* Write out data */ for(k=kl; k<=ku; k++){ for(j=jl; j<=ju; j++){ for(i=il; i<=iu; i++){ cc_pos(pG,i,j,k,&x1,&x2,&x3); if (pG->Nx[0] > 1) fprintf(pfile,zone_fmt,i); if (pG->Nx[1] > 1) fprintf(pfile,zone_fmt,j); if (pG->Nx[2] > 1) fprintf(pfile,zone_fmt,k); if (pG->Nx[0] > 1) fprintf(pfile,fmt,x1); if (pG->Nx[1] > 1) fprintf(pfile,fmt,x2); if (pG->Nx[2] > 1) fprintf(pfile,fmt,x3); /* Dump all variables */ fprintf(pfile,fmt,pG->U[k][j][i].d); fprintf(pfile,fmt,pG->U[k][j][i].M1); fprintf(pfile,fmt,pG->U[k][j][i].M2); fprintf(pfile,fmt,pG->U[k][j][i].M3); #ifndef BAROTROPIC fprintf(pfile,fmt,pG->U[k][j][i].E); #endif /* BAROTROPIC */ #ifdef MHD fprintf(pfile,fmt,pG->U[k][j][i].B1c); fprintf(pfile,fmt,pG->U[k][j][i].B2c); fprintf(pfile,fmt,pG->U[k][j][i].B3c); #endif #ifdef SELF_GRAVITY fprintf(pfile,fmt,pG->Phi[k][j][i]); #endif #ifdef PARTICLES if (pOut->out_pargrid) { fprintf(pfile,fmt,pG->Coup[k][j][i].grid_d); fprintf(pfile,fmt,pG->Coup[k][j][i].grid_v1); fprintf(pfile,fmt,pG->Coup[k][j][i].grid_v2); fprintf(pfile,fmt,pG->Coup[k][j][i].grid_v3); } #endif #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) fprintf(pfile,fmt,pG->U[k][j][i].s[n]); #endif fprintf(pfile,"\n"); } } } fclose(pfile); }} } /* end loop over domains */ } /* end loop over levels */ return; }
void output_pgm(MeshS *pM, OutputS *pOut) { GridS *pGrid; FILE *pfile; char *fname,*plev=NULL,*pdom=NULL; char levstr[8],domstr[8]; int nl,nd,nx1,nx2,gray,i,j; Real **data, dmin, dmax, max_min, sfact; /* check output data is 2D (output must be a 2D slice for 3D runs) */ if (pOut->ndim != 2) { ath_error("[output_pgm]: Output must be a 2D slice\n"); return; } /* Loop over all Domains in Mesh, and output Grid data */ for (nl=0; nl<(pM->NLevels); nl++){ for (nd=0; nd<(pM->DomainsPerLevel[nl]); nd++){ if (pM->Domain[nl][nd].Grid != NULL){ /* write files if domain and level match input, or are not specified (-1) */ if ((pOut->nlevel == -1 || pOut->nlevel == nl) && (pOut->ndomain == -1 || pOut->ndomain == nd)){ pGrid = pM->Domain[nl][nd].Grid; /* Extract 2D data from 3D data, Can either be slice or average along axis, * depending on range of ix1,ix2,ix3 in <ouput> block. If OutData2 returns * NULL pointer, then slice is outside range of data in pGrid, so skip */ data = OutData2(pGrid,pOut,&nx1,&nx2); if (data != NULL) { /* construct output filename. pOut->id will either be name of variable, * if 'id=...' was included in <ouput> block, or 'outN' where N is number of * <output> block. */ if (nl>0) { plev = &levstr[0]; sprintf(plev,"lev%d",nl); } if (nd>0) { pdom = &domstr[0]; sprintf(pdom,"dom%d",nd); } if((fname = ath_fname(plev,pM->outfilename,plev,pdom,num_digit, pOut->num,pOut->id,"pgm")) == NULL){ ath_error("[output_pgm]: Error constructing filename\n"); } /* open output file */ if((pfile = fopen(fname,"w")) == NULL){ ath_error("[output_pgm]: Unable to open pgm file %s\n",fname); return; } free(fname); fprintf(pfile,"P5\n%d %d\n255\n",nx1,nx2); /* Store the global min / max, for output at end of run */ minmax2(data,nx2,nx1,&dmin,&dmax); pOut->gmin = MIN(dmin,pOut->gmin); pOut->gmax = MAX(dmax,pOut->gmax); /* Override auto-scale? */ if (pOut->sdmin != 0) dmin = pOut->dmin; if (pOut->sdmax != 0) dmax = pOut->dmax; max_min = (dmax - dmin)*(1.0 + FLT_EPSILON); /* map the data which satisfies [min <= data <= max] to the range * [0.0 , 256.0] -- Not inclusive of 256 */ if(max_min > 0.0) { sfact = 256.0/max_min; for (j=nx2-1; j>=0; j--) { for (i=0; i<nx1; i++) { /* Map the data to an 8 bit int, i.e. 0 -> 255 */ gray = (int)(sfact*(data[j][i] - dmin)); /* Out of bounds data is mapped to the min or max integer value */ gray = gray > 0 ? gray : 0; gray = gray < 255 ? gray : 255; fputc(gray,pfile); } } /* else, if max=min set image to constant */ } else { gray = 0; for (j=0; j<nx2; j++) { for (i=0; i<nx1; i++) { fputc(gray,pfile); } } } /* Close the file, free memory */ fclose(pfile); free_2d_array(data); } }} } } }