/** * Convert from column major to row major with point_dim number of columns. * * @param col_major Column major data * @param point_dim Dimension of each point (= number of columns) * @return col_major data stored row major. */ double *get_row_major(double *col_major, size_t point_dim, size_t x_len) { if (point_dim == 0) { set_error_string("Dimension of x should be larger than 0!"); return nullptr; } double *row_major = (double *) malloc(sizeof(double) * x_len); if(row_major == nullptr) { set_error_string("Out of memory!"); return nullptr; } size_t num_points = x_len / point_dim; for (size_t i = 0; i < x_len; ++i) { size_t row_num = i / point_dim; // Intentional integer division size_t col_num = i % point_dim; row_major[i] = col_major[col_num * num_points + row_num]; } return row_major; }
caValue* selector_advance(caValue* value, caValue* selectorElement, caValue* error) { if (is_int(selectorElement)) { int selectorIndex = as_int(selectorElement); if (!is_list(value)) { set_error_string(error, "Value is not indexable: "); string_append_quoted(error, value); return NULL; } if (selectorIndex >= list_length(value)) { set_error_string(error, "Index "); string_append(error, selectorIndex); string_append(error, " is out of range"); return NULL; } return get_index(value, selectorIndex); } else if (is_string(selectorElement)) { caValue* field = get_field(value, as_cstring(selectorElement)); if (field == NULL) { set_error_string(error, "Field not found: "); string_append(error, selectorElement); return NULL; } return field; } else { set_error_string(error, "Unrecognized selector element: "); string_append_quoted(error, selectorElement); return NULL; } }
std::vector<std::vector<double> > PropsSImulti(const std::vector<std::string> &Outputs, const std::string &Name1, const std::vector<double> &Prop1, const std::string &Name2, const std::vector<double> &Prop2, const std::string &backend, const std::vector<std::string> &fluids, const std::vector<double> &fractions) { std::vector<std::vector<double> > IO; #if !defined(NO_ERROR_CATCHING) try{ #endif // Call the subfunction that can bubble errors _PropsSImulti(Outputs, Name1, Prop1, Name2, Prop2, backend, fluids, fractions, IO); // Return the value(s) return IO; #if !defined(NO_ERROR_CATCHING) } catch(const std::exception& e){ set_error_string(e.what()); #if defined (PROPSSI_ERROR_STDOUT) std::cout << e.what() << std::endl; #endif if (get_debug_level() > 1){std::cout << e.what() << std::endl;} } catch(...){ } #endif return std::vector<std::vector<double> >(); }
double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &Ref) { std::string backend, fluid; #if !defined(PROPSSI_NO_ERROR_CATCH) // In this function the error catching happens; try{ #else std::cout << "macro is on; error checking disabled in PropsSI" << std::endl; #endif // BEGIN OF TRY // Here is the real code that is inside the try block extract_backend(Ref, backend, fluid); double val = _PropsSI(Output, Name1, Prop1, Name2, Prop2, backend, fluid, std::vector<double>()); if (get_debug_level() > 1){ std::cout << format("_PropsSI will return %g",val) << std::endl; } return val; // END OF TRY #if !defined(PROPSSI_NO_ERROR_CATCH) } catch(const std::exception& e){ set_error_string(e.what() + format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")",Output.c_str(),Name1.c_str(), Prop1, Name2.c_str(), Prop2, Ref.c_str())); #if defined (PROPSSI_ERROR_STDOUT) std::cout << e.what() << std::endl; #endif if (get_debug_level() > 1){std::cout << e.what() << std::endl;} return _HUGE; } catch(...){ return _HUGE; } #endif }
double Props1SI(const std::string &FluidName, const std::string &Output) { std::string _FluidName = FluidName, empty_string = "", _Output = Output; double val1 = PropsSI(_FluidName, empty_string, 0, empty_string, 0, _Output); if (!ValidNumber(val1)){ // flush the error set_error_string(""); // Try with them flipped val1 = PropsSI(_Output, empty_string, 0, empty_string, 0, _FluidName); } if (!ValidNumber(val1)){ set_error_string(format("Unable to use inputs %s,%s in Props1SI (order doesn't matter)")); return _HUGE; } return val1; }
arcus_atlas *atlas_from_file(const char *filename) { scew_reader *reader; scew_parser *parser; scew_tree *tree; arcus_atlas *ret; reader = scew_reader_file_create(filename); if (!reader) { set_error_string("atlas_from_file: cannot open/read file"); return NULL; } parser = scew_parser_create(); if (!parser) { set_error_string("atlas_from_file: cannot create a parser (scew bug?)"); scew_reader_close(reader); scew_reader_free(reader); return NULL; } tree = scew_parser_load(parser, reader); if (!tree) { set_error_string("atlas_from_file: cannot create tree from parser and reader (invalid XML?)"); scew_parser_free(parser); scew_reader_close(reader); scew_reader_free(reader); return NULL; } ret = atlas_from_xml(scew_tree_root(tree)); scew_tree_free(tree); scew_parser_free(parser); scew_reader_close(reader); scew_reader_free(reader); return ret; }
/* Check for existence of bspline_builder_ptr, then cast splinter_obj_ptr to a BSpline::Builder * */ BSpline::Builder *get_builder(splinter_obj_ptr bspline_builder_ptr) { if (bspline_builders.count(bspline_builder_ptr) > 0) { return static_cast<BSpline::Builder *>(bspline_builder_ptr); } set_error_string("Invalid reference to BSpline::Builder: Maybe it has been deleted?"); return nullptr; }
/* Cast the splinter_obj_ptr to a DataTable * */ DataTable *get_datatable(splinter_obj_ptr datatable_ptr) { if (dataTables.count(datatable_ptr) > 0) { return static_cast<DataTable *>(datatable_ptr); } set_error_string("Invalid reference to DataTable: Maybe it has been deleted?"); return nullptr; }
double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &Ref) { #if !defined(NO_ERROR_CATCHING) try{ #endif // BEGIN OF TRY // Here is the real code that is inside the try block std::string backend, fluid; extract_backend(Ref, backend, fluid); std::vector<double> fractions(1, 1.0); // extract_fractions checks for has_fractions_in_string / has_solution_concentration; no need to double check std::string fluid_string = extract_fractions(fluid, fractions); std::vector<std::vector<double> > IO; _PropsSImulti(strsplit(Output,'&'), Name1, std::vector<double>(1, Prop1), Name2, std::vector<double>(1, Prop2), backend, strsplit(fluid_string, '&'), fractions, IO); if (IO.empty()){ throw ValueError(get_global_param_string("errstring").c_str()); } if (IO.size()!= 1 || IO[0].size() != 1){ throw ValueError(format("output should be 1x1; error was %s", get_global_param_string("errstring").c_str())); } double val = IO[0][0]; if (get_debug_level() > 1){ std::cout << format("_PropsSI will return %g",val) << std::endl; } return val; // END OF TRY #if !defined(NO_ERROR_CATCHING) } catch(const std::exception& e){ set_error_string(e.what() + format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")",Output.c_str(),Name1.c_str(), Prop1, Name2.c_str(), Prop2, Ref.c_str())); #if defined (PROPSSI_ERROR_STDOUT) std::cout << e.what() << std::endl; #endif if (get_debug_level() > 1){std::cout << e.what() << std::endl;} return _HUGE; } catch(...){ return _HUGE; } #endif }
static arcus_system *system_create(void) { arcus_system *ret; ret = (arcus_system *)malloc(sizeof(arcus_system)); if (!ret) { fprintf(stderr, "system_create: out of memory!\n"); exit(1); } ret->id = NULL; ret->metric = NULL; ret->cs = NULL; ret->range = af_create_formula(BACKEND_DEFAULT); if (!ret->range) { fprintf(stderr, "system_create: out of memory!\n"); exit(1); } if (!af_formula_setvariable(ret->range, "v0", &ret->v0) || !af_formula_setvariable(ret->range, "v1", &ret->v1) || !af_formula_setvariable(ret->range, "v2", &ret->v2) || !af_formula_setvariable(ret->range, "v3", &ret->v3)) { set_error_string("system_create: could not set variables"); af_destroy_formula(ret->range); free(ret); return NULL; } return ret; }
arcus_atlas *atlas_from_xml(scew_element *element) { arcus_atlas *atlas; scew_list *list, *i; int expected_transforms, ii, jj, kk; if (!element) { set_error_string("atlas_from_xml: NULL element"); return NULL; } if (strcmp(scew_element_name(element), "atlas") != 0) { set_error_string("atlas_from_xml: element name != 'atlas'"); return NULL; } atlas = atlas_create(); if (!atlas) return NULL; list = scew_element_list_by_name(element, "system"); if (!list) { set_error_string("atlas_from_xml: no systems in atlas"); atlas_destroy(atlas); return NULL; } for (i = list ; i ; i = scew_list_next(i)) { scew_element *e; arcus_system *s; e = (scew_element *)scew_list_data(i); s = system_from_xml(e); if (!s) { atlas_destroy(atlas); return NULL; } atlas->systems = (arcus_system **)realloc(atlas->systems, (atlas->num_systems + 1) * sizeof(arcus_system *)); atlas->systems[atlas->num_systems] = s; atlas->num_systems++; } // If there's only one system, ignore the transforms if (atlas->num_systems == 1) return atlas; // Figure out how many transforms we should have (n choose k, both directions) expected_transforms = binomial(atlas->num_systems, 2) * 2; // Load transforms list = scew_element_list_by_name(element, "transform"); if (!list) { set_error_string("atlas_from_xml: no transforms in atlas when expected"); atlas_destroy(atlas); return NULL; } if (scew_list_size(list) != expected_transforms) { set_error_string("atlas_from_xml: wrong number of transforms in atlas"); atlas_destroy(atlas); return NULL; } for (i = list ; i ; i = scew_list_next(i)) { scew_element *e; arcus_transform *t; e = (scew_element *)scew_list_data(i); t = transform_from_xml(e); if (!t) { atlas_destroy(atlas); return NULL; } atlas->transforms = (arcus_transform **)realloc(atlas->transforms, (atlas->num_transforms + 1) * sizeof(arcus_transform *)); atlas->transforms[atlas->num_transforms] = t; atlas->num_transforms++; } // Load differential transforms list = scew_element_list_by_name(element, "transform_diff"); if (!list) { set_error_string("atlas_from_xml: no differential transforms in atlas when expected"); atlas_destroy(atlas); return NULL; } if (scew_list_size(list) != expected_transforms) { set_error_string("atlas_from_xml: wrong number of differential transforms in atlas"); atlas_destroy(atlas); return NULL; } for (i = list ; i ; i = scew_list_next(i)) { scew_element *e; arcus_transform *t; e = (scew_element *)scew_list_data(i); t = transform_from_xml(e); if (!t) { atlas_destroy(atlas); return NULL; } atlas->diff_transforms = (arcus_transform **)realloc(atlas->diff_transforms, (atlas->num_diff_transforms + 1) * sizeof(arcus_transform *)); atlas->diff_transforms[atlas->num_diff_transforms] = t; atlas->num_diff_transforms++; } // Check the accuracy and completeness of the transform lists for (ii = 0 ; ii < expected_transforms ; ii++) { arcus_transform *t, *dt; int found_t_from = 0, found_t_to = 0; int found_dt_from = 0, found_dt_to = 0; t = atlas->transforms[ii]; dt = atlas->diff_transforms[ii]; for (jj = 0 ; jj < atlas->num_systems ; jj++) { if (strcmp(system_id(atlas->systems[jj]), transform_from(t)) == 0) found_t_from = 1; if (strcmp(system_id(atlas->systems[jj]), transform_from(dt)) == 0) found_dt_from = 1; if (strcmp(system_id(atlas->systems[jj]), transform_to(t)) == 0) found_t_to = 1; if (strcmp(system_id(atlas->systems[jj]), transform_to(dt)) == 0) found_dt_to = 1; } if (!found_t_from || !found_t_to) { set_error_string("atlas_from_xml: transform has invalid from/to"); atlas_destroy(atlas); return NULL; } if (!found_dt_from || !found_dt_to) { set_error_string("atlas_from_xml: transform_diff has invalid from/to"); atlas_destroy(atlas); return NULL; } } for (ii = 0 ; ii < atlas->num_systems ; ii++) { for (jj = 0 ; jj < atlas->num_systems ; jj++) { int found_ij = 0, found_ji = 0, found_ij_d = 0, found_ji_d = 0; if (ii == jj) continue; arcus_system *si, *sj; si = atlas->systems[ii]; sj = atlas->systems[jj]; for (kk = 0 ; kk < expected_transforms ; kk++) { arcus_transform *t = atlas->transforms[kk]; if (strcmp(system_id(si), transform_from(t)) == 0 && strcmp(system_id(sj), transform_to(t)) == 0) found_ij = 1; else if (strcmp(system_id(sj), transform_from(t)) == 0 && strcmp(system_id(si), transform_to(t)) == 0) found_ji = 1; t = atlas->diff_transforms[kk]; if (strcmp(system_id(si), transform_from(t)) == 0 && strcmp(system_id(sj), transform_to(t)) == 0) found_ij_d = 1; else if (strcmp(system_id(sj), transform_from(t)) == 0 && strcmp(system_id(si), transform_to(t)) == 0) found_ji_d = 1; } if (!found_ij || !found_ji) { set_error_string("atlas_from_xml: no transforms found for one pair of systems"); atlas_destroy(atlas); return NULL; } if (!found_ij_d || !found_ji_d) { set_error_string("atlas_from_xml: no differential transforms found for one pair of systems"); atlas_destroy(atlas); return NULL; } } } return atlas; }
arcus_system *system_from_xml(scew_element *element) { arcus_system *sys; scew_attribute *attr; const char *attr_val; scew_list *list; scew_element *e; const char *contents; if (!element) { set_error_string("system_from_xml: NULL element"); return NULL; } if (strcmp(scew_element_name(element), "system") != 0) { set_error_string("system_from_xml: element name != 'system'"); return NULL; } sys = system_create(); if (!sys) return NULL; // Get system id attr = scew_element_attribute_by_name(element, "id"); if (!attr) { set_error_string("system_from_xml: system without id"); system_destroy(sys); return NULL; } attr_val = scew_attribute_value(attr); if (!attr_val) { set_error_string("system_from_xml: attribute without value (scew bug?)"); system_destroy(sys); return NULL; } sys->id = strdup(attr_val); // Load metric list = scew_element_list_by_name(element, "metric"); if (!list) { set_error_string("system_create: no metric in system"); system_destroy(sys); return NULL; } if (scew_list_size(list) != 1) { set_error_string("system_create: more than one metric in system"); system_destroy(sys); return NULL; } sys->metric = metric_from_xml((scew_element *)scew_list_data(list)); if (!sys->metric) { system_destroy(sys); return NULL; } // Load christoffel symbols sys->cs = christoffel_from_xml(element); if (!sys->cs) { system_destroy(sys); return NULL; } // Load range list = scew_element_list_by_name(element, "range"); if (!list) { set_error_string("system_create: no range in system"); system_destroy(sys); return NULL; } if (scew_list_size(list) != 1) { set_error_string("system_create: more than one range in system"); system_destroy(sys); return NULL; } e = (scew_element *)scew_list_data(list); if (!e || strcmp(scew_element_name(e), "range") != 0) { set_error_string("system_create: no/wrong range element in list (SCEW bug?)"); system_destroy(sys); return NULL; } contents = scew_element_contents(e); if (!contents || !contents[0]) { set_error_string("system_create: no contents in range element"); system_destroy(sys); return NULL; } if (!af_formula_setexpr(sys->range, contents)) { set_error_string("system_create: cannot set range function expression"); system_destroy(sys); return NULL; } return sys; }