Actual source code: ex1.cxx

  1: static char help[] = "Simple MOAB example\n\n";

  3: #include <petscdmmoab.h>
  4: #if defined(__GNUC__) || defined(__GNUG__)
  5:   #pragma GCC diagnostic push
  6:   #pragma GCC diagnostic ignored "-Wunused-result"
  7: #endif
  8: #include "moab/ScdInterface.hpp"
  9: #if defined(__GNUC__) || defined(__GNUG__)
 10:   #pragma GCC diagnostic pop
 11: #endif

 13: typedef struct {
 14:   DM            dm; /* DM implementation using the MOAB interface */
 15:   PetscLogEvent createMeshEvent;
 16:   /* Domain and mesh definition */
 17:   PetscInt dim;
 18:   char     filename[PETSC_MAX_PATH_LEN];
 19:   char     tagname[PETSC_MAX_PATH_LEN];
 20: } AppCtx;

 22: PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
 23: {
 24:   PetscBool flg;

 26:   PetscFunctionBegin;
 27:   PetscCall(PetscStrncpy(options->filename, "", sizeof(options->filename)));
 28:   PetscCall(PetscStrncpy(options->tagname, "petsc_tag", sizeof(options->tagname)));
 29:   options->dim = -1;

 31:   PetscOptionsBegin(comm, "", "MOAB example options", "DMMOAB");
 32:   PetscCall(PetscOptionsRangeInt("-dim", "The topological mesh dimension", "ex1.cxx", options->dim, &options->dim, NULL, PETSC_DECIDE, 3));
 33:   PetscCall(PetscOptionsString("-filename", "The file containing the mesh", "ex1.cxx", options->filename, options->filename, sizeof(options->filename), NULL));
 34:   PetscCall(PetscOptionsString("-tagname", "The tag name from which to create a vector", "ex1.cxx", options->tagname, options->tagname, sizeof(options->tagname), &flg));
 35:   PetscOptionsEnd();

 37:   PetscCall(PetscLogEventRegister("CreateMesh", DM_CLASSID, &options->createMeshEvent));
 38:   PetscFunctionReturn(PETSC_SUCCESS);
 39: }

 41: PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
 42: {
 43:   moab::Interface *iface    = NULL;
 44:   moab::Tag        tag      = NULL;
 45:   moab::Tag        ltog_tag = NULL;
 46:   moab::Range      range;
 47:   PetscInt         tagsize;

 49:   PetscFunctionBegin;
 50:   PetscCall(PetscLogEventBegin(user->createMeshEvent, 0, 0, 0, 0));
 51:   PetscCall(DMMoabCreateMoab(comm, iface, &ltog_tag, &range, dm));
 52:   std::cout << "Created DMMoab using DMMoabCreateMoab." << std::endl;
 53:   PetscCall(DMMoabGetInterface(*dm, &iface));

 55:   // load file and get entities of requested or max dimension
 56:   if (strlen(user->filename) > 0) {
 57:     PetscCallMOAB(iface->load_file(user->filename));
 58:     std::cout << "Read mesh from file " << user->filename << std::endl;
 59:   } else {
 60:     // make a simple structured mesh
 61:     moab::ScdInterface *scdi;
 62:     PetscCallMOAB(iface->query_interface(scdi));

 64:     moab::ScdBox *box;
 65:     PetscCallMOAB(scdi->construct_box(moab::HomCoord(0, 0, 0), moab::HomCoord(5, 5, 5), NULL, 0, box));
 66:     user->dim = 3;
 67:     PetscCallMOAB(iface->set_dimension(user->dim));
 68:     std::cout << "Created structured 5x5x5 mesh." << std::endl;
 69:   }
 70:   if (-1 == user->dim) {
 71:     moab::Range tmp_range;
 72:     PetscCallMOAB(iface->get_entities_by_handle(0, tmp_range));
 73:     PetscCheck(!tmp_range.empty(), PETSC_COMM_SELF, PETSC_ERR_LIB, "Tmp range is empty");
 74:     user->dim = iface->dimension_from_handle(*tmp_range.rbegin());
 75:   }
 76:   PetscCallMOAB(iface->get_entities_by_dimension(0, user->dim, range));
 77:   PetscCall(DMMoabSetLocalVertices(*dm, &range));

 79:   // get the requested tag and create if necessary
 80:   std::cout << "Creating tag with name: " << user->tagname << ";\n";
 81:   PetscCallMOAB(iface->tag_get_handle(user->tagname, 1, moab::MB_TYPE_DOUBLE, tag, moab::MB_TAG_CREAT | moab::MB_TAG_DENSE));
 82:   {
 83:     // initialize new tag with gids
 84:     std::vector<double> tag_vals(range.size());
 85:     PetscCallMOAB(iface->tag_get_data(ltog_tag, range, tag_vals.data()));
 86:     double *dval = tag_vals.data();
 87:     int    *ival = reinterpret_cast<int *>(dval); // "stretch" them into doubles, from the end
 88:     for (int i = tag_vals.size() - 1; i >= 0; i--) dval[i] = ival[i];
 89:     PetscCallMOAB(iface->tag_set_data(tag, range, tag_vals.data()));
 90:   }
 91:   PetscCallMOAB(iface->tag_get_length(tag, tagsize));
 92:   PetscCall(DMSetUp(*dm));

 94:   // create the dmmoab and initialize its data
 95:   PetscCall(PetscObjectSetName((PetscObject)*dm, "MOAB mesh"));
 96:   PetscCall(PetscLogEventEnd(user->createMeshEvent, 0, 0, 0, 0));
 97:   user->dm = *dm;
 98:   PetscFunctionReturn(PETSC_SUCCESS);
 99: }

101: int main(int argc, char **argv)
102: {
103:   AppCtx           user; /* user-defined work context */
104:   Vec              vec;
105:   moab::Interface *mbImpl  = NULL;
106:   moab::Tag        datatag = NULL;

108:   PetscFunctionBeginUser;
109:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
110:   PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user));

112:   PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &user.dm)); /* create the MOAB dm and the mesh */

114:   PetscCall(DMMoabGetInterface(user.dm, &mbImpl));
115:   PetscCallMOAB(mbImpl->tag_get_handle(user.tagname, datatag));
116:   PetscCall(DMMoabCreateVector(user.dm, datatag, NULL, PETSC_TRUE, PETSC_FALSE, &vec)); /* create a vec from user-input tag */

118:   std::cout << "Created VecMoab from existing tag." << std::endl;
119:   PetscCall(VecDestroy(&vec));
120:   std::cout << "Destroyed VecMoab." << std::endl;
121:   PetscCall(DMDestroy(&user.dm));
122:   std::cout << "Destroyed DMMoab." << std::endl;
123:   PetscCall(PetscFinalize());
124:   return 0;
125: }

127: /*TEST

129:      build:
130:        requires: moab !complex

132:      test:

134: TEST*/