Cond* createcond(void) { Cond *p; if((p = malloc(sizeof *p)) == nil){ errorf("createcond -- out of memory\n"); return nil; } if(initcond(p) != 0){ free(p); return nil; } return p; }
//------------------------------------------------------------------------------ int main(int argc, char *argv[]) { PetscErrorCode ierr; DM da; Vec ug, ul; PetscInt i, ibeg, nloc, nx=200; const PetscInt sw = 3, ndof = 1; // stencil width PetscMPIInt rank, size; double cfl = 0.4; ierr = PetscInitialize(&argc, &argv, (char*)0, help); CHKERRQ(ierr); MPI_Comm_rank(PETSC_COMM_WORLD, &rank); MPI_Comm_size(PETSC_COMM_WORLD, &size); ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, nx, ndof, sw, NULL, &da); CHKERRQ(ierr); ierr = DMSetFromOptions(da); CHKERRQ(ierr); ierr = DMSetUp(da); CHKERRQ(ierr); ierr = DMCreateGlobalVector(da, &ug); CHKERRQ(ierr); ierr = DMDAGetCorners(da, &ibeg, 0, 0, &nloc, 0, 0); CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&nx,0,0,0,0,0,0,0,0,0,0,0); CHKERRQ(ierr); PetscReal dx = (xmax - xmin) / (PetscReal)(nx); PetscPrintf(PETSC_COMM_WORLD,"nx = %d, dx = %e\n", nx, dx); for(i=ibeg; i<ibeg+nloc; ++i) { PetscReal x = xmin + i*dx; PetscReal v = initcond(x); ierr = VecSetValues(ug,1,&i,&v,INSERT_VALUES); CHKERRQ(ierr); } ierr = VecAssemblyBegin(ug); CHKERRQ(ierr); ierr = VecAssemblyEnd(ug); CHKERRQ(ierr); savesol(nx, dx, ug); // Get local view ierr = DMGetLocalVector(da, &ul); CHKERRQ(ierr); PetscInt il, nl; ierr = DMDAGetGhostCorners(da,&il,0,0,&nl,0,0); CHKERRQ(ierr); double res[nloc], uold[nloc]; double dt = cfl * dx; double lam= dt/dx; double tfinal = 2.0, t = 0.0; while(t < tfinal) { if(t+dt > tfinal) { dt = tfinal - t; lam = dt/dx; } for(int rk=0; rk<3; ++rk) { ierr = DMGlobalToLocalBegin(da, ug, INSERT_VALUES, ul); CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da, ug, INSERT_VALUES, ul); CHKERRQ(ierr); PetscScalar *u; ierr = DMDAVecGetArrayRead(da, ul, &u); CHKERRQ(ierr); PetscScalar *unew; ierr = DMDAVecGetArray(da, ug, &unew); CHKERRQ(ierr); if(rk==0) for(i=ibeg; i<ibeg+nloc; ++i) uold[i-ibeg] = u[i]; for(i=0; i<nloc; ++i) res[i] = 0.0; // Loop over faces and compute flux for(i=0; i<nloc+1; ++i) { // face between j-1, j int j = il+sw+i; int jm1 = j-1; int jm2 = j-2; int jm3 = j-3; int jp1 = j+1; double uleft = weno5(u[jm3],u[jm2],u[jm1],u[j],u[jp1]); double flux = uleft; if(i==0) { res[i] -= flux; } else if(i==nloc) { res[i-1] += flux; } else { res[i] -= flux; res[i-1] += flux; } } // Update solution for(i=ibeg; i<ibeg+nloc; ++i) unew[i] = ark[rk]*uold[i-ibeg] + (1-ark[rk])*(u[i] - lam * res[i-ibeg]); ierr = DMDAVecRestoreArrayRead(da, ul, &u); CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da, ug, &unew); CHKERRQ(ierr); } t += dt; PetscPrintf(PETSC_COMM_WORLD,"t = %f\n", t); } savesol(nx, dx, ug); // Destroy everything before finishing ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = VecDestroy(&ug); CHKERRQ(ierr); ierr = PetscFinalize(); CHKERRQ(ierr); }