From a4199521d066a517ca3c660255723f636235866f Mon Sep 17 00:00:00 2001 From: AntoineSIMTEK Date: Tue, 20 Oct 2020 13:29:08 +0200 Subject: [PATCH 01/10] WIP: template for electrostatic calculations --- Adhesion/Interactions/Electrostatic.py | 55 +++++++++++++++++++++++++ test/Interactions/test_electrostatic.py | 2 + 2 files changed, 57 insertions(+) create mode 100644 Adhesion/Interactions/Electrostatic.py create mode 100644 test/Interactions/test_electrostatic.py diff --git a/Adhesion/Interactions/Electrostatic.py b/Adhesion/Interactions/Electrostatic.py new file mode 100644 index 00000000..d9fe3560 --- /dev/null +++ b/Adhesion/Interactions/Electrostatic.py @@ -0,0 +1,55 @@ +from Adhesion.Interactions import Potential +from NuMPI import MPI + + +def ChargePatternsInteraction(Potential): + """ + Potential for the interaction of charges + + Please cite: + Persson, B. N. J. et al. EPL 103, 36003 (2013) + """ + + def __init__(self, + charge_distribution, + physical_sizes, + dielectric_constant_material=1., + dielectric_constant_gap=1., + communicator=MPI.COMM_WORLD): + """ + + Parameters + ---------- + charge_distribution: float ndarray + spatial distribution + physical_sizes: tuple + + dielectric_constant_material: float + dielectric_constant_gap: float + + Returns + ------- + + """ + Potential.__init__(self, communicator=communicator) + self.nb_grid_points = charge_distribution.shape + + def evaluate(gap, ): + """ + + Parameters + ---------- + gap: array_like + + Returns + ------- + + potential: float + + gradient: ndarray + first derivative of the potential wrt. gap (= - forces by pixel) + curvature: ndarray or linear operator (callable) + second derivative of the potential + # TODO: is that easy/possible/computationally tractable ? + """ + pass \ No newline at end of file diff --git a/test/Interactions/test_electrostatic.py b/test/Interactions/test_electrostatic.py new file mode 100644 index 00000000..867e4a13 --- /dev/null +++ b/test/Interactions/test_electrostatic.py @@ -0,0 +1,2 @@ +def test_sinewave(): + pass From 694c9b80052f55a572ad6a3d11d948f734f5fa6c Mon Sep 17 00:00:00 2001 From: yzuuang Date: Tue, 10 Nov 2020 17:19:36 +0100 Subject: [PATCH 02/10] WIP --- Adhesion/Interactions/Electrostatic.py | 121 ++++++++++++++++++++++-- test/Interactions/test_electrostatic.py | 80 +++++++++++++++- 2 files changed, 192 insertions(+), 9 deletions(-) diff --git a/Adhesion/Interactions/Electrostatic.py b/Adhesion/Interactions/Electrostatic.py index d9fe3560..36abf2aa 100644 --- a/Adhesion/Interactions/Electrostatic.py +++ b/Adhesion/Interactions/Electrostatic.py @@ -1,8 +1,8 @@ from Adhesion.Interactions import Potential from NuMPI import MPI +import numpy as np - -def ChargePatternsInteraction(Potential): +class ChargePatternsInteraction(Potential): """ Potential for the interaction of charges @@ -15,6 +15,7 @@ def __init__(self, physical_sizes, dielectric_constant_material=1., dielectric_constant_gap=1., + pixel_sizes=(1e-9,1e-9), communicator=MPI.COMM_WORLD): """ @@ -23,18 +24,41 @@ def __init__(self, charge_distribution: float ndarray spatial distribution physical_sizes: tuple - + length and width of the plate dielectric_constant_material: float dielectric_constant_gap: float + pixel_sizes: tuple float Returns ------- """ + assert np.ndim(charge_distribution) == 2 + self.charge_distribution = charge_distribution + self.physical_sizes = physical_sizes + epsilon0 = 8.854e-12 # [C/m^2], permittivity in vacuum + self.epsilon_material = dielectric_constant_material * epsilon0 + self.epsilon_gap = dielectric_constant_gap * epsilon0 + self.pixel_area = np.prod(pixel_sizes) Potential.__init__(self, communicator=communicator) - self.nb_grid_points = charge_distribution.shape + self.num_grid_points = charge_distribution.shape + + @property + def r_min(self): + return None + + @property + def r_infl(self): + return None + + def __repr__(self, ): + return ("Potential '{0.name}': ε = {0.eps}, σ = {0.sig}").format(self) - def evaluate(gap, ): + def evaluate(self, + gap, + potential=True, + gradient=False, + curvature=False): """ Parameters @@ -44,7 +68,7 @@ def evaluate(gap, ): Returns ------- - potential: float + potential: float ndarray gradient: ndarray first derivative of the potential wrt. gap (= - forces by pixel) @@ -52,4 +76,87 @@ def evaluate(gap, ): second derivative of the potential # TODO: is that easy/possible/computationally tractable ? """ - pass \ No newline at end of file + assert np.ndim(gap) == 1 # unit[m] + + # fast Fourier transform, σ(x1, x2) -> σ(q1, q2) + fft_charge_distribution = np.fft.fft2(self.charge_distribution, + s=self.num_grid_points) + fft_magnitude = np.abs(fft_charge_distribution) * self.pixel_area + # According to sampling theory, the magnitude after discretization + # is not exactly the same as in the continuous cases. One must + # multiply the result by a sampling resolution to keep equivalent. + + # q1 as first axis, q2 as second axis, z as third axis + # reshape to become three independent axes for easier handling + size1, size2 = self.num_grid_points + q1_axis = np.fft.fftfreq(size1, + d=self.physical_sizes[0]/(2*np.pi*size1)).reshape(-1,1,1) + q2_axis = np.fft.fftfreq(size2, + d=self.physical_sizes[1]/(2*np.pi*size2)).reshape(1,-1,1) + gap_axis = np.reshape(gap, (1,1,-1)) + + # dq1, dq2 are assumed to be discretized as constants + # 2 π + # d_qi = ─────── + # L_i + d_q1 = 2 * np.pi / self.physical_sizes[0] + d_q2 = 2 * np.pi / self.physical_sizes[1] + + # ϵ_m + # coefficient A = ───────────────────── + # 2 π^2 (ϵ_m + ϵ_g)^2 + A = self.epsilon_material + A /= 2 * np.pi**2 * (self.epsilon_material + self.epsilon_gap)**2 + + # A + # integral = - ─────── ∫∫ dq1 dq2 σ(q1, q2)^2 K(q1, q2, z) + # L1 L2 + # K is the kernel function, will be different in different cases + integral = lambda K: -A / np.prod(self.physical_sizes) * np.einsum( + "...,...,pq,pqz->z", d_q1, d_q2, fft_magnitude**2, K) + # ... is used to handle zero dimension arrays + + # q_norm = |q| = √(q1^2 + q2^2) + q_norm = np.sqrt(q1_axis**2 + q2_axis**2) + + # decay = exp(-|q|z) + decay = np.exp(-q_norm * gap_axis) + + # ϵ_m - ϵ_g + # coefficient B = ─────────── + # ϵ_m + ϵ_g + B = self.epsilon_material - self.epsilon_gap + B /= self.epsilon_material + self.epsilon_gap + + if potential: + # -exp(-|q|z) + # K(q1, q2, z) = ────────────────────── + # |q| [1 - B exp(-|q|z)] + kernel = -decay / q_norm / (1 - B*decay) + potential = integral(kernel) + else: + potential = None + + if gradient: + # exp(-|q|z) + # K(q1, q2, z) = ───────────────────── + # [1 - B exp(-|q|z)]^2 + kernel = decay / (1 - B*decay)**2 + gradient = integral(kernel) + else: + gradient = None + + if curvature: + # -|q| exp(-|q|z) [1 + B exp(-|q|z)] + # K(q1, q2, z) = ──────────────────────────────────── + # [1 - B exp(-|q|z)]^3 + kernel = -q_norm * decay * (1 + B*decay) / (1 - B*decay)**3 + curvature = integral(kernel) + else: + curvature = None + + return (potential, gradient, curvature) + + + + \ No newline at end of file diff --git a/test/Interactions/test_electrostatic.py b/test/Interactions/test_electrostatic.py index 867e4a13..24bd9256 100644 --- a/test/Interactions/test_electrostatic.py +++ b/test/Interactions/test_electrostatic.py @@ -1,2 +1,78 @@ -def test_sinewave(): - pass +from Adhesion.Interactions.Electrostatic import ChargePatternsInteraction + + +epsilon0 = 8.854e-12 # [C/m^2], permittivity in vacuum + + +def test_sine_wave(): + import numpy as np + magnitude = 0.01 # [C/m2] + length = 50e-9 # [m] + resolution = 1e-9 # [m] + size = round(length/resolution) + charge_distribution = np.empty([size, size]) + for index in range(size): + charge_distribution[index,:] = magnitude * np.sin(2*np.pi*index/size) + sine_wave = ChargePatternsInteraction(charge_distribution, + physical_sizes=(length, length)) + if False: + import matplotlib.pyplot as plt + fig, ax = plt.subplots() + colormap = ax.imshow(sine_wave.charge_distribution.T, origin="lower") + fig.colorbar(colormap) + plt.show() + + gaps = np.linspace(0.1, 10) * length + stress_numerical = sine_wave.evaluate(gaps, + potential=False, gradient=True, curvature=False)[1] + # σ^2 d + # T_ad(d) = - ─────── exp(- 2π ───) + # 4 ϵ_0 L + decay = np.exp(-2 * np.pi * gaps / length) + stress_analytical = -magnitude**2 / (4*epsilon0) * decay + if False: + import matplotlib.pyplot as plt + fig, ax = plt.subplots() + ax.plot(gaps, stress_numerical, label="numerical") + ax.plot(gaps, stress_analytical, label="analytical") + plt.show() + np.testing.assert_allclose(stress_numerical, stress_analytical, + atol=1e-6, rtol=1e-4) + + +def test_sine_wave2D(): + import numpy as np + magnitude = 0.01 # [C/m2] + length = 50e-9 # [m] + resolution = 1e-9 # [m] + size = round(length/resolution) + charge_distribution = np.empty([size, size]) + for x, y in np.ndindex(size, size): + sin_2pi = lambda t: np.sin(2 * np.pi * t) + charge_distribution[x, y] = sin_2pi(x/size) * sin_2pi(y/size) + charge_distribution *= magnitude + sine_wave2D = ChargePatternsInteraction(charge_distribution, + physical_sizes=(length, length)) + if False: + import matplotlib.pyplot as plt + fig, ax = plt.subplots() + colormap = ax.imshow(sine_wave2D.charge_distribution.T, origin="lower") + fig.colorbar(colormap) + plt.show() + + gaps = np.linspace(0.1, 10) * length + stress_numerical = sine_wave2D.evaluate(gaps, + potential=False, gradient=True, curvature=False)[1] + # σ^2 d + # T_ad(z) = - ─────── exp(-√2 2π ───) + # 8 ϵ_0 L + decay = np.exp(-2 * np.pi * gaps / length) + stress_analytical = -magnitude**2 / (8*epsilon0) * decay**np.sqrt(2) + if False: + import matplotlib.pyplot as plt + fig, ax = plt.subplots() + ax.plot(gaps, stress_numerical, label="numerical") + ax.plot(gaps, stress_analytical, label="analytical") + plt.show() + np.testing.assert_allclose(stress_numerical, stress_analytical, + atol=1e-6, rtol=1e-4) \ No newline at end of file From 9540c520b8c5a99a2c21171b3498d1e90bfae657 Mon Sep 17 00:00:00 2001 From: yzuuang Date: Tue, 1 Dec 2020 15:51:15 +0100 Subject: [PATCH 03/10] WIP --- Adhesion/Interactions/Electrostatic.py | 139 +++++++++++++++++------- test/Interactions/test_electrostatic.py | 79 ++++++++------ 2 files changed, 147 insertions(+), 71 deletions(-) diff --git a/Adhesion/Interactions/Electrostatic.py b/Adhesion/Interactions/Electrostatic.py index 36abf2aa..91337d19 100644 --- a/Adhesion/Interactions/Electrostatic.py +++ b/Adhesion/Interactions/Electrostatic.py @@ -2,6 +2,7 @@ from NuMPI import MPI import numpy as np + class ChargePatternsInteraction(Potential): """ Potential for the interaction of charges @@ -15,7 +16,7 @@ def __init__(self, physical_sizes, dielectric_constant_material=1., dielectric_constant_gap=1., - pixel_sizes=(1e-9,1e-9), + pixel_sizes=(1e-9, 1e-9), communicator=MPI.COMM_WORLD): """ @@ -42,23 +43,24 @@ def __init__(self, self.pixel_area = np.prod(pixel_sizes) Potential.__init__(self, communicator=communicator) self.num_grid_points = charge_distribution.shape - + @property def r_min(self): return None - + @property def r_infl(self): return None - - def __repr__(self, ): + + def __repr__(self): return ("Potential '{0.name}': ε = {0.eps}, σ = {0.sig}").format(self) def evaluate(self, - gap, + gap, potential=True, gradient=False, - curvature=False): + curvature=False, + stress_dist=False): """ Parameters @@ -77,58 +79,63 @@ def evaluate(self, # TODO: is that easy/possible/computationally tractable ? """ assert np.ndim(gap) == 1 # unit[m] - + # fast Fourier transform, σ(x1, x2) -> σ(q1, q2) - fft_charge_distribution = np.fft.fft2(self.charge_distribution, - s=self.num_grid_points) + fft_charge_distribution = np.fft.fft2( + self.charge_distribution, s=self.num_grid_points + ) + + # According to sampling theory, the magnitude after discretization + # is not exactly the same as in the continuous cases. One must + # multiply the result by a sampling resolution to keep equivalent. fft_magnitude = np.abs(fft_charge_distribution) * self.pixel_area - # According to sampling theory, the magnitude after discretization - # is not exactly the same as in the continuous cases. One must - # multiply the result by a sampling resolution to keep equivalent. - + # q1 as first axis, q2 as second axis, z as third axis # reshape to become three independent axes for easier handling size1, size2 = self.num_grid_points - q1_axis = np.fft.fftfreq(size1, - d=self.physical_sizes[0]/(2*np.pi*size1)).reshape(-1,1,1) - q2_axis = np.fft.fftfreq(size2, - d=self.physical_sizes[1]/(2*np.pi*size2)).reshape(1,-1,1) - gap_axis = np.reshape(gap, (1,1,-1)) - + q1_axis = np.fft.fftfreq( + size1, d=self.physical_sizes[0]/(2*np.pi*size1) + ).reshape(-1, 1, 1) + q2_axis = np.fft.fftfreq( + size2, d=self.physical_sizes[1]/(2*np.pi*size2) + ).reshape(1, -1, 1) + gap_axis = np.reshape(gap, (1, 1, -1)) + # dq1, dq2 are assumed to be discretized as constants # 2 π # d_qi = ─────── # L_i d_q1 = 2 * np.pi / self.physical_sizes[0] d_q2 = 2 * np.pi / self.physical_sizes[1] - + # ϵ_m # coefficient A = ───────────────────── # 2 π^2 (ϵ_m + ϵ_g)^2 A = self.epsilon_material A /= 2 * np.pi**2 * (self.epsilon_material + self.epsilon_gap)**2 - + # A # integral = - ─────── ∫∫ dq1 dq2 σ(q1, q2)^2 K(q1, q2, z) # L1 L2 # K is the kernel function, will be different in different cases - integral = lambda K: -A / np.prod(self.physical_sizes) * np.einsum( - "...,...,pq,pqz->z", d_q1, d_q2, fft_magnitude**2, K) - # ... is used to handle zero dimension arrays - + def integral(K): + return -A / np.prod(self.physical_sizes) * np.einsum( + "..., ..., pq, pqz-> z", d_q1, d_q2, fft_magnitude**2, K + ) # ... is used to handle constants (zero dimension arrays) + # q_norm = |q| = √(q1^2 + q2^2) q_norm = np.sqrt(q1_axis**2 + q2_axis**2) - + # decay = exp(-|q|z) decay = np.exp(-q_norm * gap_axis) - + # ϵ_m - ϵ_g # coefficient B = ─────────── # ϵ_m + ϵ_g B = self.epsilon_material - self.epsilon_gap B /= self.epsilon_material + self.epsilon_gap - - if potential: + + if potential: # work of adhesion # -exp(-|q|z) # K(q1, q2, z) = ────────────────────── # |q| [1 - B exp(-|q|z)] @@ -136,8 +143,8 @@ def evaluate(self, potential = integral(kernel) else: potential = None - - if gradient: + + if gradient: # normal stress of adhesion # exp(-|q|z) # K(q1, q2, z) = ───────────────────── # [1 - B exp(-|q|z)]^2 @@ -145,18 +152,70 @@ def evaluate(self, gradient = integral(kernel) else: gradient = None - - if curvature: + + if curvature: # change of normal stress # -|q| exp(-|q|z) [1 + B exp(-|q|z)] # K(q1, q2, z) = ──────────────────────────────────── # [1 - B exp(-|q|z)]^3 kernel = -q_norm * decay * (1 + B*decay) / (1 - B*decay)**3 curvature = integral(kernel) else: - curvature = None - - return (potential, gradient, curvature) + curvature = None + + if stress_dist: + # frequency spectrum for E_normal + # σ(q1, q2) [1 - exp(-|q|d)] + # f = ────────────────────────────── + # (ϵ_m + ϵ_g) [1 - B exp(-|q|z)] + # where, q is vector, q1, q2 are components of vectors + E_normal = np.fft.ifft2( + np.einsum( + "pq, pqz pqz-> pqz", + fft_magnitude / (self.epsilon_material + self.epsilon_gap), + 1 - np.exp(-q_norm*gap_axis), + 1 / (1 - B*decay), + ), + s=self.num_grid_points, + axes=(0, 1), + ) + + # frequency spectrum for E_tangential + # (-iq) σ(q1, q2) [1 + exp(-|q|d)] + # f = ────────────────────────────────── + # |q| (ϵ_m + ϵ_g) [1 - B exp(-|q|z)] + # + # where, q is vector, q1, q2 are components of vectors + # i is imaginary unit + E_x = np.fft.ifft2( + np.multiply( + "pq, pq, pqz, pqz-> pqz", + -complex("j") * q1_axis / q_norm + fft_magnitude / (self.epsilon_material + self.epsilon_gap), + 1 + np.exp(-q_norm*gap_axis), + 1 / (1 - B*decay), + ), + s=self.num_grid_points, + axes=(0, 1), + ) + E_y = np.fft.ifft2( + np.multiply( + "pq, pq, pqz, pqz-> pqz", + -complex("j") * q2_axis / q_norm + fft_magnitude / (self.epsilon_material + self.epsilon_gap), + 1 + np.exp(-q_norm*gap_axis), + 1 / (1 - B*decay), + ), + s=self.num_grid_points, + axes=(0, 1), + ) + + # ϵ_m + # T_zz(x1, x2) = ─── (E_normal^2 - E_tangential^2) + # 2 + T_zz = self.epsilon_material / 2 + T_zz *= np.abs(E_normal)**2 - np.abs(E_x)**2 - np.abs(E_y)**2 + stress_dist = T_zz + else: + stress_dist = None - - - \ No newline at end of file + return (potential, gradient, curvature, stress_dist) diff --git a/test/Interactions/test_electrostatic.py b/test/Interactions/test_electrostatic.py index 24bd9256..a6ac22a7 100644 --- a/test/Interactions/test_electrostatic.py +++ b/test/Interactions/test_electrostatic.py @@ -1,30 +1,30 @@ +import numpy as np from Adhesion.Interactions.Electrostatic import ChargePatternsInteraction epsilon0 = 8.854e-12 # [C/m^2], permittivity in vacuum -def test_sine_wave(): - import numpy as np +def test_sinewave(): magnitude = 0.01 # [C/m2] length = 50e-9 # [m] resolution = 1e-9 # [m] - size = round(length/resolution) - charge_distribution = np.empty([size, size]) - for index in range(size): - charge_distribution[index,:] = magnitude * np.sin(2*np.pi*index/size) - sine_wave = ChargePatternsInteraction(charge_distribution, - physical_sizes=(length, length)) + n = round(length/resolution) # number of points in one axis + charge_distribution = magnitude * np.broadcast_to( + np.sin(2*np.pi*np.arange(n)/n), [n, n]) + sinewave = ChargePatternsInteraction( + charge_distribution, physical_sizes=(length, length)) if False: import matplotlib.pyplot as plt fig, ax = plt.subplots() - colormap = ax.imshow(sine_wave.charge_distribution.T, origin="lower") + colormap = ax.imshow(sinewave.charge_distribution.T, origin="lower") fig.colorbar(colormap) plt.show() - + gaps = np.linspace(0.1, 10) * length - stress_numerical = sine_wave.evaluate(gaps, - potential=False, gradient=True, curvature=False)[1] + stress_numerical = sinewave.evaluate( + gaps, potential=False, gradient=True, curvature=False + )[1] # σ^2 d # T_ad(d) = - ─────── exp(- 2π ───) # 4 ϵ_0 L @@ -36,33 +36,31 @@ def test_sine_wave(): ax.plot(gaps, stress_numerical, label="numerical") ax.plot(gaps, stress_analytical, label="analytical") plt.show() - np.testing.assert_allclose(stress_numerical, stress_analytical, - atol=1e-6, rtol=1e-4) - + np.testing.assert_allclose( + stress_numerical, stress_analytical, atol=1e-6, rtol=1e-4 + ) + -def test_sine_wave2D(): - import numpy as np +def test_sinewave2D(): magnitude = 0.01 # [C/m2] length = 50e-9 # [m] resolution = 1e-9 # [m] - size = round(length/resolution) - charge_distribution = np.empty([size, size]) - for x, y in np.ndindex(size, size): - sin_2pi = lambda t: np.sin(2 * np.pi * t) - charge_distribution[x, y] = sin_2pi(x/size) * sin_2pi(y/size) - charge_distribution *= magnitude - sine_wave2D = ChargePatternsInteraction(charge_distribution, - physical_sizes=(length, length)) + n = round(length/resolution) # number of points in one axis + charge_distribution = magnitude * np.outer( + np.sin(2*np.pi*np.arange(n)/n), np.sin(2*np.pi*np.arange(n)/n)) + sinewave2D = ChargePatternsInteraction( + charge_distribution, physical_sizes=(length, length)) if False: import matplotlib.pyplot as plt fig, ax = plt.subplots() - colormap = ax.imshow(sine_wave2D.charge_distribution.T, origin="lower") + colormap = ax.imshow(sinewave2D.charge_distribution.T, origin="lower") fig.colorbar(colormap) plt.show() - + gaps = np.linspace(0.1, 10) * length - stress_numerical = sine_wave2D.evaluate(gaps, - potential=False, gradient=True, curvature=False)[1] + stress_numerical = sinewave2D.evaluate( + gaps, potential=False, gradient=True, curvature=False + )[1] # σ^2 d # T_ad(z) = - ─────── exp(-√2 2π ───) # 8 ϵ_0 L @@ -74,5 +72,24 @@ def test_sine_wave2D(): ax.plot(gaps, stress_numerical, label="numerical") ax.plot(gaps, stress_analytical, label="analytical") plt.show() - np.testing.assert_allclose(stress_numerical, stress_analytical, - atol=1e-6, rtol=1e-4) \ No newline at end of file + np.testing.assert_allclose( + stress_numerical, stress_analytical, atol=1e-6, rtol=1e-4 + ) + + +def test_distribution(): + magnitude = 0.01 # [C/m2] + length = 50e-9 # [m] + resolution = 1e-9 # [m] + n = round(length/resolution) # number of points in one axis + charge_distribution = magnitude * np.outer( + np.sin(2*np.pi*np.arange(n)/n), np.sin(2*np.pi*np.arange(n)/n)) + sinewave2D = ChargePatternsInteraction( + charge_distribution, physical_sizes=(length, length)) + gaps = np.linspace(0.1, 10, 10) * length + test_return = sinewave2D.evaluate( + gaps, + potential=False, + stress_dist=True, + )[3] + print(test_return) From fa5e6b55c6f132331c883790b0f89b960c2e26c9 Mon Sep 17 00:00:00 2001 From: yzuuang Date: Tue, 1 Dec 2020 16:25:34 +0100 Subject: [PATCH 04/10] WIP --- Adhesion/Interactions/Electrostatic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adhesion/Interactions/Electrostatic.py b/Adhesion/Interactions/Electrostatic.py index 91337d19..d2018e01 100644 --- a/Adhesion/Interactions/Electrostatic.py +++ b/Adhesion/Interactions/Electrostatic.py @@ -189,7 +189,7 @@ def integral(K): E_x = np.fft.ifft2( np.multiply( "pq, pq, pqz, pqz-> pqz", - -complex("j") * q1_axis / q_norm + -complex("j") * q1_axis / q_norm, fft_magnitude / (self.epsilon_material + self.epsilon_gap), 1 + np.exp(-q_norm*gap_axis), 1 / (1 - B*decay), @@ -200,7 +200,7 @@ def integral(K): E_y = np.fft.ifft2( np.multiply( "pq, pq, pqz, pqz-> pqz", - -complex("j") * q2_axis / q_norm + -complex("j") * q2_axis / q_norm, fft_magnitude / (self.epsilon_material + self.epsilon_gap), 1 + np.exp(-q_norm*gap_axis), 1 / (1 - B*decay), From c78d25e80d97b0b832a3b0ca0922d127342e3d14 Mon Sep 17 00:00:00 2001 From: Antoine Sanner <40853209+sannant@users.noreply.github.com> Date: Sun, 22 Jan 2023 09:04:53 +0100 Subject: [PATCH 05/10] Delete .gitignore --- .idea/.gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .idea/.gitignore diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 5c98b428..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml \ No newline at end of file From 4f55b8ea82d3b3e007f34d980d87e37e8e5ae8c0 Mon Sep 17 00:00:00 2001 From: Antoine Sanner <40853209+sannant@users.noreply.github.com> Date: Sun, 22 Jan 2023 09:05:04 +0100 Subject: [PATCH 06/10] Delete .idea directory --- .idea/vcs.xml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .idea/vcs.xml diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 8b50b6108494dbbacc36f1805b64c3619584bdaa Mon Sep 17 00:00:00 2001 From: Antoine Sanner <40853209+sannant@users.noreply.github.com> Date: Sun, 22 Jan 2023 09:05:16 +0100 Subject: [PATCH 07/10] Delete env.sh --- env.sh | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 env.sh diff --git a/env.sh b/env.sh deleted file mode 100644 index 4ac53474..00000000 --- a/env.sh +++ /dev/null @@ -1,17 +0,0 @@ -#! /bin/sh - -PYTHON="$1" -if [ -z "$PYTHON" ]; then - PYTHON="python3" -fi - -ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -PLATFORM=`$PYTHON -c "from __future__ import print_function ; from distutils.util import get_platform ; from distutils.sysconfig import get_python_version ; print('{0}-{1}'.format(get_platform(), get_python_version()))"` - -echo "Setting Python environment" -echo "--------------------------" -echo "Python executable: $PYTHON" -echo "Root directory: $ROOT" -echo "Platform: $PLATFORM" - -export PYTHONPATH="$ROOT:$ROOT/build/lib.$PLATFORM:$PYTHONPATH" From 49a1f4f23c5ee5408ddb502f0a9f63bc5932042e Mon Sep 17 00:00:00 2001 From: sannant Date: Sun, 22 Jan 2023 09:49:51 +0100 Subject: [PATCH 08/10] BUG: fix small errors in array dimensions in Einstein summations --- Adhesion/Interactions/Electrostatic.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Adhesion/Interactions/Electrostatic.py b/Adhesion/Interactions/Electrostatic.py index d2018e01..feec53bb 100644 --- a/Adhesion/Interactions/Electrostatic.py +++ b/Adhesion/Interactions/Electrostatic.py @@ -170,7 +170,7 @@ def integral(K): # where, q is vector, q1, q2 are components of vectors E_normal = np.fft.ifft2( np.einsum( - "pq, pqz pqz-> pqz", + "pq, pqz, pqz-> pqz", fft_magnitude / (self.epsilon_material + self.epsilon_gap), 1 - np.exp(-q_norm*gap_axis), 1 / (1 - B*decay), @@ -187,9 +187,9 @@ def integral(K): # where, q is vector, q1, q2 are components of vectors # i is imaginary unit E_x = np.fft.ifft2( - np.multiply( + np.einsum( "pq, pq, pqz, pqz-> pqz", - -complex("j") * q1_axis / q_norm, + -complex("j") * q1_axis[:,:,0] / q_norm[:,:,0], fft_magnitude / (self.epsilon_material + self.epsilon_gap), 1 + np.exp(-q_norm*gap_axis), 1 / (1 - B*decay), @@ -198,9 +198,9 @@ def integral(K): axes=(0, 1), ) E_y = np.fft.ifft2( - np.multiply( + np.einsum( "pq, pq, pqz, pqz-> pqz", - -complex("j") * q2_axis / q_norm, + -complex("j") * q2_axis[:,:,0] / q_norm[:,:,0], fft_magnitude / (self.epsilon_material + self.epsilon_gap), 1 + np.exp(-q_norm*gap_axis), 1 / (1 - B*decay), From affd6ae010f033e2b5661cd4e56a23f5513e5174 Mon Sep 17 00:00:00 2001 From: sannant Date: Sun, 22 Jan 2023 09:58:52 +0100 Subject: [PATCH 09/10] MAINT: flake8 --- Adhesion/Interactions/Electrostatic.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Adhesion/Interactions/Electrostatic.py b/Adhesion/Interactions/Electrostatic.py index feec53bb..553a2f59 100644 --- a/Adhesion/Interactions/Electrostatic.py +++ b/Adhesion/Interactions/Electrostatic.py @@ -189,25 +189,25 @@ def integral(K): E_x = np.fft.ifft2( np.einsum( "pq, pq, pqz, pqz-> pqz", - -complex("j") * q1_axis[:,:,0] / q_norm[:,:,0], + -complex("j") * q1_axis[:, :, 0] / q_norm[:, :, 0], fft_magnitude / (self.epsilon_material + self.epsilon_gap), - 1 + np.exp(-q_norm*gap_axis), - 1 / (1 - B*decay), - ), + 1 + np.exp(-q_norm * gap_axis), + 1 / (1 - B * decay), + ), s=self.num_grid_points, axes=(0, 1), ) E_y = np.fft.ifft2( np.einsum( "pq, pq, pqz, pqz-> pqz", - -complex("j") * q2_axis[:,:,0] / q_norm[:,:,0], + -complex("j") * q2_axis[:, :, 0] / q_norm[:, :, 0], fft_magnitude / (self.epsilon_material + self.epsilon_gap), - 1 + np.exp(-q_norm*gap_axis), - 1 / (1 - B*decay), - ), + 1 + np.exp(-q_norm * gap_axis), + 1 / (1 - B * decay), + ), s=self.num_grid_points, axes=(0, 1), - ) + ) # ϵ_m # T_zz(x1, x2) = ─── (E_normal^2 - E_tangential^2) From 3b38aa40cebab8627b95d6c3ebc9f90f54448ae2 Mon Sep 17 00:00:00 2001 From: sannant Date: Thu, 26 Jan 2023 15:43:26 +0100 Subject: [PATCH 10/10] MAINT: PEP8 --- Adhesion/Interactions/Electrostatic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adhesion/Interactions/Electrostatic.py b/Adhesion/Interactions/Electrostatic.py index 553a2f59..156d47a4 100644 --- a/Adhesion/Interactions/Electrostatic.py +++ b/Adhesion/Interactions/Electrostatic.py @@ -53,7 +53,7 @@ def r_infl(self): return None def __repr__(self): - return ("Potential '{0.name}': ε = {0.eps}, σ = {0.sig}").format(self) + return "Potential '{0.name}': ε = {0.eps}, σ = {0.sig}".format(self) def evaluate(self, gap, @@ -218,4 +218,4 @@ def integral(K): else: stress_dist = None - return (potential, gradient, curvature, stress_dist) + return potential, gradient, curvature, stress_dist