Computational Physics (CompPhys), Computational Fluid Dynamics (CFD)

I went through Ch.10 of Hjorth-Jensen (2015) and wrote up as many C++ scripts to illustrate all the (serial) PDE solvers: forward, backward Euler, Crank-Nicolson, Jacobi method.

Cpp/progs/ch10pde of CompPhys github repository

Lid-driven cavity with incompressible, viscous fluid on a 512×512 staggered grid, in CUDA C++11, with finite difference method for 2-dim., unsteady Navier-Stokes equations solver

cf. https://github.com/ernestyalumni/CUDACFD_out/tree/master/NavSt2DIncompFiniteDiff

u_re1000_t014u_re1000_t024u_re1000_t034u_re1000_t044u_re1000_t054u_re1000_t064u_re1000_t074u_re1000_t084u_re1000_t094uv_re1000_t014uv_re1000_t024uv_re1000_t034uv_re1000_t044uv_re1000_t054uv_re1000_t064uv_re1000_t074uv_re1000_t084uv_re1000_t094

Compare this with pp. 69 of Ch. 5, Example Applications of Griebel, Dornsheifer, Neunhoeffer.

 

Michael Griebel, Thomas Dornsheifer, Tilman Neunhoeffer.  Numerical Simulation in Fluid Dynamics: A Practical Introduction (Monographs on Mathematical Modeling and Computation).  SIAM.  1997.

Advertisements

Cantera installation tips (on Fedora Linux, namely Fedora 23 Workstation Linux)

I spent an obscene amount of time documenting my installation on Fedora 23 Workstation Linux of Cantera on my github repository subdirectory cantera_install_tips in Markdown. I’ll try copying markdown in here, in wordpress. Otherwise, go here: github:Propulsion/cantera_stuff/cantera_install_tips/

Cantera Installation Tips

Installing Cantera on Fedora Linux, straight, directly from the github repository, all the way to being compiled with scons, was nontrivial, mostly because of the installation prerequisites, which, in retrospect, can be easily installed if one knows what they are with respect to what it is in terms of Fedora/CentOS/RedHat dnf.

codename directory reference webpage (if any) Description
cantera_install_success ./ None A verbose, but complete Terminal log of cantera installation on Fedora Workstation 23 Linux, from git clone, cloning the githb repository for cantera, directly, all the way to a successful scons install.
ClassThermoPhaseExam.cpp ./ Computing Thermodynamic Properties, Class ThermoPhase, Cantera C++ Interface User’s Guide Simple, complete program creates object representing gas mixture and prints its temperature
chemeqex.cpp ./ Chemical Equilibrium Example Program, Cantera C++ Interface User’s Guide equilibrate method called to set gas to state of chemical equilibrium, holding temperature and pressure fixed.
verysimplecppprog.cpp ./

Installation Prerequisites, ala Fedora Linux, Fedora/CentOS/RedHat dnf

While Cantera mainpage’s Cantera Compilation Guide gave the packages in terms of Ubuntu/Debian’s package manager:

g++ python scons libboost-all-dev libsundials-serial-dev

and for the python module

cython python-dev python-numpy python-numpy-dev

