SimSite Deploy
Deploy SimSite - Simulation platform with FEniCS and Dang Van analysis
4464a90
import os
from django.utils import timezone
from django.conf import settings
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from .models import Simulation
from .serializers import SimulationSerializer
from .fenics_runner import run_simulation
from rest_framework.views import APIView
from DangVan.dangvan import compute_dang_van
import threading
class SimulationViewSet(viewsets.ModelViewSet):
permission_classes = [AllowAny]
queryset = Simulation.objects.all().order_by('-created_at')
serializer_class = SimulationSerializer
def create(self, request, *args, **kwargs):
name = request.data.get('name', '')
parameters = request.data.get('parameters', {})
simulation = Simulation.objects.create(
name=name,
parameters=parameters,
status='running'
)
thread = threading.Thread(
target=self._run_simulation_async,
args=(simulation.id, parameters)
)
thread.start()
serializer = self.get_serializer(simulation)
return Response(serializer.data, status=status.HTTP_201_CREATED)
def _run_simulation_async(self, simulation_id, parameters):
simulation = Simulation.objects.get(id=simulation_id)
try:
result = run_simulation(parameters)
results_dir = os.path.join(settings.BASE_DIR, 'simulation_results')
os.makedirs(results_dir, exist_ok=True)
import shutil
final_result_path = os.path.join(
results_dir,
f'result_{simulation_id}.txt'
)
shutil.copy(result['results_file'], final_result_path)
final_image_path = os.path.join(
results_dir,
f'result_{simulation_id}.png'
)
shutil.copy(result['image_file'], final_image_path)
# Copy generated frames if present
frames_meta = None
frames_src = result.get('frames') or []
if frames_src:
frames_target_dir = os.path.join(results_dir, f'frames_{simulation_id}')
os.makedirs(frames_target_dir, exist_ok=True)
copied = []
for fp in frames_src:
try:
basename = os.path.basename(fp)
dest = os.path.join(frames_target_dir, basename)
shutil.copy(fp, dest)
copied.append(f'simulation_results/frames_{simulation_id}/{basename}')
except Exception:
continue
if copied:
frames_meta = {
'dir': f'simulation_results/frames_{simulation_id}',
'files': copied,
'count': len(copied),
}
simulation.result_summary = {
'final_max': result['final_max'],
'final_mean': result['final_mean'],
'time_series': result['time_series'],
'frames': frames_meta
}
simulation.result_file_path = f'simulation_results/result_{simulation_id}.txt'
simulation.result_image_path = f'simulation_results/result_{simulation_id}.png'
simulation.status = 'completed'
simulation.completed_at = timezone.now()
simulation.save()
except Exception as e:
simulation.status = 'failed'
simulation.error_message = str(e)
simulation.save()
@action(detail=True, methods=['get'])
def result_image(self, request, pk=None):
simulation = self.get_object()
if simulation.result_image_path:
image_path = os.path.join(settings.BASE_DIR, simulation.result_image_path)
from django.http import FileResponse
return FileResponse(open(image_path, 'rb'), content_type='image/png')
return Response({'error': 'Aucune image disponible'}, status=404)
@action(detail=True, methods=['get'], url_path='frame/(?P<index>\\d+)')
def frame(self, request, pk=None, index=None):
simulation = self.get_object()
frames = (simulation.result_summary or {}).get('frames') or {}
files = frames.get('files') or []
try:
idx = int(index)
except Exception:
return Response({'error': 'Index invalide'}, status=400)
if 0 <= idx < len(files):
frame_rel = files[idx]
frame_abs = os.path.join(settings.BASE_DIR, frame_rel)
from django.http import FileResponse
return FileResponse(open(frame_abs, 'rb'), content_type='image/png')
return Response({'error': 'Frame non disponible'}, status=404)
class DangVanView(APIView):
permission_classes = [AllowAny]
def post(self, request):
data = request.data or {}
stress_series = data.get('stress_series')
a = data.get('a')
b = data.get('b')
if stress_series is None or a is None or b is None:
return Response({'error': 'Paramètres requis: stress_series, a, b'}, status=status.HTTP_400_BAD_REQUEST)
try:
result = compute_dang_van(stress_series, a, b)
return Response(result, status=status.HTTP_200_OK)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)