Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/obsolete/MovingElstatSolver.F90
5255 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 program is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU General Public License
9
! * as published by the Free Software Foundation; either version 2
10
! * of the License, or (at your option) any later version.
11
! *
12
! * This program 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
15
! * GNU General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU General Public License
18
! * along with this program (in file fem/GPL-2); if not, write to the
19
! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
! * Boston, MA 02110-1301, USA.
21
! *
22
! *****************************************************************************/
23
!
24
!/******************************************************************************
25
! *
26
! * Authors: Peter RÃ¥back
27
! * Email: Peter.Rabackcsc.fi
28
! * Web: http://www.csc.fi/elmer
29
! * Address: CSC - IT Center for Science Ltd.
30
! * Keilaranta 14
31
! * 02101 Espoo, Finland
32
! *
33
! * Original Date: 8.2.2006
34
! *
35
! ******************************************************************************/
36
37
!------------------------------------------------------------------------------
38
!> Solver for the computation the capacitance and sensitivity of capacitance for
39
!> a rigid system with rotations and translations. The solver includes features
40
!> of electrostatics and mesh solver within one solver and its usability is limited
41
!> to cartesian coordinates. Probably of very limited use.
42
!> \ingroup Solvers
43
!------------------------------------------------------------------------------
44
SUBROUTINE MovingElstatSolver( Model,Solver,dt,TransientSimulation )
45
!------------------------------------------------------------------------------
46
47
USE Types
48
USE Lists
49
USE Integration
50
USE ElementDescription
51
USE Differentials
52
USE SolverUtils
53
USE ElementUtils
54
USE DefUtils
55
56
IMPLICIT NONE
57
!------------------------------------------------------------------------------
58
59
TYPE(Model_t) :: Model
60
TYPE(Solver_t), TARGET:: Solver
61
REAL (KIND=DP) :: dt
62
LOGICAL :: TransientSimulation
63
64
!------------------------------------------------------------------------------
65
! Local variables
66
!------------------------------------------------------------------------------
67
TYPE(Matrix_t), POINTER :: StiffMatrix
68
TYPE(Element_t), POINTER :: CurrentElement, Parent
69
TYPE(Variable_t), POINTER :: Var
70
TYPE(Nodes_t) :: ElementNodes, ParentNodes
71
72
REAL (KIND=DP), POINTER :: Coordinate(:), Displacement(:,:), ForceVector(:), Coords(:), Component(:), &
73
xorig(:), yorig(:), zorig(:), ElemPotential(:), Parray(:,:)
74
REAL (KIND=DP), ALLOCATABLE :: LocalStiffMatrix(:,:), LocalForce(:), &
75
xnew(:), ynew(:), znew(:), MatrixValues(:), &
76
Basis(:),dBasisdx(:,:),ddBasisddx(:,:,:), AplacResults(:,:), &
77
ParentBasis(:),ParentdBasisdx(:,:),xelem(:),yelem(:),zelem(:)
78
REAL (KIND=DP) :: Norm, at, st, val, Normal(3), MinMaxEdge(3,2), Eps, aid, &
79
da, ds, Dx(6), Dx0(6), Rotate(3,3), Point(3), Displace(3), Translate(3), Center(3), &
80
TotCapac, ElemCapac, PermittivityOfVacuum, Base(6,6), Limits(6,2), Amplitude(6), &
81
TotForce(3), TotMoment(3), TotArea, TotCharge, TotTime, MinMaxMoving(3,2), &
82
SectionCapac(3,2), Dist, LengthScale
83
INTEGER, POINTER :: NodeIndexes(:), CoordinatePerm(:)
84
INTEGER, ALLOCATABLE :: ElementNormals(:)
85
INTEGER :: i, j, k, n, t, istat, bf_id, MeshNodes, DIM, coord, Visited = 0, &
86
Intervals(6), Counter(6), i1, i2, i3, i4, i5, i6, TableDim, pn, Cases, &
87
VerticalCoordinate, PeriodicCoordinate
88
LOGICAL :: AllocationsDone = .FALSE., gotIt, stat, SaveCoords, MovingEdge(3,2), DoRotate(3), &
89
CalculateMoment, CalculateForce, Debug, DoTranslate(3), MappedCoordinates, SetPoint
90
LOGICAL, POINTER :: MovingNodes(:)
91
CHARACTER(LEN=MAX_NAME_LEN) :: FileName
92
93
CHARACTER(LEN=MAX_NAME_LEN) :: VariableName
94
95
SAVE LocalStiffMatrix, LocalForce, ElementNodes, AllocationsDone, &
96
xnew, ynew, znew, ElementNormals, ParentNodes, &
97
Coords, SaveCoords, MinMaxEdge, MovingEdge, Eps, MeshNodes, &
98
MatrixValues, Visited, Basis, dBasisdx, ddBasisddx, ElemPotential, &
99
ParentBasis, ParentdBasisdx, MovingNodes, MinMaxMoving, &
100
xelem, yelem, zelem, CalculateMoment, CalculateForce, VerticalCoordinate, &
101
PeriodicCoordinate, LengthScale, Filename
102
103
!------------------------------------------------------------------------------
104
105
CALL Info( 'MovingElstatSolver', '-------------------------------------',Level=4 )
106
CALL Info( 'MovingElstatSolver', 'Rigid body coordinate update solver: ', Level=4 )
107
CALL Info( 'MovingElstatSolver', '-------------------------------------',Level=4 )
108
109
110
!------------------------------------------------------------------------------
111
! Get variables needed for solution
112
!------------------------------------------------------------------------------
113
Coordinate => Solver % Variable % Values
114
CoordinatePerm => Solver % Variable % Perm
115
116
StiffMatrix => Solver % Matrix
117
ForceVector => StiffMatrix % RHS
118
119
Norm = Solver % Variable % Norm
120
DIM = CoordinateSystemDimension()
121
122
xorig => Solver % Mesh % Nodes % x
123
yorig => Solver % Mesh % Nodes % y
124
zorig => Solver % Mesh % Nodes % z
125
126
!------------------------------------------------------------------------------
127
! Allocate some permanent storage, this is done first time only
128
!------------------------------------------------------------------------------
129
IF ( .NOT. AllocationsDone ) THEN
130
N = Model % MaxElementNodes
131
MeshNodes = SIZE(Solver % Mesh % Nodes % x)
132
133
ALLOCATE( ElementNodes % x(N), &
134
ElementNodes % y(N), &
135
ElementNodes % z(N), &
136
ParentNodes % x(N), &
137
ParentNodes % y(N), &
138
ParentNodes % z(N), &
139
ElemPotential(N), &
140
LocalForce(N), &
141
LocalStiffMatrix(N,N), &
142
Basis(n), &
143
dBasisdx(n,3), &
144
ddBasisddx(n,3,3), &
145
ParentBasis(n), &
146
ParentdBasisdx(n,3), &
147
xelem(n), &
148
yelem(n), &
149
zelem(n), &
150
xnew(MeshNodes), &
151
ynew(MeshNodes), &
152
znew(MeshNodes), &
153
MovingNodes(MeshNodes), &
154
ElementNormals(Solver % Mesh % NumberOfBoundaryElements), &
155
MatrixValues(SIZE(StiffMatrix % Values)), &
156
STAT=istat )
157
158
IF ( istat /= 0 ) THEN
159
CALL Fatal( 'MovingElstatSolver', 'Memory allocation error 1' )
160
END IF
161
162
!------------------------------------------------------------------------------
163
! Check whether the new coordinates should be saved
164
!------------------------------------------------------------------------------
165
SaveCoords = ListGetLogical(Solver % Values,'Save Displacements',GotIt)
166
IF(SaveCoords) THEN
167
ALLOCATE(Coords(3*MeshNodes))
168
Coords = 0.0d0
169
CALL VariableAddVector( Solver % Mesh % Variables, Solver % Mesh, Solver, 'dCoords',3,Coords)
170
END IF
171
172
AllocationsDone = .TRUE.
173
END IF
174
175
176
TotTime = CPUTime()
177
178
IF(Visited == 0) THEN
179
180
!------------------------------------------------------------------------------
181
! Read some control stuff
182
!------------------------------------------------------------------------------
183
184
CalculateMoment = ListGetLogical(Solver % Values,'Calculate Moment',GotIt)
185
CalculateForce = CalculateMoment .OR. ListGetLogical(Solver % Values,'Calculate Force',GotIt)
186
187
VerticalCoordinate = ListGetInteger(Solver % Values,'Vertical Coordinate',GotIt)
188
IF(.NOT. GotIt) VerticalCoordinate = 3
189
PeriodicCoordinate = ListGetInteger(Solver % Values,'Periodic Coordinate',GotIt)
190
IF(.NOT. GotIt) PeriodicCoordinate = 1
191
192
LengthScale = ListGetConstReal(Solver % Values,'Length Scale',GotIt)
193
IF(.NOT. GotIt) LengthScale = 1.0d0
194
195
FileName = ListGetString(Solver % Values,'Filename',GotIt )
196
IF(.NOT. GotIt) FileName = 'lumped.dat'
197
198
!------------------------------------------------------------------------------
199
! Check directions of surface normals and memorize the moving nodes
200
!------------------------------------------------------------------------------
201
202
ElementNormals = 0
203
MovingNodes = .FALSE.
204
205
DO t = Solver % Mesh % NumberOfBulkElements + 1, &
206
Solver % Mesh % NumberOfBulkElements + Solver % Mesh % NumberOfBoundaryElements
207
208
CurrentElement => Solver % Mesh % Elements(t)
209
NodeIndexes => CurrentElement % NodeIndexes
210
n = CurrentElement % TYPE % NumberOfNodes
211
212
ElementNodes % x(1:n) = xorig(NodeIndexes)
213
ElementNodes % y(1:n) = yorig(NodeIndexes)
214
ElementNodes % z(1:n) = zorig(NodeIndexes)
215
216
Model % CurrentElement => CurrentElement
217
j = t - Solver % Mesh % NumberOfBulkElements
218
219
Normal = NormalVector(CurrentElement,ElementNodes,0.0d0,0.0d0)
220
221
DO coord = 1, 3
222
IF(ABS(Normal(coord)) > 1.0 - 1.0d-3) ElementNormals(j) = coord
223
END DO
224
225
DO j=1,Model % NumberOfBCs
226
IF ( CurrentElement % BoundaryInfo % Constraint == &
227
Model % BCs(j) % Tag ) THEN
228
229
IF ( ListGetLogical(Model % BCs(j) % Values,'Moving Boundary',gotIt) ) THEN
230
MovingNodes(NodeIndexes) = .TRUE.
231
END IF
232
END IF
233
END DO
234
235
END DO
236
237
!------------------------------------------------------------------------------
238
! Find the edges of the cartesian domain
239
!------------------------------------------------------------------------------
240
MinMaxEdge(:,1) = HUGE(MinMaxEdge(:,1))
241
MinMaxEdge(:,2) = -HUGE(MinMaxEdge(:,2))
242
MinMaxMoving = MinMaxEdge
243
244
DO i = 1, MeshNodes
245
IF(CoordinatePerm(i) == 0) CYCLE
246
MinMaxEdge(1,1) = MIN( MinMaxEdge(1,1), xorig(i) )
247
MinMaxEdge(1,2) = MAX( MinMaxEdge(1,2), xorig(i) )
248
MinMaxEdge(2,1) = MIN( MinMaxEdge(2,1), yorig(i) )
249
MinMaxEdge(2,2) = MAX( MinMaxEdge(2,2), yorig(i) )
250
MinMaxEdge(3,1) = MIN( MinMaxEdge(3,1), zorig(i) )
251
MinMaxEdge(3,2) = MAX( MinMaxEdge(3,2), zorig(i) )
252
253
IF(.NOT. MovingNodes(i) ) CYCLE
254
MinMaxMoving(1,1) = MIN( MinMaxMoving(1,1), xorig(i) )
255
MinMaxMoving(1,2) = MAX( MinMaxMoving(1,2), xorig(i) )
256
MinMaxMoving(2,1) = MIN( MinMaxMoving(2,1), yorig(i) )
257
MinMaxMoving(2,2) = MAX( MinMaxMoving(2,2), yorig(i) )
258
MinMaxMoving(3,1) = MIN( MinMaxMoving(3,1), zorig(i) )
259
MinMaxMoving(3,2) = MAX( MinMaxMoving(3,2), zorig(i) )
260
END DO
261
262
Eps = 1.0d-8 * SQRT( (MinMaxEdge(1,1)-MinMaxEdge(1,2))**2 + &
263
(MinMaxEdge(2,1)-MinMaxEdge(2,2))**2 + &
264
(MinMaxEdge(3,1)-MinMaxEdge(3,2))**2 )
265
266
!------------------------------------------------------------------------------
267
! If edge is not moving with Displacement it is assumed to be fixed
268
! Also periodic coordinate direction is assumed to be fixed.
269
!------------------------------------------------------------------------------
270
MovingEdge = .FALSE.
271
DO i=1,3
272
DO j=1,2
273
IF( ABS( MinMaxEdge(i,j) - MinMaxMoving(i,j) ) < Eps) MovingEdge(i,j) = .TRUE.
274
END DO
275
END DO
276
277
IF(PeriodicCoordinate > 0) THEN
278
MovingEdge(PeriodicCoordinate,1:2) = .FALSE.
279
END IF
280
281
PRINT *,'Epsilon',Eps
282
PRINT *,'MinMaxEdge',MinMaxEdge
283
PRINT *,'MinMaxMoving',MinMaxMoving
284
PRINT *,'Moving',MovingEdge
285
286
!------------------------------------------------------------------------------
287
! Assembly the Laplace operator and save it for repetitious use
288
!------------------------------------------------------------------------------
289
at = CPUTime()
290
LocalForce = 0.0d0
291
CALL InitializeToZero( StiffMatrix, ForceVector )
292
293
DO t = 1, Solver % NumberOfActiveElements
294
295
CurrentElement => Solver % Mesh % Elements(Solver % ActiveElements(t))
296
NodeIndexes => CurrentElement % NodeIndexes
297
n = CurrentElement % TYPE % NumberOfNodes
298
299
ElementNodes % x(1:n) = xorig(NodeIndexes)
300
ElementNodes % y(1:n) = yorig(NodeIndexes)
301
ElementNodes % z(1:n) = zorig(NodeIndexes)
302
303
Model % CurrentElement => CurrentElement
304
305
CALL LaplaceCompose( LocalStiffMatrix,CurrentElement,n,ElementNodes)
306
307
CALL UpdateGlobalEquations( StiffMatrix,LocalStiffMatrix, &
308
ForceVector, LocalForce,n,1,CoordinatePerm(NodeIndexes) )
309
END DO
310
311
CALL FinishAssembly( Solver,ForceVector )
312
313
WRITE( Message, * ) 'Bulk Assembly (s) :',CPUTime() - at
314
CALL Info( 'MovingElstatSolver', Message, Level=4 )
315
316
MatrixValues = StiffMatrix % Values
317
END IF
318
319
!------------------------------------------------------------------------------
320
! Get the rules for rigid displacement
321
!------------------------------------------------------------------------------
322
Center(1) = ListGetConstReal( Model % Simulation,'Moment About 1', GotIt )
323
IF(.NOT. GotIt) Center(1) = ListGetConstReal( Solver % Values,'Moment About 1', GotIt )
324
IF(.NOT. GotIt) Center(1) = ListGetConstReal( Model % Simulation,'res: Center of Mass 1')
325
Center(2) = ListGetConstReal( Model % Simulation,'Moment About 2', GotIt )
326
IF(.NOT. GotIt) Center(2) = ListGetConstReal( Solver % Values,'Moment About 2', GotIt )
327
IF(.NOT. GotIt) Center(2) = ListGetConstReal( Model % Simulation,'res: Center of Mass 2')
328
Center(3) = ListGetConstReal( Model % Simulation,'Moment About 3', GotIt )
329
IF(.NOT. GotIt) Center(3) = ListGetConstReal( Solver % Values,'Moment About 3', GotIt )
330
IF(.NOT. GotIt) Center(3) = ListGetConstReal( Model % Simulation,'res: Center of Mass 3')
331
332
Base = 0.0d0
333
Limits = 0.0d0
334
Intervals = 1
335
TableDim = 0
336
Cases = 1
337
338
DO i=1,6
339
PArray => ListGetConstRealArray( Solver % Values,'Lumping Basis '//CHAR(i+ICHAR('0')),GotIt)
340
IF(GotIt) THEN
341
Base(i,1:6) = Parray(1:6,1)
342
ELSE
343
Base(i,i) = 1.0d0
344
END IF
345
346
PArray => ListGetConstRealArray( Solver % Values,'Lumping Limits '//CHAR(i+ICHAR('0')),GotIt)
347
IF(GotIt) Limits(i,1:2) = Parray(1:2,1)
348
349
Intervals(i) = ListGetInteger( Solver % Values,'Lumping Points '//CHAR(i+ICHAR('0')),GotIt)
350
Intervals(i) = MAX(1,Intervals(i))
351
Cases = Cases * Intervals(i)
352
IF(Intervals(i) > 1) TableDim = TableDim + 1
353
END DO
354
355
IF(TableDim == 1) THEN
356
ALLOCATE( AplacResults(Cases, 2) )
357
END IF
358
359
!------------------------------------------------------------------------------
360
! Write a file with metainformation of the lumping procedure
361
!------------------------------------------------------------------------------
362
OPEN (10, FILE=TRIM(FileName)//'.info')
363
WRITE(10,*) 'Information for lumped electrostatics'
364
WRITE(10,*) '*************************************'
365
WRITE(10,*)
366
WRITE(10,*) 'Lumping base'
367
DO i=1,6
368
WRITE(10,*) Base(i,1:6)
369
END DO
370
371
WRITE(10,*)
372
WRITE(10,*) 'Lumping Interval and Limits'
373
DO i=1,6
374
WRITE(10,*) Intervals(i), Limits(i,1:2)
375
END DO
376
377
WRITE(10,*)
378
WRITE(10,*) 'Center of coordinate'
379
WRITE(10,*) Center
380
381
j = 0
382
WRITE(10,*)
383
WRITE(10,*) 'Columns in file: ',TRIM(FileName)
384
DO i=1,6
385
IF(Intervals(i) > 1) THEN
386
j = j + 1
387
WRITE(10,*) j,': Amplitude of base',i
388
END IF
389
END DO
390
WRITE(10,*) j+1,': C'
391
WRITE(10,*) j+2,': Cup'
392
WRITE(10,*) j+3,': Cdown'
393
IF(CalculateForce) THEN
394
WRITE(10,*) j+4,': C (surface)'
395
WRITE(10,*) j+5,': dC/dx'
396
WRITE(10,*) j+6,': dC/dy'
397
WRITE(10,*) j+7,': dC/dz'
398
END IF
399
IF(CalculateMoment) THEN
400
WRITE(10,*) j+8,': Mx'
401
WRITE(10,*) j+9,': My'
402
WRITE(10,*) j+10,': Mz'
403
END IF
404
405
WRITE(10,*)
406
WRITE(10,*) 'Degrees of Freedom',SIZE(Coordinate)
407
408
CLOSE(10)
409
410
411
!------------------------------------------------------------------------------
412
! Loop over all possible combinations of displacement
413
!------------------------------------------------------------------------------
414
Cases = 0
415
DO i1 = 1, Intervals(1)
416
DO i2 = 1, Intervals(2)
417
DO i3 = 1, Intervals(3)
418
DO i4 = 1, Intervals(4)
419
DO i5 = 1, Intervals(5)
420
DO i6 = 1, Intervals(6)
421
422
Counter(1) = i1
423
Counter(2) = i2
424
Counter(3) = i3
425
Counter(4) = i4
426
Counter(5) = i5
427
Counter(6) = i6
428
429
Cases = Cases + 1
430
431
Dx = 0.0d0
432
DO i=1,6
433
Amplitude(i) = Limits(i,1)
434
IF(Counter(i) > 1) THEN
435
Amplitude(i) = Amplitude(i) + (Counter(i)-1) * (Limits(i,2)-Limits(i,1)) / (Intervals(i)-1)
436
END IF
437
Dx = Dx + Base(i,:) * Amplitude(i)
438
END DO
439
440
Translate(1:3) = Dx(1:3)
441
Rotate = 0.0d0
442
Rotate(1,2) = Dx(6)
443
Rotate(1,3) = -Dx(5)
444
Rotate(2,3) = Dx(4)
445
446
DO i=1,3
447
DO j=i+1,3
448
Rotate(j,i) = -Rotate(i,j)
449
END DO
450
END DO
451
452
DoTranslate = (ABS(Dx(1:3)) > 1.0d-20)
453
DO i=1,3
454
DoRotate(i) = ANY( ABS(Rotate(i,1:3)) > 1.0d-20 )
455
END DO
456
457
!------------------------------------------------------------------------------
458
! Go through the coordinates separately and set the following BCs
459
! 1) Set nodes attached to rigid bodies
460
! 2) Set the normal component of all other boundaries to zero
461
! 3) Set the normal component of the whole frame to zero
462
!------------------------------------------------------------------------------
463
464
MappedCoordinates = .FALSE.
465
466
DO coord = 1, DIM
467
468
IF(.NOT. ( DoTranslate(coord) .OR. DoRotate(coord) ) ) THEN
469
IF(coord == 1) xnew = xorig
470
IF(coord == 2) ynew = yorig
471
IF(coord == 3) znew = zorig
472
WRITE(Message,'(a,i1)' ) 'No need to map coordinate ',coord
473
CALL Info( 'MovingElstatSolver', Message, Level=4 )
474
CYCLE
475
END IF
476
477
MappedCoordinates = .TRUE.
478
WRITE(Message,'(a,i1)' ) 'Mapping coordinate ',coord
479
CALL Info( 'MovingElstatSolver', Message, Level=4 )
480
at = CPUTime()
481
482
StiffMatrix % Values = MatrixValues
483
ForceVector = 0.0d0
484
485
!------------------------------------------------------------------------------
486
! Fix displacements to normal direction
487
! and for the whole moving part in case of rotation
488
!------------------------------------------------------------------------------
489
490
DO t = Solver % Mesh % NumberOfBulkElements + 1, &
491
Solver % Mesh % NumberOfBulkElements + Solver % Mesh % NumberOfBoundaryElements
492
493
CurrentElement => Solver % Mesh % Elements(t)
494
NodeIndexes => CurrentElement % NodeIndexes
495
n = CurrentElement % TYPE % NumberOfNodes
496
k = t - Solver % Mesh % NumberOfBulkElements
497
498
DO j=1,Model % NumberOfBCs
499
IF ( CurrentElement % BoundaryInfo % Constraint == &
500
Model % BCs(j) % Tag ) THEN
501
502
IF ( ListGetLogical(Model % BCs(j) % Values,'Moving Boundary',gotIt) ) THEN
503
504
IF(ElementNormals(k) == 0 .OR. ElementNormals(k) == coord) THEN
505
! Fix displacement in normal direction and to unclear direction
506
SetPoint = .TRUE.
507
ELSE IF( DoRotate(ElementNormals(k)) ) THEN
508
! If normal direction is not constant fix the others too
509
SetPoint = .TRUE.
510
ELSE
511
SetPoint = .FALSE.
512
END IF
513
514
IF( SetPoint ) THEN
515
DO i = 1, n
516
Point(1) = xorig(NodeIndexes(i))
517
Point(2) = yorig(NodeIndexes(i))
518
Point(3) = zorig(NodeIndexes(i))
519
520
Point = Point - Center
521
Displace = Translate + MATMUL(Rotate,Point)
522
523
val = Displace(coord)
524
525
CALL SetDirichletPoint( StiffMatrix, ForceVector,1,1, &
526
CoordinatePerm, NodeIndexes(i), val)
527
END DO
528
END IF
529
ELSE IF( ListGetLogical(Model % BCs(j) % Values,'Fixed Boundary',gotIt) ) THEN
530
IF( ElementNormals(k) == 0 .OR. ElementNormals(k) == coord ) THEN
531
val = 0.0d0
532
DO i = 1, n
533
CALL SetDirichletPoint( StiffMatrix, ForceVector,1,1, &
534
CoordinatePerm, NodeIndexes(i), val)
535
END DO
536
END IF
537
END IF
538
539
END IF
540
END DO
541
END DO
542
543
!------------------------------------------------------------------------------
544
! Fix the movement of the whole frame in the normal direction
545
!------------------------------------------------------------------------------
546
547
DO i = 1, MeshNodes
548
IF( CoordinatePerm(i) == 0 ) CYCLE
549
550
Point(1) = xorig(i)
551
Point(2) = yorig(i)
552
Point(3) = zorig(i)
553
554
DO j= 1,2
555
IF( ABS( MinMaxEdge(coord,j) - Point(coord) ) < Eps) THEN
556
557
! In case of displaced frame only account for the translation
558
! This will ensure that the box remains a box
559
IF( MovingEdge(coord,j)) THEN
560
val = Translate(coord)
561
ELSE
562
val = 0.0d0
563
END IF
564
565
CALL SetDirichletPoint( StiffMatrix, ForceVector,1,1, &
566
CoordinatePerm, i, val)
567
END IF
568
END DO
569
END DO
570
571
572
at = CPUTime() - at
573
WRITE( Message, * ) 'Boundary Assembly (s) :',at
574
CALL Info( 'MovingElstatSolver', Message, Level=4 )
575
576
!------------------------------------------------------------------------------
577
! Solve the system
578
!------------------------------------------------------------------------------
579
st = CPUTime()
580
CALL SolveSystem( StiffMatrix, ParMatrix, ForceVector, &
581
Coordinate, Norm, 1, Solver )
582
st = CPUTime() - st
583
WRITE( Message, * ) 'Solve (s) :',st
584
CALL Info( 'MovingElstatSolver', Message, Level=4 )
585
586
!------------------------------------------------------------------------------
587
! Add the displacement to the coordinate values
588
!------------------------------------------------------------------------------
589
DO i=1,MeshNodes
590
j = CoordinatePerm(i)
591
IF(j > 0) THEN
592
IF(coord == 1) xnew(i) = xorig(i) + Coordinate(j)
593
IF(coord == 2) ynew(i) = yorig(i) + Coordinate(j)
594
IF(coord == 3) znew(i) = zorig(i) + Coordinate(j)
595
IF(SaveCoords) Coords(DIM*(i-1)+coord) = Coordinate(j)
596
END IF
597
END DO
598
599
END DO
600
601
CALL Info('MovingElstatSolver','Coordinates updated')
602
603
Visited = Visited + 1
604
605
!------------------------------------------------------------------------------
606
! Assembly the electrostatic Equation
607
!------------------------------------------------------------------------------
608
at = CPUTime()
609
610
IF(.NOT. MappedCoordinates) THEN
611
CALL Info('MovingElstatSolver','Using original matrix for potential equation')
612
StiffMatrix % Values = MatrixValues
613
ELSE
614
CALL Info('MovingElstatSolver','Assembling the potential equation')
615
LocalForce = 0.0d0
616
CALL InitializeToZero( StiffMatrix, ForceVector )
617
618
DO t = 1, Solver % NumberOfActiveElements
619
620
CurrentElement => Solver % Mesh % Elements(Solver % ActiveElements(t))
621
NodeIndexes => CurrentElement % NodeIndexes
622
n = CurrentElement % TYPE % NumberOfNodes
623
624
ElementNodes % x(1:n) = xnew(NodeIndexes)
625
ElementNodes % y(1:n) = ynew(NodeIndexes)
626
ElementNodes % z(1:n) = znew(NodeIndexes)
627
628
Model % CurrentElement => CurrentElement
629
630
CALL LaplaceCompose( LocalStiffMatrix,CurrentElement,n,ElementNodes)
631
632
CALL UpdateGlobalEquations( StiffMatrix,LocalStiffMatrix, &
633
ForceVector, LocalForce,n,1,CoordinatePerm(NodeIndexes) )
634
END DO
635
END IF
636
637
638
!------------------------------------------------------------------------------
639
! Set the Boundary conditions to be either zero or one
640
!------------------------------------------------------------------------------
641
642
DO t = Solver % Mesh % NumberOfBulkElements + 1, &
643
Solver % Mesh % NumberOfBulkElements + Solver % Mesh % NumberOfBoundaryElements
644
645
CurrentElement => Solver % Mesh % Elements(t)
646
NodeIndexes => CurrentElement % NodeIndexes
647
n = CurrentElement % TYPE % NumberOfNodes
648
649
DO j=1,Model % NumberOfBCs
650
IF ( CurrentElement % BoundaryInfo % Constraint == &
651
Model % BCs(j) % Tag ) THEN
652
653
IF( ListGetLogical(Model % BCs(j) % Values, &
654
'Moving Boundary',gotIt) ) THEN
655
val = 1.0d0
656
DO i = 1, n
657
CALL SetDirichletPoint( StiffMatrix, ForceVector,1,1, &
658
CoordinatePerm, NodeIndexes(i), val)
659
END DO
660
ELSE IF( ListGetLogical(Model % BCs(j) % Values, &
661
'Fixed Boundary',gotIt) ) THEN
662
val = 0.0d0
663
DO i = 1, n
664
CALL SetDirichletPoint( StiffMatrix, ForceVector,1,1, &
665
CoordinatePerm, NodeIndexes(i), val)
666
END DO
667
END IF
668
669
END IF
670
END DO
671
END DO
672
673
674
CALL FinishAssembly( Solver,ForceVector )
675
676
!------------------------------------------------------------------------------
677
! Dirichlet boundary conditions (symmetry)
678
!------------------------------------------------------------------------------
679
CALL SetDirichletBoundaries( Model,StiffMatrix,ForceVector, &
680
ComponentName(Solver % Variable),1,1,CoordinatePerm )
681
682
683
WRITE( Message, * ) 'Bulk Assembly (s) :',CPUTime() - at
684
CALL Info( 'MovingElstatSolver', Message, Level=4 )
685
686
!------------------------------------------------------------------------------
687
! Solve the system
688
!------------------------------------------------------------------------------
689
st = CPUTime()
690
CALL SolveSystem( StiffMatrix, ParMatrix, ForceVector, Coordinate, Norm, 1, Solver )
691
st = CPUTime() - st
692
WRITE( Message, * ) 'Solve (s) :',st
693
CALL Info( 'MovingElstatSolver', Message, Level=4 )
694
695
!------------------------------------------------------------------------------
696
! Calculate Electric Capacitance From Volume Integral
697
!------------------------------------------------------------------------------
698
699
TotCapac = 0.0d0
700
SectionCapac = 0.0d0
701
702
DO t = 1, Solver % NumberOfActiveElements
703
CurrentElement => Solver % Mesh % Elements(Solver % ActiveElements(t))
704
NodeIndexes => CurrentElement % NodeIndexes
705
n = CurrentElement % TYPE % NumberOfNodes
706
707
ElementNodes % x(1:n) = xnew(NodeIndexes)
708
ElementNodes % y(1:n) = ynew(NodeIndexes)
709
ElementNodes % z(1:n) = znew(NodeIndexes)
710
711
Model % CurrentElement => CurrentElement
712
ElemPotential(1:n) = Coordinate(CoordinatePerm(NodeIndexes))
713
714
ElemCapac = ElementEnergy(CurrentElement, n, ElementNodes, ElemPotential)
715
TotCapac = TotCapac + ElemCapac
716
END DO
717
718
PermittivityOfVacuum = ListGetConstReal( Model % Constants, &
719
'Permittivity Of Vacuum',gotIt )
720
IF ( .NOT.gotIt ) PermittivityOfVacuum = 1.0d0
721
722
TotCapac = PermittivityOfVacuum * TotCapac
723
PRINT *,'Dx',Dx
724
PRINT *,'Capacitance',TotCapac
725
PRINT *,'SectionCapac',SectionCapac
726
727
!------------------------------------------------------------------------------
728
! Calculate Electric Force and Charge from Surface Integral
729
!------------------------------------------------------------------------------
730
731
IF(CalculateForce .OR. CalculateMoment) THEN
732
TotForce = 0.0d0
733
TotMoment = 0.0d0
734
TotArea = 0.0d0
735
TotCharge = 0.0d0
736
737
DO t = Solver % Mesh % NumberOfBulkElements + 1, &
738
Solver % Mesh % NumberOfBulkElements + Solver % Mesh % NumberOfBoundaryElements
739
740
CurrentElement => Solver % Mesh % Elements(t)
741
742
DO j=1,Model % NumberOfBCs
743
IF ( CurrentElement % BoundaryInfo % Constraint == Model % BCs(j) % Tag ) THEN
744
745
IF( .NOT. ListGetLogical(Model % BCs(j) % Values,'Moving Boundary',gotIt)) CYCLE
746
747
NodeIndexes => CurrentElement % NodeIndexes
748
IF( ANY (CoordinatePerm(NodeIndexes) == 0 ) ) CYCLE
749
750
n = CurrentElement % TYPE % NumberOfNodes
751
Model % CurrentElement => CurrentElement
752
753
ElementNodes % x(1:n) = xnew(NodeIndexes)
754
ElementNodes % y(1:n) = ynew(NodeIndexes)
755
ElementNodes % z(1:n) = znew(NodeIndexes)
756
757
!------------------------------------------------------------------------------
758
! Need parent element to determine the derivative at the surface
759
!------------------------------------------------------------------------------
760
Parent => CurrentElement % BoundaryInfo % Left
761
stat = ASSOCIATED( Parent )
762
IF ( stat ) stat = ALL (CoordinatePerm(Parent % NodeIndexes) > 0 )
763
764
IF ( .NOT. stat ) THEN
765
Parent => CurrentElement % BoundaryInfo % Right
766
stat = ASSOCIATED( Parent)
767
IF(stat) stat = ALL (CoordinatePerm(Parent % NodeIndexes) > 0 )
768
END IF
769
770
IF(.NOT. stat) CYCLE
771
772
pn = Parent % TYPE % NumberOfNodes
773
ParentNodes % x(1:pn) = xnew(Parent % NodeIndexes)
774
ParentNodes % y(1:pn) = ynew(Parent % NodeIndexes)
775
ParentNodes % z(1:pn) = znew(Parent % NodeIndexes)
776
777
ElemPotential(1:pn) = Coordinate( CoordinatePerm( Parent % NodeIndexes ) )
778
CALL ElectricForceIntegrate( TotForce, TotMoment, TotArea, TotCharge )
779
780
END IF
781
END DO
782
END DO
783
784
TotCharge = -PermittivityOfVacuum * TotCharge
785
TotForce = 2.0d0 * PermittivityOfVacuum * TotForce
786
TotMoment = PermittivityOfVacuum * TotMoment
787
TotArea = TotArea
788
789
PRINT *,'Charge',TotCharge
790
PRINT *,'dC/dx',TotForce
791
IF(CalculateMoment) PRINT *,'Moment',TotMoment
792
PRINT *,'Area',TotArea
793
END IF
794
795
796
!------------------------------------------------------------------------------
797
! Save results in matrix format
798
!------------------------------------------------------------------------------
799
IF(Cases == 1) THEN
800
OPEN (10, FILE=TRIM(FileName))
801
ELSE
802
OPEN (10, FILE=TRIM(FileName), POSITION='APPEND')
803
END IF
804
805
DO i=1,6
806
IF(Intervals(i) > 1) WRITE (10,'(ES22.12E3)',advance='no') Amplitude(i)
807
END DO
808
809
WRITE (10,'(ES20.10E3)',advance='no') TotCapac
810
WRITE (10,'(2ES20.10E3)',advance='no') SectionCapac(VerticalCoordinate, 1:2)
811
IF(CalculateForce) THEN
812
WRITE (10,'(ES20.10E3)',advance='no') TotCharge
813
WRITE (10,'(3ES20.10E3)',advance='no') TotForce
814
END IF
815
IF(CalculateMoment) THEN
816
WRITE (10,'(3ES20.10E3)',advance='no') TotMoment
817
END IF
818
WRITE (10,*) ' '
819
CLOSE(10)
820
821
!------------------------------------------------------------------------------
822
! Save results in Aplac format
823
!------------------------------------------------------------------------------
824
IF(TableDim == 1) THEN
825
DO i=1,6
826
IF(Intervals(i) > 1) AplacResults(Cases,1) = Amplitude(i)
827
END DO
828
AplacResults(Cases,2) = TotCapac
829
END IF
830
831
END DO
832
END DO
833
END DO
834
END DO
835
END DO
836
END DO
837
838
IF(TableDim == 1) THEN
839
DO i=1,6
840
IF(Intervals(i) > 1) EXIT
841
END DO
842
843
Dist = ListGetConstReal(Solver % Values,'Aplac Distance',GotIt)
844
845
OPEN (10, FILE=TRIM(FileName)//'.aplac')
846
847
WRITE(10,'(A)',advance='no') 'vector vh'
848
DO i=1,Cases
849
WRITE (10,'(ES16.8E2,A)',advance='no') &
850
1.0d6 * LengthScale * AplacResults(i,1),'u'
851
END DO
852
WRITE(10,'(A)') ' '
853
854
WRITE(10,'(A)',advance='no') 'vector vc'
855
DO i=1,Cases
856
WRITE (10,'(ES16.8E2,A)',advance='no') &
857
1.0d12 * LengthScale**2 * AplacResults(i,2),'p'
858
END DO
859
WRITE(10,'(A)') ' '
860
861
WRITE(10,'(A,ES16.8E2,A,I3)') 'GeneralTransducer "Elmer" nv 0 nz 0 nU 0 D=',&
862
1.0d6*LengthScale*Dist,'u H=vh C=vc N=',Cases
863
864
END IF
865
866
867
TotTime = CPUTime() - TotTime
868
OPEN (10, FILE=TRIM(FileName)//'.info',POSITION='append')
869
WRITE(10,*) 'Number of Cases',Cases
870
WRITE(10,*) 'Total CPU Time (s)',TotTime
871
872
873
!------------------------------------------------------------------------------
874
875
CONTAINS
876
877
878
!------------------------------------------------------------------------------
879
SUBROUTINE LaplaceCompose( StiffMatrix,Element,n,Nodes )
880
!------------------------------------------------------------------------------
881
REAL(KIND=dp) :: StiffMatrix(:,:)
882
INTEGER :: n
883
TYPE(Nodes_t) :: Nodes
884
TYPE(Element_t), POINTER :: Element
885
!------------------------------------------------------------------------------
886
887
REAL(KIND=dp) :: SqrtElementMetric,U,V,W,S,A,L,x,y,z,aid
888
LOGICAL :: Stat
889
INTEGER :: i,j,p,q,t
890
TYPE(GaussIntegrationPoints_t) :: IntegStuff
891
892
!------------------------------------------------------------------------------
893
894
StiffMatrix = 0.0d0
895
896
!------------------------------------------------------------------------------
897
! Numerical integration
898
!------------------------------------------------------------------------------
899
IntegStuff = GaussPoints( Element )
900
901
DO t=1,IntegStuff % n
902
U = IntegStuff % u(t)
903
V = IntegStuff % v(t)
904
W = IntegStuff % w(t)
905
!------------------------------------------------------------------------------
906
! Basis function values & derivatives at the integration point
907
!------------------------------------------------------------------------------
908
stat = ElementInfo( Element,Nodes,U,V,W,SqrtElementMetric, &
909
Basis,dBasisdx,ddBasisddx,.FALSE. )
910
S = IntegStuff % s(t) * SqrtElementMetric
911
912
!------------------------------------------------------------------------------
913
! The Poisson equation
914
!------------------------------------------------------------------------------
915
916
DO p=1,N
917
DO q=1,N
918
DO i=1,DIM
919
StiffMatrix(p,q) = StiffMatrix(p,q) + s * dBasisdx(p,i) * dBasisdx(q,i)
920
END DO
921
END DO
922
END DO
923
924
END DO
925
!------------------------------------------------------------------------------
926
927
!------------------------------------------------------------------------------
928
END SUBROUTINE LaplaceCompose
929
!------------------------------------------------------------------------------
930
931
932
!------------------------------------------------------------------------------
933
FUNCTION ElementEnergy( Element,n,Nodes,ElemPotential) RESULT (Wetot)
934
!------------------------------------------------------------------------------
935
INTEGER :: n
936
TYPE(Nodes_t) :: Nodes
937
TYPE(Element_t), POINTER :: Element
938
REAL(KIND=dp), POINTER :: ElemPotential(:)
939
REAL(KIND=dp) :: Wetot
940
!------------------------------------------------------------------------------
941
942
REAL(KIND=dp) :: SqrtElementMetric,U,V,W,S,A,L,x,y,z,Grad(3),We
943
LOGICAL :: Stat
944
INTEGER :: i,j,p,q,t
945
TYPE(GaussIntegrationPoints_t) :: IntegStuff
946
947
!------------------------------------------------------------------------------
948
949
Wetot = 0.0d0
950
951
!------------------------------------------------------------------------------
952
! Numerical integration
953
!------------------------------------------------------------------------------
954
IntegStuff = GaussPoints( Element )
955
956
DO t=1,IntegStuff % n
957
U = IntegStuff % u(t)
958
V = IntegStuff % v(t)
959
W = IntegStuff % w(t)
960
S = IntegStuff % s(t)
961
!------------------------------------------------------------------------------
962
! Basis function values & derivatives at the integration point
963
!------------------------------------------------------------------------------
964
stat = ElementInfo( Element,Nodes,U,V,W,SqrtElementMetric, &
965
Basis,dBasisdx,ddBasisddx,.FALSE. )
966
S = S * SqrtElementMetric
967
968
x = SUM( Basis(1:n) * Nodes % x(1:n) )
969
y = SUM( Basis(1:n) * Nodes % y(1:n) )
970
z = SUM( Basis(1:n) * Nodes % z(1:n) )
971
972
!------------------------------------------------------------------------------
973
! The Poisson equation
974
!------------------------------------------------------------------------------
975
976
DO j = 1, DIM
977
Grad(j) = SUM( dBasisdx(1:n,j) * ElemPotential(1:n) )
978
END DO
979
980
We = s * SUM( Grad(1:DIM) * Grad(1:DIM) )
981
982
Wetot = Wetot + We
983
984
IF(x < MinMaxMoving(1,1) ) SectionCapac(1,1) = SectionCapac(1,1) + We
985
IF(x > MinMaxMoving(1,2) ) SectionCapac(1,2) = SectionCapac(1,2) + We
986
IF(y < MinMaxMoving(2,1) ) SectionCapac(2,1) = SectionCapac(2,1) + We
987
IF(y > MinMaxMoving(2,2) ) SectionCapac(2,2) = SectionCapac(2,2) + We
988
IF(z < MinMaxMoving(3,1) ) SectionCapac(3,1) = SectionCapac(3,1) + We
989
IF(z > MinMaxMoving(3,2) ) SectionCapac(3,2) = SectionCapac(3,2) + We
990
991
END DO
992
993
!------------------------------------------------------------------------------
994
END FUNCTION ElementEnergy
995
!------------------------------------------------------------------------------
996
997
998
!------------------------------------------------------------------------------
999
SUBROUTINE ElectricForceIntegrate( Force, Moment, Area, Charge )
1000
!------------------------------------------------------------------------------
1001
REAL(KIND=dp) :: Force(3), Moment(3), Area, Charge
1002
!------------------------------------------------------------------------------
1003
1004
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
1005
REAL(KIND=dp), POINTER :: U_Integ(:), V_Integ(:), W_Integ(:), S_Integ(:)
1006
REAL(KIND=dp) :: u,v,w,s, detJ, Tensor(3,3), Normal(3), EField(3), DFlux(3), Lforce(3), &
1007
LMoment(3), Radius(3), ElemForce(3), ElemMoment(3), ElemArea, ElemCharge, &
1008
ElementArea, ElementForce(3), xpos, ypos, zpos, LCharge
1009
INTEGER :: N_Integ,i,j,l
1010
LOGICAL :: stat
1011
1012
!------------------------------------------------------------------------------
1013
! Integration stuff
1014
!------------------------------------------------------------------------------
1015
IntegStuff = GaussPoints( CurrentElement )
1016
1017
U_Integ => IntegStuff % u
1018
V_Integ => IntegStuff % v
1019
W_Integ => IntegStuff % w
1020
S_Integ => IntegStuff % s
1021
N_Integ = IntegStuff % n
1022
1023
ElemForce = 0.0d0
1024
ElemMoment = 0.0d0
1025
ElemArea = 0.0d0
1026
ElemCharge = 0.0d0
1027
1028
!------------------------------------------------------------------------------
1029
! Over integration points
1030
!------------------------------------------------------------------------------
1031
DO l=1,N_Integ
1032
!------------------------------------------------------------------------------
1033
u = U_Integ(l)
1034
v = V_Integ(l)
1035
w = W_Integ(l)
1036
!------------------------------------------------------------------------------
1037
! Basis function values & derivatives at the integration point
1038
!------------------------------------------------------------------------------
1039
stat = ElementInfo( CurrentElement, ElementNodes, u, v, w, &
1040
detJ, Basis, dBasisdx, ddBasisddx, .FALSE., .FALSE. )
1041
s = detJ * S_Integ(l)
1042
1043
Model % CurrentElement => CurrentElement
1044
1045
!------------------------------------------------------------------------------
1046
! The checking of normal direction is problematic since it requires that
1047
! densities are given and new coordinates are updated. For this reason
1048
! the normal direction is set by the PlusMinus sign later on.
1049
!------------------------------------------------------------------------------
1050
1051
1052
Normal = NormalVector( CurrentElement, ElementNodes, u, v, .FALSE. )
1053
!------------------------------------------------------------------------------
1054
! Need parent element basis etc., for computing normal derivatives on boundary.
1055
!------------------------------------------------------------------------------
1056
DO i = 1,n
1057
DO j = 1,pn
1058
IF ( CurrentElement % NodeIndexes(i) == &
1059
Parent % NodeIndexes(j) ) THEN
1060
xelem(i) = Parent % TYPE % NodeU(j)
1061
yelem(i) = Parent % TYPE % NodeV(j)
1062
zelem(i) = Parent % TYPE % NodeW(j)
1063
EXIT
1064
END IF
1065
END DO
1066
END DO
1067
1068
u = SUM( Basis(1:n) * xelem(1:n) )
1069
v = SUM( Basis(1:n) * yelem(1:n) )
1070
w = SUM( Basis(1:n) * zelem(1:n) )
1071
1072
stat = ElementInfo( Parent, ParentNodes, u, v, w, detJ, ParentBasis, &
1073
ParentdBasisdx, ddBasisddx, .FALSE., .FALSE. )
1074
1075
!------------------------------------------------------------------------------
1076
DO i=1,DIM
1077
EField(i) = SUM( ParentdBasisdx(1:pn,i) * ElemPotential(1:pn) )
1078
END DO
1079
DFlux = EField
1080
1081
DO i=1, DIM
1082
DO j=1, DIM
1083
Tensor(i,j) = - DFlux(i) * EField(j)
1084
END DO
1085
END DO
1086
DO i=1, DIM
1087
Tensor(i,i) = Tensor(i,i) + SUM( DFlux * EField ) / 2.0d0
1088
END DO
1089
1090
ElemArea = ElemArea + s
1091
1092
LCharge = SUM( DFlux(1:DIM) * Normal(1:DIM) )
1093
ElemCharge = ElemCharge + s * LCharge
1094
1095
LForce = - MATMUL( Tensor, Normal )
1096
ElemForce = ElemForce + s * LForce
1097
1098
IF(CalculateMoment) THEN
1099
Radius(1) = SUM( ElementNodes % x(1:n) * Basis(1:n) ) - Center(1)
1100
Radius(2) = SUM( ElementNodes % y(1:n) * Basis(1:n) ) - Center(2)
1101
Radius(3) = SUM( ElementNodes % z(1:n) * Basis(1:n) ) - Center(3)
1102
1103
LMoment(1) = Radius(2) * LForce(3) - Radius(3) * LForce(2)
1104
LMoment(2) = Radius(3) * LForce(1) - Radius(1) * LForce(3)
1105
LMoment(3) = Radius(1) * LForce(2) - Radius(2) * LForce(1)
1106
1107
ElemMoment = ElemMoment + s * Lmoment
1108
END IF
1109
1110
!------------------------------------------------------------------------------
1111
END DO
1112
1113
IF(ElemCharge > 0) THEN
1114
ElemCharge = -ElemCharge
1115
ElemForce = -ElemForce
1116
ElemMoment = -ElemMoment
1117
END IF
1118
1119
Force = Force + ElemForce
1120
Area = Area + ElemArea
1121
Charge = Charge + ElemCharge
1122
Moment = Moment + ElemMoment
1123
1124
!------------------------------------------------------------------------------
1125
END SUBROUTINE ElectricForceIntegrate
1126
!------------------------------------------------------------------------------
1127
1128
1129
!------------------------------------------------------------------------------
1130
END SUBROUTINE MovingElstatSolver
1131
!------------------------------------------------------------------------------
1132
1133
1134