1 static char help[] = "Test for function and field projection\n\n"; 2 3 #include <petscdmplex.h> 4 #include <petscds.h> 5 6 typedef struct { 7 PetscInt dim; /* The topological mesh dimension */ 8 PetscBool cellSimplex; /* Flag for simplices */ 9 PetscBool multifield; /* Different numbers of input and output fields */ 10 PetscBool subdomain; /* Try with a volumetric submesh */ 11 PetscBool submesh; /* Try with a boundary submesh */ 12 PetscBool auxfield; /* Try with auxiliary fields */ 13 } AppCtx; 14 15 /* (x + y)*dim + d */ 16 static PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 17 { 18 PetscInt c; 19 for (c = 0; c < Nc; ++c) u[c] = (x[0] + x[1])*Nc + c; 20 return 0; 21 } 22 23 /* {x, y, z} */ 24 static PetscErrorCode linear2(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 25 { 26 PetscInt c; 27 for (c = 0; c < Nc; ++c) u[c] = x[c]; 28 return 0; 29 } 30 31 /* {u_x, u_y, u_z} */ 32 static void linear_vector(PetscInt dim, PetscInt Nf, PetscInt NfAux, 33 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 34 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 35 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]) 36 { 37 PetscInt d; 38 for (d = 0; d < uOff[1]-uOff[0]; ++d) f[d] = u[d+uOff[0]]; 39 } 40 41 /* p */ 42 static void linear_scalar(PetscInt dim, PetscInt Nf, PetscInt NfAux, 43 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 44 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 45 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]) 46 { 47 f[0] = u[uOff[1]]; 48 } 49 50 /* {div u, p^2} */ 51 static void divergence_sq(PetscInt dim, PetscInt Nf, PetscInt NfAux, 52 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 53 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 54 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]) 55 { 56 PetscInt d; 57 f[0] = 0.0; 58 for (d = 0; d < dim; ++d) f[0] += u_x[uOff_x[0]+d*dim+d]; 59 f[1] = PetscSqr(u[uOff[1]]); 60 } 61 62 static PetscErrorCode ProcessOptions(AppCtx *options) 63 { 64 PetscErrorCode ierr; 65 66 PetscFunctionBegin; 67 options->dim = 2; 68 options->cellSimplex = PETSC_TRUE; 69 options->multifield = PETSC_FALSE; 70 options->subdomain = PETSC_FALSE; 71 options->submesh = PETSC_FALSE; 72 options->auxfield = PETSC_FALSE; 73 74 ierr = PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr); 75 ierr = PetscOptionsRangeInt("-dim", "The topological mesh dimension", "ex23.c", options->dim, &options->dim, NULL,1,3);CHKERRQ(ierr); 76 ierr = PetscOptionsBool("-cellSimplex", "Flag for simplices", "ex23.c", options->cellSimplex, &options->cellSimplex, NULL);CHKERRQ(ierr); 77 ierr = PetscOptionsBool("-multifield", "Flag for trying different numbers of input/output fields", "ex23.c", options->multifield, &options->multifield, NULL);CHKERRQ(ierr); 78 ierr = PetscOptionsBool("-subdomain", "Flag for trying volumetric submesh", "ex23.c", options->subdomain, &options->subdomain, NULL);CHKERRQ(ierr); 79 ierr = PetscOptionsBool("-submesh", "Flag for trying boundary submesh", "ex23.c", options->submesh, &options->submesh, NULL);CHKERRQ(ierr); 80 ierr = PetscOptionsBool("-auxfield", "Flag for trying auxiliary fields", "ex23.c", options->auxfield, &options->auxfield, NULL);CHKERRQ(ierr); 81 ierr = PetscOptionsEnd();CHKERRQ(ierr); 82 PetscFunctionReturn(0); 83 } 84 85 static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 86 { 87 PetscInt dim = user->dim; 88 PetscBool simplex = user->cellSimplex; 89 PetscInt cells[3] = {1, 1, 1}; 90 PetscErrorCode ierr; 91 92 PetscFunctionBegin; 93 ierr = DMPlexCreateBoxMesh(comm, dim, simplex, cells, NULL, NULL, NULL, PETSC_TRUE, dm);CHKERRQ(ierr); 94 { 95 DM ddm = NULL; 96 97 ierr = DMPlexDistribute(*dm, 0, NULL, &ddm);CHKERRQ(ierr); 98 if (ddm) { 99 ierr = DMDestroy(dm);CHKERRQ(ierr); 100 *dm = ddm; 101 } 102 } 103 ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); 104 ierr = DMViewFromOptions(*dm, NULL, "-orig_dm_view");CHKERRQ(ierr); 105 PetscFunctionReturn(0); 106 } 107 108 static PetscErrorCode SetupDiscretization(DM dm, PetscInt dim, PetscBool simplex, AppCtx *user) 109 { 110 PetscFE fe; 111 MPI_Comm comm; 112 PetscErrorCode ierr; 113 114 PetscFunctionBeginUser; 115 ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 116 ierr = PetscFECreateDefault(comm, dim, dim, simplex, "velocity_", -1, &fe);CHKERRQ(ierr); 117 ierr = PetscObjectSetName((PetscObject) fe, "velocity");CHKERRQ(ierr); 118 ierr = DMSetField(dm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 119 ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 120 ierr = PetscFECreateDefault(comm, dim, 1, simplex, "pressure_", -1, &fe);CHKERRQ(ierr); 121 ierr = PetscObjectSetName((PetscObject) fe, "pressure");CHKERRQ(ierr); 122 ierr = DMSetField(dm, 1, NULL, (PetscObject) fe);CHKERRQ(ierr); 123 ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 124 ierr = DMCreateDS(dm);CHKERRQ(ierr); 125 PetscFunctionReturn(0); 126 } 127 128 static PetscErrorCode SetupOutputDiscretization(DM dm, PetscInt dim, PetscBool simplex, AppCtx *user) 129 { 130 PetscFE fe; 131 MPI_Comm comm; 132 PetscErrorCode ierr; 133 134 PetscFunctionBeginUser; 135 ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 136 ierr = PetscFECreateDefault(comm, dim, dim, simplex, "output_", -1, &fe);CHKERRQ(ierr); 137 ierr = PetscObjectSetName((PetscObject) fe, "output");CHKERRQ(ierr); 138 ierr = DMSetField(dm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 139 ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 140 ierr = DMCreateDS(dm);CHKERRQ(ierr); 141 PetscFunctionReturn(0); 142 } 143 144 static PetscErrorCode CreateSubdomainMesh(DM dm, DMLabel *domLabel, DM *subdm, AppCtx *user) 145 { 146 DMLabel label; 147 PetscInt dim, cStart, cEnd, c; 148 PetscErrorCode ierr; 149 150 PetscFunctionBeginUser; 151 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 152 ierr = DMLabelCreate(PETSC_COMM_SELF, "subdomain", &label);CHKERRQ(ierr); 153 for (c = cStart + (cEnd-cStart)/2; c < cEnd; ++c) {ierr = DMLabelSetValue(label, c, 1);CHKERRQ(ierr);} 154 ierr = DMPlexFilter(dm, label, 1, subdm);CHKERRQ(ierr); 155 ierr = DMGetDimension(*subdm, &dim);CHKERRQ(ierr); 156 ierr = SetupDiscretization(*subdm, dim, user->cellSimplex, user);CHKERRQ(ierr); 157 ierr = PetscObjectSetName((PetscObject) *subdm, "subdomain");CHKERRQ(ierr); 158 ierr = DMViewFromOptions(*subdm, NULL, "-sub_dm_view");CHKERRQ(ierr); 159 if (domLabel) *domLabel = label; 160 else {ierr = DMLabelDestroy(&label);CHKERRQ(ierr);} 161 PetscFunctionReturn(0); 162 } 163 164 static PetscErrorCode CreateBoundaryMesh(DM dm, DMLabel *bdLabel, DM *subdm, AppCtx *user) 165 { 166 DMLabel label; 167 PetscInt dim; 168 PetscErrorCode ierr; 169 170 PetscFunctionBeginUser; 171 ierr = DMLabelCreate(PETSC_COMM_SELF, "sub", &label);CHKERRQ(ierr); 172 ierr = DMPlexMarkBoundaryFaces(dm, 1, label);CHKERRQ(ierr); 173 ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); 174 ierr = DMPlexCreateSubmesh(dm, label, 1, PETSC_TRUE, subdm);CHKERRQ(ierr); 175 ierr = DMGetDimension(*subdm, &dim);CHKERRQ(ierr); 176 ierr = SetupDiscretization(*subdm, dim, user->cellSimplex, user);CHKERRQ(ierr); 177 ierr = PetscObjectSetName((PetscObject) *subdm, "boundary");CHKERRQ(ierr); 178 ierr = DMViewFromOptions(*subdm, NULL, "-sub_dm_view");CHKERRQ(ierr); 179 if (bdLabel) *bdLabel = label; 180 else {ierr = DMLabelDestroy(&label);CHKERRQ(ierr);} 181 PetscFunctionReturn(0); 182 } 183 184 static PetscErrorCode CreateAuxiliaryData(DM dm, DM *auxdm, Vec *la, AppCtx *user) 185 { 186 PetscErrorCode (**afuncs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *); 187 PetscInt dim, Nf, f; 188 PetscErrorCode ierr; 189 190 PetscFunctionBeginUser; 191 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 192 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 193 ierr = PetscMalloc1(Nf, &afuncs);CHKERRQ(ierr); 194 for (f = 0; f < Nf; ++f) afuncs[f] = linear; 195 ierr = DMClone(dm, auxdm);CHKERRQ(ierr); 196 ierr = SetupDiscretization(*auxdm, dim, user->cellSimplex, user);CHKERRQ(ierr); 197 ierr = DMCreateLocalVector(*auxdm, la);CHKERRQ(ierr); 198 ierr = DMProjectFunctionLocal(dm, 0.0, afuncs, NULL, INSERT_VALUES, *la);CHKERRQ(ierr); 199 ierr = VecViewFromOptions(*la, NULL, "-local_aux_view");CHKERRQ(ierr); 200 ierr = PetscFree(afuncs);CHKERRQ(ierr); 201 PetscFunctionReturn(0); 202 } 203 204 static PetscErrorCode TestFunctionProjection(DM dm, DM dmAux, DMLabel label, Vec la, const char name[], AppCtx *user) 205 { 206 PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *); 207 Vec x, lx; 208 PetscInt Nf, f; 209 PetscInt val[1] = {1}; 210 char lname[PETSC_MAX_PATH_LEN]; 211 PetscErrorCode ierr; 212 213 PetscFunctionBeginUser; 214 if (dmAux) { 215 ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAux);CHKERRQ(ierr); 216 ierr = PetscObjectCompose((PetscObject) dm, "A", (PetscObject) la);CHKERRQ(ierr); 217 } 218 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 219 ierr = PetscMalloc1(Nf, &funcs);CHKERRQ(ierr); 220 for (f = 0; f < Nf; ++f) funcs[f] = linear; 221 ierr = DMGetGlobalVector(dm, &x);CHKERRQ(ierr); 222 ierr = PetscStrcpy(lname, "Function ");CHKERRQ(ierr); 223 ierr = PetscStrcat(lname, name);CHKERRQ(ierr); 224 ierr = PetscObjectSetName((PetscObject) x, lname);CHKERRQ(ierr); 225 if (!label) {ierr = DMProjectFunction(dm, 0.0, funcs, NULL, INSERT_VALUES, x);CHKERRQ(ierr);} 226 else {ierr = DMProjectFunctionLabel(dm, 0.0, label, 1, val, 0, NULL, funcs, NULL, INSERT_VALUES, x);CHKERRQ(ierr);} 227 ierr = VecViewFromOptions(x, NULL, "-func_view");CHKERRQ(ierr); 228 ierr = DMRestoreGlobalVector(dm, &x);CHKERRQ(ierr); 229 ierr = DMGetLocalVector(dm, &lx);CHKERRQ(ierr); 230 ierr = PetscStrcpy(lname, "Local Function ");CHKERRQ(ierr); 231 ierr = PetscStrcat(lname, name);CHKERRQ(ierr); 232 ierr = PetscObjectSetName((PetscObject) lx, lname);CHKERRQ(ierr); 233 if (!label) {ierr = DMProjectFunctionLocal(dm, 0.0, funcs, NULL, INSERT_VALUES, lx);CHKERRQ(ierr);} 234 else {ierr = DMProjectFunctionLabelLocal(dm, 0.0, label, 1, val, 0, NULL, funcs, NULL, INSERT_VALUES, lx);CHKERRQ(ierr);} 235 ierr = VecViewFromOptions(lx, NULL, "-local_func_view");CHKERRQ(ierr); 236 ierr = DMRestoreLocalVector(dm, &lx);CHKERRQ(ierr); 237 ierr = PetscFree(funcs);CHKERRQ(ierr); 238 if (dmAux) { 239 ierr = PetscObjectCompose((PetscObject) dm, "dmAux", NULL);CHKERRQ(ierr); 240 ierr = PetscObjectCompose((PetscObject) dm, "A", NULL);CHKERRQ(ierr); 241 } 242 PetscFunctionReturn(0); 243 } 244 245 static PetscErrorCode TestFieldProjection(DM dm, DM dmAux, DMLabel label, Vec la, const char name[], AppCtx *user) 246 { 247 PetscErrorCode (**afuncs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *); 248 void (**funcs)(PetscInt, PetscInt, PetscInt, 249 const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 250 const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 251 PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]); 252 Vec lx, lu; 253 PetscInt Nf, f; 254 PetscInt val[1] = {1}; 255 char lname[PETSC_MAX_PATH_LEN]; 256 PetscErrorCode ierr; 257 258 PetscFunctionBeginUser; 259 if (dmAux) { 260 ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAux);CHKERRQ(ierr); 261 ierr = PetscObjectCompose((PetscObject) dm, "A", (PetscObject) la);CHKERRQ(ierr); 262 } 263 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 264 ierr = PetscMalloc2(Nf, &funcs, Nf, &afuncs);CHKERRQ(ierr); 265 for (f = 0; f < Nf; ++f) afuncs[f] = linear; 266 funcs[0] = linear_vector; 267 funcs[1] = linear_scalar; 268 ierr = DMGetLocalVector(dm, &lu);CHKERRQ(ierr); 269 ierr = PetscStrcpy(lname, "Local Field Input ");CHKERRQ(ierr); 270 ierr = PetscStrcat(lname, name);CHKERRQ(ierr); 271 ierr = PetscObjectSetName((PetscObject) lu, lname);CHKERRQ(ierr); 272 if (!label) {ierr = DMProjectFunctionLocal(dm, 0.0, afuncs, NULL, INSERT_VALUES, lu);CHKERRQ(ierr);} 273 else {ierr = DMProjectFunctionLabelLocal(dm, 0.0, label, 1, val, 0, NULL, afuncs, NULL, INSERT_VALUES, lu);CHKERRQ(ierr);} 274 ierr = VecViewFromOptions(lu, NULL, "-local_input_view");CHKERRQ(ierr); 275 ierr = DMGetLocalVector(dm, &lx);CHKERRQ(ierr); 276 ierr = PetscStrcpy(lname, "Local Field ");CHKERRQ(ierr); 277 ierr = PetscStrcat(lname, name);CHKERRQ(ierr); 278 ierr = PetscObjectSetName((PetscObject) lx, lname);CHKERRQ(ierr); 279 if (!label) {ierr = DMProjectFieldLocal(dm, 0.0, lu, funcs, INSERT_VALUES, lx);CHKERRQ(ierr);} 280 else {ierr = DMProjectFieldLabelLocal(dm, 0.0, label, 1, val, 0, NULL, lu, funcs, INSERT_VALUES, lx);CHKERRQ(ierr);} 281 ierr = VecViewFromOptions(lx, NULL, "-local_field_view");CHKERRQ(ierr); 282 ierr = DMRestoreLocalVector(dm, &lx);CHKERRQ(ierr); 283 ierr = DMRestoreLocalVector(dm, &lu);CHKERRQ(ierr); 284 ierr = PetscFree2(funcs, afuncs);CHKERRQ(ierr); 285 if (dmAux) { 286 ierr = PetscObjectCompose((PetscObject) dm, "dmAux", NULL);CHKERRQ(ierr); 287 ierr = PetscObjectCompose((PetscObject) dm, "A", NULL);CHKERRQ(ierr); 288 } 289 PetscFunctionReturn(0); 290 } 291 292 static PetscErrorCode TestFieldProjectionMultiple(DM dm, DM dmIn, DM dmAux, DMLabel label, Vec la, const char name[], AppCtx *user) 293 { 294 PetscErrorCode (**afuncs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *); 295 void (**funcs)(PetscInt, PetscInt, PetscInt, 296 const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 297 const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 298 PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]); 299 Vec lx, lu; 300 PetscInt Nf, NfIn; 301 PetscInt val[1] = {1}; 302 char lname[PETSC_MAX_PATH_LEN]; 303 PetscErrorCode ierr; 304 305 PetscFunctionBeginUser; 306 if (dmAux) { 307 ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAux);CHKERRQ(ierr); 308 ierr = PetscObjectCompose((PetscObject) dm, "A", (PetscObject) la);CHKERRQ(ierr); 309 } 310 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 311 ierr = DMGetNumFields(dmIn, &NfIn);CHKERRQ(ierr); 312 ierr = PetscMalloc2(Nf, &funcs, NfIn, &afuncs);CHKERRQ(ierr); 313 funcs[0] = divergence_sq; 314 afuncs[0] = linear2; 315 afuncs[1] = linear; 316 ierr = DMGetLocalVector(dmIn, &lu);CHKERRQ(ierr); 317 ierr = PetscStrcpy(lname, "Local MultiField Input ");CHKERRQ(ierr); 318 ierr = PetscStrcat(lname, name);CHKERRQ(ierr); 319 ierr = PetscObjectSetName((PetscObject) lu, lname);CHKERRQ(ierr); 320 if (!label) {ierr = DMProjectFunctionLocal(dmIn, 0.0, afuncs, NULL, INSERT_VALUES, lu);CHKERRQ(ierr);} 321 else {ierr = DMProjectFunctionLabelLocal(dmIn, 0.0, label, 1, val, 0, NULL, afuncs, NULL, INSERT_VALUES, lu);CHKERRQ(ierr);} 322 ierr = VecViewFromOptions(lu, NULL, "-local_input_view");CHKERRQ(ierr); 323 ierr = DMGetLocalVector(dm, &lx);CHKERRQ(ierr); 324 ierr = PetscStrcpy(lname, "Local MultiField ");CHKERRQ(ierr); 325 ierr = PetscStrcat(lname, name);CHKERRQ(ierr); 326 ierr = PetscObjectSetName((PetscObject) lx, lname);CHKERRQ(ierr); 327 if (!label) {ierr = DMProjectFieldLocal(dm, 0.0, lu, funcs, INSERT_VALUES, lx);CHKERRQ(ierr);} 328 else {ierr = DMProjectFieldLabelLocal(dm, 0.0, label, 1, val, 0, NULL, lu, funcs, INSERT_VALUES, lx);CHKERRQ(ierr);} 329 ierr = VecViewFromOptions(lx, NULL, "-local_field_view");CHKERRQ(ierr); 330 ierr = DMRestoreLocalVector(dm, &lx);CHKERRQ(ierr); 331 ierr = DMRestoreLocalVector(dmIn, &lu);CHKERRQ(ierr); 332 ierr = PetscFree2(funcs, afuncs);CHKERRQ(ierr); 333 if (dmAux) { 334 ierr = PetscObjectCompose((PetscObject) dm, "dmAux", NULL);CHKERRQ(ierr); 335 ierr = PetscObjectCompose((PetscObject) dm, "A", NULL);CHKERRQ(ierr); 336 } 337 PetscFunctionReturn(0); 338 } 339 340 int main(int argc, char **argv) 341 { 342 DM dm, subdm, auxdm; 343 Vec la; 344 AppCtx user; 345 PetscErrorCode ierr; 346 347 ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; 348 ierr = ProcessOptions(&user);CHKERRQ(ierr); 349 ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); 350 ierr = SetupDiscretization(dm, user.dim, user.cellSimplex, &user);CHKERRQ(ierr); 351 /* Volumetric Mesh Projection */ 352 if (!user.multifield) { 353 ierr = TestFunctionProjection(dm, NULL, NULL, NULL, "Volumetric Primary", &user);CHKERRQ(ierr); 354 ierr = TestFieldProjection(dm, NULL, NULL, NULL, "Volumetric Primary", &user);CHKERRQ(ierr); 355 } else { 356 DM dmOut; 357 358 ierr = DMClone(dm, &dmOut);CHKERRQ(ierr); 359 ierr = SetupOutputDiscretization(dmOut, user.dim, user.cellSimplex, &user);CHKERRQ(ierr); 360 ierr = TestFieldProjectionMultiple(dmOut, dm, NULL, NULL, NULL, "Volumetric Primary", &user);CHKERRQ(ierr); 361 ierr = DMDestroy(&dmOut);CHKERRQ(ierr); 362 } 363 if (user.auxfield) { 364 /* Volumetric Mesh Projection with Volumetric Data */ 365 ierr = CreateAuxiliaryData(dm, &auxdm, &la, &user);CHKERRQ(ierr); 366 ierr = TestFunctionProjection(dm, auxdm, NULL, la, "Volumetric Primary and Volumetric Auxiliary", &user);CHKERRQ(ierr); 367 ierr = TestFieldProjection(dm, auxdm, NULL, la, "Volumetric Primary and Volumetric Auxiliary", &user);CHKERRQ(ierr); 368 ierr = VecDestroy(&la);CHKERRQ(ierr); 369 /* Update of Volumetric Auxiliary Data with primary Volumetric Data */ 370 ierr = DMGetLocalVector(dm, &la);CHKERRQ(ierr); 371 ierr = VecSet(la, 1.0);CHKERRQ(ierr); 372 ierr = TestFieldProjection(auxdm, dm, NULL, la, "Volumetric Auxiliary Update with Volumetric Primary", &user);CHKERRQ(ierr); 373 ierr = DMRestoreLocalVector(dm, &la);CHKERRQ(ierr); 374 ierr = DMDestroy(&auxdm);CHKERRQ(ierr); 375 } 376 if (user.subdomain) { 377 DMLabel domLabel; 378 379 /* Subdomain Mesh Projection */ 380 ierr = CreateSubdomainMesh(dm, &domLabel, &subdm, &user);CHKERRQ(ierr); 381 ierr = TestFunctionProjection(subdm, NULL, NULL, NULL, "Subdomain Primary", &user);CHKERRQ(ierr); 382 ierr = TestFieldProjection(subdm, NULL, NULL, NULL, "Subdomain Primary", &user);CHKERRQ(ierr); 383 if (user.auxfield) { 384 /* Subdomain Mesh Projection with Subdomain Data */ 385 ierr = CreateAuxiliaryData(subdm, &auxdm, &la, &user);CHKERRQ(ierr); 386 ierr = TestFunctionProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Subdomain Auxiliary", &user);CHKERRQ(ierr); 387 ierr = TestFieldProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Subdomain Auxiliary", &user);CHKERRQ(ierr); 388 ierr = VecDestroy(&la);CHKERRQ(ierr); 389 ierr = DMDestroy(&auxdm);CHKERRQ(ierr); 390 /* Subdomain Mesh Projection with Volumetric Data */ 391 ierr = CreateAuxiliaryData(dm, &auxdm, &la, &user);CHKERRQ(ierr); 392 ierr = TestFunctionProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Volumetric Auxiliary", &user);CHKERRQ(ierr); 393 ierr = TestFieldProjection(subdm, auxdm, NULL, la, "Subdomain Primary and Volumetric Auxiliary", &user);CHKERRQ(ierr); 394 ierr = VecDestroy(&la);CHKERRQ(ierr); 395 ierr = DMDestroy(&auxdm);CHKERRQ(ierr); 396 /* Volumetric Mesh Projection with Subdomain Data */ 397 ierr = CreateAuxiliaryData(subdm, &auxdm, &la, &user);CHKERRQ(ierr); 398 ierr = TestFunctionProjection(subdm, auxdm, domLabel, la, "Volumetric Primary and Subdomain Auxiliary", &user);CHKERRQ(ierr); 399 ierr = TestFieldProjection(subdm, auxdm, domLabel, la, "Volumetric Primary and Subdomain Auxiliary", &user);CHKERRQ(ierr); 400 ierr = VecDestroy(&la);CHKERRQ(ierr); 401 ierr = DMDestroy(&auxdm);CHKERRQ(ierr); 402 } 403 ierr = DMDestroy(&subdm);CHKERRQ(ierr); 404 ierr = DMLabelDestroy(&domLabel);CHKERRQ(ierr); 405 } 406 if (user.submesh) { 407 DMLabel bdLabel; 408 409 /* Boundary Mesh Projection */ 410 ierr = CreateBoundaryMesh(dm, &bdLabel, &subdm, &user);CHKERRQ(ierr); 411 ierr = TestFunctionProjection(subdm, NULL, NULL, NULL, "Boundary Primary", &user);CHKERRQ(ierr); 412 ierr = TestFieldProjection(subdm, NULL, NULL, NULL, "Boundary Primary", &user);CHKERRQ(ierr); 413 if (user.auxfield) { 414 /* Boundary Mesh Projection with Boundary Data */ 415 ierr = CreateAuxiliaryData(subdm, &auxdm, &la, &user);CHKERRQ(ierr); 416 ierr = TestFunctionProjection(subdm, auxdm, NULL, la, "Boundary Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); 417 ierr = TestFieldProjection(subdm, auxdm, NULL, la, "Boundary Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); 418 ierr = VecDestroy(&la);CHKERRQ(ierr); 419 ierr = DMDestroy(&auxdm);CHKERRQ(ierr); 420 /* Volumetric Mesh Projection with Boundary Data */ 421 ierr = CreateAuxiliaryData(subdm, &auxdm, &la, &user);CHKERRQ(ierr); 422 ierr = TestFunctionProjection(dm, auxdm, bdLabel, la, "Volumetric Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); 423 ierr = TestFieldProjection(dm, auxdm, bdLabel, la, "Volumetric Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); 424 ierr = VecDestroy(&la);CHKERRQ(ierr); 425 ierr = DMDestroy(&auxdm);CHKERRQ(ierr); 426 } 427 ierr = DMLabelDestroy(&bdLabel);CHKERRQ(ierr); 428 ierr = DMDestroy(&subdm);CHKERRQ(ierr); 429 } 430 ierr = DMDestroy(&dm);CHKERRQ(ierr); 431 ierr = PetscFinalize(); 432 return ierr; 433 } 434 435 /*TEST 436 437 test: 438 suffix: 0 439 requires: triangle 440 args: -dim 2 -func_view -local_func_view -local_input_view -local_field_view 441 test: 442 suffix: mf_0 443 requires: triangle 444 args: -dim 2 -velocity_petscspace_degree 1 -velocity_petscfe_default_quadrature_order 2 \ 445 -pressure_petscspace_degree 2 -pressure_petscfe_default_quadrature_order 2 \ 446 -multifield -output_petscspace_degree 1 -output_petscfe_default_quadrature_order 2 \ 447 -local_input_view -local_field_view 448 test: 449 suffix: 1 450 requires: triangle 451 args: -dim 2 -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 452 test: 453 suffix: 2 454 requires: triangle 455 args: -dim 2 -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 456 457 TEST*/ 458 459 /* 460 Post-processing wants to project a function of the fields into some FE space 461 - This is DMProjectField() 462 - What about changing the number of components of the output, like displacement to stress? Aux vars 463 464 Update of state variables 465 - This is DMProjectField(), but solution must be the aux var 466 */ 467