1c4762a1bSJed Brown static char help[] = "Test for function and field projection\n\n"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown #include <petscdmplex.h> 4c4762a1bSJed Brown #include <petscds.h> 5c4762a1bSJed Brown 6c4762a1bSJed Brown typedef struct { 7c4762a1bSJed Brown PetscBool multifield; /* Different numbers of input and output fields */ 8c4762a1bSJed Brown PetscBool subdomain; /* Try with a volumetric submesh */ 9c4762a1bSJed Brown PetscBool submesh; /* Try with a boundary submesh */ 10c4762a1bSJed Brown PetscBool auxfield; /* Try with auxiliary fields */ 11c4762a1bSJed Brown } AppCtx; 12c4762a1bSJed Brown 13c4762a1bSJed Brown /* (x + y)*dim + d */ 14d71ae5a4SJacob Faibussowitsch static PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 15d71ae5a4SJacob Faibussowitsch { 16c4762a1bSJed Brown PetscInt c; 17c4762a1bSJed Brown for (c = 0; c < Nc; ++c) u[c] = (x[0] + x[1]) * Nc + c; 183ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 19c4762a1bSJed Brown } 20c4762a1bSJed Brown 21c4762a1bSJed Brown /* {x, y, z} */ 22d71ae5a4SJacob Faibussowitsch static PetscErrorCode linear2(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 23d71ae5a4SJacob Faibussowitsch { 24c4762a1bSJed Brown PetscInt c; 25c4762a1bSJed Brown for (c = 0; c < Nc; ++c) u[c] = x[c]; 263ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 27c4762a1bSJed Brown } 28c4762a1bSJed Brown 29c4762a1bSJed Brown /* {u_x, u_y, u_z} */ 30d71ae5a4SJacob Faibussowitsch static void linear_vector(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]) 31d71ae5a4SJacob Faibussowitsch { 32c4762a1bSJed Brown PetscInt d; 33c4762a1bSJed Brown for (d = 0; d < uOff[1] - uOff[0]; ++d) f[d] = u[d + uOff[0]]; 34c4762a1bSJed Brown } 35c4762a1bSJed Brown 36c4762a1bSJed Brown /* p */ 37d71ae5a4SJacob Faibussowitsch static void linear_scalar(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]) 38d71ae5a4SJacob Faibussowitsch { 39c4762a1bSJed Brown f[0] = u[uOff[1]]; 40c4762a1bSJed Brown } 41c4762a1bSJed Brown 42c4762a1bSJed Brown /* {div u, p^2} */ 43d71ae5a4SJacob Faibussowitsch static void divergence_sq(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]) 44d71ae5a4SJacob Faibussowitsch { 45c4762a1bSJed Brown PetscInt d; 46c4762a1bSJed Brown f[0] = 0.0; 47c4762a1bSJed Brown for (d = 0; d < dim; ++d) f[0] += u_x[uOff_x[0] + d * dim + d]; 48c4762a1bSJed Brown f[1] = PetscSqr(u[uOff[1]]); 49c4762a1bSJed Brown } 50c4762a1bSJed Brown 51d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(AppCtx *options) 52d71ae5a4SJacob Faibussowitsch { 53c4762a1bSJed Brown PetscFunctionBegin; 54c4762a1bSJed Brown options->multifield = PETSC_FALSE; 55c4762a1bSJed Brown options->subdomain = PETSC_FALSE; 56c4762a1bSJed Brown options->submesh = PETSC_FALSE; 57c4762a1bSJed Brown options->auxfield = PETSC_FALSE; 58c4762a1bSJed Brown 59d0609cedSBarry Smith PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX"); 609566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-multifield", "Flag for trying different numbers of input/output fields", "ex23.c", options->multifield, &options->multifield, NULL)); 619566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-subdomain", "Flag for trying volumetric submesh", "ex23.c", options->subdomain, &options->subdomain, NULL)); 629566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-submesh", "Flag for trying boundary submesh", "ex23.c", options->submesh, &options->submesh, NULL)); 639566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-auxfield", "Flag for trying auxiliary fields", "ex23.c", options->auxfield, &options->auxfield, NULL)); 64d0609cedSBarry Smith PetscOptionsEnd(); 653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66c4762a1bSJed Brown } 67c4762a1bSJed Brown 68d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 69d71ae5a4SJacob Faibussowitsch { 70c4762a1bSJed Brown PetscFunctionBegin; 719566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, dm)); 729566063dSJacob Faibussowitsch PetscCall(DMSetType(*dm, DMPLEX)); 739566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(*dm)); 749566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*dm, NULL, "-orig_dm_view")); 753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76c4762a1bSJed Brown } 77c4762a1bSJed Brown 78d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupDiscretization(DM dm, PetscInt dim, PetscBool simplex, AppCtx *user) 79d71ae5a4SJacob Faibussowitsch { 80c4762a1bSJed Brown PetscFE fe; 81c4762a1bSJed Brown MPI_Comm comm; 82c4762a1bSJed Brown 83c4762a1bSJed Brown PetscFunctionBeginUser; 849566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 859566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(comm, dim, dim, simplex, "velocity_", -1, &fe)); 869566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe, "velocity")); 879566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe)); 889566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 899566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(comm, dim, 1, simplex, "pressure_", -1, &fe)); 909566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe, "pressure")); 919566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, 1, NULL, (PetscObject)fe)); 929566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 939566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dm)); 943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 95c4762a1bSJed Brown } 96c4762a1bSJed Brown 97d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupOutputDiscretization(DM dm, PetscInt dim, PetscBool simplex, AppCtx *user) 98d71ae5a4SJacob Faibussowitsch { 99c4762a1bSJed Brown PetscFE fe; 100c4762a1bSJed Brown MPI_Comm comm; 101c4762a1bSJed Brown 102c4762a1bSJed Brown PetscFunctionBeginUser; 1039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 1049566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(comm, dim, dim, simplex, "output_", -1, &fe)); 1059566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe, "output")); 1069566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe)); 1079566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 1089566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dm)); 1093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 110c4762a1bSJed Brown } 111c4762a1bSJed Brown 112d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateSubdomainMesh(DM dm, DMLabel *domLabel, DM *subdm, AppCtx *user) 113d71ae5a4SJacob Faibussowitsch { 114c4762a1bSJed Brown DMLabel label; 11530602db0SMatthew G. Knepley PetscBool simplex; 116c4762a1bSJed Brown PetscInt dim, cStart, cEnd, c; 117c4762a1bSJed Brown 118c4762a1bSJed Brown PetscFunctionBeginUser; 1199566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 1209566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 1219566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "subdomain", &label)); 1229566063dSJacob Faibussowitsch for (c = cStart + (cEnd - cStart) / 2; c < cEnd; ++c) PetscCall(DMLabelSetValue(label, c, 1)); 123*71f1c950SStefano Zampini PetscCall(DMPlexFilter(dm, label, 1, PETSC_FALSE, PETSC_FALSE, PetscObjectComm((PetscObject)dm), NULL, subdm)); 1249566063dSJacob Faibussowitsch PetscCall(DMGetDimension(*subdm, &dim)); 1259566063dSJacob Faibussowitsch PetscCall(SetupDiscretization(*subdm, dim, simplex, user)); 1269566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*subdm, "subdomain")); 1279566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*subdm, NULL, "-sub_dm_view")); 128c4762a1bSJed Brown if (domLabel) *domLabel = label; 1299566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&label)); 1303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 131c4762a1bSJed Brown } 132c4762a1bSJed Brown 133d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateBoundaryMesh(DM dm, DMLabel *bdLabel, DM *subdm, AppCtx *user) 134d71ae5a4SJacob Faibussowitsch { 135c4762a1bSJed Brown DMLabel label; 13630602db0SMatthew G. Knepley PetscBool simplex; 137c4762a1bSJed Brown PetscInt dim; 138c4762a1bSJed Brown 139c4762a1bSJed Brown PetscFunctionBeginUser; 1409566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 1419566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "sub", &label)); 1429566063dSJacob Faibussowitsch PetscCall(DMPlexMarkBoundaryFaces(dm, 1, label)); 1439566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(dm, label)); 1449566063dSJacob Faibussowitsch PetscCall(DMPlexCreateSubmesh(dm, label, 1, PETSC_TRUE, subdm)); 1459566063dSJacob Faibussowitsch PetscCall(DMGetDimension(*subdm, &dim)); 1469566063dSJacob Faibussowitsch PetscCall(SetupDiscretization(*subdm, dim, simplex, user)); 1479566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*subdm, "boundary")); 1489566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*subdm, NULL, "-sub_dm_view")); 149c4762a1bSJed Brown if (bdLabel) *bdLabel = label; 1509566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&label)); 1513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 152c4762a1bSJed Brown } 153c4762a1bSJed Brown 154d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateAuxiliaryVec(DM dm, DM *auxdm, Vec *la, AppCtx *user) 155d71ae5a4SJacob Faibussowitsch { 156c4762a1bSJed Brown PetscErrorCode (**afuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *); 15730602db0SMatthew G. Knepley PetscBool simplex; 158c4762a1bSJed Brown PetscInt dim, Nf, f; 159c4762a1bSJed Brown 160c4762a1bSJed Brown PetscFunctionBeginUser; 1619566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1629566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 1639566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &afuncs)); 165c4762a1bSJed Brown for (f = 0; f < Nf; ++f) afuncs[f] = linear; 1669566063dSJacob Faibussowitsch PetscCall(DMClone(dm, auxdm)); 1679566063dSJacob Faibussowitsch PetscCall(SetupDiscretization(*auxdm, dim, simplex, user)); 1689566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(*auxdm, la)); 1699566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, 0.0, afuncs, NULL, INSERT_VALUES, *la)); 1709566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(*la, NULL, "-local_aux_view")); 1719566063dSJacob Faibussowitsch PetscCall(PetscFree(afuncs)); 1723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 173c4762a1bSJed Brown } 174c4762a1bSJed Brown 175d71ae5a4SJacob Faibussowitsch static PetscErrorCode TestFunctionProjection(DM dm, DM dmAux, DMLabel label, Vec la, const char name[], AppCtx *user) 176d71ae5a4SJacob Faibussowitsch { 177c4762a1bSJed Brown PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *); 178c4762a1bSJed Brown Vec x, lx; 179c4762a1bSJed Brown PetscInt Nf, f; 180c4762a1bSJed Brown PetscInt val[1] = {1}; 181c4762a1bSJed Brown char lname[PETSC_MAX_PATH_LEN]; 182c4762a1bSJed Brown 183c4762a1bSJed Brown PetscFunctionBeginUser; 1849566063dSJacob Faibussowitsch if (dmAux) PetscCall(DMSetAuxiliaryVec(dm, NULL, 0, 0, la)); 1859566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &funcs)); 187c4762a1bSJed Brown for (f = 0; f < Nf; ++f) funcs[f] = linear; 1889566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &x)); 189c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(lname, "Function ", sizeof(lname))); 190c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(lname, name, sizeof(lname))); 1919566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)x, lname)); 1929566063dSJacob Faibussowitsch if (!label) PetscCall(DMProjectFunction(dm, 0.0, funcs, NULL, INSERT_VALUES, x)); 1939566063dSJacob Faibussowitsch else PetscCall(DMProjectFunctionLabel(dm, 0.0, label, 1, val, 0, NULL, funcs, NULL, INSERT_VALUES, x)); 1949566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(x, NULL, "-func_view")); 1959566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &x)); 1969566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &lx)); 197c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(lname, "Local Function ", sizeof(lname))); 198c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(lname, name, sizeof(lname))); 1999566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)lx, lname)); 2009566063dSJacob Faibussowitsch if (!label) PetscCall(DMProjectFunctionLocal(dm, 0.0, funcs, NULL, INSERT_VALUES, lx)); 2019566063dSJacob Faibussowitsch else PetscCall(DMProjectFunctionLabelLocal(dm, 0.0, label, 1, val, 0, NULL, funcs, NULL, INSERT_VALUES, lx)); 2029566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(lx, NULL, "-local_func_view")); 2039566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &lx)); 2049566063dSJacob Faibussowitsch PetscCall(PetscFree(funcs)); 2059566063dSJacob Faibussowitsch if (dmAux) PetscCall(DMSetAuxiliaryVec(dm, NULL, 0, 0, NULL)); 2063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 207c4762a1bSJed Brown } 208c4762a1bSJed Brown 209d71ae5a4SJacob Faibussowitsch static PetscErrorCode TestFieldProjection(DM dm, DM dmAux, DMLabel label, Vec la, const char name[], AppCtx *user) 210d71ae5a4SJacob Faibussowitsch { 211c4762a1bSJed Brown PetscErrorCode (**afuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *); 2129371c9d4SSatish Balay void (**funcs)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]); 213c4762a1bSJed Brown Vec lx, lu; 214c4762a1bSJed Brown PetscInt Nf, f; 215c4762a1bSJed Brown PetscInt val[1] = {1}; 216c4762a1bSJed Brown char lname[PETSC_MAX_PATH_LEN]; 217c4762a1bSJed Brown 218c4762a1bSJed Brown PetscFunctionBeginUser; 2199566063dSJacob Faibussowitsch if (dmAux) PetscCall(DMSetAuxiliaryVec(dm, NULL, 0, 0, la)); 2209566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 2219566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &funcs, Nf, &afuncs)); 222c4762a1bSJed Brown for (f = 0; f < Nf; ++f) afuncs[f] = linear; 223c4762a1bSJed Brown funcs[0] = linear_vector; 224c4762a1bSJed Brown funcs[1] = linear_scalar; 2259566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &lu)); 226c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(lname, "Local Field Input ", sizeof(lname))); 227c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(lname, name, sizeof(lname))); 2289566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)lu, lname)); 2299566063dSJacob Faibussowitsch if (!label) PetscCall(DMProjectFunctionLocal(dm, 0.0, afuncs, NULL, INSERT_VALUES, lu)); 2309566063dSJacob Faibussowitsch else PetscCall(DMProjectFunctionLabelLocal(dm, 0.0, label, 1, val, 0, NULL, afuncs, NULL, INSERT_VALUES, lu)); 2319566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(lu, NULL, "-local_input_view")); 2329566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &lx)); 233c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(lname, "Local Field ", sizeof(lname))); 234c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(lname, name, sizeof(lname))); 2359566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)lx, lname)); 2369566063dSJacob Faibussowitsch if (!label) PetscCall(DMProjectFieldLocal(dm, 0.0, lu, funcs, INSERT_VALUES, lx)); 2379566063dSJacob Faibussowitsch else PetscCall(DMProjectFieldLabelLocal(dm, 0.0, label, 1, val, 0, NULL, lu, funcs, INSERT_VALUES, lx)); 2389566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(lx, NULL, "-local_field_view")); 2399566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &lx)); 2409566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &lu)); 2419566063dSJacob Faibussowitsch PetscCall(PetscFree2(funcs, afuncs)); 2429566063dSJacob Faibussowitsch if (dmAux) PetscCall(DMSetAuxiliaryVec(dm, NULL, 0, 0, NULL)); 2433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 244c4762a1bSJed Brown } 245c4762a1bSJed Brown 246d71ae5a4SJacob Faibussowitsch static PetscErrorCode TestFieldProjectionMultiple(DM dm, DM dmIn, DM dmAux, DMLabel label, Vec la, const char name[], AppCtx *user) 247d71ae5a4SJacob Faibussowitsch { 248c4762a1bSJed Brown PetscErrorCode (**afuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *); 2499371c9d4SSatish Balay void (**funcs)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]); 250c4762a1bSJed Brown Vec lx, lu; 251c4762a1bSJed Brown PetscInt Nf, NfIn; 252c4762a1bSJed Brown PetscInt val[1] = {1}; 253c4762a1bSJed Brown char lname[PETSC_MAX_PATH_LEN]; 254c4762a1bSJed Brown 255c4762a1bSJed Brown PetscFunctionBeginUser; 2569566063dSJacob Faibussowitsch if (dmAux) PetscCall(DMSetAuxiliaryVec(dm, NULL, 0, 0, la)); 2579566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 2589566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dmIn, &NfIn)); 2599566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &funcs, NfIn, &afuncs)); 260c4762a1bSJed Brown funcs[0] = divergence_sq; 261c4762a1bSJed Brown afuncs[0] = linear2; 262c4762a1bSJed Brown afuncs[1] = linear; 2639566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dmIn, &lu)); 264c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(lname, "Local MultiField Input ", sizeof(lname))); 265c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(lname, name, sizeof(lname))); 2669566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)lu, lname)); 2679566063dSJacob Faibussowitsch if (!label) PetscCall(DMProjectFunctionLocal(dmIn, 0.0, afuncs, NULL, INSERT_VALUES, lu)); 2689566063dSJacob Faibussowitsch else PetscCall(DMProjectFunctionLabelLocal(dmIn, 0.0, label, 1, val, 0, NULL, afuncs, NULL, INSERT_VALUES, lu)); 2699566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(lu, NULL, "-local_input_view")); 2709566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &lx)); 271c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(lname, "Local MultiField ", sizeof(lname))); 272c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(lname, name, sizeof(lname))); 2739566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)lx, lname)); 2749566063dSJacob Faibussowitsch if (!label) PetscCall(DMProjectFieldLocal(dm, 0.0, lu, funcs, INSERT_VALUES, lx)); 2759566063dSJacob Faibussowitsch else PetscCall(DMProjectFieldLabelLocal(dm, 0.0, label, 1, val, 0, NULL, lu, funcs, INSERT_VALUES, lx)); 2769566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(lx, NULL, "-local_field_view")); 2779566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &lx)); 2789566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dmIn, &lu)); 2799566063dSJacob Faibussowitsch PetscCall(PetscFree2(funcs, afuncs)); 2809566063dSJacob Faibussowitsch if (dmAux) PetscCall(DMSetAuxiliaryVec(dm, NULL, 0, 0, NULL)); 2813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 282c4762a1bSJed Brown } 283c4762a1bSJed Brown 284d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 285d71ae5a4SJacob Faibussowitsch { 286c4762a1bSJed Brown DM dm, subdm, auxdm; 287c4762a1bSJed Brown Vec la; 28830602db0SMatthew G. Knepley PetscInt dim; 28930602db0SMatthew G. Knepley PetscBool simplex; 290c4762a1bSJed Brown AppCtx user; 291c4762a1bSJed Brown 292327415f7SBarry Smith PetscFunctionBeginUser; 2939566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 2949566063dSJacob Faibussowitsch PetscCall(ProcessOptions(&user)); 2959566063dSJacob Faibussowitsch PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 2969566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 2979566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 2989566063dSJacob Faibussowitsch PetscCall(SetupDiscretization(dm, dim, simplex, &user)); 299c4762a1bSJed Brown /* Volumetric Mesh Projection */ 300c4762a1bSJed Brown if (!user.multifield) { 3019566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(dm, NULL, NULL, NULL, "Volumetric Primary", &user)); 3029566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(dm, NULL, NULL, NULL, "Volumetric Primary", &user)); 303c4762a1bSJed Brown } else { 304c4762a1bSJed Brown DM dmOut; 305c4762a1bSJed Brown 3069566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dmOut)); 3079566063dSJacob Faibussowitsch PetscCall(SetupOutputDiscretization(dmOut, dim, simplex, &user)); 3089566063dSJacob Faibussowitsch PetscCall(TestFieldProjectionMultiple(dmOut, dm, NULL, NULL, NULL, "Volumetric Primary", &user)); 3099566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmOut)); 310c4762a1bSJed Brown } 311c4762a1bSJed Brown if (user.auxfield) { 312c4762a1bSJed Brown /* Volumetric Mesh Projection with Volumetric Data */ 3139566063dSJacob Faibussowitsch PetscCall(CreateAuxiliaryVec(dm, &auxdm, &la, &user)); 3149566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(dm, auxdm, NULL, la, "Volumetric Primary and Volumetric Auxiliary", &user)); 3159566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(dm, auxdm, NULL, la, "Volumetric Primary and Volumetric Auxiliary", &user)); 3169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&la)); 317c4762a1bSJed Brown /* Update of Volumetric Auxiliary Data with primary Volumetric Data */ 3189566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &la)); 3199566063dSJacob Faibussowitsch PetscCall(VecSet(la, 1.0)); 3209566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(auxdm, dm, NULL, la, "Volumetric Auxiliary Update with Volumetric Primary", &user)); 3219566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &la)); 3229566063dSJacob Faibussowitsch PetscCall(DMDestroy(&auxdm)); 323c4762a1bSJed Brown } 324c4762a1bSJed Brown if (user.subdomain) { 325c4762a1bSJed Brown DMLabel domLabel; 326c4762a1bSJed Brown 327c4762a1bSJed Brown /* Subdomain Mesh Projection */ 3289566063dSJacob Faibussowitsch PetscCall(CreateSubdomainMesh(dm, &domLabel, &subdm, &user)); 3299566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(subdm, NULL, NULL, NULL, "Subdomain Primary", &user)); 3309566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(subdm, NULL, NULL, NULL, "Subdomain Primary", &user)); 331c4762a1bSJed Brown if (user.auxfield) { 332c4762a1bSJed Brown /* Subdomain Mesh Projection with Subdomain Data */ 3339566063dSJacob Faibussowitsch PetscCall(CreateAuxiliaryVec(subdm, &auxdm, &la, &user)); 3349566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Subdomain Auxiliary", &user)); 3359566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Subdomain Auxiliary", &user)); 3369566063dSJacob Faibussowitsch PetscCall(VecDestroy(&la)); 3379566063dSJacob Faibussowitsch PetscCall(DMDestroy(&auxdm)); 338c4762a1bSJed Brown /* Subdomain Mesh Projection with Volumetric Data */ 3399566063dSJacob Faibussowitsch PetscCall(CreateAuxiliaryVec(dm, &auxdm, &la, &user)); 3409566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Volumetric Auxiliary", &user)); 3419566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Volumetric Auxiliary", &user)); 3429566063dSJacob Faibussowitsch PetscCall(VecDestroy(&la)); 3439566063dSJacob Faibussowitsch PetscCall(DMDestroy(&auxdm)); 344c4762a1bSJed Brown /* Volumetric Mesh Projection with Subdomain Data */ 3459566063dSJacob Faibussowitsch PetscCall(CreateAuxiliaryVec(subdm, &auxdm, &la, &user)); 3469566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(subdm, auxdm, domLabel, la, "Volumetric Primary and Subdomain Auxiliary", &user)); 3479566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(subdm, auxdm, domLabel, la, "Volumetric Primary and Subdomain Auxiliary", &user)); 3489566063dSJacob Faibussowitsch PetscCall(VecDestroy(&la)); 3499566063dSJacob Faibussowitsch PetscCall(DMDestroy(&auxdm)); 350c4762a1bSJed Brown } 3519566063dSJacob Faibussowitsch PetscCall(DMDestroy(&subdm)); 3529566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&domLabel)); 353c4762a1bSJed Brown } 354c4762a1bSJed Brown if (user.submesh) { 355c4762a1bSJed Brown DMLabel bdLabel; 356c4762a1bSJed Brown 357c4762a1bSJed Brown /* Boundary Mesh Projection */ 3589566063dSJacob Faibussowitsch PetscCall(CreateBoundaryMesh(dm, &bdLabel, &subdm, &user)); 3599566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(subdm, NULL, NULL, NULL, "Boundary Primary", &user)); 3609566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(subdm, NULL, NULL, NULL, "Boundary Primary", &user)); 361c4762a1bSJed Brown if (user.auxfield) { 362c4762a1bSJed Brown /* Boundary Mesh Projection with Boundary Data */ 3639566063dSJacob Faibussowitsch PetscCall(CreateAuxiliaryVec(subdm, &auxdm, &la, &user)); 3649566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(subdm, auxdm, NULL, la, "Boundary Primary and Boundary Auxiliary", &user)); 3659566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(subdm, auxdm, NULL, la, "Boundary Primary and Boundary Auxiliary", &user)); 3669566063dSJacob Faibussowitsch PetscCall(VecDestroy(&la)); 3679566063dSJacob Faibussowitsch PetscCall(DMDestroy(&auxdm)); 368c4762a1bSJed Brown /* Volumetric Mesh Projection with Boundary Data */ 3699566063dSJacob Faibussowitsch PetscCall(CreateAuxiliaryVec(subdm, &auxdm, &la, &user)); 3709566063dSJacob Faibussowitsch PetscCall(TestFunctionProjection(dm, auxdm, bdLabel, la, "Volumetric Primary and Boundary Auxiliary", &user)); 3719566063dSJacob Faibussowitsch PetscCall(TestFieldProjection(dm, auxdm, bdLabel, la, "Volumetric Primary and Boundary Auxiliary", &user)); 3729566063dSJacob Faibussowitsch PetscCall(VecDestroy(&la)); 3739566063dSJacob Faibussowitsch PetscCall(DMDestroy(&auxdm)); 374c4762a1bSJed Brown } 3759566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&bdLabel)); 3769566063dSJacob Faibussowitsch PetscCall(DMDestroy(&subdm)); 377c4762a1bSJed Brown } 3789566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 3799566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 380b122ec5aSJacob Faibussowitsch return 0; 381c4762a1bSJed Brown } 382c4762a1bSJed Brown 383c4762a1bSJed Brown /*TEST 384c4762a1bSJed Brown 385c4762a1bSJed Brown test: 386c4762a1bSJed Brown suffix: 0 387c4762a1bSJed Brown requires: triangle 38830602db0SMatthew G. Knepley args: -dm_plex_box_faces 1,1 -func_view -local_func_view -local_input_view -local_field_view 389c4762a1bSJed Brown test: 390c4762a1bSJed Brown suffix: mf_0 391c4762a1bSJed Brown requires: triangle 39230602db0SMatthew G. Knepley args: -dm_plex_box_faces 1,1 -velocity_petscspace_degree 1 -velocity_petscfe_default_quadrature_order 2 \ 393c4762a1bSJed Brown -pressure_petscspace_degree 2 -pressure_petscfe_default_quadrature_order 2 \ 394c4762a1bSJed Brown -multifield -output_petscspace_degree 1 -output_petscfe_default_quadrature_order 2 \ 395c4762a1bSJed Brown -local_input_view -local_field_view 396c4762a1bSJed Brown test: 397c4762a1bSJed Brown suffix: 1 398c4762a1bSJed Brown requires: triangle 39930602db0SMatthew G. Knepley args: -dm_plex_box_faces 1,1 -velocity_petscspace_degree 1 -velocity_petscfe_default_quadrature_order 2 -pressure_petscspace_degree 2 -pressure_petscfe_default_quadrature_order 2 -func_view -local_func_view -local_input_view -local_field_view -submesh -auxfield 400c4762a1bSJed Brown test: 401c4762a1bSJed Brown suffix: 2 402c4762a1bSJed Brown requires: triangle 40330602db0SMatthew G. Knepley args: -dm_plex_box_faces 1,1 -velocity_petscspace_degree 1 -velocity_petscfe_default_quadrature_order 2 -pressure_petscspace_degree 2 -pressure_petscfe_default_quadrature_order 2 -func_view -local_func_view -local_input_view -local_field_view -subdomain -auxfield 404c4762a1bSJed Brown 405c4762a1bSJed Brown TEST*/ 406c4762a1bSJed Brown 407c4762a1bSJed Brown /* 408c4762a1bSJed Brown Post-processing wants to project a function of the fields into some FE space 409c4762a1bSJed Brown - This is DMProjectField() 410c4762a1bSJed Brown - What about changing the number of components of the output, like displacement to stress? Aux vars 411c4762a1bSJed Brown 412c4762a1bSJed Brown Update of state variables 413c4762a1bSJed Brown - This is DMProjectField(), but solution must be the aux var 414c4762a1bSJed Brown */ 415