Оптимизация светодиодов для равномерного света на поверхностиPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Оптимизация светодиодов для равномерного света на поверхности

Сообщение Anonymous »

Итак, у меня есть эта проблема, в которой я хочу сделать шаблон светодиодов, так что наиболее равномерный свет достигается в области на плоскости в 5 см. Я не могу изменить силу светодиодов по отдельности, и я не могу изменить схему излучения светодиодов. Таким образом, все, что я могу сделать, это распределять светодиоды в пределах площади 40 × 40 см, чтобы достичь наиболее равномерного распределения в пределах площади 20 × 20 см в 5 см от светодиодной плоскости. Я пробовал разные методы, но еще не нашел хорошего пути, ближе всего, что я получил, - это картина ниже, но это было не с моей реальной схемой радиации. Я хочу использовать от 100-200 светодиодов, что также делает его довольно большой проблемой, по крайней мере, с тем, что я пробовал. Также требуется, чтобы светодиоды расположены с минимальным расстоянием 1 см. Я думаю, что из симметрии есть много, но не смог найти хорошего способа реализовать это. Кто -нибудь знает, что это было решено где -то еще или имеет хорошую идею для этого?import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt

class SimpleRadiationPattern:
"""A simple Lambertian radiation pattern for LED illumination."""

def get_intensity_factor(self, cos_theta):
"""Return the relative intensity factor based on angle cosine."""
# Lambertian pattern: intensity proportional to cosine of the angle
if isinstance(cos_theta, np.ndarray):
return np.maximum(0, cos_theta)
else:
return max(0, cos_theta)

class LEDOptimizer:
def __init__(self, grid_size=0.2, grid_resolution=50, target_area_size=0.1, z_distance=0.05):
"""Initialize the LED optimization system."""
self.grid_size = grid_size # Size of the entire simulation area (meters)
self.grid_resolution = grid_resolution # Number of grid points
self.target_area_size = target_area_size # Size of target area (meters)
self.z_distance = z_distance # Distance from LED plane to target plane
self.radiation_pattern = SimpleRadiationPattern()

# Create the grid
self.x = np.linspace(-grid_size/2, grid_size/2, grid_resolution)
self.y = np.linspace(-grid_size/2, grid_size/2, grid_resolution)
self.X, self.Y = np.meshgrid(self.x, self.y)

