diff --git a/Pre/TPZGmshReader.cpp b/Pre/TPZGmshReader.cpp index cc8e3b05d..0dcb69384 100644 --- a/Pre/TPZGmshReader.cpp +++ b/Pre/TPZGmshReader.cpp @@ -33,6 +33,8 @@ #include "TPZGeoElement.h" #include "TPZRefPattern.h" #include "tpzgeoelrefpattern.h" +#include "pzvec_extras.h" +#include "TPZParallelUtils.h" #include TPZGmshReader::TPZGmshReader() { @@ -438,6 +440,7 @@ void TPZGmshReader::ReadPeriodic4(std::istream &read) std::string str_end; read >> str_end; assert(str_end == "$EndPeriodic" || str_end == "$EndPeriodic\r"); + std::cout << "Finished reading periodic elements, setting periodicity..."<< std::endl; /*now we need to find the correspondence between periodic elements we will both: - create the periodic_els map that relates the ids of dependent/independent @@ -446,8 +449,9 @@ void TPZGmshReader::ReadPeriodic4(std::istream &read) in the independent el. this ensures that they will have the same orientation */ + SetPeriodicElements(m_gmesh, entity_periodic_nodes, periodic_entities); - + std::cout<<"Finished setting periodicity!"< periodic_physical_ids; /**for a given region, all the periodic nodes. indexed by the dimension of the physical region.*/ - std::vector>> - periodic_nodes_by_physical_ids(4); + constexpr int big_alloc{20000}; + + TPZManVector dep_ids, indep_ids; + std::map periodic_nodes_map; + for (int idim = 0; idim < max_dimension; idim++) { // just to make it more readable auto &physical_entity_map = m_dim_entity_tag_and_physical_tag[idim]; @@ -1375,13 +1382,14 @@ void TPZGmshReader::SetPeriodicElements( periodic_physical_ids[depid] = indepid; const auto periodic_nodes = entity_periodic_nodes[idim][deptag]; for (auto [dep, indep] : periodic_nodes) { - periodic_nodes_by_physical_ids[idim][depid][dep] = indep; + dep_ids.push_back(dep); + indep_ids.push_back(indep); + periodic_nodes_map[dep]=indep; } } } } - - std::set dep_ids, indep_ids; + /* now we just want to change the ids of the dependent nodes so as to match the ordering of the independent nodes @@ -1389,22 +1397,10 @@ void TPZGmshReader::SetPeriodicElements( //contain all periodic nodes { - TPZManVector,100000> all_per_nodes; - - for(auto &all_periodic_ids : periodic_nodes_by_physical_ids){ - for(const auto &[_,periodic_ids] : all_periodic_ids){ - for(const auto &[dep_node,indep_node] : periodic_ids){ - all_per_nodes.push_back({dep_node,indep_node}); - } - } - } - - for(auto [dep,indep] : all_per_nodes){ - dep_ids.insert(dep); - indep_ids.insert(indep); - } + RemoveDuplicates(dep_ids); + RemoveDuplicates(indep_ids); - TPZManVector common_ids; + TPZManVector common_ids; std::set_intersection(dep_ids.begin(),dep_ids.end(), indep_ids.begin(),indep_ids.end(), std::inserter(common_ids,common_ids.begin())); @@ -1417,13 +1413,9 @@ void TPZGmshReader::SetPeriodicElements( const int n_nodes = dep_ids.size(); auto d_i = dep_ids.begin(); auto i_i = indep_ids.begin(); - for(auto i = 0; i < n_nodes; i++){ - auto dep_node = all_per_nodes[i].first; - auto indep_node = all_per_nodes[i].second; - m_gmesh->NodeVec()[dep_node].SetNodeId(*d_i); - m_gmesh->NodeVec()[indep_node].SetNodeId(*i_i); - d_i++; - i_i++; + for(const auto &[dep_node,indep_node] : periodic_nodes_map){ + m_gmesh->NodeVec()[dep_node].SetNodeId(*d_i++); + m_gmesh->NodeVec()[indep_node].SetNodeId(*i_i++); } } /** @@ -1432,117 +1424,64 @@ void TPZGmshReader::SetPeriodicElements( now we no longer have index == id */ for (auto depel : gmesh->ElementVec()) { - const auto dim = depel->Dimension(); const auto depmatid = depel->MaterialId(); - if (periodic_nodes_by_physical_ids[dim].find(depmatid) == - periodic_nodes_by_physical_ids[dim].end()){continue;} - auto &periodic_nodes = periodic_nodes_by_physical_ids[dim][depmatid]; + //not a dependent periodic mat + if (periodic_physical_ids.find(depmatid) == + periodic_physical_ids.end()){continue;} //we have found a dependent el const auto nnodes = depel->NNodes(); const auto nsides = depel->NSides(); const auto dep_type = depel->Type(); - TPZManVector mapped_nodes(nnodes); + constexpr int max_nnodes{8}; + TPZManVector mapped_nodes(nnodes); for (auto in = 0; in < nnodes; in++) { const auto depnode = depel->NodeIndex(in); -#ifdef PZDEBUG - if(periodic_nodes.find(depnode) == periodic_nodes.end()){ - PZError<<__PRETTY_FUNCTION__ - <<"\nnode "<ElementVec()) { - if(found_indep){break;} - const int indep_type = indepel->Type(); - const bool sametype = indep_type == dep_type; - constexpr int max_nnodes{8}; + TPZGeoEl* indepel{nullptr}; + const int nelem = gmesh->ElementVec().NElements(); + for(auto gel : gmesh->ElementVec()){ + if(indepel){break;} + if (gel->MaterialId() != indepmatid || + gel->Type() != dep_type) {continue;} + TPZManVector indepnodes(nnodes); - indepel->GetNodeIndices(indepnodes); - if (indepel->MaterialId() == indepmatid && sametype) { - bool samenodes = true; - for (auto in = 0; in < nnodes && samenodes; in++) { - const auto indepnode = indepnodes[in]; - const bool hasnode = - std::find(mapped_nodes.begin(), mapped_nodes.end(), - indepnode) != mapped_nodes.end(); - samenodes = samenodes && hasnode; - } - if (samenodes) { - m_periodic_els[depel->Id()] = indepel->Id(); - found_indep=true; - //now we check if we need to change orientation - bool sameorient{true}; - for (auto in = 0; in < nnodes && sameorient; in++) { - if(indepnodes[in] != mapped_nodes[in]){ - sameorient=false; - } - } - //nothing to else be done here - if(sameorient){break;} - /* - WARNING: - right now, SetPeriodic is called before BuildConnectivity. - should this change in the future, changing node ordering is - not enough, connectivity should be changed as well. - For this purpose, TPZChangeEl::ChangeNodeOrdering - should be sued. - */ - for (auto in = 0; in < nnodes; in++) { - const auto mapped = mapped_nodes[in]; - indepel->SetNodeIndex(in, mapped); - } - //since we are changing node ordering we dont need to perform this check again -#ifdef PZDEBUG2 - const int dim = depel->Dimension(); - TPZManVector qsi(dim,0); - TPZFNMatrix<9,REAL> jac, jacinv; - REAL detjac; - TPZFNMatrix<9,REAL> dep_axes, indep_axes,res; - depel->Jacobian(qsi,jac,dep_axes,detjac,jacinv); - indepel->Jacobian(qsi,jac,indep_axes,detjac,jacinv); - res = dep_axes; - res -= indep_axes; - constexpr REAL tol{1e-8}; - const int nr = res.Rows(); - const int nc = res.Cols(); - for(int ir = 0; ir < nr; ir++){ - for(int ic = 0; ic < nc; ic++){ - if(res.GetVal(ir,ic) > tol){ - PZError<<__PRETTY_FUNCTION__ - <<"\nError in periodic elements orientation!\n" - <<"dep el "<Id()<<" indep el "<Id()< qsi(depel->Dimension(),0), xcenter(3,0); - depel->CenterPoint(depel->NSides()-1, qsi); - depel->X(qsi,xcenter); - PZError<<"dep el center : "<CenterPoint(indepel->NSides()-1, qsi); - indepel->X(qsi,xcenter); - PZError<<"indep el center : "<NodeIndex(in) - // <<" indep "<NodeIndex(in) - // <<" map(dep) "<NodeIndex(in)) - // <GetNodeIndices(indepnodes); + bool samenodes = true; + for (auto in = 0; in < nnodes && samenodes; in++) { + const auto indepnode = indepnodes[in]; + const bool hasnode = + std::find(mapped_nodes.begin(), mapped_nodes.end(), + indepnode) != mapped_nodes.end(); + samenodes = samenodes && hasnode; } + if (!samenodes) {continue;} + indepel=gel; + } + m_periodic_els[depel->Id()] = indepel->Id(); + //now we check for node ordering + TPZManVector indepnodes(nnodes); + indepel->GetNodeIndices(indepnodes); + bool sameorient{true}; + for (auto in = 0; in < nnodes && sameorient; in++) { + if(indepnodes[in] != mapped_nodes[in]){ + sameorient=false; + } + } + //nothing to else be done here + if(sameorient){continue;} + /* + WARNING: + right now, SetPeriodic is called before BuildConnectivity. + should this change in the future, changing node ordering is + not enough, connectivity should be changed as well. + For this purpose, TPZChangeEl::ChangeNodeOrdering + should be sued. + */ + for (auto in = 0; in < nnodes; in++) { + const auto mapped = mapped_nodes[in]; + indepel->SetNodeIndex(in, mapped); } } }