Skip to content

Commit fa53fec

Browse files
Fixed bug in exchange class; problem was in the argument order in the test
1 parent d4132dc commit fa53fec

File tree

4 files changed

+85
-46
lines changed

4 files changed

+85
-46
lines changed

fidimag/common/c_clib.pyx

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def init_vector_func_fast(m0, mesh, double[:] field, norm=False, *args):
238238
#
239239
# - Methods that are redefined in inherited classes are only specified in the
240240
# base class
241-
# - These can be declared in a .pxd file:
241+
# - These can be declared in a .pxd file:
242242

243243
cdef extern from "c_energy.h":
244244

@@ -250,27 +250,29 @@ cdef extern from "c_energy.h":
250250
void compute_field(double t)
251251
double compute_energy()
252252
void setup(int nx, int ny, int nz, double dx, double dy, double dz,
253-
double unit_length, double *spin,
254-
double *Ms, double *Ms_inv)
255-
256-
bool set_up
257-
int nx, ny, nz, n
258-
double dx, dy, dz
259-
double unit_length
260-
double *spin
261-
double *Ms
262-
double *Ms_inv
263-
double *field
264-
double *energy
265-
double *coordinates
266-
int *ngbs
253+
double unit_length, double *spin, double *Ms, double *Ms_inv,
254+
double *coordinates, int *ngbs,
255+
double *energy, double *field
256+
)
257+
258+
# bool set_up
259+
# int nx, ny, nz, n
260+
# double dx, dy, dz
261+
# double unit_length
262+
# double *spin
263+
# double *Ms
264+
# double *Ms_inv
265+
# double *field
266+
# double *energy
267+
# double *coordinates
268+
# int *ngbs
267269

268270
cdef cppclass ExchangeEnergy(Energy):
269271
ExchangeEnergy() except +
270272

271273
void init(double *A)
272274

273-
double *A
275+
# double *A
274276

275277
# cdef extern from "c_energy.cpp":
276278
# pass
@@ -285,17 +287,17 @@ cdef extern from "c_energy.h":
285287
# __cinit__ and __dealloc__ methods which are guaranteed to be called exactly
286288
# once upon creation and deletion of the Python instance.
287289

288-
cdef class PyEnergy:
289-
cdef Energy *thisptr
290-
# Try cinit:
291-
def __cinit__(self):
292-
# Should we allocate?
293-
# self.thisptr = new ExchangeEnergy()
294-
print("In Python A")
295-
296-
# We need to inherit from a cdef-ined base class to make the inheritance to
297-
# work. This way the constructors are called properly
298-
cdef class PyExchangeEnergy(PyEnergy):
290+
#cdef class PyEnergy:
291+
# cdef Energy *thisptr
292+
# # Try cinit:
293+
# def __cinit__(self):
294+
# # Should we allocate?
295+
# # self.thisptr = new Energy()
296+
# print("In Python A")
297+
298+
# No need to replicate C++ class structure; we make the ExchangeEnergy a
299+
# base class in Python (which we know inherits from Energy in C++)
300+
cdef class PyExchangeEnergy(object):
299301
cdef ExchangeEnergy *derivedptr
300302
# Try cinit:
301303
def __cinit__(self, double [:] A):
@@ -304,9 +306,8 @@ cdef class PyExchangeEnergy(PyEnergy):
304306
self.derivedptr = new ExchangeEnergy()
305307
self.derivedptr.init(&A[0])
306308

307-
if self.thisptr:
308-
print("in B: deallocating old A")
309-
del self.thisptr
309+
def __dealloc__(self):
310+
del self.derivedptr
310311

311312
# DEBUG: check contents of the A array
312313
# def printA(self):
@@ -315,21 +316,20 @@ cdef class PyExchangeEnergy(PyEnergy):
315316
# lst.append(self.derivedptr.A[i])
316317
# print(lst)
317318

318-
# We could use another constructor if we use this method:
319-
# def __cinit__(self):
320-
# if type(self) is PyExchangeEnergy:
321-
# self.thisptr = new ExchangeEnergy()
322-
# def __dealloc__(self):
323-
# if type(self) is PyExchangeEnergy:
324-
# del self.thisptr
325-
326319
# Necessary?:
327320
def compute_field(self, t):
328321
self.derivedptr.compute_field(t)
322+
329323
def compute_energy(self, time):
330324
return self.derivedptr.compute_energy()
325+
331326
def setup(self, nx, ny, nz, dx, dy, dz, unit_length,
332-
double [:] spin, double [:] Ms, double [:] Ms_inv):
333-
return self.derivedptr.setup(nx, ny, nz, dx, dy, dz, unit_length,
334-
&spin[0], &Ms[0], &Ms_inv[0])
327+
double [:] spin, double [:] Ms, double [:] Ms_inv,
328+
double [:, :] coordinates, int [:, :] neighbours,
329+
double [:] energy, double [:] field):
335330

