added all files reserch
This commit is contained in:
27
1.py
Normal file
27
1.py
Normal file
@@ -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()
|
||||||
64
10.py
Normal file
64
10.py
Normal file
@@ -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)
|
||||||
118
11g.py
Normal file
118
11g.py
Normal file
@@ -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()
|
||||||
179
12g.py
Normal file
179
12g.py
Normal file
@@ -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}")
|
||||||
122
12gdef.py
Normal file
122
12gdef.py
Normal file
@@ -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 можно передать в цикл моделирования
|
||||||
|
# (который мы создавали ранее), чтобы начать расчеты.
|
||||||
100
12gui.py
Normal file
100
12gui.py
Normal file
@@ -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)
|
||||||
47
2.py
Normal file
47
2.py
Normal file
@@ -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()
|
||||||
51
3.py
Normal file
51
3.py
Normal file
@@ -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)
|
||||||
52
4.py
Normal file
52
4.py
Normal file
@@ -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)
|
||||||
55
5.py
Normal file
55
5.py
Normal file
@@ -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)
|
||||||
61
6.py
Normal file
61
6.py
Normal file
@@ -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)
|
||||||
16
7-1.py
Normal file
16
7-1.py
Normal file
@@ -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()
|
||||||
47
7.py
Normal file
47
7.py
Normal file
@@ -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()
|
||||||
75
8.py
Normal file
75
8.py
Normal file
@@ -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()
|
||||||
37
9.py
Normal file
37
9.py
Normal file
@@ -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}")
|
||||||
Reference in New Issue
Block a user