1af33a6ddSJed Brown 2b45d2f2cSJed Brown #include <petsc-private/characteristicimpl.h> /*I "petsccharacteristic.h" I*/ 31e25c274SJed Brown #include <petscdmda.h> 4*665c2dedSJed Brown #include <petscviewer.h> 5af33a6ddSJed Brown 6af33a6ddSJed Brown PetscClassId CHARACTERISTIC_CLASSID; 7af33a6ddSJed Brown PetscLogEvent CHARACTERISTIC_SetUp, CHARACTERISTIC_Solve, CHARACTERISTIC_QueueSetup, CHARACTERISTIC_DAUpdate; 8af33a6ddSJed Brown PetscLogEvent CHARACTERISTIC_HalfTimeLocal, CHARACTERISTIC_HalfTimeRemote, CHARACTERISTIC_HalfTimeExchange; 9af33a6ddSJed Brown PetscLogEvent CHARACTERISTIC_FullTimeLocal, CHARACTERISTIC_FullTimeRemote, CHARACTERISTIC_FullTimeExchange; 10af33a6ddSJed Brown /* 11af33a6ddSJed Brown Contains the list of registered characteristic routines 12af33a6ddSJed Brown */ 130298fd71SBarry Smith PetscFunctionList CharacteristicList = NULL; 14140e18c1SBarry Smith PetscBool CharacteristicRegisterAllCalled = PETSC_FALSE; 15af33a6ddSJed Brown 16af33a6ddSJed Brown PetscErrorCode DMDAGetNeighborsRank(DM, PetscMPIInt []); 17af33a6ddSJed Brown PetscInt DMDAGetNeighborRelative(DM, PassiveReal, PassiveReal); 18af33a6ddSJed Brown PetscErrorCode DMDAMapToPeriodicDomain(DM, PetscScalar []); 19af33a6ddSJed Brown 200b8f38c8SBarry Smith PetscErrorCode CharacteristicHeapSort(Characteristic, Queue, PetscInt); 210b8f38c8SBarry Smith PetscErrorCode CharacteristicSiftDown(Characteristic, Queue, PetscInt, PetscInt); 22af33a6ddSJed Brown 23af33a6ddSJed Brown #undef __FUNCT__ 24af33a6ddSJed Brown #define __FUNCT__ "CharacteristicView" 25af33a6ddSJed Brown PetscErrorCode CharacteristicView(Characteristic c, PetscViewer viewer) 26af33a6ddSJed Brown { 27af33a6ddSJed Brown PetscBool iascii; 28af33a6ddSJed Brown PetscErrorCode ierr; 29af33a6ddSJed Brown 30af33a6ddSJed Brown PetscFunctionBegin; 31af33a6ddSJed Brown PetscValidHeaderSpecific(c, CHARACTERISTIC_CLASSID, 1); 32af33a6ddSJed Brown if (!viewer) { 33ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)c),&viewer);CHKERRQ(ierr); 34af33a6ddSJed Brown } 35af33a6ddSJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 36af33a6ddSJed Brown PetscCheckSameComm(c, 1, viewer, 2); 37af33a6ddSJed Brown 38251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 39af33a6ddSJed Brown if (!iascii) { 40af33a6ddSJed Brown if (c->ops->view) { 41af33a6ddSJed Brown ierr = (*c->ops->view)(c, viewer);CHKERRQ(ierr); 42af33a6ddSJed Brown } 43af33a6ddSJed Brown } 44af33a6ddSJed Brown PetscFunctionReturn(0); 45af33a6ddSJed Brown } 46af33a6ddSJed Brown 47af33a6ddSJed Brown #undef __FUNCT__ 48af33a6ddSJed Brown #define __FUNCT__ "CharacteristicDestroy" 496bf464f9SBarry Smith PetscErrorCode CharacteristicDestroy(Characteristic *c) 50af33a6ddSJed Brown { 51af33a6ddSJed Brown PetscErrorCode ierr; 52af33a6ddSJed Brown 53af33a6ddSJed Brown PetscFunctionBegin; 546bf464f9SBarry Smith if (!*c) PetscFunctionReturn(0); 556bf464f9SBarry Smith PetscValidHeaderSpecific(*c, CHARACTERISTIC_CLASSID, 1); 566bf464f9SBarry Smith if (--((PetscObject)(*c))->refct > 0) PetscFunctionReturn(0); 57af33a6ddSJed Brown 586bf464f9SBarry Smith if ((*c)->ops->destroy) { 596bf464f9SBarry Smith ierr = (*(*c)->ops->destroy)((*c));CHKERRQ(ierr); 60af33a6ddSJed Brown } 616bf464f9SBarry Smith ierr = MPI_Type_free(&(*c)->itemType);CHKERRQ(ierr); 626bf464f9SBarry Smith ierr = PetscFree((*c)->queue);CHKERRQ(ierr); 636bf464f9SBarry Smith ierr = PetscFree((*c)->queueLocal);CHKERRQ(ierr); 646bf464f9SBarry Smith ierr = PetscFree((*c)->queueRemote);CHKERRQ(ierr); 656bf464f9SBarry Smith ierr = PetscFree((*c)->neighbors);CHKERRQ(ierr); 666bf464f9SBarry Smith ierr = PetscFree((*c)->needCount);CHKERRQ(ierr); 676bf464f9SBarry Smith ierr = PetscFree((*c)->localOffsets);CHKERRQ(ierr); 686bf464f9SBarry Smith ierr = PetscFree((*c)->fillCount);CHKERRQ(ierr); 696bf464f9SBarry Smith ierr = PetscFree((*c)->remoteOffsets);CHKERRQ(ierr); 706bf464f9SBarry Smith ierr = PetscFree((*c)->request);CHKERRQ(ierr); 716bf464f9SBarry Smith ierr = PetscFree((*c)->status);CHKERRQ(ierr); 72af33a6ddSJed Brown ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 73af33a6ddSJed Brown PetscFunctionReturn(0); 74af33a6ddSJed Brown } 75af33a6ddSJed Brown 76af33a6ddSJed Brown #undef __FUNCT__ 77af33a6ddSJed Brown #define __FUNCT__ "CharacteristicCreate" 78af33a6ddSJed Brown PetscErrorCode CharacteristicCreate(MPI_Comm comm, Characteristic *c) 79af33a6ddSJed Brown { 80af33a6ddSJed Brown Characteristic newC; 81af33a6ddSJed Brown PetscErrorCode ierr; 82af33a6ddSJed Brown 83af33a6ddSJed Brown PetscFunctionBegin; 84af33a6ddSJed Brown PetscValidPointer(c, 2); 850298fd71SBarry Smith *c = NULL; 86519f805aSKarl Rupp #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 870298fd71SBarry Smith ierr = CharacteristicInitializePackage(NULL);CHKERRQ(ierr); 88af33a6ddSJed Brown #endif 89af33a6ddSJed Brown 9067c2884eSBarry Smith ierr = PetscHeaderCreate(newC, _p_Characteristic, struct _CharacteristicOps, CHARACTERISTIC_CLASSID, "Characteristic", "Characteristic", "SemiLagrange", comm, CharacteristicDestroy, CharacteristicView);CHKERRQ(ierr); 91af33a6ddSJed Brown ierr = PetscLogObjectCreate(newC);CHKERRQ(ierr); 92af33a6ddSJed Brown *c = newC; 93af33a6ddSJed Brown 94af33a6ddSJed Brown newC->structured = PETSC_TRUE; 95af33a6ddSJed Brown newC->numIds = 0; 960298fd71SBarry Smith newC->velocityDA = NULL; 970298fd71SBarry Smith newC->velocity = NULL; 980298fd71SBarry Smith newC->velocityOld = NULL; 99af33a6ddSJed Brown newC->numVelocityComp = 0; 1000298fd71SBarry Smith newC->velocityComp = NULL; 1010298fd71SBarry Smith newC->velocityInterp = NULL; 1020298fd71SBarry Smith newC->velocityInterpLocal = NULL; 1030298fd71SBarry Smith newC->velocityCtx = NULL; 1040298fd71SBarry Smith newC->fieldDA = NULL; 1050298fd71SBarry Smith newC->field = NULL; 106af33a6ddSJed Brown newC->numFieldComp = 0; 1070298fd71SBarry Smith newC->fieldComp = NULL; 1080298fd71SBarry Smith newC->fieldInterp = NULL; 1090298fd71SBarry Smith newC->fieldInterpLocal = NULL; 1100298fd71SBarry Smith newC->fieldCtx = NULL; 1110298fd71SBarry Smith newC->itemType = 0; 1120298fd71SBarry Smith newC->queue = NULL; 113af33a6ddSJed Brown newC->queueSize = 0; 114af33a6ddSJed Brown newC->queueMax = 0; 1150298fd71SBarry Smith newC->queueLocal = NULL; 116af33a6ddSJed Brown newC->queueLocalSize = 0; 117af33a6ddSJed Brown newC->queueLocalMax = 0; 1180298fd71SBarry Smith newC->queueRemote = NULL; 119af33a6ddSJed Brown newC->queueRemoteSize = 0; 120af33a6ddSJed Brown newC->queueRemoteMax = 0; 121af33a6ddSJed Brown newC->numNeighbors = 0; 1220298fd71SBarry Smith newC->neighbors = NULL; 1230298fd71SBarry Smith newC->needCount = NULL; 1240298fd71SBarry Smith newC->localOffsets = NULL; 1250298fd71SBarry Smith newC->fillCount = NULL; 1260298fd71SBarry Smith newC->remoteOffsets = NULL; 1270298fd71SBarry Smith newC->request = NULL; 1280298fd71SBarry Smith newC->status = NULL; 129af33a6ddSJed Brown PetscFunctionReturn(0); 130af33a6ddSJed Brown } 131af33a6ddSJed Brown 132af33a6ddSJed Brown #undef __FUNCT__ 133af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSetType" 134af33a6ddSJed Brown /*@C 135af33a6ddSJed Brown CharacteristicSetType - Builds Characteristic for a particular solver. 136af33a6ddSJed Brown 137af33a6ddSJed Brown Logically Collective on Characteristic 138af33a6ddSJed Brown 139af33a6ddSJed Brown Input Parameters: 140af33a6ddSJed Brown + c - the method of characteristics context 141af33a6ddSJed Brown - type - a known method 142af33a6ddSJed Brown 143af33a6ddSJed Brown Options Database Key: 144af33a6ddSJed Brown . -characteristic_type <method> - Sets the method; use -help for a list 145af33a6ddSJed Brown of available methods 146af33a6ddSJed Brown 147af33a6ddSJed Brown Notes: 14830a76a96SBarry Smith See "include/petsccharacteristic.h" for available methods 149af33a6ddSJed Brown 150af33a6ddSJed Brown Normally, it is best to use the CharacteristicSetFromOptions() command and 151af33a6ddSJed Brown then set the Characteristic type from the options database rather than by using 152af33a6ddSJed Brown this routine. Using the options database provides the user with 153af33a6ddSJed Brown maximum flexibility in evaluating the many different Krylov methods. 154af33a6ddSJed Brown The CharacteristicSetType() routine is provided for those situations where it 155af33a6ddSJed Brown is necessary to set the iterative solver independently of the command 156af33a6ddSJed Brown line or options database. This might be the case, for example, when 157af33a6ddSJed Brown the choice of iterative solver changes during the execution of the 158af33a6ddSJed Brown program, and the user's application is taking responsibility for 159af33a6ddSJed Brown choosing the appropriate method. In other words, this routine is 160af33a6ddSJed Brown not for beginners. 161af33a6ddSJed Brown 162af33a6ddSJed Brown Level: intermediate 163af33a6ddSJed Brown 164af33a6ddSJed Brown .keywords: Characteristic, set, method 165af33a6ddSJed Brown 166af33a6ddSJed Brown .seealso: CharacteristicType 167af33a6ddSJed Brown 168af33a6ddSJed Brown @*/ 16919fd82e9SBarry Smith PetscErrorCode CharacteristicSetType(Characteristic c, CharacteristicType type) 170af33a6ddSJed Brown { 171af33a6ddSJed Brown PetscErrorCode ierr, (*r)(Characteristic); 172af33a6ddSJed Brown PetscBool match; 173af33a6ddSJed Brown 174af33a6ddSJed Brown PetscFunctionBegin; 175af33a6ddSJed Brown PetscValidHeaderSpecific(c, CHARACTERISTIC_CLASSID, 1); 176af33a6ddSJed Brown PetscValidCharPointer(type, 2); 177af33a6ddSJed Brown 178251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) c, type, &match);CHKERRQ(ierr); 179af33a6ddSJed Brown if (match) PetscFunctionReturn(0); 180af33a6ddSJed Brown 181af33a6ddSJed Brown if (c->data) { 182af33a6ddSJed Brown /* destroy the old private Characteristic context */ 183af33a6ddSJed Brown ierr = (*c->ops->destroy)(c);CHKERRQ(ierr); 1840298fd71SBarry Smith c->ops->destroy = NULL; 185af33a6ddSJed Brown c->data = 0; 186af33a6ddSJed Brown } 187af33a6ddSJed Brown 188ce94432eSBarry Smith ierr = PetscFunctionListFind(PetscObjectComm((PetscObject)c),CharacteristicList, type,PETSC_TRUE, (void (**)(void)) &r);CHKERRQ(ierr); 189af33a6ddSJed Brown if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown Characteristic type given: %s", type); 190af33a6ddSJed Brown c->setupcalled = 0; 191af33a6ddSJed Brown ierr = (*r)(c);CHKERRQ(ierr); 192af33a6ddSJed Brown ierr = PetscObjectChangeTypeName((PetscObject) c, type);CHKERRQ(ierr); 193af33a6ddSJed Brown PetscFunctionReturn(0); 194af33a6ddSJed Brown } 195af33a6ddSJed Brown 196af33a6ddSJed Brown #undef __FUNCT__ 197af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSetUp" 198af33a6ddSJed Brown /*@ 199af33a6ddSJed Brown CharacteristicSetUp - Sets up the internal data structures for the 200af33a6ddSJed Brown later use of an iterative solver. 201af33a6ddSJed Brown 202af33a6ddSJed Brown Collective on Characteristic 203af33a6ddSJed Brown 204af33a6ddSJed Brown Input Parameter: 205af33a6ddSJed Brown . ksp - iterative context obtained from CharacteristicCreate() 206af33a6ddSJed Brown 207af33a6ddSJed Brown Level: developer 208af33a6ddSJed Brown 209af33a6ddSJed Brown .keywords: Characteristic, setup 210af33a6ddSJed Brown 211af33a6ddSJed Brown .seealso: CharacteristicCreate(), CharacteristicSolve(), CharacteristicDestroy() 212af33a6ddSJed Brown @*/ 213af33a6ddSJed Brown PetscErrorCode CharacteristicSetUp(Characteristic c) 214af33a6ddSJed Brown { 215af33a6ddSJed Brown PetscErrorCode ierr; 216af33a6ddSJed Brown 217af33a6ddSJed Brown PetscFunctionBegin; 218af33a6ddSJed Brown PetscValidHeaderSpecific(c, CHARACTERISTIC_CLASSID, 1); 219af33a6ddSJed Brown 220af33a6ddSJed Brown if (!((PetscObject)c)->type_name) { 221af33a6ddSJed Brown ierr = CharacteristicSetType(c, CHARACTERISTICDA);CHKERRQ(ierr); 222af33a6ddSJed Brown } 223af33a6ddSJed Brown 224af33a6ddSJed Brown if (c->setupcalled == 2) PetscFunctionReturn(0); 225af33a6ddSJed Brown 226af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_SetUp,c,0,0,0);CHKERRQ(ierr); 227af33a6ddSJed Brown if (!c->setupcalled) { 228af33a6ddSJed Brown ierr = (*c->ops->setup)(c);CHKERRQ(ierr); 229af33a6ddSJed Brown } 230af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_SetUp,c,0,0,0);CHKERRQ(ierr); 231af33a6ddSJed Brown c->setupcalled = 2; 232af33a6ddSJed Brown PetscFunctionReturn(0); 233af33a6ddSJed Brown } 234af33a6ddSJed Brown 235af33a6ddSJed Brown #undef __FUNCT__ 236af33a6ddSJed Brown #define __FUNCT__ "CharacteristicRegister" 237af33a6ddSJed Brown /*@C 238af33a6ddSJed Brown CharacteristicRegister - See CharacteristicRegisterDynamic() 239af33a6ddSJed Brown 240af33a6ddSJed Brown Level: advanced 241af33a6ddSJed Brown @*/ 242af33a6ddSJed Brown PetscErrorCode CharacteristicRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Characteristic)) 243af33a6ddSJed Brown { 244af33a6ddSJed Brown PetscErrorCode ierr; 245af33a6ddSJed Brown char fullname[PETSC_MAX_PATH_LEN]; 246af33a6ddSJed Brown 247af33a6ddSJed Brown PetscFunctionBegin; 248140e18c1SBarry Smith ierr = PetscFunctionListConcat(path,name,fullname);CHKERRQ(ierr); 249140e18c1SBarry Smith ierr = PetscFunctionListAdd(PETSC_COMM_WORLD,&CharacteristicList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 250af33a6ddSJed Brown PetscFunctionReturn(0); 251af33a6ddSJed Brown } 252af33a6ddSJed Brown 253af33a6ddSJed Brown #undef __FUNCT__ 254af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSetVelocityInterpolation" 255af33a6ddSJed Brown PetscErrorCode CharacteristicSetVelocityInterpolation(Characteristic c, DM da, Vec v, Vec vOld, PetscInt numComponents, PetscInt components[], PetscErrorCode (*interp)(Vec, PetscReal[], PetscInt, PetscInt[], PetscScalar[], void*), void *ctx) 256af33a6ddSJed Brown { 257af33a6ddSJed Brown PetscFunctionBegin; 258af33a6ddSJed Brown c->velocityDA = da; 259af33a6ddSJed Brown c->velocity = v; 260af33a6ddSJed Brown c->velocityOld = vOld; 261af33a6ddSJed Brown c->numVelocityComp = numComponents; 262af33a6ddSJed Brown c->velocityComp = components; 263af33a6ddSJed Brown c->velocityInterp = interp; 264af33a6ddSJed Brown c->velocityCtx = ctx; 265af33a6ddSJed Brown PetscFunctionReturn(0); 266af33a6ddSJed Brown } 267af33a6ddSJed Brown 268af33a6ddSJed Brown #undef __FUNCT__ 269af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSetVelocityInterpolationLocal" 270af33a6ddSJed Brown PetscErrorCode CharacteristicSetVelocityInterpolationLocal(Characteristic c, DM da, Vec v, Vec vOld, PetscInt numComponents, PetscInt components[], PetscErrorCode (*interp)(void*, PetscReal [], PetscInt, PetscInt[], PetscScalar[], void*), void *ctx) 271af33a6ddSJed Brown { 272af33a6ddSJed Brown PetscFunctionBegin; 273af33a6ddSJed Brown c->velocityDA = da; 274af33a6ddSJed Brown c->velocity = v; 275af33a6ddSJed Brown c->velocityOld = vOld; 276af33a6ddSJed Brown c->numVelocityComp = numComponents; 277af33a6ddSJed Brown c->velocityComp = components; 278af33a6ddSJed Brown c->velocityInterpLocal = interp; 279af33a6ddSJed Brown c->velocityCtx = ctx; 280af33a6ddSJed Brown PetscFunctionReturn(0); 281af33a6ddSJed Brown } 282af33a6ddSJed Brown 283af33a6ddSJed Brown #undef __FUNCT__ 284af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSetFieldInterpolation" 285af33a6ddSJed Brown PetscErrorCode CharacteristicSetFieldInterpolation(Characteristic c, DM da, Vec v, PetscInt numComponents, PetscInt components[], PetscErrorCode (*interp)(Vec, PetscReal[], PetscInt, PetscInt[], PetscScalar[], void*), void *ctx) 286af33a6ddSJed Brown { 287af33a6ddSJed Brown PetscFunctionBegin; 288af33a6ddSJed Brown #if 0 289af33a6ddSJed Brown if (numComponents > 2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "Fields with more than 2 components are not supported. Send mail to petsc-maint@mcs.anl.gov."); 290af33a6ddSJed Brown #endif 291af33a6ddSJed Brown c->fieldDA = da; 292af33a6ddSJed Brown c->field = v; 293af33a6ddSJed Brown c->numFieldComp = numComponents; 294af33a6ddSJed Brown c->fieldComp = components; 295af33a6ddSJed Brown c->fieldInterp = interp; 296af33a6ddSJed Brown c->fieldCtx = ctx; 297af33a6ddSJed Brown PetscFunctionReturn(0); 298af33a6ddSJed Brown } 299af33a6ddSJed Brown 300af33a6ddSJed Brown #undef __FUNCT__ 301af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSetFieldInterpolationLocal" 302af33a6ddSJed Brown PetscErrorCode CharacteristicSetFieldInterpolationLocal(Characteristic c, DM da, Vec v, PetscInt numComponents, PetscInt components[], PetscErrorCode (*interp)(void*, PetscReal[], PetscInt, PetscInt[], PetscScalar [], void*), void *ctx) 303af33a6ddSJed Brown { 304af33a6ddSJed Brown PetscFunctionBegin; 305af33a6ddSJed Brown #if 0 306af33a6ddSJed Brown if (numComponents > 2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "Fields with more than 2 components are not supported. Send mail to petsc-maint@mcs.anl.gov."); 307af33a6ddSJed Brown #endif 308af33a6ddSJed Brown c->fieldDA = da; 309af33a6ddSJed Brown c->field = v; 310af33a6ddSJed Brown c->numFieldComp = numComponents; 311af33a6ddSJed Brown c->fieldComp = components; 312af33a6ddSJed Brown c->fieldInterpLocal = interp; 313af33a6ddSJed Brown c->fieldCtx = ctx; 314af33a6ddSJed Brown PetscFunctionReturn(0); 315af33a6ddSJed Brown } 316af33a6ddSJed Brown 317af33a6ddSJed Brown #undef __FUNCT__ 318af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSolve" 319af33a6ddSJed Brown PetscErrorCode CharacteristicSolve(Characteristic c, PetscReal dt, Vec solution) 320af33a6ddSJed Brown { 321af33a6ddSJed Brown CharacteristicPointDA2D Qi; 322af33a6ddSJed Brown DM da = c->velocityDA; 323af33a6ddSJed Brown Vec velocityLocal, velocityLocalOld; 324af33a6ddSJed Brown Vec fieldLocal; 325af33a6ddSJed Brown DMDALocalInfo info; 326af33a6ddSJed Brown PetscScalar **solArray; 327af33a6ddSJed Brown void *velocityArray; 328af33a6ddSJed Brown void *velocityArrayOld; 329af33a6ddSJed Brown void *fieldArray; 330af33a6ddSJed Brown PassiveScalar *interpIndices; 331af33a6ddSJed Brown PassiveScalar *velocityValues, *velocityValuesOld; 332af33a6ddSJed Brown PassiveScalar *fieldValues; 333af33a6ddSJed Brown PetscMPIInt rank; 334af33a6ddSJed Brown PetscInt dim; 335af33a6ddSJed Brown PetscMPIInt neighbors[9]; 336af33a6ddSJed Brown PetscInt dof; 337af33a6ddSJed Brown PetscInt gx, gy; 338af33a6ddSJed Brown PetscInt n, is, ie, js, je, comp; 339af33a6ddSJed Brown PetscErrorCode ierr; 340af33a6ddSJed Brown 341af33a6ddSJed Brown PetscFunctionBegin; 342af33a6ddSJed Brown c->queueSize = 0; 343ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)c), &rank);CHKERRQ(ierr); 344af33a6ddSJed Brown ierr = DMDAGetNeighborsRank(da, neighbors);CHKERRQ(ierr); 345af33a6ddSJed Brown ierr = CharacteristicSetNeighbors(c, 9, neighbors);CHKERRQ(ierr); 346af33a6ddSJed Brown ierr = CharacteristicSetUp(c);CHKERRQ(ierr); 347af33a6ddSJed Brown /* global and local grid info */ 348af33a6ddSJed Brown ierr = DMDAGetInfo(da, &dim, &gx, &gy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr); 349af33a6ddSJed Brown ierr = DMDAGetLocalInfo(da, &info);CHKERRQ(ierr); 350af33a6ddSJed Brown is = info.xs; ie = info.xs+info.xm; 351af33a6ddSJed Brown js = info.ys; je = info.ys+info.ym; 352af33a6ddSJed Brown /* Allocation */ 353af33a6ddSJed Brown ierr = PetscMalloc(dim*sizeof(PetscScalar), &interpIndices);CHKERRQ(ierr); 354af33a6ddSJed Brown ierr = PetscMalloc(c->numVelocityComp*sizeof(PetscScalar), &velocityValues);CHKERRQ(ierr); 355af33a6ddSJed Brown ierr = PetscMalloc(c->numVelocityComp*sizeof(PetscScalar), &velocityValuesOld);CHKERRQ(ierr); 356af33a6ddSJed Brown ierr = PetscMalloc(c->numFieldComp*sizeof(PetscScalar), &fieldValues);CHKERRQ(ierr); 357af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_Solve,0,0,0,0);CHKERRQ(ierr); 358af33a6ddSJed Brown 359af33a6ddSJed Brown /* ----------------------------------------------------------------------- 360af33a6ddSJed Brown PART 1, AT t-dt/2 361af33a6ddSJed Brown -----------------------------------------------------------------------*/ 362af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_QueueSetup,0,0,0,0);CHKERRQ(ierr); 363af33a6ddSJed Brown /* GET POSITION AT HALF TIME IN THE PAST */ 364af33a6ddSJed Brown if (c->velocityInterpLocal) { 365af33a6ddSJed Brown ierr = DMGetLocalVector(c->velocityDA, &velocityLocal);CHKERRQ(ierr); 366af33a6ddSJed Brown ierr = DMGetLocalVector(c->velocityDA, &velocityLocalOld);CHKERRQ(ierr); 367af33a6ddSJed Brown ierr = DMGlobalToLocalBegin(c->velocityDA, c->velocity, INSERT_VALUES, velocityLocal);CHKERRQ(ierr); 368af33a6ddSJed Brown ierr = DMGlobalToLocalEnd(c->velocityDA, c->velocity, INSERT_VALUES, velocityLocal);CHKERRQ(ierr); 369af33a6ddSJed Brown ierr = DMGlobalToLocalBegin(c->velocityDA, c->velocityOld, INSERT_VALUES, velocityLocalOld);CHKERRQ(ierr); 370af33a6ddSJed Brown ierr = DMGlobalToLocalEnd(c->velocityDA, c->velocityOld, INSERT_VALUES, velocityLocalOld);CHKERRQ(ierr); 371af33a6ddSJed Brown ierr = DMDAVecGetArray(c->velocityDA, velocityLocal, &velocityArray);CHKERRQ(ierr); 372af33a6ddSJed Brown ierr = DMDAVecGetArray(c->velocityDA, velocityLocalOld, &velocityArrayOld);CHKERRQ(ierr); 373af33a6ddSJed Brown } 3740298fd71SBarry Smith ierr = PetscInfo(NULL, "Calculating position at t_{n - 1/2}\n");CHKERRQ(ierr); 375af33a6ddSJed Brown for (Qi.j = js; Qi.j < je; Qi.j++) { 376af33a6ddSJed Brown for (Qi.i = is; Qi.i < ie; Qi.i++) { 377af33a6ddSJed Brown interpIndices[0] = Qi.i; 378af33a6ddSJed Brown interpIndices[1] = Qi.j; 379bbd56ea5SKarl Rupp if (c->velocityInterpLocal) c->velocityInterpLocal(velocityArray, interpIndices, c->numVelocityComp, c->velocityComp, velocityValues, c->velocityCtx); 380bbd56ea5SKarl Rupp else c->velocityInterp(c->velocity, interpIndices, c->numVelocityComp, c->velocityComp, velocityValues, c->velocityCtx); 381af33a6ddSJed Brown Qi.x = Qi.i - velocityValues[0]*dt/2.0; 382af33a6ddSJed Brown Qi.y = Qi.j - velocityValues[1]*dt/2.0; 383af33a6ddSJed Brown 384af33a6ddSJed Brown /* Determine whether the position at t - dt/2 is local */ 385af33a6ddSJed Brown Qi.proc = DMDAGetNeighborRelative(da, Qi.x, Qi.y); 386af33a6ddSJed Brown 387af33a6ddSJed Brown /* Check for Periodic boundaries and move all periodic points back onto the domain */ 388af33a6ddSJed Brown ierr = DMDAMapCoordsToPeriodicDomain(da,&(Qi.x),&(Qi.y));CHKERRQ(ierr); 389af33a6ddSJed Brown ierr = CharacteristicAddPoint(c, &Qi);CHKERRQ(ierr); 390af33a6ddSJed Brown } 391af33a6ddSJed Brown } 392af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_QueueSetup,0,0,0,0);CHKERRQ(ierr); 393af33a6ddSJed Brown 394af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_HalfTimeExchange,0,0,0,0);CHKERRQ(ierr); 395af33a6ddSJed Brown ierr = CharacteristicSendCoordinatesBegin(c);CHKERRQ(ierr); 396af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_HalfTimeExchange,0,0,0,0);CHKERRQ(ierr); 397af33a6ddSJed Brown 398af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_HalfTimeLocal,0,0,0,0);CHKERRQ(ierr); 399af33a6ddSJed Brown /* Calculate velocity at t_n+1/2 (local values) */ 4000298fd71SBarry Smith ierr = PetscInfo(NULL, "Calculating local velocities at t_{n - 1/2}\n");CHKERRQ(ierr); 401af33a6ddSJed Brown for (n = 0; n < c->queueSize; n++) { 402af33a6ddSJed Brown Qi = c->queue[n]; 403af33a6ddSJed Brown if (c->neighbors[Qi.proc] == rank) { 404af33a6ddSJed Brown interpIndices[0] = Qi.x; 405af33a6ddSJed Brown interpIndices[1] = Qi.y; 406af33a6ddSJed Brown if (c->velocityInterpLocal) { 407af33a6ddSJed Brown c->velocityInterpLocal(velocityArray, interpIndices, c->numVelocityComp, c->velocityComp, velocityValues, c->velocityCtx); 408af33a6ddSJed Brown c->velocityInterpLocal(velocityArrayOld, interpIndices, c->numVelocityComp, c->velocityComp, velocityValuesOld, c->velocityCtx); 409af33a6ddSJed Brown } else { 410af33a6ddSJed Brown c->velocityInterp(c->velocity, interpIndices, c->numVelocityComp, c->velocityComp, velocityValues, c->velocityCtx); 411af33a6ddSJed Brown c->velocityInterp(c->velocityOld, interpIndices, c->numVelocityComp, c->velocityComp, velocityValuesOld, c->velocityCtx); 412af33a6ddSJed Brown } 413af33a6ddSJed Brown Qi.x = 0.5*(velocityValues[0] + velocityValuesOld[0]); 414af33a6ddSJed Brown Qi.y = 0.5*(velocityValues[1] + velocityValuesOld[1]); 415af33a6ddSJed Brown } 416af33a6ddSJed Brown c->queue[n] = Qi; 417af33a6ddSJed Brown } 418af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_HalfTimeLocal,0,0,0,0);CHKERRQ(ierr); 419af33a6ddSJed Brown 420af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_HalfTimeExchange,0,0,0,0);CHKERRQ(ierr); 421af33a6ddSJed Brown ierr = CharacteristicSendCoordinatesEnd(c);CHKERRQ(ierr); 422af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_HalfTimeExchange,0,0,0,0);CHKERRQ(ierr); 423af33a6ddSJed Brown 424af33a6ddSJed Brown 425af33a6ddSJed Brown /* Calculate velocity at t_n+1/2 (fill remote requests) */ 426af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_HalfTimeRemote,0,0,0,0);CHKERRQ(ierr); 4270298fd71SBarry Smith ierr = PetscInfo1(NULL, "Calculating %d remote velocities at t_{n - 1/2}\n", c->queueRemoteSize);CHKERRQ(ierr); 428af33a6ddSJed Brown for (n = 0; n < c->queueRemoteSize; n++) { 429af33a6ddSJed Brown Qi = c->queueRemote[n]; 430af33a6ddSJed Brown interpIndices[0] = Qi.x; 431af33a6ddSJed Brown interpIndices[1] = Qi.y; 432af33a6ddSJed Brown if (c->velocityInterpLocal) { 433af33a6ddSJed Brown c->velocityInterpLocal(velocityArray, interpIndices, c->numVelocityComp, c->velocityComp, velocityValues, c->velocityCtx); 434af33a6ddSJed Brown c->velocityInterpLocal(velocityArrayOld, interpIndices, c->numVelocityComp, c->velocityComp, velocityValuesOld, c->velocityCtx); 435af33a6ddSJed Brown } else { 436af33a6ddSJed Brown c->velocityInterp(c->velocity, interpIndices, c->numVelocityComp, c->velocityComp, velocityValues, c->velocityCtx); 437af33a6ddSJed Brown c->velocityInterp(c->velocityOld, interpIndices, c->numVelocityComp, c->velocityComp, velocityValuesOld, c->velocityCtx); 438af33a6ddSJed Brown } 439af33a6ddSJed Brown Qi.x = 0.5*(velocityValues[0] + velocityValuesOld[0]); 440af33a6ddSJed Brown Qi.y = 0.5*(velocityValues[1] + velocityValuesOld[1]); 441af33a6ddSJed Brown c->queueRemote[n] = Qi; 442af33a6ddSJed Brown } 443af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_HalfTimeRemote,0,0,0,0);CHKERRQ(ierr); 444af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_HalfTimeExchange,0,0,0,0);CHKERRQ(ierr); 445af33a6ddSJed Brown ierr = CharacteristicGetValuesBegin(c);CHKERRQ(ierr); 446af33a6ddSJed Brown ierr = CharacteristicGetValuesEnd(c);CHKERRQ(ierr); 447af33a6ddSJed Brown if (c->velocityInterpLocal) { 448af33a6ddSJed Brown ierr = DMDAVecRestoreArray(c->velocityDA, velocityLocal, &velocityArray);CHKERRQ(ierr); 449af33a6ddSJed Brown ierr = DMDAVecRestoreArray(c->velocityDA, velocityLocalOld, &velocityArrayOld);CHKERRQ(ierr); 450af33a6ddSJed Brown ierr = DMRestoreLocalVector(c->velocityDA, &velocityLocal);CHKERRQ(ierr); 451af33a6ddSJed Brown ierr = DMRestoreLocalVector(c->velocityDA, &velocityLocalOld);CHKERRQ(ierr); 452af33a6ddSJed Brown } 453af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_HalfTimeExchange,0,0,0,0);CHKERRQ(ierr); 454af33a6ddSJed Brown 455af33a6ddSJed Brown /* ----------------------------------------------------------------------- 456af33a6ddSJed Brown PART 2, AT t-dt 457af33a6ddSJed Brown -----------------------------------------------------------------------*/ 458af33a6ddSJed Brown 459af33a6ddSJed Brown /* GET POSITION AT t_n (local values) */ 460af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_FullTimeLocal,0,0,0,0);CHKERRQ(ierr); 4610298fd71SBarry Smith ierr = PetscInfo(NULL, "Calculating position at t_{n}\n");CHKERRQ(ierr); 462af33a6ddSJed Brown for (n = 0; n < c->queueSize; n++) { 463af33a6ddSJed Brown Qi = c->queue[n]; 464af33a6ddSJed Brown Qi.x = Qi.i - Qi.x*dt; 465af33a6ddSJed Brown Qi.y = Qi.j - Qi.y*dt; 466af33a6ddSJed Brown 467af33a6ddSJed Brown /* Determine whether the position at t-dt is local */ 468af33a6ddSJed Brown Qi.proc = DMDAGetNeighborRelative(da, Qi.x, Qi.y); 469af33a6ddSJed Brown 470af33a6ddSJed Brown /* Check for Periodic boundaries and move all periodic points back onto the domain */ 471af33a6ddSJed Brown ierr = DMDAMapCoordsToPeriodicDomain(da,&(Qi.x),&(Qi.y));CHKERRQ(ierr); 472af33a6ddSJed Brown 473af33a6ddSJed Brown c->queue[n] = Qi; 474af33a6ddSJed Brown } 475af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_FullTimeLocal,0,0,0,0);CHKERRQ(ierr); 476af33a6ddSJed Brown 477af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_FullTimeExchange,0,0,0,0);CHKERRQ(ierr); 478af33a6ddSJed Brown ierr = CharacteristicSendCoordinatesBegin(c);CHKERRQ(ierr); 479af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_FullTimeExchange,0,0,0,0);CHKERRQ(ierr); 480af33a6ddSJed Brown 481af33a6ddSJed Brown /* GET VALUE AT FULL TIME IN THE PAST (LOCAL REQUESTS) */ 482af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_FullTimeLocal,0,0,0,0);CHKERRQ(ierr); 483af33a6ddSJed Brown if (c->fieldInterpLocal) { 484af33a6ddSJed Brown ierr = DMGetLocalVector(c->fieldDA, &fieldLocal);CHKERRQ(ierr); 485af33a6ddSJed Brown ierr = DMGlobalToLocalBegin(c->fieldDA, c->field, INSERT_VALUES, fieldLocal);CHKERRQ(ierr); 486af33a6ddSJed Brown ierr = DMGlobalToLocalEnd(c->fieldDA, c->field, INSERT_VALUES, fieldLocal);CHKERRQ(ierr); 487af33a6ddSJed Brown ierr = DMDAVecGetArray(c->fieldDA, fieldLocal, &fieldArray);CHKERRQ(ierr); 488af33a6ddSJed Brown } 4890298fd71SBarry Smith ierr = PetscInfo(NULL, "Calculating local field at t_{n}\n");CHKERRQ(ierr); 490af33a6ddSJed Brown for (n = 0; n < c->queueSize; n++) { 491af33a6ddSJed Brown if (c->neighbors[c->queue[n].proc] == rank) { 492af33a6ddSJed Brown interpIndices[0] = c->queue[n].x; 493af33a6ddSJed Brown interpIndices[1] = c->queue[n].y; 494bbd56ea5SKarl Rupp if (c->fieldInterpLocal) c->fieldInterpLocal(fieldArray, interpIndices, c->numFieldComp, c->fieldComp, fieldValues, c->fieldCtx); 495bbd56ea5SKarl Rupp else c->fieldInterp(c->field, interpIndices, c->numFieldComp, c->fieldComp, fieldValues, c->fieldCtx); 496bbd56ea5SKarl Rupp for (comp = 0; comp < c->numFieldComp; comp++) c->queue[n].field[comp] = fieldValues[comp]; 497af33a6ddSJed Brown } 498af33a6ddSJed Brown } 499af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_FullTimeLocal,0,0,0,0);CHKERRQ(ierr); 500af33a6ddSJed Brown 501af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_FullTimeExchange,0,0,0,0);CHKERRQ(ierr); 502af33a6ddSJed Brown ierr = CharacteristicSendCoordinatesEnd(c);CHKERRQ(ierr); 503af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_FullTimeExchange,0,0,0,0);CHKERRQ(ierr); 504af33a6ddSJed Brown 505af33a6ddSJed Brown /* GET VALUE AT FULL TIME IN THE PAST (REMOTE REQUESTS) */ 506af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_FullTimeRemote,0,0,0,0);CHKERRQ(ierr); 5070298fd71SBarry Smith ierr = PetscInfo1(NULL, "Calculating %d remote field points at t_{n}\n", c->queueRemoteSize);CHKERRQ(ierr); 508af33a6ddSJed Brown for (n = 0; n < c->queueRemoteSize; n++) { 509af33a6ddSJed Brown interpIndices[0] = c->queueRemote[n].x; 510af33a6ddSJed Brown interpIndices[1] = c->queueRemote[n].y; 511af33a6ddSJed Brown 512af33a6ddSJed Brown /* for debugging purposes */ 513af33a6ddSJed Brown if (1) { /* hacked bounds test...let's do better */ 514af33a6ddSJed Brown PetscScalar im = interpIndices[0]; PetscScalar jm = interpIndices[1]; 515af33a6ddSJed Brown 516bbd56ea5SKarl Rupp if ((im < (PetscScalar) is - 1.) || (im > (PetscScalar) ie) || (jm < (PetscScalar) js - 1.) || (jm > (PetscScalar) je)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB, "Nonlocal point: (%g,%g)", im, jm); 517af33a6ddSJed Brown } 518af33a6ddSJed Brown 519bbd56ea5SKarl Rupp if (c->fieldInterpLocal) c->fieldInterpLocal(fieldArray, interpIndices, c->numFieldComp, c->fieldComp, fieldValues, c->fieldCtx); 520bbd56ea5SKarl Rupp else c->fieldInterp(c->field, interpIndices, c->numFieldComp, c->fieldComp, fieldValues, c->fieldCtx); 521bbd56ea5SKarl Rupp for (comp = 0; comp < c->numFieldComp; comp++) c->queueRemote[n].field[comp] = fieldValues[comp]; 522af33a6ddSJed Brown } 523af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_FullTimeRemote,0,0,0,0);CHKERRQ(ierr); 524af33a6ddSJed Brown 525af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_FullTimeExchange,0,0,0,0);CHKERRQ(ierr); 526af33a6ddSJed Brown ierr = CharacteristicGetValuesBegin(c);CHKERRQ(ierr); 527af33a6ddSJed Brown ierr = CharacteristicGetValuesEnd(c);CHKERRQ(ierr); 528af33a6ddSJed Brown if (c->fieldInterpLocal) { 529af33a6ddSJed Brown ierr = DMDAVecRestoreArray(c->fieldDA, fieldLocal, &fieldArray);CHKERRQ(ierr); 530af33a6ddSJed Brown ierr = DMRestoreLocalVector(c->fieldDA, &fieldLocal);CHKERRQ(ierr); 531af33a6ddSJed Brown } 532af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_FullTimeExchange,0,0,0,0);CHKERRQ(ierr); 533af33a6ddSJed Brown 534af33a6ddSJed Brown /* Return field of characteristics at t_n-1 */ 535af33a6ddSJed Brown ierr = PetscLogEventBegin(CHARACTERISTIC_DAUpdate,0,0,0,0);CHKERRQ(ierr); 536af33a6ddSJed Brown ierr = DMDAGetInfo(c->fieldDA,0,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 537af33a6ddSJed Brown ierr = DMDAVecGetArray(c->fieldDA, solution, &solArray);CHKERRQ(ierr); 538af33a6ddSJed Brown for (n = 0; n < c->queueSize; n++) { 539af33a6ddSJed Brown Qi = c->queue[n]; 540bbd56ea5SKarl Rupp for (comp = 0; comp < c->numFieldComp; comp++) solArray[Qi.j][Qi.i*dof+c->fieldComp[comp]] = Qi.field[comp]; 541af33a6ddSJed Brown } 542af33a6ddSJed Brown ierr = DMDAVecRestoreArray(c->fieldDA, solution, &solArray);CHKERRQ(ierr); 543af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_DAUpdate,0,0,0,0);CHKERRQ(ierr); 544af33a6ddSJed Brown ierr = PetscLogEventEnd(CHARACTERISTIC_Solve,0,0,0,0);CHKERRQ(ierr); 545af33a6ddSJed Brown 546af33a6ddSJed Brown /* Cleanup */ 547af33a6ddSJed Brown ierr = PetscFree(interpIndices);CHKERRQ(ierr); 548af33a6ddSJed Brown ierr = PetscFree(velocityValues);CHKERRQ(ierr); 549af33a6ddSJed Brown ierr = PetscFree(velocityValuesOld);CHKERRQ(ierr); 550af33a6ddSJed Brown ierr = PetscFree(fieldValues);CHKERRQ(ierr); 551af33a6ddSJed Brown PetscFunctionReturn(0); 552af33a6ddSJed Brown } 553af33a6ddSJed Brown 554af33a6ddSJed Brown #undef __FUNCT__ 555af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSetNeighbors" 556af33a6ddSJed Brown PetscErrorCode CharacteristicSetNeighbors(Characteristic c, PetscInt numNeighbors, PetscMPIInt neighbors[]) 557af33a6ddSJed Brown { 558af33a6ddSJed Brown PetscErrorCode ierr; 559af33a6ddSJed Brown 560af33a6ddSJed Brown PetscFunctionBegin; 561af33a6ddSJed Brown c->numNeighbors = numNeighbors; 5626eaa7dc8SBarry Smith ierr = PetscFree(c->neighbors);CHKERRQ(ierr); 563af33a6ddSJed Brown ierr = PetscMalloc(numNeighbors * sizeof(PetscMPIInt), &c->neighbors);CHKERRQ(ierr); 564af33a6ddSJed Brown ierr = PetscMemcpy(c->neighbors, neighbors, numNeighbors * sizeof(PetscMPIInt));CHKERRQ(ierr); 565af33a6ddSJed Brown PetscFunctionReturn(0); 566af33a6ddSJed Brown } 567af33a6ddSJed Brown 568af33a6ddSJed Brown #undef __FUNCT__ 569af33a6ddSJed Brown #define __FUNCT__ "CharacteristicAddPoint" 570af33a6ddSJed Brown PetscErrorCode CharacteristicAddPoint(Characteristic c, CharacteristicPointDA2D *point) 571af33a6ddSJed Brown { 572af33a6ddSJed Brown PetscFunctionBegin; 573f23aa3ddSBarry Smith if (c->queueSize >= c->queueMax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Exceeeded maximum queue size %d", c->queueMax); 574af33a6ddSJed Brown c->queue[c->queueSize++] = *point; 575af33a6ddSJed Brown PetscFunctionReturn(0); 576af33a6ddSJed Brown } 577af33a6ddSJed Brown 578af33a6ddSJed Brown #undef __FUNCT__ 579af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSendCoordinatesBegin" 580af33a6ddSJed Brown int CharacteristicSendCoordinatesBegin(Characteristic c) 581af33a6ddSJed Brown { 582af33a6ddSJed Brown PetscMPIInt rank, tag = 121; 583af33a6ddSJed Brown PetscInt i, n; 584af33a6ddSJed Brown PetscErrorCode ierr; 585af33a6ddSJed Brown 586af33a6ddSJed Brown PetscFunctionBegin; 587ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)c), &rank);CHKERRQ(ierr); 5880b8f38c8SBarry Smith ierr = CharacteristicHeapSort(c, c->queue, c->queueSize);CHKERRQ(ierr); 589af33a6ddSJed Brown ierr = PetscMemzero(c->needCount, c->numNeighbors * sizeof(PetscInt));CHKERRQ(ierr); 590bbd56ea5SKarl Rupp for (i = 0; i < c->queueSize; i++) c->needCount[c->queue[i].proc]++; 591af33a6ddSJed Brown c->fillCount[0] = 0; 592af33a6ddSJed Brown for (n = 1; n < c->numNeighbors; n++) { 593ce94432eSBarry Smith ierr = MPI_Irecv(&(c->fillCount[n]), 1, MPIU_INT, c->neighbors[n], tag, PetscObjectComm((PetscObject)c), &(c->request[n-1]));CHKERRQ(ierr); 594af33a6ddSJed Brown } 595af33a6ddSJed Brown for (n = 1; n < c->numNeighbors; n++) { 596ce94432eSBarry Smith ierr = MPI_Send(&(c->needCount[n]), 1, MPIU_INT, c->neighbors[n], tag, PetscObjectComm((PetscObject)c));CHKERRQ(ierr); 597af33a6ddSJed Brown } 598af33a6ddSJed Brown ierr = MPI_Waitall(c->numNeighbors-1, c->request, c->status);CHKERRQ(ierr); 599af33a6ddSJed Brown /* Initialize the remote queue */ 600af33a6ddSJed Brown c->queueLocalMax = c->localOffsets[0] = 0; 601af33a6ddSJed Brown c->queueRemoteMax = c->remoteOffsets[0] = 0; 602af33a6ddSJed Brown for (n = 1; n < c->numNeighbors; n++) { 603af33a6ddSJed Brown c->remoteOffsets[n] = c->queueRemoteMax; 604af33a6ddSJed Brown c->queueRemoteMax += c->fillCount[n]; 605af33a6ddSJed Brown c->localOffsets[n] = c->queueLocalMax; 606af33a6ddSJed Brown c->queueLocalMax += c->needCount[n]; 607af33a6ddSJed Brown } 608af33a6ddSJed Brown /* HACK BEGIN */ 609bbd56ea5SKarl Rupp for (n = 1; n < c->numNeighbors; n++) c->localOffsets[n] += c->needCount[0]; 610af33a6ddSJed Brown c->needCount[0] = 0; 611af33a6ddSJed Brown /* HACK END */ 612af33a6ddSJed Brown if (c->queueRemoteMax) { 613af33a6ddSJed Brown ierr = PetscMalloc(sizeof(CharacteristicPointDA2D) * c->queueRemoteMax, &c->queueRemote);CHKERRQ(ierr); 6140298fd71SBarry Smith } else c->queueRemote = NULL; 615af33a6ddSJed Brown c->queueRemoteSize = c->queueRemoteMax; 616af33a6ddSJed Brown 617af33a6ddSJed Brown /* Send and Receive requests for values at t_n+1/2, giving the coordinates for interpolation */ 618af33a6ddSJed Brown for (n = 1; n < c->numNeighbors; n++) { 6190298fd71SBarry Smith ierr = PetscInfo2(NULL, "Receiving %d requests for values from proc %d\n", c->fillCount[n], c->neighbors[n]);CHKERRQ(ierr); 620ce94432eSBarry Smith ierr = MPI_Irecv(&(c->queueRemote[c->remoteOffsets[n]]), c->fillCount[n], c->itemType, c->neighbors[n], tag, PetscObjectComm((PetscObject)c), &(c->request[n-1]));CHKERRQ(ierr); 621af33a6ddSJed Brown } 622af33a6ddSJed Brown for (n = 1; n < c->numNeighbors; n++) { 6230298fd71SBarry Smith ierr = PetscInfo2(NULL, "Sending %d requests for values from proc %d\n", c->needCount[n], c->neighbors[n]);CHKERRQ(ierr); 624ce94432eSBarry Smith ierr = MPI_Send(&(c->queue[c->localOffsets[n]]), c->needCount[n], c->itemType, c->neighbors[n], tag, PetscObjectComm((PetscObject)c));CHKERRQ(ierr); 625af33a6ddSJed Brown } 626af33a6ddSJed Brown PetscFunctionReturn(0); 627af33a6ddSJed Brown } 628af33a6ddSJed Brown 629af33a6ddSJed Brown #undef __FUNCT__ 630af33a6ddSJed Brown #define __FUNCT__ "CharacteristicSendCoordinatesEnd" 631af33a6ddSJed Brown PetscErrorCode CharacteristicSendCoordinatesEnd(Characteristic c) 632af33a6ddSJed Brown { 633af33a6ddSJed Brown #if 0 634af33a6ddSJed Brown PetscMPIInt rank; 635af33a6ddSJed Brown PetscInt n; 636af33a6ddSJed Brown #endif 637af33a6ddSJed Brown PetscErrorCode ierr; 638af33a6ddSJed Brown 639af33a6ddSJed Brown PetscFunctionBegin; 640af33a6ddSJed Brown ierr = MPI_Waitall(c->numNeighbors-1, c->request, c->status);CHKERRQ(ierr); 641af33a6ddSJed Brown #if 0 642ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)c), &rank);CHKERRQ(ierr); 643af33a6ddSJed Brown for (n = 0; n < c->queueRemoteSize; n++) { 644f23aa3ddSBarry Smith if (c->neighbors[c->queueRemote[n].proc] == rank) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB, "This is messed up, n = %d proc = %d", n, c->queueRemote[n].proc); 645af33a6ddSJed Brown } 646af33a6ddSJed Brown #endif 647af33a6ddSJed Brown PetscFunctionReturn(0); 648af33a6ddSJed Brown } 649af33a6ddSJed Brown 650af33a6ddSJed Brown #undef __FUNCT__ 651af33a6ddSJed Brown #define __FUNCT__ "CharacteristicGetValuesBegin" 652af33a6ddSJed Brown PetscErrorCode CharacteristicGetValuesBegin(Characteristic c) 653af33a6ddSJed Brown { 654af33a6ddSJed Brown PetscMPIInt tag = 121; 655af33a6ddSJed Brown PetscInt n; 656af33a6ddSJed Brown PetscErrorCode ierr; 657af33a6ddSJed Brown 658af33a6ddSJed Brown PetscFunctionBegin; 659af33a6ddSJed Brown /* SEND AND RECIEVE FILLED REQUESTS for velocities at t_n+1/2 */ 660af33a6ddSJed Brown for (n = 1; n < c->numNeighbors; n++) { 661ce94432eSBarry Smith ierr = MPI_Irecv(&(c->queue[c->localOffsets[n]]), c->needCount[n], c->itemType, c->neighbors[n], tag, PetscObjectComm((PetscObject)c), &(c->request[n-1]));CHKERRQ(ierr); 662af33a6ddSJed Brown } 663af33a6ddSJed Brown for (n = 1; n < c->numNeighbors; n++) { 664ce94432eSBarry Smith ierr = MPI_Send(&(c->queueRemote[c->remoteOffsets[n]]), c->fillCount[n], c->itemType, c->neighbors[n], tag, PetscObjectComm((PetscObject)c));CHKERRQ(ierr); 665af33a6ddSJed Brown } 666af33a6ddSJed Brown PetscFunctionReturn(0); 667af33a6ddSJed Brown } 668af33a6ddSJed Brown 669af33a6ddSJed Brown #undef __FUNCT__ 670af33a6ddSJed Brown #define __FUNCT__ "CharacteristicGetValuesEnd" 671af33a6ddSJed Brown PetscErrorCode CharacteristicGetValuesEnd(Characteristic c) 672af33a6ddSJed Brown { 673af33a6ddSJed Brown PetscErrorCode ierr; 674af33a6ddSJed Brown 675af33a6ddSJed Brown PetscFunctionBegin; 676af33a6ddSJed Brown ierr = MPI_Waitall(c->numNeighbors-1, c->request, c->status);CHKERRQ(ierr); 677af33a6ddSJed Brown /* Free queue of requests from other procs */ 678af33a6ddSJed Brown ierr = PetscFree(c->queueRemote);CHKERRQ(ierr); 679af33a6ddSJed Brown PetscFunctionReturn(0); 680af33a6ddSJed Brown } 681af33a6ddSJed Brown 682af33a6ddSJed Brown /*---------------------------------------------------------------------*/ 683af33a6ddSJed Brown #undef __FUNCT__ 6840b8f38c8SBarry Smith #define __FUNCT__ "CharacteristicHeapSort" 685af33a6ddSJed Brown /* 686af33a6ddSJed Brown Based on code from http://linux.wku.edu/~lamonml/algor/sort/heap.html 687af33a6ddSJed Brown */ 6880b8f38c8SBarry Smith PetscErrorCode CharacteristicHeapSort(Characteristic c, Queue queue, PetscInt size) 689af33a6ddSJed Brown /*---------------------------------------------------------------------*/ 690af33a6ddSJed Brown { 6910b8f38c8SBarry Smith PetscErrorCode ierr; 692af33a6ddSJed Brown CharacteristicPointDA2D temp; 6930b8f38c8SBarry Smith PetscInt n; 694af33a6ddSJed Brown 6950b8f38c8SBarry Smith PetscFunctionBegin; 696af33a6ddSJed Brown if (0) { /* Check the order of the queue before sorting */ 6970298fd71SBarry Smith PetscInfo(NULL, "Before Heap sort\n"); 698af33a6ddSJed Brown for (n=0; n<size; n++) { 6990298fd71SBarry Smith ierr = PetscInfo2(NULL,"%d %d\n",n,queue[n].proc);CHKERRQ(ierr); 700af33a6ddSJed Brown } 701af33a6ddSJed Brown } 702af33a6ddSJed Brown 703af33a6ddSJed Brown /* SORTING PHASE */ 7040b8f38c8SBarry Smith for (n = (size / 2)-1; n >= 0; n--) { 7050b8f38c8SBarry Smith ierr = CharacteristicSiftDown(c, queue, n, size-1);CHKERRQ(ierr); /* Rich had size-1 here, Matt had size*/ 7060b8f38c8SBarry Smith } 707af33a6ddSJed Brown for (n = size-1; n >= 1; n--) { 708af33a6ddSJed Brown temp = queue[0]; 709af33a6ddSJed Brown queue[0] = queue[n]; 710af33a6ddSJed Brown queue[n] = temp; 7110b8f38c8SBarry Smith ierr = CharacteristicSiftDown(c, queue, 0, n-1);CHKERRQ(ierr); 712af33a6ddSJed Brown } 713af33a6ddSJed Brown if (0) { /* Check the order of the queue after sorting */ 7140298fd71SBarry Smith ierr = PetscInfo(NULL, "Avter Heap sort\n");CHKERRQ(ierr); 715af33a6ddSJed Brown for (n=0; n<size; n++) { 7160298fd71SBarry Smith ierr = PetscInfo2(NULL,"%d %d\n",n,queue[n].proc);CHKERRQ(ierr); 717af33a6ddSJed Brown } 718af33a6ddSJed Brown } 7190b8f38c8SBarry Smith PetscFunctionReturn(0); 720af33a6ddSJed Brown } 721af33a6ddSJed Brown 722af33a6ddSJed Brown /*---------------------------------------------------------------------*/ 723af33a6ddSJed Brown #undef __FUNCT__ 7240b8f38c8SBarry Smith #define __FUNCT__ "CharacteristicSiftDown" 725af33a6ddSJed Brown /* 726af33a6ddSJed Brown Based on code from http://linux.wku.edu/~lamonml/algor/sort/heap.html 727af33a6ddSJed Brown */ 7280b8f38c8SBarry Smith PetscErrorCode CharacteristicSiftDown(Characteristic c, Queue queue, PetscInt root, PetscInt bottom) 729af33a6ddSJed Brown /*---------------------------------------------------------------------*/ 730af33a6ddSJed Brown { 731af33a6ddSJed Brown PetscBool done = PETSC_FALSE; 732af33a6ddSJed Brown PetscInt maxChild; 733af33a6ddSJed Brown CharacteristicPointDA2D temp; 734af33a6ddSJed Brown 735af33a6ddSJed Brown PetscFunctionBegin; 736af33a6ddSJed Brown while ((root*2 <= bottom) && (!done)) { 737af33a6ddSJed Brown if (root*2 == bottom) maxChild = root * 2; 738af33a6ddSJed Brown else if (queue[root*2].proc > queue[root*2+1].proc) maxChild = root * 2; 739af33a6ddSJed Brown else maxChild = root * 2 + 1; 740af33a6ddSJed Brown 741af33a6ddSJed Brown if (queue[root].proc < queue[maxChild].proc) { 742af33a6ddSJed Brown temp = queue[root]; 743af33a6ddSJed Brown queue[root] = queue[maxChild]; 744af33a6ddSJed Brown queue[maxChild] = temp; 745af33a6ddSJed Brown root = maxChild; 746db4deed7SKarl Rupp } else done = PETSC_TRUE; 747af33a6ddSJed Brown } 748af33a6ddSJed Brown PetscFunctionReturn(0); 749af33a6ddSJed Brown } 750af33a6ddSJed Brown 751af33a6ddSJed Brown #undef __FUNCT__ 752af33a6ddSJed Brown #define __FUNCT__ "DMDAGetNeighborsRank" 753af33a6ddSJed Brown /* [center, left, top-left, top, top-right, right, bottom-right, bottom, bottom-left] */ 754af33a6ddSJed Brown PetscErrorCode DMDAGetNeighborsRank(DM da, PetscMPIInt neighbors[]) 755af33a6ddSJed Brown { 756af33a6ddSJed Brown DMDABoundaryType bx, by; 757af33a6ddSJed Brown PetscBool IPeriodic = PETSC_FALSE, JPeriodic = PETSC_FALSE; 758af33a6ddSJed Brown MPI_Comm comm; 759af33a6ddSJed Brown PetscMPIInt rank; 760af33a6ddSJed Brown PetscInt **procs,pi,pj,pim,pip,pjm,pjp,PI,PJ; 761af33a6ddSJed Brown PetscErrorCode ierr; 762af33a6ddSJed Brown 763af33a6ddSJed Brown PetscFunctionBegin; 764af33a6ddSJed Brown ierr = PetscObjectGetComm((PetscObject) da, &comm);CHKERRQ(ierr); 765af33a6ddSJed Brown ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 76622d28d08SBarry Smith ierr = DMDAGetInfo(da, 0, 0, 0, 0, &PI,&PJ, 0, 0, 0, &bx, &by,0, 0);CHKERRQ(ierr); 767af33a6ddSJed Brown 768bbd56ea5SKarl Rupp if (bx == DMDA_BOUNDARY_PERIODIC) IPeriodic = PETSC_TRUE; 769bbd56ea5SKarl Rupp if (by == DMDA_BOUNDARY_PERIODIC) JPeriodic = PETSC_TRUE; 770af33a6ddSJed Brown 771af33a6ddSJed Brown neighbors[0] = rank; 772af33a6ddSJed Brown rank = 0; 773af33a6ddSJed Brown ierr = PetscMalloc(sizeof(PetscInt*)*PJ,&procs);CHKERRQ(ierr); 774af33a6ddSJed Brown for (pj=0; pj<PJ; pj++) { 775af33a6ddSJed Brown ierr = PetscMalloc(sizeof(PetscInt)*PI,&(procs[pj]));CHKERRQ(ierr); 776af33a6ddSJed Brown for (pi=0; pi<PI; pi++) { 777af33a6ddSJed Brown procs[pj][pi] = rank; 778af33a6ddSJed Brown rank++; 779af33a6ddSJed Brown } 780af33a6ddSJed Brown } 781af33a6ddSJed Brown 782af33a6ddSJed Brown pi = neighbors[0] % PI; 783af33a6ddSJed Brown pj = neighbors[0] / PI; 784af33a6ddSJed Brown pim = pi-1; if (pim<0) pim=PI-1; 785af33a6ddSJed Brown pip = (pi+1)%PI; 786af33a6ddSJed Brown pjm = pj-1; if (pjm<0) pjm=PJ-1; 787af33a6ddSJed Brown pjp = (pj+1)%PJ; 788af33a6ddSJed Brown 789af33a6ddSJed Brown neighbors[1] = procs[pj] [pim]; 790af33a6ddSJed Brown neighbors[2] = procs[pjp][pim]; 791af33a6ddSJed Brown neighbors[3] = procs[pjp][pi]; 792af33a6ddSJed Brown neighbors[4] = procs[pjp][pip]; 793af33a6ddSJed Brown neighbors[5] = procs[pj] [pip]; 794af33a6ddSJed Brown neighbors[6] = procs[pjm][pip]; 795af33a6ddSJed Brown neighbors[7] = procs[pjm][pi]; 796af33a6ddSJed Brown neighbors[8] = procs[pjm][pim]; 797af33a6ddSJed Brown 798af33a6ddSJed Brown if (!IPeriodic) { 799af33a6ddSJed Brown if (pi==0) neighbors[1]=neighbors[2]=neighbors[8]=neighbors[0]; 800af33a6ddSJed Brown if (pi==PI-1) neighbors[4]=neighbors[5]=neighbors[6]=neighbors[0]; 801af33a6ddSJed Brown } 802af33a6ddSJed Brown 803af33a6ddSJed Brown if (!JPeriodic) { 804af33a6ddSJed Brown if (pj==0) neighbors[6]=neighbors[7]=neighbors[8]=neighbors[0]; 805af33a6ddSJed Brown if (pj==PJ-1) neighbors[2]=neighbors[3]=neighbors[4]=neighbors[0]; 806af33a6ddSJed Brown } 807af33a6ddSJed Brown 808af33a6ddSJed Brown for (pj = 0; pj < PJ; pj++) { 809af33a6ddSJed Brown ierr = PetscFree(procs[pj]);CHKERRQ(ierr); 810af33a6ddSJed Brown } 811af33a6ddSJed Brown ierr = PetscFree(procs);CHKERRQ(ierr); 812af33a6ddSJed Brown PetscFunctionReturn(0); 813af33a6ddSJed Brown } 814af33a6ddSJed Brown 815af33a6ddSJed Brown #undef __FUNCT__ 816af33a6ddSJed Brown #define __FUNCT__ "DMDAGetNeighborRelative" 817af33a6ddSJed Brown /* 818af33a6ddSJed Brown SUBDOMAIN NEIGHBORHOOD PROCESS MAP: 819af33a6ddSJed Brown 2 | 3 | 4 820af33a6ddSJed Brown __|___|__ 821af33a6ddSJed Brown 1 | 0 | 5 822af33a6ddSJed Brown __|___|__ 823af33a6ddSJed Brown 8 | 7 | 6 824af33a6ddSJed Brown | | 825af33a6ddSJed Brown */ 826af33a6ddSJed Brown PetscInt DMDAGetNeighborRelative(DM da, PassiveReal ir, PassiveReal jr) 827af33a6ddSJed Brown { 828af33a6ddSJed Brown DMDALocalInfo info; 829af33a6ddSJed Brown PassiveReal is,ie,js,je; 830af33a6ddSJed Brown PetscErrorCode ierr; 831af33a6ddSJed Brown 832af33a6ddSJed Brown ierr = DMDAGetLocalInfo(da, &info);CHKERRQ(ierr); 833af33a6ddSJed Brown is = (PassiveReal) info.xs - 0.5; ie = (PassiveReal) info.xs + info.xm - 0.5; 834af33a6ddSJed Brown js = (PassiveReal) info.ys - 0.5; je = (PassiveReal) info.ys + info.ym - 0.5; 835af33a6ddSJed Brown 836af33a6ddSJed Brown if (ir >= is && ir <= ie) { /* center column */ 837bbd56ea5SKarl Rupp if (jr >= js && jr <= je) return 0; 838bbd56ea5SKarl Rupp else if (jr < js) return 7; 839bbd56ea5SKarl Rupp else return 3; 840af33a6ddSJed Brown } else if (ir < is) { /* left column */ 841bbd56ea5SKarl Rupp if (jr >= js && jr <= je) return 1; 842bbd56ea5SKarl Rupp else if (jr < js) return 8; 843bbd56ea5SKarl Rupp else return 2; 844af33a6ddSJed Brown } else { /* right column */ 845bbd56ea5SKarl Rupp if (jr >= js && jr <= je) return 5; 846bbd56ea5SKarl Rupp else if (jr < js) return 6; 847bbd56ea5SKarl Rupp else return 4; 848af33a6ddSJed Brown } 849af33a6ddSJed Brown } 850