// Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights // reserved. See files LICENSE and NOTICE for details. // // This file is part of CEED, a collection of benchmarks, miniapps, software // libraries and APIs for efficient high-order finite element and spectral // element discretizations for exascale applications. For more information and // source code availability see http://github.com/ceed. // // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, // a collaborative effort of two U.S. Department of Energy organizations (Office // of Science and the National Nuclear Security Administration) responsible for // the planning and preparation of a capable exascale ecosystem, including // software, applications, hardware, advanced system engineering and early // testbed platforms, in support of the nation's exascale computing imperative. // libCEED + PETSc Example: Surface Area // // This example demonstrates a simple usage of libCEED with PETSc to calculate // the surface area of a simple closed surface, such as the one of a cube // via the mass operator. // // The code uses higher level communication protocols in DMPlex. // // Build with: // // make area [PETSC_DIR=] [CEED_DIR=] // // Sample runs: // Sequential: // // area -petscspace_degree 3 // // In parallel: // // mpiexec -n 4 area -petscspace_degree 3 // //TESTARGS -ceed {ceed_resource} -test -petscspace_degree 3 /// @file /// libCEED example using the mass operator to compute surface area using PETSc with DMPlex static const char help[] = "Compute surface area of a cube using DMPlex in PETSc\n"; #include #include #include #include "qfunctions/area/area.h" // Auxiliary function to define CEED restrictions from DMPlex data static int CreateRestrictionPlex(Ceed ceed, CeedInt P, CeedInt ncomp, CeedElemRestriction *Erestrict, DM dm) { PetscInt ierr; PetscInt c, cStart, cEnd, nelem, nnodes, *erestrict, eoffset; PetscSection section; Vec Uloc; PetscFunctionBegin; // Get Nelem ierr = DMGetSection(dm, §ion); CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart,& cEnd); CHKERRQ(ierr); nelem = cEnd - cStart; // Get indices ierr = PetscMalloc1(nelem*P*P, &erestrict); CHKERRQ(ierr); for (c=cStart, eoffset = 0; c 'v' CeedOperatorApply(op_apply, uceed, vceed, CEED_REQUEST_IMMEDIATE); CeedVectorSyncArray(vceed, CEED_MEM_HOST); // Gather output vector ierr = VecRestoreArray(Vloc, &v); CHKERRQ(ierr); ierr = VecZeroEntries(V); CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(dm, Vloc, ADD_VALUES, V); CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(dm, Vloc, ADD_VALUES, V); CHKERRQ(ierr); // Compute and print the sum of the entries of 'v' giving the mesh surface area PetscScalar area; ierr = VecSum(V, &area); CHKERRQ(ierr); // Compute the exact surface area and print the result CeedScalar exact_surfarea = 6 * (2*l) * (2*l); if (!test_mode) { ierr = PetscPrintf(comm, "Exact mesh surface area : % .14g\n", exact_surfarea); CHKERRQ(ierr); ierr = PetscPrintf(comm, "Computed mesh surface area : % .14g\n", area); CHKERRQ(ierr); ierr = PetscPrintf(comm, "Area error : % .14g\n", fabs(area - exact_surfarea)); CHKERRQ(ierr); } // PETSc cleanup ierr = DMDestroy(&dm); CHKERRQ(ierr); ierr = VecDestroy(&X); CHKERRQ(ierr); ierr = VecDestroy(&Xloc); CHKERRQ(ierr); ierr = VecDestroy(&V); CHKERRQ(ierr); ierr = VecDestroy(&Vloc); CHKERRQ(ierr); // libCEED cleanup CeedQFunctionDestroy(&qf_setupgeo); CeedOperatorDestroy(&op_setupgeo); CeedVectorDestroy(&xcoord); CeedVectorDestroy(&uceed); CeedVectorDestroy(&vceed); CeedVectorDestroy(&qdata); CeedBasisDestroy(&basisx); CeedBasisDestroy(&basisu); CeedElemRestrictionDestroy(&Erestrictu); CeedElemRestrictionDestroy(&Erestrictx); CeedElemRestrictionDestroy(&Erestrictxi); CeedElemRestrictionDestroy(&Erestrictqdi); CeedQFunctionDestroy(&qf_apply); CeedOperatorDestroy(&op_apply); CeedDestroy(&ceed); return PetscFinalize(); }