fiqus 2025.2.0__py3-none-any.whl → 2025.11.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fiqus/MainFiQuS.py +24 -28
- fiqus/data/DataConductor.py +350 -301
- fiqus/data/DataFiQuS.py +42 -115
- fiqus/data/DataFiQuSCCT.py +150 -150
- fiqus/data/DataFiQuSConductor.py +97 -84
- fiqus/data/DataFiQuSConductorAC_Strand.py +701 -565
- fiqus/data/DataModelCommon.py +439 -0
- fiqus/data/DataMultipole.py +0 -13
- fiqus/data/DataRoxieParser.py +7 -0
- fiqus/data/DataWindingsCCT.py +37 -37
- fiqus/data/RegionsModelFiQuS.py +61 -104
- fiqus/geom_generators/GeometryCCT.py +904 -905
- fiqus/geom_generators/GeometryConductorAC_Strand.py +1863 -1391
- fiqus/geom_generators/GeometryMultipole.py +5 -4
- fiqus/geom_generators/GeometryPancake3D.py +1 -1
- fiqus/getdp_runners/RunGetdpCCT.py +13 -4
- fiqus/getdp_runners/RunGetdpConductorAC_Strand.py +341 -201
- fiqus/getdp_runners/RunGetdpPancake3D.py +2 -2
- fiqus/mains/MainConductorAC_Strand.py +141 -133
- fiqus/mains/MainMultipole.py +6 -5
- fiqus/mains/MainPancake3D.py +3 -4
- fiqus/mesh_generators/MeshCCT.py +209 -209
- fiqus/mesh_generators/MeshConductorAC_Strand.py +709 -656
- fiqus/mesh_generators/MeshMultipole.py +43 -46
- fiqus/parsers/ParserDAT.py +16 -16
- fiqus/parsers/ParserGetDPOnSection.py +212 -212
- fiqus/parsers/ParserGetDPTimeTable.py +134 -134
- fiqus/parsers/ParserMSH.py +53 -53
- fiqus/parsers/ParserPOS.py +214 -214
- fiqus/parsers/ParserRES.py +142 -142
- fiqus/plotters/PlotPythonCCT.py +133 -133
- fiqus/plotters/PlotPythonConductorAC.py +1079 -855
- fiqus/plotters/PlotPythonMultipole.py +18 -18
- fiqus/post_processors/PostProcessCCT.py +444 -440
- fiqus/post_processors/PostProcessConductorAC.py +997 -49
- fiqus/post_processors/PostProcessMultipole.py +19 -19
- fiqus/pre_processors/PreProcessCCT.py +175 -175
- fiqus/pro_material_functions/ironBHcurves.pro +246 -246
- fiqus/pro_templates/combined/CCT_template.pro +275 -274
- fiqus/pro_templates/combined/ConductorAC_template.pro +1474 -1025
- fiqus/pro_templates/combined/Multipole_template.pro +5 -5
- fiqus/utils/Utils.py +12 -7
- {fiqus-2025.2.0.dist-info → fiqus-2025.11.0.dist-info}/METADATA +65 -63
- fiqus-2025.11.0.dist-info/RECORD +86 -0
- {fiqus-2025.2.0.dist-info → fiqus-2025.11.0.dist-info}/WHEEL +1 -1
- tests/test_geometry_generators.py +4 -0
- tests/test_mesh_generators.py +5 -0
- tests/test_solvers.py +41 -4
- tests/utils/fiqus_test_classes.py +15 -6
- tests/utils/generate_reference_files_ConductorAC.py +57 -57
- tests/utils/helpers.py +97 -97
- fiqus-2025.2.0.dist-info/RECORD +0 -85
- {fiqus-2025.2.0.dist-info → fiqus-2025.11.0.dist-info}/LICENSE.txt +0 -0
- {fiqus-2025.2.0.dist-info → fiqus-2025.11.0.dist-info}/top_level.txt +0 -0
|
@@ -1,1025 +1,1474 @@
|
|
|
1
|
-
Group {
|
|
2
|
-
// ------- PROBLEM DEFINITION -------
|
|
3
|
-
// Filaments
|
|
4
|
-
Filaments_SC = Region[{<<rm.powered.Filaments.vol.numbers|join(', ')>>}]; // Filament superconducting region
|
|
5
|
-
Filament_holes = Region[{<<rm.powered.Filaments.surf_in.numbers|join(', ')>>}]; // Filament holes
|
|
6
|
-
|
|
7
|
-
Filaments = Region[{Filaments_SC, Filament_holes}]; // Filaments (including holes)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Cuts = Region[{<<rm.powered.Filaments.cochain.numbers|join(', ')>>}]; // Cuts on filament boundaries
|
|
12
|
-
|
|
13
|
-
// Define the filaments, boundaries and cuts according to their layer and index in the layer
|
|
14
|
-
{% if len(rm.powered.Filaments.vol.numbers) % 6 == 0 %} // There is no inner layer (of length 1)
|
|
15
|
-
{% for layer in range( int(len(rm.powered.Filaments.vol.numbers)/6 )) %}
|
|
16
|
-
{% for filament_index in range(6) %}
|
|
17
|
-
filament_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.vol.numbers[layer*6 + filament_index]>>}]; // Filament surface
|
|
18
|
-
filamentBnd_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.surf.numbers[layer*6 + filament_index]>>}]; // Boundary
|
|
19
|
-
Cut_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.cochain.numbers[layer*6 + filament_index]>>}]; // Cut
|
|
20
|
-
{%endfor%}
|
|
21
|
-
{%endfor%}
|
|
22
|
-
|
|
23
|
-
{% elif len(rm.powered.Filaments.vol.numbers) % 6 == 1 %} // There is an inner layer (of length 1)
|
|
24
|
-
// Define the inner point
|
|
25
|
-
filament_0_0 = Region[{<<rm.powered.Filaments.vol.numbers[0]>>}];
|
|
26
|
-
filamentBnd_0_0 = Region[{<<rm.powered.Filaments.surf.numbers[0]>>}];
|
|
27
|
-
Cut_0_0 = Region[{<<rm.powered.Filaments.cochain.numbers[0]>>}];
|
|
28
|
-
|
|
29
|
-
{% for layer in range(0, int((len(rm.powered.Filaments.vol.numbers)-1) /6 ) ) %}
|
|
30
|
-
{% for filament_index in range(6) %}
|
|
31
|
-
filament_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.vol.numbers[layer*6 + filament_index + 1]>>}];
|
|
32
|
-
filamentBnd_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.surf.numbers[layer*6 + filament_index + 1]>>}];
|
|
33
|
-
Cut_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.cochain.numbers[layer*6 + filament_index + 1]>>}];
|
|
34
|
-
{%endfor%}
|
|
35
|
-
{%endfor%}
|
|
36
|
-
|
|
37
|
-
{% endif %}
|
|
38
|
-
|
|
39
|
-
// To assign different material properties to each filament hole, we need to assign them separately.
|
|
40
|
-
{% for i, hole in enumerate(rm.powered.Filaments.surf_in.numbers) %}
|
|
41
|
-
FilamentHole_<<i>> = Region[{<<hole>>}];
|
|
42
|
-
{%endfor%}
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
{%
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
{% endif %}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
{% endif %}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
{
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
{
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
{%
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
{
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
{% endif %}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
{
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
{
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
//
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
{
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
//
|
|
530
|
-
{
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
{
|
|
559
|
-
{
|
|
560
|
-
{
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
{
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
{Name
|
|
637
|
-
|
|
638
|
-
{Name
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
{
|
|
661
|
-
|
|
662
|
-
{% if dm.magnet.
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
{
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
}
|
|
803
|
-
{ Name
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
}
|
|
809
|
-
{
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
}
|
|
815
|
-
{ Name
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
{
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
{
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
In
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
{
|
|
866
|
-
|
|
867
|
-
{
|
|
868
|
-
In Matrix_partitions_for_TI; Jacobian Vol;
|
|
869
|
-
{
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
{
|
|
874
|
-
|
|
875
|
-
{
|
|
876
|
-
|
|
877
|
-
{
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
{%
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
//
|
|
908
|
-
{
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
{
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
}
|
|
1
|
+
Group {
|
|
2
|
+
// ------- PROBLEM DEFINITION -------
|
|
3
|
+
// Filaments
|
|
4
|
+
Filaments_SC = Region[{<<rm.powered.Filaments.vol.numbers|join(', ')>>}]; // Filament superconducting region
|
|
5
|
+
Filament_holes = Region[{<<rm.powered.Filaments.surf_in.numbers|join(', ')>>}]; // Filament holes
|
|
6
|
+
|
|
7
|
+
// Filaments = Region[{Filaments_SC, Filament_holes}]; // Filaments (including holes) - not used
|
|
8
|
+
|
|
9
|
+
BndFilaments = Region[{<<rm.powered.Filaments.surf.numbers|join(', ')>>}]; // Filament boundaries
|
|
10
|
+
BndFilaments_holes = Region[{<<rm.insulator.curve.numbers|join(', ')>>}]; // Filament hole boundaries
|
|
11
|
+
Cuts = Region[{<<rm.powered.Filaments.cochain.numbers|join(', ')>>}]; // Cuts on filament boundaries
|
|
12
|
+
|
|
13
|
+
// Define the filaments, boundaries and cuts according to their layer and index in the layer
|
|
14
|
+
{% if len(rm.powered.Filaments.vol.numbers) % 6 == 0 %} // There is no inner layer (of length 1)
|
|
15
|
+
{% for layer in range( int(len(rm.powered.Filaments.vol.numbers)/6 )) %}
|
|
16
|
+
{% for filament_index in range(6) %}
|
|
17
|
+
filament_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.vol.numbers[layer*6 + filament_index]>>}]; // Filament surface
|
|
18
|
+
filamentBnd_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.surf.numbers[layer*6 + filament_index]>>}]; // Boundary
|
|
19
|
+
Cut_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.cochain.numbers[layer*6 + filament_index]>>}]; // Cut
|
|
20
|
+
{%endfor%}
|
|
21
|
+
{%endfor%}
|
|
22
|
+
|
|
23
|
+
{% elif len(rm.powered.Filaments.vol.numbers) % 6 == 1 %} // There is an inner layer (of length 1)
|
|
24
|
+
// Define the inner point
|
|
25
|
+
filament_0_0 = Region[{<<rm.powered.Filaments.vol.numbers[0]>>}];
|
|
26
|
+
filamentBnd_0_0 = Region[{<<rm.powered.Filaments.surf.numbers[0]>>}];
|
|
27
|
+
Cut_0_0 = Region[{<<rm.powered.Filaments.cochain.numbers[0]>>}];
|
|
28
|
+
|
|
29
|
+
{% for layer in range(0, int((len(rm.powered.Filaments.vol.numbers)-1) /6 ) ) %}
|
|
30
|
+
{% for filament_index in range(6) %}
|
|
31
|
+
filament_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.vol.numbers[layer*6 + filament_index + 1]>>}];
|
|
32
|
+
filamentBnd_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.surf.numbers[layer*6 + filament_index + 1]>>}];
|
|
33
|
+
Cut_<<layer + 1>>_<<filament_index + 1>> = Region[{<<rm.powered.Filaments.cochain.numbers[layer*6 + filament_index + 1]>>}];
|
|
34
|
+
{%endfor%}
|
|
35
|
+
{%endfor%}
|
|
36
|
+
|
|
37
|
+
{% endif %}
|
|
38
|
+
|
|
39
|
+
// To assign different material properties to each filament hole, we need to assign them separately.
|
|
40
|
+
{% for i, hole in enumerate(rm.powered.Filaments.surf_in.numbers) %}
|
|
41
|
+
FilamentHole_<<i>> = Region[{<<hole>>}];
|
|
42
|
+
{%endfor%}
|
|
43
|
+
|
|
44
|
+
// Matrix partitions
|
|
45
|
+
{% for i, matrix_partition in enumerate(rm.induced.Matrix.vol.numbers)%}
|
|
46
|
+
Matrix_<<i>> = Region[{<<matrix_partition>>}];
|
|
47
|
+
{%endfor%}
|
|
48
|
+
|
|
49
|
+
// Matrix
|
|
50
|
+
Matrix = Region[{<<rm.induced.Matrix.vol.numbers|join(', ')>>}];
|
|
51
|
+
BndMatrix = Region[ <<rm.induced.Matrix.surf_out.numbers[0]>> ]; // Strand outer boundary
|
|
52
|
+
BndMatrixCut = Region[ {<<rm.induced.Matrix.cochain.numbers|join(', ')>>} ]; // Strand outer boundary cut
|
|
53
|
+
|
|
54
|
+
// Air
|
|
55
|
+
Air = Region[<<rm.air.vol.number>>]; // Air surface
|
|
56
|
+
BndAir = Region[<<rm.air.surf.number>>]; // Air outer boundary
|
|
57
|
+
|
|
58
|
+
// Cuts
|
|
59
|
+
{% if dm.magnet.geometry.type == 'periodic_square' %}
|
|
60
|
+
// Manual cuts
|
|
61
|
+
CutAirVertical = Region[<<rm.air.cochain.numbers[0]>>];
|
|
62
|
+
AirVerticalBoundary = Region[<<rm.air.cochain.numbers[1]>>];
|
|
63
|
+
CutAirHorizontal = Region[<<rm.air.cochain.numbers[2]>>];
|
|
64
|
+
AirHorizontalBoundary = Region[<<rm.air.cochain.numbers[3]>>];
|
|
65
|
+
|
|
66
|
+
BndMatrixCut += Region[{CutAirVertical, CutAirHorizontal}];
|
|
67
|
+
// Transition Layers of cuts
|
|
68
|
+
CutAirVerticalTL = ElementsOf[AirVerticalBoundary, OnOneSideOf CutAirVertical];
|
|
69
|
+
CutAirHorizontalTL = ElementsOf[AirHorizontalBoundary, OnOneSideOf CutAirHorizontal];
|
|
70
|
+
|
|
71
|
+
// Domain boundaries for periodic condition
|
|
72
|
+
BndDomainTop = Region[<<rm.induced.Domain.surf_out.numbers[0]>>];
|
|
73
|
+
BndDomainBottom = Region[<<rm.induced.Domain.surf_out.numbers[1]>>];
|
|
74
|
+
BndDomainLeft = Region[<<rm.induced.Domain.surf_out.numbers[2]>>];
|
|
75
|
+
BndDomainRight = Region[<<rm.induced.Domain.surf_out.numbers[3]>>];
|
|
76
|
+
{% endif %}
|
|
77
|
+
// Cuts += Region[BndMatrixCut]; // The matrix cut is not part of the 'Cuts' group anymore, but is rtreated separately
|
|
78
|
+
|
|
79
|
+
// Define a region for the matrix partitions to be included in the TI (transverse currents) problem
|
|
80
|
+
TI_adjacent_region = Region[ {Air} ]; // Define the regions adjacent to the region on which the TI problem is solved (used for defining h_perp_space_dynamic)
|
|
81
|
+
{% if dm.magnet.geometry.io_settings.load.load_from_yaml %}
|
|
82
|
+
Matrix_partitions_excluded_from_TI = Region[{<<mp.Surfaces_excluded_from_TI|join(', ')>>}]; // Matrix partitions excluded from the TI problem
|
|
83
|
+
|
|
84
|
+
Matrix_partitions_for_TI = Region[ {Matrix} ];
|
|
85
|
+
Matrix_partitions_for_TI -= Region[ {Matrix_partitions_excluded_from_TI} ]; // Matrix partitions included in the TI problem
|
|
86
|
+
|
|
87
|
+
TI_adjacent_region += Region[ {Matrix_partitions_excluded_from_TI} ]; // Define the regions adjacent to the region on which the TI problem is solved (used for defining h_perp_space_dynamic)
|
|
88
|
+
{% else %}
|
|
89
|
+
Matrix_partitions_for_TI = Region[ {Matrix} ];
|
|
90
|
+
{% endif %}
|
|
91
|
+
|
|
92
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
93
|
+
// Regions for resistors representing diffusion barriers
|
|
94
|
+
Resistors_diffusion_barrier = Region[ {} ]; // Initialize the region for the resistors representing diffusion barriers
|
|
95
|
+
{% if len(rm.powered.Filaments.vol.numbers) % 6 == 0 %} // There is no inner layer (of length 1)
|
|
96
|
+
{% for layer in range( int(len(rm.powered.Filaments.vol.numbers)/6 )) %}
|
|
97
|
+
{% for filament_index in range(6) %}
|
|
98
|
+
R_diffusion_barrier_<<layer+1>>_<<filament_index+1>> = Region[{<<5000 + layer*6 + filament_index + 1>>}];
|
|
99
|
+
Resistors_diffusion_barrier += Region[{R_diffusion_barrier_<<layer+1>>_<<filament_index+1>>}];
|
|
100
|
+
{%endfor%}
|
|
101
|
+
{%endfor%}
|
|
102
|
+
|
|
103
|
+
{% elif len(rm.powered.Filaments.vol.numbers) % 6 == 1 %} // There is an inner layer (of length 1)
|
|
104
|
+
|
|
105
|
+
{% for layer in range(0, int((len(rm.powered.Filaments.vol.numbers)-1) /6 ) ) %}
|
|
106
|
+
{% for filament_index in range(6) %}
|
|
107
|
+
R_diffusion_barrier_<<layer+1>>_<<filament_index+1>> = Region[{<<5000 + layer*6 + filament_index + 1>>}];
|
|
108
|
+
Resistors_diffusion_barrier += Region[{R_diffusion_barrier_<<layer+1>>_<<filament_index+1>>}];
|
|
109
|
+
{%endfor%}
|
|
110
|
+
{%endfor%}
|
|
111
|
+
|
|
112
|
+
{% endif %}
|
|
113
|
+
{% endif %}
|
|
114
|
+
|
|
115
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
116
|
+
// Defining physical regions for the global diffusion barrier in the matrix between filament region and external region
|
|
117
|
+
GlobalDiffusionBarrier = Region[ {<<mp.GlobalDiffusionBarrier.RegionTag>>} ]; // the barrier itself
|
|
118
|
+
MatrixInternalSurface = Region[ {<<mp.GlobalDiffusionBarrier.InternalRegionTag>>} ]; // the physical region inside of it, of which the barrier is the external boundary
|
|
119
|
+
// (for safe implementation of the discontinuous function space, instead of OnOneSideOf, which depends on the orientation of the curves)
|
|
120
|
+
{% endif %}
|
|
121
|
+
|
|
122
|
+
// Split into conducting and non-conducting domains
|
|
123
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes == 'None' or dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes == 0.0 %}
|
|
124
|
+
// Holes are treated as air -> non-conducting domain
|
|
125
|
+
LinOmegaC = Region[ {Matrix} ];
|
|
126
|
+
BndOmegaC = Region[ {BndMatrix, BndFilaments, BndFilaments_holes} ];
|
|
127
|
+
OmegaCC = Region[ {Air, Filament_holes} ];
|
|
128
|
+
{% else %}
|
|
129
|
+
// Holes are conducting -> part of the conducting domain
|
|
130
|
+
LinOmegaC = Region[ {Matrix, Filament_holes} ];
|
|
131
|
+
BndOmegaC = Region[ {BndMatrix, BndFilaments} ];
|
|
132
|
+
OmegaCC = Region[ {Air} ];
|
|
133
|
+
{% endif %}
|
|
134
|
+
NonLinOmegaC = Region[ {Filaments_SC} ];
|
|
135
|
+
OmegaC = Region[ {LinOmegaC, NonLinOmegaC} ];
|
|
136
|
+
Omega = Region[ {OmegaC, OmegaCC} ]; // the whole domain (only surfaces in 2D, or volumes in 3D)
|
|
137
|
+
|
|
138
|
+
OmegaC_AndBnd = Region[{OmegaC, BndOmegaC}]; // useful for function space definition
|
|
139
|
+
OmegaCC_AndBnd = Region[{OmegaCC, BndOmegaC, BndAir}]; // useful for function space definition
|
|
140
|
+
|
|
141
|
+
// Here we define points on the boundaries of the filaments and the outer matrix boundary.
|
|
142
|
+
// These points are used to fix the magnetic potential to zero on the boundaries.
|
|
143
|
+
MatrixPointOnBoundary = Region[<<rm.air.point.numbers[0]>>];
|
|
144
|
+
FilamentPointsOnBoundaries = Region[{<<rm.powered.Filaments.curve.numbers|join(', ')>>}];
|
|
145
|
+
ArbitraryPoints = Region[{MatrixPointOnBoundary, FilamentPointsOnBoundaries}];
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
Function{
|
|
150
|
+
// ------- GEOMETRY PARAMETERS -------
|
|
151
|
+
{% if len(rm.powered.Filaments.vol.numbers) % 6 == 0 %}
|
|
152
|
+
number_of_layers = <<len(rm.powered.Filaments.vol.numbers)>>/6;
|
|
153
|
+
{% elif len(rm.powered.Filaments.vol.numbers) % 6 == 1 %}
|
|
154
|
+
number_of_layers = (<<len(rm.powered.Filaments.vol.numbers)>>-1) / 6;
|
|
155
|
+
{% endif %}
|
|
156
|
+
|
|
157
|
+
// Set correction factor based on the periodicity length
|
|
158
|
+
{% if dm.magnet.solve.formulation_parameters.two_ell_periodicity %}
|
|
159
|
+
correctionFactor = 0.827; // to be automatized (equal to sin(x)/x with x = pi*ell/p, with ell = p/6 in the hexagonal lattice case)
|
|
160
|
+
ell = 2*correctionFactor * <<dm.conductors[dm.magnet.solve.conductor_name].strand.fil_twist_pitch>> / 6;
|
|
161
|
+
{% else %}
|
|
162
|
+
correctionFactor = 0.9549;
|
|
163
|
+
ell = correctionFactor * <<dm.conductors[dm.magnet.solve.conductor_name].strand.fil_twist_pitch>> / 6;
|
|
164
|
+
{% endif %}
|
|
165
|
+
|
|
166
|
+
// ------- MATERIAL PARAMETERS -------
|
|
167
|
+
temperature = <<dm.magnet.solve.general_parameters.temperature>>;
|
|
168
|
+
T[] = temperature; // this can be made a function of time if needed. Later on, T may also be a field we solve for.
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
mu0 = Pi*4e-7; // [H/m]
|
|
172
|
+
nu0 = 1.0/mu0; // [m/H]
|
|
173
|
+
mu[Omega] = mu0;
|
|
174
|
+
nu[Omega] = nu0;
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// Assigning resistances associated with diffusion barriers:
|
|
178
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
179
|
+
{% if dm.magnet.geometry.io_settings.load.load_from_yaml and dm.magnet.solve.diffusion_barriers.load_data_from_yaml %}
|
|
180
|
+
// If we load the geometry from a YAML file, we can load the resistances of the diffusion barriers from the YAML file.
|
|
181
|
+
{% for layer in range( int(len(rm.powered.Filaments.vol.numbers)/6 )) %}
|
|
182
|
+
{% for filament_index in range(6) %}
|
|
183
|
+
R[R_diffusion_barrier_<<layer+1>>_<<filament_index+1>>] = <<mp.DiffusionBarriers.FilamentResistances[layer*6 + filament_index]>>; // [Ohm]
|
|
184
|
+
{% endfor %}
|
|
185
|
+
{% endfor %}
|
|
186
|
+
{% else %}
|
|
187
|
+
// If we don't load the geometry from a YAML file, we can assign the resistances of the diffusion barriers from the material properties data structure.
|
|
188
|
+
{% for layer in range( int(len(rm.powered.Filaments.vol.numbers)/6 )) %}
|
|
189
|
+
{% for filament_index in range(6) %}
|
|
190
|
+
R[R_diffusion_barrier_<<layer+1>>_<<filament_index+1>>] = <<mp.DiffusionBarriers.FilamentResistances[layer*6 + filament_index]>>; // [Ohm]
|
|
191
|
+
{% endfor %}
|
|
192
|
+
{% endfor %}
|
|
193
|
+
{% endif %}
|
|
194
|
+
{% endif %}
|
|
195
|
+
|
|
196
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
197
|
+
// Handling global diffusion barrier in the matrix between filament region and external region
|
|
198
|
+
rho_contact[GlobalDiffusionBarrier] = <<mp.GlobalDiffusionBarrier.ContactResistivity>>;
|
|
199
|
+
{% endif %}
|
|
200
|
+
|
|
201
|
+
// Copper-like Matrix
|
|
202
|
+
{% if isinstance(dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer, float) %} // If the matrix has constant resistivity we can assign it directly
|
|
203
|
+
rho[Matrix] = <<dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer>>;
|
|
204
|
+
{% elif dm.magnet.geometry.io_settings.load.load_from_yaml %}
|
|
205
|
+
// If we load the geometry from a YAML file, we also have material properties assigned in a MaterialProperties (mp) data structure.
|
|
206
|
+
// This is a temporary solution. It reads the material property functions from the input YAML file and only assigns the RRR value from the geometry YAML.
|
|
207
|
+
// In the future the material properties should be assigned directly from the geometry YAML.
|
|
208
|
+
{% for i, matrix_partition_material in zip(range(len(rm.induced.Matrix.vol.numbers)), rm.induced.Matrix.vol.names)%}
|
|
209
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer == 'CFUN_rhoCu_T' %}
|
|
210
|
+
rho[Matrix_<<i>>] = CFUN_rhoCu_T[T[]]{0, << mp.Materials[matrix_partition_material].RRR >>};
|
|
211
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer == 'CFUN_rhoCu' %}
|
|
212
|
+
rho[Matrix_<<i>>] = CFUN_rhoCu_T_B[T[], $1]{<< mp.Materials[matrix_partition_material].RRR >>};
|
|
213
|
+
{% endif %}
|
|
214
|
+
{%endfor%}
|
|
215
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].strand.RRR is iterable %}
|
|
216
|
+
{% for i, RRR_i in enumerate(dm.conductors[dm.magnet.solve.conductor_name].strand.RRR) %}
|
|
217
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer == 'CFUN_rhoCu_T' %}
|
|
218
|
+
rho[Matrix_<<i>>] = CFUN_rhoCu_T[T[]]{0, <<RRR_i>>};
|
|
219
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer == 'CFUN_rhoCu' %}
|
|
220
|
+
rho[Matrix_<<i>>] = CFUN_rhoCu_T_B[T[], $1]{<<RRR_i>>};
|
|
221
|
+
{% endif %}
|
|
222
|
+
{%endfor%}
|
|
223
|
+
{% else %} // If we don't load the geometry from a YAML file, we can assign the material properties directly
|
|
224
|
+
RRR_matrix = <<dm.conductors[dm.magnet.solve.conductor_name].strand.RRR>>;
|
|
225
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer == 'CFUN_rhoCu_T' %}
|
|
226
|
+
rho[Matrix] = CFUN_rhoCu_T[T[]]{0, RRR_matrix};
|
|
227
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_stabilizer == 'CFUN_rhoCu' %}
|
|
228
|
+
rho[Matrix] = CFUN_rhoCu_T_B[T[], $1]{RRR_matrix}; //1.81e-10; //
|
|
229
|
+
// rho[Matrix_0] = CFUN_rhoCu_T_B[T[], $1]{10}; //1.81e-10; //
|
|
230
|
+
// rho[Matrix_1] = CFUN_rhoCu_T_B[T[], $1]{100}; //1.81e-10; //
|
|
231
|
+
// rho[Matrix_2] = CFUN_rhoCu_T_B[T[], $1]{1000}; //1.81e-10; //
|
|
232
|
+
{% endif %}
|
|
233
|
+
{% endif %}
|
|
234
|
+
|
|
235
|
+
// Superconducting filaments (nonlinear now)
|
|
236
|
+
ec = <<dm.conductors[dm.magnet.solve.conductor_name].strand.ec_superconductor>>; // [V/m], the value 1e-4 V/m is a common convention
|
|
237
|
+
|
|
238
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type == 'Ic_A_NbTi' and dm.conductors[dm.magnet.solve.conductor_name].strand.material_superconductor == 'NbTi' %}
|
|
239
|
+
jc[] = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Jc_5T_4_2K>> / 1.70732393e9 * CFUN_IcNbTi_T_B_a[T[], $1, 1]; // [A/m2] critical current density as function of temperature and field amplitude
|
|
240
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type == 'Ic_A_Nb3Sn' and dm.conductors[dm.magnet.solve.conductor_name].strand.material_superconductor == 'Nb3Sn' %}
|
|
241
|
+
jc[] = CFUN_IcNb3Sn_T_B_a[T[], $1, 1]; // [A/m2] critical current density as function of temperature and field amplitude
|
|
242
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type == 'Bottura' and dm.conductors[dm.magnet.solve.conductor_name].strand.material_superconductor == 'Nb3Sn' %}
|
|
243
|
+
Tc0_Bottura = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Tc0_Bottura>>;
|
|
244
|
+
Bc20_Bottura = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Bc20_Bottura>>;
|
|
245
|
+
C0_Bottura = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.C0_Bottura>>;
|
|
246
|
+
jc[] = CFUN_Jc_Nb3Sn_Bottura_T_B[T[], $1]{Tc0_Bottura, Bc20_Bottura, C0_Bottura, 0.5, 2, 1, 1}; // p = 0.5, q = 2
|
|
247
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type == 'Bordini' %}
|
|
248
|
+
C0_Bordini = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.C0_Bordini>>;
|
|
249
|
+
Tc0_Bordini = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Tc0_Bordini>>;
|
|
250
|
+
Bc20_Bordini = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Bc20_Bordini>>;
|
|
251
|
+
alpha_Bordini = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.alpha_Bordini>>;
|
|
252
|
+
jc[] = CFUN_Jc_Bordini_T_B[T[], $1]{C0_Bordini, Tc0_Bordini, Bc20_Bordini, alpha_Bordini};
|
|
253
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type == 'Nb3Sn_HFM' %}
|
|
254
|
+
C0_Nb3Sn_HFM = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.C0_Nb3Sn_HFM>>;
|
|
255
|
+
Tc0_Nb3Sn_HFM = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Tc0_Nb3Sn_HFM>>;
|
|
256
|
+
Bc20_Nb3Sn_HFM = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Bc20_Nb3Sn_HFM>>;
|
|
257
|
+
alpha_Nb3Sn_HFM = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.alpha_Nb3Sn_HFM>>;
|
|
258
|
+
nu_Nb3Sn_HFM = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.nu_Nb3Sn_HFM>>;
|
|
259
|
+
p_Nb3Sn_HFM = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.p_Nb3Sn_HFM>>;
|
|
260
|
+
q_Nb3Sn_HFM = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.q_Nb3Sn_HFM>>;
|
|
261
|
+
jc[] = CFUN_Jc_Nb3Sn_HFM_T_B[T[], $1]{C0_Nb3Sn_HFM, Tc0_Nb3Sn_HFM, Bc20_Nb3Sn_HFM, alpha_Nb3Sn_HFM, nu_Nb3Sn_HFM, p_Nb3Sn_HFM, q_Nb3Sn_HFM};
|
|
262
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type == 'ProDefined' %}
|
|
263
|
+
C0 = <<float(dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.C0)>>;
|
|
264
|
+
Tc0 = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Tc0>>;
|
|
265
|
+
Bc20 = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Bc20>> + <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.B0>>;
|
|
266
|
+
alpha = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.alpha>>;
|
|
267
|
+
p = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.p>>;
|
|
268
|
+
q = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.q>>;
|
|
269
|
+
v = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.v>>;
|
|
270
|
+
B0 = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.B0>>;
|
|
271
|
+
jc[] = (C0 * (1 - (T[] / Tc0)^v)^alpha * (1 - (T[] / Tc0)^2)^alpha) / (Abs[$1] + B0) * (Min[(Abs[$1] + B0) / (Bc20 * (1 - (T[] / Tc0)^v)), 1])^p * (1 - Min[(Abs[$1] + B0) / (Bc20 * (1 - (T[] / Tc0)^v)), 1])^q ;
|
|
272
|
+
|
|
273
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type == 'Constant Jc' %}
|
|
274
|
+
jc[] = <<dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.Jc_constant>>; // [A/m2] constant critical current density
|
|
275
|
+
{% endif %}
|
|
276
|
+
|
|
277
|
+
// Power law
|
|
278
|
+
eps_jc[] = <<dm.conductors[dm.magnet.solve.conductor_name].strand.minimum_jc_fraction>> * jc[<<dm.conductors[dm.magnet.solve.conductor_name].strand.minimum_jc_field>>];
|
|
279
|
+
n = <<dm.conductors[dm.magnet.solve.conductor_name].strand.n_value_superconductor>>; // [-] power law index, one key parameter for the power law
|
|
280
|
+
rho_power[] = ec / (Max[jc[$2],eps_jc[]]) * (Norm[$1] / (Max[jc[$2],eps_jc[]]))^(n - 1); // [Ohm m] power law resistivity
|
|
281
|
+
e_power[] = rho_power[$1, $2] * $1;
|
|
282
|
+
dedj_power[] = (
|
|
283
|
+
ec / ((Max[jc[$2],eps_jc[]])#1) * (Norm[$1]/#1)^(n - 1) * TensorDiag[1, 1, 1] +
|
|
284
|
+
ec / (#1)^3 * (n - 1) * (Norm[$1]/#1)^(n - 3) * SquDyadicProduct[$1]);
|
|
285
|
+
|
|
286
|
+
db = 0.005;
|
|
287
|
+
// outer_product[] = Tensor[CompX[$1]*CompX[$2], CompX[$1]*CompY[$2], CompX[$1]*CompZ[$2], CompY[$1]*CompX[$2], CompY[$1]*CompY[$2], CompY[$1]*CompZ[$2], CompZ[$1]*CompX[$2], CompZ[$1]*CompY[$2], CompZ[$1]*CompZ[$2]];
|
|
288
|
+
// dedb_power[] = -n*ec/jc[Norm[$2]]^2 * (Norm[$1]/jc[Norm[$2]])^(n-1) * ( jc[Norm[$2] + db] - jc[Max[0, Norm[$2] - db]] ) / (2*db) * outer_product[$1, $2]/(Norm[$2]+1e-10); // Is this one correct?
|
|
289
|
+
dedb_power[] = Tensor[ CompX[(e_power[$1, Norm[$2+Vector[db,0,0]]] - e_power[$1, Norm[$2+Vector[-db,0,0]]])#1],
|
|
290
|
+
CompX[(e_power[$1, Norm[$2+Vector[0,db,0]]] - e_power[$1, Norm[$2+Vector[0,-db,0]]])#2],
|
|
291
|
+
CompX[(e_power[$1, Norm[$2+Vector[0,0,db]]] - e_power[$1, Norm[$2+Vector[0,0,-db]]])#3],
|
|
292
|
+
CompY[#1], CompY[#2], CompY[#3],
|
|
293
|
+
CompZ[#1], CompZ[#2], CompZ[#3]] / (2*db);
|
|
294
|
+
|
|
295
|
+
// Trials for extending the power to overcritical regimes
|
|
296
|
+
rho_N = 1e-7; // Resistivity of the filaments in their normal state
|
|
297
|
+
// 1) This first option shows very poor convergence properties: fails to convergence at the transition from normal state to superconducting state (NaN)
|
|
298
|
+
// rho_power_normal[] = Min[rho_power[$1, $2], rho_N];
|
|
299
|
+
// dedj_power_normal[] = (rho_power[$1, $2] <= rho_N) ? dedj_power[$1, $2] : rho_N * TensorDiag[1, 1, 1];
|
|
300
|
+
// dedb_power_normal[] = (jc[Norm[$2]] > eps_jc) ? dedb_power[$1, $2] : TensorDiag[0, 0, 0];
|
|
301
|
+
// 2) The second option below also shows very poor convergence: iteration cycles
|
|
302
|
+
// rho_power_normal[] = 1. / (1./rho_power[$1,$2] + 1./rho_N);
|
|
303
|
+
rho_power_normal[] = rho_power[$1,$2] / (1 + rho_power[$1,$2]/rho_N);
|
|
304
|
+
dedj_power_normal[] = rho_power_normal[$1,$2] * TensorDiag[1, 1, 1] + ec*(n-1)*Norm[$1]^(n-3) /((Max[jc[$2],eps_jc[]])^n)/(1+rho_power[$1,$2]/rho_N)^2 * SquDyadicProduct[$1];
|
|
305
|
+
// dedb_power_normal[] = 1./(1+rho_power[$1,Norm[$2]]/rho_N)^2 * dedb_power[$1,$2];
|
|
306
|
+
// 3) Third option with log-sum-exp expression to describe the transition... to be tried.
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
{% if dm.magnet.solve.general_parameters.superconductor_linear %}
|
|
310
|
+
mult_copper_like = 1e-5;
|
|
311
|
+
// Set everything to copper
|
|
312
|
+
rho[Filaments_SC] = 1.81e-10;
|
|
313
|
+
dedj[Filaments_SC] = 1.81e-10;
|
|
314
|
+
{% else %}
|
|
315
|
+
rho[Filaments_SC] = rho_power[$1, $2];
|
|
316
|
+
dedj[Filaments_SC] = dedj_power[$1, $2];
|
|
317
|
+
// rho[Filaments_SC] = rho_power_normal[$1, $2]; // Power law in parallel with constant resistivity -> poor convergence is observed
|
|
318
|
+
// dedj[Filaments_SC] = dedj_power_normal[$1, $2];
|
|
319
|
+
{% endif %}
|
|
320
|
+
// The de/db Jacobian is not used for the moment
|
|
321
|
+
dedb[Filaments_SC] = dedb_power[$1, $2];
|
|
322
|
+
// dedb[Filaments_SC] = dedb_power_normal[$1, $2]; // Poor convergence observed (cycles)
|
|
323
|
+
|
|
324
|
+
{% if dm.magnet.geometry.io_settings.load.load_from_yaml %}
|
|
325
|
+
// We assign material properties to each filament hole. Currently we just assign the same properties as the matrix, but with a different RRR.
|
|
326
|
+
// This must be updated to actually use the correct material property read from the geometry YAML.
|
|
327
|
+
{% for i, hole_material in zip(range(len(rm.powered.Filaments.surf_in.numbers)), rm.powered.Filaments.surf_in.names)%}
|
|
328
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes == 'CFUN_rhoCu_T' %}
|
|
329
|
+
rho[FilamentHole_<<i>>] = CFUN_rhoCu_T[T[]]{0, << mp.Materials[hole_material].RRR >>};
|
|
330
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes == 'CFUN_rhoCu_T_B' %}
|
|
331
|
+
rho[FilamentHole_<<i>>] = CFUN_rhoCu_T_B[T[], $1]{<< mp.Materials[hole_material].RRR >>};
|
|
332
|
+
{% elif isinstance(dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes, float) %} // If the matrix has constant resistivity we can assign it directly
|
|
333
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes %} // non-zero
|
|
334
|
+
rho[FilamentHole_<<i>>] = <<dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes>>;
|
|
335
|
+
{% endif %}
|
|
336
|
+
{% endif %}
|
|
337
|
+
{% endfor %}
|
|
338
|
+
{% else %} // parametric geometry
|
|
339
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.filament_hole_diameter %} // only if holes are present
|
|
340
|
+
{% for i, hole_material in zip(range(len(rm.powered.Filaments.surf_in.numbers)), rm.powered.Filaments.surf_in.names)%}
|
|
341
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes == 'CFUN_rhoCu_T' %}
|
|
342
|
+
rho[FilamentHole_<<i>>] = CFUN_rhoCu_T[T[]]{0, 50}; // only temporary as the hole material should be air
|
|
343
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes == 'CFUN_rhoCu_T_B' %}
|
|
344
|
+
rho[FilamentHole_<<i>>] = CFUN_rhoCu_T_B[T[], $1]{50}; // only temporary as the hole material should be air
|
|
345
|
+
{% elif isinstance(dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes, float) %} // If the matrix has constant resistivity we can assign it directly
|
|
346
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes %} // non-zero
|
|
347
|
+
rho[FilamentHole_<<i>>] = <<dm.conductors[dm.magnet.solve.conductor_name].strand.rho_material_holes>>;
|
|
348
|
+
{% endif %}
|
|
349
|
+
{% endif %}
|
|
350
|
+
{% endfor %}
|
|
351
|
+
{% endif %}
|
|
352
|
+
{% endif %}
|
|
353
|
+
|
|
354
|
+
sigma[] = 1/rho[$1] ; // Can only be used in the matrix
|
|
355
|
+
|
|
356
|
+
// HEAT APPROXIMATION
|
|
357
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.Cv_material_superconductor == 'CFUN_CvNbTi' %}
|
|
358
|
+
filament_Cv[] = CFUN_CvNbTi_T_B[$1, $2]{0, 1, 0}; // Volumetric heat capacity [J/(m3 K)], as function of temperature and field magnitude.
|
|
359
|
+
{% elif dm.conductors[dm.magnet.solve.conductor_name].strand.Cv_material_superconductor == 'CFUN_CvNb3Sn' %}
|
|
360
|
+
filament_Cv[] = CFUN_CvNb3Sn_T_B[$1, $2]; // Volumetric heat capacity [J/(m3 K)], as function of temperature and field magnitude.
|
|
361
|
+
{% endif %}
|
|
362
|
+
|
|
363
|
+
{% if dm.conductors[dm.magnet.solve.conductor_name].strand.Cv_material_stabilizer == 'CFUN_CvCu' %}
|
|
364
|
+
matrix_Cv[] = CFUN_CvCu_T[$1]; // Volumetric heat capacity [J/(m3 K)], as function of temperature
|
|
365
|
+
{% endif %}
|
|
366
|
+
|
|
367
|
+
// ------- SOURCE PARAMETERS -------
|
|
368
|
+
directionApplied[] = Vector[Cos[<<dm.magnet.solve.source_parameters.field_angle>>*Pi/180], Sin[<<dm.magnet.solve.source_parameters.field_angle>>*Pi/180], 0.];
|
|
369
|
+
// same for piecewise and sine
|
|
370
|
+
{% if dm.magnet.solve.source_parameters.source_type == 'sine' %}
|
|
371
|
+
// Sine wave source (with DC component)
|
|
372
|
+
f = <<dm.magnet.solve.source_parameters.sine.frequency>>; // Frequency of applied field [Hz]
|
|
373
|
+
|
|
374
|
+
time_multiplier = 1; // Set to 1, as it is being used in the resolution
|
|
375
|
+
|
|
376
|
+
// ramp_duration = -5e-2 / f; // Ramp duration for constant source components
|
|
377
|
+
// quad_ramp_I[] = (Sqrt[<<dm.magnet.solve.source_parameters.sine.superimposed_DC.current_magnitude>>] / ramp_duration * $Time )^2;
|
|
378
|
+
// constant_I_transport[] = ($Time < ramp_duration ) ? InterpolationLinear[$Time]{List[{0,0,ramp_duration,<<dm.magnet.solve.source_parameters.sine.superimposed_DC.current_magnitude>>}]} : <<dm.magnet.solve.source_parameters.sine.superimposed_DC.current_magnitude>>;
|
|
379
|
+
constant_I_transport[] = <<dm.magnet.solve.source_parameters.sine.superimposed_DC.current_magnitude>>;
|
|
380
|
+
I_transport[] = constant_I_transport[$Time] + <<dm.magnet.solve.source_parameters.sine.current_amplitude>> * Sin[2*Pi*f * $Time];
|
|
381
|
+
|
|
382
|
+
constant_field_magnitude = <<dm.magnet.solve.source_parameters.sine.superimposed_DC.field_magnitude>>;
|
|
383
|
+
hsVal[] = nu0 * (<<dm.magnet.solve.source_parameters.sine.field_amplitude>> * Sin[2*Pi*f * $Time] + constant_field_magnitude) * directionApplied[];
|
|
384
|
+
hsVal_prev[] = nu0 *(<<dm.magnet.solve.source_parameters.sine.field_amplitude>> * Sin[2*Pi*f * ($Time-$DTime)] + constant_field_magnitude) * directionApplied[];
|
|
385
|
+
|
|
386
|
+
{% elif dm.magnet.solve.source_parameters.source_type == 'rotating' %}
|
|
387
|
+
// Rotating magnetic field
|
|
388
|
+
f = <<dm.magnet.solve.source_parameters.rotating.frequency>>;
|
|
389
|
+
ramp_duration = 1e-1 / f;
|
|
390
|
+
|
|
391
|
+
time_multiplier = 1;
|
|
392
|
+
I_transport[] = 0;
|
|
393
|
+
constant_field_magnitude[] = ($Time < ramp_duration ) ? InterpolationLinear[$Time]{List[{0,0,ramp_duration,<<dm.magnet.solve.source_parameters.rotating.field_magnitude>>}]} : <<dm.magnet.solve.source_parameters.rotating.field_magnitude>>;
|
|
394
|
+
constant_field_magnitude_prev[] = ($Time-$DTime < ramp_duration ) ? InterpolationLinear[$Time-$DTime]{List[{0,0,ramp_duration,<<dm.magnet.solve.source_parameters.rotating.field_magnitude>>}]} : <<dm.magnet.solve.source_parameters.rotating.field_magnitude>>;
|
|
395
|
+
|
|
396
|
+
hsVal[] = nu0 * constant_field_magnitude[] * Vector[Cos[2*Pi*f*$Time], Sin[2*Pi*f*$Time], 0.];
|
|
397
|
+
hsVal_prev[] = nu0 * constant_field_magnitude_prev[] * Vector[Cos[2*Pi*f*($Time-$DTime)], Sin[2*Pi*f*($Time-$DTime)], 0.];
|
|
398
|
+
|
|
399
|
+
{% elif dm.magnet.solve.source_parameters.source_type == 'piecewise' %}
|
|
400
|
+
|
|
401
|
+
time_multiplier = <<dm.magnet.solve.source_parameters.piecewise.time_multiplier>>;
|
|
402
|
+
applied_field_multiplier = <<dm.magnet.solve.source_parameters.piecewise.applied_field_multiplier>>;
|
|
403
|
+
transport_current_multiplier = <<dm.magnet.solve.source_parameters.piecewise.transport_current_multiplier>>;
|
|
404
|
+
|
|
405
|
+
{% if dm.magnet.solve.source_parameters.piecewise.source_csv_file %} // Source from CSV file
|
|
406
|
+
timeList() = {<<ed['time']|join(', ')>>};
|
|
407
|
+
valueList() = {<<ed['value']|join(', ')>>};
|
|
408
|
+
timeValuesList() = ListAlt[timeList(), valueList()];
|
|
409
|
+
|
|
410
|
+
hsVal[] = nu0 * applied_field_multiplier * InterpolationLinear[Max[0,($Time)/time_multiplier]]{List[timeValuesList()]} * directionApplied[];
|
|
411
|
+
hsVal_prev[] = nu0 * applied_field_multiplier * InterpolationLinear[Max[0,($Time-$DTime)/time_multiplier]]{List[timeValuesList()]} * directionApplied[];
|
|
412
|
+
I_transport[] = transport_current_multiplier * InterpolationLinear[Max[0,($Time)/time_multiplier]]{List[timeValuesList()]};
|
|
413
|
+
|
|
414
|
+
{% else %} // Source from parameters
|
|
415
|
+
times_source_piecewise_linear() = {<<dm.magnet.solve.source_parameters.piecewise.times|join(', ')>>};
|
|
416
|
+
transport_currents_relative_piecewise_linear() = {<<dm.magnet.solve.source_parameters.piecewise.transport_currents_relative|join(', ')>>};
|
|
417
|
+
applied_fields_relative_piecewise_linear() = {<<dm.magnet.solve.source_parameters.piecewise.applied_fields_relative|join(', ')>>};
|
|
418
|
+
|
|
419
|
+
hsVal[] = nu0 * applied_field_multiplier * InterpolationLinear[Max[0,($Time)/time_multiplier]]{ListAlt[times_source_piecewise_linear(), applied_fields_relative_piecewise_linear()]} * directionApplied[];
|
|
420
|
+
hsVal_prev[] = nu0 * applied_field_multiplier * InterpolationLinear[Max[0,($Time-$DTime)/time_multiplier]]{ListAlt[times_source_piecewise_linear(), applied_fields_relative_piecewise_linear()]} * directionApplied[];
|
|
421
|
+
I_transport[] = transport_current_multiplier * InterpolationLinear[Max[0,($Time)/time_multiplier]]{ListAlt[times_source_piecewise_linear(), transport_currents_relative_piecewise_linear()]};
|
|
422
|
+
{% endif %}
|
|
423
|
+
{% endif %}
|
|
424
|
+
|
|
425
|
+
// For the natural boundary condition (restricted to fields of constant direction for the moment, should be generalized)
|
|
426
|
+
dbsdt[] = mu0 * (hsVal[] - hsVal_prev[]) / $DTime; // must be a finite difference to avoid error accumulation
|
|
427
|
+
|
|
428
|
+
// ------- NUMERICAL PARAMETERS -------
|
|
429
|
+
timeStart = 0.; // Initial time [s]
|
|
430
|
+
|
|
431
|
+
{% if dm.magnet.solve.source_parameters.source_type == 'sine'%}
|
|
432
|
+
timeFinal = <<dm.magnet.solve.numerical_parameters.sine.number_of_periods_to_simulate>>/f; // Final time for source definition (s)
|
|
433
|
+
dt = 1 / (f*<<dm.magnet.solve.numerical_parameters.sine.timesteps_per_period>>); // Time step (initial if adaptive) (s)
|
|
434
|
+
dt_max = dt; // Fixed maximum time step
|
|
435
|
+
dt_max_var[] = dt_max;
|
|
436
|
+
{% elif dm.magnet.solve.source_parameters.source_type == 'rotating'%}
|
|
437
|
+
timeFinal = <<dm.magnet.solve.numerical_parameters.rotating.number_of_periods_to_simulate>>/f; // Final time for source definition (s)
|
|
438
|
+
dt = 1 / (f*<<dm.magnet.solve.numerical_parameters.rotating.timesteps_per_period>>); // Time step (initial if adaptive) (s)
|
|
439
|
+
dt_max = dt; // Fixed maximum time step
|
|
440
|
+
dt_max_var[] = dt_max;
|
|
441
|
+
{% else %}
|
|
442
|
+
timeFinal = <<dm.magnet.solve.numerical_parameters.piecewise.time_to_simulate>>;
|
|
443
|
+
|
|
444
|
+
{% if dm.magnet.solve.numerical_parameters.piecewise.variable_max_timestep %}
|
|
445
|
+
times_max_timestep_piecewise_linear() = {<<dm.magnet.solve.numerical_parameters.piecewise.times_max_timestep_piecewise_linear|join(', ')>>};
|
|
446
|
+
max_timestep_piecewise_linear() = {<<dm.magnet.solve.numerical_parameters.piecewise.max_timestep_piecewise_linear|join(', ')>>};
|
|
447
|
+
dt = max_timestep_piecewise_linear(0);
|
|
448
|
+
dt_max_var[] = InterpolationLinear[Max[0,$Time]]{ListAlt[times_max_timestep_piecewise_linear(), max_timestep_piecewise_linear()]};
|
|
449
|
+
{% else %}
|
|
450
|
+
dt = timeFinal / <<dm.magnet.solve.numerical_parameters.piecewise.timesteps_per_time_to_simulate>>;
|
|
451
|
+
dt_max = dt; // Fixed maximum time step
|
|
452
|
+
dt_max_var[] = dt_max;
|
|
453
|
+
{% endif %}
|
|
454
|
+
|
|
455
|
+
{% if dm.magnet.solve.numerical_parameters.piecewise.force_stepping_at_times_piecewise_linear%}
|
|
456
|
+
control_time_instants_list() = {<<dm.magnet.solve.source_parameters.piecewise.times|join(', ')>>, 1e99}; // last one is just to avoid 'seg. fault' errors
|
|
457
|
+
{% endif %}
|
|
458
|
+
|
|
459
|
+
{% endif %}
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
iter_max = 60; // Maximum number of iterations (after which we exit the iterative loop)
|
|
464
|
+
extrapolationOrder = 1; // Extrapolation order for predictor
|
|
465
|
+
tol_energy = 1e-6; // Tolerance on the relative change of the power indicator
|
|
466
|
+
writeInterval = dt; // Time interval to save the solution [s]
|
|
467
|
+
|
|
468
|
+
// ------- SIMULATION NAME -------
|
|
469
|
+
name = "text_output";
|
|
470
|
+
resDirectory = StrCat["./",name];
|
|
471
|
+
infoResidualFile = StrCat[resDirectory,"/residual.txt"];
|
|
472
|
+
outputPower = StrCat[resDirectory,"/power.txt"]; // File updated during runtime
|
|
473
|
+
crashReportFile = StrCat[resDirectory,"/crash_report.txt"];
|
|
474
|
+
outputTemperature = StrCat[resDirectory,"/temperature.txt"];
|
|
475
|
+
|
|
476
|
+
{% if dm.magnet.solve.initial_conditions.init_type == 'pos_file' %}
|
|
477
|
+
h_from_file[] = VectorField[XYZ[]]; // After GmshRead[] in Resolution, this vector field contains the solution from a .pos file that can be accessed at any point XYZ[]
|
|
478
|
+
{% endif %}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
Constraint {
|
|
482
|
+
{ Name phi ;
|
|
483
|
+
Case {
|
|
484
|
+
// For natural boundary condition (in formulation) if dm.magnet.geometry.type == 'strand_only'
|
|
485
|
+
{Region ArbitraryPoints ; Value 0.0 ;} // Fix the magnetic potential to zero on the boundaries of the filaments and the outer matrix boundary
|
|
486
|
+
//{Region BndAir ; Type Assign ; Value XYZ[]*directionApplied[] ; TimeFunction hsVal[] * directionApplied[] ;} // Essential boundary condition (not compatible with transport current)
|
|
487
|
+
{% if dm.magnet.geometry.type == 'periodic_square' %}
|
|
488
|
+
// Link phi top to bottom
|
|
489
|
+
{
|
|
490
|
+
Region BndDomainBottom ;
|
|
491
|
+
Type Link ;
|
|
492
|
+
RegionRef BndDomainTop ;
|
|
493
|
+
Coefficient 1.0 ;
|
|
494
|
+
Function Vector[X[], Y[] + <<dm.magnet.geometry.air_radius*2>>, Z[]] ;
|
|
495
|
+
}
|
|
496
|
+
// Link phi left to right
|
|
497
|
+
{
|
|
498
|
+
Region BndDomainLeft ;
|
|
499
|
+
Type Link ;
|
|
500
|
+
RegionRef BndDomainRight ;
|
|
501
|
+
Coefficient 1.0 ;
|
|
502
|
+
Function Vector[X[] + <<dm.magnet.geometry.air_radius*2>>, Y[], Z[]] ;
|
|
503
|
+
}
|
|
504
|
+
{% endif %}
|
|
505
|
+
{% if dm.magnet.solve.initial_conditions.init_type != 'virgin' %}
|
|
506
|
+
{Region Omega ; Type InitFromResolution ; NameOfResolution Projection_h_to_h ;}
|
|
507
|
+
{% endif %}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
{ Name Current ;
|
|
511
|
+
Case {
|
|
512
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "AI_uncoupled" %}
|
|
513
|
+
{Region Cuts ; Type Assign ; Value 0. ;} // For fully uncoupled filaments !without! transport current
|
|
514
|
+
{% endif %}
|
|
515
|
+
{% if dm.magnet.solve.initial_conditions.init_type != 'virgin' %}
|
|
516
|
+
{Region Cuts ; Type InitFromResolution ; NameOfResolution Projection_h_to_h ;}
|
|
517
|
+
{% endif %}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
{ Name Current_t ;
|
|
521
|
+
Case {
|
|
522
|
+
{Region BndMatrixCut ; Type Assign ; Value 1.0 ; TimeFunction I_transport[] ;} // Contraint for the total transport current
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
{ Name FieldCirculation ;
|
|
526
|
+
Case {
|
|
527
|
+
// impose a circulation of the h-field in omegaCC
|
|
528
|
+
// MAIN CHANGE: this one or the one below
|
|
529
|
+
// {Region CutAirVertical ; Type Assign ; Value <<dm.magnet.geometry.air_radius>>*2 ; TimeFunction CompX[hsVal[]] ;} // impose component in x direction
|
|
530
|
+
// {Region CutAirHorizontal ; Type Assign ; Value <<dm.magnet.geometry.air_radius>>*2 ; TimeFunction CompY[hsVal[]] ;} // impose component in y direction
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
{ Name FluxChange ;
|
|
534
|
+
Case {
|
|
535
|
+
// impose the flux change connect through b in omegaCC
|
|
536
|
+
// MAIN CHANGE: this one or the one above (this one is for imposed flux, which maybe makes more sense physically)
|
|
537
|
+
{% if dm.magnet.geometry.type == 'periodic_square' %}
|
|
538
|
+
{Region CutAirHorizontal ; Type Assign ; Value -<<dm.magnet.geometry.air_radius>>*2 ; TimeFunction CompY[dbsdt[]] ;} // impose component in y direction
|
|
539
|
+
{Region CutAirVertical ; Type Assign ; Value -<<dm.magnet.geometry.air_radius>>*2 ; TimeFunction CompX[dbsdt[]] ;} // impose component in x direction
|
|
540
|
+
{% endif %}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
{ Name Voltage ; Case {} } // Empty to avoid warnings
|
|
544
|
+
{ Name Voltage_t ; Case {} } // Empty to avoid warnings
|
|
545
|
+
{ Name Current_plane ; Case {} } // Empty to avoid warnings
|
|
546
|
+
{ Name Voltage_plane ;
|
|
547
|
+
Case {
|
|
548
|
+
// The constraint below can be useful for debugging (together with the Current one on Cuts, they uncouple the AI and TI problems in the linked-flux formulation)
|
|
549
|
+
//{Region filamentBnd_1_1 ; Type Assign ; Value 1. ;} // Put just one to non-zero voltage to see a non-trivial solution
|
|
550
|
+
//{Region BndFilaments ; Type Assign ; Value 0. ;} // All the other ones are forced to be zero
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
{ Name Current_Cir ; Case {} } //
|
|
554
|
+
{ Name Voltage_Cir ; Case {} } //
|
|
555
|
+
|
|
556
|
+
{ Name v_plane ;
|
|
557
|
+
Case {
|
|
558
|
+
// {Region filamentBnd_1_1 ; Type Assign ; Value 1. ;}
|
|
559
|
+
// {Region BndFilaments ; Type Assign ; Value 0. ;}
|
|
560
|
+
{Region MatrixPointOnBoundary ; Type Assign ; Value 0. ;}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
565
|
+
// As only the curl of the field is projected, the absolute value is unknown. We need to symmetrize the field
|
|
566
|
+
{ Name hp_static ;
|
|
567
|
+
Case {
|
|
568
|
+
// {Region CenterPoint ; Value 0.0 ;} // replaced by a Lagrange multiplier in the formulation (more general, as there might be a filament at the center!)
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
{% endif %}
|
|
572
|
+
|
|
573
|
+
// This is the key constraint for coupling global quantities: it contains the links between the filaments
|
|
574
|
+
{Name ElectricalCircuit ; Type Network ;
|
|
575
|
+
Case circuit {
|
|
576
|
+
{% if len(rm.powered.Filaments.vol.numbers) % 6 == 1 %}
|
|
577
|
+
// A filament in the center is treated separately.
|
|
578
|
+
{ Region Cut_0_0 ; Branch { 0, 0 } ; }
|
|
579
|
+
{ Region filamentBnd_0_0 ; Branch {1000, 0} ; }
|
|
580
|
+
{% endif %}
|
|
581
|
+
|
|
582
|
+
{% if dm.magnet.solve.formulation_parameters.two_ell_periodicity %}
|
|
583
|
+
{% for layer in range(1, int( len(rm.powered.Filaments.vol.numbers)/6 ) + 1) %}
|
|
584
|
+
{% for filament in range(1, 4) %}
|
|
585
|
+
{ Region Cut_<<layer>>_<<2*filament>> ; Branch { <<100*layer + 2*filament-1>>, <<100*layer + (2*filament+1)%6>> } ; }
|
|
586
|
+
{ Region Cut_<<layer>>_<<(2*filament+1)%6>> ; Branch { <<100*layer + 2*filament>>, <<100*layer + (2*filament+1)%6+1>> } ; }
|
|
587
|
+
|
|
588
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
589
|
+
{ Region R_diffusion_barrier_<<layer>>_<<2*filament-1>> ; Branch { 1000, <<100*layer + 2*filament-1 + 10>>} ; }
|
|
590
|
+
{ Region filamentBnd_<<layer>>_<<2*filament-1>> ; Branch {<<100*layer + 2*filament-1 + 10>>, <<100*layer + 2*filament-1>>} ; }
|
|
591
|
+
|
|
592
|
+
{ Region R_diffusion_barrier_<<layer>>_<<2*filament>> ; Branch { 1000, <<100*layer + 2*filament + 10>>} ; }
|
|
593
|
+
{ Region filamentBnd_<<layer>>_<<2*filament>> ; Branch {<<100*layer + 2*filament + 10>>, <<100*layer + 2*filament>>} ; }
|
|
594
|
+
{% else %}
|
|
595
|
+
{ Region filamentBnd_<<layer>>_<<2*filament-1>> ; Branch {1000, <<100*layer + 2*filament-1>>} ; }
|
|
596
|
+
{ Region filamentBnd_<<layer>>_<<2*filament>> ; Branch {1000, <<100*layer + 2*filament>>} ; }
|
|
597
|
+
{% endif %}
|
|
598
|
+
{%endfor%}
|
|
599
|
+
{%endfor%}
|
|
600
|
+
|
|
601
|
+
{% else %}
|
|
602
|
+
{% for layer in range(1, int( len(rm.powered.Filaments.vol.numbers)/6 ) + 1) %}
|
|
603
|
+
{% for filament in range(1, 7) %}
|
|
604
|
+
{ Region Cut_<<layer>>_<<filament>> ; Branch { <<100*layer + filament>>, <<100*layer + filament%6+1>> } ; }
|
|
605
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
606
|
+
{ Region R_diffusion_barrier_<<layer>>_<<filament>> ; Branch { 1000, <<100*layer + filament + 10>>} ; }
|
|
607
|
+
{ Region filamentBnd_<<layer>>_<<filament>> ; Branch {<<100*layer + filament + 10>>, <<100*layer + filament>>} ; }
|
|
608
|
+
{% else %}
|
|
609
|
+
{ Region filamentBnd_<<layer>>_<<filament>> ; Branch {1000, <<100*layer + filament>>} ; }
|
|
610
|
+
{% endif %}
|
|
611
|
+
{%endfor%}
|
|
612
|
+
{%endfor%}
|
|
613
|
+
{% endif %}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
{ Name h ; Type Assign ;
|
|
617
|
+
Case {
|
|
618
|
+
{% if dm.magnet.solve.initial_conditions.init_type != 'virgin' %}
|
|
619
|
+
{Region OmegaC ; Type InitFromResolution ; NameOfResolution Projection_h_to_h ;}
|
|
620
|
+
{% endif %}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
FunctionSpace {
|
|
627
|
+
// Function space for magnetic field h in h-conform formulation. Main field for the magnetodynamic problem.
|
|
628
|
+
// h = sum phi_n * grad(psi_n) (nodes in Omega_CC with boundary)
|
|
629
|
+
// + sum h_e * psi_e (edges in Omega_C)
|
|
630
|
+
// + sum I_i * c_i (filament cuts - homology gmsh)
|
|
631
|
+
// + sum I_i2 * c_i2 (air cuts - manually computed)
|
|
632
|
+
{ Name h_space; Type Form1;
|
|
633
|
+
BasisFunction {
|
|
634
|
+
{ Name gradpsin; NameOfCoef phin; Function BF_GradNode;
|
|
635
|
+
Support OmegaCC_AndBnd; Entity NodesOf[OmegaCC]; } // Extend support to boundary for surface integration (e.g. useful for weak B.C.)
|
|
636
|
+
{ Name gradpsin; NameOfCoef phin2; Function BF_GroupOfEdges;
|
|
637
|
+
Support OmegaC; Entity GroupsOfEdgesOnNodesOf[BndOmegaC]; } // To treat properly the Omega_CC-Omega_C boundary
|
|
638
|
+
{ Name psie; NameOfCoef he; Function BF_Edge;
|
|
639
|
+
Support OmegaC_AndBnd; Entity EdgesOf[All, Not BndOmegaC]; }
|
|
640
|
+
{ Name ci; NameOfCoef Ii; Function BF_GroupOfEdges;
|
|
641
|
+
Support Omega; Entity GroupsOfEdgesOf[Cuts]; } // The region Cuts contains the union of all the relevant cuts (cohomology basis function support)
|
|
642
|
+
{ Name ct; NameOfCoef It; Function BF_GroupOfEdges;
|
|
643
|
+
Support Omega; Entity GroupsOfEdgesOf[BndMatrixCut]; } // The region Cuts contains the union of all the relevant cuts (cohomology basis function support)
|
|
644
|
+
{% if dm.magnet.geometry.type == 'periodic_square' %}
|
|
645
|
+
{ Name ci2; NameOfCoef Ii2; Function BF_GradGroupOfNodes;
|
|
646
|
+
Support ElementsOf[OmegaCC, OnPositiveSideOf CutAirHorizontal];
|
|
647
|
+
Entity GroupsOfNodesOf[CutAirHorizontal]; }
|
|
648
|
+
{ Name ci2; NameOfCoef Ii3; Function BF_GroupOfEdges;
|
|
649
|
+
Support OmegaC; Entity GroupsOfEdgesOf[CutAirHorizontal, InSupport CutAirHorizontalTL]; }
|
|
650
|
+
{ Name ci3; NameOfCoef Ii4; Function BF_GradGroupOfNodes;
|
|
651
|
+
Support ElementsOf[OmegaCC, OnPositiveSideOf CutAirVertical];
|
|
652
|
+
Entity GroupsOfNodesOf[CutAirVertical]; }
|
|
653
|
+
{ Name ci3; NameOfCoef Ii5; Function BF_GroupOfEdges;
|
|
654
|
+
Support OmegaC; Entity GroupsOfEdgesOf[CutAirVertical, InSupport CutAirVerticalTL]; }
|
|
655
|
+
{% endif %}
|
|
656
|
+
}
|
|
657
|
+
GlobalQuantity {
|
|
658
|
+
{ Name I ; Type AliasOf ; NameOfCoef Ii ; }
|
|
659
|
+
{ Name V ; Type AssociatedWith ; NameOfCoef Ii ; }
|
|
660
|
+
{ Name It ; Type AliasOf ; NameOfCoef It ; }
|
|
661
|
+
{ Name Vt ; Type AssociatedWith ; NameOfCoef It ; }
|
|
662
|
+
{% if dm.magnet.geometry.type == 'periodic_square'%}
|
|
663
|
+
{ Name CirculationHorizontal ; Type AliasOf ; NameOfCoef Ii2 ; }
|
|
664
|
+
{ Name FluxChangeHorizontal ; Type AssociatedWith ; NameOfCoef Ii2 ; }
|
|
665
|
+
{ Name CirculationVertical ; Type AliasOf ; NameOfCoef Ii4 ; }
|
|
666
|
+
{ Name FluxChangeVertical ; Type AssociatedWith ; NameOfCoef Ii4 ; }
|
|
667
|
+
{% endif %}
|
|
668
|
+
}
|
|
669
|
+
SubSpace {
|
|
670
|
+
{ Name c ; NameOfBasisFunction ct ; }
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
Constraint {
|
|
674
|
+
{ NameOfCoef he; EntityType EdgesOf; NameOfConstraint h; }
|
|
675
|
+
{ NameOfCoef phin; EntityType NodesOf; NameOfConstraint phi; }
|
|
676
|
+
{ NameOfCoef phin2; EntityType NodesOf; NameOfConstraint phi; }
|
|
677
|
+
{ NameOfCoef Ii ;
|
|
678
|
+
EntityType GroupsOfEdgesOf ; NameOfConstraint Current ; }
|
|
679
|
+
{ NameOfCoef It ;
|
|
680
|
+
EntityType GroupsOfEdgesOf ; NameOfConstraint Current_t ; }
|
|
681
|
+
{% if dm.magnet.geometry.type == 'periodic_square' %}
|
|
682
|
+
{ NameOfCoef Ii2 ;
|
|
683
|
+
EntityType GroupsOfNodesOf ; NameOfConstraint FieldCirculation ; }
|
|
684
|
+
{ NameOfCoef FluxChangeHorizontal ;
|
|
685
|
+
EntityType GroupsOfNodesOf ; NameOfConstraint FluxChange ; }
|
|
686
|
+
{ NameOfCoef Ii4 ;
|
|
687
|
+
EntityType GroupsOfNodesOf ; NameOfConstraint FieldCirculation ; }
|
|
688
|
+
{ NameOfCoef FluxChangeVertical ;
|
|
689
|
+
EntityType GroupsOfNodesOf ; NameOfConstraint FluxChange ; }
|
|
690
|
+
{% endif %}
|
|
691
|
+
{ NameOfCoef V ;
|
|
692
|
+
EntityType GroupsOfNodesOf ; NameOfConstraint Voltage ; }
|
|
693
|
+
{ NameOfCoef Vt ;
|
|
694
|
+
EntityType GroupsOfNodesOf ; NameOfConstraint Voltage_t ; }
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
// Function space for the transverse problem voltage field. Main field for the electrokinetics problem.
|
|
698
|
+
// The (transverse) coupling current derive from this voltage j_coupling = - sigma * grad(v).
|
|
699
|
+
{ Name v_space_elKin ; Type Form0 ;
|
|
700
|
+
BasisFunction {
|
|
701
|
+
{ Name vn ; NameOfCoef vn ; Function BF_Node ;
|
|
702
|
+
Support Matrix_partitions_for_TI ; Entity NodesOf[All, Not BndFilaments] ; }
|
|
703
|
+
{ Name vi; NameOfCoef vi; Function BF_GroupOfNodes;
|
|
704
|
+
Support Matrix_partitions_for_TI; Entity GroupsOfNodesOf[BndFilaments]; }
|
|
705
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
706
|
+
{ Name vd ; NameOfCoef vd ; Function BF_Node ;
|
|
707
|
+
Support MatrixInternalSurface ; Entity NodesOf[GlobalDiffusionBarrier] ; }
|
|
708
|
+
{ Name vd ; NameOfCoef vd2 ; Function BF_Node ;
|
|
709
|
+
Support GlobalDiffusionBarrier ; Entity NodesOf[GlobalDiffusionBarrier] ; } // Only the discontinuous contribution must be defined on the global diffusion barrier, and nothing else (the formulation relies on this).
|
|
710
|
+
{% endif %}
|
|
711
|
+
}
|
|
712
|
+
GlobalQuantity {
|
|
713
|
+
{ Name V ; Type AliasOf ; NameOfCoef vi ; }
|
|
714
|
+
{ Name I ; Type AssociatedWith ; NameOfCoef vi ; }
|
|
715
|
+
}
|
|
716
|
+
Constraint {
|
|
717
|
+
{ NameOfCoef vn ; EntityType NodesOf ; NameOfConstraint v_plane ; }
|
|
718
|
+
{ NameOfCoef V ;
|
|
719
|
+
EntityType Region ; NameOfConstraint Voltage_plane ; }
|
|
720
|
+
{ NameOfCoef I ;
|
|
721
|
+
EntityType Region ; NameOfConstraint Current_plane ; }
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
725
|
+
// The curl of this space is the projection of the coupling current on this subspace (no net current from fil.)
|
|
726
|
+
{ Name h_perp_space_static; Type Form1P;
|
|
727
|
+
BasisFunction {
|
|
728
|
+
{ Name sn; NameOfCoef hn; Function BF_PerpendicularEdge;
|
|
729
|
+
Support Matrix_partitions_for_TI; Entity NodesOf[All]; }
|
|
730
|
+
}
|
|
731
|
+
Constraint {
|
|
732
|
+
{ NameOfCoef hn; EntityType NodesOf; NameOfConstraint hp_static; }
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
// This is a Lagrange multplier for forcing the integral of hp_static to be zero in the matrix (avg field = 0)
|
|
736
|
+
{ Name h_perp_space_static_lagrange; Type Vector;
|
|
737
|
+
BasisFunction {
|
|
738
|
+
{ Name sn_lag; NameOfCoef hn_lag; Function BF_RegionZ;
|
|
739
|
+
Support Matrix_partitions_for_TI; Entity Matrix_partitions_for_TI; } // Ideally, should be only one function (not one per matrix part). To be double-checked!
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
// This space will correct the static space above with dynamic effects
|
|
743
|
+
{ Name h_perp_space_dynamic; Type Form1P;
|
|
744
|
+
BasisFunction {
|
|
745
|
+
{ Name sn; NameOfCoef hn; Function BF_PerpendicularEdge;
|
|
746
|
+
Support Matrix_partitions_for_TI; Entity NodesOf[All, Not TI_adjacent_region ]; }
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
{% endif %}
|
|
750
|
+
|
|
751
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
752
|
+
// Function space for the circuit domain
|
|
753
|
+
{ Name ElectricalCircuit; Type Scalar;
|
|
754
|
+
BasisFunction {
|
|
755
|
+
{ Name sn; NameOfCoef Ir; Function BF_Region;
|
|
756
|
+
Support Resistors_diffusion_barrier; Entity Resistors_diffusion_barrier; }
|
|
757
|
+
}
|
|
758
|
+
GlobalQuantity {
|
|
759
|
+
{ Name Iz ; Type AliasOf ; NameOfCoef Ir ; }
|
|
760
|
+
{ Name Vz ; Type AssociatedWith ; NameOfCoef Ir ; }
|
|
761
|
+
}
|
|
762
|
+
Constraint {
|
|
763
|
+
{ NameOfCoef Iz ; EntityType Region ; NameOfConstraint Current_Cir ; }
|
|
764
|
+
{ NameOfCoef Vz ; EntityType Region ; NameOfConstraint Voltage_Cir ; }
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
{% endif %}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
Jacobian {
|
|
771
|
+
{ Name Vol ;
|
|
772
|
+
Case {
|
|
773
|
+
{Region All ; Jacobian Vol ;}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
{ Name Sur ;
|
|
777
|
+
Case {
|
|
778
|
+
{ Region All ; Jacobian Sur ; }
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
Integration {
|
|
784
|
+
{ Name Int ;
|
|
785
|
+
Case {
|
|
786
|
+
{ Type Gauss ;
|
|
787
|
+
Case {
|
|
788
|
+
{ GeoElement Point ; NumberOfPoints 1 ; }
|
|
789
|
+
{ GeoElement Line ; NumberOfPoints 3 ; }
|
|
790
|
+
{ GeoElement Triangle ; NumberOfPoints 3 ; }
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
Formulation{
|
|
798
|
+
// h-formulation
|
|
799
|
+
{ Name MagDyn_hphi; Type FemEquation;
|
|
800
|
+
Quantity {
|
|
801
|
+
// Functions for the axial current (AI) problem
|
|
802
|
+
{ Name h; Type Local; NameOfSpace h_space; }
|
|
803
|
+
{ Name hp; Type Local; NameOfSpace h_space; }
|
|
804
|
+
{ Name I; Type Global; NameOfSpace h_space[I]; }
|
|
805
|
+
{ Name V; Type Global; NameOfSpace h_space[V]; }
|
|
806
|
+
{ Name It; Type Global; NameOfSpace h_space[It]; }
|
|
807
|
+
{ Name Vt; Type Global; NameOfSpace h_space[Vt]; }
|
|
808
|
+
{ Name c; Type Local; NameOfSpace h_space[c]; }
|
|
809
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" %}
|
|
810
|
+
// Functions for the transverse current (TI) problem
|
|
811
|
+
{ Name v; Type Local; NameOfSpace v_space_elKin; }
|
|
812
|
+
{ Name Vp; Type Global; NameOfSpace v_space_elKin[V]; }
|
|
813
|
+
{ Name Ip; Type Global; NameOfSpace v_space_elKin[I]; }
|
|
814
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
815
|
+
{ Name Iz; Type Global; NameOfSpace ElectricalCircuit[Iz]; }
|
|
816
|
+
{ Name Vz; Type Global; NameOfSpace ElectricalCircuit[Vz]; }
|
|
817
|
+
{% endif %}
|
|
818
|
+
{% endif %}
|
|
819
|
+
{% if dm.magnet.geometry.type == 'periodic_square' %}
|
|
820
|
+
{ Name CirculationHorizontal; Type Global; NameOfSpace h_space[CirculationHorizontal]; }
|
|
821
|
+
{ Name FluxChangeHorizontal; Type Global; NameOfSpace h_space[FluxChangeHorizontal]; }
|
|
822
|
+
{ Name CirculationVertical; Type Global; NameOfSpace h_space[CirculationVertical]; }
|
|
823
|
+
{ Name FluxChangeVertical; Type Global; NameOfSpace h_space[FluxChangeVertical]; }
|
|
824
|
+
{% endif %}
|
|
825
|
+
}
|
|
826
|
+
Equation {
|
|
827
|
+
// --- AI problem ---
|
|
828
|
+
// Time derivative of b (NonMagnDomain)
|
|
829
|
+
Galerkin { [ ell* mu[] * Dof{h} / $DTime , {h} ];
|
|
830
|
+
In Omega; Integration Int; Jacobian Vol; }
|
|
831
|
+
Galerkin { [ - ell*mu[] * {h}[1] / $DTime , {h} ];
|
|
832
|
+
In Omega; Integration Int; Jacobian Vol; }
|
|
833
|
+
// Induced current (linear OmegaC)
|
|
834
|
+
Galerkin { [ ell*rho[mu0*Norm[{h}]] * Dof{d h} , {d h} ];
|
|
835
|
+
In LinOmegaC; Integration Int; Jacobian Vol; }
|
|
836
|
+
// Induced current (non-linear OmegaC)
|
|
837
|
+
Galerkin { [ ell*rho[{d h}, mu0*Norm[{h}]] * {d h} , {d h} ];
|
|
838
|
+
In NonLinOmegaC; Integration Int; Jacobian Vol; }
|
|
839
|
+
|
|
840
|
+
Galerkin { [ ell*dedj[{d h}, mu0*Norm[{h}]] * Dof{d h} , {d hp} ];
|
|
841
|
+
In NonLinOmegaC; Integration Int; Jacobian Vol; } // For Newton-Raphson method
|
|
842
|
+
Galerkin { [ - ell*dedj[{d h}, mu0*Norm[{h}]] * {d h} , {d hp} ];
|
|
843
|
+
In NonLinOmegaC; Integration Int; Jacobian Vol; } // For Newton-Raphson method
|
|
844
|
+
|
|
845
|
+
{% if 0 and dm.conductors[dm.magnet.solve.conductor_name].Jc_fit.type != 'Constant Jc' and dm.magnet.solve.general_parameters.superconductor_linear == False%}
|
|
846
|
+
// We don't use this N-R for the moment (does not seem to decrease number of iterations, but is expensive for assembly -> to double-check)
|
|
847
|
+
Galerkin { [ ell*dedb[{d h}, mu0*{h}] * mu0*Dof{h} , {d hp} ];
|
|
848
|
+
In NonLinOmegaC; Integration Int; Jacobian Vol; } // For Newton-Raphson method
|
|
849
|
+
Galerkin { [ -ell*dedb[{d h}, mu0*{h}] * mu0*{h} , {d hp} ];
|
|
850
|
+
In NonLinOmegaC; Integration Int; Jacobian Vol; } // For Newton-Raphson method
|
|
851
|
+
{% endif %}
|
|
852
|
+
|
|
853
|
+
// Natural boundary condition for normal flux density (useful when transport current is an essential condition)
|
|
854
|
+
{% if dm.magnet.geometry.type == 'coil' or dm.magnet.geometry.type == 'strand_only'%}
|
|
855
|
+
Galerkin { [ - ell*dbsdt[] * Normal[] , {dInv h} ];
|
|
856
|
+
In BndAir; Integration Int; Jacobian Sur; }
|
|
857
|
+
{% endif %}
|
|
858
|
+
|
|
859
|
+
// Global terms for imposing flux changes
|
|
860
|
+
{% if dm.magnet.geometry.type == 'periodic_square' %}
|
|
861
|
+
GlobalTerm { [ ell*Dof{FluxChangeHorizontal} , {CirculationHorizontal} ] ; In CutAirHorizontal ; }
|
|
862
|
+
GlobalTerm { [ ell*Dof{FluxChangeVertical} , {CirculationVertical} ] ; In CutAirVertical ; }
|
|
863
|
+
{% endif %}
|
|
864
|
+
|
|
865
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" %}
|
|
866
|
+
// --- TI problem ---
|
|
867
|
+
Galerkin { [ ell * sigma[mu0*Norm[{h}]] * Dof{d v} , {d v} ];
|
|
868
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; } // Matrix
|
|
869
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
870
|
+
Galerkin { [ ell * 1/rho_contact[] * Dof{v} , {v} ];
|
|
871
|
+
In GlobalDiffusionBarrier; Integration Int; Jacobian Sur; } // This requires that only the discontinuous component of {v} is defined on the global diffusion barrier
|
|
872
|
+
{% endif %}
|
|
873
|
+
GlobalTerm { [ Dof{Ip} , {Vp} ] ; In BndFilaments ; }
|
|
874
|
+
|
|
875
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
876
|
+
// Diffusion barriers
|
|
877
|
+
GlobalTerm{ [ Dof{Vz}, {Iz} ]; In Resistors_diffusion_barrier; }
|
|
878
|
+
GlobalTerm{ [ R[] * Dof{Iz}, {Iz} ]; In Resistors_diffusion_barrier; }
|
|
879
|
+
// --- Coupling between AI and TI problems via circuit equations ---
|
|
880
|
+
GlobalEquation {
|
|
881
|
+
Type Network ; NameOfConstraint ElectricalCircuit ;
|
|
882
|
+
{ Node {I}; Loop {V}; Equation {V}; In Cuts ; }
|
|
883
|
+
{ Node {Ip}; Loop {Vp}; Equation {Ip}; In BndFilaments ; }
|
|
884
|
+
{ Node {Iz}; Loop {Vz}; Equation {Vz}; In Resistors_diffusion_barrier; }
|
|
885
|
+
}
|
|
886
|
+
{% else %}
|
|
887
|
+
// --- Coupling between AI and TI problems via circuit equations ---
|
|
888
|
+
GlobalEquation {
|
|
889
|
+
Type Network ; NameOfConstraint ElectricalCircuit ;
|
|
890
|
+
{ Node {I}; Loop {V}; Equation {V}; In Cuts ; }
|
|
891
|
+
{ Node {Ip}; Loop {Vp}; Equation {Ip}; In BndFilaments ; }
|
|
892
|
+
}
|
|
893
|
+
{% endif %}
|
|
894
|
+
{% endif %}
|
|
895
|
+
// Global term (these terms apparently must be placed at the end, it is not clear why)
|
|
896
|
+
GlobalTerm { [ Dof{V} , {I} ] ; In Cuts ; }
|
|
897
|
+
GlobalTerm { [ Dof{Vt} , {It} ] ; In BndMatrixCut ; }
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
901
|
+
// h-formulation
|
|
902
|
+
{ Name MagDyn_hphi_dynCorr; Type FemEquation;
|
|
903
|
+
Quantity {
|
|
904
|
+
// Functions for the AI and TI problems, that are just used here (and not solved for)
|
|
905
|
+
{ Name h; Type Local; NameOfSpace h_space; }
|
|
906
|
+
{ Name v; Type Local; NameOfSpace v_space_elKin; }
|
|
907
|
+
// Functions for the dynamic correction of the TI problem
|
|
908
|
+
{ Name hp_static; Type Local; NameOfSpace h_perp_space_static; }
|
|
909
|
+
{ Name hp_static_lagrange; Type Local; NameOfSpace h_perp_space_static_lagrange; }
|
|
910
|
+
{ Name hp_dynamic; Type Local; NameOfSpace h_perp_space_dynamic; }
|
|
911
|
+
}
|
|
912
|
+
Equation {
|
|
913
|
+
// --- Dynamic correction of the TI problem ---
|
|
914
|
+
// Projection of the static current flow on the curl of a "static" magnetic field
|
|
915
|
+
Galerkin { [ sigma[mu0*Norm[{h}]] * {d v} , {d hp_static} ]; // No DOF! Just take the solution of the previously solved v-based formulation
|
|
916
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; }
|
|
917
|
+
Galerkin { [ Dof{d hp_static} , {d hp_static} ];
|
|
918
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; }
|
|
919
|
+
Galerkin { [ Dof{hp_static_lagrange} , {hp_static} ];
|
|
920
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; }
|
|
921
|
+
Galerkin { [ Dof{hp_static} , {hp_static_lagrange} ];
|
|
922
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; } // ensure the magnetic field is averaged to zero over the matrix
|
|
923
|
+
// Introduce a dynamic component to the magnetic field
|
|
924
|
+
Galerkin { [ mu[] * Dof{hp_static} / $DTime , {hp_dynamic} ];
|
|
925
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; }
|
|
926
|
+
Galerkin { [ mu[] * Dof{hp_dynamic} / $DTime , {hp_dynamic} ];
|
|
927
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; }
|
|
928
|
+
Galerkin { [ - mu[] * {hp_static}[1] / $DTime , {hp_dynamic} ];
|
|
929
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; }
|
|
930
|
+
Galerkin { [ - mu[] * {hp_dynamic}[1] / $DTime , {hp_dynamic} ];
|
|
931
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; }
|
|
932
|
+
//Galerkin { [ - Dof{d v} , {d hp_dynamic} ];
|
|
933
|
+
// In Matrix; Integration Int; Jacobian Vol; } // Static field is curl-free so this contribution is unnecessary!
|
|
934
|
+
Galerkin { [ rho[mu0*Norm[{h}]] * Dof{d hp_dynamic} , {d hp_dynamic} ];
|
|
935
|
+
In Matrix_partitions_for_TI; Integration Int; Jacobian Vol; } // Only the dynamic correction is an eddy current
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
{% endif %}
|
|
939
|
+
{% if dm.magnet.solve.initial_conditions.init_type != 'virgin' %}
|
|
940
|
+
// Projection formulation for initial condition
|
|
941
|
+
{ Name Projection_h_to_h; Type FemEquation;
|
|
942
|
+
Quantity {
|
|
943
|
+
{ Name h; Type Local; NameOfSpace h_space; }
|
|
944
|
+
}
|
|
945
|
+
Equation{
|
|
946
|
+
// For the current formulation, it seems to be accurate enough to project the field directly (and not its curl as an intermediate to reconstruct it).
|
|
947
|
+
// Validity of this to be checked again if we go to different meshes between the initial condition and the following simulation
|
|
948
|
+
Galerkin { [ Dof{h}, {h} ] ;
|
|
949
|
+
In Omega ; Jacobian Vol ; Integration Int ; }
|
|
950
|
+
{% if dm.magnet.solve.initial_conditions.init_type == 'pos_file' %}
|
|
951
|
+
Galerkin { [ - h_from_file[], {h} ] ;
|
|
952
|
+
In Omega ; Jacobian Vol ; Integration Int ; }
|
|
953
|
+
{% elif dm.magnet.solve.initial_conditions.init_type == 'uniform_field' %}
|
|
954
|
+
Galerkin { [ - hsVal[], {h} ] ;
|
|
955
|
+
In Omega ; Jacobian Vol ; Integration Int ; }
|
|
956
|
+
{% endif %}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
{% endif %}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
Macro CustomIterativeLoop
|
|
963
|
+
// Compute first solution guess and residual at step $TimeStep
|
|
964
|
+
Generate[A];
|
|
965
|
+
Solve[A]; Evaluate[ $syscount = $syscount + 1 ];
|
|
966
|
+
Generate[A]; GetResidual[A, $res0];
|
|
967
|
+
Evaluate[ $res = $res0 ];
|
|
968
|
+
Evaluate[ $iter = 0 ];
|
|
969
|
+
Evaluate[ $convCrit = 1e99 ];
|
|
970
|
+
PostOperation[MagDyn_energy];
|
|
971
|
+
Print[{$iter, $res, $res / $res0, $indicFilamentLoss},
|
|
972
|
+
Format "%g %14.12e %14.12e %14.12e", File infoResidualFile];
|
|
973
|
+
// ----- Enter the iterative loop (hand-made) -----
|
|
974
|
+
While[$convCrit > 1 && $res / $res0 <= 1e10 && $iter < iter_max]{
|
|
975
|
+
Solve[A]; Evaluate[ $syscount = $syscount + 1 ];
|
|
976
|
+
Generate[A]; GetResidual[A, $res];
|
|
977
|
+
Evaluate[ $iter = $iter + 1 ];
|
|
978
|
+
Evaluate[ $indicFilamentLossOld = $indicFilamentLoss];
|
|
979
|
+
PostOperation[MagDyn_energy];
|
|
980
|
+
Print[{$iter, $res, $res / $res0, $indicFilamentLoss},
|
|
981
|
+
Format "%g %14.12e %14.12e %14.12e", File infoResidualFile];
|
|
982
|
+
// Evaluate the convergence indicator
|
|
983
|
+
Evaluate[ $relChangeACLoss = Abs[($indicFilamentLossOld - $indicFilamentLoss)/((Abs[$indicFilamentLossOld]>1e-7 || $iter < 10) ? $indicFilamentLossOld:1e-7)] ];
|
|
984
|
+
Evaluate[ $convCrit = $relChangeACLoss/tol_energy];
|
|
985
|
+
}
|
|
986
|
+
Return
|
|
987
|
+
|
|
988
|
+
Resolution {
|
|
989
|
+
{ Name MagDyn;
|
|
990
|
+
System {
|
|
991
|
+
{Name A; NameOfFormulation MagDyn_hphi;}
|
|
992
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
993
|
+
{Name A_dynCorr; NameOfFormulation MagDyn_hphi_dynCorr;}
|
|
994
|
+
{% endif %}
|
|
995
|
+
}
|
|
996
|
+
Operation {
|
|
997
|
+
// Initialize directories
|
|
998
|
+
CreateDirectory[resDirectory];
|
|
999
|
+
DeleteFile[outputPower];
|
|
1000
|
+
DeleteFile[infoResidualFile];
|
|
1001
|
+
// Initialize the solution (initial condition)
|
|
1002
|
+
SetTime[ timeStart ];
|
|
1003
|
+
SetDTime[ dt ];
|
|
1004
|
+
SetTimeStep[ 0 ];
|
|
1005
|
+
InitSolution[A];
|
|
1006
|
+
SaveSolution[A]; // Saves the solution x (from Ax = B) to .res file
|
|
1007
|
+
Evaluate[ $syscount = 0 ];
|
|
1008
|
+
Evaluate[ $saved = 1 ];
|
|
1009
|
+
Evaluate[ $elapsedCTI = 1 ]; // Number of control time instants already treated
|
|
1010
|
+
Evaluate[ $isCTI = 0 ];
|
|
1011
|
+
|
|
1012
|
+
{% if dm.magnet.solve.formulation_parameters.compute_temperature %}
|
|
1013
|
+
Evaluate[ $cumulative_temperature = 0 ];
|
|
1014
|
+
Evaluate[ $dT_old = 0 ];
|
|
1015
|
+
{% endif %}
|
|
1016
|
+
|
|
1017
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
1018
|
+
InitSolution[A_dynCorr];
|
|
1019
|
+
SaveSolution[A_dynCorr];
|
|
1020
|
+
{% else %}
|
|
1021
|
+
Evaluate[ $indicTotalLoss_dyn = 0 ]; // Put it to zero to avoid warnings
|
|
1022
|
+
Evaluate[ $indicCouplingLoss_dyn = 0 ]; // Put it to zero to avoid warnings
|
|
1023
|
+
{% if dm.magnet.solve.formulation_parameters.formulation != "CATI" %}
|
|
1024
|
+
Evaluate[ $indicCouplingLoss = 0 ]; // For conventional 2D formulation, no coupling currents and hence no coupling loss
|
|
1025
|
+
{% endif %}
|
|
1026
|
+
{% endif %}
|
|
1027
|
+
// ----- Enter implicit Euler time integration loop (hand-made) -----
|
|
1028
|
+
// Avoid too close steps at the end. Stop the simulation if the step becomes ridiculously small
|
|
1029
|
+
SetExtrapolationOrder[ extrapolationOrder ];
|
|
1030
|
+
While[$Time < timeFinal] {
|
|
1031
|
+
SetTime[ $Time + $DTime ]; // Time instant at which we are looking for the solution
|
|
1032
|
+
SetTimeStep[ $TimeStep + 1 ];
|
|
1033
|
+
{% if dm.magnet.solve.numerical_parameters.piecewise.force_stepping_at_times_piecewise_linear and dm.magnet.solve.source_parameters.source_type == 'piecewise'%}
|
|
1034
|
+
// Make sure all CTI are exactly chosen
|
|
1035
|
+
Evaluate[ $isCTI = 0 ];
|
|
1036
|
+
Test[$Time >= time_multiplier*AtIndex[$elapsedCTI]{List[control_time_instants_list]} - 1e-7 ]{
|
|
1037
|
+
Evaluate[ $isCTI = 1, $prevDTime = $DTime ]; // Also save the previous time step to restart from it after the CTI
|
|
1038
|
+
SetDTime[ time_multiplier*AtIndex[$elapsedCTI]{List[control_time_instants_list]} - $Time + $DTime ];
|
|
1039
|
+
SetTime[ time_multiplier*AtIndex[$elapsedCTI]{List[control_time_instants_list]} ]; // To compute exactly at the asked time instant
|
|
1040
|
+
Print[{$Time}, Format "*** Control time instant: %g s."];
|
|
1041
|
+
}
|
|
1042
|
+
{% endif %}
|
|
1043
|
+
// Iterative loop defined as a macro above
|
|
1044
|
+
Print[{$Time, $DTime, $TimeStep}, Format "Start new time step. Time: %g s. Time step: %g s. Step: %g."];
|
|
1045
|
+
Call CustomIterativeLoop;
|
|
1046
|
+
// Has it converged? If yes, save solution and possibly increase the time step...
|
|
1047
|
+
Test[ $iter < iter_max && ($res / $res0 <= 1e10 || $res0 == 0)]{
|
|
1048
|
+
Print[{$Time, $DTime, $iter}, Format "Converged time %g s with time step %g s in %g iterations."];
|
|
1049
|
+
// Save the solution of few time steps (small correction to avoid bad rounding)
|
|
1050
|
+
// Test[ $Time >= $saved * writeInterval - 1e-7 || $Time + $DTime >= timeFinal]{
|
|
1051
|
+
Test[ 1 ]{
|
|
1052
|
+
// Test[ $Time >= $saved * $DTime - 1e-7 || $Time + $DTime >= timeFinal]{
|
|
1053
|
+
SaveSolution[A];
|
|
1054
|
+
// Post-operation for power loss quantities
|
|
1055
|
+
PostOperation[test_Losses];
|
|
1056
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
1057
|
+
Generate[A_dynCorr]; Solve[A_dynCorr]; SaveSolution[A_dynCorr];
|
|
1058
|
+
PostOperation[test_Losses_dynCorr];
|
|
1059
|
+
{% endif %}
|
|
1060
|
+
Print[{$Time, $saved}, Format "Saved time %g s (saved solution number %g). Output power infos:"];
|
|
1061
|
+
Print[{$Time, $indicFilamentLoss, $indicCouplingLoss, $indicEddyLoss, $indicTotalLoss, $indicCouplingLoss_dyn, $indicTotalLoss_dyn},
|
|
1062
|
+
Format "%g %14.12e %14.12e %14.12e %14.12e %14.12e %14.12e", File outputPower];
|
|
1063
|
+
|
|
1064
|
+
// Compute the temperature
|
|
1065
|
+
{% if dm.magnet.solve.formulation_parameters.compute_temperature == True %}
|
|
1066
|
+
PostOperation[heat_capacity];
|
|
1067
|
+
Evaluate[$dT = $DTime * $indicTotalLoss/$heat_capacity_per_unit_length];
|
|
1068
|
+
Evaluate[ $cumulative_temperature = $cumulative_temperature + ($dT_old + $dT)/2 ];
|
|
1069
|
+
Print[{$Time, $dT, $cumulative_temperature}, Format "%g %14.12e %14.12e", File outputTemperature];
|
|
1070
|
+
Evaluate[ $dT_old = $dT ];
|
|
1071
|
+
{% endif %}
|
|
1072
|
+
|
|
1073
|
+
Evaluate[$saved = $saved + 1];
|
|
1074
|
+
}
|
|
1075
|
+
{% if dm.magnet.solve.numerical_parameters.piecewise.force_stepping_at_times_piecewise_linear and dm.magnet.solve.source_parameters.source_type == 'piecewise' %}
|
|
1076
|
+
// Consider the time step before the control time instant (if relevant) and increment $elapsedCTI
|
|
1077
|
+
Test[ $isCTI == 1 ]{
|
|
1078
|
+
Evaluate[ $elapsedCTI = $elapsedCTI + 1 ];
|
|
1079
|
+
SetDTime[ $prevDTime ];
|
|
1080
|
+
}
|
|
1081
|
+
{% endif %}
|
|
1082
|
+
// Increase the step if we converged sufficiently "fast" (and not a control time instant)
|
|
1083
|
+
Test[ $iter < iter_max / 4 && $DTime < dt_max_var[] && $isCTI == 0 ]{
|
|
1084
|
+
Evaluate[ $dt_new = Min[$DTime * 2, dt_max_var[]] ];
|
|
1085
|
+
Print[{$dt_new}, Format "*** Fast convergence: increasing time step to %g"];
|
|
1086
|
+
SetDTime[$dt_new];
|
|
1087
|
+
}
|
|
1088
|
+
Test[ $DTime > dt_max_var[]]{
|
|
1089
|
+
Evaluate[ $dt_new = dt_max_var[] ];
|
|
1090
|
+
Print[{$dt_new}, Format "*** Variable maximum time-stepping: reducing time step to %g"];
|
|
1091
|
+
SetDTime[$dt_new];
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
// ...otherwise, reduce the time step and try again
|
|
1095
|
+
{
|
|
1096
|
+
Evaluate[ $dt_new = $DTime / 2 ];
|
|
1097
|
+
Print[{$iter, $dt_new},
|
|
1098
|
+
Format "*** Non convergence (iter %g): recomputing with reduced step %g"];
|
|
1099
|
+
RemoveLastSolution[A];
|
|
1100
|
+
SetTime[$Time - $DTime];
|
|
1101
|
+
SetTimeStep[$TimeStep - 1];
|
|
1102
|
+
SetDTime[$dt_new];
|
|
1103
|
+
// If it gets ridicoulously small, end the simulation, and report the information in crash file.
|
|
1104
|
+
Test[ $dt_new < dt_max_var[]/1000000 ]{
|
|
1105
|
+
Print[{$iter, $dt_new, $Time},
|
|
1106
|
+
Format "*** Non convergence (iter %g): time step %g too small, stopping the simulation at time %g s.", File crashReportFile];
|
|
1107
|
+
// Print[A];
|
|
1108
|
+
Exit;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
} // ----- End time loop -----
|
|
1112
|
+
// Print information about the resolution and the nonlinear iterations
|
|
1113
|
+
Print[{$syscount}, Format "Total number of linear systems solved: %g"];
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
{% if dm.magnet.solve.initial_conditions.init_type != 'virgin' %}
|
|
1117
|
+
{ Name Projection_h_to_h;
|
|
1118
|
+
System {
|
|
1119
|
+
{Name Projection_h_to_h; NameOfFormulation Projection_h_to_h; DestinationSystem A ;}
|
|
1120
|
+
}
|
|
1121
|
+
Operation {
|
|
1122
|
+
{% if dm.magnet.solve.initial_conditions.init_type == 'pos_file' %}
|
|
1123
|
+
GmshRead[StrCat["../", "Solution_<<dm.magnet.solve.initial_conditions.solution_to_init_from>>/", "last_magnetic_field.pos"]]; // This file has to be in format without mesh (no -v2, here with GmshParsed format)
|
|
1124
|
+
{% endif %}
|
|
1125
|
+
Generate[Projection_h_to_h]; Solve[Projection_h_to_h];
|
|
1126
|
+
TransferSolution[Projection_h_to_h];
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
{% endif %}
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
PostProcessing {
|
|
1133
|
+
{ Name MagDyn_hphi; NameOfFormulation MagDyn_hphi;
|
|
1134
|
+
Quantity {
|
|
1135
|
+
{ Name phi; Value{ Local{ [ {dInv h} ] ;
|
|
1136
|
+
In OmegaCC_AndBnd; Jacobian Vol; } } }
|
|
1137
|
+
{ Name h; Value{ Local{ [ {h} ] ;
|
|
1138
|
+
In Omega; Jacobian Vol; } } }
|
|
1139
|
+
{ Name b; Value{ Local{ [ mu[] * {h} ] ;
|
|
1140
|
+
In Omega; Jacobian Vol; } } }
|
|
1141
|
+
{ Name b_reaction; Value{ Local{ [ mu[] * ({h} - hsVal[]) ] ;
|
|
1142
|
+
In Omega; Jacobian Vol; } } }
|
|
1143
|
+
{ Name j; Value{ Local{ [ {d h} ] ;
|
|
1144
|
+
In OmegaC; Jacobian Vol; } } }
|
|
1145
|
+
{ Name jz; Value{ Local{ [ {d h} * Vector[0,0,1]] ;
|
|
1146
|
+
In OmegaC; Jacobian Vol; } } }
|
|
1147
|
+
{ Name jc; Value{ Local{ [ jc[mu0*Norm[{h}]] ] ;
|
|
1148
|
+
In NonLinOmegaC; Jacobian Vol; } } }
|
|
1149
|
+
{ Name rho; Value{ Local{ [ rho_power[{d h}, mu0*Norm[{h}]] ] ;
|
|
1150
|
+
In NonLinOmegaC; Jacobian Vol; } } }
|
|
1151
|
+
{ Name power_filaments; Value{ Local{ [ rho[{d h}, mu0*Norm[{h}]] * {d h} * {d h} ] ; // j*e : Power (only for filaments)
|
|
1152
|
+
In NonLinOmegaC; Jacobian Vol; } } }
|
|
1153
|
+
{ Name selffield_dfluxdt; Value{ Integral{ [ CompZ[rho[{d h}, mu0*Norm[{h}]] * {d h}] ] ;
|
|
1154
|
+
In OmegaC; Integration Int; Jacobian Vol; } } }
|
|
1155
|
+
{ Name sigma_matrix; Value{ Local{ [ sigma[mu0*Norm[{h}]]] ;
|
|
1156
|
+
In Matrix; Jacobian Vol; } } }
|
|
1157
|
+
{ Name flux_external; Value{ Integral{ [ (mu[] * {h} * {c} / I_transport[]) ] ;
|
|
1158
|
+
In OmegaCC; Integration Int ; Jacobian Vol; } } }
|
|
1159
|
+
{ Name flux_internal; Value{ Integral{ [ mu[] * {h} * (UnitVectorZ[] /\ XYZ[]/Norm[XYZ[]]) / (2 * Pi * Norm[XYZ[]]) ] ;
|
|
1160
|
+
In OmegaC; Integration Int; Jacobian Vol; } } }
|
|
1161
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" %}
|
|
1162
|
+
// TI model quantities
|
|
1163
|
+
{ Name j_plane; Value{ Local{ [ -1/rho[mu0*Norm[{h}]] * {d v} ] ;
|
|
1164
|
+
In Matrix; Jacobian Vol; } } }
|
|
1165
|
+
{ Name v_plane; Value{ Local{ [ {v} ] ;
|
|
1166
|
+
In Matrix; Jacobian Vol; } } }
|
|
1167
|
+
{ Name Ip; Value { Term{ [ {Ip} ] ; In BndFilaments; } } }
|
|
1168
|
+
{ Name Vp; Value { Term{ [ {Vp} ] ; In BndFilaments; } } }
|
|
1169
|
+
{ Name power_matrix;
|
|
1170
|
+
Value{
|
|
1171
|
+
Local{ [rho[mu0*Norm[{h}]] * {d h} * {d h}] ; // j*e = rho*j^2 in matrix (eddy)
|
|
1172
|
+
In Matrix ; Integration Int ; Jacobian Vol; }
|
|
1173
|
+
Local{ [ (sigma[mu0*Norm[{h}]] * {d v}) * {d v}] ; // j*e = sigma*e^2 in matrix (coupling)
|
|
1174
|
+
In Matrix ; Integration Int ; Jacobian Vol; }
|
|
1175
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
1176
|
+
Local { [ 1/rho_contact[] * {v} * {v} ];
|
|
1177
|
+
In GlobalDiffusionBarrier; Integration Int; Jacobian Sur; } // This requires that only the discontinuous component of {v} is defined on the diffusion barrier
|
|
1178
|
+
{% endif %}
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
{ Name couplingLoss; // Does not include (global) contribution from possible diffusion barriers around filaments
|
|
1182
|
+
Value{
|
|
1183
|
+
Integral{ [ (sigma[mu0*Norm[{h}]] * {d v}) * {d v}] ; // j*e = sigma*e^2 in matrix
|
|
1184
|
+
In Matrix ; Integration Int ; Jacobian Vol; }
|
|
1185
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
1186
|
+
Integral { [ 1/rho_contact[] * {v} * {v} ];
|
|
1187
|
+
In GlobalDiffusionBarrier; Integration Int; Jacobian Sur; } // This requires that only the discontinuous component of {v} is defined on the diffusion barrier
|
|
1188
|
+
{% endif %}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
{% if dm.magnet.solve.diffusion_barriers.enable %}
|
|
1192
|
+
{ Name diffusion_barrier_loss; // Loss per unit length (W/m)
|
|
1193
|
+
Value{
|
|
1194
|
+
Term{ [ 1/ell * R[] * {Iz} * {Iz}] ; // P = 1/ell * R*I^2 in diffusion barriers
|
|
1195
|
+
In Resistors_diffusion_barrier ; }
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
{% endif %}
|
|
1199
|
+
{% endif %}
|
|
1200
|
+
{ Name eddyLoss; // NEW. Eddyloss was computed as totalLoss[matrix], which combines eddy and couplingLoss
|
|
1201
|
+
Value{
|
|
1202
|
+
Integral{ [rho[mu0*Norm[{h}]] * {d h} * {d h}] ; // EddyLoss = rho*j^2 in matrix
|
|
1203
|
+
In Matrix ; Integration Int ; Jacobian Vol; }
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
{ Name totalLoss; // Does not include (global) contribution from possible diffusion barriers around filaments
|
|
1207
|
+
Value{
|
|
1208
|
+
// Separate OmegaC into Matrix and nonlinear (resistivities take different argument types)
|
|
1209
|
+
Integral{ [rho[{d h}, mu0*Norm[{h}]] * {d h} * {d h}] ; // j*e = rho*j^2 (filaments)
|
|
1210
|
+
In NonLinOmegaC ; Integration Int ; Jacobian Vol; }
|
|
1211
|
+
Integral{ [rho[mu0*Norm[{h}]] * {d h} * {d h}] ; // j*e = rho*j^2 (eddy)
|
|
1212
|
+
In Matrix ; Integration Int ; Jacobian Vol; }
|
|
1213
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" %}
|
|
1214
|
+
Integral{ [ (sigma[mu0*Norm[{h}]]*{d v}) * {d v}] ; // j*e = sigma*e^2 in matrix (coupling)
|
|
1215
|
+
In Matrix ; Integration Int ; Jacobian Vol; }
|
|
1216
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
1217
|
+
Integral { [ 1/rho_contact[] * {v} * {v} ];
|
|
1218
|
+
In GlobalDiffusionBarrier; Integration Int; Jacobian Sur; } // This requires that only the discontinuous component of {v} is defined on the diffusion barrier
|
|
1219
|
+
{% endif %}
|
|
1220
|
+
{% endif %}
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
{ Name heat_capacity;
|
|
1224
|
+
Value{
|
|
1225
|
+
Integral{ [(filament_Cv[T[] + $cumulative_temperature, mu0*Norm[{h}]] )] ; // j*e = rho*j^2 in filaments (?)
|
|
1226
|
+
In NonLinOmegaC ; Integration Int ; Jacobian Vol; }
|
|
1227
|
+
Integral{ [(matrix_Cv[T[] + $cumulative_temperature]) ] ; // j*e = rho*j^2 in filaments (?)
|
|
1228
|
+
In NonLinOmegaC ; Integration Int ; Jacobian Vol; }
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
{ Name I; Value { Term{ [ {I} ] ; In Cuts; } } }
|
|
1232
|
+
{ Name V; Value { Term{ [ {V} ] ; In Cuts; } } }
|
|
1233
|
+
{ Name V_unitlen; Value { Term{ [ {V} / ell ] ; In Cuts; } } }
|
|
1234
|
+
{ Name It; Value { Term{ [ {It} ] ; In BndMatrixCut; } } }
|
|
1235
|
+
{ Name Vt; Value { Term{ [ {Vt} ] ; In BndMatrixCut; } } }
|
|
1236
|
+
{ Name Vt_unitlen; Value { Term{ [ {Vt} / ell ] ; In BndMatrixCut; } } }
|
|
1237
|
+
{ Name I_integral;
|
|
1238
|
+
Value{
|
|
1239
|
+
Integral{ [ {d h} * Vector[0,0,1]] ;
|
|
1240
|
+
In OmegaC ; Integration Int ; Jacobian Vol; }
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
{ Name I_abs_integral;
|
|
1244
|
+
Value{
|
|
1245
|
+
Integral{ [ Fabs[{d h} * Vector[0,0,1]]] ;
|
|
1246
|
+
In OmegaC ; Integration Int ; Jacobian Vol; }
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
{ Name area;
|
|
1250
|
+
Value{
|
|
1251
|
+
Integral{ [ 1 ] ;
|
|
1252
|
+
In Omega ; Integration Int ; Jacobian Vol; }
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
// Applied field (useful for magnetization plots)
|
|
1256
|
+
{ Name hsVal; Value{ Term { [ hsVal[] ]; In Omega; } } }
|
|
1257
|
+
// Magnetization: integral of 1/2 * (r /\ j) in a conducting (sub-)domain
|
|
1258
|
+
{ Name magnetization; Value{ Integral{ [ 0.5 * XYZ[] /\ {d h} ] ;
|
|
1259
|
+
In OmegaC; Integration Int; Jacobian Vol; } } }
|
|
1260
|
+
// Magnetic energy
|
|
1261
|
+
{ Name magnetic_energy; Value{ Integral{ [ 0.5 * mu[] * {h} * {h} ] ;
|
|
1262
|
+
In Omega; Integration Int; Jacobian Vol; } } }
|
|
1263
|
+
{ Name b_integral; Value{ Integral{ [ mu[] * {h} ] ;
|
|
1264
|
+
In Omega; Integration Int; Jacobian Vol; } } }
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
1268
|
+
{ Name MagDyn_hphi_dynCorr; NameOfFormulation MagDyn_hphi_dynCorr;
|
|
1269
|
+
Quantity {
|
|
1270
|
+
{ Name hp_static; Value{ Local{ [ {hp_static} ] ;
|
|
1271
|
+
In Matrix_partitions_for_TI; Jacobian Vol; } } }
|
|
1272
|
+
{ Name hp_static_lagrange; Value{ Local{ [ {hp_static_lagrange} ] ;
|
|
1273
|
+
In Matrix_partitions_for_TI; Jacobian Vol; } } }
|
|
1274
|
+
{ Name j_static; Value{ Local{ [ {d hp_static} ] ;
|
|
1275
|
+
In Matrix_partitions_for_TI; Jacobian Vol; } } }
|
|
1276
|
+
{ Name hp_dynamic; Value{ Local{ [ {hp_dynamic} ] ;
|
|
1277
|
+
In Matrix_partitions_for_TI; Jacobian Vol; } } }
|
|
1278
|
+
{ Name j_dynamic; Value{ Local{ [ {d hp_dynamic} ] ;
|
|
1279
|
+
In Matrix_partitions_for_TI; Jacobian Vol; } } }
|
|
1280
|
+
{ Name j_stadyn; Value{ Local{ [ {d hp_static} + {d hp_dynamic} ] ;
|
|
1281
|
+
In Matrix_partitions_for_TI; Jacobian Vol; } } }
|
|
1282
|
+
{ Name j_stadyn_mixed; Value{ Local{ [ - sigma[mu0*Norm[{h}]] * {d v} + {d hp_dynamic} ] ;
|
|
1283
|
+
In Matrix_partitions_for_TI; Jacobian Vol; } } }
|
|
1284
|
+
{ Name totalLoss_dyn; // Does not include (global) contribution from possible diffusion barriers around filaments
|
|
1285
|
+
Value{
|
|
1286
|
+
// Integral{ [rho[{d h}, mu0*Norm[{h}]] * {d h} * {d h}] ;
|
|
1287
|
+
// In OmegaC ; Integration Int ; Jacobian Vol; }
|
|
1288
|
+
// NEW separate OmegaC into Matrix and nonlinear
|
|
1289
|
+
Integral{ [rho[{d h}, mu0*Norm[{h}]] * {d h} * {d h}] ; // j*e = rho*j^2 in filaments
|
|
1290
|
+
In NonLinOmegaC ; Integration Int ; Jacobian Vol; }
|
|
1291
|
+
Integral{ [rho[mu0*Norm[{h}]] * {d h} * {d h}] ; // Eddy
|
|
1292
|
+
In Matrix ; Integration Int ; Jacobian Vol; }
|
|
1293
|
+
Integral{ [ (- sigma[mu0*Norm[{h}]]*{d v} + {d hp_dynamic}) * (- {d v} + rho[mu0*Norm[{h}]] * {d hp_dynamic})] ;
|
|
1294
|
+
In Matrix_partitions_for_TI ; Integration Int ; Jacobian Vol; } // Attention to signs!
|
|
1295
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
1296
|
+
Integral { [ 1/rho_contact[] * {v} * {v} ];
|
|
1297
|
+
In GlobalDiffusionBarrier; Integration Int; Jacobian Sur; } // This requires that only the discontinuous component of {v} is defined on the diffusion barrier
|
|
1298
|
+
{% endif %}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
{ Name couplingLoss_dyn; // Does not include (global) contribution from possible diffusion barriers around filaments
|
|
1302
|
+
Value{
|
|
1303
|
+
Integral{ [(- sigma[mu0*Norm[{h}]]*{d v} + {d hp_dynamic}) * (- {d v} + rho[mu0*Norm[{h}]] * {d hp_dynamic})] ;
|
|
1304
|
+
In Matrix_partitions_for_TI ; Integration Int ; Jacobian Vol; } // Attention to signs!
|
|
1305
|
+
{% if dm.magnet.solve.global_diffusion_barrier.enable %}
|
|
1306
|
+
Integral { [ 1/rho_contact[] * {v} * {v} ];
|
|
1307
|
+
In GlobalDiffusionBarrier; Integration Int; Jacobian Sur; } // This requires that only the discontinuous component of {v} is defined on the diffusion barrier
|
|
1308
|
+
{% endif %}
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
{% endif %}
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
PostOperation {
|
|
1317
|
+
{ Name MagDyn;
|
|
1318
|
+
NameOfPostProcessing MagDyn_hphi;
|
|
1319
|
+
Operation {
|
|
1320
|
+
{% set units_dict = {
|
|
1321
|
+
"b": "T",
|
|
1322
|
+
"b_reaction": "T",
|
|
1323
|
+
"h": "A/m",
|
|
1324
|
+
"hsVal": "A/m",
|
|
1325
|
+
"phi": "A",
|
|
1326
|
+
"power_filaments": "W",
|
|
1327
|
+
"power_matrix": "W",
|
|
1328
|
+
"j": "A/m2",
|
|
1329
|
+
"jz": "A/m2",
|
|
1330
|
+
"jc": "A/m2",
|
|
1331
|
+
"jPlane": "A/m2",
|
|
1332
|
+
"vPlane": "V/m",
|
|
1333
|
+
"sigma_matrix": "S/m",
|
|
1334
|
+
"j_dynamic": "A/m2",
|
|
1335
|
+
"j_stadyn_mixed": "A/m2",
|
|
1336
|
+
"hp_dynamic": "A/m",
|
|
1337
|
+
"hp_static": "A/m",
|
|
1338
|
+
"hp_static_lagrange": "A/m",
|
|
1339
|
+
} %}
|
|
1340
|
+
// Print[ phi, OnElementsOf OmegaCC , File StrCat["phi_f.pos"], Name "phi [A]" ];
|
|
1341
|
+
// Print[ b_reaction, OnElementsOf Omega , File StrCat["br.pos"], Name "br [T]" ];
|
|
1342
|
+
// Print[ j, OnElementsOf OmegaC , File StrCat["j.pos"], Name "j [A/m2]" ];
|
|
1343
|
+
// Print[ jz, OnElementsOf OmegaC , File StrCat["jz.pos"], Name "jz [A/m2]" ];
|
|
1344
|
+
//Print[ jc, OnElementsOf NonLinOmegaC , File StrCat["jc.pos"], Name "jc [A/m2]" ];
|
|
1345
|
+
//Print[ rho, OnElementsOf NonLinOmegaC , File StrCat["rho.pos"], Name "rho [Ohm.m]" ];
|
|
1346
|
+
// Print[ j_plane, OnElementsOf Matrix , File StrCat["jPlane.pos"], Name "j_plane [A/m2]" ];
|
|
1347
|
+
// Print[ v_plane, OnElementsOf Matrix , File StrCat["vPlane.pos"], Name "v_plane [V/m]" ];
|
|
1348
|
+
// Print[ power_filaments, OnElementsOf NonLinOmegaC , File StrCat["powFil_f.pos"], Name "powerFilaments [W]" ];
|
|
1349
|
+
// Print[ power_matrix, OnElementsOf Matrix , File StrCat["powMat_f.pos"], Name "powerMatrix [W]" ];
|
|
1350
|
+
// Print[ sigma_matrix, OnElementsOf Matrix , File StrCat["sigmaMat_f.pos"], Name "sigmaMatrix [S/m]" ];
|
|
1351
|
+
// Print[ b, OnElementsOf Omega , File StrCat["b.pos"], Name "b [T]" ];
|
|
1352
|
+
// Global solutions
|
|
1353
|
+
Print[ b_integral[Omega], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/b_integral.txt"]];
|
|
1354
|
+
Print[ It, OnRegion BndMatrixCut, File StrCat[resDirectory,"/I_transport.txt"], Format SimpleTable];
|
|
1355
|
+
Print[ Vt, OnRegion BndMatrixCut, File StrCat[resDirectory,"/V_transport.txt"], Format SimpleTable];
|
|
1356
|
+
Print[ Vt_unitlen, OnRegion BndMatrixCut, File StrCat[resDirectory,"/V_transport_unitlen.txt"], Format SimpleTable];
|
|
1357
|
+
Print[ hsVal[Omega], OnRegion Matrix, Format TimeTable, File StrCat[resDirectory, "/hs_val.txt"]];
|
|
1358
|
+
Print[ area[NonLinOmegaC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/area_sc_filaments.txt"]];
|
|
1359
|
+
Print[ area[Filament_holes], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/area_filament_holes.txt"]];
|
|
1360
|
+
Print[ area[Matrix], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/area_matrix.txt"]];
|
|
1361
|
+
{% for i, matrix_partition_material in zip(range(len(rm.induced.Matrix.vol.numbers)), rm.induced.Matrix.vol.names)%}
|
|
1362
|
+
Print[ area[Matrix_<<i>>], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/area_matrix_<<i>>.txt"]];
|
|
1363
|
+
{%endfor%}
|
|
1364
|
+
Print[ magnetization[Filaments_SC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/magn_fil.txt"]];
|
|
1365
|
+
Print[ magnetization[Matrix], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/magn_matrix.txt"]];
|
|
1366
|
+
Print[ magnetization[OmegaC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/magn_total.txt"]];
|
|
1367
|
+
Print[ flux_external[OmegaCC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/flux_external.txt"]];
|
|
1368
|
+
Print[ flux_internal[OmegaC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/flux_internal.txt"]];
|
|
1369
|
+
Print[ magnetic_energy[OmegaC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/magnetic_energy_internal.txt"]];
|
|
1370
|
+
Print[ magnetic_energy[OmegaCC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/magnetic_energy_external.txt"]];
|
|
1371
|
+
Print[ selffield_dfluxdt[Filaments_SC], OnGlobal, Format TimeTable, File StrCat[resDirectory, "/selffield_dfluxdt.txt"]];
|
|
1372
|
+
// Local field solutions
|
|
1373
|
+
{% for quantity, region in zip(dm.magnet.postproc.pos_files.quantities, dm.magnet.postproc.pos_files.regions) %}
|
|
1374
|
+
Print[ <<quantity>>, OnElementsOf <<region>> , File StrCat["<<quantity>>_<<region>>.pos"], Name "<<quantity>> [<<units_dict[quantity]>>]" ];
|
|
1375
|
+
{% endfor %}
|
|
1376
|
+
{% if dm.magnet.postproc.compute_current_per_filament == True %}
|
|
1377
|
+
// Integrals of local quantities
|
|
1378
|
+
Print[I_integral[filament_1_1], OnGlobal, File StrCat[resDirectory,"/I_integral.txt"], Format SimpleTable];
|
|
1379
|
+
For i In {1:number_of_layers}
|
|
1380
|
+
For j In {((i==1)?2:1):6}
|
|
1381
|
+
Print[I_integral[filament~{i}~{j}], OnGlobal, File > StrCat[resDirectory,"/I_integral.txt"], Format SimpleTable];
|
|
1382
|
+
EndFor
|
|
1383
|
+
EndFor
|
|
1384
|
+
Print[I_abs_integral[filament_1_1], OnGlobal, File StrCat[resDirectory,"/I_abs_integral.txt"], Format SimpleTable];
|
|
1385
|
+
For i In {1:number_of_layers}
|
|
1386
|
+
For j In {((i==1)?2:1):6}
|
|
1387
|
+
Print[I_abs_integral[filament~{i}~{j}], OnGlobal, File > StrCat[resDirectory,"/I_abs_integral.txt"], Format SimpleTable];
|
|
1388
|
+
EndFor
|
|
1389
|
+
EndFor
|
|
1390
|
+
// Global quantities (axial current problem)
|
|
1391
|
+
Print[I, OnRegion Cut_1_1, File StrCat[resDirectory,"/I.txt"], Format SimpleTable];
|
|
1392
|
+
For i In {1:number_of_layers}
|
|
1393
|
+
For j In {((i==1)?2:1):6}
|
|
1394
|
+
Print[I, OnRegion Cut~{i}~{j}, File > StrCat[resDirectory,"/I.txt"], Format SimpleTable];
|
|
1395
|
+
EndFor
|
|
1396
|
+
EndFor
|
|
1397
|
+
Print[V, OnRegion Cut_1_1, File StrCat[resDirectory,"/V.txt"], Format SimpleTable];
|
|
1398
|
+
For i In {1:number_of_layers}
|
|
1399
|
+
For j In {((i==1)?2:1):6}
|
|
1400
|
+
Print[V, OnRegion Cut~{i}~{j}, File > StrCat[resDirectory,"/V.txt"], Format SimpleTable];
|
|
1401
|
+
EndFor
|
|
1402
|
+
EndFor
|
|
1403
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" %}
|
|
1404
|
+
// Global quantities (transverse current problem)
|
|
1405
|
+
Print[Ip, OnRegion filamentBnd_1_1, File StrCat[resDirectory,"/Ip.txt"], Format SimpleTable];
|
|
1406
|
+
For i In {1:number_of_layers}
|
|
1407
|
+
For j In {((i==1)?2:1):6}
|
|
1408
|
+
Print[Ip, OnRegion filamentBnd~{i}~{j}, File > StrCat[resDirectory,"/Ip.txt"], Format SimpleTable];
|
|
1409
|
+
EndFor
|
|
1410
|
+
EndFor
|
|
1411
|
+
Print[Vp, OnRegion filamentBnd_1_1, File StrCat[resDirectory,"/Vp.txt"], Format SimpleTable];
|
|
1412
|
+
For i In {1:number_of_layers}
|
|
1413
|
+
For j In {((i==1)?2:1):6}
|
|
1414
|
+
Print[Vp, OnRegion filamentBnd~{i}~{j}, File > StrCat[resDirectory,"/Vp.txt"], Format SimpleTable];
|
|
1415
|
+
EndFor
|
|
1416
|
+
EndFor
|
|
1417
|
+
{% endif %}
|
|
1418
|
+
{% endif %}
|
|
1419
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.diffusion_barriers.enable %}
|
|
1420
|
+
// Gives loss per unit length, first column for time, then one column per filament boundary
|
|
1421
|
+
Print[ diffusion_barrier_loss, OnRegion Resistors_diffusion_barrier, Format TimeTable, File StrCat[resDirectory, "/power_diffusion_barrier.txt"]];
|
|
1422
|
+
{% endif %}
|
|
1423
|
+
|
|
1424
|
+
// Last magnetic field solution for projection. Always saved. Note the special format GmshParsed required for proper GmshRead[] operation in the later pre-resolution.
|
|
1425
|
+
Print[ h, OnElementsOf Omega, Format GmshParsed , File "last_magnetic_field.pos", Name "h [A/m]", LastTimeStepOnly ];
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
1429
|
+
{ Name MagDyn_dynCorr;
|
|
1430
|
+
NameOfPostProcessing MagDyn_hphi_dynCorr;
|
|
1431
|
+
Operation {
|
|
1432
|
+
// Print[ j_dynamic, OnElementsOf Matrix_partitions_for_TI , File StrCat["j_dynamic.pos"], Name "j_dynamic [A/m2]" ];
|
|
1433
|
+
// Print[ j_stadyn_mixed, OnElementsOf Matrix_partitions_for_TI , File StrCat["j_stadyn_mixed.pos"], Name "j_stadyn_mixed [A/m2]" ];
|
|
1434
|
+
// Print[ hp_dynamic, OnElementsOf Matrix_partitions_for_TI , File StrCat["hp_dynamic.pos"], Name "hp_dynamic [A/m]" ];
|
|
1435
|
+
// Print[ hp_static, OnElementsOf Matrix , File StrCat["hp_static.pos"], Name "hp_static [A/m]" ];
|
|
1436
|
+
// Print[ hp_static_lagrange, OnElementsOf Matrix , File StrCat["hp_static_lagrange.pos"], Name "hp_static_lagrange [A/m]" ];
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
{% endif %}
|
|
1440
|
+
{ Name MagDyn_energy; LastTimeStepOnly 1 ;
|
|
1441
|
+
NameOfPostProcessing MagDyn_hphi;
|
|
1442
|
+
Operation {
|
|
1443
|
+
Print[ totalLoss[NonLinOmegaC], OnGlobal, Format Table, StoreInVariable $indicFilamentLoss, File StrCat[resDirectory,"/dummy.txt"] ];
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
{ Name test_Losses; LastTimeStepOnly 1 ;
|
|
1447
|
+
NameOfPostProcessing MagDyn_hphi;
|
|
1448
|
+
Operation {
|
|
1449
|
+
Print[ totalLoss[OmegaC], OnGlobal, Format Table, StoreInVariable $indicTotalLoss, File > StrCat[resDirectory,"/dummy.txt"] ];
|
|
1450
|
+
Print[ totalLoss[NonLinOmegaC], OnGlobal, Format Table, StoreInVariable $indicFilamentLoss, File StrCat[resDirectory,"/dummy.txt"] ];
|
|
1451
|
+
Print[ eddyLoss[Matrix], OnGlobal, Format Table, StoreInVariable $indicEddyLoss, File > StrCat[resDirectory,"/dummy.txt"] ];
|
|
1452
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" %}
|
|
1453
|
+
Print[ couplingLoss[Matrix], OnGlobal, Format Table, StoreInVariable $indicCouplingLoss, File > StrCat[resDirectory,"/dummy.txt"] ];
|
|
1454
|
+
{% endif %}
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
{ Name heat_capacity; LastTimeStepOnly 1 ;
|
|
1459
|
+
NameOfPostProcessing MagDyn_hphi;
|
|
1460
|
+
Operation {
|
|
1461
|
+
Print[ heat_capacity[OmegaC], OnGlobal, Format Table, StoreInVariable $heat_capacity_per_unit_length, File StrCat[resDirectory,"/dummy.txt"] ];
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
{% if dm.magnet.solve.formulation_parameters.formulation == "CATI" and dm.magnet.solve.formulation_parameters.dynamic_correction == True %}
|
|
1466
|
+
{ Name test_Losses_dynCorr; LastTimeStepOnly 1 ;
|
|
1467
|
+
NameOfPostProcessing MagDyn_hphi_dynCorr;
|
|
1468
|
+
Operation {
|
|
1469
|
+
Print[ totalLoss_dyn[OmegaC], OnGlobal, Format Table, StoreInVariable $indicTotalLoss_dyn, File > StrCat[resDirectory,"/dummy.txt"] ];
|
|
1470
|
+
Print[ couplingLoss_dyn[Matrix_partitions_for_TI], OnGlobal, Format Table, StoreInVariable $indicCouplingLoss_dyn, File > StrCat[resDirectory,"/dummy.txt"] ];
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
{% endif %}
|
|
1474
|
+
}
|