htot.c

Go to the documentation of this file.
00001 /*
00002     This file is part of magpar.
00003 
00004     Copyright (C) 2002-2009 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: htot.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 #ifdef ADDONS
00030 #include "addons/addons.h"
00031 #endif
00032 
00033 #ifdef SPINTORQ
00034 #include "spintorq/spintorq.h"
00035 #endif
00036 
00037 static int doinit=1;
00038 static Vec VHtotsum=PETSC_NULL;
00039 static Vec VMom; 
00041 int Htot_Init(GridData *gdata)
00042 {
00043   MagparFunctionLogBegin;
00044 
00045   PetscPrintf(PETSC_COMM_WORLD,"Htot on\n");
00046 
00047   ierr = VecDuplicate(gdata->M,&gdata->VHtot);CHKERRQ(ierr);
00048   ierr = VecDuplicate(gdata->M,&VMom);CHKERRQ(ierr);
00049   ierr = VecDuplicate(gdata->M,&VHtotsum);CHKERRQ(ierr);
00050 
00051   MagparFunctionLogReturn(0);
00052 }
00053 
00054 
00055 int Htot(GridData *gdata)
00056 {
00057   MagparFunctionInfoBegin;
00058 
00059   /* initialize if necessary */
00060   if (doinit) {
00061     ierr = Htot_Init(gdata);CHKERRQ(ierr);
00062     doinit=0;
00063   }
00064 
00065   ierr = VecZeroEntries(VHtotsum);CHKERRQ(ierr);
00066 
00067   ierr = Hcubic(gdata,VHtotsum);CHKERRQ(ierr);
00068   ierr = Hdemag(gdata,VHtotsum);CHKERRQ(ierr);
00069   ierr = Helastic(gdata,VHtotsum);CHKERRQ(ierr);
00070   ierr = Hexchani(gdata,VHtotsum);CHKERRQ(ierr);
00071   ierr = Hexternal(gdata,VHtotsum);CHKERRQ(ierr);
00072 #ifdef ADDONS
00073   ierr = HIlayerExch(gdata,VHtotsum);CHKERRQ(ierr);
00074   ierr = Hnonlin(gdata,VHtotsum);CHKERRQ(ierr);
00075 #endif
00076 #ifdef SPINTORQ
00077   /* initialize vectors to NULL */
00078   gdata->VHspintorque=PETSC_NULL;
00079   gdata->VHspinforce=PETSC_NULL;
00080 
00081   ierr = Hspintorq(gdata);CHKERRQ(ierr);
00082   ierr = Hspinforce(gdata);CHKERRQ(ierr);
00083 
00084   if (gdata->VHspintorque!=PETSC_NULL && gdata->VHspinforce!=PETSC_NULL) {
00085     SETERRQ(PETSC_ERR_ARG_INCOMP,"Spin torque and spin force are switched on at the same time!\n");
00086   }
00087 #endif
00088 
00089   ierr = VecCopy(VHtotsum,gdata->VHtot);CHKERRQ(ierr);
00090 
00091   MagparFunctionProfReturn(0);
00092 }
00093 
00094 
00095 int Htot_Gradient(GridData *gdata)
00096 {
00097   Vec VHtemp;
00098 
00099   MagparFunctionInfoBegin;
00100 
00101   /* abusing VMom */
00102   VHtemp=VMom;
00103 
00104   /* initialize if necessary */
00105   if (doinit) {
00106     ierr = Htot_Init(gdata);CHKERRQ(ierr);
00107     doinit=0;
00108   }
00109 
00110 #if 1
00111   /* gives correct result for Etot in example mumag3: 1.240375e+05 ; LLG: 1.240388e+05 */
00112   /* appears to converge faster for example fept, headfield_nonlin w/o demag (but higher Etot) ! */
00113   /*
00114   m=M*Ms*V
00115   grad(E)=dE/dm=dE/d(M*Ms*V)
00116   H=-dE/dm
00117   grad(E)=-H*Ms*V
00118 
00119   However, Ms and V are fixed and only M varies.
00120 
00121   grad(E)=dE/dM=Ms*V*dE/d(M*Ms*V)=Ms*V*dE/dm=Ms*V*(-H)
00122   */
00123 
00124   ierr = Htot(gdata);CHKERRQ(ierr);
00125 
00126   /* This scaling with gdata->VMs3 is necessary for big writer models to converge properly.
00127      Causes wiggles in M in headfield_nonlin while iterating, but converges fine.
00128   */
00129   ierr = VecPointwiseMult(gdata->VHtot,gdata->VHtot,gdata->VMs3);CHKERRQ(ierr);
00130 #else
00131   /* for comparison between hand-coded and TAO's finite difference gradient: magpar_examples5/cube_test_grad */
00132   /* gives incorrect result for Etot in example mumag3: 1.256195e+05 (too high) */
00133 
00134   ierr = VecZeroEntries(VHtotsum);CHKERRQ(ierr);
00135 
00136   /* calculate field/gradient contributions and apply fudge (?) factor */
00137   VecZeroEntries(VHtemp);Hcubic(gdata,VHtemp);     VecAXPY(VHtotsum,2.0,VHtemp); /* ok */
00138   VecZeroEntries(VHtemp);Hdemag(gdata,VHtemp);     VecAXPY(VHtotsum,1.0,VHtemp); /* ok */
00139   VecZeroEntries(VHtemp);Helastic(gdata,VHtemp);   VecAXPY(VHtotsum,4.0,VHtemp); /* ok */
00140   VecZeroEntries(VHtemp);Hexchani(gdata,VHtemp);   VecAXPY(VHtotsum,2.0,VHtemp); /* ok */
00141   VecZeroEntries(VHtemp);Hexternal(gdata,VHtemp);  VecAXPY(VHtotsum,2.0,VHtemp); /* ok */
00142 #ifdef ADDONS
00143   VecZeroEntries(VHtemp);HIlayerExch(gdata,VHtemp);VecAXPY(VHtotsum,2.0,VHtemp); /* TODO: to be verified */
00144   VecZeroEntries(VHtemp);Hnonlin(gdata,VHtemp);    VecAXPY(VHtotsum,4.0,VHtemp); /* ok */
00145 #endif
00146 
00147   ierr = VecCopy(VHtotsum,gdata->VHtot);CHKERRQ(ierr);
00148   ierr = VecPointwiseMult(gdata->VHtot,gdata->VHtot,gdata->VMs3);CHKERRQ(ierr);
00149 
00150   /* scale gradient to get agreement between hand-coded and finite difference gradient */
00151   ierr = VecScale(gdata->VHtot,1.0/2.0);CHKERRQ(ierr);
00152 #endif
00153 
00154   ierr = VecScale(gdata->VHtot,-1.0);CHKERRQ(ierr);
00155 
00156   PetscReal *ta_Htot;
00157   VecGetArray(gdata->VHtot,&ta_Htot);
00158 
00159   /* TODO: set up Vec and do VecPointwiseMult instead of the loop */
00160   for (int i=0;i<gdata->ln_vert;i++) {
00161     /* skip non-magnetic vertices and vertices with alpha >= RIGID_M_ALPHA */
00162     if (gdata->propdat[NP*gdata->vertprop[i]+4]<=0.0 ||
00163         gdata->propdat[NP*gdata->vertprop[i]+9]>=RIGID_M_ALPHA) {
00164       ta_Htot[ND*i+0]=0.0;
00165       ta_Htot[ND*i+1]=0.0;
00166       ta_Htot[ND*i+2]=0.0;
00167       continue;
00168     }
00169   }
00170 
00171   VecRestoreArray(gdata->VHtot,&ta_Htot);
00172 
00173   MagparFunctionProfReturn(0);
00174 }
00175 
00176 
00177 int Htot_Energy(GridData *gdata)
00178 {
00179   MagparFunctionInfoBegin;
00180 
00181   /* calculate "magnetic moments" VMom on vertices */
00182   ierr = VecPointwiseMult(VMom,gdata->VMs3,gdata->M);CHKERRQ(ierr);
00183 
00184   PetscReal e,etot;
00185   etot=0;
00186 
00187   ierr = Hcubic_Energy(gdata,VMom,&e);     CHKERRQ(ierr);etot += e;gdata->Eexchani  = e/gdata->totvol; /* part of anisotropy energy */
00188   ierr = Hdemag_Energy(gdata,VMom,&e);     CHKERRQ(ierr);etot += e;gdata->Edem      = e/gdata->totvol;
00189   ierr = Helastic_Energy(gdata,VMom,&e);   CHKERRQ(ierr);etot += e;
00190   ierr = Hexchani_Energy(gdata,VMom,&e);   CHKERRQ(ierr);etot += e;gdata->Eexchani += e/gdata->totvol; /* add to anisotropy+exchange energy */
00191 #ifdef EXCH
00192   ierr = Hexchonly_Energy(gdata,VMom,&e);  CHKERRQ(ierr);          gdata->Eexchonly = e/gdata->totvol; /* don't add to etot!!! */
00193 #endif
00194   ierr = Hexternal_Energy(gdata,VMom,&e);  CHKERRQ(ierr);etot += e;gdata->Eext      = e/gdata->totvol;
00195 #ifdef ADDONS
00196   ierr = HIlayerExch_Energy(gdata,VMom,&e);CHKERRQ(ierr);etot += e;gdata->Eexchani += e/gdata->totvol; /* add to anisotropy+exchange energy */
00197   ierr = Hnonlin_Energy(gdata,VMom,&e);    CHKERRQ(ierr);etot += e;gdata->Eexchani += e/gdata->totvol; /* add to anisotropy+exchange energy */
00198 #ifdef EXCH
00199                                                                    gdata->Eexchonly+= e/gdata->totvol; /* add to exchange only energy */
00200 #endif
00201 #endif
00202 #ifdef SPINTORQ
00203 /* TODO: implement
00204   ierr = Hspintorq_Energy(gdata,VMom,&e);  CHKERRQ(ierr);etot += e;
00205   ierr = Hspinforce_Energy(gdata,VMom,&e); CHKERRQ(ierr);etot += e;
00206 */
00207 #endif
00208 
00209   gdata->Etot=etot/gdata->totvol;
00210 
00211   MagparFunctionProfReturn(0);
00212 }
00213 

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