renormvec.c

Go to the documentation of this file.
00001 /*
00002     This file is part of magpar.
00003 
00004     Copyright (C) 2002-2010 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: renormvec.c 2962 2010-02-04 19:50:44Z scholz $\n\n";
00025 static char const Td[] = "$Today: " __FILE__ "  " __DATE__ "  "  __TIME__  " $\n\n";
00026 
00027 #include "util.h"
00028 
00029 PetscReal RenormVec(Vec v, PetscReal normset, PetscReal normtol, int dim)
00030 {
00031   MagparFunctionInfoBegin;
00032 
00033   int t_vlen;
00034   ierr = VecGetLocalSize(v,(PetscInt*)&t_vlen);CHKERRQ(ierr);
00035   assert(t_vlen%dim==0);
00036 
00037   PetscReal *ta_v;
00038   ierr = VecGetArray(v,&ta_v);CHKERRQ(ierr);
00039 
00040   assert(dim==ND); /* otherwise replace my_* calls by cblas calls again */
00041 
00042   PetscReal normmax,normmin;
00043   normmax=0;
00044   normmin=PETSC_MAX;
00045   for (int i=0;i<t_vlen/dim;i++) {
00046     PetscReal nrm;
00047     nrm=my_dnrm2(dim,ta_v+dim*i,1);
00048     normmax=PetscMax(normmax,nrm);
00049     normmin=PetscMin(normmin,nrm);
00050   }
00051 
00052   PetscReal gnormmax,gnormmin;
00053   ierr = PetscGlobalMax(&normmax,&gnormmax,PETSC_COMM_WORLD);CHKERRQ(ierr);
00054   ierr = PetscGlobalMin(&normmin,&gnormmin,PETSC_COMM_WORLD);CHKERRQ(ierr);
00055 
00056   PetscReal normdev;
00057   normdev = PetscMax(PetscAbsReal(gnormmax-normset),
00058                      PetscAbsReal(gnormmin-normset));
00059 
00060   /* rescale vectors only if maximum deviation is larger than tolerance */
00061   if (PetscAbsReal(normdev) > normtol) {
00062     for (int i=0;i<t_vlen/dim;i++) {
00063       /* recalculate norm since we did not store it anywhere */
00064       PetscReal nrm;
00065       nrm=my_dnrm2(dim,ta_v+dim*i,1);
00066 
00067       /* work around problems if nrm is small */
00068       if (nrm>D_EPS) {
00069         my_dscal(dim,normset/nrm,ta_v+dim*i,1);
00070       }
00071       /* if nrm is too small and normtol==0
00072          set vector (at will) parallel to z-axis
00073          TODO: good idea? problem for GMR calculation
00074       */
00075       /*
00076       else if (normtol==0){
00077       */
00078       else {
00079         ta_v[dim*i+0]=0.0;
00080         ta_v[dim*i+1]=0.0;
00081         ta_v[dim*i+2]=1.0;
00082       }
00083     }
00084   }
00085 
00086   VecRestoreArray(v,&ta_v);
00087 
00088   MagparFunctionInfoReturn(normdev);
00089 }
00090 

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