static PyObject * PongoDict_search(PongoDict *self, PyObject *args) { PyObject *path, *value, *ret=NULL; dbtype_t dbpath, dbvalue, dbrslt; char *rel; char *sep = "."; int decpath = 0; relop_t relop; if (!PyArg_ParseTuple(args, "OsO:search", &path, &rel, &value)) return NULL; if (!strcmp(rel, "==") || !strcmp(rel, "eq")) { relop = db_EQ; } else if (!strcmp(rel, "!=") || !strcmp(rel, "ne")) { relop = db_NE; } else if (!strcmp(rel, "<") || !strcmp(rel, "lt")) { relop = db_LT; } else if (!strcmp(rel, "<=") || !strcmp(rel, "le")) { relop = db_LE; } else if (!strcmp(rel, ">") || !strcmp(rel, "gt")) { relop = db_GT; } else if (!strcmp(rel, ">=") || !strcmp(rel, "ge")) { relop = db_GE; } else { PyErr_Format(PyExc_ValueError, "Unknown relop '%s'", rel); return NULL; } if (PyString_Check(path)) { path = PyObject_CallMethod(path, "split", "s", sep); decpath = 1; } if (!PySequence_Check(path)) { PyErr_Format(PyExc_TypeError, "path must be a sequence"); return NULL; } dblock(self->ctx); dbpath = from_python(self->ctx, path); if (decpath) Py_DECREF(path); if (dbtype(self->ctx, dbpath) == List) { dbvalue = from_python(self->ctx, value); if (!PyErr_Occurred()) { dbrslt = dbcollection_new(self->ctx, 0); db_search(SELF_CTX_AND_DBPTR, dbpath, -1, relop, dbvalue, dbrslt); // PROXYCHLD means turn the root object into a real dict, but // create proxy objects for all children. ret = to_python(self->ctx, dbrslt, TP_PROXYCHLD); } } else { PyErr_Format(PyExc_Exception, "path type isn't List (%d)", dbtype(self->ctx, dbpath)); } dbunlock(self->ctx); return ret; }
static PyObject * PongoDict_set(PongoDict *self, PyObject *args, PyObject *kwargs) { PyObject *key, *value; PyObject *klist = NULL; PyObject *ret = NULL; dbtype_t k, v; int sync = self->ctx->sync; int fail = 0; multi_t op = multi_SET; char *kwlist[] = {"key", "value", "sep", "sync", "fail", NULL}; char *sep = "."; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|sii:set", kwlist, &key, &value, &sep, &sync, &fail)) return NULL; k = DBNULL; dblock(self->ctx); if (PyString_Check(key) || PyUnicode_Check(key)) { klist = PyObject_CallMethod(key, "split", "s", sep); k = from_python(self->ctx, klist); Py_XDECREF(klist); } else { if (key == pongo_id) { sync |= PUT_ID; } else { k = from_python(self->ctx, key); } } v = from_python(self->ctx, value); if (!PyErr_Occurred()) { if (dbtype(self->ctx, k) == List) { if (fail) op = multi_SET_OR_FAIL; if (db_multi(SELF_CTX_AND_DBPTR, k, op, &v, sync) == 0) { ret = Py_None; } else { PyErr_SetObject(PyExc_KeyError, key); } } else if (db_multi(SELF_CTX_AND_DBPTR, k, op, &v, sync) == 0) { // db_mutli will tell us the newly created value of // "_id" when PUT_ID is enabled. ret = (sync & PUT_ID) ? to_python(self->ctx, v, TP_PROXY) : Py_None; } else { if (sync & PUT_ID) { PyErr_Format(PyExc_ValueError, "value must be a dictionary"); } else { PyErr_SetObject(PyExc_KeyError, key); } } } dbunlock(self->ctx); Py_XINCREF(ret); return ret; }
static PyObject * PongoDict_get(PongoDict *self, PyObject *args, PyObject *kwargs) { PyObject *key, *dflt = Py_None; PyObject *klist = NULL; PyObject *ret = NULL; dbtype_t k, v; char *sep = "."; char *kwlist[] = {"key", "default", "sep", NULL}; int r; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Os:get", kwlist, &key, &dflt, &sep)) return NULL; dblock(self->ctx); if (PyString_Check(key) || PyUnicode_Check(key)) { klist = PyObject_CallMethod(key, "split", "s", sep); k = from_python(self->ctx, klist); Py_XDECREF(klist); } else { k = from_python(self->ctx, key); } if (!PyErr_Occurred()) { if (dbtype(self->ctx, k) == List) { r = db_multi(SELF_CTX_AND_DBPTR, k, multi_GET, &v, 0); if (r == 0) { ret = to_python(self->ctx, v, TP_PROXY); } else if (dflt) { Py_INCREF(dflt); ret = dflt; } else { PyErr_SetObject(PyExc_KeyError, key); } } else if (dbobject_getitem(SELF_CTX_AND_DBPTR, k, &v) == 0) { ret = to_python(self->ctx, v, TP_PROXY); } else { if (dflt) { ret = dflt; Py_INCREF(ret); } else { PyErr_SetObject(PyExc_KeyError, key); } } } dbunlock(self->ctx); return ret; }
/// This function shows the basic calls needed to perform definition /// and input of the mesh model and definition and periodic output /// of a results database. The function is given the mesh filename /// and the output filename and goes through all steps of /// associating the filename with an Ioss::DatabaseIO object of the /// correct type ("exodusII" in this example); creating an /// Ioss::Region and then defining an stk::mesh corresponding to /// this mesh. The function also provides an example of how /// specific element blocks existing in the mesh database could be /// omitted from the analysis model. /// /// The example then shows how to define a results database /// corresponding to the analysis model and periodically output the /// results in an execute loop. /// /// A true application would have to provide additional /// functionality and robustness, but the example shows how the /// basic functionality can be provided by an application. /// /// Note that the paradigm illustrated here is different than the /// mesh input and output paradigm provided in the current /// framework. In this case, the application is responsible for the /// majority of the IO behavior and the toolkit only provides some /// helper functions to bridge between the Ioss and the stk::mesh. /// It is hoped that this paradigm will result in more functionality /// for the application with less complication and overhead. void io_example( const std::string& in_filename, const std::string& out_filename, const std::string& decomp_method) { // Initialize IO system. Registers all element types and storage // types and the exodusII default database type. Ioss::Init::Initializer init_db; std::cout << "========================================================================\n" << " Copy input mesh to output mesh. \n" << "========================================================================\n"; std::string dbtype("exodusII"); Ioss::PropertyManager properties; if (!decomp_method.empty()) { properties.add(Ioss::Property("DECOMPOSITION_METHOD", Ioss::Utils::uppercase(decomp_method))); } Ioss::DatabaseIO *dbi = Ioss::IOFactory::create(dbtype, in_filename, Ioss::READ_MODEL, MPI_COMM_WORLD, properties); if (dbi == NULL || !dbi->ok()) { std::cerr << "ERROR: Could not open database '" << in_filename << "' of type '" << dbtype << "'\n"; std::exit(EXIT_FAILURE); } std::cout << "Reading input file: " << in_filename << "\n"; // NOTE: 'in_region' owns 'dbi' pointer at this time... Ioss::Region in_region(dbi, "input_model"); // SUBSETTING PARSING/PREPROCESSING... // Just an example of how application could control whether an // entity is subsetted or not... #if 0 // Example command line in current code corresponding to behavior below: std::cout << "\nWhen processing file multi-block.g for use case 2, the blocks below will be omitted:\n"; std::cout << "\tOMIT BLOCK Cblock Eblock I1 I2\n\n"; Ioss::ElementBlock *eb = in_region.get_element_block("cblock"); if (eb != NULL) eb->property_add(Ioss::Property(std::string("omitted"), 1)); eb = in_region.get_element_block("eblock"); if (eb != NULL) eb->property_add(Ioss::Property(std::string("omitted"), 1)); eb = in_region.get_element_block("i1"); if (eb != NULL) eb->property_add(Ioss::Property(std::string("omitted"), 1)); eb = in_region.get_element_block("i2"); if (eb != NULL) eb->property_add(Ioss::Property(std::string("omitted"), 1)); #endif #if 0 // Example for subsetting -- omit "odd" blocks if (entity->type() == Ioss::ELEMENTBLOCK) { int id = entity->get_property("id").get_int(); if (id % 2) { entity->property_add(Ioss::Property(std::string("omitted"), 1)); std::cout << "Skipping " << entity->type_string() << ": " << entity->name() << "\n"; } } #endif //---------------------------------- // Process Entity Types. Subsetting is possible. static size_t spatial_dimension = in_region.get_property("spatial_dimension").get_int(); stk::mesh::MetaData fem_meta_data( spatial_dimension ); process_elementblocks(in_region, fem_meta_data); process_nodeblocks(in_region, fem_meta_data); process_sidesets(in_region, fem_meta_data); process_nodesets(in_region, fem_meta_data); //---------------------------------- // Done populating meta data, commit and create bulk data fem_meta_data.commit(); //---------------------------------- // Process Bulkdata for all Entity Types. Subsetting is possible. stk::mesh::BulkData bulk_data(fem_meta_data, MPI_COMM_WORLD); bulk_data.modification_begin(); process_elementblocks(in_region, bulk_data); process_nodeblocks(in_region, bulk_data); process_sidesets(in_region, bulk_data); process_nodesets(in_region, bulk_data); bulk_data.modification_end(); //---------------------------------- // OUTPUT...Create the output "mesh" portion std::cout << "Creating output file: " << out_filename << "\n"; Ioss::DatabaseIO *dbo = Ioss::IOFactory::create(dbtype, out_filename, Ioss::WRITE_RESULTS, MPI_COMM_WORLD); if (dbo == NULL || !dbo->ok()) { std::cerr << "ERROR: Could not open results database '" << out_filename << "' of type '" << dbtype << "'\n"; std::exit(EXIT_FAILURE); } #if 0 { // Code to test the remove_io_part_attribute functionality. // Hook this up to a command line option at some point to test nightly... const stk::mesh::PartVector & all_parts = fem_meta_data.get_parts(); for ( stk::mesh::PartVector::const_iterator ip = all_parts.begin(); ip != all_parts.end(); ++ip ) { stk::mesh::Part * const part = *ip; const stk::mesh::EntityRank part_rank = part->primary_entity_rank(); if (stk::io::is_part_io_part(*part) && part_rank == 2) { std::cout << "Removing part attribute from " << part->name() << "\n"; stk::io::remove_io_part_attribute(*part); } } } #endif // NOTE: 'out_region' owns 'dbo' pointer at this time... Ioss::Region out_region(dbo, "results_output"); stk::io::define_output_db(out_region, bulk_data, &in_region); stk::io::write_output_db(out_region, bulk_data); // ------------------------------------------------------------------------ /** \todo REFACTOR A real app would register a subset of the * fields on the mesh database as fields that the app would want * read at one or all or specified steps. In this example, all * fields existing on the input mesh database are defined on the * parts in the stk::mesh. * * The real app would also only register a subset of the stk::mesh * fields as output fields and would probably have a mapping from * the internally used name to some name picked by the user. In * this example, all Ioss::Field::TRANSIENT fields defined on the stk::mesh are * output to the results database and the internal stk::mesh field * name is used as the name on the database.... */ out_region.begin_mode(Ioss::STATE_DEFINE_TRANSIENT); // Special processing for nodeblock (all nodes in model)... stk::io::ioss_add_fields(fem_meta_data.universal_part(), stk::topology::NODE_RANK, out_region.get_node_blocks()[0], Ioss::Field::TRANSIENT); const stk::mesh::PartVector & all_parts = fem_meta_data.get_parts(); for ( stk::mesh::PartVector::const_iterator ip = all_parts.begin(); ip != all_parts.end(); ++ip ) { stk::mesh::Part * const part = *ip; const stk::mesh::EntityRank part_rank = part->primary_entity_rank(); // Check whether this part should be output to results database. if (stk::io::is_part_io_part(*part)) { // Get Ioss::GroupingEntity corresponding to this part... Ioss::GroupingEntity *entity = out_region.get_entity(part->name()); if (entity != NULL) { if (entity->type() == Ioss::SIDESET) { Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity); assert(sset != NULL); int block_count = sset->block_count(); for (int i=0; i < block_count; i++) { Ioss::SideBlock *fb = sset->get_block(i); stk::io::ioss_add_fields(*part, part_rank, fb, Ioss::Field::TRANSIENT); } } else { stk::io::ioss_add_fields(*part, part_rank, entity, Ioss::Field::TRANSIENT); } } else { /// \todo IMPLEMENT handle error... Possibly an assert since /// I think the corresponding entity should always exist... } } } out_region.end_mode(Ioss::STATE_DEFINE_TRANSIENT); // ------------------------------------------------------------------------ // Read and Write transient fields... out_region.begin_mode(Ioss::STATE_TRANSIENT); int timestep_count = in_region.get_property("state_count").get_int(); for (int step = 1; step <= timestep_count; step++) { double time = in_region.get_state_time(step); // Read data from the io input mesh database into stk::mesh fields... process_input_request(in_region, bulk_data, step); // execute() // Write data from the stk::mesh fields out to the output database.a int out_step = out_region.add_state(time); process_output_request(out_region, bulk_data, out_step); } out_region.end_mode(Ioss::STATE_TRANSIENT); }
int main(int argc, char *argv[]) { extern int optind; extern char *optarg; enum S command, state; DB *dbp; DBT data, key, keydata; size_t len; int ch, oflags, sflag; char *fname, *infoarg, *p, *t, buf[8 * 1024]; infoarg = NULL; fname = NULL; oflags = O_CREAT | O_RDWR; sflag = 0; while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) switch (ch) { case 'f': fname = optarg; break; case 'i': infoarg = optarg; break; case 'l': oflags |= DB_LOCK; break; case 'o': if ((ofd = open(optarg, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) err("%s: %s", optarg, strerror(errno)); break; case 's': sflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc != 2) usage(); /* Set the type. */ type = dbtype(*argv++); /* Open the descriptor file. */ if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) err("%s: %s", *argv, strerror(errno)); /* Set up the db structure as necessary. */ if (infoarg == NULL) infop = NULL; else for (p = strtok(infoarg, ",\t "); p != NULL; p = strtok(0, ",\t ")) if (*p != '\0') infop = setinfo(type, p); /* * Open the DB. Delete any preexisting copy, you almost never * want it around, and it often screws up tests. */ if (fname == NULL) { p = getenv("TMPDIR"); if (p == NULL) p = "/var/tmp"; snprintf(buf, sizeof(buf), "%s/__dbtest", p); fname = buf; unlink(buf); } else if (!sflag) unlink(fname); if ((dbp = dbopen(fname, oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) err("dbopen: %s", strerror(errno)); XXdbp = dbp; state = COMMAND; for (lineno = 1; (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { /* Delete the newline, displaying the key/data is easier. */ if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) *t = '\0'; if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#') continue; /* Convenient gdb break point. */ if (XXlineno == lineno) XXlineno = 1; switch (*p) { case 'c': /* compare */ if (state != COMMAND) err("line %lu: not expecting command", lineno); state = KEY; command = COMPARE; break; case 'e': /* echo */ if (state != COMMAND) err("line %lu: not expecting command", lineno); /* Don't display the newline, if CR at EOL. */ if (p[len - 2] == '\r') --len; if (write(ofd, p + 1, len - 1) != len - 1 || write(ofd, "\n", 1) != 1) err("write: %s", strerror(errno)); break; case 'g': /* get */ if (state != COMMAND) err("line %lu: not expecting command", lineno); state = KEY; command = GET; break; case 'p': /* put */ if (state != COMMAND) err("line %lu: not expecting command", lineno); state = KEY; command = PUT; break; case 'r': /* remove */ if (state != COMMAND) err("line %lu: not expecting command", lineno); if (flags == R_CURSOR) { rem(dbp, &key); state = COMMAND; } else { state = KEY; command = REMOVE; } break; case 'S': /* sync */ if (state != COMMAND) err("line %lu: not expecting command", lineno); synk(dbp); state = COMMAND; break; case 's': /* seq */ if (state != COMMAND) err("line %lu: not expecting command", lineno); if (flags == R_CURSOR) { state = KEY; command = SEQ; } else seq(dbp, &key); break; case 'f': flags = setflags(p + 1); break; case 'D': /* data file */ if (state != DATA) err("line %lu: not expecting data", lineno); data.data = rfile(p + 1, &data.size); goto ldata; case 'd': /* data */ if (state != DATA) err("line %lu: not expecting data", lineno); data.data = xmalloc(p + 1, len - 1); data.size = len - 1; ldata: switch (command) { case COMPARE: compare(&keydata, &data); break; case PUT: put(dbp, &key, &data); break; default: err("line %lu: command doesn't take data", lineno); } if (type != DB_RECNO) free(key.data); free(data.data); state = COMMAND; break; case 'K': /* key file */ if (state != KEY) err("line %lu: not expecting a key", lineno); if (type == DB_RECNO) err("line %lu: 'K' not available for recno", lineno); key.data = rfile(p + 1, &key.size); goto lkey; case 'k': /* key */ if (state != KEY) err("line %lu: not expecting a key", lineno); if (type == DB_RECNO) { static recno_t recno; recno = atoi(p + 1); key.data = &recno; key.size = sizeof(recno); } else { key.data = xmalloc(p + 1, len - 1); key.size = len - 1; } lkey: switch (command) { case COMPARE: getdata(dbp, &key, &keydata); state = DATA; break; case GET: get(dbp, &key); if (type != DB_RECNO) free(key.data); state = COMMAND; break; case PUT: state = DATA; break; case REMOVE: rem(dbp, &key); if ((type != DB_RECNO) && (flags != R_CURSOR)) free(key.data); state = COMMAND; break; case SEQ: seq(dbp, &key); if ((type != DB_RECNO) && (flags != R_CURSOR)) free(key.data); state = COMMAND; break; default: err("line %lu: command doesn't take a key", lineno); } break; case 'o': dump(dbp, p[1] == 'r'); break; default: err("line %lu: %s: unknown command character", lineno, p); } } #ifdef STATISTICS /* * -l must be used (DB_LOCK must be set) for this to be * used, otherwise a page will be locked and it will fail. */ if (type == DB_BTREE && oflags & DB_LOCK) __bt_stat(dbp); #endif if (dbp->close(dbp)) err("db->close: %s", strerror(errno)); close(ofd); exit(0); }