Skip to content

Resistance functions

Those functions are used to compute the resistance of a given system. They are all defined in the resistance module for version upside of 1.2.0.

GMR_expr()

Get the symbolic expression for the GMR.

Returns:

Type Description

GMR function

Source code in cmtj/utils/resistance.py
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
def GMR_expr():
    """Get the symbolic expression for the GMR.
    :returns: GMR function
    """
    GMR_s = sym.Symbol(r"\mathrm{GMR}")
    theta1 = sym.Symbol(r"\theta_1")
    phi1 = sym.Symbol(r"\phi_1")
    m1 = sym.Matrix(
        [
            sym.sin(theta1) * sym.cos(phi1),
            sym.sin(theta1) * sym.sin(phi1),
            sym.cos(theta1),
        ]
    )
    theta2 = sym.Symbol(r"\theta_2")
    phi2 = sym.Symbol(r"\phi_2")
    m2 = sym.Matrix(
        [
            sym.sin(theta2) * sym.cos(phi2),
            sym.sin(theta2) * sym.sin(phi2),
            sym.cos(theta2),
        ]
    )
    Rf = GMR_s * (1 - m1.dot(m2)) / 2
    dRdt1 = sym.diff(Rf, theta1)
    dRdp1 = sym.diff(Rf, phi1)
    dRdt2 = sym.diff(Rf, theta2)
    dRdp2 = sym.diff(Rf, phi2)
    linearised_terms = sym.symbols(
        r"\partial\theta_1, \partial\phi_1, \partial\theta_2, \partial\phi_2"
    )
    dRf = (
        dRdt1 * linearised_terms[0]
        + dRdp1 * linearised_terms[1]
        + dRdt2 * linearised_terms[2]
        + dRdp2 * linearised_terms[3]
    )

    Rf_func = sym.lambdify([GMR_s, [theta1, phi1, theta2, phi2]], Rf)
    dRf_func = sym.lambdify(
        [GMR_s, [theta1, phi1, theta2, phi2], linearised_terms], dRf
    )
    return Rf_func, dRf_func

Rxx_parallel_bilayer_expr()

Get the symbolic expressions for the parallel and linearised resistance of a bilayer system.

Returns:

Type Description

linearised and parallel resistance functions Signals: - GMR: GMR - AMR1: AMR of layer 1 - SMR1: SMR of layer 1 - AMR2: AMR of layer 2 - SMR2: SMR of layer 2 - stationary angles: [t1, p1, t2, p2] - linearised angles: [dt1, dp1, dt2, dp2] Function signatures - Rlin_func: linearised resistance function f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2], [dt1, dp1, dt2, dp2]) - R_func: series resistance function f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2])

Source code in cmtj/utils/resistance.py
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def Rxx_parallel_bilayer_expr():
    """Get the symbolic expressions for the parallel and linearised resistance of a bilayer system.
    :returns: linearised and parallel resistance functions
    Signals:
    - GMR: GMR
    - AMR1: AMR of layer 1
    - SMR1: SMR of layer 1
    - AMR2: AMR of layer 2
    - SMR2: SMR of layer 2
    - stationary angles: [t1, p1, t2, p2]
    - linearised angles: [dt1, dp1, dt2, dp2]

    Function signatures
    - Rlin_func: linearised resistance function
        f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2], [dt1, dp1, dt2, dp2])
    - R_func: series resistance function
        f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2])
    """
    AMR_1 = sym.Symbol(r"\mathrm{AMR}_1")
    SMR_1 = sym.Symbol(r"\mathrm{SMR}_1")
    AMR_2 = sym.Symbol(r"\mathrm{AMR}_2")
    SMR_2 = sym.Symbol(r"\mathrm{SMR}_2")
    GMR_s = sym.Symbol(r"\mathrm{GMR}")
    R_1, t1, p1, m1 = Rxx_symbolic(1, AMR_1, SMR_1)
    R_2, t2, p2, m2 = Rxx_symbolic(2, AMR_2, SMR_2)
    gmr_term = GMR_s * (1 - m1.dot(m2)) / 2

    Rparallel = gmr_term + (R_1 * R_2) / (R_1 + R_2 + EPS)
    linearised_terms = sym.symbols(
        r"\partial\theta_1, \partial\phi_1, \partial\theta_2, \partial\phi_2"
    )
    dRdtheta1 = sym.diff(Rparallel, t1) * linearised_terms[0]
    dRdphi1 = sym.diff(Rparallel, p1) * linearised_terms[1]
    dRdtheta2 = sym.diff(Rparallel, t2) * linearised_terms[2]
    dRdphi2 = sym.diff(Rparallel, p2) * linearised_terms[3]

    linearised_R = dRdtheta1 + dRdtheta2 + dRdphi1 + dRdphi2

    Rlin_func = sym.lambdify(
        [GMR_s, AMR_1, SMR_1, AMR_2, SMR_2, [t1, p1, t2, p2], linearised_terms],
        linearised_R,
    )
    R_func = sym.lambdify(
        [GMR_s, AMR_1, SMR_1, AMR_2, SMR_2, [t1, p1, t2, p2]], Rparallel
    )

    return Rlin_func, R_func

