10e2ec84fSDave May #define PETSCDM_DLL 20e2ec84fSDave May #include <petsc/private/dmswarmimpl.h> /*I "petscdmswarm.h" I*/ 30e2ec84fSDave May #include <petscsf.h> 4b799feefSDave May #include <petscdmda.h> 5b799feefSDave May #include <petscdmplex.h> 635b38c60SMatthew G. Knepley #include <petscdt.h> 7279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h" 80e2ec84fSDave May 935b38c60SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> /* For CoordinatesRefToReal() */ 1035b38c60SMatthew G. Knepley 1119307e5cSMatthew G. Knepley PetscClassId DMSWARMCELLDM_CLASSID; 1219307e5cSMatthew G. Knepley 1319307e5cSMatthew G. Knepley /*@ 1419307e5cSMatthew G. Knepley DMSwarmCellDMDestroy - destroy a `DMSwarmCellDM` 1519307e5cSMatthew G. Knepley 1619307e5cSMatthew G. Knepley Collective 1719307e5cSMatthew G. Knepley 1819307e5cSMatthew G. Knepley Input Parameter: 1919307e5cSMatthew G. Knepley . celldm - address of `DMSwarmCellDM` 2019307e5cSMatthew G. Knepley 2119307e5cSMatthew G. Knepley Level: advanced 2219307e5cSMatthew G. Knepley 2319307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DMSwarmCellDMCreate()` 2419307e5cSMatthew G. Knepley @*/ 2519307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMDestroy(DMSwarmCellDM *celldm) 2619307e5cSMatthew G. Knepley { 2719307e5cSMatthew G. Knepley PetscFunctionBegin; 2819307e5cSMatthew G. Knepley if (!*celldm) PetscFunctionReturn(PETSC_SUCCESS); 2919307e5cSMatthew G. Knepley PetscValidHeaderSpecific(*celldm, DMSWARMCELLDM_CLASSID, 1); 3019307e5cSMatthew G. Knepley if (--((PetscObject)*celldm)->refct > 0) { 3119307e5cSMatthew G. Knepley *celldm = NULL; 3219307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 3319307e5cSMatthew G. Knepley } 3419307e5cSMatthew G. Knepley PetscTryTypeMethod(*celldm, destroy); 3519307e5cSMatthew G. Knepley for (PetscInt f = 0; f < (*celldm)->Nf; ++f) PetscCall(PetscFree((*celldm)->dmFields[f])); 3619307e5cSMatthew G. Knepley PetscCall(PetscFree((*celldm)->dmFields)); 3719307e5cSMatthew G. Knepley for (PetscInt f = 0; f < (*celldm)->Nfc; ++f) PetscCall(PetscFree((*celldm)->coordFields[f])); 3819307e5cSMatthew G. Knepley PetscCall(PetscFree((*celldm)->coordFields)); 3919307e5cSMatthew G. Knepley PetscCall(PetscFree((*celldm)->cellid)); 4019307e5cSMatthew G. Knepley PetscCall(DMSwarmSortDestroy(&(*celldm)->sort)); 4119307e5cSMatthew G. Knepley PetscCall(DMDestroy(&(*celldm)->dm)); 4219307e5cSMatthew G. Knepley PetscCall(PetscHeaderDestroy(celldm)); 4319307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 4419307e5cSMatthew G. Knepley } 4519307e5cSMatthew G. Knepley 4619307e5cSMatthew G. Knepley /*@ 4719307e5cSMatthew G. Knepley DMSwarmCellDMView - view a `DMSwarmCellDM` 4819307e5cSMatthew G. Knepley 4919307e5cSMatthew G. Knepley Collective 5019307e5cSMatthew G. Knepley 5119307e5cSMatthew G. Knepley Input Parameters: 5219307e5cSMatthew G. Knepley + celldm - `DMSwarmCellDM` 5319307e5cSMatthew G. Knepley - viewer - viewer to display field, for example `PETSC_VIEWER_STDOUT_WORLD` 5419307e5cSMatthew G. Knepley 5519307e5cSMatthew G. Knepley Level: advanced 5619307e5cSMatthew G. Knepley 5719307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DMSwarmCellDMCreate()` 5819307e5cSMatthew G. Knepley @*/ 5919307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMView(DMSwarmCellDM celldm, PetscViewer viewer) 6019307e5cSMatthew G. Knepley { 6119307e5cSMatthew G. Knepley PetscBool iascii; 6219307e5cSMatthew G. Knepley 6319307e5cSMatthew G. Knepley PetscFunctionBegin; 6419307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 6519307e5cSMatthew G. Knepley if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)celldm), &viewer)); 6619307e5cSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6719307e5cSMatthew G. Knepley PetscCheckSameComm(celldm, 1, viewer, 2); 6819307e5cSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 6919307e5cSMatthew G. Knepley if (iascii) { 7019307e5cSMatthew G. Knepley PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)celldm, viewer)); 7119307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPushTab(viewer)); 7219307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "solution field%s:", celldm->Nf > 1 ? "s" : "")); 7319307e5cSMatthew G. Knepley for (PetscInt f = 0; f < celldm->Nf; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, " %s", celldm->dmFields[f])); 7419307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 7519307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "coordinate field%s:", celldm->Nfc > 1 ? "s" : "")); 7619307e5cSMatthew G. Knepley for (PetscInt f = 0; f < celldm->Nfc; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, " %s", celldm->coordFields[f])); 7719307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 7819307e5cSMatthew G. Knepley PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_DEFAULT)); 7919307e5cSMatthew G. Knepley PetscCall(DMView(celldm->dm, viewer)); 8019307e5cSMatthew G. Knepley PetscCall(PetscViewerPopFormat(viewer)); 8119307e5cSMatthew G. Knepley } 8219307e5cSMatthew G. Knepley PetscTryTypeMethod(celldm, view, viewer); 8319307e5cSMatthew G. Knepley if (iascii) PetscCall(PetscViewerASCIIPopTab(viewer)); 8419307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 8519307e5cSMatthew G. Knepley } 8619307e5cSMatthew G. Knepley 8719307e5cSMatthew G. Knepley /*@ 8819307e5cSMatthew G. Knepley DMSwarmCellDMGetDM - Returns the background `DM` for the `DMSwarm` 8919307e5cSMatthew G. Knepley 9019307e5cSMatthew G. Knepley Not Collective 9119307e5cSMatthew G. Knepley 9219307e5cSMatthew G. Knepley Input Parameter: 9319307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object 9419307e5cSMatthew G. Knepley 9519307e5cSMatthew G. Knepley Output Parameter: 9619307e5cSMatthew G. Knepley . dm - The `DM` object 9719307e5cSMatthew G. Knepley 9819307e5cSMatthew G. Knepley Level: intermediate 9919307e5cSMatthew G. Knepley 10019307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()` 10119307e5cSMatthew G. Knepley @*/ 10219307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetDM(DMSwarmCellDM celldm, DM *dm) 10319307e5cSMatthew G. Knepley { 10419307e5cSMatthew G. Knepley PetscFunctionBegin; 10519307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 10619307e5cSMatthew G. Knepley PetscAssertPointer(dm, 2); 10719307e5cSMatthew G. Knepley *dm = celldm->dm; 10819307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 10919307e5cSMatthew G. Knepley } 11019307e5cSMatthew G. Knepley 11119307e5cSMatthew G. Knepley /*@C 11219307e5cSMatthew G. Knepley DMSwarmCellDMGetFields - Returns the `DM` fields for the `DMSwarm` 11319307e5cSMatthew G. Knepley 11419307e5cSMatthew G. Knepley Not Collective 11519307e5cSMatthew G. Knepley 11619307e5cSMatthew G. Knepley Input Parameter: 11719307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object 11819307e5cSMatthew G. Knepley 11919307e5cSMatthew G. Knepley Output Parameters: 12019307e5cSMatthew G. Knepley + Nf - The number of fields 12119307e5cSMatthew G. Knepley - names - The array of field names in the `DMSWARM` 12219307e5cSMatthew G. Knepley 12319307e5cSMatthew G. Knepley Level: intermediate 12419307e5cSMatthew G. Knepley 12519307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()` 12619307e5cSMatthew G. Knepley @*/ 12719307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetFields(DMSwarmCellDM celldm, PetscInt *Nf, const char **names[]) 12819307e5cSMatthew G. Knepley { 12919307e5cSMatthew G. Knepley PetscFunctionBegin; 13019307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 13119307e5cSMatthew G. Knepley if (Nf) { 13219307e5cSMatthew G. Knepley PetscAssertPointer(Nf, 2); 13319307e5cSMatthew G. Knepley *Nf = celldm->Nf; 13419307e5cSMatthew G. Knepley } 13519307e5cSMatthew G. Knepley if (names) { 13619307e5cSMatthew G. Knepley PetscAssertPointer(names, 3); 13719307e5cSMatthew G. Knepley *names = (const char **)celldm->dmFields; 13819307e5cSMatthew G. Knepley } 13919307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 14019307e5cSMatthew G. Knepley } 14119307e5cSMatthew G. Knepley 14219307e5cSMatthew G. Knepley /*@C 14319307e5cSMatthew G. Knepley DMSwarmCellDMGetCoordinateFields - Returns the `DM` coordinate fields for the `DMSwarm` 14419307e5cSMatthew G. Knepley 14519307e5cSMatthew G. Knepley Not Collective 14619307e5cSMatthew G. Knepley 14719307e5cSMatthew G. Knepley Input Parameter: 14819307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object 14919307e5cSMatthew G. Knepley 15019307e5cSMatthew G. Knepley Output Parameters: 15119307e5cSMatthew G. Knepley + Nfc - The number of coordinate fields 15219307e5cSMatthew G. Knepley - names - The array of coordinate field names in the `DMSWARM` 15319307e5cSMatthew G. Knepley 15419307e5cSMatthew G. Knepley Level: intermediate 15519307e5cSMatthew G. Knepley 15619307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()` 15719307e5cSMatthew G. Knepley @*/ 15819307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetCoordinateFields(DMSwarmCellDM celldm, PetscInt *Nfc, const char **names[]) 15919307e5cSMatthew G. Knepley { 16019307e5cSMatthew G. Knepley PetscFunctionBegin; 16119307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 16219307e5cSMatthew G. Knepley if (Nfc) { 16319307e5cSMatthew G. Knepley PetscAssertPointer(Nfc, 2); 16419307e5cSMatthew G. Knepley *Nfc = celldm->Nfc; 16519307e5cSMatthew G. Knepley } 16619307e5cSMatthew G. Knepley if (names) { 16719307e5cSMatthew G. Knepley PetscAssertPointer(names, 3); 16819307e5cSMatthew G. Knepley *names = (const char **)celldm->coordFields; 16919307e5cSMatthew G. Knepley } 17019307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 17119307e5cSMatthew G. Knepley } 17219307e5cSMatthew G. Knepley 17319307e5cSMatthew G. Knepley /*@C 17419307e5cSMatthew G. Knepley DMSwarmCellDMGetCellID - Returns the cell id field name for the `DMSwarm` 17519307e5cSMatthew G. Knepley 17619307e5cSMatthew G. Knepley Not Collective 17719307e5cSMatthew G. Knepley 17819307e5cSMatthew G. Knepley Input Parameter: 17919307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object 18019307e5cSMatthew G. Knepley 18119307e5cSMatthew G. Knepley Output Parameters: 18219307e5cSMatthew G. Knepley . cellid - The cell id field name in the `DMSWARM` 18319307e5cSMatthew G. Knepley 18419307e5cSMatthew G. Knepley Level: intermediate 18519307e5cSMatthew G. Knepley 18619307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()` 18719307e5cSMatthew G. Knepley @*/ 18819307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetCellID(DMSwarmCellDM celldm, const char *cellid[]) 18919307e5cSMatthew G. Knepley { 19019307e5cSMatthew G. Knepley PetscFunctionBegin; 19119307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 19219307e5cSMatthew G. Knepley PetscAssertPointer(cellid, 2); 19319307e5cSMatthew G. Knepley *cellid = celldm->cellid; 19419307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 19519307e5cSMatthew G. Knepley } 19619307e5cSMatthew G. Knepley 19719307e5cSMatthew G. Knepley /*@C 19819307e5cSMatthew G. Knepley DMSwarmCellDMGetSort - Returns the sort context over the active `DMSwarmCellDM` for the `DMSwarm` 19919307e5cSMatthew G. Knepley 20019307e5cSMatthew G. Knepley Not Collective 20119307e5cSMatthew G. Knepley 20219307e5cSMatthew G. Knepley Input Parameter: 20319307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object 20419307e5cSMatthew G. Knepley 20519307e5cSMatthew G. Knepley Output Parameter: 20619307e5cSMatthew G. Knepley . sort - The `DMSwarmSort` object 20719307e5cSMatthew G. Knepley 20819307e5cSMatthew G. Knepley Level: intermediate 20919307e5cSMatthew G. Knepley 21019307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()` 21119307e5cSMatthew G. Knepley @*/ 21219307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetSort(DMSwarmCellDM celldm, DMSwarmSort *sort) 21319307e5cSMatthew G. Knepley { 21419307e5cSMatthew G. Knepley PetscFunctionBegin; 21519307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 21619307e5cSMatthew G. Knepley PetscAssertPointer(sort, 2); 21719307e5cSMatthew G. Knepley *sort = celldm->sort; 21819307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 21919307e5cSMatthew G. Knepley } 22019307e5cSMatthew G. Knepley 22119307e5cSMatthew G. Knepley /*@C 22219307e5cSMatthew G. Knepley DMSwarmCellDMSetSort - Sets the sort context over the active `DMSwarmCellDM` for the `DMSwarm` 22319307e5cSMatthew G. Knepley 22419307e5cSMatthew G. Knepley Not Collective 22519307e5cSMatthew G. Knepley 22619307e5cSMatthew G. Knepley Input Parameters: 22719307e5cSMatthew G. Knepley + celldm - The `DMSwarmCellDM` object 22819307e5cSMatthew G. Knepley - sort - The `DMSwarmSort` object 22919307e5cSMatthew G. Knepley 23019307e5cSMatthew G. Knepley Level: intermediate 23119307e5cSMatthew G. Knepley 23219307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()` 23319307e5cSMatthew G. Knepley @*/ 23419307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMSetSort(DMSwarmCellDM celldm, DMSwarmSort sort) 23519307e5cSMatthew G. Knepley { 23619307e5cSMatthew G. Knepley PetscFunctionBegin; 23719307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 23819307e5cSMatthew G. Knepley PetscAssertPointer(sort, 2); 23919307e5cSMatthew G. Knepley celldm->sort = sort; 24019307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 24119307e5cSMatthew G. Knepley } 24219307e5cSMatthew G. Knepley 24319307e5cSMatthew G. Knepley /*@ 24419307e5cSMatthew G. Knepley DMSwarmCellDMGetBlockSize - Returns the total blocksize for the `DM` fields 24519307e5cSMatthew G. Knepley 24619307e5cSMatthew G. Knepley Not Collective 24719307e5cSMatthew G. Knepley 24819307e5cSMatthew G. Knepley Input Parameters: 24919307e5cSMatthew G. Knepley + celldm - The `DMSwarmCellDM` object 25019307e5cSMatthew G. Knepley - sw - The `DMSwarm` object 25119307e5cSMatthew G. Knepley 25219307e5cSMatthew G. Knepley Output Parameter: 25319307e5cSMatthew G. Knepley . bs - The total block size 25419307e5cSMatthew G. Knepley 25519307e5cSMatthew G. Knepley Level: intermediate 25619307e5cSMatthew G. Knepley 25719307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()` 25819307e5cSMatthew G. Knepley @*/ 25919307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetBlockSize(DMSwarmCellDM celldm, DM sw, PetscInt *bs) 26019307e5cSMatthew G. Knepley { 26119307e5cSMatthew G. Knepley PetscFunctionBegin; 26219307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1); 26319307e5cSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 2); 26419307e5cSMatthew G. Knepley PetscAssertPointer(bs, 3); 26519307e5cSMatthew G. Knepley *bs = 0; 26619307e5cSMatthew G. Knepley for (PetscInt f = 0; f < celldm->Nf; ++f) { 26719307e5cSMatthew G. Knepley PetscInt fbs; 26819307e5cSMatthew G. Knepley 26919307e5cSMatthew G. Knepley PetscCall(DMSwarmGetFieldInfo(sw, celldm->dmFields[f], &fbs, NULL)); 27019307e5cSMatthew G. Knepley *bs += fbs; 27119307e5cSMatthew G. Knepley } 27219307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 27319307e5cSMatthew G. Knepley } 27419307e5cSMatthew G. Knepley 27519307e5cSMatthew G. Knepley /*@ 27619307e5cSMatthew G. Knepley DMSwarmCellDMCreate - create a `DMSwarmCellDM` 27719307e5cSMatthew G. Knepley 27819307e5cSMatthew G. Knepley Collective 27919307e5cSMatthew G. Knepley 280*d6ae5217SJose E. Roman Input Parameters: 28119307e5cSMatthew G. Knepley + dm - The background `DM` for the `DMSwarm` 28219307e5cSMatthew G. Knepley . Nf - The number of swarm fields defined over `dm` 28319307e5cSMatthew G. Knepley . dmFields - The swarm field names for the `dm` fields 28419307e5cSMatthew G. Knepley . Nfc - The number of swarm fields to use for coordinates over `dm` 28519307e5cSMatthew G. Knepley - coordFields - The swarm field names for the `dm` coordinate fields 28619307e5cSMatthew G. Knepley 28719307e5cSMatthew G. Knepley Output Parameter: 28819307e5cSMatthew G. Knepley . celldm - The new `DMSwarmCellDM` 28919307e5cSMatthew G. Knepley 29019307e5cSMatthew G. Knepley Level: advanced 29119307e5cSMatthew G. Knepley 29219307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DMSWARM`, `DMSetType()` 29319307e5cSMatthew G. Knepley @*/ 29419307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMCreate(DM dm, PetscInt Nf, const char *dmFields[], PetscInt Nfc, const char *coordFields[], DMSwarmCellDM *celldm) 29519307e5cSMatthew G. Knepley { 29619307e5cSMatthew G. Knepley DMSwarmCellDM b; 29719307e5cSMatthew G. Knepley const char *name; 29819307e5cSMatthew G. Knepley char cellid[PETSC_MAX_PATH_LEN]; 29919307e5cSMatthew G. Knepley 30019307e5cSMatthew G. Knepley PetscFunctionBegin; 30119307e5cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 30219307e5cSMatthew G. Knepley if (Nf) PetscAssertPointer(dmFields, 3); 30319307e5cSMatthew G. Knepley if (Nfc) PetscAssertPointer(coordFields, 5); 30419307e5cSMatthew G. Knepley PetscCall(DMInitializePackage()); 30519307e5cSMatthew G. Knepley 30619307e5cSMatthew G. Knepley PetscCall(PetscHeaderCreate(b, DMSWARMCELLDM_CLASSID, "DMSwarmCellDM", "Background DM for a Swarm", "DM", PetscObjectComm((PetscObject)dm), DMSwarmCellDMDestroy, DMSwarmCellDMView)); 30719307e5cSMatthew G. Knepley PetscCall(PetscObjectGetName((PetscObject)dm, &name)); 30819307e5cSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)b, name)); 30919307e5cSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dm)); 31019307e5cSMatthew G. Knepley b->dm = dm; 31119307e5cSMatthew G. Knepley b->Nf = Nf; 31219307e5cSMatthew G. Knepley b->Nfc = Nfc; 31319307e5cSMatthew G. Knepley PetscCall(PetscMalloc1(b->Nf, &b->dmFields)); 31419307e5cSMatthew G. Knepley for (PetscInt f = 0; f < b->Nf; ++f) PetscCall(PetscStrallocpy(dmFields[f], &b->dmFields[f])); 31519307e5cSMatthew G. Knepley PetscCall(PetscMalloc1(b->Nfc, &b->coordFields)); 31619307e5cSMatthew G. Knepley for (PetscInt f = 0; f < b->Nfc; ++f) PetscCall(PetscStrallocpy(coordFields[f], &b->coordFields[f])); 31719307e5cSMatthew G. Knepley PetscCall(PetscSNPrintf(cellid, PETSC_MAX_PATH_LEN, "%s_cellid", name)); 31819307e5cSMatthew G. Knepley PetscCall(PetscStrallocpy(cellid, &b->cellid)); 31919307e5cSMatthew G. Knepley *celldm = b; 32019307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 32119307e5cSMatthew G. Knepley } 32219307e5cSMatthew G. Knepley 3230e2ec84fSDave May /* Coordinate insertition/addition API */ 324cc4c1da9SBarry Smith /*@ 32520f4b53cSBarry Smith DMSwarmSetPointsUniformCoordinates - Set point coordinates in a `DMSWARM` on a regular (ijk) grid 3260e2ec84fSDave May 32720f4b53cSBarry Smith Collective 3280e2ec84fSDave May 32960225df5SJacob Faibussowitsch Input Parameters: 33019307e5cSMatthew G. Knepley + sw - the `DMSWARM` 3310e2ec84fSDave May . min - minimum coordinate values in the x, y, z directions (array of length dim) 3320e2ec84fSDave May . max - maximum coordinate values in the x, y, z directions (array of length dim) 3330e2ec84fSDave May . npoints - number of points in each spatial direction (array of length dim) 33420f4b53cSBarry Smith - mode - indicates whether to append points to the swarm (`ADD_VALUES`), or over-ride existing points (`INSERT_VALUES`) 3350e2ec84fSDave May 3360e2ec84fSDave May Level: beginner 3370e2ec84fSDave May 3380e2ec84fSDave May Notes: 33920f4b53cSBarry Smith When using mode = `INSERT_VALUES`, this method will reset the number of particles in the `DMSWARM` 340a3b724e8SBarry Smith to be `npoints[0]` x `npoints[1]` (2D) or `npoints[0]` x `npoints[1]` x `npoints[2]` (3D). When using mode = `ADD_VALUES`, 34120f4b53cSBarry Smith new points will be appended to any already existing in the `DMSWARM` 3420e2ec84fSDave May 34320f4b53cSBarry Smith .seealso: `DM`, `DMSWARM`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType` 3440e2ec84fSDave May @*/ 34519307e5cSMatthew G. Knepley PetscErrorCode DMSwarmSetPointsUniformCoordinates(DM sw, PetscReal min[], PetscReal max[], PetscInt npoints[], InsertMode mode) 346d71ae5a4SJacob Faibussowitsch { 347c448b993SMatthew G. Knepley PetscReal lmin[] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 348c448b993SMatthew G. Knepley PetscReal lmax[] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 34919307e5cSMatthew G. Knepley PetscInt i, j, k, bs, b, n_estimate, n_curr, n_new_est, p, n_found, Nfc; 3500e2ec84fSDave May const PetscScalar *_coor; 35119307e5cSMatthew G. Knepley DMSwarmCellDM celldm; 35219307e5cSMatthew G. Knepley DM dm; 3530e2ec84fSDave May PetscReal dx[3]; 3542e3d3761SDave May PetscInt _npoints[] = {0, 0, 1}; 3550e2ec84fSDave May Vec pos; 3560e2ec84fSDave May PetscScalar *_pos; 3570e2ec84fSDave May PetscReal *swarm_coor; 3580e2ec84fSDave May PetscInt *swarm_cellid; 3590e2ec84fSDave May PetscSF sfcell = NULL; 3600e2ec84fSDave May const PetscSFNode *LA_sfcell; 36119307e5cSMatthew G. Knepley const char **coordFields, *cellid; 3620e2ec84fSDave May 3630e2ec84fSDave May PetscFunctionBegin; 36419307e5cSMatthew G. Knepley DMSWARMPICVALID(sw); 36519307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm)); 36619307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields)); 36719307e5cSMatthew G. Knepley PetscCheck(Nfc == 1, PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "We only support a single coordinate field right now, not %" PetscInt_FMT, Nfc); 36819307e5cSMatthew G. Knepley 36919307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetDM(celldm, &dm)); 37019307e5cSMatthew G. Knepley PetscCall(DMGetLocalBoundingBox(dm, lmin, lmax)); 37119307e5cSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &bs)); 3720e2ec84fSDave May 3730e2ec84fSDave May for (b = 0; b < bs; b++) { 37471844bb8SDave May if (npoints[b] > 1) { 3750e2ec84fSDave May dx[b] = (max[b] - min[b]) / ((PetscReal)(npoints[b] - 1)); 37671844bb8SDave May } else { 37771844bb8SDave May dx[b] = 0.0; 37871844bb8SDave May } 3792e3d3761SDave May _npoints[b] = npoints[b]; 3800e2ec84fSDave May } 3810e2ec84fSDave May 3820e2ec84fSDave May /* determine number of points living in the bounding box */ 3830e2ec84fSDave May n_estimate = 0; 3842e3d3761SDave May for (k = 0; k < _npoints[2]; k++) { 3852e3d3761SDave May for (j = 0; j < _npoints[1]; j++) { 3862e3d3761SDave May for (i = 0; i < _npoints[0]; i++) { 3870e2ec84fSDave May PetscReal xp[] = {0.0, 0.0, 0.0}; 3880e2ec84fSDave May PetscInt ijk[3]; 3890e2ec84fSDave May PetscBool point_inside = PETSC_TRUE; 3900e2ec84fSDave May 3910e2ec84fSDave May ijk[0] = i; 3920e2ec84fSDave May ijk[1] = j; 3930e2ec84fSDave May ijk[2] = k; 394ad540459SPierre Jolivet for (b = 0; b < bs; b++) xp[b] = min[b] + ijk[b] * dx[b]; 3950e2ec84fSDave May for (b = 0; b < bs; b++) { 396c448b993SMatthew G. Knepley if (xp[b] < lmin[b]) point_inside = PETSC_FALSE; 397c448b993SMatthew G. Knepley if (xp[b] > lmax[b]) point_inside = PETSC_FALSE; 3980e2ec84fSDave May } 399ad540459SPierre Jolivet if (point_inside) n_estimate++; 4000e2ec84fSDave May } 4010e2ec84fSDave May } 4020e2ec84fSDave May } 4030e2ec84fSDave May 4040e2ec84fSDave May /* create candidate list */ 4059566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF, &pos)); 4069566063dSJacob Faibussowitsch PetscCall(VecSetSizes(pos, bs * n_estimate, PETSC_DECIDE)); 4079566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(pos, bs)); 4089566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(pos)); 4099566063dSJacob Faibussowitsch PetscCall(VecGetArray(pos, &_pos)); 4100e2ec84fSDave May 4110e2ec84fSDave May n_estimate = 0; 4122e3d3761SDave May for (k = 0; k < _npoints[2]; k++) { 4132e3d3761SDave May for (j = 0; j < _npoints[1]; j++) { 4142e3d3761SDave May for (i = 0; i < _npoints[0]; i++) { 4150e2ec84fSDave May PetscReal xp[] = {0.0, 0.0, 0.0}; 4160e2ec84fSDave May PetscInt ijk[3]; 4170e2ec84fSDave May PetscBool point_inside = PETSC_TRUE; 4180e2ec84fSDave May 4190e2ec84fSDave May ijk[0] = i; 4200e2ec84fSDave May ijk[1] = j; 4210e2ec84fSDave May ijk[2] = k; 422ad540459SPierre Jolivet for (b = 0; b < bs; b++) xp[b] = min[b] + ijk[b] * dx[b]; 4230e2ec84fSDave May for (b = 0; b < bs; b++) { 424c448b993SMatthew G. Knepley if (xp[b] < lmin[b]) point_inside = PETSC_FALSE; 425c448b993SMatthew G. Knepley if (xp[b] > lmax[b]) point_inside = PETSC_FALSE; 4260e2ec84fSDave May } 4270e2ec84fSDave May if (point_inside) { 428ad540459SPierre Jolivet for (b = 0; b < bs; b++) _pos[bs * n_estimate + b] = xp[b]; 4290e2ec84fSDave May n_estimate++; 4300e2ec84fSDave May } 4310e2ec84fSDave May } 4320e2ec84fSDave May } 4330e2ec84fSDave May } 4349566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(pos, &_pos)); 4350e2ec84fSDave May 4360e2ec84fSDave May /* locate points */ 43719307e5cSMatthew G. Knepley PetscCall(DMLocatePoints(dm, pos, DM_POINTLOCATION_NONE, &sfcell)); 4389566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sfcell, NULL, NULL, NULL, &LA_sfcell)); 4390e2ec84fSDave May n_found = 0; 4400e2ec84fSDave May for (p = 0; p < n_estimate; p++) { 441ad540459SPierre Jolivet if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) n_found++; 4420e2ec84fSDave May } 4430e2ec84fSDave May 4440e2ec84fSDave May /* adjust size */ 4450e2ec84fSDave May if (mode == ADD_VALUES) { 44619307e5cSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &n_curr)); 4470e2ec84fSDave May n_new_est = n_curr + n_found; 44819307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1)); 4490e2ec84fSDave May } 4500e2ec84fSDave May if (mode == INSERT_VALUES) { 4510e2ec84fSDave May n_curr = 0; 4520e2ec84fSDave May n_new_est = n_found; 45319307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1)); 4540e2ec84fSDave May } 4550e2ec84fSDave May 4560e2ec84fSDave May /* initialize new coords, cell owners, pid */ 45719307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid)); 4589566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(pos, &_coor)); 45919307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor)); 46019307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 4610e2ec84fSDave May n_found = 0; 4620e2ec84fSDave May for (p = 0; p < n_estimate; p++) { 4630e2ec84fSDave May if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) { 464ad540459SPierre Jolivet for (b = 0; b < bs; b++) swarm_coor[bs * (n_curr + n_found) + b] = PetscRealPart(_coor[bs * p + b]); 4650e2ec84fSDave May swarm_cellid[n_curr + n_found] = LA_sfcell[p].index; 4660e2ec84fSDave May n_found++; 4670e2ec84fSDave May } 4680e2ec84fSDave May } 46919307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 47019307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor)); 4719566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(pos, &_coor)); 4720e2ec84fSDave May 4739566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfcell)); 4749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&pos)); 4753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4760e2ec84fSDave May } 4770e2ec84fSDave May 478cc4c1da9SBarry Smith /*@ 47920f4b53cSBarry Smith DMSwarmSetPointCoordinates - Set point coordinates in a `DMSWARM` from a user defined list 4800e2ec84fSDave May 48120f4b53cSBarry Smith Collective 4820e2ec84fSDave May 48360225df5SJacob Faibussowitsch Input Parameters: 48419307e5cSMatthew G. Knepley + sw - the `DMSWARM` 4850e2ec84fSDave May . npoints - the number of points to insert 4860e2ec84fSDave May . coor - the coordinate values 48720f4b53cSBarry Smith . redundant - if set to `PETSC_TRUE`, it is assumed that `npoints` and `coor` are only valid on rank 0 and should be broadcast to other ranks 48820f4b53cSBarry Smith - mode - indicates whether to append points to the swarm (`ADD_VALUES`), or over-ride existing points (`INSERT_VALUES`) 4890e2ec84fSDave May 4900e2ec84fSDave May Level: beginner 4910e2ec84fSDave May 4920e2ec84fSDave May Notes: 49320f4b53cSBarry Smith If the user has specified `redundant` as `PETSC_FALSE`, the cell `DM` will attempt to locate the coordinates provided by `coor` within 49420f4b53cSBarry Smith its sub-domain. If they any values within `coor` are not located in the sub-domain, they will be ignored and will not get 49520f4b53cSBarry Smith added to the `DMSWARM`. 4960e2ec84fSDave May 49720f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType`, `DMSwarmSetPointsUniformCoordinates()` 4980e2ec84fSDave May @*/ 49919307e5cSMatthew G. Knepley PetscErrorCode DMSwarmSetPointCoordinates(DM sw, PetscInt npoints, PetscReal coor[], PetscBool redundant, InsertMode mode) 500d71ae5a4SJacob Faibussowitsch { 5010e2ec84fSDave May PetscReal gmin[] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 5020e2ec84fSDave May PetscReal gmax[] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 5030e2ec84fSDave May PetscInt i, N, bs, b, n_estimate, n_curr, n_new_est, p, n_found; 5040e2ec84fSDave May Vec coorlocal; 5050e2ec84fSDave May const PetscScalar *_coor; 50619307e5cSMatthew G. Knepley DMSwarmCellDM celldm; 50719307e5cSMatthew G. Knepley DM dm; 5080e2ec84fSDave May Vec pos; 5090e2ec84fSDave May PetscScalar *_pos; 5100e2ec84fSDave May PetscReal *swarm_coor; 5110e2ec84fSDave May PetscInt *swarm_cellid; 5120e2ec84fSDave May PetscSF sfcell = NULL; 5130e2ec84fSDave May const PetscSFNode *LA_sfcell; 5140e2ec84fSDave May PetscReal *my_coor; 51519307e5cSMatthew G. Knepley PetscInt my_npoints, Nfc; 5160e2ec84fSDave May PetscMPIInt rank; 5170e2ec84fSDave May MPI_Comm comm; 51819307e5cSMatthew G. Knepley const char **coordFields, *cellid; 5190e2ec84fSDave May 5200e2ec84fSDave May PetscFunctionBegin; 52119307e5cSMatthew G. Knepley DMSWARMPICVALID(sw); 52219307e5cSMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)sw, &comm)); 5239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5240e2ec84fSDave May 52519307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm)); 52619307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields)); 52719307e5cSMatthew G. Knepley PetscCheck(Nfc == 1, PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "We only support a single coordinate field right now, not %" PetscInt_FMT, Nfc); 52819307e5cSMatthew G. Knepley 52919307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetDM(celldm, &dm)); 53019307e5cSMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coorlocal)); 5319566063dSJacob Faibussowitsch PetscCall(VecGetSize(coorlocal, &N)); 5329566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(coorlocal, &bs)); 5330e2ec84fSDave May N = N / bs; 5349566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(coorlocal, &_coor)); 5350e2ec84fSDave May for (i = 0; i < N; i++) { 5360e2ec84fSDave May for (b = 0; b < bs; b++) { 537a5f152d1SDave May gmin[b] = PetscMin(gmin[b], PetscRealPart(_coor[bs * i + b])); 538a5f152d1SDave May gmax[b] = PetscMax(gmax[b], PetscRealPart(_coor[bs * i + b])); 5390e2ec84fSDave May } 5400e2ec84fSDave May } 5419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(coorlocal, &_coor)); 5420e2ec84fSDave May 5430e2ec84fSDave May /* broadcast points from rank 0 if requested */ 5440e2ec84fSDave May if (redundant) { 5456497c311SBarry Smith PetscMPIInt imy; 5466497c311SBarry Smith 5470e2ec84fSDave May my_npoints = npoints; 5489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&my_npoints, 1, MPIU_INT, 0, comm)); 5490e2ec84fSDave May 5500e2ec84fSDave May if (rank > 0) { /* allocate space */ 5519566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bs * my_npoints, &my_coor)); 5520e2ec84fSDave May } else { 5530e2ec84fSDave May my_coor = coor; 5540e2ec84fSDave May } 5556497c311SBarry Smith PetscCall(PetscMPIIntCast(bs * my_npoints, &imy)); 5566497c311SBarry Smith PetscCallMPI(MPI_Bcast(my_coor, imy, MPIU_REAL, 0, comm)); 5570e2ec84fSDave May } else { 5580e2ec84fSDave May my_npoints = npoints; 5590e2ec84fSDave May my_coor = coor; 5600e2ec84fSDave May } 5610e2ec84fSDave May 5620e2ec84fSDave May /* determine the number of points living in the bounding box */ 5630e2ec84fSDave May n_estimate = 0; 5640e2ec84fSDave May for (i = 0; i < my_npoints; i++) { 5650e2ec84fSDave May PetscBool point_inside = PETSC_TRUE; 5660e2ec84fSDave May 5670e2ec84fSDave May for (b = 0; b < bs; b++) { 568ad540459SPierre Jolivet if (my_coor[bs * i + b] < gmin[b]) point_inside = PETSC_FALSE; 569ad540459SPierre Jolivet if (my_coor[bs * i + b] > gmax[b]) point_inside = PETSC_FALSE; 5700e2ec84fSDave May } 571ad540459SPierre Jolivet if (point_inside) n_estimate++; 5720e2ec84fSDave May } 5730e2ec84fSDave May 5740e2ec84fSDave May /* create candidate list */ 5759566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF, &pos)); 5769566063dSJacob Faibussowitsch PetscCall(VecSetSizes(pos, bs * n_estimate, PETSC_DECIDE)); 5779566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(pos, bs)); 5789566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(pos)); 5799566063dSJacob Faibussowitsch PetscCall(VecGetArray(pos, &_pos)); 5800e2ec84fSDave May 5810e2ec84fSDave May n_estimate = 0; 5820e2ec84fSDave May for (i = 0; i < my_npoints; i++) { 5830e2ec84fSDave May PetscBool point_inside = PETSC_TRUE; 5840e2ec84fSDave May 5850e2ec84fSDave May for (b = 0; b < bs; b++) { 586ad540459SPierre Jolivet if (my_coor[bs * i + b] < gmin[b]) point_inside = PETSC_FALSE; 587ad540459SPierre Jolivet if (my_coor[bs * i + b] > gmax[b]) point_inside = PETSC_FALSE; 5880e2ec84fSDave May } 5890e2ec84fSDave May if (point_inside) { 590ad540459SPierre Jolivet for (b = 0; b < bs; b++) _pos[bs * n_estimate + b] = my_coor[bs * i + b]; 5910e2ec84fSDave May n_estimate++; 5920e2ec84fSDave May } 5930e2ec84fSDave May } 5949566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(pos, &_pos)); 5950e2ec84fSDave May 5960e2ec84fSDave May /* locate points */ 59719307e5cSMatthew G. Knepley PetscCall(DMLocatePoints(dm, pos, DM_POINTLOCATION_NONE, &sfcell)); 5980e2ec84fSDave May 5999566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sfcell, NULL, NULL, NULL, &LA_sfcell)); 6000e2ec84fSDave May n_found = 0; 6010e2ec84fSDave May for (p = 0; p < n_estimate; p++) { 602ad540459SPierre Jolivet if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) n_found++; 6030e2ec84fSDave May } 6040e2ec84fSDave May 6050e2ec84fSDave May /* adjust size */ 6060e2ec84fSDave May if (mode == ADD_VALUES) { 60719307e5cSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &n_curr)); 6080e2ec84fSDave May n_new_est = n_curr + n_found; 60919307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1)); 6100e2ec84fSDave May } 6110e2ec84fSDave May if (mode == INSERT_VALUES) { 6120e2ec84fSDave May n_curr = 0; 6130e2ec84fSDave May n_new_est = n_found; 61419307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1)); 6150e2ec84fSDave May } 6160e2ec84fSDave May 6170e2ec84fSDave May /* initialize new coords, cell owners, pid */ 61819307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid)); 6199566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(pos, &_coor)); 62019307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor)); 62119307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 6220e2ec84fSDave May n_found = 0; 6230e2ec84fSDave May for (p = 0; p < n_estimate; p++) { 6240e2ec84fSDave May if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) { 625ad540459SPierre Jolivet for (b = 0; b < bs; b++) swarm_coor[bs * (n_curr + n_found) + b] = PetscRealPart(_coor[bs * p + b]); 6260e2ec84fSDave May swarm_cellid[n_curr + n_found] = LA_sfcell[p].index; 6270e2ec84fSDave May n_found++; 6280e2ec84fSDave May } 6290e2ec84fSDave May } 63019307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 63119307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor)); 6329566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(pos, &_coor)); 6330e2ec84fSDave May 6340e2ec84fSDave May if (redundant) { 63548a46eb9SPierre Jolivet if (rank > 0) PetscCall(PetscFree(my_coor)); 6360e2ec84fSDave May } 6379566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfcell)); 6389566063dSJacob Faibussowitsch PetscCall(VecDestroy(&pos)); 6393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6400e2ec84fSDave May } 6410e2ec84fSDave May 6420e2ec84fSDave May extern PetscErrorCode private_DMSwarmInsertPointsUsingCellDM_DA(DM, DM, DMSwarmPICLayoutType, PetscInt); 6430e2ec84fSDave May extern PetscErrorCode private_DMSwarmInsertPointsUsingCellDM_PLEX(DM, DM, DMSwarmPICLayoutType, PetscInt); 6440e2ec84fSDave May 645cc4c1da9SBarry Smith /*@ 6460e2ec84fSDave May DMSwarmInsertPointsUsingCellDM - Insert point coordinates within each cell 6470e2ec84fSDave May 64820f4b53cSBarry Smith Not Collective 6490e2ec84fSDave May 65060225df5SJacob Faibussowitsch Input Parameters: 65120f4b53cSBarry Smith + dm - the `DMSWARM` 65220f4b53cSBarry Smith . layout_type - method used to fill each cell with the cell `DM` 6530e2ec84fSDave May - fill_param - parameter controlling how many points per cell are added (the meaning of this parameter is dependent on the layout type) 6540e2ec84fSDave May 6550e2ec84fSDave May Level: beginner 6560e2ec84fSDave May 6570e2ec84fSDave May Notes: 65820f4b53cSBarry Smith The insert method will reset any previous defined points within the `DMSWARM`. 659e7af74c8SDave May 66020f4b53cSBarry Smith When using a `DMDA` both 2D and 3D are supported for all layout types provided you are using `DMDA_ELEMENT_Q1`. 661e7af74c8SDave May 662a4e35b19SJacob Faibussowitsch When using a `DMPLEX` the following case are supported\: 66320f4b53cSBarry Smith .vb 664ea3d7275SDave May (i) DMSWARMPIC_LAYOUT_REGULAR: 2D (triangle), 665ea3d7275SDave May (ii) DMSWARMPIC_LAYOUT_GAUSS: 2D and 3D provided the cell is a tri/tet or a quad/hex, 666ea3d7275SDave May (iii) DMSWARMPIC_LAYOUT_SUBDIVISION: 2D and 3D for quad/hex and 2D tri. 66720f4b53cSBarry Smith .ve 6680e2ec84fSDave May 66920f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmPICLayoutType`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType` 6700e2ec84fSDave May @*/ 671cc4c1da9SBarry Smith PetscErrorCode DMSwarmInsertPointsUsingCellDM(DM dm, DMSwarmPICLayoutType layout_type, PetscInt fill_param) 672d71ae5a4SJacob Faibussowitsch { 6730e2ec84fSDave May DM celldm; 6740e2ec84fSDave May PetscBool isDA, isPLEX; 6750e2ec84fSDave May 6760e2ec84fSDave May PetscFunctionBegin; 6770e2ec84fSDave May DMSWARMPICVALID(dm); 6789566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &celldm)); 6799566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMDA, &isDA)); 6809566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMPLEX, &isPLEX)); 6810e2ec84fSDave May if (isDA) { 6829566063dSJacob Faibussowitsch PetscCall(private_DMSwarmInsertPointsUsingCellDM_DA(dm, celldm, layout_type, fill_param)); 6830e2ec84fSDave May } else if (isPLEX) { 6849566063dSJacob Faibussowitsch PetscCall(private_DMSwarmInsertPointsUsingCellDM_PLEX(dm, celldm, layout_type, fill_param)); 6850e2ec84fSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only supported for cell DMs of type DMDA and DMPLEX"); 6863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6870e2ec84fSDave May } 6880e2ec84fSDave May 689431382f2SDave May extern PetscErrorCode private_DMSwarmSetPointCoordinatesCellwise_PLEX(DM, DM, PetscInt, PetscReal *); 690431382f2SDave May 691431382f2SDave May /*@C 692431382f2SDave May DMSwarmSetPointCoordinatesCellwise - Insert point coordinates (defined over the reference cell) within each cell 693431382f2SDave May 69420f4b53cSBarry Smith Not Collective 695431382f2SDave May 69660225df5SJacob Faibussowitsch Input Parameters: 69720f4b53cSBarry Smith + dm - the `DMSWARM` 698431382f2SDave May . npoints - the number of points to insert in each cell 699431382f2SDave May - xi - the coordinates (defined in the local coordinate system for each cell) to insert 700431382f2SDave May 701431382f2SDave May Level: beginner 702431382f2SDave May 703431382f2SDave May Notes: 70420f4b53cSBarry Smith The method will reset any previous defined points within the `DMSWARM`. 70520f4b53cSBarry Smith Only supported for `DMPLEX`. If you are using a `DMDA` it is recommended to either use 70620f4b53cSBarry Smith `DMSwarmInsertPointsUsingCellDM()`, or extract and set the coordinates yourself the following code 70720f4b53cSBarry Smith .vb 70820f4b53cSBarry Smith PetscReal *coor; 709d52c2f21SMatthew G. Knepley const char *coordname; 710d52c2f21SMatthew G. Knepley DMSwarmGetCoordinateField(dm, &coordname); 711d52c2f21SMatthew G. Knepley DMSwarmGetField(dm,coordname,NULL,NULL,(void**)&coor); 71220f4b53cSBarry Smith // user code to define the coordinates here 713d52c2f21SMatthew G. Knepley DMSwarmRestoreField(dm,coordname,NULL,NULL,(void**)&coor); 71420f4b53cSBarry Smith .ve 715e7af74c8SDave May 71620f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetCellDM()`, `DMSwarmInsertPointsUsingCellDM()` 717431382f2SDave May @*/ 718cc4c1da9SBarry Smith PetscErrorCode DMSwarmSetPointCoordinatesCellwise(DM dm, PetscInt npoints, PetscReal xi[]) 719d71ae5a4SJacob Faibussowitsch { 720431382f2SDave May DM celldm; 721431382f2SDave May PetscBool isDA, isPLEX; 722431382f2SDave May 7230e2ec84fSDave May PetscFunctionBegin; 724431382f2SDave May DMSWARMPICVALID(dm); 7259566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &celldm)); 7269566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMDA, &isDA)); 7279566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMPLEX, &isPLEX)); 72828b400f6SJacob Faibussowitsch PetscCheck(!isDA, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only supported for cell DMs of type DMPLEX. Recommended you use DMSwarmInsertPointsUsingCellDM()"); 729f7d195e4SLawrence Mitchell if (isPLEX) { 7309566063dSJacob Faibussowitsch PetscCall(private_DMSwarmSetPointCoordinatesCellwise_PLEX(dm, celldm, npoints, xi)); 731431382f2SDave May } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only supported for cell DMs of type DMDA and DMPLEX"); 7323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7330e2ec84fSDave May } 734431382f2SDave May 735cc4c1da9SBarry Smith /*@ 736b799feefSDave May DMSwarmCreatePointPerCellCount - Count the number of points within all cells in the cell DM 7370e2ec84fSDave May 73820f4b53cSBarry Smith Not Collective 7390e2ec84fSDave May 74060225df5SJacob Faibussowitsch Input Parameter: 74119307e5cSMatthew G. Knepley . sw - the `DMSWARM` 7420e2ec84fSDave May 74360225df5SJacob Faibussowitsch Output Parameters: 74420f4b53cSBarry Smith + ncells - the number of cells in the cell `DM` (optional argument, pass `NULL` to ignore) 745b799feefSDave May - count - array of length ncells containing the number of points per cell 7460e2ec84fSDave May 7470e2ec84fSDave May Level: beginner 7480e2ec84fSDave May 7490e2ec84fSDave May Notes: 7500e2ec84fSDave May The array count is allocated internally and must be free'd by the user. 7510e2ec84fSDave May 75220f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType` 7530e2ec84fSDave May @*/ 75419307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCreatePointPerCellCount(DM sw, PetscInt *ncells, PetscInt **count) 755d71ae5a4SJacob Faibussowitsch { 75619307e5cSMatthew G. Knepley DMSwarmCellDM celldm; 757b799feefSDave May PetscBool isvalid; 758b799feefSDave May PetscInt nel; 759b799feefSDave May PetscInt *sum; 76019307e5cSMatthew G. Knepley const char *cellid; 761b799feefSDave May 7620e2ec84fSDave May PetscFunctionBegin; 76319307e5cSMatthew G. Knepley PetscCall(DMSwarmSortGetIsValid(sw, &isvalid)); 764b799feefSDave May nel = 0; 765b799feefSDave May if (isvalid) { 766b799feefSDave May PetscInt e; 767b799feefSDave May 76819307e5cSMatthew G. Knepley PetscCall(DMSwarmSortGetSizes(sw, &nel, NULL)); 769b799feefSDave May 7709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nel, &sum)); 77119307e5cSMatthew G. Knepley for (e = 0; e < nel; e++) PetscCall(DMSwarmSortGetNumberOfPointsPerCell(sw, e, &sum[e])); 772b799feefSDave May } else { 77319307e5cSMatthew G. Knepley DM dm; 774b799feefSDave May PetscBool isda, isplex, isshell; 775b799feefSDave May PetscInt p, npoints; 776b799feefSDave May PetscInt *swarm_cellid; 777b799feefSDave May 778b799feefSDave May /* get the number of cells */ 77919307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm)); 78019307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetDM(celldm, &dm)); 78119307e5cSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda)); 78219307e5cSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMPLEX, &isplex)); 78319307e5cSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell)); 784b799feefSDave May if (isda) { 785b799feefSDave May PetscInt _nel, _npe; 786b799feefSDave May const PetscInt *_element; 787b799feefSDave May 78819307e5cSMatthew G. Knepley PetscCall(DMDAGetElements(dm, &_nel, &_npe, &_element)); 789b799feefSDave May nel = _nel; 79019307e5cSMatthew G. Knepley PetscCall(DMDARestoreElements(dm, &_nel, &_npe, &_element)); 791b799feefSDave May } else if (isplex) { 792b799feefSDave May PetscInt ps, pe; 793b799feefSDave May 79419307e5cSMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dm, 0, &ps, &pe)); 795b799feefSDave May nel = pe - ps; 796b799feefSDave May } else if (isshell) { 797b799feefSDave May PetscErrorCode (*method_DMShellGetNumberOfCells)(DM, PetscInt *); 798b799feefSDave May 79919307e5cSMatthew G. Knepley PetscCall(PetscObjectQueryFunction((PetscObject)dm, "DMGetNumberOfCells_C", &method_DMShellGetNumberOfCells)); 800b799feefSDave May if (method_DMShellGetNumberOfCells) { 80119307e5cSMatthew G. Knepley PetscCall(method_DMShellGetNumberOfCells(dm, &nel)); 8029371c9d4SSatish Balay } else 80319307e5cSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "Cannot determine the number of cells for the DMSHELL object. User must provide a method via PetscObjectComposeFunction( (PetscObject)shelldm, \"DMGetNumberOfCells_C\", your_function_to_compute_number_of_cells);"); 80419307e5cSMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "Cannot determine the number of cells for a DM not of type DA, PLEX or SHELL"); 805b799feefSDave May 8069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nel, &sum)); 8079566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(sum, nel)); 80819307e5cSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &npoints)); 80919307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid)); 81019307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 811b799feefSDave May for (p = 0; p < npoints; p++) { 812ad540459SPierre Jolivet if (swarm_cellid[p] != DMLOCATEPOINT_POINT_NOT_FOUND) sum[swarm_cellid[p]]++; 813b799feefSDave May } 81419307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 815b799feefSDave May } 816ad540459SPierre Jolivet if (ncells) *ncells = nel; 817b799feefSDave May *count = sum; 8183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8190e2ec84fSDave May } 82035b38c60SMatthew G. Knepley 82135b38c60SMatthew G. Knepley /*@ 82235b38c60SMatthew G. Knepley DMSwarmGetNumSpecies - Get the number of particle species 82335b38c60SMatthew G. Knepley 82420f4b53cSBarry Smith Not Collective 82535b38c60SMatthew G. Knepley 82660225df5SJacob Faibussowitsch Input Parameter: 82760225df5SJacob Faibussowitsch . sw - the `DMSWARM` 82835b38c60SMatthew G. Knepley 82960225df5SJacob Faibussowitsch Output Parameters: 83035b38c60SMatthew G. Knepley . Ns - the number of species 83135b38c60SMatthew G. Knepley 83235b38c60SMatthew G. Knepley Level: intermediate 83335b38c60SMatthew G. Knepley 83420f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetNumSpecies()`, `DMSwarmSetType()`, `DMSwarmType` 83535b38c60SMatthew G. Knepley @*/ 836d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmGetNumSpecies(DM sw, PetscInt *Ns) 837d71ae5a4SJacob Faibussowitsch { 83835b38c60SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data; 83935b38c60SMatthew G. Knepley 84035b38c60SMatthew G. Knepley PetscFunctionBegin; 84135b38c60SMatthew G. Knepley *Ns = swarm->Ns; 8423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 84335b38c60SMatthew G. Knepley } 84435b38c60SMatthew G. Knepley 84535b38c60SMatthew G. Knepley /*@ 84635b38c60SMatthew G. Knepley DMSwarmSetNumSpecies - Set the number of particle species 84735b38c60SMatthew G. Knepley 84820f4b53cSBarry Smith Not Collective 84935b38c60SMatthew G. Knepley 85060225df5SJacob Faibussowitsch Input Parameters: 85160225df5SJacob Faibussowitsch + sw - the `DMSWARM` 85235b38c60SMatthew G. Knepley - Ns - the number of species 85335b38c60SMatthew G. Knepley 85435b38c60SMatthew G. Knepley Level: intermediate 85535b38c60SMatthew G. Knepley 85620f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmGetNumSpecies()`, `DMSwarmSetType()`, `DMSwarmType` 85735b38c60SMatthew G. Knepley @*/ 858d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmSetNumSpecies(DM sw, PetscInt Ns) 859d71ae5a4SJacob Faibussowitsch { 86035b38c60SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data; 86135b38c60SMatthew G. Knepley 86235b38c60SMatthew G. Knepley PetscFunctionBegin; 86335b38c60SMatthew G. Knepley swarm->Ns = Ns; 8643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86535b38c60SMatthew G. Knepley } 86635b38c60SMatthew G. Knepley 86735b38c60SMatthew G. Knepley /*@C 8686c5a79ebSMatthew G. Knepley DMSwarmGetCoordinateFunction - Get the function setting initial particle positions, if it exists 8696c5a79ebSMatthew G. Knepley 87020f4b53cSBarry Smith Not Collective 8716c5a79ebSMatthew G. Knepley 87260225df5SJacob Faibussowitsch Input Parameter: 87360225df5SJacob Faibussowitsch . sw - the `DMSWARM` 8746c5a79ebSMatthew G. Knepley 8756c5a79ebSMatthew G. Knepley Output Parameter: 8768434afd1SBarry Smith . coordFunc - the function setting initial particle positions, or `NULL`, see `PetscSimplePointFn` for the calling sequence 8776c5a79ebSMatthew G. Knepley 8786c5a79ebSMatthew G. Knepley Level: intermediate 8796c5a79ebSMatthew G. Knepley 8808434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmSetCoordinateFunction()`, `DMSwarmGetVelocityFunction()`, `DMSwarmInitializeCoordinates()`, `PetscSimplePointFn` 8816c5a79ebSMatthew G. Knepley @*/ 8828434afd1SBarry Smith PetscErrorCode DMSwarmGetCoordinateFunction(DM sw, PetscSimplePointFn **coordFunc) 883d71ae5a4SJacob Faibussowitsch { 8846c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data; 8856c5a79ebSMatthew G. Knepley 8866c5a79ebSMatthew G. Knepley PetscFunctionBegin; 8876c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1); 8884f572ea9SToby Isaac PetscAssertPointer(coordFunc, 2); 8896c5a79ebSMatthew G. Knepley *coordFunc = swarm->coordFunc; 8903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8916c5a79ebSMatthew G. Knepley } 8926c5a79ebSMatthew G. Knepley 8936c5a79ebSMatthew G. Knepley /*@C 8946c5a79ebSMatthew G. Knepley DMSwarmSetCoordinateFunction - Set the function setting initial particle positions 8956c5a79ebSMatthew G. Knepley 89620f4b53cSBarry Smith Not Collective 8976c5a79ebSMatthew G. Knepley 89860225df5SJacob Faibussowitsch Input Parameters: 89960225df5SJacob Faibussowitsch + sw - the `DMSWARM` 9008434afd1SBarry Smith - coordFunc - the function setting initial particle positions, see `PetscSimplePointFn` for the calling sequence 9016c5a79ebSMatthew G. Knepley 9026c5a79ebSMatthew G. Knepley Level: intermediate 9036c5a79ebSMatthew G. Knepley 9048434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmGetCoordinateFunction()`, `DMSwarmSetVelocityFunction()`, `DMSwarmInitializeCoordinates()`, `PetscSimplePointFn` 9056c5a79ebSMatthew G. Knepley @*/ 9068434afd1SBarry Smith PetscErrorCode DMSwarmSetCoordinateFunction(DM sw, PetscSimplePointFn *coordFunc) 907d71ae5a4SJacob Faibussowitsch { 9086c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data; 9096c5a79ebSMatthew G. Knepley 9106c5a79ebSMatthew G. Knepley PetscFunctionBegin; 9116c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1); 9126c5a79ebSMatthew G. Knepley PetscValidFunction(coordFunc, 2); 9136c5a79ebSMatthew G. Knepley swarm->coordFunc = coordFunc; 9143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9156c5a79ebSMatthew G. Knepley } 9166c5a79ebSMatthew G. Knepley 9176c5a79ebSMatthew G. Knepley /*@C 91860225df5SJacob Faibussowitsch DMSwarmGetVelocityFunction - Get the function setting initial particle velocities, if it exists 9196c5a79ebSMatthew G. Knepley 92020f4b53cSBarry Smith Not Collective 9216c5a79ebSMatthew G. Knepley 92260225df5SJacob Faibussowitsch Input Parameter: 92360225df5SJacob Faibussowitsch . sw - the `DMSWARM` 9246c5a79ebSMatthew G. Knepley 9256c5a79ebSMatthew G. Knepley Output Parameter: 9268434afd1SBarry Smith . velFunc - the function setting initial particle velocities, or `NULL`, see `PetscSimplePointFn` for the calling sequence 9276c5a79ebSMatthew G. Knepley 9286c5a79ebSMatthew G. Knepley Level: intermediate 9296c5a79ebSMatthew G. Knepley 9308434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmSetVelocityFunction()`, `DMSwarmGetCoordinateFunction()`, `DMSwarmInitializeVelocities()`, `PetscSimplePointFn` 9316c5a79ebSMatthew G. Knepley @*/ 9328434afd1SBarry Smith PetscErrorCode DMSwarmGetVelocityFunction(DM sw, PetscSimplePointFn **velFunc) 933d71ae5a4SJacob Faibussowitsch { 9346c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data; 9356c5a79ebSMatthew G. Knepley 9366c5a79ebSMatthew G. Knepley PetscFunctionBegin; 9376c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1); 9384f572ea9SToby Isaac PetscAssertPointer(velFunc, 2); 9396c5a79ebSMatthew G. Knepley *velFunc = swarm->velFunc; 9403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9416c5a79ebSMatthew G. Knepley } 9426c5a79ebSMatthew G. Knepley 9436c5a79ebSMatthew G. Knepley /*@C 9446c5a79ebSMatthew G. Knepley DMSwarmSetVelocityFunction - Set the function setting initial particle velocities 9456c5a79ebSMatthew G. Knepley 94620f4b53cSBarry Smith Not Collective 9476c5a79ebSMatthew G. Knepley 94860225df5SJacob Faibussowitsch Input Parameters: 949a4e35b19SJacob Faibussowitsch + sw - the `DMSWARM` 9508434afd1SBarry Smith - velFunc - the function setting initial particle velocities, see `PetscSimplePointFn` for the calling sequence 9516c5a79ebSMatthew G. Knepley 9526c5a79ebSMatthew G. Knepley Level: intermediate 9536c5a79ebSMatthew G. Knepley 9548434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmGetVelocityFunction()`, `DMSwarmSetCoordinateFunction()`, `DMSwarmInitializeVelocities()`, `PetscSimplePointFn` 9556c5a79ebSMatthew G. Knepley @*/ 9568434afd1SBarry Smith PetscErrorCode DMSwarmSetVelocityFunction(DM sw, PetscSimplePointFn *velFunc) 957d71ae5a4SJacob Faibussowitsch { 9586c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data; 9596c5a79ebSMatthew G. Knepley 9606c5a79ebSMatthew G. Knepley PetscFunctionBegin; 9616c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1); 9626c5a79ebSMatthew G. Knepley PetscValidFunction(velFunc, 2); 9636c5a79ebSMatthew G. Knepley swarm->velFunc = velFunc; 9643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9656c5a79ebSMatthew G. Knepley } 9666c5a79ebSMatthew G. Knepley 9676c5a79ebSMatthew G. Knepley /*@C 96835b38c60SMatthew G. Knepley DMSwarmComputeLocalSize - Compute the local number and distribution of particles based upon a density function 96935b38c60SMatthew G. Knepley 97020f4b53cSBarry Smith Not Collective 97135b38c60SMatthew G. Knepley 97235b38c60SMatthew G. Knepley Input Parameters: 97320f4b53cSBarry Smith + sw - The `DMSWARM` 97435b38c60SMatthew G. Knepley . N - The target number of particles 97535b38c60SMatthew G. Knepley - density - The density field for the particle layout, normalized to unity 97635b38c60SMatthew G. Knepley 97735b38c60SMatthew G. Knepley Level: advanced 97835b38c60SMatthew G. Knepley 97920f4b53cSBarry Smith Note: 98020f4b53cSBarry Smith One particle will be created for each species. 98120f4b53cSBarry Smith 98220f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSizeFromOptions()` 98335b38c60SMatthew G. Knepley @*/ 984d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmComputeLocalSize(DM sw, PetscInt N, PetscProbFunc density) 985d71ae5a4SJacob Faibussowitsch { 98635b38c60SMatthew G. Knepley DM dm; 98719307e5cSMatthew G. Knepley DMSwarmCellDM celldm; 98835b38c60SMatthew G. Knepley PetscQuadrature quad; 98935b38c60SMatthew G. Knepley const PetscReal *xq, *wq; 990ea7032a0SMatthew G. Knepley PetscReal *n_int; 99119307e5cSMatthew G. Knepley PetscInt *npc_s, *swarm_cellid, Ni; 992ea7032a0SMatthew G. Knepley PetscReal gmin[3], gmax[3], xi0[3]; 993ea7032a0SMatthew G. Knepley PetscInt Ns, cStart, cEnd, c, dim, d, Nq, q, Np = 0, p, s; 99435b38c60SMatthew G. Knepley PetscBool simplex; 99519307e5cSMatthew G. Knepley const char *cellid; 99635b38c60SMatthew G. Knepley 99735b38c60SMatthew G. Knepley PetscFunctionBegin; 9989566063dSJacob Faibussowitsch PetscCall(DMSwarmGetNumSpecies(sw, &Ns)); 9999566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(sw, &dm)); 10009566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1001ea7032a0SMatthew G. Knepley PetscCall(DMGetBoundingBox(dm, gmin, gmax)); 10029566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 10039566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 10046858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(dm)); 10059566063dSJacob Faibussowitsch if (simplex) PetscCall(PetscDTStroudConicalQuadrature(dim, 1, 5, -1.0, 1.0, &quad)); 10069566063dSJacob Faibussowitsch else PetscCall(PetscDTGaussTensorQuadrature(dim, 1, 5, -1.0, 1.0, &quad)); 10079566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, &xq, &wq)); 1008ea7032a0SMatthew G. Knepley PetscCall(PetscCalloc2(Ns, &n_int, (cEnd - cStart) * Ns, &npc_s)); 100935b38c60SMatthew G. Knepley /* Integrate the density function to get the number of particles in each cell */ 101035b38c60SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0; 101135b38c60SMatthew G. Knepley for (c = 0; c < cEnd - cStart; ++c) { 101235b38c60SMatthew G. Knepley const PetscInt cell = c + cStart; 1013ea7032a0SMatthew G. Knepley PetscReal v0[3], J[9], invJ[9], detJ, detJp = 2. / (gmax[0] - gmin[0]), xr[3], den; 101435b38c60SMatthew G. Knepley 1015ea7032a0SMatthew G. Knepley /* Have to transform quadrature points/weights to cell domain */ 10169566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, cell, NULL, v0, J, invJ, &detJ)); 1017ea7032a0SMatthew G. Knepley PetscCall(PetscArrayzero(n_int, Ns)); 101835b38c60SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 101935b38c60SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, &xq[q * dim], xr); 1020ea7032a0SMatthew G. Knepley /* Have to transform mesh to domain of definition of PDF, [-1, 1], and weight PDF by |J|/2 */ 1021ea7032a0SMatthew G. Knepley xr[0] = detJp * (xr[0] - gmin[0]) - 1.; 1022ea7032a0SMatthew G. Knepley 1023ea7032a0SMatthew G. Knepley for (s = 0; s < Ns; ++s) { 1024ea7032a0SMatthew G. Knepley PetscCall(density(xr, NULL, &den)); 1025ea7032a0SMatthew G. Knepley n_int[s] += (detJp * den) * (detJ * wq[q]) / (PetscReal)Ns; 102635b38c60SMatthew G. Knepley } 1027ea7032a0SMatthew G. Knepley } 1028ea7032a0SMatthew G. Knepley for (s = 0; s < Ns; ++s) { 1029ea7032a0SMatthew G. Knepley Ni = N; 1030ea7032a0SMatthew G. Knepley npc_s[c * Ns + s] += (PetscInt)(Ni * n_int[s]); 1031ea7032a0SMatthew G. Knepley Np += npc_s[c * Ns + s]; 1032ea7032a0SMatthew G. Knepley } 103335b38c60SMatthew G. Knepley } 10349566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&quad)); 10359566063dSJacob Faibussowitsch PetscCall(DMSwarmSetLocalSizes(sw, Np, 0)); 103619307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm)); 103719307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid)); 103819307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 103935b38c60SMatthew G. Knepley for (c = 0, p = 0; c < cEnd - cStart; ++c) { 1040ea7032a0SMatthew G. Knepley for (s = 0; s < Ns; ++s) { 104119307e5cSMatthew G. Knepley for (q = 0; q < npc_s[c * Ns + s]; ++q, ++p) swarm_cellid[p] = c; 1042ea7032a0SMatthew G. Knepley } 104335b38c60SMatthew G. Knepley } 104419307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid)); 1045ea7032a0SMatthew G. Knepley PetscCall(PetscFree2(n_int, npc_s)); 10463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 104735b38c60SMatthew G. Knepley } 104835b38c60SMatthew G. Knepley 104935b38c60SMatthew G. Knepley /*@ 105035b38c60SMatthew G. Knepley DMSwarmComputeLocalSizeFromOptions - Compute the local number and distribution of particles based upon a density function determined by options 105135b38c60SMatthew G. Knepley 105220f4b53cSBarry Smith Not Collective 105335b38c60SMatthew G. Knepley 10542fe279fdSBarry Smith Input Parameter: 10552fe279fdSBarry Smith . sw - The `DMSWARM` 105635b38c60SMatthew G. Knepley 105735b38c60SMatthew G. Knepley Level: advanced 105835b38c60SMatthew G. Knepley 105920f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()` 106035b38c60SMatthew G. Knepley @*/ 1061d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmComputeLocalSizeFromOptions(DM sw) 1062d71ae5a4SJacob Faibussowitsch { 106335b38c60SMatthew G. Knepley PetscProbFunc pdf; 106435b38c60SMatthew G. Knepley const char *prefix; 10656c5a79ebSMatthew G. Knepley char funcname[PETSC_MAX_PATH_LEN]; 10666c5a79ebSMatthew G. Knepley PetscInt *N, Ns, dim, n; 10676c5a79ebSMatthew G. Knepley PetscBool flg; 10686c5a79ebSMatthew G. Knepley PetscMPIInt size, rank; 106935b38c60SMatthew G. Knepley 107035b38c60SMatthew G. Knepley PetscFunctionBegin; 10716c5a79ebSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sw), &size)); 10726c5a79ebSMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)sw), &rank)); 10736c5a79ebSMatthew G. Knepley PetscCall(PetscCalloc1(size, &N)); 1074d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)sw), "", "DMSwarm Options", "DMSWARM"); 10756c5a79ebSMatthew G. Knepley n = size; 10766c5a79ebSMatthew G. Knepley PetscCall(PetscOptionsIntArray("-dm_swarm_num_particles", "The target number of particles", "", N, &n, NULL)); 10776c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetNumSpecies(sw, &Ns)); 10789566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-dm_swarm_num_species", "The number of species", "DMSwarmSetNumSpecies", Ns, &Ns, &flg)); 10799566063dSJacob Faibussowitsch if (flg) PetscCall(DMSwarmSetNumSpecies(sw, Ns)); 10806c5a79ebSMatthew G. Knepley PetscCall(PetscOptionsString("-dm_swarm_coordinate_function", "Function to determine particle coordinates", "DMSwarmSetCoordinateFunction", funcname, funcname, sizeof(funcname), &flg)); 1081d0609cedSBarry Smith PetscOptionsEnd(); 10826c5a79ebSMatthew G. Knepley if (flg) { 10838434afd1SBarry Smith PetscSimplePointFn *coordFunc; 108435b38c60SMatthew G. Knepley 10856c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetNumSpecies(sw, &Ns)); 10866c5a79ebSMatthew G. Knepley PetscCall(PetscDLSym(NULL, funcname, (void **)&coordFunc)); 10876c5a79ebSMatthew G. Knepley PetscCheck(coordFunc, PetscObjectComm((PetscObject)sw), PETSC_ERR_ARG_WRONG, "Could not locate function %s", funcname); 10886c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetNumSpecies(sw, &Ns)); 10896c5a79ebSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, N[rank] * Ns, 0)); 10906c5a79ebSMatthew G. Knepley PetscCall(DMSwarmSetCoordinateFunction(sw, coordFunc)); 10916c5a79ebSMatthew G. Knepley } else { 10929566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim)); 10939566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sw, &prefix)); 10949566063dSJacob Faibussowitsch PetscCall(PetscProbCreateFromOptions(dim, prefix, "-dm_swarm_coordinate_density", &pdf, NULL, NULL)); 10956c5a79ebSMatthew G. Knepley PetscCall(DMSwarmComputeLocalSize(sw, N[rank], pdf)); 10966c5a79ebSMatthew G. Knepley } 10976c5a79ebSMatthew G. Knepley PetscCall(PetscFree(N)); 10983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 109935b38c60SMatthew G. Knepley } 110035b38c60SMatthew G. Knepley 110135b38c60SMatthew G. Knepley /*@ 110235b38c60SMatthew G. Knepley DMSwarmInitializeCoordinates - Determine the initial coordinates of particles for a PIC method 110335b38c60SMatthew G. Knepley 110420f4b53cSBarry Smith Not Collective 110535b38c60SMatthew G. Knepley 110620f4b53cSBarry Smith Input Parameter: 110720f4b53cSBarry Smith . sw - The `DMSWARM` 110835b38c60SMatthew G. Knepley 110935b38c60SMatthew G. Knepley Level: advanced 111035b38c60SMatthew G. Knepley 111120f4b53cSBarry Smith Note: 111220f4b53cSBarry Smith Currently, we randomly place particles in their assigned cell 111320f4b53cSBarry Smith 111420f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()`, `DMSwarmInitializeVelocities()` 111535b38c60SMatthew G. Knepley @*/ 1116d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmInitializeCoordinates(DM sw) 1117d71ae5a4SJacob Faibussowitsch { 111819307e5cSMatthew G. Knepley DMSwarmCellDM celldm; 11198434afd1SBarry Smith PetscSimplePointFn *coordFunc; 112035b38c60SMatthew G. Knepley PetscScalar *weight; 11216c5a79ebSMatthew G. Knepley PetscReal *x; 112235b38c60SMatthew G. Knepley PetscInt *species; 11236c5a79ebSMatthew G. Knepley void *ctx; 112435b38c60SMatthew G. Knepley PetscBool removePoints = PETSC_TRUE; 112535b38c60SMatthew G. Knepley PetscDataType dtype; 112619307e5cSMatthew G. Knepley PetscInt Nfc, Np, p, Ns, dim, d, bs; 112719307e5cSMatthew G. Knepley const char **coordFields; 112835b38c60SMatthew G. Knepley 112935b38c60SMatthew G. Knepley PetscFunctionBeginUser; 11306c5a79ebSMatthew G. Knepley PetscCall(DMGetDimension(sw, &dim)); 11316c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &Np)); 11329566063dSJacob Faibussowitsch PetscCall(DMSwarmGetNumSpecies(sw, &Ns)); 11336c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetCoordinateFunction(sw, &coordFunc)); 11346c5a79ebSMatthew G. Knepley 113519307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm)); 113619307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields)); 113719307e5cSMatthew G. Knepley PetscCheck(Nfc == 1, PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "We only support a single coordinate field right now, not %" PetscInt_FMT, Nfc); 113819307e5cSMatthew G. Knepley 113919307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, coordFields[0], &bs, &dtype, (void **)&x)); 11406c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, "w_q", &bs, &dtype, (void **)&weight)); 11416c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, "species", NULL, NULL, (void **)&species)); 11426c5a79ebSMatthew G. Knepley if (coordFunc) { 11436c5a79ebSMatthew G. Knepley PetscCall(DMGetApplicationContext(sw, &ctx)); 11446c5a79ebSMatthew G. Knepley for (p = 0; p < Np; ++p) { 11456c5a79ebSMatthew G. Knepley PetscScalar X[3]; 11466c5a79ebSMatthew G. Knepley 11476c5a79ebSMatthew G. Knepley PetscCall((*coordFunc)(dim, 0., NULL, p, X, ctx)); 11486c5a79ebSMatthew G. Knepley for (d = 0; d < dim; ++d) x[p * dim + d] = PetscRealPart(X[d]); 11496c5a79ebSMatthew G. Knepley weight[p] = 1.0; 11506c5a79ebSMatthew G. Knepley species[p] = p % Ns; 11516c5a79ebSMatthew G. Knepley } 11526c5a79ebSMatthew G. Knepley } else { 11536c5a79ebSMatthew G. Knepley DM dm; 11546c5a79ebSMatthew G. Knepley PetscRandom rnd; 11556c5a79ebSMatthew G. Knepley PetscReal xi0[3]; 11566c5a79ebSMatthew G. Knepley PetscInt cStart, cEnd, c; 11576c5a79ebSMatthew G. Knepley 11589566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(sw, &dm)); 11599566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 1160ea7032a0SMatthew G. Knepley PetscCall(DMGetApplicationContext(sw, &ctx)); 116135b38c60SMatthew G. Knepley 116235b38c60SMatthew G. Knepley /* Set particle position randomly in cell, set weights to 1 */ 11639566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)dm), &rnd)); 11649566063dSJacob Faibussowitsch PetscCall(PetscRandomSetInterval(rnd, -1.0, 1.0)); 11659566063dSJacob Faibussowitsch PetscCall(PetscRandomSetFromOptions(rnd)); 11669566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(sw)); 116735b38c60SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0; 116835b38c60SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 116935b38c60SMatthew G. Knepley PetscReal v0[3], J[9], invJ[9], detJ; 117035b38c60SMatthew G. Knepley PetscInt *pidx, Npc, q; 117135b38c60SMatthew G. Knepley 11729566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(sw, c, &Npc, &pidx)); 11739566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, c, NULL, v0, J, invJ, &detJ)); 117435b38c60SMatthew G. Knepley for (q = 0; q < Npc; ++q) { 117535b38c60SMatthew G. Knepley const PetscInt p = pidx[q]; 117635b38c60SMatthew G. Knepley PetscReal xref[3]; 117735b38c60SMatthew G. Knepley 11789566063dSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscRandomGetValueReal(rnd, &xref[d])); 117935b38c60SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, xref, &x[p * dim]); 118035b38c60SMatthew G. Knepley 1181ea7032a0SMatthew G. Knepley weight[p] = 1.0 / Np; 11826c5a79ebSMatthew G. Knepley species[p] = p % Ns; 118335b38c60SMatthew G. Knepley } 1184fe11354eSMatthew G. Knepley PetscCall(DMSwarmSortRestorePointsPerCell(sw, c, &Npc, &pidx)); 118535b38c60SMatthew G. Knepley } 11869566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&rnd)); 11879566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(sw)); 11886c5a79ebSMatthew G. Knepley } 118919307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, coordFields[0], NULL, NULL, (void **)&x)); 11906c5a79ebSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, "w_q", NULL, NULL, (void **)&weight)); 11919566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(sw, "species", NULL, NULL, (void **)&species)); 11926c5a79ebSMatthew G. Knepley 11939566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate(sw, removePoints)); 11949566063dSJacob Faibussowitsch PetscCall(DMLocalizeCoordinates(sw)); 11953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119635b38c60SMatthew G. Knepley } 119735b38c60SMatthew G. Knepley 119835b38c60SMatthew G. Knepley /*@C 119935b38c60SMatthew G. Knepley DMSwarmInitializeVelocities - Set the initial velocities of particles using a distribution. 120035b38c60SMatthew G. Knepley 120120f4b53cSBarry Smith Collective 120235b38c60SMatthew G. Knepley 120335b38c60SMatthew G. Knepley Input Parameters: 120420f4b53cSBarry Smith + sw - The `DMSWARM` object 120535b38c60SMatthew G. Knepley . sampler - A function which uniformly samples the velocity PDF 120635b38c60SMatthew G. Knepley - v0 - The velocity scale for nondimensionalization for each species 120735b38c60SMatthew G. Knepley 120835b38c60SMatthew G. Knepley Level: advanced 120935b38c60SMatthew G. Knepley 121020f4b53cSBarry Smith Note: 121120f4b53cSBarry Smith If `v0` is zero for the first species, all velocities are set to zero. If it is zero for any other species, the effect will be to give that species zero velocity. 121220f4b53cSBarry Smith 121320f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()`, `DMSwarmInitializeCoordinates()`, `DMSwarmInitializeVelocitiesFromOptions()` 121435b38c60SMatthew G. Knepley @*/ 1215d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmInitializeVelocities(DM sw, PetscProbFunc sampler, const PetscReal v0[]) 1216d71ae5a4SJacob Faibussowitsch { 12178434afd1SBarry Smith PetscSimplePointFn *velFunc; 121835b38c60SMatthew G. Knepley PetscReal *v; 121935b38c60SMatthew G. Knepley PetscInt *species; 12206c5a79ebSMatthew G. Knepley void *ctx; 122135b38c60SMatthew G. Knepley PetscInt dim, Np, p; 122235b38c60SMatthew G. Knepley 122335b38c60SMatthew G. Knepley PetscFunctionBegin; 12246c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetVelocityFunction(sw, &velFunc)); 122535b38c60SMatthew G. Knepley 12269566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim)); 12279566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(sw, &Np)); 12289566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(sw, "velocity", NULL, NULL, (void **)&v)); 12299566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(sw, "species", NULL, NULL, (void **)&species)); 12306c5a79ebSMatthew G. Knepley if (v0[0] == 0.) { 12316c5a79ebSMatthew G. Knepley PetscCall(PetscArrayzero(v, Np * dim)); 12326c5a79ebSMatthew G. Knepley } else if (velFunc) { 12336c5a79ebSMatthew G. Knepley PetscCall(DMGetApplicationContext(sw, &ctx)); 12346c5a79ebSMatthew G. Knepley for (p = 0; p < Np; ++p) { 12356c5a79ebSMatthew G. Knepley PetscInt s = species[p], d; 12366c5a79ebSMatthew G. Knepley PetscScalar vel[3]; 12376c5a79ebSMatthew G. Knepley 12386c5a79ebSMatthew G. Knepley PetscCall((*velFunc)(dim, 0., NULL, p, vel, ctx)); 12396c5a79ebSMatthew G. Knepley for (d = 0; d < dim; ++d) v[p * dim + d] = (v0[s] / v0[0]) * PetscRealPart(vel[d]); 12406c5a79ebSMatthew G. Knepley } 12416c5a79ebSMatthew G. Knepley } else { 12426c5a79ebSMatthew G. Knepley PetscRandom rnd; 12436c5a79ebSMatthew G. Knepley 12446c5a79ebSMatthew G. Knepley PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)sw), &rnd)); 12456c5a79ebSMatthew G. Knepley PetscCall(PetscRandomSetInterval(rnd, 0, 1.)); 12466c5a79ebSMatthew G. Knepley PetscCall(PetscRandomSetFromOptions(rnd)); 12476c5a79ebSMatthew G. Knepley 124835b38c60SMatthew G. Knepley for (p = 0; p < Np; ++p) { 124935b38c60SMatthew G. Knepley PetscInt s = species[p], d; 125035b38c60SMatthew G. Knepley PetscReal a[3], vel[3]; 125135b38c60SMatthew G. Knepley 12529566063dSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscRandomGetValueReal(rnd, &a[d])); 12539566063dSJacob Faibussowitsch PetscCall(sampler(a, NULL, vel)); 1254ad540459SPierre Jolivet for (d = 0; d < dim; ++d) v[p * dim + d] = (v0[s] / v0[0]) * vel[d]; 125535b38c60SMatthew G. Knepley } 12566c5a79ebSMatthew G. Knepley PetscCall(PetscRandomDestroy(&rnd)); 12576c5a79ebSMatthew G. Knepley } 12589566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(sw, "velocity", NULL, NULL, (void **)&v)); 12599566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(sw, "species", NULL, NULL, (void **)&species)); 12603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 126135b38c60SMatthew G. Knepley } 126235b38c60SMatthew G. Knepley 126335b38c60SMatthew G. Knepley /*@ 126435b38c60SMatthew G. Knepley DMSwarmInitializeVelocitiesFromOptions - Set the initial velocities of particles using a distribution determined from options. 126535b38c60SMatthew G. Knepley 126620f4b53cSBarry Smith Collective 126735b38c60SMatthew G. Knepley 126835b38c60SMatthew G. Knepley Input Parameters: 126920f4b53cSBarry Smith + sw - The `DMSWARM` object 127035b38c60SMatthew G. Knepley - v0 - The velocity scale for nondimensionalization for each species 127135b38c60SMatthew G. Knepley 127235b38c60SMatthew G. Knepley Level: advanced 127335b38c60SMatthew G. Knepley 127420f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()`, `DMSwarmInitializeCoordinates()`, `DMSwarmInitializeVelocities()` 127535b38c60SMatthew G. Knepley @*/ 1276d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmInitializeVelocitiesFromOptions(DM sw, const PetscReal v0[]) 1277d71ae5a4SJacob Faibussowitsch { 127835b38c60SMatthew G. Knepley PetscProbFunc sampler; 127935b38c60SMatthew G. Knepley PetscInt dim; 128035b38c60SMatthew G. Knepley const char *prefix; 12816c5a79ebSMatthew G. Knepley char funcname[PETSC_MAX_PATH_LEN]; 12826c5a79ebSMatthew G. Knepley PetscBool flg; 128335b38c60SMatthew G. Knepley 128435b38c60SMatthew G. Knepley PetscFunctionBegin; 1285d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)sw), "", "DMSwarm Options", "DMSWARM"); 12866c5a79ebSMatthew G. Knepley PetscCall(PetscOptionsString("-dm_swarm_velocity_function", "Function to determine particle velocities", "DMSwarmSetVelocityFunction", funcname, funcname, sizeof(funcname), &flg)); 1287d0609cedSBarry Smith PetscOptionsEnd(); 12886c5a79ebSMatthew G. Knepley if (flg) { 12898434afd1SBarry Smith PetscSimplePointFn *velFunc; 12906c5a79ebSMatthew G. Knepley 12916c5a79ebSMatthew G. Knepley PetscCall(PetscDLSym(NULL, funcname, (void **)&velFunc)); 12926c5a79ebSMatthew G. Knepley PetscCheck(velFunc, PetscObjectComm((PetscObject)sw), PETSC_ERR_ARG_WRONG, "Could not locate function %s", funcname); 12936c5a79ebSMatthew G. Knepley PetscCall(DMSwarmSetVelocityFunction(sw, velFunc)); 12946c5a79ebSMatthew G. Knepley } 12959566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim)); 12969566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sw, &prefix)); 12979566063dSJacob Faibussowitsch PetscCall(PetscProbCreateFromOptions(dim, prefix, "-dm_swarm_velocity_density", NULL, NULL, &sampler)); 12989566063dSJacob Faibussowitsch PetscCall(DMSwarmInitializeVelocities(sw, sampler, v0)); 12993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 130035b38c60SMatthew G. Knepley } 1301