You are on page 1of 18

MagnetoDynamics2D Solver

LOKALNA MATRICA
SUBROUTINE LocalMatrix(Element, n, nd)

Lokalni argumenti:
INTEGER :: n, nd !n je broj čvorova, a nd je broj stupnjeva slobode

TYPE(Element_t), POINTER :: Element !trenutni element

!------------------------------------------------------------------------------

Lokalne varijable:
REAL(KIND=dp) :: Basis(nd),dBasisdx(nd,3),DetJ,LoadAtIP

INTEGER :: i,p,q,t,siz

Basis(nd) je vektor u kojem se čuvaju vrijednosti svih baznih funkcija u trenutnoj integracijskoj
točki IP trenutnog elementa. Njihov broj je jednak broju stupnjeva slobode nd trenutnog
elementa.
dBasisdx(nd,3) je matrica u kojoj se čuvaju sve vrijednosti prvih derivacija svih baznih funkcija
trenutnog elementa po varijablama koordinatnog sustava u trenutnoj integracijskoj točki IP
trenutnog elementa.
DetJ je površina trenutnog elementa (2D solver)
LoadAtIP predstavlja vrijednost izvora polja u trenutnoj integracijskoj točki IP.
TYPE(GaussIntegrationPoints_t) :: IP !integracijska točka

STIFF(:,:) je stiffness matrica trenutno aktivnog elementa, LOAD(:) je vektor u kojemu se nalaze
vrijednosti BodyForce (npr. naboja) za trenutno aktivni element, a FORCE(:) je rhs-vektor koji se
preračuna iz LOAD(:) vektora i predstavlja desnu stranu sustava V(:)*STIFF(:,:)=FORCE(:). Sve tri
varijable su spremljene uz AllocationsDone varijablu što znači da se alokacija prostora za lokalne
(elementarne) matrice i vektore obavlja samo jednom.
MASS(nd,nd) je oblik STIFF matrice u kojoj su elementi pretpostavljeni kao koeficijenti koji se u
slaboj formulaciji diferencijalne jednadžbe nalaze uz vremensku derivaciju varijable, za razliku od
elemenata STIFF matrice koji se u slaboj formulaciji nalaze uz vremenski stacionarni oblik
varijable, a u ovom solveru tu varijablu predstavlja z-komponenta vektorskog magnetskog
potencijala.
R(2,2,n) je matrica koja predstavlja 2x2 tenzor reluktancije (inverz permeabilnosti). C(n) je vektor
koji čuva el. vodljivosti u n čvorova elementa. Varijabla mu čuva iznos reluktivnosti za neku
konkretnu apsolutnu vrijednost indukcije Babs. Varijabla muder čuva vrijednost derivacije
reluktivnosti (recipročne permeabilnosti) po varijabli Babs u točki Babs. M(2,n) je matrica koja
čuva vektore magnetizacije za n čvorova elementa.
Varijabla POT(nd) čuva vrijednost z-komponente magnetskog potencijala u svim stupnjevima
slobode trenutnog elementa iz prethodne iteracije solvera.
Matrica JAC(nd,nd)
Varijabla C_ip čuva vrijednost električne vodljivosti u integracijskoj točki trenutnog elementa.
Varijabla M_ip(2) je vektor koji čuva vrijednost vektora magnetizacije u integracijskoj točki.
REAL(KIND=dp) :: MASS(nd,nd), STIFF(nd,nd), FORCE(nd), &

LOAD(nd),R(2,2,n),C(n), mu,muder,Babs,POT(nd), &

JAC(nd,nd),Agrad(3),C_ip,M(2,n),M_ip(2),x

Varijabla Cubic je TRUE ako su zadani koeficijenti kubne funkcije koja nadomješta BH-krivulju.
Varijabla HBcurve je TRUE ako je zadano u SIF-fileu polje (array) realnih koeficijenata koji opisuju
HB krivulju.
LOGICAL :: Cubic, HBcurve, Found, Stat

Vektor Bval(:) čuva vrijednosti indukcije, a vektor Hval(:) čuva vrijednosti jakosti magnetskog polja
koje odgovaraju vrijednostima funkcije opisane HB-krivuljom u točkama indukcije vektora Bval(:).
CubicCoeff(:) je pokazivač na vektor podataka koji sadrži koeficijente kubne funkcije koja
aproksimira HB-krivulju. Cval(:) je pokazivač na CubicCoeff(:) vektor, tj. na koef. kubne funkcije.
Matrica HB(:,:) čuva domenu i kodomenu HB-krivulje .
REAL(KIND=dp), POINTER :: Bval(:), Hval(:), Cval(:), &

CubicCoeff(:) => NULL(), HB(:,:) => NULL()

Material je struktura koja čuva lanca listi koje sadrže podatake vezane za materijal tijela kojemu
element pripada.
BodyForce na isti način čuva liste podataka koje sadrže podatke o izvoru polja.
Varijabla Nodes je struktura Nodes_t koja između ostalog sadrži integer NumberOfNodes te
realne varijable (pokazivače na vektore) x(:), y(:), z(:) koje čuvaju globalne koordinate čvorova
elementa. Veličina tih vektora je jednaka broju čvorova NumberOfNodes.
TYPE(ValueListEntry_t), POINTER :: Lst !pokazivač na listu

TYPE(ValueList_t), POINTER :: Material, BodyForce

TYPE(Nodes_t), SAVE :: Nodes