Rxx_series_bilayer_expr()

Get the symbolic expressions for the series and linearised resistance of a bilayer system.

Returns:

Type Description

linearised and series resistance functions Signals: - GMR: GMR - AMR1: AMR of layer 1 - SMR1: SMR of layer 1 - AMR2: AMR of layer 2 - SMR2: SMR of layer 2 - stationary angles: [t1, p1, t2, p2] - linearised angles: [dt1, dp1, dt2, dp2] Function signatures - Rlin_func: linearised resistance function f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2], [dt1, dp1, dt2, dp2]) - R_func: series resistance function f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2])

Source code in cmtj/utils/resistance.py
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
def Rxx_series_bilayer_expr():
    """Get the symbolic expressions for the series and linearised resistance of a bilayer system.

    :returns: linearised and series resistance functions
    Signals:
    - GMR: GMR
    - AMR1: AMR of layer 1
    - SMR1: SMR of layer 1
    - AMR2: AMR of layer 2
    - SMR2: SMR of layer 2
    - stationary angles: [t1, p1, t2, p2]
    - linearised angles: [dt1, dp1, dt2, dp2]

    Function signatures
    - Rlin_func: linearised resistance function
        f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2], [dt1, dp1, dt2, dp2])
    - R_func: series resistance function
        f(GMR, AMR1, SMR1, AMR2, SMR2, [t1, p1, t2, p2])
    """
    AMR_1 = sym.Symbol(r"\mathrm{AMR}_1")
    SMR_1 = sym.Symbol(r"\mathrm{SMR}_1")
    AMR_2 = sym.Symbol(r"\mathrm{AMR}_2")
    SMR_2 = sym.Symbol(r"\mathrm{SMR}_2")
    GMR_s = sym.Symbol(r"\mathrm{GMR}")
    R_1, t1, p1, m1 = Rxx_symbolic(1, AMR_1, SMR_1)
    R_2, t2, p2, m2 = Rxx_symbolic(2, AMR_2, SMR_2)
    gmr_term = GMR_s * (1 - m1.dot(m2)) / 2

    Rseries = gmr_term + R_1 + R_2
    linearised_terms = sym.symbols(
        r"\partial\theta_1, \partial\phi_1, \partial\theta_2, \partial\phi_2"
    )
    dRdtheta1 = sym.diff(Rseries, t1) * linearised_terms[0]
    dRdphi1 = sym.diff(Rseries, p1) * linearised_terms[1]
    dRdtheta2 = sym.diff(Rseries, t2) * linearised_terms[2]
    dRdphi2 = sym.diff(Rseries, p2) * linearised_terms[3]

    linearised_R = dRdtheta1 + dRdtheta2 + dRdphi1 + dRdphi2

    Rlin_func = sym.lambdify(
        [GMR_s, AMR_1, SMR_1, AMR_2, SMR_2, [t1, p1, t2, p2], linearised_terms],
        linearised_R,
    )
    R_func = sym.lambdify(
        [GMR_s, AMR_1, SMR_1, AMR_2, SMR_2, [t1, p1, t2, p2]], Rseries
    )

    return Rlin_func, R_func

Rxx_symbolic(id, AMR, SMR) cached

Compute the Rxx resistance for a given layer.

Parameters:

Name Type Description Default
id int

layer id

required
AMR float

anisotropic magnetoresistance

required
SMR float

spin Hall magnetoresistance

