hcubic.c

Go to the documentation of this file.
00001 /*
00002     This file is part of magpar.
00003 
00004     Copyright (C) 2005-2009 Greg Parker, Werner Scholz
00005 
00006     www:   http://www.magpar.net/
00007     email: magpar(at)magpar.net
00008 
00009     magpar is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     magpar is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with magpar; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 */
00023 
00024 static char const Id[] = "$Id: hcubic.c 2681 2009-07-31 04:30:53Z scholz $\n\n";
00025 static char const Td[] = "$Today: " __FILE__ "  " __DATE__ "  "  __TIME__  " $\n\n";
00026 
00027 #include "field.h"
00028 
00029 static int       doinit=1;
00030 static int       fieldon=0;
00031 static Vec       VHcubic;
00032 #ifdef EXCH
00033 static PetscReal Ecubic;
00034 #endif
00035 
00036 int Hcubic_Init(GridData *gdata)
00037 {
00038   MagparFunctionLogBegin;
00039 
00040   for (int i=0;i<gdata->n_prop;i++) {
00041     if (gdata->propdat[NP*i+16]==1 ||
00042         PetscAbsReal(gdata->propdat[NP*i+ 3]) > D_EPS) {
00043       /* FIXME: latter case not really cubic, but hcubic.c calculates the K_2 term
00044          anisotropy field calculation then off!? Hani calculated twice?
00045       */
00046       fieldon=1;
00047       break;
00048     }
00049   }
00050 
00051   if (fieldon) {
00052     PetscPrintf(PETSC_COMM_WORLD,"Hcubic on\n");
00053     ierr = VecDuplicate(gdata->M,&VHcubic);CHKERRQ(ierr);
00054   }
00055   else {
00056     PetscPrintf(PETSC_COMM_WORLD,"Hcubic off\n");
00057   }
00058 
00059   MagparFunctionLogReturn(0);
00060 }
00061 
00062 
00063 int Hcubic(GridData *gdata,Vec VHtotsum)
00064 {
00065   MagparFunctionInfoBegin;
00066 
00067   /* initialize if necessary */
00068   if (doinit) {
00069     ierr = Hcubic_Init(gdata);CHKERRQ(ierr);
00070     doinit=0;
00071   }
00072   if (!fieldon) {
00073     MagparFunctionInfoReturn(0);
00074   }
00075 
00076   PetscReal *ta_Hcubic,*ta_M;
00077   ierr = VecGetArray(VHcubic,&ta_Hcubic);CHKERRQ(ierr);
00078   ierr = VecGetArray(gdata->M,&ta_M);CHKERRQ(ierr);
00079 
00080 #ifdef EXCH
00081   PetscReal *ta_VMs3;
00082   ierr = VecGetArray(gdata->VMs3,&ta_VMs3);CHKERRQ(ierr);
00083   Ecubic=0.0;
00084 #endif
00085 
00086   /* TODO: for nodes at interfaces, the assignment is "at will" */
00087   for (int j=0; j<gdata->ln_vert; j++) {
00088     if (gdata->propdat[NP*gdata->vertprop[j]+16]) {
00089 
00090       /* only collect cubic Hk if 'grain' has cubic Hk */
00091       PetscReal k1,k2,jsi;
00092       jsi=gdata->propdat[NP*gdata->vertprop[j]+4];
00093       /* FIXME: why 1e-20? */
00094       jsi /= (jsi*jsi+1.e-20);
00095       k1=gdata->propdat[NP*gdata->vertprop[j]+2]*jsi;
00096       k2=gdata->propdat[NP*gdata->vertprop[j]+3]*jsi;
00097 
00098       /* a-axis of cubic crystal */
00099       PetscReal ax,ay,az;
00100       ax=gdata->propdat[NP*gdata->vertprop[j]+6];
00101       ay=gdata->propdat[NP*gdata->vertprop[j]+7];
00102       az=gdata->propdat[NP*gdata->vertprop[j]+8];
00103 
00104       /* b-axis of cubic crystal */
00105       PetscReal bx,by,bz;
00106       bx=gdata->propdat[NP*gdata->vertprop[j]+10];
00107       by=gdata->propdat[NP*gdata->vertprop[j]+11];
00108       bz=gdata->propdat[NP*gdata->vertprop[j]+12];
00109 
00110       /* c-axis of cubic crystal */
00111       PetscReal cx,cy,cz;
00112       cx=gdata->propdat[NP*gdata->vertprop[j]+13];
00113       cy=gdata->propdat[NP*gdata->vertprop[j]+14];
00114       cz=gdata->propdat[NP*gdata->vertprop[j]+15];
00115 
00116       /* get components of M */
00117       PetscReal mx,my,mz;
00118       mx=ta_M[ND*j+0];
00119       my=ta_M[ND*j+1];
00120       mz=ta_M[ND*j+2];
00121 
00122       /* direction cosines and their squares */
00123       PetscReal a1,a2,a3;
00124       a1=mx*ax+my*ay+mz*az;
00125       a2=mx*bx+my*by+mz*bz;
00126       a3=mx*cx+my*cy+mz*cz;
00127 
00128       PetscReal a12,a22,a32;
00129       a12=a1*a1;
00130       a22=a2*a2;
00131       a32=a3*a3;
00132 
00133       /* a_i ( K1 (a_j^2 a_k^2) + K2 a_j^2 a_k^2) and permutations */
00134       PetscReal b1,b2,b3;
00135       b1=-2.0*a1*(k1*(a22+a32)+k2*a22*a32);
00136       b2=-2.0*a2*(k1*(a12+a32)+k2*a12*a32);
00137       b3=-2.0*a3*(k1*(a12+a22)+k2*a12*a22);
00138 
00139       /* assemble cubic H components */
00140       ta_Hcubic[ND*j+0] = ax*b1+bx*b2+cx*b3;
00141       ta_Hcubic[ND*j+1] = ay*b1+by*b2+cy*b3;
00142       ta_Hcubic[ND*j+2] = az*b1+bz*b2+cz*b3;
00143 
00144 #ifdef EXCH
00145       Ecubic +=
00146         (k1*(a12*a22+a12*a32+a22*a32)+k2*a12*a22*a32)*ta_VMs3[ND*j+0];
00147     }
00148     else if (gdata->propdat[NP*gdata->vertprop[j]+3] != 0.0) {
00149       PetscReal k2,jsi;
00150       /* might as well do uniaxial k2 term... */
00151 
00152       jsi=gdata->propdat[NP*gdata->vertprop[j]+4];
00153       jsi /= (jsi*jsi+1.e-20);
00154 
00155       /* k2/Js */
00156       k2=gdata->propdat[NP*gdata->vertprop[j]+3]*jsi;
00157 
00158       /* easy axis of uniaxial crystal */
00159       PetscReal ax,ay,az;
00160       ax=gdata->propdat[NP*gdata->vertprop[j]+6];
00161       ay=gdata->propdat[NP*gdata->vertprop[j]+7];
00162       az=gdata->propdat[NP*gdata->vertprop[j]+8];
00163 
00164       PetscReal a1,a2;
00165       a1=ax*ta_M[ND*j+0]+ay*ta_M[ND*j+1]+az*ta_M[ND*j+2];  /* m.k */
00166       /* field magnitude: 4 k2 (m.k) (1-(m.k)^2) / Js */
00167       a2=4.0*k2*a1*(1.0-a1*a1);
00168 
00169       /* energy: k2(1-(m.k)^2)^2 * volume */
00170       Ecubic += k2*(1.0-a1*a1)*(1.0-a1*a1)*ta_VMs3[ND*j+0];
00171 
00172       /* assemble cubic H components */
00173       ta_Hcubic[ND*j+0] = ax*a2;
00174       ta_Hcubic[ND*j+1] = ay*a2;
00175       ta_Hcubic[ND*j+2] = az*a2;
00176 #endif
00177     }
00178     else {
00179       ta_Hcubic[ND*j+0] = 0.0;
00180       ta_Hcubic[ND*j+1] = 0.0;
00181       ta_Hcubic[ND*j+2] = 0.0;
00182     }
00183   }
00184 
00185   ierr = VecRestoreArray(gdata->M,&ta_M);CHKERRQ(ierr);
00186   ierr = VecRestoreArray(VHcubic,&ta_Hcubic);CHKERRQ(ierr);
00187 #ifdef EXCH
00188   ierr = VecRestoreArray(gdata->VMs3,&ta_VMs3);CHKERRQ(ierr);
00189 #endif
00190 
00191   ierr = VecAXPY(VHtotsum,1.0,VHcubic);CHKERRQ(ierr);
00192 
00193   MagparFunctionProfReturn(0);
00194 }
00195 
00196 
00197 int Hcubic_Energy(GridData *gdata,Vec VMom,PetscReal *energy)
00198 {
00199   PetscReal e;
00200 
00201   MagparFunctionInfoBegin;
00202 
00203   if (!fieldon) {
00204     *energy=0.0;
00205     MagparFunctionInfoReturn(0);
00206   }
00207 
00208 #ifdef EXCH
00209   ierr = PetscGlobalSum(&Ecubic,&e,PETSC_COMM_WORLD);CHKERRQ(ierr);
00210 #else
00211   /* only correct if K2=0, otherwise K2 term scaled by -1/6, not -1/4 */
00212   ierr = VecDot(VMom,VHcubic,&e);CHKERRQ(ierr);
00213   e /= -4.0;
00214 #endif
00215 
00216   *energy=e;
00217 
00218   MagparFunctionProfReturn(0);
00219 }
00220 

magpar - Parallel Finite Element Micromagnetics Package
Copyright (C) 2002-2009 Werner Scholz