Do ficheiro de texto ao diagrama de esforços

No artigo anterior mostrámos como os ficheiros de texto dos programas CSI (o .s2k do SAP2000) permitem automatizar a criação do modelo: grupos, section cuts, tudo gerado por rotinas escritas com auxílio de AI. Hoje fechamos o ciclo do lado oposto: a consulta de resultados.

A observação de partida é simples e, para muitos utilizadores, surpreendente: quando se exporta um modelo calculado para .s2k com as tabelas de resultados incluídas, esse ficheiro de texto passa a conter tudo: a geometria, os section cuts, os esforços das combinações, estação a estação. Não é preciso API, não é preciso Excel intermédio, não é preciso sequer abrir o SAP2000. É um ficheiro que qualquer programa (ou qualquer AI) consegue ler.

 
E aqui está uma mais-valia dos programas CSI que vale a pena sublinhar. O .s2k, como o .e2k do ETABS ou o .f2k do SAFE, não é uma exportação parcial nem um relatório para leitura: é o modelo completo, com geometria, atribuições, casos, combinações e todas as tabelas de resultados, em texto legível e documentado, que o próprio programa volta a importar. São poucos os programas de cálculo que oferecem esta via de duplo sentido: o habitual é o modelo ficar fechado em formato binário e os resultados saírem apenas em exportações parciais, relatórios ou através de uma API. Nos programas CSI, o modelo e os seus resultados estão sempre ao alcance de quem os quiser automatizar, sem licenças adicionais, sem intermediários, com um simples ficheiro de texto.

 

O âmbito da ferramenta

O que pedimos à AI foi uma rotina de consulta com uma regra de interação clara: primeiro escolhe-se o elemento estrutural, só depois se gera a vista dos esforços. O resultado é um único ficheiro HTML que se abre no browser, com a planta do edifício desenhada automaticamente a partir da geometria do próprio .s2k: contorno da laje, vigas, pilares e paredes, cada um identificado pelo tipo de elemento finito que o modela.

Melhor do que descrever é deixar testar: a ferramenta real está aqui em baixo, embebida no artigo.

 

A planta é reconstruída a partir das tabelas de geometria do .s2k — paredes = áreas verticais, pilares = frames verticais, vigas e contorno da laje a cinzento. Clique no círculo laranja (núcleo) ou num dos quadrados (pilares) e escolha o caso de carga. (Os gráficos carregam da CDN do Plotly; é necessária ligação à internet.)

 

A partir daí, cada clique gera a vista correspondente, com dois comportamentos distintos e deliberados:

Núcleo e paredes: os esforços vêm dos section cuts definidos no modelo (a convenção de nomes do artigo anterior: PAR_P3_inf, etc.). São os seis esforços integrados F1, F2, F3, M1, M2, M3 em altura, com envelope Max/Min das combinações.

Pilares: aqui não usamos section cuts. Cada pilar é clicável individualmente e o diagrama (P, V2, V3, T, M2, M3) vem diretamente dos esforços dos frames, estação a estação. Curiosamente, a rotina detetou que o section cut de "pilares" do modelo original cortava todos os pilares de uma vez, o que é útil como corte global de piso mas redundante quando cada pilar tem diagrama próprio, e por isso é ocultado automaticamente (com opção de o manter).

 

Como é simples, na prática

Aqui está o ponto que queremos espicaçar: não escrevemos uma linha de código. O "código-fonte" desta ferramenta foram pedidos como este:

 
"Cria uma rotina onde se pode escolher o elemento estrutural e só depois se gera a vista dos esforços."

"Preciso que a planta seja apresentada para se saber e selecionar o elemento."

"Para os pilares não uses o section cut: apresenta um diagrama isolado para cada pilar."

 

Três iterações em linguagem natural, cada uma refinando a anterior. A AI encarregou-se de ler as tabelas, reconstruir a planta, tratar convenções de sinais e gerar a interface. O ficheiro de teste tinha 374 MB; a rotina processa-o em cerca de 1,5 segundos, sem instalar nada além do Python.

 

A anatomia do ficheiro .s2k

Para perceber como o algoritmo vai buscar os resultados, vale a pena olhar para dentro do ficheiro. Um .s2k exportado com o modelo calculado é simplesmente uma sequência de tabelas, as mesmas que se veem no SAP2000 em Display > Show Tables, escritas em texto, com registos chave=valor. Primeiro a definição do modelo, no fim os resultados:

 
TABLE: "PROGRAM CONTROL" ProgramName=SAP2000 Version=27.1.0 CurrUnits="KN, m, C" ... ← unidades
TABLE: "JOINT COORDINATES" ← geometria: nós…
   Joint=1 GlobalX=-15 GlobalY=-6 GlobalZ=0 ...
