Actual source code: meshPeriodic.c

  1: #ifdef PETSC_RCS_HEADER
  2: static char vcid[] = "$Id: meshPeriodic.c,v 1.00 2001/09/25 06:48:57 knepley Exp $";
  3: #endif

  5: /*
  6:      Defines the interface to functions on a periodic mesh
  7: */

 9:  #include src/mesh/meshimpl.h

 11: /*@
 12:   MeshIsPeriodic - This function returns the periodicity of the mesh.

 14:   Not collective

 16:   Input Parameter:
 17: . mesh - The mesh

 19:   Output Parameter:
 20: . per  - The flag for periodicity

 22:   Level: intermediate

 24: .keywords: mesh, coordinates, periodic
 25: .seealso: MeshIsPeriodicDimension(), MeshSetPeriodicDimension(), MeshPeriodicX(), MeshPeriodicRelativeX(), MeshPeriodicDiffX()
 26: @*/
 27: int MeshIsPeriodic(Mesh mesh, PetscTruth *per)
 28: {
 32:   *per = mesh->isPeriodic;
 33:   return(0);
 34: }

 36: /*@
 37:   MeshIsPeriodicDimension - This function returns the periodicity of a given dimension the mesh.

 39:   Not collective

 41:   Input Parameters:
 42: + mesh - The mesh
 43: - dir  - The coordinate direction

 45:   Output Parameter:
 46: . per  - The flag for periodicity

 48:   Level: intermediate

 50: .keywords: mesh, coordinates, periodic. dimension
 51: .seealso: MeshIsPeriodic(), MeshSetPeriodicDimension(), MeshPeriodicX(), MeshPeriodicRelativeX(), MeshPeriodicDiffX()
 52: @*/
 53: int MeshIsPeriodicDimension(Mesh mesh, int dir, PetscTruth *per)
 54: {
 58:   if ((dir < 0) || (dir >= mesh->dim)) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Direction %d does not appear in this mesh", dir)
 59:   *per = mesh->isPeriodicDim[dir];
 60:   return(0);
 61: }

 63: /*@
 64:   MeshSetPeriodicDimension - This function sets the periodicity of a given dimension the mesh.

 66:   Not collective

 68:   Input Parameters:
 69: + mesh - The mesh
 70: . dir  - The coordinate direction
 71: - per  - The flag for periodicity

 73:   Level: intermediate

 75: .keywords: mesh, coordinates, periodic. dimension
 76: .seealso: MeshIsPeriodic(), MeshIsPeriodicDimension(), MeshPeriodicX(), MeshPeriodicRelativeX(), MeshPeriodicDiffX()
 77: @*/
 78: int MeshSetPeriodicDimension(Mesh mesh, int dir, PetscTruth per)
 79: {
 80:   int d;

 84:   if ((dir < 0) || (dir >= mesh->dim)) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Direction %d does not appear in this mesh", dir)
 85:   mesh->isPeriodicDim[dir] = per;
 86:   for(mesh->isPeriodic = PETSC_FALSE, d = 0; d < mesh->dim; d++) {
 87:     if (mesh->isPeriodicDim[d] == PETSC_TRUE) mesh->isPeriodic = PETSC_TRUE;
 88:   }
 89:   return(0);
 90: }

 92: /* If optimized, these functions are replaced by macros in $PETSC_DIR/include/mesh.h */
 93: #ifndef MESH_PERIODIC_OPTIMIZED

 95: /*@C
 96:   MeshPeriodicX - Returns the value modulo the period of the mesh.

 98:   Not collective

100:   Input Parameters:
101: + mesh - The mesh
102: - x    - The original coordinate

104:   Output Parameter:
105: . ret  - The normalized coordinate

107:   Level: intermediate

109: .keywords: mesh, coordinates, periodic
110: .seealso: MeshPeriodicY(), MeshPeriodicZ(), MeshPeriodicRelativeX(), MeshPeriodicDiffX()
111: @*/
112: double MeshPeriodicX(Mesh mesh, double x)
113: {
116:   if (mesh->isPeriodicDim[0] == PETSC_FALSE)
117:     PetscFunctionReturn(x);
118:   if (x - PETSC_MACHINE_EPSILON > mesh->endX) {
119:     if (x - mesh->sizeX > mesh->endX) {
120:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than onen", x);
121:       PetscFunctionReturn(0.0);
122:     }
123:     PetscFunctionReturn(x - mesh->sizeX);
124:   } else if (x + PETSC_MACHINE_EPSILON < mesh->startX) {
125:     if (x + mesh->sizeX < mesh->startX) {
126:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than onen", x);
127:       PetscFunctionReturn(0.0);
128:     }
129:     PetscFunctionReturn(x + mesh->sizeX);
130:   } else {
131:     PetscFunctionReturn(x);
132:   }
133: }

