I wanted to find a numerical library that could solve a system of partial differential equations (PDEs) and would support automatic creation of a mesh. My other requirement was to be able to create my application under my favorite MIT license, so GPL libraries were out of question. There are many FEM libraries, however most of them are either GPL, have GPL dependencies (like UMFPACK in latest releases), don’t have automatic mesh creation or are not mature enough. After searching for a while I decided on getfem++, which looked like a promising LGPL library that would suit my needs.
getfem++ is a finite element library, which might be useful if you want to numerically solve a system of PDEs. It uses LAPACK and BLAS libraries for matrix/vector operations, gmm++ library for solving linear systems defined by sparse matrices, optionally Qhull library for automatic mesh creation and optionally muparser library for parsing mathematical expressions (like function determining Dirichlet boundary condition). Licenses were okay – BSD/MIT/BSD-ish for LAPACK, BLAS, Qhull and muparser and LGPL for getfem++ and gmm++.
Everything was great until I actually tried to compile this set on MinGW and make a shared library out of it. Results of my work can be found in my getfem++ bitbucket repository. If you’re not interested in compilation and just want to use this library with MinGW, you can stop reading here.
Let me note that I was doing the compilation on Windows 7 with GNUStep’s mingw32 with g++ 4.6.1.
First dependencies. I downloaded precompiled win32 LAPACK 3.4.1 and BLAS dynamic libraries for mingw32 from here. I’d like to mention that LAPACK and BLAS libraries need two basic libraries to run – libgfortran and libquadmath.
Next one was muparser 2.2.3. While it did build dynamically, for some reason compiled dynamic library didn’t work with getfem++. So I decided to go with custom static muparser library build (it’s on MIT license, so it’s okay). At this point of time I’m not even sure if customizing the build was required, but it worked.
After unzipping sources I built a dynamic library:
cd build mingw32-make -f makefile.mingw SHARED=1
That made files being built with appropriate flags for dynamic library. Then I created the static library myself from produced files:
cd build/obj/gcc_shared_rel ar cru libmuparser.a muParser*.o ranlib libmuparser.a
Last dependency is Qhull 2012.1. I didn’t build the library, I just copied qhull.dll from bin/ folder from its package. I took headers them from src/libqhull/*.h. The problem was that getfem++ required qhull.h header, but it was named libqhull.h in Qhull. So I renamed it to qhull.h and changed #include’s in other headers to look for qhull.h. I also tried building Qhull static library, but for some reason it didn’t work well with getfem++.
Last task was to build getfem++ 4.2 library. It required quite a bit of tweaking in exports and experimenting with builds of its dependencies to make it work. Exports I used in my msys console (put to .profile) were:
export CPPFLAGS="-L/home/Xilexio/lib -I/home/Xilexio/include" export CXXFLAGS="$CPPFLAGS" LDFLAGS="-L/home/Xilexio/lib" export LD_LIBRARY_PATH="/home/Xilexio/lib:$LD_LIBRARY_PATH" export LIBRARY_PATH="C:/GNUstep/msys/1.0/home/Xilexio/lib;$LIBRARY_PATH"
Where /home/Xilexio/lib contained all previously built libraries and /home/Xilexio/include contained all headers (note: Qhull headers were supposed to be in qhull subdirectory). Those exports allowed both proper compilation and finding libraries by executables. Later I compiled the getfem++ itself with:
./configure --enable-qhull --enable-muparser --enable-shared --prefix="/home/xilexio/getfem" && make && make install
That created static getfem++ library. Next, I created a shared version of the library. I did it by simply taking libgetfem.a static library from install directory, extracting all its contents (.o files) and combining them back together, this time into a dynamic library:
ar x libgetfem.a g++ -shared -fPIC -Wl,--enable-auto-import -Wl,-no-undefined -Wl,--enable-runtime-pseudo-reloc -Wl,--out-implib,libgetfem_dll.a -o getfem.dll $CPPFLAGS *.o -lblas -llapack -lqhull -lmuparser
Done. This library worked for me.
But still, I wanted to check if getfem++ tests were passing. Because they were compiling test applications directly with src/.libs/libgetfem.a static library, I had to trick this build process by copying getfem.dll to src/.libs/libgetfem.a. In the end g++ somehow understood that it was a dynamic library and linked properly with it. Application didn’t work without getfem.dll in its location, so I guess dynamic linking was done properly. That change made tests build, but one of tests failed – test_large_sliding_contact.cc. It worked after removing one of asserts:
GMM_ASSERT1(err < 4e-6, "Erroneous gradient of normal vector "); I think something might have gone wrong with computations in this test, because I didn't compile this library with QD (high precision floats library). By the way, I couldn't find a version of QD that would work on Windows. Warning: getfem++'s user documentation states that we should have built a static library, so this is not a normal build. There is also no problem in using static getfem++ library version with non-GPL programs, because of getfem++ uses GCC Runtime Library Exception.