[petsc-users] PETSc :: FEM Help

Brandon Denton bldenton at buffalo.edu
Wed Jun 7 10:04:41 CDT 2023


Good Morning,

I'm trying to verify that the CAD -> PETSc/DMPlex methods I've developed
can be used for FEM analyses using PETSc. Attached is my current attempt
where I import a CAD STEP file to create a volumetric tetrahedral
discretization (DMPlex),  designate boundary condition points using
DMLabels, and solve the Laplace problem (heat) with Dirichlet conditions on
each end. At command line I indicate the STEP file with the -filename
option and the dual space degree with -petscspace_degree 2. The run ends
with either a SEGV Fault or a General MPI Communication Error.

Could you please look over the attached file to tell me if what I'm doing
to set up the FEM problem is wrong?

Thank you in advance for your time and help.
-Brandon

TYPICAL ERROR MESSAGE
[0]PETSC ERROR: --------------------- Error Message
--------------------------------------------------------------
[0]PETSC ERROR: General MPI error
[0]PETSC ERROR: MPI error 605109765 Invalid communicator, error stack:
                PMPI_Comm_get_attr(344): MPI_Comm_get_attr(comm=0x0,
comm_keyval=-1539309568, attribute_val=0x7ffe75a58848, flag=0x7ffe75a58844)
failed
                MPII_Comm_get_attr(257): MPIR_Comm_get_attr(comm=0x0,
comm_keyval=-1539309568, attribute_val=0x7ffe75a58848, flag=0x7ffe75a58844)
failed
                MPII_Comm_get_attr(53).: Invalid communicator
[0]PETSC ERROR: WARNING! There are option(s) set that were not used! Could
be the program crashed before they were used or a spelling mistake, etc!
[0]PETSC ERROR:   Option left: name:-dm_plex_refine_without_snap_to_geom
value: 0 source: command line
[0]PETSC ERROR:   Option left: name:-dm_refine value: 1 source: command line
[0]PETSC ERROR:   Option left: name:-snes_monitor (no value) source:
command line
[0]PETSC ERROR: See https://petsc.org/release/faq/ for trouble shooting.
[0]PETSC ERROR: Petsc Development GIT revision: v3.18.5-1817-gd2497b8de4c
GIT Date: 2023-05-22 18:44:03 +0000
[0]PETSC ERROR: ./thermal on a  named XPS. by bdenton Wed Jun  7 11:03:43
2023
[0]PETSC ERROR: Configure options --with-make-np=16
--prefix=/mnt/c/Users/Brandon/software/libs/petsc/3.19.1-gitlab/gcc/11.2.0/mpich/3.4.2/openblas/0.3.17/opt
--with-debugging=false --COPTFLAGS="-O3 -mavx" --CXXOPTFLAGS="-O3 -mavx"
--FOPTFLAGS=-O3 --with-shared-libraries=1
--with-mpi-dir=/mnt/c/Users/Brandon/software/libs/mpich/3.4.2/gcc/11.2.0
--with-mumps=true --download-mumps=1 --with-metis=true --download-metis=1
--with-parmetis=true --download-parmetis=1 --with-superlu=true
--download-superlu=1 --with-superludir=true --download-superlu_dist=1
--with-blacs=true --download-blacs=1 --with-scalapack=true
--download-scalapack=1 --with-hypre=true --download-hypre=1
--with-hdf5-dir=/mnt/c/Users/Brandon/software/libs/hdf5/1.12.1/gcc/11.2.0
--with-valgrind-dir=/mnt/c/Users/Brandon/software/apps/valgrind/3.14.0
--with-blas-lib="[/mnt/c/Users/Brandon/software/libs/openblas/0.3.17/gcc/11.2.0/lib/libopenblas.so]"
--with-lapack-lib="[/mnt/c/Users/Brandon/software/libs/openblas/0.3.17/gcc/11.2.0/lib/libopenblas.so]"
--LDFLAGS= --with-tetgen=true --download-tetgen=1 --download-ctetgen=1
--download-opencascade=1 --download-egads
[0]PETSC ERROR: #1 PetscObjectName() at
/mnt/c/Users/Brandon/software/builddir/petsc-3.19.1-gitlab/src/sys/objects/pname.c:119
[0]PETSC ERROR: #2 PetscObjectGetName() at
/mnt/c/Users/Brandon/software/builddir/petsc-3.19.1-gitlab/src/sys/objects/pgname.c:27
[0]PETSC ERROR: #3 PetscDSAddBoundary() at
/mnt/c/Users/Brandon/software/builddir/petsc-3.19.1-gitlab/src/dm/dt/interface/dtds.c:3404
[0]PETSC ERROR: #4 DMAddBoundary() at
/mnt/c/Users/Brandon/software/builddir/petsc-3.19.1-gitlab/src/dm/interface/dm.c:7828
[0]PETSC ERROR: #5 main() at
/mnt/c/Users/Brandon/Documents/School/Dissertation/Software/EGADS-dev/thermal_v319/thermal_nozzle.c:173
[0]PETSC ERROR: PETSc Option Table entries:
[0]PETSC ERROR: -dm_plex_geom_print_model 1 (source: command line)
[0]PETSC ERROR: -dm_plex_geom_shape_opt 0 (source: command line)
[0]PETSC ERROR: -dm_plex_refine_without_snap_to_geom 0 (source: command
line)
[0]PETSC ERROR: -dm_refine 1 (source: command line)
[0]PETSC ERROR: -filename ./examples/Nozzle_example.stp (source: command
line)
[0]PETSC ERROR: -petscspace_degree 2 (source: command line)
[0]PETSC ERROR: -snes_monitor (source: command line)
[0]PETSC ERROR: ----------------End of Error Message -------send entire
error message to petsc-maint at mcs.anl.gov----------
application called MPI_Abort(MPI_COMM_SELF, 98) - process 0
[unset]: write_line error; fd=-1 buf=:cmd=abort exitcode=98
:
system msg for write_line failure : Bad file descriptor
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20230607/8a6eb394/attachment.html>
-------------- next part --------------
static const char help[] = "Test of FEA DMPlex w/CAD functionality";