331+
return self.derivedptr.setup(nx, ny, nz, dx, dy, dz, unit_length,
332+
&spin[0], &Ms[0], &Ms_inv[0],
333+
&coordinates[0, 0], &neighbours[0, 0],
334+
&energy[0], &field[0]
335+
)

native/include/c_energy.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class Energy {
55
public:
66
Energy() {std::cout << "In A; at " << this << "\n";};
7-
~Energy() {std::cout << "Killing A\n";};
7+
virtual ~Energy() {std::cout << "Killing A\n";};
88
bool set_up;
99
int nx, ny, nz, n;
1010
double dx, dy, dz;
@@ -19,7 +19,7 @@ class Energy {
1919
double compute_energy();
2020
void setup(int nx, int ny, int nz, double dx, double dy, double dz,
2121
double unit_length, double *spin, double *Ms, double *Ms_inv,
22-
double *coordinates, double *ngbs,
22+
double *coordinates, int *ngbs,
2323
double *energy, double *field
2424
);
2525
virtual void compute_field(double t) {};
@@ -28,6 +28,7 @@ class Energy {
2828
class ExchangeEnergy : public Energy {
2929
public:
3030
ExchangeEnergy() {std::cout << "In B; at " << this << "\n";};
31+
~ExchangeEnergy() {std::cout << "Killing B\n";};
3132
void init(double *A) {
3233
this->set_up = false;
3334
this->A = A;

native/src/c_energy.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ double Energy::compute_energy() {
1212

1313
void Energy::setup(int nx, int ny, int nz, double dx, double dy, double dz,
1414
double unit_length, double *spin, double *Ms, double *Ms_inv,
15-
double *coordinates, double *ngbs,
15+
double *coordinates, int *ngbs,
1616
double *energy, double *field
17-
); {
17+
) {
18+
1819
this->nx = nx;
1920
this->ny = ny;
2021
this->nz = nz;
22+
this->n = nx * ny * nz;
2123
this->dx = dx;
2224
this->dy = dy;
2325
this->dz = dz;
@@ -29,7 +31,7 @@ void Energy::setup(int nx, int ny, int nz, double dx, double dy, double dz,
2931
this->Ms_inv = Ms_inv;
3032
this->coordinates = coordinates;
3133
this->ngbs = ngbs;
32-
this ->energy->energy;
34+
this->energy = energy;
3335
this->field = field;
3436

3537
set_up = true;
@@ -190,5 +192,6 @@ void ExchangeEnergy::compute_field(double t) {
190192
field[3 * i] = fx * Ms_inv[i] * MU_0_INV;
191193
field[3 * i + 1] = fy * Ms_inv[i] * MU_0_INV;
192194
field[3 * i + 2] = fz * Ms_inv[i] * MU_0_INV;
195+
193196
}
194197
}

tests/test_C_classes.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,41 @@
11
from fidimag.extensions.c_clib import PyExchangeEnergy
2+
from fidimag.common import CuboidMesh
3+
4+
import time
25
import numpy as np
36

47
A = np.ones(9, dtype=np.double)
58
print(A)
69
Exch = PyExchangeEnergy(A)
10+
# A[2] = 4
11+
# Exch.printA()
12+
13+
nx, ny, nz = 3, 3, 1
14+
n = nx * ny * nz
15+
dx, dy, dz = 1, 1, 1
16+
unit_length = 1.
17+
18+
mesh = CuboidMesh(nx=nx, ny=ny, nz=nz, dx=dx, dy=dy, dz=dz)
19+
20+
spin = np.ones(3 * n, dtype=np.double)
21+
spin[::3] = 0
22+
spin[1::3] = 0
23+
spin[3 * 4:3 * 4 + 3] = [0, 1, 0]
24+
Ms = np.ones(n)
25+
Ms_inv = 1 / Ms
26+
27+
field = np.zeros(3 * n, dtype=np.double)
28+
energy = np.zeros(n, dtype=np.double)
29+
30+
Exch.setup(mesh.nx, mesh.ny, mesh.nz, mesh.dx, mesh.dy, mesh.dz,
31+
mesh.unit_length,
32+
spin, Ms, Ms_inv,
33+
mesh.coordinates, mesh.neighbours,
34+
energy, field
35+
)
36+
37+
Exch.compute_field(0)
38+
print(field)
39+
print(energy)
40+
41+
# time.sleep(5)

0 commit comments

Comments
 (0)