diff --git a/srcs/FEM/my_code.cpp b/srcs/FEM/my_code.cpp index d709f7e510f5a9cbc917f1b0988c18089ee25f15..ca1b86262cca5ec0755d45a7aae7d23433bfe696 100644 --- a/srcs/FEM/my_code.cpp +++ b/srcs/FEM/my_code.cpp @@ -26,7 +26,7 @@ int main(int argc, char **argv) /*--------Integration rule used in the code----------*/ // could be useful to pass it as an argument in the .geo file - std::string integration_rule = "CompositeGauss4"; // tested with other methods, OK too. + std::string integration_rule = "CompositeGauss2"; // tested with other methods, OK too. /*--------get physical groups--------------*/ std::map<std::string, std::pair<int, int>> groups; @@ -873,6 +873,18 @@ int main(int argc, char **argv) std::vector<std::vector<double>> data18(nbelems); std::vector<std::size_t> elems2D_bis(nbelems); + std::vector<int> nb_adjacent_elements(all_nodeTags.size()); // number of 2d elements adjacent to node (i+1) + std::vector<double> nodal_sigma_x(all_nodeTags.size()); // will store nodal values (may be helpful later) + std::vector<double> nodal_sigma_y(all_nodeTags.size()); + std::vector<double> nodal_sigma_xy(all_nodeTags.size()); + + for(int i = 0; i < all_nodeTags.size(); ++i){ + nb_adjacent_elements[i] = 0; + nodal_sigma_x[i] = 0.; + nodal_sigma_y[i] = 0.; + nodal_sigma_xy[i] = 0.; + } + // for each element type k=0; for (std::size_t ityp = 0; ityp < elementTypes.size(); ++ityp) @@ -950,9 +962,12 @@ int main(int argc, char **argv) int nodeTag = enods[numNodes * i + j]; nodal_displacement(2*j) = full_d_vector[2*(nodeTag-1)]; nodal_displacement(2*j+1) = full_d_vector[2*(nodeTag-1)+1]; + + nb_adjacent_elements[nodeTag-1] +=1; // -1 is because nodeTags begin at 1 } // looping over the nodes for (int j = 0; j < numNodes; ++j){ + int nodeTag = enods[numNodes * i + j]; // converting jacobian to Eigen format Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> > jacob(&jacobians[9*j+9*numNodes*i], 3, 3); @@ -990,12 +1005,15 @@ int main(int argc, char **argv) data16[k][j] = sigma(1); data17[k][j] = sigma(2); data18[k][j] = sqrt(sigma(0)*sigma(0) + sigma(1)*sigma(1) - sigma(0)*sigma(1) + 3*sigma(2)*sigma(2)); // VM stress in plane stress configuration + + nodal_sigma_x[nodeTag - 1] += sigma(0); + nodal_sigma_y[nodeTag - 1] += sigma(1); + nodal_sigma_xy[nodeTag - 1] += sigma(2); } k++; } } - std::cout << "hello"; gmsh::view::addModelData(viewtag11, 0, names[0], "ElementNodeData", elems2D_bis, data11, 1); // the last ,1 is important! gmsh::view::addModelData(viewtag12, 0, names[0], "ElementNodeData", @@ -1013,6 +1031,128 @@ int main(int argc, char **argv) gmsh::view::addModelData(viewtag18, 0, names[0], "ElementNodeData", elems2D_bis, data18, 1); // the last ,1 is important! + // empeche que tout se plot l'un sur l'autre + int nb_views = 18; //hardcoded + for( int i = 0; i < nb_views; ++i){ + std::string hello = "View[" + std::to_string(i) + "].Visible"; + gmsh::option::setNumber(hello, 0); + } + + // computing mean nodal values + for (int i = 0; i < all_nodeTags.size(); ++i){ + nodal_sigma_x[i] = nodal_sigma_x[i] / nb_adjacent_elements[i]; + nodal_sigma_y[i] = nodal_sigma_y[i] / nb_adjacent_elements[i]; + nodal_sigma_xy[i] = nodal_sigma_xy[i] / nb_adjacent_elements[i]; + } + + // computing reaction forces (if ux imposed, need to compute Rx (pareil pr y)) + // using INTEGRATION PAR TRAPEZE + double Rx = 0.; + double Ry = 0.; + for (auto &key : keys) + { + // get corresponding value + std::vector<double> value; + gmsh::onelab::getNumber(key, value); + // expected key structure is "type/group_name/field" + // => split the key string into components + std::stringstream ss(key); + std::vector<std::string> words; + std::string word; + while(std::getline(ss, word, '/')) // read string until '/' + words.push_back(word); + if(words.size()==3) + { + if(words[2].compare("ux") == 0 || words[2].compare("uy") == 0){ + Rx = 0; + Ry = 0; + groupname = words[1]; + std::cout << "-------------------- " << groupname << " ------------------- \n"; + + //loop over elements of group_name + dim = groups[groupname].first; + tag = groups[groupname].second; + if (tag == 0) + { + std::cerr << "Group '" << groupname << "' does not exist!\n"; + return 1; + } + gmsh::model::getEntitiesForPhysicalGroup(dim, tag, tags); + + // loop over entities + for (int k = 0; k < tags.size(); ++k) + { + std::vector<int> elementTypes; + std::vector<std::vector<std::size_t>> elementTags; + std::vector<std::vector<std::size_t>> nodeTags; + gmsh::model::mesh::getElements(elementTypes, elementTags, + nodeTags, dim, tags[k]); + + for (int i = 0; i < elementTypes.size(); ++i) + { + + // getting element properties + std::string elementName; + int dim, order, numNodes, numPrimaryNodes; + std::vector<double> localNodeCoord; + gmsh::model::mesh::getElementProperties(elementTypes[i], + elementName, dim, order, + numNodes, localNodeCoord, + numPrimaryNodes); + // getting nodal coordinates + std::vector<std::size_t> my_nodeTags; // rien de nouveau % nodeTags[i] + std::vector<double> model_coord; // utile ici !! les coordonnées + std::vector<double> param_coord; // inutile + gmsh::model::mesh::getNodesByElementType(elementTypes[i], my_nodeTags, model_coord, param_coord, tags[k]); + + //looping over the elements (they are 1D -> 2 nodes) + for (int el = 0; el < elementTags[i].size(); el++){ + int first_node = nodeTags[i][numNodes*el]; + int second_node = nodeTags[i][numNodes*el + 1]; + + // retrieving the coordinates + double x1 = model_coord[3*numNodes*el]; + double y1 = model_coord[3*numNodes*el + 1]; + double x2 = model_coord[3*numNodes*el + 3]; + double y2 = model_coord[3*numNodes*el + 4]; + // computing the normal (how to deal with the signs ?????) + double dx = x1 - x2; + double dy = y1 - y2; + double length = sqrt(dx*dx+dy*dy); + double nx; + double ny; + if (dx == 0){ + nx = 1; + ny = 0; + } + else if (dy == 0){ + nx = 0; + ny = 1; + } + else{ + double slope = dx/dy; + nx = 1/sqrt(slope*slope+1); + ny = slope/sqrt(slope*slope+1); + } + + double mean_sigma_x = (nodal_sigma_x[first_node - 1] + nodal_sigma_x[second_node - 1])/2; //-1 because nodeTags begin at 1 + double mean_sigma_y = (nodal_sigma_y[first_node - 1] + nodal_sigma_y[second_node - 1])/2; + double mean_sigma_xy = (nodal_sigma_x[first_node - 1] + nodal_sigma_xy[second_node - 1])/2; + + if(words[2].compare("ux") == 0){ + Rx += (mean_sigma_x*nx + mean_sigma_xy*ny)*length; + } + if(words[2].compare("uy") == 0){ + Ry += (mean_sigma_xy*nx + mean_sigma_y*ny)*length; + } + } + } + } + std::cout << "Rx: " << Rx << " [N/m], Ry: " << Ry << " [N/m] \n"; + } + } + } + gmsh::fltk::run(); // opens the gmsh window gmsh::finalize();