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> 8*4cc7f7b2SMatthew G. Knepley #include <petscblaslapack.h> 9279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h" 1057795646SDave May 11f2b2bee7SDave May PetscLogEvent DMSWARM_Migrate, DMSWARM_SetSizes, DMSWARM_AddPoints, DMSWARM_RemovePoints, DMSWARM_Sort; 12ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd; 13ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack; 14ed923d71SDave May 15ea78f98cSLisandro Dalcin const char* DMSwarmTypeNames[] = { "basic", "pic", NULL }; 16ea78f98cSLisandro Dalcin const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", NULL }; 17ea78f98cSLisandro Dalcin const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", NULL }; 18ea78f98cSLisandro Dalcin const char* DMSwarmPICLayoutTypeNames[] = { "regular", "gauss", "subdivision", NULL }; 19f0cdbbbaSDave May 20f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid"; 21f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank"; 22f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor"; 23e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid"; 24f0cdbbbaSDave May 2574d0cae8SMatthew G. Knepley PETSC_EXTERN PetscErrorCode VecView_Seq(Vec, PetscViewer); 2674d0cae8SMatthew G. Knepley PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 2774d0cae8SMatthew G. Knepley 2874d0cae8SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 2974d0cae8SMatthew G. Knepley #include <petscviewerhdf5.h> 3074d0cae8SMatthew G. Knepley 3174d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm_HDF5_Internal(Vec v, PetscViewer viewer) 3274d0cae8SMatthew G. Knepley { 3374d0cae8SMatthew G. Knepley DM dm; 3474d0cae8SMatthew G. Knepley PetscReal seqval; 3574d0cae8SMatthew G. Knepley PetscInt seqnum, bs; 3674d0cae8SMatthew G. Knepley PetscBool isseq; 3774d0cae8SMatthew G. Knepley PetscErrorCode ierr; 3874d0cae8SMatthew G. Knepley 3974d0cae8SMatthew G. Knepley PetscFunctionBegin; 4074d0cae8SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 4174d0cae8SMatthew G. Knepley ierr = VecGetBlockSize(v, &bs);CHKERRQ(ierr); 4274d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PushGroup(viewer, "/particle_fields");CHKERRQ(ierr); 4374d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 4474d0cae8SMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, &seqnum, &seqval);CHKERRQ(ierr); 4574d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5SetTimestep(viewer, seqnum);CHKERRQ(ierr); 4674d0cae8SMatthew G. Knepley /* ierr = DMSequenceView_HDF5(dm, "time", seqnum, (PetscScalar) seqval, viewer);CHKERRQ(ierr); */ 4774d0cae8SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 4874d0cae8SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 4974d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) v, "Nc", PETSC_INT, (void *) &bs);CHKERRQ(ierr); 5074d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PopGroup(viewer);CHKERRQ(ierr); 5174d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 5274d0cae8SMatthew G. Knepley } 5374d0cae8SMatthew G. Knepley 5474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmView_HDF5(DM dm, PetscViewer viewer) 5574d0cae8SMatthew G. Knepley { 5674d0cae8SMatthew G. Knepley Vec coordinates; 5774d0cae8SMatthew G. Knepley PetscInt Np; 5874d0cae8SMatthew G. Knepley PetscBool isseq; 5974d0cae8SMatthew G. Knepley PetscErrorCode ierr; 6074d0cae8SMatthew G. Knepley 6174d0cae8SMatthew G. Knepley PetscFunctionBegin; 6274d0cae8SMatthew G. Knepley ierr = DMSwarmGetSize(dm, &Np);CHKERRQ(ierr); 6374d0cae8SMatthew G. Knepley ierr = DMSwarmCreateGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates);CHKERRQ(ierr); 6474d0cae8SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 6574d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PushGroup(viewer, "/particles");CHKERRQ(ierr); 6674d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) coordinates, VECSEQ, &isseq);CHKERRQ(ierr); 6774d0cae8SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(coordinates, viewer);CHKERRQ(ierr);} 6874d0cae8SMatthew G. Knepley else {ierr = VecView_MPI(coordinates, viewer);CHKERRQ(ierr);} 6974d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) coordinates, "Np", PETSC_INT, (void *) &Np);CHKERRQ(ierr); 7074d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PopGroup(viewer);CHKERRQ(ierr); 7174d0cae8SMatthew G. Knepley ierr = DMSwarmDestroyGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates);CHKERRQ(ierr); 7274d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 7374d0cae8SMatthew G. Knepley } 7474d0cae8SMatthew G. Knepley #endif 7574d0cae8SMatthew G. Knepley 7674d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm(Vec v, PetscViewer viewer) 7774d0cae8SMatthew G. Knepley { 7874d0cae8SMatthew G. Knepley DM dm; 7974d0cae8SMatthew G. Knepley PetscBool ishdf5; 8074d0cae8SMatthew G. Knepley PetscErrorCode ierr; 8174d0cae8SMatthew G. Knepley 8274d0cae8SMatthew G. Knepley PetscFunctionBegin; 8374d0cae8SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 8474d0cae8SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 8574d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 8674d0cae8SMatthew G. Knepley if (ishdf5) { 8774d0cae8SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 8874d0cae8SMatthew G. Knepley ierr = VecView_Swarm_HDF5_Internal(v, viewer);CHKERRQ(ierr); 8974d0cae8SMatthew G. Knepley #else 9074d0cae8SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 9174d0cae8SMatthew G. Knepley #endif 9274d0cae8SMatthew G. Knepley } else { 9374d0cae8SMatthew G. Knepley PetscBool isseq; 9474d0cae8SMatthew G. Knepley 9574d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 9674d0cae8SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 9774d0cae8SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 9874d0cae8SMatthew G. Knepley } 9974d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 10074d0cae8SMatthew G. Knepley } 10174d0cae8SMatthew G. Knepley 102d3a51819SDave May /*@C 10362741f57SDave May DMSwarmVectorDefineField - Sets the field from which to define a Vec object 10462741f57SDave May when DMCreateLocalVector(), or DMCreateGlobalVector() is called 10557795646SDave May 106d083f849SBarry Smith Collective on dm 10757795646SDave May 108d3a51819SDave May Input parameters: 10962741f57SDave May + dm - a DMSwarm 11062741f57SDave May - fieldname - the textual name given to a registered field 11157795646SDave May 112d3a51819SDave May Level: beginner 11357795646SDave May 114d3a51819SDave May Notes: 115e7af74c8SDave May 11662741f57SDave May The field with name fieldname must be defined as having a data type of PetscScalar. 117e7af74c8SDave May 118d3a51819SDave May This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector(). 119d3a51819SDave May Mutiple calls to DMSwarmVectorDefineField() are permitted. 12057795646SDave May 1218b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector() 122d3a51819SDave May @*/ 12374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[]) 124b5bcf523SDave May { 125b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 126b5bcf523SDave May PetscErrorCode ierr; 127b5bcf523SDave May PetscInt bs,n; 128b5bcf523SDave May PetscScalar *array; 129b5bcf523SDave May PetscDataType type; 130b5bcf523SDave May 131a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1323454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 13377048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 134b5bcf523SDave May ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 135b5bcf523SDave May 136b5bcf523SDave May /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 137b5bcf523SDave May if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 138521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr); 139b5bcf523SDave May swarm->vec_field_set = PETSC_TRUE; 1401b1ea282SDave May swarm->vec_field_bs = bs; 141b5bcf523SDave May swarm->vec_field_nlocal = n; 142dcf43ee8SDave May ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 143b5bcf523SDave May PetscFunctionReturn(0); 144b5bcf523SDave May } 145b5bcf523SDave May 146cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */ 147b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec) 148b5bcf523SDave May { 149b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 150b5bcf523SDave May PetscErrorCode ierr; 151b5bcf523SDave May Vec x; 152b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 153b5bcf523SDave May 154a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1553454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 156b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 157cc651181SDave 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 */ 158cc651181SDave May 159521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 160b5bcf523SDave May ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr); 161b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 1621b1ea282SDave May ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 163b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 164c6b011d8SStefano Zampini ierr = VecSetDM(x,dm);CHKERRQ(ierr); 165b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 16674d0cae8SMatthew G. Knepley ierr = VecSetDM(x, dm);CHKERRQ(ierr); 16774d0cae8SMatthew G. Knepley ierr = VecSetOperation(x, VECOP_VIEW, (void (*)(void)) VecView_Swarm);CHKERRQ(ierr); 168b5bcf523SDave May *vec = x; 169b5bcf523SDave May PetscFunctionReturn(0); 170b5bcf523SDave May } 171b5bcf523SDave May 172b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */ 173b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec) 174b5bcf523SDave May { 175b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 176b5bcf523SDave May PetscErrorCode ierr; 177b5bcf523SDave May Vec x; 178b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 179b5bcf523SDave May 180a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1813454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 182b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 183cc651181SDave 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 */ 184cc651181SDave May 185521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 186b5bcf523SDave May ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr); 187b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 188071900c8SMatthew G. Knepley ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 189b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 190c6b011d8SStefano Zampini ierr = VecSetDM(x,dm);CHKERRQ(ierr); 191b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 192b5bcf523SDave May *vec = x; 193b5bcf523SDave May PetscFunctionReturn(0); 194b5bcf523SDave May } 195b5bcf523SDave May 196fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec) 197fb1bcc12SMatthew G. Knepley { 198fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 19977048351SPatrick Sanan DMSwarmDataField gfield; 200fb1bcc12SMatthew G. Knepley void (*fptr)(void); 201fb1bcc12SMatthew G. Knepley PetscInt bs, nlocal; 202fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 203fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 204d3a51819SDave May 205fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 206fb1bcc12SMatthew G. Knepley ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr); 207fb1bcc12SMatthew G. Knepley ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr); 208fb1bcc12SMatthew 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 */ 20977048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr); 210fb1bcc12SMatthew G. Knepley /* check vector is an inplace array */ 211521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 212fb1bcc12SMatthew G. Knepley ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr); 213fb1bcc12SMatthew G. Knepley if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname); 21477048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 215fb1bcc12SMatthew G. Knepley ierr = VecDestroy(vec);CHKERRQ(ierr); 216fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 217fb1bcc12SMatthew G. Knepley } 218fb1bcc12SMatthew G. Knepley 219fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec) 220fb1bcc12SMatthew G. Knepley { 221fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 222fb1bcc12SMatthew G. Knepley PetscDataType type; 223fb1bcc12SMatthew G. Knepley PetscScalar *array; 224fb1bcc12SMatthew G. Knepley PetscInt bs, n; 225fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 226e4fbd051SBarry Smith PetscMPIInt size; 227fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 228fb1bcc12SMatthew G. Knepley 229fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 230fb1bcc12SMatthew G. Knepley if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 23177048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr); 232fb1bcc12SMatthew G. Knepley ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr); 233fb1bcc12SMatthew G. Knepley if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL"); 234fb1bcc12SMatthew G. Knepley 235e4fbd051SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 236e4fbd051SBarry Smith if (size == 1) { 237fb1bcc12SMatthew G. Knepley ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr); 238fb1bcc12SMatthew G. Knepley } else { 239fb1bcc12SMatthew G. Knepley ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr); 240fb1bcc12SMatthew G. Knepley } 241fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr); 242fb1bcc12SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr); 243fb1bcc12SMatthew G. Knepley 244fb1bcc12SMatthew G. Knepley /* Set guard */ 245fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 246fb1bcc12SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr); 24774d0cae8SMatthew G. Knepley 24874d0cae8SMatthew G. Knepley ierr = VecSetDM(*vec, dm);CHKERRQ(ierr); 24974d0cae8SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Swarm);CHKERRQ(ierr); 250fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 251fb1bcc12SMatthew G. Knepley } 252fb1bcc12SMatthew G. Knepley 2530643ed39SMatthew G. Knepley /* This creates a "mass matrix" between a finite element and particle space. If a finite element interpolant is given by 2540643ed39SMatthew G. Knepley 2550643ed39SMatthew G. Knepley \hat f = \sum_i f_i \phi_i 2560643ed39SMatthew G. Knepley 2570643ed39SMatthew G. Knepley and a particle function is given by 2580643ed39SMatthew G. Knepley 2590643ed39SMatthew G. Knepley f = \sum_i w_i \delta(x - x_i) 2600643ed39SMatthew G. Knepley 2610643ed39SMatthew G. Knepley then we want to require that 2620643ed39SMatthew G. Knepley 2630643ed39SMatthew G. Knepley M \hat f = M_p f 2640643ed39SMatthew G. Knepley 2650643ed39SMatthew G. Knepley where the particle mass matrix is given by 2660643ed39SMatthew G. Knepley 2670643ed39SMatthew G. Knepley (M_p)_{ij} = \int \phi_i \delta(x - x_j) 2680643ed39SMatthew G. Knepley 2690643ed39SMatthew G. Knepley The way Dave May does particles, they amount to quadratue weights rather than delta functions, so he has |J| is in 2700643ed39SMatthew G. Knepley his integral. We allow this with the boolean flag. 2710643ed39SMatthew G. Knepley */ 2720643ed39SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrix_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 27383c47955SMatthew G. Knepley { 27483c47955SMatthew G. Knepley const char *name = "Mass Matrix"; 2750643ed39SMatthew G. Knepley MPI_Comm comm; 27683c47955SMatthew G. Knepley PetscDS prob; 27783c47955SMatthew G. Knepley PetscSection fsection, globalFSection; 278e8f14785SLisandro Dalcin PetscHSetIJ ht; 2790643ed39SMatthew G. Knepley PetscLayout rLayout, colLayout; 28083c47955SMatthew G. Knepley PetscInt *dnz, *onz; 281adb2528bSMark Adams PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 2820643ed39SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 28383c47955SMatthew G. Knepley PetscScalar *elemMat; 2840643ed39SMatthew G. Knepley PetscInt dim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 28583c47955SMatthew G. Knepley PetscErrorCode ierr; 28683c47955SMatthew G. Knepley 28783c47955SMatthew G. Knepley PetscFunctionBegin; 2880643ed39SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr); 28983c47955SMatthew G. Knepley ierr = DMGetCoordinateDim(dmf, &dim);CHKERRQ(ierr); 29083c47955SMatthew G. Knepley ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr); 29183c47955SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 2920643ed39SMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 29383c47955SMatthew G. Knepley ierr = PetscMalloc3(dim, &v0, dim*dim, &J, dim*dim,&invJ);CHKERRQ(ierr); 29492fd8e1eSJed Brown ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr); 295e87a4003SBarry Smith ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr); 29683c47955SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr); 2970643ed39SMatthew G. Knepley ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr); 29883c47955SMatthew G. Knepley 2990643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr); 3000643ed39SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr); 3010643ed39SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr); 3020643ed39SMatthew G. Knepley ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr); 3030643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr); 3040643ed39SMatthew G. Knepley ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr); 3050643ed39SMatthew G. Knepley 3060643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 30783c47955SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 30883c47955SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 30983c47955SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 3100643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr); 31183c47955SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 3120643ed39SMatthew G. Knepley 31383c47955SMatthew G. Knepley ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr); 314e8f14785SLisandro Dalcin ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr); 31553e60ab4SJoseph Pusztay 3160643ed39SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 3170643ed39SMatthew G. Knepley /* count non-zeros */ 3180643ed39SMatthew G. Knepley ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr); 31983c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 32083c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 3210643ed39SMatthew G. Knepley PetscInt c, i; 3220643ed39SMatthew G. Knepley PetscInt *findices, *cindices; /* fine is vertices, coarse is particles */ 32383c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 32483c47955SMatthew G. Knepley 32571f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 326fc7c92abSMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 327fc7c92abSMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 32883c47955SMatthew G. Knepley { 329e8f14785SLisandro Dalcin PetscHashIJKey key; 330e8f14785SLisandro Dalcin PetscBool missing; 33183c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 332adb2528bSMark Adams key.j = findices[i]; /* global column (from Plex) */ 333adb2528bSMark Adams if (key.j >= 0) { 33483c47955SMatthew G. Knepley /* Get indices for coarse elements */ 33583c47955SMatthew G. Knepley for (c = 0; c < numCIndices; ++c) { 336adb2528bSMark Adams key.i = cindices[c] + rStart; /* global cols (from Swarm) */ 337adb2528bSMark Adams if (key.i < 0) continue; 338e8f14785SLisandro Dalcin ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 33983c47955SMatthew G. Knepley if (missing) { 3400643ed39SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 341e8f14785SLisandro Dalcin else ++onz[key.i - rStart]; 3420643ed39SMatthew G. Knepley } else SETERRQ2(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %D,%D", key.i, key.j); 34383c47955SMatthew G. Knepley } 344fc7c92abSMatthew G. Knepley } 345fc7c92abSMatthew G. Knepley } 34683c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 34783c47955SMatthew G. Knepley } 34871f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 34983c47955SMatthew G. Knepley } 35083c47955SMatthew G. Knepley } 351e8f14785SLisandro Dalcin ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 35283c47955SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 35383c47955SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 35483c47955SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 355adb2528bSMark Adams ierr = PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi);CHKERRQ(ierr); 35683c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 357ef0bb6c7SMatthew G. Knepley PetscTabulation Tcoarse; 35883c47955SMatthew G. Knepley PetscObject obj; 359ef0bb6c7SMatthew G. Knepley PetscReal *coords; 3600643ed39SMatthew G. Knepley PetscInt Nc, i; 36183c47955SMatthew G. Knepley 36283c47955SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 3630643ed39SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 3640643ed39SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 3650643ed39SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 36683c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 36783c47955SMatthew G. Knepley PetscInt *findices , *cindices; 36883c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 3690643ed39SMatthew G. Knepley PetscInt p, c; 37083c47955SMatthew G. Knepley 3710643ed39SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 37283c47955SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 37371f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 37483c47955SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 3750643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3760643ed39SMatthew G. Knepley CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]); 3770643ed39SMatthew G. Knepley } 378ef0bb6c7SMatthew G. Knepley ierr = PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse);CHKERRQ(ierr); 37983c47955SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 380580bdb30SBarry Smith ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr); 38183c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 3820643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3830643ed39SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 3840643ed39SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 385ef0bb6c7SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 38683c47955SMatthew G. Knepley } 3870643ed39SMatthew G. Knepley } 3880643ed39SMatthew G. Knepley } 389adb2528bSMark Adams for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 39083c47955SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 391adb2528bSMark Adams ierr = MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES);CHKERRQ(ierr); 39283c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 39371f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 394ef0bb6c7SMatthew G. Knepley ierr = PetscTabulationDestroy(&Tcoarse);CHKERRQ(ierr); 39583c47955SMatthew G. Knepley } 3960643ed39SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 39783c47955SMatthew G. Knepley } 398adb2528bSMark Adams ierr = PetscFree3(elemMat, rowIDXs, xi);CHKERRQ(ierr); 39983c47955SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 40083c47955SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 40183c47955SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 40283c47955SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 40383c47955SMatthew G. Knepley PetscFunctionReturn(0); 40483c47955SMatthew G. Knepley } 40583c47955SMatthew G. Knepley 406adb2528bSMark Adams /* FEM cols, Particle rows */ 40783c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass) 40883c47955SMatthew G. Knepley { 409895a1698SMatthew G. Knepley PetscSection gsf; 41083c47955SMatthew G. Knepley PetscInt m, n; 41183c47955SMatthew G. Knepley void *ctx; 41283c47955SMatthew G. Knepley PetscErrorCode ierr; 41383c47955SMatthew G. Knepley 41483c47955SMatthew G. Knepley PetscFunctionBegin; 415e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 41683c47955SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 417895a1698SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 41883c47955SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 419adb2528bSMark Adams ierr = MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 42083c47955SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 42183c47955SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 42283c47955SMatthew G. Knepley 4230643ed39SMatthew G. Knepley ierr = DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 42483c47955SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 42583c47955SMatthew G. Knepley PetscFunctionReturn(0); 42683c47955SMatthew G. Knepley } 42783c47955SMatthew G. Knepley 428*4cc7f7b2SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrixSquare_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 429*4cc7f7b2SMatthew G. Knepley { 430*4cc7f7b2SMatthew G. Knepley const char *name = "Mass Matrix Square"; 431*4cc7f7b2SMatthew G. Knepley MPI_Comm comm; 432*4cc7f7b2SMatthew G. Knepley PetscDS prob; 433*4cc7f7b2SMatthew G. Knepley PetscSection fsection, globalFSection; 434*4cc7f7b2SMatthew G. Knepley PetscHSetIJ ht; 435*4cc7f7b2SMatthew G. Knepley PetscLayout rLayout, colLayout; 436*4cc7f7b2SMatthew G. Knepley PetscInt *dnz, *onz, *adj, depth, maxConeSize, maxSupportSize, maxAdjSize; 437*4cc7f7b2SMatthew G. Knepley PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 438*4cc7f7b2SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 439*4cc7f7b2SMatthew G. Knepley PetscScalar *elemMat, *elemMatSq; 440*4cc7f7b2SMatthew G. Knepley PetscInt cdim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 441*4cc7f7b2SMatthew G. Knepley PetscErrorCode ierr; 442*4cc7f7b2SMatthew G. Knepley 443*4cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 444*4cc7f7b2SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr); 445*4cc7f7b2SMatthew G. Knepley ierr = DMGetCoordinateDim(dmf, &cdim);CHKERRQ(ierr); 446*4cc7f7b2SMatthew G. Knepley ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr); 447*4cc7f7b2SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 448*4cc7f7b2SMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 449*4cc7f7b2SMatthew G. Knepley ierr = PetscMalloc3(cdim, &v0, cdim*cdim, &J, cdim*cdim,&invJ);CHKERRQ(ierr); 450*4cc7f7b2SMatthew G. Knepley ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr); 451*4cc7f7b2SMatthew G. Knepley ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr); 452*4cc7f7b2SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr); 453*4cc7f7b2SMatthew G. Knepley ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr); 454*4cc7f7b2SMatthew G. Knepley 455*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr); 456*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr); 457*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr); 458*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr); 459*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr); 460*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr); 461*4cc7f7b2SMatthew G. Knepley 462*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 463*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 464*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 465*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 466*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr); 467*4cc7f7b2SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 468*4cc7f7b2SMatthew G. Knepley 469*4cc7f7b2SMatthew G. Knepley ierr = DMPlexGetDepth(dmf, &depth);CHKERRQ(ierr); 470*4cc7f7b2SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dmf, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 471*4cc7f7b2SMatthew G. Knepley maxAdjSize = PetscPowInt(maxConeSize*maxSupportSize, depth); 472*4cc7f7b2SMatthew G. Knepley ierr = PetscMalloc1(maxAdjSize, &adj);CHKERRQ(ierr); 473*4cc7f7b2SMatthew G. Knepley 474*4cc7f7b2SMatthew G. Knepley ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr); 475*4cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr); 476*4cc7f7b2SMatthew G. Knepley /* Count nonzeros 477*4cc7f7b2SMatthew G. Knepley This is just FVM++, but we cannot use the Plex P0 allocation since unknowns in a cell will not be contiguous 478*4cc7f7b2SMatthew G. Knepley */ 479*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr); 480*4cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 481*4cc7f7b2SMatthew G. Knepley PetscInt i; 482*4cc7f7b2SMatthew G. Knepley PetscInt *cindices; 483*4cc7f7b2SMatthew G. Knepley PetscInt numCIndices; 484*4cc7f7b2SMatthew G. Knepley #if 0 485*4cc7f7b2SMatthew G. Knepley PetscInt adjSize = maxAdjSize, a, j; 486*4cc7f7b2SMatthew G. Knepley #endif 487*4cc7f7b2SMatthew G. Knepley 488*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 489*4cc7f7b2SMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 490*4cc7f7b2SMatthew G. Knepley /* Diagonal block */ 491*4cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) {dnz[cindices[i]] += numCIndices;} 492*4cc7f7b2SMatthew G. Knepley #if 0 493*4cc7f7b2SMatthew G. Knepley /* Off-diagonal blocks */ 494*4cc7f7b2SMatthew G. Knepley ierr = DMPlexGetAdjacency(dmf, cell, &adjSize, &adj);CHKERRQ(ierr); 495*4cc7f7b2SMatthew G. Knepley for (a = 0; a < adjSize; ++a) { 496*4cc7f7b2SMatthew G. Knepley if (adj[a] >= cStart && adj[a] < cEnd && adj[a] != cell) { 497*4cc7f7b2SMatthew G. Knepley const PetscInt ncell = adj[a]; 498*4cc7f7b2SMatthew G. Knepley PetscInt *ncindices; 499*4cc7f7b2SMatthew G. Knepley PetscInt numNCIndices; 500*4cc7f7b2SMatthew G. Knepley 501*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, ncell, &numNCIndices, &ncindices);CHKERRQ(ierr); 502*4cc7f7b2SMatthew G. Knepley { 503*4cc7f7b2SMatthew G. Knepley PetscHashIJKey key; 504*4cc7f7b2SMatthew G. Knepley PetscBool missing; 505*4cc7f7b2SMatthew G. Knepley 506*4cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) { 507*4cc7f7b2SMatthew G. Knepley key.i = cindices[i] + rStart; /* global rows (from Swarm) */ 508*4cc7f7b2SMatthew G. Knepley if (key.i < 0) continue; 509*4cc7f7b2SMatthew G. Knepley for (j = 0; j < numNCIndices; ++j) { 510*4cc7f7b2SMatthew G. Knepley key.j = ncindices[j] + rStart; /* global column (from Swarm) */ 511*4cc7f7b2SMatthew G. Knepley if (key.j < 0) continue; 512*4cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 513*4cc7f7b2SMatthew G. Knepley if (missing) { 514*4cc7f7b2SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 515*4cc7f7b2SMatthew G. Knepley else ++onz[key.i - rStart]; 516*4cc7f7b2SMatthew G. Knepley } 517*4cc7f7b2SMatthew G. Knepley } 518*4cc7f7b2SMatthew G. Knepley } 519*4cc7f7b2SMatthew G. Knepley } 520*4cc7f7b2SMatthew G. Knepley ierr = PetscFree(ncindices);CHKERRQ(ierr); 521*4cc7f7b2SMatthew G. Knepley } 522*4cc7f7b2SMatthew G. Knepley } 523*4cc7f7b2SMatthew G. Knepley #endif 524*4cc7f7b2SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 525*4cc7f7b2SMatthew G. Knepley } 526*4cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 527*4cc7f7b2SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 528*4cc7f7b2SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 529*4cc7f7b2SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 530*4cc7f7b2SMatthew G. Knepley ierr = PetscMalloc4(maxC*totDim, &elemMat, maxC*maxC, &elemMatSq, maxC, &rowIDXs, maxC*cdim, &xi);CHKERRQ(ierr); 531*4cc7f7b2SMatthew G. Knepley /* Fill in values 532*4cc7f7b2SMatthew G. Knepley Each entry is a sum of terms \phi_i(x_p) \phi_i(x_q) 533*4cc7f7b2SMatthew G. Knepley Start just by producing block diagonal 534*4cc7f7b2SMatthew G. Knepley Could loop over adjacent cells 535*4cc7f7b2SMatthew G. Knepley Produce neighboring element matrix 536*4cc7f7b2SMatthew G. Knepley TODO Determine which columns and rows correspond to shared dual vector 537*4cc7f7b2SMatthew G. Knepley Do MatMatMult with rectangular matrices 538*4cc7f7b2SMatthew G. Knepley Insert block 539*4cc7f7b2SMatthew G. Knepley */ 540*4cc7f7b2SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 541*4cc7f7b2SMatthew G. Knepley PetscTabulation Tcoarse; 542*4cc7f7b2SMatthew G. Knepley PetscObject obj; 543*4cc7f7b2SMatthew G. Knepley PetscReal *coords; 544*4cc7f7b2SMatthew G. Knepley PetscInt Nc, i; 545*4cc7f7b2SMatthew G. Knepley 546*4cc7f7b2SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 547*4cc7f7b2SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 548*4cc7f7b2SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 549*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 550*4cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 551*4cc7f7b2SMatthew G. Knepley PetscInt *findices , *cindices; 552*4cc7f7b2SMatthew G. Knepley PetscInt numFIndices, numCIndices; 553*4cc7f7b2SMatthew G. Knepley PetscInt p, c; 554*4cc7f7b2SMatthew G. Knepley 555*4cc7f7b2SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 556*4cc7f7b2SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 557*4cc7f7b2SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 558*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 559*4cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 560*4cc7f7b2SMatthew G. Knepley CoordinatesRealToRef(cdim, cdim, v0ref, v0, invJ, &coords[cindices[p]*cdim], &xi[p*cdim]); 561*4cc7f7b2SMatthew G. Knepley } 562*4cc7f7b2SMatthew G. Knepley ierr = PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse);CHKERRQ(ierr); 563*4cc7f7b2SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 564*4cc7f7b2SMatthew G. Knepley ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr); 565*4cc7f7b2SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 566*4cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 567*4cc7f7b2SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 568*4cc7f7b2SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 569*4cc7f7b2SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 570*4cc7f7b2SMatthew G. Knepley } 571*4cc7f7b2SMatthew G. Knepley } 572*4cc7f7b2SMatthew G. Knepley } 573*4cc7f7b2SMatthew G. Knepley ierr = PetscTabulationDestroy(&Tcoarse);CHKERRQ(ierr); 574*4cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 575*4cc7f7b2SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 576*4cc7f7b2SMatthew G. Knepley /* Block diagonal */ 577*4cc7f7b2SMatthew G. Knepley { 578*4cc7f7b2SMatthew G. Knepley PetscBLASInt blasn, blask; 579*4cc7f7b2SMatthew G. Knepley PetscScalar one = 1.0, zero = 0.0; 580*4cc7f7b2SMatthew G. Knepley 581*4cc7f7b2SMatthew G. Knepley ierr = PetscBLASIntCast(numCIndices, &blasn);CHKERRQ(ierr); 582*4cc7f7b2SMatthew G. Knepley ierr = PetscBLASIntCast(numFIndices, &blask);CHKERRQ(ierr); 583*4cc7f7b2SMatthew G. Knepley PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&blasn,&blasn,&blask,&one,elemMat,&blask,elemMat,&blask,&zero,elemMatSq,&blasn)); 584*4cc7f7b2SMatthew G. Knepley } 585*4cc7f7b2SMatthew G. Knepley ierr = MatSetValues(mass, numCIndices, rowIDXs, numCIndices, rowIDXs, elemMatSq, ADD_VALUES);CHKERRQ(ierr); 586*4cc7f7b2SMatthew G. Knepley /* TODO Off-diagonal */ 587*4cc7f7b2SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 588*4cc7f7b2SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 589*4cc7f7b2SMatthew G. Knepley } 590*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 591*4cc7f7b2SMatthew G. Knepley } 592*4cc7f7b2SMatthew G. Knepley ierr = PetscFree4(elemMat, elemMatSq, rowIDXs, xi);CHKERRQ(ierr); 593*4cc7f7b2SMatthew G. Knepley ierr = PetscFree(adj);CHKERRQ(ierr); 594*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 595*4cc7f7b2SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 596*4cc7f7b2SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 597*4cc7f7b2SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 598*4cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 599*4cc7f7b2SMatthew G. Knepley } 600*4cc7f7b2SMatthew G. Knepley 601*4cc7f7b2SMatthew G. Knepley /*@C 602*4cc7f7b2SMatthew G. Knepley DMSwarmCreateMassMatrixSquare - Creates the block-diagonal of the square, M^T_p M_p, of the particle mass matrix M_p 603*4cc7f7b2SMatthew G. Knepley 604*4cc7f7b2SMatthew G. Knepley Collective on dmCoarse 605*4cc7f7b2SMatthew G. Knepley 606*4cc7f7b2SMatthew G. Knepley Input parameters: 607*4cc7f7b2SMatthew G. Knepley + dmCoarse - a DMSwarm 608*4cc7f7b2SMatthew G. Knepley - dmFine - a DMPlex 609*4cc7f7b2SMatthew G. Knepley 610*4cc7f7b2SMatthew G. Knepley Output parameter: 611*4cc7f7b2SMatthew G. Knepley . mass - the square of the particle mass matrix 612*4cc7f7b2SMatthew G. Knepley 613*4cc7f7b2SMatthew G. Knepley Level: advanced 614*4cc7f7b2SMatthew G. Knepley 615*4cc7f7b2SMatthew G. Knepley Notes: 616*4cc7f7b2SMatthew G. Knepley We only compute the block diagonal since this provides a good preconditioner and is completely local. It would be possible in the 617*4cc7f7b2SMatthew G. Knepley future to compute the full normal equations. 618*4cc7f7b2SMatthew G. Knepley 619*4cc7f7b2SMatthew G. Knepley .seealso: DMCreateMassMatrix() 620*4cc7f7b2SMatthew G. Knepley @*/ 621*4cc7f7b2SMatthew G. Knepley PetscErrorCode DMSwarmCreateMassMatrixSquare(DM dmCoarse, DM dmFine, Mat *mass) 622*4cc7f7b2SMatthew G. Knepley { 623*4cc7f7b2SMatthew G. Knepley PetscInt n; 624*4cc7f7b2SMatthew G. Knepley void *ctx; 625*4cc7f7b2SMatthew G. Knepley PetscErrorCode ierr; 626*4cc7f7b2SMatthew G. Knepley 627*4cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 628*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 629*4cc7f7b2SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 630*4cc7f7b2SMatthew G. Knepley ierr = MatSetSizes(*mass, n, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 631*4cc7f7b2SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 632*4cc7f7b2SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 633*4cc7f7b2SMatthew G. Knepley 634*4cc7f7b2SMatthew G. Knepley ierr = DMSwarmComputeMassMatrixSquare_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 635*4cc7f7b2SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_sq_mat_view");CHKERRQ(ierr); 636*4cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 637*4cc7f7b2SMatthew G. Knepley } 638*4cc7f7b2SMatthew G. Knepley 639*4cc7f7b2SMatthew G. Knepley 640fb1bcc12SMatthew G. Knepley /*@C 641d3a51819SDave May DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 642d3a51819SDave May 643d083f849SBarry Smith Collective on dm 644d3a51819SDave May 645d3a51819SDave May Input parameters: 64662741f57SDave May + dm - a DMSwarm 64762741f57SDave May - fieldname - the textual name given to a registered field 648d3a51819SDave May 6498b8a3813SDave May Output parameter: 650d3a51819SDave May . vec - the vector 651d3a51819SDave May 652d3a51819SDave May Level: beginner 653d3a51819SDave May 6548b8a3813SDave May Notes: 6558b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField(). 6568b8a3813SDave May 6578b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField() 658d3a51819SDave May @*/ 65974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 660b5bcf523SDave May { 661fb1bcc12SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject) dm); 662b5bcf523SDave May PetscErrorCode ierr; 663b5bcf523SDave May 664fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 665fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 666b5bcf523SDave May PetscFunctionReturn(0); 667b5bcf523SDave May } 668b5bcf523SDave May 669d3a51819SDave May /*@C 670d3a51819SDave May DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 671d3a51819SDave May 672d083f849SBarry Smith Collective on dm 673d3a51819SDave May 674d3a51819SDave May Input parameters: 67562741f57SDave May + dm - a DMSwarm 67662741f57SDave May - fieldname - the textual name given to a registered field 677d3a51819SDave May 6788b8a3813SDave May Output parameter: 679d3a51819SDave May . vec - the vector 680d3a51819SDave May 681d3a51819SDave May Level: beginner 682d3a51819SDave May 6838b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField() 684d3a51819SDave May @*/ 68574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 686b5bcf523SDave May { 687b5bcf523SDave May PetscErrorCode ierr; 688cc651181SDave May 689fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 690fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 691b5bcf523SDave May PetscFunctionReturn(0); 692b5bcf523SDave May } 693b5bcf523SDave May 694fb1bcc12SMatthew G. Knepley /*@C 695fb1bcc12SMatthew G. Knepley DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field 696fb1bcc12SMatthew G. Knepley 697d083f849SBarry Smith Collective on dm 698fb1bcc12SMatthew G. Knepley 699fb1bcc12SMatthew G. Knepley Input parameters: 70062741f57SDave May + dm - a DMSwarm 70162741f57SDave May - fieldname - the textual name given to a registered field 702fb1bcc12SMatthew G. Knepley 7038b8a3813SDave May Output parameter: 704fb1bcc12SMatthew G. Knepley . vec - the vector 705fb1bcc12SMatthew G. Knepley 706fb1bcc12SMatthew G. Knepley Level: beginner 707fb1bcc12SMatthew G. Knepley 7088b8a3813SDave May Notes: 7098b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField(). 7108b8a3813SDave May 7118b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField() 712fb1bcc12SMatthew G. Knepley @*/ 71374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 714bbe8250bSMatthew G. Knepley { 715fb1bcc12SMatthew G. Knepley MPI_Comm comm = PETSC_COMM_SELF; 716bbe8250bSMatthew G. Knepley PetscErrorCode ierr; 717bbe8250bSMatthew G. Knepley 718fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 719fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 720fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 721bbe8250bSMatthew G. Knepley } 722fb1bcc12SMatthew G. Knepley 723fb1bcc12SMatthew G. Knepley /*@C 724fb1bcc12SMatthew G. Knepley DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field 725fb1bcc12SMatthew G. Knepley 726d083f849SBarry Smith Collective on dm 727fb1bcc12SMatthew G. Knepley 728fb1bcc12SMatthew G. Knepley Input parameters: 72962741f57SDave May + dm - a DMSwarm 73062741f57SDave May - fieldname - the textual name given to a registered field 731fb1bcc12SMatthew G. Knepley 7328b8a3813SDave May Output parameter: 733fb1bcc12SMatthew G. Knepley . vec - the vector 734fb1bcc12SMatthew G. Knepley 735fb1bcc12SMatthew G. Knepley Level: beginner 736fb1bcc12SMatthew G. Knepley 7378b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField() 738fb1bcc12SMatthew G. Knepley @*/ 73974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 740fb1bcc12SMatthew G. Knepley { 741fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 742fb1bcc12SMatthew G. Knepley 743fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 744fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 745bbe8250bSMatthew G. Knepley PetscFunctionReturn(0); 746bbe8250bSMatthew G. Knepley } 747bbe8250bSMatthew G. Knepley 748b5bcf523SDave May /* 74974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec) 750b5bcf523SDave May { 751b5bcf523SDave May PetscFunctionReturn(0); 752b5bcf523SDave May } 753b5bcf523SDave May 75474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec) 755b5bcf523SDave May { 756b5bcf523SDave May PetscFunctionReturn(0); 757b5bcf523SDave May } 758b5bcf523SDave May */ 759b5bcf523SDave May 760d3a51819SDave May /*@C 761d3a51819SDave May DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 762d3a51819SDave May 763d083f849SBarry Smith Collective on dm 764d3a51819SDave May 765d3a51819SDave May Input parameter: 766d3a51819SDave May . dm - a DMSwarm 767d3a51819SDave May 768d3a51819SDave May Level: beginner 769d3a51819SDave May 770d3a51819SDave May Notes: 7718b8a3813SDave May After all fields have been registered, you must call DMSwarmFinalizeFieldRegister(). 772d3a51819SDave May 773d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 774d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 775d3a51819SDave May @*/ 77674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 7775f50eb2eSDave May { 7785f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *) dm->data; 7793454631fSDave May PetscErrorCode ierr; 7803454631fSDave May 781521f74f9SMatthew G. Knepley PetscFunctionBegin; 782cc651181SDave May if (!swarm->field_registration_initialized) { 7835f50eb2eSDave May swarm->field_registration_initialized = PETSC_TRUE; 78443f984edSMatthew G. Knepley ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_INT64);CHKERRQ(ierr); /* unique identifer */ 785f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */ 786cc651181SDave May } 7875f50eb2eSDave May PetscFunctionReturn(0); 7885f50eb2eSDave May } 7895f50eb2eSDave May 79074d0cae8SMatthew G. Knepley /*@ 791d3a51819SDave May DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 792d3a51819SDave May 793d083f849SBarry Smith Collective on dm 794d3a51819SDave May 795d3a51819SDave May Input parameter: 796d3a51819SDave May . dm - a DMSwarm 797d3a51819SDave May 798d3a51819SDave May Level: beginner 799d3a51819SDave May 800d3a51819SDave May Notes: 80162741f57SDave May After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm. 802d3a51819SDave May 803d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 804d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 805d3a51819SDave May @*/ 80674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 8075f50eb2eSDave May { 8085f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8096845f8f5SDave May PetscErrorCode ierr; 8106845f8f5SDave May 811521f74f9SMatthew G. Knepley PetscFunctionBegin; 812f0cdbbbaSDave May if (!swarm->field_registration_finalized) { 81377048351SPatrick Sanan ierr = DMSwarmDataBucketFinalize(swarm->db);CHKERRQ(ierr); 814f0cdbbbaSDave May } 815f0cdbbbaSDave May swarm->field_registration_finalized = PETSC_TRUE; 8165f50eb2eSDave May PetscFunctionReturn(0); 8175f50eb2eSDave May } 8185f50eb2eSDave May 81974d0cae8SMatthew G. Knepley /*@ 820d3a51819SDave May DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 821d3a51819SDave May 822d3a51819SDave May Not collective 823d3a51819SDave May 824d3a51819SDave May Input parameters: 82562741f57SDave May + dm - a DMSwarm 826d3a51819SDave May . nlocal - the length of each registered field 82762741f57SDave May - buffer - the length of the buffer used to efficient dynamic re-sizing 828d3a51819SDave May 829d3a51819SDave May Level: beginner 830d3a51819SDave May 831d3a51819SDave May .seealso: DMSwarmGetLocalSize() 832d3a51819SDave May @*/ 83374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 8345f50eb2eSDave May { 8355f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8366845f8f5SDave May PetscErrorCode ierr; 8375f50eb2eSDave May 838521f74f9SMatthew G. Knepley PetscFunctionBegin; 839f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 84077048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr); 841f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 8425f50eb2eSDave May PetscFunctionReturn(0); 8435f50eb2eSDave May } 8445f50eb2eSDave May 84574d0cae8SMatthew G. Knepley /*@ 846d3a51819SDave May DMSwarmSetCellDM - Attachs a DM to a DMSwarm 847d3a51819SDave May 848d083f849SBarry Smith Collective on dm 849d3a51819SDave May 850d3a51819SDave May Input parameters: 85162741f57SDave May + dm - a DMSwarm 85262741f57SDave May - dmcell - the DM to attach to the DMSwarm 853d3a51819SDave May 854d3a51819SDave May Level: beginner 855d3a51819SDave May 856d3a51819SDave May Notes: 857d3a51819SDave May The attached DM (dmcell) will be queried for point location and 8588b8a3813SDave May neighbor MPI-rank information if DMSwarmMigrate() is called. 859d3a51819SDave May 8608b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate() 861d3a51819SDave May @*/ 86274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 863b16650c8SDave May { 864b16650c8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 865521f74f9SMatthew G. Knepley 866521f74f9SMatthew G. Knepley PetscFunctionBegin; 867b16650c8SDave May swarm->dmcell = dmcell; 868b16650c8SDave May PetscFunctionReturn(0); 869b16650c8SDave May } 870b16650c8SDave May 87174d0cae8SMatthew G. Knepley /*@ 872d3a51819SDave May DMSwarmGetCellDM - Fetches the attached cell DM 873d3a51819SDave May 874d083f849SBarry Smith Collective on dm 875d3a51819SDave May 876d3a51819SDave May Input parameter: 877d3a51819SDave May . dm - a DMSwarm 878d3a51819SDave May 879d3a51819SDave May Output parameter: 880d3a51819SDave May . dmcell - the DM which was attached to the DMSwarm 881d3a51819SDave May 882d3a51819SDave May Level: beginner 883d3a51819SDave May 884d3a51819SDave May .seealso: DMSwarmSetCellDM() 885d3a51819SDave May @*/ 88674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 887fe39f135SDave May { 888fe39f135SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 889521f74f9SMatthew G. Knepley 890521f74f9SMatthew G. Knepley PetscFunctionBegin; 891fe39f135SDave May *dmcell = swarm->dmcell; 892fe39f135SDave May PetscFunctionReturn(0); 893fe39f135SDave May } 894fe39f135SDave May 89574d0cae8SMatthew G. Knepley /*@ 896d3a51819SDave May DMSwarmGetLocalSize - Retrives the local length of fields registered 897d3a51819SDave May 898d3a51819SDave May Not collective 899d3a51819SDave May 900d3a51819SDave May Input parameter: 901d3a51819SDave May . dm - a DMSwarm 902d3a51819SDave May 903d3a51819SDave May Output parameter: 904d3a51819SDave May . nlocal - the length of each registered field 905d3a51819SDave May 906d3a51819SDave May Level: beginner 907d3a51819SDave May 9088b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes() 909d3a51819SDave May @*/ 91074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 911dcf43ee8SDave May { 912dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 913dcf43ee8SDave May PetscErrorCode ierr; 914dcf43ee8SDave May 915521f74f9SMatthew G. Knepley PetscFunctionBegin; 91677048351SPatrick Sanan if (nlocal) {ierr = DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);} 917dcf43ee8SDave May PetscFunctionReturn(0); 918dcf43ee8SDave May } 919dcf43ee8SDave May 92074d0cae8SMatthew G. Knepley /*@ 921d3a51819SDave May DMSwarmGetSize - Retrives the total length of fields registered 922d3a51819SDave May 923d083f849SBarry Smith Collective on dm 924d3a51819SDave May 925d3a51819SDave May Input parameter: 926d3a51819SDave May . dm - a DMSwarm 927d3a51819SDave May 928d3a51819SDave May Output parameter: 929d3a51819SDave May . n - the total length of each registered field 930d3a51819SDave May 931d3a51819SDave May Level: beginner 932d3a51819SDave May 933d3a51819SDave May Note: 934d3a51819SDave May This calls MPI_Allreduce upon each call (inefficient but safe) 935d3a51819SDave May 9368b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes() 937d3a51819SDave May @*/ 93874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 939dcf43ee8SDave May { 940dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 941dcf43ee8SDave May PetscErrorCode ierr; 942dcf43ee8SDave May PetscInt nlocal,ng; 943dcf43ee8SDave May 944521f74f9SMatthew G. Knepley PetscFunctionBegin; 94577048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 946dcf43ee8SDave May ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 947dcf43ee8SDave May if (n) { *n = ng; } 948dcf43ee8SDave May PetscFunctionReturn(0); 949dcf43ee8SDave May } 950dcf43ee8SDave May 951d3a51819SDave May /*@C 9528b8a3813SDave May DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type 953d3a51819SDave May 954d083f849SBarry Smith Collective on dm 955d3a51819SDave May 956d3a51819SDave May Input parameters: 95762741f57SDave May + dm - a DMSwarm 958d3a51819SDave May . fieldname - the textual name to identify this field 959d3a51819SDave May . blocksize - the number of each data type 96062741f57SDave May - type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 961d3a51819SDave May 962d3a51819SDave May Level: beginner 963d3a51819SDave May 964d3a51819SDave May Notes: 9658b8a3813SDave May The textual name for each registered field must be unique. 966d3a51819SDave May 967d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 968d3a51819SDave May @*/ 96974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 970b62e03f8SDave May { 9712eac95f8SDave May PetscErrorCode ierr; 972b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 973b62e03f8SDave May size_t size; 974b62e03f8SDave May 975521f74f9SMatthew G. Knepley PetscFunctionBegin; 9765f50eb2eSDave May if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 9775f50eb2eSDave May if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 9785f50eb2eSDave May 9795f50eb2eSDave May if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9805f50eb2eSDave May if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9815f50eb2eSDave May if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9825f50eb2eSDave May if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9835f50eb2eSDave May if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 984b62e03f8SDave May 9852ddcf43eSMatthew G. Knepley ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr); 986b62e03f8SDave May /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 98777048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 98852c3ed93SDave May { 98977048351SPatrick Sanan DMSwarmDataField gfield; 99052c3ed93SDave May 99177048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 99277048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 99352c3ed93SDave May } 994b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 995b62e03f8SDave May PetscFunctionReturn(0); 996b62e03f8SDave May } 997b62e03f8SDave May 998d3a51819SDave May /*@C 999d3a51819SDave May DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 1000d3a51819SDave May 1001d083f849SBarry Smith Collective on dm 1002d3a51819SDave May 1003d3a51819SDave May Input parameters: 100462741f57SDave May + dm - a DMSwarm 1005d3a51819SDave May . fieldname - the textual name to identify this field 100662741f57SDave May - size - the size in bytes of the user struct of each data type 1007d3a51819SDave May 1008d3a51819SDave May Level: beginner 1009d3a51819SDave May 1010d3a51819SDave May Notes: 10118b8a3813SDave May The textual name for each registered field must be unique. 1012d3a51819SDave May 1013d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField() 1014d3a51819SDave May @*/ 101574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 1016b62e03f8SDave May { 10172eac95f8SDave May PetscErrorCode ierr; 1018b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1019b62e03f8SDave May 1020521f74f9SMatthew G. Knepley PetscFunctionBegin; 102177048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 1022b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 1023b62e03f8SDave May PetscFunctionReturn(0); 1024b62e03f8SDave May } 1025b62e03f8SDave May 1026d3a51819SDave May /*@C 1027d3a51819SDave May DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 1028d3a51819SDave May 1029d083f849SBarry Smith Collective on dm 1030d3a51819SDave May 1031d3a51819SDave May Input parameters: 103262741f57SDave May + dm - a DMSwarm 1033d3a51819SDave May . fieldname - the textual name to identify this field 1034d3a51819SDave May . size - the size in bytes of the user data type 103562741f57SDave May - blocksize - the number of each data type 1036d3a51819SDave May 1037d3a51819SDave May Level: beginner 1038d3a51819SDave May 1039d3a51819SDave May Notes: 10408b8a3813SDave May The textual name for each registered field must be unique. 1041d3a51819SDave May 1042d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 1043d3a51819SDave May @*/ 104474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 1045b62e03f8SDave May { 1046b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 10476845f8f5SDave May PetscErrorCode ierr; 1048b62e03f8SDave May 1049521f74f9SMatthew G. Knepley PetscFunctionBegin; 105077048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 1051320740a0SDave May { 105277048351SPatrick Sanan DMSwarmDataField gfield; 1053320740a0SDave May 105477048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 105577048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 1056320740a0SDave May } 1057b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 1058b62e03f8SDave May PetscFunctionReturn(0); 1059b62e03f8SDave May } 1060b62e03f8SDave May 1061d3a51819SDave May /*@C 1062d3a51819SDave May DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 1063d3a51819SDave May 1064d3a51819SDave May Not collective 1065d3a51819SDave May 1066d3a51819SDave May Input parameters: 106762741f57SDave May + dm - a DMSwarm 106862741f57SDave May - fieldname - the textual name to identify this field 1069d3a51819SDave May 1070d3a51819SDave May Output parameters: 107162741f57SDave May + blocksize - the number of each data type 1072d3a51819SDave May . type - the data type 107362741f57SDave May - data - pointer to raw array 1074d3a51819SDave May 1075d3a51819SDave May Level: beginner 1076d3a51819SDave May 1077d3a51819SDave May Notes: 10788b8a3813SDave May The array must be returned using a matching call to DMSwarmRestoreField(). 1079d3a51819SDave May 1080d3a51819SDave May .seealso: DMSwarmRestoreField() 1081d3a51819SDave May @*/ 108274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1083b62e03f8SDave May { 1084b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 108577048351SPatrick Sanan DMSwarmDataField gfield; 10862eac95f8SDave May PetscErrorCode ierr; 1087b62e03f8SDave May 1088521f74f9SMatthew G. Knepley PetscFunctionBegin; 10893454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 109077048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 109177048351SPatrick Sanan ierr = DMSwarmDataFieldGetAccess(gfield);CHKERRQ(ierr); 109277048351SPatrick Sanan ierr = DMSwarmDataFieldGetEntries(gfield,data);CHKERRQ(ierr); 10931b1ea282SDave May if (blocksize) {*blocksize = gfield->bs; } 1094b5bcf523SDave May if (type) { *type = gfield->petsc_type; } 1095b62e03f8SDave May PetscFunctionReturn(0); 1096b62e03f8SDave May } 1097b62e03f8SDave May 1098d3a51819SDave May /*@C 1099d3a51819SDave May DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 1100d3a51819SDave May 1101d3a51819SDave May Not collective 1102d3a51819SDave May 1103d3a51819SDave May Input parameters: 110462741f57SDave May + dm - a DMSwarm 110562741f57SDave May - fieldname - the textual name to identify this field 1106d3a51819SDave May 1107d3a51819SDave May Output parameters: 110862741f57SDave May + blocksize - the number of each data type 1109d3a51819SDave May . type - the data type 111062741f57SDave May - data - pointer to raw array 1111d3a51819SDave May 1112d3a51819SDave May Level: beginner 1113d3a51819SDave May 1114d3a51819SDave May Notes: 11158b8a3813SDave May The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField(). 1116d3a51819SDave May 1117d3a51819SDave May .seealso: DMSwarmGetField() 1118d3a51819SDave May @*/ 111974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1120b62e03f8SDave May { 1121b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 112277048351SPatrick Sanan DMSwarmDataField gfield; 11232eac95f8SDave May PetscErrorCode ierr; 1124b62e03f8SDave May 1125521f74f9SMatthew G. Knepley PetscFunctionBegin; 112677048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 112777048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 1128b62e03f8SDave May if (data) *data = NULL; 1129b62e03f8SDave May PetscFunctionReturn(0); 1130b62e03f8SDave May } 1131b62e03f8SDave May 113274d0cae8SMatthew G. Knepley /*@ 1133d3a51819SDave May DMSwarmAddPoint - Add space for one new point in the DMSwarm 1134d3a51819SDave May 1135d3a51819SDave May Not collective 1136d3a51819SDave May 1137d3a51819SDave May Input parameter: 1138d3a51819SDave May . dm - a DMSwarm 1139d3a51819SDave May 1140d3a51819SDave May Level: beginner 1141d3a51819SDave May 1142d3a51819SDave May Notes: 11438b8a3813SDave May The new point will have all fields initialized to zero. 1144d3a51819SDave May 1145d3a51819SDave May .seealso: DMSwarmAddNPoints() 1146d3a51819SDave May @*/ 114774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddPoint(DM dm) 1148cb1d1399SDave May { 1149cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1150cb1d1399SDave May PetscErrorCode ierr; 1151cb1d1399SDave May 1152521f74f9SMatthew G. Knepley PetscFunctionBegin; 11533454631fSDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 1154f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 115577048351SPatrick Sanan ierr = DMSwarmDataBucketAddPoint(swarm->db);CHKERRQ(ierr); 1156f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 1157cb1d1399SDave May PetscFunctionReturn(0); 1158cb1d1399SDave May } 1159cb1d1399SDave May 116074d0cae8SMatthew G. Knepley /*@ 1161d3a51819SDave May DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 1162d3a51819SDave May 1163d3a51819SDave May Not collective 1164d3a51819SDave May 1165d3a51819SDave May Input parameters: 116662741f57SDave May + dm - a DMSwarm 116762741f57SDave May - npoints - the number of new points to add 1168d3a51819SDave May 1169d3a51819SDave May Level: beginner 1170d3a51819SDave May 1171d3a51819SDave May Notes: 11728b8a3813SDave May The new point will have all fields initialized to zero. 1173d3a51819SDave May 1174d3a51819SDave May .seealso: DMSwarmAddPoint() 1175d3a51819SDave May @*/ 117674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 1177cb1d1399SDave May { 1178cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1179cb1d1399SDave May PetscErrorCode ierr; 1180cb1d1399SDave May PetscInt nlocal; 1181cb1d1399SDave May 1182521f74f9SMatthew G. Knepley PetscFunctionBegin; 1183f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 118477048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 1185cb1d1399SDave May nlocal = nlocal + npoints; 118677048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr); 1187f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 1188cb1d1399SDave May PetscFunctionReturn(0); 1189cb1d1399SDave May } 1190cb1d1399SDave May 119174d0cae8SMatthew G. Knepley /*@ 1192d3a51819SDave May DMSwarmRemovePoint - Remove the last point from the DMSwarm 1193d3a51819SDave May 1194d3a51819SDave May Not collective 1195d3a51819SDave May 1196d3a51819SDave May Input parameter: 1197d3a51819SDave May . dm - a DMSwarm 1198d3a51819SDave May 1199d3a51819SDave May Level: beginner 1200d3a51819SDave May 1201d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex() 1202d3a51819SDave May @*/ 120374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePoint(DM dm) 1204cb1d1399SDave May { 1205cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1206cb1d1399SDave May PetscErrorCode ierr; 1207cb1d1399SDave May 1208521f74f9SMatthew G. Knepley PetscFunctionBegin; 1209f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 121077048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 1211f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 1212cb1d1399SDave May PetscFunctionReturn(0); 1213cb1d1399SDave May } 1214cb1d1399SDave May 121574d0cae8SMatthew G. Knepley /*@ 1216d3a51819SDave May DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 1217d3a51819SDave May 1218d3a51819SDave May Not collective 1219d3a51819SDave May 1220d3a51819SDave May Input parameters: 122162741f57SDave May + dm - a DMSwarm 122262741f57SDave May - idx - index of point to remove 1223d3a51819SDave May 1224d3a51819SDave May Level: beginner 1225d3a51819SDave May 1226d3a51819SDave May .seealso: DMSwarmRemovePoint() 1227d3a51819SDave May @*/ 122874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 1229cb1d1399SDave May { 1230cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1231cb1d1399SDave May PetscErrorCode ierr; 1232cb1d1399SDave May 1233521f74f9SMatthew G. Knepley PetscFunctionBegin; 1234f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 123577048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 1236f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 1237cb1d1399SDave May PetscFunctionReturn(0); 1238cb1d1399SDave May } 1239b62e03f8SDave May 124074d0cae8SMatthew G. Knepley /*@ 1241ba4fc9c6SDave May DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm 1242ba4fc9c6SDave May 1243ba4fc9c6SDave May Not collective 1244ba4fc9c6SDave May 1245ba4fc9c6SDave May Input parameters: 1246ba4fc9c6SDave May + dm - a DMSwarm 1247ba4fc9c6SDave May . pi - the index of the point to copy 1248ba4fc9c6SDave May - pj - the point index where the copy should be located 1249ba4fc9c6SDave May 1250ba4fc9c6SDave May Level: beginner 1251ba4fc9c6SDave May 1252ba4fc9c6SDave May .seealso: DMSwarmRemovePoint() 1253ba4fc9c6SDave May @*/ 125474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj) 1255ba4fc9c6SDave May { 1256ba4fc9c6SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1257ba4fc9c6SDave May PetscErrorCode ierr; 1258ba4fc9c6SDave May 1259ba4fc9c6SDave May PetscFunctionBegin; 1260ba4fc9c6SDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 126177048351SPatrick Sanan ierr = DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr); 1262ba4fc9c6SDave May PetscFunctionReturn(0); 1263ba4fc9c6SDave May } 1264ba4fc9c6SDave May 1265095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 12663454631fSDave May { 1267dcf43ee8SDave May PetscErrorCode ierr; 1268521f74f9SMatthew G. Knepley 1269521f74f9SMatthew G. Knepley PetscFunctionBegin; 1270dcf43ee8SDave May ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 12713454631fSDave May PetscFunctionReturn(0); 12723454631fSDave May } 12733454631fSDave May 127474d0cae8SMatthew G. Knepley /*@ 1275d3a51819SDave May DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 1276d3a51819SDave May 1277d083f849SBarry Smith Collective on dm 1278d3a51819SDave May 1279d3a51819SDave May Input parameters: 128062741f57SDave May + dm - the DMSwarm 128162741f57SDave May - remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 1282d3a51819SDave May 1283d3a51819SDave May Notes: 12848b8a3813SDave May The DM will be modified to accomodate received points. 12858b8a3813SDave May If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM. 12868b8a3813SDave May Different styles of migration are supported. See DMSwarmSetMigrateType(). 1287d3a51819SDave May 1288d3a51819SDave May Level: advanced 1289d3a51819SDave May 1290d3a51819SDave May .seealso: DMSwarmSetMigrateType() 1291d3a51819SDave May @*/ 129274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 12933454631fSDave May { 1294f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 12953454631fSDave May PetscErrorCode ierr; 1296f0cdbbbaSDave May 1297521f74f9SMatthew G. Knepley PetscFunctionBegin; 1298ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 1299f0cdbbbaSDave May switch (swarm->migrate_type) { 1300f0cdbbbaSDave May case DMSWARM_MIGRATE_BASIC: 1301095059a4SDave May ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 1302f0cdbbbaSDave May break; 1303f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLNSCATTER: 1304f0cdbbbaSDave May ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 1305f0cdbbbaSDave May break; 1306f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLEXACT: 1307f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 1308f0cdbbbaSDave May break; 1309f0cdbbbaSDave May case DMSWARM_MIGRATE_USER: 1310f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 1311f0cdbbbaSDave May break; 1312f0cdbbbaSDave May default: 1313f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 1314f0cdbbbaSDave May break; 1315f0cdbbbaSDave May } 1316ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 13173454631fSDave May PetscFunctionReturn(0); 13183454631fSDave May } 13193454631fSDave May 1320f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 1321f0cdbbbaSDave May 1322d3a51819SDave May /* 1323d3a51819SDave May DMSwarmCollectViewCreate 1324d3a51819SDave May 1325d3a51819SDave May * Applies a collection method and gathers point neighbour points into dm 1326d3a51819SDave May 1327d3a51819SDave May Notes: 13288b8a3813SDave May Users should call DMSwarmCollectViewDestroy() after 1329d3a51819SDave May they have finished computations associated with the collected points 1330d3a51819SDave May */ 1331d3a51819SDave May 133274d0cae8SMatthew G. Knepley /*@ 1333d3a51819SDave May DMSwarmCollectViewCreate - Applies a collection method and gathers points 1334d3a51819SDave May in neighbour MPI-ranks into the DMSwarm 1335d3a51819SDave May 1336d083f849SBarry Smith Collective on dm 1337d3a51819SDave May 1338d3a51819SDave May Input parameter: 1339d3a51819SDave May . dm - the DMSwarm 1340d3a51819SDave May 1341d3a51819SDave May Notes: 1342d3a51819SDave May Users should call DMSwarmCollectViewDestroy() after 1343d3a51819SDave May they have finished computations associated with the collected points 13448b8a3813SDave May Different collect methods are supported. See DMSwarmSetCollectType(). 1345d3a51819SDave May 1346d3a51819SDave May Level: advanced 1347d3a51819SDave May 1348d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType() 1349d3a51819SDave May @*/ 135074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewCreate(DM dm) 13512712d1f2SDave May { 13522712d1f2SDave May PetscErrorCode ierr; 13532712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13542712d1f2SDave May PetscInt ng; 13552712d1f2SDave May 1356521f74f9SMatthew G. Knepley PetscFunctionBegin; 1357480eef7bSDave May if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 1358480eef7bSDave May ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 1359480eef7bSDave May switch (swarm->collect_type) { 1360f0cdbbbaSDave May 1361480eef7bSDave May case DMSWARM_COLLECT_BASIC: 13622712d1f2SDave May ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 1363480eef7bSDave May break; 1364480eef7bSDave May case DMSWARM_COLLECT_DMDABOUNDINGBOX: 1365f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 1366480eef7bSDave May break; 1367480eef7bSDave May case DMSWARM_COLLECT_GENERAL: 1368f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 1369480eef7bSDave May break; 1370480eef7bSDave May default: 1371f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 1372480eef7bSDave May break; 1373480eef7bSDave May } 1374480eef7bSDave May swarm->collect_view_active = PETSC_TRUE; 1375480eef7bSDave May swarm->collect_view_reset_nlocal = ng; 13762712d1f2SDave May PetscFunctionReturn(0); 13772712d1f2SDave May } 13782712d1f2SDave May 137974d0cae8SMatthew G. Knepley /*@ 1380d3a51819SDave May DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 1381d3a51819SDave May 1382d083f849SBarry Smith Collective on dm 1383d3a51819SDave May 1384d3a51819SDave May Input parameters: 1385d3a51819SDave May . dm - the DMSwarm 1386d3a51819SDave May 1387d3a51819SDave May Notes: 1388d3a51819SDave May Users should call DMSwarmCollectViewCreate() before this function is called. 1389d3a51819SDave May 1390d3a51819SDave May Level: advanced 1391d3a51819SDave May 1392d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType() 1393d3a51819SDave May @*/ 139474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 13952712d1f2SDave May { 13962712d1f2SDave May PetscErrorCode ierr; 13972712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13982712d1f2SDave May 1399521f74f9SMatthew G. Knepley PetscFunctionBegin; 1400480eef7bSDave May if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 1401480eef7bSDave May ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 1402480eef7bSDave May swarm->collect_view_active = PETSC_FALSE; 14032712d1f2SDave May PetscFunctionReturn(0); 14042712d1f2SDave May } 14053454631fSDave May 1406f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm) 1407f0cdbbbaSDave May { 1408f0cdbbbaSDave May PetscInt dim; 1409f0cdbbbaSDave May PetscErrorCode ierr; 1410f0cdbbbaSDave May 1411521f74f9SMatthew G. Knepley PetscFunctionBegin; 1412f0cdbbbaSDave May ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 1413f0cdbbbaSDave May if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1414f0cdbbbaSDave May if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1415f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 1416e2d107dbSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr); 1417f0cdbbbaSDave May PetscFunctionReturn(0); 1418f0cdbbbaSDave May } 1419f0cdbbbaSDave May 142074d0cae8SMatthew G. Knepley /*@ 1421d3a51819SDave May DMSwarmSetType - Set particular flavor of DMSwarm 1422d3a51819SDave May 1423d083f849SBarry Smith Collective on dm 1424d3a51819SDave May 1425d3a51819SDave May Input parameters: 142662741f57SDave May + dm - the DMSwarm 142762741f57SDave May - stype - the DMSwarm type (e.g. DMSWARM_PIC) 1428d3a51819SDave May 1429d3a51819SDave May Level: advanced 1430d3a51819SDave May 1431d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType() 1432d3a51819SDave May @*/ 143374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 1434f0cdbbbaSDave May { 1435f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1436f0cdbbbaSDave May PetscErrorCode ierr; 1437f0cdbbbaSDave May 1438521f74f9SMatthew G. Knepley PetscFunctionBegin; 1439f0cdbbbaSDave May swarm->swarm_type = stype; 1440f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1441f0cdbbbaSDave May ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 1442f0cdbbbaSDave May } 1443f0cdbbbaSDave May PetscFunctionReturn(0); 1444f0cdbbbaSDave May } 1445f0cdbbbaSDave May 14463454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm) 14473454631fSDave May { 14483454631fSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 14493454631fSDave May PetscErrorCode ierr; 14503454631fSDave May PetscMPIInt rank; 14513454631fSDave May PetscInt p,npoints,*rankval; 14523454631fSDave May 1453521f74f9SMatthew G. Knepley PetscFunctionBegin; 14543454631fSDave May if (swarm->issetup) PetscFunctionReturn(0); 14553454631fSDave May 14563454631fSDave May swarm->issetup = PETSC_TRUE; 14573454631fSDave May 1458f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1459f0cdbbbaSDave May /* check dmcell exists */ 1460f0cdbbbaSDave May if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1461f0cdbbbaSDave May 1462f0cdbbbaSDave May if (swarm->dmcell->ops->locatepointssubdomain) { 1463f0cdbbbaSDave May /* check methods exists for exact ownership identificiation */ 146477b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr); 1465f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1466f0cdbbbaSDave May } else { 1467f0cdbbbaSDave May /* check methods exist for point location AND rank neighbor identification */ 1468f0cdbbbaSDave May if (swarm->dmcell->ops->locatepoints) { 146977b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr); 1470f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1471f0cdbbbaSDave May 1472f0cdbbbaSDave May if (swarm->dmcell->ops->getneighbors) { 147377b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr); 1474f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1475f0cdbbbaSDave May 1476f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1477f0cdbbbaSDave May } 1478f0cdbbbaSDave May } 1479f0cdbbbaSDave May 1480f0cdbbbaSDave May ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 1481f0cdbbbaSDave May 14823454631fSDave May /* check some fields were registered */ 14833454631fSDave May if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 14843454631fSDave May 14853454631fSDave May /* check local sizes were set */ 14863454631fSDave May if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 14873454631fSDave May 14883454631fSDave May /* initialize values in pid and rank placeholders */ 14893454631fSDave May /* TODO: [pid - use MPI_Scan] */ 14903454631fSDave May ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 149177048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 1492f0cdbbbaSDave May ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 14933454631fSDave May for (p=0; p<npoints; p++) { 14943454631fSDave May rankval[p] = (PetscInt)rank; 14953454631fSDave May } 1496f0cdbbbaSDave May ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 14973454631fSDave May PetscFunctionReturn(0); 14983454631fSDave May } 14993454631fSDave May 1500dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx); 1501dc5f5ce9SDave May 150257795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm) 150357795646SDave May { 150457795646SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 150557795646SDave May PetscErrorCode ierr; 150657795646SDave May 150757795646SDave May PetscFunctionBegin; 150877048351SPatrick Sanan ierr = DMSwarmDataBucketDestroy(&swarm->db);CHKERRQ(ierr); 1509dc5f5ce9SDave May if (swarm->sort_context) { 1510dc5f5ce9SDave May ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr); 1511dc5f5ce9SDave May } 151257795646SDave May ierr = PetscFree(swarm);CHKERRQ(ierr); 151357795646SDave May PetscFunctionReturn(0); 151457795646SDave May } 151557795646SDave May 1516a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) 1517a9ee3421SMatthew G. Knepley { 1518a9ee3421SMatthew G. Knepley DM cdm; 1519a9ee3421SMatthew G. Knepley PetscDraw draw; 1520a9ee3421SMatthew G. Knepley PetscReal *coords, oldPause; 1521a9ee3421SMatthew G. Knepley PetscInt Np, p, bs; 1522a9ee3421SMatthew G. Knepley PetscErrorCode ierr; 1523a9ee3421SMatthew G. Knepley 1524a9ee3421SMatthew G. Knepley PetscFunctionBegin; 1525a9ee3421SMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1526a9ee3421SMatthew G. Knepley ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 1527a9ee3421SMatthew G. Knepley ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr); 1528a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr); 1529a9ee3421SMatthew G. Knepley ierr = DMView(cdm, viewer);CHKERRQ(ierr); 1530a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr); 1531a9ee3421SMatthew G. Knepley 1532a9ee3421SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr); 1533a9ee3421SMatthew G. Knepley ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1534a9ee3421SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1535a9ee3421SMatthew G. Knepley const PetscInt i = p*bs; 1536a9ee3421SMatthew G. Knepley 1537a9ee3421SMatthew G. Knepley ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr); 1538a9ee3421SMatthew G. Knepley } 1539a9ee3421SMatthew G. Knepley ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1540a9ee3421SMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1541a9ee3421SMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1542a9ee3421SMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1543a9ee3421SMatthew G. Knepley PetscFunctionReturn(0); 1544a9ee3421SMatthew G. Knepley } 1545a9ee3421SMatthew G. Knepley 15465f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 15475f50eb2eSDave May { 15485f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1549a9ee3421SMatthew G. Knepley PetscBool iascii,ibinary,ishdf5,isvtk,isdraw; 15505f50eb2eSDave May PetscErrorCode ierr; 15515f50eb2eSDave May 15525f50eb2eSDave May PetscFunctionBegin; 15535f50eb2eSDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 15545f50eb2eSDave May PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 15555f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 15565f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 15575f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 15585f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1559a9ee3421SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 15605f50eb2eSDave May if (iascii) { 156177048351SPatrick Sanan ierr = DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 1562298827fbSBarry Smith } else if (ibinary) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support"); 15635f50eb2eSDave May #if defined(PETSC_HAVE_HDF5) 156474d0cae8SMatthew G. Knepley else if (ishdf5) { 156574d0cae8SMatthew G. Knepley ierr = DMSwarmView_HDF5(dm, viewer);CHKERRQ(ierr); 156674d0cae8SMatthew G. Knepley } 15675f50eb2eSDave May #else 1568298827fbSBarry Smith else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 15695f50eb2eSDave May #endif 1570298827fbSBarry Smith else if (isvtk) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1571298827fbSBarry Smith else if (isdraw) { 1572a9ee3421SMatthew G. Knepley ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr); 15735f50eb2eSDave May } 15745f50eb2eSDave May PetscFunctionReturn(0); 15755f50eb2eSDave May } 15765f50eb2eSDave May 1577d3a51819SDave May /*MC 1578d3a51819SDave May 1579d3a51819SDave May DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 158062741f57SDave May This implementation was designed for particle methods in which the underlying 1581d3a51819SDave May data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1582d3a51819SDave May 158362741f57SDave May User data can be represented by DMSwarm through a registering "fields". 158462741f57SDave May To register a field, the user must provide; 158562741f57SDave May (a) a unique name; 158662741f57SDave May (b) the data type (or size in bytes); 158762741f57SDave May (c) the block size of the data. 1588d3a51819SDave May 1589d3a51819SDave May For example, suppose the application requires a unique id, energy, momentum and density to be stored 1590c215a47eSMatthew Knepley on a set of particles. Then the following code could be used 1591d3a51819SDave May 159262741f57SDave May $ DMSwarmInitializeFieldRegister(dm) 159362741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 159462741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 159562741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 159662741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 159762741f57SDave May $ DMSwarmFinalizeFieldRegister(dm) 1598d3a51819SDave May 1599d3a51819SDave May The fields represented by DMSwarm are dynamic and can be re-sized at any time. 160062741f57SDave May The only restriction imposed by DMSwarm is that all fields contain the same number of points. 1601d3a51819SDave May 1602d3a51819SDave May To support particle methods, "migration" techniques are provided. These methods migrate data 1603d3a51819SDave May between MPI-ranks. 1604d3a51819SDave May 1605d3a51819SDave May DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1606d3a51819SDave May As a DMSwarm may internally define and store values of different data types, 160762741f57SDave May before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which 1608d3a51819SDave May fields should be used to define a Vec object via 1609d3a51819SDave May DMSwarmVectorDefineField() 1610c215a47eSMatthew Knepley The specified field can be changed at any time - thereby permitting vectors 1611c215a47eSMatthew Knepley compatible with different fields to be created. 1612d3a51819SDave May 161362741f57SDave May A dual representation of fields in the DMSwarm and a Vec object is permitted via 1614d3a51819SDave May DMSwarmCreateGlobalVectorFromField() 1615d3a51819SDave May Here the data defining the field in the DMSwarm is shared with a Vec. 1616d3a51819SDave May This is inherently unsafe if you alter the size of the field at any time between 1617d3a51819SDave May calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1618cc651181SDave May If the local size of the DMSwarm does not match the local size of the global vector 1619cc651181SDave May when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1620d3a51819SDave May 162162741f57SDave May Additional high-level support is provided for Particle-In-Cell methods. 162262741f57SDave May Please refer to the man page for DMSwarmSetType(). 162362741f57SDave May 1624d3a51819SDave May Level: beginner 1625d3a51819SDave May 1626d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType() 1627d3a51819SDave May M*/ 162857795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 162957795646SDave May { 163057795646SDave May DM_Swarm *swarm; 163157795646SDave May PetscErrorCode ierr; 163257795646SDave May 163357795646SDave May PetscFunctionBegin; 163457795646SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 163557795646SDave May ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 1636f0cdbbbaSDave May dm->data = swarm; 163757795646SDave May 163877048351SPatrick Sanan ierr = DMSwarmDataBucketCreate(&swarm->db);CHKERRQ(ierr); 1639f0cdbbbaSDave May ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 1640f0cdbbbaSDave May 1641b5bcf523SDave May swarm->vec_field_set = PETSC_FALSE; 16423454631fSDave May swarm->issetup = PETSC_FALSE; 1643480eef7bSDave May swarm->swarm_type = DMSWARM_BASIC; 1644480eef7bSDave May swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1645480eef7bSDave May swarm->collect_type = DMSWARM_COLLECT_BASIC; 164640c453e9SDave May swarm->migrate_error_on_missing_point = PETSC_FALSE; 1647b62e03f8SDave May 1648f0cdbbbaSDave May swarm->dmcell = NULL; 1649f0cdbbbaSDave May swarm->collect_view_active = PETSC_FALSE; 1650f0cdbbbaSDave May swarm->collect_view_reset_nlocal = -1; 165157795646SDave May 1652f0cdbbbaSDave May dm->dim = 0; 16535f50eb2eSDave May dm->ops->view = DMView_Swarm; 165457795646SDave May dm->ops->load = NULL; 165557795646SDave May dm->ops->setfromoptions = NULL; 165657795646SDave May dm->ops->clone = NULL; 16573454631fSDave May dm->ops->setup = DMSetup_Swarm; 16581bb6d2a8SBarry Smith dm->ops->createlocalsection = NULL; 165957795646SDave May dm->ops->createdefaultconstraints = NULL; 1660b5bcf523SDave May dm->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1661b5bcf523SDave May dm->ops->createlocalvector = DMCreateLocalVector_Swarm; 166257795646SDave May dm->ops->getlocaltoglobalmapping = NULL; 166357795646SDave May dm->ops->createfieldis = NULL; 166457795646SDave May dm->ops->createcoordinatedm = NULL; 166557795646SDave May dm->ops->getcoloring = NULL; 166657795646SDave May dm->ops->creatematrix = NULL; 166757795646SDave May dm->ops->createinterpolation = NULL; 16685a84ad33SLisandro Dalcin dm->ops->createinjection = NULL; 166983c47955SMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Swarm; 167057795646SDave May dm->ops->refine = NULL; 167157795646SDave May dm->ops->coarsen = NULL; 167257795646SDave May dm->ops->refinehierarchy = NULL; 167357795646SDave May dm->ops->coarsenhierarchy = NULL; 167457795646SDave May dm->ops->globaltolocalbegin = NULL; 167557795646SDave May dm->ops->globaltolocalend = NULL; 167657795646SDave May dm->ops->localtoglobalbegin = NULL; 167757795646SDave May dm->ops->localtoglobalend = NULL; 167857795646SDave May dm->ops->destroy = DMDestroy_Swarm; 167957795646SDave May dm->ops->createsubdm = NULL; 168057795646SDave May dm->ops->getdimpoints = NULL; 168157795646SDave May dm->ops->locatepoints = NULL; 168257795646SDave May PetscFunctionReturn(0); 168357795646SDave May } 1684