Skip to content

Commit cb8988e

Browse files
authored
Merge pull request #13 from simpeg/magnetic_pole
magnetic pole
2 parents 630a9b1 + 6ff55f1 commit cb8988e

File tree

9 files changed

+204
-10
lines changed

9 files changed

+204
-10
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[bumpversion]
2-
current_version = 0.0.4
2+
current_version = 0.0.5
33
files = setup.py geoana/__init__.py docs/conf.py
44

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ install:
3838
- conda info -a
3939
- "conda create -q -n test-environment python=%PYTHON% numpy scipy matplotlib cython jupyter ipython pillow wheel"
4040
- activate test-environment
41-
- pip install -r requirements_dev.txt
4241
- python setup.py install
42+
- pip install -r requirements_dev.txt
4343

4444
test_script:
4545
- nosetests tests -v -s

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@
6464
# built documents.
6565
#
6666
# The short X.Y version.
67-
version = u'0.0.4'
67+
version = u'0.0.5'
6868
# The full version, including alpha/beta/rc tags.
69-
release = u'0.0.4'
69+
release = u'0.0.5'
7070

7171
# The language for content autogenerated by Sphinx. Refer to documentation
7272
# for a list of supported languages.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""
2+
Total magnetic fields: Dipole and Pole sources
3+
==============================================
4+
5+
In this example, we plot anomalous total magnetic field
6+
from a magnetic dipole and pole targets. These targets are
7+
excited by Earth magnetic fields.
8+
We can vary the direction of the Earth magnetic field, and
9+
magnetic moment of the target.
10+
11+
:author: Seogi Kang (`@sgkang <https://github.com/sgkang>`_)
12+
:date: Aug 19, 2018
13+
14+
"""
15+
16+
17+
import numpy as np
18+
import matplotlib.pyplot as plt
19+
from matplotlib.colors import LogNorm
20+
from scipy.constants import mu_0, epsilon_0
21+
22+
from geoana import utils, spatial
23+
from geoana.em import static
24+
25+
###############################################################################
26+
# Setup
27+
# -----
28+
#
29+
# define the location, orientation, and source, physical properties of the
30+
# wholespace and source parameters
31+
32+
mu = mu_0 # permeability of free space (this is the default)
33+
location = np.r_[0., 0., -10.] # location of the dipole or pole
34+
35+
# dipole parameters
36+
moment = 1
37+
# inclination and declination (e.g. Vancouver)
38+
inclination, declination = 67., 0.
39+
40+
41+
###############################################################################
42+
# Magnetostatic Dipole and Loop
43+
# -----------------------------
44+
#
45+
# Here, we build the geoana magnetic dipole and poie in a wholespace
46+
# using the parameters defined above.
47+
48+
def id_to_cartesian(inclination, declination):
49+
ux = np.cos(inclination/180.*np.pi)*np.sin(declination/180.*np.pi)
50+
uy = np.cos(inclination/180.*np.pi)*np.cos(declination/180.*np.pi)
51+
uz = -np.sin(inclination/180.*np.pi)
52+
return np.r_[ux, uy, uz]
53+
54+
orientation = id_to_cartesian(inclination, declination)
55+
56+
dipole = static.MagneticDipoleWholeSpace(
57+
location=location,
58+
orientation=orientation,
59+
moment=moment
60+
)
61+
62+
pole = static.MagneticPoleWholeSpace(
63+
location=location,
64+
orientation=orientation,
65+
moment=moment
66+
)
67+
68+
###############################################################################
69+
# Evaluate magnetic fields
70+
# --------------------------
71+
#
72+
# Next, we construct a grid where we want to plot the magentic fields and
73+
# evaluate
74+
75+
x = np.linspace(-36, 36, 100)
76+
y = np.linspace(-36, 36, 100)
77+
xyz = utils.ndgrid([x, y, np.r_[1.]])
78+
79+
# evaluate the magnetic field
80+
b_vec_dipole = dipole.magnetic_flux_density(xyz)
81+
b_vec_pole = pole.magnetic_flux_density(xyz)
82+
b_total_dipole = dipole.dot_orientation(b_vec_dipole)
83+
b_total_pole = pole.dot_orientation(b_vec_pole)
84+
###############################################################################
85+
#
86+
# and define plotting code to plot an image of the amplitude of the vector
87+
# field / flux as well as the streamlines
88+
89+
90+
def plot_amplitude(ax, v):
91+
plt.colorbar(
92+
ax.pcolormesh(
93+
x, y, v.reshape(len(x), len(y), order='F')
94+
), ax=ax
95+
)
96+
ax.axis('square')
97+
ax.set_xlabel('y (east, m)')
98+
ax.set_ylabel('x (north, m)')
99+
100+
###############################################################################
101+
#
102+
# Create subplots for plotting the results. Loop over frequencies and plot the
103+
# electric and magnetic fields along a slice through the center of the dipole.
104+
105+
fig, ax = plt.subplots(1, 2, figsize=(12, 5))
106+
107+
# plot dipole vector potential
108+
plot_amplitude(ax[0], b_total_dipole)
109+
110+
# plot loop vector potential
111+
plot_amplitude(ax[1], b_total_pole)
112+
113+
114+
# set the titles
115+
ax[0].set_title("Total field: dipole")
116+
ax[1].set_title("Total field: pole")
117+
118+
# format so text doesn't overlap
119+
plt.tight_layout()
120+
plt.show()

geoana/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from . import em
33
from . import utils
44

5-
__version__ = '0.0.4'
5+
__version__ = '0.0.5'
66
__author__ = 'SimPEG developers'
77
__license__ = 'MIT'
88
__copyright__ = 'Copyright 2017-2018 SimPEG developers'

geoana/em/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ def cross_orientation(self, xyz):
8383
"""
8484
orientation = np.kron(
8585
np.atleast_2d(
86-
np.array(self.orientation)), np.ones((xyz.shape[0], 1)
87-
)
86+
np.array(self.orientation)
87+
), np.ones((xyz.shape[0], 1))
8888
)
8989
return np.cross(xyz, orientation)
9090

