CalculiX MCP

Solver FEM de código aberto (ccx) como um servidor FastMCP, integrado ao ecossistema de agente + visualizador de navegador do CAE-Agent-Hub

Documentação

CalculiX MCP

Um servidor MCP que expõe o solver FEM de código aberto CalculiX (ccx) para clientes MCP. O CalculiX é GPLv2, não requer licença e executa como um CLI do tipo "dispare e esqueça" — portanto, este servidor é totalmente autônomo, sem ponte de sessão ao vivo e sem máquina de estados de licença.

O fluxo de trabalho é: analisar um deck .inp do CalculiX/Abaqus, inspecionar suas variáveis de projeto ajustáveis, editar um valor no local, submetê-lo ao ccx, ler os resultados de texto (.dat) e exportar esses resultados .dat para result_mesh.json para que o Text to CAE Viewer do repositório possa renderizar a malha e o campo de tensões.

Este é o primeiro MCP FEM com solver de código aberto no hub (a linha FEA existente parou nas referências ao FEniCS), preenchendo a lacuna observada na Issue #14.

Ferramentas

FerramentaFinalidade
fea_healthRelatar a disponibilidade do meshio e o executável ccx detectado.
parse_inpAnalisar um deck .inp: nós, contagens de elementos, seções de casca/viga, materiais, cargas.
list_design_vars_toolListar variáveis de projeto ajustáveis (espessura da casca, seção da viga, material E/nu/densidade, magnitude da carga), cada uma com um localizador var_id.
modify_card_toolEditar uma variável de projeto no local por var_id; substituição de texto puro, grava um novo .inp.
run_solver_toolExecutar ccx -i <jobname> em um deck. O sucesso ignora o código de saída (veja abaixo).
read_results_toolAnalisar o .dat para von Mises máximo (autocalculado), deslocamento máximo, volume, massa; para etapas *FREQUENCY também a tabela de autovalores (frequencies, n_modes).
export_results_toolExportar a execução para result_mesh.json (formato do visualizador); para execuções modais, passe mode=N para exportar a forma desse modo.
optimize_structure_toolOtimização de dimensionamento em dois estágios (varredura LHS + descida de coordenadas): minimizar massa sujeita a limites de tensão/deslocamento (decks estáticos) ou um piso de frequência natural (decks modais, "evitar ressonância") ajustando variáveis de projeto escalares (espessura da casca, seção da viga, material, carga). Apenas modelos de casca/viga — veja Otimização.

Contratos CalculiX conquistados com dificuldade (codificados no solver)

Estes são os motivos pelos quais este servidor não é trivial — todos a partir do comportamento público do CalculiX:

  • O código de saída do ccx não é confiávelccx retorna 0 mesmo quando imprime *ERROR. Sucesso = sem *ERROR no stdout e o arquivo .sta tem uma linha de dados e sem timeout.
  • .dat não tem von Mises — apenas 6 componentes de tensão; σ_vm é autocalculado.
  • .dat não tem volume/massa total — calculado a partir da geometria da malha × *DENSITY.
  • Nunca meshio.write — ele descarta todos os cartões e reescreve B31B31H (corrompe o arquivo). modify_card faz edições de texto puro no local.
  • Etapas *FREQUENCY gravam um .sta apenas com cabeçalho — uma solução de autovalores não tem incrementos, então o sucesso também aceita um .dat não vazio (caso contrário, toda execução modal pareceria falha). Frequências e autovetores por modo estão no texto .dat, não apenas no .frd.

Otimização

optimize_structure_tool executa otimização de dimensionamento em dois estágios: uma varredura grosseira de Hipercubo Latino, depois refinamento por descida de coordenadas (salto para o limite mais bissecção repetida em direção à fronteira viável), minimizando massa sujeita a restrições de tensão e deslocamento editando cartões escalares no local.

optimize_structure_tool(
    path="examples/bracket.inp",
    variables={"shell.PLATE.thickness": [2.0, 8.0]},
    n_lhs=8, max_solves=18,
)
# -> best ~4.1 mm, ~-48% mass, stress < 250 MPa, displacement < 1.5 mm

Restrições de frequência ("evitar ressonância") executam o mesmo loop contra um deck *FREQUENCY: cada avaliação é uma solução de autovalores, o modo N é lido da tabela de autovalores .dat, e o afinamento para onde o modo se situa logo acima do seu piso. Métricas estáticas e métricas de frequência vêm de decks estáticos e modais, respectivamente — um conjunto de restrições incompatível torna cada ponto inviável, o que a execução relata como um aviso de métricas ausentes.

optimize_structure_tool(
    path="examples/plate_modal.inp",
    variables={"shell.PLATE.thickness": [2.0, 8.0]},
    constraints=[{"metric": "freq_1_hz", "op": ">", "value": 30.0}],
    n_lhs=5, max_solves=24,
)
# -> best ~3.23 mm, ~-19% mass, f1 = 30.4 Hz