135: /*@C
136:   MeshPeriodicY - Returns the value modulo the period of the mesh.

138:   Not collective

140:   Input Parameters:
141: + mesh - The mesh
142: - y    - The original coordinate

144:   Output Parameter:
145: . ret  - The normalized coordinate

147:   Level: intermediate

149: .keywords: mesh, coordinates, periodic
150: .seealso: MeshPeriodicX(), MeshPeriodicZ(), MeshPeriodicRelativeY(), MeshPeriodicDiffY()
151: @*/
152: double MeshPeriodicY(Mesh mesh, double y)
153: {
156:   if (mesh->isPeriodicDim[1] == PETSC_FALSE)
157:     PetscFunctionReturn(y);
158:   if (y - PETSC_MACHINE_EPSILON > mesh->endY) {
159:     if (y - mesh->sizeY > mesh->endY) {
160:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than onen", y);
161:       PetscFunctionReturn(0.0);
162:     }
163:     PetscFunctionReturn(y - mesh->sizeY);
164:   } else if (y + PETSC_MACHINE_EPSILON < mesh->startY) {
165:     if (y + mesh->sizeY < mesh->startY) {
166:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than onen", y);
167:       PetscFunctionReturn(0.0);
168:     }
169:     PetscFunctionReturn(y + mesh->sizeY);
170:   } else {
171:     PetscFunctionReturn(y);
172:   }
173: }

175: /*@C
176:   MeshPeriodicZ - Returns the value modulo the period of the mesh.

178:   Not collective

180:   Input Parameters:
181: + mesh - The mesh
182: - z    - The original coordinate

184:   Output Parameter:
185: . ret  - The normalized coordinate

187:   Level: intermediate

189: .keywords: mesh, coordinates, periodic
190: .seealso: MeshPeriodicX(), MeshPeriodicY(), MeshPeriodicRelativeZ(), MeshPeriodicDiffZ()
191: @*/
192: double MeshPeriodicZ(Mesh mesh, double z)
193: {
196:   if (mesh->isPeriodicDim[2] == PETSC_FALSE)
197:     PetscFunctionReturn(z);
198:   if (z - PETSC_MACHINE_EPSILON > mesh->endZ) {
199:     if (z - mesh->sizeZ > mesh->endZ) {
200:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than onen", z);
201:       PetscFunctionReturn(0.0);
202:     }
203:     PetscFunctionReturn(z - mesh->sizeZ);
204:   } else if (z + PETSC_MACHINE_EPSILON < mesh->startZ) {
205:     if (z + mesh->sizeZ < mesh->startZ) {
206:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than onen", z);
207:       PetscFunctionReturn(0.0);
208:     }
209:     PetscFunctionReturn(z + mesh->sizeZ);
210:   } else {
211:     PetscFunctionReturn(z);
212:   }
213: }

215: /*@C
216:   MeshPeriodicRelativeX - Returns the value modulo the period of the mesh, relative
217:   to a given coordinate.

219:   Not collective

221:   Input Parameters:
222: + mesh - The mesh
223: . x    - The original coordinate
224: - xO   - The origin defining the period

226:   Output Parameter:
227: . ret  - The normalized coordinate

229:   Level: intermediate

231:   Note:
232:   This function is normally used to have a geometric object reside in a single
233:   period of the mesh. For instance, a triangle that needs to be drawn.

235: .keywords: mesh, coordinates, periodic
236: .seealso: MeshPeriodicRelativeY(), MeshPeriodicRelativeZ(), MeshPeriodicX(), MeshPeriodicDiffX()
237: @*/
238: double MeshPeriodicRelativeX(Mesh mesh, double x, double xO)
239: {
242:   if (mesh->isPeriodicDim[0] == PETSC_FALSE)
243:     PetscFunctionReturn(x);
244:   if (x - PETSC_MACHINE_EPSILON > xO + 0.5*mesh->sizeX) {
245:     if (x - mesh->sizeX > xO + mesh->sizeX) {
246:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %gn", x, xO);
247:       PetscFunctionReturn(0.0);
248:     }
249:     PetscFunctionReturn(x - mesh->sizeX);
250:   } else if (x + PETSC_MACHINE_EPSILON < xO - 0.5*mesh->sizeX) {
251:     if (x + mesh->sizeX < xO - mesh->sizeX) {
252:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %gn", x, xO);
253:       PetscFunctionReturn(0.0);
254:     }
255:     PetscFunctionReturn(x + mesh->sizeX);
256:   } else {
257:     PetscFunctionReturn(x);
258:   }
259: }

