GSoC 2013 Application Sachin Joglekar: Electromagnetism module - sympy/sympy GitHub Wiki

Personal Details

Name: Sachin Joglekar

Email and Google Code username: [email protected]

IRC: srjoglekar246 (occasionally online)

Github: srjoglekar246

Background and Skills

I am a second year undergraduate computer science student studying at Birla Institute of Technology and Science-Pilani, Goa campus. As a coder, I am at my most comfortable programming in Python, while having a good amount of experience with C++ and Java as well. I have used C++ and Java primarily for academic courses (Object Oriented Programming, Data structures and Algorithms, CS Logic etc.), and Python for all other work.

I started out with Python while coding for a project involving waveform feature extraction and classification, and acquired knowledge of coding styles and conventions during the course of my work for SymPy. I have been using Python for about two years now, and I am sure I can handle all the language features well.

I mainly work on a Windows machine, even though I am quite comfortable with Linux Mint as well. I have used git for version control for a long time now, and I can say that I am proficient with its basics.

I can be reached at any time at my email address or on Google Talk. I am only occasionally online via the IRC.

Contributions to SymPy

All my past merged work for SymPy has been for sympy.logic, primarily under the guidance of Christopher Smith (@smichr). My PRs that were merged-

My un-merged PRs-

The Project

A few months back, inspired by sympy.physics.mechanics, I started working on a module for sympy.physics based on concepts from electromagnetism. The code I wrote was quite rudimentary, and I couldn’t take it further at that time due to other commitments. That branch can be seen at-

https://github.com/sympy/sympy/pull/1695

For my GSoC project, I plan to build the basic infrastructure needed to handle electric and magnetic fields, their relationships with each other and their interactions with particle charges. Not only will this help a user in the study of electromagnetic fields, but also in the symbolic calculations pertaining to mechanics of charges under their influence. Considering the potential of the sympy.physics library, I think addition of electromagnetism features would be an important plus for SymPy.

As a part of my first year undergraduate curriculum, I have completed a course on Electrical Sciences and am currently reading up relevant texts on electromagnetism. Because of my preparation for various competitive exams, I have a good experience with solving problems based on electromagnetic concepts with pen and paper. This knowledge, along with my grasp over the object oriented paradigm will ensure that I am able to build the required class structure and helper methods for the proposed module.

Why this project?

Electric and magnetic fields, even in their classic, non-relativistic forms are used extensively in problems of physics. Combined with the mechanics package of SymPy, my proposed module would enable users to easily and effortlessly apply these concepts to study not just the said fields themselves, but also the mechanics of particles (and in the future, complex bodies) in an electromagnetic environment.

As far as my GSoC code is considered, it would be more of an extension to sympy.physics.mechanics. This is because after the application of certain key concepts and formulae, my work would essentially boil down to handling Vectors (interactions of fields as vectors) and mechanics (of ParticleCharges). Considering the complexity of the motion of ParticleCharges in presence of E-M fields, dynamics of particles would play a major role in my project.

My GSoC work would also serve as a foundation for further efforts in the direction of electromagnetic 'worlds', such as implementation of relativistic fields and mechanics of complex bodies under the influence of E-M fields. I plan to work on this in my leisure time after GSoC gets over. 'sympy.physics.electromagnetism' (tentative name) could thus also serve as an extension to PyDy, helping create something like 'PyPhysics'.

Implementation

This is a rough sketch of how I would implement my proposed module. I have included bits of code here and there to give a demo of my overall idea.

Vector Field framework

This part would involve-

  • Construction of a basic framework to handle coordinate and time variables for vector field calculations. This framework would essentially produce special types of Symbols to distinguish them from ordinary Symbols which the user may use in his definitions of vector fields. Please refer to the shown example below to get an idea of how this would work.

  • Implementation of the methods/API to derive quantities like curl, gradient, divergence and time derivatives of any vector field V of the type V(x, y, z, t).

  • Implementation of the methods/API to derive line, surface(area) and volume integrals of any vector field V of type V(x, y, z, t).

