/*@C PetscBinaryRead - Reads from a binary file. Not Collective Input Parameters: + fd - the file descriptor . num - the maximum number of items to read - type - the type of items to read (PETSC_INT, PETSC_REAL, PETSC_SCALAR, etc.) Output Parameters: + data - the buffer - count - the number of items read, optional Level: developer Notes: If count is not provided and the number of items read is less than the maximum number of items to read, then this routine errors. PetscBinaryRead() uses byte swapping to work on all machines; the files are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers are converted to the small-endian format when they are read in from the file. When PETSc is ./configure with --with-64bit-indices the integers are written to the file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices is used. Concepts: files^reading binary Concepts: binary files^reading .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() @*/ PetscErrorCode PetscBinaryRead(int fd,void *data,PetscInt num,PetscInt *count,PetscDataType type) { size_t typesize, m = (size_t) num, n = 0, maxblock = 65536; char *p = (char*)data; #if defined(PETSC_USE_REAL___FLOAT128) PetscBool readdouble = PETSC_FALSE; double *pdouble; #endif void *ptmp = data; char *fname = NULL; PetscErrorCode ierr; PetscFunctionBegin; if (count) *count = 0; if (num < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to read a negative amount of data %D",num); if (!num) PetscFunctionReturn(0); if (type == PETSC_FUNCTION) { m = 64; type = PETSC_CHAR; fname = (char*)malloc(m*sizeof(char)); p = (char*)fname; ptmp = (void*)fname; if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); } if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m); ierr = PetscDataTypeGetSize(type,&typesize);CHKERRQ(ierr); #if defined(PETSC_USE_REAL___FLOAT128) ierr = PetscOptionsGetBool(NULL,NULL,"-binary_read_double",&readdouble,NULL);CHKERRQ(ierr); /* If using __float128 precision we still read in doubles from file */ if ((type == PETSC_REAL || type == PETSC_COMPLEX) && readdouble) { PetscInt cnt = num * ((type == PETSC_REAL) ? 1 : 2); ierr = PetscMalloc1(cnt,&pdouble);CHKERRQ(ierr); p = (char*)pdouble; typesize /= 2; } #endif m *= typesize; while (m) { size_t len = (m < maxblock) ? m : maxblock; int ret = (int)read(fd,p,len); if (ret < 0 && errno == EINTR) continue; if (!ret && len > 0) break; /* Proxy for EOF */ if (ret < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno); m -= ret; p += ret; n += ret; } if (m && !count) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file"); num = (PetscInt)(n/typesize); /* Should we require `n % typesize == 0` ? */ if (count) *count = num; /* TODO: This is most likely wrong for PETSC_BIT_LOGICAL */ #if defined(PETSC_USE_REAL___FLOAT128) if ((type == PETSC_REAL || type == PETSC_COMPLEX) && readdouble) { PetscInt i, cnt = num * ((type == PETSC_REAL) ? 1 : 2); PetscReal *preal = (PetscReal*)data; if (!PetscBinaryBigEndian()) {ierr = PetscByteSwapDouble(pdouble,cnt);CHKERRQ(ierr);} for (i=0; i<cnt; i++) preal[i] = pdouble[i]; ierr = PetscFree(pdouble);CHKERRQ(ierr); PetscFunctionReturn(0); } #endif if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(ptmp,type,num);CHKERRQ(ierr);} if (type == PETSC_FUNCTION) { #if defined(PETSC_SERIALIZE_FUNCTIONS) ierr = PetscDLSym(NULL,fname,(void**)data);CHKERRQ(ierr); #else *(void**)data = NULL; #endif free(fname); } PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U; /* solution will be stored here */ Mat A; /* Jacobian matrix */ PetscErrorCode ierr; PetscMPIInt size; PetscInt n = 3; AppCtx ctx; PetscScalar *u; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatGetVecs(A,&U,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Reaction options","");CHKERRQ(ierr); { ctx.k = .9; ierr = PetscOptionsScalar("-k","Reaction coefficient","",ctx.k,&ctx.k,NULL);CHKERRQ(ierr); ierr = VecDuplicate(U,&ctx.initialsolution);CHKERRQ(ierr); ierr = VecGetArray(ctx.initialsolution,&u);CHKERRQ(ierr); u[0] = 1; u[1] = .7; u[2] = 0; ierr = VecRestoreArray(ctx.initialsolution,&u);CHKERRQ(ierr); ierr = PetscOptionsVec("-initial","Initial values","",ctx.initialsolution,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,(TSIFunction) IFunction,&ctx);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,(TSIJacobian)IJacobian,&ctx);CHKERRQ(ierr); ierr = TSSetSolutionFunction(ts,(TSSolutionFunction)Solution,&ctx);CHKERRQ(ierr); { DM dm; void *ptr; ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = PetscDLSym(NULL,"IFunctionView",&ptr);CHKERRQ(ierr); ierr = PetscDLSym(NULL,"IFunctionLoad",&ptr);CHKERRQ(ierr); ierr = DMTSSetIFunctionSerialize(dm,(PetscErrorCode (*)(void*,PetscViewer))IFunctionView,(PetscErrorCode (*)(void**,PetscViewer))IFunctionLoad);CHKERRQ(ierr); ierr = DMTSSetIJacobianSerialize(dm,(PetscErrorCode (*)(void*,PetscViewer))IFunctionView,(PetscErrorCode (*)(void**,PetscViewer))IFunctionLoad);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = Solution(ts,0,U,&ctx);CHKERRQ(ierr); ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetDuration(ts,1000,20.0);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.001);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,U);CHKERRQ(ierr); ierr = TSView(ts,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&ctx.initialsolution);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
/*@ PetscBinaryRead - Reads from a binary file. Not Collective Input Parameters: + fd - the file . n - the number of items to read - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) Output Parameters: . p - the buffer Level: developer Notes: PetscBinaryRead() uses byte swapping to work on all machines; the files are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers are converted to the small-endian format when they are read in from the file. When PETSc is ./configure with --with-64bit-indices the integers are written to the file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices is used. Concepts: files^reading binary Concepts: binary files^reading .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() @*/ PetscErrorCode PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type) { int wsize,err; size_t m = (size_t) n,maxblock = 65536; char *pp = (char*)p; #if defined(PETSC_USE_REAL___FLOAT128) PetscBool readdouble = PETSC_FALSE; double *ppp; #endif #if !defined(PETSC_WORDS_BIGENDIAN) || defined(PETSC_USE_REAL___FLOAT128) PetscErrorCode ierr; #endif #if !defined(PETSC_WORDS_BIGENDIAN) void *ptmp = p; #endif char *fname = NULL; PetscFunctionBegin; if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); if (!n) PetscFunctionReturn(0); if (type == PETSC_FUNCTION) { m = 64; type = PETSC_CHAR; fname = (char*) malloc(m*sizeof(char)); if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); pp = (char*)fname; #if !defined(PETSC_WORDS_BIGENDIAN) ptmp = (void*)fname; #endif } if (type == PETSC_INT) m *= sizeof(PetscInt); else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); else if (type == PETSC_DOUBLE) m *= sizeof(double); else if (type == PETSC_FLOAT) m *= sizeof(float); else if (type == PETSC_SHORT) m *= sizeof(short); else if (type == PETSC_CHAR) m *= sizeof(char); else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); else if (type == PETSC_BOOL) m *= sizeof(PetscBool); else if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char); else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); #if defined(PETSC_USE_REAL___FLOAT128) ierr = PetscOptionsGetBool(NULL,"-binary_read_double",&readdouble,NULL);CHKERRQ(ierr); /* If using __float128 precision we still read in doubles from file */ if (type == PETSC_SCALAR && readdouble) { m = m/2; ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr); pp = (char*)ppp; } #endif while (m) { wsize = (m < maxblock) ? m : maxblock; err = read(fd,pp,wsize); if (err < 0 && errno == EINTR) continue; if (!err && wsize > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file"); if (err < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno); m -= err; pp += err; } #if defined(PETSC_USE_REAL___FLOAT128) if (type == PETSC_SCALAR && readdouble) { PetscScalar *pv = (PetscScalar*) p; PetscInt i; #if !defined(PETSC_WORDS_BIGENDIAN) ierr = PetscByteSwapDouble(ppp,n);CHKERRQ(ierr); #endif for (i=0; i<n; i++) pv[i] = ppp[i]; ierr = PetscFree(ppp);CHKERRQ(ierr); PetscFunctionReturn(0); } #endif #if !defined(PETSC_WORDS_BIGENDIAN) ierr = PetscByteSwap(ptmp,type,n);CHKERRQ(ierr); #endif if (type == PETSC_FUNCTION) { #if defined(PETSC_SERIALIZE_FUNCTIONS) ierr = PetscDLSym(NULL,fname,(void**)p);CHKERRQ(ierr); #else *(void**)p = NULL; #endif free(fname); } PetscFunctionReturn(0); }