geoana/em/static.py

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
from .base import BaseEM, BaseDipole, BaseMagneticDipole, BaseElectricDipole
1313
from .. import spatial
1414

15-
__all__ = ["MagneticDipoleWholeSpace", "CircularLoopWholeSpace"]
15+
__all__ = [
16+
"MagneticDipoleWholeSpace", "CircularLoopWholeSpace",
17+
"MagneticPoleWholeSpace"
18+
]
1619

1720

1821
class MagneticDipoleWholeSpace(BaseMagneticDipole, BaseEM):
@@ -73,7 +76,6 @@ def vector_potential(self, xyz, coordinates="cartesian"):
7376

7477
return a
7578

76-
7779
def magnetic_flux_density(self, xyz, coordinates="cartesian"):
7880
"""Magnetic flux (:math:`\\vec{b}`) of a static magnetic dipole
7981
@@ -152,6 +154,77 @@ def magnetic_field(self, xyz, coordinates="cartesian"):
152154
return self.magnetic_flux(xyz, coordinates=coordinates) / self.mu
153155

154156

157+
class MagneticPoleWholeSpace(BaseMagneticDipole, BaseEM):
158+
"""
159+
Static magnetic pole in a wholespace.
160+
"""
161+
162+
def magnetic_flux_density(self, xyz, coordinates="cartesian"):
163+
"""Magnetic flux (:math:`\\vec{b}`) of a static magnetic dipole
164+
165+
**Required**
166+
167+
:param numpy.ndarray xyz: Location of the receivers(s)
168+
169+
**Optional**
170+
171+
:param str coordinates: coordinate system that the xyz is provided
172+
in and that the solution will be returned
173+
in (cartesian or cylindrical).
174+
Default: `"cartesian"`
175+
176+
**Returns**
177+
178+
:rtype: numpy.ndarray
179+
:return: The magnetic flux at each observation location
180+
"""
181+
182+
supported_coordinates = ["cartesian", "cylindrical"]
183+
assert coordinates.lower() in supported_coordinates, (
184+
"coordinates must be in {}, the coordinate system "
185+
"you provided, {}, is not yet supported".format(
186+
supported_coordinates, coordinates
187+
)
188+
)
189+
190+
n_obs = xyz.shape[0]
191+
192+
if coordinates.lower() == "cylindrical":
193+
xyz = spatial.cylindrical_2_cartesian(xyz)
194+
195+
r = self.vector_distance(xyz)
196+
dxyz = spatial.repeat_scalar(self.distance(xyz))
197+
198+
b = self.moment * self.mu / (4 * np.pi * (dxyz ** 3)) * r
199+
200+
if coordinates.lower() == "cylindrical":
201+
b = spatial.cartesian_2_cylindrical(xyz, b)
202+
203+
return b
204+
205+
def magnetic_field(self, xyz, coordinates="cartesian"):
206+
"""Magnetic field (:math:`\\vec{h}`) of a static magnetic dipole
207+
208+
**Required**
209+
210+
:param numpy.ndarray xyz: Location of the receivers(s)
211+
212+
**Optional**
213+
214+
:param str coordinates: coordinate system that the xyz is provided
215+
in and that the solution will be returned
216+
in (cartesian or cylindrical).
217+
Default: `"cartesian"`
218+
219+
**Returns**
220+
221+
:rtype: numpy.ndarray
222+
:return: The magnetic field at each observation location
223+
224+
"""
225+
return self.magnetic_flux(xyz, coordinates=coordinates) / self.mu
226+
227+
155228
class CircularLoopWholeSpace(BaseDipole, BaseEM):
156229

157230
"""

geoana/spatial.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def cylindrical_2_cartesian(grid, vec=None):
5252

5353
return np.vstack(newvec).T
5454

55+
5556
def cartesian_2_cylindrical(grid, vec=None):
5657
"""
5758
Takes a grid or vector (if provided)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
setup(
3333
name = 'geoana',
34-
version = '0.0.4',
34+
version = '0.0.5',
3535
packages = find_packages(),
3636
install_requires = [
3737
'future',

0 commit comments

Comments
 (0)