261: /*@C
262:   MeshPeriodicRelativeY - Returns the value modulo the period of the mesh, relative
263:   to a given coordinate.

265:   Not collective

267:   Input Parameters:
268: + mesh - The mesh
269: . y    - The original coordinate
270: - yO   - The origin defining the period

272:   Output Parameter:
273: . ret  - The normalized coordinate

275:   Level: intermediate

277:   Note:
278:   This function is normally used to have a geometric object reside in a single
279:   period of the mesh. For instance, a triangle that needs to be drawn.

281: .keywords: mesh, coordinates, periodic
282: .seealso: MeshPeriodicRelativeX(), MeshPeriodicRelativeZ(), MeshPeriodicY(), MeshPeriodicDiffY()
283: @*/
284: double MeshPeriodicRelativeY(Mesh mesh, double y, double yO)
285: {
288:   if (mesh->isPeriodicDim[1] == PETSC_FALSE)
289:     PetscFunctionReturn(y);
290:   if (y - PETSC_MACHINE_EPSILON > yO + 0.5*mesh->sizeY) {
291:     if (y - mesh->sizeY > yO + mesh->sizeY) {
292:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %gn", y, yO);
293:       PetscFunctionReturn(0.0);
294:     }
295:     PetscFunctionReturn(y - mesh->sizeY);
296:   } else if (y + PETSC_MACHINE_EPSILON < yO - 0.5*mesh->sizeY) {
297:     if (y + mesh->sizeY < yO - mesh->sizeY) {
298:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %gn", y, yO);
299:       PetscFunctionReturn(0.0);
300:     }
301:     PetscFunctionReturn(y + mesh->sizeY);
302:   } else {
303:     PetscFunctionReturn(y);
304:   }
305: }

307: /*@C
308:   MeshPeriodicRelativeZ - Returns the value modulo the period of the mesh, relative
309:   to a given coordinate.

311:   Not collective

313:   Input Parameters:
314: + mesh - The mesh
315: . z    - The original coordinate
316: - zO   - The origin defining the period

318:   Output Parameter:
319: . ret  - The normalized coordinate

321:   Level: intermediate

323:   Note:
324:   This function is normally used to have a geometric object reside in a single
325:   period of the mesh. For instance, a triangle that needs to be drawn.

327: .keywords: mesh, coordinates, periodic
328: .seealso: MeshPeriodicRelativeX(), MeshPeriodicRelativeY(), MeshPeriodicZ(), MeshPeriodicDiffZ()
329: @*/
330: double MeshPeriodicRelativeZ(Mesh mesh, double z, double zO)
331: {
334:   if (mesh->isPeriodicDim[2] == PETSC_FALSE)
335:     PetscFunctionReturn(z);
336:   if (z - PETSC_MACHINE_EPSILON > zO + 0.5*mesh->sizeZ) {
337:     if (z - mesh->sizeZ > zO + mesh->sizeZ) {
338:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %gn", z, zO);
339:       PetscFunctionReturn(0.0);
340:     }
341:     PetscFunctionReturn(z - mesh->sizeZ);
342:   } else if (z + PETSC_MACHINE_EPSILON < zO - 0.5*mesh->sizeZ) {
343:     if (z + mesh->sizeZ < zO - mesh->sizeZ) {
344:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Coordinate %g has winding number greater than one about %gn", z, zO);
345:       PetscFunctionReturn(0.0);
346:     }
347:     PetscFunctionReturn(z + mesh->sizeZ);
348:   } else {
349:     PetscFunctionReturn(z);
350:   }
351: }