for other Linux distributions/flavors, the same libraries have different names for different package managers and some libraries were already installed with the “stock” OS and some aren’t (as I found in my situation. For example, Cantera’s mainpage, for Ubuntu/Debian installation (compilation), it’s neglected that boost is already installed (which I found wasn’t for Fedora 23 Workstation Linux).

Installation Prerequisites for Fedora 23 Workstation Linux (make sure to do these dnf installs and installation with scons will go more smoothly).

I found that you can’t get away from dnf install on an administrator account – be sure to be on a sudo or admin account to be able to do dnf installs. Also, I found that compiling Cantera had to be done on a sudo-enabled or administrator account, in particular, access is needed to be granted to accessing root directories such as /opt/, etc. (more on that later).

Also, in general, you’d want to install the developer version of the libraries as well, usually suffixed with -devel, mostly because the header files will be placed in the right /usr/* subdirectory so to be included in the system (when compiling C++ files or installing).

  • g++ and gcc – For something else (namely CUDA Toolkit), I successfully installed, by dnf install, gcc 5, the C++ compiler that has compatibility with the new C++11/C++14 standard. The C++11 standard is necessary for compiling C++ files using Cantera (so the flag -std=c++11 is needed with g++).
  • scons – be sure to install scons – it seems like there is a push to use scons, a Python program, for installation and (package) compilation, as opposed to (old-school) CMake, or Make.
  • boostBoost is free peer-reviewed portable C++ source libraries.
sudo dnf install boost.x86_64
sudo dnf install boost-devel.x86_64
  • lapacklapack, Linear Algebra PACkage. Don’t take it for granted that lapack is already installed (I had to troubleshoot this myself, beyond the Cantera main page documentation, and find where it is). I had to install it because I found it was missing through the Cantera scons build
dnf list lapack*  # find lapack in dnf
sudo dnf install lapack.x86_64
sudo dnf install lapack-devel.x86_64
  • blasblas, Basic Linear Algebra Subprograms. Don’t take it for granted that blas is already installed (I had to troubleshoot this myself, beyond the Cantera main page documentation, and find where it is). I had to install it because I found it was missing through the Cantera scons build
dnf list blas*  # find blas in dnf
sudo dnf install blas.x86_64
sudo dnf install blas-devel.x86_64
  • python-devel – Following the spirit of how you’d want to install the developer’s version of the library concurrent with the library itself, in that you’d want the headers and symbolic links to be installed and saved onto the respective root /usr/* subdirectories (so that your system will know how to include the files), you’d want to install the Python developer’s libraries.
sudo dnf install python-devel

On this note, for Fedora Linux, I did not find with dnf list python-numpy nor python-numpy-dev which, supposedly, is found in Ubuntu/Debian – this is an example of how Fedora/CentOS/RedHat package manager is different from Ubuntu/Debian.
sundialsundial has (essential) non-linear solvers.

sudo dnf install sundials.x86_64
sudo dnf install sundials-devel.x86_64

Clean install, from git clone to scons install

git clone https://github.com/Cantera/cantera.git

scons build -j12

scons build -j12

scons build by itself is ok; I added the flag -j12 (correct me if I’m wrong) to optimize the compilation on 12 cores. So if you’re on a quad-core CPU processor, then you’d do -j4.
scons test
In my experience, if all the necessary libraries and prerequisite software are installed, then scons test should result in all tests being passed, none failed.
sudo scons install

sudo scons install

There’s no getting around not using sudo for scons install.

A successful sudo scons install should end up looking like this at the very end:

Cantera has been successfully installed.

File locations:

  applications                /usr/local/bin
  library files               /usr/local/lib64
  C++ headers                 /usr/local/include
  samples                     /usr/local/share/cantera/samples
  data files                  /usr/local/share/cantera/data 
  Python 2 package (cantera)  /usr/local/lib64/python2.7/site-packages
  Python 2 samples            /usr/local/lib64/python2.7/site-packages/cantera/examples 
  setup script                /usr/local/bin/setup_cantera

The setup script configures the environment for Cantera. It is recommended that
you run this script by typing:

  source /usr/local/bin/setup_cantera

before using Cantera, or else include its contents in your shell login script.

scons: done building targets.

Knowing where all the files were installed is good to know.

Compiling very simple C++ programs as a sanity check (that Cantera was installed)

The Cantera main page, C++ Interface User’s Guide, under Compiling Cantera C++ Programs gave the tips of using 3 ways, pkg-config, SCons, Make as ways to compile C++ programs.

However, a brief peruse of Cantera.mak, you’ll see that the flags included are daunting, numerous, and complicated:

# Required Cantera libraries
CANTERA_CORE_LIBS=-pthread -L/usr/local/lib64 -lcantera

CANTERA_CORE_LIBS_DEP = /usr/local/lib64/libcantera.a

CANTERA_EXTRA_LIBDIRS=

CANTERA_CORE_FTN=-L/usr/local/lib64 -lcantera_fortran -lcantera

CANTERA_FORTRAN_MODS=$(CANTERA_INSTALL_ROOT)/include/cantera

CANTERA_FORTRAN_SYSLIBS=-lpthread -lstdc++

###############################################################################
#            BOOST
###############################################################################

CANTERA_BOOST_INCLUDES=

###############################################################################
#         CVODE/SUNDIALS LINKAGE
###############################################################################

CANTERA_SUNDIALS_INCLUDE=
CANTERA_SUNDIALS_LIBS= -lsundials_cvodes -lsundials_ida -lsundials_nvecserial

Do you need sundials all the time? Does anyone (still) program in Fortran (2016)? Do we really need to include the /usr/local/lib64 directory every time? What’s the most minimal number of flags needed?

Thus, in this repository’s subdirectory, I included the simple programs that I was able to compile without a complicated Makefile such as Cantera.mak.

I found these compilation commands worked:

g++ -std=c++11 verysimplecppprog.cpp -o verysimplecppprog -lcantera -l pthread
g++ -std=c++11 chemeqex.cpp -o chemeqex -lcantera -l pthread
g++ -std=c++11 ClassThermoPhaseExam.cpp -o ClassThermoPhaseExam -lcantera -l pthread

These flags also worked, but seemed unnecessary:

g++ -std=c++11 chemeqex.cpp -o chemeqex -lcantera -L/usr/local/lib64 -lsundials_cvodes -lsundials_ida -lsundials_nvecserial -L/usr/local/lib -l pthread

Troubleshooting installation/(installation) errors that pop up

  • fatal error: Python.h: No such file or directory
fatal error: Python.h: No such file or directory
scons: *** [build/temp-py/_cantera2.os] Error 1

I found that I had to dnf install python-devel to get the header files installed onto the appropriate /usr/* root subdirectories.
scons: *** [/usr/local/include/cantera/Edge.h] /usr/local/include/cantera/Edge.h: Permission denied
Do sudo scons install
error: could not create/usr/local/lib64/python2.7′: Permission deniedDosudo scons install-scons: *** [/opt/cantera] /opt/cantera: Permission denied`

scons: *** [/opt/cantera] /opt/cantera: Permission denied
scons: building terminated because of errors.

Do sudo scons install

Troubleshooting C++ compilation/(C++ compilation) errors that pop up

I realized that I needed to include the Cantera library in this way:

-lcantera

when compiling with g++.
Package cantera was not found in the pkg-config search path.

Package cantera was not found in the pkg-config search path.
Perhaps you should add the directory containing `cantera.pc'
to the PKG_CONFIG_PATH environment variable
No package 'cantera' found
verysimplecppprog.cpp:9:29: fatal error: cantera/Cantera.h: No such file or directory
compilation terminated.

In my experience, I found that pkg-config, even though installed, didn’t work in compiling a simple program.
/usr/lib64/libpthread.so.0: error adding symbols: DSO missing from command line

I Google searched for this webpage:
cf. “error adding symbols: DSO missing from command line” while compiling g13-driver, ask ubuntu

From this page, I saw the use of the line LIBS = -lusb-1.0 -l pthread, and the idea of using the flag -l pthread ended up being the solution.
/usr/include/c++/5.3.1/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
You must include the -std=c++11 to use the new C++11 standard. Indeed:

/usr/include/c++/5.3.1/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
 #error This file requires compiler and library support \
  ^
In file included from /usr/local/include/cantera/base/fmt.h:2:0,
                 from /usr/local/include/cantera/base/ctexceptions.h:14,
                 from /usr/local/include/cantera/thermo/Phase.h:12,
                 from /usr/local/include/cantera/thermo/ThermoPhase.h:14,
                 from /usr/local/include/cantera/thermo.h:12,

So you’ll have to compile like this:

g++ -std=c++11

and include this flag in Makefiles.
usr/bin/ld: cannot find -l
include the -lcantera flag in C++ compilation.

Images gallery (that may help you with your installation process; it can be daunting)

dnf list boost-*

dnf list boost

sudo dnf install boost-devel.x86_64

sudo dnf install boost-devel.x86_64

dnf list lapack*  # find lapack in dnf
sudo dnf install lapack-devel.x86_64

sudo dnf install lapack-devel.x86_64

sudo dnf install python-devel

sudo dnf install python-devel

sudo dnf install sundials.x86_64
sudo dnf install sundials-devel.x86_64

sudo dnf install sundials.x86_64

sudo dnf install sundials-devel.x86_64

git clone https://github.com/Cantera/cantera.git

git clone

fatal error: Python.h: No such file or directory
scons: *** [build/temp-py/_cantera2.os] Error 1

fatal error: Python.h: No such file or directory

Successful installation/compilation (what we want, what it should look like)

scons build

sconsbuildsuccess

scons test

scons test

scons test success

scons test

sudo scons install

There’s no way, I found, of getting away from having to use sudo for scons install – you’ll have to be on a sudo enabled or administrator account logged in.

It troubleshoots

scons: *** [/usr/local/include/cantera/Edge.h] /usr/local/include/cantera/Edge.h: Permission denied
error: could not create `/usr/local/lib64/python2.7': Permission denied

sudo scons install

sudo scons install

sudo scons install success

sudo scons install success

Hillis/Steele and Blelloch (i.e. Prefix) scan(s) methods implemented in parallel on the GPU w/ CUDA C++11

In the subdirectory scan in Lesson Code Snippets 3 is an implementation in CUDA C++11 and C++11, with global memory, of the Hillis/Steele (inclusive) scan, Blelloch (prefix; exclusive) scan(s), each in both parallel and serial implementation.

As you can see, for large float arrays, running parallel implementations in CUDA C++11, where I used the GeForce GTX 980 Ti smokes being run serially on the CPU (I use for a CPU the Intel® Xeon(R) CPU E5-1650 v3 @ 3.50GHz × 12.

scansmainscreenshot20from202016-11-042005-12-36

I have a thorough write up on the README.md of my fork of Udacity’s cs344 on github.

Note that I was learning about the Hillis/Steele and Blelloch (i.e. Prefix) scan(s) methods in conjunction with Udacity’s cs344, Lesson 3 – Fundamental GPU Algorithms (Reduce, Scan, Histogram), i.e. Unit 3.. I have a writeup of the notes I took related to these scans, formulating them mathematically, on my big CompPhys.pdf, Computational Physics notes.

I accidentally `dnf update` on Fedora 23 w/ NVidia GTX 980 Ti & prop. drivers & new kernel trashed my video output for the 2nd time; here’s how I recovered my system; Fedora Linux installation, including install of CUDA

20161031. Note that another, similar (i.e. only a few minor changes), version of this post, in Markdown format, is on my MLGrabbag github repository, MLGrabbag README.md

Oops.  I was on an administrator account and I accidentally ran


dnf update

<!–

–>

dnf update , #fedoralinux #Fedora #linux I’m always so very weary about doing this, because I’ve set up my Linux setup to be as minimal (stock?) as possible with installs and dependencies. In particular, I’ve setup Fedora Linux to use the proprietary @nvidiageforce @nvidia drivers, NOT the open-source and not so good (they WILL trash your video output and get you to Fedora’s own blue screen of death) #negativo drivers. And I’ve changed around and added symbolic links manually into the root system’s collection of libraries involving #cuda, so it’ll make my C++ programming included and library inclusion at make easier. I cringe if dnf update automatically installs negativo or “accidentally” cleans up my symbolic links or breaks dependencies with CUDA.

A video posted by Ernest Yeung (@ernestyalumni) on Oct 30, 2016 at 7:49pm PDT

//platform.instagram.com/en_US/embeds.js

I had done this before and written about this before, in the post Fedora 23 workstation (Linux)+NVIDIA GeForce GTX 980 Ti: my experience, log of what I do (and find out).

Fix

I relied upon 2 webpages for the critical, almost life-saving, terminal commands to recover video output and the previous, working “good” kernel – they were such a life-saver that they’re worth repeating and I’ve saved a html copy of the 2 pages onto the MLgrabbag github repository:

See what video card is there and all kernels installed and present, respectively

lspci | grep VGA
lspci | grep -E "VGA|3D"
lspci | grep -i "VGA"

uname -a

Remove the offending kernel that was automatically installed by dnf install

Critical commands:

rpm -qa | grep ^kernel

uname -r

sudo yum remove kernel-core-4.7.9-100.fc23.x86_64 kernel-devel-4.7.9-100.fc23.x86_64 kernel-modules-4.7.9-100.fc23.x86_64 kernel-4.7.9-100.fc23.x86_64 kernel-headers-4.7.9-100.fc23.x86_64

Install NVidia drivers to, at least, recover video output

While at the terminal prompt (in low-resolution), change to the directory where you had downloaded the NVidia drivers (hopefully it’s there somewhere already on your hard drive because you wouldn’t have web browser capability without video output):

sudo sh ./NVIDIA-Linux-x86_64-361.42.run
reboot

dnf install gcc
dnf install dkms acpid
dnf install kernel-headers

echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf

cd /etc/sysconfig
grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg

dnf list xorg-x11-drv-nouveau

dnf remove xorg-x11-drv-nouveau
cd /boot

## Backup old initramfs nouveau image ##
mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r)-nouveau20161031.img

(the last command, with the output file name, the output file’s name is arbitrary)

## Create new initramfs image ##
dracut /boot/initramfs-$(uname -r).img $(uname -r)
systemctl set-default multi-user.target

At this point, you’ll notice that dnf update and its subsequent removal would’ve trashed your C++ setup.

cf. stackexchange: gcc: error trying to exec 'cc1': execvp: No such file or directory When compile program with popen in php

For at this point, I tried to do a make of a C++ project I had:

[topolo@localhost MacCor1d_gfx]$ make
/usr/local/cuda/bin/nvcc -std=c++11 -g -G -Xcompiler "-Wall -Wno-deprecated-declarations" -L/usr/local/cuda/samples/common/lib/linux/x86_64 -lglut -lGL -lGLU -dc main.cu -o main.o
gcc: error trying to exec 'cc1plus': execvp: No such file or directoryMakefile:21: recipe for target 'main.o' failedmake: *** [main.o] Error 1

So you’ll have to do

dnf install gcc-c++

Might as well, while we’re at it, update NVidia proprietary drivers and CUDA Toolkit

Updating the NVidia proprietary driver – similar to installing, but remember you have to go into the low-resolution, no video driver, terminal, command line, prompt

chmod +x NVIDIA-Linux-x86_64-367.57.run
systemctl set-default multi-user.target
reboot

./NVIDIA-Linux-x86_64-367.57.run
systemctl set-default graphical.target
reboot

Update to CUDA Toolkit (9.0)

Try  to use package manager on Linux distribution as much as possible (as general principle).

Remember to do Post-Installation Actions which must be done manually.  Usually, go to your bash profile, ~/.bashrc , and add the following environment variables:

LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH})

 

 

What I did was use emacs on ~/.bashrc and added these lines manually:
PATH=/usr/local/cuda-9.0/bin:$PATH

LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:/usr/lib/x86_64-linux-gpu

 

 

Updating CUDA Toolkit (8.0)

Download CUDA Toolkit (8.0)

Then follow the instructions. If the driver is updated already, before using the “.run” installation, then choose no to installing drivers – otherwise, I had chosen yes and the default for all the options.

The Linux installation guide for CUDA Toolkit 8.0 is actually very thorough, comprehensive, and easy to use. Let’s look at the Post-Installation Actions, the Environment Setup:

The PATH variable needs to include /usr/local/cuda-8.0/bin

To add this path to the PATH variable:

$ export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}

In addition, when using the runfile installation method, the LD_LIBRARY_PATH variable needs to contain /usr/local/cuda-8.0/lib64 on a 64-bit system, or /usr/local/cuda-8.0/lib on a 32-bit system

To change the environment variables for 64-bit operating systems:

$ export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64\
${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

Indeed, prior to adding the PATH variable, I was getting errors when I type nvcc at the command line. After doing this:

[propdev@localhost ~]$ export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}
[propdev@localhost ~]$ env | grep '^PATH'
PATH=/usr/local/cuda-8.0/bin:/home/propdev/anaconda2/bin:/home/propdev/anaconda2/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/propdev/.local/bin:/home/propdev/bin
[propdev@localhost ~]$ nvcc
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
nvcc fatal : No input files specified; use option --help for more information
[propdev@localhost ~]$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Sun_Sep__4_22:14:01_CDT_2016
Cuda compilation tools, release 8.0, V8.0.44

I obtain what I desired – I can use nvcc at the command line.

To get the samples that use OpenGL, be sure to have glut and/or freeglut installed:

dnf install freeglut freeglut-devel

Now for some bloody reason (please let me know), the command

$ export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64\
${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

still didn’t help me to allow my CUDA programs utilize the libraries in that lib64 subdirectory of the CUDA Toolkit. It seems like the programs, or the OS, wasn’t seeing the link that should be there in /usr/lib64.

What did work was in here, libcublas.so.7.0: cannot open shared object file, with the solution at the end, from
atv, with an answer originally from txbob (most likely Robert Cravello of github)

Solved. Finally I did:

sudo echo "/usr/local/cuda-7.0/lib64" > /etc/ld.so.conf.d/cuda.conf
sudo ldconfig

Thanks a lot txbob!

This is what I did:

[root@localhost ~]# sudo echo "/usr/local/cuda-8.0/lib64" > /etc/ld.so.conf.d/cuda.conf
[root@localhost ~]# sudo ldconfig
ldconfig: /usr/local/cuda-7.5/lib64/libcudnn.so.5 is not a symbolic link

and it worked; C++ programs compile with my make files.

Also, files, including in the Samples for the 8.0 Toolkit, using nvrtc compiled and worked.

Fun Nvidia video card version information, details

Doing

nvidia-smi

at the command prompt gave me this:

<br />[propdev@localhost ~]$ nvidia-smi
Mon Oct 31 15:28:30 2016
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 367.57 Driver Version: 367.57 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 980 Ti Off | 0000:03:00.0 On | N/A |
| 0% 50C P8 22W / 275W | 423MiB / 6077MiB | 1% Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 1349 G /usr/libexec/Xorg 50MiB |
| 0 19440 G /usr/libexec/Xorg 162MiB |
| 0 19645 G /usr/bin/gnome-shell 127MiB |
| 0 24621 G /usr/libexec/Xorg 6MiB |
+-----------------------------------------------------------------------------+

C++, C++11/C++14

Posts, notes, resources on C++, C++11/C++14.

Table of Contents

C++11 timing code execution

cf. Solarian programmer gave an excellent write up in C++11 timing code performance

C++11/14 version – the classic algorithm of binary search, using C++11/14 vector library

I implemented the classic algorithm of binary search using C++11/14 vector(s) (library) in vectors_binarysearch.cpp, inside the folder ../Cpp14 of my CompPhys github repository

functor

C++ Tutorial – Functors(Function Objects) – 2016

My implementation of the examples above for functors here on github:

functors.cpp

C++ templates, class templates and how to put them into header files; Useful links related to splitting up header files for declaration, split to .cpp files for definitions

While I already wrote about it in the README.md of my github repository folder Cpp, for CompPhysUseful links related to splitting up header files for declaration, split to .cpp files for definitions, github repo CompPhys, folder cpp, I had to look it up again, and so I’ll reiterate that material here.

, had an excellent article detailing how understandably confusing it is to split up templates to header files for C++.  The examples and options are comprehensive and crystal-clear.

Gives the reason why.

 

Texture Object API

struct cudaResourceDesc resDesc

struct myStruct myVariable;

struct Leopard leopard;
leopard.base.animal.weight = 44;

Struct declaration
http://en.cppreference.com/w/c/language/struct

Google search
struct inherit copy from another struct declare c c++

http://stackoverflow.com/questions/1114349/struct-inheritance-in-c

Typesafe inheritance in C
http://www.deleveld.dds.nl/inherit.htm

Difference between ‘struct’ and ‘typedef struct’ in C++?
http://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c

Google search
typedef struct

useful

typedef struct vs struct definitions [duplicate]
http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions

Google search terms

how to declare an instance of a struct C++

Proper way to initialize C++ structs

http://stackoverflow.com/questions/5914422/proper-way-to-initialize-c-structs

Abstract Algebra

I reviewed a little about rings and polynomial rings over this past weekend and I wanted to try to collect the resources I come across here. My aim for abstract algebra is to apply to (of course) topological field theory AND (unprecedentedly) to aerospace engineering, namely combustion CFD (computational fluid dynamics).

Cornell Math 4320 Solutions (probably more “around” this link

Using Sage Math for Abstract Algebra, especially in conjunction with jupyter notebooks, should be the way forward in the 21st century, and from there, digging deeper into various C/C++ libraries. The jupyter notebook I keep is in my qSApoly github repository:

https://github.com/ernestyalumni/qSApoly/blob/master/AbstractAlgebra.ipynb

Givaro – C++ library for arithmetic and algebraic computations

https://github.com/linbox-team/givaro

http://givaro.forge.imag.fr/

https://admin.fedoraproject.org/pkgdb/package/rpms/givaro/

Fedora package for givaro, givaro.

Electromagnetism

P.S. I just enabled Markdown for wordpress and so I’m giving wordpress another shot with Markdown, but otherwise, I find myself updating my github and writing there much more frequently because of their excellent and superior version control, terminal commands, and web interface, displaying automatically pdfs, markdown code, etc.

I was reviewing Electric propulsion which led me to review Electromagnetism, in view of differential geometry, and its covariant formulation.

All of Maxwell’s equations are contained in the following 2 statements:

$dF = 0$
$dF = 4\pi **J$ (cgs) or $dF = **J$ (SI).

Here is a reprint of my jupyter notebook on my github repository Propulsion (you’ll need Sage Math and sagemanifolds) EMsage.ipynb where I show with the Minkowski metric that you recover the usual form of Maxwell’s equations, and give the differential form formulation of the Lorentz Force. This is usually shown “by hand” in textbooks, but I show it with Sage Math and sagemanifolds (stop doing tedious calculations by hand!). I want to encourage people to try their own metric beyond the Minkowski metric and make calculations for Electromagnetism in different spacetimes.

Electromagnetism

Running Sage Math and sagemanifolds with jupyter notebooks tip: First, I’ve found that compiling from the github source the development Sage Math version (see my notes on this under the “Computers” section of my wordpress blog) works with sagemanifolds and either installing sagemanifolds into the binary that you unpack out (the click, download, double click), “breaks” Sage and so that it doesn’t run. Also, following the Sage Math instructions on their website for building from the source didn’t work for me (!!!???).

As a tip on how to run this jupyter notebook and have sagemanifolds available, you’d want to be in the working directory you desire (e.g. Propulsion/EM). But yet your Sage Math build is somewhere else (e.g. /home/topolo/Public/sage). Do this out of the working directory you’re currently working out of:
/home/topolo/Public/sage/sage -n jupyter

For the rationale, or the math, and how the math corresponds directly to the Sage Math code here, you’re going to want to look at Gravity_Notes_grande.pdf in my Gravite repository, and in there, the $\mathbb{R}^3$ section, because I define the charts and atlases for Euclidean space $\mathbb{R}^3$ as a smooth manifold.

M = Manifold(4,'M',r'M')
cart_ch = M.chart('t x y z')
U = M.open_subset('U',coord_def={cart_ch: (cart_ch[1]<0, cart_ch[2]!=0)})
cart_ch_U = cart_ch.restrict(U)
sph_ch = U.chart(r'tsp:(-oo,oo):t_{sp} rh:(0,+oo):\rho th:(0,pi):\theta ph:(0,2*pi):\phi')
tsph, rh,th,ph = [sph_ch[i[0]] for i in M.index_generator(1)]
transit_sph_to_cart = sph_ch.transition_map(cart_ch_U, 
                                            [tsph,rh*sin(th)*cos(ph),rh*sin(th)*sin(ph),rh*cos(th)])
Sphnorm = sqrt(sum([cart_ch_U[i]**2 for i in range(1,4)]))
transit_sph_to_cart.set_inverse( cart_ch[0], Sphnorm, 
                                atan2(sqrt( sum([ cart_ch_U[i]**2 for i in range(1,3)])),cart_ch_U[3]),
                                                            atan2(cart_ch_U[2],cart_ch_U[1]))
cyl_ch = U.chart(r'tcy:(-oo,oo):t_{cy} r:(0,+oo) phi:(0,2*pi):\phi zc')
tcy, r,phi,zc = [cyl_ch[i[0]] for i in M.index_generator(1)]
transit_cyl_to_cart = cyl_ch.transition_map(cart_ch_U, [tcy,r*cos(phi),r*sin(phi),zc])
transit_cyl_to_cart.set_inverse(cart_ch_U[0], sqrt(cart_ch_U[1]**2+cart_ch_U[2]**2), 
                                    atan2( cart_ch_U[2],cart_ch_U[1]), cart_ch_U[3])

Note the mostly positive (-+++) convention I use for the Minkowski metric.

g = M.riemannian_metric('g')
g[0,0] = -1 
for i in range(1,4): g[i,i] = 1

Electric Field

def make_E(ch):
    """
    make_E = make_E(ch)
    make_E creates a time-INDEPENDENT electric field as a 1-form

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    Ecomplst = []
    for i in range(1,4):
        Earglst = ['E'+str(i),] + list(ch[1:])
        Ecomplst.append( function(Earglst[0])(*Earglst[1:]) )
    Ecomplst = [0,]+Ecomplst
    E = ch.domain().diff_form(1)
    E[ch.frame(),:,ch] = Ecomplst
    return E

def make_Et(ch):
    """
    make_Et = make_Et(ch)
    make_Et creates a time-DEPENDENT electric field as a 1-form

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    Ecomplst = []
    for i in range(1,4):
        Earglst = ['E'+str(i),] + list(ch[:])
        Ecomplst.append( function(Earglst[0])(*Earglst[1:]) )
    Ecomplst = [0,]+Ecomplst
    E = ch.domain().diff_form(1)
    E[ch.frame(),:,ch] = Ecomplst
    return E

Examples of using make_E, make_Et and displaying the results

print make_E(cart_ch).display()
make_Et(sph_ch).display(sph_ch.frame(),sph_ch)
E1(x, y, z) dx + E2(x, y, z) dy + E3(x, y, z) dz





E1(tsp, rh, th, ph) drh + E2(tsp, rh, th, ph) dth + E3(tsp, rh, th, ph) dph

Magnetic Field

Programming note: make_B and make_Bt

import itertools
def make_B(ch):
    """
    make_B = make_B(ch)
    make_B creates a time-INDEPENDENT magnetic field as a 2-form

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    B = ch.domain().diff_form(2)
    farglst = list(ch[1:]) # function argument list, e.g. (x,y,z)

    B[ch.frame(),1,2,ch] = function('B_12')(*farglst)
    B[ch.frame(),2,3,ch] = function('B_23')(*farglst)
    B[ch.frame(),3,1,ch] = function('B_31')(*farglst)

    return B

def make_Bt(ch):
    """
    make_Bt = make_Bt(ch)
    make_Bt creates a time-DEPENDENT electric field as a 2-form

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    B = ch.domain().diff_form(2)
    farglst = list(ch[:]) # function argument list, e.g. (x,y,z)

    B[ch.frame(),1,2,ch] = function('B_12')(*farglst)
    B[ch.frame(),2,3,ch] = function('B_23')(*farglst)
    B[ch.frame(),3,1,ch] = function('B_31')(*farglst)

    return B
print make_Bt(cart_ch).display()
make_B(cyl_ch).display(cyl_ch.frame(),cyl_ch)
B_12(t, x, y, z) dx/\dy - B_31(t, x, y, z) dx/\dz + B_23(t, x, y, z) dy/\dz





B_12(r, phi, zc) dr/\dphi - B_31(r, phi, zc) dr/\dzc + B_23(r, phi, zc) dphi/\dzc

Notice that the orientation is correct (with the right hand rule).

Electromagnetic field 2-form

EM_F = make_Bt(cart_ch) + make_Et(cart_ch).wedge(cart_ch.coframe()[0] )
EM_F.display()
-E1(t, x, y, z) dt/\dx - E2(t, x, y, z) dt/\dy - E3(t, x, y, z) dt/\dz + B_12(t, x, y, z) dx/\dy - B_31(t, x, y, z) dx/\dz + B_23(t, x, y, z) dy/\dz
EM_F[:]
[                0   -E1(t, x, y, z)   -E2(t, x, y, z)   -E3(t, x, y, z)]
[   E1(t, x, y, z)                 0  B_12(t, x, y, z) -B_31(t, x, y, z)]
[   E2(t, x, y, z) -B_12(t, x, y, z)                 0  B_23(t, x, y, z)]
[   E3(t, x, y, z)  B_31(t, x, y, z) -B_23(t, x, y, z)                 0]
latex(EM_F.exterior_der()[:]); # delete the semi-colon ; and you can get the LaTeX code-I suppress it

$ dF = \left[\left[\left[0, 0, 0, 0\right], \left[0, 0, \frac{\partial\,B_{12}}{\partial {t}} – \frac{\partial\,E_{1}}{\partial y} + \frac{\partial\,E_{2}}{\partial x}, -\frac{\partial\,B_{31}}{\partial {t}} – \frac{\partial\,E_{1}}{\partial z} + \frac{\partial\,E_{3}}{\partial x}\right], \left[0, -\frac{\partial\,B_{12}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial y} – \frac{\partial\,E_{2}}{\partial x}, 0, \frac{\partial\,B_{23}}{\partial {t}} – \frac{\partial\,E_{2}}{\partial z} + \frac{\partial\,E_{3}}{\partial y}\right], \left[0, \frac{\partial\,B_{31}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial z} – \frac{\partial\,E_{3}}{\partial x}, -\frac{\partial\,B_{23}}{\partial {t}} + \frac{\partial\,E_{2}}{\partial z} – \frac{\partial\,E_{3}}{\partial y}, 0\right]\right], \left[\left[0, 0, -\frac{\partial\,B_{12}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial y} – \frac{\partial\,E_{2}}{\partial x}, \frac{\partial\,B_{31}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial z} – \frac{\partial\,E_{3}}{\partial x}\right], \left[0, 0, 0, 0\right], \left[\frac{\partial\,B_{12}}{\partial {t}} – \frac{\partial\,E_{1}}{\partial y} + \frac{\partial\,E_{2}}{\partial x}, 0, 0, \frac{\partial\,B_{12}}{\partial z} + \frac{\partial\,B_{23}}{\partial x} + \frac{\partial\,B_{31}}{\partial y}\right], \left[-\frac{\partial\,B_{31}}{\partial {t}} – \frac{\partial\,E_{1}}{\partial z} + \frac{\partial\,E_{3}}{\partial x}, 0, -\frac{\partial\,B_{12}}{\partial z} – \frac{\partial\,B_{23}}{\partial x} – \frac{\partial\,B_{31}}{\partial y}, 0\right]\right], \left[\left[0, \frac{\partial\,B_{12}}{\partial {t}} – \frac{\partial\,E_{1}}{\partial y} + \frac{\partial\,E_{2}}{\partial x}, 0, -\frac{\partial\,B_{23}}{\partial {t}} + \frac{\partial\,E_{2}}{\partial z} – \frac{\partial\,E_{3}}{\partial y}\right], \left[-\frac{\partial\,B_{12}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial y} – \frac{\partial\,E_{2}}{\partial x}, 0, 0, -\frac{\partial\,B_{12}}{\partial z} – \frac{\partial\,B_{23}}{\partial x} – \frac{\partial\,B_{31}}{\partial y}\right], \left[0, 0, 0, 0\right], \left[\frac{\partial\,B_{23}}{\partial {t}} – \frac{\partial\,E_{2}}{\partial z} + \frac{\partial\,E_{3}}{\partial y}, \frac{\partial\,B_{12}}{\partial z} + \frac{\partial\,B_{23}}{\partial x} + \frac{\partial\,B_{31}}{\partial y}, 0, 0\right]\right], \left[\left[0, -\frac{\partial\,B_{31}}{\partial {t}} – \frac{\partial\,E_{1}}{\partial z} + \frac{\partial\,E_{3}}{\partial x}, \frac{\partial\,B_{23}}{\partial {t}} – \frac{\partial\,E_{2}}{\partial z} + \frac{\partial\,E_{3}}{\partial y}, 0\right], \left[\frac{\partial\,B_{31}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial z} – \frac{\partial\,E_{3}}{\partial x}, 0, \frac{\partial\,B_{12}}{\partial z} + \frac{\partial\,B_{23}}{\partial x} + \frac{\partial\,B_{31}}{\partial y}, 0\right], \left[-\frac{\partial\,B_{23}}{\partial {t}} + \frac{\partial\,E_{2}}{\partial z} – \frac{\partial\,E_{3}}{\partial y}, -\frac{\partial\,B_{12}}{\partial z} – \frac{\partial\,B_{23}}{\partial x} – \frac{\partial\,B_{31}}{\partial y}, 0, 0\right], \left[0, 0, 0, 0\right]\right]\right] = 0 $

EM_F.hodge_dual(g)[:]
[                  0  I*B_23(t, x, y, z)  I*B_31(t, x, y, z)  I*B_12(t, x, y, z)]
[-I*B_23(t, x, y, z)                   0    I*E3(t, x, y, z)   -I*E2(t, x, y, z)]
[-I*B_31(t, x, y, z)   -I*E3(t, x, y, z)                   0    I*E1(t, x, y, z)]
[-I*B_12(t, x, y, z)    I*E2(t, x, y, z)   -I*E1(t, x, y, z)                   0]
g[:]
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0  1  0]
[ 0  0  0  1]

$dF$ (for $dF = 4 \pi * J$)

EM_F.hodge_dual(g).exterior_der()[:]
[[[0, 0, 0, 0],
  [0,
   0,
   I*d(B_23)/dy - I*d(B_31)/dx + I*d(E3)/dt,
   -I*d(B_12)/dx + I*d(B_23)/dz - I*d(E2)/dt],
  [0,
   -I*d(B_23)/dy + I*d(B_31)/dx - I*d(E3)/dt,
   0,
   -I*d(B_12)/dy + I*d(B_31)/dz + I*d(E1)/dt],
  [0,
   I*d(B_12)/dx - I*d(B_23)/dz + I*d(E2)/dt,
   I*d(B_12)/dy - I*d(B_31)/dz - I*d(E1)/dt,
   0]],
 [[0,
   0,
   -I*d(B_23)/dy + I*d(B_31)/dx - I*d(E3)/dt,
   I*d(B_12)/dx - I*d(B_23)/dz + I*d(E2)/dt],
  [0, 0, 0, 0],
  [I*d(B_23)/dy - I*d(B_31)/dx + I*d(E3)/dt,
   0,
   0,
   I*d(E1)/dx + I*d(E2)/dy + I*d(E3)/dz],
  [-I*d(B_12)/dx + I*d(B_23)/dz - I*d(E2)/dt,
   0,
   -I*d(E1)/dx - I*d(E2)/dy - I*d(E3)/dz,
   0]],
 [[0,
   I*d(B_23)/dy - I*d(B_31)/dx + I*d(E3)/dt,
   0,
   I*d(B_12)/dy - I*d(B_31)/dz - I*d(E1)/dt],
  [-I*d(B_23)/dy + I*d(B_31)/dx - I*d(E3)/dt,
   0,
   0,
   -I*d(E1)/dx - I*d(E2)/dy - I*d(E3)/dz],
  [0, 0, 0, 0],
  [-I*d(B_12)/dy + I*d(B_31)/dz + I*d(E1)/dt,
   I*d(E1)/dx + I*d(E2)/dy + I*d(E3)/dz,
   0,
   0]],
 [[0,
   -I*d(B_12)/dx + I*d(B_23)/dz - I*d(E2)/dt,
   -I*d(B_12)/dy + I*d(B_31)/dz + I*d(E1)/dt,
   0],
  [I*d(B_12)/dx - I*d(B_23)/dz + I*d(E2)/dt,
   0,
   I*d(E1)/dx + I*d(E2)/dy + I*d(E3)/dz,
   0],
  [I*d(B_12)/dy - I*d(B_31)/dz - I*d(E1)/dt,
   -I*d(E1)/dx - I*d(E2)/dy - I*d(E3)/dz,
   0,
   0],
  [0, 0, 0, 0]]]
latex( EM_F.hodge_dual(g).exterior_der()[:] ); # delete the semi-colon ; and you can get the LaTeX code-I suppress it

$\left[\left[\left[0, 0, 0, 0\right], \left[0, 0, i \, \frac{\partial\,B_{23}}{\partial y} – i \, \frac{\partial\,B_{31}}{\partial x} + i \, \frac{\partial\,E_{3}}{\partial {t}}, -i \, \frac{\partial\,B_{12}}{\partial x} + i \, \frac{\partial\,B_{23}}{\partial z} – i \, \frac{\partial\,E_{2}}{\partial {t}}\right], \left[0, -i \, \frac{\partial\,B_{23}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial x} – i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, -i \, \frac{\partial\,B_{12}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial z} + i \, \frac{\partial\,E_{1}}{\partial {t}}\right], \left[0, i \, \frac{\partial\,B_{12}}{\partial x} – i \, \frac{\partial\,B_{23}}{\partial z} + i \, \frac{\partial\,E_{2}}{\partial {t}}, i \, \frac{\partial\,B_{12}}{\partial y} – i \, \frac{\partial\,B_{31}}{\partial z} – i \, \frac{\partial\,E_{1}}{\partial {t}}, 0\right]\right], \left[\left[0, 0, -i \, \frac{\partial\,B_{23}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial x} – i \, \frac{\partial\,E_{3}}{\partial {t}}, i \, \frac{\partial\,B_{12}}{\partial x} – i \, \frac{\partial\,B_{23}}{\partial z} + i \, \frac{\partial\,E_{2}}{\partial {t}}\right], \left[0, 0, 0, 0\right], \left[i \, \frac{\partial\,B_{23}}{\partial y} – i \, \frac{\partial\,B_{31}}{\partial x} + i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, 0, i \, \frac{\partial\,E_{1}}{\partial x} + i \, \frac{\partial\,E_{2}}{\partial y} + i \, \frac{\partial\,E_{3}}{\partial z}\right], \left[-i \, \frac{\partial\,B_{12}}{\partial x} + i \, \frac{\partial\,B_{23}}{\partial z} – i \, \frac{\partial\,E_{2}}{\partial {t}}, 0, -i \, \frac{\partial\,E_{1}}{\partial x} – i \, \frac{\partial\,E_{2}}{\partial y} – i \, \frac{\partial\,E_{3}}{\partial z}, 0\right]\right], \left[\left[0, i \, \frac{\partial\,B_{23}}{\partial y} – i \, \frac{\partial\,B_{31}}{\partial x} + i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, i \, \frac{\partial\,B_{12}}{\partial y} – i \, \frac{\partial\,B_{31}}{\partial z} – i \, \frac{\partial\,E_{1}}{\partial {t}}\right], \left[-i \, \frac{\partial\,B_{23}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial x} – i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, 0, -i \, \frac{\partial\,E_{1}}{\partial x} – i \, \frac{\partial\,E_{2}}{\partial y} – i \, \frac{\partial\,E_{3}}{\partial z}\right], \left[0, 0, 0, 0\right], \left[-i \, \frac{\partial\,B_{12}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial z} + i \, \frac{\partial\,E_{1}}{\partial {t}}, i \, \frac{\partial\,E_{1}}{\partial x} + i \, \frac{\partial\,E_{2}}{\partial y} + i \, \frac{\partial\,E_{3}}{\partial z}, 0, 0\right]\right], \left[\left[0, -i \, \frac{\partial\,B_{12}}{\partial x} + i \, \frac{\partial\,B_{23}}{\partial z} – i \, \frac{\partial\,E_{2}}{\partial {t}}, -i \, \frac{\partial\,B_{12}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial z} + i \, \frac{\partial\,E_{1}}{\partial {t}}, 0\right], \left[i \, \frac{\partial\,B_{12}}{\partial x} – i \, \frac{\partial\,B_{23}}{\partial z} + i \, \frac{\partial\,E_{2}}{\partial {t}}, 0, i \, \frac{\partial\,E_{1}}{\partial x} + i \, \frac{\partial\,E_{2}}{\partial y} + i \, \frac{\partial\,E_{3}}{\partial z}, 0\right], \left[i \, \frac{\partial\,B_{12}}{\partial y} – i \, \frac{\partial\,B_{31}}{\partial z} – i \, \frac{\partial\,E_{1}}{\partial {t}}, -i \, \frac{\partial\,E_{1}}{\partial x} – i \, \frac{\partial\,E_{2}}{\partial y} – i \, \frac{\partial\,E_{3}}{\partial z}, 0, 0\right], \left[0, 0, 0, 0\right]\right]\right]$

EM_F.hodge_dual(g).exterior_der().hodge_dual(g)[:] 
[d(E1)/dx + d(E2)/dy + d(E3)/dz,
 -d(B_12)/dy + d(B_31)/dz + d(E1)/dt,
 d(B_12)/dx - d(B_23)/dz + d(E2)/dt,
 d(B_23)/dy - d(B_31)/dx + d(E3)/dt]
latex(EM_F.hodge_dual(g).exterior_der().hodge_dual(g)[:]); 
# delete the semi-colon ; and you can get the LaTeX code-I suppress it
\left[\frac{\partial\,E_{1}}{\partial x} + \frac{\partial\,E_{2}}{\partial y} + \frac{\partial\,E_{3}}{\partial z}, -\frac{\partial\,B_{12}}{\partial y} + \frac{\partial\,B_{31}}{\partial z} + \frac{\partial\,E_{1}}{\partial {t}}, \frac{\partial\,B_{12}}{\partial x} - \frac{\partial\,B_{23}}{\partial z} + \frac{\partial\,E_{2}}{\partial {t}}, \frac{\partial\,B_{23}}{\partial y} - \frac{\partial\,B_{31}}{\partial x} + \frac{\partial\,E_{3}}{\partial {t}}\right]

$\left[\frac{\partial\,E_{1}}{\partial x} + \frac{\partial\,E_{2}}{\partial y} + \frac{\partial\,E_{3}}{\partial z}, -\frac{\partial\,B_{12}}{\partial y} + \frac{\partial\,B_{31}}{\partial z} + \frac{\partial\,E_{1}}{\partial {t}}, \frac{\partial\,B_{12}}{\partial x} – \frac{\partial\,B_{23}}{\partial z} + \frac{\partial\,E_{2}}{\partial {t}}, \frac{\partial\,B_{23}}{\partial y} – \frac{\partial\,B_{31}}{\partial x} + \frac{\partial\,E_{3}}{\partial {t}}\right]$

Current 1-form, Current conservation, and the other side (Right-Hand Side (RHS)) of $d*F$

def make_J(ch):
    """
    make_J = make_J(ch)
    make_J creates a time-INDEPENDENT current as a 1-form

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    Jcomplst = []
    for i in range(1,4):
        Jarglst = ['j'+str(i),] + list(ch[1:])
        Jcomplst.append( function(Jarglst[0])(*Jarglst[1:]) )
    Jcomplst = [-function('rho')(*list(ch[1:])),] +Jcomplst
    J = ch.domain().diff_form(1)
    J[ch.frame(),:,ch] = Jcomplst
    return J


def make_Jt(ch):
    """
    make_Jt = make_Jt(ch)
    make_Jt creates a time-DEPENDENT current as a 1-form

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    Jcomplst = []
    for i in range(1,4):
        Jarglst = ['j'+str(i),] + list(ch[:])
        Jcomplst.append( function(Jarglst[0])(*Jarglst[1:]) )
    Jcomplst = [-function('rho')(*list(ch[:])),]+Jcomplst
    J = ch.domain().diff_form(1)
    J[ch.frame(),:,ch] = Jcomplst
    return J

print make_Jt(cart_ch).display() # these are examples of displaying the 4-current as 1-form in 
                                    # Cartesian and cylindrical coordinates
make_Jt(cyl_ch).display(cyl_ch.frame(),cyl_ch)
-rho(t, x, y, z) dt + j1(t, x, y, z) dx + j2(t, x, y, z) dy + j3(t, x, y, z) dz





-rho(tcy, r, phi, zc) dtcy + j1(tcy, r, phi, zc) dr + j2(tcy, r, phi, zc) dphi + j3(tcy, r, phi, zc) dzc
make_Jt(cart_ch).hodge_dual(g).hodge_dual(g).display()
rho(t, x, y, z) dt - j1(t, x, y, z) dx - j2(t, x, y, z) dy - j3(t, x, y, z) dz

So here, I had successfully shown that $dF = **J$ or $dF = 4\pi ** J$ (in cgs units), thus recovering Gauss’s law and Ampere’s law.

latex( make_Jt(cart_ch).hodge_dual(g).hodge_dual(g)[:]);
# delete the semi-colon ; and you can get the LaTeX code-I suppress it

$\boxed{ \left[\frac{\partial\,E_{1}}{\partial x} + \frac{\partial\,E_{2}}{\partial y} + \frac{\partial\,E_{3}}{\partial z}, -\frac{\partial\,B_{12}}{\partial y} + \frac{\partial\,B_{31}}{\partial z} + \frac{\partial\,E_{1}}{\partial {t}}, \frac{\partial\,B_{12}}{\partial x} – \frac{\partial\,B_{23}}{\partial z} + \frac{\partial\,E_{2}}{\partial {t}}, \frac{\partial\,B_{23}}{\partial y} – \frac{\partial\,B_{31}}{\partial x} + \frac{\partial\,E_{3}}{\partial {t}}\right] = \left[\rho\left({t}, x, y, z\right), -j_{1}\left({t}, x, y, z\right), -j_{2}\left({t}, x, y, z\right), -j_{3}\left({t}, x, y, z\right)\right] }$

Current conservation is easily calculated, $dJ=0$:

make_Jt(cart_ch).hodge_dual(g).exterior_der().hodge_dual(g).display(cart_ch)
M --&gt; R
(t, x, y, z) |--&gt; d(j1)/dx + d(j2)/dy + d(j3)/dz + d(rho)/dt

Lorentz Force

def make_beta(ch):
    """
    make_beta = make_beta(ch)
    make_beta creates a time-INDEPENDENT velocity field

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    betacomplst = []
    for i in range(1,4):
        betaarglst = ['beta'+str(i),] + list(ch[1:])
        betacomplst.append( function(betaarglst[0])(*betaarglst[1:]) )
    betacomplst = [1,]+betacomplst
    beta = ch.domain().vector_field()
    beta[ch.frame(),:,ch] = betacomplst
    return beta

def make_betat(ch):
    """
    make_betat = make_betat(ch)
    make_betat creates a time-DEPENDENT velocity field

    INPUT/PARAMETER
    ch = sagemanifold chart
    """
    betacomplst = []
    for i in range(1,4):
        betaarglst = ['beta'+str(i),] + list(ch[:])
        betacomplst.append( function(betaarglst[0])(*betaarglst[1:]) )
    betacomplst = [1,]+betacomplst
    beta = ch.domain().vector_field()
    beta[ch.frame(),:,ch] = betacomplst
    return beta
make_beta(cart_ch).display()
d/dt + beta1(x, y, z) d/dx + beta2(x, y, z) d/dy + beta3(x, y, z) d/dz

For interior products, you’re going to have to dig into how sagemanifolds implements Tensor products, tensor contractions, and the use of index notation, as sagemanifolds doesn’t have a “stand-alone” interior product function. From my EuclideanManifold.py implementation in sagemanifolds, look at my curl function (def curl) as a template for implementing interior products.

betaeg = make_betat(cart_ch)
Beg = make_Bt(cart_ch)
(betaeg['^i']*Beg['_ij']).display()
(-B_12(t, x, y, z)*beta2(t, x, y, z) + B_31(t, x, y, z)*beta3(t, x, y, z)) dx + (B_12(t, x, y, z)*beta1(t, x, y, z) - B_23(t, x, y, z)*beta3(t, x, y, z)) dy + (-B_31(t, x, y, z)*beta1(t, x, y, z) + B_23(t, x, y, z)*beta2(t, x, y, z)) dz

So we now have a prescription on how to implement both the interior product and the curl of 2 “vectors” –
if you want this:

$-i_{\mathbf{\beta}} B$ which is the differential form version of $\mathbf{\beta} \times B$ (curl), then do this in sagemanifolds:

-betaeg['^i']*Beg['_ij']

q = var('q',"real") # define a single charge variable in Sage Math
LorentzForce1form =  make_Et(cart_ch) - make_beta(cart_ch)['^i']*make_Bt(cart_ch)['_ij']

EY : 20160530 I have a question; is there a good way for Sage Math variables such as q in this case (var) to “play with” sagemanifolds tensors? For instance, I obtain this when I multiply a sagemanifolds 1-form by a Sage Math variable (var) q:

q * LorentzForce1form
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

 in ()
----&gt; 1 q * LorentzForce1form


/home/topolo/Public/sage/src/sage/structure/element.pyx in sage.structure.element.ModuleElement.__mul__ (/home/topolo/Public/sage/src/build/cythonized/sage/structure/element.c:12191)()
   1369         if have_same_parent_c(left, right):
   1370             raise TypeError(arith_error_message(left, right, mul))
-&gt; 1371         return coercion_model.bin_op(left, right, mul)
   1372 
   1373     def __imul__(left, right):


/home/topolo/Public/sage/src/sage/structure/coerce.pyx in sage.structure.coerce.CoercionModel_cache_maps.bin_op (/home/topolo/Public/sage/src/build/cythonized/sage/structure/coerce.c:9915)()
   1077         # We should really include the underlying error.
   1078         # This causes so much headache.
-&gt; 1079         raise TypeError(arith_error_message(x,y,op))
   1080 
   1081     cpdef canonical_coercion(self, x, y):


TypeError: unsupported operand parent(s) for '*': '' and 'Free module /\^1(M) of 1-forms on the 4-dimensional differentiable manifold M'
5.*LorentzForce1form
1-form on the 4-dimensional differentiable manifold M

Nevertheless, for $q=1$, then the 1-form version of the Lorentz Force $F$ is given by the following, and keep in mind that we integrate 1-forms, we don’t integrate vectors (because it goes back to how we transport vectors along a curve, and 1-forms either abscond, circumvent, this problem or is the most natural way to do integration on manifolds):

latex( LorentzForce1form.display() );

$F = \left( B_{12}\left({t}, x, y, z\right) \beta_{2}\left(x, y, z\right) – B_{31}\left({t}, x, y, z\right) \beta_{3}\left(x, y, z\right) + E_{1}\left({t}, x, y, z\right) \right) \mathrm{d} x + \left( -B_{12}\left({t}, x, y, z\right) \beta_{1}\left(x, y, z\right) + B_{23}\left({t}, x, y, z\right) \beta_{3}\left(x, y, z\right) + E_{2}\left({t}, x, y, z\right) \right) \mathrm{d} y + \left( B_{31}\left({t}, x, y, z\right) \beta_{1}\left(x, y, z\right) – B_{23}\left({t}, x, y, z\right) \beta_{2}\left(x, y, z\right) + E_{3}\left({t}, x, y, z\right) \right) \mathrm{d} z$

<br />