required
Source code in cmtj/utils/resistance.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
@lru_cache(maxsize=5)
def Rxx_symbolic(id: int, AMR: float, SMR: float):
    """Compute the Rxx resistance for a given layer.
    :param id: layer id
    :param AMR: anisotropic magnetoresistance
    :param SMR: spin Hall magnetoresistance
    """
    theta1 = sym.Symbol(r"\theta_" + str(id))
    phi1 = sym.Symbol(r"\phi_" + str(id))
    m = sym.Matrix(
        [
            sym.sin(theta1) * sym.cos(phi1),
            sym.sin(theta1) * sym.sin(phi1),
            sym.cos(theta1),
        ]
    )
    return AMR * m[0] ** 2 + SMR * m[1] ** 2, theta1, phi1, m

Rxy_symbolic(id, AMR, SMR, AHE, w_l) cached

Compute the Rxy resistance for a given layer.

Parameters:

Name Type Description Default
id int

layer id

required
AMR float

anisotropic magnetoresistance

required
SMR float

spin Hall magnetoresistance

required
AHE float

anomalous Hall effect

required
w_l float

width to length ratio

required
Source code in cmtj/utils/resistance.py
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
@lru_cache(maxsize=5)
def Rxy_symbolic(id: int, AMR: float, SMR: float, AHE: float, w_l: float):
    """Compute the Rxy resistance for a given layer.
    :param id: layer id
    :param AMR: anisotropic magnetoresistance
    :param SMR: spin Hall magnetoresistance
    :param AHE: anomalous Hall effect
    :param w_l: width to length ratio
    """
    theta1 = sym.Symbol(r"\theta_" + str(id))
    phi1 = sym.Symbol(r"\phi_" + str(id))
    m = sym.Matrix(
        [
            sym.sin(theta1) * sym.cos(phi1),
            sym.sin(theta1) * sym.sin(phi1),
            sym.cos(theta1),
        ]
    )
    return (0.5 * AHE * m[-1]) + w_l * (SMR - AMR) * m[0] * m[1], theta1, phi1, m

angular_calculate_resistance_gmr(Rp, Rap, theta_1, phi_1, theta_2, phi_2)

Computes the GMR using parallel and antiparallel resistance.

Parameters:

Name Type Description Default
Rp float

parallel resistance

required
Rap float

antiparallel resistance

required
theta_1 np.ndarray

angle of layer 1

required
phi_1 np.ndarray

angle of layer 1

required
theta_2 np.ndarray

angle of layer 2

required
phi_2 np.ndarray

angle of layer 2

required
Source code in cmtj/utils/resistance.py
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
def angular_calculate_resistance_gmr(
    Rp: float,
    Rap: float,
    theta_1: np.ndarray,
    phi_1: np.ndarray,
    theta_2: np.ndarray,
    phi_2: np.ndarray,
):
    """Computes the GMR using parallel and antiparallel resistance.
    :param Rp: parallel resistance
    :param Rap: antiparallel resistance
    :param theta_1: angle of layer 1
    :param phi_1: angle of layer 1
    :param theta_2: angle of layer 2
    :param phi_2: angle of layer 2
    """
    m1 = np.array(
        [
            np.cos(theta_1) * np.cos(phi_1),
            np.cos(theta_1) * np.sin(phi_1),
            np.sin(theta_1),
        ]
    )
    m2 = np.array(
        [
            np.cos(theta_2) * np.cos(phi_2),
            np.cos(theta_2) * np.sin(phi_2),
            np.sin(theta_2),
        ]
    )
    return compute_gmr(Rp, Rap, m1, m2)

calculate_linearised_resistance(GMR, AMR, SMR)

Compute the resistance of the two FM bilayer system from the linearised angles.

Parameters:

Name Type Description Default
GMR float

GMR

required
AMR list[float]

AMR

required
SMR list[float]

SMR

required
Source code in cmtj/utils/resistance.py
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
def calculate_linearised_resistance(
    GMR: float,
    AMR: list[float],
    SMR: list[float],
):
    """
    Compute the resistance of the two FM bilayer system from the linearised angles.
    :param GMR: GMR
    :param AMR: AMR
    :param SMR: SMR
    """

    Rxx1, theta1, phi1, m1 = Rxx_symbolic(1, AMR[0], SMR[0])
    Rxx2, theta2, phi2, m2 = Rxx_symbolic(2, AMR[1], SMR[1])
    GMR_resistance = GMR * (1 - (m1.dot(m2))) / 2.0
    return Rxx1, Rxx2, GMR_resistance, theta1, phi1, theta2, phi2

