add C function for FFHS integration

This commit is contained in:
Dominik Demuth 2023-04-10 19:33:23 +02:00
parent 3b79c571fb
commit ead30d127a
4 changed files with 57 additions and 13 deletions

View File

@ -2,37 +2,37 @@
#binaries #binaries
PYUIC = pyuic5 PYUIC = pyuic5
PYRCC = pyrcc5 # PYRCC = pyrcc5
CC = gcc
CFLAGS = -O2 -fPIC
LDFLAGs = -shared
#Directory with ui files #Directory with ui files
RESOURCE_DIR = resources/_ui RESOURCE_DIR = src/resources/_ui
#Directory for compiled resources #Directory for compiled resources
COMPILED_DIR = nmreval/gui_qt/_py PYQT_DIR = src/gui_qt/_py
#UI files to compile, uses every *.ui found in RESOURCE_DIR #UI files to compile, uses every *.ui found in RESOURCE_DIR
UI_FILES = $(foreach dir, $(RESOURCE_DIR), $(notdir $(wildcard $(dir)/*.ui))) UI_FILES = $(foreach dir, $(RESOURCE_DIR), $(notdir $(wildcard $(dir)/*.ui)))
COMPILED_UI = $(UI_FILES:%.ui=$(COMPILED_DIR)/%.py) PYQT_UI = $(UI_FILES:%.ui=$(PYQT_DIR)/%.py)
SVG_FILES = $(foreach dir, $(RCC_DIR), $(notdir $(wildcard $(dir)/*.svg))) SVG_FILES = $(foreach dir, $(RCC_DIR), $(notdir $(wildcard $(dir)/*.svg)))
PNG_FILES = $(SVG_FILES:%.svg=$(RCC_DIR)/%.png) PNG_FILES = $(SVG_FILES:%.svg=$(RCC_DIR)/%.png)
all : ui all : ui
ui : $(COMPILED_UI) ui : $(PYQT_UI)
rcc: $(PNG_FILES) rcc: $(PNG_FILES)
$(COMPILED_DIR)/%.py : $(RESOURCE_DIR)/%.ui $(COMPILED_DIR)/%.py : $(RESOURCE_DIR)/%.ui
$(PYUIC) $< -o $@ $(PYUIC) $< -o $@
# replace import of ressource to correct path
# @sed -i s/images_rc/nmrevalqt.$(COMPILED_DIR).images_rc/g $@
# @sed -i /images_rc/d $@
$(RCC_DIR)/%.png : $(RCC_DIR)/%.svg $(RCC_DIR)/%.png : $(RCC_DIR)/%.svg
convert -background none $< $@ convert -background none $< $@
$(PYRCC) $(RCC_DIR)/images.qrc -o $(COMPILED_DIR)/images_rc.py
clean: clean:
find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyc' -exec rm -f {} +

View File

@ -0,0 +1,15 @@
/* integrands used in quadrature integration with scipy's LowLevelCallables */
/* integrand for distributions/intermolecular/FFHS */
double ffhs_sd(double x, void *user_data) {
double *c = (double *)user_data;
double tau = c[1];
double omega = c[0];
double u = x*x;
double res = u*u * c[1];
res /= 81. + 9.*u - 2.*u*u + u*u*u;
res /= u*u + omega*omega * tau*tau;
return res;
}

View File

@ -1,8 +1,24 @@
import ctypes
import os.path
from pathlib import Path
import numpy as np import numpy as np
from scipy import LowLevelCallable
from scipy.integrate import quad from scipy.integrate import quad
from .base import Distribution from .base import Distribution
try:
print(str(Path(__file__).parents[1] / 'clib' / 'integrate.so'))
lib = ctypes.CDLL(str(Path(__file__).parents[1] / 'clib' / 'integrate.so'))
lib.ffhs_sd.restype = ctypes.c_double
lib.ffhs_sd.argtypes = (ctypes.c_double, ctypes.c_void_p)
HAS_C_FUNCS = True
print('Use C functions')
except OSError:
HAS_C_FUNCS = False
print('Use python functions')
class FFHS(Distribution): class FFHS(Distribution):
name = 'Intermolecular (FFHS)' name = 'Intermolecular (FFHS)'
@ -24,7 +40,7 @@ class FFHS(Distribution):
return ret_val return ret_val
@staticmethod @staticmethod
def specdens(omega, tau0, *args): def specdens_py(omega, tau0, *args):
def integrand(u, o, tau0): def integrand(u, o, tau0):
return u**4 * tau0 / (81 + 9*u**2 - 2*u**4 + u**6) / (u**4 + (o*tau0)**2) return u**4 * tau0 / (81 + 9*u**2 - 2*u**4 + u**6) / (u**4 + (o*tau0)**2)
# return FFHS.distribution(u, tau0) * u / (1+o**2 * u**2) # return FFHS.distribution(u, tau0) * u / (1+o**2 * u**2)
@ -33,6 +49,17 @@ class FFHS(Distribution):
return ret_val * 54 / np.pi return ret_val * 54 / np.pi
@staticmethod
def specdens_c(omega, tau0, *args):
res = []
for o in omega:
c = (ctypes.c_double * 2)(o, tau0)
user_data = ctypes.cast(ctypes.pointer(c), ctypes.c_void_p)
func = LowLevelCallable(lib.ffhs_sd, user_data)
res.append(quad(func, 0, np.infty)[0])
return np.array(res) * 54 / np.pi
@staticmethod @staticmethod
def susceptibility(omega, tau0, *args): def susceptibility(omega, tau0, *args):
def integrand_real(u, o, tau0): def integrand_real(u, o, tau0):
@ -48,6 +75,9 @@ class FFHS(Distribution):
return ret_val return ret_val
FFHS.specdens = FFHS.specdens_c if HAS_C_FUNCS else FFHS.specdens_py
# class Bessel(Distribution): # class Bessel(Distribution):
# name = 'Intermolecular (Bessel)' # name = 'Intermolecular (Bessel)'
# parameter = None # parameter = None

View File

@ -1,4 +1,3 @@
import time
import warnings import warnings
from itertools import product from itertools import product