!$omp threadprivate(Nodes)

CHARACTER(LEN=MAX_NAME_LEN) :: CoilType

LOGICAL :: CoilBody

TYPE(ValueList_t), POINTER :: CompParams


REAL(KIND=dp) :: Bt(nd,2), Ht(nd,2)

REAL(KIND=dp) :: nu_tensor(2,2)

REAL(KIND=dp) :: B_ip(2), Alocal

!------------------------------------------------------------------------------

Rutina GetElementNodes() preko varijable (argument) Nodes vraća (sprema) koordinate čvorova
trenutnog elementa.
CALL GetElementNodes( Nodes,Element )

STIFF = 0._dp !inicijalizacija

JAC = 0._dp !inicijalizacija

FORCE = 0._dp !inicijalizacija

IF(TransientSimulation) MASS = 0._dp !inicijalizacija uz uvjet

Funkcija GetMaterial()vraća pokazivač na Material valuelist_t strukturu trenutnog elementa


Rutina GetConstRealArray() dohvaća polje realnih brojeva iz valuelist_t strukture Material, iz
pripadne joj liste pod nazivom 'H-B curve' u varijablu HB(:,:).
Material => GetMaterial(Element)

CALL GetConstRealArray( Material, HB, 'H-B curve', HBCurve )

siz = 0 !inicijalizacija varijable za spremanje veličine dimenzija matrice

Cval => NULL()

IF ( HBCurve ) THEN !ako je pronađena lista i podaci u HB onda je HBcurve TRUE

siz = SIZE(HB,1) !broj redaka HB matrice, tj. broj točaka koje opisuju HB-krivulju

IF(siz>1) THEN !ako postoje barem dvije točke...

Bval=>HB(:,1) !Bval(:) pokazuje na stupac indukcijskih točaka HB-krivulje

Hval=>HB(:,2) !Hval(:) pokazuje na stupac jak. mag. polja HB-krivulje

Cubic = GetLogical( Material, 'Cubic spline for H-B curve',Found) !ako postoji

!u strukturi Material lista naziva 'Cubic spline for H-B curve' to znači da će

!HB-krivulja biti aproksimirana kubnom funkcijom preko rutine CubicSpline.

IF (Cubic.AND..NOT.ASSOCIATED(CubicCoeff)) THEN

ALLOCATE(CubicCoeff(siz)) !alociranje memorije (implicitni target) za pokazivač

CALL CubicSpline(siz,Bval,Hval,CubicCoeff) !iz Bval i Hval vektora računa

!koef. kubne funkcije u CubicCoeff

END IF

Cval=>CubicCoeff !Cval pokazuje na kubne koef. na maloprije alociranoj lokaciji

HBCurve = .TRUE.
END IF

END IF

IF(siz<=1) THEN !ako je broj redaka tj. (B,H) točaka HB-krivulje manji od 2 (nevaljano)

Lst => ListFind(Material,'H-B Curve',HBcurve) !ponovno traženje liste 'H-B curve'u

!Material strukturi ali bez automatskog dohvaćanja podataka iz liste

IF(HBcurve) THEN !ako je lista pronađena, dohvaćaju se podaci 'ručno' u nastavku

Cval => Lst % CubicCoeff !Cval pokazuje na CubicCoeff u listi Lst ('H-B curve')

Bval => Lst % TValues !Bval pokazuje na domenu HB-krivulje

Hval => Lst % FValues(1,1,:) !Hval pokazuje na kodomenu podataka HB-krivulje

END IF

END IF

Interna rutina GetLocalSolution() je zadužena za dohvaćanje vrijednosti varijable, u ovom slučaju


skalarnog polja, tj. z-komponente vektora magnetskog potencijala iz prethodne iteracije solvera.
SUBROUTINE GetScalarLocalSolution( x,name,UElement,USolver,tStep, UVariable )

U deklaracije rutine argument x predstavlja promatranu varijablu tj. vektor u koji će biti
spremljene vrijednosti varijable (ovdje je to Az) iz prethodne iteracije u svim stupnjevima
slobode trenutnog elementa.
IF(HBcurve) THEN !ako je ostvarena HB-krivulja

CALL GetLocalSolution(POT,UElement=Element,USolver=Solver)

IF (.NOT. ASSOCIATED(Bval) ) CALL Fatal ('mgdyn2D','bval not associated')

IF (.NOT. ASSOCIATED(Hval) ) CALL Fatal ('mgdyn2D','hval not associated')

ELSE

CALL GetReluctivity(Material,R,n,Element) !ako nije zadana HB-krivulja za tijelo kojemu

!trenutni element pripada, onda se dohvaća reluktivnost (inverz pemeabilnosti) kao skalar

END IF

SUBROUTINE GetReluctivity(Material,Acoef,n,Element) je rutina koja vraća tenzor relkutivnosti


(inverz permeabilnosti) preko varijable (argumenta) Acoef(2,2,n) gdje je n broj čvorova dotičnog
elementa, a to radi preko interne funkcije GetTensor koja u principu pretražuje po lancu
pokazivača strukture Material, te traži liste pod nazivom 'Permeability', 'Relative Permeability' i
'Reluctivity' i dohvaća podatke iz njih.
!-------------------------------

