void CurrentSource::add_initial_dc() { if (!b_status) return; b_i(0) -= m_i; b_i(1) += m_i; }
vector<int> grid_index::points_near_segment(Vec2 a, Vec2 b, mesh2d& idxd, int additional_cells) { /* this function will return points that are nearby a potential segment (NOT present inside mesh2d) NOTE: we could make this code specific to the use case required, meaning line-point distance, but it's not really necessary and sounds like premature optimization, on top of requiring more filtering (needs the point nearest to pt_a. */ vector<int> results; set<Vec2i> cells; Vec2i a_i(a * resolution); Vec2i b_i(b * resolution); // msgm(a_i, b_i); // if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x)-additional_cells; int x_hi = max(a_i.x, b_i.x)+additional_cells; int y_lo = min(a_i.y, b_i.y)-additional_cells; int y_hi = max(a_i.y, b_i.y)+additional_cells; for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { if(x>-1 && y>-1 && x<resolution && y<resolution){ cells.insert({x,y}); } } } } // else { // cells.insert(a_i); // } // msg(cells); set<int> already; for (auto&cell : cells) { // auto range = bucket_segments.equal_range(cell); auto range = bucket_points.equal_range(cell); for (auto it = range.first; it != range.second; ++it) { // if (already.count(it->second)) {msgm("skipping,",it->second); continue;} if (already.count(it->second)) {continue;} // msg(it->second); already.insert(it->second); results.push_back(it->second); } } return results; }
long matrix::mul_ijk(const matrix *a, const matrix *b, matrix *r) { int width, height; a->size(&height, &width); for (int i = 0; i < height; i++) { iter_row r_i(r, i); for (int j = 0; j < height; j++) { iter_row a_i(a, i); iter_col b_i(b, j); double n = 0; for (int k = 0; k < width; k++) { n += **a_i * **b_i; a_i++; b_i++; } **r_i = n; r_i++; } } return (long)width * width * height * 2; }
long matrix::mul_kij(const matrix *a, const matrix *b, matrix *r) { int width, height, h_div, h_mod; a->size(&height, &width); h_div = height / 16; h_mod = height % 16; for (iter_all i(r); *i; i++) **i = 0; for (int k = 0; k < width; k++) { iter_col a_i(a, k); for (int i = 0; i < height; i++) { number n = **a_i; a_i++; iter_row b_i(b, k); iter_row r_i(r, i); for (int j = 0; j < h_div; j++) { (*r_i)[0] += (*b_i)[0] * n; (*r_i)[1] += (*b_i)[1] * n; (*r_i)[2] += (*b_i)[2] * n; (*r_i)[3] += (*b_i)[3] * n; (*r_i)[4] += (*b_i)[4] * n; (*r_i)[5] += (*b_i)[5] * n; (*r_i)[6] += (*b_i)[6] * n; (*r_i)[7] += (*b_i)[7] * n; (*r_i)[8] += (*b_i)[8] * n; (*r_i)[9] += (*b_i)[9] * n; (*r_i)[10] += (*b_i)[10] * n; (*r_i)[11] += (*b_i)[11] * n; (*r_i)[12] += (*b_i)[12] * n; (*r_i)[13] += (*b_i)[13] * n; (*r_i)[14] += (*b_i)[14] * n; (*r_i)[15] += (*b_i)[15] * n; r_i += 16; b_i += 16; } for (int j = 0; j < h_mod; j++) { **r_i += **b_i * n; r_i++; b_i++; } } } return (long)width * width * height * 2; }
void grid_index::add(Vec2 a, Vec2 b, int i) { Vec2i a_i(a * resolution); Vec2i b_i(b * resolution); // msgm("adding segment", i, "coords", a, b); if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x); int x_hi = max(a_i.x, b_i.x); int y_lo = min(a_i.y, b_i.y); int y_hi = max(a_i.y, b_i.y); for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { bucket_segments.insert({ {x,y},i}); } } } else { //msgm("adding", i, ) bucket_segments .insert({ a_i,i}); } }
void add(Vec2 a, Vec2 b, int i) { Vec2i a_i(a / resolution); Vec2i b_i(b / resolution); if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x); int x_hi = max(a_i.x, b_i.x); int y_lo = min(a_i.y, b_i.y); int y_hi = max(a_i.y, b_i.y); for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { bucket_index.insert({ {x,y},i }); } } } else { bucket_index.insert({ a_i,i }); } if (i == 0) msg("SAY WAT AGAIN"); }
int grid_index::intersects(Vec2 a, Vec2 b, mesh2d& idxd, vector<pair<int,Vec2>> &results) { set<Vec2i> cells; Vec2i a_i(a * resolution); Vec2i b_i(b * resolution); // msgm(a_i, b_i); if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x); int x_hi = max(a_i.x, b_i.x); int y_lo = min(a_i.y, b_i.y); int y_hi = max(a_i.y, b_i.y); for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { cells.insert({x,y}); } } } else { cells.insert(a_i); } set<int> already; for (auto&cell : cells) { // auto range = bucket_index.equal_range(cell); auto range = bucket_segments.equal_range(cell); for (auto it = range.first; it != range.second; ++it) { // if (it->second > -1 || already.count(it->second)) continue; if (already.count(it->second)) continue; already.insert(it->second); // auto segment = idxd[-(it->second)-1]; auto segment = idxd[it->second]; //pair<Vec2, Vec2> segment = idxd[it->second]; Vec2 itsc_pt; bool inter = ::intersects(a, b, segment.first, segment.second, itsc_pt); if (inter) { results.push_back({ it->second, itsc_pt }); } } } return results.size(); }
void SolveSystem ( Vector<double, int>& x_local, const MatrixDense<double, int>& K_local, const Vector<double, int>& b_local, const int numb_node_i, const int* list_node_i, const int* l2i, int numb_node_p, const int* list_node_p, const int* l2p, const int numb_global_node, const int numb_l2g, const int* l2g, const MPI_Comm& mpi_comm ) { // -- number of processors int numb_procs; // -- process number (process rank) int proc_numb; // -- get number of processes MPI_Comm_size( mpi_comm, &numb_procs ); // -- get current process rank MPI_Comm_rank( mpi_comm, &proc_numb ); MatrixDense<double,int> Kii; MatrixDense<double,int> Kip; MatrixDense<double,int> Kpi; MatrixDense<double,int> Kpp; Schur::SplitMatrixToBlock(Kii, Kip, Kpi, Kpp, K_local, list_node_i, numb_node_i, list_node_p, numb_node_p); // Check transpose //CheckTranspose(Kip, Kpi); // Reconstruct K //std::string gmatrix_filename = "../output/cube-125_2/cube-125_g_2.csv"; //ReconstructK(K_local, l2g, numb_global_node, gmatrix_filename, mpi_comm); // LU factorization of Kii MatrixDense<double, int> Kii_lu; Factor::LU(Kii_lu, Kii); MatrixDense<double, int> Uii_inv,Lii_inv; Lii_inv.Allocate(numb_node_i, numb_node_i); Uii_inv.Allocate(numb_node_i, numb_node_i); Vector<double, int> x,rhs; rhs.Allocate(numb_node_i); for(int i = 0;i < numb_node_i;++i) rhs(i) = 0; // invert Lii and Uii for(int i = 0;i < numb_node_i;++i){ if(i > 0) rhs(i - 1) = 0; rhs(i) = 1; DirectSolver::Forward(x, Kii_lu, rhs); for(int j = 0;j < numb_node_i;++j) Lii_inv(j,i) = x(j); DirectSolver::Backward(x,Kii_lu, rhs); for(int j = 0;j < numb_node_i;++j) Uii_inv(j,i) = x(j); } // calculate S_local MatrixDense<double, int> Lpi,Uip,prod; Kpi.MatrixMatrixProduct(Lpi, Uii_inv); Lii_inv.MatrixMatrixProduct(Uip, Kip); Lpi.MatrixMatrixProduct(prod, Uip); MatrixDense<double, int> S_local; Kpp.MatrixMatrixSubstraction(S_local, prod); // merge all numb_node_p in one list int length_list_p[numb_procs]; MPI_Allgather(&numb_node_p, 1, MPI_INT, length_list_p, 1, MPI_INT, mpi_comm); /*std::stringstream out_length_list; for(int i = 0;i < numb_procs;++i){ out_length_list << length_list_p[i] << " "; } out_length_list << "\n";*/ int all_list_global_p[numb_procs][numb_global_node]; for(int i = 0;i < numb_procs;++i){ if(proc_numb == i){ for(int j = 0;j < numb_node_p;++j){ all_list_global_p[i][j] = l2g[ list_node_p[j] ]; } } MPI_Bcast(all_list_global_p[i], length_list_p[i], MPI_INT, i, mpi_comm); } /*for(int i = 0;i < numb_procs;++i){ for(int j = 0;j < length_list_p[i];++j){ out_length_list << all_list_global_p[i][j] << " "; } out_length_list << "\n"; } iomrg::printf("%s\n", out_length_list.str().c_str());*/ // create array pos_S : from global position to position in S int pos_S[numb_global_node]; for(int i = 0;i < numb_global_node;++i){ pos_S[i] = -1; } std::vector<int> S_indices; for(int i = 0;i < numb_procs;++i){ for(int j = 0;j < length_list_p[i];++j){ S_indices.push_back(all_list_global_p[i][j]); } } std::sort(S_indices.begin(), S_indices.end()); S_indices.erase(std::unique(S_indices.begin(), S_indices.end()), S_indices.end()); int size_S = S_indices.size(); for(int i = 0;i < size_S;++i){ pos_S[ S_indices[i] ] = i; } // Assemble S MatrixDense<double, int> S; S.Allocate(size_S, size_S); S.Initialize(0); double aux_coef[size_S]; iomrg::printf("size_S = %d\n",size_S); for(int i = 0;i < numb_procs;++i){ int size_local_S = length_list_p[i]; for(int j = 0;j < size_local_S;++j){ if(proc_numb == i){ for(int k = 0;k < size_local_S;++k){ aux_coef[k] = S_local(j,k); } } MPI_Bcast(aux_coef, size_local_S, MPI_DOUBLE, i, mpi_comm); int r = pos_S[ all_list_global_p[i][j] ]; for(int k = 0;k < size_local_S;++k){ S(r, pos_S[ all_list_global_p[i][k] ]) += aux_coef[k]; } } } // Separate b_local Vector<double, int> b_i,b_p; b_i.Allocate(numb_node_i); b_p.Allocate(numb_node_p); for(int i = 0;i < numb_l2g;++i){ if(l2p[i] == -1){ b_i( l2i[i] ) = b_local(i); }else{ b_p( l2p[i] ) = b_local(i); } } // Calculate y_p_local Vector<double, int> z; DirectSolver::Forward(z, Kii_lu, b_i); Vector<double, int> aux_prod; Lpi.MatrixVectorProduct(aux_prod, z); Vector<double, int> y_p_local; y_p_local.Allocate(numb_node_p); for(int i = 0;i < numb_node_p;++i){ y_p_local(i) = b_p(i) - aux_prod(i); } // Calculate y_p Vector<double, int> y_p(size_S); for(int i = 0;i < size_S;++i){ aux_coef[i] = 0; } for(int i = 0;i < numb_node_p;++i){ aux_coef[ pos_S[ l2g[ list_node_p[i] ] ] ] += y_p_local(i); } MPI_Allreduce(aux_coef, y_p.GetCoef(), size_S, MPI_DOUBLE, MPI_SUM,mpi_comm); // Calculate x_p Vector<double, int> x_p; DirectSolver::SolveLU(x_p, S, y_p); // Calculate y_i Vector<double, int> aux_prod_2; aux_prod_2.Allocate(numb_node_i); aux_prod_2.Assign(0, numb_node_i - 1, 0); for(int i = 0;i < numb_node_i;++i){ for(int j = 0;j < numb_node_p;++j){ int id_S = pos_S[ l2g[ list_node_p[j] ] ]; aux_prod_2(i) += Uip(i,j) * x_p(id_S); } } Vector<double, int> y_i; y_i.Allocate(numb_node_i); for(int i = 0;i < numb_node_i;++i){ y_i(i) = z(i) - aux_prod_2(i); } // Calculate x_i Vector<double, int> x_i; DirectSolver::Backward(x_i, Kii_lu, y_i); // Assemble x_local for(int i = 0;i < numb_node_i;++i){ x_local(list_node_i[i]) = x_i(i); } for(int i = 0;i < numb_node_p;++i){ x_local(list_node_p[i]) = x_p(i); } }