calculate_linearised_resistance_parallel(GMR, AMR, SMR, stationary_angles, linearised_angles)

Compute the parallel resistance of the two FM bilayer system from the linearised angles.

Parameters:

Name Type Description Default
GMR float

GMR

required
AMR list[float]

AMR

required
SMR list[float]

SMR

required
stationary_angles list[float]

stationary angles [t1, p1, t2, p2]

required
linearised_angles list[float]

linearised angles [dt1, dp1, dt2, dp2]

required
Source code in cmtj/utils/resistance.py
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
def calculate_linearised_resistance_parallel(
    GMR: float,
    AMR: list[float],
    SMR: list[float],
    stationary_angles: list[float],
    linearised_angles: list[float],
):
    """
    Compute the parallel resistance of the two FM bilayer system from the linearised angles.
    :param GMR: GMR
    :param AMR: AMR
    :param SMR: SMR
    :param stationary_angles: stationary angles [t1, p1, t2, p2]
    :param linearised_angles: linearised angles [dt1, dp1, dt2, dp2]
    """
    t01, p01 = stationary_angles[:2]
    t02, p02 = stationary_angles[2:]
    dt1, dp1 = linearised_angles[:2]
    dt2, dp2 = linearised_angles[2:]
    Rxx1, Rxx2, GMR_resistance, theta1, phi1, theta2, phi2 = (
        calculate_linearised_resistance(GMR, AMR, SMR)
    )
    Rparallel = GMR_resistance
    if any(AMR) or any(SMR):
        Rparallel += (Rxx1 * Rxx2) / (Rxx1 + Rxx2 + EPS)
    elif GMR == 0:
        return 0, 0
    dRparallel = (
        sym.diff(Rparallel, theta1) * dt1
        + sym.diff(Rparallel, phi1) * dp1
        + sym.diff(Rparallel, theta2) * dt2
        + sym.diff(Rparallel, phi2) * dp2
    )
    if isinstance(dRparallel, (list, np.ndarray)):
        dRparallel = dRparallel[0]
    dRparallel = dRparallel.subs(
        {
            theta1: t01,
            phi1: p01,
            theta2: t02,
            phi2: p02,
        }
    ).evalf()
    Rparallel = Rparallel.subs(
        {
            theta1: t01,
            phi1: p01,
            theta2: t02,
            phi2: p02,
        }
    ).evalf()
    return dRparallel, Rparallel

calculate_linearised_resistance_series(GMR, AMR, SMR, stationary_angles, linearised_angles)

Compute the resistance of the two FM bilayer system from the linearised angles.

Parameters:

Name Type Description Default
GMR float

GMR

required
AMR list[float]

AMR

required
SMR list[float]

SMR

required
stationary_angles list[float]

stationary angles [t1, p1, t2, p2]

required
linearised_angles list[float]

linearised angles [dt1, dp1, dt2, dp2]

required
Source code in cmtj/utils/resistance.py
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
def calculate_linearised_resistance_series(
    GMR: float,
    AMR: list[float],
    SMR: list[float],
    stationary_angles: list[float],
    linearised_angles: list[float],
):
    """
    Compute the resistance of the two FM bilayer system from the linearised angles.
    :param GMR: GMR
    :param AMR: AMR
    :param SMR: SMR
    :param stationary_angles: stationary angles [t1, p1, t2, p2]
    :param linearised_angles: linearised angles [dt1, dp1, dt2, dp2]
    """
    t01, p01 = stationary_angles[:2]
    t02, p02 = stationary_angles[2:]
    dt1, dp1 = linearised_angles[:2]
    dt2, dp2 = linearised_angles[2:]
    Rxx1, Rxx2, GMR_resistance, theta1, phi1, theta2, phi2 = (
        calculate_linearised_resistance(GMR, AMR, SMR)
    )
    Rseries = GMR_resistance + Rxx1 + Rxx2
    dRseries = (
        sym.diff(Rseries, theta1) * dt1
        + sym.diff(Rseries, phi1) * dp1
        + sym.diff(Rseries, theta2) * dt2
        + sym.diff(Rseries, phi2) * dp2
    )

    dRseries = dRseries.subs(
        {
            theta1: t01,
            phi1: p01,
            theta2: t02,
            phi2: p02,
        }
    ).evalf()
    Rseries = Rseries.subs(
        {
            theta1: t01,
            phi1: p01,
            theta2: t02,
            phi2: p02,
        }
    ).evalf()
    return dRseries, Rseries