Prvom retku vektora M(2,n) je pridružena x-komponenta vektora magnetizacije, a drugom retku
y-komponenta vektora magnetizacije za svih n čvorova elementa.
C = GetReal( Material, 'Electric Conductivity', Found, Element) !C pridružena el. vodlj.
M(1,:) = GetReal( Material, 'Magnetization 1', Found, Element)

M(2,:) = GetReal( Material, 'Magnetization 2', Found, Element)

Load = 0.0d0 !inicjalizacija vektora u koji će biti spremljene vrijednosti izvora polja

BodyForce => GetBodyForce(Element)!dohvaćanje strukture u kojoj je lista podataka za izvor

IF ( ASSOCIATED(BodyForce) ) &

Load(1:n) = GetReal(BodyForce, 'Current Density', Found, Element) !dohvaćanje izvora

Funkcija GetBodyForce() preko interne funkcije GetBodyForceId(), koja određuje kojem tijelu
(Element%BodyId) pripada trenutno aktivni element i ako je tom tijelu pridružen ikakav
BodyForce (npr. gustoća struje) određuje koji ID taj BodyForce ima (dodijeljen mu u SIF-file), te
joj ga vraća, pa funkcija GetBodyForce() zatim pronalazi listu podataka koja tom BodyForceu s tim
ID-om pripada u trenutnom modelu CurrentModel te tu listu podataka vraća u pozivnu funkciju.

Funkcija GetReal() u BodyForce strukturi koja sadrži lanac listi pronađena je lista naziva 'Current
Density' te je iz nje izvučen vektor realnih vrijednosti gustoće struje u vektor Load(1:n) dugačak
n čvorova trenutnog elementa .
!----------------------

NUMERIČKA INTEGRACIJA
Struktura podataka GaussIntegrationPoints_t sadrži integer N kojemu je pridružen broj točaka u
kojima će se računati vrijednosti funkcije (integration points), te sadrži vektore u(:), v(:), w(:) koji
su dugački upravo N i predstavljaju lokalne koordinate integracijskih točaka (u za 1D; u,v za 2D;
u,v,w za 3D). Struktura je prikazana u nastavku:
TYPE GaussIntegrationPoints_t

INTEGER :: N

REAL(KIND=dp), POINTER CONTIG :: u(:),v(:),w(:),s(:)

END TYPE GaussIntegrationPoints_t

Struktura pored toga sadrži i vektor s(:) koji je također dugačak N i za svaku integracijsku točku
sadrži težinu koja pripada toj integracijskoj točki u ukupnom doprinosu pri numeričkoj integraciji
nad elementom.
IP = GaussPoints(Element) !GaussPoints() vraća integracijske točke za trenutni element

DO t=1,IP % n !integracija se obavlja po svim integracijskim točkama trenutnog elementa

! Basis function values & derivatives at the integration point:

!--------------------------------------------------------------

stat = ElementInfo( Element, Nodes, IP % U(t), IP % V(t), &

IP % W(t), detJ, Basis, dBasisdx )


IF( CSymmetry ) THEN !ako je cilindrični koordinatni sustav

x = SUM( Basis(1:n) * Nodes % x(1:n) ) !trik za izračun koordinate (radijusa jer je

polarni koordinatni sustav) trenutne integracijske točke trenutnog elementa.

detJ = detJ * x !jacobijan u cilindričnom koordinatnom sustavu je J=r=x

END IF

Realni vektor Basis(nd) je zadužen za spremanje vrijednosti svih baznih funkcija u jednoj te istoj
točki unutar elementa (IP=(x0,y0) - integration point) – svakom stupnju slobode pripada jedna
bazna funkcija pa je zato vektor dugačak nd. Primjerice, za kvadrilateralni element vektor je

Basis  1 ( IP) 2 ( IP) 3 ( IP) 4 ( IP)

Realni vektor dBasisdx(nd,3) zadužen je za spremanje prvih derivacija svih baznih funkcija u istoj
točki (integration point). Primjerice, za element s četiri stupnja slobode, općenit izraz bi bio:

 1 1 1 


 x y z 
 
  2  2  2 
 x y z 
dBasisdx   
  3  3  3 
 x y z 
 
  4  4  4 
 x y z 

U našem slučaju su parcijalne derivacije baznih funkcija po varijabli z jednake nuli jer radimo u 2D
x-y ravnini. Sve parcijalne derivacije u ovoj matrici su u kodu zapravo realni brojevi koji
predstavljaju iznos parcijalnih derivacija u trenutno promatranoj integracijskoj točki.
Vektor POT bi glasio

POT   Az1 Az 2 Az 3 Az 4 

Dakle, magnetski vektor potencijal Az je aproksimiran kao suma baznih funkcija s pripadnim
stupnjevima slobode
N
Az   Ai i
i

U nastavku koda se između ostaloga vrše množenja vektora Basis i dBasisdx sa vektorom POT.
Posebno je zanimljiv sljedeći umnožak
 1 1 1 
 x y z 
 
  2  2  2 
 x y z 
POT  dBasisdx   Az1 Az 2 Az 3 Az 4   
  3  3  3 
 x y z 
 
  4  4  4 
 x y z 

     1    
POT  dBasisdx   Az1 1  Az 2 2  Az 3 3  Az 4 4 Az1  Az 2 2  Az 3 3  Az 4 4 
 x x x x y y y y 

 A Az  Az A
POT  dBasisdx   z   i  z j  Az
 x y  x x