Escopo e honestidade:

  • Apenas modelos de casca/viga. Sólidos (C3D8) não expõem cartão de geometria escalar, então não há espessura para afinar; use otimização de forma/topologia.
  • Isto é otimização de dimensionamento/parâmetros, não otimização de topologia — ele afina seções, não redistribui material no espaço.
  • O melhor deck é gravado ao lado da entrada como <stem>.optimized.inp; passe-o para export_results_tool para renderizar o projeto otimizado.

Análise modal

Decks *FREQUENCY funcionam com as mesmas ferramentas. O .dat carrega tudo: uma tabela E I G E N V A L U E O U T P U T (modo, autovalor, rad/s, ciclos/s) seguida por blocos de autovetores por modo marcados E I G E N V A L U E N U M B E R N — os vetores reutilizam o formato de linha displacements (vx,vy,vz) estático, então as formas de modo são exportadas sem tocar no .frd.

read_results_tool(result_path=...)     # -> frequencies: [{mode, eigenvalue,
                                       #     freq_rad_s, freq_hz}], n_modes
export_results_tool(path="examples/cantilever_modal.inp", mode=1)
# -> result_mesh.json holding mode 1's eigenvector (stress-free shape)

Duas notas de física que valem a pena relatar honestamente: uma seção duplamente simétrica dá pares degenerados (f1 = f2), e hexágonos C3D8 totalmente integrados travam por cisalhamento em flexão, então as frequências ficam ~5-10% acima do cálculo manual de Euler-Bernoulli (examples/cantilever_modal.inp: ccx f1 ~ 502 Hz vs cálculo manual ~ 464 Hz).

Instalação

A partir deste diretório (Linux/macOS; adapte a ativação do venv no Windows):

uv venv .venv --python 3.11
uv pip install --python .venv/bin/python "mcp>=1.0,<1.8" meshio numpy "python-dotenv>=1,<2"
uv pip install --python .venv/bin/python pytest   # dev only

mcp está fixado abaixo de 1.8: mcp 2.0 removeu mcp.server.fastmcp (a importação do FastMCP usada aqui e pelos outros MCPs do hub).

Instale o CalculiX separadamente (por exemplo, ccx ou ccx_preCICE no seu PATH, ou defina CCX_EXE). fea_health informará se o executável foi detectado.

Execução

.venv/bin/python mcp_server.py          # stdio MCP transport

Registre-o com um cliente MCP usando examples/mcp_config.example.json.

Exemplo: benchmark de viga em balanço

examples/cantilever.inp é uma viga em balanço pública de livro-texto (barra sólida C3D8 de aço, fixada em uma extremidade, carregada transversalmente na outra). Regere-o com:

python3 examples/gen_cantilever.py

Metas de sanidade por cálculo manual (Euler-Bernoulli, mm-t-s-MPa, P = 100 N): deflexão da ponta ≈ 0,8 mm, tensão na raiz ≈ 140 MPa. O visualizador amplia automaticamente a pequena deformação elástica para exibição.

examples/cantilever_modal.inp é a mesma barra com uma etapa *FREQUENCY de 5 modos: f1 = f2 ≈ 502 Hz (par degenerado), f3 = f4 ≈ 3089 Hz, f5 ≈ 6309 Hz, vs o cálculo manual f1 ≈ 464 Hz (travamento por cisalhamento C3D8). O caso do visualizador models/text-to-cae-calculix-modal renderiza o modo 1.

examples/plate_modal.inp (regere com python3 examples/gen_plate_modal.py) é uma placa em balanço de casca S4 construída para dimensionamento com restrição de frequência: ccx f1 = 37,6 Hz em t = 4 mm vs o cálculo manual de Euler-Bernoulli f1 = (1,8751²/2π)(t/L²)√(E/12ρ) ≈ 37,1 Hz, e a execução de evitar ressonância acima termina em t = 3,23 mm contra o ótimo analítico t* = 30/9,29 ≈ 3,23 mm.

Testes

.venv/bin/python -m pytest

Testes de analisador e exportador rodam sem solver. Testes de solver são pulados automaticamente quando ccx não é detectado, então a suíte permanece verde antes da instalação do CalculiX.

Conteúdo

  • mcp_server.py — servidor stdio FastMCP.
  • tools/inp_parser.py — análise de cartões .inp + edição de texto no local.
  • tools/solver.py — subprocesso ccx + análise de resultados .dat.
  • tools/result_exporter.py.dat/.inpresult_mesh.json (formato do visualizador).
  • tools/optimizer.py — otimização de dimensionamento em dois estágios (LHS + descida de coordenadas).
  • examples/ — benchmark público de viga em balanço + gerador + exemplo de configuração MCP.
  • tests/ — suíte pytest.

Regras do repositório

Confirme apenas código-fonte reutilizável, exemplos (benchmarks públicos), testes e documentação. Não confirme o ambiente virtual, .env ou qualquer saída de solver gerada (.frd, .dat, .sta, .cvg, diretórios de job). Decks de entrada .inp são código-fonte e são confirmados.