magset.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: magset.c 2753 2009-08-31 14:49:58Z scholz $\n\n";
00025 static char const Td[] = "$Today: " __FILE__ "  " __DATE__ "  "  __TIME__  " $\n\n";
00026 
00027 #include "init.h"
00028 #include "io/magpario.h"
00029 #include "util/util.h"
00030 
00031 int MagSet(int pid,int init_mag,PetscReal init_magparm,GridData *gdata)
00032 {
00033   MagparFunctionLogBegin;
00034 
00035   int rank,size;
00036   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
00037   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
00038 
00039 
00040   PetscPrintf(PETSC_COMM_WORLD,"pid:          %i\n",pid+1);
00041   PetscPrintf(PETSC_COMM_WORLD,"init_mag:     %i\n",init_mag);
00042   PetscPrintf(PETSC_COMM_WORLD,"init_magparm: %g\n",init_magparm);
00043 
00044   if (init_mag==0) {
00045     char fmesh[256];
00046     PetscPrintf(PETSC_COMM_WORLD,"inp file to be read: %s.%04d.inp\n",gdata->simname,gdata->inp);
00047     ierr = PetscSNPrintf(fmesh,255,"%s.%04d.inp",gdata->simname,gdata->inp);CHKERRQ(ierr);
00048     gdata->inp++;
00049 
00050     ierr = ReadINP(gdata,fmesh,gdata->M,1);CHKERRQ(ierr);
00051     MagparFunctionLogReturn(0);
00052   }
00053   else if (PetscAbsInt(init_mag)==14) {
00054 #ifdef PYTHON
00055     if (!rank) {
00056       /* Python stuff */
00057 
00058       if(!gdata->pModule) {
00059         SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Cannot execute Python function. Module %s has not been imported!\n",MAGPARSTDPYTHONMOD);
00060       }
00061 
00062 #define INITMAG "initmag"
00063       PyObject *pFunc;
00064       pFunc=PyObject_GetAttrString(gdata->pModule,INITMAG);  /* new reference */
00065       if(!pFunc) {
00066         SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Cannot find Python function %s!\n",INITMAG);
00067       }
00068       if (!PyCallable_Check(pFunc)) {
00069         SETERRQ1(PETSC_ERR_ARG_CORRUPT,"Python object %s is not callable (not a function)!\n",INITMAG);
00070       }
00071 
00072       /* Arguments for the module */
00073       PyObject *pTuple;
00074       pTuple = PyTuple_New(ND); /* new reference */
00075 
00076       PyObject *pVal=PETSC_NULL;
00077 
00078       /* this example sets the external field in a certain area to a
00079          non-zero value and everywhere else to zero
00080       */
00081 
00082       /* make the magnetization vector accessible */
00083       PetscReal *ta_M;
00084       ierr = VecGetArray(gdata->M,&ta_M);CHKERRQ(ierr);
00085 
00086       /* loop over all nodes */
00087       for (int j=0; j<gdata->n_vert; j++) {
00088         PetscReal x,y,z;
00089         x=gdata->vertxyz[ND*j+0];
00090         y=gdata->vertxyz[ND*j+1];
00091         z=gdata->vertxyz[ND*j+2];
00092 
00093         PyTuple_SetItem(pTuple,0,PyFloat_FromDouble(x)); /* The tuple steals the reference */
00094         PyTuple_SetItem(pTuple,1,PyFloat_FromDouble(y));
00095         PyTuple_SetItem(pTuple,2,PyFloat_FromDouble(z));
00096 
00097         /* Call the Python function */
00098         pVal = PyObject_CallObject(pFunc,pTuple);  /* new reference */
00099 
00100         /* set magnetization */
00101         for (int i=0; i<ND; i++) {
00102           ta_M[ND*j+i]=PyFloat_AsDouble(PyTuple_GetItem(pVal,i));
00103         }
00104       }
00105 
00106       ierr = VecRestoreArray(gdata->M,&ta_M);CHKERRQ(ierr);
00107 
00108       /* decrement references */
00109       Py_DECREF(pFunc);
00110       Py_DECREF(pTuple);
00111       Py_DECREF(pVal);
00112     }
00113 #else
00114     SETERRQ(PETSC_ERR_ARG_CORRUPT,"magpar not linked with Python interpreter. Cannot execute Python scripts!\n");
00115 #endif
00116   }
00117 
00118   if (rank) {
00119     VecAssemblyBegin(gdata->M);
00120     VecAssemblyEnd(gdata->M);
00121 
00122     /* rescale magnetization (required by init_mag==5) */
00123     RenormVec(gdata->M,1.0,0.0,ND);
00124 
00125     if (init_mag<0) {
00126       ierr = VecScale(gdata->M,-1.0);CHKERRQ(ierr);
00127     }
00128     MagparFunctionLogReturn(0);
00129   }
00130   else {
00131     PetscRandom rctx;
00132     ierr = PetscRandomCreate(PETSC_COMM_SELF,&rctx);CHKERRQ(ierr);
00133     ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr);
00134     /* assign property ids to vertices */
00135     ierr = VertProp(gdata);CHKERRQ(ierr);
00136 
00137     for (int i=0; i<gdata->n_vert; i++) {
00138       if (pid>=0 && gdata->vertprop[i]!=pid) continue;
00139       switch(PetscAbsInt(init_mag)) {
00140         case 0:
00141           /* taken care of before switch */
00142         break;
00143         case 1: /* Mx=1 */
00144           ierr = VecSetValue(gdata->M,ND*i+0,1.0,INSERT_VALUES);CHKERRQ(ierr);
00145           ierr = VecSetValue(gdata->M,ND*i+1,0.0,INSERT_VALUES);CHKERRQ(ierr);
00146           ierr = VecSetValue(gdata->M,ND*i+2,0.0,INSERT_VALUES);CHKERRQ(ierr);
00147         break;
00148         case 2: /* My=1 */
00149           ierr = VecSetValue(gdata->M,ND*i+0,0.0,INSERT_VALUES);CHKERRQ(ierr);
00150           ierr = VecSetValue(gdata->M,ND*i+1,1.0,INSERT_VALUES);CHKERRQ(ierr);
00151           ierr = VecSetValue(gdata->M,ND*i+2,0.0,INSERT_VALUES);CHKERRQ(ierr);
00152         break;
00153         case 3: /* Mz=1 */
00154           ierr = VecSetValue(gdata->M,ND*i+0,0.0,INSERT_VALUES);CHKERRQ(ierr);
00155           ierr = VecSetValue(gdata->M,ND*i+1,0.0,INSERT_VALUES);CHKERRQ(ierr);
00156           ierr = VecSetValue(gdata->M,ND*i+2,1.0,INSERT_VALUES);CHKERRQ(ierr);
00157         break;
00158         case 4: /* Mx=My=Mz=0.57735027 */
00159           ierr = VecSetValue(gdata->M,ND*i+0,0.57735027,INSERT_VALUES);CHKERRQ(ierr);
00160           ierr = VecSetValue(gdata->M,ND*i+1,0.57735027,INSERT_VALUES);CHKERRQ(ierr);
00161           ierr = VecSetValue(gdata->M,ND*i+2,0.57735027,INSERT_VALUES);CHKERRQ(ierr);
00162         break;
00163         case 5: /* artificial flower state */
00164           ierr = VecSetValue(gdata->M,ND*i+0,gdata->vertxyz[ND*i+0]-init_magparm,INSERT_VALUES);CHKERRQ(ierr);
00165           ierr = VecSetValue(gdata->M,ND*i+1,gdata->vertxyz[ND*i+1]-init_magparm,INSERT_VALUES);CHKERRQ(ierr);
00166           ierr = VecSetValue(gdata->M,ND*i+2,1.0,INSERT_VALUES);CHKERRQ(ierr);
00167         break;
00168         case 6: /* set magnetization in x-z plane to theta=init_magpar */
00169           ierr = VecSetValue(gdata->M,ND*i+0,sin(init_magparm),INSERT_VALUES);CHKERRQ(ierr);
00170           ierr = VecSetValue(gdata->M,ND*i+1,0.0,INSERT_VALUES);CHKERRQ(ierr);
00171           ierr = VecSetValue(gdata->M,ND*i+2,cos(init_magparm),INSERT_VALUES);CHKERRQ(ierr);
00172         break;
00173         case 7: /* vortex centered at (0,0) with radius R=init_magparm:
00174                  * if R>0, then vortex is clockwise in xy plane.
00175                  * if R<0, then vortex is counter-clockwise in xy plane.
00176                  * center of vortex points in -z direction.
00177                  */
00178           {
00179             PetscReal x, y, r, R, A;
00180             PetscReal modmx,modmy,modmz;
00181 
00182             x = gdata->vertxyz[ND*i+0];
00183             y = gdata->vertxyz[ND*i+1];
00184             r = sqrt(x*x + y*y);
00185             R = init_magparm;
00186 
00187             A = 2.0*R*r/(R*R+r*r);
00188             if (r <= fabs(R)) {
00189               if (r > 1e-10) {
00190                 modmx = A*y/r;
00191                 modmy = -A*x/r;
00192                 modmz = -sqrt(1.0-A*A);
00193               } else {
00194                 modmx=0.0;
00195                 modmy=0.0;
00196                 modmz=-1.0;
00197               }
00198             } else {
00199               modmx=y/r;
00200               modmy=-x/r;
00201               modmz=0.0;
00202             }
00203             ierr = VecSetValue(gdata->M,ND*i+0,modmx,INSERT_VALUES);CHKERRQ(ierr);
00204             ierr = VecSetValue(gdata->M,ND*i+1,modmy,INSERT_VALUES);CHKERRQ(ierr);
00205             ierr = VecSetValue(gdata->M,ND*i+2,modmz,INSERT_VALUES);CHKERRQ(ierr);
00206           }
00207         break;
00208         case 8: /* random magnetization - inaccurate: not uniform on unit sphere! */
00209           PetscReal rval[ND],rnorm;
00210 
00211           PetscRandomGetValue(rctx,&rval[0]);
00212           PetscRandomGetValue(rctx,&rval[1]);
00213           PetscRandomGetValue(rctx,&rval[2]);
00214           rnorm=my_dnrm2(ND,rval,1);
00215 
00216           for (int k=0; k<ND; k++) {
00217             ierr = VecSetValue(
00218               gdata->M,
00219               ND*i+k,
00220               rval[k]/rnorm*2.0-1.0,
00221               INSERT_VALUES
00222             );CHKERRQ(ierr);
00223           }
00224         break;
00225         case 9: /* Bloch wall at x=+9.5 */
00226           if (gdata->vertxyz[ND*i+0] < init_magparm*0.95) {
00227             ierr = VecSetValue(gdata->M,ND*i+0, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00228             ierr = VecSetValue(gdata->M,ND*i+1, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00229             ierr = VecSetValue(gdata->M,ND*i+2,+1.0,INSERT_VALUES);CHKERRQ(ierr);
00230           }
00231           else if (gdata->vertxyz[ND*i+0] > init_magparm*1.05) {
00232             ierr = VecSetValue(gdata->M,ND*i+0, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00233             ierr = VecSetValue(gdata->M,ND*i+1, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00234             ierr = VecSetValue(gdata->M,ND*i+2,-1.0,INSERT_VALUES);CHKERRQ(ierr);
00235           }
00236           else {
00237             ierr = VecSetValue(gdata->M,ND*i+0, 0.1,INSERT_VALUES);CHKERRQ(ierr);
00238             ierr = VecSetValue(gdata->M,ND*i+1,-0.9,INSERT_VALUES);CHKERRQ(ierr);
00239             ierr = VecSetValue(gdata->M,ND*i+2, 0.1,INSERT_VALUES);CHKERRQ(ierr);
00240           }
00241         break;
00242         case 10: /* magnetization parallel to anisotropy axes */
00243           for (int k=0; k<ND; k++) {
00244             ierr = VecSetValue(
00245               gdata->M,
00246               ND*i+k,
00247               gdata->propdat[NP*gdata->vertprop[i]+6+k],
00248               INSERT_VALUES
00249             );CHKERRQ(ierr);
00250           }
00251         break;
00252         case 11: /* set magnetization in x-y plane to alpha=init_magparm */
00253           ierr = VecSetValue(gdata->M,ND*i+0,cos(init_magparm*M_PI/180.0),INSERT_VALUES);CHKERRQ(ierr);
00254           ierr = VecSetValue(gdata->M,ND*i+1,sin(init_magparm*M_PI/180.0),INSERT_VALUES);CHKERRQ(ierr);
00255           ierr = VecSetValue(gdata->M,ND*i+2,0.0,INSERT_VALUES);CHKERRQ(ierr);
00256         break;
00257         case 12: /* Head-to-head transverse wall at x=init_magparm */
00258           if (gdata->vertxyz[ND*i+0] < init_magparm*0.95) {
00259             ierr=VecSetValue(gdata->M,ND*i+0, 1.0,INSERT_VALUES);CHKERRQ(ierr);
00260             ierr=VecSetValue(gdata->M,ND*i+1, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00261             ierr=VecSetValue(gdata->M,ND*i+2, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00262           }
00263           else if (gdata->vertxyz[ND*i+0] > init_magparm*1.05) {
00264             ierr=VecSetValue(gdata->M,ND*i+0,-1.0,INSERT_VALUES);CHKERRQ(ierr);
00265             ierr=VecSetValue(gdata->M,ND*i+1, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00266             ierr=VecSetValue(gdata->M,ND*i+2, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00267           }
00268           else {
00269             ierr=VecSetValue(gdata->M,ND*i+0, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00270             ierr=VecSetValue(gdata->M,ND*i+1, 1.0,INSERT_VALUES);CHKERRQ(ierr);
00271             ierr=VecSetValue(gdata->M,ND*i+2, 0.0,INSERT_VALUES);CHKERRQ(ierr);
00272           }
00273         break;
00274         case 13: /* Head-to-head vortex wall at (0,0) with radius R=init_magparm:
00275                   * if R>0, then vortex is clockwise in xy plane.
00276                   * if R<0, then vortex is counter-clockwise in xy plane.
00277                   * center of vortex points in -z direction.
00278                   */
00279           {
00280             PetscReal x, y, r, R, A;
00281             PetscReal modmx,modmy,modmz;
00282 
00283             x = gdata->vertxyz[ND*i+0];
00284             y = gdata->vertxyz[ND*i+1];
00285             r = sqrt(x*x + y*y);
00286             R = init_magparm;
00287 
00288             A = 2.0*R*r/(R*R+r*r);
00289             if (r <= fabs(R)) {
00290               if (r > 1e-10) {
00291                 modmx = A*y/r;
00292                 modmy = -A*x/r;
00293                 modmz = -sqrt(1.0-A*A);
00294               } else {
00295                 modmx = 0.0;
00296                 modmy = 0.0;
00297                 modmz = -1.0;
00298               }
00299             } else {
00300               modmx = (x<0.0 ? +1.0 : -1.0);
00301               modmy = 0.0;
00302               modmz = 0.0;
00303             }
00304             ierr = VecSetValue(gdata->M,ND*i+0,modmx,INSERT_VALUES);CHKERRQ(ierr);
00305             ierr = VecSetValue(gdata->M,ND*i+1,modmy,INSERT_VALUES);CHKERRQ(ierr);
00306             ierr = VecSetValue(gdata->M,ND*i+2,modmz,INSERT_VALUES);CHKERRQ(ierr);
00307           }
00308         break;
00309         case 14:
00310           /* taken care of before switch */
00311         break;
00312         default:
00313           SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"init_mag value %i is illegal!\n",PetscAbsInt(init_mag));
00314         break;
00315       }
00316     }
00317 
00318     ierr = PetscRandomDestroy(rctx);CHKERRQ(ierr);
00319     ierr = PetscFree(gdata->vertprop);CHKERRQ(ierr);
00320     gdata->vertprop=PETSC_NULL;
00321   }
00322 
00323   ierr = VecAssemblyBegin(gdata->M);CHKERRQ(ierr);
00324   ierr = VecAssemblyEnd(gdata->M);CHKERRQ(ierr);
00325 
00326   /* rescale magnetization (required by init_mag==5) */
00327   RenormVec(gdata->M,1.0,0.0,ND);
00328 
00329   if (init_mag<0) {
00330     ierr = VecScale(gdata->M,-1.0);CHKERRQ(ierr);
00331   }
00332 
00333   MagparFunctionLogReturn(0);
00334 }

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