Ono što se dobije jesu dakle komponente gradijenta z-komponente vektora magnetskog
potencijala. Naravno, sve parcijalne derivacije u izrazima ranije su u kodu zapravo realni brojevi
a ne simbolički izrazi, a iznosi tih realnih brojeva su dobiven pri pozivu funkcije ElementInfo() za
trenutnu integracijsku točku IP trenutnog elementa.
LoadAtIP = SUM(Basis(1:n) * LOAD(1:n)) !izračun gustoće struje u integracijskoj točki

nu_tensor = 0.0_dp !inicijalizacija tenzora reluktivnosti

IF (HBcurve) THEN

Agrad = 0.0_dp !inicijalizacija

Agrad = MATMUL( POT,dBasisdx ) !komponente gradijenta z-komp. vek. mag. pot. u IP

Alocal = SUM( POT(1:n) * Basis(1:n) ) !iznos z-komp mag. vek. pot. u integr. točki

Rotacija vektorskog magnetskog potencijala je jednaka vektoru indukcije B. Budući da je


pretpostavljena samo z-komponenta vektora magnetskog potencijala, u izrazu za rotaciju
vektorskog polja preživjet će samo x i y komponente magnetske indukcije i to samo parcijalne
derivacije nad z-komponentom vektora magnetskog potencijala. Te dvije parcijalne derivacije
koje će preživjeti upravo odgovaraju komponentama ranije izračunatog gradijenta z-komponente
vektora magnetskog potencijala uz korekciju predznaka za x-komponentu indukcije Bx u
trenutnoj integracijskoj točki, tj. za varijablu B_ip(1). Opaska! Naopako su dodijeljeni predznaci u
kodu ispod. Ipak, poslije ga se neutralizira množenjem s jednako naopakim gradijentima baznih
funkcija pa se stvar ne očituje u konačnom rezultatu kao pogreška.
B_ip(1) = -Agrad(2) !iznos x-komponente indukcije u IP tj. Bx(IP)

B_ip(2) = Agrad(1) !iznos y-komponente indukcije u IP tj. By(IP)

IF( CSymmetry ) B_ip(2) = B_ip(2) + Alocal/x

! -----
Babs = MAX( SQRT(SUM(B_ip**2)), 1.d-8 ) !apsolutna vrijednost indukcije

Za zadanu apsolutnu vrijednost indukcije Babs, funkcija InterpolateCurve() vraća interpoliranu


vrijednost funkcije koja je opisana HB-krivuljom (Hval=f(Bval) ili H=CubicCoeff*B), a to je
apsolutna vrijednost jakosti mag. polja Habs za taj iznos Babs. Dijeljenjem dobivenog apsolutnog
iznosa Habs sa Babs daje vrijednost reluktivnosti u toj integracijskoj točki.
Funkcija DerivativeCurve() vraća vrijednost derivacije HB-krivulje u točki Babs. Varijabla muder je
u biti dinamička reluktivnost podijeljena sa Babs dok je varijabla mu statička reluktivnost.
mu = InterpolateCurve(Bval,Hval,Babs,CubicCoeff=Cval)/Babs !iznos reluktivnosti

muder = (DerivateCurve(Bval,Hval,Babs,CubicCoeff=Cval)-mu)/Babs

nu_tensor(1,1) = mu !nu_tensor(1,1) je po definiciji jednak Habs_x/Babs_x

nu_tensor(2,2) = mu !nu_tensor(1,1) je po def. jednak Habs_y/Babs_y

U slučaju da nije bila zadana HB-krivulja, tenzor reluktivnosti u integracijskoj točki se odredi iz
tenzora reluktivnosti svih čvorova trenutnog elementa pomnoženog vektorom Basis.
ELSE

muder=0._dp !u tom slučaju se ne može odrediti dinamička muder, pa ni JAC

DO p=1,2

DO q=1,2

nu_tensor(p,q) = SUM(Basis(1:n) * R(p,q,1:n))

END DO

END DO

END IF

!-------------------------

CoilBody = .FALSE. !pretpostavlja se nespecificiranost zavojnice

CompParams => GetComponentParams( Element ) !dohvaća parametre zavojnice

CoilType = '' !inicijalizacija

IF (ASSOCIATED(CompParams)) THEN !ako su postojali parametri

CoilType = GetString(CompParams, 'Coil Type', Found) !iz liste dohvaća tip zavojnice

IF (Found) THEN

SELECT CASE (CoilType) !ispituje se je li zavojnica stranded, massive ili foil

CASE ('stranded')

CoilBody = .TRUE.

CASE ('massive')

CoilBody = .TRUE.

CASE ('foil winding')


CoilBody = .TRUE.

CASE DEFAULT

CALL Fatal ('MagnetoDynamics2DHarmonic', 'Non existent Coil Type Chosen!')

END SELECT

END IF

END IF

C_ip = SUM( Basis(1:n) * C(1:n) ) !iznos el. Vodljivosti u integracijskoj točki

M_ip = MATMUL( M,Basis(1:n) ) !iznos komponenata vektora magnetizacije u IP

!------------------------------------------------------

!Konačno slijedi izgradnja matrica MASS, STIFF, FORCE...

!------------------------------------------------------

