Hello, I am new both to here and to Python. This is my first attempt at writing an actual code in Python 3; I've run into a problem with my class declaration, however. It may be a glaringly obvious problem, but it's not to me, so hopefully someone might spot it. Also, I am aware that this a pretty primitive approach to my algorithm; that is okay as well, this is just a proof-of-concept code.

I am attempting to write a Maxwell equation solver via finite-differencing schemes; it solves the vector and scalar potentials and calculates the electromagnetic fields from a given charge density and current density. I found it convenient to introduce a scalar field class, which so far is just a glorified three-dimensional array. In order to get and set values in the array easily, I made a At(j, l, n) function and a Set(j, l, n, value) function; the former returns the field quantity at the given gridpoints, and the latter sets that gridpoint field quantity to the given value.

The class seems to work fine when I use it for a single quantity. The problem occurs when I try to introduce a second field. It seems to duplicate all the data from the previously-made field into the new one. For example, if I make an electric field, FD_field E_x(10, 10, 10) , and then I set the electric field magnitude to 5.0 at (1, 1, 1), E_x.Set(1, 1, 1, 5.0) , that works. But if I create a new field (say, a magnetic field), FD_field B_x(10, 10, 10) , it starts out with the SAME field quantities as the electric field. If I try changing a quantity in the magnetic field, it subsequently also changes the SAME quantity in the ELECTRIC field at that SAME gridpoint. I don't know why it does this or what I'm doing wrong.

Can anyone show me the error of my ways? Any help anyone can give me is much appreciated. I'm not really a CS guy, and I'm completely new to Python, so I hope this isn't a stupid question or a waste of time or anything.

I've posted the field class below, and a short output I wrote in Py 3 earlier demonstrating the same problem.

Oh, this is also not a homework or anything, just an attempt at understanding.

class FD_field:
    """Finite-difference Maxwell Solver Field Data-type"""
    # Data declarations and initialization
    lenx = 0
    leny = 0
    lenz = 0
    data = []
    #
    # --- Class __init__ declarations ---
    #
    def __init__(self, jj, ll, nn):
        self.lenx = jj
        self.leny = ll
        self.lenz = nn
        l = []
        for i in range(self.lenx):
            dl = []
            for j in range(self.leny):
                dm = []
                for k in range(self.lenz):
                    dm.append(0)
                dl.append(dm)
            self.data.append(dl)
        del dl, dm, l, jj, ll, nn, i, j, k
    #
    # --- At() function declaration ---
    #
    def At(self, j, l, n):
        dl = []
        dl = self.data[j]
        dm = []
        dm = dl[l]
        vl = dm[n]
        del dl, dm
        return vl
        del dl, dm, j, l, n, vl
    #
    # --- Set() function declaration ---
    #
    def Set(self, j, l, n, vl):
        dl = []
        dm = []
        dl = self.data[j]
        dm = dl[l]
        dm[n] = vl
        dl[l] = dm
        self.data[j] = dl
        del dl, dm, j, l, n, vl
    #
    # --- PrintNice(), PrintNiceH(), just to look pretty ---
    #
    def PrintNice(self):
        for i in range(self.lenz):
            for j in range(self.leny):
                for k in range(self.lenx):
                    print(self.At(k,j,i), end=' ')
                print('\n')
            print('\n\n')
        del i, j, k
    def PrintNiceH(self):
        for j in range(self.leny):
            print(" | ", end=' ')
            for k in range(self.lenz):
                for i in range(self.lenx):
                    print(self.At(i,j,k), end=' ')
                print(" | ", end=' ')
            print(" ")
        del i, j, k

and the output from Python 3:

Python 3.0.1 (r301:69561, Feb 13 2009, 20:04:18) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import FDMAX
>>> f = FDMAX.FD_field(4, 4, 4)
>>> f.At(1, 1, 1)
0
>>> f.PrintNiceH()
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
>>> # Now I set the value of the field to 5 at (1,1,1):
>>> f.Set(1, 1, 1, 5)
>>> f.At(1, 1, 1)
5
>>> f.PrintNiceH()
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 5 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
>>> # Now I make a new field, and it has the same data...?
>>> g = FDMAX.FD_field(4, 4, 4)
>>> g.At(1, 1, 1)
5
>>> g.PrintNiceH()
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 5 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
>>> # If I change the g-field, it also changes the f-field...
>>> g.Set(2, 2, 2, 8)
>>> g.At(2, 2, 2)
8
>>> g.PrintNiceH()
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 5 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 8 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
>>> f.At(2, 2, 2)
8
>>> f.PrintNiceH()
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 5 0 0  |  0 0 0 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 8 0  |  0 0 0 0  |   
 |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |  0 0 0 0  |   
>>>

Running the following code yields the result posted. id is one of the first things you want to know when two objects appear to be the same.

f = FD_field(4, 4, 4)
f.At(1, 1, 1)
print ("f #1 id = %d" % id(f.data))

f.Set(1, 1, 1, 5)
f.At(1, 1, 1)
print ("f #2 id = %d" % id(f.data))

g = FD_field(4, 4, 4)
g.At(1, 1, 1)
print ("g #1 id = %d" % id(g.data))

This prints
f #1 id = 3083171468
f #2 id = 3083171468
g #1 id = 3083171468
Note they all have the same id, and so are the same object. First avoid globals, such as the ones at the beginning of your class. Second, add a unique self.data for each instance. Running the code below should result in what you want.

class FD_field:
    """Finite-difference Maxwell Solver Field Data-type"""
    # Data declarations and initialization
    lenx = 0
    leny = 0
    lenz = 0
    data = []
    #
    # --- Class __init__ declarations ---
    #
    def __init__(self, jj, ll, nn):
        self.lenx = jj
        self.leny = ll
        self.lenz = nn

        ##---  added a unique self.data field for each instance
        self.data = []

        l = []
        for i in range(self.lenx):
            dl = []
            for j in range(self.leny):
                dm = []
                for k in range(self.lenz):
                    dm.append(0)
                dl.append(dm)
            self.data.append(dl)
        del dl, dm, l, jj, ll, nn, i, j, k
    #
## The rest of the code remains the same

The id's print
f #1 id = 3083034188
f #2 id = 3083034188
g #1 id = 3082646892 <----- different

Thanks so much, that fixed it! I didn't know about the id, that helps out a lot and will be very useful in the future.

Thanks!!

This question has already been answered. Start a new discussion instead.