1*3d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2*3d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3*3d8e8822SJeremy L Thompson // 4*3d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5*3d8e8822SJeremy L Thompson // 6*3d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7*3d8e8822SJeremy L Thompson 85754ecacSJeremy L Thompson /// @file 95754ecacSJeremy L Thompson /// DM setup for solid mechanics example using PETSc 105754ecacSJeremy L Thompson 115754ecacSJeremy L Thompson #include "../include/boundary.h" 125754ecacSJeremy L Thompson #include "../include/setup-dm.h" 135754ecacSJeremy L Thompson 145754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 155754ecacSJeremy L Thompson // Setup DM 165754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 175754ecacSJeremy L Thompson PetscErrorCode CreateBCLabel(DM dm, const char name[]) { 185754ecacSJeremy L Thompson PetscErrorCode ierr; 195754ecacSJeremy L Thompson DMLabel label; 205754ecacSJeremy L Thompson 215754ecacSJeremy L Thompson PetscFunctionBeginUser; 225754ecacSJeremy L Thompson 235754ecacSJeremy L Thompson ierr = DMCreateLabel(dm, name); CHKERRQ(ierr); 245754ecacSJeremy L Thompson ierr = DMGetLabel(dm, name, &label); CHKERRQ(ierr); 255754ecacSJeremy L Thompson ierr = DMPlexMarkBoundaryFaces(dm, 1, label); CHKERRQ(ierr); 265754ecacSJeremy L Thompson 275754ecacSJeremy L Thompson PetscFunctionReturn(0); 285754ecacSJeremy L Thompson }; 295754ecacSJeremy L Thompson 305754ecacSJeremy L Thompson // Read mesh and distribute DM in parallel 315754ecacSJeremy L Thompson PetscErrorCode CreateDistributedDM(MPI_Comm comm, AppCtx app_ctx, DM *dm) { 325754ecacSJeremy L Thompson PetscErrorCode ierr; 335754ecacSJeremy L Thompson const char *filename = app_ctx->mesh_file; 345754ecacSJeremy L Thompson PetscBool interpolate = PETSC_TRUE; 355754ecacSJeremy L Thompson DM distributed_mesh = NULL; 365754ecacSJeremy L Thompson PetscPartitioner part; 375754ecacSJeremy L Thompson 385754ecacSJeremy L Thompson PetscFunctionBeginUser; 395754ecacSJeremy L Thompson 405754ecacSJeremy L Thompson if (!*filename) { 415754ecacSJeremy L Thompson PetscInt dim = 3, faces[3] = {3, 3, 3}; 425754ecacSJeremy L Thompson ierr = PetscOptionsGetIntArray(NULL, NULL, "-dm_plex_box_faces", 435754ecacSJeremy L Thompson faces, &dim, NULL); CHKERRQ(ierr); 4420e46440SLeila Ghaffari if (!dim) dim = 3; 455754ecacSJeremy L Thompson ierr = DMPlexCreateBoxMesh(comm, dim, PETSC_FALSE, faces, NULL, 465754ecacSJeremy L Thompson NULL, NULL, interpolate, dm); CHKERRQ(ierr); 475754ecacSJeremy L Thompson } else { 487ed3e4cdSJeremy L Thompson ierr = DMPlexCreateFromFile(comm, filename, NULL, interpolate, dm); 497ed3e4cdSJeremy L Thompson CHKERRQ(ierr); 505754ecacSJeremy L Thompson } 515754ecacSJeremy L Thompson 525754ecacSJeremy L Thompson // Distribute DM in parallel 535754ecacSJeremy L Thompson ierr = DMPlexGetPartitioner(*dm, &part); CHKERRQ(ierr); 545754ecacSJeremy L Thompson ierr = PetscPartitionerSetFromOptions(part); CHKERRQ(ierr); 555754ecacSJeremy L Thompson ierr = DMPlexDistribute(*dm, 0, NULL, &distributed_mesh); CHKERRQ(ierr); 565754ecacSJeremy L Thompson if (distributed_mesh) { 575754ecacSJeremy L Thompson ierr = DMDestroy(dm); CHKERRQ(ierr); 585754ecacSJeremy L Thompson *dm = distributed_mesh; 595754ecacSJeremy L Thompson } 605754ecacSJeremy L Thompson ierr = DMViewFromOptions(*dm, NULL, "-dm_view"); CHKERRQ(ierr); 615754ecacSJeremy L Thompson 625754ecacSJeremy L Thompson PetscFunctionReturn(0); 635754ecacSJeremy L Thompson }; 645754ecacSJeremy L Thompson 655754ecacSJeremy L Thompson // Setup DM with FE space of appropriate degree 665754ecacSJeremy L Thompson PetscErrorCode SetupDMByDegree(DM dm, AppCtx app_ctx, PetscInt order, 675754ecacSJeremy L Thompson PetscBool boundary, PetscInt num_comp_u) { 685754ecacSJeremy L Thompson PetscErrorCode ierr; 6965233696SJeremy L Thompson MPI_Comm comm; 705754ecacSJeremy L Thompson PetscInt dim; 715754ecacSJeremy L Thompson PetscFE fe; 725754ecacSJeremy L Thompson IS face_set_is; // Index Set for Face Sets 735754ecacSJeremy L Thompson const char *name = "Face Sets"; // PETSc internal requirement 745754ecacSJeremy L Thompson PetscInt num_face_sets; // Number of FaceSets in face_set_is 755754ecacSJeremy L Thompson const PetscInt *face_set_ids; // id of each FaceSet 765754ecacSJeremy L Thompson 775754ecacSJeremy L Thompson PetscFunctionBeginUser; 785754ecacSJeremy L Thompson 795754ecacSJeremy L Thompson // Setup DM 805754ecacSJeremy L Thompson ierr = DMGetDimension(dm, &dim); CHKERRQ(ierr); 8165233696SJeremy L Thompson ierr = PetscObjectGetComm((PetscObject)dm, &comm); CHKERRQ(ierr); 8265233696SJeremy L Thompson ierr = PetscFECreateLagrange(comm, dim, num_comp_u, PETSC_FALSE, order, order, 8365233696SJeremy L Thompson &fe); CHKERRQ(ierr); 845754ecacSJeremy L Thompson ierr = DMSetFromOptions(dm); CHKERRQ(ierr); 855754ecacSJeremy L Thompson ierr = DMAddField(dm, NULL, (PetscObject)fe); CHKERRQ(ierr); 865754ecacSJeremy L Thompson ierr = DMCreateDS(dm); CHKERRQ(ierr); 877ed3e4cdSJeremy L Thompson { 887ed3e4cdSJeremy L Thompson /* create FE field for coordinates */ 897ed3e4cdSJeremy L Thompson PetscFE fe_coords; 907ed3e4cdSJeremy L Thompson PetscInt num_comp_coord; 917ed3e4cdSJeremy L Thompson ierr = DMGetCoordinateDim(dm, &num_comp_coord); CHKERRQ(ierr); 927ed3e4cdSJeremy L Thompson ierr = PetscFECreateLagrange(comm, dim, num_comp_coord, PETSC_FALSE, 1, 1, 937ed3e4cdSJeremy L Thompson &fe_coords); CHKERRQ(ierr); 947ed3e4cdSJeremy L Thompson ierr = DMProjectCoordinates(dm, fe_coords); CHKERRQ(ierr); 957ed3e4cdSJeremy L Thompson ierr = PetscFEDestroy(&fe_coords); CHKERRQ(ierr); 967ed3e4cdSJeremy L Thompson } 975754ecacSJeremy L Thompson 985754ecacSJeremy L Thompson // Add Dirichlet (Essential) boundary 995754ecacSJeremy L Thompson if (boundary) { 1005754ecacSJeremy L Thompson if (app_ctx->forcing_choice == FORCE_MMS) { 1015754ecacSJeremy L Thompson if (app_ctx->test_mode) { 1025754ecacSJeremy L Thompson // -- Test mode - box mesh 1035754ecacSJeremy L Thompson PetscBool has_label; 1045754ecacSJeremy L Thompson PetscInt marker_ids[1] = {1}; 1055754ecacSJeremy L Thompson ierr = DMHasLabel(dm, "marker", &has_label); CHKERRQ(ierr); 1065754ecacSJeremy L Thompson if (!has_label) { 1075754ecacSJeremy L Thompson ierr = CreateBCLabel(dm, "marker"); CHKERRQ(ierr); 1085754ecacSJeremy L Thompson } 1095754ecacSJeremy L Thompson DMLabel label; 1105754ecacSJeremy L Thompson ierr = DMGetLabel(dm, "marker", &label); CHKERRQ(ierr); 111b8962995SJeremy L Thompson ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "mms", label, 1, marker_ids, 1125754ecacSJeremy L Thompson 0, 0, NULL, (void(*)(void))BCMMS, NULL, NULL, NULL); 1135754ecacSJeremy L Thompson CHKERRQ(ierr); 1145754ecacSJeremy L Thompson } else { 1155754ecacSJeremy L Thompson // -- ExodusII mesh with MMS 1165754ecacSJeremy L Thompson ierr = DMGetLabelIdIS(dm, name, &face_set_is); CHKERRQ(ierr); 1175754ecacSJeremy L Thompson ierr = ISGetSize(face_set_is,&num_face_sets); CHKERRQ(ierr); 1185754ecacSJeremy L Thompson ierr = ISGetIndices(face_set_is, &face_set_ids); CHKERRQ(ierr); 1195754ecacSJeremy L Thompson DMLabel label; 1205754ecacSJeremy L Thompson ierr = DMGetLabel(dm, "Face Sets", &label); CHKERRQ(ierr); 121b8962995SJeremy L Thompson ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "mms", label, 1225754ecacSJeremy L Thompson num_face_sets, face_set_ids, 0, 0, NULL, 1235754ecacSJeremy L Thompson (void(*)(void))BCMMS, NULL, NULL, NULL); 1245754ecacSJeremy L Thompson CHKERRQ(ierr); 1255754ecacSJeremy L Thompson ierr = ISRestoreIndices(face_set_is, &face_set_ids); CHKERRQ(ierr); 1265754ecacSJeremy L Thompson ierr = ISDestroy(&face_set_is); CHKERRQ(ierr); 1275754ecacSJeremy L Thompson } 1285754ecacSJeremy L Thompson } else { 1297ed3e4cdSJeremy L Thompson // -- Mesh with user specified BCs 1305754ecacSJeremy L Thompson DMLabel label; 1315754ecacSJeremy L Thompson ierr = DMGetLabel(dm, "Face Sets", &label); CHKERRQ(ierr); 1327ed3e4cdSJeremy L Thompson // -- Clamp BCs 1335754ecacSJeremy L Thompson for (PetscInt i = 0; i < app_ctx->bc_clamp_count; i++) { 1345754ecacSJeremy L Thompson char bcName[25]; 1355754ecacSJeremy L Thompson snprintf(bcName, sizeof bcName, "clamp_%d", app_ctx->bc_clamp_faces[i]); 136b8962995SJeremy L Thompson ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, bcName, label, 1, 1375754ecacSJeremy L Thompson &app_ctx->bc_clamp_faces[i], 0, 0, 1385754ecacSJeremy L Thompson NULL, (void(*)(void))BCClamp, NULL, 1395754ecacSJeremy L Thompson (void *)&app_ctx->bc_clamp_max[i], NULL); 1405754ecacSJeremy L Thompson CHKERRQ(ierr); 1415754ecacSJeremy L Thompson } 1425754ecacSJeremy L Thompson } 1435754ecacSJeremy L Thompson } 1445754ecacSJeremy L Thompson ierr = DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, NULL); 1455754ecacSJeremy L Thompson CHKERRQ(ierr); 1465754ecacSJeremy L Thompson 1475754ecacSJeremy L Thompson // Cleanup 1485754ecacSJeremy L Thompson ierr = PetscFEDestroy(&fe); CHKERRQ(ierr); 1495754ecacSJeremy L Thompson 1505754ecacSJeremy L Thompson PetscFunctionReturn(0); 1515754ecacSJeremy L Thompson }; 152