calculate_magnetoresistance(Rp, Rap, m)

Computes the magnetoresistance using parallel and antiparallel resistance.

Parameters:

Name Type Description Default
Rp float

parallel resistance

required
Rap float

antiparallel resistance

required
m np.ndarray

magnetisation, 2 layers of shape [2, 3, T] where T is the time component

required
Source code in cmtj/utils/resistance.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def calculate_magnetoresistance(Rp: float, Rap: float, m: np.ndarray):
    """Computes the magnetoresistance using parallel and antiparallel resistance.
    :param Rp: parallel resistance
    :param Rap: antiparallel resistance
    :param m: magnetisation, 2 layers of shape [2, 3, T] where T is the time component
    """
    if not isinstance(m, np.ndarray):
        m = np.asarray(m)
    if m.shape[0] != 2:
        raise ValueError(
            "The magnetoresistance can only be computed for 2 layers"
            f". Current shape {m.shape}"
        )
    return Rp + 0.5 * (Rap - Rp) * np.sum(m[0] * m[1], axis=0)

calculate_resistance_parallel(Rx0, Ry0, AMR, AHE, SMR, m, l, w)

Calculates the resistance of the system in parallel. If you want to compute the resistance for an entire time series, pass m as a 3D array. [number_of_layers, 3, T] where T is the time component. Uses Kim's formula from the paper: https://link.aps.org/doi/10.1103/PhysRevLett.116.097201

Parameters:

Name Type Description Default
Rx0 list[float]

resistance offset in longitudinal direction

required
Ry0 list[float]

resistance offset in transverse direction

required
AMR list[float]

anisotropic magnetoresistance

required
AHE list[float]

anomalous Hall effect

required
SMR list[float]

spin Hall magnetoresistance

required
m list[float]

magnetisation of the layers. Shape [number_of_layers, 3, T]

required
l list[float]

length of the layers

required
w list[float]

width of the layers

required
Source code in cmtj/utils/resistance.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def calculate_resistance_parallel(
    Rx0: list[float],
    Ry0: list[float],
    AMR: list[float],
    AHE: list[float],
    SMR: list[float],
    m: list[float],
    l: list[float],
    w: list[float],
):
    """Calculates the resistance of the system in parallel.
    If you want to compute the resistance for an entire time series, pass m as a 3D array.
    [number_of_layers, 3, T] where T is the time component.
    Uses Kim's formula from the paper:
    https://link.aps.org/doi/10.1103/PhysRevLett.116.097201

    :param Rx0: resistance offset in longitudinal direction
    :param Ry0: resistance offset in transverse direction
    :param AMR: anisotropic magnetoresistance
    :param AHE: anomalous Hall effect
    :param SMR: spin Hall magnetoresistance
    :param m: magnetisation of the layers. Shape [number_of_layers, 3, T]
    :param l: length of the layers
    :param w: width of the layers
    """
    SxAll, SyAll = compute_resistance(Rx0, Ry0, AMR, AHE, SMR, m, l, w)
    Rx = 1.0 / np.sum(1.0 / SxAll, axis=0)
    Ry = 1.0 / np.sum(1.0 / SyAll, axis=0)
    return Rx, Ry

calculate_resistance_series(Rx0, Ry0, AMR, AHE, SMR, m, l, w)

Calculates the resistance of the system in series. If you want to compute the resistance for an entire time series, pass m as a 3D array. [number_of_layers, 3, T] where T is the time component. Uses Kim's formula from the paper: https://link.aps.org/doi/10.1103/PhysRevLett.116.097201

Parameters:

Name Type Description Default
Rx0 list[float]

resistance offset in longitudinal direction

required
Ry0 list[float]

resistance offset in transverse direction

required
AMR list[float]

anisotropic magnetoresistance

required
AHE list[float]

anomalous Hall effect

required
SMR list[float]

spin Hall magnetoresistance

required
m list[float]

magnetisation of the layers. Shape [number_of_layers, 3, T]

required
l list[float]

length of the layers

required
w list[float]

width of the layers