Programska implementacija FEM metode za neki fizikalni problem opisan općenitom parcijalnom
diferencijalnom jednadžbom sastoji se od nekoliko ključnih koraka. Prvi korak je obično
vremenska diskretizacija diferencijalne jednadžbe ako ista sadrži vremenske derivacije. Drugi
korak se odnosi onda na slabu formulacju vremenski diskretizirane diferencijalne jednadžbe.
Nakon toga slijedi korak FEM aproksimacije nad općim elementom domene u kojoj se varijabla
diferencijalne jednadžbe aproksimira sumom umnožaka baznih funkcija tog elementa s
pripadnim vrijednostima varijabli u pripadnim čvorovima (stupnjevima slobode). U slučaju da je
fizikalni problem nelinearan, četvrti korak je linearizacija dobivenog sustava jednadžbi, čime se
dobiva konačan sustav jednadžbi (matrična jednadžba) koji predstavlja FEM implementaciju
početne diferencijalne jednadžbe nad elementom. Dobiveni sustav općenito glasi

 1  n1 1
  MASS    STIFF   U   FORCE   MASS  U 
n

 t  t

Nakon toga slijedi peti korak u kojemu je potrebno asemblirati N takvih lokalnih sustava
jednadžbi, gdje N predstavlja broj elemenata problemske domene u jedan globalni sustav
jednadžbi, tj. u globalnu matricu nad cijelom problemskom domenom.
U Elmeru je situacija takva da je peti korak koji predstavlja asembliranje potpuno automatiziran.
Također, automatizirano je i bavljenje vremenskim derivacijama, odnosno pri FEM formulaciji
gornje matrične jednadžbe sve komponente slabe formulacije koje su uz vremensku derivaciju
varijable, što znači da predstavljaju koeficijente vremenske derivacije varijable, dovoljno je samo
ubaciti u matricu MASS i pozvati internu rutinu Default1stOrderTime(). Zatim, u Elmeru se nije
potrebno baviti ni izradom vektora varijable jer je i to automatizirano.
Ukratko, jedina stvar kojom se potrebno baviti pri pisanju solvera jest izgradnja MASS i STIFF
matrica te vektora FORCE, gdje matrica MASS predstavlja matricu u kojoj se nalaze koeficijenti
vremenske derivacije u FEM sustavu jednadžbi, matrica STIFF predstavlja koeficijente varijable
koji u istom FEM sustavu jednadžbi nisu uz nikakvu vremenski derivaciju varijable (tj. stacionarni
dio sustava), a vektor FORCE predstavlja vektor u kojemu se nalaze elementi koji fizikalno
predstavljaju izvore polja varijable (BodyForce).
Parcijalna diferencijalna jednadžba koja opisuje fizikalni problem magnetske dinamike u 2D (x-y
ravnina) i čija će FEM implementacija u Elmeru razjašnjena u ovom dokumentu glasi

 Az 1 
     Az   J z   M
t  
Budući da je struja kao izvor polja pretpostavljena samo u z-smjeru (okomita na 2D ravninu), ne
postoji gradijent električnog polja u 2D ravnini što znači da je električni potencijal konstantan u
svim točkama 2D ravnine pa je iz gornje A-V formulacije nestao električni potencijal V. Osim toga,
i smjer vektora magnetizacije je pretpostavljen u x-y ravnini (z-komponenta mu je nula). Iz tih
dviju pretpostavki slijedi da će magnetski vektor potencijal imati samo z-komponentu različitu od
nule u promatranoj 2D domeni.
Slaba formulacija prethodne parcijalne diferencijalne jednadžbe je izvedena u nastavku. Budući
da samo drugi pribrojnik s lijeve strane u prethodnoj diferencijalnoj jednadžbi sadrži rotaciju
magnetske indukcije, samo je u njemu potrebno putem parcijalne integracije diferencijaciju
(rotaciju) prebaciti na vektorsku test funkciju a koja također ima samo z-komponentu.
Parcijalna derivacija drugog pribrojnika s lijeve strane glasi

1  1  1 
     Az  a      Az  a      Az    a
     
 
Dvostruka integracija po 2D domeni daje parcijalnu integraciju

1  1  1 
       A  adS        A  a  dS       A    a  dS

z

z

z

Primjenom Gaussovog teorema divergencije prvi integral s lijeve strane prelazi iz dvostrukog u
krivuljni integral po granici domene a on je jednak nuli jer je test funkcija a pretpostavljena kao
jednaka nuli na granici domene.

1  1 
       A  adS      A  adl       A    a  dS
1
z z z
 C 
0

Dakle, množenjem početne parcijalne diferencijalne jednadžbe s test funkcijom a te primjenom


parcijalne integracije na drugi pribrojnik s lijeve strane dobivena je slaba formulacija

 Az 1 
  t
 
adS     Az   a dS   J z   M adS

 
    
Implementacija slabe formulacije u programskom kodu će rezultirati sustavom od nd jednadžbi
koje će činiti sljedeći matrični sustav

 Az 1 
  t
 
adS      Az    a dS   J z    M adS

 
    

 MASS 
d 
Az 
 STIFF  Az   FORCE 
 dt 

U nastavku će biti objašnjena programska implementacija MASS i STIFF matrica te FORCE vektora.

MASS MATRICA
Prvi integral na lijevoj strani slabe formulacije može se raspisati na slijedeći način

 Az   nd 
  adS      Aii   j dS za j=1,2,3,…nd,

t 
t  i 
gdje je magnetski vektor potencijal Az aproksimiran sljedećom sumom (nad elementom Γ)
nd
Az   Ai i ,
i

