static void process_dowhile(ast_node node){ // indicate that its a dowhile loop quad dowhile_quad = create_quad(dowhileloop); add_quad(node, dowhile_quad); // add the compound (body of dowhile loop) add_quad_list(node, node->left_child->code); int beginning = node->code->first->next->num; quad end_loop = create_quad(end_dowhileloop); add_quad(node, end_loop); // add the code for the condition add_quad_list(node, node->left_child->right_sibling->code); // test the condition (move on if it fails) and add its quad to code quad if_false = create_quad(ifFalse); char * loc = strdup(node->left_child->right_sibling->location); if_false->address1 = loc; add_quad(node, if_false); // unconditional jump to top of compound quad jump_to = create_quad(jumpTo); char * buffer = malloc(10); sprintf(buffer, "%d", beginning); jump_to->address1 = buffer; add_quad(node, jump_to); // backpatch the if_false quad buffer = malloc(10); sprintf(buffer, "%d", num_quads); if_false->address2 = buffer; }
/* builds the code for a compound: * enter scope * code of its children * leave scope */ static void process_cmpd(ast_node node){ quad enter_scope = create_quad(enter); quad exit_scope = create_quad(leave); add_quad(node, enter_scope); build_code(node, exit_scope, NULL, NULL, NULL); }
static void process_if(ast_node node){ quad ifFalse_quad = create_quad(ifFalse); char * loc = strdup(node->left_child->location); ifFalse_quad->address1 = loc; // indicate that this is an if-statement quad if_false = create_quad(ifstmt); add_quad(node, if_false); // add the code for the condition add_quad_list(node, node->left_child->code); // add the ifFalse quad add_quad(node, ifFalse_quad); // add the compound if (node->left_child->right_sibling != NULL){ add_quad_list(node, node->left_child->right_sibling->code); } // indicate that the if ends here quad if_end = create_quad(end_ifstmt); add_quad(node, if_end); // Backpatch if_quad by filling in the number of the quad it should go to // if it is false. char * buffer = malloc(10); sprintf(buffer, "%d", num_quads); ifFalse_quad->address2 = buffer; }
// process float math static void process_float_math(ast_node node){ quad new_quad = NULL; switch (node->node_type){ case OP_PLUS: new_quad = create_quad(f_add); break; case OP_MINUS: new_quad = create_quad(f_sub); break; case OP_TIMES: new_quad = create_quad(f_mult); break; case OP_DIVIDE: new_quad = create_quad(f_divide); break; case OP_EQUALS: new_quad = create_quad(f_eq); break; case OP_NEQUALS: new_quad = create_quad(f_neq); break; case OP_LT: new_quad = create_quad(f_lt); break; case OP_LEQ: new_quad = create_quad(f_leq); break; case OP_GT: new_quad = create_quad(f_gt); break; case OP_GEQ: new_quad = create_quad(f_geq); break; } // location being assigned to is new! char *target = new_address(); char * left = process_left(node); char *right = process_right(node); if (new_quad != NULL && target != NULL && left != NULL && right != NULL){ build_code(node, new_quad, target, left, right); } else { destroy_quad(new_quad); error("process_float_math"); } }
void generate_traverse(ast_node node){ generate_traverse_recurse(node); // add the end quad quad end_quad = create_quad(end); add_quad(node, end_quad); }
/* processes a call * 1. push the params onto the stack * 2. goto_sub the function (location will be stored in symbol table maybe?) * 3. get the return value (will be in a register) */ static void process_call(ast_node node){ // 1. push the params onto the stack in reverse order ast_node args = node->left_child->right_sibling; quad goto_sub_quad = create_quad(goto_sub); goto_sub_quad->address1 = node->left_child->value.string; add_quad(node, goto_sub_quad); ast_node curr; for (curr = args->left_child; curr != NULL; curr = curr->right_sibling){ quad push_quad = create_quad(push); push_quad->address1 = curr->location; // it's a literal! if (push_quad->address1 == NULL){ char buffer[MAX_LEN]; char *val; if (curr->type == Int){ snprintf(buffer, MAX_LEN, "%d", curr->value.int_value); val = strdup(buffer); push_quad->address1 = val; } else{ snprintf(buffer, MAX_LEN, "%f", curr->value.double_value); val = strdup(buffer); push_quad->address1 = val; } } add_quad_to_beginning(node, push_quad); add_quad_list_to_beginning(node, curr->code); //add_quad_list(node, curr->code); } // 2. jump to the function's subroutine /* quad goto_sub_quad = create_quad(goto_sub); goto_sub_quad->address1 = node->left_child->value.string; add_quad(node, goto_sub_quad); */ // 3. get the return value quad get_return = create_quad(get_rtrn); get_return->address1 = new_address(); node->location = get_return->address1; add_quad(node, get_return); }
// (print, location or string lit, NULL, NULL) static void process_print(ast_node node){ quad print_quad = create_quad(print); char *left = process_left(node); print_quad->address1 = left; add_quad_list(node, node->left_child->code); add_quad(node, print_quad); }
// (read, location, NULL, NULL) static void process_read(ast_node node){ quad read_quad = create_quad(read); char * left = process_left(node); printf("left: %s\n", left); read_quad->address1 = left; add_quad(node, read_quad); // if it's an array, assign temp to the array if (node->left_child->left_child != NULL){ quad array_quad = create_quad(array_assn); array_quad->address1 = process_left(node->left_child); array_quad->address2 = process_right(node->left_child); array_quad->address3 = left; add_quad(node, array_quad); } }
static void process_or(ast_node node){ quad or_quad = create_quad(or); add_quad(node, or_quad); // the value of the OR will be stored here: char * or_address = new_address(); node->location = or_address; char * left = process_left(node); char * right = process_right(node); // add the code for the left child add_quad_list(node, node->left_child->code); // if the left child is false, go to test for right child quad if_false = create_quad(ifFalse); char * loc = strdup(left); if_false->address1 = loc; add_quad(node, if_false); // unconditional jump (short circuiting) quad short_circuit = create_quad(jumpTo); add_quad(node, short_circuit); // add the code for the right child - if_false jumps here! add_quad_list(node, node->left_child->right_sibling->code); int if_false_jumps_here = node->left_child->right_sibling->code->first->num; char * buffer = malloc(10); sprintf(buffer, "%d", if_false_jumps_here); if_false->address2 = buffer; // OR gets the value of the right child quad assign_from_right = create_quad(assn); assign_from_right->address1 = or_address; assign_from_right->address2 = right; add_quad(node, assign_from_right); // unconditional jump (done) quad done_jump = create_quad(jumpTo); add_quad(node, done_jump); // OR gets the value of the left child - short circuit jumps here! quad assign_from_left = create_quad(assn); assign_from_left->address1 = or_address; assign_from_left->address2 = left; add_quad(node, assign_from_left); // backpatch short_circuit buffer = malloc(10); sprintf(buffer, "%d", assign_from_left->num); short_circuit->address1 = buffer; // backpatch done_jump (goes to next generated quad) buffer = malloc(10); sprintf(buffer, "%d", num_quads); done_jump->address1 = buffer; quad end_or_quad = create_quad(end_or); add_quad(node, end_or_quad); }
static void process_while(ast_node node){ quad if_false = create_quad(ifFalse); char * loc = strdup(node->left_child->location); if_false->address1 = loc; // Get the num of the quad that starts the code that computes // the condition. int start_of_condition = node->left_child->code->first->num; // indicate that it's a while loop quad while_quad = create_quad(whileloop); add_quad(node, while_quad); // add the code for the condition add_quad_list(node, node->left_child->code); // add the ifFalse quad add_quad(node, if_false); // add the code for the body if (node->left_child->right_sibling != NULL){ add_quad_list(node, node->left_child->right_sibling->code); } // mark the end of the body // quad end_while = create_quad(end_whileloop); //add_quad(node, end_while); // create the jumpTo quad that takes you back to the condition // and add it to the code quad back_to_condition = create_quad(jumpTo); char *buffer = malloc(10); sprintf(buffer, "%d", start_of_condition); back_to_condition->address1 = buffer; add_quad(node, back_to_condition); // mark the end of the body quad end_while = create_quad(end_whileloop); add_quad(node, end_while); // backpatch the ifFalse quad buffer = malloc(10); sprintf(buffer, "%d", num_quads); if_false->address2 = buffer; }
// Format: (array_lkup, target, name, index) static void process_array(ast_node node){ quad array_quad = create_quad(array_lkup); // where you'll put value of array once you look it up array_quad->address1 = new_address(); array_quad->address2 = process_left(node); array_quad->address3 = process_right(node); add_quad(node, array_quad); node->location = array_quad->address1; }
/* declare a variable * This only happens if it has a left child (otherwise it's saying the type * of a function. * Format: (vardec, type, name, NULL) */ static void process_vardec(ast_node node){ int assign; ast_node curr = node->left_child; char * address1; char * address2; // get the data type if (node->node_type == INT_TYPE) address1 = "int"; else if (node->node_type == DOUBLE_TYPE) address1 = "double"; while (curr != NULL){ quad vardec_quad = create_quad(vardec); vardec_quad->address1 = address1; if (curr->node_type == OP_ASSIGN){ vardec_quad->address2 = curr->left_child->value.string; assign = 1; } // process array declaration else if (curr->node_type == ARRAY){ int size; // get the size of the array if (curr->left_child->right_sibling == NULL) size = 1; else{ size = curr->left_child->right_sibling->value.int_value; } char buffer[MAX_LEN]; snprintf(buffer, MAX_LEN, "%d", size); vardec_quad->address3 = strdup(buffer); // get the name of the array vardec_quad->address2 = process_left(curr); } else { vardec_quad->address2 = curr->value.string; } if (vardec_quad->address2 != NULL) node->location = strdup(vardec_quad->address2); add_quad(node, vardec_quad); if (assign){ add_quad_list(node, curr->code); } curr = curr->right_sibling; } }
// (rtrn, location, NULL, NULL); static void process_return(ast_node node){ quad return_quad = create_quad(rtrn); if (node->left_child != NULL){ char * left = process_left(node); return_quad->address1 = left; node->location = left; add_quad_list(node, node->left_child->code); } add_quad(node, return_quad); }
static void process_for(ast_node node){ // add start and condition code add_quad_list(node, node->left_child->code); // indicate that it's a for-loop // while loops are the same thing, so pretend it's one! shhhh ... quad for_quad = create_quad(whileloop); add_quad(node, for_quad); add_quad_list(node, node->left_child->right_sibling->code); int cond_start = node->left_child->right_sibling->code->first->num; // if the condition is false, exit the loop char * condition_location = node->left_child->right_sibling->location; quad if_false = create_quad(ifFalse); if_false->address1 = condition_location; add_quad(node, if_false); // add the code for the compound add_quad_list(node, node->left_child->right_sibling->right_sibling->right_sibling->code); // add update code add_quad_list(node, node->left_child->right_sibling->right_sibling->code); // unconditional jump back to the condition quad jump = create_quad(jumpTo); char * buffer = malloc(10); sprintf(buffer, "%d", cond_start); jump->address1 = buffer; add_quad(node, jump); quad end_for = create_quad(end_whileloop); add_quad(node, end_for); // backpatch the if_false quad buffer = malloc(10); sprintf(buffer, "%d", num_quads); if_false->address2 = buffer; }
/* builds the code of a function; * 1. Function declaration: (func_dec, type, name, NULL) * 2. Code of its children */ static void process_function(ast_node node){ // create a quad with address1 = type and address2 = name quad func_dec_node = create_quad(func_dec); char * type; if (node->left_child->node_type == INT_TYPE){ type = "int"; } else if (node->left_child->node_type == DOUBLE_TYPE){ type = "double"; } else if (node->left_child->node_type == VOID_TYPE){ type = "void"; } char * name = node->left_child->right_sibling->value.string; func_dec_node->address1 = type; func_dec_node->address2 = name; add_quad(node, func_dec_node); // enter scope - hackity hack hack hack quad enter_quad = create_quad(enter); add_quad(node, enter_quad); build_code(node, NULL, NULL, NULL, NULL); // exit hacky scope quad leave_quad = create_quad(leave); add_quad(node, leave_quad); // JUST ADDED // if it's main, add halt if (strcmp(name, "main") == 0){ quad halt_quad = create_quad(halt); add_quad(node, halt_quad); } // default return quad return_quad = create_quad(rtrn); add_quad(node, return_quad); // leave subroutine (return addr will be in a register) quad exit_sub_quad = create_quad(exit_sub); add_quad(node, exit_sub_quad); // if it's main, add halt if (strcmp(name, "main") == 0){ quad halt_quad = create_quad(halt); add_quad(node, halt_quad); } }
// Format: (assn, target location, value location, null) static void process_assign(ast_node node){ char * target = NULL; // deal with arrays a little differently if (node->left_child->node_type == ARRAY){ quad array_quad = create_quad(array_assn); ast_node array = node->left_child; // (array_assn, array, index, value) array_quad->address1 = process_left(array); array_quad->address2 = process_right(array); ; array_quad->address3 = process_right(node); // add code to calculuate right hand side, then to find array location add_quad_list(node, node->left_child->right_sibling->code); add_quad(node, array_quad); } else { quad new_quad = create_quad(assn); // get location to being assigned if (node->left_child != NULL && node->left_child->node_type == IDENT){ target = strdup(node->left_child->value.string); // DO I NEED TO DUPLICATE THE STRING? } else if (node->left_child != NULL){ target = strdup(node->left_child->location); } // get location of value char * value = process_right(node); if (target != NULL && value != NULL){ build_code(node, new_quad, target, value, NULL); } else{ destroy_quad(new_quad); error("process_assign"); } } }
// handle increments and decrements static void process_inc(ast_node node, char * inc){ quad new_quad = create_quad(add); char * target = process_left(node); char *value = target; char *amount = strdup(inc); if (value != NULL){ build_code(node, new_quad, target, value, amount); } else{ destroy_quad(new_quad); error("process inc"); } }
static void process_negate(ast_node node){ quad new_quad = create_quad(mult); char * target = new_address(); char * value = process_left(node); char * multby = strdup("-1"); if (value != NULL){ build_code(node, new_quad, target, value, multby); } else{ destroy_quad(new_quad); error("process_negate"); } }
int main(){ oprand op1, op2, op3; quad qd; op1 = create_oprand(OP_TYPE_INT, 1); op2 = create_oprand(OP_TYPE_NA, 1); op3 = create_oprand(OP_TYPE_DOUBLE, 1.5); qd = create_quad(FUNC_BODY, op1, op2, op3); insert_quad(qd); insert_quad(qd); insert_quad(qd); print_code(); return 0; }
static void process_ifelse(ast_node node){ quad if_quad = create_quad(ifFalse); char * loc = strdup(node->left_child->location); if_quad->address1 = loc; // indicate that it's an ifelse quad ifelse_quad = create_quad(ifelse); add_quad(node, ifelse_quad); // add the code for the condition add_quad_list(node, node->left_child->code); // add the ifFalse quad add_quad(node, if_quad); // add the compound if (node->left_child->right_sibling != NULL){ add_quad_list(node, node->left_child->right_sibling->code); } // if part is over quad end_if_quad = create_quad(end_ifstmt); add_quad(node, end_if_quad); // do the goto quad jump_quad = create_quad(jumpTo); add_quad(node, jump_quad); // if part is starting quad else_quad = create_quad(elsestmt); add_quad(node, else_quad); // add the else compound if (node->left_child->right_sibling->right_sibling != NULL){ add_quad_list(node, node->left_child->right_sibling->right_sibling->code); } // else part is over quad end_else = create_quad(end_elsestmt); add_quad(node, end_else); // Backpatch if_false int ifFalse_backpatch = jump_quad->next->num; char * buffer = malloc(10); sprintf(buffer, "%d", ifFalse_backpatch); if_quad->address2 = buffer; // Backpatch the jump_quad buffer = malloc(10); sprintf(buffer, "%d", num_quads); jump_quad->address1 = buffer; }
static void process_and(ast_node node){ quad and_quad = create_quad(and); add_quad(node, and_quad); // address the value of the and will be stored here: char * and_address = new_address(); node->location = and_address; char * left = process_left(node); char * right = process_right(node); // do the code for the left child add_quad_list(node, node->left_child->code); // if the left child is false, short circuit quad if_false = create_quad(ifFalse); char * loc = strdup(left); if_false->address1 = loc; add_quad(node, if_false); // do the code for the right child add_quad_list(node, node->left_child->right_sibling->code); quad assign = create_quad(assn); assign->address1 = and_address; assign->address2 = right; add_quad(node, assign); // unconditional jump to code after the and quad jump_to = create_quad(jumpTo); add_quad(node, jump_to); // first was false, so the value is false (short circuited) quad assign2 = create_quad(assn); assign2->address1 = and_address; assign2->address2 = left; add_quad(node, assign2); int short_circuit = assign2->num; // backpatch the unconditional jump: char * buffer = malloc(10); sprintf(buffer, "%d", num_quads); jump_to->address1 = buffer; // backpatch the short circuit buffer = malloc(10); sprintf(buffer, "%d", short_circuit); if_false->address2 = buffer; quad end_and_quad = create_quad(end_and); add_quad(node, end_and_quad); }
static int build_quads(hpquads_t* me, int Nhptotry, il* hptotry, int R) { int nthispass = 0; int lastgrass = 0; int i; for (i=0; i<Nhptotry; i++) { anbool ok; int hp; if ((i * 80 / Nhptotry) != lastgrass) { printf("."); fflush(stdout); lastgrass = i * 80 / Nhptotry; } if (hptotry) hp = il_get(hptotry, i); else hp = i; me->hp = hp; me->quad_created = FALSE; ok = find_stars(me, me->radius2, R); if (ok) create_quad(me, TRUE); if (me->quad_created) nthispass++; else { if (R && me->Nstars && me->retryhps) // there were some stars, and we're counting how many times stars are used. //il_insert_unique_ascending(me->retryhps, hp); // we don't mind hps showing up multiple times because we want to make up for the lost // passes during loosening... il_append(me->retryhps, hp); // FIXME -- could also track which hps are worth visiting in a future pass } } printf("\n"); return nthispass; }
/* Handles mathy operations (all the same pattern) * Format: (operation, target location, left argument, right argument) */ static void process_math(ast_node node){ // if its a float - process float math if (node->type == Double){ process_float_math(node); return; } quad new_quad = NULL; if (node->node_type == OP_PLUS){ new_quad = create_quad(add); } else if (node->node_type == OP_MINUS){ new_quad = create_quad(sub); } else if (node->node_type == OP_TIMES){ new_quad = create_quad(mult); } else if (node->node_type == OP_DIVIDE){ new_quad = create_quad(divide); } else if (node->node_type == OP_MOD){ new_quad = create_quad(mod); } else if (node->node_type == OP_EQUALS){ new_quad = create_quad(eq); } else if (node->node_type == OP_NEQUALS){ new_quad = create_quad(neq); } else if (node->node_type == OP_LT){ new_quad = create_quad(lt); } else if (node->node_type == OP_LEQ){ new_quad = create_quad(leq); } else if (node->node_type == OP_GT){ new_quad = create_quad(gt); } else if (node->node_type == OP_GEQ){ new_quad = create_quad(geq); } else if (node->node_type == OP_NOT){ new_quad = create_quad(not); } // location being assigned to is new! char * target = new_address(); // get left argument char * left = process_left(node); // get right argument (if it's not OP_NOT) char * right = NULL; if (node->node_type != OP_NOT) right = process_right(node); if (new_quad != NULL && target != NULL && left != NULL){ build_code(node, new_quad, target, left, right); } else { destroy_quad(new_quad); error("process math"); } }
bool H2DReader::load_stream(std::istream &is, Mesh *mesh, const char *filename) { int i, j, k, n; Node* en; bool debug = false; mesh->free(); std::string mesh_str = read_file(is); Python p; initpython_reader(); p.exec("from python_reader import read_hermes_format_str"); p.push_str("s", mesh_str); p.exec("vertices, elements, boundaries, curves, refinements" " = read_hermes_format_str(s)"); //// vertices //////////////////////////////////////////////////////////////// p.exec("n = len(vertices)"); n = p.pull_int("n"); if (n < 0) error("File %s: 'vertices' must be a list.", filename); if (n < 2) error("File %s: invalid number of vertices.", filename); // create a hash table large enough int size = HashTable::H2D_DEFAULT_HASH_SIZE; while (size < 8*n) size *= 2; mesh->init(size); // create top-level vertex nodes for (i = 0; i < n; i++) { Node* node = mesh->nodes.add(); assert(node->id == i); node->ref = TOP_LEVEL_REF; node->type = HERMES_TYPE_VERTEX; node->bnd = 0; node->p1 = node->p2 = -1; node->next_hash = NULL; p.push_int("i", i); p.exec("x, y = vertices[i]"); node->x = p.pull_double("x"); node->y = p.pull_double("y"); } mesh->ntopvert = n; //// elements //////////////////////////////////////////////////////////////// p.exec("n = len(elements)"); n = p.pull_int("n"); if (n < 0) error("File %s: 'elements' must be a list.", filename); if (n < 1) error("File %s: no elements defined.", filename); // create elements mesh->nactive = 0; for (i = 0; i < n; i++) { // read and check vertex indices p.push_int("i", i); p.exec("nv = len(elements[i])"); int nv = p.pull_int("nv"); int idx[5]; std::string el_marker; if (!nv) { mesh->elements.skip_slot(); continue; } if (nv < 4 || nv > 5) error("File %s: element #%d: wrong number of vertex indices.", filename, i); if (nv == 4) { p.exec("n1, n2, n3, marker = elements[i]"); idx[0] = p.pull_int("n1"); idx[1] = p.pull_int("n2"); idx[2] = p.pull_int("n3"); p.exec("marker_str = 1 if isinstance(marker, str) else 0"); if (p.pull_int("marker_str")) el_marker = p.pull_str("marker"); else { std::ostringstream string_stream; string_stream << p.pull_int("marker"); el_marker = string_stream.str(); } } else { p.exec("n1, n2, n3, n4, marker = elements[i]"); idx[0] = p.pull_int("n1"); idx[1] = p.pull_int("n2"); idx[2] = p.pull_int("n3"); idx[3] = p.pull_int("n4"); p.exec("marker_str = 1 if isinstance(marker, str) else 0"); if (p.pull_int("marker_str")) el_marker = p.pull_str("marker"); else { std::ostringstream string_stream; string_stream << p.pull_int("marker"); el_marker = string_stream.str(); } } for (j = 0; j < nv-1; j++) if (idx[j] < 0 || idx[j] >= mesh->ntopvert) error("File %s: error creating element #%d: vertex #%d does not exist.", filename, i, idx[j]); Node *v0 = &mesh->nodes[idx[0]], *v1 = &mesh->nodes[idx[1]], *v2 = &mesh->nodes[idx[2]]; int marker; // This functions check if the user-supplied marker on this element has been // already used, and if not, inserts it in the appropriate structure. mesh->element_markers_conversion.insert_marker(mesh->element_markers_conversion.min_marker_unused, el_marker); marker = mesh->element_markers_conversion.get_internal_marker(el_marker); if(nv == 4) { check_triangle(i, v0, v1, v2); create_triangle(mesh, marker, v0, v1, v2, NULL); } else { Node *v3 = &mesh->nodes[idx[3]]; check_quad(i, v0, v1, v2, v3); create_quad(mesh, marker, v0, v1, v2, v3, NULL); } mesh->nactive++; } mesh->nbase = n; //// boundaries ////////////////////////////////////////////////////////////// p.exec("have_boundaries = 1 if boundaries else 0"); if (p.pull_int("have_boundaries")) { p.exec("n = len(boundaries)"); n = p.pull_int("n"); // read boundary data for (i = 0; i < n; i++) { int v1, v2, marker; p.push_int("i", i); p.exec("v1, v2, marker = boundaries[i]"); v1 = p.pull_int("v1"); v2 = p.pull_int("v2"); en = mesh->peek_edge_node(v1, v2); if (en == NULL) error("File %s: boundary data #%d: edge %d-%d does not exist", filename, i, v1, v2); std::string bnd_marker; p.exec("marker_str = 1 if isinstance(marker, str) else 0"); if (p.pull_int("marker_str")) bnd_marker = p.pull_str("marker"); else { std::ostringstream string_stream; string_stream << p.pull_int("marker"); bnd_marker = string_stream.str(); } // This functions check if the user-supplied marker on this element has been // already used, and if not, inserts it in the appropriate structure. mesh->boundary_markers_conversion.insert_marker(mesh->boundary_markers_conversion.min_marker_unused, bnd_marker); marker = mesh->boundary_markers_conversion.get_internal_marker(bnd_marker); en->marker = marker; // This is extremely important, as in DG, it is assumed that negative boundary markers are reserved // for the inner edges. if (marker > 0) { mesh->nodes[v1].bnd = 1; mesh->nodes[v2].bnd = 1; en->bnd = 1; } } } #ifdef HERMES_COMMON_CHECK_BOUNDARY_CONDITIONS // check that all boundary edges have a marker assigned for_all_edge_nodes(en, mesh) if (en->ref < 2 && en->marker == 0) { warn("Boundary edge node does not have a boundary marker"); } #endif //// curves ////////////////////////////////////////////////////////////////// p.exec("have_curves = 1 if curves else 0"); if (p.pull_int("have_curves")) { p.exec("n = len(curves)"); n = p.pull_int("n"); if (n < 0) error("File %s: 'curves' must be a list.", filename); // load curved edges for (i = 0; i < n; i++) { // load the control points, knot vector, etc. Node* en; int p1, p2; p.push_int("i", i); p.exec("curve = curves[i]"); Nurbs* nurbs = load_nurbs(mesh, p, i, &en, p1, p2); // assign the nurbs to the elements sharing the edge node for (k = 0; k < 2; k++) { Element* e = en->elem[k]; if (e == NULL) continue; if (e->cm == NULL) { e->cm = new CurvMap; memset(e->cm, 0, sizeof(CurvMap)); e->cm->toplevel = 1; e->cm->order = 4; } int idx = -1; for (unsigned j = 0; j < e->nvert; j++) if (e->en[j] == en) { idx = j; break; } assert(idx >= 0); if (e->vn[idx]->id == p1) { e->cm->nurbs[idx] = nurbs; nurbs->ref++; } else { Nurbs* nurbs_rev = mesh->reverse_nurbs(nurbs); e->cm->nurbs[idx] = nurbs_rev; nurbs_rev->ref++; } } if (!nurbs->ref) delete nurbs; } } // update refmap coeffs of curvilinear elements Element* e; for_all_elements(e, mesh) if (e->cm != NULL) e->cm->update_refmap_coeffs(e); //// refinements ///////////////////////////////////////////////////////////// p.exec("have_refinements = 1 if refinements else 0"); if (p.pull_int("have_refinements")) { p.exec("n = len(refinements)"); n = p.pull_int("n"); if (n < 0) error("File %s: 'refinements' must be a list.", filename); // perform initial refinements for (i = 0; i < n; i++) { int id, ref; p.push_int("i", i); p.exec("id, ref = refinements[i]"); id = p.pull_int("id"); ref = p.pull_int("ref"); mesh->refine_element_id(id, ref); } } mesh->ninitial = mesh->elements.get_num_items(); mesh->seq = g_mesh_seq++; return true; }