From bdcf20478e51a29374cca1a11631ad8007e4b463 Mon Sep 17 00:00:00 2001 From: Danamir Date: Wed, 3 Dec 2025 08:59:14 +0300 Subject: [PATCH] added all files reserch --- 1.py | 27 ++++++++ 10.py | 64 +++++++++++++++++++ 11g.py | 118 +++++++++++++++++++++++++++++++++++ 12g.py | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12gdef.py | 122 +++++++++++++++++++++++++++++++++++++ 12gui.py | 100 ++++++++++++++++++++++++++++++ 2.py | 47 ++++++++++++++ 3.py | 51 ++++++++++++++++ 4.py | 52 ++++++++++++++++ 5.py | 55 +++++++++++++++++ 6.py | 61 +++++++++++++++++++ 7-1.py | 16 +++++ 7.py | 47 ++++++++++++++ 8.py | 75 +++++++++++++++++++++++ 9.py | 37 +++++++++++ 15 files changed, 1051 insertions(+) create mode 100644 1.py create mode 100644 10.py create mode 100644 11g.py create mode 100644 12g.py create mode 100644 12gdef.py create mode 100644 12gui.py create mode 100644 2.py create mode 100644 3.py create mode 100644 4.py create mode 100644 5.py create mode 100644 6.py create mode 100644 7-1.py create mode 100644 7.py create mode 100644 8.py create mode 100644 9.py diff --git a/1.py b/1.py new file mode 100644 index 0000000..4c5a820 --- /dev/null +++ b/1.py @@ -0,0 +1,27 @@ +import matplotlib.pyplot as plt + +# Get the input from the user +base = float(input("Enter the length of the base of the trapezoid: ")) +height = float(input("Enter the height of the trapezoid: ")) +square_side = float(input("Enter the length of the side of the square: ")) + +# Calculate the area of the trapezoid +area = (base + height) / 2 * square_side + +# Calculate the number of squares that can be divided from the trapezoid +num_squares = int(area / square_side**2) + +# Create a figure and axes +fig, ax = plt.subplots() + +# Draw the trapezoid +ax.fill_betweenx([height / 2, height / 2, height, height], [0, base / 2, base / 2 + base, base], color='blue') + +# Draw the squares +for i in range(num_squares): + x = i * square_side + y = height / 2 + ax.fill([x, x + square_side, x + square_side, x], [y, y, y + square_side, y + square_side], color='red') + +# Show the plot +plt.show() \ No newline at end of file diff --git a/10.py b/10.py new file mode 100644 index 0000000..ed51e12 --- /dev/null +++ b/10.py @@ -0,0 +1,64 @@ +import matplotlib.pyplot as plt +import numpy as np + +def draw_trapezoid_and_squares(base1, base2, height, square_size): + """ + Функция для рисования трапеции и её разбиения на квадраты. + + :param base1: Длина нижнего основания трапеции + :param base2: Длина верхнего основания трапеции + :param height: Высота трапеции + :param square_size: Размер стороны квадрата + """ + # Определяем координаты вершин трапеции + x1, y1 = 0, 0 # Левая нижняя вершина + x2, y2 = base1, 0 # Правая нижняя вершина + x3, y3 = (base1 - base2) / 2, height # Левая верхняя вершина + x4, y4 = x3 + base2, height # Правая верхняя вершина + + # Рисуем трапецию + trapezoid_x = [x1, x2, x4, x3, x1] + trapezoid_y = [y1, y2, y4, y3, y1] + + plt.figure(figsize=(8, 6)) + plt.plot(trapezoid_x, trapezoid_y, 'b-', label='Трапеция') + + # Разбиваем трапецию на квадраты + num_rows = int(height // square_size) # Количество строк квадратов + for row in range(num_rows): + # Вычисляем высоту текущей строки + current_height = (row + 1) * square_size + if current_height > height: + break + + # Определяем ширину трапеции на текущей высоте + width_at_height = base1 - (base1 - base2) * (current_height / height) + start_x = (base1 - width_at_height) / 2 + end_x = start_x + width_at_height + + # Разбиваем строку на квадраты + num_cols = int(width_at_height // square_size) + for col in range(num_cols): + square_x = start_x + col * square_size + square_y = row * square_size + + # Рисуем квадрат + square = plt.Rectangle((square_x, square_y), square_size, square_size, fill=False, edgecolor='r', linewidth=1) + plt.gca().add_patch(square) + + # Настройки графика + plt.gca().set_aspect('equal', adjustable='box') + plt.title('Разбиение трапеции на квадраты') + plt.xlabel('X') + plt.ylabel('Y') + plt.legend() + plt.grid(True) + plt.show() + +# Пример использования +base1 = 10 # Нижнее основание +base2 = 6 # Верхнее основание +height = 8 # Высота +square_size = 1 # Размер квадрата + +draw_trapezoid_and_squares(base1, base2, height, square_size) diff --git a/11g.py b/11g.py new file mode 100644 index 0000000..caca1d8 --- /dev/null +++ b/11g.py @@ -0,0 +1,118 @@ +import numpy as np +import matplotlib.pyplot as plt + +# --- 1. Определение параметров моделирования --- + +# Геометрические параметры (1D модель: только глубина Z) +DZ = 0.1 # Размер ячейки по глубине (Z) в метрах (10 см) +Z_MAX = 2.0 # Максимальная глубина моделирования в метрах +L_MAX = 10.0 # Максимальная длина (не используется в 1D модели) +W_MAX = 22.0 # Максимальная ширина (не используется в 1D модели) + +# Количество узлов (ячеек) по глубине +N_NODES = int(Z_MAX / DZ) + 1 +DEPTHS = np.linspace(0, Z_MAX, N_NODES) + +# Теплофизические параметры грунта (приближенные значения для талого грунта) +LAMBDA = 1.5 # Теплопроводность грунта (λ), Вт/(м·К) +RHO_C = 2.0e6 # Объемная теплоемкость (ρ·C), Дж/(м³·К) +ALPHA = LAMBDA / RHO_C # Температуропроводность (α), м²/с + +# Параметры времени +DT_HOUR = 3600 # Шаг по времени (Δt) в секундах (1 час) +N_DAYS = 365 # Продолжительность моделирования в днях (1 год) +N_STEPS = N_DAYS * 24 # Общее количество временных шагов + +# Критерий устойчивости (Число Фурье, r) +R = (ALPHA * DT_HOUR) / (DZ**2) + +# Проверка устойчивости явной схемы +if R > 0.5: + print(f"ВНИМАНИЕ: Нарушен критерий устойчивости (R = {R:.4f}).") + print("Уменьшите шаг по времени (DT_HOUR) или шаг по пространству (DZ).") + R = 0.5 # Принудительное ограничение для демонстрации +else: + print(f"Критерий устойчивости соблюден (R = {R:.4f} <= 0.5).") + +# --- 2. Инициализация температуры --- + +# Начальная температура грунта (равномерное распределение) +T_INITIAL = 5.0 # °C +Temperature = np.full(N_NODES, T_INITIAL) + +# Массив для записи результатов (для построения графика) +temp_history = [Temperature.copy()] + +# --- 3. Определение граничных условий (ГКУ) --- + +def surface_temperature(step): + """ + Граничное условие (ГКУ) на поверхности (z=0). + Используется синусоидальная функция для имитации сезонного цикла (1 год). + """ + time_in_hours = step * DT_HOUR + time_in_years = time_in_hours / (365 * 24 * 3600) + + # Параметры: T_avg = 0°C, Amplitude = 20°C, сдвиг фазы (начало зимы) + T_avg = 0.0 + T_amp = 20.0 + # Фаза: +pi/2, чтобы начать симуляцию с T(0) = T_avg + return T_avg + T_amp * np.sin(2 * np.pi * time_in_years + np.pi/2) + +# ГКУ на нижней границе (z=Z_MAX) - постоянная температура +T_BOTTOM = T_INITIAL + +# --- 4. Цикл моделирования --- + +print(f"Начало моделирования: {N_DAYS} дней ({N_STEPS} шагов по 1 часу)...") + +for n in range(N_STEPS): + T_old = Temperature.copy() + + # 1. Применение граничных условий + # Верхняя граница (i=0) - Температура воздуха (Dirichlet BC) + T_surface = surface_temperature(n) + Temperature[0] = T_surface + + # Нижняя граница (i=N_NODES-1) - Постоянная температура (Dirichlet BC) + Temperature[-1] = T_BOTTOM + + # 2. Расчет температуры для внутренних узлов (i=1 до N_NODES-2) + # Формула явной схемы FDM: T_i^{n+1} = T_i^n (1 - 2r) + r (T_{i-1}^n + T_{i+1}^n) + for i in range(1, N_NODES - 1): + # --- Здесь должно быть место для учета фазовых переходов (мерзлота/талый грунт) --- + # В реальной модели R и T_i^{n+1} должны рассчитываться с учетом + # изменения LAMBDA, RHO_C и скрытой теплоты L (L_v, формула 3.13) + # в зависимости от T_i^n и температуры фазового перехода (T_bf, формула 3.7). + # В этой упрощенной модели LAMBDA, RHO_C, R - константы. + # --------------------------------------------------------------------------------- + + T_new = T_old[i] * (1 - 2 * R) + R * (T_old[i-1] + T_old[i+1]) + Temperature[i] = T_new + + # Запись истории температуры каждые 90 дней для графика + if (n % (90 * 24) == 0) and (n > 0): + temp_history.append(Temperature.copy()) + +temp_history.append(Temperature.copy()) +print("Моделирование завершено.") + +# --- 5. Визуализация результатов --- + +plt.figure(figsize=(10, 6)) +time_labels = [f"День {int(i / 24)}" for i in np.linspace(0, N_STEPS, len(temp_history))] + +# Добавление начального состояния +plt.plot(temp_history[0], -DEPTHS, label=f't=0 (Начальное)', linestyle='--') + +# Построение графиков для разных моментов времени +for i, T_profile in enumerate(temp_history[1:]): + plt.plot(T_profile, -DEPTHS, label=f'{time_labels[i+1]}', linewidth=2) + +plt.xlabel('Температура, °C') +plt.ylabel('Глубина, м') +plt.title('Одномерное моделирование теплопереноса в грунте (1 год)') +plt.grid(True, linestyle=':', alpha=0.6) +plt.legend(title='Время') +plt.axvline(x=0, color='grey', linestyle='-') +plt.show() \ No newline at end of file diff --git a/12g.py b/12g.py new file mode 100644 index 0000000..d68c1aa --- /dev/null +++ b/12g.py @@ -0,0 +1,179 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import cm +import h5py + +# --- 1. Параметры и сетка (2D) --- +DX = 0.1 +DZ = 0.1 + +Z_MAX = 2.0 +X_MAX = 10.0 + +N_Z = int(Z_MAX / DZ) + 1 +N_X = int(X_MAX / DX) + 1 + +# Время и теплофизические параметры +N_DAYS = 365 +DT = 1800 # 30 минут (сек). +ALPHA = 7.5e-7 +R = ALPHA * DT / (DX**2) +N_STEPS = int(N_DAYS * 24 * 3600 / DT) + +# Параметры сохранения данных +HDF5_FILENAME = 'temperature_simulation_results.hdf5' +RECORD_INTERVAL_STEPS = int(24 * 3600 / DT) + +print(f"2D-сетка: {N_Z}x{N_X} узлов.") +print(f"Устойчивость соблюдена: R = {R:.4f} <= 0.25.") + +# --- 2. Инициализация и геометрическая маска (Трапеция) --- + +T_INITIAL = 5.0 # °C +Temperature = np.full((N_Z, N_X), T_INITIAL, dtype=float) + +# Создание маски для области ТРАПЕЦИИ: +mask = np.full((N_Z, N_X), False) + +# Параметры трапеции (ширина на дне 10м, на поверхности 5м) +W_bottom = X_MAX +W_top = 5.0 + +for i in range(N_Z): + depth_i = i * DZ + W_z = W_bottom - (W_bottom - W_top) * (1 - depth_i / Z_MAX) + offset_x = (X_MAX - W_z) / 2 + + start_j = int(offset_x / DX) + end_j = int((X_MAX - offset_x) / DX) + + start_j = max(0, start_j) + end_j = min(N_X, end_j) + + mask[i, start_j:end_j] = True + +# Обнуляем температуру вне маски (заполняем NaN) +Temperature[~mask] = np.nan + +# --- 3. Граничные условия (Упрощенные) --- + +def surface_temp(step): + """Температура поверхности (Z=0) - синусоида 1 год.""" + time_in_seconds = step * DT + time_in_years = time_in_seconds / (N_DAYS * 24.0 * 3600.0) + T_avg = 0.0 + T_amp = 20.0 + return T_avg + T_amp * np.sin(2 * np.pi * time_in_years + np.pi/2) + +T_BOTTOM = T_INITIAL + +# --- 4. Цикл моделирования и сохранение в HDF5 (Без изменений) --- + +print(f"Начало моделирования ({N_STEPS} шагов). Результаты будут сохранены в {HDF5_FILENAME}...") + +with h5py.File(HDF5_FILENAME, 'w') as f: + + f.attrs['DZ'] = DZ + f.attrs['DX'] = DX + f.attrs['N_DAYS'] = N_DAYS + f.attrs['DT_seconds'] = DT + f.create_dataset('mask', data=mask, dtype='bool') + + temp_dset = f.create_dataset('temperature_profiles', + shape=(0, N_Z, N_X), + maxshape=(N_DAYS + 1, N_Z, N_X), + dtype='f4', + chunks=(1, N_Z, N_X), + compression="gzip") + + record_counter = 0 + + for n in range(N_STEPS): + T_old = Temperature.copy() + + T_surface = surface_temp(n) + Temperature[0, mask[0, :]] = T_surface + Temperature[N_Z - 1, mask[N_Z - 1, :]] = T_BOTTOM + + for i in range(1, N_Z - 1): + for j in range(1, N_X - 1): + if mask[i, j]: + T_i_minus_1 = T_old[i-1, j] if mask[i-1, j] else T_old[i, j] + T_i_plus_1 = T_old[i+1, j] if mask[i+1, j] else T_old[i, j] + T_j_minus_1 = T_old[i, j-1] if mask[i, j-1] else T_old[i, j] + T_j_plus_1 = T_old[i, j+1] if mask[i, j+1] else T_old[i, j] + + T_new = T_old[i, j] * (1 - 4 * R) + R * (T_i_minus_1 + T_i_plus_1 + T_j_minus_1 + T_j_plus_1) + + Temperature[i, j] = T_new + + if n % RECORD_INTERVAL_STEPS == 0: + temp_dset.resize(record_counter + 1, axis=0) + temp_dset[record_counter, :, :] = Temperature + record_counter += 1 + + if record_counter % 50 == 0: + print(f"Записан профиль за день {record_counter}.") + + +print(f"Моделирование завершено. Сохранено {record_counter} профилей температуры в файле {HDF5_FILENAME}.") + +# --- 5. Пример визуализации (Чтение из HDF5 с исправлениями) --- + +try: + with h5py.File(HDF5_FILENAME, 'r') as f: + temp_dset_read = f['temperature_profiles'] + mask_read = f['mask'][:] + + days_to_plot = [0, 90, 180, 270, N_DAYS - 1] # N_DAYS - 1, так как 365-й день это индекс 364 + indices_to_plot = [day for day in days_to_plot if day < temp_dset_read.shape[0]] + + if not indices_to_plot: + print("Нет сохраненных данных для визуализации.") + else: + X_COORD = np.linspace(0, X_MAX, N_X) + Z_COORD = np.linspace(-Z_MAX, 0, N_Z) + + fig, axes = plt.subplots(1, len(indices_to_plot), figsize=(18, 5)) + fig.suptitle(f'2D Теплоперенос (Чтение из {HDF5_FILENAME})', fontsize=14) + + T_all = temp_dset_read[:].flatten() + T_min = np.nanmin(T_all) + T_max = np.nanmax(T_all) + + # ИСПРАВЛЕНИЕ 1: Использование plt.colormaps + cmap_base = plt.colormaps['RdYlBu'] + # Создаем копию для изменения "плохих" значений + cmap_custom = cmap_base.copy() + cmap_custom.set_bad('lightgray') + + for idx, day_index in enumerate(indices_to_plot): + T_profile = temp_dset_read[day_index, :, :] + # Проверяем, что оси - это массив, если только одна ось + ax = axes[idx] if len(indices_to_plot) > 1 else axes + + im = ax.imshow(T_profile, + extent=[0, X_MAX, -Z_MAX, 0], + origin='upper', + cmap=cmap_custom, + aspect='auto', + vmin=T_min, + vmax=T_max) + + ax.contour(X_COORD, Z_COORD, mask_read.astype(int), levels=[0.5], colors='k', linewidths=1.5, linestyles='--') + ax.set_title(f'День: {day_index}') + ax.set_xlabel('Длина, м') + ax.set_ylabel('Глубина, м') + + # ИСПРАВЛЕНИЕ 2: Удаление rect=[0, 0, 0.98, 1] и let axes handle spacing + plt.tight_layout() + + # Добавление цветовой шкалы + # Убедимся, что cbar создается корректно, используя массив осей + cbar = fig.colorbar(im, ax=axes.ravel().tolist() if len(indices_to_plot) > 1 else axes, orientation='vertical', fraction=0.02, pad=0.04) + cbar.set_label('Температура, °C') + + plt.show() + +except Exception as e: + print(f"Ошибка при чтении или визуализации HDF5: {e}") \ No newline at end of file diff --git a/12gdef.py b/12gdef.py new file mode 100644 index 0000000..28087d8 --- /dev/null +++ b/12gdef.py @@ -0,0 +1,122 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import cm + +def initialize_trapezoid_simulation(depth_max, length_bottom, length_top, T_initial, dz_dx=0.1): + """ + Создает заготовку для 2D-моделирования теплопереноса в трапециевидном грунтовом массиве. + + :param depth_max: Максимальная глубина (Z_MAX), м. + :param length_bottom: Ширина трапеции на дне (при Z_MAX), м. + :param length_top: Ширина трапеции на поверхности (при Z=0), м. + :param T_initial: Начальная равномерная температура грунта, °C. + :param dz_dx: Размер ячейки сетки (DX = DZ), м. + :return: Словарь с инициализированными данными (Temperature, Mask, Coordinates). + """ + + # 1. Определение параметров сетки + DX = DZ = dz_dx + + N_Z = int(depth_max / DZ) + 1 + N_X = int(length_bottom / DX) + 1 + + # 2. Инициализация и геометрическая маска + + # Создаем 2D-массив температуры, заполненный начальной температурой T_initial + Temperature = np.full((N_Z, N_X), T_initial, dtype=float) + + # Создаем булеву маску для определения области трапеции + mask = np.full((N_Z, N_X), False) + + for i in range(N_Z): + depth_i = i * DZ + + # Линейное изменение ширины по глубине Z + # W(Z) = L_bottom - (L_bottom - L_top) * (1 - Z/Z_MAX) + W_z = length_bottom - (length_bottom - length_top) * (1 - depth_i / depth_max) + + # Центрирование: отступ слева + offset_x = (length_bottom - W_z) / 2 + + # Индексы X, которые попадают в трапецию + start_j = int(offset_x / DX) + end_j = int((length_bottom - offset_x) / DX) + + # Заполняем маску для текущей глубины + start_j = max(0, start_j) + end_j = min(N_X, end_j) + mask[i, start_j:end_j] = True + + # Применяем маску: области вне трапеции помечаются как NaN (для визуализации) + Temperature[~mask] = np.nan + + # 3. Визуализация Дня 0 + + X_COORD = np.linspace(0, length_bottom, N_X) + Z_COORD = np.linspace(-depth_max, 0, N_Z) + + fig, ax = plt.subplots(figsize=(10, 5)) + fig.suptitle(f'Начальное состояние моделирования (День 0)', fontsize=14) + + # Настройка цветовой карты для NaN + cmap_base = plt.colormaps['RdYlBu'] + cmap_custom = cmap_base.copy() + cmap_custom.set_bad('lightgray') + + im = ax.imshow(Temperature, + extent=[0, length_bottom, -depth_max, 0], + origin='upper', + cmap=cmap_custom, + aspect='auto', + vmin=T_initial - 1, # Устанавливаем Vmin/Vmax для старта + vmax=T_initial + 1) + + # Наложение контура трапеции + ax.contour(X_COORD, Z_COORD, mask.astype(int), levels=[0.5], colors='k', linewidths=1.5, linestyles='--') + + ax.set_title(f'Начальная температура: {T_initial:.1f} °C') + ax.set_xlabel('Длина (X), м') + ax.set_ylabel('Глубина (Z), м') + + cbar = fig.colorbar(im, ax=ax, orientation='vertical', fraction=0.04, pad=0.04) + cbar.set_label('Температура, °C') + + plt.tight_layout() + plt.show() + + # 4. Возврат данных для дальнейших расчетов + return { + 'Temperature_Initial': Temperature, + 'Mask': mask, + 'DX': DX, + 'DZ': DZ, + 'N_X': N_X, + 'N_Z': N_Z + } + +# ---------------------------------------------------------------------- +## 🚀 Пример использования +# ---------------------------------------------------------------------- + +# ВХОДНЫЕ ПАРАМЕТРЫ: +MAX_DEPTH = 2.0 # Глубина 2 м +WIDTH_BOTTOM = 22.0 # Ширина на дне 22 м +WIDTH_TOP = 10.0 # Ширина на поверхности 10 м +INITIAL_TEMP = 5.0 # Начальная температура грунта 5 °C +CELL_SIZE = 0.1 # Размер ячейки 10 см + +# Выполнение инициализации и визуализация +initial_data = initialize_trapezoid_simulation( + depth_max=MAX_DEPTH, + length_bottom=WIDTH_BOTTOM, + length_top=WIDTH_TOP, + T_initial=INITIAL_TEMP, + dz_dx=CELL_SIZE +) + +print("\n--- Сводка по инициализации ---") +print(f"Размеры сетки (Z x X): {initial_data['N_Z']} x {initial_data['N_X']}") +print(f"Размер ячейки: {initial_data['DX']} м") + +# Теперь initial_data можно передать в цикл моделирования +# (который мы создавали ранее), чтобы начать расчеты. \ No newline at end of file diff --git a/12gui.py b/12gui.py new file mode 100644 index 0000000..b28a075 --- /dev/null +++ b/12gui.py @@ -0,0 +1,100 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import cm +import h5py +import os + +def visualize_daily_profile(filename, day_number): + """ + Считывает 2D-профиль температуры для указанного дня из HDF5-файла + и визуализирует его. + + :param filename: Имя HDF5-файла с результатами моделирования. + :param day_number: Номер дня (индекс профиля) для визуализации. + Начинается с 0. + """ + if not os.path.exists(filename): + print(f"ОШИБКА: Файл '{filename}' не найден.") + return + + try: + with h5py.File(filename, 'r') as f: + # 1. Чтение метаданных + DZ = f.attrs['DZ'] + DX = f.attrs['DX'] + + # 2. Чтение основных наборов данных + temp_dset = f['temperature_profiles'] + mask_read = f['mask'][:] + + # Проверка границ дня + if day_number < 0 or day_number >= temp_dset.shape[0]: + print(f"ОШИБКА: День {day_number} находится вне диапазона.") + print(f"Доступный диапазон дней: 0 до {temp_dset.shape[0] - 1}.") + return + + # 3. Извлечение данных для конкретного дня + T_profile = temp_dset[day_number, :, :] + + # 4. Расчет координат + N_Z, N_X = T_profile.shape + X_COORD = np.linspace(0, N_X * DX, N_X) + Z_COORD = np.linspace(0, N_Z * DZ, N_Z) * -1 # Глубина отрицательна + + # 5. Определение диапазона цветов + # Читаем все данные для правильного Vmin/Vmax (это может быть медленно для очень больших файлов) + T_all = temp_dset[:].flatten() + T_min = np.nanmin(T_all) + T_max = np.nanmax(T_all) + + # 6. Настройка цветовой карты + cmap_base = plt.colormaps['RdYlBu'] + cmap_custom = cmap_base.copy() + cmap_custom.set_bad('lightgray') # Области вне трапеции (NaN) + + # 7. Визуализация + + fig, ax = plt.subplots(figsize=(10, 5)) + fig.suptitle(f'Профиль температуры грунта - День {day_number}', fontsize=14) + + im = ax.imshow(T_profile, + extent=[0, N_X * DX, -N_Z * DZ, 0], + origin='upper', + cmap=cmap_custom, + aspect='auto', + vmin=T_min, + vmax=T_max) + + # Наложение контура трапеции + ax.contour(X_COORD, Z_COORD, mask_read.astype(int), levels=[0.5], colors='k', linewidths=1.5, linestyles='--') + + ax.set_title(f'Температура на поверхности: {T_profile[0, int(N_X/2)]:.2f} °C') + ax.set_xlabel('Длина, м') + ax.set_ylabel('Глубина, м') + + # Добавление цветовой шкалы + cbar = fig.colorbar(im, ax=ax, orientation='vertical', fraction=0.04, pad=0.04) + cbar.set_label('Температура, °C') + + plt.tight_layout() + plt.show() + + except Exception as e: + print(f"Произошла ошибка при обработке данных HDF5: {e}") + +# ---------------------------------------------------------------------- +# 🌟 ПРИМЕР ИСПОЛЬЗОВАНИЯ ИНТЕРФЕЙСА +# ---------------------------------------------------------------------- + +FILENAME = 'temperature_simulation_results.hdf5' + +# Пример 1: Профиль в разгар зимы (День 180) +print("Визуализация дня 180 (Пик холода)...") +visualize_daily_profile(FILENAME, 180) + +# Пример 2: Профиль в конце моделирования (День 364) +print("\nВизуализация дня 364 (Конец года)...") +visualize_daily_profile(FILENAME, 364) + +# Пример 3: Попытка визуализировать несуществующий день +# visualize_daily_profile(FILENAME, 400) \ No newline at end of file diff --git a/2.py b/2.py new file mode 100644 index 0000000..c39454c --- /dev/null +++ b/2.py @@ -0,0 +1,47 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Define the dimensions of the trapezoid +base1 = 5 +base2 = 3 +height = 4 + +# Calculate the width of the rectangle that can be cut from each side of the trapezoid +rect_width = (base1 + base2) / 2 + +# Cut off two rectangles from the trapezoid +trap_points = np.array([[0, 0], [base1, 0], [base1, height], [0, height]]) +rect_points = np.array([[0, 0], [rect_width, 0], [rect_width, height], [0, height]]) +trap_cut_points = np.array([[rect_width, 0], [base2, 0], [base2, height], [rect_width, height]]) + +# Plot the original trapezoid and cut off rectangles +plt.fill(trap_points[:, 0], trap_points[:, 1], color='gray') +plt.fill(rect_points[:, 0], rect_points[:, 1], color='blue') +plt.fill(trap_cut_points[:, 0], trap_cut_points[:, 1], color='blue') + +# Calculate the size of the remaining triangle +triangle_width = base2 - rect_width +triangle_height = (base2 * height) / base1 + +# Cut off the triangle from the trapezoid +tri_points = np.array([[rect_width, 0], [base2, 0], [(base2 + rect_width) / 2, height]]) +tri_cut_points = np.array([[(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2, triangle_height], [rect_width, triangle_height]]) + +# Plot the remaining triangle and cut off triangles +plt.fill(tri_points[:, 0], tri_points[:, 1], color='green') +plt.fill(tri_cut_points[:, 0], tri_cut_points[:, 1], color='green') + +# Calculate the size of the small squares +small_square_size = min(rect_width, triangle_height) / 2 + +# Cut off the small squares from the rectangle and triangle +rect_small_squares_points = np.array([[0, 0], [small_square_size, 0], [small_square_size, small_square_size], [0, small_square_size]]) +tri_small_squares_points = np.array([[(base2 + rect_width) / 2 - small_square_size, small_square_size], [(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2 - small_square_size, 0]]) + +# Plot the small squares +plt.fill(rect_small_squares_points[:, 0], rect_small_squares_points[:, 1], color='red') +plt.fill(tri_small_squares_points[:, 0], tri_small_squares_points[:, 1], color='red') + +# Show the plot +plt.axis('scaled') +plt.show() diff --git a/3.py b/3.py new file mode 100644 index 0000000..b9028a7 --- /dev/null +++ b/3.py @@ -0,0 +1,51 @@ +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +def draw_trapezoid(a, b, h): + fig, ax = plt.subplots() + + # Рисуем трапецию + trapezoid = patches.Polygon([(0, 0), (a, 0), (b, h), (0, h)], closed=True, fill=None, edgecolor='r') + ax.add_patch(trapezoid) + + # Разбиваем трапецию на квадраты + split_trapezoid(a, b, h, ax) + + # Устанавливаем пределы осей + ax.set_xlim(-1, max(a, b) + 1) + ax.set_ylim(-1, h + 1) + ax.set_aspect('equal') + + plt.show() + +def split_trapezoid(a, b, h, ax): + if a == 0 or b == 0 or h == 0: + return + + # Найдите самый большой квадрат, который можно вписать в трапецию + largest_square_side = h + + # Поместите квадрат в трапецию + place_square(largest_square_side, 0, 0, ax) + + # Разделите оставшуюся часть трапеции + remaining_a = a - largest_square_side + remaining_b = b - largest_square_side + + # Повторите процесс для новых трапеций + if remaining_a > 0: + split_trapezoid(remaining_a, b, h, ax) + if remaining_b > 0: + split_trapezoid(a, remaining_b, h, ax) + +def place_square(side, x, y, ax): + # Функция для помещения квадрата в трапецию + square = patches.Rectangle((x, y), side, side, linewidth=1, edgecolor='b', facecolor='none') + ax.add_patch(square) + +# Пример использования +a = 10 # Длина верхнего основания трапеции +b = 20 # Длина нижнего основания трапеции +h = 5 # Высота трапеции + +draw_trapezoid(a, b, h) diff --git a/4.py b/4.py new file mode 100644 index 0000000..268aec6 --- /dev/null +++ b/4.py @@ -0,0 +1,52 @@ +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +def draw_trapezoid(a, b, h): + fig, ax = plt.subplots() + + # Рисуем трапецию + trapezoid = patches.Polygon([(0, 0), (a, 0), (b, h), (0, h)], closed=True, fill=None, edgecolor='r') + ax.add_patch(trapezoid) + + # Разбиваем трапецию на квадраты + split_trapezoid(a, b, h, ax, 0, 0) + + # Устанавливаем пределы осей + ax.set_xlim(-1, max(a, b) + 1) + ax.set_ylim(-1, h + 1) + ax.set_aspect('equal') + + plt.show() + +def split_trapezoid(a, b, h, ax, x_offset, y_offset): + if a <= 0 or b <= 0 or h <= 0: + return + + # Найдите самый большой квадрат, который можно вписать в трапецию + largest_square_side = min(a, b, h) + + # Поместите квадрат в трапецию + place_square(largest_square_side, x_offset, y_offset, ax) + + # Разделите оставшуюся часть трапеции + remaining_a = a - largest_square_side + remaining_b = b - largest_square_side + remaining_h = h - largest_square_side + + # Повторите процесс для новых трапеций + if remaining_a > 0 and remaining_h > 0: + split_trapezoid(remaining_a, b, remaining_h, ax, x_offset + largest_square_side, y_offset) + if remaining_b > 0 and remaining_h > 0: + split_trapezoid(a, remaining_b, remaining_h, ax, x_offset, y_offset + largest_square_side) + +def place_square(side, x, y, ax): + # Функция для помещения квадрата в трапецию + square = patches.Rectangle((x, y), side, side, linewidth=1, edgecolor='b', facecolor='none') + ax.add_patch(square) + +# Пример использования +a = 10 # Длина верхнего основания трапеции +b = 20 # Длина нижнего основания трапеции +h = 5 # Высота трапеции + +draw_trapezoid(a, b, h) diff --git a/5.py b/5.py new file mode 100644 index 0000000..c5ca0b0 --- /dev/null +++ b/5.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# Функция для создания координат трапеции +def trapezoid(a, b, h): + # Точки четырехугольника трапеции + x = [-(a/2), -(b/2), b/2, a/2, -(a/2)] + y = [0, h, h, 0, 0] + return x, y + +# Функция для рисования квадратов внутри трапеции +def draw_squares_in_trapezoid(a, b, h, square_size): + fig, ax = plt.subplots() + + # Координаты трапеции + x_trap, y_trap = trapezoid(a, b, h) + + # Рисуем трапецию + ax.plot(x_trap, y_trap, 'b') + + # Высота и шаги по оси y + current_y = 0 + while current_y + square_size <= h: + # Находим ширину трапеции на уровне current_y + width_at_y = b + (a - b) * (current_y / h) + + # Количество квадратов в текущем ряду + num_squares_in_row = int(width_at_y // square_size) + + # Начальная точка для отрисовки квадратов по оси x + start_x = -(num_squares_in_row * square_size) / 2 + + # Рисуем квадраты в ряду + for i in range(num_squares_in_row): + square = plt.Rectangle((start_x + i * square_size, current_y), square_size, square_size, + edgecolor='black', facecolor='none') + ax.add_patch(square) + + # Переходим на следующий ряд + current_y += square_size + + ax.set_aspect('equal') + plt.xlim(-a / 2 - 1, a / 2 + 1) + plt.ylim(0, h + 1) + plt.title("Разбиение трапеции на квадраты") + plt.grid(True) + plt.show() + +# Задаем размеры трапеции и квадрата +a = 10 # длина большего основания +b = 6 # длина меньшего основания +h = 8 # высота +square_size = 1 # сторона квадрата + +draw_squares_in_trapezoid(a, b, h, square_size) diff --git a/6.py b/6.py new file mode 100644 index 0000000..73c997c --- /dev/null +++ b/6.py @@ -0,0 +1,61 @@ +import matplotlib.pyplot as plt +import numpy as np + +def draw_trapezoid_with_squares(a, b, h, square_size): + """ + Рисует трапецию с квадратами внутри. + + Параметры: + a (float): Верхнее основание трапеции. + b (float): Нижнее основание трапеции. + h (float): Высота трапеции. + square_size (float): Сторона квадрата. + """ + + # Функция для вычисления ширины трапеции на уровне y + def width_at_height(y): + return b - (b - a) * (y / h) + + # Параметры для построения графика + fig, ax = plt.subplots() + + # Стартовая высота + y = 0 + + # Проходим по каждому уровню, начиная с нижнего + while y < h: + # Вычисляем ширину трапеции на текущем уровне + current_width = width_at_height(y) + + # Определяем левый и правый край на уровне + left_x = -(current_width / 2) + right_x = current_width / 2 + + # Заполняем уровень квадратами + x = left_x + while x + square_size <= right_x: + # Рисуем квадрат + square = plt.Rectangle((x, y), square_size, square_size, edgecolor='black', facecolor='blue', fill=True) + ax.add_patch(square) + x += square_size + + # Если осталась неполная часть, рисуем неполный квадрат + if x < right_x: + square = plt.Rectangle((x, y), right_x - x, square_size, edgecolor='black', facecolor='blue', fill=True) + ax.add_patch(square) + + # Переходим на следующий уровень + y += square_size + + # Рисуем саму трапецию + trapezoid = np.array([[-b/2, 0], [b/2, 0], [a/2, h], [-a/2, h], [-b/2, 0]]) + ax.plot(trapezoid[:, 0], trapezoid[:, 1], color='black') + + # Настройки графика + ax.set_aspect('equal') + plt.xlim(-b/2 - 1, b/2 + 1) + plt.ylim(0, h + square_size) + plt.show() + +# Пример использования +draw_trapezoid_with_squares(a=6, b=10, h=8, square_size=1) diff --git a/7-1.py b/7-1.py new file mode 100644 index 0000000..480792c --- /dev/null +++ b/7-1.py @@ -0,0 +1,16 @@ + +import numpy as np +import matplotlib.pyplot as plt + +# Define the dimensions of the trapezoid +base1 = 5 +base2 = 3 +height = 4 + +# Plot the trapezoid +trap_points = np.array([[0, 0], [base1, 0], [base1, height], [0, height]]) +plt.fill(trap_points[:, 0], trap_points[:, 1], color='gray') + +# Show the plot +plt.axis('scaled') +plt.show() diff --git a/7.py b/7.py new file mode 100644 index 0000000..c76a58b --- /dev/null +++ b/7.py @@ -0,0 +1,47 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Define the dimensions of the trapezoid +base1 = 5 +base2 = 3 +height = 4 + +# Calculate the width of the rectangle that can be cut from each side of the trapezoid +rect_width = (base1 + base2) / 2 + +# Cut off two rectangles from the trapezoid +trap_points = np.array([[0, 0], [base1, 0], [base1, height], [0, height]]) +rect_points = np.array([[0, 0], [rect_width, 0], [rect_width, height], [0, height]]) +trap_cut_points = np.array([[rect_width, 0], [base2, 0], [base2, height], [rect_width, height]]) + +# Plot the original trapezoid and cut off rectangles +plt.fill(trap_points[:, 0], trap_points[:, 1], color='gray') +plt.fill(rect_points[:, 0], rect_points[:, 1], color='blue') +plt.fill(trap_cut_points[:, 0], trap_cut_points[:, 1], color='blue') + +# Calculate the size of the remaining triangle +triangle_width = base2 - rect_width +triangle_height = (base2 * height) / base1 + +# Cut off the triangle from the trapezoid +tri_points = np.array([[rect_width, 0], [base2, 0], [(base2 + rect_width) / 2, height]]) +tri_cut_points = np.array([[(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2, triangle_height], [rect_width, triangle_height]]) + +# Plot the remaining triangle and cut off triangles +plt.fill(tri_points[:, 0], tri_points[:, 1], color='green') +plt.fill(tri_cut_points[:, 0], tri_cut_points[:, 1], color='green') + +# Calculate the size of the small squares +small_square_size = min(rect_width, triangle_height) / 2 + +# Cut off the small squares from the rectangle and triangle +rect_small_squares_points = np.array([[0, 0], [small_square_size, 0], [small_square_size, small_square_size], [0, small_square_size]]) +tri_small_squares_points = np.array([[(base2 + rect_width) / 2 - small_square_size, small_square_size], [(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2 - small_square_size, 0]]) + +# Plot the small squares +plt.fill(rect_small_squares_points[:, 0], rect_small_squares_points[:, 1], color='red') +plt.fill(tri_small_squares_points[:, 0], tri_small_squares_points[:, 1], color='red') + +# Show the plot +plt.axis('scaled') +plt.show() \ No newline at end of file diff --git a/8.py b/8.py new file mode 100644 index 0000000..051dde0 --- /dev/null +++ b/8.py @@ -0,0 +1,75 @@ +import numpy as np +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d.art3d import Poly3DCollection +import matplotlib.colors as mcolors + +# Определяем новые параметры трапеции +height = 200000 # Высота трапеции увеличена до 200000 см +top_width = 8 # Ширина верхней стороны +bottom_width = 12 # Ширина нижней стороны +depth = 8 # Глубина трапеции + +# Генерация температуры на каждом уровне z (реверсированная) +def calculate_temperature(z): + # Температура изменяется от 0°C у основания до 100°C на вершине + return 100 * (z / height) + +# Сетка для разбиения трапеции на кубы +# Чтобы избежать слишком больших затрат памяти, увеличим шаг кубов до, например, 10000 см. +x_step, y_step, z_step = 1000, 1000, 10000 +x_range = np.arange(0, bottom_width, x_step) +y_range = np.arange(0, depth, y_step) +z_range = np.arange(0, height, z_step) + +fig = plt.figure(figsize=(10, 8)) +ax = fig.add_subplot(111, projection='3d') + +# Нормализация и палитра цветов +cmap = plt.get_cmap("coolwarm") +norm = mcolors.Normalize(vmin=0, vmax=100) + +# Функция для добавления куба к визуализации +def add_cube(ax, x, y, z, temperature): + vertices = [ + [x, y, z], [x+x_step, y, z], [x+x_step, y+y_step, z], [x, y+y_step, z], # нижняя грань + [x, y, z+z_step], [x+x_step, y, z+z_step], [x+x_step, y+y_step, z+z_step], [x, y+y_step, z+z_step] # верхняя грань + ] + edges = [ + [vertices[j] for j in [0, 1, 2, 3]], # нижняя грань + [vertices[j] for j in [4, 5, 6, 7]], # верхняя грань + [vertices[j] for j in [0, 1, 5, 4]], # боковая грань + [vertices[j] for j in [2, 3, 7, 6]], # боковая грань + [vertices[j] for j in [0, 3, 7, 4]], # передняя грань + [vertices[j] for j in [1, 2, 6, 5]] # задняя грань + ] + + # Определяем цвет в зависимости от температуры + color = cmap(norm(temperature)) + + ax.add_collection3d(Poly3DCollection(edges, color=color, edgecolor='black', linewidths=0.1, alpha=0.7)) + +# Заполняем трапецию кубами +for z in z_range: + # Линейная интерполяция для ширины на каждом уровне высоты + width = top_width + (bottom_width - top_width) * (height - z) / height + x_min = (bottom_width - width) / 2 + x_max = x_min + width + for x in np.arange(x_min, x_max, x_step): + for y in y_range: + temperature = calculate_temperature(z) + add_cube(ax, x, y, z, temperature) + +# Настройки графика +ax.set_xlabel("X") +ax.set_ylabel("Y") +ax.set_zlabel("Z") +ax.set_xlim(0, bottom_width) +ax.set_ylim(0, depth) +ax.set_zlim(0, height) + +# Создаём цветовую шкалу +mappable = plt.cm.ScalarMappable(cmap=cmap, norm=norm) +mappable.set_array([]) +plt.colorbar(mappable, ax=ax, label="Температура (°C)") + +plt.show() diff --git a/9.py b/9.py new file mode 100644 index 0000000..6daf428 --- /dev/null +++ b/9.py @@ -0,0 +1,37 @@ +import numpy as np +import csv + +# Параметры трапеции +height = 200000 # Высота трапеции +top_width = 8 # Ширина верхней стороны +bottom_width = 12 # Ширина нижней стороны +depth = 8 # Глубина трапеции + +# Функция для вычисления температуры в зависимости от высоты z +def calculate_temperature(z): + # Температура изменяется от 0°C у основания до 100°C на вершине + return 100 * (z / height) + +# Имя файла для сохранения данных +filename = "trapezoid_cubes_data.csv" + +# Открываем файл для записи +with open(filename, mode='w', newline='') as file: + writer = csv.writer(file) + # Записываем заголовки столбцов + writer.writerow(["x", "y", "z", "temperature"]) + + # Заполняем трапецию кубиками 1x1x1 см + for z in range(height): + # Линейная интерполяция для ширины на каждом уровне высоты + width = top_width + (bottom_width - top_width) * (height - z) / height + x_min = (bottom_width - width) / 2 + x_max = x_min + width + temperature = calculate_temperature(z) + + for x in range(int(x_min), int(x_max)): + for y in range(depth): + # Записываем координаты центра кубика и его температуру + writer.writerow([x + 0.5, y + 0.5, z + 0.5, temperature]) + +print(f"Данные успешно сохранены в файл {filename}")