157795646SDave May #define PETSCDM_DLL 257795646SDave May #include <petsc/private/dmswarmimpl.h> /*I "petscdmswarm.h" I*/ 3e8f14785SLisandro Dalcin #include <petsc/private/hashsetij.h> 40643ed39SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> 55917a6f0SStefano Zampini #include <petscviewer.h> 65917a6f0SStefano Zampini #include <petscdraw.h> 783c47955SMatthew G. Knepley #include <petscdmplex.h> 84cc7f7b2SMatthew G. Knepley #include <petscblaslapack.h> 9279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h" 10d0c080abSJoseph Pusztay #include <petscdmlabel.h> 11d0c080abSJoseph Pusztay #include <petscsection.h> 1257795646SDave May 13f2b2bee7SDave May PetscLogEvent DMSWARM_Migrate, DMSWARM_SetSizes, DMSWARM_AddPoints, DMSWARM_RemovePoints, DMSWARM_Sort; 14ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd; 15ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack; 16ed923d71SDave May 17ea78f98cSLisandro Dalcin const char* DMSwarmTypeNames[] = { "basic", "pic", NULL }; 18ea78f98cSLisandro Dalcin const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", NULL }; 19ea78f98cSLisandro Dalcin const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", NULL }; 20ea78f98cSLisandro Dalcin const char* DMSwarmPICLayoutTypeNames[] = { "regular", "gauss", "subdivision", NULL }; 21f0cdbbbaSDave May 22f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid"; 23f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank"; 24f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor"; 25e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid"; 26f0cdbbbaSDave May 2774d0cae8SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 2874d0cae8SMatthew G. Knepley #include <petscviewerhdf5.h> 2974d0cae8SMatthew G. Knepley 3074d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm_HDF5_Internal(Vec v, PetscViewer viewer) 3174d0cae8SMatthew G. Knepley { 3274d0cae8SMatthew G. Knepley DM dm; 3374d0cae8SMatthew G. Knepley PetscReal seqval; 3474d0cae8SMatthew G. Knepley PetscInt seqnum, bs; 3574d0cae8SMatthew G. Knepley PetscBool isseq; 3674d0cae8SMatthew G. Knepley PetscErrorCode ierr; 3774d0cae8SMatthew G. Knepley 3874d0cae8SMatthew G. Knepley PetscFunctionBegin; 3974d0cae8SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 4074d0cae8SMatthew G. Knepley ierr = VecGetBlockSize(v, &bs);CHKERRQ(ierr); 4174d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PushGroup(viewer, "/particle_fields");CHKERRQ(ierr); 4274d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 4374d0cae8SMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, &seqnum, &seqval);CHKERRQ(ierr); 4474d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5SetTimestep(viewer, seqnum);CHKERRQ(ierr); 4574d0cae8SMatthew G. Knepley /* ierr = DMSequenceView_HDF5(dm, "time", seqnum, (PetscScalar) seqval, viewer);CHKERRQ(ierr); */ 46*f9558f5cSBarry Smith ierr = VecViewNative(v, viewer);CHKERRQ(ierr); 4774d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) v, "Nc", PETSC_INT, (void *) &bs);CHKERRQ(ierr); 4874d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PopGroup(viewer);CHKERRQ(ierr); 4974d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 5074d0cae8SMatthew G. Knepley } 5174d0cae8SMatthew G. Knepley 5274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmView_HDF5(DM dm, PetscViewer viewer) 5374d0cae8SMatthew G. Knepley { 5474d0cae8SMatthew G. Knepley Vec coordinates; 5574d0cae8SMatthew G. Knepley PetscInt Np; 5674d0cae8SMatthew G. Knepley PetscBool isseq; 5774d0cae8SMatthew G. Knepley PetscErrorCode ierr; 5874d0cae8SMatthew G. Knepley 5974d0cae8SMatthew G. Knepley PetscFunctionBegin; 6074d0cae8SMatthew G. Knepley ierr = DMSwarmGetSize(dm, &Np);CHKERRQ(ierr); 6174d0cae8SMatthew G. Knepley ierr = DMSwarmCreateGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates);CHKERRQ(ierr); 6274d0cae8SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 6374d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PushGroup(viewer, "/particles");CHKERRQ(ierr); 6474d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) coordinates, VECSEQ, &isseq);CHKERRQ(ierr); 65*f9558f5cSBarry Smith ierr = VecViewNative(coordinates, viewer);CHKERRQ(ierr); 6674d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) coordinates, "Np", PETSC_INT, (void *) &Np);CHKERRQ(ierr); 6774d0cae8SMatthew G. Knepley ierr = PetscViewerHDF5PopGroup(viewer);CHKERRQ(ierr); 6874d0cae8SMatthew G. Knepley ierr = DMSwarmDestroyGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates);CHKERRQ(ierr); 6974d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 7074d0cae8SMatthew G. Knepley } 7174d0cae8SMatthew G. Knepley #endif 7274d0cae8SMatthew G. Knepley 7374d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm(Vec v, PetscViewer viewer) 7474d0cae8SMatthew G. Knepley { 7574d0cae8SMatthew G. Knepley DM dm; 76*f9558f5cSBarry Smith #if defined(PETSC_HAVE_HDF5) 7774d0cae8SMatthew G. Knepley PetscBool ishdf5; 78*f9558f5cSBarry Smith #endif 7974d0cae8SMatthew G. Knepley PetscErrorCode ierr; 8074d0cae8SMatthew G. Knepley 8174d0cae8SMatthew G. Knepley PetscFunctionBegin; 8274d0cae8SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 8374d0cae8SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 84*f9558f5cSBarry Smith #if defined(PETSC_HAVE_HDF5) 8574d0cae8SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 8674d0cae8SMatthew G. Knepley if (ishdf5) { 8774d0cae8SMatthew G. Knepley ierr = VecView_Swarm_HDF5_Internal(v, viewer);CHKERRQ(ierr); 88*f9558f5cSBarry Smith PetscFunctionReturn(0); 8974d0cae8SMatthew G. Knepley } 90*f9558f5cSBarry Smith #endif 91*f9558f5cSBarry Smith ierr = VecViewNative(v, viewer);CHKERRQ(ierr); 9274d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 9374d0cae8SMatthew G. Knepley } 9474d0cae8SMatthew G. Knepley 95d3a51819SDave May /*@C 9662741f57SDave May DMSwarmVectorDefineField - Sets the field from which to define a Vec object 9762741f57SDave May when DMCreateLocalVector(), or DMCreateGlobalVector() is called 9857795646SDave May 99d083f849SBarry Smith Collective on dm 10057795646SDave May 101d3a51819SDave May Input parameters: 10262741f57SDave May + dm - a DMSwarm 10362741f57SDave May - fieldname - the textual name given to a registered field 10457795646SDave May 105d3a51819SDave May Level: beginner 10657795646SDave May 107d3a51819SDave May Notes: 108e7af74c8SDave May 10962741f57SDave May The field with name fieldname must be defined as having a data type of PetscScalar. 110e7af74c8SDave May 111d3a51819SDave May This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector(). 112d3a51819SDave May Mutiple calls to DMSwarmVectorDefineField() are permitted. 11357795646SDave May 1148b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector() 115d3a51819SDave May @*/ 11674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[]) 117b5bcf523SDave May { 118b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 119b5bcf523SDave May PetscErrorCode ierr; 120b5bcf523SDave May PetscInt bs,n; 121b5bcf523SDave May PetscScalar *array; 122b5bcf523SDave May PetscDataType type; 123b5bcf523SDave May 124a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1253454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 12677048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 127b5bcf523SDave May ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 128b5bcf523SDave May 129b5bcf523SDave May /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 130b5bcf523SDave May if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 131521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr); 132b5bcf523SDave May swarm->vec_field_set = PETSC_TRUE; 1331b1ea282SDave May swarm->vec_field_bs = bs; 134b5bcf523SDave May swarm->vec_field_nlocal = n; 135dcf43ee8SDave May ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 136b5bcf523SDave May PetscFunctionReturn(0); 137b5bcf523SDave May } 138b5bcf523SDave May 139cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */ 140b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec) 141b5bcf523SDave May { 142b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 143b5bcf523SDave May PetscErrorCode ierr; 144b5bcf523SDave May Vec x; 145b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 146b5bcf523SDave May 147a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1483454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 149b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 150cc651181SDave 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 */ 151cc651181SDave May 152521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 153b5bcf523SDave May ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr); 154b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 1551b1ea282SDave May ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 156b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 157c6b011d8SStefano Zampini ierr = VecSetDM(x,dm);CHKERRQ(ierr); 158b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 15974d0cae8SMatthew G. Knepley ierr = VecSetDM(x, dm);CHKERRQ(ierr); 16074d0cae8SMatthew G. Knepley ierr = VecSetOperation(x, VECOP_VIEW, (void (*)(void)) VecView_Swarm);CHKERRQ(ierr); 161b5bcf523SDave May *vec = x; 162b5bcf523SDave May PetscFunctionReturn(0); 163b5bcf523SDave May } 164b5bcf523SDave May 165b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */ 166b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec) 167b5bcf523SDave May { 168b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 169b5bcf523SDave May PetscErrorCode ierr; 170b5bcf523SDave May Vec x; 171b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 172b5bcf523SDave May 173a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1743454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 175b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 176cc651181SDave 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 */ 177cc651181SDave May 178521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 179b5bcf523SDave May ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr); 180b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 181071900c8SMatthew G. Knepley ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 182b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 183c6b011d8SStefano Zampini ierr = VecSetDM(x,dm);CHKERRQ(ierr); 184b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 185b5bcf523SDave May *vec = x; 186b5bcf523SDave May PetscFunctionReturn(0); 187b5bcf523SDave May } 188b5bcf523SDave May 189fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec) 190fb1bcc12SMatthew G. Knepley { 191fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 19277048351SPatrick Sanan DMSwarmDataField gfield; 193fb1bcc12SMatthew G. Knepley void (*fptr)(void); 194fb1bcc12SMatthew G. Knepley PetscInt bs, nlocal; 195fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 196fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 197d3a51819SDave May 198fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 199fb1bcc12SMatthew G. Knepley ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr); 200fb1bcc12SMatthew G. Knepley ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr); 201fb1bcc12SMatthew 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 */ 20277048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr); 203fb1bcc12SMatthew G. Knepley /* check vector is an inplace array */ 204521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 205fb1bcc12SMatthew G. Knepley ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr); 206fb1bcc12SMatthew G. Knepley if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname); 20777048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 208fb1bcc12SMatthew G. Knepley ierr = VecDestroy(vec);CHKERRQ(ierr); 209fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 210fb1bcc12SMatthew G. Knepley } 211fb1bcc12SMatthew G. Knepley 212fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec) 213fb1bcc12SMatthew G. Knepley { 214fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 215fb1bcc12SMatthew G. Knepley PetscDataType type; 216fb1bcc12SMatthew G. Knepley PetscScalar *array; 217fb1bcc12SMatthew G. Knepley PetscInt bs, n; 218fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 219e4fbd051SBarry Smith PetscMPIInt size; 220fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 221fb1bcc12SMatthew G. Knepley 222fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 223fb1bcc12SMatthew G. Knepley if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 22477048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr); 225fb1bcc12SMatthew G. Knepley ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr); 226fb1bcc12SMatthew G. Knepley if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL"); 227fb1bcc12SMatthew G. Knepley 228ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 229e4fbd051SBarry Smith if (size == 1) { 230fb1bcc12SMatthew G. Knepley ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr); 231fb1bcc12SMatthew G. Knepley } else { 232fb1bcc12SMatthew G. Knepley ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr); 233fb1bcc12SMatthew G. Knepley } 234fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr); 235fb1bcc12SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr); 236fb1bcc12SMatthew G. Knepley 237fb1bcc12SMatthew G. Knepley /* Set guard */ 238fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 239fb1bcc12SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr); 24074d0cae8SMatthew G. Knepley 24174d0cae8SMatthew G. Knepley ierr = VecSetDM(*vec, dm);CHKERRQ(ierr); 24274d0cae8SMatthew G. Knepley ierr = VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Swarm);CHKERRQ(ierr); 243fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 244fb1bcc12SMatthew G. Knepley } 245fb1bcc12SMatthew G. Knepley 2460643ed39SMatthew G. Knepley /* This creates a "mass matrix" between a finite element and particle space. If a finite element interpolant is given by 2470643ed39SMatthew G. Knepley 2480643ed39SMatthew G. Knepley \hat f = \sum_i f_i \phi_i 2490643ed39SMatthew G. Knepley 2500643ed39SMatthew G. Knepley and a particle function is given by 2510643ed39SMatthew G. Knepley 2520643ed39SMatthew G. Knepley f = \sum_i w_i \delta(x - x_i) 2530643ed39SMatthew G. Knepley 2540643ed39SMatthew G. Knepley then we want to require that 2550643ed39SMatthew G. Knepley 2560643ed39SMatthew G. Knepley M \hat f = M_p f 2570643ed39SMatthew G. Knepley 2580643ed39SMatthew G. Knepley where the particle mass matrix is given by 2590643ed39SMatthew G. Knepley 2600643ed39SMatthew G. Knepley (M_p)_{ij} = \int \phi_i \delta(x - x_j) 2610643ed39SMatthew G. Knepley 2620643ed39SMatthew G. Knepley The way Dave May does particles, they amount to quadratue weights rather than delta functions, so he has |J| is in 2630643ed39SMatthew G. Knepley his integral. We allow this with the boolean flag. 2640643ed39SMatthew G. Knepley */ 2650643ed39SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrix_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 26683c47955SMatthew G. Knepley { 26783c47955SMatthew G. Knepley const char *name = "Mass Matrix"; 2680643ed39SMatthew G. Knepley MPI_Comm comm; 26983c47955SMatthew G. Knepley PetscDS prob; 27083c47955SMatthew G. Knepley PetscSection fsection, globalFSection; 271e8f14785SLisandro Dalcin PetscHSetIJ ht; 2720643ed39SMatthew G. Knepley PetscLayout rLayout, colLayout; 27383c47955SMatthew G. Knepley PetscInt *dnz, *onz; 274adb2528bSMark Adams PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 2750643ed39SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 27683c47955SMatthew G. Knepley PetscScalar *elemMat; 2770643ed39SMatthew G. Knepley PetscInt dim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 27883c47955SMatthew G. Knepley PetscErrorCode ierr; 27983c47955SMatthew G. Knepley 28083c47955SMatthew G. Knepley PetscFunctionBegin; 2810643ed39SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr); 28283c47955SMatthew G. Knepley ierr = DMGetCoordinateDim(dmf, &dim);CHKERRQ(ierr); 28383c47955SMatthew G. Knepley ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr); 28483c47955SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 2850643ed39SMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 28683c47955SMatthew G. Knepley ierr = PetscMalloc3(dim, &v0, dim*dim, &J, dim*dim,&invJ);CHKERRQ(ierr); 28792fd8e1eSJed Brown ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr); 288e87a4003SBarry Smith ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr); 28983c47955SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr); 2900643ed39SMatthew G. Knepley ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr); 29183c47955SMatthew G. Knepley 2920643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr); 2930643ed39SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr); 2940643ed39SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr); 2950643ed39SMatthew G. Knepley ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr); 2960643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr); 2970643ed39SMatthew G. Knepley ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr); 2980643ed39SMatthew G. Knepley 2990643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 30083c47955SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 30183c47955SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 30283c47955SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 3030643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr); 30483c47955SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 3050643ed39SMatthew G. Knepley 30683c47955SMatthew G. Knepley ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr); 307e8f14785SLisandro Dalcin ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr); 30853e60ab4SJoseph Pusztay 3090643ed39SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 3100643ed39SMatthew G. Knepley /* count non-zeros */ 3110643ed39SMatthew G. Knepley ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr); 31283c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 31383c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 3140643ed39SMatthew G. Knepley PetscInt c, i; 3150643ed39SMatthew G. Knepley PetscInt *findices, *cindices; /* fine is vertices, coarse is particles */ 31683c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 31783c47955SMatthew G. Knepley 31871f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 319fc7c92abSMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 320fc7c92abSMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 32183c47955SMatthew G. Knepley { 322e8f14785SLisandro Dalcin PetscHashIJKey key; 323e8f14785SLisandro Dalcin PetscBool missing; 32483c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 325adb2528bSMark Adams key.j = findices[i]; /* global column (from Plex) */ 326adb2528bSMark Adams if (key.j >= 0) { 32783c47955SMatthew G. Knepley /* Get indices for coarse elements */ 32883c47955SMatthew G. Knepley for (c = 0; c < numCIndices; ++c) { 329adb2528bSMark Adams key.i = cindices[c] + rStart; /* global cols (from Swarm) */ 330adb2528bSMark Adams if (key.i < 0) continue; 331e8f14785SLisandro Dalcin ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 33283c47955SMatthew G. Knepley if (missing) { 3330643ed39SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 334e8f14785SLisandro Dalcin else ++onz[key.i - rStart]; 3350643ed39SMatthew G. Knepley } else SETERRQ2(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %D,%D", key.i, key.j); 33683c47955SMatthew G. Knepley } 337fc7c92abSMatthew G. Knepley } 338fc7c92abSMatthew G. Knepley } 33983c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 34083c47955SMatthew G. Knepley } 34171f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 34283c47955SMatthew G. Knepley } 34383c47955SMatthew G. Knepley } 344e8f14785SLisandro Dalcin ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 34583c47955SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 34683c47955SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 34783c47955SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 348adb2528bSMark Adams ierr = PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi);CHKERRQ(ierr); 34983c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 350ef0bb6c7SMatthew G. Knepley PetscTabulation Tcoarse; 35183c47955SMatthew G. Knepley PetscObject obj; 352ef0bb6c7SMatthew G. Knepley PetscReal *coords; 3530643ed39SMatthew G. Knepley PetscInt Nc, i; 35483c47955SMatthew G. Knepley 35583c47955SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 3560643ed39SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 3570643ed39SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 3580643ed39SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 35983c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 36083c47955SMatthew G. Knepley PetscInt *findices , *cindices; 36183c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 3620643ed39SMatthew G. Knepley PetscInt p, c; 36383c47955SMatthew G. Knepley 3640643ed39SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 36583c47955SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 36671f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 36783c47955SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 3680643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3690643ed39SMatthew G. Knepley CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]); 3700643ed39SMatthew G. Knepley } 371ef0bb6c7SMatthew G. Knepley ierr = PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse);CHKERRQ(ierr); 37283c47955SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 373580bdb30SBarry Smith ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr); 37483c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 3750643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3760643ed39SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 3770643ed39SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 378ef0bb6c7SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 37983c47955SMatthew G. Knepley } 3800643ed39SMatthew G. Knepley } 3810643ed39SMatthew G. Knepley } 382adb2528bSMark Adams for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 38383c47955SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 384adb2528bSMark Adams ierr = MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES);CHKERRQ(ierr); 38583c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 38671f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 387ef0bb6c7SMatthew G. Knepley ierr = PetscTabulationDestroy(&Tcoarse);CHKERRQ(ierr); 38883c47955SMatthew G. Knepley } 3890643ed39SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 39083c47955SMatthew G. Knepley } 391adb2528bSMark Adams ierr = PetscFree3(elemMat, rowIDXs, xi);CHKERRQ(ierr); 39283c47955SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 39383c47955SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 39483c47955SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 39583c47955SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 39683c47955SMatthew G. Knepley PetscFunctionReturn(0); 39783c47955SMatthew G. Knepley } 39883c47955SMatthew G. Knepley 399d0c080abSJoseph Pusztay /* Returns empty matrix for use with SNES FD */ 40070a7d78aSStefano Zampini static PetscErrorCode DMCreateMatrix_Swarm(DM sw, Mat* m) 40170a7d78aSStefano Zampini { 402d0c080abSJoseph Pusztay Vec field; 403d0c080abSJoseph Pusztay PetscInt size; 404d0c080abSJoseph Pusztay PetscErrorCode ierr; 405d0c080abSJoseph Pusztay 406d0c080abSJoseph Pusztay PetscFunctionBegin; 407d0c080abSJoseph Pusztay ierr = DMGetGlobalVector(sw, &field);CHKERRQ(ierr); 408d0c080abSJoseph Pusztay ierr = VecGetLocalSize(field, &size);CHKERRQ(ierr); 409d0c080abSJoseph Pusztay ierr = DMRestoreGlobalVector(sw, &field);CHKERRQ(ierr); 410d0c080abSJoseph Pusztay ierr = MatCreate(PETSC_COMM_WORLD, m);CHKERRQ(ierr); 411d0c080abSJoseph Pusztay ierr = MatSetFromOptions(*m);CHKERRQ(ierr); 4121e1ea65dSPierre Jolivet ierr = MatSetSizes(*m, PETSC_DECIDE, PETSC_DECIDE, size, size);CHKERRQ(ierr); 413d0c080abSJoseph Pusztay ierr = MatSeqAIJSetPreallocation(*m, 1, NULL);CHKERRQ(ierr); 414d0c080abSJoseph Pusztay ierr = MatZeroEntries(*m);CHKERRQ(ierr); 415d0c080abSJoseph Pusztay ierr = MatAssemblyBegin(*m, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 416d0c080abSJoseph Pusztay ierr = MatAssemblyEnd(*m, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 417d0c080abSJoseph Pusztay ierr = MatShift(*m, 1.0);CHKERRQ(ierr); 418d0c080abSJoseph Pusztay ierr = MatSetDM(*m, sw);CHKERRQ(ierr); 419d0c080abSJoseph Pusztay PetscFunctionReturn(0); 420d0c080abSJoseph Pusztay } 421d0c080abSJoseph Pusztay 422adb2528bSMark Adams /* FEM cols, Particle rows */ 42383c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass) 42483c47955SMatthew G. Knepley { 425895a1698SMatthew G. Knepley PetscSection gsf; 42683c47955SMatthew G. Knepley PetscInt m, n; 42783c47955SMatthew G. Knepley void *ctx; 42883c47955SMatthew G. Knepley PetscErrorCode ierr; 42983c47955SMatthew G. Knepley 43083c47955SMatthew G. Knepley PetscFunctionBegin; 431e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 43283c47955SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 433895a1698SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 43483c47955SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 435adb2528bSMark Adams ierr = MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 43683c47955SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 43783c47955SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 43883c47955SMatthew G. Knepley 4390643ed39SMatthew G. Knepley ierr = DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 44083c47955SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 44183c47955SMatthew G. Knepley PetscFunctionReturn(0); 44283c47955SMatthew G. Knepley } 44383c47955SMatthew G. Knepley 4444cc7f7b2SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrixSquare_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 4454cc7f7b2SMatthew G. Knepley { 4464cc7f7b2SMatthew G. Knepley const char *name = "Mass Matrix Square"; 4474cc7f7b2SMatthew G. Knepley MPI_Comm comm; 4484cc7f7b2SMatthew G. Knepley PetscDS prob; 4494cc7f7b2SMatthew G. Knepley PetscSection fsection, globalFSection; 4504cc7f7b2SMatthew G. Knepley PetscHSetIJ ht; 4514cc7f7b2SMatthew G. Knepley PetscLayout rLayout, colLayout; 4524cc7f7b2SMatthew G. Knepley PetscInt *dnz, *onz, *adj, depth, maxConeSize, maxSupportSize, maxAdjSize; 4534cc7f7b2SMatthew G. Knepley PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 4544cc7f7b2SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 4554cc7f7b2SMatthew G. Knepley PetscScalar *elemMat, *elemMatSq; 4564cc7f7b2SMatthew G. Knepley PetscInt cdim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 4574cc7f7b2SMatthew G. Knepley PetscErrorCode ierr; 4584cc7f7b2SMatthew G. Knepley 4594cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 4604cc7f7b2SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr); 4614cc7f7b2SMatthew G. Knepley ierr = DMGetCoordinateDim(dmf, &cdim);CHKERRQ(ierr); 4624cc7f7b2SMatthew G. Knepley ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr); 4634cc7f7b2SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 4644cc7f7b2SMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 4654cc7f7b2SMatthew G. Knepley ierr = PetscMalloc3(cdim, &v0, cdim*cdim, &J, cdim*cdim,&invJ);CHKERRQ(ierr); 4664cc7f7b2SMatthew G. Knepley ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr); 4674cc7f7b2SMatthew G. Knepley ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr); 4684cc7f7b2SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr); 4694cc7f7b2SMatthew G. Knepley ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr); 4704cc7f7b2SMatthew G. Knepley 4714cc7f7b2SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr); 4724cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr); 4734cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr); 4744cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr); 4754cc7f7b2SMatthew G. Knepley ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr); 4764cc7f7b2SMatthew G. Knepley ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr); 4774cc7f7b2SMatthew G. Knepley 4784cc7f7b2SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 4794cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 4804cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 4814cc7f7b2SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 4824cc7f7b2SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr); 4834cc7f7b2SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 4844cc7f7b2SMatthew G. Knepley 4854cc7f7b2SMatthew G. Knepley ierr = DMPlexGetDepth(dmf, &depth);CHKERRQ(ierr); 4864cc7f7b2SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dmf, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 4874cc7f7b2SMatthew G. Knepley maxAdjSize = PetscPowInt(maxConeSize*maxSupportSize, depth); 4884cc7f7b2SMatthew G. Knepley ierr = PetscMalloc1(maxAdjSize, &adj);CHKERRQ(ierr); 4894cc7f7b2SMatthew G. Knepley 4904cc7f7b2SMatthew G. Knepley ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr); 4914cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr); 4924cc7f7b2SMatthew G. Knepley /* Count nonzeros 4934cc7f7b2SMatthew G. Knepley This is just FVM++, but we cannot use the Plex P0 allocation since unknowns in a cell will not be contiguous 4944cc7f7b2SMatthew G. Knepley */ 4954cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr); 4964cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 4974cc7f7b2SMatthew G. Knepley PetscInt i; 4984cc7f7b2SMatthew G. Knepley PetscInt *cindices; 4994cc7f7b2SMatthew G. Knepley PetscInt numCIndices; 5004cc7f7b2SMatthew G. Knepley #if 0 5014cc7f7b2SMatthew G. Knepley PetscInt adjSize = maxAdjSize, a, j; 5024cc7f7b2SMatthew G. Knepley #endif 5034cc7f7b2SMatthew G. Knepley 5044cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 5054cc7f7b2SMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 5064cc7f7b2SMatthew G. Knepley /* Diagonal block */ 5074cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) {dnz[cindices[i]] += numCIndices;} 5084cc7f7b2SMatthew G. Knepley #if 0 5094cc7f7b2SMatthew G. Knepley /* Off-diagonal blocks */ 5104cc7f7b2SMatthew G. Knepley ierr = DMPlexGetAdjacency(dmf, cell, &adjSize, &adj);CHKERRQ(ierr); 5114cc7f7b2SMatthew G. Knepley for (a = 0; a < adjSize; ++a) { 5124cc7f7b2SMatthew G. Knepley if (adj[a] >= cStart && adj[a] < cEnd && adj[a] != cell) { 5134cc7f7b2SMatthew G. Knepley const PetscInt ncell = adj[a]; 5144cc7f7b2SMatthew G. Knepley PetscInt *ncindices; 5154cc7f7b2SMatthew G. Knepley PetscInt numNCIndices; 5164cc7f7b2SMatthew G. Knepley 5174cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, ncell, &numNCIndices, &ncindices);CHKERRQ(ierr); 5184cc7f7b2SMatthew G. Knepley { 5194cc7f7b2SMatthew G. Knepley PetscHashIJKey key; 5204cc7f7b2SMatthew G. Knepley PetscBool missing; 5214cc7f7b2SMatthew G. Knepley 5224cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) { 5234cc7f7b2SMatthew G. Knepley key.i = cindices[i] + rStart; /* global rows (from Swarm) */ 5244cc7f7b2SMatthew G. Knepley if (key.i < 0) continue; 5254cc7f7b2SMatthew G. Knepley for (j = 0; j < numNCIndices; ++j) { 5264cc7f7b2SMatthew G. Knepley key.j = ncindices[j] + rStart; /* global column (from Swarm) */ 5274cc7f7b2SMatthew G. Knepley if (key.j < 0) continue; 5284cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 5294cc7f7b2SMatthew G. Knepley if (missing) { 5304cc7f7b2SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 5314cc7f7b2SMatthew G. Knepley else ++onz[key.i - rStart]; 5324cc7f7b2SMatthew G. Knepley } 5334cc7f7b2SMatthew G. Knepley } 5344cc7f7b2SMatthew G. Knepley } 5354cc7f7b2SMatthew G. Knepley } 5364cc7f7b2SMatthew G. Knepley ierr = PetscFree(ncindices);CHKERRQ(ierr); 5374cc7f7b2SMatthew G. Knepley } 5384cc7f7b2SMatthew G. Knepley } 5394cc7f7b2SMatthew G. Knepley #endif 5404cc7f7b2SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 5414cc7f7b2SMatthew G. Knepley } 5424cc7f7b2SMatthew G. Knepley ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 5434cc7f7b2SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 5444cc7f7b2SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 5454cc7f7b2SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 5464cc7f7b2SMatthew G. Knepley ierr = PetscMalloc4(maxC*totDim, &elemMat, maxC*maxC, &elemMatSq, maxC, &rowIDXs, maxC*cdim, &xi);CHKERRQ(ierr); 5474cc7f7b2SMatthew G. Knepley /* Fill in values 5484cc7f7b2SMatthew G. Knepley Each entry is a sum of terms \phi_i(x_p) \phi_i(x_q) 5494cc7f7b2SMatthew G. Knepley Start just by producing block diagonal 5504cc7f7b2SMatthew G. Knepley Could loop over adjacent cells 5514cc7f7b2SMatthew G. Knepley Produce neighboring element matrix 5524cc7f7b2SMatthew G. Knepley TODO Determine which columns and rows correspond to shared dual vector 5534cc7f7b2SMatthew G. Knepley Do MatMatMult with rectangular matrices 5544cc7f7b2SMatthew G. Knepley Insert block 5554cc7f7b2SMatthew G. Knepley */ 5564cc7f7b2SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 5574cc7f7b2SMatthew G. Knepley PetscTabulation Tcoarse; 5584cc7f7b2SMatthew G. Knepley PetscObject obj; 5594cc7f7b2SMatthew G. Knepley PetscReal *coords; 5604cc7f7b2SMatthew G. Knepley PetscInt Nc, i; 5614cc7f7b2SMatthew G. Knepley 5624cc7f7b2SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 5634cc7f7b2SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 5644cc7f7b2SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 5654cc7f7b2SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 5664cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 5674cc7f7b2SMatthew G. Knepley PetscInt *findices , *cindices; 5684cc7f7b2SMatthew G. Knepley PetscInt numFIndices, numCIndices; 5694cc7f7b2SMatthew G. Knepley PetscInt p, c; 5704cc7f7b2SMatthew G. Knepley 5714cc7f7b2SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 5724cc7f7b2SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 5734cc7f7b2SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 5744cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 5754cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 5764cc7f7b2SMatthew G. Knepley CoordinatesRealToRef(cdim, cdim, v0ref, v0, invJ, &coords[cindices[p]*cdim], &xi[p*cdim]); 5774cc7f7b2SMatthew G. Knepley } 5784cc7f7b2SMatthew G. Knepley ierr = PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse);CHKERRQ(ierr); 5794cc7f7b2SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 5804cc7f7b2SMatthew G. Knepley ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr); 5814cc7f7b2SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 5824cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 5834cc7f7b2SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 5844cc7f7b2SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 5854cc7f7b2SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 5864cc7f7b2SMatthew G. Knepley } 5874cc7f7b2SMatthew G. Knepley } 5884cc7f7b2SMatthew G. Knepley } 5894cc7f7b2SMatthew G. Knepley ierr = PetscTabulationDestroy(&Tcoarse);CHKERRQ(ierr); 5904cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 5914cc7f7b2SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 5924cc7f7b2SMatthew G. Knepley /* Block diagonal */ 59378884ca7SMatthew G. Knepley if (numCIndices) { 5944cc7f7b2SMatthew G. Knepley PetscBLASInt blasn, blask; 5954cc7f7b2SMatthew G. Knepley PetscScalar one = 1.0, zero = 0.0; 5964cc7f7b2SMatthew G. Knepley 5974cc7f7b2SMatthew G. Knepley ierr = PetscBLASIntCast(numCIndices, &blasn);CHKERRQ(ierr); 5984cc7f7b2SMatthew G. Knepley ierr = PetscBLASIntCast(numFIndices, &blask);CHKERRQ(ierr); 5994cc7f7b2SMatthew G. Knepley PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&blasn,&blasn,&blask,&one,elemMat,&blask,elemMat,&blask,&zero,elemMatSq,&blasn)); 6004cc7f7b2SMatthew G. Knepley } 6014cc7f7b2SMatthew G. Knepley ierr = MatSetValues(mass, numCIndices, rowIDXs, numCIndices, rowIDXs, elemMatSq, ADD_VALUES);CHKERRQ(ierr); 6024cc7f7b2SMatthew G. Knepley /* TODO Off-diagonal */ 6034cc7f7b2SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 6044cc7f7b2SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL);CHKERRQ(ierr); 6054cc7f7b2SMatthew G. Knepley } 6064cc7f7b2SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 6074cc7f7b2SMatthew G. Knepley } 6084cc7f7b2SMatthew G. Knepley ierr = PetscFree4(elemMat, elemMatSq, rowIDXs, xi);CHKERRQ(ierr); 6094cc7f7b2SMatthew G. Knepley ierr = PetscFree(adj);CHKERRQ(ierr); 6104cc7f7b2SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 6114cc7f7b2SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 6124cc7f7b2SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6134cc7f7b2SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6144cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 6154cc7f7b2SMatthew G. Knepley } 6164cc7f7b2SMatthew G. Knepley 6174cc7f7b2SMatthew G. Knepley /*@C 6184cc7f7b2SMatthew G. Knepley DMSwarmCreateMassMatrixSquare - Creates the block-diagonal of the square, M^T_p M_p, of the particle mass matrix M_p 6194cc7f7b2SMatthew G. Knepley 6204cc7f7b2SMatthew G. Knepley Collective on dmCoarse 6214cc7f7b2SMatthew G. Knepley 6224cc7f7b2SMatthew G. Knepley Input parameters: 6234cc7f7b2SMatthew G. Knepley + dmCoarse - a DMSwarm 6244cc7f7b2SMatthew G. Knepley - dmFine - a DMPlex 6254cc7f7b2SMatthew G. Knepley 6264cc7f7b2SMatthew G. Knepley Output parameter: 6274cc7f7b2SMatthew G. Knepley . mass - the square of the particle mass matrix 6284cc7f7b2SMatthew G. Knepley 6294cc7f7b2SMatthew G. Knepley Level: advanced 6304cc7f7b2SMatthew G. Knepley 6314cc7f7b2SMatthew G. Knepley Notes: 6324cc7f7b2SMatthew G. Knepley We only compute the block diagonal since this provides a good preconditioner and is completely local. It would be possible in the 6334cc7f7b2SMatthew G. Knepley future to compute the full normal equations. 6344cc7f7b2SMatthew G. Knepley 6354cc7f7b2SMatthew G. Knepley .seealso: DMCreateMassMatrix() 6364cc7f7b2SMatthew G. Knepley @*/ 6374cc7f7b2SMatthew G. Knepley PetscErrorCode DMSwarmCreateMassMatrixSquare(DM dmCoarse, DM dmFine, Mat *mass) 6384cc7f7b2SMatthew G. Knepley { 6394cc7f7b2SMatthew G. Knepley PetscInt n; 6404cc7f7b2SMatthew G. Knepley void *ctx; 6414cc7f7b2SMatthew G. Knepley PetscErrorCode ierr; 6424cc7f7b2SMatthew G. Knepley 6434cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 6444cc7f7b2SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 6454cc7f7b2SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 6464cc7f7b2SMatthew G. Knepley ierr = MatSetSizes(*mass, n, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 6474cc7f7b2SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 6484cc7f7b2SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 6494cc7f7b2SMatthew G. Knepley 6504cc7f7b2SMatthew G. Knepley ierr = DMSwarmComputeMassMatrixSquare_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 6514cc7f7b2SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_sq_mat_view");CHKERRQ(ierr); 6524cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 6534cc7f7b2SMatthew G. Knepley } 6544cc7f7b2SMatthew G. Knepley 655fb1bcc12SMatthew G. Knepley /*@C 656d3a51819SDave May DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 657d3a51819SDave May 658d083f849SBarry Smith Collective on dm 659d3a51819SDave May 660d3a51819SDave May Input parameters: 66162741f57SDave May + dm - a DMSwarm 66262741f57SDave May - fieldname - the textual name given to a registered field 663d3a51819SDave May 6648b8a3813SDave May Output parameter: 665d3a51819SDave May . vec - the vector 666d3a51819SDave May 667d3a51819SDave May Level: beginner 668d3a51819SDave May 6698b8a3813SDave May Notes: 6708b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField(). 6718b8a3813SDave May 6728b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField() 673d3a51819SDave May @*/ 67474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 675b5bcf523SDave May { 676fb1bcc12SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject) dm); 677b5bcf523SDave May PetscErrorCode ierr; 678b5bcf523SDave May 679fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 680fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 681b5bcf523SDave May PetscFunctionReturn(0); 682b5bcf523SDave May } 683b5bcf523SDave May 684d3a51819SDave May /*@C 685d3a51819SDave May DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 686d3a51819SDave May 687d083f849SBarry Smith Collective on dm 688d3a51819SDave May 689d3a51819SDave May Input parameters: 69062741f57SDave May + dm - a DMSwarm 69162741f57SDave May - fieldname - the textual name given to a registered field 692d3a51819SDave May 6938b8a3813SDave May Output parameter: 694d3a51819SDave May . vec - the vector 695d3a51819SDave May 696d3a51819SDave May Level: beginner 697d3a51819SDave May 6988b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField() 699d3a51819SDave May @*/ 70074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 701b5bcf523SDave May { 702b5bcf523SDave May PetscErrorCode ierr; 703cc651181SDave May 704fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 705fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 706b5bcf523SDave May PetscFunctionReturn(0); 707b5bcf523SDave May } 708b5bcf523SDave May 709fb1bcc12SMatthew G. Knepley /*@C 710fb1bcc12SMatthew G. Knepley DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field 711fb1bcc12SMatthew G. Knepley 712d083f849SBarry Smith Collective on dm 713fb1bcc12SMatthew G. Knepley 714fb1bcc12SMatthew G. Knepley Input parameters: 71562741f57SDave May + dm - a DMSwarm 71662741f57SDave May - fieldname - the textual name given to a registered field 717fb1bcc12SMatthew G. Knepley 7188b8a3813SDave May Output parameter: 719fb1bcc12SMatthew G. Knepley . vec - the vector 720fb1bcc12SMatthew G. Knepley 721fb1bcc12SMatthew G. Knepley Level: beginner 722fb1bcc12SMatthew G. Knepley 7238b8a3813SDave May Notes: 7248b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField(). 7258b8a3813SDave May 7268b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField() 727fb1bcc12SMatthew G. Knepley @*/ 72874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 729bbe8250bSMatthew G. Knepley { 730fb1bcc12SMatthew G. Knepley MPI_Comm comm = PETSC_COMM_SELF; 731bbe8250bSMatthew G. Knepley PetscErrorCode ierr; 732bbe8250bSMatthew G. Knepley 733fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 734fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 735fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 736bbe8250bSMatthew G. Knepley } 737fb1bcc12SMatthew G. Knepley 738fb1bcc12SMatthew G. Knepley /*@C 739fb1bcc12SMatthew G. Knepley DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field 740fb1bcc12SMatthew G. Knepley 741d083f849SBarry Smith Collective on dm 742fb1bcc12SMatthew G. Knepley 743fb1bcc12SMatthew G. Knepley Input parameters: 74462741f57SDave May + dm - a DMSwarm 74562741f57SDave May - fieldname - the textual name given to a registered field 746fb1bcc12SMatthew G. Knepley 7478b8a3813SDave May Output parameter: 748fb1bcc12SMatthew G. Knepley . vec - the vector 749fb1bcc12SMatthew G. Knepley 750fb1bcc12SMatthew G. Knepley Level: beginner 751fb1bcc12SMatthew G. Knepley 7528b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField() 753fb1bcc12SMatthew G. Knepley @*/ 75474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 755fb1bcc12SMatthew G. Knepley { 756fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 757fb1bcc12SMatthew G. Knepley 758fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 759fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 760bbe8250bSMatthew G. Knepley PetscFunctionReturn(0); 761bbe8250bSMatthew G. Knepley } 762bbe8250bSMatthew G. Knepley 763b5bcf523SDave May /* 76474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec) 765b5bcf523SDave May { 766b5bcf523SDave May PetscFunctionReturn(0); 767b5bcf523SDave May } 768b5bcf523SDave May 76974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec) 770b5bcf523SDave May { 771b5bcf523SDave May PetscFunctionReturn(0); 772b5bcf523SDave May } 773b5bcf523SDave May */ 774b5bcf523SDave May 775d3a51819SDave May /*@C 776d3a51819SDave May DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 777d3a51819SDave May 778d083f849SBarry Smith Collective on dm 779d3a51819SDave May 780d3a51819SDave May Input parameter: 781d3a51819SDave May . dm - a DMSwarm 782d3a51819SDave May 783d3a51819SDave May Level: beginner 784d3a51819SDave May 785d3a51819SDave May Notes: 7868b8a3813SDave May After all fields have been registered, you must call DMSwarmFinalizeFieldRegister(). 787d3a51819SDave May 788d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 789d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 790d3a51819SDave May @*/ 79174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 7925f50eb2eSDave May { 7935f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *) dm->data; 7943454631fSDave May PetscErrorCode ierr; 7953454631fSDave May 796521f74f9SMatthew G. Knepley PetscFunctionBegin; 797cc651181SDave May if (!swarm->field_registration_initialized) { 7985f50eb2eSDave May swarm->field_registration_initialized = PETSC_TRUE; 79943f984edSMatthew G. Knepley ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_INT64);CHKERRQ(ierr); /* unique identifer */ 800f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */ 801cc651181SDave May } 8025f50eb2eSDave May PetscFunctionReturn(0); 8035f50eb2eSDave May } 8045f50eb2eSDave May 80574d0cae8SMatthew G. Knepley /*@ 806d3a51819SDave May DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 807d3a51819SDave May 808d083f849SBarry Smith Collective on dm 809d3a51819SDave May 810d3a51819SDave May Input parameter: 811d3a51819SDave May . dm - a DMSwarm 812d3a51819SDave May 813d3a51819SDave May Level: beginner 814d3a51819SDave May 815d3a51819SDave May Notes: 81662741f57SDave May After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm. 817d3a51819SDave May 818d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 819d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 820d3a51819SDave May @*/ 82174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 8225f50eb2eSDave May { 8235f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8246845f8f5SDave May PetscErrorCode ierr; 8256845f8f5SDave May 826521f74f9SMatthew G. Knepley PetscFunctionBegin; 827f0cdbbbaSDave May if (!swarm->field_registration_finalized) { 82877048351SPatrick Sanan ierr = DMSwarmDataBucketFinalize(swarm->db);CHKERRQ(ierr); 829f0cdbbbaSDave May } 830f0cdbbbaSDave May swarm->field_registration_finalized = PETSC_TRUE; 8315f50eb2eSDave May PetscFunctionReturn(0); 8325f50eb2eSDave May } 8335f50eb2eSDave May 83474d0cae8SMatthew G. Knepley /*@ 835d3a51819SDave May DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 836d3a51819SDave May 837d3a51819SDave May Not collective 838d3a51819SDave May 839d3a51819SDave May Input parameters: 84062741f57SDave May + dm - a DMSwarm 841d3a51819SDave May . nlocal - the length of each registered field 84262741f57SDave May - buffer - the length of the buffer used to efficient dynamic re-sizing 843d3a51819SDave May 844d3a51819SDave May Level: beginner 845d3a51819SDave May 846d3a51819SDave May .seealso: DMSwarmGetLocalSize() 847d3a51819SDave May @*/ 84874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 8495f50eb2eSDave May { 8505f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8516845f8f5SDave May PetscErrorCode ierr; 8525f50eb2eSDave May 853521f74f9SMatthew G. Knepley PetscFunctionBegin; 854f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 85577048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr); 856f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 8575f50eb2eSDave May PetscFunctionReturn(0); 8585f50eb2eSDave May } 8595f50eb2eSDave May 86074d0cae8SMatthew G. Knepley /*@ 861d3a51819SDave May DMSwarmSetCellDM - Attachs a DM to a DMSwarm 862d3a51819SDave May 863d083f849SBarry Smith Collective on dm 864d3a51819SDave May 865d3a51819SDave May Input parameters: 86662741f57SDave May + dm - a DMSwarm 86762741f57SDave May - dmcell - the DM to attach to the DMSwarm 868d3a51819SDave May 869d3a51819SDave May Level: beginner 870d3a51819SDave May 871d3a51819SDave May Notes: 872d3a51819SDave May The attached DM (dmcell) will be queried for point location and 8738b8a3813SDave May neighbor MPI-rank information if DMSwarmMigrate() is called. 874d3a51819SDave May 8758b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate() 876d3a51819SDave May @*/ 87774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 878b16650c8SDave May { 879b16650c8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 880521f74f9SMatthew G. Knepley 881521f74f9SMatthew G. Knepley PetscFunctionBegin; 882b16650c8SDave May swarm->dmcell = dmcell; 883b16650c8SDave May PetscFunctionReturn(0); 884b16650c8SDave May } 885b16650c8SDave May 88674d0cae8SMatthew G. Knepley /*@ 887d3a51819SDave May DMSwarmGetCellDM - Fetches the attached cell DM 888d3a51819SDave May 889d083f849SBarry Smith Collective on dm 890d3a51819SDave May 891d3a51819SDave May Input parameter: 892d3a51819SDave May . dm - a DMSwarm 893d3a51819SDave May 894d3a51819SDave May Output parameter: 895d3a51819SDave May . dmcell - the DM which was attached to the DMSwarm 896d3a51819SDave May 897d3a51819SDave May Level: beginner 898d3a51819SDave May 899d3a51819SDave May .seealso: DMSwarmSetCellDM() 900d3a51819SDave May @*/ 90174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 902fe39f135SDave May { 903fe39f135SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 904521f74f9SMatthew G. Knepley 905521f74f9SMatthew G. Knepley PetscFunctionBegin; 906fe39f135SDave May *dmcell = swarm->dmcell; 907fe39f135SDave May PetscFunctionReturn(0); 908fe39f135SDave May } 909fe39f135SDave May 91074d0cae8SMatthew G. Knepley /*@ 911d3a51819SDave May DMSwarmGetLocalSize - Retrives the local length of fields registered 912d3a51819SDave May 913d3a51819SDave May Not collective 914d3a51819SDave May 915d3a51819SDave May Input parameter: 916d3a51819SDave May . dm - a DMSwarm 917d3a51819SDave May 918d3a51819SDave May Output parameter: 919d3a51819SDave May . nlocal - the length of each registered field 920d3a51819SDave May 921d3a51819SDave May Level: beginner 922d3a51819SDave May 9238b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes() 924d3a51819SDave May @*/ 92574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 926dcf43ee8SDave May { 927dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 928dcf43ee8SDave May PetscErrorCode ierr; 929dcf43ee8SDave May 930521f74f9SMatthew G. Knepley PetscFunctionBegin; 93177048351SPatrick Sanan if (nlocal) {ierr = DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);} 932dcf43ee8SDave May PetscFunctionReturn(0); 933dcf43ee8SDave May } 934dcf43ee8SDave May 93574d0cae8SMatthew G. Knepley /*@ 936d3a51819SDave May DMSwarmGetSize - Retrives the total length of fields registered 937d3a51819SDave May 938d083f849SBarry Smith Collective on dm 939d3a51819SDave May 940d3a51819SDave May Input parameter: 941d3a51819SDave May . dm - a DMSwarm 942d3a51819SDave May 943d3a51819SDave May Output parameter: 944d3a51819SDave May . n - the total length of each registered field 945d3a51819SDave May 946d3a51819SDave May Level: beginner 947d3a51819SDave May 948d3a51819SDave May Note: 949d3a51819SDave May This calls MPI_Allreduce upon each call (inefficient but safe) 950d3a51819SDave May 9518b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes() 952d3a51819SDave May @*/ 95374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 954dcf43ee8SDave May { 955dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 956dcf43ee8SDave May PetscErrorCode ierr; 957dcf43ee8SDave May PetscInt nlocal,ng; 958dcf43ee8SDave May 959521f74f9SMatthew G. Knepley PetscFunctionBegin; 96077048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 961ffc4695bSBarry Smith ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 962dcf43ee8SDave May if (n) { *n = ng; } 963dcf43ee8SDave May PetscFunctionReturn(0); 964dcf43ee8SDave May } 965dcf43ee8SDave May 966d3a51819SDave May /*@C 9678b8a3813SDave May DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type 968d3a51819SDave May 969d083f849SBarry Smith Collective on dm 970d3a51819SDave May 971d3a51819SDave May Input parameters: 97262741f57SDave May + dm - a DMSwarm 973d3a51819SDave May . fieldname - the textual name to identify this field 974d3a51819SDave May . blocksize - the number of each data type 97562741f57SDave May - type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 976d3a51819SDave May 977d3a51819SDave May Level: beginner 978d3a51819SDave May 979d3a51819SDave May Notes: 9808b8a3813SDave May The textual name for each registered field must be unique. 981d3a51819SDave May 982d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 983d3a51819SDave May @*/ 98474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 985b62e03f8SDave May { 9862eac95f8SDave May PetscErrorCode ierr; 987b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 988b62e03f8SDave May size_t size; 989b62e03f8SDave May 990521f74f9SMatthew G. Knepley PetscFunctionBegin; 9915f50eb2eSDave May if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 9925f50eb2eSDave May if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 9935f50eb2eSDave May 9945f50eb2eSDave May if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9955f50eb2eSDave May if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9965f50eb2eSDave May if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9975f50eb2eSDave May if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 9985f50eb2eSDave May if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 999b62e03f8SDave May 10002ddcf43eSMatthew G. Knepley ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr); 1001b62e03f8SDave May /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 100277048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 100352c3ed93SDave May { 100477048351SPatrick Sanan DMSwarmDataField gfield; 100552c3ed93SDave May 100677048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 100777048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 100852c3ed93SDave May } 1009b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 1010b62e03f8SDave May PetscFunctionReturn(0); 1011b62e03f8SDave May } 1012b62e03f8SDave May 1013d3a51819SDave May /*@C 1014d3a51819SDave May DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 1015d3a51819SDave May 1016d083f849SBarry Smith Collective on dm 1017d3a51819SDave May 1018d3a51819SDave May Input parameters: 101962741f57SDave May + dm - a DMSwarm 1020d3a51819SDave May . fieldname - the textual name to identify this field 102162741f57SDave May - size - the size in bytes of the user struct of each data type 1022d3a51819SDave May 1023d3a51819SDave May Level: beginner 1024d3a51819SDave May 1025d3a51819SDave May Notes: 10268b8a3813SDave May The textual name for each registered field must be unique. 1027d3a51819SDave May 1028d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField() 1029d3a51819SDave May @*/ 103074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 1031b62e03f8SDave May { 10322eac95f8SDave May PetscErrorCode ierr; 1033b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1034b62e03f8SDave May 1035521f74f9SMatthew G. Knepley PetscFunctionBegin; 103677048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 1037b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 1038b62e03f8SDave May PetscFunctionReturn(0); 1039b62e03f8SDave May } 1040b62e03f8SDave May 1041d3a51819SDave May /*@C 1042d3a51819SDave May DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 1043d3a51819SDave May 1044d083f849SBarry Smith Collective on dm 1045d3a51819SDave May 1046d3a51819SDave May Input parameters: 104762741f57SDave May + dm - a DMSwarm 1048d3a51819SDave May . fieldname - the textual name to identify this field 1049d3a51819SDave May . size - the size in bytes of the user data type 105062741f57SDave May - blocksize - the number of each data type 1051d3a51819SDave May 1052d3a51819SDave May Level: beginner 1053d3a51819SDave May 1054d3a51819SDave May Notes: 10558b8a3813SDave May The textual name for each registered field must be unique. 1056d3a51819SDave May 1057d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 1058d3a51819SDave May @*/ 105974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 1060b62e03f8SDave May { 1061b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 10626845f8f5SDave May PetscErrorCode ierr; 1063b62e03f8SDave May 1064521f74f9SMatthew G. Knepley PetscFunctionBegin; 106577048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 1066320740a0SDave May { 106777048351SPatrick Sanan DMSwarmDataField gfield; 1068320740a0SDave May 106977048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 107077048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 1071320740a0SDave May } 1072b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 1073b62e03f8SDave May PetscFunctionReturn(0); 1074b62e03f8SDave May } 1075b62e03f8SDave May 1076d3a51819SDave May /*@C 1077d3a51819SDave May DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 1078d3a51819SDave May 1079d3a51819SDave May Not collective 1080d3a51819SDave May 1081d3a51819SDave May Input parameters: 108262741f57SDave May + dm - a DMSwarm 108362741f57SDave May - fieldname - the textual name to identify this field 1084d3a51819SDave May 1085d3a51819SDave May Output parameters: 108662741f57SDave May + blocksize - the number of each data type 1087d3a51819SDave May . type - the data type 108862741f57SDave May - data - pointer to raw array 1089d3a51819SDave May 1090d3a51819SDave May Level: beginner 1091d3a51819SDave May 1092d3a51819SDave May Notes: 10938b8a3813SDave May The array must be returned using a matching call to DMSwarmRestoreField(). 1094d3a51819SDave May 1095d3a51819SDave May .seealso: DMSwarmRestoreField() 1096d3a51819SDave May @*/ 109774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1098b62e03f8SDave May { 1099b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 110077048351SPatrick Sanan DMSwarmDataField gfield; 11012eac95f8SDave May PetscErrorCode ierr; 1102b62e03f8SDave May 1103521f74f9SMatthew G. Knepley PetscFunctionBegin; 11043454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 110577048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 110677048351SPatrick Sanan ierr = DMSwarmDataFieldGetAccess(gfield);CHKERRQ(ierr); 110777048351SPatrick Sanan ierr = DMSwarmDataFieldGetEntries(gfield,data);CHKERRQ(ierr); 11081b1ea282SDave May if (blocksize) {*blocksize = gfield->bs; } 1109b5bcf523SDave May if (type) { *type = gfield->petsc_type; } 1110b62e03f8SDave May PetscFunctionReturn(0); 1111b62e03f8SDave May } 1112b62e03f8SDave May 1113d3a51819SDave May /*@C 1114d3a51819SDave May DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 1115d3a51819SDave May 1116d3a51819SDave May Not collective 1117d3a51819SDave May 1118d3a51819SDave May Input parameters: 111962741f57SDave May + dm - a DMSwarm 112062741f57SDave May - fieldname - the textual name to identify this field 1121d3a51819SDave May 1122d3a51819SDave May Output parameters: 112362741f57SDave May + blocksize - the number of each data type 1124d3a51819SDave May . type - the data type 112562741f57SDave May - data - pointer to raw array 1126d3a51819SDave May 1127d3a51819SDave May Level: beginner 1128d3a51819SDave May 1129d3a51819SDave May Notes: 11308b8a3813SDave May The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField(). 1131d3a51819SDave May 1132d3a51819SDave May .seealso: DMSwarmGetField() 1133d3a51819SDave May @*/ 113474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1135b62e03f8SDave May { 1136b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 113777048351SPatrick Sanan DMSwarmDataField gfield; 11382eac95f8SDave May PetscErrorCode ierr; 1139b62e03f8SDave May 1140521f74f9SMatthew G. Knepley PetscFunctionBegin; 114177048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 114277048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 1143b62e03f8SDave May if (data) *data = NULL; 1144b62e03f8SDave May PetscFunctionReturn(0); 1145b62e03f8SDave May } 1146b62e03f8SDave May 114774d0cae8SMatthew G. Knepley /*@ 1148d3a51819SDave May DMSwarmAddPoint - Add space for one new point in the DMSwarm 1149d3a51819SDave May 1150d3a51819SDave May Not collective 1151d3a51819SDave May 1152d3a51819SDave May Input parameter: 1153d3a51819SDave May . dm - a DMSwarm 1154d3a51819SDave May 1155d3a51819SDave May Level: beginner 1156d3a51819SDave May 1157d3a51819SDave May Notes: 11588b8a3813SDave May The new point will have all fields initialized to zero. 1159d3a51819SDave May 1160d3a51819SDave May .seealso: DMSwarmAddNPoints() 1161d3a51819SDave May @*/ 116274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddPoint(DM dm) 1163cb1d1399SDave May { 1164cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1165cb1d1399SDave May PetscErrorCode ierr; 1166cb1d1399SDave May 1167521f74f9SMatthew G. Knepley PetscFunctionBegin; 11683454631fSDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 1169f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 117077048351SPatrick Sanan ierr = DMSwarmDataBucketAddPoint(swarm->db);CHKERRQ(ierr); 1171f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 1172cb1d1399SDave May PetscFunctionReturn(0); 1173cb1d1399SDave May } 1174cb1d1399SDave May 117574d0cae8SMatthew G. Knepley /*@ 1176d3a51819SDave May DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 1177d3a51819SDave May 1178d3a51819SDave May Not collective 1179d3a51819SDave May 1180d3a51819SDave May Input parameters: 118162741f57SDave May + dm - a DMSwarm 118262741f57SDave May - npoints - the number of new points to add 1183d3a51819SDave May 1184d3a51819SDave May Level: beginner 1185d3a51819SDave May 1186d3a51819SDave May Notes: 11878b8a3813SDave May The new point will have all fields initialized to zero. 1188d3a51819SDave May 1189d3a51819SDave May .seealso: DMSwarmAddPoint() 1190d3a51819SDave May @*/ 119174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 1192cb1d1399SDave May { 1193cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1194cb1d1399SDave May PetscErrorCode ierr; 1195cb1d1399SDave May PetscInt nlocal; 1196cb1d1399SDave May 1197521f74f9SMatthew G. Knepley PetscFunctionBegin; 1198f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 119977048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 1200cb1d1399SDave May nlocal = nlocal + npoints; 120177048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr); 1202f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 1203cb1d1399SDave May PetscFunctionReturn(0); 1204cb1d1399SDave May } 1205cb1d1399SDave May 120674d0cae8SMatthew G. Knepley /*@ 1207d3a51819SDave May DMSwarmRemovePoint - Remove the last point from the DMSwarm 1208d3a51819SDave May 1209d3a51819SDave May Not collective 1210d3a51819SDave May 1211d3a51819SDave May Input parameter: 1212d3a51819SDave May . dm - a DMSwarm 1213d3a51819SDave May 1214d3a51819SDave May Level: beginner 1215d3a51819SDave May 1216d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex() 1217d3a51819SDave May @*/ 121874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePoint(DM dm) 1219cb1d1399SDave May { 1220cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1221cb1d1399SDave May PetscErrorCode ierr; 1222cb1d1399SDave May 1223521f74f9SMatthew G. Knepley PetscFunctionBegin; 1224f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 122577048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 1226f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 1227cb1d1399SDave May PetscFunctionReturn(0); 1228cb1d1399SDave May } 1229cb1d1399SDave May 123074d0cae8SMatthew G. Knepley /*@ 1231d3a51819SDave May DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 1232d3a51819SDave May 1233d3a51819SDave May Not collective 1234d3a51819SDave May 1235d3a51819SDave May Input parameters: 123662741f57SDave May + dm - a DMSwarm 123762741f57SDave May - idx - index of point to remove 1238d3a51819SDave May 1239d3a51819SDave May Level: beginner 1240d3a51819SDave May 1241d3a51819SDave May .seealso: DMSwarmRemovePoint() 1242d3a51819SDave May @*/ 124374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 1244cb1d1399SDave May { 1245cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1246cb1d1399SDave May PetscErrorCode ierr; 1247cb1d1399SDave May 1248521f74f9SMatthew G. Knepley PetscFunctionBegin; 1249f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 125077048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 1251f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 1252cb1d1399SDave May PetscFunctionReturn(0); 1253cb1d1399SDave May } 1254b62e03f8SDave May 125574d0cae8SMatthew G. Knepley /*@ 1256ba4fc9c6SDave May DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm 1257ba4fc9c6SDave May 1258ba4fc9c6SDave May Not collective 1259ba4fc9c6SDave May 1260ba4fc9c6SDave May Input parameters: 1261ba4fc9c6SDave May + dm - a DMSwarm 1262ba4fc9c6SDave May . pi - the index of the point to copy 1263ba4fc9c6SDave May - pj - the point index where the copy should be located 1264ba4fc9c6SDave May 1265ba4fc9c6SDave May Level: beginner 1266ba4fc9c6SDave May 1267ba4fc9c6SDave May .seealso: DMSwarmRemovePoint() 1268ba4fc9c6SDave May @*/ 126974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj) 1270ba4fc9c6SDave May { 1271ba4fc9c6SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1272ba4fc9c6SDave May PetscErrorCode ierr; 1273ba4fc9c6SDave May 1274ba4fc9c6SDave May PetscFunctionBegin; 1275ba4fc9c6SDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 127677048351SPatrick Sanan ierr = DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr); 1277ba4fc9c6SDave May PetscFunctionReturn(0); 1278ba4fc9c6SDave May } 1279ba4fc9c6SDave May 1280095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 12813454631fSDave May { 1282dcf43ee8SDave May PetscErrorCode ierr; 1283521f74f9SMatthew G. Knepley 1284521f74f9SMatthew G. Knepley PetscFunctionBegin; 1285dcf43ee8SDave May ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 12863454631fSDave May PetscFunctionReturn(0); 12873454631fSDave May } 12883454631fSDave May 128974d0cae8SMatthew G. Knepley /*@ 1290d3a51819SDave May DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 1291d3a51819SDave May 1292d083f849SBarry Smith Collective on dm 1293d3a51819SDave May 1294d3a51819SDave May Input parameters: 129562741f57SDave May + dm - the DMSwarm 129662741f57SDave May - remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 1297d3a51819SDave May 1298d3a51819SDave May Notes: 1299a5b23f4aSJose E. Roman The DM will be modified to accommodate received points. 13008b8a3813SDave May If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM. 13018b8a3813SDave May Different styles of migration are supported. See DMSwarmSetMigrateType(). 1302d3a51819SDave May 1303d3a51819SDave May Level: advanced 1304d3a51819SDave May 1305d3a51819SDave May .seealso: DMSwarmSetMigrateType() 1306d3a51819SDave May @*/ 130774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 13083454631fSDave May { 1309f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13103454631fSDave May PetscErrorCode ierr; 1311f0cdbbbaSDave May 1312521f74f9SMatthew G. Knepley PetscFunctionBegin; 1313ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 1314f0cdbbbaSDave May switch (swarm->migrate_type) { 1315f0cdbbbaSDave May case DMSWARM_MIGRATE_BASIC: 1316095059a4SDave May ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 1317f0cdbbbaSDave May break; 1318f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLNSCATTER: 1319f0cdbbbaSDave May ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 1320f0cdbbbaSDave May break; 1321f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLEXACT: 1322f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 1323f0cdbbbaSDave May case DMSWARM_MIGRATE_USER: 1324f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 1325f0cdbbbaSDave May default: 1326f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 1327f0cdbbbaSDave May } 1328ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 1329183d2d45SMatthew G. Knepley ierr = DMClearGlobalVectors(dm);CHKERRQ(ierr); 13303454631fSDave May PetscFunctionReturn(0); 13313454631fSDave May } 13323454631fSDave May 1333f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 1334f0cdbbbaSDave May 1335d3a51819SDave May /* 1336d3a51819SDave May DMSwarmCollectViewCreate 1337d3a51819SDave May 1338d3a51819SDave May * Applies a collection method and gathers point neighbour points into dm 1339d3a51819SDave May 1340d3a51819SDave May Notes: 13418b8a3813SDave May Users should call DMSwarmCollectViewDestroy() after 1342d3a51819SDave May they have finished computations associated with the collected points 1343d3a51819SDave May */ 1344d3a51819SDave May 134574d0cae8SMatthew G. Knepley /*@ 1346d3a51819SDave May DMSwarmCollectViewCreate - Applies a collection method and gathers points 1347d3a51819SDave May in neighbour MPI-ranks into the DMSwarm 1348d3a51819SDave May 1349d083f849SBarry Smith Collective on dm 1350d3a51819SDave May 1351d3a51819SDave May Input parameter: 1352d3a51819SDave May . dm - the DMSwarm 1353d3a51819SDave May 1354d3a51819SDave May Notes: 1355d3a51819SDave May Users should call DMSwarmCollectViewDestroy() after 1356d3a51819SDave May they have finished computations associated with the collected points 13578b8a3813SDave May Different collect methods are supported. See DMSwarmSetCollectType(). 1358d3a51819SDave May 1359d3a51819SDave May Level: advanced 1360d3a51819SDave May 1361d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType() 1362d3a51819SDave May @*/ 136374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewCreate(DM dm) 13642712d1f2SDave May { 13652712d1f2SDave May PetscErrorCode ierr; 13662712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13672712d1f2SDave May PetscInt ng; 13682712d1f2SDave May 1369521f74f9SMatthew G. Knepley PetscFunctionBegin; 1370480eef7bSDave May if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 1371480eef7bSDave May ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 1372480eef7bSDave May switch (swarm->collect_type) { 1373f0cdbbbaSDave May 1374480eef7bSDave May case DMSWARM_COLLECT_BASIC: 13752712d1f2SDave May ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 1376480eef7bSDave May break; 1377480eef7bSDave May case DMSWARM_COLLECT_DMDABOUNDINGBOX: 1378f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 1379480eef7bSDave May case DMSWARM_COLLECT_GENERAL: 1380f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 1381480eef7bSDave May default: 1382f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 1383480eef7bSDave May } 1384480eef7bSDave May swarm->collect_view_active = PETSC_TRUE; 1385480eef7bSDave May swarm->collect_view_reset_nlocal = ng; 13862712d1f2SDave May PetscFunctionReturn(0); 13872712d1f2SDave May } 13882712d1f2SDave May 138974d0cae8SMatthew G. Knepley /*@ 1390d3a51819SDave May DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 1391d3a51819SDave May 1392d083f849SBarry Smith Collective on dm 1393d3a51819SDave May 1394d3a51819SDave May Input parameters: 1395d3a51819SDave May . dm - the DMSwarm 1396d3a51819SDave May 1397d3a51819SDave May Notes: 1398d3a51819SDave May Users should call DMSwarmCollectViewCreate() before this function is called. 1399d3a51819SDave May 1400d3a51819SDave May Level: advanced 1401d3a51819SDave May 1402d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType() 1403d3a51819SDave May @*/ 140474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 14052712d1f2SDave May { 14062712d1f2SDave May PetscErrorCode ierr; 14072712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 14082712d1f2SDave May 1409521f74f9SMatthew G. Knepley PetscFunctionBegin; 1410480eef7bSDave May if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 1411480eef7bSDave May ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 1412480eef7bSDave May swarm->collect_view_active = PETSC_FALSE; 14132712d1f2SDave May PetscFunctionReturn(0); 14142712d1f2SDave May } 14153454631fSDave May 1416f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm) 1417f0cdbbbaSDave May { 1418f0cdbbbaSDave May PetscInt dim; 1419f0cdbbbaSDave May PetscErrorCode ierr; 1420f0cdbbbaSDave May 1421521f74f9SMatthew G. Knepley PetscFunctionBegin; 1422f0cdbbbaSDave May ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 1423f0cdbbbaSDave May if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1424f0cdbbbaSDave May if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1425f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 1426e2d107dbSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr); 1427f0cdbbbaSDave May PetscFunctionReturn(0); 1428f0cdbbbaSDave May } 1429f0cdbbbaSDave May 143074d0cae8SMatthew G. Knepley /*@ 143131403186SMatthew G. Knepley DMSwarmSetPointCoordinatesRandom - Sets initial coordinates for particles in each cell 143231403186SMatthew G. Knepley 143331403186SMatthew G. Knepley Collective on dm 143431403186SMatthew G. Knepley 143531403186SMatthew G. Knepley Input parameters: 143631403186SMatthew G. Knepley + dm - the DMSwarm 143731403186SMatthew G. Knepley - Npc - The number of particles per cell in the cell DM 143831403186SMatthew G. Knepley 143931403186SMatthew G. Knepley Notes: 144031403186SMatthew G. Knepley The user must use DMSwarmSetCellDM() to set the cell DM first. The particles are placed randomly inside each cell. If only 144131403186SMatthew G. Knepley one particle is in each cell, it is placed at the centroid. 144231403186SMatthew G. Knepley 144331403186SMatthew G. Knepley Level: intermediate 144431403186SMatthew G. Knepley 144531403186SMatthew G. Knepley .seealso: DMSwarmSetCellDM() 144631403186SMatthew G. Knepley @*/ 144731403186SMatthew G. Knepley PetscErrorCode DMSwarmSetPointCoordinatesRandom(DM dm, PetscInt Npc) 144831403186SMatthew G. Knepley { 144931403186SMatthew G. Knepley DM cdm; 145031403186SMatthew G. Knepley PetscRandom rnd; 145131403186SMatthew G. Knepley DMPolytopeType ct; 145231403186SMatthew G. Knepley PetscBool simplex; 145331403186SMatthew G. Knepley PetscReal *centroid, *coords, *xi0, *v0, *J, *invJ, detJ; 145431403186SMatthew G. Knepley PetscInt dim, d, cStart, cEnd, c, p; 145531403186SMatthew G. Knepley PetscErrorCode ierr; 145631403186SMatthew G. Knepley 145731403186SMatthew G. Knepley PetscFunctionBeginUser; 145831403186SMatthew G. Knepley ierr = PetscRandomCreate(PetscObjectComm((PetscObject) dm), &rnd);CHKERRQ(ierr); 145931403186SMatthew G. Knepley ierr = PetscRandomSetInterval(rnd, -1.0, 1.0);CHKERRQ(ierr); 146031403186SMatthew G. Knepley ierr = PetscRandomSetType(rnd, PETSCRAND48);CHKERRQ(ierr); 146131403186SMatthew G. Knepley 146231403186SMatthew G. Knepley ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 146331403186SMatthew G. Knepley ierr = DMGetDimension(cdm, &dim);CHKERRQ(ierr); 146431403186SMatthew G. Knepley ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 146531403186SMatthew G. Knepley ierr = DMPlexGetCellType(cdm, cStart, &ct);CHKERRQ(ierr); 146631403186SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 146731403186SMatthew G. Knepley 146831403186SMatthew G. Knepley ierr = PetscMalloc5(dim, ¢roid, dim, &xi0, dim, &v0, dim*dim, &J, dim*dim, &invJ);CHKERRQ(ierr); 146931403186SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0; 147031403186SMatthew G. Knepley ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 147131403186SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 147231403186SMatthew G. Knepley if (Npc == 1) { 147331403186SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(cdm, c, NULL, centroid, NULL);CHKERRQ(ierr); 147431403186SMatthew G. Knepley for (d = 0; d < dim; ++d) coords[c*dim+d] = centroid[d]; 147531403186SMatthew G. Knepley } else { 147631403186SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(cdm, c, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); /* affine */ 147731403186SMatthew G. Knepley for (p = 0; p < Npc; ++p) { 147831403186SMatthew G. Knepley const PetscInt n = c*Npc + p; 147931403186SMatthew G. Knepley PetscReal sum = 0.0, refcoords[3]; 148031403186SMatthew G. Knepley 148131403186SMatthew G. Knepley for (d = 0; d < dim; ++d) { 148231403186SMatthew G. Knepley ierr = PetscRandomGetValueReal(rnd, &refcoords[d]);CHKERRQ(ierr); 148331403186SMatthew G. Knepley sum += refcoords[d]; 148431403186SMatthew G. Knepley } 148531403186SMatthew G. Knepley if (simplex && sum > 0.0) for (d = 0; d < dim; ++d) refcoords[d] -= PetscSqrtReal(dim)*sum; 148631403186SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, refcoords, &coords[n*dim]); 148731403186SMatthew G. Knepley } 148831403186SMatthew G. Knepley } 148931403186SMatthew G. Knepley } 149031403186SMatthew G. Knepley ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 149131403186SMatthew G. Knepley ierr = PetscFree5(centroid, xi0, v0, J, invJ);CHKERRQ(ierr); 149231403186SMatthew G. Knepley ierr = PetscRandomDestroy(&rnd);CHKERRQ(ierr); 149331403186SMatthew G. Knepley PetscFunctionReturn(0); 149431403186SMatthew G. Knepley } 149531403186SMatthew G. Knepley 149631403186SMatthew G. Knepley /*@ 1497d3a51819SDave May DMSwarmSetType - Set particular flavor of DMSwarm 1498d3a51819SDave May 1499d083f849SBarry Smith Collective on dm 1500d3a51819SDave May 1501d3a51819SDave May Input parameters: 150262741f57SDave May + dm - the DMSwarm 150362741f57SDave May - stype - the DMSwarm type (e.g. DMSWARM_PIC) 1504d3a51819SDave May 1505d3a51819SDave May Level: advanced 1506d3a51819SDave May 1507d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType() 1508d3a51819SDave May @*/ 150974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 1510f0cdbbbaSDave May { 1511f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1512f0cdbbbaSDave May PetscErrorCode ierr; 1513f0cdbbbaSDave May 1514521f74f9SMatthew G. Knepley PetscFunctionBegin; 1515f0cdbbbaSDave May swarm->swarm_type = stype; 1516f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1517f0cdbbbaSDave May ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 1518f0cdbbbaSDave May } 1519f0cdbbbaSDave May PetscFunctionReturn(0); 1520f0cdbbbaSDave May } 1521f0cdbbbaSDave May 15223454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm) 15233454631fSDave May { 15243454631fSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 15253454631fSDave May PetscErrorCode ierr; 15263454631fSDave May PetscMPIInt rank; 15273454631fSDave May PetscInt p,npoints,*rankval; 15283454631fSDave May 1529521f74f9SMatthew G. Knepley PetscFunctionBegin; 15303454631fSDave May if (swarm->issetup) PetscFunctionReturn(0); 15313454631fSDave May 15323454631fSDave May swarm->issetup = PETSC_TRUE; 15333454631fSDave May 1534f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1535f0cdbbbaSDave May /* check dmcell exists */ 1536f0cdbbbaSDave May if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1537f0cdbbbaSDave May 1538f0cdbbbaSDave May if (swarm->dmcell->ops->locatepointssubdomain) { 1539f0cdbbbaSDave May /* check methods exists for exact ownership identificiation */ 154077b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr); 1541f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1542f0cdbbbaSDave May } else { 1543f0cdbbbaSDave May /* check methods exist for point location AND rank neighbor identification */ 1544f0cdbbbaSDave May if (swarm->dmcell->ops->locatepoints) { 154577b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr); 1546f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1547f0cdbbbaSDave May 1548f0cdbbbaSDave May if (swarm->dmcell->ops->getneighbors) { 154977b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr); 1550f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1551f0cdbbbaSDave May 1552f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1553f0cdbbbaSDave May } 1554f0cdbbbaSDave May } 1555f0cdbbbaSDave May 1556f0cdbbbaSDave May ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 1557f0cdbbbaSDave May 15583454631fSDave May /* check some fields were registered */ 15593454631fSDave May if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 15603454631fSDave May 15613454631fSDave May /* check local sizes were set */ 15623454631fSDave May if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 15633454631fSDave May 15643454631fSDave May /* initialize values in pid and rank placeholders */ 15653454631fSDave May /* TODO: [pid - use MPI_Scan] */ 1566ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 156777048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 1568f0cdbbbaSDave May ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 15693454631fSDave May for (p=0; p<npoints; p++) { 15703454631fSDave May rankval[p] = (PetscInt)rank; 15713454631fSDave May } 1572f0cdbbbaSDave May ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 15733454631fSDave May PetscFunctionReturn(0); 15743454631fSDave May } 15753454631fSDave May 1576dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx); 1577dc5f5ce9SDave May 157857795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm) 157957795646SDave May { 158057795646SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 158157795646SDave May PetscErrorCode ierr; 158257795646SDave May 158357795646SDave May PetscFunctionBegin; 1584d0c080abSJoseph Pusztay if (--swarm->refct > 0) PetscFunctionReturn(0); 158577048351SPatrick Sanan ierr = DMSwarmDataBucketDestroy(&swarm->db);CHKERRQ(ierr); 1586dc5f5ce9SDave May if (swarm->sort_context) { 1587dc5f5ce9SDave May ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr); 1588dc5f5ce9SDave May } 158957795646SDave May ierr = PetscFree(swarm);CHKERRQ(ierr); 159057795646SDave May PetscFunctionReturn(0); 159157795646SDave May } 159257795646SDave May 1593a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) 1594a9ee3421SMatthew G. Knepley { 1595a9ee3421SMatthew G. Knepley DM cdm; 1596a9ee3421SMatthew G. Knepley PetscDraw draw; 159731403186SMatthew G. Knepley PetscReal *coords, oldPause, radius = 0.01; 1598a9ee3421SMatthew G. Knepley PetscInt Np, p, bs; 1599a9ee3421SMatthew G. Knepley PetscErrorCode ierr; 1600a9ee3421SMatthew G. Knepley 1601a9ee3421SMatthew G. Knepley PetscFunctionBegin; 160231403186SMatthew G. Knepley ierr = PetscOptionsGetReal(NULL, ((PetscObject) dm)->prefix, "-dm_view_swarm_radius", &radius, NULL);CHKERRQ(ierr); 1603a9ee3421SMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1604a9ee3421SMatthew G. Knepley ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 1605a9ee3421SMatthew G. Knepley ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr); 1606a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr); 1607a9ee3421SMatthew G. Knepley ierr = DMView(cdm, viewer);CHKERRQ(ierr); 1608a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr); 1609a9ee3421SMatthew G. Knepley 1610a9ee3421SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr); 1611a9ee3421SMatthew G. Knepley ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1612a9ee3421SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1613a9ee3421SMatthew G. Knepley const PetscInt i = p*bs; 1614a9ee3421SMatthew G. Knepley 161531403186SMatthew G. Knepley ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], radius, radius, PETSC_DRAW_BLUE);CHKERRQ(ierr); 1616a9ee3421SMatthew G. Knepley } 1617a9ee3421SMatthew G. Knepley ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1618a9ee3421SMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1619a9ee3421SMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1620a9ee3421SMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1621a9ee3421SMatthew G. Knepley PetscFunctionReturn(0); 1622a9ee3421SMatthew G. Knepley } 1623a9ee3421SMatthew G. Knepley 16245f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 16255f50eb2eSDave May { 16265f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1627a9ee3421SMatthew G. Knepley PetscBool iascii,ibinary,ishdf5,isvtk,isdraw; 16285f50eb2eSDave May PetscErrorCode ierr; 16295f50eb2eSDave May 16305f50eb2eSDave May PetscFunctionBegin; 16315f50eb2eSDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 16325f50eb2eSDave May PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 16335f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 16345f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 16355f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 16365f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1637a9ee3421SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 16385f50eb2eSDave May if (iascii) { 163977048351SPatrick Sanan ierr = DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 1640298827fbSBarry Smith } else if (ibinary) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support"); 16415f50eb2eSDave May #if defined(PETSC_HAVE_HDF5) 164274d0cae8SMatthew G. Knepley else if (ishdf5) { 164374d0cae8SMatthew G. Knepley ierr = DMSwarmView_HDF5(dm, viewer);CHKERRQ(ierr); 164474d0cae8SMatthew G. Knepley } 16455f50eb2eSDave May #else 1646298827fbSBarry Smith else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 16475f50eb2eSDave May #endif 1648298827fbSBarry Smith else if (isvtk) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1649298827fbSBarry Smith else if (isdraw) { 1650a9ee3421SMatthew G. Knepley ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr); 16515f50eb2eSDave May } 16525f50eb2eSDave May PetscFunctionReturn(0); 16535f50eb2eSDave May } 16545f50eb2eSDave May 1655d0c080abSJoseph Pusztay /*@C 1656d0c080abSJoseph Pusztay DMSwarmGetCellSwarm - Extracts a single cell from the DMSwarm object, returns it as a single cell DMSwarm. 1657d0c080abSJoseph Pusztay The cell DM is filtered for fields of that cell, and the filtered DM is used as the cell DM of the new swarm object. 1658d0c080abSJoseph Pusztay 1659d0c080abSJoseph Pusztay Important: Changes to this cell of the swarm will be lost if they are made prior to restoring this cell. 1660d0c080abSJoseph Pusztay 1661d0c080abSJoseph Pusztay Noncollective 1662d0c080abSJoseph Pusztay 1663d0c080abSJoseph Pusztay Input parameters: 1664d0c080abSJoseph Pusztay + sw - the DMSwarm 1665d0c080abSJoseph Pusztay - cellID - the integer id of the cell to be extracted and filtered 1666d0c080abSJoseph Pusztay 1667d0c080abSJoseph Pusztay Output parameters: 1668d0c080abSJoseph Pusztay . cellswarm - The new DMSwarm 1669d0c080abSJoseph Pusztay 1670d0c080abSJoseph Pusztay Level: beginner 1671d0c080abSJoseph Pusztay 1672d0c080abSJoseph Pusztay Note: This presently only supports DMSWARM_PIC type 1673d0c080abSJoseph Pusztay 1674d0c080abSJoseph Pusztay .seealso: DMSwarmRestoreCellSwarm() 1675d0c080abSJoseph Pusztay @*/ 1676d0c080abSJoseph Pusztay PETSC_EXTERN PetscErrorCode DMSwarmGetCellSwarm(DM sw, PetscInt cellID, DM cellswarm) 1677d0c080abSJoseph Pusztay { 1678d0c080abSJoseph Pusztay DM_Swarm *original = (DM_Swarm*) sw->data; 1679d0c080abSJoseph Pusztay DMLabel label; 1680d0c080abSJoseph Pusztay DM dmc, subdmc; 1681d0c080abSJoseph Pusztay PetscInt *pids, particles, dim; 1682d0c080abSJoseph Pusztay PetscErrorCode ierr; 1683d0c080abSJoseph Pusztay 1684d0c080abSJoseph Pusztay PetscFunctionBegin; 1685d0c080abSJoseph Pusztay /* Configure new swarm */ 1686d0c080abSJoseph Pusztay ierr = DMSetType(cellswarm, DMSWARM);CHKERRQ(ierr); 1687d0c080abSJoseph Pusztay ierr = DMGetDimension(sw, &dim);CHKERRQ(ierr); 1688d0c080abSJoseph Pusztay ierr = DMSetDimension(cellswarm, dim);CHKERRQ(ierr); 1689d0c080abSJoseph Pusztay ierr = DMSwarmSetType(cellswarm, DMSWARM_PIC);CHKERRQ(ierr); 1690d0c080abSJoseph Pusztay /* Destroy the unused, unconfigured data bucket to prevent stragglers in memory */ 16911e1ea65dSPierre Jolivet ierr = DMSwarmDataBucketDestroy(&((DM_Swarm*)cellswarm->data)->db);CHKERRQ(ierr); 1692d0c080abSJoseph Pusztay ierr = DMSwarmSortGetAccess(sw);CHKERRQ(ierr); 1693d0c080abSJoseph Pusztay ierr = DMSwarmSortGetNumberOfPointsPerCell(sw, cellID, &particles);CHKERRQ(ierr); 1694d0c080abSJoseph Pusztay ierr = DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids);CHKERRQ(ierr); 16951e1ea65dSPierre Jolivet ierr = DMSwarmDataBucketCreateFromSubset(original->db, particles, pids, &((DM_Swarm*)cellswarm->data)->db);CHKERRQ(ierr); 1696d0c080abSJoseph Pusztay ierr = DMSwarmSortRestoreAccess(sw);CHKERRQ(ierr); 1697d0c080abSJoseph Pusztay ierr = PetscFree(pids);CHKERRQ(ierr); 1698d0c080abSJoseph Pusztay ierr = DMSwarmGetCellDM(sw, &dmc);CHKERRQ(ierr); 1699d0c080abSJoseph Pusztay ierr = DMLabelCreate(PetscObjectComm((PetscObject)sw), "singlecell", &label);CHKERRQ(ierr); 1700d0c080abSJoseph Pusztay ierr = DMAddLabel(dmc, label);CHKERRQ(ierr); 1701d0c080abSJoseph Pusztay ierr = DMLabelSetValue(label, cellID, 1);CHKERRQ(ierr); 1702d0c080abSJoseph Pusztay ierr = DMPlexFilter(dmc, label, 1, &subdmc);CHKERRQ(ierr); 17031e1ea65dSPierre Jolivet ierr = DMSwarmSetCellDM(cellswarm, subdmc);CHKERRQ(ierr); 17041e1ea65dSPierre Jolivet ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 1705d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1706d0c080abSJoseph Pusztay } 1707d0c080abSJoseph Pusztay 1708d0c080abSJoseph Pusztay /*@C 1709d0c080abSJoseph Pusztay DMSwarmRestoreCellSwarm - Restores a DMSwarm object obtained with DMSwarmGetCellSwarm. All fields are copied back into the parent swarm. 1710d0c080abSJoseph Pusztay 1711d0c080abSJoseph Pusztay Noncollective 1712d0c080abSJoseph Pusztay 1713d0c080abSJoseph Pusztay Input parameters: 1714d0c080abSJoseph Pusztay + sw - the parent DMSwarm 1715d0c080abSJoseph Pusztay . cellID - the integer id of the cell to be copied back into the parent swarm 1716d0c080abSJoseph Pusztay - cellswarm - the cell swarm object 1717d0c080abSJoseph Pusztay 1718d0c080abSJoseph Pusztay Level: beginner 1719d0c080abSJoseph Pusztay 1720d0c080abSJoseph Pusztay Note: This only supports DMSWARM_PIC types of DMSwarms 1721d0c080abSJoseph Pusztay 1722d0c080abSJoseph Pusztay .seealso: DMSwarmGetCellSwarm() 1723d0c080abSJoseph Pusztay @*/ 1724d0c080abSJoseph Pusztay PETSC_EXTERN PetscErrorCode DMSwarmRestoreCellSwarm(DM sw, PetscInt cellID, DM cellswarm) 1725d0c080abSJoseph Pusztay { 1726d0c080abSJoseph Pusztay DM dmc; 1727d0c080abSJoseph Pusztay PetscInt *pids, particles, p; 1728d0c080abSJoseph Pusztay PetscErrorCode ierr; 1729d0c080abSJoseph Pusztay 1730d0c080abSJoseph Pusztay PetscFunctionBegin; 1731d0c080abSJoseph Pusztay ierr = DMSwarmSortGetAccess(sw);CHKERRQ(ierr); 1732d0c080abSJoseph Pusztay ierr = DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids);CHKERRQ(ierr); 1733d0c080abSJoseph Pusztay ierr = DMSwarmSortRestoreAccess(sw);CHKERRQ(ierr); 1734d0c080abSJoseph Pusztay /* Pointwise copy of each particle based on pid. The parent swarm may not be altered during this process. */ 1735d0c080abSJoseph Pusztay for (p=0; p<particles; ++p) { 1736d0c080abSJoseph Pusztay ierr = DMSwarmDataBucketCopyPoint(((DM_Swarm*)cellswarm->data)->db,pids[p],((DM_Swarm*)sw->data)->db,pids[p]);CHKERRQ(ierr); 1737d0c080abSJoseph Pusztay } 1738d0c080abSJoseph Pusztay /* Free memory, destroy cell dm */ 17391e1ea65dSPierre Jolivet ierr = DMSwarmGetCellDM(cellswarm, &dmc);CHKERRQ(ierr); 17401e1ea65dSPierre Jolivet ierr = DMDestroy(&dmc);CHKERRQ(ierr); 1741d0c080abSJoseph Pusztay ierr = PetscFree(pids);CHKERRQ(ierr); 1742d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1743d0c080abSJoseph Pusztay } 1744d0c080abSJoseph Pusztay 1745d0c080abSJoseph Pusztay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM, DM *); 1746d0c080abSJoseph Pusztay 1747d0c080abSJoseph Pusztay static PetscErrorCode DMInitialize_Swarm(DM sw) 1748d0c080abSJoseph Pusztay { 1749d0c080abSJoseph Pusztay PetscFunctionBegin; 1750d0c080abSJoseph Pusztay sw->dim = 0; 1751d0c080abSJoseph Pusztay sw->ops->view = DMView_Swarm; 1752d0c080abSJoseph Pusztay sw->ops->load = NULL; 1753d0c080abSJoseph Pusztay sw->ops->setfromoptions = NULL; 1754d0c080abSJoseph Pusztay sw->ops->clone = DMClone_Swarm; 1755d0c080abSJoseph Pusztay sw->ops->setup = DMSetup_Swarm; 1756d0c080abSJoseph Pusztay sw->ops->createlocalsection = NULL; 1757d0c080abSJoseph Pusztay sw->ops->createdefaultconstraints = NULL; 1758d0c080abSJoseph Pusztay sw->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1759d0c080abSJoseph Pusztay sw->ops->createlocalvector = DMCreateLocalVector_Swarm; 1760d0c080abSJoseph Pusztay sw->ops->getlocaltoglobalmapping = NULL; 1761d0c080abSJoseph Pusztay sw->ops->createfieldis = NULL; 1762d0c080abSJoseph Pusztay sw->ops->createcoordinatedm = NULL; 1763d0c080abSJoseph Pusztay sw->ops->getcoloring = NULL; 1764d0c080abSJoseph Pusztay sw->ops->creatematrix = DMCreateMatrix_Swarm; 1765d0c080abSJoseph Pusztay sw->ops->createinterpolation = NULL; 1766d0c080abSJoseph Pusztay sw->ops->createinjection = NULL; 1767d0c080abSJoseph Pusztay sw->ops->createmassmatrix = DMCreateMassMatrix_Swarm; 1768d0c080abSJoseph Pusztay sw->ops->refine = NULL; 1769d0c080abSJoseph Pusztay sw->ops->coarsen = NULL; 1770d0c080abSJoseph Pusztay sw->ops->refinehierarchy = NULL; 1771d0c080abSJoseph Pusztay sw->ops->coarsenhierarchy = NULL; 1772d0c080abSJoseph Pusztay sw->ops->globaltolocalbegin = NULL; 1773d0c080abSJoseph Pusztay sw->ops->globaltolocalend = NULL; 1774d0c080abSJoseph Pusztay sw->ops->localtoglobalbegin = NULL; 1775d0c080abSJoseph Pusztay sw->ops->localtoglobalend = NULL; 1776d0c080abSJoseph Pusztay sw->ops->destroy = DMDestroy_Swarm; 1777d0c080abSJoseph Pusztay sw->ops->createsubdm = NULL; 1778d0c080abSJoseph Pusztay sw->ops->getdimpoints = NULL; 1779d0c080abSJoseph Pusztay sw->ops->locatepoints = NULL; 1780d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1781d0c080abSJoseph Pusztay } 1782d0c080abSJoseph Pusztay 1783d0c080abSJoseph Pusztay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM dm, DM *newdm) 1784d0c080abSJoseph Pusztay { 1785d0c080abSJoseph Pusztay DM_Swarm *swarm = (DM_Swarm *) dm->data; 1786d0c080abSJoseph Pusztay PetscErrorCode ierr; 1787d0c080abSJoseph Pusztay 1788d0c080abSJoseph Pusztay PetscFunctionBegin; 1789d0c080abSJoseph Pusztay swarm->refct++; 1790d0c080abSJoseph Pusztay (*newdm)->data = swarm; 1791d0c080abSJoseph Pusztay ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMSWARM);CHKERRQ(ierr); 1792d0c080abSJoseph Pusztay ierr = DMInitialize_Swarm(*newdm);CHKERRQ(ierr); 17932e56dffeSJoe Pusztay (*newdm)->dim = dm->dim; 1794d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1795d0c080abSJoseph Pusztay } 1796d0c080abSJoseph Pusztay 1797d3a51819SDave May /*MC 1798d3a51819SDave May 1799d3a51819SDave May DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 180062741f57SDave May This implementation was designed for particle methods in which the underlying 1801d3a51819SDave May data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1802d3a51819SDave May 180362741f57SDave May User data can be represented by DMSwarm through a registering "fields". 180462741f57SDave May To register a field, the user must provide; 180562741f57SDave May (a) a unique name; 180662741f57SDave May (b) the data type (or size in bytes); 180762741f57SDave May (c) the block size of the data. 1808d3a51819SDave May 1809d3a51819SDave May For example, suppose the application requires a unique id, energy, momentum and density to be stored 1810c215a47eSMatthew Knepley on a set of particles. Then the following code could be used 1811d3a51819SDave May 181262741f57SDave May $ DMSwarmInitializeFieldRegister(dm) 181362741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 181462741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 181562741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 181662741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 181762741f57SDave May $ DMSwarmFinalizeFieldRegister(dm) 1818d3a51819SDave May 1819d3a51819SDave May The fields represented by DMSwarm are dynamic and can be re-sized at any time. 182062741f57SDave May The only restriction imposed by DMSwarm is that all fields contain the same number of points. 1821d3a51819SDave May 1822d3a51819SDave May To support particle methods, "migration" techniques are provided. These methods migrate data 1823d3a51819SDave May between MPI-ranks. 1824d3a51819SDave May 1825d3a51819SDave May DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1826d3a51819SDave May As a DMSwarm may internally define and store values of different data types, 182762741f57SDave May before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which 1828d3a51819SDave May fields should be used to define a Vec object via 1829d3a51819SDave May DMSwarmVectorDefineField() 1830c215a47eSMatthew Knepley The specified field can be changed at any time - thereby permitting vectors 1831c215a47eSMatthew Knepley compatible with different fields to be created. 1832d3a51819SDave May 183362741f57SDave May A dual representation of fields in the DMSwarm and a Vec object is permitted via 1834d3a51819SDave May DMSwarmCreateGlobalVectorFromField() 1835d3a51819SDave May Here the data defining the field in the DMSwarm is shared with a Vec. 1836d3a51819SDave May This is inherently unsafe if you alter the size of the field at any time between 1837d3a51819SDave May calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1838cc651181SDave May If the local size of the DMSwarm does not match the local size of the global vector 1839cc651181SDave May when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1840d3a51819SDave May 184162741f57SDave May Additional high-level support is provided for Particle-In-Cell methods. 184262741f57SDave May Please refer to the man page for DMSwarmSetType(). 184362741f57SDave May 1844d3a51819SDave May Level: beginner 1845d3a51819SDave May 1846d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType() 1847d3a51819SDave May M*/ 184857795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 184957795646SDave May { 185057795646SDave May DM_Swarm *swarm; 185157795646SDave May PetscErrorCode ierr; 185257795646SDave May 185357795646SDave May PetscFunctionBegin; 185457795646SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 185557795646SDave May ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 1856f0cdbbbaSDave May dm->data = swarm; 185777048351SPatrick Sanan ierr = DMSwarmDataBucketCreate(&swarm->db);CHKERRQ(ierr); 1858f0cdbbbaSDave May ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 1859d0c080abSJoseph Pusztay swarm->refct = 1; 1860b5bcf523SDave May swarm->vec_field_set = PETSC_FALSE; 18613454631fSDave May swarm->issetup = PETSC_FALSE; 1862480eef7bSDave May swarm->swarm_type = DMSWARM_BASIC; 1863480eef7bSDave May swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1864480eef7bSDave May swarm->collect_type = DMSWARM_COLLECT_BASIC; 186540c453e9SDave May swarm->migrate_error_on_missing_point = PETSC_FALSE; 1866f0cdbbbaSDave May swarm->dmcell = NULL; 1867f0cdbbbaSDave May swarm->collect_view_active = PETSC_FALSE; 1868f0cdbbbaSDave May swarm->collect_view_reset_nlocal = -1; 1869d0c080abSJoseph Pusztay ierr = DMInitialize_Swarm(dm);CHKERRQ(ierr); 187057795646SDave May PetscFunctionReturn(0); 187157795646SDave May } 1872