Como começar com a API - Otimizar componentes numa ligação 04

Este artigo também está disponível em:
Traduzido por IA a partir do inglês
Neste tutorial, aprenderá a otimizar alguns componentes (soldaduras, parafusos) numa ligação utilizando parâmetros.

Primeiros passos

Recomendamos que consulte o tutorial Como começar com a API - Noções básicas 01, que o ensina sobre a API e como configurar o ambiente.

Ficheiro de ligação 

Este exemplo baseia-se em ficheiros criados no tutorial Como começar com a API - Importar um modelo e executar o cálculo 03.

Por favor, descarregue o ficheiro tutorial 03 with template-new.ideaCon.

inline image in article

Pretendemos otimizar os componentes da ligação (soldaduras, diâmetro e número de parafusos). O resultado da otimização são os custos da junta, apresentados de forma clara num gráfico.

Cliente Python

Execute o "IdeaStatiCa.ConnectionRestApi.exe" no CMD dentro da pasta correta do IDEA StatiCa e abra a ferramenta IDE da sua preferência.

inline image in article
  • Crie um novo ficheiro e importe os pacotes que permitirão a utilização do cálculo e a ligação com o URL do localhost. 

Código fonte:

## Import of API package
from ideastatica_connection_api.models.con_calculation_parameter import ConCalculationParameter
from ideastatica_connection_api.models.idea_parameter_update import IdeaParameterUpdate

## Link with baseUrl
import ideastatica_connection_api.connection_api_service_attacher as connection_api_service_attacher
from ideastatica_connection_api.models.con_calculation_parameter import ConCalculationParameterfrom ideastatica_connection_api.models.con_production_cost import ConProductionCost

#additional packages
import matplotlib.pyplot as plt
import numpy as np
from typing import Concatenate

inline image in article
  • Configure o registo através da variável "baseUrl," que irá carregar o seu localhost. No segundo passo, associe o caminho absoluto do seu ficheiro IDEA StatiCa Connection.

## Configure logging
baseUrl = "http://localhost:5000"

## Absolute path into folder with your python script and connection module
project_file_path = r"C:\Users\AlexanderSzotkowski\Documents\IDEA\API\Tutorial 04\tutorial 03 with template -new.ideaCon"
print(project_file_path)

  • Associe o cliente a um serviço já em execução. Utilize o bloco try/except - uma vez que o bloco try gera um erro, o bloco except será executado. Na primeira fase, é necessário abrir o projeto e encontrar o ID do projeto, que é único para cada projeto IDEA StatiCa. De seguida, selecionamos a primeira ligação armazenada no nosso ficheiro.

# Create a client attached to an already running service
with connection_api_service_attacher.ConnectionApiServiceAttacher(baseUrl).create_api_client() as api_client:
    try:
        # Open project
        print("Opening project %s" % project_file_path)
       #api_client.project.active_project_id  - ID of opened project
       openedProject = api_client.project.open_project_from_filepath(project_file_path)      

       #openedProject.connections = [  {Con1}, {Con2}, {Con3} ....      ]
       firstConId = openedProject.connections[0].id
       activeProjectId = api_client.project.active_project_id
       print("Active project ID: %s" % activeProjectId)

inline image in article
  • Obtenha todos os parâmetros necessários do ficheiro ideaCon (número de parafusos, diâmetro, dimensão da soldadura, conjunto de parafusos)

       #get parameters from ideaCon file
       include_hidden = True
       parameters = api_client.parameter.get_parameters(activeProjectId, firstConId, include_hidden=include_hidden)       
       #get default values from the ideaCon file
       #Diameter of the bolt
       boltParameter = parameters[3]
       #print('bolt ',boltParameter.value)
       #Number of bolt rows
       rowParameter = parameters[11]
       #print('row ',rowParameter.value)
       #Weld size
       weldParameter = parameters[28]
       #print('weld ',weldParameter.value)
       #Bolt assembly
       boltAssemblyParameter = parameters[29]
       #print('bolt assembly ',boltAssemblyParameter.value)

  • Pretendemos obter resultados apenas quando o cálculo é 100% positivo para todas as partes (chapas, soldaduras, parafusos), pelo que temos de definir Parar na deformação limite como Verdadeiro. Os resultados serão armazenados numa lista denominada matrix, que utilizamos posteriormente para apresentar um gráfico.

       #setup
      updateSettings = api_client.settings.get_settings(api_client.project.active_project_id)

       from typing import Dict
       updateSettings: Dict [str, object] = {
        "calculationCommon/Analysis/AnalysisGeneral/Shared/StopAtLimitStrain@01" : True,
        "calculationCommon/Checks/Shared/LimitPlasticStrain@01" : 0.05        
             }
       api_client.settings.update_settings(api_client.project.active_project_id, updateSettings)  

       #Final results database
       matrix = []             

