void TransformerSPRINGEMBEDDER::SpringEmbed(Graph& G, vector<float> dimension_limits, IntermediateStepHandler* intermediatestephandler) { vector<VectorND> tractions; int dimensions = dimension_limits.size(); unstressed_spring_length = dimension_limits[0]; for(int i = 1; i < dimensions; i++) unstressed_spring_length *= dimension_limits[i]; unstressed_spring_length /= G.NumberOfVertices(); unstressed_spring_length = pow(unstressed_spring_length, 1.0f/dimensions) / (dimensions * 2); // init srand ( time(NULL) ); for(VertexIterator a = G.BeginVertices(); a != G.EndVertices(); a++) { Coordinates coordinates; for(int i = 0; i < dimensions; i++) coordinates.push_back(fmod(rand(), dimension_limits[i])); (*a)->SetCoordinates(coordinates); // should make sure that no two vertices have the same position tractions.push_back(VectorND(dimensions)); } float max_movement; iteration = 0; do { // compute movement max_movement = 0; int i = 0; for(VertexIterator a = G.BeginVertices(); a != G.EndVertices(); a++, i++) { VectorND traction = tractions[i] * friction; // compute forces on a by the other vertices VectorND aCoordinates((*a)->GetCoordinates(0)); for(VertexIterator b = G.BeginVertices(); b != G.EndVertices(); b++) { if(b==a) continue; // force on a by vertex b VectorND bCoordinates((*b)->GetCoordinates(0)); traction += coulomb(aCoordinates, bCoordinates); if((*a)->Adjacent(*b)) traction += hooke(aCoordinates, bCoordinates); } tractions[i] = traction; } // execute movement VertexIterator a = G.BeginVertices(); for(int i = 0; a != G.EndVertices(); a++, i++) { Coordinates OldCoordinates = (*a)->GetCoordinates(0); Coordinates NewCoordinates(dimensions); for(int j = 0; j < dimensions; j++) NewCoordinates[j] = max(0.0f,min(dimension_limits[j], OldCoordinates[j] + delta * tractions[i][j] )); (*a)->SetCoordinates( NewCoordinates ); // for the loop-condition float current_movement = 0.0f; for(int j = 0; j < dimensions; j++) current_movement += (OldCoordinates[j] - NewCoordinates[j]) * (OldCoordinates[j] - NewCoordinates[j]); if(sqrt(current_movement) > max_movement) max_movement = sqrt(current_movement); } if(intermediatestephandler != NULL) intermediatestephandler->Handle(&G); if(++iteration > nextincrease) { movement_threshold += 0.01f; nextincrease *= 4; } if(iteration > max_iterations) break; } while(max_movement > movement_threshold*unstressed_spring_length); }
TPZGeoMesh * TPZHierarquicalGrid::ComputeExtrusion(REAL t, REAL dt, int n) { fSubBases.Resize(n+1); fComputedGeomesh = new TPZGeoMesh; int NNodesBase = fBase->NNodes(); fComputedGeomesh->NodeVec().Resize( (n+1) * NNodesBase); // Creating new elements int nodeId = 0; REAL sing = 1.0; for(int il = 0; il < (n+1); il++ ) { // copying l extrusions // For a while all of them are equal // fSubBases[il] = new TPZGeoMesh(fBase); for(int inode = 0; inode < NNodesBase; inode++) { TPZVec<REAL> tpara(1),NewCoordinates_r(3,0.0); TPZVec<REAL> NewCoordinates(3,0.0); tpara[0] = dt*il+t; TPZVec<REAL> Coordinates(3,0.0); fComputedGeomesh->NodeVec()[inode + il * NNodesBase] = fBase->NodeVec()[inode]; // NewGeomesh->NodeVec()[inode + il*fBase->NNodes()] = fSubBases[il]->NodeVec()[inode]; fComputedGeomesh->NodeVec()[inode + il * NNodesBase].GetCoordinates(Coordinates); fParametricFunction->Execute(tpara,NewCoordinates); NewCoordinates_r[0] = REAL(NewCoordinates[0]); NewCoordinates_r[1] = REAL(NewCoordinates[1]); NewCoordinates_r[2] = REAL(NewCoordinates[2]); if(((il+1)%2==0 && fNonAffineQ) && fBase->Dimension() == 2){ Coordinates[0]+=NewCoordinates_r[0]; Coordinates[1]+=NewCoordinates_r[1]; Coordinates[2]+=NewCoordinates_r[2]; Coordinates[2]+= sing*dt/2.0; sing *= -1.0; } else{ Coordinates[0]+=NewCoordinates_r[0]; Coordinates[1]+=NewCoordinates_r[1]; Coordinates[2]+=NewCoordinates_r[2]; } fComputedGeomesh->NodeVec()[inode + il * NNodesBase].SetCoord(Coordinates); fComputedGeomesh->NodeVec()[inode + il * NNodesBase].SetNodeId(nodeId); nodeId++; } } fComputedGeomesh->SetMaxNodeId(nodeId); // int fbasedim = fBase->Dimension(); int elid=0; for(int iel = 0; iel < fBase->NElements(); iel++) { int ielDim = fBase->ElementVec()[iel]->Dimension(); int ielMatId = fBase->ElementVec()[iel]->MaterialId(); CreateGeometricElement(n,iel,ielDim,ielMatId,elid); } fComputedGeomesh->SetMaxElementId(elid); fComputedGeomesh->BuildConnectivity(); return fComputedGeomesh; }