# Define the target area (square region where we want uniform illumination)
self.target_mask = (
(self.X >= -target_area_size/2) &
(self.X = -target_area_size/2) &
(self.Y 0:
non_uniformity = std_dev_illuminance / mean_illuminance
else:
non_uniformity = float('inf') # Avoid division by zero

return non_uniformity

def optimize_led_positions(self, n_leds, max_iterations=100, convergence_threshold=0.001, patience=10):
"""
Optimize the positions of n_leds to achieve uniform illumination.

Parameters:
- n_leds: Number of LEDs to place
- max_iterations: Maximum number of optimization iterations
- convergence_threshold: If relative improvement is less than this for 'patience' iterations, stop
- patience: Number of consecutive iterations with minimal improvement before stopping

Returns:
- optimal_positions: Array of shape (n_leds, 2) with optimized positions
- uniformity_score: Final uniformity score (lower is better)
"""
# Initialize history for convergence tracking
self.convergence_history = []

# Track consecutive iterations with minimal improvement
stagnant_iterations = 0

# Initial guess: place LEDs in a grid around the target area
grid_side = int(np.ceil(np.sqrt(n_leds)))
spacing = self.target_area_size * 1.5 / (grid_side - 1) if grid_side > 1 else 0

initial_positions = []
for i in range(grid_side):
for j in range(grid_side):
if len(initial_positions) < n_leds:
x = -self.target_area_size * 0.75 + i * spacing
y = -self.target_area_size * 0.75 + j * spacing
initial_positions.append([x, y])

initial_positions = np.array(initial_positions).flatten()

# Define bounds for the LED positions
bounds = []
for _ in range(n_leds):
bounds.extend([
(-self.grid_size/2, self.grid_size/2), # x bounds
(-self.grid_size/2, self.grid_size/2) # y bounds
])

# Initial score for starting point
initial_score = self.evaluate_uniformity(initial_positions)
self.convergence_history.append(initial_score)
previous_score = initial_score
print(f"Initial uniformity score: {initial_score:.6f}")

# Define callback function to track progress and implement early stopping
def callback(xk):
nonlocal stagnant_iterations, previous_score

score = self.evaluate_uniformity(xk)
self.convergence_history.append(score)

# Calculate relative improvement
if previous_score > 0:
rel_improvement = (previous_score - score) / previous_score
else:
rel_improvement = 0

# Check for convergence
if rel_improvement < convergence_threshold:
stagnant_iterations += 1
else:
stagnant_iterations = 0

previous_score = score

# Print status every 10 iterations
if len(self.convergence_history) % 10 == 0:
print(f"Iteration {len(self.convergence_history)-1}: Score = {score:.6f}")

# Stop if we've had too many iterations with minimal improvement
if stagnant_iterations >= patience:
print(f"Stopping early - minimal improvement for {patience} consecutive iterations")
return True

return False

# Run the optimization
result = minimize(
self.evaluate_uniformity,
initial_positions,
method='L-BFGS-B',
bounds=bounds,
options={'maxiter': max_iterations},
callback=callback
)

# Reshape the result back to (n_leds, 2)
optimal_positions = result.x.reshape(-1, 2)

# Calculate the final uniformity score
uniformity_score = self.evaluate_uniformity(result.x)

print(f"Optimization complete: Final score = {uniformity_score:.6f}")
print(f"Improvement: {(initial_score - uniformity_score) / initial_score * 100:.2f}%")

return optimal_positions, uniformity_score

def plot_illuminance(self, led_positions, title="LED Illuminance Distribution"):
"""Plot the illuminance distribution with the given LED positions."""
# Calculate the illuminance
total_illuminance = self.calculate_illuminance(led_positions)

# Create the figure
plt.figure(figsize=(10, 8))

# Plot the illuminance heatmap
plt.pcolormesh(self.X, self.Y, total_illuminance, cmap='viridis', shading='auto')
plt.colorbar(label='Relative Illuminance')
plt.xlabel('X (meters)')
plt.ylabel('Y (meters)')

# Mark the target area boundary
target_x = self.target_area_size / 2
target_y = self.target_area_size / 2
plt.plot(
[-target_x, target_x, target_x, -target_x, -target_x],
[-target_y, -target_y, target_y, target_y, -target_y],
'r--', linewidth=2, label='Target Area'
)

# Mark the LED positions
plt.scatter(led_positions[:, 0], led_positions[:, 1],
color='red', marker='x', s=50, label='LEDs')

plt.title(title)
plt.legend()
plt.axis('equal')
plt.tight_layout()
plt.show()

# Example usage
if __name__ == "__main__":
# Create an optimizer instance
optimizer = LEDOptimizer(
grid_size=0.2, # 20cm x 20cm simulation area
grid_resolution=50, # 50x50 grid points for faster calculation
target_area_size=0.1, # 10cm x 10cm target area
z_distance=0.05 # 5cm distance from LEDs to target
)

# Optimize positions for 4 LEDs
n_leds = 40
optimal_positions, score = optimizer.optimize_led_positions(
n_leds,
max_iterations=100,
convergence_threshold=0.001,
patience=10
)

# Plot the results
optimizer.plot_illuminance(optimal_positions, title=f"Optimal {n_leds} LED Configuration")

# Print optimized LED positions
print("\nOptimized LED positions:")
for i, pos in enumerate(optimal_positions):
print(f"LED {i+1}: ({pos[0]:.4f}, {pos[1]:.4f})")


Подробнее здесь: https://stackoverflow.com/questions/795 ... on-surface
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»