a vektorska test funkcija a pripada skupu baznih funkcija αj gdje je j=1,2,3,…nd. Dakle, test
funkcija upravo predstavlja jednu od nd baznih funkcija, što znači da u konačnici imamo sustav
od nd jednadžbi takvih da je u svakoj točno nd pribrojnika (integrala) pomnoženo jednom od nd
baznih funkcija αj. Dakle, dobivamo nd∙nd pribrojnika, a jedan od takvih pribrojnika glasi


  t ( A  ) dS

i i j

Ai je vrijednost magnetskog vektorskog potencijala u i-tom čvoru (stupnju slobode) elementa Γ


te prema tome ne varira pri integriranju, tj. predstavlja konstantu u integralu s obzirom na
poziciju, ali predstavlja varijablu s obzirom na vrijeme. S druge strane, bazne funkcije imaju
vremenski nevarijabilnu vrijednost ali su promjenjive vrijednosti s obzirom na poziciju u
elementu. Stoga, gornji integral možemo preoblikovat na sljedeći način
Ai
   dS

i j
t

Budući da gornji integral predstavlja jedan od nd∙nd sličnih pribrojnika tog sustava od nd
jednadžbi, cijeli sustav u matričnom obliku glasi
 A 
 11dS ...  1 
     dS   t 
1 2
 
d    A
 MASS    Az     1 2 dS .. ..   2 
 
 dt      t 
 .. .. ..   ... 
 
 

Prema tome, gornji integral predstavlja jedan od elemenata MASS matrice pomnožen
vremenskom derivacijom magnetskog vektorskog potencijala u i-tom čvoru. Programska
implementacija gornjih izraza tj. određivanje elemenata MASS matrice prikazano je u nastavku
IF(TransientSimulation .AND. C_ip/=0._dp) THEN !vremenski promjenjiva simulacija => MASS

DO p=1,nd !p predstavlja i u prethodnim izrazima

DO q=1,nd !q predstavlja j u prethodnim izrazima

IF(CoilType /= 'stranded') MASS(p,q) = MASS(p,q) + IP % s(t) * detJ * C_ip * &

Basis(q)*Basis(p)

END DO

END DO

END IF

Dakle, MASS(p,q) predstavlja jedan od elemenata MASS matrice (integral u gornjoj matrici) a
računa se umnoškom dviju baznih funkcija αj*αj = Basis(q)*Basis(p) te množenjem svega toga s
dijelom površine dS elementa određenog težinom integracijske točke elementa IP%s(t)*detJ, te
na kraju množenjem s električnom vodljivošću u trenutnoj integracijskoj točki elementa C_ip.

STIFF MATRICA
Drugi integral na lijevoj strani slabe formulacije ne sadrži nikakvu vremensku derivaciju varijable
(vremenski stacionaran) pa će njegova implementacija u programskom kodu predstavljati STIFF
matricu. Radi preglednosti ćemo ga ponovno zapisati

1 
     A     a  dS

z

Rotor vektorske test funkcije 𝑎⃗ u ovoj implementaciji (Galerkin – definirana u skupu baznih
⃗⃗ gdje je j=1,2,3,…nd) predstavlja rotor baznih funkcija αj gdje po definiciji rotacije
funkcija 𝑎⃗ =αj𝑘
svake od baznih funkcija uz pretpostavku postojanja samo z-komponente vektora test funkcije
dobivamo matricu (predznak je naopako zapisan da bude u skladu s predznakom u kodu koji je
pogrešan)
 1 1 
 y 
x 
 
  2  2 

Bt    a    Basis   dBasisdx(:, 2) dBasisdx(:,1)   y x 
 
 ... ... 
 
  nd 
 nd 
 y x 
Bt(:,1) = -dbasisdx(:,2) !predznak opet naopako

Bt(:,2) = dbasisdx(:,1) !predznak opet naopako

IF ( CSymmetry ) Bt(:,2) = Bt(:,2) + Basis(:)/x

Budući da je magnetski vektor potencijal prikazan aproksimiran sumom umnožaka baznih


funkcija sa vrijednostima varijable u čvorovima Ai ∙αi, rotor vektorske test funkcije 𝐴⃗𝑧 će biti
jednak

 1 1 
 A1 y  A1
x 
 
  2  2 
A2  A2
  Az     A11 A2 2 ... And  nd    y x 
 
 ... ... 
 
 A3  nd 
 A3 nd 
 y x 

Bitno je uočiti vezu između transponirana prethodne matrice i transponirane matrice Bt

 A1 
A 
  Az    B   2 
T T

 ... 
 
 A3 

Preostalo je još uključiti tenzor reluktivnosti (recipročna permeabilnost)

1  rxx rxy 
 r   
  ryx ryy 

Množenjem matrice r (tenzor reluktivnosti) s rotacijom svake bazne funkcije koja ju aproksimira
tj. sa svakim retkom matrice rot(𝐴⃗𝑧 ) (što je ekvivalentno množenju s transponiranom matricom
rotacije 𝐴⃗𝑧 pa time i sa umnoškom transponirane matrice Bt i vektora varijable Az) dobivamo
umnožak matrice koju ćemo nazvati transponirana matrica Ht s vektorom varijable Az
 A1 
 rxx rxy   rxx rxy  A 
1
  Az   Ht   Az       Az     Bt   2
T T T
   ... 
  ryx ryy   ryx ryy 
 
 A3 

