Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/src/MagnetoDynamicsUtils.F90
3203 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer, A Finite Element Software for Multiphysical Problems
4
! *
5
! * Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
! *
7
! * This library is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU Lesser General Public
9
! * License as published by the Free Software Foundation; either
10
! * version 2.1 of the License, or (at your option) any later version.
11
! *
12
! * This library is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
! * Lesser General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU Lesser General Public
18
! * License along with this library (in file ../LGPL-2.1); if not, write
19
! * to the Free Software Foundation, Inc., 51 Franklin Street,
20
! * Fifth Floor, Boston, MA 02110-1301 USA
21
! *
22
! *****************************************************************************/
23
!
24
25
!------------------------------------------------------------------------------
26
MODULE MGDynMaterialUtils
27
!------------------------------------------------------------------------------
28
USE DefUtils
29
IMPLICIT NONE
30
31
INTERFACE GetPermittivity
32
MODULE PROCEDURE GetPermittivityR, GetPermittivityC
33
END INTERFACE
34
35
CONTAINS
36
!------------------------------------------------------------------------------
37
FUNCTION GetElectricConductivityTensor(Element, n, Part, &
38
CoilBody,CoilType) RESULT (Tcoef)
39
!------------------------------------------------------------------------------
40
IMPLICIT NONE
41
REAL(KIND=dp), SAVE, POINTER :: Cwrk(:,:,:) => NULL()
42
TYPE(Element_t), POINTER :: Element
43
INTEGER :: n, i, j
44
TYPE(Valuelist_t), POINTER :: Material
45
REAL(KIND=dp) :: Tcoef(3,3,n)
46
CHARACTER(LEN=*):: CoilType
47
CHARACTER(LEN=2) :: Part
48
LOGICAL :: Found
49
LOGICAL :: CoilBody
50
!$OMP THREADPRIVATE(Cwrk)
51
52
Tcoef=0._dp
53
Material => GetMaterial( Element )
54
IF ( ASSOCIATED(Material) ) THEN
55
IF (Part=='re') THEN
56
CALL ListGetRealArray( Material, &
57
'Electric Conductivity', Cwrk, n, Element % NodeIndexes, Found )
58
ELSE
59
CALL ListGetRealArray( Material, &
60
'Electric Conductivity im', Cwrk, n, Element % NodeIndexes, Found )
61
END IF
62
IF (Found) THEN
63
IF (SIZE(Cwrk,1) == 1 .AND. SIZE(Cwrk,2) == 1) THEN
64
DO i=1,3
65
Tcoef(i,i,1:n) = Cwrk(1,1,1:n)
66
END DO
67
ELSE
68
IF ( SIZE(Cwrk,1) == 1 ) THEN
69
DO i=1,MIN(3, SIZE(Cwrk,2))
70
Tcoef( i,i,1:n ) = Cwrk( 1,i,1:n )
71
END DO
72
ELSE IF ( SIZE(Cwrk,2) == 1 ) THEN
73
DO i=1,MIN(3,SIZE(Cwrk,1))
74
Tcoef(i,i,1:n) = Cwrk(i,1,1:n)
75
END DO
76
ELSE
77
DO i=1,MIN(3,SIZE(Cwrk,1))
78
DO j=1,MIN(3,SIZE(Cwrk,2))
79
Tcoef( i,j,1:n ) = Cwrk(i,j,1:n)
80
END DO
81
END DO
82
END IF
83
END IF
84
END IF
85
END IF
86
87
IF (CoilBody) THEN
88
SELECT CASE (CoilType)
89
CASE ('stranded')
90
!Tcoef(1,1,1:n) = 0._dp
91
!Tcoef(2,2,1:n) = 0._dp
92
CASE ('foil winding')
93
Tcoef(1,1,1:n) = 0._dp
94
END SELECT
95
END IF
96
97
!------------------------------------------------------------------------------
98
END FUNCTION GetElectricConductivityTensor
99
!------------------------------------------------------------------------------
100
101
!------------------------------------------------------------------------------
102
FUNCTION GetCMPLXElectricConductivityTensor(Element, n, CoilBody, CoilType) &
103
RESULT (TCoef)
104
!------------------------------------------------------------------------------
105
IMPLICIT NONE
106
COMPLEX(KIND=dp) :: TCoef(3,3,n)
107
REAL(KIND=dp) :: TCoefRe(3,3,n), TCoefIm(3,3,n)
108
TYPE(Element_t), POINTER :: Element
109
INTEGER :: n, i, j
110
LOGICAL :: CoilBody
111
CHARACTER(LEN=*) :: CoilType
112
113
TCoef=0._dp
114
TCoefRe=0._dp
115
TCoefIm=0._dp
116
TCoefRe = GetElectricConductivityTensor(Element,n,'re',CoilBody,CoilType)
117
TCoefIm = GetElectricConductivityTensor(Element,n,'im',CoilBody,CoilType)
118
DO i=1,3
119
DO j=1,3
120
Tcoef( i,j,1:n ) = CMPLX( TcoefRe( i,j,1:n ), TCoefIm( i,j,1:n ), KIND=dp)
121
END DO
122
END DO
123
124
!------------------------------------------------------------------------------
125
END FUNCTION GetCMPLXElectricConductivityTensor
126
!------------------------------------------------------------------------------
127
128
!------------------------------------------------------------------------------
129
FUNCTION GetPermeabilityTensor(Element, n, Part) &
130
RESULT (mu)
131
!------------------------------------------------------------------------------
132
IMPLICIT NONE
133
REAL(KIND=dp), SAVE, POINTER :: Cwrk(:,:,:) => NULL()
134
TYPE(Element_t), POINTER :: Element
135
INTEGER :: n, i, j
136
TYPE(Valuelist_t), POINTER :: Material
137
REAL(KIND=dp) :: mu(3,3,n)
138
CHARACTER(LEN=2) :: Part
139
LOGICAL :: Found
140
!$OMP THREADPRIVATE(Cwrk)
141
142
mu=0._dp
143
Material => GetMaterial( Element )
144
IF ( ASSOCIATED(Material) ) THEN
145
IF (Part=='re') THEN
146
CALL ListGetRealArray( Material, &
147
'Relative Permeability', Cwrk, n, Element % NodeIndexes, Found )
148
ELSE
149
CALL ListGetRealArray( Material, &
150
'Relative Permeability im', Cwrk, n, Element % NodeIndexes, Found )
151
END IF
152
IF (Found) THEN
153
IF (SIZE(Cwrk,1) == 1 .AND. SIZE(Cwrk,2) == 1) THEN
154
DO i=1,3
155
mu(i,i,1:n) = Cwrk(1,1,1:n)
156
END DO
157
ELSE
158
IF ( SIZE(Cwrk,1) == 1 ) THEN
159
DO i=1,MIN(3, SIZE(Cwrk,2))
160
mu( i,i,1:n ) = Cwrk( 1,i,1:n )
161
END DO
162
ELSE IF ( SIZE(Cwrk,2) == 1 ) THEN
163
DO i=1,MIN(3,SIZE(Cwrk,1))
164
mu(i,i,1:n) = Cwrk(i,1,1:n)
165
END DO
166
ELSE
167
DO i=1,MIN(3,SIZE(Cwrk,1))
168
DO j=1,MIN(3,SIZE(Cwrk,2))
169
mu( i,j,1:n ) = Cwrk(i,j,1:n)
170
END DO
171
END DO
172
END IF
173
END IF
174
END IF
175
END IF
176
!------------------------------------------------------------------------------
177
END FUNCTION GetPermeabilityTensor
178
!------------------------------------------------------------------------------
179
180
!------------------------------------------------------------------------------
181
FUNCTION GetTensor(Element, n, tsize, varname, Part, Found) &
182
RESULT (T)
183
!------------------------------------------------------------------------------
184
IMPLICIT NONE
185
REAL(KIND=dp), POINTER :: Cwrk(:,:,:) => NULL()
186
TYPE(Element_t), POINTER :: Element
187
INTEGER :: n, i, j, slen, tsize
188
TYPE(Valuelist_t), POINTER :: Material
189
REAL(KIND=dp) :: T(tsize,tsize,n)
190
CHARACTER(LEN=2) :: Part
191
CHARACTER(LEN=*) :: varname
192
LOGICAL, OPTIONAL :: Found
193
!$OMP THREADPRIVATE(Cwrk)
194
195
IF (.NOT. ASSOCIATED(Element)) CALL Fatal ('GetTensor', 'Element not associated')
196
T=0._dp
197
Material => GetMaterial( Element )
198
IF ( ASSOCIATED(Material) ) THEN
199
slen = LEN_TRIM(varname)
200
IF (Part=='re') THEN
201
CALL ListGetRealArray( Material, &
202
varname(1:slen), Cwrk, n, Element % NodeIndexes, Found )
203
ELSE
204
CALL ListGetRealArray( Material, &
205
varname(1:slen)//' im', Cwrk, n, Element % NodeIndexes, Found )
206
END IF
207
IF (Found) THEN
208
IF (SIZE(Cwrk,1) == 1 .AND. SIZE(Cwrk,2) == 1) THEN
209
DO i=1,tsize
210
T(i,i,1:n) = Cwrk(1,1,1:n)
211
END DO
212
ELSE
213
IF ( SIZE(Cwrk,1) == 1 ) THEN
214
DO i=1,MIN(tsize, SIZE(Cwrk,2))
215
T( i,i,1:n ) = Cwrk( 1,i,1:n )
216
END DO
217
ELSE IF ( SIZE(Cwrk,2) == 1 ) THEN
218
DO i=1,MIN(tsize,SIZE(Cwrk,1))
219
T(i,i,1:n) = Cwrk(i,1,1:n)
220
END DO
221
ELSE
222
DO i=1,MIN(tsize,SIZE(Cwrk,1))
223
DO j=1,MIN(tsize,SIZE(Cwrk,2))
224
T( i,j,1:n ) = Cwrk(i,j,1:n)
225
END DO
226
END DO
227
END IF
228
END IF
229
END IF
230
END IF
231
!------------------------------------------------------------------------------
232
END FUNCTION GetTensor
233
!------------------------------------------------------------------------------
234
235
!------------------------------------------------------------------------------
236
FUNCTION GetCMPLXTensor(Element, n, tsize, varname, Found) &
237
RESULT (T)
238
!------------------------------------------------------------------------------
239
IMPLICIT NONE
240
TYPE(Element_t), POINTER :: Element
241
INTEGER :: n, i, j, slen, tsize
242
COMPLEX(KIND=dp) :: T(tsize,tsize,n)
243
REAL(KIND=dp) :: TRe(tsize,tsize,n), TIm(tsize,tsize,n)
244
CHARACTER(LEN=2) :: Part
245
CHARACTER(LEN=*) :: varname
246
LOGICAL, OPTIONAL :: Found
247
LOGICAL :: FoundRe, FoundIm
248
249
T=0._dp
250
TRe=0._dp
251
TIm=0._dp
252
TRe = GetTensor(Element,n,tsize,varname,'re',FoundRe)
253
TIm = GetTensor(Element,n,tsize,varname,'im',FoundIm)
254
Found = FoundRe .OR. FoundIm
255
DO i=1,tsize
256
DO j=1,tsize
257
T( i,j,1:n ) = CMPLX( REAL(TRe( i,j,1:n )), TIm( i,j,1:n ), KIND=dp)
258
END DO
259
END DO
260
!------------------------------------------------------------------------------
261
END FUNCTION GetCMPLXTensor
262
!------------------------------------------------------------------------------
263
264
265
!-------------------------------------------------------------------
266
FUNCTION Get2x2MatrixInverse(M) &
267
RESULT (Minv)
268
!-------------------------------------------------------------------
269
IMPLICIT NONE
270
REAL(KIND=dp) :: M(2,2), Minv(2,2)
271
REAL(KIND=dp) :: det, a, b, c, d
272
273
a = M(1,1); b = M(1,2); c=M(2,1); d=M(2,2)
274
Minv=0._dp
275
276
IF ( ABS(a) <= TINY(a) .AND. ABS(b) <= TINY(b) .AND. &
277
ABS(c) <= TINY(c) .AND. ABS(d) <= TINY(d) ) RETURN
278
det = a*d-b*c
279
IF (ABS(det) <= TINY(det)) CALL Fatal('Get2x2MatrixInverse', 'Determinant is zero! This should not happen...')
280
281
Minv(1,1) = 1/det * d
282
Minv(1,2) = -1/det * b
283
Minv(2,1) = -1/det * c
284
Minv(2,2) = 1/det * a
285
286
!-------------------------------------------------------------------
287
END FUNCTION Get2x2MatrixInverse
288
!-------------------------------------------------------------------
289
290
!-------------------------------------------------------------------
291
FUNCTION Get2x2TensorInverse(T, n) &
292
RESULT (Tinv)
293
!-------------------------------------------------------------------
294
IMPLICIT NONE
295
REAL(KIND=dp) :: T(2,2,n), Tinv(2,2,n)
296
INTEGER :: i, n
297
298
DO i = 1, n
299
Tinv(:,:,i) = Get2x2MatrixInverse(T(:,:,i))
300
END DO
301
302
!-------------------------------------------------------------------
303
END FUNCTION Get2x2TensorInverse
304
!-------------------------------------------------------------------
305
306
!-------------------------------------------------------------------
307
FUNCTION Get2x2CMPLXMatrixInverse(M) &
308
RESULT (Minv)
309
!-------------------------------------------------------------------
310
IMPLICIT NONE
311
COMPLEX(KIND=dp) :: M(2,2), Minv(2,2)
312
COMPLEX(KIND=dp) :: det, a, b, c, d
313
REAL(KIND=dp) :: r
314
315
a = M(1,1); b = M(1,2); c=M(2,1); d=M(2,2)
316
Minv=0._dp
317
318
IF ( ABS(a) <= TINY(r) .AND. ABS(b) <= TINY(r) .AND. &
319
ABS(c) <= TINY(r) .AND. ABS(d) <= TINY(r) ) RETURN
320
det = a*d-b*c
321
IF (ABS(det) <= TINY(r)) CALL Fatal('Get2x2MatrixInverse', 'Determinant is zero! This should not happen...')
322
323
Minv(1,1) = 1/det * d
324
Minv(1,2) = -1/det * b
325
Minv(2,1) = -1/det * c
326
Minv(2,2) = 1/det * a
327
328
!-------------------------------------------------------------------
329
END FUNCTION Get2x2CMPLXMatrixInverse
330
!-------------------------------------------------------------------
331
332
!-------------------------------------------------------------------
333
FUNCTION Get2x2CMPLXTensorInverse(T, n) &
334
RESULT (Tinv)
335
!-------------------------------------------------------------------
336
IMPLICIT NONE
337
COMPLEX(KIND=dp) :: T(2,2,n), Tinv(2,2,n)
338
INTEGER :: i, n
339
340
DO i = 1, n
341
Tinv(:,:,i) = Get2x2CMPLXMatrixInverse(T(:,:,i))
342
END DO
343
344
!-------------------------------------------------------------------
345
END FUNCTION Get2x2CMPLXTensorInverse
346
!-------------------------------------------------------------------
347
348
!------------------------------------------------------------------------------
349
SUBROUTINE GetElementRotM(Element,RotM,n)
350
!------------------------------------------------------------------------------
351
USE CircuitUtils
352
IMPLICIT NONE
353
TYPE(Mesh_t), POINTER, SAVE :: Mesh
354
TYPE(Element_t), POINTER :: Element
355
TYPE(Valuelist_t), POINTER :: CompParams
356
INTEGER :: k, l, m, j, n
357
REAL(KIND=dp) :: RotM(3,3,n)
358
INTEGER, PARAMETER :: ind1(9) = [1,1,1,2,2,2,3,3,3]
359
INTEGER, PARAMETER :: ind2(9) = [1,2,3,1,2,3,1,2,3]
360
TYPE(Variable_t), POINTER, SAVE :: RotMvar !, alphavecvar
361
REAL(KIND=dp), POINTER, SAVE :: ConstArray(:,:)
362
REAL(KIND=dp) :: Origin(3), alpha_ref(3), beta_ref(3)
363
REAL(KIND=dp) :: x(3), r(3), xref(3)
364
REAL(KIND=dp) :: C, S, t
365
LOGICAL, SAVE :: visited = .FALSE.
366
TYPE(Nodes_t), SAVE :: Nodes
367
368
LOGICAL :: GotIt
369
370
IF(.NOT. visited) THEN
371
visited = .TRUE.
372
Mesh => GetMesh()
373
RotMvar => VariableGet( Mesh % Variables, 'RotM E')
374
IF(.NOT. ASSOCIATED(RotMVar)) THEN
375
CALL Fatal('GetElementRotM','RotM E variable not found')
376
END IF
377
378
! alphavecvar => VariableGet( Mesh % Variables, 'Alpha Vector E')
379
! IF(.NOT. ASSOCIATED(alphavecvar)) THEN
380
! CALL Fatal('RotMSolver()','Alpha Vector E variable not found')
381
! END IF
382
END IF
383
384
RotM = 0._dp
385
386
CompParams => GetComponentParams(Element)
387
CALL GetConstRealArray( CompParams, ConstArray, 'Rotation Matrix Origin', GotIt )
388
IF (GotIt) THEN
389
IF (SIZE(Origin) /= 3) CALL Fatal('GetElementRotM', 'Rotation Matrix Origin needs three components!')
390
Origin = ConstArray(1:3,1)
391
CALL GetConstRealArray( CompParams, ConstArray, 'Rotation Matrix Alpha Reference', GotIt )
392
IF (.NOT. GotIt) CALL Fatal('GetElementRotM', 'Rotation Matrix Origin set but Rotation Matrix Alpha Reference not found!')
393
IF (SIZE(alpha_ref) /= 3) CALL Fatal('GetElementRotM', 'Rotation Matrix Alpha Reference needs three components!')
394
alpha_ref = ConstArray(1:3,1)
395
396
CALL GetConstRealArray( CompParams, ConstArray, 'Rotation Matrix Beta Reference', GotIt )
397
IF (.NOT. GotIt) CALL Fatal('GetElementRotM', 'Rotation Matrix Origin set but Rotation Matrix Beta Reference not found!')
398
IF (SIZE(beta_ref) /= 3) CALL Fatal('GetElementRotM', 'Rotation Matrix Beta Reference needs three components!')
399
beta_ref = ConstArray(1:3,1)
400
401
CALL GetElementNodes( Nodes )
402
DO j = 1, n
403
x(1) = Nodes % x(j)
404
x(2) = Nodes % y(j)
405
x(3) = Nodes % z(j)
406
407
r = beta_ref/SQRT(SUM(beta_ref**2.)) ! Normalize the rotation axis
408
409
xref = x - Origin ! take reference according to the origin of rotation
410
xref = xref - SUM(xref * r) * r ! project xref to the rotation plane (beta_ref is the normal)
411
C = SUM(xref * alpha_ref)/SQRT(SUM(xref**2.))/SQRT(SUM(alpha_ref**2.)) ! cosine of the angle of rotation
412
S = SQRT(1-C**2) ! sine of the angle of rotation
413
t = 1-C
414
415
RotM(1,1,j) = t*r(1)**2+C
416
RotM(1,2,j) = t*r(1)*r(2)-S*r(3)
417
RotM(1,3,j) = t*r(1)*r(3)+S*r(2)
418
419
RotM(2,1,j) = t*r(1)*r(2)+S*r(3)
420
RotM(2,2,j) = t*r(2)**2+C
421
RotM(2,3,j) = t*r(2)*r(3)-S*r(1)
422
423
RotM(3,1,j) = t*r(1)*r(3)-S*r(2)
424
RotM(3,2,j) = t*r(2)*r(3)+S*r(1)
425
RotM(3,3,j) = t*r(3)**2+C
426
END DO
427
! This is debug stuff (remove later if necessary)
428
! DO j = 1, n
429
! DO k=1,RotMvar % DOFs
430
! RotMvar % Values(RotMvar % DOFs*(&
431
! RotMvar % Perm(Element % DGIndexes(j))-1)+k) = RotM(ind1(k),ind2(k),j)
432
! END DO
433
!
434
! IF (ASSOCIATED(alphavecvar)) THEN
435
! x=(/1,1,1/)
436
! x=MATMUL(RotM(:,:,j),x)
437
! DO k=1,alphavecvar % DOFs
438
! alphavecvar % Values( alphavecvar % DOFs*(alphavecvar % Perm( &
439
! Element % DGIndexes(j))-1)+k) = x(k)
440
! END DO
441
! END IF
442
! END DO
443
ELSE
444
DO j = 1, n
445
DO k=1,RotMvar % DOFs
446
RotM(ind1(k),ind2(k),j) = RotMvar % Values( &
447
RotMvar % DOFs*(RotMvar % Perm(Element % DGIndexes(j))-1)+k)
448
END DO
449
END DO
450
END IF
451
452
! IF (SUM(Origin) == 0) THEN
453
! x(1) = 0
454
! x(2) = 1
455
! x(3) = 0
456
!
457
! r = beta_ref/SQRT(SUM(beta_ref**2.)) ! Normalize the rotation axis
458
!
459
! xref = x - Origin ! take reference according to the origin of rotation
460
! xref = xref - xref * beta_ref ! project xref to the rotation plane (beta_ref is the normal)
461
! C = SUM(xref * alpha_ref)/SQRT(SUM(xref**2.))/SQRT(SUM(alpha_ref**2.)) ! cosine of the angle of rotation
462
! S = SQRT(1-C**2) ! sine of the angle of rotation
463
! t = 1+C
464
!
465
! RotM(1,1,1) = t*r(1)**2+C
466
! RotM(1,2,1) = t*r(1)*r(2)-S*r(3)
467
! RotM(1,3,1) = t*r(1)*r(3)+S*r(2)
468
!
469
! RotM(2,1,1) = t*r(1)*r(2)+S*r(3)
470
! RotM(2,2,1) = t*r(2)**2+C
471
! RotM(2,3,1) = t*r(2)*r(3)-S*r(1)
472
!
473
! RotM(3,1,1) = t*r(1)*r(3)-S*r(2)
474
! RotM(3,2,1) = t*r(2)*r(3)+S*r(1)
475
! RotM(3,3,1) = t*r(3)**2+C
476
!
477
! x = MATMUL(RotM(:,:,1),x)
478
! print *, "RotM", RotM
479
! print *, "x", x
480
! END IF
481
! END IF
482
483
484
!------------------------------------------------------------------------------
485
END SUBROUTINE GetElementRotM
486
!------------------------------------------------------------------------------
487
488
!------------------------------------------------------------------------------
489
SUBROUTINE GetPermittivityR(Material,Acoef,n)
490
!------------------------------------------------------------------------------
491
IMPLICIT NONE
492
TYPE(ValueList_t), POINTER :: Material
493
INTEGER :: n
494
REAL(KIND=dp) :: Acoef(:)
495
!------------------------------------------------------------------------------
496
LOGICAL :: Found, FirstTime = .TRUE., Warned = .FALSE.
497
REAL(KIND=dp) :: Pvacuum
498
SAVE FirstTime, Warned, Pvacuum
499
!------------------------------------------------------------------------------
500
501
IF ( FirstTime ) THEN
502
Pvacuum = GetConstReal( CurrentModel % Constants, &
503
'Permittivity of Vacuum', Found )
504
IF (.NOT. Found) Pvacuum = 8.854187817d-12
505
FirstTime = .FALSE.
506
END IF
507
508
Acoef(1:n) = GetReal( Material, 'Relative Permittivity', Found )
509
IF ( Found ) THEN
510
Acoef(1:n) = Pvacuum * Acoef(1:n)
511
ELSE
512
Acoef(1:n) = GetReal( Material, 'Permittivity', Found )
513
END IF
514
515
IF( .NOT. Found ) THEN
516
IF(.NOT. Warned ) THEN
517
CALL Warn('GetPermittivity','Permittivity not defined in material, defaulting to that of vacuum')
518
Warned = .TRUE.
519
END IF
520
Acoef(1:n) = Pvacuum
521
END IF
522
!------------------------------------------------------------------------------
523
END SUBROUTINE GetPermittivityR
524
!------------------------------------------------------------------------------
525
526
!------------------------------------------------------------------------------
527
SUBROUTINE GetPermittivityC(Material,Acoef,n)
528
!------------------------------------------------------------------------------
529
IMPLICIT NONE
530
TYPE(ValueList_t), POINTER :: Material
531
INTEGER :: n
532
COMPLEX(KIND=dp) :: Acoef(:)
533
!------------------------------------------------------------------------------
534
LOGICAL :: Found, Found_im, FirstTime = .TRUE., Warned = .FALSE.
535
REAL(KIND=dp) :: Pvacuum
536
SAVE FirstTime, Warned, Pvacuum
537
REAL(KIND=dp), PARAMETER :: im = (0._dp, 1._dp)
538
!------------------------------------------------------------------------------
539
540
IF ( FirstTime ) THEN
541
Pvacuum = GetConstReal( CurrentModel % Constants, &
542
'Permittivity of Vacuum', Found )
543
IF (.NOT. Found) Pvacuum = 8.854187817d-12
544
FirstTime = .FALSE.
545
END IF
546
547
Acoef(1:n) = GetReal( Material, 'Relative Permittivity', Found )
548
IF ( Found ) THEN
549
Acoef(1:n) = Pvacuum * Acoef(1:n)
550
Acoef(1:n) = Acoef(1:n) + im * Pvacuum * &
551
GetReal(Material,'Relative Permittivity im', Found_im )
552
ELSE
553
Acoef(1:n) = GetReal( Material, 'Permittivity', Found )
554
Acoef(1:n) = Acoef(1:n) + im * &
555
GetReal(Material,'Permittivity im', Found_im )
556
END IF
557
558
IF( .NOT. Found ) THEN
559
IF(.NOT. Warned ) THEN
560
CALL Warn('GetPermittivity','Permittivity not defined in material, defaulting to that of vacuum')
561
Warned = .TRUE.
562
END IF
563
Acoef(1:n) = Pvacuum
564
END IF
565
!------------------------------------------------------------------------------
566
END SUBROUTINE GetPermittivityC
567
!------------------------------------------------------------------------------
568
569
570
!------------------------------------------------------------------------------
571
!> This gets keywords for a loss model that is needed by FourierLossSolver and
572
!> MagnetoDynamicsCalcFields. There is an old and new format.
573
!------------------------------------------------------------------------------
574
SUBROUTINE GetLossExponents(vList,FreqPower,FieldPower,Ncomp,OldKeywords)
575
!------------------------------------------------------------------------------
576
TYPE(ValueList_t),POINTER :: vList
577
REAL(KIND=dp) :: FreqPower(:), FieldPower(:)
578
INTEGER :: Ncomp
579
LOGICAL, OPTIONAL :: OldKeywords
580
581
REAL(KIND=dp), POINTER :: WrkArray(:,:)
582
LOGICAL :: Found
583
INTEGER :: icomp
584
CHARACTER(*), PARAMETER :: Caller = 'GetLossExponents'
585
586
IF( PRESENT(OldKeywords) ) THEN
587
IF( OldKeywords ) THEN
588
CALL Info('GetLossExponents','Using old keyword format',Level=20)
589
FreqPower(1) = GetCReal( vList,'Harmonic Loss Linear Frequency Exponent',Found )
590
IF( .NOT. Found ) FreqPower(1) = 1.0_dp
591
592
FreqPower(2) = GetCReal( vList,'Harmonic Loss Quadratic Frequency Exponent',Found )
593
IF( .NOT. Found ) FreqPower(2) = 2.0_dp
594
595
FieldPower(1) = GetCReal( vList,'Harmonic Loss Linear Exponent',Found )
596
IF( .NOT. Found ) FieldPower(1) = 2.0_dp
597
FieldPower(1) = FieldPower(1) / 2.0_dp
598
599
FieldPower(2) = GetCReal( vList,'Harmonic Loss Quadratic Exponent',Found )
600
IF( .NOT. Found ) FieldPower(2) = 2.0_dp
601
FieldPower(2) = FieldPower(2) / 2.0_dp
602
RETURN
603
ELSE
604
CALL Info('GetLossExponents','Using new keyword format',Level=20)
605
END IF
606
END IF
607
608
WrkArray => ListGetConstRealArray( vList,'Harmonic Loss Frequency Exponent',Found )
609
IF( Found ) THEN
610
IF( SIZE( WrkArray,1 ) < Ncomp ) THEN
611
CALL Fatal(Caller,'> Harmonic Loss Frequency Exponent < too small')
612
END IF
613
FreqPower(1:Ncomp) = WrkArray(1:Ncomp,1)
614
ELSE
615
DO icomp = 1, Ncomp
616
FreqPower(icomp) = GetCReal( vList,'Harmonic Loss Frequency Exponent '//I2S(icomp) )
617
END DO
618
END IF
619
620
WrkArray => ListGetConstRealArray( vList,'Harmonic Loss Field Exponent',Found )
621
IF( Found ) THEN
622
IF( SIZE( WrkArray,1 ) < Ncomp ) THEN
623
CALL Fatal(Caller,'> Harmonic Loss Field Exponent < too small')
624
END IF
625
FieldPower(1:Ncomp) = WrkArray(1:Ncomp,1)
626
ELSE
627
DO icomp = 1, Ncomp
628
FieldPower(icomp) = GetCReal( vList,'Harmonic Loss Field Exponent '//I2S(icomp) )
629
END DO
630
END IF
631
632
END SUBROUTINE GetLossExponents
633
634
635
!------------------------------------------------------------------------------
636
END MODULE MGDynMaterialUtils
637
!------------------------------------------------------------------------------
638
639