#ifdef PETSC_RCS_HEADER static char vcid[] = "$Id: meshPeriodic.c,v 1.00 2001/09/25 06:48:57 knepley Exp $"; #endif /* Defines the interface to functions on a periodic mesh */ #include "src/mesh/meshimpl.h" /*I "mesh.h" I*/ #undef __FUNCT__ #define __FUNCT__ "MeshIsPeriodic" /*@ MeshIsPeriodic - This function returns the periodicity of the mesh. Not collective Input Parameter: . mesh - The mesh Output Parameter: . per - The flag for periodicity Level: intermediate .keywords: mesh, coordinates, periodic .seealso: MeshIsPeriodicDimension(), MeshSetPeriodicDimension(), MeshPeriodicX(), MeshPeriodicRelativeX(), MeshPeriodicDiffX() @*/ int MeshIsPeriodic(Mesh mesh, PetscTruth *per) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); PetscValidPointer(per); *per = mesh->isPeriodic; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MeshIsPeriodicDimension" /*@ MeshIsPeriodicDimension - This function returns the periodicity of a given dimension the mesh. Not collective Input Parameters: + mesh - The mesh - dir - The coordinate direction Output Parameter: . per - The flag for periodicity Level: intermediate .keywords: mesh, coordinates, periodic. dimension .seealso: MeshIsPeriodic(), MeshSetPeriodicDimension(), MeshPeriodicX(), MeshPeriodicRelativeX(), MeshPeriodicDiffX() @*/ int MeshIsPeriodicDimension(Mesh mesh, int dir, PetscTruth *per) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); PetscValidPointer(per); if ((dir < 0) || (dir >= mesh->dim)) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Direction %d does not appear in this mesh", dir) *per = mesh->isPeriodicDim[dir]; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MeshSetPeriodicDimension" /*@ MeshSetPeriodicDimension - This function sets the periodicity of a given dimension the mesh. Not collective Input Parameters: + mesh - The mesh . dir - The coordinate direction - per - The flag for periodicity Level: intermediate .keywords: mesh, coordinates, periodic. dimension .seealso: MeshIsPeriodic(), MeshIsPeriodicDimension(), MeshPeriodicX(), MeshPeriodicRelativeX(), MeshPeriodicDiffX() @*/ int MeshSetPeriodicDimension(Mesh mesh, int dir, PetscTruth per) { int d; PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if ((dir < 0) || (dir >= mesh->dim)) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Direction %d does not appear in this mesh", dir) mesh->isPeriodicDim[dir] = per; for(mesh->isPeriodic = PETSC_FALSE, d = 0; d < mesh->dim; d++) { if (mesh->isPeriodicDim[d] == PETSC_TRUE) mesh->isPeriodic = PETSC_TRUE; } PetscFunctionReturn(0); } /* If optimized, these functions are replaced by macros in $PETSC_DIR/include/mesh.h */ #ifndef MESH_PERIODIC_OPTIMIZED #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicX" /*@C MeshPeriodicX - Returns the value modulo the period of the mesh. Not collective Input Parameters: + mesh - The mesh - x - The original coordinate Output Parameter: . ret - The normalized coordinate Level: intermediate .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicY(), MeshPeriodicZ(), MeshPeriodicRelativeX(), MeshPeriodicDiffX() @*/ double MeshPeriodicX(Mesh mesh, double x) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[0] == PETSC_FALSE) PetscFunctionReturn(x); if (x - PETSC_MACHINE_EPSILON > mesh->endX) { if (x - mesh->sizeX > mesh->endX) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one\n", x); PetscFunctionReturn(0.0); } PetscFunctionReturn(x - mesh->sizeX); } else if (x + PETSC_MACHINE_EPSILON < mesh->startX) { if (x + mesh->sizeX < mesh->startX) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one\n", x); PetscFunctionReturn(0.0); } PetscFunctionReturn(x + mesh->sizeX); } else { PetscFunctionReturn(x); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicY" /*@C MeshPeriodicY - Returns the value modulo the period of the mesh. Not collective Input Parameters: + mesh - The mesh - y - The original coordinate Output Parameter: . ret - The normalized coordinate Level: intermediate .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicX(), MeshPeriodicZ(), MeshPeriodicRelativeY(), MeshPeriodicDiffY() @*/ double MeshPeriodicY(Mesh mesh, double y) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[1] == PETSC_FALSE) PetscFunctionReturn(y); if (y - PETSC_MACHINE_EPSILON > mesh->endY) { if (y - mesh->sizeY > mesh->endY) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one\n", y); PetscFunctionReturn(0.0); } PetscFunctionReturn(y - mesh->sizeY); } else if (y + PETSC_MACHINE_EPSILON < mesh->startY) { if (y + mesh->sizeY < mesh->startY) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one\n", y); PetscFunctionReturn(0.0); } PetscFunctionReturn(y + mesh->sizeY); } else { PetscFunctionReturn(y); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicZ" /*@C MeshPeriodicZ - Returns the value modulo the period of the mesh. Not collective Input Parameters: + mesh - The mesh - z - The original coordinate Output Parameter: . ret - The normalized coordinate Level: intermediate .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicX(), MeshPeriodicY(), MeshPeriodicRelativeZ(), MeshPeriodicDiffZ() @*/ double MeshPeriodicZ(Mesh mesh, double z) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[2] == PETSC_FALSE) PetscFunctionReturn(z); if (z - PETSC_MACHINE_EPSILON > mesh->endZ) { if (z - mesh->sizeZ > mesh->endZ) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one\n", z); PetscFunctionReturn(0.0); } PetscFunctionReturn(z - mesh->sizeZ); } else if (z + PETSC_MACHINE_EPSILON < mesh->startZ) { if (z + mesh->sizeZ < mesh->startZ) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one\n", z); PetscFunctionReturn(0.0); } PetscFunctionReturn(z + mesh->sizeZ); } else { PetscFunctionReturn(z); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicRelativeX" /*@C MeshPeriodicRelativeX - Returns the value modulo the period of the mesh, relative to a given coordinate. Not collective Input Parameters: + mesh - The mesh . x - The original coordinate - xO - The origin defining the period Output Parameter: . ret - The normalized coordinate Level: intermediate Note: This function is normally used to have a geometric object reside in a single period of the mesh. For instance, a triangle that needs to be drawn. .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicRelativeY(), MeshPeriodicRelativeZ(), MeshPeriodicX(), MeshPeriodicDiffX() @*/ double MeshPeriodicRelativeX(Mesh mesh, double x, double xO) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[0] == PETSC_FALSE) PetscFunctionReturn(x); if (x - PETSC_MACHINE_EPSILON > xO + 0.5*mesh->sizeX) { if (x - mesh->sizeX > xO + mesh->sizeX) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %g\n", x, xO); PetscFunctionReturn(0.0); } PetscFunctionReturn(x - mesh->sizeX); } else if (x + PETSC_MACHINE_EPSILON < xO - 0.5*mesh->sizeX) { if (x + mesh->sizeX < xO - mesh->sizeX) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %g\n", x, xO); PetscFunctionReturn(0.0); } PetscFunctionReturn(x + mesh->sizeX); } else { PetscFunctionReturn(x); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicRelativeY" /*@C MeshPeriodicRelativeY - Returns the value modulo the period of the mesh, relative to a given coordinate. Not collective Input Parameters: + mesh - The mesh . y - The original coordinate - yO - The origin defining the period Output Parameter: . ret - The normalized coordinate Level: intermediate Note: This function is normally used to have a geometric object reside in a single period of the mesh. For instance, a triangle that needs to be drawn. .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicRelativeX(), MeshPeriodicRelativeZ(), MeshPeriodicY(), MeshPeriodicDiffY() @*/ double MeshPeriodicRelativeY(Mesh mesh, double y, double yO) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[1] == PETSC_FALSE) PetscFunctionReturn(y); if (y - PETSC_MACHINE_EPSILON > yO + 0.5*mesh->sizeY) { if (y - mesh->sizeY > yO + mesh->sizeY) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %g\n", y, yO); PetscFunctionReturn(0.0); } PetscFunctionReturn(y - mesh->sizeY); } else if (y + PETSC_MACHINE_EPSILON < yO - 0.5*mesh->sizeY) { if (y + mesh->sizeY < yO - mesh->sizeY) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %g\n", y, yO); PetscFunctionReturn(0.0); } PetscFunctionReturn(y + mesh->sizeY); } else { PetscFunctionReturn(y); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicRelativeZ" /*@C MeshPeriodicRelativeZ - Returns the value modulo the period of the mesh, relative to a given coordinate. Not collective Input Parameters: + mesh - The mesh . z - The original coordinate - zO - The origin defining the period Output Parameter: . ret - The normalized coordinate Level: intermediate Note: This function is normally used to have a geometric object reside in a single period of the mesh. For instance, a triangle that needs to be drawn. .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicRelativeX(), MeshPeriodicRelativeY(), MeshPeriodicZ(), MeshPeriodicDiffZ() @*/ double MeshPeriodicRelativeZ(Mesh mesh, double z, double zO) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[2] == PETSC_FALSE) PetscFunctionReturn(z); if (z - PETSC_MACHINE_EPSILON > zO + 0.5*mesh->sizeZ) { if (z - mesh->sizeZ > zO + mesh->sizeZ) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %g\n", z, zO); PetscFunctionReturn(0.0); } PetscFunctionReturn(z - mesh->sizeZ); } else if (z + PETSC_MACHINE_EPSILON < zO - 0.5*mesh->sizeZ) { if (z + mesh->sizeZ < zO - mesh->sizeZ) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %g\n", z, zO); PetscFunctionReturn(0.0); } PetscFunctionReturn(z + mesh->sizeZ); } else { PetscFunctionReturn(z); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicDiffX" /*@C MeshPeriodicDiffX - Takes the difference of two x-coordinates in the domain, and returns the value modulo the period of the mesh. Not collective Input Parameters: + mesh - The mesh - diff - The original difference Output Parameter: . ret - The normalized difference Level: intermediate .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicDiffY(), MeshPeriodicDiffZ(), MeshPeriodicX(), MeshPeriodicRelativeX() @*/ double MeshPeriodicDiffX(Mesh mesh, double diff) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[0] == PETSC_FALSE) PetscFunctionReturn(diff); if (diff - PETSC_MACHINE_EPSILON > 0.5*mesh->sizeX) { if (diff - mesh->sizeX > 0.5*mesh->sizeX) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than one\n", diff); PetscFunctionReturn(0.0); } PetscFunctionReturn(diff - mesh->sizeX); } else if (diff + PETSC_MACHINE_EPSILON < -0.5*mesh->sizeX) { if (diff + mesh->sizeX < -0.5*mesh->sizeX) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than one\n", diff); PetscFunctionReturn(0.0); } PetscFunctionReturn(diff + mesh->sizeX); } else { PetscFunctionReturn(diff); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicDiffY" /*@C MeshPeriodicDiffY - Takes the difference of two y-coordinates in the domain, and returns the value modulo the period of the mesh. Not collective Input Parameters: + mesh - The mesh - diff - The original difference Output Parameter: . ret - The normalized difference Level: intermediate .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicDiffX(), MeshPeriodicDiffZ(), MeshPeriodicY(), MeshPeriodicRelativeY() @*/ double MeshPeriodicDiffY(Mesh mesh, double diff) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[1] == PETSC_FALSE) PetscFunctionReturn(diff); if (diff - PETSC_MACHINE_EPSILON > 0.5*mesh->sizeY) { if (diff - mesh->sizeY > 0.5*mesh->sizeY) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than one\n", diff); PetscFunctionReturn(0.0); } PetscFunctionReturn(diff - mesh->sizeY); } else if (diff + PETSC_MACHINE_EPSILON < -0.5*mesh->sizeY) { if (diff + mesh->sizeY < -0.5*mesh->sizeY) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than one\n", diff); PetscFunctionReturn(0.0); } PetscFunctionReturn(diff + mesh->sizeY); } else { PetscFunctionReturn(diff); } } #undef __FUNCT__ #define __FUNCT__ "MeshPeriodicDiffZ" /*@C MeshPeriodicDiffZ - Takes the difference of two z-coordinates in the domain, and returns the value modulo the period of the mesh. Not collective Input Parameters: + mesh - The mesh - diff - The original difference Output Parameter: . ret - The normalized difference Level: intermediate .keywords: mesh, coordinates, periodic .seealso: MeshPeriodicDiffX(), MeshPeriodicDiffY(), MeshPeriodicZ(), MeshPeriodicRelativeZ() @*/ double MeshPeriodicDiffZ(Mesh mesh, double diff) { PetscFunctionBegin; PetscValidHeaderSpecific(mesh, MESH_COOKIE); if (mesh->isPeriodicDim[2] == PETSC_FALSE) PetscFunctionReturn(diff); if (diff - PETSC_MACHINE_EPSILON > 0.5*mesh->sizeZ) { if (diff - mesh->sizeZ > 0.5*mesh->sizeZ) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than one\n", diff); PetscFunctionReturn(0.0); } PetscFunctionReturn(diff - mesh->sizeZ); } else if (diff + PETSC_MACHINE_EPSILON < -0.5*mesh->sizeZ) { if (diff + mesh->sizeZ < -0.5*mesh->sizeZ) { PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than one\n", diff); PetscFunctionReturn(0.0); } PetscFunctionReturn(diff + mesh->sizeZ); } else { PetscFunctionReturn(diff); } } #endif /* MESH_PERIODIC_OPTIMIZED */