Implementacija izračuna matrice Ht u programskom kodu je


DO p = 1,nd

Ht(p,:) = MATMUL(nu_tensor, Bt(p,:))

END DO

Konačno cijeli integral se u sustavu nd jednadžbi prikazuje kao

 1  1  
 
     ( A1 k1 )    (k1 ) dS ...      ( A k )    (k )  dS 
  
1 1 nd
  
 STIFF  Az    ... ... ... 
 
 1  1 
 
      ( And k nd )    (k1 ) dS ...      ( A nd k nd )    
  (k nd ) dS 
     
Raspisivanjem jednog elementa prethodne matrice dobivamo

1 

STIFF (i, j )  Ai      ( Ai k i )     (k j ) dS


  

 1  d d    d j d j 
STIFF (i, j )  Ai  ( IP%s(t )  DetJ )  Ai  i i  i j     i j
   dy dx    dy dx 

Raspisivanjem svih integrala u gornjoj matrici i sortiranjem u matrični oblik dobiva se sljedeća
matrična jednadžba gdje skalarni izraz (IP % s(t) * DetJ) daje integralni smisao cijeloj matričnoj
jednadžbi tako što prema postupku numeričke integracije površinu trenutnog elementa (DetJ)
množi težinom trenutne integracijske točke (IP % s(t)).

 
T
 
 1    1  
T T
   1    1  
  y x  y x 
     
     A1 
    2    2  2   A 
 r rxy   2   
 STIFF  Az    ( IP%s(t )  DetJ )  rxx y x  
 y x   2 
   yx ryy   

    ... 
  ... ...   ... ...  A 
     
   nd 

   nd 
 nd 
   nd 
 nd  
   y x    y x  
   
Prepoznavanjem unutarnjih matrica kao matrica koje su definirane ranije slijedi konačan izraz za
STIFF matricu

 STIFF   ( IP%s(t )  DetJ ) r  Bt    Bt 


T T T

 STIFF   ( IP%s(t )  DetJ )   Ht  Bt 


T

Programska implementacija izračuna STIFF matrice prikazana je u nastavku


STIFF(1:nd,1:nd) = STIFF(1:nd,1:nd) + IP % s(t) * DetJ * &

MATMUL(Ht, TRANSPOSE(Bt)) !petlja se odvija za svaku integracijsku točku

FORCE VEKTOR
Izgradnja FORCE vektora je prilično izravna. Vektorska polja gustoće struje Jz i vektora
magnetizacije M koja predstavljaju izvor vektorskog polja magnetskog potencijala tj. varijable u
ovom solveru aproksimirana su pomoću baznih funkcija na sljedeći način
N
J z  k  J ii
i

N
M   M xii i  M yii j
i

Uvrštavanjem prethodnih suma u integral s desne strane slabe formulacije dobiva se jedan redak
(jedan element) vektora FORCE

 N  N 
  J

z 
  M adS    k  J i i     M xi i i  M yi i
  i  i
j   k j dS

Suma po gustoći struje u integracijskoj točki je već ranije izračunata kao LoadAtIP varijabla
N
LoadAtIP  J z  k  J ii
i

Pored toga, vektor magnetizacije M je pretpostavljen s z-komponentom jednakom nuli te nepromjenjivog


iznosa u z-smjeru.

  N   
FORCE ( j )    kLoadAtIP    M xi i k  M yi i k   k j dS
   i y x 

Dakle, konačan oblik vektora FORCE glasi


  1    
  LoadAtIP   M xi  M y1 1   1 
  y x   
 
 LoadAtIP   M  2  M  2    
 x2  2
 FORCE   ( IP%s(t )  DetJ )   y
y2
x   
 
 ... 
 
 LoadAtIP   M  n  M  n    
  xn  n
y x   
yn
 

Programska implementacija prethodnog izraza prikazana je u nastavku


FORCE(1:nd) = FORCE(1:nd) + IP % s(t) * DetJ * (LoadAtip * Basis(1:nd) + &

(M_ip(1)*dBasisdx(1:nd,2)-M_ip(2)*dBasisdx(1:nd,1)))

Time su definirane sve matrice (MASS i STIFF) te vektor FORCE ovog linearnog sustava. U slučaju
da je početna parcijalna diferencijalna jednadžba nelinearna potrebno je izgraditi i matricu JAC.

JAC MATRICA
U slučaju da je permeabilnost tijela zadana preko HB-krivulje, što znači da permeabilnost nije
konstantna nego ovisi o iznosu indukcije (dakle i o varijabli magnetskog vektorskog potencijala)
u elementu, slaba formulacija razmatrane diferencijalne jednadžbe više nije linearan problem jer
vrijednost parametra koji se u njoj nalazi (permeabilnost) ovisi o iznosu varijable, tj. o samom
rješenju diferencijalne jednadžbe, pa za rješenje općenito nije dovoljno samo riješiti linearni
sustav (matričnu jednadžbu) jer je na početku nužno pretpostaviti vrijednost permeabilnosti.
Dakle, fizikalni problem je postao nelinearan. Pristup rješavanju nelinearnog problema koji se u
tom slučaju ovdje primjenjuje jest linearizacija slabe formulacije te iterativno rješavanje
dobivenog linearnog sustava (matrične jednadžbe) putem Newton-Raphson metode.
Postupak linearizacije slabe formulacije se svodi na linearizaciju nelinearnih dijelova jednadžbe,
a to je u ovom slučaju samo parametar permeabilnosti. U nastavku je zapisana linearizacija
(diferencijacija) permeabilnosti, gdje ∆Ai predstavlja promjenu iznosa varijable tj. razliku trenutne
varijable i njene vrijednosti u prethodnoj iteraciji (∆Ai = Ai – POT(i)):

