static char help[] = "Checks the functionality of DMGetInterpolation() on deformed grids.\n\n"; #include #include typedef struct _n_CCmplx CCmplx; struct _n_CCmplx { PetscReal real; PetscReal imag; }; CCmplx CCmplxPow(CCmplx a,PetscReal n) { CCmplx b; PetscReal r,theta; r = PetscSqrtReal(a.real*a.real + a.imag*a.imag); theta = PetscAtan2Real(a.imag,a.real); b.real = PetscPowReal(r,n) * PetscCosReal(n*theta); b.imag = PetscPowReal(r,n) * PetscSinReal(n*theta); return b; } CCmplx CCmplxExp(CCmplx a) { CCmplx b; b.real = PetscExpReal(a.real) * PetscCosReal(a.imag); b.imag = PetscExpReal(a.real) * PetscSinReal(a.imag); return b; } CCmplx CCmplxSqrt(CCmplx a) { CCmplx b; PetscReal r,theta; r = PetscSqrtReal(a.real*a.real + a.imag*a.imag); theta = PetscAtan2Real(a.imag,a.real); b.real = PetscSqrtReal(r) * PetscCosReal(0.5*theta); b.imag = PetscSqrtReal(r) * PetscSinReal(0.5*theta); return b; } CCmplx CCmplxAdd(CCmplx a,CCmplx c) { CCmplx b; b.real = a.real +c.real; b.imag = a.imag +c.imag; return b; } PetscScalar CCmplxRe(CCmplx a) { return (PetscScalar)a.real; } PetscScalar CCmplxIm(CCmplx a) { return (PetscScalar)a.imag; } PetscErrorCode DAApplyConformalMapping(DM da,PetscInt idx) { PetscInt i,n; PetscInt sx,nx,sy,ny,sz,nz,dim; Vec Gcoords; PetscScalar *XX; PetscScalar xx,yy,zz; DM cda; PetscFunctionBeginUser; if (idx==0) { PetscFunctionReturn(0); } else if (idx==1) { /* dam break */ CHKERRQ(DMDASetUniformCoordinates(da, -1.0,1.0, -1.0,1.0, -1.0,1.0)); } else if (idx==2) { /* stagnation in a corner */ CHKERRQ(DMDASetUniformCoordinates(da, -1.0,1.0, 0.0,1.0, -1.0,1.0)); } else if (idx==3) { /* nautilis */ CHKERRQ(DMDASetUniformCoordinates(da, -1.0,1.0, -1.0,1.0, -1.0,1.0)); } else if (idx==4) { CHKERRQ(DMDASetUniformCoordinates(da, -1.0,1.0, -1.0,1.0, -1.0,1.0)); } CHKERRQ(DMGetCoordinateDM(da,&cda)); CHKERRQ(DMGetCoordinates(da,&Gcoords)); CHKERRQ(VecGetArray(Gcoords,&XX)); CHKERRQ(DMDAGetCorners(da,&sx,&sy,&sz,&nx,&ny,&nz)); CHKERRQ(DMDAGetInfo(da, &dim, 0,0,0, 0,0,0, 0,0,0,0,0,0)); CHKERRQ(VecGetLocalSize(Gcoords,&n)); n = n / dim; for (i=0; i%D, interp err = %1.4e\n",mx,Mx,(double)(nrm/PetscSqrtReal((PetscReal)N)))); CHKERRQ(VecDestroy(&afexact)); } CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-output",&output,NULL)); if (output) { CHKERRQ(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_1D.vtr", &vv)); CHKERRQ(VecView(ac, vv)); CHKERRQ(PetscViewerDestroy(&vv)); CHKERRQ(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_1D.vtr", &vv)); CHKERRQ(VecView(af, vv)); CHKERRQ(PetscViewerDestroy(&vv)); } CHKERRQ(MatDestroy(&INTERP)); CHKERRQ(DMDestroy(&dac)); CHKERRQ(DMDestroy(&daf)); CHKERRQ(VecDestroy(&ac)); CHKERRQ(VecDestroy(&af)); PetscFunctionReturn(0); } PetscErrorCode da_test_RefineCoords2D(PetscInt mx,PetscInt my) { DM dac,daf; PetscViewer vv; Vec ac,af; PetscInt map_id,Mx,My; Mat II,INTERP; Vec scale; PetscBool output = PETSC_FALSE; PetscFunctionBeginUser; CHKERRQ(DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_BOX,mx+1,my+1,PETSC_DECIDE, PETSC_DECIDE,1, /* 1 dof */1, /* stencil = 1 */NULL, NULL,&dac)); CHKERRQ(DMSetFromOptions(dac)); CHKERRQ(DMSetUp(dac)); CHKERRQ(DMRefine(dac,MPI_COMM_NULL,&daf)); CHKERRQ(DMDAGetInfo(daf,0,&Mx,&My,0,0,0,0,0,0,0,0,0,0)); Mx--; My--; CHKERRQ(DMDASetUniformCoordinates(dac, -1.0,1.0, -1.0,1.0, PETSC_DECIDE,PETSC_DECIDE)); CHKERRQ(DMDASetUniformCoordinates(daf, -1.0,1.0, -1.0,1.0, PETSC_DECIDE,PETSC_DECIDE)); /* apply conformal mappings */ map_id = 0; CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-cmap", &map_id,NULL)); if (map_id >= 1) { CHKERRQ(DAApplyConformalMapping(dac,map_id)); } { DM cdaf,cdac; Vec coordsc,coordsf; CHKERRQ(DMGetCoordinateDM(dac,&cdac)); CHKERRQ(DMGetCoordinateDM(daf,&cdaf)); CHKERRQ(DMGetCoordinates(dac,&coordsc)); CHKERRQ(DMGetCoordinates(daf,&coordsf)); CHKERRQ(DMCreateInterpolation(cdac,cdaf,&II,&scale)); CHKERRQ(MatInterpolate(II,coordsc,coordsf)); CHKERRQ(MatDestroy(&II)); CHKERRQ(VecDestroy(&scale)); } CHKERRQ(DMCreateInterpolation(dac,daf,&INTERP,NULL)); CHKERRQ(DMCreateGlobalVector(dac,&ac)); CHKERRQ(DADefineXLinearField2D(dac,ac)); CHKERRQ(DMCreateGlobalVector(daf,&af)); CHKERRQ(MatMult(INTERP,ac, af)); { Vec afexact; PetscReal nrm; PetscInt N; CHKERRQ(DMCreateGlobalVector(daf,&afexact)); CHKERRQ(VecZeroEntries(afexact)); CHKERRQ(DADefineXLinearField2D(daf,afexact)); CHKERRQ(VecAXPY(afexact,-1.0,af)); /* af <= af - afinterp */ CHKERRQ(VecNorm(afexact,NORM_2,&nrm)); CHKERRQ(VecGetSize(afexact,&N)); CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[%D x %D]=>[%D x %D], interp err = %1.4e\n",mx,my,Mx,My,(double)(nrm/PetscSqrtReal((PetscReal)N)))); CHKERRQ(VecDestroy(&afexact)); } CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-output",&output,NULL)); if (output) { CHKERRQ(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_2D.vtr", &vv)); CHKERRQ(VecView(ac, vv)); CHKERRQ(PetscViewerDestroy(&vv)); CHKERRQ(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_2D.vtr", &vv)); CHKERRQ(VecView(af, vv)); CHKERRQ(PetscViewerDestroy(&vv)); } CHKERRQ(MatDestroy(&INTERP)); CHKERRQ(DMDestroy(&dac)); CHKERRQ(DMDestroy(&daf)); CHKERRQ(VecDestroy(&ac)); CHKERRQ(VecDestroy(&af)); PetscFunctionReturn(0); } PetscErrorCode da_test_RefineCoords3D(PetscInt mx,PetscInt my,PetscInt mz) { PetscErrorCode ierr; DM dac,daf; PetscViewer vv; Vec ac,af; PetscInt map_id,Mx,My,Mz; Mat II,INTERP; Vec scale; PetscBool output = PETSC_FALSE; PetscFunctionBeginUser; ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,mx+1, my+1,mz+1,PETSC_DECIDE, PETSC_DECIDE,PETSC_DECIDE,1, /* 1 dof */ 1, /* stencil = 1 */NULL,NULL,NULL,&dac);CHKERRQ(ierr); CHKERRQ(DMSetFromOptions(dac)); CHKERRQ(DMSetUp(dac)); CHKERRQ(DMRefine(dac,MPI_COMM_NULL,&daf)); CHKERRQ(DMDAGetInfo(daf,0,&Mx,&My,&Mz,0,0,0,0,0,0,0,0,0)); Mx--; My--; Mz--; CHKERRQ(DMDASetUniformCoordinates(dac, -1.0,1.0, -1.0,1.0, -1.0,1.0)); CHKERRQ(DMDASetUniformCoordinates(daf, -1.0,1.0, -1.0,1.0, -1.0,1.0)); /* apply trilinear mappings */ /*CHKERRQ(DAApplyTrilinearMapping(dac));*/ /* apply conformal mappings */ map_id = 0; CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-cmap", &map_id,NULL)); if (map_id >= 1) { CHKERRQ(DAApplyConformalMapping(dac,map_id)); } { DM cdaf,cdac; Vec coordsc,coordsf; CHKERRQ(DMGetCoordinateDM(dac,&cdac)); CHKERRQ(DMGetCoordinateDM(daf,&cdaf)); CHKERRQ(DMGetCoordinates(dac,&coordsc)); CHKERRQ(DMGetCoordinates(daf,&coordsf)); CHKERRQ(DMCreateInterpolation(cdac,cdaf,&II,&scale)); CHKERRQ(MatInterpolate(II,coordsc,coordsf)); CHKERRQ(MatDestroy(&II)); CHKERRQ(VecDestroy(&scale)); } CHKERRQ(DMCreateInterpolation(dac,daf,&INTERP,NULL)); CHKERRQ(DMCreateGlobalVector(dac,&ac)); CHKERRQ(VecZeroEntries(ac)); CHKERRQ(DADefineXLinearField3D(dac,ac)); CHKERRQ(DMCreateGlobalVector(daf,&af)); CHKERRQ(VecZeroEntries(af)); CHKERRQ(MatMult(INTERP,ac, af)); { Vec afexact; PetscReal nrm; PetscInt N; CHKERRQ(DMCreateGlobalVector(daf,&afexact)); CHKERRQ(VecZeroEntries(afexact)); CHKERRQ(DADefineXLinearField3D(daf,afexact)); CHKERRQ(VecAXPY(afexact,-1.0,af)); /* af <= af - afinterp */ CHKERRQ(VecNorm(afexact,NORM_2,&nrm)); CHKERRQ(VecGetSize(afexact,&N)); CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[%D x %D x %D]=>[%D x %D x %D], interp err = %1.4e\n",mx,my,mz,Mx,My,Mz,(double)(nrm/PetscSqrtReal((PetscReal)N)))); CHKERRQ(VecDestroy(&afexact)); } CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-output",&output,NULL)); if (output) { CHKERRQ(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_3D.vtr", &vv)); CHKERRQ(VecView(ac, vv)); CHKERRQ(PetscViewerDestroy(&vv)); CHKERRQ(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_3D.vtr", &vv)); CHKERRQ(VecView(af, vv)); CHKERRQ(PetscViewerDestroy(&vv)); } CHKERRQ(MatDestroy(&INTERP)); CHKERRQ(DMDestroy(&dac)); CHKERRQ(DMDestroy(&daf)); CHKERRQ(VecDestroy(&ac)); CHKERRQ(VecDestroy(&af)); PetscFunctionReturn(0); } int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt mx = 2,my = 2,mz = 2,l,nl,dim; ierr = PetscInitialize(&argc,&argv,0,help);if (ierr) return ierr; CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-mx", &mx, 0)); CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-my", &my, 0)); CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-mz", &mz, 0)); nl = 1; CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-nl", &nl, 0)); dim = 2; CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-dim", &dim, 0)); for (l=0; l