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 */ PetscCall(DMDASetUniformCoordinates(da, -1.0,1.0, -1.0,1.0, -1.0,1.0)); } else if (idx==2) { /* stagnation in a corner */ PetscCall(DMDASetUniformCoordinates(da, -1.0,1.0, 0.0,1.0, -1.0,1.0)); } else if (idx==3) { /* nautilis */ PetscCall(DMDASetUniformCoordinates(da, -1.0,1.0, -1.0,1.0, -1.0,1.0)); } else if (idx==4) { PetscCall(DMDASetUniformCoordinates(da, -1.0,1.0, -1.0,1.0, -1.0,1.0)); } PetscCall(DMGetCoordinateDM(da,&cda)); PetscCall(DMGetCoordinates(da,&Gcoords)); PetscCall(VecGetArray(Gcoords,&XX)); PetscCall(DMDAGetCorners(da,&sx,&sy,&sz,&nx,&ny,&nz)); PetscCall(DMDAGetInfo(da, &dim, 0,0,0, 0,0,0, 0,0,0,0,0,0)); PetscCall(VecGetLocalSize(Gcoords,&n)); n = n / dim; for (i=0; i%" PetscInt_FMT ", interp err = %1.4e\n",mx,Mx,(double)(nrm/PetscSqrtReal((PetscReal)N)))); PetscCall(VecDestroy(&afexact)); } PetscCall(PetscOptionsGetBool(NULL,NULL,"-output",&output,NULL)); if (output) { PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_1D.vtr", &vv)); PetscCall(VecView(ac, vv)); PetscCall(PetscViewerDestroy(&vv)); PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_1D.vtr", &vv)); PetscCall(VecView(af, vv)); PetscCall(PetscViewerDestroy(&vv)); } PetscCall(MatDestroy(&INTERP)); PetscCall(DMDestroy(&dac)); PetscCall(DMDestroy(&daf)); PetscCall(VecDestroy(&ac)); PetscCall(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; PetscCall(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)); PetscCall(DMSetFromOptions(dac)); PetscCall(DMSetUp(dac)); PetscCall(DMRefine(dac,MPI_COMM_NULL,&daf)); PetscCall(DMDAGetInfo(daf,0,&Mx,&My,0,0,0,0,0,0,0,0,0,0)); Mx--; My--; PetscCall(DMDASetUniformCoordinates(dac, -1.0,1.0, -1.0,1.0, PETSC_DECIDE,PETSC_DECIDE)); PetscCall(DMDASetUniformCoordinates(daf, -1.0,1.0, -1.0,1.0, PETSC_DECIDE,PETSC_DECIDE)); /* apply conformal mappings */ map_id = 0; PetscCall(PetscOptionsGetInt(NULL,NULL,"-cmap", &map_id,NULL)); if (map_id >= 1) { PetscCall(DAApplyConformalMapping(dac,map_id)); } { DM cdaf,cdac; Vec coordsc,coordsf; PetscCall(DMGetCoordinateDM(dac,&cdac)); PetscCall(DMGetCoordinateDM(daf,&cdaf)); PetscCall(DMGetCoordinates(dac,&coordsc)); PetscCall(DMGetCoordinates(daf,&coordsf)); PetscCall(DMCreateInterpolation(cdac,cdaf,&II,&scale)); PetscCall(MatInterpolate(II,coordsc,coordsf)); PetscCall(MatDestroy(&II)); PetscCall(VecDestroy(&scale)); } PetscCall(DMCreateInterpolation(dac,daf,&INTERP,NULL)); PetscCall(DMCreateGlobalVector(dac,&ac)); PetscCall(DADefineXLinearField2D(dac,ac)); PetscCall(DMCreateGlobalVector(daf,&af)); PetscCall(MatMult(INTERP,ac, af)); { Vec afexact; PetscReal nrm; PetscInt N; PetscCall(DMCreateGlobalVector(daf,&afexact)); PetscCall(VecZeroEntries(afexact)); PetscCall(DADefineXLinearField2D(daf,afexact)); PetscCall(VecAXPY(afexact,-1.0,af)); /* af <= af - afinterp */ PetscCall(VecNorm(afexact,NORM_2,&nrm)); PetscCall(VecGetSize(afexact,&N)); PetscCall(PetscPrintf(PETSC_COMM_WORLD,"[%" PetscInt_FMT " x %" PetscInt_FMT "]=>[%" PetscInt_FMT " x %" PetscInt_FMT "], interp err = %1.4e\n",mx,my,Mx,My,(double)(nrm/PetscSqrtReal((PetscReal)N)))); PetscCall(VecDestroy(&afexact)); } PetscCall(PetscOptionsGetBool(NULL,NULL,"-output",&output,NULL)); if (output) { PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_2D.vtr", &vv)); PetscCall(VecView(ac, vv)); PetscCall(PetscViewerDestroy(&vv)); PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_2D.vtr", &vv)); PetscCall(VecView(af, vv)); PetscCall(PetscViewerDestroy(&vv)); } PetscCall(MatDestroy(&INTERP)); PetscCall(DMDestroy(&dac)); PetscCall(DMDestroy(&daf)); PetscCall(VecDestroy(&ac)); PetscCall(VecDestroy(&af)); PetscFunctionReturn(0); } PetscErrorCode da_test_RefineCoords3D(PetscInt mx,PetscInt my,PetscInt mz) { DM dac,daf; PetscViewer vv; Vec ac,af; PetscInt map_id,Mx,My,Mz; Mat II,INTERP; Vec scale; PetscBool output = PETSC_FALSE; PetscFunctionBeginUser; PetscCall(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)); PetscCall(DMSetFromOptions(dac)); PetscCall(DMSetUp(dac)); PetscCall(DMRefine(dac,MPI_COMM_NULL,&daf)); PetscCall(DMDAGetInfo(daf,0,&Mx,&My,&Mz,0,0,0,0,0,0,0,0,0)); Mx--; My--; Mz--; PetscCall(DMDASetUniformCoordinates(dac, -1.0,1.0, -1.0,1.0, -1.0,1.0)); PetscCall(DMDASetUniformCoordinates(daf, -1.0,1.0, -1.0,1.0, -1.0,1.0)); /* apply trilinear mappings */ /*PetscCall(DAApplyTrilinearMapping(dac));*/ /* apply conformal mappings */ map_id = 0; PetscCall(PetscOptionsGetInt(NULL,NULL,"-cmap", &map_id,NULL)); if (map_id >= 1) { PetscCall(DAApplyConformalMapping(dac,map_id)); } { DM cdaf,cdac; Vec coordsc,coordsf; PetscCall(DMGetCoordinateDM(dac,&cdac)); PetscCall(DMGetCoordinateDM(daf,&cdaf)); PetscCall(DMGetCoordinates(dac,&coordsc)); PetscCall(DMGetCoordinates(daf,&coordsf)); PetscCall(DMCreateInterpolation(cdac,cdaf,&II,&scale)); PetscCall(MatInterpolate(II,coordsc,coordsf)); PetscCall(MatDestroy(&II)); PetscCall(VecDestroy(&scale)); } PetscCall(DMCreateInterpolation(dac,daf,&INTERP,NULL)); PetscCall(DMCreateGlobalVector(dac,&ac)); PetscCall(VecZeroEntries(ac)); PetscCall(DADefineXLinearField3D(dac,ac)); PetscCall(DMCreateGlobalVector(daf,&af)); PetscCall(VecZeroEntries(af)); PetscCall(MatMult(INTERP,ac, af)); { Vec afexact; PetscReal nrm; PetscInt N; PetscCall(DMCreateGlobalVector(daf,&afexact)); PetscCall(VecZeroEntries(afexact)); PetscCall(DADefineXLinearField3D(daf,afexact)); PetscCall(VecAXPY(afexact,-1.0,af)); /* af <= af - afinterp */ PetscCall(VecNorm(afexact,NORM_2,&nrm)); PetscCall(VecGetSize(afexact,&N)); PetscCall(PetscPrintf(PETSC_COMM_WORLD,"[%" PetscInt_FMT " x %" PetscInt_FMT " x %" PetscInt_FMT "]=>[%" PetscInt_FMT " x %" PetscInt_FMT " x %" PetscInt_FMT "], interp err = %1.4e\n",mx,my,mz,Mx,My,Mz,(double)(nrm/PetscSqrtReal((PetscReal)N)))); PetscCall(VecDestroy(&afexact)); } PetscCall(PetscOptionsGetBool(NULL,NULL,"-output",&output,NULL)); if (output) { PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_3D.vtr", &vv)); PetscCall(VecView(ac, vv)); PetscCall(PetscViewerDestroy(&vv)); PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_3D.vtr", &vv)); PetscCall(VecView(af, vv)); PetscCall(PetscViewerDestroy(&vv)); } PetscCall(MatDestroy(&INTERP)); PetscCall(DMDestroy(&dac)); PetscCall(DMDestroy(&daf)); PetscCall(VecDestroy(&ac)); PetscCall(VecDestroy(&af)); PetscFunctionReturn(0); } int main(int argc,char **argv) { PetscInt mx = 2,my = 2,mz = 2,l,nl,dim; PetscCall(PetscInitialize(&argc,&argv,0,help)); PetscCall(PetscOptionsGetInt(NULL,NULL,"-mx", &mx, 0)); PetscCall(PetscOptionsGetInt(NULL,NULL,"-my", &my, 0)); PetscCall(PetscOptionsGetInt(NULL,NULL,"-mz", &mz, 0)); nl = 1; PetscCall(PetscOptionsGetInt(NULL,NULL,"-nl", &nl, 0)); dim = 2; PetscCall(PetscOptionsGetInt(NULL,NULL,"-dim", &dim, 0)); for (l=0; l