solidangle.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: solidangle.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 int PointFromPlane(PetscReal *x, PetscReal *v1, PetscReal *v2, PetscReal *v3, PetscReal *d)
00030 {
00031   PetscReal  ab[ND],ac[ND];
00032   PetscReal  n[ND];
00033 
00034   /* calculate edge vectors */
00035   my_dcopy(ND,v1,1,ab,1);
00036   my_daxpy(ND,-1.0,v2,1,ab,1);
00037   my_dcopy(ND,v1,1,ac,1);
00038   my_daxpy(ND,-1.0,v3,1,ac,1);
00039 
00040   /* calculate normal vector */
00041   douter(ND,ab,ac,n);
00042 
00043   /* calculate distance */
00044   *d=my_ddot(ND,x,1,n,1)-my_ddot(ND,v1,1,n,1);
00045 
00046   return(0);
00047 }
00048 
00049 int SolidAngle(PetscReal *x, PetscReal *v1, PetscReal *v2, PetscReal *v3, PetscReal *omega)
00050 {
00051   /* http://en.wikipedia.org/wiki/Solid_angle */
00052 
00053   PetscReal d;
00054   PointFromPlane(x,v1,v2,v3,&d);
00055   if (PetscAbsReal(d)<D_EPS) {
00056     *omega=0.0;
00057     return(0);
00058   }
00059 
00060   PetscReal  t_ea[ND],t_eb[ND],t_ec[ND];
00061   PetscReal  t_nab[ND],t_nbc[ND],t_nca[ND];
00062   PetscReal  t_norm;
00063 
00064   /* calculate edge vectors */
00065   my_dcopy(ND,v1,1,t_ea,1);
00066   my_daxpy(ND,-1.0,x,1,t_ea,1);
00067   my_dcopy(ND,v2,1,t_eb,1);
00068   my_daxpy(ND,-1.0,x,1,t_eb,1);
00069   my_dcopy(ND,v3,1,t_ec,1);
00070   my_daxpy(ND,-1.0,x,1,t_ec,1);
00071 
00072   /* calculate normal vectors */
00073   douter(ND,t_ea,t_eb,t_nab);
00074   douter(ND,t_eb,t_ec,t_nbc);
00075   douter(ND,t_ec,t_ea,t_nca);
00076 
00077   /* normalize vectors */
00078 
00079   t_norm=my_dnrm2(ND,t_nab,1);
00080   if (t_norm < D_EPS) {
00081     *omega=0.0;
00082     return(0);
00083   }
00084   my_dscal(ND,1.0/t_norm,t_nab,1);
00085 
00086   t_norm=my_dnrm2(ND,t_nbc,1);
00087   if (t_norm < D_EPS) {
00088     *omega=0.0;
00089     return(0);
00090   }
00091   my_dscal(ND,1.0/t_norm,t_nbc,1);
00092 
00093   t_norm=my_dnrm2(ND,t_nca,1);
00094   if (t_norm < D_EPS) {
00095     *omega=0.0;
00096     return(0);
00097   }
00098   my_dscal(ND,1.0/t_norm,t_nca,1);
00099 
00100   /* calculate dihedral angles between facets */
00101   /* TODO source of this formula ? */
00102 
00103   PetscReal t_a_abbc,t_a_bcca,t_a_caab;
00104   t_a_abbc=t_nab[0]*t_nbc[0]+t_nab[1]*t_nbc[1]+t_nab[2]*t_nbc[2];
00105   t_a_bcca=t_nbc[0]*t_nca[0]+t_nbc[1]*t_nca[1]+t_nbc[2]*t_nca[2];
00106   t_a_caab=t_nca[0]*t_nab[0]+t_nca[1]*t_nab[1]+t_nca[2]*t_nab[2];
00107   if (t_a_abbc>1) t_a_abbc=PETSC_PI; else if (t_a_abbc<-1) t_a_abbc=0; else t_a_abbc=PETSC_PI-acos(t_nab[0]*t_nbc[0]+t_nab[1]*t_nbc[1]+t_nab[2]*t_nbc[2]);
00108   if (t_a_bcca>1) t_a_bcca=PETSC_PI; else if (t_a_bcca<-1) t_a_bcca=0; else t_a_bcca=PETSC_PI-acos(t_nbc[0]*t_nca[0]+t_nbc[1]*t_nca[1]+t_nbc[2]*t_nca[2]);
00109   if (t_a_caab>1) t_a_caab=PETSC_PI; else if (t_a_caab<-1) t_a_caab=0; else t_a_caab=PETSC_PI-acos(t_nca[0]*t_nab[0]+t_nca[1]*t_nab[1]+t_nca[2]*t_nab[2]);
00110 
00111   *omega=t_a_abbc+t_a_bcca+t_a_caab-PETSC_PI;
00112 
00113   return(0);
00114 }

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