API –

a. line_integral(vfield, curve, Point1, Point2)

b. Implementation of surface and volume integrals would take some planning to do.

In the worst case, I will implement all the special cases like spheres and circles, cubes and squares etc using equations of curves in space. (I have tried to demonstrate a surface integral in the prototype during the usage of EMF_induced, using intersection of two curves.) Further work done on Vector Calculus would aid my code in that case.

  • Implement methods to handle different units systems like MKS, Heaviside-Lorents and CGS(Gaussian) during calculations on electromagnetic quantities.

Example of working -

#Define coordinate and time variables

x_v, y_v, z_v, t_v = CoordinateSymbols(‘ x_v y_v z_v t_v’)

R = ReferenceFrame(‘R’)

#Associate ReferenceFrame with CoordinateSymbols

R.associate_symbols(x_v, y_v, z_v, t_v)

vector1 = 2 * x_v * R.x + 3 * y_v**2 * R.y – sin(z_v) * R.z

gradient(vector1)

Output –> 2 * R.x + 6 * y_v * R.y – cos(z_v) * R.z

vector2 = 3 * t_v**2 * R.x

time_derivative(vector2, 2)


#time_derivative would automatically find the time variable and differentiate. In case of multiple time variables, raise error.

Output -> 6 * R.x

[Note: I have not yet finalized the Vector Field framework, and the above API is tentative. I plan to work on this more after my endsems end and interact with the mentor/community before I settle on any implementation.]

ScalarPotential

ScalarPotential class would denote scalar fields in space. They would essentially help in initialisation of corresponding ElectricFields and to get the ScalarPotential produced by an ElectricField [ If ElectricField is non-conservative, a corresponding VectorPotential or MagneticField will also be have to be provided to get the ScalarPotential]

API-

a. sfield.electric_field()

ElectricField

ElectricField class would have the methods and attributes for implementation of following features-

  • Check whether ElectricField is conservative (is_conservative = True) or not.

  • Vectorial value and magnitude.

API –

efield.value() would return symbolic vectorial value of the field in space, while efield.value(p, origin) where p is a Point would return the calculated value of the field at that Point in space. p’s coordinates would be calculated with respect to the specified Point origin.

  • Corresponding ScalarPotentials (and potential difference between two Points). Also helpful would be option of an arbitrary datum (may be defined at oo) in calculation of absolute potential at any given Point.

API –

a. efield.scalar_potential(c) would return ScalarPotential with added constant ‘c’.

b. efield.potential_difference(Point1, Point2, origin) [The origin would be required to find values of coordinates of Point1 and Point2]

c. efield.scalar_potential(p, datumpoint, valueatdatum) would return value of scalar potential at Point p with respect to specified datum, which may be infinity as remarked earlier.

  • Field energy density at a Point, Field energy in a given volume(in vaccum)

API –

efield.energy_density() would return Vector value of energy density in terms of coordinate variables, while efield.energy_density(p, origin) would give value of the energy density at Point p.

  • Flux of the ElectricField through a given area

Example of working of ScalarPotential and ElectricField-

sfield = ScalarPotential(6 * x_v**2 * y_v)

sfield.vector_gradient(R)

Output -> 12 * x_v * y_v * R.x + 6 * x_v**2 * R.y


#Define ElectricField with respect to ScalarPotential

efield = ElectricField(sfield)

#Assume Point m is at R.x + R.z with respect to Point origin

efield.value(m, origin)

Output -> 6 * R.y

efield.energy_density(m, origin, 'MKS')

Output -> 1.5937538076e-08

VectorPotential

The class VectorPotential would be implemented in analogy to ScalarPotential, to help initialise MagneticFields and Electricfields.

ChargeDensity and CurrentDensity

For the time being, I plan to handle all the usual, ‘simple to handle’ charge densities like spherically symmetrical, constant etc. Some functions on the rest would return ‘NotImplementedError’. Also included will be mechanisms to implement Principle of Charge Conservation.

MagneticField