inline image in article
  • Agora, iniciamos um ciclo alterando as soldaduras (de t = 8 a 5 mm), o diâmetro dos parafusos (de M16 a M12) e o número de fiadas (de 3 a 1). Os valores 8, M16 e 3 são valores retirados do ficheiro ideaCon. Os resultados em curso são apresentados no ecrã e também adicionados à lista de resultados.

       #cycling through welds with given rows and bolts
       for row in range(rowParameter.value,1, -1):
           #print ('Number of bolt rows is', row)
           for bolt in range(int(1000*boltParameter.value), 12,-2):               

               for weld in range(int(1000*weldParameter.value), 5,-1):                   

                   par_row = IdeaParameterUpdate()            # Create a new instance
                   par_row.key = rowParameter.key
                   par_row.expression = str(row)                    

                   par_bolt = IdeaParameterUpdate()            # Create a new instance
                   par_bolt.key = boltParameter.key
                   par_bolt.expression = str(bolt/1000)  # Decrement the expression                                                        

                   par_boltAssembly = IdeaParameterUpdate()            # Create a new instance  
                 par_boltAssembly.key = boltAssemblyParameter.key
                 par_boltAssembly.expression = str('M'+ str(bolt) + ' 8.8')                                 

                   par_weld = IdeaParameterUpdate()            # Create a new instance
                   par_weld.key = weldParameter.key
                   par_weld.expression = str(weld/1000)  # Decrement the expression

                   updateResponse = api_client.parameter.update(activeProjectId, firstConId, [par_row, par_bolt, par_boltAssembly, par_weld]  )
                   updateResponse.set_to_model                                 

                   # Check if the parameters were updated successfully
                   if updateResponse.set_to_model == False:
                  print('Parameters failed: %s' % ', '.join(updateResponse.failed_validations))

                   #set the type of analysis
                   ConCalculationParameter.analysis_type = "stress_strain"                        

                   conParameter = ConCalculationParameter()
                   conParameter.connection_ids = [ firstConId ]
                   summary = api_client.calculation.calculate(activeProjectId, conParameter.connection_ids)                    

                  # Get results after calculation, store it in separate file and print the actual results          
                   results = api_client.calculation.get_results(activeProjectId, conParameter.connection_ids)
                 CheckResSummary = results[0].check_res_summary
                  costs = api_client.connection.get_production_cost(api_client.project.active_project_id, firstConId)

                   api_client.project.download_project(activeProjectId, r'C:\Users\AlexanderSzotkowski\Documents\IDEA\API\Tutorial 04\tutorial 03 with template-updated.ideaCon')

                   if CheckResSummary[0].check_status == False:
                      break

                   if CheckResSummary[0].check_status == True:
                    print (row,'rows of', bolt, 'bolts', 'and weld size ',par_weld.expression,' results are OK. Costs: ', costs.total_estimated_cost)
                    values= [row, bolt,par_weld.expression,costs.total_estimated_cost]
                    #print(values)
                    matrix.append(values)                   

                   else:
                     print ('Iteration %i failed' % weld)

               else:
                     print ('Iteration %i for weld failed' % weld)                    

           else:
                  print ('Iteration %i for bolts failed' % bolt)                 

       else:
           print ('Iteration %i for rows failed' % row)

inline image in article
  • A última parte consiste em criar um gráfico com os nossos resultados. 

           #Create graph with results
           # Extracting values from the matrix          
           flat = [x for row in matrix for x in row]
           rows = flat[0::4]
           #print('rows', rows)
           diameter = flat[1::4]
           #print('diammeter', diameter)  
           weld = flat[2::4]
           #print('weld', weld)
           costs = flat[3::4]  
           #print('costs', costs)
           s = 50

        

           fig, ax = plt.subplots( )
           # Use a loop to plot each point with a different marker based on diameter and number of rows
           for weldi, costsi, rowsi, diameteri in zip(weld, costs, rows, diameter):

            if diameteri == 16 and rowsi == 3:
                    marker_style = 'o'
                    col = 'blue'

            elif diameteri == 16 and rowsi == 2:
                    marker_style = 'o'
                    col = 'red' 

            elif diameteri == 14 and rowsi == 3:
                    marker_style = '+'
                    col = 'blue'

            elif diameteri == 14 and rowsi == 2:
                    marker_style = '+'
                    col = 'red' 

            else:
                    marker_style = 'D'
                   col = 'black'                  

            ax.scatter(weldi, costsi, s, marker=marker_style, c=col)           

           ax.set_ylim([min(costs)-10, max(costs)+10])

           #ax.legend()
           plt.text(0, 90, 'red "x" 2 rows of M12', fontsize=10, color='red', ha='left', va='center')
           plt.text(0, 92, 'blue "x" 3 rows of M12', fontsize=10, color='blue', ha='left', va='center')
           plt.text(0, 94, 'red "+" 2 rows of M14', fontsize=10, color='red', ha='left', va='center')
           plt.text(0, 96, 'blue "+" 3 rows of M14', fontsize=10, color='blue', ha='left', va='center')
           plt.text(0, 98, 'red "dot" 2 rows of M16', fontsize=10, color='red', ha='left', va='center')
           plt.text(0, 100, 'blue "dot" 3 rows of M16', fontsize=10, color='blue', ha='left', va='center')

           ax.set_title("Costs")
           ax.set_ylabel('Costs in €')
           ax.set_xlabel('Welds in m')
           ax.axhline(0, color='grey', linewidth=0.8)
           ax.grid(True)
           plt.show()

inline image in article

Como se pode verificar, neste caso particular, a junta mais económica é aquela com uma soldadura de 6 mm e três fiadas de parafusos M14.

inline image in article

Transferências Anexadas

Artigos relacionados