353: /*@C
354:   MeshPeriodicDiffX - Takes the difference of two x-coordinates in the domain, and returns
355:   the value modulo the period of the mesh.

357:   Not collective

359:   Input Parameters:
360: + mesh - The mesh
361: - diff - The original difference

363:   Output Parameter:
364: . ret  - The normalized difference

366:   Level: intermediate

368: .keywords: mesh, coordinates, periodic
369: .seealso: MeshPeriodicDiffY(), MeshPeriodicDiffZ(), MeshPeriodicX(), MeshPeriodicRelativeX()
370: @*/
371: double MeshPeriodicDiffX(Mesh mesh, double diff)
372: {
375:   if (mesh->isPeriodicDim[0] == PETSC_FALSE)
376:     PetscFunctionReturn(diff);
377:   if (diff - PETSC_MACHINE_EPSILON > 0.5*mesh->sizeX) {
378:     if (diff - mesh->sizeX > 0.5*mesh->sizeX) {
379:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than onen", diff);
380:       PetscFunctionReturn(0.0);
381:     }
382:     PetscFunctionReturn(diff - mesh->sizeX);
383:   } else if (diff + PETSC_MACHINE_EPSILON < -0.5*mesh->sizeX) {
384:     if (diff + mesh->sizeX < -0.5*mesh->sizeX) {
385:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than onen", diff);
386:       PetscFunctionReturn(0.0);
387:     }
388:     PetscFunctionReturn(diff + mesh->sizeX);
389:   } else {
390:     PetscFunctionReturn(diff);
391:   }
392: }

394: /*@C
395:   MeshPeriodicDiffY - Takes the difference of two y-coordinates in the domain, and returns
396:   the value modulo the period of the mesh.

398:   Not collective

400:   Input Parameters:
401: + mesh - The mesh
402: - diff - The original difference

404:   Output Parameter:
405: . ret  - The normalized difference

407:   Level: intermediate

409: .keywords: mesh, coordinates, periodic
410: .seealso: MeshPeriodicDiffX(), MeshPeriodicDiffZ(), MeshPeriodicY(), MeshPeriodicRelativeY()
411: @*/
412: double MeshPeriodicDiffY(Mesh mesh, double diff)
413: {
416:   if (mesh->isPeriodicDim[1] == PETSC_FALSE)
417:     PetscFunctionReturn(diff);
418:   if (diff - PETSC_MACHINE_EPSILON > 0.5*mesh->sizeY) {
419:     if (diff - mesh->sizeY > 0.5*mesh->sizeY) {
420:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than onen", diff);
421:       PetscFunctionReturn(0.0);
422:     }
423:     PetscFunctionReturn(diff - mesh->sizeY);
424:   } else if (diff + PETSC_MACHINE_EPSILON < -0.5*mesh->sizeY) {
425:     if (diff + mesh->sizeY < -0.5*mesh->sizeY) {
426:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than onen", diff);
427:       PetscFunctionReturn(0.0);
428:     }
429:     PetscFunctionReturn(diff + mesh->sizeY);
430:   } else {
431:     PetscFunctionReturn(diff);
432:   }
433: }

435: /*@C
436:   MeshPeriodicDiffZ - Takes the difference of two z-coordinates in the domain, and returns
437:   the value modulo the period of the mesh.

439:   Not collective

441:   Input Parameters:
442: + mesh - The mesh
443: - diff - The original difference

445:   Output Parameter:
446: . ret  - The normalized difference

448:   Level: intermediate

450: .keywords: mesh, coordinates, periodic
451: .seealso: MeshPeriodicDiffX(), MeshPeriodicDiffY(), MeshPeriodicZ(), MeshPeriodicRelativeZ()
452: @*/
453: double MeshPeriodicDiffZ(Mesh mesh, double diff)
454: {
457:   if (mesh->isPeriodicDim[2] == PETSC_FALSE)
458:     PetscFunctionReturn(diff);
459:   if (diff - PETSC_MACHINE_EPSILON > 0.5*mesh->sizeZ) {
460:     if (diff - mesh->sizeZ > 0.5*mesh->sizeZ) {
461:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than onen", diff);
462:       PetscFunctionReturn(0.0);
463:     }
464:     PetscFunctionReturn(diff - mesh->sizeZ);
465:   } else if (diff + PETSC_MACHINE_EPSILON < -0.5*mesh->sizeZ) {
466:     if (diff + mesh->sizeZ < -0.5*mesh->sizeZ) {
467:       PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference %g has winding number greater than onen", diff);
468:       PetscFunctionReturn(0.0);
469:     }
470:     PetscFunctionReturn(diff + mesh->sizeZ);
471:   } else {
472:     PetscFunctionReturn(diff);
473:   }
474: }

476: #endif /* MESH_PERIODIC_OPTIMIZED */