File size: 5,678 Bytes
4464a90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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)