1 1  1  1  1


    A1    A2  ...    And
 0 A1    A2    And   

Parcijalna derivacija reluktivnosti (recipročne permeabilnosti) je provedena u nastavku

  1    H abs    H abs  Babs  1  H abs  H abs  Babs


          2 

Ai    Ai  Babs  Babs  Babs  Ai  Babs  Babs  Babs  Ai
Bx B  i 
2 Bx  2 By y Bx  By i
Babs  B B
2 2
Ai Ai y x
  
x y

Ai Ai 2 Bx2  By2 Babs

Konačan oblik parcijalne derivacije reluktivnosti je


nd
 1 nd
  i    1  H abs  H abs  1
 A       B y
 By i  
x   Babs
  2 

 Babs  Babs  Babs
x
i i   i 

Linearizirana verzija slabe formulacije glasi

 
 Az   1 nd   1   
 t
 adS     0 i Ai    i 
  A   A


z    a dS   J z    M adS   

 
 PROMJENA 

Ona se može rastaviti na zbroj linearne verzije slabe formulacije koju smo dosada razmatrali i
novog člana dobivenog linerizacijom reluktivnosti

 Az 1    nd   1   
  t 

adS      Az    a dS     
   
Ai   

Ai    Az    a dS   J z    M adS
   
      i   

NOVI INTEGRAL

Dakle, kako bi se uzela u obzir nelinearnost problema, dovoljno je dosadašnjem linearnom


sustavu samo dodati matrični oblik za NOVI INTEGRAL iz prethodne formulacije. Isti integral ćemo
ponovno zapisati te podesiti na način da se rotacija vektorskog magnetskog potencijala zapiše
kao magnetska indukcija, a rotacija test funkcije raspiše i potom pomnoži vektorom indukcije

  nd  1     nd  1     j  j 
   i Ai 
  i

A    A 
z    a dS 
 
   i Ai 
  i  B  

A   dS
       y x 

 nd   1    j  j 
      Ai  Bx  By  dS
  i
Ai     y x 

Uvrštavanjem parcijalne derivacije dobiva se konačan oblik jednog od nd integrala koji čini j-ti
redak matrice JAC koja predstavlja matricu novog integrala
nd
     1  H abs  H abs  1   j  j 
JAC ( j ,:)     Bx i  By i       B  B  dS
y x   Babs  Babs  Babs 2  Babs  y x 
x y
 i 

 1  H abs  H abs  1 nd
  i     j  j 
JAC ( j ,:)      
2 
    Bx  By i   Bx  By  dS
 Babs  Babs  Babs  Babs  i  y x   y x 
 1  H abs  H abs  1 nd
  i     j  j 
JAC ( j ,:)  ( IP%s(t )  DetJ )    2 
  B  By i   Bx  By 
 Babs  Babs y x  y x 
x
 Babs  Babs i 
muder

Programska implementacija prethodnog izraza prikazana je u nastavku


!Csymmetry još uvijek nije podložan Newtonovoj linearizaciji

IF (HBcurve .AND. NewtonRaphson) THEN !Ako je nelinearna formulacija i NR metoda =>JAC

DO p=1,nd !vanjska petlja

DO q=1,nd !unutarnja petlja

JAC(p,q) = JAC(p,q) + IP % s(t) * DetJ * &

muder/babs*SUM(B_ip(:)*Bt(q,:))*SUM(B_ip*Bt(p,:))

END DO

END DO

END IF

END DO !završetak petlje numeričke integracije po svim integracijskim točkama

Ako je permeabilnost zadana preko HB-krivulje što znači da je u pitanju nelinearna formulacija
te ako se koristi Newton-Raphson metoda tada se matrica JAC dodaje STIFF matrici što znači da
će ju Elmer pri rješavanju linearnog sustava množiti vektorom varijable, a također se dodaje i
FORCE vektoru nakon prethodnog množenja vektorom POT koji predstavlja vrijednost varijable
iz prethodne iteracije čime je ostvaren ∆Ai iz diferencijala reluktivnosti ∆Ai = Ai – POT(i)
IF (HBcurve .AND. NewtonRaphson) THEN

STIFF = STIFF + JAC

FORCE = FORCE + MATMUL(JAC,POT)

END IF

Ako je u pitanju tranzijentna tj. vremenski promjenjiva simulacija tada će vremenska derivacija
varijable biti općenito različita od nule pa se poziva interna rutina Default1stOrderTime() koja
automatski na osnovu elemenata MASS matrice dodaje utjecaj vremenske derivacije varijable u
sustav te time izgrađuje konačne verzije STIFF matrice i FORCE vektora.
IF(TransientSimulation) THEN

CALL Default1stOrderTime( MASS, STIFF, FORCE,UElement=Element, USolver=Solver )

END IF

Na kraju se poziva interna rutina DefaultUpdateEquations() koja izgrađenu lokalnu matricu


ugrađuje u globalnu matricu čime je završena LocalMatrix rutina.
CALL DefaultUpdateEquations( STIFF, FORCE,UElement=Element, USolver=Solver)

You might also like