required
Source code in cmtj/utils/resistance.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def calculate_resistance_series(
    Rx0: list[float],
    Ry0: list[float],
    AMR: list[float],
    AHE: list[float],
    SMR: list[float],
    m: list[float],
    l: list[float],
    w: list[float],
):
    """Calculates the resistance of the system in series.
    If you want to compute the resistance for an entire time series, pass m as a 3D array.
    [number_of_layers, 3, T] where T is the time component.
    Uses Kim's formula from the paper:
    https://link.aps.org/doi/10.1103/PhysRevLett.116.097201

    :param Rx0: resistance offset in longitudinal direction
    :param Ry0: resistance offset in transverse direction
    :param AMR: anisotropic magnetoresistance
    :param AHE: anomalous Hall effect
    :param SMR: spin Hall magnetoresistance
    :param m: magnetisation of the layers. Shape [number_of_layers, 3, T]
    :param l: length of the layers
    :param w: width of the layers
    """
    SxAll, SyAll = compute_resistance(Rx0, Ry0, AMR, AHE, SMR, m, l, w)
    Rx = np.sum(SxAll, axis=0)
    Ry = np.sum(SyAll, axis=0)
    return Rx, Ry

compute_gmr(Rp, Rap, m1, m2)

Computes the GMR using parallel and antiparallel resistance.

Parameters:

Name Type Description Default
Rp float

parallel resistance

required
Rap float

antiparallel resistance

required
m1 np.ndarray

magnetisation of layer 1

required
m2 np.ndarray

magnetisation of layer 2

required
Source code in cmtj/utils/resistance.py
63
64
65
66
67
68
69
def compute_gmr(Rp: float, Rap: float, m1: np.ndarray, m2: np.ndarray):
    """Computes the GMR using parallel and antiparallel resistance.
    :param Rp: parallel resistance
    :param Rap: antiparallel resistance
    :param m1: magnetisation of layer 1
    :param m2: magnetisation of layer 2"""
    return Rp + 0.5 * (Rap - Rp) * (1 - np.sum(m1 * m2, axis=0))

compute_resistance(Rx0, Ry0, AMR, AHE, SMR, m, l, w)

Computes the resistance of the system. If you want to compute the resistance for an entire time series, pass m as a 3D array with shape [number_of_layers, 3, T], where T is the time component. [number_of_layers, 3, T] where T is the time component.

Source code in cmtj/utils/resistance.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def compute_resistance(
    Rx0: list[float],
    Ry0: list[float],
    AMR: list[float],
    AHE: list[float],
    SMR: list[float],
    m: Union[list[float], np.ndarray],
    l: list[float],
    w: list[float],
):
    """Computes the resistance of the system.
    If you want to compute the resistance for an entire time series, pass m as a 3D array
    with shape [number_of_layers, 3, T], where T is the time component.
    [number_of_layers, 3, T] where T is the time component.
    """
    number_of_layers = len(Rx0)
    if not isinstance(m, np.ndarray):
        m = np.asarray(m)
    if m.ndim == 2:
        SxAll = np.zeros((number_of_layers,))
        SyAll = np.zeros((number_of_layers,))

    elif m.ndim == 3:
        SxAll = np.zeros((number_of_layers, m.shape[2]))
        SyAll = np.zeros((number_of_layers, m.shape[2]))

    for i in range(number_of_layers):
        w_l = w[i] / l[i]
        SxAll[i] = Rx0[i] + (AMR[i] * m[i, 0] ** 2 + SMR[i] * m[i, 1] ** 2)
        SyAll[i] = (
            Ry0[i]
            + 0.5 * AHE[i] * m[i, 2]
            + (w_l) * (SMR[i] - AMR[i]) * m[i, 0] * m[i, 1]
        )
    return SxAll, SyAll

compute_sd(dynamic_r, dynamic_i, integration_step)

Computes the SD voltage.

Parameters:

Name Type Description Default
dynamic_r np.ndarray

magnetoresistance from log

required
dynamic_i np.ndarray

excitation current

required
integration_step float

integration paramemter from run_simulation

required
Source code in cmtj/utils/resistance.py
12
13
14
15
16
17
18
19
20
21
22
23
def compute_sd(
    dynamic_r: np.ndarray, dynamic_i: np.ndarray, integration_step: float
) -> np.ndarray:
    """Computes the SD voltage.
    :param dynamic_r: magnetoresistance from log
    :param dynamic_i: excitation current
    :param integration_step: integration paramemter from run_simulation
    """
    SD = -dynamic_i * dynamic_r
    fs = 1.0 / integration_step
    SD_dc = Filters.butter_lowpass_filter(SD, cutoff=10e6, fs=fs, order=3)
    return np.mean(SD_dc)