static char help[] = "Simple MOAB example\n\n"; #include #if defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" #endif #include "moab/ScdInterface.hpp" #if defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic pop #endif typedef struct { DM dm; /* DM implementation using the MOAB interface */ PetscLogEvent createMeshEvent; /* Domain and mesh definition */ PetscInt dim; char filename[PETSC_MAX_PATH_LEN]; char tagname[PETSC_MAX_PATH_LEN]; } AppCtx; PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) { PetscBool flg; PetscFunctionBegin; PetscCall(PetscStrncpy(options->filename, "", sizeof(options->filename))); PetscCall(PetscStrncpy(options->tagname, "petsc_tag", sizeof(options->tagname))); options->dim = -1; PetscOptionsBegin(comm, "", "MOAB example options", "DMMOAB"); PetscCall(PetscOptionsRangeInt("-dim", "The topological mesh dimension", "ex1.cxx", options->dim, &options->dim, NULL, PETSC_DECIDE, 3)); PetscCall(PetscOptionsString("-filename", "The file containing the mesh", "ex1.cxx", options->filename, options->filename, sizeof(options->filename), NULL)); PetscCall(PetscOptionsString("-tagname", "The tag name from which to create a vector", "ex1.cxx", options->tagname, options->tagname, sizeof(options->tagname), &flg)); PetscOptionsEnd(); PetscCall(PetscLogEventRegister("CreateMesh", DM_CLASSID, &options->createMeshEvent)); PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { moab::Interface *iface = NULL; moab::Tag tag = NULL; moab::Tag ltog_tag = NULL; moab::Range range; PetscInt tagsize; moab::ErrorCode merr; PetscFunctionBegin; PetscCall(PetscLogEventBegin(user->createMeshEvent, 0, 0, 0, 0)); PetscCall(DMMoabCreateMoab(comm, iface, <og_tag, &range, dm)); std::cout << "Created DMMoab using DMMoabCreateMoab." << std::endl; PetscCall(DMMoabGetInterface(*dm, &iface)); // load file and get entities of requested or max dimension if (strlen(user->filename) > 0) { merr = iface->load_file(user->filename); MBERRNM(merr); std::cout << "Read mesh from file " << user->filename << std::endl; } else { // make a simple structured mesh moab::ScdInterface *scdi; merr = iface->query_interface(scdi); moab::ScdBox *box; merr = scdi->construct_box(moab::HomCoord(0, 0, 0), moab::HomCoord(5, 5, 5), NULL, 0, box); MBERRNM(merr); user->dim = 3; merr = iface->set_dimension(user->dim); MBERRNM(merr); std::cout << "Created structured 5x5x5 mesh." << std::endl; } if (-1 == user->dim) { moab::Range tmp_range; merr = iface->get_entities_by_handle(0, tmp_range); MBERRNM(merr); if (tmp_range.empty()) MBERRNM(moab::MB_FAILURE); user->dim = iface->dimension_from_handle(*tmp_range.rbegin()); } merr = iface->get_entities_by_dimension(0, user->dim, range); MBERRNM(merr); PetscCall(DMMoabSetLocalVertices(*dm, &range)); // get the requested tag and create if necessary std::cout << "Creating tag with name: " << user->tagname << ";\n"; merr = iface->tag_get_handle(user->tagname, 1, moab::MB_TYPE_DOUBLE, tag, moab::MB_TAG_CREAT | moab::MB_TAG_DENSE); MBERRNM(merr); { // initialize new tag with gids std::vector tag_vals(range.size()); merr = iface->tag_get_data(ltog_tag, range, tag_vals.data()); MBERRNM(merr); // read them into ints double *dval = tag_vals.data(); int *ival = reinterpret_cast(dval); // "stretch" them into doubles, from the end for (int i = tag_vals.size() - 1; i >= 0; i--) dval[i] = ival[i]; merr = iface->tag_set_data(tag, range, tag_vals.data()); MBERRNM(merr); // write them into doubles } merr = iface->tag_get_length(tag, tagsize); MBERRNM(merr); PetscCall(DMSetUp(*dm)); // create the dmmoab and initialize its data PetscCall(PetscObjectSetName((PetscObject)*dm, "MOAB mesh")); PetscCall(PetscLogEventEnd(user->createMeshEvent, 0, 0, 0, 0)); user->dm = *dm; PetscFunctionReturn(PETSC_SUCCESS); } int main(int argc, char **argv) { AppCtx user; /* user-defined work context */ moab::ErrorCode merr; Vec vec; moab::Interface *mbImpl = NULL; moab::Tag datatag = NULL; PetscFunctionBeginUser; PetscCall(PetscInitialize(&argc, &argv, NULL, help)); PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &user.dm)); /* create the MOAB dm and the mesh */ PetscCall(DMMoabGetInterface(user.dm, &mbImpl)); merr = mbImpl->tag_get_handle(user.tagname, datatag); MBERRNM(merr); PetscCall(DMMoabCreateVector(user.dm, datatag, NULL, PETSC_TRUE, PETSC_FALSE, &vec)); /* create a vec from user-input tag */ std::cout << "Created VecMoab from existing tag." << std::endl; PetscCall(VecDestroy(&vec)); std::cout << "Destroyed VecMoab." << std::endl; PetscCall(DMDestroy(&user.dm)); std::cout << "Destroyed DMMoab." << std::endl; PetscCall(PetscFinalize()); return 0; } /*TEST build: requires: moab !complex test: TEST*/