MagneticField would have methods and attributes to implement the following features -

  • Vectorial value and magnitude.

API would be similar to that of ElectricField.

  • Corresponding VectorPotentials.

  • Field energy density at a Point, Field energy in a volume.

API of the above would be similar to that of ElectricField.

  • Induced ElectricField based on Faradays Law/ Amperes Law. The condition assumed would be that of free space, unless the user specifies a CurrentDensity.

API-

mfield.induced_electric_field(j) where j is the CurrentDensity, would produce return the ElectricField induced by the MagneticField mfield.

Changes to the classes of fields

Once MagneticField is implemented, the focus would shift to ElectricField. The changes would be -

  • Adding methods to ElectricField to generate MagneticField based on its time-varying nature and CurrentDensity of environment ( efield.induced_magnetic_field() ), using Ampere’s Law.

  • Overloading of the initializer for ElectricField to accept different arguments like Vectors, ScalarPotentials and magnetic VectorPotentials. This would help a user define the ElectricField according to the specific parameters of his particular problem, instead of having to convert them. Constructor for MagneticField would also be overloaded in a similar fashion.

I also plan to implement certain auxiliary methods like -

  1. total_Electric_Field_at(Point, *factors) -based on principle of superposition

  2. total_Magnetic_Field_at(Point, *factors)

  3. EMF_induced(curve, *magneticfields)

Example of use of MagneticField and EMF_induced(To find EMF induced by a certain magnetic field in a given curve)-

#Define magnetic field with vector

mfield = MagneticField(3 * R.y)


#Find EMF induced in circle in X-Y plane

EMF_induced( [x_v  ** 2 + y_v ** 2 = 4, z_v = 0], mfield)

Output -> 0

ParticleCharge

ParticleCharge will be extended as a subclass of the current Particle class from sympy.physics.mechanics. This class would have methods to simulate its interactions with ElectricField and MagneticField, such as-

  • set_motion(*factors, time = 0)

This method would just set the ParticleCharge’s velocities and accelerations symbolically according to fields provided (in terms of coordinate variables). If time is zero or positive, it would calculate the velocity, acceleration and Point parameters of the ParticleCharge and set the values accordingly.

This part would take some time, especially considering handling of different ReferenceFrames and complexity of operations.

  • lorentz_force(*fields)

  • electric_field_at()

Would return ElectricField produced by the ParticleCharge itself.

  • magnetic_field_at()

Would return the MagneticField produced by ParticleCharge as per Biot-Savart law.

  • potential_energy()

Would return the potential energy of the ParticleCharge

The last phase would be modification of ParticleCharge to accomodate and express its interactions with other instances of ParticleCharge, especially the changes to potential_energy() and set_motion() where the field of one ParticleCharge would affect the other.

Also included in this phase would be the creation of auxiliary functions to study ParticleCharge distributions in presence or absence of an ElectricField and/or MagneticField, energy of assembly of charge distributions, etc.

Example of basic usage of ParticleCharge-

origin = Point(‘origin’)

p = Point(‘p’)

q = Point('q')

p.set_pos(origin, 1 * R.x)

q.set_pos(origin, -R.x)

#Define ParticleCharges having charge 1 Coulomb at Points p and q

P1 = ParticleCharge('P1', p, 1)

Q1 = ParticleCharge('Q1', q, 1)


#The vectorial value of field due to P1 and Q1 has no component along R.x

(P1.electric_field_at(r) + Q1.electric_field_at(r)).value().dot(R.x)

Output -> 0

Important formulae and concepts

Principle of Charge Conservation

Charge conservation is a physical law that states that the change in the amount of electric charge in any volume of space is exactly equal to the amount of charge flowing into the volume minus the amount of charge flowing out of the volume.

Mathematically, this reduces to divergence(j) = - time_derivative(rho) where j is the current density and rho is the charge density.

Potentials and fields

Let A be the magnetic VectorPotential, V be the electric ScalarPotential and E and B be an ElectricField and MagneticField respectively. Hence, by potential thery,

  1. B = curl(A)

  2. E = -vector_gradient(V) – g * time_derivative(A)