TABLE: "CONNECTIVITY - FRAME" ← …pilares e vigas…
TABLE: "CONNECTIVITY - AREA" ← …paredes e lajes (a planta!)
TABLE: "SECTION CUTS 1 - GENERAL" ← definição dos cortes
   CutName=PAR_P1_inf DefinedBy=Group Group=SC_PAR_P1_inf ...
        
TABLE: "ELEMENT FORCES - FRAMES" ← resultados dos pilares
   Frame=1 Station=0 OutputCase=DEAD P=-905.89 V2=-5.15 ...
TABLE: "SECTION CUT FORCES - ANALYSIS" ← resultados dos section cuts
   SectionCut=PAR_P1_inf OutputCase=COMB1 StepType=Max
        F1=3390.04 F2=2777.05 F3=12594.85 M1=25015.55 M2=39173.12 M3=9316.00 GlobalZ=0

 

Está tudo à vista: as tabelas de geometria dão a planta, a convenção de nomes (PAR_P1_inf = parede, piso 1, corte inferior) dá a organização em altura, e as duas tabelas de resultados dão os números. É por isso que a validação é tão direta: o que a ferramenta desenha é literalmente o que está nestas linhas.

 

Um lamiré do algoritmo

Com a estrutura à frente, o coração da extração, tal como a AI o escreveu, cabe em meia dúzia de linhas: ler o ficheiro em streaming (por isso os 374 MB não assustam) e apanhar a tabela certa:

 
# ler apenas a tabela de resultados, linha a linha (streaming)
dentro = False
for linha in open("Modelo.s2k", errors="ignore"):
    if linha.startswith("TABLE:"):
        dentro = 'SECTION CUT FORCES - ANALYSIS' in linha
        continue
    if dentro and "SectionCut=" in linha:
        # cada linha é uma lista de pares chave=valor; a expressão
        # (w+)=(S+) apanha cada par; w+ = nome do campo (letras/
        # dígitos), S+ = valor (tudo até ao espaço); e o dict()
        # transforma-os num dicionário:
        r = dict(re.findall(r'(w+)=(S+)', linha))
        # r["SectionCut"] -> "PAR_P1_inf"
        # r["OutputCase"] -> "COMB1"
        # r["M2"] -> "39173.12"
        # r["M3"] -> "9316.00" (e por aí fora)

 

O resto segue exatamente a mesma lógica, e foi todo escrito pela AI a partir dos pedidos acima: juntar as linhas de continuação (terminadas em _), reconstruir a planta a partir das tabelas de geometria, ler os esforços dos frames para os pilares e gerar o HTML interativo. Não há magia: há um formato de texto bem documentado e uma máquina paciente a lê-lo.

A utilidade é imediata: consulta rápida de esforços sem abrir o modelo, vistas partilháveis com colegas ou revisores (é um HTML, abre em qualquer máquina), e uma base que se adapta a qualquer modelo que siga a mesma convenção de nomes nos section cuts.

 

Os riscos e porque aqui são rastreáveis

Seria irresponsável apresentar isto sem a outra metade da história. Uma rotina escrita por AI pode errar, e em resultados estruturais um erro silencioso é perigoso. No desenvolvimento desta ferramenta encontrámos exemplos concretos: os cortes "sup" devolvem esforços com sinal invertido (são o equilíbrio do lado oposto do corte), e nos envelopes essa inversão troca o Max com o Min, uma subtileza que uma implementação ingénua falharia sem ninguém dar por isso.

 
A salvaguarda essencial: neste tipo de ferramenta, tudo o que a rotina apresenta existe, número a número, nas tabelas do próprio SAP2000. A validação é trivial: abrem-se as tabelas (Display > Show Tables), comparam-se meia dúzia de valores em pontos estratégicos (base do núcleo, base de um pilar, um envelope Max/Min) e confirma-se o diagrama. Foi exatamente assim que validámos cada versão: amostragem direta contra a fonte.

 

É esta a fronteira que recomendamos: usar AI para automatizar leitura, organização e visualização de resultados, onde cada número é rastreável até à origem e a verificação custa minutos, e manter o engenheiro como responsável pela validação e pela interpretação. A ferramenta não decide nada; mostra, mais depressa e melhor, aquilo que o modelo já calculou. A responsabilidade do dimensionamento não se delega.