#include <petsc.h>

/* User-defined Work Context  */
typedef struct {
    PetscInt  dummy;
    char filename[PETSC_MAX_PATH_LEN];    // context containing CAD filename from command line
} AppCtx;


void f0_function(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[], PetscScalar f0[])
{
  f0[0] = 0.0;
}

void f1_function(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[], PetscScalar f1[])
{
  for(PetscInt d = 0; d < dim; ++d) f1[d] = u_x[d];
}

void g3_uu_function(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[], PetscScalar g3[])
{
  for (PetscInt d=0; d < dim; ++d) g3[d*dim + d] = 1.0;
}

//void bc_inlet(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
static PetscErrorCode bc_inlet(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
{
  u[0] = 1400.0;
  return PETSC_SUCCESS;
  //bcval[0] = 1400.0;
}

//void bc_outlet(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
static PetscErrorCode bc_outlet(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
{
  u[0] = 100.0;
  return PETSC_SUCCESS;
  //bcval[0] = 100.0;
}

/* Procees Options - This should be removed once creation bug is fixed by Prof. Knepley */
static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
{
  PetscFunctionBeginUser;
  options->filename[0] = '\0';

  PetscOptionsBegin(comm, "", "FEA DMPlex w/CAD Options", "DMPlex w/CAD");
  PetscOptionsString("-filename", "The CAD/Geometry file", "ex18.c", options->filename, options->filename, PETSC_MAX_PATH_LEN, NULL);
  PetscOptionsEnd();
  PetscFunctionReturn(0);
}

/* Main Function */
int main(int argc, char **argv)
{
  // Define PETSc Variables
  DM            dm, dmSurface;    // Unstructured Grid
  SNES          snes;             // Nonlinear Solver
  Vec           temp;             // Solutions
  AppCtx        ctx;      // User-defined Work Context
  PetscInt      dim;      // DM Geometric Dimension
  PetscBool     simplex;  // Is DMPlex Simplex type?
  PetscFE       fe;       // PETSc Finite Element Object
  PetscDS       ds;       // PETSc Discretization System Object
  PetscMPIInt   rank;     // PETSc MPI Processor ID
  
  PetscFunctionBeginUser;
  PetscCall(PetscInitialize(&argc, &argv, NULL, help));   // Initialize PETSc
  PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx));      // Process Options :: Here we get the filename from the command line options

  PetscCall(DMCreate(PETSC_COMM_WORLD, &dmSurface));
  PetscCall(DMCreate(PETSC_COMM_WORLD, &dm));
  PetscCall(DMSetType(dmSurface, DMPLEX));
  PetscCall(DMSetType(dm, DMPLEX));
  
  // Create DMPlex from CAD file
  PetscCall(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));      // Get Rank of Current Processor
  if (!rank) {
    PetscCall(DMPlexCreateFromFile(PETSC_COMM_WORLD, ctx.filename, "EGADS", PETSC_TRUE, &dmSurface)); // Return dm created from CAD file
  }
  
  // Setup DMLabels for Boundary Conditions on DMPlex Vertices
  PetscInt    nStart, nEnd, eStart, eEnd, faceID;
  DMLabel     inletLabel, outletLabel;
  const PetscInt  idA = 1, idB = 2;
  
  PetscCall(DMCreateLabel(dmSurface, "inlet"));
  PetscCall(DMCreateLabel(dmSurface, "outlet"));
  PetscCall(DMGetLabel(dmSurface, "inlet", &inletLabel));
  PetscCall(DMGetLabel(dmSurface, "outlet", &outletLabel));
  PetscCall(DMPlexGetDepthStratum(dmSurface, 0, &nStart, &nEnd));
  PetscCall(DMPlexGetDepthStratum(dmSurface, 1, &eStart, &eEnd));
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [nStart = %d  ||  nEnd = %d] \n", nStart, nEnd));
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [eStart = %d  ||  eEnd = %d] \n", eStart, eEnd));
  for (PetscInt ii = nStart; ii < nEnd; ++ii) {
    PetscCall(DMGetLabelValue(dmSurface, "EGADS Face ID", ii, &faceID));
    
    if (faceID == 14) {PetscCall(DMSetLabelValue(dmSurface, "inlet", ii, faceID));}
    if (faceID == 7)  {PetscCall(DMSetLabelValue(dmSurface, "outlet", ii, faceID));}
  }
  
  for (PetscInt ii = eStart; ii < eEnd; ++ii) {
    PetscCall(DMGetLabelValue(dmSurface, "EGADS Face ID", ii, &faceID));
    
    if (faceID == 14) {PetscCall(DMSetLabelValue(dmSurface, "inlet", ii, faceID));}
    if (faceID == 7)  {PetscCall(DMSetLabelValue(dmSurface, "outlet", ii, faceID));}
  }
  
  // Generate Volumetric Mesh
  PetscCall(DMPlexGenerate(dmSurface, "tetgen", PETSC_TRUE, &dm));   // Generate Volumetric Mesh
  PetscCall(DMDestroy(&dmSurface));      // Destroy DM dmSurface no longer needed
  PetscCall(DMSetApplicationContext(dm, &ctx));            // Link context to dm
  PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));     // Write DM to file (hdf5)
  PetscCall(DMView(dm, PETSC_VIEWER_STDOUT_SELF));
  
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [CREATED MESH] \n"));
  
  // Setup SNES and link to DM
  PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes));         // Create SNES object
  PetscCall(SNESSetDM(snes, dm));                         // Link SNES object to DM
  
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [SETUP SNES] \n"));
  
  // Setup Discretization
  PetscCall(DMGetDimension(dm, &dim));        // Get Geometric Dimension of the DM (2D or 3D)
  PetscCall(DMPlexIsSimplex(dm, &simplex));   // Check if DMPlex is Simplex Type
  PetscCall(PetscFECreateDefault(PetscObjectComm((PetscObject)dm), dim, 1, simplex, NULL, -1, &fe));    // Define and Create PetscFE Object
  PetscCall(DMAddField(dm, NULL, (PetscObject)fe));        // Add Field to Discretization object. In this case, the temperature field.
  PetscCall(DMCreateDS(dm));                  // Create The Discretization System (DS) based on the field(s) added to the DM
  
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [SETUP DISCRETIZATION] \n"));
  
  // Setup Residuals & (Optional) Jacobian
  PetscInt    testFieldID = 0;                // This is an assumption. How do we find out which field ID goes with each added field?
  PetscCall(DMGetDS(dm, &ds));                // Get DS associated with DM
  PetscCall(PetscDSSetResidual(ds, testFieldID, (void (*))f0_function, (void (*))f1_function));            // Set Residual Function
  PetscCall(PetscDSSetJacobian(ds, testFieldID, testFieldID, NULL, NULL, NULL, (void (*))g3_uu_function));    // Set Jacobian Function
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [SETUP RESIDUAL & JACOBIAN] \n"));
  
  // Apply inlet face conditions - Dirichlet    
  PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "inTemp", inletLabel, 1, &idA, 0, 0, NULL, (void (*)(void))bc_inlet, NULL, &ctx, NULL));
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [SETUP BOUNDARY CONDITION inTemp] \n"));
  PetscCall(DMAddBoundary(dm, DM_BC_ESSENTIAL, "outTemp", outletLabel, 1, &idB, 0, 0, NULL, (void (*)(void))bc_outlet, NULL, &ctx, NULL));

  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [SETUP BOUNDARY CONDITIONS] \n"));

  // Create Global Vector, Initialize Values & Name
  PetscCall(DMCreateGlobalVector(dm, &temp));
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [AFTER GLOBAL VECTOR] \n"));
  PetscCall(VecSet(temp, 100.0));
  PetscCall(VecView(temp, PETSC_VIEWER_STDOUT_SELF));
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [AFTER temp set to 100] \n"));
  PetscCall(PetscObjectSetName((PetscObject)temp, "temperature"));
  
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [AFTER SET OBJECT NAME] \n"));
  
  PetscCall(DMPlexSetSNESLocalFEM(dm, &ctx, &ctx, &ctx));
  
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [AFTER SNESLocalFEM] \n"));
  
  //Set SNES from Options
  PetscCall(SNESSetFromOptions(snes));
  PetscCall(SNESView(snes, PETSC_VIEWER_STDOUT_SELF));
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [AFTER SNESSetFromOptions] \n"));
  
  // Solve System of Equations
  PetscCall(SNESSolve(snes, NULL, temp));
  
  PetscCall(PetscPrintf(PETSC_COMM_SELF, "   [SOLVED PROBLEM] \n"));
  
  //Get Solution and View
  PetscCall(SNESGetSolution(snes, &temp));
  PetscCall(VecViewFromOptions(temp, NULL, "-sol_view"));
  
  // Cleanup
  PetscCall(VecDestroy(&temp));
  PetscCall(SNESDestroy(&snes));
  PetscCall(DMDestroy(&dm));

  PetscCall(PetscFinalize());  
  return 0;
}


More information about the petsc-users mailing list