10e2ec84fSDave May #include <petsc/private/dmswarmimpl.h> /*I "petscdmswarm.h" I*/
20e2ec84fSDave May #include <petscsf.h>
3b799feefSDave May #include <petscdmda.h>
4b799feefSDave May #include <petscdmplex.h>
535b38c60SMatthew G. Knepley #include <petscdt.h>
6279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h"
70e2ec84fSDave May
835b38c60SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> /* For CoordinatesRefToReal() */
935b38c60SMatthew G. Knepley
1019307e5cSMatthew G. Knepley PetscClassId DMSWARMCELLDM_CLASSID;
1119307e5cSMatthew G. Knepley
1219307e5cSMatthew G. Knepley /*@
1319307e5cSMatthew G. Knepley DMSwarmCellDMDestroy - destroy a `DMSwarmCellDM`
1419307e5cSMatthew G. Knepley
1519307e5cSMatthew G. Knepley Collective
1619307e5cSMatthew G. Knepley
1719307e5cSMatthew G. Knepley Input Parameter:
1819307e5cSMatthew G. Knepley . celldm - address of `DMSwarmCellDM`
1919307e5cSMatthew G. Knepley
2019307e5cSMatthew G. Knepley Level: advanced
2119307e5cSMatthew G. Knepley
2219307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DMSwarmCellDMCreate()`
2319307e5cSMatthew G. Knepley @*/
DMSwarmCellDMDestroy(DMSwarmCellDM * celldm)2419307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMDestroy(DMSwarmCellDM *celldm)
2519307e5cSMatthew G. Knepley {
2619307e5cSMatthew G. Knepley PetscFunctionBegin;
2719307e5cSMatthew G. Knepley if (!*celldm) PetscFunctionReturn(PETSC_SUCCESS);
2819307e5cSMatthew G. Knepley PetscValidHeaderSpecific(*celldm, DMSWARMCELLDM_CLASSID, 1);
2919307e5cSMatthew G. Knepley if (--((PetscObject)*celldm)->refct > 0) {
3019307e5cSMatthew G. Knepley *celldm = NULL;
3119307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
3219307e5cSMatthew G. Knepley }
3319307e5cSMatthew G. Knepley PetscTryTypeMethod(*celldm, destroy);
3419307e5cSMatthew G. Knepley for (PetscInt f = 0; f < (*celldm)->Nf; ++f) PetscCall(PetscFree((*celldm)->dmFields[f]));
3519307e5cSMatthew G. Knepley PetscCall(PetscFree((*celldm)->dmFields));
3619307e5cSMatthew G. Knepley for (PetscInt f = 0; f < (*celldm)->Nfc; ++f) PetscCall(PetscFree((*celldm)->coordFields[f]));
3719307e5cSMatthew G. Knepley PetscCall(PetscFree((*celldm)->coordFields));
3819307e5cSMatthew G. Knepley PetscCall(PetscFree((*celldm)->cellid));
3919307e5cSMatthew G. Knepley PetscCall(DMSwarmSortDestroy(&(*celldm)->sort));
4019307e5cSMatthew G. Knepley PetscCall(DMDestroy(&(*celldm)->dm));
4119307e5cSMatthew G. Knepley PetscCall(PetscHeaderDestroy(celldm));
4219307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
4319307e5cSMatthew G. Knepley }
4419307e5cSMatthew G. Knepley
4519307e5cSMatthew G. Knepley /*@
4619307e5cSMatthew G. Knepley DMSwarmCellDMView - view a `DMSwarmCellDM`
4719307e5cSMatthew G. Knepley
4819307e5cSMatthew G. Knepley Collective
4919307e5cSMatthew G. Knepley
5019307e5cSMatthew G. Knepley Input Parameters:
5119307e5cSMatthew G. Knepley + celldm - `DMSwarmCellDM`
5219307e5cSMatthew G. Knepley - viewer - viewer to display field, for example `PETSC_VIEWER_STDOUT_WORLD`
5319307e5cSMatthew G. Knepley
5419307e5cSMatthew G. Knepley Level: advanced
5519307e5cSMatthew G. Knepley
5619307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DMSwarmCellDMCreate()`
5719307e5cSMatthew G. Knepley @*/
DMSwarmCellDMView(DMSwarmCellDM celldm,PetscViewer viewer)5819307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMView(DMSwarmCellDM celldm, PetscViewer viewer)
5919307e5cSMatthew G. Knepley {
609f196a02SMartin Diehl PetscBool isascii;
6119307e5cSMatthew G. Knepley
6219307e5cSMatthew G. Knepley PetscFunctionBegin;
6319307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
6419307e5cSMatthew G. Knepley if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)celldm), &viewer));
6519307e5cSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6619307e5cSMatthew G. Knepley PetscCheckSameComm(celldm, 1, viewer, 2);
679f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
689f196a02SMartin Diehl if (isascii) {
6919307e5cSMatthew G. Knepley PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)celldm, viewer));
7019307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPushTab(viewer));
7119307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "solution field%s:", celldm->Nf > 1 ? "s" : ""));
7219307e5cSMatthew G. Knepley for (PetscInt f = 0; f < celldm->Nf; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, " %s", celldm->dmFields[f]));
7319307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
7419307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "coordinate field%s:", celldm->Nfc > 1 ? "s" : ""));
7519307e5cSMatthew G. Knepley for (PetscInt f = 0; f < celldm->Nfc; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, " %s", celldm->coordFields[f]));
7619307e5cSMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
7719307e5cSMatthew G. Knepley PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_DEFAULT));
7819307e5cSMatthew G. Knepley PetscCall(DMView(celldm->dm, viewer));
7919307e5cSMatthew G. Knepley PetscCall(PetscViewerPopFormat(viewer));
8019307e5cSMatthew G. Knepley }
8119307e5cSMatthew G. Knepley PetscTryTypeMethod(celldm, view, viewer);
829f196a02SMartin Diehl if (isascii) PetscCall(PetscViewerASCIIPopTab(viewer));
8319307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
8419307e5cSMatthew G. Knepley }
8519307e5cSMatthew G. Knepley
8619307e5cSMatthew G. Knepley /*@
8719307e5cSMatthew G. Knepley DMSwarmCellDMGetDM - Returns the background `DM` for the `DMSwarm`
8819307e5cSMatthew G. Knepley
8919307e5cSMatthew G. Knepley Not Collective
9019307e5cSMatthew G. Knepley
9119307e5cSMatthew G. Knepley Input Parameter:
9219307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object
9319307e5cSMatthew G. Knepley
9419307e5cSMatthew G. Knepley Output Parameter:
9519307e5cSMatthew G. Knepley . dm - The `DM` object
9619307e5cSMatthew G. Knepley
9719307e5cSMatthew G. Knepley Level: intermediate
9819307e5cSMatthew G. Knepley
9919307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()`
10019307e5cSMatthew G. Knepley @*/
DMSwarmCellDMGetDM(DMSwarmCellDM celldm,DM * dm)10119307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetDM(DMSwarmCellDM celldm, DM *dm)
10219307e5cSMatthew G. Knepley {
10319307e5cSMatthew G. Knepley PetscFunctionBegin;
10419307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
10519307e5cSMatthew G. Knepley PetscAssertPointer(dm, 2);
10619307e5cSMatthew G. Knepley *dm = celldm->dm;
10719307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
10819307e5cSMatthew G. Knepley }
10919307e5cSMatthew G. Knepley
11019307e5cSMatthew G. Knepley /*@C
11119307e5cSMatthew G. Knepley DMSwarmCellDMGetFields - Returns the `DM` fields for the `DMSwarm`
11219307e5cSMatthew G. Knepley
11319307e5cSMatthew G. Knepley Not Collective
11419307e5cSMatthew G. Knepley
11519307e5cSMatthew G. Knepley Input Parameter:
11619307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object
11719307e5cSMatthew G. Knepley
11819307e5cSMatthew G. Knepley Output Parameters:
11919307e5cSMatthew G. Knepley + Nf - The number of fields
12019307e5cSMatthew G. Knepley - names - The array of field names in the `DMSWARM`
12119307e5cSMatthew G. Knepley
12219307e5cSMatthew G. Knepley Level: intermediate
12319307e5cSMatthew G. Knepley
12419307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()`
12519307e5cSMatthew G. Knepley @*/
DMSwarmCellDMGetFields(DMSwarmCellDM celldm,PetscInt * Nf,const char ** names[])12619307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetFields(DMSwarmCellDM celldm, PetscInt *Nf, const char **names[])
12719307e5cSMatthew G. Knepley {
12819307e5cSMatthew G. Knepley PetscFunctionBegin;
12919307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
13019307e5cSMatthew G. Knepley if (Nf) {
13119307e5cSMatthew G. Knepley PetscAssertPointer(Nf, 2);
13219307e5cSMatthew G. Knepley *Nf = celldm->Nf;
13319307e5cSMatthew G. Knepley }
13419307e5cSMatthew G. Knepley if (names) {
13519307e5cSMatthew G. Knepley PetscAssertPointer(names, 3);
13619307e5cSMatthew G. Knepley *names = (const char **)celldm->dmFields;
13719307e5cSMatthew G. Knepley }
13819307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
13919307e5cSMatthew G. Knepley }
14019307e5cSMatthew G. Knepley
14119307e5cSMatthew G. Knepley /*@C
14219307e5cSMatthew G. Knepley DMSwarmCellDMGetCoordinateFields - Returns the `DM` coordinate fields for the `DMSwarm`
14319307e5cSMatthew G. Knepley
14419307e5cSMatthew G. Knepley Not Collective
14519307e5cSMatthew G. Knepley
14619307e5cSMatthew G. Knepley Input Parameter:
14719307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object
14819307e5cSMatthew G. Knepley
14919307e5cSMatthew G. Knepley Output Parameters:
15019307e5cSMatthew G. Knepley + Nfc - The number of coordinate fields
15119307e5cSMatthew G. Knepley - names - The array of coordinate field names in the `DMSWARM`
15219307e5cSMatthew G. Knepley
15319307e5cSMatthew G. Knepley Level: intermediate
15419307e5cSMatthew G. Knepley
15519307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()`
15619307e5cSMatthew G. Knepley @*/
DMSwarmCellDMGetCoordinateFields(DMSwarmCellDM celldm,PetscInt * Nfc,const char ** names[])15719307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetCoordinateFields(DMSwarmCellDM celldm, PetscInt *Nfc, const char **names[])
15819307e5cSMatthew G. Knepley {
15919307e5cSMatthew G. Knepley PetscFunctionBegin;
16019307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
16119307e5cSMatthew G. Knepley if (Nfc) {
16219307e5cSMatthew G. Knepley PetscAssertPointer(Nfc, 2);
16319307e5cSMatthew G. Knepley *Nfc = celldm->Nfc;
16419307e5cSMatthew G. Knepley }
16519307e5cSMatthew G. Knepley if (names) {
16619307e5cSMatthew G. Knepley PetscAssertPointer(names, 3);
16719307e5cSMatthew G. Knepley *names = (const char **)celldm->coordFields;
16819307e5cSMatthew G. Knepley }
16919307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
17019307e5cSMatthew G. Knepley }
17119307e5cSMatthew G. Knepley
17219307e5cSMatthew G. Knepley /*@C
17319307e5cSMatthew G. Knepley DMSwarmCellDMGetCellID - Returns the cell id field name for the `DMSwarm`
17419307e5cSMatthew G. Knepley
17519307e5cSMatthew G. Knepley Not Collective
17619307e5cSMatthew G. Knepley
17719307e5cSMatthew G. Knepley Input Parameter:
17819307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object
17919307e5cSMatthew G. Knepley
18019307e5cSMatthew G. Knepley Output Parameters:
18119307e5cSMatthew G. Knepley . cellid - The cell id field name in the `DMSWARM`
18219307e5cSMatthew G. Knepley
18319307e5cSMatthew G. Knepley Level: intermediate
18419307e5cSMatthew G. Knepley
18519307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()`
18619307e5cSMatthew G. Knepley @*/
DMSwarmCellDMGetCellID(DMSwarmCellDM celldm,const char * cellid[])18719307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetCellID(DMSwarmCellDM celldm, const char *cellid[])
18819307e5cSMatthew G. Knepley {
18919307e5cSMatthew G. Knepley PetscFunctionBegin;
19019307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
19119307e5cSMatthew G. Knepley PetscAssertPointer(cellid, 2);
19219307e5cSMatthew G. Knepley *cellid = celldm->cellid;
19319307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
19419307e5cSMatthew G. Knepley }
19519307e5cSMatthew G. Knepley
19619307e5cSMatthew G. Knepley /*@C
19719307e5cSMatthew G. Knepley DMSwarmCellDMGetSort - Returns the sort context over the active `DMSwarmCellDM` for the `DMSwarm`
19819307e5cSMatthew G. Knepley
19919307e5cSMatthew G. Knepley Not Collective
20019307e5cSMatthew G. Knepley
20119307e5cSMatthew G. Knepley Input Parameter:
20219307e5cSMatthew G. Knepley . celldm - The `DMSwarmCellDM` object
20319307e5cSMatthew G. Knepley
20419307e5cSMatthew G. Knepley Output Parameter:
20519307e5cSMatthew G. Knepley . sort - The `DMSwarmSort` object
20619307e5cSMatthew G. Knepley
20719307e5cSMatthew G. Knepley Level: intermediate
20819307e5cSMatthew G. Knepley
20919307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()`
21019307e5cSMatthew G. Knepley @*/
DMSwarmCellDMGetSort(DMSwarmCellDM celldm,DMSwarmSort * sort)21119307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetSort(DMSwarmCellDM celldm, DMSwarmSort *sort)
21219307e5cSMatthew G. Knepley {
21319307e5cSMatthew G. Knepley PetscFunctionBegin;
21419307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
21519307e5cSMatthew G. Knepley PetscAssertPointer(sort, 2);
21619307e5cSMatthew G. Knepley *sort = celldm->sort;
21719307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
21819307e5cSMatthew G. Knepley }
21919307e5cSMatthew G. Knepley
22019307e5cSMatthew G. Knepley /*@C
22119307e5cSMatthew G. Knepley DMSwarmCellDMSetSort - Sets the sort context over the active `DMSwarmCellDM` for the `DMSwarm`
22219307e5cSMatthew G. Knepley
22319307e5cSMatthew G. Knepley Not Collective
22419307e5cSMatthew G. Knepley
22519307e5cSMatthew G. Knepley Input Parameters:
22619307e5cSMatthew G. Knepley + celldm - The `DMSwarmCellDM` object
22719307e5cSMatthew G. Knepley - sort - The `DMSwarmSort` object
22819307e5cSMatthew G. Knepley
22919307e5cSMatthew G. Knepley Level: intermediate
23019307e5cSMatthew G. Knepley
23119307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()`
23219307e5cSMatthew G. Knepley @*/
DMSwarmCellDMSetSort(DMSwarmCellDM celldm,DMSwarmSort sort)23319307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMSetSort(DMSwarmCellDM celldm, DMSwarmSort sort)
23419307e5cSMatthew G. Knepley {
23519307e5cSMatthew G. Knepley PetscFunctionBegin;
23619307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
23719307e5cSMatthew G. Knepley PetscAssertPointer(sort, 2);
23819307e5cSMatthew G. Knepley celldm->sort = sort;
23919307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
24019307e5cSMatthew G. Knepley }
24119307e5cSMatthew G. Knepley
24219307e5cSMatthew G. Knepley /*@
24319307e5cSMatthew G. Knepley DMSwarmCellDMGetBlockSize - Returns the total blocksize for the `DM` fields
24419307e5cSMatthew G. Knepley
24519307e5cSMatthew G. Knepley Not Collective
24619307e5cSMatthew G. Knepley
24719307e5cSMatthew G. Knepley Input Parameters:
24819307e5cSMatthew G. Knepley + celldm - The `DMSwarmCellDM` object
24919307e5cSMatthew G. Knepley - sw - The `DMSwarm` object
25019307e5cSMatthew G. Knepley
25119307e5cSMatthew G. Knepley Output Parameter:
25219307e5cSMatthew G. Knepley . bs - The total block size
25319307e5cSMatthew G. Knepley
25419307e5cSMatthew G. Knepley Level: intermediate
25519307e5cSMatthew G. Knepley
25619307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DM`, `DMSwarmSetCellDM()`
25719307e5cSMatthew G. Knepley @*/
DMSwarmCellDMGetBlockSize(DMSwarmCellDM celldm,DM sw,PetscInt * bs)25819307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMGetBlockSize(DMSwarmCellDM celldm, DM sw, PetscInt *bs)
25919307e5cSMatthew G. Knepley {
26019307e5cSMatthew G. Knepley PetscFunctionBegin;
26119307e5cSMatthew G. Knepley PetscValidHeaderSpecific(celldm, DMSWARMCELLDM_CLASSID, 1);
26219307e5cSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 2);
26319307e5cSMatthew G. Knepley PetscAssertPointer(bs, 3);
26419307e5cSMatthew G. Knepley *bs = 0;
26519307e5cSMatthew G. Knepley for (PetscInt f = 0; f < celldm->Nf; ++f) {
26619307e5cSMatthew G. Knepley PetscInt fbs;
26719307e5cSMatthew G. Knepley
26819307e5cSMatthew G. Knepley PetscCall(DMSwarmGetFieldInfo(sw, celldm->dmFields[f], &fbs, NULL));
26919307e5cSMatthew G. Knepley *bs += fbs;
27019307e5cSMatthew G. Knepley }
27119307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
27219307e5cSMatthew G. Knepley }
27319307e5cSMatthew G. Knepley
27419307e5cSMatthew G. Knepley /*@
27519307e5cSMatthew G. Knepley DMSwarmCellDMCreate - create a `DMSwarmCellDM`
27619307e5cSMatthew G. Knepley
27719307e5cSMatthew G. Knepley Collective
27819307e5cSMatthew G. Knepley
279d6ae5217SJose E. Roman Input Parameters:
28019307e5cSMatthew G. Knepley + dm - The background `DM` for the `DMSwarm`
28119307e5cSMatthew G. Knepley . Nf - The number of swarm fields defined over `dm`
28219307e5cSMatthew G. Knepley . dmFields - The swarm field names for the `dm` fields
28319307e5cSMatthew G. Knepley . Nfc - The number of swarm fields to use for coordinates over `dm`
28419307e5cSMatthew G. Knepley - coordFields - The swarm field names for the `dm` coordinate fields
28519307e5cSMatthew G. Knepley
28619307e5cSMatthew G. Knepley Output Parameter:
28719307e5cSMatthew G. Knepley . celldm - The new `DMSwarmCellDM`
28819307e5cSMatthew G. Knepley
28919307e5cSMatthew G. Knepley Level: advanced
29019307e5cSMatthew G. Knepley
29119307e5cSMatthew G. Knepley .seealso: `DMSwarmCellDM`, `DMSWARM`, `DMSetType()`
29219307e5cSMatthew G. Knepley @*/
DMSwarmCellDMCreate(DM dm,PetscInt Nf,const char * dmFields[],PetscInt Nfc,const char * coordFields[],DMSwarmCellDM * celldm)29319307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCellDMCreate(DM dm, PetscInt Nf, const char *dmFields[], PetscInt Nfc, const char *coordFields[], DMSwarmCellDM *celldm)
29419307e5cSMatthew G. Knepley {
29519307e5cSMatthew G. Knepley DMSwarmCellDM b;
29619307e5cSMatthew G. Knepley const char *name;
29719307e5cSMatthew G. Knepley char cellid[PETSC_MAX_PATH_LEN];
29819307e5cSMatthew G. Knepley
29919307e5cSMatthew G. Knepley PetscFunctionBegin;
30019307e5cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
30119307e5cSMatthew G. Knepley if (Nf) PetscAssertPointer(dmFields, 3);
30219307e5cSMatthew G. Knepley if (Nfc) PetscAssertPointer(coordFields, 5);
30319307e5cSMatthew G. Knepley PetscCall(DMInitializePackage());
30419307e5cSMatthew G. Knepley
30519307e5cSMatthew G. Knepley PetscCall(PetscHeaderCreate(b, DMSWARMCELLDM_CLASSID, "DMSwarmCellDM", "Background DM for a Swarm", "DM", PetscObjectComm((PetscObject)dm), DMSwarmCellDMDestroy, DMSwarmCellDMView));
30619307e5cSMatthew G. Knepley PetscCall(PetscObjectGetName((PetscObject)dm, &name));
30719307e5cSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)b, name));
30819307e5cSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dm));
30919307e5cSMatthew G. Knepley b->dm = dm;
31019307e5cSMatthew G. Knepley b->Nf = Nf;
31119307e5cSMatthew G. Knepley b->Nfc = Nfc;
31219307e5cSMatthew G. Knepley PetscCall(PetscMalloc1(b->Nf, &b->dmFields));
31319307e5cSMatthew G. Knepley for (PetscInt f = 0; f < b->Nf; ++f) PetscCall(PetscStrallocpy(dmFields[f], &b->dmFields[f]));
31419307e5cSMatthew G. Knepley PetscCall(PetscMalloc1(b->Nfc, &b->coordFields));
31519307e5cSMatthew G. Knepley for (PetscInt f = 0; f < b->Nfc; ++f) PetscCall(PetscStrallocpy(coordFields[f], &b->coordFields[f]));
31619307e5cSMatthew G. Knepley PetscCall(PetscSNPrintf(cellid, PETSC_MAX_PATH_LEN, "%s_cellid", name));
31719307e5cSMatthew G. Knepley PetscCall(PetscStrallocpy(cellid, &b->cellid));
31819307e5cSMatthew G. Knepley *celldm = b;
31919307e5cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
32019307e5cSMatthew G. Knepley }
32119307e5cSMatthew G. Knepley
3220e2ec84fSDave May /* Coordinate insertition/addition API */
323cc4c1da9SBarry Smith /*@
32420f4b53cSBarry Smith DMSwarmSetPointsUniformCoordinates - Set point coordinates in a `DMSWARM` on a regular (ijk) grid
3250e2ec84fSDave May
32620f4b53cSBarry Smith Collective
3270e2ec84fSDave May
32860225df5SJacob Faibussowitsch Input Parameters:
32919307e5cSMatthew G. Knepley + sw - the `DMSWARM`
3300e2ec84fSDave May . min - minimum coordinate values in the x, y, z directions (array of length dim)
3310e2ec84fSDave May . max - maximum coordinate values in the x, y, z directions (array of length dim)
3320e2ec84fSDave May . npoints - number of points in each spatial direction (array of length dim)
33320f4b53cSBarry Smith - mode - indicates whether to append points to the swarm (`ADD_VALUES`), or over-ride existing points (`INSERT_VALUES`)
3340e2ec84fSDave May
3350e2ec84fSDave May Level: beginner
3360e2ec84fSDave May
3370e2ec84fSDave May Notes:
33820f4b53cSBarry Smith When using mode = `INSERT_VALUES`, this method will reset the number of particles in the `DMSWARM`
339a3b724e8SBarry Smith to be `npoints[0]` x `npoints[1]` (2D) or `npoints[0]` x `npoints[1]` x `npoints[2]` (3D). When using mode = `ADD_VALUES`,
34020f4b53cSBarry Smith new points will be appended to any already existing in the `DMSWARM`
3410e2ec84fSDave May
34220f4b53cSBarry Smith .seealso: `DM`, `DMSWARM`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType`
3430e2ec84fSDave May @*/
DMSwarmSetPointsUniformCoordinates(DM sw,PetscReal min[],PetscReal max[],PetscInt npoints[],InsertMode mode)34419307e5cSMatthew G. Knepley PetscErrorCode DMSwarmSetPointsUniformCoordinates(DM sw, PetscReal min[], PetscReal max[], PetscInt npoints[], InsertMode mode)
345d71ae5a4SJacob Faibussowitsch {
346c448b993SMatthew G. Knepley PetscReal lmin[] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL};
347c448b993SMatthew G. Knepley PetscReal lmax[] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL};
34819307e5cSMatthew G. Knepley PetscInt i, j, k, bs, b, n_estimate, n_curr, n_new_est, p, n_found, Nfc;
3490e2ec84fSDave May const PetscScalar *_coor;
35019307e5cSMatthew G. Knepley DMSwarmCellDM celldm;
35119307e5cSMatthew G. Knepley DM dm;
3520e2ec84fSDave May PetscReal dx[3];
3532e3d3761SDave May PetscInt _npoints[] = {0, 0, 1};
3540e2ec84fSDave May Vec pos;
3550e2ec84fSDave May PetscScalar *_pos;
3560e2ec84fSDave May PetscReal *swarm_coor;
3570e2ec84fSDave May PetscInt *swarm_cellid;
3580e2ec84fSDave May PetscSF sfcell = NULL;
3590e2ec84fSDave May const PetscSFNode *LA_sfcell;
36019307e5cSMatthew G. Knepley const char **coordFields, *cellid;
3610e2ec84fSDave May
3620e2ec84fSDave May PetscFunctionBegin;
36319307e5cSMatthew G. Knepley DMSWARMPICVALID(sw);
36419307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm));
36519307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields));
36619307e5cSMatthew G. Knepley PetscCheck(Nfc == 1, PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "We only support a single coordinate field right now, not %" PetscInt_FMT, Nfc);
36719307e5cSMatthew G. Knepley
36819307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetDM(celldm, &dm));
36919307e5cSMatthew G. Knepley PetscCall(DMGetLocalBoundingBox(dm, lmin, lmax));
37019307e5cSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &bs));
3710e2ec84fSDave May
3720e2ec84fSDave May for (b = 0; b < bs; b++) {
37371844bb8SDave May if (npoints[b] > 1) {
3740e2ec84fSDave May dx[b] = (max[b] - min[b]) / ((PetscReal)(npoints[b] - 1));
37571844bb8SDave May } else {
37671844bb8SDave May dx[b] = 0.0;
37771844bb8SDave May }
3782e3d3761SDave May _npoints[b] = npoints[b];
3790e2ec84fSDave May }
3800e2ec84fSDave May
3810e2ec84fSDave May /* determine number of points living in the bounding box */
3820e2ec84fSDave May n_estimate = 0;
3832e3d3761SDave May for (k = 0; k < _npoints[2]; k++) {
3842e3d3761SDave May for (j = 0; j < _npoints[1]; j++) {
3852e3d3761SDave May for (i = 0; i < _npoints[0]; i++) {
3860e2ec84fSDave May PetscReal xp[] = {0.0, 0.0, 0.0};
3870e2ec84fSDave May PetscInt ijk[3];
3880e2ec84fSDave May PetscBool point_inside = PETSC_TRUE;
3890e2ec84fSDave May
3900e2ec84fSDave May ijk[0] = i;
3910e2ec84fSDave May ijk[1] = j;
3920e2ec84fSDave May ijk[2] = k;
393ad540459SPierre Jolivet for (b = 0; b < bs; b++) xp[b] = min[b] + ijk[b] * dx[b];
3940e2ec84fSDave May for (b = 0; b < bs; b++) {
395c448b993SMatthew G. Knepley if (xp[b] < lmin[b]) point_inside = PETSC_FALSE;
396c448b993SMatthew G. Knepley if (xp[b] > lmax[b]) point_inside = PETSC_FALSE;
3970e2ec84fSDave May }
398ad540459SPierre Jolivet if (point_inside) n_estimate++;
3990e2ec84fSDave May }
4000e2ec84fSDave May }
4010e2ec84fSDave May }
4020e2ec84fSDave May
4030e2ec84fSDave May /* create candidate list */
4049566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF, &pos));
4059566063dSJacob Faibussowitsch PetscCall(VecSetSizes(pos, bs * n_estimate, PETSC_DECIDE));
4069566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(pos, bs));
4079566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(pos));
4089566063dSJacob Faibussowitsch PetscCall(VecGetArray(pos, &_pos));
4090e2ec84fSDave May
4100e2ec84fSDave May n_estimate = 0;
4112e3d3761SDave May for (k = 0; k < _npoints[2]; k++) {
4122e3d3761SDave May for (j = 0; j < _npoints[1]; j++) {
4132e3d3761SDave May for (i = 0; i < _npoints[0]; i++) {
4140e2ec84fSDave May PetscReal xp[] = {0.0, 0.0, 0.0};
4150e2ec84fSDave May PetscInt ijk[3];
4160e2ec84fSDave May PetscBool point_inside = PETSC_TRUE;
4170e2ec84fSDave May
4180e2ec84fSDave May ijk[0] = i;
4190e2ec84fSDave May ijk[1] = j;
4200e2ec84fSDave May ijk[2] = k;
421ad540459SPierre Jolivet for (b = 0; b < bs; b++) xp[b] = min[b] + ijk[b] * dx[b];
4220e2ec84fSDave May for (b = 0; b < bs; b++) {
423c448b993SMatthew G. Knepley if (xp[b] < lmin[b]) point_inside = PETSC_FALSE;
424c448b993SMatthew G. Knepley if (xp[b] > lmax[b]) point_inside = PETSC_FALSE;
4250e2ec84fSDave May }
4260e2ec84fSDave May if (point_inside) {
427ad540459SPierre Jolivet for (b = 0; b < bs; b++) _pos[bs * n_estimate + b] = xp[b];
4280e2ec84fSDave May n_estimate++;
4290e2ec84fSDave May }
4300e2ec84fSDave May }
4310e2ec84fSDave May }
4320e2ec84fSDave May }
4339566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(pos, &_pos));
4340e2ec84fSDave May
4350e2ec84fSDave May /* locate points */
43619307e5cSMatthew G. Knepley PetscCall(DMLocatePoints(dm, pos, DM_POINTLOCATION_NONE, &sfcell));
4379566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sfcell, NULL, NULL, NULL, &LA_sfcell));
4380e2ec84fSDave May n_found = 0;
4390e2ec84fSDave May for (p = 0; p < n_estimate; p++) {
440ad540459SPierre Jolivet if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) n_found++;
4410e2ec84fSDave May }
4420e2ec84fSDave May
4430e2ec84fSDave May /* adjust size */
4440e2ec84fSDave May if (mode == ADD_VALUES) {
44519307e5cSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &n_curr));
4460e2ec84fSDave May n_new_est = n_curr + n_found;
44719307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1));
4480e2ec84fSDave May }
4490e2ec84fSDave May if (mode == INSERT_VALUES) {
4500e2ec84fSDave May n_curr = 0;
4510e2ec84fSDave May n_new_est = n_found;
45219307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1));
4530e2ec84fSDave May }
4540e2ec84fSDave May
4550e2ec84fSDave May /* initialize new coords, cell owners, pid */
45619307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid));
4579566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(pos, &_coor));
45819307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor));
45919307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
4600e2ec84fSDave May n_found = 0;
4610e2ec84fSDave May for (p = 0; p < n_estimate; p++) {
4620e2ec84fSDave May if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) {
463ad540459SPierre Jolivet for (b = 0; b < bs; b++) swarm_coor[bs * (n_curr + n_found) + b] = PetscRealPart(_coor[bs * p + b]);
4640e2ec84fSDave May swarm_cellid[n_curr + n_found] = LA_sfcell[p].index;
4650e2ec84fSDave May n_found++;
4660e2ec84fSDave May }
4670e2ec84fSDave May }
46819307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
46919307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor));
4709566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(pos, &_coor));
4710e2ec84fSDave May
4729566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfcell));
4739566063dSJacob Faibussowitsch PetscCall(VecDestroy(&pos));
4743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4750e2ec84fSDave May }
4760e2ec84fSDave May
477cc4c1da9SBarry Smith /*@
47820f4b53cSBarry Smith DMSwarmSetPointCoordinates - Set point coordinates in a `DMSWARM` from a user defined list
4790e2ec84fSDave May
48020f4b53cSBarry Smith Collective
4810e2ec84fSDave May
48260225df5SJacob Faibussowitsch Input Parameters:
48319307e5cSMatthew G. Knepley + sw - the `DMSWARM`
4840e2ec84fSDave May . npoints - the number of points to insert
4850e2ec84fSDave May . coor - the coordinate values
48620f4b53cSBarry 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
48720f4b53cSBarry Smith - mode - indicates whether to append points to the swarm (`ADD_VALUES`), or over-ride existing points (`INSERT_VALUES`)
4880e2ec84fSDave May
4890e2ec84fSDave May Level: beginner
4900e2ec84fSDave May
4910e2ec84fSDave May Notes:
49220f4b53cSBarry Smith If the user has specified `redundant` as `PETSC_FALSE`, the cell `DM` will attempt to locate the coordinates provided by `coor` within
49320f4b53cSBarry 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
49420f4b53cSBarry Smith added to the `DMSWARM`.
4950e2ec84fSDave May
49620f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType`, `DMSwarmSetPointsUniformCoordinates()`
4970e2ec84fSDave May @*/
DMSwarmSetPointCoordinates(DM sw,PetscInt npoints,PetscReal coor[],PetscBool redundant,InsertMode mode)49819307e5cSMatthew G. Knepley PetscErrorCode DMSwarmSetPointCoordinates(DM sw, PetscInt npoints, PetscReal coor[], PetscBool redundant, InsertMode mode)
499d71ae5a4SJacob Faibussowitsch {
5000e2ec84fSDave May PetscReal gmin[] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL};
5010e2ec84fSDave May PetscReal gmax[] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL};
5020e2ec84fSDave May PetscInt i, N, bs, b, n_estimate, n_curr, n_new_est, p, n_found;
5030e2ec84fSDave May Vec coorlocal;
5040e2ec84fSDave May const PetscScalar *_coor;
50519307e5cSMatthew G. Knepley DMSwarmCellDM celldm;
50619307e5cSMatthew G. Knepley DM dm;
5070e2ec84fSDave May Vec pos;
5080e2ec84fSDave May PetscScalar *_pos;
5090e2ec84fSDave May PetscReal *swarm_coor;
5100e2ec84fSDave May PetscInt *swarm_cellid;
5110e2ec84fSDave May PetscSF sfcell = NULL;
5120e2ec84fSDave May const PetscSFNode *LA_sfcell;
5130e2ec84fSDave May PetscReal *my_coor;
51419307e5cSMatthew G. Knepley PetscInt my_npoints, Nfc;
5150e2ec84fSDave May PetscMPIInt rank;
5160e2ec84fSDave May MPI_Comm comm;
51719307e5cSMatthew G. Knepley const char **coordFields, *cellid;
5180e2ec84fSDave May
5190e2ec84fSDave May PetscFunctionBegin;
52019307e5cSMatthew G. Knepley DMSWARMPICVALID(sw);
52119307e5cSMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)sw, &comm));
5229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
5230e2ec84fSDave May
52419307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm));
52519307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields));
52619307e5cSMatthew G. Knepley PetscCheck(Nfc == 1, PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "We only support a single coordinate field right now, not %" PetscInt_FMT, Nfc);
52719307e5cSMatthew G. Knepley
52819307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetDM(celldm, &dm));
52919307e5cSMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coorlocal));
5309566063dSJacob Faibussowitsch PetscCall(VecGetSize(coorlocal, &N));
5319566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(coorlocal, &bs));
5320e2ec84fSDave May N = N / bs;
5339566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(coorlocal, &_coor));
5340e2ec84fSDave May for (i = 0; i < N; i++) {
5350e2ec84fSDave May for (b = 0; b < bs; b++) {
536a5f152d1SDave May gmin[b] = PetscMin(gmin[b], PetscRealPart(_coor[bs * i + b]));
537a5f152d1SDave May gmax[b] = PetscMax(gmax[b], PetscRealPart(_coor[bs * i + b]));
5380e2ec84fSDave May }
5390e2ec84fSDave May }
5409566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(coorlocal, &_coor));
5410e2ec84fSDave May
5420e2ec84fSDave May /* broadcast points from rank 0 if requested */
5430e2ec84fSDave May if (redundant) {
5446497c311SBarry Smith PetscMPIInt imy;
5456497c311SBarry Smith
5460e2ec84fSDave May my_npoints = npoints;
5479566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&my_npoints, 1, MPIU_INT, 0, comm));
5480e2ec84fSDave May
5490e2ec84fSDave May if (rank > 0) { /* allocate space */
5509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bs * my_npoints, &my_coor));
5510e2ec84fSDave May } else {
5520e2ec84fSDave May my_coor = coor;
5530e2ec84fSDave May }
5546497c311SBarry Smith PetscCall(PetscMPIIntCast(bs * my_npoints, &imy));
5556497c311SBarry Smith PetscCallMPI(MPI_Bcast(my_coor, imy, MPIU_REAL, 0, comm));
5560e2ec84fSDave May } else {
5570e2ec84fSDave May my_npoints = npoints;
5580e2ec84fSDave May my_coor = coor;
5590e2ec84fSDave May }
5600e2ec84fSDave May
5610e2ec84fSDave May /* determine the number of points living in the bounding box */
5620e2ec84fSDave May n_estimate = 0;
5630e2ec84fSDave May for (i = 0; i < my_npoints; i++) {
5640e2ec84fSDave May PetscBool point_inside = PETSC_TRUE;
5650e2ec84fSDave May
5660e2ec84fSDave May for (b = 0; b < bs; b++) {
567ad540459SPierre Jolivet if (my_coor[bs * i + b] < gmin[b]) point_inside = PETSC_FALSE;
568ad540459SPierre Jolivet if (my_coor[bs * i + b] > gmax[b]) point_inside = PETSC_FALSE;
5690e2ec84fSDave May }
570ad540459SPierre Jolivet if (point_inside) n_estimate++;
5710e2ec84fSDave May }
5720e2ec84fSDave May
5730e2ec84fSDave May /* create candidate list */
5749566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF, &pos));
5759566063dSJacob Faibussowitsch PetscCall(VecSetSizes(pos, bs * n_estimate, PETSC_DECIDE));
5769566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(pos, bs));
5779566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(pos));
5789566063dSJacob Faibussowitsch PetscCall(VecGetArray(pos, &_pos));
5790e2ec84fSDave May
5800e2ec84fSDave May n_estimate = 0;
5810e2ec84fSDave May for (i = 0; i < my_npoints; i++) {
5820e2ec84fSDave May PetscBool point_inside = PETSC_TRUE;
5830e2ec84fSDave May
5840e2ec84fSDave May for (b = 0; b < bs; b++) {
585ad540459SPierre Jolivet if (my_coor[bs * i + b] < gmin[b]) point_inside = PETSC_FALSE;
586ad540459SPierre Jolivet if (my_coor[bs * i + b] > gmax[b]) point_inside = PETSC_FALSE;
5870e2ec84fSDave May }
5880e2ec84fSDave May if (point_inside) {
589ad540459SPierre Jolivet for (b = 0; b < bs; b++) _pos[bs * n_estimate + b] = my_coor[bs * i + b];
5900e2ec84fSDave May n_estimate++;
5910e2ec84fSDave May }
5920e2ec84fSDave May }
5939566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(pos, &_pos));
5940e2ec84fSDave May
5950e2ec84fSDave May /* locate points */
59619307e5cSMatthew G. Knepley PetscCall(DMLocatePoints(dm, pos, DM_POINTLOCATION_NONE, &sfcell));
5970e2ec84fSDave May
5989566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sfcell, NULL, NULL, NULL, &LA_sfcell));
5990e2ec84fSDave May n_found = 0;
6000e2ec84fSDave May for (p = 0; p < n_estimate; p++) {
601ad540459SPierre Jolivet if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) n_found++;
6020e2ec84fSDave May }
6030e2ec84fSDave May
6040e2ec84fSDave May /* adjust size */
6050e2ec84fSDave May if (mode == ADD_VALUES) {
60619307e5cSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &n_curr));
6070e2ec84fSDave May n_new_est = n_curr + n_found;
60819307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1));
6090e2ec84fSDave May }
6100e2ec84fSDave May if (mode == INSERT_VALUES) {
6110e2ec84fSDave May n_curr = 0;
6120e2ec84fSDave May n_new_est = n_found;
61319307e5cSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, n_new_est, -1));
6140e2ec84fSDave May }
6150e2ec84fSDave May
6160e2ec84fSDave May /* initialize new coords, cell owners, pid */
61719307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid));
6189566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(pos, &_coor));
61919307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor));
62019307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
6210e2ec84fSDave May n_found = 0;
6220e2ec84fSDave May for (p = 0; p < n_estimate; p++) {
6230e2ec84fSDave May if (LA_sfcell[p].index != DMLOCATEPOINT_POINT_NOT_FOUND) {
624ad540459SPierre Jolivet for (b = 0; b < bs; b++) swarm_coor[bs * (n_curr + n_found) + b] = PetscRealPart(_coor[bs * p + b]);
6250e2ec84fSDave May swarm_cellid[n_curr + n_found] = LA_sfcell[p].index;
6260e2ec84fSDave May n_found++;
6270e2ec84fSDave May }
6280e2ec84fSDave May }
62919307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
63019307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, coordFields[0], NULL, NULL, (void **)&swarm_coor));
6319566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(pos, &_coor));
6320e2ec84fSDave May
6330e2ec84fSDave May if (redundant) {
63448a46eb9SPierre Jolivet if (rank > 0) PetscCall(PetscFree(my_coor));
6350e2ec84fSDave May }
6369566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfcell));
6379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&pos));
6383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6390e2ec84fSDave May }
6400e2ec84fSDave May
6410e2ec84fSDave May extern PetscErrorCode private_DMSwarmInsertPointsUsingCellDM_DA(DM, DM, DMSwarmPICLayoutType, PetscInt);
6420e2ec84fSDave May extern PetscErrorCode private_DMSwarmInsertPointsUsingCellDM_PLEX(DM, DM, DMSwarmPICLayoutType, PetscInt);
6430e2ec84fSDave May
644cc4c1da9SBarry Smith /*@
6450e2ec84fSDave May DMSwarmInsertPointsUsingCellDM - Insert point coordinates within each cell
6460e2ec84fSDave May
64720f4b53cSBarry Smith Not Collective
6480e2ec84fSDave May
64960225df5SJacob Faibussowitsch Input Parameters:
65020f4b53cSBarry Smith + dm - the `DMSWARM`
65120f4b53cSBarry Smith . layout_type - method used to fill each cell with the cell `DM`
6520e2ec84fSDave May - fill_param - parameter controlling how many points per cell are added (the meaning of this parameter is dependent on the layout type)
6530e2ec84fSDave May
6540e2ec84fSDave May Level: beginner
6550e2ec84fSDave May
6560e2ec84fSDave May Notes:
65720f4b53cSBarry Smith The insert method will reset any previous defined points within the `DMSWARM`.
658e7af74c8SDave May
65920f4b53cSBarry Smith When using a `DMDA` both 2D and 3D are supported for all layout types provided you are using `DMDA_ELEMENT_Q1`.
660e7af74c8SDave May
661a4e35b19SJacob Faibussowitsch When using a `DMPLEX` the following case are supported\:
66220f4b53cSBarry Smith .vb
663ea3d7275SDave May (i) DMSWARMPIC_LAYOUT_REGULAR: 2D (triangle),
664ea3d7275SDave May (ii) DMSWARMPIC_LAYOUT_GAUSS: 2D and 3D provided the cell is a tri/tet or a quad/hex,
665ea3d7275SDave May (iii) DMSWARMPIC_LAYOUT_SUBDIVISION: 2D and 3D for quad/hex and 2D tri.
66620f4b53cSBarry Smith .ve
6670e2ec84fSDave May
66820f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmPICLayoutType`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType`
6690e2ec84fSDave May @*/
DMSwarmInsertPointsUsingCellDM(DM dm,DMSwarmPICLayoutType layout_type,PetscInt fill_param)670cc4c1da9SBarry Smith PetscErrorCode DMSwarmInsertPointsUsingCellDM(DM dm, DMSwarmPICLayoutType layout_type, PetscInt fill_param)
671d71ae5a4SJacob Faibussowitsch {
6720e2ec84fSDave May DM celldm;
6730e2ec84fSDave May PetscBool isDA, isPLEX;
6740e2ec84fSDave May
6750e2ec84fSDave May PetscFunctionBegin;
6760e2ec84fSDave May DMSWARMPICVALID(dm);
6779566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &celldm));
6789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMDA, &isDA));
6799566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMPLEX, &isPLEX));
6800e2ec84fSDave May if (isDA) {
6819566063dSJacob Faibussowitsch PetscCall(private_DMSwarmInsertPointsUsingCellDM_DA(dm, celldm, layout_type, fill_param));
6820e2ec84fSDave May } else if (isPLEX) {
6839566063dSJacob Faibussowitsch PetscCall(private_DMSwarmInsertPointsUsingCellDM_PLEX(dm, celldm, layout_type, fill_param));
6840e2ec84fSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only supported for cell DMs of type DMDA and DMPLEX");
6853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6860e2ec84fSDave May }
6870e2ec84fSDave May
688431382f2SDave May extern PetscErrorCode private_DMSwarmSetPointCoordinatesCellwise_PLEX(DM, DM, PetscInt, PetscReal *);
689431382f2SDave May
690431382f2SDave May /*@C
691431382f2SDave May DMSwarmSetPointCoordinatesCellwise - Insert point coordinates (defined over the reference cell) within each cell
692431382f2SDave May
69320f4b53cSBarry Smith Not Collective
694431382f2SDave May
69560225df5SJacob Faibussowitsch Input Parameters:
69620f4b53cSBarry Smith + dm - the `DMSWARM`
697431382f2SDave May . npoints - the number of points to insert in each cell
698431382f2SDave May - xi - the coordinates (defined in the local coordinate system for each cell) to insert
699431382f2SDave May
700431382f2SDave May Level: beginner
701431382f2SDave May
702431382f2SDave May Notes:
70320f4b53cSBarry Smith The method will reset any previous defined points within the `DMSWARM`.
70420f4b53cSBarry Smith Only supported for `DMPLEX`. If you are using a `DMDA` it is recommended to either use
70520f4b53cSBarry Smith `DMSwarmInsertPointsUsingCellDM()`, or extract and set the coordinates yourself the following code
70620f4b53cSBarry Smith .vb
70720f4b53cSBarry Smith PetscReal *coor;
708d52c2f21SMatthew G. Knepley const char *coordname;
709d52c2f21SMatthew G. Knepley DMSwarmGetCoordinateField(dm, &coordname);
710d52c2f21SMatthew G. Knepley DMSwarmGetField(dm,coordname,NULL,NULL,(void**)&coor);
71120f4b53cSBarry Smith // user code to define the coordinates here
712d52c2f21SMatthew G. Knepley DMSwarmRestoreField(dm,coordname,NULL,NULL,(void**)&coor);
71320f4b53cSBarry Smith .ve
714e7af74c8SDave May
71520f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetCellDM()`, `DMSwarmInsertPointsUsingCellDM()`
716431382f2SDave May @*/
DMSwarmSetPointCoordinatesCellwise(DM dm,PetscInt npoints,PetscReal xi[])717cc4c1da9SBarry Smith PetscErrorCode DMSwarmSetPointCoordinatesCellwise(DM dm, PetscInt npoints, PetscReal xi[])
718d71ae5a4SJacob Faibussowitsch {
719431382f2SDave May DM celldm;
720431382f2SDave May PetscBool isDA, isPLEX;
721431382f2SDave May
7220e2ec84fSDave May PetscFunctionBegin;
723431382f2SDave May DMSWARMPICVALID(dm);
7249566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &celldm));
7259566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMDA, &isDA));
7269566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)celldm, DMPLEX, &isPLEX));
72728b400f6SJacob Faibussowitsch PetscCheck(!isDA, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only supported for cell DMs of type DMPLEX. Recommended you use DMSwarmInsertPointsUsingCellDM()");
728*966bd95aSPierre Jolivet PetscCheck(isPLEX, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only supported for cell DMs of type DMDA and DMPLEX");
7299566063dSJacob Faibussowitsch PetscCall(private_DMSwarmSetPointCoordinatesCellwise_PLEX(dm, celldm, npoints, xi));
7303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7310e2ec84fSDave May }
732431382f2SDave May
733cc4c1da9SBarry Smith /*@
734b799feefSDave May DMSwarmCreatePointPerCellCount - Count the number of points within all cells in the cell DM
7350e2ec84fSDave May
73620f4b53cSBarry Smith Not Collective
7370e2ec84fSDave May
73860225df5SJacob Faibussowitsch Input Parameter:
73919307e5cSMatthew G. Knepley . sw - the `DMSWARM`
7400e2ec84fSDave May
74160225df5SJacob Faibussowitsch Output Parameters:
74220f4b53cSBarry Smith + ncells - the number of cells in the cell `DM` (optional argument, pass `NULL` to ignore)
743b799feefSDave May - count - array of length ncells containing the number of points per cell
7440e2ec84fSDave May
7450e2ec84fSDave May Level: beginner
7460e2ec84fSDave May
7470e2ec84fSDave May Notes:
7480e2ec84fSDave May The array count is allocated internally and must be free'd by the user.
7490e2ec84fSDave May
75020f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetType()`, `DMSwarmSetCellDM()`, `DMSwarmType`
7510e2ec84fSDave May @*/
DMSwarmCreatePointPerCellCount(DM sw,PetscInt * ncells,PetscInt ** count)75219307e5cSMatthew G. Knepley PetscErrorCode DMSwarmCreatePointPerCellCount(DM sw, PetscInt *ncells, PetscInt **count)
753d71ae5a4SJacob Faibussowitsch {
75419307e5cSMatthew G. Knepley DMSwarmCellDM celldm;
755b799feefSDave May PetscBool isvalid;
756b799feefSDave May PetscInt nel;
757b799feefSDave May PetscInt *sum;
75819307e5cSMatthew G. Knepley const char *cellid;
759b799feefSDave May
7600e2ec84fSDave May PetscFunctionBegin;
76119307e5cSMatthew G. Knepley PetscCall(DMSwarmSortGetIsValid(sw, &isvalid));
762b799feefSDave May nel = 0;
763b799feefSDave May if (isvalid) {
764b799feefSDave May PetscInt e;
765b799feefSDave May
76619307e5cSMatthew G. Knepley PetscCall(DMSwarmSortGetSizes(sw, &nel, NULL));
767b799feefSDave May
7689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nel, &sum));
76919307e5cSMatthew G. Knepley for (e = 0; e < nel; e++) PetscCall(DMSwarmSortGetNumberOfPointsPerCell(sw, e, &sum[e]));
770b799feefSDave May } else {
77119307e5cSMatthew G. Knepley DM dm;
772b799feefSDave May PetscBool isda, isplex, isshell;
773b799feefSDave May PetscInt p, npoints;
774b799feefSDave May PetscInt *swarm_cellid;
775b799feefSDave May
776b799feefSDave May /* get the number of cells */
77719307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm));
77819307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetDM(celldm, &dm));
77919307e5cSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda));
78019307e5cSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMPLEX, &isplex));
78119307e5cSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSHELL, &isshell));
782b799feefSDave May if (isda) {
783b799feefSDave May PetscInt _nel, _npe;
784b799feefSDave May const PetscInt *_element;
785b799feefSDave May
78619307e5cSMatthew G. Knepley PetscCall(DMDAGetElements(dm, &_nel, &_npe, &_element));
787b799feefSDave May nel = _nel;
78819307e5cSMatthew G. Knepley PetscCall(DMDARestoreElements(dm, &_nel, &_npe, &_element));
789b799feefSDave May } else if (isplex) {
790b799feefSDave May PetscInt ps, pe;
791b799feefSDave May
79219307e5cSMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dm, 0, &ps, &pe));
793b799feefSDave May nel = pe - ps;
794b799feefSDave May } else if (isshell) {
795b799feefSDave May PetscErrorCode (*method_DMShellGetNumberOfCells)(DM, PetscInt *);
796b799feefSDave May
79719307e5cSMatthew G. Knepley PetscCall(PetscObjectQueryFunction((PetscObject)dm, "DMGetNumberOfCells_C", &method_DMShellGetNumberOfCells));
798b799feefSDave May if (method_DMShellGetNumberOfCells) {
79919307e5cSMatthew G. Knepley PetscCall(method_DMShellGetNumberOfCells(dm, &nel));
8009371c9d4SSatish Balay } else
80119307e5cSMatthew 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);");
80219307e5cSMatthew 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");
803b799feefSDave May
8049566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nel, &sum));
8059566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(sum, nel));
80619307e5cSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &npoints));
80719307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid));
80819307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
809b799feefSDave May for (p = 0; p < npoints; p++) {
810ad540459SPierre Jolivet if (swarm_cellid[p] != DMLOCATEPOINT_POINT_NOT_FOUND) sum[swarm_cellid[p]]++;
811b799feefSDave May }
81219307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
813b799feefSDave May }
814ad540459SPierre Jolivet if (ncells) *ncells = nel;
815b799feefSDave May *count = sum;
8163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8170e2ec84fSDave May }
81835b38c60SMatthew G. Knepley
81935b38c60SMatthew G. Knepley /*@
82035b38c60SMatthew G. Knepley DMSwarmGetNumSpecies - Get the number of particle species
82135b38c60SMatthew G. Knepley
82220f4b53cSBarry Smith Not Collective
82335b38c60SMatthew G. Knepley
82460225df5SJacob Faibussowitsch Input Parameter:
82560225df5SJacob Faibussowitsch . sw - the `DMSWARM`
82635b38c60SMatthew G. Knepley
82760225df5SJacob Faibussowitsch Output Parameters:
82835b38c60SMatthew G. Knepley . Ns - the number of species
82935b38c60SMatthew G. Knepley
83035b38c60SMatthew G. Knepley Level: intermediate
83135b38c60SMatthew G. Knepley
83220f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmSetNumSpecies()`, `DMSwarmSetType()`, `DMSwarmType`
83335b38c60SMatthew G. Knepley @*/
DMSwarmGetNumSpecies(DM sw,PetscInt * Ns)834d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmGetNumSpecies(DM sw, PetscInt *Ns)
835d71ae5a4SJacob Faibussowitsch {
83635b38c60SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data;
83735b38c60SMatthew G. Knepley
83835b38c60SMatthew G. Knepley PetscFunctionBegin;
83935b38c60SMatthew G. Knepley *Ns = swarm->Ns;
8403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
84135b38c60SMatthew G. Knepley }
84235b38c60SMatthew G. Knepley
84335b38c60SMatthew G. Knepley /*@
84435b38c60SMatthew G. Knepley DMSwarmSetNumSpecies - Set the number of particle species
84535b38c60SMatthew G. Knepley
84620f4b53cSBarry Smith Not Collective
84735b38c60SMatthew G. Knepley
84860225df5SJacob Faibussowitsch Input Parameters:
84960225df5SJacob Faibussowitsch + sw - the `DMSWARM`
85035b38c60SMatthew G. Knepley - Ns - the number of species
85135b38c60SMatthew G. Knepley
85235b38c60SMatthew G. Knepley Level: intermediate
85335b38c60SMatthew G. Knepley
85420f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmGetNumSpecies()`, `DMSwarmSetType()`, `DMSwarmType`
85535b38c60SMatthew G. Knepley @*/
DMSwarmSetNumSpecies(DM sw,PetscInt Ns)856d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmSetNumSpecies(DM sw, PetscInt Ns)
857d71ae5a4SJacob Faibussowitsch {
85835b38c60SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data;
85935b38c60SMatthew G. Knepley
86035b38c60SMatthew G. Knepley PetscFunctionBegin;
86135b38c60SMatthew G. Knepley swarm->Ns = Ns;
8623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
86335b38c60SMatthew G. Knepley }
86435b38c60SMatthew G. Knepley
86535b38c60SMatthew G. Knepley /*@C
8666c5a79ebSMatthew G. Knepley DMSwarmGetCoordinateFunction - Get the function setting initial particle positions, if it exists
8676c5a79ebSMatthew G. Knepley
86820f4b53cSBarry Smith Not Collective
8696c5a79ebSMatthew G. Knepley
87060225df5SJacob Faibussowitsch Input Parameter:
87160225df5SJacob Faibussowitsch . sw - the `DMSWARM`
8726c5a79ebSMatthew G. Knepley
8736c5a79ebSMatthew G. Knepley Output Parameter:
8748434afd1SBarry Smith . coordFunc - the function setting initial particle positions, or `NULL`, see `PetscSimplePointFn` for the calling sequence
8756c5a79ebSMatthew G. Knepley
8766c5a79ebSMatthew G. Knepley Level: intermediate
8776c5a79ebSMatthew G. Knepley
8788434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmSetCoordinateFunction()`, `DMSwarmGetVelocityFunction()`, `DMSwarmInitializeCoordinates()`, `PetscSimplePointFn`
8796c5a79ebSMatthew G. Knepley @*/
DMSwarmGetCoordinateFunction(DM sw,PetscSimplePointFn ** coordFunc)8808434afd1SBarry Smith PetscErrorCode DMSwarmGetCoordinateFunction(DM sw, PetscSimplePointFn **coordFunc)
881d71ae5a4SJacob Faibussowitsch {
8826c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data;
8836c5a79ebSMatthew G. Knepley
8846c5a79ebSMatthew G. Knepley PetscFunctionBegin;
8856c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1);
8864f572ea9SToby Isaac PetscAssertPointer(coordFunc, 2);
8876c5a79ebSMatthew G. Knepley *coordFunc = swarm->coordFunc;
8883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8896c5a79ebSMatthew G. Knepley }
8906c5a79ebSMatthew G. Knepley
8916c5a79ebSMatthew G. Knepley /*@C
8926c5a79ebSMatthew G. Knepley DMSwarmSetCoordinateFunction - Set the function setting initial particle positions
8936c5a79ebSMatthew G. Knepley
89420f4b53cSBarry Smith Not Collective
8956c5a79ebSMatthew G. Knepley
89660225df5SJacob Faibussowitsch Input Parameters:
89760225df5SJacob Faibussowitsch + sw - the `DMSWARM`
8988434afd1SBarry Smith - coordFunc - the function setting initial particle positions, see `PetscSimplePointFn` for the calling sequence
8996c5a79ebSMatthew G. Knepley
9006c5a79ebSMatthew G. Knepley Level: intermediate
9016c5a79ebSMatthew G. Knepley
9028434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmGetCoordinateFunction()`, `DMSwarmSetVelocityFunction()`, `DMSwarmInitializeCoordinates()`, `PetscSimplePointFn`
9036c5a79ebSMatthew G. Knepley @*/
DMSwarmSetCoordinateFunction(DM sw,PetscSimplePointFn * coordFunc)9048434afd1SBarry Smith PetscErrorCode DMSwarmSetCoordinateFunction(DM sw, PetscSimplePointFn *coordFunc)
905d71ae5a4SJacob Faibussowitsch {
9066c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data;
9076c5a79ebSMatthew G. Knepley
9086c5a79ebSMatthew G. Knepley PetscFunctionBegin;
9096c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1);
9106c5a79ebSMatthew G. Knepley PetscValidFunction(coordFunc, 2);
9116c5a79ebSMatthew G. Knepley swarm->coordFunc = coordFunc;
9123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
9136c5a79ebSMatthew G. Knepley }
9146c5a79ebSMatthew G. Knepley
9156c5a79ebSMatthew G. Knepley /*@C
91660225df5SJacob Faibussowitsch DMSwarmGetVelocityFunction - Get the function setting initial particle velocities, if it exists
9176c5a79ebSMatthew G. Knepley
91820f4b53cSBarry Smith Not Collective
9196c5a79ebSMatthew G. Knepley
92060225df5SJacob Faibussowitsch Input Parameter:
92160225df5SJacob Faibussowitsch . sw - the `DMSWARM`
9226c5a79ebSMatthew G. Knepley
9236c5a79ebSMatthew G. Knepley Output Parameter:
9248434afd1SBarry Smith . velFunc - the function setting initial particle velocities, or `NULL`, see `PetscSimplePointFn` for the calling sequence
9256c5a79ebSMatthew G. Knepley
9266c5a79ebSMatthew G. Knepley Level: intermediate
9276c5a79ebSMatthew G. Knepley
9288434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmSetVelocityFunction()`, `DMSwarmGetCoordinateFunction()`, `DMSwarmInitializeVelocities()`, `PetscSimplePointFn`
9296c5a79ebSMatthew G. Knepley @*/
DMSwarmGetVelocityFunction(DM sw,PetscSimplePointFn ** velFunc)9308434afd1SBarry Smith PetscErrorCode DMSwarmGetVelocityFunction(DM sw, PetscSimplePointFn **velFunc)
931d71ae5a4SJacob Faibussowitsch {
9326c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data;
9336c5a79ebSMatthew G. Knepley
9346c5a79ebSMatthew G. Knepley PetscFunctionBegin;
9356c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1);
9364f572ea9SToby Isaac PetscAssertPointer(velFunc, 2);
9376c5a79ebSMatthew G. Knepley *velFunc = swarm->velFunc;
9383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
9396c5a79ebSMatthew G. Knepley }
9406c5a79ebSMatthew G. Knepley
9416c5a79ebSMatthew G. Knepley /*@C
9426c5a79ebSMatthew G. Knepley DMSwarmSetVelocityFunction - Set the function setting initial particle velocities
9436c5a79ebSMatthew G. Knepley
94420f4b53cSBarry Smith Not Collective
9456c5a79ebSMatthew G. Knepley
94660225df5SJacob Faibussowitsch Input Parameters:
947a4e35b19SJacob Faibussowitsch + sw - the `DMSWARM`
9488434afd1SBarry Smith - velFunc - the function setting initial particle velocities, see `PetscSimplePointFn` for the calling sequence
9496c5a79ebSMatthew G. Knepley
9506c5a79ebSMatthew G. Knepley Level: intermediate
9516c5a79ebSMatthew G. Knepley
9528434afd1SBarry Smith .seealso: `DMSWARM`, `DMSwarmGetVelocityFunction()`, `DMSwarmSetCoordinateFunction()`, `DMSwarmInitializeVelocities()`, `PetscSimplePointFn`
9536c5a79ebSMatthew G. Knepley @*/
DMSwarmSetVelocityFunction(DM sw,PetscSimplePointFn * velFunc)9548434afd1SBarry Smith PetscErrorCode DMSwarmSetVelocityFunction(DM sw, PetscSimplePointFn *velFunc)
955d71ae5a4SJacob Faibussowitsch {
9566c5a79ebSMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)sw->data;
9576c5a79ebSMatthew G. Knepley
9586c5a79ebSMatthew G. Knepley PetscFunctionBegin;
9596c5a79ebSMatthew G. Knepley PetscValidHeaderSpecific(sw, DM_CLASSID, 1);
9606c5a79ebSMatthew G. Knepley PetscValidFunction(velFunc, 2);
9616c5a79ebSMatthew G. Knepley swarm->velFunc = velFunc;
9623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
9636c5a79ebSMatthew G. Knepley }
9646c5a79ebSMatthew G. Knepley
9656c5a79ebSMatthew G. Knepley /*@C
96635b38c60SMatthew G. Knepley DMSwarmComputeLocalSize - Compute the local number and distribution of particles based upon a density function
96735b38c60SMatthew G. Knepley
96820f4b53cSBarry Smith Not Collective
96935b38c60SMatthew G. Knepley
97035b38c60SMatthew G. Knepley Input Parameters:
97120f4b53cSBarry Smith + sw - The `DMSWARM`
97235b38c60SMatthew G. Knepley . N - The target number of particles
97335b38c60SMatthew G. Knepley - density - The density field for the particle layout, normalized to unity
97435b38c60SMatthew G. Knepley
97535b38c60SMatthew G. Knepley Level: advanced
97635b38c60SMatthew G. Knepley
97720f4b53cSBarry Smith Note:
97820f4b53cSBarry Smith One particle will be created for each species.
97920f4b53cSBarry Smith
98020f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSizeFromOptions()`
98135b38c60SMatthew G. Knepley @*/
DMSwarmComputeLocalSize(DM sw,PetscInt N,PetscProbFn * density)982f8662bd6SBarry Smith PetscErrorCode DMSwarmComputeLocalSize(DM sw, PetscInt N, PetscProbFn *density)
983d71ae5a4SJacob Faibussowitsch {
98435b38c60SMatthew G. Knepley DM dm;
98519307e5cSMatthew G. Knepley DMSwarmCellDM celldm;
98635b38c60SMatthew G. Knepley PetscQuadrature quad;
98735b38c60SMatthew G. Knepley const PetscReal *xq, *wq;
988ea7032a0SMatthew G. Knepley PetscReal *n_int;
98919307e5cSMatthew G. Knepley PetscInt *npc_s, *swarm_cellid, Ni;
990ea7032a0SMatthew G. Knepley PetscReal gmin[3], gmax[3], xi0[3];
991ea7032a0SMatthew G. Knepley PetscInt Ns, cStart, cEnd, c, dim, d, Nq, q, Np = 0, p, s;
99235b38c60SMatthew G. Knepley PetscBool simplex;
99319307e5cSMatthew G. Knepley const char *cellid;
99435b38c60SMatthew G. Knepley
99535b38c60SMatthew G. Knepley PetscFunctionBegin;
9969566063dSJacob Faibussowitsch PetscCall(DMSwarmGetNumSpecies(sw, &Ns));
9979566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(sw, &dm));
9989566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim));
999ea7032a0SMatthew G. Knepley PetscCall(DMGetBoundingBox(dm, gmin, gmax));
10009566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd));
10019566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex));
10026858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(dm));
10039566063dSJacob Faibussowitsch if (simplex) PetscCall(PetscDTStroudConicalQuadrature(dim, 1, 5, -1.0, 1.0, &quad));
10049566063dSJacob Faibussowitsch else PetscCall(PetscDTGaussTensorQuadrature(dim, 1, 5, -1.0, 1.0, &quad));
10059566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, &xq, &wq));
1006ea7032a0SMatthew G. Knepley PetscCall(PetscCalloc2(Ns, &n_int, (cEnd - cStart) * Ns, &npc_s));
100735b38c60SMatthew G. Knepley /* Integrate the density function to get the number of particles in each cell */
100835b38c60SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0;
100935b38c60SMatthew G. Knepley for (c = 0; c < cEnd - cStart; ++c) {
101035b38c60SMatthew G. Knepley const PetscInt cell = c + cStart;
1011ea7032a0SMatthew G. Knepley PetscReal v0[3], J[9], invJ[9], detJ, detJp = 2. / (gmax[0] - gmin[0]), xr[3], den;
101235b38c60SMatthew G. Knepley
1013ea7032a0SMatthew G. Knepley /* Have to transform quadrature points/weights to cell domain */
10149566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, cell, NULL, v0, J, invJ, &detJ));
1015ea7032a0SMatthew G. Knepley PetscCall(PetscArrayzero(n_int, Ns));
101635b38c60SMatthew G. Knepley for (q = 0; q < Nq; ++q) {
101735b38c60SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, &xq[q * dim], xr);
1018ea7032a0SMatthew G. Knepley /* Have to transform mesh to domain of definition of PDF, [-1, 1], and weight PDF by |J|/2 */
1019ea7032a0SMatthew G. Knepley xr[0] = detJp * (xr[0] - gmin[0]) - 1.;
1020ea7032a0SMatthew G. Knepley
1021ea7032a0SMatthew G. Knepley for (s = 0; s < Ns; ++s) {
1022ea7032a0SMatthew G. Knepley PetscCall(density(xr, NULL, &den));
1023ea7032a0SMatthew G. Knepley n_int[s] += (detJp * den) * (detJ * wq[q]) / (PetscReal)Ns;
102435b38c60SMatthew G. Knepley }
1025ea7032a0SMatthew G. Knepley }
1026ea7032a0SMatthew G. Knepley for (s = 0; s < Ns; ++s) {
1027ea7032a0SMatthew G. Knepley Ni = N;
1028f940b0e3Sdanofinn npc_s[c * Ns + s] += (PetscInt)(Ni * n_int[s] + 0.5); // TODO Wish we wrapped round()
1029ea7032a0SMatthew G. Knepley Np += npc_s[c * Ns + s];
1030ea7032a0SMatthew G. Knepley }
103135b38c60SMatthew G. Knepley }
10329566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&quad));
10339566063dSJacob Faibussowitsch PetscCall(DMSwarmSetLocalSizes(sw, Np, 0));
103419307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm));
103519307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid));
103619307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
103735b38c60SMatthew G. Knepley for (c = 0, p = 0; c < cEnd - cStart; ++c) {
1038ea7032a0SMatthew G. Knepley for (s = 0; s < Ns; ++s) {
103919307e5cSMatthew G. Knepley for (q = 0; q < npc_s[c * Ns + s]; ++q, ++p) swarm_cellid[p] = c;
1040ea7032a0SMatthew G. Knepley }
104135b38c60SMatthew G. Knepley }
104219307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, cellid, NULL, NULL, (void **)&swarm_cellid));
1043ea7032a0SMatthew G. Knepley PetscCall(PetscFree2(n_int, npc_s));
10443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
104535b38c60SMatthew G. Knepley }
104635b38c60SMatthew G. Knepley
104735b38c60SMatthew G. Knepley /*@
104835b38c60SMatthew G. Knepley DMSwarmComputeLocalSizeFromOptions - Compute the local number and distribution of particles based upon a density function determined by options
104935b38c60SMatthew G. Knepley
105020f4b53cSBarry Smith Not Collective
105135b38c60SMatthew G. Knepley
10522fe279fdSBarry Smith Input Parameter:
10532fe279fdSBarry Smith . sw - The `DMSWARM`
105435b38c60SMatthew G. Knepley
105535b38c60SMatthew G. Knepley Level: advanced
105635b38c60SMatthew G. Knepley
105720f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()`
105835b38c60SMatthew G. Knepley @*/
DMSwarmComputeLocalSizeFromOptions(DM sw)1059d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmComputeLocalSizeFromOptions(DM sw)
1060d71ae5a4SJacob Faibussowitsch {
1061f8662bd6SBarry Smith PetscProbFn *pdf;
106235b38c60SMatthew G. Knepley const char *prefix;
10636c5a79ebSMatthew G. Knepley char funcname[PETSC_MAX_PATH_LEN];
10646c5a79ebSMatthew G. Knepley PetscInt *N, Ns, dim, n;
10656c5a79ebSMatthew G. Knepley PetscBool flg;
10666c5a79ebSMatthew G. Knepley PetscMPIInt size, rank;
106735b38c60SMatthew G. Knepley
106835b38c60SMatthew G. Knepley PetscFunctionBegin;
10696c5a79ebSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sw), &size));
10706c5a79ebSMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)sw), &rank));
10716c5a79ebSMatthew G. Knepley PetscCall(PetscCalloc1(size, &N));
1072d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)sw), "", "DMSwarm Options", "DMSWARM");
10736c5a79ebSMatthew G. Knepley n = size;
10746c5a79ebSMatthew G. Knepley PetscCall(PetscOptionsIntArray("-dm_swarm_num_particles", "The target number of particles", "", N, &n, NULL));
10756c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetNumSpecies(sw, &Ns));
10769566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-dm_swarm_num_species", "The number of species", "DMSwarmSetNumSpecies", Ns, &Ns, &flg));
10779566063dSJacob Faibussowitsch if (flg) PetscCall(DMSwarmSetNumSpecies(sw, Ns));
10786c5a79ebSMatthew G. Knepley PetscCall(PetscOptionsString("-dm_swarm_coordinate_function", "Function to determine particle coordinates", "DMSwarmSetCoordinateFunction", funcname, funcname, sizeof(funcname), &flg));
1079d0609cedSBarry Smith PetscOptionsEnd();
10806c5a79ebSMatthew G. Knepley if (flg) {
10818434afd1SBarry Smith PetscSimplePointFn *coordFunc;
108235b38c60SMatthew G. Knepley
10836c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetNumSpecies(sw, &Ns));
10846c5a79ebSMatthew G. Knepley PetscCall(PetscDLSym(NULL, funcname, (void **)&coordFunc));
10856c5a79ebSMatthew G. Knepley PetscCheck(coordFunc, PetscObjectComm((PetscObject)sw), PETSC_ERR_ARG_WRONG, "Could not locate function %s", funcname);
10866c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetNumSpecies(sw, &Ns));
10876c5a79ebSMatthew G. Knepley PetscCall(DMSwarmSetLocalSizes(sw, N[rank] * Ns, 0));
10886c5a79ebSMatthew G. Knepley PetscCall(DMSwarmSetCoordinateFunction(sw, coordFunc));
10896c5a79ebSMatthew G. Knepley } else {
10909566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim));
10919566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sw, &prefix));
10929566063dSJacob Faibussowitsch PetscCall(PetscProbCreateFromOptions(dim, prefix, "-dm_swarm_coordinate_density", &pdf, NULL, NULL));
10936c5a79ebSMatthew G. Knepley PetscCall(DMSwarmComputeLocalSize(sw, N[rank], pdf));
10946c5a79ebSMatthew G. Knepley }
10956c5a79ebSMatthew G. Knepley PetscCall(PetscFree(N));
10963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
109735b38c60SMatthew G. Knepley }
109835b38c60SMatthew G. Knepley
109935b38c60SMatthew G. Knepley /*@
110035b38c60SMatthew G. Knepley DMSwarmInitializeCoordinates - Determine the initial coordinates of particles for a PIC method
110135b38c60SMatthew G. Knepley
110220f4b53cSBarry Smith Not Collective
110335b38c60SMatthew G. Knepley
110420f4b53cSBarry Smith Input Parameter:
110520f4b53cSBarry Smith . sw - The `DMSWARM`
110635b38c60SMatthew G. Knepley
110735b38c60SMatthew G. Knepley Level: advanced
110835b38c60SMatthew G. Knepley
110920f4b53cSBarry Smith Note:
111020f4b53cSBarry Smith Currently, we randomly place particles in their assigned cell
111120f4b53cSBarry Smith
111220f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()`, `DMSwarmInitializeVelocities()`
111335b38c60SMatthew G. Knepley @*/
DMSwarmInitializeCoordinates(DM sw)1114d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmInitializeCoordinates(DM sw)
1115d71ae5a4SJacob Faibussowitsch {
111619307e5cSMatthew G. Knepley DMSwarmCellDM celldm;
11178434afd1SBarry Smith PetscSimplePointFn *coordFunc;
111835b38c60SMatthew G. Knepley PetscScalar *weight;
11196c5a79ebSMatthew G. Knepley PetscReal *x;
112035b38c60SMatthew G. Knepley PetscInt *species;
11216c5a79ebSMatthew G. Knepley void *ctx;
112235b38c60SMatthew G. Knepley PetscBool removePoints = PETSC_TRUE;
112335b38c60SMatthew G. Knepley PetscDataType dtype;
112419307e5cSMatthew G. Knepley PetscInt Nfc, Np, p, Ns, dim, d, bs;
112519307e5cSMatthew G. Knepley const char **coordFields;
112635b38c60SMatthew G. Knepley
112735b38c60SMatthew G. Knepley PetscFunctionBeginUser;
11286c5a79ebSMatthew G. Knepley PetscCall(DMGetDimension(sw, &dim));
11296c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(sw, &Np));
11309566063dSJacob Faibussowitsch PetscCall(DMSwarmGetNumSpecies(sw, &Ns));
11316c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetCoordinateFunction(sw, &coordFunc));
11326c5a79ebSMatthew G. Knepley
113319307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(sw, &celldm));
113419307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields));
113519307e5cSMatthew G. Knepley PetscCheck(Nfc == 1, PetscObjectComm((PetscObject)sw), PETSC_ERR_SUP, "We only support a single coordinate field right now, not %" PetscInt_FMT, Nfc);
113619307e5cSMatthew G. Knepley
113719307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, coordFields[0], &bs, &dtype, (void **)&x));
11386c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, "w_q", &bs, &dtype, (void **)&weight));
11396c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, "species", NULL, NULL, (void **)&species));
11406c5a79ebSMatthew G. Knepley if (coordFunc) {
11416c5a79ebSMatthew G. Knepley PetscCall(DMGetApplicationContext(sw, &ctx));
11426c5a79ebSMatthew G. Knepley for (p = 0; p < Np; ++p) {
11436c5a79ebSMatthew G. Knepley PetscScalar X[3];
11446c5a79ebSMatthew G. Knepley
11456c5a79ebSMatthew G. Knepley PetscCall((*coordFunc)(dim, 0., NULL, p, X, ctx));
11466c5a79ebSMatthew G. Knepley for (d = 0; d < dim; ++d) x[p * dim + d] = PetscRealPart(X[d]);
11476c5a79ebSMatthew G. Knepley weight[p] = 1.0;
11486c5a79ebSMatthew G. Knepley species[p] = p % Ns;
11496c5a79ebSMatthew G. Knepley }
11506c5a79ebSMatthew G. Knepley } else {
11516c5a79ebSMatthew G. Knepley DM dm;
11526c5a79ebSMatthew G. Knepley PetscRandom rnd;
11536c5a79ebSMatthew G. Knepley PetscReal xi0[3];
11546c5a79ebSMatthew G. Knepley PetscInt cStart, cEnd, c;
11556c5a79ebSMatthew G. Knepley
11569566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(sw, &dm));
11579566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd));
1158ea7032a0SMatthew G. Knepley PetscCall(DMGetApplicationContext(sw, &ctx));
115935b38c60SMatthew G. Knepley
116035b38c60SMatthew G. Knepley /* Set particle position randomly in cell, set weights to 1 */
11619566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)dm), &rnd));
11629566063dSJacob Faibussowitsch PetscCall(PetscRandomSetInterval(rnd, -1.0, 1.0));
11639566063dSJacob Faibussowitsch PetscCall(PetscRandomSetFromOptions(rnd));
11649566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(sw));
116535b38c60SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0;
116635b38c60SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) {
116735b38c60SMatthew G. Knepley PetscReal v0[3], J[9], invJ[9], detJ;
116835b38c60SMatthew G. Knepley PetscInt *pidx, Npc, q;
116935b38c60SMatthew G. Knepley
11709566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(sw, c, &Npc, &pidx));
11719566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, c, NULL, v0, J, invJ, &detJ));
117235b38c60SMatthew G. Knepley for (q = 0; q < Npc; ++q) {
117335b38c60SMatthew G. Knepley const PetscInt p = pidx[q];
117435b38c60SMatthew G. Knepley PetscReal xref[3];
117535b38c60SMatthew G. Knepley
11769566063dSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscRandomGetValueReal(rnd, &xref[d]));
117735b38c60SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, xref, &x[p * dim]);
117835b38c60SMatthew G. Knepley
1179ea7032a0SMatthew G. Knepley weight[p] = 1.0 / Np;
11806c5a79ebSMatthew G. Knepley species[p] = p % Ns;
118135b38c60SMatthew G. Knepley }
1182fe11354eSMatthew G. Knepley PetscCall(DMSwarmSortRestorePointsPerCell(sw, c, &Npc, &pidx));
118335b38c60SMatthew G. Knepley }
11849566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&rnd));
11859566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(sw));
11866c5a79ebSMatthew G. Knepley }
118719307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, coordFields[0], NULL, NULL, (void **)&x));
11886c5a79ebSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, "w_q", NULL, NULL, (void **)&weight));
11899566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(sw, "species", NULL, NULL, (void **)&species));
11906c5a79ebSMatthew G. Knepley
11919566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate(sw, removePoints));
11929566063dSJacob Faibussowitsch PetscCall(DMLocalizeCoordinates(sw));
11933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
119435b38c60SMatthew G. Knepley }
119535b38c60SMatthew G. Knepley
119635b38c60SMatthew G. Knepley /*@C
119735b38c60SMatthew G. Knepley DMSwarmInitializeVelocities - Set the initial velocities of particles using a distribution.
119835b38c60SMatthew G. Knepley
119920f4b53cSBarry Smith Collective
120035b38c60SMatthew G. Knepley
120135b38c60SMatthew G. Knepley Input Parameters:
120220f4b53cSBarry Smith + sw - The `DMSWARM` object
120335b38c60SMatthew G. Knepley . sampler - A function which uniformly samples the velocity PDF
120435b38c60SMatthew G. Knepley - v0 - The velocity scale for nondimensionalization for each species
120535b38c60SMatthew G. Knepley
120635b38c60SMatthew G. Knepley Level: advanced
120735b38c60SMatthew G. Knepley
120820f4b53cSBarry Smith Note:
120920f4b53cSBarry 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.
121020f4b53cSBarry Smith
121120f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()`, `DMSwarmInitializeCoordinates()`, `DMSwarmInitializeVelocitiesFromOptions()`
121235b38c60SMatthew G. Knepley @*/
DMSwarmInitializeVelocities(DM sw,PetscProbFn * sampler,const PetscReal v0[])1213f8662bd6SBarry Smith PetscErrorCode DMSwarmInitializeVelocities(DM sw, PetscProbFn *sampler, const PetscReal v0[])
1214d71ae5a4SJacob Faibussowitsch {
12158434afd1SBarry Smith PetscSimplePointFn *velFunc;
121635b38c60SMatthew G. Knepley PetscReal *v;
121735b38c60SMatthew G. Knepley PetscInt *species;
12186c5a79ebSMatthew G. Knepley void *ctx;
121935b38c60SMatthew G. Knepley PetscInt dim, Np, p;
122035b38c60SMatthew G. Knepley
122135b38c60SMatthew G. Knepley PetscFunctionBegin;
12226c5a79ebSMatthew G. Knepley PetscCall(DMSwarmGetVelocityFunction(sw, &velFunc));
122335b38c60SMatthew G. Knepley
12249566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim));
12259566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(sw, &Np));
12269566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(sw, "velocity", NULL, NULL, (void **)&v));
12279566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(sw, "species", NULL, NULL, (void **)&species));
12286c5a79ebSMatthew G. Knepley if (v0[0] == 0.) {
12296c5a79ebSMatthew G. Knepley PetscCall(PetscArrayzero(v, Np * dim));
12306c5a79ebSMatthew G. Knepley } else if (velFunc) {
12316c5a79ebSMatthew G. Knepley PetscCall(DMGetApplicationContext(sw, &ctx));
12326c5a79ebSMatthew G. Knepley for (p = 0; p < Np; ++p) {
12336c5a79ebSMatthew G. Knepley PetscInt s = species[p], d;
12346c5a79ebSMatthew G. Knepley PetscScalar vel[3];
12356c5a79ebSMatthew G. Knepley
12366c5a79ebSMatthew G. Knepley PetscCall((*velFunc)(dim, 0., NULL, p, vel, ctx));
12376c5a79ebSMatthew G. Knepley for (d = 0; d < dim; ++d) v[p * dim + d] = (v0[s] / v0[0]) * PetscRealPart(vel[d]);
12386c5a79ebSMatthew G. Knepley }
12396c5a79ebSMatthew G. Knepley } else {
12406c5a79ebSMatthew G. Knepley PetscRandom rnd;
12416c5a79ebSMatthew G. Knepley
12426c5a79ebSMatthew G. Knepley PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)sw), &rnd));
12436c5a79ebSMatthew G. Knepley PetscCall(PetscRandomSetInterval(rnd, 0, 1.));
12446c5a79ebSMatthew G. Knepley PetscCall(PetscRandomSetFromOptions(rnd));
12456c5a79ebSMatthew G. Knepley
124635b38c60SMatthew G. Knepley for (p = 0; p < Np; ++p) {
124735b38c60SMatthew G. Knepley PetscInt s = species[p], d;
124835b38c60SMatthew G. Knepley PetscReal a[3], vel[3];
124935b38c60SMatthew G. Knepley
12509566063dSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscRandomGetValueReal(rnd, &a[d]));
12519566063dSJacob Faibussowitsch PetscCall(sampler(a, NULL, vel));
1252ad540459SPierre Jolivet for (d = 0; d < dim; ++d) v[p * dim + d] = (v0[s] / v0[0]) * vel[d];
125335b38c60SMatthew G. Knepley }
12546c5a79ebSMatthew G. Knepley PetscCall(PetscRandomDestroy(&rnd));
12556c5a79ebSMatthew G. Knepley }
12569566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(sw, "velocity", NULL, NULL, (void **)&v));
12579566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(sw, "species", NULL, NULL, (void **)&species));
12583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
125935b38c60SMatthew G. Knepley }
126035b38c60SMatthew G. Knepley
126135b38c60SMatthew G. Knepley /*@
126235b38c60SMatthew G. Knepley DMSwarmInitializeVelocitiesFromOptions - Set the initial velocities of particles using a distribution determined from options.
126335b38c60SMatthew G. Knepley
126420f4b53cSBarry Smith Collective
126535b38c60SMatthew G. Knepley
126635b38c60SMatthew G. Knepley Input Parameters:
126720f4b53cSBarry Smith + sw - The `DMSWARM` object
126835b38c60SMatthew G. Knepley - v0 - The velocity scale for nondimensionalization for each species
126935b38c60SMatthew G. Knepley
127035b38c60SMatthew G. Knepley Level: advanced
127135b38c60SMatthew G. Knepley
127220f4b53cSBarry Smith .seealso: `DMSWARM`, `DMSwarmComputeLocalSize()`, `DMSwarmInitializeCoordinates()`, `DMSwarmInitializeVelocities()`
127335b38c60SMatthew G. Knepley @*/
DMSwarmInitializeVelocitiesFromOptions(DM sw,const PetscReal v0[])1274d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmInitializeVelocitiesFromOptions(DM sw, const PetscReal v0[])
1275d71ae5a4SJacob Faibussowitsch {
1276f8662bd6SBarry Smith PetscProbFn *sampler;
127735b38c60SMatthew G. Knepley PetscInt dim;
127835b38c60SMatthew G. Knepley const char *prefix;
12796c5a79ebSMatthew G. Knepley char funcname[PETSC_MAX_PATH_LEN];
12806c5a79ebSMatthew G. Knepley PetscBool flg;
128135b38c60SMatthew G. Knepley
128235b38c60SMatthew G. Knepley PetscFunctionBegin;
1283d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)sw), "", "DMSwarm Options", "DMSWARM");
12846c5a79ebSMatthew G. Knepley PetscCall(PetscOptionsString("-dm_swarm_velocity_function", "Function to determine particle velocities", "DMSwarmSetVelocityFunction", funcname, funcname, sizeof(funcname), &flg));
1285d0609cedSBarry Smith PetscOptionsEnd();
12866c5a79ebSMatthew G. Knepley if (flg) {
12878434afd1SBarry Smith PetscSimplePointFn *velFunc;
12886c5a79ebSMatthew G. Knepley
12896c5a79ebSMatthew G. Knepley PetscCall(PetscDLSym(NULL, funcname, (void **)&velFunc));
12906c5a79ebSMatthew G. Knepley PetscCheck(velFunc, PetscObjectComm((PetscObject)sw), PETSC_ERR_ARG_WRONG, "Could not locate function %s", funcname);
12916c5a79ebSMatthew G. Knepley PetscCall(DMSwarmSetVelocityFunction(sw, velFunc));
12926c5a79ebSMatthew G. Knepley }
12939566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim));
12949566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sw, &prefix));
12959566063dSJacob Faibussowitsch PetscCall(PetscProbCreateFromOptions(dim, prefix, "-dm_swarm_velocity_density", NULL, NULL, &sampler));
12969566063dSJacob Faibussowitsch PetscCall(DMSwarmInitializeVelocities(sw, sampler, v0));
12973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
129835b38c60SMatthew G. Knepley }
12999d50c5ebSMatthew G. Knepley
13009d50c5ebSMatthew G. Knepley // The input vector U is assumed to be from a PetscFE. The Swarm fields are input as auxiliary values.
DMProjectFieldLocal_Swarm(DM dm,PetscReal time,Vec U,PetscPointFn ** funcs,InsertMode mode,Vec X)13019d50c5ebSMatthew G. Knepley PetscErrorCode DMProjectFieldLocal_Swarm(DM dm, PetscReal time, Vec U, PetscPointFn **funcs, InsertMode mode, Vec X)
13029d50c5ebSMatthew G. Knepley {
13039d50c5ebSMatthew G. Knepley MPI_Comm comm;
13049d50c5ebSMatthew G. Knepley DM dmIn;
13059d50c5ebSMatthew G. Knepley PetscDS ds;
13069d50c5ebSMatthew G. Knepley PetscTabulation *T;
13079d50c5ebSMatthew G. Knepley DMSwarmCellDM celldm;
13089d50c5ebSMatthew G. Knepley PetscScalar *a, *val, *u, *u_x;
13099d50c5ebSMatthew G. Knepley PetscFEGeom fegeom;
13109d50c5ebSMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0};
13119d50c5ebSMatthew G. Knepley PetscInt dim, dE, Np, n, Nf, Nfc, Nfu, cStart, cEnd, maxC = 0, totbs = 0;
13129d50c5ebSMatthew G. Knepley const char **coordFields, **fields;
13139d50c5ebSMatthew G. Knepley PetscReal **coordVals, **vals;
13149d50c5ebSMatthew G. Knepley PetscInt *cbs, *bs, *uOff, *uOff_x;
13159d50c5ebSMatthew G. Knepley
13169d50c5ebSMatthew G. Knepley PetscFunctionBegin;
13179d50c5ebSMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
13189d50c5ebSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn));
13199d50c5ebSMatthew G. Knepley PetscCall(DMGetDimension(dmIn, &dim));
13209d50c5ebSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dmIn, &dE));
13219d50c5ebSMatthew G. Knepley PetscCall(DMGetDS(dmIn, &ds));
13229d50c5ebSMatthew G. Knepley PetscCall(PetscDSGetNumFields(ds, &Nfu));
13239d50c5ebSMatthew G. Knepley PetscCall(PetscDSGetComponentOffsets(ds, &uOff));
13249d50c5ebSMatthew G. Knepley PetscCall(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x));
13259d50c5ebSMatthew G. Knepley PetscCall(PetscDSGetTabulation(ds, &T));
13269d50c5ebSMatthew G. Knepley PetscCall(PetscDSGetEvaluationArrays(ds, &u, NULL, &u_x));
13279d50c5ebSMatthew G. Knepley PetscCall(PetscMalloc3(dim, &v0, dim * dim, &J, dim * dim, &invJ));
13289d50c5ebSMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dmIn, 0, &cStart, &cEnd));
13299d50c5ebSMatthew G. Knepley
13309d50c5ebSMatthew G. Knepley fegeom.dim = dim;
13319d50c5ebSMatthew G. Knepley fegeom.dimEmbed = dE;
13329d50c5ebSMatthew G. Knepley fegeom.v = v0;
13339d50c5ebSMatthew G. Knepley fegeom.xi = v0ref;
13349d50c5ebSMatthew G. Knepley fegeom.J = J;
13359d50c5ebSMatthew G. Knepley fegeom.invJ = invJ;
13369d50c5ebSMatthew G. Knepley fegeom.detJ = &detJ;
13379d50c5ebSMatthew G. Knepley
13389d50c5ebSMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(dm, &Np));
13399d50c5ebSMatthew G. Knepley PetscCall(VecGetLocalSize(X, &n));
13409d50c5ebSMatthew G. Knepley PetscCheck(n == Np, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Output vector local size %" PetscInt_FMT " != %" PetscInt_FMT " number of local particles", n, Np);
13419d50c5ebSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(dm, &celldm));
13429d50c5ebSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields));
13439d50c5ebSMatthew G. Knepley PetscCall(DMSwarmCellDMGetFields(celldm, &Nf, &fields));
13449d50c5ebSMatthew G. Knepley
13459d50c5ebSMatthew G. Knepley PetscCall(PetscMalloc2(Nfc, &coordVals, Nfc, &cbs));
13469d50c5ebSMatthew G. Knepley for (PetscInt i = 0; i < Nfc; ++i) PetscCall(DMSwarmGetField(dm, coordFields[i], &cbs[i], NULL, (void **)&coordVals[i]));
13479d50c5ebSMatthew G. Knepley PetscCall(PetscMalloc2(Nf, &vals, Nfc, &bs));
13489d50c5ebSMatthew G. Knepley for (PetscInt i = 0; i < Nf; ++i) {
13499d50c5ebSMatthew G. Knepley PetscCall(DMSwarmGetField(dm, fields[i], &bs[i], NULL, (void **)&vals[i]));
13509d50c5ebSMatthew G. Knepley totbs += bs[i];
13519d50c5ebSMatthew G. Knepley }
13529d50c5ebSMatthew G. Knepley
13539d50c5ebSMatthew G. Knepley PetscCall(DMSwarmSortGetAccess(dm));
13549d50c5ebSMatthew G. Knepley for (PetscInt cell = cStart; cell < cEnd; ++cell) {
13559d50c5ebSMatthew G. Knepley PetscInt *pindices, Npc;
13569d50c5ebSMatthew G. Knepley
13579d50c5ebSMatthew G. Knepley PetscCall(DMSwarmSortGetPointsPerCell(dm, cell, &Npc, &pindices));
13589d50c5ebSMatthew G. Knepley maxC = PetscMax(maxC, Npc);
13599d50c5ebSMatthew G. Knepley PetscCall(DMSwarmSortRestorePointsPerCell(dm, cell, &Npc, &pindices));
13609d50c5ebSMatthew G. Knepley }
13619d50c5ebSMatthew G. Knepley PetscCall(PetscMalloc3(maxC * dim, &xi, maxC * totbs, &val, Nfu, &T));
13629d50c5ebSMatthew G. Knepley PetscCall(VecGetArray(X, &a));
13639d50c5ebSMatthew G. Knepley {
13649d50c5ebSMatthew G. Knepley for (PetscInt cell = cStart; cell < cEnd; ++cell) {
13659d50c5ebSMatthew G. Knepley PetscInt *pindices, Npc;
13669d50c5ebSMatthew G. Knepley
13679d50c5ebSMatthew G. Knepley // TODO: Use DMField instead of assuming affine
13689d50c5ebSMatthew G. Knepley PetscCall(DMPlexComputeCellGeometryFEM(dmIn, cell, NULL, v0, J, invJ, &detJ));
13699d50c5ebSMatthew G. Knepley PetscCall(DMSwarmSortGetPointsPerCell(dm, cell, &Npc, &pindices));
13709d50c5ebSMatthew G. Knepley
13719d50c5ebSMatthew G. Knepley PetscScalar *closure = NULL;
13729d50c5ebSMatthew G. Knepley PetscInt Ncl;
13739d50c5ebSMatthew G. Knepley
13749d50c5ebSMatthew G. Knepley // Get fields from input vector and auxiliary fields from swarm
13759d50c5ebSMatthew G. Knepley for (PetscInt p = 0; p < Npc; ++p) {
13769d50c5ebSMatthew G. Knepley PetscReal xr[8];
13779d50c5ebSMatthew G. Knepley PetscInt off;
13789d50c5ebSMatthew G. Knepley
13799d50c5ebSMatthew G. Knepley off = 0;
13809d50c5ebSMatthew G. Knepley for (PetscInt i = 0; i < Nfc; ++i) {
13819d50c5ebSMatthew G. Knepley for (PetscInt b = 0; b < cbs[i]; ++b, ++off) xr[off] = coordVals[i][pindices[p] * cbs[i] + b];
13829d50c5ebSMatthew G. Knepley }
13839d50c5ebSMatthew G. Knepley PetscCheck(off == dim, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The total block size of coordinates is %" PetscInt_FMT " != %" PetscInt_FMT " the DM coordinate dimension", off, dim);
13849d50c5ebSMatthew G. Knepley CoordinatesRealToRef(dE, dim, fegeom.xi, fegeom.v, fegeom.invJ, xr, &xi[p * dim]);
13859d50c5ebSMatthew G. Knepley off = 0;
13869d50c5ebSMatthew G. Knepley for (PetscInt i = 0; i < Nf; ++i) {
13879d50c5ebSMatthew G. Knepley for (PetscInt b = 0; b < bs[i]; ++b, ++off) val[p * totbs + off] = vals[i][pindices[p] * bs[i] + b];
13889d50c5ebSMatthew G. Knepley }
13899d50c5ebSMatthew G. Knepley PetscCheck(off == totbs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The total block size of swarm fields is %" PetscInt_FMT " != %" PetscInt_FMT " the computed total block size", off, totbs);
13909d50c5ebSMatthew G. Knepley }
13919d50c5ebSMatthew G. Knepley PetscCall(DMPlexVecGetClosure(dmIn, NULL, U, cell, &Ncl, &closure));
13929d50c5ebSMatthew G. Knepley for (PetscInt field = 0; field < Nfu; ++field) {
13939d50c5ebSMatthew G. Knepley PetscFE fe;
13949d50c5ebSMatthew G. Knepley
13959d50c5ebSMatthew G. Knepley PetscCall(PetscDSGetDiscretization(ds, field, (PetscObject *)&fe));
13969d50c5ebSMatthew G. Knepley PetscCall(PetscFECreateTabulation(fe, 1, Npc, xi, 1, &T[field]));
13979d50c5ebSMatthew G. Knepley }
13989d50c5ebSMatthew G. Knepley for (PetscInt p = 0; p < Npc; ++p) {
13999d50c5ebSMatthew G. Knepley // Get fields from input vector
14009d50c5ebSMatthew G. Knepley PetscCall(PetscFEEvaluateFieldJets_Internal(ds, Nfu, 0, p, T, &fegeom, closure, NULL, u, u_x, NULL));
14019d50c5ebSMatthew G. Knepley (*funcs[0])(dim, 1, 1, uOff, uOff_x, u, NULL, u_x, bs, NULL, &val[p * totbs], NULL, NULL, time, &xi[p * dim], 0, NULL, &a[pindices[p]]);
14029d50c5ebSMatthew G. Knepley }
14039d50c5ebSMatthew G. Knepley PetscCall(DMSwarmSortRestorePointsPerCell(dm, cell, &Npc, &pindices));
14049d50c5ebSMatthew G. Knepley PetscCall(DMPlexVecRestoreClosure(dmIn, NULL, U, cell, &Ncl, &closure));
14059d50c5ebSMatthew G. Knepley for (PetscInt field = 0; field < Nfu; ++field) PetscCall(PetscTabulationDestroy(&T[field]));
14069d50c5ebSMatthew G. Knepley }
14079d50c5ebSMatthew G. Knepley }
14089d50c5ebSMatthew G. Knepley for (PetscInt i = 0; i < Nfc; ++i) PetscCall(DMSwarmRestoreField(dm, coordFields[i], &cbs[i], NULL, (void **)&coordVals[i]));
14099d50c5ebSMatthew G. Knepley for (PetscInt i = 0; i < Nf; ++i) PetscCall(DMSwarmRestoreField(dm, fields[i], &bs[i], NULL, (void **)&vals[i]));
14109d50c5ebSMatthew G. Knepley PetscCall(VecRestoreArray(X, &a));
14119d50c5ebSMatthew G. Knepley PetscCall(DMSwarmSortRestoreAccess(dm));
14129d50c5ebSMatthew G. Knepley PetscCall(PetscFree3(xi, val, T));
14139d50c5ebSMatthew G. Knepley PetscCall(PetscFree3(v0, J, invJ));
14149d50c5ebSMatthew G. Knepley PetscCall(PetscFree2(coordVals, cbs));
14159d50c5ebSMatthew G. Knepley PetscCall(PetscFree2(vals, bs));
14169d50c5ebSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
14179d50c5ebSMatthew G. Knepley }
1418