157795646SDave May #define PETSCDM_DLL 257795646SDave May #include <petsc/private/dmswarmimpl.h> /*I "petscdmswarm.h" I*/ 3e8f14785SLisandro Dalcin #include <petsc/private/hashsetij.h> 40643ed39SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> 55917a6f0SStefano Zampini #include <petscviewer.h> 65917a6f0SStefano Zampini #include <petscdraw.h> 783c47955SMatthew G. Knepley #include <petscdmplex.h> 84cc7f7b2SMatthew G. Knepley #include <petscblaslapack.h> 9279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h" 10d0c080abSJoseph Pusztay #include <petscdmlabel.h> 11d0c080abSJoseph Pusztay #include <petscsection.h> 1257795646SDave May 13f2b2bee7SDave May PetscLogEvent DMSWARM_Migrate, DMSWARM_SetSizes, DMSWARM_AddPoints, DMSWARM_RemovePoints, DMSWARM_Sort; 14ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd; 15ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack; 16ed923d71SDave May 17ea78f98cSLisandro Dalcin const char* DMSwarmTypeNames[] = { "basic", "pic", NULL }; 18ea78f98cSLisandro Dalcin const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", NULL }; 19ea78f98cSLisandro Dalcin const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", NULL }; 20ea78f98cSLisandro Dalcin const char* DMSwarmPICLayoutTypeNames[] = { "regular", "gauss", "subdivision", NULL }; 21f0cdbbbaSDave May 22f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid"; 23f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank"; 24f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor"; 25e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid"; 26f0cdbbbaSDave May 2774d0cae8SMatthew G. Knepley PETSC_EXTERN PetscErrorCode VecView_Seq(Vec, PetscViewer); 2874d0cae8SMatthew G. Knepley PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 2974d0cae8SMatthew G. Knepley 3074d0cae8SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 3174d0cae8SMatthew G. Knepley #include <petscviewerhdf5.h> 3274d0cae8SMatthew G. Knepley 3374d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm_HDF5_Internal(Vec v, PetscViewer viewer) 3474d0cae8SMatthew G. Knepley { 3574d0cae8SMatthew G. Knepley DM dm; 3674d0cae8SMatthew G. Knepley PetscReal seqval; 3774d0cae8SMatthew G. Knepley PetscInt seqnum, bs; 3874d0cae8SMatthew G. Knepley PetscBool isseq; 3974d0cae8SMatthew G. Knepley PetscErrorCode ierr; 4074d0cae8SMatthew G. Knepley 4174d0cae8SMatthew G. Knepley PetscFunctionBegin; 4274d0cae8SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 4374d0cae8SMatthew G. Knepley ierr = VecGetBlockSize(v, &bs);CHKERRQ(ierr); 4474d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PushGroup(viewer, "/particle_fields");CHKERRQ(ierr); 4574d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 4674d0cae8SMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, &seqnum, &seqval);CHKERRQ(ierr); 4774d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5SetTimestep(viewer, seqnum);CHKERRQ(ierr); 4874d0cae8SMatthew G. Knepley /* ierr = DMSequenceView_HDF5(dm, "time", seqnum, (PetscScalar) seqval, viewer);CHKERRQ(ierr); */ 4974d0cae8SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 5074d0cae8SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 5174d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) v, "Nc", PETSC_INT, (void *) &bs);CHKERRQ(ierr); 5274d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PopGroup(viewer);CHKERRQ(ierr); 5374d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 5474d0cae8SMatthew G. Knepley } 5574d0cae8SMatthew G. Knepley 5674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmView_HDF5(DM dm, PetscViewer viewer) 5774d0cae8SMatthew G. Knepley { 5874d0cae8SMatthew G. Knepley Vec coordinates; 5974d0cae8SMatthew G. Knepley PetscInt Np; 6074d0cae8SMatthew G. Knepley PetscBool isseq; 6174d0cae8SMatthew G. Knepley PetscErrorCode ierr; 6274d0cae8SMatthew G. Knepley 6374d0cae8SMatthew G. Knepley PetscFunctionBegin; 6474d0cae8SMatthew G. Knepley ierr = DMSwarmGetSize(dm, &Np);CHKERRQ(ierr); 6574d0cae8SMatthew G. Knepley ierr = DMSwarmCreateGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates);CHKERRQ(ierr); 6674d0cae8SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 6774d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PushGroup(viewer, "/particles");CHKERRQ(ierr); 6874d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) coordinates, VECSEQ, &isseq);CHKERRQ(ierr); 6974d0cae8SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(coordinates, viewer);CHKERRQ(ierr);} 7074d0cae8SMatthew G. Knepley else {ierr = VecView_MPI(coordinates, viewer);CHKERRQ(ierr);} 7174d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) coordinates, "Np", PETSC_INT, (void *) &Np);CHKERRQ(ierr); 7274d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PopGroup(viewer);CHKERRQ(ierr); 7374d0cae8SMatthew G. Knepley ierr = DMSwarmDestroyGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates);CHKERRQ(ierr); 7474d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 7574d0cae8SMatthew G. Knepley } 7674d0cae8SMatthew G. Knepley #endif 7774d0cae8SMatthew G. Knepley 7874d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm(Vec v, PetscViewer viewer) 7974d0cae8SMatthew G. Knepley { 8074d0cae8SMatthew G. Knepley DM dm; 8174d0cae8SMatthew G. Knepley PetscBool ishdf5; 8274d0cae8SMatthew G. Knepley PetscErrorCode ierr; 8374d0cae8SMatthew G. Knepley 8474d0cae8SMatthew G. Knepley PetscFunctionBegin; 8574d0cae8SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 8674d0cae8SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 8774d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 8874d0cae8SMatthew G. Knepley if (ishdf5) { 8974d0cae8SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 9074d0cae8SMatthew G. Knepley ierr = VecView_Swarm_HDF5_Internal(v, viewer);CHKERRQ(ierr); 9174d0cae8SMatthew G. Knepley #else 9274d0cae8SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 9374d0cae8SMatthew G. Knepley #endif 9474d0cae8SMatthew G. Knepley } else { 9574d0cae8SMatthew G. Knepley PetscBool isseq; 9674d0cae8SMatthew G. Knepley 9774d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 9874d0cae8SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 9974d0cae8SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 10074d0cae8SMatthew G. Knepley } 10174d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 10274d0cae8SMatthew G. Knepley } 10374d0cae8SMatthew G. Knepley 104d3a51819SDave May /*@C 10562741f57SDave May DMSwarmVectorDefineField - Sets the field from which to define a Vec object 10662741f57SDave May when DMCreateLocalVector(), or DMCreateGlobalVector() is called 10757795646SDave May 108d083f849SBarry Smith Collective on dm 10957795646SDave May 110d3a51819SDave May Input parameters: 11162741f57SDave May + dm - a DMSwarm 11262741f57SDave May - fieldname - the textual name given to a registered field 11357795646SDave May 114d3a51819SDave May Level: beginner 11557795646SDave May 116d3a51819SDave May Notes: 117e7af74c8SDave May 11862741f57SDave May The field with name fieldname must be defined as having a data type of PetscScalar. 119e7af74c8SDave May 120d3a51819SDave May This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector(). 121d3a51819SDave May Mutiple calls to DMSwarmVectorDefineField() are permitted. 12257795646SDave May 1238b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector() 124d3a51819SDave May @*/ 12574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[]) 126b5bcf523SDave May { 127b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 128b5bcf523SDave May PetscErrorCode ierr; 129b5bcf523SDave May PetscInt bs,n; 130b5bcf523SDave May PetscScalar *array; 131b5bcf523SDave May PetscDataType type; 132b5bcf523SDave May 133a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1343454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 13577048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 136b5bcf523SDave May ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 137b5bcf523SDave May 138b5bcf523SDave May /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 139b5bcf523SDave May if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 140521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr); 141b5bcf523SDave May swarm->vec_field_set = PETSC_TRUE; 1421b1ea282SDave May swarm->vec_field_bs = bs; 143b5bcf523SDave May swarm->vec_field_nlocal = n; 144dcf43ee8SDave May ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 145b5bcf523SDave May PetscFunctionReturn(0); 146b5bcf523SDave May } 147b5bcf523SDave May 148cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */ 149b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec) 150b5bcf523SDave May { 151b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 152b5bcf523SDave May PetscErrorCode ierr; 153b5bcf523SDave May Vec x; 154b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 155b5bcf523SDave May 156a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1573454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 158b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 159cc651181SDave May if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */ 160cc651181SDave May 161521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 162b5bcf523SDave May ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr); 163b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 1641b1ea282SDave May ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 165b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 166c6b011d8SStefano Zampini ierr = VecSetDM(x,dm);CHKERRQ(ierr); 167b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 16874d0cae8SMatthew G. Knepley ierr = VecSetDM(x, dm);CHKERRQ(ierr); 16974d0cae8SMatthew G. Knepley ierr = VecSetOperation(x, VECOP_VIEW, (void (*)(void)) VecView_Swarm);CHKERRQ(ierr); 170b5bcf523SDave May *vec = x; 171b5bcf523SDave May PetscFunctionReturn(0); 172b5bcf523SDave May } 173b5bcf523SDave May 174b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */ 175b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec) 176b5bcf523SDave May { 177b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 178b5bcf523SDave May PetscErrorCode ierr; 179b5bcf523SDave May Vec x; 180b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 181b5bcf523SDave May 182a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1833454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 184b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 185cc651181SDave May if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */ 186cc651181SDave May 187521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 188b5bcf523SDave May ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr); 189b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 190071900c8SMatthew G. Knepley ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 191b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 192c6b011d8SStefano Zampini ierr = VecSetDM(x,dm);CHKERRQ(ierr); 193b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 194b5bcf523SDave May *vec = x; 195b5bcf523SDave May PetscFunctionReturn(0); 196b5bcf523SDave May } 197b5bcf523SDave May 198fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec) 199fb1bcc12SMatthew G. Knepley { 200fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 20177048351SPatrick Sanan DMSwarmDataField gfield; 202fb1bcc12SMatthew G. Knepley void (*fptr)(void); 203fb1bcc12SMatthew G. Knepley PetscInt bs, nlocal; 204fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 205fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 206d3a51819SDave May 207fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 208fb1bcc12SMatthew G. Knepley ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr); 209fb1bcc12SMatthew G. Knepley ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr); 210fb1bcc12SMatthew G. Knepley if (nlocal/bs != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since vector was created - cannot ensure pointers are valid"); /* Stale data */ 21177048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr); 212fb1bcc12SMatthew G. Knepley /* check vector is an inplace array */ 213521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 214fb1bcc12SMatthew G. Knepley ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr); 215fb1bcc12SMatthew G. Knepley if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname); 21677048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 217fb1bcc12SMatthew G. Knepley ierr = VecDestroy(vec);CHKERRQ(ierr); 218fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 219fb1bcc12SMatthew G. Knepley } 220fb1bcc12SMatthew G. Knepley 221fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec) 222fb1bcc12SMatthew G. Knepley { 223fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 224fb1bcc12SMatthew G. Knepley PetscDataType type; 225fb1bcc12SMatthew G. Knepley PetscScalar *array; 226fb1bcc12SMatthew G. Knepley PetscInt bs, n; 227fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 228e4fbd051SBarry Smith PetscMPIInt size; 229fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 230fb1bcc12SMatthew G. Knepley 231fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 232fb1bcc12SMatthew G. Knepley if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 23377048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr); 234fb1bcc12SMatthew G. Knepley ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr); 235fb1bcc12SMatthew G. Knepley if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL"); 236fb1bcc12SMatthew G. Knepley 237ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 238e4fbd051SBarry Smith if (size == 1) { 239fb1bcc12SMatthew G. Knepley ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr); 240fb1bcc12SMatthew G. Knepley } else { 241fb1bcc12SMatthew G. Knepley ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr); 242fb1bcc12SMatthew G. Knepley } 243fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr); 244fb1bcc12SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr); 245fb1bcc12SMatthew G. Knepley 246fb1bcc12SMatthew G. Knepley /* Set guard */ 247fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 248fb1bcc12SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr); 24974d0cae8SMatthew G. Knepley 25074d0cae8SMatthew G. Knepley ierr = VecSetDM(*vec, dm);CHKERRQ(ierr); 25174d0cae8SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Swarm);CHKERRQ(ierr); 252fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 253fb1bcc12SMatthew G. Knepley } 254fb1bcc12SMatthew G. Knepley 2550643ed39SMatthew G. Knepley /* This creates a "mass matrix" between a finite element and particle space. If a finite element interpolant is given by 2560643ed39SMatthew G. Knepley 2570643ed39SMatthew G. Knepley \hat f = \sum_i f_i \phi_i 2580643ed39SMatthew G. Knepley 2590643ed39SMatthew G. Knepley and a particle function is given by 2600643ed39SMatthew G. Knepley 2610643ed39SMatthew G. Knepley f = \sum_i w_i \delta(x - x_i) 2620643ed39SMatthew G. Knepley 2630643ed39SMatthew G. Knepley then we want to require that 2640643ed39SMatthew G. Knepley 2650643ed39SMatthew G. Knepley M \hat f = M_p f 2660643ed39SMatthew G. Knepley 2670643ed39SMatthew G. Knepley where the particle mass matrix is given by 2680643ed39SMatthew G. Knepley 2690643ed39SMatthew G. Knepley (M_p)_{ij} = \int \phi_i \delta(x - x_j) 2700643ed39SMatthew G. Knepley 2710643ed39SMatthew G. Knepley The way Dave May does particles, they amount to quadratue weights rather than delta functions, so he has |J| is in 2720643ed39SMatthew G. Knepley his integral. We allow this with the boolean flag. 2730643ed39SMatthew G. Knepley */ 2740643ed39SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrix_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 27583c47955SMatthew G. Knepley { 27683c47955SMatthew G. Knepley const char *name = "Mass Matrix"; 2770643ed39SMatthew G. Knepley MPI_Comm comm; 27883c47955SMatthew G. Knepley PetscDS prob; 27983c47955SMatthew G. Knepley PetscSection fsection, globalFSection; 280e8f14785SLisandro Dalcin PetscHSetIJ ht; 2810643ed39SMatthew G. Knepley PetscLayout rLayout, colLayout; 28283c47955SMatthew G. Knepley PetscInt *dnz, *onz; 283adb2528bSMark Adams PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 2840643ed39SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 28583c47955SMatthew G. Knepley PetscScalar *elemMat; 2860643ed39SMatthew G. Knepley PetscInt dim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 28783c47955SMatthew G. Knepley PetscErrorCode ierr; 28883c47955SMatthew G. Knepley 28983c47955SMatthew G. Knepley PetscFunctionBegin; 2900643ed39SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr); 29183c47955SMatthew G. Knepley ierr = DMGetCoordinateDim(dmf, &dim);CHKERRQ(ierr); 29283c47955SMatthew G. Knepley ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr); 29383c47955SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 2940643ed39SMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 29583c47955SMatthew G. Knepley ierr = PetscMalloc3(dim, &v0, dim*dim, &J, dim*dim,&invJ);CHKERRQ(ierr); 29692fd8e1eSJed Brown ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr); 297e87a4003SBarry Smith ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr); 29883c47955SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr); 2990643ed39SMatthew G. Knepley ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr); 30083c47955SMatthew G. Knepley 3010643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr); 3020643ed39SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr); 3030643ed39SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr); 3040643ed39SMatthew G. Knepley ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr); 3050643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr); 3060643ed39SMatthew G. Knepley ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr); 3070643ed39SMatthew G. Knepley 3080643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 30983c47955SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 31083c47955SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 31183c47955SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 3120643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr); 31383c47955SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 3140643ed39SMatthew G. Knepley 31583c47955SMatthew G. Knepley ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr); 316e8f14785SLisandro Dalcin ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr); 31753e60ab4SJoseph Pusztay 3180643ed39SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 3190643ed39SMatthew G. Knepley /* count non-zeros */ 3200643ed39SMatthew G. Knepley ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr); 32183c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 32283c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 3230643ed39SMatthew G. Knepley PetscInt c, i; 3240643ed39SMatthew G. Knepley PetscInt *findices, *cindices; /* fine is vertices, coarse is particles */ 32583c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 32683c47955SMatthew G. Knepley 32771f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 328fc7c92abSMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 329fc7c92abSMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 33083c47955SMatthew G. Knepley { 331e8f14785SLisandro Dalcin PetscHashIJKey key; 332e8f14785SLisandro Dalcin PetscBool missing; 33383c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 334adb2528bSMark Adams key.j = findices[i]; /* global column (from Plex) */ 335adb2528bSMark Adams if (key.j >= 0) { 33683c47955SMatthew G. Knepley /* Get indices for coarse elements */ 33783c47955SMatthew G. Knepley for (c = 0; c < numCIndices; ++c) { 338adb2528bSMark Adams key.i = cindices[c] + rStart; /* global cols (from Swarm) */ 339adb2528bSMark Adams if (key.i < 0) continue; 340e8f14785SLisandro Dalcin ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 34183c47955SMatthew G. Knepley if (missing) { 3420643ed39SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 343e8f14785SLisandro Dalcin else ++onz[key.i - rStart]; 3440643ed39SMatthew G. Knepley } else SETERRQ2(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %D,%D", key.i, key.j); 34583c47955SMatthew G. Knepley } 346fc7c92abSMatthew G. Knepley } 347fc7c92abSMatthew G. Knepley } 34883c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 34983c47955SMatthew G. Knepley } 35071f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 35183c47955SMatthew G. Knepley } 35283c47955SMatthew G. Knepley } 353e8f14785SLisandro Dalcin ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 35483c47955SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 35583c47955SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 35683c47955SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 357adb2528bSMark Adams ierr = PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi);CHKERRQ(ierr); 35883c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 359ef0bb6c7SMatthew G. Knepley PetscTabulation Tcoarse; 36083c47955SMatthew G. Knepley PetscObject obj; 361ef0bb6c7SMatthew G. Knepley PetscReal *coords; 3620643ed39SMatthew G. Knepley PetscInt Nc, i; 36383c47955SMatthew G. Knepley 36483c47955SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 3650643ed39SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 3660643ed39SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 3670643ed39SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 36883c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 36983c47955SMatthew G. Knepley PetscInt *findices , *cindices; 37083c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 3710643ed39SMatthew G. Knepley PetscInt p, c; 37283c47955SMatthew G. Knepley 3730643ed39SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 37483c47955SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 37571f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 37683c47955SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 3770643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3780643ed39SMatthew G. Knepley CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]); 3790643ed39SMatthew G. Knepley } 380ef0bb6c7SMatthew G. Knepley ierr = PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse);CHKERRQ(ierr); 38183c47955SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 382580bdb30SBarry Smith ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr); 38383c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 3840643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3850643ed39SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 3860643ed39SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 387ef0bb6c7SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 38883c47955SMatthew G. Knepley } 3890643ed39SMatthew G. Knepley } 3900643ed39SMatthew G. Knepley } 391adb2528bSMark Adams for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 39283c47955SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 393adb2528bSMark Adams ierr = MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES);CHKERRQ(ierr); 39483c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 39571f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 396ef0bb6c7SMatthew G. Knepley ierr = PetscTabulationDestroy(&Tcoarse);CHKERRQ(ierr); 39783c47955SMatthew G. Knepley } 3980643ed39SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 39983c47955SMatthew G. Knepley } 400adb2528bSMark Adams ierr = PetscFree3(elemMat, rowIDXs, xi);CHKERRQ(ierr); 40183c47955SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 40283c47955SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 40383c47955SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 40483c47955SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 40583c47955SMatthew G. Knepley PetscFunctionReturn(0); 40683c47955SMatthew G. Knepley } 40783c47955SMatthew G. Knepley 408d0c080abSJoseph Pusztay /* Returns empty matrix for use with SNES FD */ 40970a7d78aSStefano Zampini static PetscErrorCode DMCreateMatrix_Swarm(DM sw, Mat* m) 41070a7d78aSStefano Zampini { 411d0c080abSJoseph Pusztay Vec field; 412d0c080abSJoseph Pusztay PetscInt size; 413d0c080abSJoseph Pusztay PetscErrorCode ierr; 414d0c080abSJoseph Pusztay 415d0c080abSJoseph Pusztay PetscFunctionBegin; 416d0c080abSJoseph Pusztay ierr = DMGetGlobalVector(sw, &field);CHKERRQ(ierr); 417d0c080abSJoseph Pusztay ierr = VecGetLocalSize(field, &size);CHKERRQ(ierr); 418d0c080abSJoseph Pusztay ierr = DMRestoreGlobalVector(sw, &field);CHKERRQ(ierr); 419d0c080abSJoseph Pusztay ierr = MatCreate(PETSC_COMM_WORLD, m);CHKERRQ(ierr); 420d0c080abSJoseph Pusztay ierr = MatSetFromOptions(*m);CHKERRQ(ierr); 4211e1ea65dSPierre Jolivet ierr = MatSetSizes(*m, PETSC_DECIDE, PETSC_DECIDE, size, size);CHKERRQ(ierr); 422d0c080abSJoseph Pusztay ierr = MatSeqAIJSetPreallocation(*m, 1, NULL);CHKERRQ(ierr); 423d0c080abSJoseph Pusztay ierr = MatZeroEntries(*m);CHKERRQ(ierr); 424d0c080abSJoseph Pusztay ierr = MatAssemblyBegin(*m, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 425d0c080abSJoseph Pusztay ierr = MatAssemblyEnd(*m, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 426d0c080abSJoseph Pusztay ierr = MatShift(*m, 1.0);CHKERRQ(ierr); 427d0c080abSJoseph Pusztay ierr = MatSetDM(*m, sw);CHKERRQ(ierr); 428d0c080abSJoseph Pusztay PetscFunctionReturn(0); 429d0c080abSJoseph Pusztay } 430d0c080abSJoseph Pusztay 431adb2528bSMark Adams /* FEM cols, Particle rows */ 43283c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass) 43383c47955SMatthew G. Knepley { 434895a1698SMatthew G. Knepley PetscSection gsf; 43583c47955SMatthew G. Knepley PetscInt m, n; 43683c47955SMatthew G. Knepley void *ctx; 43783c47955SMatthew G. Knepley PetscErrorCode ierr; 43883c47955SMatthew G. Knepley 43983c47955SMatthew G. Knepley PetscFunctionBegin; 440e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 44183c47955SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 442895a1698SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 44383c47955SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 444adb2528bSMark Adams ierr = MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 44583c47955SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 44683c47955SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 44783c47955SMatthew G. Knepley 4480643ed39SMatthew G. Knepley ierr = DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 44983c47955SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 45083c47955SMatthew G. Knepley PetscFunctionReturn(0); 45183c47955SMatthew G. Knepley } 45283c47955SMatthew G. Knepley 4534cc7f7b2SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrixSquare_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 4544cc7f7b2SMatthew G. Knepley { 4554cc7f7b2SMatthew G. Knepley const char *name = "Mass Matrix Square"; 4564cc7f7b2SMatthew G. Knepley MPI_Comm comm; 4574cc7f7b2SMatthew G. Knepley PetscDS prob; 4584cc7f7b2SMatthew G. Knepley PetscSection fsection, globalFSection; 4594cc7f7b2SMatthew G. Knepley PetscHSetIJ ht; 4604cc7f7b2SMatthew G. Knepley PetscLayout rLayout, colLayout; 4614cc7f7b2SMatthew G. Knepley PetscInt *dnz, *onz, *adj, depth, maxConeSize, maxSupportSize, maxAdjSize; 4624cc7f7b2SMatthew G. Knepley PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 4634cc7f7b2SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 4644cc7f7b2SMatthew G. Knepley PetscScalar *elemMat, *elemMatSq; 4654cc7f7b2SMatthew G. Knepley PetscInt cdim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 4664cc7f7b2SMatthew G. Knepley PetscErrorCode ierr; 4674cc7f7b2SMatthew G. Knepley 4684cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 4694cc7f7b2SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr); 4704cc7f7b2SMatthew G. Knepley ierr = DMGetCoordinateDim(dmf, &cdim);CHKERRQ(ierr); 4714cc7f7b2SMatthew G. Knepley ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr); 4724cc7f7b2SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 4734cc7f7b2SMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 4744cc7f7b2SMatthew G. Knepley ierr = PetscMalloc3(cdim, &v0, cdim*cdim, &J, cdim*cdim,&invJ);CHKERRQ(ierr); 4754cc7f7b2SMatthew G. Knepley ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr); 4764cc7f7b2SMatthew G. Knepley ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr); 4774cc7f7b2SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr); 4784cc7f7b2SMatthew G. Knepley ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr); 4794cc7f7b2SMatthew G. Knepley 4804cc7f7b2SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr); 4814cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr); 4824cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr); 4834cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr); 4844cc7f7b2SMatthew G. Knepley ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr); 4854cc7f7b2SMatthew G. Knepley ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr); 4864cc7f7b2SMatthew G. Knepley 4874cc7f7b2SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 4884cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 4894cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 4904cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 4914cc7f7b2SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr); 4924cc7f7b2SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 4934cc7f7b2SMatthew G. Knepley 4944cc7f7b2SMatthew G. Knepley ierr = DMPlexGetDepth(dmf, &depth);CHKERRQ(ierr); 4954cc7f7b2SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dmf, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 4964cc7f7b2SMatthew G. Knepley maxAdjSize = PetscPowInt(maxConeSize*maxSupportSize, depth); 4974cc7f7b2SMatthew G. Knepley ierr = PetscMalloc1(maxAdjSize, &adj);CHKERRQ(ierr); 4984cc7f7b2SMatthew G. Knepley 4994cc7f7b2SMatthew G. Knepley ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr); 5004cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr); 5014cc7f7b2SMatthew G. Knepley /* Count nonzeros 5024cc7f7b2SMatthew G. Knepley This is just FVM++, but we cannot use the Plex P0 allocation since unknowns in a cell will not be contiguous 5034cc7f7b2SMatthew G. Knepley */ 5044cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr); 5054cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 5064cc7f7b2SMatthew G. Knepley PetscInt i; 5074cc7f7b2SMatthew G. Knepley PetscInt *cindices; 5084cc7f7b2SMatthew G. Knepley PetscInt numCIndices; 5094cc7f7b2SMatthew G. Knepley #if 0 5104cc7f7b2SMatthew G. Knepley PetscInt adjSize = maxAdjSize, a, j; 5114cc7f7b2SMatthew G. Knepley #endif 5124cc7f7b2SMatthew G. Knepley 5134cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 5144cc7f7b2SMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 5154cc7f7b2SMatthew G. Knepley /* Diagonal block */ 5164cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) {dnz[cindices[i]] += numCIndices;} 5174cc7f7b2SMatthew G. Knepley #if 0 5184cc7f7b2SMatthew G. Knepley /* Off-diagonal blocks */ 5194cc7f7b2SMatthew G. Knepley ierr = DMPlexGetAdjacency(dmf, cell, &adjSize, &adj);CHKERRQ(ierr); 5204cc7f7b2SMatthew G. Knepley for (a = 0; a < adjSize; ++a) { 5214cc7f7b2SMatthew G. Knepley if (adj[a] >= cStart && adj[a] < cEnd && adj[a] != cell) { 5224cc7f7b2SMatthew G. Knepley const PetscInt ncell = adj[a]; 5234cc7f7b2SMatthew G. Knepley PetscInt *ncindices; 5244cc7f7b2SMatthew G. Knepley PetscInt numNCIndices; 5254cc7f7b2SMatthew G. Knepley 5264cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, ncell, &numNCIndices, &ncindices);CHKERRQ(ierr); 5274cc7f7b2SMatthew G. Knepley { 5284cc7f7b2SMatthew G. Knepley PetscHashIJKey key; 5294cc7f7b2SMatthew G. Knepley PetscBool missing; 5304cc7f7b2SMatthew G. Knepley 5314cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) { 5324cc7f7b2SMatthew G. Knepley key.i = cindices[i] + rStart; /* global rows (from Swarm) */ 5334cc7f7b2SMatthew G. Knepley if (key.i < 0) continue; 5344cc7f7b2SMatthew G. Knepley for (j = 0; j < numNCIndices; ++j) { 5354cc7f7b2SMatthew G. Knepley key.j = ncindices[j] + rStart; /* global column (from Swarm) */ 5364cc7f7b2SMatthew G. Knepley if (key.j < 0) continue; 5374cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 5384cc7f7b2SMatthew G. Knepley if (missing) { 5394cc7f7b2SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 5404cc7f7b2SMatthew G. Knepley else ++onz[key.i - rStart]; 5414cc7f7b2SMatthew G. Knepley } 5424cc7f7b2SMatthew G. Knepley } 5434cc7f7b2SMatthew G. Knepley } 5444cc7f7b2SMatthew G. Knepley } 5454cc7f7b2SMatthew G. Knepley ierr = PetscFree(ncindices);CHKERRQ(ierr); 5464cc7f7b2SMatthew G. Knepley } 5474cc7f7b2SMatthew G. Knepley } 5484cc7f7b2SMatthew G. Knepley #endif 5494cc7f7b2SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 5504cc7f7b2SMatthew G. Knepley } 5514cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 5524cc7f7b2SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 5534cc7f7b2SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 5544cc7f7b2SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 5554cc7f7b2SMatthew G. Knepley ierr = PetscMalloc4(maxC*totDim, &elemMat, maxC*maxC, &elemMatSq, maxC, &rowIDXs, maxC*cdim, &xi);CHKERRQ(ierr); 5564cc7f7b2SMatthew G. Knepley /* Fill in values 5574cc7f7b2SMatthew G. Knepley Each entry is a sum of terms \phi_i(x_p) \phi_i(x_q) 5584cc7f7b2SMatthew G. Knepley Start just by producing block diagonal 5594cc7f7b2SMatthew G. Knepley Could loop over adjacent cells 5604cc7f7b2SMatthew G. Knepley Produce neighboring element matrix 5614cc7f7b2SMatthew G. Knepley TODO Determine which columns and rows correspond to shared dual vector 5624cc7f7b2SMatthew G. Knepley Do MatMatMult with rectangular matrices 5634cc7f7b2SMatthew G. Knepley Insert block 5644cc7f7b2SMatthew G. Knepley */ 5654cc7f7b2SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 5664cc7f7b2SMatthew G. Knepley PetscTabulation Tcoarse; 5674cc7f7b2SMatthew G. Knepley PetscObject obj; 5684cc7f7b2SMatthew G. Knepley PetscReal *coords; 5694cc7f7b2SMatthew G. Knepley PetscInt Nc, i; 5704cc7f7b2SMatthew G. Knepley 5714cc7f7b2SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 5724cc7f7b2SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 5734cc7f7b2SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 5744cc7f7b2SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 5754cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 5764cc7f7b2SMatthew G. Knepley PetscInt *findices , *cindices; 5774cc7f7b2SMatthew G. Knepley PetscInt numFIndices, numCIndices; 5784cc7f7b2SMatthew G. Knepley PetscInt p, c; 5794cc7f7b2SMatthew G. Knepley 5804cc7f7b2SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 5814cc7f7b2SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 5824cc7f7b2SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 5834cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 5844cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 5854cc7f7b2SMatthew G. Knepley CoordinatesRealToRef(cdim, cdim, v0ref, v0, invJ, &coords[cindices[p]*cdim], &xi[p*cdim]); 5864cc7f7b2SMatthew G. Knepley } 5874cc7f7b2SMatthew G. Knepley ierr = PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse);CHKERRQ(ierr); 5884cc7f7b2SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 5894cc7f7b2SMatthew G. Knepley ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr); 5904cc7f7b2SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 5914cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 5924cc7f7b2SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 5934cc7f7b2SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 5944cc7f7b2SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 5954cc7f7b2SMatthew G. Knepley } 5964cc7f7b2SMatthew G. Knepley } 5974cc7f7b2SMatthew G. Knepley } 5984cc7f7b2SMatthew G. Knepley ierr = PetscTabulationDestroy(&Tcoarse);CHKERRQ(ierr); 5994cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 6004cc7f7b2SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 6014cc7f7b2SMatthew G. Knepley /* Block diagonal */ 602*78884ca7SMatthew G. Knepley if (numCIndices) { 6034cc7f7b2SMatthew G. Knepley PetscBLASInt blasn, blask; 6044cc7f7b2SMatthew G. Knepley PetscScalar one = 1.0, zero = 0.0; 6054cc7f7b2SMatthew G. Knepley 6064cc7f7b2SMatthew G. Knepley ierr = PetscBLASIntCast(numCIndices, &blasn);CHKERRQ(ierr); 6074cc7f7b2SMatthew G. Knepley ierr = PetscBLASIntCast(numFIndices, &blask);CHKERRQ(ierr); 6084cc7f7b2SMatthew G. Knepley PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&blasn,&blasn,&blask,&one,elemMat,&blask,elemMat,&blask,&zero,elemMatSq,&blasn)); 6094cc7f7b2SMatthew G. Knepley } 6104cc7f7b2SMatthew G. Knepley ierr = MatSetValues(mass, numCIndices, rowIDXs, numCIndices, rowIDXs, elemMatSq, ADD_VALUES);CHKERRQ(ierr); 6114cc7f7b2SMatthew G. Knepley /* TODO Off-diagonal */ 6124cc7f7b2SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 6134cc7f7b2SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 6144cc7f7b2SMatthew G. Knepley } 6154cc7f7b2SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 6164cc7f7b2SMatthew G. Knepley } 6174cc7f7b2SMatthew G. Knepley ierr = PetscFree4(elemMat, elemMatSq, rowIDXs, xi);CHKERRQ(ierr); 6184cc7f7b2SMatthew G. Knepley ierr = PetscFree(adj);CHKERRQ(ierr); 6194cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 6204cc7f7b2SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 6214cc7f7b2SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6224cc7f7b2SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6234cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 6244cc7f7b2SMatthew G. Knepley } 6254cc7f7b2SMatthew G. Knepley 6264cc7f7b2SMatthew G. Knepley /*@C 6274cc7f7b2SMatthew G. Knepley DMSwarmCreateMassMatrixSquare - Creates the block-diagonal of the square, M^T_p M_p, of the particle mass matrix M_p 6284cc7f7b2SMatthew G. Knepley 6294cc7f7b2SMatthew G. Knepley Collective on dmCoarse 6304cc7f7b2SMatthew G. Knepley 6314cc7f7b2SMatthew G. Knepley Input parameters: 6324cc7f7b2SMatthew G. Knepley + dmCoarse - a DMSwarm 6334cc7f7b2SMatthew G. Knepley - dmFine - a DMPlex 6344cc7f7b2SMatthew G. Knepley 6354cc7f7b2SMatthew G. Knepley Output parameter: 6364cc7f7b2SMatthew G. Knepley . mass - the square of the particle mass matrix 6374cc7f7b2SMatthew G. Knepley 6384cc7f7b2SMatthew G. Knepley Level: advanced 6394cc7f7b2SMatthew G. Knepley 6404cc7f7b2SMatthew G. Knepley Notes: 6414cc7f7b2SMatthew G. Knepley We only compute the block diagonal since this provides a good preconditioner and is completely local. It would be possible in the 6424cc7f7b2SMatthew G. Knepley future to compute the full normal equations. 6434cc7f7b2SMatthew G. Knepley 6444cc7f7b2SMatthew G. Knepley .seealso: DMCreateMassMatrix() 6454cc7f7b2SMatthew G. Knepley @*/ 6464cc7f7b2SMatthew G. Knepley PetscErrorCode DMSwarmCreateMassMatrixSquare(DM dmCoarse, DM dmFine, Mat *mass) 6474cc7f7b2SMatthew G. Knepley { 6484cc7f7b2SMatthew G. Knepley PetscInt n; 6494cc7f7b2SMatthew G. Knepley void *ctx; 6504cc7f7b2SMatthew G. Knepley PetscErrorCode ierr; 6514cc7f7b2SMatthew G. Knepley 6524cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 6534cc7f7b2SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 6544cc7f7b2SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 6554cc7f7b2SMatthew G. Knepley ierr = MatSetSizes(*mass, n, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 6564cc7f7b2SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 6574cc7f7b2SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 6584cc7f7b2SMatthew G. Knepley 6594cc7f7b2SMatthew G. Knepley ierr = DMSwarmComputeMassMatrixSquare_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 6604cc7f7b2SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_sq_mat_view");CHKERRQ(ierr); 6614cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 6624cc7f7b2SMatthew G. Knepley } 6634cc7f7b2SMatthew G. Knepley 664fb1bcc12SMatthew G. Knepley /*@C 665d3a51819SDave May DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 666d3a51819SDave May 667d083f849SBarry Smith Collective on dm 668d3a51819SDave May 669d3a51819SDave May Input parameters: 67062741f57SDave May + dm - a DMSwarm 67162741f57SDave May - fieldname - the textual name given to a registered field 672d3a51819SDave May 6738b8a3813SDave May Output parameter: 674d3a51819SDave May . vec - the vector 675d3a51819SDave May 676d3a51819SDave May Level: beginner 677d3a51819SDave May 6788b8a3813SDave May Notes: 6798b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField(). 6808b8a3813SDave May 6818b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField() 682d3a51819SDave May @*/ 68374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 684b5bcf523SDave May { 685fb1bcc12SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject) dm); 686b5bcf523SDave May PetscErrorCode ierr; 687b5bcf523SDave May 688fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 689fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 690b5bcf523SDave May PetscFunctionReturn(0); 691b5bcf523SDave May } 692b5bcf523SDave May 693d3a51819SDave May /*@C 694d3a51819SDave May DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 695d3a51819SDave May 696d083f849SBarry Smith Collective on dm 697d3a51819SDave May 698d3a51819SDave May Input parameters: 69962741f57SDave May + dm - a DMSwarm 70062741f57SDave May - fieldname - the textual name given to a registered field 701d3a51819SDave May 7028b8a3813SDave May Output parameter: 703d3a51819SDave May . vec - the vector 704d3a51819SDave May 705d3a51819SDave May Level: beginner 706d3a51819SDave May 7078b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField() 708d3a51819SDave May @*/ 70974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 710b5bcf523SDave May { 711b5bcf523SDave May PetscErrorCode ierr; 712cc651181SDave May 713fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 714fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 715b5bcf523SDave May PetscFunctionReturn(0); 716b5bcf523SDave May } 717b5bcf523SDave May 718fb1bcc12SMatthew G. Knepley /*@C 719fb1bcc12SMatthew G. Knepley DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field 720fb1bcc12SMatthew G. Knepley 721d083f849SBarry Smith Collective on dm 722fb1bcc12SMatthew G. Knepley 723fb1bcc12SMatthew G. Knepley Input parameters: 72462741f57SDave May + dm - a DMSwarm 72562741f57SDave May - fieldname - the textual name given to a registered field 726fb1bcc12SMatthew G. Knepley 7278b8a3813SDave May Output parameter: 728fb1bcc12SMatthew G. Knepley . vec - the vector 729fb1bcc12SMatthew G. Knepley 730fb1bcc12SMatthew G. Knepley Level: beginner 731fb1bcc12SMatthew G. Knepley 7328b8a3813SDave May Notes: 7338b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField(). 7348b8a3813SDave May 7358b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField() 736fb1bcc12SMatthew G. Knepley @*/ 73774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 738bbe8250bSMatthew G. Knepley { 739fb1bcc12SMatthew G. Knepley MPI_Comm comm = PETSC_COMM_SELF; 740bbe8250bSMatthew G. Knepley PetscErrorCode ierr; 741bbe8250bSMatthew G. Knepley 742fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 743fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 744fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 745bbe8250bSMatthew G. Knepley } 746fb1bcc12SMatthew G. Knepley 747fb1bcc12SMatthew G. Knepley /*@C 748fb1bcc12SMatthew G. Knepley DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field 749fb1bcc12SMatthew G. Knepley 750d083f849SBarry Smith Collective on dm 751fb1bcc12SMatthew G. Knepley 752fb1bcc12SMatthew G. Knepley Input parameters: 75362741f57SDave May + dm - a DMSwarm 75462741f57SDave May - fieldname - the textual name given to a registered field 755fb1bcc12SMatthew G. Knepley 7568b8a3813SDave May Output parameter: 757fb1bcc12SMatthew G. Knepley . vec - the vector 758fb1bcc12SMatthew G. Knepley 759fb1bcc12SMatthew G. Knepley Level: beginner 760fb1bcc12SMatthew G. Knepley 7618b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField() 762fb1bcc12SMatthew G. Knepley @*/ 76374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 764fb1bcc12SMatthew G. Knepley { 765fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 766fb1bcc12SMatthew G. Knepley 767fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 768fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 769bbe8250bSMatthew G. Knepley PetscFunctionReturn(0); 770bbe8250bSMatthew G. Knepley } 771bbe8250bSMatthew G. Knepley 772b5bcf523SDave May /* 77374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec) 774b5bcf523SDave May { 775b5bcf523SDave May PetscFunctionReturn(0); 776b5bcf523SDave May } 777b5bcf523SDave May 77874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec) 779b5bcf523SDave May { 780b5bcf523SDave May PetscFunctionReturn(0); 781b5bcf523SDave May } 782b5bcf523SDave May */ 783b5bcf523SDave May 784d3a51819SDave May /*@C 785d3a51819SDave May DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 786d3a51819SDave May 787d083f849SBarry Smith Collective on dm 788d3a51819SDave May 789d3a51819SDave May Input parameter: 790d3a51819SDave May . dm - a DMSwarm 791d3a51819SDave May 792d3a51819SDave May Level: beginner 793d3a51819SDave May 794d3a51819SDave May Notes: 7958b8a3813SDave May After all fields have been registered, you must call DMSwarmFinalizeFieldRegister(). 796d3a51819SDave May 797d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 798d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 799d3a51819SDave May @*/ 80074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 8015f50eb2eSDave May { 8025f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *) dm->data; 8033454631fSDave May PetscErrorCode ierr; 8043454631fSDave May 805521f74f9SMatthew G. Knepley PetscFunctionBegin; 806cc651181SDave May if (!swarm->field_registration_initialized) { 8075f50eb2eSDave May swarm->field_registration_initialized = PETSC_TRUE; 80843f984edSMatthew G. Knepley ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_INT64);CHKERRQ(ierr); /* unique identifer */ 809f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */ 810cc651181SDave May } 8115f50eb2eSDave May PetscFunctionReturn(0); 8125f50eb2eSDave May } 8135f50eb2eSDave May 81474d0cae8SMatthew G. Knepley /*@ 815d3a51819SDave May DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 816d3a51819SDave May 817d083f849SBarry Smith Collective on dm 818d3a51819SDave May 819d3a51819SDave May Input parameter: 820d3a51819SDave May . dm - a DMSwarm 821d3a51819SDave May 822d3a51819SDave May Level: beginner 823d3a51819SDave May 824d3a51819SDave May Notes: 82562741f57SDave May After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm. 826d3a51819SDave May 827d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 828d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 829d3a51819SDave May @*/ 83074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 8315f50eb2eSDave May { 8325f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8336845f8f5SDave May PetscErrorCode ierr; 8346845f8f5SDave May 835521f74f9SMatthew G. Knepley PetscFunctionBegin; 836f0cdbbbaSDave May if (!swarm->field_registration_finalized) { 83777048351SPatrick Sanan ierr = DMSwarmDataBucketFinalize(swarm->db);CHKERRQ(ierr); 838f0cdbbbaSDave May } 839f0cdbbbaSDave May swarm->field_registration_finalized = PETSC_TRUE; 8405f50eb2eSDave May PetscFunctionReturn(0); 8415f50eb2eSDave May } 8425f50eb2eSDave May 84374d0cae8SMatthew G. Knepley /*@ 844d3a51819SDave May DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 845d3a51819SDave May 846d3a51819SDave May Not collective 847d3a51819SDave May 848d3a51819SDave May Input parameters: 84962741f57SDave May + dm - a DMSwarm 850d3a51819SDave May . nlocal - the length of each registered field 85162741f57SDave May - buffer - the length of the buffer used to efficient dynamic re-sizing 852d3a51819SDave May 853d3a51819SDave May Level: beginner 854d3a51819SDave May 855d3a51819SDave May .seealso: DMSwarmGetLocalSize() 856d3a51819SDave May @*/ 85774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 8585f50eb2eSDave May { 8595f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8606845f8f5SDave May PetscErrorCode ierr; 8615f50eb2eSDave May 862521f74f9SMatthew G. Knepley PetscFunctionBegin; 863f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 86477048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr); 865f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 8665f50eb2eSDave May PetscFunctionReturn(0); 8675f50eb2eSDave May } 8685f50eb2eSDave May 86974d0cae8SMatthew G. Knepley /*@ 870d3a51819SDave May DMSwarmSetCellDM - Attachs a DM to a DMSwarm 871d3a51819SDave May 872d083f849SBarry Smith Collective on dm 873d3a51819SDave May 874d3a51819SDave May Input parameters: 87562741f57SDave May + dm - a DMSwarm 87662741f57SDave May - dmcell - the DM to attach to the DMSwarm 877d3a51819SDave May 878d3a51819SDave May Level: beginner 879d3a51819SDave May 880d3a51819SDave May Notes: 881d3a51819SDave May The attached DM (dmcell) will be queried for point location and 8828b8a3813SDave May neighbor MPI-rank information if DMSwarmMigrate() is called. 883d3a51819SDave May 8848b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate() 885d3a51819SDave May @*/ 88674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 887b16650c8SDave May { 888b16650c8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 889521f74f9SMatthew G. Knepley 890521f74f9SMatthew G. Knepley PetscFunctionBegin; 891b16650c8SDave May swarm->dmcell = dmcell; 892b16650c8SDave May PetscFunctionReturn(0); 893b16650c8SDave May } 894b16650c8SDave May 89574d0cae8SMatthew G. Knepley /*@ 896d3a51819SDave May DMSwarmGetCellDM - Fetches the attached cell DM 897d3a51819SDave May 898d083f849SBarry Smith Collective on dm 899d3a51819SDave May 900d3a51819SDave May Input parameter: 901d3a51819SDave May . dm - a DMSwarm 902d3a51819SDave May 903d3a51819SDave May Output parameter: 904d3a51819SDave May . dmcell - the DM which was attached to the DMSwarm 905d3a51819SDave May 906d3a51819SDave May Level: beginner 907d3a51819SDave May 908d3a51819SDave May .seealso: DMSwarmSetCellDM() 909d3a51819SDave May @*/ 91074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 911fe39f135SDave May { 912fe39f135SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 913521f74f9SMatthew G. Knepley 914521f74f9SMatthew G. Knepley PetscFunctionBegin; 915fe39f135SDave May *dmcell = swarm->dmcell; 916fe39f135SDave May PetscFunctionReturn(0); 917fe39f135SDave May } 918fe39f135SDave May 91974d0cae8SMatthew G. Knepley /*@ 920d3a51819SDave May DMSwarmGetLocalSize - Retrives the local length of fields registered 921d3a51819SDave May 922d3a51819SDave May Not collective 923d3a51819SDave May 924d3a51819SDave May Input parameter: 925d3a51819SDave May . dm - a DMSwarm 926d3a51819SDave May 927d3a51819SDave May Output parameter: 928d3a51819SDave May . nlocal - the length of each registered field 929d3a51819SDave May 930d3a51819SDave May Level: beginner 931d3a51819SDave May 9328b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes() 933d3a51819SDave May @*/ 93474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 935dcf43ee8SDave May { 936dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 937dcf43ee8SDave May PetscErrorCode ierr; 938dcf43ee8SDave May 939521f74f9SMatthew G. Knepley PetscFunctionBegin; 94077048351SPatrick Sanan if (nlocal) {ierr = DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);} 941dcf43ee8SDave May PetscFunctionReturn(0); 942dcf43ee8SDave May } 943dcf43ee8SDave May 94474d0cae8SMatthew G. Knepley /*@ 945d3a51819SDave May DMSwarmGetSize - Retrives the total length of fields registered 946d3a51819SDave May 947d083f849SBarry Smith Collective on dm 948d3a51819SDave May 949d3a51819SDave May Input parameter: 950d3a51819SDave May . dm - a DMSwarm 951d3a51819SDave May 952d3a51819SDave May Output parameter: 953d3a51819SDave May . n - the total length of each registered field 954d3a51819SDave May 955d3a51819SDave May Level: beginner 956d3a51819SDave May 957d3a51819SDave May Note: 958d3a51819SDave May This calls MPI_Allreduce upon each call (inefficient but safe) 959d3a51819SDave May 9608b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes() 961d3a51819SDave May @*/ 96274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 963dcf43ee8SDave May { 964dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 965dcf43ee8SDave May PetscErrorCode ierr; 966dcf43ee8SDave May PetscInt nlocal,ng; 967dcf43ee8SDave May 968521f74f9SMatthew G. Knepley PetscFunctionBegin; 96977048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 970ffc4695bSBarry Smith ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 971dcf43ee8SDave May if (n) { *n = ng; } 972dcf43ee8SDave May PetscFunctionReturn(0); 973dcf43ee8SDave May } 974dcf43ee8SDave May 975d3a51819SDave May /*@C 9768b8a3813SDave May DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type 977d3a51819SDave May 978d083f849SBarry Smith Collective on dm 979d3a51819SDave May 980d3a51819SDave May Input parameters: 98162741f57SDave May + dm - a DMSwarm 982d3a51819SDave May . fieldname - the textual name to identify this field 983d3a51819SDave May . blocksize - the number of each data type 98462741f57SDave May - type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 985d3a51819SDave May 986d3a51819SDave May Level: beginner 987d3a51819SDave May 988d3a51819SDave May Notes: 9898b8a3813SDave May The textual name for each registered field must be unique. 990d3a51819SDave May 991d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 992d3a51819SDave May @*/ 99374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 994b62e03f8SDave May { 9952eac95f8SDave May PetscErrorCode ierr; 996b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 997b62e03f8SDave May size_t size; 998b62e03f8SDave May 999521f74f9SMatthew G. Knepley PetscFunctionBegin; 10005f50eb2eSDave May if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 10015f50eb2eSDave May if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 10025f50eb2eSDave May 10035f50eb2eSDave May if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 10045f50eb2eSDave May if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 10055f50eb2eSDave May if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 10065f50eb2eSDave May if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 10075f50eb2eSDave May if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 1008b62e03f8SDave May 10092ddcf43eSMatthew G. Knepley ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr); 1010b62e03f8SDave May /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 101177048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 101252c3ed93SDave May { 101377048351SPatrick Sanan DMSwarmDataField gfield; 101452c3ed93SDave May 101577048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 101677048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 101752c3ed93SDave May } 1018b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 1019b62e03f8SDave May PetscFunctionReturn(0); 1020b62e03f8SDave May } 1021b62e03f8SDave May 1022d3a51819SDave May /*@C 1023d3a51819SDave May DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 1024d3a51819SDave May 1025d083f849SBarry Smith Collective on dm 1026d3a51819SDave May 1027d3a51819SDave May Input parameters: 102862741f57SDave May + dm - a DMSwarm 1029d3a51819SDave May . fieldname - the textual name to identify this field 103062741f57SDave May - size - the size in bytes of the user struct of each data type 1031d3a51819SDave May 1032d3a51819SDave May Level: beginner 1033d3a51819SDave May 1034d3a51819SDave May Notes: 10358b8a3813SDave May The textual name for each registered field must be unique. 1036d3a51819SDave May 1037d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField() 1038d3a51819SDave May @*/ 103974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 1040b62e03f8SDave May { 10412eac95f8SDave May PetscErrorCode ierr; 1042b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1043b62e03f8SDave May 1044521f74f9SMatthew G. Knepley PetscFunctionBegin; 104577048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 1046b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 1047b62e03f8SDave May PetscFunctionReturn(0); 1048b62e03f8SDave May } 1049b62e03f8SDave May 1050d3a51819SDave May /*@C 1051d3a51819SDave May DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 1052d3a51819SDave May 1053d083f849SBarry Smith Collective on dm 1054d3a51819SDave May 1055d3a51819SDave May Input parameters: 105662741f57SDave May + dm - a DMSwarm 1057d3a51819SDave May . fieldname - the textual name to identify this field 1058d3a51819SDave May . size - the size in bytes of the user data type 105962741f57SDave May - blocksize - the number of each data type 1060d3a51819SDave May 1061d3a51819SDave May Level: beginner 1062d3a51819SDave May 1063d3a51819SDave May Notes: 10648b8a3813SDave May The textual name for each registered field must be unique. 1065d3a51819SDave May 1066d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 1067d3a51819SDave May @*/ 106874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 1069b62e03f8SDave May { 1070b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 10716845f8f5SDave May PetscErrorCode ierr; 1072b62e03f8SDave May 1073521f74f9SMatthew G. Knepley PetscFunctionBegin; 107477048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 1075320740a0SDave May { 107677048351SPatrick Sanan DMSwarmDataField gfield; 1077320740a0SDave May 107877048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 107977048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 1080320740a0SDave May } 1081b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 1082b62e03f8SDave May PetscFunctionReturn(0); 1083b62e03f8SDave May } 1084b62e03f8SDave May 1085d3a51819SDave May /*@C 1086d3a51819SDave May DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 1087d3a51819SDave May 1088d3a51819SDave May Not collective 1089d3a51819SDave May 1090d3a51819SDave May Input parameters: 109162741f57SDave May + dm - a DMSwarm 109262741f57SDave May - fieldname - the textual name to identify this field 1093d3a51819SDave May 1094d3a51819SDave May Output parameters: 109562741f57SDave May + blocksize - the number of each data type 1096d3a51819SDave May . type - the data type 109762741f57SDave May - data - pointer to raw array 1098d3a51819SDave May 1099d3a51819SDave May Level: beginner 1100d3a51819SDave May 1101d3a51819SDave May Notes: 11028b8a3813SDave May The array must be returned using a matching call to DMSwarmRestoreField(). 1103d3a51819SDave May 1104d3a51819SDave May .seealso: DMSwarmRestoreField() 1105d3a51819SDave May @*/ 110674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1107b62e03f8SDave May { 1108b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 110977048351SPatrick Sanan DMSwarmDataField gfield; 11102eac95f8SDave May PetscErrorCode ierr; 1111b62e03f8SDave May 1112521f74f9SMatthew G. Knepley PetscFunctionBegin; 11133454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 111477048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 111577048351SPatrick Sanan ierr = DMSwarmDataFieldGetAccess(gfield);CHKERRQ(ierr); 111677048351SPatrick Sanan ierr = DMSwarmDataFieldGetEntries(gfield,data);CHKERRQ(ierr); 11171b1ea282SDave May if (blocksize) {*blocksize = gfield->bs; } 1118b5bcf523SDave May if (type) { *type = gfield->petsc_type; } 1119b62e03f8SDave May PetscFunctionReturn(0); 1120b62e03f8SDave May } 1121b62e03f8SDave May 1122d3a51819SDave May /*@C 1123d3a51819SDave May DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 1124d3a51819SDave May 1125d3a51819SDave May Not collective 1126d3a51819SDave May 1127d3a51819SDave May Input parameters: 112862741f57SDave May + dm - a DMSwarm 112962741f57SDave May - fieldname - the textual name to identify this field 1130d3a51819SDave May 1131d3a51819SDave May Output parameters: 113262741f57SDave May + blocksize - the number of each data type 1133d3a51819SDave May . type - the data type 113462741f57SDave May - data - pointer to raw array 1135d3a51819SDave May 1136d3a51819SDave May Level: beginner 1137d3a51819SDave May 1138d3a51819SDave May Notes: 11398b8a3813SDave May The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField(). 1140d3a51819SDave May 1141d3a51819SDave May .seealso: DMSwarmGetField() 1142d3a51819SDave May @*/ 114374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1144b62e03f8SDave May { 1145b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 114677048351SPatrick Sanan DMSwarmDataField gfield; 11472eac95f8SDave May PetscErrorCode ierr; 1148b62e03f8SDave May 1149521f74f9SMatthew G. Knepley PetscFunctionBegin; 115077048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 115177048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 1152b62e03f8SDave May if (data) *data = NULL; 1153b62e03f8SDave May PetscFunctionReturn(0); 1154b62e03f8SDave May } 1155b62e03f8SDave May 115674d0cae8SMatthew G. Knepley /*@ 1157d3a51819SDave May DMSwarmAddPoint - Add space for one new point in the DMSwarm 1158d3a51819SDave May 1159d3a51819SDave May Not collective 1160d3a51819SDave May 1161d3a51819SDave May Input parameter: 1162d3a51819SDave May . dm - a DMSwarm 1163d3a51819SDave May 1164d3a51819SDave May Level: beginner 1165d3a51819SDave May 1166d3a51819SDave May Notes: 11678b8a3813SDave May The new point will have all fields initialized to zero. 1168d3a51819SDave May 1169d3a51819SDave May .seealso: DMSwarmAddNPoints() 1170d3a51819SDave May @*/ 117174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddPoint(DM dm) 1172cb1d1399SDave May { 1173cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1174cb1d1399SDave May PetscErrorCode ierr; 1175cb1d1399SDave May 1176521f74f9SMatthew G. Knepley PetscFunctionBegin; 11773454631fSDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 1178f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 117977048351SPatrick Sanan ierr = DMSwarmDataBucketAddPoint(swarm->db);CHKERRQ(ierr); 1180f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 1181cb1d1399SDave May PetscFunctionReturn(0); 1182cb1d1399SDave May } 1183cb1d1399SDave May 118474d0cae8SMatthew G. Knepley /*@ 1185d3a51819SDave May DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 1186d3a51819SDave May 1187d3a51819SDave May Not collective 1188d3a51819SDave May 1189d3a51819SDave May Input parameters: 119062741f57SDave May + dm - a DMSwarm 119162741f57SDave May - npoints - the number of new points to add 1192d3a51819SDave May 1193d3a51819SDave May Level: beginner 1194d3a51819SDave May 1195d3a51819SDave May Notes: 11968b8a3813SDave May The new point will have all fields initialized to zero. 1197d3a51819SDave May 1198d3a51819SDave May .seealso: DMSwarmAddPoint() 1199d3a51819SDave May @*/ 120074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 1201cb1d1399SDave May { 1202cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1203cb1d1399SDave May PetscErrorCode ierr; 1204cb1d1399SDave May PetscInt nlocal; 1205cb1d1399SDave May 1206521f74f9SMatthew G. Knepley PetscFunctionBegin; 1207f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 120877048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 1209cb1d1399SDave May nlocal = nlocal + npoints; 121077048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr); 1211f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 1212cb1d1399SDave May PetscFunctionReturn(0); 1213cb1d1399SDave May } 1214cb1d1399SDave May 121574d0cae8SMatthew G. Knepley /*@ 1216d3a51819SDave May DMSwarmRemovePoint - Remove the last point from the DMSwarm 1217d3a51819SDave May 1218d3a51819SDave May Not collective 1219d3a51819SDave May 1220d3a51819SDave May Input parameter: 1221d3a51819SDave May . dm - a DMSwarm 1222d3a51819SDave May 1223d3a51819SDave May Level: beginner 1224d3a51819SDave May 1225d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex() 1226d3a51819SDave May @*/ 122774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePoint(DM dm) 1228cb1d1399SDave May { 1229cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1230cb1d1399SDave May PetscErrorCode ierr; 1231cb1d1399SDave May 1232521f74f9SMatthew G. Knepley PetscFunctionBegin; 1233f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 123477048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 1235f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 1236cb1d1399SDave May PetscFunctionReturn(0); 1237cb1d1399SDave May } 1238cb1d1399SDave May 123974d0cae8SMatthew G. Knepley /*@ 1240d3a51819SDave May DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 1241d3a51819SDave May 1242d3a51819SDave May Not collective 1243d3a51819SDave May 1244d3a51819SDave May Input parameters: 124562741f57SDave May + dm - a DMSwarm 124662741f57SDave May - idx - index of point to remove 1247d3a51819SDave May 1248d3a51819SDave May Level: beginner 1249d3a51819SDave May 1250d3a51819SDave May .seealso: DMSwarmRemovePoint() 1251d3a51819SDave May @*/ 125274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 1253cb1d1399SDave May { 1254cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1255cb1d1399SDave May PetscErrorCode ierr; 1256cb1d1399SDave May 1257521f74f9SMatthew G. Knepley PetscFunctionBegin; 1258f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 125977048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 1260f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 1261cb1d1399SDave May PetscFunctionReturn(0); 1262cb1d1399SDave May } 1263b62e03f8SDave May 126474d0cae8SMatthew G. Knepley /*@ 1265ba4fc9c6SDave May DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm 1266ba4fc9c6SDave May 1267ba4fc9c6SDave May Not collective 1268ba4fc9c6SDave May 1269ba4fc9c6SDave May Input parameters: 1270ba4fc9c6SDave May + dm - a DMSwarm 1271ba4fc9c6SDave May . pi - the index of the point to copy 1272ba4fc9c6SDave May - pj - the point index where the copy should be located 1273ba4fc9c6SDave May 1274ba4fc9c6SDave May Level: beginner 1275ba4fc9c6SDave May 1276ba4fc9c6SDave May .seealso: DMSwarmRemovePoint() 1277ba4fc9c6SDave May @*/ 127874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj) 1279ba4fc9c6SDave May { 1280ba4fc9c6SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1281ba4fc9c6SDave May PetscErrorCode ierr; 1282ba4fc9c6SDave May 1283ba4fc9c6SDave May PetscFunctionBegin; 1284ba4fc9c6SDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 128577048351SPatrick Sanan ierr = DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr); 1286ba4fc9c6SDave May PetscFunctionReturn(0); 1287ba4fc9c6SDave May } 1288ba4fc9c6SDave May 1289095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 12903454631fSDave May { 1291dcf43ee8SDave May PetscErrorCode ierr; 1292521f74f9SMatthew G. Knepley 1293521f74f9SMatthew G. Knepley PetscFunctionBegin; 1294dcf43ee8SDave May ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 12953454631fSDave May PetscFunctionReturn(0); 12963454631fSDave May } 12973454631fSDave May 129874d0cae8SMatthew G. Knepley /*@ 1299d3a51819SDave May DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 1300d3a51819SDave May 1301d083f849SBarry Smith Collective on dm 1302d3a51819SDave May 1303d3a51819SDave May Input parameters: 130462741f57SDave May + dm - the DMSwarm 130562741f57SDave May - remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 1306d3a51819SDave May 1307d3a51819SDave May Notes: 1308a5b23f4aSJose E. Roman The DM will be modified to accommodate received points. 13098b8a3813SDave May If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM. 13108b8a3813SDave May Different styles of migration are supported. See DMSwarmSetMigrateType(). 1311d3a51819SDave May 1312d3a51819SDave May Level: advanced 1313d3a51819SDave May 1314d3a51819SDave May .seealso: DMSwarmSetMigrateType() 1315d3a51819SDave May @*/ 131674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 13173454631fSDave May { 1318f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13193454631fSDave May PetscErrorCode ierr; 1320f0cdbbbaSDave May 1321521f74f9SMatthew G. Knepley PetscFunctionBegin; 1322ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 1323f0cdbbbaSDave May switch (swarm->migrate_type) { 1324f0cdbbbaSDave May case DMSWARM_MIGRATE_BASIC: 1325095059a4SDave May ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 1326f0cdbbbaSDave May break; 1327f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLNSCATTER: 1328f0cdbbbaSDave May ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 1329f0cdbbbaSDave May break; 1330f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLEXACT: 1331f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 1332f0cdbbbaSDave May case DMSWARM_MIGRATE_USER: 1333f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 1334f0cdbbbaSDave May default: 1335f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 1336f0cdbbbaSDave May } 1337ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 1338183d2d45SMatthew G. Knepley ierr = DMClearGlobalVectors(dm);CHKERRQ(ierr); 13393454631fSDave May PetscFunctionReturn(0); 13403454631fSDave May } 13413454631fSDave May 1342f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 1343f0cdbbbaSDave May 1344d3a51819SDave May /* 1345d3a51819SDave May DMSwarmCollectViewCreate 1346d3a51819SDave May 1347d3a51819SDave May * Applies a collection method and gathers point neighbour points into dm 1348d3a51819SDave May 1349d3a51819SDave May Notes: 13508b8a3813SDave May Users should call DMSwarmCollectViewDestroy() after 1351d3a51819SDave May they have finished computations associated with the collected points 1352d3a51819SDave May */ 1353d3a51819SDave May 135474d0cae8SMatthew G. Knepley /*@ 1355d3a51819SDave May DMSwarmCollectViewCreate - Applies a collection method and gathers points 1356d3a51819SDave May in neighbour MPI-ranks into the DMSwarm 1357d3a51819SDave May 1358d083f849SBarry Smith Collective on dm 1359d3a51819SDave May 1360d3a51819SDave May Input parameter: 1361d3a51819SDave May . dm - the DMSwarm 1362d3a51819SDave May 1363d3a51819SDave May Notes: 1364d3a51819SDave May Users should call DMSwarmCollectViewDestroy() after 1365d3a51819SDave May they have finished computations associated with the collected points 13668b8a3813SDave May Different collect methods are supported. See DMSwarmSetCollectType(). 1367d3a51819SDave May 1368d3a51819SDave May Level: advanced 1369d3a51819SDave May 1370d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType() 1371d3a51819SDave May @*/ 137274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewCreate(DM dm) 13732712d1f2SDave May { 13742712d1f2SDave May PetscErrorCode ierr; 13752712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13762712d1f2SDave May PetscInt ng; 13772712d1f2SDave May 1378521f74f9SMatthew G. Knepley PetscFunctionBegin; 1379480eef7bSDave May if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 1380480eef7bSDave May ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 1381480eef7bSDave May switch (swarm->collect_type) { 1382f0cdbbbaSDave May 1383480eef7bSDave May case DMSWARM_COLLECT_BASIC: 13842712d1f2SDave May ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 1385480eef7bSDave May break; 1386480eef7bSDave May case DMSWARM_COLLECT_DMDABOUNDINGBOX: 1387f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 1388480eef7bSDave May case DMSWARM_COLLECT_GENERAL: 1389f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 1390480eef7bSDave May default: 1391f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 1392480eef7bSDave May } 1393480eef7bSDave May swarm->collect_view_active = PETSC_TRUE; 1394480eef7bSDave May swarm->collect_view_reset_nlocal = ng; 13952712d1f2SDave May PetscFunctionReturn(0); 13962712d1f2SDave May } 13972712d1f2SDave May 139874d0cae8SMatthew G. Knepley /*@ 1399d3a51819SDave May DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 1400d3a51819SDave May 1401d083f849SBarry Smith Collective on dm 1402d3a51819SDave May 1403d3a51819SDave May Input parameters: 1404d3a51819SDave May . dm - the DMSwarm 1405d3a51819SDave May 1406d3a51819SDave May Notes: 1407d3a51819SDave May Users should call DMSwarmCollectViewCreate() before this function is called. 1408d3a51819SDave May 1409d3a51819SDave May Level: advanced 1410d3a51819SDave May 1411d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType() 1412d3a51819SDave May @*/ 141374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 14142712d1f2SDave May { 14152712d1f2SDave May PetscErrorCode ierr; 14162712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 14172712d1f2SDave May 1418521f74f9SMatthew G. Knepley PetscFunctionBegin; 1419480eef7bSDave May if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 1420480eef7bSDave May ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 1421480eef7bSDave May swarm->collect_view_active = PETSC_FALSE; 14222712d1f2SDave May PetscFunctionReturn(0); 14232712d1f2SDave May } 14243454631fSDave May 1425f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm) 1426f0cdbbbaSDave May { 1427f0cdbbbaSDave May PetscInt dim; 1428f0cdbbbaSDave May PetscErrorCode ierr; 1429f0cdbbbaSDave May 1430521f74f9SMatthew G. Knepley PetscFunctionBegin; 1431f0cdbbbaSDave May ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 1432f0cdbbbaSDave May if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1433f0cdbbbaSDave May if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1434f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 1435e2d107dbSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr); 1436f0cdbbbaSDave May PetscFunctionReturn(0); 1437f0cdbbbaSDave May } 1438f0cdbbbaSDave May 143974d0cae8SMatthew G. Knepley /*@ 144031403186SMatthew G. Knepley DMSwarmSetPointCoordinatesRandom - Sets initial coordinates for particles in each cell 144131403186SMatthew G. Knepley 144231403186SMatthew G. Knepley Collective on dm 144331403186SMatthew G. Knepley 144431403186SMatthew G. Knepley Input parameters: 144531403186SMatthew G. Knepley + dm - the DMSwarm 144631403186SMatthew G. Knepley - Npc - The number of particles per cell in the cell DM 144731403186SMatthew G. Knepley 144831403186SMatthew G. Knepley Notes: 144931403186SMatthew G. Knepley The user must use DMSwarmSetCellDM() to set the cell DM first. The particles are placed randomly inside each cell. If only 145031403186SMatthew G. Knepley one particle is in each cell, it is placed at the centroid. 145131403186SMatthew G. Knepley 145231403186SMatthew G. Knepley Level: intermediate 145331403186SMatthew G. Knepley 145431403186SMatthew G. Knepley .seealso: DMSwarmSetCellDM() 145531403186SMatthew G. Knepley @*/ 145631403186SMatthew G. Knepley PetscErrorCode DMSwarmSetPointCoordinatesRandom(DM dm, PetscInt Npc) 145731403186SMatthew G. Knepley { 145831403186SMatthew G. Knepley DM cdm; 145931403186SMatthew G. Knepley PetscRandom rnd; 146031403186SMatthew G. Knepley DMPolytopeType ct; 146131403186SMatthew G. Knepley PetscBool simplex; 146231403186SMatthew G. Knepley PetscReal *centroid, *coords, *xi0, *v0, *J, *invJ, detJ; 146331403186SMatthew G. Knepley PetscInt dim, d, cStart, cEnd, c, p; 146431403186SMatthew G. Knepley PetscErrorCode ierr; 146531403186SMatthew G. Knepley 146631403186SMatthew G. Knepley PetscFunctionBeginUser; 146731403186SMatthew G. Knepley ierr = PetscRandomCreate(PetscObjectComm((PetscObject) dm), &rnd);CHKERRQ(ierr); 146831403186SMatthew G. Knepley ierr = PetscRandomSetInterval(rnd, -1.0, 1.0);CHKERRQ(ierr); 146931403186SMatthew G. Knepley ierr = PetscRandomSetType(rnd, PETSCRAND48);CHKERRQ(ierr); 147031403186SMatthew G. Knepley 147131403186SMatthew G. Knepley ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 147231403186SMatthew G. Knepley ierr = DMGetDimension(cdm, &dim);CHKERRQ(ierr); 147331403186SMatthew G. Knepley ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 147431403186SMatthew G. Knepley ierr = DMPlexGetCellType(cdm, cStart, &ct);CHKERRQ(ierr); 147531403186SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 147631403186SMatthew G. Knepley 147731403186SMatthew G. Knepley ierr = PetscMalloc5(dim, ¢roid, dim, &xi0, dim, &v0, dim*dim, &J, dim*dim, &invJ);CHKERRQ(ierr); 147831403186SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0; 147931403186SMatthew G. Knepley ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 148031403186SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 148131403186SMatthew G. Knepley if (Npc == 1) { 148231403186SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(cdm, c, NULL, centroid, NULL);CHKERRQ(ierr); 148331403186SMatthew G. Knepley for (d = 0; d < dim; ++d) coords[c*dim+d] = centroid[d]; 148431403186SMatthew G. Knepley } else { 148531403186SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(cdm, c, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); /* affine */ 148631403186SMatthew G. Knepley for (p = 0; p < Npc; ++p) { 148731403186SMatthew G. Knepley const PetscInt n = c*Npc + p; 148831403186SMatthew G. Knepley PetscReal sum = 0.0, refcoords[3]; 148931403186SMatthew G. Knepley 149031403186SMatthew G. Knepley for (d = 0; d < dim; ++d) { 149131403186SMatthew G. Knepley ierr = PetscRandomGetValueReal(rnd, &refcoords[d]);CHKERRQ(ierr); 149231403186SMatthew G. Knepley sum += refcoords[d]; 149331403186SMatthew G. Knepley } 149431403186SMatthew G. Knepley if (simplex && sum > 0.0) for (d = 0; d < dim; ++d) refcoords[d] -= PetscSqrtReal(dim)*sum; 149531403186SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, refcoords, &coords[n*dim]); 149631403186SMatthew G. Knepley } 149731403186SMatthew G. Knepley } 149831403186SMatthew G. Knepley } 149931403186SMatthew G. Knepley ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 150031403186SMatthew G. Knepley ierr = PetscFree5(centroid, xi0, v0, J, invJ);CHKERRQ(ierr); 150131403186SMatthew G. Knepley ierr = PetscRandomDestroy(&rnd);CHKERRQ(ierr); 150231403186SMatthew G. Knepley PetscFunctionReturn(0); 150331403186SMatthew G. Knepley } 150431403186SMatthew G. Knepley 150531403186SMatthew G. Knepley /*@ 1506d3a51819SDave May DMSwarmSetType - Set particular flavor of DMSwarm 1507d3a51819SDave May 1508d083f849SBarry Smith Collective on dm 1509d3a51819SDave May 1510d3a51819SDave May Input parameters: 151162741f57SDave May + dm - the DMSwarm 151262741f57SDave May - stype - the DMSwarm type (e.g. DMSWARM_PIC) 1513d3a51819SDave May 1514d3a51819SDave May Level: advanced 1515d3a51819SDave May 1516d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType() 1517d3a51819SDave May @*/ 151874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 1519f0cdbbbaSDave May { 1520f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1521f0cdbbbaSDave May PetscErrorCode ierr; 1522f0cdbbbaSDave May 1523521f74f9SMatthew G. Knepley PetscFunctionBegin; 1524f0cdbbbaSDave May swarm->swarm_type = stype; 1525f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1526f0cdbbbaSDave May ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 1527f0cdbbbaSDave May } 1528f0cdbbbaSDave May PetscFunctionReturn(0); 1529f0cdbbbaSDave May } 1530f0cdbbbaSDave May 15313454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm) 15323454631fSDave May { 15333454631fSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 15343454631fSDave May PetscErrorCode ierr; 15353454631fSDave May PetscMPIInt rank; 15363454631fSDave May PetscInt p,npoints,*rankval; 15373454631fSDave May 1538521f74f9SMatthew G. Knepley PetscFunctionBegin; 15393454631fSDave May if (swarm->issetup) PetscFunctionReturn(0); 15403454631fSDave May 15413454631fSDave May swarm->issetup = PETSC_TRUE; 15423454631fSDave May 1543f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1544f0cdbbbaSDave May /* check dmcell exists */ 1545f0cdbbbaSDave May if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1546f0cdbbbaSDave May 1547f0cdbbbaSDave May if (swarm->dmcell->ops->locatepointssubdomain) { 1548f0cdbbbaSDave May /* check methods exists for exact ownership identificiation */ 154977b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr); 1550f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1551f0cdbbbaSDave May } else { 1552f0cdbbbaSDave May /* check methods exist for point location AND rank neighbor identification */ 1553f0cdbbbaSDave May if (swarm->dmcell->ops->locatepoints) { 155477b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr); 1555f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1556f0cdbbbaSDave May 1557f0cdbbbaSDave May if (swarm->dmcell->ops->getneighbors) { 155877b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr); 1559f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1560f0cdbbbaSDave May 1561f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1562f0cdbbbaSDave May } 1563f0cdbbbaSDave May } 1564f0cdbbbaSDave May 1565f0cdbbbaSDave May ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 1566f0cdbbbaSDave May 15673454631fSDave May /* check some fields were registered */ 15683454631fSDave May if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 15693454631fSDave May 15703454631fSDave May /* check local sizes were set */ 15713454631fSDave May if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 15723454631fSDave May 15733454631fSDave May /* initialize values in pid and rank placeholders */ 15743454631fSDave May /* TODO: [pid - use MPI_Scan] */ 1575ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 157677048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 1577f0cdbbbaSDave May ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 15783454631fSDave May for (p=0; p<npoints; p++) { 15793454631fSDave May rankval[p] = (PetscInt)rank; 15803454631fSDave May } 1581f0cdbbbaSDave May ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 15823454631fSDave May PetscFunctionReturn(0); 15833454631fSDave May } 15843454631fSDave May 1585dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx); 1586dc5f5ce9SDave May 158757795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm) 158857795646SDave May { 158957795646SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 159057795646SDave May PetscErrorCode ierr; 159157795646SDave May 159257795646SDave May PetscFunctionBegin; 1593d0c080abSJoseph Pusztay if (--swarm->refct > 0) PetscFunctionReturn(0); 159477048351SPatrick Sanan ierr = DMSwarmDataBucketDestroy(&swarm->db);CHKERRQ(ierr); 1595dc5f5ce9SDave May if (swarm->sort_context) { 1596dc5f5ce9SDave May ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr); 1597dc5f5ce9SDave May } 159857795646SDave May ierr = PetscFree(swarm);CHKERRQ(ierr); 159957795646SDave May PetscFunctionReturn(0); 160057795646SDave May } 160157795646SDave May 1602a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) 1603a9ee3421SMatthew G. Knepley { 1604a9ee3421SMatthew G. Knepley DM cdm; 1605a9ee3421SMatthew G. Knepley PetscDraw draw; 160631403186SMatthew G. Knepley PetscReal *coords, oldPause, radius = 0.01; 1607a9ee3421SMatthew G. Knepley PetscInt Np, p, bs; 1608a9ee3421SMatthew G. Knepley PetscErrorCode ierr; 1609a9ee3421SMatthew G. Knepley 1610a9ee3421SMatthew G. Knepley PetscFunctionBegin; 161131403186SMatthew G. Knepley ierr = PetscOptionsGetReal(NULL, ((PetscObject) dm)->prefix, "-dm_view_swarm_radius", &radius, NULL);CHKERRQ(ierr); 1612a9ee3421SMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1613a9ee3421SMatthew G. Knepley ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 1614a9ee3421SMatthew G. Knepley ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr); 1615a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr); 1616a9ee3421SMatthew G. Knepley ierr = DMView(cdm, viewer);CHKERRQ(ierr); 1617a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr); 1618a9ee3421SMatthew G. Knepley 1619a9ee3421SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr); 1620a9ee3421SMatthew G. Knepley ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1621a9ee3421SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1622a9ee3421SMatthew G. Knepley const PetscInt i = p*bs; 1623a9ee3421SMatthew G. Knepley 162431403186SMatthew G. Knepley ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], radius, radius, PETSC_DRAW_BLUE);CHKERRQ(ierr); 1625a9ee3421SMatthew G. Knepley } 1626a9ee3421SMatthew G. Knepley ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1627a9ee3421SMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1628a9ee3421SMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1629a9ee3421SMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1630a9ee3421SMatthew G. Knepley PetscFunctionReturn(0); 1631a9ee3421SMatthew G. Knepley } 1632a9ee3421SMatthew G. Knepley 16335f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 16345f50eb2eSDave May { 16355f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1636a9ee3421SMatthew G. Knepley PetscBool iascii,ibinary,ishdf5,isvtk,isdraw; 16375f50eb2eSDave May PetscErrorCode ierr; 16385f50eb2eSDave May 16395f50eb2eSDave May PetscFunctionBegin; 16405f50eb2eSDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 16415f50eb2eSDave May PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 16425f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 16435f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 16445f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 16455f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1646a9ee3421SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 16475f50eb2eSDave May if (iascii) { 164877048351SPatrick Sanan ierr = DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 1649298827fbSBarry Smith } else if (ibinary) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support"); 16505f50eb2eSDave May #if defined(PETSC_HAVE_HDF5) 165174d0cae8SMatthew G. Knepley else if (ishdf5) { 165274d0cae8SMatthew G. Knepley ierr = DMSwarmView_HDF5(dm, viewer);CHKERRQ(ierr); 165374d0cae8SMatthew G. Knepley } 16545f50eb2eSDave May #else 1655298827fbSBarry Smith else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 16565f50eb2eSDave May #endif 1657298827fbSBarry Smith else if (isvtk) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1658298827fbSBarry Smith else if (isdraw) { 1659a9ee3421SMatthew G. Knepley ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr); 16605f50eb2eSDave May } 16615f50eb2eSDave May PetscFunctionReturn(0); 16625f50eb2eSDave May } 16635f50eb2eSDave May 1664d0c080abSJoseph Pusztay /*@C 1665d0c080abSJoseph Pusztay DMSwarmGetCellSwarm - Extracts a single cell from the DMSwarm object, returns it as a single cell DMSwarm. 1666d0c080abSJoseph Pusztay The cell DM is filtered for fields of that cell, and the filtered DM is used as the cell DM of the new swarm object. 1667d0c080abSJoseph Pusztay 1668d0c080abSJoseph Pusztay Important: Changes to this cell of the swarm will be lost if they are made prior to restoring this cell. 1669d0c080abSJoseph Pusztay 1670d0c080abSJoseph Pusztay Noncollective 1671d0c080abSJoseph Pusztay 1672d0c080abSJoseph Pusztay Input parameters: 1673d0c080abSJoseph Pusztay + sw - the DMSwarm 1674d0c080abSJoseph Pusztay - cellID - the integer id of the cell to be extracted and filtered 1675d0c080abSJoseph Pusztay 1676d0c080abSJoseph Pusztay Output parameters: 1677d0c080abSJoseph Pusztay . cellswarm - The new DMSwarm 1678d0c080abSJoseph Pusztay 1679d0c080abSJoseph Pusztay Level: beginner 1680d0c080abSJoseph Pusztay 1681d0c080abSJoseph Pusztay Note: This presently only supports DMSWARM_PIC type 1682d0c080abSJoseph Pusztay 1683d0c080abSJoseph Pusztay .seealso: DMSwarmRestoreCellSwarm() 1684d0c080abSJoseph Pusztay @*/ 1685d0c080abSJoseph Pusztay PETSC_EXTERN PetscErrorCode DMSwarmGetCellSwarm(DM sw, PetscInt cellID, DM cellswarm) 1686d0c080abSJoseph Pusztay { 1687d0c080abSJoseph Pusztay DM_Swarm *original = (DM_Swarm*) sw->data; 1688d0c080abSJoseph Pusztay DMLabel label; 1689d0c080abSJoseph Pusztay DM dmc, subdmc; 1690d0c080abSJoseph Pusztay PetscInt *pids, particles, dim; 1691d0c080abSJoseph Pusztay PetscErrorCode ierr; 1692d0c080abSJoseph Pusztay 1693d0c080abSJoseph Pusztay PetscFunctionBegin; 1694d0c080abSJoseph Pusztay /* Configure new swarm */ 1695d0c080abSJoseph Pusztay ierr = DMSetType(cellswarm, DMSWARM);CHKERRQ(ierr); 1696d0c080abSJoseph Pusztay ierr = DMGetDimension(sw, &dim);CHKERRQ(ierr); 1697d0c080abSJoseph Pusztay ierr = DMSetDimension(cellswarm, dim);CHKERRQ(ierr); 1698d0c080abSJoseph Pusztay ierr = DMSwarmSetType(cellswarm, DMSWARM_PIC);CHKERRQ(ierr); 1699d0c080abSJoseph Pusztay /* Destroy the unused, unconfigured data bucket to prevent stragglers in memory */ 17001e1ea65dSPierre Jolivet ierr = DMSwarmDataBucketDestroy(&((DM_Swarm*)cellswarm->data)->db);CHKERRQ(ierr); 1701d0c080abSJoseph Pusztay ierr = DMSwarmSortGetAccess(sw);CHKERRQ(ierr); 1702d0c080abSJoseph Pusztay ierr = DMSwarmSortGetNumberOfPointsPerCell(sw, cellID, &particles);CHKERRQ(ierr); 1703d0c080abSJoseph Pusztay ierr = DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids);CHKERRQ(ierr); 17041e1ea65dSPierre Jolivet ierr = DMSwarmDataBucketCreateFromSubset(original->db, particles, pids, &((DM_Swarm*)cellswarm->data)->db);CHKERRQ(ierr); 1705d0c080abSJoseph Pusztay ierr = DMSwarmSortRestoreAccess(sw);CHKERRQ(ierr); 1706d0c080abSJoseph Pusztay ierr = PetscFree(pids);CHKERRQ(ierr); 1707d0c080abSJoseph Pusztay ierr = DMSwarmGetCellDM(sw, &dmc);CHKERRQ(ierr); 1708d0c080abSJoseph Pusztay ierr = DMLabelCreate(PetscObjectComm((PetscObject)sw), "singlecell", &label);CHKERRQ(ierr); 1709d0c080abSJoseph Pusztay ierr = DMAddLabel(dmc, label);CHKERRQ(ierr); 1710d0c080abSJoseph Pusztay ierr = DMLabelSetValue(label, cellID, 1);CHKERRQ(ierr); 1711d0c080abSJoseph Pusztay ierr = DMPlexFilter(dmc, label, 1, &subdmc);CHKERRQ(ierr); 17121e1ea65dSPierre Jolivet ierr = DMSwarmSetCellDM(cellswarm, subdmc);CHKERRQ(ierr); 17131e1ea65dSPierre Jolivet ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 1714d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1715d0c080abSJoseph Pusztay } 1716d0c080abSJoseph Pusztay 1717d0c080abSJoseph Pusztay /*@C 1718d0c080abSJoseph Pusztay DMSwarmRestoreCellSwarm - Restores a DMSwarm object obtained with DMSwarmGetCellSwarm. All fields are copied back into the parent swarm. 1719d0c080abSJoseph Pusztay 1720d0c080abSJoseph Pusztay Noncollective 1721d0c080abSJoseph Pusztay 1722d0c080abSJoseph Pusztay Input parameters: 1723d0c080abSJoseph Pusztay + sw - the parent DMSwarm 1724d0c080abSJoseph Pusztay . cellID - the integer id of the cell to be copied back into the parent swarm 1725d0c080abSJoseph Pusztay - cellswarm - the cell swarm object 1726d0c080abSJoseph Pusztay 1727d0c080abSJoseph Pusztay Level: beginner 1728d0c080abSJoseph Pusztay 1729d0c080abSJoseph Pusztay Note: This only supports DMSWARM_PIC types of DMSwarms 1730d0c080abSJoseph Pusztay 1731d0c080abSJoseph Pusztay .seealso: DMSwarmGetCellSwarm() 1732d0c080abSJoseph Pusztay @*/ 1733d0c080abSJoseph Pusztay PETSC_EXTERN PetscErrorCode DMSwarmRestoreCellSwarm(DM sw, PetscInt cellID, DM cellswarm) 1734d0c080abSJoseph Pusztay { 1735d0c080abSJoseph Pusztay DM dmc; 1736d0c080abSJoseph Pusztay PetscInt *pids, particles, p; 1737d0c080abSJoseph Pusztay PetscErrorCode ierr; 1738d0c080abSJoseph Pusztay 1739d0c080abSJoseph Pusztay PetscFunctionBegin; 1740d0c080abSJoseph Pusztay ierr = DMSwarmSortGetAccess(sw);CHKERRQ(ierr); 1741d0c080abSJoseph Pusztay ierr = DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids);CHKERRQ(ierr); 1742d0c080abSJoseph Pusztay ierr = DMSwarmSortRestoreAccess(sw);CHKERRQ(ierr); 1743d0c080abSJoseph Pusztay /* Pointwise copy of each particle based on pid. The parent swarm may not be altered during this process. */ 1744d0c080abSJoseph Pusztay for (p=0; p<particles; ++p) { 1745d0c080abSJoseph Pusztay ierr = DMSwarmDataBucketCopyPoint(((DM_Swarm*)cellswarm->data)->db,pids[p],((DM_Swarm*)sw->data)->db,pids[p]);CHKERRQ(ierr); 1746d0c080abSJoseph Pusztay } 1747d0c080abSJoseph Pusztay /* Free memory, destroy cell dm */ 17481e1ea65dSPierre Jolivet ierr = DMSwarmGetCellDM(cellswarm, &dmc);CHKERRQ(ierr); 17491e1ea65dSPierre Jolivet ierr = DMDestroy(&dmc);CHKERRQ(ierr); 1750d0c080abSJoseph Pusztay ierr = PetscFree(pids);CHKERRQ(ierr); 1751d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1752d0c080abSJoseph Pusztay } 1753d0c080abSJoseph Pusztay 1754d0c080abSJoseph Pusztay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM, DM *); 1755d0c080abSJoseph Pusztay 1756d0c080abSJoseph Pusztay static PetscErrorCode DMInitialize_Swarm(DM sw) 1757d0c080abSJoseph Pusztay { 1758d0c080abSJoseph Pusztay PetscFunctionBegin; 1759d0c080abSJoseph Pusztay sw->dim = 0; 1760d0c080abSJoseph Pusztay sw->ops->view = DMView_Swarm; 1761d0c080abSJoseph Pusztay sw->ops->load = NULL; 1762d0c080abSJoseph Pusztay sw->ops->setfromoptions = NULL; 1763d0c080abSJoseph Pusztay sw->ops->clone = DMClone_Swarm; 1764d0c080abSJoseph Pusztay sw->ops->setup = DMSetup_Swarm; 1765d0c080abSJoseph Pusztay sw->ops->createlocalsection = NULL; 1766d0c080abSJoseph Pusztay sw->ops->createdefaultconstraints = NULL; 1767d0c080abSJoseph Pusztay sw->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1768d0c080abSJoseph Pusztay sw->ops->createlocalvector = DMCreateLocalVector_Swarm; 1769d0c080abSJoseph Pusztay sw->ops->getlocaltoglobalmapping = NULL; 1770d0c080abSJoseph Pusztay sw->ops->createfieldis = NULL; 1771d0c080abSJoseph Pusztay sw->ops->createcoordinatedm = NULL; 1772d0c080abSJoseph Pusztay sw->ops->getcoloring = NULL; 1773d0c080abSJoseph Pusztay sw->ops->creatematrix = DMCreateMatrix_Swarm; 1774d0c080abSJoseph Pusztay sw->ops->createinterpolation = NULL; 1775d0c080abSJoseph Pusztay sw->ops->createinjection = NULL; 1776d0c080abSJoseph Pusztay sw->ops->createmassmatrix = DMCreateMassMatrix_Swarm; 1777d0c080abSJoseph Pusztay sw->ops->refine = NULL; 1778d0c080abSJoseph Pusztay sw->ops->coarsen = NULL; 1779d0c080abSJoseph Pusztay sw->ops->refinehierarchy = NULL; 1780d0c080abSJoseph Pusztay sw->ops->coarsenhierarchy = NULL; 1781d0c080abSJoseph Pusztay sw->ops->globaltolocalbegin = NULL; 1782d0c080abSJoseph Pusztay sw->ops->globaltolocalend = NULL; 1783d0c080abSJoseph Pusztay sw->ops->localtoglobalbegin = NULL; 1784d0c080abSJoseph Pusztay sw->ops->localtoglobalend = NULL; 1785d0c080abSJoseph Pusztay sw->ops->destroy = DMDestroy_Swarm; 1786d0c080abSJoseph Pusztay sw->ops->createsubdm = NULL; 1787d0c080abSJoseph Pusztay sw->ops->getdimpoints = NULL; 1788d0c080abSJoseph Pusztay sw->ops->locatepoints = NULL; 1789d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1790d0c080abSJoseph Pusztay } 1791d0c080abSJoseph Pusztay 1792d0c080abSJoseph Pusztay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM dm, DM *newdm) 1793d0c080abSJoseph Pusztay { 1794d0c080abSJoseph Pusztay DM_Swarm *swarm = (DM_Swarm *) dm->data; 1795d0c080abSJoseph Pusztay PetscErrorCode ierr; 1796d0c080abSJoseph Pusztay 1797d0c080abSJoseph Pusztay PetscFunctionBegin; 1798d0c080abSJoseph Pusztay swarm->refct++; 1799d0c080abSJoseph Pusztay (*newdm)->data = swarm; 1800d0c080abSJoseph Pusztay ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMSWARM);CHKERRQ(ierr); 1801d0c080abSJoseph Pusztay ierr = DMInitialize_Swarm(*newdm);CHKERRQ(ierr); 1802d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1803d0c080abSJoseph Pusztay } 1804d0c080abSJoseph Pusztay 1805d3a51819SDave May /*MC 1806d3a51819SDave May 1807d3a51819SDave May DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 180862741f57SDave May This implementation was designed for particle methods in which the underlying 1809d3a51819SDave May data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1810d3a51819SDave May 181162741f57SDave May User data can be represented by DMSwarm through a registering "fields". 181262741f57SDave May To register a field, the user must provide; 181362741f57SDave May (a) a unique name; 181462741f57SDave May (b) the data type (or size in bytes); 181562741f57SDave May (c) the block size of the data. 1816d3a51819SDave May 1817d3a51819SDave May For example, suppose the application requires a unique id, energy, momentum and density to be stored 1818c215a47eSMatthew Knepley on a set of particles. Then the following code could be used 1819d3a51819SDave May 182062741f57SDave May $ DMSwarmInitializeFieldRegister(dm) 182162741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 182262741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 182362741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 182462741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 182562741f57SDave May $ DMSwarmFinalizeFieldRegister(dm) 1826d3a51819SDave May 1827d3a51819SDave May The fields represented by DMSwarm are dynamic and can be re-sized at any time. 182862741f57SDave May The only restriction imposed by DMSwarm is that all fields contain the same number of points. 1829d3a51819SDave May 1830d3a51819SDave May To support particle methods, "migration" techniques are provided. These methods migrate data 1831d3a51819SDave May between MPI-ranks. 1832d3a51819SDave May 1833d3a51819SDave May DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1834d3a51819SDave May As a DMSwarm may internally define and store values of different data types, 183562741f57SDave May before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which 1836d3a51819SDave May fields should be used to define a Vec object via 1837d3a51819SDave May DMSwarmVectorDefineField() 1838c215a47eSMatthew Knepley The specified field can be changed at any time - thereby permitting vectors 1839c215a47eSMatthew Knepley compatible with different fields to be created. 1840d3a51819SDave May 184162741f57SDave May A dual representation of fields in the DMSwarm and a Vec object is permitted via 1842d3a51819SDave May DMSwarmCreateGlobalVectorFromField() 1843d3a51819SDave May Here the data defining the field in the DMSwarm is shared with a Vec. 1844d3a51819SDave May This is inherently unsafe if you alter the size of the field at any time between 1845d3a51819SDave May calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1846cc651181SDave May If the local size of the DMSwarm does not match the local size of the global vector 1847cc651181SDave May when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1848d3a51819SDave May 184962741f57SDave May Additional high-level support is provided for Particle-In-Cell methods. 185062741f57SDave May Please refer to the man page for DMSwarmSetType(). 185162741f57SDave May 1852d3a51819SDave May Level: beginner 1853d3a51819SDave May 1854d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType() 1855d3a51819SDave May M*/ 185657795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 185757795646SDave May { 185857795646SDave May DM_Swarm *swarm; 185957795646SDave May PetscErrorCode ierr; 186057795646SDave May 186157795646SDave May PetscFunctionBegin; 186257795646SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 186357795646SDave May ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 1864f0cdbbbaSDave May dm->data = swarm; 186577048351SPatrick Sanan ierr = DMSwarmDataBucketCreate(&swarm->db);CHKERRQ(ierr); 1866f0cdbbbaSDave May ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 1867d0c080abSJoseph Pusztay swarm->refct = 1; 1868b5bcf523SDave May swarm->vec_field_set = PETSC_FALSE; 18693454631fSDave May swarm->issetup = PETSC_FALSE; 1870480eef7bSDave May swarm->swarm_type = DMSWARM_BASIC; 1871480eef7bSDave May swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1872480eef7bSDave May swarm->collect_type = DMSWARM_COLLECT_BASIC; 187340c453e9SDave May swarm->migrate_error_on_missing_point = PETSC_FALSE; 1874f0cdbbbaSDave May swarm->dmcell = NULL; 1875f0cdbbbaSDave May swarm->collect_view_active = PETSC_FALSE; 1876f0cdbbbaSDave May swarm->collect_view_reset_nlocal = -1; 1877d0c080abSJoseph Pusztay ierr = DMInitialize_Swarm(dm);CHKERRQ(ierr); 187857795646SDave May PetscFunctionReturn(0); 187957795646SDave May } 1880