Maxwell’s equations

Maxwell’s equations, in differential or integral form, lay down the basis for classical electrodynamics.

  • Gauss’s theorem for electric field can be expressed mathematically as

divergence(electricfield) = 4 * pi * k * chargedensity

  • Gauss’s law for magnetic field states that

divergence(magneticfield) = 0 always

  • Faradays Law-

curl(electricfield) + g * time_derivative(magneticfield) = 0

  • Ampere’s Law-

curl(magneticfield) – 1 / (g * c**2) * time_derivative(electricfield) = 4 * pi * k / (g * c**2) * j where j is the current density in space.

Faraday’s Law ,Ampere’s Law, and Gauss’ Law in their differential and integral forms can be used to calculate the interactions of the two types of fields, and also to derive some of their properties like line integrals and closed surface integrals.

###Lorentz Force

While the fields and potential functions generated by a ParticleCharge are well known, the Lorentz force F exerted by a combination of magnetic field B and electric field E can be given as–

F = particle_charge * (E + g * (particle_velocity.cross(B))

[ Note – the constants used above will change with respect to the Unit System used.]

Tentative timeline

This is a tentative schedule that I intend to follow during the summer. I have kept the expected timeline a little pessimistic to accommodate uncertainties. I will have no problem in dedicating the required 40 hours per week to this project.

Each of the components of my timeline (except the Community Bonding Period) would correspond to one pull request from my side. I have structured my timeline in such a way that my code is compartmentalized and the work is divided into sub-parts that can be individually evaluated. Will also help in debugging, if needed at a later stage.

Community Bonding Period

I intend to extend this part backwards up to the day I write this, to ensure that I get sufficiently acquainted with the concepts related to the project well before I start coding. I would mainly be focussing on doing the following-

  • Research various aspects of Electric and Magnetic fields and their interactions. For this part, I plan to thoroughly read through the relevant parts of ‘Classical Electrodynamics for Undergraduates’ by Prof. John Norbury and use ‘Introduction to Electrodynamics’ by David Griffiths as a reference book.

  • Based on my research, identify the features that would be essential and useful to a symbolic electromagnetism module.

  • Chalk out the basic class structure and set of methods that I would be expected to implement during summer, with the help of the sympy.physics community and my mentor(after May 27).

  • Figure out ways to implement functions of line, surface and volume integrals of vector fields.

Week 1-2

Objectives-

  • Implement the Vector field framework and add tests to ensure its proper working.

  • Write detailed plans and rough docstrings for every class and method I plan to implement as a part of GSoC. These plans will be put up by me as a separate PR so that discussion on my project framework will be easy. Get the plans approved by mentor.

Week 3-4

Objectives-

  • Implementation of ScalarPotential class.

  • Implementation of features of conservative ElectricField.

  • Add tests to ensure proper working of code. Make sure documentation is perfect.

Week 5-6

Objectives-

  • Implementation of a VectorPotential class in analogy with ScalarPotential.

  • Implementation of classes to represent CurrentDensity(j) of magnetization and ChargeDensity(rho).

  • Implementation of features of MagneticField class.

  • Add tests and perfect the documentation for VectorPotential , MagneticField and the density classes.

MID-TERM EVALUATION

Week 7-8

Objectives-

  • Addition of auxiliary functions for MagneticField and ElectricField, as specified in Implementaion section.

  • Overloading initializers for ElectricField and MagneticField.

  • Improving ElectricField class to accommodate handling of non-conservative ElectricField.

(For details, please refer to Implementation section)

  • Ensuring complete consistency of infrastructure created till this week through tests and detailed examples.

Week 9

Objectives-

  • Add docstrings to Sphinx documentation.

  • Fix any bugs if found.

  • Make any further tweaks as per mentor’s reviews on code.

Week 10-11

Objectives-

  1. Implementation of ParticleCharge

Week 12

Objectives-

  1. Implementation of functions to study interactions of instances of ParticleCharge with each other. For example, work done in assembly of charges, charged-particle distributions in electric fields, etc.

Week 13

Buffer period.

Objectives-

  1. Make sure previous code is bug free.

  2. Write detailed tests for ParticleCharge code.

  3. Add docstrings to Sphinx documentation.

  4. Write a tutorial on the use of the code written during GSoC, along with sufficient examples for illustration.

Solved Example (Prototype)

This section demonstrates the procedure to solve a simple example problem using my module.

Problem statement : An intitially static particle of mass m and charge q is put under the influence of an electric field of magnitude E and angle Y to the X-axis. After time t, this field is switched off and a magnetic field of magnitude M, along the X-axis is switched on. At the same moment, another particle is projected in direction of the magnetic field from the same point as the initial particle. What should be the speed of the second particle so that the particles meet again and again after regular intervals of time?

Solution : Consider R as the ReferenceFrame. The first charged particle, under the influence of the electric field, will gain a velocity of (qEt/m)*(cos(Y)*R.x + sin(Y)*R.y) after time t. Once the magnetic field is switched on and electric field is switched off, it will start moving in a helical path due to Lorentz force such that the axis of the helix will lie along the X-axis(i.e. in the direction of the magnetic field). As the second particle's velocity is along the magnetic field, it will not experience any acceleration. Now, the two particles will meet only if the first particle's velocity along the magnetic field is equal to the second particle's velocity.

Note that the solution is same irrespective of directions of the fields, as long as their relative angle remains the same.

# Initialise the essentials, assuming all required import have been made and ReferenceFrame R with CoordinateSymbols is already defined

E, M, q, Y, t = symbols('E M q Y t')

# Initialise ElectricField with vector 

efield = ElectricField(E * cos(Y) * R.x + E * sin(Y) * R.y)

# Set properties of first particle

p = Point('p')

P = ParticleCharge('P', p, q)

P.set_mass(m)

# Set motion of P with the values after time t with respect to efield

P.set_motion(efield, t)

# Set acceleration to zero to denote switching off of Electricfield

P.set_acceleration(0)

# Define MagneticField with vector 

mfield = MagneticField(R.x)

# Set motion as per MagneticField. As the component of velocity along MagneticField will be constant, time does not matter 

P.set_motion(mfield)

# Get component of P's velocity along mfield's direction 

(P.linear_momentum() / P.get_mass()).dot(mfield.value())

Output -> q*E*t*cos(Y)/m

Notes-

  • Prasoon’s project on Vector Calculus, if successful, will aid my work with basic functions of vector fields and coordinate frames, thus improving their handling in my module. What I propose to do in such a case is to get his working API and insert it into my code, after understanding its exact functioning. I plan to structure the relevant parts of my module in such a way that this process would be easy and his methods would gel easily into my work. This would essentially be done during the last two weeks of my GSoC period. In the unfortunate case that Prasoon’s project does not get accepted, I would be implementing the required vector functions in 3 dimensions in the manner I have specified before. If any work is done in the future regarding vector calculus, the relevant API would fit easily into my code.
  • If I happen to make progress faster than the timeline shown above, I plan to implement dipoles and wires as a part of the module, considering they are quite relevant to the understanding of electromagnetic fields in space. They will be implemented to interact with fields in a manner similar to ParticleCharges. I will have an API of these classes ready by the end of the community bonding period.
  • I have my university endsem exams till May 12, so till then I won't be able to work much apart from replying to any comments I receive about my proposal and updating it if necessary. After May 12, I plan to start studying and drawing out rough plans as I have mentioned in the 'Community bonding' section. At any time, pre or post-May 3, I can be reached at my email for any doubts/queries regarding my proposal.

Post-GSoC

As stated earlier, I plan to work on this module even after GSoC. Future work on this module would include-

  • Implementation of special electromagnetic bodies like dipoles, wires, special magnets and also dielectrics.

  • Integration of this module with PyDy to enable solving electromagnetism-mechanics based problems on complex bodies.

  • Implementation of relativistic fields in space.

References-