inline void print_data_to_files(double *phi, double *density, double *residual, int tl) { double x0 = get_center_x() + tl*TAU * func_u(tl*TAU, get_center_x(), get_center_y()); double y0 = get_center_y() + tl*TAU* func_v(tl*TAU, get_center_x(), get_center_y()); print_surface("phi", NX, NY, HX, HY, tl, A, C, x0, y0, TAU, U, V, phi); print_surface("rho", NX, NY, HX, HY, tl, A, C, x0, y0, TAU, U, V, density); // print_surface("res", NX, NY, HX, HY, tl, A, C, get_center_x_2(), get_center_y_2(), TAU, // U, V, residual); double *err_lock = calc_error_2(HX, HY, tl * TAU, density); print_surface("err-l", NX, NY, HX, HY, tl, A, C, x0, y0, TAU, U, V, err_lock); delete[] err_lock; }
inline static double analytical_solution_circle(double t, double x, double y) { double x0 = get_center_x() + t * func_u(t, x, y); double y0 = get_center_y() + t * func_v(t, x, y); double value = (x - x0) * (x - x0) + (y - y0) * (y - y0); if (value <= R_SQ) return INN_DENSITY; return OUT_DENSITY; }
float Sprite::get_distance_to(Sprite *target) { /* * Calculates the distance between two sprites center positions */ float delta_x = get_center_x() - target->get_center_x(); float delta_y = get_center_y() - target->get_center_y(); double distance = sqrt( pow(delta_x, 2.f) + pow(delta_y, 2.f) ); return (float)distance; }
bool GridMap::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name == "theme") { r_ret = get_theme(); } else if (name == "cell_size") { r_ret = get_cell_size(); } else if (name == "cell_octant_size") { r_ret = get_octant_size(); } else if (name == "cell_center_x") { r_ret = get_center_x(); } else if (name == "cell_center_y") { r_ret = get_center_y(); } else if (name == "cell_center_z") { r_ret = get_center_z(); } else if (name == "cell_scale") { r_ret = cell_scale; } else if (name == "data") { Dictionary d; PoolVector<int> cells; cells.resize(cell_map.size() * 3); { PoolVector<int>::Write w = cells.write(); int i = 0; for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) { encode_uint64(E->key().key, (uint8_t *)&w[i * 3]); encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]); } } d["cells"] = cells; r_ret = d; } else if (name.begins_with("areas/")) { int which = name.get_slicec('/', 1).to_int(); String what = name.get_slicec('/', 2); if (what == "bounds") r_ret = area_get_bounds(which); else if (what == "name") r_ret = area_get_name(which); else if (what == "disable_distance") r_ret = area_get_portal_disable_distance(which); else if (what == "exterior_portal") r_ret = area_is_exterior_portal(which); else return false; } else return false; return true; }
float Sprite::get_distance_to_edge(Sprite* target) { float x1 = get_center_x(); float y1 = get_center_y(); float x2 = target->get_center_x(); float y2 = target->get_center_y(); float deltaY = y1 - y2; float deltaX = x1 - x2; float angleInRadians = atan2(deltaY, deltaX); float extraLength = target->get_width() / 2.f ; double distance = sqrt(pow(deltaX, 2.f) + pow(deltaY, 2.f)); return (float)distance - extraLength; }
bool GridMap::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name == "theme") { r_ret = get_theme(); } else if (name == "cell_size") { r_ret = get_cell_size(); } else if (name == "cell_octant_size") { r_ret = get_octant_size(); } else if (name == "cell_center_x") { r_ret = get_center_x(); } else if (name == "cell_center_y") { r_ret = get_center_y(); } else if (name == "cell_center_z") { r_ret = get_center_z(); } else if (name == "cell_scale") { r_ret = cell_scale; } else if (name == "data") { Dictionary d; PoolVector<int> cells; cells.resize(cell_map.size() * 3); { PoolVector<int>::Write w = cells.write(); int i = 0; for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) { encode_uint64(E->key().key, (uint8_t *)&w[i * 3]); encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]); } } d["cells"] = cells; r_ret = d; } else return false; return true; }
double *solve_2(double &tme) { fflush(stdout); int ic = 0; double *phi = new double[XY]; double *prev_density = new double[XY]; double *density = new double[XY]; double *residual = new double[XY]; //<editor-fold desc="Fill initial data"> for (int i = 0; i < NX_1; ++i) { for (int j = 0; j < NY_1; ++j) { density[NY_1 * i + j] = 0.; prev_density[NY_1 * i + j] = 0.; residual[NY_1 * i + j] = 0.; phi[NY_1 * i + j] = 0.; } } // G1 -- (x_i, 0=C) -- bottom boundary for (int i = 0; i < NX_1; ++i) { prev_density[NY_1 * i] = analytical_solution_circle(0., A + HX * i, C); if (fabs(prev_density[NY_1 * i]) < fabs(DBL_MIN_TRIM)) prev_density[NY_1 * i] = 0; } // G2 -- (NX=B, y_j) -- right boundary for (int j = 1; j < NY; ++j) { prev_density[NY_1 * NX + j] = analytical_solution_circle(0., A + HX * NX, C + HY * j); if (fabs(prev_density[NY_1 * NX + j]) < fabs(DBL_MIN_TRIM)) prev_density[NY_1 * NX + j] = 0; } // G3 -- (x_i, NY=D) -- top boundary for (int i = 0; i < NX_1; ++i) { prev_density[NY_1 * i + NY] = analytical_solution_circle(0., A + HX * i, C + HY * NY); if (fabs(prev_density[NY_1 * i + NY]) < fabs(DBL_MIN_TRIM)) prev_density[NY_1 * i + NY] = 0; } // G4 -- (0=A, y_j) -- left boundary for (int j = 1; j < NY; ++j) { prev_density[j] = analytical_solution_circle(0., A, C + HY * j); if (fabs(prev_density[j]) < fabs(DBL_MIN_TRIM)) prev_density[j] = 0; } memcpy(density, prev_density, XY * sizeof(double)); // inner points for (int i = 1; i < NX; ++i) { for (int j = 1; j < NY; ++j) { prev_density[NY_1 * i + j] = analytical_solution_circle(0., A + HX * i, C + HY * j); //if (fabs(prev_density[NY_1 * i + j]) < fabs(DBL_MIN_TRIM)) prev_density[NY_1 * i + j] = 0; } } //</editor-fold> double sum_rho = calc_array_sum(prev_density, NX_1, NY_1, 0); double sum_abs_rho = calc_array_sum(prev_density, NX_1, NY_1, 1); printf("SUM RHO INIT = %le\n", sum_rho); printf("SUM ABS RHO INIT= %le\n", sum_abs_rho); fflush(stdout); double maxRes = FLT_MAX; double *extrems = new double[2]; double *extrems_err = new double[2]; for (int tl = 1; tl <= TIME_STEP_CNT; tl++) { //<editor-fold desc="Calculate phi"> // with usage of prev_density we calculate phi function values // G3 -- (x_i, NY=D) -- top boundary for (int i = 1; i < NX; ++i) { double integ = 0.; if (INTEGR_TYPE == 1) { integ = get_phi_integ_midpoint(i, NY, prev_density, TAU * tl); } else if (INTEGR_TYPE == 2) { integ = get_phi_integ_trapezium(i, NY, prev_density, TAU * tl); } else if (INTEGR_TYPE == 3) { integ = get_phi_integ_exact(i, NY, prev_density, TAU * tl); } else if (INTEGR_TYPE == 4) { integ = get_phi_integ_b_control_midpoint(i, NY, prev_density, TAU * tl); } phi[NY_1 * i + NY] = integ; } // G2 -- (NX=B, y_j) -- right boundary for (int j = 1; j < NY; ++j) { double integ = 0.; if (INTEGR_TYPE == 1) { integ = get_phi_integ_midpoint(NX, j, prev_density, TAU * tl); } else if (INTEGR_TYPE == 2) { integ = get_phi_integ_trapezium(NX, j, prev_density, TAU * tl); } else if (INTEGR_TYPE == 3) { integ = get_phi_integ_exact(NX, j, prev_density, TAU * tl); } else if (INTEGR_TYPE == 4) { integ = get_phi_integ_b_control_midpoint(NX, j, prev_density, TAU * tl); } phi[NY_1 * NX + j] = integ; } double integ = 0.; if (INTEGR_TYPE == 1) { integ = get_phi_integ_midpoint(NX, NY, prev_density, TAU * tl); } else if (INTEGR_TYPE == 2) { integ = get_phi_integ_trapezium(NX, NY, prev_density, TAU * tl); } else if (INTEGR_TYPE == 3) { integ = get_phi_integ_exact(NX, NY, prev_density, TAU * tl); } else if (INTEGR_TYPE == 4) { integ = get_phi_integ_b_control_midpoint(NX, NY, prev_density, TAU * tl); } // point (1,1) phi[NY_1 * NX + NY] = integ; // inner points for (int i = 1; i < NX; ++i) for (int j = 1; j < NY; ++j) { double integ = 0.; if (INTEGR_TYPE == 1) { integ = get_phi_integ_midpoint(i, j, prev_density, TAU * tl); } else if (INTEGR_TYPE == 2) { integ = get_phi_integ_trapezium(i, j, prev_density, TAU * tl); } else if (INTEGR_TYPE == 3) { integ = get_phi_integ_exact(i, j, prev_density, TAU * tl); } else if (INTEGR_TYPE == 4) { integ = get_phi_integ_b_control_midpoint(i, j, prev_density, TAU * tl); } phi[NY_1 * i + j] = integ; } //</editor-fold> ic = 0; double maxErr = FLT_MAX; while (((maxErr > EPS) || (maxRes > RES_EPS)) && (ic < NX_1 * NY_1)) { //<editor-fold desc="Calculate density"> // point 1,1 double rpCoef = 64. / (9. * HX * HY); density[NY_1 * NX + NY] = -1. / 3. * (prev_density[NY_1 * NX + NY - 1] + prev_density[NY_1 * (NX - 1) + NY]) - 1. / 9. * prev_density[NY_1 * (NX - 1) + NY - 1] + rpCoef * phi[NY_1 * NX + NY]; if (fabs(density[NY_1 * NX + NY]) < fabs(DBL_MIN_TRIM)) density[NY_1 * NX + NY] = 0; // G3 -- (x_i, NY=D) -- top boundary rpCoef = 32. / (9. * HX * HY); for (int i = 1; i < NX; ++i) { density[NY_1 * i + NY] = -1. / 3. * prev_density[NY_1 * i + NY - 1] - 1. / 6. * (prev_density[NY_1 * (i + 1) + NY] + prev_density[NY_1 * (i - 1) + NY]) - 1. / 18. * (prev_density[NY_1 * (i + 1) + NY - 1] + prev_density[NY_1 * (i - 1) + NY - 1]) + rpCoef * phi[NY_1 * i + NY]; if (fabs(density[NY_1 * i + NY]) < fabs(DBL_MIN_TRIM)) density[NY_1 * i + NY] = 0; } // G2 -- (NX=B, y_j) -- right boundary rpCoef = 32. / (9. * HX * HY); for (int j = 1; j < NY; ++j) { density[NY_1 * NX + j] = -1. / 3. * prev_density[NY_1 * (NX - 1) + j] - 1. / 6. * (prev_density[NY_1 * NX + j - 1] + prev_density[NY_1 * NX + j + 1]) - 1. / 18. * (prev_density[NY_1 * (NX - 1) + j - 1] + prev_density[NY_1 * (NX - 1) + j + 1]) + rpCoef * phi[NY_1 * NX + j]; if (fabs(density[NY_1 * NX + j]) < fabs(DBL_MIN_TRIM)) density[NY_1 * NX + j] = 0; } rpCoef = 16. / (9. * HX * HY); for (int i = 1; i < NX; ++i) { for (int j = 1; j < NY; ++j) { density[NY_1 * i + j] = -1. / 6. * ( prev_density[NY_1 * i + j - 1] + // left prev_density[NY_1 * (i - 1) + j] + // upper prev_density[NY_1 * i + j + 1] + // right prev_density[NY_1 * (i + 1) + j] // bottom ) - 1. / 36. * ( prev_density[NY_1 * (i + 1) + j + 1] + // bottom right prev_density[NY_1 * (i + 1) + j - 1] + // bottom left prev_density[NY_1 * (i - 1) + j + 1] + // upper right prev_density[NY_1 * (i - 1) + j - 1] // upper left ) + rpCoef * phi[NY_1 * i + j]; if (fabs(density[NY_1 * i + j]) < fabs(DBL_MIN_TRIM)) density[NY_1 * i + j] = 0; } } ++ic; maxErr = FLT_MIN; for (int i = 0; i < NX_1; ++i) for (int j = 0; j < NY_1; ++j) { double val = fabs(density[i * NY_1 + j] - prev_density[i * NY_1 + j]); if (val > maxErr) maxErr = val; } //</editor-fold> //<editor-fold desc="Calculate residual"> // point 1,1 rpCoef = HX * HY / 64.; residual[NY_1 * NX + NY] = rpCoef * ( 9. * density[NY_1 * NX + NY] + 3. * ( density[NY_1 * NX + NY - 1] + density[NY_1 * (NX - 1) + NY] ) + density[NY_1 * (NX - 1) + NY - 1] ) - phi[NY_1 * NX + NY]; // G3 -- (x_i, NY=D) -- top boundary for (int i = 1; i < NX; ++i) residual[NY_1 * i + NY] = rpCoef * ( 18. * density[NY_1 * i + NY] + 6. * density[NY_1 * i + NY - 1] + 3. * ( density[NY_1 * (i + 1) + NY] + density[NY_1 * (i - 1) + NY] ) + density[NY_1 * (i + 1) + NY - 1] + density[NY_1 * (i - 1) + NY - 1] ) - phi[NY_1 * i + NY]; // G2 -- (NX=B, y_j) -- right boundary for (int j = 1; j < NY; ++j) residual[NY_1 * NX + j] = rpCoef * ( 18. * density[NY_1 * NX + j] + 6. * density[NY_1 * (NX - 1) + j] + 3. * ( density[NY_1 * NX + j - 1] + density[NY_1 * NX + j + 1] ) + density[NY_1 * (NX - 1) + j - 1] + density[NY_1 * (NX - 1) + j + 1] ) - phi[NY_1 * NX + j]; // inner points for (int i = 1; i < NX; ++i) { for (int j = 1; j < NY; ++j) { residual[NY_1 * i + j] = rpCoef * ( 36. * density[NY_1 * i + j] + 6. * ( density[NY_1 * i + j - 1] + // left density[NY_1 * (i - 1) + j] + // upper density[NY_1 * i + j + 1] + // right density[NY_1 * (i + 1) + j] // bottom ) + prev_density[NY_1 * (i + 1) + j + 1] + // bottom right prev_density[NY_1 * (i + 1) + j - 1] + // bottom left prev_density[NY_1 * (i - 1) + j + 1] + // upper right prev_density[NY_1 * (i - 1) + j - 1] // upper left ) - phi[NY_1 * i + j]; } } maxRes = FLT_MIN; for (int i = 0; i < NX_1; ++i) { for (int j = 0; j < NY_1; ++j) { double val = fabs(residual[i * NY_1 + j]); if (val > maxRes) maxRes = val; } } //</editor-fold> memcpy(prev_density, density, XY * sizeof(double)); } sum_rho = calc_array_sum(density, NX_1, NY_1, 0); sum_abs_rho = calc_array_sum(density, NX_1, NY_1, 1); extrems = calc_array_extrems(density, NX_1, NY_1); printf("tl = %d IterCount = %d Max(Residual) = %le Sum(Rho) = %le Sum(absRho) = %le " "Min(Rho) = %le Max(Rho) = %le\n", tl, ic, maxRes, sum_rho, sum_abs_rho, extrems[0], extrems[1]); fflush(stdout); if (tl % 1 == 0) { print_data_to_files(phi, density, residual, tl); double x_0 = get_center_x() + tl * TAU * func_u(0, 0, 0); double y_0 = get_center_y() + tl * TAU * func_v(0, 0, 0); int fixed_x = (int) (x_0 / HX); int fixed_y = (int) (y_0 / HY); print_line_along_x("rho", NX, NY, HX, HY, tl, A, C, x_0, y_0, TAU, U, V, density, fixed_y); print_line_along_y("rho", NX, NY, HX, HY, tl, A, C, x_0, y_0, TAU, U, V, density, fixed_x); } } double x_0 = get_center_x() + TIME_STEP_CNT * TAU * func_u(0, 0, 0); double y_0 = get_center_y() + TIME_STEP_CNT * TAU * func_v(0, 0, 0); int fixed_x = (int) (x_0 / HX); int fixed_y = (int) (y_0 / HY); /* print_line_along_x("rho", NX, NY, HX, HY, TIME_STEP_CNT, A, C, x_0, y_0, TAU, U, V, density, fixed_y); print_line_along_y("rho", NX, NY, HX, HY, TIME_STEP_CNT, A, C, x_0, y_0, TAU, U, V, density, fixed_x); */ double *err = calc_error_22(HX, HY, TAU * TIME_STEP_CNT, density); print_line_along_x("err", NX, NY, HX, HY, TIME_STEP_CNT, A, C, x_0, y_0, TAU, U, V, err, fixed_y); print_line_along_y("err", NX, NY, HX, HY, TIME_STEP_CNT, A, C, x_0, y_0, TAU, U, V, err, fixed_x); extrems_err = calc_array_extrems(err, NX_1, NY_1); err = calc_error_2(HX, HY, TAU * TIME_STEP_CNT, density); double l1_err_vec = get_l1_norm_vec(NX_1, NY_1, err); double l1_err_tr = get_l1_norm_int_trapezoidal(HX, HY, NX, NY, err); // note! a loop boundary extrems = calc_array_extrems(density, NX_1, NY_1); append_statistics(NX_1, NY_1, TAU, ic, l1_err_vec, l1_err_tr, maxRes, extrems, extrems_err, TIME_STEP_CNT); delete[] prev_density; delete[] phi; delete[] err; delete[] residual; delete[] extrems; delete[] extrems_err; return density; }