Розробка AI-системи генеративного проектування виробів Generative Design

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Розробка AI-системи генеративного проектування виробів Generative Design
Складний
від 2 тижнів до 3 місяців
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

AI-генеративний дизайн продуктів

Генеративний дизайн застосовує AI для створення оптимальних форм виробів із заданими фізичними обмеженнями: максимальна міцність при мінімальній вазі, аеродинаміка, тепловідвід. Використовується в авіації, автопромі, медичних імплантатах, архітектурі.

Топологічна оптимізація з SIMP

import numpy as np
from scipy.sparse import lil_matrix
from scipy.sparse.linalg import spsolve

class TopologyOptimizer:
    """
    SIMP (Solid Isotropic Material with Penalization) метод.
    Класичний алгоритм генеративного дизайну.
    """

    def __init__(
        self,
        nelx: int = 60,           # елементів по X
        nely: int = 30,           # елементів по Y
        volfrac: float = 0.5,     # цільова доля матеріалу (50%)
        penal: float = 3.0,       # ступінь штрафу
        rmin: float = 1.5         # радіус фільтра
    ):
        self.nelx = nelx
        self.nely = nely
        self.volfrac = volfrac
        self.penal = penal
        self.rmin = rmin

    def optimize(
        self,
        load_case: dict,           # {node: (fx, fy), ...}
        boundary_conditions: dict, # {node: (ux, uy), ...} — 0=фіксовано
        max_iterations: int = 100
    ) -> np.ndarray:
        """Повертає матрицю щільностей (0=пусто, 1=матеріал)"""
        # Ініціалізація
        x = np.full((self.nely, self.nelx), self.volfrac)
        xold = x.copy()

        for iteration in range(max_iterations):
            # Аналіз методом скінченних елементів
            U = self._finite_element_analysis(x, load_case, boundary_conditions)

            # Аналіз чутливості
            dc = self._sensitivity_analysis(x, U)

            # Фільтрація чутливостей
            dc = self._filter_sensitivity(x, dc)

            # Оновлення через OC (Optimality Criteria)
            x = self._oc_update(x, dc)

            # Конвергенція
            change = np.max(np.abs(x - xold))
            xold = x.copy()

            print(f"Iter {iteration+1:3d}, Volume: {x.mean():.4f}, Change: {change:.4f}")

            if change < 0.01:
                print(f"Збіжність на ітерації {iteration+1}")
                break

        return x

    def _oc_update(self, x: np.ndarray, dc: np.ndarray) -> np.ndarray:
        """Оновлення за критеріями оптимальності"""
        l1, l2 = 0, 1e9
        move = 0.2

        while (l2 - l1) / (l1 + l2) > 1e-3:
            lmid = 0.5 * (l1 + l2)
            xnew = np.maximum(
                1e-3,
                np.maximum(
                    x - move,
                    np.minimum(
                        1.0,
                        np.minimum(x + move, x * np.sqrt(-dc / lmid))
                    )
                )
            )
            if xnew.mean() - self.volfrac > 0:
                l1 = lmid
            else:
                l2 = lmid

        return xnew

Нейросетевий генеративний дизайн

import torch
import torch.nn as nn

class DesignGeneratorVAE(nn.Module):
    """
    Варіаційний автокодер для генерування нових дизайнів
    за заданими фізичними вимогами.
    """

    def __init__(self, latent_dim: int = 64, design_resolution: int = 64):
        super().__init__()
        self.latent_dim = latent_dim
        res = design_resolution

        # Енкодер: дизайн → латентний вектор
        self.encoder = nn.Sequential(
            nn.Conv2d(1, 32, 4, stride=2, padding=1),   # res/2
            nn.ReLU(),
            nn.Conv2d(32, 64, 4, stride=2, padding=1),  # res/4
            nn.ReLU(),
            nn.Conv2d(64, 128, 4, stride=2, padding=1), # res/8
            nn.ReLU(),
            nn.Flatten()
        )

        encoder_out_size = 128 * (res // 8) ** 2
        self.fc_mu = nn.Linear(encoder_out_size, latent_dim)
        self.fc_logvar = nn.Linear(encoder_out_size, latent_dim)

        # Умовний вектор: фізичні обмеження
        self.condition_proj = nn.Linear(16, latent_dim)

        # Декодер: латентний вектор + умова → дизайн
        self.decoder_input = nn.Linear(latent_dim * 2, 128 * (res // 8) ** 2)
        self.decoder = nn.Sequential(
            nn.ConvTranspose2d(128, 64, 4, stride=2, padding=1),
            nn.ReLU(),
            nn.ConvTranspose2d(64, 32, 4, stride=2, padding=1),
            nn.ReLU(),
            nn.ConvTranspose2d(32, 1, 4, stride=2, padding=1),
            nn.Sigmoid()
        )
        self.res = res

    def generate(self, conditions: torch.Tensor, n_samples: int = 1) -> torch.Tensor:
        """
        conditions: тензор фізичних обмежень (навантаження, граничні умови)
        Повертає матрицю щільностей 64×64 для кожного зразка
        """
        with torch.no_grad():
            z = torch.randn(n_samples, self.latent_dim)
            c = self.condition_proj(conditions.expand(n_samples, -1))
            zc = torch.cat([z, c], dim=1)

            h = self.decoder_input(zc)
            h = h.view(n_samples, 128, self.res // 8, self.res // 8)
            return self.decoder(h)

Інтеграція з CAD (через Python-OCC)

from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeSolid
from OCC.Core.TopoDS import TopoDS_Shape
import trimesh
import numpy as np

def density_to_mesh(density_matrix: np.ndarray, threshold: float = 0.5) -> trimesh.Trimesh:
    """Конвертуємо матрицю щільностей в 3D mesh через marching cubes"""
    from skimage.measure import marching_cubes

    # 2D → 3D екструзія для демонстрації
    density_3d = np.stack([density_matrix] * 10, axis=-1)

    verts, faces, normals, _ = marching_cubes(
        density_3d,
        level=threshold,
        spacing=(1.0, 1.0, 1.0)
    )

    mesh = trimesh.Trimesh(vertices=verts, faces=faces, vertex_normals=normals)
    mesh = trimesh.smoothing.filter_laplacian(mesh, iterations=10)
    return mesh

def export_to_stl(mesh: trimesh.Trimesh, output_path: str) -> None:
    mesh.export(output_path)

Застосування

Область Задача Обмеження Мета
Авіація Кронштейн Навантаження на зсув -40% ваги
Медицина Костний імплант Біомеханічні навантаження Пористість для остеоінтеграції
Авто Амортизаційна скоба Ударні навантаження -30% матеріалу
Архітектура Несучі колони Вітрові + снігові навантаження Мінімальний матеріал

Терміни: SIMP топологічна оптимізація для 2D задач — 1–2 тижні. VAE-генератор з навчанням на датасеті оптимізованих форм — 4–6 тижнів.